solidrun.patch 6.7 MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541475424754347544475454754647547475484754947550475514755247553475544755547556475574755847559475604756147562475634756447565475664756747568475694757047571475724757347574475754757647577475784757947580475814758247583475844758547586475874758847589475904759147592475934759447595475964759747598475994760047601476024760347604476054760647607476084760947610476114761247613476144761547616476174761847619476204762147622476234762447625476264762747628476294763047631476324763347634476354763647637476384763947640476414764247643476444764547646476474764847649476504765147652476534765447655476564765747658476594766047661476624766347664476654766647667476684766947670476714767247673476744767547676476774767847679476804768147682476834768447685476864768747688476894769047691476924769347694476954769647697476984769947700477014770247703477044770547706477074770847709477104771147712477134771447715477164771747718477194772047721477224772347724477254772647727477284772947730477314773247733477344773547736477374773847739477404774147742477434774447745477464774747748477494775047751477524775347754477554775647757477584775947760477614776247763477644776547766477674776847769477704777147772477734777447775477764777747778477794778047781477824778347784477854778647787477884778947790477914779247793477944779547796477974779847799478004780147802478034780447805478064780747808478094781047811478124781347814478154781647817478184781947820478214782247823478244782547826478274782847829478304783147832478334783447835478364783747838478394784047841478424784347844478454784647847478484784947850478514785247853478544785547856478574785847859478604786147862478634786447865478664786747868478694787047871478724787347874478754787647877478784787947880478814788247883478844788547886478874788847889478904789147892478934789447895478964789747898478994790047901479024790347904479054790647907479084790947910479114791247913479144791547916479174791847919479204792147922479234792447925479264792747928479294793047931479324793347934479354793647937479384793947940479414794247943479444794547946479474794847949479504795147952479534795447955479564795747958479594796047961479624796347964479654796647967479684796947970479714797247973479744797547976479774797847979479804798147982479834798447985479864798747988479894799047991479924799347994479954799647997479984799948000480014800248003480044800548006480074800848009480104801148012480134801448015480164801748018480194802048021480224802348024480254802648027480284802948030480314803248033480344803548036480374803848039480404804148042480434804448045480464804748048480494805048051480524805348054480554805648057480584805948060480614806248063480644806548066480674806848069480704807148072480734807448075480764807748078480794808048081480824808348084480854808648087480884808948090480914809248093480944809548096480974809848099481004810148102481034810448105481064810748108481094811048111481124811348114481154811648117481184811948120481214812248123481244812548126481274812848129481304813148132481334813448135481364813748138481394814048141481424814348144481454814648147481484814948150481514815248153481544815548156481574815848159481604816148162481634816448165481664816748168481694817048171481724817348174481754817648177481784817948180481814818248183481844818548186481874818848189481904819148192481934819448195481964819748198481994820048201482024820348204482054820648207482084820948210482114821248213482144821548216482174821848219482204822148222482234822448225482264822748228482294823048231482324823348234482354823648237482384823948240482414824248243482444824548246482474824848249482504825148252482534825448255482564825748258482594826048261482624826348264482654826648267482684826948270482714827248273482744827548276482774827848279482804828148282482834828448285482864828748288482894829048291482924829348294482954829648297482984829948300483014830248303483044830548306483074830848309483104831148312483134831448315483164831748318483194832048321483224832348324483254832648327483284832948330483314833248333483344833548336483374833848339483404834148342483434834448345483464834748348483494835048351483524835348354483554835648357483584835948360483614836248363483644836548366483674836848369483704837148372483734837448375483764837748378483794838048381483824838348384483854838648387483884838948390483914839248393483944839548396483974839848399484004840148402484034840448405484064840748408484094841048411484124841348414484154841648417484184841948420484214842248423484244842548426484274842848429484304843148432484334843448435484364843748438484394844048441484424844348444484454844648447484484844948450484514845248453484544845548456484574845848459484604846148462484634846448465484664846748468484694847048471484724847348474484754847648477484784847948480484814848248483484844848548486484874848848489484904849148492484934849448495484964849748498484994850048501485024850348504485054850648507485084850948510485114851248513485144851548516485174851848519485204852148522485234852448525485264852748528485294853048531485324853348534485354853648537485384853948540485414854248543485444854548546485474854848549485504855148552485534855448555485564855748558485594856048561485624856348564485654856648567485684856948570485714857248573485744857548576485774857848579485804858148582485834858448585485864858748588485894859048591485924859348594485954859648597485984859948600486014860248603486044860548606486074860848609486104861148612486134861448615486164861748618486194862048621486224862348624486254862648627486284862948630486314863248633486344863548636486374863848639486404864148642486434864448645486464864748648486494865048651486524865348654486554865648657486584865948660486614866248663486644866548666486674866848669486704867148672486734867448675486764867748678486794868048681486824868348684486854868648687486884868948690486914869248693486944869548696486974869848699487004870148702487034870448705487064870748708487094871048711487124871348714487154871648717487184871948720487214872248723487244872548726487274872848729487304873148732487334873448735487364873748738487394874048741487424874348744487454874648747487484874948750487514875248753487544875548756487574875848759487604876148762487634876448765487664876748768487694877048771487724877348774487754877648777487784877948780487814878248783487844878548786487874878848789487904879148792487934879448795487964879748798487994880048801488024880348804488054880648807488084880948810488114881248813488144881548816488174881848819488204882148822488234882448825488264882748828488294883048831488324883348834488354883648837488384883948840488414884248843488444884548846488474884848849488504885148852488534885448855488564885748858488594886048861488624886348864488654886648867488684886948870488714887248873488744887548876488774887848879488804888148882488834888448885488864888748888488894889048891488924889348894488954889648897488984889948900489014890248903489044890548906489074890848909489104891148912489134891448915489164891748918489194892048921489224892348924489254892648927489284892948930489314893248933489344893548936489374893848939489404894148942489434894448945489464894748948489494895048951489524895348954489554895648957489584895948960489614896248963489644896548966489674896848969489704897148972489734897448975489764897748978489794898048981489824898348984489854898648987489884898948990489914899248993489944899548996489974899848999490004900149002490034900449005490064900749008490094901049011490124901349014490154901649017490184901949020490214902249023490244902549026490274902849029490304903149032490334903449035490364903749038490394904049041490424904349044490454904649047490484904949050490514905249053490544905549056490574905849059490604906149062490634906449065490664906749068490694907049071490724907349074490754907649077490784907949080490814908249083490844908549086490874908849089490904909149092490934909449095490964909749098490994910049101491024910349104491054910649107491084910949110491114911249113491144911549116491174911849119491204912149122491234912449125491264912749128491294913049131491324913349134491354913649137491384913949140491414914249143491444914549146491474914849149491504915149152491534915449155491564915749158491594916049161491624916349164491654916649167491684916949170491714917249173491744917549176491774917849179491804918149182491834918449185491864918749188491894919049191491924919349194491954919649197491984919949200492014920249203492044920549206492074920849209492104921149212492134921449215492164921749218492194922049221492224922349224492254922649227492284922949230492314923249233492344923549236492374923849239492404924149242492434924449245492464924749248492494925049251492524925349254492554925649257492584925949260492614926249263492644926549266492674926849269492704927149272492734927449275492764927749278492794928049281492824928349284492854928649287492884928949290492914929249293492944929549296492974929849299493004930149302493034930449305493064930749308493094931049311493124931349314493154931649317493184931949320493214932249323493244932549326493274932849329493304933149332493334933449335493364933749338493394934049341493424934349344493454934649347493484934949350493514935249353493544935549356493574935849359493604936149362493634936449365493664936749368493694937049371493724937349374493754937649377493784937949380493814938249383493844938549386493874938849389493904939149392493934939449395493964939749398493994940049401494024940349404494054940649407494084940949410494114941249413494144941549416494174941849419494204942149422494234942449425494264942749428494294943049431494324943349434494354943649437494384943949440494414944249443494444944549446494474944849449494504945149452494534945449455494564945749458494594946049461494624946349464494654946649467494684946949470494714947249473494744947549476494774947849479494804948149482494834948449485494864948749488494894949049491494924949349494494954949649497494984949949500495014950249503495044950549506495074950849509495104951149512495134951449515495164951749518495194952049521495224952349524495254952649527495284952949530495314953249533495344953549536495374953849539495404954149542495434954449545495464954749548495494955049551495524955349554495554955649557495584955949560495614956249563495644956549566495674956849569495704957149572495734957449575495764957749578495794958049581495824958349584495854958649587495884958949590495914959249593495944959549596495974959849599496004960149602496034960449605496064960749608496094961049611496124961349614496154961649617496184961949620496214962249623496244962549626496274962849629496304963149632496334963449635496364963749638496394964049641496424964349644496454964649647496484964949650496514965249653496544965549656496574965849659496604966149662496634966449665496664966749668496694967049671496724967349674496754967649677496784967949680496814968249683496844968549686496874968849689496904969149692496934969449695496964969749698496994970049701497024970349704497054970649707497084970949710497114971249713497144971549716497174971849719497204972149722497234972449725497264972749728497294973049731497324973349734497354973649737497384973949740497414974249743497444974549746497474974849749497504975149752497534975449755497564975749758497594976049761497624976349764497654976649767497684976949770497714977249773497744977549776497774977849779497804978149782497834978449785497864978749788497894979049791497924979349794497954979649797497984979949800498014980249803498044980549806498074980849809498104981149812498134981449815498164981749818498194982049821498224982349824498254982649827498284982949830498314983249833498344983549836498374983849839498404984149842498434984449845498464984749848498494985049851498524985349854498554985649857498584985949860498614986249863498644986549866498674986849869498704987149872498734987449875498764987749878498794988049881498824988349884498854988649887498884988949890498914989249893498944989549896498974989849899499004990149902499034990449905499064990749908499094991049911499124991349914499154991649917499184991949920499214992249923499244992549926499274992849929499304993149932499334993449935499364993749938499394994049941499424994349944499454994649947499484994949950499514995249953499544995549956499574995849959499604996149962499634996449965499664996749968499694997049971499724997349974499754997649977499784997949980499814998249983499844998549986499874998849989499904999149992499934999449995499964999749998499995000050001500025000350004500055000650007500085000950010500115001250013500145001550016500175001850019500205002150022500235002450025500265002750028500295003050031500325003350034500355003650037500385003950040500415004250043500445004550046500475004850049500505005150052500535005450055500565005750058500595006050061500625006350064500655006650067500685006950070500715007250073500745007550076500775007850079500805008150082500835008450085500865008750088500895009050091500925009350094500955009650097500985009950100501015010250103501045010550106501075010850109501105011150112501135011450115501165011750118501195012050121501225012350124501255012650127501285012950130501315013250133501345013550136501375013850139501405014150142501435014450145501465014750148501495015050151501525015350154501555015650157501585015950160501615016250163501645016550166501675016850169501705017150172501735017450175501765017750178501795018050181501825018350184501855018650187501885018950190501915019250193501945019550196501975019850199502005020150202502035020450205502065020750208502095021050211502125021350214502155021650217502185021950220502215022250223502245022550226502275022850229502305023150232502335023450235502365023750238502395024050241502425024350244502455024650247502485024950250502515025250253502545025550256502575025850259502605026150262502635026450265502665026750268502695027050271502725027350274502755027650277502785027950280502815028250283502845028550286502875028850289502905029150292502935029450295502965029750298502995030050301503025030350304503055030650307503085030950310503115031250313503145031550316503175031850319503205032150322503235032450325503265032750328503295033050331503325033350334503355033650337503385033950340503415034250343503445034550346503475034850349503505035150352503535035450355503565035750358503595036050361503625036350364503655036650367503685036950370503715037250373503745037550376503775037850379503805038150382503835038450385503865038750388503895039050391503925039350394503955039650397503985039950400504015040250403504045040550406504075040850409504105041150412504135041450415504165041750418504195042050421504225042350424504255042650427504285042950430504315043250433504345043550436504375043850439504405044150442504435044450445504465044750448504495045050451504525045350454504555045650457504585045950460504615046250463504645046550466504675046850469504705047150472504735047450475504765047750478504795048050481504825048350484504855048650487504885048950490504915049250493504945049550496504975049850499505005050150502505035050450505505065050750508505095051050511505125051350514505155051650517505185051950520505215052250523505245052550526505275052850529505305053150532505335053450535505365053750538505395054050541505425054350544505455054650547505485054950550505515055250553505545055550556505575055850559505605056150562505635056450565505665056750568505695057050571505725057350574505755057650577505785057950580505815058250583505845058550586505875058850589505905059150592505935059450595505965059750598505995060050601506025060350604506055060650607506085060950610506115061250613506145061550616506175061850619506205062150622506235062450625506265062750628506295063050631506325063350634506355063650637506385063950640506415064250643506445064550646506475064850649506505065150652506535065450655506565065750658506595066050661506625066350664506655066650667506685066950670506715067250673506745067550676506775067850679506805068150682506835068450685506865068750688506895069050691506925069350694506955069650697506985069950700507015070250703507045070550706507075070850709507105071150712507135071450715507165071750718507195072050721507225072350724507255072650727507285072950730507315073250733507345073550736507375073850739507405074150742507435074450745507465074750748507495075050751507525075350754507555075650757507585075950760507615076250763507645076550766507675076850769507705077150772507735077450775507765077750778507795078050781507825078350784507855078650787507885078950790507915079250793507945079550796507975079850799508005080150802508035080450805508065080750808508095081050811508125081350814508155081650817508185081950820508215082250823508245082550826508275082850829508305083150832508335083450835508365083750838508395084050841508425084350844508455084650847508485084950850508515085250853508545085550856508575085850859508605086150862508635086450865508665086750868508695087050871508725087350874508755087650877508785087950880508815088250883508845088550886508875088850889508905089150892508935089450895508965089750898508995090050901509025090350904509055090650907509085090950910509115091250913509145091550916509175091850919509205092150922509235092450925509265092750928509295093050931509325093350934509355093650937509385093950940509415094250943509445094550946509475094850949509505095150952509535095450955509565095750958509595096050961509625096350964509655096650967509685096950970509715097250973509745097550976509775097850979509805098150982509835098450985509865098750988509895099050991509925099350994509955099650997509985099951000510015100251003510045100551006510075100851009510105101151012510135101451015510165101751018510195102051021510225102351024510255102651027510285102951030510315103251033510345103551036510375103851039510405104151042510435104451045510465104751048510495105051051510525105351054510555105651057510585105951060510615106251063510645106551066510675106851069510705107151072510735107451075510765107751078510795108051081510825108351084510855108651087510885108951090510915109251093510945109551096510975109851099511005110151102511035110451105511065110751108511095111051111511125111351114511155111651117511185111951120511215112251123511245112551126511275112851129511305113151132511335113451135511365113751138511395114051141511425114351144511455114651147511485114951150511515115251153511545115551156511575115851159511605116151162511635116451165511665116751168511695117051171511725117351174511755117651177511785117951180511815118251183511845118551186511875118851189511905119151192511935119451195511965119751198511995120051201512025120351204512055120651207512085120951210512115121251213512145121551216512175121851219512205122151222512235122451225512265122751228512295123051231512325123351234512355123651237512385123951240512415124251243512445124551246512475124851249512505125151252512535125451255512565125751258512595126051261512625126351264512655126651267512685126951270512715127251273512745127551276512775127851279512805128151282512835128451285512865128751288512895129051291512925129351294512955129651297512985129951300513015130251303513045130551306513075130851309513105131151312513135131451315513165131751318513195132051321513225132351324513255132651327513285132951330513315133251333513345133551336513375133851339513405134151342513435134451345513465134751348513495135051351513525135351354513555135651357513585135951360513615136251363513645136551366513675136851369513705137151372513735137451375513765137751378513795138051381513825138351384513855138651387513885138951390513915139251393513945139551396513975139851399514005140151402514035140451405514065140751408514095141051411514125141351414514155141651417514185141951420514215142251423514245142551426514275142851429514305143151432514335143451435514365143751438514395144051441514425144351444514455144651447514485144951450514515145251453514545145551456514575145851459514605146151462514635146451465514665146751468514695147051471514725147351474514755147651477514785147951480514815148251483514845148551486514875148851489514905149151492514935149451495514965149751498514995150051501515025150351504515055150651507515085150951510515115151251513515145151551516515175151851519515205152151522515235152451525515265152751528515295153051531515325153351534515355153651537515385153951540515415154251543515445154551546515475154851549515505155151552515535155451555515565155751558515595156051561515625156351564515655156651567515685156951570515715157251573515745157551576515775157851579515805158151582515835158451585515865158751588515895159051591515925159351594515955159651597515985159951600516015160251603516045160551606516075160851609516105161151612516135161451615516165161751618516195162051621516225162351624516255162651627516285162951630516315163251633516345163551636516375163851639516405164151642516435164451645516465164751648516495165051651516525165351654516555165651657516585165951660516615166251663516645166551666516675166851669516705167151672516735167451675516765167751678516795168051681516825168351684516855168651687516885168951690516915169251693516945169551696516975169851699517005170151702517035170451705517065170751708517095171051711517125171351714517155171651717517185171951720517215172251723517245172551726517275172851729517305173151732517335173451735517365173751738517395174051741517425174351744517455174651747517485174951750517515175251753517545175551756517575175851759517605176151762517635176451765517665176751768517695177051771517725177351774517755177651777517785177951780517815178251783517845178551786517875178851789517905179151792517935179451795517965179751798517995180051801518025180351804518055180651807518085180951810518115181251813518145181551816518175181851819518205182151822518235182451825518265182751828518295183051831518325183351834518355183651837518385183951840518415184251843518445184551846518475184851849518505185151852518535185451855518565185751858518595186051861518625186351864518655186651867518685186951870518715187251873518745187551876518775187851879518805188151882518835188451885518865188751888518895189051891518925189351894518955189651897518985189951900519015190251903519045190551906519075190851909519105191151912519135191451915519165191751918519195192051921519225192351924519255192651927519285192951930519315193251933519345193551936519375193851939519405194151942519435194451945519465194751948519495195051951519525195351954519555195651957519585195951960519615196251963519645196551966519675196851969519705197151972519735197451975519765197751978519795198051981519825198351984519855198651987519885198951990519915199251993519945199551996519975199851999520005200152002520035200452005520065200752008520095201052011520125201352014520155201652017520185201952020520215202252023520245202552026520275202852029520305203152032520335203452035520365203752038520395204052041520425204352044520455204652047520485204952050520515205252053520545205552056520575205852059520605206152062520635206452065520665206752068520695207052071520725207352074520755207652077520785207952080520815208252083520845208552086520875208852089520905209152092520935209452095520965209752098520995210052101521025210352104521055210652107521085210952110521115211252113521145211552116521175211852119521205212152122521235212452125521265212752128521295213052131521325213352134521355213652137521385213952140521415214252143521445214552146521475214852149521505215152152521535215452155521565215752158521595216052161521625216352164521655216652167521685216952170521715217252173521745217552176521775217852179521805218152182521835218452185521865218752188521895219052191521925219352194521955219652197521985219952200522015220252203522045220552206522075220852209522105221152212522135221452215522165221752218522195222052221522225222352224522255222652227522285222952230522315223252233522345223552236522375223852239522405224152242522435224452245522465224752248522495225052251522525225352254522555225652257522585225952260522615226252263522645226552266522675226852269522705227152272522735227452275522765227752278522795228052281522825228352284522855228652287522885228952290522915229252293522945229552296522975229852299523005230152302523035230452305523065230752308523095231052311523125231352314523155231652317523185231952320523215232252323523245232552326523275232852329523305233152332523335233452335523365233752338523395234052341523425234352344523455234652347523485234952350523515235252353523545235552356523575235852359523605236152362523635236452365523665236752368523695237052371523725237352374523755237652377523785237952380523815238252383523845238552386523875238852389523905239152392523935239452395523965239752398523995240052401524025240352404524055240652407524085240952410524115241252413524145241552416524175241852419524205242152422524235242452425524265242752428524295243052431524325243352434524355243652437524385243952440524415244252443524445244552446524475244852449524505245152452524535245452455524565245752458524595246052461524625246352464524655246652467524685246952470524715247252473524745247552476524775247852479524805248152482524835248452485524865248752488524895249052491524925249352494524955249652497524985249952500525015250252503525045250552506525075250852509525105251152512525135251452515525165251752518525195252052521525225252352524525255252652527525285252952530525315253252533525345253552536525375253852539525405254152542525435254452545525465254752548525495255052551525525255352554525555255652557525585255952560525615256252563525645256552566525675256852569525705257152572525735257452575525765257752578525795258052581525825258352584525855258652587525885258952590525915259252593525945259552596525975259852599526005260152602526035260452605526065260752608526095261052611526125261352614526155261652617526185261952620526215262252623526245262552626526275262852629526305263152632526335263452635526365263752638526395264052641526425264352644526455264652647526485264952650526515265252653526545265552656526575265852659526605266152662526635266452665526665266752668526695267052671526725267352674526755267652677526785267952680526815268252683526845268552686526875268852689526905269152692526935269452695526965269752698526995270052701527025270352704527055270652707527085270952710527115271252713527145271552716527175271852719527205272152722527235272452725527265272752728527295273052731527325273352734527355273652737527385273952740527415274252743527445274552746527475274852749527505275152752527535275452755527565275752758527595276052761527625276352764527655276652767527685276952770527715277252773527745277552776527775277852779527805278152782527835278452785527865278752788527895279052791527925279352794527955279652797527985279952800528015280252803528045280552806528075280852809528105281152812528135281452815528165281752818528195282052821528225282352824528255282652827528285282952830528315283252833528345283552836528375283852839528405284152842528435284452845528465284752848528495285052851528525285352854528555285652857528585285952860528615286252863528645286552866528675286852869528705287152872528735287452875528765287752878528795288052881528825288352884528855288652887528885288952890528915289252893528945289552896528975289852899529005290152902529035290452905529065290752908529095291052911529125291352914529155291652917529185291952920529215292252923529245292552926529275292852929529305293152932529335293452935529365293752938529395294052941529425294352944529455294652947529485294952950529515295252953529545295552956529575295852959529605296152962529635296452965529665296752968529695297052971529725297352974529755297652977529785297952980529815298252983529845298552986529875298852989529905299152992529935299452995529965299752998529995300053001530025300353004530055300653007530085300953010530115301253013530145301553016530175301853019530205302153022530235302453025530265302753028530295303053031530325303353034530355303653037530385303953040530415304253043530445304553046530475304853049530505305153052530535305453055530565305753058530595306053061530625306353064530655306653067530685306953070530715307253073530745307553076530775307853079530805308153082530835308453085530865308753088530895309053091530925309353094530955309653097530985309953100531015310253103531045310553106531075310853109531105311153112531135311453115531165311753118531195312053121531225312353124531255312653127531285312953130531315313253133531345313553136531375313853139531405314153142531435314453145531465314753148531495315053151531525315353154531555315653157531585315953160531615316253163531645316553166531675316853169531705317153172531735317453175531765317753178531795318053181531825318353184531855318653187531885318953190531915319253193531945319553196531975319853199532005320153202532035320453205532065320753208532095321053211532125321353214532155321653217532185321953220532215322253223532245322553226532275322853229532305323153232532335323453235532365323753238532395324053241532425324353244532455324653247532485324953250532515325253253532545325553256532575325853259532605326153262532635326453265532665326753268532695327053271532725327353274532755327653277532785327953280532815328253283532845328553286532875328853289532905329153292532935329453295532965329753298532995330053301533025330353304533055330653307533085330953310533115331253313533145331553316533175331853319533205332153322533235332453325533265332753328533295333053331533325333353334533355333653337533385333953340533415334253343533445334553346533475334853349533505335153352533535335453355533565335753358533595336053361533625336353364533655336653367533685336953370533715337253373533745337553376533775337853379533805338153382533835338453385533865338753388533895339053391533925339353394533955339653397533985339953400534015340253403534045340553406534075340853409534105341153412534135341453415534165341753418534195342053421534225342353424534255342653427534285342953430534315343253433534345343553436534375343853439534405344153442534435344453445534465344753448534495345053451534525345353454534555345653457534585345953460534615346253463534645346553466534675346853469534705347153472534735347453475534765347753478534795348053481534825348353484534855348653487534885348953490534915349253493534945349553496534975349853499535005350153502535035350453505535065350753508535095351053511535125351353514535155351653517535185351953520535215352253523535245352553526535275352853529535305353153532535335353453535535365353753538535395354053541535425354353544535455354653547535485354953550535515355253553535545355553556535575355853559535605356153562535635356453565535665356753568535695357053571535725357353574535755357653577535785357953580535815358253583535845358553586535875358853589535905359153592535935359453595535965359753598535995360053601536025360353604536055360653607536085360953610536115361253613536145361553616536175361853619536205362153622536235362453625536265362753628536295363053631536325363353634536355363653637536385363953640536415364253643536445364553646536475364853649536505365153652536535365453655536565365753658536595366053661536625366353664536655366653667536685366953670536715367253673536745367553676536775367853679536805368153682536835368453685536865368753688536895369053691536925369353694536955369653697536985369953700537015370253703537045370553706537075370853709537105371153712537135371453715537165371753718537195372053721537225372353724537255372653727537285372953730537315373253733537345373553736537375373853739537405374153742537435374453745537465374753748537495375053751537525375353754537555375653757537585375953760537615376253763537645376553766537675376853769537705377153772537735377453775537765377753778537795378053781537825378353784537855378653787537885378953790537915379253793537945379553796537975379853799538005380153802538035380453805538065380753808538095381053811538125381353814538155381653817538185381953820538215382253823538245382553826538275382853829538305383153832538335383453835538365383753838538395384053841538425384353844538455384653847538485384953850538515385253853538545385553856538575385853859538605386153862538635386453865538665386753868538695387053871538725387353874538755387653877538785387953880538815388253883538845388553886538875388853889538905389153892538935389453895538965389753898538995390053901539025390353904539055390653907539085390953910539115391253913539145391553916539175391853919539205392153922539235392453925539265392753928539295393053931539325393353934539355393653937539385393953940539415394253943539445394553946539475394853949539505395153952539535395453955539565395753958539595396053961539625396353964539655396653967539685396953970539715397253973539745397553976539775397853979539805398153982539835398453985539865398753988539895399053991539925399353994539955399653997539985399954000540015400254003540045400554006540075400854009540105401154012540135401454015540165401754018540195402054021540225402354024540255402654027540285402954030540315403254033540345403554036540375403854039540405404154042540435404454045540465404754048540495405054051540525405354054540555405654057540585405954060540615406254063540645406554066540675406854069540705407154072540735407454075540765407754078540795408054081540825408354084540855408654087540885408954090540915409254093540945409554096540975409854099541005410154102541035410454105541065410754108541095411054111541125411354114541155411654117541185411954120541215412254123541245412554126541275412854129541305413154132541335413454135541365413754138541395414054141541425414354144541455414654147541485414954150541515415254153541545415554156541575415854159541605416154162541635416454165541665416754168541695417054171541725417354174541755417654177541785417954180541815418254183541845418554186541875418854189541905419154192541935419454195541965419754198541995420054201542025420354204542055420654207542085420954210542115421254213542145421554216542175421854219542205422154222542235422454225542265422754228542295423054231542325423354234542355423654237542385423954240542415424254243542445424554246542475424854249542505425154252542535425454255542565425754258542595426054261542625426354264542655426654267542685426954270542715427254273542745427554276542775427854279542805428154282542835428454285542865428754288542895429054291542925429354294542955429654297542985429954300543015430254303543045430554306543075430854309543105431154312543135431454315543165431754318543195432054321543225432354324543255432654327543285432954330543315433254333543345433554336543375433854339543405434154342543435434454345543465434754348543495435054351543525435354354543555435654357543585435954360543615436254363543645436554366543675436854369543705437154372543735437454375543765437754378543795438054381543825438354384543855438654387543885438954390543915439254393543945439554396543975439854399544005440154402544035440454405544065440754408544095441054411544125441354414544155441654417544185441954420544215442254423544245442554426544275442854429544305443154432544335443454435544365443754438544395444054441544425444354444544455444654447544485444954450544515445254453544545445554456544575445854459544605446154462544635446454465544665446754468544695447054471544725447354474544755447654477544785447954480544815448254483544845448554486544875448854489544905449154492544935449454495544965449754498544995450054501545025450354504545055450654507545085450954510545115451254513545145451554516545175451854519545205452154522545235452454525545265452754528545295453054531545325453354534545355453654537545385453954540545415454254543545445454554546545475454854549545505455154552545535455454555545565455754558545595456054561545625456354564545655456654567545685456954570545715457254573545745457554576545775457854579545805458154582545835458454585545865458754588545895459054591545925459354594545955459654597545985459954600546015460254603546045460554606546075460854609546105461154612546135461454615546165461754618546195462054621546225462354624546255462654627546285462954630546315463254633546345463554636546375463854639546405464154642546435464454645546465464754648546495465054651546525465354654546555465654657546585465954660546615466254663546645466554666546675466854669546705467154672546735467454675546765467754678546795468054681546825468354684546855468654687546885468954690546915469254693546945469554696546975469854699547005470154702547035470454705547065470754708547095471054711547125471354714547155471654717547185471954720547215472254723547245472554726547275472854729547305473154732547335473454735547365473754738547395474054741547425474354744547455474654747547485474954750547515475254753547545475554756547575475854759547605476154762547635476454765547665476754768547695477054771547725477354774547755477654777547785477954780547815478254783547845478554786547875478854789547905479154792547935479454795547965479754798547995480054801548025480354804548055480654807548085480954810548115481254813548145481554816548175481854819548205482154822548235482454825548265482754828548295483054831548325483354834548355483654837548385483954840548415484254843548445484554846548475484854849548505485154852548535485454855548565485754858548595486054861548625486354864548655486654867548685486954870548715487254873548745487554876548775487854879548805488154882548835488454885548865488754888548895489054891548925489354894548955489654897548985489954900549015490254903549045490554906549075490854909549105491154912549135491454915549165491754918549195492054921549225492354924549255492654927549285492954930549315493254933549345493554936549375493854939549405494154942549435494454945549465494754948549495495054951549525495354954549555495654957549585495954960549615496254963549645496554966549675496854969549705497154972549735497454975549765497754978549795498054981549825498354984549855498654987549885498954990549915499254993549945499554996549975499854999550005500155002550035500455005550065500755008550095501055011550125501355014550155501655017550185501955020550215502255023550245502555026550275502855029550305503155032550335503455035550365503755038550395504055041550425504355044550455504655047550485504955050550515505255053550545505555056550575505855059550605506155062550635506455065550665506755068550695507055071550725507355074550755507655077550785507955080550815508255083550845508555086550875508855089550905509155092550935509455095550965509755098550995510055101551025510355104551055510655107551085510955110551115511255113551145511555116551175511855119551205512155122551235512455125551265512755128551295513055131551325513355134551355513655137551385513955140551415514255143551445514555146551475514855149551505515155152551535515455155551565515755158551595516055161551625516355164551655516655167551685516955170551715517255173551745517555176551775517855179551805518155182551835518455185551865518755188551895519055191551925519355194551955519655197551985519955200552015520255203552045520555206552075520855209552105521155212552135521455215552165521755218552195522055221552225522355224552255522655227552285522955230552315523255233552345523555236552375523855239552405524155242552435524455245552465524755248552495525055251552525525355254552555525655257552585525955260552615526255263552645526555266552675526855269552705527155272552735527455275552765527755278552795528055281552825528355284552855528655287552885528955290552915529255293552945529555296552975529855299553005530155302553035530455305553065530755308553095531055311553125531355314553155531655317553185531955320553215532255323553245532555326553275532855329553305533155332553335533455335553365533755338553395534055341553425534355344553455534655347553485534955350553515535255353553545535555356553575535855359553605536155362553635536455365553665536755368553695537055371553725537355374553755537655377553785537955380553815538255383553845538555386553875538855389553905539155392553935539455395553965539755398553995540055401554025540355404554055540655407554085540955410554115541255413554145541555416554175541855419554205542155422554235542455425554265542755428554295543055431554325543355434554355543655437554385543955440554415544255443554445544555446554475544855449554505545155452554535545455455554565545755458554595546055461554625546355464554655546655467554685546955470554715547255473554745547555476554775547855479554805548155482554835548455485554865548755488554895549055491554925549355494554955549655497554985549955500555015550255503555045550555506555075550855509555105551155512555135551455515555165551755518555195552055521555225552355524555255552655527555285552955530555315553255533555345553555536555375553855539555405554155542555435554455545555465554755548555495555055551555525555355554555555555655557555585555955560555615556255563555645556555566555675556855569555705557155572555735557455575555765557755578555795558055581555825558355584555855558655587555885558955590555915559255593555945559555596555975559855599556005560155602556035560455605556065560755608556095561055611556125561355614556155561655617556185561955620556215562255623556245562555626556275562855629556305563155632556335563455635556365563755638556395564055641556425564355644556455564655647556485564955650556515565255653556545565555656556575565855659556605566155662556635566455665556665566755668556695567055671556725567355674556755567655677556785567955680556815568255683556845568555686556875568855689556905569155692556935569455695556965569755698556995570055701557025570355704557055570655707557085570955710557115571255713557145571555716557175571855719557205572155722557235572455725557265572755728557295573055731557325573355734557355573655737557385573955740557415574255743557445574555746557475574855749557505575155752557535575455755557565575755758557595576055761557625576355764557655576655767557685576955770557715577255773557745577555776557775577855779557805578155782557835578455785557865578755788557895579055791557925579355794557955579655797557985579955800558015580255803558045580555806558075580855809558105581155812558135581455815558165581755818558195582055821558225582355824558255582655827558285582955830558315583255833558345583555836558375583855839558405584155842558435584455845558465584755848558495585055851558525585355854558555585655857558585585955860558615586255863558645586555866558675586855869558705587155872558735587455875558765587755878558795588055881558825588355884558855588655887558885588955890558915589255893558945589555896558975589855899559005590155902559035590455905559065590755908559095591055911559125591355914559155591655917559185591955920559215592255923559245592555926559275592855929559305593155932559335593455935559365593755938559395594055941559425594355944559455594655947559485594955950559515595255953559545595555956559575595855959559605596155962559635596455965559665596755968559695597055971559725597355974559755597655977559785597955980559815598255983559845598555986559875598855989559905599155992559935599455995559965599755998559995600056001560025600356004560055600656007560085600956010560115601256013560145601556016560175601856019560205602156022560235602456025560265602756028560295603056031560325603356034560355603656037560385603956040560415604256043560445604556046560475604856049560505605156052560535605456055560565605756058560595606056061560625606356064560655606656067560685606956070560715607256073560745607556076560775607856079560805608156082560835608456085560865608756088560895609056091560925609356094560955609656097560985609956100561015610256103561045610556106561075610856109561105611156112561135611456115561165611756118561195612056121561225612356124561255612656127561285612956130561315613256133561345613556136561375613856139561405614156142561435614456145561465614756148561495615056151561525615356154561555615656157561585615956160561615616256163561645616556166561675616856169561705617156172561735617456175561765617756178561795618056181561825618356184561855618656187561885618956190561915619256193561945619556196561975619856199562005620156202562035620456205562065620756208562095621056211562125621356214562155621656217562185621956220562215622256223562245622556226562275622856229562305623156232562335623456235562365623756238562395624056241562425624356244562455624656247562485624956250562515625256253562545625556256562575625856259562605626156262562635626456265562665626756268562695627056271562725627356274562755627656277562785627956280562815628256283562845628556286562875628856289562905629156292562935629456295562965629756298562995630056301563025630356304563055630656307563085630956310563115631256313563145631556316563175631856319563205632156322563235632456325563265632756328563295633056331563325633356334563355633656337563385633956340563415634256343563445634556346563475634856349563505635156352563535635456355563565635756358563595636056361563625636356364563655636656367563685636956370563715637256373563745637556376563775637856379563805638156382563835638456385563865638756388563895639056391563925639356394563955639656397563985639956400564015640256403564045640556406564075640856409564105641156412564135641456415564165641756418564195642056421564225642356424564255642656427564285642956430564315643256433564345643556436564375643856439564405644156442564435644456445564465644756448564495645056451564525645356454564555645656457564585645956460564615646256463564645646556466564675646856469564705647156472564735647456475564765647756478564795648056481564825648356484564855648656487564885648956490564915649256493564945649556496564975649856499565005650156502565035650456505565065650756508565095651056511565125651356514565155651656517565185651956520565215652256523565245652556526565275652856529565305653156532565335653456535565365653756538565395654056541565425654356544565455654656547565485654956550565515655256553565545655556556565575655856559565605656156562565635656456565565665656756568565695657056571565725657356574565755657656577565785657956580565815658256583565845658556586565875658856589565905659156592565935659456595565965659756598565995660056601566025660356604566055660656607566085660956610566115661256613566145661556616566175661856619566205662156622566235662456625566265662756628566295663056631566325663356634566355663656637566385663956640566415664256643566445664556646566475664856649566505665156652566535665456655566565665756658566595666056661566625666356664566655666656667566685666956670566715667256673566745667556676566775667856679566805668156682566835668456685566865668756688566895669056691566925669356694566955669656697566985669956700567015670256703567045670556706567075670856709567105671156712567135671456715567165671756718567195672056721567225672356724567255672656727567285672956730567315673256733567345673556736567375673856739567405674156742567435674456745567465674756748567495675056751567525675356754567555675656757567585675956760567615676256763567645676556766567675676856769567705677156772567735677456775567765677756778567795678056781567825678356784567855678656787567885678956790567915679256793567945679556796567975679856799568005680156802568035680456805568065680756808568095681056811568125681356814568155681656817568185681956820568215682256823568245682556826568275682856829568305683156832568335683456835568365683756838568395684056841568425684356844568455684656847568485684956850568515685256853568545685556856568575685856859568605686156862568635686456865568665686756868568695687056871568725687356874568755687656877568785687956880568815688256883568845688556886568875688856889568905689156892568935689456895568965689756898568995690056901569025690356904569055690656907569085690956910569115691256913569145691556916569175691856919569205692156922569235692456925569265692756928569295693056931569325693356934569355693656937569385693956940569415694256943569445694556946569475694856949569505695156952569535695456955569565695756958569595696056961569625696356964569655696656967569685696956970569715697256973569745697556976569775697856979569805698156982569835698456985569865698756988569895699056991569925699356994569955699656997569985699957000570015700257003570045700557006570075700857009570105701157012570135701457015570165701757018570195702057021570225702357024570255702657027570285702957030570315703257033570345703557036570375703857039570405704157042570435704457045570465704757048570495705057051570525705357054570555705657057570585705957060570615706257063570645706557066570675706857069570705707157072570735707457075570765707757078570795708057081570825708357084570855708657087570885708957090570915709257093570945709557096570975709857099571005710157102571035710457105571065710757108571095711057111571125711357114571155711657117571185711957120571215712257123571245712557126571275712857129571305713157132571335713457135571365713757138571395714057141571425714357144571455714657147571485714957150571515715257153571545715557156571575715857159571605716157162571635716457165571665716757168571695717057171571725717357174571755717657177571785717957180571815718257183571845718557186571875718857189571905719157192571935719457195571965719757198571995720057201572025720357204572055720657207572085720957210572115721257213572145721557216572175721857219572205722157222572235722457225572265722757228572295723057231572325723357234572355723657237572385723957240572415724257243572445724557246572475724857249572505725157252572535725457255572565725757258572595726057261572625726357264572655726657267572685726957270572715727257273572745727557276572775727857279572805728157282572835728457285572865728757288572895729057291572925729357294572955729657297572985729957300573015730257303573045730557306573075730857309573105731157312573135731457315573165731757318573195732057321573225732357324573255732657327573285732957330573315733257333573345733557336573375733857339573405734157342573435734457345573465734757348573495735057351573525735357354573555735657357573585735957360573615736257363573645736557366573675736857369573705737157372573735737457375573765737757378573795738057381573825738357384573855738657387573885738957390573915739257393573945739557396573975739857399574005740157402574035740457405574065740757408574095741057411574125741357414574155741657417574185741957420574215742257423574245742557426574275742857429574305743157432574335743457435574365743757438574395744057441574425744357444574455744657447574485744957450574515745257453574545745557456574575745857459574605746157462574635746457465574665746757468574695747057471574725747357474574755747657477574785747957480574815748257483574845748557486574875748857489574905749157492574935749457495574965749757498574995750057501575025750357504575055750657507575085750957510575115751257513575145751557516575175751857519575205752157522575235752457525575265752757528575295753057531575325753357534575355753657537575385753957540575415754257543575445754557546575475754857549575505755157552575535755457555575565755757558575595756057561575625756357564575655756657567575685756957570575715757257573575745757557576575775757857579575805758157582575835758457585575865758757588575895759057591575925759357594575955759657597575985759957600576015760257603576045760557606576075760857609576105761157612576135761457615576165761757618576195762057621576225762357624576255762657627576285762957630576315763257633576345763557636576375763857639576405764157642576435764457645576465764757648576495765057651576525765357654576555765657657576585765957660576615766257663576645766557666576675766857669576705767157672576735767457675576765767757678576795768057681576825768357684576855768657687576885768957690576915769257693576945769557696576975769857699577005770157702577035770457705577065770757708577095771057711577125771357714577155771657717577185771957720577215772257723577245772557726577275772857729577305773157732577335773457735577365773757738577395774057741577425774357744577455774657747577485774957750577515775257753577545775557756577575775857759577605776157762577635776457765577665776757768577695777057771577725777357774577755777657777577785777957780577815778257783577845778557786577875778857789577905779157792577935779457795577965779757798577995780057801578025780357804578055780657807578085780957810578115781257813578145781557816578175781857819578205782157822578235782457825578265782757828578295783057831578325783357834578355783657837578385783957840578415784257843578445784557846578475784857849578505785157852578535785457855578565785757858578595786057861578625786357864578655786657867578685786957870578715787257873578745787557876578775787857879578805788157882578835788457885578865788757888578895789057891578925789357894578955789657897578985789957900579015790257903579045790557906579075790857909579105791157912579135791457915579165791757918579195792057921579225792357924579255792657927579285792957930579315793257933579345793557936579375793857939579405794157942579435794457945579465794757948579495795057951579525795357954579555795657957579585795957960579615796257963579645796557966579675796857969579705797157972579735797457975579765797757978579795798057981579825798357984579855798657987579885798957990579915799257993579945799557996579975799857999580005800158002580035800458005580065800758008580095801058011580125801358014580155801658017580185801958020580215802258023580245802558026580275802858029580305803158032580335803458035580365803758038580395804058041580425804358044580455804658047580485804958050580515805258053580545805558056580575805858059580605806158062580635806458065580665806758068580695807058071580725807358074580755807658077580785807958080580815808258083580845808558086580875808858089580905809158092580935809458095580965809758098580995810058101581025810358104581055810658107581085810958110581115811258113581145811558116581175811858119581205812158122581235812458125581265812758128581295813058131581325813358134581355813658137581385813958140581415814258143581445814558146581475814858149581505815158152581535815458155581565815758158581595816058161581625816358164581655816658167581685816958170581715817258173581745817558176581775817858179581805818158182581835818458185581865818758188581895819058191581925819358194581955819658197581985819958200582015820258203582045820558206582075820858209582105821158212582135821458215582165821758218582195822058221582225822358224582255822658227582285822958230582315823258233582345823558236582375823858239582405824158242582435824458245582465824758248582495825058251582525825358254582555825658257582585825958260582615826258263582645826558266582675826858269582705827158272582735827458275582765827758278582795828058281582825828358284582855828658287582885828958290582915829258293582945829558296582975829858299583005830158302583035830458305583065830758308583095831058311583125831358314583155831658317583185831958320583215832258323583245832558326583275832858329583305833158332583335833458335583365833758338583395834058341583425834358344583455834658347583485834958350583515835258353583545835558356583575835858359583605836158362583635836458365583665836758368583695837058371583725837358374583755837658377583785837958380583815838258383583845838558386583875838858389583905839158392583935839458395583965839758398583995840058401584025840358404584055840658407584085840958410584115841258413584145841558416584175841858419584205842158422584235842458425584265842758428584295843058431584325843358434584355843658437584385843958440584415844258443584445844558446584475844858449584505845158452584535845458455584565845758458584595846058461584625846358464584655846658467584685846958470584715847258473584745847558476584775847858479584805848158482584835848458485584865848758488584895849058491584925849358494584955849658497584985849958500585015850258503585045850558506585075850858509585105851158512585135851458515585165851758518585195852058521585225852358524585255852658527585285852958530585315853258533585345853558536585375853858539585405854158542585435854458545585465854758548585495855058551585525855358554585555855658557585585855958560585615856258563585645856558566585675856858569585705857158572585735857458575585765857758578585795858058581585825858358584585855858658587585885858958590585915859258593585945859558596585975859858599586005860158602586035860458605586065860758608586095861058611586125861358614586155861658617586185861958620586215862258623586245862558626586275862858629586305863158632586335863458635586365863758638586395864058641586425864358644586455864658647586485864958650586515865258653586545865558656586575865858659586605866158662586635866458665586665866758668586695867058671586725867358674586755867658677586785867958680586815868258683586845868558686586875868858689586905869158692586935869458695586965869758698586995870058701587025870358704587055870658707587085870958710587115871258713587145871558716587175871858719587205872158722587235872458725587265872758728587295873058731587325873358734587355873658737587385873958740587415874258743587445874558746587475874858749587505875158752587535875458755587565875758758587595876058761587625876358764587655876658767587685876958770587715877258773587745877558776587775877858779587805878158782587835878458785587865878758788587895879058791587925879358794587955879658797587985879958800588015880258803588045880558806588075880858809588105881158812588135881458815588165881758818588195882058821588225882358824588255882658827588285882958830588315883258833588345883558836588375883858839588405884158842588435884458845588465884758848588495885058851588525885358854588555885658857588585885958860588615886258863588645886558866588675886858869588705887158872588735887458875588765887758878588795888058881588825888358884588855888658887588885888958890588915889258893588945889558896588975889858899589005890158902589035890458905589065890758908589095891058911589125891358914589155891658917589185891958920589215892258923589245892558926589275892858929589305893158932589335893458935589365893758938589395894058941589425894358944589455894658947589485894958950589515895258953589545895558956589575895858959589605896158962589635896458965589665896758968589695897058971589725897358974589755897658977589785897958980589815898258983589845898558986589875898858989589905899158992589935899458995589965899758998589995900059001590025900359004590055900659007590085900959010590115901259013590145901559016590175901859019590205902159022590235902459025590265902759028590295903059031590325903359034590355903659037590385903959040590415904259043590445904559046590475904859049590505905159052590535905459055590565905759058590595906059061590625906359064590655906659067590685906959070590715907259073590745907559076590775907859079590805908159082590835908459085590865908759088590895909059091590925909359094590955909659097590985909959100591015910259103591045910559106591075910859109591105911159112591135911459115591165911759118591195912059121591225912359124591255912659127591285912959130591315913259133591345913559136591375913859139591405914159142591435914459145591465914759148591495915059151591525915359154591555915659157591585915959160591615916259163591645916559166591675916859169591705917159172591735917459175591765917759178591795918059181591825918359184591855918659187591885918959190591915919259193591945919559196591975919859199592005920159202592035920459205592065920759208592095921059211592125921359214592155921659217592185921959220592215922259223592245922559226592275922859229592305923159232592335923459235592365923759238592395924059241592425924359244592455924659247592485924959250592515925259253592545925559256592575925859259592605926159262592635926459265592665926759268592695927059271592725927359274592755927659277592785927959280592815928259283592845928559286592875928859289592905929159292592935929459295592965929759298592995930059301593025930359304593055930659307593085930959310593115931259313593145931559316593175931859319593205932159322593235932459325593265932759328593295933059331593325933359334593355933659337593385933959340593415934259343593445934559346593475934859349593505935159352593535935459355593565935759358593595936059361593625936359364593655936659367593685936959370593715937259373593745937559376593775937859379593805938159382593835938459385593865938759388593895939059391593925939359394593955939659397593985939959400594015940259403594045940559406594075940859409594105941159412594135941459415594165941759418594195942059421594225942359424594255942659427594285942959430594315943259433594345943559436594375943859439594405944159442594435944459445594465944759448594495945059451594525945359454594555945659457594585945959460594615946259463594645946559466594675946859469594705947159472594735947459475594765947759478594795948059481594825948359484594855948659487594885948959490594915949259493594945949559496594975949859499595005950159502595035950459505595065950759508595095951059511595125951359514595155951659517595185951959520595215952259523595245952559526595275952859529595305953159532595335953459535595365953759538595395954059541595425954359544595455954659547595485954959550595515955259553595545955559556595575955859559595605956159562595635956459565595665956759568595695957059571595725957359574595755957659577595785957959580595815958259583595845958559586595875958859589595905959159592595935959459595595965959759598595995960059601596025960359604596055960659607596085960959610596115961259613596145961559616596175961859619596205962159622596235962459625596265962759628596295963059631596325963359634596355963659637596385963959640596415964259643596445964559646596475964859649596505965159652596535965459655596565965759658596595966059661596625966359664596655966659667596685966959670596715967259673596745967559676596775967859679596805968159682596835968459685596865968759688596895969059691596925969359694596955969659697596985969959700597015970259703597045970559706597075970859709597105971159712597135971459715597165971759718597195972059721597225972359724597255972659727597285972959730597315973259733597345973559736597375973859739597405974159742597435974459745597465974759748597495975059751597525975359754597555975659757597585975959760597615976259763597645976559766597675976859769597705977159772597735977459775597765977759778597795978059781597825978359784597855978659787597885978959790597915979259793597945979559796597975979859799598005980159802598035980459805598065980759808598095981059811598125981359814598155981659817598185981959820598215982259823598245982559826598275982859829598305983159832598335983459835598365983759838598395984059841598425984359844598455984659847598485984959850598515985259853598545985559856598575985859859598605986159862598635986459865598665986759868598695987059871598725987359874598755987659877598785987959880598815988259883598845988559886598875988859889598905989159892598935989459895598965989759898598995990059901599025990359904599055990659907599085990959910599115991259913599145991559916599175991859919599205992159922599235992459925599265992759928599295993059931599325993359934599355993659937599385993959940599415994259943599445994559946599475994859949599505995159952599535995459955599565995759958599595996059961599625996359964599655996659967599685996959970599715997259973599745997559976599775997859979599805998159982599835998459985599865998759988599895999059991599925999359994599955999659997599985999960000600016000260003600046000560006600076000860009600106001160012600136001460015600166001760018600196002060021600226002360024600256002660027600286002960030600316003260033600346003560036600376003860039600406004160042600436004460045600466004760048600496005060051600526005360054600556005660057600586005960060600616006260063600646006560066600676006860069600706007160072600736007460075600766007760078600796008060081600826008360084600856008660087600886008960090600916009260093600946009560096600976009860099601006010160102601036010460105601066010760108601096011060111601126011360114601156011660117601186011960120601216012260123601246012560126601276012860129601306013160132601336013460135601366013760138601396014060141601426014360144601456014660147601486014960150601516015260153601546015560156601576015860159601606016160162601636016460165601666016760168601696017060171601726017360174601756017660177601786017960180601816018260183601846018560186601876018860189601906019160192601936019460195601966019760198601996020060201602026020360204602056020660207602086020960210602116021260213602146021560216602176021860219602206022160222602236022460225602266022760228602296023060231602326023360234602356023660237602386023960240602416024260243602446024560246602476024860249602506025160252602536025460255602566025760258602596026060261602626026360264602656026660267602686026960270602716027260273602746027560276602776027860279602806028160282602836028460285602866028760288602896029060291602926029360294602956029660297602986029960300603016030260303603046030560306603076030860309603106031160312603136031460315603166031760318603196032060321603226032360324603256032660327603286032960330603316033260333603346033560336603376033860339603406034160342603436034460345603466034760348603496035060351603526035360354603556035660357603586035960360603616036260363603646036560366603676036860369603706037160372603736037460375603766037760378603796038060381603826038360384603856038660387603886038960390603916039260393603946039560396603976039860399604006040160402604036040460405604066040760408604096041060411604126041360414604156041660417604186041960420604216042260423604246042560426604276042860429604306043160432604336043460435604366043760438604396044060441604426044360444604456044660447604486044960450604516045260453604546045560456604576045860459604606046160462604636046460465604666046760468604696047060471604726047360474604756047660477604786047960480604816048260483604846048560486604876048860489604906049160492604936049460495604966049760498604996050060501605026050360504605056050660507605086050960510605116051260513605146051560516605176051860519605206052160522605236052460525605266052760528605296053060531605326053360534605356053660537605386053960540605416054260543605446054560546605476054860549605506055160552605536055460555605566055760558605596056060561605626056360564605656056660567605686056960570605716057260573605746057560576605776057860579605806058160582605836058460585605866058760588605896059060591605926059360594605956059660597605986059960600606016060260603606046060560606606076060860609606106061160612606136061460615606166061760618606196062060621606226062360624606256062660627606286062960630606316063260633606346063560636606376063860639606406064160642606436064460645606466064760648606496065060651606526065360654606556065660657606586065960660606616066260663606646066560666606676066860669606706067160672606736067460675606766067760678606796068060681606826068360684606856068660687606886068960690606916069260693606946069560696606976069860699607006070160702607036070460705607066070760708607096071060711607126071360714607156071660717607186071960720607216072260723607246072560726607276072860729607306073160732607336073460735607366073760738607396074060741607426074360744607456074660747607486074960750607516075260753607546075560756607576075860759607606076160762607636076460765607666076760768607696077060771607726077360774607756077660777607786077960780607816078260783607846078560786607876078860789607906079160792607936079460795607966079760798607996080060801608026080360804608056080660807608086080960810608116081260813608146081560816608176081860819608206082160822608236082460825608266082760828608296083060831608326083360834608356083660837608386083960840608416084260843608446084560846608476084860849608506085160852608536085460855608566085760858608596086060861608626086360864608656086660867608686086960870608716087260873608746087560876608776087860879608806088160882608836088460885608866088760888608896089060891608926089360894608956089660897608986089960900609016090260903609046090560906609076090860909609106091160912609136091460915609166091760918609196092060921609226092360924609256092660927609286092960930609316093260933609346093560936609376093860939609406094160942609436094460945609466094760948609496095060951609526095360954609556095660957609586095960960609616096260963609646096560966609676096860969609706097160972609736097460975609766097760978609796098060981609826098360984609856098660987609886098960990609916099260993609946099560996609976099860999610006100161002610036100461005610066100761008610096101061011610126101361014610156101661017610186101961020610216102261023610246102561026610276102861029610306103161032610336103461035610366103761038610396104061041610426104361044610456104661047610486104961050610516105261053610546105561056610576105861059610606106161062610636106461065610666106761068610696107061071610726107361074610756107661077610786107961080610816108261083610846108561086610876108861089610906109161092610936109461095610966109761098610996110061101611026110361104611056110661107611086110961110611116111261113611146111561116611176111861119611206112161122611236112461125611266112761128611296113061131611326113361134611356113661137611386113961140611416114261143611446114561146611476114861149611506115161152611536115461155611566115761158611596116061161611626116361164611656116661167611686116961170611716117261173611746117561176611776117861179611806118161182611836118461185611866118761188611896119061191611926119361194611956119661197611986119961200612016120261203612046120561206612076120861209612106121161212612136121461215612166121761218612196122061221612226122361224612256122661227612286122961230612316123261233612346123561236612376123861239612406124161242612436124461245612466124761248612496125061251612526125361254612556125661257612586125961260612616126261263612646126561266612676126861269612706127161272612736127461275612766127761278612796128061281612826128361284612856128661287612886128961290612916129261293612946129561296612976129861299613006130161302613036130461305613066130761308613096131061311613126131361314613156131661317613186131961320613216132261323613246132561326613276132861329613306133161332613336133461335613366133761338613396134061341613426134361344613456134661347613486134961350613516135261353613546135561356613576135861359613606136161362613636136461365613666136761368613696137061371613726137361374613756137661377613786137961380613816138261383613846138561386613876138861389613906139161392613936139461395613966139761398613996140061401614026140361404614056140661407614086140961410614116141261413614146141561416614176141861419614206142161422614236142461425614266142761428614296143061431614326143361434614356143661437614386143961440614416144261443614446144561446614476144861449614506145161452614536145461455614566145761458614596146061461614626146361464614656146661467614686146961470614716147261473614746147561476614776147861479614806148161482614836148461485614866148761488614896149061491614926149361494614956149661497614986149961500615016150261503615046150561506615076150861509615106151161512615136151461515615166151761518615196152061521615226152361524615256152661527615286152961530615316153261533615346153561536615376153861539615406154161542615436154461545615466154761548615496155061551615526155361554615556155661557615586155961560615616156261563615646156561566615676156861569615706157161572615736157461575615766157761578615796158061581615826158361584615856158661587615886158961590615916159261593615946159561596615976159861599616006160161602616036160461605616066160761608616096161061611616126161361614616156161661617616186161961620616216162261623616246162561626616276162861629616306163161632616336163461635616366163761638616396164061641616426164361644616456164661647616486164961650616516165261653616546165561656616576165861659616606166161662616636166461665616666166761668616696167061671616726167361674616756167661677616786167961680616816168261683616846168561686616876168861689616906169161692616936169461695616966169761698616996170061701617026170361704617056170661707617086170961710617116171261713617146171561716617176171861719617206172161722617236172461725617266172761728617296173061731617326173361734617356173661737617386173961740617416174261743617446174561746617476174861749617506175161752617536175461755617566175761758617596176061761617626176361764617656176661767617686176961770617716177261773617746177561776617776177861779617806178161782617836178461785617866178761788617896179061791617926179361794617956179661797617986179961800618016180261803618046180561806618076180861809618106181161812618136181461815618166181761818618196182061821618226182361824618256182661827618286182961830618316183261833618346183561836618376183861839618406184161842618436184461845618466184761848618496185061851618526185361854618556185661857618586185961860618616186261863618646186561866618676186861869618706187161872618736187461875618766187761878618796188061881618826188361884618856188661887618886188961890618916189261893618946189561896618976189861899619006190161902619036190461905619066190761908619096191061911619126191361914619156191661917619186191961920619216192261923619246192561926619276192861929619306193161932619336193461935619366193761938619396194061941619426194361944619456194661947619486194961950619516195261953619546195561956619576195861959619606196161962619636196461965619666196761968619696197061971619726197361974619756197661977619786197961980619816198261983619846198561986619876198861989619906199161992619936199461995619966199761998619996200062001620026200362004620056200662007620086200962010620116201262013620146201562016620176201862019620206202162022620236202462025620266202762028620296203062031620326203362034620356203662037620386203962040620416204262043620446204562046620476204862049620506205162052620536205462055620566205762058620596206062061620626206362064620656206662067620686206962070620716207262073620746207562076620776207862079620806208162082620836208462085620866208762088620896209062091620926209362094620956209662097620986209962100621016210262103621046210562106621076210862109621106211162112621136211462115621166211762118621196212062121621226212362124621256212662127621286212962130621316213262133621346213562136621376213862139621406214162142621436214462145621466214762148621496215062151621526215362154621556215662157621586215962160621616216262163621646216562166621676216862169621706217162172621736217462175621766217762178621796218062181621826218362184621856218662187621886218962190621916219262193621946219562196621976219862199622006220162202622036220462205622066220762208622096221062211622126221362214622156221662217622186221962220622216222262223622246222562226622276222862229622306223162232622336223462235622366223762238622396224062241622426224362244622456224662247622486224962250622516225262253622546225562256622576225862259622606226162262622636226462265622666226762268622696227062271622726227362274622756227662277622786227962280622816228262283622846228562286622876228862289622906229162292622936229462295622966229762298622996230062301623026230362304623056230662307623086230962310623116231262313623146231562316623176231862319623206232162322623236232462325623266232762328623296233062331623326233362334623356233662337623386233962340623416234262343623446234562346623476234862349623506235162352623536235462355623566235762358623596236062361623626236362364623656236662367623686236962370623716237262373623746237562376623776237862379623806238162382623836238462385623866238762388623896239062391623926239362394623956239662397623986239962400624016240262403624046240562406624076240862409624106241162412624136241462415624166241762418624196242062421624226242362424624256242662427624286242962430624316243262433624346243562436624376243862439624406244162442624436244462445624466244762448624496245062451624526245362454624556245662457624586245962460624616246262463624646246562466624676246862469624706247162472624736247462475624766247762478624796248062481624826248362484624856248662487624886248962490624916249262493624946249562496624976249862499625006250162502625036250462505625066250762508625096251062511625126251362514625156251662517625186251962520625216252262523625246252562526625276252862529625306253162532625336253462535625366253762538625396254062541625426254362544625456254662547625486254962550625516255262553625546255562556625576255862559625606256162562625636256462565625666256762568625696257062571625726257362574625756257662577625786257962580625816258262583625846258562586625876258862589625906259162592625936259462595625966259762598625996260062601626026260362604626056260662607626086260962610626116261262613626146261562616626176261862619626206262162622626236262462625626266262762628626296263062631626326263362634626356263662637626386263962640626416264262643626446264562646626476264862649626506265162652626536265462655626566265762658626596266062661626626266362664626656266662667626686266962670626716267262673626746267562676626776267862679626806268162682626836268462685626866268762688626896269062691626926269362694626956269662697626986269962700627016270262703627046270562706627076270862709627106271162712627136271462715627166271762718627196272062721627226272362724627256272662727627286272962730627316273262733627346273562736627376273862739627406274162742627436274462745627466274762748627496275062751627526275362754627556275662757627586275962760627616276262763627646276562766627676276862769627706277162772627736277462775627766277762778627796278062781627826278362784627856278662787627886278962790627916279262793627946279562796627976279862799628006280162802628036280462805628066280762808628096281062811628126281362814628156281662817628186281962820628216282262823628246282562826628276282862829628306283162832628336283462835628366283762838628396284062841628426284362844628456284662847628486284962850628516285262853628546285562856628576285862859628606286162862628636286462865628666286762868628696287062871628726287362874628756287662877628786287962880628816288262883628846288562886628876288862889628906289162892628936289462895628966289762898628996290062901629026290362904629056290662907629086290962910629116291262913629146291562916629176291862919629206292162922629236292462925629266292762928629296293062931629326293362934629356293662937629386293962940629416294262943629446294562946629476294862949629506295162952629536295462955629566295762958629596296062961629626296362964629656296662967629686296962970629716297262973629746297562976629776297862979629806298162982629836298462985629866298762988629896299062991629926299362994629956299662997629986299963000630016300263003630046300563006630076300863009630106301163012630136301463015630166301763018630196302063021630226302363024630256302663027630286302963030630316303263033630346303563036630376303863039630406304163042630436304463045630466304763048630496305063051630526305363054630556305663057630586305963060630616306263063630646306563066630676306863069630706307163072630736307463075630766307763078630796308063081630826308363084630856308663087630886308963090630916309263093630946309563096630976309863099631006310163102631036310463105631066310763108631096311063111631126311363114631156311663117631186311963120631216312263123631246312563126631276312863129631306313163132631336313463135631366313763138631396314063141631426314363144631456314663147631486314963150631516315263153631546315563156631576315863159631606316163162631636316463165631666316763168631696317063171631726317363174631756317663177631786317963180631816318263183631846318563186631876318863189631906319163192631936319463195631966319763198631996320063201632026320363204632056320663207632086320963210632116321263213632146321563216632176321863219632206322163222632236322463225632266322763228632296323063231632326323363234632356323663237632386323963240632416324263243632446324563246632476324863249632506325163252632536325463255632566325763258632596326063261632626326363264632656326663267632686326963270632716327263273632746327563276632776327863279632806328163282632836328463285632866328763288632896329063291632926329363294632956329663297632986329963300633016330263303633046330563306633076330863309633106331163312633136331463315633166331763318633196332063321633226332363324633256332663327633286332963330633316333263333633346333563336633376333863339633406334163342633436334463345633466334763348633496335063351633526335363354633556335663357633586335963360633616336263363633646336563366633676336863369633706337163372633736337463375633766337763378633796338063381633826338363384633856338663387633886338963390633916339263393633946339563396633976339863399634006340163402634036340463405634066340763408634096341063411634126341363414634156341663417634186341963420634216342263423634246342563426634276342863429634306343163432634336343463435634366343763438634396344063441634426344363444634456344663447634486344963450634516345263453634546345563456634576345863459634606346163462634636346463465634666346763468634696347063471634726347363474634756347663477634786347963480634816348263483634846348563486634876348863489634906349163492634936349463495634966349763498634996350063501635026350363504635056350663507635086350963510635116351263513635146351563516635176351863519635206352163522635236352463525635266352763528635296353063531635326353363534635356353663537635386353963540635416354263543635446354563546635476354863549635506355163552635536355463555635566355763558635596356063561635626356363564635656356663567635686356963570635716357263573635746357563576635776357863579635806358163582635836358463585635866358763588635896359063591635926359363594635956359663597635986359963600636016360263603636046360563606636076360863609636106361163612636136361463615636166361763618636196362063621636226362363624636256362663627636286362963630636316363263633636346363563636636376363863639636406364163642636436364463645636466364763648636496365063651636526365363654636556365663657636586365963660636616366263663636646366563666636676366863669636706367163672636736367463675636766367763678636796368063681636826368363684636856368663687636886368963690636916369263693636946369563696636976369863699637006370163702637036370463705637066370763708637096371063711637126371363714637156371663717637186371963720637216372263723637246372563726637276372863729637306373163732637336373463735637366373763738637396374063741637426374363744637456374663747637486374963750637516375263753637546375563756637576375863759637606376163762637636376463765637666376763768637696377063771637726377363774637756377663777637786377963780637816378263783637846378563786637876378863789637906379163792637936379463795637966379763798637996380063801638026380363804638056380663807638086380963810638116381263813638146381563816638176381863819638206382163822638236382463825638266382763828638296383063831638326383363834638356383663837638386383963840638416384263843638446384563846638476384863849638506385163852638536385463855638566385763858638596386063861638626386363864638656386663867638686386963870638716387263873638746387563876638776387863879638806388163882638836388463885638866388763888638896389063891638926389363894638956389663897638986389963900639016390263903639046390563906639076390863909639106391163912639136391463915639166391763918639196392063921639226392363924639256392663927639286392963930639316393263933639346393563936639376393863939639406394163942639436394463945639466394763948639496395063951639526395363954639556395663957639586395963960639616396263963639646396563966639676396863969639706397163972639736397463975639766397763978639796398063981639826398363984639856398663987639886398963990639916399263993639946399563996639976399863999640006400164002640036400464005640066400764008640096401064011640126401364014640156401664017640186401964020640216402264023640246402564026640276402864029640306403164032640336403464035640366403764038640396404064041640426404364044640456404664047640486404964050640516405264053640546405564056640576405864059640606406164062640636406464065640666406764068640696407064071640726407364074640756407664077640786407964080640816408264083640846408564086640876408864089640906409164092640936409464095640966409764098640996410064101641026410364104641056410664107641086410964110641116411264113641146411564116641176411864119641206412164122641236412464125641266412764128641296413064131641326413364134641356413664137641386413964140641416414264143641446414564146641476414864149641506415164152641536415464155641566415764158641596416064161641626416364164641656416664167641686416964170641716417264173641746417564176641776417864179641806418164182641836418464185641866418764188641896419064191641926419364194641956419664197641986419964200642016420264203642046420564206642076420864209642106421164212642136421464215642166421764218642196422064221642226422364224642256422664227642286422964230642316423264233642346423564236642376423864239642406424164242642436424464245642466424764248642496425064251642526425364254642556425664257642586425964260642616426264263642646426564266642676426864269642706427164272642736427464275642766427764278642796428064281642826428364284642856428664287642886428964290642916429264293642946429564296642976429864299643006430164302643036430464305643066430764308643096431064311643126431364314643156431664317643186431964320643216432264323643246432564326643276432864329643306433164332643336433464335643366433764338643396434064341643426434364344643456434664347643486434964350643516435264353643546435564356643576435864359643606436164362643636436464365643666436764368643696437064371643726437364374643756437664377643786437964380643816438264383643846438564386643876438864389643906439164392643936439464395643966439764398643996440064401644026440364404644056440664407644086440964410644116441264413644146441564416644176441864419644206442164422644236442464425644266442764428644296443064431644326443364434644356443664437644386443964440644416444264443644446444564446644476444864449644506445164452644536445464455644566445764458644596446064461644626446364464644656446664467644686446964470644716447264473644746447564476644776447864479644806448164482644836448464485644866448764488644896449064491644926449364494644956449664497644986449964500645016450264503645046450564506645076450864509645106451164512645136451464515645166451764518645196452064521645226452364524645256452664527645286452964530645316453264533645346453564536645376453864539645406454164542645436454464545645466454764548645496455064551645526455364554645556455664557645586455964560645616456264563645646456564566645676456864569645706457164572645736457464575645766457764578645796458064581645826458364584645856458664587645886458964590645916459264593645946459564596645976459864599646006460164602646036460464605646066460764608646096461064611646126461364614646156461664617646186461964620646216462264623646246462564626646276462864629646306463164632646336463464635646366463764638646396464064641646426464364644646456464664647646486464964650646516465264653646546465564656646576465864659646606466164662646636466464665646666466764668646696467064671646726467364674646756467664677646786467964680646816468264683646846468564686646876468864689646906469164692646936469464695646966469764698646996470064701647026470364704647056470664707647086470964710647116471264713647146471564716647176471864719647206472164722647236472464725647266472764728647296473064731647326473364734647356473664737647386473964740647416474264743647446474564746647476474864749647506475164752647536475464755647566475764758647596476064761647626476364764647656476664767647686476964770647716477264773647746477564776647776477864779647806478164782647836478464785647866478764788647896479064791647926479364794647956479664797647986479964800648016480264803648046480564806648076480864809648106481164812648136481464815648166481764818648196482064821648226482364824648256482664827648286482964830648316483264833648346483564836648376483864839648406484164842648436484464845648466484764848648496485064851648526485364854648556485664857648586485964860648616486264863648646486564866648676486864869648706487164872648736487464875648766487764878648796488064881648826488364884648856488664887648886488964890648916489264893648946489564896648976489864899649006490164902649036490464905649066490764908649096491064911649126491364914649156491664917649186491964920649216492264923649246492564926649276492864929649306493164932649336493464935649366493764938649396494064941649426494364944649456494664947649486494964950649516495264953649546495564956649576495864959649606496164962649636496464965649666496764968649696497064971649726497364974649756497664977649786497964980649816498264983649846498564986649876498864989649906499164992649936499464995649966499764998649996500065001650026500365004650056500665007650086500965010650116501265013650146501565016650176501865019650206502165022650236502465025650266502765028650296503065031650326503365034650356503665037650386503965040650416504265043650446504565046650476504865049650506505165052650536505465055650566505765058650596506065061650626506365064650656506665067650686506965070650716507265073650746507565076650776507865079650806508165082650836508465085650866508765088650896509065091650926509365094650956509665097650986509965100651016510265103651046510565106651076510865109651106511165112651136511465115651166511765118651196512065121651226512365124651256512665127651286512965130651316513265133651346513565136651376513865139651406514165142651436514465145651466514765148651496515065151651526515365154651556515665157651586515965160651616516265163651646516565166651676516865169651706517165172651736517465175651766517765178651796518065181651826518365184651856518665187651886518965190651916519265193651946519565196651976519865199652006520165202652036520465205652066520765208652096521065211652126521365214652156521665217652186521965220652216522265223652246522565226652276522865229652306523165232652336523465235652366523765238652396524065241652426524365244652456524665247652486524965250652516525265253652546525565256652576525865259652606526165262652636526465265652666526765268652696527065271652726527365274652756527665277652786527965280652816528265283652846528565286652876528865289652906529165292652936529465295652966529765298652996530065301653026530365304653056530665307653086530965310653116531265313653146531565316653176531865319653206532165322653236532465325653266532765328653296533065331653326533365334653356533665337653386533965340653416534265343653446534565346653476534865349653506535165352653536535465355653566535765358653596536065361653626536365364653656536665367653686536965370653716537265373653746537565376653776537865379653806538165382653836538465385653866538765388653896539065391653926539365394653956539665397653986539965400654016540265403654046540565406654076540865409654106541165412654136541465415654166541765418654196542065421654226542365424654256542665427654286542965430654316543265433654346543565436654376543865439654406544165442654436544465445654466544765448654496545065451654526545365454654556545665457654586545965460654616546265463654646546565466654676546865469654706547165472654736547465475654766547765478654796548065481654826548365484654856548665487654886548965490654916549265493654946549565496654976549865499655006550165502655036550465505655066550765508655096551065511655126551365514655156551665517655186551965520655216552265523655246552565526655276552865529655306553165532655336553465535655366553765538655396554065541655426554365544655456554665547655486554965550655516555265553655546555565556655576555865559655606556165562655636556465565655666556765568655696557065571655726557365574655756557665577655786557965580655816558265583655846558565586655876558865589655906559165592655936559465595655966559765598655996560065601656026560365604656056560665607656086560965610656116561265613656146561565616656176561865619656206562165622656236562465625656266562765628656296563065631656326563365634656356563665637656386563965640656416564265643656446564565646656476564865649656506565165652656536565465655656566565765658656596566065661656626566365664656656566665667656686566965670656716567265673656746567565676656776567865679656806568165682656836568465685656866568765688656896569065691656926569365694656956569665697656986569965700657016570265703657046570565706657076570865709657106571165712657136571465715657166571765718657196572065721657226572365724657256572665727657286572965730657316573265733657346573565736657376573865739657406574165742657436574465745657466574765748657496575065751657526575365754657556575665757657586575965760657616576265763657646576565766657676576865769657706577165772657736577465775657766577765778657796578065781657826578365784657856578665787657886578965790657916579265793657946579565796657976579865799658006580165802658036580465805658066580765808658096581065811658126581365814658156581665817658186581965820658216582265823658246582565826658276582865829658306583165832658336583465835658366583765838658396584065841658426584365844658456584665847658486584965850658516585265853658546585565856658576585865859658606586165862658636586465865658666586765868658696587065871658726587365874658756587665877658786587965880658816588265883658846588565886658876588865889658906589165892658936589465895658966589765898658996590065901659026590365904659056590665907659086590965910659116591265913659146591565916659176591865919659206592165922659236592465925659266592765928659296593065931659326593365934659356593665937659386593965940659416594265943659446594565946659476594865949659506595165952659536595465955659566595765958659596596065961659626596365964659656596665967659686596965970659716597265973659746597565976659776597865979659806598165982659836598465985659866598765988659896599065991659926599365994659956599665997659986599966000660016600266003660046600566006660076600866009660106601166012660136601466015660166601766018660196602066021660226602366024660256602666027660286602966030660316603266033660346603566036660376603866039660406604166042660436604466045660466604766048660496605066051660526605366054660556605666057660586605966060660616606266063660646606566066660676606866069660706607166072660736607466075660766607766078660796608066081660826608366084660856608666087660886608966090660916609266093660946609566096660976609866099661006610166102661036610466105661066610766108661096611066111661126611366114661156611666117661186611966120661216612266123661246612566126661276612866129661306613166132661336613466135661366613766138661396614066141661426614366144661456614666147661486614966150661516615266153661546615566156661576615866159661606616166162661636616466165661666616766168661696617066171661726617366174661756617666177661786617966180661816618266183661846618566186661876618866189661906619166192661936619466195661966619766198661996620066201662026620366204662056620666207662086620966210662116621266213662146621566216662176621866219662206622166222662236622466225662266622766228662296623066231662326623366234662356623666237662386623966240662416624266243662446624566246662476624866249662506625166252662536625466255662566625766258662596626066261662626626366264662656626666267662686626966270662716627266273662746627566276662776627866279662806628166282662836628466285662866628766288662896629066291662926629366294662956629666297662986629966300663016630266303663046630566306663076630866309663106631166312663136631466315663166631766318663196632066321663226632366324663256632666327663286632966330663316633266333663346633566336663376633866339663406634166342663436634466345663466634766348663496635066351663526635366354663556635666357663586635966360663616636266363663646636566366663676636866369663706637166372663736637466375663766637766378663796638066381663826638366384663856638666387663886638966390663916639266393663946639566396663976639866399664006640166402664036640466405664066640766408664096641066411664126641366414664156641666417664186641966420664216642266423664246642566426664276642866429664306643166432664336643466435664366643766438664396644066441664426644366444664456644666447664486644966450664516645266453664546645566456664576645866459664606646166462664636646466465664666646766468664696647066471664726647366474664756647666477664786647966480664816648266483664846648566486664876648866489664906649166492664936649466495664966649766498664996650066501665026650366504665056650666507665086650966510665116651266513665146651566516665176651866519665206652166522665236652466525665266652766528665296653066531665326653366534665356653666537665386653966540665416654266543665446654566546665476654866549665506655166552665536655466555665566655766558665596656066561665626656366564665656656666567665686656966570665716657266573665746657566576665776657866579665806658166582665836658466585665866658766588665896659066591665926659366594665956659666597665986659966600666016660266603666046660566606666076660866609666106661166612666136661466615666166661766618666196662066621666226662366624666256662666627666286662966630666316663266633666346663566636666376663866639666406664166642666436664466645666466664766648666496665066651666526665366654666556665666657666586665966660666616666266663666646666566666666676666866669666706667166672666736667466675666766667766678666796668066681666826668366684666856668666687666886668966690666916669266693666946669566696666976669866699667006670166702667036670466705667066670766708667096671066711667126671366714667156671666717667186671966720667216672266723667246672566726667276672866729667306673166732667336673466735667366673766738667396674066741667426674366744667456674666747667486674966750667516675266753667546675566756667576675866759667606676166762667636676466765667666676766768667696677066771667726677366774667756677666777667786677966780667816678266783667846678566786667876678866789667906679166792667936679466795667966679766798667996680066801668026680366804668056680666807668086680966810668116681266813668146681566816668176681866819668206682166822668236682466825668266682766828668296683066831668326683366834668356683666837668386683966840668416684266843668446684566846668476684866849668506685166852668536685466855668566685766858668596686066861668626686366864668656686666867668686686966870668716687266873668746687566876668776687866879668806688166882668836688466885668866688766888668896689066891668926689366894668956689666897668986689966900669016690266903669046690566906669076690866909669106691166912669136691466915669166691766918669196692066921669226692366924669256692666927669286692966930669316693266933669346693566936669376693866939669406694166942669436694466945669466694766948669496695066951669526695366954669556695666957669586695966960669616696266963669646696566966669676696866969669706697166972669736697466975669766697766978669796698066981669826698366984669856698666987669886698966990669916699266993669946699566996669976699866999670006700167002670036700467005670066700767008670096701067011670126701367014670156701667017670186701967020670216702267023670246702567026670276702867029670306703167032670336703467035670366703767038670396704067041670426704367044670456704667047670486704967050670516705267053670546705567056670576705867059670606706167062670636706467065670666706767068670696707067071670726707367074670756707667077670786707967080670816708267083670846708567086670876708867089670906709167092670936709467095670966709767098670996710067101671026710367104671056710667107671086710967110671116711267113671146711567116671176711867119671206712167122671236712467125671266712767128671296713067131671326713367134671356713667137671386713967140671416714267143671446714567146671476714867149671506715167152671536715467155671566715767158671596716067161671626716367164671656716667167671686716967170671716717267173671746717567176671776717867179671806718167182671836718467185671866718767188671896719067191671926719367194671956719667197671986719967200672016720267203672046720567206672076720867209672106721167212672136721467215672166721767218672196722067221672226722367224672256722667227672286722967230672316723267233672346723567236672376723867239672406724167242672436724467245672466724767248672496725067251672526725367254672556725667257672586725967260672616726267263672646726567266672676726867269672706727167272672736727467275672766727767278672796728067281672826728367284672856728667287672886728967290672916729267293672946729567296672976729867299673006730167302673036730467305673066730767308673096731067311673126731367314673156731667317673186731967320673216732267323673246732567326673276732867329673306733167332673336733467335673366733767338673396734067341673426734367344673456734667347673486734967350673516735267353673546735567356673576735867359673606736167362673636736467365673666736767368673696737067371673726737367374673756737667377673786737967380673816738267383673846738567386673876738867389673906739167392673936739467395673966739767398673996740067401674026740367404674056740667407674086740967410674116741267413674146741567416674176741867419674206742167422674236742467425674266742767428674296743067431674326743367434674356743667437674386743967440674416744267443674446744567446674476744867449674506745167452674536745467455674566745767458674596746067461674626746367464674656746667467674686746967470674716747267473674746747567476674776747867479674806748167482674836748467485674866748767488674896749067491674926749367494674956749667497674986749967500675016750267503675046750567506675076750867509675106751167512675136751467515675166751767518675196752067521675226752367524675256752667527675286752967530675316753267533675346753567536675376753867539675406754167542675436754467545675466754767548675496755067551675526755367554675556755667557675586755967560675616756267563675646756567566675676756867569675706757167572675736757467575675766757767578675796758067581675826758367584675856758667587675886758967590675916759267593675946759567596675976759867599676006760167602676036760467605676066760767608676096761067611676126761367614676156761667617676186761967620676216762267623676246762567626676276762867629676306763167632676336763467635676366763767638676396764067641676426764367644676456764667647676486764967650676516765267653676546765567656676576765867659676606766167662676636766467665676666766767668676696767067671676726767367674676756767667677676786767967680676816768267683676846768567686676876768867689676906769167692676936769467695676966769767698676996770067701677026770367704677056770667707677086770967710677116771267713677146771567716677176771867719677206772167722677236772467725677266772767728677296773067731677326773367734677356773667737677386773967740677416774267743677446774567746677476774867749677506775167752677536775467755677566775767758677596776067761677626776367764677656776667767677686776967770677716777267773677746777567776677776777867779677806778167782677836778467785677866778767788677896779067791677926779367794677956779667797677986779967800678016780267803678046780567806678076780867809678106781167812678136781467815678166781767818678196782067821678226782367824678256782667827678286782967830678316783267833678346783567836678376783867839678406784167842678436784467845678466784767848678496785067851678526785367854678556785667857678586785967860678616786267863678646786567866678676786867869678706787167872678736787467875678766787767878678796788067881678826788367884678856788667887678886788967890678916789267893678946789567896678976789867899679006790167902679036790467905679066790767908679096791067911679126791367914679156791667917679186791967920679216792267923679246792567926679276792867929679306793167932679336793467935679366793767938679396794067941679426794367944679456794667947679486794967950679516795267953679546795567956679576795867959679606796167962679636796467965679666796767968679696797067971679726797367974679756797667977679786797967980679816798267983679846798567986679876798867989679906799167992679936799467995679966799767998679996800068001680026800368004680056800668007680086800968010680116801268013680146801568016680176801868019680206802168022680236802468025680266802768028680296803068031680326803368034680356803668037680386803968040680416804268043680446804568046680476804868049680506805168052680536805468055680566805768058680596806068061680626806368064680656806668067680686806968070680716807268073680746807568076680776807868079680806808168082680836808468085680866808768088680896809068091680926809368094680956809668097680986809968100681016810268103681046810568106681076810868109681106811168112681136811468115681166811768118681196812068121681226812368124681256812668127681286812968130681316813268133681346813568136681376813868139681406814168142681436814468145681466814768148681496815068151681526815368154681556815668157681586815968160681616816268163681646816568166681676816868169681706817168172681736817468175681766817768178681796818068181681826818368184681856818668187681886818968190681916819268193681946819568196681976819868199682006820168202682036820468205682066820768208682096821068211682126821368214682156821668217682186821968220682216822268223682246822568226682276822868229682306823168232682336823468235682366823768238682396824068241682426824368244682456824668247682486824968250682516825268253682546825568256682576825868259682606826168262682636826468265682666826768268682696827068271682726827368274682756827668277682786827968280682816828268283682846828568286682876828868289682906829168292682936829468295682966829768298682996830068301683026830368304683056830668307683086830968310683116831268313683146831568316683176831868319683206832168322683236832468325683266832768328683296833068331683326833368334683356833668337683386833968340683416834268343683446834568346683476834868349683506835168352683536835468355683566835768358683596836068361683626836368364683656836668367683686836968370683716837268373683746837568376683776837868379683806838168382683836838468385683866838768388683896839068391683926839368394683956839668397683986839968400684016840268403684046840568406684076840868409684106841168412684136841468415684166841768418684196842068421684226842368424684256842668427684286842968430684316843268433684346843568436684376843868439684406844168442684436844468445684466844768448684496845068451684526845368454684556845668457684586845968460684616846268463684646846568466684676846868469684706847168472684736847468475684766847768478684796848068481684826848368484684856848668487684886848968490684916849268493684946849568496684976849868499685006850168502685036850468505685066850768508685096851068511685126851368514685156851668517685186851968520685216852268523685246852568526685276852868529685306853168532685336853468535685366853768538685396854068541685426854368544685456854668547685486854968550685516855268553685546855568556685576855868559685606856168562685636856468565685666856768568685696857068571685726857368574685756857668577685786857968580685816858268583685846858568586685876858868589685906859168592685936859468595685966859768598685996860068601686026860368604686056860668607686086860968610686116861268613686146861568616686176861868619686206862168622686236862468625686266862768628686296863068631686326863368634686356863668637686386863968640686416864268643686446864568646686476864868649686506865168652686536865468655686566865768658686596866068661686626866368664686656866668667686686866968670686716867268673686746867568676686776867868679686806868168682686836868468685686866868768688686896869068691686926869368694686956869668697686986869968700687016870268703687046870568706687076870868709687106871168712687136871468715687166871768718687196872068721687226872368724687256872668727687286872968730687316873268733687346873568736687376873868739687406874168742687436874468745687466874768748687496875068751687526875368754687556875668757687586875968760687616876268763687646876568766687676876868769687706877168772687736877468775687766877768778687796878068781687826878368784687856878668787687886878968790687916879268793687946879568796687976879868799688006880168802688036880468805688066880768808688096881068811688126881368814688156881668817688186881968820688216882268823688246882568826688276882868829688306883168832688336883468835688366883768838688396884068841688426884368844688456884668847688486884968850688516885268853688546885568856688576885868859688606886168862688636886468865688666886768868688696887068871688726887368874688756887668877688786887968880688816888268883688846888568886688876888868889688906889168892688936889468895688966889768898688996890068901689026890368904689056890668907689086890968910689116891268913689146891568916689176891868919689206892168922689236892468925689266892768928689296893068931689326893368934689356893668937689386893968940689416894268943689446894568946689476894868949689506895168952689536895468955689566895768958689596896068961689626896368964689656896668967689686896968970689716897268973689746897568976689776897868979689806898168982689836898468985689866898768988689896899068991689926899368994689956899668997689986899969000690016900269003690046900569006690076900869009690106901169012690136901469015690166901769018690196902069021690226902369024690256902669027690286902969030690316903269033690346903569036690376903869039690406904169042690436904469045690466904769048690496905069051690526905369054690556905669057690586905969060690616906269063690646906569066690676906869069690706907169072690736907469075690766907769078690796908069081690826908369084690856908669087690886908969090690916909269093690946909569096690976909869099691006910169102691036910469105691066910769108691096911069111691126911369114691156911669117691186911969120691216912269123691246912569126691276912869129691306913169132691336913469135691366913769138691396914069141691426914369144691456914669147691486914969150691516915269153691546915569156691576915869159691606916169162691636916469165691666916769168691696917069171691726917369174691756917669177691786917969180691816918269183691846918569186691876918869189691906919169192691936919469195691966919769198691996920069201692026920369204692056920669207692086920969210692116921269213692146921569216692176921869219692206922169222692236922469225692266922769228692296923069231692326923369234692356923669237692386923969240692416924269243692446924569246692476924869249692506925169252692536925469255692566925769258692596926069261692626926369264692656926669267692686926969270692716927269273692746927569276692776927869279692806928169282692836928469285692866928769288692896929069291692926929369294692956929669297692986929969300693016930269303693046930569306693076930869309693106931169312693136931469315693166931769318693196932069321693226932369324693256932669327693286932969330693316933269333693346933569336693376933869339693406934169342693436934469345693466934769348693496935069351693526935369354693556935669357693586935969360693616936269363693646936569366693676936869369693706937169372693736937469375693766937769378693796938069381693826938369384693856938669387693886938969390693916939269393693946939569396693976939869399694006940169402694036940469405694066940769408694096941069411694126941369414694156941669417694186941969420694216942269423694246942569426694276942869429694306943169432694336943469435694366943769438694396944069441694426944369444694456944669447694486944969450694516945269453694546945569456694576945869459694606946169462694636946469465694666946769468694696947069471694726947369474694756947669477694786947969480694816948269483694846948569486694876948869489694906949169492694936949469495694966949769498694996950069501695026950369504695056950669507695086950969510695116951269513695146951569516695176951869519695206952169522695236952469525695266952769528695296953069531695326953369534695356953669537695386953969540695416954269543695446954569546695476954869549695506955169552695536955469555695566955769558695596956069561695626956369564695656956669567695686956969570695716957269573695746957569576695776957869579695806958169582695836958469585695866958769588695896959069591695926959369594695956959669597695986959969600696016960269603696046960569606696076960869609696106961169612696136961469615696166961769618696196962069621696226962369624696256962669627696286962969630696316963269633696346963569636696376963869639696406964169642696436964469645696466964769648696496965069651696526965369654696556965669657696586965969660696616966269663696646966569666696676966869669696706967169672696736967469675696766967769678696796968069681696826968369684696856968669687696886968969690696916969269693696946969569696696976969869699697006970169702697036970469705697066970769708697096971069711697126971369714697156971669717697186971969720697216972269723697246972569726697276972869729697306973169732697336973469735697366973769738697396974069741697426974369744697456974669747697486974969750697516975269753697546975569756697576975869759697606976169762697636976469765697666976769768697696977069771697726977369774697756977669777697786977969780697816978269783697846978569786697876978869789697906979169792697936979469795697966979769798697996980069801698026980369804698056980669807698086980969810698116981269813698146981569816698176981869819698206982169822698236982469825698266982769828698296983069831698326983369834698356983669837698386983969840698416984269843698446984569846698476984869849698506985169852698536985469855698566985769858698596986069861698626986369864698656986669867698686986969870698716987269873698746987569876698776987869879698806988169882698836988469885698866988769888698896989069891698926989369894698956989669897698986989969900699016990269903699046990569906699076990869909699106991169912699136991469915699166991769918699196992069921699226992369924699256992669927699286992969930699316993269933699346993569936699376993869939699406994169942699436994469945699466994769948699496995069951699526995369954699556995669957699586995969960699616996269963699646996569966699676996869969699706997169972699736997469975699766997769978699796998069981699826998369984699856998669987699886998969990699916999269993699946999569996699976999869999700007000170002700037000470005700067000770008700097001070011700127001370014700157001670017700187001970020700217002270023700247002570026700277002870029700307003170032700337003470035700367003770038700397004070041700427004370044700457004670047700487004970050700517005270053700547005570056700577005870059700607006170062700637006470065700667006770068700697007070071700727007370074700757007670077700787007970080700817008270083700847008570086700877008870089700907009170092700937009470095700967009770098700997010070101701027010370104701057010670107701087010970110701117011270113701147011570116701177011870119701207012170122701237012470125701267012770128701297013070131701327013370134701357013670137701387013970140701417014270143701447014570146701477014870149701507015170152701537015470155701567015770158701597016070161701627016370164701657016670167701687016970170701717017270173701747017570176701777017870179701807018170182701837018470185701867018770188701897019070191701927019370194701957019670197701987019970200702017020270203702047020570206702077020870209702107021170212702137021470215702167021770218702197022070221702227022370224702257022670227702287022970230702317023270233702347023570236702377023870239702407024170242702437024470245702467024770248702497025070251702527025370254702557025670257702587025970260702617026270263702647026570266702677026870269702707027170272702737027470275702767027770278702797028070281702827028370284702857028670287702887028970290702917029270293702947029570296702977029870299703007030170302703037030470305703067030770308703097031070311703127031370314703157031670317703187031970320703217032270323703247032570326703277032870329703307033170332703337033470335703367033770338703397034070341703427034370344703457034670347703487034970350703517035270353703547035570356703577035870359703607036170362703637036470365703667036770368703697037070371703727037370374703757037670377703787037970380703817038270383703847038570386703877038870389703907039170392703937039470395703967039770398703997040070401704027040370404704057040670407704087040970410704117041270413704147041570416704177041870419704207042170422704237042470425704267042770428704297043070431704327043370434704357043670437704387043970440704417044270443704447044570446704477044870449704507045170452704537045470455704567045770458704597046070461704627046370464704657046670467704687046970470704717047270473704747047570476704777047870479704807048170482704837048470485704867048770488704897049070491704927049370494704957049670497704987049970500705017050270503705047050570506705077050870509705107051170512705137051470515705167051770518705197052070521705227052370524705257052670527705287052970530705317053270533705347053570536705377053870539705407054170542705437054470545705467054770548705497055070551705527055370554705557055670557705587055970560705617056270563705647056570566705677056870569705707057170572705737057470575705767057770578705797058070581705827058370584705857058670587705887058970590705917059270593705947059570596705977059870599706007060170602706037060470605706067060770608706097061070611706127061370614706157061670617706187061970620706217062270623706247062570626706277062870629706307063170632706337063470635706367063770638706397064070641706427064370644706457064670647706487064970650706517065270653706547065570656706577065870659706607066170662706637066470665706667066770668706697067070671706727067370674706757067670677706787067970680706817068270683706847068570686706877068870689706907069170692706937069470695706967069770698706997070070701707027070370704707057070670707707087070970710707117071270713707147071570716707177071870719707207072170722707237072470725707267072770728707297073070731707327073370734707357073670737707387073970740707417074270743707447074570746707477074870749707507075170752707537075470755707567075770758707597076070761707627076370764707657076670767707687076970770707717077270773707747077570776707777077870779707807078170782707837078470785707867078770788707897079070791707927079370794707957079670797707987079970800708017080270803708047080570806708077080870809708107081170812708137081470815708167081770818708197082070821708227082370824708257082670827708287082970830708317083270833708347083570836708377083870839708407084170842708437084470845708467084770848708497085070851708527085370854708557085670857708587085970860708617086270863708647086570866708677086870869708707087170872708737087470875708767087770878708797088070881708827088370884708857088670887708887088970890708917089270893708947089570896708977089870899709007090170902709037090470905709067090770908709097091070911709127091370914709157091670917709187091970920709217092270923709247092570926709277092870929709307093170932709337093470935709367093770938709397094070941709427094370944709457094670947709487094970950709517095270953709547095570956709577095870959709607096170962709637096470965709667096770968709697097070971709727097370974709757097670977709787097970980709817098270983709847098570986709877098870989709907099170992709937099470995709967099770998709997100071001710027100371004710057100671007710087100971010710117101271013710147101571016710177101871019710207102171022710237102471025710267102771028710297103071031710327103371034710357103671037710387103971040710417104271043710447104571046710477104871049710507105171052710537105471055710567105771058710597106071061710627106371064710657106671067710687106971070710717107271073710747107571076710777107871079710807108171082710837108471085710867108771088710897109071091710927109371094710957109671097710987109971100711017110271103711047110571106711077110871109711107111171112711137111471115711167111771118711197112071121711227112371124711257112671127711287112971130711317113271133711347113571136711377113871139711407114171142711437114471145711467114771148711497115071151711527115371154711557115671157711587115971160711617116271163711647116571166711677116871169711707117171172711737117471175711767117771178711797118071181711827118371184711857118671187711887118971190711917119271193711947119571196711977119871199712007120171202712037120471205712067120771208712097121071211712127121371214712157121671217712187121971220712217122271223712247122571226712277122871229712307123171232712337123471235712367123771238712397124071241712427124371244712457124671247712487124971250712517125271253712547125571256712577125871259712607126171262712637126471265712667126771268712697127071271712727127371274712757127671277712787127971280712817128271283712847128571286712877128871289712907129171292712937129471295712967129771298712997130071301713027130371304713057130671307713087130971310713117131271313713147131571316713177131871319713207132171322713237132471325713267132771328713297133071331713327133371334713357133671337713387133971340713417134271343713447134571346713477134871349713507135171352713537135471355713567135771358713597136071361713627136371364713657136671367713687136971370713717137271373713747137571376713777137871379713807138171382713837138471385713867138771388713897139071391713927139371394713957139671397713987139971400714017140271403714047140571406714077140871409714107141171412714137141471415714167141771418714197142071421714227142371424714257142671427714287142971430714317143271433714347143571436714377143871439714407144171442714437144471445714467144771448714497145071451714527145371454714557145671457714587145971460714617146271463714647146571466714677146871469714707147171472714737147471475714767147771478714797148071481714827148371484714857148671487714887148971490714917149271493714947149571496714977149871499715007150171502715037150471505715067150771508715097151071511715127151371514715157151671517715187151971520715217152271523715247152571526715277152871529715307153171532715337153471535715367153771538715397154071541715427154371544715457154671547715487154971550715517155271553715547155571556715577155871559715607156171562715637156471565715667156771568715697157071571715727157371574715757157671577715787157971580715817158271583715847158571586715877158871589715907159171592715937159471595715967159771598715997160071601716027160371604716057160671607716087160971610716117161271613716147161571616716177161871619716207162171622716237162471625716267162771628716297163071631716327163371634716357163671637716387163971640716417164271643716447164571646716477164871649716507165171652716537165471655716567165771658716597166071661716627166371664716657166671667716687166971670716717167271673716747167571676716777167871679716807168171682716837168471685716867168771688716897169071691716927169371694716957169671697716987169971700717017170271703717047170571706717077170871709717107171171712717137171471715717167171771718717197172071721717227172371724717257172671727717287172971730717317173271733717347173571736717377173871739717407174171742717437174471745717467174771748717497175071751717527175371754717557175671757717587175971760717617176271763717647176571766717677176871769717707177171772717737177471775717767177771778717797178071781717827178371784717857178671787717887178971790717917179271793717947179571796717977179871799718007180171802718037180471805718067180771808718097181071811718127181371814718157181671817718187181971820718217182271823718247182571826718277182871829718307183171832718337183471835718367183771838718397184071841718427184371844718457184671847718487184971850718517185271853718547185571856718577185871859718607186171862718637186471865718667186771868718697187071871718727187371874718757187671877718787187971880718817188271883718847188571886718877188871889718907189171892718937189471895718967189771898718997190071901719027190371904719057190671907719087190971910719117191271913719147191571916719177191871919719207192171922719237192471925719267192771928719297193071931719327193371934719357193671937719387193971940719417194271943719447194571946719477194871949719507195171952719537195471955719567195771958719597196071961719627196371964719657196671967719687196971970719717197271973719747197571976719777197871979719807198171982719837198471985719867198771988719897199071991719927199371994719957199671997719987199972000720017200272003720047200572006720077200872009720107201172012720137201472015720167201772018720197202072021720227202372024720257202672027720287202972030720317203272033720347203572036720377203872039720407204172042720437204472045720467204772048720497205072051720527205372054720557205672057720587205972060720617206272063720647206572066720677206872069720707207172072720737207472075720767207772078720797208072081720827208372084720857208672087720887208972090720917209272093720947209572096720977209872099721007210172102721037210472105721067210772108721097211072111721127211372114721157211672117721187211972120721217212272123721247212572126721277212872129721307213172132721337213472135721367213772138721397214072141721427214372144721457214672147721487214972150721517215272153721547215572156721577215872159721607216172162721637216472165721667216772168721697217072171721727217372174721757217672177721787217972180721817218272183721847218572186721877218872189721907219172192721937219472195721967219772198721997220072201722027220372204722057220672207722087220972210722117221272213722147221572216722177221872219722207222172222722237222472225722267222772228722297223072231722327223372234722357223672237722387223972240722417224272243722447224572246722477224872249722507225172252722537225472255722567225772258722597226072261722627226372264722657226672267722687226972270722717227272273722747227572276722777227872279722807228172282722837228472285722867228772288722897229072291722927229372294722957229672297722987229972300723017230272303723047230572306723077230872309723107231172312723137231472315723167231772318723197232072321723227232372324723257232672327723287232972330723317233272333723347233572336723377233872339723407234172342723437234472345723467234772348723497235072351723527235372354723557235672357723587235972360723617236272363723647236572366723677236872369723707237172372723737237472375723767237772378723797238072381723827238372384723857238672387723887238972390723917239272393723947239572396723977239872399724007240172402724037240472405724067240772408724097241072411724127241372414724157241672417724187241972420724217242272423724247242572426724277242872429724307243172432724337243472435724367243772438724397244072441724427244372444724457244672447724487244972450724517245272453724547245572456724577245872459724607246172462724637246472465724667246772468724697247072471724727247372474724757247672477724787247972480724817248272483724847248572486724877248872489724907249172492724937249472495724967249772498724997250072501725027250372504725057250672507725087250972510725117251272513725147251572516725177251872519725207252172522725237252472525725267252772528725297253072531725327253372534725357253672537725387253972540725417254272543725447254572546725477254872549725507255172552725537255472555725567255772558725597256072561725627256372564725657256672567725687256972570725717257272573725747257572576725777257872579725807258172582725837258472585725867258772588725897259072591725927259372594725957259672597725987259972600726017260272603726047260572606726077260872609726107261172612726137261472615726167261772618726197262072621726227262372624726257262672627726287262972630726317263272633726347263572636726377263872639726407264172642726437264472645726467264772648726497265072651726527265372654726557265672657726587265972660726617266272663726647266572666726677266872669726707267172672726737267472675726767267772678726797268072681726827268372684726857268672687726887268972690726917269272693726947269572696726977269872699727007270172702727037270472705727067270772708727097271072711727127271372714727157271672717727187271972720727217272272723727247272572726727277272872729727307273172732727337273472735727367273772738727397274072741727427274372744727457274672747727487274972750727517275272753727547275572756727577275872759727607276172762727637276472765727667276772768727697277072771727727277372774727757277672777727787277972780727817278272783727847278572786727877278872789727907279172792727937279472795727967279772798727997280072801728027280372804728057280672807728087280972810728117281272813728147281572816728177281872819728207282172822728237282472825728267282772828728297283072831728327283372834728357283672837728387283972840728417284272843728447284572846728477284872849728507285172852728537285472855728567285772858728597286072861728627286372864728657286672867728687286972870728717287272873728747287572876728777287872879728807288172882728837288472885728867288772888728897289072891728927289372894728957289672897728987289972900729017290272903729047290572906729077290872909729107291172912729137291472915729167291772918729197292072921729227292372924729257292672927729287292972930729317293272933729347293572936729377293872939729407294172942729437294472945729467294772948729497295072951729527295372954729557295672957729587295972960729617296272963729647296572966729677296872969729707297172972729737297472975729767297772978729797298072981729827298372984729857298672987729887298972990729917299272993729947299572996729977299872999730007300173002730037300473005730067300773008730097301073011730127301373014730157301673017730187301973020730217302273023730247302573026730277302873029730307303173032730337303473035730367303773038730397304073041730427304373044730457304673047730487304973050730517305273053730547305573056730577305873059730607306173062730637306473065730667306773068730697307073071730727307373074730757307673077730787307973080730817308273083730847308573086730877308873089730907309173092730937309473095730967309773098730997310073101731027310373104731057310673107731087310973110731117311273113731147311573116731177311873119731207312173122731237312473125731267312773128731297313073131731327313373134731357313673137731387313973140731417314273143731447314573146731477314873149731507315173152731537315473155731567315773158731597316073161731627316373164731657316673167731687316973170731717317273173731747317573176731777317873179731807318173182731837318473185731867318773188731897319073191731927319373194731957319673197731987319973200732017320273203732047320573206732077320873209732107321173212732137321473215732167321773218732197322073221732227322373224732257322673227732287322973230732317323273233732347323573236732377323873239732407324173242732437324473245732467324773248732497325073251732527325373254732557325673257732587325973260732617326273263732647326573266732677326873269732707327173272732737327473275732767327773278732797328073281732827328373284732857328673287732887328973290732917329273293732947329573296732977329873299733007330173302733037330473305733067330773308733097331073311733127331373314733157331673317733187331973320733217332273323733247332573326733277332873329733307333173332733337333473335733367333773338733397334073341733427334373344733457334673347733487334973350733517335273353733547335573356733577335873359733607336173362733637336473365733667336773368733697337073371733727337373374733757337673377733787337973380733817338273383733847338573386733877338873389733907339173392733937339473395733967339773398733997340073401734027340373404734057340673407734087340973410734117341273413734147341573416734177341873419734207342173422734237342473425734267342773428734297343073431734327343373434734357343673437734387343973440734417344273443734447344573446734477344873449734507345173452734537345473455734567345773458734597346073461734627346373464734657346673467734687346973470734717347273473734747347573476734777347873479734807348173482734837348473485734867348773488734897349073491734927349373494734957349673497734987349973500735017350273503735047350573506735077350873509735107351173512735137351473515735167351773518735197352073521735227352373524735257352673527735287352973530735317353273533735347353573536735377353873539735407354173542735437354473545735467354773548735497355073551735527355373554735557355673557735587355973560735617356273563735647356573566735677356873569735707357173572735737357473575735767357773578735797358073581735827358373584735857358673587735887358973590735917359273593735947359573596735977359873599736007360173602736037360473605736067360773608736097361073611736127361373614736157361673617736187361973620736217362273623736247362573626736277362873629736307363173632736337363473635736367363773638736397364073641736427364373644736457364673647736487364973650736517365273653736547365573656736577365873659736607366173662736637366473665736667366773668736697367073671736727367373674736757367673677736787367973680736817368273683736847368573686736877368873689736907369173692736937369473695736967369773698736997370073701737027370373704737057370673707737087370973710737117371273713737147371573716737177371873719737207372173722737237372473725737267372773728737297373073731737327373373734737357373673737737387373973740737417374273743737447374573746737477374873749737507375173752737537375473755737567375773758737597376073761737627376373764737657376673767737687376973770737717377273773737747377573776737777377873779737807378173782737837378473785737867378773788737897379073791737927379373794737957379673797737987379973800738017380273803738047380573806738077380873809738107381173812738137381473815738167381773818738197382073821738227382373824738257382673827738287382973830738317383273833738347383573836738377383873839738407384173842738437384473845738467384773848738497385073851738527385373854738557385673857738587385973860738617386273863738647386573866738677386873869738707387173872738737387473875738767387773878738797388073881738827388373884738857388673887738887388973890738917389273893738947389573896738977389873899739007390173902739037390473905739067390773908739097391073911739127391373914739157391673917739187391973920739217392273923739247392573926739277392873929739307393173932739337393473935739367393773938739397394073941739427394373944739457394673947739487394973950739517395273953739547395573956739577395873959739607396173962739637396473965739667396773968739697397073971739727397373974739757397673977739787397973980739817398273983739847398573986739877398873989739907399173992739937399473995739967399773998739997400074001740027400374004740057400674007740087400974010740117401274013740147401574016740177401874019740207402174022740237402474025740267402774028740297403074031740327403374034740357403674037740387403974040740417404274043740447404574046740477404874049740507405174052740537405474055740567405774058740597406074061740627406374064740657406674067740687406974070740717407274073740747407574076740777407874079740807408174082740837408474085740867408774088740897409074091740927409374094740957409674097740987409974100741017410274103741047410574106741077410874109741107411174112741137411474115741167411774118741197412074121741227412374124741257412674127741287412974130741317413274133741347413574136741377413874139741407414174142741437414474145741467414774148741497415074151741527415374154741557415674157741587415974160741617416274163741647416574166741677416874169741707417174172741737417474175741767417774178741797418074181741827418374184741857418674187741887418974190741917419274193741947419574196741977419874199742007420174202742037420474205742067420774208742097421074211742127421374214742157421674217742187421974220742217422274223742247422574226742277422874229742307423174232742337423474235742367423774238742397424074241742427424374244742457424674247742487424974250742517425274253742547425574256742577425874259742607426174262742637426474265742667426774268742697427074271742727427374274742757427674277742787427974280742817428274283742847428574286742877428874289742907429174292742937429474295742967429774298742997430074301743027430374304743057430674307743087430974310743117431274313743147431574316743177431874319743207432174322743237432474325743267432774328743297433074331743327433374334743357433674337743387433974340743417434274343743447434574346743477434874349743507435174352743537435474355743567435774358743597436074361743627436374364743657436674367743687436974370743717437274373743747437574376743777437874379743807438174382743837438474385743867438774388743897439074391743927439374394743957439674397743987439974400744017440274403744047440574406744077440874409744107441174412744137441474415744167441774418744197442074421744227442374424744257442674427744287442974430744317443274433744347443574436744377443874439744407444174442744437444474445744467444774448744497445074451744527445374454744557445674457744587445974460744617446274463744647446574466744677446874469744707447174472744737447474475744767447774478744797448074481744827448374484744857448674487744887448974490744917449274493744947449574496744977449874499745007450174502745037450474505745067450774508745097451074511745127451374514745157451674517745187451974520745217452274523745247452574526745277452874529745307453174532745337453474535745367453774538745397454074541745427454374544745457454674547745487454974550745517455274553745547455574556745577455874559745607456174562745637456474565745667456774568745697457074571745727457374574745757457674577745787457974580745817458274583745847458574586745877458874589745907459174592745937459474595745967459774598745997460074601746027460374604746057460674607746087460974610746117461274613746147461574616746177461874619746207462174622746237462474625746267462774628746297463074631746327463374634746357463674637746387463974640746417464274643746447464574646746477464874649746507465174652746537465474655746567465774658746597466074661746627466374664746657466674667746687466974670746717467274673746747467574676746777467874679746807468174682746837468474685746867468774688746897469074691746927469374694746957469674697746987469974700747017470274703747047470574706747077470874709747107471174712747137471474715747167471774718747197472074721747227472374724747257472674727747287472974730747317473274733747347473574736747377473874739747407474174742747437474474745747467474774748747497475074751747527475374754747557475674757747587475974760747617476274763747647476574766747677476874769747707477174772747737477474775747767477774778747797478074781747827478374784747857478674787747887478974790747917479274793747947479574796747977479874799748007480174802748037480474805748067480774808748097481074811748127481374814748157481674817748187481974820748217482274823748247482574826748277482874829748307483174832748337483474835748367483774838748397484074841748427484374844748457484674847748487484974850748517485274853748547485574856748577485874859748607486174862748637486474865748667486774868748697487074871748727487374874748757487674877748787487974880748817488274883748847488574886748877488874889748907489174892748937489474895748967489774898748997490074901749027490374904749057490674907749087490974910749117491274913749147491574916749177491874919749207492174922749237492474925749267492774928749297493074931749327493374934749357493674937749387493974940749417494274943749447494574946749477494874949749507495174952749537495474955749567495774958749597496074961749627496374964749657496674967749687496974970749717497274973749747497574976749777497874979749807498174982749837498474985749867498774988749897499074991749927499374994749957499674997749987499975000750017500275003750047500575006750077500875009750107501175012750137501475015750167501775018750197502075021750227502375024750257502675027750287502975030750317503275033750347503575036750377503875039750407504175042750437504475045750467504775048750497505075051750527505375054750557505675057750587505975060750617506275063750647506575066750677506875069750707507175072750737507475075750767507775078750797508075081750827508375084750857508675087750887508975090750917509275093750947509575096750977509875099751007510175102751037510475105751067510775108751097511075111751127511375114751157511675117751187511975120751217512275123751247512575126751277512875129751307513175132751337513475135751367513775138751397514075141751427514375144751457514675147751487514975150751517515275153751547515575156751577515875159751607516175162751637516475165751667516775168751697517075171751727517375174751757517675177751787517975180751817518275183751847518575186751877518875189751907519175192751937519475195751967519775198751997520075201752027520375204752057520675207752087520975210752117521275213752147521575216752177521875219752207522175222752237522475225752267522775228752297523075231752327523375234752357523675237752387523975240752417524275243752447524575246752477524875249752507525175252752537525475255752567525775258752597526075261752627526375264752657526675267752687526975270752717527275273752747527575276752777527875279752807528175282752837528475285752867528775288752897529075291752927529375294752957529675297752987529975300753017530275303753047530575306753077530875309753107531175312753137531475315753167531775318753197532075321753227532375324753257532675327753287532975330753317533275333753347533575336753377533875339753407534175342753437534475345753467534775348753497535075351753527535375354753557535675357753587535975360753617536275363753647536575366753677536875369753707537175372753737537475375753767537775378753797538075381753827538375384753857538675387753887538975390753917539275393753947539575396753977539875399754007540175402754037540475405754067540775408754097541075411754127541375414754157541675417754187541975420754217542275423754247542575426754277542875429754307543175432754337543475435754367543775438754397544075441754427544375444754457544675447754487544975450754517545275453754547545575456754577545875459754607546175462754637546475465754667546775468754697547075471754727547375474754757547675477754787547975480754817548275483754847548575486754877548875489754907549175492754937549475495754967549775498754997550075501755027550375504755057550675507755087550975510755117551275513755147551575516755177551875519755207552175522755237552475525755267552775528755297553075531755327553375534755357553675537755387553975540755417554275543755447554575546755477554875549755507555175552755537555475555755567555775558755597556075561755627556375564755657556675567755687556975570755717557275573755747557575576755777557875579755807558175582755837558475585755867558775588755897559075591755927559375594755957559675597755987559975600756017560275603756047560575606756077560875609756107561175612756137561475615756167561775618756197562075621756227562375624756257562675627756287562975630756317563275633756347563575636756377563875639756407564175642756437564475645756467564775648756497565075651756527565375654756557565675657756587565975660756617566275663756647566575666756677566875669756707567175672756737567475675756767567775678756797568075681756827568375684756857568675687756887568975690756917569275693756947569575696756977569875699757007570175702757037570475705757067570775708757097571075711757127571375714757157571675717757187571975720757217572275723757247572575726757277572875729757307573175732757337573475735757367573775738757397574075741757427574375744757457574675747757487574975750757517575275753757547575575756757577575875759757607576175762757637576475765757667576775768757697577075771757727577375774757757577675777757787577975780757817578275783757847578575786757877578875789757907579175792757937579475795757967579775798757997580075801758027580375804758057580675807758087580975810758117581275813758147581575816758177581875819758207582175822758237582475825758267582775828758297583075831758327583375834758357583675837758387583975840758417584275843758447584575846758477584875849758507585175852758537585475855758567585775858758597586075861758627586375864758657586675867758687586975870758717587275873758747587575876758777587875879758807588175882758837588475885758867588775888758897589075891758927589375894758957589675897758987589975900759017590275903759047590575906759077590875909759107591175912759137591475915759167591775918759197592075921759227592375924759257592675927759287592975930759317593275933759347593575936759377593875939759407594175942759437594475945759467594775948759497595075951759527595375954759557595675957759587595975960759617596275963759647596575966759677596875969759707597175972759737597475975759767597775978759797598075981759827598375984759857598675987759887598975990759917599275993759947599575996759977599875999760007600176002760037600476005760067600776008760097601076011760127601376014760157601676017760187601976020760217602276023760247602576026760277602876029760307603176032760337603476035760367603776038760397604076041760427604376044760457604676047760487604976050760517605276053760547605576056760577605876059760607606176062760637606476065760667606776068760697607076071760727607376074760757607676077760787607976080760817608276083760847608576086760877608876089760907609176092760937609476095760967609776098760997610076101761027610376104761057610676107761087610976110761117611276113761147611576116761177611876119761207612176122761237612476125761267612776128761297613076131761327613376134761357613676137761387613976140761417614276143761447614576146761477614876149761507615176152761537615476155761567615776158761597616076161761627616376164761657616676167761687616976170761717617276173761747617576176761777617876179761807618176182761837618476185761867618776188761897619076191761927619376194761957619676197761987619976200762017620276203762047620576206762077620876209762107621176212762137621476215762167621776218762197622076221762227622376224762257622676227762287622976230762317623276233762347623576236762377623876239762407624176242762437624476245762467624776248762497625076251762527625376254762557625676257762587625976260762617626276263762647626576266762677626876269762707627176272762737627476275762767627776278762797628076281762827628376284762857628676287762887628976290762917629276293762947629576296762977629876299763007630176302763037630476305763067630776308763097631076311763127631376314763157631676317763187631976320763217632276323763247632576326763277632876329763307633176332763337633476335763367633776338763397634076341763427634376344763457634676347763487634976350763517635276353763547635576356763577635876359763607636176362763637636476365763667636776368763697637076371763727637376374763757637676377763787637976380763817638276383763847638576386763877638876389763907639176392763937639476395763967639776398763997640076401764027640376404764057640676407764087640976410764117641276413764147641576416764177641876419764207642176422764237642476425764267642776428764297643076431764327643376434764357643676437764387643976440764417644276443764447644576446764477644876449764507645176452764537645476455764567645776458764597646076461764627646376464764657646676467764687646976470764717647276473764747647576476764777647876479764807648176482764837648476485764867648776488764897649076491764927649376494764957649676497764987649976500765017650276503765047650576506765077650876509765107651176512765137651476515765167651776518765197652076521765227652376524765257652676527765287652976530765317653276533765347653576536765377653876539765407654176542765437654476545765467654776548765497655076551765527655376554765557655676557765587655976560765617656276563765647656576566765677656876569765707657176572765737657476575765767657776578765797658076581765827658376584765857658676587765887658976590765917659276593765947659576596765977659876599766007660176602766037660476605766067660776608766097661076611766127661376614766157661676617766187661976620766217662276623766247662576626766277662876629766307663176632766337663476635766367663776638766397664076641766427664376644766457664676647766487664976650766517665276653766547665576656766577665876659766607666176662766637666476665766667666776668766697667076671766727667376674766757667676677766787667976680766817668276683766847668576686766877668876689766907669176692766937669476695766967669776698766997670076701767027670376704767057670676707767087670976710767117671276713767147671576716767177671876719767207672176722767237672476725767267672776728767297673076731767327673376734767357673676737767387673976740767417674276743767447674576746767477674876749767507675176752767537675476755767567675776758767597676076761767627676376764767657676676767767687676976770767717677276773767747677576776767777677876779767807678176782767837678476785767867678776788767897679076791767927679376794767957679676797767987679976800768017680276803768047680576806768077680876809768107681176812768137681476815768167681776818768197682076821768227682376824768257682676827768287682976830768317683276833768347683576836768377683876839768407684176842768437684476845768467684776848768497685076851768527685376854768557685676857768587685976860768617686276863768647686576866768677686876869768707687176872768737687476875768767687776878768797688076881768827688376884768857688676887768887688976890768917689276893768947689576896768977689876899769007690176902769037690476905769067690776908769097691076911769127691376914769157691676917769187691976920769217692276923769247692576926769277692876929769307693176932769337693476935769367693776938769397694076941769427694376944769457694676947769487694976950769517695276953769547695576956769577695876959769607696176962769637696476965769667696776968769697697076971769727697376974769757697676977769787697976980769817698276983769847698576986769877698876989769907699176992769937699476995769967699776998769997700077001770027700377004770057700677007770087700977010770117701277013770147701577016770177701877019770207702177022770237702477025770267702777028770297703077031770327703377034770357703677037770387703977040770417704277043770447704577046770477704877049770507705177052770537705477055770567705777058770597706077061770627706377064770657706677067770687706977070770717707277073770747707577076770777707877079770807708177082770837708477085770867708777088770897709077091770927709377094770957709677097770987709977100771017710277103771047710577106771077710877109771107711177112771137711477115771167711777118771197712077121771227712377124771257712677127771287712977130771317713277133771347713577136771377713877139771407714177142771437714477145771467714777148771497715077151771527715377154771557715677157771587715977160771617716277163771647716577166771677716877169771707717177172771737717477175771767717777178771797718077181771827718377184771857718677187771887718977190771917719277193771947719577196771977719877199772007720177202772037720477205772067720777208772097721077211772127721377214772157721677217772187721977220772217722277223772247722577226772277722877229772307723177232772337723477235772367723777238772397724077241772427724377244772457724677247772487724977250772517725277253772547725577256772577725877259772607726177262772637726477265772667726777268772697727077271772727727377274772757727677277772787727977280772817728277283772847728577286772877728877289772907729177292772937729477295772967729777298772997730077301773027730377304773057730677307773087730977310773117731277313773147731577316773177731877319773207732177322773237732477325773267732777328773297733077331773327733377334773357733677337773387733977340773417734277343773447734577346773477734877349773507735177352773537735477355773567735777358773597736077361773627736377364773657736677367773687736977370773717737277373773747737577376773777737877379773807738177382773837738477385773867738777388773897739077391773927739377394773957739677397773987739977400774017740277403774047740577406774077740877409774107741177412774137741477415774167741777418774197742077421774227742377424774257742677427774287742977430774317743277433774347743577436774377743877439774407744177442774437744477445774467744777448774497745077451774527745377454774557745677457774587745977460774617746277463774647746577466774677746877469774707747177472774737747477475774767747777478774797748077481774827748377484774857748677487774887748977490774917749277493774947749577496774977749877499775007750177502775037750477505775067750777508775097751077511775127751377514775157751677517775187751977520775217752277523775247752577526775277752877529775307753177532775337753477535775367753777538775397754077541775427754377544775457754677547775487754977550775517755277553775547755577556775577755877559775607756177562775637756477565775667756777568775697757077571775727757377574775757757677577775787757977580775817758277583775847758577586775877758877589775907759177592775937759477595775967759777598775997760077601776027760377604776057760677607776087760977610776117761277613776147761577616776177761877619776207762177622776237762477625776267762777628776297763077631776327763377634776357763677637776387763977640776417764277643776447764577646776477764877649776507765177652776537765477655776567765777658776597766077661776627766377664776657766677667776687766977670776717767277673776747767577676776777767877679776807768177682776837768477685776867768777688776897769077691776927769377694776957769677697776987769977700777017770277703777047770577706777077770877709777107771177712777137771477715777167771777718777197772077721777227772377724777257772677727777287772977730777317773277733777347773577736777377773877739777407774177742777437774477745777467774777748777497775077751777527775377754777557775677757777587775977760777617776277763777647776577766777677776877769777707777177772777737777477775777767777777778777797778077781777827778377784777857778677787777887778977790777917779277793777947779577796777977779877799778007780177802778037780477805778067780777808778097781077811778127781377814778157781677817778187781977820778217782277823778247782577826778277782877829778307783177832778337783477835778367783777838778397784077841778427784377844778457784677847778487784977850778517785277853778547785577856778577785877859778607786177862778637786477865778667786777868778697787077871778727787377874778757787677877778787787977880778817788277883778847788577886778877788877889778907789177892778937789477895778967789777898778997790077901779027790377904779057790677907779087790977910779117791277913779147791577916779177791877919779207792177922779237792477925779267792777928779297793077931779327793377934779357793677937779387793977940779417794277943779447794577946779477794877949779507795177952779537795477955779567795777958779597796077961779627796377964779657796677967779687796977970779717797277973779747797577976779777797877979779807798177982779837798477985779867798777988779897799077991779927799377994779957799677997779987799978000780017800278003780047800578006780077800878009780107801178012780137801478015780167801778018780197802078021780227802378024780257802678027780287802978030780317803278033780347803578036780377803878039780407804178042780437804478045780467804778048780497805078051780527805378054780557805678057780587805978060780617806278063780647806578066780677806878069780707807178072780737807478075780767807778078780797808078081780827808378084780857808678087780887808978090780917809278093780947809578096780977809878099781007810178102781037810478105781067810778108781097811078111781127811378114781157811678117781187811978120781217812278123781247812578126781277812878129781307813178132781337813478135781367813778138781397814078141781427814378144781457814678147781487814978150781517815278153781547815578156781577815878159781607816178162781637816478165781667816778168781697817078171781727817378174781757817678177781787817978180781817818278183781847818578186781877818878189781907819178192781937819478195781967819778198781997820078201782027820378204782057820678207782087820978210782117821278213782147821578216782177821878219782207822178222782237822478225782267822778228782297823078231782327823378234782357823678237782387823978240782417824278243782447824578246782477824878249782507825178252782537825478255782567825778258782597826078261782627826378264782657826678267782687826978270782717827278273782747827578276782777827878279782807828178282782837828478285782867828778288782897829078291782927829378294782957829678297782987829978300783017830278303783047830578306783077830878309783107831178312783137831478315783167831778318783197832078321783227832378324783257832678327783287832978330783317833278333783347833578336783377833878339783407834178342783437834478345783467834778348783497835078351783527835378354783557835678357783587835978360783617836278363783647836578366783677836878369783707837178372783737837478375783767837778378783797838078381783827838378384783857838678387783887838978390783917839278393783947839578396783977839878399784007840178402784037840478405784067840778408784097841078411784127841378414784157841678417784187841978420784217842278423784247842578426784277842878429784307843178432784337843478435784367843778438784397844078441784427844378444784457844678447784487844978450784517845278453784547845578456784577845878459784607846178462784637846478465784667846778468784697847078471784727847378474784757847678477784787847978480784817848278483784847848578486784877848878489784907849178492784937849478495784967849778498784997850078501785027850378504785057850678507785087850978510785117851278513785147851578516785177851878519785207852178522785237852478525785267852778528785297853078531785327853378534785357853678537785387853978540785417854278543785447854578546785477854878549785507855178552785537855478555785567855778558785597856078561785627856378564785657856678567785687856978570785717857278573785747857578576785777857878579785807858178582785837858478585785867858778588785897859078591785927859378594785957859678597785987859978600786017860278603786047860578606786077860878609786107861178612786137861478615786167861778618786197862078621786227862378624786257862678627786287862978630786317863278633786347863578636786377863878639786407864178642786437864478645786467864778648786497865078651786527865378654786557865678657786587865978660786617866278663786647866578666786677866878669786707867178672786737867478675786767867778678786797868078681786827868378684786857868678687786887868978690786917869278693786947869578696786977869878699787007870178702787037870478705787067870778708787097871078711787127871378714787157871678717787187871978720787217872278723787247872578726787277872878729787307873178732787337873478735787367873778738787397874078741787427874378744787457874678747787487874978750787517875278753787547875578756787577875878759787607876178762787637876478765787667876778768787697877078771787727877378774787757877678777787787877978780787817878278783787847878578786787877878878789787907879178792787937879478795787967879778798787997880078801788027880378804788057880678807788087880978810788117881278813788147881578816788177881878819788207882178822788237882478825788267882778828788297883078831788327883378834788357883678837788387883978840788417884278843788447884578846788477884878849788507885178852788537885478855788567885778858788597886078861788627886378864788657886678867788687886978870788717887278873788747887578876788777887878879788807888178882788837888478885788867888778888788897889078891788927889378894788957889678897788987889978900789017890278903789047890578906789077890878909789107891178912789137891478915789167891778918789197892078921789227892378924789257892678927789287892978930789317893278933789347893578936789377893878939789407894178942789437894478945789467894778948789497895078951789527895378954789557895678957789587895978960789617896278963789647896578966789677896878969789707897178972789737897478975789767897778978789797898078981789827898378984789857898678987789887898978990789917899278993789947899578996789977899878999790007900179002790037900479005790067900779008790097901079011790127901379014790157901679017790187901979020790217902279023790247902579026790277902879029790307903179032790337903479035790367903779038790397904079041790427904379044790457904679047790487904979050790517905279053790547905579056790577905879059790607906179062790637906479065790667906779068790697907079071790727907379074790757907679077790787907979080790817908279083790847908579086790877908879089790907909179092790937909479095790967909779098790997910079101791027910379104791057910679107791087910979110791117911279113791147911579116791177911879119791207912179122791237912479125791267912779128791297913079131791327913379134791357913679137791387913979140791417914279143791447914579146791477914879149791507915179152791537915479155791567915779158791597916079161791627916379164791657916679167791687916979170791717917279173791747917579176791777917879179791807918179182791837918479185791867918779188791897919079191791927919379194791957919679197791987919979200792017920279203792047920579206792077920879209792107921179212792137921479215792167921779218792197922079221792227922379224792257922679227792287922979230792317923279233792347923579236792377923879239792407924179242792437924479245792467924779248792497925079251792527925379254792557925679257792587925979260792617926279263792647926579266792677926879269792707927179272792737927479275792767927779278792797928079281792827928379284792857928679287792887928979290792917929279293792947929579296792977929879299793007930179302793037930479305793067930779308793097931079311793127931379314793157931679317793187931979320793217932279323793247932579326793277932879329793307933179332793337933479335793367933779338793397934079341793427934379344793457934679347793487934979350793517935279353793547935579356793577935879359793607936179362793637936479365793667936779368793697937079371793727937379374793757937679377793787937979380793817938279383793847938579386793877938879389793907939179392793937939479395793967939779398793997940079401794027940379404794057940679407794087940979410794117941279413794147941579416794177941879419794207942179422794237942479425794267942779428794297943079431794327943379434794357943679437794387943979440794417944279443794447944579446794477944879449794507945179452794537945479455794567945779458794597946079461794627946379464794657946679467794687946979470794717947279473794747947579476794777947879479794807948179482794837948479485794867948779488794897949079491794927949379494794957949679497794987949979500795017950279503795047950579506795077950879509795107951179512795137951479515795167951779518795197952079521795227952379524795257952679527795287952979530795317953279533795347953579536795377953879539795407954179542795437954479545795467954779548795497955079551795527955379554795557955679557795587955979560795617956279563795647956579566795677956879569795707957179572795737957479575795767957779578795797958079581795827958379584795857958679587795887958979590795917959279593795947959579596795977959879599796007960179602796037960479605796067960779608796097961079611796127961379614796157961679617796187961979620796217962279623796247962579626796277962879629796307963179632796337963479635796367963779638796397964079641796427964379644796457964679647796487964979650796517965279653796547965579656796577965879659796607966179662796637966479665796667966779668796697967079671796727967379674796757967679677796787967979680796817968279683796847968579686796877968879689796907969179692796937969479695796967969779698796997970079701797027970379704797057970679707797087970979710797117971279713797147971579716797177971879719797207972179722797237972479725797267972779728797297973079731797327973379734797357973679737797387973979740797417974279743797447974579746797477974879749797507975179752797537975479755797567975779758797597976079761797627976379764797657976679767797687976979770797717977279773797747977579776797777977879779797807978179782797837978479785797867978779788797897979079791797927979379794797957979679797797987979979800798017980279803798047980579806798077980879809798107981179812798137981479815798167981779818798197982079821798227982379824798257982679827798287982979830798317983279833798347983579836798377983879839798407984179842798437984479845798467984779848798497985079851798527985379854798557985679857798587985979860798617986279863798647986579866798677986879869798707987179872798737987479875798767987779878798797988079881798827988379884798857988679887798887988979890798917989279893798947989579896798977989879899799007990179902799037990479905799067990779908799097991079911799127991379914799157991679917799187991979920799217992279923799247992579926799277992879929799307993179932799337993479935799367993779938799397994079941799427994379944799457994679947799487994979950799517995279953799547995579956799577995879959799607996179962799637996479965799667996779968799697997079971799727997379974799757997679977799787997979980799817998279983799847998579986799877998879989799907999179992799937999479995799967999779998799998000080001800028000380004800058000680007800088000980010800118001280013800148001580016800178001880019800208002180022800238002480025800268002780028800298003080031800328003380034800358003680037800388003980040800418004280043800448004580046800478004880049800508005180052800538005480055800568005780058800598006080061800628006380064800658006680067800688006980070800718007280073800748007580076800778007880079800808008180082800838008480085800868008780088800898009080091800928009380094800958009680097800988009980100801018010280103801048010580106801078010880109801108011180112801138011480115801168011780118801198012080121801228012380124801258012680127801288012980130801318013280133801348013580136801378013880139801408014180142801438014480145801468014780148801498015080151801528015380154801558015680157801588015980160801618016280163801648016580166801678016880169801708017180172801738017480175801768017780178801798018080181801828018380184801858018680187801888018980190801918019280193801948019580196801978019880199802008020180202802038020480205802068020780208802098021080211802128021380214802158021680217802188021980220802218022280223802248022580226802278022880229802308023180232802338023480235802368023780238802398024080241802428024380244802458024680247802488024980250802518025280253802548025580256802578025880259802608026180262802638026480265802668026780268802698027080271802728027380274802758027680277802788027980280802818028280283802848028580286802878028880289802908029180292802938029480295802968029780298802998030080301803028030380304803058030680307803088030980310803118031280313803148031580316803178031880319803208032180322803238032480325803268032780328803298033080331803328033380334803358033680337803388033980340803418034280343803448034580346803478034880349803508035180352803538035480355803568035780358803598036080361803628036380364803658036680367803688036980370803718037280373803748037580376803778037880379803808038180382803838038480385803868038780388803898039080391803928039380394803958039680397803988039980400804018040280403804048040580406804078040880409804108041180412804138041480415804168041780418804198042080421804228042380424804258042680427804288042980430804318043280433804348043580436804378043880439804408044180442804438044480445804468044780448804498045080451804528045380454804558045680457804588045980460804618046280463804648046580466804678046880469804708047180472804738047480475804768047780478804798048080481804828048380484804858048680487804888048980490804918049280493804948049580496804978049880499805008050180502805038050480505805068050780508805098051080511805128051380514805158051680517805188051980520805218052280523805248052580526805278052880529805308053180532805338053480535805368053780538805398054080541805428054380544805458054680547805488054980550805518055280553805548055580556805578055880559805608056180562805638056480565805668056780568805698057080571805728057380574805758057680577805788057980580805818058280583805848058580586805878058880589805908059180592805938059480595805968059780598805998060080601806028060380604806058060680607806088060980610806118061280613806148061580616806178061880619806208062180622806238062480625806268062780628806298063080631806328063380634806358063680637806388063980640806418064280643806448064580646806478064880649806508065180652806538065480655806568065780658806598066080661806628066380664806658066680667806688066980670806718067280673806748067580676806778067880679806808068180682806838068480685806868068780688806898069080691806928069380694806958069680697806988069980700807018070280703807048070580706807078070880709807108071180712807138071480715807168071780718807198072080721807228072380724807258072680727807288072980730807318073280733807348073580736807378073880739807408074180742807438074480745807468074780748807498075080751807528075380754807558075680757807588075980760807618076280763807648076580766807678076880769807708077180772807738077480775807768077780778807798078080781807828078380784807858078680787807888078980790807918079280793807948079580796807978079880799808008080180802808038080480805808068080780808808098081080811808128081380814808158081680817808188081980820808218082280823808248082580826808278082880829808308083180832808338083480835808368083780838808398084080841808428084380844808458084680847808488084980850808518085280853808548085580856808578085880859808608086180862808638086480865808668086780868808698087080871808728087380874808758087680877808788087980880808818088280883808848088580886808878088880889808908089180892808938089480895808968089780898808998090080901809028090380904809058090680907809088090980910809118091280913809148091580916809178091880919809208092180922809238092480925809268092780928809298093080931809328093380934809358093680937809388093980940809418094280943809448094580946809478094880949809508095180952809538095480955809568095780958809598096080961809628096380964809658096680967809688096980970809718097280973809748097580976809778097880979809808098180982809838098480985809868098780988809898099080991809928099380994809958099680997809988099981000810018100281003810048100581006810078100881009810108101181012810138101481015810168101781018810198102081021810228102381024810258102681027810288102981030810318103281033810348103581036810378103881039810408104181042810438104481045810468104781048810498105081051810528105381054810558105681057810588105981060810618106281063810648106581066810678106881069810708107181072810738107481075810768107781078810798108081081810828108381084810858108681087810888108981090810918109281093810948109581096810978109881099811008110181102811038110481105811068110781108811098111081111811128111381114811158111681117811188111981120811218112281123811248112581126811278112881129811308113181132811338113481135811368113781138811398114081141811428114381144811458114681147811488114981150811518115281153811548115581156811578115881159811608116181162811638116481165811668116781168811698117081171811728117381174811758117681177811788117981180811818118281183811848118581186811878118881189811908119181192811938119481195811968119781198811998120081201812028120381204812058120681207812088120981210812118121281213812148121581216812178121881219812208122181222812238122481225812268122781228812298123081231812328123381234812358123681237812388123981240812418124281243812448124581246812478124881249812508125181252812538125481255812568125781258812598126081261812628126381264812658126681267812688126981270812718127281273812748127581276812778127881279812808128181282812838128481285812868128781288812898129081291812928129381294812958129681297812988129981300813018130281303813048130581306813078130881309813108131181312813138131481315813168131781318813198132081321813228132381324813258132681327813288132981330813318133281333813348133581336813378133881339813408134181342813438134481345813468134781348813498135081351813528135381354813558135681357813588135981360813618136281363813648136581366813678136881369813708137181372813738137481375813768137781378813798138081381813828138381384813858138681387813888138981390813918139281393813948139581396813978139881399814008140181402814038140481405814068140781408814098141081411814128141381414814158141681417814188141981420814218142281423814248142581426814278142881429814308143181432814338143481435814368143781438814398144081441814428144381444814458144681447814488144981450814518145281453814548145581456814578145881459814608146181462814638146481465814668146781468814698147081471814728147381474814758147681477814788147981480814818148281483814848148581486814878148881489814908149181492814938149481495814968149781498814998150081501815028150381504815058150681507815088150981510815118151281513815148151581516815178151881519815208152181522815238152481525815268152781528815298153081531815328153381534815358153681537815388153981540815418154281543815448154581546815478154881549815508155181552815538155481555815568155781558815598156081561815628156381564815658156681567815688156981570815718157281573815748157581576815778157881579815808158181582815838158481585815868158781588815898159081591815928159381594815958159681597815988159981600816018160281603816048160581606816078160881609816108161181612816138161481615816168161781618816198162081621816228162381624816258162681627816288162981630816318163281633816348163581636816378163881639816408164181642816438164481645816468164781648816498165081651816528165381654816558165681657816588165981660816618166281663816648166581666816678166881669816708167181672816738167481675816768167781678816798168081681816828168381684816858168681687816888168981690816918169281693816948169581696816978169881699817008170181702817038170481705817068170781708817098171081711817128171381714817158171681717817188171981720817218172281723817248172581726817278172881729817308173181732817338173481735817368173781738817398174081741817428174381744817458174681747817488174981750817518175281753817548175581756817578175881759817608176181762817638176481765817668176781768817698177081771817728177381774817758177681777817788177981780817818178281783817848178581786817878178881789817908179181792817938179481795817968179781798817998180081801818028180381804818058180681807818088180981810818118181281813818148181581816818178181881819818208182181822818238182481825818268182781828818298183081831818328183381834818358183681837818388183981840818418184281843818448184581846818478184881849818508185181852818538185481855818568185781858818598186081861818628186381864818658186681867818688186981870818718187281873818748187581876818778187881879818808188181882818838188481885818868188781888818898189081891818928189381894818958189681897818988189981900819018190281903819048190581906819078190881909819108191181912819138191481915819168191781918819198192081921819228192381924819258192681927819288192981930819318193281933819348193581936819378193881939819408194181942819438194481945819468194781948819498195081951819528195381954819558195681957819588195981960819618196281963819648196581966819678196881969819708197181972819738197481975819768197781978819798198081981819828198381984819858198681987819888198981990819918199281993819948199581996819978199881999820008200182002820038200482005820068200782008820098201082011820128201382014820158201682017820188201982020820218202282023820248202582026820278202882029820308203182032820338203482035820368203782038820398204082041820428204382044820458204682047820488204982050820518205282053820548205582056820578205882059820608206182062820638206482065820668206782068820698207082071820728207382074820758207682077820788207982080820818208282083820848208582086820878208882089820908209182092820938209482095820968209782098820998210082101821028210382104821058210682107821088210982110821118211282113821148211582116821178211882119821208212182122821238212482125821268212782128821298213082131821328213382134821358213682137821388213982140821418214282143821448214582146821478214882149821508215182152821538215482155821568215782158821598216082161821628216382164821658216682167821688216982170821718217282173821748217582176821778217882179821808218182182821838218482185821868218782188821898219082191821928219382194821958219682197821988219982200822018220282203822048220582206822078220882209822108221182212822138221482215822168221782218822198222082221822228222382224822258222682227822288222982230822318223282233822348223582236822378223882239822408224182242822438224482245822468224782248822498225082251822528225382254822558225682257822588225982260822618226282263822648226582266822678226882269822708227182272822738227482275822768227782278822798228082281822828228382284822858228682287822888228982290822918229282293822948229582296822978229882299823008230182302823038230482305823068230782308823098231082311823128231382314823158231682317823188231982320823218232282323823248232582326823278232882329823308233182332823338233482335823368233782338823398234082341823428234382344823458234682347823488234982350823518235282353823548235582356823578235882359823608236182362823638236482365823668236782368823698237082371823728237382374823758237682377823788237982380823818238282383823848238582386823878238882389823908239182392823938239482395823968239782398823998240082401824028240382404824058240682407824088240982410824118241282413824148241582416824178241882419824208242182422824238242482425824268242782428824298243082431824328243382434824358243682437824388243982440824418244282443824448244582446824478244882449824508245182452824538245482455824568245782458824598246082461824628246382464824658246682467824688246982470824718247282473824748247582476824778247882479824808248182482824838248482485824868248782488824898249082491824928249382494824958249682497824988249982500825018250282503825048250582506825078250882509825108251182512825138251482515825168251782518825198252082521825228252382524825258252682527825288252982530825318253282533825348253582536825378253882539825408254182542825438254482545825468254782548825498255082551825528255382554825558255682557825588255982560825618256282563825648256582566825678256882569825708257182572825738257482575825768257782578825798258082581825828258382584825858258682587825888258982590825918259282593825948259582596825978259882599826008260182602826038260482605826068260782608826098261082611826128261382614826158261682617826188261982620826218262282623826248262582626826278262882629826308263182632826338263482635826368263782638826398264082641826428264382644826458264682647826488264982650826518265282653826548265582656826578265882659826608266182662826638266482665826668266782668826698267082671826728267382674826758267682677826788267982680826818268282683826848268582686826878268882689826908269182692826938269482695826968269782698826998270082701827028270382704827058270682707827088270982710827118271282713827148271582716827178271882719827208272182722827238272482725827268272782728827298273082731827328273382734827358273682737827388273982740827418274282743827448274582746827478274882749827508275182752827538275482755827568275782758827598276082761827628276382764827658276682767827688276982770827718277282773827748277582776827778277882779827808278182782827838278482785827868278782788827898279082791827928279382794827958279682797827988279982800828018280282803828048280582806828078280882809828108281182812828138281482815828168281782818828198282082821828228282382824828258282682827828288282982830828318283282833828348283582836828378283882839828408284182842828438284482845828468284782848828498285082851828528285382854828558285682857828588285982860828618286282863828648286582866828678286882869828708287182872828738287482875828768287782878828798288082881828828288382884828858288682887828888288982890828918289282893828948289582896828978289882899829008290182902829038290482905829068290782908829098291082911829128291382914829158291682917829188291982920829218292282923829248292582926829278292882929829308293182932829338293482935829368293782938829398294082941829428294382944829458294682947829488294982950829518295282953829548295582956829578295882959829608296182962829638296482965829668296782968829698297082971829728297382974829758297682977829788297982980829818298282983829848298582986829878298882989829908299182992829938299482995829968299782998829998300083001830028300383004830058300683007830088300983010830118301283013830148301583016830178301883019830208302183022830238302483025830268302783028830298303083031830328303383034830358303683037830388303983040830418304283043830448304583046830478304883049830508305183052830538305483055830568305783058830598306083061830628306383064830658306683067830688306983070830718307283073830748307583076830778307883079830808308183082830838308483085830868308783088830898309083091830928309383094830958309683097830988309983100831018310283103831048310583106831078310883109831108311183112831138311483115831168311783118831198312083121831228312383124831258312683127831288312983130831318313283133831348313583136831378313883139831408314183142831438314483145831468314783148831498315083151831528315383154831558315683157831588315983160831618316283163831648316583166831678316883169831708317183172831738317483175831768317783178831798318083181831828318383184831858318683187831888318983190831918319283193831948319583196831978319883199832008320183202832038320483205832068320783208832098321083211832128321383214832158321683217832188321983220832218322283223832248322583226832278322883229832308323183232832338323483235832368323783238832398324083241832428324383244832458324683247832488324983250832518325283253832548325583256832578325883259832608326183262832638326483265832668326783268832698327083271832728327383274832758327683277832788327983280832818328283283832848328583286832878328883289832908329183292832938329483295832968329783298832998330083301833028330383304833058330683307833088330983310833118331283313833148331583316833178331883319833208332183322833238332483325833268332783328833298333083331833328333383334833358333683337833388333983340833418334283343833448334583346833478334883349833508335183352833538335483355833568335783358833598336083361833628336383364833658336683367833688336983370833718337283373833748337583376833778337883379833808338183382833838338483385833868338783388833898339083391833928339383394833958339683397833988339983400834018340283403834048340583406834078340883409834108341183412834138341483415834168341783418834198342083421834228342383424834258342683427834288342983430834318343283433834348343583436834378343883439834408344183442834438344483445834468344783448834498345083451834528345383454834558345683457834588345983460834618346283463834648346583466834678346883469834708347183472834738347483475834768347783478834798348083481834828348383484834858348683487834888348983490834918349283493834948349583496834978349883499835008350183502835038350483505835068350783508835098351083511835128351383514835158351683517835188351983520835218352283523835248352583526835278352883529835308353183532835338353483535835368353783538835398354083541835428354383544835458354683547835488354983550835518355283553835548355583556835578355883559835608356183562835638356483565835668356783568835698357083571835728357383574835758357683577835788357983580835818358283583835848358583586835878358883589835908359183592835938359483595835968359783598835998360083601836028360383604836058360683607836088360983610836118361283613836148361583616836178361883619836208362183622836238362483625836268362783628836298363083631836328363383634836358363683637836388363983640836418364283643836448364583646836478364883649836508365183652836538365483655836568365783658836598366083661836628366383664836658366683667836688366983670836718367283673836748367583676836778367883679836808368183682836838368483685836868368783688836898369083691836928369383694836958369683697836988369983700837018370283703837048370583706837078370883709837108371183712837138371483715837168371783718837198372083721837228372383724837258372683727837288372983730837318373283733837348373583736837378373883739837408374183742837438374483745837468374783748837498375083751837528375383754837558375683757837588375983760837618376283763837648376583766837678376883769837708377183772837738377483775837768377783778837798378083781837828378383784837858378683787837888378983790837918379283793837948379583796837978379883799838008380183802838038380483805838068380783808838098381083811838128381383814838158381683817838188381983820838218382283823838248382583826838278382883829838308383183832838338383483835838368383783838838398384083841838428384383844838458384683847838488384983850838518385283853838548385583856838578385883859838608386183862838638386483865838668386783868838698387083871838728387383874838758387683877838788387983880838818388283883838848388583886838878388883889838908389183892838938389483895838968389783898838998390083901839028390383904839058390683907839088390983910839118391283913839148391583916839178391883919839208392183922839238392483925839268392783928839298393083931839328393383934839358393683937839388393983940839418394283943839448394583946839478394883949839508395183952839538395483955839568395783958839598396083961839628396383964839658396683967839688396983970839718397283973839748397583976839778397883979839808398183982839838398483985839868398783988839898399083991839928399383994839958399683997839988399984000840018400284003840048400584006840078400884009840108401184012840138401484015840168401784018840198402084021840228402384024840258402684027840288402984030840318403284033840348403584036840378403884039840408404184042840438404484045840468404784048840498405084051840528405384054840558405684057840588405984060840618406284063840648406584066840678406884069840708407184072840738407484075840768407784078840798408084081840828408384084840858408684087840888408984090840918409284093840948409584096840978409884099841008410184102841038410484105841068410784108841098411084111841128411384114841158411684117841188411984120841218412284123841248412584126841278412884129841308413184132841338413484135841368413784138841398414084141841428414384144841458414684147841488414984150841518415284153841548415584156841578415884159841608416184162841638416484165841668416784168841698417084171841728417384174841758417684177841788417984180841818418284183841848418584186841878418884189841908419184192841938419484195841968419784198841998420084201842028420384204842058420684207842088420984210842118421284213842148421584216842178421884219842208422184222842238422484225842268422784228842298423084231842328423384234842358423684237842388423984240842418424284243842448424584246842478424884249842508425184252842538425484255842568425784258842598426084261842628426384264842658426684267842688426984270842718427284273842748427584276842778427884279842808428184282842838428484285842868428784288842898429084291842928429384294842958429684297842988429984300843018430284303843048430584306843078430884309843108431184312843138431484315843168431784318843198432084321843228432384324843258432684327843288432984330843318433284333843348433584336843378433884339843408434184342843438434484345843468434784348843498435084351843528435384354843558435684357843588435984360843618436284363843648436584366843678436884369843708437184372843738437484375843768437784378843798438084381843828438384384843858438684387843888438984390843918439284393843948439584396843978439884399844008440184402844038440484405844068440784408844098441084411844128441384414844158441684417844188441984420844218442284423844248442584426844278442884429844308443184432844338443484435844368443784438844398444084441844428444384444844458444684447844488444984450844518445284453844548445584456844578445884459844608446184462844638446484465844668446784468844698447084471844728447384474844758447684477844788447984480844818448284483844848448584486844878448884489844908449184492844938449484495844968449784498844998450084501845028450384504845058450684507845088450984510845118451284513845148451584516845178451884519845208452184522845238452484525845268452784528845298453084531845328453384534845358453684537845388453984540845418454284543845448454584546845478454884549845508455184552845538455484555845568455784558845598456084561845628456384564845658456684567845688456984570845718457284573845748457584576845778457884579845808458184582845838458484585845868458784588845898459084591845928459384594845958459684597845988459984600846018460284603846048460584606846078460884609846108461184612846138461484615846168461784618846198462084621846228462384624846258462684627846288462984630846318463284633846348463584636846378463884639846408464184642846438464484645846468464784648846498465084651846528465384654846558465684657846588465984660846618466284663846648466584666846678466884669846708467184672846738467484675846768467784678846798468084681846828468384684846858468684687846888468984690846918469284693846948469584696846978469884699847008470184702847038470484705847068470784708847098471084711847128471384714847158471684717847188471984720847218472284723847248472584726847278472884729847308473184732847338473484735847368473784738847398474084741847428474384744847458474684747847488474984750847518475284753847548475584756847578475884759847608476184762847638476484765847668476784768847698477084771847728477384774847758477684777847788477984780847818478284783847848478584786847878478884789847908479184792847938479484795847968479784798847998480084801848028480384804848058480684807848088480984810848118481284813848148481584816848178481884819848208482184822848238482484825848268482784828848298483084831848328483384834848358483684837848388483984840848418484284843848448484584846848478484884849848508485184852848538485484855848568485784858848598486084861848628486384864848658486684867848688486984870848718487284873848748487584876848778487884879848808488184882848838488484885848868488784888848898489084891848928489384894848958489684897848988489984900849018490284903849048490584906849078490884909849108491184912849138491484915849168491784918849198492084921849228492384924849258492684927849288492984930849318493284933849348493584936849378493884939849408494184942849438494484945849468494784948849498495084951849528495384954849558495684957849588495984960849618496284963849648496584966849678496884969849708497184972849738497484975849768497784978849798498084981849828498384984849858498684987849888498984990849918499284993849948499584996849978499884999850008500185002850038500485005850068500785008850098501085011850128501385014850158501685017850188501985020850218502285023850248502585026850278502885029850308503185032850338503485035850368503785038850398504085041850428504385044850458504685047850488504985050850518505285053850548505585056850578505885059850608506185062850638506485065850668506785068850698507085071850728507385074850758507685077850788507985080850818508285083850848508585086850878508885089850908509185092850938509485095850968509785098850998510085101851028510385104851058510685107851088510985110851118511285113851148511585116851178511885119851208512185122851238512485125851268512785128851298513085131851328513385134851358513685137851388513985140851418514285143851448514585146851478514885149851508515185152851538515485155851568515785158851598516085161851628516385164851658516685167851688516985170851718517285173851748517585176851778517885179851808518185182851838518485185851868518785188851898519085191851928519385194851958519685197851988519985200852018520285203852048520585206852078520885209852108521185212852138521485215852168521785218852198522085221852228522385224852258522685227852288522985230852318523285233852348523585236852378523885239852408524185242852438524485245852468524785248852498525085251852528525385254852558525685257852588525985260852618526285263852648526585266852678526885269852708527185272852738527485275852768527785278852798528085281852828528385284852858528685287852888528985290852918529285293852948529585296852978529885299853008530185302853038530485305853068530785308853098531085311853128531385314853158531685317853188531985320853218532285323853248532585326853278532885329853308533185332853338533485335853368533785338853398534085341853428534385344853458534685347853488534985350853518535285353853548535585356853578535885359853608536185362853638536485365853668536785368853698537085371853728537385374853758537685377853788537985380853818538285383853848538585386853878538885389853908539185392853938539485395853968539785398853998540085401854028540385404854058540685407854088540985410854118541285413854148541585416854178541885419854208542185422854238542485425854268542785428854298543085431854328543385434854358543685437854388543985440854418544285443854448544585446854478544885449854508545185452854538545485455854568545785458854598546085461854628546385464854658546685467854688546985470854718547285473854748547585476854778547885479854808548185482854838548485485854868548785488854898549085491854928549385494854958549685497854988549985500855018550285503855048550585506855078550885509855108551185512855138551485515855168551785518855198552085521855228552385524855258552685527855288552985530855318553285533855348553585536855378553885539855408554185542855438554485545855468554785548855498555085551855528555385554855558555685557855588555985560855618556285563855648556585566855678556885569855708557185572855738557485575855768557785578855798558085581855828558385584855858558685587855888558985590855918559285593855948559585596855978559885599856008560185602856038560485605856068560785608856098561085611856128561385614856158561685617856188561985620856218562285623856248562585626856278562885629856308563185632856338563485635856368563785638856398564085641856428564385644856458564685647856488564985650856518565285653856548565585656856578565885659856608566185662856638566485665856668566785668856698567085671856728567385674856758567685677856788567985680856818568285683856848568585686856878568885689856908569185692856938569485695856968569785698856998570085701857028570385704857058570685707857088570985710857118571285713857148571585716857178571885719857208572185722857238572485725857268572785728857298573085731857328573385734857358573685737857388573985740857418574285743857448574585746857478574885749857508575185752857538575485755857568575785758857598576085761857628576385764857658576685767857688576985770857718577285773857748577585776857778577885779857808578185782857838578485785857868578785788857898579085791857928579385794857958579685797857988579985800858018580285803858048580585806858078580885809858108581185812858138581485815858168581785818858198582085821858228582385824858258582685827858288582985830858318583285833858348583585836858378583885839858408584185842858438584485845858468584785848858498585085851858528585385854858558585685857858588585985860858618586285863858648586585866858678586885869858708587185872858738587485875858768587785878858798588085881858828588385884858858588685887858888588985890858918589285893858948589585896858978589885899859008590185902859038590485905859068590785908859098591085911859128591385914859158591685917859188591985920859218592285923859248592585926859278592885929859308593185932859338593485935859368593785938859398594085941859428594385944859458594685947859488594985950859518595285953859548595585956859578595885959859608596185962859638596485965859668596785968859698597085971859728597385974859758597685977859788597985980859818598285983859848598585986859878598885989859908599185992859938599485995859968599785998859998600086001860028600386004860058600686007860088600986010860118601286013860148601586016860178601886019860208602186022860238602486025860268602786028860298603086031860328603386034860358603686037860388603986040860418604286043860448604586046860478604886049860508605186052860538605486055860568605786058860598606086061860628606386064860658606686067860688606986070860718607286073860748607586076860778607886079860808608186082860838608486085860868608786088860898609086091860928609386094860958609686097860988609986100861018610286103861048610586106861078610886109861108611186112861138611486115861168611786118861198612086121861228612386124861258612686127861288612986130861318613286133861348613586136861378613886139861408614186142861438614486145861468614786148861498615086151861528615386154861558615686157861588615986160861618616286163861648616586166861678616886169861708617186172861738617486175861768617786178861798618086181861828618386184861858618686187861888618986190861918619286193861948619586196861978619886199862008620186202862038620486205862068620786208862098621086211862128621386214862158621686217862188621986220862218622286223862248622586226862278622886229862308623186232862338623486235862368623786238862398624086241862428624386244862458624686247862488624986250862518625286253862548625586256862578625886259862608626186262862638626486265862668626786268862698627086271862728627386274862758627686277862788627986280862818628286283862848628586286862878628886289862908629186292862938629486295862968629786298862998630086301863028630386304863058630686307863088630986310863118631286313863148631586316863178631886319863208632186322863238632486325863268632786328863298633086331863328633386334863358633686337863388633986340863418634286343863448634586346863478634886349863508635186352863538635486355863568635786358863598636086361863628636386364863658636686367863688636986370863718637286373863748637586376863778637886379863808638186382863838638486385863868638786388863898639086391863928639386394863958639686397863988639986400864018640286403864048640586406864078640886409864108641186412864138641486415864168641786418864198642086421864228642386424864258642686427864288642986430864318643286433864348643586436864378643886439864408644186442864438644486445864468644786448864498645086451864528645386454864558645686457864588645986460864618646286463864648646586466864678646886469864708647186472864738647486475864768647786478864798648086481864828648386484864858648686487864888648986490864918649286493864948649586496864978649886499865008650186502865038650486505865068650786508865098651086511865128651386514865158651686517865188651986520865218652286523865248652586526865278652886529865308653186532865338653486535865368653786538865398654086541865428654386544865458654686547865488654986550865518655286553865548655586556865578655886559865608656186562865638656486565865668656786568865698657086571865728657386574865758657686577865788657986580865818658286583865848658586586865878658886589865908659186592865938659486595865968659786598865998660086601866028660386604866058660686607866088660986610866118661286613866148661586616866178661886619866208662186622866238662486625866268662786628866298663086631866328663386634866358663686637866388663986640866418664286643866448664586646866478664886649866508665186652866538665486655866568665786658866598666086661866628666386664866658666686667866688666986670866718667286673866748667586676866778667886679866808668186682866838668486685866868668786688866898669086691866928669386694866958669686697866988669986700867018670286703867048670586706867078670886709867108671186712867138671486715867168671786718867198672086721867228672386724867258672686727867288672986730867318673286733867348673586736867378673886739867408674186742867438674486745867468674786748867498675086751867528675386754867558675686757867588675986760867618676286763867648676586766867678676886769867708677186772867738677486775867768677786778867798678086781867828678386784867858678686787867888678986790867918679286793867948679586796867978679886799868008680186802868038680486805868068680786808868098681086811868128681386814868158681686817868188681986820868218682286823868248682586826868278682886829868308683186832868338683486835868368683786838868398684086841868428684386844868458684686847868488684986850868518685286853868548685586856868578685886859868608686186862868638686486865868668686786868868698687086871868728687386874868758687686877868788687986880868818688286883868848688586886868878688886889868908689186892868938689486895868968689786898868998690086901869028690386904869058690686907869088690986910869118691286913869148691586916869178691886919869208692186922869238692486925869268692786928869298693086931869328693386934869358693686937869388693986940869418694286943869448694586946869478694886949869508695186952869538695486955869568695786958869598696086961869628696386964869658696686967869688696986970869718697286973869748697586976869778697886979869808698186982869838698486985869868698786988869898699086991869928699386994869958699686997869988699987000870018700287003870048700587006870078700887009870108701187012870138701487015870168701787018870198702087021870228702387024870258702687027870288702987030870318703287033870348703587036870378703887039870408704187042870438704487045870468704787048870498705087051870528705387054870558705687057870588705987060870618706287063870648706587066870678706887069870708707187072870738707487075870768707787078870798708087081870828708387084870858708687087870888708987090870918709287093870948709587096870978709887099871008710187102871038710487105871068710787108871098711087111871128711387114871158711687117871188711987120871218712287123871248712587126871278712887129871308713187132871338713487135871368713787138871398714087141871428714387144871458714687147871488714987150871518715287153871548715587156871578715887159871608716187162871638716487165871668716787168871698717087171871728717387174871758717687177871788717987180871818718287183871848718587186871878718887189871908719187192871938719487195871968719787198871998720087201872028720387204872058720687207872088720987210872118721287213872148721587216872178721887219872208722187222872238722487225872268722787228872298723087231872328723387234872358723687237872388723987240872418724287243872448724587246872478724887249872508725187252872538725487255872568725787258872598726087261872628726387264872658726687267872688726987270872718727287273872748727587276872778727887279872808728187282872838728487285872868728787288872898729087291872928729387294872958729687297872988729987300873018730287303873048730587306873078730887309873108731187312873138731487315873168731787318873198732087321873228732387324873258732687327873288732987330873318733287333873348733587336873378733887339873408734187342873438734487345873468734787348873498735087351873528735387354873558735687357873588735987360873618736287363873648736587366873678736887369873708737187372873738737487375873768737787378873798738087381873828738387384873858738687387873888738987390873918739287393873948739587396873978739887399874008740187402874038740487405874068740787408874098741087411874128741387414874158741687417874188741987420874218742287423874248742587426874278742887429874308743187432874338743487435874368743787438874398744087441874428744387444874458744687447874488744987450874518745287453874548745587456874578745887459874608746187462874638746487465874668746787468874698747087471874728747387474874758747687477874788747987480874818748287483874848748587486874878748887489874908749187492874938749487495874968749787498874998750087501875028750387504875058750687507875088750987510875118751287513875148751587516875178751887519875208752187522875238752487525875268752787528875298753087531875328753387534875358753687537875388753987540875418754287543875448754587546875478754887549875508755187552875538755487555875568755787558875598756087561875628756387564875658756687567875688756987570875718757287573875748757587576875778757887579875808758187582875838758487585875868758787588875898759087591875928759387594875958759687597875988759987600876018760287603876048760587606876078760887609876108761187612876138761487615876168761787618876198762087621876228762387624876258762687627876288762987630876318763287633876348763587636876378763887639876408764187642876438764487645876468764787648876498765087651876528765387654876558765687657876588765987660876618766287663876648766587666876678766887669876708767187672876738767487675876768767787678876798768087681876828768387684876858768687687876888768987690876918769287693876948769587696876978769887699877008770187702877038770487705877068770787708877098771087711877128771387714877158771687717877188771987720877218772287723877248772587726877278772887729877308773187732877338773487735877368773787738877398774087741877428774387744877458774687747877488774987750877518775287753877548775587756877578775887759877608776187762877638776487765877668776787768877698777087771877728777387774877758777687777877788777987780877818778287783877848778587786877878778887789877908779187792877938779487795877968779787798877998780087801878028780387804878058780687807878088780987810878118781287813878148781587816878178781887819878208782187822878238782487825878268782787828878298783087831878328783387834878358783687837878388783987840878418784287843878448784587846878478784887849878508785187852878538785487855878568785787858878598786087861878628786387864878658786687867878688786987870878718787287873878748787587876878778787887879878808788187882878838788487885878868788787888878898789087891878928789387894878958789687897878988789987900879018790287903879048790587906879078790887909879108791187912879138791487915879168791787918879198792087921879228792387924879258792687927879288792987930879318793287933879348793587936879378793887939879408794187942879438794487945879468794787948879498795087951879528795387954879558795687957879588795987960879618796287963879648796587966879678796887969879708797187972879738797487975879768797787978879798798087981879828798387984879858798687987879888798987990879918799287993879948799587996879978799887999880008800188002880038800488005880068800788008880098801088011880128801388014880158801688017880188801988020880218802288023880248802588026880278802888029880308803188032880338803488035880368803788038880398804088041880428804388044880458804688047880488804988050880518805288053880548805588056880578805888059880608806188062880638806488065880668806788068880698807088071880728807388074880758807688077880788807988080880818808288083880848808588086880878808888089880908809188092880938809488095880968809788098880998810088101881028810388104881058810688107881088810988110881118811288113881148811588116881178811888119881208812188122881238812488125881268812788128881298813088131881328813388134881358813688137881388813988140881418814288143881448814588146881478814888149881508815188152881538815488155881568815788158881598816088161881628816388164881658816688167881688816988170881718817288173881748817588176881778817888179881808818188182881838818488185881868818788188881898819088191881928819388194881958819688197881988819988200882018820288203882048820588206882078820888209882108821188212882138821488215882168821788218882198822088221882228822388224882258822688227882288822988230882318823288233882348823588236882378823888239882408824188242882438824488245882468824788248882498825088251882528825388254882558825688257882588825988260882618826288263882648826588266882678826888269882708827188272882738827488275882768827788278882798828088281882828828388284882858828688287882888828988290882918829288293882948829588296882978829888299883008830188302883038830488305883068830788308883098831088311883128831388314883158831688317883188831988320883218832288323883248832588326883278832888329883308833188332883338833488335883368833788338883398834088341883428834388344883458834688347883488834988350883518835288353883548835588356883578835888359883608836188362883638836488365883668836788368883698837088371883728837388374883758837688377883788837988380883818838288383883848838588386883878838888389883908839188392883938839488395883968839788398883998840088401884028840388404884058840688407884088840988410884118841288413884148841588416884178841888419884208842188422884238842488425884268842788428884298843088431884328843388434884358843688437884388843988440884418844288443884448844588446884478844888449884508845188452884538845488455884568845788458884598846088461884628846388464884658846688467884688846988470884718847288473884748847588476884778847888479884808848188482884838848488485884868848788488884898849088491884928849388494884958849688497884988849988500885018850288503885048850588506885078850888509885108851188512885138851488515885168851788518885198852088521885228852388524885258852688527885288852988530885318853288533885348853588536885378853888539885408854188542885438854488545885468854788548885498855088551885528855388554885558855688557885588855988560885618856288563885648856588566885678856888569885708857188572885738857488575885768857788578885798858088581885828858388584885858858688587885888858988590885918859288593885948859588596885978859888599886008860188602886038860488605886068860788608886098861088611886128861388614886158861688617886188861988620886218862288623886248862588626886278862888629886308863188632886338863488635886368863788638886398864088641886428864388644886458864688647886488864988650886518865288653886548865588656886578865888659886608866188662886638866488665886668866788668886698867088671886728867388674886758867688677886788867988680886818868288683886848868588686886878868888689886908869188692886938869488695886968869788698886998870088701887028870388704887058870688707887088870988710887118871288713887148871588716887178871888719887208872188722887238872488725887268872788728887298873088731887328873388734887358873688737887388873988740887418874288743887448874588746887478874888749887508875188752887538875488755887568875788758887598876088761887628876388764887658876688767887688876988770887718877288773887748877588776887778877888779887808878188782887838878488785887868878788788887898879088791887928879388794887958879688797887988879988800888018880288803888048880588806888078880888809888108881188812888138881488815888168881788818888198882088821888228882388824888258882688827888288882988830888318883288833888348883588836888378883888839888408884188842888438884488845888468884788848888498885088851888528885388854888558885688857888588885988860888618886288863888648886588866888678886888869888708887188872888738887488875888768887788878888798888088881888828888388884888858888688887888888888988890888918889288893888948889588896888978889888899889008890188902889038890488905889068890788908889098891088911889128891388914889158891688917889188891988920889218892288923889248892588926889278892888929889308893188932889338893488935889368893788938889398894088941889428894388944889458894688947889488894988950889518895288953889548895588956889578895888959889608896188962889638896488965889668896788968889698897088971889728897388974889758897688977889788897988980889818898288983889848898588986889878898888989889908899188992889938899488995889968899788998889998900089001890028900389004890058900689007890088900989010890118901289013890148901589016890178901889019890208902189022890238902489025890268902789028890298903089031890328903389034890358903689037890388903989040890418904289043890448904589046890478904889049890508905189052890538905489055890568905789058890598906089061890628906389064890658906689067890688906989070890718907289073890748907589076890778907889079890808908189082890838908489085890868908789088890898909089091890928909389094890958909689097890988909989100891018910289103891048910589106891078910889109891108911189112891138911489115891168911789118891198912089121891228912389124891258912689127891288912989130891318913289133891348913589136891378913889139891408914189142891438914489145891468914789148891498915089151891528915389154891558915689157891588915989160891618916289163891648916589166891678916889169891708917189172891738917489175891768917789178891798918089181891828918389184891858918689187891888918989190891918919289193891948919589196891978919889199892008920189202892038920489205892068920789208892098921089211892128921389214892158921689217892188921989220892218922289223892248922589226892278922889229892308923189232892338923489235892368923789238892398924089241892428924389244892458924689247892488924989250892518925289253892548925589256892578925889259892608926189262892638926489265892668926789268892698927089271892728927389274892758927689277892788927989280892818928289283892848928589286892878928889289892908929189292892938929489295892968929789298892998930089301893028930389304893058930689307893088930989310893118931289313893148931589316893178931889319893208932189322893238932489325893268932789328893298933089331893328933389334893358933689337893388933989340893418934289343893448934589346893478934889349893508935189352893538935489355893568935789358893598936089361893628936389364893658936689367893688936989370893718937289373893748937589376893778937889379893808938189382893838938489385893868938789388893898939089391893928939389394893958939689397893988939989400894018940289403894048940589406894078940889409894108941189412894138941489415894168941789418894198942089421894228942389424894258942689427894288942989430894318943289433894348943589436894378943889439894408944189442894438944489445894468944789448894498945089451894528945389454894558945689457894588945989460894618946289463894648946589466894678946889469894708947189472894738947489475894768947789478894798948089481894828948389484894858948689487894888948989490894918949289493894948949589496894978949889499895008950189502895038950489505895068950789508895098951089511895128951389514895158951689517895188951989520895218952289523895248952589526895278952889529895308953189532895338953489535895368953789538895398954089541895428954389544895458954689547895488954989550895518955289553895548955589556895578955889559895608956189562895638956489565895668956789568895698957089571895728957389574895758957689577895788957989580895818958289583895848958589586895878958889589895908959189592895938959489595895968959789598895998960089601896028960389604896058960689607896088960989610896118961289613896148961589616896178961889619896208962189622896238962489625896268962789628896298963089631896328963389634896358963689637896388963989640896418964289643896448964589646896478964889649896508965189652896538965489655896568965789658896598966089661896628966389664896658966689667896688966989670896718967289673896748967589676896778967889679896808968189682896838968489685896868968789688896898969089691896928969389694896958969689697896988969989700897018970289703897048970589706897078970889709897108971189712897138971489715897168971789718897198972089721897228972389724897258972689727897288972989730897318973289733897348973589736897378973889739897408974189742897438974489745897468974789748897498975089751897528975389754897558975689757897588975989760897618976289763897648976589766897678976889769897708977189772897738977489775897768977789778897798978089781897828978389784897858978689787897888978989790897918979289793897948979589796897978979889799898008980189802898038980489805898068980789808898098981089811898128981389814898158981689817898188981989820898218982289823898248982589826898278982889829898308983189832898338983489835898368983789838898398984089841898428984389844898458984689847898488984989850898518985289853898548985589856898578985889859898608986189862898638986489865898668986789868898698987089871898728987389874898758987689877898788987989880898818988289883898848988589886898878988889889898908989189892898938989489895898968989789898898998990089901899028990389904899058990689907899088990989910899118991289913899148991589916899178991889919899208992189922899238992489925899268992789928899298993089931899328993389934899358993689937899388993989940899418994289943899448994589946899478994889949899508995189952899538995489955899568995789958899598996089961899628996389964899658996689967899688996989970899718997289973899748997589976899778997889979899808998189982899838998489985899868998789988899898999089991899928999389994899958999689997899988999990000900019000290003900049000590006900079000890009900109001190012900139001490015900169001790018900199002090021900229002390024900259002690027900289002990030900319003290033900349003590036900379003890039900409004190042900439004490045900469004790048900499005090051900529005390054900559005690057900589005990060900619006290063900649006590066900679006890069900709007190072900739007490075900769007790078900799008090081900829008390084900859008690087900889008990090900919009290093900949009590096900979009890099901009010190102901039010490105901069010790108901099011090111901129011390114901159011690117901189011990120901219012290123901249012590126901279012890129901309013190132901339013490135901369013790138901399014090141901429014390144901459014690147901489014990150901519015290153901549015590156901579015890159901609016190162901639016490165901669016790168901699017090171901729017390174901759017690177901789017990180901819018290183901849018590186901879018890189901909019190192901939019490195901969019790198901999020090201902029020390204902059020690207902089020990210902119021290213902149021590216902179021890219902209022190222902239022490225902269022790228902299023090231902329023390234902359023690237902389023990240902419024290243902449024590246902479024890249902509025190252902539025490255902569025790258902599026090261902629026390264902659026690267902689026990270902719027290273902749027590276902779027890279902809028190282902839028490285902869028790288902899029090291902929029390294902959029690297902989029990300903019030290303903049030590306903079030890309903109031190312903139031490315903169031790318903199032090321903229032390324903259032690327903289032990330903319033290333903349033590336903379033890339903409034190342903439034490345903469034790348903499035090351903529035390354903559035690357903589035990360903619036290363903649036590366903679036890369903709037190372903739037490375903769037790378903799038090381903829038390384903859038690387903889038990390903919039290393903949039590396903979039890399904009040190402904039040490405904069040790408904099041090411904129041390414904159041690417904189041990420904219042290423904249042590426904279042890429904309043190432904339043490435904369043790438904399044090441904429044390444904459044690447904489044990450904519045290453904549045590456904579045890459904609046190462904639046490465904669046790468904699047090471904729047390474904759047690477904789047990480904819048290483904849048590486904879048890489904909049190492904939049490495904969049790498904999050090501905029050390504905059050690507905089050990510905119051290513905149051590516905179051890519905209052190522905239052490525905269052790528905299053090531905329053390534905359053690537905389053990540905419054290543905449054590546905479054890549905509055190552905539055490555905569055790558905599056090561905629056390564905659056690567905689056990570905719057290573905749057590576905779057890579905809058190582905839058490585905869058790588905899059090591905929059390594905959059690597905989059990600906019060290603906049060590606906079060890609906109061190612906139061490615906169061790618906199062090621906229062390624906259062690627906289062990630906319063290633906349063590636906379063890639906409064190642906439064490645906469064790648906499065090651906529065390654906559065690657906589065990660906619066290663906649066590666906679066890669906709067190672906739067490675906769067790678906799068090681906829068390684906859068690687906889068990690906919069290693906949069590696906979069890699907009070190702907039070490705907069070790708907099071090711907129071390714907159071690717907189071990720907219072290723907249072590726907279072890729907309073190732907339073490735907369073790738907399074090741907429074390744907459074690747907489074990750907519075290753907549075590756907579075890759907609076190762907639076490765907669076790768907699077090771907729077390774907759077690777907789077990780907819078290783907849078590786907879078890789907909079190792907939079490795907969079790798907999080090801908029080390804908059080690807908089080990810908119081290813908149081590816908179081890819908209082190822908239082490825908269082790828908299083090831908329083390834908359083690837908389083990840908419084290843908449084590846908479084890849908509085190852908539085490855908569085790858908599086090861908629086390864908659086690867908689086990870908719087290873908749087590876908779087890879908809088190882908839088490885908869088790888908899089090891908929089390894908959089690897908989089990900909019090290903909049090590906909079090890909909109091190912909139091490915909169091790918909199092090921909229092390924909259092690927909289092990930909319093290933909349093590936909379093890939909409094190942909439094490945909469094790948909499095090951909529095390954909559095690957909589095990960909619096290963909649096590966909679096890969909709097190972909739097490975909769097790978909799098090981909829098390984909859098690987909889098990990909919099290993909949099590996909979099890999910009100191002910039100491005910069100791008910099101091011910129101391014910159101691017910189101991020910219102291023910249102591026910279102891029910309103191032910339103491035910369103791038910399104091041910429104391044910459104691047910489104991050910519105291053910549105591056910579105891059910609106191062910639106491065910669106791068910699107091071910729107391074910759107691077910789107991080910819108291083910849108591086910879108891089910909109191092910939109491095910969109791098910999110091101911029110391104911059110691107911089110991110911119111291113911149111591116911179111891119911209112191122911239112491125911269112791128911299113091131911329113391134911359113691137911389113991140911419114291143911449114591146911479114891149911509115191152911539115491155911569115791158911599116091161911629116391164911659116691167911689116991170911719117291173911749117591176911779117891179911809118191182911839118491185911869118791188911899119091191911929119391194911959119691197911989119991200912019120291203912049120591206912079120891209912109121191212912139121491215912169121791218912199122091221912229122391224912259122691227912289122991230912319123291233912349123591236912379123891239912409124191242912439124491245912469124791248912499125091251912529125391254912559125691257912589125991260912619126291263912649126591266912679126891269912709127191272912739127491275912769127791278912799128091281912829128391284912859128691287912889128991290912919129291293912949129591296912979129891299913009130191302913039130491305913069130791308913099131091311913129131391314913159131691317913189131991320913219132291323913249132591326913279132891329913309133191332913339133491335913369133791338913399134091341913429134391344913459134691347913489134991350913519135291353913549135591356913579135891359913609136191362913639136491365913669136791368913699137091371913729137391374913759137691377913789137991380913819138291383913849138591386913879138891389913909139191392913939139491395913969139791398913999140091401914029140391404914059140691407914089140991410914119141291413914149141591416914179141891419914209142191422914239142491425914269142791428914299143091431914329143391434914359143691437914389143991440914419144291443914449144591446914479144891449914509145191452914539145491455914569145791458914599146091461914629146391464914659146691467914689146991470914719147291473914749147591476914779147891479914809148191482914839148491485914869148791488914899149091491914929149391494914959149691497914989149991500915019150291503915049150591506915079150891509915109151191512915139151491515915169151791518915199152091521915229152391524915259152691527915289152991530915319153291533915349153591536915379153891539915409154191542915439154491545915469154791548915499155091551915529155391554915559155691557915589155991560915619156291563915649156591566915679156891569915709157191572915739157491575915769157791578915799158091581915829158391584915859158691587915889158991590915919159291593915949159591596915979159891599916009160191602916039160491605916069160791608916099161091611916129161391614916159161691617916189161991620916219162291623916249162591626916279162891629916309163191632916339163491635916369163791638916399164091641916429164391644916459164691647916489164991650916519165291653916549165591656916579165891659916609166191662916639166491665916669166791668916699167091671916729167391674916759167691677916789167991680916819168291683916849168591686916879168891689916909169191692916939169491695916969169791698916999170091701917029170391704917059170691707917089170991710917119171291713917149171591716917179171891719917209172191722917239172491725917269172791728917299173091731917329173391734917359173691737917389173991740917419174291743917449174591746917479174891749917509175191752917539175491755917569175791758917599176091761917629176391764917659176691767917689176991770917719177291773917749177591776917779177891779917809178191782917839178491785917869178791788917899179091791917929179391794917959179691797917989179991800918019180291803918049180591806918079180891809918109181191812918139181491815918169181791818918199182091821918229182391824918259182691827918289182991830918319183291833918349183591836918379183891839918409184191842918439184491845918469184791848918499185091851918529185391854918559185691857918589185991860918619186291863918649186591866918679186891869918709187191872918739187491875918769187791878918799188091881918829188391884918859188691887918889188991890918919189291893918949189591896918979189891899919009190191902919039190491905919069190791908919099191091911919129191391914919159191691917919189191991920919219192291923919249192591926919279192891929919309193191932919339193491935919369193791938919399194091941919429194391944919459194691947919489194991950919519195291953919549195591956919579195891959919609196191962919639196491965919669196791968919699197091971919729197391974919759197691977919789197991980919819198291983919849198591986919879198891989919909199191992919939199491995919969199791998919999200092001920029200392004920059200692007920089200992010920119201292013920149201592016920179201892019920209202192022920239202492025920269202792028920299203092031920329203392034920359203692037920389203992040920419204292043920449204592046920479204892049920509205192052920539205492055920569205792058920599206092061920629206392064920659206692067920689206992070920719207292073920749207592076920779207892079920809208192082920839208492085920869208792088920899209092091920929209392094920959209692097920989209992100921019210292103921049210592106921079210892109921109211192112921139211492115921169211792118921199212092121921229212392124921259212692127921289212992130921319213292133921349213592136921379213892139921409214192142921439214492145921469214792148921499215092151921529215392154921559215692157921589215992160921619216292163921649216592166921679216892169921709217192172921739217492175921769217792178921799218092181921829218392184921859218692187921889218992190921919219292193921949219592196921979219892199922009220192202922039220492205922069220792208922099221092211922129221392214922159221692217922189221992220922219222292223922249222592226922279222892229922309223192232922339223492235922369223792238922399224092241922429224392244922459224692247922489224992250922519225292253922549225592256922579225892259922609226192262922639226492265922669226792268922699227092271922729227392274922759227692277922789227992280922819228292283922849228592286922879228892289922909229192292922939229492295922969229792298922999230092301923029230392304923059230692307923089230992310923119231292313923149231592316923179231892319923209232192322923239232492325923269232792328923299233092331923329233392334923359233692337923389233992340923419234292343923449234592346923479234892349923509235192352923539235492355923569235792358923599236092361923629236392364923659236692367923689236992370923719237292373923749237592376923779237892379923809238192382923839238492385923869238792388923899239092391923929239392394923959239692397923989239992400924019240292403924049240592406924079240892409924109241192412924139241492415924169241792418924199242092421924229242392424924259242692427924289242992430924319243292433924349243592436924379243892439924409244192442924439244492445924469244792448924499245092451924529245392454924559245692457924589245992460924619246292463924649246592466924679246892469924709247192472924739247492475924769247792478924799248092481924829248392484924859248692487924889248992490924919249292493924949249592496924979249892499925009250192502925039250492505925069250792508925099251092511925129251392514925159251692517925189251992520925219252292523925249252592526925279252892529925309253192532925339253492535925369253792538925399254092541925429254392544925459254692547925489254992550925519255292553925549255592556925579255892559925609256192562925639256492565925669256792568925699257092571925729257392574925759257692577925789257992580925819258292583925849258592586925879258892589925909259192592925939259492595925969259792598925999260092601926029260392604926059260692607926089260992610926119261292613926149261592616926179261892619926209262192622926239262492625926269262792628926299263092631926329263392634926359263692637926389263992640926419264292643926449264592646926479264892649926509265192652926539265492655926569265792658926599266092661926629266392664926659266692667926689266992670926719267292673926749267592676926779267892679926809268192682926839268492685926869268792688926899269092691926929269392694926959269692697926989269992700927019270292703927049270592706927079270892709927109271192712927139271492715927169271792718927199272092721927229272392724927259272692727927289272992730927319273292733927349273592736927379273892739927409274192742927439274492745927469274792748927499275092751927529275392754927559275692757927589275992760927619276292763927649276592766927679276892769927709277192772927739277492775927769277792778927799278092781927829278392784927859278692787927889278992790927919279292793927949279592796927979279892799928009280192802928039280492805928069280792808928099281092811928129281392814928159281692817928189281992820928219282292823928249282592826928279282892829928309283192832928339283492835928369283792838928399284092841928429284392844928459284692847928489284992850928519285292853928549285592856928579285892859928609286192862928639286492865928669286792868928699287092871928729287392874928759287692877928789287992880928819288292883928849288592886928879288892889928909289192892928939289492895928969289792898928999290092901929029290392904929059290692907929089290992910929119291292913929149291592916929179291892919929209292192922929239292492925929269292792928929299293092931929329293392934929359293692937929389293992940929419294292943929449294592946929479294892949929509295192952929539295492955929569295792958929599296092961929629296392964929659296692967929689296992970929719297292973929749297592976929779297892979929809298192982929839298492985929869298792988929899299092991929929299392994929959299692997929989299993000930019300293003930049300593006930079300893009930109301193012930139301493015930169301793018930199302093021930229302393024930259302693027930289302993030930319303293033930349303593036930379303893039930409304193042930439304493045930469304793048930499305093051930529305393054930559305693057930589305993060930619306293063930649306593066930679306893069930709307193072930739307493075930769307793078930799308093081930829308393084930859308693087930889308993090930919309293093930949309593096930979309893099931009310193102931039310493105931069310793108931099311093111931129311393114931159311693117931189311993120931219312293123931249312593126931279312893129931309313193132931339313493135931369313793138931399314093141931429314393144931459314693147931489314993150931519315293153931549315593156931579315893159931609316193162931639316493165931669316793168931699317093171931729317393174931759317693177931789317993180931819318293183931849318593186931879318893189931909319193192931939319493195931969319793198931999320093201932029320393204932059320693207932089320993210932119321293213932149321593216932179321893219932209322193222932239322493225932269322793228932299323093231932329323393234932359323693237932389323993240932419324293243932449324593246932479324893249932509325193252932539325493255932569325793258932599326093261932629326393264932659326693267932689326993270932719327293273932749327593276932779327893279932809328193282932839328493285932869328793288932899329093291932929329393294932959329693297932989329993300933019330293303933049330593306933079330893309933109331193312933139331493315933169331793318933199332093321933229332393324933259332693327933289332993330933319333293333933349333593336933379333893339933409334193342933439334493345933469334793348933499335093351933529335393354933559335693357933589335993360933619336293363933649336593366933679336893369933709337193372933739337493375933769337793378933799338093381933829338393384933859338693387933889338993390933919339293393933949339593396933979339893399934009340193402934039340493405934069340793408934099341093411934129341393414934159341693417934189341993420934219342293423934249342593426934279342893429934309343193432934339343493435934369343793438934399344093441934429344393444934459344693447934489344993450934519345293453934549345593456934579345893459934609346193462934639346493465934669346793468934699347093471934729347393474934759347693477934789347993480934819348293483934849348593486934879348893489934909349193492934939349493495934969349793498934999350093501935029350393504935059350693507935089350993510935119351293513935149351593516935179351893519935209352193522935239352493525935269352793528935299353093531935329353393534935359353693537935389353993540935419354293543935449354593546935479354893549935509355193552935539355493555935569355793558935599356093561935629356393564935659356693567935689356993570935719357293573935749357593576935779357893579935809358193582935839358493585935869358793588935899359093591935929359393594935959359693597935989359993600936019360293603936049360593606936079360893609936109361193612936139361493615936169361793618936199362093621936229362393624936259362693627936289362993630936319363293633936349363593636936379363893639936409364193642936439364493645936469364793648936499365093651936529365393654936559365693657936589365993660936619366293663936649366593666936679366893669936709367193672936739367493675936769367793678936799368093681936829368393684936859368693687936889368993690936919369293693936949369593696936979369893699937009370193702937039370493705937069370793708937099371093711937129371393714937159371693717937189371993720937219372293723937249372593726937279372893729937309373193732937339373493735937369373793738937399374093741937429374393744937459374693747937489374993750937519375293753937549375593756937579375893759937609376193762937639376493765937669376793768937699377093771937729377393774937759377693777937789377993780937819378293783937849378593786937879378893789937909379193792937939379493795937969379793798937999380093801938029380393804938059380693807938089380993810938119381293813938149381593816938179381893819938209382193822938239382493825938269382793828938299383093831938329383393834938359383693837938389383993840938419384293843938449384593846938479384893849938509385193852938539385493855938569385793858938599386093861938629386393864938659386693867938689386993870938719387293873938749387593876938779387893879938809388193882938839388493885938869388793888938899389093891938929389393894938959389693897938989389993900939019390293903939049390593906939079390893909939109391193912939139391493915939169391793918939199392093921939229392393924939259392693927939289392993930939319393293933939349393593936939379393893939939409394193942939439394493945939469394793948939499395093951939529395393954939559395693957939589395993960939619396293963939649396593966939679396893969939709397193972939739397493975939769397793978939799398093981939829398393984939859398693987939889398993990939919399293993939949399593996939979399893999940009400194002940039400494005940069400794008940099401094011940129401394014940159401694017940189401994020940219402294023940249402594026940279402894029940309403194032940339403494035940369403794038940399404094041940429404394044940459404694047940489404994050940519405294053940549405594056940579405894059940609406194062940639406494065940669406794068940699407094071940729407394074940759407694077940789407994080940819408294083940849408594086940879408894089940909409194092940939409494095940969409794098940999410094101941029410394104941059410694107941089410994110941119411294113941149411594116941179411894119941209412194122941239412494125941269412794128941299413094131941329413394134941359413694137941389413994140941419414294143941449414594146941479414894149941509415194152941539415494155941569415794158941599416094161941629416394164941659416694167941689416994170941719417294173941749417594176941779417894179941809418194182941839418494185941869418794188941899419094191941929419394194941959419694197941989419994200942019420294203942049420594206942079420894209942109421194212942139421494215942169421794218942199422094221942229422394224942259422694227942289422994230942319423294233942349423594236942379423894239942409424194242942439424494245942469424794248942499425094251942529425394254942559425694257942589425994260942619426294263942649426594266942679426894269942709427194272942739427494275942769427794278942799428094281942829428394284942859428694287942889428994290942919429294293942949429594296942979429894299943009430194302943039430494305943069430794308943099431094311943129431394314943159431694317943189431994320943219432294323943249432594326943279432894329943309433194332943339433494335943369433794338943399434094341943429434394344943459434694347943489434994350943519435294353943549435594356943579435894359943609436194362943639436494365943669436794368943699437094371943729437394374943759437694377943789437994380943819438294383943849438594386943879438894389943909439194392943939439494395943969439794398943999440094401944029440394404944059440694407944089440994410944119441294413944149441594416944179441894419944209442194422944239442494425944269442794428944299443094431944329443394434944359443694437944389443994440944419444294443944449444594446944479444894449944509445194452944539445494455944569445794458944599446094461944629446394464944659446694467944689446994470944719447294473944749447594476944779447894479944809448194482944839448494485944869448794488944899449094491944929449394494944959449694497944989449994500945019450294503945049450594506945079450894509945109451194512945139451494515945169451794518945199452094521945229452394524945259452694527945289452994530945319453294533945349453594536945379453894539945409454194542945439454494545945469454794548945499455094551945529455394554945559455694557945589455994560945619456294563945649456594566945679456894569945709457194572945739457494575945769457794578945799458094581945829458394584945859458694587945889458994590945919459294593945949459594596945979459894599946009460194602946039460494605946069460794608946099461094611946129461394614946159461694617946189461994620946219462294623946249462594626946279462894629946309463194632946339463494635946369463794638946399464094641946429464394644946459464694647946489464994650946519465294653946549465594656946579465894659946609466194662946639466494665946669466794668946699467094671946729467394674946759467694677946789467994680946819468294683946849468594686946879468894689946909469194692946939469494695946969469794698946999470094701947029470394704947059470694707947089470994710947119471294713947149471594716947179471894719947209472194722947239472494725947269472794728947299473094731947329473394734947359473694737947389473994740947419474294743947449474594746947479474894749947509475194752947539475494755947569475794758947599476094761947629476394764947659476694767947689476994770947719477294773947749477594776947779477894779947809478194782947839478494785947869478794788947899479094791947929479394794947959479694797947989479994800948019480294803948049480594806948079480894809948109481194812948139481494815948169481794818948199482094821948229482394824948259482694827948289482994830948319483294833948349483594836948379483894839948409484194842948439484494845948469484794848948499485094851948529485394854948559485694857948589485994860948619486294863948649486594866948679486894869948709487194872948739487494875948769487794878948799488094881948829488394884948859488694887948889488994890948919489294893948949489594896948979489894899949009490194902949039490494905949069490794908949099491094911949129491394914949159491694917949189491994920949219492294923949249492594926949279492894929949309493194932949339493494935949369493794938949399494094941949429494394944949459494694947949489494994950949519495294953949549495594956949579495894959949609496194962949639496494965949669496794968949699497094971949729497394974949759497694977949789497994980949819498294983949849498594986949879498894989949909499194992949939499494995949969499794998949999500095001950029500395004950059500695007950089500995010950119501295013950149501595016950179501895019950209502195022950239502495025950269502795028950299503095031950329503395034950359503695037950389503995040950419504295043950449504595046950479504895049950509505195052950539505495055950569505795058950599506095061950629506395064950659506695067950689506995070950719507295073950749507595076950779507895079950809508195082950839508495085950869508795088950899509095091950929509395094950959509695097950989509995100951019510295103951049510595106951079510895109951109511195112951139511495115951169511795118951199512095121951229512395124951259512695127951289512995130951319513295133951349513595136951379513895139951409514195142951439514495145951469514795148951499515095151951529515395154951559515695157951589515995160951619516295163951649516595166951679516895169951709517195172951739517495175951769517795178951799518095181951829518395184951859518695187951889518995190951919519295193951949519595196951979519895199952009520195202952039520495205952069520795208952099521095211952129521395214952159521695217952189521995220952219522295223952249522595226952279522895229952309523195232952339523495235952369523795238952399524095241952429524395244952459524695247952489524995250952519525295253952549525595256952579525895259952609526195262952639526495265952669526795268952699527095271952729527395274952759527695277952789527995280952819528295283952849528595286952879528895289952909529195292952939529495295952969529795298952999530095301953029530395304953059530695307953089530995310953119531295313953149531595316953179531895319953209532195322953239532495325953269532795328953299533095331953329533395334953359533695337953389533995340953419534295343953449534595346953479534895349953509535195352953539535495355953569535795358953599536095361953629536395364953659536695367953689536995370953719537295373953749537595376953779537895379953809538195382953839538495385953869538795388953899539095391953929539395394953959539695397953989539995400954019540295403954049540595406954079540895409954109541195412954139541495415954169541795418954199542095421954229542395424954259542695427954289542995430954319543295433954349543595436954379543895439954409544195442954439544495445954469544795448954499545095451954529545395454954559545695457954589545995460954619546295463954649546595466954679546895469954709547195472954739547495475954769547795478954799548095481954829548395484954859548695487954889548995490954919549295493954949549595496954979549895499955009550195502955039550495505955069550795508955099551095511955129551395514955159551695517955189551995520955219552295523955249552595526955279552895529955309553195532955339553495535955369553795538955399554095541955429554395544955459554695547955489554995550955519555295553955549555595556955579555895559955609556195562955639556495565955669556795568955699557095571955729557395574955759557695577955789557995580955819558295583955849558595586955879558895589955909559195592955939559495595955969559795598955999560095601956029560395604956059560695607956089560995610956119561295613956149561595616956179561895619956209562195622956239562495625956269562795628956299563095631956329563395634956359563695637956389563995640956419564295643956449564595646956479564895649956509565195652956539565495655956569565795658956599566095661956629566395664956659566695667956689566995670956719567295673956749567595676956779567895679956809568195682956839568495685956869568795688956899569095691956929569395694956959569695697956989569995700957019570295703957049570595706957079570895709957109571195712957139571495715957169571795718957199572095721957229572395724957259572695727957289572995730957319573295733957349573595736957379573895739957409574195742957439574495745957469574795748957499575095751957529575395754957559575695757957589575995760957619576295763957649576595766957679576895769957709577195772957739577495775957769577795778957799578095781957829578395784957859578695787957889578995790957919579295793957949579595796957979579895799958009580195802958039580495805958069580795808958099581095811958129581395814958159581695817958189581995820958219582295823958249582595826958279582895829958309583195832958339583495835958369583795838958399584095841958429584395844958459584695847958489584995850958519585295853958549585595856958579585895859958609586195862958639586495865958669586795868958699587095871958729587395874958759587695877958789587995880958819588295883958849588595886958879588895889958909589195892958939589495895958969589795898958999590095901959029590395904959059590695907959089590995910959119591295913959149591595916959179591895919959209592195922959239592495925959269592795928959299593095931959329593395934959359593695937959389593995940959419594295943959449594595946959479594895949959509595195952959539595495955959569595795958959599596095961959629596395964959659596695967959689596995970959719597295973959749597595976959779597895979959809598195982959839598495985959869598795988959899599095991959929599395994959959599695997959989599996000960019600296003960049600596006960079600896009960109601196012960139601496015960169601796018960199602096021960229602396024960259602696027960289602996030960319603296033960349603596036960379603896039960409604196042960439604496045960469604796048960499605096051960529605396054960559605696057960589605996060960619606296063960649606596066960679606896069960709607196072960739607496075960769607796078960799608096081960829608396084960859608696087960889608996090960919609296093960949609596096960979609896099961009610196102961039610496105961069610796108961099611096111961129611396114961159611696117961189611996120961219612296123961249612596126961279612896129961309613196132961339613496135961369613796138961399614096141961429614396144961459614696147961489614996150961519615296153961549615596156961579615896159961609616196162961639616496165961669616796168961699617096171961729617396174961759617696177961789617996180961819618296183961849618596186961879618896189961909619196192961939619496195961969619796198961999620096201962029620396204962059620696207962089620996210962119621296213962149621596216962179621896219962209622196222962239622496225962269622796228962299623096231962329623396234962359623696237962389623996240962419624296243962449624596246962479624896249962509625196252962539625496255962569625796258962599626096261962629626396264962659626696267962689626996270962719627296273962749627596276962779627896279962809628196282962839628496285962869628796288962899629096291962929629396294962959629696297962989629996300963019630296303963049630596306963079630896309963109631196312963139631496315963169631796318963199632096321963229632396324963259632696327963289632996330963319633296333963349633596336963379633896339963409634196342963439634496345963469634796348963499635096351963529635396354963559635696357963589635996360963619636296363963649636596366963679636896369963709637196372963739637496375963769637796378963799638096381963829638396384963859638696387963889638996390963919639296393963949639596396963979639896399964009640196402964039640496405964069640796408964099641096411964129641396414964159641696417964189641996420964219642296423964249642596426964279642896429964309643196432964339643496435964369643796438964399644096441964429644396444964459644696447964489644996450964519645296453964549645596456964579645896459964609646196462964639646496465964669646796468964699647096471964729647396474964759647696477964789647996480964819648296483964849648596486964879648896489964909649196492964939649496495964969649796498964999650096501965029650396504965059650696507965089650996510965119651296513965149651596516965179651896519965209652196522965239652496525965269652796528965299653096531965329653396534965359653696537965389653996540965419654296543965449654596546965479654896549965509655196552965539655496555965569655796558965599656096561965629656396564965659656696567965689656996570965719657296573965749657596576965779657896579965809658196582965839658496585965869658796588965899659096591965929659396594965959659696597965989659996600966019660296603966049660596606966079660896609966109661196612966139661496615966169661796618966199662096621966229662396624966259662696627966289662996630966319663296633966349663596636966379663896639966409664196642966439664496645966469664796648966499665096651966529665396654966559665696657966589665996660966619666296663966649666596666966679666896669966709667196672966739667496675966769667796678966799668096681966829668396684966859668696687966889668996690966919669296693966949669596696966979669896699967009670196702967039670496705967069670796708967099671096711967129671396714967159671696717967189671996720967219672296723967249672596726967279672896729967309673196732967339673496735967369673796738967399674096741967429674396744967459674696747967489674996750967519675296753967549675596756967579675896759967609676196762967639676496765967669676796768967699677096771967729677396774967759677696777967789677996780967819678296783967849678596786967879678896789967909679196792967939679496795967969679796798967999680096801968029680396804968059680696807968089680996810968119681296813968149681596816968179681896819968209682196822968239682496825968269682796828968299683096831968329683396834968359683696837968389683996840968419684296843968449684596846968479684896849968509685196852968539685496855968569685796858968599686096861968629686396864968659686696867968689686996870968719687296873968749687596876968779687896879968809688196882968839688496885968869688796888968899689096891968929689396894968959689696897968989689996900969019690296903969049690596906969079690896909969109691196912969139691496915969169691796918969199692096921969229692396924969259692696927969289692996930969319693296933969349693596936969379693896939969409694196942969439694496945969469694796948969499695096951969529695396954969559695696957969589695996960969619696296963969649696596966969679696896969969709697196972969739697496975969769697796978969799698096981969829698396984969859698696987969889698996990969919699296993969949699596996969979699896999970009700197002970039700497005970069700797008970099701097011970129701397014970159701697017970189701997020970219702297023970249702597026970279702897029970309703197032970339703497035970369703797038970399704097041970429704397044970459704697047970489704997050970519705297053970549705597056970579705897059970609706197062970639706497065970669706797068970699707097071970729707397074970759707697077970789707997080970819708297083970849708597086970879708897089970909709197092970939709497095970969709797098970999710097101971029710397104971059710697107971089710997110971119711297113971149711597116971179711897119971209712197122971239712497125971269712797128971299713097131971329713397134971359713697137971389713997140971419714297143971449714597146971479714897149971509715197152971539715497155971569715797158971599716097161971629716397164971659716697167971689716997170971719717297173971749717597176971779717897179971809718197182971839718497185971869718797188971899719097191971929719397194971959719697197971989719997200972019720297203972049720597206972079720897209972109721197212972139721497215972169721797218972199722097221972229722397224972259722697227972289722997230972319723297233972349723597236972379723897239972409724197242972439724497245972469724797248972499725097251972529725397254972559725697257972589725997260972619726297263972649726597266972679726897269972709727197272972739727497275972769727797278972799728097281972829728397284972859728697287972889728997290972919729297293972949729597296972979729897299973009730197302973039730497305973069730797308973099731097311973129731397314973159731697317973189731997320973219732297323973249732597326973279732897329973309733197332973339733497335973369733797338973399734097341973429734397344973459734697347973489734997350973519735297353973549735597356973579735897359973609736197362973639736497365973669736797368973699737097371973729737397374973759737697377973789737997380973819738297383973849738597386973879738897389973909739197392973939739497395973969739797398973999740097401974029740397404974059740697407974089740997410974119741297413974149741597416974179741897419974209742197422974239742497425974269742797428974299743097431974329743397434974359743697437974389743997440974419744297443974449744597446974479744897449974509745197452974539745497455974569745797458974599746097461974629746397464974659746697467974689746997470974719747297473974749747597476974779747897479974809748197482974839748497485974869748797488974899749097491974929749397494974959749697497974989749997500975019750297503975049750597506975079750897509975109751197512975139751497515975169751797518975199752097521975229752397524975259752697527975289752997530975319753297533975349753597536975379753897539975409754197542975439754497545975469754797548975499755097551975529755397554975559755697557975589755997560975619756297563975649756597566975679756897569975709757197572975739757497575975769757797578975799758097581975829758397584975859758697587975889758997590975919759297593975949759597596975979759897599976009760197602976039760497605976069760797608976099761097611976129761397614976159761697617976189761997620976219762297623976249762597626976279762897629976309763197632976339763497635976369763797638976399764097641976429764397644976459764697647976489764997650976519765297653976549765597656976579765897659976609766197662976639766497665976669766797668976699767097671976729767397674976759767697677976789767997680976819768297683976849768597686976879768897689976909769197692976939769497695976969769797698976999770097701977029770397704977059770697707977089770997710977119771297713977149771597716977179771897719977209772197722977239772497725977269772797728977299773097731977329773397734977359773697737977389773997740977419774297743977449774597746977479774897749977509775197752977539775497755977569775797758977599776097761977629776397764977659776697767977689776997770977719777297773977749777597776977779777897779977809778197782977839778497785977869778797788977899779097791977929779397794977959779697797977989779997800978019780297803978049780597806978079780897809978109781197812978139781497815978169781797818978199782097821978229782397824978259782697827978289782997830978319783297833978349783597836978379783897839978409784197842978439784497845978469784797848978499785097851978529785397854978559785697857978589785997860978619786297863978649786597866978679786897869978709787197872978739787497875978769787797878978799788097881978829788397884978859788697887978889788997890978919789297893978949789597896978979789897899979009790197902979039790497905979069790797908979099791097911979129791397914979159791697917979189791997920979219792297923979249792597926979279792897929979309793197932979339793497935979369793797938979399794097941979429794397944979459794697947979489794997950979519795297953979549795597956979579795897959979609796197962979639796497965979669796797968979699797097971979729797397974979759797697977979789797997980979819798297983979849798597986979879798897989979909799197992979939799497995979969799797998979999800098001980029800398004980059800698007980089800998010980119801298013980149801598016980179801898019980209802198022980239802498025980269802798028980299803098031980329803398034980359803698037980389803998040980419804298043980449804598046980479804898049980509805198052980539805498055980569805798058980599806098061980629806398064980659806698067980689806998070980719807298073980749807598076980779807898079980809808198082980839808498085980869808798088980899809098091980929809398094980959809698097980989809998100981019810298103981049810598106981079810898109981109811198112981139811498115981169811798118981199812098121981229812398124981259812698127981289812998130981319813298133981349813598136981379813898139981409814198142981439814498145981469814798148981499815098151981529815398154981559815698157981589815998160981619816298163981649816598166981679816898169981709817198172981739817498175981769817798178981799818098181981829818398184981859818698187981889818998190981919819298193981949819598196981979819898199982009820198202982039820498205982069820798208982099821098211982129821398214982159821698217982189821998220982219822298223982249822598226982279822898229982309823198232982339823498235982369823798238982399824098241982429824398244982459824698247982489824998250982519825298253982549825598256982579825898259982609826198262982639826498265982669826798268982699827098271982729827398274982759827698277982789827998280982819828298283982849828598286982879828898289982909829198292982939829498295982969829798298982999830098301983029830398304983059830698307983089830998310983119831298313983149831598316983179831898319983209832198322983239832498325983269832798328983299833098331983329833398334983359833698337983389833998340983419834298343983449834598346983479834898349983509835198352983539835498355983569835798358983599836098361983629836398364983659836698367983689836998370983719837298373983749837598376983779837898379983809838198382983839838498385983869838798388983899839098391983929839398394983959839698397983989839998400984019840298403984049840598406984079840898409984109841198412984139841498415984169841798418984199842098421984229842398424984259842698427984289842998430984319843298433984349843598436984379843898439984409844198442984439844498445984469844798448984499845098451984529845398454984559845698457984589845998460984619846298463984649846598466984679846898469984709847198472984739847498475984769847798478984799848098481984829848398484984859848698487984889848998490984919849298493984949849598496984979849898499985009850198502985039850498505985069850798508985099851098511985129851398514985159851698517985189851998520985219852298523985249852598526985279852898529985309853198532985339853498535985369853798538985399854098541985429854398544985459854698547985489854998550985519855298553985549855598556985579855898559985609856198562985639856498565985669856798568985699857098571985729857398574985759857698577985789857998580985819858298583985849858598586985879858898589985909859198592985939859498595985969859798598985999860098601986029860398604986059860698607986089860998610986119861298613986149861598616986179861898619986209862198622986239862498625986269862798628986299863098631986329863398634986359863698637986389863998640986419864298643986449864598646986479864898649986509865198652986539865498655986569865798658986599866098661986629866398664986659866698667986689866998670986719867298673986749867598676986779867898679986809868198682986839868498685986869868798688986899869098691986929869398694986959869698697986989869998700987019870298703987049870598706987079870898709987109871198712987139871498715987169871798718987199872098721987229872398724987259872698727987289872998730987319873298733987349873598736987379873898739987409874198742987439874498745987469874798748987499875098751987529875398754987559875698757987589875998760987619876298763987649876598766987679876898769987709877198772987739877498775987769877798778987799878098781987829878398784987859878698787987889878998790987919879298793987949879598796987979879898799988009880198802988039880498805988069880798808988099881098811988129881398814988159881698817988189881998820988219882298823988249882598826988279882898829988309883198832988339883498835988369883798838988399884098841988429884398844988459884698847988489884998850988519885298853988549885598856988579885898859988609886198862988639886498865988669886798868988699887098871988729887398874988759887698877988789887998880988819888298883988849888598886988879888898889988909889198892988939889498895988969889798898988999890098901989029890398904989059890698907989089890998910989119891298913989149891598916989179891898919989209892198922989239892498925989269892798928989299893098931989329893398934989359893698937989389893998940989419894298943989449894598946989479894898949989509895198952989539895498955989569895798958989599896098961989629896398964989659896698967989689896998970989719897298973989749897598976989779897898979989809898198982989839898498985989869898798988989899899098991989929899398994989959899698997989989899999000990019900299003990049900599006990079900899009990109901199012990139901499015990169901799018990199902099021990229902399024990259902699027990289902999030990319903299033990349903599036990379903899039990409904199042990439904499045990469904799048990499905099051990529905399054990559905699057990589905999060990619906299063990649906599066990679906899069990709907199072990739907499075990769907799078990799908099081990829908399084990859908699087990889908999090990919909299093990949909599096990979909899099991009910199102991039910499105991069910799108991099911099111991129911399114991159911699117991189911999120991219912299123991249912599126991279912899129991309913199132991339913499135991369913799138991399914099141991429914399144991459914699147991489914999150991519915299153991549915599156991579915899159991609916199162991639916499165991669916799168991699917099171991729917399174991759917699177991789917999180991819918299183991849918599186991879918899189991909919199192991939919499195991969919799198991999920099201992029920399204992059920699207992089920999210992119921299213992149921599216992179921899219992209922199222992239922499225992269922799228992299923099231992329923399234992359923699237992389923999240992419924299243992449924599246992479924899249992509925199252992539925499255992569925799258992599926099261992629926399264992659926699267992689926999270992719927299273992749927599276992779927899279992809928199282992839928499285992869928799288992899929099291992929929399294992959929699297992989929999300993019930299303993049930599306993079930899309993109931199312993139931499315993169931799318993199932099321993229932399324993259932699327993289932999330993319933299333993349933599336993379933899339993409934199342993439934499345993469934799348993499935099351993529935399354993559935699357993589935999360993619936299363993649936599366993679936899369993709937199372993739937499375993769937799378993799938099381993829938399384993859938699387993889938999390993919939299393993949939599396993979939899399994009940199402994039940499405994069940799408994099941099411994129941399414994159941699417994189941999420994219942299423994249942599426994279942899429994309943199432994339943499435994369943799438994399944099441994429944399444994459944699447994489944999450994519945299453994549945599456994579945899459994609946199462994639946499465994669946799468994699947099471994729947399474994759947699477994789947999480994819948299483994849948599486994879948899489994909949199492994939949499495994969949799498994999950099501995029950399504995059950699507995089950999510995119951299513995149951599516995179951899519995209952199522995239952499525995269952799528995299953099531995329953399534995359953699537995389953999540995419954299543995449954599546995479954899549995509955199552995539955499555995569955799558995599956099561995629956399564995659956699567995689956999570995719957299573995749957599576995779957899579995809958199582995839958499585995869958799588995899959099591995929959399594995959959699597995989959999600996019960299603996049960599606996079960899609996109961199612996139961499615996169961799618996199962099621996229962399624996259962699627996289962999630996319963299633996349963599636996379963899639996409964199642996439964499645996469964799648996499965099651996529965399654996559965699657996589965999660996619966299663996649966599666996679966899669996709967199672996739967499675996769967799678996799968099681996829968399684996859968699687996889968999690996919969299693996949969599696996979969899699997009970199702997039970499705997069970799708997099971099711997129971399714997159971699717997189971999720997219972299723997249972599726997279972899729997309973199732997339973499735997369973799738997399974099741997429974399744997459974699747997489974999750997519975299753997549975599756997579975899759997609976199762997639976499765997669976799768997699977099771997729977399774997759977699777997789977999780997819978299783997849978599786997879978899789997909979199792997939979499795997969979799798997999980099801998029980399804998059980699807998089980999810998119981299813998149981599816998179981899819998209982199822998239982499825998269982799828998299983099831998329983399834998359983699837998389983999840998419984299843998449984599846998479984899849998509985199852998539985499855998569985799858998599986099861998629986399864998659986699867998689986999870998719987299873998749987599876998779987899879998809988199882998839988499885998869988799888998899989099891998929989399894998959989699897998989989999900999019990299903999049990599906999079990899909999109991199912999139991499915999169991799918999199992099921999229992399924999259992699927999289992999930999319993299933999349993599936999379993899939999409994199942999439994499945999469994799948999499995099951999529995399954999559995699957999589995999960999619996299963999649996599966999679996899969999709997199972999739997499975999769997799978999799998099981999829998399984999859998699987999889998999990999919999299993999949999599996999979999899999100000100001100002100003100004100005100006100007100008100009100010100011100012100013100014100015100016100017100018100019100020100021100022100023100024100025100026100027100028100029100030100031100032100033100034100035100036100037100038100039100040100041100042100043100044100045100046100047100048100049100050100051100052100053100054100055100056100057100058100059100060100061100062100063100064100065100066100067100068100069100070100071100072100073100074100075100076100077100078100079100080100081100082100083100084100085100086100087100088100089100090100091100092100093100094100095100096100097100098100099100100100101100102100103100104100105100106100107100108100109100110100111100112100113100114100115100116100117100118100119100120100121100122100123100124100125100126100127100128100129100130100131100132100133100134100135100136100137100138100139100140100141100142100143100144100145100146100147100148100149100150100151100152100153100154100155100156100157100158100159100160100161100162100163100164100165100166100167100168100169100170100171100172100173100174100175100176100177100178100179100180100181100182100183100184100185100186100187100188100189100190100191100192100193100194100195100196100197100198100199100200100201100202100203100204100205100206100207100208100209100210100211100212100213100214100215100216100217100218100219100220100221100222100223100224100225100226100227100228100229100230100231100232100233100234100235100236100237100238100239100240100241100242100243100244100245100246100247100248100249100250100251100252100253100254100255100256100257100258100259100260100261100262100263100264100265100266100267100268100269100270100271100272100273100274100275100276100277100278100279100280100281100282100283100284100285100286100287100288100289100290100291100292100293100294100295100296100297100298100299100300100301100302100303100304100305100306100307100308100309100310100311100312100313100314100315100316100317100318100319100320100321100322100323100324100325100326100327100328100329100330100331100332100333100334100335100336100337100338100339100340100341100342100343100344100345100346100347100348100349100350100351100352100353100354100355100356100357100358100359100360100361100362100363100364100365100366100367100368100369100370100371100372100373100374100375100376100377100378100379100380100381100382100383100384100385100386100387100388100389100390100391100392100393100394100395100396100397100398100399100400100401100402100403100404100405100406100407100408100409100410100411100412100413100414100415100416100417100418100419100420100421100422100423100424100425100426100427100428100429100430100431100432100433100434100435100436100437100438100439100440100441100442100443100444100445100446100447100448100449100450100451100452100453100454100455100456100457100458100459100460100461100462100463100464100465100466100467100468100469100470100471100472100473100474100475100476100477100478100479100480100481100482100483100484100485100486100487100488100489100490100491100492100493100494100495100496100497100498100499100500100501100502100503100504100505100506100507100508100509100510100511100512100513100514100515100516100517100518100519100520100521100522100523100524100525100526100527100528100529100530100531100532100533100534100535100536100537100538100539100540100541100542100543100544100545100546100547100548100549100550100551100552100553100554100555100556100557100558100559100560100561100562100563100564100565100566100567100568100569100570100571100572100573100574100575100576100577100578100579100580100581100582100583100584100585100586100587100588100589100590100591100592100593100594100595100596100597100598100599100600100601100602100603100604100605100606100607100608100609100610100611100612100613100614100615100616100617100618100619100620100621100622100623100624100625100626100627100628100629100630100631100632100633100634100635100636100637100638100639100640100641100642100643100644100645100646100647100648100649100650100651100652100653100654100655100656100657100658100659100660100661100662100663100664100665100666100667100668100669100670100671100672100673100674100675100676100677100678100679100680100681100682100683100684100685100686100687100688100689100690100691100692100693100694100695100696100697100698100699100700100701100702100703100704100705100706100707100708100709100710100711100712100713100714100715100716100717100718100719100720100721100722100723100724100725100726100727100728100729100730100731100732100733100734100735100736100737100738100739100740100741100742100743100744100745100746100747100748100749100750100751100752100753100754100755100756100757100758100759100760100761100762100763100764100765100766100767100768100769100770100771100772100773100774100775100776100777100778100779100780100781100782100783100784100785100786100787100788100789100790100791100792100793100794100795100796100797100798100799100800100801100802100803100804100805100806100807100808100809100810100811100812100813100814100815100816100817100818100819100820100821100822100823100824100825100826100827100828100829100830100831100832100833100834100835100836100837100838100839100840100841100842100843100844100845100846100847100848100849100850100851100852100853100854100855100856100857100858100859100860100861100862100863100864100865100866100867100868100869100870100871100872100873100874100875100876100877100878100879100880100881100882100883100884100885100886100887100888100889100890100891100892100893100894100895100896100897100898100899100900100901100902100903100904100905100906100907100908100909100910100911100912100913100914100915100916100917100918100919100920100921100922100923100924100925100926100927100928100929100930100931100932100933100934100935100936100937100938100939100940100941100942100943100944100945100946100947100948100949100950100951100952100953100954100955100956100957100958100959100960100961100962100963100964100965100966100967100968100969100970100971100972100973100974100975100976100977100978100979100980100981100982100983100984100985100986100987100988100989100990100991100992100993100994100995100996100997100998100999101000101001101002101003101004101005101006101007101008101009101010101011101012101013101014101015101016101017101018101019101020101021101022101023101024101025101026101027101028101029101030101031101032101033101034101035101036101037101038101039101040101041101042101043101044101045101046101047101048101049101050101051101052101053101054101055101056101057101058101059101060101061101062101063101064101065101066101067101068101069101070101071101072101073101074101075101076101077101078101079101080101081101082101083101084101085101086101087101088101089101090101091101092101093101094101095101096101097101098101099101100101101101102101103101104101105101106101107101108101109101110101111101112101113101114101115101116101117101118101119101120101121101122101123101124101125101126101127101128101129101130101131101132101133101134101135101136101137101138101139101140101141101142101143101144101145101146101147101148101149101150101151101152101153101154101155101156101157101158101159101160101161101162101163101164101165101166101167101168101169101170101171101172101173101174101175101176101177101178101179101180101181101182101183101184101185101186101187101188101189101190101191101192101193101194101195101196101197101198101199101200101201101202101203101204101205101206101207101208101209101210101211101212101213101214101215101216101217101218101219101220101221101222101223101224101225101226101227101228101229101230101231101232101233101234101235101236101237101238101239101240101241101242101243101244101245101246101247101248101249101250101251101252101253101254101255101256101257101258101259101260101261101262101263101264101265101266101267101268101269101270101271101272101273101274101275101276101277101278101279101280101281101282101283101284101285101286101287101288101289101290101291101292101293101294101295101296101297101298101299101300101301101302101303101304101305101306101307101308101309101310101311101312101313101314101315101316101317101318101319101320101321101322101323101324101325101326101327101328101329101330101331101332101333101334101335101336101337101338101339101340101341101342101343101344101345101346101347101348101349101350101351101352101353101354101355101356101357101358101359101360101361101362101363101364101365101366101367101368101369101370101371101372101373101374101375101376101377101378101379101380101381101382101383101384101385101386101387101388101389101390101391101392101393101394101395101396101397101398101399101400101401101402101403101404101405101406101407101408101409101410101411101412101413101414101415101416101417101418101419101420101421101422101423101424101425101426101427101428101429101430101431101432101433101434101435101436101437101438101439101440101441101442101443101444101445101446101447101448101449101450101451101452101453101454101455101456101457101458101459101460101461101462101463101464101465101466101467101468101469101470101471101472101473101474101475101476101477101478101479101480101481101482101483101484101485101486101487101488101489101490101491101492101493101494101495101496101497101498101499101500101501101502101503101504101505101506101507101508101509101510101511101512101513101514101515101516101517101518101519101520101521101522101523101524101525101526101527101528101529101530101531101532101533101534101535101536101537101538101539101540101541101542101543101544101545101546101547101548101549101550101551101552101553101554101555101556101557101558101559101560101561101562101563101564101565101566101567101568101569101570101571101572101573101574101575101576101577101578101579101580101581101582101583101584101585101586101587101588101589101590101591101592101593101594101595101596101597101598101599101600101601101602101603101604101605101606101607101608101609101610101611101612101613101614101615101616101617101618101619101620101621101622101623101624101625101626101627101628101629101630101631101632101633101634101635101636101637101638101639101640101641101642101643101644101645101646101647101648101649101650101651101652101653101654101655101656101657101658101659101660101661101662101663101664101665101666101667101668101669101670101671101672101673101674101675101676101677101678101679101680101681101682101683101684101685101686101687101688101689101690101691101692101693101694101695101696101697101698101699101700101701101702101703101704101705101706101707101708101709101710101711101712101713101714101715101716101717101718101719101720101721101722101723101724101725101726101727101728101729101730101731101732101733101734101735101736101737101738101739101740101741101742101743101744101745101746101747101748101749101750101751101752101753101754101755101756101757101758101759101760101761101762101763101764101765101766101767101768101769101770101771101772101773101774101775101776101777101778101779101780101781101782101783101784101785101786101787101788101789101790101791101792101793101794101795101796101797101798101799101800101801101802101803101804101805101806101807101808101809101810101811101812101813101814101815101816101817101818101819101820101821101822101823101824101825101826101827101828101829101830101831101832101833101834101835101836101837101838101839101840101841101842101843101844101845101846101847101848101849101850101851101852101853101854101855101856101857101858101859101860101861101862101863101864101865101866101867101868101869101870101871101872101873101874101875101876101877101878101879101880101881101882101883101884101885101886101887101888101889101890101891101892101893101894101895101896101897101898101899101900101901101902101903101904101905101906101907101908101909101910101911101912101913101914101915101916101917101918101919101920101921101922101923101924101925101926101927101928101929101930101931101932101933101934101935101936101937101938101939101940101941101942101943101944101945101946101947101948101949101950101951101952101953101954101955101956101957101958101959101960101961101962101963101964101965101966101967101968101969101970101971101972101973101974101975101976101977101978101979101980101981101982101983101984101985101986101987101988101989101990101991101992101993101994101995101996101997101998101999102000102001102002102003102004102005102006102007102008102009102010102011102012102013102014102015102016102017102018102019102020102021102022102023102024102025102026102027102028102029102030102031102032102033102034102035102036102037102038102039102040102041102042102043102044102045102046102047102048102049102050102051102052102053102054102055102056102057102058102059102060102061102062102063102064102065102066102067102068102069102070102071102072102073102074102075102076102077102078102079102080102081102082102083102084102085102086102087102088102089102090102091102092102093102094102095102096102097102098102099102100102101102102102103102104102105102106102107102108102109102110102111102112102113102114102115102116102117102118102119102120102121102122102123102124102125102126102127102128102129102130102131102132102133102134102135102136102137102138102139102140102141102142102143102144102145102146102147102148102149102150102151102152102153102154102155102156102157102158102159102160102161102162102163102164102165102166102167102168102169102170102171102172102173102174102175102176102177102178102179102180102181102182102183102184102185102186102187102188102189102190102191102192102193102194102195102196102197102198102199102200102201102202102203102204102205102206102207102208102209102210102211102212102213102214102215102216102217102218102219102220102221102222102223102224102225102226102227102228102229102230102231102232102233102234102235102236102237102238102239102240102241102242102243102244102245102246102247102248102249102250102251102252102253102254102255102256102257102258102259102260102261102262102263102264102265102266102267102268102269102270102271102272102273102274102275102276102277102278102279102280102281102282102283102284102285102286102287102288102289102290102291102292102293102294102295102296102297102298102299102300102301102302102303102304102305102306102307102308102309102310102311102312102313102314102315102316102317102318102319102320102321102322102323102324102325102326102327102328102329102330102331102332102333102334102335102336102337102338102339102340102341102342102343102344102345102346102347102348102349102350102351102352102353102354102355102356102357102358102359102360102361102362102363102364102365102366102367102368102369102370102371102372102373102374102375102376102377102378102379102380102381102382102383102384102385102386102387102388102389102390102391102392102393102394102395102396102397102398102399102400102401102402102403102404102405102406102407102408102409102410102411102412102413102414102415102416102417102418102419102420102421102422102423102424102425102426102427102428102429102430102431102432102433102434102435102436102437102438102439102440102441102442102443102444102445102446102447102448102449102450102451102452102453102454102455102456102457102458102459102460102461102462102463102464102465102466102467102468102469102470102471102472102473102474102475102476102477102478102479102480102481102482102483102484102485102486102487102488102489102490102491102492102493102494102495102496102497102498102499102500102501102502102503102504102505102506102507102508102509102510102511102512102513102514102515102516102517102518102519102520102521102522102523102524102525102526102527102528102529102530102531102532102533102534102535102536102537102538102539102540102541102542102543102544102545102546102547102548102549102550102551102552102553102554102555102556102557102558102559102560102561102562102563102564102565102566102567102568102569102570102571102572102573102574102575102576102577102578102579102580102581102582102583102584102585102586102587102588102589102590102591102592102593102594102595102596102597102598102599102600102601102602102603102604102605102606102607102608102609102610102611102612102613102614102615102616102617102618102619102620102621102622102623102624102625102626102627102628102629102630102631102632102633102634102635102636102637102638102639102640102641102642102643102644102645102646102647102648102649102650102651102652102653102654102655102656102657102658102659102660102661102662102663102664102665102666102667102668102669102670102671102672102673102674102675102676102677102678102679102680102681102682102683102684102685102686102687102688102689102690102691102692102693102694102695102696102697102698102699102700102701102702102703102704102705102706102707102708102709102710102711102712102713102714102715102716102717102718102719102720102721102722102723102724102725102726102727102728102729102730102731102732102733102734102735102736102737102738102739102740102741102742102743102744102745102746102747102748102749102750102751102752102753102754102755102756102757102758102759102760102761102762102763102764102765102766102767102768102769102770102771102772102773102774102775102776102777102778102779102780102781102782102783102784102785102786102787102788102789102790102791102792102793102794102795102796102797102798102799102800102801102802102803102804102805102806102807102808102809102810102811102812102813102814102815102816102817102818102819102820102821102822102823102824102825102826102827102828102829102830102831102832102833102834102835102836102837102838102839102840102841102842102843102844102845102846102847102848102849102850102851102852102853102854102855102856102857102858102859102860102861102862102863102864102865102866102867102868102869102870102871102872102873102874102875102876102877102878102879102880102881102882102883102884102885102886102887102888102889102890102891102892102893102894102895102896102897102898102899102900102901102902102903102904102905102906102907102908102909102910102911102912102913102914102915102916102917102918102919102920102921102922102923102924102925102926102927102928102929102930102931102932102933102934102935102936102937102938102939102940102941102942102943102944102945102946102947102948102949102950102951102952102953102954102955102956102957102958102959102960102961102962102963102964102965102966102967102968102969102970102971102972102973102974102975102976102977102978102979102980102981102982102983102984102985102986102987102988102989102990102991102992102993102994102995102996102997102998102999103000103001103002103003103004103005103006103007103008103009103010103011103012103013103014103015103016103017103018103019103020103021103022103023103024103025103026103027103028103029103030103031103032103033103034103035103036103037103038103039103040103041103042103043103044103045103046103047103048103049103050103051103052103053103054103055103056103057103058103059103060103061103062103063103064103065103066103067103068103069103070103071103072103073103074103075103076103077103078103079103080103081103082103083103084103085103086103087103088103089103090103091103092103093103094103095103096103097103098103099103100103101103102103103103104103105103106103107103108103109103110103111103112103113103114103115103116103117103118103119103120103121103122103123103124103125103126103127103128103129103130103131103132103133103134103135103136103137103138103139103140103141103142103143103144103145103146103147103148103149103150103151103152103153103154103155103156103157103158103159103160103161103162103163103164103165103166103167103168103169103170103171103172103173103174103175103176103177103178103179103180103181103182103183103184103185103186103187103188103189103190103191103192103193103194103195103196103197103198103199103200103201103202103203103204103205103206103207103208103209103210103211103212103213103214103215103216103217103218103219103220103221103222103223103224103225103226103227103228103229103230103231103232103233103234103235103236103237103238103239103240103241103242103243103244103245103246103247103248103249103250103251103252103253103254103255103256103257103258103259103260103261103262103263103264103265103266103267103268103269103270103271103272103273103274103275103276103277103278103279103280103281103282103283103284103285103286103287103288103289103290103291103292103293103294103295103296103297103298103299103300103301103302103303103304103305103306103307103308103309103310103311103312103313103314103315103316103317103318103319103320103321103322103323103324103325103326103327103328103329103330103331103332103333103334103335103336103337103338103339103340103341103342103343103344103345103346103347103348103349103350103351103352103353103354103355103356103357103358103359103360103361103362103363103364103365103366103367103368103369103370103371103372103373103374103375103376103377103378103379103380103381103382103383103384103385103386103387103388103389103390103391103392103393103394103395103396103397103398103399103400103401103402103403103404103405103406103407103408103409103410103411103412103413103414103415103416103417103418103419103420103421103422103423103424103425103426103427103428103429103430103431103432103433103434103435103436103437103438103439103440103441103442103443103444103445103446103447103448103449103450103451103452103453103454103455103456103457103458103459103460103461103462103463103464103465103466103467103468103469103470103471103472103473103474103475103476103477103478103479103480103481103482103483103484103485103486103487103488103489103490103491103492103493103494103495103496103497103498103499103500103501103502103503103504103505103506103507103508103509103510103511103512103513103514103515103516103517103518103519103520103521103522103523103524103525103526103527103528103529103530103531103532103533103534103535103536103537103538103539103540103541103542103543103544103545103546103547103548103549103550103551103552103553103554103555103556103557103558103559103560103561103562103563103564103565103566103567103568103569103570103571103572103573103574103575103576103577103578103579103580103581103582103583103584103585103586103587103588103589103590103591103592103593103594103595103596103597103598103599103600103601103602103603103604103605103606103607103608103609103610103611103612103613103614103615103616103617103618103619103620103621103622103623103624103625103626103627103628103629103630103631103632103633103634103635103636103637103638103639103640103641103642103643103644103645103646103647103648103649103650103651103652103653103654103655103656103657103658103659103660103661103662103663103664103665103666103667103668103669103670103671103672103673103674103675103676103677103678103679103680103681103682103683103684103685103686103687103688103689103690103691103692103693103694103695103696103697103698103699103700103701103702103703103704103705103706103707103708103709103710103711103712103713103714103715103716103717103718103719103720103721103722103723103724103725103726103727103728103729103730103731103732103733103734103735103736103737103738103739103740103741103742103743103744103745103746103747103748103749103750103751103752103753103754103755103756103757103758103759103760103761103762103763103764103765103766103767103768103769103770103771103772103773103774103775103776103777103778103779103780103781103782103783103784103785103786103787103788103789103790103791103792103793103794103795103796103797103798103799103800103801103802103803103804103805103806103807103808103809103810103811103812103813103814103815103816103817103818103819103820103821103822103823103824103825103826103827103828103829103830103831103832103833103834103835103836103837103838103839103840103841103842103843103844103845103846103847103848103849103850103851103852103853103854103855103856103857103858103859103860103861103862103863103864103865103866103867103868103869103870103871103872103873103874103875103876103877103878103879103880103881103882103883103884103885103886103887103888103889103890103891103892103893103894103895103896103897103898103899103900103901103902103903103904103905103906103907103908103909103910103911103912103913103914103915103916103917103918103919103920103921103922103923103924103925103926103927103928103929103930103931103932103933103934103935103936103937103938103939103940103941103942103943103944103945103946103947103948103949103950103951103952103953103954103955103956103957103958103959103960103961103962103963103964103965103966103967103968103969103970103971103972103973103974103975103976103977103978103979103980103981103982103983103984103985103986103987103988103989103990103991103992103993103994103995103996103997103998103999104000104001104002104003104004104005104006104007104008104009104010104011104012104013104014104015104016104017104018104019104020104021104022104023104024104025104026104027104028104029104030104031104032104033104034104035104036104037104038104039104040104041104042104043104044104045104046104047104048104049104050104051104052104053104054104055104056104057104058104059104060104061104062104063104064104065104066104067104068104069104070104071104072104073104074104075104076104077104078104079104080104081104082104083104084104085104086104087104088104089104090104091104092104093104094104095104096104097104098104099104100104101104102104103104104104105104106104107104108104109104110104111104112104113104114104115104116104117104118104119104120104121104122104123104124104125104126104127104128104129104130104131104132104133104134104135104136104137104138104139104140104141104142104143104144104145104146104147104148104149104150104151104152104153104154104155104156104157104158104159104160104161104162104163104164104165104166104167104168104169104170104171104172104173104174104175104176104177104178104179104180104181104182104183104184104185104186104187104188104189104190104191104192104193104194104195104196104197104198104199104200104201104202104203104204104205104206104207104208104209104210104211104212104213104214104215104216104217104218104219104220104221104222104223104224104225104226104227104228104229104230104231104232104233104234104235104236104237104238104239104240104241104242104243104244104245104246104247104248104249104250104251104252104253104254104255104256104257104258104259104260104261104262104263104264104265104266104267104268104269104270104271104272104273104274104275104276104277104278104279104280104281104282104283104284104285104286104287104288104289104290104291104292104293104294104295104296104297104298104299104300104301104302104303104304104305104306104307104308104309104310104311104312104313104314104315104316104317104318104319104320104321104322104323104324104325104326104327104328104329104330104331104332104333104334104335104336104337104338104339104340104341104342104343104344104345104346104347104348104349104350104351104352104353104354104355104356104357104358104359104360104361104362104363104364104365104366104367104368104369104370104371104372104373104374104375104376104377104378104379104380104381104382104383104384104385104386104387104388104389104390104391104392104393104394104395104396104397104398104399104400104401104402104403104404104405104406104407104408104409104410104411104412104413104414104415104416104417104418104419104420104421104422104423104424104425104426104427104428104429104430104431104432104433104434104435104436104437104438104439104440104441104442104443104444104445104446104447104448104449104450104451104452104453104454104455104456104457104458104459104460104461104462104463104464104465104466104467104468104469104470104471104472104473104474104475104476104477104478104479104480104481104482104483104484104485104486104487104488104489104490104491104492104493104494104495104496104497104498104499104500104501104502104503104504104505104506104507104508104509104510104511104512104513104514104515104516104517104518104519104520104521104522104523104524104525104526104527104528104529104530104531104532104533104534104535104536104537104538104539104540104541104542104543104544104545104546104547104548104549104550104551104552104553104554104555104556104557104558104559104560104561104562104563104564104565104566104567104568104569104570104571104572104573104574104575104576104577104578104579104580104581104582104583104584104585104586104587104588104589104590104591104592104593104594104595104596104597104598104599104600104601104602104603104604104605104606104607104608104609104610104611104612104613104614104615104616104617104618104619104620104621104622104623104624104625104626104627104628104629104630104631104632104633104634104635104636104637104638104639104640104641104642104643104644104645104646104647104648104649104650104651104652104653104654104655104656104657104658104659104660104661104662104663104664104665104666104667104668104669104670104671104672104673104674104675104676104677104678104679104680104681104682104683104684104685104686104687104688104689104690104691104692104693104694104695104696104697104698104699104700104701104702104703104704104705104706104707104708104709104710104711104712104713104714104715104716104717104718104719104720104721104722104723104724104725104726104727104728104729104730104731104732104733104734104735104736104737104738104739104740104741104742104743104744104745104746104747104748104749104750104751104752104753104754104755104756104757104758104759104760104761104762104763104764104765104766104767104768104769104770104771104772104773104774104775104776104777104778104779104780104781104782104783104784104785104786104787104788104789104790104791104792104793104794104795104796104797104798104799104800104801104802104803104804104805104806104807104808104809104810104811104812104813104814104815104816104817104818104819104820104821104822104823104824104825104826104827104828104829104830104831104832104833104834104835104836104837104838104839104840104841104842104843104844104845104846104847104848104849104850104851104852104853104854104855104856104857104858104859104860104861104862104863104864104865104866104867104868104869104870104871104872104873104874104875104876104877104878104879104880104881104882104883104884104885104886104887104888104889104890104891104892104893104894104895104896104897104898104899104900104901104902104903104904104905104906104907104908104909104910104911104912104913104914104915104916104917104918104919104920104921104922104923104924104925104926104927104928104929104930104931104932104933104934104935104936104937104938104939104940104941104942104943104944104945104946104947104948104949104950104951104952104953104954104955104956104957104958104959104960104961104962104963104964104965104966104967104968104969104970104971104972104973104974104975104976104977104978104979104980104981104982104983104984104985104986104987104988104989104990104991104992104993104994104995104996104997104998104999105000105001105002105003105004105005105006105007105008105009105010105011105012105013105014105015105016105017105018105019105020105021105022105023105024105025105026105027105028105029105030105031105032105033105034105035105036105037105038105039105040105041105042105043105044105045105046105047105048105049105050105051105052105053105054105055105056105057105058105059105060105061105062105063105064105065105066105067105068105069105070105071105072105073105074105075105076105077105078105079105080105081105082105083105084105085105086105087105088105089105090105091105092105093105094105095105096105097105098105099105100105101105102105103105104105105105106105107105108105109105110105111105112105113105114105115105116105117105118105119105120105121105122105123105124105125105126105127105128105129105130105131105132105133105134105135105136105137105138105139105140105141105142105143105144105145105146105147105148105149105150105151105152105153105154105155105156105157105158105159105160105161105162105163105164105165105166105167105168105169105170105171105172105173105174105175105176105177105178105179105180105181105182105183105184105185105186105187105188105189105190105191105192105193105194105195105196105197105198105199105200105201105202105203105204105205105206105207105208105209105210105211105212105213105214105215105216105217105218105219105220105221105222105223105224105225105226105227105228105229105230105231105232105233105234105235105236105237105238105239105240105241105242105243105244105245105246105247105248105249105250105251105252105253105254105255105256105257105258105259105260105261105262105263105264105265105266105267105268105269105270105271105272105273105274105275105276105277105278105279105280105281105282105283105284105285105286105287105288105289105290105291105292105293105294105295105296105297105298105299105300105301105302105303105304105305105306105307105308105309105310105311105312105313105314105315105316105317105318105319105320105321105322105323105324105325105326105327105328105329105330105331105332105333105334105335105336105337105338105339105340105341105342105343105344105345105346105347105348105349105350105351105352105353105354105355105356105357105358105359105360105361105362105363105364105365105366105367105368105369105370105371105372105373105374105375105376105377105378105379105380105381105382105383105384105385105386105387105388105389105390105391105392105393105394105395105396105397105398105399105400105401105402105403105404105405105406105407105408105409105410105411105412105413105414105415105416105417105418105419105420105421105422105423105424105425105426105427105428105429105430105431105432105433105434105435105436105437105438105439105440105441105442105443105444105445105446105447105448105449105450105451105452105453105454105455105456105457105458105459105460105461105462105463105464105465105466105467105468105469105470105471105472105473105474105475105476105477105478105479105480105481105482105483105484105485105486105487105488105489105490105491105492105493105494105495105496105497105498105499105500105501105502105503105504105505105506105507105508105509105510105511105512105513105514105515105516105517105518105519105520105521105522105523105524105525105526105527105528105529105530105531105532105533105534105535105536105537105538105539105540105541105542105543105544105545105546105547105548105549105550105551105552105553105554105555105556105557105558105559105560105561105562105563105564105565105566105567105568105569105570105571105572105573105574105575105576105577105578105579105580105581105582105583105584105585105586105587105588105589105590105591105592105593105594105595105596105597105598105599105600105601105602105603105604105605105606105607105608105609105610105611105612105613105614105615105616105617105618105619105620105621105622105623105624105625105626105627105628105629105630105631105632105633105634105635105636105637105638105639105640105641105642105643105644105645105646105647105648105649105650105651105652105653105654105655105656105657105658105659105660105661105662105663105664105665105666105667105668105669105670105671105672105673105674105675105676105677105678105679105680105681105682105683105684105685105686105687105688105689105690105691105692105693105694105695105696105697105698105699105700105701105702105703105704105705105706105707105708105709105710105711105712105713105714105715105716105717105718105719105720105721105722105723105724105725105726105727105728105729105730105731105732105733105734105735105736105737105738105739105740105741105742105743105744105745105746105747105748105749105750105751105752105753105754105755105756105757105758105759105760105761105762105763105764105765105766105767105768105769105770105771105772105773105774105775105776105777105778105779105780105781105782105783105784105785105786105787105788105789105790105791105792105793105794105795105796105797105798105799105800105801105802105803105804105805105806105807105808105809105810105811105812105813105814105815105816105817105818105819105820105821105822105823105824105825105826105827105828105829105830105831105832105833105834105835105836105837105838105839105840105841105842105843105844105845105846105847105848105849105850105851105852105853105854105855105856105857105858105859105860105861105862105863105864105865105866105867105868105869105870105871105872105873105874105875105876105877105878105879105880105881105882105883105884105885105886105887105888105889105890105891105892105893105894105895105896105897105898105899105900105901105902105903105904105905105906105907105908105909105910105911105912105913105914105915105916105917105918105919105920105921105922105923105924105925105926105927105928105929105930105931105932105933105934105935105936105937105938105939105940105941105942105943105944105945105946105947105948105949105950105951105952105953105954105955105956105957105958105959105960105961105962105963105964105965105966105967105968105969105970105971105972105973105974105975105976105977105978105979105980105981105982105983105984105985105986105987105988105989105990105991105992105993105994105995105996105997105998105999106000106001106002106003106004106005106006106007106008106009106010106011106012106013106014106015106016106017106018106019106020106021106022106023106024106025106026106027106028106029106030106031106032106033106034106035106036106037106038106039106040106041106042106043106044106045106046106047106048106049106050106051106052106053106054106055106056106057106058106059106060106061106062106063106064106065106066106067106068106069106070106071106072106073106074106075106076106077106078106079106080106081106082106083106084106085106086106087106088106089106090106091106092106093106094106095106096106097106098106099106100106101106102106103106104106105106106106107106108106109106110106111106112106113106114106115106116106117106118106119106120106121106122106123106124106125106126106127106128106129106130106131106132106133106134106135106136106137106138106139106140106141106142106143106144106145106146106147106148106149106150106151106152106153106154106155106156106157106158106159106160106161106162106163106164106165106166106167106168106169106170106171106172106173106174106175106176106177106178106179106180106181106182106183106184106185106186106187106188106189106190106191106192106193106194106195106196106197106198106199106200106201106202106203106204106205106206106207106208106209106210106211106212106213106214106215106216106217106218106219106220106221106222106223106224106225106226106227106228106229106230106231106232106233106234106235106236106237106238106239106240106241106242106243106244106245106246106247106248106249106250106251106252106253106254106255106256106257106258106259106260106261106262106263106264106265106266106267106268106269106270106271106272106273106274106275106276106277106278106279106280106281106282106283106284106285106286106287106288106289106290106291106292106293106294106295106296106297106298106299106300106301106302106303106304106305106306106307106308106309106310106311106312106313106314106315106316106317106318106319106320106321106322106323106324106325106326106327106328106329106330106331106332106333106334106335106336106337106338106339106340106341106342106343106344106345106346106347106348106349106350106351106352106353106354106355106356106357106358106359106360106361106362106363106364106365106366106367106368106369106370106371106372106373106374106375106376106377106378106379106380106381106382106383106384106385106386106387106388106389106390106391106392106393106394106395106396106397106398106399106400106401106402106403106404106405106406106407106408106409106410106411106412106413106414106415106416106417106418106419106420106421106422106423106424106425106426106427106428106429106430106431106432106433106434106435106436106437106438106439106440106441106442106443106444106445106446106447106448106449106450106451106452106453106454106455106456106457106458106459106460106461106462106463106464106465106466106467106468106469106470106471106472106473106474106475106476106477106478106479106480106481106482106483106484106485106486106487106488106489106490106491106492106493106494106495106496106497106498106499106500106501106502106503106504106505106506106507106508106509106510106511106512106513106514106515106516106517106518106519106520106521106522106523106524106525106526106527106528106529106530106531106532106533106534106535106536106537106538106539106540106541106542106543106544106545106546106547106548106549106550106551106552106553106554106555106556106557106558106559106560106561106562106563106564106565106566106567106568106569106570106571106572106573106574106575106576106577106578106579106580106581106582106583106584106585106586106587106588106589106590106591106592106593106594106595106596106597106598106599106600106601106602106603106604106605106606106607106608106609106610106611106612106613106614106615106616106617106618106619106620106621106622106623106624106625106626106627106628106629106630106631106632106633106634106635106636106637106638106639106640106641106642106643106644106645106646106647106648106649106650106651106652106653106654106655106656106657106658106659106660106661106662106663106664106665106666106667106668106669106670106671106672106673106674106675106676106677106678106679106680106681106682106683106684106685106686106687106688106689106690106691106692106693106694106695106696106697106698106699106700106701106702106703106704106705106706106707106708106709106710106711106712106713106714106715106716106717106718106719106720106721106722106723106724106725106726106727106728106729106730106731106732106733106734106735106736106737106738106739106740106741106742106743106744106745106746106747106748106749106750106751106752106753106754106755106756106757106758106759106760106761106762106763106764106765106766106767106768106769106770106771106772106773106774106775106776106777106778106779106780106781106782106783106784106785106786106787106788106789106790106791106792106793106794106795106796106797106798106799106800106801106802106803106804106805106806106807106808106809106810106811106812106813106814106815106816106817106818106819106820106821106822106823106824106825106826106827106828106829106830106831106832106833106834106835106836106837106838106839106840106841106842106843106844106845106846106847106848106849106850106851106852106853106854106855106856106857106858106859106860106861106862106863106864106865106866106867106868106869106870106871106872106873106874106875106876106877106878106879106880106881106882106883106884106885106886106887106888106889106890106891106892106893106894106895106896106897106898106899106900106901106902106903106904106905106906106907106908106909106910106911106912106913106914106915106916106917106918106919106920106921106922106923106924106925106926106927106928106929106930106931106932106933106934106935106936106937106938106939106940106941106942106943106944106945106946106947106948106949106950106951106952106953106954106955106956106957106958106959106960106961106962106963106964106965106966106967106968106969106970106971106972106973106974106975106976106977106978106979106980106981106982106983106984106985106986106987106988106989106990106991106992106993106994106995106996106997106998106999107000107001107002107003107004107005107006107007107008107009107010107011107012107013107014107015107016107017107018107019107020107021107022107023107024107025107026107027107028107029107030107031107032107033107034107035107036107037107038107039107040107041107042107043107044107045107046107047107048107049107050107051107052107053107054107055107056107057107058107059107060107061107062107063107064107065107066107067107068107069107070107071107072107073107074107075107076107077107078107079107080107081107082107083107084107085107086107087107088107089107090107091107092107093107094107095107096107097107098107099107100107101107102107103107104107105107106107107107108107109107110107111107112107113107114107115107116107117107118107119107120107121107122107123107124107125107126107127107128107129107130107131107132107133107134107135107136107137107138107139107140107141107142107143107144107145107146107147107148107149107150107151107152107153107154107155107156107157107158107159107160107161107162107163107164107165107166107167107168107169107170107171107172107173107174107175107176107177107178107179107180107181107182107183107184107185107186107187107188107189107190107191107192107193107194107195107196107197107198107199107200107201107202107203107204107205107206107207107208107209107210107211107212107213107214107215107216107217107218107219107220107221107222107223107224107225107226107227107228107229107230107231107232107233107234107235107236107237107238107239107240107241107242107243107244107245107246107247107248107249107250107251107252107253107254107255107256107257107258107259107260107261107262107263107264107265107266107267107268107269107270107271107272107273107274107275107276107277107278107279107280107281107282107283107284107285107286107287107288107289107290107291107292107293107294107295107296107297107298107299107300107301107302107303107304107305107306107307107308107309107310107311107312107313107314107315107316107317107318107319107320107321107322107323107324107325107326107327107328107329107330107331107332107333107334107335107336107337107338107339107340107341107342107343107344107345107346107347107348107349107350107351107352107353107354107355107356107357107358107359107360107361107362107363107364107365107366107367107368107369107370107371107372107373107374107375107376107377107378107379107380107381107382107383107384107385107386107387107388107389107390107391107392107393107394107395107396107397107398107399107400107401107402107403107404107405107406107407107408107409107410107411107412107413107414107415107416107417107418107419107420107421107422107423107424107425107426107427107428107429107430107431107432107433107434107435107436107437107438107439107440107441107442107443107444107445107446107447107448107449107450107451107452107453107454107455107456107457107458107459107460107461107462107463107464107465107466107467107468107469107470107471107472107473107474107475107476107477107478107479107480107481107482107483107484107485107486107487107488107489107490107491107492107493107494107495107496107497107498107499107500107501107502107503107504107505107506107507107508107509107510107511107512107513107514107515107516107517107518107519107520107521107522107523107524107525107526107527107528107529107530107531107532107533107534107535107536107537107538107539107540107541107542107543107544107545107546107547107548107549107550107551107552107553107554107555107556107557107558107559107560107561107562107563107564107565107566107567107568107569107570107571107572107573107574107575107576107577107578107579107580107581107582107583107584107585107586107587107588107589107590107591107592107593107594107595107596107597107598107599107600107601107602107603107604107605107606107607107608107609107610107611107612107613107614107615107616107617107618107619107620107621107622107623107624107625107626107627107628107629107630107631107632107633107634107635107636107637107638107639107640107641107642107643107644107645107646107647107648107649107650107651107652107653107654107655107656107657107658107659107660107661107662107663107664107665107666107667107668107669107670107671107672107673107674107675107676107677107678107679107680107681107682107683107684107685107686107687107688107689107690107691107692107693107694107695107696107697107698107699107700107701107702107703107704107705107706107707107708107709107710107711107712107713107714107715107716107717107718107719107720107721107722107723107724107725107726107727107728107729107730107731107732107733107734107735107736107737107738107739107740107741107742107743107744107745107746107747107748107749107750107751107752107753107754107755107756107757107758107759107760107761107762107763107764107765107766107767107768107769107770107771107772107773107774107775107776107777107778107779107780107781107782107783107784107785107786107787107788107789107790107791107792107793107794107795107796107797107798107799107800107801107802107803107804107805107806107807107808107809107810107811107812107813107814107815107816107817107818107819107820107821107822107823107824107825107826107827107828107829107830107831107832107833107834107835107836107837107838107839107840107841107842107843107844107845107846107847107848107849107850107851107852107853107854107855107856107857107858107859107860107861107862107863107864107865107866107867107868107869107870107871107872107873107874107875107876107877107878107879107880107881107882107883107884107885107886107887107888107889107890107891107892107893107894107895107896107897107898107899107900107901107902107903107904107905107906107907107908107909107910107911107912107913107914107915107916107917107918107919107920107921107922107923107924107925107926107927107928107929107930107931107932107933107934107935107936107937107938107939107940107941107942107943107944107945107946107947107948107949107950107951107952107953107954107955107956107957107958107959107960107961107962107963107964107965107966107967107968107969107970107971107972107973107974107975107976107977107978107979107980107981107982107983107984107985107986107987107988107989107990107991107992107993107994107995107996107997107998107999108000108001108002108003108004108005108006108007108008108009108010108011108012108013108014108015108016108017108018108019108020108021108022108023108024108025108026108027108028108029108030108031108032108033108034108035108036108037108038108039108040108041108042108043108044108045108046108047108048108049108050108051108052108053108054108055108056108057108058108059108060108061108062108063108064108065108066108067108068108069108070108071108072108073108074108075108076108077108078108079108080108081108082108083108084108085108086108087108088108089108090108091108092108093108094108095108096108097108098108099108100108101108102108103108104108105108106108107108108108109108110108111108112108113108114108115108116108117108118108119108120108121108122108123108124108125108126108127108128108129108130108131108132108133108134108135108136108137108138108139108140108141108142108143108144108145108146108147108148108149108150108151108152108153108154108155108156108157108158108159108160108161108162108163108164108165108166108167108168108169108170108171108172108173108174108175108176108177108178108179108180108181108182108183108184108185108186108187108188108189108190108191108192108193108194108195108196108197108198108199108200108201108202108203108204108205108206108207108208108209108210108211108212108213108214108215108216108217108218108219108220108221108222108223108224108225108226108227108228108229108230108231108232108233108234108235108236108237108238108239108240108241108242108243108244108245108246108247108248108249108250108251108252108253108254108255108256108257108258108259108260108261108262108263108264108265108266108267108268108269108270108271108272108273108274108275108276108277108278108279108280108281108282108283108284108285108286108287108288108289108290108291108292108293108294108295108296108297108298108299108300108301108302108303108304108305108306108307108308108309108310108311108312108313108314108315108316108317108318108319108320108321108322108323108324108325108326108327108328108329108330108331108332108333108334108335108336108337108338108339108340108341108342108343108344108345108346108347108348108349108350108351108352108353108354108355108356108357108358108359108360108361108362108363108364108365108366108367108368108369108370108371108372108373108374108375108376108377108378108379108380108381108382108383108384108385108386108387108388108389108390108391108392108393108394108395108396108397108398108399108400108401108402108403108404108405108406108407108408108409108410108411108412108413108414108415108416108417108418108419108420108421108422108423108424108425108426108427108428108429108430108431108432108433108434108435108436108437108438108439108440108441108442108443108444108445108446108447108448108449108450108451108452108453108454108455108456108457108458108459108460108461108462108463108464108465108466108467108468108469108470108471108472108473108474108475108476108477108478108479108480108481108482108483108484108485108486108487108488108489108490108491108492108493108494108495108496108497108498108499108500108501108502108503108504108505108506108507108508108509108510108511108512108513108514108515108516108517108518108519108520108521108522108523108524108525108526108527108528108529108530108531108532108533108534108535108536108537108538108539108540108541108542108543108544108545108546108547108548108549108550108551108552108553108554108555108556108557108558108559108560108561108562108563108564108565108566108567108568108569108570108571108572108573108574108575108576108577108578108579108580108581108582108583108584108585108586108587108588108589108590108591108592108593108594108595108596108597108598108599108600108601108602108603108604108605108606108607108608108609108610108611108612108613108614108615108616108617108618108619108620108621108622108623108624108625108626108627108628108629108630108631108632108633108634108635108636108637108638108639108640108641108642108643108644108645108646108647108648108649108650108651108652108653108654108655108656108657108658108659108660108661108662108663108664108665108666108667108668108669108670108671108672108673108674108675108676108677108678108679108680108681108682108683108684108685108686108687108688108689108690108691108692108693108694108695108696108697108698108699108700108701108702108703108704108705108706108707108708108709108710108711108712108713108714108715108716108717108718108719108720108721108722108723108724108725108726108727108728108729108730108731108732108733108734108735108736108737108738108739108740108741108742108743108744108745108746108747108748108749108750108751108752108753108754108755108756108757108758108759108760108761108762108763108764108765108766108767108768108769108770108771108772108773108774108775108776108777108778108779108780108781108782108783108784108785108786108787108788108789108790108791108792108793108794108795108796108797108798108799108800108801108802108803108804108805108806108807108808108809108810108811108812108813108814108815108816108817108818108819108820108821108822108823108824108825108826108827108828108829108830108831108832108833108834108835108836108837108838108839108840108841108842108843108844108845108846108847108848108849108850108851108852108853108854108855108856108857108858108859108860108861108862108863108864108865108866108867108868108869108870108871108872108873108874108875108876108877108878108879108880108881108882108883108884108885108886108887108888108889108890108891108892108893108894108895108896108897108898108899108900108901108902108903108904108905108906108907108908108909108910108911108912108913108914108915108916108917108918108919108920108921108922108923108924108925108926108927108928108929108930108931108932108933108934108935108936108937108938108939108940108941108942108943108944108945108946108947108948108949108950108951108952108953108954108955108956108957108958108959108960108961108962108963108964108965108966108967108968108969108970108971108972108973108974108975108976108977108978108979108980108981108982108983108984108985108986108987108988108989108990108991108992108993108994108995108996108997108998108999109000109001109002109003109004109005109006109007109008109009109010109011109012109013109014109015109016109017109018109019109020109021109022109023109024109025109026109027109028109029109030109031109032109033109034109035109036109037109038109039109040109041109042109043109044109045109046109047109048109049109050109051109052109053109054109055109056109057109058109059109060109061109062109063109064109065109066109067109068109069109070109071109072109073109074109075109076109077109078109079109080109081109082109083109084109085109086109087109088109089109090109091109092109093109094109095109096109097109098109099109100109101109102109103109104109105109106109107109108109109109110109111109112109113109114109115109116109117109118109119109120109121109122109123109124109125109126109127109128109129109130109131109132109133109134109135109136109137109138109139109140109141109142109143109144109145109146109147109148109149109150109151109152109153109154109155109156109157109158109159109160109161109162109163109164109165109166109167109168109169109170109171109172109173109174109175109176109177109178109179109180109181109182109183109184109185109186109187109188109189109190109191109192109193109194109195109196109197109198109199109200109201109202109203109204109205109206109207109208109209109210109211109212109213109214109215109216109217109218109219109220109221109222109223109224109225109226109227109228109229109230109231109232109233109234109235109236109237109238109239109240109241109242109243109244109245109246109247109248109249109250109251109252109253109254109255109256109257109258109259109260109261109262109263109264109265109266109267109268109269109270109271109272109273109274109275109276109277109278109279109280109281109282109283109284109285109286109287109288109289109290109291109292109293109294109295109296109297109298109299109300109301109302109303109304109305109306109307109308109309109310109311109312109313109314109315109316109317109318109319109320109321109322109323109324109325109326109327109328109329109330109331109332109333109334109335109336109337109338109339109340109341109342109343109344109345109346109347109348109349109350109351109352109353109354109355109356109357109358109359109360109361109362109363109364109365109366109367109368109369109370109371109372109373109374109375109376109377109378109379109380109381109382109383109384109385109386109387109388109389109390109391109392109393109394109395109396109397109398109399109400109401109402109403109404109405109406109407109408109409109410109411109412109413109414109415109416109417109418109419109420109421109422109423109424109425109426109427109428109429109430109431109432109433109434109435109436109437109438109439109440109441109442109443109444109445109446109447109448109449109450109451109452109453109454109455109456109457109458109459109460109461109462109463109464109465109466109467109468109469109470109471109472109473109474109475109476109477109478109479109480109481109482109483109484109485109486109487109488109489109490109491109492109493109494109495109496109497109498109499109500109501109502109503109504109505109506109507109508109509109510109511109512109513109514109515109516109517109518109519109520109521109522109523109524109525109526109527109528109529109530109531109532109533109534109535109536109537109538109539109540109541109542109543109544109545109546109547109548109549109550109551109552109553109554109555109556109557109558109559109560109561109562109563109564109565109566109567109568109569109570109571109572109573109574109575109576109577109578109579109580109581109582109583109584109585109586109587109588109589109590109591109592109593109594109595109596109597109598109599109600109601109602109603109604109605109606109607109608109609109610109611109612109613109614109615109616109617109618109619109620109621109622109623109624109625109626109627109628109629109630109631109632109633109634109635109636109637109638109639109640109641109642109643109644109645109646109647109648109649109650109651109652109653109654109655109656109657109658109659109660109661109662109663109664109665109666109667109668109669109670109671109672109673109674109675109676109677109678109679109680109681109682109683109684109685109686109687109688109689109690109691109692109693109694109695109696109697109698109699109700109701109702109703109704109705109706109707109708109709109710109711109712109713109714109715109716109717109718109719109720109721109722109723109724109725109726109727109728109729109730109731109732109733109734109735109736109737109738109739109740109741109742109743109744109745109746109747109748109749109750109751109752109753109754109755109756109757109758109759109760109761109762109763109764109765109766109767109768109769109770109771109772109773109774109775109776109777109778109779109780109781109782109783109784109785109786109787109788109789109790109791109792109793109794109795109796109797109798109799109800109801109802109803109804109805109806109807109808109809109810109811109812109813109814109815109816109817109818109819109820109821109822109823109824109825109826109827109828109829109830109831109832109833109834109835109836109837109838109839109840109841109842109843109844109845109846109847109848109849109850109851109852109853109854109855109856109857109858109859109860109861109862109863109864109865109866109867109868109869109870109871109872109873109874109875109876109877109878109879109880109881109882109883109884109885109886109887109888109889109890109891109892109893109894109895109896109897109898109899109900109901109902109903109904109905109906109907109908109909109910109911109912109913109914109915109916109917109918109919109920109921109922109923109924109925109926109927109928109929109930109931109932109933109934109935109936109937109938109939109940109941109942109943109944109945109946109947109948109949109950109951109952109953109954109955109956109957109958109959109960109961109962109963109964109965109966109967109968109969109970109971109972109973109974109975109976109977109978109979109980109981109982109983109984109985109986109987109988109989109990109991109992109993109994109995109996109997109998109999110000110001110002110003110004110005110006110007110008110009110010110011110012110013110014110015110016110017110018110019110020110021110022110023110024110025110026110027110028110029110030110031110032110033110034110035110036110037110038110039110040110041110042110043110044110045110046110047110048110049110050110051110052110053110054110055110056110057110058110059110060110061110062110063110064110065110066110067110068110069110070110071110072110073110074110075110076110077110078110079110080110081110082110083110084110085110086110087110088110089110090110091110092110093110094110095110096110097110098110099110100110101110102110103110104110105110106110107110108110109110110110111110112110113110114110115110116110117110118110119110120110121110122110123110124110125110126110127110128110129110130110131110132110133110134110135110136110137110138110139110140110141110142110143110144110145110146110147110148110149110150110151110152110153110154110155110156110157110158110159110160110161110162110163110164110165110166110167110168110169110170110171110172110173110174110175110176110177110178110179110180110181110182110183110184110185110186110187110188110189110190110191110192110193110194110195110196110197110198110199110200110201110202110203110204110205110206110207110208110209110210110211110212110213110214110215110216110217110218110219110220110221110222110223110224110225110226110227110228110229110230110231110232110233110234110235110236110237110238110239110240110241110242110243110244110245110246110247110248110249110250110251110252110253110254110255110256110257110258110259110260110261110262110263110264110265110266110267110268110269110270110271110272110273110274110275110276110277110278110279110280110281110282110283110284110285110286110287110288110289110290110291110292110293110294110295110296110297110298110299110300110301110302110303110304110305110306110307110308110309110310110311110312110313110314110315110316110317110318110319110320110321110322110323110324110325110326110327110328110329110330110331110332110333110334110335110336110337110338110339110340110341110342110343110344110345110346110347110348110349110350110351110352110353110354110355110356110357110358110359110360110361110362110363110364110365110366110367110368110369110370110371110372110373110374110375110376110377110378110379110380110381110382110383110384110385110386110387110388110389110390110391110392110393110394110395110396110397110398110399110400110401110402110403110404110405110406110407110408110409110410110411110412110413110414110415110416110417110418110419110420110421110422110423110424110425110426110427110428110429110430110431110432110433110434110435110436110437110438110439110440110441110442110443110444110445110446110447110448110449110450110451110452110453110454110455110456110457110458110459110460110461110462110463110464110465110466110467110468110469110470110471110472110473110474110475110476110477110478110479110480110481110482110483110484110485110486110487110488110489110490110491110492110493110494110495110496110497110498110499110500110501110502110503110504110505110506110507110508110509110510110511110512110513110514110515110516110517110518110519110520110521110522110523110524110525110526110527110528110529110530110531110532110533110534110535110536110537110538110539110540110541110542110543110544110545110546110547110548110549110550110551110552110553110554110555110556110557110558110559110560110561110562110563110564110565110566110567110568110569110570110571110572110573110574110575110576110577110578110579110580110581110582110583110584110585110586110587110588110589110590110591110592110593110594110595110596110597110598110599110600110601110602110603110604110605110606110607110608110609110610110611110612110613110614110615110616110617110618110619110620110621110622110623110624110625110626110627110628110629110630110631110632110633110634110635110636110637110638110639110640110641110642110643110644110645110646110647110648110649110650110651110652110653110654110655110656110657110658110659110660110661110662110663110664110665110666110667110668110669110670110671110672110673110674110675110676110677110678110679110680110681110682110683110684110685110686110687110688110689110690110691110692110693110694110695110696110697110698110699110700110701110702110703110704110705110706110707110708110709110710110711110712110713110714110715110716110717110718110719110720110721110722110723110724110725110726110727110728110729110730110731110732110733110734110735110736110737110738110739110740110741110742110743110744110745110746110747110748110749110750110751110752110753110754110755110756110757110758110759110760110761110762110763110764110765110766110767110768110769110770110771110772110773110774110775110776110777110778110779110780110781110782110783110784110785110786110787110788110789110790110791110792110793110794110795110796110797110798110799110800110801110802110803110804110805110806110807110808110809110810110811110812110813110814110815110816110817110818110819110820110821110822110823110824110825110826110827110828110829110830110831110832110833110834110835110836110837110838110839110840110841110842110843110844110845110846110847110848110849110850110851110852110853110854110855110856110857110858110859110860110861110862110863110864110865110866110867110868110869110870110871110872110873110874110875110876110877110878110879110880110881110882110883110884110885110886110887110888110889110890110891110892110893110894110895110896110897110898110899110900110901110902110903110904110905110906110907110908110909110910110911110912110913110914110915110916110917110918110919110920110921110922110923110924110925110926110927110928110929110930110931110932110933110934110935110936110937110938110939110940110941110942110943110944110945110946110947110948110949110950110951110952110953110954110955110956110957110958110959110960110961110962110963110964110965110966110967110968110969110970110971110972110973110974110975110976110977110978110979110980110981110982110983110984110985110986110987110988110989110990110991110992110993110994110995110996110997110998110999111000111001111002111003111004111005111006111007111008111009111010111011111012111013111014111015111016111017111018111019111020111021111022111023111024111025111026111027111028111029111030111031111032111033111034111035111036111037111038111039111040111041111042111043111044111045111046111047111048111049111050111051111052111053111054111055111056111057111058111059111060111061111062111063111064111065111066111067111068111069111070111071111072111073111074111075111076111077111078111079111080111081111082111083111084111085111086111087111088111089111090111091111092111093111094111095111096111097111098111099111100111101111102111103111104111105111106111107111108111109111110111111111112111113111114111115111116111117111118111119111120111121111122111123111124111125111126111127111128111129111130111131111132111133111134111135111136111137111138111139111140111141111142111143111144111145111146111147111148111149111150111151111152111153111154111155111156111157111158111159111160111161111162111163111164111165111166111167111168111169111170111171111172111173111174111175111176111177111178111179111180111181111182111183111184111185111186111187111188111189111190111191111192111193111194111195111196111197111198111199111200111201111202111203111204111205111206111207111208111209111210111211111212111213111214111215111216111217111218111219111220111221111222111223111224111225111226111227111228111229111230111231111232111233111234111235111236111237111238111239111240111241111242111243111244111245111246111247111248111249111250111251111252111253111254111255111256111257111258111259111260111261111262111263111264111265111266111267111268111269111270111271111272111273111274111275111276111277111278111279111280111281111282111283111284111285111286111287111288111289111290111291111292111293111294111295111296111297111298111299111300111301111302111303111304111305111306111307111308111309111310111311111312111313111314111315111316111317111318111319111320111321111322111323111324111325111326111327111328111329111330111331111332111333111334111335111336111337111338111339111340111341111342111343111344111345111346111347111348111349111350111351111352111353111354111355111356111357111358111359111360111361111362111363111364111365111366111367111368111369111370111371111372111373111374111375111376111377111378111379111380111381111382111383111384111385111386111387111388111389111390111391111392111393111394111395111396111397111398111399111400111401111402111403111404111405111406111407111408111409111410111411111412111413111414111415111416111417111418111419111420111421111422111423111424111425111426111427111428111429111430111431111432111433111434111435111436111437111438111439111440111441111442111443111444111445111446111447111448111449111450111451111452111453111454111455111456111457111458111459111460111461111462111463111464111465111466111467111468111469111470111471111472111473111474111475111476111477111478111479111480111481111482111483111484111485111486111487111488111489111490111491111492111493111494111495111496111497111498111499111500111501111502111503111504111505111506111507111508111509111510111511111512111513111514111515111516111517111518111519111520111521111522111523111524111525111526111527111528111529111530111531111532111533111534111535111536111537111538111539111540111541111542111543111544111545111546111547111548111549111550111551111552111553111554111555111556111557111558111559111560111561111562111563111564111565111566111567111568111569111570111571111572111573111574111575111576111577111578111579111580111581111582111583111584111585111586111587111588111589111590111591111592111593111594111595111596111597111598111599111600111601111602111603111604111605111606111607111608111609111610111611111612111613111614111615111616111617111618111619111620111621111622111623111624111625111626111627111628111629111630111631111632111633111634111635111636111637111638111639111640111641111642111643111644111645111646111647111648111649111650111651111652111653111654111655111656111657111658111659111660111661111662111663111664111665111666111667111668111669111670111671111672111673111674111675111676111677111678111679111680111681111682111683111684111685111686111687111688111689111690111691111692111693111694111695111696111697111698111699111700111701111702111703111704111705111706111707111708111709111710111711111712111713111714111715111716111717111718111719111720111721111722111723111724111725111726111727111728111729111730111731111732111733111734111735111736111737111738111739111740111741111742111743111744111745111746111747111748111749111750111751111752111753111754111755111756111757111758111759111760111761111762111763111764111765111766111767111768111769111770111771111772111773111774111775111776111777111778111779111780111781111782111783111784111785111786111787111788111789111790111791111792111793111794111795111796111797111798111799111800111801111802111803111804111805111806111807111808111809111810111811111812111813111814111815111816111817111818111819111820111821111822111823111824111825111826111827111828111829111830111831111832111833111834111835111836111837111838111839111840111841111842111843111844111845111846111847111848111849111850111851111852111853111854111855111856111857111858111859111860111861111862111863111864111865111866111867111868111869111870111871111872111873111874111875111876111877111878111879111880111881111882111883111884111885111886111887111888111889111890111891111892111893111894111895111896111897111898111899111900111901111902111903111904111905111906111907111908111909111910111911111912111913111914111915111916111917111918111919111920111921111922111923111924111925111926111927111928111929111930111931111932111933111934111935111936111937111938111939111940111941111942111943111944111945111946111947111948111949111950111951111952111953111954111955111956111957111958111959111960111961111962111963111964111965111966111967111968111969111970111971111972111973111974111975111976111977111978111979111980111981111982111983111984111985111986111987111988111989111990111991111992111993111994111995111996111997111998111999112000112001112002112003112004112005112006112007112008112009112010112011112012112013112014112015112016112017112018112019112020112021112022112023112024112025112026112027112028112029112030112031112032112033112034112035112036112037112038112039112040112041112042112043112044112045112046112047112048112049112050112051112052112053112054112055112056112057112058112059112060112061112062112063112064112065112066112067112068112069112070112071112072112073112074112075112076112077112078112079112080112081112082112083112084112085112086112087112088112089112090112091112092112093112094112095112096112097112098112099112100112101112102112103112104112105112106112107112108112109112110112111112112112113112114112115112116112117112118112119112120112121112122112123112124112125112126112127112128112129112130112131112132112133112134112135112136112137112138112139112140112141112142112143112144112145112146112147112148112149112150112151112152112153112154112155112156112157112158112159112160112161112162112163112164112165112166112167112168112169112170112171112172112173112174112175112176112177112178112179112180112181112182112183112184112185112186112187112188112189112190112191112192112193112194112195112196112197112198112199112200112201112202112203112204112205112206112207112208112209112210112211112212112213112214112215112216112217112218112219112220112221112222112223112224112225112226112227112228112229112230112231112232112233112234112235112236112237112238112239112240112241112242112243112244112245112246112247112248112249112250112251112252112253112254112255112256112257112258112259112260112261112262112263112264112265112266112267112268112269112270112271112272112273112274112275112276112277112278112279112280112281112282112283112284112285112286112287112288112289112290112291112292112293112294112295112296112297112298112299112300112301112302112303112304112305112306112307112308112309112310112311112312112313112314112315112316112317112318112319112320112321112322112323112324112325112326112327112328112329112330112331112332112333112334112335112336112337112338112339112340112341112342112343112344112345112346112347112348112349112350112351112352112353112354112355112356112357112358112359112360112361112362112363112364112365112366112367112368112369112370112371112372112373112374112375112376112377112378112379112380112381112382112383112384112385112386112387112388112389112390112391112392112393112394112395112396112397112398112399112400112401112402112403112404112405112406112407112408112409112410112411112412112413112414112415112416112417112418112419112420112421112422112423112424112425112426112427112428112429112430112431112432112433112434112435112436112437112438112439112440112441112442112443112444112445112446112447112448112449112450112451112452112453112454112455112456112457112458112459112460112461112462112463112464112465112466112467112468112469112470112471112472112473112474112475112476112477112478112479112480112481112482112483112484112485112486112487112488112489112490112491112492112493112494112495112496112497112498112499112500112501112502112503112504112505112506112507112508112509112510112511112512112513112514112515112516112517112518112519112520112521112522112523112524112525112526112527112528112529112530112531112532112533112534112535112536112537112538112539112540112541112542112543112544112545112546112547112548112549112550112551112552112553112554112555112556112557112558112559112560112561112562112563112564112565112566112567112568112569112570112571112572112573112574112575112576112577112578112579112580112581112582112583112584112585112586112587112588112589112590112591112592112593112594112595112596112597112598112599112600112601112602112603112604112605112606112607112608112609112610112611112612112613112614112615112616112617112618112619112620112621112622112623112624112625112626112627112628112629112630112631112632112633112634112635112636112637112638112639112640112641112642112643112644112645112646112647112648112649112650112651112652112653112654112655112656112657112658112659112660112661112662112663112664112665112666112667112668112669112670112671112672112673112674112675112676112677112678112679112680112681112682112683112684112685112686112687112688112689112690112691112692112693112694112695112696112697112698112699112700112701112702112703112704112705112706112707112708112709112710112711112712112713112714112715112716112717112718112719112720112721112722112723112724112725112726112727112728112729112730112731112732112733112734112735112736112737112738112739112740112741112742112743112744112745112746112747112748112749112750112751112752112753112754112755112756112757112758112759112760112761112762112763112764112765112766112767112768112769112770112771112772112773112774112775112776112777112778112779112780112781112782112783112784112785112786112787112788112789112790112791112792112793112794112795112796112797112798112799112800112801112802112803112804112805112806112807112808112809112810112811112812112813112814112815112816112817112818112819112820112821112822112823112824112825112826112827112828112829112830112831112832112833112834112835112836112837112838112839112840112841112842112843112844112845112846112847112848112849112850112851112852112853112854112855112856112857112858112859112860112861112862112863112864112865112866112867112868112869112870112871112872112873112874112875112876112877112878112879112880112881112882112883112884112885112886112887112888112889112890112891112892112893112894112895112896112897112898112899112900112901112902112903112904112905112906112907112908112909112910112911112912112913112914112915112916112917112918112919112920112921112922112923112924112925112926112927112928112929112930112931112932112933112934112935112936112937112938112939112940112941112942112943112944112945112946112947112948112949112950112951112952112953112954112955112956112957112958112959112960112961112962112963112964112965112966112967112968112969112970112971112972112973112974112975112976112977112978112979112980112981112982112983112984112985112986112987112988112989112990112991112992112993112994112995112996112997112998112999113000113001113002113003113004113005113006113007113008113009113010113011113012113013113014113015113016113017113018113019113020113021113022113023113024113025113026113027113028113029113030113031113032113033113034113035113036113037113038113039113040113041113042113043113044113045113046113047113048113049113050113051113052113053113054113055113056113057113058113059113060113061113062113063113064113065113066113067113068113069113070113071113072113073113074113075113076113077113078113079113080113081113082113083113084113085113086113087113088113089113090113091113092113093113094113095113096113097113098113099113100113101113102113103113104113105113106113107113108113109113110113111113112113113113114113115113116113117113118113119113120113121113122113123113124113125113126113127113128113129113130113131113132113133113134113135113136113137113138113139113140113141113142113143113144113145113146113147113148113149113150113151113152113153113154113155113156113157113158113159113160113161113162113163113164113165113166113167113168113169113170113171113172113173113174113175113176113177113178113179113180113181113182113183113184113185113186113187113188113189113190113191113192113193113194113195113196113197113198113199113200113201113202113203113204113205113206113207113208113209113210113211113212113213113214113215113216113217113218113219113220113221113222113223113224113225113226113227113228113229113230113231113232113233113234113235113236113237113238113239113240113241113242113243113244113245113246113247113248113249113250113251113252113253113254113255113256113257113258113259113260113261113262113263113264113265113266113267113268113269113270113271113272113273113274113275113276113277113278113279113280113281113282113283113284113285113286113287113288113289113290113291113292113293113294113295113296113297113298113299113300113301113302113303113304113305113306113307113308113309113310113311113312113313113314113315113316113317113318113319113320113321113322113323113324113325113326113327113328113329113330113331113332113333113334113335113336113337113338113339113340113341113342113343113344113345113346113347113348113349113350113351113352113353113354113355113356113357113358113359113360113361113362113363113364113365113366113367113368113369113370113371113372113373113374113375113376113377113378113379113380113381113382113383113384113385113386113387113388113389113390113391113392113393113394113395113396113397113398113399113400113401113402113403113404113405113406113407113408113409113410113411113412113413113414113415113416113417113418113419113420113421113422113423113424113425113426113427113428113429113430113431113432113433113434113435113436113437113438113439113440113441113442113443113444113445113446113447113448113449113450113451113452113453113454113455113456113457113458113459113460113461113462113463113464113465113466113467113468113469113470113471113472113473113474113475113476113477113478113479113480113481113482113483113484113485113486113487113488113489113490113491113492113493113494113495113496113497113498113499113500113501113502113503113504113505113506113507113508113509113510113511113512113513113514113515113516113517113518113519113520113521113522113523113524113525113526113527113528113529113530113531113532113533113534113535113536113537113538113539113540113541113542113543113544113545113546113547113548113549113550113551113552113553113554113555113556113557113558113559113560113561113562113563113564113565113566113567113568113569113570113571113572113573113574113575113576113577113578113579113580113581113582113583113584113585113586113587113588113589113590113591113592113593113594113595113596113597113598113599113600113601113602113603113604113605113606113607113608113609113610113611113612113613113614113615113616113617113618113619113620113621113622113623113624113625113626113627113628113629113630113631113632113633113634113635113636113637113638113639113640113641113642113643113644113645113646113647113648113649113650113651113652113653113654113655113656113657113658113659113660113661113662113663113664113665113666113667113668113669113670113671113672113673113674113675113676113677113678113679113680113681113682113683113684113685113686113687113688113689113690113691113692113693113694113695113696113697113698113699113700113701113702113703113704113705113706113707113708113709113710113711113712113713113714113715113716113717113718113719113720113721113722113723113724113725113726113727113728113729113730113731113732113733113734113735113736113737113738113739113740113741113742113743113744113745113746113747113748113749113750113751113752113753113754113755113756113757113758113759113760113761113762113763113764113765113766113767113768113769113770113771113772113773113774113775113776113777113778113779113780113781113782113783113784113785113786113787113788113789113790113791113792113793113794113795113796113797113798113799113800113801113802113803113804113805113806113807113808113809113810113811113812113813113814113815113816113817113818113819113820113821113822113823113824113825113826113827113828113829113830113831113832113833113834113835113836113837113838113839113840113841113842113843113844113845113846113847113848113849113850113851113852113853113854113855113856113857113858113859113860113861113862113863113864113865113866113867113868113869113870113871113872113873113874113875113876113877113878113879113880113881113882113883113884113885113886113887113888113889113890113891113892113893113894113895113896113897113898113899113900113901113902113903113904113905113906113907113908113909113910113911113912113913113914113915113916113917113918113919113920113921113922113923113924113925113926113927113928113929113930113931113932113933113934113935113936113937113938113939113940113941113942113943113944113945113946113947113948113949113950113951113952113953113954113955113956113957113958113959113960113961113962113963113964113965113966113967113968113969113970113971113972113973113974113975113976113977113978113979113980113981113982113983113984113985113986113987113988113989113990113991113992113993113994113995113996113997113998113999114000114001114002114003114004114005114006114007114008114009114010114011114012114013114014114015114016114017114018114019114020114021114022114023114024114025114026114027114028114029114030114031114032114033114034114035114036114037114038114039114040114041114042114043114044114045114046114047114048114049114050114051114052114053114054114055114056114057114058114059114060114061114062114063114064114065114066114067114068114069114070114071114072114073114074114075114076114077114078114079114080114081114082114083114084114085114086114087114088114089114090114091114092114093114094114095114096114097114098114099114100114101114102114103114104114105114106114107114108114109114110114111114112114113114114114115114116114117114118114119114120114121114122114123114124114125114126114127114128114129114130114131114132114133114134114135114136114137114138114139114140114141114142114143114144114145114146114147114148114149114150114151114152114153114154114155114156114157114158114159114160114161114162114163114164114165114166114167114168114169114170114171114172114173114174114175114176114177114178114179114180114181114182114183114184114185114186114187114188114189114190114191114192114193114194114195114196114197114198114199114200114201114202114203114204114205114206114207114208114209114210114211114212114213114214114215114216114217114218114219114220114221114222114223114224114225114226114227114228114229114230114231114232114233114234114235114236114237114238114239114240114241114242114243114244114245114246114247114248114249114250114251114252114253114254114255114256114257114258114259114260114261114262114263114264114265114266114267114268114269114270114271114272114273114274114275114276114277114278114279114280114281114282114283114284114285114286114287114288114289114290114291114292114293114294114295114296114297114298114299114300114301114302114303114304114305114306114307114308114309114310114311114312114313114314114315114316114317114318114319114320114321114322114323114324114325114326114327114328114329114330114331114332114333114334114335114336114337114338114339114340114341114342114343114344114345114346114347114348114349114350114351114352114353114354114355114356114357114358114359114360114361114362114363114364114365114366114367114368114369114370114371114372114373114374114375114376114377114378114379114380114381114382114383114384114385114386114387114388114389114390114391114392114393114394114395114396114397114398114399114400114401114402114403114404114405114406114407114408114409114410114411114412114413114414114415114416114417114418114419114420114421114422114423114424114425114426114427114428114429114430114431114432114433114434114435114436114437114438114439114440114441114442114443114444114445114446114447114448114449114450114451114452114453114454114455114456114457114458114459114460114461114462114463114464114465114466114467114468114469114470114471114472114473114474114475114476114477114478114479114480114481114482114483114484114485114486114487114488114489114490114491114492114493114494114495114496114497114498114499114500114501114502114503114504114505114506114507114508114509114510114511114512114513114514114515114516114517114518114519114520114521114522114523114524114525114526114527114528114529114530114531114532114533114534114535114536114537114538114539114540114541114542114543114544114545114546114547114548114549114550114551114552114553114554114555114556114557114558114559114560114561114562114563114564114565114566114567114568114569114570114571114572114573114574114575114576114577114578114579114580114581114582114583114584114585114586114587114588114589114590114591114592114593114594114595114596114597114598114599114600114601114602114603114604114605114606114607114608114609114610114611114612114613114614114615114616114617114618114619114620114621114622114623114624114625114626114627114628114629114630114631114632114633114634114635114636114637114638114639114640114641114642114643114644114645114646114647114648114649114650114651114652114653114654114655114656114657114658114659114660114661114662114663114664114665114666114667114668114669114670114671114672114673114674114675114676114677114678114679114680114681114682114683114684114685114686114687114688114689114690114691114692114693114694114695114696114697114698114699114700114701114702114703114704114705114706114707114708114709114710114711114712114713114714114715114716114717114718114719114720114721114722114723114724114725114726114727114728114729114730114731114732114733114734114735114736114737114738114739114740114741114742114743114744114745114746114747114748114749114750114751114752114753114754114755114756114757114758114759114760114761114762114763114764114765114766114767114768114769114770114771114772114773114774114775114776114777114778114779114780114781114782114783114784114785114786114787114788114789114790114791114792114793114794114795114796114797114798114799114800114801114802114803114804114805114806114807114808114809114810114811114812114813114814114815114816114817114818114819114820114821114822114823114824114825114826114827114828114829114830114831114832114833114834114835114836114837114838114839114840114841114842114843114844114845114846114847114848114849114850114851114852114853114854114855114856114857114858114859114860114861114862114863114864114865114866114867114868114869114870114871114872114873114874114875114876114877114878114879114880114881114882114883114884114885114886114887114888114889114890114891114892114893114894114895114896114897114898114899114900114901114902114903114904114905114906114907114908114909114910114911114912114913114914114915114916114917114918114919114920114921114922114923114924114925114926114927114928114929114930114931114932114933114934114935114936114937114938114939114940114941114942114943114944114945114946114947114948114949114950114951114952114953114954114955114956114957114958114959114960114961114962114963114964114965114966114967114968114969114970114971114972114973114974114975114976114977114978114979114980114981114982114983114984114985114986114987114988114989114990114991114992114993114994114995114996114997114998114999115000115001115002115003115004115005115006115007115008115009115010115011115012115013115014115015115016115017115018115019115020115021115022115023115024115025115026115027115028115029115030115031115032115033115034115035115036115037115038115039115040115041115042115043115044115045115046115047115048115049115050115051115052115053115054115055115056115057115058115059115060115061115062115063115064115065115066115067115068115069115070115071115072115073115074115075115076115077115078115079115080115081115082115083115084115085115086115087115088115089115090115091115092115093115094115095115096115097115098115099115100115101115102115103115104115105115106115107115108115109115110115111115112115113115114115115115116115117115118115119115120115121115122115123115124115125115126115127115128115129115130115131115132115133115134115135115136115137115138115139115140115141115142115143115144115145115146115147115148115149115150115151115152115153115154115155115156115157115158115159115160115161115162115163115164115165115166115167115168115169115170115171115172115173115174115175115176115177115178115179115180115181115182115183115184115185115186115187115188115189115190115191115192115193115194115195115196115197115198115199115200115201115202115203115204115205115206115207115208115209115210115211115212115213115214115215115216115217115218115219115220115221115222115223115224115225115226115227115228115229115230115231115232115233115234115235115236115237115238115239115240115241115242115243115244115245115246115247115248115249115250115251115252115253115254115255115256115257115258115259115260115261115262115263115264115265115266115267115268115269115270115271115272115273115274115275115276115277115278115279115280115281115282115283115284115285115286115287115288115289115290115291115292115293115294115295115296115297115298115299115300115301115302115303115304115305115306115307115308115309115310115311115312115313115314115315115316115317115318115319115320115321115322115323115324115325115326115327115328115329115330115331115332115333115334115335115336115337115338115339115340115341115342115343115344115345115346115347115348115349115350115351115352115353115354115355115356115357115358115359115360115361115362115363115364115365115366115367115368115369115370115371115372115373115374115375115376115377115378115379115380115381115382115383115384115385115386115387115388115389115390115391115392115393115394115395115396115397115398115399115400115401115402115403115404115405115406115407115408115409115410115411115412115413115414115415115416115417115418115419115420115421115422115423115424115425115426115427115428115429115430115431115432115433115434115435115436115437115438115439115440115441115442115443115444115445115446115447115448115449115450115451115452115453115454115455115456115457115458115459115460115461115462115463115464115465115466115467115468115469115470115471115472115473115474115475115476115477115478115479115480115481115482115483115484115485115486115487115488115489115490115491115492115493115494115495115496115497115498115499115500115501115502115503115504115505115506115507115508115509115510115511115512115513115514115515115516115517115518115519115520115521115522115523115524115525115526115527115528115529115530115531115532115533115534115535115536115537115538115539115540115541115542115543115544115545115546115547115548115549115550115551115552115553115554115555115556115557115558115559115560115561115562115563115564115565115566115567115568115569115570115571115572115573115574115575115576115577115578115579115580115581115582115583115584115585115586115587115588115589115590115591115592115593115594115595115596115597115598115599115600115601115602115603115604115605115606115607115608115609115610115611115612115613115614115615115616115617115618115619115620115621115622115623115624115625115626115627115628115629115630115631115632115633115634115635115636115637115638115639115640115641115642115643115644115645115646115647115648115649115650115651115652115653115654115655115656115657115658115659115660115661115662115663115664115665115666115667115668115669115670115671115672115673115674115675115676115677115678115679115680115681115682115683115684115685115686115687115688115689115690115691115692115693115694115695115696115697115698115699115700115701115702115703115704115705115706115707115708115709115710115711115712115713115714115715115716115717115718115719115720115721115722115723115724115725115726115727115728115729115730115731115732115733115734115735115736115737115738115739115740115741115742115743115744115745115746115747115748115749115750115751115752115753115754115755115756115757115758115759115760115761115762115763115764115765115766115767115768115769115770115771115772115773115774115775115776115777115778115779115780115781115782115783115784115785115786115787115788115789115790115791115792115793115794115795115796115797115798115799115800115801115802115803115804115805115806115807115808115809115810115811115812115813115814115815115816115817115818115819115820115821115822115823115824115825115826115827115828115829115830115831115832115833115834115835115836115837115838115839115840115841115842115843115844115845115846115847115848115849115850115851115852115853115854115855115856115857115858115859115860115861115862115863115864115865115866115867115868115869115870115871115872115873115874115875115876115877115878115879115880115881115882115883115884115885115886115887115888115889115890115891115892115893115894115895115896115897115898115899115900115901115902115903115904115905115906115907115908115909115910115911115912115913115914115915115916115917115918115919115920115921115922115923115924115925115926115927115928115929115930115931115932115933115934115935115936115937115938115939115940115941115942115943115944115945115946115947115948115949115950115951115952115953115954115955115956115957115958115959115960115961115962115963115964115965115966115967115968115969115970115971115972115973115974115975115976115977115978115979115980115981115982115983115984115985115986115987115988115989115990115991115992115993115994115995115996115997115998115999116000116001116002116003116004116005116006116007116008116009116010116011116012116013116014116015116016116017116018116019116020116021116022116023116024116025116026116027116028116029116030116031116032116033116034116035116036116037116038116039116040116041116042116043116044116045116046116047116048116049116050116051116052116053116054116055116056116057116058116059116060116061116062116063116064116065116066116067116068116069116070116071116072116073116074116075116076116077116078116079116080116081116082116083116084116085116086116087116088116089116090116091116092116093116094116095116096116097116098116099116100116101116102116103116104116105116106116107116108116109116110116111116112116113116114116115116116116117116118116119116120116121116122116123116124116125116126116127116128116129116130116131116132116133116134116135116136116137116138116139116140116141116142116143116144116145116146116147116148116149116150116151116152116153116154116155116156116157116158116159116160116161116162116163116164116165116166116167116168116169116170116171116172116173116174116175116176116177116178116179116180116181116182116183116184116185116186116187116188116189116190116191116192116193116194116195116196116197116198116199116200116201116202116203116204116205116206116207116208116209116210116211116212116213116214116215116216116217116218116219116220116221116222116223116224116225116226116227116228116229116230116231116232116233116234116235116236116237116238116239116240116241116242116243116244116245116246116247116248116249116250116251116252116253116254116255116256116257116258116259116260116261116262116263116264116265116266116267116268116269116270116271116272116273116274116275116276116277116278116279116280116281116282116283116284116285116286116287116288116289116290116291116292116293116294116295116296116297116298116299116300116301116302116303116304116305116306116307116308116309116310116311116312116313116314116315116316116317116318116319116320116321116322116323116324116325116326116327116328116329116330116331116332116333116334116335116336116337116338116339116340116341116342116343116344116345116346116347116348116349116350116351116352116353116354116355116356116357116358116359116360116361116362116363116364116365116366116367116368116369116370116371116372116373116374116375116376116377116378116379116380116381116382116383116384116385116386116387116388116389116390116391116392116393116394116395116396116397116398116399116400116401116402116403116404116405116406116407116408116409116410116411116412116413116414116415116416116417116418116419116420116421116422116423116424116425116426116427116428116429116430116431116432116433116434116435116436116437116438116439116440116441116442116443116444116445116446116447116448116449116450116451116452116453116454116455116456116457116458116459116460116461116462116463116464116465116466116467116468116469116470116471116472116473116474116475116476116477116478116479116480116481116482116483116484116485116486116487116488116489116490116491116492116493116494116495116496116497116498116499116500116501116502116503116504116505116506116507116508116509116510116511116512116513116514116515116516116517116518116519116520116521116522116523116524116525116526116527116528116529116530116531116532116533116534116535116536116537116538116539116540116541116542116543116544116545116546116547116548116549116550116551116552116553116554116555116556116557116558116559116560116561116562116563116564116565116566116567116568116569116570116571116572116573116574116575116576116577116578116579116580116581116582116583116584116585116586116587116588116589116590116591116592116593116594116595116596116597116598116599116600116601116602116603116604116605116606116607116608116609116610116611116612116613116614116615116616116617116618116619116620116621116622116623116624116625116626116627116628116629116630116631116632116633116634116635116636116637116638116639116640116641116642116643116644116645116646116647116648116649116650116651116652116653116654116655116656116657116658116659116660116661116662116663116664116665116666116667116668116669116670116671116672116673116674116675116676116677116678116679116680116681116682116683116684116685116686116687116688116689116690116691116692116693116694116695116696116697116698116699116700116701116702116703116704116705116706116707116708116709116710116711116712116713116714116715116716116717116718116719116720116721116722116723116724116725116726116727116728116729116730116731116732116733116734116735116736116737116738116739116740116741116742116743116744116745116746116747116748116749116750116751116752116753116754116755116756116757116758116759116760116761116762116763116764116765116766116767116768116769116770116771116772116773116774116775116776116777116778116779116780116781116782116783116784116785116786116787116788116789116790116791116792116793116794116795116796116797116798116799116800116801116802116803116804116805116806116807116808116809116810116811116812116813116814116815116816116817116818116819116820116821116822116823116824116825116826116827116828116829116830116831116832116833116834116835116836116837116838116839116840116841116842116843116844116845116846116847116848116849116850116851116852116853116854116855116856116857116858116859116860116861116862116863116864116865116866116867116868116869116870116871116872116873116874116875116876116877116878116879116880116881116882116883116884116885116886116887116888116889116890116891116892116893116894116895116896116897116898116899116900116901116902116903116904116905116906116907116908116909116910116911116912116913116914116915116916116917116918116919116920116921116922116923116924116925116926116927116928116929116930116931116932116933116934116935116936116937116938116939116940116941116942116943116944116945116946116947116948116949116950116951116952116953116954116955116956116957116958116959116960116961116962116963116964116965116966116967116968116969116970116971116972116973116974116975116976116977116978116979116980116981116982116983116984116985116986116987116988116989116990116991116992116993116994116995116996116997116998116999117000117001117002117003117004117005117006117007117008117009117010117011117012117013117014117015117016117017117018117019117020117021117022117023117024117025117026117027117028117029117030117031117032117033117034117035117036117037117038117039117040117041117042117043117044117045117046117047117048117049117050117051117052117053117054117055117056117057117058117059117060117061117062117063117064117065117066117067117068117069117070117071117072117073117074117075117076117077117078117079117080117081117082117083117084117085117086117087117088117089117090117091117092117093117094117095117096117097117098117099117100117101117102117103117104117105117106117107117108117109117110117111117112117113117114117115117116117117117118117119117120117121117122117123117124117125117126117127117128117129117130117131117132117133117134117135117136117137117138117139117140117141117142117143117144117145117146117147117148117149117150117151117152117153117154117155117156117157117158117159117160117161117162117163117164117165117166117167117168117169117170117171117172117173117174117175117176117177117178117179117180117181117182117183117184117185117186117187117188117189117190117191117192117193117194117195117196117197117198117199117200117201117202117203117204117205117206117207117208117209117210117211117212117213117214117215117216117217117218117219117220117221117222117223117224117225117226117227117228117229117230117231117232117233117234117235117236117237117238117239117240117241117242117243117244117245117246117247117248117249117250117251117252117253117254117255117256117257117258117259117260117261117262117263117264117265117266117267117268117269117270117271117272117273117274117275117276117277117278117279117280117281117282117283117284117285117286117287117288117289117290117291117292117293117294117295117296117297117298117299117300117301117302117303117304117305117306117307117308117309117310117311117312117313117314117315117316117317117318117319117320117321117322117323117324117325117326117327117328117329117330117331117332117333117334117335117336117337117338117339117340117341117342117343117344117345117346117347117348117349117350117351117352117353117354117355117356117357117358117359117360117361117362117363117364117365117366117367117368117369117370117371117372117373117374117375117376117377117378117379117380117381117382117383117384117385117386117387117388117389117390117391117392117393117394117395117396117397117398117399117400117401117402117403117404117405117406117407117408117409117410117411117412117413117414117415117416117417117418117419117420117421117422117423117424117425117426117427117428117429117430117431117432117433117434117435117436117437117438117439117440117441117442117443117444117445117446117447117448117449117450117451117452117453117454117455117456117457117458117459117460117461117462117463117464117465117466117467117468117469117470117471117472117473117474117475117476117477117478117479117480117481117482117483117484117485117486117487117488117489117490117491117492117493117494117495117496117497117498117499117500117501117502117503117504117505117506117507117508117509117510117511117512117513117514117515117516117517117518117519117520117521117522117523117524117525117526117527117528117529117530117531117532117533117534117535117536117537117538117539117540117541117542117543117544117545117546117547117548117549117550117551117552117553117554117555117556117557117558117559117560117561117562117563117564117565117566117567117568117569117570117571117572117573117574117575117576117577117578117579117580117581117582117583117584117585117586117587117588117589117590117591117592117593117594117595117596117597117598117599117600117601117602117603117604117605117606117607117608117609117610117611117612117613117614117615117616117617117618117619117620117621117622117623117624117625117626117627117628117629117630117631117632117633117634117635117636117637117638117639117640117641117642117643117644117645117646117647117648117649117650117651117652117653117654117655117656117657117658117659117660117661117662117663117664117665117666117667117668117669117670117671117672117673117674117675117676117677117678117679117680117681117682117683117684117685117686117687117688117689117690117691117692117693117694117695117696117697117698117699117700117701117702117703117704117705117706117707117708117709117710117711117712117713117714117715117716117717117718117719117720117721117722117723117724117725117726117727117728117729117730117731117732117733117734117735117736117737117738117739117740117741117742117743117744117745117746117747117748117749117750117751117752117753117754117755117756117757117758117759117760117761117762117763117764117765117766117767117768117769117770117771117772117773117774117775117776117777117778117779117780117781117782117783117784117785117786117787117788117789117790117791117792117793117794117795117796117797117798117799117800117801117802117803117804117805117806117807117808117809117810117811117812117813117814117815117816117817117818117819117820117821117822117823117824117825117826117827117828117829117830117831117832117833117834117835117836117837117838117839117840117841117842117843117844117845117846117847117848117849117850117851117852117853117854117855117856117857117858117859117860117861117862117863117864117865117866117867117868117869117870117871117872117873117874117875117876117877117878117879117880117881117882117883117884117885117886117887117888117889117890117891117892117893117894117895117896117897117898117899117900117901117902117903117904117905117906117907117908117909117910117911117912117913117914117915117916117917117918117919117920117921117922117923117924117925117926117927117928117929117930117931117932117933117934117935117936117937117938117939117940117941117942117943117944117945117946117947117948117949117950117951117952117953117954117955117956117957117958117959117960117961117962117963117964117965117966117967117968117969117970117971117972117973117974117975117976117977117978117979117980117981117982117983117984117985117986117987117988117989117990117991117992117993117994117995117996117997117998117999118000118001118002118003118004118005118006118007118008118009118010118011118012118013118014118015118016118017118018118019118020118021118022118023118024118025118026118027118028118029118030118031118032118033118034118035118036118037118038118039118040118041118042118043118044118045118046118047118048118049118050118051118052118053118054118055118056118057118058118059118060118061118062118063118064118065118066118067118068118069118070118071118072118073118074118075118076118077118078118079118080118081118082118083118084118085118086118087118088118089118090118091118092118093118094118095118096118097118098118099118100118101118102118103118104118105118106118107118108118109118110118111118112118113118114118115118116118117118118118119118120118121118122118123118124118125118126118127118128118129118130118131118132118133118134118135118136118137118138118139118140118141118142118143118144118145118146118147118148118149118150118151118152118153118154118155118156118157118158118159118160118161118162118163118164118165118166118167118168118169118170118171118172118173118174118175118176118177118178118179118180118181118182118183118184118185118186118187118188118189118190118191118192118193118194118195118196118197118198118199118200118201118202118203118204118205118206118207118208118209118210118211118212118213118214118215118216118217118218118219118220118221118222118223118224118225118226118227118228118229118230118231118232118233118234118235118236118237118238118239118240118241118242118243118244118245118246118247118248118249118250118251118252118253118254118255118256118257118258118259118260118261118262118263118264118265118266118267118268118269118270118271118272118273118274118275118276118277118278118279118280118281118282118283118284118285118286118287118288118289118290118291118292118293118294118295118296118297118298118299118300118301118302118303118304118305118306118307118308118309118310118311118312118313118314118315118316118317118318118319118320118321118322118323118324118325118326118327118328118329118330118331118332118333118334118335118336118337118338118339118340118341118342118343118344118345118346118347118348118349118350118351118352118353118354118355118356118357118358118359118360118361118362118363118364118365118366118367118368118369118370118371118372118373118374118375118376118377118378118379118380118381118382118383118384118385118386118387118388118389118390118391118392118393118394118395118396118397118398118399118400118401118402118403118404118405118406118407118408118409118410118411118412118413118414118415118416118417118418118419118420118421118422118423118424118425118426118427118428118429118430118431118432118433118434118435118436118437118438118439118440118441118442118443118444118445118446118447118448118449118450118451118452118453118454118455118456118457118458118459118460118461118462118463118464118465118466118467118468118469118470118471118472118473118474118475118476118477118478118479118480118481118482118483118484118485118486118487118488118489118490118491118492118493118494118495118496118497118498118499118500118501118502118503118504118505118506118507118508118509118510118511118512118513118514118515118516118517118518118519118520118521118522118523118524118525118526118527118528118529118530118531118532118533118534118535118536118537118538118539118540118541118542118543118544118545118546118547118548118549118550118551118552118553118554118555118556118557118558118559118560118561118562118563118564118565118566118567118568118569118570118571118572118573118574118575118576118577118578118579118580118581118582118583118584118585118586118587118588118589118590118591118592118593118594118595118596118597118598118599118600118601118602118603118604118605118606118607118608118609118610118611118612118613118614118615118616118617118618118619118620118621118622118623118624118625118626118627118628118629118630118631118632118633118634118635118636118637118638118639118640118641118642118643118644118645118646118647118648118649118650118651118652118653118654118655118656118657118658118659118660118661118662118663118664118665118666118667118668118669118670118671118672118673118674118675118676118677118678118679118680118681118682118683118684118685118686118687118688118689118690118691118692118693118694118695118696118697118698118699118700118701118702118703118704118705118706118707118708118709118710118711118712118713118714118715118716118717118718118719118720118721118722118723118724118725118726118727118728118729118730118731118732118733118734118735118736118737118738118739118740118741118742118743118744118745118746118747118748118749118750118751118752118753118754118755118756118757118758118759118760118761118762118763118764118765118766118767118768118769118770118771118772118773118774118775118776118777118778118779118780118781118782118783118784118785118786118787118788118789118790118791118792118793118794118795118796118797118798118799118800118801118802118803118804118805118806118807118808118809118810118811118812118813118814118815118816118817118818118819118820118821118822118823118824118825118826118827118828118829118830118831118832118833118834118835118836118837118838118839118840118841118842118843118844118845118846118847118848118849118850118851118852118853118854118855118856118857118858118859118860118861118862118863118864118865118866118867118868118869118870118871118872118873118874118875118876118877118878118879118880118881118882118883118884118885118886118887118888118889118890118891118892118893118894118895118896118897118898118899118900118901118902118903118904118905118906118907118908118909118910118911118912118913118914118915118916118917118918118919118920118921118922118923118924118925118926118927118928118929118930118931118932118933118934118935118936118937118938118939118940118941118942118943118944118945118946118947118948118949118950118951118952118953118954118955118956118957118958118959118960118961118962118963118964118965118966118967118968118969118970118971118972118973118974118975118976118977118978118979118980118981118982118983118984118985118986118987118988118989118990118991118992118993118994118995118996118997118998118999119000119001119002119003119004119005119006119007119008119009119010119011119012119013119014119015119016119017119018119019119020119021119022119023119024119025119026119027119028119029119030119031119032119033119034119035119036119037119038119039119040119041119042119043119044119045119046119047119048119049119050119051119052119053119054119055119056119057119058119059119060119061119062119063119064119065119066119067119068119069119070119071119072119073119074119075119076119077119078119079119080119081119082119083119084119085119086119087119088119089119090119091119092119093119094119095119096119097119098119099119100119101119102119103119104119105119106119107119108119109119110119111119112119113119114119115119116119117119118119119119120119121119122119123119124119125119126119127119128119129119130119131119132119133119134119135119136119137119138119139119140119141119142119143119144119145119146119147119148119149119150119151119152119153119154119155119156119157119158119159119160119161119162119163119164119165119166119167119168119169119170119171119172119173119174119175119176119177119178119179119180119181119182119183119184119185119186119187119188119189119190119191119192119193119194119195119196119197119198119199119200119201119202119203119204119205119206119207119208119209119210119211119212119213119214119215119216119217119218119219119220119221119222119223119224119225119226119227119228119229119230119231119232119233119234119235119236119237119238119239119240119241119242119243119244119245119246119247119248119249119250119251119252119253119254119255119256119257119258119259119260119261119262119263119264119265119266119267119268119269119270119271119272119273119274119275119276119277119278119279119280119281119282119283119284119285119286119287119288119289119290119291119292119293119294119295119296119297119298119299119300119301119302119303119304119305119306119307119308119309119310119311119312119313119314119315119316119317119318119319119320119321119322119323119324119325119326119327119328119329119330119331119332119333119334119335119336119337119338119339119340119341119342119343119344119345119346119347119348119349119350119351119352119353119354119355119356119357119358119359119360119361119362119363119364119365119366119367119368119369119370119371119372119373119374119375119376119377119378119379119380119381119382119383119384119385119386119387119388119389119390119391119392119393119394119395119396119397119398119399119400119401119402119403119404119405119406119407119408119409119410119411119412119413119414119415119416119417119418119419119420119421119422119423119424119425119426119427119428119429119430119431119432119433119434119435119436119437119438119439119440119441119442119443119444119445119446119447119448119449119450119451119452119453119454119455119456119457119458119459119460119461119462119463119464119465119466119467119468119469119470119471119472119473119474119475119476119477119478119479119480119481119482119483119484119485119486119487119488119489119490119491119492119493119494119495119496119497119498119499119500119501119502119503119504119505119506119507119508119509119510119511119512119513119514119515119516119517119518119519119520119521119522119523119524119525119526119527119528119529119530119531119532119533119534119535119536119537119538119539119540119541119542119543119544119545119546119547119548119549119550119551119552119553119554119555119556119557119558119559119560119561119562119563119564119565119566119567119568119569119570119571119572119573119574119575119576119577119578119579119580119581119582119583119584119585119586119587119588119589119590119591119592119593119594119595119596119597119598119599119600119601119602119603119604119605119606119607119608119609119610119611119612119613119614119615119616119617119618119619119620119621119622119623119624119625119626119627119628119629119630119631119632119633119634119635119636119637119638119639119640119641119642119643119644119645119646119647119648119649119650119651119652119653119654119655119656119657119658119659119660119661119662119663119664119665119666119667119668119669119670119671119672119673119674119675119676119677119678119679119680119681119682119683119684119685119686119687119688119689119690119691119692119693119694119695119696119697119698119699119700119701119702119703119704119705119706119707119708119709119710119711119712119713119714119715119716119717119718119719119720119721119722119723119724119725119726119727119728119729119730119731119732119733119734119735119736119737119738119739119740119741119742119743119744119745119746119747119748119749119750119751119752119753119754119755119756119757119758119759119760119761119762119763119764119765119766119767119768119769119770119771119772119773119774119775119776119777119778119779119780119781119782119783119784119785119786119787119788119789119790119791119792119793119794119795119796119797119798119799119800119801119802119803119804119805119806119807119808119809119810119811119812119813119814119815119816119817119818119819119820119821119822119823119824119825119826119827119828119829119830119831119832119833119834119835119836119837119838119839119840119841119842119843119844119845119846119847119848119849119850119851119852119853119854119855119856119857119858119859119860119861119862119863119864119865119866119867119868119869119870119871119872119873119874119875119876119877119878119879119880119881119882119883119884119885119886119887119888119889119890119891119892119893119894119895119896119897119898119899119900119901119902119903119904119905119906119907119908119909119910119911119912119913119914119915119916119917119918119919119920119921119922119923119924119925119926119927119928119929119930119931119932119933119934119935119936119937119938119939119940119941119942119943119944119945119946119947119948119949119950119951119952119953119954119955119956119957119958119959119960119961119962119963119964119965119966119967119968119969119970119971119972119973119974119975119976119977119978119979119980119981119982119983119984119985119986119987119988119989119990119991119992119993119994119995119996119997119998119999120000120001120002120003120004120005120006120007120008120009120010120011120012120013120014120015120016120017120018120019120020120021120022120023120024120025120026120027120028120029120030120031120032120033120034120035120036120037120038120039120040120041120042120043120044120045120046120047120048120049120050120051120052120053120054120055120056120057120058120059120060120061120062120063120064120065120066120067120068120069120070120071120072120073120074120075120076120077120078120079120080120081120082120083120084120085120086120087120088120089120090120091120092120093120094120095120096120097120098120099120100120101120102120103120104120105120106120107120108120109120110120111120112120113120114120115120116120117120118120119120120120121120122120123120124120125120126120127120128120129120130120131120132120133120134120135120136120137120138120139120140120141120142120143120144120145120146120147120148120149120150120151120152120153120154120155120156120157120158120159120160120161120162120163120164120165120166120167120168120169120170120171120172120173120174120175120176120177120178120179120180120181120182120183120184120185120186120187120188120189120190120191120192120193120194120195120196120197120198120199120200120201120202120203120204120205120206120207120208120209120210120211120212120213120214120215120216120217120218120219120220120221120222120223120224120225120226120227120228120229120230120231120232120233120234120235120236120237120238120239120240120241120242120243120244120245120246120247120248120249120250120251120252120253120254120255120256120257120258120259120260120261120262120263120264120265120266120267120268120269120270120271120272120273120274120275120276120277120278120279120280120281120282120283120284120285120286120287120288120289120290120291120292120293120294120295120296120297120298120299120300120301120302120303120304120305120306120307120308120309120310120311120312120313120314120315120316120317120318120319120320120321120322120323120324120325120326120327120328120329120330120331120332120333120334120335120336120337120338120339120340120341120342120343120344120345120346120347120348120349120350120351120352120353120354120355120356120357120358120359120360120361120362120363120364120365120366120367120368120369120370120371120372120373120374120375120376120377120378120379120380120381120382120383120384120385120386120387120388120389120390120391120392120393120394120395120396120397120398120399120400120401120402120403120404120405120406120407120408120409120410120411120412120413120414120415120416120417120418120419120420120421120422120423120424120425120426120427120428120429120430120431120432120433120434120435120436120437120438120439120440120441120442120443120444120445120446120447120448120449120450120451120452120453120454120455120456120457120458120459120460120461120462120463120464120465120466120467120468120469120470120471120472120473120474120475120476120477120478120479120480120481120482120483120484120485120486120487120488120489120490120491120492120493120494120495120496120497120498120499120500120501120502120503120504120505120506120507120508120509120510120511120512120513120514120515120516120517120518120519120520120521120522120523120524120525120526120527120528120529120530120531120532120533120534120535120536120537120538120539120540120541120542120543120544120545120546120547120548120549120550120551120552120553120554120555120556120557120558120559120560120561120562120563120564120565120566120567120568120569120570120571120572120573120574120575120576120577120578120579120580120581120582120583120584120585120586120587120588120589120590120591120592120593120594120595120596120597120598120599120600120601120602120603120604120605120606120607120608120609120610120611120612120613120614120615120616120617120618120619120620120621120622120623120624120625120626120627120628120629120630120631120632120633120634120635120636120637120638120639120640120641120642120643120644120645120646120647120648120649120650120651120652120653120654120655120656120657120658120659120660120661120662120663120664120665120666120667120668120669120670120671120672120673120674120675120676120677120678120679120680120681120682120683120684120685120686120687120688120689120690120691120692120693120694120695120696120697120698120699120700120701120702120703120704120705120706120707120708120709120710120711120712120713120714120715120716120717120718120719120720120721120722120723120724120725120726120727120728120729120730120731120732120733120734120735120736120737120738120739120740120741120742120743120744120745120746120747120748120749120750120751120752120753120754120755120756120757120758120759120760120761120762120763120764120765120766120767120768120769120770120771120772120773120774120775120776120777120778120779120780120781120782120783120784120785120786120787120788120789120790120791120792120793120794120795120796120797120798120799120800120801120802120803120804120805120806120807120808120809120810120811120812120813120814120815120816120817120818120819120820120821120822120823120824120825120826120827120828120829120830120831120832120833120834120835120836120837120838120839120840120841120842120843120844120845120846120847120848120849120850120851120852120853120854120855120856120857120858120859120860120861120862120863120864120865120866120867120868120869120870120871120872120873120874120875120876120877120878120879120880120881120882120883120884120885120886120887120888120889120890120891120892120893120894120895120896120897120898120899120900120901120902120903120904120905120906120907120908120909120910120911120912120913120914120915120916120917120918120919120920120921120922120923120924120925120926120927120928120929120930120931120932120933120934120935120936120937120938120939120940120941120942120943120944120945120946120947120948120949120950120951120952120953120954120955120956120957120958120959120960120961120962120963120964120965120966120967120968120969120970120971120972120973120974120975120976120977120978120979120980120981120982120983120984120985120986120987120988120989120990120991120992120993120994120995120996120997120998120999121000121001121002121003121004121005121006121007121008121009121010121011121012121013121014121015121016121017121018121019121020121021121022121023121024121025121026121027121028121029121030121031121032121033121034121035121036121037121038121039121040121041121042121043121044121045121046121047121048121049121050121051121052121053121054121055121056121057121058121059121060121061121062121063121064121065121066121067121068121069121070121071121072121073121074121075121076121077121078121079121080121081121082121083121084121085121086121087121088121089121090121091121092121093121094121095121096121097121098121099121100121101121102121103121104121105121106121107121108121109121110121111121112121113121114121115121116121117121118121119121120121121121122121123121124121125121126121127121128121129121130121131121132121133121134121135121136121137121138121139121140121141121142121143121144121145121146121147121148121149121150121151121152121153121154121155121156121157121158121159121160121161121162121163121164121165121166121167121168121169121170121171121172121173121174121175121176121177121178121179121180121181121182121183121184121185121186121187121188121189121190121191121192121193121194121195121196121197121198121199121200121201121202121203121204121205121206121207121208121209121210121211121212121213121214121215121216121217121218121219121220121221121222121223121224121225121226121227121228121229121230121231121232121233121234121235121236121237121238121239121240121241121242121243121244121245121246121247121248121249121250121251121252121253121254121255121256121257121258121259121260121261121262121263121264121265121266121267121268121269121270121271121272121273121274121275121276121277121278121279121280121281121282121283121284121285121286121287121288121289121290121291121292121293121294121295121296121297121298121299121300121301121302121303121304121305121306121307121308121309121310121311121312121313121314121315121316121317121318121319121320121321121322121323121324121325121326121327121328121329121330121331121332121333121334121335121336121337121338121339121340121341121342121343121344121345121346121347121348121349121350121351121352121353121354121355121356121357121358121359121360121361121362121363121364121365121366121367121368121369121370121371121372121373121374121375121376121377121378121379121380121381121382121383121384121385121386121387121388121389121390121391121392121393121394121395121396121397121398121399121400121401121402121403121404121405121406121407121408121409121410121411121412121413121414121415121416121417121418121419121420121421121422121423121424121425121426121427121428121429121430121431121432121433121434121435121436121437121438121439121440121441121442121443121444121445121446121447121448121449121450121451121452121453121454121455121456121457121458121459121460121461121462121463121464121465121466121467121468121469121470121471121472121473121474121475121476121477121478121479121480121481121482121483121484121485121486121487121488121489121490121491121492121493121494121495121496121497121498121499121500121501121502121503121504121505121506121507121508121509121510121511121512121513121514121515121516121517121518121519121520121521121522121523121524121525121526121527121528121529121530121531121532121533121534121535121536121537121538121539121540121541121542121543121544121545121546121547121548121549121550121551121552121553121554121555121556121557121558121559121560121561121562121563121564121565121566121567121568121569121570121571121572121573121574121575121576121577121578121579121580121581121582121583121584121585121586121587121588121589121590121591121592121593121594121595121596121597121598121599121600121601121602121603121604121605121606121607121608121609121610121611121612121613121614121615121616121617121618121619121620121621121622121623121624121625121626121627121628121629121630121631121632121633121634121635121636121637121638121639121640121641121642121643121644121645121646121647121648121649121650121651121652121653121654121655121656121657121658121659121660121661121662121663121664121665121666121667121668121669121670121671121672121673121674121675121676121677121678121679121680121681121682121683121684121685121686121687121688121689121690121691121692121693121694121695121696121697121698121699121700121701121702121703121704121705121706121707121708121709121710121711121712121713121714121715121716121717121718121719121720121721121722121723121724121725121726121727121728121729121730121731121732121733121734121735121736121737121738121739121740121741121742121743121744121745121746121747121748121749121750121751121752121753121754121755121756121757121758121759121760121761121762121763121764121765121766121767121768121769121770121771121772121773121774121775121776121777121778121779121780121781121782121783121784121785121786121787121788121789121790121791121792121793121794121795121796121797121798121799121800121801121802121803121804121805121806121807121808121809121810121811121812121813121814121815121816121817121818121819121820121821121822121823121824121825121826121827121828121829121830121831121832121833121834121835121836121837121838121839121840121841121842121843121844121845121846121847121848121849121850121851121852121853121854121855121856121857121858121859121860121861121862121863121864121865121866121867121868121869121870121871121872121873121874121875121876121877121878121879121880121881121882121883121884121885121886121887121888121889121890121891121892121893121894121895121896121897121898121899121900121901121902121903121904121905121906121907121908121909121910121911121912121913121914121915121916121917121918121919121920121921121922121923121924121925121926121927121928121929121930121931121932121933121934121935121936121937121938121939121940121941121942121943121944121945121946121947121948121949121950121951121952121953121954121955121956121957121958121959121960121961121962121963121964121965121966121967121968121969121970121971121972121973121974121975121976121977121978121979121980121981121982121983121984121985121986121987121988121989121990121991121992121993121994121995121996121997121998121999122000122001122002122003122004122005122006122007122008122009122010122011122012122013122014122015122016122017122018122019122020122021122022122023122024122025122026122027122028122029122030122031122032122033122034122035122036122037122038122039122040122041122042122043122044122045122046122047122048122049122050122051122052122053122054122055122056122057122058122059122060122061122062122063122064122065122066122067122068122069122070122071122072122073122074122075122076122077122078122079122080122081122082122083122084122085122086122087122088122089122090122091122092122093122094122095122096122097122098122099122100122101122102122103122104122105122106122107122108122109122110122111122112122113122114122115122116122117122118122119122120122121122122122123122124122125122126122127122128122129122130122131122132122133122134122135122136122137122138122139122140122141122142122143122144122145122146122147122148122149122150122151122152122153122154122155122156122157122158122159122160122161122162122163122164122165122166122167122168122169122170122171122172122173122174122175122176122177122178122179122180122181122182122183122184122185122186122187122188122189122190122191122192122193122194122195122196122197122198122199122200122201122202122203122204122205122206122207122208122209122210122211122212122213122214122215122216122217122218122219122220122221122222122223122224122225122226122227122228122229122230122231122232122233122234122235122236122237122238122239122240122241122242122243122244122245122246122247122248122249122250122251122252122253122254122255122256122257122258122259122260122261122262122263122264122265122266122267122268122269122270122271122272122273122274122275122276122277122278122279122280122281122282122283122284122285122286122287122288122289122290122291122292122293122294122295122296122297122298122299122300122301122302122303122304122305122306122307122308122309122310122311122312122313122314122315122316122317122318122319122320122321122322122323122324122325122326122327122328122329122330122331122332122333122334122335122336122337122338122339122340122341122342122343122344122345122346122347122348122349122350122351122352122353122354122355122356122357122358122359122360122361122362122363122364122365122366122367122368122369122370122371122372122373122374122375122376122377122378122379122380122381122382122383122384122385122386122387122388122389122390122391122392122393122394122395122396122397122398122399122400122401122402122403122404122405122406122407122408122409122410122411122412122413122414122415122416122417122418122419122420122421122422122423122424122425122426122427122428122429122430122431122432122433122434122435122436122437122438122439122440122441122442122443122444122445122446122447122448122449122450122451122452122453122454122455122456122457122458122459122460122461122462122463122464122465122466122467122468122469122470122471122472122473122474122475122476122477122478122479122480122481122482122483122484122485122486122487122488122489122490122491122492122493122494122495122496122497122498122499122500122501122502122503122504122505122506122507122508122509122510122511122512122513122514122515122516122517122518122519122520122521122522122523122524122525122526122527122528122529122530122531122532122533122534122535122536122537122538122539122540122541122542122543122544122545122546122547122548122549122550122551122552122553122554122555122556122557122558122559122560122561122562122563122564122565122566122567122568122569122570122571122572122573122574122575122576122577122578122579122580122581122582122583122584122585122586122587122588122589122590122591122592122593122594122595122596122597122598122599122600122601122602122603122604122605122606122607122608122609122610122611122612122613122614122615122616122617122618122619122620122621122622122623122624122625122626122627122628122629122630122631122632122633122634122635122636122637122638122639122640122641122642122643122644122645122646122647122648122649122650122651122652122653122654122655122656122657122658122659122660122661122662122663122664122665122666122667122668122669122670122671122672122673122674122675122676122677122678122679122680122681122682122683122684122685122686122687122688122689122690122691122692122693122694122695122696122697122698122699122700122701122702122703122704122705122706122707122708122709122710122711122712122713122714122715122716122717122718122719122720122721122722122723122724122725122726122727122728122729122730122731122732122733122734122735122736122737122738122739122740122741122742122743122744122745122746122747122748122749122750122751122752122753122754122755122756122757122758122759122760122761122762122763122764122765122766122767122768122769122770122771122772122773122774122775122776122777122778122779122780122781122782122783122784122785122786122787122788122789122790122791122792122793122794122795122796122797122798122799122800122801122802122803122804122805122806122807122808122809122810122811122812122813122814122815122816122817122818122819122820122821122822122823122824122825122826122827122828122829122830122831122832122833122834122835122836122837122838122839122840122841122842122843122844122845122846122847122848122849122850122851122852122853122854122855122856122857122858122859122860122861122862122863122864122865122866122867122868122869122870122871122872122873122874122875122876122877122878122879122880122881122882122883122884122885122886122887122888122889122890122891122892122893122894122895122896122897122898122899122900122901122902122903122904122905122906122907122908122909122910122911122912122913122914122915122916122917122918122919122920122921122922122923122924122925122926122927122928122929122930122931122932122933122934122935122936122937122938122939122940122941122942122943122944122945122946122947122948122949122950122951122952122953122954122955122956122957122958122959122960122961122962122963122964122965122966122967122968122969122970122971122972122973122974122975122976122977122978122979122980122981122982122983122984122985122986122987122988122989122990122991122992122993122994122995122996122997122998122999123000123001123002123003123004123005123006123007123008123009123010123011123012123013123014123015123016123017123018123019123020123021123022123023123024123025123026123027123028123029123030123031123032123033123034123035123036123037123038123039123040123041123042123043123044123045123046123047123048123049123050123051123052123053123054123055123056123057123058123059123060123061123062123063123064123065123066123067123068123069123070123071123072123073123074123075123076123077123078123079123080123081123082123083123084123085123086123087123088123089123090123091123092123093123094123095123096123097123098123099123100123101123102123103123104123105123106123107123108123109123110123111123112123113123114123115123116123117123118123119123120123121123122123123123124123125123126123127123128123129123130123131123132123133123134123135123136123137123138123139123140123141123142123143123144123145123146123147123148123149123150123151123152123153123154123155123156123157123158123159123160123161123162123163123164123165123166123167123168123169123170123171123172123173123174123175123176123177123178123179123180123181123182123183123184123185123186123187123188123189123190123191123192123193123194123195123196123197123198123199123200123201123202123203123204123205123206123207123208123209123210123211123212123213123214123215123216123217123218123219123220123221123222123223123224123225123226123227123228123229123230123231123232123233123234123235123236123237123238123239123240123241123242123243123244123245123246123247123248123249123250123251123252123253123254123255123256123257123258123259123260123261123262123263123264123265123266123267123268123269123270123271123272123273123274123275123276123277123278123279123280123281123282123283123284123285123286123287123288123289123290123291123292123293123294123295123296123297123298123299123300123301123302123303123304123305123306123307123308123309123310123311123312123313123314123315123316123317123318123319123320123321123322123323123324123325123326123327123328123329123330123331123332123333123334123335123336123337123338123339123340123341123342123343123344123345123346123347123348123349123350123351123352123353123354123355123356123357123358123359123360123361123362123363123364123365123366123367123368123369123370123371123372123373123374123375123376123377123378123379123380123381123382123383123384123385123386123387123388123389123390123391123392123393123394123395123396123397123398123399123400123401123402123403123404123405123406123407123408123409123410123411123412123413123414123415123416123417123418123419123420123421123422123423123424123425123426123427123428123429123430123431123432123433123434123435123436123437123438123439123440123441123442123443123444123445123446123447123448123449123450123451123452123453123454123455123456123457123458123459123460123461123462123463123464123465123466123467123468123469123470123471123472123473123474123475123476123477123478123479123480123481123482123483123484123485123486123487123488123489123490123491123492123493123494123495123496123497123498123499123500123501123502123503123504123505123506123507123508123509123510123511123512123513123514123515123516123517123518123519123520123521123522123523123524123525123526123527123528123529123530123531123532123533123534123535123536123537123538123539123540123541123542123543123544123545123546123547123548123549123550123551123552123553123554123555123556123557123558123559123560123561123562123563123564123565123566123567123568123569123570123571123572123573123574123575123576123577123578123579123580123581123582123583123584123585123586123587123588123589123590123591123592123593123594123595123596123597123598123599123600123601123602123603123604123605123606123607123608123609123610123611123612123613123614123615123616123617123618123619123620123621123622123623123624123625123626123627123628123629123630123631123632123633123634123635123636123637123638123639123640123641123642123643123644123645123646123647123648123649123650123651123652123653123654123655123656123657123658123659123660123661123662123663123664123665123666123667123668123669123670123671123672123673123674123675123676123677123678123679123680123681123682123683123684123685123686123687123688123689123690123691123692123693123694123695123696123697123698123699123700123701123702123703123704123705123706123707123708123709123710123711123712123713123714123715123716123717123718123719123720123721123722123723123724123725123726123727123728123729123730123731123732123733123734123735123736123737123738123739123740123741123742123743123744123745123746123747123748123749123750123751123752123753123754123755123756123757123758123759123760123761123762123763123764123765123766123767123768123769123770123771123772123773123774123775123776123777123778123779123780123781123782123783123784123785123786123787123788123789123790123791123792123793123794123795123796123797123798123799123800123801123802123803123804123805123806123807123808123809123810123811123812123813123814123815123816123817123818123819123820123821123822123823123824123825123826123827123828123829123830123831123832123833123834123835123836123837123838123839123840123841123842123843123844123845123846123847123848123849123850123851123852123853123854123855123856123857123858123859123860123861123862123863123864123865123866123867123868123869123870123871123872123873123874123875123876123877123878123879123880123881123882123883123884123885123886123887123888123889123890123891123892123893123894123895123896123897123898123899123900123901123902123903123904123905123906123907123908123909123910123911123912123913123914123915123916123917123918123919123920123921123922123923123924123925123926123927123928123929123930123931123932123933123934123935123936123937123938123939123940123941123942123943123944123945123946123947123948123949123950123951123952123953123954123955123956123957123958123959123960123961123962123963123964123965123966123967123968123969123970123971123972123973123974123975123976123977123978123979123980123981123982123983123984123985123986123987123988123989123990123991123992123993123994123995123996123997123998123999124000124001124002124003124004124005124006124007124008124009124010124011124012124013124014124015124016124017124018124019124020124021124022124023124024124025124026124027124028124029124030124031124032124033124034124035124036124037124038124039124040124041124042124043124044124045124046124047124048124049124050124051124052124053124054124055124056124057124058124059124060124061124062124063124064124065124066124067124068124069124070124071124072124073124074124075124076124077124078124079124080124081124082124083124084124085124086124087124088124089124090124091124092124093124094124095124096124097124098124099124100124101124102124103124104124105124106124107124108124109124110124111124112124113124114124115124116124117124118124119124120124121124122124123124124124125124126124127124128124129124130124131124132124133124134124135124136124137124138124139124140124141124142124143124144124145124146124147124148124149124150124151124152124153124154124155124156124157124158124159124160124161124162124163124164124165124166124167124168124169124170124171124172124173124174124175124176124177124178124179124180124181124182124183124184124185124186124187124188124189124190124191124192124193124194124195124196124197124198124199124200124201124202124203124204124205124206124207124208124209124210124211124212124213124214124215124216124217124218124219124220124221124222124223124224124225124226124227124228124229124230124231124232124233124234124235124236124237124238124239124240124241124242124243124244124245124246124247124248124249124250124251124252124253124254124255124256124257124258124259124260124261124262124263124264124265124266124267124268124269124270124271124272124273124274124275124276124277124278124279124280124281124282124283124284124285124286124287124288124289124290124291124292124293124294124295124296124297124298124299124300124301124302124303124304124305124306124307124308124309124310124311124312124313124314124315124316124317124318124319124320124321124322124323124324124325124326124327124328124329124330124331124332124333124334124335124336124337124338124339124340124341124342124343124344124345124346124347124348124349124350124351124352124353124354124355124356124357124358124359124360124361124362124363124364124365124366124367124368124369124370124371124372124373124374124375124376124377124378124379124380124381124382124383124384124385124386124387124388124389124390124391124392124393124394124395124396124397124398124399124400124401124402124403124404124405124406124407124408124409124410124411124412124413124414124415124416124417124418124419124420124421124422124423124424124425124426124427124428124429124430124431124432124433124434124435124436124437124438124439124440124441124442124443124444124445124446124447124448124449124450124451124452124453124454124455124456124457124458124459124460124461124462124463124464124465124466124467124468124469124470124471124472124473124474124475124476124477124478124479124480124481124482124483124484124485124486124487124488124489124490124491124492124493124494124495124496124497124498124499124500124501124502124503124504124505124506124507124508124509124510124511124512124513124514124515124516124517124518124519124520124521124522124523124524124525124526124527124528124529124530124531124532124533124534124535124536124537124538124539124540124541124542124543124544124545124546124547124548124549124550124551124552124553124554124555124556124557124558124559124560124561124562124563124564124565124566124567124568124569124570124571124572124573124574124575124576124577124578124579124580124581124582124583124584124585124586124587124588124589124590124591124592124593124594124595124596124597124598124599124600124601124602124603124604124605124606124607124608124609124610124611124612124613124614124615124616124617124618124619124620124621124622124623124624124625124626124627124628124629124630124631124632124633124634124635124636124637124638124639124640124641124642124643124644124645124646124647124648124649124650124651124652124653124654124655124656124657124658124659124660124661124662124663124664124665124666124667124668124669124670124671124672124673124674124675124676124677124678124679124680124681124682124683124684124685124686124687124688124689124690124691124692124693124694124695124696124697124698124699124700124701124702124703124704124705124706124707124708124709124710124711124712124713124714124715124716124717124718124719124720124721124722124723124724124725124726124727124728124729124730124731124732124733124734124735124736124737124738124739124740124741124742124743124744124745124746124747124748124749124750124751124752124753124754124755124756124757124758124759124760124761124762124763124764124765124766124767124768124769124770124771124772124773124774124775124776124777124778124779124780124781124782124783124784124785124786124787124788124789124790124791124792124793124794124795124796124797124798124799124800124801124802124803124804124805124806124807124808124809124810124811124812124813124814124815124816124817124818124819124820124821124822124823124824124825124826124827124828124829124830124831124832124833124834124835124836124837124838124839124840124841124842124843124844124845124846124847124848124849124850124851124852124853124854124855124856124857124858124859124860124861124862124863124864124865124866124867124868124869124870124871124872124873124874124875124876124877124878124879124880124881124882124883124884124885124886124887124888124889124890124891124892124893124894124895124896124897124898124899124900124901124902124903124904124905124906124907124908124909124910124911124912124913124914124915124916124917124918124919124920124921124922124923124924124925124926124927124928124929124930124931124932124933124934124935124936124937124938124939124940124941124942124943124944124945124946124947124948124949124950124951124952124953124954124955124956124957124958124959124960124961124962124963124964124965124966124967124968124969124970124971124972124973124974124975124976124977124978124979124980124981124982124983124984124985124986124987124988124989124990124991124992124993124994124995124996124997124998124999125000125001125002125003125004125005125006125007125008125009125010125011125012125013125014125015125016125017125018125019125020125021125022125023125024125025125026125027125028125029125030125031125032125033125034125035125036125037125038125039125040125041125042125043125044125045125046125047125048125049125050125051125052125053125054125055125056125057125058125059125060125061125062125063125064125065125066125067125068125069125070125071125072125073125074125075125076125077125078125079125080125081125082125083125084125085125086125087125088125089125090125091125092125093125094125095125096125097125098125099125100125101125102125103125104125105125106125107125108125109125110125111125112125113125114125115125116125117125118125119125120125121125122125123125124125125125126125127125128125129125130125131125132125133125134125135125136125137125138125139125140125141125142125143125144125145125146125147125148125149125150125151125152125153125154125155125156125157125158125159125160125161125162125163125164125165125166125167125168125169125170125171125172125173125174125175125176125177125178125179125180125181125182125183125184125185125186125187125188125189125190125191125192125193125194125195125196125197125198125199125200125201125202125203125204125205125206125207125208125209125210125211125212125213125214125215125216125217125218125219125220125221125222125223125224125225125226125227125228125229125230125231125232125233125234125235125236125237125238125239125240125241125242125243125244125245125246125247125248125249125250125251125252125253125254125255125256125257125258125259125260125261125262125263125264125265125266125267125268125269125270125271125272125273125274125275125276125277125278125279125280125281125282125283125284125285125286125287125288125289125290125291125292125293125294125295125296125297125298125299125300125301125302125303125304125305125306125307125308125309125310125311125312125313125314125315125316125317125318125319125320125321125322125323125324125325125326125327125328125329125330125331125332125333125334125335125336125337125338125339125340125341125342125343125344125345125346125347125348125349125350125351125352125353125354125355125356125357125358125359125360125361125362125363125364125365125366125367125368125369125370125371125372125373125374125375125376125377125378125379125380125381125382125383125384125385125386125387125388125389125390125391125392125393125394125395125396125397125398125399125400125401125402125403125404125405125406125407125408125409125410125411125412125413125414125415125416125417125418125419125420125421125422125423125424125425125426125427125428125429125430125431125432125433125434125435125436125437125438125439125440125441125442125443125444125445125446125447125448125449125450125451125452125453125454125455125456125457125458125459125460125461125462125463125464125465125466125467125468125469125470125471125472125473125474125475125476125477125478125479125480125481125482125483125484125485125486125487125488125489125490125491125492125493125494125495125496125497125498125499125500125501125502125503125504125505125506125507125508125509125510125511125512125513125514125515125516125517125518125519125520125521125522125523125524125525125526125527125528125529125530125531125532125533125534125535125536125537125538125539125540125541125542125543125544125545125546125547125548125549125550125551125552125553125554125555125556125557125558125559125560125561125562125563125564125565125566125567125568125569125570125571125572125573125574125575125576125577125578125579125580125581125582125583125584125585125586125587125588125589125590125591125592125593125594125595125596125597125598125599125600125601125602125603125604125605125606125607125608125609125610125611125612125613125614125615125616125617125618125619125620125621125622125623125624125625125626125627125628125629125630125631125632125633125634125635125636125637125638125639125640125641125642125643125644125645125646125647125648125649125650125651125652125653125654125655125656125657125658125659125660125661125662125663125664125665125666125667125668125669125670125671125672125673125674125675125676125677125678125679125680125681125682125683125684125685125686125687125688125689125690125691125692125693125694125695125696125697125698125699125700125701125702125703125704125705125706125707125708125709125710125711125712125713125714125715125716125717125718125719125720125721125722125723125724125725125726125727125728125729125730125731125732125733125734125735125736125737125738125739125740125741125742125743125744125745125746125747125748125749125750125751125752125753125754125755125756125757125758125759125760125761125762125763125764125765125766125767125768125769125770125771125772125773125774125775125776125777125778125779125780125781125782125783125784125785125786125787125788125789125790125791125792125793125794125795125796125797125798125799125800125801125802125803125804125805125806125807125808125809125810125811125812125813125814125815125816125817125818125819125820125821125822125823125824125825125826125827125828125829125830125831125832125833125834125835125836125837125838125839125840125841125842125843125844125845125846125847125848125849125850125851125852125853125854125855125856125857125858125859125860125861125862125863125864125865125866125867125868125869125870125871125872125873125874125875125876125877125878125879125880125881125882125883125884125885125886125887125888125889125890125891125892125893125894125895125896125897125898125899125900125901125902125903125904125905125906125907125908125909125910125911125912125913125914125915125916125917125918125919125920125921125922125923125924125925125926125927125928125929125930125931125932125933125934125935125936125937125938125939125940125941125942125943125944125945125946125947125948125949125950125951125952125953125954125955125956125957125958125959125960125961125962125963125964125965125966125967125968125969125970125971125972125973125974125975125976125977125978125979125980125981125982125983125984125985125986125987125988125989125990125991125992125993125994125995125996125997125998125999126000126001126002126003126004126005126006126007126008126009126010126011126012126013126014126015126016126017126018126019126020126021126022126023126024126025126026126027126028126029126030126031126032126033126034126035126036126037126038126039126040126041126042126043126044126045126046126047126048126049126050126051126052126053126054126055126056126057126058126059126060126061126062126063126064126065126066126067126068126069126070126071126072126073126074126075126076126077126078126079126080126081126082126083126084126085126086126087126088126089126090126091126092126093126094126095126096126097126098126099126100126101126102126103126104126105126106126107126108126109126110126111126112126113126114126115126116126117126118126119126120126121126122126123126124126125126126126127126128126129126130126131126132126133126134126135126136126137126138126139126140126141126142126143126144126145126146126147126148126149126150126151126152126153126154126155126156126157126158126159126160126161126162126163126164126165126166126167126168126169126170126171126172126173126174126175126176126177126178126179126180126181126182126183126184126185126186126187126188126189126190126191126192126193126194126195126196126197126198126199126200126201126202126203126204126205126206126207126208126209126210126211126212126213126214126215126216126217126218126219126220126221126222126223126224126225126226126227126228126229126230126231126232126233126234126235126236126237126238126239126240126241126242126243126244126245126246126247126248126249126250126251126252126253126254126255126256126257126258126259126260126261126262126263126264126265126266126267126268126269126270126271126272126273126274126275126276126277126278126279126280126281126282126283126284126285126286126287126288126289126290126291126292126293126294126295126296126297126298126299126300126301126302126303126304126305126306126307126308126309126310126311126312126313126314126315126316126317126318126319126320126321126322126323126324126325126326126327126328126329126330126331126332126333126334126335126336126337126338126339126340126341126342126343126344126345126346126347126348126349126350126351126352126353126354126355126356126357126358126359126360126361126362126363126364126365126366126367126368126369126370126371126372126373126374126375126376126377126378126379126380126381126382126383126384126385126386126387126388126389126390126391126392126393126394126395126396126397126398126399126400126401126402126403126404126405126406126407126408126409126410126411126412126413126414126415126416126417126418126419126420126421126422126423126424126425126426126427126428126429126430126431126432126433126434126435126436126437126438126439126440126441126442126443126444126445126446126447126448126449126450126451126452126453126454126455126456126457126458126459126460126461126462126463126464126465126466126467126468126469126470126471126472126473126474126475126476126477126478126479126480126481126482126483126484126485126486126487126488126489126490126491126492126493126494126495126496126497126498126499126500126501126502126503126504126505126506126507126508126509126510126511126512126513126514126515126516126517126518126519126520126521126522126523126524126525126526126527126528126529126530126531126532126533126534126535126536126537126538126539126540126541126542126543126544126545126546126547126548126549126550126551126552126553126554126555126556126557126558126559126560126561126562126563126564126565126566126567126568126569126570126571126572126573126574126575126576126577126578126579126580126581126582126583126584126585126586126587126588126589126590126591126592126593126594126595126596126597126598126599126600126601126602126603126604126605126606126607126608126609126610126611126612126613126614126615126616126617126618126619126620126621126622126623126624126625126626126627126628126629126630126631126632126633126634126635126636126637126638126639126640126641126642126643126644126645126646126647126648126649126650126651126652126653126654126655126656126657126658126659126660126661126662126663126664126665126666126667126668126669126670126671126672126673126674126675126676126677126678126679126680126681126682126683126684126685126686126687126688126689126690126691126692126693126694126695126696126697126698126699126700126701126702126703126704126705126706126707126708126709126710126711126712126713126714126715126716126717126718126719126720126721126722126723126724126725126726126727126728126729126730126731126732126733126734126735126736126737126738126739126740126741126742126743126744126745126746126747126748126749126750126751126752126753126754126755126756126757126758126759126760126761126762126763126764126765126766126767126768126769126770126771126772126773126774126775126776126777126778126779126780126781126782126783126784126785126786126787126788126789126790126791126792126793126794126795126796126797126798126799126800126801126802126803126804126805126806126807126808126809126810126811126812126813126814126815126816126817126818126819126820126821126822126823126824126825126826126827126828126829126830126831126832126833126834126835126836126837126838126839126840126841126842126843126844126845126846126847126848126849126850126851126852126853126854126855126856126857126858126859126860126861126862126863126864126865126866126867126868126869126870126871126872126873126874126875126876126877126878126879126880126881126882126883126884126885126886126887126888126889126890126891126892126893126894126895126896126897126898126899126900126901126902126903126904126905126906126907126908126909126910126911126912126913126914126915126916126917126918126919126920126921126922126923126924126925126926126927126928126929126930126931126932126933126934126935126936126937126938126939126940126941126942126943126944126945126946126947126948126949126950126951126952126953126954126955126956126957126958126959126960126961126962126963126964126965126966126967126968126969126970126971126972126973126974126975126976126977126978126979126980126981126982126983126984126985126986126987126988126989126990126991126992126993126994126995126996126997126998126999127000127001127002127003127004127005127006127007127008127009127010127011127012127013127014127015127016127017127018127019127020127021127022127023127024127025127026127027127028127029127030127031127032127033127034127035127036127037127038127039127040127041127042127043127044127045127046127047127048127049127050127051127052127053127054127055127056127057127058127059127060127061127062127063127064127065127066127067127068127069127070127071127072127073127074127075127076127077127078127079127080127081127082127083127084127085127086127087127088127089127090127091127092127093127094127095127096127097127098127099127100127101127102127103127104127105127106127107127108127109127110127111127112127113127114127115127116127117127118127119127120127121127122127123127124127125127126127127127128127129127130127131127132127133127134127135127136127137127138127139127140127141127142127143127144127145127146127147127148127149127150127151127152127153127154127155127156127157127158127159127160127161127162127163127164127165127166127167127168127169127170127171127172127173127174127175127176127177127178127179127180127181127182127183127184127185127186127187127188127189127190127191127192127193127194127195127196127197127198127199127200127201127202127203127204127205127206127207127208127209127210127211127212127213127214127215127216127217127218127219127220127221127222127223127224127225127226127227127228127229127230127231127232127233127234127235127236127237127238127239127240127241127242127243127244127245127246127247127248127249127250127251127252127253127254127255127256127257127258127259127260127261127262127263127264127265127266127267127268127269127270127271127272127273127274127275127276127277127278127279127280127281127282127283127284127285127286127287127288127289127290127291127292127293127294127295127296127297127298127299127300127301127302127303127304127305127306127307127308127309127310127311127312127313127314127315127316127317127318127319127320127321127322127323127324127325127326127327127328127329127330127331127332127333127334127335127336127337127338127339127340127341127342127343127344127345127346127347127348127349127350127351127352127353127354127355127356127357127358127359127360127361127362127363127364127365127366127367127368127369127370127371127372127373127374127375127376127377127378127379127380127381127382127383127384127385127386127387127388127389127390127391127392127393127394127395127396127397127398127399127400127401127402127403127404127405127406127407127408127409127410127411127412127413127414127415127416127417127418127419127420127421127422127423127424127425127426127427127428127429127430127431127432127433127434127435127436127437127438127439127440127441127442127443127444127445127446127447127448127449127450127451127452127453127454127455127456127457127458127459127460127461127462127463127464127465127466127467127468127469127470127471127472127473127474127475127476127477127478127479127480127481127482127483127484127485127486127487127488127489127490127491127492127493127494127495127496127497127498127499127500127501127502127503127504127505127506127507127508127509127510127511127512127513127514127515127516127517127518127519127520127521127522127523127524127525127526127527127528127529127530127531127532127533127534127535127536127537127538127539127540127541127542127543127544127545127546127547127548127549127550127551127552127553127554127555127556127557127558127559127560127561127562127563127564127565127566127567127568127569127570127571127572127573127574127575127576127577127578127579127580127581127582127583127584127585127586127587127588127589127590127591127592127593127594127595127596127597127598127599127600127601127602127603127604127605127606127607127608127609127610127611127612127613127614127615127616127617127618127619127620127621127622127623127624127625127626127627127628127629127630127631127632127633127634127635127636127637127638127639127640127641127642127643127644127645127646127647127648127649127650127651127652127653127654127655127656127657127658127659127660127661127662127663127664127665127666127667127668127669127670127671127672127673127674127675127676127677127678127679127680127681127682127683127684127685127686127687127688127689127690127691127692127693127694127695127696127697127698127699127700127701127702127703127704127705127706127707127708127709127710127711127712127713127714127715127716127717127718127719127720127721127722127723127724127725127726127727127728127729127730127731127732127733127734127735127736127737127738127739127740127741127742127743127744127745127746127747127748127749127750127751127752127753127754127755127756127757127758127759127760127761127762127763127764127765127766127767127768127769127770127771127772127773127774127775127776127777127778127779127780127781127782127783127784127785127786127787127788127789127790127791127792127793127794127795127796127797127798127799127800127801127802127803127804127805127806127807127808127809127810127811127812127813127814127815127816127817127818127819127820127821127822127823127824127825127826127827127828127829127830127831127832127833127834127835127836127837127838127839127840127841127842127843127844127845127846127847127848127849127850127851127852127853127854127855127856127857127858127859127860127861127862127863127864127865127866127867127868127869127870127871127872127873127874127875127876127877127878127879127880127881127882127883127884127885127886127887127888127889127890127891127892127893127894127895127896127897127898127899127900127901127902127903127904127905127906127907127908127909127910127911127912127913127914127915127916127917127918127919127920127921127922127923127924127925127926127927127928127929127930127931127932127933127934127935127936127937127938127939127940127941127942127943127944127945127946127947127948127949127950127951127952127953127954127955127956127957127958127959127960127961127962127963127964127965127966127967127968127969127970127971127972127973127974127975127976127977127978127979127980127981127982127983127984127985127986127987127988127989127990127991127992127993127994127995127996127997127998127999128000128001128002128003128004128005128006128007128008128009128010128011128012128013128014128015128016128017128018128019128020128021128022128023128024128025128026128027128028128029128030128031128032128033128034128035128036128037128038128039128040128041128042128043128044128045128046128047128048128049128050128051128052128053128054128055128056128057128058128059128060128061128062128063128064128065128066128067128068128069128070128071128072128073128074128075128076128077128078128079128080128081128082128083128084128085128086128087128088128089128090128091128092128093128094128095128096128097128098128099128100128101128102128103128104128105128106128107128108128109128110128111128112128113128114128115128116128117128118128119128120128121128122128123128124128125128126128127128128128129128130128131128132128133128134128135128136128137128138128139128140128141128142128143128144128145128146128147128148128149128150128151128152128153128154128155128156128157128158128159128160128161128162128163128164128165128166128167128168128169128170128171128172128173128174128175128176128177128178128179128180128181128182128183128184128185128186128187128188128189128190128191128192128193128194128195128196128197128198128199128200128201128202128203128204128205128206128207128208128209128210128211128212128213128214128215128216128217128218128219128220128221128222128223128224128225128226128227128228128229128230128231128232128233128234128235128236128237128238128239128240128241128242128243128244128245128246128247128248128249128250128251128252128253128254128255128256128257128258128259128260128261128262128263128264128265128266128267128268128269128270128271128272128273128274128275128276128277128278128279128280128281128282128283128284128285128286128287128288128289128290128291128292128293128294128295128296128297128298128299128300128301128302128303128304128305128306128307128308128309128310128311128312128313128314128315128316128317128318128319128320128321128322128323128324128325128326128327128328128329128330128331128332128333128334128335128336128337128338128339128340128341128342128343128344128345128346128347128348128349128350128351128352128353128354128355128356128357128358128359128360128361128362128363128364128365128366128367128368128369128370128371128372128373128374128375128376128377128378128379128380128381128382128383128384128385128386128387128388128389128390128391128392128393128394128395128396128397128398128399128400128401128402128403128404128405128406128407128408128409128410128411128412128413128414128415128416128417128418128419128420128421128422128423128424128425128426128427128428128429128430128431128432128433128434128435128436128437128438128439128440128441128442128443128444128445128446128447128448128449128450128451128452128453128454128455128456128457128458128459128460128461128462128463128464128465128466128467128468128469128470128471128472128473128474128475128476128477128478128479128480128481128482128483128484128485128486128487128488128489128490128491128492128493128494128495128496128497128498128499128500128501128502128503128504128505128506128507128508128509128510128511128512128513128514128515128516128517128518128519128520128521128522128523128524128525128526128527128528128529128530128531128532128533128534128535128536128537128538128539128540128541128542128543128544128545128546128547128548128549128550128551128552128553128554128555128556128557128558128559128560128561128562128563128564128565128566128567128568128569128570128571128572128573128574128575128576128577128578128579128580128581128582128583128584128585128586128587128588128589128590128591128592128593128594128595128596128597128598128599128600128601128602128603128604128605128606128607128608128609128610128611128612128613128614128615128616128617128618128619128620128621128622128623128624128625128626128627128628128629128630128631128632128633128634128635128636128637128638128639128640128641128642128643128644128645128646128647128648128649128650128651128652128653128654128655128656128657128658128659128660128661128662128663128664128665128666128667128668128669128670128671128672128673128674128675128676128677128678128679128680128681128682128683128684128685128686128687128688128689128690128691128692128693128694128695128696128697128698128699128700128701128702128703128704128705128706128707128708128709128710128711128712128713128714128715128716128717128718128719128720128721128722128723128724128725128726128727128728128729128730128731128732128733128734128735128736128737128738128739128740128741128742128743128744128745128746128747128748128749128750128751128752128753128754128755128756128757128758128759128760128761128762128763128764128765128766128767128768128769128770128771128772128773128774128775128776128777128778128779128780128781128782128783128784128785128786128787128788128789128790128791128792128793128794128795128796128797128798128799128800128801128802128803128804128805128806128807128808128809128810128811128812128813128814128815128816128817128818128819128820128821128822128823128824128825128826128827128828128829128830128831128832128833128834128835128836128837128838128839128840128841128842128843128844128845128846128847128848128849128850128851128852128853128854128855128856128857128858128859128860128861128862128863128864128865128866128867128868128869128870128871128872128873128874128875128876128877128878128879128880128881128882128883128884128885128886128887128888128889128890128891128892128893128894128895128896128897128898128899128900128901128902128903128904128905128906128907128908128909128910128911128912128913128914128915128916128917128918128919128920128921128922128923128924128925128926128927128928128929128930128931128932128933128934128935128936128937128938128939128940128941128942128943128944128945128946128947128948128949128950128951128952128953128954128955128956128957128958128959128960128961128962128963128964128965128966128967128968128969128970128971128972128973128974128975128976128977128978128979128980128981128982128983128984128985128986128987128988128989128990128991128992128993128994128995128996128997128998128999129000129001129002129003129004129005129006129007129008129009129010129011129012129013129014129015129016129017129018129019129020129021129022129023129024129025129026129027129028129029129030129031129032129033129034129035129036129037129038129039129040129041129042129043129044129045129046129047129048129049129050129051129052129053129054129055129056129057129058129059129060129061129062129063129064129065129066129067129068129069129070129071129072129073129074129075129076129077129078129079129080129081129082129083129084129085129086129087129088129089129090129091129092129093129094129095129096129097129098129099129100129101129102129103129104129105129106129107129108129109129110129111129112129113129114129115129116129117129118129119129120129121129122129123129124129125129126129127129128129129129130129131129132129133129134129135129136129137129138129139129140129141129142129143129144129145129146129147129148129149129150129151129152129153129154129155129156129157129158129159129160129161129162129163129164129165129166129167129168129169129170129171129172129173129174129175129176129177129178129179129180129181129182129183129184129185129186129187129188129189129190129191129192129193129194129195129196129197129198129199129200129201129202129203129204129205129206129207129208129209129210129211129212129213129214129215129216129217129218129219129220129221129222129223129224129225129226129227129228129229129230129231129232129233129234129235129236129237129238129239129240129241129242129243129244129245129246129247129248129249129250129251129252129253129254129255129256129257129258129259129260129261129262129263129264129265129266129267129268129269129270129271129272129273129274129275129276129277129278129279129280129281129282129283129284129285129286129287129288129289129290129291129292129293129294129295129296129297129298129299129300129301129302129303129304129305129306129307129308129309129310129311129312129313129314129315129316129317129318129319129320129321129322129323129324129325129326129327129328129329129330129331129332129333129334129335129336129337129338129339129340129341129342129343129344129345129346129347129348129349129350129351129352129353129354129355129356129357129358129359129360129361129362129363129364129365129366129367129368129369129370129371129372129373129374129375129376129377129378129379129380129381129382129383129384129385129386129387129388129389129390129391129392129393129394129395129396129397129398129399129400129401129402129403129404129405129406129407129408129409129410129411129412129413129414129415129416129417129418129419129420129421129422129423129424129425129426129427129428129429129430129431129432129433129434129435129436129437129438129439129440129441129442129443129444129445129446129447129448129449129450129451129452129453129454129455129456129457129458129459129460129461129462129463129464129465129466129467129468129469129470129471129472129473129474129475129476129477129478129479129480129481129482129483129484129485129486129487129488129489129490129491129492129493129494129495129496129497129498129499129500129501129502129503129504129505129506129507129508129509129510129511129512129513129514129515129516129517129518129519129520129521129522129523129524129525129526129527129528129529129530129531129532129533129534129535129536129537129538129539129540129541129542129543129544129545129546129547129548129549129550129551129552129553129554129555129556129557129558129559129560129561129562129563129564129565129566129567129568129569129570129571129572129573129574129575129576129577129578129579129580129581129582129583129584129585129586129587129588129589129590129591129592129593129594129595129596129597129598129599129600129601129602129603129604129605129606129607129608129609129610129611129612129613129614129615129616129617129618129619129620129621129622129623129624129625129626129627129628129629129630129631129632129633129634129635129636129637129638129639129640129641129642129643129644129645129646129647129648129649129650129651129652129653129654129655129656129657129658129659129660129661129662129663129664129665129666129667129668129669129670129671129672129673129674129675129676129677129678129679129680129681129682129683129684129685129686129687129688129689129690129691129692129693129694129695129696129697129698129699129700129701129702129703129704129705129706129707129708129709129710129711129712129713129714129715129716129717129718129719129720129721129722129723129724129725129726129727129728129729129730129731129732129733129734129735129736129737129738129739129740129741129742129743129744129745129746129747129748129749129750129751129752129753129754129755129756129757129758129759129760129761129762129763129764129765129766129767129768129769129770129771129772129773129774129775129776129777129778129779129780129781129782129783129784129785129786129787129788129789129790129791129792129793129794129795129796129797129798129799129800129801129802129803129804129805129806129807129808129809129810129811129812129813129814129815129816129817129818129819129820129821129822129823129824129825129826129827129828129829129830129831129832129833129834129835129836129837129838129839129840129841129842129843129844129845129846129847129848129849129850129851129852129853129854129855129856129857129858129859129860129861129862129863129864129865129866129867129868129869129870129871129872129873129874129875129876129877129878129879129880129881129882129883129884129885129886129887129888129889129890129891129892129893129894129895129896129897129898129899129900129901129902129903129904129905129906129907129908129909129910129911129912129913129914129915129916129917129918129919129920129921129922129923129924129925129926129927129928129929129930129931129932129933129934129935129936129937129938129939129940129941129942129943129944129945129946129947129948129949129950129951129952129953129954129955129956129957129958129959129960129961129962129963129964129965129966129967129968129969129970129971129972129973129974129975129976129977129978129979129980129981129982129983129984129985129986129987129988129989129990129991129992129993129994129995129996129997129998129999130000130001130002130003130004130005130006130007130008130009130010130011130012130013130014130015130016130017130018130019130020130021130022130023130024130025130026130027130028130029130030130031130032130033130034130035130036130037130038130039130040130041130042130043130044130045130046130047130048130049130050130051130052130053130054130055130056130057130058130059130060130061130062130063130064130065130066130067130068130069130070130071130072130073130074130075130076130077130078130079130080130081130082130083130084130085130086130087130088130089130090130091130092130093130094130095130096130097130098130099130100130101130102130103130104130105130106130107130108130109130110130111130112130113130114130115130116130117130118130119130120130121130122130123130124130125130126130127130128130129130130130131130132130133130134130135130136130137130138130139130140130141130142130143130144130145130146130147130148130149130150130151130152130153130154130155130156130157130158130159130160130161130162130163130164130165130166130167130168130169130170130171130172130173130174130175130176130177130178130179130180130181130182130183130184130185130186130187130188130189130190130191130192130193130194130195130196130197130198130199130200130201130202130203130204130205130206130207130208130209130210130211130212130213130214130215130216130217130218130219130220130221130222130223130224130225130226130227130228130229130230130231130232130233130234130235130236130237130238130239130240130241130242130243130244130245130246130247130248130249130250130251130252130253130254130255130256130257130258130259130260130261130262130263130264130265130266130267130268130269130270130271130272130273130274130275130276130277130278130279130280130281130282130283130284130285130286130287130288130289130290130291130292130293130294130295130296130297130298130299130300130301130302130303130304130305130306130307130308130309130310130311130312130313130314130315130316130317130318130319130320130321130322130323130324130325130326130327130328130329130330130331130332130333130334130335130336130337130338130339130340130341130342130343130344130345130346130347130348130349130350130351130352130353130354130355130356130357130358130359130360130361130362130363130364130365130366130367130368130369130370130371130372130373130374130375130376130377130378130379130380130381130382130383130384130385130386130387130388130389130390130391130392130393130394130395130396130397130398130399130400130401130402130403130404130405130406130407130408130409130410130411130412130413130414130415130416130417130418130419130420130421130422130423130424130425130426130427130428130429130430130431130432130433130434130435130436130437130438130439130440130441130442130443130444130445130446130447130448130449130450130451130452130453130454130455130456130457130458130459130460130461130462130463130464130465130466130467130468130469130470130471130472130473130474130475130476130477130478130479130480130481130482130483130484130485130486130487130488130489130490130491130492130493130494130495130496130497130498130499130500130501130502130503130504130505130506130507130508130509130510130511130512130513130514130515130516130517130518130519130520130521130522130523130524130525130526130527130528130529130530130531130532130533130534130535130536130537130538130539130540130541130542130543130544130545130546130547130548130549130550130551130552130553130554130555130556130557130558130559130560130561130562130563130564130565130566130567130568130569130570130571130572130573130574130575130576130577130578130579130580130581130582130583130584130585130586130587130588130589130590130591130592130593130594130595130596130597130598130599130600130601130602130603130604130605130606130607130608130609130610130611130612130613130614130615130616130617130618130619130620130621130622130623130624130625130626130627130628130629130630130631130632130633130634130635130636130637130638130639130640130641130642130643130644130645130646130647130648130649130650130651130652130653130654130655130656130657130658130659130660130661130662130663130664130665130666130667130668130669130670130671130672130673130674130675130676130677130678130679130680130681130682130683130684130685130686130687130688130689130690130691130692130693130694130695130696130697130698130699130700130701130702130703130704130705130706130707130708130709130710130711130712130713130714130715130716130717130718130719130720130721130722130723130724130725130726130727130728130729130730130731130732130733130734130735130736130737130738130739130740130741130742130743130744130745130746130747130748130749130750130751130752130753130754130755130756130757130758130759130760130761130762130763130764130765130766130767130768130769130770130771130772130773130774130775130776130777130778130779130780130781130782130783130784130785130786130787130788130789130790130791130792130793130794130795130796130797130798130799130800130801130802130803130804130805130806130807130808130809130810130811130812130813130814130815130816130817130818130819130820130821130822130823130824130825130826130827130828130829130830130831130832130833130834130835130836130837130838130839130840130841130842130843130844130845130846130847130848130849130850130851130852130853130854130855130856130857130858130859130860130861130862130863130864130865130866130867130868130869130870130871130872130873130874130875130876130877130878130879130880130881130882130883130884130885130886130887130888130889130890130891130892130893130894130895130896130897130898130899130900130901130902130903130904130905130906130907130908130909130910130911130912130913130914130915130916130917130918130919130920130921130922130923130924130925130926130927130928130929130930130931130932130933130934130935130936130937130938130939130940130941130942130943130944130945130946130947130948130949130950130951130952130953130954130955130956130957130958130959130960130961130962130963130964130965130966130967130968130969130970130971130972130973130974130975130976130977130978130979130980130981130982130983130984130985130986130987130988130989130990130991130992130993130994130995130996130997130998130999131000131001131002131003131004131005131006131007131008131009131010131011131012131013131014131015131016131017131018131019131020131021131022131023131024131025131026131027131028131029131030131031131032131033131034131035131036131037131038131039131040131041131042131043131044131045131046131047131048131049131050131051131052131053131054131055131056131057131058131059131060131061131062131063131064131065131066131067131068131069131070131071131072131073131074131075131076131077131078131079131080131081131082131083131084131085131086131087131088131089131090131091131092131093131094131095131096131097131098131099131100131101131102131103131104131105131106131107131108131109131110131111131112131113131114131115131116131117131118131119131120131121131122131123131124131125131126131127131128131129131130131131131132131133131134131135131136131137131138131139131140131141131142131143131144131145131146131147131148131149131150131151131152131153131154131155131156131157131158131159131160131161131162131163131164131165131166131167131168131169131170131171131172131173131174131175131176131177131178131179131180131181131182131183131184131185131186131187131188131189131190131191131192131193131194131195131196131197131198131199131200131201131202131203131204131205131206131207131208131209131210131211131212131213131214131215131216131217131218131219131220131221131222131223131224131225131226131227131228131229131230131231131232131233131234131235131236131237131238131239131240131241131242131243131244131245131246131247131248131249131250131251131252131253131254131255131256131257131258131259131260131261131262131263131264131265131266131267131268131269131270131271131272131273131274131275131276131277131278131279131280131281131282131283131284131285131286131287131288131289131290131291131292131293131294131295131296131297131298131299131300131301131302131303131304131305131306131307131308131309131310131311131312131313131314131315131316131317131318131319131320131321131322131323131324131325131326131327131328131329131330131331131332131333131334131335131336131337131338131339131340131341131342131343131344131345131346131347131348131349131350131351131352131353131354131355131356131357131358131359131360131361131362131363131364131365131366131367131368131369131370131371131372131373131374131375131376131377131378131379131380131381131382131383131384131385131386131387131388131389131390131391131392131393131394131395131396131397131398131399131400131401131402131403131404131405131406131407131408131409131410131411131412131413131414131415131416131417131418131419131420131421131422131423131424131425131426131427131428131429131430131431131432131433131434131435131436131437131438131439131440131441131442131443131444131445131446131447131448131449131450131451131452131453131454131455131456131457131458131459131460131461131462131463131464131465131466131467131468131469131470131471131472131473131474131475131476131477131478131479131480131481131482131483131484131485131486131487131488131489131490131491131492131493131494131495131496131497131498131499131500131501131502131503131504131505131506131507131508131509131510131511131512131513131514131515131516131517131518131519131520131521131522131523131524131525131526131527131528131529131530131531131532131533131534131535131536131537131538131539131540131541131542131543131544131545131546131547131548131549131550131551131552131553131554131555131556131557131558131559131560131561131562131563131564131565131566131567131568131569131570131571131572131573131574131575131576131577131578131579131580131581131582131583131584131585131586131587131588131589131590131591131592131593131594131595131596131597131598131599131600131601131602131603131604131605131606131607131608131609131610131611131612131613131614131615131616131617131618131619131620131621131622131623131624131625131626131627131628131629131630131631131632131633131634131635131636131637131638131639131640131641131642131643131644131645131646131647131648131649131650131651131652131653131654131655131656131657131658131659131660131661131662131663131664131665131666131667131668131669131670131671131672131673131674131675131676131677131678131679131680131681131682131683131684131685131686131687131688131689131690131691131692131693131694131695131696131697131698131699131700131701131702131703131704131705131706131707131708131709131710131711131712131713131714131715131716131717131718131719131720131721131722131723131724131725131726131727131728131729131730131731131732131733131734131735131736131737131738131739131740131741131742131743131744131745131746131747131748131749131750131751131752131753131754131755131756131757131758131759131760131761131762131763131764131765131766131767131768131769131770131771131772131773131774131775131776131777131778131779131780131781131782131783131784131785131786131787131788131789131790131791131792131793131794131795131796131797131798131799131800131801131802131803131804131805131806131807131808131809131810131811131812131813131814131815131816131817131818131819131820131821131822131823131824131825131826131827131828131829131830131831131832131833131834131835131836131837131838131839131840131841131842131843131844131845131846131847131848131849131850131851131852131853131854131855131856131857131858131859131860131861131862131863131864131865131866131867131868131869131870131871131872131873131874131875131876131877131878131879131880131881131882131883131884131885131886131887131888131889131890131891131892131893131894131895131896131897131898131899131900131901131902131903131904131905131906131907131908131909131910131911131912131913131914131915131916131917131918131919131920131921131922131923131924131925131926131927131928131929131930131931131932131933131934131935131936131937131938131939131940131941131942131943131944131945131946131947131948131949131950131951131952131953131954131955131956131957131958131959131960131961131962131963131964131965131966131967131968131969131970131971131972131973131974131975131976131977131978131979131980131981131982131983131984131985131986131987131988131989131990131991131992131993131994131995131996131997131998131999132000132001132002132003132004132005132006132007132008132009132010132011132012132013132014132015132016132017132018132019132020132021132022132023132024132025132026132027132028132029132030132031132032132033132034132035132036132037132038132039132040132041132042132043132044132045132046132047132048132049132050132051132052132053132054132055132056132057132058132059132060132061132062132063132064132065132066132067132068132069132070132071132072132073132074132075132076132077132078132079132080132081132082132083132084132085132086132087132088132089132090132091132092132093132094132095132096132097132098132099132100132101132102132103132104132105132106132107132108132109132110132111132112132113132114132115132116132117132118132119132120132121132122132123132124132125132126132127132128132129132130132131132132132133132134132135132136132137132138132139132140132141132142132143132144132145132146132147132148132149132150132151132152132153132154132155132156132157132158132159132160132161132162132163132164132165132166132167132168132169132170132171132172132173132174132175132176132177132178132179132180132181132182132183132184132185132186132187132188132189132190132191132192132193132194132195132196132197132198132199132200132201132202132203132204132205132206132207132208132209132210132211132212132213132214132215132216132217132218132219132220132221132222132223132224132225132226132227132228132229132230132231132232132233132234132235132236132237132238132239132240132241132242132243132244132245132246132247132248132249132250132251132252132253132254132255132256132257132258132259132260132261132262132263132264132265132266132267132268132269132270132271132272132273132274132275132276132277132278132279132280132281132282132283132284132285132286132287132288132289132290132291132292132293132294132295132296132297132298132299132300132301132302132303132304132305132306132307132308132309132310132311132312132313132314132315132316132317132318132319132320132321132322132323132324132325132326132327132328132329132330132331132332132333132334132335132336132337132338132339132340132341132342132343132344132345132346132347132348132349132350132351132352132353132354132355132356132357132358132359132360132361132362132363132364132365132366132367132368132369132370132371132372132373132374132375132376132377132378132379132380132381132382132383132384132385132386132387132388132389132390132391132392132393132394132395132396132397132398132399132400132401132402132403132404132405132406132407132408132409132410132411132412132413132414132415132416132417132418132419132420132421132422132423132424132425132426132427132428132429132430132431132432132433132434132435132436132437132438132439132440132441132442132443132444132445132446132447132448132449132450132451132452132453132454132455132456132457132458132459132460132461132462132463132464132465132466132467132468132469132470132471132472132473132474132475132476132477132478132479132480132481132482132483132484132485132486132487132488132489132490132491132492132493132494132495132496132497132498132499132500132501132502132503132504132505132506132507132508132509132510132511132512132513132514132515132516132517132518132519132520132521132522132523132524132525132526132527132528132529132530132531132532132533132534132535132536132537132538132539132540132541132542132543132544132545132546132547132548132549132550132551132552132553132554132555132556132557132558132559132560132561132562132563132564132565132566132567132568132569132570132571132572132573132574132575132576132577132578132579132580132581132582132583132584132585132586132587132588132589132590132591132592132593132594132595132596132597132598132599132600132601132602132603132604132605132606132607132608132609132610132611132612132613132614132615132616132617132618132619132620132621132622132623132624132625132626132627132628132629132630132631132632132633132634132635132636132637132638132639132640132641132642132643132644132645132646132647132648132649132650132651132652132653132654132655132656132657132658132659132660132661132662132663132664132665132666132667132668132669132670132671132672132673132674132675132676132677132678132679132680132681132682132683132684132685132686132687132688132689132690132691132692132693132694132695132696132697132698132699132700132701132702132703132704132705132706132707132708132709132710132711132712132713132714132715132716132717132718132719132720132721132722132723132724132725132726132727132728132729132730132731132732132733132734132735132736132737132738132739132740132741132742132743132744132745132746132747132748132749132750132751132752132753132754132755132756132757132758132759132760132761132762132763132764132765132766132767132768132769132770132771132772132773132774132775132776132777132778132779132780132781132782132783132784132785132786132787132788132789132790132791132792132793132794132795132796132797132798132799132800132801132802132803132804132805132806132807132808132809132810132811132812132813132814132815132816132817132818132819132820132821132822132823132824132825132826132827132828132829132830132831132832132833132834132835132836132837132838132839132840132841132842132843132844132845132846132847132848132849132850132851132852132853132854132855132856132857132858132859132860132861132862132863132864132865132866132867132868132869132870132871132872132873132874132875132876132877132878132879132880132881132882132883132884132885132886132887132888132889132890132891132892132893132894132895132896132897132898132899132900132901132902132903132904132905132906132907132908132909132910132911132912132913132914132915132916132917132918132919132920132921132922132923132924132925132926132927132928132929132930132931132932132933132934132935132936132937132938132939132940132941132942132943132944132945132946132947132948132949132950132951132952132953132954132955132956132957132958132959132960132961132962132963132964132965132966132967132968132969132970132971132972132973132974132975132976132977132978132979132980132981132982132983132984132985132986132987132988132989132990132991132992132993132994132995132996132997132998132999133000133001133002133003133004133005133006133007133008133009133010133011133012133013133014133015133016133017133018133019133020133021133022133023133024133025133026133027133028133029133030133031133032133033133034133035133036133037133038133039133040133041133042133043133044133045133046133047133048133049133050133051133052133053133054133055133056133057133058133059133060133061133062133063133064133065133066133067133068133069133070133071133072133073133074133075133076133077133078133079133080133081133082133083133084133085133086133087133088133089133090133091133092133093133094133095133096133097133098133099133100133101133102133103133104133105133106133107133108133109133110133111133112133113133114133115133116133117133118133119133120133121133122133123133124133125133126133127133128133129133130133131133132133133133134133135133136133137133138133139133140133141133142133143133144133145133146133147133148133149133150133151133152133153133154133155133156133157133158133159133160133161133162133163133164133165133166133167133168133169133170133171133172133173133174133175133176133177133178133179133180133181133182133183133184133185133186133187133188133189133190133191133192133193133194133195133196133197133198133199133200133201133202133203133204133205133206133207133208133209133210133211133212133213133214133215133216133217133218133219133220133221133222133223133224133225133226133227133228133229133230133231133232133233133234133235133236133237133238133239133240133241133242133243133244133245133246133247133248133249133250133251133252133253133254133255133256133257133258133259133260133261133262133263133264133265133266133267133268133269133270133271133272133273133274133275133276133277133278133279133280133281133282133283133284133285133286133287133288133289133290133291133292133293133294133295133296133297133298133299133300133301133302133303133304133305133306133307133308133309133310133311133312133313133314133315133316133317133318133319133320133321133322133323133324133325133326133327133328133329133330133331133332133333133334133335133336133337133338133339133340133341133342133343133344133345133346133347133348133349133350133351133352133353133354133355133356133357133358133359133360133361133362133363133364133365133366133367133368133369133370133371133372133373133374133375133376133377133378133379133380133381133382133383133384133385133386133387133388133389133390133391133392133393133394133395133396133397133398133399133400133401133402133403133404133405133406133407133408133409133410133411133412133413133414133415133416133417133418133419133420133421133422133423133424133425133426133427133428133429133430133431133432133433133434133435133436133437133438133439133440133441133442133443133444133445133446133447133448133449133450133451133452133453133454133455133456133457133458133459133460133461133462133463133464133465133466133467133468133469133470133471133472133473133474133475133476133477133478133479133480133481133482133483133484133485133486133487133488133489133490133491133492133493133494133495133496133497133498133499133500133501133502133503133504133505133506133507133508133509133510133511133512133513133514133515133516133517133518133519133520133521133522133523133524133525133526133527133528133529133530133531133532133533133534133535133536133537133538133539133540133541133542133543133544133545133546133547133548133549133550133551133552133553133554133555133556133557133558133559133560133561133562133563133564133565133566133567133568133569133570133571133572133573133574133575133576133577133578133579133580133581133582133583133584133585133586133587133588133589133590133591133592133593133594133595133596133597133598133599133600133601133602133603133604133605133606133607133608133609133610133611133612133613133614133615133616133617133618133619133620133621133622133623133624133625133626133627133628133629133630133631133632133633133634133635133636133637133638133639133640133641133642133643133644133645133646133647133648133649133650133651133652133653133654133655133656133657133658133659133660133661133662133663133664133665133666133667133668133669133670133671133672133673133674133675133676133677133678133679133680133681133682133683133684133685133686133687133688133689133690133691133692133693133694133695133696133697133698133699133700133701133702133703133704133705133706133707133708133709133710133711133712133713133714133715133716133717133718133719133720133721133722133723133724133725133726133727133728133729133730133731133732133733133734133735133736133737133738133739133740133741133742133743133744133745133746133747133748133749133750133751133752133753133754133755133756133757133758133759133760133761133762133763133764133765133766133767133768133769133770133771133772133773133774133775133776133777133778133779133780133781133782133783133784133785133786133787133788133789133790133791133792133793133794133795133796133797133798133799133800133801133802133803133804133805133806133807133808133809133810133811133812133813133814133815133816133817133818133819133820133821133822133823133824133825133826133827133828133829133830133831133832133833133834133835133836133837133838133839133840133841133842133843133844133845133846133847133848133849133850133851133852133853133854133855133856133857133858133859133860133861133862133863133864133865133866133867133868133869133870133871133872133873133874133875133876133877133878133879133880133881133882133883133884133885133886133887133888133889133890133891133892133893133894133895133896133897133898133899133900133901133902133903133904133905133906133907133908133909133910133911133912133913133914133915133916133917133918133919133920133921133922133923133924133925133926133927133928133929133930133931133932133933133934133935133936133937133938133939133940133941133942133943133944133945133946133947133948133949133950133951133952133953133954133955133956133957133958133959133960133961133962133963133964133965133966133967133968133969133970133971133972133973133974133975133976133977133978133979133980133981133982133983133984133985133986133987133988133989133990133991133992133993133994133995133996133997133998133999134000134001134002134003134004134005134006134007134008134009134010134011134012134013134014134015134016134017134018134019134020134021134022134023134024134025134026134027134028134029134030134031134032134033134034134035134036134037134038134039134040134041134042134043134044134045134046134047134048134049134050134051134052134053134054134055134056134057134058134059134060134061134062134063134064134065134066134067134068134069134070134071134072134073134074134075134076134077134078134079134080134081134082134083134084134085134086134087134088134089134090134091134092134093134094134095134096134097134098134099134100134101134102134103134104134105134106134107134108134109134110134111134112134113134114134115134116134117134118134119134120134121134122134123134124134125134126134127134128134129134130134131134132134133134134134135134136134137134138134139134140134141134142134143134144134145134146134147134148134149134150134151134152134153134154134155134156134157134158134159134160134161134162134163134164134165134166134167134168134169134170134171134172134173134174134175134176134177134178134179134180134181134182134183134184134185134186134187134188134189134190134191134192134193134194134195134196134197134198134199134200134201134202134203134204134205134206134207134208134209134210134211134212134213134214134215134216134217134218134219134220134221134222134223134224134225134226134227134228134229134230134231134232134233134234134235134236134237134238134239134240134241134242134243134244134245134246134247134248134249134250134251134252134253134254134255134256134257134258134259134260134261134262134263134264134265134266134267134268134269134270134271134272134273134274134275134276134277134278134279134280134281134282134283134284134285134286134287134288134289134290134291134292134293134294134295134296134297134298134299134300134301134302134303134304134305134306134307134308134309134310134311134312134313134314134315134316134317134318134319134320134321134322134323134324134325134326134327134328134329134330134331134332134333134334134335134336134337134338134339134340134341134342134343134344134345134346134347134348134349134350134351134352134353134354134355134356134357134358134359134360134361134362134363134364134365134366134367134368134369134370134371134372134373134374134375134376134377134378134379134380134381134382134383134384134385134386134387134388134389134390134391134392134393134394134395134396134397134398134399134400134401134402134403134404134405134406134407134408134409134410134411134412134413134414134415134416134417134418134419134420134421134422134423134424134425134426134427134428134429134430134431134432134433134434134435134436134437134438134439134440134441134442134443134444134445134446134447134448134449134450134451134452134453134454134455134456134457134458134459134460134461134462134463134464134465134466134467134468134469134470134471134472134473134474134475134476134477134478134479134480134481134482134483134484134485134486134487134488134489134490134491134492134493134494134495134496134497134498134499134500134501134502134503134504134505134506134507134508134509134510134511134512134513134514134515134516134517134518134519134520134521134522134523134524134525134526134527134528134529134530134531134532134533134534134535134536134537134538134539134540134541134542134543134544134545134546134547134548134549134550134551134552134553134554134555134556134557134558134559134560134561134562134563134564134565134566134567134568134569134570134571134572134573134574134575134576134577134578134579134580134581134582134583134584134585134586134587134588134589134590134591134592134593134594134595134596134597134598134599134600134601134602134603134604134605134606134607134608134609134610134611134612134613134614134615134616134617134618134619134620134621134622134623134624134625134626134627134628134629134630134631134632134633134634134635134636134637134638134639134640134641134642134643134644134645134646134647134648134649134650134651134652134653134654134655134656134657134658134659134660134661134662134663134664134665134666134667134668134669134670134671134672134673134674134675134676134677134678134679134680134681134682134683134684134685134686134687134688134689134690134691134692134693134694134695134696134697134698134699134700134701134702134703134704134705134706134707134708134709134710134711134712134713134714134715134716134717134718134719134720134721134722134723134724134725134726134727134728134729134730134731134732134733134734134735134736134737134738134739134740134741134742134743134744134745134746134747134748134749134750134751134752134753134754134755134756134757134758134759134760134761134762134763134764134765134766134767134768134769134770134771134772134773134774134775134776134777134778134779134780134781134782134783134784134785134786134787134788134789134790134791134792134793134794134795134796134797134798134799134800134801134802134803134804134805134806134807134808134809134810134811134812134813134814134815134816134817134818134819134820134821134822134823134824134825134826134827134828134829134830134831134832134833134834134835134836134837134838134839134840134841134842134843134844134845134846134847134848134849134850134851134852134853134854134855134856134857134858134859134860134861134862134863134864134865134866134867134868134869134870134871134872134873134874134875134876134877134878134879134880134881134882134883134884134885134886134887134888134889134890134891134892134893134894134895134896134897134898134899134900134901134902134903134904134905134906134907134908134909134910134911134912134913134914134915134916134917134918134919134920134921134922134923134924134925134926134927134928134929134930134931134932134933134934134935134936134937134938134939134940134941134942134943134944134945134946134947134948134949134950134951134952134953134954134955134956134957134958134959134960134961134962134963134964134965134966134967134968134969134970134971134972134973134974134975134976134977134978134979134980134981134982134983134984134985134986134987134988134989134990134991134992134993134994134995134996134997134998134999135000135001135002135003135004135005135006135007135008135009135010135011135012135013135014135015135016135017135018135019135020135021135022135023135024135025135026135027135028135029135030135031135032135033135034135035135036135037135038135039135040135041135042135043135044135045135046135047135048135049135050135051135052135053135054135055135056135057135058135059135060135061135062135063135064135065135066135067135068135069135070135071135072135073135074135075135076135077135078135079135080135081135082135083135084135085135086135087135088135089135090135091135092135093135094135095135096135097135098135099135100135101135102135103135104135105135106135107135108135109135110135111135112135113135114135115135116135117135118135119135120135121135122135123135124135125135126135127135128135129135130135131135132135133135134135135135136135137135138135139135140135141135142135143135144135145135146135147135148135149135150135151135152135153135154135155135156135157135158135159135160135161135162135163135164135165135166135167135168135169135170135171135172135173135174135175135176135177135178135179135180135181135182135183135184135185135186135187135188135189135190135191135192135193135194135195135196135197135198135199135200135201135202135203135204135205135206135207135208135209135210135211135212135213135214135215135216135217135218135219135220135221135222135223135224135225135226135227135228135229135230135231135232135233135234135235135236135237135238135239135240135241135242135243135244135245135246135247135248135249135250135251135252135253135254135255135256135257135258135259135260135261135262135263135264135265135266135267135268135269135270135271135272135273135274135275135276135277135278135279135280135281135282135283135284135285135286135287135288135289135290135291135292135293135294135295135296135297135298135299135300135301135302135303135304135305135306135307135308135309135310135311135312135313135314135315135316135317135318135319135320135321135322135323135324135325135326135327135328135329135330135331135332135333135334135335135336135337135338135339135340135341135342135343135344135345135346135347135348135349135350135351135352135353135354135355135356135357135358135359135360135361135362135363135364135365135366135367135368135369135370135371135372135373135374135375135376135377135378135379135380135381135382135383135384135385135386135387135388135389135390135391135392135393135394135395135396135397135398135399135400135401135402135403135404135405135406135407135408135409135410135411135412135413135414135415135416135417135418135419135420135421135422135423135424135425135426135427135428135429135430135431135432135433135434135435135436135437135438135439135440135441135442135443135444135445135446135447135448135449135450135451135452135453135454135455135456135457135458135459135460135461135462135463135464135465135466135467135468135469135470135471135472135473135474135475135476135477135478135479135480135481135482135483135484135485135486135487135488135489135490135491135492135493135494135495135496135497135498135499135500135501135502135503135504135505135506135507135508135509135510135511135512135513135514135515135516135517135518135519135520135521135522135523135524135525135526135527135528135529135530135531135532135533135534135535135536135537135538135539135540135541135542135543135544135545135546135547135548135549135550135551135552135553135554135555135556135557135558135559135560135561135562135563135564135565135566135567135568135569135570135571135572135573135574135575135576135577135578135579135580135581135582135583135584135585135586135587135588135589135590135591135592135593135594135595135596135597135598135599135600135601135602135603135604135605135606135607135608135609135610135611135612135613135614135615135616135617135618135619135620135621135622135623135624135625135626135627135628135629135630135631135632135633135634135635135636135637135638135639135640135641135642135643135644135645135646135647135648135649135650135651135652135653135654135655135656135657135658135659135660135661135662135663135664135665135666135667135668135669135670135671135672135673135674135675135676135677135678135679135680135681135682135683135684135685135686135687135688135689135690135691135692135693135694135695135696135697135698135699135700135701135702135703135704135705135706135707135708135709135710135711135712135713135714135715135716135717135718135719135720135721135722135723135724135725135726135727135728135729135730135731135732135733135734135735135736135737135738135739135740135741135742135743135744135745135746135747135748135749135750135751135752135753135754135755135756135757135758135759135760135761135762135763135764135765135766135767135768135769135770135771135772135773135774135775135776135777135778135779135780135781135782135783135784135785135786135787135788135789135790135791135792135793135794135795135796135797135798135799135800135801135802135803135804135805135806135807135808135809135810135811135812135813135814135815135816135817135818135819135820135821135822135823135824135825135826135827135828135829135830135831135832135833135834135835135836135837135838135839135840135841135842135843135844135845135846135847135848135849135850135851135852135853135854135855135856135857135858135859135860135861135862135863135864135865135866135867135868135869135870135871135872135873135874135875135876135877135878135879135880135881135882135883135884135885135886135887135888135889135890135891135892135893135894135895135896135897135898135899135900135901135902135903135904135905135906135907135908135909135910135911135912135913135914135915135916135917135918135919135920135921135922135923135924135925135926135927135928135929135930135931135932135933135934135935135936135937135938135939135940135941135942135943135944135945135946135947135948135949135950135951135952135953135954135955135956135957135958135959135960135961135962135963135964135965135966135967135968135969135970135971135972135973135974135975135976135977135978135979135980135981135982135983135984135985135986135987135988135989135990135991135992135993135994135995135996135997135998135999136000136001136002136003136004136005136006136007136008136009136010136011136012136013136014136015136016136017136018136019136020136021136022136023136024136025136026136027136028136029136030136031136032136033136034136035136036136037136038136039136040136041136042136043136044136045136046136047136048136049136050136051136052136053136054136055136056136057136058136059136060136061136062136063136064136065136066136067136068136069136070136071136072136073136074136075136076136077136078136079136080136081136082136083136084136085136086136087136088136089136090136091136092136093136094136095136096136097136098136099136100136101136102136103136104136105136106136107136108136109136110136111136112136113136114136115136116136117136118136119136120136121136122136123136124136125136126136127136128136129136130136131136132136133136134136135136136136137136138136139136140136141136142136143136144136145136146136147136148136149136150136151136152136153136154136155136156136157136158136159136160136161136162136163136164136165136166136167136168136169136170136171136172136173136174136175136176136177136178136179136180136181136182136183136184136185136186136187136188136189136190136191136192136193136194136195136196136197136198136199136200136201136202136203136204136205136206136207136208136209136210136211136212136213136214136215136216136217136218136219136220136221136222136223136224136225136226136227136228136229136230136231136232136233136234136235136236136237136238136239136240136241136242136243136244136245136246136247136248136249136250136251136252136253136254136255136256136257136258136259136260136261136262136263136264136265136266136267136268136269136270136271136272136273136274136275136276136277136278136279136280136281136282136283136284136285136286136287136288136289136290136291136292136293136294136295136296136297136298136299136300136301136302136303136304136305136306136307136308136309136310136311136312136313136314136315136316136317136318136319136320136321136322136323136324136325136326136327136328136329136330136331136332136333136334136335136336136337136338136339136340136341136342136343136344136345136346136347136348136349136350136351136352136353136354136355136356136357136358136359136360136361136362136363136364136365136366136367136368136369136370136371136372136373136374136375136376136377136378136379136380136381136382136383136384136385136386136387136388136389136390136391136392136393136394136395136396136397136398136399136400136401136402136403136404136405136406136407136408136409136410136411136412136413136414136415136416136417136418136419136420136421136422136423136424136425136426136427136428136429136430136431136432136433136434136435136436136437136438136439136440136441136442136443136444136445136446136447136448136449136450136451136452136453136454136455136456136457136458136459136460136461136462136463136464136465136466136467136468136469136470136471136472136473136474136475136476136477136478136479136480136481136482136483136484136485136486136487136488136489136490136491136492136493136494136495136496136497136498136499136500136501136502136503136504136505136506136507136508136509136510136511136512136513136514136515136516136517136518136519136520136521136522136523136524136525136526136527136528136529136530136531136532136533136534136535136536136537136538136539136540136541136542136543136544136545136546136547136548136549136550136551136552136553136554136555136556136557136558136559136560136561136562136563136564136565136566136567136568136569136570136571136572136573136574136575136576136577136578136579136580136581136582136583136584136585136586136587136588136589136590136591136592136593136594136595136596136597136598136599136600136601136602136603136604136605136606136607136608136609136610136611136612136613136614136615136616136617136618136619136620136621136622136623136624136625136626136627136628136629136630136631136632136633136634136635136636136637136638136639136640136641136642136643136644136645136646136647136648136649136650136651136652136653136654136655136656136657136658136659136660136661136662136663136664136665136666136667136668136669136670136671136672136673136674136675136676136677136678136679136680136681136682136683136684136685136686136687136688136689136690136691136692136693136694136695136696136697136698136699136700136701136702136703136704136705136706136707136708136709136710136711136712136713136714136715136716136717136718136719136720136721136722136723136724136725136726136727136728136729136730136731136732136733136734136735136736136737136738136739136740136741136742136743136744136745136746136747136748136749136750136751136752136753136754136755136756136757136758136759136760136761136762136763136764136765136766136767136768136769136770136771136772136773136774136775136776136777136778136779136780136781136782136783136784136785136786136787136788136789136790136791136792136793136794136795136796136797136798136799136800136801136802136803136804136805136806136807136808136809136810136811136812136813136814136815136816136817136818136819136820136821136822136823136824136825136826136827136828136829136830136831136832136833136834136835136836136837136838136839136840136841136842136843136844136845136846136847136848136849136850136851136852136853136854136855136856136857136858136859136860136861136862136863136864136865136866136867136868136869136870136871136872136873136874136875136876136877136878136879136880136881136882136883136884136885136886136887136888136889136890136891136892136893136894136895136896136897136898136899136900136901136902136903136904136905136906136907136908136909136910136911136912136913136914136915136916136917136918136919136920136921136922136923136924136925136926136927136928136929136930136931136932136933136934136935136936136937136938136939136940136941136942136943136944136945136946136947136948136949136950136951136952136953136954136955136956136957136958136959136960136961136962136963136964136965136966136967136968136969136970136971136972136973136974136975136976136977136978136979136980136981136982136983136984136985136986136987136988136989136990136991136992136993136994136995136996136997136998136999137000137001137002137003137004137005137006137007137008137009137010137011137012137013137014137015137016137017137018137019137020137021137022137023137024137025137026137027137028137029137030137031137032137033137034137035137036137037137038137039137040137041137042137043137044137045137046137047137048137049137050137051137052137053137054137055137056137057137058137059137060137061137062137063137064137065137066137067137068137069137070137071137072137073137074137075137076137077137078137079137080137081137082137083137084137085137086137087137088137089137090137091137092137093137094137095137096137097137098137099137100137101137102137103137104137105137106137107137108137109137110137111137112137113137114137115137116137117137118137119137120137121137122137123137124137125137126137127137128137129137130137131137132137133137134137135137136137137137138137139137140137141137142137143137144137145137146137147137148137149137150137151137152137153137154137155137156137157137158137159137160137161137162137163137164137165137166137167137168137169137170137171137172137173137174137175137176137177137178137179137180137181137182137183137184137185137186137187137188137189137190137191137192137193137194137195137196137197137198137199137200137201137202137203137204137205137206137207137208137209137210137211137212137213137214137215137216137217137218137219137220137221137222137223137224137225137226137227137228137229137230137231137232137233137234137235137236137237137238137239137240137241137242137243137244137245137246137247137248137249137250137251137252137253137254137255137256137257137258137259137260137261137262137263137264137265137266137267137268137269137270137271137272137273137274137275137276137277137278137279137280137281137282137283137284137285137286137287137288137289137290137291137292137293137294137295137296137297137298137299137300137301137302137303137304137305137306137307137308137309137310137311137312137313137314137315137316137317137318137319137320137321137322137323137324137325137326137327137328137329137330137331137332137333137334137335137336137337137338137339137340137341137342137343137344137345137346137347137348137349137350137351137352137353137354137355137356137357137358137359137360137361137362137363137364137365137366137367137368137369137370137371137372137373137374137375137376137377137378137379137380137381137382137383137384137385137386137387137388137389137390137391137392137393137394137395137396137397137398137399137400137401137402137403137404137405137406137407137408137409137410137411137412137413137414137415137416137417137418137419137420137421137422137423137424137425137426137427137428137429137430137431137432137433137434137435137436137437137438137439137440137441137442137443137444137445137446137447137448137449137450137451137452137453137454137455137456137457137458137459137460137461137462137463137464137465137466137467137468137469137470137471137472137473137474137475137476137477137478137479137480137481137482137483137484137485137486137487137488137489137490137491137492137493137494137495137496137497137498137499137500137501137502137503137504137505137506137507137508137509137510137511137512137513137514137515137516137517137518137519137520137521137522137523137524137525137526137527137528137529137530137531137532137533137534137535137536137537137538137539137540137541137542137543137544137545137546137547137548137549137550137551137552137553137554137555137556137557137558137559137560137561137562137563137564137565137566137567137568137569137570137571137572137573137574137575137576137577137578137579137580137581137582137583137584137585137586137587137588137589137590137591137592137593137594137595137596137597137598137599137600137601137602137603137604137605137606137607137608137609137610137611137612137613137614137615137616137617137618137619137620137621137622137623137624137625137626137627137628137629137630137631137632137633137634137635137636137637137638137639137640137641137642137643137644137645137646137647137648137649137650137651137652137653137654137655137656137657137658137659137660137661137662137663137664137665137666137667137668137669137670137671137672137673137674137675137676137677137678137679137680137681137682137683137684137685137686137687137688137689137690137691137692137693137694137695137696137697137698137699137700137701137702137703137704137705137706137707137708137709137710137711137712137713137714137715137716137717137718137719137720137721137722137723137724137725137726137727137728137729137730137731137732137733137734137735137736137737137738137739137740137741137742137743137744137745137746137747137748137749137750137751137752137753137754137755137756137757137758137759137760137761137762137763137764137765137766137767137768137769137770137771137772137773137774137775137776137777137778137779137780137781137782137783137784137785137786137787137788137789137790137791137792137793137794137795137796137797137798137799137800137801137802137803137804137805137806137807137808137809137810137811137812137813137814137815137816137817137818137819137820137821137822137823137824137825137826137827137828137829137830137831137832137833137834137835137836137837137838137839137840137841137842137843137844137845137846137847137848137849137850137851137852137853137854137855137856137857137858137859137860137861137862137863137864137865137866137867137868137869137870137871137872137873137874137875137876137877137878137879137880137881137882137883137884137885137886137887137888137889137890137891137892137893137894137895137896137897137898137899137900137901137902137903137904137905137906137907137908137909137910137911137912137913137914137915137916137917137918137919137920137921137922137923137924137925137926137927137928137929137930137931137932137933137934137935137936137937137938137939137940137941137942137943137944137945137946137947137948137949137950137951137952137953137954137955137956137957137958137959137960137961137962137963137964137965137966137967137968137969137970137971137972137973137974137975137976137977137978137979137980137981137982137983137984137985137986137987137988137989137990137991137992137993137994137995137996137997137998137999138000138001138002138003138004138005138006138007138008138009138010138011138012138013138014138015138016138017138018138019138020138021138022138023138024138025138026138027138028138029138030138031138032138033138034138035138036138037138038138039138040138041138042138043138044138045138046138047138048138049138050138051138052138053138054138055138056138057138058138059138060138061138062138063138064138065138066138067138068138069138070138071138072138073138074138075138076138077138078138079138080138081138082138083138084138085138086138087138088138089138090138091138092138093138094138095138096138097138098138099138100138101138102138103138104138105138106138107138108138109138110138111138112138113138114138115138116138117138118138119138120138121138122138123138124138125138126138127138128138129138130138131138132138133138134138135138136138137138138138139138140138141138142138143138144138145138146138147138148138149138150138151138152138153138154138155138156138157138158138159138160138161138162138163138164138165138166138167138168138169138170138171138172138173138174138175138176138177138178138179138180138181138182138183138184138185138186138187138188138189138190138191138192138193138194138195138196138197138198138199138200138201138202138203138204138205138206138207138208138209138210138211138212138213138214138215138216138217138218138219138220138221138222138223138224138225138226138227138228138229138230138231138232138233138234138235138236138237138238138239138240138241138242138243138244138245138246138247138248138249138250138251138252138253138254138255138256138257138258138259138260138261138262138263138264138265138266138267138268138269138270138271138272138273138274138275138276138277138278138279138280138281138282138283138284138285138286138287138288138289138290138291138292138293138294138295138296138297138298138299138300138301138302138303138304138305138306138307138308138309138310138311138312138313138314138315138316138317138318138319138320138321138322138323138324138325138326138327138328138329138330138331138332138333138334138335138336138337138338138339138340138341138342138343138344138345138346138347138348138349138350138351138352138353138354138355138356138357138358138359138360138361138362138363138364138365138366138367138368138369138370138371138372138373138374138375138376138377138378138379138380138381138382138383138384138385138386138387138388138389138390138391138392138393138394138395138396138397138398138399138400138401138402138403138404138405138406138407138408138409138410138411138412138413138414138415138416138417138418138419138420138421138422138423138424138425138426138427138428138429138430138431138432138433138434138435138436138437138438138439138440138441138442138443138444138445138446138447138448138449138450138451138452138453138454138455138456138457138458138459138460138461138462138463138464138465138466138467138468138469138470138471138472138473138474138475138476138477138478138479138480138481138482138483138484138485138486138487138488138489138490138491138492138493138494138495138496138497138498138499138500138501138502138503138504138505138506138507138508138509138510138511138512138513138514138515138516138517138518138519138520138521138522138523138524138525138526138527138528138529138530138531138532138533138534138535138536138537138538138539138540138541138542138543138544138545138546138547138548138549138550138551138552138553138554138555138556138557138558138559138560138561138562138563138564138565138566138567138568138569138570138571138572138573138574138575138576138577138578138579138580138581138582138583138584138585138586138587138588138589138590138591138592138593138594138595138596138597138598138599138600138601138602138603138604138605138606138607138608138609138610138611138612138613138614138615138616138617138618138619138620138621138622138623138624138625138626138627138628138629138630138631138632138633138634138635138636138637138638138639138640138641138642138643138644138645138646138647138648138649138650138651138652138653138654138655138656138657138658138659138660138661138662138663138664138665138666138667138668138669138670138671138672138673138674138675138676138677138678138679138680138681138682138683138684138685138686138687138688138689138690138691138692138693138694138695138696138697138698138699138700138701138702138703138704138705138706138707138708138709138710138711138712138713138714138715138716138717138718138719138720138721138722138723138724138725138726138727138728138729138730138731138732138733138734138735138736138737138738138739138740138741138742138743138744138745138746138747138748138749138750138751138752138753138754138755138756138757138758138759138760138761138762138763138764138765138766138767138768138769138770138771138772138773138774138775138776138777138778138779138780138781138782138783138784138785138786138787138788138789138790138791138792138793138794138795138796138797138798138799138800138801138802138803138804138805138806138807138808138809138810138811138812138813138814138815138816138817138818138819138820138821138822138823138824138825138826138827138828138829138830138831138832138833138834138835138836138837138838138839138840138841138842138843138844138845138846138847138848138849138850138851138852138853138854138855138856138857138858138859138860138861138862138863138864138865138866138867138868138869138870138871138872138873138874138875138876138877138878138879138880138881138882138883138884138885138886138887138888138889138890138891138892138893138894138895138896138897138898138899138900138901138902138903138904138905138906138907138908138909138910138911138912138913138914138915138916138917138918138919138920138921138922138923138924138925138926138927138928138929138930138931138932138933138934138935138936138937138938138939138940138941138942138943138944138945138946138947138948138949138950138951138952138953138954138955138956138957138958138959138960138961138962138963138964138965138966138967138968138969138970138971138972138973138974138975138976138977138978138979138980138981138982138983138984138985138986138987138988138989138990138991138992138993138994138995138996138997138998138999139000139001139002139003139004139005139006139007139008139009139010139011139012139013139014139015139016139017139018139019139020139021139022139023139024139025139026139027139028139029139030139031139032139033139034139035139036139037139038139039139040139041139042139043139044139045139046139047139048139049139050139051139052139053139054139055139056139057139058139059139060139061139062139063139064139065139066139067139068139069139070139071139072139073139074139075139076139077139078139079139080139081139082139083139084139085139086139087139088139089139090139091139092139093139094139095139096139097139098139099139100139101139102139103139104139105139106139107139108139109139110139111139112139113139114139115139116139117139118139119139120139121139122139123139124139125139126139127139128139129139130139131139132139133139134139135139136139137139138139139139140139141139142139143139144139145139146139147139148139149139150139151139152139153139154139155139156139157139158139159139160139161139162139163139164139165139166139167139168139169139170139171139172139173139174139175139176139177139178139179139180139181139182139183139184139185139186139187139188139189139190139191139192139193139194139195139196139197139198139199139200139201139202139203139204139205139206139207139208139209139210139211139212139213139214139215139216139217139218139219139220139221139222139223139224139225139226139227139228139229139230139231139232139233139234139235139236139237139238139239139240139241139242139243139244139245139246139247139248139249139250139251139252139253139254139255139256139257139258139259139260139261139262139263139264139265139266139267139268139269139270139271139272139273139274139275139276139277139278139279139280139281139282139283139284139285139286139287139288139289139290139291139292139293139294139295139296139297139298139299139300139301139302139303139304139305139306139307139308139309139310139311139312139313139314139315139316139317139318139319139320139321139322139323139324139325139326139327139328139329139330139331139332139333139334139335139336139337139338139339139340139341139342139343139344139345139346139347139348139349139350139351139352139353139354139355139356139357139358139359139360139361139362139363139364139365139366139367139368139369139370139371139372139373139374139375139376139377139378139379139380139381139382139383139384139385139386139387139388139389139390139391139392139393139394139395139396139397139398139399139400139401139402139403139404139405139406139407139408139409139410139411139412139413139414139415139416139417139418139419139420139421139422139423139424139425139426139427139428139429139430139431139432139433139434139435139436139437139438139439139440139441139442139443139444139445139446139447139448139449139450139451139452139453139454139455139456139457139458139459139460139461139462139463139464139465139466139467139468139469139470139471139472139473139474139475139476139477139478139479139480139481139482139483139484139485139486139487139488139489139490139491139492139493139494139495139496139497139498139499139500139501139502139503139504139505139506139507139508139509139510139511139512139513139514139515139516139517139518139519139520139521139522139523139524139525139526139527139528139529139530139531139532139533139534139535139536139537139538139539139540139541139542139543139544139545139546139547139548139549139550139551139552139553139554139555139556139557139558139559139560139561139562139563139564139565139566139567139568139569139570139571139572139573139574139575139576139577139578139579139580139581139582139583139584139585139586139587139588139589139590139591139592139593139594139595139596139597139598139599139600139601139602139603139604139605139606139607139608139609139610139611139612139613139614139615139616139617139618139619139620139621139622139623139624139625139626139627139628139629139630139631139632139633139634139635139636139637139638139639139640139641139642139643139644139645139646139647139648139649139650139651139652139653139654139655139656139657139658139659139660139661139662139663139664139665139666139667139668139669139670139671139672139673139674139675139676139677139678139679139680139681139682139683139684139685139686139687139688139689139690139691139692139693139694139695139696139697139698139699139700139701139702139703139704139705139706139707139708139709139710139711139712139713139714139715139716139717139718139719139720139721139722139723139724139725139726139727139728139729139730139731139732139733139734139735139736139737139738139739139740139741139742139743139744139745139746139747139748139749139750139751139752139753139754139755139756139757139758139759139760139761139762139763139764139765139766139767139768139769139770139771139772139773139774139775139776139777139778139779139780139781139782139783139784139785139786139787139788139789139790139791139792139793139794139795139796139797139798139799139800139801139802139803139804139805139806139807139808139809139810139811139812139813139814139815139816139817139818139819139820139821139822139823139824139825139826139827139828139829139830139831139832139833139834139835139836139837139838139839139840139841139842139843139844139845139846139847139848139849139850139851139852139853139854139855139856139857139858139859139860139861139862139863139864139865139866139867139868139869139870139871139872139873139874139875139876139877139878139879139880139881139882139883139884139885139886139887139888139889139890139891139892139893139894139895139896139897139898139899139900139901139902139903139904139905139906139907139908139909139910139911139912139913139914139915139916139917139918139919139920139921139922139923139924139925139926139927139928139929139930139931139932139933139934139935139936139937139938139939139940139941139942139943139944139945139946139947139948139949139950139951139952139953139954139955139956139957139958139959139960139961139962139963139964139965139966139967139968139969139970139971139972139973139974139975139976139977139978139979139980139981139982139983139984139985139986139987139988139989139990139991139992139993139994139995139996139997139998139999140000140001140002140003140004140005140006140007140008140009140010140011140012140013140014140015140016140017140018140019140020140021140022140023140024140025140026140027140028140029140030140031140032140033140034140035140036140037140038140039140040140041140042140043140044140045140046140047140048140049140050140051140052140053140054140055140056140057140058140059140060140061140062140063140064140065140066140067140068140069140070140071140072140073140074140075140076140077140078140079140080140081140082140083140084140085140086140087140088140089140090140091140092140093140094140095140096140097140098140099140100140101140102140103140104140105140106140107140108140109140110140111140112140113140114140115140116140117140118140119140120140121140122140123140124140125140126140127140128140129140130140131140132140133140134140135140136140137140138140139140140140141140142140143140144140145140146140147140148140149140150140151140152140153140154140155140156140157140158140159140160140161140162140163140164140165140166140167140168140169140170140171140172140173140174140175140176140177140178140179140180140181140182140183140184140185140186140187140188140189140190140191140192140193140194140195140196140197140198140199140200140201140202140203140204140205140206140207140208140209140210140211140212140213140214140215140216140217140218140219140220140221140222140223140224140225140226140227140228140229140230140231140232140233140234140235140236140237140238140239140240140241140242140243140244140245140246140247140248140249140250140251140252140253140254140255140256140257140258140259140260140261140262140263140264140265140266140267140268140269140270140271140272140273140274140275140276140277140278140279140280140281140282140283140284140285140286140287140288140289140290140291140292140293140294140295140296140297140298140299140300140301140302140303140304140305140306140307140308140309140310140311140312140313140314140315140316140317140318140319140320140321140322140323140324140325140326140327140328140329140330140331140332140333140334140335140336140337140338140339140340140341140342140343140344140345140346140347140348140349140350140351140352140353140354140355140356140357140358140359140360140361140362140363140364140365140366140367140368140369140370140371140372140373140374140375140376140377140378140379140380140381140382140383140384140385140386140387140388140389140390140391140392140393140394140395140396140397140398140399140400140401140402140403140404140405140406140407140408140409140410140411140412140413140414140415140416140417140418140419140420140421140422140423140424140425140426140427140428140429140430140431140432140433140434140435140436140437140438140439140440140441140442140443140444140445140446140447140448140449140450140451140452140453140454140455140456140457140458140459140460140461140462140463140464140465140466140467140468140469140470140471140472140473140474140475140476140477140478140479140480140481140482140483140484140485140486140487140488140489140490140491140492140493140494140495140496140497140498140499140500140501140502140503140504140505140506140507140508140509140510140511140512140513140514140515140516140517140518140519140520140521140522140523140524140525140526140527140528140529140530140531140532140533140534140535140536140537140538140539140540140541140542140543140544140545140546140547140548140549140550140551140552140553140554140555140556140557140558140559140560140561140562140563140564140565140566140567140568140569140570140571140572140573140574140575140576140577140578140579140580140581140582140583140584140585140586140587140588140589140590140591140592140593140594140595140596140597140598140599140600140601140602140603140604140605140606140607140608140609140610140611140612140613140614140615140616140617140618140619140620140621140622140623140624140625140626140627140628140629140630140631140632140633140634140635140636140637140638140639140640140641140642140643140644140645140646140647140648140649140650140651140652140653140654140655140656140657140658140659140660140661140662140663140664140665140666140667140668140669140670140671140672140673140674140675140676140677140678140679140680140681140682140683140684140685140686140687140688140689140690140691140692140693140694140695140696140697140698140699140700140701140702140703140704140705140706140707140708140709140710140711140712140713140714140715140716140717140718140719140720140721140722140723140724140725140726140727140728140729140730140731140732140733140734140735140736140737140738140739140740140741140742140743140744140745140746140747140748140749140750140751140752140753140754140755140756140757140758140759140760140761140762140763140764140765140766140767140768140769140770140771140772140773140774140775140776140777140778140779140780140781140782140783140784140785140786140787140788140789140790140791140792140793140794140795140796140797140798140799140800140801140802140803140804140805140806140807140808140809140810140811140812140813140814140815140816140817140818140819140820140821140822140823140824140825140826140827140828140829140830140831140832140833140834140835140836140837140838140839140840140841140842140843140844140845140846140847140848140849140850140851140852140853140854140855140856140857140858140859140860140861140862140863140864140865140866140867140868140869140870140871140872140873140874140875140876140877140878140879140880140881140882140883140884140885140886140887140888140889140890140891140892140893140894140895140896140897140898140899140900140901140902140903140904140905140906140907140908140909140910140911140912140913140914140915140916140917140918140919140920140921140922140923140924140925140926140927140928140929140930140931140932140933140934140935140936140937140938140939140940140941140942140943140944140945140946140947140948140949140950140951140952140953140954140955140956140957140958140959140960140961140962140963140964140965140966140967140968140969140970140971140972140973140974140975140976140977140978140979140980140981140982140983140984140985140986140987140988140989140990140991140992140993140994140995140996140997140998140999141000141001141002141003141004141005141006141007141008141009141010141011141012141013141014141015141016141017141018141019141020141021141022141023141024141025141026141027141028141029141030141031141032141033141034141035141036141037141038141039141040141041141042141043141044141045141046141047141048141049141050141051141052141053141054141055141056141057141058141059141060141061141062141063141064141065141066141067141068141069141070141071141072141073141074141075141076141077141078141079141080141081141082141083141084141085141086141087141088141089141090141091141092141093141094141095141096141097141098141099141100141101141102141103141104141105141106141107141108141109141110141111141112141113141114141115141116141117141118141119141120141121141122141123141124141125141126141127141128141129141130141131141132141133141134141135141136141137141138141139141140141141141142141143141144141145141146141147141148141149141150141151141152141153141154141155141156141157141158141159141160141161141162141163141164141165141166141167141168141169141170141171141172141173141174141175141176141177141178141179141180141181141182141183141184141185141186141187141188141189141190141191141192141193141194141195141196141197141198141199141200141201141202141203141204141205141206141207141208141209141210141211141212141213141214141215141216141217141218141219141220141221141222141223141224141225141226141227141228141229141230141231141232141233141234141235141236141237141238141239141240141241141242141243141244141245141246141247141248141249141250141251141252141253141254141255141256141257141258141259141260141261141262141263141264141265141266141267141268141269141270141271141272141273141274141275141276141277141278141279141280141281141282141283141284141285141286141287141288141289141290141291141292141293141294141295141296141297141298141299141300141301141302141303141304141305141306141307141308141309141310141311141312141313141314141315141316141317141318141319141320141321141322141323141324141325141326141327141328141329141330141331141332141333141334141335141336141337141338141339141340141341141342141343141344141345141346141347141348141349141350141351141352141353141354141355141356141357141358141359141360141361141362141363141364141365141366141367141368141369141370141371141372141373141374141375141376141377141378141379141380141381141382141383141384141385141386141387141388141389141390141391141392141393141394141395141396141397141398141399141400141401141402141403141404141405141406141407141408141409141410141411141412141413141414141415141416141417141418141419141420141421141422141423141424141425141426141427141428141429141430141431141432141433141434141435141436141437141438141439141440141441141442141443141444141445141446141447141448141449141450141451141452141453141454141455141456141457141458141459141460141461141462141463141464141465141466141467141468141469141470141471141472141473141474141475141476141477141478141479141480141481141482141483141484141485141486141487141488141489141490141491141492141493141494141495141496141497141498141499141500141501141502141503141504141505141506141507141508141509141510141511141512141513141514141515141516141517141518141519141520141521141522141523141524141525141526141527141528141529141530141531141532141533141534141535141536141537141538141539141540141541141542141543141544141545141546141547141548141549141550141551141552141553141554141555141556141557141558141559141560141561141562141563141564141565141566141567141568141569141570141571141572141573141574141575141576141577141578141579141580141581141582141583141584141585141586141587141588141589141590141591141592141593141594141595141596141597141598141599141600141601141602141603141604141605141606141607141608141609141610141611141612141613141614141615141616141617141618141619141620141621141622141623141624141625141626141627141628141629141630141631141632141633141634141635141636141637141638141639141640141641141642141643141644141645141646141647141648141649141650141651141652141653141654141655141656141657141658141659141660141661141662141663141664141665141666141667141668141669141670141671141672141673141674141675141676141677141678141679141680141681141682141683141684141685141686141687141688141689141690141691141692141693141694141695141696141697141698141699141700141701141702141703141704141705141706141707141708141709141710141711141712141713141714141715141716141717141718141719141720141721141722141723141724141725141726141727141728141729141730141731141732141733141734141735141736141737141738141739141740141741141742141743141744141745141746141747141748141749141750141751141752141753141754141755141756141757141758141759141760141761141762141763141764141765141766141767141768141769141770141771141772141773141774141775141776141777141778141779141780141781141782141783141784141785141786141787141788141789141790141791141792141793141794141795141796141797141798141799141800141801141802141803141804141805141806141807141808141809141810141811141812141813141814141815141816141817141818141819141820141821141822141823141824141825141826141827141828141829141830141831141832141833141834141835141836141837141838141839141840141841141842141843141844141845141846141847141848141849141850141851141852141853141854141855141856141857141858141859141860141861141862141863141864141865141866141867141868141869141870141871141872141873141874141875141876141877141878141879141880141881141882141883141884141885141886141887141888141889141890141891141892141893141894141895141896141897141898141899141900141901141902141903141904141905141906141907141908141909141910141911141912141913141914141915141916141917141918141919141920141921141922141923141924141925141926141927141928141929141930141931141932141933141934141935141936141937141938141939141940141941141942141943141944141945141946141947141948141949141950141951141952141953141954141955141956141957141958141959141960141961141962141963141964141965141966141967141968141969141970141971141972141973141974141975141976141977141978141979141980141981141982141983141984141985141986141987141988141989141990141991141992141993141994141995141996141997141998141999142000142001142002142003142004142005142006142007142008142009142010142011142012142013142014142015142016142017142018142019142020142021142022142023142024142025142026142027142028142029142030142031142032142033142034142035142036142037142038142039142040142041142042142043142044142045142046142047142048142049142050142051142052142053142054142055142056142057142058142059142060142061142062142063142064142065142066142067142068142069142070142071142072142073142074142075142076142077142078142079142080142081142082142083142084142085142086142087142088142089142090142091142092142093142094142095142096142097142098142099142100142101142102142103142104142105142106142107142108142109142110142111142112142113142114142115142116142117142118142119142120142121142122142123142124142125142126142127142128142129142130142131142132142133142134142135142136142137142138142139142140142141142142142143142144142145142146142147142148142149142150142151142152142153142154142155142156142157142158142159142160142161142162142163142164142165142166142167142168142169142170142171142172142173142174142175142176142177142178142179142180142181142182142183142184142185142186142187142188142189142190142191142192142193142194142195142196142197142198142199142200142201142202142203142204142205142206142207142208142209142210142211142212142213142214142215142216142217142218142219142220142221142222142223142224142225142226142227142228142229142230142231142232142233142234142235142236142237142238142239142240142241142242142243142244142245142246142247142248142249142250142251142252142253142254142255142256142257142258142259142260142261142262142263142264142265142266142267142268142269142270142271142272142273142274142275142276142277142278142279142280142281142282142283142284142285142286142287142288142289142290142291142292142293142294142295142296142297142298142299142300142301142302142303142304142305142306142307142308142309142310142311142312142313142314142315142316142317142318142319142320142321142322142323142324142325142326142327142328142329142330142331142332142333142334142335142336142337142338142339142340142341142342142343142344142345142346142347142348142349142350142351142352142353142354142355142356142357142358142359142360142361142362142363142364142365142366142367142368142369142370142371142372142373142374142375142376142377142378142379142380142381142382142383142384142385142386142387142388142389142390142391142392142393142394142395142396142397142398142399142400142401142402142403142404142405142406142407142408142409142410142411142412142413142414142415142416142417142418142419142420142421142422142423142424142425142426142427142428142429142430142431142432142433142434142435142436142437142438142439142440142441142442142443142444142445142446142447142448142449142450142451142452142453142454142455142456142457142458142459142460142461142462142463142464142465142466142467142468142469142470142471142472142473142474142475142476142477142478142479142480142481142482142483142484142485142486142487142488142489142490142491142492142493142494142495142496142497142498142499142500142501142502142503142504142505142506142507142508142509142510142511142512142513142514142515142516142517142518142519142520142521142522142523142524142525142526142527142528142529142530142531142532142533142534142535142536142537142538142539142540142541142542142543142544142545142546142547142548142549142550142551142552142553142554142555142556142557142558142559142560142561142562142563142564142565142566142567142568142569142570142571142572142573142574142575142576142577142578142579142580142581142582142583142584142585142586142587142588142589142590142591142592142593142594142595142596142597142598142599142600142601142602142603142604142605142606142607142608142609142610142611142612142613142614142615142616142617142618142619142620142621142622142623142624142625142626142627142628142629142630142631142632142633142634142635142636142637142638142639142640142641142642142643142644142645142646142647142648142649142650142651142652142653142654142655142656142657142658142659142660142661142662142663142664142665142666142667142668142669142670142671142672142673142674142675142676142677142678142679142680142681142682142683142684142685142686142687142688142689142690142691142692142693142694142695142696142697142698142699142700142701142702142703142704142705142706142707142708142709142710142711142712142713142714142715142716142717142718142719142720142721142722142723142724142725142726142727142728142729142730142731142732142733142734142735142736142737142738142739142740142741142742142743142744142745142746142747142748142749142750142751142752142753142754142755142756142757142758142759142760142761142762142763142764142765142766142767142768142769142770142771142772142773142774142775142776142777142778142779142780142781142782142783142784142785142786142787142788142789142790142791142792142793142794142795142796142797142798142799142800142801142802142803142804142805142806142807142808142809142810142811142812142813142814142815142816142817142818142819142820142821142822142823142824142825142826142827142828142829142830142831142832142833142834142835142836142837142838142839142840142841142842142843142844142845142846142847142848142849142850142851142852142853142854142855142856142857142858142859142860142861142862142863142864142865142866142867142868142869142870142871142872142873142874142875142876142877142878142879142880142881142882142883142884142885142886142887142888142889142890142891142892142893142894142895142896142897142898142899142900142901142902142903142904142905142906142907142908142909142910142911142912142913142914142915142916142917142918142919142920142921142922142923142924142925142926142927142928142929142930142931142932142933142934142935142936142937142938142939142940142941142942142943142944142945142946142947142948142949142950142951142952142953142954142955142956142957142958142959142960142961142962142963142964142965142966142967142968142969142970142971142972142973142974142975142976142977142978142979142980142981142982142983142984142985142986142987142988142989142990142991142992142993142994142995142996142997142998142999143000143001143002143003143004143005143006143007143008143009143010143011143012143013143014143015143016143017143018143019143020143021143022143023143024143025143026143027143028143029143030143031143032143033143034143035143036143037143038143039143040143041143042143043143044143045143046143047143048143049143050143051143052143053143054143055143056143057143058143059143060143061143062143063143064143065143066143067143068143069143070143071143072143073143074143075143076143077143078143079143080143081143082143083143084143085143086143087143088143089143090143091143092143093143094143095143096143097143098143099143100143101143102143103143104143105143106143107143108143109143110143111143112143113143114143115143116143117143118143119143120143121143122143123143124143125143126143127143128143129143130143131143132143133143134143135143136143137143138143139143140143141143142143143143144143145143146143147143148143149143150143151143152143153143154143155143156143157143158143159143160143161143162143163143164143165143166143167143168143169143170143171143172143173143174143175143176143177143178143179143180143181143182143183143184143185143186143187143188143189143190143191143192143193143194143195143196143197143198143199143200143201143202143203143204143205143206143207143208143209143210143211143212143213143214143215143216143217143218143219143220143221143222143223143224143225143226143227143228143229143230143231143232143233143234143235143236143237143238143239143240143241143242143243143244143245143246143247143248143249143250143251143252143253143254143255143256143257143258143259143260143261143262143263143264143265143266143267143268143269143270143271143272143273143274143275143276143277143278143279143280143281143282143283143284143285143286143287143288143289143290143291143292143293143294143295143296143297143298143299143300143301143302143303143304143305143306143307143308143309143310143311143312143313143314143315143316143317143318143319143320143321143322143323143324143325143326143327143328143329143330143331143332143333143334143335143336143337143338143339143340143341143342143343143344143345143346143347143348143349143350143351143352143353143354143355143356143357143358143359143360143361143362143363143364143365143366143367143368143369143370143371143372143373143374143375143376143377143378143379143380143381143382143383143384143385143386143387143388143389143390143391143392143393143394143395143396143397143398143399143400143401143402143403143404143405143406143407143408143409143410143411143412143413143414143415143416143417143418143419143420143421143422143423143424143425143426143427143428143429143430143431143432143433143434143435143436143437143438143439143440143441143442143443143444143445143446143447143448143449143450143451143452143453143454143455143456143457143458143459143460143461143462143463143464143465143466143467143468143469143470143471143472143473143474143475143476143477143478143479143480143481143482143483143484143485143486143487143488143489143490143491143492143493143494143495143496143497143498143499143500143501143502143503143504143505143506143507143508143509143510143511143512143513143514143515143516143517143518143519143520143521143522143523143524143525143526143527143528143529143530143531143532143533143534143535143536143537143538143539143540143541143542143543143544143545143546143547143548143549143550143551143552143553143554143555143556143557143558143559143560143561143562143563143564143565143566143567143568143569143570143571143572143573143574143575143576143577143578143579143580143581143582143583143584143585143586143587143588143589143590143591143592143593143594143595143596143597143598143599143600143601143602143603143604143605143606143607143608143609143610143611143612143613143614143615143616143617143618143619143620143621143622143623143624143625143626143627143628143629143630143631143632143633143634143635143636143637143638143639143640143641143642143643143644143645143646143647143648143649143650143651143652143653143654143655143656143657143658143659143660143661143662143663143664143665143666143667143668143669143670143671143672143673143674143675143676143677143678143679143680143681143682143683143684143685143686143687143688143689143690143691143692143693143694143695143696143697143698143699143700143701143702143703143704143705143706143707143708143709143710143711143712143713143714143715143716143717143718143719143720143721143722143723143724143725143726143727143728143729143730143731143732143733143734143735143736143737143738143739143740143741143742143743143744143745143746143747143748143749143750143751143752143753143754143755143756143757143758143759143760143761143762143763143764143765143766143767143768143769143770143771143772143773143774143775143776143777143778143779143780143781143782143783143784143785143786143787143788143789143790143791143792143793143794143795143796143797143798143799143800143801143802143803143804143805143806143807143808143809143810143811143812143813143814143815143816143817143818143819143820143821143822143823143824143825143826143827143828143829143830143831143832143833143834143835143836143837143838143839143840143841143842143843143844143845143846143847143848143849143850143851143852143853143854143855143856143857143858143859143860143861143862143863143864143865143866143867143868143869143870143871143872143873143874143875143876143877143878143879143880143881143882143883143884143885143886143887143888143889143890143891143892143893143894143895143896143897143898143899143900143901143902143903143904143905143906143907143908143909143910143911143912143913143914143915143916143917143918143919143920143921143922143923143924143925143926143927143928143929143930143931143932143933143934143935143936143937143938143939143940143941143942143943143944143945143946143947143948143949143950143951143952143953143954143955143956143957143958143959143960143961143962143963143964143965143966143967143968143969143970143971143972143973143974143975143976143977143978143979143980143981143982143983143984143985143986143987143988143989143990143991143992143993143994143995143996143997143998143999144000144001144002144003144004144005144006144007144008144009144010144011144012144013144014144015144016144017144018144019144020144021144022144023144024144025144026144027144028144029144030144031144032144033144034144035144036144037144038144039144040144041144042144043144044144045144046144047144048144049144050144051144052144053144054144055144056144057144058144059144060144061144062144063144064144065144066144067144068144069144070144071144072144073144074144075144076144077144078144079144080144081144082144083144084144085144086144087144088144089144090144091144092144093144094144095144096144097144098144099144100144101144102144103144104144105144106144107144108144109144110144111144112144113144114144115144116144117144118144119144120144121144122144123144124144125144126144127144128144129144130144131144132144133144134144135144136144137144138144139144140144141144142144143144144144145144146144147144148144149144150144151144152144153144154144155144156144157144158144159144160144161144162144163144164144165144166144167144168144169144170144171144172144173144174144175144176144177144178144179144180144181144182144183144184144185144186144187144188144189144190144191144192144193144194144195144196144197144198144199144200144201144202144203144204144205144206144207144208144209144210144211144212144213144214144215144216144217144218144219144220144221144222144223144224144225144226144227144228144229144230144231144232144233144234144235144236144237144238144239144240144241144242144243144244144245144246144247144248144249144250144251144252144253144254144255144256144257144258144259144260144261144262144263144264144265144266144267144268144269144270144271144272144273144274144275144276144277144278144279144280144281144282144283144284144285144286144287144288144289144290144291144292144293144294144295144296144297144298144299144300144301144302144303144304144305144306144307144308144309144310144311144312144313144314144315144316144317144318144319144320144321144322144323144324144325144326144327144328144329144330144331144332144333144334144335144336144337144338144339144340144341144342144343144344144345144346144347144348144349144350144351144352144353144354144355144356144357144358144359144360144361144362144363144364144365144366144367144368144369144370144371144372144373144374144375144376144377144378144379144380144381144382144383144384144385144386144387144388144389144390144391144392144393144394144395144396144397144398144399144400144401144402144403144404144405144406144407144408144409144410144411144412144413144414144415144416144417144418144419144420144421144422144423144424144425144426144427144428144429144430144431144432144433144434144435144436144437144438144439144440144441144442144443144444144445144446144447144448144449144450144451144452144453144454144455144456144457144458144459144460144461144462144463144464144465144466144467144468144469144470144471144472144473144474144475144476144477144478144479144480144481144482144483144484144485144486144487144488144489144490144491144492144493144494144495144496144497144498144499144500144501144502144503144504144505144506144507144508144509144510144511144512144513144514144515144516144517144518144519144520144521144522144523144524144525144526144527144528144529144530144531144532144533144534144535144536144537144538144539144540144541144542144543144544144545144546144547144548144549144550144551144552144553144554144555144556144557144558144559144560144561144562144563144564144565144566144567144568144569144570144571144572144573144574144575144576144577144578144579144580144581144582144583144584144585144586144587144588144589144590144591144592144593144594144595144596144597144598144599144600144601144602144603144604144605144606144607144608144609144610144611144612144613144614144615144616144617144618144619144620144621144622144623144624144625144626144627144628144629144630144631144632144633144634144635144636144637144638144639144640144641144642144643144644144645144646144647144648144649144650144651144652144653144654144655144656144657144658144659144660144661144662144663144664144665144666144667144668144669144670144671144672144673144674144675144676144677144678144679144680144681144682144683144684144685144686144687144688144689144690144691144692144693144694144695144696144697144698144699144700144701144702144703144704144705144706144707144708144709144710144711144712144713144714144715144716144717144718144719144720144721144722144723144724144725144726144727144728144729144730144731144732144733144734144735144736144737144738144739144740144741144742144743144744144745144746144747144748144749144750144751144752144753144754144755144756144757144758144759144760144761144762144763144764144765144766144767144768144769144770144771144772144773144774144775144776144777144778144779144780144781144782144783144784144785144786144787144788144789144790144791144792144793144794144795144796144797144798144799144800144801144802144803144804144805144806144807144808144809144810144811144812144813144814144815144816144817144818144819144820144821144822144823144824144825144826144827144828144829144830144831144832144833144834144835144836144837144838144839144840144841144842144843144844144845144846144847144848144849144850144851144852144853144854144855144856144857144858144859144860144861144862144863144864144865144866144867144868144869144870144871144872144873144874144875144876144877144878144879144880144881144882144883144884144885144886144887144888144889144890144891144892144893144894144895144896144897144898144899144900144901144902144903144904144905144906144907144908144909144910144911144912144913144914144915144916144917144918144919144920144921144922144923144924144925144926144927144928144929144930144931144932144933144934144935144936144937144938144939144940144941144942144943144944144945144946144947144948144949144950144951144952144953144954144955144956144957144958144959144960144961144962144963144964144965144966144967144968144969144970144971144972144973144974144975144976144977144978144979144980144981144982144983144984144985144986144987144988144989144990144991144992144993144994144995144996144997144998144999145000145001145002145003145004145005145006145007145008145009145010145011145012145013145014145015145016145017145018145019145020145021145022145023145024145025145026145027145028145029145030145031145032145033145034145035145036145037145038145039145040145041145042145043145044145045145046145047145048145049145050145051145052145053145054145055145056145057145058145059145060145061145062145063145064145065145066145067145068145069145070145071145072145073145074145075145076145077145078145079145080145081145082145083145084145085145086145087145088145089145090145091145092145093145094145095145096145097145098145099145100145101145102145103145104145105145106145107145108145109145110145111145112145113145114145115145116145117145118145119145120145121145122145123145124145125145126145127145128145129145130145131145132145133145134145135145136145137145138145139145140145141145142145143145144145145145146145147145148145149145150145151145152145153145154145155145156145157145158145159145160145161145162145163145164145165145166145167145168145169145170145171145172145173145174145175145176145177145178145179145180145181145182145183145184145185145186145187145188145189145190145191145192145193145194145195145196145197145198145199145200145201145202145203145204145205145206145207145208145209145210145211145212145213145214145215145216145217145218145219145220145221145222145223145224145225145226145227145228145229145230145231145232145233145234145235145236145237145238145239145240145241145242145243145244145245145246145247145248145249145250145251145252145253145254145255145256145257145258145259145260145261145262145263145264145265145266145267145268145269145270145271145272145273145274145275145276145277145278145279145280145281145282145283145284145285145286145287145288145289145290145291145292145293145294145295145296145297145298145299145300145301145302145303145304145305145306145307145308145309145310145311145312145313145314145315145316145317145318145319145320145321145322145323145324145325145326145327145328145329145330145331145332145333145334145335145336145337145338145339145340145341145342145343145344145345145346145347145348145349145350145351145352145353145354145355145356145357145358145359145360145361145362145363145364145365145366145367145368145369145370145371145372145373145374145375145376145377145378145379145380145381145382145383145384145385145386145387145388145389145390145391145392145393145394145395145396145397145398145399145400145401145402145403145404145405145406145407145408145409145410145411145412145413145414145415145416145417145418145419145420145421145422145423145424145425145426145427145428145429145430145431145432145433145434145435145436145437145438145439145440145441145442145443145444145445145446145447145448145449145450145451145452145453145454145455145456145457145458145459145460145461145462145463145464145465145466145467145468145469145470145471145472145473145474145475145476145477145478145479145480145481145482145483145484145485145486145487145488145489145490145491145492145493145494145495145496145497145498145499145500145501145502145503145504145505145506145507145508145509145510145511145512145513145514145515145516145517145518145519145520145521145522145523145524145525145526145527145528145529145530145531145532145533145534145535145536145537145538145539145540145541145542145543145544145545145546145547145548145549145550145551145552145553145554145555145556145557145558145559145560145561145562145563145564145565145566145567145568145569145570145571145572145573145574145575145576145577145578145579145580145581145582145583145584145585145586145587145588145589145590145591145592145593145594145595145596145597145598145599145600145601145602145603145604145605145606145607145608145609145610145611145612145613145614145615145616145617145618145619145620145621145622145623145624145625145626145627145628145629145630145631145632145633145634145635145636145637145638145639145640145641145642145643145644145645145646145647145648145649145650145651145652145653145654145655145656145657145658145659145660145661145662145663145664145665145666145667145668145669145670145671145672145673145674145675145676145677145678145679145680145681145682145683145684145685145686145687145688145689145690145691145692145693145694145695145696145697145698145699145700145701145702145703145704145705145706145707145708145709145710145711145712145713145714145715145716145717145718145719145720145721145722145723145724145725145726145727145728145729145730145731145732145733145734145735145736145737145738145739145740145741145742145743145744145745145746145747145748145749145750145751145752145753145754145755145756145757145758145759145760145761145762145763145764145765145766145767145768145769145770145771145772145773145774145775145776145777145778145779145780145781145782145783145784145785145786145787145788145789145790145791145792145793145794145795145796145797145798145799145800145801145802145803145804145805145806145807145808145809145810145811145812145813145814145815145816145817145818145819145820145821145822145823145824145825145826145827145828145829145830145831145832145833145834145835145836145837145838145839145840145841145842145843145844145845145846145847145848145849145850145851145852145853145854145855145856145857145858145859145860145861145862145863145864145865145866145867145868145869145870145871145872145873145874145875145876145877145878145879145880145881145882145883145884145885145886145887145888145889145890145891145892145893145894145895145896145897145898145899145900145901145902145903145904145905145906145907145908145909145910145911145912145913145914145915145916145917145918145919145920145921145922145923145924145925145926145927145928145929145930145931145932145933145934145935145936145937145938145939145940145941145942145943145944145945145946145947145948145949145950145951145952145953145954145955145956145957145958145959145960145961145962145963145964145965145966145967145968145969145970145971145972145973145974145975145976145977145978145979145980145981145982145983145984145985145986145987145988145989145990145991145992145993145994145995145996145997145998145999146000146001146002146003146004146005146006146007146008146009146010146011146012146013146014146015146016146017146018146019146020146021146022146023146024146025146026146027146028146029146030146031146032146033146034146035146036146037146038146039146040146041146042146043146044146045146046146047146048146049146050146051146052146053146054146055146056146057146058146059146060146061146062146063146064146065146066146067146068146069146070146071146072146073146074146075146076146077146078146079146080146081146082146083146084146085146086146087146088146089146090146091146092146093146094146095146096146097146098146099146100146101146102146103146104146105146106146107146108146109146110146111146112146113146114146115146116146117146118146119146120146121146122146123146124146125146126146127146128146129146130146131146132146133146134146135146136146137146138146139146140146141146142146143146144146145146146146147146148146149146150146151146152146153146154146155146156146157146158146159146160146161146162146163146164146165146166146167146168146169146170146171146172146173146174146175146176146177146178146179146180146181146182146183146184146185146186146187146188146189146190146191146192146193146194146195146196146197146198146199146200146201146202146203146204146205146206146207146208146209146210146211146212146213146214146215146216146217146218146219146220146221146222146223146224146225146226146227146228146229146230146231146232146233146234146235146236146237146238146239146240146241146242146243146244146245146246146247146248146249146250146251146252146253146254146255146256146257146258146259146260146261146262146263146264146265146266146267146268146269146270146271146272146273146274146275146276146277146278146279146280146281146282146283146284146285146286146287146288146289146290146291146292146293146294146295146296146297146298146299146300146301146302146303146304146305146306146307146308146309146310146311146312146313146314146315146316146317146318146319146320146321146322146323146324146325146326146327146328146329146330146331146332146333146334146335146336146337146338146339146340146341146342146343146344146345146346146347146348146349146350146351146352146353146354146355146356146357146358146359146360146361146362146363146364146365146366146367146368146369146370146371146372146373146374146375146376146377146378146379146380146381146382146383146384146385146386146387146388146389146390146391146392146393146394146395146396146397146398146399146400146401146402146403146404146405146406146407146408146409146410146411146412146413146414146415146416146417146418146419146420146421146422146423146424146425146426146427146428146429146430146431146432146433146434146435146436146437146438146439146440146441146442146443146444146445146446146447146448146449146450146451146452146453146454146455146456146457146458146459146460146461146462146463146464146465146466146467146468146469146470146471146472146473146474146475146476146477146478146479146480146481146482146483146484146485146486146487146488146489146490146491146492146493146494146495146496146497146498146499146500146501146502146503146504146505146506146507146508146509146510146511146512146513146514146515146516146517146518146519146520146521146522146523146524146525146526146527146528146529146530146531146532146533146534146535146536146537146538146539146540146541146542146543146544146545146546146547146548146549146550146551146552146553146554146555146556146557146558146559146560146561146562146563146564146565146566146567146568146569146570146571146572146573146574146575146576146577146578146579146580146581146582146583146584146585146586146587146588146589146590146591146592146593146594146595146596146597146598146599146600146601146602146603146604146605146606146607146608146609146610146611146612146613146614146615146616146617146618146619146620146621146622146623146624146625146626146627146628146629146630146631146632146633146634146635146636146637146638146639146640146641146642146643146644146645146646146647146648146649146650146651146652146653146654146655146656146657146658146659146660146661146662146663146664146665146666146667146668146669146670146671146672146673146674146675146676146677146678146679146680146681146682146683146684146685146686146687146688146689146690146691146692146693146694146695146696146697146698146699146700146701146702146703146704146705146706146707146708146709146710146711146712146713146714146715146716146717146718146719146720146721146722146723146724146725146726146727146728146729146730146731146732146733146734146735146736146737146738146739146740146741146742146743146744146745146746146747146748146749146750146751146752146753146754146755146756146757146758146759146760146761146762146763146764146765146766146767146768146769146770146771146772146773146774146775146776146777146778146779146780146781146782146783146784146785146786146787146788146789146790146791146792146793146794146795146796146797146798146799146800146801146802146803146804146805146806146807146808146809146810146811146812146813146814146815146816146817146818146819146820146821146822146823146824146825146826146827146828146829146830146831146832146833146834146835146836146837146838146839146840146841146842146843146844146845146846146847146848146849146850146851146852146853146854146855146856146857146858146859146860146861146862146863146864146865146866146867146868146869146870146871146872146873146874146875146876146877146878146879146880146881146882146883146884146885146886146887146888146889146890146891146892146893146894146895146896146897146898146899146900146901146902146903146904146905146906146907146908146909146910146911146912146913146914146915146916146917146918146919146920146921146922146923146924146925146926146927146928146929146930146931146932146933146934146935146936146937146938146939146940146941146942146943146944146945146946146947146948146949146950146951146952146953146954146955146956146957146958146959146960146961146962146963146964146965146966146967146968146969146970146971146972146973146974146975146976146977146978146979146980146981146982146983146984146985146986146987146988146989146990146991146992146993146994146995146996146997146998146999147000147001147002147003147004147005147006147007147008147009147010147011147012147013147014147015147016147017147018147019147020147021147022147023147024147025147026147027147028147029147030147031147032147033147034147035147036147037147038147039147040147041147042147043147044147045147046147047147048147049147050147051147052147053147054147055147056147057147058147059147060147061147062147063147064147065147066147067147068147069147070147071147072147073147074147075147076147077147078147079147080147081147082147083147084147085147086147087147088147089147090147091147092147093147094147095147096147097147098147099147100147101147102147103147104147105147106147107147108147109147110147111147112147113147114147115147116147117147118147119147120147121147122147123147124147125147126147127147128147129147130147131147132147133147134147135147136147137147138147139147140147141147142147143147144147145147146147147147148147149147150147151147152147153147154147155147156147157147158147159147160147161147162147163147164147165147166147167147168147169147170147171147172147173147174147175147176147177147178147179147180147181147182147183147184147185147186147187147188147189147190147191147192147193147194147195147196147197147198147199147200147201147202147203147204147205147206147207147208147209147210147211147212147213147214147215147216147217147218147219147220147221147222147223147224147225147226147227147228147229147230147231147232147233147234147235147236147237147238147239147240147241147242147243147244147245147246147247147248147249147250147251147252147253147254147255147256147257147258147259147260147261147262147263147264147265147266147267147268147269147270147271147272147273147274147275147276147277147278147279147280147281147282147283147284147285147286147287147288147289147290147291147292147293147294147295147296147297147298147299147300147301147302147303147304147305147306147307147308147309147310147311147312147313147314147315147316147317147318147319147320147321147322147323147324147325147326147327147328147329147330147331147332147333147334147335147336147337147338147339147340147341147342147343147344147345147346147347147348147349147350147351147352147353147354147355147356147357147358147359147360147361147362147363147364147365147366147367147368147369147370147371147372147373147374147375147376147377147378147379147380147381147382147383147384147385147386147387147388147389147390147391147392147393147394147395147396147397147398147399147400147401147402147403147404147405147406147407147408147409147410147411147412147413147414147415147416147417147418147419147420147421147422147423147424147425147426147427147428147429147430147431147432147433147434147435147436147437147438147439147440147441147442147443147444147445147446147447147448147449147450147451147452147453147454147455147456147457147458147459147460147461147462147463147464147465147466147467147468147469147470147471147472147473147474147475147476147477147478147479147480147481147482147483147484147485147486147487147488147489147490147491147492147493147494147495147496147497147498147499147500147501147502147503147504147505147506147507147508147509147510147511147512147513147514147515147516147517147518147519147520147521147522147523147524147525147526147527147528147529147530147531147532147533147534147535147536147537147538147539147540147541147542147543147544147545147546147547147548147549147550147551147552147553147554147555147556147557147558147559147560147561147562147563147564147565147566147567147568147569147570147571147572147573147574147575147576147577147578147579147580147581147582147583147584147585147586147587147588147589147590147591147592147593147594147595147596147597147598147599147600147601147602147603147604147605147606147607147608147609147610147611147612147613147614147615147616147617147618147619147620147621147622147623147624147625147626147627147628147629147630147631147632147633147634147635147636147637147638147639147640147641147642147643147644147645147646147647147648147649147650147651147652147653147654147655147656147657147658147659147660147661147662147663147664147665147666147667147668147669147670147671147672147673147674147675147676147677147678147679147680147681147682147683147684147685147686147687147688147689147690147691147692147693147694147695147696147697147698147699147700147701147702147703147704147705147706147707147708147709147710147711147712147713147714147715147716147717147718147719147720147721147722147723147724147725147726147727147728147729147730147731147732147733147734147735147736147737147738147739147740147741147742147743147744147745147746147747147748147749147750147751147752147753147754147755147756147757147758147759147760147761147762147763147764147765147766147767147768147769147770147771147772147773147774147775147776147777147778147779147780147781147782147783147784147785147786147787147788147789147790147791147792147793147794147795147796147797147798147799147800147801147802147803147804147805147806147807147808147809147810147811147812147813147814147815147816147817147818147819147820147821147822147823147824147825147826147827147828147829147830147831147832147833147834147835147836147837147838147839147840147841147842147843147844147845147846147847147848147849147850147851147852147853147854147855147856147857147858147859147860147861147862147863147864147865147866147867147868147869147870147871147872147873147874147875147876147877147878147879147880147881147882147883147884147885147886147887147888147889147890147891147892147893147894147895147896147897147898147899147900147901147902147903147904147905147906147907147908147909147910147911147912147913147914147915147916147917147918147919147920147921147922147923147924147925147926147927147928147929147930147931147932147933147934147935147936147937147938147939147940147941147942147943147944147945147946147947147948147949147950147951147952147953147954147955147956147957147958147959147960147961147962147963147964147965147966147967147968147969147970147971147972147973147974147975147976147977147978147979147980147981147982147983147984147985147986147987147988147989147990147991147992147993147994147995147996147997147998147999148000148001148002148003148004148005148006148007148008148009148010148011148012148013148014148015148016148017148018148019148020148021148022148023148024148025148026148027148028148029148030148031148032148033148034148035148036148037148038148039148040148041148042148043148044148045148046148047148048148049148050148051148052148053148054148055148056148057148058148059148060148061148062148063148064148065148066148067148068148069148070148071148072148073148074148075148076148077148078148079148080148081148082148083148084148085148086148087148088148089148090148091148092148093148094148095148096148097148098148099148100148101148102148103148104148105148106148107148108148109148110148111148112148113148114148115148116148117148118148119148120148121148122148123148124148125148126148127148128148129148130148131148132148133148134148135148136148137148138148139148140148141148142148143148144148145148146148147148148148149148150148151148152148153148154148155148156148157148158148159148160148161148162148163148164148165148166148167148168148169148170148171148172148173148174148175148176148177148178148179148180148181148182148183148184148185148186148187148188148189148190148191148192148193148194148195148196148197148198148199148200148201148202148203148204148205148206148207148208148209148210148211148212148213148214148215148216148217148218148219148220148221148222148223148224148225148226148227148228148229148230148231148232148233148234148235148236148237148238148239148240148241148242148243148244148245148246148247148248148249148250148251148252148253148254148255148256148257148258148259148260148261148262148263148264148265148266148267148268148269148270148271148272148273148274148275148276148277148278148279148280148281148282148283148284148285148286148287148288148289148290148291148292148293148294148295148296148297148298148299148300148301148302148303148304148305148306148307148308148309148310148311148312148313148314148315148316148317148318148319148320148321148322148323148324148325148326148327148328148329148330148331148332148333148334148335148336148337148338148339148340148341148342148343148344148345148346148347148348148349148350148351148352148353148354148355148356148357148358148359148360148361148362148363148364148365148366148367148368148369148370148371148372148373148374148375148376148377148378148379148380148381148382148383148384148385148386148387148388148389148390148391148392148393148394148395148396148397148398148399148400148401148402148403148404148405148406148407148408148409148410148411148412148413148414148415148416148417148418148419148420148421148422148423148424148425148426148427148428148429148430148431148432148433148434148435148436148437148438148439148440148441148442148443148444148445148446148447148448148449148450148451148452148453148454148455148456148457148458148459148460148461148462148463148464148465148466148467148468148469148470148471148472148473148474148475148476148477148478148479148480148481148482148483148484148485148486148487148488148489148490148491148492148493148494148495148496148497148498148499148500148501148502148503148504148505148506148507148508148509148510148511148512148513148514148515148516148517148518148519148520148521148522148523148524148525148526148527148528148529148530148531148532148533148534148535148536148537148538148539148540148541148542148543148544148545148546148547148548148549148550148551148552148553148554148555148556148557148558148559148560148561148562148563148564148565148566148567148568148569148570148571148572148573148574148575148576148577148578148579148580148581148582148583148584148585148586148587148588148589148590148591148592148593148594148595148596148597148598148599148600148601148602148603148604148605148606148607148608148609148610148611148612148613148614148615148616148617148618148619148620148621148622148623148624148625148626148627148628148629148630148631148632148633148634148635148636148637148638148639148640148641148642148643148644148645148646148647148648148649148650148651148652148653148654148655148656148657148658148659148660148661148662148663148664148665148666148667148668148669148670148671148672148673148674148675148676148677148678148679148680148681148682148683148684148685148686148687148688148689148690148691148692148693148694148695148696148697148698148699148700148701148702148703148704148705148706148707148708148709148710148711148712148713148714148715148716148717148718148719148720148721148722148723148724148725148726148727148728148729148730148731148732148733148734148735148736148737148738148739148740148741148742148743148744148745148746148747148748148749148750148751148752148753148754148755148756148757148758148759148760148761148762148763148764148765148766148767148768148769148770148771148772148773148774148775148776148777148778148779148780148781148782148783148784148785148786148787148788148789148790148791148792148793148794148795148796148797148798148799148800148801148802148803148804148805148806148807148808148809148810148811148812148813148814148815148816148817148818148819148820148821148822148823148824148825148826148827148828148829148830148831148832148833148834148835148836148837148838148839148840148841148842148843148844148845148846148847148848148849148850148851148852148853148854148855148856148857148858148859148860148861148862148863148864148865148866148867148868148869148870148871148872148873148874148875148876148877148878148879148880148881148882148883148884148885148886148887148888148889148890148891148892148893148894148895148896148897148898148899148900148901148902148903148904148905148906148907148908148909148910148911148912148913148914148915148916148917148918148919148920148921148922148923148924148925148926148927148928148929148930148931148932148933148934148935148936148937148938148939148940148941148942148943148944148945148946148947148948148949148950148951148952148953148954148955148956148957148958148959148960148961148962148963148964148965148966148967148968148969148970148971148972148973148974148975148976148977148978148979148980148981148982148983148984148985148986148987148988148989148990148991148992148993148994148995148996148997148998148999149000149001149002149003149004149005149006149007149008149009149010149011149012149013149014149015149016149017149018149019149020149021149022149023149024149025149026149027149028149029149030149031149032149033149034149035149036149037149038149039149040149041149042149043149044149045149046149047149048149049149050149051149052149053149054149055149056149057149058149059149060149061149062149063149064149065149066149067149068149069149070149071149072149073149074149075149076149077149078149079149080149081149082149083149084149085149086149087149088149089149090149091149092149093149094149095149096149097149098149099149100149101149102149103149104149105149106149107149108149109149110149111149112149113149114149115149116149117149118149119149120149121149122149123149124149125149126149127149128149129149130149131149132149133149134149135149136149137149138149139149140149141149142149143149144149145149146149147149148149149149150149151149152149153149154149155149156149157149158149159149160149161149162149163149164149165149166149167149168149169149170149171149172149173149174149175149176149177149178149179149180149181149182149183149184149185149186149187149188149189149190149191149192149193149194149195149196149197149198149199149200149201149202149203149204149205149206149207149208149209149210149211149212149213149214149215149216149217149218149219149220149221149222149223149224149225149226149227149228149229149230149231149232149233149234149235149236149237149238149239149240149241149242149243149244149245149246149247149248149249149250149251149252149253149254149255149256149257149258149259149260149261149262149263149264149265149266149267149268149269149270149271149272149273149274149275149276149277149278149279149280149281149282149283149284149285149286149287149288149289149290149291149292149293149294149295149296149297149298149299149300149301149302149303149304149305149306149307149308149309149310149311149312149313149314149315149316149317149318149319149320149321149322149323149324149325149326149327149328149329149330149331149332149333149334149335149336149337149338149339149340149341149342149343149344149345149346149347149348149349149350149351149352149353149354149355149356149357149358149359149360149361149362149363149364149365149366149367149368149369149370149371149372149373149374149375149376149377149378149379149380149381149382149383149384149385149386149387149388149389149390149391149392149393149394149395149396149397149398149399149400149401149402149403149404149405149406149407149408149409149410149411149412149413149414149415149416149417149418149419149420149421149422149423149424149425149426149427149428149429149430149431149432149433149434149435149436149437149438149439149440149441149442149443149444149445149446149447149448149449149450149451149452149453149454149455149456149457149458149459149460149461149462149463149464149465149466149467149468149469149470149471149472149473149474149475149476149477149478149479149480149481149482149483149484149485149486149487149488149489149490149491149492149493149494149495149496149497149498149499149500149501149502149503149504149505149506149507149508149509149510149511149512149513149514149515149516149517149518149519149520149521149522149523149524149525149526149527149528149529149530149531149532149533149534149535149536149537149538149539149540149541149542149543149544149545149546149547149548149549149550149551149552149553149554149555149556149557149558149559149560149561149562149563149564149565149566149567149568149569149570149571149572149573149574149575149576149577149578149579149580149581149582149583149584149585149586149587149588149589149590149591149592149593149594149595149596149597149598149599149600149601149602149603149604149605149606149607149608149609149610149611149612149613149614149615149616149617149618149619149620149621149622149623149624149625149626149627149628149629149630149631149632149633149634149635149636149637149638149639149640149641149642149643149644149645149646149647149648149649149650149651149652149653149654149655149656149657149658149659149660149661149662149663149664149665149666149667149668149669149670149671149672149673149674149675149676149677149678149679149680149681149682149683149684149685149686149687149688149689149690149691149692149693149694149695149696149697149698149699149700149701149702149703149704149705149706149707149708149709149710149711149712149713149714149715149716149717149718149719149720149721149722149723149724149725149726149727149728149729149730149731149732149733149734149735149736149737149738149739149740149741149742149743149744149745149746149747149748149749149750149751149752149753149754149755149756149757149758149759149760149761149762149763149764149765149766149767149768149769149770149771149772149773149774149775149776149777149778149779149780149781149782149783149784149785149786149787149788149789149790149791149792149793149794149795149796149797149798149799149800149801149802149803149804149805149806149807149808149809149810149811149812149813149814149815149816149817149818149819149820149821149822149823149824149825149826149827149828149829149830149831149832149833149834149835149836149837149838149839149840149841149842149843149844149845149846149847149848149849149850149851149852149853149854149855149856149857149858149859149860149861149862149863149864149865149866149867149868149869149870149871149872149873149874149875149876149877149878149879149880149881149882149883149884149885149886149887149888149889149890149891149892149893149894149895149896149897149898149899149900149901149902149903149904149905149906149907149908149909149910149911149912149913149914149915149916149917149918149919149920149921149922149923149924149925149926149927149928149929149930149931149932149933149934149935149936149937149938149939149940149941149942149943149944149945149946149947149948149949149950149951149952149953149954149955149956149957149958149959149960149961149962149963149964149965149966149967149968149969149970149971149972149973149974149975149976149977149978149979149980149981149982149983149984149985149986149987149988149989149990149991149992149993149994149995149996149997149998149999150000150001150002150003150004150005150006150007150008150009150010150011150012150013150014150015150016150017150018150019150020150021150022150023150024150025150026150027150028150029150030150031150032150033150034150035150036150037150038150039150040150041150042150043150044150045150046150047150048150049150050150051150052150053150054150055150056150057150058150059150060150061150062150063150064150065150066150067150068150069150070150071150072150073150074150075150076150077150078150079150080150081150082150083150084150085150086150087150088150089150090150091150092150093150094150095150096150097150098150099150100150101150102150103150104150105150106150107150108150109150110150111150112150113150114150115150116150117150118150119150120150121150122150123150124150125150126150127150128150129150130150131150132150133150134150135150136150137150138150139150140150141150142150143150144150145150146150147150148150149150150150151150152150153150154150155150156150157150158150159150160150161150162150163150164150165150166150167150168150169150170150171150172150173150174150175150176150177150178150179150180150181150182150183150184150185150186150187150188150189150190150191150192150193150194150195150196150197150198150199150200150201150202150203150204150205150206150207150208150209150210150211150212150213150214150215150216150217150218150219150220150221150222150223150224150225150226150227150228150229150230150231150232150233150234150235150236150237150238150239150240150241150242150243150244150245150246150247150248150249150250150251150252150253150254150255150256150257150258150259150260150261150262150263150264150265150266150267150268150269150270150271150272150273150274150275150276150277150278150279150280150281150282150283150284150285150286150287150288150289150290150291150292150293150294150295150296150297150298150299150300150301150302150303150304150305150306150307150308150309150310150311150312150313150314150315150316150317150318150319150320150321150322150323150324150325150326150327150328150329150330150331150332150333150334150335150336150337150338150339150340150341150342150343150344150345150346150347150348150349150350150351150352150353150354150355150356150357150358150359150360150361150362150363150364150365150366150367150368150369150370150371150372150373150374150375150376150377150378150379150380150381150382150383150384150385150386150387150388150389150390150391150392150393150394150395150396150397150398150399150400150401150402150403150404150405150406150407150408150409150410150411150412150413150414150415150416150417150418150419150420150421150422150423150424150425150426150427150428150429150430150431150432150433150434150435150436150437150438150439150440150441150442150443150444150445150446150447150448150449150450150451150452150453150454150455150456150457150458150459150460150461150462150463150464150465150466150467150468150469150470150471150472150473150474150475150476150477150478150479150480150481150482150483150484150485150486150487150488150489150490150491150492150493150494150495150496150497150498150499150500150501150502150503150504150505150506150507150508150509150510150511150512150513150514150515150516150517150518150519150520150521150522150523150524150525150526150527150528150529150530150531150532150533150534150535150536150537150538150539150540150541150542150543150544150545150546150547150548150549150550150551150552150553150554150555150556150557150558150559150560150561150562150563150564150565150566150567150568150569150570150571150572150573150574150575150576150577150578150579150580150581150582150583150584150585150586150587150588150589150590150591150592150593150594150595150596150597150598150599150600150601150602150603150604150605150606150607150608150609150610150611150612150613150614150615150616150617150618150619150620150621150622150623150624150625150626150627150628150629150630150631150632150633150634150635150636150637150638150639150640150641150642150643150644150645150646150647150648150649150650150651150652150653150654150655150656150657150658150659150660150661150662150663150664150665150666150667150668150669150670150671150672150673150674150675150676150677150678150679150680150681150682150683150684150685150686150687150688150689150690150691150692150693150694150695150696150697150698150699150700150701150702150703150704150705150706150707150708150709150710150711150712150713150714150715150716150717150718150719150720150721150722150723150724150725150726150727150728150729150730150731150732150733150734150735150736150737150738150739150740150741150742150743150744150745150746150747150748150749150750150751150752150753150754150755150756150757150758150759150760150761150762150763150764150765150766150767150768150769150770150771150772150773150774150775150776150777150778150779150780150781150782150783150784150785150786150787150788150789150790150791150792150793150794150795150796150797150798150799150800150801150802150803150804150805150806150807150808150809150810150811150812150813150814150815150816150817150818150819150820150821150822150823150824150825150826150827150828150829150830150831150832150833150834150835150836150837150838150839150840150841150842150843150844150845150846150847150848150849150850150851150852150853150854150855150856150857150858150859150860150861150862150863150864150865150866150867150868150869150870150871150872150873150874150875150876150877150878150879150880150881150882150883150884150885150886150887150888150889150890150891150892150893150894150895150896150897150898150899150900150901150902150903150904150905150906150907150908150909150910150911150912150913150914150915150916150917150918150919150920150921150922150923150924150925150926150927150928150929150930150931150932150933150934150935150936150937150938150939150940150941150942150943150944150945150946150947150948150949150950150951150952150953150954150955150956150957150958150959150960150961150962150963150964150965150966150967150968150969150970150971150972150973150974150975150976150977150978150979150980150981150982150983150984150985150986150987150988150989150990150991150992150993150994150995150996150997150998150999151000151001151002151003151004151005151006151007151008151009151010151011151012151013151014151015151016151017151018151019151020151021151022151023151024151025151026151027151028151029151030151031151032151033151034151035151036151037151038151039151040151041151042151043151044151045151046151047151048151049151050151051151052151053151054151055151056151057151058151059151060151061151062151063151064151065151066151067151068151069151070151071151072151073151074151075151076151077151078151079151080151081151082151083151084151085151086151087151088151089151090151091151092151093151094151095151096151097151098151099151100151101151102151103151104151105151106151107151108151109151110151111151112151113151114151115151116151117151118151119151120151121151122151123151124151125151126151127151128151129151130151131151132151133151134151135151136151137151138151139151140151141151142151143151144151145151146151147151148151149151150151151151152151153151154151155151156151157151158151159151160151161151162151163151164151165151166151167151168151169151170151171151172151173151174151175151176151177151178151179151180151181151182151183151184151185151186151187151188151189151190151191151192151193151194151195151196151197151198151199151200151201151202151203151204151205151206151207151208151209151210151211151212151213151214151215151216151217151218151219151220151221151222151223151224151225151226151227151228151229151230151231151232151233151234151235151236151237151238151239151240151241151242151243151244151245151246151247151248151249151250151251151252151253151254151255151256151257151258151259151260151261151262151263151264151265151266151267151268151269151270151271151272151273151274151275151276151277151278151279151280151281151282151283151284151285151286151287151288151289151290151291151292151293151294151295151296151297151298151299151300151301151302151303151304151305151306151307151308151309151310151311151312151313151314151315151316151317151318151319151320151321151322151323151324151325151326151327151328151329151330151331151332151333151334151335151336151337151338151339151340151341151342151343151344151345151346151347151348151349151350151351151352151353151354151355151356151357151358151359151360151361151362151363151364151365151366151367151368151369151370151371151372151373151374151375151376151377151378151379151380151381151382151383151384151385151386151387151388151389151390151391151392151393151394151395151396151397151398151399151400151401151402151403151404151405151406151407151408151409151410151411151412151413151414151415151416151417151418151419151420151421151422151423151424151425151426151427151428151429151430151431151432151433151434151435151436151437151438151439151440151441151442151443151444151445151446151447151448151449151450151451151452151453151454151455151456151457151458151459151460151461151462151463151464151465151466151467151468151469151470151471151472151473151474151475151476151477151478151479151480151481151482151483151484151485151486151487151488151489151490151491151492151493151494151495151496151497151498151499151500151501151502151503151504151505151506151507151508151509151510151511151512151513151514151515151516151517151518151519151520151521151522151523151524151525151526151527151528151529151530151531151532151533151534151535151536151537151538151539151540151541151542151543151544151545151546151547151548151549151550151551151552151553151554151555151556151557151558151559151560151561151562151563151564151565151566151567151568151569151570151571151572151573151574151575151576151577151578151579151580151581151582151583151584151585151586151587151588151589151590151591151592151593151594151595151596151597151598151599151600151601151602151603151604151605151606151607151608151609151610151611151612151613151614151615151616151617151618151619151620151621151622151623151624151625151626151627151628151629151630151631151632151633151634151635151636151637151638151639151640151641151642151643151644151645151646151647151648151649151650151651151652151653151654151655151656151657151658151659151660151661151662151663151664151665151666151667151668151669151670151671151672151673151674151675151676151677151678151679151680151681151682151683151684151685151686151687151688151689151690151691151692151693151694151695151696151697151698151699151700151701151702151703151704151705151706151707151708151709151710151711151712151713151714151715151716151717151718151719151720151721151722151723151724151725151726151727151728151729151730151731151732151733151734151735151736151737151738151739151740151741151742151743151744151745151746151747151748151749151750151751151752151753151754151755151756151757151758151759151760151761151762151763151764151765151766151767151768151769151770151771151772151773151774151775151776151777151778151779151780151781151782151783151784151785151786151787151788151789151790151791151792151793151794151795151796151797151798151799151800151801151802151803151804151805151806151807151808151809151810151811151812151813151814151815151816151817151818151819151820151821151822151823151824151825151826151827151828151829151830151831151832151833151834151835151836151837151838151839151840151841151842151843151844151845151846151847151848151849151850151851151852151853151854151855151856151857151858151859151860151861151862151863151864151865151866151867151868151869151870151871151872151873151874151875151876151877151878151879151880151881151882151883151884151885151886151887151888151889151890151891151892151893151894151895151896151897151898151899151900151901151902151903151904151905151906151907151908151909151910151911151912151913151914151915151916151917151918151919151920151921151922151923151924151925151926151927151928151929151930151931151932151933151934151935151936151937151938151939151940151941151942151943151944151945151946151947151948151949151950151951151952151953151954151955151956151957151958151959151960151961151962151963151964151965151966151967151968151969151970151971151972151973151974151975151976151977151978151979151980151981151982151983151984151985151986151987151988151989151990151991151992151993151994151995151996151997151998151999152000152001152002152003152004152005152006152007152008152009152010152011152012152013152014152015152016152017152018152019152020152021152022152023152024152025152026152027152028152029152030152031152032152033152034152035152036152037152038152039152040152041152042152043152044152045152046152047152048152049152050152051152052152053152054152055152056152057152058152059152060152061152062152063152064152065152066152067152068152069152070152071152072152073152074152075152076152077152078152079152080152081152082152083152084152085152086152087152088152089152090152091152092152093152094152095152096152097152098152099152100152101152102152103152104152105152106152107152108152109152110152111152112152113152114152115152116152117152118152119152120152121152122152123152124152125152126152127152128152129152130152131152132152133152134152135152136152137152138152139152140152141152142152143152144152145152146152147152148152149152150152151152152152153152154152155152156152157152158152159152160152161152162152163152164152165152166152167152168152169152170152171152172152173152174152175152176152177152178152179152180152181152182152183152184152185152186152187152188152189152190152191152192152193152194152195152196152197152198152199152200152201152202152203152204152205152206152207152208152209152210152211152212152213152214152215152216152217152218152219152220152221152222152223152224152225152226152227152228152229152230152231152232152233152234152235152236152237152238152239152240152241152242152243152244152245152246152247152248152249152250152251152252152253152254152255152256152257152258152259152260152261152262152263152264152265152266152267152268152269152270152271152272152273152274152275152276152277152278152279152280152281152282152283152284152285152286152287152288152289152290152291152292152293152294152295152296152297152298152299152300152301152302152303152304152305152306152307152308152309152310152311152312152313152314152315152316152317152318152319152320152321152322152323152324152325152326152327152328152329152330152331152332152333152334152335152336152337152338152339152340152341152342152343152344152345152346152347152348152349152350152351152352152353152354152355152356152357152358152359152360152361152362152363152364152365152366152367152368152369152370152371152372152373152374152375152376152377152378152379152380152381152382152383152384152385152386152387152388152389152390152391152392152393152394152395152396152397152398152399152400152401152402152403152404152405152406152407152408152409152410152411152412152413152414152415152416152417152418152419152420152421152422152423152424152425152426152427152428152429152430152431152432152433152434152435152436152437152438152439152440152441152442152443152444152445152446152447152448152449152450152451152452152453152454152455152456152457152458152459152460152461152462152463152464152465152466152467152468152469152470152471152472152473152474152475152476152477152478152479152480152481152482152483152484152485152486152487152488152489152490152491152492152493152494152495152496152497152498152499152500152501152502152503152504152505152506152507152508152509152510152511152512152513152514152515152516152517152518152519152520152521152522152523152524152525152526152527152528152529152530152531152532152533152534152535152536152537152538152539152540152541152542152543152544152545152546152547152548152549152550152551152552152553152554152555152556152557152558152559152560152561152562152563152564152565152566152567152568152569152570152571152572152573152574152575152576152577152578152579152580152581152582152583152584152585152586152587152588152589152590152591152592152593152594152595152596152597152598152599152600152601152602152603152604152605152606152607152608152609152610152611152612152613152614152615152616152617152618152619152620152621152622152623152624152625152626152627152628152629152630152631152632152633152634152635152636152637152638152639152640152641152642152643152644152645152646152647152648152649152650152651152652152653152654152655152656152657152658152659152660152661152662152663152664152665152666152667152668152669152670152671152672152673152674152675152676152677152678152679152680152681152682152683152684152685152686152687152688152689152690152691152692152693152694152695152696152697152698152699152700152701152702152703152704152705152706152707152708152709152710152711152712152713152714152715152716152717152718152719152720152721152722152723152724152725152726152727152728152729152730152731152732152733152734152735152736152737152738152739152740152741152742152743152744152745152746152747152748152749152750152751152752152753152754152755152756152757152758152759152760152761152762152763152764152765152766152767152768152769152770152771152772152773152774152775152776152777152778152779152780152781152782152783152784152785152786152787152788152789152790152791152792152793152794152795152796152797152798152799152800152801152802152803152804152805152806152807152808152809152810152811152812152813152814152815152816152817152818152819152820152821152822152823152824152825152826152827152828152829152830152831152832152833152834152835152836152837152838152839152840152841152842152843152844152845152846152847152848152849152850152851152852152853152854152855152856152857152858152859152860152861152862152863152864152865152866152867152868152869152870152871152872152873152874152875152876152877152878152879152880152881152882152883152884152885152886152887152888152889152890152891152892152893152894152895152896152897152898152899152900152901152902152903152904152905152906152907152908152909152910152911152912152913152914152915152916152917152918152919152920152921152922152923152924152925152926152927152928152929152930152931152932152933152934152935152936152937152938152939152940152941152942152943152944152945152946152947152948152949152950152951152952152953152954152955152956152957152958152959152960152961152962152963152964152965152966152967152968152969152970152971152972152973152974152975152976152977152978152979152980152981152982152983152984152985152986152987152988152989152990152991152992152993152994152995152996152997152998152999153000153001153002153003153004153005153006153007153008153009153010153011153012153013153014153015153016153017153018153019153020153021153022153023153024153025153026153027153028153029153030153031153032153033153034153035153036153037153038153039153040153041153042153043153044153045153046153047153048153049153050153051153052153053153054153055153056153057153058153059153060153061153062153063153064153065153066153067153068153069153070153071153072153073153074153075153076153077153078153079153080153081153082153083153084153085153086153087153088153089153090153091153092153093153094153095153096153097153098153099153100153101153102153103153104153105153106153107153108153109153110153111153112153113153114153115153116153117153118153119153120153121153122153123153124153125153126153127153128153129153130153131153132153133153134153135153136153137153138153139153140153141153142153143153144153145153146153147153148153149153150153151153152153153153154153155153156153157153158153159153160153161153162153163153164153165153166153167153168153169153170153171153172153173153174153175153176153177153178153179153180153181153182153183153184153185153186153187153188153189153190153191153192153193153194153195153196153197153198153199153200153201153202153203153204153205153206153207153208153209153210153211153212153213153214153215153216153217153218153219153220153221153222153223153224153225153226153227153228153229153230153231153232153233153234153235153236153237153238153239153240153241153242153243153244153245153246153247153248153249153250153251153252153253153254153255153256153257153258153259153260153261153262153263153264153265153266153267153268153269153270153271153272153273153274153275153276153277153278153279153280153281153282153283153284153285153286153287153288153289153290153291153292153293153294153295153296153297153298153299153300153301153302153303153304153305153306153307153308153309153310153311153312153313153314153315153316153317153318153319153320153321153322153323153324153325153326153327153328153329153330153331153332153333153334153335153336153337153338153339153340153341153342153343153344153345153346153347153348153349153350153351153352153353153354153355153356153357153358153359153360153361153362153363153364153365153366153367153368153369153370153371153372153373153374153375153376153377153378153379153380153381153382153383153384153385153386153387153388153389153390153391153392153393153394153395153396153397153398153399153400153401153402153403153404153405153406153407153408153409153410153411153412153413153414153415153416153417153418153419153420153421153422153423153424153425153426153427153428153429153430153431153432153433153434153435153436153437153438153439153440153441153442153443153444153445153446153447153448153449153450153451153452153453153454153455153456153457153458153459153460153461153462153463153464153465153466153467153468153469153470153471153472153473153474153475153476153477153478153479153480153481153482153483153484153485153486153487153488153489153490153491153492153493153494153495153496153497153498153499153500153501153502153503153504153505153506153507153508153509153510153511153512153513153514153515153516153517153518153519153520153521153522153523153524153525153526153527153528153529153530153531153532153533153534153535153536153537153538153539153540153541153542153543153544153545153546153547153548153549153550153551153552153553153554153555153556153557153558153559153560153561153562153563153564153565153566153567153568153569153570153571153572153573153574153575153576153577153578153579153580153581153582153583153584153585153586153587153588153589153590153591153592153593153594153595153596153597153598153599153600153601153602153603153604153605153606153607153608153609153610153611153612153613153614153615153616153617153618153619153620153621153622153623153624153625153626153627153628153629153630153631153632153633153634153635153636153637153638153639153640153641153642153643153644153645153646153647153648153649153650153651153652153653153654153655153656153657153658153659153660153661153662153663153664153665153666153667153668153669153670153671153672153673153674153675153676153677153678153679153680153681153682153683153684153685153686153687153688153689153690153691153692153693153694153695153696153697153698153699153700153701153702153703153704153705153706153707153708153709153710153711153712153713153714153715153716153717153718153719153720153721153722153723153724153725153726153727153728153729153730153731153732153733153734153735153736153737153738153739153740153741153742153743153744153745153746153747153748153749153750153751153752153753153754153755153756153757153758153759153760153761153762153763153764153765153766153767153768153769153770153771153772153773153774153775153776153777153778153779153780153781153782153783153784153785153786153787153788153789153790153791153792153793153794153795153796153797153798153799153800153801153802153803153804153805153806153807153808153809153810153811153812153813153814153815153816153817153818153819153820153821153822153823153824153825153826153827153828153829153830153831153832153833153834153835153836153837153838153839153840153841153842153843153844153845153846153847153848153849153850153851153852153853153854153855153856153857153858153859153860153861153862153863153864153865153866153867153868153869153870153871153872153873153874153875153876153877153878153879153880153881153882153883153884153885153886153887153888153889153890153891153892153893153894153895153896153897153898153899153900153901153902153903153904153905153906153907153908153909153910153911153912153913153914153915153916153917153918153919153920153921153922153923153924153925153926153927153928153929153930153931153932153933153934153935153936153937153938153939153940153941153942153943153944153945153946153947153948153949153950153951153952153953153954153955153956153957153958153959153960153961153962153963153964153965153966153967153968153969153970153971153972153973153974153975153976153977153978153979153980153981153982153983153984153985153986153987153988153989153990153991153992153993153994153995153996153997153998153999154000154001154002154003154004154005154006154007154008154009154010154011154012154013154014154015154016154017154018154019154020154021154022154023154024154025154026154027154028154029154030154031154032154033154034154035154036154037154038154039154040154041154042154043154044154045154046154047154048154049154050154051154052154053154054154055154056154057154058154059154060154061154062154063154064154065154066154067154068154069154070154071154072154073154074154075154076154077154078154079154080154081154082154083154084154085154086154087154088154089154090154091154092154093154094154095154096154097154098154099154100154101154102154103154104154105154106154107154108154109154110154111154112154113154114154115154116154117154118154119154120154121154122154123154124154125154126154127154128154129154130154131154132154133154134154135154136154137154138154139154140154141154142154143154144154145154146154147154148154149154150154151154152154153154154154155154156154157154158154159154160154161154162154163154164154165154166154167154168154169154170154171154172154173154174154175154176154177154178154179154180154181154182154183154184154185154186154187154188154189154190154191154192154193154194154195154196154197154198154199154200154201154202154203154204154205154206154207154208154209154210154211154212154213154214154215154216154217154218154219154220154221154222154223154224154225154226154227154228154229154230154231154232154233154234154235154236154237154238154239154240154241154242154243154244154245154246154247154248154249154250154251154252154253154254154255154256154257154258154259154260154261154262154263154264154265154266154267154268154269154270154271154272154273154274154275154276154277154278154279154280154281154282154283154284154285154286154287154288154289154290154291154292154293154294154295154296154297154298154299154300154301154302154303154304154305154306154307154308154309154310154311154312154313154314154315154316154317154318154319154320154321154322154323154324154325154326154327154328154329154330154331154332154333154334154335154336154337154338154339154340154341154342154343154344154345154346154347154348154349154350154351154352154353154354154355154356154357154358154359154360154361154362154363154364154365154366154367154368154369154370154371154372154373154374154375154376154377154378154379154380154381154382154383154384154385154386154387154388154389154390154391154392154393154394154395154396154397154398154399154400154401154402154403154404154405154406154407154408154409154410154411154412154413154414154415154416154417154418154419154420154421154422154423154424154425154426154427154428154429154430154431154432154433154434154435154436154437154438154439154440154441154442154443154444154445154446154447154448154449154450154451154452154453154454154455154456154457154458154459154460154461154462154463154464154465154466154467154468154469154470154471154472154473154474154475154476154477154478154479154480154481154482154483154484154485154486154487154488154489154490154491154492154493154494154495154496154497154498154499154500154501154502154503154504154505154506154507154508154509154510154511154512154513154514154515154516154517154518154519154520154521154522154523154524154525154526154527154528154529154530154531154532154533154534154535154536154537154538154539154540154541154542154543154544154545154546154547154548154549154550154551154552154553154554154555154556154557154558154559154560154561154562154563154564154565154566154567154568154569154570154571154572154573154574154575154576154577154578154579154580154581154582154583154584154585154586154587154588154589154590154591154592154593154594154595154596154597154598154599154600154601154602154603154604154605154606154607154608154609154610154611154612154613154614154615154616154617154618154619154620154621154622154623154624154625154626154627154628154629154630154631154632154633154634154635154636154637154638154639154640154641154642154643154644154645154646154647154648154649154650154651154652154653154654154655154656154657154658154659154660154661154662154663154664154665154666154667154668154669154670154671154672154673154674154675154676154677154678154679154680154681154682154683154684154685154686154687154688154689154690154691154692154693154694154695154696154697154698154699154700154701154702154703154704154705154706154707154708154709154710154711154712154713154714154715154716154717154718154719154720154721154722154723154724154725154726154727154728154729154730154731154732154733154734154735154736154737154738154739154740154741154742154743154744154745154746154747154748154749154750154751154752154753154754154755154756154757154758154759154760154761154762154763154764154765154766154767154768154769154770154771154772154773154774154775154776154777154778154779154780154781154782154783154784154785154786154787154788154789154790154791154792154793154794154795154796154797154798154799154800154801154802154803154804154805154806154807154808154809154810154811154812154813154814154815154816154817154818154819154820154821154822154823154824154825154826154827154828154829154830154831154832154833154834154835154836154837154838154839154840154841154842154843154844154845154846154847154848154849154850154851154852154853154854154855154856154857154858154859154860154861154862154863154864154865154866154867154868154869154870154871154872154873154874154875154876154877154878154879154880154881154882154883154884154885154886154887154888154889154890154891154892154893154894154895154896154897154898154899154900154901154902154903154904154905154906154907154908154909154910154911154912154913154914154915154916154917154918154919154920154921154922154923154924154925154926154927154928154929154930154931154932154933154934154935154936154937154938154939154940154941154942154943154944154945154946154947154948154949154950154951154952154953154954154955154956154957154958154959154960154961154962154963154964154965154966154967154968154969154970154971154972154973154974154975154976154977154978154979154980154981154982154983154984154985154986154987154988154989154990154991154992154993154994154995154996154997154998154999155000155001155002155003155004155005155006155007155008155009155010155011155012155013155014155015155016155017155018155019155020155021155022155023155024155025155026155027155028155029155030155031155032155033155034155035155036155037155038155039155040155041155042155043155044155045155046155047155048155049155050155051155052155053155054155055155056155057155058155059155060155061155062155063155064155065155066155067155068155069155070155071155072155073155074155075155076155077155078155079155080155081155082155083155084155085155086155087155088155089155090155091155092155093155094155095155096155097155098155099155100155101155102155103155104155105155106155107155108155109155110155111155112155113155114155115155116155117155118155119155120155121155122155123155124155125155126155127155128155129155130155131155132155133155134155135155136155137155138155139155140155141155142155143155144155145155146155147155148155149155150155151155152155153155154155155155156155157155158155159155160155161155162155163155164155165155166155167155168155169155170155171155172155173155174155175155176155177155178155179155180155181155182155183155184155185155186155187155188155189155190155191155192155193155194155195155196155197155198155199155200155201155202155203155204155205155206155207155208155209155210155211155212155213155214155215155216155217155218155219155220155221155222155223155224155225155226155227155228155229155230155231155232155233155234155235155236155237155238155239155240155241155242155243155244155245155246155247155248155249155250155251155252155253155254155255155256155257155258155259155260155261155262155263155264155265155266155267155268155269155270155271155272155273155274155275155276155277155278155279155280155281155282155283155284155285155286155287155288155289155290155291155292155293155294155295155296155297155298155299155300155301155302155303155304155305155306155307155308155309155310155311155312155313155314155315155316155317155318155319155320155321155322155323155324155325155326155327155328155329155330155331155332155333155334155335155336155337155338155339155340155341155342155343155344155345155346155347155348155349155350155351155352155353155354155355155356155357155358155359155360155361155362155363155364155365155366155367155368155369155370155371155372155373155374155375155376155377155378155379155380155381155382155383155384155385155386155387155388155389155390155391155392155393155394155395155396155397155398155399155400155401155402155403155404155405155406155407155408155409155410155411155412155413155414155415155416155417155418155419155420155421155422155423155424155425155426155427155428155429155430155431155432155433155434155435155436155437155438155439155440155441155442155443155444155445155446155447155448155449155450155451155452155453155454155455155456155457155458155459155460155461155462155463155464155465155466155467155468155469155470155471155472155473155474155475155476155477155478155479155480155481155482155483155484155485155486155487155488155489155490155491155492155493155494155495155496155497155498155499155500155501155502155503155504155505155506155507155508155509155510155511155512155513155514155515155516155517155518155519155520155521155522155523155524155525155526155527155528155529155530155531155532155533155534155535155536155537155538155539155540155541155542155543155544155545155546155547155548155549155550155551155552155553155554155555155556155557155558155559155560155561155562155563155564155565155566155567155568155569155570155571155572155573155574155575155576155577155578155579155580155581155582155583155584155585155586155587155588155589155590155591155592155593155594155595155596155597155598155599155600155601155602155603155604155605155606155607155608155609155610155611155612155613155614155615155616155617155618155619155620155621155622155623155624155625155626155627155628155629155630155631155632155633155634155635155636155637155638155639155640155641155642155643155644155645155646155647155648155649155650155651155652155653155654155655155656155657155658155659155660155661155662155663155664155665155666155667155668155669155670155671155672155673155674155675155676155677155678155679155680155681155682155683155684155685155686155687155688155689155690155691155692155693155694155695155696155697155698155699155700155701155702155703155704155705155706155707155708155709155710155711155712155713155714155715155716155717155718155719155720155721155722155723155724155725155726155727155728155729155730155731155732155733155734155735155736155737155738155739155740155741155742155743155744155745155746155747155748155749155750155751155752155753155754155755155756155757155758155759155760155761155762155763155764155765155766155767155768155769155770155771155772155773155774155775155776155777155778155779155780155781155782155783155784155785155786155787155788155789155790155791155792155793155794155795155796155797155798155799155800155801155802155803155804155805155806155807155808155809155810155811155812155813155814155815155816155817155818155819155820155821155822155823155824155825155826155827155828155829155830155831155832155833155834155835155836155837155838155839155840155841155842155843155844155845155846155847155848155849155850155851155852155853155854155855155856155857155858155859155860155861155862155863155864155865155866155867155868155869155870155871155872155873155874155875155876155877155878155879155880155881155882155883155884155885155886155887155888155889155890155891155892155893155894155895155896155897155898155899155900155901155902155903155904155905155906155907155908155909155910155911155912155913155914155915155916155917155918155919155920155921155922155923155924155925155926155927155928155929155930155931155932155933155934155935155936155937155938155939155940155941155942155943155944155945155946155947155948155949155950155951155952155953155954155955155956155957155958155959155960155961155962155963155964155965155966155967155968155969155970155971155972155973155974155975155976155977155978155979155980155981155982155983155984155985155986155987155988155989155990155991155992155993155994155995155996155997155998155999156000156001156002156003156004156005156006156007156008156009156010156011156012156013156014156015156016156017156018156019156020156021156022156023156024156025156026156027156028156029156030156031156032156033156034156035156036156037156038156039156040156041156042156043156044156045156046156047156048156049156050156051156052156053156054156055156056156057156058156059156060156061156062156063156064156065156066156067156068156069156070156071156072156073156074156075156076156077156078156079156080156081156082156083156084156085156086156087156088156089156090156091156092156093156094156095156096156097156098156099156100156101156102156103156104156105156106156107156108156109156110156111156112156113156114156115156116156117156118156119156120156121156122156123156124156125156126156127156128156129156130156131156132156133156134156135156136156137156138156139156140156141156142156143156144156145156146156147156148156149156150156151156152156153156154156155156156156157156158156159156160156161156162156163156164156165156166156167156168156169156170156171156172156173156174156175156176156177156178156179156180156181156182156183156184156185156186156187156188156189156190156191156192156193156194156195156196156197156198156199156200156201156202156203156204156205156206156207156208156209156210156211156212156213156214156215156216156217156218156219156220156221156222156223156224156225156226156227156228156229156230156231156232156233156234156235156236156237156238156239156240156241156242156243156244156245156246156247156248156249156250156251156252156253156254156255156256156257156258156259156260156261156262156263156264156265156266156267156268156269156270156271156272156273156274156275156276156277156278156279156280156281156282156283156284156285156286156287156288156289156290156291156292156293156294156295156296156297156298156299156300156301156302156303156304156305156306156307156308156309156310156311156312156313156314156315156316156317156318156319156320156321156322156323156324156325156326156327156328156329156330156331156332156333156334156335156336156337156338156339156340156341156342156343156344156345156346156347156348156349156350156351156352156353156354156355156356156357156358156359156360156361156362156363156364156365156366156367156368156369156370156371156372156373156374156375156376156377156378156379156380156381156382156383156384156385156386156387156388156389156390156391156392156393156394156395156396156397156398156399156400156401156402156403156404156405156406156407156408156409156410156411156412156413156414156415156416156417156418156419156420156421156422156423156424156425156426156427156428156429156430156431156432156433156434156435156436156437156438156439156440156441156442156443156444156445156446156447156448156449156450156451156452156453156454156455156456156457156458156459156460156461156462156463156464156465156466156467156468156469156470156471156472156473156474156475156476156477156478156479156480156481156482156483156484156485156486156487156488156489156490156491156492156493156494156495156496156497156498156499156500156501156502156503156504156505156506156507156508156509156510156511156512156513156514156515156516156517156518156519156520156521156522156523156524156525156526156527156528156529156530156531156532156533156534156535156536156537156538156539156540156541156542156543156544156545156546156547156548156549156550156551156552156553156554156555156556156557156558156559156560156561156562156563156564156565156566156567156568156569156570156571156572156573156574156575156576156577156578156579156580156581156582156583156584156585156586156587156588156589156590156591156592156593156594156595156596156597156598156599156600156601156602156603156604156605156606156607156608156609156610156611156612156613156614156615156616156617156618156619156620156621156622156623156624156625156626156627156628156629156630156631156632156633156634156635156636156637156638156639156640156641156642156643156644156645156646156647156648156649156650156651156652156653156654156655156656156657156658156659156660156661156662156663156664156665156666156667156668156669156670156671156672156673156674156675156676156677156678156679156680156681156682156683156684156685156686156687156688156689156690156691156692156693156694156695156696156697156698156699156700156701156702156703156704156705156706156707156708156709156710156711156712156713156714156715156716156717156718156719156720156721156722156723156724156725156726156727156728156729156730156731156732156733156734156735156736156737156738156739156740156741156742156743156744156745156746156747156748156749156750156751156752156753156754156755156756156757156758156759156760156761156762156763156764156765156766156767156768156769156770156771156772156773156774156775156776156777156778156779156780156781156782156783156784156785156786156787156788156789156790156791156792156793156794156795156796156797156798156799156800156801156802156803156804156805156806156807156808156809156810156811156812156813156814156815156816156817156818156819156820156821156822156823156824156825156826156827156828156829156830156831156832156833156834156835156836156837156838156839156840156841156842156843156844156845156846156847156848156849156850156851156852156853156854156855156856156857156858156859156860156861156862156863156864156865156866156867156868156869156870156871156872156873156874156875156876156877156878156879156880156881156882156883156884156885156886156887156888156889156890156891156892156893156894156895156896156897156898156899156900156901156902156903156904156905156906156907156908156909156910156911156912156913156914156915156916156917156918156919156920156921156922156923156924156925156926156927156928156929156930156931156932156933156934156935156936156937156938156939156940156941156942156943156944156945156946156947156948156949156950156951156952156953156954156955156956156957156958156959156960156961156962156963156964156965156966156967156968156969156970156971156972156973156974156975156976156977156978156979156980156981156982156983156984156985156986156987156988156989156990156991156992156993156994156995156996156997156998156999157000157001157002157003157004157005157006157007157008157009157010157011157012157013157014157015157016157017157018157019157020157021157022157023157024157025157026157027157028157029157030157031157032157033157034157035157036157037157038157039157040157041157042157043157044157045157046157047157048157049157050157051157052157053157054157055157056157057157058157059157060157061157062157063157064157065157066157067157068157069157070157071157072157073157074157075157076157077157078157079157080157081157082157083157084157085157086157087157088157089157090157091157092157093157094157095157096157097157098157099157100157101157102157103157104157105157106157107157108157109157110157111157112157113157114157115157116157117157118157119157120157121157122157123157124157125157126157127157128157129157130157131157132157133157134157135157136157137157138157139157140157141157142157143157144157145157146157147157148157149157150157151157152157153157154157155157156157157157158157159157160157161157162157163157164157165157166157167157168157169157170157171157172157173157174157175157176157177157178157179157180157181157182157183157184157185157186157187157188157189157190157191157192157193157194157195157196157197157198157199157200157201157202157203157204157205157206157207157208157209157210157211157212157213157214157215157216157217157218157219157220157221157222157223157224157225157226157227157228157229157230157231157232157233157234157235157236157237157238157239157240157241157242157243157244157245157246157247157248157249157250157251157252157253157254157255157256157257157258157259157260157261157262157263157264157265157266157267157268157269157270157271157272157273157274157275157276157277157278157279157280157281157282157283157284157285157286157287157288157289157290157291157292157293157294157295157296157297157298157299157300157301157302157303157304157305157306157307157308157309157310157311157312157313157314157315157316157317157318157319157320157321157322157323157324157325157326157327157328157329157330157331157332157333157334157335157336157337157338157339157340157341157342157343157344157345157346157347157348157349157350157351157352157353157354157355157356157357157358157359157360157361157362157363157364157365157366157367157368157369157370157371157372157373157374157375157376157377157378157379157380157381157382157383157384157385157386157387157388157389157390157391157392157393157394157395157396157397157398157399157400157401157402157403157404157405157406157407157408157409157410157411157412157413157414157415157416157417157418157419157420157421157422157423157424157425157426157427157428157429157430157431157432157433157434157435157436157437157438157439157440157441157442157443157444157445157446157447157448157449157450157451157452157453157454157455157456157457157458157459157460157461157462157463157464157465157466157467157468157469157470157471157472157473157474157475157476157477157478157479157480157481157482157483157484157485157486157487157488157489157490157491157492157493157494157495157496157497157498157499157500157501157502157503157504157505157506157507157508157509157510157511157512157513157514157515157516157517157518157519157520157521157522157523157524157525157526157527157528157529157530157531157532157533157534157535157536157537157538157539157540157541157542157543157544157545157546157547157548157549157550157551157552157553157554157555157556157557157558157559157560157561157562157563157564157565157566157567157568157569157570157571157572157573157574157575157576157577157578157579157580157581157582157583157584157585157586157587157588157589157590157591157592157593157594157595157596157597157598157599157600157601157602157603157604157605157606157607157608157609157610157611157612157613157614157615157616157617157618157619157620157621157622157623157624157625157626157627157628157629157630157631157632157633157634157635157636157637157638157639157640157641157642157643157644157645157646157647157648157649157650157651157652157653157654157655157656157657157658157659157660157661157662157663157664157665157666157667157668157669157670157671157672157673157674157675157676157677157678157679157680157681157682157683157684157685157686157687157688157689157690157691157692157693157694157695157696157697157698157699157700157701157702157703157704157705157706157707157708157709157710157711157712157713157714157715157716157717157718157719157720157721157722157723157724157725157726157727157728157729157730157731157732157733157734157735157736157737157738157739157740157741157742157743157744157745157746157747157748157749157750157751157752157753157754157755157756157757157758157759157760157761157762157763157764157765157766157767157768157769157770157771157772157773157774157775157776157777157778157779157780157781157782157783157784157785157786157787157788157789157790157791157792157793157794157795157796157797157798157799157800157801157802157803157804157805157806157807157808157809157810157811157812157813157814157815157816157817157818157819157820157821157822157823157824157825157826157827157828157829157830157831157832157833157834157835157836157837157838157839157840157841157842157843157844157845157846157847157848157849157850157851157852157853157854157855157856157857157858157859157860157861157862157863157864157865157866157867157868157869157870157871157872157873157874157875157876157877157878157879157880157881157882157883157884157885157886157887157888157889157890157891157892157893157894157895157896157897157898157899157900157901157902157903157904157905157906157907157908157909157910157911157912157913157914157915157916157917157918157919157920157921157922157923157924157925157926157927157928157929157930157931157932157933157934157935157936157937157938157939157940157941157942157943157944157945157946157947157948157949157950157951157952157953157954157955157956157957157958157959157960157961157962157963157964157965157966157967157968157969157970157971157972157973157974157975157976157977157978157979157980157981157982157983157984157985157986157987157988157989157990157991157992157993157994157995157996157997157998157999158000158001158002158003158004158005158006158007158008158009158010158011158012158013158014158015158016158017158018158019158020158021158022158023158024158025158026158027158028158029158030158031158032158033158034158035158036158037158038158039158040158041158042158043158044158045158046158047158048158049158050158051158052158053158054158055158056158057158058158059158060158061158062158063158064158065158066158067158068158069158070158071158072158073158074158075158076158077158078158079158080158081158082158083158084158085158086158087158088158089158090158091158092158093158094158095158096158097158098158099158100158101158102158103158104158105158106158107158108158109158110158111158112158113158114158115158116158117158118158119158120158121158122158123158124158125158126158127158128158129158130158131158132158133158134158135158136158137158138158139158140158141158142158143158144158145158146158147158148158149158150158151158152158153158154158155158156158157158158158159158160158161158162158163158164158165158166158167158168158169158170158171158172158173158174158175158176158177158178158179158180158181158182158183158184158185158186158187158188158189158190158191158192158193158194158195158196158197158198158199158200158201158202158203158204158205158206158207158208158209158210158211158212158213158214158215158216158217158218158219158220158221158222158223158224158225158226158227158228158229158230158231158232158233158234158235158236158237158238158239158240158241158242158243158244158245158246158247158248158249158250158251158252158253158254158255158256158257158258158259158260158261158262158263158264158265158266158267158268158269158270158271158272158273158274158275158276158277158278158279158280158281158282158283158284158285158286158287158288158289158290158291158292158293158294158295158296158297158298158299158300158301158302158303158304158305158306158307158308158309158310158311158312158313158314158315158316158317158318158319158320158321158322158323158324158325158326158327158328158329158330158331158332158333158334158335158336158337158338158339158340158341158342158343158344158345158346158347158348158349158350158351158352158353158354158355158356158357158358158359158360158361158362158363158364158365158366158367158368158369158370158371158372158373158374158375158376158377158378158379158380158381158382158383158384158385158386158387158388158389158390158391158392158393158394158395158396158397158398158399158400158401158402158403158404158405158406158407158408158409158410158411158412158413158414158415158416158417158418158419158420158421158422158423158424158425158426158427158428158429158430158431158432158433158434158435158436158437158438158439158440158441158442158443158444158445158446158447158448158449158450158451158452158453158454158455158456158457158458158459158460158461158462158463158464158465158466158467158468158469158470158471158472158473158474158475158476158477158478158479158480158481158482158483158484158485158486158487158488158489158490158491158492158493158494158495158496158497158498158499158500158501158502158503158504158505158506158507158508158509158510158511158512158513158514158515158516158517158518158519158520158521158522158523158524158525158526158527158528158529158530158531158532158533158534158535158536158537158538158539158540158541158542158543158544158545158546158547158548158549158550158551158552158553158554158555158556158557158558158559158560158561158562158563158564158565158566158567158568158569158570158571158572158573158574158575158576158577158578158579158580158581158582158583158584158585158586158587158588158589158590158591158592158593158594158595158596158597158598158599158600158601158602158603158604158605158606158607158608158609158610158611158612158613158614158615158616158617158618158619158620158621158622158623158624158625158626158627158628158629158630158631158632158633158634158635158636158637158638158639158640158641158642158643158644158645158646158647158648158649158650158651158652158653158654158655158656158657158658158659158660158661158662158663158664158665158666158667158668158669158670158671158672158673158674158675158676158677158678158679158680158681158682158683158684158685158686158687158688158689158690158691158692158693158694158695158696158697158698158699158700158701158702158703158704158705158706158707158708158709158710158711158712158713158714158715158716158717158718158719158720158721158722158723158724158725158726158727158728158729158730158731158732158733158734158735158736158737158738158739158740158741158742158743158744158745158746158747158748158749158750158751158752158753158754158755158756158757158758158759158760158761158762158763158764158765158766158767158768158769158770158771158772158773158774158775158776158777158778158779158780158781158782158783158784158785158786158787158788158789158790158791158792158793158794158795158796158797158798158799158800158801158802158803158804158805158806158807158808158809158810158811158812158813158814158815158816158817158818158819158820158821158822158823158824158825158826158827158828158829158830158831158832158833158834158835158836158837158838158839158840158841158842158843158844158845158846158847158848158849158850158851158852158853158854158855158856158857158858158859158860158861158862158863158864158865158866158867158868158869158870158871158872158873158874158875158876158877158878158879158880158881158882158883158884158885158886158887158888158889158890158891158892158893158894158895158896158897158898158899158900158901158902158903158904158905158906158907158908158909158910158911158912158913158914158915158916158917158918158919158920158921158922158923158924158925158926158927158928158929158930158931158932158933158934158935158936158937158938158939158940158941158942158943158944158945158946158947158948158949158950158951158952158953158954158955158956158957158958158959158960158961158962158963158964158965158966158967158968158969158970158971158972158973158974158975158976158977158978158979158980158981158982158983158984158985158986158987158988158989158990158991158992158993158994158995158996158997158998158999159000159001159002159003159004159005159006159007159008159009159010159011159012159013159014159015159016159017159018159019159020159021159022159023159024159025159026159027159028159029159030159031159032159033159034159035159036159037159038159039159040159041159042159043159044159045159046159047159048159049159050159051159052159053159054159055159056159057159058159059159060159061159062159063159064159065159066159067159068159069159070159071159072159073159074159075159076159077159078159079159080159081159082159083159084159085159086159087159088159089159090159091159092159093159094159095159096159097159098159099159100159101159102159103159104159105159106159107159108159109159110159111159112159113159114159115159116159117159118159119159120159121159122159123159124159125159126159127159128159129159130159131159132159133159134159135159136159137159138159139159140159141159142159143159144159145159146159147159148159149159150159151159152159153159154159155159156159157159158159159159160159161159162159163159164159165159166159167159168159169159170159171159172159173159174159175159176159177159178159179159180159181159182159183159184159185159186159187159188159189159190159191159192159193159194159195159196159197159198159199159200159201159202159203159204159205159206159207159208159209159210159211159212159213159214159215159216159217159218159219159220159221159222159223159224159225159226159227159228159229159230159231159232159233159234159235159236159237159238159239159240159241159242159243159244159245159246159247159248159249159250159251159252159253159254159255159256159257159258159259159260159261159262159263159264159265159266159267159268159269159270159271159272159273159274159275159276159277159278159279159280159281159282159283159284159285159286159287159288159289159290159291159292159293159294159295159296159297159298159299159300159301159302159303159304159305159306159307159308159309159310159311159312159313159314159315159316159317159318159319159320159321159322159323159324159325159326159327159328159329159330159331159332159333159334159335159336159337159338159339159340159341159342159343159344159345159346159347159348159349159350159351159352159353159354159355159356159357159358159359159360159361159362159363159364159365159366159367159368159369159370159371159372159373159374159375159376159377159378159379159380159381159382159383159384159385159386159387159388159389159390159391159392159393159394159395159396159397159398159399159400159401159402159403159404159405159406159407159408159409159410159411159412159413159414159415159416159417159418159419159420159421159422159423159424159425159426159427159428159429159430159431159432159433159434159435159436159437159438159439159440159441159442159443159444159445159446159447159448159449159450159451159452159453159454159455159456159457159458159459159460159461159462159463159464159465159466159467159468159469159470159471159472159473159474159475159476159477159478159479159480159481159482159483159484159485159486159487159488159489159490159491159492159493159494159495159496159497159498159499159500159501159502159503159504159505159506159507159508159509159510159511159512159513159514159515159516159517159518159519159520159521159522159523159524159525159526159527159528159529159530159531159532159533159534159535159536159537159538159539159540159541159542159543159544159545159546159547159548159549159550159551159552159553159554159555159556159557159558159559159560159561159562159563159564159565159566159567159568159569159570159571159572159573159574159575159576159577159578159579159580159581159582159583159584159585159586159587159588159589159590159591159592159593159594159595159596159597159598159599159600159601159602159603159604159605159606159607159608159609159610159611159612159613159614159615159616159617159618159619159620159621159622159623159624159625159626159627159628159629159630159631159632159633159634159635159636159637159638159639159640159641159642159643159644159645159646159647159648159649159650159651159652159653159654159655159656159657159658159659159660159661159662159663159664159665159666159667159668159669159670159671159672159673159674159675159676159677159678159679159680159681159682159683159684159685159686159687159688159689159690159691159692159693159694159695159696159697159698159699159700159701159702159703159704159705159706159707159708159709159710159711159712159713159714159715159716159717159718159719159720159721159722159723159724159725159726159727159728159729159730159731159732159733159734159735159736159737159738159739159740159741159742159743159744159745159746159747159748159749159750159751159752159753159754159755159756159757159758159759159760159761159762159763159764159765159766159767159768159769159770159771159772159773159774159775159776159777159778159779159780159781159782159783159784159785159786159787159788159789159790159791159792159793159794159795159796159797159798159799159800159801159802159803159804159805159806159807159808159809159810159811159812159813159814159815159816159817159818159819159820159821159822159823159824159825159826159827159828159829159830159831159832159833159834159835159836159837159838159839159840159841159842159843159844159845159846159847159848159849159850159851159852159853159854159855159856159857159858159859159860159861159862159863159864159865159866159867159868159869159870159871159872159873159874159875159876159877159878159879159880159881159882159883159884159885159886159887159888159889159890159891159892159893159894159895159896159897159898159899159900159901159902159903159904159905159906159907159908159909159910159911159912159913159914159915159916159917159918159919159920159921159922159923159924159925159926159927159928159929159930159931159932159933159934159935159936159937159938159939159940159941159942159943159944159945159946159947159948159949159950159951159952159953159954159955159956159957159958159959159960159961159962159963159964159965159966159967159968159969159970159971159972159973159974159975159976159977159978159979159980159981159982159983159984159985159986159987159988159989159990159991159992159993159994159995159996159997159998159999160000160001160002160003160004160005160006160007160008160009160010160011160012160013160014160015160016160017160018160019160020160021160022160023160024160025160026160027160028160029160030160031160032160033160034160035160036160037160038160039160040160041160042160043160044160045160046160047160048160049160050160051160052160053160054160055160056160057160058160059160060160061160062160063160064160065160066160067160068160069160070160071160072160073160074160075160076160077160078160079160080160081160082160083160084160085160086160087160088160089160090160091160092160093160094160095160096160097160098160099160100160101160102160103160104160105160106160107160108160109160110160111160112160113160114160115160116160117160118160119160120160121160122160123160124160125160126160127160128160129160130160131160132160133160134160135160136160137160138160139160140160141160142160143160144160145160146160147160148160149160150160151160152160153160154160155160156160157160158160159160160160161160162160163160164160165160166160167160168160169160170160171160172160173160174160175160176160177160178160179160180160181160182160183160184160185160186160187160188160189160190160191160192160193160194160195160196160197160198160199160200160201160202160203160204160205160206160207160208160209160210160211160212160213160214160215160216160217160218160219160220160221160222160223160224160225160226160227160228160229160230160231160232160233160234160235160236160237160238160239160240160241160242160243160244160245160246160247160248160249160250160251160252160253160254160255160256160257160258160259160260160261160262160263160264160265160266160267160268160269160270160271160272160273160274160275160276160277160278160279160280160281160282160283160284160285160286160287160288160289160290160291160292160293160294160295160296160297160298160299160300160301160302160303160304160305160306160307160308160309160310160311160312160313160314160315160316160317160318160319160320160321160322160323160324160325160326160327160328160329160330160331160332160333160334160335160336160337160338160339160340160341160342160343160344160345160346160347160348160349160350160351160352160353160354160355160356160357160358160359160360160361160362160363160364160365160366160367160368160369160370160371160372160373160374160375160376160377160378160379160380160381160382160383160384160385160386160387160388160389160390160391160392160393160394160395160396160397160398160399160400160401160402160403160404160405160406160407160408160409160410160411160412160413160414160415160416160417160418160419160420160421160422160423160424160425160426160427160428160429160430160431160432160433160434160435160436160437160438160439160440160441160442160443160444160445160446160447160448160449160450160451160452160453160454160455160456160457160458160459160460160461160462160463160464160465160466160467160468160469160470160471160472160473160474160475160476160477160478160479160480160481160482160483160484160485160486160487160488160489160490160491160492160493160494160495160496160497160498160499160500160501160502160503160504160505160506160507160508160509160510160511160512160513160514160515160516160517160518160519160520160521160522160523160524160525160526160527160528160529160530160531160532160533160534160535160536160537160538160539160540160541160542160543160544160545160546160547160548160549160550160551160552160553160554160555160556160557160558160559160560160561160562160563160564160565160566160567160568160569160570160571160572160573160574160575160576160577160578160579160580160581160582160583160584160585160586160587160588160589160590160591160592160593160594160595160596160597160598160599160600160601160602160603160604160605160606160607160608160609160610160611160612160613160614160615160616160617160618160619160620160621160622160623160624160625160626160627160628160629160630160631160632160633160634160635160636160637160638160639160640160641160642160643160644160645160646160647160648160649160650160651160652160653160654160655160656160657160658160659160660160661160662160663160664160665160666160667160668160669160670160671160672160673160674160675160676160677160678160679160680160681160682160683160684160685160686160687160688160689160690160691160692160693160694160695160696160697160698160699160700160701160702160703160704160705160706160707160708160709160710160711160712160713160714160715160716160717160718160719160720160721160722160723160724160725160726160727160728160729160730160731160732160733160734160735160736160737160738160739160740160741160742160743160744160745160746160747160748160749160750160751160752160753160754160755160756160757160758160759160760160761160762160763160764160765160766160767160768160769160770160771160772160773160774160775160776160777160778160779160780160781160782160783160784160785160786160787160788160789160790160791160792160793160794160795160796160797160798160799160800160801160802160803160804160805160806160807160808160809160810160811160812160813160814160815160816160817160818160819160820160821160822160823160824160825160826160827160828160829160830160831160832160833160834160835160836160837160838160839160840160841160842160843160844160845160846160847160848160849160850160851160852160853160854160855160856160857160858160859160860160861160862160863160864160865160866160867160868160869160870160871160872160873160874160875160876160877160878160879160880160881160882160883160884160885160886160887160888160889160890160891160892160893160894160895160896160897160898160899160900160901160902160903160904160905160906160907160908160909160910160911160912160913160914160915160916160917160918160919160920160921160922160923160924160925160926160927160928160929160930160931160932160933160934160935160936160937160938160939160940160941160942160943160944160945160946160947160948160949160950160951160952160953160954160955160956160957160958160959160960160961160962160963160964160965160966160967160968160969160970160971160972160973160974160975160976160977160978160979160980160981160982160983160984160985160986160987160988160989160990160991160992160993160994160995160996160997160998160999161000161001161002161003161004161005161006161007161008161009161010161011161012161013161014161015161016161017161018161019161020161021161022161023161024161025161026161027161028161029161030161031161032161033161034161035161036161037161038161039161040161041161042161043161044161045161046161047161048161049161050161051161052161053161054161055161056161057161058161059161060161061161062161063161064161065161066161067161068161069161070161071161072161073161074161075161076161077161078161079161080161081161082161083161084161085161086161087161088161089161090161091161092161093161094161095161096161097161098161099161100161101161102161103161104161105161106161107161108161109161110161111161112161113161114161115161116161117161118161119161120161121161122161123161124161125161126161127161128161129161130161131161132161133161134161135161136161137161138161139161140161141161142161143161144161145161146161147161148161149161150161151161152161153161154161155161156161157161158161159161160161161161162161163161164161165161166161167161168161169161170161171161172161173161174161175161176161177161178161179161180161181161182161183161184161185161186161187161188161189161190161191161192161193161194161195161196161197161198161199161200161201161202161203161204161205161206161207161208161209161210161211161212161213161214161215161216161217161218161219161220161221161222161223161224161225161226161227161228161229161230161231161232161233161234161235161236161237161238161239161240161241161242161243161244161245161246161247161248161249161250161251161252161253161254161255161256161257161258161259161260161261161262161263161264161265161266161267161268161269161270161271161272161273161274161275161276161277161278161279161280161281161282161283161284161285161286161287161288161289161290161291161292161293161294161295161296161297161298161299161300161301161302161303161304161305161306161307161308161309161310161311161312161313161314161315161316161317161318161319161320161321161322161323161324161325161326161327161328161329161330161331161332161333161334161335161336161337161338161339161340161341161342161343161344161345161346161347161348161349161350161351161352161353161354161355161356161357161358161359161360161361161362161363161364161365161366161367161368161369161370161371161372161373161374161375161376161377161378161379161380161381161382161383161384161385161386161387161388161389161390161391161392161393161394161395161396161397161398161399161400161401161402161403161404161405161406161407161408161409161410161411161412161413161414161415161416161417161418161419161420161421161422161423161424161425161426161427161428161429161430161431161432161433161434161435161436161437161438161439161440161441161442161443161444161445161446161447161448161449161450161451161452161453161454161455161456161457161458161459161460161461161462161463161464161465161466161467161468161469161470161471161472161473161474161475161476161477161478161479161480161481161482161483161484161485161486161487161488161489161490161491161492161493161494161495161496161497161498161499161500161501161502161503161504161505161506161507161508161509161510161511161512161513161514161515161516161517161518161519161520161521161522161523161524161525161526161527161528161529161530161531161532161533161534161535161536161537161538161539161540161541161542161543161544161545161546161547161548161549161550161551161552161553161554161555161556161557161558161559161560161561161562161563161564161565161566161567161568161569161570161571161572161573161574161575161576161577161578161579161580161581161582161583161584161585161586161587161588161589161590161591161592161593161594161595161596161597161598161599161600161601161602161603161604161605161606161607161608161609161610161611161612161613161614161615161616161617161618161619161620161621161622161623161624161625161626161627161628161629161630161631161632161633161634161635161636161637161638161639161640161641161642161643161644161645161646161647161648161649161650161651161652161653161654161655161656161657161658161659161660161661161662161663161664161665161666161667161668161669161670161671161672161673161674161675161676161677161678161679161680161681161682161683161684161685161686161687161688161689161690161691161692161693161694161695161696161697161698161699161700161701161702161703161704161705161706161707161708161709161710161711161712161713161714161715161716161717161718161719161720161721161722161723161724161725161726161727161728161729161730161731161732161733161734161735161736161737161738161739161740161741161742161743161744161745161746161747161748161749161750161751161752161753161754161755161756161757161758161759161760161761161762161763161764161765161766161767161768161769161770161771161772161773161774161775161776161777161778161779161780161781161782161783161784161785161786161787161788161789161790161791161792161793161794161795161796161797161798161799161800161801161802161803161804161805161806161807161808161809161810161811161812161813161814161815161816161817161818161819161820161821161822161823161824161825161826161827161828161829161830161831161832161833161834161835161836161837161838161839161840161841161842161843161844161845161846161847161848161849161850161851161852161853161854161855161856161857161858161859161860161861161862161863161864161865161866161867161868161869161870161871161872161873161874161875161876161877161878161879161880161881161882161883161884161885161886161887161888161889161890161891161892161893161894161895161896161897161898161899161900161901161902161903161904161905161906161907161908161909161910161911161912161913161914161915161916161917161918161919161920161921161922161923161924161925161926161927161928161929161930161931161932161933161934161935161936161937161938161939161940161941161942161943161944161945161946161947161948161949161950161951161952161953161954161955161956161957161958161959161960161961161962161963161964161965161966161967161968161969161970161971161972161973161974161975161976161977161978161979161980161981161982161983161984161985161986161987161988161989161990161991161992161993161994161995161996161997161998161999162000162001162002162003162004162005162006162007162008162009162010162011162012162013162014162015162016162017162018162019162020162021162022162023162024162025162026162027162028162029162030162031162032162033162034162035162036162037162038162039162040162041162042162043162044162045162046162047162048162049162050162051162052162053162054162055162056162057162058162059162060162061162062162063162064162065162066162067162068162069162070162071162072162073162074162075162076162077162078162079162080162081162082162083162084162085162086162087162088162089162090162091162092162093162094162095162096162097162098162099162100162101162102162103162104162105162106162107162108162109162110162111162112162113162114162115162116162117162118162119162120162121162122162123162124162125162126162127162128162129162130162131162132162133162134162135162136162137162138162139162140162141162142162143162144162145162146162147162148162149162150162151162152162153162154162155162156162157162158162159162160162161162162162163162164162165162166162167162168162169162170162171162172162173162174162175162176162177162178162179162180162181162182162183162184162185162186162187162188162189162190162191162192162193162194162195162196162197162198162199162200162201162202162203162204162205162206162207162208162209162210162211162212162213162214162215162216162217162218162219162220162221162222162223162224162225162226162227162228162229162230162231162232162233162234162235162236162237162238162239162240162241162242162243162244162245162246162247162248162249162250162251162252162253162254162255162256162257162258162259162260162261162262162263162264162265162266162267162268162269162270162271162272162273162274162275162276162277162278162279162280162281162282162283162284162285162286162287162288162289162290162291162292162293162294162295162296162297162298162299162300162301162302162303162304162305162306162307162308162309162310162311162312162313162314162315162316162317162318162319162320162321162322162323162324162325162326162327162328162329162330162331162332162333162334162335162336162337162338162339162340162341162342162343162344162345162346162347162348162349162350162351162352162353162354162355162356162357162358162359162360162361162362162363162364162365162366162367162368162369162370162371162372162373162374162375162376162377162378162379162380162381162382162383162384162385162386162387162388162389162390162391162392162393162394162395162396162397162398162399162400162401162402162403162404162405162406162407162408162409162410162411162412162413162414162415162416162417162418162419162420162421162422162423162424162425162426162427162428162429162430162431162432162433162434162435162436162437162438162439162440162441162442162443162444162445162446162447162448162449162450162451162452162453162454162455162456162457162458162459162460162461162462162463162464162465162466162467162468162469162470162471162472162473162474162475162476162477162478162479162480162481162482162483162484162485162486162487162488162489162490162491162492162493162494162495162496162497162498162499162500162501162502162503162504162505162506162507162508162509162510162511162512162513162514162515162516162517162518162519162520162521162522162523162524162525162526162527162528162529162530162531162532162533162534162535162536162537162538162539162540162541162542162543162544162545162546162547162548162549162550162551162552162553162554162555162556162557162558162559162560162561162562162563162564162565162566162567162568162569162570162571162572162573162574162575162576162577162578162579162580162581162582162583162584162585162586162587162588162589162590162591162592162593162594162595162596162597162598162599162600162601162602162603162604162605162606162607162608162609162610162611162612162613162614162615162616162617162618162619162620162621162622162623162624162625162626162627162628162629162630162631162632162633162634162635162636162637162638162639162640162641162642162643162644162645162646162647162648162649162650162651162652162653162654162655162656162657162658162659162660162661162662162663162664162665162666162667162668162669162670162671162672162673162674162675162676162677162678162679162680162681162682162683162684162685162686162687162688162689162690162691162692162693162694162695162696162697162698162699162700162701162702162703162704162705162706162707162708162709162710162711162712162713162714162715162716162717162718162719162720162721162722162723162724162725162726162727162728162729162730162731162732162733162734162735162736162737162738162739162740162741162742162743162744162745162746162747162748162749162750162751162752162753162754162755162756162757162758162759162760162761162762162763162764162765162766162767162768162769162770162771162772162773162774162775162776162777162778162779162780162781162782162783162784162785162786162787162788162789162790162791162792162793162794162795162796162797162798162799162800162801162802162803162804162805162806162807162808162809162810162811162812162813162814162815162816162817162818162819162820162821162822162823162824162825162826162827162828162829162830162831162832162833162834162835162836162837162838162839162840162841162842162843162844162845162846162847162848162849162850162851162852162853162854162855162856162857162858162859162860162861162862162863162864162865162866162867162868162869162870162871162872162873162874162875162876162877162878162879162880162881162882162883162884162885162886162887162888162889162890162891162892162893162894162895162896162897162898162899162900162901162902162903162904162905162906162907162908162909162910162911162912162913162914162915162916162917162918162919162920162921162922162923162924162925162926162927162928162929162930162931162932162933162934162935162936162937162938162939162940162941162942162943162944162945162946162947162948162949162950162951162952162953162954162955162956162957162958162959162960162961162962162963162964162965162966162967162968162969162970162971162972162973162974162975162976162977162978162979162980162981162982162983162984162985162986162987162988162989162990162991162992162993162994162995162996162997162998162999163000163001163002163003163004163005163006163007163008163009163010163011163012163013163014163015163016163017163018163019163020163021163022163023163024163025163026163027163028163029163030163031163032163033163034163035163036163037163038163039163040163041163042163043163044163045163046163047163048163049163050163051163052163053163054163055163056163057163058163059163060163061163062163063163064163065163066163067163068163069163070163071163072163073163074163075163076163077163078163079163080163081163082163083163084163085163086163087163088163089163090163091163092163093163094163095163096163097163098163099163100163101163102163103163104163105163106163107163108163109163110163111163112163113163114163115163116163117163118163119163120163121163122163123163124163125163126163127163128163129163130163131163132163133163134163135163136163137163138163139163140163141163142163143163144163145163146163147163148163149163150163151163152163153163154163155163156163157163158163159163160163161163162163163163164163165163166163167163168163169163170163171163172163173163174163175163176163177163178163179163180163181163182163183163184163185163186163187163188163189163190163191163192163193163194163195163196163197163198163199163200163201163202163203163204163205163206163207163208163209163210163211163212163213163214163215163216163217163218163219163220163221163222163223163224163225163226163227163228163229163230163231163232163233163234163235163236163237163238163239163240163241163242163243163244163245163246163247163248163249163250163251163252163253163254163255163256163257163258163259163260163261163262163263163264163265163266163267163268163269163270163271163272163273163274163275163276163277163278163279163280163281163282163283163284163285163286163287163288163289163290163291163292163293163294163295163296163297163298163299163300163301163302163303163304163305163306163307163308163309163310163311163312163313163314163315163316163317163318163319163320163321163322163323163324163325163326163327163328163329163330163331163332163333163334163335163336163337163338163339163340163341163342163343163344163345163346163347163348163349163350163351163352163353163354163355163356163357163358163359163360163361163362163363163364163365163366163367163368163369163370163371163372163373163374163375163376163377163378163379163380163381163382163383163384163385163386163387163388163389163390163391163392163393163394163395163396163397163398163399163400163401163402163403163404163405163406163407163408163409163410163411163412163413163414163415163416163417163418163419163420163421163422163423163424163425163426163427163428163429163430163431163432163433163434163435163436163437163438163439163440163441163442163443163444163445163446163447163448163449163450163451163452163453163454163455163456163457163458163459163460163461163462163463163464163465163466163467163468163469163470163471163472163473163474163475163476163477163478163479163480163481163482163483163484163485163486163487163488163489163490163491163492163493163494163495163496163497163498163499163500163501163502163503163504163505163506163507163508163509163510163511163512163513163514163515163516163517163518163519163520163521163522163523163524163525163526163527163528163529163530163531163532163533163534163535163536163537163538163539163540163541163542163543163544163545163546163547163548163549163550163551163552163553163554163555163556163557163558163559163560163561163562163563163564163565163566163567163568163569163570163571163572163573163574163575163576163577163578163579163580163581163582163583163584163585163586163587163588163589163590163591163592163593163594163595163596163597163598163599163600163601163602163603163604163605163606163607163608163609163610163611163612163613163614163615163616163617163618163619163620163621163622163623163624163625163626163627163628163629163630163631163632163633163634163635163636163637163638163639163640163641163642163643163644163645163646163647163648163649163650163651163652163653163654163655163656163657163658163659163660163661163662163663163664163665163666163667163668163669163670163671163672163673163674163675163676163677163678163679163680163681163682163683163684163685163686163687163688163689163690163691163692163693163694163695163696163697163698163699163700163701163702163703163704163705163706163707163708163709163710163711163712163713163714163715163716163717163718163719163720163721163722163723163724163725163726163727163728163729163730163731163732163733163734163735163736163737163738163739163740163741163742163743163744163745163746163747163748163749163750163751163752163753163754163755163756163757163758163759163760163761163762163763163764163765163766163767163768163769163770163771163772163773163774163775163776163777163778163779163780163781163782163783163784163785163786163787163788163789163790163791163792163793163794163795163796163797163798163799163800163801163802163803163804163805163806163807163808163809163810163811163812163813163814163815163816163817163818163819163820163821163822163823163824163825163826163827163828163829163830163831163832163833163834163835163836163837163838163839163840163841163842163843163844163845163846163847163848163849163850163851163852163853163854163855163856163857163858163859163860163861163862163863163864163865163866163867163868163869163870163871163872163873163874163875163876163877163878163879163880163881163882163883163884163885163886163887163888163889163890163891163892163893163894163895163896163897163898163899163900163901163902163903163904163905163906163907163908163909163910163911163912163913163914163915163916163917163918163919163920163921163922163923163924163925163926163927163928163929163930163931163932163933163934163935163936163937163938163939163940163941163942163943163944163945163946163947163948163949163950163951163952163953163954163955163956163957163958163959163960163961163962163963163964163965163966163967163968163969163970163971163972163973163974163975163976163977163978163979163980163981163982163983163984163985163986163987163988163989163990163991163992163993163994163995163996163997163998163999164000164001164002164003164004164005164006164007164008164009164010164011164012164013164014164015164016164017164018164019164020164021164022164023164024164025164026164027164028164029164030164031164032164033164034164035164036164037164038164039164040164041164042164043164044164045164046164047164048164049164050164051164052164053164054164055164056164057164058164059164060164061164062164063164064164065164066164067164068164069164070164071164072164073164074164075164076164077164078164079164080164081164082164083164084164085164086164087164088164089164090164091164092164093164094164095164096164097164098164099164100164101164102164103164104164105164106164107164108164109164110164111164112164113164114164115164116164117164118164119164120164121164122164123164124164125164126164127164128164129164130164131164132164133164134164135164136164137164138164139164140164141164142164143164144164145164146164147164148164149164150164151164152164153164154164155164156164157164158164159164160164161164162164163164164164165164166164167164168164169164170164171164172164173164174164175164176164177164178164179164180164181164182164183164184164185164186164187164188164189164190164191164192164193164194164195164196164197164198164199164200164201164202164203164204164205164206164207164208164209164210164211164212164213164214164215164216164217164218164219164220164221164222164223164224164225164226164227164228164229164230164231164232164233164234164235164236164237164238164239164240164241164242164243164244164245164246164247164248164249164250164251164252164253164254164255164256164257164258164259164260164261164262164263164264164265164266164267164268164269164270164271164272164273164274164275164276164277164278164279164280164281164282164283164284164285164286164287164288164289164290164291164292164293164294164295164296164297164298164299164300164301164302164303164304164305164306164307164308164309164310164311164312164313164314164315164316164317164318164319164320164321164322164323164324164325164326164327164328164329164330164331164332164333164334164335164336164337164338164339164340164341164342164343164344164345164346164347164348164349164350164351164352164353164354164355164356164357164358164359164360164361164362164363164364164365164366164367164368164369164370164371164372164373164374164375164376164377164378164379164380164381164382164383164384164385164386164387164388164389164390164391164392164393164394164395164396164397164398164399164400164401164402164403164404164405164406164407164408164409164410164411164412164413164414164415164416164417164418164419164420164421164422164423164424164425164426164427164428164429164430164431164432164433164434164435164436164437164438164439164440164441164442164443164444164445164446164447164448164449164450164451164452164453164454164455164456164457164458164459164460164461164462164463164464164465164466164467164468164469164470164471164472164473164474164475164476164477164478164479164480164481164482164483164484164485164486164487164488164489164490164491164492164493164494164495164496164497164498164499164500164501164502164503164504164505164506164507164508164509164510164511164512164513164514164515164516164517164518164519164520164521164522164523164524164525164526164527164528164529164530164531164532164533164534164535164536164537164538164539164540164541164542164543164544164545164546164547164548164549164550164551164552164553164554164555164556164557164558164559164560164561164562164563164564164565164566164567164568164569164570164571164572164573164574164575164576164577164578164579164580164581164582164583164584164585164586164587164588164589164590164591164592164593164594164595164596164597164598164599164600164601164602164603164604164605164606164607164608164609164610164611164612164613164614164615164616164617164618164619164620164621164622164623164624164625164626164627164628164629164630164631164632164633164634164635164636164637164638164639164640164641164642164643164644164645164646164647164648164649164650164651164652164653164654164655164656164657164658164659164660164661164662164663164664164665164666164667164668164669164670164671164672164673164674164675164676164677164678164679164680164681164682164683164684164685164686164687164688164689164690164691164692164693164694164695164696164697164698164699164700164701164702164703164704164705164706164707164708164709164710164711164712164713164714164715164716164717164718164719164720164721164722164723164724164725164726164727164728164729164730164731164732164733164734164735164736164737164738164739164740164741164742164743164744164745164746164747164748164749164750164751164752164753164754164755164756164757164758164759164760164761164762164763164764164765164766164767164768164769164770164771164772164773164774164775164776164777164778164779164780164781164782164783164784164785164786164787164788164789164790164791164792164793164794164795164796164797164798164799164800164801164802164803164804164805164806164807164808164809164810164811164812164813164814164815164816164817164818164819164820164821164822164823164824164825164826164827164828164829164830164831164832164833164834164835164836164837164838164839164840164841164842164843164844164845164846164847164848164849164850164851164852164853164854164855164856164857164858164859164860164861164862164863164864164865164866164867164868164869164870164871164872164873164874164875164876164877164878164879164880164881164882164883164884164885164886164887164888164889164890164891164892164893164894164895164896164897164898164899164900164901164902164903164904164905164906164907164908164909164910164911164912164913164914164915164916164917164918164919164920164921164922164923164924164925164926164927164928164929164930164931164932164933164934164935164936164937164938164939164940164941164942164943164944164945164946164947164948164949164950164951164952164953164954164955164956164957164958164959164960164961164962164963164964164965164966164967164968164969164970164971164972164973164974164975164976164977164978164979164980164981164982164983164984164985164986164987164988164989164990164991164992164993164994164995164996164997164998164999165000165001165002165003165004165005165006165007165008165009165010165011165012165013165014165015165016165017165018165019165020165021165022165023165024165025165026165027165028165029165030165031165032165033165034165035165036165037165038165039165040165041165042165043165044165045165046165047165048165049165050165051165052165053165054165055165056165057165058165059165060165061165062165063165064165065165066165067165068165069165070165071165072165073165074165075165076165077165078165079165080165081165082165083165084165085165086165087165088165089165090165091165092165093165094165095165096165097165098165099165100165101165102165103165104165105165106165107165108165109165110165111165112165113165114165115165116165117165118165119165120165121165122165123165124165125165126165127165128165129165130165131165132165133165134165135165136165137165138165139165140165141165142165143165144165145165146165147165148165149165150165151165152165153165154165155165156165157165158165159165160165161165162165163165164165165165166165167165168165169165170165171165172165173165174165175165176165177165178165179165180165181165182165183165184165185165186165187165188165189165190165191165192165193165194165195165196165197165198165199165200165201165202165203165204165205165206165207165208165209165210165211165212165213165214165215165216165217165218165219165220165221165222165223165224165225165226165227165228165229165230165231165232165233165234165235165236165237165238165239165240165241165242165243165244165245165246165247165248165249165250165251165252165253165254165255165256165257165258165259165260165261165262165263165264165265165266165267165268165269165270165271165272165273165274165275165276165277165278165279165280165281165282165283165284165285165286165287165288165289165290165291165292165293165294165295165296165297165298165299165300165301165302165303165304165305165306165307165308165309165310165311165312165313165314165315165316165317165318165319165320165321165322165323165324165325165326165327165328165329165330165331165332165333165334165335165336165337165338165339165340165341165342165343165344165345165346165347165348165349165350165351165352165353165354165355165356165357165358165359165360165361165362165363165364165365165366165367165368165369165370165371165372165373165374165375165376165377165378165379165380165381165382165383165384165385165386165387165388165389165390165391165392165393165394165395165396165397165398165399165400165401165402165403165404165405165406165407165408165409165410165411165412165413165414165415165416165417165418165419165420165421165422165423165424165425165426165427165428165429165430165431165432165433165434165435165436165437165438165439165440165441165442165443165444165445165446165447165448165449165450165451165452165453165454165455165456165457165458165459165460165461165462165463165464165465165466165467165468165469165470165471165472165473165474165475165476165477165478165479165480165481165482165483165484165485165486165487165488165489165490165491165492165493165494165495165496165497165498165499165500165501165502165503165504165505165506165507165508165509165510165511165512165513165514165515165516165517165518165519165520165521165522165523165524165525165526165527165528165529165530165531165532165533165534165535165536165537165538165539165540165541165542165543165544165545165546165547165548165549165550165551165552165553165554165555165556165557165558165559165560165561165562165563165564165565165566165567165568165569165570165571165572165573165574165575165576165577165578165579165580165581165582165583165584165585165586165587165588165589165590165591165592165593165594165595165596165597165598165599165600165601165602165603165604165605165606165607165608165609165610165611165612165613165614165615165616165617165618165619165620165621165622165623165624165625165626165627165628165629165630165631165632165633165634165635165636165637165638165639165640165641165642165643165644165645165646165647165648165649165650165651165652165653165654165655165656165657165658165659165660165661165662165663165664165665165666165667165668165669165670165671165672165673165674165675165676165677165678165679165680165681165682165683165684165685165686165687165688165689165690165691165692165693165694165695165696165697165698165699165700165701165702165703165704165705165706165707165708165709165710165711165712165713165714165715165716165717165718165719165720165721165722165723165724165725165726165727165728165729165730165731165732165733165734165735165736165737165738165739165740165741165742165743165744165745165746165747165748165749165750165751165752165753165754165755165756165757165758165759165760165761165762165763165764165765165766165767165768165769165770165771165772165773165774165775165776165777165778165779165780165781165782165783165784165785165786165787165788165789165790165791165792165793165794165795165796165797165798165799165800165801165802165803165804165805165806165807165808165809165810165811165812165813165814165815165816165817165818165819165820165821165822165823165824165825165826165827165828165829165830165831165832165833165834165835165836165837165838165839165840165841165842165843165844165845165846165847165848165849165850165851165852165853165854165855165856165857165858165859165860165861165862165863165864165865165866165867165868165869165870165871165872165873165874165875165876165877165878165879165880165881165882165883165884165885165886165887165888165889165890165891165892165893165894165895165896165897165898165899165900165901165902165903165904165905165906165907165908165909165910165911165912165913165914165915165916165917165918165919165920165921165922165923165924165925165926165927165928165929165930165931165932165933165934165935165936165937165938165939165940165941165942165943165944165945165946165947165948165949165950165951165952165953165954165955165956165957165958165959165960165961165962165963165964165965165966165967165968165969165970165971165972165973165974165975165976165977165978165979165980165981165982165983165984165985165986165987165988165989165990165991165992165993165994165995165996165997165998165999166000166001166002166003166004166005166006166007166008166009166010166011166012166013166014166015166016166017166018166019166020166021166022166023166024166025166026166027166028166029166030166031166032166033166034166035166036166037166038166039166040166041166042166043166044166045166046166047166048166049166050166051166052166053166054166055166056166057166058166059166060166061166062166063166064166065166066166067166068166069166070166071166072166073166074166075166076166077166078166079166080166081166082166083166084166085166086166087166088166089166090166091166092166093166094166095166096166097166098166099166100166101166102166103166104166105166106166107166108166109166110166111166112166113166114166115166116166117166118166119166120166121166122166123166124166125166126166127166128166129166130166131166132166133166134166135166136166137166138166139166140166141166142166143166144166145166146166147166148166149166150166151166152166153166154166155166156166157166158166159166160166161166162166163166164166165166166166167166168166169166170166171166172166173166174166175166176166177166178166179166180166181166182166183166184166185166186166187166188166189166190166191166192166193166194166195166196166197166198166199166200166201166202166203166204166205166206166207166208166209166210166211166212166213166214166215166216166217166218166219166220166221166222166223166224166225166226166227166228166229166230166231166232166233166234166235166236166237166238166239166240166241166242166243166244166245166246166247166248166249166250166251166252166253166254166255166256166257166258166259166260166261166262166263166264166265166266166267166268166269166270166271166272166273166274166275166276166277166278166279166280166281166282166283166284166285166286166287166288166289166290166291166292166293166294166295166296166297166298166299166300166301166302166303166304166305166306166307166308166309166310166311166312166313166314166315166316166317166318166319166320166321166322166323166324166325166326166327166328166329166330166331166332166333166334166335166336166337166338166339166340166341166342166343166344166345166346166347166348166349166350166351166352166353166354166355166356166357166358166359166360166361166362166363166364166365166366166367166368166369166370166371166372166373166374166375166376166377166378166379166380166381166382166383166384166385166386166387166388166389166390166391166392166393166394166395166396166397166398166399166400166401166402166403166404166405166406166407166408166409166410166411166412166413166414166415166416166417166418166419166420166421166422166423166424166425166426166427166428166429166430166431166432166433166434166435166436166437166438166439166440166441166442166443166444166445166446166447166448166449166450166451166452166453166454166455166456166457166458166459166460166461166462166463166464166465166466166467166468166469166470166471166472166473166474166475166476166477166478166479166480166481166482166483166484166485166486166487166488166489166490166491166492166493166494166495166496166497166498166499166500166501166502166503166504166505166506166507166508166509166510166511166512166513166514166515166516166517166518166519166520166521166522166523166524166525166526166527166528166529166530166531166532166533166534166535166536166537166538166539166540166541166542166543166544166545166546166547166548166549166550166551166552166553166554166555166556166557166558166559166560166561166562166563166564166565166566166567166568166569166570166571166572166573166574166575166576166577166578166579166580166581166582166583166584166585166586166587166588166589166590166591166592166593166594166595166596166597166598166599166600166601166602166603166604166605166606166607166608166609166610166611166612166613166614166615166616166617166618166619166620166621166622166623166624166625166626166627166628166629166630166631166632166633166634166635166636166637166638166639166640166641166642166643166644166645166646166647166648166649166650166651166652166653166654166655166656166657166658166659166660166661166662166663166664166665166666166667166668166669166670166671166672166673166674166675166676166677166678166679166680166681166682166683166684166685166686166687166688166689166690166691166692166693166694166695166696166697166698166699166700166701166702166703166704166705166706166707166708166709166710166711166712166713166714166715166716166717166718166719166720166721166722166723166724166725166726166727166728166729166730166731166732166733166734166735166736166737166738166739166740166741166742166743166744166745166746166747166748166749166750166751166752166753166754166755166756166757166758166759166760166761166762166763166764166765166766166767166768166769166770166771166772166773166774166775166776166777166778166779166780166781166782166783166784166785166786166787166788166789166790166791166792166793166794166795166796166797166798166799166800166801166802166803166804166805166806166807166808166809166810166811166812166813166814166815166816166817166818166819166820166821166822166823166824166825166826166827166828166829166830166831166832166833166834166835166836166837166838166839166840166841166842166843166844166845166846166847166848166849166850166851166852166853166854166855166856166857166858166859166860166861166862166863166864166865166866166867166868166869166870166871166872166873166874166875166876166877166878166879166880166881166882166883166884166885166886166887166888166889166890166891166892166893166894166895166896166897166898166899166900166901166902166903166904166905166906166907166908166909166910166911166912166913166914166915166916166917166918166919166920166921166922166923166924166925166926166927166928166929166930166931166932166933166934166935166936166937166938166939166940166941166942166943166944166945166946166947166948166949166950166951166952166953166954166955166956166957166958166959166960166961166962166963166964166965166966166967166968166969166970166971166972166973166974166975166976166977166978166979166980166981166982166983166984166985166986166987166988166989166990166991166992166993166994166995166996166997166998166999167000167001167002167003167004167005167006167007167008167009167010167011167012167013167014167015167016167017167018167019167020167021167022167023167024167025167026167027167028167029167030167031167032167033167034167035167036167037167038167039167040167041167042167043167044167045167046167047167048167049167050167051167052167053167054167055167056167057167058167059167060167061167062167063167064167065167066167067167068167069167070167071167072167073167074167075167076167077167078167079167080167081167082167083167084167085167086167087167088167089167090167091167092167093167094167095167096167097167098167099167100167101167102167103167104167105167106167107167108167109167110167111167112167113167114167115167116167117167118167119167120167121167122167123167124167125167126167127167128167129167130167131167132167133167134167135167136167137167138167139167140167141167142167143167144167145167146167147167148167149167150167151167152167153167154167155167156167157167158167159167160167161167162167163167164167165167166167167167168167169167170167171167172167173167174167175167176167177167178167179167180167181167182167183167184167185167186167187167188167189167190167191167192167193167194167195167196167197167198167199167200167201167202167203167204167205167206167207167208167209167210167211167212167213167214167215167216167217167218167219167220167221167222167223167224167225167226167227167228167229167230167231167232167233167234167235167236167237167238167239167240167241167242167243167244167245167246167247167248167249167250167251167252167253167254167255167256167257167258167259167260167261167262167263167264167265167266167267167268167269167270167271167272167273167274167275167276167277167278167279167280167281167282167283167284167285167286167287167288167289167290167291167292167293167294167295167296167297167298167299167300167301167302167303167304167305167306167307167308167309167310167311167312167313167314167315167316167317167318167319167320167321167322167323167324167325167326167327167328167329167330167331167332167333167334167335167336167337167338167339167340167341167342167343167344167345167346167347167348167349167350167351167352167353167354167355167356167357167358167359167360167361167362167363167364167365167366167367167368167369167370167371167372167373167374167375167376167377167378167379167380167381167382167383167384167385167386167387167388167389167390167391167392167393167394167395167396167397167398167399167400167401167402167403167404167405167406167407167408167409167410167411167412167413167414167415167416167417167418167419167420167421167422167423167424167425167426167427167428167429167430167431167432167433167434167435167436167437167438167439167440167441167442167443167444167445167446167447167448167449167450167451167452167453167454167455167456167457167458167459167460167461167462167463167464167465167466167467167468167469167470167471167472167473167474167475167476167477167478167479167480167481167482167483167484167485167486167487167488167489167490167491167492167493167494167495167496167497167498167499167500167501167502167503167504167505167506167507167508167509167510167511167512167513167514167515167516167517167518167519167520167521167522167523167524167525167526167527167528167529167530167531167532167533167534167535167536167537167538167539167540167541167542167543167544167545167546167547167548167549167550167551167552167553167554167555167556167557167558167559167560167561167562167563167564167565167566167567167568167569167570167571167572167573167574167575167576167577167578167579167580167581167582167583167584167585167586167587167588167589167590167591167592167593167594167595167596167597167598167599167600167601167602167603167604167605167606167607167608167609167610167611167612167613167614167615167616167617167618167619167620167621167622167623167624167625167626167627167628167629167630167631167632167633167634167635167636167637167638167639167640167641167642167643167644167645167646167647167648167649167650167651167652167653167654167655167656167657167658167659167660167661167662167663167664167665167666167667167668167669167670167671167672167673167674167675167676167677167678167679167680167681167682167683167684167685167686167687167688167689167690167691167692167693167694167695167696167697167698167699167700167701167702167703167704167705167706167707167708167709167710167711167712167713167714167715167716167717167718167719167720167721167722167723167724167725167726167727167728167729167730167731167732167733167734167735167736167737167738167739167740167741167742167743167744167745167746167747167748167749167750167751167752167753167754167755167756167757167758167759167760167761167762167763167764167765167766167767167768167769167770167771167772167773167774167775167776167777167778167779167780167781167782167783167784167785167786167787167788167789167790167791167792167793167794167795167796167797167798167799167800167801167802167803167804167805167806167807167808167809167810167811167812167813167814167815167816167817167818167819167820167821167822167823167824167825167826167827167828167829167830167831167832167833167834167835167836167837167838167839167840167841167842167843167844167845167846167847167848167849167850167851167852167853167854167855167856167857167858167859167860167861167862167863167864167865167866167867167868167869167870167871167872167873167874167875167876167877167878167879167880167881167882167883167884167885167886167887167888167889167890167891167892167893167894167895167896167897167898167899167900167901167902167903167904167905167906167907167908167909167910167911167912167913167914167915167916167917167918167919167920167921167922167923167924167925167926167927167928167929167930167931167932167933167934167935167936167937167938167939167940167941167942167943167944167945167946167947167948167949167950167951167952167953167954167955167956167957167958167959167960167961167962167963167964167965167966167967167968167969167970167971167972167973167974167975167976167977167978167979167980167981167982167983167984167985167986167987167988167989167990167991167992167993167994167995167996167997167998167999168000168001168002168003168004168005168006168007168008168009168010168011168012168013168014168015168016168017168018168019168020168021168022168023168024168025168026168027168028168029168030168031168032168033168034168035168036168037168038168039168040168041168042168043168044168045168046168047168048168049168050168051168052168053168054168055168056168057168058168059168060168061168062168063168064168065168066168067168068168069168070168071168072168073168074168075168076168077168078168079168080168081168082168083168084168085168086168087168088168089168090168091168092168093168094168095168096168097168098168099168100168101168102168103168104168105168106168107168108168109168110168111168112168113168114168115168116168117168118168119168120168121168122168123168124168125168126168127168128168129168130168131168132168133168134168135168136168137168138168139168140168141168142168143168144168145168146168147168148168149168150168151168152168153168154168155168156168157168158168159168160168161168162168163168164168165168166168167168168168169168170168171168172168173168174168175168176168177168178168179168180168181168182168183168184168185168186168187168188168189168190168191168192168193168194168195168196168197168198168199168200168201168202168203168204168205168206168207168208168209168210168211168212168213168214168215168216168217168218168219168220168221168222168223168224168225168226168227168228168229168230168231168232168233168234168235168236168237168238168239168240168241168242168243168244168245168246168247168248168249168250168251168252168253168254168255168256168257168258168259168260168261168262168263168264168265168266168267168268168269168270168271168272168273168274168275168276168277168278168279168280168281168282168283168284168285168286168287168288168289168290168291168292168293168294168295168296168297168298168299168300168301168302168303168304168305168306168307168308168309168310168311168312168313168314168315168316168317168318168319168320168321168322168323168324168325168326168327168328168329168330168331168332168333168334168335168336168337168338168339168340168341168342168343168344168345168346168347168348168349168350168351168352168353168354168355168356168357168358168359168360168361168362168363168364168365168366168367168368168369168370168371168372168373168374168375168376168377168378168379168380168381168382168383168384168385168386168387168388168389168390168391168392168393168394168395168396168397168398168399168400168401168402168403168404168405168406168407168408168409168410168411168412168413168414168415168416168417168418168419168420168421168422168423168424168425168426168427168428168429168430168431168432168433168434168435168436168437168438168439168440168441168442168443168444168445168446168447168448168449168450168451168452168453168454168455168456168457168458168459168460168461168462168463168464168465168466168467168468168469168470168471168472168473168474168475168476168477168478168479168480168481168482168483168484168485168486168487168488168489168490168491168492168493168494168495168496168497168498168499168500168501168502168503168504168505168506168507168508168509168510168511168512168513168514168515168516168517168518168519168520168521168522168523168524168525168526168527168528168529168530168531168532168533168534168535168536168537168538168539168540168541168542168543168544168545168546168547168548168549168550168551168552168553168554168555168556168557168558168559168560168561168562168563168564168565168566168567168568168569168570168571168572168573168574168575168576168577168578168579168580168581168582168583168584168585168586168587168588168589168590168591168592168593168594168595168596168597168598168599168600168601168602168603168604168605168606168607168608168609168610168611168612168613168614168615168616168617168618168619168620168621168622168623168624168625168626168627168628168629168630168631168632168633168634168635168636168637168638168639168640168641168642168643168644168645168646168647168648168649168650168651168652168653168654168655168656168657168658168659168660168661168662168663168664168665168666168667168668168669168670168671168672168673168674168675168676168677168678168679168680168681168682168683168684168685168686168687168688168689168690168691168692168693168694168695168696168697168698168699168700168701168702168703168704168705168706168707168708168709168710168711168712168713168714168715168716168717168718168719168720168721168722168723168724168725168726168727168728168729168730168731168732168733168734168735168736168737168738168739168740168741168742168743168744168745168746168747168748168749168750168751168752168753168754168755168756168757168758168759168760168761168762168763168764168765168766168767168768168769168770168771168772168773168774168775168776168777168778168779168780168781168782168783168784168785168786168787168788168789168790168791168792168793168794168795168796168797168798168799168800168801168802168803168804168805168806168807168808168809168810168811168812168813168814168815168816168817168818168819168820168821168822168823168824168825168826168827168828168829168830168831168832168833168834168835168836168837168838168839168840168841168842168843168844168845168846168847168848168849168850168851168852168853168854168855168856168857168858168859168860168861168862168863168864168865168866168867168868168869168870168871168872168873168874168875168876168877168878168879168880168881168882168883168884168885168886168887168888168889168890168891168892168893168894168895168896168897168898168899168900168901168902168903168904168905168906168907168908168909168910168911168912168913168914168915168916168917168918168919168920168921168922168923168924168925168926168927168928168929168930168931168932168933168934168935168936168937168938168939168940168941168942168943168944168945168946168947168948168949168950168951168952168953168954168955168956168957168958168959168960168961168962168963168964168965168966168967168968168969168970168971168972168973168974168975168976168977168978168979168980168981168982168983168984168985168986168987168988168989168990168991168992168993168994168995168996168997168998168999169000169001169002169003169004169005169006169007169008169009169010169011169012169013169014169015169016169017169018169019169020169021169022169023169024169025169026169027169028169029169030169031169032169033169034169035169036169037169038169039169040169041169042169043169044169045169046169047169048169049169050169051169052169053169054169055169056169057169058169059169060169061169062169063169064169065169066169067169068169069169070169071169072169073169074169075169076169077169078169079169080169081169082169083169084169085169086169087169088169089169090169091169092169093169094169095169096169097169098169099169100169101169102169103169104169105169106169107169108169109169110169111169112169113169114169115169116169117169118169119169120169121169122169123169124169125169126169127169128169129169130169131169132169133169134169135169136169137169138169139169140169141169142169143169144169145169146169147169148169149169150169151169152169153169154169155169156169157169158169159169160169161169162169163169164169165169166169167169168169169169170169171169172169173169174169175169176169177169178169179169180169181169182169183169184169185169186169187169188169189169190169191169192169193169194169195169196169197169198169199169200169201169202169203169204169205169206169207169208169209169210169211169212169213169214169215169216169217169218169219169220169221169222169223169224169225169226169227169228169229169230169231169232169233169234169235169236169237169238169239169240169241169242169243169244169245169246169247169248169249169250169251169252169253169254169255169256169257169258169259169260169261169262169263169264169265169266169267169268169269169270169271169272169273169274169275169276169277169278169279169280169281169282169283169284169285169286169287169288169289169290169291169292169293169294169295169296169297169298169299169300169301169302169303169304169305169306169307169308169309169310169311169312169313169314169315169316169317169318169319169320169321169322169323169324169325169326169327169328169329169330169331169332169333169334169335169336169337169338169339169340169341169342169343169344169345169346169347169348169349169350169351169352169353169354169355169356169357169358169359169360169361169362169363169364169365169366169367169368169369169370169371169372169373169374169375169376169377169378169379169380169381169382169383169384169385169386169387169388169389169390169391169392169393169394169395169396169397169398169399169400169401169402169403169404169405169406169407169408169409169410169411169412169413169414169415169416169417169418169419169420169421169422169423169424169425169426169427169428169429169430169431169432169433169434169435169436169437169438169439169440169441169442169443169444169445169446169447169448169449169450169451169452169453169454169455169456169457169458169459169460169461169462169463169464169465169466169467169468169469169470169471169472169473169474169475169476169477169478169479169480169481169482169483169484169485169486169487169488169489169490169491169492169493169494169495169496169497169498169499169500169501169502169503169504169505169506169507169508169509169510169511169512169513169514169515169516169517169518169519169520169521169522169523169524169525169526169527169528169529169530169531169532169533169534169535169536169537169538169539169540169541169542169543169544169545169546169547169548169549169550169551169552169553169554169555169556169557169558169559169560169561169562169563169564169565169566169567169568169569169570169571169572169573169574169575169576169577169578169579169580169581169582169583169584169585169586169587169588169589169590169591169592169593169594169595169596169597169598169599169600169601169602169603169604169605169606169607169608169609169610169611169612169613169614169615169616169617169618169619169620169621169622169623169624169625169626169627169628169629169630169631169632169633169634169635169636169637169638169639169640169641169642169643169644169645169646169647169648169649169650169651169652169653169654169655169656169657169658169659169660169661169662169663169664169665169666169667169668169669169670169671169672169673169674169675169676169677169678169679169680169681169682169683169684169685169686169687169688169689169690169691169692169693169694169695169696169697169698169699169700169701169702169703169704169705169706169707169708169709169710169711169712169713169714169715169716169717169718169719169720169721169722169723169724169725169726169727169728169729169730169731169732169733169734169735169736169737169738169739169740169741169742169743169744169745169746169747169748169749169750169751169752169753169754169755169756169757169758169759169760169761169762169763169764169765169766169767169768169769169770169771169772169773169774169775169776169777169778169779169780169781169782169783169784169785169786169787169788169789169790169791169792169793169794169795169796169797169798169799169800169801169802169803169804169805169806169807169808169809169810169811169812169813169814169815169816169817169818169819169820169821169822169823169824169825169826169827169828169829169830169831169832169833169834169835169836169837169838169839169840169841169842169843169844169845169846169847169848169849169850169851169852169853169854169855169856169857169858169859169860169861169862169863169864169865169866169867169868169869169870169871169872169873169874169875169876169877169878169879169880169881169882169883169884169885169886169887169888169889169890169891169892169893169894169895169896169897169898169899169900169901169902169903169904169905169906169907169908169909169910169911169912169913169914169915169916169917169918169919169920169921169922169923169924169925169926169927169928169929169930169931169932169933169934169935169936169937169938169939169940169941169942169943169944169945169946169947169948169949169950169951169952169953169954169955169956169957169958169959169960169961169962169963169964169965169966169967169968169969169970169971169972169973169974169975169976169977169978169979169980169981169982169983169984169985169986169987169988169989169990169991169992169993169994169995169996169997169998169999170000170001170002170003170004170005170006170007170008170009170010170011170012170013170014170015170016170017170018170019170020170021170022170023170024170025170026170027170028170029170030170031170032170033170034170035170036170037170038170039170040170041170042170043170044170045170046170047170048170049170050170051170052170053170054170055170056170057170058170059170060170061170062170063170064170065170066170067170068170069170070170071170072170073170074170075170076170077170078170079170080170081170082170083170084170085170086170087170088170089170090170091170092170093170094170095170096170097170098170099170100170101170102170103170104170105170106170107170108170109170110170111170112170113170114170115170116170117170118170119170120170121170122170123170124170125170126170127170128170129170130170131170132170133170134170135170136170137170138170139170140170141170142170143170144170145170146170147170148170149170150170151170152170153170154170155170156170157170158170159170160170161170162170163170164170165170166170167170168170169170170170171170172170173170174170175170176170177170178170179170180170181170182170183170184170185170186170187170188170189170190170191170192170193170194170195170196170197170198170199170200170201170202170203170204170205170206170207170208170209170210170211170212170213170214170215170216170217170218170219170220170221170222170223170224170225170226170227170228170229170230170231170232170233170234170235170236170237170238170239170240170241170242170243170244170245170246170247170248170249170250170251170252170253170254170255170256170257170258170259170260170261170262170263170264170265170266170267170268170269170270170271170272170273170274170275170276170277170278170279170280170281170282170283170284170285170286170287170288170289170290170291170292170293170294170295170296170297170298170299170300170301170302170303170304170305170306170307170308170309170310170311170312170313170314170315170316170317170318170319170320170321170322170323170324170325170326170327170328170329170330170331170332170333170334170335170336170337170338170339170340170341170342170343170344170345170346170347170348170349170350170351170352170353170354170355170356170357170358170359170360170361170362170363170364170365170366170367170368170369170370170371170372170373170374170375170376170377170378170379170380170381170382170383170384170385170386170387170388170389170390170391170392170393170394170395170396170397170398170399170400170401170402170403170404170405170406170407170408170409170410170411170412170413170414170415170416170417170418170419170420170421170422170423170424170425170426170427170428170429170430170431170432170433170434170435170436170437170438170439170440170441170442170443170444170445170446170447170448170449170450170451170452170453170454170455170456170457170458170459170460170461170462170463170464170465170466170467170468170469170470170471170472170473170474170475170476170477170478170479170480170481170482170483170484170485170486170487170488170489170490170491170492170493170494170495170496170497170498170499170500170501170502170503170504170505170506170507170508170509170510170511170512170513170514170515170516170517170518170519170520170521170522170523170524170525170526170527170528170529170530170531170532170533170534170535170536170537170538170539170540170541170542170543170544170545170546170547170548170549170550170551170552170553170554170555170556170557170558170559170560170561170562170563170564170565170566170567170568170569170570170571170572170573170574170575170576170577170578170579170580170581170582170583170584170585170586170587170588170589170590170591170592170593170594170595170596170597170598170599170600170601170602170603170604170605170606170607170608170609170610170611170612170613170614170615170616170617170618170619170620170621170622170623170624170625170626170627170628170629170630170631170632170633170634170635170636170637170638170639170640170641170642170643170644170645170646170647170648170649170650170651170652170653170654170655170656170657170658170659170660170661170662170663170664170665170666170667170668170669170670170671170672170673170674170675170676170677170678170679170680170681170682170683170684170685170686170687170688170689170690170691170692170693170694170695170696170697170698170699170700170701170702170703170704170705170706170707170708170709170710170711170712170713170714170715170716170717170718170719170720170721170722170723170724170725170726170727170728170729170730170731170732170733170734170735170736170737170738170739170740170741170742170743170744170745170746170747170748170749170750170751170752170753170754170755170756170757170758170759170760170761170762170763170764170765170766170767170768170769170770170771170772170773170774170775170776170777170778170779170780170781170782170783170784170785170786170787170788170789170790170791170792170793170794170795170796170797170798170799170800170801170802170803170804170805170806170807170808170809170810170811170812170813170814170815170816170817170818170819170820170821170822170823170824170825170826170827170828170829170830170831170832170833170834170835170836170837170838170839170840170841170842170843170844170845170846170847170848170849170850170851170852170853170854170855170856170857170858170859170860170861170862170863170864170865170866170867170868170869170870170871170872170873170874170875170876170877170878170879170880170881170882170883170884170885170886170887170888170889170890170891170892170893170894170895170896170897170898170899170900170901170902170903170904170905170906170907170908170909170910170911170912170913170914170915170916170917170918170919170920170921170922170923170924170925170926170927170928170929170930170931170932170933170934170935170936170937170938170939170940170941170942170943170944170945170946170947170948170949170950170951170952170953170954170955170956170957170958170959170960170961170962170963170964170965170966170967170968170969170970170971170972170973170974170975170976170977170978170979170980170981170982170983170984170985170986170987170988170989170990170991170992170993170994170995170996170997170998170999171000171001171002171003171004171005171006171007171008171009171010171011171012171013171014171015171016171017171018171019171020171021171022171023171024171025171026171027171028171029171030171031171032171033171034171035171036171037171038171039171040171041171042171043171044171045171046171047171048171049171050171051171052171053171054171055171056171057171058171059171060171061171062171063171064171065171066171067171068171069171070171071171072171073171074171075171076171077171078171079171080171081171082171083171084171085171086171087171088171089171090171091171092171093171094171095171096171097171098171099171100171101171102171103171104171105171106171107171108171109171110171111171112171113171114171115171116171117171118171119171120171121171122171123171124171125171126171127171128171129171130171131171132171133171134171135171136171137171138171139171140171141171142171143171144171145171146171147171148171149171150171151171152171153171154171155171156171157171158171159171160171161171162171163171164171165171166171167171168171169171170171171171172171173171174171175171176171177171178171179171180171181171182171183171184171185171186171187171188171189171190171191171192171193171194171195171196171197171198171199171200171201171202171203171204171205171206171207171208171209171210171211171212171213171214171215171216171217171218171219171220171221171222171223171224171225171226171227171228171229171230171231171232171233171234171235171236171237171238171239171240171241171242171243171244171245171246171247171248171249171250171251171252171253171254171255171256171257171258171259171260171261171262171263171264171265171266171267171268171269171270171271171272171273171274171275171276171277171278171279171280171281171282171283171284171285171286171287171288171289171290171291171292171293171294171295171296171297171298171299171300171301171302171303171304171305171306171307171308171309171310171311171312171313171314171315171316171317171318171319171320171321171322171323171324171325171326171327171328171329171330171331171332171333171334171335171336171337171338171339171340171341171342171343171344171345171346171347171348171349171350171351171352171353171354171355171356171357171358171359171360171361171362171363171364171365171366171367171368171369171370171371171372171373171374171375171376171377171378171379171380171381171382171383171384171385171386171387171388171389171390171391171392171393171394171395171396171397171398171399171400171401171402171403171404171405171406171407171408171409171410171411171412171413171414171415171416171417171418171419171420171421171422171423171424171425171426171427171428171429171430171431171432171433171434171435171436171437171438171439171440171441171442171443171444171445171446171447171448171449171450171451171452171453171454171455171456171457171458171459171460171461171462171463171464171465171466171467171468171469171470171471171472171473171474171475171476171477171478171479171480171481171482171483171484171485171486171487171488171489171490171491171492171493171494171495171496171497171498171499171500171501171502171503171504171505171506171507171508171509171510171511171512171513171514171515171516171517171518171519171520171521171522171523171524171525171526171527171528171529171530171531171532171533171534171535171536171537171538171539171540171541171542171543171544171545171546171547171548171549171550171551171552171553171554171555171556171557171558171559171560171561171562171563171564171565171566171567171568171569171570171571171572171573171574171575171576171577171578171579171580171581171582171583171584171585171586171587171588171589171590171591171592171593171594171595171596171597171598171599171600171601171602171603171604171605171606171607171608171609171610171611171612171613171614171615171616171617171618171619171620171621171622171623171624171625171626171627171628171629171630171631171632171633171634171635171636171637171638171639171640171641171642171643171644171645171646171647171648171649171650171651171652171653171654171655171656171657171658171659171660171661171662171663171664171665171666171667171668171669171670171671171672171673171674171675171676171677171678171679171680171681171682171683171684171685171686171687171688171689171690171691171692171693171694171695171696171697171698171699171700171701171702171703171704171705171706171707171708171709171710171711171712171713171714171715171716171717171718171719171720171721171722171723171724171725171726171727171728171729171730171731171732171733171734171735171736171737171738171739171740171741171742171743171744171745171746171747171748171749171750171751171752171753171754171755171756171757171758171759171760171761171762171763171764171765171766171767171768171769171770171771171772171773171774171775171776171777171778171779171780171781171782171783171784171785171786171787171788171789171790171791171792171793171794171795171796171797171798171799171800171801171802171803171804171805171806171807171808171809171810171811171812171813171814171815171816171817171818171819171820171821171822171823171824171825171826171827171828171829171830171831171832171833171834171835171836171837171838171839171840171841171842171843171844171845171846171847171848171849171850171851171852171853171854171855171856171857171858171859171860171861171862171863171864171865171866171867171868171869171870171871171872171873171874171875171876171877171878171879171880171881171882171883171884171885171886171887171888171889171890171891171892171893171894171895171896171897171898171899171900171901171902171903171904171905171906171907171908171909171910171911171912171913171914171915171916171917171918171919171920171921171922171923171924171925171926171927171928171929171930171931171932171933171934171935171936171937171938171939171940171941171942171943171944171945171946171947171948171949171950171951171952171953171954171955171956171957171958171959171960171961171962171963171964171965171966171967171968171969171970171971171972171973171974171975171976171977171978171979171980171981171982171983171984171985171986171987171988171989171990171991171992171993171994171995171996171997171998171999172000172001172002172003172004172005172006172007172008172009172010172011172012172013172014172015172016172017172018172019172020172021172022172023172024172025172026172027172028172029172030172031172032172033172034172035172036172037172038172039172040172041172042172043172044172045172046172047172048172049172050172051172052172053172054172055172056172057172058172059172060172061172062172063172064172065172066172067172068172069172070172071172072172073172074172075172076172077172078172079172080172081172082172083172084172085172086172087172088172089172090172091172092172093172094172095172096172097172098172099172100172101172102172103172104172105172106172107172108172109172110172111172112172113172114172115172116172117172118172119172120172121172122172123172124172125172126172127172128172129172130172131172132172133172134172135172136172137172138172139172140172141172142172143172144172145172146172147172148172149172150172151172152172153172154172155172156172157172158172159172160172161172162172163172164172165172166172167172168172169172170172171172172172173172174172175172176172177172178172179172180172181172182172183172184172185172186172187172188172189172190172191172192172193172194172195172196172197172198172199172200172201172202172203172204172205172206172207172208172209172210172211172212172213172214172215172216172217172218172219172220172221172222172223172224172225172226172227172228172229172230172231172232172233172234172235172236172237172238172239172240172241172242172243172244172245172246172247172248172249172250172251172252172253172254172255172256172257172258172259172260172261172262172263172264172265172266172267172268172269172270172271172272172273172274172275172276172277172278172279172280172281172282172283172284172285172286172287172288172289172290172291172292172293172294172295172296172297172298172299172300172301172302172303172304172305172306172307172308172309172310172311172312172313172314172315172316172317172318172319172320172321172322172323172324172325172326172327172328172329172330172331172332172333172334172335172336172337172338172339172340172341172342172343172344172345172346172347172348172349172350172351172352172353172354172355172356172357172358172359172360172361172362172363172364172365172366172367172368172369172370172371172372172373172374172375172376172377172378172379172380172381172382172383172384172385172386172387172388172389172390172391172392172393172394172395172396172397172398172399172400172401172402172403172404172405172406172407172408172409172410172411172412172413172414172415172416172417172418172419172420172421172422172423172424172425172426172427172428172429172430172431172432172433172434172435172436172437172438172439172440172441172442172443172444172445172446172447172448172449172450172451172452172453172454172455172456172457172458172459172460172461172462172463172464172465172466172467172468172469172470172471172472172473172474172475172476172477172478172479172480172481172482172483172484172485172486172487172488172489172490172491172492172493172494172495172496172497172498172499172500172501172502172503172504172505172506172507172508172509172510172511172512172513172514172515172516172517172518172519172520172521172522172523172524172525172526172527172528172529172530172531172532172533172534172535172536172537172538172539172540172541172542172543172544172545172546172547172548172549172550172551172552172553172554172555172556172557172558172559172560172561172562172563172564172565172566172567172568172569172570172571172572172573172574172575172576172577172578172579172580172581172582172583172584172585172586172587172588172589172590172591172592172593172594172595172596172597172598172599172600172601172602172603172604172605172606172607172608172609172610172611172612172613172614172615172616172617172618172619172620172621172622172623172624172625172626172627172628172629172630172631172632172633172634172635172636172637172638172639172640172641172642172643172644172645172646172647172648172649172650172651172652172653172654172655172656172657172658172659172660172661172662172663172664172665172666172667172668172669172670172671172672172673172674172675172676172677172678172679172680172681172682172683172684172685172686172687172688172689172690172691172692172693172694172695172696172697172698172699172700172701172702172703172704172705172706172707172708172709172710172711172712172713172714172715172716172717172718172719172720172721172722172723172724172725172726172727172728172729172730172731172732172733172734172735172736172737172738172739172740172741172742172743172744172745172746172747172748172749172750172751172752172753172754172755172756172757172758172759172760172761172762172763172764172765172766172767172768172769172770172771172772172773172774172775172776172777172778172779172780172781172782172783172784172785172786172787172788172789172790172791172792172793172794172795172796172797172798172799172800172801172802172803172804172805172806172807172808172809172810172811172812172813172814172815172816172817172818172819172820172821172822172823172824172825172826172827172828172829172830172831172832172833172834172835172836172837172838172839172840172841172842172843172844172845172846172847172848172849172850172851172852172853172854172855172856172857172858172859172860172861172862172863172864172865172866172867172868172869172870172871172872172873172874172875172876172877172878172879172880172881172882172883172884172885172886172887172888172889172890172891172892172893172894172895172896172897172898172899172900172901172902172903172904172905172906172907172908172909172910172911172912172913172914172915172916172917172918172919172920172921172922172923172924172925172926172927172928172929172930172931172932172933172934172935172936172937172938172939172940172941172942172943172944172945172946172947172948172949172950172951172952172953172954172955172956172957172958172959172960172961172962172963172964172965172966172967172968172969172970172971172972172973172974172975172976172977172978172979172980172981172982172983172984172985172986172987172988172989172990172991172992172993172994172995172996172997172998172999173000173001173002173003173004173005173006173007173008173009173010173011173012173013173014173015173016173017173018173019173020173021173022173023173024173025173026173027173028173029173030173031173032173033173034173035173036173037173038173039173040173041173042173043173044173045173046173047173048173049173050173051173052173053173054173055173056173057173058173059173060173061173062173063173064173065173066173067173068173069173070173071173072173073173074173075173076173077173078173079173080173081173082173083173084173085173086173087173088173089173090173091173092173093173094173095173096173097173098173099173100173101173102173103173104173105173106173107173108173109173110173111173112173113173114173115173116173117173118173119173120173121173122173123173124173125173126173127173128173129173130173131173132173133173134173135173136173137173138173139173140173141173142173143173144173145173146173147173148173149173150173151173152173153173154173155173156173157173158173159173160173161173162173163173164173165173166173167173168173169173170173171173172173173173174173175173176173177173178173179173180173181173182173183173184173185173186173187173188173189173190173191173192173193173194173195173196173197173198173199173200173201173202173203173204173205173206173207173208173209173210173211173212173213173214173215173216173217173218173219173220173221173222173223173224173225173226173227173228173229173230173231173232173233173234173235173236173237173238173239173240173241173242173243173244173245173246173247173248173249173250173251173252173253173254173255173256173257173258173259173260173261173262173263173264173265173266173267173268173269173270173271173272173273173274173275173276173277173278173279173280173281173282173283173284173285173286173287173288173289173290173291173292173293173294173295173296173297173298173299173300173301173302173303173304173305173306173307173308173309173310173311173312173313173314173315173316173317173318173319173320173321173322173323173324173325173326173327173328173329173330173331173332173333173334173335173336173337173338173339173340173341173342173343173344173345173346173347173348173349173350173351173352173353173354173355173356173357173358173359173360173361173362173363173364173365173366173367173368173369173370173371173372173373173374173375173376173377173378173379173380173381173382173383173384173385173386173387173388173389173390173391173392173393173394173395173396173397173398173399173400173401173402173403173404173405173406173407173408173409173410173411173412173413173414173415173416173417173418173419173420173421173422173423173424173425173426173427173428173429173430173431173432173433173434173435173436173437173438173439173440173441173442173443173444173445173446173447173448173449173450173451173452173453173454173455173456173457173458173459173460173461173462173463173464173465173466173467173468173469173470173471173472173473173474173475173476173477173478173479173480173481173482173483173484173485173486173487173488173489173490173491173492173493173494173495173496173497173498173499173500173501173502173503173504173505173506173507173508173509173510173511173512173513173514173515173516173517173518173519173520173521173522173523173524173525173526173527173528173529173530173531173532173533173534173535173536173537173538173539173540173541173542173543173544173545173546173547173548173549173550173551173552173553173554173555173556173557173558173559173560173561173562173563173564173565173566173567173568173569173570173571173572173573173574173575173576173577173578173579173580173581173582173583173584173585173586173587173588173589173590173591173592173593173594173595173596173597173598173599173600173601173602173603173604173605173606173607173608173609173610173611173612173613173614173615173616173617173618173619173620173621173622173623173624173625173626173627173628173629173630173631173632173633173634173635173636173637173638173639173640173641173642173643173644173645173646173647173648173649173650173651173652173653173654173655173656173657173658173659173660173661173662173663173664173665173666173667173668173669173670173671173672173673173674173675173676173677173678173679173680173681173682173683173684173685173686173687173688173689173690173691173692173693173694173695173696173697173698173699173700173701173702173703173704173705173706173707173708173709173710173711173712173713173714173715173716173717173718173719173720173721173722173723173724173725173726173727173728173729173730173731173732173733173734173735173736173737173738173739173740173741173742173743173744173745173746173747173748173749173750173751173752173753173754173755173756173757173758173759173760173761173762173763173764173765173766173767173768173769173770173771173772173773173774173775173776173777173778173779173780173781173782173783173784173785173786173787173788173789173790173791173792173793173794173795173796173797173798173799173800173801173802173803173804173805173806173807173808173809173810173811173812173813173814173815173816173817173818173819173820173821173822173823173824173825173826173827173828173829173830173831173832173833173834173835173836173837173838173839173840173841173842173843173844173845173846173847173848173849173850173851173852173853173854173855173856173857173858173859173860173861173862173863173864173865173866173867173868173869173870173871173872173873173874173875173876173877173878173879173880173881173882173883173884173885173886173887173888173889173890173891173892173893173894173895173896173897173898173899173900173901173902173903173904173905173906173907173908173909173910173911173912173913173914173915173916173917173918173919173920173921173922173923173924173925173926173927173928173929173930173931173932173933173934173935173936173937173938173939173940173941173942173943173944173945173946173947173948173949173950173951173952173953173954173955173956173957173958173959173960173961173962173963173964173965173966173967173968173969173970173971173972173973173974173975173976173977173978173979173980173981173982173983173984173985173986173987173988173989173990173991173992173993173994173995173996173997173998173999174000174001174002174003174004174005174006174007174008174009174010174011174012174013174014174015174016174017174018174019174020174021174022174023174024174025174026174027174028174029174030174031174032174033174034174035174036174037174038174039174040174041174042174043174044174045174046174047174048174049174050174051174052174053174054174055174056174057174058174059174060174061174062174063174064174065174066174067174068174069174070174071174072174073174074174075174076174077174078174079174080174081174082174083174084174085174086174087174088174089174090174091174092174093174094174095174096174097174098174099174100174101174102174103174104174105174106174107174108174109174110174111174112174113174114174115174116174117174118174119174120174121174122174123174124174125174126174127174128174129174130174131174132174133174134174135174136174137174138174139174140174141174142174143174144174145174146174147174148174149174150174151174152174153174154174155174156174157174158174159174160174161174162174163174164174165174166174167174168174169174170174171174172174173174174174175174176174177174178174179174180174181174182174183174184174185174186174187174188174189174190174191174192174193174194174195174196174197174198174199174200174201174202174203174204174205174206174207174208174209174210174211174212174213174214174215174216174217174218174219174220174221174222174223174224174225174226174227174228174229174230174231174232174233174234174235174236174237174238174239174240174241174242174243174244174245174246174247174248174249174250174251174252174253174254174255174256174257174258174259174260174261174262174263174264174265174266174267174268174269174270174271174272174273174274174275174276174277174278174279174280174281174282174283174284174285174286174287174288174289174290174291174292174293174294174295174296174297174298174299174300174301174302174303174304174305174306174307174308174309174310174311174312174313174314174315174316174317174318174319174320174321174322174323174324174325174326174327174328174329174330174331174332174333174334174335174336174337174338174339174340174341174342174343174344174345174346174347174348174349174350174351174352174353174354174355174356174357174358174359174360174361174362174363174364174365174366174367174368174369174370174371174372174373174374174375174376174377174378174379174380174381174382174383174384174385174386174387174388174389174390174391174392174393174394174395174396174397174398174399174400174401174402174403174404174405174406174407174408174409174410174411174412174413174414174415174416174417174418174419174420174421174422174423174424174425174426174427174428174429174430174431174432174433174434174435174436174437174438174439174440174441174442174443174444174445174446174447174448174449174450174451174452174453174454174455174456174457174458174459174460174461174462174463174464174465174466174467174468174469174470174471174472174473174474174475174476174477174478174479174480174481174482174483174484174485174486174487174488174489174490174491174492174493174494174495174496174497174498174499174500174501174502174503174504174505174506174507174508174509174510174511174512174513174514174515174516174517174518174519174520174521174522174523174524174525174526174527174528174529174530174531174532174533174534174535174536174537174538174539174540174541174542174543174544174545174546174547174548174549174550174551174552174553174554174555174556174557174558174559174560174561174562174563174564174565174566174567174568174569174570174571174572174573174574174575174576174577174578174579174580174581174582174583174584174585174586174587174588174589174590174591174592174593174594174595174596174597174598174599174600174601174602174603174604174605174606174607174608174609174610174611174612174613174614174615174616174617174618174619174620174621174622174623174624174625174626174627174628174629174630174631174632174633174634174635174636174637174638174639174640174641174642174643174644174645174646174647174648174649174650174651174652174653174654174655174656174657174658174659174660174661174662174663174664174665174666174667174668174669174670174671174672174673174674174675174676174677174678174679174680174681174682174683174684174685174686174687174688174689174690174691174692174693174694174695174696174697174698174699174700174701174702174703174704174705174706174707174708174709174710174711174712174713174714174715174716174717174718174719174720174721174722174723174724174725174726174727174728174729174730174731174732174733174734174735174736174737174738174739174740174741174742174743174744174745174746174747174748174749174750174751174752174753174754174755174756174757174758174759174760174761174762174763174764174765174766174767174768174769174770174771174772174773174774174775174776174777174778174779174780174781174782174783174784174785174786174787174788174789174790174791174792174793174794174795174796174797174798174799174800174801174802174803174804174805174806174807174808174809174810174811174812174813174814174815174816174817174818174819174820174821174822174823174824174825174826174827174828174829174830174831174832174833174834174835174836174837174838174839174840174841174842174843174844174845174846174847174848174849174850174851174852174853174854174855174856174857174858174859174860174861174862174863174864174865174866174867174868174869174870174871174872174873174874174875174876174877174878174879174880174881174882174883174884174885174886174887174888174889174890174891174892174893174894174895174896174897174898174899174900174901174902174903174904174905174906174907174908174909174910174911174912174913174914174915174916174917174918174919174920174921174922174923174924174925174926174927174928174929174930174931174932174933174934174935174936174937174938174939174940174941174942174943174944174945174946174947174948174949174950174951174952174953174954174955174956174957174958174959174960174961174962174963174964174965174966174967174968174969174970174971174972174973174974174975174976174977174978174979174980174981174982174983174984174985174986174987174988174989174990174991174992174993174994174995174996174997174998174999175000175001175002175003175004175005175006175007175008175009175010175011175012175013175014175015175016175017175018175019175020175021175022175023175024175025175026175027175028175029175030175031175032175033175034175035175036175037175038175039175040175041175042175043175044175045175046175047175048175049175050175051175052175053175054175055175056175057175058175059175060175061175062175063175064175065175066175067175068175069175070175071175072175073175074175075175076175077175078175079175080175081175082175083175084175085175086175087175088175089175090175091175092175093175094175095175096175097175098175099175100175101175102175103175104175105175106175107175108175109175110175111175112175113175114175115175116175117175118175119175120175121175122175123175124175125175126175127175128175129175130175131175132175133175134175135175136175137175138175139175140175141175142175143175144175145175146175147175148175149175150175151175152175153175154175155175156175157175158175159175160175161175162175163175164175165175166175167175168175169175170175171175172175173175174175175175176175177175178175179175180175181175182175183175184175185175186175187175188175189175190175191175192175193175194175195175196175197175198175199175200175201175202175203175204175205175206175207175208175209175210175211175212175213175214175215175216175217175218175219175220175221175222175223175224175225175226175227175228175229175230175231175232175233175234175235175236175237175238175239175240175241175242175243175244175245175246175247175248175249175250175251175252175253175254175255175256175257175258175259175260175261175262175263175264175265175266175267175268175269175270175271175272175273175274175275175276175277175278175279175280175281175282175283175284175285175286175287175288175289175290175291175292175293175294175295175296175297175298175299175300175301175302175303175304175305175306175307175308175309175310175311175312175313175314175315175316175317175318175319175320175321175322175323175324175325175326175327175328175329175330175331175332175333175334175335175336175337175338175339175340175341175342175343175344175345175346175347175348175349175350175351175352175353175354175355175356175357175358175359175360175361175362175363175364175365175366175367175368175369175370175371175372175373175374175375175376175377175378175379175380175381175382175383175384175385175386175387175388175389175390175391175392175393175394175395175396175397175398175399175400175401175402175403175404175405175406175407175408175409175410175411175412175413175414175415175416175417175418175419175420175421175422175423175424175425175426175427175428175429175430175431175432175433175434175435175436175437175438175439175440175441175442175443175444175445175446175447175448175449175450175451175452175453175454175455175456175457175458175459175460175461175462175463175464175465175466175467175468175469175470175471175472175473175474175475175476175477175478175479175480175481175482175483175484175485175486175487175488175489175490175491175492175493175494175495175496175497175498175499175500175501175502175503175504175505175506175507175508175509175510175511175512175513175514175515175516175517175518175519175520175521175522175523175524175525175526175527175528175529175530175531175532175533175534175535175536175537175538175539175540175541175542175543175544175545175546175547175548175549175550175551175552175553175554175555175556175557175558175559175560175561175562175563175564175565175566175567175568175569175570175571175572175573175574175575175576175577175578175579175580175581175582175583175584175585175586175587175588175589175590175591175592175593175594175595175596175597175598175599175600175601175602175603175604175605175606175607175608175609175610175611175612175613175614175615175616175617175618175619175620175621175622175623175624175625175626175627175628175629175630175631175632175633175634175635175636175637175638175639175640175641175642175643175644175645175646175647175648175649175650175651175652175653175654175655175656175657175658175659175660175661175662175663175664175665175666175667175668175669175670175671175672175673175674175675175676175677175678175679175680175681175682175683175684175685175686175687175688175689175690175691175692175693175694175695175696175697175698175699175700175701175702175703175704175705175706175707175708175709175710175711175712175713175714175715175716175717175718175719175720175721175722175723175724175725175726175727175728175729175730175731175732175733175734175735175736175737175738175739175740175741175742175743175744175745175746175747175748175749175750175751175752175753175754175755175756175757175758175759175760175761175762175763175764175765175766175767175768175769175770175771175772175773175774175775175776175777175778175779175780175781175782175783175784175785175786175787175788175789175790175791175792175793175794175795175796175797175798175799175800175801175802175803175804175805175806175807175808175809175810175811175812175813175814175815175816175817175818175819175820175821175822175823175824175825175826175827175828175829175830175831175832175833175834175835175836175837175838175839175840175841175842175843175844175845175846175847175848175849175850175851175852175853175854175855175856175857175858175859175860175861175862175863175864175865175866175867175868175869175870175871175872175873175874175875175876175877175878175879175880175881175882175883175884175885175886175887175888175889175890175891175892175893175894175895175896175897175898175899175900175901175902175903175904175905175906175907175908175909175910175911175912175913175914175915175916175917175918175919175920175921175922175923175924175925175926175927175928175929175930175931175932175933175934175935175936175937175938175939175940175941175942175943175944175945175946175947175948175949175950175951175952175953175954175955175956175957175958175959175960175961175962175963175964175965175966175967175968175969175970175971175972175973175974175975175976175977175978175979175980175981175982175983175984175985175986175987175988175989175990175991175992175993175994175995175996175997175998175999176000176001176002176003176004176005176006176007176008176009176010176011176012176013176014176015176016176017176018176019176020176021176022176023176024176025176026176027176028176029176030176031176032176033176034176035176036176037176038176039176040176041176042176043176044176045176046176047176048176049176050176051176052176053176054176055176056176057176058176059176060176061176062176063176064176065176066176067176068176069176070176071176072176073176074176075176076176077176078176079176080176081176082176083176084176085176086176087176088176089176090176091176092176093176094176095176096176097176098176099176100176101176102176103176104176105176106176107176108176109176110176111176112176113176114176115176116176117176118176119176120176121176122176123176124176125176126176127176128176129176130176131176132176133176134176135176136176137176138176139176140176141176142176143176144176145176146176147176148176149176150176151176152176153176154176155176156176157176158176159176160176161176162176163176164176165176166176167176168176169176170176171176172176173176174176175176176176177176178176179176180176181176182176183176184176185176186176187176188176189176190176191176192176193176194176195176196176197176198176199176200176201176202176203176204176205176206176207176208176209176210176211176212176213176214176215176216176217176218176219176220176221176222176223176224176225176226176227176228176229176230176231176232176233176234176235176236176237176238176239176240176241176242176243176244176245176246176247176248176249176250176251176252176253176254176255176256176257176258176259176260176261176262176263176264176265176266176267176268176269176270176271176272176273176274176275176276176277176278176279176280176281176282176283176284176285176286176287176288176289176290176291176292176293176294176295176296176297176298176299176300176301176302176303176304176305176306176307176308176309176310176311176312176313176314176315176316176317176318176319176320176321176322176323176324176325176326176327176328176329176330176331176332176333176334176335176336176337176338176339176340176341176342176343176344176345176346176347176348176349176350176351176352176353176354176355176356176357176358176359176360176361176362176363176364176365176366176367176368176369176370176371176372176373176374176375176376176377176378176379176380176381176382176383176384176385176386176387176388176389176390176391176392176393176394176395176396176397176398176399176400176401176402176403176404176405176406176407176408176409176410176411176412176413176414176415176416176417176418176419176420176421176422176423176424176425176426176427176428176429176430176431176432176433176434176435176436176437176438176439176440176441176442176443176444176445176446176447176448176449176450176451176452176453176454176455176456176457176458176459176460176461176462176463176464176465176466176467176468176469176470176471176472176473176474176475176476176477176478176479176480176481176482176483176484176485176486176487176488176489176490176491176492176493176494176495176496176497176498176499176500176501176502176503176504176505176506176507176508176509176510176511176512176513176514176515176516176517176518176519176520176521176522176523176524176525176526176527176528176529176530176531176532176533176534176535176536176537176538176539176540176541176542176543176544176545176546176547176548176549176550176551176552176553176554176555176556176557176558176559176560176561176562176563176564176565176566176567176568176569176570176571176572176573176574176575176576176577176578176579176580176581176582176583176584176585176586176587176588176589176590176591176592176593176594176595176596176597176598176599176600176601176602176603176604176605176606176607176608176609176610176611176612176613176614176615176616176617176618176619176620176621176622176623176624176625176626176627176628176629176630176631176632176633176634176635176636176637176638176639176640176641176642176643176644176645176646176647176648176649176650176651176652176653176654176655176656176657176658176659176660176661176662176663176664176665176666176667176668176669176670176671176672176673176674176675176676176677176678176679176680176681176682176683176684176685176686176687176688176689176690176691176692176693176694176695176696176697176698176699176700176701176702176703176704176705176706176707176708176709176710176711176712176713176714176715176716176717176718176719176720176721176722176723176724176725176726176727176728176729176730176731176732176733176734176735176736176737176738176739176740176741176742176743176744176745176746176747176748176749176750176751176752176753176754176755176756176757176758176759176760176761176762176763176764176765176766176767176768176769176770176771176772176773176774176775176776176777176778176779176780176781176782176783176784176785176786176787176788176789176790176791176792176793176794176795176796176797176798176799176800176801176802176803176804176805176806176807176808176809176810176811176812176813176814176815176816176817176818176819176820176821176822176823176824176825176826176827176828176829176830176831176832176833176834176835176836176837176838176839176840176841176842176843176844176845176846176847176848176849176850176851176852176853176854176855176856176857176858176859176860176861176862176863176864176865176866176867176868176869176870176871176872176873176874176875176876176877176878176879176880176881176882176883176884176885176886176887176888176889176890176891176892176893176894176895176896176897176898176899176900176901176902176903176904176905176906176907176908176909176910176911176912176913176914176915176916176917176918176919176920176921176922176923176924176925176926176927176928176929176930176931176932176933176934176935176936176937176938176939176940176941176942176943176944176945176946176947176948176949176950176951176952176953176954176955176956176957176958176959176960176961176962176963176964176965176966176967176968176969176970176971176972176973176974176975176976176977176978176979176980176981176982176983176984176985176986176987176988176989176990176991176992176993176994176995176996176997176998176999177000177001177002177003177004177005177006177007177008177009177010177011177012177013177014177015177016177017177018177019177020177021177022177023177024177025177026177027177028177029177030177031177032177033177034177035177036177037177038177039177040177041177042177043177044177045177046177047177048177049177050177051177052177053177054177055177056177057177058177059177060177061177062177063177064177065177066177067177068177069177070177071177072177073177074177075177076177077177078177079177080177081177082177083177084177085177086177087177088177089177090177091177092177093177094177095177096177097177098177099177100177101177102177103177104177105177106177107177108177109177110177111177112177113177114177115177116177117177118177119177120177121177122177123177124177125177126177127177128177129177130177131177132177133177134177135177136177137177138177139177140177141177142177143177144177145177146177147177148177149177150177151177152177153177154177155177156177157177158177159177160177161177162177163177164177165177166177167177168177169177170177171177172177173177174177175177176177177177178177179177180177181177182177183177184177185177186177187177188177189177190177191177192177193177194177195177196177197177198177199177200177201177202177203177204177205177206177207177208177209177210177211177212177213177214177215177216177217177218177219177220177221177222177223177224177225177226177227177228177229177230177231177232177233177234177235177236177237177238177239177240177241177242177243177244177245177246177247177248177249177250177251177252177253177254177255177256177257177258177259177260177261177262177263177264177265177266177267177268177269177270177271177272177273177274177275177276177277177278177279177280177281177282177283177284177285177286177287177288177289177290177291177292177293177294177295177296177297177298177299177300177301177302177303177304177305177306177307177308177309177310177311177312177313177314177315177316177317177318177319177320177321177322177323177324177325177326177327177328177329177330177331177332177333177334177335177336177337177338177339177340177341177342177343177344177345177346177347177348177349177350177351177352177353177354177355177356177357177358177359177360177361177362177363177364177365177366177367177368177369177370177371177372177373177374177375177376177377177378177379177380177381177382177383177384177385177386177387177388177389177390177391177392177393177394177395177396177397177398177399177400177401177402177403177404177405177406177407177408177409177410177411177412177413177414177415177416177417177418177419177420177421177422177423177424177425177426177427177428177429177430177431177432177433177434177435177436177437177438177439177440177441177442177443177444177445177446177447177448177449177450177451177452177453177454177455177456177457177458177459177460177461177462177463177464177465177466177467177468177469177470177471177472177473177474177475177476177477177478177479177480177481177482177483177484177485177486177487177488177489177490177491177492177493177494177495177496177497177498177499177500177501177502177503177504177505177506177507177508177509177510177511177512177513177514177515177516177517177518177519177520177521177522177523177524177525177526177527177528177529177530177531177532177533177534177535177536177537177538177539177540177541177542177543177544177545177546177547177548177549177550177551177552177553177554177555177556177557177558177559177560177561177562177563177564177565177566177567177568177569177570177571177572177573177574177575177576177577177578177579177580177581177582177583177584177585177586177587177588177589177590177591177592177593177594177595177596177597177598177599177600177601177602177603177604177605177606177607177608177609177610177611177612177613177614177615177616177617177618177619177620177621177622177623177624177625177626177627177628177629177630177631177632177633177634177635177636177637177638177639177640177641177642177643177644177645177646177647177648177649177650177651177652177653177654177655177656177657177658177659177660177661177662177663177664177665177666177667177668177669177670177671177672177673177674177675177676177677177678177679177680177681177682177683177684177685177686177687177688177689177690177691177692177693177694177695177696177697177698177699177700177701177702177703177704177705177706177707177708177709177710177711177712177713177714177715177716177717177718177719177720177721177722177723177724177725177726177727177728177729177730177731177732177733177734177735177736177737177738177739177740177741177742177743177744177745177746177747177748177749177750177751177752177753177754177755177756177757177758177759177760177761177762177763177764177765177766177767177768177769177770177771177772177773177774177775177776177777177778177779177780177781177782177783177784177785177786177787177788177789177790177791177792177793177794177795177796177797177798177799177800177801177802177803177804177805177806177807177808177809177810177811177812177813177814177815177816177817177818177819177820177821177822177823177824177825177826177827177828177829177830177831177832177833177834177835177836177837177838177839177840177841177842177843177844177845177846177847177848177849177850177851177852177853177854177855177856177857177858177859177860177861177862177863177864177865177866177867177868177869177870177871177872177873177874177875177876177877177878177879177880177881177882177883177884177885177886177887177888177889177890177891177892177893177894177895177896177897177898177899177900177901177902177903177904177905177906177907177908177909177910177911177912177913177914177915177916177917177918177919177920177921177922177923177924177925177926177927177928177929177930177931177932177933177934177935177936177937177938177939177940177941177942177943177944177945177946177947177948177949177950177951177952177953177954177955177956177957177958177959177960177961177962177963177964177965177966177967177968177969177970177971177972177973177974177975177976177977177978177979177980177981177982177983177984177985177986177987177988177989177990177991177992177993177994177995177996177997177998177999178000178001178002178003178004178005178006178007178008178009178010178011178012178013178014178015178016178017178018178019178020178021178022178023178024178025178026178027178028178029178030178031178032178033178034178035178036178037178038178039178040178041178042178043178044178045178046178047178048178049178050178051178052178053178054178055178056178057178058178059178060178061178062178063178064178065178066178067178068178069178070178071178072178073178074178075178076178077178078178079178080178081178082178083178084178085178086178087178088178089178090178091178092178093178094178095178096178097178098178099178100178101178102178103178104178105178106178107178108178109178110178111178112178113178114178115178116178117178118178119178120178121178122178123178124178125178126178127178128178129178130178131178132178133178134178135178136178137178138178139178140178141178142178143178144178145178146178147178148178149178150178151178152178153178154178155178156178157178158178159178160178161178162178163178164178165178166178167178168178169178170178171178172178173178174178175178176178177178178178179178180178181178182178183178184178185178186178187178188178189178190178191178192178193178194178195178196178197178198178199178200178201178202178203178204178205178206178207178208178209178210178211178212178213178214178215178216178217178218178219178220178221178222178223178224178225178226178227178228178229178230178231178232178233178234178235178236178237178238178239178240178241178242178243178244178245178246178247178248178249178250178251178252178253178254178255178256178257178258178259178260178261178262178263178264178265178266178267178268178269178270178271178272178273178274178275178276178277178278178279178280178281178282178283178284178285178286178287178288178289178290178291178292178293178294178295178296178297178298178299178300178301178302178303178304178305178306178307178308178309178310178311178312178313178314178315178316178317178318178319178320178321178322178323178324178325178326178327178328178329178330178331178332178333178334178335178336178337178338178339178340178341178342178343178344178345178346178347178348178349178350178351178352178353178354178355178356178357178358178359178360178361178362178363178364178365178366178367178368178369178370178371178372178373178374178375178376178377178378178379178380178381178382178383178384178385178386178387178388178389178390178391178392178393178394178395178396178397178398178399178400178401178402178403178404178405178406178407178408178409178410178411178412178413178414178415178416178417178418178419178420178421178422178423178424178425178426178427178428178429178430178431178432178433178434178435178436178437178438178439178440178441178442178443178444178445178446178447178448178449178450178451178452178453178454178455178456178457178458178459178460178461178462178463178464178465178466178467178468178469178470178471178472178473178474178475178476178477178478178479178480178481178482178483178484178485178486178487178488178489178490178491178492178493178494178495178496178497178498178499178500178501178502178503178504178505178506178507178508178509178510178511178512178513178514178515178516178517178518178519178520178521178522178523178524178525178526178527178528178529178530178531178532178533178534178535178536178537178538178539178540178541178542178543178544178545178546178547178548178549178550178551178552178553178554178555178556178557178558178559178560178561178562178563178564178565178566178567178568178569178570178571178572178573178574178575178576178577178578178579178580178581178582178583178584178585178586178587178588178589178590178591178592178593178594178595178596178597178598178599178600178601178602178603178604178605178606178607178608178609178610178611178612178613178614178615178616178617178618178619178620178621178622178623178624178625178626178627178628178629178630178631178632178633178634178635178636178637178638178639178640178641178642178643178644178645178646178647178648178649178650178651178652178653178654178655178656178657178658178659178660178661178662178663178664178665178666178667178668178669178670178671178672178673178674178675178676178677178678178679178680178681178682178683178684178685178686178687178688178689178690178691178692178693178694178695178696178697178698178699178700178701178702178703178704178705178706178707178708178709178710178711178712178713178714178715178716178717178718178719178720178721178722178723178724178725178726178727178728178729178730178731178732178733178734178735178736178737178738178739178740178741178742178743178744178745178746178747178748178749178750178751178752178753178754178755178756178757178758178759178760178761178762178763178764178765178766178767178768178769178770178771178772178773178774178775178776178777178778178779178780178781178782178783178784178785178786178787178788178789178790178791178792178793178794178795178796178797178798178799178800178801178802178803178804178805178806178807178808178809178810178811178812178813178814178815178816178817178818178819178820178821178822178823178824178825178826178827178828178829178830178831178832178833178834178835178836178837178838178839178840178841178842178843178844178845178846178847178848178849178850178851178852178853178854178855178856178857178858178859178860178861178862178863178864178865178866178867178868178869178870178871178872178873178874178875178876178877178878178879178880178881178882178883178884178885178886178887178888178889178890178891178892178893178894178895178896178897178898178899178900178901178902178903178904178905178906178907178908178909178910178911178912178913178914178915178916178917178918178919178920178921178922178923178924178925178926178927178928178929178930178931178932178933178934178935178936178937178938178939178940178941178942178943178944178945178946178947178948178949178950178951178952178953178954178955178956178957178958178959178960178961178962178963178964178965178966178967178968178969178970178971178972178973178974178975178976178977178978178979178980178981178982178983178984178985178986178987178988178989178990178991178992178993178994178995178996178997178998178999179000179001179002179003179004179005179006179007179008179009179010179011179012179013179014179015179016179017179018179019179020179021179022179023179024179025179026179027179028179029179030179031179032179033179034179035179036179037179038179039179040179041179042179043179044179045179046179047179048179049179050179051179052179053179054179055179056179057179058179059179060179061179062179063179064179065179066179067179068179069179070179071179072179073179074179075179076179077179078179079179080179081179082179083179084179085179086179087179088179089179090179091179092179093179094179095179096179097179098179099179100179101179102179103179104179105179106179107179108179109179110179111179112179113179114179115179116179117179118179119179120179121179122179123179124179125179126179127179128179129179130179131179132179133179134179135179136179137179138179139179140179141179142179143179144179145179146179147179148179149179150179151179152179153179154179155179156179157179158179159179160179161179162179163179164179165179166179167179168179169179170179171179172179173179174179175179176179177179178179179179180179181179182179183179184179185179186179187179188179189179190179191179192179193179194179195179196179197179198179199179200179201179202179203179204179205179206179207179208179209179210179211179212179213179214179215179216179217179218179219179220179221179222179223179224179225179226179227179228179229179230179231179232179233179234179235179236179237179238179239179240179241179242179243179244179245179246179247179248179249179250179251179252179253179254179255179256179257179258179259179260179261179262179263179264179265179266179267179268179269179270179271179272179273179274179275179276179277179278179279179280179281179282179283179284179285179286179287179288179289179290179291179292179293179294179295179296179297179298179299179300179301179302179303179304179305179306179307179308179309179310179311179312179313179314179315179316179317179318179319179320179321179322179323179324179325179326179327179328179329179330179331179332179333179334179335179336179337179338179339179340179341179342179343179344179345179346179347179348179349179350179351179352179353179354179355179356179357179358179359179360179361179362179363179364179365179366179367179368179369179370179371179372179373179374179375179376179377179378179379179380179381179382179383179384179385179386179387179388179389179390179391179392179393179394179395179396179397179398179399179400179401179402179403179404179405179406179407179408179409179410179411179412179413179414179415179416179417179418179419179420179421179422179423179424179425179426179427179428179429179430179431179432179433179434179435179436179437179438179439179440179441179442179443179444179445179446179447179448179449179450179451179452179453179454179455179456179457179458179459179460179461179462179463179464179465179466179467179468179469179470179471179472179473179474179475179476179477179478179479179480179481179482179483179484179485179486179487179488179489179490179491179492179493179494179495179496179497179498179499179500179501179502179503179504179505179506179507179508179509179510179511179512179513179514179515179516179517179518179519179520179521179522179523179524179525179526179527179528179529179530179531179532179533179534179535179536179537179538179539179540179541179542179543179544179545179546179547179548179549179550179551179552179553179554179555179556179557179558179559179560179561179562179563179564179565179566179567179568179569179570179571179572179573179574179575179576179577179578179579179580179581179582179583179584179585179586179587179588179589179590179591179592179593179594179595179596179597179598179599179600179601179602179603179604179605179606179607179608179609179610179611179612179613179614179615179616179617179618179619179620179621179622179623179624179625179626179627179628179629179630179631179632179633179634179635179636179637179638179639179640179641179642179643179644179645179646179647179648179649179650179651179652179653179654179655179656179657179658179659179660179661179662179663179664179665179666179667179668179669179670179671179672179673179674179675179676179677179678179679179680179681179682179683179684179685179686179687179688179689179690179691179692179693179694179695179696179697179698179699179700179701179702179703179704179705179706179707179708179709179710179711179712179713179714179715179716179717179718179719179720179721179722179723179724179725179726179727179728179729179730179731179732179733179734179735179736179737179738179739179740179741179742179743179744179745179746179747179748179749179750179751179752179753179754179755179756179757179758179759179760179761179762179763179764179765179766179767179768179769179770179771179772179773179774179775179776179777179778179779179780179781179782179783179784179785179786179787179788179789179790179791179792179793179794179795179796179797179798179799179800179801179802179803179804179805179806179807179808179809179810179811179812179813179814179815179816179817179818179819179820179821179822179823179824179825179826179827179828179829179830179831179832179833179834179835179836179837179838179839179840179841179842179843179844179845179846179847179848179849179850179851179852179853179854179855179856179857179858179859179860179861179862179863179864179865179866179867179868179869179870179871179872179873179874179875179876179877179878179879179880179881179882179883179884179885179886179887179888179889179890179891179892179893179894179895179896179897179898179899179900179901179902179903179904179905179906179907179908179909179910179911179912179913179914179915179916179917179918179919179920179921179922179923179924179925179926179927179928179929179930179931179932179933179934179935179936179937179938179939179940179941179942179943179944179945179946179947179948179949179950179951179952179953179954179955179956179957179958179959179960179961179962179963179964179965179966179967179968179969179970179971179972179973179974179975179976179977179978179979179980179981179982179983179984179985179986179987179988179989179990179991179992179993179994179995179996179997179998179999180000180001180002180003180004180005180006180007180008180009180010180011180012180013180014180015180016180017180018180019180020180021180022180023180024180025180026180027180028180029180030180031180032180033180034180035180036180037180038180039180040180041180042180043180044180045180046180047180048180049180050180051180052180053180054180055180056180057180058180059180060180061180062180063180064180065180066180067180068180069180070180071180072180073180074180075180076180077180078180079180080180081180082180083180084180085180086180087180088180089180090180091180092180093180094180095180096180097180098180099180100180101180102180103180104180105180106180107180108180109180110180111180112180113180114180115180116180117180118180119180120180121180122180123180124180125180126180127180128180129180130180131180132180133180134180135180136180137180138180139180140180141180142180143180144180145180146180147180148180149180150180151180152180153180154180155180156180157180158180159180160180161180162180163180164180165180166180167180168180169180170180171180172180173180174180175180176180177180178180179180180180181180182180183180184180185180186180187180188180189180190180191180192180193180194180195180196180197180198180199180200180201180202180203180204180205180206180207180208180209180210180211180212180213180214180215180216180217180218180219180220180221180222180223180224180225180226180227180228180229180230180231180232180233180234180235180236180237180238180239180240180241180242180243180244180245180246180247180248180249180250180251180252180253180254180255180256180257180258180259180260180261180262180263180264180265180266180267180268180269180270180271180272180273180274180275180276180277180278180279180280180281180282180283180284180285180286180287180288180289180290180291180292180293180294180295180296180297180298180299180300180301180302180303180304180305180306180307180308180309180310180311180312180313180314180315180316180317180318180319180320180321180322180323180324180325180326180327180328180329180330180331180332180333180334180335180336180337180338180339180340180341180342180343180344180345180346180347180348180349180350180351180352180353180354180355180356180357180358180359180360180361180362180363180364180365180366180367180368180369180370180371180372180373180374180375180376180377180378180379180380180381180382180383180384180385180386180387180388180389180390180391180392180393180394180395180396180397180398180399180400180401180402180403180404180405180406180407180408180409180410180411180412180413180414180415180416180417180418180419180420180421180422180423180424180425180426180427180428180429180430180431180432180433180434180435180436180437180438180439180440180441180442180443180444180445180446180447180448180449180450180451180452180453180454180455180456180457180458180459180460180461180462180463180464180465180466180467180468180469180470180471180472180473180474180475180476180477180478180479180480180481180482180483180484180485180486180487180488180489180490180491180492180493180494180495180496180497180498180499180500180501180502180503180504180505180506180507180508180509180510180511180512180513180514180515180516180517180518180519180520180521180522180523180524180525180526180527180528180529180530180531180532180533180534180535180536180537180538180539180540180541180542180543180544180545180546180547180548180549180550180551180552180553180554180555180556180557180558180559180560180561180562180563180564180565180566180567180568180569180570180571180572180573180574180575180576180577180578180579180580180581180582180583180584180585180586180587180588180589180590180591180592180593180594180595180596180597180598180599180600180601180602180603180604180605180606180607180608180609180610180611180612180613180614180615180616180617180618180619180620180621180622180623180624180625180626180627180628180629180630180631180632180633180634180635180636180637180638180639180640180641180642180643180644180645180646180647180648180649180650180651180652180653180654180655180656180657180658180659180660180661180662180663180664180665180666180667180668180669180670180671180672180673180674180675180676180677180678180679180680180681180682180683180684180685180686180687180688180689180690180691180692180693180694180695180696180697180698180699180700180701180702180703180704180705180706180707180708180709180710180711180712180713180714180715180716180717180718180719180720180721180722180723180724180725180726180727180728180729180730180731180732180733180734180735180736180737180738180739180740180741180742180743180744180745180746180747180748180749180750180751180752180753180754180755180756180757180758180759180760180761180762180763180764180765180766180767180768180769180770180771180772180773180774180775180776180777180778180779180780180781180782180783180784180785180786180787180788180789180790180791180792180793180794180795180796180797180798180799180800180801180802180803180804180805180806180807180808180809180810180811180812180813180814180815180816180817180818180819180820180821180822180823180824180825180826180827180828180829180830180831180832180833180834180835180836180837180838180839180840180841180842180843180844180845180846180847180848180849180850180851180852180853180854180855180856180857180858180859180860180861180862180863180864180865180866180867180868180869180870180871180872180873180874180875180876180877180878180879180880180881180882180883180884180885180886180887180888180889180890180891180892180893180894180895180896180897180898180899180900180901180902180903180904180905180906180907180908180909180910180911180912180913180914180915180916180917180918180919180920180921180922180923180924180925180926180927180928180929180930180931180932180933180934180935180936180937180938180939180940180941180942180943180944180945180946180947180948180949180950180951180952180953180954180955180956180957180958180959180960180961180962180963180964180965180966180967180968180969180970180971180972180973180974180975180976180977180978180979180980180981180982180983180984180985180986180987180988180989180990180991180992180993180994180995180996180997180998180999181000181001181002181003181004181005181006181007181008181009181010181011181012181013181014181015181016181017181018181019181020181021181022181023181024181025181026181027181028181029181030181031181032181033181034181035181036181037181038181039181040181041181042181043181044181045181046181047181048181049181050181051181052181053181054181055181056181057181058181059181060181061181062181063181064181065181066181067181068181069181070181071181072181073181074181075181076181077181078181079181080181081181082181083181084181085181086181087181088181089181090181091181092181093181094181095181096181097181098181099181100181101181102181103181104181105181106181107181108181109181110181111181112181113181114181115181116181117181118181119181120181121181122181123181124181125181126181127181128181129181130181131181132181133181134181135181136181137181138181139181140181141181142181143181144181145181146181147181148181149181150181151181152181153181154181155181156181157181158181159181160181161181162181163181164181165181166181167181168181169181170181171181172181173181174181175181176181177181178181179181180181181181182181183181184181185181186181187181188181189181190181191181192181193181194181195181196181197181198181199181200181201181202181203181204181205181206181207181208181209181210181211181212181213181214181215181216181217181218181219181220181221181222181223181224181225181226181227181228181229181230181231181232181233181234181235181236181237181238181239181240181241181242181243181244181245181246181247181248181249181250181251181252181253181254181255181256181257181258181259181260181261181262181263181264181265181266181267181268181269181270181271181272181273181274181275181276181277181278181279181280181281181282181283181284181285181286181287181288181289181290181291181292181293181294181295181296181297181298181299181300181301181302181303181304181305181306181307181308181309181310181311181312181313181314181315181316181317181318181319181320181321181322181323181324181325181326181327181328181329181330181331181332181333181334181335181336181337181338181339181340181341181342181343181344181345181346181347181348181349181350181351181352181353181354181355181356181357181358181359181360181361181362181363181364181365181366181367181368181369181370181371181372181373181374181375181376181377181378181379181380181381181382181383181384181385181386181387181388181389181390181391181392181393181394181395181396181397181398181399181400181401181402181403181404181405181406181407181408181409181410181411181412181413181414181415181416181417181418181419181420181421181422181423181424181425181426181427181428181429181430181431181432181433181434181435181436181437181438181439181440181441181442181443181444181445181446181447181448181449181450181451181452181453181454181455181456181457181458181459181460181461181462181463181464181465181466181467181468181469181470181471181472181473181474181475181476181477181478181479181480181481181482181483181484181485181486181487181488181489181490181491181492181493181494181495181496181497181498181499181500181501181502181503181504181505181506181507181508181509181510181511181512181513181514181515181516181517181518181519181520181521181522181523181524181525181526181527181528181529181530181531181532181533181534181535181536181537181538181539181540181541181542181543181544181545181546181547181548181549181550181551181552181553181554181555181556181557181558181559181560181561181562181563181564181565181566181567181568181569181570181571181572181573181574181575181576181577181578181579181580181581181582181583181584181585181586181587181588181589181590181591181592181593181594181595181596181597181598181599181600181601181602181603181604181605181606181607181608181609181610181611181612181613181614181615181616181617181618181619181620181621181622181623181624181625181626181627181628181629181630181631181632181633181634181635181636181637181638181639181640181641181642181643181644181645181646181647181648181649181650181651181652181653181654181655181656181657181658181659181660181661181662181663181664181665181666181667181668181669181670181671181672181673181674181675181676181677181678181679181680181681181682181683181684181685181686181687181688181689181690181691181692181693181694181695181696181697181698181699181700181701181702181703181704181705181706181707181708181709181710181711181712181713181714181715181716181717181718181719181720181721181722181723181724181725181726181727181728181729181730181731181732181733181734181735181736181737181738181739181740181741181742181743181744181745181746181747181748181749181750181751181752181753181754181755181756181757181758181759181760181761181762181763181764181765181766181767181768181769181770181771181772181773181774181775181776181777181778181779181780181781181782181783181784181785181786181787181788181789181790181791181792181793181794181795181796181797181798181799181800181801181802181803181804181805181806181807181808181809181810181811181812181813181814181815181816181817181818181819181820181821181822181823181824181825181826181827181828181829181830181831181832181833181834181835181836181837181838181839181840181841181842181843181844181845181846181847181848181849181850181851181852181853181854181855181856181857181858181859181860181861181862181863181864181865181866181867181868181869181870181871181872181873181874181875181876181877181878181879181880181881181882181883181884181885181886181887181888181889181890181891181892181893181894181895181896181897181898181899181900181901181902181903181904181905181906181907181908181909181910181911181912181913181914181915181916181917181918181919181920181921181922181923181924181925181926181927181928181929181930181931181932181933181934181935181936181937181938181939181940181941181942181943181944181945181946181947181948181949181950181951181952181953181954181955181956181957181958181959181960181961181962181963181964181965181966181967181968181969181970181971181972181973181974181975181976181977181978181979181980181981181982181983181984181985181986181987181988181989181990181991181992181993181994181995181996181997181998181999182000182001182002182003182004182005182006182007182008182009182010182011182012182013182014182015182016182017182018182019182020182021182022182023182024182025182026182027182028182029182030182031182032182033182034182035182036182037182038182039182040182041182042182043182044182045182046182047182048182049182050182051182052182053182054182055182056182057182058182059182060182061182062182063182064182065182066182067182068182069182070182071182072182073182074182075182076182077182078182079182080182081182082182083182084182085182086182087182088182089182090182091182092182093182094182095182096182097182098182099182100182101182102182103182104182105182106182107182108182109182110182111182112182113182114182115182116182117182118182119182120182121182122182123182124182125182126182127182128182129182130182131182132182133182134182135182136182137182138182139182140182141182142182143182144182145182146182147182148182149182150182151182152182153182154182155182156182157182158182159182160182161182162182163182164182165182166182167182168182169182170182171182172182173182174182175182176182177182178182179182180182181182182182183182184182185182186182187182188182189182190182191182192182193182194182195182196182197182198182199182200182201182202182203182204182205182206182207182208182209182210182211182212182213182214182215182216182217182218182219182220182221182222182223182224182225182226182227182228182229182230182231182232182233182234182235182236182237182238182239182240182241182242182243182244182245182246182247182248182249182250182251182252182253182254182255182256182257182258182259182260182261182262182263182264182265182266182267182268182269182270182271182272182273182274182275182276182277182278182279182280182281182282182283182284182285182286182287182288182289182290182291182292182293182294182295182296182297182298182299182300182301182302182303182304182305182306182307182308182309182310182311182312182313182314182315182316182317182318182319182320182321182322182323182324182325182326182327182328182329182330182331182332182333182334182335182336182337182338182339182340182341182342182343182344182345182346182347182348182349182350182351182352182353182354182355182356182357182358182359182360182361182362182363182364182365182366182367182368182369182370182371182372182373182374182375182376182377182378182379182380182381182382182383182384182385182386182387182388182389182390182391182392182393182394182395182396182397182398182399182400182401182402182403182404182405182406182407182408182409182410182411182412182413182414182415182416182417182418182419182420182421182422182423182424182425182426182427182428182429182430182431182432182433182434182435182436182437182438182439182440182441182442182443182444182445182446182447182448182449182450182451182452182453182454182455182456182457182458182459182460182461182462182463182464182465182466182467182468182469182470182471182472182473182474182475182476182477182478182479182480182481182482182483182484182485182486182487182488182489182490182491182492182493182494182495182496182497182498182499182500182501182502182503182504182505182506182507182508182509182510182511182512182513182514182515182516182517182518182519182520182521182522182523182524182525182526182527182528182529182530182531182532182533182534182535182536182537182538182539182540182541182542182543182544182545182546182547182548182549182550182551182552182553182554182555182556182557182558182559182560182561182562182563182564182565182566182567182568182569182570182571182572182573182574182575182576182577182578182579182580182581182582182583182584182585182586182587182588182589182590182591182592182593182594182595182596182597182598182599182600182601182602182603182604182605182606182607182608182609182610182611182612182613182614182615182616182617182618182619182620182621182622182623182624182625182626182627182628182629182630182631182632182633182634182635182636182637182638182639182640182641182642182643182644182645182646182647182648182649182650182651182652182653182654182655182656182657182658182659182660182661182662182663182664182665182666182667182668182669182670182671182672182673182674182675182676182677182678182679182680182681182682182683182684182685182686182687182688182689182690182691182692182693182694182695182696182697182698182699182700182701182702182703182704182705182706182707182708182709182710182711182712182713182714182715182716182717182718182719182720182721182722182723182724182725182726182727182728182729182730182731182732182733182734182735182736182737182738182739182740182741182742182743182744182745182746182747182748182749182750182751182752182753182754182755182756182757182758182759182760182761182762182763182764182765182766182767182768182769182770182771182772182773182774182775182776182777182778182779182780182781182782182783182784182785182786182787182788182789182790182791182792182793182794182795182796182797182798182799182800182801182802182803182804182805182806182807182808182809182810182811182812182813182814182815182816182817182818182819182820182821182822182823182824182825182826182827182828182829182830182831182832182833182834182835182836182837182838182839182840182841182842182843182844182845182846182847182848182849182850182851182852182853182854182855182856182857182858182859182860182861182862182863182864182865182866182867182868182869182870182871182872182873182874182875182876182877182878182879182880182881182882182883182884182885182886182887182888182889182890182891182892182893182894182895182896182897182898182899182900182901182902182903182904182905182906182907182908182909182910182911182912182913182914182915182916182917182918182919182920182921182922182923182924182925182926182927182928182929182930182931182932182933182934182935182936182937182938182939182940182941182942182943182944182945182946182947182948182949182950182951182952182953182954182955182956182957182958182959182960182961182962182963182964182965182966182967182968182969182970182971182972182973182974182975182976182977182978182979182980182981182982182983182984182985182986182987182988182989182990182991182992182993182994182995182996182997182998182999183000183001183002183003183004183005183006183007183008183009183010183011183012183013183014183015183016183017183018183019183020183021183022183023183024183025183026183027183028183029183030183031183032183033183034183035183036183037183038183039183040183041183042183043183044183045183046183047183048183049183050183051183052183053183054183055183056183057183058183059183060183061183062183063183064183065183066183067183068183069183070183071183072183073183074183075183076183077183078183079183080183081183082183083183084183085183086183087183088183089183090183091183092183093183094183095183096183097183098183099183100183101183102183103183104183105183106183107183108183109183110183111183112183113183114183115183116183117183118183119183120183121183122183123183124183125183126183127183128183129183130183131183132183133183134183135183136183137183138183139183140183141183142183143183144183145183146183147183148183149183150183151183152183153183154183155183156183157183158183159183160183161183162183163183164183165183166183167183168183169183170183171183172183173183174183175183176183177183178183179183180183181183182183183183184183185183186183187183188183189183190183191183192183193183194183195183196183197183198183199183200183201183202183203183204183205183206183207183208183209183210183211183212183213183214183215183216183217183218183219183220183221183222183223183224183225183226183227183228183229183230183231183232183233183234183235183236183237183238183239183240183241183242183243183244183245183246183247183248183249183250183251183252183253183254183255183256183257183258183259183260183261183262183263183264183265183266183267183268183269183270183271183272183273183274183275183276183277183278183279183280183281183282183283183284183285183286183287183288183289183290183291183292183293183294183295183296183297183298183299183300183301183302183303183304183305183306183307183308183309183310183311183312183313183314183315183316183317183318183319183320183321183322183323183324183325183326183327183328183329183330183331183332183333183334183335183336183337183338183339183340183341183342183343183344183345183346183347183348183349183350183351183352183353183354183355183356183357183358183359183360183361183362183363183364183365183366183367183368183369183370183371183372183373183374183375183376183377183378183379183380183381183382183383183384183385183386183387183388183389183390183391183392183393183394183395183396183397183398183399183400183401183402183403183404183405183406183407183408183409183410183411183412183413183414183415183416183417183418183419183420183421183422183423183424183425183426183427183428183429183430183431183432183433183434183435183436183437183438183439183440183441183442183443183444183445183446183447183448183449183450183451183452183453183454183455183456183457183458183459183460183461183462183463183464183465183466183467183468183469183470183471183472183473183474183475183476183477183478183479183480183481183482183483183484183485183486183487183488183489183490183491183492183493183494183495183496183497183498183499183500183501183502183503183504183505183506183507183508183509183510183511183512183513183514183515183516183517183518183519183520183521183522183523183524183525183526183527183528183529183530183531183532183533183534183535183536183537183538183539183540183541183542183543183544183545183546183547183548183549183550183551183552183553183554183555183556183557183558183559183560183561183562183563183564183565183566183567183568183569183570183571183572183573183574183575183576183577183578183579183580183581183582183583183584183585183586183587183588183589183590183591183592183593183594183595183596183597183598183599183600183601183602183603183604183605183606183607183608183609183610183611183612183613183614183615183616183617183618183619183620183621183622183623183624183625183626183627183628183629183630183631183632183633183634183635183636183637183638183639183640183641183642183643183644183645183646183647183648183649183650183651183652183653183654183655183656183657183658183659183660183661183662183663183664183665183666183667183668183669183670183671183672183673183674183675183676183677183678183679183680183681183682183683183684183685183686183687183688183689183690183691183692183693183694183695183696183697183698183699183700183701183702183703183704183705183706183707183708183709183710183711183712183713183714183715183716183717183718183719183720183721183722183723183724183725183726183727183728183729183730183731183732183733183734183735183736183737183738183739183740183741183742183743183744183745183746183747183748183749183750183751183752183753183754183755183756183757183758183759183760183761183762183763183764183765183766183767183768183769183770183771183772183773183774183775183776183777183778183779183780183781183782183783183784183785183786183787183788183789183790183791183792183793183794183795183796183797183798183799183800183801183802183803183804183805183806183807183808183809183810183811183812183813183814183815183816183817183818183819183820183821183822183823183824183825183826183827183828183829183830183831183832183833183834183835183836183837183838183839183840183841183842183843183844183845183846183847183848183849183850183851183852183853183854183855183856183857183858183859183860183861183862183863183864183865183866183867183868183869183870183871183872183873183874183875183876183877183878183879183880183881183882183883183884183885183886183887183888183889183890183891183892183893183894183895183896183897183898183899183900183901183902183903183904183905183906183907183908183909183910183911183912183913183914183915183916183917183918183919183920183921183922183923183924183925183926183927183928183929183930183931183932183933183934183935183936183937183938183939183940183941183942183943183944183945183946183947183948183949183950183951183952183953183954183955183956183957183958183959183960183961183962183963183964183965183966183967183968183969183970183971183972183973183974183975183976183977183978183979183980183981183982183983183984183985183986183987183988183989183990183991183992183993183994183995183996183997183998183999184000184001184002184003184004184005184006184007184008184009184010184011184012184013184014184015184016184017184018184019184020184021184022184023184024184025184026184027184028184029184030184031184032184033184034184035184036184037184038184039184040184041184042184043184044184045184046184047184048184049184050184051184052184053184054184055184056184057184058184059184060184061184062184063184064184065184066184067184068184069184070184071184072184073184074184075184076184077184078184079184080184081184082184083184084184085184086184087184088184089184090184091184092184093184094184095184096184097184098184099184100184101184102184103184104184105184106184107184108184109184110184111184112184113184114184115184116184117184118184119184120184121184122184123184124184125184126184127184128184129184130184131184132184133184134184135184136184137184138184139184140184141184142184143184144184145184146184147184148184149184150184151184152184153184154184155184156184157184158184159184160184161184162184163184164184165184166184167184168184169184170184171184172184173184174184175184176184177184178184179184180184181184182184183184184184185184186184187184188184189184190184191184192184193184194184195184196184197184198184199184200184201184202184203184204184205184206184207184208184209184210184211184212184213184214184215184216184217184218184219184220184221184222184223184224184225184226184227184228184229184230184231184232184233184234184235184236184237184238184239184240184241184242184243184244184245184246184247184248184249184250184251184252184253184254184255184256184257184258184259184260184261184262184263184264184265184266184267184268184269184270184271184272184273184274184275184276184277184278184279184280184281184282184283184284184285184286184287184288184289184290184291184292184293184294184295184296184297184298184299184300184301184302184303184304184305184306184307184308184309184310184311184312184313184314184315184316184317184318184319184320184321184322184323184324184325184326184327184328184329184330184331184332184333184334184335184336184337184338184339184340184341184342184343184344184345184346184347184348184349184350184351184352184353184354184355184356184357184358184359184360184361184362184363184364184365184366184367184368184369184370184371184372184373184374184375184376184377184378184379184380184381184382184383184384184385184386184387184388184389184390184391184392184393184394184395184396184397184398184399184400184401184402184403184404184405184406184407184408184409184410184411184412184413184414184415184416184417184418184419184420184421184422184423184424184425184426184427184428184429184430184431184432184433184434184435184436184437184438184439184440184441184442184443184444184445184446184447184448184449184450184451184452184453184454184455184456184457184458184459184460184461184462184463184464184465184466184467184468184469184470184471184472184473184474184475184476184477184478184479184480184481184482184483184484184485184486184487184488184489184490184491184492184493184494184495184496184497184498184499184500184501184502184503184504184505184506184507184508184509184510184511184512184513184514184515184516184517184518184519184520184521184522184523184524184525184526184527184528184529184530184531184532184533184534184535184536184537184538184539184540184541184542184543184544184545184546184547184548184549184550184551184552184553184554184555184556184557184558184559184560184561184562184563184564184565184566184567184568184569184570184571184572184573184574184575184576184577184578184579184580184581184582184583184584184585184586184587184588184589184590184591184592184593184594184595184596184597184598184599184600184601184602184603184604184605184606184607184608184609184610184611184612184613184614184615184616184617184618184619184620184621184622184623184624184625184626184627184628184629184630184631184632184633184634184635184636184637184638184639184640184641184642184643184644184645184646184647184648184649184650184651184652184653184654184655184656184657184658184659184660184661184662184663184664184665184666184667184668184669184670184671184672184673184674184675184676184677184678184679184680184681184682184683184684184685184686184687184688184689184690184691184692184693184694184695184696184697184698184699184700184701184702184703184704184705184706184707184708184709184710184711184712184713184714184715184716184717184718184719184720184721184722184723184724184725184726184727184728184729184730184731184732184733184734184735184736184737184738184739184740184741184742184743184744184745184746184747184748184749184750184751184752184753184754184755184756184757184758184759184760184761184762184763184764184765184766184767184768184769184770184771184772184773184774184775184776184777184778184779184780184781184782184783184784184785184786184787184788184789184790184791184792184793184794184795184796184797184798184799184800184801184802184803184804184805184806184807184808184809184810184811184812184813184814184815184816184817184818184819184820184821184822184823184824184825184826184827184828184829184830184831184832184833184834184835184836184837184838184839184840184841184842184843184844184845184846184847184848184849184850184851184852184853184854184855184856184857184858184859184860184861184862184863184864184865184866184867184868184869184870184871184872184873184874184875184876184877184878184879184880184881184882184883184884184885184886184887184888184889184890184891184892184893184894184895184896184897184898184899184900184901184902184903184904184905184906184907184908184909184910184911184912184913184914184915184916184917184918184919184920184921184922184923184924184925184926184927184928184929184930184931184932184933184934184935184936184937184938184939184940184941184942184943184944184945184946184947184948184949184950184951184952184953184954184955184956184957184958184959184960184961184962184963184964184965184966184967184968184969184970184971184972184973184974184975184976184977184978184979184980184981184982184983184984184985184986184987184988184989184990184991184992184993184994184995184996184997184998184999185000185001185002185003185004185005185006185007185008185009185010185011185012185013185014185015185016185017185018185019185020185021185022185023185024185025185026185027185028185029185030185031185032185033185034185035185036185037185038185039185040185041185042185043185044185045185046185047185048185049185050185051185052185053185054185055185056185057185058185059185060185061185062185063185064185065185066185067185068185069185070185071185072185073185074185075185076185077185078185079185080185081185082185083185084185085185086185087185088185089185090185091185092185093185094185095185096185097185098185099185100185101185102185103185104185105185106185107185108185109185110185111185112185113185114185115185116185117185118185119185120185121185122185123185124185125185126185127185128185129185130185131185132185133185134185135185136185137185138185139185140185141185142185143185144185145185146185147185148185149185150185151185152185153185154185155185156185157185158185159185160185161185162185163185164185165185166185167185168185169185170185171185172185173185174185175185176185177185178185179185180185181185182185183185184185185185186185187185188185189185190185191185192185193185194185195185196185197185198185199185200185201185202185203185204185205185206185207185208185209185210185211185212185213185214185215185216185217185218185219185220185221185222185223185224185225185226185227185228185229185230185231185232185233185234185235185236185237185238185239185240185241185242185243185244185245185246185247185248185249185250185251185252185253185254185255185256185257185258185259185260185261185262185263185264185265185266185267185268185269185270185271185272185273185274185275185276185277185278185279185280185281185282185283185284185285185286185287185288185289185290185291185292185293185294185295185296185297185298185299185300185301185302185303185304185305185306185307185308185309185310185311185312185313185314185315185316185317185318185319185320185321185322185323185324185325185326185327185328185329185330185331185332185333185334185335185336185337185338185339185340185341185342185343185344185345185346185347185348185349185350185351185352185353185354185355185356185357185358185359185360185361185362185363185364185365185366185367185368185369185370185371185372185373185374185375185376185377185378185379185380185381185382185383185384185385185386185387185388185389185390185391185392185393185394185395185396185397185398185399185400185401185402185403185404185405185406185407185408185409185410185411185412185413185414185415185416185417185418185419185420185421185422185423185424185425185426185427185428185429185430185431185432185433185434185435185436185437185438185439185440185441185442185443185444185445185446185447185448185449185450185451185452185453185454185455185456185457185458185459185460185461185462185463185464185465185466185467185468185469185470185471185472185473185474185475185476185477185478185479185480185481185482185483185484185485185486185487185488185489185490185491185492185493185494185495185496185497185498185499185500185501185502185503185504185505185506185507185508185509185510185511185512185513185514185515185516185517185518185519185520185521185522185523185524185525185526185527185528185529185530185531185532185533185534185535185536185537185538185539185540185541185542185543185544185545185546185547185548185549185550185551185552185553185554185555185556185557185558185559185560185561185562185563185564185565185566185567185568185569185570185571185572185573185574185575185576185577185578185579185580185581185582185583185584185585185586185587185588185589185590185591185592185593185594185595185596185597185598185599185600185601185602185603185604185605185606185607185608185609185610185611185612185613185614185615185616185617185618185619185620185621185622185623185624185625185626185627185628185629185630185631185632185633185634185635185636185637185638185639185640185641185642185643185644185645185646185647185648185649185650185651185652185653185654185655185656185657185658185659185660185661185662185663185664185665185666185667185668185669185670185671185672185673185674185675185676185677185678185679185680185681185682185683185684185685185686185687185688185689185690185691185692185693185694185695185696185697185698185699185700185701185702185703185704185705185706185707185708185709185710185711185712185713185714185715185716185717185718185719185720185721185722185723185724185725185726185727185728185729185730185731185732185733185734185735185736185737185738185739185740185741185742185743185744185745185746185747185748185749185750185751185752185753185754185755185756185757185758185759185760185761185762185763185764185765185766185767185768185769185770185771185772185773185774185775185776185777185778185779185780185781185782185783185784185785185786185787185788185789185790185791185792185793185794185795185796185797185798185799185800185801185802185803185804185805185806185807185808185809185810185811185812185813185814185815185816185817185818185819185820185821185822185823185824185825185826185827185828185829185830185831185832185833185834185835185836185837185838185839185840185841185842185843185844185845185846185847185848185849185850185851185852185853185854185855185856185857185858185859185860185861185862185863185864185865185866185867185868185869185870185871185872185873185874185875185876185877185878185879185880185881185882185883185884185885185886185887185888185889185890185891185892185893185894185895185896185897185898185899185900185901185902185903185904185905185906185907185908185909185910185911185912185913185914185915185916185917185918185919185920185921185922185923185924185925185926185927185928185929185930185931185932185933185934185935185936185937185938185939185940185941185942185943185944185945185946185947185948185949185950185951185952185953185954185955185956185957185958185959185960185961185962185963185964185965185966185967185968185969185970185971185972185973185974185975185976185977185978185979185980185981185982185983185984185985185986185987185988185989185990185991185992185993185994185995185996185997185998185999186000186001186002186003186004186005186006186007186008186009186010186011186012186013186014186015186016186017186018186019186020186021186022186023186024186025186026186027186028186029186030186031186032186033186034186035186036186037186038186039186040186041186042186043186044186045186046186047186048186049186050186051186052186053186054186055186056186057186058186059186060186061186062186063186064186065186066186067186068186069186070186071186072186073186074186075186076186077186078186079186080186081186082186083186084186085186086186087186088186089186090186091186092186093186094186095186096186097186098186099186100186101186102186103186104186105186106186107186108186109186110186111186112186113186114186115186116186117186118186119186120186121186122186123186124186125186126186127186128186129186130186131186132186133186134186135186136186137186138186139186140186141186142186143186144186145186146186147186148186149186150186151186152186153186154186155186156186157186158186159186160186161186162186163186164186165186166186167186168186169186170186171186172186173186174186175186176186177186178186179186180186181186182186183186184186185186186186187186188186189186190186191186192186193186194186195186196186197186198186199186200186201186202186203186204186205186206186207186208186209186210186211186212186213186214186215186216186217186218186219186220186221186222186223186224186225186226186227186228186229186230186231186232186233186234186235186236186237186238186239186240186241186242186243186244186245186246186247186248186249186250186251186252186253186254186255186256186257186258186259186260186261186262186263186264186265186266186267186268186269186270186271186272186273186274186275186276186277186278186279186280186281186282186283186284186285186286186287186288186289186290186291186292186293186294186295186296186297186298186299186300186301186302186303186304186305186306186307186308186309186310186311186312186313186314186315186316186317186318186319186320186321186322186323186324186325186326186327186328186329186330186331186332186333186334186335186336186337186338186339186340186341186342186343186344186345186346186347186348186349186350186351186352186353186354186355186356186357186358186359186360186361186362186363186364186365186366186367186368186369186370186371186372186373186374186375186376186377186378186379186380186381186382186383186384186385186386186387186388186389186390186391186392186393186394186395186396186397186398186399186400186401186402186403186404186405186406186407186408186409186410186411186412186413186414186415186416186417186418186419186420186421186422186423186424186425186426186427186428186429186430186431186432186433186434186435186436186437186438186439186440186441186442186443186444186445186446186447186448186449186450186451186452186453186454186455186456186457186458186459186460186461186462186463186464186465186466186467186468186469186470186471186472186473186474186475186476186477186478186479186480186481186482186483186484186485186486186487186488186489186490186491186492186493186494186495186496186497186498186499186500186501186502186503186504186505186506186507186508186509186510186511186512186513186514186515186516186517186518186519186520186521186522186523186524186525186526186527186528186529186530186531186532186533186534186535186536186537186538186539186540186541186542186543186544186545186546186547186548186549186550186551186552186553186554186555186556186557186558186559186560186561186562186563186564186565186566186567186568186569186570186571186572186573186574186575186576186577186578186579186580186581186582186583186584186585186586186587186588186589186590186591186592186593186594186595186596186597186598186599186600186601186602186603186604186605186606186607186608186609186610186611186612186613186614186615186616186617186618186619186620186621186622186623186624186625186626186627186628186629186630186631186632186633186634186635186636186637186638186639186640186641186642186643186644186645186646186647186648186649186650186651186652186653186654186655186656186657186658186659186660186661186662186663186664186665186666186667186668186669186670186671186672186673186674186675186676186677186678186679186680186681186682186683186684186685186686186687186688186689186690186691186692186693186694186695186696186697186698186699186700186701186702186703186704186705186706186707186708186709186710186711186712186713186714186715186716186717186718186719186720186721186722186723186724186725186726186727186728186729186730186731186732186733186734186735186736186737186738186739186740186741186742186743186744186745186746186747186748186749186750186751186752186753186754186755186756186757186758186759186760186761186762186763186764186765186766186767186768186769186770186771186772186773186774186775186776186777186778186779186780186781186782186783186784186785186786186787186788186789186790186791186792186793186794186795186796186797186798186799186800186801186802186803186804186805186806186807186808186809186810186811186812186813186814186815186816186817186818186819186820186821186822186823186824186825186826186827186828186829186830186831186832186833186834186835186836186837186838186839186840186841186842186843186844186845186846186847186848186849186850186851186852186853186854186855186856186857186858186859186860186861186862186863186864186865186866186867186868186869186870186871186872186873186874186875186876186877186878186879186880186881186882186883186884186885186886186887186888186889186890186891186892186893186894186895186896186897186898186899186900186901186902186903186904186905186906186907186908186909186910186911186912186913186914186915186916186917186918186919186920186921186922186923186924186925186926186927186928186929186930186931186932186933186934186935186936186937186938186939186940186941186942186943186944186945186946186947186948186949186950186951186952186953186954186955186956186957186958186959186960186961186962186963186964186965186966186967186968186969186970186971186972186973186974186975186976186977186978186979186980186981186982186983186984186985186986186987186988186989186990186991186992186993186994186995186996186997186998186999187000187001187002187003187004187005187006187007187008187009187010187011187012187013187014187015187016187017187018187019187020187021187022187023187024187025187026187027187028187029187030187031187032187033187034187035187036187037187038187039187040187041187042187043187044187045187046187047187048187049187050187051187052187053187054187055187056187057187058187059187060187061187062187063187064187065187066187067187068187069187070187071187072187073187074187075187076187077187078187079187080187081187082187083187084187085187086187087187088187089187090187091187092187093187094187095187096187097187098187099187100187101187102187103187104187105187106187107187108187109187110187111187112187113187114187115187116187117187118187119187120187121187122187123187124187125187126187127187128187129187130187131187132187133187134187135187136187137187138187139187140187141187142187143187144187145187146187147187148187149187150187151187152187153187154187155187156187157187158187159187160187161187162187163187164187165187166187167187168187169187170187171187172187173187174187175187176187177187178187179187180187181187182187183187184187185187186187187187188187189187190187191187192187193187194187195187196187197187198187199187200187201187202187203187204187205187206187207187208187209187210187211187212187213187214187215187216187217187218187219187220187221187222187223187224187225187226187227187228187229187230187231187232187233187234187235187236187237187238187239187240187241187242187243187244187245187246187247187248187249187250187251187252187253187254187255187256187257187258187259187260187261187262187263187264187265187266187267187268187269187270187271187272187273187274187275187276187277187278187279187280187281187282187283187284187285187286187287187288187289187290187291187292187293187294187295187296187297187298187299187300187301187302187303187304187305187306187307187308187309187310187311187312187313187314187315187316187317187318187319187320187321187322187323187324187325187326187327187328187329187330187331187332187333187334187335187336187337187338187339187340187341187342187343187344187345187346187347187348187349187350187351187352187353187354187355187356187357187358187359187360187361187362187363187364187365187366187367187368187369187370187371187372187373187374187375187376187377187378187379187380187381187382187383187384187385187386187387187388187389187390187391187392187393187394187395187396187397187398187399187400187401187402187403187404187405187406187407187408187409187410187411187412187413187414187415187416187417187418187419187420187421187422187423187424187425187426187427187428187429187430187431187432187433187434187435187436187437187438187439187440187441187442187443187444187445187446187447187448187449187450187451187452187453187454187455187456187457187458187459187460187461187462187463187464187465187466187467187468187469187470187471187472187473187474187475187476187477187478187479187480187481187482187483187484187485187486187487187488187489187490187491187492187493187494187495187496187497187498187499187500187501187502187503187504187505187506187507187508187509187510187511187512187513187514187515187516187517187518187519187520187521187522187523187524187525187526187527187528187529187530187531187532187533187534187535187536187537187538187539187540187541187542187543187544187545187546187547187548187549187550187551187552187553187554187555187556187557187558187559187560187561187562187563187564187565187566187567187568187569187570187571187572187573187574187575187576187577187578187579187580187581187582187583187584187585187586187587187588187589187590187591187592187593187594187595187596187597187598187599187600187601187602187603187604187605187606187607187608187609187610187611187612187613187614187615187616187617187618187619187620187621187622187623187624187625187626187627187628187629187630187631187632187633187634187635187636187637187638187639187640187641187642187643187644187645187646187647187648187649187650187651187652187653187654187655187656187657187658187659187660187661187662187663187664187665187666187667187668187669187670187671187672187673187674187675187676187677187678187679187680187681187682187683187684187685187686187687187688187689187690187691187692187693187694187695187696187697187698187699187700187701187702187703187704187705187706187707187708187709187710187711187712187713187714187715187716187717187718187719187720187721187722187723187724187725187726187727187728187729187730187731187732187733187734187735187736187737187738187739187740187741187742187743187744187745187746187747187748187749187750187751187752187753187754187755187756187757187758187759187760187761187762187763187764187765187766187767187768187769187770187771187772187773187774187775187776187777187778187779187780187781187782187783187784187785187786187787187788187789187790187791187792187793187794187795187796187797187798187799187800187801187802187803187804187805187806187807187808187809187810187811187812187813187814187815187816187817187818187819187820187821187822187823187824187825187826187827187828187829187830187831187832187833187834187835187836187837187838187839187840187841187842187843187844187845187846187847187848187849187850187851187852187853187854187855187856187857187858187859187860187861187862187863187864187865187866187867187868187869187870187871187872187873187874187875187876187877187878187879187880187881187882187883187884187885187886187887187888187889187890187891187892187893187894187895187896187897187898187899187900187901187902187903187904187905187906187907187908187909187910187911187912187913187914187915187916187917187918187919187920187921187922187923187924187925187926187927187928187929187930187931187932187933187934187935187936187937187938187939187940187941187942187943187944187945187946187947187948187949187950187951187952187953187954187955187956187957187958187959187960187961187962187963187964187965187966187967187968187969187970187971187972187973187974187975187976187977187978187979187980187981187982187983187984187985187986187987187988187989187990187991187992187993187994187995187996187997187998187999188000188001188002188003188004188005188006188007188008188009188010188011188012188013188014188015188016188017188018188019188020188021188022188023188024188025188026188027188028188029188030188031188032188033188034188035188036188037188038188039188040188041188042188043188044188045188046188047188048188049188050188051188052188053188054188055188056188057188058188059188060188061188062188063188064188065188066188067188068188069188070188071188072188073188074188075188076188077188078188079188080188081188082188083188084188085188086188087188088188089188090188091188092188093188094188095188096188097188098188099188100188101188102188103188104188105188106188107188108188109188110188111188112188113188114188115188116188117188118188119188120188121188122188123188124188125188126188127188128188129188130188131188132188133188134188135188136188137188138188139188140188141188142188143188144188145188146188147188148188149188150188151188152188153188154188155188156188157188158188159188160188161188162188163188164188165188166188167188168188169188170188171188172188173188174188175188176188177188178188179188180188181188182188183188184188185188186188187188188188189188190188191188192188193188194188195188196188197188198188199188200188201188202188203188204188205188206188207188208188209188210188211188212188213188214188215188216188217188218188219188220188221188222188223188224188225188226188227188228188229188230188231188232188233188234188235188236188237188238188239188240188241188242188243188244188245188246188247188248188249188250188251188252188253188254188255188256188257188258188259188260188261188262188263188264188265188266188267188268188269188270188271188272188273188274188275188276188277188278188279188280188281188282188283188284188285188286188287188288188289188290188291188292188293188294188295188296188297188298188299188300188301188302188303188304188305188306188307188308188309188310188311188312188313188314188315188316188317188318188319188320188321188322188323188324188325188326188327188328188329188330188331188332188333188334188335188336188337188338188339188340188341188342188343188344188345188346188347188348188349188350188351188352188353188354188355188356188357188358188359188360188361188362188363188364188365188366188367188368188369188370188371188372188373188374188375188376188377188378188379188380188381188382188383188384188385188386188387188388188389188390188391188392188393188394188395188396188397188398188399188400188401188402188403188404188405188406188407188408188409188410188411188412188413188414188415188416188417188418188419188420188421188422188423188424188425188426188427188428188429188430188431188432188433188434188435188436188437188438188439188440188441188442188443188444188445188446188447188448188449188450188451188452188453188454188455188456188457188458188459188460188461188462188463188464188465188466188467188468188469188470188471188472188473188474188475188476188477188478188479188480188481188482188483188484188485188486188487188488188489188490188491188492188493188494188495188496188497188498188499188500188501188502188503188504188505188506188507188508188509188510188511188512188513188514188515188516188517188518188519188520188521188522188523188524188525188526188527188528188529188530188531188532188533188534188535188536188537188538188539188540188541188542188543188544188545188546188547188548188549188550188551188552188553188554188555188556188557188558188559188560188561188562188563188564188565188566188567188568188569188570188571188572188573188574188575188576188577188578188579188580188581188582188583188584188585188586188587188588188589188590188591188592188593188594188595188596188597188598188599188600188601188602188603188604188605188606188607188608188609188610188611188612188613188614188615188616188617188618188619188620188621188622188623188624188625188626188627188628188629188630188631188632188633188634188635188636188637188638188639188640188641188642188643188644188645188646188647188648188649188650188651188652188653188654188655188656188657188658188659188660188661188662188663188664188665188666188667188668188669188670188671188672188673188674188675188676188677188678188679188680188681188682188683188684188685188686188687188688188689188690188691188692188693188694188695188696188697188698188699188700188701188702188703188704188705188706188707188708188709188710188711188712188713188714188715188716188717188718188719188720188721188722188723188724188725188726188727188728188729188730188731188732188733188734188735188736188737188738188739188740188741188742188743188744188745188746188747188748188749188750188751188752188753188754188755188756188757188758188759188760188761188762188763188764188765188766188767188768188769188770188771188772188773188774188775188776188777188778188779188780188781188782188783188784188785188786188787188788188789188790188791188792188793188794188795188796188797188798188799188800188801188802188803188804188805188806188807188808188809188810188811188812188813188814188815188816188817188818188819188820188821188822188823188824188825188826188827188828188829188830188831188832188833188834188835188836188837188838188839188840188841188842188843188844188845188846188847188848188849188850188851188852188853188854188855188856188857188858188859188860188861188862188863188864188865188866188867188868188869188870188871188872188873188874188875188876188877188878188879188880188881188882188883188884188885188886188887188888188889188890188891188892188893188894188895188896188897188898188899188900188901188902188903188904188905188906188907188908188909188910188911188912188913188914188915188916188917188918188919188920188921188922188923188924188925188926188927188928188929188930188931188932188933188934188935188936188937188938188939188940188941188942188943188944188945188946188947188948188949188950188951188952188953188954188955188956188957188958188959188960188961188962188963188964188965188966188967188968188969188970188971188972188973188974188975188976188977188978188979188980188981188982188983188984188985188986188987188988188989188990188991188992188993188994188995188996188997188998188999189000189001189002189003189004189005189006189007189008189009189010189011189012189013189014189015189016189017189018189019189020189021189022189023189024189025189026189027189028189029189030189031189032189033189034189035189036189037189038189039189040189041189042189043189044189045189046189047189048189049189050189051189052189053189054189055189056189057189058189059189060189061189062189063189064189065189066189067189068189069189070189071189072189073189074189075189076189077189078189079189080189081189082189083189084189085189086189087189088189089189090189091189092189093189094189095189096189097189098189099189100189101189102189103189104189105189106189107189108189109189110189111189112189113189114189115189116189117189118189119189120189121189122189123189124189125189126189127189128189129189130189131189132189133189134189135189136189137189138189139189140189141189142189143189144189145189146189147189148189149189150189151189152189153189154189155189156189157189158189159189160189161189162189163189164189165189166189167189168189169189170189171189172189173189174189175189176189177189178189179189180189181189182189183189184189185189186189187189188189189189190189191189192189193189194189195189196189197189198189199189200189201189202189203189204189205189206189207189208189209189210189211189212189213189214189215189216189217189218189219189220189221189222189223189224189225189226189227189228189229189230189231189232189233189234189235189236189237189238189239189240189241189242189243189244189245189246189247189248189249189250189251189252189253189254189255189256189257189258189259189260189261189262189263189264189265189266189267189268189269189270189271189272189273189274189275189276189277189278189279189280189281189282189283189284189285189286189287189288189289189290189291189292189293189294189295189296189297189298189299189300189301189302189303189304189305189306189307189308189309189310189311189312189313189314189315189316189317189318189319189320189321189322189323189324189325189326189327189328189329189330189331189332189333189334189335189336189337189338189339189340189341189342189343189344189345189346189347189348189349189350189351189352189353189354189355189356189357189358189359189360189361189362189363189364189365189366189367189368189369189370189371189372189373189374189375189376189377189378189379189380189381189382189383189384189385189386189387189388189389189390189391189392189393189394189395189396189397189398189399189400189401189402189403189404189405189406189407189408189409189410189411189412189413189414189415189416189417189418189419189420189421189422189423189424189425189426189427189428189429189430189431189432189433189434189435189436189437189438189439189440189441189442189443189444189445189446189447189448189449189450189451189452189453189454189455189456189457189458189459189460189461189462189463189464189465189466189467189468189469189470189471189472189473189474189475189476189477189478189479189480189481189482189483189484189485189486189487189488189489189490189491189492189493189494189495189496189497189498189499189500189501189502189503189504189505189506189507189508189509189510189511189512189513189514189515189516189517189518189519189520189521189522189523189524189525189526189527189528189529189530189531189532189533189534189535189536189537189538189539189540189541189542189543189544189545189546189547189548189549189550189551189552189553189554189555189556189557189558189559189560189561189562189563189564189565189566189567189568189569189570189571189572189573189574189575189576189577189578189579189580189581189582189583189584189585189586189587189588189589189590189591189592189593189594189595189596189597189598189599189600189601189602189603189604189605189606189607189608189609189610189611189612189613189614189615189616189617189618189619189620189621189622189623189624189625189626189627189628189629189630189631189632189633189634189635189636189637189638189639189640189641189642189643189644189645189646189647189648189649189650189651189652189653189654189655189656189657189658189659189660189661189662189663189664189665189666189667189668189669189670189671189672189673189674189675189676189677189678189679189680189681189682189683189684189685189686189687189688189689189690189691189692189693189694189695189696189697189698189699189700189701189702189703189704189705189706189707189708189709189710189711189712189713189714189715189716189717189718189719189720189721189722189723189724189725189726189727189728189729189730189731189732189733189734189735189736189737189738189739189740189741189742189743189744189745189746189747189748189749189750189751189752189753189754189755189756189757189758189759189760189761189762189763189764189765189766189767189768189769189770189771189772189773189774189775189776189777189778189779189780189781189782189783189784189785189786189787189788189789189790189791189792189793189794189795189796189797189798189799189800189801189802189803189804189805189806189807189808189809189810189811189812189813189814189815189816189817189818189819189820189821189822189823189824189825189826189827189828189829189830189831189832189833189834189835189836189837189838189839189840189841189842189843189844189845189846189847189848189849189850189851189852189853189854189855189856189857189858189859189860189861189862189863189864189865189866189867189868189869189870189871189872189873189874189875189876189877189878189879189880189881189882189883189884189885189886189887189888189889189890189891189892189893189894189895189896189897189898189899189900189901189902189903189904189905189906189907189908189909189910189911189912189913189914189915189916189917189918189919189920189921189922189923189924189925189926189927189928189929189930189931189932189933189934189935189936189937189938189939189940189941189942189943189944189945189946189947189948189949189950189951189952189953189954189955189956189957189958189959189960189961189962189963189964189965189966189967189968189969189970189971189972189973189974189975189976189977189978189979189980189981189982189983189984189985189986189987189988189989189990189991189992189993189994189995189996189997189998189999190000190001190002190003190004190005190006190007190008190009190010190011190012190013190014190015190016190017190018190019190020190021190022190023190024190025190026190027190028190029190030190031190032190033190034190035190036190037190038190039190040190041190042190043190044190045190046190047190048190049190050190051190052190053190054190055190056190057190058190059190060190061190062190063190064190065190066190067190068190069190070190071190072190073190074190075190076190077190078190079190080190081190082190083190084190085190086190087190088190089190090190091190092190093190094190095190096190097190098190099190100190101190102190103190104190105190106190107190108190109190110190111190112190113190114190115190116190117190118190119190120190121190122190123190124190125190126190127190128190129190130190131190132190133190134190135190136190137190138190139190140190141190142190143190144190145190146190147190148190149190150190151190152190153190154190155190156190157190158190159190160190161190162190163190164190165190166190167190168190169190170190171190172190173190174190175190176190177190178190179190180190181190182190183190184190185190186190187190188190189190190190191190192190193190194190195190196190197190198190199190200190201190202190203190204190205190206190207190208190209190210190211190212190213190214190215190216190217190218190219190220190221190222190223190224190225190226190227190228190229190230190231190232190233190234190235190236190237190238190239190240190241190242190243190244190245190246190247190248190249190250190251190252190253190254190255190256190257190258190259190260190261190262190263190264190265190266190267190268190269190270190271190272190273190274190275190276190277190278190279190280190281190282190283190284190285190286190287190288190289190290190291190292190293190294190295190296190297190298190299190300190301190302190303190304190305190306190307190308190309190310190311190312190313190314190315190316190317190318190319190320190321190322190323190324190325190326190327190328190329190330190331190332190333190334190335190336190337190338190339190340190341190342190343190344190345190346190347190348190349190350190351190352190353190354190355190356190357190358190359190360190361190362190363190364190365190366190367190368190369190370190371190372190373190374190375190376190377190378190379190380190381190382190383190384190385190386190387190388190389190390190391190392190393190394190395190396190397190398190399190400190401190402190403190404190405190406190407190408190409190410190411190412190413190414190415190416190417190418190419190420190421190422190423190424190425190426190427190428190429190430190431190432190433190434190435190436190437190438190439190440190441190442190443190444190445190446190447190448190449190450190451190452190453190454190455190456190457190458190459190460190461190462190463190464190465190466190467190468190469190470190471190472190473190474190475190476190477190478190479190480190481190482190483190484190485190486190487190488190489190490190491190492190493190494190495190496190497190498190499190500190501190502190503190504190505190506190507190508190509190510190511190512190513190514190515190516190517190518190519190520190521190522190523190524190525190526190527190528190529190530190531190532190533190534190535190536190537190538190539190540190541190542190543190544190545190546190547190548190549190550190551190552190553190554190555190556190557190558190559190560190561190562190563190564190565190566190567190568190569190570190571190572190573190574190575190576190577190578190579190580190581190582190583190584190585190586190587190588190589190590190591190592190593190594190595190596190597190598190599190600190601190602190603190604190605190606190607190608190609190610190611190612190613190614190615190616190617190618190619190620190621190622190623190624190625190626190627190628190629190630190631190632190633190634190635190636190637190638190639190640190641190642190643190644190645190646190647190648190649190650190651190652190653190654190655190656190657190658190659190660190661190662190663190664190665190666190667190668190669190670190671190672190673190674190675190676190677190678190679190680190681190682190683190684190685190686190687190688190689190690190691190692190693190694190695190696190697190698190699190700190701190702190703190704190705190706190707190708190709190710190711190712190713190714190715190716190717190718190719190720190721190722190723190724190725190726190727190728190729190730190731190732190733190734190735190736190737190738190739190740190741190742190743190744190745190746190747190748190749190750190751190752190753190754190755190756190757190758190759190760190761190762190763190764190765190766190767190768190769190770190771190772190773190774190775190776190777190778190779190780190781190782190783190784190785190786190787190788190789190790190791190792190793190794190795190796190797190798190799190800190801190802190803190804190805190806190807190808190809190810190811190812190813190814190815190816190817190818190819190820190821190822190823190824190825190826190827190828190829190830190831190832190833190834190835190836190837190838190839190840190841190842190843190844190845190846190847190848190849190850190851190852190853190854190855190856190857190858190859190860190861190862190863190864190865190866190867190868190869190870190871190872190873190874190875190876190877190878190879190880190881190882190883190884190885190886190887190888190889190890190891190892190893190894190895190896190897190898190899190900190901190902190903190904190905190906190907190908190909190910190911190912190913190914190915190916190917190918190919190920190921190922190923190924190925190926190927190928190929190930190931190932190933190934190935190936190937190938190939190940190941190942190943190944190945190946190947190948190949190950190951190952190953190954190955190956190957190958190959190960190961190962190963190964190965190966190967190968190969190970190971190972190973190974190975190976190977190978190979190980190981190982190983190984190985190986190987190988190989190990190991190992190993190994190995190996190997190998190999191000191001191002191003191004191005191006191007191008191009191010191011191012191013191014191015191016191017191018191019191020191021191022191023191024191025191026191027191028191029191030191031191032191033191034191035191036191037191038191039191040191041191042191043191044191045191046191047191048191049191050191051191052191053191054191055191056191057191058191059191060191061191062191063191064191065191066191067191068191069191070191071191072191073191074191075191076191077191078191079191080191081191082191083191084191085191086191087191088191089191090191091191092191093191094191095191096191097191098191099191100191101191102191103191104191105191106191107191108191109191110191111191112191113191114191115191116191117191118191119191120191121191122191123191124191125191126191127191128191129191130191131191132191133191134191135191136191137191138191139191140191141191142191143191144191145191146191147191148191149191150191151191152191153191154191155191156191157191158191159191160191161191162191163191164191165191166191167191168191169191170191171191172191173191174191175191176191177191178191179191180191181191182191183191184191185191186191187191188191189191190191191191192191193191194191195191196191197191198191199191200191201191202191203191204191205191206191207191208191209191210191211191212191213191214191215191216191217191218191219191220191221191222191223191224191225191226191227191228191229191230191231191232191233191234191235191236191237191238191239191240191241191242191243191244191245191246191247191248191249191250191251191252191253191254191255191256191257191258191259191260191261191262191263191264191265191266191267191268191269191270191271191272191273191274191275191276191277191278191279191280191281191282191283191284191285191286191287191288191289191290191291191292191293191294191295191296191297191298191299191300191301191302191303191304191305191306191307191308191309191310191311191312191313191314191315191316191317191318191319191320191321191322191323191324191325191326191327191328191329191330191331191332191333191334191335191336191337191338191339191340191341191342191343191344191345191346191347191348191349191350191351191352191353191354191355191356191357191358191359191360191361191362191363191364191365191366191367191368191369191370191371191372191373191374191375191376191377191378191379191380191381191382191383191384191385191386191387191388191389191390191391191392191393191394191395191396191397191398191399191400191401191402191403191404191405191406191407191408191409191410191411191412191413191414191415191416191417191418191419191420191421191422191423191424191425191426191427191428191429191430191431191432191433191434191435191436191437191438191439191440191441191442191443191444191445191446191447191448191449191450191451191452191453191454191455191456191457191458191459191460191461191462191463191464191465191466191467191468191469191470191471191472191473191474191475191476191477191478191479191480191481191482191483191484191485191486191487191488191489191490191491191492191493191494191495191496191497191498191499191500191501191502191503191504191505191506191507191508191509191510191511191512191513191514191515191516191517191518191519191520191521191522191523191524191525191526191527191528191529191530191531191532191533191534191535191536191537191538191539191540191541191542191543191544191545191546191547191548191549191550191551191552191553191554191555191556191557191558191559191560191561191562191563191564191565191566191567191568191569191570191571191572191573191574191575191576191577191578191579191580191581191582191583191584191585191586191587191588191589191590191591191592191593191594191595191596191597191598191599191600191601191602191603191604191605191606191607191608191609191610191611191612191613191614191615191616191617191618191619191620191621191622191623191624191625191626191627191628191629191630191631191632191633191634191635191636191637191638191639191640191641191642191643191644191645191646191647191648191649191650191651191652191653191654191655191656191657191658191659191660191661191662191663191664191665191666191667191668191669191670191671191672191673191674191675191676191677191678191679191680191681191682191683191684191685191686191687191688191689191690191691191692191693191694191695191696191697191698191699191700191701191702191703191704191705191706191707191708191709191710191711191712191713191714191715191716191717191718191719191720191721191722191723191724191725191726191727191728191729191730191731191732191733191734191735191736191737191738191739191740191741191742191743191744191745191746191747191748191749191750191751191752191753191754191755191756191757191758191759191760191761191762191763191764191765191766191767191768191769191770191771191772191773191774191775191776191777191778191779191780191781191782191783191784191785191786191787191788191789191790191791191792191793191794191795191796191797191798191799191800191801191802191803191804191805191806191807191808191809191810191811191812191813191814191815191816191817191818191819191820191821191822191823191824191825191826191827191828191829191830191831191832191833191834191835191836191837191838191839191840191841191842191843191844191845191846191847191848191849191850191851191852191853191854191855191856191857191858191859191860191861191862191863191864191865191866191867191868191869191870191871191872191873191874191875191876191877191878191879191880191881191882191883191884191885191886191887191888191889191890191891191892191893191894191895191896191897191898191899191900191901191902191903191904191905191906191907191908191909191910191911191912191913191914191915191916191917191918191919191920191921191922191923191924191925191926191927191928191929191930191931191932191933191934191935191936191937191938191939191940191941191942191943191944191945191946191947191948191949191950191951191952191953191954191955191956191957191958191959191960191961191962191963191964191965191966191967191968191969191970191971191972191973191974191975191976191977191978191979191980191981191982191983191984191985191986191987191988191989191990191991191992191993191994191995191996191997191998191999192000192001192002192003192004192005192006192007192008192009192010192011192012192013192014192015192016192017192018192019192020192021192022192023192024192025192026192027192028192029192030192031192032192033192034192035192036192037192038192039192040192041192042192043192044192045192046192047192048192049192050192051192052192053192054192055192056192057192058192059192060192061192062192063192064192065192066192067192068192069192070192071192072192073192074192075192076192077192078192079192080192081192082192083192084192085192086192087192088192089192090192091192092192093192094192095192096192097192098192099192100192101192102192103192104192105192106192107192108192109192110192111192112192113192114192115192116192117192118192119192120192121192122192123192124192125192126192127192128192129192130192131192132192133192134192135192136192137192138192139192140192141192142192143192144192145192146192147192148192149192150192151192152192153192154192155192156192157192158192159192160192161192162192163192164192165192166192167192168192169192170192171192172192173192174192175192176192177192178192179192180192181192182192183192184192185192186192187192188192189192190192191192192192193192194192195192196192197192198192199192200192201192202192203192204192205192206192207192208192209192210192211192212192213192214192215192216192217192218192219192220192221192222192223192224192225192226192227192228192229192230192231192232192233192234192235192236192237192238192239192240192241192242192243192244192245192246192247192248192249192250192251192252192253192254192255192256192257192258192259192260192261192262192263192264192265192266192267192268192269192270192271192272192273192274192275192276192277192278192279192280192281192282192283192284192285192286192287192288192289192290192291192292192293192294192295192296192297192298192299192300192301192302192303192304192305192306192307192308192309192310192311192312192313192314192315192316192317192318192319192320192321192322192323192324192325192326192327192328192329192330192331192332192333192334192335192336192337192338192339192340192341192342192343192344192345192346192347192348192349192350192351192352192353192354192355192356192357192358192359192360192361192362192363192364192365192366192367192368192369192370192371192372192373192374192375192376192377192378192379192380192381192382192383192384192385192386192387192388192389192390192391192392192393192394192395192396192397192398192399192400192401192402192403192404192405192406192407192408192409192410192411192412192413192414192415192416192417192418192419192420192421192422192423192424192425192426192427192428192429192430192431192432192433192434192435192436192437192438192439192440192441192442192443192444192445192446192447192448192449192450192451192452192453192454192455192456192457192458192459192460192461192462192463192464192465192466192467192468192469192470192471192472192473192474192475192476192477192478192479192480192481192482192483192484192485192486192487192488192489192490192491192492192493192494192495192496192497192498192499192500192501192502192503192504192505192506192507192508192509192510192511192512192513192514192515192516192517192518192519192520192521192522192523192524192525192526192527192528192529192530192531192532192533192534192535192536192537192538192539192540192541192542192543192544192545192546192547192548192549192550192551192552192553192554192555192556192557192558192559192560192561192562192563192564192565192566192567192568192569192570192571192572192573192574192575192576192577192578192579192580192581192582192583192584192585192586192587192588192589192590192591192592192593192594192595192596192597192598192599192600192601192602192603192604192605192606192607192608192609192610192611192612192613192614192615192616192617192618192619192620192621192622192623192624192625192626192627192628192629192630192631192632192633192634192635192636192637192638192639192640192641192642192643192644192645192646192647192648192649192650192651192652192653192654192655192656192657192658192659192660192661192662192663192664192665192666192667192668192669192670192671192672192673192674192675192676192677192678192679192680192681192682192683192684192685192686192687192688192689192690192691192692192693192694192695192696192697192698192699192700192701192702192703192704192705192706192707192708192709192710192711192712192713192714192715192716192717192718192719192720192721192722192723192724192725192726192727192728192729192730192731192732192733192734192735192736192737192738192739192740192741192742192743192744192745192746192747192748192749192750192751192752192753192754192755192756192757192758192759192760192761192762192763192764192765192766192767192768192769192770192771192772192773192774192775192776192777192778192779192780192781192782192783192784192785192786192787192788192789192790192791192792192793192794192795192796192797192798192799192800192801192802192803192804192805192806192807192808192809192810192811192812192813192814192815192816192817192818192819192820192821192822192823192824192825192826192827192828192829192830192831192832192833192834192835192836192837192838192839192840192841192842192843192844192845192846192847192848192849192850192851192852192853192854192855192856192857192858192859192860192861192862192863192864192865192866192867192868192869192870192871192872192873192874192875192876192877192878192879192880192881192882192883192884192885192886192887192888192889192890192891192892192893192894192895192896192897192898192899192900192901192902192903192904192905192906192907192908192909192910192911192912192913192914192915192916192917192918192919192920192921192922192923192924192925192926192927192928192929192930192931192932192933192934192935192936192937192938192939192940192941192942192943192944192945192946192947192948192949192950192951192952192953192954192955192956192957192958192959192960192961192962192963192964192965192966192967192968192969192970192971192972192973192974192975192976192977192978192979192980192981192982192983192984192985192986192987192988192989192990192991192992192993192994192995192996192997192998192999193000193001193002193003193004193005193006193007193008193009193010193011193012193013193014193015193016193017193018193019193020193021193022193023193024193025193026193027193028193029193030193031193032193033193034193035193036193037193038193039193040193041193042193043193044193045193046193047193048193049193050193051193052193053193054193055193056193057193058193059193060193061193062193063193064193065193066193067193068193069193070193071193072193073193074193075193076193077193078193079193080193081193082193083193084193085193086193087193088193089193090193091193092193093193094193095193096193097193098193099193100193101193102193103193104193105193106193107193108193109193110193111193112193113193114193115193116193117193118193119193120193121193122193123193124193125193126193127193128193129193130193131193132193133193134193135193136193137193138193139193140193141193142193143193144193145193146193147193148193149193150193151193152193153193154193155193156193157193158193159193160193161193162193163193164193165193166193167193168193169193170193171193172193173193174193175193176193177193178193179193180193181193182193183193184193185193186193187193188193189193190193191193192193193193194193195193196193197193198193199193200193201193202193203193204193205193206193207193208193209193210193211193212193213193214193215193216193217193218193219193220193221193222193223193224193225193226193227193228193229193230193231193232193233193234193235193236193237193238193239193240193241193242193243193244193245193246193247193248193249193250193251193252193253193254193255193256193257193258193259193260193261193262193263193264193265193266193267193268193269193270193271193272193273193274193275193276193277193278193279193280193281193282193283193284193285193286193287193288193289193290193291193292193293193294193295193296193297193298193299193300193301193302193303193304193305193306193307193308193309193310193311193312193313193314193315193316193317193318193319193320193321193322193323193324193325193326193327193328193329193330193331193332193333193334193335193336193337193338193339193340193341193342193343193344193345193346193347193348193349193350193351193352193353193354193355193356193357193358193359193360193361193362193363193364193365193366193367193368193369193370193371193372193373193374193375193376193377193378193379193380193381193382193383193384193385193386193387193388193389193390193391193392193393193394193395193396193397193398193399193400193401193402193403193404193405193406193407193408193409193410193411193412193413193414193415193416193417193418193419193420193421193422193423193424193425193426193427193428193429193430193431193432193433193434193435193436193437193438193439193440193441193442193443193444193445193446193447193448193449193450193451193452193453193454193455193456193457193458193459193460193461193462193463193464193465193466193467193468193469193470193471193472193473193474193475193476193477193478193479193480193481193482193483193484193485193486193487193488193489193490193491193492193493193494193495193496193497193498193499193500193501193502193503193504193505193506193507193508193509193510193511193512193513193514193515193516193517193518193519193520193521193522193523193524193525193526193527193528193529193530193531193532193533193534193535193536193537193538193539193540193541193542193543193544193545193546193547193548193549193550193551193552193553193554193555193556193557193558193559193560193561193562193563193564193565193566193567193568193569193570193571193572193573193574193575193576193577193578193579193580193581193582193583193584193585193586193587193588193589193590193591193592193593193594193595193596193597193598193599193600193601193602193603193604193605193606193607193608193609193610193611193612193613193614193615193616193617193618193619193620193621193622193623193624193625193626193627193628193629193630193631193632193633193634193635193636193637193638193639193640193641193642193643193644193645193646193647193648193649193650193651193652193653193654193655193656193657193658193659193660193661193662193663193664193665193666193667193668193669193670193671193672193673193674193675193676193677193678193679193680193681193682193683193684193685193686193687193688193689193690193691193692193693193694193695193696193697193698193699193700193701193702193703193704193705193706193707193708193709193710193711193712193713193714193715193716193717193718193719193720193721193722193723193724193725193726193727193728193729193730193731193732193733193734193735193736193737193738193739193740193741193742193743193744193745193746193747193748193749193750193751193752193753193754193755193756193757193758193759193760193761193762193763193764193765193766193767193768193769193770193771193772193773193774193775193776193777193778193779193780193781193782193783193784193785193786193787193788193789193790193791193792193793193794193795193796193797193798193799193800193801193802193803193804193805193806193807193808193809193810193811193812193813193814193815193816193817193818193819193820193821193822193823193824193825193826193827193828193829193830193831193832193833193834193835193836193837193838193839193840193841193842193843193844193845193846193847193848193849193850193851193852193853193854193855193856193857193858193859193860193861193862193863193864193865193866193867193868193869193870193871193872193873193874193875193876193877193878193879193880193881193882193883193884193885193886193887193888193889193890193891193892193893193894193895193896193897193898193899193900193901193902193903193904193905193906193907193908193909193910193911193912193913193914193915193916193917193918193919193920193921193922193923193924193925193926193927193928193929193930193931193932193933193934193935193936193937193938193939193940193941193942193943193944193945193946193947193948193949193950193951193952193953193954193955193956193957193958193959193960193961193962193963193964193965193966193967193968193969193970193971193972193973193974193975193976193977193978193979193980193981193982193983193984193985193986193987193988193989193990193991193992193993193994193995193996193997193998193999194000194001194002194003194004194005194006194007194008194009194010194011194012194013194014194015194016194017194018194019194020194021194022194023194024194025194026194027194028194029194030194031194032194033194034194035194036194037194038194039194040194041194042194043194044194045194046194047194048194049194050194051194052194053194054194055194056194057194058194059194060194061194062194063194064194065194066194067194068194069194070194071194072194073194074194075194076194077194078194079194080194081194082194083194084194085194086194087194088194089194090194091194092194093194094194095194096194097194098194099194100194101194102194103194104194105194106194107194108194109194110194111194112194113194114194115194116194117194118194119194120194121194122194123194124194125194126194127194128194129194130194131194132194133194134194135194136194137194138194139194140194141194142194143194144194145194146194147194148194149194150194151194152194153194154194155194156194157194158194159194160194161194162194163194164194165194166194167194168194169194170194171194172194173194174194175194176194177194178194179194180194181194182194183194184194185194186194187194188194189194190194191194192194193194194194195194196194197194198194199194200194201194202194203194204194205194206194207194208194209194210194211194212194213194214194215194216194217194218194219194220194221194222194223194224194225194226194227194228194229194230194231194232194233194234194235194236194237194238194239194240194241194242194243194244194245194246194247194248194249194250194251194252194253194254194255194256194257194258194259194260194261194262194263194264194265194266194267194268194269194270194271194272194273194274194275194276194277194278194279194280194281194282194283194284194285194286194287194288194289194290194291194292194293194294194295194296194297194298194299194300194301194302194303194304194305194306194307194308194309194310194311194312194313194314194315194316194317194318194319194320194321194322194323194324194325194326194327194328194329194330194331194332194333194334194335194336194337194338194339194340194341194342194343194344194345194346194347194348194349194350194351194352194353194354194355194356194357194358194359194360194361194362194363194364194365194366194367194368194369194370194371194372194373194374194375194376194377194378194379194380194381194382194383194384194385194386194387194388194389194390194391194392194393194394194395194396194397194398194399194400194401194402194403194404194405194406194407194408194409194410194411194412194413194414194415194416194417194418194419194420194421194422194423194424194425194426194427194428194429194430194431194432194433194434194435194436194437194438194439194440194441194442194443194444194445194446194447194448194449194450194451194452194453194454194455194456194457194458194459194460194461194462194463194464194465194466194467194468194469194470194471194472194473194474194475194476194477194478194479194480194481194482194483194484194485194486194487194488194489194490194491194492194493194494194495194496194497194498194499194500194501194502194503194504194505194506194507194508194509194510194511194512194513194514194515194516194517194518194519194520194521194522194523194524194525194526194527194528194529194530194531194532194533194534194535194536194537194538194539194540194541194542194543194544194545194546194547194548194549194550194551194552194553194554194555194556194557194558194559194560194561194562194563194564194565194566194567194568194569194570194571194572194573194574194575194576194577194578194579194580194581194582194583194584194585194586194587194588194589194590194591194592194593194594194595194596194597194598194599194600194601194602194603194604194605194606194607194608194609194610194611194612194613194614194615194616194617194618194619194620194621194622194623194624194625194626194627194628194629194630194631194632194633194634194635194636194637194638194639194640194641194642194643194644194645194646194647194648194649194650194651194652194653194654194655194656194657194658194659194660194661194662194663194664194665194666194667194668194669194670194671194672194673194674194675194676194677194678194679194680194681194682194683194684194685194686194687194688194689194690194691194692194693194694194695194696194697194698194699194700194701194702194703194704194705194706194707194708194709194710194711194712194713194714194715194716194717194718194719194720194721194722194723194724194725194726194727194728194729194730194731194732194733194734194735194736194737194738194739194740194741194742194743194744194745194746194747194748194749194750194751194752194753194754194755194756194757194758194759194760194761194762194763194764194765194766194767194768194769194770194771194772194773194774194775194776194777194778194779194780194781194782194783194784194785194786194787194788194789194790194791194792194793194794194795194796194797194798194799194800194801194802194803194804194805194806194807194808194809194810194811194812194813194814194815194816194817194818194819194820194821194822194823194824194825194826194827194828194829194830194831194832194833194834194835194836194837194838194839194840194841194842194843194844194845194846194847194848194849194850194851194852194853194854194855194856194857194858194859194860194861194862194863194864194865194866194867194868194869194870194871194872194873194874194875194876194877194878194879194880194881194882194883194884194885194886194887194888194889194890194891194892194893194894194895194896194897194898194899194900194901194902194903194904194905194906194907194908194909194910194911194912194913194914194915194916194917194918194919194920194921194922194923194924194925194926194927194928194929194930194931194932194933194934194935194936194937194938194939194940194941194942194943194944194945194946194947194948194949194950194951194952194953194954194955194956194957194958194959194960194961194962194963194964194965194966194967194968194969194970194971194972194973194974194975194976194977194978194979194980194981194982194983194984194985194986194987194988194989194990194991194992194993194994194995194996194997194998194999195000195001195002195003195004195005195006195007195008195009195010195011195012195013195014195015195016195017195018195019195020195021195022195023195024195025195026195027195028195029195030195031195032195033195034195035195036195037195038195039195040195041195042195043195044195045195046195047195048195049195050195051195052195053195054195055195056195057195058195059195060195061195062195063195064195065195066195067195068195069195070195071195072195073195074195075195076195077195078195079195080195081195082195083195084195085195086195087195088195089195090195091195092195093195094195095195096195097195098195099195100195101195102195103195104195105195106195107195108195109195110195111195112195113195114195115195116195117195118195119195120195121195122195123195124195125195126195127195128195129195130195131195132195133195134195135195136195137195138195139195140195141195142195143195144195145195146195147195148195149195150195151195152195153195154195155195156195157195158195159195160195161195162195163195164195165195166195167195168195169195170195171195172195173195174195175195176195177195178195179195180195181195182195183195184195185195186195187195188195189195190195191195192195193195194195195195196195197195198195199195200195201195202195203195204195205195206195207195208195209195210195211195212195213195214195215195216195217195218195219195220195221195222195223195224195225195226195227195228195229195230195231195232195233195234195235195236195237195238195239195240195241195242195243195244195245195246195247195248195249195250195251195252195253195254195255195256195257195258195259195260195261195262195263195264195265195266195267195268195269195270195271195272195273195274195275195276195277195278195279195280195281195282195283195284195285195286195287195288195289195290195291195292195293195294195295195296195297195298195299195300195301195302195303195304195305195306195307195308195309195310195311195312195313195314195315195316195317195318195319195320195321195322195323195324195325195326195327195328195329195330195331195332195333195334195335195336195337195338195339195340195341195342195343195344195345195346195347195348195349195350195351195352195353195354195355195356195357195358195359195360195361195362195363195364195365195366195367195368195369195370195371195372195373195374195375195376195377195378195379195380195381195382195383195384195385195386195387195388195389195390195391195392195393195394195395195396195397195398195399195400195401195402195403195404195405195406195407195408195409195410195411195412195413195414195415195416195417195418195419195420195421195422195423195424195425195426195427195428195429195430195431195432195433195434195435195436195437195438195439195440195441195442195443195444195445195446195447195448195449195450195451195452195453195454195455195456195457195458195459195460195461195462195463195464195465195466195467195468195469195470195471195472195473195474195475195476195477195478195479195480195481195482195483195484195485195486195487195488195489195490195491195492195493195494195495195496195497195498195499195500195501195502195503195504195505195506195507195508195509195510195511195512195513195514195515195516195517195518195519195520195521195522195523195524195525195526195527195528195529195530195531195532195533195534195535195536195537195538195539195540195541195542195543195544195545195546195547195548195549195550195551195552195553195554195555195556195557195558195559195560195561195562195563195564195565195566195567195568195569195570195571195572195573195574195575195576195577195578195579195580195581195582195583195584195585195586195587195588195589195590195591195592195593195594195595195596195597195598195599195600195601195602195603195604195605195606195607195608195609195610195611195612195613195614195615195616195617195618195619195620195621195622195623195624195625195626195627195628195629195630195631195632195633195634195635195636195637195638195639195640195641195642195643195644195645195646195647195648195649195650195651195652195653195654195655195656195657195658195659195660195661195662195663195664195665195666195667195668195669195670195671195672195673195674195675195676195677195678195679195680195681195682195683195684195685195686195687195688195689195690195691195692195693195694195695195696195697195698195699195700195701195702195703195704195705195706195707195708195709195710195711195712195713195714195715195716195717195718195719195720195721195722195723195724195725195726195727195728195729195730195731195732195733195734195735195736195737195738195739195740195741195742195743195744195745195746195747195748195749195750195751195752195753195754195755195756195757195758195759195760195761195762195763195764195765195766195767195768195769195770195771195772195773195774195775195776195777195778195779195780195781195782195783195784195785195786195787195788195789195790195791195792195793195794195795195796195797195798195799195800195801195802195803195804195805195806195807195808195809195810195811195812195813195814195815195816195817195818195819195820195821195822195823195824195825195826195827195828195829195830195831195832195833195834195835195836195837195838195839195840195841195842195843195844195845195846195847195848195849195850195851195852195853195854195855195856195857195858195859195860195861195862195863195864195865195866195867195868195869195870195871195872195873195874195875195876195877195878195879195880195881195882195883195884195885195886195887195888195889195890195891195892195893195894195895195896195897195898195899195900195901195902195903195904195905195906195907195908195909195910195911195912195913195914195915195916195917195918195919195920195921195922195923195924195925195926195927195928195929195930195931195932195933195934195935195936195937195938195939195940195941195942195943195944195945195946195947195948195949195950195951195952195953195954195955195956195957195958195959195960195961195962195963195964195965195966195967195968195969195970195971195972195973195974195975195976195977195978195979195980195981195982195983195984195985195986195987195988195989195990195991195992195993195994195995195996195997195998195999196000196001196002196003196004196005196006196007196008196009196010196011196012196013196014196015196016196017196018196019196020196021196022196023196024196025196026196027196028196029196030196031196032196033196034196035196036196037196038196039196040196041196042196043196044196045196046196047196048196049196050196051196052196053196054196055196056196057196058196059196060196061196062196063196064196065196066196067196068196069196070196071196072196073196074196075196076196077196078196079196080196081196082196083196084196085196086196087196088196089196090196091196092196093196094196095196096196097196098196099196100196101196102196103196104196105196106196107196108196109196110196111196112196113196114196115196116196117196118196119196120196121196122196123196124196125196126196127196128196129196130196131196132196133196134196135196136196137196138196139196140196141196142196143196144196145196146196147196148196149196150196151196152196153196154196155196156196157196158196159196160196161196162196163196164196165196166196167196168196169196170196171196172196173196174196175196176196177196178196179196180196181196182196183196184196185196186196187196188196189196190196191196192196193196194196195196196196197196198196199196200196201196202196203196204196205196206196207196208196209196210196211196212196213196214196215196216196217196218196219196220196221196222196223196224196225196226196227196228196229196230196231196232196233196234196235196236196237196238196239196240196241196242196243196244196245196246196247196248196249196250196251196252196253196254196255196256196257196258196259196260196261196262196263196264196265196266196267196268196269196270196271196272196273196274196275196276196277196278196279196280196281196282196283196284196285196286196287196288196289196290196291196292196293196294196295196296196297196298196299196300196301196302196303196304196305196306196307196308196309196310196311196312196313196314196315196316196317196318196319196320196321196322196323196324196325196326196327196328196329196330196331196332196333196334196335196336196337196338196339196340196341196342196343196344196345196346196347196348196349196350196351196352196353196354196355196356196357196358196359196360196361196362196363196364196365196366196367196368196369196370196371196372196373196374196375196376196377196378196379196380196381196382196383196384196385196386196387196388196389196390196391196392196393196394196395196396196397196398196399196400196401196402196403196404196405196406196407196408196409196410196411196412196413196414196415196416196417196418196419196420196421196422196423196424196425196426196427196428196429196430196431196432196433196434196435196436196437196438196439196440196441196442196443196444196445196446196447196448196449196450196451196452196453196454196455196456196457196458196459196460196461196462196463196464196465196466196467196468196469196470196471196472196473196474196475196476196477196478196479196480196481196482196483196484196485196486196487196488196489196490196491196492196493196494196495196496196497196498196499196500196501196502196503196504196505196506196507196508196509196510196511196512196513196514196515196516196517196518196519196520196521196522196523196524196525196526196527196528196529196530196531196532196533196534196535196536196537196538196539196540196541196542196543196544196545196546196547196548196549196550196551196552196553196554196555196556196557196558196559196560196561196562196563196564196565196566196567196568196569196570196571196572196573196574196575196576196577196578196579196580196581196582196583196584196585196586196587196588196589196590196591196592196593196594196595196596196597196598196599196600196601196602196603196604196605196606196607196608196609196610196611196612196613196614196615196616196617196618196619196620196621196622196623196624196625196626196627196628196629196630196631196632196633196634196635196636196637196638196639196640196641196642196643196644196645196646196647196648196649196650196651196652196653196654196655196656196657196658196659196660196661196662196663196664196665196666196667196668196669196670196671196672196673196674196675196676196677196678196679196680196681196682196683196684196685196686196687196688196689196690196691196692196693196694196695196696196697196698196699196700196701196702196703196704196705196706196707196708196709196710196711196712196713196714196715196716196717196718196719196720196721196722196723196724196725196726196727196728196729196730196731196732196733196734196735196736196737196738196739196740196741196742196743196744196745196746196747196748196749196750196751196752196753196754196755196756196757196758196759196760196761196762196763196764196765196766196767196768196769196770196771196772196773196774196775196776196777196778196779196780196781196782196783196784196785196786196787196788196789196790196791196792196793196794196795196796196797196798196799196800196801196802196803196804196805196806196807196808196809196810196811196812196813196814196815196816196817196818196819196820196821196822196823196824196825196826196827196828196829196830196831196832196833196834196835196836196837196838196839196840196841196842196843196844196845196846196847196848196849196850196851196852196853196854196855196856196857196858196859196860196861196862196863196864196865196866196867196868196869196870196871196872196873196874196875196876196877196878196879196880196881196882196883196884196885196886196887196888196889196890196891196892196893196894196895196896196897196898196899196900196901196902196903196904196905196906196907196908196909196910196911196912196913196914196915196916196917196918196919196920196921196922196923196924196925196926196927196928196929196930196931196932196933196934196935196936196937196938196939196940196941196942196943196944196945196946196947196948196949196950196951196952196953196954196955196956196957196958196959196960196961196962196963196964196965196966196967196968196969196970196971196972196973196974196975196976196977196978196979196980196981196982196983196984196985196986196987196988196989196990196991196992196993196994196995196996196997196998196999197000197001197002197003197004197005197006197007197008197009197010197011197012197013197014197015197016197017197018197019197020197021197022197023197024197025197026197027197028197029197030197031197032197033197034197035197036197037197038197039197040197041197042197043197044197045197046197047197048197049197050197051197052197053197054197055197056197057197058197059197060197061197062197063197064197065197066197067197068197069197070197071197072197073197074197075197076197077197078197079197080197081197082197083197084197085197086197087197088197089197090197091197092197093197094197095197096197097197098197099197100197101197102197103197104197105197106197107197108197109197110197111197112197113197114197115197116197117197118197119197120197121197122197123197124197125197126197127197128197129197130197131197132197133197134197135197136197137197138197139197140197141197142197143197144197145197146197147197148197149197150197151197152197153197154197155197156197157197158197159197160197161197162197163197164197165197166197167197168197169197170197171197172197173197174197175197176197177197178197179197180197181197182197183197184197185197186197187197188197189197190197191197192197193197194197195197196197197197198197199197200197201197202197203197204197205197206197207197208197209197210197211197212197213197214197215197216197217197218197219197220197221197222197223197224197225197226197227197228197229197230197231197232197233197234197235197236197237197238197239197240197241197242197243197244197245197246197247197248197249197250197251197252197253197254197255197256197257197258197259197260197261197262197263197264197265197266197267197268197269197270197271197272197273197274197275197276197277197278197279197280197281197282197283197284197285197286197287197288197289197290197291197292197293197294197295197296197297197298197299197300197301197302197303197304197305197306197307197308197309197310197311197312197313197314197315197316197317197318197319197320197321197322197323197324197325197326197327197328197329197330197331197332197333197334197335197336197337197338197339197340197341197342197343197344197345197346197347197348197349197350197351197352197353197354197355197356197357197358197359197360197361197362197363197364197365197366197367197368197369197370197371197372197373197374197375197376197377197378197379197380197381197382197383197384197385197386197387197388197389197390197391197392197393197394197395197396197397197398197399197400197401197402197403197404197405197406197407197408197409197410197411197412197413197414197415197416197417197418197419197420197421197422197423197424197425197426197427197428197429197430197431197432197433197434197435197436197437197438197439197440197441197442197443197444197445197446197447197448197449197450197451197452197453197454197455197456197457197458197459197460197461197462197463197464197465197466197467197468197469197470197471197472197473197474197475197476197477197478197479197480197481197482197483197484197485197486197487197488197489197490197491197492197493197494197495197496197497197498197499197500197501197502197503197504197505197506197507197508197509197510197511197512197513197514197515197516197517197518197519197520197521197522197523197524197525197526197527197528197529197530197531197532197533197534197535197536197537197538197539197540197541197542197543197544197545197546197547197548197549197550197551197552197553197554197555197556197557197558197559197560197561197562197563197564197565197566197567197568197569197570197571197572197573197574197575197576197577197578197579197580197581197582197583197584197585197586197587197588197589197590197591197592197593197594197595197596197597197598197599197600197601197602197603197604197605197606197607197608197609197610197611197612197613197614197615197616197617197618197619197620197621197622197623197624197625197626197627197628197629197630197631197632197633197634197635197636197637197638197639197640197641197642197643197644197645197646197647197648197649197650197651197652197653197654197655197656197657197658197659197660197661197662197663197664197665197666197667197668197669197670197671197672197673197674197675197676197677197678197679197680197681197682197683197684197685197686197687197688197689197690197691197692197693197694197695197696197697197698197699197700197701197702197703197704197705197706197707197708197709197710197711197712197713197714197715197716197717197718197719197720197721197722197723197724197725197726197727197728197729197730197731197732197733197734197735197736197737197738197739197740197741197742197743197744197745197746197747197748197749197750197751197752197753197754197755197756197757197758197759197760197761197762197763197764197765197766197767197768197769197770197771197772197773197774197775197776197777197778197779197780197781197782197783197784197785197786197787197788197789197790197791197792197793197794197795197796197797197798197799197800197801197802197803197804197805197806197807197808197809197810197811197812197813197814197815197816197817197818197819197820197821197822197823197824197825197826197827197828197829197830197831197832197833197834197835197836197837197838197839197840197841197842197843197844197845197846197847197848197849197850197851197852197853197854197855197856197857197858197859197860197861197862197863197864197865197866197867197868197869197870197871197872197873197874197875197876197877197878197879197880197881197882197883197884197885197886197887197888197889197890197891197892197893197894197895197896197897197898197899197900197901197902197903197904197905197906197907197908197909197910197911197912197913197914197915197916197917197918197919197920197921197922197923197924197925197926197927197928197929197930197931197932197933197934197935197936197937197938197939197940197941197942197943197944197945197946197947197948197949197950197951197952197953197954197955197956197957197958197959197960197961197962197963197964197965197966197967197968197969197970197971197972197973197974197975197976197977197978197979197980197981197982197983197984197985197986197987197988197989197990197991197992197993197994197995197996197997197998197999198000198001198002198003198004198005198006198007198008198009198010198011198012198013198014198015198016198017198018198019198020198021198022198023198024198025198026198027198028198029198030198031198032198033198034198035198036198037198038198039198040198041198042198043198044198045198046198047198048198049198050198051198052198053198054198055198056198057198058198059198060198061198062198063198064198065198066198067198068198069198070198071198072198073198074198075198076198077198078198079198080198081198082198083198084198085198086198087198088198089198090198091198092198093198094198095198096198097198098198099198100198101198102198103198104198105198106198107198108198109198110198111198112198113198114198115198116198117198118198119198120198121198122198123198124198125198126198127198128198129198130198131198132198133198134198135198136198137198138198139198140198141198142198143198144198145198146198147198148198149198150198151198152198153198154198155198156198157198158198159198160198161198162198163198164198165198166198167198168198169198170198171198172198173198174198175198176198177198178198179198180198181198182198183198184198185198186198187198188198189198190198191198192198193198194198195198196198197198198198199198200198201198202198203198204198205198206198207198208198209198210198211198212198213198214198215198216198217198218198219198220198221198222198223198224198225198226198227198228198229198230198231198232198233198234198235198236198237198238198239198240198241198242198243198244198245198246198247198248198249198250198251198252198253198254198255198256198257198258198259198260198261198262198263198264198265198266198267198268198269198270198271198272198273198274198275198276198277198278198279198280198281198282198283198284198285198286198287198288198289198290198291198292198293198294198295198296198297198298198299198300198301198302198303198304198305198306198307198308198309198310198311198312198313198314198315198316198317198318198319198320198321198322198323198324198325198326198327198328198329198330198331198332198333198334198335198336198337198338198339198340198341198342198343198344198345198346198347198348198349198350198351198352198353198354198355198356198357198358198359198360198361198362198363198364198365198366198367198368198369198370198371198372198373198374198375198376198377198378198379198380198381198382198383198384198385198386198387198388198389198390198391198392198393198394198395198396198397198398198399198400198401198402198403198404198405198406198407198408198409198410198411198412198413198414198415198416198417198418198419198420198421198422198423198424198425198426198427198428198429198430198431198432198433198434198435198436198437198438198439198440198441198442198443198444198445198446198447198448198449198450198451198452198453198454198455198456198457198458198459198460198461198462198463198464198465198466198467198468198469198470198471198472198473198474198475198476198477198478198479198480198481198482198483198484198485198486198487198488198489198490198491198492198493198494198495198496198497198498198499198500198501198502198503198504198505198506198507198508198509198510198511198512198513198514198515198516198517198518198519198520198521198522198523198524198525198526198527198528198529198530198531198532198533198534198535198536198537198538198539198540198541198542198543198544198545198546198547198548198549198550198551198552198553198554198555198556198557198558198559198560198561198562198563198564198565198566198567198568198569198570198571198572198573198574198575198576198577198578198579198580198581198582198583198584198585198586198587198588198589198590198591198592198593198594198595198596198597198598198599198600198601198602198603198604198605198606198607198608198609198610198611198612198613198614198615198616198617198618198619198620198621198622198623198624198625198626198627198628198629198630198631198632198633198634198635198636198637198638198639198640198641198642198643198644198645198646198647198648198649198650198651198652198653198654198655198656198657198658198659198660198661198662198663198664198665198666198667198668198669198670198671198672198673198674198675198676198677198678198679198680198681198682198683198684198685198686198687198688198689198690198691198692198693198694198695198696198697198698198699198700198701198702198703198704198705198706198707198708198709198710198711198712198713198714198715198716198717198718198719198720198721198722198723198724198725198726198727198728198729198730198731198732198733198734198735198736198737198738198739198740198741198742198743198744198745198746198747198748198749198750198751198752198753198754198755198756198757198758198759198760198761198762198763198764198765198766198767198768198769198770198771198772198773198774198775198776198777198778198779198780198781198782198783198784198785198786198787198788198789198790198791198792198793198794198795198796198797198798198799198800198801198802198803198804198805198806198807198808198809198810198811198812198813198814198815198816198817198818198819198820198821198822198823198824198825198826198827198828198829198830198831198832198833198834198835198836198837198838198839198840198841198842198843198844198845198846198847198848198849198850198851198852198853198854198855198856198857198858198859198860198861198862198863198864198865198866198867198868198869198870198871198872198873198874198875198876198877198878198879198880198881198882198883198884198885198886198887198888198889198890198891198892198893198894198895198896198897198898198899198900198901198902198903198904198905198906198907198908198909198910198911198912198913198914198915198916198917198918198919198920198921198922198923198924198925198926198927198928198929198930198931198932198933198934198935198936198937198938198939198940198941198942198943198944198945198946198947198948198949198950198951198952198953198954198955198956198957198958198959198960198961198962198963198964198965198966198967198968198969198970198971198972198973198974198975198976198977198978198979198980198981198982198983198984198985198986198987198988198989198990198991198992198993198994198995198996198997198998198999199000199001199002199003199004199005199006199007199008199009199010199011199012199013199014199015199016199017199018199019199020199021199022199023199024199025199026199027199028199029199030199031199032199033199034199035199036199037199038199039199040199041199042199043199044199045199046199047199048199049199050199051199052199053199054199055199056199057199058199059199060199061199062199063199064199065199066199067199068199069199070199071199072199073199074199075199076199077199078199079199080199081199082199083199084199085199086199087199088199089199090199091199092199093199094199095199096199097199098199099199100199101199102199103199104199105199106199107199108199109199110199111199112199113199114199115199116199117199118199119199120199121199122199123199124199125199126199127199128199129199130199131199132199133199134199135199136199137199138199139199140199141199142199143199144199145199146199147199148199149199150199151199152199153199154199155199156199157199158199159199160199161199162199163199164199165199166199167199168199169199170199171199172199173199174199175199176199177199178199179199180199181199182199183199184199185199186199187199188199189199190199191199192199193199194199195199196199197199198199199199200199201199202199203199204199205199206199207199208199209199210199211199212199213199214199215199216199217199218199219199220199221199222199223199224199225199226199227199228199229199230199231199232199233199234199235199236199237199238199239199240199241199242199243199244199245199246199247199248199249199250199251199252199253199254199255199256199257199258199259199260199261199262199263199264199265199266199267199268199269199270199271199272199273199274199275199276199277199278199279199280199281199282199283199284199285199286199287199288199289199290199291199292199293199294199295199296199297199298199299199300199301199302199303199304199305199306199307199308199309199310199311199312199313199314199315199316199317199318199319199320199321199322199323199324199325199326199327199328199329199330199331199332199333199334199335199336199337199338199339199340199341199342199343199344199345199346199347199348199349199350199351199352199353199354199355199356199357199358199359199360199361199362199363199364199365199366199367199368199369199370199371199372199373199374199375199376199377199378199379199380199381199382199383199384199385199386199387199388199389199390199391199392199393199394199395199396199397199398199399199400199401199402199403199404199405199406199407199408199409199410199411199412199413199414199415199416199417199418199419199420199421199422199423199424199425199426199427199428199429199430199431199432199433199434199435199436199437199438199439199440199441199442199443199444199445199446199447199448199449199450199451199452199453199454199455199456199457199458199459199460199461199462199463199464199465199466199467199468199469199470199471199472199473199474199475199476199477199478199479199480199481199482199483199484199485199486199487199488199489199490199491199492199493199494199495199496199497199498199499199500199501199502199503199504199505199506199507199508199509199510199511199512199513199514199515199516199517199518199519199520199521199522199523199524199525199526199527199528199529199530199531199532199533199534199535199536199537199538199539199540199541199542199543199544199545199546199547199548199549199550199551199552199553199554199555199556199557199558199559199560199561199562199563199564199565199566199567199568199569199570199571199572199573199574199575199576199577199578199579199580199581199582199583199584199585199586199587199588199589199590199591199592199593199594199595199596199597199598199599199600199601199602199603199604199605199606199607199608199609199610199611199612199613199614199615199616199617199618199619199620199621199622199623199624199625199626199627199628199629199630199631199632199633199634199635199636199637199638199639199640199641199642199643199644199645199646199647199648199649199650199651199652199653199654199655199656199657199658199659199660199661199662199663199664199665199666199667199668199669199670199671199672199673199674199675199676199677199678199679199680199681199682199683199684199685199686199687199688199689199690199691199692199693199694199695199696199697199698199699199700199701199702199703199704199705199706199707199708199709199710199711199712199713199714199715199716199717199718199719199720199721199722199723199724199725199726199727199728199729199730199731199732199733199734199735199736199737199738199739199740199741199742199743199744199745199746199747199748199749199750199751199752199753199754199755199756199757199758199759199760199761199762199763199764199765199766199767199768199769199770199771199772199773199774199775199776199777199778199779199780199781199782199783199784199785199786199787199788199789199790199791199792199793199794199795199796199797199798199799199800199801199802199803199804199805199806199807199808199809199810199811199812199813199814199815199816199817199818199819199820199821199822199823199824199825199826199827199828199829199830199831199832199833199834199835199836199837199838199839199840199841199842199843199844199845199846199847199848199849199850199851199852199853199854199855199856199857199858199859199860199861199862199863199864199865199866199867199868199869199870199871199872199873199874199875199876199877199878199879199880199881199882199883199884199885199886199887199888199889199890199891199892199893199894199895199896199897199898199899199900199901199902199903199904199905199906199907199908199909199910199911199912199913199914199915199916199917199918199919199920199921199922199923199924199925199926199927199928199929199930199931199932199933199934199935199936199937199938199939199940199941199942199943199944199945199946199947199948199949199950199951199952199953199954199955199956199957199958199959199960199961199962199963199964199965199966199967199968199969199970199971199972199973199974199975199976199977199978199979199980199981199982199983199984199985199986199987199988199989199990199991199992199993199994199995199996199997199998199999200000200001200002200003200004200005200006200007200008200009200010200011200012200013200014200015200016200017200018200019200020200021200022200023200024200025200026200027200028200029200030200031200032200033200034200035200036200037200038200039200040200041200042200043200044200045200046200047200048200049200050200051200052200053200054200055200056200057200058200059200060200061200062200063200064200065200066200067200068200069200070200071200072200073200074200075200076200077200078200079200080200081200082200083200084200085200086200087200088200089200090200091200092200093200094200095200096200097200098200099200100200101200102200103200104200105200106200107200108200109200110200111200112200113200114200115200116200117200118200119200120200121200122200123200124200125200126200127200128200129200130200131200132200133200134200135200136200137200138200139200140200141200142200143200144200145200146200147200148200149200150200151200152200153200154200155200156200157200158200159200160200161200162200163200164200165200166200167200168200169200170200171200172200173200174200175200176200177200178200179200180200181200182200183200184200185200186200187200188200189200190200191200192200193200194200195200196200197200198200199200200200201200202200203200204200205200206200207200208200209200210200211200212200213200214200215200216200217200218200219200220200221200222200223200224200225200226200227200228200229200230200231200232200233200234200235200236200237200238200239200240200241200242200243200244200245200246200247200248200249200250200251200252200253200254200255200256200257200258200259200260200261200262200263200264200265200266200267200268200269200270200271200272200273200274200275200276200277200278200279200280200281200282200283200284200285200286200287200288200289200290200291200292200293200294200295200296200297200298200299200300200301200302200303200304200305200306200307200308200309200310200311200312200313200314200315200316200317200318200319200320200321200322200323200324200325200326200327200328200329200330200331200332200333200334200335200336200337200338200339200340200341200342200343200344200345200346200347200348200349200350200351200352200353200354200355200356200357200358200359200360200361200362200363200364200365200366200367200368200369200370200371200372200373200374200375200376200377200378200379200380200381200382200383200384200385200386200387200388200389200390200391200392200393200394200395200396200397200398200399200400200401200402200403200404200405200406200407200408200409200410200411200412200413200414200415200416200417200418200419200420200421200422200423200424200425200426200427200428200429200430200431200432200433200434200435200436200437200438200439200440200441200442200443200444200445200446200447200448200449200450200451200452200453200454200455200456200457200458200459200460200461200462200463200464200465200466200467200468200469200470200471200472200473200474200475200476200477200478200479200480200481200482200483200484200485200486200487200488200489200490200491200492200493200494200495200496200497200498200499200500200501200502200503200504200505200506200507200508200509200510200511200512200513200514200515200516200517200518200519200520200521200522200523200524200525200526200527200528200529200530200531200532200533200534200535200536200537200538200539200540200541200542200543200544200545200546200547200548200549200550200551200552200553200554200555200556200557200558200559200560200561200562200563200564200565200566200567200568200569200570200571200572200573200574200575200576200577200578200579200580200581200582200583200584200585200586200587200588200589200590200591200592200593200594200595200596200597200598200599200600200601200602200603200604200605200606200607200608200609200610200611200612200613200614200615200616200617200618200619200620200621200622200623200624200625200626200627200628200629200630200631200632200633200634200635200636200637200638200639200640200641200642200643200644200645200646200647200648200649200650200651200652200653200654200655200656200657200658200659200660200661200662200663200664200665200666200667200668200669200670200671200672200673200674200675200676200677200678200679200680200681200682200683200684200685200686200687200688200689200690200691200692200693200694200695200696200697200698200699200700200701200702200703200704200705200706200707200708200709200710200711200712200713200714200715200716200717200718200719200720200721200722200723200724200725200726200727200728200729200730200731200732200733200734200735200736200737200738200739200740200741200742200743200744200745200746200747200748200749200750200751200752200753200754200755200756200757200758200759200760200761200762200763200764200765200766200767200768200769200770200771200772200773200774200775200776200777200778200779200780200781200782200783200784200785200786200787200788200789200790200791200792200793200794200795200796200797200798200799200800200801200802200803200804200805200806200807200808200809200810200811200812200813200814200815200816200817200818200819200820200821200822200823200824200825200826200827200828200829200830200831200832200833200834200835200836200837200838200839200840200841200842200843200844200845200846200847200848200849200850200851200852200853200854200855200856200857200858200859200860200861200862200863200864200865200866200867200868200869200870200871200872200873200874200875200876200877200878200879200880200881200882200883200884200885200886200887200888200889200890200891200892200893200894200895200896200897200898200899200900200901200902200903200904200905200906200907200908200909200910200911200912200913200914200915200916200917200918200919200920200921200922200923200924200925200926200927200928200929200930200931200932200933200934200935200936200937200938200939200940200941200942200943200944200945200946200947200948200949200950200951200952200953200954200955200956200957200958200959200960200961200962200963200964200965200966200967200968200969200970200971200972200973200974200975200976200977200978200979200980200981200982200983200984200985200986200987200988200989200990200991200992200993200994200995200996200997200998200999201000201001201002201003201004201005201006201007201008201009201010201011201012201013201014201015201016201017201018201019201020201021201022201023201024201025201026201027201028201029201030201031201032201033201034201035201036201037201038201039201040201041201042201043201044201045201046201047201048201049201050201051201052201053201054201055201056201057201058201059201060201061201062201063201064201065201066201067201068201069201070201071201072201073201074201075201076201077201078201079201080201081201082201083201084201085201086201087201088201089201090201091201092201093201094201095201096201097201098201099201100201101201102201103201104201105201106201107201108201109201110201111201112201113201114201115201116201117201118201119201120201121201122201123201124201125201126201127201128201129201130201131201132201133201134201135201136201137201138201139201140201141201142201143201144201145201146201147201148201149201150201151201152201153201154201155201156201157201158201159201160201161201162201163201164201165201166201167201168201169201170201171201172201173201174201175201176201177201178201179201180201181201182201183201184201185201186201187201188201189201190201191201192201193201194201195201196201197201198201199201200201201201202201203201204201205201206201207201208201209201210201211201212201213201214201215201216201217201218201219201220201221201222201223201224201225201226201227201228201229201230201231201232201233201234201235201236201237201238201239201240201241201242201243201244201245201246201247201248201249201250201251201252201253201254201255201256201257201258201259201260201261201262201263201264201265201266201267201268201269201270201271201272201273201274201275201276201277201278201279201280201281201282201283201284201285201286201287201288201289201290201291201292201293201294201295201296201297201298201299201300201301201302201303201304201305201306201307201308201309201310201311201312201313201314201315201316201317201318201319201320201321201322201323201324201325201326201327201328201329201330201331201332201333201334201335201336201337201338201339201340201341201342201343201344201345201346201347201348201349201350201351201352201353201354201355201356201357201358201359201360201361201362201363201364201365201366201367201368201369201370201371201372201373201374201375201376201377201378201379201380201381201382201383201384201385201386201387201388201389201390201391201392201393201394201395201396201397201398201399201400201401201402201403201404201405201406201407201408201409201410201411201412201413201414201415201416201417201418201419201420201421201422201423201424201425201426201427201428201429201430201431201432201433201434201435201436201437201438201439201440201441201442201443201444201445201446201447201448201449201450201451201452201453201454201455201456201457201458201459201460201461201462201463201464201465201466201467201468201469201470201471201472201473201474201475201476201477201478201479201480201481201482201483201484201485201486201487201488201489201490201491201492201493201494201495201496201497201498201499201500201501201502201503201504201505201506201507201508201509201510201511201512201513201514201515201516201517201518201519201520201521201522201523201524201525201526201527201528201529201530201531201532201533201534201535201536201537201538201539201540201541201542201543201544201545201546201547201548201549201550201551201552201553201554201555201556201557201558201559201560201561201562201563201564201565201566201567201568201569201570201571201572201573201574201575201576201577201578201579201580201581201582201583201584201585201586201587201588201589201590201591201592201593201594201595201596201597201598201599201600201601201602201603201604201605201606201607201608201609201610201611201612201613201614201615201616201617201618201619201620201621201622201623201624201625201626201627201628201629201630201631201632201633201634201635201636201637201638201639201640201641201642201643201644201645201646201647201648201649201650201651201652201653201654201655201656201657201658201659201660201661201662201663201664201665201666201667201668201669201670201671201672201673201674201675201676201677201678201679201680201681201682201683201684201685201686201687201688201689201690201691201692201693201694201695201696201697201698201699201700201701201702201703201704201705201706201707201708201709201710201711201712201713201714201715201716201717201718201719201720201721201722201723201724201725201726201727201728201729201730201731201732201733201734201735201736201737201738201739201740201741201742201743201744201745201746201747201748201749201750201751201752201753201754201755201756201757201758201759201760201761201762201763201764201765201766201767201768201769201770201771201772201773201774201775201776201777201778201779201780201781201782201783201784201785201786201787201788201789201790201791201792201793201794201795201796201797201798201799201800201801201802201803201804201805201806201807201808201809201810201811201812201813201814201815201816201817201818201819201820201821201822201823201824201825201826201827201828201829201830201831201832201833201834201835201836201837201838201839201840201841201842201843201844201845201846201847201848201849201850201851201852201853201854201855201856201857201858201859201860201861201862201863201864201865201866201867201868201869201870201871201872201873201874201875201876201877201878201879201880201881201882201883201884201885201886201887201888201889201890201891201892201893201894201895201896201897201898201899201900201901201902201903201904201905201906201907201908201909201910201911201912201913201914201915201916201917201918201919201920201921201922201923201924201925201926201927201928201929201930201931201932201933201934201935201936201937201938201939201940201941201942201943201944201945201946201947201948201949201950201951201952201953201954201955201956201957201958201959201960201961201962201963201964201965201966201967201968201969201970201971201972201973201974201975201976201977201978201979201980201981201982201983201984201985201986201987201988201989201990201991201992201993201994201995201996201997201998201999202000202001202002202003202004202005202006202007202008202009202010202011202012202013202014202015202016202017202018202019202020202021202022202023202024202025202026202027202028202029202030202031202032202033202034202035202036202037202038202039202040202041202042202043202044202045202046202047202048202049202050202051202052202053202054202055202056202057202058202059202060202061202062202063202064202065202066202067202068202069202070202071202072202073202074202075202076202077202078202079202080202081202082202083202084202085202086202087202088202089202090202091202092202093202094202095202096202097202098202099202100202101202102202103202104202105202106202107202108202109202110202111202112202113202114202115202116202117202118202119202120202121202122202123202124202125202126202127202128202129202130202131202132202133202134202135202136202137202138202139202140202141202142202143202144202145202146202147202148202149202150202151202152202153202154202155202156202157202158202159202160202161202162202163202164202165202166202167202168202169202170202171202172202173202174202175202176202177202178202179202180202181202182202183202184202185202186202187202188202189202190202191202192202193202194202195202196202197202198202199202200202201202202202203202204202205202206202207202208202209202210202211202212202213202214202215202216202217202218202219202220202221202222202223202224202225202226202227202228202229202230202231202232202233202234202235202236202237202238202239202240202241202242202243202244202245202246202247202248202249202250202251202252202253202254202255202256202257202258202259202260202261202262202263202264202265202266202267202268202269202270202271202272202273202274202275202276202277202278202279202280202281202282202283202284202285202286202287202288202289202290202291202292202293202294202295202296202297202298202299202300202301202302202303202304202305202306202307202308202309202310202311202312202313202314202315202316202317202318202319202320202321202322202323202324202325202326202327202328202329202330202331202332202333202334202335202336202337202338202339202340202341202342202343202344202345202346202347202348202349202350202351202352202353202354202355202356202357202358202359202360202361202362202363202364202365202366202367202368202369202370202371202372202373202374202375202376202377202378202379202380202381202382202383202384202385202386202387202388202389202390202391202392202393202394202395202396202397202398202399202400202401202402202403202404202405202406202407202408202409202410202411202412202413202414202415202416202417202418202419202420202421202422202423202424202425202426202427202428202429202430202431202432202433202434202435202436202437202438202439202440202441202442202443202444202445202446202447202448202449202450202451202452202453202454202455202456202457202458202459202460202461202462202463202464202465202466202467202468202469202470202471202472202473202474202475202476202477202478202479202480202481202482202483202484202485202486202487202488202489202490202491202492202493202494202495202496202497202498202499202500202501202502202503202504202505202506202507202508202509202510202511202512202513202514202515202516202517202518202519202520202521202522202523202524202525202526202527202528202529202530202531202532202533202534202535202536202537202538202539202540202541202542202543202544202545202546202547202548202549202550202551202552202553202554202555202556202557202558202559202560202561202562202563202564202565202566202567202568202569202570202571202572202573202574202575202576202577202578202579202580202581202582202583202584202585202586202587202588202589202590202591202592202593202594202595202596202597202598202599202600202601202602202603202604202605202606202607202608202609202610202611202612202613202614202615202616202617202618202619202620202621202622202623202624202625202626202627202628202629202630202631202632202633202634202635202636202637202638202639202640202641202642202643202644202645202646202647202648202649202650202651202652202653202654202655202656202657202658202659202660202661202662202663202664202665202666202667202668202669202670202671202672202673202674202675202676202677202678202679202680202681202682202683202684202685202686202687202688202689202690202691202692202693202694202695202696202697202698202699202700202701202702202703202704202705202706202707202708202709202710202711202712202713202714202715202716202717202718202719202720202721202722202723202724202725202726202727202728202729202730202731202732202733202734202735202736202737202738202739202740202741202742202743202744202745202746202747202748202749202750202751202752202753202754202755202756202757202758202759202760202761202762202763202764202765202766202767202768202769202770202771202772202773202774202775202776202777202778202779202780202781202782202783202784202785202786202787202788202789202790202791202792202793202794202795202796202797202798202799202800202801202802202803202804202805202806202807202808202809202810202811202812202813202814202815202816202817202818202819202820202821202822202823202824202825202826202827202828202829202830202831202832202833202834202835202836202837202838202839202840202841202842202843202844202845202846202847202848202849202850202851202852202853202854202855202856202857202858202859202860202861202862202863202864202865202866202867202868202869202870202871202872202873202874202875202876202877202878202879202880202881202882202883202884202885202886202887202888202889202890202891202892202893202894202895202896202897202898202899202900202901202902202903202904202905202906202907202908202909202910202911202912202913202914202915202916202917202918202919202920202921202922202923202924202925202926202927202928202929202930202931202932202933202934202935202936202937202938202939202940202941202942202943202944202945202946202947202948202949202950202951202952202953202954202955202956202957202958202959202960202961202962202963202964202965202966202967202968202969202970202971202972202973202974202975202976202977202978202979202980202981202982202983202984202985202986202987202988202989202990202991202992202993202994202995202996202997202998202999203000203001203002203003203004203005203006203007203008203009203010203011203012203013203014203015203016203017203018203019203020203021203022203023203024203025203026203027203028203029203030203031203032203033203034203035203036203037203038203039203040203041203042203043203044203045203046203047203048203049203050203051203052203053203054203055203056203057203058203059203060203061203062203063203064203065203066203067203068203069203070203071203072203073203074203075203076203077203078203079203080203081203082203083203084203085203086203087203088203089203090203091203092203093203094203095203096203097203098203099203100203101203102203103203104203105203106203107203108203109203110203111203112203113203114203115203116203117203118203119203120203121203122203123203124203125203126203127203128203129203130203131203132203133203134203135203136203137203138203139203140203141203142203143203144203145203146203147203148203149203150203151203152203153203154203155203156203157203158203159203160203161203162203163203164203165203166203167203168203169203170203171203172203173203174203175203176203177203178203179203180203181203182203183203184203185203186203187203188203189203190203191203192203193203194203195203196203197203198203199203200203201203202203203203204203205203206203207203208203209203210203211203212203213203214203215203216203217203218203219203220203221203222203223203224203225203226203227203228203229203230203231203232203233203234203235203236203237203238203239203240203241203242203243203244203245203246203247203248203249203250203251203252203253203254203255203256203257203258203259203260203261203262203263203264203265203266203267203268203269203270203271203272203273203274203275203276203277203278203279203280203281203282203283203284203285203286203287203288203289203290203291203292203293203294203295203296203297203298203299203300203301203302203303203304203305203306203307203308203309203310203311203312203313203314203315203316203317203318203319203320203321203322203323203324203325203326203327203328203329203330203331203332203333203334203335203336203337203338203339203340203341203342203343203344203345203346203347203348203349203350203351203352203353203354203355203356203357203358203359203360203361203362203363203364203365203366203367203368203369203370203371203372203373203374203375203376203377203378203379203380203381203382203383203384203385203386203387203388203389203390203391203392203393203394203395203396203397203398203399203400203401203402203403203404203405203406203407203408203409203410203411203412203413203414203415203416203417203418203419203420203421203422203423203424203425203426203427203428203429203430203431203432203433203434203435203436203437203438203439203440203441203442203443203444203445203446203447203448203449203450203451203452203453203454203455203456203457203458203459203460203461203462203463203464203465203466203467203468203469203470203471203472203473203474203475203476203477203478203479203480203481203482203483203484203485203486203487203488203489203490203491203492203493203494203495203496203497203498203499203500203501203502203503203504203505203506203507203508203509203510203511203512203513203514203515203516203517203518203519203520203521203522203523203524203525203526203527203528203529203530203531203532203533203534203535203536203537203538203539203540203541203542203543203544203545203546203547203548203549203550203551203552203553203554203555203556203557203558203559203560203561203562203563203564203565203566203567203568203569203570203571203572203573203574203575203576203577203578203579203580203581203582203583203584203585203586203587203588203589203590203591203592203593203594203595203596203597203598203599203600203601203602203603203604203605203606203607203608203609203610203611203612203613203614203615203616203617203618203619203620203621203622203623203624203625203626203627203628203629203630203631203632203633203634203635203636203637203638203639203640203641203642203643203644203645203646203647203648203649203650203651203652203653203654203655203656203657203658203659203660203661203662203663203664203665203666203667203668203669203670203671203672203673203674203675203676203677203678203679203680203681203682203683203684203685203686203687203688203689203690203691203692203693203694203695203696203697203698203699203700203701203702203703203704203705203706203707203708203709203710203711203712203713203714203715203716203717203718203719203720203721203722203723203724203725203726203727203728203729203730203731203732203733203734203735203736203737203738203739203740203741203742203743203744203745203746203747203748203749203750203751203752203753203754203755203756203757203758203759203760203761203762203763203764203765203766203767203768203769203770203771203772203773203774203775203776203777203778203779203780203781203782203783203784203785203786203787203788203789203790203791203792203793203794203795203796203797203798203799203800203801203802203803203804203805203806203807203808203809203810203811203812203813203814203815203816203817203818203819203820203821203822203823203824203825203826203827203828203829203830203831203832203833203834203835203836203837203838203839203840203841203842203843203844203845203846203847203848203849203850203851203852203853203854203855203856203857203858203859203860203861203862203863203864203865203866203867203868203869203870203871203872203873203874203875203876203877203878203879203880203881203882203883203884203885203886203887203888203889203890203891203892203893203894203895203896203897203898203899203900203901203902203903203904203905203906203907203908203909203910203911203912203913203914203915203916203917203918203919203920203921203922203923203924203925203926203927203928203929203930203931203932203933203934203935203936203937203938203939203940203941203942203943203944203945203946203947203948203949203950203951203952203953203954203955203956203957203958203959203960203961203962203963203964203965203966203967203968203969203970203971203972203973203974203975203976203977203978203979203980203981203982203983203984203985203986203987203988203989203990203991203992203993203994203995203996203997203998203999204000204001204002204003204004204005204006204007204008204009204010204011204012204013204014204015204016204017204018204019204020204021204022204023204024204025204026204027204028204029204030204031204032204033204034204035204036204037204038204039204040204041204042204043204044204045204046204047204048204049204050204051204052204053204054204055204056204057204058204059204060204061204062204063204064204065204066204067204068204069204070204071204072204073204074204075204076204077204078204079204080204081204082204083204084204085204086204087204088204089204090204091204092204093204094204095204096204097204098204099204100204101204102204103204104204105204106204107204108204109204110204111204112204113204114204115204116204117204118204119204120204121204122204123204124204125204126204127204128204129204130204131204132204133204134204135204136204137204138204139204140204141204142204143204144204145204146204147204148204149204150204151204152204153204154204155204156204157204158204159204160204161204162204163204164204165204166204167204168204169204170204171204172204173204174204175204176204177204178204179204180204181204182204183204184204185204186204187204188204189204190204191204192204193204194204195204196204197204198204199204200204201204202204203204204204205204206204207204208204209204210204211204212204213204214204215204216204217204218204219204220204221204222204223204224204225204226204227204228204229204230204231204232204233204234204235204236204237204238204239204240204241204242204243204244204245204246204247204248204249204250204251204252204253204254204255204256204257204258204259204260204261204262204263204264204265204266204267204268204269204270204271204272204273204274204275204276204277204278204279204280204281204282204283204284204285204286204287204288204289204290204291204292204293204294204295204296204297204298204299204300204301204302204303204304204305204306204307204308204309204310204311204312204313204314204315204316204317204318204319204320204321204322204323204324204325204326204327204328204329204330204331204332204333204334204335204336204337204338204339204340204341204342204343204344204345204346204347204348204349204350204351204352204353204354204355204356204357204358204359204360204361204362204363204364204365204366204367204368204369204370204371204372204373204374204375204376204377204378204379204380204381204382204383204384204385204386204387204388204389204390204391204392204393204394204395204396204397204398204399204400204401204402204403204404204405204406204407204408204409204410204411204412204413204414204415204416204417204418204419204420204421204422204423204424204425204426204427204428204429204430204431204432204433204434204435204436204437204438204439204440204441204442204443204444204445204446204447204448204449204450204451204452204453204454204455204456204457204458204459204460204461204462204463204464204465204466204467204468204469204470204471204472204473204474204475204476204477204478204479204480204481204482204483204484204485204486204487204488204489204490204491204492204493204494204495204496204497204498204499204500204501204502204503204504204505204506204507204508204509204510204511204512204513204514204515204516204517204518204519204520204521204522204523204524204525204526204527204528204529204530204531204532204533204534204535204536204537204538204539204540204541204542204543204544204545204546204547204548204549204550204551204552204553204554204555204556204557204558204559204560204561204562204563204564204565204566204567204568204569204570204571204572204573204574204575204576204577204578204579204580204581204582204583204584204585204586204587204588204589204590204591204592204593204594204595204596204597204598204599204600204601204602204603204604204605204606204607204608204609204610204611204612204613204614204615204616204617204618204619204620204621204622204623204624204625204626204627204628204629204630204631204632204633204634204635204636204637204638204639204640204641204642204643204644204645204646204647204648204649204650204651204652204653204654204655204656204657204658204659204660204661204662204663204664204665204666204667204668204669204670204671204672204673204674204675204676204677204678204679204680204681204682204683204684204685204686204687204688204689204690204691204692204693204694204695204696204697204698204699204700204701204702204703204704204705204706204707204708204709204710204711204712204713204714204715204716204717204718204719204720204721204722204723204724204725204726204727204728204729204730204731204732204733204734204735204736204737204738204739204740204741204742204743204744204745204746204747204748204749204750204751204752204753204754204755204756204757204758204759204760204761204762204763204764204765204766204767204768204769204770204771204772204773204774204775204776204777204778204779204780204781204782204783204784204785204786204787204788204789204790204791204792204793204794204795204796204797204798204799204800204801204802204803204804204805204806204807204808204809204810204811204812204813204814204815204816204817204818204819204820204821204822204823204824204825204826204827204828204829204830204831204832204833204834204835204836204837204838204839204840204841204842204843204844204845204846204847204848204849204850204851204852204853204854204855204856204857204858204859204860204861204862204863204864204865204866204867204868204869204870204871204872204873204874204875204876204877204878204879204880204881204882204883204884204885204886204887204888204889204890204891204892204893204894204895204896204897204898204899204900204901204902204903204904204905204906204907204908204909204910204911204912204913204914204915204916204917204918204919204920204921204922204923204924204925204926204927204928204929204930204931204932204933204934204935204936204937204938204939204940204941204942204943204944204945204946204947204948204949204950204951204952204953204954204955204956204957204958204959204960204961204962204963204964204965204966204967204968204969204970204971204972204973204974204975204976204977204978204979204980204981204982204983204984204985204986204987204988204989204990204991204992204993204994204995204996204997204998204999205000205001205002205003205004205005205006205007205008205009205010205011205012205013205014205015205016205017205018205019205020205021205022205023205024205025205026205027205028205029205030205031205032205033205034205035205036205037205038205039205040205041205042205043205044205045205046205047205048205049205050205051205052205053205054205055205056205057205058205059205060205061205062205063205064205065205066205067205068205069205070205071205072205073205074205075205076205077205078205079205080205081205082205083205084205085205086205087205088205089205090205091205092205093205094205095205096205097205098205099205100205101205102205103205104205105205106205107205108205109205110205111205112205113205114205115205116205117205118205119205120205121205122205123205124205125205126205127205128205129205130205131205132205133205134205135205136205137205138205139205140205141205142205143205144205145205146205147205148205149205150205151205152205153205154205155205156205157205158205159205160205161205162205163205164205165205166205167205168205169205170205171205172205173205174205175205176205177205178205179205180205181205182205183205184205185205186205187205188205189205190205191205192205193205194205195205196205197205198205199205200205201205202205203205204205205205206205207205208205209205210205211205212205213205214205215205216205217205218205219205220205221205222205223205224205225205226205227205228205229205230205231205232205233205234205235205236205237205238205239205240205241205242205243205244205245205246205247205248205249205250205251205252205253205254205255205256205257205258205259205260205261205262205263205264205265205266205267205268205269205270205271205272205273205274205275205276205277205278205279205280205281205282205283205284205285205286205287205288205289205290205291205292205293205294205295205296205297205298205299205300205301205302205303205304205305205306205307205308205309205310205311205312205313205314205315205316205317205318205319205320205321205322205323205324205325205326205327205328205329205330205331205332205333205334205335205336205337205338205339205340205341205342205343205344205345205346205347205348205349205350205351205352205353205354205355205356205357205358205359205360205361205362205363205364205365205366205367205368205369205370205371205372205373205374205375205376205377205378205379205380205381205382205383205384205385205386205387205388205389205390205391205392205393205394205395205396205397205398205399205400205401205402205403205404205405205406205407205408205409205410205411205412205413205414205415205416205417205418205419205420205421205422205423205424205425205426205427205428205429205430205431205432205433205434205435205436205437205438205439205440205441205442205443205444205445205446205447205448205449205450205451205452205453205454205455205456205457205458205459205460205461205462205463205464205465205466205467205468205469205470205471205472205473205474205475205476205477205478205479205480205481205482205483205484205485205486205487205488205489205490205491205492205493205494205495205496205497205498205499205500205501205502205503205504205505205506205507205508205509205510205511205512205513205514205515205516205517205518205519205520205521205522205523205524205525205526205527205528205529205530205531205532205533205534205535205536205537205538205539205540205541205542205543205544205545205546205547205548205549205550205551205552205553205554205555205556205557205558205559205560205561205562205563205564205565205566205567205568205569205570205571205572205573205574205575205576205577205578205579205580205581205582205583205584205585205586205587205588205589205590205591205592205593205594205595205596205597205598205599205600205601205602205603205604205605205606205607205608205609205610205611205612205613205614205615205616205617205618205619205620205621205622205623205624205625205626205627205628205629205630205631205632205633205634205635205636205637205638205639205640205641205642205643205644205645205646205647205648205649205650205651205652205653205654205655205656205657205658205659205660205661205662205663205664205665205666205667205668205669205670205671205672205673205674205675205676205677205678205679205680205681205682205683205684205685205686205687205688205689205690205691205692205693205694205695205696205697205698205699205700205701205702205703205704205705205706205707205708205709205710205711205712205713205714205715205716205717205718205719205720205721205722205723205724205725205726205727205728205729205730205731205732205733205734205735205736205737205738205739205740205741205742205743205744205745205746205747205748205749205750205751205752205753205754205755205756205757205758205759205760205761205762205763205764205765205766205767205768205769205770205771205772205773205774205775205776205777205778205779205780205781205782205783205784205785205786205787205788205789205790205791205792205793205794205795205796205797205798205799205800205801205802205803205804205805205806205807205808205809205810205811205812205813205814205815205816205817205818205819205820205821205822205823205824205825205826205827205828205829205830205831205832205833205834205835205836205837205838205839205840205841205842205843205844205845205846205847205848205849205850205851205852205853205854205855205856205857205858205859205860205861205862205863205864205865205866205867205868205869205870205871205872205873205874205875205876205877205878205879205880205881205882205883205884205885205886205887205888205889205890205891205892205893205894205895205896205897205898205899205900205901205902205903205904205905205906205907205908205909205910205911205912205913205914205915205916205917205918205919205920205921205922205923205924205925205926205927205928205929205930205931205932205933205934205935205936205937205938205939205940205941205942205943205944205945205946205947205948205949205950205951205952205953205954205955205956205957205958205959205960205961205962205963205964205965205966205967205968205969205970205971205972205973205974205975205976205977205978205979205980205981205982205983205984205985205986205987205988205989205990205991205992205993205994205995205996205997205998205999206000206001206002206003206004206005206006206007206008206009206010206011206012206013206014206015206016206017206018206019206020206021206022206023206024206025206026206027206028206029206030206031206032206033206034206035206036206037206038206039206040206041206042206043206044206045206046206047206048206049206050206051206052206053206054206055206056206057206058206059206060206061206062206063206064206065206066206067206068206069206070206071206072206073206074206075206076206077206078206079206080206081206082206083206084206085206086206087206088206089206090206091206092206093206094206095206096206097206098206099206100206101206102206103206104206105206106206107206108206109206110206111206112206113206114206115206116206117206118206119206120206121206122206123206124206125206126206127206128206129206130206131206132206133206134206135206136206137206138206139206140206141206142206143206144206145206146206147206148206149206150206151206152206153206154206155206156206157206158206159206160206161206162206163206164206165206166206167206168206169206170206171206172206173206174206175206176206177206178206179206180206181206182206183206184206185206186206187206188206189206190206191206192206193206194206195206196206197206198206199206200206201206202206203206204206205206206206207206208206209206210206211206212206213206214206215206216206217206218206219206220206221206222206223206224206225206226206227206228206229206230206231206232206233206234206235206236206237206238206239206240206241206242206243206244206245206246206247206248206249206250206251206252206253206254206255206256206257206258206259206260206261206262206263206264206265206266206267206268206269206270206271206272206273206274206275206276206277206278206279206280206281206282206283206284206285206286206287206288206289206290206291206292206293206294206295206296206297206298206299206300206301206302206303206304206305206306206307206308206309206310206311206312206313206314206315206316206317206318206319206320206321206322206323206324206325206326206327206328206329206330206331206332206333206334206335206336206337206338206339206340206341206342206343206344206345206346206347206348206349206350206351206352206353206354206355206356206357206358206359206360206361206362206363206364206365206366206367206368206369206370206371206372206373206374206375206376206377206378206379206380206381206382206383206384206385206386206387206388206389206390206391206392206393206394206395206396206397206398206399206400206401206402206403206404206405206406206407206408206409206410206411206412206413206414206415206416206417206418206419206420206421206422206423206424206425206426206427206428206429206430206431206432206433206434206435206436206437206438206439206440206441206442206443206444206445206446206447206448206449206450206451206452206453206454206455206456206457206458206459206460206461206462206463206464206465206466206467206468206469206470206471206472206473206474206475206476206477206478206479206480206481206482206483206484206485206486206487206488206489206490206491206492206493206494206495206496206497206498206499206500206501206502206503206504206505206506206507206508206509206510206511206512206513206514206515206516206517206518206519206520206521206522206523206524206525206526206527206528206529206530206531206532206533206534206535206536206537206538206539206540206541206542206543206544206545206546206547206548206549206550206551206552206553206554206555206556206557206558206559206560206561206562206563206564206565206566206567206568206569206570206571206572206573206574206575206576206577206578206579206580206581206582206583206584206585206586206587206588206589206590206591206592206593206594206595206596206597206598206599206600206601206602206603206604206605206606206607206608206609206610206611206612206613206614206615206616206617206618206619206620206621206622206623206624206625206626206627206628206629206630206631206632206633206634206635206636206637206638206639206640206641206642206643206644206645206646206647206648206649206650206651206652206653206654206655206656206657206658206659206660206661206662206663206664206665206666206667206668206669206670206671206672206673206674206675206676206677206678206679206680206681206682206683206684206685206686206687206688206689206690206691206692206693206694206695206696206697206698206699206700206701206702206703206704206705206706206707206708206709206710206711206712206713206714206715206716206717206718206719206720206721206722206723206724206725206726206727206728206729206730206731206732206733206734206735206736206737206738206739206740206741206742206743206744206745206746206747206748206749206750206751206752206753206754206755206756206757206758206759206760206761206762206763206764206765206766206767206768206769206770206771206772206773206774206775206776206777206778206779206780206781206782206783206784206785206786206787206788206789206790206791206792206793206794206795206796206797206798206799206800206801206802206803206804206805206806206807206808206809206810206811206812206813206814206815206816206817206818206819206820206821206822206823206824206825206826206827206828206829206830206831206832206833206834206835206836206837206838206839206840206841206842206843206844206845206846206847206848206849206850206851206852206853206854206855206856206857206858206859206860206861206862206863206864206865206866206867206868206869206870206871206872206873206874206875206876206877206878206879206880206881206882206883206884206885206886206887206888206889206890206891206892206893206894206895206896206897206898206899206900206901206902206903206904206905206906206907206908206909206910206911206912206913206914206915206916206917206918206919206920206921206922206923206924206925206926206927206928206929206930206931206932206933206934206935206936206937206938206939206940206941206942206943206944206945206946206947206948206949206950206951206952206953206954206955206956206957206958206959206960206961206962206963206964206965206966206967206968206969206970206971206972206973206974206975206976206977206978206979206980206981206982206983206984206985206986206987206988206989206990206991206992206993206994206995206996206997206998206999207000207001207002207003207004207005207006207007207008207009207010207011207012207013207014207015207016207017207018207019207020207021207022207023207024207025207026207027207028207029207030207031207032207033207034207035207036207037207038207039207040207041207042207043207044207045207046207047207048207049207050207051207052207053207054207055207056207057207058207059207060207061207062207063207064207065207066207067207068207069207070207071207072207073207074207075207076207077207078207079207080207081207082207083207084207085207086207087207088207089207090207091207092207093207094207095207096207097207098207099207100207101207102207103207104207105207106207107207108207109207110207111207112207113207114207115207116207117207118207119207120207121207122207123207124207125207126207127207128207129207130207131207132207133207134207135207136207137207138207139207140207141207142207143207144207145207146207147207148207149207150207151207152207153207154207155207156207157207158207159207160207161207162207163207164207165207166207167207168207169207170207171207172207173207174207175207176207177207178207179207180207181207182207183207184207185207186207187207188207189207190207191207192207193207194207195207196207197207198207199207200207201207202207203207204207205207206207207207208207209207210207211207212207213207214207215207216207217207218207219207220207221207222207223207224207225207226207227207228207229207230207231207232207233207234207235207236207237207238207239207240207241207242207243207244207245207246207247207248207249207250207251207252207253207254207255207256207257207258207259207260207261207262207263207264207265207266207267207268207269207270207271207272207273207274207275207276207277207278207279207280207281207282207283207284207285207286207287207288207289207290207291207292207293207294207295207296207297207298207299207300207301207302207303207304207305207306207307207308207309207310207311207312207313207314207315207316207317207318207319207320207321207322207323207324207325207326207327207328207329207330207331207332207333207334207335207336207337207338207339207340207341207342207343207344207345207346207347207348207349207350207351207352207353207354207355207356207357207358207359207360207361207362207363207364207365207366207367207368207369207370207371207372207373207374207375207376207377207378207379207380207381207382207383207384207385207386207387207388207389207390207391207392207393207394207395207396207397207398207399207400207401207402207403207404207405207406207407207408207409207410207411207412207413207414207415207416207417207418207419207420207421207422207423207424207425207426207427207428207429207430207431207432207433207434207435207436207437207438207439207440207441207442207443207444207445207446207447207448207449207450207451207452207453207454207455207456207457207458207459207460207461207462207463207464207465207466207467207468207469207470207471207472207473207474207475207476207477207478207479207480207481207482207483207484207485207486207487207488207489207490207491207492207493207494207495207496207497207498207499207500207501207502207503207504207505207506207507207508207509207510207511207512207513207514207515207516207517207518207519207520207521207522207523207524207525207526207527207528207529207530207531207532207533207534207535207536207537207538207539207540207541207542207543207544207545207546207547207548207549207550207551207552207553207554207555207556207557207558207559207560207561207562207563207564207565207566207567207568207569207570207571207572207573207574207575207576207577207578207579207580207581207582207583207584207585207586207587207588207589207590207591207592207593207594207595207596207597207598207599207600207601207602207603207604207605207606207607207608207609207610207611207612207613207614207615207616207617207618207619207620207621207622207623207624207625207626207627207628207629207630207631207632207633207634207635207636207637207638207639207640207641207642207643207644207645207646207647207648207649207650207651207652207653207654207655207656207657207658207659207660207661207662207663207664207665207666207667207668207669207670207671207672207673207674207675207676207677207678207679207680207681207682207683207684207685207686207687207688207689207690207691207692207693207694207695207696207697207698207699207700207701207702207703207704207705207706207707207708207709207710207711207712207713207714207715207716207717207718207719207720207721207722207723207724207725207726207727207728207729207730207731207732207733207734207735207736207737207738207739207740207741207742207743207744207745207746207747207748207749207750207751207752207753207754207755207756207757207758207759207760207761207762207763207764207765207766207767207768207769207770207771207772207773207774207775207776207777207778207779207780207781207782207783207784207785207786207787207788207789207790207791207792207793207794207795207796207797207798207799207800207801207802207803207804207805207806207807207808207809207810207811207812207813207814207815207816207817207818207819207820207821207822207823207824207825207826207827207828207829207830207831207832207833207834207835207836207837207838207839207840207841207842207843207844207845207846207847207848207849207850207851207852207853207854207855207856207857207858207859207860207861207862207863207864207865207866207867207868207869207870207871207872207873207874207875207876207877207878207879207880207881207882207883207884207885207886207887207888207889207890207891207892207893207894207895207896207897207898207899207900207901207902207903207904207905207906207907207908207909207910207911207912207913207914207915207916207917207918207919207920207921207922207923207924207925207926207927207928207929207930207931207932207933207934207935207936207937207938207939207940207941207942207943207944207945207946207947207948207949207950207951207952207953207954207955207956207957207958207959207960207961207962207963207964207965207966207967207968207969207970207971207972207973207974207975207976207977207978207979207980207981207982207983207984207985207986207987207988207989207990207991207992207993207994207995207996207997207998207999208000208001208002208003208004208005208006208007208008208009208010208011208012208013208014208015208016208017208018208019208020208021208022208023208024208025208026208027208028208029208030208031208032208033208034208035208036208037208038208039208040208041208042208043208044208045208046208047208048208049208050208051208052208053208054208055208056208057208058208059208060208061208062208063208064208065208066208067208068208069208070208071208072208073208074208075208076208077208078208079208080208081208082208083208084208085208086208087208088208089208090208091208092208093208094208095208096208097208098208099208100208101208102208103208104208105208106208107208108208109208110208111208112208113208114208115208116208117208118208119208120208121208122208123208124208125208126208127208128208129208130208131208132208133208134208135208136208137208138208139208140208141208142208143208144208145208146208147208148208149208150208151208152208153208154208155208156208157208158208159208160208161208162208163208164208165208166208167208168208169208170208171208172208173208174208175208176208177208178208179208180208181208182208183208184208185208186208187208188208189208190208191208192208193208194208195208196208197208198208199208200208201208202208203208204208205208206208207208208208209208210208211208212208213208214208215208216208217208218208219208220208221208222208223208224208225208226208227208228208229208230208231208232208233208234208235208236208237208238208239208240208241208242208243208244208245208246208247208248208249208250208251208252208253208254208255208256208257208258208259208260208261208262208263208264208265208266208267208268208269208270208271208272208273208274208275208276208277208278208279208280208281208282208283208284208285208286208287208288208289208290208291208292208293208294208295208296208297208298208299208300208301208302208303208304208305208306208307208308208309208310208311208312208313208314208315208316208317208318208319208320208321208322208323208324208325208326208327208328208329208330208331208332208333208334208335208336208337208338208339208340208341208342208343208344208345208346208347208348208349208350208351208352208353208354208355208356208357208358208359208360208361208362208363208364208365208366208367208368208369208370208371208372208373208374208375208376208377208378208379208380208381208382208383208384208385208386208387208388208389208390208391208392208393208394208395208396208397208398208399208400208401208402208403208404208405208406208407208408208409208410208411208412208413208414208415208416208417208418208419208420208421208422208423208424208425208426208427208428208429208430208431208432208433208434208435208436208437208438208439208440208441208442208443208444208445208446208447208448208449208450208451208452208453208454208455208456208457208458208459208460208461208462208463208464208465208466208467208468208469208470208471208472208473208474208475208476208477208478208479208480208481208482208483208484208485208486208487208488208489208490208491208492208493208494208495208496208497208498208499208500208501208502208503208504208505208506208507208508208509208510208511208512208513208514208515208516208517208518208519208520208521208522208523208524208525208526208527208528208529208530208531208532208533208534208535208536208537208538208539208540208541208542208543208544208545208546208547208548208549208550208551208552208553208554208555208556208557208558208559208560208561208562208563208564208565208566208567208568208569208570208571208572208573208574208575208576208577208578208579208580208581208582208583208584208585208586208587208588208589208590208591208592208593208594208595208596208597208598208599208600208601208602208603208604208605208606208607208608208609208610208611208612208613208614208615208616208617208618208619208620208621208622208623208624208625208626208627208628208629208630208631208632208633208634208635208636208637208638208639208640208641208642208643208644208645208646208647208648208649208650208651208652208653208654208655208656208657208658208659208660208661208662208663208664208665208666208667208668208669208670208671208672208673208674208675208676208677208678208679208680208681208682208683208684208685208686208687208688208689208690208691208692208693208694208695208696208697208698208699208700208701208702208703208704208705208706208707208708208709208710208711208712208713208714208715208716208717208718208719208720208721208722208723208724208725208726208727208728208729208730208731208732208733208734208735208736208737208738208739208740208741208742208743208744208745208746208747208748208749208750208751208752208753208754208755208756208757208758208759208760208761208762208763208764208765208766208767208768208769208770208771208772208773208774208775208776208777208778208779208780208781208782208783208784208785208786208787208788208789208790208791208792208793208794208795208796208797208798208799208800208801208802208803208804208805208806208807208808208809208810208811208812208813208814208815208816208817208818208819208820208821208822208823208824208825208826208827208828208829208830208831208832208833208834208835208836208837208838208839208840208841208842208843208844208845208846208847208848208849208850208851208852208853208854208855208856208857208858208859208860208861208862208863208864208865208866208867208868208869208870208871208872208873208874208875208876208877208878208879208880208881208882208883208884208885208886208887208888208889208890208891208892208893208894208895208896208897208898208899208900208901208902208903208904208905208906208907208908208909208910208911208912208913208914208915208916208917208918208919208920208921208922208923208924208925208926208927208928208929208930208931208932208933208934208935208936208937208938208939208940208941208942208943208944208945208946208947208948208949208950208951208952208953208954208955208956208957208958208959208960208961208962208963208964208965208966208967208968208969208970208971208972208973208974208975208976208977208978208979208980208981208982208983208984208985208986208987208988208989208990208991208992208993208994208995208996208997208998208999209000209001209002209003209004209005209006209007209008209009209010209011209012209013209014209015209016209017209018209019209020209021209022209023209024209025209026209027209028209029209030209031209032209033209034209035209036209037209038209039209040209041209042209043209044209045209046209047209048209049209050209051209052209053209054209055209056209057209058209059209060209061209062209063209064209065209066209067209068209069209070209071209072209073209074209075209076209077209078209079209080209081209082209083209084209085209086209087209088209089209090209091209092209093209094209095209096209097209098209099209100209101209102209103209104209105209106209107209108209109209110209111209112209113209114209115209116209117209118209119209120209121209122209123209124209125209126209127209128209129209130209131209132209133209134209135209136209137209138209139209140209141209142209143209144209145209146209147209148209149209150209151209152209153209154209155209156209157209158209159209160209161209162209163209164209165209166209167209168209169209170209171209172209173209174209175209176209177209178209179209180209181209182209183209184209185209186209187209188209189209190209191209192209193209194209195209196209197209198209199209200209201209202209203209204209205209206209207209208209209209210209211209212209213209214209215209216209217209218209219209220209221209222209223209224209225209226209227209228209229209230209231209232209233209234209235209236209237209238209239209240209241209242209243209244209245209246209247209248209249209250209251209252209253209254209255209256209257209258209259209260209261209262209263209264209265209266209267209268209269209270209271209272209273209274209275209276209277209278209279209280209281209282209283209284209285209286209287209288209289209290209291209292209293209294209295209296209297209298209299209300209301209302209303209304209305209306209307209308209309209310209311209312209313209314209315209316209317209318209319209320209321209322209323209324209325209326209327209328209329209330209331209332209333209334209335209336209337209338209339209340209341209342209343209344209345209346209347209348209349209350209351209352209353209354209355209356209357209358209359209360209361209362209363209364209365209366209367209368209369209370209371209372209373209374209375209376209377209378209379209380209381209382209383209384209385209386209387209388209389209390209391209392209393209394209395209396209397209398209399209400209401209402209403209404209405209406209407209408209409209410209411209412209413209414209415209416209417209418209419209420209421209422209423209424209425209426209427209428209429209430209431209432209433209434209435209436209437209438209439209440209441209442209443209444209445209446209447209448209449209450209451209452209453209454209455209456209457209458209459209460209461209462209463209464209465209466209467209468209469209470209471209472209473209474209475209476209477209478209479209480209481209482209483209484209485209486209487209488209489209490209491209492209493209494209495209496209497209498209499209500209501209502209503209504209505209506209507209508209509209510209511209512209513209514209515209516209517209518209519209520209521209522209523209524209525209526209527209528209529209530209531209532209533209534209535209536209537209538209539209540209541209542209543209544209545209546209547209548209549209550209551209552209553209554209555209556209557209558209559209560209561209562209563209564209565209566209567209568209569209570209571209572209573209574209575209576209577209578209579209580209581209582209583209584209585209586209587209588209589209590209591209592209593209594209595209596209597209598209599209600209601209602209603209604209605209606209607209608209609209610209611209612209613209614209615209616209617209618209619209620209621209622209623209624209625209626209627209628209629209630209631209632209633209634209635209636209637209638209639209640209641209642209643209644209645209646209647209648209649209650209651209652209653209654209655209656209657209658209659209660209661209662209663209664209665209666209667209668209669209670209671209672209673209674209675209676209677209678209679209680209681209682209683209684209685209686209687209688209689209690209691209692209693209694209695209696209697209698209699209700209701209702209703209704209705209706209707209708209709209710209711209712209713209714209715209716209717209718209719209720209721209722209723209724209725209726209727209728209729209730209731209732209733209734209735209736209737209738209739209740209741209742209743209744209745209746209747209748209749209750209751209752209753209754209755209756209757209758209759209760209761209762209763209764209765209766209767209768209769209770209771209772209773209774209775209776209777209778209779209780209781209782209783209784209785209786209787209788209789209790209791209792209793209794209795209796209797209798209799209800209801209802209803209804209805209806209807209808209809209810209811209812209813209814209815209816209817209818209819209820209821209822209823209824209825209826209827209828209829209830209831209832209833209834209835209836209837209838209839209840209841209842209843209844209845209846209847209848209849209850209851209852209853209854209855209856209857209858209859209860209861209862209863209864209865209866209867209868209869209870209871209872209873209874209875209876209877209878209879209880209881209882209883209884209885209886209887209888209889209890209891209892209893209894209895209896209897209898209899209900209901209902209903209904209905209906209907209908209909209910209911209912209913209914209915209916209917209918209919209920209921209922209923209924209925209926209927209928209929209930209931209932209933209934209935209936209937209938209939209940209941209942209943209944209945209946209947209948209949209950209951209952209953209954209955209956209957209958209959209960209961209962209963209964209965209966209967209968209969209970209971209972209973209974209975209976209977209978209979209980209981209982209983209984209985209986209987209988209989209990209991209992209993209994209995209996209997209998209999210000210001210002210003210004210005210006210007210008210009210010210011210012210013210014210015210016210017210018210019210020210021210022210023210024210025210026210027210028210029210030210031210032210033210034210035210036210037210038210039210040210041210042210043210044210045210046210047210048210049210050210051210052210053210054210055210056210057210058210059210060210061210062210063210064210065210066210067210068210069210070210071210072210073210074210075210076210077210078210079210080210081210082210083210084210085210086210087210088210089210090210091210092210093210094210095210096210097210098210099210100210101210102210103210104210105210106210107210108210109210110210111210112210113210114210115210116210117210118210119210120210121210122210123210124210125210126210127210128210129210130210131210132210133210134210135210136210137210138210139210140210141210142210143210144210145210146210147210148210149210150210151210152210153210154210155210156210157210158210159210160210161210162210163210164210165210166210167210168210169210170210171210172210173210174210175210176210177210178210179210180210181210182210183210184210185210186210187210188210189210190210191210192210193210194210195210196210197210198210199210200210201210202210203210204210205210206210207210208210209210210210211210212210213210214210215210216210217210218210219210220210221210222210223210224210225210226210227210228210229210230210231210232210233210234210235210236210237210238210239210240210241210242210243210244210245210246210247210248210249210250210251210252210253210254210255210256210257210258210259210260210261210262210263210264210265210266210267210268210269210270210271210272210273210274210275210276210277210278210279210280210281210282210283210284210285210286210287210288210289210290210291210292210293210294210295210296210297210298210299210300210301210302210303210304210305210306210307210308210309210310210311210312210313210314210315210316210317210318210319210320210321210322210323210324210325210326210327210328210329210330210331210332210333210334210335210336210337210338210339210340210341210342210343210344210345210346210347210348210349210350210351210352210353210354210355210356210357210358210359210360210361210362210363210364210365210366210367210368210369210370210371210372210373210374210375210376210377210378210379210380210381210382210383210384210385210386210387210388210389210390210391210392210393210394210395210396210397210398210399210400210401210402210403210404210405210406210407210408210409210410210411210412210413210414210415210416210417210418210419210420210421210422210423210424210425210426210427210428210429210430210431210432210433210434210435210436210437210438210439210440210441210442210443210444210445210446210447210448210449210450210451210452210453210454210455210456210457210458210459210460210461210462210463210464210465210466210467210468210469210470210471210472210473210474210475210476210477210478210479210480210481210482210483210484210485210486210487210488210489210490210491210492210493210494210495210496210497210498210499210500210501210502210503210504210505210506210507210508210509210510210511210512210513210514210515210516210517210518210519210520210521210522210523210524210525210526210527210528210529210530210531210532210533210534210535210536210537210538210539210540210541210542210543210544210545210546210547210548210549210550210551210552210553210554210555210556210557210558210559210560210561210562210563210564210565210566210567210568210569210570210571210572210573210574210575210576210577210578210579210580210581210582210583210584210585210586210587210588210589210590210591210592210593210594210595210596210597210598210599210600210601210602210603210604210605210606210607210608210609210610210611210612210613210614210615210616210617210618210619210620210621210622210623210624210625210626210627210628210629210630210631210632210633210634210635210636210637210638210639210640210641210642210643210644210645210646210647210648210649210650210651210652210653210654210655210656210657210658210659210660210661210662210663210664210665210666210667210668210669210670210671210672210673210674210675210676210677210678210679210680210681210682210683210684210685210686210687210688210689210690210691210692210693210694210695210696210697210698210699210700210701210702210703210704210705210706210707210708210709210710210711210712210713210714210715210716210717210718210719210720210721210722210723210724210725210726210727210728210729210730210731210732210733210734210735210736210737210738210739210740210741210742210743210744210745210746210747210748210749210750210751210752210753210754210755210756210757210758210759210760210761210762210763210764210765210766210767210768210769210770210771210772210773210774210775210776210777210778210779210780210781210782210783210784210785210786210787210788210789210790210791210792210793210794210795210796210797210798210799210800210801210802210803210804210805210806210807210808210809210810210811210812210813210814210815210816210817210818210819210820210821210822210823210824210825210826210827210828210829210830210831210832210833210834210835210836210837210838210839210840210841210842210843210844210845210846210847210848210849210850210851210852210853210854210855210856210857210858210859210860210861210862210863210864210865210866210867210868210869210870210871210872210873210874210875210876210877210878210879210880210881210882210883210884210885210886210887210888210889210890210891210892210893210894210895210896210897210898210899210900210901210902210903210904210905210906210907210908210909210910210911210912210913210914210915210916210917210918210919210920210921210922210923210924210925210926210927210928210929210930210931210932210933210934210935210936210937210938210939210940210941210942210943210944210945210946210947210948210949210950210951210952210953210954210955210956210957210958210959210960210961210962210963210964210965210966210967210968210969210970210971210972210973210974210975210976210977210978210979210980210981210982210983210984210985210986210987210988210989210990210991210992210993210994210995210996210997210998210999211000211001211002211003211004211005211006211007211008211009211010211011211012211013211014211015211016211017211018211019211020211021211022211023211024211025211026211027211028211029211030211031211032211033211034211035211036211037211038211039211040211041211042211043211044211045211046211047211048211049211050211051211052211053211054211055211056211057211058211059211060211061211062211063211064211065211066211067211068211069211070211071211072211073211074211075211076211077211078211079211080211081211082211083211084211085211086211087211088211089211090211091211092211093211094211095211096211097211098211099211100211101211102211103211104211105211106211107211108211109211110211111211112211113211114211115211116211117211118211119211120211121211122211123211124211125211126211127211128211129211130211131211132211133211134211135211136211137211138211139211140211141211142211143211144211145211146211147211148211149211150211151211152211153211154211155211156211157211158211159211160211161211162211163211164211165211166211167211168211169211170211171211172211173211174211175211176211177211178211179211180211181211182211183211184211185211186211187211188211189211190211191211192211193211194211195211196211197211198211199211200211201211202211203211204211205211206211207211208211209211210211211211212211213211214211215211216211217211218211219211220211221211222211223211224211225211226211227211228211229211230211231211232211233211234211235211236211237211238211239211240211241211242211243211244211245211246211247211248211249211250211251211252211253211254211255211256211257211258211259211260211261211262211263211264211265211266211267211268211269211270211271211272211273211274211275211276211277211278211279211280211281211282211283211284211285211286211287211288211289211290211291211292211293211294211295211296211297211298211299211300211301211302211303211304211305211306211307211308211309211310211311211312211313211314211315211316211317211318211319211320211321211322211323211324211325211326211327211328211329211330211331211332211333211334211335211336211337211338211339211340211341211342211343211344211345211346211347211348211349211350211351211352211353211354211355211356211357211358211359211360211361211362211363211364211365211366211367211368211369211370211371211372211373211374211375211376211377211378211379211380211381211382211383211384211385211386211387211388211389211390211391211392211393211394211395211396211397211398211399211400211401211402211403211404211405211406211407211408211409211410211411211412211413211414211415211416211417211418211419211420211421211422211423211424211425211426211427211428211429211430211431211432211433211434211435211436211437211438211439211440211441211442211443211444211445211446211447211448211449211450211451211452211453211454211455211456211457211458211459211460211461211462211463211464211465211466211467211468211469211470211471211472211473211474211475211476211477211478211479211480211481211482211483211484211485211486211487211488211489211490211491211492211493211494211495211496211497211498211499211500211501211502211503211504211505211506211507211508211509211510211511211512211513211514211515211516211517211518211519211520211521211522211523211524211525211526211527211528211529211530211531211532211533211534211535211536211537211538211539211540211541211542211543211544211545211546211547211548211549211550211551211552211553211554211555211556211557211558211559211560211561211562211563211564211565211566211567211568211569211570211571211572211573211574211575211576211577211578211579211580211581211582211583211584211585211586211587211588211589211590211591211592211593211594211595211596211597211598211599211600211601211602211603211604211605211606211607211608211609211610211611211612211613211614211615211616211617211618211619211620211621211622211623211624211625211626211627211628211629211630211631211632211633211634211635211636211637211638211639211640211641211642211643211644211645211646211647211648211649211650211651211652211653211654211655211656211657211658211659211660211661211662211663211664211665211666211667211668211669211670211671211672211673211674211675211676211677211678211679211680211681211682211683211684211685211686211687211688211689211690211691211692211693211694211695211696211697211698211699211700211701211702211703211704211705211706211707211708211709211710211711211712211713211714211715211716211717211718211719211720211721211722211723211724211725211726211727211728211729211730211731211732211733211734211735211736211737211738211739211740211741211742211743211744211745211746211747211748211749211750211751211752211753211754211755211756211757211758211759211760211761211762211763211764211765211766211767211768211769211770211771211772211773211774211775211776211777211778211779211780211781211782211783211784211785211786211787211788211789211790211791211792211793211794211795211796211797211798211799211800211801211802211803211804211805211806211807211808211809211810211811211812211813211814211815211816211817211818211819211820211821211822211823211824211825211826211827211828211829211830211831211832211833211834211835211836211837211838211839211840211841211842211843211844211845211846211847211848211849211850211851211852211853211854211855211856211857211858211859211860211861211862211863211864211865211866211867211868211869211870211871211872211873211874211875211876211877211878211879211880211881211882211883211884211885211886211887211888211889211890211891211892211893211894211895211896211897211898211899211900211901211902211903211904211905211906211907211908211909211910211911211912211913211914211915211916211917211918211919211920211921211922211923211924211925211926211927211928211929211930211931211932211933211934211935211936211937211938211939211940211941211942211943211944211945211946211947211948211949211950211951211952211953211954211955211956211957211958211959211960211961211962211963211964211965211966211967211968211969211970211971211972211973211974211975211976211977211978211979211980211981211982211983211984211985211986211987211988211989211990211991211992211993211994211995211996211997211998211999212000212001212002212003212004212005212006212007212008212009212010212011212012212013212014212015212016212017212018212019212020212021212022212023212024212025212026212027212028212029212030212031212032212033212034212035212036212037212038212039212040212041212042212043212044212045212046212047212048212049212050212051212052212053212054212055212056212057212058212059212060212061212062212063212064212065212066212067212068212069212070212071212072212073212074212075212076212077212078212079212080212081212082212083212084212085212086212087212088212089212090212091212092212093212094212095212096212097212098212099212100212101212102212103212104212105212106212107212108212109212110212111212112212113212114212115212116212117212118212119212120212121212122212123212124212125212126212127212128212129212130212131212132212133212134212135212136212137212138212139212140212141212142212143212144212145212146212147212148212149212150212151212152212153212154212155212156212157212158212159212160212161212162212163212164212165212166212167212168212169212170212171212172212173212174212175212176212177212178212179212180212181212182212183212184212185212186212187212188212189212190212191212192212193212194212195212196212197212198212199212200212201212202212203212204212205212206212207212208212209212210212211212212212213212214212215212216212217212218212219212220212221212222212223212224212225212226212227212228212229212230212231212232212233212234212235212236212237212238212239212240212241212242212243212244212245212246212247212248212249212250212251212252212253212254212255212256212257212258212259212260212261212262212263212264212265212266212267212268212269212270212271212272212273212274212275212276212277212278212279212280212281212282212283212284212285212286212287212288212289212290212291212292212293212294212295212296212297212298212299212300212301212302212303212304212305212306212307212308212309212310212311212312212313212314212315212316212317212318212319212320212321212322212323212324212325212326212327212328212329212330212331212332212333212334212335212336212337212338212339212340212341212342212343212344212345212346212347212348212349212350212351212352212353212354212355212356212357212358212359212360212361212362212363212364212365212366212367212368212369212370212371212372212373212374212375212376212377212378212379212380212381212382212383212384212385212386212387212388212389212390212391212392212393212394212395212396212397212398212399212400212401212402212403212404212405212406212407212408212409212410212411212412212413212414212415212416212417212418212419212420212421212422212423212424212425212426212427212428212429212430212431212432212433212434212435212436212437212438212439212440212441212442212443212444212445212446212447212448212449212450212451212452212453212454212455212456212457212458212459212460212461212462212463212464212465212466212467212468212469212470212471212472212473212474212475212476212477212478212479212480212481212482212483212484212485212486212487212488212489212490212491212492212493212494212495212496212497212498212499212500212501212502212503212504212505212506212507212508212509212510212511212512212513212514212515212516212517212518212519212520212521212522212523212524212525212526212527212528212529212530212531212532212533212534212535212536212537212538212539212540212541212542212543212544212545212546212547212548212549212550212551212552212553212554212555212556212557212558212559212560212561212562212563212564212565212566212567212568212569212570212571212572212573212574212575212576212577212578212579212580212581212582212583212584212585212586212587212588212589212590212591212592212593212594212595212596212597212598212599212600212601212602212603212604212605212606212607212608212609212610212611212612212613212614212615212616212617212618212619212620212621212622212623212624212625212626212627212628212629212630212631212632212633212634212635212636212637212638212639212640212641212642212643212644212645212646212647212648212649212650212651212652212653212654212655212656212657212658212659212660212661212662212663212664212665212666212667212668212669212670212671212672212673212674212675212676212677212678212679212680212681212682212683212684212685212686212687212688212689212690212691212692212693212694212695212696212697212698212699212700212701212702212703212704212705212706212707212708212709212710212711212712212713212714212715212716212717212718212719212720212721212722212723212724212725212726212727212728212729212730212731212732212733212734212735212736212737212738212739212740212741212742212743212744212745212746212747212748212749212750212751212752212753212754212755212756212757212758212759212760212761212762212763212764212765212766212767212768212769212770212771212772212773212774212775212776212777212778212779212780212781212782212783212784212785212786212787212788212789212790212791212792212793212794212795212796212797212798212799212800212801212802212803212804212805212806212807212808212809212810212811212812212813212814212815212816212817212818212819212820212821212822212823212824212825212826212827212828212829212830212831212832212833212834212835212836212837212838212839212840212841212842212843212844212845212846212847212848212849212850212851212852212853212854212855212856212857212858212859212860212861212862212863212864212865212866212867212868212869212870212871212872212873212874212875212876212877212878212879212880212881212882212883212884212885212886212887212888212889212890212891212892212893212894212895212896212897212898212899212900212901212902212903212904212905212906212907212908212909212910212911212912212913212914212915212916212917212918212919212920212921212922212923212924212925212926212927212928212929212930212931212932212933212934212935212936212937212938212939212940212941212942212943212944212945212946212947212948212949212950212951212952212953212954212955212956212957212958212959212960212961212962212963212964212965212966212967212968212969212970212971212972212973212974212975212976212977212978212979212980212981212982212983212984212985212986212987212988212989212990212991212992212993212994212995212996212997212998212999213000213001213002213003213004213005213006213007213008213009213010213011213012213013213014213015213016213017213018213019213020213021213022213023213024213025213026213027213028213029213030213031213032213033213034213035213036213037213038213039213040213041213042213043213044213045213046213047213048213049213050213051213052213053213054213055213056213057213058213059213060213061213062213063213064213065213066213067213068213069213070213071213072213073213074213075213076213077213078213079213080213081213082213083213084213085213086213087213088213089213090213091213092213093213094213095213096213097213098213099213100213101213102213103213104213105213106213107213108213109213110213111213112213113213114213115213116213117213118213119213120213121213122213123213124213125213126213127213128213129213130213131213132213133213134213135213136213137213138213139213140213141213142213143213144213145213146213147213148213149213150213151213152213153213154213155213156213157213158213159213160213161213162213163213164213165213166213167213168213169213170213171213172213173213174213175213176213177213178213179213180213181213182213183213184213185213186213187213188213189213190213191213192213193213194213195213196213197213198213199213200213201213202213203213204213205213206213207213208213209213210213211213212213213213214213215213216213217213218213219213220213221213222213223213224213225213226213227213228213229213230213231213232213233213234213235213236213237213238213239213240213241213242213243213244213245213246213247213248213249213250213251213252213253213254213255213256213257213258213259213260213261213262213263213264213265213266213267213268213269213270213271213272213273213274213275213276213277213278213279213280213281213282213283213284213285213286213287213288213289213290213291213292213293213294213295213296213297213298213299213300213301213302213303213304213305213306213307213308213309213310213311213312213313213314213315213316213317213318213319213320213321213322213323213324213325213326213327213328213329213330213331213332213333213334213335213336213337213338213339213340213341213342213343213344213345213346213347213348213349213350213351213352213353213354213355213356213357213358213359213360213361213362213363213364213365213366213367213368213369213370213371213372213373213374213375213376213377213378213379213380213381213382213383213384213385213386213387213388213389213390213391213392213393213394213395213396213397213398213399213400213401213402213403213404213405213406213407213408213409213410213411213412213413213414213415213416213417213418213419213420213421213422213423213424213425213426213427213428213429213430213431213432213433213434213435213436213437213438213439213440213441213442213443213444213445213446213447213448213449213450213451213452213453213454213455213456213457213458213459213460213461213462213463213464213465213466213467213468213469213470213471213472213473213474213475213476213477213478213479213480213481213482213483213484213485213486213487213488213489213490213491213492213493213494213495213496213497213498213499213500213501213502213503213504213505213506213507213508213509213510213511213512213513213514213515213516213517213518213519213520213521213522213523213524213525213526213527213528213529213530213531213532213533213534213535213536213537213538213539213540213541213542213543213544213545213546213547213548213549213550213551213552213553213554213555213556213557213558213559213560213561213562213563213564213565213566213567213568213569213570213571213572213573213574213575213576213577213578213579213580213581213582213583213584213585213586213587213588213589213590213591213592213593213594213595213596213597213598213599213600213601213602213603213604213605213606213607213608213609213610213611213612213613213614213615213616213617213618213619213620213621213622213623213624213625213626213627213628213629213630213631213632213633213634213635213636213637213638213639213640213641213642213643213644213645213646213647213648213649213650213651213652213653213654213655213656213657213658213659213660213661213662213663213664213665213666213667213668213669213670213671213672213673213674213675213676213677213678213679213680213681213682213683213684213685213686213687213688213689213690213691213692213693213694213695213696213697213698213699213700213701213702213703213704213705213706213707213708213709213710213711213712213713213714213715213716213717213718213719213720213721213722213723213724213725213726213727213728213729213730213731213732213733213734213735213736213737213738213739213740213741213742213743213744213745213746213747213748213749213750213751213752213753213754213755213756213757213758213759213760213761213762213763213764213765213766213767213768213769213770213771213772213773213774213775213776213777213778213779213780213781213782213783213784213785213786213787213788213789213790213791213792213793213794213795213796213797213798213799213800213801213802213803213804213805213806213807213808213809213810213811213812213813213814213815213816213817213818213819213820213821213822213823213824213825213826213827213828213829213830213831213832213833213834213835213836213837213838213839213840213841213842213843213844213845213846213847213848213849213850213851213852213853213854213855213856213857213858213859213860213861213862213863213864213865213866213867213868213869213870213871213872213873213874213875213876213877213878213879213880213881213882213883213884213885213886213887213888213889213890213891213892213893213894213895213896213897213898213899213900213901213902213903213904213905213906213907213908213909213910213911213912213913213914213915213916213917213918213919213920213921213922213923213924213925213926213927213928213929213930213931213932213933213934213935213936213937213938213939213940213941213942213943213944213945213946213947213948213949213950213951213952213953213954213955213956213957213958213959213960213961213962213963213964213965213966213967213968213969213970213971213972213973213974213975213976213977213978213979213980213981213982213983213984213985213986213987213988213989213990213991213992213993213994213995213996213997213998213999214000214001214002214003214004214005214006214007214008214009214010214011214012214013214014214015214016214017214018214019214020214021214022214023214024214025214026214027214028214029214030214031214032214033214034214035214036214037214038214039214040214041214042214043214044214045214046214047214048214049214050214051214052214053214054214055214056214057214058214059214060214061214062214063214064214065214066214067214068214069214070214071214072214073214074214075214076214077214078214079214080214081214082214083214084214085214086214087214088214089214090214091214092214093214094214095214096214097214098214099214100214101214102214103214104214105214106214107214108214109214110214111214112214113214114214115214116214117214118214119214120214121214122214123214124214125214126214127214128214129214130214131214132214133214134214135214136214137214138214139214140214141214142214143214144214145214146214147214148214149214150214151214152214153214154214155214156214157214158214159214160214161214162214163214164214165214166214167214168214169214170214171214172214173214174214175214176214177214178214179214180214181214182214183214184214185214186214187214188214189214190214191214192214193214194214195214196214197214198214199214200214201214202214203214204214205214206214207214208214209214210214211214212214213214214214215214216214217214218214219214220214221214222214223214224214225214226214227214228214229214230214231214232214233214234214235214236214237214238214239214240214241214242214243214244214245214246214247214248214249214250214251214252214253214254214255214256214257214258214259214260214261214262214263214264214265214266214267214268214269214270214271214272214273214274214275214276214277214278214279214280214281214282214283214284214285214286214287214288214289214290214291214292214293214294214295214296214297214298214299214300214301214302214303214304214305214306214307214308214309214310214311214312214313214314214315214316214317214318214319214320214321214322214323214324214325214326214327214328214329214330214331214332214333214334214335214336214337214338214339214340214341214342214343214344214345214346214347214348214349214350214351214352214353214354214355214356214357214358214359214360214361214362214363214364214365214366214367214368214369214370214371214372214373214374214375214376214377214378214379214380214381214382214383214384214385214386214387214388214389214390214391214392214393214394214395214396214397214398214399214400214401214402214403214404214405214406214407214408214409214410214411214412214413214414214415214416214417214418214419214420214421214422214423214424214425214426214427214428214429214430214431214432214433214434214435214436214437214438214439214440214441214442214443214444214445214446214447214448214449214450214451214452214453214454214455214456214457214458214459214460214461214462214463214464214465214466214467214468214469214470214471214472214473214474214475214476214477214478214479214480214481214482214483214484214485214486214487214488214489214490214491214492214493214494214495214496214497214498214499214500214501214502214503214504214505214506214507214508214509214510214511214512214513214514214515214516214517214518214519214520214521214522214523214524214525214526214527214528214529214530214531214532214533214534214535214536214537214538214539214540214541214542214543214544214545214546214547214548214549214550214551214552214553214554214555214556214557214558214559214560214561214562214563214564214565214566214567214568214569214570214571214572214573214574214575214576214577214578214579214580214581214582214583214584214585214586214587214588214589214590214591214592214593214594214595214596214597214598214599214600214601214602214603214604214605214606214607214608214609214610214611214612214613214614214615214616214617214618214619214620214621214622214623214624214625214626214627214628214629214630214631214632214633214634214635214636214637214638214639214640214641214642214643214644214645214646214647214648214649214650214651214652214653214654214655214656214657214658214659214660214661214662214663214664214665214666214667214668214669214670214671214672214673214674214675214676214677214678214679214680214681214682214683214684214685214686214687214688214689214690214691214692214693214694214695214696214697214698214699214700214701214702214703214704214705214706214707214708214709214710214711214712214713214714214715214716214717214718214719214720214721214722214723214724214725214726214727214728214729214730214731214732214733214734214735214736214737214738214739214740214741214742214743214744214745214746214747214748214749214750214751214752214753214754214755214756214757214758214759214760214761214762214763214764214765214766214767214768214769214770214771214772214773214774214775214776214777214778214779214780214781214782214783214784214785214786214787214788214789214790214791214792214793214794214795214796214797214798214799214800214801214802214803214804214805214806214807214808214809214810214811214812214813214814214815214816214817214818214819214820214821214822214823214824214825214826214827214828214829214830214831214832214833214834214835214836214837214838214839214840214841214842214843214844214845214846214847214848214849214850214851214852214853214854214855214856214857214858214859214860214861214862214863214864214865214866214867214868214869214870214871214872214873214874214875214876214877214878214879214880214881214882214883214884214885214886214887214888214889214890214891214892214893214894214895214896214897214898214899214900214901214902214903214904214905214906214907214908214909214910214911214912214913214914214915214916214917214918214919214920214921214922214923214924214925214926214927214928214929214930214931214932214933214934214935214936214937214938214939214940214941214942214943214944214945214946214947214948214949214950214951214952214953214954214955214956214957214958214959214960214961214962214963214964214965214966214967214968214969214970214971214972214973214974214975214976214977214978214979214980214981214982214983214984214985214986214987214988214989214990214991214992214993214994214995214996214997214998214999215000215001215002215003215004215005215006215007215008215009215010215011215012215013215014215015215016215017215018215019215020215021215022215023215024215025215026215027215028215029215030215031215032215033215034215035215036215037215038215039215040215041215042215043215044215045215046215047215048215049215050215051215052215053215054215055215056215057215058215059215060215061215062215063215064215065215066215067215068215069215070215071215072215073215074215075215076215077215078215079215080215081215082215083215084215085215086215087215088215089215090215091215092215093215094215095215096215097215098215099215100215101215102215103215104215105215106215107215108215109215110215111215112215113215114215115215116215117215118215119215120215121215122215123215124215125215126215127215128215129215130215131215132215133215134215135215136215137215138215139215140215141215142215143215144215145215146215147215148215149215150215151215152215153215154215155215156215157215158215159215160215161215162215163215164215165215166215167215168215169215170215171215172215173215174215175215176215177215178215179215180215181215182215183215184215185215186215187215188215189215190215191215192215193215194215195215196215197215198215199215200215201215202215203215204215205215206215207215208215209215210215211215212215213215214215215215216215217215218215219215220215221215222215223215224215225215226215227215228215229215230215231215232215233215234215235215236215237215238215239215240215241215242215243215244215245215246215247215248215249215250215251215252215253215254215255215256215257215258215259215260215261215262215263215264215265215266215267215268215269215270215271215272215273215274215275215276215277215278215279215280215281215282215283215284215285215286215287215288215289215290215291215292215293215294215295215296215297215298215299215300215301215302215303215304215305215306215307215308215309215310215311215312215313215314215315215316215317215318215319215320215321215322215323215324215325215326215327215328215329215330215331215332215333215334215335215336215337215338215339215340215341215342215343215344215345215346215347215348215349215350215351215352215353215354215355215356215357215358215359215360215361215362215363215364215365215366215367215368215369215370215371215372215373215374215375215376215377215378215379215380215381215382215383215384215385215386215387215388215389215390215391215392215393215394215395215396215397215398215399215400215401215402215403215404215405215406215407215408215409215410215411215412215413215414215415215416215417215418215419215420215421215422215423215424215425215426215427215428215429215430215431215432215433215434215435215436215437215438215439215440215441215442215443215444215445215446215447215448215449215450215451215452215453215454215455215456215457215458215459215460215461215462215463215464215465215466215467215468215469215470215471215472215473215474215475215476215477215478215479215480215481215482215483215484215485215486215487215488215489215490215491215492215493215494215495215496215497215498215499215500215501215502215503215504215505215506215507215508215509215510215511215512215513215514215515215516215517215518215519215520215521215522215523215524215525215526215527215528215529215530215531215532215533215534215535215536215537215538215539215540215541215542215543215544215545215546215547215548215549215550215551215552215553215554215555215556215557215558215559215560215561215562215563215564215565215566215567215568215569215570215571215572215573215574215575215576215577215578215579215580215581215582215583215584215585215586215587215588215589215590215591215592215593215594215595215596215597215598215599215600215601215602215603215604215605215606215607215608215609215610215611215612215613215614215615215616215617215618215619215620215621215622215623215624215625215626215627215628215629215630215631215632215633215634215635215636215637215638215639215640215641215642215643215644215645215646215647215648215649215650215651215652215653215654215655215656215657215658215659215660215661215662215663215664215665215666215667215668215669215670215671215672215673215674215675215676215677215678215679215680215681215682215683215684215685215686215687215688215689215690215691215692215693215694215695215696215697215698215699215700215701215702215703215704215705215706215707215708215709215710215711215712215713215714215715215716215717215718215719215720215721215722215723215724215725215726215727215728215729215730215731215732215733215734215735215736215737215738215739215740215741215742215743215744215745215746215747215748215749215750215751215752215753215754215755215756215757215758215759215760215761215762215763215764215765215766215767215768215769215770215771215772215773215774215775215776215777215778215779215780215781215782215783215784215785215786215787215788215789215790215791215792215793215794215795215796215797215798215799215800215801215802215803215804215805215806215807215808215809215810215811215812215813215814215815215816215817215818215819215820215821215822215823215824215825215826215827215828215829215830215831215832215833215834215835215836215837215838215839215840215841215842215843215844215845215846215847215848215849215850215851215852215853215854215855215856215857215858215859215860215861215862215863215864215865215866215867215868215869215870215871215872215873215874215875215876215877215878215879215880215881215882215883215884215885215886215887215888215889215890215891215892215893215894215895215896215897215898215899215900215901215902215903215904215905215906215907215908215909215910215911215912215913215914215915215916215917215918215919215920215921215922215923215924215925215926215927215928215929215930215931215932215933215934215935215936215937215938215939215940215941215942215943215944215945215946215947215948215949215950215951215952215953215954215955215956215957215958215959215960215961215962215963215964215965215966215967215968215969215970215971215972215973215974215975215976215977215978215979215980215981215982215983215984215985215986215987215988215989215990215991215992215993215994215995215996215997215998215999216000216001216002216003216004216005216006216007216008216009216010216011216012216013216014216015216016216017216018216019216020216021216022216023216024216025216026216027216028216029216030216031216032216033216034216035216036216037216038216039216040216041216042216043216044216045216046216047216048216049216050216051216052216053216054216055216056216057216058216059216060216061216062216063216064216065216066216067216068216069216070216071216072216073216074216075216076216077216078216079216080216081216082216083216084216085216086216087216088216089216090216091216092216093216094216095216096216097216098216099216100216101216102216103216104216105216106216107216108216109216110216111216112216113216114216115216116216117216118216119216120216121216122216123216124216125216126216127216128216129216130216131216132216133216134216135216136216137216138216139216140216141216142216143216144216145216146216147216148216149216150216151216152216153216154216155216156216157216158216159216160216161216162216163216164216165216166216167216168216169216170216171216172216173216174216175216176216177216178216179216180216181216182216183216184216185216186216187216188216189216190216191216192216193216194216195216196216197216198216199216200216201216202216203216204216205216206216207216208216209216210216211216212216213216214216215216216216217216218216219216220216221216222216223216224216225216226216227216228216229216230216231216232216233216234216235216236216237216238216239216240216241216242216243216244216245216246216247216248216249216250216251216252216253216254216255216256216257216258216259216260216261216262216263216264216265216266216267216268216269216270216271216272216273216274216275216276216277216278216279216280216281216282216283216284216285216286216287216288216289216290216291216292216293216294216295216296216297216298216299216300216301216302216303216304216305216306216307216308216309216310216311216312216313216314216315216316216317216318216319216320216321216322216323216324216325216326216327216328216329216330216331216332216333216334216335216336216337216338216339216340216341216342216343216344216345216346216347216348216349216350216351216352216353216354216355216356216357216358216359216360216361216362216363216364216365216366216367216368216369216370216371216372216373216374216375216376216377216378216379216380216381216382216383216384216385216386216387216388216389216390216391216392216393216394216395216396216397216398216399216400216401216402216403216404216405216406216407216408216409216410216411216412216413216414216415216416216417216418216419216420216421216422216423216424216425216426216427216428216429216430216431216432216433216434216435216436216437216438216439216440216441216442216443216444216445216446216447216448216449216450216451216452216453216454216455216456216457216458216459216460216461216462216463216464216465216466216467216468216469216470216471216472216473216474216475216476216477216478216479216480216481216482216483216484216485216486216487216488216489216490216491216492216493216494216495216496216497216498216499216500216501216502216503216504216505216506216507216508216509216510216511216512216513216514216515216516216517216518216519216520216521216522216523216524216525216526216527216528216529216530216531216532216533216534216535216536216537216538216539216540216541216542216543216544216545216546216547216548216549216550216551216552216553216554216555216556216557216558216559216560216561216562216563216564216565216566216567216568216569216570216571216572216573216574216575216576216577216578216579216580216581216582216583216584216585216586216587216588216589216590216591216592216593216594216595216596216597216598216599216600216601216602216603216604216605216606216607216608216609216610216611216612216613216614216615216616216617216618216619216620216621216622216623216624216625216626216627216628216629216630216631216632216633216634216635216636216637216638216639216640216641216642216643216644216645216646216647216648216649216650216651216652216653216654216655216656216657216658216659216660216661216662216663216664216665216666216667216668216669216670216671216672216673216674216675216676216677216678216679216680216681216682216683216684216685216686216687216688216689216690216691216692216693216694216695216696216697216698216699216700216701216702216703216704216705216706216707216708216709216710216711216712216713216714216715216716216717216718216719216720216721216722216723216724216725216726216727216728216729216730216731216732216733216734216735216736216737216738216739216740216741216742216743216744216745216746216747216748216749216750216751216752216753216754216755216756216757216758216759216760216761216762216763216764216765216766216767216768216769216770216771216772216773216774216775216776216777216778216779216780216781216782216783216784216785216786216787216788216789216790216791216792216793216794216795216796216797216798216799216800216801216802216803216804216805216806216807216808216809216810216811216812216813216814216815216816216817216818216819216820216821216822216823216824216825216826216827216828216829216830216831216832216833216834216835216836216837216838216839216840216841216842216843216844216845216846216847216848216849216850216851216852216853216854216855216856216857216858216859216860216861216862216863216864216865216866216867216868216869216870216871216872216873216874216875216876216877216878216879216880216881216882216883216884216885216886216887216888216889216890216891216892216893216894216895216896216897216898216899216900216901216902216903216904216905216906216907216908216909216910216911216912216913216914216915216916216917216918216919216920216921216922216923216924216925216926216927216928216929216930216931216932216933216934216935216936216937216938216939216940216941216942216943216944216945216946216947216948216949216950216951216952216953216954216955216956216957216958216959216960216961216962216963216964216965216966216967216968216969216970216971216972216973216974216975216976216977216978216979216980216981216982216983216984216985216986216987216988216989216990216991216992216993216994216995216996216997216998216999217000217001217002217003217004217005217006217007217008217009217010217011217012217013217014217015217016217017217018217019217020217021217022217023217024217025217026217027217028217029217030217031217032217033217034217035217036217037217038217039217040217041217042217043217044217045217046217047217048217049217050217051217052217053217054217055217056217057217058217059217060217061217062217063217064217065217066217067217068217069217070217071217072217073217074217075217076217077217078217079217080217081217082217083217084217085217086217087217088217089217090217091217092217093217094217095217096217097217098217099217100217101217102217103217104217105217106217107217108217109217110217111217112217113217114217115217116217117217118217119217120217121217122217123217124217125217126217127217128217129217130217131217132217133217134217135217136217137217138217139217140217141217142217143217144217145217146217147217148217149217150217151217152217153217154217155217156217157217158217159217160217161217162217163217164217165217166217167217168217169217170217171217172217173217174217175217176217177217178217179217180217181217182217183217184217185217186217187217188217189217190217191217192217193217194217195217196217197217198217199217200217201217202217203217204217205217206217207217208217209217210217211217212217213217214217215217216217217217218217219217220217221217222217223217224217225217226217227217228217229217230217231217232217233217234217235217236217237217238217239217240217241217242217243217244217245217246217247217248217249217250217251217252217253217254217255217256217257217258217259217260217261217262217263217264217265217266217267217268217269217270217271217272217273217274217275217276217277217278217279217280217281217282217283217284217285217286217287217288217289217290217291217292217293217294217295217296217297217298217299217300217301217302217303217304217305217306217307217308217309217310217311217312217313217314217315217316217317217318217319217320217321217322217323217324217325217326217327217328217329217330217331217332217333217334217335217336217337217338217339217340217341217342217343217344217345217346217347217348217349217350217351217352217353217354217355217356217357217358217359217360217361217362217363217364217365217366217367217368217369217370217371217372217373217374217375217376217377217378217379217380217381217382217383217384217385217386217387217388217389217390217391217392217393217394217395217396217397217398217399217400217401217402217403217404217405217406217407217408217409217410217411217412217413217414217415217416217417217418217419217420217421217422217423217424217425217426217427217428217429217430217431217432217433217434217435217436217437217438217439217440217441217442217443217444217445217446217447217448217449217450217451217452217453217454217455217456217457217458217459217460217461217462217463217464217465217466217467217468217469217470217471217472217473217474217475217476217477217478217479217480217481217482217483217484217485217486217487217488217489217490217491217492217493217494217495217496217497217498217499217500217501217502217503217504217505217506217507217508217509217510217511217512217513217514217515217516217517217518217519217520217521217522217523217524217525217526217527217528217529217530217531217532217533217534217535217536217537217538217539217540217541217542217543217544217545217546217547217548217549217550217551217552217553217554217555217556217557217558217559217560217561217562217563217564217565217566217567217568217569217570217571217572217573217574217575217576217577217578217579217580217581217582217583217584217585217586217587217588217589217590217591217592217593217594217595217596217597217598217599217600217601217602217603217604217605217606217607217608217609217610217611217612217613217614217615217616217617217618217619217620217621217622217623217624217625217626217627217628217629217630217631217632217633217634217635217636217637217638217639217640217641217642217643217644217645217646217647217648217649217650217651217652217653217654217655217656217657217658217659217660217661217662217663217664217665217666217667217668217669217670217671217672217673217674217675217676217677217678217679217680217681217682217683217684217685217686217687217688217689217690217691217692217693217694217695217696217697217698217699217700217701217702217703217704217705217706217707217708217709217710217711217712217713217714217715217716217717217718217719217720217721217722217723217724217725217726217727217728217729217730217731217732217733217734217735217736217737217738217739217740217741217742217743217744217745217746217747217748217749217750217751217752217753217754217755217756217757217758217759217760217761217762217763217764217765217766217767217768217769217770217771217772217773217774217775217776217777217778217779217780217781217782217783217784217785217786217787217788217789217790217791217792217793217794217795217796217797217798217799217800217801217802217803217804217805217806217807217808217809217810217811217812217813217814217815217816217817217818217819217820217821217822217823217824217825217826217827217828217829217830217831217832217833217834217835217836217837217838217839217840217841217842217843217844217845217846217847217848217849217850217851217852217853217854217855217856217857217858217859217860217861217862217863217864217865217866217867217868217869217870217871217872217873217874217875217876217877217878217879217880217881217882217883217884217885217886217887217888217889217890217891217892217893217894217895217896217897217898217899217900217901217902217903217904217905217906217907217908217909217910217911217912217913217914217915217916217917217918217919217920217921217922217923217924217925217926217927217928217929217930217931217932217933217934217935217936217937217938217939217940217941217942217943217944217945217946217947217948217949217950217951217952217953217954217955217956217957217958217959217960217961217962217963217964217965217966217967217968217969217970217971217972217973217974217975217976217977217978217979217980217981217982217983217984217985217986217987217988217989217990217991217992217993217994217995217996217997217998217999218000218001218002218003218004218005218006218007218008218009218010218011218012218013218014218015218016218017218018218019218020218021218022218023218024218025218026218027218028218029218030218031218032218033218034218035218036218037218038218039218040218041218042218043218044218045218046218047218048218049218050218051218052218053218054218055218056218057218058218059218060218061218062218063218064218065218066218067218068218069218070218071218072218073218074218075218076218077218078218079218080218081218082218083218084218085218086218087218088218089218090218091218092218093218094218095218096218097218098218099218100218101218102218103218104218105218106218107218108218109218110218111218112218113218114218115218116218117218118218119218120218121218122218123218124218125218126218127218128218129218130218131218132218133218134218135218136218137218138218139218140218141218142218143218144218145218146218147218148218149218150218151218152218153218154218155218156218157218158218159218160218161218162218163218164218165218166218167218168218169218170218171218172218173218174218175218176218177218178218179218180218181218182218183218184218185218186218187218188218189218190218191218192218193218194218195218196218197218198218199218200218201218202218203218204218205218206218207218208218209218210218211218212218213218214218215218216218217218218218219218220218221218222218223218224218225218226218227218228218229218230218231218232218233218234218235218236218237218238218239218240218241218242218243218244218245218246218247218248218249218250218251218252218253218254218255218256218257218258218259218260218261218262218263218264218265218266218267218268218269218270218271218272218273218274218275218276218277218278218279218280218281218282218283218284218285218286218287218288218289218290218291218292218293218294218295218296218297218298218299218300218301218302218303218304218305218306218307218308218309218310218311218312218313218314218315218316218317218318218319218320218321218322218323218324218325218326218327218328218329218330218331218332218333218334218335218336218337218338218339218340218341218342218343218344218345218346218347218348218349218350218351218352218353218354218355218356218357218358218359218360218361218362218363218364218365218366218367218368218369218370218371218372218373218374218375218376218377218378218379218380218381218382218383218384218385218386218387218388218389218390218391218392218393218394218395218396218397218398218399218400218401218402218403218404218405218406218407218408218409218410218411218412218413218414218415218416218417218418218419218420218421218422218423218424218425218426218427218428218429218430218431218432218433218434218435218436218437218438218439218440218441218442218443218444218445218446218447218448218449218450218451218452218453218454218455218456218457218458218459218460218461218462218463218464218465218466218467218468218469218470218471218472218473218474218475218476218477218478218479218480218481218482218483218484218485218486218487218488218489218490218491218492218493218494218495218496218497218498218499218500218501218502218503218504218505218506218507218508218509218510218511218512218513218514218515218516218517218518218519218520218521218522218523218524218525218526218527218528218529218530218531218532218533218534218535218536218537218538218539218540218541218542218543218544218545218546218547218548218549218550218551218552218553218554218555218556218557218558218559218560218561218562218563218564218565218566218567218568218569218570218571218572218573218574218575218576218577218578218579218580218581218582218583218584218585218586218587218588218589218590218591218592218593218594218595218596218597218598218599218600218601218602218603218604218605218606218607218608218609218610218611218612218613218614218615218616218617218618218619218620218621218622218623218624218625218626218627218628218629218630218631218632218633218634218635218636218637218638218639218640218641218642218643218644218645218646218647218648218649218650218651218652218653218654218655218656218657218658218659218660218661218662218663218664218665218666218667218668218669218670218671218672218673218674218675218676218677218678218679218680218681218682218683218684218685218686218687218688218689218690218691218692218693218694218695218696218697218698218699218700218701218702218703218704218705218706218707218708218709218710218711218712218713218714218715218716218717218718218719218720218721218722218723218724218725218726218727218728218729218730218731218732218733218734218735218736218737218738218739218740218741218742218743218744218745218746218747218748218749218750218751218752218753218754218755218756218757218758218759218760218761218762218763218764218765218766218767218768218769218770218771218772218773218774218775218776218777218778218779218780218781218782218783218784218785218786218787218788218789218790218791218792218793218794218795218796218797218798218799218800218801218802218803218804218805218806218807218808218809218810218811218812218813218814218815218816218817218818218819218820218821218822218823218824218825218826218827218828218829218830218831218832218833218834218835218836218837218838218839218840218841218842218843218844218845218846218847218848218849218850218851218852218853218854218855218856218857218858218859218860218861218862218863218864218865218866218867218868218869218870218871218872218873218874218875218876218877218878218879218880218881218882218883218884218885218886218887218888218889218890218891218892218893218894218895218896218897218898218899218900218901218902218903218904218905218906218907218908218909218910218911218912218913218914218915218916218917218918218919218920218921218922218923218924218925218926218927218928218929218930218931218932218933218934218935218936218937218938218939218940218941218942218943218944218945218946218947218948218949218950218951218952218953218954218955218956218957218958218959218960218961218962218963218964218965218966218967218968218969218970218971218972218973218974218975218976218977218978218979218980218981218982218983218984218985218986218987218988218989218990218991218992218993218994218995218996218997218998218999219000219001219002219003219004219005219006219007219008219009219010219011219012219013219014219015219016219017219018219019219020219021219022219023219024219025219026219027219028219029219030219031219032219033219034219035219036219037219038219039219040219041219042219043219044219045219046219047219048219049219050219051219052219053219054219055219056219057219058219059219060219061219062219063219064219065219066219067219068219069219070219071219072219073219074219075219076219077219078219079219080219081219082219083219084219085219086219087219088219089219090219091219092219093219094219095219096219097219098219099219100219101219102219103219104219105219106219107219108219109219110219111219112219113219114219115219116219117219118219119219120219121219122219123219124219125219126219127219128219129219130219131219132219133219134219135219136219137219138219139219140219141219142219143219144219145219146219147219148219149219150219151219152219153219154219155219156219157219158219159219160219161219162219163219164219165219166219167219168219169219170219171219172219173219174219175219176219177219178219179219180219181219182219183219184219185219186219187219188219189219190219191219192219193219194219195219196219197219198219199219200219201219202219203219204219205219206219207219208219209219210219211219212219213219214219215219216219217219218219219219220219221219222219223219224219225219226219227219228219229219230219231219232219233219234219235219236219237219238219239219240219241219242219243219244219245219246219247219248219249219250219251219252219253219254219255219256219257219258219259219260219261219262219263219264219265219266219267219268219269219270219271219272219273219274219275219276219277219278219279219280219281219282219283219284219285219286219287219288219289219290219291219292219293219294219295219296219297219298219299219300219301219302219303219304219305219306219307219308219309219310219311219312219313219314219315219316219317219318219319219320219321219322219323219324219325219326219327219328219329219330219331219332219333219334219335219336219337219338219339219340219341219342219343219344219345219346219347219348219349219350219351219352219353219354219355219356219357219358219359219360219361219362219363219364219365219366219367219368219369219370219371219372219373219374219375219376219377219378219379219380219381219382219383219384219385219386219387219388219389219390219391219392219393219394219395219396219397219398219399219400219401219402219403219404219405219406219407219408219409219410219411219412219413219414219415219416219417219418219419219420219421219422219423219424219425219426219427219428219429219430219431219432219433219434219435219436219437219438219439219440219441219442219443219444219445219446219447219448219449219450219451219452219453219454219455219456219457219458219459219460219461219462219463219464219465219466219467219468219469219470219471219472219473219474219475219476219477219478219479219480219481219482219483219484219485219486219487219488219489219490219491219492219493219494219495219496219497219498219499219500219501219502219503219504219505219506219507219508219509219510219511219512219513219514219515219516219517219518219519219520219521219522219523219524219525219526219527219528219529219530219531219532219533219534219535219536219537219538219539219540219541219542219543219544219545219546219547219548219549219550219551219552219553219554219555219556219557219558219559219560219561219562219563219564219565219566219567219568219569219570219571219572219573219574219575219576219577219578219579219580219581219582219583219584219585219586219587219588219589219590219591219592219593219594219595219596219597219598219599219600219601219602219603219604219605219606219607219608219609219610219611219612219613219614219615219616219617219618219619219620219621219622219623219624219625219626219627219628219629219630219631219632219633219634219635219636219637219638219639219640219641219642219643219644219645219646219647219648219649219650219651219652219653219654219655219656219657219658219659219660219661219662219663219664219665219666219667219668219669219670219671219672219673219674219675219676219677219678219679219680219681219682219683219684219685219686219687219688219689219690219691219692219693219694219695219696219697219698219699219700219701219702219703219704219705219706219707219708219709219710219711219712219713219714219715219716219717219718219719219720219721219722219723219724219725219726219727219728219729219730219731219732219733219734219735219736219737219738219739219740219741219742219743219744219745219746219747219748219749219750219751219752219753219754219755219756219757219758219759219760219761219762219763219764219765219766219767219768219769219770219771219772219773219774219775219776219777219778219779219780219781219782219783219784219785219786219787219788219789219790219791219792219793219794219795219796219797219798219799219800219801219802219803219804219805219806219807219808219809219810219811219812219813219814219815219816219817219818219819219820219821219822219823219824219825219826219827219828219829219830219831219832219833219834219835219836219837219838219839219840219841219842219843219844219845219846219847219848219849219850219851219852219853219854219855219856219857219858219859219860219861219862219863219864219865219866219867219868219869219870219871219872219873219874219875219876219877219878219879219880219881219882219883219884219885219886219887219888219889219890219891219892219893219894219895219896219897219898219899219900219901219902219903219904219905219906219907219908219909219910219911219912219913219914219915219916219917219918219919219920219921219922219923219924219925219926219927219928219929219930219931219932219933219934219935219936219937219938219939219940219941219942219943219944219945219946219947219948219949219950219951219952219953219954219955219956219957219958219959219960219961219962219963219964219965219966219967219968219969219970219971219972219973219974219975219976219977219978219979219980219981219982219983219984219985219986219987219988219989219990219991219992219993219994219995219996219997219998219999220000220001220002220003220004220005220006220007220008220009220010220011220012220013220014220015220016220017220018220019220020220021220022220023220024220025220026220027220028220029220030220031220032220033220034220035220036220037220038220039220040220041220042220043220044220045220046220047220048220049220050220051220052220053220054220055220056220057220058220059220060220061220062220063220064220065220066220067220068220069220070220071220072220073220074220075220076220077220078220079220080220081220082220083220084220085220086220087220088220089220090220091220092220093220094220095220096220097220098220099220100220101220102220103220104220105220106220107220108220109220110220111220112220113220114220115220116220117220118220119220120220121220122220123220124220125220126220127220128220129220130220131220132220133220134220135220136220137220138220139220140220141220142220143220144220145220146220147220148220149220150220151220152220153220154220155220156220157220158220159220160220161220162220163220164220165220166220167220168220169220170220171220172220173220174220175220176220177220178220179220180220181220182220183220184220185220186220187220188220189220190220191220192220193220194220195220196220197220198220199220200220201220202220203220204220205220206220207220208220209220210220211220212220213220214220215220216220217220218220219220220220221220222220223220224220225220226220227220228220229220230220231220232220233220234220235220236220237220238220239220240220241220242220243220244220245220246220247220248220249220250220251220252220253220254220255220256220257220258220259220260220261220262220263220264220265220266220267220268220269220270220271220272220273220274220275220276220277220278220279220280220281220282220283220284220285220286220287220288220289220290220291220292220293220294220295220296220297220298220299220300220301220302220303220304220305220306220307220308220309220310220311220312220313220314220315220316220317220318220319220320220321220322220323220324220325220326220327220328220329220330220331220332220333220334220335220336220337220338220339220340220341220342220343220344220345220346220347220348220349220350220351220352220353220354220355220356220357220358220359220360220361220362220363220364220365220366220367220368220369220370220371220372220373220374220375220376220377220378220379220380220381220382220383220384220385220386220387220388220389220390220391220392220393220394220395220396220397220398220399220400220401220402220403220404220405220406220407220408220409220410220411220412220413220414220415220416220417220418220419220420220421220422220423220424220425220426220427220428220429220430220431220432220433220434220435220436220437220438220439220440220441220442220443220444220445220446220447220448220449220450220451220452220453220454220455220456220457220458220459220460220461220462220463220464220465220466220467220468220469220470220471220472220473220474220475220476220477220478220479220480220481220482220483220484220485220486220487220488220489220490220491220492220493220494220495220496220497220498220499220500220501220502220503220504220505220506220507220508220509220510220511220512220513220514220515220516220517220518220519220520220521220522220523220524220525220526220527220528220529220530220531220532220533220534220535220536220537220538220539220540220541220542220543220544220545220546220547220548220549220550220551220552220553220554220555220556220557220558220559220560220561220562220563220564220565220566220567220568220569220570220571220572220573220574220575220576220577220578220579220580220581220582220583220584220585220586220587220588220589220590220591220592220593220594220595220596220597220598220599220600220601220602220603220604220605220606220607220608220609220610220611220612220613220614220615220616220617220618220619220620220621220622220623220624220625220626220627220628220629220630220631220632220633220634220635220636220637220638220639220640220641220642220643220644220645220646220647220648220649220650220651220652220653220654220655220656220657220658220659220660220661220662220663220664220665220666220667220668220669220670220671220672220673220674220675220676220677220678220679220680220681220682220683220684220685220686220687220688220689220690220691220692220693220694220695220696220697220698220699220700220701220702220703220704220705220706220707220708220709220710220711220712220713220714220715220716220717220718220719220720220721220722220723220724220725220726220727220728220729220730220731220732220733220734220735220736220737220738220739220740220741220742220743220744220745220746220747220748220749220750220751220752220753220754220755220756220757220758220759220760220761220762220763220764220765220766220767220768220769220770220771220772220773220774220775220776220777220778220779220780220781220782220783220784220785220786220787220788220789220790220791220792220793220794220795220796220797220798220799220800220801220802220803220804220805220806220807220808220809220810220811220812220813220814220815220816220817220818220819220820220821220822220823220824220825220826220827220828220829220830220831220832220833220834220835220836220837220838220839220840220841220842220843220844220845220846220847220848220849220850220851220852220853220854220855220856220857220858220859220860220861220862220863220864220865220866220867220868220869220870220871220872220873220874220875220876220877220878220879220880220881220882220883220884220885220886220887220888220889220890220891220892220893220894220895220896220897220898220899220900220901220902220903220904220905220906220907220908220909220910220911220912220913220914220915220916220917220918220919220920220921220922220923220924220925220926220927220928220929220930220931220932220933220934220935220936220937220938220939220940220941220942220943220944220945220946220947220948220949220950220951220952220953220954220955220956220957220958220959220960220961220962220963220964220965220966220967220968220969220970220971220972220973220974220975220976220977220978220979220980220981220982220983220984220985220986220987220988220989220990220991220992220993220994220995220996220997220998220999221000221001221002221003221004221005221006221007221008221009221010221011221012221013221014221015221016221017221018221019221020221021221022221023221024221025221026221027221028221029221030221031221032221033221034221035221036221037221038221039221040221041221042221043221044221045221046221047221048221049221050221051221052221053221054221055221056221057221058221059221060221061221062221063221064221065221066221067221068221069221070221071221072221073221074221075221076221077221078221079221080221081221082221083221084221085221086221087221088221089221090221091221092221093221094221095221096221097221098221099221100221101221102221103221104221105221106221107221108221109221110221111221112221113221114221115221116221117221118221119221120221121221122221123221124221125221126221127221128221129221130221131221132221133221134221135221136221137221138221139221140221141221142221143221144221145221146221147221148221149221150221151221152221153221154221155221156221157221158221159221160221161221162221163221164221165221166221167221168221169221170221171221172221173221174221175221176221177221178221179221180221181221182221183221184221185221186221187221188221189221190221191221192221193221194221195221196221197221198221199221200221201221202221203221204221205221206221207221208221209221210221211221212221213221214221215221216221217221218221219221220221221221222221223221224221225221226221227221228221229221230221231221232221233221234221235221236221237221238221239221240221241221242221243221244221245221246221247221248221249221250221251221252221253221254221255221256221257221258221259221260221261221262221263221264221265221266221267221268221269221270221271221272221273221274221275221276221277221278221279221280221281221282221283221284221285221286221287221288221289221290221291221292221293221294221295221296221297221298221299221300221301221302221303221304221305221306221307221308221309221310221311221312221313221314221315221316221317221318221319221320221321221322221323221324221325221326221327221328221329221330221331221332221333221334221335221336221337221338221339221340221341221342221343221344221345221346221347221348221349221350221351221352221353221354221355221356221357221358221359221360221361221362221363221364221365221366221367221368221369221370221371221372221373221374221375221376221377221378221379221380221381221382221383221384221385221386221387221388221389221390221391221392221393221394221395221396221397221398221399221400221401221402221403221404221405221406221407221408221409221410221411221412221413221414221415221416221417221418221419221420221421221422221423221424221425221426221427221428221429221430221431221432221433221434221435221436221437221438221439221440221441221442221443221444221445221446221447221448221449221450221451221452221453221454221455221456221457221458221459221460221461221462221463221464221465221466221467221468221469221470221471221472221473221474221475221476221477221478221479221480221481221482221483221484221485221486221487221488221489221490221491221492221493221494221495221496221497221498221499221500221501221502221503221504221505221506221507221508221509221510221511221512221513221514221515221516221517221518221519221520221521221522221523221524221525221526221527221528221529221530221531221532221533221534221535221536221537221538221539221540221541221542221543221544221545221546221547221548221549221550221551221552221553221554221555221556221557221558221559221560221561221562221563221564221565221566221567221568221569221570221571221572221573221574221575221576221577221578221579221580221581221582221583221584221585221586221587221588221589221590221591221592221593221594221595221596221597221598221599221600221601221602221603221604221605221606221607221608221609221610221611221612221613221614221615221616221617221618221619221620221621221622221623221624221625221626221627221628221629221630221631221632221633221634221635221636221637221638221639221640221641221642221643221644221645221646221647221648221649221650221651221652221653221654221655221656221657221658221659221660221661221662221663221664221665221666221667221668221669221670221671221672221673221674221675221676221677221678221679221680221681221682221683221684221685221686221687221688221689221690221691221692221693221694221695221696221697221698221699221700221701221702221703221704221705221706221707221708221709221710221711221712221713221714221715221716221717221718221719221720221721221722221723221724221725221726221727221728221729221730221731221732221733221734221735221736221737221738221739221740221741221742221743221744221745221746221747221748221749221750221751221752221753221754221755221756221757221758221759221760221761221762221763221764221765221766221767221768221769221770221771221772221773221774221775221776221777221778221779221780221781221782221783221784221785221786221787221788221789221790221791221792221793221794221795221796221797221798221799221800221801221802221803221804221805221806221807221808221809221810221811221812221813221814221815221816221817221818221819221820221821221822221823221824221825221826221827221828221829221830221831221832221833221834221835221836221837221838221839221840221841221842221843221844221845221846221847221848221849221850221851221852221853221854221855221856221857221858221859221860221861221862221863221864221865221866221867221868221869221870221871221872221873221874221875221876221877221878221879221880221881221882221883221884221885221886221887221888221889221890221891221892221893221894221895221896221897221898221899221900221901221902221903221904221905221906221907221908221909221910221911221912221913221914221915221916221917221918221919221920221921221922221923221924221925221926221927221928221929221930221931221932221933221934221935221936221937221938221939221940221941221942221943221944221945221946221947221948221949221950221951221952221953221954221955221956221957221958221959221960221961221962221963221964221965221966221967221968221969221970221971221972221973221974221975221976221977221978221979221980221981221982221983221984221985221986221987221988221989221990221991221992221993221994221995221996221997221998221999222000222001222002222003222004222005222006222007222008222009222010222011222012222013222014222015222016222017222018222019222020222021222022222023222024222025222026222027222028222029222030222031222032222033222034222035222036222037222038222039222040222041222042222043222044222045222046222047222048222049222050222051222052222053222054222055222056222057222058222059222060222061222062222063222064222065222066222067222068222069222070222071222072222073222074222075222076222077222078222079222080222081222082222083222084222085222086222087222088222089222090222091222092222093222094222095222096222097222098222099222100222101222102222103222104222105222106222107222108222109222110222111222112222113222114222115222116222117222118222119222120222121222122222123222124222125222126222127222128222129222130222131222132222133222134222135222136222137222138222139222140222141222142222143222144222145222146222147222148222149222150222151222152222153222154222155222156222157222158222159222160222161222162222163222164222165222166222167222168222169222170222171222172222173222174222175222176222177222178222179222180222181222182222183222184222185222186222187222188222189222190222191222192222193222194222195222196222197222198222199222200222201222202222203222204222205222206222207222208222209222210222211222212222213222214222215222216222217222218222219222220222221222222222223222224222225222226222227222228222229222230222231222232222233222234222235222236222237222238222239222240222241222242222243222244222245222246222247222248222249222250222251222252222253222254222255222256222257222258222259222260222261222262222263222264222265222266222267222268222269222270222271222272222273222274222275222276222277222278222279222280222281222282222283222284222285222286222287222288222289222290222291222292222293222294222295222296222297222298222299222300222301222302222303222304222305222306222307222308222309222310222311222312222313222314222315222316222317222318222319222320222321222322222323222324222325222326222327222328222329222330222331222332222333222334222335222336222337222338222339222340222341222342222343222344222345222346222347222348222349222350222351222352222353222354222355222356222357222358222359222360222361222362222363222364222365222366222367222368222369222370222371222372222373222374222375222376222377222378222379222380222381222382222383222384222385222386222387222388222389222390222391222392222393222394222395222396222397222398222399222400222401222402222403222404222405222406222407222408222409222410222411222412222413222414222415222416222417222418222419222420222421222422222423222424222425222426222427222428222429222430222431222432222433222434222435222436222437222438222439222440222441222442222443222444222445222446222447222448222449222450222451222452222453222454222455222456222457222458222459222460222461222462222463222464222465222466222467222468222469222470222471222472222473222474222475222476222477222478222479222480222481222482222483222484222485222486222487222488222489222490222491222492222493222494222495222496222497222498222499222500222501222502222503222504222505222506222507222508222509222510222511222512222513222514222515222516222517222518222519222520222521222522222523222524222525222526222527222528222529222530222531222532222533222534222535222536222537222538222539222540222541222542222543222544222545222546222547222548222549222550222551222552222553222554222555222556222557222558222559222560222561222562222563222564222565222566222567222568222569222570222571222572222573222574222575222576222577222578222579222580222581222582222583222584222585222586222587222588222589222590222591222592222593222594222595222596222597222598222599222600222601222602222603222604222605222606222607222608222609222610222611222612222613222614222615222616222617222618222619222620222621222622222623222624222625222626222627222628222629222630222631222632222633222634222635222636222637222638222639222640222641222642222643222644222645222646222647222648222649222650222651222652222653222654222655222656222657222658222659222660222661222662222663222664222665222666222667222668222669222670222671222672222673222674222675222676222677222678222679222680222681222682222683222684222685222686222687222688222689222690222691222692222693222694222695222696222697222698222699222700222701222702222703222704222705222706222707222708222709222710222711222712222713222714222715222716222717222718222719222720222721222722222723222724222725222726222727222728222729222730222731222732222733222734222735222736222737222738222739222740222741222742222743222744222745222746222747222748222749222750222751222752222753222754222755222756222757222758222759222760222761222762222763222764222765222766222767222768222769222770222771222772222773222774222775222776222777222778222779222780222781222782222783222784222785222786222787222788222789222790222791222792222793222794222795222796222797222798222799222800222801222802222803222804222805222806222807222808222809222810222811222812222813222814222815222816222817222818222819222820222821222822222823222824222825222826222827222828222829222830222831222832222833222834222835222836222837222838222839222840222841222842222843222844222845222846222847222848222849222850222851222852222853222854222855222856222857222858222859222860222861222862222863222864222865222866222867222868222869222870222871222872222873222874222875222876222877222878222879222880222881222882222883222884222885222886222887222888222889222890222891222892222893222894222895222896222897222898222899222900222901222902222903222904222905222906222907222908222909222910222911222912222913222914222915222916222917222918222919222920222921222922222923222924222925222926222927222928222929222930222931222932222933222934222935222936222937222938222939222940222941222942222943222944222945222946222947222948222949222950222951222952222953222954222955222956222957222958222959222960222961222962222963222964222965222966222967222968222969222970222971222972222973222974222975222976222977222978222979222980222981222982222983222984222985222986222987222988222989222990222991222992222993222994222995222996222997222998222999223000223001223002223003223004223005223006223007223008223009223010223011223012223013223014223015223016223017223018223019223020223021223022223023223024223025223026223027223028223029223030223031223032223033223034223035223036223037223038223039223040223041223042223043223044223045223046223047223048223049223050223051223052223053223054223055223056223057223058223059223060223061223062223063223064223065223066223067223068223069223070223071223072223073223074223075223076223077223078223079223080223081223082223083223084223085223086223087223088223089223090223091223092223093223094223095223096223097223098223099223100223101223102223103223104223105223106223107223108223109223110223111223112223113223114223115223116223117223118223119223120223121223122223123223124223125223126223127223128223129223130223131223132223133223134223135223136223137223138223139223140223141223142223143223144223145223146223147223148223149223150223151223152223153223154223155223156223157223158223159223160223161223162223163223164223165223166223167223168223169223170223171223172223173223174223175223176223177223178223179223180223181223182223183223184223185223186223187223188223189223190223191223192223193223194223195223196223197223198223199223200223201223202223203223204223205223206223207223208223209223210223211223212223213223214223215223216223217223218223219223220223221223222223223223224223225223226223227223228223229223230223231223232223233223234223235223236223237223238223239223240223241223242223243223244223245223246223247223248223249223250223251223252223253223254223255223256223257223258223259223260223261223262223263223264223265223266223267223268223269223270223271223272223273223274223275223276223277223278223279223280223281223282223283223284223285223286223287223288223289223290223291223292223293223294223295223296223297223298223299223300223301223302223303223304223305223306223307223308223309223310223311223312223313223314223315223316223317223318223319223320223321223322223323223324223325223326223327223328223329223330223331223332223333223334223335223336223337223338223339223340223341223342223343223344223345223346223347223348223349223350223351223352223353223354223355223356223357223358223359223360223361223362223363223364223365223366223367223368223369223370223371223372223373223374223375223376223377223378223379223380223381223382223383223384223385223386223387223388223389223390223391223392223393223394223395223396223397223398223399223400223401223402223403223404223405223406223407223408223409223410223411223412223413223414223415223416223417223418223419223420223421223422223423223424223425223426223427223428223429223430223431223432223433223434223435223436223437223438223439223440223441223442223443223444223445223446223447223448223449223450223451223452223453223454223455223456223457223458223459223460223461223462223463223464223465223466223467223468223469223470223471223472223473223474223475223476223477223478223479223480223481223482223483223484223485223486223487223488223489223490223491223492223493223494223495223496223497223498223499223500223501223502223503223504223505223506223507223508223509223510223511223512223513223514223515223516223517223518223519223520223521223522223523223524223525223526223527223528223529223530223531223532223533223534223535223536223537223538223539223540223541223542223543223544223545223546223547223548223549223550223551223552223553223554223555223556223557223558223559223560223561223562223563223564223565223566223567223568223569223570223571223572223573223574223575223576223577223578223579223580223581223582223583223584223585223586223587223588223589223590223591223592223593223594223595223596223597223598223599223600223601223602223603223604223605223606223607223608223609223610223611223612223613223614223615223616223617223618223619223620223621223622223623223624223625223626223627223628223629223630223631223632223633223634223635223636223637223638223639223640223641223642223643223644223645223646223647223648223649223650223651223652223653223654223655223656223657223658223659223660223661223662223663223664223665223666223667223668223669223670223671223672223673223674223675223676223677223678223679223680223681223682223683223684223685223686223687223688223689223690223691223692223693223694223695223696223697223698223699223700223701223702223703223704223705223706223707223708223709223710223711223712223713223714223715223716223717223718223719223720223721223722223723223724223725223726223727223728223729223730223731223732223733223734223735223736223737223738223739223740223741223742223743223744223745223746223747223748223749223750223751223752223753223754223755223756223757223758223759223760223761223762223763223764223765223766223767223768223769223770223771223772223773223774223775223776223777223778223779223780223781223782223783223784223785223786223787223788223789223790223791223792223793223794223795223796223797223798223799223800223801223802223803223804223805223806223807223808223809223810223811223812223813223814223815223816223817223818223819223820223821223822223823223824223825223826223827223828223829223830223831223832223833223834223835223836223837223838223839223840223841223842223843223844223845223846223847223848223849223850223851223852223853223854223855223856223857223858223859223860223861223862223863223864223865223866223867223868223869223870223871223872223873223874223875223876223877223878223879223880223881223882223883223884223885223886223887223888223889223890223891223892223893223894223895223896223897223898223899223900223901223902223903223904223905223906223907223908223909223910223911223912223913223914223915223916223917223918223919223920223921223922223923223924223925223926223927223928223929223930223931223932223933223934223935223936223937223938223939223940223941223942223943223944223945223946223947223948223949223950223951223952223953223954223955223956223957223958223959223960223961223962223963223964223965223966223967223968223969223970223971223972223973223974223975223976223977223978223979223980223981223982223983223984223985223986223987223988223989223990223991223992223993223994223995223996223997223998223999224000224001224002224003224004224005224006224007224008224009224010224011224012224013224014224015224016224017224018224019224020224021224022224023224024224025224026224027224028224029224030224031224032224033224034224035224036224037224038224039224040224041224042224043224044224045224046224047224048224049224050224051224052224053224054224055224056224057224058224059224060224061224062224063224064224065224066224067224068224069224070224071224072224073224074224075224076224077224078224079224080224081224082224083224084224085224086224087224088224089224090224091224092224093224094224095224096224097224098224099224100224101224102224103224104224105224106224107224108224109224110224111224112224113224114224115224116224117224118224119224120224121224122224123224124224125224126224127224128224129224130224131224132224133224134224135224136224137224138224139224140224141224142224143224144224145224146224147224148224149224150224151224152224153224154224155224156224157224158224159224160224161224162224163224164224165224166224167224168224169224170224171224172224173224174224175224176224177224178224179224180224181224182224183224184224185224186224187224188224189224190224191224192224193224194224195224196224197224198224199224200224201224202224203224204224205224206224207224208224209224210224211224212224213224214224215224216224217224218224219224220224221224222224223224224224225224226224227224228224229224230224231224232224233224234224235224236224237224238224239224240224241224242224243224244224245224246224247224248224249224250224251224252224253224254224255224256224257224258224259224260224261224262224263224264224265224266224267224268224269224270224271224272224273224274224275224276224277224278224279224280224281224282224283224284224285224286224287224288224289224290224291224292224293224294224295224296224297224298224299224300224301224302224303224304224305224306224307224308224309224310224311224312224313224314224315224316224317224318224319224320224321224322224323224324224325224326224327224328224329224330224331224332224333224334224335224336224337224338224339224340224341224342224343224344224345224346224347224348224349224350224351224352224353224354224355224356224357224358224359224360224361224362224363224364224365224366224367224368224369224370224371224372224373224374224375224376224377224378224379224380224381224382224383224384224385224386224387224388224389224390224391224392224393224394224395224396224397224398224399224400224401224402224403224404224405224406224407224408224409224410224411224412224413224414224415224416224417224418224419224420224421224422224423224424224425224426224427224428224429224430224431224432224433224434224435224436224437224438224439224440224441224442224443224444224445224446224447224448224449224450224451224452224453224454224455224456224457224458224459224460224461224462224463224464224465224466224467224468224469224470224471224472224473224474224475224476224477224478224479224480224481224482224483224484224485224486224487224488224489224490224491224492224493224494224495224496224497224498224499224500224501224502224503224504224505224506224507224508224509224510224511224512224513224514224515224516224517224518224519224520224521224522224523224524224525224526224527224528224529224530224531224532224533224534224535224536224537224538224539224540224541224542224543224544224545224546224547224548224549224550224551224552224553224554224555224556224557224558224559224560224561224562224563224564224565224566224567224568224569224570224571224572224573224574224575224576224577224578224579224580224581224582224583224584224585224586224587224588224589224590224591224592224593224594224595224596224597224598224599224600224601224602224603224604224605224606224607224608224609224610224611224612224613224614224615224616224617224618224619224620224621224622224623224624224625224626224627224628224629224630224631224632224633224634224635224636224637224638224639224640224641224642224643224644224645224646224647224648224649224650224651224652224653224654224655224656224657224658224659224660224661224662224663224664224665224666224667224668224669224670224671224672224673224674224675224676224677224678224679224680224681224682224683224684224685224686224687224688224689224690224691224692224693224694224695224696224697224698224699224700224701224702224703224704224705224706224707224708224709224710224711224712224713224714224715224716224717224718224719224720224721224722224723224724224725224726224727224728224729224730224731224732224733224734224735224736224737224738224739224740224741224742224743224744224745224746224747224748224749224750224751224752224753224754224755224756224757224758224759224760224761224762224763224764224765224766224767224768224769224770224771224772224773224774224775224776224777224778224779224780224781224782224783224784224785224786224787224788224789224790224791224792224793224794224795224796224797224798224799224800224801224802224803224804224805224806224807224808224809224810224811224812224813224814224815224816224817224818224819224820224821224822224823224824224825224826224827224828224829224830224831224832224833224834224835224836224837224838224839224840224841224842224843224844224845224846224847224848224849224850224851224852224853224854224855224856224857224858224859224860224861224862224863224864224865224866224867224868224869224870224871224872224873224874224875224876224877224878224879224880224881224882224883224884224885224886224887224888224889224890224891224892224893224894224895224896224897224898224899224900224901224902224903224904224905224906224907224908224909224910224911224912224913224914224915224916224917224918224919224920224921224922224923224924224925224926224927224928224929224930224931224932224933224934224935224936224937224938224939224940224941224942224943224944224945224946224947224948224949224950224951224952224953224954224955224956224957224958224959224960224961224962224963224964224965224966224967224968224969224970224971224972224973224974224975224976224977224978224979224980224981224982224983224984224985224986224987224988224989224990224991224992224993224994224995224996224997224998224999225000225001225002225003225004225005225006225007225008225009225010225011225012225013225014225015225016225017225018225019225020225021225022225023225024225025225026225027225028225029225030225031225032225033225034225035225036225037225038225039225040225041225042225043225044225045225046225047225048225049225050225051225052225053225054225055225056225057225058225059225060225061225062225063225064225065225066225067225068225069225070225071225072225073225074225075225076225077225078225079225080225081225082225083225084225085225086225087225088225089225090225091225092225093225094225095225096225097225098225099225100225101225102225103225104225105225106225107225108225109225110225111225112225113225114225115225116225117225118225119225120225121225122225123225124225125225126225127225128225129225130225131225132225133225134225135225136225137225138225139225140225141225142225143225144225145225146225147225148225149225150225151225152225153225154225155225156225157225158225159225160225161225162225163225164225165225166225167225168225169225170225171225172225173225174225175225176225177225178225179225180225181225182225183225184225185225186225187225188225189225190225191225192225193225194225195225196225197225198225199225200225201225202225203225204225205225206225207225208225209225210225211225212225213225214225215225216225217225218225219225220225221225222225223225224225225225226225227225228225229225230225231225232225233225234225235225236225237225238225239225240225241225242225243225244225245225246225247225248225249225250225251225252225253225254225255225256225257225258225259225260225261225262225263225264225265225266225267225268225269225270225271225272225273225274225275225276225277225278225279225280225281225282225283225284225285225286225287225288225289225290225291225292225293225294225295225296225297225298225299225300225301225302225303225304225305225306225307225308225309225310225311225312225313225314225315225316225317225318225319225320225321225322225323225324225325225326225327225328225329225330225331225332225333225334225335225336225337225338225339225340225341225342225343225344225345225346225347225348225349225350225351225352225353225354225355225356225357225358225359225360225361225362225363225364225365225366225367225368225369225370225371225372225373225374225375225376225377225378225379225380225381225382225383225384225385225386225387225388225389225390225391225392225393225394225395225396225397225398225399225400225401225402225403225404225405225406225407225408225409225410225411225412225413225414225415225416225417225418225419225420225421225422225423225424225425225426225427225428225429225430225431225432225433225434225435225436225437225438225439225440225441225442225443225444225445225446225447225448225449225450225451225452225453225454225455225456225457225458225459225460225461225462225463225464225465225466225467225468225469225470225471225472225473225474225475225476225477225478225479225480225481225482225483225484225485225486225487225488225489225490225491225492225493225494225495225496225497225498225499225500225501225502225503225504225505225506225507225508225509225510225511225512225513225514225515225516225517225518225519225520225521225522225523225524225525225526225527225528225529225530225531225532225533225534225535225536225537225538225539225540225541225542225543225544225545225546225547225548225549225550225551225552225553225554225555225556225557225558225559225560225561225562225563225564225565225566225567225568225569225570225571225572225573225574225575225576225577225578225579225580225581225582225583225584225585225586225587225588225589225590225591225592225593225594225595225596225597225598225599225600225601225602225603225604225605225606225607225608225609225610225611225612225613225614225615225616225617225618225619225620225621225622225623225624225625225626225627225628225629225630225631225632225633225634225635225636225637225638225639225640225641225642225643225644225645225646225647225648225649225650225651225652225653225654225655225656225657225658225659225660225661225662225663225664225665225666225667225668225669225670225671225672225673225674225675225676225677225678225679225680225681225682225683225684225685225686225687225688225689225690225691225692225693225694225695225696225697225698225699225700225701225702225703225704225705225706225707225708225709225710225711225712225713225714225715225716225717225718225719225720225721225722225723225724225725225726225727225728225729225730225731225732225733225734225735225736225737225738225739225740225741225742225743225744225745225746225747225748225749225750225751225752225753225754225755225756225757225758225759225760225761225762225763225764225765225766225767225768225769225770225771225772225773225774225775225776225777225778225779225780225781225782225783225784225785225786225787225788225789225790225791225792225793225794225795225796225797225798225799225800225801225802225803225804225805225806225807225808225809225810225811225812225813225814225815225816225817225818225819225820225821225822225823225824225825225826225827225828225829225830225831225832225833225834225835225836225837225838225839225840225841225842225843225844225845225846225847225848225849225850225851225852225853225854225855225856225857225858225859225860225861225862225863225864225865225866225867225868225869225870225871225872225873225874225875225876225877225878225879225880225881225882225883225884225885225886225887225888225889225890225891225892225893225894225895225896225897225898225899225900225901225902225903225904225905225906225907225908225909225910225911225912225913225914225915225916225917225918225919225920225921225922225923225924225925225926225927225928225929225930225931225932225933225934225935225936225937225938225939225940225941225942225943225944225945225946225947225948225949225950225951225952225953225954225955225956225957225958225959225960225961225962225963225964225965225966225967225968225969225970225971225972225973225974225975225976225977225978225979225980225981225982225983225984225985225986225987225988225989225990225991225992225993225994225995225996225997225998225999226000226001226002226003226004226005226006226007226008226009226010226011226012226013226014226015226016226017226018226019226020226021226022226023226024226025226026226027226028226029226030226031226032226033226034226035226036226037226038226039226040226041226042226043226044226045226046226047226048226049226050226051226052226053226054226055226056226057226058226059226060226061226062226063226064226065226066226067226068226069226070226071226072226073226074226075226076226077226078226079226080226081226082226083226084226085226086226087226088226089226090226091226092226093226094226095226096226097226098226099226100226101226102226103226104226105226106226107226108226109226110226111226112226113226114226115226116226117226118226119226120226121226122226123226124226125226126226127226128226129226130226131226132226133226134226135226136226137226138226139226140226141226142226143226144226145226146226147226148226149226150226151226152226153226154226155226156226157226158226159226160226161226162226163226164226165226166226167226168226169226170226171226172226173226174226175226176226177226178226179226180226181226182226183226184226185226186226187226188226189226190226191226192226193226194226195226196226197226198226199226200226201226202226203226204226205226206226207226208226209226210226211226212226213226214226215226216226217226218226219226220226221226222226223226224226225226226226227226228226229226230226231226232226233226234226235226236226237226238226239226240226241226242226243226244226245226246226247226248226249226250226251226252226253226254226255226256226257226258226259226260226261226262226263226264226265226266226267226268226269226270226271226272226273226274226275226276226277226278226279226280226281226282226283226284226285226286226287226288226289226290226291226292226293226294226295226296226297226298226299226300226301226302226303226304226305226306226307226308226309226310226311226312226313226314226315226316226317226318226319226320226321226322226323226324226325226326226327226328226329226330226331226332226333226334226335226336226337226338226339226340226341226342226343226344226345226346226347226348226349226350226351226352226353226354226355226356226357226358226359226360226361226362226363226364226365226366226367226368226369226370226371226372226373226374226375226376226377226378226379226380226381226382226383226384226385226386226387226388226389226390226391226392226393226394226395226396226397226398226399226400226401226402226403226404226405226406226407226408226409226410226411226412226413226414226415226416226417226418226419226420226421226422226423226424226425226426226427226428226429226430226431226432226433226434226435226436226437226438226439226440226441226442226443226444226445226446226447226448226449226450226451226452226453226454226455226456226457226458226459226460226461226462226463226464226465226466226467226468226469226470226471226472226473226474226475226476226477226478226479226480226481226482226483226484226485226486226487226488226489226490226491226492226493226494226495226496226497226498226499226500226501226502226503226504226505226506226507226508226509226510226511226512226513226514226515226516226517226518226519226520226521226522226523226524226525226526226527226528226529226530226531226532226533226534226535226536226537226538226539226540226541226542226543226544226545226546226547226548226549226550226551226552226553226554226555226556226557226558226559226560226561226562226563226564226565226566226567226568226569226570226571226572226573226574226575226576226577226578226579226580226581226582226583226584226585226586226587226588226589226590226591226592226593226594226595226596226597226598226599226600226601226602226603226604226605226606226607226608226609226610226611226612226613226614226615226616226617226618226619226620226621226622226623226624226625226626226627226628226629226630226631226632226633226634226635226636226637226638226639226640226641226642226643226644226645226646226647226648226649226650226651226652226653226654226655226656226657226658226659226660226661226662226663226664226665226666226667226668226669226670226671226672226673226674226675226676226677226678226679226680226681226682226683226684226685226686226687226688226689226690226691226692226693226694226695226696226697226698226699226700226701226702226703226704226705226706226707226708226709226710226711226712226713226714226715226716226717226718226719226720226721226722226723226724226725226726226727226728226729226730226731226732226733226734226735226736226737226738226739226740226741226742226743226744226745226746226747226748226749226750226751226752226753226754226755226756226757226758226759226760226761226762226763226764226765226766226767226768226769226770226771226772226773226774226775226776226777226778226779226780226781226782226783226784226785226786226787226788226789226790226791226792226793226794226795226796226797226798226799226800226801226802226803226804226805226806226807226808226809226810226811226812226813226814226815226816226817226818226819226820226821226822226823226824226825226826226827226828226829226830226831226832226833226834226835226836226837226838226839226840226841226842226843226844226845226846226847226848226849226850226851226852226853226854226855226856226857226858226859226860226861226862226863226864226865226866226867226868226869226870226871226872226873226874226875226876226877226878226879226880226881226882226883226884226885226886226887226888226889226890226891226892226893226894226895226896226897226898226899226900226901226902226903226904226905226906226907226908226909226910226911226912226913226914226915226916226917226918226919226920226921226922226923226924226925226926226927226928226929226930226931226932226933226934226935226936226937226938226939226940226941226942226943226944226945226946226947226948226949226950226951226952226953226954226955226956226957226958226959226960226961226962226963226964226965226966226967226968226969226970226971226972226973226974226975226976226977226978226979226980226981226982226983226984226985226986226987226988226989226990226991226992226993226994226995226996226997226998226999227000227001227002227003227004227005227006227007227008227009227010227011227012227013227014227015227016227017227018227019227020227021227022227023227024227025227026227027227028227029227030227031227032227033227034227035227036227037227038227039227040227041227042227043227044227045227046227047227048227049227050227051227052227053227054227055227056227057227058227059227060227061227062227063227064227065227066227067227068227069227070227071227072227073227074227075227076227077227078227079227080227081227082227083227084227085227086227087227088227089227090227091227092227093227094227095227096227097227098227099227100227101227102227103227104227105227106227107227108227109227110227111227112227113227114227115227116227117227118227119227120227121227122227123227124227125227126227127227128227129227130227131227132227133227134227135227136227137227138227139227140227141227142227143227144227145227146227147227148227149227150227151227152227153227154227155227156227157227158227159227160227161227162227163227164227165227166227167227168227169227170227171227172227173227174227175227176227177227178227179227180227181227182227183227184227185227186227187227188227189227190227191227192227193227194227195227196227197227198227199227200227201227202227203227204227205227206227207227208227209227210227211227212227213227214227215227216227217227218227219227220227221227222227223227224227225227226227227227228227229227230227231227232227233227234227235227236227237227238227239227240227241227242227243227244227245227246227247227248227249227250227251227252227253227254227255227256227257227258227259227260227261227262227263227264227265227266227267227268227269227270227271227272227273227274227275227276227277227278227279227280227281227282227283227284227285227286227287227288227289227290227291227292227293227294227295227296227297227298227299227300227301227302227303227304227305227306227307227308227309227310227311227312227313227314227315227316227317227318227319227320227321227322227323227324227325227326227327227328227329227330227331227332227333227334227335227336227337227338227339227340227341227342227343227344227345227346227347227348227349227350227351227352227353227354227355227356227357227358227359227360227361227362227363227364227365227366227367227368227369227370227371227372227373227374227375227376227377227378227379227380227381227382227383227384227385227386227387227388227389227390227391227392227393227394227395227396227397227398227399227400227401227402227403227404227405227406227407227408227409227410227411227412227413227414227415227416227417227418227419227420227421227422227423227424227425227426227427227428227429227430227431227432227433227434227435227436227437227438227439227440227441227442227443227444227445227446227447227448227449227450227451227452227453227454227455227456227457227458227459227460227461227462227463227464227465227466227467227468227469227470227471227472227473227474227475227476227477227478227479227480227481227482227483227484227485227486227487227488227489227490227491227492227493227494227495227496227497227498227499227500227501227502227503227504227505227506227507227508227509227510227511227512227513227514227515227516227517227518227519227520227521227522227523227524227525227526227527227528227529227530227531227532227533227534227535227536227537227538227539227540227541227542227543227544227545227546227547227548227549227550227551227552227553227554227555227556227557227558227559227560227561227562227563227564227565227566227567227568227569227570227571227572227573227574227575227576227577227578227579227580227581227582227583227584227585227586227587227588227589227590227591227592227593227594227595227596227597227598227599227600227601227602227603227604227605227606227607227608227609227610227611227612227613227614227615227616227617227618227619227620227621227622227623227624227625227626227627227628227629227630227631227632227633227634227635227636227637227638227639227640227641227642227643227644227645227646227647227648227649227650227651227652227653227654227655227656227657227658227659227660227661227662227663227664227665227666227667227668227669227670227671227672227673227674227675227676227677227678227679227680227681227682227683227684227685227686227687227688227689227690227691227692227693227694227695227696227697227698227699227700227701227702227703227704227705227706227707227708227709227710227711227712227713227714227715227716227717227718227719227720227721227722227723227724227725227726227727227728227729227730227731227732227733227734227735227736227737227738227739227740227741227742227743227744227745227746227747227748227749227750227751227752227753227754227755227756227757227758227759227760227761227762227763227764227765227766227767227768227769227770227771227772227773227774227775227776227777227778227779227780227781227782227783227784227785227786227787227788227789227790227791227792227793227794227795227796227797227798227799227800227801227802227803227804227805227806227807227808227809227810227811227812227813227814227815227816227817227818227819227820227821227822227823227824227825227826227827227828227829227830227831227832227833227834227835227836227837227838227839227840227841227842227843227844227845227846227847227848227849227850227851227852227853227854227855227856227857227858227859227860227861227862227863227864227865227866227867227868227869227870227871227872227873227874227875227876227877227878227879227880227881227882227883227884227885227886227887227888227889227890227891227892227893227894227895227896227897227898227899227900227901227902227903227904227905227906227907227908227909227910227911227912227913227914227915227916227917227918227919227920227921227922227923227924227925227926227927227928227929227930227931227932227933227934227935227936227937227938227939227940227941227942227943227944227945227946227947227948227949227950227951227952227953227954227955227956227957227958227959227960227961227962227963227964227965227966227967227968227969227970227971227972227973227974227975227976227977227978227979227980227981227982227983227984227985227986227987227988227989227990227991227992227993227994227995227996227997227998227999228000228001228002228003228004228005228006228007228008228009228010228011228012228013228014228015228016228017228018228019228020228021228022228023228024228025228026228027228028228029228030228031228032228033228034228035228036228037228038228039228040228041228042228043228044228045228046228047228048228049228050228051228052228053228054228055228056228057228058228059228060228061228062228063228064228065228066228067228068228069228070228071228072228073228074228075228076228077228078228079228080228081228082228083228084228085228086228087228088228089228090228091228092228093228094228095228096228097228098228099228100228101228102228103228104228105228106228107228108228109228110228111228112228113228114228115228116228117228118228119228120228121228122228123228124228125228126228127228128228129228130228131228132228133228134228135228136228137228138228139228140228141228142228143228144228145228146228147228148228149228150228151228152228153228154228155228156228157228158228159228160228161228162228163228164228165228166228167228168228169228170228171228172228173228174228175228176228177228178228179228180228181228182228183228184228185228186228187228188228189228190228191228192228193228194228195228196228197228198228199228200228201228202228203228204228205228206228207228208228209228210228211228212228213228214228215228216228217228218228219228220228221228222228223228224228225228226228227228228228229228230228231228232228233228234228235228236228237228238228239228240228241228242228243228244228245228246228247228248228249228250228251228252228253228254228255228256228257228258228259228260228261228262228263228264228265228266228267228268228269228270228271228272228273228274228275228276228277228278228279228280228281228282228283228284228285228286228287228288228289228290228291228292228293228294228295228296228297228298228299228300228301228302228303228304228305228306228307228308228309228310228311228312228313228314228315228316228317228318228319228320228321228322228323228324228325228326228327228328228329228330228331228332228333228334228335228336228337228338228339228340228341228342228343228344228345228346228347228348228349228350228351228352228353228354228355228356228357228358228359228360228361228362228363228364228365228366228367228368228369228370228371228372228373228374228375228376228377228378228379228380228381228382228383228384228385228386228387228388228389228390228391228392228393228394228395228396228397228398228399228400228401228402228403228404228405228406228407228408228409228410228411228412228413228414228415228416228417228418228419228420228421228422228423228424228425228426228427228428228429228430228431228432228433228434228435228436228437228438228439228440228441228442228443228444228445228446228447228448228449228450228451228452228453228454228455228456228457228458228459228460228461228462228463228464228465228466228467228468228469228470228471228472228473228474228475228476228477228478228479228480228481228482228483228484228485228486228487228488228489228490228491228492228493228494228495228496228497228498228499228500228501228502228503228504228505228506228507228508228509228510228511228512228513228514228515228516228517228518228519228520228521228522228523228524228525228526228527228528228529228530228531228532228533228534228535228536228537228538228539228540228541228542228543228544228545228546228547228548228549228550228551228552228553228554228555228556228557228558228559228560228561228562228563228564228565228566228567228568228569228570228571228572228573228574228575228576228577228578228579228580228581228582228583228584228585228586228587228588228589228590228591228592228593228594228595228596228597228598228599228600228601228602228603228604228605228606228607228608228609228610228611228612228613228614228615228616228617228618228619228620228621228622228623228624228625228626228627228628228629228630228631228632228633228634228635228636228637228638228639228640228641228642228643228644228645228646228647228648228649228650228651228652228653228654228655228656228657228658228659228660228661228662228663228664228665228666228667228668228669228670228671228672228673228674228675228676228677228678228679228680228681228682228683228684228685228686228687228688228689228690228691228692228693228694228695228696228697228698228699228700228701228702228703228704228705228706228707228708228709228710228711228712228713228714228715228716228717228718228719228720228721228722228723228724228725228726228727228728228729228730228731228732228733228734228735228736228737228738228739228740228741228742228743228744228745228746228747228748228749228750228751228752228753228754228755228756228757228758228759228760228761228762228763228764228765228766228767228768228769228770228771228772228773228774228775228776228777228778228779228780228781228782228783228784228785228786228787228788228789228790228791228792228793228794228795228796228797228798228799228800228801228802228803228804228805228806228807228808228809228810228811228812228813228814228815228816228817228818228819228820228821228822228823228824228825228826228827228828228829228830228831228832228833228834228835228836228837228838228839228840228841228842228843228844228845228846228847228848228849228850228851228852228853228854228855228856228857228858228859228860228861228862228863228864228865228866228867228868228869228870228871228872228873228874228875228876228877228878228879228880228881228882228883228884228885228886228887228888228889228890228891228892228893228894228895228896228897228898228899228900228901228902228903228904228905228906228907228908228909228910228911228912228913228914228915228916228917228918228919228920228921228922228923228924228925228926228927228928228929228930228931228932228933228934228935228936228937228938228939228940228941228942228943228944228945228946228947228948228949228950228951228952228953228954228955228956228957228958228959228960228961228962228963228964228965228966228967228968228969228970228971228972228973228974228975228976228977228978228979228980228981228982228983228984228985228986228987228988228989228990228991228992228993228994228995228996228997228998228999229000229001229002229003229004229005229006229007229008229009229010229011229012229013229014229015229016229017229018229019229020229021229022229023229024229025229026229027229028229029229030229031229032229033229034229035229036229037229038229039229040229041229042229043229044229045229046229047229048229049229050229051229052229053229054229055229056229057229058229059229060229061229062229063229064229065229066229067229068229069229070229071229072229073229074229075229076229077229078229079229080229081229082229083229084229085229086229087229088229089229090229091229092229093229094229095229096229097229098229099229100229101229102229103229104229105229106229107229108229109229110229111229112229113229114229115229116229117229118229119229120229121229122229123229124229125229126229127229128229129229130229131229132229133229134229135229136229137229138229139229140229141229142229143229144229145229146229147229148229149229150229151229152229153229154229155229156229157229158229159229160229161229162229163229164229165229166229167229168229169229170229171229172229173229174229175229176229177229178229179229180229181229182229183229184229185229186229187229188229189229190229191229192229193229194229195229196229197229198229199229200229201229202229203229204229205229206229207229208229209229210229211229212229213229214229215229216229217229218229219229220229221229222229223229224229225229226229227229228229229229230229231229232229233229234229235229236229237229238229239229240229241229242229243229244229245229246229247229248229249229250229251229252229253229254229255229256229257229258229259229260229261229262229263229264229265229266229267229268229269229270229271229272229273229274229275229276229277229278229279229280229281229282229283229284229285229286229287229288229289229290229291229292229293229294229295229296229297229298229299229300229301229302229303229304229305229306229307229308229309229310229311229312229313229314229315229316229317229318229319229320229321229322229323229324229325229326229327229328229329229330229331229332229333229334229335229336229337229338229339229340229341229342229343229344229345229346229347229348229349229350229351229352229353229354229355229356229357229358229359229360229361229362229363229364229365229366229367229368229369229370229371229372229373229374229375229376229377229378229379229380229381229382229383229384229385229386229387229388229389229390229391229392229393229394229395229396229397229398229399229400229401229402229403229404229405229406229407229408229409229410229411229412229413229414229415229416229417229418229419229420229421229422229423229424229425229426229427229428229429229430229431229432229433229434229435229436229437229438229439229440229441229442229443229444229445229446229447229448229449229450229451229452229453229454229455229456229457229458229459229460229461229462229463229464229465229466229467229468229469229470229471229472229473229474229475229476229477229478229479229480229481229482229483229484229485229486229487229488229489229490229491229492229493229494229495229496229497229498229499229500229501229502229503229504229505229506229507229508229509229510229511229512229513229514229515229516229517229518229519229520229521229522229523229524229525229526229527229528229529229530229531229532229533229534229535229536229537229538229539229540229541229542229543229544229545229546229547229548229549229550229551229552229553229554229555229556229557229558229559229560229561229562229563229564229565229566229567229568229569229570229571229572229573229574229575229576229577229578229579229580229581229582229583229584229585229586229587229588229589229590229591229592229593229594229595229596229597229598229599229600229601229602229603229604229605229606229607229608229609229610229611229612229613229614229615229616229617229618229619229620229621229622229623229624229625229626229627229628229629229630229631229632229633229634229635229636229637229638229639229640229641229642229643229644229645229646229647229648229649229650229651229652229653229654229655229656229657229658229659229660229661229662229663229664229665229666229667229668229669229670229671229672229673229674229675229676229677229678229679229680229681229682229683229684229685229686229687229688229689229690229691229692229693229694229695229696229697229698229699229700229701229702229703229704229705229706229707229708229709229710229711229712229713229714229715229716229717229718229719229720229721229722229723229724229725229726229727229728229729229730229731229732229733229734229735229736229737229738229739229740229741229742229743229744229745229746229747229748229749229750229751229752229753229754229755229756229757229758229759229760229761229762229763229764229765229766229767229768229769229770229771229772229773229774229775229776229777229778229779229780229781229782229783229784229785229786229787229788229789229790229791229792229793229794229795229796229797229798229799229800229801229802229803229804229805229806229807229808229809229810229811229812229813229814229815229816229817229818229819229820229821229822229823229824229825229826229827229828229829229830229831229832229833229834229835229836229837229838229839229840229841229842229843229844229845229846229847229848229849229850229851229852229853229854229855229856229857229858229859229860229861229862229863229864229865229866229867229868229869229870229871229872229873229874229875229876229877229878229879229880229881229882229883229884229885229886229887229888229889229890229891229892229893229894229895229896229897229898229899229900229901229902229903229904229905229906229907229908229909229910229911229912229913229914229915229916229917229918229919229920229921229922229923229924229925229926229927229928229929229930229931229932229933229934229935229936229937229938229939229940229941229942229943229944229945229946229947229948229949229950229951229952229953229954229955229956229957229958229959229960229961229962229963229964229965229966229967229968229969229970229971229972229973229974229975229976229977229978229979229980229981229982229983229984229985229986229987229988229989229990229991229992229993229994229995229996229997229998229999230000230001230002230003230004230005230006230007230008230009230010230011230012230013230014230015230016230017230018230019230020230021230022230023230024230025230026230027230028230029230030230031230032230033230034230035230036230037230038230039230040230041230042230043230044230045230046230047230048230049230050230051230052230053230054230055230056230057230058230059230060230061230062230063230064230065230066230067230068230069230070230071230072230073230074230075230076230077230078230079230080230081230082230083230084230085230086230087230088230089230090230091230092230093230094230095230096230097230098230099230100230101230102230103230104230105230106230107230108230109230110230111230112230113230114230115230116230117230118230119230120230121230122230123230124230125230126230127230128230129230130230131230132230133230134230135230136230137230138230139230140230141230142230143230144230145230146230147230148230149230150230151230152230153230154230155230156230157230158230159230160230161230162230163230164230165230166230167230168230169230170230171230172230173230174230175230176230177230178230179230180230181230182230183230184230185230186230187230188230189230190230191230192230193230194230195230196230197230198230199230200230201230202230203230204230205230206230207230208230209230210230211230212230213230214230215230216230217230218230219230220230221230222230223230224230225230226230227230228230229230230230231230232230233230234230235230236230237230238230239230240230241230242230243230244230245230246230247230248230249230250230251230252230253230254230255230256230257230258230259230260230261230262230263230264230265230266230267230268230269230270230271230272230273230274230275230276230277230278230279230280230281230282230283230284230285230286230287230288230289230290230291230292230293230294230295230296230297230298230299230300230301230302230303230304230305230306230307230308230309230310230311230312230313230314230315230316230317230318230319230320230321230322230323230324230325230326230327230328230329230330230331230332230333230334230335230336230337230338230339230340230341230342230343230344230345230346230347230348230349230350230351230352230353230354230355230356230357230358230359230360230361230362230363230364230365230366230367230368230369230370230371230372230373230374230375230376230377230378230379230380230381230382230383230384230385230386230387230388230389230390230391230392230393230394230395230396230397230398230399230400230401230402230403230404230405230406230407230408230409230410230411230412230413230414230415230416230417230418230419230420230421230422230423230424230425230426230427230428230429230430230431230432230433230434230435230436230437230438230439230440230441230442230443230444230445230446230447230448230449230450230451230452230453230454230455230456230457230458230459230460230461230462230463230464230465230466230467230468230469230470230471230472230473230474230475230476230477230478230479230480230481230482230483230484230485230486230487230488230489230490230491230492230493230494230495230496230497230498230499230500230501230502230503230504230505230506230507230508230509230510230511230512230513230514230515230516230517230518230519230520230521230522230523230524230525230526230527230528230529230530230531230532230533230534230535230536230537230538230539230540230541230542230543230544230545230546230547230548230549230550230551230552230553230554230555230556230557230558230559230560230561230562230563230564230565230566230567230568230569230570230571230572230573230574230575230576230577230578230579230580230581230582230583230584230585230586230587230588230589230590230591230592230593230594230595230596230597230598230599230600230601230602230603230604230605230606230607230608230609230610230611230612230613230614230615230616230617230618230619230620230621230622230623230624230625230626230627230628230629230630230631230632230633230634230635230636230637230638230639230640230641230642230643230644230645230646230647230648230649230650230651230652230653230654230655230656230657230658230659230660230661230662230663230664230665230666230667230668230669230670230671230672230673230674230675230676230677230678230679230680230681230682230683230684230685230686230687230688230689230690230691230692230693230694230695230696230697230698230699230700230701230702230703230704230705230706230707230708230709230710230711230712230713230714230715230716230717230718230719230720230721230722230723230724230725230726230727230728230729230730230731230732230733230734230735230736230737230738230739230740230741230742230743230744230745230746230747230748230749230750230751230752230753230754230755230756230757230758230759230760230761230762230763230764230765230766230767230768230769230770230771230772230773230774230775230776230777230778230779230780230781230782230783230784230785230786230787230788230789230790230791230792230793230794230795230796230797230798230799230800230801230802230803230804230805230806230807230808230809230810230811230812230813230814230815230816230817230818230819230820230821230822230823230824230825230826230827230828230829230830230831230832230833230834230835230836230837230838230839230840230841230842230843230844230845230846230847230848230849230850230851230852230853230854230855230856230857230858230859230860230861230862230863230864230865230866230867230868230869230870230871230872230873230874230875230876230877230878230879230880230881230882230883230884230885230886230887230888230889230890230891230892230893230894230895230896230897230898230899230900230901230902230903230904230905230906230907230908230909230910230911230912230913230914230915230916230917230918230919230920230921230922230923230924230925230926230927230928230929230930230931230932230933230934230935230936230937230938230939230940230941230942230943230944230945230946230947230948230949230950230951230952230953230954230955230956230957230958230959230960230961230962230963230964230965230966230967230968230969230970230971230972230973230974230975230976230977230978230979230980230981230982230983230984230985230986230987230988230989230990230991230992230993230994230995230996230997230998230999231000231001231002231003231004231005231006231007231008231009231010231011231012231013231014231015231016231017231018231019231020231021231022231023231024231025231026231027231028231029231030231031231032231033231034231035231036231037231038231039231040231041231042231043231044231045231046231047231048231049231050231051231052231053231054231055231056231057231058231059231060231061231062231063231064231065231066231067231068231069231070231071231072231073231074231075231076231077231078231079231080231081231082231083231084231085231086231087231088231089231090231091231092231093231094231095231096231097231098231099231100231101231102231103231104231105231106231107231108231109231110231111231112231113231114231115231116231117231118231119231120231121231122231123231124231125231126231127231128231129231130231131231132231133231134231135231136231137231138231139231140231141231142231143231144231145231146231147231148231149231150231151231152231153231154231155231156231157231158231159231160231161231162231163231164231165231166231167231168231169231170231171231172231173231174231175231176231177231178231179231180231181231182231183231184231185231186231187231188231189231190231191231192231193231194231195231196231197231198231199231200231201231202231203231204231205231206231207231208231209231210231211231212231213231214231215231216231217231218231219231220231221231222231223231224231225231226231227231228231229231230231231231232231233231234231235231236231237231238231239231240231241231242231243231244231245231246231247231248231249231250231251231252231253231254231255231256231257231258231259231260231261231262231263231264231265231266231267231268231269231270231271231272231273231274231275231276231277231278231279231280231281231282231283231284231285231286231287231288231289231290231291231292231293231294231295231296231297231298231299231300231301231302231303231304231305231306231307231308231309231310231311231312231313231314231315231316231317231318231319231320231321231322231323231324231325231326231327231328231329231330231331231332231333231334231335231336231337231338231339231340231341231342231343231344231345231346231347231348231349231350231351231352231353231354231355231356231357231358231359231360231361231362231363231364231365231366231367231368231369231370231371231372231373231374231375231376231377231378231379231380231381231382231383231384231385231386231387231388231389231390231391231392231393231394231395231396231397231398231399231400231401231402231403231404231405231406231407231408231409231410231411231412231413231414231415231416231417231418231419231420231421231422231423231424231425231426231427231428231429231430231431231432231433231434231435231436231437231438231439231440231441231442231443231444231445231446231447231448231449231450231451231452231453231454231455231456231457231458231459231460231461231462231463231464231465231466231467231468231469231470231471231472231473231474231475231476231477231478231479231480231481231482231483231484231485231486231487231488231489231490231491231492231493231494231495231496231497231498231499231500231501231502231503231504231505231506231507231508231509231510231511231512231513231514231515231516231517231518231519231520231521231522231523231524231525231526231527231528231529231530231531231532231533231534231535231536231537231538231539231540231541231542231543231544231545231546231547231548231549231550231551231552231553231554231555231556231557231558231559231560231561231562231563231564231565231566231567231568231569231570231571231572231573231574231575231576231577231578231579231580231581231582231583231584231585231586231587231588231589231590231591231592231593231594231595231596231597231598231599231600231601231602231603231604231605231606231607231608231609231610231611231612231613231614231615231616231617231618231619231620231621231622231623231624231625231626231627231628231629231630231631231632231633231634231635231636231637231638231639231640231641231642231643231644231645231646231647231648231649231650231651231652231653231654231655231656231657231658231659231660231661231662231663231664231665231666231667231668231669231670231671231672231673231674231675231676231677231678231679231680231681231682231683231684231685231686231687231688231689231690231691231692231693231694231695231696231697231698231699231700231701231702231703231704231705231706231707231708231709231710231711231712231713231714231715231716231717231718231719231720231721231722231723231724231725231726231727231728231729231730231731231732231733231734231735231736231737231738231739231740231741231742231743231744231745231746231747231748231749231750231751231752231753231754231755231756231757231758231759231760231761231762231763231764231765231766231767231768231769231770231771231772231773231774231775231776231777231778231779231780231781231782231783231784231785231786231787231788231789231790231791231792231793231794231795231796231797231798231799231800231801231802231803231804231805231806231807231808231809231810231811231812231813231814231815231816231817231818231819231820231821231822231823231824231825231826231827231828231829231830231831231832231833231834231835231836231837231838231839231840231841231842231843231844231845231846231847231848231849231850231851231852231853231854231855231856231857231858231859231860231861231862231863231864231865231866231867231868231869231870231871231872231873231874231875231876231877231878231879231880231881231882231883231884231885231886231887231888231889231890231891231892231893231894231895231896231897231898231899231900231901231902231903231904231905231906231907231908231909231910231911231912231913231914231915231916231917231918231919231920231921231922231923231924231925231926231927231928231929231930231931231932231933231934231935231936231937231938231939231940231941231942231943231944231945231946231947231948231949231950231951231952231953231954231955231956231957231958231959231960231961231962231963231964231965231966231967231968231969231970231971231972231973231974231975231976231977231978231979231980231981231982231983231984231985231986231987231988231989231990231991231992231993231994231995231996231997231998231999232000232001232002232003232004232005232006232007232008232009232010232011232012232013232014232015232016232017232018232019232020232021232022232023232024232025232026232027232028232029232030232031232032232033232034232035232036232037232038232039232040232041232042232043232044232045232046232047232048232049232050232051232052232053232054232055232056232057232058232059232060232061232062232063232064232065232066232067232068232069232070232071232072232073232074232075232076232077232078232079232080232081232082232083232084232085232086232087232088232089232090232091232092232093232094232095232096232097232098232099232100232101232102232103232104232105232106232107232108232109232110232111232112232113232114232115232116232117232118232119232120232121232122232123232124232125232126232127232128232129232130232131232132232133232134232135232136232137232138232139232140232141232142232143232144232145232146232147232148232149232150232151232152232153232154232155232156232157232158232159232160232161232162232163232164232165232166232167232168232169232170232171232172232173232174232175232176232177232178232179232180232181232182232183232184232185232186232187232188232189232190232191232192232193232194232195232196232197232198232199232200232201232202232203232204232205232206232207232208232209232210232211232212232213232214232215232216232217232218232219232220232221232222232223232224232225232226232227232228232229232230232231232232232233232234232235232236232237232238232239232240232241232242232243232244232245232246232247232248232249232250232251232252232253232254232255232256232257232258232259232260232261232262232263232264232265232266232267232268232269232270232271232272232273232274232275232276232277232278232279232280232281232282232283232284232285232286232287232288232289232290232291232292232293232294232295232296232297232298232299232300232301232302232303232304232305232306232307232308232309232310232311232312232313232314232315232316232317232318232319232320232321232322232323232324232325232326232327232328232329232330232331232332232333232334232335232336232337232338232339232340232341232342232343232344232345232346232347232348232349232350232351232352232353232354232355232356232357232358232359232360232361232362232363232364232365232366232367232368232369232370232371232372232373232374232375232376232377232378232379232380232381232382232383232384232385232386232387232388232389232390232391232392232393232394232395232396232397232398232399232400232401232402232403232404232405232406232407232408232409232410232411232412232413232414232415232416232417232418232419232420232421232422232423232424232425232426232427232428232429232430232431232432232433232434232435232436232437232438232439232440232441232442232443232444232445232446232447232448232449232450232451232452232453232454232455232456232457232458232459232460232461232462232463232464232465232466232467232468232469232470232471232472232473232474232475232476232477232478232479232480232481232482232483232484232485232486232487232488232489232490232491232492232493232494232495232496232497232498232499232500232501232502232503232504232505232506232507232508232509232510232511232512232513232514232515232516232517232518232519232520232521232522232523232524232525232526232527232528232529232530232531232532232533232534232535232536232537232538232539232540232541232542232543232544232545232546232547232548232549232550232551232552232553232554232555232556232557232558232559232560232561232562232563232564232565232566232567232568232569232570232571232572232573232574232575232576232577232578232579232580232581232582232583232584232585232586232587232588232589232590232591232592232593232594232595232596232597232598232599232600232601232602232603232604232605232606232607232608232609232610232611232612232613232614232615232616232617232618232619232620232621232622232623232624232625232626232627232628232629232630232631232632232633232634232635232636232637232638232639232640232641232642232643232644232645232646232647232648232649232650232651232652232653232654232655232656232657232658232659232660232661232662232663232664232665232666232667232668232669232670232671232672232673232674232675232676232677232678232679232680232681232682232683232684232685232686232687232688232689232690232691232692232693232694232695232696232697232698232699232700232701232702232703232704232705232706232707232708232709232710232711232712232713232714232715232716232717232718232719232720232721232722232723232724232725232726232727232728232729232730232731232732232733232734232735232736232737232738232739232740232741232742232743232744232745232746232747232748232749232750232751232752232753232754232755232756232757232758232759232760232761232762232763232764232765232766232767232768232769232770232771232772232773232774232775232776232777232778232779232780232781232782232783232784232785232786232787232788232789232790232791232792232793232794232795232796232797232798232799232800232801232802232803232804232805232806232807232808232809232810232811232812232813232814232815232816232817232818232819232820232821232822232823232824232825232826232827232828232829232830232831232832232833232834232835232836232837232838232839232840232841232842232843232844232845232846232847232848232849232850232851232852232853232854232855232856232857232858232859232860232861232862232863232864232865232866232867232868232869232870232871232872232873232874232875232876232877232878232879232880232881232882232883232884232885232886232887232888232889232890232891232892232893232894232895232896232897232898232899232900232901232902232903232904232905232906232907232908232909232910232911232912232913232914232915232916232917232918232919232920232921232922232923232924232925232926232927232928232929232930232931232932232933232934232935232936232937232938232939232940232941232942232943232944232945232946232947232948232949232950232951232952232953232954232955232956232957232958232959232960232961232962232963232964232965232966232967232968232969232970232971232972232973232974232975232976232977232978232979232980232981232982232983232984232985232986232987232988232989232990232991232992232993232994232995232996232997232998232999233000233001233002233003233004233005233006233007233008233009233010233011233012233013233014233015233016233017233018233019233020233021233022233023233024233025233026233027233028233029233030233031233032233033233034233035233036233037233038233039233040233041233042233043233044233045233046233047233048233049233050233051233052233053233054233055233056233057233058233059233060233061233062233063233064233065233066233067233068233069233070233071233072233073233074233075233076233077233078233079233080233081233082233083233084233085233086233087233088233089233090233091233092233093233094233095233096233097233098233099233100233101233102233103233104233105233106233107233108233109233110233111233112233113233114233115233116233117233118233119233120233121233122233123233124233125233126233127233128233129233130233131233132233133233134233135233136233137233138233139233140233141233142233143233144233145233146233147233148233149233150233151233152233153233154233155233156233157233158233159233160233161233162233163233164233165233166233167233168233169233170233171233172233173233174233175233176233177233178233179233180233181233182233183233184233185233186233187233188233189233190233191233192233193233194233195233196233197233198233199233200233201233202233203233204233205233206233207233208233209233210233211233212233213233214233215233216233217233218233219233220233221233222233223233224233225233226233227233228233229233230233231233232233233233234233235233236233237233238233239233240233241233242233243233244233245233246233247233248233249233250233251233252233253233254233255233256233257233258233259233260233261233262233263233264233265233266233267233268233269233270233271233272233273233274233275233276233277233278233279233280233281233282233283233284233285233286233287233288233289233290233291233292233293233294233295233296233297233298233299233300233301233302233303233304233305233306233307233308233309233310233311233312233313233314233315233316233317233318233319233320233321233322233323233324233325233326233327233328233329233330233331233332233333233334233335233336233337233338233339233340233341233342233343233344233345233346233347233348233349233350233351233352233353233354233355233356233357233358233359233360233361233362233363233364233365233366233367233368233369233370233371233372233373233374233375233376233377233378233379233380233381233382233383233384233385233386233387233388233389233390233391233392233393233394233395233396233397233398233399233400233401233402233403233404233405233406233407233408233409233410233411233412233413233414233415233416233417233418233419233420233421233422233423233424233425233426233427233428233429233430233431233432233433233434233435233436233437233438233439233440233441233442233443233444233445233446233447233448233449233450233451233452233453233454233455233456233457233458233459233460233461233462233463233464233465233466233467233468233469233470233471233472233473233474233475233476233477233478233479233480233481233482233483233484233485233486233487233488233489233490233491233492233493233494233495233496233497233498233499233500233501233502233503233504233505233506233507233508233509233510233511233512233513233514233515233516233517233518233519233520233521233522233523233524233525233526233527233528233529233530233531233532233533233534233535233536233537233538233539233540233541233542233543233544233545233546233547233548233549233550233551233552233553233554233555233556233557233558233559233560233561233562233563233564233565233566233567233568233569233570233571233572233573233574233575233576233577233578233579233580233581233582233583233584233585233586233587233588233589233590233591233592233593233594233595233596233597233598233599233600233601233602233603233604233605233606233607233608233609233610233611233612233613233614233615233616233617233618233619233620233621233622233623233624233625233626233627233628233629233630233631233632233633233634233635233636233637233638233639233640233641233642233643233644233645233646233647233648233649233650233651233652233653233654233655233656233657233658233659233660233661233662233663233664233665233666233667233668233669233670233671233672233673233674233675233676233677233678233679233680233681233682233683233684233685233686233687233688233689233690233691233692233693233694233695233696233697233698233699233700233701233702233703233704233705233706233707233708233709233710233711233712233713233714233715233716233717233718233719233720233721233722233723233724233725233726233727233728233729233730233731233732233733233734233735233736233737233738233739233740233741233742233743233744233745233746233747233748233749233750233751233752233753233754233755233756233757233758233759233760233761233762233763233764233765233766233767233768233769233770233771233772233773233774233775233776233777233778233779233780233781233782233783233784233785233786233787233788233789233790233791233792233793233794233795233796233797233798233799233800233801233802233803233804233805233806233807233808233809233810233811233812233813233814233815233816233817233818233819233820233821233822233823233824233825233826233827233828233829233830233831233832233833233834233835233836233837233838233839233840233841233842233843233844233845233846233847233848233849233850233851233852233853233854233855233856233857233858233859233860233861233862233863233864233865233866233867233868233869233870233871233872233873233874233875233876233877233878233879233880233881233882233883233884233885233886233887233888233889233890233891233892233893233894233895233896233897233898233899233900233901233902233903233904233905233906233907233908233909233910233911233912233913233914233915233916233917233918233919233920233921233922233923233924233925233926233927233928233929233930233931233932233933233934233935233936233937233938233939233940233941233942233943233944233945233946233947233948233949233950233951233952233953233954233955233956233957233958233959233960233961233962233963233964233965233966233967233968233969233970233971233972233973233974233975233976233977233978233979233980233981233982233983233984233985233986233987233988233989233990233991233992233993233994233995233996233997233998233999234000234001234002234003234004234005234006234007234008234009234010234011234012234013234014234015234016234017234018234019234020234021234022234023234024234025234026234027234028234029234030234031234032234033234034234035234036234037234038234039234040234041234042234043234044234045234046234047234048234049234050234051234052234053234054234055234056234057234058234059234060234061234062234063234064234065234066234067234068234069234070234071234072234073234074234075234076234077234078234079234080234081234082234083234084234085234086234087234088234089234090234091234092234093234094234095234096234097234098234099234100234101234102234103234104234105234106234107234108234109234110234111234112234113234114234115234116234117234118234119234120234121234122234123234124234125234126234127234128234129234130234131234132234133234134234135234136234137234138234139234140234141234142234143234144234145234146234147234148234149234150234151234152234153234154234155234156234157234158234159234160234161234162234163234164234165234166234167234168234169234170234171234172234173234174234175234176234177234178234179234180234181234182234183234184234185234186234187234188234189234190234191234192234193234194234195234196234197234198234199234200234201234202234203234204234205234206234207234208234209234210234211234212234213234214234215234216234217234218234219234220234221234222234223234224234225234226234227234228234229234230234231234232234233234234234235234236234237234238234239234240234241234242234243234244234245234246234247234248234249234250234251234252234253234254234255234256234257234258234259234260234261234262234263234264234265234266234267234268234269234270234271234272234273234274234275234276234277234278234279234280234281234282234283234284234285234286234287234288234289234290234291234292234293234294234295234296234297234298234299234300234301234302234303234304234305234306234307234308234309234310234311234312234313234314234315234316234317234318234319234320234321234322234323234324234325234326234327234328234329234330234331234332234333234334234335234336234337234338234339234340234341234342234343234344234345234346234347234348234349234350234351234352234353234354234355234356234357234358234359234360234361234362234363234364234365234366234367234368234369234370234371234372234373234374234375234376234377234378234379234380234381234382234383234384234385234386234387234388234389234390234391234392234393234394234395234396234397234398234399234400234401234402234403234404234405234406234407234408234409234410234411234412234413234414234415234416234417234418234419234420234421234422234423234424234425234426234427234428234429234430234431234432234433234434234435234436234437234438234439234440234441234442234443234444234445234446234447234448234449234450234451234452234453234454234455234456234457234458234459234460234461234462234463234464234465234466234467234468234469234470234471234472234473234474234475234476234477234478234479234480234481234482234483234484234485234486234487234488234489234490234491234492234493234494234495234496234497234498234499234500234501234502234503234504234505234506234507234508234509234510234511234512234513234514234515234516234517234518234519234520234521234522234523234524234525234526234527234528234529234530234531234532234533234534234535234536234537234538234539234540234541234542234543234544234545234546234547234548234549234550234551234552234553234554234555234556234557234558234559234560234561234562234563234564234565234566234567234568234569234570234571234572234573234574234575234576234577234578234579234580234581234582234583234584234585234586234587234588234589234590234591234592234593234594234595234596234597234598234599234600234601234602234603234604234605234606234607234608234609234610234611234612234613234614234615234616234617234618234619234620234621234622234623234624234625234626234627234628234629234630234631234632234633234634234635234636234637234638234639234640234641234642234643234644234645234646234647234648234649234650234651234652234653234654234655234656234657234658234659234660234661234662234663234664234665234666234667234668234669234670234671234672234673234674234675234676234677234678234679234680234681234682234683234684234685234686234687234688234689234690234691234692234693234694234695234696234697234698234699234700234701234702234703234704234705234706234707234708234709234710234711234712234713234714234715234716234717234718234719234720234721234722234723234724234725234726234727234728234729234730234731234732234733234734234735234736234737234738234739234740234741234742234743234744234745234746234747234748234749234750234751234752234753234754234755234756234757234758234759234760234761234762234763234764234765234766234767234768234769234770234771234772234773234774234775234776234777234778234779234780234781234782234783234784234785234786234787234788234789234790234791234792234793234794234795234796234797234798234799234800234801234802234803234804234805234806234807234808234809234810234811234812234813234814234815234816234817234818234819234820234821234822234823234824234825234826234827234828234829234830234831234832234833234834234835234836234837234838234839234840234841234842234843234844234845234846234847234848234849234850234851234852234853234854234855234856234857234858234859234860234861234862234863234864234865234866234867234868234869234870234871234872234873234874234875234876234877234878234879234880234881234882234883234884234885234886234887234888234889234890234891234892234893234894234895234896234897234898234899234900234901234902234903234904234905234906234907234908234909234910234911234912234913234914234915234916234917234918234919234920234921234922234923234924234925234926234927234928234929234930234931234932234933234934234935234936234937234938234939234940234941234942234943234944234945234946234947234948234949234950234951234952234953234954234955234956234957234958234959234960234961234962234963234964234965234966234967234968234969234970234971234972234973234974234975234976234977234978234979234980234981234982234983234984234985234986234987234988234989234990234991234992234993234994234995234996234997234998234999235000235001235002235003235004235005235006235007235008235009235010235011235012235013235014235015235016235017235018235019235020235021235022235023235024235025235026235027235028235029235030235031235032235033235034235035235036235037235038235039235040235041235042235043235044235045235046235047235048235049235050235051235052235053235054235055235056235057235058235059235060235061235062235063235064235065235066235067235068235069235070235071235072235073235074235075235076235077235078235079235080235081235082235083235084235085235086235087235088235089235090235091235092235093235094235095235096235097235098235099235100235101235102235103235104235105235106235107235108235109235110235111235112235113235114235115235116235117235118235119235120235121235122235123235124235125235126235127235128235129235130235131235132235133235134235135235136235137235138235139235140235141235142235143235144235145235146235147235148235149235150235151235152235153235154235155235156235157235158235159235160235161235162235163235164235165235166235167235168235169235170235171235172235173235174235175235176235177235178235179235180235181235182235183235184235185235186235187235188235189235190235191235192235193235194235195235196235197235198235199235200235201235202235203235204235205235206235207235208235209235210235211235212235213235214235215235216235217235218235219235220235221235222235223235224235225235226235227235228235229235230235231235232235233235234235235235236235237235238235239235240235241235242235243235244235245235246235247235248235249235250235251235252235253235254235255
  1. diff -Nur linux-3.14.15/arch/arm/boot/dts/clcd-panels.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/clcd-panels.dtsi
  2. --- linux-3.14.15/arch/arm/boot/dts/clcd-panels.dtsi 1970-01-01 01:00:00.000000000 +0100
  3. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/clcd-panels.dtsi 2014-08-20 19:23:45.534811583 +0200
  4. @@ -0,0 +1,52 @@
  5. +/*
  6. + * ARM Ltd. Versatile Express
  7. + *
  8. + */
  9. +
  10. +/ {
  11. + panels {
  12. + panel@0 {
  13. + compatible = "panel";
  14. + mode = "VGA";
  15. + refresh = <60>;
  16. + xres = <640>;
  17. + yres = <480>;
  18. + pixclock = <39721>;
  19. + left_margin = <40>;
  20. + right_margin = <24>;
  21. + upper_margin = <32>;
  22. + lower_margin = <11>;
  23. + hsync_len = <96>;
  24. + vsync_len = <2>;
  25. + sync = <0>;
  26. + vmode = "FB_VMODE_NONINTERLACED";
  27. +
  28. + tim2 = "TIM2_BCD", "TIM2_IPC";
  29. + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
  30. + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
  31. + bpp = <16>;
  32. + };
  33. +
  34. + panel@1 {
  35. + compatible = "panel";
  36. + mode = "XVGA";
  37. + refresh = <60>;
  38. + xres = <1024>;
  39. + yres = <768>;
  40. + pixclock = <15748>;
  41. + left_margin = <152>;
  42. + right_margin = <48>;
  43. + upper_margin = <23>;
  44. + lower_margin = <3>;
  45. + hsync_len = <104>;
  46. + vsync_len = <4>;
  47. + sync = <0>;
  48. + vmode = "FB_VMODE_NONINTERLACED";
  49. +
  50. + tim2 = "TIM2_BCD", "TIM2_IPC";
  51. + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
  52. + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
  53. + bpp = <16>;
  54. + };
  55. + };
  56. +};
  57. diff -Nur linux-3.14.15/arch/arm/boot/dts/efm32gg-dk3750.dts linux-linaro-stable-mx6/arch/arm/boot/dts/efm32gg-dk3750.dts
  58. --- linux-3.14.15/arch/arm/boot/dts/efm32gg-dk3750.dts 2014-07-31 23:51:43.000000000 +0200
  59. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/efm32gg-dk3750.dts 2014-08-20 19:31:39.860842101 +0200
  60. @@ -26,7 +26,7 @@
  61. };
  62. i2c@4000a000 {
  63. - location = <3>;
  64. + efm32,location = <3>;
  65. status = "ok";
  66. temp@48 {
  67. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx23.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx23.dtsi
  68. --- linux-3.14.15/arch/arm/boot/dts/imx23.dtsi 2014-07-31 23:51:43.000000000 +0200
  69. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx23.dtsi 2014-08-20 19:31:39.884842204 +0200
  70. @@ -363,7 +363,8 @@
  71. compatible = "fsl,imx23-lcdif";
  72. reg = <0x80030000 2000>;
  73. interrupts = <46 45>;
  74. - clocks = <&clks 38>;
  75. + clocks = <&clks 38>, <&clks 38>;
  76. + clock-names = "pix", "axi";
  77. status = "disabled";
  78. };
  79. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx25.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx25.dtsi
  80. --- linux-3.14.15/arch/arm/boot/dts/imx25.dtsi 2014-07-31 23:51:43.000000000 +0200
  81. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx25.dtsi 2014-08-20 19:31:39.888842222 +0200
  82. @@ -13,6 +13,7 @@
  83. / {
  84. aliases {
  85. + ethernet0 = &fec;
  86. gpio0 = &gpio1;
  87. gpio1 = &gpio2;
  88. gpio2 = &gpio3;
  89. @@ -56,6 +57,7 @@
  90. osc {
  91. compatible = "fsl,imx-osc", "fixed-clock";
  92. + #clock-cells = <0>;
  93. clock-frequency = <24000000>;
  94. };
  95. };
  96. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx25-karo-tx25.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx25-karo-tx25.dts
  97. --- linux-3.14.15/arch/arm/boot/dts/imx25-karo-tx25.dts 2014-07-31 23:51:43.000000000 +0200
  98. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx25-karo-tx25.dts 2014-08-20 19:31:39.884842204 +0200
  99. @@ -16,6 +16,10 @@
  100. model = "Ka-Ro TX25";
  101. compatible = "karo,imx25-tx25", "fsl,imx25";
  102. + chosen {
  103. + stdout-path = &uart1;
  104. + };
  105. +
  106. memory {
  107. reg = <0x80000000 0x02000000 0x90000000 0x02000000>;
  108. };
  109. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx27-apf27.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx27-apf27.dts
  110. --- linux-3.14.15/arch/arm/boot/dts/imx27-apf27.dts 2014-07-31 23:51:43.000000000 +0200
  111. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx27-apf27.dts 2014-08-20 19:31:39.888842222 +0200
  112. @@ -29,6 +29,7 @@
  113. osc26m {
  114. compatible = "fsl,imx-osc26m", "fixed-clock";
  115. + #clock-cells = <0>;
  116. clock-frequency = <0>;
  117. };
  118. };
  119. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx27.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx27.dtsi
  120. --- linux-3.14.15/arch/arm/boot/dts/imx27.dtsi 2014-07-31 23:51:43.000000000 +0200
  121. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx27.dtsi 2014-08-20 19:31:39.892842237 +0200
  122. @@ -13,6 +13,7 @@
  123. / {
  124. aliases {
  125. + ethernet0 = &fec;
  126. gpio0 = &gpio1;
  127. gpio1 = &gpio2;
  128. gpio2 = &gpio3;
  129. @@ -46,6 +47,7 @@
  130. osc26m {
  131. compatible = "fsl,imx-osc26m", "fixed-clock";
  132. + #clock-cells = <0>;
  133. clock-frequency = <26000000>;
  134. };
  135. };
  136. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts
  137. --- linux-3.14.15/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts 2014-07-31 23:51:43.000000000 +0200
  138. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts 2014-08-20 19:31:39.888842222 +0200
  139. @@ -15,6 +15,10 @@
  140. model = "Phytec pca100 rapid development kit";
  141. compatible = "phytec,imx27-pca100-rdk", "phytec,imx27-pca100", "fsl,imx27";
  142. + chosen {
  143. + stdout-path = &uart1;
  144. + };
  145. +
  146. display: display {
  147. model = "Primeview-PD050VL1";
  148. native-mode = <&timing0>;
  149. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx28.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx28.dtsi
  150. --- linux-3.14.15/arch/arm/boot/dts/imx28.dtsi 2014-07-31 23:51:43.000000000 +0200
  151. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx28.dtsi 2014-08-20 19:31:39.892842237 +0200
  152. @@ -840,7 +840,8 @@
  153. compatible = "fsl,imx28-lcdif";
  154. reg = <0x80030000 0x2000>;
  155. interrupts = <38>;
  156. - clocks = <&clks 55>;
  157. + clocks = <&clks 55>, <&clks 55>;
  158. + clock-names = "pix", "axi";
  159. dmas = <&dma_apbh 13>;
  160. dma-names = "rx";
  161. status = "disabled";
  162. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx51-babbage.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx51-babbage.dts
  163. --- linux-3.14.15/arch/arm/boot/dts/imx51-babbage.dts 2014-07-31 23:51:43.000000000 +0200
  164. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx51-babbage.dts 2014-08-20 19:31:39.896842254 +0200
  165. @@ -17,6 +17,10 @@
  166. model = "Freescale i.MX51 Babbage Board";
  167. compatible = "fsl,imx51-babbage", "fsl,imx51";
  168. + chosen {
  169. + stdout-path = &uart1;
  170. + };
  171. +
  172. memory {
  173. reg = <0x90000000 0x20000000>;
  174. };
  175. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx51.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx51.dtsi
  176. --- linux-3.14.15/arch/arm/boot/dts/imx51.dtsi 2014-07-31 23:51:43.000000000 +0200
  177. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx51.dtsi 2014-08-20 19:31:39.896842254 +0200
  178. @@ -15,6 +15,7 @@
  179. / {
  180. aliases {
  181. + ethernet0 = &fec;
  182. gpio0 = &gpio1;
  183. gpio1 = &gpio2;
  184. gpio2 = &gpio3;
  185. @@ -43,21 +44,25 @@
  186. ckil {
  187. compatible = "fsl,imx-ckil", "fixed-clock";
  188. + #clock-cells = <0>;
  189. clock-frequency = <32768>;
  190. };
  191. ckih1 {
  192. compatible = "fsl,imx-ckih1", "fixed-clock";
  193. + #clock-cells = <0>;
  194. clock-frequency = <0>;
  195. };
  196. ckih2 {
  197. compatible = "fsl,imx-ckih2", "fixed-clock";
  198. + #clock-cells = <0>;
  199. clock-frequency = <0>;
  200. };
  201. osc {
  202. compatible = "fsl,imx-osc", "fixed-clock";
  203. + #clock-cells = <0>;
  204. clock-frequency = <24000000>;
  205. };
  206. };
  207. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx53.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx53.dtsi
  208. --- linux-3.14.15/arch/arm/boot/dts/imx53.dtsi 2014-07-31 23:51:43.000000000 +0200
  209. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx53.dtsi 2014-08-20 19:31:39.896842254 +0200
  210. @@ -15,6 +15,7 @@
  211. / {
  212. aliases {
  213. + ethernet0 = &fec;
  214. gpio0 = &gpio1;
  215. gpio1 = &gpio2;
  216. gpio2 = &gpio3;
  217. @@ -59,21 +60,25 @@
  218. ckil {
  219. compatible = "fsl,imx-ckil", "fixed-clock";
  220. + #clock-cells = <0>;
  221. clock-frequency = <32768>;
  222. };
  223. ckih1 {
  224. compatible = "fsl,imx-ckih1", "fixed-clock";
  225. + #clock-cells = <0>;
  226. clock-frequency = <22579200>;
  227. };
  228. ckih2 {
  229. compatible = "fsl,imx-ckih2", "fixed-clock";
  230. + #clock-cells = <0>;
  231. clock-frequency = <0>;
  232. };
  233. osc {
  234. compatible = "fsl,imx-osc", "fixed-clock";
  235. + #clock-cells = <0>;
  236. clock-frequency = <24000000>;
  237. };
  238. };
  239. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx53-mba53.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx53-mba53.dts
  240. --- linux-3.14.15/arch/arm/boot/dts/imx53-mba53.dts 2014-07-31 23:51:43.000000000 +0200
  241. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx53-mba53.dts 2014-08-20 19:31:39.896842254 +0200
  242. @@ -25,6 +25,10 @@
  243. enable-active-low;
  244. };
  245. + chosen {
  246. + stdout-path = &uart2;
  247. + };
  248. +
  249. backlight {
  250. compatible = "pwm-backlight";
  251. pwms = <&pwm2 0 50000>;
  252. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
  253. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts 1970-01-01 01:00:00.000000000 +0100
  254. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts 2014-08-20 19:31:39.896842254 +0200
  255. @@ -0,0 +1,23 @@
  256. +/*
  257. + * Copyright 2013 Sascha Hauer <s.hauer@pengutronix.de>
  258. + *
  259. + * The code contained herein is licensed under the GNU General Public
  260. + * License. You may obtain a copy of the GNU General Public License
  261. + * Version 2 or later at the following locations:
  262. + *
  263. + * http://www.opensource.org/licenses/gpl-license.html
  264. + * http://www.gnu.org/copyleft/gpl.html
  265. + */
  266. +
  267. +#ifndef __DTS_V1__
  268. +#define __DTS_V1__
  269. +/dts-v1/;
  270. +#endif
  271. +
  272. +#include "imx6dl.dtsi"
  273. +#include "imx6qdl-dfi-fs700-m60.dtsi"
  274. +
  275. +/ {
  276. + model = "DFI FS700-M60-6DL i.MX6dl Q7 Board";
  277. + compatible = "dfi,fs700-m60-6dl", "dfi,fs700e-m60", "fsl,imx6dl";
  278. +};
  279. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl.dtsi
  280. --- linux-3.14.15/arch/arm/boot/dts/imx6dl.dtsi 2014-07-31 23:51:43.000000000 +0200
  281. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl.dtsi 2014-08-20 19:31:39.896842254 +0200
  282. @@ -8,6 +8,7 @@
  283. *
  284. */
  285. +#include <dt-bindings/interrupt-controller/irq.h>
  286. #include "imx6dl-pinfunc.h"
  287. #include "imx6qdl.dtsi"
  288. @@ -21,6 +22,26 @@
  289. device_type = "cpu";
  290. reg = <0>;
  291. next-level-cache = <&L2>;
  292. + operating-points = <
  293. + /* kHz uV */
  294. + 996000 1275000
  295. + 792000 1175000
  296. + 396000 1075000
  297. + >;
  298. + fsl,soc-operating-points = <
  299. + /* ARM kHz SOC-PU uV */
  300. + 996000 1175000
  301. + 792000 1175000
  302. + 396000 1175000
  303. + >;
  304. + clock-latency = <61036>; /* two CLK32 periods */
  305. + clocks = <&clks 104>, <&clks 6>, <&clks 16>,
  306. + <&clks 17>, <&clks 170>;
  307. + clock-names = "arm", "pll2_pfd2_396m", "step",
  308. + "pll1_sw", "pll1_sys";
  309. + arm-supply = <&reg_arm>;
  310. + pu-supply = <&reg_pu>;
  311. + soc-supply = <&reg_soc>;
  312. };
  313. cpu@1 {
  314. @@ -32,40 +53,124 @@
  315. };
  316. soc {
  317. +
  318. + busfreq { /* BUSFREQ */
  319. + compatible = "fsl,imx6_busfreq";
  320. + clocks = <&clks 171>, <&clks 6>, <&clks 11>, <&clks 104>, <&clks 172>, <&clks 58>,
  321. + <&clks 18>, <&clks 60>, <&clks 20>, <&clks 3>, <&clks 22> , <&clks 8>;
  322. + clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
  323. + "periph_pre", "periph_clk2", "periph_clk2_sel", "osc", "axi_sel", "pll3_pfd1_540m";
  324. + interrupts = <0 107 0x04>, <0 112 0x4>;
  325. + interrupt-names = "irq_busfreq_0", "irq_busfreq_1";
  326. + fsl,max_ddr_freq = <400000000>;
  327. + };
  328. +
  329. + gpu@00130000 {
  330. + compatible = "fsl,imx6dl-gpu", "fsl,imx6q-gpu";
  331. + reg = <0x00130000 0x4000>, <0x00134000 0x4000>,
  332. + <0x0 0x0>;
  333. + reg-names = "iobase_3d", "iobase_2d",
  334. + "phys_baseaddr";
  335. + interrupts = <0 9 0x04>, <0 10 0x04>;
  336. + interrupt-names = "irq_3d", "irq_2d";
  337. + clocks = <&clks 143>, <&clks 27>,
  338. + <&clks 121>, <&clks 122>,
  339. + <&clks 0>;
  340. + clock-names = "gpu2d_axi_clk", "gpu3d_axi_clk",
  341. + "gpu2d_clk", "gpu3d_clk",
  342. + "gpu3d_shader_clk";
  343. + resets = <&src 0>, <&src 3>;
  344. + reset-names = "gpu3d", "gpu2d";
  345. + pu-supply = <&reg_pu>;
  346. + };
  347. +
  348. ocram: sram@00900000 {
  349. compatible = "mmio-sram";
  350. reg = <0x00900000 0x20000>;
  351. clocks = <&clks 142>;
  352. };
  353. + hdmi_core: hdmi_core@00120000 {
  354. + compatible = "fsl,imx6dl-hdmi-core";
  355. + reg = <0x00120000 0x9000>;
  356. + clocks = <&clks 124>, <&clks 123>;
  357. + clock-names = "hdmi_isfr", "hdmi_iahb";
  358. + status = "disabled";
  359. + };
  360. +
  361. + hdmi_video: hdmi_video@020e0000 {
  362. + compatible = "fsl,imx6dl-hdmi-video";
  363. + reg = <0x020e0000 0x1000>;
  364. + reg-names = "hdmi_gpr";
  365. + interrupts = <0 115 0x04>;
  366. + clocks = <&clks 124>, <&clks 123>;
  367. + clock-names = "hdmi_isfr", "hdmi_iahb";
  368. + status = "disabled";
  369. + };
  370. +
  371. + hdmi_audio: hdmi_audio@00120000 {
  372. + compatible = "fsl,imx6dl-hdmi-audio";
  373. + clocks = <&clks 124>, <&clks 123>;
  374. + clock-names = "hdmi_isfr", "hdmi_iahb";
  375. + dmas = <&sdma 2 23 0>;
  376. + dma-names = "tx";
  377. + status = "disabled";
  378. + };
  379. +
  380. + hdmi_cec: hdmi_cec@00120000 {
  381. + compatible = "fsl,imx6dl-hdmi-cec";
  382. + interrupts = <0 115 0x04>;
  383. + status = "disabled";
  384. + };
  385. +
  386. aips1: aips-bus@02000000 {
  387. + vpu@02040000 {
  388. + iramsize = <0>;
  389. + status = "okay";
  390. + };
  391. +
  392. iomuxc: iomuxc@020e0000 {
  393. compatible = "fsl,imx6dl-iomuxc";
  394. };
  395. pxp: pxp@020f0000 {
  396. + compatible = "fsl,imx6dl-pxp-dma";
  397. reg = <0x020f0000 0x4000>;
  398. - interrupts = <0 98 0x04>;
  399. + interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
  400. + clocks = <&clks 133>;
  401. + clock-names = "pxp-axi";
  402. + status = "disabled";
  403. };
  404. epdc: epdc@020f4000 {
  405. reg = <0x020f4000 0x4000>;
  406. - interrupts = <0 97 0x04>;
  407. + interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
  408. };
  409. lcdif: lcdif@020f8000 {
  410. reg = <0x020f8000 0x4000>;
  411. - interrupts = <0 39 0x04>;
  412. + interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
  413. };
  414. };
  415. aips2: aips-bus@02100000 {
  416. + mipi_dsi: mipi@021e0000 {
  417. + compatible = "fsl,imx6dl-mipi-dsi";
  418. + reg = <0x021e0000 0x4000>;
  419. + interrupts = <0 102 0x04>;
  420. + gpr = <&gpr>;
  421. + clocks = <&clks 138>, <&clks 209>;
  422. + clock-names = "mipi_pllref_clk", "mipi_cfg_clk";
  423. + status = "disabled";
  424. + };
  425. +
  426. i2c4: i2c@021f8000 {
  427. #address-cells = <1>;
  428. #size-cells = <0>;
  429. - compatible = "fsl,imx1-i2c";
  430. + compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
  431. reg = <0x021f8000 0x4000>;
  432. - interrupts = <0 35 0x04>;
  433. + interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
  434. + clocks = <&clks 116>;
  435. status = "disabled";
  436. };
  437. };
  438. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-gw51xx.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-gw51xx.dts
  439. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-gw51xx.dts 1970-01-01 01:00:00.000000000 +0100
  440. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-gw51xx.dts 2014-08-20 19:31:39.896842254 +0200
  441. @@ -0,0 +1,19 @@
  442. +/*
  443. + * Copyright 2013 Gateworks Corporation
  444. + *
  445. + * The code contained herein is licensed under the GNU General Public
  446. + * License. You may obtain a copy of the GNU General Public License
  447. + * Version 2 or later at the following locations:
  448. + *
  449. + * http://www.opensource.org/licenses/gpl-license.html
  450. + * http://www.gnu.org/copyleft/gpl.html
  451. + */
  452. +
  453. +/dts-v1/;
  454. +#include "imx6dl.dtsi"
  455. +#include "imx6qdl-gw51xx.dtsi"
  456. +
  457. +/ {
  458. + model = "Gateworks Ventana i.MX6 DualLite GW51XX";
  459. + compatible = "gw,imx6dl-gw51xx", "gw,ventana", "fsl,imx6dl";
  460. +};
  461. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-gw52xx.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-gw52xx.dts
  462. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-gw52xx.dts 1970-01-01 01:00:00.000000000 +0100
  463. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-gw52xx.dts 2014-08-20 19:31:39.896842254 +0200
  464. @@ -0,0 +1,19 @@
  465. +/*
  466. + * Copyright 2013 Gateworks Corporation
  467. + *
  468. + * The code contained herein is licensed under the GNU General Public
  469. + * License. You may obtain a copy of the GNU General Public License
  470. + * Version 2 or later at the following locations:
  471. + *
  472. + * http://www.opensource.org/licenses/gpl-license.html
  473. + * http://www.gnu.org/copyleft/gpl.html
  474. + */
  475. +
  476. +/dts-v1/;
  477. +#include "imx6dl.dtsi"
  478. +#include "imx6qdl-gw52xx.dtsi"
  479. +
  480. +/ {
  481. + model = "Gateworks Ventana i.MX6 DualLite GW52XX";
  482. + compatible = "gw,imx6dl-gw52xx", "gw,ventana", "fsl,imx6dl";
  483. +};
  484. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-gw53xx.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-gw53xx.dts
  485. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-gw53xx.dts 1970-01-01 01:00:00.000000000 +0100
  486. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-gw53xx.dts 2014-08-20 19:31:39.896842254 +0200
  487. @@ -0,0 +1,19 @@
  488. +/*
  489. + * Copyright 2013 Gateworks Corporation
  490. + *
  491. + * The code contained herein is licensed under the GNU General Public
  492. + * License. You may obtain a copy of the GNU General Public License
  493. + * Version 2 or later at the following locations:
  494. + *
  495. + * http://www.opensource.org/licenses/gpl-license.html
  496. + * http://www.gnu.org/copyleft/gpl.html
  497. + */
  498. +
  499. +/dts-v1/;
  500. +#include "imx6dl.dtsi"
  501. +#include "imx6qdl-gw53xx.dtsi"
  502. +
  503. +/ {
  504. + model = "Gateworks Ventana i.MX6 DualLite GW53XX";
  505. + compatible = "gw,imx6dl-gw53xx", "gw,ventana", "fsl,imx6dl";
  506. +};
  507. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-gw54xx.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-gw54xx.dts
  508. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-gw54xx.dts 1970-01-01 01:00:00.000000000 +0100
  509. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-gw54xx.dts 2014-08-20 19:31:39.896842254 +0200
  510. @@ -0,0 +1,19 @@
  511. +/*
  512. + * Copyright 2013 Gateworks Corporation
  513. + *
  514. + * The code contained herein is licensed under the GNU General Public
  515. + * License. You may obtain a copy of the GNU General Public License
  516. + * Version 2 or later at the following locations:
  517. + *
  518. + * http://www.opensource.org/licenses/gpl-license.html
  519. + * http://www.gnu.org/copyleft/gpl.html
  520. + */
  521. +
  522. +/dts-v1/;
  523. +#include "imx6dl.dtsi"
  524. +#include "imx6qdl-gw54xx.dtsi"
  525. +
  526. +/ {
  527. + model = "Gateworks Ventana i.MX6 DualLite GW54XX";
  528. + compatible = "gw,imx6dl-gw54xx", "gw,ventana", "fsl,imx6dl";
  529. +};
  530. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-hummingboard.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-hummingboard.dts
  531. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-07-31 23:51:43.000000000 +0200
  532. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-08-20 19:31:39.896842254 +0200
  533. @@ -1,163 +1,13 @@
  534. /*
  535. - * Copyright (C) 2013,2014 Russell King
  536. + * Copyright (C) 2014 Rabeeh Khoury (rabeeh@solid-run.com)
  537. + * Based on work by Russell King
  538. */
  539. /dts-v1/;
  540. #include "imx6dl.dtsi"
  541. -#include "imx6qdl-microsom.dtsi"
  542. -#include "imx6qdl-microsom-ar8035.dtsi"
  543. +#include "imx6qdl-hummingboard.dtsi"
  544. / {
  545. - model = "SolidRun HummingBoard DL/Solo";
  546. - compatible = "solidrun,hummingboard", "fsl,imx6dl";
  547. -
  548. - ir_recv: ir-receiver {
  549. - compatible = "gpio-ir-receiver";
  550. - gpios = <&gpio1 2 1>;
  551. - pinctrl-names = "default";
  552. - pinctrl-0 = <&pinctrl_hummingboard_gpio1_2>;
  553. - };
  554. -
  555. - regulators {
  556. - compatible = "simple-bus";
  557. -
  558. - reg_3p3v: 3p3v {
  559. - compatible = "regulator-fixed";
  560. - regulator-name = "3P3V";
  561. - regulator-min-microvolt = <3300000>;
  562. - regulator-max-microvolt = <3300000>;
  563. - regulator-always-on;
  564. - };
  565. -
  566. - reg_usbh1_vbus: usb-h1-vbus {
  567. - compatible = "regulator-fixed";
  568. - enable-active-high;
  569. - gpio = <&gpio1 0 0>;
  570. - pinctrl-names = "default";
  571. - pinctrl-0 = <&pinctrl_hummingboard_usbh1_vbus>;
  572. - regulator-name = "usb_h1_vbus";
  573. - regulator-min-microvolt = <5000000>;
  574. - regulator-max-microvolt = <5000000>;
  575. - };
  576. -
  577. - reg_usbotg_vbus: usb-otg-vbus {
  578. - compatible = "regulator-fixed";
  579. - enable-active-high;
  580. - gpio = <&gpio3 22 0>;
  581. - pinctrl-names = "default";
  582. - pinctrl-0 = <&pinctrl_hummingboard_usbotg_vbus>;
  583. - regulator-name = "usb_otg_vbus";
  584. - regulator-min-microvolt = <5000000>;
  585. - regulator-max-microvolt = <5000000>;
  586. - };
  587. - };
  588. -
  589. - sound-spdif {
  590. - compatible = "fsl,imx-audio-spdif";
  591. - model = "imx-spdif";
  592. - /* IMX6 doesn't implement this yet */
  593. - spdif-controller = <&spdif>;
  594. - spdif-out;
  595. - };
  596. -};
  597. -
  598. -&can1 {
  599. - pinctrl-names = "default";
  600. - pinctrl-0 = <&pinctrl_hummingboard_flexcan1>;
  601. - status = "okay";
  602. -};
  603. -
  604. -&i2c1 {
  605. - pinctrl-names = "default";
  606. - pinctrl-0 = <&pinctrl_hummingboard_i2c1>;
  607. -
  608. - /*
  609. - * Not fitted on Carrier-1 board... yet
  610. - status = "okay";
  611. -
  612. - rtc: pcf8523@68 {
  613. - compatible = "nxp,pcf8523";
  614. - reg = <0x68>;
  615. - };
  616. - */
  617. -};
  618. -
  619. -&iomuxc {
  620. - hummingboard {
  621. - pinctrl_hummingboard_flexcan1: hummingboard-flexcan1 {
  622. - fsl,pins = <
  623. - MX6QDL_PAD_SD3_CLK__FLEXCAN1_RX 0x80000000
  624. - MX6QDL_PAD_SD3_CMD__FLEXCAN1_TX 0x80000000
  625. - >;
  626. - };
  627. -
  628. - pinctrl_hummingboard_gpio1_2: hummingboard-gpio1_2 {
  629. - fsl,pins = <
  630. - MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000
  631. - >;
  632. - };
  633. -
  634. - pinctrl_hummingboard_i2c1: hummingboard-i2c1 {
  635. - fsl,pins = <
  636. - MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  637. - MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  638. - >;
  639. - };
  640. -
  641. - pinctrl_hummingboard_spdif: hummingboard-spdif {
  642. - fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
  643. - };
  644. -
  645. - pinctrl_hummingboard_usbh1_vbus: hummingboard-usbh1-vbus {
  646. - fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0>;
  647. - };
  648. -
  649. - pinctrl_hummingboard_usbotg_vbus: hummingboard-usbotg-vbus {
  650. - fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0>;
  651. - };
  652. -
  653. - pinctrl_hummingboard_usdhc2_aux: hummingboard-usdhc2-aux {
  654. - fsl,pins = <
  655. - MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
  656. - >;
  657. - };
  658. -
  659. - pinctrl_hummingboard_usdhc2: hummingboard-usdhc2 {
  660. - fsl,pins = <
  661. - MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  662. - MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  663. - MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  664. - MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  665. - MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  666. - MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
  667. - >;
  668. - };
  669. - };
  670. -};
  671. -
  672. -&spdif {
  673. - pinctrl-names = "default";
  674. - pinctrl-0 = <&pinctrl_hummingboard_spdif>;
  675. - status = "okay";
  676. -};
  677. -
  678. -&usbh1 {
  679. - vbus-supply = <&reg_usbh1_vbus>;
  680. - status = "okay";
  681. -};
  682. -
  683. -&usbotg {
  684. - vbus-supply = <&reg_usbotg_vbus>;
  685. - status = "okay";
  686. -};
  687. -
  688. -&usdhc2 {
  689. - pinctrl-names = "default";
  690. - pinctrl-0 = <
  691. - &pinctrl_hummingboard_usdhc2_aux
  692. - &pinctrl_hummingboard_usdhc2
  693. - >;
  694. - vmmc-supply = <&reg_3p3v>;
  695. - cd-gpios = <&gpio1 4 0>;
  696. - status = "okay";
  697. + model = "SolidRun HummingBoard Solo/DualLite";
  698. + compatible = "solidrun,hummingboard/dl", "fsl,imx6dl";
  699. };
  700. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-nitrogen6x.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-nitrogen6x.dts
  701. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-nitrogen6x.dts 1970-01-01 01:00:00.000000000 +0100
  702. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-nitrogen6x.dts 2014-08-20 19:31:39.896842254 +0200
  703. @@ -0,0 +1,21 @@
  704. +/*
  705. + * Copyright 2013 Boundary Devices, Inc.
  706. + * Copyright 2012 Freescale Semiconductor, Inc.
  707. + * Copyright 2011 Linaro Ltd.
  708. + *
  709. + * The code contained herein is licensed under the GNU General Public
  710. + * License. You may obtain a copy of the GNU General Public License
  711. + * Version 2 or later at the following locations:
  712. + *
  713. + * http://www.opensource.org/licenses/gpl-license.html
  714. + * http://www.gnu.org/copyleft/gpl.html
  715. + */
  716. +
  717. +/dts-v1/;
  718. +#include "imx6dl.dtsi"
  719. +#include "imx6qdl-nitrogen6x.dtsi"
  720. +
  721. +/ {
  722. + model = "Freescale i.MX6 DualLite Nitrogen6x Board";
  723. + compatible = "fsl,imx6dl-nitrogen6x", "fsl,imx6dl";
  724. +};
  725. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts
  726. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts 1970-01-01 01:00:00.000000000 +0100
  727. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts 2014-08-20 19:31:39.896842254 +0200
  728. @@ -0,0 +1,19 @@
  729. +/*
  730. + * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
  731. + *
  732. + * The code contained herein is licensed under the GNU General Public
  733. + * License. You may obtain a copy of the GNU General Public License
  734. + * Version 2 or later at the following locations:
  735. + *
  736. + * http://www.opensource.org/licenses/gpl-license.html
  737. + * http://www.gnu.org/copyleft/gpl.html
  738. + */
  739. +
  740. +/dts-v1/;
  741. +#include "imx6dl-phytec-pfla02.dtsi"
  742. +#include "imx6qdl-phytec-pbab01.dtsi"
  743. +
  744. +/ {
  745. + model = "Phytec phyFLEX-i.MX6 DualLite/Solo Carrier-Board";
  746. + compatible = "phytec,imx6dl-pbab01", "phytec,imx6dl-pfla02", "fsl,imx6dl";
  747. +};
  748. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi
  749. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi 1970-01-01 01:00:00.000000000 +0100
  750. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi 2014-08-20 19:31:39.896842254 +0200
  751. @@ -0,0 +1,22 @@
  752. +/*
  753. + * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
  754. + *
  755. + * The code contained herein is licensed under the GNU General Public
  756. + * License. You may obtain a copy of the GNU General Public License
  757. + * Version 2 or later at the following locations:
  758. + *
  759. + * http://www.opensource.org/licenses/gpl-license.html
  760. + * http://www.gnu.org/copyleft/gpl.html
  761. + */
  762. +
  763. +#include "imx6dl.dtsi"
  764. +#include "imx6qdl-phytec-pfla02.dtsi"
  765. +
  766. +/ {
  767. + model = "Phytec phyFLEX-i.MX6 DualLite/Solo";
  768. + compatible = "phytec,imx6dl-pfla02", "fsl,imx6dl";
  769. +
  770. + memory {
  771. + reg = <0x10000000 0x20000000>;
  772. + };
  773. +};
  774. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-pinfunc.h linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-pinfunc.h
  775. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-pinfunc.h 2014-07-31 23:51:43.000000000 +0200
  776. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-pinfunc.h 2014-08-20 19:31:39.896842254 +0200
  777. @@ -755,6 +755,7 @@
  778. #define MX6QDL_PAD_GPIO_5__I2C3_SCL 0x230 0x600 0x878 0x6 0x2
  779. #define MX6QDL_PAD_GPIO_5__ARM_EVENTI 0x230 0x600 0x000 0x7 0x0
  780. #define MX6QDL_PAD_GPIO_6__ESAI_TX_CLK 0x234 0x604 0x840 0x0 0x1
  781. +#define MX6QDL_PAD_GPIO_6__ENET_IRQ 0x234 0x604 0x03c 0x11 0xff000609
  782. #define MX6QDL_PAD_GPIO_6__I2C3_SDA 0x234 0x604 0x87c 0x2 0x2
  783. #define MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x234 0x604 0x000 0x5 0x0
  784. #define MX6QDL_PAD_GPIO_6__SD2_LCTL 0x234 0x604 0x000 0x6 0x0
  785. @@ -950,6 +951,7 @@
  786. #define MX6QDL_PAD_RGMII_TXC__GPIO6_IO19 0x2d8 0x6c0 0x000 0x5 0x0
  787. #define MX6QDL_PAD_RGMII_TXC__XTALOSC_REF_CLK_24M 0x2d8 0x6c0 0x000 0x7 0x0
  788. #define MX6QDL_PAD_SD1_CLK__SD1_CLK 0x2dc 0x6c4 0x928 0x0 0x1
  789. +#define MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT 0x2dc 0x6c4 0x000 0x2 0x0
  790. #define MX6QDL_PAD_SD1_CLK__GPT_CLKIN 0x2dc 0x6c4 0x000 0x3 0x0
  791. #define MX6QDL_PAD_SD1_CLK__GPIO1_IO20 0x2dc 0x6c4 0x000 0x5 0x0
  792. #define MX6QDL_PAD_SD1_CMD__SD1_CMD 0x2e0 0x6c8 0x000 0x0 0x0
  793. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-sabreauto.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-sabreauto.dts
  794. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-sabreauto.dts 2014-07-31 23:51:43.000000000 +0200
  795. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-sabreauto.dts 2014-08-20 19:23:45.542811617 +0200
  796. @@ -15,3 +15,16 @@
  797. model = "Freescale i.MX6 DualLite/Solo SABRE Automotive Board";
  798. compatible = "fsl,imx6dl-sabreauto", "fsl,imx6dl";
  799. };
  800. +
  801. +&ldb {
  802. + ipu_id = <0>;
  803. + sec_ipu_id = <0>;
  804. +};
  805. +
  806. +&mxcfb1 {
  807. + status = "okay";
  808. +};
  809. +
  810. +&mxcfb2 {
  811. + status = "okay";
  812. +};
  813. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-sabrelite.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-sabrelite.dts
  814. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-sabrelite.dts 1970-01-01 01:00:00.000000000 +0100
  815. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-sabrelite.dts 2014-08-20 19:31:39.896842254 +0200
  816. @@ -0,0 +1,20 @@
  817. +/*
  818. + * Copyright 2011 Freescale Semiconductor, Inc.
  819. + * Copyright 2011 Linaro Ltd.
  820. + *
  821. + * The code contained herein is licensed under the GNU General Public
  822. + * License. You may obtain a copy of the GNU General Public License
  823. + * Version 2 or later at the following locations:
  824. + *
  825. + * http://www.opensource.org/licenses/gpl-license.html
  826. + * http://www.gnu.org/copyleft/gpl.html
  827. + */
  828. +
  829. +/dts-v1/;
  830. +#include "imx6dl.dtsi"
  831. +#include "imx6qdl-sabrelite.dtsi"
  832. +
  833. +/ {
  834. + model = "Freescale i.MX6 DualLite SABRE Lite Board";
  835. + compatible = "fsl,imx6dl-sabrelite", "fsl,imx6dl";
  836. +};
  837. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-sabresd.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-sabresd.dts
  838. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-sabresd.dts 2014-07-31 23:51:43.000000000 +0200
  839. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-sabresd.dts 2014-08-20 19:31:39.896842254 +0200
  840. @@ -15,3 +15,20 @@
  841. model = "Freescale i.MX6 DualLite SABRE Smart Device Board";
  842. compatible = "fsl,imx6dl-sabresd", "fsl,imx6dl";
  843. };
  844. +
  845. +&ldb {
  846. + ipu_id = <0>;
  847. + sec_ipu_id = <0>;
  848. +};
  849. +
  850. +&pxp {
  851. + status = "okay";
  852. +};
  853. +
  854. +&mxcfb1 {
  855. + status = "okay";
  856. +};
  857. +
  858. +&mxcfb2 {
  859. + status = "okay";
  860. +};
  861. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts
  862. --- linux-3.14.15/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts 1970-01-01 01:00:00.000000000 +0100
  863. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts 2014-08-20 19:31:39.896842254 +0200
  864. @@ -0,0 +1,19 @@
  865. +/*
  866. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  867. + *
  868. + * This program is free software; you can redistribute it and/or modify
  869. + * it under the terms of the GNU General Public License version 2 as
  870. + * published by the Free Software Foundation.
  871. + */
  872. +
  873. +#include "imx6dl-sabresd.dts"
  874. +
  875. +&hdmi_video {
  876. + pinctrl-names = "default";
  877. + pinctrl-0 = <&pinctrl_hdmi_hdcp>;
  878. + fsl,hdcp;
  879. +};
  880. +
  881. +&i2c2 {
  882. + status = "disable";
  883. +};
  884. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-arm2.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-arm2.dts
  885. --- linux-3.14.15/arch/arm/boot/dts/imx6q-arm2.dts 2014-07-31 23:51:43.000000000 +0200
  886. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-arm2.dts 2014-08-20 19:31:39.900842271 +0200
  887. @@ -23,14 +23,27 @@
  888. regulators {
  889. compatible = "simple-bus";
  890. + #address-cells = <1>;
  891. + #size-cells = <0>;
  892. - reg_3p3v: 3p3v {
  893. + reg_3p3v: regulator@0 {
  894. compatible = "regulator-fixed";
  895. + reg = <0>;
  896. regulator-name = "3P3V";
  897. regulator-min-microvolt = <3300000>;
  898. regulator-max-microvolt = <3300000>;
  899. regulator-always-on;
  900. };
  901. +
  902. + reg_usb_otg_vbus: regulator@1 {
  903. + compatible = "regulator-fixed";
  904. + reg = <1>;
  905. + regulator-name = "usb_otg_vbus";
  906. + regulator-min-microvolt = <5000000>;
  907. + regulator-max-microvolt = <5000000>;
  908. + gpio = <&gpio3 22 0>;
  909. + enable-active-high;
  910. + };
  911. };
  912. leds {
  913. @@ -46,7 +59,7 @@
  914. &gpmi {
  915. pinctrl-names = "default";
  916. - pinctrl-0 = <&pinctrl_gpmi_nand_1>;
  917. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  918. status = "disabled"; /* gpmi nand conflicts with SD */
  919. };
  920. @@ -54,28 +67,131 @@
  921. pinctrl-names = "default";
  922. pinctrl-0 = <&pinctrl_hog>;
  923. - hog {
  924. + imx6q-arm2 {
  925. pinctrl_hog: hoggrp {
  926. fsl,pins = <
  927. MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x80000000
  928. >;
  929. };
  930. - };
  931. - arm2 {
  932. - pinctrl_usdhc3_arm2: usdhc3grp-arm2 {
  933. + pinctrl_enet: enetgrp {
  934. + fsl,pins = <
  935. + MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
  936. + MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0
  937. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  938. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  939. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  940. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  941. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  942. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  943. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  944. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  945. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  946. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  947. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  948. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  949. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  950. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  951. + >;
  952. + };
  953. +
  954. + pinctrl_gpmi_nand: gpminandgrp {
  955. + fsl,pins = <
  956. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  957. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  958. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  959. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  960. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  961. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  962. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  963. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  964. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  965. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  966. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  967. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  968. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  969. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  970. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  971. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  972. + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  973. + >;
  974. + };
  975. +
  976. + pinctrl_uart2: uart2grp {
  977. + fsl,pins = <
  978. + MX6QDL_PAD_EIM_D26__UART2_RX_DATA 0x1b0b1
  979. + MX6QDL_PAD_EIM_D27__UART2_TX_DATA 0x1b0b1
  980. + MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B 0x1b0b1
  981. + MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B 0x1b0b1
  982. + >;
  983. + };
  984. +
  985. + pinctrl_uart4: uart4grp {
  986. + fsl,pins = <
  987. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  988. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  989. + >;
  990. + };
  991. +
  992. + pinctrl_usbotg: usbotggrp {
  993. + fsl,pins = <
  994. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  995. + >;
  996. + };
  997. +
  998. + pinctrl_usdhc3: usdhc3grp {
  999. + fsl,pins = <
  1000. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  1001. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  1002. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  1003. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  1004. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  1005. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  1006. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
  1007. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
  1008. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
  1009. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
  1010. + >;
  1011. + };
  1012. +
  1013. + pinctrl_usdhc3_cdwp: usdhc3cdwp {
  1014. fsl,pins = <
  1015. MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
  1016. MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
  1017. >;
  1018. };
  1019. +
  1020. + pinctrl_usdhc4: usdhc4grp {
  1021. + fsl,pins = <
  1022. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  1023. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  1024. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  1025. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  1026. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  1027. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  1028. + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  1029. + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  1030. + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  1031. + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  1032. + >;
  1033. + };
  1034. };
  1035. };
  1036. &fec {
  1037. pinctrl-names = "default";
  1038. - pinctrl-0 = <&pinctrl_enet_2>;
  1039. + pinctrl-0 = <&pinctrl_enet>;
  1040. phy-mode = "rgmii";
  1041. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  1042. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  1043. + status = "okay";
  1044. +};
  1045. +
  1046. +&usbotg {
  1047. + vbus-supply = <&reg_usb_otg_vbus>;
  1048. + pinctrl-names = "default";
  1049. + pinctrl-0 = <&pinctrl_usbotg>;
  1050. + disable-over-current;
  1051. status = "okay";
  1052. };
  1053. @@ -84,8 +200,8 @@
  1054. wp-gpios = <&gpio6 14 0>;
  1055. vmmc-supply = <&reg_3p3v>;
  1056. pinctrl-names = "default";
  1057. - pinctrl-0 = <&pinctrl_usdhc3_1
  1058. - &pinctrl_usdhc3_arm2>;
  1059. + pinctrl-0 = <&pinctrl_usdhc3
  1060. + &pinctrl_usdhc3_cdwp>;
  1061. status = "okay";
  1062. };
  1063. @@ -93,13 +209,13 @@
  1064. non-removable;
  1065. vmmc-supply = <&reg_3p3v>;
  1066. pinctrl-names = "default";
  1067. - pinctrl-0 = <&pinctrl_usdhc4_1>;
  1068. + pinctrl-0 = <&pinctrl_usdhc4>;
  1069. status = "okay";
  1070. };
  1071. &uart2 {
  1072. pinctrl-names = "default";
  1073. - pinctrl-0 = <&pinctrl_uart2_2>;
  1074. + pinctrl-0 = <&pinctrl_uart2>;
  1075. fsl,dte-mode;
  1076. fsl,uart-has-rtscts;
  1077. status = "okay";
  1078. @@ -107,6 +223,6 @@
  1079. &uart4 {
  1080. pinctrl-names = "default";
  1081. - pinctrl-0 = <&pinctrl_uart4_1>;
  1082. + pinctrl-0 = <&pinctrl_uart4>;
  1083. status = "okay";
  1084. };
  1085. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-arm2-hsic.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-arm2-hsic.dts
  1086. --- linux-3.14.15/arch/arm/boot/dts/imx6q-arm2-hsic.dts 1970-01-01 01:00:00.000000000 +0100
  1087. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-arm2-hsic.dts 2014-08-20 19:31:39.896842254 +0200
  1088. @@ -0,0 +1,32 @@
  1089. +/*
  1090. + * Copyright 2013 Freescale Semiconductor, Inc.
  1091. + *
  1092. + * The code contained herein is licensed under the GNU General Public
  1093. + * License. You may obtain a copy of the GNU General Public License
  1094. + * Version 2 or later at the following locations:
  1095. + *
  1096. + * http://www.opensource.org/licenses/gpl-license.html
  1097. + * http://www.gnu.org/copyleft/gpl.html
  1098. + */
  1099. +
  1100. +#include "imx6q-arm2.dts"
  1101. +
  1102. +&fec {
  1103. + status = "disabled";
  1104. +};
  1105. +
  1106. +&usbh2 {
  1107. + pinctrl-names = "idle", "active";
  1108. + pinctrl-0 = <&pinctrl_usbh2_1>;
  1109. + pinctrl-1 = <&pinctrl_usbh2_2>;
  1110. + osc-clkgate-delay = <0x3>;
  1111. + status = "okay";
  1112. +};
  1113. +
  1114. +&usbh3 {
  1115. + pinctrl-names = "idle", "active";
  1116. + pinctrl-0 = <&pinctrl_usbh3_1>;
  1117. + pinctrl-1 = <&pinctrl_usbh3_2>;
  1118. + osc-clkgate-delay = <0x3>;
  1119. + status = "okay";
  1120. +};
  1121. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-cm-fx6.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-cm-fx6.dts
  1122. --- linux-3.14.15/arch/arm/boot/dts/imx6q-cm-fx6.dts 1970-01-01 01:00:00.000000000 +0100
  1123. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-cm-fx6.dts 2014-08-20 19:31:39.900842271 +0200
  1124. @@ -0,0 +1,107 @@
  1125. +/*
  1126. + * Copyright 2013 CompuLab Ltd.
  1127. + *
  1128. + * Author: Valentin Raevsky <valentin@compulab.co.il>
  1129. + *
  1130. + * The code contained herein is licensed under the GNU General Public
  1131. + * License. You may obtain a copy of the GNU General Public License
  1132. + * Version 2 or later at the following locations:
  1133. + *
  1134. + * http://www.opensource.org/licenses/gpl-license.html
  1135. + * http://www.gnu.org/copyleft/gpl.html
  1136. + */
  1137. +
  1138. +/dts-v1/;
  1139. +#include "imx6q.dtsi"
  1140. +
  1141. +/ {
  1142. + model = "CompuLab CM-FX6";
  1143. + compatible = "compulab,cm-fx6", "fsl,imx6q";
  1144. +
  1145. + memory {
  1146. + reg = <0x10000000 0x80000000>;
  1147. + };
  1148. +
  1149. + leds {
  1150. + compatible = "gpio-leds";
  1151. +
  1152. + heartbeat-led {
  1153. + label = "Heartbeat";
  1154. + gpios = <&gpio2 31 0>;
  1155. + linux,default-trigger = "heartbeat";
  1156. + };
  1157. + };
  1158. +};
  1159. +
  1160. +&fec {
  1161. + pinctrl-names = "default";
  1162. + pinctrl-0 = <&pinctrl_enet>;
  1163. + phy-mode = "rgmii";
  1164. + status = "okay";
  1165. +};
  1166. +
  1167. +&gpmi {
  1168. + pinctrl-names = "default";
  1169. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  1170. + status = "okay";
  1171. +};
  1172. +
  1173. +&iomuxc {
  1174. + imx6q-cm-fx6 {
  1175. + pinctrl_enet: enetgrp {
  1176. + fsl,pins = <
  1177. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  1178. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  1179. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  1180. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  1181. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  1182. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  1183. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  1184. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  1185. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  1186. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  1187. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  1188. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  1189. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  1190. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  1191. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  1192. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  1193. + >;
  1194. + };
  1195. +
  1196. + pinctrl_gpmi_nand: gpminandgrp {
  1197. + fsl,pins = <
  1198. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  1199. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  1200. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  1201. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  1202. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  1203. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  1204. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  1205. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  1206. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  1207. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  1208. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  1209. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  1210. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  1211. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  1212. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  1213. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  1214. + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  1215. + >;
  1216. + };
  1217. +
  1218. + pinctrl_uart4: uart4grp {
  1219. + fsl,pins = <
  1220. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  1221. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  1222. + >;
  1223. + };
  1224. + };
  1225. +};
  1226. +
  1227. +&uart4 {
  1228. + pinctrl-names = "default";
  1229. + pinctrl-0 = <&pinctrl_uart4>;
  1230. + status = "okay";
  1231. +};
  1232. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-cubox-i.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-cubox-i.dts
  1233. --- linux-3.14.15/arch/arm/boot/dts/imx6q-cubox-i.dts 2014-07-31 23:51:43.000000000 +0200
  1234. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-cubox-i.dts 2014-08-20 19:31:39.900842271 +0200
  1235. @@ -13,4 +13,8 @@
  1236. &sata {
  1237. status = "okay";
  1238. + fsl,transmit-level-mV = <1104>;
  1239. + fsl,transmit-boost-mdB = <0>;
  1240. + fsl,transmit-atten-16ths = <9>;
  1241. + fsl,no-spread-spectrum;
  1242. };
  1243. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
  1244. --- linux-3.14.15/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts 1970-01-01 01:00:00.000000000 +0100
  1245. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts 2014-08-20 19:31:39.900842271 +0200
  1246. @@ -0,0 +1,23 @@
  1247. +/*
  1248. + * Copyright 2013 Sascha Hauer <s.hauer@pengutronix.de>
  1249. + *
  1250. + * The code contained herein is licensed under the GNU General Public
  1251. + * License. You may obtain a copy of the GNU General Public License
  1252. + * Version 2 or later at the following locations:
  1253. + *
  1254. + * http://www.opensource.org/licenses/gpl-license.html
  1255. + * http://www.gnu.org/copyleft/gpl.html
  1256. + */
  1257. +
  1258. +#ifndef __DTS_V1__
  1259. +#define __DTS_V1__
  1260. +/dts-v1/;
  1261. +#endif
  1262. +
  1263. +#include "imx6q.dtsi"
  1264. +#include "imx6qdl-dfi-fs700-m60.dtsi"
  1265. +
  1266. +/ {
  1267. + model = "DFI FS700-M60-6QD i.MX6qd Q7 Board";
  1268. + compatible = "dfi,fs700-m60-6qd", "dfi,fs700e-m60", "fsl,imx6q";
  1269. +};
  1270. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
  1271. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-07-31 23:51:43.000000000 +0200
  1272. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-08-20 19:31:39.900842271 +0200
  1273. @@ -5,6 +5,10 @@
  1274. #include "imx6qdl-microsom-ar8035.dtsi"
  1275. / {
  1276. + aliases {
  1277. + mxcfb0 = &mxcfb1;
  1278. + };
  1279. +
  1280. ir_recv: ir-receiver {
  1281. compatible = "gpio-ir-receiver";
  1282. gpios = <&gpio3 9 1>;
  1283. @@ -12,6 +16,19 @@
  1284. pinctrl-0 = <&pinctrl_cubox_i_ir>;
  1285. };
  1286. + pwmleds {
  1287. + compatible = "pwm-leds";
  1288. + pinctrl-names = "default";
  1289. + pinctrl-0 = <&pinctrl_cubox_i_pwm1>;
  1290. +
  1291. + front {
  1292. + active-low;
  1293. + label = "imx6:red:front";
  1294. + max-brightness = <248>;
  1295. + pwms = <&pwm1 0 50000>;
  1296. + };
  1297. + };
  1298. +
  1299. regulators {
  1300. compatible = "simple-bus";
  1301. @@ -49,10 +66,62 @@
  1302. sound-spdif {
  1303. compatible = "fsl,imx-audio-spdif";
  1304. model = "imx-spdif";
  1305. - /* IMX6 doesn't implement this yet */
  1306. spdif-controller = <&spdif>;
  1307. spdif-out;
  1308. };
  1309. +
  1310. + sound-hdmi {
  1311. + compatible = "fsl,imx6q-audio-hdmi",
  1312. + "fsl,imx-audio-hdmi";
  1313. + model = "imx-audio-hdmi";
  1314. + hdmi-controller = <&hdmi_audio>;
  1315. + };
  1316. +
  1317. + mxcfb1: fb@0 {
  1318. + compatible = "fsl,mxc_sdc_fb";
  1319. + disp_dev = "hdmi";
  1320. + interface_pix_fmt = "RGB24";
  1321. + mode_str ="1920x1080M@60";
  1322. + default_bpp = <32>;
  1323. + int_clk = <0>;
  1324. + late_init = <0>;
  1325. + status = "okay";
  1326. + };
  1327. +};
  1328. +
  1329. +&hdmi_core {
  1330. + ipu_id = <0>;
  1331. + disp_id = <0>;
  1332. + status = "okay";
  1333. +};
  1334. +
  1335. +&hdmi_video {
  1336. + fsl,phy_reg_vlev = <0x0294>;
  1337. + fsl,phy_reg_cksymtx = <0x800d>;
  1338. + status = "okay";
  1339. +};
  1340. +
  1341. +&hdmi_audio {
  1342. + status = "okay";
  1343. +};
  1344. +
  1345. +&hdmi_cec {
  1346. + pinctrl-names = "default";
  1347. + pinctrl-0 = <&pinctrl_cubox_i_hdmi>;
  1348. + status = "okay";
  1349. +};
  1350. +
  1351. +&i2c2 {
  1352. + clock-frequency = <100000>;
  1353. + pinctrl-names = "default";
  1354. + pinctrl-0 = <&pinctrl_cubox_i_i2c2>;
  1355. +
  1356. + status = "okay";
  1357. +
  1358. + ddc: imx6_hdmi_i2c@50 {
  1359. + compatible = "fsl,imx6-hdmi-i2c";
  1360. + reg = <0x50>;
  1361. + };
  1362. };
  1363. &i2c3 {
  1364. @@ -69,6 +138,19 @@
  1365. &iomuxc {
  1366. cubox_i {
  1367. + pinctrl_cubox_i_hdmi: cubox-i-hdmi {
  1368. + fsl,pins = <
  1369. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  1370. + >;
  1371. + };
  1372. +
  1373. + pinctrl_cubox_i_i2c2: cubox-i-i2c2 {
  1374. + fsl,pins = <
  1375. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  1376. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  1377. + >;
  1378. + };
  1379. +
  1380. pinctrl_cubox_i_i2c3: cubox-i-i2c3 {
  1381. fsl,pins = <
  1382. MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
  1383. @@ -82,16 +164,35 @@
  1384. >;
  1385. };
  1386. + pinctrl_cubox_i_pwm1: cubox-i-pwm1-front-led {
  1387. + fsl,pins = <MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x1b0b0>;
  1388. + };
  1389. +
  1390. pinctrl_cubox_i_spdif: cubox-i-spdif {
  1391. fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
  1392. };
  1393. + pinctrl_cubox_i_usbh1: cubox-i-usbh1 {
  1394. + fsl,pins = <MX6QDL_PAD_GPIO_3__USB_H1_OC 0x1b0b0>;
  1395. + };
  1396. +
  1397. pinctrl_cubox_i_usbh1_vbus: cubox-i-usbh1-vbus {
  1398. - fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x4001b0b0>;
  1399. + fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0>;
  1400. + };
  1401. +
  1402. + pinctrl_cubox_i_usbotg: cubox-i-usbotg {
  1403. + /*
  1404. + * The Cubox-i pulls ID low, but as it's pointless
  1405. + * leaving it as a pull-up, even if it is just 10uA.
  1406. + */
  1407. + fsl,pins = <
  1408. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059
  1409. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  1410. + >;
  1411. };
  1412. pinctrl_cubox_i_usbotg_vbus: cubox-i-usbotg-vbus {
  1413. - fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x4001b0b0>;
  1414. + fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0>;
  1415. };
  1416. pinctrl_cubox_i_usdhc2_aux: cubox-i-usdhc2-aux {
  1417. @@ -111,29 +212,76 @@
  1418. MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
  1419. >;
  1420. };
  1421. +
  1422. + pinctrl_cubox_i_usdhc2_100mhz: cubox-i-usdhc2-100mhz {
  1423. + fsl,pins = <
  1424. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170b9
  1425. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100b9
  1426. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
  1427. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
  1428. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
  1429. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x130b9
  1430. + >;
  1431. + };
  1432. +
  1433. + pinctrl_cubox_i_usdhc2_200mhz: cubox-i-usdhc2-200mhz {
  1434. + fsl,pins = <
  1435. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170f9
  1436. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100f9
  1437. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
  1438. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
  1439. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
  1440. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x130f9
  1441. + >;
  1442. + };
  1443. };
  1444. };
  1445. &spdif {
  1446. pinctrl-names = "default";
  1447. pinctrl-0 = <&pinctrl_cubox_i_spdif>;
  1448. + clocks = <&clks 197>, <&clks 0>,
  1449. + <&clks 197>, <&clks 0>,
  1450. + <&clks 0>, <&clks 0>,
  1451. + <&clks 0>, <&clks 0>,
  1452. + <&clks 0>;
  1453. + clock-names = "core", "rxtx0",
  1454. + "rxtx1", "rxtx2",
  1455. + "rxtx3", "rxtx4",
  1456. + "rxtx5", "rxtx6",
  1457. + "rxtx7";
  1458. status = "okay";
  1459. };
  1460. &usbh1 {
  1461. + pinctrl-names = "default";
  1462. + pinctrl-0 = <&pinctrl_cubox_i_usbh1>;
  1463. vbus-supply = <&reg_usbh1_vbus>;
  1464. status = "okay";
  1465. };
  1466. &usbotg {
  1467. + pinctrl-names = "default";
  1468. + pinctrl-0 = <&pinctrl_cubox_i_usbotg>;
  1469. vbus-supply = <&reg_usbotg_vbus>;
  1470. status = "okay";
  1471. };
  1472. &usdhc2 {
  1473. - pinctrl-names = "default";
  1474. + pinctrl-names = "default", "state_100mhz", "state_200mhz";
  1475. pinctrl-0 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2>;
  1476. + pinctrl-1 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2_100mhz>;
  1477. + pinctrl-2 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2_200mhz>;
  1478. vmmc-supply = <&reg_3p3v>;
  1479. cd-gpios = <&gpio1 4 0>;
  1480. + no-1-8-v;
  1481. status = "okay";
  1482. };
  1483. +
  1484. +
  1485. +&gpc {
  1486. + fsl,cpu_pupscr_sw2iso = <0xf>;
  1487. + fsl,cpu_pupscr_sw = <0xf>;
  1488. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  1489. + fsl,cpu_pdnscr_iso = <0x1>;
  1490. +};
  1491. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
  1492. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi 1970-01-01 01:00:00.000000000 +0100
  1493. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi 2014-08-20 19:31:39.900842271 +0200
  1494. @@ -0,0 +1,199 @@
  1495. +/ {
  1496. + regulators {
  1497. + compatible = "simple-bus";
  1498. + #address-cells = <1>;
  1499. + #size-cells = <0>;
  1500. +
  1501. + dummy_reg: regulator@0 {
  1502. + compatible = "regulator-fixed";
  1503. + reg = <0>;
  1504. + regulator-name = "dummy-supply";
  1505. + };
  1506. +
  1507. + reg_usb_otg_vbus: regulator@1 {
  1508. + compatible = "regulator-fixed";
  1509. + reg = <1>;
  1510. + regulator-name = "usb_otg_vbus";
  1511. + regulator-min-microvolt = <5000000>;
  1512. + regulator-max-microvolt = <5000000>;
  1513. + gpio = <&gpio3 22 0>;
  1514. + enable-active-high;
  1515. + };
  1516. + };
  1517. +
  1518. + chosen {
  1519. + stdout-path = &uart1;
  1520. + };
  1521. +};
  1522. +
  1523. +&ecspi3 {
  1524. + fsl,spi-num-chipselects = <1>;
  1525. + cs-gpios = <&gpio4 24 0>;
  1526. + pinctrl-names = "default";
  1527. + pinctrl-0 = <&pinctrl_ecspi3>;
  1528. + status = "okay";
  1529. +
  1530. + flash: m25p80@0 {
  1531. + #address-cells = <1>;
  1532. + #size-cells = <1>;
  1533. + compatible = "sst,sst25vf040b", "m25p80";
  1534. + spi-max-frequency = <20000000>;
  1535. + reg = <0>;
  1536. + };
  1537. +};
  1538. +
  1539. +&fec {
  1540. + pinctrl-names = "default";
  1541. + pinctrl-0 = <&pinctrl_enet>;
  1542. + status = "okay";
  1543. + phy-mode = "rgmii";
  1544. +};
  1545. +
  1546. +&iomuxc {
  1547. + pinctrl-names = "default";
  1548. + pinctrl-0 = <&pinctrl_hog>;
  1549. +
  1550. + imx6qdl-dfi-fs700-m60 {
  1551. + pinctrl_hog: hoggrp {
  1552. + fsl,pins = <
  1553. + MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
  1554. + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x80000000 /* PMIC irq */
  1555. + MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x80000000 /* MAX11801 irq */
  1556. + MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x000030b0 /* Backlight enable */
  1557. + >;
  1558. + };
  1559. +
  1560. + pinctrl_enet: enetgrp {
  1561. + fsl,pins = <
  1562. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  1563. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  1564. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  1565. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  1566. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  1567. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  1568. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  1569. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  1570. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  1571. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  1572. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  1573. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  1574. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  1575. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  1576. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  1577. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  1578. + >;
  1579. + };
  1580. +
  1581. + pinctrl_i2c2: i2c2grp {
  1582. + fsl,pins = <
  1583. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  1584. + MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
  1585. + >;
  1586. + };
  1587. +
  1588. + pinctrl_uart1: uart1grp {
  1589. + fsl,pins = <
  1590. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  1591. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  1592. + >;
  1593. + };
  1594. +
  1595. + pinctrl_usbotg: usbotggrp {
  1596. + fsl,pins = <
  1597. + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  1598. + >;
  1599. + };
  1600. +
  1601. + pinctrl_usdhc2: usdhc2grp {
  1602. + fsl,pins = <
  1603. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  1604. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  1605. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  1606. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  1607. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  1608. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  1609. + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000 /* card detect */
  1610. + >;
  1611. + };
  1612. +
  1613. + pinctrl_usdhc3: usdhc3grp {
  1614. + fsl,pins = <
  1615. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  1616. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  1617. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  1618. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  1619. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  1620. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  1621. + >;
  1622. + };
  1623. +
  1624. + pinctrl_usdhc4: usdhc4grp {
  1625. + fsl,pins = <
  1626. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  1627. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  1628. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  1629. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  1630. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  1631. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  1632. + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  1633. + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  1634. + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  1635. + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  1636. + >;
  1637. + };
  1638. +
  1639. + pinctrl_ecspi3: ecspi3grp {
  1640. + fsl,pins = <
  1641. + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
  1642. + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
  1643. + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
  1644. + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
  1645. + >;
  1646. + };
  1647. + };
  1648. +};
  1649. +
  1650. +&i2c2 {
  1651. + pinctrl-names = "default";
  1652. + pinctrl-0 = <&pinctrl_i2c2>;
  1653. + status = "okay";
  1654. +};
  1655. +
  1656. +&uart1 {
  1657. + pinctrl-names = "default";
  1658. + pinctrl-0 = <&pinctrl_uart1>;
  1659. + status = "okay";
  1660. +};
  1661. +
  1662. +&usbh1 {
  1663. + status = "okay";
  1664. +};
  1665. +
  1666. +&usbotg {
  1667. + vbus-supply = <&reg_usb_otg_vbus>;
  1668. + pinctrl-names = "default";
  1669. + pinctrl-0 = <&pinctrl_usbotg>;
  1670. + disable-over-current;
  1671. + dr_mode = "host";
  1672. + status = "okay";
  1673. +};
  1674. +
  1675. +&usdhc2 { /* module slot */
  1676. + pinctrl-names = "default";
  1677. + pinctrl-0 = <&pinctrl_usdhc2>;
  1678. + cd-gpios = <&gpio2 2 0>;
  1679. + status = "okay";
  1680. +};
  1681. +
  1682. +&usdhc3 { /* baseboard slot */
  1683. + pinctrl-names = "default";
  1684. + pinctrl-0 = <&pinctrl_usdhc3>;
  1685. +};
  1686. +
  1687. +&usdhc4 { /* eMMC */
  1688. + pinctrl-names = "default";
  1689. + pinctrl-0 = <&pinctrl_usdhc4>;
  1690. + bus-width = <8>;
  1691. + non-removable;
  1692. + status = "okay";
  1693. +};
  1694. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl.dtsi
  1695. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl.dtsi 2014-07-31 23:51:43.000000000 +0200
  1696. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl.dtsi 2014-08-20 19:31:39.904842290 +0200
  1697. @@ -10,10 +10,16 @@
  1698. * http://www.gnu.org/copyleft/gpl.html
  1699. */
  1700. +#include <dt-bindings/interrupt-controller/arm-gic.h>
  1701. +
  1702. #include "skeleton.dtsi"
  1703. +#include <dt-bindings/gpio/gpio.h>
  1704. / {
  1705. aliases {
  1706. + ethernet0 = &fec;
  1707. + can0 = &can1;
  1708. + can1 = &can2;
  1709. gpio0 = &gpio1;
  1710. gpio1 = &gpio2;
  1711. gpio2 = &gpio3;
  1712. @@ -24,6 +30,11 @@
  1713. i2c0 = &i2c1;
  1714. i2c1 = &i2c2;
  1715. i2c2 = &i2c3;
  1716. + ipu0 = &ipu1;
  1717. + mmc0 = &usdhc1;
  1718. + mmc1 = &usdhc2;
  1719. + mmc2 = &usdhc3;
  1720. + mmc3 = &usdhc4;
  1721. serial0 = &uart1;
  1722. serial1 = &uart2;
  1723. serial2 = &uart3;
  1724. @@ -33,13 +44,13 @@
  1725. spi1 = &ecspi2;
  1726. spi2 = &ecspi3;
  1727. spi3 = &ecspi4;
  1728. + usbphy0 = &usbphy1;
  1729. + usbphy1 = &usbphy2;
  1730. };
  1731. intc: interrupt-controller@00a01000 {
  1732. compatible = "arm,cortex-a9-gic";
  1733. #interrupt-cells = <3>;
  1734. - #address-cells = <1>;
  1735. - #size-cells = <1>;
  1736. interrupt-controller;
  1737. reg = <0x00a01000 0x1000>,
  1738. <0x00a00100 0x100>;
  1739. @@ -51,20 +62,27 @@
  1740. ckil {
  1741. compatible = "fsl,imx-ckil", "fixed-clock";
  1742. + #clock-cells = <0>;
  1743. clock-frequency = <32768>;
  1744. };
  1745. ckih1 {
  1746. compatible = "fsl,imx-ckih1", "fixed-clock";
  1747. + #clock-cells = <0>;
  1748. clock-frequency = <0>;
  1749. };
  1750. osc {
  1751. compatible = "fsl,imx-osc", "fixed-clock";
  1752. + #clock-cells = <0>;
  1753. clock-frequency = <24000000>;
  1754. };
  1755. };
  1756. + pu_dummy: pudummy_reg {
  1757. + compatible = "fsl,imx6-dummy-pureg"; /* only used in ldo-bypass */
  1758. + };
  1759. +
  1760. soc {
  1761. #address-cells = <1>;
  1762. #size-cells = <1>;
  1763. @@ -75,7 +93,10 @@
  1764. dma_apbh: dma-apbh@00110000 {
  1765. compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
  1766. reg = <0x00110000 0x2000>;
  1767. - interrupts = <0 13 0x04>, <0 13 0x04>, <0 13 0x04>, <0 13 0x04>;
  1768. + interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>,
  1769. + <0 13 IRQ_TYPE_LEVEL_HIGH>,
  1770. + <0 13 IRQ_TYPE_LEVEL_HIGH>,
  1771. + <0 13 IRQ_TYPE_LEVEL_HIGH>;
  1772. interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
  1773. #dma-cells = <1>;
  1774. dma-channels = <4>;
  1775. @@ -88,7 +109,7 @@
  1776. #size-cells = <1>;
  1777. reg = <0x00112000 0x2000>, <0x00114000 0x2000>;
  1778. reg-names = "gpmi-nand", "bch";
  1779. - interrupts = <0 15 0x04>;
  1780. + interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
  1781. interrupt-names = "bch";
  1782. clocks = <&clks 152>, <&clks 153>, <&clks 151>,
  1783. <&clks 150>, <&clks 149>;
  1784. @@ -109,11 +130,13 @@
  1785. L2: l2-cache@00a02000 {
  1786. compatible = "arm,pl310-cache";
  1787. reg = <0x00a02000 0x1000>;
  1788. - interrupts = <0 92 0x04>;
  1789. + interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
  1790. cache-unified;
  1791. cache-level = <2>;
  1792. arm,tag-latency = <4 2 3>;
  1793. arm,data-latency = <4 2 3>;
  1794. + arm,dynamic-clk-gating;
  1795. + arm,standby-mode;
  1796. };
  1797. pcie: pcie@0x01000000 {
  1798. @@ -126,15 +149,22 @@
  1799. 0x81000000 0 0 0x01f80000 0 0x00010000 /* downstream I/O */
  1800. 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
  1801. num-lanes = <1>;
  1802. - interrupts = <0 123 0x04>;
  1803. - clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
  1804. - clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
  1805. + interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
  1806. + interrupt-names = "msi";
  1807. + #interrupt-cells = <1>;
  1808. + interrupt-map-mask = <0 0 0 0x7>;
  1809. + interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
  1810. + <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
  1811. + <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
  1812. + <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
  1813. + clocks = <&clks 144>, <&clks 206>, <&clks 189>, <&clks 221>;
  1814. + clock-names = "pcie", "pcie_bus", "pcie_phy", "lvds_gate";
  1815. status = "disabled";
  1816. };
  1817. pmu {
  1818. compatible = "arm,cortex-a9-pmu";
  1819. - interrupts = <0 94 0x04>;
  1820. + interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
  1821. };
  1822. aips-bus@02000000 { /* AIPS1 */
  1823. @@ -154,7 +184,7 @@
  1824. spdif: spdif@02004000 {
  1825. compatible = "fsl,imx35-spdif";
  1826. reg = <0x02004000 0x4000>;
  1827. - interrupts = <0 52 0x04>;
  1828. + interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
  1829. dmas = <&sdma 14 18 0>,
  1830. <&sdma 15 18 0>;
  1831. dma-names = "rx", "tx";
  1832. @@ -176,9 +206,11 @@
  1833. #size-cells = <0>;
  1834. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1835. reg = <0x02008000 0x4000>;
  1836. - interrupts = <0 31 0x04>;
  1837. + interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
  1838. clocks = <&clks 112>, <&clks 112>;
  1839. clock-names = "ipg", "per";
  1840. + dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
  1841. + dma-names = "rx", "tx";
  1842. status = "disabled";
  1843. };
  1844. @@ -187,9 +219,11 @@
  1845. #size-cells = <0>;
  1846. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1847. reg = <0x0200c000 0x4000>;
  1848. - interrupts = <0 32 0x04>;
  1849. + interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
  1850. clocks = <&clks 113>, <&clks 113>;
  1851. clock-names = "ipg", "per";
  1852. + dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
  1853. + dma-names = "rx", "tx";
  1854. status = "disabled";
  1855. };
  1856. @@ -198,9 +232,11 @@
  1857. #size-cells = <0>;
  1858. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1859. reg = <0x02010000 0x4000>;
  1860. - interrupts = <0 33 0x04>;
  1861. + interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
  1862. clocks = <&clks 114>, <&clks 114>;
  1863. clock-names = "ipg", "per";
  1864. + dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
  1865. + dma-names = "rx", "tx";
  1866. status = "disabled";
  1867. };
  1868. @@ -209,16 +245,18 @@
  1869. #size-cells = <0>;
  1870. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1871. reg = <0x02014000 0x4000>;
  1872. - interrupts = <0 34 0x04>;
  1873. + interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
  1874. clocks = <&clks 115>, <&clks 115>;
  1875. clock-names = "ipg", "per";
  1876. + dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
  1877. + dma-names = "rx", "tx";
  1878. status = "disabled";
  1879. };
  1880. uart1: serial@02020000 {
  1881. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  1882. reg = <0x02020000 0x4000>;
  1883. - interrupts = <0 26 0x04>;
  1884. + interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
  1885. clocks = <&clks 160>, <&clks 161>;
  1886. clock-names = "ipg", "per";
  1887. dmas = <&sdma 25 4 0>, <&sdma 26 4 0>;
  1888. @@ -227,15 +265,23 @@
  1889. };
  1890. esai: esai@02024000 {
  1891. + compatible = "fsl,imx6q-esai";
  1892. reg = <0x02024000 0x4000>;
  1893. - interrupts = <0 51 0x04>;
  1894. + interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
  1895. + clocks = <&clks 118>;
  1896. + fsl,esai-dma-events = <24 23>;
  1897. + fsl,flags = <1>;
  1898. + status = "disabled";
  1899. };
  1900. ssi1: ssi@02028000 {
  1901. - compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
  1902. + compatible = "fsl,imx6q-ssi",
  1903. + "fsl,imx51-ssi",
  1904. + "fsl,imx21-ssi";
  1905. reg = <0x02028000 0x4000>;
  1906. - interrupts = <0 46 0x04>;
  1907. - clocks = <&clks 178>;
  1908. + interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
  1909. + clocks = <&clks 178>, <&clks 157>;
  1910. + clock-names = "ipg", "baud";
  1911. dmas = <&sdma 37 1 0>,
  1912. <&sdma 38 1 0>;
  1913. dma-names = "rx", "tx";
  1914. @@ -245,10 +291,13 @@
  1915. };
  1916. ssi2: ssi@0202c000 {
  1917. - compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
  1918. + compatible = "fsl,imx6q-ssi",
  1919. + "fsl,imx51-ssi",
  1920. + "fsl,imx21-ssi";
  1921. reg = <0x0202c000 0x4000>;
  1922. - interrupts = <0 47 0x04>;
  1923. - clocks = <&clks 179>;
  1924. + interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
  1925. + clocks = <&clks 179>, <&clks 158>;
  1926. + clock-names = "ipg", "baud";
  1927. dmas = <&sdma 41 1 0>,
  1928. <&sdma 42 1 0>;
  1929. dma-names = "rx", "tx";
  1930. @@ -258,10 +307,13 @@
  1931. };
  1932. ssi3: ssi@02030000 {
  1933. - compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
  1934. + compatible = "fsl,imx6q-ssi",
  1935. + "fsl,imx51-ssi",
  1936. + "fsl,imx21-ssi";
  1937. reg = <0x02030000 0x4000>;
  1938. - interrupts = <0 48 0x04>;
  1939. - clocks = <&clks 180>;
  1940. + interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
  1941. + clocks = <&clks 180>, <&clks 159>;
  1942. + clock-names = "ipg", "baud";
  1943. dmas = <&sdma 45 1 0>,
  1944. <&sdma 46 1 0>;
  1945. dma-names = "rx", "tx";
  1946. @@ -271,8 +323,25 @@
  1947. };
  1948. asrc: asrc@02034000 {
  1949. + compatible = "fsl,imx53-asrc";
  1950. reg = <0x02034000 0x4000>;
  1951. - interrupts = <0 50 0x04>;
  1952. + interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
  1953. + clocks = <&clks 107>, <&clks 156>;
  1954. + clock-names = "core", "dma";
  1955. + dmas = <&sdma 17 20 1>, <&sdma 18 20 1>, <&sdma 19 20 1>,
  1956. + <&sdma 20 20 1>, <&sdma 21 20 1>, <&sdma 22 20 1>;
  1957. + dma-names = "rxa", "rxb", "rxc",
  1958. + "txa", "txb", "txc";
  1959. + status = "okay";
  1960. + };
  1961. +
  1962. + asrc_p2p: asrc_p2p {
  1963. + compatible = "fsl,imx6q-asrc-p2p";
  1964. + fsl,output-rate = <48000>;
  1965. + fsl,output-width = <16>;
  1966. + fsl,asrc-dma-rx-events = <17 18 19>;
  1967. + fsl,asrc-dma-tx-events = <20 21 22>;
  1968. + status = "okay";
  1969. };
  1970. spba@0203c000 {
  1971. @@ -281,8 +350,19 @@
  1972. };
  1973. vpu: vpu@02040000 {
  1974. + compatible = "fsl,imx6-vpu";
  1975. reg = <0x02040000 0x3c000>;
  1976. - interrupts = <0 3 0x04 0 12 0x04>;
  1977. + reg-names = "vpu_regs";
  1978. + interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>,
  1979. + <0 12 IRQ_TYPE_LEVEL_HIGH>;
  1980. + interrupt-names = "vpu_jpu_irq", "vpu_ipi_irq";
  1981. + clocks = <&clks 168>, <&clks 140>, <&clks 142>;
  1982. + clock-names = "vpu_clk", "mmdc_ch0_axi", "ocram";
  1983. + iramsize = <0x21000>;
  1984. + iram = <&ocram>;
  1985. + resets = <&src 1>;
  1986. + pu-supply = <&reg_pu>;
  1987. + status = "disabled";
  1988. };
  1989. aipstz@0207c000 { /* AIPSTZ1 */
  1990. @@ -293,7 +373,7 @@
  1991. #pwm-cells = <2>;
  1992. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  1993. reg = <0x02080000 0x4000>;
  1994. - interrupts = <0 83 0x04>;
  1995. + interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
  1996. clocks = <&clks 62>, <&clks 145>;
  1997. clock-names = "ipg", "per";
  1998. };
  1999. @@ -302,7 +382,7 @@
  2000. #pwm-cells = <2>;
  2001. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  2002. reg = <0x02084000 0x4000>;
  2003. - interrupts = <0 84 0x04>;
  2004. + interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
  2005. clocks = <&clks 62>, <&clks 146>;
  2006. clock-names = "ipg", "per";
  2007. };
  2008. @@ -311,7 +391,7 @@
  2009. #pwm-cells = <2>;
  2010. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  2011. reg = <0x02088000 0x4000>;
  2012. - interrupts = <0 85 0x04>;
  2013. + interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
  2014. clocks = <&clks 62>, <&clks 147>;
  2015. clock-names = "ipg", "per";
  2016. };
  2017. @@ -320,7 +400,7 @@
  2018. #pwm-cells = <2>;
  2019. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  2020. reg = <0x0208c000 0x4000>;
  2021. - interrupts = <0 86 0x04>;
  2022. + interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
  2023. clocks = <&clks 62>, <&clks 148>;
  2024. clock-names = "ipg", "per";
  2025. };
  2026. @@ -328,23 +408,25 @@
  2027. can1: flexcan@02090000 {
  2028. compatible = "fsl,imx6q-flexcan";
  2029. reg = <0x02090000 0x4000>;
  2030. - interrupts = <0 110 0x04>;
  2031. + interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
  2032. clocks = <&clks 108>, <&clks 109>;
  2033. clock-names = "ipg", "per";
  2034. + status = "disabled";
  2035. };
  2036. can2: flexcan@02094000 {
  2037. compatible = "fsl,imx6q-flexcan";
  2038. reg = <0x02094000 0x4000>;
  2039. - interrupts = <0 111 0x04>;
  2040. + interrupts = <0 111 IRQ_TYPE_LEVEL_HIGH>;
  2041. clocks = <&clks 110>, <&clks 111>;
  2042. clock-names = "ipg", "per";
  2043. + status = "disabled";
  2044. };
  2045. gpt: gpt@02098000 {
  2046. compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt";
  2047. reg = <0x02098000 0x4000>;
  2048. - interrupts = <0 55 0x04>;
  2049. + interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
  2050. clocks = <&clks 119>, <&clks 120>;
  2051. clock-names = "ipg", "per";
  2052. };
  2053. @@ -352,7 +434,8 @@
  2054. gpio1: gpio@0209c000 {
  2055. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2056. reg = <0x0209c000 0x4000>;
  2057. - interrupts = <0 66 0x04 0 67 0x04>;
  2058. + interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
  2059. + <0 67 IRQ_TYPE_LEVEL_HIGH>;
  2060. gpio-controller;
  2061. #gpio-cells = <2>;
  2062. interrupt-controller;
  2063. @@ -362,7 +445,8 @@
  2064. gpio2: gpio@020a0000 {
  2065. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2066. reg = <0x020a0000 0x4000>;
  2067. - interrupts = <0 68 0x04 0 69 0x04>;
  2068. + interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
  2069. + <0 69 IRQ_TYPE_LEVEL_HIGH>;
  2070. gpio-controller;
  2071. #gpio-cells = <2>;
  2072. interrupt-controller;
  2073. @@ -372,7 +456,8 @@
  2074. gpio3: gpio@020a4000 {
  2075. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2076. reg = <0x020a4000 0x4000>;
  2077. - interrupts = <0 70 0x04 0 71 0x04>;
  2078. + interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
  2079. + <0 71 IRQ_TYPE_LEVEL_HIGH>;
  2080. gpio-controller;
  2081. #gpio-cells = <2>;
  2082. interrupt-controller;
  2083. @@ -382,7 +467,8 @@
  2084. gpio4: gpio@020a8000 {
  2085. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2086. reg = <0x020a8000 0x4000>;
  2087. - interrupts = <0 72 0x04 0 73 0x04>;
  2088. + interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
  2089. + <0 73 IRQ_TYPE_LEVEL_HIGH>;
  2090. gpio-controller;
  2091. #gpio-cells = <2>;
  2092. interrupt-controller;
  2093. @@ -392,7 +478,8 @@
  2094. gpio5: gpio@020ac000 {
  2095. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2096. reg = <0x020ac000 0x4000>;
  2097. - interrupts = <0 74 0x04 0 75 0x04>;
  2098. + interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
  2099. + <0 75 IRQ_TYPE_LEVEL_HIGH>;
  2100. gpio-controller;
  2101. #gpio-cells = <2>;
  2102. interrupt-controller;
  2103. @@ -402,7 +489,8 @@
  2104. gpio6: gpio@020b0000 {
  2105. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2106. reg = <0x020b0000 0x4000>;
  2107. - interrupts = <0 76 0x04 0 77 0x04>;
  2108. + interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>,
  2109. + <0 77 IRQ_TYPE_LEVEL_HIGH>;
  2110. gpio-controller;
  2111. #gpio-cells = <2>;
  2112. interrupt-controller;
  2113. @@ -412,7 +500,8 @@
  2114. gpio7: gpio@020b4000 {
  2115. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2116. reg = <0x020b4000 0x4000>;
  2117. - interrupts = <0 78 0x04 0 79 0x04>;
  2118. + interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>,
  2119. + <0 79 IRQ_TYPE_LEVEL_HIGH>;
  2120. gpio-controller;
  2121. #gpio-cells = <2>;
  2122. interrupt-controller;
  2123. @@ -421,20 +510,20 @@
  2124. kpp: kpp@020b8000 {
  2125. reg = <0x020b8000 0x4000>;
  2126. - interrupts = <0 82 0x04>;
  2127. + interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
  2128. };
  2129. wdog1: wdog@020bc000 {
  2130. compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
  2131. reg = <0x020bc000 0x4000>;
  2132. - interrupts = <0 80 0x04>;
  2133. + interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
  2134. clocks = <&clks 0>;
  2135. };
  2136. wdog2: wdog@020c0000 {
  2137. compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
  2138. reg = <0x020c0000 0x4000>;
  2139. - interrupts = <0 81 0x04>;
  2140. + interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
  2141. clocks = <&clks 0>;
  2142. status = "disabled";
  2143. };
  2144. @@ -442,14 +531,17 @@
  2145. clks: ccm@020c4000 {
  2146. compatible = "fsl,imx6q-ccm";
  2147. reg = <0x020c4000 0x4000>;
  2148. - interrupts = <0 87 0x04 0 88 0x04>;
  2149. + interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
  2150. + <0 88 IRQ_TYPE_LEVEL_HIGH>;
  2151. #clock-cells = <1>;
  2152. };
  2153. anatop: anatop@020c8000 {
  2154. compatible = "fsl,imx6q-anatop", "syscon", "simple-bus";
  2155. reg = <0x020c8000 0x1000>;
  2156. - interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
  2157. + interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
  2158. + <0 54 IRQ_TYPE_LEVEL_HIGH>,
  2159. + <0 127 IRQ_TYPE_LEVEL_HIGH>;
  2160. regulator-1p1@110 {
  2161. compatible = "fsl,anatop-regulator";
  2162. @@ -495,7 +587,7 @@
  2163. reg_arm: regulator-vddcore@140 {
  2164. compatible = "fsl,anatop-regulator";
  2165. - regulator-name = "cpu";
  2166. + regulator-name = "vddarm";
  2167. regulator-min-microvolt = <725000>;
  2168. regulator-max-microvolt = <1450000>;
  2169. regulator-always-on;
  2170. @@ -515,7 +607,6 @@
  2171. regulator-name = "vddpu";
  2172. regulator-min-microvolt = <725000>;
  2173. regulator-max-microvolt = <1450000>;
  2174. - regulator-always-on;
  2175. anatop-reg-offset = <0x140>;
  2176. anatop-vol-bit-shift = <9>;
  2177. anatop-vol-bit-width = <5>;
  2178. @@ -547,23 +638,38 @@
  2179. tempmon: tempmon {
  2180. compatible = "fsl,imx6q-tempmon";
  2181. - interrupts = <0 49 0x04>;
  2182. + interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>;
  2183. fsl,tempmon = <&anatop>;
  2184. fsl,tempmon-data = <&ocotp>;
  2185. + clocks = <&clks 172>;
  2186. };
  2187. usbphy1: usbphy@020c9000 {
  2188. compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
  2189. reg = <0x020c9000 0x1000>;
  2190. - interrupts = <0 44 0x04>;
  2191. + interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
  2192. clocks = <&clks 182>;
  2193. + fsl,anatop = <&anatop>;
  2194. };
  2195. usbphy2: usbphy@020ca000 {
  2196. compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
  2197. reg = <0x020ca000 0x1000>;
  2198. - interrupts = <0 45 0x04>;
  2199. + interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
  2200. clocks = <&clks 183>;
  2201. + fsl,anatop = <&anatop>;
  2202. + };
  2203. +
  2204. + usbphy_nop1: usbphy_nop1 {
  2205. + compatible = "usb-nop-xceiv";
  2206. + clocks = <&clks 182>;
  2207. + clock-names = "main_clk";
  2208. + };
  2209. +
  2210. + usbphy_nop2: usbphy_nop2 {
  2211. + compatible = "usb-nop-xceiv";
  2212. + clocks = <&clks 182>;
  2213. + clock-names = "main_clk";
  2214. };
  2215. snvs@020cc000 {
  2216. @@ -575,31 +681,39 @@
  2217. snvs-rtc-lp@34 {
  2218. compatible = "fsl,sec-v4.0-mon-rtc-lp";
  2219. reg = <0x34 0x58>;
  2220. - interrupts = <0 19 0x04 0 20 0x04>;
  2221. + interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
  2222. + <0 20 IRQ_TYPE_LEVEL_HIGH>;
  2223. };
  2224. };
  2225. epit1: epit@020d0000 { /* EPIT1 */
  2226. reg = <0x020d0000 0x4000>;
  2227. - interrupts = <0 56 0x04>;
  2228. + interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
  2229. };
  2230. epit2: epit@020d4000 { /* EPIT2 */
  2231. reg = <0x020d4000 0x4000>;
  2232. - interrupts = <0 57 0x04>;
  2233. + interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
  2234. };
  2235. src: src@020d8000 {
  2236. compatible = "fsl,imx6q-src", "fsl,imx51-src";
  2237. reg = <0x020d8000 0x4000>;
  2238. - interrupts = <0 91 0x04 0 96 0x04>;
  2239. + interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
  2240. + <0 96 IRQ_TYPE_LEVEL_HIGH>;
  2241. #reset-cells = <1>;
  2242. };
  2243. gpc: gpc@020dc000 {
  2244. compatible = "fsl,imx6q-gpc";
  2245. reg = <0x020dc000 0x4000>;
  2246. - interrupts = <0 89 0x04 0 90 0x04>;
  2247. + interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>,
  2248. + <0 90 IRQ_TYPE_LEVEL_HIGH>;
  2249. + clocks = <&clks 122>, <&clks 74>, <&clks 121>,
  2250. + <&clks 26>, <&clks 143>, <&clks 168>, <&clks 62>;
  2251. + clock-names = "gpu3d_core", "gpu3d_shader", "gpu2d_core",
  2252. + "gpu2d_axi", "openvg_axi", "vpu_axi", "ipg";
  2253. + pu-supply = <&reg_pu>;
  2254. };
  2255. gpr: iomuxc-gpr@020e0000 {
  2256. @@ -610,778 +724,40 @@
  2257. iomuxc: iomuxc@020e0000 {
  2258. compatible = "fsl,imx6dl-iomuxc", "fsl,imx6q-iomuxc";
  2259. reg = <0x020e0000 0x4000>;
  2260. -
  2261. - audmux {
  2262. - pinctrl_audmux_1: audmux-1 {
  2263. - fsl,pins = <
  2264. - MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x80000000
  2265. - MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x80000000
  2266. - MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x80000000
  2267. - MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x80000000
  2268. - >;
  2269. - };
  2270. -
  2271. - pinctrl_audmux_2: audmux-2 {
  2272. - fsl,pins = <
  2273. - MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x80000000
  2274. - MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x80000000
  2275. - MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x80000000
  2276. - MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x80000000
  2277. - >;
  2278. - };
  2279. -
  2280. - pinctrl_audmux_3: audmux-3 {
  2281. - fsl,pins = <
  2282. - MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x80000000
  2283. - MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x80000000
  2284. - MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x80000000
  2285. - >;
  2286. - };
  2287. - };
  2288. -
  2289. - ecspi1 {
  2290. - pinctrl_ecspi1_1: ecspi1grp-1 {
  2291. - fsl,pins = <
  2292. - MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  2293. - MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  2294. - MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  2295. - >;
  2296. - };
  2297. -
  2298. - pinctrl_ecspi1_2: ecspi1grp-2 {
  2299. - fsl,pins = <
  2300. - MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1
  2301. - MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1
  2302. - MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1
  2303. - >;
  2304. - };
  2305. - };
  2306. -
  2307. - ecspi3 {
  2308. - pinctrl_ecspi3_1: ecspi3grp-1 {
  2309. - fsl,pins = <
  2310. - MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
  2311. - MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
  2312. - MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
  2313. - >;
  2314. - };
  2315. - };
  2316. -
  2317. - enet {
  2318. - pinctrl_enet_1: enetgrp-1 {
  2319. - fsl,pins = <
  2320. - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  2321. - MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  2322. - MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  2323. - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  2324. - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  2325. - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  2326. - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  2327. - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  2328. - MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  2329. - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  2330. - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  2331. - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  2332. - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  2333. - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  2334. - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  2335. - MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  2336. - >;
  2337. - };
  2338. -
  2339. - pinctrl_enet_2: enetgrp-2 {
  2340. - fsl,pins = <
  2341. - MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
  2342. - MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0
  2343. - MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  2344. - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  2345. - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  2346. - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  2347. - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  2348. - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  2349. - MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  2350. - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  2351. - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  2352. - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  2353. - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  2354. - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  2355. - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  2356. - >;
  2357. - };
  2358. -
  2359. - pinctrl_enet_3: enetgrp-3 {
  2360. - fsl,pins = <
  2361. - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  2362. - MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  2363. - MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  2364. - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  2365. - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  2366. - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  2367. - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  2368. - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  2369. - MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  2370. - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  2371. - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  2372. - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  2373. - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  2374. - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  2375. - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  2376. - MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
  2377. - >;
  2378. - };
  2379. - };
  2380. -
  2381. - esai {
  2382. - pinctrl_esai_1: esaigrp-1 {
  2383. - fsl,pins = <
  2384. - MX6QDL_PAD_ENET_RXD0__ESAI_TX_HF_CLK 0x1b030
  2385. - MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1b030
  2386. - MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS 0x1b030
  2387. - MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1b030
  2388. - MX6QDL_PAD_ENET_TXD1__ESAI_TX2_RX3 0x1b030
  2389. - MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1 0x1b030
  2390. - MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0 0x1b030
  2391. - MX6QDL_PAD_NANDF_CS2__ESAI_TX0 0x1b030
  2392. - MX6QDL_PAD_NANDF_CS3__ESAI_TX1 0x1b030
  2393. - >;
  2394. - };
  2395. -
  2396. - pinctrl_esai_2: esaigrp-2 {
  2397. - fsl,pins = <
  2398. - MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1b030
  2399. - MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS 0x1b030
  2400. - MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1b030
  2401. - MX6QDL_PAD_GPIO_5__ESAI_TX2_RX3 0x1b030
  2402. - MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1 0x1b030
  2403. - MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0 0x1b030
  2404. - MX6QDL_PAD_GPIO_17__ESAI_TX0 0x1b030
  2405. - MX6QDL_PAD_NANDF_CS3__ESAI_TX1 0x1b030
  2406. - MX6QDL_PAD_ENET_MDIO__ESAI_RX_CLK 0x1b030
  2407. - MX6QDL_PAD_GPIO_9__ESAI_RX_FS 0x1b030
  2408. - >;
  2409. - };
  2410. - };
  2411. -
  2412. - flexcan1 {
  2413. - pinctrl_flexcan1_1: flexcan1grp-1 {
  2414. - fsl,pins = <
  2415. - MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  2416. - MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x80000000
  2417. - >;
  2418. - };
  2419. -
  2420. - pinctrl_flexcan1_2: flexcan1grp-2 {
  2421. - fsl,pins = <
  2422. - MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x80000000
  2423. - MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  2424. - >;
  2425. - };
  2426. - };
  2427. -
  2428. - flexcan2 {
  2429. - pinctrl_flexcan2_1: flexcan2grp-1 {
  2430. - fsl,pins = <
  2431. - MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x80000000
  2432. - MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x80000000
  2433. - >;
  2434. - };
  2435. - };
  2436. -
  2437. - gpmi-nand {
  2438. - pinctrl_gpmi_nand_1: gpmi-nand-1 {
  2439. - fsl,pins = <
  2440. - MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  2441. - MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  2442. - MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  2443. - MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  2444. - MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  2445. - MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  2446. - MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  2447. - MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  2448. - MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  2449. - MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  2450. - MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  2451. - MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  2452. - MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  2453. - MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  2454. - MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  2455. - MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  2456. - MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  2457. - >;
  2458. - };
  2459. - };
  2460. -
  2461. - hdmi_hdcp {
  2462. - pinctrl_hdmi_hdcp_1: hdmihdcpgrp-1 {
  2463. - fsl,pins = <
  2464. - MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
  2465. - MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
  2466. - >;
  2467. - };
  2468. -
  2469. - pinctrl_hdmi_hdcp_2: hdmihdcpgrp-2 {
  2470. - fsl,pins = <
  2471. - MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
  2472. - MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x4001b8b1
  2473. - >;
  2474. - };
  2475. -
  2476. - pinctrl_hdmi_hdcp_3: hdmihdcpgrp-3 {
  2477. - fsl,pins = <
  2478. - MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
  2479. - MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
  2480. - >;
  2481. - };
  2482. - };
  2483. -
  2484. - hdmi_cec {
  2485. - pinctrl_hdmi_cec_1: hdmicecgrp-1 {
  2486. - fsl,pins = <
  2487. - MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE 0x1f8b0
  2488. - >;
  2489. - };
  2490. -
  2491. - pinctrl_hdmi_cec_2: hdmicecgrp-2 {
  2492. - fsl,pins = <
  2493. - MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  2494. - >;
  2495. - };
  2496. - };
  2497. -
  2498. - i2c1 {
  2499. - pinctrl_i2c1_1: i2c1grp-1 {
  2500. - fsl,pins = <
  2501. - MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  2502. - MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  2503. - >;
  2504. - };
  2505. -
  2506. - pinctrl_i2c1_2: i2c1grp-2 {
  2507. - fsl,pins = <
  2508. - MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
  2509. - MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
  2510. - >;
  2511. - };
  2512. - };
  2513. -
  2514. - i2c2 {
  2515. - pinctrl_i2c2_1: i2c2grp-1 {
  2516. - fsl,pins = <
  2517. - MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  2518. - MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
  2519. - >;
  2520. - };
  2521. -
  2522. - pinctrl_i2c2_2: i2c2grp-2 {
  2523. - fsl,pins = <
  2524. - MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  2525. - MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  2526. - >;
  2527. - };
  2528. -
  2529. - pinctrl_i2c2_3: i2c2grp-3 {
  2530. - fsl,pins = <
  2531. - MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  2532. - MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  2533. - >;
  2534. - };
  2535. - };
  2536. -
  2537. - i2c3 {
  2538. - pinctrl_i2c3_1: i2c3grp-1 {
  2539. - fsl,pins = <
  2540. - MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
  2541. - MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
  2542. - >;
  2543. - };
  2544. -
  2545. - pinctrl_i2c3_2: i2c3grp-2 {
  2546. - fsl,pins = <
  2547. - MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  2548. - MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  2549. - >;
  2550. - };
  2551. -
  2552. - pinctrl_i2c3_3: i2c3grp-3 {
  2553. - fsl,pins = <
  2554. - MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
  2555. - MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
  2556. - >;
  2557. - };
  2558. -
  2559. - pinctrl_i2c3_4: i2c3grp-4 {
  2560. - fsl,pins = <
  2561. - MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  2562. - MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
  2563. - >;
  2564. - };
  2565. - };
  2566. -
  2567. - ipu1 {
  2568. - pinctrl_ipu1_1: ipu1grp-1 {
  2569. - fsl,pins = <
  2570. - MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
  2571. - MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
  2572. - MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
  2573. - MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
  2574. - MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x80000000
  2575. - MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10
  2576. - MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
  2577. - MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
  2578. - MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
  2579. - MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
  2580. - MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
  2581. - MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
  2582. - MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
  2583. - MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
  2584. - MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
  2585. - MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
  2586. - MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
  2587. - MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
  2588. - MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
  2589. - MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
  2590. - MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
  2591. - MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
  2592. - MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
  2593. - MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
  2594. - MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
  2595. - MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
  2596. - MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
  2597. - MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
  2598. - MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
  2599. - >;
  2600. - };
  2601. -
  2602. - pinctrl_ipu1_2: ipu1grp-2 { /* parallel camera */
  2603. - fsl,pins = <
  2604. - MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x80000000
  2605. - MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x80000000
  2606. - MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x80000000
  2607. - MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x80000000
  2608. - MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x80000000
  2609. - MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x80000000
  2610. - MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x80000000
  2611. - MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x80000000
  2612. - MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x80000000
  2613. - MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x80000000
  2614. - MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x80000000
  2615. - MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x80000000
  2616. - >;
  2617. - };
  2618. -
  2619. - pinctrl_ipu1_3: ipu1grp-3 { /* parallel port 16-bit */
  2620. - fsl,pins = <
  2621. - MX6QDL_PAD_CSI0_DAT4__IPU1_CSI0_DATA04 0x80000000
  2622. - MX6QDL_PAD_CSI0_DAT5__IPU1_CSI0_DATA05 0x80000000
  2623. - MX6QDL_PAD_CSI0_DAT6__IPU1_CSI0_DATA06 0x80000000
  2624. - MX6QDL_PAD_CSI0_DAT7__IPU1_CSI0_DATA07 0x80000000
  2625. - MX6QDL_PAD_CSI0_DAT8__IPU1_CSI0_DATA08 0x80000000
  2626. - MX6QDL_PAD_CSI0_DAT9__IPU1_CSI0_DATA09 0x80000000
  2627. - MX6QDL_PAD_CSI0_DAT10__IPU1_CSI0_DATA10 0x80000000
  2628. - MX6QDL_PAD_CSI0_DAT11__IPU1_CSI0_DATA11 0x80000000
  2629. - MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x80000000
  2630. - MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x80000000
  2631. - MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x80000000
  2632. - MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x80000000
  2633. - MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x80000000
  2634. - MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x80000000
  2635. - MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x80000000
  2636. - MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x80000000
  2637. - MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x80000000
  2638. - MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x80000000
  2639. - MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x80000000
  2640. - >;
  2641. - };
  2642. - };
  2643. -
  2644. - mlb {
  2645. - pinctrl_mlb_1: mlbgrp-1 {
  2646. - fsl,pins = <
  2647. - MX6QDL_PAD_GPIO_3__MLB_CLK 0x71
  2648. - MX6QDL_PAD_GPIO_6__MLB_SIG 0x71
  2649. - MX6QDL_PAD_GPIO_2__MLB_DATA 0x71
  2650. - >;
  2651. - };
  2652. -
  2653. - pinctrl_mlb_2: mlbgrp-2 {
  2654. - fsl,pins = <
  2655. - MX6QDL_PAD_ENET_TXD1__MLB_CLK 0x71
  2656. - MX6QDL_PAD_GPIO_6__MLB_SIG 0x71
  2657. - MX6QDL_PAD_GPIO_2__MLB_DATA 0x71
  2658. - >;
  2659. - };
  2660. - };
  2661. -
  2662. - pwm0 {
  2663. - pinctrl_pwm0_1: pwm0grp-1 {
  2664. - fsl,pins = <
  2665. - MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  2666. - >;
  2667. - };
  2668. - };
  2669. -
  2670. - pwm3 {
  2671. - pinctrl_pwm3_1: pwm3grp-1 {
  2672. - fsl,pins = <
  2673. - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
  2674. - >;
  2675. - };
  2676. - };
  2677. -
  2678. - spdif {
  2679. - pinctrl_spdif_1: spdifgrp-1 {
  2680. - fsl,pins = <
  2681. - MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x1b0b0
  2682. - >;
  2683. - };
  2684. -
  2685. - pinctrl_spdif_2: spdifgrp-2 {
  2686. - fsl,pins = <
  2687. - MX6QDL_PAD_GPIO_16__SPDIF_IN 0x1b0b0
  2688. - MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0
  2689. - >;
  2690. - };
  2691. -
  2692. - pinctrl_spdif_3: spdifgrp-3 {
  2693. - fsl,pins = <
  2694. - MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1b0b0
  2695. - >;
  2696. - };
  2697. - };
  2698. -
  2699. - uart1 {
  2700. - pinctrl_uart1_1: uart1grp-1 {
  2701. - fsl,pins = <
  2702. - MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  2703. - MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  2704. - >;
  2705. - };
  2706. - };
  2707. -
  2708. - uart2 {
  2709. - pinctrl_uart2_1: uart2grp-1 {
  2710. - fsl,pins = <
  2711. - MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  2712. - MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  2713. - >;
  2714. - };
  2715. -
  2716. - pinctrl_uart2_2: uart2grp-2 { /* DTE mode */
  2717. - fsl,pins = <
  2718. - MX6QDL_PAD_EIM_D26__UART2_RX_DATA 0x1b0b1
  2719. - MX6QDL_PAD_EIM_D27__UART2_TX_DATA 0x1b0b1
  2720. - MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B 0x1b0b1
  2721. - MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B 0x1b0b1
  2722. - >;
  2723. - };
  2724. - };
  2725. -
  2726. - uart3 {
  2727. - pinctrl_uart3_1: uart3grp-1 {
  2728. - fsl,pins = <
  2729. - MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x1b0b1
  2730. - MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x1b0b1
  2731. - MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x1b0b1
  2732. - MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  2733. - >;
  2734. - };
  2735. -
  2736. - pinctrl_uart3_2: uart3grp-2 {
  2737. - fsl,pins = <
  2738. - MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  2739. - MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  2740. - MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1
  2741. - MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  2742. - >;
  2743. - };
  2744. - };
  2745. -
  2746. - uart4 {
  2747. - pinctrl_uart4_1: uart4grp-1 {
  2748. - fsl,pins = <
  2749. - MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  2750. - MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  2751. - >;
  2752. - };
  2753. - };
  2754. -
  2755. - usbotg {
  2756. - pinctrl_usbotg_1: usbotggrp-1 {
  2757. - fsl,pins = <
  2758. - MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  2759. - >;
  2760. - };
  2761. -
  2762. - pinctrl_usbotg_2: usbotggrp-2 {
  2763. - fsl,pins = <
  2764. - MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  2765. - >;
  2766. - };
  2767. - };
  2768. -
  2769. - usbh2 {
  2770. - pinctrl_usbh2_1: usbh2grp-1 {
  2771. - fsl,pins = <
  2772. - MX6QDL_PAD_RGMII_TXC__USB_H2_DATA 0x40013030
  2773. - MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40013030
  2774. - >;
  2775. - };
  2776. -
  2777. - pinctrl_usbh2_2: usbh2grp-2 {
  2778. - fsl,pins = <
  2779. - MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40017030
  2780. - >;
  2781. - };
  2782. - };
  2783. -
  2784. - usbh3 {
  2785. - pinctrl_usbh3_1: usbh3grp-1 {
  2786. - fsl,pins = <
  2787. - MX6QDL_PAD_RGMII_RX_CTL__USB_H3_DATA 0x40013030
  2788. - MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x40013030
  2789. - >;
  2790. - };
  2791. -
  2792. - pinctrl_usbh3_2: usbh3grp-2 {
  2793. - fsl,pins = <
  2794. - MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x40017030
  2795. - >;
  2796. - };
  2797. - };
  2798. -
  2799. - usdhc1 {
  2800. - pinctrl_usdhc1_1: usdhc1grp-1 {
  2801. - fsl,pins = <
  2802. - MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  2803. - MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  2804. - MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  2805. - MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  2806. - MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  2807. - MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  2808. - MX6QDL_PAD_NANDF_D0__SD1_DATA4 0x17059
  2809. - MX6QDL_PAD_NANDF_D1__SD1_DATA5 0x17059
  2810. - MX6QDL_PAD_NANDF_D2__SD1_DATA6 0x17059
  2811. - MX6QDL_PAD_NANDF_D3__SD1_DATA7 0x17059
  2812. - >;
  2813. - };
  2814. -
  2815. - pinctrl_usdhc1_2: usdhc1grp-2 {
  2816. - fsl,pins = <
  2817. - MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  2818. - MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  2819. - MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  2820. - MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  2821. - MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  2822. - MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  2823. - >;
  2824. - };
  2825. - };
  2826. -
  2827. - usdhc2 {
  2828. - pinctrl_usdhc2_1: usdhc2grp-1 {
  2829. - fsl,pins = <
  2830. - MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  2831. - MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  2832. - MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  2833. - MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  2834. - MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  2835. - MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  2836. - MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x17059
  2837. - MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x17059
  2838. - MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x17059
  2839. - MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x17059
  2840. - >;
  2841. - };
  2842. -
  2843. - pinctrl_usdhc2_2: usdhc2grp-2 {
  2844. - fsl,pins = <
  2845. - MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  2846. - MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  2847. - MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  2848. - MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  2849. - MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  2850. - MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  2851. - >;
  2852. - };
  2853. - };
  2854. -
  2855. - usdhc3 {
  2856. - pinctrl_usdhc3_1: usdhc3grp-1 {
  2857. - fsl,pins = <
  2858. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  2859. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  2860. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  2861. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  2862. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  2863. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  2864. - MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
  2865. - MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
  2866. - MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
  2867. - MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
  2868. - >;
  2869. - };
  2870. -
  2871. - pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz { /* 100Mhz */
  2872. - fsl,pins = <
  2873. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9
  2874. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9
  2875. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  2876. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  2877. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  2878. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  2879. - MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9
  2880. - MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9
  2881. - MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9
  2882. - MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9
  2883. - >;
  2884. - };
  2885. -
  2886. - pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz { /* 200Mhz */
  2887. - fsl,pins = <
  2888. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9
  2889. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9
  2890. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  2891. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  2892. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  2893. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  2894. - MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
  2895. - MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
  2896. - MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
  2897. - MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
  2898. - >;
  2899. - };
  2900. -
  2901. - pinctrl_usdhc3_2: usdhc3grp-2 {
  2902. - fsl,pins = <
  2903. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  2904. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  2905. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  2906. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  2907. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  2908. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  2909. - >;
  2910. - };
  2911. - };
  2912. -
  2913. - usdhc4 {
  2914. - pinctrl_usdhc4_1: usdhc4grp-1 {
  2915. - fsl,pins = <
  2916. - MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  2917. - MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  2918. - MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  2919. - MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  2920. - MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  2921. - MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  2922. - MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  2923. - MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  2924. - MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  2925. - MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  2926. - >;
  2927. - };
  2928. -
  2929. - pinctrl_usdhc4_2: usdhc4grp-2 {
  2930. - fsl,pins = <
  2931. - MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  2932. - MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  2933. - MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  2934. - MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  2935. - MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  2936. - MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  2937. - >;
  2938. - };
  2939. - };
  2940. -
  2941. - weim {
  2942. - pinctrl_weim_cs0_1: weim_cs0grp-1 {
  2943. - fsl,pins = <
  2944. - MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0xb0b1
  2945. - >;
  2946. - };
  2947. -
  2948. - pinctrl_weim_nor_1: weim_norgrp-1 {
  2949. - fsl,pins = <
  2950. - MX6QDL_PAD_EIM_OE__EIM_OE_B 0xb0b1
  2951. - MX6QDL_PAD_EIM_RW__EIM_RW 0xb0b1
  2952. - MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060
  2953. - /* data */
  2954. - MX6QDL_PAD_EIM_D16__EIM_DATA16 0x1b0b0
  2955. - MX6QDL_PAD_EIM_D17__EIM_DATA17 0x1b0b0
  2956. - MX6QDL_PAD_EIM_D18__EIM_DATA18 0x1b0b0
  2957. - MX6QDL_PAD_EIM_D19__EIM_DATA19 0x1b0b0
  2958. - MX6QDL_PAD_EIM_D20__EIM_DATA20 0x1b0b0
  2959. - MX6QDL_PAD_EIM_D21__EIM_DATA21 0x1b0b0
  2960. - MX6QDL_PAD_EIM_D22__EIM_DATA22 0x1b0b0
  2961. - MX6QDL_PAD_EIM_D23__EIM_DATA23 0x1b0b0
  2962. - MX6QDL_PAD_EIM_D24__EIM_DATA24 0x1b0b0
  2963. - MX6QDL_PAD_EIM_D25__EIM_DATA25 0x1b0b0
  2964. - MX6QDL_PAD_EIM_D26__EIM_DATA26 0x1b0b0
  2965. - MX6QDL_PAD_EIM_D27__EIM_DATA27 0x1b0b0
  2966. - MX6QDL_PAD_EIM_D28__EIM_DATA28 0x1b0b0
  2967. - MX6QDL_PAD_EIM_D29__EIM_DATA29 0x1b0b0
  2968. - MX6QDL_PAD_EIM_D30__EIM_DATA30 0x1b0b0
  2969. - MX6QDL_PAD_EIM_D31__EIM_DATA31 0x1b0b0
  2970. - /* address */
  2971. - MX6QDL_PAD_EIM_A23__EIM_ADDR23 0xb0b1
  2972. - MX6QDL_PAD_EIM_A22__EIM_ADDR22 0xb0b1
  2973. - MX6QDL_PAD_EIM_A21__EIM_ADDR21 0xb0b1
  2974. - MX6QDL_PAD_EIM_A20__EIM_ADDR20 0xb0b1
  2975. - MX6QDL_PAD_EIM_A19__EIM_ADDR19 0xb0b1
  2976. - MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0b1
  2977. - MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0b1
  2978. - MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0b1
  2979. - MX6QDL_PAD_EIM_DA15__EIM_AD15 0xb0b1
  2980. - MX6QDL_PAD_EIM_DA14__EIM_AD14 0xb0b1
  2981. - MX6QDL_PAD_EIM_DA13__EIM_AD13 0xb0b1
  2982. - MX6QDL_PAD_EIM_DA12__EIM_AD12 0xb0b1
  2983. - MX6QDL_PAD_EIM_DA11__EIM_AD11 0xb0b1
  2984. - MX6QDL_PAD_EIM_DA10__EIM_AD10 0xb0b1
  2985. - MX6QDL_PAD_EIM_DA9__EIM_AD09 0xb0b1
  2986. - MX6QDL_PAD_EIM_DA8__EIM_AD08 0xb0b1
  2987. - MX6QDL_PAD_EIM_DA7__EIM_AD07 0xb0b1
  2988. - MX6QDL_PAD_EIM_DA6__EIM_AD06 0xb0b1
  2989. - MX6QDL_PAD_EIM_DA5__EIM_AD05 0xb0b1
  2990. - MX6QDL_PAD_EIM_DA4__EIM_AD04 0xb0b1
  2991. - MX6QDL_PAD_EIM_DA3__EIM_AD03 0xb0b1
  2992. - MX6QDL_PAD_EIM_DA2__EIM_AD02 0xb0b1
  2993. - MX6QDL_PAD_EIM_DA1__EIM_AD01 0xb0b1
  2994. - MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0b1
  2995. - >;
  2996. - };
  2997. - };
  2998. };
  2999. ldb: ldb@020e0008 {
  3000. - #address-cells = <1>;
  3001. - #size-cells = <0>;
  3002. compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb";
  3003. - gpr = <&gpr>;
  3004. + reg = <0x020e0000 0x4000>;
  3005. + clocks = <&clks 135>, <&clks 136>,
  3006. + <&clks 39>, <&clks 40>,
  3007. + <&clks 41>, <&clks 42>,
  3008. + <&clks 184>, <&clks 185>,
  3009. + <&clks 210>, <&clks 211>,
  3010. + <&clks 212>, <&clks 213>;
  3011. + clock-names = "ldb_di0", "ldb_di1",
  3012. + "ipu1_di0_sel", "ipu1_di1_sel",
  3013. + "ipu2_di0_sel", "ipu2_di1_sel",
  3014. + "di0_div_3_5", "di1_div_3_5",
  3015. + "di0_div_7", "di1_div_7",
  3016. + "di0_div_sel", "di1_div_sel";
  3017. status = "disabled";
  3018. -
  3019. - lvds-channel@0 {
  3020. - reg = <0>;
  3021. - status = "disabled";
  3022. - };
  3023. -
  3024. - lvds-channel@1 {
  3025. - reg = <1>;
  3026. - status = "disabled";
  3027. - };
  3028. };
  3029. dcic1: dcic@020e4000 {
  3030. reg = <0x020e4000 0x4000>;
  3031. - interrupts = <0 124 0x04>;
  3032. + interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>;
  3033. };
  3034. dcic2: dcic@020e8000 {
  3035. reg = <0x020e8000 0x4000>;
  3036. - interrupts = <0 125 0x04>;
  3037. + interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
  3038. };
  3039. sdma: sdma@020ec000 {
  3040. compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
  3041. reg = <0x020ec000 0x4000>;
  3042. - interrupts = <0 2 0x04>;
  3043. + interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
  3044. clocks = <&clks 155>, <&clks 155>;
  3045. clock-names = "ipg", "ahb";
  3046. #dma-cells = <3>;
  3047. @@ -1396,9 +772,29 @@
  3048. reg = <0x02100000 0x100000>;
  3049. ranges;
  3050. - caam@02100000 {
  3051. - reg = <0x02100000 0x40000>;
  3052. - interrupts = <0 105 0x04 0 106 0x04>;
  3053. + crypto: caam@02100000 {
  3054. + compatible = "fsl,sec-v4.0";
  3055. + #address-cells = <1>;
  3056. + #size-cells = <1>;
  3057. + reg = <0x2100000 0x40000>;
  3058. + ranges = <0 0x2100000 0x40000>;
  3059. + interrupt-parent = <&intc>; /* interrupts = <0 92 0x4>; */
  3060. + clocks = <&clks 214>, <&clks 215>, <&clks 216>, <&clks 196>;
  3061. + clock-names = "caam_mem", "caam_aclk", "caam_ipg", "caam_emi_slow";
  3062. +
  3063. + sec_jr0: jr0@1000 {
  3064. + compatible = "fsl,sec-v4.0-job-ring";
  3065. + reg = <0x1000 0x1000>;
  3066. + interrupt-parent = <&intc>;
  3067. + interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
  3068. + };
  3069. +
  3070. + sec_jr1: jr1@2000 {
  3071. + compatible = "fsl,sec-v4.0-job-ring";
  3072. + reg = <0x2000 0x1000>;
  3073. + interrupt-parent = <&intc>;
  3074. + interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
  3075. + };
  3076. };
  3077. aipstz@0217c000 { /* AIPSTZ2 */
  3078. @@ -1408,7 +804,7 @@
  3079. usbotg: usb@02184000 {
  3080. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3081. reg = <0x02184000 0x200>;
  3082. - interrupts = <0 43 0x04>;
  3083. + interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
  3084. clocks = <&clks 162>;
  3085. fsl,usbphy = <&usbphy1>;
  3086. fsl,usbmisc = <&usbmisc 0>;
  3087. @@ -1418,7 +814,7 @@
  3088. usbh1: usb@02184200 {
  3089. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3090. reg = <0x02184200 0x200>;
  3091. - interrupts = <0 40 0x04>;
  3092. + interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
  3093. clocks = <&clks 162>;
  3094. fsl,usbphy = <&usbphy2>;
  3095. fsl,usbmisc = <&usbmisc 1>;
  3096. @@ -1428,18 +824,24 @@
  3097. usbh2: usb@02184400 {
  3098. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3099. reg = <0x02184400 0x200>;
  3100. - interrupts = <0 41 0x04>;
  3101. + interrupts = <0 41 IRQ_TYPE_LEVEL_HIGH>;
  3102. clocks = <&clks 162>;
  3103. fsl,usbmisc = <&usbmisc 2>;
  3104. + phy_type = "hsic";
  3105. + fsl,usbphy = <&usbphy_nop1>;
  3106. + fsl,anatop = <&anatop>;
  3107. status = "disabled";
  3108. };
  3109. usbh3: usb@02184600 {
  3110. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3111. reg = <0x02184600 0x200>;
  3112. - interrupts = <0 42 0x04>;
  3113. + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
  3114. clocks = <&clks 162>;
  3115. fsl,usbmisc = <&usbmisc 3>;
  3116. + phy_type = "hsic";
  3117. + fsl,usbphy = <&usbphy_nop2>;
  3118. + fsl,anatop = <&anatop>;
  3119. status = "disabled";
  3120. };
  3121. @@ -1453,7 +855,9 @@
  3122. fec: ethernet@02188000 {
  3123. compatible = "fsl,imx6q-fec";
  3124. reg = <0x02188000 0x4000>;
  3125. - interrupts = <0 118 0x04 0 119 0x04>;
  3126. + interrupts-extended =
  3127. + <&intc 0 118 IRQ_TYPE_LEVEL_HIGH>,
  3128. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  3129. clocks = <&clks 117>, <&clks 117>, <&clks 190>;
  3130. clock-names = "ipg", "ahb", "ptp";
  3131. status = "disabled";
  3132. @@ -1461,13 +865,15 @@
  3133. mlb@0218c000 {
  3134. reg = <0x0218c000 0x4000>;
  3135. - interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
  3136. + interrupts = <0 53 IRQ_TYPE_LEVEL_HIGH>,
  3137. + <0 117 IRQ_TYPE_LEVEL_HIGH>,
  3138. + <0 126 IRQ_TYPE_LEVEL_HIGH>;
  3139. };
  3140. usdhc1: usdhc@02190000 {
  3141. compatible = "fsl,imx6q-usdhc";
  3142. reg = <0x02190000 0x4000>;
  3143. - interrupts = <0 22 0x04>;
  3144. + interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
  3145. clocks = <&clks 163>, <&clks 163>, <&clks 163>;
  3146. clock-names = "ipg", "ahb", "per";
  3147. bus-width = <4>;
  3148. @@ -1477,7 +883,7 @@
  3149. usdhc2: usdhc@02194000 {
  3150. compatible = "fsl,imx6q-usdhc";
  3151. reg = <0x02194000 0x4000>;
  3152. - interrupts = <0 23 0x04>;
  3153. + interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
  3154. clocks = <&clks 164>, <&clks 164>, <&clks 164>;
  3155. clock-names = "ipg", "ahb", "per";
  3156. bus-width = <4>;
  3157. @@ -1487,7 +893,7 @@
  3158. usdhc3: usdhc@02198000 {
  3159. compatible = "fsl,imx6q-usdhc";
  3160. reg = <0x02198000 0x4000>;
  3161. - interrupts = <0 24 0x04>;
  3162. + interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
  3163. clocks = <&clks 165>, <&clks 165>, <&clks 165>;
  3164. clock-names = "ipg", "ahb", "per";
  3165. bus-width = <4>;
  3166. @@ -1497,7 +903,7 @@
  3167. usdhc4: usdhc@0219c000 {
  3168. compatible = "fsl,imx6q-usdhc";
  3169. reg = <0x0219c000 0x4000>;
  3170. - interrupts = <0 25 0x04>;
  3171. + interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
  3172. clocks = <&clks 166>, <&clks 166>, <&clks 166>;
  3173. clock-names = "ipg", "ahb", "per";
  3174. bus-width = <4>;
  3175. @@ -1509,7 +915,7 @@
  3176. #size-cells = <0>;
  3177. compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
  3178. reg = <0x021a0000 0x4000>;
  3179. - interrupts = <0 36 0x04>;
  3180. + interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
  3181. clocks = <&clks 125>;
  3182. status = "disabled";
  3183. };
  3184. @@ -1519,7 +925,7 @@
  3185. #size-cells = <0>;
  3186. compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
  3187. reg = <0x021a4000 0x4000>;
  3188. - interrupts = <0 37 0x04>;
  3189. + interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
  3190. clocks = <&clks 126>;
  3191. status = "disabled";
  3192. };
  3193. @@ -1529,7 +935,7 @@
  3194. #size-cells = <0>;
  3195. compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
  3196. reg = <0x021a8000 0x4000>;
  3197. - interrupts = <0 38 0x04>;
  3198. + interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
  3199. clocks = <&clks 127>;
  3200. status = "disabled";
  3201. };
  3202. @@ -1538,6 +944,11 @@
  3203. reg = <0x021ac000 0x4000>;
  3204. };
  3205. + mmdc0-1@021b0000 { /* MMDC0-1 */
  3206. + compatible = "fsl,imx6q-mmdc-combine";
  3207. + reg = <0x021b0000 0x8000>;
  3208. + };
  3209. +
  3210. mmdc0: mmdc@021b0000 { /* MMDC0 */
  3211. compatible = "fsl,imx6q-mmdc";
  3212. reg = <0x021b0000 0x4000>;
  3213. @@ -1550,23 +961,29 @@
  3214. weim: weim@021b8000 {
  3215. compatible = "fsl,imx6q-weim";
  3216. reg = <0x021b8000 0x4000>;
  3217. - interrupts = <0 14 0x04>;
  3218. + interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
  3219. clocks = <&clks 196>;
  3220. };
  3221. - ocotp: ocotp@021bc000 {
  3222. - compatible = "fsl,imx6q-ocotp", "syscon";
  3223. + ocotp: ocotp-ctrl@021bc000 {
  3224. + compatible = "syscon";
  3225. reg = <0x021bc000 0x4000>;
  3226. };
  3227. + ocotp-fuse@021bc000 {
  3228. + compatible = "fsl,imx6q-ocotp";
  3229. + reg = <0x021bc000 0x4000>;
  3230. + clocks = <&clks 128>;
  3231. + };
  3232. +
  3233. tzasc@021d0000 { /* TZASC1 */
  3234. reg = <0x021d0000 0x4000>;
  3235. - interrupts = <0 108 0x04>;
  3236. + interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
  3237. };
  3238. tzasc@021d4000 { /* TZASC2 */
  3239. reg = <0x021d4000 0x4000>;
  3240. - interrupts = <0 109 0x04>;
  3241. + interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
  3242. };
  3243. audmux: audmux@021d8000 {
  3244. @@ -1575,23 +992,32 @@
  3245. status = "disabled";
  3246. };
  3247. - mipi@021dc000 { /* MIPI-CSI */
  3248. + mipi_csi: mipi_csi@021dc000 {
  3249. + compatible = "fsl,imx6q-mipi-csi2";
  3250. reg = <0x021dc000 0x4000>;
  3251. - };
  3252. -
  3253. - mipi@021e0000 { /* MIPI-DSI */
  3254. - reg = <0x021e0000 0x4000>;
  3255. + interrupts = <0 100 0x04>, <0 101 0x04>;
  3256. + clocks = <&clks 138>, <&clks 53>, <&clks 204>;
  3257. + /* Note: clks 138 is hsi_tx, however, the dphy_c
  3258. + * hsi_tx and pll_refclk use the same clk gate.
  3259. + * In current clk driver, open/close clk gate do
  3260. + * use hsi_tx for a temporary debug purpose.
  3261. + */
  3262. + clock-names = "dphy_clk", "pixel_clk", "cfg_clk";
  3263. + status = "disabled";
  3264. };
  3265. vdoa@021e4000 {
  3266. + compatible = "fsl,imx6q-vdoa";
  3267. reg = <0x021e4000 0x4000>;
  3268. - interrupts = <0 18 0x04>;
  3269. + interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
  3270. + clocks = <&clks 202>;
  3271. + iram = <&ocram>;
  3272. };
  3273. uart2: serial@021e8000 {
  3274. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3275. reg = <0x021e8000 0x4000>;
  3276. - interrupts = <0 27 0x04>;
  3277. + interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
  3278. clocks = <&clks 160>, <&clks 161>;
  3279. clock-names = "ipg", "per";
  3280. dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
  3281. @@ -1602,7 +1028,7 @@
  3282. uart3: serial@021ec000 {
  3283. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3284. reg = <0x021ec000 0x4000>;
  3285. - interrupts = <0 28 0x04>;
  3286. + interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
  3287. clocks = <&clks 160>, <&clks 161>;
  3288. clock-names = "ipg", "per";
  3289. dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
  3290. @@ -1613,7 +1039,7 @@
  3291. uart4: serial@021f0000 {
  3292. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3293. reg = <0x021f0000 0x4000>;
  3294. - interrupts = <0 29 0x04>;
  3295. + interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
  3296. clocks = <&clks 160>, <&clks 161>;
  3297. clock-names = "ipg", "per";
  3298. dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
  3299. @@ -1624,7 +1050,7 @@
  3300. uart5: serial@021f4000 {
  3301. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3302. reg = <0x021f4000 0x4000>;
  3303. - interrupts = <0 30 0x04>;
  3304. + interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
  3305. clocks = <&clks 160>, <&clks 161>;
  3306. clock-names = "ipg", "per";
  3307. dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
  3308. @@ -1634,13 +1060,18 @@
  3309. };
  3310. ipu1: ipu@02400000 {
  3311. - #crtc-cells = <1>;
  3312. compatible = "fsl,imx6q-ipu";
  3313. reg = <0x02400000 0x400000>;
  3314. - interrupts = <0 6 0x4 0 5 0x4>;
  3315. - clocks = <&clks 130>, <&clks 131>, <&clks 132>;
  3316. - clock-names = "bus", "di0", "di1";
  3317. + interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>,
  3318. + <0 5 IRQ_TYPE_LEVEL_HIGH>;
  3319. + clocks = <&clks 130>, <&clks 131>, <&clks 132>,
  3320. + <&clks 39>, <&clks 40>,
  3321. + <&clks 135>, <&clks 136>;
  3322. + clock-names = "bus", "di0", "di1",
  3323. + "di0_sel", "di1_sel",
  3324. + "ldb_di0", "ldb_di1";
  3325. resets = <&src 2>;
  3326. + bypass_reset = <0>;
  3327. };
  3328. };
  3329. };
  3330. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
  3331. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi 1970-01-01 01:00:00.000000000 +0100
  3332. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi 2014-08-20 19:31:39.900842271 +0200
  3333. @@ -0,0 +1,374 @@
  3334. +/*
  3335. + * Copyright 2013 Gateworks Corporation
  3336. + *
  3337. + * The code contained herein is licensed under the GNU General Public
  3338. + * License. You may obtain a copy of the GNU General Public License
  3339. + * Version 2 or later at the following locations:
  3340. + *
  3341. + * http://www.opensource.org/licenses/gpl-license.html
  3342. + * http://www.gnu.org/copyleft/gpl.html
  3343. + */
  3344. +
  3345. +/ {
  3346. + /* these are used by bootloader for disabling nodes */
  3347. + aliases {
  3348. + can0 = &can1;
  3349. + ethernet0 = &fec;
  3350. + led0 = &led0;
  3351. + led1 = &led1;
  3352. + nand = &gpmi;
  3353. + usb0 = &usbh1;
  3354. + usb1 = &usbotg;
  3355. + };
  3356. +
  3357. + chosen {
  3358. + bootargs = "console=ttymxc1,115200";
  3359. + };
  3360. +
  3361. + leds {
  3362. + compatible = "gpio-leds";
  3363. +
  3364. + led0: user1 {
  3365. + label = "user1";
  3366. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  3367. + default-state = "on";
  3368. + linux,default-trigger = "heartbeat";
  3369. + };
  3370. +
  3371. + led1: user2 {
  3372. + label = "user2";
  3373. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  3374. + default-state = "off";
  3375. + };
  3376. + };
  3377. +
  3378. + memory {
  3379. + reg = <0x10000000 0x20000000>;
  3380. + };
  3381. +
  3382. + pps {
  3383. + compatible = "pps-gpio";
  3384. + gpios = <&gpio1 26 0>;
  3385. + status = "okay";
  3386. + };
  3387. +
  3388. + regulators {
  3389. + compatible = "simple-bus";
  3390. + #address-cells = <1>;
  3391. + #size-cells = <0>;
  3392. +
  3393. + reg_3p3v: regulator@0 {
  3394. + compatible = "regulator-fixed";
  3395. + reg = <0>;
  3396. + regulator-name = "3P3V";
  3397. + regulator-min-microvolt = <3300000>;
  3398. + regulator-max-microvolt = <3300000>;
  3399. + regulator-always-on;
  3400. + };
  3401. +
  3402. + reg_5p0v: regulator@1 {
  3403. + compatible = "regulator-fixed";
  3404. + reg = <1>;
  3405. + regulator-name = "5P0V";
  3406. + regulator-min-microvolt = <5000000>;
  3407. + regulator-max-microvolt = <5000000>;
  3408. + regulator-always-on;
  3409. + };
  3410. +
  3411. + reg_usb_otg_vbus: regulator@2 {
  3412. + compatible = "regulator-fixed";
  3413. + reg = <2>;
  3414. + regulator-name = "usb_otg_vbus";
  3415. + regulator-min-microvolt = <5000000>;
  3416. + regulator-max-microvolt = <5000000>;
  3417. + gpio = <&gpio3 22 0>;
  3418. + enable-active-high;
  3419. + };
  3420. + };
  3421. +};
  3422. +
  3423. +&fec {
  3424. + pinctrl-names = "default";
  3425. + pinctrl-0 = <&pinctrl_enet>;
  3426. + phy-mode = "rgmii";
  3427. + phy-reset-gpios = <&gpio1 30 0>;
  3428. + status = "okay";
  3429. +};
  3430. +
  3431. +&gpmi {
  3432. + pinctrl-names = "default";
  3433. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  3434. + status = "okay";
  3435. +};
  3436. +
  3437. +&i2c1 {
  3438. + clock-frequency = <100000>;
  3439. + pinctrl-names = "default";
  3440. + pinctrl-0 = <&pinctrl_i2c1>;
  3441. + status = "okay";
  3442. +
  3443. + eeprom1: eeprom@50 {
  3444. + compatible = "atmel,24c02";
  3445. + reg = <0x50>;
  3446. + pagesize = <16>;
  3447. + };
  3448. +
  3449. + eeprom2: eeprom@51 {
  3450. + compatible = "atmel,24c02";
  3451. + reg = <0x51>;
  3452. + pagesize = <16>;
  3453. + };
  3454. +
  3455. + eeprom3: eeprom@52 {
  3456. + compatible = "atmel,24c02";
  3457. + reg = <0x52>;
  3458. + pagesize = <16>;
  3459. + };
  3460. +
  3461. + eeprom4: eeprom@53 {
  3462. + compatible = "atmel,24c02";
  3463. + reg = <0x53>;
  3464. + pagesize = <16>;
  3465. + };
  3466. +
  3467. + gpio: pca9555@23 {
  3468. + compatible = "nxp,pca9555";
  3469. + reg = <0x23>;
  3470. + gpio-controller;
  3471. + #gpio-cells = <2>;
  3472. + };
  3473. +
  3474. + hwmon: gsc@29 {
  3475. + compatible = "gw,gsp";
  3476. + reg = <0x29>;
  3477. + };
  3478. +
  3479. + rtc: ds1672@68 {
  3480. + compatible = "dallas,ds1672";
  3481. + reg = <0x68>;
  3482. + };
  3483. +};
  3484. +
  3485. +&i2c2 {
  3486. + clock-frequency = <100000>;
  3487. + pinctrl-names = "default";
  3488. + pinctrl-0 = <&pinctrl_i2c2>;
  3489. + status = "okay";
  3490. +
  3491. + pmic: ltc3676@3c {
  3492. + compatible = "ltc,ltc3676";
  3493. + reg = <0x3c>;
  3494. +
  3495. + regulators {
  3496. + sw1_reg: ltc3676__sw1 {
  3497. + regulator-min-microvolt = <1175000>;
  3498. + regulator-max-microvolt = <1175000>;
  3499. + regulator-boot-on;
  3500. + regulator-always-on;
  3501. + };
  3502. +
  3503. + sw2_reg: ltc3676__sw2 {
  3504. + regulator-min-microvolt = <1800000>;
  3505. + regulator-max-microvolt = <1800000>;
  3506. + regulator-boot-on;
  3507. + regulator-always-on;
  3508. + };
  3509. +
  3510. + sw3_reg: ltc3676__sw3 {
  3511. + regulator-min-microvolt = <1175000>;
  3512. + regulator-max-microvolt = <1175000>;
  3513. + regulator-boot-on;
  3514. + regulator-always-on;
  3515. + };
  3516. +
  3517. + sw4_reg: ltc3676__sw4 {
  3518. + regulator-min-microvolt = <1500000>;
  3519. + regulator-max-microvolt = <1500000>;
  3520. + regulator-boot-on;
  3521. + regulator-always-on;
  3522. + };
  3523. +
  3524. + ldo2_reg: ltc3676__ldo2 {
  3525. + regulator-min-microvolt = <2500000>;
  3526. + regulator-max-microvolt = <2500000>;
  3527. + regulator-boot-on;
  3528. + regulator-always-on;
  3529. + };
  3530. +
  3531. + ldo4_reg: ltc3676__ldo4 {
  3532. + regulator-min-microvolt = <3000000>;
  3533. + regulator-max-microvolt = <3000000>;
  3534. + };
  3535. + };
  3536. + };
  3537. +};
  3538. +
  3539. +&i2c3 {
  3540. + clock-frequency = <100000>;
  3541. + pinctrl-names = "default";
  3542. + pinctrl-0 = <&pinctrl_i2c3>;
  3543. + status = "okay";
  3544. +
  3545. + videoin: adv7180@20 {
  3546. + compatible = "adi,adv7180";
  3547. + reg = <0x20>;
  3548. + };
  3549. +};
  3550. +
  3551. +&iomuxc {
  3552. + pinctrl-names = "default";
  3553. + pinctrl-0 = <&pinctrl_hog>;
  3554. +
  3555. + imx6qdl-gw51xx {
  3556. + pinctrl_hog: hoggrp {
  3557. + fsl,pins = <
  3558. + MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x80000000 /* MEZZ_DIO0 */
  3559. + MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x80000000 /* MEZZ_DIO1 */
  3560. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  3561. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  3562. + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* PHY Reset */
  3563. + MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x80000000 /* PCIE_RST# */
  3564. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  3565. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  3566. + >;
  3567. + };
  3568. +
  3569. + pinctrl_enet: enetgrp {
  3570. + fsl,pins = <
  3571. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  3572. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  3573. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  3574. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  3575. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  3576. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  3577. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  3578. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  3579. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  3580. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  3581. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  3582. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  3583. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  3584. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  3585. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  3586. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  3587. + >;
  3588. + };
  3589. +
  3590. + pinctrl_gpmi_nand: gpminandgrp {
  3591. + fsl,pins = <
  3592. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  3593. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  3594. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  3595. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  3596. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  3597. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  3598. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  3599. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  3600. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  3601. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  3602. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  3603. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  3604. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  3605. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  3606. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  3607. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  3608. + >;
  3609. + };
  3610. +
  3611. + pinctrl_i2c1: i2c1grp {
  3612. + fsl,pins = <
  3613. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  3614. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  3615. + >;
  3616. + };
  3617. +
  3618. + pinctrl_i2c2: i2c2grp {
  3619. + fsl,pins = <
  3620. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  3621. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  3622. + >;
  3623. + };
  3624. +
  3625. + pinctrl_i2c3: i2c3grp {
  3626. + fsl,pins = <
  3627. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  3628. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  3629. + >;
  3630. + };
  3631. +
  3632. + pinctrl_uart1: uart1grp {
  3633. + fsl,pins = <
  3634. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  3635. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  3636. + >;
  3637. + };
  3638. +
  3639. + pinctrl_uart2: uart2grp {
  3640. + fsl,pins = <
  3641. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  3642. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  3643. + >;
  3644. + };
  3645. +
  3646. + pinctrl_uart3: uart3grp {
  3647. + fsl,pins = <
  3648. + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  3649. + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  3650. + >;
  3651. + };
  3652. +
  3653. + pinctrl_uart5: uart5grp {
  3654. + fsl,pins = <
  3655. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  3656. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  3657. + >;
  3658. + };
  3659. +
  3660. + pinctrl_usbotg: usbotggrp {
  3661. + fsl,pins = <
  3662. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  3663. + >;
  3664. + };
  3665. + };
  3666. +};
  3667. +
  3668. +&pcie {
  3669. + reset-gpio = <&gpio1 0 0>;
  3670. + status = "okay";
  3671. +};
  3672. +
  3673. +&uart1 {
  3674. + pinctrl-names = "default";
  3675. + pinctrl-0 = <&pinctrl_uart1>;
  3676. + status = "okay";
  3677. +};
  3678. +
  3679. +&uart2 {
  3680. + pinctrl-names = "default";
  3681. + pinctrl-0 = <&pinctrl_uart2>;
  3682. + status = "okay";
  3683. +};
  3684. +
  3685. +&uart3 {
  3686. + pinctrl-names = "default";
  3687. + pinctrl-0 = <&pinctrl_uart3>;
  3688. + status = "okay";
  3689. +};
  3690. +
  3691. +&uart5 {
  3692. + pinctrl-names = "default";
  3693. + pinctrl-0 = <&pinctrl_uart5>;
  3694. + status = "okay";
  3695. +};
  3696. +
  3697. +&usbotg {
  3698. + vbus-supply = <&reg_usb_otg_vbus>;
  3699. + pinctrl-names = "default";
  3700. + pinctrl-0 = <&pinctrl_usbotg>;
  3701. + disable-over-current;
  3702. + status = "okay";
  3703. +};
  3704. +
  3705. +&usbh1 {
  3706. + status = "okay";
  3707. +};
  3708. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
  3709. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi 1970-01-01 01:00:00.000000000 +0100
  3710. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi 2014-08-20 19:31:39.900842271 +0200
  3711. @@ -0,0 +1,527 @@
  3712. +/*
  3713. + * Copyright 2013 Gateworks Corporation
  3714. + *
  3715. + * The code contained herein is licensed under the GNU General Public
  3716. + * License. You may obtain a copy of the GNU General Public License
  3717. + * Version 2 or later at the following locations:
  3718. + *
  3719. + * http://www.opensource.org/licenses/gpl-license.html
  3720. + * http://www.gnu.org/copyleft/gpl.html
  3721. + */
  3722. +
  3723. +/ {
  3724. + /* these are used by bootloader for disabling nodes */
  3725. + aliases {
  3726. + ethernet0 = &fec;
  3727. + led0 = &led0;
  3728. + led1 = &led1;
  3729. + led2 = &led2;
  3730. + nand = &gpmi;
  3731. + ssi0 = &ssi1;
  3732. + usb0 = &usbh1;
  3733. + usb1 = &usbotg;
  3734. + usdhc2 = &usdhc3;
  3735. + };
  3736. +
  3737. + chosen {
  3738. + bootargs = "console=ttymxc1,115200";
  3739. + };
  3740. +
  3741. + backlight {
  3742. + compatible = "pwm-backlight";
  3743. + pwms = <&pwm4 0 5000000>;
  3744. + brightness-levels = <0 4 8 16 32 64 128 255>;
  3745. + default-brightness-level = <7>;
  3746. + };
  3747. +
  3748. + leds {
  3749. + compatible = "gpio-leds";
  3750. +
  3751. + led0: user1 {
  3752. + label = "user1";
  3753. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  3754. + default-state = "on";
  3755. + linux,default-trigger = "heartbeat";
  3756. + };
  3757. +
  3758. + led1: user2 {
  3759. + label = "user2";
  3760. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  3761. + default-state = "off";
  3762. + };
  3763. +
  3764. + led2: user3 {
  3765. + label = "user3";
  3766. + gpios = <&gpio4 15 1>; /* 111 - MX6_LOCLED# */
  3767. + default-state = "off";
  3768. + };
  3769. + };
  3770. +
  3771. + memory {
  3772. + reg = <0x10000000 0x20000000>;
  3773. + };
  3774. +
  3775. + pps {
  3776. + compatible = "pps-gpio";
  3777. + gpios = <&gpio1 26 0>;
  3778. + status = "okay";
  3779. + };
  3780. +
  3781. + regulators {
  3782. + compatible = "simple-bus";
  3783. + #address-cells = <1>;
  3784. + #size-cells = <0>;
  3785. +
  3786. + reg_1p0v: regulator@0 {
  3787. + compatible = "regulator-fixed";
  3788. + reg = <0>;
  3789. + regulator-name = "1P0V";
  3790. + regulator-min-microvolt = <1000000>;
  3791. + regulator-max-microvolt = <1000000>;
  3792. + regulator-always-on;
  3793. + };
  3794. +
  3795. + /* remove this fixed regulator once ltc3676__sw2 driver available */
  3796. + reg_1p8v: regulator@1 {
  3797. + compatible = "regulator-fixed";
  3798. + reg = <1>;
  3799. + regulator-name = "1P8V";
  3800. + regulator-min-microvolt = <1800000>;
  3801. + regulator-max-microvolt = <1800000>;
  3802. + regulator-always-on;
  3803. + };
  3804. +
  3805. + reg_3p3v: regulator@2 {
  3806. + compatible = "regulator-fixed";
  3807. + reg = <2>;
  3808. + regulator-name = "3P3V";
  3809. + regulator-min-microvolt = <3300000>;
  3810. + regulator-max-microvolt = <3300000>;
  3811. + regulator-always-on;
  3812. + };
  3813. +
  3814. + reg_5p0v: regulator@3 {
  3815. + compatible = "regulator-fixed";
  3816. + reg = <3>;
  3817. + regulator-name = "5P0V";
  3818. + regulator-min-microvolt = <5000000>;
  3819. + regulator-max-microvolt = <5000000>;
  3820. + regulator-always-on;
  3821. + };
  3822. +
  3823. + reg_usb_otg_vbus: regulator@4 {
  3824. + compatible = "regulator-fixed";
  3825. + reg = <4>;
  3826. + regulator-name = "usb_otg_vbus";
  3827. + regulator-min-microvolt = <5000000>;
  3828. + regulator-max-microvolt = <5000000>;
  3829. + gpio = <&gpio3 22 0>;
  3830. + enable-active-high;
  3831. + };
  3832. + };
  3833. +
  3834. + sound {
  3835. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  3836. + "fsl,imx-audio-sgtl5000";
  3837. + model = "imx6q-sabrelite-sgtl5000";
  3838. + ssi-controller = <&ssi1>;
  3839. + audio-codec = <&codec>;
  3840. + audio-routing =
  3841. + "MIC_IN", "Mic Jack",
  3842. + "Mic Jack", "Mic Bias",
  3843. + "Headphone Jack", "HP_OUT";
  3844. + mux-int-port = <1>;
  3845. + mux-ext-port = <4>;
  3846. + };
  3847. +};
  3848. +
  3849. +&audmux {
  3850. + pinctrl-names = "default";
  3851. + pinctrl-0 = <&pinctrl_audmux>;
  3852. + status = "okay";
  3853. +};
  3854. +
  3855. +&fec {
  3856. + pinctrl-names = "default";
  3857. + pinctrl-0 = <&pinctrl_enet>;
  3858. + phy-mode = "rgmii";
  3859. + phy-reset-gpios = <&gpio1 30 0>;
  3860. + status = "okay";
  3861. +};
  3862. +
  3863. +&gpmi {
  3864. + pinctrl-names = "default";
  3865. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  3866. + status = "okay";
  3867. +};
  3868. +
  3869. +&i2c1 {
  3870. + clock-frequency = <100000>;
  3871. + pinctrl-names = "default";
  3872. + pinctrl-0 = <&pinctrl_i2c1>;
  3873. + status = "okay";
  3874. +
  3875. + eeprom1: eeprom@50 {
  3876. + compatible = "atmel,24c02";
  3877. + reg = <0x50>;
  3878. + pagesize = <16>;
  3879. + };
  3880. +
  3881. + eeprom2: eeprom@51 {
  3882. + compatible = "atmel,24c02";
  3883. + reg = <0x51>;
  3884. + pagesize = <16>;
  3885. + };
  3886. +
  3887. + eeprom3: eeprom@52 {
  3888. + compatible = "atmel,24c02";
  3889. + reg = <0x52>;
  3890. + pagesize = <16>;
  3891. + };
  3892. +
  3893. + eeprom4: eeprom@53 {
  3894. + compatible = "atmel,24c02";
  3895. + reg = <0x53>;
  3896. + pagesize = <16>;
  3897. + };
  3898. +
  3899. + gpio: pca9555@23 {
  3900. + compatible = "nxp,pca9555";
  3901. + reg = <0x23>;
  3902. + gpio-controller;
  3903. + #gpio-cells = <2>;
  3904. + };
  3905. +
  3906. + hwmon: gsc@29 {
  3907. + compatible = "gw,gsp";
  3908. + reg = <0x29>;
  3909. + };
  3910. +
  3911. + rtc: ds1672@68 {
  3912. + compatible = "dallas,ds1672";
  3913. + reg = <0x68>;
  3914. + };
  3915. +};
  3916. +
  3917. +&i2c2 {
  3918. + clock-frequency = <100000>;
  3919. + pinctrl-names = "default";
  3920. + pinctrl-0 = <&pinctrl_i2c2>;
  3921. + status = "okay";
  3922. +
  3923. + pciswitch: pex8609@3f {
  3924. + compatible = "plx,pex8609";
  3925. + reg = <0x3f>;
  3926. + };
  3927. +
  3928. + pmic: ltc3676@3c {
  3929. + compatible = "ltc,ltc3676";
  3930. + reg = <0x3c>;
  3931. +
  3932. + regulators {
  3933. + sw1_reg: ltc3676__sw1 {
  3934. + regulator-min-microvolt = <1175000>;
  3935. + regulator-max-microvolt = <1175000>;
  3936. + regulator-boot-on;
  3937. + regulator-always-on;
  3938. + };
  3939. +
  3940. + sw2_reg: ltc3676__sw2 {
  3941. + regulator-min-microvolt = <1800000>;
  3942. + regulator-max-microvolt = <1800000>;
  3943. + regulator-boot-on;
  3944. + regulator-always-on;
  3945. + };
  3946. +
  3947. + sw3_reg: ltc3676__sw3 {
  3948. + regulator-min-microvolt = <1175000>;
  3949. + regulator-max-microvolt = <1175000>;
  3950. + regulator-boot-on;
  3951. + regulator-always-on;
  3952. + };
  3953. +
  3954. + sw4_reg: ltc3676__sw4 {
  3955. + regulator-min-microvolt = <1500000>;
  3956. + regulator-max-microvolt = <1500000>;
  3957. + regulator-boot-on;
  3958. + regulator-always-on;
  3959. + };
  3960. +
  3961. + ldo2_reg: ltc3676__ldo2 {
  3962. + regulator-min-microvolt = <2500000>;
  3963. + regulator-max-microvolt = <2500000>;
  3964. + regulator-boot-on;
  3965. + regulator-always-on;
  3966. + };
  3967. +
  3968. + ldo3_reg: ltc3676__ldo3 {
  3969. + regulator-min-microvolt = <1800000>;
  3970. + regulator-max-microvolt = <1800000>;
  3971. + regulator-boot-on;
  3972. + regulator-always-on;
  3973. + };
  3974. +
  3975. + ldo4_reg: ltc3676__ldo4 {
  3976. + regulator-min-microvolt = <3000000>;
  3977. + regulator-max-microvolt = <3000000>;
  3978. + };
  3979. + };
  3980. + };
  3981. +};
  3982. +
  3983. +&i2c3 {
  3984. + clock-frequency = <100000>;
  3985. + pinctrl-names = "default";
  3986. + pinctrl-0 = <&pinctrl_i2c3>;
  3987. + status = "okay";
  3988. +
  3989. + accelerometer: fxos8700@1e {
  3990. + compatible = "fsl,fxos8700";
  3991. + reg = <0x13>;
  3992. + };
  3993. +
  3994. + codec: sgtl5000@0a {
  3995. + compatible = "fsl,sgtl5000";
  3996. + reg = <0x0a>;
  3997. + clocks = <&clks 169>;
  3998. + VDDA-supply = <&reg_1p8v>;
  3999. + VDDIO-supply = <&reg_3p3v>;
  4000. + };
  4001. +
  4002. + touchscreen: egalax_ts@04 {
  4003. + compatible = "eeti,egalax_ts";
  4004. + reg = <0x04>;
  4005. + interrupt-parent = <&gpio7>;
  4006. + interrupts = <12 2>; /* gpio7_12 active low */
  4007. + wakeup-gpios = <&gpio7 12 0>;
  4008. + };
  4009. +
  4010. + videoin: adv7180@20 {
  4011. + compatible = "adi,adv7180";
  4012. + reg = <0x20>;
  4013. + };
  4014. +};
  4015. +
  4016. +&iomuxc {
  4017. + pinctrl-names = "default";
  4018. + pinctrl-0 = <&pinctrl_hog>;
  4019. +
  4020. + imx6qdl-gw52xx {
  4021. + pinctrl_hog: hoggrp {
  4022. + fsl,pins = <
  4023. + MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x80000000 /* MEZZ_DIO0 */
  4024. + MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x80000000 /* MEZZ_DIO1 */
  4025. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  4026. + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x80000000 /* VIDDEC_PDN# */
  4027. + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* PHY Reset */
  4028. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE_RST# */
  4029. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000 /* GPS_PWDN */
  4030. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  4031. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  4032. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 /* USB_SEL_PCI */
  4033. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* TOUCH_IRQ# */
  4034. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  4035. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  4036. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  4037. + MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x80000000 /* LVDS_TCH# */
  4038. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000 /* SD3_CD# */
  4039. + MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x80000000 /* UART2_EN# */
  4040. + >;
  4041. + };
  4042. +
  4043. + pinctrl_audmux: audmuxgrp {
  4044. + fsl,pins = <
  4045. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  4046. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  4047. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  4048. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  4049. + >;
  4050. + };
  4051. +
  4052. + pinctrl_enet: enetgrp {
  4053. + fsl,pins = <
  4054. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  4055. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  4056. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  4057. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  4058. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  4059. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  4060. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  4061. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  4062. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  4063. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  4064. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  4065. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  4066. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  4067. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  4068. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  4069. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  4070. + >;
  4071. + };
  4072. +
  4073. + pinctrl_gpmi_nand: gpminandgrp {
  4074. + fsl,pins = <
  4075. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  4076. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  4077. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  4078. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  4079. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  4080. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  4081. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  4082. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  4083. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  4084. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  4085. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  4086. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  4087. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  4088. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  4089. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  4090. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  4091. + >;
  4092. + };
  4093. +
  4094. + pinctrl_i2c1: i2c1grp {
  4095. + fsl,pins = <
  4096. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  4097. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  4098. + >;
  4099. + };
  4100. +
  4101. + pinctrl_i2c2: i2c2grp {
  4102. + fsl,pins = <
  4103. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  4104. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  4105. + >;
  4106. + };
  4107. +
  4108. + pinctrl_i2c3: i2c3grp {
  4109. + fsl,pins = <
  4110. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  4111. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  4112. + >;
  4113. + };
  4114. +
  4115. + pinctrl_pwm4: pwm4grp {
  4116. + fsl,pins = <
  4117. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  4118. + >;
  4119. + };
  4120. +
  4121. + pinctrl_uart1: uart1grp {
  4122. + fsl,pins = <
  4123. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  4124. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  4125. + >;
  4126. + };
  4127. +
  4128. + pinctrl_uart2: uart2grp {
  4129. + fsl,pins = <
  4130. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  4131. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  4132. + >;
  4133. + };
  4134. +
  4135. + pinctrl_uart5: uart5grp {
  4136. + fsl,pins = <
  4137. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  4138. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  4139. + >;
  4140. + };
  4141. +
  4142. + pinctrl_usbotg: usbotggrp {
  4143. + fsl,pins = <
  4144. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  4145. + >;
  4146. + };
  4147. +
  4148. + pinctrl_usdhc3: usdhc3grp {
  4149. + fsl,pins = <
  4150. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  4151. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  4152. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  4153. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  4154. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  4155. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  4156. + >;
  4157. + };
  4158. + };
  4159. +};
  4160. +
  4161. +&ldb {
  4162. + status = "okay";
  4163. +
  4164. + lvds-channel@0 {
  4165. + fsl,data-mapping = "spwg";
  4166. + fsl,data-width = <18>;
  4167. + status = "okay";
  4168. +
  4169. + display-timings {
  4170. + native-mode = <&timing0>;
  4171. + timing0: hsd100pxn1 {
  4172. + clock-frequency = <65000000>;
  4173. + hactive = <1024>;
  4174. + vactive = <768>;
  4175. + hback-porch = <220>;
  4176. + hfront-porch = <40>;
  4177. + vback-porch = <21>;
  4178. + vfront-porch = <7>;
  4179. + hsync-len = <60>;
  4180. + vsync-len = <10>;
  4181. + };
  4182. + };
  4183. + };
  4184. +};
  4185. +
  4186. +&pcie {
  4187. + reset-gpio = <&gpio1 29 0>;
  4188. + status = "okay";
  4189. +};
  4190. +
  4191. +&pwm4 {
  4192. + pinctrl-names = "default";
  4193. + pinctrl-0 = <&pinctrl_pwm4>;
  4194. + status = "okay";
  4195. +};
  4196. +
  4197. +&ssi1 {
  4198. + fsl,mode = "i2s-slave";
  4199. + status = "okay";
  4200. +};
  4201. +
  4202. +&uart1 {
  4203. + pinctrl-names = "default";
  4204. + pinctrl-0 = <&pinctrl_uart1>;
  4205. + status = "okay";
  4206. +};
  4207. +
  4208. +&uart2 {
  4209. + pinctrl-names = "default";
  4210. + pinctrl-0 = <&pinctrl_uart2>;
  4211. + status = "okay";
  4212. +};
  4213. +
  4214. +&uart5 {
  4215. + pinctrl-names = "default";
  4216. + pinctrl-0 = <&pinctrl_uart5>;
  4217. + status = "okay";
  4218. +};
  4219. +
  4220. +&usbotg {
  4221. + vbus-supply = <&reg_usb_otg_vbus>;
  4222. + pinctrl-names = "default";
  4223. + pinctrl-0 = <&pinctrl_usbotg>;
  4224. + disable-over-current;
  4225. + status = "okay";
  4226. +};
  4227. +
  4228. +&usbh1 {
  4229. + status = "okay";
  4230. +};
  4231. +
  4232. +&usdhc3 {
  4233. + pinctrl-names = "default";
  4234. + pinctrl-0 = <&pinctrl_usdhc3>;
  4235. + cd-gpios = <&gpio7 0 0>;
  4236. + vmmc-supply = <&reg_3p3v>;
  4237. + status = "okay";
  4238. +};
  4239. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
  4240. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi 1970-01-01 01:00:00.000000000 +0100
  4241. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi 2014-08-20 19:31:39.900842271 +0200
  4242. @@ -0,0 +1,572 @@
  4243. +/*
  4244. + * Copyright 2013 Gateworks Corporation
  4245. + *
  4246. + * The code contained herein is licensed under the GNU General Public
  4247. + * License. You may obtain a copy of the GNU General Public License
  4248. + * Version 2 or later at the following locations:
  4249. + *
  4250. + * http://www.opensource.org/licenses/gpl-license.html
  4251. + * http://www.gnu.org/copyleft/gpl.html
  4252. + */
  4253. +
  4254. +/ {
  4255. + /* these are used by bootloader for disabling nodes */
  4256. + aliases {
  4257. + can0 = &can1;
  4258. + ethernet0 = &fec;
  4259. + ethernet1 = &eth1;
  4260. + led0 = &led0;
  4261. + led1 = &led1;
  4262. + led2 = &led2;
  4263. + nand = &gpmi;
  4264. + sky2 = &eth1;
  4265. + ssi0 = &ssi1;
  4266. + usb0 = &usbh1;
  4267. + usb1 = &usbotg;
  4268. + usdhc2 = &usdhc3;
  4269. + };
  4270. +
  4271. + chosen {
  4272. + bootargs = "console=ttymxc1,115200";
  4273. + };
  4274. +
  4275. + backlight {
  4276. + compatible = "pwm-backlight";
  4277. + pwms = <&pwm4 0 5000000>;
  4278. + brightness-levels = <0 4 8 16 32 64 128 255>;
  4279. + default-brightness-level = <7>;
  4280. + };
  4281. +
  4282. + leds {
  4283. + compatible = "gpio-leds";
  4284. +
  4285. + led0: user1 {
  4286. + label = "user1";
  4287. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  4288. + default-state = "on";
  4289. + linux,default-trigger = "heartbeat";
  4290. + };
  4291. +
  4292. + led1: user2 {
  4293. + label = "user2";
  4294. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  4295. + default-state = "off";
  4296. + };
  4297. +
  4298. + led2: user3 {
  4299. + label = "user3";
  4300. + gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
  4301. + default-state = "off";
  4302. + };
  4303. + };
  4304. +
  4305. + memory {
  4306. + reg = <0x10000000 0x40000000>;
  4307. + };
  4308. +
  4309. + pps {
  4310. + compatible = "pps-gpio";
  4311. + gpios = <&gpio1 26 0>;
  4312. + status = "okay";
  4313. + };
  4314. +
  4315. + regulators {
  4316. + compatible = "simple-bus";
  4317. + #address-cells = <1>;
  4318. + #size-cells = <0>;
  4319. +
  4320. + reg_1p0v: regulator@0 {
  4321. + compatible = "regulator-fixed";
  4322. + reg = <0>;
  4323. + regulator-name = "1P0V";
  4324. + regulator-min-microvolt = <1000000>;
  4325. + regulator-max-microvolt = <1000000>;
  4326. + regulator-always-on;
  4327. + };
  4328. +
  4329. + /* remove when pmic 1p8 regulator available */
  4330. + reg_1p8v: regulator@1 {
  4331. + compatible = "regulator-fixed";
  4332. + reg = <1>;
  4333. + regulator-name = "1P8V";
  4334. + regulator-min-microvolt = <1800000>;
  4335. + regulator-max-microvolt = <1800000>;
  4336. + regulator-always-on;
  4337. + };
  4338. +
  4339. + reg_3p3v: regulator@2 {
  4340. + compatible = "regulator-fixed";
  4341. + reg = <2>;
  4342. + regulator-name = "3P3V";
  4343. + regulator-min-microvolt = <3300000>;
  4344. + regulator-max-microvolt = <3300000>;
  4345. + regulator-always-on;
  4346. + };
  4347. +
  4348. + reg_usb_h1_vbus: regulator@3 {
  4349. + compatible = "regulator-fixed";
  4350. + reg = <3>;
  4351. + regulator-name = "usb_h1_vbus";
  4352. + regulator-min-microvolt = <5000000>;
  4353. + regulator-max-microvolt = <5000000>;
  4354. + regulator-always-on;
  4355. + };
  4356. +
  4357. + reg_usb_otg_vbus: regulator@4 {
  4358. + compatible = "regulator-fixed";
  4359. + reg = <4>;
  4360. + regulator-name = "usb_otg_vbus";
  4361. + regulator-min-microvolt = <5000000>;
  4362. + regulator-max-microvolt = <5000000>;
  4363. + gpio = <&gpio3 22 0>;
  4364. + enable-active-high;
  4365. + };
  4366. + };
  4367. +
  4368. + sound {
  4369. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  4370. + "fsl,imx-audio-sgtl5000";
  4371. + model = "imx6q-sabrelite-sgtl5000";
  4372. + ssi-controller = <&ssi1>;
  4373. + audio-codec = <&codec>;
  4374. + audio-routing =
  4375. + "MIC_IN", "Mic Jack",
  4376. + "Mic Jack", "Mic Bias",
  4377. + "Headphone Jack", "HP_OUT";
  4378. + mux-int-port = <1>;
  4379. + mux-ext-port = <4>;
  4380. + };
  4381. +};
  4382. +
  4383. +&audmux {
  4384. + pinctrl-names = "default";
  4385. + pinctrl-0 = <&pinctrl_audmux>;
  4386. + status = "okay";
  4387. +};
  4388. +
  4389. +&can1 {
  4390. + pinctrl-names = "default";
  4391. + pinctrl-0 = <&pinctrl_flexcan1>;
  4392. + status = "okay";
  4393. +};
  4394. +
  4395. +&fec {
  4396. + pinctrl-names = "default";
  4397. + pinctrl-0 = <&pinctrl_enet>;
  4398. + phy-mode = "rgmii";
  4399. + phy-reset-gpios = <&gpio1 30 0>;
  4400. + status = "okay";
  4401. +};
  4402. +
  4403. +&gpmi {
  4404. + pinctrl-names = "default";
  4405. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  4406. + status = "okay";
  4407. +};
  4408. +
  4409. +&i2c1 {
  4410. + clock-frequency = <100000>;
  4411. + pinctrl-names = "default";
  4412. + pinctrl-0 = <&pinctrl_i2c1>;
  4413. + status = "okay";
  4414. +
  4415. + eeprom1: eeprom@50 {
  4416. + compatible = "atmel,24c02";
  4417. + reg = <0x50>;
  4418. + pagesize = <16>;
  4419. + };
  4420. +
  4421. + eeprom2: eeprom@51 {
  4422. + compatible = "atmel,24c02";
  4423. + reg = <0x51>;
  4424. + pagesize = <16>;
  4425. + };
  4426. +
  4427. + eeprom3: eeprom@52 {
  4428. + compatible = "atmel,24c02";
  4429. + reg = <0x52>;
  4430. + pagesize = <16>;
  4431. + };
  4432. +
  4433. + eeprom4: eeprom@53 {
  4434. + compatible = "atmel,24c02";
  4435. + reg = <0x53>;
  4436. + pagesize = <16>;
  4437. + };
  4438. +
  4439. + gpio: pca9555@23 {
  4440. + compatible = "nxp,pca9555";
  4441. + reg = <0x23>;
  4442. + gpio-controller;
  4443. + #gpio-cells = <2>;
  4444. + };
  4445. +
  4446. + hwmon: gsc@29 {
  4447. + compatible = "gw,gsp";
  4448. + reg = <0x29>;
  4449. + };
  4450. +
  4451. + rtc: ds1672@68 {
  4452. + compatible = "dallas,ds1672";
  4453. + reg = <0x68>;
  4454. + };
  4455. +};
  4456. +
  4457. +&i2c2 {
  4458. + clock-frequency = <100000>;
  4459. + pinctrl-names = "default";
  4460. + pinctrl-0 = <&pinctrl_i2c2>;
  4461. + status = "okay";
  4462. +
  4463. + pciclkgen: si53156@6b {
  4464. + compatible = "sil,si53156";
  4465. + reg = <0x6b>;
  4466. + };
  4467. +
  4468. + pciswitch: pex8606@3f {
  4469. + compatible = "plx,pex8606";
  4470. + reg = <0x3f>;
  4471. + };
  4472. +
  4473. + pmic: ltc3676@3c {
  4474. + compatible = "ltc,ltc3676";
  4475. + reg = <0x3c>;
  4476. +
  4477. + regulators {
  4478. + /* VDD_SOC */
  4479. + sw1_reg: ltc3676__sw1 {
  4480. + regulator-min-microvolt = <1175000>;
  4481. + regulator-max-microvolt = <1175000>;
  4482. + regulator-boot-on;
  4483. + regulator-always-on;
  4484. + };
  4485. +
  4486. + /* VDD_1P8 */
  4487. + sw2_reg: ltc3676__sw2 {
  4488. + regulator-min-microvolt = <1800000>;
  4489. + regulator-max-microvolt = <1800000>;
  4490. + regulator-boot-on;
  4491. + regulator-always-on;
  4492. + };
  4493. +
  4494. + /* VDD_ARM */
  4495. + sw3_reg: ltc3676__sw3 {
  4496. + regulator-min-microvolt = <1175000>;
  4497. + regulator-max-microvolt = <1175000>;
  4498. + regulator-boot-on;
  4499. + regulator-always-on;
  4500. + };
  4501. +
  4502. + /* VDD_DDR */
  4503. + sw4_reg: ltc3676__sw4 {
  4504. + regulator-min-microvolt = <1500000>;
  4505. + regulator-max-microvolt = <1500000>;
  4506. + regulator-boot-on;
  4507. + regulator-always-on;
  4508. + };
  4509. +
  4510. + /* VDD_2P5 */
  4511. + ldo2_reg: ltc3676__ldo2 {
  4512. + regulator-min-microvolt = <2500000>;
  4513. + regulator-max-microvolt = <2500000>;
  4514. + regulator-boot-on;
  4515. + regulator-always-on;
  4516. + };
  4517. +
  4518. + /* VDD_1P8 */
  4519. + ldo3_reg: ltc3676__ldo3 {
  4520. + regulator-min-microvolt = <1800000>;
  4521. + regulator-max-microvolt = <1800000>;
  4522. + regulator-boot-on;
  4523. + regulator-always-on;
  4524. + };
  4525. +
  4526. + /* VDD_HIGH */
  4527. + ldo4_reg: ltc3676__ldo4 {
  4528. + regulator-min-microvolt = <3000000>;
  4529. + regulator-max-microvolt = <3000000>;
  4530. + };
  4531. + };
  4532. + };
  4533. +};
  4534. +
  4535. +&i2c3 {
  4536. + clock-frequency = <100000>;
  4537. + pinctrl-names = "default";
  4538. + pinctrl-0 = <&pinctrl_i2c3>;
  4539. + status = "okay";
  4540. +
  4541. + accelerometer: fxos8700@1e {
  4542. + compatible = "fsl,fxos8700";
  4543. + reg = <0x1e>;
  4544. + };
  4545. +
  4546. + codec: sgtl5000@0a {
  4547. + compatible = "fsl,sgtl5000";
  4548. + reg = <0x0a>;
  4549. + clocks = <&clks 201>;
  4550. + VDDA-supply = <&reg_1p8v>;
  4551. + VDDIO-supply = <&reg_3p3v>;
  4552. + };
  4553. +
  4554. + hdmiin: adv7611@4c {
  4555. + compatible = "adi,adv7611";
  4556. + reg = <0x4c>;
  4557. + };
  4558. +
  4559. + touchscreen: egalax_ts@04 {
  4560. + compatible = "eeti,egalax_ts";
  4561. + reg = <0x04>;
  4562. + interrupt-parent = <&gpio1>;
  4563. + interrupts = <11 2>; /* gpio1_11 active low */
  4564. + wakeup-gpios = <&gpio1 11 0>;
  4565. + };
  4566. +
  4567. + videoout: adv7393@2a {
  4568. + compatible = "adi,adv7393";
  4569. + reg = <0x2a>;
  4570. + };
  4571. +
  4572. + videoin: adv7180@20 {
  4573. + compatible = "adi,adv7180";
  4574. + reg = <0x20>;
  4575. + };
  4576. +};
  4577. +
  4578. +&iomuxc {
  4579. + pinctrl-names = "default";
  4580. + pinctrl-0 = <&pinctrl_hog>;
  4581. +
  4582. + imx6qdl-gw53xx {
  4583. + pinctrl_hog: hoggrp {
  4584. + fsl,pins = <
  4585. + MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x80000000 /* PCIE6EXP_DIO0 */
  4586. + MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x80000000 /* PCIE6EXP_DIO1 */
  4587. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  4588. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000 /* GPS_SHDN */
  4589. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  4590. + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
  4591. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE RST */
  4592. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  4593. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 /* CAN_STBY */
  4594. + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x80000000 /* PMIC_IRQ# */
  4595. + MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x80000000 /* HUB_RST# */
  4596. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* PCIE_WDIS# */
  4597. + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x80000000 /* ACCEL_IRQ# */
  4598. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  4599. + MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x80000000 /* USBOTG_OC# */
  4600. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  4601. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  4602. + MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x80000000 /* TOUCH_IRQ# */
  4603. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000 /* SD3_DET# */
  4604. + >;
  4605. + };
  4606. +
  4607. + pinctrl_audmux: audmuxgrp {
  4608. + fsl,pins = <
  4609. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  4610. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  4611. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  4612. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  4613. + >;
  4614. + };
  4615. +
  4616. + pinctrl_enet: enetgrp {
  4617. + fsl,pins = <
  4618. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  4619. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  4620. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  4621. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  4622. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  4623. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  4624. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  4625. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  4626. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  4627. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  4628. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  4629. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  4630. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  4631. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  4632. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  4633. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  4634. + >;
  4635. + };
  4636. +
  4637. + pinctrl_flexcan1: flexcan1grp {
  4638. + fsl,pins = <
  4639. + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  4640. + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x80000000
  4641. + >;
  4642. + };
  4643. +
  4644. + pinctrl_gpmi_nand: gpminandgrp {
  4645. + fsl,pins = <
  4646. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  4647. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  4648. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  4649. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  4650. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  4651. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  4652. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  4653. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  4654. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  4655. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  4656. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  4657. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  4658. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  4659. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  4660. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  4661. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  4662. + >;
  4663. + };
  4664. +
  4665. + pinctrl_i2c1: i2c1grp {
  4666. + fsl,pins = <
  4667. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  4668. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  4669. + >;
  4670. + };
  4671. +
  4672. + pinctrl_i2c2: i2c2grp {
  4673. + fsl,pins = <
  4674. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  4675. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  4676. + >;
  4677. + };
  4678. +
  4679. + pinctrl_i2c3: i2c3grp {
  4680. + fsl,pins = <
  4681. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  4682. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  4683. + >;
  4684. + };
  4685. +
  4686. + pinctrl_pwm4: pwm4grp {
  4687. + fsl,pins = <
  4688. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  4689. + >;
  4690. + };
  4691. +
  4692. + pinctrl_uart1: uart1grp {
  4693. + fsl,pins = <
  4694. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  4695. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  4696. + >;
  4697. + };
  4698. +
  4699. + pinctrl_uart2: uart2grp {
  4700. + fsl,pins = <
  4701. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  4702. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  4703. + >;
  4704. + };
  4705. +
  4706. + pinctrl_uart5: uart5grp {
  4707. + fsl,pins = <
  4708. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  4709. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  4710. + >;
  4711. + };
  4712. +
  4713. + pinctrl_usbotg: usbotggrp {
  4714. + fsl,pins = <
  4715. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  4716. + >;
  4717. + };
  4718. +
  4719. + pinctrl_usdhc3: usdhc3grp {
  4720. + fsl,pins = <
  4721. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  4722. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  4723. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  4724. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  4725. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  4726. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  4727. + >;
  4728. + };
  4729. + };
  4730. +};
  4731. +
  4732. +&ldb {
  4733. + status = "okay";
  4734. +
  4735. + lvds-channel@1 {
  4736. + fsl,data-mapping = "spwg";
  4737. + fsl,data-width = <18>;
  4738. + status = "okay";
  4739. +
  4740. + display-timings {
  4741. + native-mode = <&timing0>;
  4742. + timing0: hsd100pxn1 {
  4743. + clock-frequency = <65000000>;
  4744. + hactive = <1024>;
  4745. + vactive = <768>;
  4746. + hback-porch = <220>;
  4747. + hfront-porch = <40>;
  4748. + vback-porch = <21>;
  4749. + vfront-porch = <7>;
  4750. + hsync-len = <60>;
  4751. + vsync-len = <10>;
  4752. + };
  4753. + };
  4754. + };
  4755. +};
  4756. +
  4757. +&pcie {
  4758. + reset-gpio = <&gpio1 29 0>;
  4759. + status = "okay";
  4760. +
  4761. + eth1: sky2@8 { /* MAC/PHY on bus 8 */
  4762. + compatible = "marvell,sky2";
  4763. + };
  4764. +};
  4765. +
  4766. +&pwm4 {
  4767. + pinctrl-names = "default";
  4768. + pinctrl-0 = <&pinctrl_pwm4>;
  4769. + status = "okay";
  4770. +};
  4771. +
  4772. +&ssi1 {
  4773. + fsl,mode = "i2s-slave";
  4774. + status = "okay";
  4775. +};
  4776. +
  4777. +&uart1 {
  4778. + pinctrl-names = "default";
  4779. + pinctrl-0 = <&pinctrl_uart1>;
  4780. + status = "okay";
  4781. +};
  4782. +
  4783. +&uart2 {
  4784. + pinctrl-names = "default";
  4785. + pinctrl-0 = <&pinctrl_uart2>;
  4786. + status = "okay";
  4787. +};
  4788. +
  4789. +&uart5 {
  4790. + pinctrl-names = "default";
  4791. + pinctrl-0 = <&pinctrl_uart5>;
  4792. + status = "okay";
  4793. +};
  4794. +
  4795. +&usbotg {
  4796. + vbus-supply = <&reg_usb_otg_vbus>;
  4797. + pinctrl-names = "default";
  4798. + pinctrl-0 = <&pinctrl_usbotg>;
  4799. + disable-over-current;
  4800. + status = "okay";
  4801. +};
  4802. +
  4803. +&usbh1 {
  4804. + vbus-supply = <&reg_usb_h1_vbus>;
  4805. + status = "okay";
  4806. +};
  4807. +
  4808. +&usdhc3 {
  4809. + pinctrl-names = "default";
  4810. + pinctrl-0 = <&pinctrl_usdhc3>;
  4811. + cd-gpios = <&gpio7 0 0>;
  4812. + vmmc-supply = <&reg_3p3v>;
  4813. + status = "okay";
  4814. +};
  4815. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
  4816. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi 1970-01-01 01:00:00.000000000 +0100
  4817. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi 2014-08-20 19:31:39.900842271 +0200
  4818. @@ -0,0 +1,599 @@
  4819. +/*
  4820. + * Copyright 2013 Gateworks Corporation
  4821. + *
  4822. + * The code contained herein is licensed under the GNU General Public
  4823. + * License. You may obtain a copy of the GNU General Public License
  4824. + * Version 2 or later at the following locations:
  4825. + *
  4826. + * http://www.opensource.org/licenses/gpl-license.html
  4827. + * http://www.gnu.org/copyleft/gpl.html
  4828. + */
  4829. +
  4830. +/ {
  4831. + /* these are used by bootloader for disabling nodes */
  4832. + aliases {
  4833. + can0 = &can1;
  4834. + ethernet0 = &fec;
  4835. + ethernet1 = &eth1;
  4836. + led0 = &led0;
  4837. + led1 = &led1;
  4838. + led2 = &led2;
  4839. + nand = &gpmi;
  4840. + sky2 = &eth1;
  4841. + ssi0 = &ssi1;
  4842. + usb0 = &usbh1;
  4843. + usb1 = &usbotg;
  4844. + usdhc2 = &usdhc3;
  4845. + };
  4846. +
  4847. + chosen {
  4848. + bootargs = "console=ttymxc1,115200";
  4849. + };
  4850. +
  4851. + backlight {
  4852. + compatible = "pwm-backlight";
  4853. + pwms = <&pwm4 0 5000000>;
  4854. + brightness-levels = <0 4 8 16 32 64 128 255>;
  4855. + default-brightness-level = <7>;
  4856. + };
  4857. +
  4858. + leds {
  4859. + compatible = "gpio-leds";
  4860. +
  4861. + led0: user1 {
  4862. + label = "user1";
  4863. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  4864. + default-state = "on";
  4865. + linux,default-trigger = "heartbeat";
  4866. + };
  4867. +
  4868. + led1: user2 {
  4869. + label = "user2";
  4870. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  4871. + default-state = "off";
  4872. + };
  4873. +
  4874. + led2: user3 {
  4875. + label = "user3";
  4876. + gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
  4877. + default-state = "off";
  4878. + };
  4879. + };
  4880. +
  4881. + memory {
  4882. + reg = <0x10000000 0x40000000>;
  4883. + };
  4884. +
  4885. + pps {
  4886. + compatible = "pps-gpio";
  4887. + gpios = <&gpio1 26 0>;
  4888. + status = "okay";
  4889. + };
  4890. +
  4891. + regulators {
  4892. + compatible = "simple-bus";
  4893. + #address-cells = <1>;
  4894. + #size-cells = <0>;
  4895. +
  4896. + reg_1p0v: regulator@0 {
  4897. + compatible = "regulator-fixed";
  4898. + reg = <0>;
  4899. + regulator-name = "1P0V";
  4900. + regulator-min-microvolt = <1000000>;
  4901. + regulator-max-microvolt = <1000000>;
  4902. + regulator-always-on;
  4903. + };
  4904. +
  4905. + reg_3p3v: regulator@1 {
  4906. + compatible = "regulator-fixed";
  4907. + reg = <1>;
  4908. + regulator-name = "3P3V";
  4909. + regulator-min-microvolt = <3300000>;
  4910. + regulator-max-microvolt = <3300000>;
  4911. + regulator-always-on;
  4912. + };
  4913. +
  4914. + reg_usb_h1_vbus: regulator@2 {
  4915. + compatible = "regulator-fixed";
  4916. + reg = <2>;
  4917. + regulator-name = "usb_h1_vbus";
  4918. + regulator-min-microvolt = <5000000>;
  4919. + regulator-max-microvolt = <5000000>;
  4920. + regulator-always-on;
  4921. + };
  4922. +
  4923. + reg_usb_otg_vbus: regulator@3 {
  4924. + compatible = "regulator-fixed";
  4925. + reg = <3>;
  4926. + regulator-name = "usb_otg_vbus";
  4927. + regulator-min-microvolt = <5000000>;
  4928. + regulator-max-microvolt = <5000000>;
  4929. + gpio = <&gpio3 22 0>;
  4930. + enable-active-high;
  4931. + };
  4932. + };
  4933. +
  4934. + sound {
  4935. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  4936. + "fsl,imx-audio-sgtl5000";
  4937. + model = "imx6q-sabrelite-sgtl5000";
  4938. + ssi-controller = <&ssi1>;
  4939. + audio-codec = <&codec>;
  4940. + audio-routing =
  4941. + "MIC_IN", "Mic Jack",
  4942. + "Mic Jack", "Mic Bias",
  4943. + "Headphone Jack", "HP_OUT";
  4944. + mux-int-port = <1>;
  4945. + mux-ext-port = <4>;
  4946. + };
  4947. +};
  4948. +
  4949. +&audmux {
  4950. + pinctrl-names = "default";
  4951. + pinctrl-0 = <&pinctrl_audmux>; /* AUD4<->sgtl5000 */
  4952. + status = "okay";
  4953. +};
  4954. +
  4955. +&can1 {
  4956. + pinctrl-names = "default";
  4957. + pinctrl-0 = <&pinctrl_flexcan1>;
  4958. + status = "okay";
  4959. +};
  4960. +
  4961. +&fec {
  4962. + pinctrl-names = "default";
  4963. + pinctrl-0 = <&pinctrl_enet>;
  4964. + phy-mode = "rgmii";
  4965. + phy-reset-gpios = <&gpio1 30 0>;
  4966. + status = "okay";
  4967. +};
  4968. +
  4969. +&gpmi {
  4970. + pinctrl-names = "default";
  4971. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  4972. + status = "okay";
  4973. +};
  4974. +
  4975. +&i2c1 {
  4976. + clock-frequency = <100000>;
  4977. + pinctrl-names = "default";
  4978. + pinctrl-0 = <&pinctrl_i2c1>;
  4979. + status = "okay";
  4980. +
  4981. + eeprom1: eeprom@50 {
  4982. + compatible = "atmel,24c02";
  4983. + reg = <0x50>;
  4984. + pagesize = <16>;
  4985. + };
  4986. +
  4987. + eeprom2: eeprom@51 {
  4988. + compatible = "atmel,24c02";
  4989. + reg = <0x51>;
  4990. + pagesize = <16>;
  4991. + };
  4992. +
  4993. + eeprom3: eeprom@52 {
  4994. + compatible = "atmel,24c02";
  4995. + reg = <0x52>;
  4996. + pagesize = <16>;
  4997. + };
  4998. +
  4999. + eeprom4: eeprom@53 {
  5000. + compatible = "atmel,24c02";
  5001. + reg = <0x53>;
  5002. + pagesize = <16>;
  5003. + };
  5004. +
  5005. + gpio: pca9555@23 {
  5006. + compatible = "nxp,pca9555";
  5007. + reg = <0x23>;
  5008. + gpio-controller;
  5009. + #gpio-cells = <2>;
  5010. + };
  5011. +
  5012. + hwmon: gsc@29 {
  5013. + compatible = "gw,gsp";
  5014. + reg = <0x29>;
  5015. + };
  5016. +
  5017. + rtc: ds1672@68 {
  5018. + compatible = "dallas,ds1672";
  5019. + reg = <0x68>;
  5020. + };
  5021. +};
  5022. +
  5023. +&i2c2 {
  5024. + clock-frequency = <100000>;
  5025. + pinctrl-names = "default";
  5026. + pinctrl-0 = <&pinctrl_i2c2>;
  5027. + status = "okay";
  5028. +
  5029. + pmic: pfuze100@08 {
  5030. + compatible = "fsl,pfuze100";
  5031. + reg = <0x08>;
  5032. +
  5033. + regulators {
  5034. + sw1a_reg: sw1ab {
  5035. + regulator-min-microvolt = <300000>;
  5036. + regulator-max-microvolt = <1875000>;
  5037. + regulator-boot-on;
  5038. + regulator-always-on;
  5039. + regulator-ramp-delay = <6250>;
  5040. + };
  5041. +
  5042. + sw1c_reg: sw1c {
  5043. + regulator-min-microvolt = <300000>;
  5044. + regulator-max-microvolt = <1875000>;
  5045. + regulator-boot-on;
  5046. + regulator-always-on;
  5047. + regulator-ramp-delay = <6250>;
  5048. + };
  5049. +
  5050. + sw2_reg: sw2 {
  5051. + regulator-min-microvolt = <800000>;
  5052. + regulator-max-microvolt = <3950000>;
  5053. + regulator-boot-on;
  5054. + regulator-always-on;
  5055. + };
  5056. +
  5057. + sw3a_reg: sw3a {
  5058. + regulator-min-microvolt = <400000>;
  5059. + regulator-max-microvolt = <1975000>;
  5060. + regulator-boot-on;
  5061. + regulator-always-on;
  5062. + };
  5063. +
  5064. + sw3b_reg: sw3b {
  5065. + regulator-min-microvolt = <400000>;
  5066. + regulator-max-microvolt = <1975000>;
  5067. + regulator-boot-on;
  5068. + regulator-always-on;
  5069. + };
  5070. +
  5071. + sw4_reg: sw4 {
  5072. + regulator-min-microvolt = <800000>;
  5073. + regulator-max-microvolt = <3300000>;
  5074. + };
  5075. +
  5076. + swbst_reg: swbst {
  5077. + regulator-min-microvolt = <5000000>;
  5078. + regulator-max-microvolt = <5150000>;
  5079. + };
  5080. +
  5081. + snvs_reg: vsnvs {
  5082. + regulator-min-microvolt = <1000000>;
  5083. + regulator-max-microvolt = <3000000>;
  5084. + regulator-boot-on;
  5085. + regulator-always-on;
  5086. + };
  5087. +
  5088. + vref_reg: vrefddr {
  5089. + regulator-boot-on;
  5090. + regulator-always-on;
  5091. + };
  5092. +
  5093. + vgen1_reg: vgen1 {
  5094. + regulator-min-microvolt = <800000>;
  5095. + regulator-max-microvolt = <1550000>;
  5096. + };
  5097. +
  5098. + vgen2_reg: vgen2 {
  5099. + regulator-min-microvolt = <800000>;
  5100. + regulator-max-microvolt = <1550000>;
  5101. + };
  5102. +
  5103. + vgen3_reg: vgen3 {
  5104. + regulator-min-microvolt = <1800000>;
  5105. + regulator-max-microvolt = <3300000>;
  5106. + };
  5107. +
  5108. + vgen4_reg: vgen4 {
  5109. + regulator-min-microvolt = <1800000>;
  5110. + regulator-max-microvolt = <3300000>;
  5111. + regulator-always-on;
  5112. + };
  5113. +
  5114. + vgen5_reg: vgen5 {
  5115. + regulator-min-microvolt = <1800000>;
  5116. + regulator-max-microvolt = <3300000>;
  5117. + regulator-always-on;
  5118. + };
  5119. +
  5120. + vgen6_reg: vgen6 {
  5121. + regulator-min-microvolt = <1800000>;
  5122. + regulator-max-microvolt = <3300000>;
  5123. + regulator-always-on;
  5124. + };
  5125. + };
  5126. + };
  5127. +
  5128. + pciswitch: pex8609@3f {
  5129. + compatible = "plx,pex8609";
  5130. + reg = <0x3f>;
  5131. + };
  5132. +
  5133. + pciclkgen: si52147@6b {
  5134. + compatible = "sil,si52147";
  5135. + reg = <0x6b>;
  5136. + };
  5137. +};
  5138. +
  5139. +&i2c3 {
  5140. + clock-frequency = <100000>;
  5141. + pinctrl-names = "default";
  5142. + pinctrl-0 = <&pinctrl_i2c3>;
  5143. + status = "okay";
  5144. +
  5145. + accelerometer: fxos8700@1e {
  5146. + compatible = "fsl,fxos8700";
  5147. + reg = <0x1e>;
  5148. + };
  5149. +
  5150. + codec: sgtl5000@0a {
  5151. + compatible = "fsl,sgtl5000";
  5152. + reg = <0x0a>;
  5153. + clocks = <&clks 201>;
  5154. + VDDA-supply = <&sw4_reg>;
  5155. + VDDIO-supply = <&reg_3p3v>;
  5156. + };
  5157. +
  5158. + hdmiin: adv7611@4c {
  5159. + compatible = "adi,adv7611";
  5160. + reg = <0x4c>;
  5161. + };
  5162. +
  5163. + touchscreen: egalax_ts@04 {
  5164. + compatible = "eeti,egalax_ts";
  5165. + reg = <0x04>;
  5166. + interrupt-parent = <&gpio7>;
  5167. + interrupts = <12 2>; /* gpio7_12 active low */
  5168. + wakeup-gpios = <&gpio7 12 0>;
  5169. + };
  5170. +
  5171. + videoout: adv7393@2a {
  5172. + compatible = "adi,adv7393";
  5173. + reg = <0x2a>;
  5174. + };
  5175. +
  5176. + videoin: adv7180@20 {
  5177. + compatible = "adi,adv7180";
  5178. + reg = <0x20>;
  5179. + };
  5180. +};
  5181. +
  5182. +&iomuxc {
  5183. + pinctrl-names = "default";
  5184. + pinctrl-0 = <&pinctrl_hog>;
  5185. +
  5186. + imx6qdl-gw54xx {
  5187. + pinctrl_hog: hoggrp {
  5188. + fsl,pins = <
  5189. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  5190. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000 /* SPINOR_CS0# */
  5191. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  5192. + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
  5193. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE RST */
  5194. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  5195. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 /* CAN_STBY */
  5196. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* TOUCH_IRQ# */
  5197. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  5198. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  5199. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  5200. + MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x80000000 /* USBHUB_RST# */
  5201. + MX6QDL_PAD_SD1_DAT3__GPIO1_IO21 0x80000000 /* MIPI_DIO */
  5202. + >;
  5203. + };
  5204. +
  5205. + pinctrl_audmux: audmuxgrp {
  5206. + fsl,pins = <
  5207. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  5208. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  5209. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  5210. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  5211. + >;
  5212. + };
  5213. +
  5214. + pinctrl_enet: enetgrp {
  5215. + fsl,pins = <
  5216. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  5217. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  5218. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  5219. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  5220. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  5221. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  5222. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  5223. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  5224. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  5225. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  5226. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  5227. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  5228. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  5229. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  5230. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  5231. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  5232. + >;
  5233. + };
  5234. +
  5235. + pinctrl_flexcan1: flexcan1grp {
  5236. + fsl,pins = <
  5237. + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  5238. + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x80000000
  5239. + >;
  5240. + };
  5241. +
  5242. + pinctrl_gpmi_nand: gpminandgrp {
  5243. + fsl,pins = <
  5244. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  5245. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  5246. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  5247. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  5248. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  5249. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  5250. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  5251. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  5252. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  5253. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  5254. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  5255. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  5256. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  5257. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  5258. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  5259. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  5260. + >;
  5261. + };
  5262. +
  5263. + pinctrl_i2c1: i2c1grp {
  5264. + fsl,pins = <
  5265. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  5266. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  5267. + >;
  5268. + };
  5269. +
  5270. + pinctrl_i2c2: i2c2grp {
  5271. + fsl,pins = <
  5272. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  5273. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  5274. + >;
  5275. + };
  5276. +
  5277. + pinctrl_i2c3: i2c3grp {
  5278. + fsl,pins = <
  5279. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  5280. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  5281. + >;
  5282. + };
  5283. +
  5284. + pinctrl_pwm4: pwm4grp {
  5285. + fsl,pins = <
  5286. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  5287. + >;
  5288. + };
  5289. +
  5290. + pinctrl_uart1: uart1grp {
  5291. + fsl,pins = <
  5292. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  5293. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  5294. + >;
  5295. + };
  5296. +
  5297. + pinctrl_uart2: uart2grp {
  5298. + fsl,pins = <
  5299. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  5300. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  5301. + >;
  5302. + };
  5303. +
  5304. + pinctrl_uart5: uart5grp {
  5305. + fsl,pins = <
  5306. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  5307. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  5308. + >;
  5309. + };
  5310. +
  5311. + pinctrl_usbotg: usbotggrp {
  5312. + fsl,pins = <
  5313. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  5314. + >;
  5315. + };
  5316. +
  5317. + pinctrl_usdhc3: usdhc3grp {
  5318. + fsl,pins = <
  5319. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  5320. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  5321. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  5322. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  5323. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  5324. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  5325. + >;
  5326. + };
  5327. + };
  5328. +};
  5329. +
  5330. +&ldb {
  5331. + status = "okay";
  5332. +
  5333. + lvds-channel@1 {
  5334. + fsl,data-mapping = "spwg";
  5335. + fsl,data-width = <18>;
  5336. + status = "okay";
  5337. +
  5338. + display-timings {
  5339. + native-mode = <&timing0>;
  5340. + timing0: hsd100pxn1 {
  5341. + clock-frequency = <65000000>;
  5342. + hactive = <1024>;
  5343. + vactive = <768>;
  5344. + hback-porch = <220>;
  5345. + hfront-porch = <40>;
  5346. + vback-porch = <21>;
  5347. + vfront-porch = <7>;
  5348. + hsync-len = <60>;
  5349. + vsync-len = <10>;
  5350. + };
  5351. + };
  5352. + };
  5353. +};
  5354. +
  5355. +&pcie {
  5356. + reset-gpio = <&gpio1 29 0>;
  5357. + status = "okay";
  5358. +
  5359. + eth1: sky2@8 { /* MAC/PHY on bus 8 */
  5360. + compatible = "marvell,sky2";
  5361. + };
  5362. +};
  5363. +
  5364. +&pwm4 {
  5365. + pinctrl-names = "default";
  5366. + pinctrl-0 = <&pinctrl_pwm4>;
  5367. + status = "okay";
  5368. +};
  5369. +
  5370. +&ssi1 {
  5371. + fsl,mode = "i2s-slave";
  5372. + status = "okay";
  5373. +};
  5374. +
  5375. +&ssi2 {
  5376. + fsl,mode = "i2s-slave";
  5377. + status = "okay";
  5378. +};
  5379. +
  5380. +&uart1 {
  5381. + pinctrl-names = "default";
  5382. + pinctrl-0 = <&pinctrl_uart1>;
  5383. + status = "okay";
  5384. +};
  5385. +
  5386. +&uart2 {
  5387. + pinctrl-names = "default";
  5388. + pinctrl-0 = <&pinctrl_uart2>;
  5389. + status = "okay";
  5390. +};
  5391. +
  5392. +&uart5 {
  5393. + pinctrl-names = "default";
  5394. + pinctrl-0 = <&pinctrl_uart5>;
  5395. + status = "okay";
  5396. +};
  5397. +
  5398. +&usbotg {
  5399. + vbus-supply = <&reg_usb_otg_vbus>;
  5400. + pinctrl-names = "default";
  5401. + pinctrl-0 = <&pinctrl_usbotg>;
  5402. + disable-over-current;
  5403. + status = "okay";
  5404. +};
  5405. +
  5406. +&usbh1 {
  5407. + vbus-supply = <&reg_usb_h1_vbus>;
  5408. + status = "okay";
  5409. +};
  5410. +
  5411. +&usdhc3 {
  5412. + pinctrl-names = "default";
  5413. + pinctrl-0 = <&pinctrl_usdhc3>;
  5414. + cd-gpios = <&gpio7 0 0>;
  5415. + vmmc-supply = <&reg_3p3v>;
  5416. + status = "okay";
  5417. +};
  5418. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi
  5419. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi 1970-01-01 01:00:00.000000000 +0100
  5420. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi 2014-08-20 19:31:39.900842271 +0200
  5421. @@ -0,0 +1,315 @@
  5422. +/*
  5423. + * Copyright (C) 2013,2014 Russell King
  5424. + */
  5425. +#include "imx6qdl-microsom.dtsi"
  5426. +#include "imx6qdl-microsom-ar8035.dtsi"
  5427. +
  5428. +/ {
  5429. + aliases {
  5430. + mxcfb0 = &mxcfb1;
  5431. + };
  5432. +
  5433. + ir_recv: ir-receiver {
  5434. + compatible = "gpio-ir-receiver";
  5435. + gpios = <&gpio1 2 1>;
  5436. + pinctrl-names = "default";
  5437. + pinctrl-0 = <&pinctrl_hummingboard_gpio1_2>;
  5438. + };
  5439. +
  5440. + regulators {
  5441. + compatible = "simple-bus";
  5442. +
  5443. + reg_3p3v: 3p3v {
  5444. + compatible = "regulator-fixed";
  5445. + regulator-name = "3P3V";
  5446. + regulator-min-microvolt = <3300000>;
  5447. + regulator-max-microvolt = <3300000>;
  5448. + regulator-always-on;
  5449. + };
  5450. +
  5451. + reg_usbh1_vbus: usb-h1-vbus {
  5452. + compatible = "regulator-fixed";
  5453. + enable-active-high;
  5454. + gpio = <&gpio1 0 0>;
  5455. + pinctrl-names = "default";
  5456. + pinctrl-0 = <&pinctrl_hummingboard_usbh1_vbus>;
  5457. + regulator-name = "usb_h1_vbus";
  5458. + regulator-min-microvolt = <5000000>;
  5459. + regulator-max-microvolt = <5000000>;
  5460. + };
  5461. +
  5462. + reg_usbotg_vbus: usb-otg-vbus {
  5463. + compatible = "regulator-fixed";
  5464. + enable-active-high;
  5465. + gpio = <&gpio3 22 0>;
  5466. + pinctrl-names = "default";
  5467. + pinctrl-0 = <&pinctrl_hummingboard_usbotg_vbus>;
  5468. + regulator-name = "usb_otg_vbus";
  5469. + regulator-min-microvolt = <5000000>;
  5470. + regulator-max-microvolt = <5000000>;
  5471. + };
  5472. + };
  5473. +
  5474. + sound-sgtl5000 {
  5475. + audio-codec = <&sgtl5000>;
  5476. + audio-routing =
  5477. + "MIC_IN", "Mic Jack",
  5478. + "Mic Jack", "Mic Bias",
  5479. + "Headphone Jack", "HP_OUT";
  5480. + compatible = "fsl,imx-audio-sgtl5000";
  5481. + model = "On-board Codec";
  5482. + mux-ext-port = <5>;
  5483. + mux-int-port = <1>;
  5484. + ssi-controller = <&ssi1>;
  5485. + };
  5486. +
  5487. + sound-spdif {
  5488. + compatible = "fsl,imx-audio-spdif";
  5489. + model = "imx-spdif";
  5490. + spdif-controller = <&spdif>;
  5491. + spdif-out;
  5492. + };
  5493. +
  5494. + sound-hdmi {
  5495. + compatible = "fsl,imx6q-audio-hdmi",
  5496. + "fsl,imx-audio-hdmi";
  5497. + model = "imx-audio-hdmi";
  5498. + hdmi-controller = <&hdmi_audio>;
  5499. + };
  5500. +
  5501. + mxcfb1: fb@0 {
  5502. + compatible = "fsl,mxc_sdc_fb";
  5503. + disp_dev = "hdmi";
  5504. + interface_pix_fmt = "RGB24";
  5505. + mode_str ="1920x1080M@60";
  5506. + default_bpp = <32>;
  5507. + int_clk = <0>;
  5508. + late_init = <0>;
  5509. + status = "okay";
  5510. + };
  5511. +};
  5512. +
  5513. +&hdmi_core {
  5514. + ipu_id = <0>;
  5515. + disp_id = <0>;
  5516. + status = "okay";
  5517. +};
  5518. +
  5519. +&hdmi_video {
  5520. + fsl,phy_reg_vlev = <0x0294>;
  5521. + fsl,phy_reg_cksymtx = <0x800d>;
  5522. + status = "okay";
  5523. +};
  5524. +
  5525. +&hdmi_audio {
  5526. + status = "okay";
  5527. +};
  5528. +
  5529. +&hdmi_cec {
  5530. + pinctrl-names = "default";
  5531. + pinctrl-0 = <&pinctrl_hummingboard_hdmi>;
  5532. + status = "okay";
  5533. +};
  5534. +
  5535. +&i2c2 {
  5536. + clock-frequency = <100000>;
  5537. + pinctrl-names = "default";
  5538. + pinctrl-0 = <&pinctrl_hummingboard_i2c2>;
  5539. + status = "okay";
  5540. +
  5541. + ddc: imx6_hdmi_i2c@50 {
  5542. + compatible = "fsl,imx6-hdmi-i2c";
  5543. + reg = <0x50>;
  5544. + };
  5545. +};
  5546. +
  5547. +&audmux {
  5548. + status = "okay";
  5549. +};
  5550. +
  5551. +&can1 {
  5552. + pinctrl-names = "default";
  5553. + status = "okay";
  5554. +};
  5555. +
  5556. +&i2c1 {
  5557. + pinctrl-names = "default";
  5558. + pinctrl-0 = <&pinctrl_hummingboard_i2c1>;
  5559. + status = "okay";
  5560. +
  5561. + /* Pro model */
  5562. + rtc: pcf8523@68 {
  5563. + compatible = "nxp,pcf8523";
  5564. + reg = <0x68>;
  5565. + };
  5566. +
  5567. + /* Pro model */
  5568. + sgtl5000: sgtl5000@0a {
  5569. + clocks = <&clks 201>;
  5570. + compatible = "fsl,sgtl5000";
  5571. + pinctrl-names = "default";
  5572. + pinctrl-0 = <&pinctrl_hummingboard_sgtl5000>;
  5573. + reg = <0x0a>;
  5574. + VDDA-supply = <&reg_3p3v>;
  5575. + VDDIO-supply = <&reg_3p3v>;
  5576. + };
  5577. +};
  5578. +
  5579. +&iomuxc {
  5580. + pinctrl-names = "default";
  5581. + pinctrl-0 = <&pinctrl_hog>;
  5582. + hummingboard {
  5583. + pinctrl_hog: hoggrp {
  5584. + fsl,pins = <
  5585. + /*
  5586. + * 26 pin header GPIO description. The pins
  5587. + * numbering as following -
  5588. + * GPIO number | GPIO (bank,num) | PIN number
  5589. + * ------------+-----------------+------------
  5590. + * gpio1 | (1,1) | IO7
  5591. + * gpio73 | (3,9) | IO11
  5592. + * gpio72 | (3,8) | IO12
  5593. + * gpio71 | (3,7) | IO13
  5594. + * gpio70 | (3,6) | IO15
  5595. + * gpio194 | (7,2) | IO16
  5596. + * gpio195 | (7,3) | IO18
  5597. + * gpio67 | (3,3) | IO22
  5598. + */
  5599. + MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x8001b0b1
  5600. + MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x8001b0b1
  5601. + MX6QDL_PAD_EIM_DA8__GPIO3_IO08 0x8001b0b1
  5602. + MX6QDL_PAD_EIM_DA7__GPIO3_IO07 0x8001b0b1
  5603. + MX6QDL_PAD_EIM_DA6__GPIO3_IO06 0x8001b0b1
  5604. + MX6QDL_PAD_SD3_CMD__GPIO7_IO02 0x8001b0b1
  5605. + MX6QDL_PAD_SD3_CLK__GPIO7_IO03 0x8001b0b1
  5606. + MX6QDL_PAD_EIM_DA3__GPIO3_IO03 0x8001b0b1
  5607. + >;
  5608. + };
  5609. +
  5610. + pinctrl_hummingboard_gpio1_2: hummingboard-gpio1_2 {
  5611. + fsl,pins = <
  5612. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000
  5613. + >;
  5614. + };
  5615. +
  5616. + pinctrl_hummingboard_hdmi: hummingboard-hdmi {
  5617. + fsl,pins = <
  5618. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  5619. + >;
  5620. + };
  5621. +
  5622. + pinctrl_hummingboard_i2c1: hummingboard-i2c1 {
  5623. + fsl,pins = <
  5624. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  5625. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  5626. + >;
  5627. + };
  5628. +
  5629. + pinctrl_hummingboard_i2c2: hummingboard-i2c2 {
  5630. + fsl,pins = <
  5631. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  5632. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  5633. + >;
  5634. + };
  5635. +
  5636. + pinctrl_hummingboard_sgtl5000: hummingboard-sgtl5000 {
  5637. + fsl,pins = <
  5638. + MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0 /*brk*/
  5639. + MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x130b0 /*ok*/
  5640. + MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x110b0 /*brk*/
  5641. + MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x130b0 /*ok*/
  5642. + MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x130b0
  5643. + >;
  5644. + };
  5645. +
  5646. + pinctrl_hummingboard_spdif: hummingboard-spdif {
  5647. + fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
  5648. + };
  5649. +
  5650. + pinctrl_hummingboard_usbh1_vbus: hummingboard-usbh1-vbus {
  5651. + fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0>;
  5652. + };
  5653. +
  5654. + pinctrl_hummingboard_usbotg_id: hummingboard-usbotg-id {
  5655. + /*
  5656. + * Similar to pinctrl_usbotg_2, but we want it
  5657. + * pulled down for a fixed host connection.
  5658. + */
  5659. + fsl,pins = <MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x13059>;
  5660. + };
  5661. +
  5662. + pinctrl_hummingboard_usbotg_vbus: hummingboard-usbotg-vbus {
  5663. + fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0>;
  5664. + };
  5665. +
  5666. + pinctrl_hummingboard_usdhc2_aux: hummingboard-usdhc2-aux {
  5667. + fsl,pins = <
  5668. + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
  5669. + >;
  5670. + };
  5671. +
  5672. + pinctrl_hummingboard_usdhc2: hummingboard-usdhc2 {
  5673. + fsl,pins = <
  5674. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  5675. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  5676. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  5677. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  5678. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  5679. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
  5680. + >;
  5681. + };
  5682. + };
  5683. +};
  5684. +
  5685. +&spdif {
  5686. + pinctrl-names = "default";
  5687. + pinctrl-0 = <&pinctrl_hummingboard_spdif>;
  5688. + clocks = <&clks 197>, <&clks 0>,
  5689. + <&clks 197>, <&clks 0>,
  5690. + <&clks 0>, <&clks 0>,
  5691. + <&clks 0>, <&clks 0>,
  5692. + <&clks 0>;
  5693. + clock-names = "core", "rxtx0",
  5694. + "rxtx1", "rxtx2",
  5695. + "rxtx3", "rxtx4",
  5696. + "rxtx5", "rxtx6",
  5697. + "rxtx7";
  5698. + status = "okay";
  5699. +};
  5700. +
  5701. +&ssi1 {
  5702. + fsl,mode = "i2s-slave";
  5703. + status = "okay";
  5704. +};
  5705. +
  5706. +&usbh1 {
  5707. + disable-over-current;
  5708. + vbus-supply = <&reg_usbh1_vbus>;
  5709. + status = "okay";
  5710. +};
  5711. +
  5712. +&usbotg {
  5713. + disable-over-current;
  5714. + pinctrl-names = "default";
  5715. + pinctrl-0 = <&pinctrl_hummingboard_usbotg_id>;
  5716. + vbus-supply = <&reg_usbotg_vbus>;
  5717. + status = "okay";
  5718. +};
  5719. +
  5720. +&usdhc2 {
  5721. + pinctrl-names = "default";
  5722. + pinctrl-0 = <
  5723. + &pinctrl_hummingboard_usdhc2_aux
  5724. + &pinctrl_hummingboard_usdhc2
  5725. + >;
  5726. + vmmc-supply = <&reg_3p3v>;
  5727. + cd-gpios = <&gpio1 4 0>;
  5728. + status = "okay";
  5729. +};
  5730. +
  5731. +&gpc {
  5732. + fsl,cpu_pupscr_sw2iso = <0xf>;
  5733. + fsl,cpu_pupscr_sw = <0xf>;
  5734. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  5735. + fsl,cpu_pdnscr_iso = <0x1>;
  5736. +};
  5737. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi
  5738. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi 2014-07-31 23:51:43.000000000 +0200
  5739. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi 2014-08-20 19:31:39.900842271 +0200
  5740. @@ -17,7 +17,7 @@
  5741. enet {
  5742. pinctrl_microsom_enet_ar8035: microsom-enet-ar8035 {
  5743. fsl,pins = <
  5744. - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  5745. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b8b0
  5746. MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  5747. /* AR8035 reset */
  5748. MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x130b0
  5749. @@ -26,25 +26,25 @@
  5750. /* GPIO16 -> AR8035 25MHz */
  5751. MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0xc0000000
  5752. MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x80000000
  5753. - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  5754. - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  5755. - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  5756. - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  5757. - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  5758. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b030
  5759. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b030
  5760. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b030
  5761. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b030
  5762. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b030
  5763. /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */
  5764. MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x0a0b1
  5765. /* AR8035 pin strapping: IO voltage: pull up */
  5766. - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  5767. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030
  5768. /* AR8035 pin strapping: PHYADDR#0: pull down */
  5769. - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x130b0
  5770. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x13030
  5771. /* AR8035 pin strapping: PHYADDR#1: pull down */
  5772. - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x130b0
  5773. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x13030
  5774. /* AR8035 pin strapping: MODE#1: pull up */
  5775. - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  5776. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030
  5777. /* AR8035 pin strapping: MODE#3: pull up */
  5778. - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  5779. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030
  5780. /* AR8035 pin strapping: MODE#0: pull down */
  5781. - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x130b0
  5782. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x13030
  5783. /*
  5784. * As the RMII pins are also connected to RGMII
  5785. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-microsom.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-microsom.dtsi
  5786. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-microsom.dtsi 2014-07-31 23:51:43.000000000 +0200
  5787. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-microsom.dtsi 2014-08-20 19:31:39.900842271 +0200
  5788. @@ -1,9 +1,69 @@
  5789. /*
  5790. * Copyright (C) 2013,2014 Russell King
  5791. */
  5792. +#include <dt-bindings/gpio/gpio.h>
  5793. +/ {
  5794. + regulators {
  5795. + compatible = "simple-bus";
  5796. +
  5797. + reg_brcm_osc: brcm-osc-reg {
  5798. + compatible = "regulator-fixed";
  5799. + enable-active-high;
  5800. + gpio = <&gpio5 5 0>;
  5801. + pinctrl-names = "default";
  5802. + pinctrl-0 = <&pinctrl_microsom_brcm_osc_reg>;
  5803. + regulator-name = "brcm_osc_reg";
  5804. + regulator-min-microvolt = <3300000>;
  5805. + regulator-max-microvolt = <3300000>;
  5806. + regulator-always-on;
  5807. + regulator-boot-on;
  5808. + };
  5809. +
  5810. + reg_brcm: brcm-reg {
  5811. + compatible = "regulator-fixed";
  5812. + enable-active-high;
  5813. + gpio = <&gpio3 19 0>;
  5814. + pinctrl-names = "default";
  5815. + pinctrl-0 = <&pinctrl_microsom_brcm_reg>;
  5816. + regulator-name = "brcm_reg";
  5817. + regulator-min-microvolt = <3300000>;
  5818. + regulator-max-microvolt = <3300000>;
  5819. + startup-delay-us = <200000>;
  5820. + };
  5821. + };
  5822. +};
  5823. &iomuxc {
  5824. microsom {
  5825. + pinctrl_microsom_brcm_bt: microsom-brcm-bt {
  5826. + fsl,pins = <
  5827. + MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00 0x40013070
  5828. + MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01 0x40013070
  5829. + MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04 0x40013070
  5830. + >;
  5831. + };
  5832. +
  5833. + pinctrl_microsom_brcm_osc_reg: microsom-brcm-osc-reg {
  5834. + fsl,pins = <
  5835. + MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05 0x40013070
  5836. + >;
  5837. + };
  5838. +
  5839. + pinctrl_microsom_brcm_reg: microsom-brcm-reg {
  5840. + fsl,pins = <
  5841. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x40013070
  5842. + >;
  5843. + };
  5844. +
  5845. + pinctrl_microsom_brcm_wifi: microsom-brcm-wifi {
  5846. + fsl,pins = <
  5847. + MX6QDL_PAD_GPIO_8__XTALOSC_REF_CLK_32K 0x1b0b0
  5848. + MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x40013070
  5849. + MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x40013070
  5850. + MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x40013070
  5851. + >;
  5852. + };
  5853. +
  5854. pinctrl_microsom_uart1: microsom-uart1 {
  5855. fsl,pins = <
  5856. MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  5857. @@ -11,12 +71,24 @@
  5858. >;
  5859. };
  5860. - pinctrl_microsom_usbotg: microsom-usbotg {
  5861. - /*
  5862. - * Similar to pinctrl_usbotg_2, but we want it
  5863. - * pulled down for a fixed host connection.
  5864. - */
  5865. - fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>;
  5866. + pinctrl_microsom_uart4_1: microsom-uart4 {
  5867. + fsl,pins = <
  5868. + MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1
  5869. + MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1
  5870. + MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x1b0b1
  5871. + MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x1b0b1
  5872. + >;
  5873. + };
  5874. +
  5875. + pinctrl_microsom_usdhc1: microsom-usdhc1 {
  5876. + fsl,pins = <
  5877. + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  5878. + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  5879. + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  5880. + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  5881. + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  5882. + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  5883. + >;
  5884. };
  5885. };
  5886. };
  5887. @@ -27,7 +99,23 @@
  5888. status = "okay";
  5889. };
  5890. -&usbotg {
  5891. +/* UART4 - Connected to optional BRCM Wifi/BT/FM */
  5892. +&uart4 {
  5893. + pinctrl-names = "default";
  5894. + pinctrl-0 = <&pinctrl_microsom_brcm_bt &pinctrl_microsom_uart4_1>;
  5895. + fsl,uart-has-rtscts;
  5896. + status = "okay";
  5897. +};
  5898. +
  5899. +/* USDHC1 - Connected to optional BRCM Wifi/BT/FM */
  5900. +&usdhc1 {
  5901. + card-external-vcc-supply = <&reg_brcm>;
  5902. + card-reset-gpios = <&gpio5 26 GPIO_ACTIVE_LOW>, <&gpio6 0 GPIO_ACTIVE_LOW>;
  5903. + keep-power-in-suspend;
  5904. + non-removable;
  5905. pinctrl-names = "default";
  5906. - pinctrl-0 = <&pinctrl_microsom_usbotg>;
  5907. + pinctrl-0 = <&pinctrl_microsom_brcm_wifi &pinctrl_microsom_usdhc1>;
  5908. + vmmc-supply = <&reg_brcm>;
  5909. + status = "okay";
  5910. };
  5911. +
  5912. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
  5913. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi 1970-01-01 01:00:00.000000000 +0100
  5914. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi 2014-08-20 19:31:39.900842271 +0200
  5915. @@ -0,0 +1,426 @@
  5916. +/*
  5917. + * Copyright 2013 Boundary Devices, Inc.
  5918. + * Copyright 2011 Freescale Semiconductor, Inc.
  5919. + * Copyright 2011 Linaro Ltd.
  5920. + *
  5921. + * The code contained herein is licensed under the GNU General Public
  5922. + * License. You may obtain a copy of the GNU General Public License
  5923. + * Version 2 or later at the following locations:
  5924. + *
  5925. + * http://www.opensource.org/licenses/gpl-license.html
  5926. + * http://www.gnu.org/copyleft/gpl.html
  5927. + */
  5928. +#include <dt-bindings/gpio/gpio.h>
  5929. +#include <dt-bindings/input/input.h>
  5930. +
  5931. +/ {
  5932. + chosen {
  5933. + stdout-path = &uart2;
  5934. + };
  5935. +
  5936. + memory {
  5937. + reg = <0x10000000 0x40000000>;
  5938. + };
  5939. +
  5940. + regulators {
  5941. + compatible = "simple-bus";
  5942. + #address-cells = <1>;
  5943. + #size-cells = <0>;
  5944. +
  5945. + reg_2p5v: regulator@0 {
  5946. + compatible = "regulator-fixed";
  5947. + reg = <0>;
  5948. + regulator-name = "2P5V";
  5949. + regulator-min-microvolt = <2500000>;
  5950. + regulator-max-microvolt = <2500000>;
  5951. + regulator-always-on;
  5952. + };
  5953. +
  5954. + reg_3p3v: regulator@1 {
  5955. + compatible = "regulator-fixed";
  5956. + reg = <1>;
  5957. + regulator-name = "3P3V";
  5958. + regulator-min-microvolt = <3300000>;
  5959. + regulator-max-microvolt = <3300000>;
  5960. + regulator-always-on;
  5961. + };
  5962. +
  5963. + reg_usb_otg_vbus: regulator@2 {
  5964. + compatible = "regulator-fixed";
  5965. + reg = <2>;
  5966. + regulator-name = "usb_otg_vbus";
  5967. + regulator-min-microvolt = <5000000>;
  5968. + regulator-max-microvolt = <5000000>;
  5969. + gpio = <&gpio3 22 0>;
  5970. + enable-active-high;
  5971. + };
  5972. + };
  5973. +
  5974. + gpio-keys {
  5975. + compatible = "gpio-keys";
  5976. + pinctrl-names = "default";
  5977. + pinctrl-0 = <&pinctrl_gpio_keys>;
  5978. +
  5979. + power {
  5980. + label = "Power Button";
  5981. + gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
  5982. + linux,code = <KEY_POWER>;
  5983. + gpio-key,wakeup;
  5984. + };
  5985. +
  5986. + menu {
  5987. + label = "Menu";
  5988. + gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
  5989. + linux,code = <KEY_MENU>;
  5990. + };
  5991. +
  5992. + home {
  5993. + label = "Home";
  5994. + gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
  5995. + linux,code = <KEY_HOME>;
  5996. + };
  5997. +
  5998. + back {
  5999. + label = "Back";
  6000. + gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
  6001. + linux,code = <KEY_BACK>;
  6002. + };
  6003. +
  6004. + volume-up {
  6005. + label = "Volume Up";
  6006. + gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
  6007. + linux,code = <KEY_VOLUMEUP>;
  6008. + };
  6009. +
  6010. + volume-down {
  6011. + label = "Volume Down";
  6012. + gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
  6013. + linux,code = <KEY_VOLUMEDOWN>;
  6014. + };
  6015. + };
  6016. +
  6017. + sound {
  6018. + compatible = "fsl,imx6q-nitrogen6x-sgtl5000",
  6019. + "fsl,imx-audio-sgtl5000";
  6020. + model = "imx6q-nitrogen6x-sgtl5000";
  6021. + ssi-controller = <&ssi1>;
  6022. + audio-codec = <&codec>;
  6023. + audio-routing =
  6024. + "MIC_IN", "Mic Jack",
  6025. + "Mic Jack", "Mic Bias",
  6026. + "Headphone Jack", "HP_OUT";
  6027. + mux-int-port = <1>;
  6028. + mux-ext-port = <3>;
  6029. + };
  6030. +
  6031. + backlight_lcd {
  6032. + compatible = "pwm-backlight";
  6033. + pwms = <&pwm1 0 5000000>;
  6034. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6035. + default-brightness-level = <7>;
  6036. + power-supply = <&reg_3p3v>;
  6037. + status = "okay";
  6038. + };
  6039. +
  6040. + backlight_lvds {
  6041. + compatible = "pwm-backlight";
  6042. + pwms = <&pwm4 0 5000000>;
  6043. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6044. + default-brightness-level = <7>;
  6045. + power-supply = <&reg_3p3v>;
  6046. + status = "okay";
  6047. + };
  6048. +};
  6049. +
  6050. +&audmux {
  6051. + pinctrl-names = "default";
  6052. + pinctrl-0 = <&pinctrl_audmux>;
  6053. + status = "okay";
  6054. +};
  6055. +
  6056. +&ecspi1 {
  6057. + fsl,spi-num-chipselects = <1>;
  6058. + cs-gpios = <&gpio3 19 0>;
  6059. + pinctrl-names = "default";
  6060. + pinctrl-0 = <&pinctrl_ecspi1>;
  6061. + status = "okay";
  6062. +
  6063. + flash: m25p80@0 {
  6064. + compatible = "sst,sst25vf016b";
  6065. + spi-max-frequency = <20000000>;
  6066. + reg = <0>;
  6067. + };
  6068. +};
  6069. +
  6070. +&fec {
  6071. + pinctrl-names = "default";
  6072. + pinctrl-0 = <&pinctrl_enet>;
  6073. + phy-mode = "rgmii";
  6074. + phy-reset-gpios = <&gpio1 27 0>;
  6075. + txen-skew-ps = <0>;
  6076. + txc-skew-ps = <3000>;
  6077. + rxdv-skew-ps = <0>;
  6078. + rxc-skew-ps = <3000>;
  6079. + rxd0-skew-ps = <0>;
  6080. + rxd1-skew-ps = <0>;
  6081. + rxd2-skew-ps = <0>;
  6082. + rxd3-skew-ps = <0>;
  6083. + txd0-skew-ps = <0>;
  6084. + txd1-skew-ps = <0>;
  6085. + txd2-skew-ps = <0>;
  6086. + txd3-skew-ps = <0>;
  6087. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  6088. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  6089. + status = "okay";
  6090. +};
  6091. +
  6092. +&i2c1 {
  6093. + clock-frequency = <100000>;
  6094. + pinctrl-names = "default";
  6095. + pinctrl-0 = <&pinctrl_i2c1>;
  6096. + status = "okay";
  6097. +
  6098. + codec: sgtl5000@0a {
  6099. + compatible = "fsl,sgtl5000";
  6100. + reg = <0x0a>;
  6101. + clocks = <&clks 201>;
  6102. + VDDA-supply = <&reg_2p5v>;
  6103. + VDDIO-supply = <&reg_3p3v>;
  6104. + };
  6105. +};
  6106. +
  6107. +&iomuxc {
  6108. + pinctrl-names = "default";
  6109. + pinctrl-0 = <&pinctrl_hog>;
  6110. +
  6111. + imx6q-nitrogen6x {
  6112. + pinctrl_hog: hoggrp {
  6113. + fsl,pins = <
  6114. + /* SGTL5000 sys_mclk */
  6115. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x030b0
  6116. + >;
  6117. + };
  6118. +
  6119. + pinctrl_audmux: audmuxgrp {
  6120. + fsl,pins = <
  6121. + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
  6122. + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
  6123. + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
  6124. + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
  6125. + >;
  6126. + };
  6127. +
  6128. + pinctrl_ecspi1: ecspi1grp {
  6129. + fsl,pins = <
  6130. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  6131. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  6132. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  6133. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x000b1 /* CS */
  6134. + >;
  6135. + };
  6136. +
  6137. + pinctrl_enet: enetgrp {
  6138. + fsl,pins = <
  6139. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0
  6140. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0
  6141. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0
  6142. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0
  6143. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0
  6144. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0
  6145. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0
  6146. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0
  6147. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0
  6148. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  6149. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  6150. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  6151. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  6152. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  6153. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  6154. + /* Phy reset */
  6155. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x000b0
  6156. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  6157. + >;
  6158. + };
  6159. +
  6160. + pinctrl_gpio_keys: gpio_keysgrp {
  6161. + fsl,pins = <
  6162. + /* Power Button */
  6163. + MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
  6164. + /* Menu Button */
  6165. + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
  6166. + /* Home Button */
  6167. + MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
  6168. + /* Back Button */
  6169. + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
  6170. + /* Volume Up Button */
  6171. + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0
  6172. + /* Volume Down Button */
  6173. + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
  6174. + >;
  6175. + };
  6176. +
  6177. + pinctrl_i2c1: i2c1grp {
  6178. + fsl,pins = <
  6179. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  6180. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  6181. + >;
  6182. + };
  6183. +
  6184. + pinctrl_pwm1: pwm1grp {
  6185. + fsl,pins = <
  6186. + MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  6187. + >;
  6188. + };
  6189. +
  6190. + pinctrl_pwm3: pwm3grp {
  6191. + fsl,pins = <
  6192. + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
  6193. + >;
  6194. + };
  6195. +
  6196. + pinctrl_pwm4: pwm4grp {
  6197. + fsl,pins = <
  6198. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  6199. + >;
  6200. + };
  6201. +
  6202. + pinctrl_uart1: uart1grp {
  6203. + fsl,pins = <
  6204. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  6205. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  6206. + >;
  6207. + };
  6208. +
  6209. + pinctrl_uart2: uart2grp {
  6210. + fsl,pins = <
  6211. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  6212. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  6213. + >;
  6214. + };
  6215. +
  6216. + pinctrl_usbotg: usbotggrp {
  6217. + fsl,pins = <
  6218. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  6219. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  6220. + /* power enable, high active */
  6221. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x000b0
  6222. + >;
  6223. + };
  6224. +
  6225. + pinctrl_usdhc3: usdhc3grp {
  6226. + fsl,pins = <
  6227. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  6228. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  6229. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  6230. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  6231. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  6232. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  6233. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
  6234. + >;
  6235. + };
  6236. +
  6237. + pinctrl_usdhc4: usdhc4grp {
  6238. + fsl,pins = <
  6239. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  6240. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  6241. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  6242. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  6243. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  6244. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  6245. + MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /* CD */
  6246. + >;
  6247. + };
  6248. + };
  6249. +};
  6250. +
  6251. +&ldb {
  6252. + status = "okay";
  6253. +
  6254. + lvds-channel@0 {
  6255. + fsl,data-mapping = "spwg";
  6256. + fsl,data-width = <18>;
  6257. + status = "okay";
  6258. +
  6259. + display-timings {
  6260. + native-mode = <&timing0>;
  6261. + timing0: hsd100pxn1 {
  6262. + clock-frequency = <65000000>;
  6263. + hactive = <1024>;
  6264. + vactive = <768>;
  6265. + hback-porch = <220>;
  6266. + hfront-porch = <40>;
  6267. + vback-porch = <21>;
  6268. + vfront-porch = <7>;
  6269. + hsync-len = <60>;
  6270. + vsync-len = <10>;
  6271. + };
  6272. + };
  6273. + };
  6274. +};
  6275. +
  6276. +&pcie {
  6277. + status = "okay";
  6278. +};
  6279. +
  6280. +&pwm1 {
  6281. + pinctrl-names = "default";
  6282. + pinctrl-0 = <&pinctrl_pwm1>;
  6283. + status = "okay";
  6284. +};
  6285. +
  6286. +&pwm3 {
  6287. + pinctrl-names = "default";
  6288. + pinctrl-0 = <&pinctrl_pwm3>;
  6289. + status = "okay";
  6290. +};
  6291. +
  6292. +&pwm4 {
  6293. + pinctrl-names = "default";
  6294. + pinctrl-0 = <&pinctrl_pwm4>;
  6295. + status = "okay";
  6296. +};
  6297. +
  6298. +&ssi1 {
  6299. + fsl,mode = "i2s-slave";
  6300. + status = "okay";
  6301. +};
  6302. +
  6303. +&uart1 {
  6304. + pinctrl-names = "default";
  6305. + pinctrl-0 = <&pinctrl_uart1>;
  6306. + status = "okay";
  6307. +};
  6308. +
  6309. +&uart2 {
  6310. + pinctrl-names = "default";
  6311. + pinctrl-0 = <&pinctrl_uart2>;
  6312. + status = "okay";
  6313. +};
  6314. +
  6315. +&usbh1 {
  6316. + status = "okay";
  6317. +};
  6318. +
  6319. +&usbotg {
  6320. + vbus-supply = <&reg_usb_otg_vbus>;
  6321. + pinctrl-names = "default";
  6322. + pinctrl-0 = <&pinctrl_usbotg>;
  6323. + disable-over-current;
  6324. + status = "okay";
  6325. +};
  6326. +
  6327. +&usdhc3 {
  6328. + pinctrl-names = "default";
  6329. + pinctrl-0 = <&pinctrl_usdhc3>;
  6330. + cd-gpios = <&gpio7 0 0>;
  6331. + vmmc-supply = <&reg_3p3v>;
  6332. + status = "okay";
  6333. +};
  6334. +
  6335. +&usdhc4 {
  6336. + pinctrl-names = "default";
  6337. + pinctrl-0 = <&pinctrl_usdhc4>;
  6338. + cd-gpios = <&gpio2 6 0>;
  6339. + vmmc-supply = <&reg_3p3v>;
  6340. + status = "okay";
  6341. +};
  6342. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
  6343. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi 1970-01-01 01:00:00.000000000 +0100
  6344. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi 2014-08-20 19:31:39.900842271 +0200
  6345. @@ -0,0 +1,98 @@
  6346. +/*
  6347. + * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
  6348. + *
  6349. + * The code contained herein is licensed under the GNU General Public
  6350. + * License. You may obtain a copy of the GNU General Public License
  6351. + * Version 2 or later at the following locations:
  6352. + *
  6353. + * http://www.opensource.org/licenses/gpl-license.html
  6354. + * http://www.gnu.org/copyleft/gpl.html
  6355. + */
  6356. +
  6357. +/ {
  6358. + chosen {
  6359. + linux,stdout-path = &uart4;
  6360. + };
  6361. +};
  6362. +
  6363. +&fec {
  6364. + status = "okay";
  6365. +};
  6366. +
  6367. +&gpmi {
  6368. + status = "okay";
  6369. +};
  6370. +
  6371. +&i2c2 {
  6372. + pinctrl-names = "default";
  6373. + pinctrl-0 = <&pinctrl_i2c2>;
  6374. + clock-frequency = <100000>;
  6375. + status = "okay";
  6376. +
  6377. + tlv320@18 {
  6378. + compatible = "ti,tlv320aic3x";
  6379. + reg = <0x18>;
  6380. + };
  6381. +
  6382. + stmpe@41 {
  6383. + compatible = "st,stmpe811";
  6384. + reg = <0x41>;
  6385. + };
  6386. +
  6387. + rtc@51 {
  6388. + compatible = "nxp,rtc8564";
  6389. + reg = <0x51>;
  6390. + };
  6391. +
  6392. + adc@64 {
  6393. + compatible = "maxim,max1037";
  6394. + reg = <0x64>;
  6395. + };
  6396. +};
  6397. +
  6398. +&i2c3 {
  6399. + pinctrl-names = "default";
  6400. + pinctrl-0 = <&pinctrl_i2c3>;
  6401. + clock-frequency = <100000>;
  6402. + status = "okay";
  6403. +};
  6404. +
  6405. +&uart3 {
  6406. + status = "okay";
  6407. +};
  6408. +
  6409. +&uart4 {
  6410. + status = "okay";
  6411. +};
  6412. +
  6413. +&usbh1 {
  6414. + status = "okay";
  6415. +};
  6416. +
  6417. +&usbotg {
  6418. + status = "okay";
  6419. +};
  6420. +
  6421. +&usdhc2 {
  6422. + status = "okay";
  6423. +};
  6424. +
  6425. +&usdhc3 {
  6426. + status = "okay";
  6427. +};
  6428. +
  6429. +&iomuxc {
  6430. + pinctrl_i2c2: i2c2grp {
  6431. + fsl,pins = <
  6432. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  6433. + MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
  6434. + >;
  6435. + };
  6436. +
  6437. + pinctrl_i2c3: i2c3grp {
  6438. + fsl,pins = <
  6439. + MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
  6440. + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
  6441. + >;
  6442. + };
  6443. +};
  6444. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
  6445. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi 1970-01-01 01:00:00.000000000 +0100
  6446. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi 2014-08-20 19:31:39.900842271 +0200
  6447. @@ -0,0 +1,356 @@
  6448. +/*
  6449. + * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
  6450. + *
  6451. + * The code contained herein is licensed under the GNU General Public
  6452. + * License. You may obtain a copy of the GNU General Public License
  6453. + * Version 2 or later at the following locations:
  6454. + *
  6455. + * http://www.opensource.org/licenses/gpl-license.html
  6456. + * http://www.gnu.org/copyleft/gpl.html
  6457. + */
  6458. +
  6459. +#include <dt-bindings/gpio/gpio.h>
  6460. +
  6461. +/ {
  6462. + model = "Phytec phyFLEX-i.MX6 Ouad";
  6463. + compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
  6464. +
  6465. + memory {
  6466. + reg = <0x10000000 0x80000000>;
  6467. + };
  6468. +
  6469. + regulators {
  6470. + compatible = "simple-bus";
  6471. + #address-cells = <1>;
  6472. + #size-cells = <0>;
  6473. +
  6474. + reg_usb_otg_vbus: regulator@0 {
  6475. + compatible = "regulator-fixed";
  6476. + reg = <0>;
  6477. + regulator-name = "usb_otg_vbus";
  6478. + regulator-min-microvolt = <5000000>;
  6479. + regulator-max-microvolt = <5000000>;
  6480. + gpio = <&gpio4 15 0>;
  6481. + };
  6482. +
  6483. + reg_usb_h1_vbus: regulator@1 {
  6484. + compatible = "regulator-fixed";
  6485. + reg = <1>;
  6486. + regulator-name = "usb_h1_vbus";
  6487. + regulator-min-microvolt = <5000000>;
  6488. + regulator-max-microvolt = <5000000>;
  6489. + gpio = <&gpio1 0 0>;
  6490. + };
  6491. + };
  6492. +
  6493. + gpio_leds: leds {
  6494. + compatible = "gpio-leds";
  6495. +
  6496. + green {
  6497. + label = "phyflex:green";
  6498. + gpios = <&gpio1 30 0>;
  6499. + };
  6500. +
  6501. + red {
  6502. + label = "phyflex:red";
  6503. + gpios = <&gpio2 31 0>;
  6504. + };
  6505. + };
  6506. +};
  6507. +
  6508. +&ecspi3 {
  6509. + pinctrl-names = "default";
  6510. + pinctrl-0 = <&pinctrl_ecspi3>;
  6511. + status = "okay";
  6512. + fsl,spi-num-chipselects = <1>;
  6513. + cs-gpios = <&gpio4 24 0>;
  6514. +
  6515. + flash@0 {
  6516. + compatible = "m25p80";
  6517. + spi-max-frequency = <20000000>;
  6518. + reg = <0>;
  6519. + };
  6520. +};
  6521. +
  6522. +&i2c1 {
  6523. + pinctrl-names = "default";
  6524. + pinctrl-0 = <&pinctrl_i2c1>;
  6525. + status = "okay";
  6526. +
  6527. + eeprom@50 {
  6528. + compatible = "atmel,24c32";
  6529. + reg = <0x50>;
  6530. + };
  6531. +
  6532. + pmic@58 {
  6533. + compatible = "dialog,da9063";
  6534. + reg = <0x58>;
  6535. + interrupt-parent = <&gpio4>;
  6536. + interrupts = <17 0x8>; /* active-low GPIO4_17 */
  6537. +
  6538. + regulators {
  6539. + vddcore_reg: bcore1 {
  6540. + regulator-min-microvolt = <730000>;
  6541. + regulator-max-microvolt = <1380000>;
  6542. + regulator-always-on;
  6543. + };
  6544. +
  6545. + vddsoc_reg: bcore2 {
  6546. + regulator-min-microvolt = <730000>;
  6547. + regulator-max-microvolt = <1380000>;
  6548. + regulator-always-on;
  6549. + };
  6550. +
  6551. + vdd_ddr3_reg: bpro {
  6552. + regulator-min-microvolt = <1500000>;
  6553. + regulator-max-microvolt = <1500000>;
  6554. + regulator-always-on;
  6555. + };
  6556. +
  6557. + vdd_3v3_reg: bperi {
  6558. + regulator-min-microvolt = <3300000>;
  6559. + regulator-max-microvolt = <3300000>;
  6560. + regulator-always-on;
  6561. + };
  6562. +
  6563. + vdd_buckmem_reg: bmem {
  6564. + regulator-min-microvolt = <3300000>;
  6565. + regulator-max-microvolt = <3300000>;
  6566. + regulator-always-on;
  6567. + };
  6568. +
  6569. + vdd_eth_reg: bio {
  6570. + regulator-min-microvolt = <1200000>;
  6571. + regulator-max-microvolt = <1200000>;
  6572. + regulator-always-on;
  6573. + };
  6574. +
  6575. + vdd_eth_io_reg: ldo4 {
  6576. + regulator-min-microvolt = <2500000>;
  6577. + regulator-max-microvolt = <2500000>;
  6578. + regulator-always-on;
  6579. + };
  6580. +
  6581. + vdd_mx6_snvs_reg: ldo5 {
  6582. + regulator-min-microvolt = <3000000>;
  6583. + regulator-max-microvolt = <3000000>;
  6584. + regulator-always-on;
  6585. + };
  6586. +
  6587. + vdd_3v3_pmic_io_reg: ldo6 {
  6588. + regulator-min-microvolt = <3300000>;
  6589. + regulator-max-microvolt = <3300000>;
  6590. + regulator-always-on;
  6591. + };
  6592. +
  6593. + vdd_sd0_reg: ldo9 {
  6594. + regulator-min-microvolt = <3300000>;
  6595. + regulator-max-microvolt = <3300000>;
  6596. + };
  6597. +
  6598. + vdd_sd1_reg: ldo10 {
  6599. + regulator-min-microvolt = <3300000>;
  6600. + regulator-max-microvolt = <3300000>;
  6601. + };
  6602. +
  6603. + vdd_mx6_high_reg: ldo11 {
  6604. + regulator-min-microvolt = <3000000>;
  6605. + regulator-max-microvolt = <3000000>;
  6606. + regulator-always-on;
  6607. + };
  6608. + };
  6609. + };
  6610. +};
  6611. +
  6612. +&iomuxc {
  6613. + pinctrl-names = "default";
  6614. + pinctrl-0 = <&pinctrl_hog>;
  6615. +
  6616. + imx6q-phytec-pfla02 {
  6617. + pinctrl_hog: hoggrp {
  6618. + fsl,pins = <
  6619. + MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  6620. + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
  6621. + MX6QDL_PAD_DI0_PIN15__GPIO4_IO17 0x80000000 /* PMIC interrupt */
  6622. + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* Green LED */
  6623. + MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x80000000 /* Red LED */
  6624. + >;
  6625. + };
  6626. +
  6627. + pinctrl_ecspi3: ecspi3grp {
  6628. + fsl,pins = <
  6629. + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
  6630. + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
  6631. + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
  6632. + >;
  6633. + };
  6634. +
  6635. + pinctrl_enet: enetgrp {
  6636. + fsl,pins = <
  6637. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  6638. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  6639. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  6640. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  6641. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  6642. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  6643. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  6644. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  6645. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  6646. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  6647. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  6648. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  6649. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  6650. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  6651. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  6652. + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
  6653. + >;
  6654. + };
  6655. +
  6656. + pinctrl_gpmi_nand: gpminandgrp {
  6657. + fsl,pins = <
  6658. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  6659. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  6660. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  6661. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  6662. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  6663. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  6664. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  6665. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  6666. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  6667. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  6668. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  6669. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  6670. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  6671. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  6672. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  6673. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  6674. + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  6675. + >;
  6676. + };
  6677. +
  6678. + pinctrl_i2c1: i2c1grp {
  6679. + fsl,pins = <
  6680. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  6681. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  6682. + >;
  6683. + };
  6684. +
  6685. + pinctrl_uart3: uart3grp {
  6686. + fsl,pins = <
  6687. + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  6688. + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  6689. + MX6QDL_PAD_EIM_D30__UART3_RTS_B 0x1b0b1
  6690. + MX6QDL_PAD_EIM_D31__UART3_CTS_B 0x1b0b1
  6691. + >;
  6692. + };
  6693. +
  6694. + pinctrl_uart4: uart4grp {
  6695. + fsl,pins = <
  6696. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  6697. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  6698. + >;
  6699. + };
  6700. +
  6701. + pinctrl_usbh1: usbh1grp {
  6702. + fsl,pins = <
  6703. + MX6QDL_PAD_GPIO_0__USB_H1_PWR 0x80000000
  6704. + >;
  6705. + };
  6706. +
  6707. + pinctrl_usbotg: usbotggrp {
  6708. + fsl,pins = <
  6709. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  6710. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  6711. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000
  6712. + >;
  6713. + };
  6714. +
  6715. + pinctrl_usdhc2: usdhc2grp {
  6716. + fsl,pins = <
  6717. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  6718. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  6719. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  6720. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  6721. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  6722. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  6723. + >;
  6724. + };
  6725. +
  6726. + pinctrl_usdhc3: usdhc3grp {
  6727. + fsl,pins = <
  6728. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  6729. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  6730. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  6731. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  6732. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  6733. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  6734. + >;
  6735. + };
  6736. +
  6737. + pinctrl_usdhc3_cdwp: usdhc3cdwp {
  6738. + fsl,pins = <
  6739. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
  6740. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
  6741. + >;
  6742. + };
  6743. + };
  6744. +};
  6745. +
  6746. +&fec {
  6747. + pinctrl-names = "default";
  6748. + pinctrl-0 = <&pinctrl_enet>;
  6749. + phy-mode = "rgmii";
  6750. + phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
  6751. + status = "disabled";
  6752. +};
  6753. +
  6754. +&gpmi {
  6755. + pinctrl-names = "default";
  6756. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  6757. + nand-on-flash-bbt;
  6758. + status = "disabled";
  6759. +};
  6760. +
  6761. +&uart3 {
  6762. + pinctrl-names = "default";
  6763. + pinctrl-0 = <&pinctrl_uart3>;
  6764. + status = "disabled";
  6765. +};
  6766. +
  6767. +&uart4 {
  6768. + pinctrl-names = "default";
  6769. + pinctrl-0 = <&pinctrl_uart4>;
  6770. + status = "disabled";
  6771. +};
  6772. +
  6773. +&usbh1 {
  6774. + vbus-supply = <&reg_usb_h1_vbus>;
  6775. + pinctrl-names = "default";
  6776. + pinctrl-0 = <&pinctrl_usbh1>;
  6777. + status = "disabled";
  6778. +};
  6779. +
  6780. +&usbotg {
  6781. + vbus-supply = <&reg_usb_otg_vbus>;
  6782. + pinctrl-names = "default";
  6783. + pinctrl-0 = <&pinctrl_usbotg>;
  6784. + disable-over-current;
  6785. + status = "disabled";
  6786. +};
  6787. +
  6788. +&usdhc2 {
  6789. + pinctrl-names = "default";
  6790. + pinctrl-0 = <&pinctrl_usdhc2>;
  6791. + cd-gpios = <&gpio1 4 0>;
  6792. + wp-gpios = <&gpio1 2 0>;
  6793. + status = "disabled";
  6794. +};
  6795. +
  6796. +&usdhc3 {
  6797. + pinctrl-names = "default";
  6798. + pinctrl-0 = <&pinctrl_usdhc3
  6799. + &pinctrl_usdhc3_cdwp>;
  6800. + cd-gpios = <&gpio1 27 0>;
  6801. + wp-gpios = <&gpio1 29 0>;
  6802. + status = "disabled";
  6803. +};
  6804. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
  6805. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi 2014-07-31 23:51:43.000000000 +0200
  6806. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi 2014-08-20 19:31:39.904842290 +0200
  6807. @@ -10,17 +10,146 @@
  6808. * http://www.gnu.org/copyleft/gpl.html
  6809. */
  6810. +#include <dt-bindings/gpio/gpio.h>
  6811. +
  6812. / {
  6813. + aliases {
  6814. + mxcfb0 = &mxcfb1;
  6815. + mxcfb1 = &mxcfb2;
  6816. + mxcfb2 = &mxcfb3;
  6817. + mxcfb3 = &mxcfb4;
  6818. + };
  6819. +
  6820. memory {
  6821. reg = <0x10000000 0x80000000>;
  6822. };
  6823. +
  6824. + leds {
  6825. + compatible = "gpio-leds";
  6826. + pinctrl-names = "default";
  6827. + pinctrl-0 = <&pinctrl_gpio_leds>;
  6828. +
  6829. + user {
  6830. + label = "debug";
  6831. + gpios = <&gpio5 15 GPIO_ACTIVE_HIGH>;
  6832. + };
  6833. + };
  6834. +
  6835. + sound-spdif {
  6836. + compatible = "fsl,imx-audio-spdif",
  6837. + "fsl,imx-sabreauto-spdif";
  6838. + model = "imx-spdif";
  6839. + spdif-controller = <&spdif>;
  6840. + spdif-in;
  6841. + };
  6842. +
  6843. + backlight {
  6844. + compatible = "pwm-backlight";
  6845. + pwms = <&pwm3 0 5000000>;
  6846. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6847. + default-brightness-level = <7>;
  6848. + status = "okay";
  6849. + };
  6850. +
  6851. + max7310_reset: max7310-reset {
  6852. + compatible = "gpio-reset";
  6853. + reset-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
  6854. + reset-delay-us = <1>;
  6855. + #reset-cells = <0>;
  6856. + };
  6857. +
  6858. + mxcfb1: fb@0 {
  6859. + compatible = "fsl,mxc_sdc_fb";
  6860. + disp_dev = "ldb";
  6861. + interface_pix_fmt = "RGB666";
  6862. + mode_str ="LDB-XGA";
  6863. + default_bpp = <16>;
  6864. + int_clk = <0>;
  6865. + late_init = <0>;
  6866. + status = "disabled";
  6867. + };
  6868. +
  6869. + mxcfb2: fb@1 {
  6870. + compatible = "fsl,mxc_sdc_fb";
  6871. + disp_dev = "hdmi";
  6872. + interface_pix_fmt = "RGB24";
  6873. + mode_str ="1920x1080M@60";
  6874. + default_bpp = <24>;
  6875. + int_clk = <0>;
  6876. + late_init = <0>;
  6877. + status = "disabled";
  6878. + };
  6879. +
  6880. + mxcfb3: fb@2 {
  6881. + compatible = "fsl,mxc_sdc_fb";
  6882. + disp_dev = "lcd";
  6883. + interface_pix_fmt = "RGB565";
  6884. + mode_str ="CLAA-WVGA";
  6885. + default_bpp = <16>;
  6886. + int_clk = <0>;
  6887. + late_init = <0>;
  6888. + status = "disabled";
  6889. + };
  6890. +
  6891. + mxcfb4: fb@3 {
  6892. + compatible = "fsl,mxc_sdc_fb";
  6893. + disp_dev = "ldb";
  6894. + interface_pix_fmt = "RGB666";
  6895. + mode_str ="LDB-XGA";
  6896. + default_bpp = <16>;
  6897. + int_clk = <0>;
  6898. + late_init = <0>;
  6899. + status = "disabled";
  6900. + };
  6901. +
  6902. + backlight {
  6903. + compatible = "pwm-backlight";
  6904. + pwms = <&pwm3 0 5000000>;
  6905. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6906. + default-brightness-level = <7>;
  6907. + };
  6908. +
  6909. + regulators {
  6910. + compatible = "simple-bus";
  6911. + reg_audio: cs42888_supply {
  6912. + compatible = "regulator-fixed";
  6913. + regulator-name = "cs42888_supply";
  6914. + regulator-min-microvolt = <3300000>;
  6915. + regulator-max-microvolt = <3300000>;
  6916. + regulator-always-on;
  6917. + };
  6918. + };
  6919. +
  6920. + sound-cs42888 {
  6921. + compatible = "fsl,imx6-sabreauto-cs42888",
  6922. + "fsl,imx-audio-cs42888";
  6923. + model = "imx-cs42888";
  6924. + esai-controller = <&esai>;
  6925. + asrc-controller = <&asrc_p2p>;
  6926. + audio-codec = <&codec>;
  6927. + };
  6928. +
  6929. + sound-hdmi {
  6930. + compatible = "fsl,imx6q-audio-hdmi",
  6931. + "fsl,imx-audio-hdmi";
  6932. + model = "imx-audio-hdmi";
  6933. + hdmi-controller = <&hdmi_audio>;
  6934. + };
  6935. +
  6936. + clocks {
  6937. + codec_osc: anaclk2 {
  6938. + compatible = "fixed-clock";
  6939. + #clock-cells = <0>;
  6940. + clock-frequency = <24576000>;
  6941. + };
  6942. + };
  6943. };
  6944. &ecspi1 {
  6945. fsl,spi-num-chipselects = <1>;
  6946. cs-gpios = <&gpio3 19 0>;
  6947. pinctrl-names = "default";
  6948. - pinctrl-0 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_sabreauto>;
  6949. + pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
  6950. status = "disabled"; /* pin conflict with WEIM NOR */
  6951. flash: m25p80@0 {
  6952. @@ -34,51 +163,481 @@
  6953. &fec {
  6954. pinctrl-names = "default";
  6955. - pinctrl-0 = <&pinctrl_enet_2>;
  6956. + pinctrl-0 = <&pinctrl_enet>;
  6957. phy-mode = "rgmii";
  6958. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  6959. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  6960. status = "okay";
  6961. };
  6962. &gpmi {
  6963. pinctrl-names = "default";
  6964. - pinctrl-0 = <&pinctrl_gpmi_nand_1>;
  6965. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  6966. + status = "okay";
  6967. +};
  6968. +
  6969. +&i2c2 {
  6970. + clock-frequency = <100000>;
  6971. + pinctrl-names = "default";
  6972. + pinctrl-0 = <&pinctrl_i2c2>;
  6973. + status = "okay";
  6974. +
  6975. + egalax_ts@04 {
  6976. + compatible = "eeti,egalax_ts";
  6977. + reg = <0x04>;
  6978. + interrupt-parent = <&gpio2>;
  6979. + interrupts = <28 2>;
  6980. + wakeup-gpios = <&gpio2 28 0>;
  6981. + };
  6982. +
  6983. + pmic: pfuze100@08 {
  6984. + compatible = "fsl,pfuze100";
  6985. + reg = <0x08>;
  6986. +
  6987. + regulators {
  6988. + sw1a_reg: sw1ab {
  6989. + regulator-min-microvolt = <300000>;
  6990. + regulator-max-microvolt = <1875000>;
  6991. + regulator-boot-on;
  6992. + regulator-always-on;
  6993. + regulator-ramp-delay = <6250>;
  6994. + };
  6995. +
  6996. + sw1c_reg: sw1c {
  6997. + regulator-min-microvolt = <300000>;
  6998. + regulator-max-microvolt = <1875000>;
  6999. + regulator-boot-on;
  7000. + regulator-always-on;
  7001. + regulator-ramp-delay = <6250>;
  7002. + };
  7003. +
  7004. + sw2_reg: sw2 {
  7005. + regulator-min-microvolt = <800000>;
  7006. + regulator-max-microvolt = <3300000>;
  7007. + regulator-boot-on;
  7008. + regulator-always-on;
  7009. + };
  7010. +
  7011. + sw3a_reg: sw3a {
  7012. + regulator-min-microvolt = <400000>;
  7013. + regulator-max-microvolt = <1975000>;
  7014. + regulator-boot-on;
  7015. + regulator-always-on;
  7016. + };
  7017. +
  7018. + sw3b_reg: sw3b {
  7019. + regulator-min-microvolt = <400000>;
  7020. + regulator-max-microvolt = <1975000>;
  7021. + regulator-boot-on;
  7022. + regulator-always-on;
  7023. + };
  7024. +
  7025. + sw4_reg: sw4 {
  7026. + regulator-min-microvolt = <800000>;
  7027. + regulator-max-microvolt = <3300000>;
  7028. + };
  7029. +
  7030. + swbst_reg: swbst {
  7031. + regulator-min-microvolt = <5000000>;
  7032. + regulator-max-microvolt = <5150000>;
  7033. + };
  7034. +
  7035. + snvs_reg: vsnvs {
  7036. + regulator-min-microvolt = <1000000>;
  7037. + regulator-max-microvolt = <3000000>;
  7038. + regulator-boot-on;
  7039. + regulator-always-on;
  7040. + };
  7041. +
  7042. + vref_reg: vrefddr {
  7043. + regulator-boot-on;
  7044. + regulator-always-on;
  7045. + };
  7046. +
  7047. + vgen1_reg: vgen1 {
  7048. + regulator-min-microvolt = <800000>;
  7049. + regulator-max-microvolt = <1550000>;
  7050. + };
  7051. +
  7052. + vgen2_reg: vgen2 {
  7053. + regulator-min-microvolt = <800000>;
  7054. + regulator-max-microvolt = <1550000>;
  7055. + };
  7056. +
  7057. + vgen3_reg: vgen3 {
  7058. + regulator-min-microvolt = <1800000>;
  7059. + regulator-max-microvolt = <3300000>;
  7060. + };
  7061. +
  7062. + vgen4_reg: vgen4 {
  7063. + regulator-min-microvolt = <1800000>;
  7064. + regulator-max-microvolt = <3300000>;
  7065. + regulator-always-on;
  7066. + };
  7067. +
  7068. + vgen5_reg: vgen5 {
  7069. + regulator-min-microvolt = <1800000>;
  7070. + regulator-max-microvolt = <3300000>;
  7071. + regulator-always-on;
  7072. + };
  7073. +
  7074. + vgen6_reg: vgen6 {
  7075. + regulator-min-microvolt = <1800000>;
  7076. + regulator-max-microvolt = <3300000>;
  7077. + regulator-always-on;
  7078. + };
  7079. + };
  7080. + };
  7081. +
  7082. + codec: cs42888@048 {
  7083. + compatible = "cirrus,cs42888";
  7084. + reg = <0x048>;
  7085. + clocks = <&codec_osc 0>;
  7086. + clock-names = "codec_osc";
  7087. + VA-supply = <&reg_audio>;
  7088. + VD-supply = <&reg_audio>;
  7089. + VLS-supply = <&reg_audio>;
  7090. + VLC-supply = <&reg_audio>;
  7091. + };
  7092. +
  7093. + hdmi: edid@50 {
  7094. + compatible = "fsl,imx6-hdmi-i2c";
  7095. + reg = <0x50>;
  7096. + };
  7097. +};
  7098. +
  7099. +&i2c3 {
  7100. + pinctrl-names = "default";
  7101. + pinctrl-0 = <&pinctrl_i2c3>;
  7102. + pinctrl-assert-gpios = <&gpio5 4 GPIO_ACTIVE_HIGH>;
  7103. status = "okay";
  7104. +
  7105. + max7310_a: gpio@30 {
  7106. + compatible = "maxim,max7310";
  7107. + reg = <0x30>;
  7108. + gpio-controller;
  7109. + #gpio-cells = <2>;
  7110. + resets = <&max7310_reset>;
  7111. + };
  7112. +
  7113. + max7310_b: gpio@32 {
  7114. + compatible = "maxim,max7310";
  7115. + reg = <0x32>;
  7116. + gpio-controller;
  7117. + #gpio-cells = <2>;
  7118. + };
  7119. +
  7120. + max7310_c: gpio@34 {
  7121. + compatible = "maxim,max7310";
  7122. + reg = <0x34>;
  7123. + gpio-controller;
  7124. + #gpio-cells = <2>;
  7125. + };
  7126. };
  7127. &iomuxc {
  7128. pinctrl-names = "default";
  7129. pinctrl-0 = <&pinctrl_hog>;
  7130. - hog {
  7131. + imx6qdl-sabreauto {
  7132. pinctrl_hog: hoggrp {
  7133. fsl,pins = <
  7134. MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
  7135. MX6QDL_PAD_SD2_DAT2__GPIO1_IO13 0x80000000
  7136. + MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x80000000
  7137. + MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x80000000
  7138. MX6QDL_PAD_GPIO_18__SD3_VSELECT 0x17059
  7139. >;
  7140. };
  7141. - };
  7142. - ecspi1 {
  7143. - pinctrl_ecspi1_sabreauto: ecspi1-sabreauto {
  7144. + pinctrl_esai1: esai1grp {
  7145. + fsl,pins = <
  7146. + MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1b030
  7147. + MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS 0x1b030
  7148. + MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1b030
  7149. + MX6QDL_PAD_GPIO_5__ESAI_TX2_RX3 0x1b030
  7150. + MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1 0x1b030
  7151. + MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0 0x1b030
  7152. + MX6QDL_PAD_GPIO_17__ESAI_TX0 0x1b030
  7153. + MX6QDL_PAD_NANDF_CS3__ESAI_TX1 0x1b030
  7154. + MX6QDL_PAD_ENET_MDIO__ESAI_RX_CLK 0x1b030
  7155. + MX6QDL_PAD_GPIO_9__ESAI_RX_FS 0x1b030
  7156. + >;
  7157. + };
  7158. +
  7159. + pinctrl_ecspi1: ecspi1grp {
  7160. + fsl,pins = <
  7161. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  7162. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  7163. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  7164. + >;
  7165. + };
  7166. +
  7167. + pinctrl_ecspi1_cs: ecspi1cs {
  7168. fsl,pins = <
  7169. MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000
  7170. >;
  7171. };
  7172. +
  7173. + pinctrl_enet: enetgrp {
  7174. + fsl,pins = <
  7175. + MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
  7176. + MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0
  7177. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  7178. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  7179. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  7180. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  7181. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  7182. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  7183. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  7184. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  7185. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  7186. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  7187. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  7188. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  7189. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  7190. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  7191. + >;
  7192. + };
  7193. +
  7194. + pinctrl_gpio_leds: gpioledsgrp {
  7195. + fsl,pins = <
  7196. + MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x80000000
  7197. + >;
  7198. + };
  7199. +
  7200. + pinctrl_gpmi_nand: gpminandgrp {
  7201. + fsl,pins = <
  7202. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  7203. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  7204. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  7205. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  7206. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  7207. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  7208. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  7209. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  7210. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  7211. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  7212. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  7213. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  7214. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  7215. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  7216. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  7217. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  7218. + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  7219. + >;
  7220. + };
  7221. +
  7222. + pinctrl_hdmi_cec_2: hdmicecgrp-2 {
  7223. + fsl,pins = <
  7224. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  7225. + >;
  7226. + };
  7227. +
  7228. + pinctrl_i2c2: i2c2grp {
  7229. + fsl,pins = <
  7230. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  7231. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  7232. + >;
  7233. + };
  7234. +
  7235. + pinctrl_i2c3: i2c3grp {
  7236. + fsl,pins = <
  7237. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  7238. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  7239. + >;
  7240. + };
  7241. +
  7242. + pinctrl_pwm1: pwm1grp {
  7243. + fsl,pins = <
  7244. + MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
  7245. + >;
  7246. + };
  7247. +
  7248. + pinctrl_spdif: spdifgrp {
  7249. + fsl,pins = <
  7250. + MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x1b0b0
  7251. + >;
  7252. + };
  7253. +
  7254. + pinctrl_uart3: uart3grp {
  7255. + fsl,pins = <
  7256. + MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x1b0b1
  7257. + MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x1b0b1
  7258. + MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x1b0b1
  7259. + MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  7260. + >;
  7261. + };
  7262. +
  7263. + pinctrl_uart4: uart4grp {
  7264. + fsl,pins = <
  7265. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  7266. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  7267. + >;
  7268. + };
  7269. +
  7270. + pinctrl_usdhc3: usdhc3grp {
  7271. + fsl,pins = <
  7272. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  7273. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  7274. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  7275. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  7276. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  7277. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  7278. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
  7279. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
  7280. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
  7281. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
  7282. + >;
  7283. + };
  7284. +
  7285. + pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
  7286. + fsl,pins = <
  7287. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9
  7288. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9
  7289. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  7290. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  7291. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  7292. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  7293. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9
  7294. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9
  7295. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9
  7296. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9
  7297. + >;
  7298. + };
  7299. +
  7300. + pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
  7301. + fsl,pins = <
  7302. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9
  7303. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9
  7304. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  7305. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  7306. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  7307. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  7308. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
  7309. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
  7310. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
  7311. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
  7312. + >;
  7313. + };
  7314. +
  7315. + pinctrl_weim_cs0: weimcs0grp {
  7316. + fsl,pins = <
  7317. + MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0xb0b1
  7318. + >;
  7319. + };
  7320. +
  7321. + pinctrl_weim_nor: weimnorgrp {
  7322. + fsl,pins = <
  7323. + MX6QDL_PAD_EIM_OE__EIM_OE_B 0xb0b1
  7324. + MX6QDL_PAD_EIM_RW__EIM_RW 0xb0b1
  7325. + MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060
  7326. + MX6QDL_PAD_EIM_D16__EIM_DATA16 0x1b0b0
  7327. + MX6QDL_PAD_EIM_D17__EIM_DATA17 0x1b0b0
  7328. + MX6QDL_PAD_EIM_D18__EIM_DATA18 0x1b0b0
  7329. + MX6QDL_PAD_EIM_D19__EIM_DATA19 0x1b0b0
  7330. + MX6QDL_PAD_EIM_D20__EIM_DATA20 0x1b0b0
  7331. + MX6QDL_PAD_EIM_D21__EIM_DATA21 0x1b0b0
  7332. + MX6QDL_PAD_EIM_D22__EIM_DATA22 0x1b0b0
  7333. + MX6QDL_PAD_EIM_D23__EIM_DATA23 0x1b0b0
  7334. + MX6QDL_PAD_EIM_D24__EIM_DATA24 0x1b0b0
  7335. + MX6QDL_PAD_EIM_D25__EIM_DATA25 0x1b0b0
  7336. + MX6QDL_PAD_EIM_D26__EIM_DATA26 0x1b0b0
  7337. + MX6QDL_PAD_EIM_D27__EIM_DATA27 0x1b0b0
  7338. + MX6QDL_PAD_EIM_D28__EIM_DATA28 0x1b0b0
  7339. + MX6QDL_PAD_EIM_D29__EIM_DATA29 0x1b0b0
  7340. + MX6QDL_PAD_EIM_D30__EIM_DATA30 0x1b0b0
  7341. + MX6QDL_PAD_EIM_D31__EIM_DATA31 0x1b0b0
  7342. + MX6QDL_PAD_EIM_A23__EIM_ADDR23 0xb0b1
  7343. + MX6QDL_PAD_EIM_A22__EIM_ADDR22 0xb0b1
  7344. + MX6QDL_PAD_EIM_A21__EIM_ADDR21 0xb0b1
  7345. + MX6QDL_PAD_EIM_A20__EIM_ADDR20 0xb0b1
  7346. + MX6QDL_PAD_EIM_A19__EIM_ADDR19 0xb0b1
  7347. + MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0b1
  7348. + MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0b1
  7349. + MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0b1
  7350. + MX6QDL_PAD_EIM_DA15__EIM_AD15 0xb0b1
  7351. + MX6QDL_PAD_EIM_DA14__EIM_AD14 0xb0b1
  7352. + MX6QDL_PAD_EIM_DA13__EIM_AD13 0xb0b1
  7353. + MX6QDL_PAD_EIM_DA12__EIM_AD12 0xb0b1
  7354. + MX6QDL_PAD_EIM_DA11__EIM_AD11 0xb0b1
  7355. + MX6QDL_PAD_EIM_DA10__EIM_AD10 0xb0b1
  7356. + MX6QDL_PAD_EIM_DA9__EIM_AD09 0xb0b1
  7357. + MX6QDL_PAD_EIM_DA8__EIM_AD08 0xb0b1
  7358. + MX6QDL_PAD_EIM_DA7__EIM_AD07 0xb0b1
  7359. + MX6QDL_PAD_EIM_DA6__EIM_AD06 0xb0b1
  7360. + MX6QDL_PAD_EIM_DA5__EIM_AD05 0xb0b1
  7361. + MX6QDL_PAD_EIM_DA4__EIM_AD04 0xb0b1
  7362. + MX6QDL_PAD_EIM_DA3__EIM_AD03 0xb0b1
  7363. + MX6QDL_PAD_EIM_DA2__EIM_AD02 0xb0b1
  7364. + MX6QDL_PAD_EIM_DA1__EIM_AD01 0xb0b1
  7365. + MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0b1
  7366. + >;
  7367. + };
  7368. + };
  7369. +};
  7370. +
  7371. +&ldb {
  7372. + status = "okay";
  7373. +
  7374. + lvds-channel@0 {
  7375. + fsl,data-mapping = "spwg";
  7376. + fsl,data-width = <18>;
  7377. + status = "okay";
  7378. +
  7379. + display-timings {
  7380. + native-mode = <&timing0>;
  7381. + timing0: hsd100pxn1 {
  7382. + clock-frequency = <65000000>;
  7383. + hactive = <1024>;
  7384. + vactive = <768>;
  7385. + hback-porch = <220>;
  7386. + hfront-porch = <40>;
  7387. + vback-porch = <21>;
  7388. + vfront-porch = <7>;
  7389. + hsync-len = <60>;
  7390. + vsync-len = <10>;
  7391. + };
  7392. + };
  7393. };
  7394. };
  7395. +&pcie {
  7396. + status = "okay";
  7397. +};
  7398. +
  7399. +&pwm3 {
  7400. + pinctrl-names = "default";
  7401. + pinctrl-0 = <&pinctrl_pwm1>;
  7402. + status = "okay";
  7403. +};
  7404. +
  7405. +&spdif {
  7406. + pinctrl-names = "default";
  7407. + pinctrl-0 = <&pinctrl_spdif>;
  7408. + status = "okay";
  7409. +};
  7410. +
  7411. +&uart3 {
  7412. + pinctrl-names = "default";
  7413. + pinctrl-0 = <&pinctrl_uart3>;
  7414. + pinctrl-assert-gpios = <&max7310_b 4 GPIO_ACTIVE_HIGH>, /* CTS */
  7415. + <&max7310_c 3 GPIO_ACTIVE_HIGH>; /* RXD and TXD */
  7416. + fsl,uart-has-rtscts;
  7417. + status = "okay";
  7418. +};
  7419. +
  7420. &uart4 {
  7421. pinctrl-names = "default";
  7422. - pinctrl-0 = <&pinctrl_uart4_1>;
  7423. + pinctrl-0 = <&pinctrl_uart4>;
  7424. status = "okay";
  7425. };
  7426. &usdhc3 {
  7427. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  7428. - pinctrl-0 = <&pinctrl_usdhc3_1>;
  7429. - pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
  7430. - pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
  7431. + pinctrl-0 = <&pinctrl_usdhc3>;
  7432. + pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
  7433. + pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
  7434. cd-gpios = <&gpio6 15 0>;
  7435. wp-gpios = <&gpio1 13 0>;
  7436. status = "okay";
  7437. @@ -86,7 +645,7 @@
  7438. &weim {
  7439. pinctrl-names = "default";
  7440. - pinctrl-0 = <&pinctrl_weim_nor_1 &pinctrl_weim_cs0_1>;
  7441. + pinctrl-0 = <&pinctrl_weim_nor &pinctrl_weim_cs0>;
  7442. #address-cells = <2>;
  7443. #size-cells = <1>;
  7444. ranges = <0 0 0x08000000 0x08000000>;
  7445. @@ -102,3 +661,48 @@
  7446. 0x0000c000 0x1404a38e 0x00000000>;
  7447. };
  7448. };
  7449. +
  7450. +&ldb {
  7451. + ipu_id = <1>;
  7452. + disp_id = <0>;
  7453. + ext_ref = <1>;
  7454. + mode = "sep0";
  7455. + sec_ipu_id = <1>;
  7456. + sec_disp_id = <1>;
  7457. + status = "okay";
  7458. +};
  7459. +
  7460. +&esai {
  7461. + pinctrl-names = "default";
  7462. + pinctrl-0 = <&pinctrl_esai1>;
  7463. + status = "okay";
  7464. +};
  7465. +
  7466. +&hdmi_core {
  7467. + ipu_id = <0>;
  7468. + disp_id = <1>;
  7469. + status = "okay";
  7470. +};
  7471. +
  7472. +&hdmi_video {
  7473. + fsl,phy_reg_vlev = <0x0294>;
  7474. + fsl,phy_reg_cksymtx = <0x800d>;
  7475. + status = "okay";
  7476. +};
  7477. +
  7478. +&hdmi_audio {
  7479. + status = "okay";
  7480. +};
  7481. +
  7482. +&hdmi_cec {
  7483. + pinctrl-names = "default";
  7484. + pinctrl-0 = <&pinctrl_hdmi_cec_2>;
  7485. + status = "okay";
  7486. +};
  7487. +
  7488. +&gpc {
  7489. + fsl,cpu_pupscr_sw2iso = <0xf>;
  7490. + fsl,cpu_pupscr_sw = <0xf>;
  7491. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  7492. + fsl,cpu_pdnscr_iso = <0x1>;
  7493. +};
  7494. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
  7495. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi 1970-01-01 01:00:00.000000000 +0100
  7496. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi 2014-08-20 19:31:39.904842290 +0200
  7497. @@ -0,0 +1,427 @@
  7498. +/*
  7499. + * Copyright 2011 Freescale Semiconductor, Inc.
  7500. + * Copyright 2011 Linaro Ltd.
  7501. + *
  7502. + * The code contained herein is licensed under the GNU General Public
  7503. + * License. You may obtain a copy of the GNU General Public License
  7504. + * Version 2 or later at the following locations:
  7505. + *
  7506. + * http://www.opensource.org/licenses/gpl-license.html
  7507. + * http://www.gnu.org/copyleft/gpl.html
  7508. + */
  7509. +#include <dt-bindings/gpio/gpio.h>
  7510. +#include <dt-bindings/input/input.h>
  7511. +
  7512. +/ {
  7513. + chosen {
  7514. + stdout-path = &uart2;
  7515. + };
  7516. +
  7517. + memory {
  7518. + reg = <0x10000000 0x40000000>;
  7519. + };
  7520. +
  7521. + regulators {
  7522. + compatible = "simple-bus";
  7523. + #address-cells = <1>;
  7524. + #size-cells = <0>;
  7525. +
  7526. + reg_2p5v: regulator@0 {
  7527. + compatible = "regulator-fixed";
  7528. + reg = <0>;
  7529. + regulator-name = "2P5V";
  7530. + regulator-min-microvolt = <2500000>;
  7531. + regulator-max-microvolt = <2500000>;
  7532. + regulator-always-on;
  7533. + };
  7534. +
  7535. + reg_3p3v: regulator@1 {
  7536. + compatible = "regulator-fixed";
  7537. + reg = <1>;
  7538. + regulator-name = "3P3V";
  7539. + regulator-min-microvolt = <3300000>;
  7540. + regulator-max-microvolt = <3300000>;
  7541. + regulator-always-on;
  7542. + };
  7543. +
  7544. + reg_usb_otg_vbus: regulator@2 {
  7545. + compatible = "regulator-fixed";
  7546. + reg = <2>;
  7547. + regulator-name = "usb_otg_vbus";
  7548. + regulator-min-microvolt = <5000000>;
  7549. + regulator-max-microvolt = <5000000>;
  7550. + gpio = <&gpio3 22 0>;
  7551. + enable-active-high;
  7552. + };
  7553. + };
  7554. +
  7555. + gpio-keys {
  7556. + compatible = "gpio-keys";
  7557. + pinctrl-names = "default";
  7558. + pinctrl-0 = <&pinctrl_gpio_keys>;
  7559. +
  7560. + power {
  7561. + label = "Power Button";
  7562. + gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
  7563. + linux,code = <KEY_POWER>;
  7564. + gpio-key,wakeup;
  7565. + };
  7566. +
  7567. + menu {
  7568. + label = "Menu";
  7569. + gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
  7570. + linux,code = <KEY_MENU>;
  7571. + };
  7572. +
  7573. + home {
  7574. + label = "Home";
  7575. + gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
  7576. + linux,code = <KEY_HOME>;
  7577. + };
  7578. +
  7579. + back {
  7580. + label = "Back";
  7581. + gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
  7582. + linux,code = <KEY_BACK>;
  7583. + };
  7584. +
  7585. + volume-up {
  7586. + label = "Volume Up";
  7587. + gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
  7588. + linux,code = <KEY_VOLUMEUP>;
  7589. + };
  7590. +
  7591. + volume-down {
  7592. + label = "Volume Down";
  7593. + gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
  7594. + linux,code = <KEY_VOLUMEDOWN>;
  7595. + };
  7596. + };
  7597. +
  7598. + sound {
  7599. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  7600. + "fsl,imx-audio-sgtl5000";
  7601. + model = "imx6q-sabrelite-sgtl5000";
  7602. + ssi-controller = <&ssi1>;
  7603. + audio-codec = <&codec>;
  7604. + audio-routing =
  7605. + "MIC_IN", "Mic Jack",
  7606. + "Mic Jack", "Mic Bias",
  7607. + "Headphone Jack", "HP_OUT";
  7608. + mux-int-port = <1>;
  7609. + mux-ext-port = <4>;
  7610. + };
  7611. +
  7612. + backlight_lcd {
  7613. + compatible = "pwm-backlight";
  7614. + pwms = <&pwm1 0 5000000>;
  7615. + brightness-levels = <0 4 8 16 32 64 128 255>;
  7616. + default-brightness-level = <7>;
  7617. + power-supply = <&reg_3p3v>;
  7618. + status = "okay";
  7619. + };
  7620. +
  7621. + backlight_lvds {
  7622. + compatible = "pwm-backlight";
  7623. + pwms = <&pwm4 0 5000000>;
  7624. + brightness-levels = <0 4 8 16 32 64 128 255>;
  7625. + default-brightness-level = <7>;
  7626. + power-supply = <&reg_3p3v>;
  7627. + status = "okay";
  7628. + };
  7629. +};
  7630. +
  7631. +&audmux {
  7632. + pinctrl-names = "default";
  7633. + pinctrl-0 = <&pinctrl_audmux>;
  7634. + status = "okay";
  7635. +};
  7636. +
  7637. +&ecspi1 {
  7638. + fsl,spi-num-chipselects = <1>;
  7639. + cs-gpios = <&gpio3 19 0>;
  7640. + pinctrl-names = "default";
  7641. + pinctrl-0 = <&pinctrl_ecspi1>;
  7642. + status = "okay";
  7643. +
  7644. + flash: m25p80@0 {
  7645. + compatible = "sst,sst25vf016b";
  7646. + spi-max-frequency = <20000000>;
  7647. + reg = <0>;
  7648. + };
  7649. +};
  7650. +
  7651. +&fec {
  7652. + pinctrl-names = "default";
  7653. + pinctrl-0 = <&pinctrl_enet>;
  7654. + phy-mode = "rgmii";
  7655. + phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
  7656. + txen-skew-ps = <0>;
  7657. + txc-skew-ps = <3000>;
  7658. + rxdv-skew-ps = <0>;
  7659. + rxc-skew-ps = <3000>;
  7660. + rxd0-skew-ps = <0>;
  7661. + rxd1-skew-ps = <0>;
  7662. + rxd2-skew-ps = <0>;
  7663. + rxd3-skew-ps = <0>;
  7664. + txd0-skew-ps = <0>;
  7665. + txd1-skew-ps = <0>;
  7666. + txd2-skew-ps = <0>;
  7667. + txd3-skew-ps = <0>;
  7668. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  7669. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  7670. + status = "okay";
  7671. +};
  7672. +
  7673. +&i2c1 {
  7674. + clock-frequency = <100000>;
  7675. + pinctrl-names = "default";
  7676. + pinctrl-0 = <&pinctrl_i2c1>;
  7677. + status = "okay";
  7678. +
  7679. + codec: sgtl5000@0a {
  7680. + compatible = "fsl,sgtl5000";
  7681. + reg = <0x0a>;
  7682. + clocks = <&clks 201>;
  7683. + VDDA-supply = <&reg_2p5v>;
  7684. + VDDIO-supply = <&reg_3p3v>;
  7685. + };
  7686. +};
  7687. +
  7688. +&iomuxc {
  7689. + pinctrl-names = "default";
  7690. + pinctrl-0 = <&pinctrl_hog>;
  7691. +
  7692. + imx6q-sabrelite {
  7693. + pinctrl_hog: hoggrp {
  7694. + fsl,pins = <
  7695. + /* SGTL5000 sys_mclk */
  7696. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x030b0
  7697. + >;
  7698. + };
  7699. +
  7700. + pinctrl_audmux: audmuxgrp {
  7701. + fsl,pins = <
  7702. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  7703. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  7704. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  7705. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  7706. + >;
  7707. + };
  7708. +
  7709. + pinctrl_ecspi1: ecspi1grp {
  7710. + fsl,pins = <
  7711. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  7712. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  7713. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  7714. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x000b1 /* CS */
  7715. + >;
  7716. + };
  7717. +
  7718. + pinctrl_enet: enetgrp {
  7719. + fsl,pins = <
  7720. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0
  7721. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0
  7722. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0
  7723. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0
  7724. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0
  7725. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0
  7726. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0
  7727. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0
  7728. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0
  7729. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  7730. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  7731. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  7732. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  7733. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  7734. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  7735. + /* Phy reset */
  7736. + MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x000b0
  7737. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  7738. + >;
  7739. + };
  7740. +
  7741. + pinctrl_gpio_keys: gpio_keysgrp {
  7742. + fsl,pins = <
  7743. + /* Power Button */
  7744. + MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
  7745. + /* Menu Button */
  7746. + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
  7747. + /* Home Button */
  7748. + MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
  7749. + /* Back Button */
  7750. + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
  7751. + /* Volume Up Button */
  7752. + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0
  7753. + /* Volume Down Button */
  7754. + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
  7755. + >;
  7756. + };
  7757. +
  7758. + pinctrl_i2c1: i2c1grp {
  7759. + fsl,pins = <
  7760. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  7761. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  7762. + >;
  7763. + };
  7764. +
  7765. + pinctrl_pwm1: pwm1grp {
  7766. + fsl,pins = <
  7767. + MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  7768. + >;
  7769. + };
  7770. +
  7771. + pinctrl_pwm3: pwm3grp {
  7772. + fsl,pins = <
  7773. + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
  7774. + >;
  7775. + };
  7776. +
  7777. + pinctrl_pwm4: pwm4grp {
  7778. + fsl,pins = <
  7779. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  7780. + >;
  7781. + };
  7782. +
  7783. + pinctrl_uart1: uart1grp {
  7784. + fsl,pins = <
  7785. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  7786. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  7787. + >;
  7788. + };
  7789. +
  7790. + pinctrl_uart2: uart2grp {
  7791. + fsl,pins = <
  7792. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  7793. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  7794. + >;
  7795. + };
  7796. +
  7797. + pinctrl_usbotg: usbotggrp {
  7798. + fsl,pins = <
  7799. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  7800. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  7801. + /* power enable, high active */
  7802. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x000b0
  7803. + >;
  7804. + };
  7805. +
  7806. + pinctrl_usdhc3: usdhc3grp {
  7807. + fsl,pins = <
  7808. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  7809. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  7810. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  7811. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  7812. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  7813. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  7814. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
  7815. + MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0 /* WP */
  7816. + >;
  7817. + };
  7818. +
  7819. + pinctrl_usdhc4: usdhc4grp {
  7820. + fsl,pins = <
  7821. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  7822. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  7823. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  7824. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  7825. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  7826. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  7827. + MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /* CD */
  7828. + >;
  7829. + };
  7830. + };
  7831. +};
  7832. +
  7833. +&ldb {
  7834. + status = "okay";
  7835. +
  7836. + lvds-channel@0 {
  7837. + fsl,data-mapping = "spwg";
  7838. + fsl,data-width = <18>;
  7839. + status = "okay";
  7840. +
  7841. + display-timings {
  7842. + native-mode = <&timing0>;
  7843. + timing0: hsd100pxn1 {
  7844. + clock-frequency = <65000000>;
  7845. + hactive = <1024>;
  7846. + vactive = <768>;
  7847. + hback-porch = <220>;
  7848. + hfront-porch = <40>;
  7849. + vback-porch = <21>;
  7850. + vfront-porch = <7>;
  7851. + hsync-len = <60>;
  7852. + vsync-len = <10>;
  7853. + };
  7854. + };
  7855. + };
  7856. +};
  7857. +
  7858. +&pcie {
  7859. + status = "okay";
  7860. +};
  7861. +
  7862. +&pwm1 {
  7863. + pinctrl-names = "default";
  7864. + pinctrl-0 = <&pinctrl_pwm1>;
  7865. + status = "okay";
  7866. +};
  7867. +
  7868. +&pwm3 {
  7869. + pinctrl-names = "default";
  7870. + pinctrl-0 = <&pinctrl_pwm3>;
  7871. + status = "okay";
  7872. +};
  7873. +
  7874. +&pwm4 {
  7875. + pinctrl-names = "default";
  7876. + pinctrl-0 = <&pinctrl_pwm4>;
  7877. + status = "okay";
  7878. +};
  7879. +
  7880. +&ssi1 {
  7881. + fsl,mode = "i2s-slave";
  7882. + status = "okay";
  7883. +};
  7884. +
  7885. +&uart1 {
  7886. + pinctrl-names = "default";
  7887. + pinctrl-0 = <&pinctrl_uart1>;
  7888. + status = "okay";
  7889. +};
  7890. +
  7891. +&uart2 {
  7892. + pinctrl-names = "default";
  7893. + pinctrl-0 = <&pinctrl_uart2>;
  7894. + status = "okay";
  7895. +};
  7896. +
  7897. +&usbh1 {
  7898. + status = "okay";
  7899. +};
  7900. +
  7901. +&usbotg {
  7902. + vbus-supply = <&reg_usb_otg_vbus>;
  7903. + pinctrl-names = "default";
  7904. + pinctrl-0 = <&pinctrl_usbotg>;
  7905. + disable-over-current;
  7906. + status = "okay";
  7907. +};
  7908. +
  7909. +&usdhc3 {
  7910. + pinctrl-names = "default";
  7911. + pinctrl-0 = <&pinctrl_usdhc3>;
  7912. + cd-gpios = <&gpio7 0 0>;
  7913. + wp-gpios = <&gpio7 1 0>;
  7914. + vmmc-supply = <&reg_3p3v>;
  7915. + status = "okay";
  7916. +};
  7917. +
  7918. +&usdhc4 {
  7919. + pinctrl-names = "default";
  7920. + pinctrl-0 = <&pinctrl_usdhc4>;
  7921. + cd-gpios = <&gpio2 6 0>;
  7922. + vmmc-supply = <&reg_3p3v>;
  7923. + status = "okay";
  7924. +};
  7925. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-sabresd.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
  7926. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-sabresd.dtsi 2014-07-31 23:51:43.000000000 +0200
  7927. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-sabresd.dtsi 2014-08-20 19:31:39.904842290 +0200
  7928. @@ -10,16 +10,33 @@
  7929. * http://www.gnu.org/copyleft/gpl.html
  7930. */
  7931. +#include <dt-bindings/gpio/gpio.h>
  7932. +#include <dt-bindings/input/input.h>
  7933. +
  7934. / {
  7935. + aliases {
  7936. + mxcfb0 = &mxcfb1;
  7937. + mxcfb1 = &mxcfb2;
  7938. + mxcfb2 = &mxcfb3;
  7939. + mxcfb3 = &mxcfb4;
  7940. + };
  7941. +
  7942. + chosen {
  7943. + stdout-path = &uart1;
  7944. + };
  7945. +
  7946. memory {
  7947. reg = <0x10000000 0x40000000>;
  7948. };
  7949. regulators {
  7950. compatible = "simple-bus";
  7951. + #address-cells = <1>;
  7952. + #size-cells = <0>;
  7953. - reg_usb_otg_vbus: usb_otg_vbus {
  7954. + reg_usb_otg_vbus: regulator@0 {
  7955. compatible = "regulator-fixed";
  7956. + reg = <0>;
  7957. regulator-name = "usb_otg_vbus";
  7958. regulator-min-microvolt = <5000000>;
  7959. regulator-max-microvolt = <5000000>;
  7960. @@ -27,8 +44,9 @@
  7961. enable-active-high;
  7962. };
  7963. - reg_usb_h1_vbus: usb_h1_vbus {
  7964. + reg_usb_h1_vbus: regulator@1 {
  7965. compatible = "regulator-fixed";
  7966. + reg = <1>;
  7967. regulator-name = "usb_h1_vbus";
  7968. regulator-min-microvolt = <5000000>;
  7969. regulator-max-microvolt = <5000000>;
  7970. @@ -36,29 +54,46 @@
  7971. enable-active-high;
  7972. };
  7973. - reg_audio: wm8962_supply {
  7974. + reg_audio: regulator@2 {
  7975. compatible = "regulator-fixed";
  7976. + reg = <2>;
  7977. regulator-name = "wm8962-supply";
  7978. gpio = <&gpio4 10 0>;
  7979. enable-active-high;
  7980. };
  7981. +
  7982. + reg_mipi_dsi_pwr_on: mipi_dsi_pwr_on {
  7983. + compatible = "regulator-fixed";
  7984. + regulator-name = "mipi_dsi_pwr_on";
  7985. + gpio = <&gpio6 14 0>;
  7986. + enable-active-high;
  7987. + };
  7988. };
  7989. gpio-keys {
  7990. compatible = "gpio-keys";
  7991. + pinctrl-names = "default";
  7992. + pinctrl-0 = <&pinctrl_gpio_keys>;
  7993. +
  7994. + power {
  7995. + label = "Power Button";
  7996. + gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
  7997. + gpio-key,wakeup;
  7998. + linux,code = <KEY_POWER>;
  7999. + };
  8000. volume-up {
  8001. label = "Volume Up";
  8002. - gpios = <&gpio1 4 0>;
  8003. + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
  8004. gpio-key,wakeup;
  8005. - linux,code = <115>; /* KEY_VOLUMEUP */
  8006. + linux,code = <KEY_VOLUMEUP>;
  8007. };
  8008. volume-down {
  8009. label = "Volume Down";
  8010. - gpios = <&gpio1 5 0>;
  8011. + gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
  8012. gpio-key,wakeup;
  8013. - linux,code = <114>; /* KEY_VOLUMEDOWN */
  8014. + linux,code = <KEY_VOLUMEDOWN>;
  8015. };
  8016. };
  8017. @@ -88,11 +123,107 @@
  8018. default-brightness-level = <7>;
  8019. status = "okay";
  8020. };
  8021. +
  8022. + leds {
  8023. + compatible = "gpio-leds";
  8024. + pinctrl-names = "default";
  8025. + pinctrl-0 = <&pinctrl_gpio_leds>;
  8026. +
  8027. + red {
  8028. + gpios = <&gpio1 2 0>;
  8029. + default-state = "on";
  8030. + };
  8031. + };
  8032. +
  8033. + sound-hdmi {
  8034. + compatible = "fsl,imx6q-audio-hdmi",
  8035. + "fsl,imx-audio-hdmi";
  8036. + model = "imx-audio-hdmi";
  8037. + hdmi-controller = <&hdmi_audio>;
  8038. + };
  8039. +
  8040. + mxcfb1: fb@0 {
  8041. + compatible = "fsl,mxc_sdc_fb";
  8042. + disp_dev = "ldb";
  8043. + interface_pix_fmt = "RGB666";
  8044. + mode_str ="LDB-XGA";
  8045. + default_bpp = <16>;
  8046. + int_clk = <0>;
  8047. + late_init = <0>;
  8048. + status = "disabled";
  8049. + };
  8050. +
  8051. + mxcfb2: fb@1 {
  8052. + compatible = "fsl,mxc_sdc_fb";
  8053. + disp_dev = "hdmi";
  8054. + interface_pix_fmt = "RGB24";
  8055. + mode_str ="1920x1080M@60";
  8056. + default_bpp = <24>;
  8057. + int_clk = <0>;
  8058. + late_init = <0>;
  8059. + status = "disabled";
  8060. + };
  8061. +
  8062. + mxcfb3: fb@2 {
  8063. + compatible = "fsl,mxc_sdc_fb";
  8064. + disp_dev = "lcd";
  8065. + interface_pix_fmt = "RGB565";
  8066. + mode_str ="CLAA-WVGA";
  8067. + default_bpp = <16>;
  8068. + int_clk = <0>;
  8069. + late_init = <0>;
  8070. + status = "disabled";
  8071. + };
  8072. +
  8073. + mxcfb4: fb@3 {
  8074. + compatible = "fsl,mxc_sdc_fb";
  8075. + disp_dev = "ldb";
  8076. + interface_pix_fmt = "RGB666";
  8077. + mode_str ="LDB-XGA";
  8078. + default_bpp = <16>;
  8079. + int_clk = <0>;
  8080. + late_init = <0>;
  8081. + status = "disabled";
  8082. + };
  8083. +
  8084. + lcd@0 {
  8085. + compatible = "fsl,lcd";
  8086. + ipu_id = <0>;
  8087. + disp_id = <0>;
  8088. + default_ifmt = "RGB565";
  8089. + pinctrl-names = "default";
  8090. + pinctrl-0 = <&pinctrl_ipu1>;
  8091. + status = "okay";
  8092. + };
  8093. +
  8094. + backlight {
  8095. + compatible = "pwm-backlight";
  8096. + pwms = <&pwm1 0 5000000>;
  8097. + brightness-levels = <0 4 8 16 32 64 128 255>;
  8098. + default-brightness-level = <7>;
  8099. + };
  8100. +
  8101. + v4l2_out {
  8102. + compatible = "fsl,mxc_v4l2_output";
  8103. + status = "okay";
  8104. + };
  8105. +
  8106. + lvds_cabc_ctrl {
  8107. + lvds0-gpios = <&gpio6 15 0>;
  8108. + lvds1-gpios = <&gpio6 16 0>;
  8109. + };
  8110. +
  8111. + mipi_dsi_reset: mipi-dsi-reset {
  8112. + compatible = "gpio-reset";
  8113. + reset-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
  8114. + reset-delay-us = <50>;
  8115. + #reset-cells = <0>;
  8116. + };
  8117. };
  8118. &audmux {
  8119. pinctrl-names = "default";
  8120. - pinctrl-0 = <&pinctrl_audmux_2>;
  8121. + pinctrl-0 = <&pinctrl_audmux>;
  8122. status = "okay";
  8123. };
  8124. @@ -100,7 +231,7 @@
  8125. fsl,spi-num-chipselects = <1>;
  8126. cs-gpios = <&gpio4 9 0>;
  8127. pinctrl-names = "default";
  8128. - pinctrl-0 = <&pinctrl_ecspi1_2>;
  8129. + pinctrl-0 = <&pinctrl_ecspi1>;
  8130. status = "okay";
  8131. flash: m25p80@0 {
  8132. @@ -114,7 +245,7 @@
  8133. &fec {
  8134. pinctrl-names = "default";
  8135. - pinctrl-0 = <&pinctrl_enet_1>;
  8136. + pinctrl-0 = <&pinctrl_enet>;
  8137. phy-mode = "rgmii";
  8138. phy-reset-gpios = <&gpio1 25 0>;
  8139. status = "okay";
  8140. @@ -123,7 +254,7 @@
  8141. &i2c1 {
  8142. clock-frequency = <100000>;
  8143. pinctrl-names = "default";
  8144. - pinctrl-0 = <&pinctrl_i2c1_2>;
  8145. + pinctrl-0 = <&pinctrl_i2c1>;
  8146. status = "okay";
  8147. codec: wm8962@1a {
  8148. @@ -149,10 +280,121 @@
  8149. };
  8150. };
  8151. +&i2c2 {
  8152. + clock-frequency = <100000>;
  8153. + pinctrl-names = "default";
  8154. + pinctrl-0 = <&pinctrl_i2c2>;
  8155. + status = "okay";
  8156. +
  8157. + hdmi: edid@50 {
  8158. + compatible = "fsl,imx6-hdmi-i2c";
  8159. + reg = <0x50>;
  8160. + };
  8161. +
  8162. + pmic: pfuze100@08 {
  8163. + compatible = "fsl,pfuze100";
  8164. + reg = <0x08>;
  8165. +
  8166. + regulators {
  8167. + sw1a_reg: sw1ab {
  8168. + regulator-min-microvolt = <300000>;
  8169. + regulator-max-microvolt = <1875000>;
  8170. + regulator-boot-on;
  8171. + regulator-always-on;
  8172. + regulator-ramp-delay = <6250>;
  8173. + };
  8174. +
  8175. + sw1c_reg: sw1c {
  8176. + regulator-min-microvolt = <300000>;
  8177. + regulator-max-microvolt = <1875000>;
  8178. + regulator-boot-on;
  8179. + regulator-always-on;
  8180. + regulator-ramp-delay = <6250>;
  8181. + };
  8182. +
  8183. + sw2_reg: sw2 {
  8184. + regulator-min-microvolt = <800000>;
  8185. + regulator-max-microvolt = <3300000>;
  8186. + regulator-boot-on;
  8187. + regulator-always-on;
  8188. + };
  8189. +
  8190. + sw3a_reg: sw3a {
  8191. + regulator-min-microvolt = <400000>;
  8192. + regulator-max-microvolt = <1975000>;
  8193. + regulator-boot-on;
  8194. + regulator-always-on;
  8195. + };
  8196. +
  8197. + sw3b_reg: sw3b {
  8198. + regulator-min-microvolt = <400000>;
  8199. + regulator-max-microvolt = <1975000>;
  8200. + regulator-boot-on;
  8201. + regulator-always-on;
  8202. + };
  8203. +
  8204. + sw4_reg: sw4 {
  8205. + regulator-min-microvolt = <800000>;
  8206. + regulator-max-microvolt = <3300000>;
  8207. + };
  8208. +
  8209. + swbst_reg: swbst {
  8210. + regulator-min-microvolt = <5000000>;
  8211. + regulator-max-microvolt = <5150000>;
  8212. + };
  8213. +
  8214. + snvs_reg: vsnvs {
  8215. + regulator-min-microvolt = <1000000>;
  8216. + regulator-max-microvolt = <3000000>;
  8217. + regulator-boot-on;
  8218. + regulator-always-on;
  8219. + };
  8220. +
  8221. + vref_reg: vrefddr {
  8222. + regulator-boot-on;
  8223. + regulator-always-on;
  8224. + };
  8225. +
  8226. + vgen1_reg: vgen1 {
  8227. + regulator-min-microvolt = <800000>;
  8228. + regulator-max-microvolt = <1550000>;
  8229. + };
  8230. +
  8231. + vgen2_reg: vgen2 {
  8232. + regulator-min-microvolt = <800000>;
  8233. + regulator-max-microvolt = <1550000>;
  8234. + };
  8235. +
  8236. + vgen3_reg: vgen3 {
  8237. + regulator-min-microvolt = <1800000>;
  8238. + regulator-max-microvolt = <3300000>;
  8239. + };
  8240. +
  8241. + vgen4_reg: vgen4 {
  8242. + regulator-min-microvolt = <1800000>;
  8243. + regulator-max-microvolt = <3300000>;
  8244. + regulator-always-on;
  8245. + };
  8246. +
  8247. + vgen5_reg: vgen5 {
  8248. + regulator-min-microvolt = <1800000>;
  8249. + regulator-max-microvolt = <3300000>;
  8250. + regulator-always-on;
  8251. + };
  8252. +
  8253. + vgen6_reg: vgen6 {
  8254. + regulator-min-microvolt = <1800000>;
  8255. + regulator-max-microvolt = <3300000>;
  8256. + regulator-always-on;
  8257. + };
  8258. + };
  8259. + };
  8260. +};
  8261. +
  8262. &i2c3 {
  8263. clock-frequency = <100000>;
  8264. pinctrl-names = "default";
  8265. - pinctrl-0 = <&pinctrl_i2c3_2>;
  8266. + pinctrl-0 = <&pinctrl_i2c3>;
  8267. status = "okay";
  8268. egalax_ts@04 {
  8269. @@ -168,11 +410,9 @@
  8270. pinctrl-names = "default";
  8271. pinctrl-0 = <&pinctrl_hog>;
  8272. - hog {
  8273. + imx6qdl-sabresd {
  8274. pinctrl_hog: hoggrp {
  8275. fsl,pins = <
  8276. - MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x80000000
  8277. - MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x80000000
  8278. MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x80000000
  8279. MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x80000000
  8280. MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000
  8281. @@ -182,6 +422,202 @@
  8282. MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
  8283. MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000
  8284. MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
  8285. + MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
  8286. + MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x80000000
  8287. + MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
  8288. + MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
  8289. + >;
  8290. + };
  8291. +
  8292. + pinctrl_audmux: audmuxgrp {
  8293. + fsl,pins = <
  8294. + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
  8295. + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
  8296. + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
  8297. + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
  8298. + >;
  8299. + };
  8300. +
  8301. + pinctrl_ecspi1: ecspi1grp {
  8302. + fsl,pins = <
  8303. + MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1
  8304. + MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1
  8305. + MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1
  8306. + >;
  8307. + };
  8308. +
  8309. + pinctrl_enet: enetgrp {
  8310. + fsl,pins = <
  8311. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  8312. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  8313. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  8314. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  8315. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  8316. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  8317. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  8318. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  8319. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  8320. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  8321. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  8322. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  8323. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  8324. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  8325. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  8326. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  8327. + >;
  8328. + };
  8329. +
  8330. + pinctrl_gpio_keys: gpio_keysgrp {
  8331. + fsl,pins = <
  8332. + MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000
  8333. + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x80000000
  8334. + MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x80000000
  8335. + >;
  8336. + };
  8337. +
  8338. + pinctrl_hdmi_cec: hdmi_cecgrp {
  8339. + fsl,pins = <
  8340. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  8341. + >;
  8342. + };
  8343. +
  8344. + pinctrl_hdmi_hdcp: hdmi_hdcpgrp {
  8345. + fsl,pins = <
  8346. + MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
  8347. + MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
  8348. + >;
  8349. + };
  8350. +
  8351. + pinctrl_i2c1: i2c1grp {
  8352. + fsl,pins = <
  8353. + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
  8354. + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
  8355. + >;
  8356. + };
  8357. +
  8358. + pinctrl_i2c2: i2c2grp {
  8359. + fsl,pins = <
  8360. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  8361. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  8362. + >;
  8363. + };
  8364. +
  8365. + pinctrl_i2c3: i2c3grp {
  8366. + fsl,pins = <
  8367. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  8368. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  8369. + >;
  8370. + };
  8371. +
  8372. + pinctrl_ipu1: ipu1grp {
  8373. + fsl,pins = <
  8374. + MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
  8375. + MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
  8376. + MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
  8377. + MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
  8378. + MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x80000000
  8379. + MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10
  8380. + MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
  8381. + MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
  8382. + MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
  8383. + MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
  8384. + MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
  8385. + MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
  8386. + MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
  8387. + MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
  8388. + MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
  8389. + MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
  8390. + MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
  8391. + MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
  8392. + MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
  8393. + MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
  8394. + MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
  8395. + MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
  8396. + MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
  8397. + MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
  8398. + MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
  8399. + MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
  8400. + MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
  8401. + MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
  8402. + MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
  8403. + >;
  8404. + };
  8405. +
  8406. + pinctrl_pcie: pciegrp {
  8407. + fsl,pins = <
  8408. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000
  8409. + >;
  8410. + };
  8411. +
  8412. + pinctrl_pwm1: pwm1grp {
  8413. + fsl,pins = <
  8414. + MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  8415. + >;
  8416. + };
  8417. +
  8418. + pinctrl_uart1: uart1grp {
  8419. + fsl,pins = <
  8420. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  8421. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  8422. + >;
  8423. + };
  8424. +
  8425. + pinctrl_usbotg: usbotggrp {
  8426. + fsl,pins = <
  8427. + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  8428. + >;
  8429. + };
  8430. +
  8431. + pinctrl_usdhc2: usdhc2grp {
  8432. + fsl,pins = <
  8433. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  8434. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  8435. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  8436. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  8437. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  8438. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  8439. + MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x17059
  8440. + MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x17059
  8441. + MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x17059
  8442. + MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x17059
  8443. + >;
  8444. + };
  8445. +
  8446. + pinctrl_usdhc3: usdhc3grp {
  8447. + fsl,pins = <
  8448. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  8449. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  8450. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  8451. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  8452. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  8453. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  8454. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
  8455. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
  8456. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
  8457. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
  8458. + >;
  8459. + };
  8460. +
  8461. + pinctrl_usdhc4: usdhc4grp {
  8462. + fsl,pins = <
  8463. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  8464. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  8465. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  8466. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  8467. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  8468. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  8469. + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  8470. + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  8471. + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  8472. + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  8473. + >;
  8474. + };
  8475. + };
  8476. +
  8477. + gpio_leds {
  8478. + pinctrl_gpio_leds: gpioledsgrp {
  8479. + fsl,pins = <
  8480. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000
  8481. >;
  8482. };
  8483. };
  8484. @@ -212,9 +648,33 @@
  8485. };
  8486. };
  8487. +&pcie {
  8488. + pinctrl-names = "default";
  8489. + pinctrl-0 = <&pinctrl_pcie>;
  8490. + reset-gpio = <&gpio7 12 0>;
  8491. + status = "okay";
  8492. +};
  8493. +
  8494. +&pcie {
  8495. + power-on-gpio = <&gpio3 19 0>;
  8496. + reset-gpio = <&gpio7 12 0>;
  8497. + status = "okay";
  8498. +};
  8499. +
  8500. +
  8501. &pwm1 {
  8502. pinctrl-names = "default";
  8503. - pinctrl-0 = <&pinctrl_pwm0_1>;
  8504. + pinctrl-0 = <&pinctrl_pwm1>;
  8505. + status = "okay";
  8506. +};
  8507. +
  8508. +&ldb {
  8509. + ipu_id = <1>;
  8510. + disp_id = <1>;
  8511. + ext_ref = <1>;
  8512. + mode = "sep1";
  8513. + sec_ipu_id = <1>;
  8514. + sec_disp_id = <0>;
  8515. status = "okay";
  8516. };
  8517. @@ -225,7 +685,16 @@
  8518. &uart1 {
  8519. pinctrl-names = "default";
  8520. - pinctrl-0 = <&pinctrl_uart1_1>;
  8521. + pinctrl-0 = <&pinctrl_uart1>;
  8522. + status = "okay";
  8523. +};
  8524. +
  8525. +&mipi_dsi {
  8526. + dev_id = <0>;
  8527. + disp_id = <0>;
  8528. + lcd_panel = "TRULY-WVGA";
  8529. + disp-power-on-supply = <&reg_mipi_dsi_pwr_on>;
  8530. + resets = <&mipi_dsi_reset>;
  8531. status = "okay";
  8532. };
  8533. @@ -237,14 +706,14 @@
  8534. &usbotg {
  8535. vbus-supply = <&reg_usb_otg_vbus>;
  8536. pinctrl-names = "default";
  8537. - pinctrl-0 = <&pinctrl_usbotg_2>;
  8538. + pinctrl-0 = <&pinctrl_usbotg>;
  8539. disable-over-current;
  8540. status = "okay";
  8541. };
  8542. &usdhc2 {
  8543. pinctrl-names = "default";
  8544. - pinctrl-0 = <&pinctrl_usdhc2_1>;
  8545. + pinctrl-0 = <&pinctrl_usdhc2>;
  8546. bus-width = <8>;
  8547. cd-gpios = <&gpio2 2 0>;
  8548. wp-gpios = <&gpio2 3 0>;
  8549. @@ -253,9 +722,47 @@
  8550. &usdhc3 {
  8551. pinctrl-names = "default";
  8552. - pinctrl-0 = <&pinctrl_usdhc3_1>;
  8553. + pinctrl-0 = <&pinctrl_usdhc3>;
  8554. bus-width = <8>;
  8555. cd-gpios = <&gpio2 0 0>;
  8556. wp-gpios = <&gpio2 1 0>;
  8557. status = "okay";
  8558. };
  8559. +
  8560. +&usdhc4 {
  8561. + pinctrl-names = "default";
  8562. + pinctrl-0 = <&pinctrl_usdhc4>;
  8563. + bus-width = <8>;
  8564. + non-removable;
  8565. + no-1-8-v;
  8566. + status = "okay";
  8567. +};
  8568. +
  8569. +&hdmi_core {
  8570. + ipu_id = <0>;
  8571. + disp_id = <0>;
  8572. + status = "okay";
  8573. +};
  8574. +
  8575. +&hdmi_video {
  8576. + fsl,phy_reg_vlev = <0x0294>;
  8577. + fsl,phy_reg_cksymtx = <0x800d>;
  8578. + status = "okay";
  8579. +};
  8580. +
  8581. +&hdmi_audio {
  8582. + status = "okay";
  8583. +};
  8584. +
  8585. +&hdmi_cec {
  8586. + pinctrl-names = "default";
  8587. + pinctrl-0 = <&pinctrl_hdmi_cec>;
  8588. + status = "okay";
  8589. +};
  8590. +
  8591. +&gpc {
  8592. + fsl,cpu_pupscr_sw2iso = <0xf>;
  8593. + fsl,cpu_pupscr_sw = <0xf>;
  8594. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  8595. + fsl,cpu_pdnscr_iso = <0x1>;
  8596. +};
  8597. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6qdl-wandboard.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
  8598. --- linux-3.14.15/arch/arm/boot/dts/imx6qdl-wandboard.dtsi 2014-07-31 23:51:43.000000000 +0200
  8599. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6qdl-wandboard.dtsi 2014-08-20 19:31:39.904842290 +0200
  8600. @@ -12,17 +12,21 @@
  8601. / {
  8602. regulators {
  8603. compatible = "simple-bus";
  8604. + #address-cells = <1>;
  8605. + #size-cells = <0>;
  8606. - reg_2p5v: 2p5v {
  8607. + reg_2p5v: regulator@0 {
  8608. compatible = "regulator-fixed";
  8609. + reg = <0>;
  8610. regulator-name = "2P5V";
  8611. regulator-min-microvolt = <2500000>;
  8612. regulator-max-microvolt = <2500000>;
  8613. regulator-always-on;
  8614. };
  8615. - reg_3p3v: 3p3v {
  8616. + reg_3p3v: regulator@1 {
  8617. compatible = "regulator-fixed";
  8618. + reg = <1>;
  8619. regulator-name = "3P3V";
  8620. regulator-min-microvolt = <3300000>;
  8621. regulator-max-microvolt = <3300000>;
  8622. @@ -54,14 +58,14 @@
  8623. &audmux {
  8624. pinctrl-names = "default";
  8625. - pinctrl-0 = <&pinctrl_audmux_2>;
  8626. + pinctrl-0 = <&pinctrl_audmux>;
  8627. status = "okay";
  8628. };
  8629. &i2c2 {
  8630. clock-frequency = <100000>;
  8631. pinctrl-names = "default";
  8632. - pinctrl-0 = <&pinctrl_i2c2_2>;
  8633. + pinctrl-0 = <&pinctrl_i2c2>;
  8634. status = "okay";
  8635. codec: sgtl5000@0a {
  8636. @@ -77,7 +81,7 @@
  8637. pinctrl-names = "default";
  8638. pinctrl-0 = <&pinctrl_hog>;
  8639. - hog {
  8640. + imx6qdl-wandboard {
  8641. pinctrl_hog: hoggrp {
  8642. fsl,pins = <
  8643. MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0
  8644. @@ -91,20 +95,121 @@
  8645. MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000
  8646. >;
  8647. };
  8648. +
  8649. + pinctrl_audmux: audmuxgrp {
  8650. + fsl,pins = <
  8651. + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
  8652. + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
  8653. + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
  8654. + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
  8655. + >;
  8656. + };
  8657. +
  8658. + pinctrl_enet: enetgrp {
  8659. + fsl,pins = <
  8660. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  8661. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  8662. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  8663. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  8664. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  8665. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  8666. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  8667. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  8668. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  8669. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  8670. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  8671. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  8672. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  8673. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  8674. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  8675. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  8676. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  8677. + >;
  8678. + };
  8679. +
  8680. + pinctrl_i2c2: i2c2grp {
  8681. + fsl,pins = <
  8682. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  8683. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  8684. + >;
  8685. + };
  8686. +
  8687. + pinctrl_spdif: spdifgrp {
  8688. + fsl,pins = <
  8689. + MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1b0b0
  8690. + >;
  8691. + };
  8692. +
  8693. + pinctrl_uart1: uart1grp {
  8694. + fsl,pins = <
  8695. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  8696. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  8697. + >;
  8698. + };
  8699. +
  8700. + pinctrl_uart3: uart3grp {
  8701. + fsl,pins = <
  8702. + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  8703. + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  8704. + MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1
  8705. + MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  8706. + >;
  8707. + };
  8708. +
  8709. + pinctrl_usbotg: usbotggrp {
  8710. + fsl,pins = <
  8711. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  8712. + >;
  8713. + };
  8714. +
  8715. + pinctrl_usdhc1: usdhc1grp {
  8716. + fsl,pins = <
  8717. + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  8718. + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  8719. + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  8720. + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  8721. + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  8722. + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  8723. + >;
  8724. + };
  8725. +
  8726. + pinctrl_usdhc2: usdhc2grp {
  8727. + fsl,pins = <
  8728. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  8729. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  8730. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  8731. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  8732. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  8733. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  8734. + >;
  8735. + };
  8736. +
  8737. + pinctrl_usdhc3: usdhc3grp {
  8738. + fsl,pins = <
  8739. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  8740. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  8741. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  8742. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  8743. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  8744. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  8745. + >;
  8746. + };
  8747. };
  8748. };
  8749. &fec {
  8750. pinctrl-names = "default";
  8751. - pinctrl-0 = <&pinctrl_enet_1>;
  8752. + pinctrl-0 = <&pinctrl_enet>;
  8753. phy-mode = "rgmii";
  8754. phy-reset-gpios = <&gpio3 29 0>;
  8755. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  8756. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  8757. status = "okay";
  8758. };
  8759. &spdif {
  8760. pinctrl-names = "default";
  8761. - pinctrl-0 = <&pinctrl_spdif_3>;
  8762. + pinctrl-0 = <&pinctrl_spdif>;
  8763. status = "okay";
  8764. };
  8765. @@ -115,13 +220,13 @@
  8766. &uart1 {
  8767. pinctrl-names = "default";
  8768. - pinctrl-0 = <&pinctrl_uart1_1>;
  8769. + pinctrl-0 = <&pinctrl_uart1>;
  8770. status = "okay";
  8771. };
  8772. &uart3 {
  8773. pinctrl-names = "default";
  8774. - pinctrl-0 = <&pinctrl_uart3_2>;
  8775. + pinctrl-0 = <&pinctrl_uart3>;
  8776. fsl,uart-has-rtscts;
  8777. status = "okay";
  8778. };
  8779. @@ -132,7 +237,7 @@
  8780. &usbotg {
  8781. pinctrl-names = "default";
  8782. - pinctrl-0 = <&pinctrl_usbotg_1>;
  8783. + pinctrl-0 = <&pinctrl_usbotg>;
  8784. disable-over-current;
  8785. dr_mode = "peripheral";
  8786. status = "okay";
  8787. @@ -140,21 +245,21 @@
  8788. &usdhc1 {
  8789. pinctrl-names = "default";
  8790. - pinctrl-0 = <&pinctrl_usdhc1_2>;
  8791. + pinctrl-0 = <&pinctrl_usdhc1>;
  8792. cd-gpios = <&gpio1 2 0>;
  8793. status = "okay";
  8794. };
  8795. &usdhc2 {
  8796. pinctrl-names = "default";
  8797. - pinctrl-0 = <&pinctrl_usdhc2_2>;
  8798. + pinctrl-0 = <&pinctrl_usdhc2>;
  8799. non-removable;
  8800. status = "okay";
  8801. };
  8802. &usdhc3 {
  8803. pinctrl-names = "default";
  8804. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  8805. + pinctrl-0 = <&pinctrl_usdhc3>;
  8806. cd-gpios = <&gpio3 9 0>;
  8807. status = "okay";
  8808. };
  8809. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
  8810. --- linux-3.14.15/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts 1970-01-01 01:00:00.000000000 +0100
  8811. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts 2014-08-20 19:31:39.900842271 +0200
  8812. @@ -0,0 +1,432 @@
  8813. +/*
  8814. + * Copyright 2013 Data Modul AG
  8815. + *
  8816. + * The code contained herein is licensed under the GNU General Public
  8817. + * License. You may obtain a copy of the GNU General Public License
  8818. + * Version 2 or later at the following locations:
  8819. + *
  8820. + * http://www.opensource.org/licenses/gpl-license.html
  8821. + * http://www.gnu.org/copyleft/gpl.html
  8822. + */
  8823. +
  8824. +/dts-v1/;
  8825. +
  8826. +#include <dt-bindings/gpio/gpio.h>
  8827. +#include "imx6q.dtsi"
  8828. +
  8829. +/ {
  8830. + model = "Data Modul eDM-QMX6 Board";
  8831. + compatible = "dmo,imx6q-edmqmx6", "fsl,imx6q";
  8832. +
  8833. + chosen {
  8834. + stdout-path = &uart2;
  8835. + };
  8836. +
  8837. + aliases {
  8838. + gpio7 = &stmpe_gpio1;
  8839. + gpio8 = &stmpe_gpio2;
  8840. + stmpe-i2c0 = &stmpe1;
  8841. + stmpe-i2c1 = &stmpe2;
  8842. + };
  8843. +
  8844. + memory {
  8845. + reg = <0x10000000 0x80000000>;
  8846. + };
  8847. +
  8848. + regulators {
  8849. + compatible = "simple-bus";
  8850. + #address-cells = <1>;
  8851. + #size-cells = <0>;
  8852. +
  8853. + reg_3p3v: regulator@0 {
  8854. + compatible = "regulator-fixed";
  8855. + reg = <0>;
  8856. + regulator-name = "3P3V";
  8857. + regulator-min-microvolt = <3300000>;
  8858. + regulator-max-microvolt = <3300000>;
  8859. + regulator-always-on;
  8860. + };
  8861. +
  8862. + reg_usb_otg_switch: regulator@1 {
  8863. + compatible = "regulator-fixed";
  8864. + reg = <1>;
  8865. + regulator-name = "usb_otg_switch";
  8866. + regulator-min-microvolt = <5000000>;
  8867. + regulator-max-microvolt = <5000000>;
  8868. + gpio = <&gpio7 12 0>;
  8869. + regulator-boot-on;
  8870. + regulator-always-on;
  8871. + };
  8872. +
  8873. + reg_usb_host1: regulator@2 {
  8874. + compatible = "regulator-fixed";
  8875. + reg = <2>;
  8876. + regulator-name = "usb_host1_en";
  8877. + regulator-min-microvolt = <3300000>;
  8878. + regulator-max-microvolt = <3300000>;
  8879. + gpio = <&gpio3 31 0>;
  8880. + enable-active-high;
  8881. + };
  8882. + };
  8883. +
  8884. + gpio-leds {
  8885. + compatible = "gpio-leds";
  8886. +
  8887. + led-blue {
  8888. + label = "blue";
  8889. + gpios = <&stmpe_gpio1 8 GPIO_ACTIVE_HIGH>;
  8890. + linux,default-trigger = "heartbeat";
  8891. + };
  8892. +
  8893. + led-green {
  8894. + label = "green";
  8895. + gpios = <&stmpe_gpio1 9 GPIO_ACTIVE_HIGH>;
  8896. + };
  8897. +
  8898. + led-pink {
  8899. + label = "pink";
  8900. + gpios = <&stmpe_gpio1 10 GPIO_ACTIVE_HIGH>;
  8901. + };
  8902. +
  8903. + led-red {
  8904. + label = "red";
  8905. + gpios = <&stmpe_gpio1 11 GPIO_ACTIVE_HIGH>;
  8906. + };
  8907. + };
  8908. +};
  8909. +
  8910. +&ecspi5 {
  8911. + pinctrl-names = "default";
  8912. + pinctrl-0 = <&pinctrl_ecspi5>;
  8913. + fsl,spi-num-chipselects = <1>;
  8914. + cs-gpios = <&gpio1 12 0>;
  8915. + status = "okay";
  8916. +
  8917. + flash: m25p80@0 {
  8918. + compatible = "m25p80";
  8919. + spi-max-frequency = <40000000>;
  8920. + reg = <0>;
  8921. + };
  8922. +};
  8923. +
  8924. +&fec {
  8925. + pinctrl-names = "default";
  8926. + pinctrl-0 = <&pinctrl_enet>;
  8927. + phy-mode = "rgmii";
  8928. + phy-reset-gpios = <&gpio3 23 0>;
  8929. + phy-supply = <&vgen2_1v2_eth>;
  8930. + status = "okay";
  8931. +};
  8932. +
  8933. +&i2c2 {
  8934. + clock-frequency = <100000>;
  8935. + pinctrl-names = "default";
  8936. + pinctrl-0 = <&pinctrl_i2c2
  8937. + &pinctrl_stmpe1
  8938. + &pinctrl_stmpe2
  8939. + &pinctrl_pfuze>;
  8940. + status = "okay";
  8941. +
  8942. + pmic: pfuze100@08 {
  8943. + compatible = "fsl,pfuze100";
  8944. + reg = <0x08>;
  8945. + interrupt-parent = <&gpio3>;
  8946. + interrupts = <20 8>;
  8947. +
  8948. + regulators {
  8949. + sw1a_reg: sw1ab {
  8950. + regulator-min-microvolt = <300000>;
  8951. + regulator-max-microvolt = <1875000>;
  8952. + regulator-boot-on;
  8953. + regulator-always-on;
  8954. + };
  8955. +
  8956. + sw1c_reg: sw1c {
  8957. + regulator-min-microvolt = <300000>;
  8958. + regulator-max-microvolt = <1875000>;
  8959. + regulator-boot-on;
  8960. + regulator-always-on;
  8961. + };
  8962. +
  8963. + sw2_reg: sw2 {
  8964. + regulator-min-microvolt = <800000>;
  8965. + regulator-max-microvolt = <3300000>;
  8966. + regulator-boot-on;
  8967. + regulator-always-on;
  8968. + };
  8969. +
  8970. + sw3a_reg: sw3a {
  8971. + regulator-min-microvolt = <400000>;
  8972. + regulator-max-microvolt = <1975000>;
  8973. + regulator-boot-on;
  8974. + regulator-always-on;
  8975. + };
  8976. +
  8977. + sw3b_reg: sw3b {
  8978. + regulator-min-microvolt = <400000>;
  8979. + regulator-max-microvolt = <1975000>;
  8980. + regulator-boot-on;
  8981. + regulator-always-on;
  8982. + };
  8983. +
  8984. + sw4_reg: sw4 {
  8985. + regulator-min-microvolt = <400000>;
  8986. + regulator-max-microvolt = <1975000>;
  8987. + regulator-always-on;
  8988. + };
  8989. +
  8990. + swbst_reg: swbst {
  8991. + regulator-min-microvolt = <5000000>;
  8992. + regulator-max-microvolt = <5150000>;
  8993. + regulator-always-on;
  8994. + };
  8995. +
  8996. + snvs_reg: vsnvs {
  8997. + regulator-min-microvolt = <1000000>;
  8998. + regulator-max-microvolt = <3000000>;
  8999. + regulator-boot-on;
  9000. + regulator-always-on;
  9001. + };
  9002. +
  9003. + vref_reg: vrefddr {
  9004. + regulator-boot-on;
  9005. + regulator-always-on;
  9006. + };
  9007. +
  9008. + vgen1_reg: vgen1 {
  9009. + regulator-min-microvolt = <800000>;
  9010. + regulator-max-microvolt = <1550000>;
  9011. + };
  9012. +
  9013. + vgen2_1v2_eth: vgen2 {
  9014. + regulator-min-microvolt = <800000>;
  9015. + regulator-max-microvolt = <1550000>;
  9016. + };
  9017. +
  9018. + vdd_high_in: vgen3 {
  9019. + regulator-min-microvolt = <1800000>;
  9020. + regulator-max-microvolt = <3300000>;
  9021. + regulator-boot-on;
  9022. + regulator-always-on;
  9023. + };
  9024. +
  9025. + vgen4_reg: vgen4 {
  9026. + regulator-min-microvolt = <1800000>;
  9027. + regulator-max-microvolt = <3300000>;
  9028. + regulator-always-on;
  9029. + };
  9030. +
  9031. + vgen5_reg: vgen5 {
  9032. + regulator-min-microvolt = <1800000>;
  9033. + regulator-max-microvolt = <3300000>;
  9034. + regulator-always-on;
  9035. + };
  9036. +
  9037. + vgen6_reg: vgen6 {
  9038. + regulator-min-microvolt = <1800000>;
  9039. + regulator-max-microvolt = <3300000>;
  9040. + regulator-always-on;
  9041. + };
  9042. + };
  9043. + };
  9044. +
  9045. + stmpe1: stmpe1601@40 {
  9046. + compatible = "st,stmpe1601";
  9047. + reg = <0x40>;
  9048. + interrupts = <30 0>;
  9049. + interrupt-parent = <&gpio3>;
  9050. + vcc-supply = <&sw2_reg>;
  9051. + vio-supply = <&sw2_reg>;
  9052. +
  9053. + stmpe_gpio1: stmpe_gpio {
  9054. + #gpio-cells = <2>;
  9055. + compatible = "st,stmpe-gpio";
  9056. + };
  9057. + };
  9058. +
  9059. + stmpe2: stmpe1601@44 {
  9060. + compatible = "st,stmpe1601";
  9061. + reg = <0x44>;
  9062. + interrupts = <2 0>;
  9063. + interrupt-parent = <&gpio5>;
  9064. + vcc-supply = <&sw2_reg>;
  9065. + vio-supply = <&sw2_reg>;
  9066. +
  9067. + stmpe_gpio2: stmpe_gpio {
  9068. + #gpio-cells = <2>;
  9069. + compatible = "st,stmpe-gpio";
  9070. + };
  9071. + };
  9072. +
  9073. + temp1: ad7414@4c {
  9074. + compatible = "ad,ad7414";
  9075. + reg = <0x4c>;
  9076. + };
  9077. +
  9078. + temp2: ad7414@4d {
  9079. + compatible = "ad,ad7414";
  9080. + reg = <0x4d>;
  9081. + };
  9082. +
  9083. + rtc: m41t62@68 {
  9084. + compatible = "stm,m41t62";
  9085. + reg = <0x68>;
  9086. + };
  9087. +};
  9088. +
  9089. +&iomuxc {
  9090. + pinctrl-names = "default";
  9091. + pinctrl-0 = <&pinctrl_hog>;
  9092. +
  9093. + imx6q-dmo-edmqmx6 {
  9094. + pinctrl_hog: hoggrp {
  9095. + fsl,pins = <
  9096. + MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x80000000
  9097. + MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x80000000
  9098. + >;
  9099. + };
  9100. +
  9101. + pinctrl_ecspi5: ecspi5rp-1 {
  9102. + fsl,pins = <
  9103. + MX6QDL_PAD_SD1_DAT0__ECSPI5_MISO 0x80000000
  9104. + MX6QDL_PAD_SD1_CMD__ECSPI5_MOSI 0x80000000
  9105. + MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK 0x80000000
  9106. + MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x80000000
  9107. + >;
  9108. + };
  9109. +
  9110. + pinctrl_enet: enetgrp {
  9111. + fsl,pins = <
  9112. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  9113. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  9114. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  9115. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  9116. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  9117. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  9118. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  9119. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  9120. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  9121. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  9122. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  9123. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  9124. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  9125. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  9126. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  9127. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  9128. + >;
  9129. + };
  9130. +
  9131. + pinctrl_i2c2: i2c2grp {
  9132. + fsl,pins = <
  9133. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  9134. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  9135. + >;
  9136. + };
  9137. +
  9138. + pinctrl_pfuze: pfuze100grp1 {
  9139. + fsl,pins = <
  9140. + MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x80000000
  9141. + >;
  9142. + };
  9143. +
  9144. + pinctrl_stmpe1: stmpe1grp {
  9145. + fsl,pins = <MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x80000000>;
  9146. + };
  9147. +
  9148. + pinctrl_stmpe2: stmpe2grp {
  9149. + fsl,pins = <MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x80000000>;
  9150. + };
  9151. +
  9152. + pinctrl_uart1: uart1grp {
  9153. + fsl,pins = <
  9154. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  9155. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  9156. + >;
  9157. + };
  9158. +
  9159. + pinctrl_uart2: uart2grp {
  9160. + fsl,pins = <
  9161. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  9162. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  9163. + >;
  9164. + };
  9165. +
  9166. + pinctrl_usbotg: usbotggrp {
  9167. + fsl,pins = <
  9168. + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  9169. + >;
  9170. + };
  9171. +
  9172. + pinctrl_usdhc3: usdhc3grp {
  9173. + fsl,pins = <
  9174. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  9175. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  9176. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  9177. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  9178. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  9179. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  9180. + >;
  9181. + };
  9182. +
  9183. + pinctrl_usdhc4: usdhc4grp {
  9184. + fsl,pins = <
  9185. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  9186. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  9187. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  9188. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  9189. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  9190. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  9191. + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  9192. + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  9193. + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  9194. + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  9195. + >;
  9196. + };
  9197. + };
  9198. +};
  9199. +
  9200. +&sata {
  9201. + status = "okay";
  9202. +};
  9203. +
  9204. +&uart1 {
  9205. + pinctrl-names = "default";
  9206. + pinctrl-0 = <&pinctrl_uart1>;
  9207. + status = "okay";
  9208. +};
  9209. +
  9210. +&uart2 {
  9211. + pinctrl-names = "default";
  9212. + pinctrl-0 = <&pinctrl_uart2>;
  9213. + status = "okay";
  9214. +};
  9215. +
  9216. +&usbh1 {
  9217. + vbus-supply = <&reg_usb_host1>;
  9218. + disable-over-current;
  9219. + dr_mode = "host";
  9220. + status = "okay";
  9221. +};
  9222. +
  9223. +&usbotg {
  9224. + pinctrl-names = "default";
  9225. + pinctrl-0 = <&pinctrl_usbotg>;
  9226. + disable-over-current;
  9227. + status = "okay";
  9228. +};
  9229. +
  9230. +&usdhc3 {
  9231. + pinctrl-names = "default";
  9232. + pinctrl-0 = <&pinctrl_usdhc3>;
  9233. + vmmc-supply = <&reg_3p3v>;
  9234. + status = "okay";
  9235. +};
  9236. +
  9237. +&usdhc4 {
  9238. + pinctrl-names = "default";
  9239. + pinctrl-0 = <&pinctrl_usdhc4>;
  9240. + vmmc-supply = <&reg_3p3v>;
  9241. + non-removable;
  9242. + bus-width = <8>;
  9243. + status = "okay";
  9244. +};
  9245. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q.dtsi
  9246. --- linux-3.14.15/arch/arm/boot/dts/imx6q.dtsi 2014-07-31 23:51:43.000000000 +0200
  9247. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q.dtsi 2014-08-20 19:31:39.900842271 +0200
  9248. @@ -8,10 +8,16 @@
  9249. *
  9250. */
  9251. +#include <dt-bindings/interrupt-controller/irq.h>
  9252. #include "imx6q-pinfunc.h"
  9253. #include "imx6qdl.dtsi"
  9254. / {
  9255. + aliases {
  9256. + ipu1 = &ipu2;
  9257. + spi4 = &ecspi5;
  9258. + };
  9259. +
  9260. cpus {
  9261. #address-cells = <1>;
  9262. #size-cells = <0>;
  9263. @@ -25,8 +31,17 @@
  9264. /* kHz uV */
  9265. 1200000 1275000
  9266. 996000 1250000
  9267. + 852000 1250000
  9268. 792000 1150000
  9269. - 396000 950000
  9270. + 396000 975000
  9271. + >;
  9272. + fsl,soc-operating-points = <
  9273. + /* ARM kHz SOC-PU uV */
  9274. + 1200000 1275000
  9275. + 996000 1250000
  9276. + 852000 1250000
  9277. + 792000 1175000
  9278. + 396000 1175000
  9279. >;
  9280. clock-latency = <61036>; /* two CLK32 periods */
  9281. clocks = <&clks 104>, <&clks 6>, <&clks 16>,
  9282. @@ -61,12 +76,77 @@
  9283. };
  9284. soc {
  9285. +
  9286. + busfreq { /* BUSFREQ */
  9287. + compatible = "fsl,imx6_busfreq";
  9288. + clocks = <&clks 171>, <&clks 6>, <&clks 11>, <&clks 104>, <&clks 172>, <&clks 58>,
  9289. + <&clks 18>, <&clks 60>, <&clks 20>, <&clks 3>;
  9290. + clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
  9291. + "periph_pre", "periph_clk2", "periph_clk2_sel", "osc";
  9292. + interrupts = <0 107 0x04>, <0 112 0x4>, <0 113 0x4>, <0 114 0x4>;
  9293. + interrupt-names = "irq_busfreq_0", "irq_busfreq_1", "irq_busfreq_2", "irq_busfreq_3";
  9294. + fsl,max_ddr_freq = <528000000>;
  9295. + };
  9296. +
  9297. + gpu@00130000 {
  9298. + compatible = "fsl,imx6q-gpu";
  9299. + reg = <0x00130000 0x4000>, <0x00134000 0x4000>,
  9300. + <0x02204000 0x4000>, <0x0 0x0>;
  9301. + reg-names = "iobase_3d", "iobase_2d",
  9302. + "iobase_vg", "phys_baseaddr";
  9303. + interrupts = <0 9 0x04>, <0 10 0x04>,<0 11 0x04>;
  9304. + interrupt-names = "irq_3d", "irq_2d", "irq_vg";
  9305. + clocks = <&clks 26>, <&clks 143>,
  9306. + <&clks 27>, <&clks 121>,
  9307. + <&clks 122>, <&clks 74>;
  9308. + clock-names = "gpu2d_axi_clk", "openvg_axi_clk",
  9309. + "gpu3d_axi_clk", "gpu2d_clk",
  9310. + "gpu3d_clk", "gpu3d_shader_clk";
  9311. + resets = <&src 0>, <&src 3>, <&src 3>;
  9312. + reset-names = "gpu3d", "gpu2d", "gpuvg";
  9313. + pu-supply = <&reg_pu>;
  9314. + };
  9315. +
  9316. ocram: sram@00900000 {
  9317. compatible = "mmio-sram";
  9318. reg = <0x00900000 0x40000>;
  9319. clocks = <&clks 142>;
  9320. };
  9321. + hdmi_core: hdmi_core@00120000 {
  9322. + compatible = "fsl,imx6q-hdmi-core";
  9323. + reg = <0x00120000 0x9000>;
  9324. + clocks = <&clks 124>, <&clks 123>;
  9325. + clock-names = "hdmi_isfr", "hdmi_iahb";
  9326. + status = "disabled";
  9327. + };
  9328. +
  9329. + hdmi_video: hdmi_video@020e0000 {
  9330. + compatible = "fsl,imx6q-hdmi-video";
  9331. + reg = <0x020e0000 0x1000>;
  9332. + reg-names = "hdmi_gpr";
  9333. + interrupts = <0 115 0x04>;
  9334. + clocks = <&clks 124>, <&clks 123>;
  9335. + clock-names = "hdmi_isfr", "hdmi_iahb";
  9336. + status = "disabled";
  9337. + };
  9338. +
  9339. + hdmi_audio: hdmi_audio@00120000 {
  9340. + compatible = "fsl,imx6q-hdmi-audio";
  9341. + clocks = <&clks 124>, <&clks 123>;
  9342. + clock-names = "hdmi_isfr", "hdmi_iahb";
  9343. + dmas = <&sdma 2 23 0>;
  9344. + dma-names = "tx";
  9345. + status = "disabled";
  9346. + };
  9347. +
  9348. + hdmi_cec: hdmi_cec@00120000 {
  9349. + compatible = "fsl,imx6q-hdmi-cec";
  9350. + interrupts = <0 115 0x04>;
  9351. + status = "disabled";
  9352. + };
  9353. +
  9354. +
  9355. aips-bus@02000000 { /* AIPS1 */
  9356. spba-bus@02000000 {
  9357. ecspi5: ecspi@02018000 {
  9358. @@ -74,13 +154,17 @@
  9359. #size-cells = <0>;
  9360. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  9361. reg = <0x02018000 0x4000>;
  9362. - interrupts = <0 35 0x04>;
  9363. + interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
  9364. clocks = <&clks 116>, <&clks 116>;
  9365. clock-names = "ipg", "per";
  9366. status = "disabled";
  9367. };
  9368. };
  9369. + vpu@02040000 {
  9370. + status = "okay";
  9371. + };
  9372. +
  9373. iomuxc: iomuxc@020e0000 {
  9374. compatible = "fsl,imx6q-iomuxc";
  9375. @@ -122,40 +206,40 @@
  9376. };
  9377. };
  9378. + aips-bus@02100000 { /* AIPS2 */
  9379. + mipi_dsi: mipi@021e0000 {
  9380. + compatible = "fsl,imx6q-mipi-dsi";
  9381. + reg = <0x021e0000 0x4000>;
  9382. + interrupts = <0 102 0x04>;
  9383. + gpr = <&gpr>;
  9384. + clocks = <&clks 138>, <&clks 209>;
  9385. + clock-names = "mipi_pllref_clk", "mipi_cfg_clk";
  9386. + status = "disabled";
  9387. + };
  9388. + };
  9389. +
  9390. sata: sata@02200000 {
  9391. compatible = "fsl,imx6q-ahci";
  9392. reg = <0x02200000 0x4000>;
  9393. - interrupts = <0 39 0x04>;
  9394. + interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
  9395. clocks = <&clks 154>, <&clks 187>, <&clks 105>;
  9396. clock-names = "sata", "sata_ref", "ahb";
  9397. status = "disabled";
  9398. };
  9399. ipu2: ipu@02800000 {
  9400. - #crtc-cells = <1>;
  9401. compatible = "fsl,imx6q-ipu";
  9402. reg = <0x02800000 0x400000>;
  9403. - interrupts = <0 8 0x4 0 7 0x4>;
  9404. - clocks = <&clks 133>, <&clks 134>, <&clks 137>;
  9405. - clock-names = "bus", "di0", "di1";
  9406. + interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>,
  9407. + <0 7 IRQ_TYPE_LEVEL_HIGH>;
  9408. + clocks = <&clks 133>, <&clks 134>, <&clks 137>,
  9409. + <&clks 41>, <&clks 42>,
  9410. + <&clks 135>, <&clks 136>;
  9411. + clock-names = "bus", "di0", "di1",
  9412. + "di0_sel", "di1_sel",
  9413. + "ldb_di0", "ldb_di1";
  9414. resets = <&src 4>;
  9415. + bypass_reset = <0>;
  9416. };
  9417. };
  9418. };
  9419. -
  9420. -&ldb {
  9421. - clocks = <&clks 33>, <&clks 34>,
  9422. - <&clks 39>, <&clks 40>, <&clks 41>, <&clks 42>,
  9423. - <&clks 135>, <&clks 136>;
  9424. - clock-names = "di0_pll", "di1_pll",
  9425. - "di0_sel", "di1_sel", "di2_sel", "di3_sel",
  9426. - "di0", "di1";
  9427. -
  9428. - lvds-channel@0 {
  9429. - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
  9430. - };
  9431. -
  9432. - lvds-channel@1 {
  9433. - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
  9434. - };
  9435. -};
  9436. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-gk802.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gk802.dts
  9437. --- linux-3.14.15/arch/arm/boot/dts/imx6q-gk802.dts 1970-01-01 01:00:00.000000000 +0100
  9438. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gk802.dts 2014-08-20 19:31:39.900842271 +0200
  9439. @@ -0,0 +1,229 @@
  9440. +/*
  9441. + * Copyright (C) 2013 Philipp Zabel
  9442. + *
  9443. + * This file is licensed under the terms of the GNU General Public License
  9444. + * version 2. This program is licensed "as is" without any warranty of any
  9445. + * kind, whether express or implied.
  9446. + */
  9447. +
  9448. +/dts-v1/;
  9449. +#include "imx6q.dtsi"
  9450. +
  9451. +/ {
  9452. + model = "Zealz GK802";
  9453. + compatible = "zealz,imx6q-gk802", "fsl,imx6q";
  9454. +
  9455. + aliases {
  9456. + mxcfb0 = &mxcfb1;
  9457. + };
  9458. +
  9459. + chosen {
  9460. + stdout-path = &uart4;
  9461. + };
  9462. +
  9463. + memory {
  9464. + reg = <0x10000000 0x40000000>;
  9465. + };
  9466. +
  9467. + regulators {
  9468. + compatible = "simple-bus";
  9469. + #address-cells = <1>;
  9470. + #size-cells = <0>;
  9471. +
  9472. + reg_3p3v: regulator@0 {
  9473. + compatible = "regulator-fixed";
  9474. + reg = <0>;
  9475. + regulator-name = "3P3V";
  9476. + regulator-min-microvolt = <3300000>;
  9477. + regulator-max-microvolt = <3300000>;
  9478. + regulator-always-on;
  9479. + };
  9480. +
  9481. + reg_usb_h1_vbus: usb_h1_vbus {
  9482. + compatible = "regulator-fixed";
  9483. + regulator-name = "usb_h1_vbus";
  9484. + regulator-min-microvolt = <5000000>;
  9485. + regulator-max-microvolt = <5000000>;
  9486. + gpio = <&gpio2 0 0>;
  9487. + };
  9488. + };
  9489. +
  9490. + gpio-keys {
  9491. + compatible = "gpio-keys";
  9492. +
  9493. + recovery-button {
  9494. + label = "recovery";
  9495. + gpios = <&gpio3 16 1>;
  9496. + linux,code = <0x198>; /* KEY_RESTART */
  9497. + gpio-key,wakeup;
  9498. + };
  9499. +
  9500. + };
  9501. +
  9502. + sound-hdmi {
  9503. + compatible = "fsl,imx6q-audio-hdmi",
  9504. + "fsl,imx-audio-hdmi";
  9505. + model = "imx-audio-hdmi";
  9506. + hdmi-controller = <&hdmi_audio>;
  9507. + };
  9508. +
  9509. + mxcfb1: fb@0 {
  9510. + compatible = "fsl,mxc_sdc_fb";
  9511. + disp_dev = "hdmi";
  9512. + interface_pix_fmt = "RGB24";
  9513. + mode_str ="1920x1080M@60";
  9514. + default_bpp = <32>;
  9515. + int_clk = <0>;
  9516. + late_init = <0>;
  9517. + status = "okay";
  9518. + };
  9519. +};
  9520. +
  9521. +&hdmi_core {
  9522. + ipu_id = <0>;
  9523. + disp_id = <0>;
  9524. + status = "okay";
  9525. +};
  9526. +
  9527. +&hdmi_video {
  9528. + fsl,phy_reg_vlev = <0x0294>;
  9529. + fsl,phy_reg_cksymtx = <0x800d>;
  9530. + status = "okay";
  9531. +};
  9532. +
  9533. +&hdmi_audio {
  9534. + status = "okay";
  9535. +};
  9536. +
  9537. +
  9538. +/* Internal I2C */
  9539. +&i2c2 {
  9540. + pinctrl-names = "default";
  9541. + pinctrl-0 = <&pinctrl_i2c2>;
  9542. + clock-frequency = <100000>;
  9543. + status = "okay";
  9544. +
  9545. + /* SDMC DM2016 1024 bit EEPROM + 128 bit OTP */
  9546. + eeprom: dm2016@51 {
  9547. + compatible = "sdmc,dm2016";
  9548. + reg = <0x51>;
  9549. + };
  9550. +};
  9551. +
  9552. +/* External I2C via HDMI */
  9553. +&i2c3 {
  9554. + pinctrl-names = "default";
  9555. + pinctrl-0 = <&pinctrl_i2c3>;
  9556. + clock-frequency = <100000>;
  9557. + status = "okay";
  9558. +
  9559. + ddc: imx6_hdmi_i2c@50 {
  9560. + compatible = "fsl,imx6-hdmi-i2c";
  9561. + reg = <0x50>;
  9562. + };
  9563. +};
  9564. +
  9565. +&iomuxc {
  9566. + pinctrl-names = "default";
  9567. + pinctrl-0 = <&pinctrl_hog>;
  9568. +
  9569. + imx6q-gk802 {
  9570. + pinctrl_hog: hoggrp {
  9571. + fsl,pins = <
  9572. + /* Recovery button, active-low */
  9573. + MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x100b1
  9574. + /* RTL8192CU enable GPIO, active-low */
  9575. + MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
  9576. + >;
  9577. + };
  9578. +
  9579. + pinctrl_i2c2: i2c2grp {
  9580. + fsl,pins = <
  9581. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  9582. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  9583. + >;
  9584. + };
  9585. +
  9586. + pinctrl_i2c3: i2c3grp {
  9587. + fsl,pins = <
  9588. + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
  9589. + MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
  9590. + >;
  9591. + };
  9592. +
  9593. + pinctrl_uart4: uart4grp {
  9594. + fsl,pins = <
  9595. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  9596. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  9597. + >;
  9598. + };
  9599. +
  9600. + pinctrl_usdhc3: usdhc3grp {
  9601. + fsl,pins = <
  9602. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  9603. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  9604. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  9605. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  9606. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  9607. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  9608. + >;
  9609. + };
  9610. +
  9611. + pinctrl_usdhc4: usdhc4grp {
  9612. + fsl,pins = <
  9613. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  9614. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  9615. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  9616. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  9617. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  9618. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  9619. + >;
  9620. + };
  9621. + };
  9622. +};
  9623. +
  9624. +&uart2 {
  9625. + status = "okay";
  9626. +};
  9627. +
  9628. +&uart4 {
  9629. + pinctrl-names = "default";
  9630. + pinctrl-0 = <&pinctrl_uart4>;
  9631. + status = "okay";
  9632. +};
  9633. +
  9634. +/* External USB-A port (USBOTG) */
  9635. +&usbotg {
  9636. + phy_type = "utmi";
  9637. + dr_mode = "host";
  9638. + disable-over-current;
  9639. + status = "okay";
  9640. +};
  9641. +
  9642. +/* Internal USB port (USBH1), connected to RTL8192CU */
  9643. +&usbh1 {
  9644. + phy_type = "utmi";
  9645. + dr_mode = "host";
  9646. + vbus-supply = <&reg_usb_h1_vbus>;
  9647. + disable-over-current;
  9648. + status = "okay";
  9649. +};
  9650. +
  9651. +/* External microSD */
  9652. +&usdhc3 {
  9653. + pinctrl-names = "default";
  9654. + pinctrl-0 = <&pinctrl_usdhc3>;
  9655. + bus-width = <4>;
  9656. + cd-gpios = <&gpio6 11 0>;
  9657. + vmmc-supply = <&reg_3p3v>;
  9658. + status = "okay";
  9659. +};
  9660. +
  9661. +/* Internal microSD */
  9662. +&usdhc4 {
  9663. + pinctrl-names = "default";
  9664. + pinctrl-0 = <&pinctrl_usdhc4>;
  9665. + bus-width = <4>;
  9666. + vmmc-supply = <&reg_3p3v>;
  9667. + status = "okay";
  9668. +};
  9669. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-gw51xx.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gw51xx.dts
  9670. --- linux-3.14.15/arch/arm/boot/dts/imx6q-gw51xx.dts 1970-01-01 01:00:00.000000000 +0100
  9671. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gw51xx.dts 2014-08-20 19:31:39.900842271 +0200
  9672. @@ -0,0 +1,19 @@
  9673. +/*
  9674. + * Copyright 2013 Gateworks Corporation
  9675. + *
  9676. + * The code contained herein is licensed under the GNU General Public
  9677. + * License. You may obtain a copy of the GNU General Public License
  9678. + * Version 2 or later at the following locations:
  9679. + *
  9680. + * http://www.opensource.org/licenses/gpl-license.html
  9681. + * http://www.gnu.org/copyleft/gpl.html
  9682. + */
  9683. +
  9684. +/dts-v1/;
  9685. +#include "imx6q.dtsi"
  9686. +#include "imx6qdl-gw54xx.dtsi"
  9687. +
  9688. +/ {
  9689. + model = "Gateworks Ventana i.MX6 Quad GW51XX";
  9690. + compatible = "gw,imx6q-gw51xx", "gw,ventana", "fsl,imx6q";
  9691. +};
  9692. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-gw52xx.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gw52xx.dts
  9693. --- linux-3.14.15/arch/arm/boot/dts/imx6q-gw52xx.dts 1970-01-01 01:00:00.000000000 +0100
  9694. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gw52xx.dts 2014-08-20 19:31:39.900842271 +0200
  9695. @@ -0,0 +1,23 @@
  9696. +/*
  9697. + * Copyright 2013 Gateworks Corporation
  9698. + *
  9699. + * The code contained herein is licensed under the GNU General Public
  9700. + * License. You may obtain a copy of the GNU General Public License
  9701. + * Version 2 or later at the following locations:
  9702. + *
  9703. + * http://www.opensource.org/licenses/gpl-license.html
  9704. + * http://www.gnu.org/copyleft/gpl.html
  9705. + */
  9706. +
  9707. +/dts-v1/;
  9708. +#include "imx6q.dtsi"
  9709. +#include "imx6qdl-gw52xx.dtsi"
  9710. +
  9711. +/ {
  9712. + model = "Gateworks Ventana i.MX6 Quad GW52XX";
  9713. + compatible = "gw,imx6q-gw52xx", "gw,ventana", "fsl,imx6q";
  9714. +};
  9715. +
  9716. +&sata {
  9717. + status = "okay";
  9718. +};
  9719. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-gw53xx.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gw53xx.dts
  9720. --- linux-3.14.15/arch/arm/boot/dts/imx6q-gw53xx.dts 1970-01-01 01:00:00.000000000 +0100
  9721. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gw53xx.dts 2014-08-20 19:31:39.900842271 +0200
  9722. @@ -0,0 +1,23 @@
  9723. +/*
  9724. + * Copyright 2013 Gateworks Corporation
  9725. + *
  9726. + * The code contained herein is licensed under the GNU General Public
  9727. + * License. You may obtain a copy of the GNU General Public License
  9728. + * Version 2 or later at the following locations:
  9729. + *
  9730. + * http://www.opensource.org/licenses/gpl-license.html
  9731. + * http://www.gnu.org/copyleft/gpl.html
  9732. + */
  9733. +
  9734. +/dts-v1/;
  9735. +#include "imx6q.dtsi"
  9736. +#include "imx6qdl-gw53xx.dtsi"
  9737. +
  9738. +/ {
  9739. + model = "Gateworks Ventana i.MX6 Quad GW53XX";
  9740. + compatible = "gw,imx6q-gw53xx", "gw,ventana", "fsl,imx6q";
  9741. +};
  9742. +
  9743. +&sata {
  9744. + status = "okay";
  9745. +};
  9746. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-gw5400-a.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gw5400-a.dts
  9747. --- linux-3.14.15/arch/arm/boot/dts/imx6q-gw5400-a.dts 1970-01-01 01:00:00.000000000 +0100
  9748. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gw5400-a.dts 2014-08-20 19:31:39.900842271 +0200
  9749. @@ -0,0 +1,543 @@
  9750. +/*
  9751. + * Copyright 2013 Gateworks Corporation
  9752. + *
  9753. + * The code contained herein is licensed under the GNU General Public
  9754. + * License. You may obtain a copy of the GNU General Public License
  9755. + * Version 2 or later at the following locations:
  9756. + *
  9757. + * http://www.opensource.org/licenses/gpl-license.html
  9758. + * http://www.gnu.org/copyleft/gpl.html
  9759. + */
  9760. +
  9761. +/dts-v1/;
  9762. +#include "imx6q.dtsi"
  9763. +
  9764. +/ {
  9765. + model = "Gateworks Ventana GW5400-A";
  9766. + compatible = "gw,imx6q-gw5400-a", "gw,ventana", "fsl,imx6q";
  9767. +
  9768. + /* these are used by bootloader for disabling nodes */
  9769. + aliases {
  9770. + ethernet0 = &fec;
  9771. + ethernet1 = &eth1;
  9772. + i2c0 = &i2c1;
  9773. + i2c1 = &i2c2;
  9774. + i2c2 = &i2c3;
  9775. + led0 = &led0;
  9776. + led1 = &led1;
  9777. + led2 = &led2;
  9778. + sky2 = &eth1;
  9779. + ssi0 = &ssi1;
  9780. + spi0 = &ecspi1;
  9781. + usb0 = &usbh1;
  9782. + usb1 = &usbotg;
  9783. + usdhc2 = &usdhc3;
  9784. + };
  9785. +
  9786. + chosen {
  9787. + bootargs = "console=ttymxc1,115200";
  9788. + };
  9789. +
  9790. + leds {
  9791. + compatible = "gpio-leds";
  9792. +
  9793. + led0: user1 {
  9794. + label = "user1";
  9795. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  9796. + default-state = "on";
  9797. + linux,default-trigger = "heartbeat";
  9798. + };
  9799. +
  9800. + led1: user2 {
  9801. + label = "user2";
  9802. + gpios = <&gpio4 10 0>; /* 106 -> MX6_PANLEDR */
  9803. + default-state = "off";
  9804. + };
  9805. +
  9806. + led2: user3 {
  9807. + label = "user3";
  9808. + gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
  9809. + default-state = "off";
  9810. + };
  9811. + };
  9812. +
  9813. + memory {
  9814. + reg = <0x10000000 0x40000000>;
  9815. + };
  9816. +
  9817. + pps {
  9818. + compatible = "pps-gpio";
  9819. + gpios = <&gpio1 5 0>;
  9820. + status = "okay";
  9821. + };
  9822. +
  9823. + regulators {
  9824. + compatible = "simple-bus";
  9825. + #address-cells = <1>;
  9826. + #size-cells = <0>;
  9827. +
  9828. + reg_1p0v: regulator@0 {
  9829. + compatible = "regulator-fixed";
  9830. + reg = <0>;
  9831. + regulator-name = "1P0V";
  9832. + regulator-min-microvolt = <1000000>;
  9833. + regulator-max-microvolt = <1000000>;
  9834. + regulator-always-on;
  9835. + };
  9836. +
  9837. + reg_3p3v: regulator@1 {
  9838. + compatible = "regulator-fixed";
  9839. + reg = <1>;
  9840. + regulator-name = "3P3V";
  9841. + regulator-min-microvolt = <3300000>;
  9842. + regulator-max-microvolt = <3300000>;
  9843. + regulator-always-on;
  9844. + };
  9845. +
  9846. + reg_usb_h1_vbus: regulator@2 {
  9847. + compatible = "regulator-fixed";
  9848. + reg = <2>;
  9849. + regulator-name = "usb_h1_vbus";
  9850. + regulator-min-microvolt = <5000000>;
  9851. + regulator-max-microvolt = <5000000>;
  9852. + regulator-always-on;
  9853. + };
  9854. +
  9855. + reg_usb_otg_vbus: regulator@3 {
  9856. + compatible = "regulator-fixed";
  9857. + reg = <3>;
  9858. + regulator-name = "usb_otg_vbus";
  9859. + regulator-min-microvolt = <5000000>;
  9860. + regulator-max-microvolt = <5000000>;
  9861. + gpio = <&gpio3 22 0>;
  9862. + enable-active-high;
  9863. + };
  9864. + };
  9865. +
  9866. + sound {
  9867. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  9868. + "fsl,imx-audio-sgtl5000";
  9869. + model = "imx6q-sabrelite-sgtl5000";
  9870. + ssi-controller = <&ssi1>;
  9871. + audio-codec = <&codec>;
  9872. + audio-routing =
  9873. + "MIC_IN", "Mic Jack",
  9874. + "Mic Jack", "Mic Bias",
  9875. + "Headphone Jack", "HP_OUT";
  9876. + mux-int-port = <1>;
  9877. + mux-ext-port = <4>;
  9878. + };
  9879. +};
  9880. +
  9881. +&audmux {
  9882. + pinctrl-names = "default";
  9883. + pinctrl-0 = <&pinctrl_audmux>;
  9884. + status = "okay";
  9885. +};
  9886. +
  9887. +&ecspi1 {
  9888. + fsl,spi-num-chipselects = <1>;
  9889. + cs-gpios = <&gpio3 19 0>;
  9890. + pinctrl-names = "default";
  9891. + pinctrl-0 = <&pinctrl_ecspi1>;
  9892. + status = "okay";
  9893. +
  9894. + flash: m25p80@0 {
  9895. + compatible = "sst,w25q256";
  9896. + spi-max-frequency = <30000000>;
  9897. + reg = <0>;
  9898. + };
  9899. +};
  9900. +
  9901. +&fec {
  9902. + pinctrl-names = "default";
  9903. + pinctrl-0 = <&pinctrl_enet>;
  9904. + phy-mode = "rgmii";
  9905. + phy-reset-gpios = <&gpio1 30 0>;
  9906. + status = "okay";
  9907. +};
  9908. +
  9909. +&i2c1 {
  9910. + clock-frequency = <100000>;
  9911. + pinctrl-names = "default";
  9912. + pinctrl-0 = <&pinctrl_i2c1>;
  9913. + status = "okay";
  9914. +
  9915. + eeprom1: eeprom@50 {
  9916. + compatible = "atmel,24c02";
  9917. + reg = <0x50>;
  9918. + pagesize = <16>;
  9919. + };
  9920. +
  9921. + eeprom2: eeprom@51 {
  9922. + compatible = "atmel,24c02";
  9923. + reg = <0x51>;
  9924. + pagesize = <16>;
  9925. + };
  9926. +
  9927. + eeprom3: eeprom@52 {
  9928. + compatible = "atmel,24c02";
  9929. + reg = <0x52>;
  9930. + pagesize = <16>;
  9931. + };
  9932. +
  9933. + eeprom4: eeprom@53 {
  9934. + compatible = "atmel,24c02";
  9935. + reg = <0x53>;
  9936. + pagesize = <16>;
  9937. + };
  9938. +
  9939. + gpio: pca9555@23 {
  9940. + compatible = "nxp,pca9555";
  9941. + reg = <0x23>;
  9942. + gpio-controller;
  9943. + #gpio-cells = <2>;
  9944. + };
  9945. +
  9946. + hwmon: gsc@29 {
  9947. + compatible = "gw,gsp";
  9948. + reg = <0x29>;
  9949. + };
  9950. +
  9951. + rtc: ds1672@68 {
  9952. + compatible = "dallas,ds1672";
  9953. + reg = <0x68>;
  9954. + };
  9955. +};
  9956. +
  9957. +&i2c2 {
  9958. + clock-frequency = <100000>;
  9959. + pinctrl-names = "default";
  9960. + pinctrl-0 = <&pinctrl_i2c2>;
  9961. + status = "okay";
  9962. +
  9963. + pmic: pfuze100@08 {
  9964. + compatible = "fsl,pfuze100";
  9965. + reg = <0x08>;
  9966. +
  9967. + regulators {
  9968. + sw1a_reg: sw1ab {
  9969. + regulator-min-microvolt = <300000>;
  9970. + regulator-max-microvolt = <1875000>;
  9971. + regulator-boot-on;
  9972. + regulator-always-on;
  9973. + regulator-ramp-delay = <6250>;
  9974. + };
  9975. +
  9976. + sw1c_reg: sw1c {
  9977. + regulator-min-microvolt = <300000>;
  9978. + regulator-max-microvolt = <1875000>;
  9979. + regulator-boot-on;
  9980. + regulator-always-on;
  9981. + regulator-ramp-delay = <6250>;
  9982. + };
  9983. +
  9984. + sw2_reg: sw2 {
  9985. + regulator-min-microvolt = <800000>;
  9986. + regulator-max-microvolt = <3950000>;
  9987. + regulator-boot-on;
  9988. + regulator-always-on;
  9989. + };
  9990. +
  9991. + sw3a_reg: sw3a {
  9992. + regulator-min-microvolt = <400000>;
  9993. + regulator-max-microvolt = <1975000>;
  9994. + regulator-boot-on;
  9995. + regulator-always-on;
  9996. + };
  9997. +
  9998. + sw3b_reg: sw3b {
  9999. + regulator-min-microvolt = <400000>;
  10000. + regulator-max-microvolt = <1975000>;
  10001. + regulator-boot-on;
  10002. + regulator-always-on;
  10003. + };
  10004. +
  10005. + sw4_reg: sw4 {
  10006. + regulator-min-microvolt = <800000>;
  10007. + regulator-max-microvolt = <3300000>;
  10008. + };
  10009. +
  10010. + swbst_reg: swbst {
  10011. + regulator-min-microvolt = <5000000>;
  10012. + regulator-max-microvolt = <5150000>;
  10013. + };
  10014. +
  10015. + snvs_reg: vsnvs {
  10016. + regulator-min-microvolt = <1000000>;
  10017. + regulator-max-microvolt = <3000000>;
  10018. + regulator-boot-on;
  10019. + regulator-always-on;
  10020. + };
  10021. +
  10022. + vref_reg: vrefddr {
  10023. + regulator-boot-on;
  10024. + regulator-always-on;
  10025. + };
  10026. +
  10027. + vgen1_reg: vgen1 {
  10028. + regulator-min-microvolt = <800000>;
  10029. + regulator-max-microvolt = <1550000>;
  10030. + };
  10031. +
  10032. + vgen2_reg: vgen2 {
  10033. + regulator-min-microvolt = <800000>;
  10034. + regulator-max-microvolt = <1550000>;
  10035. + };
  10036. +
  10037. + vgen3_reg: vgen3 {
  10038. + regulator-min-microvolt = <1800000>;
  10039. + regulator-max-microvolt = <3300000>;
  10040. + };
  10041. +
  10042. + vgen4_reg: vgen4 {
  10043. + regulator-min-microvolt = <1800000>;
  10044. + regulator-max-microvolt = <3300000>;
  10045. + regulator-always-on;
  10046. + };
  10047. +
  10048. + vgen5_reg: vgen5 {
  10049. + regulator-min-microvolt = <1800000>;
  10050. + regulator-max-microvolt = <3300000>;
  10051. + regulator-always-on;
  10052. + };
  10053. +
  10054. + vgen6_reg: vgen6 {
  10055. + regulator-min-microvolt = <1800000>;
  10056. + regulator-max-microvolt = <3300000>;
  10057. + regulator-always-on;
  10058. + };
  10059. + };
  10060. + };
  10061. +
  10062. + pciswitch: pex8609@3f {
  10063. + compatible = "plx,pex8609";
  10064. + reg = <0x3f>;
  10065. + };
  10066. +
  10067. + pciclkgen: si52147@6b {
  10068. + compatible = "sil,si52147";
  10069. + reg = <0x6b>;
  10070. + };
  10071. +};
  10072. +
  10073. +&i2c3 {
  10074. + clock-frequency = <100000>;
  10075. + pinctrl-names = "default";
  10076. + pinctrl-0 = <&pinctrl_i2c3>;
  10077. + status = "okay";
  10078. +
  10079. + accelerometer: mma8450@1c {
  10080. + compatible = "fsl,mma8450";
  10081. + reg = <0x1c>;
  10082. + };
  10083. +
  10084. + codec: sgtl5000@0a {
  10085. + compatible = "fsl,sgtl5000";
  10086. + reg = <0x0a>;
  10087. + clocks = <&clks 201>;
  10088. + VDDA-supply = <&sw4_reg>;
  10089. + VDDIO-supply = <&reg_3p3v>;
  10090. + };
  10091. +
  10092. + hdmiin: adv7611@4c {
  10093. + compatible = "adi,adv7611";
  10094. + reg = <0x4c>;
  10095. + };
  10096. +
  10097. + touchscreen: egalax_ts@04 {
  10098. + compatible = "eeti,egalax_ts";
  10099. + reg = <0x04>;
  10100. + interrupt-parent = <&gpio7>;
  10101. + interrupts = <12 2>; /* gpio7_12 active low */
  10102. + wakeup-gpios = <&gpio7 12 0>;
  10103. + };
  10104. +
  10105. + videoout: adv7393@2a {
  10106. + compatible = "adi,adv7393";
  10107. + reg = <0x2a>;
  10108. + };
  10109. +
  10110. + videoin: adv7180@20 {
  10111. + compatible = "adi,adv7180";
  10112. + reg = <0x20>;
  10113. + };
  10114. +};
  10115. +
  10116. +&iomuxc {
  10117. + pinctrl-names = "default";
  10118. + pinctrl-0 = <&pinctrl_hog>;
  10119. +
  10120. + imx6q-gw5400-a {
  10121. + pinctrl_hog: hoggrp {
  10122. + fsl,pins = <
  10123. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  10124. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000 /* SPINOR_CS0# */
  10125. + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
  10126. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE RST */
  10127. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  10128. + MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x80000000 /* GPS_PPS */
  10129. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* TOUCH_IRQ# */
  10130. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  10131. + MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x80000000 /* user2 led */
  10132. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  10133. + MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x80000000 /* USBHUB_RST# */
  10134. + MX6QDL_PAD_SD1_DAT3__GPIO1_IO21 0x80000000 /* MIPI_DIO */
  10135. + >;
  10136. + };
  10137. +
  10138. + pinctrl_audmux: audmuxgrp {
  10139. + fsl,pins = <
  10140. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  10141. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  10142. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  10143. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  10144. + >;
  10145. + };
  10146. +
  10147. + pinctrl_ecspi1: ecspi1grp {
  10148. + fsl,pins = <
  10149. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  10150. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  10151. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  10152. + >;
  10153. + };
  10154. +
  10155. + pinctrl_enet: enetgrp {
  10156. + fsl,pins = <
  10157. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  10158. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  10159. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  10160. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  10161. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  10162. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  10163. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  10164. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  10165. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  10166. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  10167. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  10168. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  10169. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  10170. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  10171. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  10172. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  10173. + >;
  10174. + };
  10175. +
  10176. + pinctrl_i2c1: i2c1grp {
  10177. + fsl,pins = <
  10178. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  10179. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  10180. + >;
  10181. + };
  10182. +
  10183. + pinctrl_i2c2: i2c2grp {
  10184. + fsl,pins = <
  10185. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  10186. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  10187. + >;
  10188. + };
  10189. +
  10190. + pinctrl_i2c3: i2c3grp {
  10191. + fsl,pins = <
  10192. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  10193. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  10194. + >;
  10195. + };
  10196. +
  10197. + pinctrl_uart1: uart1grp {
  10198. + fsl,pins = <
  10199. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  10200. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  10201. + >;
  10202. + };
  10203. +
  10204. + pinctrl_uart2: uart2grp {
  10205. + fsl,pins = <
  10206. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  10207. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  10208. + >;
  10209. + };
  10210. +
  10211. + pinctrl_uart5: uart5grp {
  10212. + fsl,pins = <
  10213. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  10214. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  10215. + >;
  10216. + };
  10217. +
  10218. + pinctrl_usbotg: usbotggrp {
  10219. + fsl,pins = <
  10220. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  10221. + >;
  10222. + };
  10223. +
  10224. + pinctrl_usdhc3: usdhc3grp {
  10225. + fsl,pins = <
  10226. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  10227. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  10228. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  10229. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  10230. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  10231. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  10232. + >;
  10233. + };
  10234. + };
  10235. +};
  10236. +
  10237. +&ldb {
  10238. + status = "okay";
  10239. +};
  10240. +
  10241. +&pcie {
  10242. + reset-gpio = <&gpio1 29 0>;
  10243. + status = "okay";
  10244. +
  10245. + eth1: sky2@8 { /* MAC/PHY on bus 8 */
  10246. + compatible = "marvell,sky2";
  10247. + };
  10248. +};
  10249. +
  10250. +&ssi1 {
  10251. + fsl,mode = "i2s-slave";
  10252. + status = "okay";
  10253. +};
  10254. +
  10255. +&uart1 {
  10256. + pinctrl-names = "default";
  10257. + pinctrl-0 = <&pinctrl_uart1>;
  10258. + status = "okay";
  10259. +};
  10260. +
  10261. +&uart2 {
  10262. + pinctrl-names = "default";
  10263. + pinctrl-0 = <&pinctrl_uart2>;
  10264. + status = "okay";
  10265. +};
  10266. +
  10267. +&uart5 {
  10268. + pinctrl-names = "default";
  10269. + pinctrl-0 = <&pinctrl_uart5>;
  10270. + status = "okay";
  10271. +};
  10272. +
  10273. +&usbotg {
  10274. + vbus-supply = <&reg_usb_otg_vbus>;
  10275. + pinctrl-names = "default";
  10276. + pinctrl-0 = <&pinctrl_usbotg>;
  10277. + disable-over-current;
  10278. + status = "okay";
  10279. +};
  10280. +
  10281. +&usbh1 {
  10282. + vbus-supply = <&reg_usb_h1_vbus>;
  10283. + status = "okay";
  10284. +};
  10285. +
  10286. +&usdhc3 {
  10287. + pinctrl-names = "default";
  10288. + pinctrl-0 = <&pinctrl_usdhc3>;
  10289. + cd-gpios = <&gpio7 0 0>;
  10290. + vmmc-supply = <&reg_3p3v>;
  10291. + status = "okay";
  10292. +};
  10293. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-gw54xx.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gw54xx.dts
  10294. --- linux-3.14.15/arch/arm/boot/dts/imx6q-gw54xx.dts 1970-01-01 01:00:00.000000000 +0100
  10295. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-gw54xx.dts 2014-08-20 19:31:39.900842271 +0200
  10296. @@ -0,0 +1,23 @@
  10297. +/*
  10298. + * Copyright 2013 Gateworks Corporation
  10299. + *
  10300. + * The code contained herein is licensed under the GNU General Public
  10301. + * License. You may obtain a copy of the GNU General Public License
  10302. + * Version 2 or later at the following locations:
  10303. + *
  10304. + * http://www.opensource.org/licenses/gpl-license.html
  10305. + * http://www.gnu.org/copyleft/gpl.html
  10306. + */
  10307. +
  10308. +/dts-v1/;
  10309. +#include "imx6q.dtsi"
  10310. +#include "imx6qdl-gw54xx.dtsi"
  10311. +
  10312. +/ {
  10313. + model = "Gateworks Ventana i.MX6 Quad GW54XX";
  10314. + compatible = "gw,imx6q-gw54xx", "gw,ventana", "fsl,imx6q";
  10315. +};
  10316. +
  10317. +&sata {
  10318. + status = "okay";
  10319. +};
  10320. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-hummingboard.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-hummingboard.dts
  10321. --- linux-3.14.15/arch/arm/boot/dts/imx6q-hummingboard.dts 1970-01-01 01:00:00.000000000 +0100
  10322. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-hummingboard.dts 2014-08-20 19:31:39.900842271 +0200
  10323. @@ -0,0 +1,21 @@
  10324. +/*
  10325. + * Copyright (C) 2014 Rabeeh Khoury (rabeeh@solid-run.com)
  10326. + * Based on work by Russell King
  10327. + */
  10328. +/dts-v1/;
  10329. +
  10330. +#include "imx6q.dtsi"
  10331. +#include "imx6qdl-hummingboard.dtsi"
  10332. +
  10333. +/ {
  10334. + model = "SolidRun HummingBoard Dual/Quad";
  10335. + compatible = "solidrun,hummingboard/q", "fsl,imx6q";
  10336. +};
  10337. +
  10338. +&sata {
  10339. + status = "okay";
  10340. + fsl,transmit-level-mV = <1104>;
  10341. + fsl,transmit-boost-mdB = <0>;
  10342. + fsl,transmit-atten-16ths = <9>;
  10343. + fsl,no-spread-spectrum;
  10344. +};
  10345. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-nitrogen6x.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-nitrogen6x.dts
  10346. --- linux-3.14.15/arch/arm/boot/dts/imx6q-nitrogen6x.dts 1970-01-01 01:00:00.000000000 +0100
  10347. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-nitrogen6x.dts 2014-08-20 19:31:39.900842271 +0200
  10348. @@ -0,0 +1,25 @@
  10349. +/*
  10350. + * Copyright 2013 Boundary Devices, Inc.
  10351. + * Copyright 2012 Freescale Semiconductor, Inc.
  10352. + * Copyright 2011 Linaro Ltd.
  10353. + *
  10354. + * The code contained herein is licensed under the GNU General Public
  10355. + * License. You may obtain a copy of the GNU General Public License
  10356. + * Version 2 or later at the following locations:
  10357. + *
  10358. + * http://www.opensource.org/licenses/gpl-license.html
  10359. + * http://www.gnu.org/copyleft/gpl.html
  10360. + */
  10361. +
  10362. +/dts-v1/;
  10363. +#include "imx6q.dtsi"
  10364. +#include "imx6qdl-nitrogen6x.dtsi"
  10365. +
  10366. +/ {
  10367. + model = "Freescale i.MX6 Quad Nitrogen6x Board";
  10368. + compatible = "fsl,imx6q-nitrogen6x", "fsl,imx6q";
  10369. +};
  10370. +
  10371. +&sata {
  10372. + status = "okay";
  10373. +};
  10374. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-phytec-pbab01.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-phytec-pbab01.dts
  10375. --- linux-3.14.15/arch/arm/boot/dts/imx6q-phytec-pbab01.dts 2014-07-31 23:51:43.000000000 +0200
  10376. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-phytec-pbab01.dts 2014-08-20 19:31:39.900842271 +0200
  10377. @@ -11,24 +11,17 @@
  10378. /dts-v1/;
  10379. #include "imx6q-phytec-pfla02.dtsi"
  10380. +#include "imx6qdl-phytec-pbab01.dtsi"
  10381. / {
  10382. model = "Phytec phyFLEX-i.MX6 Quad Carrier-Board";
  10383. compatible = "phytec,imx6q-pbab01", "phytec,imx6q-pfla02", "fsl,imx6q";
  10384. -};
  10385. -
  10386. -&fec {
  10387. - status = "okay";
  10388. -};
  10389. -
  10390. -&uart4 {
  10391. - status = "okay";
  10392. -};
  10393. -&usdhc2 {
  10394. - status = "okay";
  10395. + chosen {
  10396. + stdout-path = &uart4;
  10397. + };
  10398. };
  10399. -&usdhc3 {
  10400. - status = "okay";
  10401. +&sata {
  10402. + status = "okay";
  10403. };
  10404. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi
  10405. --- linux-3.14.15/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi 2014-07-31 23:51:43.000000000 +0200
  10406. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi 2014-08-20 19:31:39.900842271 +0200
  10407. @@ -10,171 +10,13 @@
  10408. */
  10409. #include "imx6q.dtsi"
  10410. +#include "imx6qdl-phytec-pfla02.dtsi"
  10411. / {
  10412. - model = "Phytec phyFLEX-i.MX6 Ouad";
  10413. + model = "Phytec phyFLEX-i.MX6 Quad";
  10414. compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
  10415. memory {
  10416. reg = <0x10000000 0x80000000>;
  10417. };
  10418. };
  10419. -
  10420. -&ecspi3 {
  10421. - pinctrl-names = "default";
  10422. - pinctrl-0 = <&pinctrl_ecspi3_1>;
  10423. - status = "okay";
  10424. - fsl,spi-num-chipselects = <1>;
  10425. - cs-gpios = <&gpio4 24 0>;
  10426. -
  10427. - flash@0 {
  10428. - compatible = "m25p80";
  10429. - spi-max-frequency = <20000000>;
  10430. - reg = <0>;
  10431. - };
  10432. -};
  10433. -
  10434. -&i2c1 {
  10435. - pinctrl-names = "default";
  10436. - pinctrl-0 = <&pinctrl_i2c1_1>;
  10437. - status = "okay";
  10438. -
  10439. - eeprom@50 {
  10440. - compatible = "atmel,24c32";
  10441. - reg = <0x50>;
  10442. - };
  10443. -
  10444. - pmic@58 {
  10445. - compatible = "dialog,da9063";
  10446. - reg = <0x58>;
  10447. - interrupt-parent = <&gpio4>;
  10448. - interrupts = <17 0x8>; /* active-low GPIO4_17 */
  10449. -
  10450. - regulators {
  10451. - vddcore_reg: bcore1 {
  10452. - regulator-min-microvolt = <730000>;
  10453. - regulator-max-microvolt = <1380000>;
  10454. - regulator-always-on;
  10455. - };
  10456. -
  10457. - vddsoc_reg: bcore2 {
  10458. - regulator-min-microvolt = <730000>;
  10459. - regulator-max-microvolt = <1380000>;
  10460. - regulator-always-on;
  10461. - };
  10462. -
  10463. - vdd_ddr3_reg: bpro {
  10464. - regulator-min-microvolt = <1500000>;
  10465. - regulator-max-microvolt = <1500000>;
  10466. - regulator-always-on;
  10467. - };
  10468. -
  10469. - vdd_3v3_reg: bperi {
  10470. - regulator-min-microvolt = <3300000>;
  10471. - regulator-max-microvolt = <3300000>;
  10472. - regulator-always-on;
  10473. - };
  10474. -
  10475. - vdd_buckmem_reg: bmem {
  10476. - regulator-min-microvolt = <3300000>;
  10477. - regulator-max-microvolt = <3300000>;
  10478. - regulator-always-on;
  10479. - };
  10480. -
  10481. - vdd_eth_reg: bio {
  10482. - regulator-min-microvolt = <1200000>;
  10483. - regulator-max-microvolt = <1200000>;
  10484. - regulator-always-on;
  10485. - };
  10486. -
  10487. - vdd_eth_io_reg: ldo4 {
  10488. - regulator-min-microvolt = <2500000>;
  10489. - regulator-max-microvolt = <2500000>;
  10490. - regulator-always-on;
  10491. - };
  10492. -
  10493. - vdd_mx6_snvs_reg: ldo5 {
  10494. - regulator-min-microvolt = <3000000>;
  10495. - regulator-max-microvolt = <3000000>;
  10496. - regulator-always-on;
  10497. - };
  10498. -
  10499. - vdd_3v3_pmic_io_reg: ldo6 {
  10500. - regulator-min-microvolt = <3300000>;
  10501. - regulator-max-microvolt = <3300000>;
  10502. - regulator-always-on;
  10503. - };
  10504. -
  10505. - vdd_sd0_reg: ldo9 {
  10506. - regulator-min-microvolt = <3300000>;
  10507. - regulator-max-microvolt = <3300000>;
  10508. - };
  10509. -
  10510. - vdd_sd1_reg: ldo10 {
  10511. - regulator-min-microvolt = <3300000>;
  10512. - regulator-max-microvolt = <3300000>;
  10513. - };
  10514. -
  10515. - vdd_mx6_high_reg: ldo11 {
  10516. - regulator-min-microvolt = <3000000>;
  10517. - regulator-max-microvolt = <3000000>;
  10518. - regulator-always-on;
  10519. - };
  10520. - };
  10521. - };
  10522. -};
  10523. -
  10524. -&iomuxc {
  10525. - pinctrl-names = "default";
  10526. - pinctrl-0 = <&pinctrl_hog>;
  10527. -
  10528. - hog {
  10529. - pinctrl_hog: hoggrp {
  10530. - fsl,pins = <
  10531. - MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  10532. - MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
  10533. - MX6QDL_PAD_DI0_PIN15__GPIO4_IO17 0x80000000 /* PMIC interrupt */
  10534. - >;
  10535. - };
  10536. - };
  10537. -
  10538. - pfla02 {
  10539. - pinctrl_usdhc3_pfla02: usdhc3grp-pfla02 {
  10540. - fsl,pins = <
  10541. - MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
  10542. - MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
  10543. - >;
  10544. - };
  10545. - };
  10546. -};
  10547. -
  10548. -&fec {
  10549. - pinctrl-names = "default";
  10550. - pinctrl-0 = <&pinctrl_enet_3>;
  10551. - phy-mode = "rgmii";
  10552. - phy-reset-gpios = <&gpio3 23 0>;
  10553. - status = "disabled";
  10554. -};
  10555. -
  10556. -&uart4 {
  10557. - pinctrl-names = "default";
  10558. - pinctrl-0 = <&pinctrl_uart4_1>;
  10559. - status = "disabled";
  10560. -};
  10561. -
  10562. -&usdhc2 {
  10563. - pinctrl-names = "default";
  10564. - pinctrl-0 = <&pinctrl_usdhc2_2>;
  10565. - cd-gpios = <&gpio1 4 0>;
  10566. - wp-gpios = <&gpio1 2 0>;
  10567. - status = "disabled";
  10568. -};
  10569. -
  10570. -&usdhc3 {
  10571. - pinctrl-names = "default";
  10572. - pinctrl-0 = <&pinctrl_usdhc3_2
  10573. - &pinctrl_usdhc3_pfla02>;
  10574. - cd-gpios = <&gpio1 27 0>;
  10575. - wp-gpios = <&gpio1 29 0>;
  10576. - status = "disabled";
  10577. -};
  10578. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-pinfunc.h linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-pinfunc.h
  10579. --- linux-3.14.15/arch/arm/boot/dts/imx6q-pinfunc.h 2014-07-31 23:51:43.000000000 +0200
  10580. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-pinfunc.h 2014-08-20 19:31:39.900842271 +0200
  10581. @@ -673,6 +673,7 @@
  10582. #define MX6QDL_PAD_GPIO_3__USB_H1_OC 0x22c 0x5fc 0x948 0x6 0x1
  10583. #define MX6QDL_PAD_GPIO_3__MLB_CLK 0x22c 0x5fc 0x900 0x7 0x1
  10584. #define MX6QDL_PAD_GPIO_6__ESAI_TX_CLK 0x230 0x600 0x870 0x0 0x1
  10585. +#define MX6QDL_PAD_GPIO_6__ENET_IRQ 0x230 0x600 0x03c 0x11 0xff000609
  10586. #define MX6QDL_PAD_GPIO_6__I2C3_SDA 0x230 0x600 0x8ac 0x2 0x1
  10587. #define MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x230 0x600 0x000 0x5 0x0
  10588. #define MX6QDL_PAD_GPIO_6__SD2_LCTL 0x230 0x600 0x000 0x6 0x0
  10589. @@ -1024,6 +1025,7 @@
  10590. #define MX6QDL_PAD_SD1_DAT2__WDOG1_RESET_B_DEB 0x34c 0x734 0x000 0x6 0x0
  10591. #define MX6QDL_PAD_SD1_CLK__SD1_CLK 0x350 0x738 0x000 0x0 0x0
  10592. #define MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK 0x350 0x738 0x828 0x1 0x0
  10593. +#define MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT 0x350 0x738 0x000 0x2 0x0
  10594. #define MX6QDL_PAD_SD1_CLK__GPT_CLKIN 0x350 0x738 0x000 0x3 0x0
  10595. #define MX6QDL_PAD_SD1_CLK__GPIO1_IO20 0x350 0x738 0x000 0x5 0x0
  10596. #define MX6QDL_PAD_SD2_CLK__SD2_CLK 0x354 0x73c 0x000 0x0 0x0
  10597. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-sabreauto.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-sabreauto.dts
  10598. --- linux-3.14.15/arch/arm/boot/dts/imx6q-sabreauto.dts 2014-07-31 23:51:43.000000000 +0200
  10599. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-sabreauto.dts 2014-08-20 19:23:45.542811617 +0200
  10600. @@ -20,6 +20,22 @@
  10601. compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
  10602. };
  10603. +&mxcfb1 {
  10604. + status = "okay";
  10605. +};
  10606. +
  10607. +&mxcfb2 {
  10608. + status = "okay";
  10609. +};
  10610. +
  10611. +&mxcfb3 {
  10612. + status = "okay";
  10613. +};
  10614. +
  10615. +&mxcfb4 {
  10616. + status = "okay";
  10617. +};
  10618. +
  10619. &sata {
  10620. status = "okay";
  10621. };
  10622. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-sabrelite.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-sabrelite.dts
  10623. --- linux-3.14.15/arch/arm/boot/dts/imx6q-sabrelite.dts 2014-07-31 23:51:43.000000000 +0200
  10624. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-sabrelite.dts 2014-08-20 19:31:39.900842271 +0200
  10625. @@ -12,189 +12,13 @@
  10626. /dts-v1/;
  10627. #include "imx6q.dtsi"
  10628. +#include "imx6qdl-sabrelite.dtsi"
  10629. / {
  10630. model = "Freescale i.MX6 Quad SABRE Lite Board";
  10631. compatible = "fsl,imx6q-sabrelite", "fsl,imx6q";
  10632. -
  10633. - memory {
  10634. - reg = <0x10000000 0x40000000>;
  10635. - };
  10636. -
  10637. - regulators {
  10638. - compatible = "simple-bus";
  10639. -
  10640. - reg_2p5v: 2p5v {
  10641. - compatible = "regulator-fixed";
  10642. - regulator-name = "2P5V";
  10643. - regulator-min-microvolt = <2500000>;
  10644. - regulator-max-microvolt = <2500000>;
  10645. - regulator-always-on;
  10646. - };
  10647. -
  10648. - reg_3p3v: 3p3v {
  10649. - compatible = "regulator-fixed";
  10650. - regulator-name = "3P3V";
  10651. - regulator-min-microvolt = <3300000>;
  10652. - regulator-max-microvolt = <3300000>;
  10653. - regulator-always-on;
  10654. - };
  10655. -
  10656. - reg_usb_otg_vbus: usb_otg_vbus {
  10657. - compatible = "regulator-fixed";
  10658. - regulator-name = "usb_otg_vbus";
  10659. - regulator-min-microvolt = <5000000>;
  10660. - regulator-max-microvolt = <5000000>;
  10661. - gpio = <&gpio3 22 0>;
  10662. - enable-active-high;
  10663. - };
  10664. - };
  10665. -
  10666. - sound {
  10667. - compatible = "fsl,imx6q-sabrelite-sgtl5000",
  10668. - "fsl,imx-audio-sgtl5000";
  10669. - model = "imx6q-sabrelite-sgtl5000";
  10670. - ssi-controller = <&ssi1>;
  10671. - audio-codec = <&codec>;
  10672. - audio-routing =
  10673. - "MIC_IN", "Mic Jack",
  10674. - "Mic Jack", "Mic Bias",
  10675. - "Headphone Jack", "HP_OUT";
  10676. - mux-int-port = <1>;
  10677. - mux-ext-port = <4>;
  10678. - };
  10679. -};
  10680. -
  10681. -&audmux {
  10682. - status = "okay";
  10683. - pinctrl-names = "default";
  10684. - pinctrl-0 = <&pinctrl_audmux_1>;
  10685. -};
  10686. -
  10687. -&ecspi1 {
  10688. - fsl,spi-num-chipselects = <1>;
  10689. - cs-gpios = <&gpio3 19 0>;
  10690. - pinctrl-names = "default";
  10691. - pinctrl-0 = <&pinctrl_ecspi1_1>;
  10692. - status = "okay";
  10693. -
  10694. - flash: m25p80@0 {
  10695. - compatible = "sst,sst25vf016b";
  10696. - spi-max-frequency = <20000000>;
  10697. - reg = <0>;
  10698. - };
  10699. -};
  10700. -
  10701. -&fec {
  10702. - pinctrl-names = "default";
  10703. - pinctrl-0 = <&pinctrl_enet_1>;
  10704. - phy-mode = "rgmii";
  10705. - phy-reset-gpios = <&gpio3 23 0>;
  10706. - status = "okay";
  10707. -};
  10708. -
  10709. -&i2c1 {
  10710. - status = "okay";
  10711. - clock-frequency = <100000>;
  10712. - pinctrl-names = "default";
  10713. - pinctrl-0 = <&pinctrl_i2c1_1>;
  10714. -
  10715. - codec: sgtl5000@0a {
  10716. - compatible = "fsl,sgtl5000";
  10717. - reg = <0x0a>;
  10718. - clocks = <&clks 201>;
  10719. - VDDA-supply = <&reg_2p5v>;
  10720. - VDDIO-supply = <&reg_3p3v>;
  10721. - };
  10722. -};
  10723. -
  10724. -&iomuxc {
  10725. - pinctrl-names = "default";
  10726. - pinctrl-0 = <&pinctrl_hog>;
  10727. -
  10728. - hog {
  10729. - pinctrl_hog: hoggrp {
  10730. - fsl,pins = <
  10731. - MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x80000000
  10732. - MX6QDL_PAD_NANDF_D7__GPIO2_IO07 0x80000000
  10733. - MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000
  10734. - MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000
  10735. - MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  10736. - MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000
  10737. - MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0
  10738. - MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x80000000
  10739. - MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  10740. - >;
  10741. - };
  10742. - };
  10743. -};
  10744. -
  10745. -&ldb {
  10746. - status = "okay";
  10747. -
  10748. - lvds-channel@0 {
  10749. - fsl,data-mapping = "spwg";
  10750. - fsl,data-width = <18>;
  10751. - status = "okay";
  10752. -
  10753. - display-timings {
  10754. - native-mode = <&timing0>;
  10755. - timing0: hsd100pxn1 {
  10756. - clock-frequency = <65000000>;
  10757. - hactive = <1024>;
  10758. - vactive = <768>;
  10759. - hback-porch = <220>;
  10760. - hfront-porch = <40>;
  10761. - vback-porch = <21>;
  10762. - vfront-porch = <7>;
  10763. - hsync-len = <60>;
  10764. - vsync-len = <10>;
  10765. - };
  10766. - };
  10767. - };
  10768. };
  10769. &sata {
  10770. status = "okay";
  10771. };
  10772. -
  10773. -&ssi1 {
  10774. - fsl,mode = "i2s-slave";
  10775. - status = "okay";
  10776. -};
  10777. -
  10778. -&uart2 {
  10779. - status = "okay";
  10780. - pinctrl-names = "default";
  10781. - pinctrl-0 = <&pinctrl_uart2_1>;
  10782. -};
  10783. -
  10784. -&usbh1 {
  10785. - status = "okay";
  10786. -};
  10787. -
  10788. -&usbotg {
  10789. - vbus-supply = <&reg_usb_otg_vbus>;
  10790. - pinctrl-names = "default";
  10791. - pinctrl-0 = <&pinctrl_usbotg_1>;
  10792. - disable-over-current;
  10793. - status = "okay";
  10794. -};
  10795. -
  10796. -&usdhc3 {
  10797. - pinctrl-names = "default";
  10798. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  10799. - cd-gpios = <&gpio7 0 0>;
  10800. - wp-gpios = <&gpio7 1 0>;
  10801. - vmmc-supply = <&reg_3p3v>;
  10802. - status = "okay";
  10803. -};
  10804. -
  10805. -&usdhc4 {
  10806. - pinctrl-names = "default";
  10807. - pinctrl-0 = <&pinctrl_usdhc4_2>;
  10808. - cd-gpios = <&gpio2 6 0>;
  10809. - wp-gpios = <&gpio2 7 0>;
  10810. - vmmc-supply = <&reg_3p3v>;
  10811. - status = "okay";
  10812. -};
  10813. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-sabresd.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-sabresd.dts
  10814. --- linux-3.14.15/arch/arm/boot/dts/imx6q-sabresd.dts 2014-07-31 23:51:43.000000000 +0200
  10815. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-sabresd.dts 2014-08-20 19:31:39.900842271 +0200
  10816. @@ -23,3 +23,19 @@
  10817. &sata {
  10818. status = "okay";
  10819. };
  10820. +
  10821. +&mxcfb1 {
  10822. + status = "okay";
  10823. +};
  10824. +
  10825. +&mxcfb2 {
  10826. + status = "okay";
  10827. +};
  10828. +
  10829. +&mxcfb3 {
  10830. + status = "okay";
  10831. +};
  10832. +
  10833. +&mxcfb4 {
  10834. + status = "okay";
  10835. +};
  10836. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts
  10837. --- linux-3.14.15/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts 1970-01-01 01:00:00.000000000 +0100
  10838. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts 2014-08-20 19:31:39.900842271 +0200
  10839. @@ -0,0 +1,23 @@
  10840. +/*
  10841. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  10842. + * Copyright 2011 Linaro Ltd.
  10843. + *
  10844. + * The code contained herein is licensed under the GNU General Public
  10845. + * License. You may obtain a copy of the GNU General Public License
  10846. + * Version 2 or later at the following locations:
  10847. + *
  10848. + * http://www.opensource.org/licenses/gpl-license.html
  10849. + * http://www.gnu.org/copyleft/gpl.html
  10850. + */
  10851. +
  10852. +#include "imx6q-sabresd.dts"
  10853. +
  10854. +&hdmi_video {
  10855. + pinctrl-names = "default";
  10856. + pinctrl-0 = <&pinctrl_hdmi_hdcp>;
  10857. + fsl,hdcp;
  10858. +};
  10859. +
  10860. +&i2c2 {
  10861. + status = "disable";
  10862. +};
  10863. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-sbc6x.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-sbc6x.dts
  10864. --- linux-3.14.15/arch/arm/boot/dts/imx6q-sbc6x.dts 2014-07-31 23:51:43.000000000 +0200
  10865. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-sbc6x.dts 2014-08-20 19:31:39.900842271 +0200
  10866. @@ -17,28 +17,78 @@
  10867. };
  10868. };
  10869. +
  10870. &fec {
  10871. pinctrl-names = "default";
  10872. - pinctrl-0 = <&pinctrl_enet_1>;
  10873. + pinctrl-0 = <&pinctrl_enet>;
  10874. phy-mode = "rgmii";
  10875. status = "okay";
  10876. };
  10877. +&iomuxc {
  10878. + imx6q-sbc6x {
  10879. + pinctrl_enet: enetgrp {
  10880. + fsl,pins = <
  10881. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  10882. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  10883. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  10884. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  10885. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  10886. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  10887. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  10888. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  10889. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  10890. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  10891. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  10892. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  10893. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  10894. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  10895. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  10896. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  10897. + >;
  10898. + };
  10899. +
  10900. + pinctrl_uart1: uart1grp {
  10901. + fsl,pins = <
  10902. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  10903. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  10904. + >;
  10905. + };
  10906. +
  10907. + pinctrl_usbotg: usbotggrp {
  10908. + fsl,pins = <
  10909. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  10910. + >;
  10911. + };
  10912. +
  10913. + pinctrl_usdhc3: usdhc3grp {
  10914. + fsl,pins = <
  10915. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  10916. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  10917. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  10918. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  10919. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  10920. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  10921. + >;
  10922. + };
  10923. + };
  10924. +};
  10925. +
  10926. &uart1 {
  10927. pinctrl-names = "default";
  10928. - pinctrl-0 = <&pinctrl_uart1_1>;
  10929. + pinctrl-0 = <&pinctrl_uart1>;
  10930. status = "okay";
  10931. };
  10932. &usbotg {
  10933. pinctrl-names = "default";
  10934. - pinctrl-0 = <&pinctrl_usbotg_1>;
  10935. + pinctrl-0 = <&pinctrl_usbotg>;
  10936. disable-over-current;
  10937. status = "okay";
  10938. };
  10939. &usdhc3 {
  10940. pinctrl-names = "default";
  10941. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  10942. + pinctrl-0 = <&pinctrl_usdhc3>;
  10943. status = "okay";
  10944. };
  10945. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6q-udoo.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-udoo.dts
  10946. --- linux-3.14.15/arch/arm/boot/dts/imx6q-udoo.dts 2014-07-31 23:51:43.000000000 +0200
  10947. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6q-udoo.dts 2014-08-20 19:31:39.900842271 +0200
  10948. @@ -16,24 +16,78 @@
  10949. model = "Udoo i.MX6 Quad Board";
  10950. compatible = "udoo,imx6q-udoo", "fsl,imx6q";
  10951. + chosen {
  10952. + stdout-path = &uart2;
  10953. + };
  10954. +
  10955. memory {
  10956. reg = <0x10000000 0x40000000>;
  10957. };
  10958. };
  10959. +&fec {
  10960. + pinctrl-names = "default";
  10961. + pinctrl-0 = <&pinctrl_enet>;
  10962. + phy-mode = "rgmii";
  10963. + status = "okay";
  10964. +};
  10965. +
  10966. +&iomuxc {
  10967. + imx6q-udoo {
  10968. + pinctrl_enet: enetgrp {
  10969. + fsl,pins = <
  10970. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  10971. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  10972. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  10973. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  10974. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  10975. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  10976. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  10977. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  10978. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  10979. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  10980. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  10981. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  10982. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  10983. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  10984. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  10985. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  10986. + >;
  10987. + };
  10988. +
  10989. + pinctrl_uart2: uart2grp {
  10990. + fsl,pins = <
  10991. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  10992. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  10993. + >;
  10994. + };
  10995. +
  10996. + pinctrl_usdhc3: usdhc3grp {
  10997. + fsl,pins = <
  10998. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  10999. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  11000. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  11001. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  11002. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  11003. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  11004. + >;
  11005. + };
  11006. + };
  11007. +};
  11008. +
  11009. &sata {
  11010. status = "okay";
  11011. };
  11012. &uart2 {
  11013. pinctrl-names = "default";
  11014. - pinctrl-0 = <&pinctrl_uart2_1>;
  11015. + pinctrl-0 = <&pinctrl_uart2>;
  11016. status = "okay";
  11017. };
  11018. &usdhc3 {
  11019. pinctrl-names = "default";
  11020. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  11021. + pinctrl-0 = <&pinctrl_usdhc3>;
  11022. non-removable;
  11023. status = "okay";
  11024. };
  11025. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6sl.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/imx6sl.dtsi
  11026. --- linux-3.14.15/arch/arm/boot/dts/imx6sl.dtsi 2014-07-31 23:51:43.000000000 +0200
  11027. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6sl.dtsi 2014-08-20 19:31:39.904842290 +0200
  11028. @@ -7,12 +7,14 @@
  11029. *
  11030. */
  11031. +#include <dt-bindings/interrupt-controller/irq.h>
  11032. #include "skeleton.dtsi"
  11033. #include "imx6sl-pinfunc.h"
  11034. #include <dt-bindings/clock/imx6sl-clock.h>
  11035. / {
  11036. aliases {
  11037. + ethernet0 = &fec;
  11038. gpio0 = &gpio1;
  11039. gpio1 = &gpio2;
  11040. gpio2 = &gpio3;
  11041. @@ -27,25 +29,46 @@
  11042. spi1 = &ecspi2;
  11043. spi2 = &ecspi3;
  11044. spi3 = &ecspi4;
  11045. + usbphy0 = &usbphy1;
  11046. + usbphy1 = &usbphy2;
  11047. };
  11048. cpus {
  11049. #address-cells = <1>;
  11050. #size-cells = <0>;
  11051. - cpu@0 {
  11052. + cpu0: cpu@0 {
  11053. compatible = "arm,cortex-a9";
  11054. device_type = "cpu";
  11055. reg = <0x0>;
  11056. next-level-cache = <&L2>;
  11057. + operating-points = <
  11058. + /* kHz uV */
  11059. + 996000 1275000
  11060. + 792000 1175000
  11061. + 396000 975000
  11062. + >;
  11063. + fsl,soc-operating-points = <
  11064. + /* ARM kHz SOC-PU uV */
  11065. + 996000 1225000
  11066. + 792000 1175000
  11067. + 396000 1175000
  11068. + >;
  11069. + clock-latency = <61036>; /* two CLK32 periods */
  11070. + clocks = <&clks IMX6SL_CLK_ARM>, <&clks IMX6SL_CLK_PLL2_PFD2>,
  11071. + <&clks IMX6SL_CLK_STEP>, <&clks IMX6SL_CLK_PLL1_SW>,
  11072. + <&clks IMX6SL_CLK_PLL1_SYS>;
  11073. + clock-names = "arm", "pll2_pfd2_396m", "step",
  11074. + "pll1_sw", "pll1_sys";
  11075. + arm-supply = <&reg_arm>;
  11076. + pu-supply = <&reg_pu>;
  11077. + soc-supply = <&reg_soc>;
  11078. };
  11079. };
  11080. intc: interrupt-controller@00a01000 {
  11081. compatible = "arm,cortex-a9-gic";
  11082. #interrupt-cells = <3>;
  11083. - #address-cells = <1>;
  11084. - #size-cells = <1>;
  11085. interrupt-controller;
  11086. reg = <0x00a01000 0x1000>,
  11087. <0x00a00100 0x100>;
  11088. @@ -57,15 +80,21 @@
  11089. ckil {
  11090. compatible = "fixed-clock";
  11091. + #clock-cells = <0>;
  11092. clock-frequency = <32768>;
  11093. };
  11094. osc {
  11095. compatible = "fixed-clock";
  11096. + #clock-cells = <0>;
  11097. clock-frequency = <24000000>;
  11098. };
  11099. };
  11100. + pu_dummy: pudummy_reg {
  11101. + compatible = "fsl,imx6-dummy-pureg"; /* only used in ldo-bypass */
  11102. + };
  11103. +
  11104. soc {
  11105. #address-cells = <1>;
  11106. #size-cells = <1>;
  11107. @@ -73,19 +102,45 @@
  11108. interrupt-parent = <&intc>;
  11109. ranges;
  11110. + ocram: sram@00900000 {
  11111. + compatible = "mmio-sram";
  11112. + reg = <0x00900000 0x20000>;
  11113. + clocks = <&clks IMX6SL_CLK_OCRAM>;
  11114. + };
  11115. +
  11116. + busfreq { /* BUSFREQ */
  11117. + compatible = "fsl,imx6_busfreq";
  11118. + clocks = <&clks IMX6SL_CLK_PLL2_BUS>, <&clks IMX6SL_CLK_PLL2_PFD2>,
  11119. + <&clks IMX6SL_CLK_PLL2_198M>, <&clks IMX6SL_CLK_ARM>,
  11120. + <&clks IMX6SL_CLK_PLL3_USB_OTG>, <&clks IMX6SL_CLK_PERIPH>,
  11121. + <&clks IMX6SL_CLK_PRE_PERIPH_SEL>, <&clks IMX6SL_CLK_PERIPH_CLK2>,
  11122. + <&clks IMX6SL_CLK_PERIPH_CLK2_SEL>, <&clks IMX6SL_CLK_OSC>,
  11123. + <&clks IMX6SL_CLK_PLL1_SYS>, <&clks IMX6SL_CLK_PERIPH2>,
  11124. + <&clks IMX6SL_CLK_AHB>, <&clks IMX6SL_CLK_OCRAM>,
  11125. + <&clks IMX6SL_CLK_PLL1_SW>, <&clks IMX6SL_CLK_PRE_PERIPH2_SEL>,
  11126. + <&clks IMX6SL_CLK_PERIPH2_CLK2_SEL>, <&clks IMX6SL_CLK_PERIPH2_CLK2>,
  11127. + <&clks IMX6SL_CLK_STEP>;
  11128. + clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
  11129. + "periph_pre", "periph_clk2", "periph_clk2_sel", "osc", "pll1_sys", "periph2", "ahb", "ocram", "pll1_sw",
  11130. + "periph2_pre", "periph2_clk2_sel", "periph2_clk2", "step";
  11131. + fsl,max_ddr_freq = <400000000>;
  11132. + };
  11133. +
  11134. L2: l2-cache@00a02000 {
  11135. compatible = "arm,pl310-cache";
  11136. reg = <0x00a02000 0x1000>;
  11137. - interrupts = <0 92 0x04>;
  11138. + interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
  11139. cache-unified;
  11140. cache-level = <2>;
  11141. arm,tag-latency = <4 2 3>;
  11142. arm,data-latency = <4 2 3>;
  11143. + arm,dynamic-clk-gating;
  11144. + arm,standby-mode;
  11145. };
  11146. pmu {
  11147. compatible = "arm,cortex-a9-pmu";
  11148. - interrupts = <0 94 0x04>;
  11149. + interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
  11150. };
  11151. aips1: aips-bus@02000000 {
  11152. @@ -104,7 +159,7 @@
  11153. spdif: spdif@02004000 {
  11154. reg = <0x02004000 0x4000>;
  11155. - interrupts = <0 52 0x04>;
  11156. + interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
  11157. };
  11158. ecspi1: ecspi@02008000 {
  11159. @@ -112,7 +167,7 @@
  11160. #size-cells = <0>;
  11161. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11162. reg = <0x02008000 0x4000>;
  11163. - interrupts = <0 31 0x04>;
  11164. + interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
  11165. clocks = <&clks IMX6SL_CLK_ECSPI1>,
  11166. <&clks IMX6SL_CLK_ECSPI1>;
  11167. clock-names = "ipg", "per";
  11168. @@ -124,7 +179,7 @@
  11169. #size-cells = <0>;
  11170. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11171. reg = <0x0200c000 0x4000>;
  11172. - interrupts = <0 32 0x04>;
  11173. + interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
  11174. clocks = <&clks IMX6SL_CLK_ECSPI2>,
  11175. <&clks IMX6SL_CLK_ECSPI2>;
  11176. clock-names = "ipg", "per";
  11177. @@ -136,7 +191,7 @@
  11178. #size-cells = <0>;
  11179. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11180. reg = <0x02010000 0x4000>;
  11181. - interrupts = <0 33 0x04>;
  11182. + interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
  11183. clocks = <&clks IMX6SL_CLK_ECSPI3>,
  11184. <&clks IMX6SL_CLK_ECSPI3>;
  11185. clock-names = "ipg", "per";
  11186. @@ -148,7 +203,7 @@
  11187. #size-cells = <0>;
  11188. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11189. reg = <0x02014000 0x4000>;
  11190. - interrupts = <0 34 0x04>;
  11191. + interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
  11192. clocks = <&clks IMX6SL_CLK_ECSPI4>,
  11193. <&clks IMX6SL_CLK_ECSPI4>;
  11194. clock-names = "ipg", "per";
  11195. @@ -159,7 +214,7 @@
  11196. compatible = "fsl,imx6sl-uart",
  11197. "fsl,imx6q-uart", "fsl,imx21-uart";
  11198. reg = <0x02018000 0x4000>;
  11199. - interrupts = <0 30 0x04>;
  11200. + interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
  11201. clocks = <&clks IMX6SL_CLK_UART>,
  11202. <&clks IMX6SL_CLK_UART_SERIAL>;
  11203. clock-names = "ipg", "per";
  11204. @@ -172,7 +227,7 @@
  11205. compatible = "fsl,imx6sl-uart",
  11206. "fsl,imx6q-uart", "fsl,imx21-uart";
  11207. reg = <0x02020000 0x4000>;
  11208. - interrupts = <0 26 0x04>;
  11209. + interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
  11210. clocks = <&clks IMX6SL_CLK_UART>,
  11211. <&clks IMX6SL_CLK_UART_SERIAL>;
  11212. clock-names = "ipg", "per";
  11213. @@ -185,7 +240,7 @@
  11214. compatible = "fsl,imx6sl-uart",
  11215. "fsl,imx6q-uart", "fsl,imx21-uart";
  11216. reg = <0x02024000 0x4000>;
  11217. - interrupts = <0 27 0x04>;
  11218. + interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
  11219. clocks = <&clks IMX6SL_CLK_UART>,
  11220. <&clks IMX6SL_CLK_UART_SERIAL>;
  11221. clock-names = "ipg", "per";
  11222. @@ -195,9 +250,11 @@
  11223. };
  11224. ssi1: ssi@02028000 {
  11225. - compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
  11226. + compatible = "fsl,imx6sl-ssi",
  11227. + "fsl,imx51-ssi",
  11228. + "fsl,imx21-ssi";
  11229. reg = <0x02028000 0x4000>;
  11230. - interrupts = <0 46 0x04>;
  11231. + interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
  11232. clocks = <&clks IMX6SL_CLK_SSI1>;
  11233. dmas = <&sdma 37 1 0>,
  11234. <&sdma 38 1 0>;
  11235. @@ -207,9 +264,11 @@
  11236. };
  11237. ssi2: ssi@0202c000 {
  11238. - compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
  11239. + compatible = "fsl,imx6sl-ssi",
  11240. + "fsl,imx51-ssi",
  11241. + "fsl,imx21-ssi";
  11242. reg = <0x0202c000 0x4000>;
  11243. - interrupts = <0 47 0x04>;
  11244. + interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
  11245. clocks = <&clks IMX6SL_CLK_SSI2>;
  11246. dmas = <&sdma 41 1 0>,
  11247. <&sdma 42 1 0>;
  11248. @@ -219,9 +278,11 @@
  11249. };
  11250. ssi3: ssi@02030000 {
  11251. - compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
  11252. + compatible = "fsl,imx6sl-ssi",
  11253. + "fsl,imx51-ssi",
  11254. + "fsl,imx21-ssi";
  11255. reg = <0x02030000 0x4000>;
  11256. - interrupts = <0 48 0x04>;
  11257. + interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
  11258. clocks = <&clks IMX6SL_CLK_SSI3>;
  11259. dmas = <&sdma 45 1 0>,
  11260. <&sdma 46 1 0>;
  11261. @@ -234,7 +295,7 @@
  11262. compatible = "fsl,imx6sl-uart",
  11263. "fsl,imx6q-uart", "fsl,imx21-uart";
  11264. reg = <0x02034000 0x4000>;
  11265. - interrupts = <0 28 0x04>;
  11266. + interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
  11267. clocks = <&clks IMX6SL_CLK_UART>,
  11268. <&clks IMX6SL_CLK_UART_SERIAL>;
  11269. clock-names = "ipg", "per";
  11270. @@ -247,7 +308,7 @@
  11271. compatible = "fsl,imx6sl-uart",
  11272. "fsl,imx6q-uart", "fsl,imx21-uart";
  11273. reg = <0x02038000 0x4000>;
  11274. - interrupts = <0 29 0x04>;
  11275. + interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
  11276. clocks = <&clks IMX6SL_CLK_UART>,
  11277. <&clks IMX6SL_CLK_UART_SERIAL>;
  11278. clock-names = "ipg", "per";
  11279. @@ -261,7 +322,7 @@
  11280. #pwm-cells = <2>;
  11281. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11282. reg = <0x02080000 0x4000>;
  11283. - interrupts = <0 83 0x04>;
  11284. + interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
  11285. clocks = <&clks IMX6SL_CLK_PWM1>,
  11286. <&clks IMX6SL_CLK_PWM1>;
  11287. clock-names = "ipg", "per";
  11288. @@ -271,7 +332,7 @@
  11289. #pwm-cells = <2>;
  11290. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11291. reg = <0x02084000 0x4000>;
  11292. - interrupts = <0 84 0x04>;
  11293. + interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
  11294. clocks = <&clks IMX6SL_CLK_PWM2>,
  11295. <&clks IMX6SL_CLK_PWM2>;
  11296. clock-names = "ipg", "per";
  11297. @@ -281,7 +342,7 @@
  11298. #pwm-cells = <2>;
  11299. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11300. reg = <0x02088000 0x4000>;
  11301. - interrupts = <0 85 0x04>;
  11302. + interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
  11303. clocks = <&clks IMX6SL_CLK_PWM3>,
  11304. <&clks IMX6SL_CLK_PWM3>;
  11305. clock-names = "ipg", "per";
  11306. @@ -291,7 +352,7 @@
  11307. #pwm-cells = <2>;
  11308. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11309. reg = <0x0208c000 0x4000>;
  11310. - interrupts = <0 86 0x04>;
  11311. + interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
  11312. clocks = <&clks IMX6SL_CLK_PWM4>,
  11313. <&clks IMX6SL_CLK_PWM4>;
  11314. clock-names = "ipg", "per";
  11315. @@ -300,7 +361,7 @@
  11316. gpt: gpt@02098000 {
  11317. compatible = "fsl,imx6sl-gpt";
  11318. reg = <0x02098000 0x4000>;
  11319. - interrupts = <0 55 0x04>;
  11320. + interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
  11321. clocks = <&clks IMX6SL_CLK_GPT>,
  11322. <&clks IMX6SL_CLK_GPT_SERIAL>;
  11323. clock-names = "ipg", "per";
  11324. @@ -309,7 +370,8 @@
  11325. gpio1: gpio@0209c000 {
  11326. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11327. reg = <0x0209c000 0x4000>;
  11328. - interrupts = <0 66 0x04 0 67 0x04>;
  11329. + interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
  11330. + <0 67 IRQ_TYPE_LEVEL_HIGH>;
  11331. gpio-controller;
  11332. #gpio-cells = <2>;
  11333. interrupt-controller;
  11334. @@ -319,7 +381,8 @@
  11335. gpio2: gpio@020a0000 {
  11336. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11337. reg = <0x020a0000 0x4000>;
  11338. - interrupts = <0 68 0x04 0 69 0x04>;
  11339. + interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
  11340. + <0 69 IRQ_TYPE_LEVEL_HIGH>;
  11341. gpio-controller;
  11342. #gpio-cells = <2>;
  11343. interrupt-controller;
  11344. @@ -329,7 +392,8 @@
  11345. gpio3: gpio@020a4000 {
  11346. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11347. reg = <0x020a4000 0x4000>;
  11348. - interrupts = <0 70 0x04 0 71 0x04>;
  11349. + interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
  11350. + <0 71 IRQ_TYPE_LEVEL_HIGH>;
  11351. gpio-controller;
  11352. #gpio-cells = <2>;
  11353. interrupt-controller;
  11354. @@ -339,7 +403,8 @@
  11355. gpio4: gpio@020a8000 {
  11356. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11357. reg = <0x020a8000 0x4000>;
  11358. - interrupts = <0 72 0x04 0 73 0x04>;
  11359. + interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
  11360. + <0 73 IRQ_TYPE_LEVEL_HIGH>;
  11361. gpio-controller;
  11362. #gpio-cells = <2>;
  11363. interrupt-controller;
  11364. @@ -349,7 +414,8 @@
  11365. gpio5: gpio@020ac000 {
  11366. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11367. reg = <0x020ac000 0x4000>;
  11368. - interrupts = <0 74 0x04 0 75 0x04>;
  11369. + interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
  11370. + <0 75 IRQ_TYPE_LEVEL_HIGH>;
  11371. gpio-controller;
  11372. #gpio-cells = <2>;
  11373. interrupt-controller;
  11374. @@ -357,21 +423,23 @@
  11375. };
  11376. kpp: kpp@020b8000 {
  11377. + compatible = "fsl,imx6sl-kpp", "fsl,imx21-kpp";
  11378. reg = <0x020b8000 0x4000>;
  11379. - interrupts = <0 82 0x04>;
  11380. + interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
  11381. + clocks = <&clks IMX6SL_CLK_DUMMY>;
  11382. };
  11383. wdog1: wdog@020bc000 {
  11384. compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
  11385. reg = <0x020bc000 0x4000>;
  11386. - interrupts = <0 80 0x04>;
  11387. + interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
  11388. clocks = <&clks IMX6SL_CLK_DUMMY>;
  11389. };
  11390. wdog2: wdog@020c0000 {
  11391. compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
  11392. reg = <0x020c0000 0x4000>;
  11393. - interrupts = <0 81 0x04>;
  11394. + interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
  11395. clocks = <&clks IMX6SL_CLK_DUMMY>;
  11396. status = "disabled";
  11397. };
  11398. @@ -379,7 +447,8 @@
  11399. clks: ccm@020c4000 {
  11400. compatible = "fsl,imx6sl-ccm";
  11401. reg = <0x020c4000 0x4000>;
  11402. - interrupts = <0 87 0x04 0 88 0x04>;
  11403. + interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
  11404. + <0 88 IRQ_TYPE_LEVEL_HIGH>;
  11405. #clock-cells = <1>;
  11406. };
  11407. @@ -388,7 +457,9 @@
  11408. "fsl,imx6q-anatop",
  11409. "syscon", "simple-bus";
  11410. reg = <0x020c8000 0x1000>;
  11411. - interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
  11412. + interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
  11413. + <0 54 IRQ_TYPE_LEVEL_HIGH>,
  11414. + <0 127 IRQ_TYPE_LEVEL_HIGH>;
  11415. regulator-1p1@110 {
  11416. compatible = "fsl,anatop-regulator";
  11417. @@ -434,7 +505,7 @@
  11418. reg_arm: regulator-vddcore@140 {
  11419. compatible = "fsl,anatop-regulator";
  11420. - regulator-name = "cpu";
  11421. + regulator-name = "vddarm";
  11422. regulator-min-microvolt = <725000>;
  11423. regulator-max-microvolt = <1450000>;
  11424. regulator-always-on;
  11425. @@ -454,7 +525,6 @@
  11426. regulator-name = "vddpu";
  11427. regulator-min-microvolt = <725000>;
  11428. regulator-max-microvolt = <1450000>;
  11429. - regulator-always-on;
  11430. anatop-reg-offset = <0x140>;
  11431. anatop-vol-bit-shift = <9>;
  11432. anatop-vol-bit-width = <5>;
  11433. @@ -484,18 +554,34 @@
  11434. };
  11435. };
  11436. + tempmon: tempmon {
  11437. + compatible = "fsl,imx6sl-tempmon", "fsl,imx6q-tempmon";
  11438. + interrupts = <0 49 0x04>;
  11439. + fsl,tempmon = <&anatop>;
  11440. + fsl,tempmon-data = <&ocotp>;
  11441. + clocks = <&clks IMX6SL_CLK_PLL3_USB_OTG>;
  11442. + };
  11443. +
  11444. usbphy1: usbphy@020c9000 {
  11445. compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
  11446. reg = <0x020c9000 0x1000>;
  11447. - interrupts = <0 44 0x04>;
  11448. + interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
  11449. clocks = <&clks IMX6SL_CLK_USBPHY1>;
  11450. + fsl,anatop = <&anatop>;
  11451. };
  11452. usbphy2: usbphy@020ca000 {
  11453. compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
  11454. reg = <0x020ca000 0x1000>;
  11455. - interrupts = <0 45 0x04>;
  11456. + interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
  11457. clocks = <&clks IMX6SL_CLK_USBPHY2>;
  11458. + fsl,anatop = <&anatop>;
  11459. + };
  11460. +
  11461. + usbphy_nop1: usbphy_nop1 {
  11462. + compatible = "usb-nop-xceiv";
  11463. + clocks = <&clks IMX6SL_CLK_USBPHY1>;
  11464. + clock-names = "main_clk";
  11465. };
  11466. snvs@020cc000 {
  11467. @@ -507,271 +593,165 @@
  11468. snvs-rtc-lp@34 {
  11469. compatible = "fsl,sec-v4.0-mon-rtc-lp";
  11470. reg = <0x34 0x58>;
  11471. - interrupts = <0 19 0x04 0 20 0x04>;
  11472. + interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
  11473. + <0 20 IRQ_TYPE_LEVEL_HIGH>;
  11474. };
  11475. - };
  11476. -
  11477. - epit1: epit@020d0000 {
  11478. - reg = <0x020d0000 0x4000>;
  11479. - interrupts = <0 56 0x04>;
  11480. - };
  11481. - epit2: epit@020d4000 {
  11482. - reg = <0x020d4000 0x4000>;
  11483. - interrupts = <0 57 0x04>;
  11484. - };
  11485. -
  11486. - src: src@020d8000 {
  11487. - compatible = "fsl,imx6sl-src", "fsl,imx51-src";
  11488. - reg = <0x020d8000 0x4000>;
  11489. - interrupts = <0 91 0x04 0 96 0x04>;
  11490. - #reset-cells = <1>;
  11491. - };
  11492. -
  11493. - gpc: gpc@020dc000 {
  11494. - compatible = "fsl,imx6sl-gpc", "fsl,imx6q-gpc";
  11495. - reg = <0x020dc000 0x4000>;
  11496. - interrupts = <0 89 0x04>;
  11497. - };
  11498. -
  11499. - gpr: iomuxc-gpr@020e0000 {
  11500. - compatible = "fsl,imx6sl-iomuxc-gpr",
  11501. - "fsl,imx6q-iomuxc-gpr", "syscon";
  11502. - reg = <0x020e0000 0x38>;
  11503. - };
  11504. -
  11505. - iomuxc: iomuxc@020e0000 {
  11506. - compatible = "fsl,imx6sl-iomuxc";
  11507. - reg = <0x020e0000 0x4000>;
  11508. -
  11509. - ecspi1 {
  11510. - pinctrl_ecspi1_1: ecspi1grp-1 {
  11511. + csi {
  11512. + pinctrl_csi_0: csigrp-0 {
  11513. fsl,pins = <
  11514. - MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
  11515. - MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
  11516. - MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
  11517. + MX6SL_PAD_EPDC_GDRL__CSI_MCLK 0x110b0
  11518. + MX6SL_PAD_EPDC_GDCLK__CSI_PIXCLK 0x110b0
  11519. + MX6SL_PAD_EPDC_GDSP__CSI_VSYNC 0x110b0
  11520. + MX6SL_PAD_EPDC_GDOE__CSI_HSYNC 0x110b0
  11521. + MX6SL_PAD_EPDC_SDLE__CSI_DATA09 0x110b0
  11522. + MX6SL_PAD_EPDC_SDCLK__CSI_DATA08 0x110b0
  11523. + MX6SL_PAD_EPDC_D7__CSI_DATA07 0x110b0
  11524. + MX6SL_PAD_EPDC_D6__CSI_DATA06 0x110b0
  11525. + MX6SL_PAD_EPDC_D5__CSI_DATA05 0x110b0
  11526. + MX6SL_PAD_EPDC_D4__CSI_DATA04 0x110b0
  11527. + MX6SL_PAD_EPDC_D3__CSI_DATA03 0x110b0
  11528. + MX6SL_PAD_EPDC_D2__CSI_DATA02 0x110b0
  11529. + MX6SL_PAD_EPDC_D1__CSI_DATA01 0x110b0
  11530. + MX6SL_PAD_EPDC_D0__CSI_DATA00 0x110b0
  11531. + MX6SL_PAD_EPDC_SDSHR__GPIO1_IO26 0x80000000
  11532. + MX6SL_PAD_EPDC_SDOE__GPIO1_IO25 0x80000000
  11533. >;
  11534. };
  11535. };
  11536. - fec {
  11537. - pinctrl_fec_1: fecgrp-1 {
  11538. + i2c1 {
  11539. + pinctrl_i2c1_1: i2c1grp-1 {
  11540. fsl,pins = <
  11541. - MX6SL_PAD_FEC_MDC__FEC_MDC 0x1b0b0
  11542. - MX6SL_PAD_FEC_MDIO__FEC_MDIO 0x1b0b0
  11543. - MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV 0x1b0b0
  11544. - MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0 0x1b0b0
  11545. - MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1 0x1b0b0
  11546. - MX6SL_PAD_FEC_TX_EN__FEC_TX_EN 0x1b0b0
  11547. - MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0 0x1b0b0
  11548. - MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1 0x1b0b0
  11549. - MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x4001b0a8
  11550. + MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1
  11551. + MX6SL_PAD_I2C1_SDA__I2C1_SDA 0x4001b8b1
  11552. >;
  11553. };
  11554. };
  11555. - uart1 {
  11556. - pinctrl_uart1_1: uart1grp-1 {
  11557. + i2c2 {
  11558. + pinctrl_i2c2_1: i2c2grp-1 {
  11559. fsl,pins = <
  11560. - MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x1b0b1
  11561. - MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1
  11562. + MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x4001b8b1
  11563. + MX6SL_PAD_I2C2_SDA__I2C2_SDA 0x4001b8b1
  11564. >;
  11565. };
  11566. };
  11567. - usbotg1 {
  11568. - pinctrl_usbotg1_1: usbotg1grp-1 {
  11569. - fsl,pins = <
  11570. - MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059
  11571. - >;
  11572. - };
  11573. -
  11574. - pinctrl_usbotg1_2: usbotg1grp-2 {
  11575. + i2c3 {
  11576. + pinctrl_i2c3_1: i2c3grp-1 {
  11577. fsl,pins = <
  11578. - MX6SL_PAD_FEC_RXD0__USB_OTG1_ID 0x17059
  11579. - >;
  11580. - };
  11581. -
  11582. - pinctrl_usbotg1_3: usbotg1grp-3 {
  11583. - fsl,pins = <
  11584. - MX6SL_PAD_LCD_DAT1__USB_OTG1_ID 0x17059
  11585. - >;
  11586. - };
  11587. -
  11588. - pinctrl_usbotg1_4: usbotg1grp-4 {
  11589. - fsl,pins = <
  11590. - MX6SL_PAD_REF_CLK_32K__USB_OTG1_ID 0x17059
  11591. - >;
  11592. - };
  11593. -
  11594. - pinctrl_usbotg1_5: usbotg1grp-5 {
  11595. - fsl,pins = <
  11596. - MX6SL_PAD_SD3_DAT0__USB_OTG1_ID 0x17059
  11597. + MX6SL_PAD_EPDC_SDCE2__I2C3_SCL 0x4001b8b1
  11598. + MX6SL_PAD_EPDC_SDCE3__I2C3_SDA 0x4001b8b1
  11599. >;
  11600. };
  11601. };
  11602. - usbotg2 {
  11603. - pinctrl_usbotg2_1: usbotg2grp-1 {
  11604. - fsl,pins = <
  11605. - MX6SL_PAD_ECSPI1_SCLK__USB_OTG2_OC 0x17059
  11606. - >;
  11607. - };
  11608. -
  11609. - pinctrl_usbotg2_2: usbotg2grp-2 {
  11610. + lcdif {
  11611. + pinctrl_lcdif_dat_0: lcdifdatgrp-0 {
  11612. fsl,pins = <
  11613. - MX6SL_PAD_ECSPI2_SCLK__USB_OTG2_OC 0x17059
  11614. + MX6SL_PAD_LCD_DAT0__LCD_DATA00 0x1b0b0
  11615. + MX6SL_PAD_LCD_DAT1__LCD_DATA01 0x1b0b0
  11616. + MX6SL_PAD_LCD_DAT2__LCD_DATA02 0x1b0b0
  11617. + MX6SL_PAD_LCD_DAT3__LCD_DATA03 0x1b0b0
  11618. + MX6SL_PAD_LCD_DAT4__LCD_DATA04 0x1b0b0
  11619. + MX6SL_PAD_LCD_DAT5__LCD_DATA05 0x1b0b0
  11620. + MX6SL_PAD_LCD_DAT6__LCD_DATA06 0x1b0b0
  11621. + MX6SL_PAD_LCD_DAT7__LCD_DATA07 0x1b0b0
  11622. + MX6SL_PAD_LCD_DAT8__LCD_DATA08 0x1b0b0
  11623. + MX6SL_PAD_LCD_DAT9__LCD_DATA09 0x1b0b0
  11624. + MX6SL_PAD_LCD_DAT10__LCD_DATA10 0x1b0b0
  11625. + MX6SL_PAD_LCD_DAT11__LCD_DATA11 0x1b0b0
  11626. + MX6SL_PAD_LCD_DAT12__LCD_DATA12 0x1b0b0
  11627. + MX6SL_PAD_LCD_DAT13__LCD_DATA13 0x1b0b0
  11628. + MX6SL_PAD_LCD_DAT14__LCD_DATA14 0x1b0b0
  11629. + MX6SL_PAD_LCD_DAT15__LCD_DATA15 0x1b0b0
  11630. + MX6SL_PAD_LCD_DAT16__LCD_DATA16 0x1b0b0
  11631. + MX6SL_PAD_LCD_DAT17__LCD_DATA17 0x1b0b0
  11632. + MX6SL_PAD_LCD_DAT18__LCD_DATA18 0x1b0b0
  11633. + MX6SL_PAD_LCD_DAT19__LCD_DATA19 0x1b0b0
  11634. + MX6SL_PAD_LCD_DAT20__LCD_DATA20 0x1b0b0
  11635. + MX6SL_PAD_LCD_DAT21__LCD_DATA21 0x1b0b0
  11636. + MX6SL_PAD_LCD_DAT22__LCD_DATA22 0x1b0b0
  11637. + MX6SL_PAD_LCD_DAT23__LCD_DATA23 0x1b0b0
  11638. >;
  11639. };
  11640. - pinctrl_usbotg2_3: usbotg2grp-3 {
  11641. + pinctrl_lcdif_ctrl_0: lcdifctrlgrp-0 {
  11642. fsl,pins = <
  11643. - MX6SL_PAD_KEY_ROW5__USB_OTG2_OC 0x17059
  11644. - >;
  11645. - };
  11646. -
  11647. - pinctrl_usbotg2_4: usbotg2grp-4 {
  11648. - fsl,pins = <
  11649. - MX6SL_PAD_SD3_DAT2__USB_OTG2_OC 0x17059
  11650. + MX6SL_PAD_LCD_CLK__LCD_CLK 0x1b0b0
  11651. + MX6SL_PAD_LCD_ENABLE__LCD_ENABLE 0x1b0b0
  11652. + MX6SL_PAD_LCD_HSYNC__LCD_HSYNC 0x1b0b0
  11653. + MX6SL_PAD_LCD_VSYNC__LCD_VSYNC 0x1b0b0
  11654. + MX6SL_PAD_LCD_RESET__LCD_RESET 0x1b0b0
  11655. >;
  11656. };
  11657. };
  11658. - usdhc1 {
  11659. - pinctrl_usdhc1_1: usdhc1grp-1 {
  11660. + pwm1 {
  11661. + pinctrl_pwm1_0: pwm1grp-0 {
  11662. fsl,pins = <
  11663. - MX6SL_PAD_SD1_CMD__SD1_CMD 0x17059
  11664. - MX6SL_PAD_SD1_CLK__SD1_CLK 0x10059
  11665. - MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  11666. - MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  11667. - MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  11668. - MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  11669. - MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x17059
  11670. - MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x17059
  11671. - MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x17059
  11672. - MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x17059
  11673. + MX6SL_PAD_PWM1__PWM1_OUT 0x110b0
  11674. >;
  11675. };
  11676. -
  11677. - pinctrl_usdhc1_1_100mhz: usdhc1grp-1-100mhz {
  11678. - fsl,pins = <
  11679. - MX6SL_PAD_SD1_CMD__SD1_CMD 0x170b9
  11680. - MX6SL_PAD_SD1_CLK__SD1_CLK 0x100b9
  11681. - MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170b9
  11682. - MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170b9
  11683. - MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170b9
  11684. - MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170b9
  11685. - MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170b9
  11686. - MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170b9
  11687. - MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170b9
  11688. - MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170b9
  11689. - >;
  11690. - };
  11691. -
  11692. - pinctrl_usdhc1_1_200mhz: usdhc1grp-1-200mhz {
  11693. - fsl,pins = <
  11694. - MX6SL_PAD_SD1_CMD__SD1_CMD 0x170f9
  11695. - MX6SL_PAD_SD1_CLK__SD1_CLK 0x100f9
  11696. - MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
  11697. - MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
  11698. - MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
  11699. - MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
  11700. - MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170f9
  11701. - MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170f9
  11702. - MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170f9
  11703. - MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170f9
  11704. - >;
  11705. - };
  11706. -
  11707. -
  11708. };
  11709. + };
  11710. - usdhc2 {
  11711. - pinctrl_usdhc2_1: usdhc2grp-1 {
  11712. - fsl,pins = <
  11713. - MX6SL_PAD_SD2_CMD__SD2_CMD 0x17059
  11714. - MX6SL_PAD_SD2_CLK__SD2_CLK 0x10059
  11715. - MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  11716. - MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  11717. - MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  11718. - MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  11719. - >;
  11720. - };
  11721. -
  11722. - pinctrl_usdhc2_1_100mhz: usdhc2grp-1-100mhz {
  11723. - fsl,pins = <
  11724. - MX6SL_PAD_SD2_CMD__SD2_CMD 0x170b9
  11725. - MX6SL_PAD_SD2_CLK__SD2_CLK 0x100b9
  11726. - MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
  11727. - MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
  11728. - MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
  11729. - MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170b9
  11730. - >;
  11731. - };
  11732. + epit1: epit@020d0000 {
  11733. + reg = <0x020d0000 0x4000>;
  11734. + interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
  11735. + };
  11736. - pinctrl_usdhc2_1_200mhz: usdhc2grp-1-200mhz {
  11737. - fsl,pins = <
  11738. - MX6SL_PAD_SD2_CMD__SD2_CMD 0x170f9
  11739. - MX6SL_PAD_SD2_CLK__SD2_CLK 0x100f9
  11740. - MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
  11741. - MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
  11742. - MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
  11743. - MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170f9
  11744. - >;
  11745. - };
  11746. + epit2: epit@020d4000 {
  11747. + reg = <0x020d4000 0x4000>;
  11748. + interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
  11749. + };
  11750. - };
  11751. + src: src@020d8000 {
  11752. + compatible = "fsl,imx6sl-src", "fsl,imx51-src";
  11753. + reg = <0x020d8000 0x4000>;
  11754. + interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
  11755. + <0 96 IRQ_TYPE_LEVEL_HIGH>;
  11756. + #reset-cells = <1>;
  11757. + };
  11758. - usdhc3 {
  11759. - pinctrl_usdhc3_1: usdhc3grp-1 {
  11760. - fsl,pins = <
  11761. - MX6SL_PAD_SD3_CMD__SD3_CMD 0x17059
  11762. - MX6SL_PAD_SD3_CLK__SD3_CLK 0x10059
  11763. - MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  11764. - MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  11765. - MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  11766. - MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  11767. - >;
  11768. - };
  11769. + gpc: gpc@020dc000 {
  11770. + compatible = "fsl,imx6sl-gpc", "fsl,imx6q-gpc";
  11771. + reg = <0x020dc000 0x4000>;
  11772. + interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
  11773. + clocks = <&clks IMX6SL_CLK_GPU2D_PODF>, <&clks IMX6SL_CLK_GPU2D_OVG>,
  11774. + <&clks IMX6SL_CLK_IPG>;
  11775. + clock-names = "gpu2d_podf", "gpu2d_ovg", "ipg";
  11776. + pu-supply = <&reg_pu>;
  11777. + };
  11778. - pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz {
  11779. - fsl,pins = <
  11780. - MX6SL_PAD_SD3_CMD__SD3_CMD 0x170b9
  11781. - MX6SL_PAD_SD3_CLK__SD3_CLK 0x100b9
  11782. - MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  11783. - MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  11784. - MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  11785. - MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  11786. - >;
  11787. - };
  11788. + gpr: iomuxc-gpr@020e0000 {
  11789. + compatible = "fsl,imx6sl-iomuxc-gpr",
  11790. + "fsl,imx6q-iomuxc-gpr", "syscon";
  11791. + reg = <0x020e0000 0x38>;
  11792. + };
  11793. - pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz {
  11794. - fsl,pins = <
  11795. - MX6SL_PAD_SD3_CMD__SD3_CMD 0x170f9
  11796. - MX6SL_PAD_SD3_CLK__SD3_CLK 0x100f9
  11797. - MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  11798. - MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  11799. - MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  11800. - MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  11801. - >;
  11802. - };
  11803. - };
  11804. + iomuxc: iomuxc@020e0000 {
  11805. + compatible = "fsl,imx6sl-iomuxc";
  11806. + reg = <0x020e0000 0x4000>;
  11807. };
  11808. csi: csi@020e4000 {
  11809. + compatible = "fsl,imx6sl-csi";
  11810. reg = <0x020e4000 0x4000>;
  11811. - interrupts = <0 7 0x04>;
  11812. + interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
  11813. + status = "disabled";
  11814. };
  11815. spdc: spdc@020e8000 {
  11816. reg = <0x020e8000 0x4000>;
  11817. - interrupts = <0 6 0x04>;
  11818. + interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
  11819. };
  11820. sdma: sdma@020ec000 {
  11821. compatible = "fsl,imx6sl-sdma", "fsl,imx35-sdma";
  11822. reg = <0x020ec000 0x4000>;
  11823. - interrupts = <0 2 0x04>;
  11824. + interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
  11825. clocks = <&clks IMX6SL_CLK_SDMA>,
  11826. <&clks IMX6SL_CLK_SDMA>;
  11827. clock-names = "ipg", "ahb";
  11828. @@ -781,23 +761,32 @@
  11829. };
  11830. pxp: pxp@020f0000 {
  11831. + compatible = "fsl,imx6sl-pxp-dma", "fsl,imx6dl-pxp-dma";
  11832. reg = <0x020f0000 0x4000>;
  11833. - interrupts = <0 98 0x04>;
  11834. + interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
  11835. + clocks = <&clks 111>;
  11836. + clock-names = "pxp-axi";
  11837. + status = "disabled";
  11838. };
  11839. epdc: epdc@020f4000 {
  11840. reg = <0x020f4000 0x4000>;
  11841. - interrupts = <0 97 0x04>;
  11842. + interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
  11843. };
  11844. lcdif: lcdif@020f8000 {
  11845. + compatible = "fsl,imx6sl-lcdif", "fsl,imx28-lcdif";
  11846. reg = <0x020f8000 0x4000>;
  11847. - interrupts = <0 39 0x04>;
  11848. + interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
  11849. + clocks = <&clks IMX6SL_CLK_LCDIF_PIX>,
  11850. + <&clks IMX6SL_CLK_LCDIF_AXI>;
  11851. + clock-names = "pix", "axi";
  11852. + status = "disabled";
  11853. };
  11854. dcp: dcp@020fc000 {
  11855. reg = <0x020fc000 0x4000>;
  11856. - interrupts = <0 99 0x04>;
  11857. + interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>;
  11858. };
  11859. };
  11860. @@ -811,7 +800,7 @@
  11861. usbotg1: usb@02184000 {
  11862. compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
  11863. reg = <0x02184000 0x200>;
  11864. - interrupts = <0 43 0x04>;
  11865. + interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
  11866. clocks = <&clks IMX6SL_CLK_USBOH3>;
  11867. fsl,usbphy = <&usbphy1>;
  11868. fsl,usbmisc = <&usbmisc 0>;
  11869. @@ -821,7 +810,7 @@
  11870. usbotg2: usb@02184200 {
  11871. compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
  11872. reg = <0x02184200 0x200>;
  11873. - interrupts = <0 42 0x04>;
  11874. + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
  11875. clocks = <&clks IMX6SL_CLK_USBOH3>;
  11876. fsl,usbphy = <&usbphy2>;
  11877. fsl,usbmisc = <&usbmisc 1>;
  11878. @@ -831,9 +820,12 @@
  11879. usbh: usb@02184400 {
  11880. compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
  11881. reg = <0x02184400 0x200>;
  11882. - interrupts = <0 40 0x04>;
  11883. + interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
  11884. clocks = <&clks IMX6SL_CLK_USBOH3>;
  11885. fsl,usbmisc = <&usbmisc 2>;
  11886. + phy_type = "hsic";
  11887. + fsl,usbphy = <&usbphy_nop1>;
  11888. + fsl,anatop = <&anatop>;
  11889. status = "disabled";
  11890. };
  11891. @@ -847,7 +839,7 @@
  11892. fec: ethernet@02188000 {
  11893. compatible = "fsl,imx6sl-fec", "fsl,imx25-fec";
  11894. reg = <0x02188000 0x4000>;
  11895. - interrupts = <0 114 0x04>;
  11896. + interrupts = <0 114 IRQ_TYPE_LEVEL_HIGH>;
  11897. clocks = <&clks IMX6SL_CLK_ENET_REF>,
  11898. <&clks IMX6SL_CLK_ENET_REF>;
  11899. clock-names = "ipg", "ahb";
  11900. @@ -857,7 +849,7 @@
  11901. usdhc1: usdhc@02190000 {
  11902. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11903. reg = <0x02190000 0x4000>;
  11904. - interrupts = <0 22 0x04>;
  11905. + interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
  11906. clocks = <&clks IMX6SL_CLK_USDHC1>,
  11907. <&clks IMX6SL_CLK_USDHC1>,
  11908. <&clks IMX6SL_CLK_USDHC1>;
  11909. @@ -869,7 +861,7 @@
  11910. usdhc2: usdhc@02194000 {
  11911. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11912. reg = <0x02194000 0x4000>;
  11913. - interrupts = <0 23 0x04>;
  11914. + interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
  11915. clocks = <&clks IMX6SL_CLK_USDHC2>,
  11916. <&clks IMX6SL_CLK_USDHC2>,
  11917. <&clks IMX6SL_CLK_USDHC2>;
  11918. @@ -881,7 +873,7 @@
  11919. usdhc3: usdhc@02198000 {
  11920. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11921. reg = <0x02198000 0x4000>;
  11922. - interrupts = <0 24 0x04>;
  11923. + interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
  11924. clocks = <&clks IMX6SL_CLK_USDHC3>,
  11925. <&clks IMX6SL_CLK_USDHC3>,
  11926. <&clks IMX6SL_CLK_USDHC3>;
  11927. @@ -893,7 +885,7 @@
  11928. usdhc4: usdhc@0219c000 {
  11929. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11930. reg = <0x0219c000 0x4000>;
  11931. - interrupts = <0 25 0x04>;
  11932. + interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
  11933. clocks = <&clks IMX6SL_CLK_USDHC4>,
  11934. <&clks IMX6SL_CLK_USDHC4>,
  11935. <&clks IMX6SL_CLK_USDHC4>;
  11936. @@ -907,7 +899,7 @@
  11937. #size-cells = <0>;
  11938. compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
  11939. reg = <0x021a0000 0x4000>;
  11940. - interrupts = <0 36 0x04>;
  11941. + interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
  11942. clocks = <&clks IMX6SL_CLK_I2C1>;
  11943. status = "disabled";
  11944. };
  11945. @@ -917,7 +909,7 @@
  11946. #size-cells = <0>;
  11947. compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
  11948. reg = <0x021a4000 0x4000>;
  11949. - interrupts = <0 37 0x04>;
  11950. + interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
  11951. clocks = <&clks IMX6SL_CLK_I2C2>;
  11952. status = "disabled";
  11953. };
  11954. @@ -927,7 +919,7 @@
  11955. #size-cells = <0>;
  11956. compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
  11957. reg = <0x021a8000 0x4000>;
  11958. - interrupts = <0 38 0x04>;
  11959. + interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
  11960. clocks = <&clks IMX6SL_CLK_I2C3>;
  11961. status = "disabled";
  11962. };
  11963. @@ -939,17 +931,23 @@
  11964. rngb: rngb@021b4000 {
  11965. reg = <0x021b4000 0x4000>;
  11966. - interrupts = <0 5 0x04>;
  11967. + interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
  11968. };
  11969. weim: weim@021b8000 {
  11970. reg = <0x021b8000 0x4000>;
  11971. - interrupts = <0 14 0x04>;
  11972. + interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
  11973. + };
  11974. +
  11975. + ocotp: ocotp-ctrl@021bc000 {
  11976. + compatible = "syscon";
  11977. + reg = <0x021bc000 0x4000>;
  11978. };
  11979. - ocotp: ocotp@021bc000 {
  11980. - compatible = "fsl,imx6sl-ocotp";
  11981. + ocotp-fuse@021bc000 {
  11982. + compatible = "fsl,imx6sl-ocotp", "fsl,imx6q-ocotp";
  11983. reg = <0x021bc000 0x4000>;
  11984. + clocks = <&clks IMX6SL_CLK_OCOTP>;
  11985. };
  11986. audmux: audmux@021d8000 {
  11987. @@ -957,6 +955,25 @@
  11988. reg = <0x021d8000 0x4000>;
  11989. status = "disabled";
  11990. };
  11991. +
  11992. + gpu: gpu@02200000 {
  11993. + compatible = "fsl,imx6sl-gpu", "fsl,imx6q-gpu";
  11994. + reg = <0x02200000 0x4000>, <0x02204000 0x4000>,
  11995. + <0x80000000 0x0>;
  11996. + reg-names = "iobase_2d", "iobase_vg",
  11997. + "phys_baseaddr";
  11998. + interrupts = <0 10 0x04>, <0 11 0x04>;
  11999. + interrupt-names = "irq_2d", "irq_vg";
  12000. + clocks = <&clks IMX6SL_CLK_MMDC_ROOT>,
  12001. + <&clks IMX6SL_CLK_MMDC_ROOT>,
  12002. + <&clks IMX6SL_CLK_GPU2D_OVG>;
  12003. + clock-names = "gpu2d_axi_clk", "openvg_axi_clk",
  12004. + "gpu2d_clk";
  12005. + resets = <&src 3>, <&src 3>;
  12006. + reset-names = "gpu2d", "gpuvg";
  12007. + pu-supply = <&reg_pu>;
  12008. + };
  12009. +
  12010. };
  12011. };
  12012. };
  12013. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6sl-evk-csi.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6sl-evk-csi.dts
  12014. --- linux-3.14.15/arch/arm/boot/dts/imx6sl-evk-csi.dts 1970-01-01 01:00:00.000000000 +0100
  12015. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6sl-evk-csi.dts 2014-08-20 19:23:45.546811635 +0200
  12016. @@ -0,0 +1,27 @@
  12017. +/*
  12018. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  12019. + *
  12020. + * This program is free software; you can redistribute it and/or modify
  12021. + * it under the terms of the GNU General Public License version 2 as
  12022. + * published by the Free Software Foundation.
  12023. + */
  12024. +
  12025. +#include "imx6sl-evk.dts"
  12026. +
  12027. +/ {
  12028. + csi_v4l2_cap {
  12029. + status = "okay";
  12030. + };
  12031. +};
  12032. +
  12033. +&csi {
  12034. + status = "okay";
  12035. +};
  12036. +
  12037. +&i2c3 {
  12038. + status = "okay";
  12039. +};
  12040. +
  12041. +&epdc {
  12042. + status = "disabled";
  12043. +};
  12044. diff -Nur linux-3.14.15/arch/arm/boot/dts/imx6sl-evk.dts linux-linaro-stable-mx6/arch/arm/boot/dts/imx6sl-evk.dts
  12045. --- linux-3.14.15/arch/arm/boot/dts/imx6sl-evk.dts 2014-07-31 23:51:43.000000000 +0200
  12046. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/imx6sl-evk.dts 2014-08-20 19:31:39.904842290 +0200
  12047. @@ -8,6 +8,8 @@
  12048. /dts-v1/;
  12049. +#include <dt-bindings/gpio/gpio.h>
  12050. +#include <dt-bindings/input/input.h>
  12051. #include "imx6sl.dtsi"
  12052. / {
  12053. @@ -18,11 +20,26 @@
  12054. reg = <0x80000000 0x40000000>;
  12055. };
  12056. + leds {
  12057. + compatible = "gpio-leds";
  12058. + pinctrl-names = "default";
  12059. + pinctrl-0 = <&pinctrl_led>;
  12060. +
  12061. + user {
  12062. + label = "debug";
  12063. + gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
  12064. + linux,default-trigger = "heartbeat";
  12065. + };
  12066. + };
  12067. +
  12068. regulators {
  12069. compatible = "simple-bus";
  12070. + #address-cells = <1>;
  12071. + #size-cells = <0>;
  12072. - reg_usb_otg1_vbus: usb_otg1_vbus {
  12073. + reg_usb_otg1_vbus: regulator@0 {
  12074. compatible = "regulator-fixed";
  12075. + reg = <0>;
  12076. regulator-name = "usb_otg1_vbus";
  12077. regulator-min-microvolt = <5000000>;
  12078. regulator-max-microvolt = <5000000>;
  12079. @@ -30,22 +47,63 @@
  12080. enable-active-high;
  12081. };
  12082. - reg_usb_otg2_vbus: usb_otg2_vbus {
  12083. + reg_usb_otg2_vbus: regulator@1 {
  12084. compatible = "regulator-fixed";
  12085. + reg = <1>;
  12086. regulator-name = "usb_otg2_vbus";
  12087. regulator-min-microvolt = <5000000>;
  12088. regulator-max-microvolt = <5000000>;
  12089. gpio = <&gpio4 2 0>;
  12090. enable-active-high;
  12091. };
  12092. +
  12093. + reg_aud3v: regulator@2 {
  12094. + compatible = "regulator-fixed";
  12095. + reg = <2>;
  12096. + regulator-name = "wm8962-supply-3v15";
  12097. + regulator-min-microvolt = <3150000>;
  12098. + regulator-max-microvolt = <3150000>;
  12099. + regulator-boot-on;
  12100. + };
  12101. +
  12102. + reg_aud4v: regulator@3 {
  12103. + compatible = "regulator-fixed";
  12104. + reg = <3>;
  12105. + regulator-name = "wm8962-supply-4v2";
  12106. + regulator-min-microvolt = <4325000>;
  12107. + regulator-max-microvolt = <4325000>;
  12108. + regulator-boot-on;
  12109. + };
  12110. };
  12111. +
  12112. + sound {
  12113. + compatible = "fsl,imx6sl-evk-wm8962", "fsl,imx-audio-wm8962";
  12114. + model = "wm8962-audio";
  12115. + ssi-controller = <&ssi2>;
  12116. + audio-codec = <&codec>;
  12117. + audio-routing =
  12118. + "Headphone Jack", "HPOUTL",
  12119. + "Headphone Jack", "HPOUTR",
  12120. + "Ext Spk", "SPKOUTL",
  12121. + "Ext Spk", "SPKOUTR",
  12122. + "AMIC", "MICBIAS",
  12123. + "IN3R", "AMIC";
  12124. + mux-int-port = <2>;
  12125. + mux-ext-port = <3>;
  12126. + };
  12127. +};
  12128. +
  12129. +&audmux {
  12130. + pinctrl-names = "default";
  12131. + pinctrl-0 = <&pinctrl_audmux3>;
  12132. + status = "okay";
  12133. };
  12134. &ecspi1 {
  12135. fsl,spi-num-chipselects = <1>;
  12136. cs-gpios = <&gpio4 11 0>;
  12137. pinctrl-names = "default";
  12138. - pinctrl-0 = <&pinctrl_ecspi1_1>;
  12139. + pinctrl-0 = <&pinctrl_ecspi1>;
  12140. status = "okay";
  12141. flash: m25p80@0 {
  12142. @@ -57,18 +115,326 @@
  12143. };
  12144. };
  12145. +&csi {
  12146. + status = "okay";
  12147. +};
  12148. +
  12149. +&cpu0 {
  12150. + arm-supply = <&sw1a_reg>;
  12151. + soc-supply = <&sw1c_reg>;
  12152. + pu-supply = <&pu_dummy>; /* use pu_dummy if VDDSOC share with VDDPU */
  12153. +};
  12154. +
  12155. &fec {
  12156. pinctrl-names = "default";
  12157. - pinctrl-0 = <&pinctrl_fec_1>;
  12158. + pinctrl-0 = <&pinctrl_fec>;
  12159. phy-mode = "rmii";
  12160. status = "okay";
  12161. };
  12162. +&i2c1 {
  12163. + clock-frequency = <100000>;
  12164. + pinctrl-names = "default";
  12165. + pinctrl-0 = <&pinctrl_i2c1>;
  12166. + status = "okay";
  12167. +
  12168. + pmic: pfuze100@08 {
  12169. + compatible = "fsl,pfuze100";
  12170. + reg = <0x08>;
  12171. +
  12172. + regulators {
  12173. + sw1a_reg: sw1ab {
  12174. + regulator-min-microvolt = <300000>;
  12175. + regulator-max-microvolt = <1875000>;
  12176. + regulator-boot-on;
  12177. + regulator-always-on;
  12178. + regulator-ramp-delay = <6250>;
  12179. + };
  12180. +
  12181. + sw1c_reg: sw1c {
  12182. + regulator-min-microvolt = <300000>;
  12183. + regulator-max-microvolt = <1875000>;
  12184. + regulator-boot-on;
  12185. + regulator-always-on;
  12186. + regulator-ramp-delay = <6250>;
  12187. + };
  12188. +
  12189. + sw2_reg: sw2 {
  12190. + regulator-min-microvolt = <800000>;
  12191. + regulator-max-microvolt = <3300000>;
  12192. + regulator-boot-on;
  12193. + regulator-always-on;
  12194. + };
  12195. +
  12196. + sw3a_reg: sw3a {
  12197. + regulator-min-microvolt = <400000>;
  12198. + regulator-max-microvolt = <1975000>;
  12199. + regulator-boot-on;
  12200. + regulator-always-on;
  12201. + };
  12202. +
  12203. + sw3b_reg: sw3b {
  12204. + regulator-min-microvolt = <400000>;
  12205. + regulator-max-microvolt = <1975000>;
  12206. + regulator-boot-on;
  12207. + regulator-always-on;
  12208. + };
  12209. +
  12210. + sw4_reg: sw4 {
  12211. + regulator-min-microvolt = <800000>;
  12212. + regulator-max-microvolt = <3300000>;
  12213. + };
  12214. +
  12215. + swbst_reg: swbst {
  12216. + regulator-min-microvolt = <5000000>;
  12217. + regulator-max-microvolt = <5150000>;
  12218. + };
  12219. +
  12220. + snvs_reg: vsnvs {
  12221. + regulator-min-microvolt = <1000000>;
  12222. + regulator-max-microvolt = <3000000>;
  12223. + regulator-boot-on;
  12224. + regulator-always-on;
  12225. + };
  12226. +
  12227. + vref_reg: vrefddr {
  12228. + regulator-boot-on;
  12229. + regulator-always-on;
  12230. + };
  12231. +
  12232. + vgen1_reg: vgen1 {
  12233. + regulator-min-microvolt = <800000>;
  12234. + regulator-max-microvolt = <1550000>;
  12235. + regulator-always-on;
  12236. + };
  12237. +
  12238. + vgen2_reg: vgen2 {
  12239. + regulator-min-microvolt = <800000>;
  12240. + regulator-max-microvolt = <1550000>;
  12241. + };
  12242. +
  12243. + vgen3_reg: vgen3 {
  12244. + regulator-min-microvolt = <1800000>;
  12245. + regulator-max-microvolt = <3300000>;
  12246. + };
  12247. +
  12248. + vgen4_reg: vgen4 {
  12249. + regulator-min-microvolt = <1800000>;
  12250. + regulator-max-microvolt = <3300000>;
  12251. + regulator-always-on;
  12252. + };
  12253. +
  12254. + vgen5_reg: vgen5 {
  12255. + regulator-min-microvolt = <1800000>;
  12256. + regulator-max-microvolt = <3300000>;
  12257. + regulator-always-on;
  12258. + };
  12259. +
  12260. + vgen6_reg: vgen6 {
  12261. + regulator-min-microvolt = <1800000>;
  12262. + regulator-max-microvolt = <3300000>;
  12263. + regulator-always-on;
  12264. + };
  12265. + };
  12266. + };
  12267. +
  12268. + regulators {
  12269. + compatible = "simple-bus";
  12270. +
  12271. + reg_lcd_3v3: lcd-3v3 {
  12272. + compatible = "regulator-fixed";
  12273. + regulator-name = "lcd-3v3";
  12274. + gpio = <&gpio4 3 0>;
  12275. + enable-active-high;
  12276. + };
  12277. + };
  12278. +
  12279. + backlight {
  12280. + compatible = "pwm-backlight";
  12281. + pwms = <&pwm1 0 5000000>;
  12282. + brightness-levels = <0 4 8 16 32 64 128 255>;
  12283. + default-brightness-level = <6>;
  12284. + };
  12285. +
  12286. + csi_v4l2_cap {
  12287. + compatible = "fsl,imx6sl-csi-v4l2";
  12288. + status = "okay";
  12289. + };
  12290. +
  12291. + pxp_v4l2_out {
  12292. + compatible = "fsl,imx6sl-pxp-v4l2";
  12293. + status = "okay";
  12294. + };
  12295. +};
  12296. +
  12297. +&i2c2 {
  12298. + clock-frequency = <100000>;
  12299. + pinctrl-names = "default";
  12300. + pinctrl-0 = <&pinctrl_i2c2>;
  12301. + status = "okay";
  12302. +
  12303. + codec: wm8962@1a {
  12304. + compatible = "wlf,wm8962";
  12305. + reg = <0x1a>;
  12306. + clocks = <&clks IMX6SL_CLK_EXTERN_AUDIO>;
  12307. + DCVDD-supply = <&vgen3_reg>;
  12308. + DBVDD-supply = <&reg_aud3v>;
  12309. + AVDD-supply = <&vgen3_reg>;
  12310. + CPVDD-supply = <&vgen3_reg>;
  12311. + MICVDD-supply = <&reg_aud3v>;
  12312. + PLLVDD-supply = <&vgen3_reg>;
  12313. + SPKVDD1-supply = <&reg_aud4v>;
  12314. + SPKVDD2-supply = <&reg_aud4v>;
  12315. + };
  12316. +};
  12317. +
  12318. +&i2c1 {
  12319. + clock-frequency = <100000>;
  12320. + pinctrl-names = "default";
  12321. + pinctrl-0 = <&pinctrl_i2c1_1>;
  12322. + status = "okay";
  12323. +
  12324. + pmic: pfuze100@08 {
  12325. + compatible = "fsl,pfuze100";
  12326. + reg = <0x08>;
  12327. +
  12328. + regulators {
  12329. + sw1a_reg: sw1ab {
  12330. + regulator-min-microvolt = <300000>;
  12331. + regulator-max-microvolt = <1875000>;
  12332. + regulator-boot-on;
  12333. + regulator-always-on;
  12334. + regulator-ramp-delay = <6250>;
  12335. + };
  12336. +
  12337. + sw1c_reg: sw1c {
  12338. + regulator-min-microvolt = <300000>;
  12339. + regulator-max-microvolt = <1875000>;
  12340. + regulator-boot-on;
  12341. + regulator-always-on;
  12342. + regulator-ramp-delay = <6250>;
  12343. + };
  12344. +
  12345. + sw2_reg: sw2 {
  12346. + regulator-min-microvolt = <800000>;
  12347. + regulator-max-microvolt = <3300000>;
  12348. + regulator-boot-on;
  12349. + regulator-always-on;
  12350. + };
  12351. +
  12352. + sw3a_reg: sw3a {
  12353. + regulator-min-microvolt = <400000>;
  12354. + regulator-max-microvolt = <1975000>;
  12355. + regulator-boot-on;
  12356. + regulator-always-on;
  12357. + };
  12358. +
  12359. + sw3b_reg: sw3b {
  12360. + regulator-min-microvolt = <400000>;
  12361. + regulator-max-microvolt = <1975000>;
  12362. + regulator-boot-on;
  12363. + regulator-always-on;
  12364. + };
  12365. +
  12366. + sw4_reg: sw4 {
  12367. + regulator-min-microvolt = <800000>;
  12368. + regulator-max-microvolt = <3300000>;
  12369. + };
  12370. +
  12371. + swbst_reg: swbst {
  12372. + regulator-min-microvolt = <5000000>;
  12373. + regulator-max-microvolt = <5150000>;
  12374. + };
  12375. +
  12376. + snvs_reg: vsnvs {
  12377. + regulator-min-microvolt = <1000000>;
  12378. + regulator-max-microvolt = <3000000>;
  12379. + regulator-boot-on;
  12380. + regulator-always-on;
  12381. + };
  12382. +
  12383. + vref_reg: vrefddr {
  12384. + regulator-boot-on;
  12385. + regulator-always-on;
  12386. + };
  12387. +
  12388. + vgen1_reg: vgen1 {
  12389. + regulator-min-microvolt = <800000>;
  12390. + regulator-max-microvolt = <1550000>;
  12391. + };
  12392. +
  12393. + vgen2_reg: vgen2 {
  12394. + regulator-min-microvolt = <800000>;
  12395. + regulator-max-microvolt = <1550000>;
  12396. + };
  12397. +
  12398. + vgen3_reg: vgen3 {
  12399. + regulator-min-microvolt = <1800000>;
  12400. + regulator-max-microvolt = <3300000>;
  12401. + regulator-always-on;
  12402. + };
  12403. +
  12404. + vgen4_reg: vgen4 {
  12405. + regulator-min-microvolt = <1800000>;
  12406. + regulator-max-microvolt = <3300000>;
  12407. + regulator-always-on;
  12408. + };
  12409. +
  12410. + vgen5_reg: vgen5 {
  12411. + regulator-min-microvolt = <1800000>;
  12412. + regulator-max-microvolt = <3300000>;
  12413. + regulator-always-on;
  12414. + };
  12415. +
  12416. + vgen6_reg: vgen6 {
  12417. + regulator-min-microvolt = <1800000>;
  12418. + regulator-max-microvolt = <3300000>;
  12419. + regulator-always-on;
  12420. + };
  12421. + };
  12422. + };
  12423. +
  12424. + mma8450@1c {
  12425. + compatible = "fsl,mma8450";
  12426. + reg = <0x1c>;
  12427. + };
  12428. +};
  12429. +
  12430. +&i2c2 {
  12431. + clock-frequency = <100000>;
  12432. + pinctrl-names = "default";
  12433. + pinctrl-0 = <&pinctrl_i2c2_1>;
  12434. + status = "okay";
  12435. +};
  12436. +
  12437. +&i2c3 {
  12438. + clock-frequency = <100000>;
  12439. + pinctrl-names = "default";
  12440. + pinctrl-0 = <&pinctrl_i2c3_1>;
  12441. + status = "okay";
  12442. +
  12443. + ov564x: ov564x@3c {
  12444. + compatible = "ovti,ov564x";
  12445. + reg = <0x3c>;
  12446. + pinctrl-names = "default";
  12447. + pinctrl-0 = <&pinctrl_csi_0>;
  12448. + clocks = <&clks IMX6SL_CLK_CSI>;
  12449. + clock-names = "csi_mclk";
  12450. + AVDD-supply = <&vgen6_reg>; /* 2.8v */
  12451. + DVDD-supply = <&vgen2_reg>; /* 1.5v*/
  12452. + pwn-gpios = <&gpio1 25 1>;
  12453. + rst-gpios = <&gpio1 26 0>;
  12454. + csi_id = <0>;
  12455. + mclk = <24000000>;
  12456. + mclk_source = <0>;
  12457. + };
  12458. +};
  12459. +
  12460. &iomuxc {
  12461. pinctrl-names = "default";
  12462. pinctrl-0 = <&pinctrl_hog>;
  12463. - hog {
  12464. + imx6sl-evk {
  12465. pinctrl_hog: hoggrp {
  12466. fsl,pins = <
  12467. MX6SL_PAD_KEY_ROW7__GPIO4_IO07 0x17059
  12468. @@ -78,21 +444,270 @@
  12469. MX6SL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059
  12470. MX6SL_PAD_KEY_COL4__GPIO4_IO00 0x80000000
  12471. MX6SL_PAD_KEY_COL5__GPIO4_IO02 0x80000000
  12472. + MX6SL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x4130b0
  12473. + >;
  12474. + };
  12475. +
  12476. + pinctrl_audmux3: audmux3grp {
  12477. + fsl,pins = <
  12478. + MX6SL_PAD_AUD_RXD__AUD3_RXD 0x4130b0
  12479. + MX6SL_PAD_AUD_TXC__AUD3_TXC 0x4130b0
  12480. + MX6SL_PAD_AUD_TXD__AUD3_TXD 0x4110b0
  12481. + MX6SL_PAD_AUD_TXFS__AUD3_TXFS 0x4130b0
  12482. + >;
  12483. + };
  12484. +
  12485. + pinctrl_ecspi1: ecspi1grp {
  12486. + fsl,pins = <
  12487. + MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
  12488. + MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
  12489. + MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
  12490. + MX6SL_PAD_ECSPI1_SS0__GPIO4_IO11 0x80000000
  12491. + >;
  12492. + };
  12493. +
  12494. + pinctrl_fec: fecgrp {
  12495. + fsl,pins = <
  12496. + MX6SL_PAD_FEC_MDC__FEC_MDC 0x1b0b0
  12497. + MX6SL_PAD_FEC_MDIO__FEC_MDIO 0x1b0b0
  12498. + MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV 0x1b0b0
  12499. + MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0 0x1b0b0
  12500. + MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1 0x1b0b0
  12501. + MX6SL_PAD_FEC_TX_EN__FEC_TX_EN 0x1b0b0
  12502. + MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0 0x1b0b0
  12503. + MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1 0x1b0b0
  12504. + MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x4001b0a8
  12505. + >;
  12506. + };
  12507. +
  12508. + pinctrl_i2c1: i2c1grp {
  12509. + fsl,pins = <
  12510. + MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1
  12511. + MX6SL_PAD_I2C1_SDA__I2C1_SDA 0x4001b8b1
  12512. + >;
  12513. + };
  12514. +
  12515. +
  12516. + pinctrl_i2c2: i2c2grp {
  12517. + fsl,pins = <
  12518. + MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x4001b8b1
  12519. + MX6SL_PAD_I2C2_SDA__I2C2_SDA 0x4001b8b1
  12520. + >;
  12521. + };
  12522. +
  12523. + pinctrl_led: ledgrp {
  12524. + fsl,pins = <
  12525. + MX6SL_PAD_HSIC_STROBE__GPIO3_IO20 0x17059
  12526. + >;
  12527. + };
  12528. +
  12529. + pinctrl_kpp: kppgrp {
  12530. + fsl,pins = <
  12531. + MX6SL_PAD_KEY_ROW0__KEY_ROW0 0x1b010
  12532. + MX6SL_PAD_KEY_ROW1__KEY_ROW1 0x1b010
  12533. + MX6SL_PAD_KEY_ROW2__KEY_ROW2 0x1b0b0
  12534. + MX6SL_PAD_KEY_COL0__KEY_COL0 0x110b0
  12535. + MX6SL_PAD_KEY_COL1__KEY_COL1 0x110b0
  12536. + MX6SL_PAD_KEY_COL2__KEY_COL2 0x110b0
  12537. + >;
  12538. + };
  12539. +
  12540. + pinctrl_uart1: uart1grp {
  12541. + fsl,pins = <
  12542. + MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x1b0b1
  12543. + MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1
  12544. + >;
  12545. + };
  12546. +
  12547. + pinctrl_usbotg1: usbotg1grp {
  12548. + fsl,pins = <
  12549. + MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059
  12550. + >;
  12551. + };
  12552. +
  12553. + pinctrl_usdhc1: usdhc1grp {
  12554. + fsl,pins = <
  12555. + MX6SL_PAD_SD1_CMD__SD1_CMD 0x17059
  12556. + MX6SL_PAD_SD1_CLK__SD1_CLK 0x10059
  12557. + MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  12558. + MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  12559. + MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  12560. + MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  12561. + MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x17059
  12562. + MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x17059
  12563. + MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x17059
  12564. + MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x17059
  12565. + >;
  12566. + };
  12567. +
  12568. + pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
  12569. + fsl,pins = <
  12570. + MX6SL_PAD_SD1_CMD__SD1_CMD 0x170b9
  12571. + MX6SL_PAD_SD1_CLK__SD1_CLK 0x100b9
  12572. + MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170b9
  12573. + MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170b9
  12574. + MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170b9
  12575. + MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170b9
  12576. + MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170b9
  12577. + MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170b9
  12578. + MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170b9
  12579. + MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170b9
  12580. + >;
  12581. + };
  12582. +
  12583. + pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
  12584. + fsl,pins = <
  12585. + MX6SL_PAD_SD1_CMD__SD1_CMD 0x170f9
  12586. + MX6SL_PAD_SD1_CLK__SD1_CLK 0x100f9
  12587. + MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
  12588. + MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
  12589. + MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
  12590. + MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
  12591. + MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170f9
  12592. + MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170f9
  12593. + MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170f9
  12594. + MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170f9
  12595. + >;
  12596. + };
  12597. +
  12598. + pinctrl_usdhc2: usdhc2grp {
  12599. + fsl,pins = <
  12600. + MX6SL_PAD_SD2_CMD__SD2_CMD 0x17059
  12601. + MX6SL_PAD_SD2_CLK__SD2_CLK 0x10059
  12602. + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  12603. + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  12604. + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  12605. + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  12606. + >;
  12607. + };
  12608. +
  12609. + pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
  12610. + fsl,pins = <
  12611. + MX6SL_PAD_SD2_CMD__SD2_CMD 0x170b9
  12612. + MX6SL_PAD_SD2_CLK__SD2_CLK 0x100b9
  12613. + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
  12614. + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
  12615. + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
  12616. + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170b9
  12617. + >;
  12618. + };
  12619. +
  12620. + pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
  12621. + fsl,pins = <
  12622. + MX6SL_PAD_SD2_CMD__SD2_CMD 0x170f9
  12623. + MX6SL_PAD_SD2_CLK__SD2_CLK 0x100f9
  12624. + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
  12625. + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
  12626. + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
  12627. + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170f9
  12628. + >;
  12629. + };
  12630. +
  12631. + pinctrl_usdhc3: usdhc3grp {
  12632. + fsl,pins = <
  12633. + MX6SL_PAD_SD3_CMD__SD3_CMD 0x17059
  12634. + MX6SL_PAD_SD3_CLK__SD3_CLK 0x10059
  12635. + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  12636. + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  12637. + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  12638. + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  12639. + >;
  12640. + };
  12641. +
  12642. + pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
  12643. + fsl,pins = <
  12644. + MX6SL_PAD_SD3_CMD__SD3_CMD 0x170b9
  12645. + MX6SL_PAD_SD3_CLK__SD3_CLK 0x100b9
  12646. + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  12647. + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  12648. + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  12649. + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  12650. + >;
  12651. + };
  12652. +
  12653. + pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
  12654. + fsl,pins = <
  12655. + MX6SL_PAD_SD3_CMD__SD3_CMD 0x170f9
  12656. + MX6SL_PAD_SD3_CLK__SD3_CLK 0x100f9
  12657. + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  12658. + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  12659. + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  12660. + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  12661. >;
  12662. };
  12663. };
  12664. };
  12665. +&kpp {
  12666. + pinctrl-names = "default";
  12667. + pinctrl-0 = <&pinctrl_kpp>;
  12668. + linux,keymap = <
  12669. + MATRIX_KEY(0x0, 0x0, KEY_UP) /* ROW0, COL0 */
  12670. + MATRIX_KEY(0x0, 0x1, KEY_DOWN) /* ROW0, COL1 */
  12671. + MATRIX_KEY(0x0, 0x2, KEY_ENTER) /* ROW0, COL2 */
  12672. + MATRIX_KEY(0x1, 0x0, KEY_HOME) /* ROW1, COL0 */
  12673. + MATRIX_KEY(0x1, 0x1, KEY_RIGHT) /* ROW1, COL1 */
  12674. + MATRIX_KEY(0x1, 0x2, KEY_LEFT) /* ROW1, COL2 */
  12675. + MATRIX_KEY(0x2, 0x0, KEY_VOLUMEDOWN) /* ROW2, COL0 */
  12676. + MATRIX_KEY(0x2, 0x1, KEY_VOLUMEUP) /* ROW2, COL1 */
  12677. + >;
  12678. + status = "okay";
  12679. +};
  12680. +
  12681. +&ssi2 {
  12682. + fsl,mode = "i2s-slave";
  12683. + status = "okay";
  12684. +};
  12685. +
  12686. +&lcdif {
  12687. + pinctrl-names = "default";
  12688. + pinctrl-0 = <&pinctrl_lcdif_dat_0
  12689. + &pinctrl_lcdif_ctrl_0>;
  12690. + lcd-supply = <&reg_lcd_3v3>;
  12691. + display = <&display>;
  12692. + status = "okay";
  12693. +
  12694. + display: display {
  12695. + bits-per-pixel = <16>;
  12696. + bus-width = <24>;
  12697. +
  12698. + display-timings {
  12699. + native-mode = <&timing0>;
  12700. + timing0: timing0 {
  12701. + clock-frequency = <33500000>;
  12702. + hactive = <800>;
  12703. + vactive = <480>;
  12704. + hback-porch = <89>;
  12705. + hfront-porch = <164>;
  12706. + vback-porch = <23>;
  12707. + vfront-porch = <10>;
  12708. + hsync-len = <10>;
  12709. + vsync-len = <10>;
  12710. + hsync-active = <0>;
  12711. + vsync-active = <0>;
  12712. + de-active = <1>;
  12713. + pixelclk-active = <0>;
  12714. + };
  12715. + };
  12716. + };
  12717. +};
  12718. +
  12719. +&pwm1 {
  12720. + pinctrl-names = "default";
  12721. + pinctrl-0 = <&pinctrl_pwm1_0>;
  12722. + status = "okay";
  12723. +};
  12724. +
  12725. &uart1 {
  12726. pinctrl-names = "default";
  12727. - pinctrl-0 = <&pinctrl_uart1_1>;
  12728. + pinctrl-0 = <&pinctrl_uart1>;
  12729. status = "okay";
  12730. };
  12731. &usbotg1 {
  12732. vbus-supply = <&reg_usb_otg1_vbus>;
  12733. pinctrl-names = "default";
  12734. - pinctrl-0 = <&pinctrl_usbotg1_1>;
  12735. + pinctrl-0 = <&pinctrl_usbotg1>;
  12736. disable-over-current;
  12737. status = "okay";
  12738. };
  12739. @@ -106,9 +721,9 @@
  12740. &usdhc1 {
  12741. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  12742. - pinctrl-0 = <&pinctrl_usdhc1_1>;
  12743. - pinctrl-1 = <&pinctrl_usdhc1_1_100mhz>;
  12744. - pinctrl-2 = <&pinctrl_usdhc1_1_200mhz>;
  12745. + pinctrl-0 = <&pinctrl_usdhc1>;
  12746. + pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
  12747. + pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
  12748. bus-width = <8>;
  12749. cd-gpios = <&gpio4 7 0>;
  12750. wp-gpios = <&gpio4 6 0>;
  12751. @@ -117,9 +732,9 @@
  12752. &usdhc2 {
  12753. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  12754. - pinctrl-0 = <&pinctrl_usdhc2_1>;
  12755. - pinctrl-1 = <&pinctrl_usdhc2_1_100mhz>;
  12756. - pinctrl-2 = <&pinctrl_usdhc2_1_200mhz>;
  12757. + pinctrl-0 = <&pinctrl_usdhc2>;
  12758. + pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
  12759. + pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
  12760. cd-gpios = <&gpio5 0 0>;
  12761. wp-gpios = <&gpio4 29 0>;
  12762. status = "okay";
  12763. @@ -127,9 +742,26 @@
  12764. &usdhc3 {
  12765. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  12766. - pinctrl-0 = <&pinctrl_usdhc3_1>;
  12767. - pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
  12768. - pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
  12769. + pinctrl-0 = <&pinctrl_usdhc3>;
  12770. + pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
  12771. + pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
  12772. cd-gpios = <&gpio3 22 0>;
  12773. status = "okay";
  12774. };
  12775. +
  12776. +&pxp {
  12777. + status = "okay";
  12778. +};
  12779. +
  12780. +&gpc {
  12781. + fsl,cpu_pupscr_sw2iso = <0xf>;
  12782. + fsl,cpu_pupscr_sw = <0xf>;
  12783. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  12784. + fsl,cpu_pdnscr_iso = <0x1>;
  12785. + fsl,ldo-bypass; /* use ldo-bypass, u-boot will check it and configure */
  12786. + pu-supply = <&pu_dummy>; /* ldo-bypass:use pu_dummy if VDDSOC share with VDDPU */
  12787. +};
  12788. +
  12789. +&gpu {
  12790. + pu-supply = <&pu_dummy>; /* ldo-bypass:use pu_dummy if VDDSOC share with VDDPU */
  12791. +};
  12792. diff -Nur linux-3.14.15/arch/arm/boot/dts/Makefile linux-linaro-stable-mx6/arch/arm/boot/dts/Makefile
  12793. --- linux-3.14.15/arch/arm/boot/dts/Makefile 2014-07-31 23:51:43.000000000 +0200
  12794. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/Makefile 2014-08-20 19:31:39.800841842 +0200
  12795. @@ -154,16 +154,37 @@
  12796. imx53-qsb.dtb \
  12797. imx53-smd.dtb \
  12798. imx6dl-cubox-i.dtb \
  12799. + imx6dl-dfi-fs700-m60.dtb \
  12800. + imx6dl-gw51xx.dtb \
  12801. + imx6dl-gw52xx.dtb \
  12802. + imx6dl-gw53xx.dtb \
  12803. + imx6dl-gw54xx.dtb \
  12804. imx6dl-hummingboard.dtb \
  12805. + imx6dl-nitrogen6x.dtb \
  12806. + imx6dl-phytec-pbab01.dtb \
  12807. imx6dl-sabreauto.dtb \
  12808. + imx6dl-sabrelite.dtb \
  12809. imx6dl-sabresd.dtb \
  12810. + imx6dl-sabresd-hdcp.dtb \
  12811. imx6dl-wandboard.dtb \
  12812. imx6q-arm2.dtb \
  12813. + imx6q-cm-fx6.dtb \
  12814. imx6q-cubox-i.dtb \
  12815. + imx6q-hummingboard.dtb \
  12816. + imx6q-dfi-fs700-m60.dtb \
  12817. + imx6q-dmo-edmqmx6.dtb \
  12818. + imx6q-gk802.dtb \
  12819. + imx6q-gw51xx.dtb \
  12820. + imx6q-gw52xx.dtb \
  12821. + imx6q-gw53xx.dtb \
  12822. + imx6q-gw5400-a.dtb \
  12823. + imx6q-gw54xx.dtb \
  12824. + imx6q-nitrogen6x.dtb \
  12825. imx6q-phytec-pbab01.dtb \
  12826. imx6q-sabreauto.dtb \
  12827. imx6q-sabrelite.dtb \
  12828. imx6q-sabresd.dtb \
  12829. + imx6q-sabresd-hdcp.dtb \
  12830. imx6q-sbc6x.dtb \
  12831. imx6q-udoo.dtb \
  12832. imx6q-wandboard.dtb \
  12833. @@ -312,7 +333,14 @@
  12834. dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
  12835. vexpress-v2p-ca9.dtb \
  12836. vexpress-v2p-ca15-tc1.dtb \
  12837. - vexpress-v2p-ca15_a7.dtb
  12838. + vexpress-v2p-ca15_a7.dtb \
  12839. + rtsm_ve-cortex_a9x2.dtb \
  12840. + rtsm_ve-cortex_a9x4.dtb \
  12841. + rtsm_ve-cortex_a15x1.dtb \
  12842. + rtsm_ve-cortex_a15x2.dtb \
  12843. + rtsm_ve-cortex_a15x4.dtb \
  12844. + rtsm_ve-v2p-ca15x1-ca7x1.dtb \
  12845. + rtsm_ve-v2p-ca15x4-ca7x4.dtb
  12846. dtb-$(CONFIG_ARCH_VIRT) += xenvm-4.2.dtb
  12847. dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
  12848. wm8505-ref.dtb \
  12849. diff -Nur linux-3.14.15/arch/arm/boot/dts/marco.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/marco.dtsi
  12850. --- linux-3.14.15/arch/arm/boot/dts/marco.dtsi 2014-07-31 23:51:43.000000000 +0200
  12851. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/marco.dtsi 2014-08-20 19:31:39.912842323 +0200
  12852. @@ -36,7 +36,7 @@
  12853. ranges = <0x40000000 0x40000000 0xa0000000>;
  12854. l2-cache-controller@c0030000 {
  12855. - compatible = "sirf,marco-pl310-cache", "arm,pl310-cache";
  12856. + compatible = "arm,pl310-cache";
  12857. reg = <0xc0030000 0x1000>;
  12858. interrupts = <0 59 0>;
  12859. arm,tag-latency = <1 1 1>;
  12860. diff -Nur linux-3.14.15/arch/arm/boot/dts/prima2.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/prima2.dtsi
  12861. --- linux-3.14.15/arch/arm/boot/dts/prima2.dtsi 2014-07-31 23:51:43.000000000 +0200
  12862. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/prima2.dtsi 2014-08-20 19:31:39.936842427 +0200
  12863. @@ -48,7 +48,7 @@
  12864. ranges = <0x40000000 0x40000000 0x80000000>;
  12865. l2-cache-controller@80040000 {
  12866. - compatible = "arm,pl310-cache", "sirf,prima2-pl310-cache";
  12867. + compatible = "arm,pl310-cache";
  12868. reg = <0x80040000 0x1000>;
  12869. interrupts = <59>;
  12870. arm,tag-latency = <1 1 1>;
  12871. diff -Nur linux-3.14.15/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts
  12872. --- linux-3.14.15/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts 1970-01-01 01:00:00.000000000 +0100
  12873. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts 2014-08-20 19:23:45.550811652 +0200
  12874. @@ -0,0 +1,159 @@
  12875. +/*
  12876. + * ARM Ltd. Fast Models
  12877. + *
  12878. + * Versatile Express (VE) system model
  12879. + * ARMCortexA15x1CT
  12880. + *
  12881. + * RTSM_VE_Cortex_A15x1.lisa
  12882. + */
  12883. +
  12884. +/dts-v1/;
  12885. +
  12886. +/ {
  12887. + model = "RTSM_VE_CortexA15x1";
  12888. + arm,vexpress,site = <0xf>;
  12889. + compatible = "arm,rtsm_ve,cortex_a15x1", "arm,vexpress";
  12890. + interrupt-parent = <&gic>;
  12891. + #address-cells = <2>;
  12892. + #size-cells = <2>;
  12893. +
  12894. + chosen { };
  12895. +
  12896. + aliases {
  12897. + serial0 = &v2m_serial0;
  12898. + serial1 = &v2m_serial1;
  12899. + serial2 = &v2m_serial2;
  12900. + serial3 = &v2m_serial3;
  12901. + };
  12902. +
  12903. + cpus {
  12904. + #address-cells = <1>;
  12905. + #size-cells = <0>;
  12906. +
  12907. + cpu@0 {
  12908. + device_type = "cpu";
  12909. + compatible = "arm,cortex-a15";
  12910. + reg = <0>;
  12911. + };
  12912. + };
  12913. +
  12914. + memory@80000000 {
  12915. + device_type = "memory";
  12916. + reg = <0 0x80000000 0 0x80000000>;
  12917. + };
  12918. +
  12919. + gic: interrupt-controller@2c001000 {
  12920. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  12921. + #interrupt-cells = <3>;
  12922. + #address-cells = <0>;
  12923. + interrupt-controller;
  12924. + reg = <0 0x2c001000 0 0x1000>,
  12925. + <0 0x2c002000 0 0x1000>,
  12926. + <0 0x2c004000 0 0x2000>,
  12927. + <0 0x2c006000 0 0x2000>;
  12928. + interrupts = <1 9 0xf04>;
  12929. + };
  12930. +
  12931. + timer {
  12932. + compatible = "arm,armv7-timer";
  12933. + interrupts = <1 13 0xf08>,
  12934. + <1 14 0xf08>,
  12935. + <1 11 0xf08>,
  12936. + <1 10 0xf08>;
  12937. + };
  12938. +
  12939. + dcc {
  12940. + compatible = "arm,vexpress,config-bus";
  12941. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  12942. +
  12943. + osc@0 {
  12944. + /* ACLK clock to the AXI master port on the test chip */
  12945. + compatible = "arm,vexpress-osc";
  12946. + arm,vexpress-sysreg,func = <1 0>;
  12947. + freq-range = <30000000 50000000>;
  12948. + #clock-cells = <0>;
  12949. + clock-output-names = "extsaxiclk";
  12950. + };
  12951. +
  12952. + oscclk1: osc@1 {
  12953. + /* Reference clock for the CLCD */
  12954. + compatible = "arm,vexpress-osc";
  12955. + arm,vexpress-sysreg,func = <1 1>;
  12956. + freq-range = <10000000 80000000>;
  12957. + #clock-cells = <0>;
  12958. + clock-output-names = "clcdclk";
  12959. + };
  12960. +
  12961. + smbclk: oscclk2: osc@2 {
  12962. + /* Reference clock for the test chip internal PLLs */
  12963. + compatible = "arm,vexpress-osc";
  12964. + arm,vexpress-sysreg,func = <1 2>;
  12965. + freq-range = <33000000 100000000>;
  12966. + #clock-cells = <0>;
  12967. + clock-output-names = "tcrefclk";
  12968. + };
  12969. + };
  12970. +
  12971. + smb {
  12972. + compatible = "simple-bus";
  12973. +
  12974. + #address-cells = <2>;
  12975. + #size-cells = <1>;
  12976. + ranges = <0 0 0 0x08000000 0x04000000>,
  12977. + <1 0 0 0x14000000 0x04000000>,
  12978. + <2 0 0 0x18000000 0x04000000>,
  12979. + <3 0 0 0x1c000000 0x04000000>,
  12980. + <4 0 0 0x0c000000 0x04000000>,
  12981. + <5 0 0 0x10000000 0x04000000>;
  12982. +
  12983. + #interrupt-cells = <1>;
  12984. + interrupt-map-mask = <0 0 63>;
  12985. + interrupt-map = <0 0 0 &gic 0 0 4>,
  12986. + <0 0 1 &gic 0 1 4>,
  12987. + <0 0 2 &gic 0 2 4>,
  12988. + <0 0 3 &gic 0 3 4>,
  12989. + <0 0 4 &gic 0 4 4>,
  12990. + <0 0 5 &gic 0 5 4>,
  12991. + <0 0 6 &gic 0 6 4>,
  12992. + <0 0 7 &gic 0 7 4>,
  12993. + <0 0 8 &gic 0 8 4>,
  12994. + <0 0 9 &gic 0 9 4>,
  12995. + <0 0 10 &gic 0 10 4>,
  12996. + <0 0 11 &gic 0 11 4>,
  12997. + <0 0 12 &gic 0 12 4>,
  12998. + <0 0 13 &gic 0 13 4>,
  12999. + <0 0 14 &gic 0 14 4>,
  13000. + <0 0 15 &gic 0 15 4>,
  13001. + <0 0 16 &gic 0 16 4>,
  13002. + <0 0 17 &gic 0 17 4>,
  13003. + <0 0 18 &gic 0 18 4>,
  13004. + <0 0 19 &gic 0 19 4>,
  13005. + <0 0 20 &gic 0 20 4>,
  13006. + <0 0 21 &gic 0 21 4>,
  13007. + <0 0 22 &gic 0 22 4>,
  13008. + <0 0 23 &gic 0 23 4>,
  13009. + <0 0 24 &gic 0 24 4>,
  13010. + <0 0 25 &gic 0 25 4>,
  13011. + <0 0 26 &gic 0 26 4>,
  13012. + <0 0 27 &gic 0 27 4>,
  13013. + <0 0 28 &gic 0 28 4>,
  13014. + <0 0 29 &gic 0 29 4>,
  13015. + <0 0 30 &gic 0 30 4>,
  13016. + <0 0 31 &gic 0 31 4>,
  13017. + <0 0 32 &gic 0 32 4>,
  13018. + <0 0 33 &gic 0 33 4>,
  13019. + <0 0 34 &gic 0 34 4>,
  13020. + <0 0 35 &gic 0 35 4>,
  13021. + <0 0 36 &gic 0 36 4>,
  13022. + <0 0 37 &gic 0 37 4>,
  13023. + <0 0 38 &gic 0 38 4>,
  13024. + <0 0 39 &gic 0 39 4>,
  13025. + <0 0 40 &gic 0 40 4>,
  13026. + <0 0 41 &gic 0 41 4>,
  13027. + <0 0 42 &gic 0 42 4>;
  13028. +
  13029. + /include/ "rtsm_ve-motherboard.dtsi"
  13030. + };
  13031. +};
  13032. +
  13033. +/include/ "clcd-panels.dtsi"
  13034. diff -Nur linux-3.14.15/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts
  13035. --- linux-3.14.15/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts 1970-01-01 01:00:00.000000000 +0100
  13036. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts 2014-08-20 19:23:45.550811652 +0200
  13037. @@ -0,0 +1,165 @@
  13038. +/*
  13039. + * ARM Ltd. Fast Models
  13040. + *
  13041. + * Versatile Express (VE) system model
  13042. + * ARMCortexA15x2CT
  13043. + *
  13044. + * RTSM_VE_Cortex_A15x2.lisa
  13045. + */
  13046. +
  13047. +/dts-v1/;
  13048. +
  13049. +/ {
  13050. + model = "RTSM_VE_CortexA15x2";
  13051. + arm,vexpress,site = <0xf>;
  13052. + compatible = "arm,rtsm_ve,cortex_a15x2", "arm,vexpress";
  13053. + interrupt-parent = <&gic>;
  13054. + #address-cells = <2>;
  13055. + #size-cells = <2>;
  13056. +
  13057. + chosen { };
  13058. +
  13059. + aliases {
  13060. + serial0 = &v2m_serial0;
  13061. + serial1 = &v2m_serial1;
  13062. + serial2 = &v2m_serial2;
  13063. + serial3 = &v2m_serial3;
  13064. + };
  13065. +
  13066. + cpus {
  13067. + #address-cells = <1>;
  13068. + #size-cells = <0>;
  13069. +
  13070. + cpu@0 {
  13071. + device_type = "cpu";
  13072. + compatible = "arm,cortex-a15";
  13073. + reg = <0>;
  13074. + };
  13075. +
  13076. + cpu@1 {
  13077. + device_type = "cpu";
  13078. + compatible = "arm,cortex-a15";
  13079. + reg = <1>;
  13080. + };
  13081. + };
  13082. +
  13083. + memory@80000000 {
  13084. + device_type = "memory";
  13085. + reg = <0 0x80000000 0 0x80000000>;
  13086. + };
  13087. +
  13088. + gic: interrupt-controller@2c001000 {
  13089. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  13090. + #interrupt-cells = <3>;
  13091. + #address-cells = <0>;
  13092. + interrupt-controller;
  13093. + reg = <0 0x2c001000 0 0x1000>,
  13094. + <0 0x2c002000 0 0x1000>,
  13095. + <0 0x2c004000 0 0x2000>,
  13096. + <0 0x2c006000 0 0x2000>;
  13097. + interrupts = <1 9 0xf04>;
  13098. + };
  13099. +
  13100. + timer {
  13101. + compatible = "arm,armv7-timer";
  13102. + interrupts = <1 13 0xf08>,
  13103. + <1 14 0xf08>,
  13104. + <1 11 0xf08>,
  13105. + <1 10 0xf08>;
  13106. + };
  13107. +
  13108. + dcc {
  13109. + compatible = "arm,vexpress,config-bus";
  13110. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13111. +
  13112. + osc@0 {
  13113. + /* ACLK clock to the AXI master port on the test chip */
  13114. + compatible = "arm,vexpress-osc";
  13115. + arm,vexpress-sysreg,func = <1 0>;
  13116. + freq-range = <30000000 50000000>;
  13117. + #clock-cells = <0>;
  13118. + clock-output-names = "extsaxiclk";
  13119. + };
  13120. +
  13121. + oscclk1: osc@1 {
  13122. + /* Reference clock for the CLCD */
  13123. + compatible = "arm,vexpress-osc";
  13124. + arm,vexpress-sysreg,func = <1 1>;
  13125. + freq-range = <10000000 80000000>;
  13126. + #clock-cells = <0>;
  13127. + clock-output-names = "clcdclk";
  13128. + };
  13129. +
  13130. + smbclk: oscclk2: osc@2 {
  13131. + /* Reference clock for the test chip internal PLLs */
  13132. + compatible = "arm,vexpress-osc";
  13133. + arm,vexpress-sysreg,func = <1 2>;
  13134. + freq-range = <33000000 100000000>;
  13135. + #clock-cells = <0>;
  13136. + clock-output-names = "tcrefclk";
  13137. + };
  13138. + };
  13139. +
  13140. + smb {
  13141. + compatible = "simple-bus";
  13142. +
  13143. + #address-cells = <2>;
  13144. + #size-cells = <1>;
  13145. + ranges = <0 0 0 0x08000000 0x04000000>,
  13146. + <1 0 0 0x14000000 0x04000000>,
  13147. + <2 0 0 0x18000000 0x04000000>,
  13148. + <3 0 0 0x1c000000 0x04000000>,
  13149. + <4 0 0 0x0c000000 0x04000000>,
  13150. + <5 0 0 0x10000000 0x04000000>;
  13151. +
  13152. + #interrupt-cells = <1>;
  13153. + interrupt-map-mask = <0 0 63>;
  13154. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13155. + <0 0 1 &gic 0 1 4>,
  13156. + <0 0 2 &gic 0 2 4>,
  13157. + <0 0 3 &gic 0 3 4>,
  13158. + <0 0 4 &gic 0 4 4>,
  13159. + <0 0 5 &gic 0 5 4>,
  13160. + <0 0 6 &gic 0 6 4>,
  13161. + <0 0 7 &gic 0 7 4>,
  13162. + <0 0 8 &gic 0 8 4>,
  13163. + <0 0 9 &gic 0 9 4>,
  13164. + <0 0 10 &gic 0 10 4>,
  13165. + <0 0 11 &gic 0 11 4>,
  13166. + <0 0 12 &gic 0 12 4>,
  13167. + <0 0 13 &gic 0 13 4>,
  13168. + <0 0 14 &gic 0 14 4>,
  13169. + <0 0 15 &gic 0 15 4>,
  13170. + <0 0 16 &gic 0 16 4>,
  13171. + <0 0 17 &gic 0 17 4>,
  13172. + <0 0 18 &gic 0 18 4>,
  13173. + <0 0 19 &gic 0 19 4>,
  13174. + <0 0 20 &gic 0 20 4>,
  13175. + <0 0 21 &gic 0 21 4>,
  13176. + <0 0 22 &gic 0 22 4>,
  13177. + <0 0 23 &gic 0 23 4>,
  13178. + <0 0 24 &gic 0 24 4>,
  13179. + <0 0 25 &gic 0 25 4>,
  13180. + <0 0 26 &gic 0 26 4>,
  13181. + <0 0 27 &gic 0 27 4>,
  13182. + <0 0 28 &gic 0 28 4>,
  13183. + <0 0 29 &gic 0 29 4>,
  13184. + <0 0 30 &gic 0 30 4>,
  13185. + <0 0 31 &gic 0 31 4>,
  13186. + <0 0 32 &gic 0 32 4>,
  13187. + <0 0 33 &gic 0 33 4>,
  13188. + <0 0 34 &gic 0 34 4>,
  13189. + <0 0 35 &gic 0 35 4>,
  13190. + <0 0 36 &gic 0 36 4>,
  13191. + <0 0 37 &gic 0 37 4>,
  13192. + <0 0 38 &gic 0 38 4>,
  13193. + <0 0 39 &gic 0 39 4>,
  13194. + <0 0 40 &gic 0 40 4>,
  13195. + <0 0 41 &gic 0 41 4>,
  13196. + <0 0 42 &gic 0 42 4>;
  13197. +
  13198. + /include/ "rtsm_ve-motherboard.dtsi"
  13199. + };
  13200. +};
  13201. +
  13202. +/include/ "clcd-panels.dtsi"
  13203. diff -Nur linux-3.14.15/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts
  13204. --- linux-3.14.15/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts 1970-01-01 01:00:00.000000000 +0100
  13205. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts 2014-08-20 19:23:45.550811652 +0200
  13206. @@ -0,0 +1,177 @@
  13207. +/*
  13208. + * ARM Ltd. Fast Models
  13209. + *
  13210. + * Versatile Express (VE) system model
  13211. + * ARMCortexA15x4CT
  13212. + *
  13213. + * RTSM_VE_Cortex_A15x4.lisa
  13214. + */
  13215. +
  13216. +/dts-v1/;
  13217. +
  13218. +/ {
  13219. + model = "RTSM_VE_CortexA15x4";
  13220. + arm,vexpress,site = <0xf>;
  13221. + compatible = "arm,rtsm_ve,cortex_a15x4", "arm,vexpress";
  13222. + interrupt-parent = <&gic>;
  13223. + #address-cells = <2>;
  13224. + #size-cells = <2>;
  13225. +
  13226. + chosen { };
  13227. +
  13228. + aliases {
  13229. + serial0 = &v2m_serial0;
  13230. + serial1 = &v2m_serial1;
  13231. + serial2 = &v2m_serial2;
  13232. + serial3 = &v2m_serial3;
  13233. + };
  13234. +
  13235. + cpus {
  13236. + #address-cells = <1>;
  13237. + #size-cells = <0>;
  13238. +
  13239. + cpu@0 {
  13240. + device_type = "cpu";
  13241. + compatible = "arm,cortex-a15";
  13242. + reg = <0>;
  13243. + };
  13244. +
  13245. + cpu@1 {
  13246. + device_type = "cpu";
  13247. + compatible = "arm,cortex-a15";
  13248. + reg = <1>;
  13249. + };
  13250. +
  13251. + cpu@2 {
  13252. + device_type = "cpu";
  13253. + compatible = "arm,cortex-a15";
  13254. + reg = <2>;
  13255. + };
  13256. +
  13257. + cpu@3 {
  13258. + device_type = "cpu";
  13259. + compatible = "arm,cortex-a15";
  13260. + reg = <3>;
  13261. + };
  13262. + };
  13263. +
  13264. + memory@80000000 {
  13265. + device_type = "memory";
  13266. + reg = <0 0x80000000 0 0x80000000>;
  13267. + };
  13268. +
  13269. + gic: interrupt-controller@2c001000 {
  13270. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  13271. + #interrupt-cells = <3>;
  13272. + #address-cells = <0>;
  13273. + interrupt-controller;
  13274. + reg = <0 0x2c001000 0 0x1000>,
  13275. + <0 0x2c002000 0 0x1000>,
  13276. + <0 0x2c004000 0 0x2000>,
  13277. + <0 0x2c006000 0 0x2000>;
  13278. + interrupts = <1 9 0xf04>;
  13279. + };
  13280. +
  13281. + timer {
  13282. + compatible = "arm,armv7-timer";
  13283. + interrupts = <1 13 0xf08>,
  13284. + <1 14 0xf08>,
  13285. + <1 11 0xf08>,
  13286. + <1 10 0xf08>;
  13287. + };
  13288. +
  13289. + dcc {
  13290. + compatible = "arm,vexpress,config-bus";
  13291. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13292. +
  13293. + osc@0 {
  13294. + /* ACLK clock to the AXI master port on the test chip */
  13295. + compatible = "arm,vexpress-osc";
  13296. + arm,vexpress-sysreg,func = <1 0>;
  13297. + freq-range = <30000000 50000000>;
  13298. + #clock-cells = <0>;
  13299. + clock-output-names = "extsaxiclk";
  13300. + };
  13301. +
  13302. + oscclk1: osc@1 {
  13303. + /* Reference clock for the CLCD */
  13304. + compatible = "arm,vexpress-osc";
  13305. + arm,vexpress-sysreg,func = <1 1>;
  13306. + freq-range = <10000000 80000000>;
  13307. + #clock-cells = <0>;
  13308. + clock-output-names = "clcdclk";
  13309. + };
  13310. +
  13311. + smbclk: oscclk2: osc@2 {
  13312. + /* Reference clock for the test chip internal PLLs */
  13313. + compatible = "arm,vexpress-osc";
  13314. + arm,vexpress-sysreg,func = <1 2>;
  13315. + freq-range = <33000000 100000000>;
  13316. + #clock-cells = <0>;
  13317. + clock-output-names = "tcrefclk";
  13318. + };
  13319. + };
  13320. +
  13321. + smb {
  13322. + compatible = "simple-bus";
  13323. +
  13324. + #address-cells = <2>;
  13325. + #size-cells = <1>;
  13326. + ranges = <0 0 0 0x08000000 0x04000000>,
  13327. + <1 0 0 0x14000000 0x04000000>,
  13328. + <2 0 0 0x18000000 0x04000000>,
  13329. + <3 0 0 0x1c000000 0x04000000>,
  13330. + <4 0 0 0x0c000000 0x04000000>,
  13331. + <5 0 0 0x10000000 0x04000000>;
  13332. +
  13333. + #interrupt-cells = <1>;
  13334. + interrupt-map-mask = <0 0 63>;
  13335. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13336. + <0 0 1 &gic 0 1 4>,
  13337. + <0 0 2 &gic 0 2 4>,
  13338. + <0 0 3 &gic 0 3 4>,
  13339. + <0 0 4 &gic 0 4 4>,
  13340. + <0 0 5 &gic 0 5 4>,
  13341. + <0 0 6 &gic 0 6 4>,
  13342. + <0 0 7 &gic 0 7 4>,
  13343. + <0 0 8 &gic 0 8 4>,
  13344. + <0 0 9 &gic 0 9 4>,
  13345. + <0 0 10 &gic 0 10 4>,
  13346. + <0 0 11 &gic 0 11 4>,
  13347. + <0 0 12 &gic 0 12 4>,
  13348. + <0 0 13 &gic 0 13 4>,
  13349. + <0 0 14 &gic 0 14 4>,
  13350. + <0 0 15 &gic 0 15 4>,
  13351. + <0 0 16 &gic 0 16 4>,
  13352. + <0 0 17 &gic 0 17 4>,
  13353. + <0 0 18 &gic 0 18 4>,
  13354. + <0 0 19 &gic 0 19 4>,
  13355. + <0 0 20 &gic 0 20 4>,
  13356. + <0 0 21 &gic 0 21 4>,
  13357. + <0 0 22 &gic 0 22 4>,
  13358. + <0 0 23 &gic 0 23 4>,
  13359. + <0 0 24 &gic 0 24 4>,
  13360. + <0 0 25 &gic 0 25 4>,
  13361. + <0 0 26 &gic 0 26 4>,
  13362. + <0 0 27 &gic 0 27 4>,
  13363. + <0 0 28 &gic 0 28 4>,
  13364. + <0 0 29 &gic 0 29 4>,
  13365. + <0 0 30 &gic 0 30 4>,
  13366. + <0 0 31 &gic 0 31 4>,
  13367. + <0 0 32 &gic 0 32 4>,
  13368. + <0 0 33 &gic 0 33 4>,
  13369. + <0 0 34 &gic 0 34 4>,
  13370. + <0 0 35 &gic 0 35 4>,
  13371. + <0 0 36 &gic 0 36 4>,
  13372. + <0 0 37 &gic 0 37 4>,
  13373. + <0 0 38 &gic 0 38 4>,
  13374. + <0 0 39 &gic 0 39 4>,
  13375. + <0 0 40 &gic 0 40 4>,
  13376. + <0 0 41 &gic 0 41 4>,
  13377. + <0 0 42 &gic 0 42 4>;
  13378. +
  13379. + /include/ "rtsm_ve-motherboard.dtsi"
  13380. + };
  13381. +};
  13382. +
  13383. +/include/ "clcd-panels.dtsi"
  13384. diff -Nur linux-3.14.15/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts
  13385. --- linux-3.14.15/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts 1970-01-01 01:00:00.000000000 +0100
  13386. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts 2014-08-20 19:23:45.550811652 +0200
  13387. @@ -0,0 +1,171 @@
  13388. +/*
  13389. + * ARM Ltd. Fast Models
  13390. + *
  13391. + * Versatile Express (VE) system model
  13392. + * ARMCortexA9MPx2CT
  13393. + *
  13394. + * RTSM_VE_Cortex_A9x2.lisa
  13395. + */
  13396. +
  13397. +/dts-v1/;
  13398. +
  13399. +/ {
  13400. + model = "RTSM_VE_CortexA9x2";
  13401. + arm,vexpress,site = <0xf>;
  13402. + compatible = "arm,rtsm_ve,cortex_a9x2", "arm,vexpress";
  13403. + interrupt-parent = <&gic>;
  13404. + #address-cells = <1>;
  13405. + #size-cells = <1>;
  13406. +
  13407. + chosen { };
  13408. +
  13409. + aliases {
  13410. + serial0 = &v2m_serial0;
  13411. + serial1 = &v2m_serial1;
  13412. + serial2 = &v2m_serial2;
  13413. + serial3 = &v2m_serial3;
  13414. + };
  13415. +
  13416. + cpus {
  13417. + #address-cells = <1>;
  13418. + #size-cells = <0>;
  13419. +
  13420. + cpu@0 {
  13421. + device_type = "cpu";
  13422. + compatible = "arm,cortex-a9";
  13423. + reg = <0>;
  13424. + };
  13425. +
  13426. + cpu@1 {
  13427. + device_type = "cpu";
  13428. + compatible = "arm,cortex-a9";
  13429. + reg = <1>;
  13430. + };
  13431. + };
  13432. +
  13433. + memory@80000000 {
  13434. + device_type = "memory";
  13435. + reg = <0x80000000 0x80000000>;
  13436. + };
  13437. +
  13438. + scu@2c000000 {
  13439. + compatible = "arm,cortex-a9-scu";
  13440. + reg = <0x2c000000 0x58>;
  13441. + };
  13442. +
  13443. + timer@2c000600 {
  13444. + compatible = "arm,cortex-a9-twd-timer";
  13445. + reg = <0x2c000600 0x20>;
  13446. + interrupts = <1 13 0xf04>;
  13447. + };
  13448. +
  13449. + watchdog@2c000620 {
  13450. + compatible = "arm,cortex-a9-twd-wdt";
  13451. + reg = <0x2c000620 0x20>;
  13452. + interrupts = <1 14 0xf04>;
  13453. + };
  13454. +
  13455. + gic: interrupt-controller@2c001000 {
  13456. + compatible = "arm,cortex-a9-gic";
  13457. + #interrupt-cells = <3>;
  13458. + #address-cells = <0>;
  13459. + interrupt-controller;
  13460. + reg = <0x2c001000 0x1000>,
  13461. + <0x2c000100 0x100>;
  13462. + };
  13463. +
  13464. + dcc {
  13465. + compatible = "arm,vexpress,config-bus";
  13466. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13467. +
  13468. + osc@0 {
  13469. + /* ACLK clock to the AXI master port on the test chip */
  13470. + compatible = "arm,vexpress-osc";
  13471. + arm,vexpress-sysreg,func = <1 0>;
  13472. + freq-range = <30000000 50000000>;
  13473. + #clock-cells = <0>;
  13474. + clock-output-names = "extsaxiclk";
  13475. + };
  13476. +
  13477. + oscclk1: osc@1 {
  13478. + /* Reference clock for the CLCD */
  13479. + compatible = "arm,vexpress-osc";
  13480. + arm,vexpress-sysreg,func = <1 1>;
  13481. + freq-range = <10000000 80000000>;
  13482. + #clock-cells = <0>;
  13483. + clock-output-names = "clcdclk";
  13484. + };
  13485. +
  13486. + smbclk: oscclk2: osc@2 {
  13487. + /* Reference clock for the test chip internal PLLs */
  13488. + compatible = "arm,vexpress-osc";
  13489. + arm,vexpress-sysreg,func = <1 2>;
  13490. + freq-range = <33000000 100000000>;
  13491. + #clock-cells = <0>;
  13492. + clock-output-names = "tcrefclk";
  13493. + };
  13494. + };
  13495. +
  13496. + smb {
  13497. + compatible = "simple-bus";
  13498. +
  13499. + #address-cells = <2>;
  13500. + #size-cells = <1>;
  13501. + ranges = <0 0 0x08000000 0x04000000>,
  13502. + <1 0 0x14000000 0x04000000>,
  13503. + <2 0 0x18000000 0x04000000>,
  13504. + <3 0 0x1c000000 0x04000000>,
  13505. + <4 0 0x0c000000 0x04000000>,
  13506. + <5 0 0x10000000 0x04000000>;
  13507. +
  13508. + #interrupt-cells = <1>;
  13509. + interrupt-map-mask = <0 0 63>;
  13510. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13511. + <0 0 1 &gic 0 1 4>,
  13512. + <0 0 2 &gic 0 2 4>,
  13513. + <0 0 3 &gic 0 3 4>,
  13514. + <0 0 4 &gic 0 4 4>,
  13515. + <0 0 5 &gic 0 5 4>,
  13516. + <0 0 6 &gic 0 6 4>,
  13517. + <0 0 7 &gic 0 7 4>,
  13518. + <0 0 8 &gic 0 8 4>,
  13519. + <0 0 9 &gic 0 9 4>,
  13520. + <0 0 10 &gic 0 10 4>,
  13521. + <0 0 11 &gic 0 11 4>,
  13522. + <0 0 12 &gic 0 12 4>,
  13523. + <0 0 13 &gic 0 13 4>,
  13524. + <0 0 14 &gic 0 14 4>,
  13525. + <0 0 15 &gic 0 15 4>,
  13526. + <0 0 16 &gic 0 16 4>,
  13527. + <0 0 17 &gic 0 17 4>,
  13528. + <0 0 18 &gic 0 18 4>,
  13529. + <0 0 19 &gic 0 19 4>,
  13530. + <0 0 20 &gic 0 20 4>,
  13531. + <0 0 21 &gic 0 21 4>,
  13532. + <0 0 22 &gic 0 22 4>,
  13533. + <0 0 23 &gic 0 23 4>,
  13534. + <0 0 24 &gic 0 24 4>,
  13535. + <0 0 25 &gic 0 25 4>,
  13536. + <0 0 26 &gic 0 26 4>,
  13537. + <0 0 27 &gic 0 27 4>,
  13538. + <0 0 28 &gic 0 28 4>,
  13539. + <0 0 29 &gic 0 29 4>,
  13540. + <0 0 30 &gic 0 30 4>,
  13541. + <0 0 31 &gic 0 31 4>,
  13542. + <0 0 32 &gic 0 32 4>,
  13543. + <0 0 33 &gic 0 33 4>,
  13544. + <0 0 34 &gic 0 34 4>,
  13545. + <0 0 35 &gic 0 35 4>,
  13546. + <0 0 36 &gic 0 36 4>,
  13547. + <0 0 37 &gic 0 37 4>,
  13548. + <0 0 38 &gic 0 38 4>,
  13549. + <0 0 39 &gic 0 39 4>,
  13550. + <0 0 40 &gic 0 40 4>,
  13551. + <0 0 41 &gic 0 41 4>,
  13552. + <0 0 42 &gic 0 42 4>;
  13553. +
  13554. + /include/ "rtsm_ve-motherboard.dtsi"
  13555. + };
  13556. +};
  13557. +
  13558. +/include/ "clcd-panels.dtsi"
  13559. diff -Nur linux-3.14.15/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts
  13560. --- linux-3.14.15/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts 1970-01-01 01:00:00.000000000 +0100
  13561. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts 2014-08-20 19:23:45.550811652 +0200
  13562. @@ -0,0 +1,183 @@
  13563. +/*
  13564. + * ARM Ltd. Fast Models
  13565. + *
  13566. + * Versatile Express (VE) system model
  13567. + * ARMCortexA9MPx4CT
  13568. + *
  13569. + * RTSM_VE_Cortex_A9x4.lisa
  13570. + */
  13571. +
  13572. +/dts-v1/;
  13573. +
  13574. +/ {
  13575. + model = "RTSM_VE_CortexA9x4";
  13576. + arm,vexpress,site = <0xf>;
  13577. + compatible = "arm,rtsm_ve,cortex_a9x4", "arm,vexpress";
  13578. + interrupt-parent = <&gic>;
  13579. + #address-cells = <1>;
  13580. + #size-cells = <1>;
  13581. +
  13582. + chosen { };
  13583. +
  13584. + aliases {
  13585. + serial0 = &v2m_serial0;
  13586. + serial1 = &v2m_serial1;
  13587. + serial2 = &v2m_serial2;
  13588. + serial3 = &v2m_serial3;
  13589. + };
  13590. +
  13591. + cpus {
  13592. + #address-cells = <1>;
  13593. + #size-cells = <0>;
  13594. +
  13595. + cpu@0 {
  13596. + device_type = "cpu";
  13597. + compatible = "arm,cortex-a9";
  13598. + reg = <0>;
  13599. + };
  13600. +
  13601. + cpu@1 {
  13602. + device_type = "cpu";
  13603. + compatible = "arm,cortex-a9";
  13604. + reg = <1>;
  13605. + };
  13606. +
  13607. + cpu@2 {
  13608. + device_type = "cpu";
  13609. + compatible = "arm,cortex-a9";
  13610. + reg = <2>;
  13611. + };
  13612. +
  13613. + cpu@3 {
  13614. + device_type = "cpu";
  13615. + compatible = "arm,cortex-a9";
  13616. + reg = <3>;
  13617. + };
  13618. + };
  13619. +
  13620. + memory@80000000 {
  13621. + device_type = "memory";
  13622. + reg = <0x80000000 0x80000000>;
  13623. + };
  13624. +
  13625. + scu@2c000000 {
  13626. + compatible = "arm,cortex-a9-scu";
  13627. + reg = <0x2c000000 0x58>;
  13628. + };
  13629. +
  13630. + timer@2c000600 {
  13631. + compatible = "arm,cortex-a9-twd-timer";
  13632. + reg = <0x2c000600 0x20>;
  13633. + interrupts = <1 13 0xf04>;
  13634. + };
  13635. +
  13636. + watchdog@2c000620 {
  13637. + compatible = "arm,cortex-a9-twd-wdt";
  13638. + reg = <0x2c000620 0x20>;
  13639. + interrupts = <1 14 0xf04>;
  13640. + };
  13641. +
  13642. + gic: interrupt-controller@2c001000 {
  13643. + compatible = "arm,cortex-a9-gic";
  13644. + #interrupt-cells = <3>;
  13645. + #address-cells = <0>;
  13646. + interrupt-controller;
  13647. + reg = <0x2c001000 0x1000>,
  13648. + <0x2c000100 0x100>;
  13649. + };
  13650. +
  13651. + dcc {
  13652. + compatible = "arm,vexpress,config-bus";
  13653. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13654. +
  13655. + osc@0 {
  13656. + /* ACLK clock to the AXI master port on the test chip */
  13657. + compatible = "arm,vexpress-osc";
  13658. + arm,vexpress-sysreg,func = <1 0>;
  13659. + freq-range = <30000000 50000000>;
  13660. + #clock-cells = <0>;
  13661. + clock-output-names = "extsaxiclk";
  13662. + };
  13663. +
  13664. + oscclk1: osc@1 {
  13665. + /* Reference clock for the CLCD */
  13666. + compatible = "arm,vexpress-osc";
  13667. + arm,vexpress-sysreg,func = <1 1>;
  13668. + freq-range = <10000000 80000000>;
  13669. + #clock-cells = <0>;
  13670. + clock-output-names = "clcdclk";
  13671. + };
  13672. +
  13673. + smbclk: oscclk2: osc@2 {
  13674. + /* Reference clock for the test chip internal PLLs */
  13675. + compatible = "arm,vexpress-osc";
  13676. + arm,vexpress-sysreg,func = <1 2>;
  13677. + freq-range = <33000000 100000000>;
  13678. + #clock-cells = <0>;
  13679. + clock-output-names = "tcrefclk";
  13680. + };
  13681. + };
  13682. +
  13683. + smb {
  13684. + compatible = "simple-bus";
  13685. +
  13686. + #address-cells = <2>;
  13687. + #size-cells = <1>;
  13688. + ranges = <0 0 0x08000000 0x04000000>,
  13689. + <1 0 0x14000000 0x04000000>,
  13690. + <2 0 0x18000000 0x04000000>,
  13691. + <3 0 0x1c000000 0x04000000>,
  13692. + <4 0 0x0c000000 0x04000000>,
  13693. + <5 0 0x10000000 0x04000000>;
  13694. +
  13695. + #interrupt-cells = <1>;
  13696. + interrupt-map-mask = <0 0 63>;
  13697. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13698. + <0 0 1 &gic 0 1 4>,
  13699. + <0 0 2 &gic 0 2 4>,
  13700. + <0 0 3 &gic 0 3 4>,
  13701. + <0 0 4 &gic 0 4 4>,
  13702. + <0 0 5 &gic 0 5 4>,
  13703. + <0 0 6 &gic 0 6 4>,
  13704. + <0 0 7 &gic 0 7 4>,
  13705. + <0 0 8 &gic 0 8 4>,
  13706. + <0 0 9 &gic 0 9 4>,
  13707. + <0 0 10 &gic 0 10 4>,
  13708. + <0 0 11 &gic 0 11 4>,
  13709. + <0 0 12 &gic 0 12 4>,
  13710. + <0 0 13 &gic 0 13 4>,
  13711. + <0 0 14 &gic 0 14 4>,
  13712. + <0 0 15 &gic 0 15 4>,
  13713. + <0 0 16 &gic 0 16 4>,
  13714. + <0 0 17 &gic 0 17 4>,
  13715. + <0 0 18 &gic 0 18 4>,
  13716. + <0 0 19 &gic 0 19 4>,
  13717. + <0 0 20 &gic 0 20 4>,
  13718. + <0 0 21 &gic 0 21 4>,
  13719. + <0 0 22 &gic 0 22 4>,
  13720. + <0 0 23 &gic 0 23 4>,
  13721. + <0 0 24 &gic 0 24 4>,
  13722. + <0 0 25 &gic 0 25 4>,
  13723. + <0 0 26 &gic 0 26 4>,
  13724. + <0 0 27 &gic 0 27 4>,
  13725. + <0 0 28 &gic 0 28 4>,
  13726. + <0 0 29 &gic 0 29 4>,
  13727. + <0 0 30 &gic 0 30 4>,
  13728. + <0 0 31 &gic 0 31 4>,
  13729. + <0 0 32 &gic 0 32 4>,
  13730. + <0 0 33 &gic 0 33 4>,
  13731. + <0 0 34 &gic 0 34 4>,
  13732. + <0 0 35 &gic 0 35 4>,
  13733. + <0 0 36 &gic 0 36 4>,
  13734. + <0 0 37 &gic 0 37 4>,
  13735. + <0 0 38 &gic 0 38 4>,
  13736. + <0 0 39 &gic 0 39 4>,
  13737. + <0 0 40 &gic 0 40 4>,
  13738. + <0 0 41 &gic 0 41 4>,
  13739. + <0 0 42 &gic 0 42 4>;
  13740. +
  13741. + /include/ "rtsm_ve-motherboard.dtsi"
  13742. + };
  13743. +};
  13744. +
  13745. +/include/ "clcd-panels.dtsi"
  13746. diff -Nur linux-3.14.15/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi
  13747. --- linux-3.14.15/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi 1970-01-01 01:00:00.000000000 +0100
  13748. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi 2014-08-20 19:23:45.550811652 +0200
  13749. @@ -0,0 +1,231 @@
  13750. +/*
  13751. + * ARM Ltd. Fast Models
  13752. + *
  13753. + * Versatile Express (VE) system model
  13754. + * Motherboard component
  13755. + *
  13756. + * VEMotherBoard.lisa
  13757. + */
  13758. +
  13759. + motherboard {
  13760. + compatible = "arm,vexpress,v2m-p1", "simple-bus";
  13761. + arm,hbi = <0x190>;
  13762. + arm,vexpress,site = <0>;
  13763. + arm,v2m-memory-map = "rs1";
  13764. + #address-cells = <2>; /* SMB chipselect number and offset */
  13765. + #size-cells = <1>;
  13766. + #interrupt-cells = <1>;
  13767. + ranges;
  13768. +
  13769. + flash@0,00000000 {
  13770. + compatible = "arm,vexpress-flash", "cfi-flash";
  13771. + reg = <0 0x00000000 0x04000000>,
  13772. + <4 0x00000000 0x04000000>;
  13773. + bank-width = <4>;
  13774. + };
  13775. +
  13776. + vram@2,00000000 {
  13777. + compatible = "arm,vexpress-vram";
  13778. + reg = <2 0x00000000 0x00800000>;
  13779. + };
  13780. +
  13781. + ethernet@2,02000000 {
  13782. + compatible = "smsc,lan91c111";
  13783. + reg = <2 0x02000000 0x10000>;
  13784. + interrupts = <15>;
  13785. + };
  13786. +
  13787. + iofpga@3,00000000 {
  13788. + compatible = "arm,amba-bus", "simple-bus";
  13789. + #address-cells = <1>;
  13790. + #size-cells = <1>;
  13791. + ranges = <0 3 0 0x200000>;
  13792. +
  13793. + v2m_sysreg: sysreg@010000 {
  13794. + compatible = "arm,vexpress-sysreg";
  13795. + reg = <0x010000 0x1000>;
  13796. + gpio-controller;
  13797. + #gpio-cells = <2>;
  13798. + };
  13799. +
  13800. + v2m_sysctl: sysctl@020000 {
  13801. + compatible = "arm,sp810", "arm,primecell";
  13802. + reg = <0x020000 0x1000>;
  13803. + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
  13804. + clock-names = "refclk", "timclk", "apb_pclk";
  13805. + #clock-cells = <1>;
  13806. + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
  13807. + };
  13808. +
  13809. + aaci@040000 {
  13810. + compatible = "arm,pl041", "arm,primecell";
  13811. + reg = <0x040000 0x1000>;
  13812. + interrupts = <11>;
  13813. + clocks = <&smbclk>;
  13814. + clock-names = "apb_pclk";
  13815. + };
  13816. +
  13817. + mmci@050000 {
  13818. + compatible = "arm,pl180", "arm,primecell";
  13819. + reg = <0x050000 0x1000>;
  13820. + interrupts = <9 10>;
  13821. + cd-gpios = <&v2m_sysreg 0 0>;
  13822. + wp-gpios = <&v2m_sysreg 1 0>;
  13823. + max-frequency = <12000000>;
  13824. + vmmc-supply = <&v2m_fixed_3v3>;
  13825. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13826. + clock-names = "mclk", "apb_pclk";
  13827. + };
  13828. +
  13829. + kmi@060000 {
  13830. + compatible = "arm,pl050", "arm,primecell";
  13831. + reg = <0x060000 0x1000>;
  13832. + interrupts = <12>;
  13833. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13834. + clock-names = "KMIREFCLK", "apb_pclk";
  13835. + };
  13836. +
  13837. + kmi@070000 {
  13838. + compatible = "arm,pl050", "arm,primecell";
  13839. + reg = <0x070000 0x1000>;
  13840. + interrupts = <13>;
  13841. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13842. + clock-names = "KMIREFCLK", "apb_pclk";
  13843. + };
  13844. +
  13845. + v2m_serial0: uart@090000 {
  13846. + compatible = "arm,pl011", "arm,primecell";
  13847. + reg = <0x090000 0x1000>;
  13848. + interrupts = <5>;
  13849. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13850. + clock-names = "uartclk", "apb_pclk";
  13851. + };
  13852. +
  13853. + v2m_serial1: uart@0a0000 {
  13854. + compatible = "arm,pl011", "arm,primecell";
  13855. + reg = <0x0a0000 0x1000>;
  13856. + interrupts = <6>;
  13857. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13858. + clock-names = "uartclk", "apb_pclk";
  13859. + };
  13860. +
  13861. + v2m_serial2: uart@0b0000 {
  13862. + compatible = "arm,pl011", "arm,primecell";
  13863. + reg = <0x0b0000 0x1000>;
  13864. + interrupts = <7>;
  13865. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13866. + clock-names = "uartclk", "apb_pclk";
  13867. + };
  13868. +
  13869. + v2m_serial3: uart@0c0000 {
  13870. + compatible = "arm,pl011", "arm,primecell";
  13871. + reg = <0x0c0000 0x1000>;
  13872. + interrupts = <8>;
  13873. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13874. + clock-names = "uartclk", "apb_pclk";
  13875. + };
  13876. +
  13877. + wdt@0f0000 {
  13878. + compatible = "arm,sp805", "arm,primecell";
  13879. + reg = <0x0f0000 0x1000>;
  13880. + interrupts = <0>;
  13881. + clocks = <&v2m_refclk32khz>, <&smbclk>;
  13882. + clock-names = "wdogclk", "apb_pclk";
  13883. + };
  13884. +
  13885. + v2m_timer01: timer@110000 {
  13886. + compatible = "arm,sp804", "arm,primecell";
  13887. + reg = <0x110000 0x1000>;
  13888. + interrupts = <2>;
  13889. + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
  13890. + clock-names = "timclken1", "timclken2", "apb_pclk";
  13891. + };
  13892. +
  13893. + v2m_timer23: timer@120000 {
  13894. + compatible = "arm,sp804", "arm,primecell";
  13895. + reg = <0x120000 0x1000>;
  13896. + interrupts = <3>;
  13897. + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
  13898. + clock-names = "timclken1", "timclken2", "apb_pclk";
  13899. + };
  13900. +
  13901. + rtc@170000 {
  13902. + compatible = "arm,pl031", "arm,primecell";
  13903. + reg = <0x170000 0x1000>;
  13904. + interrupts = <4>;
  13905. + clocks = <&smbclk>;
  13906. + clock-names = "apb_pclk";
  13907. + };
  13908. +
  13909. + clcd@1f0000 {
  13910. + compatible = "arm,pl111", "arm,primecell";
  13911. + reg = <0x1f0000 0x1000>;
  13912. + interrupts = <14>;
  13913. + clocks = <&v2m_oscclk1>, <&smbclk>;
  13914. + clock-names = "v2m:oscclk1", "apb_pclk";
  13915. + mode = "VGA";
  13916. + use_dma = <0>;
  13917. + framebuffer = <0x18000000 0x00180000>;
  13918. + };
  13919. +
  13920. + virtio_block@0130000 {
  13921. + compatible = "virtio,mmio";
  13922. + reg = <0x130000 0x200>;
  13923. + interrupts = <42>;
  13924. + };
  13925. +
  13926. + };
  13927. +
  13928. + v2m_fixed_3v3: fixedregulator@0 {
  13929. + compatible = "regulator-fixed";
  13930. + regulator-name = "3V3";
  13931. + regulator-min-microvolt = <3300000>;
  13932. + regulator-max-microvolt = <3300000>;
  13933. + regulator-always-on;
  13934. + };
  13935. +
  13936. + v2m_clk24mhz: clk24mhz {
  13937. + compatible = "fixed-clock";
  13938. + #clock-cells = <0>;
  13939. + clock-frequency = <24000000>;
  13940. + clock-output-names = "v2m:clk24mhz";
  13941. + };
  13942. +
  13943. + v2m_refclk1mhz: refclk1mhz {
  13944. + compatible = "fixed-clock";
  13945. + #clock-cells = <0>;
  13946. + clock-frequency = <1000000>;
  13947. + clock-output-names = "v2m:refclk1mhz";
  13948. + };
  13949. +
  13950. + v2m_refclk32khz: refclk32khz {
  13951. + compatible = "fixed-clock";
  13952. + #clock-cells = <0>;
  13953. + clock-frequency = <32768>;
  13954. + clock-output-names = "v2m:refclk32khz";
  13955. + };
  13956. +
  13957. + mcc {
  13958. + compatible = "simple-bus";
  13959. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13960. +
  13961. + v2m_oscclk1: osc@1 {
  13962. + /* CLCD clock */
  13963. + compatible = "arm,vexpress-osc";
  13964. + arm,vexpress-sysreg,func = <1 1>;
  13965. + freq-range = <23750000 63500000>;
  13966. + #clock-cells = <0>;
  13967. + clock-output-names = "v2m:oscclk1";
  13968. + };
  13969. +
  13970. + muxfpga@0 {
  13971. + compatible = "arm,vexpress-muxfpga";
  13972. + arm,vexpress-sysreg,func = <7 0>;
  13973. + };
  13974. +
  13975. + shutdown@0 {
  13976. + compatible = "arm,vexpress-shutdown";
  13977. + arm,vexpress-sysreg,func = <8 0>;
  13978. + };
  13979. + };
  13980. + };
  13981. diff -Nur linux-3.14.15/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts
  13982. --- linux-3.14.15/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts 1970-01-01 01:00:00.000000000 +0100
  13983. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts 2014-08-20 19:31:39.940842444 +0200
  13984. @@ -0,0 +1,233 @@
  13985. +/*
  13986. + * ARM Ltd. Fast Models
  13987. + *
  13988. + * Versatile Express (VE) system model
  13989. + * ARMCortexA15x4CT
  13990. + * ARMCortexA7x4CT
  13991. + * RTSM_VE_Cortex_A15x1_A7x1.lisa
  13992. + */
  13993. +
  13994. +/dts-v1/;
  13995. +
  13996. +/memreserve/ 0xff000000 0x01000000;
  13997. +
  13998. +/ {
  13999. + model = "RTSM_VE_CortexA15x1-A7x1";
  14000. + arm,vexpress,site = <0xf>;
  14001. + compatible = "arm,rtsm_ve,cortex_a15x1_a7x1", "arm,vexpress";
  14002. + interrupt-parent = <&gic>;
  14003. + #address-cells = <2>;
  14004. + #size-cells = <2>;
  14005. +
  14006. + chosen { };
  14007. +
  14008. + aliases {
  14009. + serial0 = &v2m_serial0;
  14010. + serial1 = &v2m_serial1;
  14011. + serial2 = &v2m_serial2;
  14012. + serial3 = &v2m_serial3;
  14013. + };
  14014. +
  14015. + clusters {
  14016. + #address-cells = <1>;
  14017. + #size-cells = <0>;
  14018. +
  14019. + cluster0: cluster@0 {
  14020. + reg = <0>;
  14021. +// freqs = <500000000 600000000 700000000 800000000 900000000 1000000000 1100000000 1200000000>;
  14022. + cores {
  14023. + #address-cells = <1>;
  14024. + #size-cells = <0>;
  14025. +
  14026. + core0: core@0 {
  14027. + reg = <0>;
  14028. + };
  14029. +
  14030. + };
  14031. + };
  14032. +
  14033. + cluster1: cluster@1 {
  14034. + reg = <1>;
  14035. +// freqs = <350000000 400000000 500000000 600000000 700000000 800000000 900000000 1000000000>;
  14036. + cores {
  14037. + #address-cells = <1>;
  14038. + #size-cells = <0>;
  14039. +
  14040. + core1: core@0 {
  14041. + reg = <0>;
  14042. + };
  14043. +
  14044. + };
  14045. + };
  14046. + };
  14047. +
  14048. + cpus {
  14049. + #address-cells = <1>;
  14050. + #size-cells = <0>;
  14051. +
  14052. + cpu0: cpu@0 {
  14053. + device_type = "cpu";
  14054. + compatible = "arm,cortex-a15";
  14055. + reg = <0>;
  14056. + cluster = <&cluster0>;
  14057. + core = <&core0>;
  14058. +// clock-frequency = <1000000000>;
  14059. + cci-control-port = <&cci_control1>;
  14060. + };
  14061. +
  14062. + cpu1: cpu@1 {
  14063. + device_type = "cpu";
  14064. + compatible = "arm,cortex-a7";
  14065. + reg = <0x100>;
  14066. + cluster = <&cluster1>;
  14067. + core = <&core1>;
  14068. +// clock-frequency = <800000000>;
  14069. + cci-control-port = <&cci_control2>;
  14070. + };
  14071. + };
  14072. +
  14073. + memory@80000000 {
  14074. + device_type = "memory";
  14075. + reg = <0 0x80000000 0 0x80000000>;
  14076. + };
  14077. +
  14078. + cci@2c090000 {
  14079. + compatible = "arm,cci-400", "arm,cci";
  14080. + #address-cells = <1>;
  14081. + #size-cells = <1>;
  14082. + reg = <0 0x2c090000 0 0x1000>;
  14083. + ranges = <0x0 0x0 0x2c090000 0x10000>;
  14084. +
  14085. + cci_control1: slave-if@4000 {
  14086. + compatible = "arm,cci-400-ctrl-if";
  14087. + interface-type = "ace";
  14088. + reg = <0x4000 0x1000>;
  14089. + };
  14090. +
  14091. + cci_control2: slave-if@5000 {
  14092. + compatible = "arm,cci-400-ctrl-if";
  14093. + interface-type = "ace";
  14094. + reg = <0x5000 0x1000>;
  14095. + };
  14096. + };
  14097. +
  14098. + dcscb@60000000 {
  14099. + compatible = "arm,rtsm,dcscb";
  14100. + reg = <0 0x60000000 0 0x1000>;
  14101. + };
  14102. +
  14103. + gic: interrupt-controller@2c001000 {
  14104. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  14105. + #interrupt-cells = <3>;
  14106. + #address-cells = <0>;
  14107. + interrupt-controller;
  14108. + reg = <0 0x2c001000 0 0x1000>,
  14109. + <0 0x2c002000 0 0x1000>,
  14110. + <0 0x2c004000 0 0x2000>,
  14111. + <0 0x2c006000 0 0x2000>;
  14112. + interrupts = <1 9 0xf04>;
  14113. + };
  14114. +
  14115. + timer {
  14116. + compatible = "arm,armv7-timer";
  14117. + interrupts = <1 13 0xf08>,
  14118. + <1 14 0xf08>,
  14119. + <1 11 0xf08>,
  14120. + <1 10 0xf08>;
  14121. + };
  14122. +
  14123. + dcc {
  14124. + compatible = "arm,vexpress,config-bus";
  14125. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  14126. +
  14127. + osc@0 {
  14128. + /* ACLK clock to the AXI master port on the test chip */
  14129. + compatible = "arm,vexpress-osc";
  14130. + arm,vexpress-sysreg,func = <1 0>;
  14131. + freq-range = <30000000 50000000>;
  14132. + #clock-cells = <0>;
  14133. + clock-output-names = "extsaxiclk";
  14134. + };
  14135. +
  14136. + oscclk1: osc@1 {
  14137. + /* Reference clock for the CLCD */
  14138. + compatible = "arm,vexpress-osc";
  14139. + arm,vexpress-sysreg,func = <1 1>;
  14140. + freq-range = <10000000 80000000>;
  14141. + #clock-cells = <0>;
  14142. + clock-output-names = "clcdclk";
  14143. + };
  14144. +
  14145. + smbclk: oscclk2: osc@2 {
  14146. + /* Reference clock for the test chip internal PLLs */
  14147. + compatible = "arm,vexpress-osc";
  14148. + arm,vexpress-sysreg,func = <1 2>;
  14149. + freq-range = <33000000 100000000>;
  14150. + #clock-cells = <0>;
  14151. + clock-output-names = "tcrefclk";
  14152. + };
  14153. + };
  14154. +
  14155. + smb {
  14156. + compatible = "simple-bus";
  14157. +
  14158. + #address-cells = <2>;
  14159. + #size-cells = <1>;
  14160. + ranges = <0 0 0 0x08000000 0x04000000>,
  14161. + <1 0 0 0x14000000 0x04000000>,
  14162. + <2 0 0 0x18000000 0x04000000>,
  14163. + <3 0 0 0x1c000000 0x04000000>,
  14164. + <4 0 0 0x0c000000 0x04000000>,
  14165. + <5 0 0 0x10000000 0x04000000>;
  14166. +
  14167. + #interrupt-cells = <1>;
  14168. + interrupt-map-mask = <0 0 63>;
  14169. + interrupt-map = <0 0 0 &gic 0 0 4>,
  14170. + <0 0 1 &gic 0 1 4>,
  14171. + <0 0 2 &gic 0 2 4>,
  14172. + <0 0 3 &gic 0 3 4>,
  14173. + <0 0 4 &gic 0 4 4>,
  14174. + <0 0 5 &gic 0 5 4>,
  14175. + <0 0 6 &gic 0 6 4>,
  14176. + <0 0 7 &gic 0 7 4>,
  14177. + <0 0 8 &gic 0 8 4>,
  14178. + <0 0 9 &gic 0 9 4>,
  14179. + <0 0 10 &gic 0 10 4>,
  14180. + <0 0 11 &gic 0 11 4>,
  14181. + <0 0 12 &gic 0 12 4>,
  14182. + <0 0 13 &gic 0 13 4>,
  14183. + <0 0 14 &gic 0 14 4>,
  14184. + <0 0 15 &gic 0 15 4>,
  14185. + <0 0 16 &gic 0 16 4>,
  14186. + <0 0 17 &gic 0 17 4>,
  14187. + <0 0 18 &gic 0 18 4>,
  14188. + <0 0 19 &gic 0 19 4>,
  14189. + <0 0 20 &gic 0 20 4>,
  14190. + <0 0 21 &gic 0 21 4>,
  14191. + <0 0 22 &gic 0 22 4>,
  14192. + <0 0 23 &gic 0 23 4>,
  14193. + <0 0 24 &gic 0 24 4>,
  14194. + <0 0 25 &gic 0 25 4>,
  14195. + <0 0 26 &gic 0 26 4>,
  14196. + <0 0 27 &gic 0 27 4>,
  14197. + <0 0 28 &gic 0 28 4>,
  14198. + <0 0 29 &gic 0 29 4>,
  14199. + <0 0 30 &gic 0 30 4>,
  14200. + <0 0 31 &gic 0 31 4>,
  14201. + <0 0 32 &gic 0 32 4>,
  14202. + <0 0 33 &gic 0 33 4>,
  14203. + <0 0 34 &gic 0 34 4>,
  14204. + <0 0 35 &gic 0 35 4>,
  14205. + <0 0 36 &gic 0 36 4>,
  14206. + <0 0 37 &gic 0 37 4>,
  14207. + <0 0 38 &gic 0 38 4>,
  14208. + <0 0 39 &gic 0 39 4>,
  14209. + <0 0 40 &gic 0 40 4>,
  14210. + <0 0 41 &gic 0 41 4>,
  14211. + <0 0 42 &gic 0 42 4>;
  14212. +
  14213. + /include/ "rtsm_ve-motherboard.dtsi"
  14214. + };
  14215. +};
  14216. +
  14217. +/include/ "clcd-panels.dtsi"
  14218. diff -Nur linux-3.14.15/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts
  14219. --- linux-3.14.15/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts 1970-01-01 01:00:00.000000000 +0100
  14220. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts 2014-08-20 19:31:39.940842444 +0200
  14221. @@ -0,0 +1,317 @@
  14222. +/*
  14223. + * ARM Ltd. Fast Models
  14224. + *
  14225. + * Versatile Express (VE) system model
  14226. + * ARMCortexA15x4CT
  14227. + * ARMCortexA7x4CT
  14228. + * RTSM_VE_Cortex_A15x4_A7x4.lisa
  14229. + */
  14230. +
  14231. +/dts-v1/;
  14232. +
  14233. +/memreserve/ 0xff000000 0x01000000;
  14234. +
  14235. +/ {
  14236. + model = "RTSM_VE_CortexA15x4-A7x4";
  14237. + arm,vexpress,site = <0xf>;
  14238. + compatible = "arm,rtsm_ve,cortex_a15x4_a7x4", "arm,vexpress";
  14239. + interrupt-parent = <&gic>;
  14240. + #address-cells = <2>;
  14241. + #size-cells = <2>;
  14242. +
  14243. + chosen { };
  14244. +
  14245. + aliases {
  14246. + serial0 = &v2m_serial0;
  14247. + serial1 = &v2m_serial1;
  14248. + serial2 = &v2m_serial2;
  14249. + serial3 = &v2m_serial3;
  14250. + };
  14251. +
  14252. + clusters {
  14253. + #address-cells = <1>;
  14254. + #size-cells = <0>;
  14255. +
  14256. + cluster0: cluster@0 {
  14257. + reg = <0>;
  14258. +// freqs = <500000000 600000000 700000000 800000000 900000000 1000000000 1100000000 1200000000>;
  14259. + cores {
  14260. + #address-cells = <1>;
  14261. + #size-cells = <0>;
  14262. +
  14263. + core0: core@0 {
  14264. + reg = <0>;
  14265. + };
  14266. +
  14267. + core1: core@1 {
  14268. + reg = <1>;
  14269. + };
  14270. +
  14271. + core2: core@2 {
  14272. + reg = <2>;
  14273. + };
  14274. +
  14275. + core3: core@3 {
  14276. + reg = <3>;
  14277. + };
  14278. +
  14279. + };
  14280. + };
  14281. +
  14282. + cluster1: cluster@1 {
  14283. + reg = <1>;
  14284. +// freqs = <350000000 400000000 500000000 600000000 700000000 800000000 900000000 1000000000>;
  14285. + cores {
  14286. + #address-cells = <1>;
  14287. + #size-cells = <0>;
  14288. +
  14289. + core4: core@0 {
  14290. + reg = <0>;
  14291. + };
  14292. +
  14293. + core5: core@1 {
  14294. + reg = <1>;
  14295. + };
  14296. +
  14297. + core6: core@2 {
  14298. + reg = <2>;
  14299. + };
  14300. +
  14301. + core7: core@3 {
  14302. + reg = <3>;
  14303. + };
  14304. +
  14305. + };
  14306. + };
  14307. + };
  14308. +
  14309. + cpus {
  14310. + #address-cells = <1>;
  14311. + #size-cells = <0>;
  14312. +
  14313. + cpu0: cpu@0 {
  14314. + device_type = "cpu";
  14315. + compatible = "arm,cortex-a15";
  14316. + reg = <0>;
  14317. + cluster = <&cluster0>;
  14318. + core = <&core0>;
  14319. +// clock-frequency = <1000000000>;
  14320. + cci-control-port = <&cci_control1>;
  14321. + };
  14322. +
  14323. + cpu1: cpu@1 {
  14324. + device_type = "cpu";
  14325. + compatible = "arm,cortex-a15";
  14326. + reg = <1>;
  14327. + cluster = <&cluster0>;
  14328. + core = <&core1>;
  14329. +// clock-frequency = <1000000000>;
  14330. + cci-control-port = <&cci_control1>;
  14331. + };
  14332. +
  14333. + cpu2: cpu@2 {
  14334. + device_type = "cpu";
  14335. + compatible = "arm,cortex-a15";
  14336. + reg = <2>;
  14337. + cluster = <&cluster0>;
  14338. + core = <&core2>;
  14339. +// clock-frequency = <1000000000>;
  14340. + cci-control-port = <&cci_control1>;
  14341. + };
  14342. +
  14343. + cpu3: cpu@3 {
  14344. + device_type = "cpu";
  14345. + compatible = "arm,cortex-a15";
  14346. + reg = <3>;
  14347. + cluster = <&cluster0>;
  14348. + core = <&core3>;
  14349. +// clock-frequency = <1000000000>;
  14350. + cci-control-port = <&cci_control1>;
  14351. + };
  14352. +
  14353. + cpu4: cpu@4 {
  14354. + device_type = "cpu";
  14355. + compatible = "arm,cortex-a7";
  14356. + reg = <0x100>;
  14357. + cluster = <&cluster1>;
  14358. + core = <&core4>;
  14359. +// clock-frequency = <800000000>;
  14360. + cci-control-port = <&cci_control2>;
  14361. + };
  14362. +
  14363. + cpu5: cpu@5 {
  14364. + device_type = "cpu";
  14365. + compatible = "arm,cortex-a7";
  14366. + reg = <0x101>;
  14367. + cluster = <&cluster1>;
  14368. + core = <&core5>;
  14369. +// clock-frequency = <800000000>;
  14370. + cci-control-port = <&cci_control2>;
  14371. + };
  14372. +
  14373. + cpu6: cpu@6 {
  14374. + device_type = "cpu";
  14375. + compatible = "arm,cortex-a7";
  14376. + reg = <0x102>;
  14377. + cluster = <&cluster1>;
  14378. + core = <&core6>;
  14379. +// clock-frequency = <800000000>;
  14380. + cci-control-port = <&cci_control2>;
  14381. + };
  14382. +
  14383. + cpu7: cpu@7 {
  14384. + device_type = "cpu";
  14385. + compatible = "arm,cortex-a7";
  14386. + reg = <0x103>;
  14387. + cluster = <&cluster1>;
  14388. + core = <&core7>;
  14389. +// clock-frequency = <800000000>;
  14390. + cci-control-port = <&cci_control2>;
  14391. + };
  14392. + };
  14393. +
  14394. + memory@80000000 {
  14395. + device_type = "memory";
  14396. + reg = <0 0x80000000 0 0x80000000>;
  14397. + };
  14398. +
  14399. + cci@2c090000 {
  14400. + compatible = "arm,cci-400", "arm,cci";
  14401. + #address-cells = <1>;
  14402. + #size-cells = <1>;
  14403. + reg = <0 0x2c090000 0 0x1000>;
  14404. + ranges = <0x0 0x0 0x2c090000 0x10000>;
  14405. +
  14406. + cci_control1: slave-if@4000 {
  14407. + compatible = "arm,cci-400-ctrl-if";
  14408. + interface-type = "ace";
  14409. + reg = <0x4000 0x1000>;
  14410. + };
  14411. +
  14412. + cci_control2: slave-if@5000 {
  14413. + compatible = "arm,cci-400-ctrl-if";
  14414. + interface-type = "ace";
  14415. + reg = <0x5000 0x1000>;
  14416. + };
  14417. + };
  14418. +
  14419. + dcscb@60000000 {
  14420. + compatible = "arm,rtsm,dcscb";
  14421. + reg = <0 0x60000000 0 0x1000>;
  14422. + };
  14423. +
  14424. + gic: interrupt-controller@2c001000 {
  14425. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  14426. + #interrupt-cells = <3>;
  14427. + #address-cells = <0>;
  14428. + interrupt-controller;
  14429. + reg = <0 0x2c001000 0 0x1000>,
  14430. + <0 0x2c002000 0 0x1000>,
  14431. + <0 0x2c004000 0 0x2000>,
  14432. + <0 0x2c006000 0 0x2000>;
  14433. + interrupts = <1 9 0xf04>;
  14434. + };
  14435. +
  14436. + timer {
  14437. + compatible = "arm,armv7-timer";
  14438. + interrupts = <1 13 0xf08>,
  14439. + <1 14 0xf08>,
  14440. + <1 11 0xf08>,
  14441. + <1 10 0xf08>;
  14442. + };
  14443. +
  14444. + dcc {
  14445. + compatible = "arm,vexpress,config-bus";
  14446. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  14447. +
  14448. + osc@0 {
  14449. + /* ACLK clock to the AXI master port on the test chip */
  14450. + compatible = "arm,vexpress-osc";
  14451. + arm,vexpress-sysreg,func = <1 0>;
  14452. + freq-range = <30000000 50000000>;
  14453. + #clock-cells = <0>;
  14454. + clock-output-names = "extsaxiclk";
  14455. + };
  14456. +
  14457. + oscclk1: osc@1 {
  14458. + /* Reference clock for the CLCD */
  14459. + compatible = "arm,vexpress-osc";
  14460. + arm,vexpress-sysreg,func = <1 1>;
  14461. + freq-range = <10000000 80000000>;
  14462. + #clock-cells = <0>;
  14463. + clock-output-names = "clcdclk";
  14464. + };
  14465. +
  14466. + smbclk: oscclk2: osc@2 {
  14467. + /* Reference clock for the test chip internal PLLs */
  14468. + compatible = "arm,vexpress-osc";
  14469. + arm,vexpress-sysreg,func = <1 2>;
  14470. + freq-range = <33000000 100000000>;
  14471. + #clock-cells = <0>;
  14472. + clock-output-names = "tcrefclk";
  14473. + };
  14474. + };
  14475. +
  14476. + smb {
  14477. + compatible = "simple-bus";
  14478. +
  14479. + #address-cells = <2>;
  14480. + #size-cells = <1>;
  14481. + ranges = <0 0 0 0x08000000 0x04000000>,
  14482. + <1 0 0 0x14000000 0x04000000>,
  14483. + <2 0 0 0x18000000 0x04000000>,
  14484. + <3 0 0 0x1c000000 0x04000000>,
  14485. + <4 0 0 0x0c000000 0x04000000>,
  14486. + <5 0 0 0x10000000 0x04000000>;
  14487. +
  14488. + #interrupt-cells = <1>;
  14489. + interrupt-map-mask = <0 0 63>;
  14490. + interrupt-map = <0 0 0 &gic 0 0 4>,
  14491. + <0 0 1 &gic 0 1 4>,
  14492. + <0 0 2 &gic 0 2 4>,
  14493. + <0 0 3 &gic 0 3 4>,
  14494. + <0 0 4 &gic 0 4 4>,
  14495. + <0 0 5 &gic 0 5 4>,
  14496. + <0 0 6 &gic 0 6 4>,
  14497. + <0 0 7 &gic 0 7 4>,
  14498. + <0 0 8 &gic 0 8 4>,
  14499. + <0 0 9 &gic 0 9 4>,
  14500. + <0 0 10 &gic 0 10 4>,
  14501. + <0 0 11 &gic 0 11 4>,
  14502. + <0 0 12 &gic 0 12 4>,
  14503. + <0 0 13 &gic 0 13 4>,
  14504. + <0 0 14 &gic 0 14 4>,
  14505. + <0 0 15 &gic 0 15 4>,
  14506. + <0 0 16 &gic 0 16 4>,
  14507. + <0 0 17 &gic 0 17 4>,
  14508. + <0 0 18 &gic 0 18 4>,
  14509. + <0 0 19 &gic 0 19 4>,
  14510. + <0 0 20 &gic 0 20 4>,
  14511. + <0 0 21 &gic 0 21 4>,
  14512. + <0 0 22 &gic 0 22 4>,
  14513. + <0 0 23 &gic 0 23 4>,
  14514. + <0 0 24 &gic 0 24 4>,
  14515. + <0 0 25 &gic 0 25 4>,
  14516. + <0 0 26 &gic 0 26 4>,
  14517. + <0 0 27 &gic 0 27 4>,
  14518. + <0 0 28 &gic 0 28 4>,
  14519. + <0 0 29 &gic 0 29 4>,
  14520. + <0 0 30 &gic 0 30 4>,
  14521. + <0 0 31 &gic 0 31 4>,
  14522. + <0 0 32 &gic 0 32 4>,
  14523. + <0 0 33 &gic 0 33 4>,
  14524. + <0 0 34 &gic 0 34 4>,
  14525. + <0 0 35 &gic 0 35 4>,
  14526. + <0 0 36 &gic 0 36 4>,
  14527. + <0 0 37 &gic 0 37 4>,
  14528. + <0 0 38 &gic 0 38 4>,
  14529. + <0 0 39 &gic 0 39 4>,
  14530. + <0 0 40 &gic 0 40 4>,
  14531. + <0 0 41 &gic 0 41 4>,
  14532. + <0 0 42 &gic 0 42 4>;
  14533. +
  14534. + /include/ "rtsm_ve-motherboard.dtsi"
  14535. + };
  14536. +};
  14537. +
  14538. +/include/ "clcd-panels.dtsi"
  14539. diff -Nur linux-3.14.15/arch/arm/boot/dts/vexpress-v2m.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2m.dtsi
  14540. --- linux-3.14.15/arch/arm/boot/dts/vexpress-v2m.dtsi 2014-07-31 23:51:43.000000000 +0200
  14541. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2m.dtsi 2014-08-20 19:23:45.558811686 +0200
  14542. @@ -227,6 +227,7 @@
  14543. };
  14544. clcd@1f000 {
  14545. + status = "disabled";
  14546. compatible = "arm,pl111", "arm,primecell";
  14547. reg = <0x1f000 0x1000>;
  14548. interrupts = <14>;
  14549. diff -Nur linux-3.14.15/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
  14550. --- linux-3.14.15/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi 2014-07-31 23:51:43.000000000 +0200
  14551. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi 2014-08-20 19:23:45.558811686 +0200
  14552. @@ -228,6 +228,7 @@
  14553. };
  14554. clcd@1f0000 {
  14555. + status = "disabled";
  14556. compatible = "arm,pl111", "arm,primecell";
  14557. reg = <0x1f0000 0x1000>;
  14558. interrupts = <14>;
  14559. diff -Nur linux-3.14.15/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
  14560. --- linux-3.14.15/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts 2014-07-31 23:51:43.000000000 +0200
  14561. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts 2014-08-20 19:31:39.956842513 +0200
  14562. @@ -9,6 +9,8 @@
  14563. /dts-v1/;
  14564. +/memreserve/ 0xff000000 0x01000000;
  14565. +
  14566. / {
  14567. model = "V2P-CA15_CA7";
  14568. arm,hbi = <0x249>;
  14569. @@ -29,29 +31,60 @@
  14570. i2c1 = &v2m_i2c_pcie;
  14571. };
  14572. - cpus {
  14573. + clusters {
  14574. #address-cells = <1>;
  14575. #size-cells = <0>;
  14576. - cpu0: cpu@0 {
  14577. - device_type = "cpu";
  14578. - compatible = "arm,cortex-a15";
  14579. + cluster0: cluster@0 {
  14580. reg = <0>;
  14581. - cci-control-port = <&cci_control1>;
  14582. + cores {
  14583. + #address-cells = <1>;
  14584. + #size-cells = <0>;
  14585. +
  14586. + core0: core@0 {
  14587. + reg = <0>;
  14588. + };
  14589. +
  14590. + core1: core@1 {
  14591. + reg = <1>;
  14592. + };
  14593. +
  14594. + };
  14595. };
  14596. - cpu1: cpu@1 {
  14597. - device_type = "cpu";
  14598. - compatible = "arm,cortex-a15";
  14599. + cluster1: cluster@1 {
  14600. reg = <1>;
  14601. - cci-control-port = <&cci_control1>;
  14602. + cores {
  14603. + #address-cells = <1>;
  14604. + #size-cells = <0>;
  14605. +
  14606. + core2: core@0 {
  14607. + reg = <0>;
  14608. + };
  14609. +
  14610. + core3: core@1 {
  14611. + reg = <1>;
  14612. + };
  14613. +
  14614. + core4: core@2 {
  14615. + reg = <2>;
  14616. + };
  14617. + };
  14618. };
  14619. + };
  14620. +
  14621. + cpus {
  14622. + #address-cells = <1>;
  14623. + #size-cells = <0>;
  14624. cpu2: cpu@2 {
  14625. device_type = "cpu";
  14626. compatible = "arm,cortex-a7";
  14627. reg = <0x100>;
  14628. cci-control-port = <&cci_control2>;
  14629. + cluster = <&cluster1>;
  14630. + core = <&core2>;
  14631. + clock-frequency = <800000000>;
  14632. };
  14633. cpu3: cpu@3 {
  14634. @@ -59,6 +92,9 @@
  14635. compatible = "arm,cortex-a7";
  14636. reg = <0x101>;
  14637. cci-control-port = <&cci_control2>;
  14638. + cluster = <&cluster1>;
  14639. + core = <&core3>;
  14640. + clock-frequency = <800000000>;
  14641. };
  14642. cpu4: cpu@4 {
  14643. @@ -66,12 +102,35 @@
  14644. compatible = "arm,cortex-a7";
  14645. reg = <0x102>;
  14646. cci-control-port = <&cci_control2>;
  14647. + cluster = <&cluster1>;
  14648. + core = <&core4>;
  14649. + clock-frequency = <800000000>;
  14650. + };
  14651. +
  14652. + cpu0: cpu@0 {
  14653. + device_type = "cpu";
  14654. + compatible = "arm,cortex-a15";
  14655. + reg = <0>;
  14656. + cci-control-port = <&cci_control1>;
  14657. + cluster = <&cluster0>;
  14658. + core = <&core0>;
  14659. + clock-frequency = <1000000000>;
  14660. + };
  14661. +
  14662. + cpu1: cpu@1 {
  14663. + device_type = "cpu";
  14664. + compatible = "arm,cortex-a15";
  14665. + reg = <1>;
  14666. + cci-control-port = <&cci_control1>;
  14667. + cluster = <&cluster0>;
  14668. + core = <&core1>;
  14669. + clock-frequency = <1000000000>;
  14670. };
  14671. };
  14672. memory@80000000 {
  14673. device_type = "memory";
  14674. - reg = <0 0x80000000 0 0x40000000>;
  14675. + reg = <0 0x80000000 0 0x80000000>;
  14676. };
  14677. wdt@2a490000 {
  14678. @@ -86,6 +145,8 @@
  14679. compatible = "arm,hdlcd";
  14680. reg = <0 0x2b000000 0 0x1000>;
  14681. interrupts = <0 85 4>;
  14682. + mode = "1024x768-16@60";
  14683. + framebuffer = <0 0xff000000 0 0x01000000>;
  14684. clocks = <&oscclk5>;
  14685. clock-names = "pxlclk";
  14686. };
  14687. @@ -127,6 +188,16 @@
  14688. interface-type = "ace";
  14689. reg = <0x5000 0x1000>;
  14690. };
  14691. +
  14692. + pmu@9000 {
  14693. + compatible = "arm,cci-400-pmu";
  14694. + reg = <0x9000 0x5000>;
  14695. + interrupts = <0 101 4>,
  14696. + <0 102 4>,
  14697. + <0 103 4>,
  14698. + <0 104 4>,
  14699. + <0 105 4>;
  14700. + };
  14701. };
  14702. memory-controller@7ffd0000 {
  14703. @@ -164,12 +235,21 @@
  14704. <1 10 0xf08>;
  14705. };
  14706. - pmu {
  14707. + pmu_a15 {
  14708. compatible = "arm,cortex-a15-pmu";
  14709. + cluster = <&cluster0>;
  14710. interrupts = <0 68 4>,
  14711. <0 69 4>;
  14712. };
  14713. + pmu_a7 {
  14714. + compatible = "arm,cortex-a7-pmu";
  14715. + cluster = <&cluster1>;
  14716. + interrupts = <0 128 4>,
  14717. + <0 129 4>,
  14718. + <0 130 4>;
  14719. + };
  14720. +
  14721. oscclk6a: oscclk6a {
  14722. /* Reference 24MHz clock */
  14723. compatible = "fixed-clock";
  14724. @@ -178,6 +258,19 @@
  14725. clock-output-names = "oscclk6a";
  14726. };
  14727. +/* PSCI requires support from firmware and is not present in the normal TC2
  14728. + * distribution, so this node is commented out by default...
  14729. +
  14730. + psci {
  14731. + compatible = "arm,psci";
  14732. + method = "smc";
  14733. + cpu_suspend = <0x80100001>;
  14734. + cpu_off = <0x80100002>;
  14735. + cpu_on = <0x80100003>;
  14736. + migrate = <0x80100004>;
  14737. + };
  14738. +*/
  14739. +
  14740. dcc {
  14741. compatible = "arm,vexpress,config-bus";
  14742. arm,vexpress,config-bridge = <&v2m_sysreg>;
  14743. diff -Nur linux-3.14.15/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
  14744. --- linux-3.14.15/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts 2014-07-31 23:51:43.000000000 +0200
  14745. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts 2014-08-20 19:31:39.956842513 +0200
  14746. @@ -9,6 +9,8 @@
  14747. /dts-v1/;
  14748. +/memreserve/ 0xbf000000 0x01000000;
  14749. +
  14750. / {
  14751. model = "V2P-CA15";
  14752. arm,hbi = <0x237>;
  14753. @@ -57,6 +59,8 @@
  14754. interrupts = <0 85 4>;
  14755. clocks = <&oscclk5>;
  14756. clock-names = "pxlclk";
  14757. + mode = "1024x768-16@60";
  14758. + framebuffer = <0 0xbf000000 0 0x01000000>;
  14759. };
  14760. memory-controller@2b0a0000 {
  14761. diff -Nur linux-3.14.15/arch/arm/boot/dts/vexpress-v2p-ca5s.dts linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
  14762. --- linux-3.14.15/arch/arm/boot/dts/vexpress-v2p-ca5s.dts 2014-07-31 23:51:43.000000000 +0200
  14763. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2p-ca5s.dts 2014-08-20 19:23:45.558811686 +0200
  14764. @@ -9,6 +9,8 @@
  14765. /dts-v1/;
  14766. +/memreserve/ 0xbf000000 0x01000000;
  14767. +
  14768. / {
  14769. model = "V2P-CA5s";
  14770. arm,hbi = <0x225>;
  14771. @@ -59,6 +61,8 @@
  14772. interrupts = <0 85 4>;
  14773. clocks = <&oscclk3>;
  14774. clock-names = "pxlclk";
  14775. + mode = "640x480-16@60";
  14776. + framebuffer = <0xbf000000 0x01000000>;
  14777. };
  14778. memory-controller@2a150000 {
  14779. diff -Nur linux-3.14.15/arch/arm/boot/dts/vexpress-v2p-ca9.dts linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2p-ca9.dts
  14780. --- linux-3.14.15/arch/arm/boot/dts/vexpress-v2p-ca9.dts 2014-07-31 23:51:43.000000000 +0200
  14781. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/vexpress-v2p-ca9.dts 2014-08-20 19:23:45.558811686 +0200
  14782. @@ -9,6 +9,8 @@
  14783. /dts-v1/;
  14784. +/include/ "clcd-panels.dtsi"
  14785. +
  14786. / {
  14787. model = "V2P-CA9";
  14788. arm,hbi = <0x191>;
  14789. @@ -73,6 +75,8 @@
  14790. interrupts = <0 44 4>;
  14791. clocks = <&oscclk1>, <&oscclk2>;
  14792. clock-names = "clcdclk", "apb_pclk";
  14793. + mode = "XVGA";
  14794. + use_dma = <1>;
  14795. };
  14796. memory-controller@100e0000 {
  14797. diff -Nur linux-3.14.15/arch/arm/boot/dts/vf610.dtsi linux-linaro-stable-mx6/arch/arm/boot/dts/vf610.dtsi
  14798. --- linux-3.14.15/arch/arm/boot/dts/vf610.dtsi 2014-07-31 23:51:43.000000000 +0200
  14799. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/vf610.dtsi 2014-08-20 19:31:39.956842513 +0200
  14800. @@ -44,11 +44,13 @@
  14801. sxosc {
  14802. compatible = "fixed-clock";
  14803. + #clock-cells = <0>;
  14804. clock-frequency = <32768>;
  14805. };
  14806. fxosc {
  14807. compatible = "fixed-clock";
  14808. + #clock-cells = <0>;
  14809. clock-frequency = <24000000>;
  14810. };
  14811. };
  14812. diff -Nur linux-3.14.15/arch/arm/boot/dts/vf610-twr.dts linux-linaro-stable-mx6/arch/arm/boot/dts/vf610-twr.dts
  14813. --- linux-3.14.15/arch/arm/boot/dts/vf610-twr.dts 2014-07-31 23:51:43.000000000 +0200
  14814. +++ linux-linaro-stable-mx6/arch/arm/boot/dts/vf610-twr.dts 2014-08-20 19:31:39.956842513 +0200
  14815. @@ -25,11 +25,13 @@
  14816. clocks {
  14817. audio_ext {
  14818. compatible = "fixed-clock";
  14819. + #clock-cells = <0>;
  14820. clock-frequency = <24576000>;
  14821. };
  14822. enet_ext {
  14823. compatible = "fixed-clock";
  14824. + #clock-cells = <0>;
  14825. clock-frequency = <50000000>;
  14826. };
  14827. };
  14828. diff -Nur linux-3.14.15/arch/arm/common/Makefile linux-linaro-stable-mx6/arch/arm/common/Makefile
  14829. --- linux-3.14.15/arch/arm/common/Makefile 2014-07-31 23:51:43.000000000 +0200
  14830. +++ linux-linaro-stable-mx6/arch/arm/common/Makefile 2014-08-20 19:31:39.960842530 +0200
  14831. @@ -13,6 +13,7 @@
  14832. obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
  14833. obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
  14834. obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o
  14835. +CFLAGS_REMOVE_mcpm_entry.o = -pg
  14836. AFLAGS_mcpm_head.o := -march=armv7-a
  14837. AFLAGS_vlock.o := -march=armv7-a
  14838. obj-$(CONFIG_TI_PRIV_EDMA) += edma.o
  14839. diff -Nur linux-3.14.15/arch/arm/configs/imx_v6_v7_defconfig linux-linaro-stable-mx6/arch/arm/configs/imx_v6_v7_defconfig
  14840. --- linux-3.14.15/arch/arm/configs/imx_v6_v7_defconfig 2014-07-31 23:51:43.000000000 +0200
  14841. +++ linux-linaro-stable-mx6/arch/arm/configs/imx_v6_v7_defconfig 2014-08-20 19:31:39.968842564 +0200
  14842. @@ -45,6 +45,9 @@
  14843. CONFIG_AEABI=y
  14844. CONFIG_HIGHMEM=y
  14845. CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  14846. +CONFIG_CPU_FREQ=y
  14847. +CONFIG_ARM_IMX6Q_CPUFREQ=y
  14848. +CONFIG_CPU_IDLE=y
  14849. CONFIG_VFP=y
  14850. CONFIG_NEON=y
  14851. CONFIG_BINFMT_MISC=m
  14852. @@ -70,6 +73,8 @@
  14853. CONFIG_DEVTMPFS=y
  14854. CONFIG_DEVTMPFS_MOUNT=y
  14855. # CONFIG_STANDALONE is not set
  14856. +CONFIG_CMA=y
  14857. +CONFIG_CMA_SIZE_MBYTES=256
  14858. CONFIG_IMX_WEIM=y
  14859. CONFIG_CONNECTOR=y
  14860. CONFIG_MTD=y
  14861. @@ -154,7 +159,12 @@
  14862. CONFIG_SPI_IMX=y
  14863. CONFIG_GPIO_SYSFS=y
  14864. CONFIG_GPIO_MC9S08DZ60=y
  14865. +CONFIG_GPIO_PCA953X=y
  14866. # CONFIG_HWMON is not set
  14867. +CONFIG_THERMAL=y
  14868. +CONFIG_CPU_THERMAL=y
  14869. +CONFIG_IMX_THERMAL=y
  14870. +CONFIG_DEVICE_THERMAL=y
  14871. CONFIG_WATCHDOG=y
  14872. CONFIG_IMX2_WDT=y
  14873. CONFIG_MFD_DA9052_I2C=y
  14874. @@ -170,32 +180,44 @@
  14875. CONFIG_REGULATOR_PFUZE100=y
  14876. CONFIG_MEDIA_SUPPORT=y
  14877. CONFIG_MEDIA_CAMERA_SUPPORT=y
  14878. +CONFIG_MEDIA_USB_SUPPORT=y
  14879. +CONFIG_USB_VIDEO_CLASS=m
  14880. CONFIG_MEDIA_RC_SUPPORT=y
  14881. CONFIG_RC_DEVICES=y
  14882. CONFIG_IR_GPIO_CIR=y
  14883. CONFIG_V4L_PLATFORM_DRIVERS=y
  14884. +CONFIG_VIDEO_MXC_OUTPUT=y
  14885. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  14886. CONFIG_SOC_CAMERA=y
  14887. CONFIG_VIDEO_MX3=y
  14888. CONFIG_V4L_MEM2MEM_DRIVERS=y
  14889. CONFIG_VIDEO_CODA=y
  14890. CONFIG_SOC_CAMERA_OV2640=y
  14891. CONFIG_DRM=y
  14892. +CONFIG_DRM_VIVANTE=y
  14893. CONFIG_BACKLIGHT_LCD_SUPPORT=y
  14894. CONFIG_LCD_CLASS_DEVICE=y
  14895. CONFIG_LCD_L4F00242T03=y
  14896. CONFIG_LCD_PLATFORM=y
  14897. CONFIG_BACKLIGHT_CLASS_DEVICE=y
  14898. CONFIG_BACKLIGHT_PWM=y
  14899. +CONFIG_FB_MXC_SYNC_PANEL=y
  14900. +CONFIG_FB_MXC_LDB=y
  14901. +CONFIG_FB_MXC_HDMI=y
  14902. +CONFIG_FB_MXC_MIPI_DSI=y
  14903. +CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
  14904. CONFIG_FRAMEBUFFER_CONSOLE=y
  14905. CONFIG_LOGO=y
  14906. CONFIG_SOUND=y
  14907. CONFIG_SND=y
  14908. +CONFIG_SND_USB_AUDIO=m
  14909. CONFIG_SND_SOC=y
  14910. CONFIG_SND_IMX_SOC=y
  14911. CONFIG_SND_SOC_PHYCORE_AC97=y
  14912. CONFIG_SND_SOC_EUKREA_TLV320=y
  14913. CONFIG_SND_SOC_IMX_WM8962=y
  14914. CONFIG_SND_SOC_IMX_SGTL5000=y
  14915. +CONFIG_SND_SOC_IMX_CS42888=y
  14916. CONFIG_SND_SOC_IMX_SPDIF=y
  14917. CONFIG_SND_SOC_IMX_MC13783=y
  14918. CONFIG_USB=y
  14919. @@ -208,12 +230,18 @@
  14920. CONFIG_NOP_USB_XCEIV=y
  14921. CONFIG_USB_MXS_PHY=y
  14922. CONFIG_USB_GADGET=y
  14923. +CONFIG_USB_ZERO=m
  14924. CONFIG_USB_ETH=m
  14925. CONFIG_USB_MASS_STORAGE=m
  14926. +CONFIG_USB_G_SERIAL=m
  14927. CONFIG_MMC=y
  14928. +CONFIG_MMC_UNSAFE_RESUME=y
  14929. CONFIG_MMC_SDHCI=y
  14930. CONFIG_MMC_SDHCI_PLTFM=y
  14931. CONFIG_MMC_SDHCI_ESDHC_IMX=y
  14932. +CONFIG_MXC_IPU=y
  14933. +CONFIG_MXC_GPU_VIV=y
  14934. +CONFIG_MXC_ASRC=y
  14935. CONFIG_NEW_LEDS=y
  14936. CONFIG_LEDS_CLASS=y
  14937. CONFIG_LEDS_GPIO=y
  14938. @@ -229,16 +257,10 @@
  14939. CONFIG_RTC_DRV_MXC=y
  14940. CONFIG_RTC_DRV_SNVS=y
  14941. CONFIG_DMADEVICES=y
  14942. +CONFIG_MXC_PXP_V2=y
  14943. CONFIG_IMX_SDMA=y
  14944. CONFIG_MXS_DMA=y
  14945. CONFIG_STAGING=y
  14946. -CONFIG_DRM_IMX=y
  14947. -CONFIG_DRM_IMX_FB_HELPER=y
  14948. -CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
  14949. -CONFIG_DRM_IMX_TVE=y
  14950. -CONFIG_DRM_IMX_LDB=y
  14951. -CONFIG_DRM_IMX_IPUV3_CORE=y
  14952. -CONFIG_DRM_IMX_IPUV3=y
  14953. CONFIG_COMMON_CLK_DEBUG=y
  14954. # CONFIG_IOMMU_SUPPORT is not set
  14955. CONFIG_PWM=y
  14956. diff -Nur linux-3.14.15/arch/arm/configs/imx_v7_cbi_hb_base_defconfig linux-linaro-stable-mx6/arch/arm/configs/imx_v7_cbi_hb_base_defconfig
  14957. --- linux-3.14.15/arch/arm/configs/imx_v7_cbi_hb_base_defconfig 1970-01-01 01:00:00.000000000 +0100
  14958. +++ linux-linaro-stable-mx6/arch/arm/configs/imx_v7_cbi_hb_base_defconfig 2014-08-20 19:31:39.968842564 +0200
  14959. @@ -0,0 +1,367 @@
  14960. +# CONFIG_LOCALVERSION_AUTO is not set
  14961. +CONFIG_KERNEL_LZO=y
  14962. +CONFIG_SYSVIPC=y
  14963. +CONFIG_FHANDLE=y
  14964. +CONFIG_NO_HZ=y
  14965. +CONFIG_HIGH_RES_TIMERS=y
  14966. +CONFIG_LOG_BUF_SHIFT=18
  14967. +CONFIG_CGROUPS=y
  14968. +CONFIG_RELAY=y
  14969. +CONFIG_BLK_DEV_INITRD=y
  14970. +CONFIG_EXPERT=y
  14971. +CONFIG_PERF_EVENTS=y
  14972. +CONFIG_CLEANCACHE=y
  14973. +CONFIG_FRONTSWAP=y
  14974. +CONFIG_ZSWAP=y
  14975. +CONFIG_ZSMALLOC=y
  14976. +# CONFIG_SLUB_DEBUG is not set
  14977. +# CONFIG_COMPAT_BRK is not set
  14978. +CONFIG_MODULES=y
  14979. +CONFIG_MODULE_UNLOAD=y
  14980. +CONFIG_MODVERSIONS=y
  14981. +CONFIG_MODULE_SRCVERSION_ALL=y
  14982. +# CONFIG_BLK_DEV_BSG is not set
  14983. +CONFIG_GPIO_PCA953X=y
  14984. +CONFIG_ARCH_MXC=y
  14985. +CONFIG_MXC_DEBUG_BOARD=y
  14986. +CONFIG_SOC_IMX6Q=y
  14987. +CONFIG_SOC_IMX6SL=y
  14988. +# CONFIG_SWP_EMULATE is not set
  14989. +CONFIG_PCI=y
  14990. +CONFIG_PCIE_DW=y
  14991. +CONFIG_PCI_IMX6=y
  14992. +CONFIG_SMP=y
  14993. +CONFIG_VMSPLIT_2G=y
  14994. +CONFIG_PREEMPT_VOLUNTARY=y
  14995. +CONFIG_AEABI=y
  14996. +# CONFIG_OABI_COMPAT is not set
  14997. +CONFIG_HIGHMEM=y
  14998. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  14999. +CONFIG_CPU_FREQ=y
  15000. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  15001. +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
  15002. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  15003. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  15004. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  15005. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  15006. +CONFIG_ARM_IMX6_CPUFREQ=y
  15007. +CONFIG_CPU_IDLE=y
  15008. +CONFIG_VFP=y
  15009. +CONFIG_VFPv3=y
  15010. +CONFIG_NEON=y
  15011. +CONFIG_KERNEL_MODE_NEON=y
  15012. +CONFIG_BINFMT_MISC=m
  15013. +CONFIG_PM_RUNTIME=y
  15014. +CONFIG_PM_DEBUG=y
  15015. +CONFIG_PM_TEST_SUSPEND=y
  15016. +CONFIG_IOSCHED_BFQ=y
  15017. +CONFIG_CGROUP_BFQIO=y
  15018. +CONFIG_DEFAULT_BFQ=y
  15019. +CONFIG_DEFAULT_IOSCHED="bfq"
  15020. +CONFIG_NET=y
  15021. +CONFIG_PACKET=y
  15022. +CONFIG_UNIX=y
  15023. +CONFIG_INET=y
  15024. +CONFIG_IP_PNP=y
  15025. +CONFIG_IP_PNP_DHCP=y
  15026. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  15027. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  15028. +# CONFIG_INET_XFRM_MODE_BEET is not set
  15029. +# CONFIG_INET_LRO is not set
  15030. +CONFIG_IPV6=y
  15031. +CONFIG_NETFILTER=y
  15032. +CONFIG_VLAN_8021Q=y
  15033. +CONFIG_WIRELESS=y
  15034. +CONFIG_WIRELESS_EXT=y
  15035. +CONFIG_WEXT_CORE=y
  15036. +CONFIG_WEXT_PROC=y
  15037. +CONFIG_WEXT_SPY=y
  15038. +CONFIG_WEXT_PRIV=y
  15039. +CONFIG_CFG80211=y
  15040. +CONFIG_ETHERNET=y
  15041. +# CONFIG_NET_VENDOR_BROADCOM is not set
  15042. +# CONFIG_NET_VENDOR_CIRRUS is not set
  15043. +# CONFIG_NET_VENDOR_FARADAY
  15044. +# CONFIG_NET_VENDOR_INTEL
  15045. +# CONFIG_NET_VENDOR_I825XX
  15046. +# CONFIG_NET_VENDOR_MARVELL
  15047. +# CONFIG_NET_VENDOR_MICROCHIP
  15048. +# CONFIG_NET_VENDOR_MICROCHIP=y
  15049. +# CONFIG_ENC28J60 is not set
  15050. +# CONFIG_NET_VENDOR_NATSEMI=y
  15051. +# CONFIG_NET_VENDOR_8390=y
  15052. +# CONFIG_AX88796 is not set
  15053. +# CONFIG_ETHOC is not set
  15054. +# CONFIG_SH_ETH is not set
  15055. +# CONFIG_NET_VENDOR_SEEQ=y
  15056. +# CONFIG_NET_VENDOR_SMSC=y
  15057. +# CONFIG_SMC91X is not set
  15058. +# CONFIG_SMC911X is not set
  15059. +# CONFIG_SMSC911X is not set
  15060. +# CONFIG_NET_VENDOR_STMICRO=y
  15061. +# CONFIG_STMMAC_ETH is not set
  15062. +# CONFIG_NET_VENDOR_VIA=y
  15063. +# CONFIG_VIA_VELOCITY is not set
  15064. +# CONFIG_NET_VENDOR_WIZNET=y
  15065. +CONFIG_NET_VENDOR_FREESCALE=y
  15066. +CONFIG_FEC=y
  15067. +CONFIG_PHYLIB=y
  15068. +CONFIG_AT803X_PHY=y
  15069. +CONFIG_WLAN=y
  15070. +CONFIG_BRCMUTIL=m
  15071. +CONFIG_BRCMFMAC=m
  15072. +CONFIG_BRCMFMAC_SDIO=y
  15073. +CONFIG_DEVTMPFS=y
  15074. +CONFIG_DEVTMPFS_MOUNT=y
  15075. +# CONFIG_STANDALONE is not set
  15076. +CONFIG_DMA_CMA=y
  15077. +CONFIG_CMA=y
  15078. +CONFIG_CMA_SIZE_MBYTES=256
  15079. +CONFIG_CONNECTOR=y
  15080. +# CONFIG_MTD is not set
  15081. +CONFIG_BLK_DEV_LOOP=y
  15082. +CONFIG_BLK_DEV_RAM=y
  15083. +CONFIG_BLK_DEV_RAM_SIZE=65536
  15084. +# CONFIG_SCSI_PROC_FS is not set
  15085. +CONFIG_BLK_DEV_SD=y
  15086. +CONFIG_SCSI_MULTI_LUN=y
  15087. +CONFIG_SCSI_CONSTANTS=y
  15088. +CONFIG_SCSI_LOGGING=y
  15089. +CONFIG_SCSI_SCAN_ASYNC=y
  15090. +# CONFIG_SCSI_LOWLEVEL is not set
  15091. +CONFIG_ATA=y
  15092. +CONFIG_SATA_AHCI_PLATFORM=y
  15093. +CONFIG_AHCI_IMX=y
  15094. +CONFIG_NETDEVICES=y
  15095. +CONFIG_INPUT_EVDEV=y
  15096. +CONFIG_INPUT_EVBUG=m
  15097. +CONFIG_KEYBOARD_GPIO=y
  15098. +CONFIG_KEYBOARD_IMX=y
  15099. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  15100. +# CONFIG_KEYBOARD_ATKBD is not set
  15101. +# CONFIG_MOUSE_PS2 is not set
  15102. +CONFIG_INPUT_MISC=y
  15103. +CONFIG_SERIO_SERPORT=m
  15104. +CONFIG_VT_HW_CONSOLE_BINDING=y
  15105. +# CONFIG_LEGACY_PTYS is not set
  15106. +# CONFIG_DEVKMEM is not set
  15107. +CONFIG_SERIAL_IMX=y
  15108. +CONFIG_SERIAL_IMX_CONSOLE=y
  15109. +CONFIG_SERIAL_FSL_LPUART=y
  15110. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  15111. +CONFIG_FSL_OTP=y
  15112. +CONFIG_GPIO_MXC=y
  15113. +# CONFIG_I2C_COMPAT is not set
  15114. +CONFIG_I2C_CHARDEV=y
  15115. +# CONFIG_I2C_HELPER_AUTO is not set
  15116. +CONFIG_I2C_ALGOPCF=m
  15117. +CONFIG_I2C_ALGOPCA=m
  15118. +CONFIG_I2C_IMX=y
  15119. +CONFIG_SPI=y
  15120. +CONFIG_SPI_IMX=y
  15121. +CONFIG_GPIO_SYSFS=y
  15122. +CONFIG_POWER_SUPPLY=y
  15123. +CONFIG_THERMAL=y
  15124. +CONFIG_CPU_THERMAL=y
  15125. +CONFIG_IMX_THERMAL=y
  15126. +CONFIG_DEVICE_THERMAL=y
  15127. +CONFIG_WATCHDOG=y
  15128. +CONFIG_IMX2_WDT=y
  15129. +CONFIG_MFD_DA9052_I2C=y
  15130. +CONFIG_MFD_MC13XXX_SPI=y
  15131. +CONFIG_MFD_MC13XXX_I2C=y
  15132. +CONFIG_MFD_SI476X_CORE=y
  15133. +CONFIG_REGULATOR=y
  15134. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  15135. +CONFIG_REGULATOR_ANATOP=y
  15136. +CONFIG_REGULATOR_PFUZE100=y
  15137. +CONFIG_MEDIA_SUPPORT=y
  15138. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  15139. +# CONFIG_MEDIA_RADIO_SUPPORT is not set
  15140. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  15141. +# CONFIG_MEDIA_USB_SUPPORT isnot set
  15142. +# CONFIG_USB_VIDEO_CLASS is not set
  15143. +# CONFIG_RADIO_ADAPTERS is not set
  15144. +CONFIG_V4L_PLATFORM_DRIVERS=y
  15145. +CONFIG_VIDEO_MXC_OUTPUT=y
  15146. +CONFIG_VIDEO_MXC_CAPTURE=m
  15147. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  15148. +CONFIG_MXC_CAMERA_OV5640=m
  15149. +CONFIG_MXC_CAMERA_OV5642=m
  15150. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  15151. +CONFIG_MXC_TVIN_ADV7180=m
  15152. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  15153. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  15154. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  15155. +CONFIG_SOC_CAMERA=y
  15156. +CONFIG_SOC_CAMERA_OV2640=y
  15157. +CONFIG_DRM=y
  15158. +CONFIG_DRM_VIVANTE=y
  15159. +CONFIG_FB=y
  15160. +# CONFIG_FB_MX3 is not set
  15161. +CONFIG_FB_MXC_SYNC_PANEL=y
  15162. +CONFIG_FB_MXC_LDB=y
  15163. +CONFIG_FB_MXC_HDMI=y
  15164. +CONFIG_FRAMEBUFFER_CONSOLE=y
  15165. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  15166. +CONFIG_FONTS=y
  15167. +CONFIG_FONT_8x8=y
  15168. +CONFIG_FONT_8x16=y
  15169. +CONFIG_LOGO=y
  15170. +CONFIG_SOUND=y
  15171. +CONFIG_SND=y
  15172. +CONFIG_SND_USB_AUDIO=m
  15173. +CONFIG_SND_SOC=y
  15174. +CONFIG_SND_IMX_SOC=y
  15175. +CONFIG_SND_SOC_IMX_SGTL5000=y
  15176. +CONFIG_SND_SOC_IMX_SPDIF=y
  15177. +CONFIG_SND_SOC_IMX_HDMI=y
  15178. +CONFIG_USB=y
  15179. +CONFIG_USB_EHCI_HCD=y
  15180. +CONFIG_USB_STORAGE=y
  15181. +CONFIG_USB_CHIPIDEA=y
  15182. +CONFIG_USB_CHIPIDEA_UDC=y
  15183. +CONFIG_USB_CHIPIDEA_HOST=y
  15184. +CONFIG_USB_PHY=y
  15185. +CONFIG_NOP_USB_XCEIV=y
  15186. +CONFIG_USB_MXS_PHY=y
  15187. +CONFIG_USB_GADGET=y
  15188. +CONFIG_USB_ZERO=m
  15189. +CONFIG_USB_ETH=m
  15190. +CONFIG_USB_MASS_STORAGE=m
  15191. +CONFIG_USB_G_SERIAL=m
  15192. +CONFIG_MMC=y
  15193. +CONFIG_MMC_UNSAFE_RESUME=y
  15194. +CONFIG_MMC_SDHCI=y
  15195. +CONFIG_MMC_SDHCI_PLTFM=y
  15196. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  15197. +CONFIG_MXC_IPU=y
  15198. +CONFIG_MXC_GPU_VIV=y
  15199. +CONFIG_MXC_ASRC=y
  15200. +CONFIG_MXC_HDMI_CEC=y
  15201. +CONFIG_MXC_MIPI_CSI2=y
  15202. +CONFIG_MXC_MLB150=m
  15203. +CONFIG_NEW_LEDS=y
  15204. +CONFIG_LEDS_CLASS=y
  15205. +CONFIG_LEDS_GPIO=y
  15206. +CONFIG_LEDS_TRIGGERS=y
  15207. +CONFIG_LEDS_TRIGGER_GPIO=y
  15208. +CONFIG_RTC_CLASS=y
  15209. +CONFIG_RTC_DRV_MXC=y
  15210. +CONFIG_RTC_DRV_SNVS=y
  15211. +CONFIG_RTC_DRV_PCF8523=y
  15212. +CONFIG_DMADEVICES=y
  15213. +CONFIG_MXC_PXP_V2=y
  15214. +CONFIG_IMX_SDMA=y
  15215. +CONFIG_MXS_DMA=y
  15216. +CONFIG_SRAM=y
  15217. +CONFIG_STAGING=y
  15218. +CONFIG_COMMON_CLK_DEBUG=y
  15219. +# CONFIG_IOMMU_SUPPORT is not set
  15220. +CONFIG_PWM=y
  15221. +CONFIG_PWM_SYSFS=y
  15222. +CONFIG_PWM_IMX=y
  15223. +CONFIG_IRQCHIP=y
  15224. +CONFIG_ARM_GIC=y
  15225. +# CONFIG_IPACK_BUS is not set
  15226. +CONFIG_ARCH_HAS_RESET_CONTROLLER=y
  15227. +CONFIG_RESET_CONTROLLER=y
  15228. +CONFIG_RESET_GPIO=y
  15229. +CONFIG_EXT4_FS=y
  15230. +CONFIG_EXT4_USE_FOR_EXT23=y
  15231. +CONFIG_EXT4_FS_XATTR=y
  15232. +CONFIG_EXT4_FS_POSIX_ACL=y
  15233. +CONFIG_EXT4_FS_SECURITY=y
  15234. +CONFIG_QUOTA=y
  15235. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  15236. +# CONFIG_PRINT_QUOTA_WARNING is not set
  15237. +CONFIG_AUTOFS4_FS=y
  15238. +CONFIG_FUSE_FS=y
  15239. +CONFIG_ISO9660_FS=m
  15240. +CONFIG_JOLIET=y
  15241. +CONFIG_ZISOFS=y
  15242. +CONFIG_UDF_FS=m
  15243. +CONFIG_MSDOS_FS=m
  15244. +CONFIG_VFAT_FS=y
  15245. +CONFIG_TMPFS=y
  15246. +CONFIG_JFFS2_FS=y
  15247. +CONFIG_UBIFS_FS=y
  15248. +CONFIG_NFS_FS=y
  15249. +CONFIG_NFS_V3_ACL=y
  15250. +CONFIG_NFS_V4=y
  15251. +CONFIG_ROOT_NFS=y
  15252. +CONFIG_NLS_DEFAULT="cp437"
  15253. +CONFIG_NLS_CODEPAGE_437=y
  15254. +CONFIG_NLS_ASCII=y
  15255. +CONFIG_NLS_ISO8859_1=y
  15256. +CONFIG_NLS_ISO8859_15=m
  15257. +CONFIG_NLS_UTF8=y
  15258. +CONFIG_MAGIC_SYSRQ=y
  15259. +# CONFIG_SCHED_DEBUG is not set
  15260. +# CONFIG_DEBUG_BUGVERBOSE is not set
  15261. +# CONFIG_FTRACE is not set
  15262. +CONFIG_SECURITYFS=y
  15263. +CONFIG_CRYPTO_USER=y
  15264. +CONFIG_CRYPTO_TEST=m
  15265. +CONFIG_CRYPTO_CCM=y
  15266. +CONFIG_CRYPTO_GCM=y
  15267. +CONFIG_CRYPTO_CBC=y
  15268. +CONFIG_CRYPTO_CTS=y
  15269. +CONFIG_CRYPTO_ECB=y
  15270. +CONFIG_CRYPTO_LRW=y
  15271. +CONFIG_CRYPTO_XTS=y
  15272. +CONFIG_CRYPTO_MD4=y
  15273. +CONFIG_CRYPTO_MD5=y
  15274. +CONFIG_CRYPTO_MICHAEL_MIC=y
  15275. +CONFIG_CRYPTO_RMD128=y
  15276. +CONFIG_CRYPTO_RMD160=y
  15277. +CONFIG_CRYPTO_RMD256=y
  15278. +CONFIG_CRYPTO_RMD320=y
  15279. +CONFIG_CRYPTO_SHA1=y
  15280. +CONFIG_CRYPTO_SHA256=y
  15281. +CONFIG_CRYPTO_SHA512=y
  15282. +CONFIG_CRYPTO_TGR192=y
  15283. +CONFIG_CRYPTO_WP512=y
  15284. +CONFIG_CRYPTO_BLOWFISH=y
  15285. +CONFIG_CRYPTO_CAMELLIA=y
  15286. +CONFIG_CRYPTO_DES=y
  15287. +CONFIG_CRYPTO_TWOFISH=y
  15288. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  15289. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  15290. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  15291. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  15292. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  15293. +CONFIG_CRYPTO_AES_ARM_BS=y
  15294. +CONFIG_CRC_CCITT=m
  15295. +CONFIG_CRC_T10DIF=y
  15296. +CONFIG_CRC7=m
  15297. +CONFIG_LIBCRC32C=m
  15298. +# CONFIG_MXC_MMA8451 is not set
  15299. +CONFIG_RC_CORE=m
  15300. +CONFIG_RC_DECODERS=y
  15301. +CONFIG_LIRC=m
  15302. +CONFIG_RC_LOOPBACK=m
  15303. +CONFIG_RC_MAP=m
  15304. +CONFIG_RC_DEVICES=y
  15305. +CONFIG_RC_ATI_REMOTE=m
  15306. +CONFIG_IR_NEC_DECODER=m
  15307. +CONFIG_IR_RC5_DECODER=m
  15308. +CONFIG_IR_RC6_DECODER=m
  15309. +CONFIG_IR_JVC_DECODER=m
  15310. +CONFIG_IR_SONY_DECODER=m
  15311. +CONFIG_IR_RC5_SZ_DECODER=m
  15312. +CONFIG_IR_SANYO_DECODER=m
  15313. +CONFIG_IR_MCE_KBD_DECODER=m
  15314. +CONFIG_IR_LIRC_CODEC=m
  15315. +CONFIG_IR_IMON=m
  15316. +CONFIG_IR_MCEUSB=m
  15317. +CONFIG_IR_ITE_CIR=m
  15318. +CONFIG_IR_NUVOTON=m
  15319. +CONFIG_IR_FINTEK=m
  15320. +CONFIG_IR_REDRAT3=m
  15321. +CONFIG_IR_ENE=m
  15322. +CONFIG_IR_STREAMZAP=m
  15323. +CONFIG_IR_WINBOND_CIR=m
  15324. +CONFIG_IR_IGUANA=m
  15325. +CONFIG_IR_TTUSBIR=m
  15326. +CONFIG_IR_GPIO_CIR=m
  15327. diff -Nur linux-3.14.15/arch/arm/configs/imx_v7_cbi_hb_defconfig linux-linaro-stable-mx6/arch/arm/configs/imx_v7_cbi_hb_defconfig
  15328. --- linux-3.14.15/arch/arm/configs/imx_v7_cbi_hb_defconfig 1970-01-01 01:00:00.000000000 +0100
  15329. +++ linux-linaro-stable-mx6/arch/arm/configs/imx_v7_cbi_hb_defconfig 2014-08-20 19:31:39.968842564 +0200
  15330. @@ -0,0 +1,5139 @@
  15331. +#
  15332. +# Automatically generated make config: don't edit
  15333. +#
  15334. +CONFIG_MMU=y
  15335. +CONFIG_HOTPLUG_CPU=y
  15336. +# CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set
  15337. +# CONFIG_DEBUG_HOTPLUG_CPU0 is not set
  15338. +CONFIG_LOCALVERSION=""
  15339. +CONFIG_CROSS_COMPILE=""
  15340. +CONFIG_DEFAULT_HOSTNAME="(none)"
  15341. +
  15342. +#
  15343. +# Code maturity level options
  15344. +#
  15345. +CONFIG_EXPERIMENTAL=y
  15346. +CONFIG_HOTPLUG=y
  15347. +CONFIG_UEVENT_HELPER_PATH=""
  15348. +CONFIG_PREVENT_FIRMWARE_BUILD=y
  15349. +
  15350. +CONFIG_BUILD_DOCSRC=y
  15351. +
  15352. +#
  15353. +# General setup
  15354. +#
  15355. +CONFIG_KERNEL_LZO=y
  15356. +# CONFIG_KERNEL_BZIP2 is not set
  15357. +# CONFIG_KERNEL_LZMA is not set
  15358. +CONFIG_SWAP=y
  15359. +CONFIG_BSD_PROCESS_ACCT=y
  15360. +CONFIG_BSD_PROCESS_ACCT_V3=y
  15361. +# CONFIG_COMPILE_TEST is not set
  15362. +CONFIG_TASKSTATS=y
  15363. +CONFIG_TASK_DELAY_ACCT=y
  15364. +CONFIG_TASK_XACCT=y
  15365. +CONFIG_TASK_IO_ACCOUNTING=y
  15366. +CONFIG_SYSCTL=y
  15367. +# CONFIG_IKCONFIG is not set
  15368. +# CONFIG_EMBEDDED is not set
  15369. +CONFIG_KALLSYMS=y
  15370. +CONFIG_KALLSYMS_ALL=y
  15371. +CONFIG_FUTEX=y
  15372. +CONFIG_EPOLL=y
  15373. +CONFIG_IOSCHED_NOOP=y
  15374. +CONFIG_IOSCHED_DEADLINE=y
  15375. +CONFIG_IOSCHED_CFQ=y
  15376. +CONFIG_CFQ_GROUP_IOSCHED=y
  15377. +CONFIG_IOSCHED_BFQ=y
  15378. +CONFIG_CGROUP_BFQIO=y
  15379. +CONFIG_DEFAULT_BFQ=y
  15380. +CONFIG_DEFAULT_IOSCHED="bfq"
  15381. +# CONFIG_CHECKPOINT_RESTORE is not set
  15382. +CONFIG_NAMESPACES=y
  15383. +CONFIG_PID_NS=y
  15384. +CONFIG_UTS_NS=y
  15385. +CONFIG_IPC_NS=y
  15386. +CONFIG_NET_NS=y
  15387. +CONFIG_USER_NS=y
  15388. +# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
  15389. +CONFIG_SYSVIPC=y
  15390. +CONFIG_FHANDLE=y
  15391. +CONFIG_NO_HZ=y
  15392. +CONFIG_HIGH_RES_TIMERS=y
  15393. +CONFIG_LOG_BUF_SHIFT=18
  15394. +CONFIG_CGROUPS=y
  15395. +CONFIG_RELAY=y
  15396. +CONFIG_BLK_DEV_INITRD=y
  15397. +CONFIG_EXPERT=y
  15398. +CONFIG_PERF_EVENTS=y
  15399. +# CONFIG_SLUB_DEBUG is not set
  15400. +# CONFIG_COMPAT_BRK is not set
  15401. +CONFIG_MODULES=y
  15402. +CONFIG_MODULE_UNLOAD=y
  15403. +CONFIG_MODVERSIONS=y
  15404. +CONFIG_MODULE_SRCVERSION_ALL=y
  15405. +
  15406. +CONFIG_POSIX_MQUEUE=y
  15407. +CONFIG_PREEMPT_VOLUNTARY=y
  15408. +
  15409. +CONFIG_SLUB=y
  15410. +CONFIG_SLUB_CPU_PARTIAL=y
  15411. +# CONFIG_SLUB_STATS is not set
  15412. +# CONFIG_SLUB_DEBUG_ON is not set
  15413. +
  15414. +# CONFIG_AD525X_DPOT is not set
  15415. +# CONFIG_ATMEL_PWM is not set
  15416. +# CONFIG_IWMC3200TOP is not set
  15417. +# CONFIG_BLK_DEV_BSG is not set
  15418. +
  15419. +# MX6 specific kernel configuration
  15420. +CONFIG_GPIO_PCA953X=y
  15421. +CONFIG_ARCH_MXC=y
  15422. +CONFIG_MXC_DEBUG_BOARD=y
  15423. +CONFIG_SOC_IMX6Q=y
  15424. +CONFIG_SOC_IMX6SL=y
  15425. +# CONFIG_SWP_EMULATE is not set
  15426. +CONFIG_PCI=y
  15427. +CONFIG_PCIE_DW=y
  15428. +CONFIG_PCI_IMX6=y
  15429. +CONFIG_SMP=y
  15430. +CONFIG_VMSPLIT_2G=y
  15431. +CONFIG_AEABI=y
  15432. +# CONFIG_OABI_COMPAT is not set
  15433. +CONFIG_HIGHMEM=y
  15434. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  15435. +CONFIG_CPU_FREQ=y
  15436. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  15437. +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
  15438. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  15439. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  15440. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  15441. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  15442. +CONFIG_ARM_IMX6_CPUFREQ=y
  15443. +CONFIG_CPU_IDLE=y
  15444. +CONFIG_VFP=y
  15445. +CONFIG_VFPv3=y
  15446. +CONFIG_NEON=y
  15447. +CONFIG_KERNEL_MODE_NEON=y
  15448. +CONFIG_BINFMT_MISC=m
  15449. +CONFIG_PM_RUNTIME=y
  15450. +CONFIG_PM_DEBUG=y
  15451. +CONFIG_PM_TEST_SUSPEND=y
  15452. +CONFIG_NET=y
  15453. +CONFIG_PACKET=y
  15454. +CONFIG_UNIX=y
  15455. +CONFIG_INET=y
  15456. +CONFIG_IP_PNP=y
  15457. +CONFIG_IP_PNP_DHCP=y
  15458. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  15459. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  15460. +# CONFIG_INET_XFRM_MODE_BEET is not set
  15461. +# CONFIG_INET_LRO is not set
  15462. +CONFIG_IPV6=y
  15463. +CONFIG_NETFILTER=y
  15464. +CONFIG_VLAN_8021Q=y
  15465. +CONFIG_WIRELESS=y
  15466. +CONFIG_WIRELESS_EXT=y
  15467. +CONFIG_WEXT_CORE=y
  15468. +CONFIG_WEXT_PROC=y
  15469. +CONFIG_WEXT_SPY=y
  15470. +CONFIG_WEXT_PRIV=y
  15471. +CONFIG_CFG80211=y
  15472. +CONFIG_ETHERNET=y
  15473. +# CONFIG_NET_VENDOR_BROADCOM is not set
  15474. +# CONFIG_NET_VENDOR_CIRRUS is not set
  15475. +# CONFIG_NET_VENDOR_FARADAY
  15476. +# CONFIG_NET_VENDOR_INTEL
  15477. +# CONFIG_NET_VENDOR_I825XX
  15478. +# CONFIG_NET_VENDOR_MARVELL
  15479. +# CONFIG_NET_VENDOR_MICROCHIP
  15480. +# CONFIG_NET_VENDOR_MICROCHIP=y
  15481. +# CONFIG_ENC28J60 is not set
  15482. +# CONFIG_NET_VENDOR_NATSEMI=y
  15483. +# CONFIG_NET_VENDOR_8390=y
  15484. +# CONFIG_AX88796 is not set
  15485. +# CONFIG_ETHOC is not set
  15486. +# CONFIG_SH_ETH is not set
  15487. +# CONFIG_NET_VENDOR_SEEQ=y
  15488. +# CONFIG_NET_VENDOR_SMSC=y
  15489. +# CONFIG_SMC91X is not set
  15490. +# CONFIG_SMC911X is not set
  15491. +# CONFIG_SMSC911X is not set
  15492. +# CONFIG_NET_VENDOR_STMICRO=y
  15493. +# CONFIG_STMMAC_ETH is not set
  15494. +# CONFIG_NET_VENDOR_VIA=y
  15495. +# CONFIG_VIA_VELOCITY is not set
  15496. +# CONFIG_NET_VENDOR_WIZNET=y
  15497. +CONFIG_NET_VENDOR_FREESCALE=y
  15498. +CONFIG_FEC=y
  15499. +CONFIG_PHYLIB=y
  15500. +CONFIG_AT803X_PHY=y
  15501. +CONFIG_WLAN=y
  15502. +CONFIG_BRCMUTIL=m
  15503. +CONFIG_BRCMFMAC=m
  15504. +CONFIG_BRCMFMAC_SDIO=y
  15505. +CONFIG_DEVTMPFS=y
  15506. +CONFIG_DEVTMPFS_MOUNT=y
  15507. +# CONFIG_STANDALONE is not set
  15508. +CONFIG_DMA_CMA=y
  15509. +CONFIG_CMA=y
  15510. +CONFIG_CMA_SIZE_MBYTES=256
  15511. +CONFIG_CONNECTOR=y
  15512. +# CONFIG_MTD is not set
  15513. +CONFIG_BLK_DEV_LOOP=y
  15514. +CONFIG_BLK_DEV_RAM=y
  15515. +CONFIG_BLK_DEV_RAM_SIZE=65536
  15516. +# CONFIG_SCSI_PROC_FS is not set
  15517. +CONFIG_BLK_DEV_SD=y
  15518. +CONFIG_SCSI_MULTI_LUN=y
  15519. +CONFIG_SCSI_CONSTANTS=y
  15520. +CONFIG_SCSI_LOGGING=y
  15521. +CONFIG_SCSI_SCAN_ASYNC=y
  15522. +# CONFIG_SCSI_LOWLEVEL is not set
  15523. +CONFIG_ATA=y
  15524. +CONFIG_SATA_AHCI_PLATFORM=y
  15525. +CONFIG_AHCI_IMX=y
  15526. +CONFIG_NETDEVICES=y
  15527. +CONFIG_INPUT_EVDEV=y
  15528. +CONFIG_INPUT_EVBUG=m
  15529. +CONFIG_KEYBOARD_GPIO=y
  15530. +CONFIG_KEYBOARD_IMX=y
  15531. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  15532. +# CONFIG_KEYBOARD_ATKBD is not set
  15533. +# CONFIG_MOUSE_PS2 is not set
  15534. +CONFIG_INPUT_MISC=y
  15535. +CONFIG_SERIO_SERPORT=m
  15536. +CONFIG_VT_HW_CONSOLE_BINDING=y
  15537. +# CONFIG_LEGACY_PTYS is not set
  15538. +# CONFIG_DEVKMEM is not set
  15539. +CONFIG_SERIAL_IMX=y
  15540. +CONFIG_SERIAL_IMX_CONSOLE=y
  15541. +CONFIG_SERIAL_FSL_LPUART=y
  15542. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  15543. +CONFIG_FSL_OTP=y
  15544. +CONFIG_GPIO_MXC=y
  15545. +# CONFIG_I2C_COMPAT is not set
  15546. +CONFIG_I2C_CHARDEV=y
  15547. +# CONFIG_I2C_HELPER_AUTO is not set
  15548. +CONFIG_I2C_ALGOPCF=m
  15549. +CONFIG_I2C_ALGOPCA=m
  15550. +CONFIG_I2C_IMX=y
  15551. +CONFIG_SPI=y
  15552. +CONFIG_SPI_IMX=y
  15553. +CONFIG_GPIO_SYSFS=y
  15554. +CONFIG_POWER_SUPPLY=y
  15555. +CONFIG_THERMAL=y
  15556. +CONFIG_CPU_THERMAL=y
  15557. +CONFIG_IMX_THERMAL=y
  15558. +CONFIG_DEVICE_THERMAL=y
  15559. +CONFIG_WATCHDOG=y
  15560. +CONFIG_IMX2_WDT=y
  15561. +CONFIG_MFD_DA9052_I2C=y
  15562. +CONFIG_MFD_MC13XXX_SPI=y
  15563. +CONFIG_MFD_MC13XXX_I2C=y
  15564. +CONFIG_MFD_SI476X_CORE=y
  15565. +CONFIG_REGULATOR=y
  15566. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  15567. +CONFIG_REGULATOR_ANATOP=y
  15568. +CONFIG_REGULATOR_PFUZE100=y
  15569. +CONFIG_MEDIA_SUPPORT=y
  15570. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  15571. +# CONFIG_MEDIA_RADIO_SUPPORT is not set
  15572. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  15573. +CONFIG_MEDIA_USB_SUPPORT=y
  15574. +CONFIG_USB_VIDEO_CLASS=m
  15575. +# CONFIG_RADIO_ADAPTERS is not set
  15576. +CONFIG_V4L_PLATFORM_DRIVERS=y
  15577. +CONFIG_VIDEO_MXC_OUTPUT=y
  15578. +CONFIG_VIDEO_MXC_CAPTURE=m
  15579. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  15580. +CONFIG_MXC_CAMERA_OV5640=m
  15581. +CONFIG_MXC_CAMERA_OV5642=m
  15582. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  15583. +CONFIG_MXC_TVIN_ADV7180=m
  15584. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  15585. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  15586. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  15587. +CONFIG_SOC_CAMERA=y
  15588. +CONFIG_SOC_CAMERA_OV2640=y
  15589. +CONFIG_DRM=y
  15590. +CONFIG_DRM_VIVANTE=y
  15591. +CONFIG_FB=y
  15592. +# CONFIG_FB_MX3 is not set
  15593. +CONFIG_FB_MXC_SYNC_PANEL=y
  15594. +CONFIG_FB_MXC_LDB=y
  15595. +CONFIG_FB_MXC_HDMI=y
  15596. +CONFIG_FRAMEBUFFER_CONSOLE=y
  15597. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  15598. +CONFIG_FONTS=y
  15599. +CONFIG_FONT_8x8=y
  15600. +CONFIG_FONT_8x16=y
  15601. +CONFIG_LOGO=y
  15602. +CONFIG_SOUND=y
  15603. +CONFIG_SND=y
  15604. +CONFIG_SND_USB_AUDIO=m
  15605. +CONFIG_SND_SOC=y
  15606. +CONFIG_SND_IMX_SOC=y
  15607. +CONFIG_SND_SOC_IMX_SGTL5000=y
  15608. +CONFIG_SND_SOC_IMX_SPDIF=y
  15609. +CONFIG_SND_SOC_IMX_HDMI=y
  15610. +CONFIG_USB=y
  15611. +CONFIG_USB_EHCI_HCD=y
  15612. +CONFIG_USB_STORAGE=y
  15613. +CONFIG_USB_CHIPIDEA=y
  15614. +CONFIG_USB_CHIPIDEA_UDC=y
  15615. +CONFIG_USB_CHIPIDEA_HOST=y
  15616. +CONFIG_USB_PHY=y
  15617. +CONFIG_NOP_USB_XCEIV=y
  15618. +CONFIG_USB_MXS_PHY=y
  15619. +CONFIG_USB_GADGET=y
  15620. +CONFIG_USB_ZERO=m
  15621. +CONFIG_USB_ETH=m
  15622. +CONFIG_USB_MASS_STORAGE=m
  15623. +CONFIG_USB_G_SERIAL=m
  15624. +CONFIG_MMC=y
  15625. +CONFIG_MMC_UNSAFE_RESUME=y
  15626. +CONFIG_MMC_SDHCI=y
  15627. +CONFIG_MMC_SDHCI_PLTFM=y
  15628. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  15629. +CONFIG_MXC_IPU=y
  15630. +CONFIG_MXC_GPU_VIV=y
  15631. +CONFIG_MXC_ASRC=y
  15632. +CONFIG_MXC_HDMI_CEC=y
  15633. +CONFIG_MXC_MIPI_CSI2=y
  15634. +CONFIG_MXC_MLB150=m
  15635. +CONFIG_NEW_LEDS=y
  15636. +CONFIG_LEDS_CLASS=y
  15637. +CONFIG_LEDS_GPIO=y
  15638. +CONFIG_LEDS_TRIGGERS=y
  15639. +CONFIG_LEDS_TRIGGER_GPIO=y
  15640. +CONFIG_RTC_CLASS=y
  15641. +CONFIG_RTC_DRV_MXC=y
  15642. +CONFIG_RTC_DRV_SNVS=y
  15643. +CONFIG_RTC_DRV_PCF8523=y
  15644. +CONFIG_DMADEVICES=y
  15645. +CONFIG_MXC_PXP_V2=y
  15646. +CONFIG_IMX_SDMA=y
  15647. +CONFIG_MXS_DMA=y
  15648. +CONFIG_SRAM=y
  15649. +CONFIG_STAGING=y
  15650. +CONFIG_COMMON_CLK_DEBUG=y
  15651. +# CONFIG_IOMMU_SUPPORT is not set
  15652. +CONFIG_PWM=y
  15653. +CONFIG_PWM_SYSFS=y
  15654. +CONFIG_PWM_IMX=y
  15655. +CONFIG_IRQCHIP=y
  15656. +CONFIG_ARM_GIC=y
  15657. +CONFIG_ARCH_HAS_RESET_CONTROLLER=y
  15658. +CONFIG_RESET_CONTROLLER=y
  15659. +CONFIG_RESET_GPIO=y
  15660. +CONFIG_EXT4_FS=y
  15661. +CONFIG_EXT4_USE_FOR_EXT23=y
  15662. +CONFIG_EXT4_FS_XATTR=y
  15663. +CONFIG_EXT4_FS_POSIX_ACL=y
  15664. +CONFIG_EXT4_FS_SECURITY=y
  15665. +CONFIG_QUOTA=y
  15666. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  15667. +# CONFIG_PRINT_QUOTA_WARNING is not set
  15668. +CONFIG_AUTOFS4_FS=y
  15669. +CONFIG_FUSE_FS=y
  15670. +CONFIG_ISO9660_FS=m
  15671. +CONFIG_JOLIET=y
  15672. +CONFIG_ZISOFS=y
  15673. +CONFIG_UDF_FS=m
  15674. +CONFIG_MSDOS_FS=m
  15675. +CONFIG_VFAT_FS=y
  15676. +CONFIG_TMPFS=y
  15677. +CONFIG_JFFS2_FS=y
  15678. +CONFIG_UBIFS_FS=y
  15679. +CONFIG_NFS_FS=y
  15680. +CONFIG_NFS_V3_ACL=y
  15681. +CONFIG_NFS_V4=y
  15682. +CONFIG_ROOT_NFS=y
  15683. +CONFIG_NLS_DEFAULT="cp437"
  15684. +CONFIG_NLS_CODEPAGE_437=y
  15685. +CONFIG_NLS_ASCII=y
  15686. +CONFIG_NLS_ISO8859_1=y
  15687. +CONFIG_NLS_ISO8859_15=m
  15688. +CONFIG_NLS_UTF8=y
  15689. +CONFIG_MAGIC_SYSRQ=y
  15690. +# CONFIG_SCHED_DEBUG is not set
  15691. +# CONFIG_DEBUG_BUGVERBOSE is not set
  15692. +# CONFIG_FTRACE is not set
  15693. +CONFIG_SECURITYFS=y
  15694. +CONFIG_CRYPTO_USER=y
  15695. +CONFIG_CRYPTO_TEST=m
  15696. +CONFIG_CRYPTO_CCM=y
  15697. +CONFIG_CRYPTO_GCM=y
  15698. +CONFIG_CRYPTO_CBC=y
  15699. +CONFIG_CRYPTO_CTS=y
  15700. +CONFIG_CRYPTO_ECB=y
  15701. +CONFIG_CRYPTO_LRW=y
  15702. +CONFIG_CRYPTO_XTS=y
  15703. +CONFIG_CRYPTO_MD4=y
  15704. +CONFIG_CRYPTO_MD5=y
  15705. +CONFIG_CRYPTO_MICHAEL_MIC=y
  15706. +CONFIG_CRYPTO_RMD128=y
  15707. +CONFIG_CRYPTO_RMD160=y
  15708. +CONFIG_CRYPTO_RMD256=y
  15709. +CONFIG_CRYPTO_RMD320=y
  15710. +CONFIG_CRYPTO_SHA1=y
  15711. +CONFIG_CRYPTO_SHA256=y
  15712. +CONFIG_CRYPTO_SHA512=y
  15713. +CONFIG_CRYPTO_TGR192=y
  15714. +CONFIG_CRYPTO_WP512=y
  15715. +CONFIG_CRYPTO_BLOWFISH=y
  15716. +CONFIG_CRYPTO_CAMELLIA=y
  15717. +CONFIG_CRYPTO_DES=y
  15718. +CONFIG_CRYPTO_TWOFISH=y
  15719. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  15720. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  15721. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  15722. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  15723. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  15724. +CONFIG_CRYPTO_AES_ARM_BS=y
  15725. +CONFIG_CRC_CCITT=m
  15726. +CONFIG_CRC_T10DIF=y
  15727. +CONFIG_CRC7=m
  15728. +CONFIG_LIBCRC32C=m
  15729. +# CONFIG_MXC_MMA8451 is not set
  15730. +
  15731. +#
  15732. +# Loadable module support
  15733. +#
  15734. +# CONFIG_MODULE_FORCE_LOAD is not set
  15735. +# -- MODULE_FORCE_UNLOAD is controlled by config-debug/nodebug
  15736. +
  15737. +# CONFIG_PCI_DEBUG is not set
  15738. +CONFIG_PCI_STUB=y
  15739. +CONFIG_PCI_IOV=y
  15740. +CONFIG_PCI_PRI=y
  15741. +CONFIG_PCI_PASID=y
  15742. +CONFIG_HT_IRQ=y
  15743. +CONFIG_PCI_MSI=y
  15744. +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
  15745. +CONFIG_PCIEPORTBUS=y
  15746. +CONFIG_PCIEAER=y
  15747. +CONFIG_PCIEASPM=y
  15748. +# CONFIG_PCIEASPM_DEBUG is not set
  15749. +CONFIG_PCIE_ECRC=y
  15750. +CONFIG_PCIEAER_INJECT=m
  15751. +CONFIG_HOTPLUG_PCI_PCIE=y
  15752. +CONFIG_HOTPLUG_PCI_FAKE=m
  15753. +
  15754. +# CONFIG_SGI_IOC4 is not set
  15755. +
  15756. +# CONFIG_ISA is not set
  15757. +# CONFIG_SCx200 is not set
  15758. +
  15759. +#
  15760. +# PCMCIA/CardBus support
  15761. +# FIXME: Deprecate Cardbus ?
  15762. +#
  15763. +CONFIG_PCMCIA=y
  15764. +CONFIG_PCMCIA_LOAD_CIS=y
  15765. +# CONFIG_PCMCIA_DEBUG is not set
  15766. +CONFIG_YENTA=m
  15767. +CONFIG_CARDBUS=y
  15768. +CONFIG_I82092=m
  15769. +CONFIG_PD6729=m
  15770. +
  15771. +CONFIG_PCCARD=y
  15772. +CONFIG_SDIO_UART=m
  15773. +# CONFIG_MMC_TEST is not set
  15774. +# CONFIG_MMC_DEBUG is not set
  15775. +# https://lists.fedoraproject.org/pipermail/kernel/2014-February/004889.html
  15776. +# CONFIG_MMC_CLKGATE is not set
  15777. +CONFIG_MMC_BLOCK=y
  15778. +CONFIG_MMC_BLOCK_MINORS=8
  15779. +CONFIG_MMC_BLOCK_BOUNCE=y
  15780. +CONFIG_MMC_SDHCI_PCI=m
  15781. +CONFIG_MMC_SDHCI_ACPI=m
  15782. +CONFIG_MMC_SDRICOH_CS=m
  15783. +CONFIG_MMC_TIFM_SD=m
  15784. +CONFIG_MMC_WBSD=m
  15785. +CONFIG_MMC_VIA_SDMMC=m
  15786. +CONFIG_MMC_CB710=m
  15787. +CONFIG_MMC_RICOH_MMC=y
  15788. +CONFIG_MMC_USHC=m
  15789. +CONFIG_MMC_REALTEK_PCI=m
  15790. +CONFIG_MMC_VUB300=m
  15791. +# CONFIG_MMC_SDHCI_PXAV2 is not set
  15792. +# CONFIG_MMC_SDHCI_PXAV3 is not set
  15793. +# CONFIG_MMC_SDHCI_OF_ARASAN is not set
  15794. +
  15795. +
  15796. +CONFIG_CB710_CORE=m
  15797. +# CONFIG_CB710_DEBUG is not set
  15798. +
  15799. +CONFIG_INFINIBAND=m
  15800. +CONFIG_INFINIBAND_MTHCA=m
  15801. +# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
  15802. +CONFIG_INFINIBAND_IPOIB=m
  15803. +CONFIG_INFINIBAND_IPOIB_DEBUG=y
  15804. +CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
  15805. +CONFIG_INFINIBAND_IPOIB_CM=y
  15806. +CONFIG_INFINIBAND_SRP=m
  15807. +CONFIG_INFINIBAND_SRPT=m
  15808. +CONFIG_INFINIBAND_USER_MAD=m
  15809. +CONFIG_INFINIBAND_USER_ACCESS=m
  15810. +# CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING is not set #staging
  15811. +CONFIG_INFINIBAND_IPATH=m
  15812. +CONFIG_INFINIBAND_ISER=m
  15813. +CONFIG_INFINIBAND_ISERT=m
  15814. +CONFIG_INFINIBAND_AMSO1100=m
  15815. +# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set
  15816. +CONFIG_INFINIBAND_CXGB3=m
  15817. +CONFIG_INFINIBAND_CXGB4=m
  15818. +CONFIG_SCSI_CXGB3_ISCSI=m
  15819. +CONFIG_SCSI_CXGB4_ISCSI=m
  15820. +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set
  15821. +CONFIG_MLX4_INFINIBAND=m
  15822. +CONFIG_MLX5_INFINIBAND=m
  15823. +CONFIG_INFINIBAND_NES=m
  15824. +# CONFIG_INFINIBAND_NES_DEBUG is not set
  15825. +CONFIG_INFINIBAND_QIB=m
  15826. +CONFIG_INFINIBAND_QIB_DCA=y
  15827. +# CONFIG_INFINIBAND_OCRDMA is not set
  15828. +# CONFIG_INFINIBAND_USNIC is not set
  15829. +
  15830. +#
  15831. +# Executable file formats
  15832. +#
  15833. +CONFIG_BINFMT_ELF=y
  15834. +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
  15835. +# CONFIG_BINFMT_AOUT is not set
  15836. +CONFIG_BINFMT_SCRIPT=y
  15837. +
  15838. +#
  15839. +# Device Drivers
  15840. +#
  15841. +
  15842. +# CONFIG_COMMON_CLK_SI5351 is not set
  15843. +
  15844. +#
  15845. +# Generic Driver Options
  15846. +#
  15847. +CONFIG_FW_LOADER=y
  15848. +# CONFIG_FIRMWARE_IN_KERNEL is not set
  15849. +CONFIG_EXTRA_FIRMWARE=""
  15850. +
  15851. +# Give this a try in rawhide for now
  15852. +# CONFIG_FW_LOADER_USER_HELPER is not set
  15853. +
  15854. +
  15855. +
  15856. +#
  15857. +# Memory Technology Devices (MTD)
  15858. +#
  15859. +# CONFIG_MTD_TESTS is not set
  15860. +# CONFIG_MTD_REDBOOT_PARTS is not set
  15861. +# CONFIG_MTD_AR7_PARTS is not set
  15862. +# CONFIG_MTD_CMDLINE_PARTS is not set
  15863. +
  15864. +#
  15865. +# User Modules And Translation Layers
  15866. +#
  15867. +# CONFIG_MTD_CHAR is not set
  15868. +# CONFIG_MTD_BLKDEVS is not set
  15869. +# CONFIG_MTD_BLOCK is not set
  15870. +# CONFIG_MTD_BLOCK_RO is not set
  15871. +# CONFIG_FTL is not set
  15872. +# CONFIG_NFTL is not set
  15873. +# CONFIG_INFTL is not set
  15874. +# CONFIG_RFD_FTL is not set
  15875. +# CONFIG_SSFDC is not set
  15876. +# CONFIG_SM_FTL is not set
  15877. +# CONFIG_MTD_OOPS is not set
  15878. +# CONFIG_MTD_SWAP is not set
  15879. +
  15880. +#
  15881. +# RAM/ROM/Flash chip drivers
  15882. +#
  15883. +# CONFIG_MTD_CFI is not set
  15884. +# CONFIG_MTD_JEDECPROBE is not set
  15885. +CONFIG_MTD_MAP_BANK_WIDTH_1=y
  15886. +CONFIG_MTD_MAP_BANK_WIDTH_2=y
  15887. +CONFIG_MTD_MAP_BANK_WIDTH_4=y
  15888. +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
  15889. +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
  15890. +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
  15891. +CONFIG_MTD_CFI_I1=y
  15892. +CONFIG_MTD_CFI_I2=y
  15893. +# CONFIG_MTD_CFI_I4 is not set
  15894. +# CONFIG_MTD_CFI_I8 is not set
  15895. +# CONFIG_MTD_RAM is not set
  15896. +# CONFIG_MTD_ROM is not set
  15897. +# CONFIG_MTD_ABSENT is not set
  15898. +
  15899. +#
  15900. +# Mapping drivers for chip access
  15901. +#
  15902. +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
  15903. +# CONFIG_MTD_TS5500 is not set
  15904. +# CONFIG_MTD_INTEL_VR_NOR is not set
  15905. +# CONFIG_MTD_PLATRAM is not set
  15906. +
  15907. +# Self-contained MTD device drivers
  15908. +# CONFIG_MTD_PMC551 is not set
  15909. +# CONFIG_MTD_SLRAM is not set
  15910. +# CONFIG_MTD_PHRAM is not set
  15911. +# CONFIG_MTD_MTDRAM is not set
  15912. +# CONFIG_MTD_BLOCK2MTD is not set
  15913. +
  15914. +#
  15915. +# Disk-On-Chip Device Drivers
  15916. +#
  15917. +# CONFIG_MTD_DOCG3 is not set
  15918. +# CONFIG_MTD_NAND is not set
  15919. +# CONFIG_MTD_ONENAND is not set
  15920. +# CONFIG_MTD_NAND_VERIFY_WRITE is not set
  15921. +# CONFIG_MTD_NAND_ECC_BCH is not set
  15922. +# CONFIG_MTD_NAND_MUSEUM_IDS is not set
  15923. +# CONFIG_MTD_NAND_DISKONCHIP is not set
  15924. +# CONFIG_MTD_LPDDR is not set
  15925. +CONFIG_MTD_UBI=m
  15926. +CONFIG_MTD_UBI_WL_THRESHOLD=4096
  15927. +CONFIG_MTD_UBI_BEB_LIMIT=20
  15928. +# CONFIG_MTD_UBI_FASTMAP is not set
  15929. +# CONFIG_MTD_UBI_GLUEBI is not set
  15930. +
  15931. +#
  15932. +# Parallel port support
  15933. +#
  15934. +CONFIG_PARPORT=m
  15935. +CONFIG_PARPORT_PC=m
  15936. +CONFIG_PARPORT_SERIAL=m
  15937. +# CONFIG_PARPORT_PC_FIFO is not set
  15938. +# CONFIG_PARPORT_PC_SUPERIO is not set
  15939. +CONFIG_PARPORT_PC_PCMCIA=m
  15940. +CONFIG_PARPORT_1284=y
  15941. +# CONFIG_PARPORT_AX88796 is not set
  15942. +
  15943. +CONFIG_ACPI_PCI_SLOT=y
  15944. +CONFIG_HOTPLUG_PCI_ACPI=y
  15945. +CONFIG_HOTPLUG_PCI_ACPI_IBM=m
  15946. +
  15947. +#
  15948. +# Block devices
  15949. +#
  15950. +CONFIG_BLK_DEV=y
  15951. +CONFIG_BLK_DEV_NULL_BLK=m
  15952. +CONFIG_BLK_DEV_FD=m
  15953. +# CONFIG_PARIDE is not set
  15954. +CONFIG_ZRAM=m
  15955. +# CONFIG_ZRAM_DEBUG is not set
  15956. +CONFIG_ENHANCEIO=m
  15957. +
  15958. +CONFIG_BLK_CPQ_DA=m
  15959. +CONFIG_BLK_CPQ_CISS_DA=m
  15960. +CONFIG_CISS_SCSI_TAPE=y
  15961. +CONFIG_BLK_DEV_DAC960=m
  15962. +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
  15963. +CONFIG_BLK_DEV_DRBD=m
  15964. +CONFIG_BLK_DEV_UMEM=m
  15965. +CONFIG_BLK_DEV_LOOP_MIN_COUNT=0
  15966. +# Fedora 18 util-linux is the last release that supports cryptoloop devices
  15967. +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
  15968. +CONFIG_BLK_DEV_NBD=m
  15969. +CONFIG_BLK_DEV_NVME=m
  15970. +CONFIG_BLK_DEV_SKD=m # 64-bit only but easier to put here
  15971. +CONFIG_BLK_DEV_OSD=m
  15972. +CONFIG_BLK_DEV_RAM_COUNT=16
  15973. +CONFIG_BLK_DEV_IO_TRACE=y
  15974. +
  15975. +CONFIG_BLK_DEV_BSGLIB=y
  15976. +CONFIG_BLK_DEV_INTEGRITY=y
  15977. +CONFIG_BLK_DEV_THROTTLING=y
  15978. +# CONFIG_BLK_CMDLINE_PARSER is not set
  15979. +
  15980. +
  15981. +#
  15982. +# ATA/ATAPI/MFM/RLL support
  15983. +#
  15984. +# CONFIG_IDE is not set
  15985. +
  15986. +# CONFIG_BLK_DEV_HD is not set
  15987. +# CONFIG_BLK_DEV_RSXX is not set
  15988. +
  15989. +CONFIG_SCSI_VIRTIO=m
  15990. +CONFIG_VIRTIO_BLK=m
  15991. +CONFIG_VIRTIO_PCI=m
  15992. +CONFIG_VIRTIO_BALLOON=m
  15993. +CONFIG_VIRTIO_MMIO=m
  15994. +# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
  15995. +CONFIG_VIRTIO_NET=m
  15996. +CONFIG_HW_RANDOM_VIRTIO=m
  15997. +CONFIG_VIRTIO_CONSOLE=m
  15998. +CONFIG_VHOST_NET=m
  15999. +CONFIG_TCM_VHOST=m
  16000. +CONFIG_VHOST_SCSI=m
  16001. +
  16002. +#
  16003. +# SCSI device support
  16004. +#
  16005. +CONFIG_SCSI=y
  16006. +
  16007. +CONFIG_SCSI_ENCLOSURE=m
  16008. +CONFIG_SCSI_SRP=m
  16009. +CONFIG_SCSI_SRP_ATTRS=m
  16010. +CONFIG_SCSI_TGT=m
  16011. +CONFIG_SCSI_ISCI=m
  16012. +CONFIG_SCSI_CHELSIO_FCOE=m
  16013. +
  16014. +CONFIG_SCSI_DH=y
  16015. +CONFIG_SCSI_DH_RDAC=m
  16016. +CONFIG_SCSI_DH_HP_SW=m
  16017. +CONFIG_SCSI_DH_EMC=m
  16018. +CONFIG_SCSI_DH_ALUA=m
  16019. +
  16020. +#
  16021. +# SCSI support type (disk, tape, CD-ROM)
  16022. +#
  16023. +CONFIG_CHR_DEV_ST=m
  16024. +CONFIG_CHR_DEV_OSST=m
  16025. +CONFIG_BLK_DEV_SR=y
  16026. +CONFIG_BLK_DEV_SR_VENDOR=y
  16027. +CONFIG_CHR_DEV_SG=y
  16028. +CONFIG_CHR_DEV_SCH=m
  16029. +
  16030. +#
  16031. +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
  16032. +#
  16033. +CONFIG_SCSI_SPI_ATTRS=m
  16034. +CONFIG_SCSI_FC_ATTRS=m
  16035. +CONFIG_SCSI_FC_TGT_ATTRS=y
  16036. +CONFIG_SCSI_ISCSI_ATTRS=m
  16037. +CONFIG_SCSI_SAS_ATTRS=m
  16038. +CONFIG_SCSI_SRP_TGT_ATTRS=y
  16039. +CONFIG_SCSI_SAS_LIBSAS=m
  16040. +CONFIG_SCSI_SAS_ATA=y
  16041. +CONFIG_SCSI_SAS_HOST_SMP=y
  16042. +CONFIG_RAID_ATTRS=m
  16043. +
  16044. +CONFIG_ISCSI_TCP=m
  16045. +CONFIG_ISCSI_BOOT_SYSFS=m
  16046. +
  16047. +#
  16048. +# SCSI low-level drivers
  16049. +#
  16050. +CONFIG_BLK_DEV_3W_XXXX_RAID=m
  16051. +CONFIG_SCSI_3W_9XXX=m
  16052. +CONFIG_SCSI_ACARD=m
  16053. +CONFIG_SCSI_AACRAID=m
  16054. +CONFIG_SCSI_AIC7XXX=m
  16055. +# http://lists.fedoraproject.org/pipermail/kernel/2013-February/004102.html
  16056. +# CONFIG_SCSI_AIC7XXX_OLD is not set
  16057. +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
  16058. +CONFIG_AIC7XXX_RESET_DELAY_MS=15000
  16059. +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
  16060. +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
  16061. +CONFIG_AIC7XXX_DEBUG_MASK=0
  16062. +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
  16063. +CONFIG_SCSI_AIC79XX=m
  16064. +CONFIG_AIC79XX_CMDS_PER_DEVICE=4
  16065. +CONFIG_AIC79XX_RESET_DELAY_MS=15000
  16066. +# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
  16067. +# CONFIG_AIC79XX_DEBUG_ENABLE is not set
  16068. +CONFIG_AIC79XX_DEBUG_MASK=0
  16069. +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
  16070. +CONFIG_SCSI_AIC94XX=m
  16071. +# CONFIG_AIC94XX_DEBUG is not set
  16072. +# CONFIG_SCSI_ADVANSYS is not set
  16073. +CONFIG_SCSI_BFA_FC=m
  16074. +CONFIG_MEGARAID_NEWGEN=y
  16075. +CONFIG_MEGARAID_MM=m
  16076. +CONFIG_MEGARAID_MAILBOX=m
  16077. +CONFIG_MEGARAID_LEGACY=m
  16078. +CONFIG_MEGARAID_SAS=m
  16079. +CONFIG_SCSI_ESAS2R=m
  16080. +CONFIG_SCSI_MVSAS=m
  16081. +# CONFIG_SCSI_MVSAS_DEBUG is not set
  16082. +CONFIG_SCSI_MVSAS_TASKLET=y
  16083. +CONFIG_SCSI_MPT2SAS=m
  16084. +CONFIG_SCSI_MPT2SAS_MAX_SGE=128
  16085. +CONFIG_SCSI_MPT2SAS_LOGGING=y
  16086. +CONFIG_SCSI_MPT3SAS=m
  16087. +CONFIG_SCSI_MPT3SAS_MAX_SGE=128
  16088. +CONFIG_SCSI_MPT3SAS_LOGGING=y
  16089. +
  16090. +CONFIG_SCSI_UFSHCD=m
  16091. +CONFIG_SCSI_UFSHCD_PCI=m
  16092. +# CONFIG_SCSI_UFSHCD_PLATFORM is not set
  16093. +
  16094. +CONFIG_SCSI_MVUMI=m
  16095. +
  16096. +CONFIG_SCSI_OSD_INITIATOR=m
  16097. +CONFIG_SCSI_OSD_ULD=m
  16098. +CONFIG_SCSI_OSD_DPRINT_SENSE=1
  16099. +# CONFIG_SCSI_OSD_DEBUG is not set
  16100. +
  16101. +CONFIG_SCSI_BNX2_ISCSI=m
  16102. +CONFIG_SCSI_BNX2X_FCOE=m
  16103. +CONFIG_BE2ISCSI=m
  16104. +CONFIG_SCSI_PMCRAID=m
  16105. +
  16106. +CONFIG_SCSI_HPSA=m
  16107. +CONFIG_SCSI_3W_SAS=m
  16108. +CONFIG_SCSI_PM8001=m
  16109. +CONFIG_VMWARE_PVSCSI=m
  16110. +CONFIG_VMWARE_BALLOON=m
  16111. +
  16112. +CONFIG_SCSI_ARCMSR=m
  16113. +CONFIG_SCSI_BUSLOGIC=m
  16114. +CONFIG_SCSI_INITIO=m
  16115. +CONFIG_SCSI_FLASHPOINT=y
  16116. +CONFIG_SCSI_DMX3191D=m
  16117. +# CONFIG_SCSI_EATA is not set
  16118. +# CONFIG_SCSI_EATA_PIO is not set
  16119. +# CONFIG_SCSI_FUTURE_DOMAIN is not set
  16120. +CONFIG_SCSI_GDTH=m
  16121. +CONFIG_SCSI_HPTIOP=m
  16122. +CONFIG_SCSI_IPS=m
  16123. +CONFIG_SCSI_INIA100=m
  16124. +# CONFIG_SCSI_PPA is not set
  16125. +# CONFIG_SCSI_IMM is not set
  16126. +# CONFIG_SCSI_IZIP_EPP16 is not set
  16127. +# CONFIG_SCSI_IZIP_SLOW_CTR is not set
  16128. +CONFIG_SCSI_STEX=m
  16129. +CONFIG_SCSI_SYM53C8XX_2=m
  16130. +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
  16131. +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
  16132. +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
  16133. +CONFIG_SCSI_SYM53C8XX_MMIO=y
  16134. +CONFIG_SCSI_QLOGIC_1280=m
  16135. +CONFIG_SCSI_DC395x=m
  16136. +# CONFIG_SCSI_NSP32 is not set
  16137. +CONFIG_SCSI_DEBUG=m
  16138. +CONFIG_SCSI_DC390T=m
  16139. +CONFIG_SCSI_QLA_FC=m
  16140. +CONFIG_TCM_QLA2XXX=m
  16141. +CONFIG_SCSI_QLA_ISCSI=m
  16142. +CONFIG_SCSI_IPR=m
  16143. +CONFIG_SCSI_IPR_TRACE=y
  16144. +CONFIG_SCSI_IPR_DUMP=y
  16145. +# CONFIG_SCSI_DPT_I2O is not set
  16146. +CONFIG_SCSI_LPFC=m
  16147. +# CONFIG_SCSI_LPFC_DEBUG_FS is not set
  16148. +
  16149. +# PCMCIA SCSI adapter support
  16150. +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
  16151. +
  16152. +CONFIG_ATA_BMDMA=y
  16153. +CONFIG_ATA_VERBOSE_ERROR=y
  16154. +CONFIG_ATA_SFF=y
  16155. +CONFIG_ATA_PIIX=y
  16156. +# CONFIG_SATA_HIGHBANK is not set
  16157. +CONFIG_ATA_ACPI=y
  16158. +CONFIG_BLK_DEV_SX8=m
  16159. +CONFIG_PDC_ADMA=m
  16160. +CONFIG_SATA_AHCI=y
  16161. +CONFIG_SATA_INIC162X=m
  16162. +CONFIG_SATA_MV=m
  16163. +CONFIG_SATA_NV=m
  16164. +CONFIG_SATA_PMP=y
  16165. +CONFIG_SATA_PROMISE=m
  16166. +CONFIG_SATA_QSTOR=m
  16167. +CONFIG_SATA_RCAR=m
  16168. +CONFIG_SATA_SIL=m
  16169. +CONFIG_SATA_SIL24=m
  16170. +CONFIG_SATA_SIS=m
  16171. +CONFIG_SATA_SVW=m
  16172. +CONFIG_SATA_SX4=m
  16173. +CONFIG_SATA_ULI=m
  16174. +CONFIG_SATA_VIA=m
  16175. +CONFIG_SATA_VITESSE=m
  16176. +# CONFIG_SATA_ZPODD is not set
  16177. +CONFIG_SATA_ACARD_AHCI=m
  16178. +
  16179. +# CONFIG_PATA_LEGACY is not set
  16180. +CONFIG_PATA_ACPI=m
  16181. +CONFIG_PATA_ALI=m
  16182. +CONFIG_PATA_AMD=m
  16183. +CONFIG_PATA_ARASAN_CF=m
  16184. +CONFIG_PATA_ARTOP=m
  16185. +CONFIG_PATA_ATIIXP=m
  16186. +CONFIG_PATA_CMD640_PCI=m
  16187. +CONFIG_PATA_CMD64X=m
  16188. +CONFIG_PATA_CS5520=m
  16189. +CONFIG_PATA_CS5530=m
  16190. +CONFIG_PATA_CS5535=m
  16191. +CONFIG_PATA_CS5536=m
  16192. +CONFIG_PATA_CYPRESS=m
  16193. +CONFIG_PATA_EFAR=m
  16194. +CONFIG_ATA_GENERIC=m
  16195. +CONFIG_PATA_HPT366=m
  16196. +CONFIG_PATA_HPT37X=m
  16197. +CONFIG_PATA_HPT3X2N=m
  16198. +CONFIG_PATA_HPT3X3=m
  16199. +# CONFIG_PATA_HPT3X3_DMA is not set
  16200. +CONFIG_PATA_IT821X=m
  16201. +CONFIG_PATA_IT8213=m
  16202. +CONFIG_PATA_JMICRON=m
  16203. +CONFIG_PATA_NINJA32=m
  16204. +CONFIG_PATA_MARVELL=m
  16205. +CONFIG_PATA_MPIIX=m
  16206. +CONFIG_PATA_NETCELL=m
  16207. +CONFIG_PATA_NS87410=m
  16208. +CONFIG_PATA_NS87415=m
  16209. +CONFIG_PATA_OLDPIIX=m
  16210. +CONFIG_PATA_OPTI=m
  16211. +CONFIG_PATA_OPTIDMA=m
  16212. +CONFIG_PATA_PCMCIA=m
  16213. +CONFIG_PATA_PDC_OLD=m
  16214. +# CONFIG_PATA_RADISYS is not set
  16215. +CONFIG_PATA_RDC=m
  16216. +# CONFIG_PATA_RZ1000 is not set
  16217. +# CONFIG_PATA_SC1200 is not set
  16218. +CONFIG_PATA_SERVERWORKS=m
  16219. +CONFIG_PATA_PDC2027X=m
  16220. +CONFIG_PATA_SCH=m
  16221. +CONFIG_PATA_SIL680=m
  16222. +CONFIG_PATA_SIS=m
  16223. +CONFIG_PATA_TOSHIBA=m
  16224. +CONFIG_PATA_TRIFLEX=m
  16225. +CONFIG_PATA_VIA=m
  16226. +CONFIG_PATA_WINBOND=m
  16227. +CONFIG_PATA_ATP867X=m
  16228. +
  16229. +
  16230. +#
  16231. +# Multi-device support (RAID and LVM)
  16232. +#
  16233. +CONFIG_MD=y
  16234. +CONFIG_BLK_DEV_MD=y
  16235. +CONFIG_MD_AUTODETECT=y
  16236. +CONFIG_MD_FAULTY=m
  16237. +CONFIG_MD_LINEAR=m
  16238. +CONFIG_MD_MULTIPATH=m
  16239. +CONFIG_MD_RAID0=m
  16240. +CONFIG_MD_RAID1=m
  16241. +CONFIG_MD_RAID10=m
  16242. +CONFIG_MD_RAID456=m
  16243. +
  16244. +CONFIG_BCACHE=m
  16245. +# CONFIG_BCACHE_DEBUG is not set
  16246. +# CONFIG_BCACHE_EDEBUG is not set
  16247. +# CONFIG_BCACHE_CLOSURES_DEBUG is not set
  16248. +
  16249. +# CONFIG_MULTICORE_RAID456 is not set
  16250. +CONFIG_ASYNC_RAID6_TEST=m
  16251. +CONFIG_BLK_DEV_DM=y
  16252. +CONFIG_DM_CRYPT=m
  16253. +CONFIG_DM_DEBUG=y
  16254. +CONFIG_DM_DELAY=m
  16255. +CONFIG_DM_MIRROR=y
  16256. +CONFIG_DM_MULTIPATH=m
  16257. +CONFIG_DM_SNAPSHOT=y
  16258. +CONFIG_DM_THIN_PROVISIONING=m
  16259. +CONFIG_DM_CACHE=m
  16260. +CONFIG_DM_CACHE_MQ=m
  16261. +CONFIG_DM_CACHE_CLEANER=m
  16262. +# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set
  16263. +# CONFIG_DM_DEBUG_SPACE_MAPS is not set
  16264. +CONFIG_DM_UEVENT=y
  16265. +CONFIG_DM_ZERO=y
  16266. +CONFIG_DM_LOG_USERSPACE=m
  16267. +CONFIG_DM_MULTIPATH_QL=m
  16268. +CONFIG_DM_MULTIPATH_ST=m
  16269. +CONFIG_DM_RAID=m
  16270. +CONFIG_DM_FLAKEY=m
  16271. +CONFIG_DM_VERITY=m
  16272. +CONFIG_DM_SWITCH=m
  16273. +
  16274. +#
  16275. +# Fusion MPT device support
  16276. +#
  16277. +CONFIG_FUSION=y
  16278. +CONFIG_FUSION_SPI=m
  16279. +CONFIG_FUSION_FC=m
  16280. +CONFIG_FUSION_MAX_SGE=40
  16281. +CONFIG_FUSION_CTL=m
  16282. +CONFIG_FUSION_LAN=m
  16283. +CONFIG_FUSION_SAS=m
  16284. +CONFIG_FUSION_LOGGING=y
  16285. +
  16286. +#
  16287. +# IEEE 1394 (FireWire) support (JUJU alternative stack)
  16288. +#
  16289. +CONFIG_FIREWIRE=m
  16290. +CONFIG_FIREWIRE_OHCI=m
  16291. +CONFIG_FIREWIRE_SBP2=m
  16292. +CONFIG_FIREWIRE_NET=m
  16293. +CONFIG_FIREWIRE_OHCI_DEBUG=y
  16294. +CONFIG_FIREWIRE_NOSY=m
  16295. +# CONFIG_FIREWIRE_SERIAL is not set
  16296. +# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set
  16297. +
  16298. +#
  16299. +# IEEE 1394 (FireWire) support
  16300. +#
  16301. +
  16302. +#
  16303. +# I2O device support
  16304. +#
  16305. +# CONFIG_I2O is not set
  16306. +# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
  16307. +
  16308. +#
  16309. +# Virtualization support drivers
  16310. +#
  16311. +# CONFIG_VIRT_DRIVERS is not set
  16312. +
  16313. +# Networking support
  16314. +#
  16315. +
  16316. +CONFIG_NET_DMA=y
  16317. +
  16318. +CONFIG_NETLINK_MMAP=y
  16319. +CONFIG_NETLINK_DIAG=m
  16320. +
  16321. +CONFIG_TCP_CONG_ADVANCED=y
  16322. +CONFIG_TCP_CONG_BIC=m
  16323. +CONFIG_TCP_CONG_CUBIC=y
  16324. +CONFIG_TCP_CONG_HTCP=m
  16325. +CONFIG_TCP_CONG_HSTCP=m
  16326. +CONFIG_TCP_CONG_HYBLA=m
  16327. +CONFIG_TCP_CONG_ILLINOIS=m
  16328. +CONFIG_TCP_CONG_LP=m
  16329. +CONFIG_TCP_CONG_SCALABLE=m
  16330. +CONFIG_TCP_CONG_VEGAS=m
  16331. +CONFIG_TCP_CONG_VENO=m
  16332. +CONFIG_TCP_CONG_WESTWOOD=m
  16333. +CONFIG_TCP_CONG_YEAH=m
  16334. +
  16335. +CONFIG_TCP_MD5SIG=y
  16336. +
  16337. +#
  16338. +# Networking options
  16339. +#
  16340. +CONFIG_PACKET_DIAG=m
  16341. +CONFIG_UNIX_DIAG=m
  16342. +CONFIG_NET_KEY=m
  16343. +CONFIG_NET_KEY_MIGRATE=y
  16344. +CONFIG_INET_TUNNEL=m
  16345. +CONFIG_INET_DIAG=m
  16346. +CONFIG_INET_UDP_DIAG=m
  16347. +CONFIG_IP_MULTICAST=y
  16348. +CONFIG_IP_ADVANCED_ROUTER=y
  16349. +CONFIG_IP_FIB_TRIE_STATS=y
  16350. +CONFIG_IP_MULTIPLE_TABLES=y
  16351. +CONFIG_IP_ROUTE_MULTIPATH=y
  16352. +CONFIG_IP_ROUTE_VERBOSE=y
  16353. +CONFIG_IP_NF_SECURITY=m
  16354. +CONFIG_NET_IPIP=m
  16355. +CONFIG_NET_IPGRE_DEMUX=m
  16356. +CONFIG_NET_IPGRE=m
  16357. +CONFIG_NET_IPGRE_BROADCAST=y
  16358. +CONFIG_IP_MROUTE=y
  16359. +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
  16360. +CONFIG_IP_PIMSM_V1=y
  16361. +CONFIG_IP_PIMSM_V2=y
  16362. +CONFIG_ARPD=y
  16363. +CONFIG_SYN_COOKIES=y
  16364. +CONFIG_NET_IPVTI=m
  16365. +CONFIG_INET_AH=m
  16366. +CONFIG_INET_ESP=m
  16367. +CONFIG_INET_IPCOMP=m
  16368. +CONFIG_NETCONSOLE=m
  16369. +CONFIG_NETCONSOLE_DYNAMIC=y
  16370. +CONFIG_NETPOLL_TRAP=y
  16371. +CONFIG_NET_POLL_CONTROLLER=y
  16372. +
  16373. +#
  16374. +# IP: Virtual Server Configuration
  16375. +#
  16376. +CONFIG_IP_VS=m
  16377. +# CONFIG_IP_VS_DEBUG is not set
  16378. +CONFIG_IP_VS_TAB_BITS=12
  16379. +CONFIG_IP_VS_PROTO_TCP=y
  16380. +CONFIG_IP_VS_PROTO_UDP=y
  16381. +CONFIG_IP_VS_PROTO_ESP=y
  16382. +CONFIG_IP_VS_PROTO_AH=y
  16383. +CONFIG_IP_VS_PROTO_SCTP=y
  16384. +CONFIG_IP_VS_IPV6=y
  16385. +CONFIG_IP_VS_RR=m
  16386. +CONFIG_IP_VS_WRR=m
  16387. +CONFIG_IP_VS_LC=m
  16388. +CONFIG_IP_VS_WLC=m
  16389. +CONFIG_IP_VS_LBLC=m
  16390. +CONFIG_IP_VS_LBLCR=m
  16391. +CONFIG_IP_VS_DH=m
  16392. +CONFIG_IP_VS_SH=m
  16393. +CONFIG_IP_VS_SED=m
  16394. +CONFIG_IP_VS_NQ=m
  16395. +
  16396. +#
  16397. +# IPVS SH scheduler
  16398. +#
  16399. +CONFIG_IP_VS_SH_TAB_BITS=8
  16400. +
  16401. +CONFIG_IP_VS_FTP=m
  16402. +CONFIG_IP_VS_PE_SIP=m
  16403. +
  16404. +CONFIG_IPV6_PRIVACY=y
  16405. +CONFIG_IPV6_ROUTER_PREF=y
  16406. +CONFIG_IPV6_ROUTE_INFO=y
  16407. +CONFIG_IPV6_OPTIMISTIC_DAD=y
  16408. +CONFIG_INET6_AH=m
  16409. +CONFIG_INET6_ESP=m
  16410. +CONFIG_INET6_IPCOMP=m
  16411. +CONFIG_IPV6_MIP6=y
  16412. +CONFIG_IPV6_VTI=m
  16413. +CONFIG_IPV6_SIT=m
  16414. +CONFIG_IPV6_SIT_6RD=y
  16415. +CONFIG_IPV6_TUNNEL=m
  16416. +# CONFIG_IPV6_GRE is not set
  16417. +CONFIG_IPV6_SUBTREES=y
  16418. +CONFIG_IPV6_MULTIPLE_TABLES=y
  16419. +CONFIG_IPV6_MROUTE=y
  16420. +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
  16421. +CONFIG_IPV6_PIMSM_V2=y
  16422. +
  16423. +CONFIG_RDS=m
  16424. +# CONFIG_RDS_DEBUG is not set
  16425. +CONFIG_RDS_RDMA=m
  16426. +CONFIG_RDS_TCP=m
  16427. +
  16428. +CONFIG_NET_9P=m
  16429. +CONFIG_NET_9P_VIRTIO=m
  16430. +# CONFIG_NET_9P_DEBUG is not set
  16431. +CONFIG_NET_9P_RDMA=m
  16432. +
  16433. +# CONFIG_DECNET is not set
  16434. +CONFIG_BRIDGE=m
  16435. +CONFIG_BRIDGE_IGMP_SNOOPING=y
  16436. +CONFIG_BRIDGE_VLAN_FILTERING=y
  16437. +
  16438. +# PHY timestamping adds overhead
  16439. +CONFIG_NETWORK_PHY_TIMESTAMPING=y
  16440. +
  16441. +CONFIG_NETFILTER_ADVANCED=y
  16442. +CONFIG_NF_CONNTRACK=m
  16443. +CONFIG_NETFILTER_NETLINK=m
  16444. +CONFIG_NETFILTER_NETLINK_ACCT=m
  16445. +CONFIG_NETFILTER_NETLINK_QUEUE=m
  16446. +CONFIG_NETFILTER_NETLINK_QUEUE_CT=y
  16447. +CONFIG_NETFILTER_NETLINK_LOG=m
  16448. +CONFIG_NETFILTER_TPROXY=m
  16449. +CONFIG_NETFILTER_XTABLES=y
  16450. +CONFIG_NETFILTER_XT_SET=m
  16451. +CONFIG_NETFILTER_XT_MARK=m
  16452. +CONFIG_NETFILTER_XT_CONNMARK=m
  16453. +
  16454. +CONFIG_NETFILTER_XT_TARGET_AUDIT=m
  16455. +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
  16456. +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
  16457. +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
  16458. +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
  16459. +CONFIG_NETFILTER_XT_TARGET_CT=m
  16460. +CONFIG_NETFILTER_XT_TARGET_DSCP=m
  16461. +CONFIG_NETFILTER_XT_TARGET_HMARK=m
  16462. +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
  16463. +CONFIG_NETFILTER_XT_TARGET_LED=m
  16464. +CONFIG_NETFILTER_XT_TARGET_LOG=m
  16465. +CONFIG_NETFILTER_XT_TARGET_MARK=m
  16466. +CONFIG_NETFILTER_XT_TARGET_NFLOG=m
  16467. +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
  16468. +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
  16469. +CONFIG_NETFILTER_XT_TARGET_RATEEST=m
  16470. +CONFIG_NETFILTER_XT_TARGET_SECMARK=m
  16471. +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
  16472. +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
  16473. +CONFIG_NETFILTER_XT_TARGET_TRACE=m
  16474. +CONFIG_NETFILTER_XT_TARGET_TEE=m
  16475. +CONFIG_NETFILTER_XT_TARGET_TPROXY=m
  16476. +
  16477. +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
  16478. +CONFIG_NETFILTER_XT_MATCH_BPF=m
  16479. +CONFIG_NETFILTER_XT_MATCH_CGROUP=m
  16480. +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
  16481. +CONFIG_NETFILTER_XT_MATCH_COMMENT=m
  16482. +CONFIG_NETFILTER_XT_MATCH_CPU=m
  16483. +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
  16484. +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
  16485. +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
  16486. +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
  16487. +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
  16488. +CONFIG_NETFILTER_XT_MATCH_DCCP=m
  16489. +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
  16490. +CONFIG_NETFILTER_XT_MATCH_DSCP=m
  16491. +CONFIG_NETFILTER_XT_MATCH_ECN=m
  16492. +CONFIG_NETFILTER_XT_MATCH_ESP=m
  16493. +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
  16494. +CONFIG_NETFILTER_XT_MATCH_HELPER=m
  16495. +CONFIG_NETFILTER_XT_MATCH_HL=m
  16496. +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m
  16497. +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
  16498. +CONFIG_NETFILTER_XT_MATCH_IPVS=m
  16499. +CONFIG_NETFILTER_XT_MATCH_L2TP=m
  16500. +CONFIG_NETFILTER_XT_MATCH_LENGTH=m
  16501. +CONFIG_NETFILTER_XT_MATCH_LIMIT=m
  16502. +CONFIG_NETFILTER_XT_MATCH_MAC=m
  16503. +CONFIG_NETFILTER_XT_MATCH_MARK=m
  16504. +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
  16505. +CONFIG_NETFILTER_XT_MATCH_NFACCT=m
  16506. +CONFIG_NETFILTER_XT_MATCH_OSF=m
  16507. +CONFIG_NETFILTER_XT_MATCH_OWNER=m
  16508. +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
  16509. +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
  16510. +CONFIG_NETFILTER_XT_MATCH_POLICY=m
  16511. +CONFIG_NETFILTER_XT_MATCH_QUOTA=m
  16512. +CONFIG_NETFILTER_XT_MATCH_RATEEST=m
  16513. +CONFIG_NETFILTER_XT_MATCH_REALM=m
  16514. +CONFIG_NETFILTER_XT_MATCH_RECENT=m
  16515. +CONFIG_NETFILTER_XT_MATCH_SCTP=m
  16516. +CONFIG_NETFILTER_XT_MATCH_SOCKET=m
  16517. +CONFIG_NETFILTER_XT_MATCH_STATE=y
  16518. +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
  16519. +CONFIG_NETFILTER_XT_MATCH_STRING=m
  16520. +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
  16521. +CONFIG_NETFILTER_XT_MATCH_TIME=m
  16522. +CONFIG_NETFILTER_XT_MATCH_U32=m
  16523. +
  16524. +# CONFIG_NETFILTER_DEBUG is not set
  16525. +CONFIG_BRIDGE_NETFILTER=y
  16526. +
  16527. +#
  16528. +# IP: Netfilter Configuration
  16529. +#
  16530. +
  16531. +CONFIG_NF_CONNTRACK_MARK=y
  16532. +CONFIG_NF_CONNTRACK_SECMARK=y
  16533. +CONFIG_NF_CONNTRACK_EVENTS=y
  16534. +CONFIG_NF_CONNTRACK_ZONES=y
  16535. +CONFIG_NF_CONNTRACK_PROCFS=y # check if contrack(8) in f17 supports netlink
  16536. +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
  16537. +CONFIG_NF_CONNTRACK_AMANDA=m
  16538. +CONFIG_NF_CONNTRACK_FTP=m
  16539. +CONFIG_NF_CONNTRACK_H323=m
  16540. +CONFIG_NF_CONNTRACK_IRC=m
  16541. +CONFIG_NF_CONNTRACK_NETBIOS_NS=m
  16542. +CONFIG_NF_CONNTRACK_PPTP=m
  16543. +CONFIG_NF_CONNTRACK_SANE=m
  16544. +CONFIG_NF_CONNTRACK_SIP=m
  16545. +CONFIG_NF_CONNTRACK_TFTP=m
  16546. +CONFIG_NF_CONNTRACK_IPV4=y
  16547. +CONFIG_NF_CONNTRACK_IPV6=y
  16548. +# CONFIG_NF_CONNTRACK_TIMEOUT is not set
  16549. +CONFIG_NF_CONNTRACK_TIMESTAMP=y
  16550. +CONFIG_NF_CONNTRACK_SNMP=m
  16551. +CONFIG_NF_NAT=m
  16552. +CONFIG_NF_NAT_SNMP_BASIC=m
  16553. +CONFIG_NF_CT_PROTO_DCCP=m
  16554. +CONFIG_NF_CT_PROTO_SCTP=m
  16555. +CONFIG_NF_CT_NETLINK=m
  16556. +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
  16557. +CONFIG_NF_CT_NETLINK_HELPER=m
  16558. +CONFIG_NF_CT_PROTO_UDPLITE=m
  16559. +
  16560. +CONFIG_IP_NF_MATCH_AH=m
  16561. +CONFIG_IP_NF_MATCH_ECN=m
  16562. +CONFIG_IP_NF_MATCH_RPFILTER=m
  16563. +CONFIG_IP_NF_MATCH_TTL=m
  16564. +CONFIG_IP_NF_TARGET_CLUSTERIP=m
  16565. +CONFIG_IP_NF_TARGET_REDIRECT=m
  16566. +CONFIG_IP_NF_TARGET_NETMAP=m
  16567. +CONFIG_IP_NF_TARGET_ECN=m
  16568. +CONFIG_IP_NF_TARGET_LOG=m
  16569. +CONFIG_IP_NF_TARGET_ULOG=m
  16570. +CONFIG_IP_NF_TARGET_REJECT=y
  16571. +CONFIG_IP_NF_TARGET_SYNPROXY=m
  16572. +CONFIG_IP_NF_TARGET_TTL=m
  16573. +CONFIG_NF_NAT_IPV4=m
  16574. +CONFIG_IP_NF_TARGET_MASQUERADE=m
  16575. +CONFIG_IP_NF_MANGLE=m
  16576. +CONFIG_IP_NF_ARPTABLES=m
  16577. +CONFIG_IP_NF_ARPFILTER=m
  16578. +CONFIG_IP_NF_ARP_MANGLE=m
  16579. +CONFIG_IP_NF_QUEUE=m
  16580. +CONFIG_IP_NF_RAW=m
  16581. +
  16582. +CONFIG_IP_NF_IPTABLES=y
  16583. +CONFIG_IP_NF_FILTER=y
  16584. +
  16585. +#
  16586. +# IPv6: Netfilter Configuration
  16587. +#
  16588. +CONFIG_IP6_NF_FILTER=m
  16589. +CONFIG_IP6_NF_IPTABLES=m
  16590. +CONFIG_IP6_NF_MANGLE=m
  16591. +CONFIG_IP6_NF_MATCH_AH=m
  16592. +CONFIG_IP6_NF_MATCH_EUI64=m
  16593. +CONFIG_IP6_NF_MATCH_FRAG=m
  16594. +CONFIG_IP6_NF_MATCH_HL=m
  16595. +CONFIG_IP6_NF_MATCH_IPV6HEADER=m
  16596. +CONFIG_IP6_NF_MATCH_MH=m
  16597. +CONFIG_IP6_NF_MATCH_RPFILTER=m
  16598. +CONFIG_IP6_NF_MATCH_OPTS=m
  16599. +CONFIG_IP6_NF_MATCH_RT=m
  16600. +CONFIG_IP6_NF_QUEUE=m
  16601. +CONFIG_IP6_NF_RAW=m
  16602. +CONFIG_IP6_NF_SECURITY=m
  16603. +CONFIG_IP6_NF_TARGET_LOG=m
  16604. +CONFIG_IP6_NF_TARGET_REJECT=m
  16605. +CONFIG_IP6_NF_TARGET_SYNPROXY=m
  16606. +CONFIG_IP6_NF_TARGET_HL=m
  16607. +CONFIG_NF_NAT_IPV6=m
  16608. +CONFIG_IP6_NF_TARGET_MASQUERADE=m
  16609. +# CONFIG_IP6_NF_TARGET_NPT is not set
  16610. +
  16611. +# nf_tables support
  16612. +CONFIG_NF_TABLES=m
  16613. +CONFIG_NF_TABLES_INET=m
  16614. +CONFIG_NFT_EXTHDR=m
  16615. +CONFIG_NFT_META=m
  16616. +CONFIG_NFT_CT=m
  16617. +CONFIG_NFT_RBTREE=m
  16618. +CONFIG_NFT_HASH=m
  16619. +CONFIG_NFT_COUNTER=m
  16620. +CONFIG_NFT_LOG=m
  16621. +CONFIG_NFT_LIMIT=m
  16622. +CONFIG_NFT_NAT=m
  16623. +CONFIG_NFT_QUEUE=m
  16624. +CONFIG_NFT_REJECT=m
  16625. +CONFIG_NFT_COMPAT=m
  16626. +
  16627. +CONFIG_NF_TABLES_IPV4=m
  16628. +CONFIG_NFT_REJECT_IPV4=m
  16629. +CONFIG_NFT_CHAIN_ROUTE_IPV4=m
  16630. +CONFIG_NFT_CHAIN_NAT_IPV4=m
  16631. +CONFIG_NF_TABLES_ARP=m
  16632. +
  16633. +CONFIG_NF_TABLES_IPV6=m
  16634. +CONFIG_NFT_CHAIN_ROUTE_IPV6=m
  16635. +CONFIG_NFT_CHAIN_NAT_IPV6=m
  16636. +
  16637. +CONFIG_NF_TABLES_BRIDGE=m
  16638. +#
  16639. +# Bridge: Netfilter Configuration
  16640. +#
  16641. +CONFIG_BRIDGE_NF_EBTABLES=m
  16642. +CONFIG_BRIDGE_EBT_802_3=m
  16643. +CONFIG_BRIDGE_EBT_AMONG=m
  16644. +CONFIG_BRIDGE_EBT_ARP=m
  16645. +CONFIG_BRIDGE_EBT_ARPREPLY=m
  16646. +CONFIG_BRIDGE_EBT_BROUTE=m
  16647. +CONFIG_BRIDGE_EBT_DNAT=m
  16648. +CONFIG_BRIDGE_EBT_IP=m
  16649. +CONFIG_BRIDGE_EBT_IP6=m
  16650. +CONFIG_BRIDGE_EBT_LIMIT=m
  16651. +CONFIG_BRIDGE_EBT_LOG=m
  16652. +CONFIG_BRIDGE_EBT_MARK=m
  16653. +CONFIG_BRIDGE_EBT_MARK_T=m
  16654. +CONFIG_BRIDGE_EBT_NFLOG=m
  16655. +CONFIG_BRIDGE_EBT_PKTTYPE=m
  16656. +CONFIG_BRIDGE_EBT_REDIRECT=m
  16657. +CONFIG_BRIDGE_EBT_SNAT=m
  16658. +CONFIG_BRIDGE_EBT_STP=m
  16659. +CONFIG_BRIDGE_EBT_T_FILTER=m
  16660. +CONFIG_BRIDGE_EBT_T_NAT=m
  16661. +CONFIG_BRIDGE_EBT_ULOG=m
  16662. +CONFIG_BRIDGE_EBT_VLAN=m
  16663. +CONFIG_XFRM=y
  16664. +CONFIG_XFRM_MIGRATE=y
  16665. +CONFIG_XFRM_SUB_POLICY=y
  16666. +CONFIG_XFRM_STATISTICS=y
  16667. +CONFIG_XFRM_USER=y
  16668. +CONFIG_INET6_XFRM_MODE_TRANSPORT=m
  16669. +CONFIG_INET6_XFRM_MODE_TUNNEL=m
  16670. +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
  16671. +CONFIG_INET6_XFRM_MODE_BEET=m
  16672. +
  16673. +CONFIG_IP_SET=m
  16674. +CONFIG_IP_SET_MAX=256
  16675. +CONFIG_IP_SET_BITMAP_IP=m
  16676. +CONFIG_IP_SET_BITMAP_IPMAC=m
  16677. +CONFIG_IP_SET_BITMAP_PORT=m
  16678. +CONFIG_IP_SET_HASH_IP=m
  16679. +CONFIG_IP_SET_HASH_IPPORT=m
  16680. +CONFIG_IP_SET_HASH_IPPORTIP=m
  16681. +CONFIG_IP_SET_HASH_IPPORTNET=m
  16682. +CONFIG_IP_SET_HASH_NETPORTNET=m
  16683. +CONFIG_IP_SET_HASH_NET=m
  16684. +CONFIG_IP_SET_HASH_NETNET=m
  16685. +CONFIG_IP_SET_HASH_NETPORT=m
  16686. +CONFIG_IP_SET_HASH_NETIFACE=m
  16687. +CONFIG_IP_SET_LIST_SET=m
  16688. +
  16689. +#
  16690. +# SCTP Configuration (EXPERIMENTAL)
  16691. +#
  16692. +CONFIG_IP_SCTP=m
  16693. +CONFIG_NET_SCTPPROBE=m
  16694. +# CONFIG_SCTP_DBG_MSG is not set
  16695. +# CONFIG_SCTP_DBG_OBJCNT is not set
  16696. +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1=y
  16697. +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5 is not set
  16698. +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
  16699. +CONFIG_SCTP_COOKIE_HMAC_MD5=y
  16700. +CONFIG_SCTP_COOKIE_HMAC_SHA1=y
  16701. +CONFIG_ATM=m
  16702. +CONFIG_VLAN_8021Q_GVRP=y
  16703. +CONFIG_VLAN_8021Q_MVRP=y
  16704. +CONFIG_LLC=m
  16705. +# CONFIG_LLC2 is not set
  16706. +CONFIG_IPX=m
  16707. +# CONFIG_IPX_INTERN is not set
  16708. +CONFIG_ATALK=m
  16709. +CONFIG_DEV_APPLETALK=m
  16710. +CONFIG_IPDDP=m
  16711. +CONFIG_IPDDP_ENCAP=y
  16712. +CONFIG_IPDDP_DECAP=y
  16713. +# CONFIG_X25 is not set
  16714. +# CONFIG_LAPB is not set
  16715. +# CONFIG_ECONET is not set
  16716. +CONFIG_WAN_ROUTER=m
  16717. +CONFIG_IP_DCCP=m
  16718. +CONFIG_IP_DCCP_CCID2=m
  16719. +# CONFIG_IP_DCCP_CCID2_DEBUG is not set
  16720. +CONFIG_IP_DCCP_CCID3=y
  16721. +# CONFIG_IP_DCCP_CCID3_DEBUG is not set
  16722. +# CONFIG_IP_DCCP_DEBUG is not set
  16723. +# CONFIG_NET_DCCPPROBE is not set
  16724. +
  16725. +#
  16726. +# TIPC Configuration (EXPERIMENTAL)
  16727. +#
  16728. +CONFIG_TIPC=m
  16729. +CONFIG_TIPC_PORTS=8192
  16730. +# CONFIG_TIPC_MEDIA_IB is not set
  16731. +# CONFIG_TIPC_ADVANCED is not set
  16732. +# CONFIG_TIPC_DEBUG is not set
  16733. +
  16734. +CONFIG_NETLABEL=y
  16735. +
  16736. +#
  16737. +# QoS and/or fair queueing
  16738. +#
  16739. +CONFIG_NET_SCHED=y
  16740. +CONFIG_NET_SCH_CBQ=m
  16741. +CONFIG_NET_SCH_DSMARK=m
  16742. +CONFIG_NET_SCH_DRR=m
  16743. +CONFIG_NET_SCH_GRED=m
  16744. +CONFIG_NET_SCH_HFSC=m
  16745. +CONFIG_NET_SCH_HTB=m
  16746. +CONFIG_NET_SCH_INGRESS=m
  16747. +CONFIG_NET_SCH_NETEM=m
  16748. +CONFIG_NET_SCH_PRIO=m
  16749. +CONFIG_NET_SCH_RED=m
  16750. +CONFIG_NET_SCH_SFQ=m
  16751. +CONFIG_NET_SCH_TBF=m
  16752. +CONFIG_NET_SCH_TEQL=m
  16753. +CONFIG_NET_SCH_SFB=m
  16754. +CONFIG_NET_SCH_MQPRIO=m
  16755. +CONFIG_NET_SCH_MULTIQ=m
  16756. +CONFIG_NET_SCH_CHOKE=m
  16757. +CONFIG_NET_SCH_QFQ=m
  16758. +CONFIG_NET_SCH_CODEL=m
  16759. +CONFIG_NET_SCH_FQ_CODEL=m
  16760. +CONFIG_NET_SCH_FQ=m
  16761. +CONFIG_NET_SCH_HHF=m
  16762. +CONFIG_NET_SCH_PIE=m
  16763. +CONFIG_NET_SCH_PLUG=m
  16764. +CONFIG_NET_CLS=y
  16765. +CONFIG_NET_CLS_ACT=y
  16766. +CONFIG_NET_CLS_BASIC=m
  16767. +CONFIG_NET_CLS_CGROUP=y
  16768. +CONFIG_NET_CLS_BPF=m
  16769. +CONFIG_NET_CLS_FLOW=m
  16770. +CONFIG_NET_CLS_FW=m
  16771. +CONFIG_NET_CLS_IND=y
  16772. +CONFIG_NET_CLS_ROUTE4=m
  16773. +CONFIG_NET_CLS_ROUTE=y
  16774. +CONFIG_NET_CLS_RSVP=m
  16775. +CONFIG_NET_CLS_RSVP6=m
  16776. +CONFIG_NET_CLS_TCINDEX=m
  16777. +CONFIG_NET_CLS_U32=m
  16778. +CONFIG_CLS_U32_MARK=y
  16779. +CONFIG_CLS_U32_PERF=y
  16780. +CONFIG_NET_EMATCH=y
  16781. +CONFIG_NET_EMATCH_CMP=m
  16782. +CONFIG_NET_EMATCH_META=m
  16783. +CONFIG_NET_EMATCH_NBYTE=m
  16784. +CONFIG_NET_EMATCH_STACK=32
  16785. +CONFIG_NET_EMATCH_TEXT=m
  16786. +CONFIG_NET_EMATCH_IPSET=m
  16787. +CONFIG_NET_EMATCH_U32=m
  16788. +
  16789. +CONFIG_NET_ACT_CSUM=m
  16790. +CONFIG_NET_ACT_GACT=m
  16791. +CONFIG_GACT_PROB=y
  16792. +CONFIG_NET_ACT_IPT=m
  16793. +CONFIG_NET_ACT_MIRRED=m
  16794. +CONFIG_NET_ACT_NAT=m
  16795. +CONFIG_NET_ACT_PEDIT=m
  16796. +CONFIG_NET_ACT_POLICE=m
  16797. +CONFIG_NET_ACT_SIMP=m
  16798. +CONFIG_NET_ACT_SKBEDIT=m
  16799. +
  16800. +CONFIG_DCB=y
  16801. +CONFIG_DNS_RESOLVER=m
  16802. +CONFIG_BATMAN_ADV=m
  16803. +CONFIG_BATMAN_ADV_BLA=y
  16804. +CONFIG_BATMAN_ADV_DAT=y
  16805. +CONFIG_BATMAN_ADV_NC=y
  16806. +
  16807. +# CONFIG_BATMAN_ADV_DEBUG is not set
  16808. +CONFIG_OPENVSWITCH=m
  16809. +CONFIG_OPENVSWITCH_GRE=y
  16810. +CONFIG_OPENVSWITCH_VXLAN=y
  16811. +CONFIG_VSOCKETS=m
  16812. +
  16813. +
  16814. +#
  16815. +# Network testing
  16816. +#
  16817. +CONFIG_NET_PKTGEN=m
  16818. +# CONFIG_NET_TCPPROBE is not set
  16819. +CONFIG_NET_DROP_MONITOR=y
  16820. +
  16821. +# disable later --kyle
  16822. +
  16823. +#
  16824. +# ARCnet devices
  16825. +#
  16826. +# CONFIG_ARCNET is not set
  16827. +CONFIG_IFB=m
  16828. +CONFIG_NET_TEAM=m
  16829. +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
  16830. +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
  16831. +CONFIG_NET_TEAM_MODE_LOADBALANCE=m
  16832. +CONFIG_NET_TEAM_MODE_BROADCAST=m
  16833. +CONFIG_NET_TEAM_MODE_RANDOM=m
  16834. +CONFIG_DUMMY=m
  16835. +CONFIG_BONDING=m
  16836. +CONFIG_MACVLAN=m
  16837. +CONFIG_MACVTAP=m
  16838. +CONFIG_VXLAN=m
  16839. +CONFIG_EQUALIZER=m
  16840. +CONFIG_TUN=m
  16841. +CONFIG_VETH=m
  16842. +CONFIG_NLMON=m
  16843. +
  16844. +#
  16845. +# ATM
  16846. +#
  16847. +CONFIG_ATM_DRIVERS=y
  16848. +# CONFIG_ATM_DUMMY is not set
  16849. +CONFIG_ATM_CLIP=m
  16850. +CONFIG_ATM_LANE=m
  16851. +CONFIG_ATM_BR2684=m
  16852. +CONFIG_NET_SCH_ATM=m
  16853. +CONFIG_ATM_TCP=m
  16854. +# CONFIG_ATM_LANAI is not set
  16855. +CONFIG_ATM_ENI=m
  16856. +CONFIG_ATM_FIRESTREAM=m
  16857. +# CONFIG_ATM_ZATM is not set
  16858. +# CONFIG_ATM_IDT77252 is not set
  16859. +# CONFIG_ATM_AMBASSADOR is not set
  16860. +# CONFIG_ATM_HORIZON is not set
  16861. +# CONFIG_ATM_FORE200E is not set
  16862. +# CONFIG_ATM_FORE200E_USE_TASKLET is not set
  16863. +CONFIG_ATM_FORE200E_TX_RETRY=16
  16864. +CONFIG_ATM_FORE200E_DEBUG=0
  16865. +
  16866. +CONFIG_ATM_HE=m
  16867. +CONFIG_PPTP=m
  16868. +CONFIG_PPPOATM=m
  16869. +CONFIG_PPPOL2TP=m
  16870. +CONFIG_ATM_NICSTAR=m
  16871. +# CONFIG_ATM_IA is not set
  16872. +# CONFIG_ATM_CLIP_NO_ICMP is not set
  16873. +# CONFIG_ATM_MPOA is not set
  16874. +# CONFIG_ATM_BR2684_IPFILTER is not set
  16875. +# CONFIG_ATM_ENI_DEBUG is not set
  16876. +# CONFIG_ATM_ENI_TUNE_BURST is not set
  16877. +# CONFIG_ATM_ZATM_DEBUG is not set
  16878. +# CONFIG_ATM_IDT77252_DEBUG is not set
  16879. +# CONFIG_ATM_IDT77252_RCV_ALL is not set
  16880. +# CONFIG_ATM_AMBASSADOR_DEBUG is not set
  16881. +# CONFIG_ATM_HORIZON_DEBUG is not set
  16882. +# CONFIG_ATM_HE_USE_SUNI is not set
  16883. +# CONFIG_ATM_NICSTAR_USE_SUNI is not set
  16884. +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
  16885. +# CONFIG_ATM_IA_DEBUG is not set
  16886. +CONFIG_ATM_SOLOS=m
  16887. +
  16888. +CONFIG_L2TP=m
  16889. +CONFIG_L2TP_V3=y
  16890. +CONFIG_L2TP_IP=m
  16891. +CONFIG_L2TP_ETH=m
  16892. +
  16893. +# CONFIG_CAIF is not set
  16894. +
  16895. +CONFIG_RFKILL=m
  16896. +CONFIG_RFKILL_GPIO=m
  16897. +CONFIG_RFKILL_INPUT=y
  16898. +
  16899. +
  16900. +#
  16901. +# Ethernet (10 or 100Mbit)
  16902. +#
  16903. +
  16904. +CONFIG_NET_VENDOR_ADAPTEC=y
  16905. +CONFIG_ADAPTEC_STARFIRE=m
  16906. +
  16907. +CONFIG_NET_VENDOR_ALTEON=y
  16908. +CONFIG_ACENIC=m
  16909. +# CONFIG_ACENIC_OMIT_TIGON_I is not set
  16910. +
  16911. +CONFIG_NET_VENDOR_AMD=y
  16912. +CONFIG_PCNET32=m
  16913. +CONFIG_AMD8111_ETH=m
  16914. +CONFIG_PCMCIA_NMCLAN=m
  16915. +
  16916. +CONFIG_NET_VENDOR_ARC=y
  16917. +CONFIG_ARC_EMAC=m
  16918. +
  16919. +CONFIG_NET_VENDOR_ATHEROS=y
  16920. +CONFIG_ALX=m
  16921. +CONFIG_ATL2=m
  16922. +CONFIG_ATL1=m
  16923. +CONFIG_ATL1C=m
  16924. +CONFIG_ATL1E=m
  16925. +CONFIG_NET_CADENCE=y
  16926. +CONFIG_ARM_AT91_ETHER=m
  16927. +CONFIG_MACB=m
  16928. +
  16929. +CONFIG_NET_VENDOR_BROCADE=y
  16930. +CONFIG_BNA=m
  16931. +CONFIG_NET_CALXEDA_XGMAC=m
  16932. +
  16933. +CONFIG_NET_VENDOR_CHELSIO=y
  16934. +CONFIG_CHELSIO_T1=m
  16935. +CONFIG_CHELSIO_T1_1G=y
  16936. +CONFIG_CHELSIO_T3=m
  16937. +CONFIG_CHELSIO_T4=m
  16938. +CONFIG_CHELSIO_T4VF=m
  16939. +
  16940. +CONFIG_NET_VENDOR_CISCO=y
  16941. +CONFIG_ENIC=m
  16942. +
  16943. +CONFIG_NET_VENDOR_DEC=y
  16944. +#
  16945. +# Tulip family network device support
  16946. +#
  16947. +CONFIG_NET_TULIP=y
  16948. +CONFIG_DE2104X=m
  16949. +CONFIG_DE2104X_DSL=0
  16950. +CONFIG_TULIP=m
  16951. +# CONFIG_TULIP_NAPI is not set
  16952. +# CONFIG_TULIP_MWI is not set
  16953. +CONFIG_TULIP_MMIO=y
  16954. +# CONFIG_NI5010 is not set
  16955. +CONFIG_DE4X5=m
  16956. +CONFIG_WINBOND_840=m
  16957. +CONFIG_DM9102=m
  16958. +CONFIG_PCMCIA_XIRCOM=m
  16959. +CONFIG_ULI526X=m
  16960. +
  16961. +CONFIG_NET_VENDOR_DLINK=y
  16962. +CONFIG_DE600=m
  16963. +CONFIG_DE620=m
  16964. +CONFIG_DL2K=m
  16965. +CONFIG_SUNDANCE=m
  16966. +# CONFIG_SUNDANCE_MMIO is not set
  16967. +
  16968. +CONFIG_NET_VENDOR_EMULEX=y
  16969. +CONFIG_BE2NET=m
  16970. +
  16971. +CONFIG_NET_VENDOR_EXAR=y
  16972. +CONFIG_S2IO=m
  16973. +CONFIG_VXGE=m
  16974. +# CONFIG_VXGE_DEBUG_TRACE_ALL is not set
  16975. +
  16976. +# CONFIG_NET_VENDOR_FARADAY is not set
  16977. +# CONFIG_NET_VENDOR_FUJITSU is not set
  16978. +# CONFIG_NET_VENDOR_HP is not set
  16979. +CONFIG_NET_VENDOR_INTEL=y
  16980. +CONFIG_E100=m
  16981. +CONFIG_E1000=m
  16982. +CONFIG_E1000E=m
  16983. +CONFIG_IGB=m
  16984. +CONFIG_IGB_HWMON=y
  16985. +CONFIG_IGB_DCA=y
  16986. +CONFIG_IGB_PTP=y
  16987. +CONFIG_IGBVF=m
  16988. +CONFIG_IXGB=m
  16989. +CONFIG_IXGBEVF=m
  16990. +CONFIG_IXGBE=m
  16991. +CONFIG_IXGBE_DCA=y
  16992. +CONFIG_IXGBE_DCB=y
  16993. +CONFIG_IXGBE_HWMON=y
  16994. +CONFIG_IXGBE_PTP=y
  16995. +CONFIG_I40E=m
  16996. +# CONFIG_I40E_VXLAN is not set
  16997. +# CONFIG_I40E_DCB is not set
  16998. +# CONFIG_I40EVF is not set
  16999. +
  17000. +
  17001. +# CONFIG_NET_VENDOR_I825XX is not set
  17002. +CONFIG_NET_VENDOR_MARVELL=y
  17003. +CONFIG_MVMDIO=m
  17004. +CONFIG_SKGE=m
  17005. +# CONFIG_SKGE_DEBUG is not set
  17006. +CONFIG_SKGE_GENESIS=y
  17007. +CONFIG_SKY2=m
  17008. +# CONFIG_SKY2_DEBUG is not set
  17009. +
  17010. +CONFIG_NET_VENDOR_MICREL=y
  17011. +CONFIG_KSZ884X_PCI=m
  17012. +# CONFIG_KS8842 is not set
  17013. +# CONFIG_KS8851_MLL is not set
  17014. +
  17015. +CONFIG_NET_VENDOR_MYRI=y
  17016. +CONFIG_MYRI10GE=m
  17017. +CONFIG_MYRI10GE_DCA=y
  17018. +
  17019. +CONFIG_NATSEMI=m
  17020. +CONFIG_NS83820=m
  17021. +
  17022. +CONFIG_PCMCIA_AXNET=m
  17023. +CONFIG_NE2K_PCI=m
  17024. +CONFIG_NE3210=m
  17025. +CONFIG_PCMCIA_PCNET=m
  17026. +
  17027. +CONFIG_NET_VENDOR_NVIDIA=y
  17028. +CONFIG_FORCEDETH=m
  17029. +
  17030. +CONFIG_NET_VENDOR_OKI=y
  17031. +# CONFIG_PCH_GBE is not set
  17032. +# CONFIG_PCH_PTP is not set
  17033. +
  17034. +CONFIG_NET_PACKET_ENGINE=y
  17035. +CONFIG_HAMACHI=m
  17036. +CONFIG_YELLOWFIN=m
  17037. +
  17038. +CONFIG_NET_VENDOR_QLOGIC=y
  17039. +CONFIG_QLA3XXX=m
  17040. +CONFIG_QLCNIC=m
  17041. +CONFIG_QLCNIC_SRIOV=y
  17042. +CONFIG_QLCNIC_DCB=y
  17043. +CONFIG_QLGE=m
  17044. +CONFIG_NETXEN_NIC=m
  17045. +
  17046. +CONFIG_NET_VENDOR_REALTEK=y
  17047. +CONFIG_ATP=m
  17048. +CONFIG_8139CP=m
  17049. +CONFIG_8139TOO=m
  17050. +# CONFIG_8139TOO_PIO is not set
  17051. +# CONFIG_8139TOO_TUNE_TWISTER is not set
  17052. +CONFIG_8139TOO_8129=y
  17053. +# CONFIG_8139_OLD_RX_RESET is not set
  17054. +CONFIG_R8169=m
  17055. +
  17056. +
  17057. +CONFIG_NET_VENDOR_RDC=y
  17058. +CONFIG_R6040=m
  17059. +
  17060. +
  17061. +CONFIG_NET_VENDOR_SILAN=y
  17062. +CONFIG_SC92031=m
  17063. +
  17064. +CONFIG_NET_VENDOR_SIS=y
  17065. +CONFIG_SIS900=m
  17066. +CONFIG_SIS190=m
  17067. +
  17068. +CONFIG_PCMCIA_SMC91C92=m
  17069. +CONFIG_EPIC100=m
  17070. +CONFIG_SMSC9420=m
  17071. +
  17072. +# CONFIG_STMMAC_PLATFORM is not set
  17073. +# CONFIG_STMMAC_PCI is not set
  17074. +# CONFIG_STMMAC_DA is not set
  17075. +# CONFIG_STMMAC_DUAL_MAC is not set
  17076. +# CONFIG_STMMAC_TIMER is not set
  17077. +# CONFIG_STMMAC_DEBUG_FS is not set
  17078. +
  17079. +CONFIG_NET_VENDOR_SUN=y
  17080. +CONFIG_HAPPYMEAL=m
  17081. +CONFIG_SUNGEM=m
  17082. +CONFIG_CASSINI=m
  17083. +CONFIG_NIU=m
  17084. +
  17085. +CONFIG_NET_VENDOR_TEHUTI=y
  17086. +CONFIG_TEHUTI=m
  17087. +
  17088. +CONFIG_NET_VENDOR_TI=y
  17089. +CONFIG_TLAN=m
  17090. +
  17091. +CONFIG_VIA_RHINE=m
  17092. +CONFIG_VIA_RHINE_MMIO=y
  17093. +
  17094. +CONFIG_WIZNET_W5100=m
  17095. +CONFIG_WIZNET_W5300=m
  17096. +CONFIG_NET_VENDOR_XIRCOM=y
  17097. +CONFIG_PCMCIA_XIRC2PS=m
  17098. +
  17099. +CONFIG_AMD_PHY=m
  17100. +CONFIG_BROADCOM_PHY=m
  17101. +CONFIG_BCM87XX_PHY=m
  17102. +CONFIG_CICADA_PHY=m
  17103. +CONFIG_DAVICOM_PHY=m
  17104. +CONFIG_DP83640_PHY=m
  17105. +CONFIG_FIXED_PHY=y
  17106. +CONFIG_MDIO_BITBANG=m
  17107. +CONFIG_NATIONAL_PHY=m
  17108. +CONFIG_ICPLUS_PHY=m
  17109. +CONFIG_BCM63XX_PHY=m
  17110. +CONFIG_LSI_ET1011C_PHY=m
  17111. +CONFIG_LXT_PHY=m
  17112. +CONFIG_MARVELL_PHY=m
  17113. +CONFIG_QSEMI_PHY=m
  17114. +CONFIG_REALTEK_PHY=m
  17115. +CONFIG_SMSC_PHY=m
  17116. +CONFIG_STE10XP=m
  17117. +CONFIG_VITESSE_PHY=m
  17118. +CONFIG_MICREL_PHY=m
  17119. +
  17120. +CONFIG_MII=m
  17121. +CONFIG_NET_CORE=y
  17122. +CONFIG_NET_VENDOR_3COM=y
  17123. +CONFIG_VORTEX=m
  17124. +CONFIG_TYPHOON=m
  17125. +CONFIG_DNET=m
  17126. +
  17127. +
  17128. +CONFIG_LNE390=m
  17129. +CONFIG_ES3210=m
  17130. +CONFIG_NET_PCI=y
  17131. +CONFIG_B44=m
  17132. +CONFIG_B44_PCI=y
  17133. +CONFIG_BNX2=m
  17134. +CONFIG_BNX2X=m
  17135. +CONFIG_BNX2X_SRIOV=y
  17136. +CONFIG_CNIC=m
  17137. +CONFIG_FEALNX=m
  17138. +CONFIG_NET_POCKET=y
  17139. +
  17140. +#
  17141. +# Ethernet (1000 Mbit)
  17142. +#
  17143. +CONFIG_TIGON3=m
  17144. +CONFIG_JME=m
  17145. +
  17146. +#
  17147. +# Ethernet (10000 Mbit)
  17148. +#
  17149. +# CONFIG_IP1000 is not set
  17150. +# CONFIG_MLX4_EN is not set
  17151. +# CONFIG_SFC is not set
  17152. +
  17153. +# CONFIG_FDDI is not set
  17154. +# CONFIG_DEFXX is not set
  17155. +# CONFIG_SKFP is not set
  17156. +# CONFIG_HIPPI is not set
  17157. +# CONFIG_PLIP is not set
  17158. +CONFIG_PPP=m
  17159. +CONFIG_PPP_MULTILINK=y
  17160. +CONFIG_PPP_FILTER=y
  17161. +CONFIG_PPP_ASYNC=m
  17162. +CONFIG_PPP_SYNC_TTY=m
  17163. +CONFIG_PPP_DEFLATE=m
  17164. +CONFIG_IPPP_FILTER=y
  17165. +CONFIG_PPP_BSDCOMP=y
  17166. +CONFIG_PPPOE=m
  17167. +CONFIG_PPP_MPPE=m
  17168. +CONFIG_SLIP=m
  17169. +CONFIG_SLIP_COMPRESSED=y
  17170. +CONFIG_SLIP_SMART=y
  17171. +# CONFIG_SLIP_MODE_SLIP6 is not set
  17172. +
  17173. +#
  17174. +# Wireless LAN
  17175. +#
  17176. +#
  17177. +# CONFIG_STRIP is not set
  17178. +# CONFIG_PCMCIA_RAYCS is not set
  17179. +
  17180. +CONFIG_CFG80211_WEXT=y
  17181. +# CONFIG_CFG80211_REG_DEBUG is not set
  17182. +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
  17183. +CONFIG_CFG80211_DEFAULT_PS=y
  17184. +CONFIG_NL80211=y
  17185. +# CONFIG_NL80211_TESTMODE is not set
  17186. +# CONFIG_WIRELESS_EXT_SYSFS is not set
  17187. +CONFIG_LIB80211=m
  17188. +CONFIG_LIB80211_CRYPT_WEP=m
  17189. +CONFIG_LIB80211_CRYPT_CCMP=m
  17190. +CONFIG_LIB80211_CRYPT_TKIP=m
  17191. +# CONFIG_LIB80211_DEBUG is not set
  17192. +
  17193. +CONFIG_MAC80211=m
  17194. +CONFIG_MAC80211_RC_MINSTREL=y
  17195. +# CONFIG_MAC80211_RC_DEFAULT_PID is not set
  17196. +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
  17197. +CONFIG_MAC80211_RC_DEFAULT="minstrel"
  17198. +CONFIG_MAC80211_MESH=y
  17199. +CONFIG_MAC80211_LEDS=y
  17200. +# CONFIG_MAC80211_DEBUG_MENU is not set
  17201. +
  17202. +# CONFIG_WIMAX is not set
  17203. +
  17204. +# CONFIG_ADM8211 is not set
  17205. +CONFIG_ATH_COMMON=m
  17206. +CONFIG_ATH_CARDS=m
  17207. +CONFIG_ATH5K=m
  17208. +CONFIG_ATH5K_DEBUG=y
  17209. +# CONFIG_ATH5K_TRACER is not set
  17210. +CONFIG_ATH6KL=m
  17211. +CONFIG_ATH6KL_DEBUG=y
  17212. +CONFIG_ATH6KL_SDIO=m
  17213. +CONFIG_ATH6KL_USB=m
  17214. +# CONFIG_ATH6KL_TRACING is not set
  17215. +CONFIG_AR5523=m
  17216. +CONFIG_ATH9K=m
  17217. +CONFIG_ATH9K_PCI=y
  17218. +CONFIG_ATH9K_AHB=y
  17219. +# CONFIG_ATH9K_DEBUG is not set
  17220. +# CONFIG_ATH9K_MAC_DEBUG is not set
  17221. +CONFIG_ATH9K_HTC=m
  17222. +CONFIG_ATH9K_BTCOEX_SUPPORT=y
  17223. +# CONFIG_ATH9K_LEGACY_RATE_CONTROL is not set
  17224. +# CONFIG_ATH9K_WOW is not set
  17225. +#
  17226. +CONFIG_ATH10K=m
  17227. +CONFIG_ATH10K_PCI=m
  17228. +# CONFIG_ATH10K_DEBUG is not set
  17229. +# CONFIG_ATH10K_TRACING is not set
  17230. +CONFIG_ATH10K_DEBUGFS=y
  17231. +CONFIG_WCN36XX=m
  17232. +# CONFIG_WCN36XX_DEBUGFS is not set
  17233. +CONFIG_WIL6210=m
  17234. +CONFIG_WIL6210_ISR_COR=y
  17235. +# CONFIG_WIL6210_TRACING is not set
  17236. +CONFIG_CARL9170=m
  17237. +CONFIG_CARL9170_LEDS=y
  17238. +# CONFIG_CARL9170_HWRNG is not set
  17239. +CONFIG_AT76C50X_USB=m
  17240. +# CONFIG_AIRO is not set
  17241. +# CONFIG_AIRO_CS is not set
  17242. +# CONFIG_ATMEL is not set
  17243. +CONFIG_B43=m
  17244. +CONFIG_B43_PCMCIA=y
  17245. +CONFIG_B43_SDIO=y
  17246. +CONFIG_B43_BCMA=y
  17247. +# CONFIG_B43_BCMA_EXTRA is not set
  17248. +CONFIG_B43_BCMA_PIO=y
  17249. +# CONFIG_B43_DEBUG is not set
  17250. +CONFIG_B43_PHY_LP=y
  17251. +CONFIG_B43_PHY_N=y
  17252. +CONFIG_B43_PHY_HT=y
  17253. +# CONFIG_B43_FORCE_PIO is not set
  17254. +CONFIG_B43LEGACY=m
  17255. +# CONFIG_B43LEGACY_DEBUG is not set
  17256. +CONFIG_B43LEGACY_DMA=y
  17257. +CONFIG_B43LEGACY_PIO=y
  17258. +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
  17259. +# CONFIG_B43LEGACY_DMA_MODE is not set
  17260. +# CONFIG_B43LEGACY_PIO_MODE is not set
  17261. +CONFIG_BRCMSMAC=m
  17262. +CONFIG_BRCMFMAC_SDIO_OOB=y
  17263. +CONFIG_BRCMFMAC_USB=y
  17264. +# CONFIG_BRCM_TRACING is not set
  17265. +# CONFIG_BRCMISCAN is not set
  17266. +# CONFIG_BRCMDBG is not set
  17267. +CONFIG_HERMES=m
  17268. +CONFIG_HERMES_CACHE_FW_ON_INIT=y
  17269. +# CONFIG_HERMES_PRISM is not set
  17270. +CONFIG_NORTEL_HERMES=m
  17271. +CONFIG_PCI_HERMES=m
  17272. +CONFIG_PLX_HERMES=m
  17273. +CONFIG_PCMCIA_HERMES=m
  17274. +CONFIG_ORINOCO_USB=m
  17275. +# CONFIG_TMD_HERMES is not set
  17276. +# CONFIG_PCMCIA_SPECTRUM is not set
  17277. +CONFIG_CW1200=m
  17278. +CONFIG_CW1200_WLAN_SDIO=m
  17279. +CONFIG_CW1200_WLAN_SPI=m
  17280. +# CONFIG_HOSTAP is not set
  17281. +# CONFIG_IPW2100 is not set
  17282. +# CONFIG_IPW2200 is not set
  17283. +# CONFIG_IPW2100_DEBUG is not set
  17284. +# CONFIG_IPW2200_DEBUG is not set
  17285. +# CONFIG_LIBIPW_DEBUG is not set
  17286. +CONFIG_LIBERTAS=m
  17287. +CONFIG_LIBERTAS_USB=m
  17288. +CONFIG_LIBERTAS_CS=m
  17289. +CONFIG_LIBERTAS_SDIO=m
  17290. +# CONFIG_LIBERTAS_DEBUG is not set
  17291. +# CONFIG_LIBERTAS_THINFIRM is not set
  17292. +CONFIG_LIBERTAS_MESH=y
  17293. +CONFIG_IWLWIFI=m
  17294. +CONFIG_IWLDVM=m
  17295. +CONFIG_IWLMVM=m
  17296. +CONFIG_IWLWIFI_DEBUG=y
  17297. +CONFIG_IWLWIFI_DEVICE_SVTOOL=y
  17298. +# CONFIG_IWLWIFI_EXPERIMENTAL_MFP is not set
  17299. +CONFIG_IWLWIFI_UCODE16=y
  17300. +# CONFIG_IWLWIFI_P2P is not set
  17301. +CONFIG_IWLEGACY=m
  17302. +CONFIG_IWLEGACY_DEBUG=y
  17303. +# CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING is not set
  17304. +CONFIG_IWL4965=y
  17305. +CONFIG_IWL3945=m
  17306. +# CONFIG_IWM is not set
  17307. +# CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE is not set
  17308. +CONFIG_MAC80211_HWSIM=m
  17309. +CONFIG_P54_COMMON=m
  17310. +CONFIG_P54_USB=m
  17311. +CONFIG_P54_PCI=m
  17312. +CONFIG_MWL8K=m
  17313. +# CONFIG_PRISM54 is not set
  17314. +# CONFIG_PCMCIA_WL3501 is not set
  17315. +CONFIG_RT2X00=m
  17316. +# CONFIG_RT2X00_DEBUG is not set
  17317. +CONFIG_RT2400PCI=m
  17318. +CONFIG_RT2500PCI=m
  17319. +CONFIG_RT61PCI=m
  17320. +CONFIG_RT2500USB=m
  17321. +CONFIG_RT2800USB=m
  17322. +CONFIG_RT2800USB_RT33XX=y
  17323. +CONFIG_RT2800USB_RT35XX=y
  17324. +CONFIG_RT2800USB_RT3573=y
  17325. +CONFIG_RT2800USB_RT53XX=y
  17326. +CONFIG_RT2800USB_RT55XX=y
  17327. +CONFIG_RT2800USB_UNKNOWN=y
  17328. +CONFIG_RT2800PCI=m
  17329. +CONFIG_RT2800PCI_RT3290=y
  17330. +CONFIG_RT2800PCI_RT33XX=y
  17331. +CONFIG_RT2800PCI_RT35XX=y
  17332. +CONFIG_RT2800PCI_RT53XX=y
  17333. +CONFIG_RT73USB=m
  17334. +CONFIG_RTL8180=m
  17335. +CONFIG_RTL8187=m
  17336. +# CONFIG_USB_ZD1201 is not set
  17337. +# CONFIG_USB_NET_SR9800 is not set
  17338. +CONFIG_USB_NET_RNDIS_WLAN=m
  17339. +CONFIG_USB_NET_KALMIA=m
  17340. +CONFIG_USB_NET_QMI_WWAN=m
  17341. +CONFIG_USB_NET_SMSC75XX=m
  17342. +# CONFIG_WL_TI is not set
  17343. +CONFIG_ZD1211RW=m
  17344. +# CONFIG_ZD1211RW_DEBUG is not set
  17345. +
  17346. +CONFIG_WL12XX=m
  17347. +CONFIG_WL12XX_SPI=m
  17348. +CONFIG_WL12XX_SDIO=m
  17349. +
  17350. +CONFIG_WL1251=m
  17351. +CONFIG_WL1251_SPI=m
  17352. +CONFIG_WL1251_SDIO=m
  17353. +
  17354. +CONFIG_RTL_CARDS=m
  17355. +CONFIG_RTLWIFI=m
  17356. +CONFIG_RTL8192CE=m
  17357. +CONFIG_RTL8192SE=m
  17358. +CONFIG_RTL8192CU=m
  17359. +CONFIG_RTL8192DE=m
  17360. +CONFIG_RTL8723AE=m
  17361. +CONFIG_RTL8188EE=m
  17362. +
  17363. +CONFIG_MWIFIEX=m
  17364. +CONFIG_MWIFIEX_SDIO=m
  17365. +CONFIG_MWIFIEX_PCIE=m
  17366. +CONFIG_MWIFIEX_USB=m
  17367. +
  17368. +#
  17369. +# Token Ring devices
  17370. +#
  17371. +# CONFIG_TR is not set
  17372. +
  17373. +CONFIG_NET_FC=y
  17374. +
  17375. +#
  17376. +# Wan interfaces
  17377. +#
  17378. +# CONFIG_WAN is not set
  17379. +
  17380. +#
  17381. +# PCMCIA network device support
  17382. +#
  17383. +CONFIG_NET_PCMCIA=y
  17384. +CONFIG_PCMCIA_3C589=m
  17385. +CONFIG_PCMCIA_3C574=m
  17386. +CONFIG_PCMCIA_FMVJ18X=m
  17387. +
  17388. +#
  17389. +# Amateur Radio support
  17390. +#
  17391. +CONFIG_HAMRADIO=y
  17392. +CONFIG_AX25=m
  17393. +CONFIG_AX25_DAMA_SLAVE=y
  17394. +
  17395. +# CONFIG_CAN is not set
  17396. +
  17397. +CONFIG_NETROM=m
  17398. +CONFIG_ROSE=m
  17399. +CONFIG_MKISS=m
  17400. +CONFIG_6PACK=m
  17401. +CONFIG_BPQETHER=m
  17402. +CONFIG_BAYCOM_SER_FDX=m
  17403. +CONFIG_BAYCOM_SER_HDX=m
  17404. +CONFIG_BAYCOM_PAR=m
  17405. +CONFIG_BAYCOM_EPP=m
  17406. +CONFIG_YAM=m
  17407. +
  17408. +CONFIG_NFC=m
  17409. +CONFIG_NFC_DIGITAL=m
  17410. +CONFIG_NFC_NCI=m
  17411. +CONFIG_NFC_HCI=m
  17412. +CONFIG_NFC_SHDLC=y
  17413. +CONFIG_NFC_LLCP=y
  17414. +CONFIG_NFC_SIM=m
  17415. +CONFIG_NFC_MRVL=m
  17416. +CONFIG_NFC_MRVL_USB=m
  17417. +
  17418. +#
  17419. +# Near Field Communication (NFC) devices
  17420. +#
  17421. +CONFIG_NFC_PORT100=m
  17422. +CONFIG_NFC_PN544=m
  17423. +CONFIG_NFC_PN544_I2C=m
  17424. +CONFIG_NFC_PN533=m
  17425. +CONFIG_NFC_MICROREAD=m
  17426. +CONFIG_NFC_MICROREAD_I2C=m
  17427. +
  17428. +#
  17429. +# IrDA (infrared) support
  17430. +#
  17431. +CONFIG_IRDA=m
  17432. +# CONFIG_IRDA_DEBUG is not set
  17433. +CONFIG_IRLAN=m
  17434. +CONFIG_IRNET=m
  17435. +CONFIG_IRCOMM=m
  17436. +# CONFIG_IRDA_ULTRA is not set
  17437. +CONFIG_IRDA_CACHE_LAST_LSAP=y
  17438. +CONFIG_IRDA_FAST_RR=y
  17439. +CONFIG_IRTTY_SIR=m
  17440. +CONFIG_DONGLE=y
  17441. +CONFIG_ACTISYS_DONGLE=m
  17442. +CONFIG_ACT200L_DONGLE=m
  17443. +CONFIG_ESI_DONGLE=m
  17444. +CONFIG_GIRBIL_DONGLE=m
  17445. +CONFIG_KINGSUN_DONGLE=m
  17446. +CONFIG_KSDAZZLE_DONGLE=m
  17447. +CONFIG_KS959_DONGLE=m
  17448. +CONFIG_LITELINK_DONGLE=m
  17449. +CONFIG_MA600_DONGLE=m
  17450. +CONFIG_MCP2120_DONGLE=m
  17451. +CONFIG_OLD_BELKIN_DONGLE=m
  17452. +CONFIG_TEKRAM_DONGLE=m
  17453. +CONFIG_TOIM3232_DONGLE=m
  17454. +
  17455. +CONFIG_ALI_FIR=m
  17456. +CONFIG_MCS_FIR=m
  17457. +CONFIG_NSC_FIR=m
  17458. +CONFIG_SIGMATEL_FIR=m
  17459. +CONFIG_SMC_IRCC_FIR=m
  17460. +# CONFIG_TOSHIBA_FIR is not set
  17461. +CONFIG_USB_IRDA=m
  17462. +CONFIG_VLSI_FIR=m
  17463. +CONFIG_VIA_FIR=m
  17464. +CONFIG_WINBOND_FIR=m
  17465. +
  17466. +#
  17467. +# Bluetooth support
  17468. +#
  17469. +CONFIG_BT=m
  17470. +CONFIG_BT_L2CAP=y
  17471. +CONFIG_BT_SCO=y
  17472. +CONFIG_BT_CMTP=m
  17473. +CONFIG_BT_RFCOMM=m
  17474. +CONFIG_BT_RFCOMM_TTY=y
  17475. +CONFIG_BT_BNEP=m
  17476. +CONFIG_BT_BNEP_MC_FILTER=y
  17477. +CONFIG_BT_BNEP_PROTO_FILTER=y
  17478. +CONFIG_BT_HIDP=m
  17479. +
  17480. +#
  17481. +# Bluetooth device drivers
  17482. +#
  17483. +CONFIG_BT_HCIBTUSB=m
  17484. +# Disable the BT_HCIUSB driver.
  17485. +# It sucks more power than BT_HCIBTUSB which has the same functionality.
  17486. +CONFIG_BT_HCIUART=m
  17487. +CONFIG_BT_HCIUART_H4=y
  17488. +CONFIG_BT_HCIUART_BCSP=y
  17489. +CONFIG_BT_HCIUART_ATH3K=y
  17490. +CONFIG_BT_HCIUART_3WIRE=y
  17491. +CONFIG_BT_HCIDTL1=m
  17492. +CONFIG_BT_HCIBT3C=m
  17493. +CONFIG_BT_HCIBLUECARD=m
  17494. +CONFIG_BT_HCIBTUART=m
  17495. +CONFIG_BT_HCIVHCI=m
  17496. +CONFIG_BT_HCIBCM203X=m
  17497. +CONFIG_BT_HCIBFUSB=m
  17498. +CONFIG_BT_HCIBPA10X=m
  17499. +CONFIG_BT_HCIBTSDIO=m
  17500. +CONFIG_BT_HCIUART_LL=y
  17501. +CONFIG_BT_MRVL=m
  17502. +CONFIG_BT_MRVL_SDIO=m
  17503. +CONFIG_BT_ATH3K=m
  17504. +CONFIG_BT_WILINK=m
  17505. +
  17506. +#
  17507. +# ISDN subsystem
  17508. +#
  17509. +CONFIG_ISDN=y
  17510. +CONFIG_MISDN=m
  17511. +CONFIG_MISDN_DSP=m
  17512. +CONFIG_MISDN_L1OIP=m
  17513. +CONFIG_MISDN_AVMFRITZ=m
  17514. +CONFIG_MISDN_SPEEDFAX=m
  17515. +CONFIG_MISDN_INFINEON=m
  17516. +CONFIG_MISDN_W6692=m
  17517. +CONFIG_MISDN_NETJET=m
  17518. +
  17519. +#
  17520. +# mISDN hardware drivers
  17521. +#
  17522. +CONFIG_MISDN_HFCPCI=m
  17523. +CONFIG_MISDN_HFCMULTI=m
  17524. +CONFIG_ISDN_I4L=m
  17525. +CONFIG_ISDN_DRV_AVMB1_B1PCI=m
  17526. +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
  17527. +CONFIG_ISDN_DRV_AVMB1_T1PCI=m
  17528. +CONFIG_ISDN_DRV_AVMB1_C4=m
  17529. +
  17530. +CONFIG_MISDN_HFCUSB=m
  17531. +
  17532. +CONFIG_ISDN_PPP=y
  17533. +CONFIG_ISDN_PPP_VJ=y
  17534. +CONFIG_ISDN_MPP=y
  17535. +# CONFIG_ISDN_PPP_BSDCOMP is not set
  17536. +CONFIG_ISDN_TTY_FAX=y
  17537. +CONFIG_DE_AOC=y
  17538. +
  17539. +CONFIG_ISDN_AUDIO=y
  17540. +
  17541. +CONFIG_ISDN_DRV_HISAX=m
  17542. +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
  17543. +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
  17544. +
  17545. +CONFIG_ISDN_CAPI_CAPIDRV=m
  17546. +CONFIG_ISDN_DIVERSION=m
  17547. +
  17548. +CONFIG_HISAX_EURO=y
  17549. +CONFIG_HISAX_1TR6=y
  17550. +CONFIG_HISAX_NI1=y
  17551. +CONFIG_HISAX_MAX_CARDS=8
  17552. +CONFIG_HISAX_16_3=y
  17553. +CONFIG_HISAX_TELESPCI=y
  17554. +CONFIG_HISAX_S0BOX=y
  17555. +CONFIG_HISAX_FRITZPCI=y
  17556. +CONFIG_HISAX_AVM_A1_PCMCIA=y
  17557. +CONFIG_HISAX_ELSA=y
  17558. +CONFIG_HISAX_DIEHLDIVA=y
  17559. +CONFIG_HISAX_SEDLBAUER=y
  17560. +CONFIG_HISAX_NETJET=y
  17561. +CONFIG_HISAX_NETJET_U=y
  17562. +CONFIG_HISAX_NICCY=y
  17563. +CONFIG_HISAX_BKM_A4T=y
  17564. +CONFIG_HISAX_SCT_QUADRO=y
  17565. +CONFIG_HISAX_GAZEL=y
  17566. +CONFIG_HISAX_HFC_PCI=y
  17567. +CONFIG_HISAX_W6692=y
  17568. +CONFIG_HISAX_HFC_SX=y
  17569. +CONFIG_HISAX_ENTERNOW_PCI=y
  17570. +# CONFIG_HISAX_DEBUG is not set
  17571. +CONFIG_HISAX_AVM_A1_CS=m
  17572. +CONFIG_HISAX_ST5481=m
  17573. +# CONFIG_HISAX_HFCUSB is not set
  17574. +CONFIG_HISAX_FRITZ_PCIPNP=m
  17575. +CONFIG_HISAX_NO_SENDCOMPLETE=y
  17576. +CONFIG_HISAX_NO_LLC=y
  17577. +CONFIG_HISAX_NO_KEYPAD=y
  17578. +CONFIG_HISAX_SEDLBAUER_CS=m
  17579. +CONFIG_HISAX_ELSA_CS=m
  17580. +CONFIG_HISAX_TELES_CS=m
  17581. +CONFIG_HISAX_HFC4S8S=m
  17582. +
  17583. +CONFIG_ISDN_DRV_LOOP=m
  17584. +CONFIG_HYSDN=m
  17585. +CONFIG_HYSDN_CAPI=y
  17586. +
  17587. +
  17588. +#
  17589. +# CAPI subsystem
  17590. +#
  17591. +CONFIG_ISDN_CAPI=m
  17592. +# CONFIG_CAPI_TRACE is not set
  17593. +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
  17594. +CONFIG_ISDN_CAPI_MIDDLEWARE=y
  17595. +CONFIG_ISDN_CAPI_CAPI20=m
  17596. +
  17597. +#
  17598. +# CAPI hardware drivers
  17599. +#
  17600. +
  17601. +#
  17602. +# Active AVM cards
  17603. +#
  17604. +CONFIG_CAPI_AVM=y
  17605. +
  17606. +#
  17607. +# Active Eicon DIVA Server cards
  17608. +#
  17609. +# CONFIG_CAPI_EICON is not set
  17610. +CONFIG_ISDN_DIVAS=m
  17611. +CONFIG_ISDN_DIVAS_BRIPCI=y
  17612. +CONFIG_ISDN_DIVAS_PRIPCI=y
  17613. +CONFIG_ISDN_DIVAS_DIVACAPI=m
  17614. +CONFIG_ISDN_DIVAS_USERIDI=m
  17615. +CONFIG_ISDN_DIVAS_MAINT=m
  17616. +
  17617. +CONFIG_ISDN_DRV_GIGASET=m
  17618. +CONFIG_GIGASET_CAPI=y
  17619. +CONFIG_GIGASET_BASE=m
  17620. +CONFIG_GIGASET_M101=m
  17621. +CONFIG_GIGASET_M105=m
  17622. +# CONFIG_GIGASET_DEBUG is not set
  17623. +
  17624. +#
  17625. +# Telephony Support
  17626. +#
  17627. +# CONFIG_PHONE is not set
  17628. +
  17629. +#
  17630. +# Input device support
  17631. +#
  17632. +CONFIG_INPUT=y
  17633. +CONFIG_INPUT_FF_MEMLESS=m
  17634. +
  17635. +#
  17636. +# Userland interfaces
  17637. +#
  17638. +CONFIG_INPUT_MOUSEDEV=y
  17639. +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
  17640. +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
  17641. +CONFIG_INPUT_JOYDEV=m
  17642. +# CONFIG_INPUT_MATRIXKMAP is not set
  17643. +
  17644. +CONFIG_INPUT_TABLET=y
  17645. +CONFIG_TABLET_USB_ACECAD=m
  17646. +CONFIG_TABLET_USB_AIPTEK=m
  17647. +CONFIG_TABLET_USB_GTCO=m
  17648. +CONFIG_TABLET_USB_HANWANG=m
  17649. +CONFIG_TABLET_USB_KBTAB=m
  17650. +CONFIG_TABLET_USB_WACOM=m
  17651. +
  17652. +CONFIG_INPUT_POWERMATE=m
  17653. +CONFIG_INPUT_YEALINK=m
  17654. +CONFIG_INPUT_CM109=m
  17655. +CONFIG_INPUT_POLLDEV=m
  17656. +CONFIG_INPUT_SPARSEKMAP=m
  17657. +# CONFIG_INPUT_ADXL34X is not set
  17658. +# CONFIG_INPUT_BMA150 is not set
  17659. +# CONFIG_INPUT_IMS_PCU is not set
  17660. +CONFIG_INPUT_CMA3000=m
  17661. +CONFIG_INPUT_CMA3000_I2C=m
  17662. +CONFIG_INPUT_IDEAPAD_SLIDEBAR=m
  17663. +
  17664. +#
  17665. +# Input I/O drivers
  17666. +#
  17667. +CONFIG_GAMEPORT=m
  17668. +CONFIG_GAMEPORT_NS558=m
  17669. +CONFIG_GAMEPORT_L4=m
  17670. +CONFIG_GAMEPORT_EMU10K1=m
  17671. +CONFIG_GAMEPORT_FM801=m
  17672. +CONFIG_SERIO=y
  17673. +CONFIG_SERIO_I8042=y
  17674. +CONFIG_SERIO_RAW=m
  17675. +CONFIG_SERIO_ALTERA_PS2=m
  17676. +# CONFIG_SERIO_PS2MULT is not set
  17677. +CONFIG_SERIO_ARC_PS2=m
  17678. +# CONFIG_SERIO_APBPS2 is not set
  17679. +
  17680. +# CONFIG_SERIO_CT82C710 is not set
  17681. +# CONFIG_SERIO_OLPC_APSP is not set
  17682. +# CONFIG_SERIO_PARKBD is not set
  17683. +# CONFIG_SERIO_PCIPS2 is not set
  17684. +# CONFIG_SERIO_LIBPS2 is not set
  17685. +
  17686. +#
  17687. +# Input Device Drivers
  17688. +#
  17689. +CONFIG_INPUT_KEYBOARD=y
  17690. +# CONFIG_KEYBOARD_SUNKBD is not set
  17691. +# CONFIG_KEYBOARD_SH_KEYSC is not set
  17692. +# CONFIG_KEYBOARD_XTKBD is not set
  17693. +# CONFIG_KEYBOARD_MATRIX is not set
  17694. +# CONFIG_KEYBOARD_NEWTON is not set
  17695. +# CONFIG_KEYBOARD_STOWAWAY is not set
  17696. +# CONFIG_KEYBOARD_LKKBD is not set
  17697. +# CONFIG_KEYBOARD_LM8323 is not set
  17698. +# CONFIG_KEYBOARD_LM8333 is not set
  17699. +# CONFIG_KEYBOARD_MAX7359 is not set
  17700. +# CONFIG_KEYBOARD_ADP5589 is not set
  17701. +# CONFIG_KEYBOARD_MPR121 is not set
  17702. +# CONFIG_KEYBOARD_QT1070 is not set
  17703. +# CONFIG_KEYBOARD_MCS is not set
  17704. +# CONFIG_KEYBOARD_OPENCORES is not set
  17705. +# CONFIG_KEYBOARD_SAMSUNG is not set
  17706. +# CONFIG_KEYBOARD_QT2160 is not set
  17707. +# CONFIG_KEYBOARD_TCA6416 is not set
  17708. +# CONFIG_KEYBOARD_TCA8418 is not set
  17709. +# CONFIG_KEYBOARD_OMAP4 is not set
  17710. +CONFIG_INPUT_MOUSE=y
  17711. +# CONFIG_MOUSE_PS2_TOUCHKIT is not set
  17712. +CONFIG_MOUSE_PS2_ELANTECH=y
  17713. +CONFIG_MOUSE_PS2_SENTELIC=y
  17714. +CONFIG_MOUSE_SERIAL=m
  17715. +CONFIG_MOUSE_VSXXXAA=m
  17716. +CONFIG_MOUSE_APPLETOUCH=m
  17717. +CONFIG_MOUSE_BCM5974=m
  17718. +CONFIG_MOUSE_SYNAPTICS_I2C=m
  17719. +CONFIG_MOUSE_SYNAPTICS_USB=m
  17720. +CONFIG_MOUSE_CYAPA=m
  17721. +CONFIG_INPUT_JOYSTICK=y
  17722. +CONFIG_JOYSTICK_ANALOG=m
  17723. +CONFIG_JOYSTICK_A3D=m
  17724. +CONFIG_JOYSTICK_ADI=m
  17725. +CONFIG_JOYSTICK_COBRA=m
  17726. +CONFIG_JOYSTICK_GF2K=m
  17727. +CONFIG_JOYSTICK_GRIP=m
  17728. +CONFIG_JOYSTICK_GRIP_MP=m
  17729. +CONFIG_JOYSTICK_GUILLEMOT=m
  17730. +CONFIG_JOYSTICK_INTERACT=m
  17731. +CONFIG_JOYSTICK_SIDEWINDER=m
  17732. +CONFIG_JOYSTICK_TMDC=m
  17733. +CONFIG_JOYSTICK_IFORCE=m
  17734. +CONFIG_JOYSTICK_IFORCE_USB=y
  17735. +CONFIG_JOYSTICK_IFORCE_232=y
  17736. +CONFIG_JOYSTICK_WARRIOR=m
  17737. +CONFIG_JOYSTICK_MAGELLAN=m
  17738. +CONFIG_JOYSTICK_SPACEORB=m
  17739. +CONFIG_JOYSTICK_SPACEBALL=m
  17740. +CONFIG_JOYSTICK_STINGER=m
  17741. +CONFIG_JOYSTICK_DB9=m
  17742. +CONFIG_JOYSTICK_GAMECON=m
  17743. +CONFIG_JOYSTICK_TURBOGRAFX=m
  17744. +CONFIG_JOYSTICK_JOYDUMP=m
  17745. +CONFIG_JOYSTICK_TWIDJOY=m
  17746. +CONFIG_JOYSTICK_WALKERA0701=m
  17747. +CONFIG_JOYSTICK_XPAD=m
  17748. +CONFIG_JOYSTICK_XPAD_FF=y
  17749. +CONFIG_JOYSTICK_XPAD_LEDS=y
  17750. +CONFIG_JOYSTICK_ZHENHUA=m
  17751. +# CONFIG_JOYSTICK_AS5011 is not set
  17752. +
  17753. +CONFIG_INPUT_TOUCHSCREEN=y
  17754. +# CONFIG_TOUCHSCREEN_AD7879 is not set
  17755. +CONFIG_TOUCHSCREEN_AD7879_I2C=m
  17756. +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
  17757. +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
  17758. +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set
  17759. +CONFIG_TOUCHSCREEN_DYNAPRO=m
  17760. +CONFIG_TOUCHSCREEN_EDT_FT5X06=m
  17761. +CONFIG_TOUCHSCREEN_EETI=m
  17762. +CONFIG_TOUCHSCREEN_EGALAX=m
  17763. +CONFIG_TOUCHSCREEN_ELO=m
  17764. +CONFIG_TOUCHSCREEN_FUJITSU=m
  17765. +CONFIG_TOUCHSCREEN_GUNZE=m
  17766. +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
  17767. +CONFIG_TOUCHSCREEN_INEXIO=m
  17768. +CONFIG_TOUCHSCREEN_ILI210X=m
  17769. +CONFIG_TOUCHSCREEN_MMS114=m
  17770. +CONFIG_TOUCHSCREEN_MTOUCH=m
  17771. +CONFIG_TOUCHSCREEN_MCS5000=m
  17772. +CONFIG_TOUCHSCREEN_MK712=m
  17773. +CONFIG_TOUCHSCREEN_PENMOUNT=m
  17774. +# CONFIG_TOUCHSCREEN_SUR40 is not set
  17775. +# CONFIG_TOUCHSCREEN_TPS6507X is not set
  17776. +CONFIG_TOUCHSCREEN_TSC_SERIO=m
  17777. +CONFIG_TOUCHSCREEN_TSC2007=m
  17778. +CONFIG_TOUCHSCREEN_TOUCHIT213=m
  17779. +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
  17780. +CONFIG_TOUCHSCREEN_TOUCHWIN=m
  17781. +CONFIG_TOUCHSCREEN_PIXCIR=m
  17782. +CONFIG_TOUCHSCREEN_UCB1400=m
  17783. +CONFIG_TOUCHSCREEN_WACOM_W8001=m
  17784. +CONFIG_TOUCHSCREEN_WACOM_I2C=m
  17785. +CONFIG_TOUCHSCREEN_USB_E2I=y
  17786. +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
  17787. +# CONFIG_TOUCHSCREEN_WM97XX is not set
  17788. +CONFIG_TOUCHSCREEN_W90X900=m
  17789. +# CONFIG_TOUCHSCREEN_BU21013 is not set
  17790. +CONFIG_TOUCHSCREEN_ST1232=m
  17791. +CONFIG_TOUCHSCREEN_ATMEL_MXT=m
  17792. +# CONFIG_TOUCHSCREEN_MAX11801 is not set
  17793. +CONFIG_TOUCHSCREEN_AUO_PIXCIR=m
  17794. +CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m
  17795. +CONFIG_TOUCHSCREEN_ZFORCE=m
  17796. +
  17797. +CONFIG_INPUT_PCSPKR=m
  17798. +CONFIG_INPUT_RETU_PWRBUTTON=m
  17799. +CONFIG_INPUT_UINPUT=m
  17800. +CONFIG_INPUT_WISTRON_BTNS=m
  17801. +CONFIG_INPUT_ATLAS_BTNS=m
  17802. +
  17803. +CONFIG_INPUT_ATI_REMOTE2=m
  17804. +CONFIG_INPUT_KEYSPAN_REMOTE=m
  17805. +
  17806. +CONFIG_MAC_EMUMOUSEBTN=y
  17807. +
  17808. +CONFIG_INPUT_WM831X_ON=m
  17809. +
  17810. +
  17811. +# CONFIG_INPUT_AD714X is not set
  17812. +# CONFIG_INPUT_PCF8574 is not set
  17813. +CONFIG_INPUT_MMA8450=m
  17814. +CONFIG_INPUT_MPU3050=m
  17815. +CONFIG_INPUT_KXTJ9=m
  17816. +# CONFIG_INPUT_KXTJ9_POLLED_MODE is not set
  17817. +
  17818. +#
  17819. +# Character devices
  17820. +#
  17821. +CONFIG_VT=y
  17822. +CONFIG_VT_CONSOLE=y
  17823. +CONFIG_HW_CONSOLE=y
  17824. +CONFIG_SERIAL_NONSTANDARD=y
  17825. +CONFIG_ROCKETPORT=m
  17826. +CONFIG_SYNCLINK=m
  17827. +CONFIG_SYNCLINKMP=m
  17828. +CONFIG_SYNCLINK_GT=m
  17829. +CONFIG_N_HDLC=m
  17830. +CONFIG_N_GSM=m
  17831. +# CONFIG_TRACE_SINK is not set
  17832. +# CONFIG_STALDRV is not set
  17833. +# CONFIG_DUMMY_IRQ is not set
  17834. +# CONFIG_IBM_ASM is not set
  17835. +CONFIG_TIFM_CORE=m
  17836. +CONFIG_TIFM_7XX1=m
  17837. +CONFIG_TCG_TPM=m
  17838. +CONFIG_TCG_TIS=m
  17839. +# CONFIG_TCG_TIS_I2C_INFINEON is not set
  17840. +# CONFIG_TCG_TIS_I2C_ATMEL is not set
  17841. +# CONFIG_TCG_TIS_I2C_NUVOTON is not set
  17842. +CONFIG_TCG_NSC=m
  17843. +CONFIG_TCG_ATMEL=m
  17844. +# CONFIG_TCG_INFINEON is not set
  17845. +# CONFIG_TCG_ST33_I2C is not set
  17846. +# CONFIG_TCG_XEN is not set
  17847. +CONFIG_TELCLOCK=m
  17848. +
  17849. +#
  17850. +# Serial drivers
  17851. +#
  17852. +CONFIG_SERIAL_8250=y
  17853. +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
  17854. +CONFIG_SERIAL_8250_CONSOLE=y
  17855. +CONFIG_SERIAL_8250_CS=m
  17856. +CONFIG_SERIAL_8250_NR_UARTS=32
  17857. +CONFIG_SERIAL_8250_RUNTIME_UARTS=4
  17858. +CONFIG_SERIAL_8250_EXTENDED=y
  17859. +CONFIG_SERIAL_8250_MANY_PORTS=y
  17860. +CONFIG_SERIAL_8250_SHARE_IRQ=y
  17861. +# CONFIG_SERIAL_8250_DETECT_IRQ is not set
  17862. +CONFIG_SERIAL_8250_RSA=y
  17863. +# CONFIG_SERIAL_8250_DW is not set
  17864. +CONFIG_CYCLADES=m
  17865. +# CONFIG_CYZ_INTR is not set
  17866. +# CONFIG_MOXA_INTELLIO is not set
  17867. +# CONFIG_MOXA_SMARTIO is not set
  17868. +# CONFIG_ISI is not set
  17869. +# CONFIG_RIO is not set
  17870. +CONFIG_SERIAL_JSM=m
  17871. +# CONFIG_SERIAL_SCCNXP is not set
  17872. +# CONFIG_SERIAL_MFD_HSU is not set
  17873. +
  17874. +# CONFIG_SERIAL_ALTERA_JTAGUART is not set
  17875. +# CONFIG_SERIAL_ALTERA_UART is not set
  17876. +
  17877. +#
  17878. +# Non-8250 serial port support
  17879. +#
  17880. +CONFIG_SERIAL_CORE=y
  17881. +CONFIG_SERIAL_CORE_CONSOLE=y
  17882. +# CONFIG_SERIAL_XILINX_PS_UART is not set
  17883. +# CONFIG_SERIAL_TIMBERDALE is not set
  17884. +CONFIG_SERIAL_ARC=m
  17885. +CONFIG_SERIAL_ARC_NR_PORTS=1
  17886. +# CONFIG_SERIAL_RP2 is not set
  17887. +# CONFIG_SERIAL_ST_ASC is not set
  17888. +# CONFIG_SERIAL_PCH_UART is not set
  17889. +
  17890. +CONFIG_UNIX98_PTYS=y
  17891. +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
  17892. +CONFIG_PRINTER=m
  17893. +CONFIG_LP_CONSOLE=y
  17894. +CONFIG_PPDEV=m
  17895. +
  17896. +#
  17897. +# I2C support
  17898. +#
  17899. +CONFIG_I2C=y
  17900. +# CONFIG_I2C_MUX is not set
  17901. +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
  17902. +# CONFIG_I2C_MUX_PCA954x is not set
  17903. +# CONFIG_I2C_MUX_GPIO is not set
  17904. +# CONFIG_I2C_MUX_PCA9541 is not set
  17905. +# CONFIG_I2C_MUX_PINCTRL is not set
  17906. +#
  17907. +
  17908. +#
  17909. +# I2C Algorithms
  17910. +#
  17911. +# CONFIG_I2C_DEBUG_ALGO is not set
  17912. +CONFIG_I2C_ALGOBIT=m
  17913. +
  17914. +#
  17915. +# I2C Hardware Bus support
  17916. +#
  17917. +
  17918. +# CONFIG_I2C_ALI1535 is not set
  17919. +# CONFIG_I2C_ALI1563 is not set
  17920. +# CONFIG_I2C_ALI15X3 is not set
  17921. +# CONFIG_I2C_AMD756 is not set
  17922. +# CONFIG_I2C_AMD756_S4882 is not set
  17923. +# CONFIG_I2C_AMD8111 is not set
  17924. +# CONFIG_I2C_DEBUG_CORE is not set
  17925. +# CONFIG_I2C_DEBUG_BUS is not set
  17926. +# CONFIG_I2C_I801 is not set
  17927. +# CONFIG_I2C_ISCH is not set
  17928. +# CONFIG_I2C_NFORCE2_S4985 is not set
  17929. +# CONFIG_I2C_INTEL_MID is not set
  17930. +# CONFIG_I2C_EG20T is not set
  17931. +# CONFIG_I2C_CBUS_GPIO is not set
  17932. +CONFIG_I2C_VIPERBOARD=m
  17933. +
  17934. +CONFIG_EEPROM_AT24=m
  17935. +CONFIG_EEPROM_LEGACY=m
  17936. +CONFIG_EEPROM_93CX6=m
  17937. +CONFIG_EEPROM_MAX6875=m
  17938. +
  17939. +CONFIG_I2C_NFORCE2=m
  17940. +# CONFIG_I2C_OCORES is not set
  17941. +CONFIG_I2C_PARPORT=m
  17942. +CONFIG_I2C_PARPORT_LIGHT=m
  17943. +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
  17944. +CONFIG_I2C_PASEMI=m
  17945. +CONFIG_I2C_PCA_PLATFORM=m
  17946. +# CONFIG_I2C_PIIX4 is not set
  17947. +# CONFIG_SCx200_ACB is not set
  17948. +# CONFIG_I2C_SIS5595 is not set
  17949. +# CONFIG_I2C_SIS630 is not set
  17950. +# CONFIG_I2C_SIS96X is not set
  17951. +CONFIG_I2C_SIMTEC=m
  17952. +CONFIG_I2C_STUB=m
  17953. +CONFIG_I2C_TINY_USB=m
  17954. +# CONFIG_I2C_TAOS_EVM is not set
  17955. +# CONFIG_I2C_VIA is not set
  17956. +# CONFIG_I2C_VIAPRO is not set
  17957. +# CONFIG_I2C_DESIGNWARE is not set
  17958. +# CONFIG_I2C_XILINX is not set
  17959. +
  17960. +CONFIG_I2C_DIOLAN_U2C=m
  17961. +
  17962. +#
  17963. +# I2C Hardware Sensors Chip support
  17964. +#
  17965. +CONFIG_SENSORS_ATK0110=m
  17966. +CONFIG_SENSORS_ABITUGURU=m
  17967. +CONFIG_SENSORS_ABITUGURU3=m
  17968. +CONFIG_SENSORS_AD7414=m
  17969. +CONFIG_SENSORS_AD7418=m
  17970. +CONFIG_SENSORS_ADM1021=m
  17971. +CONFIG_SENSORS_ADM1025=m
  17972. +CONFIG_SENSORS_ADM1026=m
  17973. +CONFIG_SENSORS_ADM1029=m
  17974. +CONFIG_SENSORS_ADM1031=m
  17975. +CONFIG_SENSORS_ADM9240=m
  17976. +CONFIG_SENSORS_ADT7310=m
  17977. +CONFIG_SENSORS_ADT7410=m
  17978. +CONFIG_SENSORS_ADS7828=m
  17979. +CONFIG_SENSORS_ADT7462=m
  17980. +CONFIG_SENSORS_ADT7470=m
  17981. +CONFIG_SENSORS_ADT7475=m
  17982. +CONFIG_SENSORS_APPLESMC=m
  17983. +CONFIG_SENSORS_ASB100=m
  17984. +CONFIG_SENSORS_ATXP1=m
  17985. +CONFIG_SENSORS_CORETEMP=m
  17986. +CONFIG_SENSORS_DME1737=m
  17987. +CONFIG_SENSORS_DS1621=m
  17988. +# CONFIG_DS1682 is not set
  17989. +CONFIG_SENSORS_F71805F=m
  17990. +CONFIG_SENSORS_F71882FG=m
  17991. +CONFIG_SENSORS_F75375S=m
  17992. +CONFIG_SENSORS_FSCHMD=m
  17993. +CONFIG_SENSORS_G760A=m
  17994. +CONFIG_SENSORS_G762=m
  17995. +CONFIG_SENSORS_GL518SM=m
  17996. +CONFIG_SENSORS_GL520SM=m
  17997. +CONFIG_SENSORS_HDAPS=m
  17998. +# CONFIG_SENSORS_HIH6130 is not set
  17999. +# CONFIG_SENSORS_HTU21 is not set
  18000. +# CONFIG_SENSORS_I5K_AMB is not set
  18001. +# FIXME: IBMAEM x86 only?
  18002. +CONFIG_SENSORS_IBMAEM=m
  18003. +CONFIG_SENSORS_IBMPEX=m
  18004. +# CONFIG_SENSORS_IIO_HWMON is not set
  18005. +CONFIG_SENSORS_IT87=m
  18006. +CONFIG_SENSORS_K8TEMP=m
  18007. +CONFIG_SENSORS_K10TEMP=m
  18008. +CONFIG_SENSORS_LIS3LV02D=m
  18009. +CONFIG_SENSORS_LIS3_SPI=m
  18010. +CONFIG_SENSORS_LIS3_I2C=m
  18011. +CONFIG_SENSORS_LM63=m
  18012. +CONFIG_SENSORS_LM75=m
  18013. +CONFIG_SENSORS_LM77=m
  18014. +CONFIG_SENSORS_LM78=m
  18015. +CONFIG_SENSORS_LM80=m
  18016. +CONFIG_SENSORS_LM83=m
  18017. +CONFIG_SENSORS_LM85=m
  18018. +CONFIG_SENSORS_LM87=m
  18019. +CONFIG_SENSORS_LM90=m
  18020. +CONFIG_SENSORS_LM92=m
  18021. +CONFIG_SENSORS_LM93=m
  18022. +CONFIG_SENSORS_LM95234=m
  18023. +CONFIG_SENSORS_LTC4245=m
  18024. +CONFIG_SENSORS_MAX1619=m
  18025. +CONFIG_SENSORS_MAX6650=m
  18026. +CONFIG_SENSORS_MAX6697=m
  18027. +CONFIG_SENSORS_MCP3021=m
  18028. +CONFIG_SENSORS_NCT6775=m
  18029. +CONFIG_SENSORS_NTC_THERMISTOR=m
  18030. +CONFIG_SENSORS_PC87360=m
  18031. +CONFIG_SENSORS_PC87427=m
  18032. +CONFIG_SENSORS_PCF8591=m
  18033. +CONFIG_SENSORS_SHT15=m
  18034. +CONFIG_SENSORS_SIS5595=m
  18035. +CONFIG_CHARGER_SMB347=m
  18036. +CONFIG_SENSORS_SMSC47M1=m
  18037. +CONFIG_SENSORS_SMSC47M192=m
  18038. +CONFIG_SENSORS_SMSC47B397=m
  18039. +CONFIG_SENSORS_THMC50=m
  18040. +CONFIG_SENSORS_TMP401=m
  18041. +CONFIG_APDS9802ALS=m
  18042. +CONFIG_ISL29020=m
  18043. +CONFIG_ISL29003=m
  18044. +CONFIG_SENSORS_BH1770=m
  18045. +CONFIG_SENSORS_APDS990X=m
  18046. +CONFIG_SENSORS_TSL2550=m
  18047. +CONFIG_SENSORS_VIA686A=m
  18048. +CONFIG_SENSORS_VIA_CPUTEMP=m
  18049. +CONFIG_SENSORS_VT1211=m
  18050. +CONFIG_SENSORS_VT8231=m
  18051. +CONFIG_SENSORS_W83627HF=m
  18052. +CONFIG_SENSORS_W83781D=m
  18053. +CONFIG_SENSORS_W83L785TS=m
  18054. +CONFIG_SENSORS_W83L786NG=m
  18055. +CONFIG_SENSORS_W83627EHF=m
  18056. +CONFIG_SENSORS_W83791D=m
  18057. +CONFIG_SENSORS_W83792D=m
  18058. +CONFIG_SENSORS_W83793=m
  18059. +CONFIG_SENSORS_LTC4215=m
  18060. +CONFIG_SENSORS_LM95241=m
  18061. +CONFIG_SENSORS_LM95245=m
  18062. +CONFIG_SENSORS_TMP421=m
  18063. +CONFIG_SENSORS_WM8350=m
  18064. +CONFIG_SENSORS_WM831X=m
  18065. +CONFIG_SENSORS_LM73=m
  18066. +CONFIG_SENSORS_AMC6821=m
  18067. +CONFIG_SENSORS_INA2XX=m
  18068. +CONFIG_SENSORS_INA209=m
  18069. +CONFIG_SENSORS_ADT7411=m
  18070. +CONFIG_SENSORS_ASC7621=m
  18071. +CONFIG_SENSORS_EMC1403=m
  18072. +CONFIG_SENSORS_TMP102=m
  18073. +CONFIG_SENSORS_LTC4261=m
  18074. +# CONFIG_SENSORS_BH1780 is not set
  18075. +# CONFIG_SENSORS_JC42 is not set
  18076. +# CONFIG_SENSORS_SMM665 is not set
  18077. +# CONFIG_SENSORS_EMC2103 is not set
  18078. +# CONFIG_SENSORS_GPIO_FAN is not set
  18079. +CONFIG_SENSORS_W83795=m
  18080. +# CONFIG_SENSORS_W83795_FANCTRL is not set
  18081. +CONFIG_SENSORS_DS620=m
  18082. +CONFIG_SENSORS_SHT21=m
  18083. +CONFIG_SENSORS_LINEAGE=m
  18084. +CONFIG_SENSORS_LTC4151=m
  18085. +CONFIG_SENSORS_MAX6639=m
  18086. +CONFIG_SENSORS_SCH5627=m
  18087. +CONFIG_SENSORS_SCH5636=m
  18088. +CONFIG_SENSORS_ADS1015=m
  18089. +CONFIG_SENSORS_MAX16065=m
  18090. +CONFIG_SENSORS_MAX6642=m
  18091. +CONFIG_SENSORS_ADM1275=m
  18092. +CONFIG_SENSORS_UCD9000=m
  18093. +CONFIG_SENSORS_UCD9200=m
  18094. +CONFIG_SENSORS_ZL6100=m
  18095. +CONFIG_SENSORS_EMC6W201=m
  18096. +
  18097. +CONFIG_PMBUS=m
  18098. +CONFIG_SENSORS_PMBUS=m
  18099. +CONFIG_SENSORS_MAX16064=m
  18100. +CONFIG_SENSORS_LM25066=m
  18101. +CONFIG_SENSORS_LTC2978=m
  18102. +CONFIG_SENSORS_MAX34440=m
  18103. +CONFIG_SENSORS_MAX8688=m
  18104. +CONFIG_SENSORS_MAX1668=m
  18105. +CONFIG_SENSORS_MAX197=m
  18106. +
  18107. +# Industrial I/O subsystem configuration
  18108. +CONFIG_IIO=m
  18109. +CONFIG_IIO_BUFFER=y
  18110. +CONFIG_IIO_BUFFER_CB=y
  18111. +# CONFIG_IIO_KFIFO_BUF is not set
  18112. +CONFIG_IIO_TRIGGERED_BUFFER=m
  18113. +CONFIG_IIO_TRIGGER=y
  18114. +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
  18115. +CONFIG_IIO_INTERRUPT_TRIGGER=m
  18116. +CONFIG_HID_SENSOR_IIO_COMMON=m
  18117. +CONFIG_HID_SENSOR_IIO_TRIGGER=m
  18118. +CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS=y
  18119. +# CONFIG_IIO_SYSFS_TRIGGER is not set
  18120. +# CONFIG_AD5446 is not set
  18121. +# CONFIG_AD5380 is not set
  18122. +# CONFIG_AD5064 is not set
  18123. +# CONFIG_BMA180 is not set
  18124. +# CONFIG_MAX1363 is not set
  18125. +# CONFIG_MAX517 is not set
  18126. +# CONFIG_MCP4725 is not set
  18127. +# CONFIG_ITG3200 is not set
  18128. +# CONFIG_APDS9300 is not set
  18129. +# CONFIG_CM32181 is not set
  18130. +# CONFIG_CM36651 is not set
  18131. +# CONFIG_GP2AP020A00F is not set
  18132. +# CONFIG_TSL2583 is not set
  18133. +# CONFIG_TSL2x7x is not set
  18134. +# CONFIG_TCS3472 is not set
  18135. +# CONFIG_TSL4531 is not set
  18136. +# CONFIG_NAU7802 is not set
  18137. +# CONFIG_TI_ADC081C is not set
  18138. +# CONFIG_EXYNOS_ADC is not set
  18139. +# CONFIG_VIPERBOARD_ADC is not set
  18140. +# CONFIG_INV_MPU6050_IIO is not set
  18141. +CONFIG_IIO_ST_GYRO_3AXIS=m
  18142. +CONFIG_IIO_ST_MAGN_3AXIS=m
  18143. +CONFIG_IIO_ST_ACCEL_3AXIS=m
  18144. +CONFIG_HID_SENSOR_INCLINOMETER_3D=m
  18145. +# CONFIG_ADJD_S311 is not set
  18146. +# CONFIG_SENSORS_TSL2563 is not set
  18147. +# CONFIG_VCNL4000 is not set
  18148. +# CONFIG_AK8975 is not set
  18149. +# CONFIG_MAG3110 is not set
  18150. +# CONFIG_TMP006 is not set
  18151. +# CONFIG_IIO_ST_PRESS is not set
  18152. +# CONFIG_KXSD9 is not set
  18153. +# CONFIG_AD7266 is not set
  18154. +# CONFIG_AD7298 is not set
  18155. +# CONFIG_AD7476 is not set
  18156. +# CONFIG_AD7791 is not set
  18157. +# CONFIG_AD7793 is not set
  18158. +# CONFIG_AD7887 is not set
  18159. +# CONFIG_AD7923 is not set
  18160. +# CONFIG_MCP320X is not set
  18161. +# CONFIG_MCP3422 is not set
  18162. +# CONFIG_AD8366 is not set
  18163. +# CONFIG_AD5360 is not set
  18164. +# CONFIG_AD5421 is not set
  18165. +# CONFIG_AD5449 is not set
  18166. +# CONFIG_AD5504 is not set
  18167. +# CONFIG_AD5624R_SPI is not set
  18168. +# CONFIG_AD5686 is not set
  18169. +# CONFIG_AD5755 is not set
  18170. +# CONFIG_AD5764 is not set
  18171. +# CONFIG_AD5791 is not set
  18172. +# CONFIG_AD7303 is not set
  18173. +# CONFIG_AD9523 is not set
  18174. +# CONFIG_ADF4350 is not set
  18175. +# CONFIG_ADIS16080 is not set
  18176. +# CONFIG_ADIS16130 is not set
  18177. +# CONFIG_ADIS16136 is not set
  18178. +# CONFIG_ADIS16260 is not set
  18179. +# CONFIG_ADXRS450 is not set
  18180. +# CONFIG_ADIS16400 is not set
  18181. +# CONFIG_ADIS16480 is not set
  18182. +# CONFIG_DHT11 is not set
  18183. +# CONFIG_MPL3115 is not set
  18184. +
  18185. +# staging IIO drivers
  18186. +# CONFIG_AD7291 is not set
  18187. +# CONFIG_AD7606 is not set
  18188. +# CONFIG_AD799X is not set
  18189. +# CONFIG_ADT7316 is not set
  18190. +# CONFIG_AD7150 is not set
  18191. +# CONFIG_AD7152 is not set
  18192. +# CONFIG_AD7746 is not set
  18193. +# CONFIG_AD5933 is not set
  18194. +# CONFIG_ADE7854 is not set
  18195. +# CONFIG_SENSORS_ISL29018 is not set
  18196. +# CONFIG_SENSORS_ISL29028 is not set
  18197. +# CONFIG_SENSORS_HMC5843 is not set
  18198. +# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set
  18199. +# CONFIG_IIO_SIMPLE_DUMMY is not set
  18200. +# CONFIG_ADIS16201 is not set
  18201. +# CONFIG_ADIS16203 is not set
  18202. +# CONFIG_ADIS16204 is not set
  18203. +# CONFIG_ADIS16209 is not set
  18204. +# CONFIG_ADIS16220 is not set
  18205. +# CONFIG_ADIS16240 is not set
  18206. +# CONFIG_LIS3L02DQ is not set
  18207. +# CONFIG_SCA3000 is not set
  18208. +# CONFIG_AD7780 is not set
  18209. +# CONFIG_AD7816 is not set
  18210. +# CONFIG_AD7192 is not set
  18211. +# CONFIG_AD7280 is not set
  18212. +# CONFIG_AD5930 is not set
  18213. +# CONFIG_AD9832 is not set
  18214. +# CONFIG_AD9834 is not set
  18215. +# CONFIG_AD9850 is not set
  18216. +# CONFIG_AD9852 is not set
  18217. +# CONFIG_AD9910 is not set
  18218. +# CONFIG_AD9951 is not set
  18219. +# CONFIG_ADIS16060 is not set
  18220. +# CONFIG_ADE7753 is not set
  18221. +# CONFIG_ADE7754 is not set
  18222. +# CONFIG_ADE7758 is not set
  18223. +# CONFIG_ADE7759 is not set
  18224. +# CONFIG_AD2S90 is not set
  18225. +# CONFIG_AD2S1200 is not set
  18226. +# CONFIG_AD2S1210 is not set
  18227. +
  18228. +
  18229. +
  18230. +# CONFIG_HMC6352 is not set
  18231. +# CONFIG_BMP085 is not set
  18232. +# CONFIG_BMP085_I2C is not set
  18233. +# CONFIG_PCH_PHUB is not set
  18234. +# CONFIG_USB_SWITCH_FSA9480 is not set
  18235. +
  18236. +CONFIG_W1=m
  18237. +CONFIG_W1_CON=y
  18238. +# CONFIG_W1_MASTER_MATROX is not set
  18239. +CONFIG_W1_MASTER_DS2490=m
  18240. +CONFIG_W1_MASTER_DS2482=m
  18241. +CONFIG_W1_MASTER_DS1WM=m
  18242. +CONFIG_W1_MASTER_GPIO=m
  18243. +# CONFIG_HDQ_MASTER_OMAP is not set
  18244. +CONFIG_W1_SLAVE_THERM=m
  18245. +CONFIG_W1_SLAVE_SMEM=m
  18246. +CONFIG_W1_SLAVE_DS2408=m
  18247. +# CONFIG_W1_SLAVE_DS2408_READBACK is not set
  18248. +CONFIG_W1_SLAVE_DS2413=m
  18249. +CONFIG_W1_SLAVE_DS2423=m
  18250. +CONFIG_W1_SLAVE_DS2431=m
  18251. +CONFIG_W1_SLAVE_DS2433=m
  18252. +CONFIG_W1_SLAVE_DS2433_CRC=y
  18253. +CONFIG_W1_SLAVE_DS2760=m
  18254. +CONFIG_W1_SLAVE_DS2780=m
  18255. +CONFIG_W1_SLAVE_DS2781=m
  18256. +CONFIG_W1_SLAVE_DS28E04=m
  18257. +CONFIG_W1_SLAVE_BQ27000=m
  18258. +
  18259. +#
  18260. +# Mice
  18261. +#
  18262. +
  18263. +#
  18264. +# IPMI
  18265. +#
  18266. +CONFIG_IPMI_HANDLER=m
  18267. +# CONFIG_IPMI_PANIC_EVENT is not set
  18268. +CONFIG_IPMI_DEVICE_INTERFACE=m
  18269. +CONFIG_IPMI_WATCHDOG=m
  18270. +CONFIG_IPMI_SI=m
  18271. +CONFIG_IPMI_POWEROFF=m
  18272. +
  18273. +#
  18274. +# Watchdog Cards
  18275. +#
  18276. +CONFIG_WATCHDOG_CORE=y
  18277. +# CONFIG_WATCHDOG_NOWAYOUT is not set
  18278. +CONFIG_SOFT_WATCHDOG=m
  18279. +CONFIG_WDTPCI=m
  18280. +# CONFIG_ACQUIRE_WDT is not set
  18281. +# CONFIG_ADVANTECH_WDT is not set
  18282. +# CONFIG_EUROTECH_WDT is not set
  18283. +CONFIG_IB700_WDT=m
  18284. +# CONFIG_SCx200_WDT is not set
  18285. +# CONFIG_60XX_WDT is not set
  18286. +CONFIG_W83877F_WDT=m
  18287. +CONFIG_W83627HF_WDT=m
  18288. +CONFIG_MACHZ_WDT=m
  18289. +# CONFIG_SC520_WDT is not set
  18290. +CONFIG_ALIM7101_WDT=m
  18291. +CONFIG_ALIM1535_WDT=m
  18292. +CONFIG_IT87_WDT=m
  18293. +CONFIG_ITCO_WDT=m
  18294. +CONFIG_ITCO_VENDOR_SUPPORT=y
  18295. +# CONFIG_SC1200_WDT is not set
  18296. +# CONFIG_PC87413_WDT is not set
  18297. +# CONFIG_WAFER_WDT is not set
  18298. +# CONFIG_CPU5_WDT is not set
  18299. +CONFIG_I6300ESB_WDT=m
  18300. +CONFIG_IT8712F_WDT=m
  18301. +# CONFIG_SBC8360_WDT is not set
  18302. +# CONFIG_SBC7240_WDT is not set
  18303. +CONFIG_SMSC_SCH311X_WDT=m
  18304. +CONFIG_W83977F_WDT=m
  18305. +CONFIG_PCIPCWATCHDOG=m
  18306. +CONFIG_USBPCWATCHDOG=m
  18307. +# CONFIG_SBC_EPX_C3_WATCHDOG is not set
  18308. +CONFIG_WM8350_WATCHDOG=m
  18309. +CONFIG_WM831X_WATCHDOG=m
  18310. +# CONFIG_MAX63XX_WATCHDOG is not set
  18311. +# CONFIG_DW_WATCHDOG is not set
  18312. +CONFIG_W83697UG_WDT=m
  18313. +# CONFIG_MEN_A21_WDT is not set
  18314. +# CONFIG_GPIO_WATCHDOG is not set
  18315. +
  18316. +CONFIG_HW_RANDOM=y
  18317. +CONFIG_HW_RANDOM_TIMERIOMEM=m
  18318. +CONFIG_HW_RANDOM_TPM=m
  18319. +# CONFIG_HW_RANDOM_ATMEL is not set
  18320. +# CONFIG_HW_RANDOM_EXYNOS is not set
  18321. +# CONFIG_NVRAM is not set
  18322. +# CONFIG_RTC is not set
  18323. +# CONFIG_RTC_DEBUG is not set
  18324. +# CONFIG_GEN_RTC is not set
  18325. +CONFIG_RTC_HCTOSYS=y
  18326. +# CONFIG_RTC_SYSTOHC is not set
  18327. +CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
  18328. +CONFIG_RTC_INTF_SYSFS=y
  18329. +CONFIG_RTC_INTF_PROC=y
  18330. +CONFIG_RTC_INTF_DEV=y
  18331. +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
  18332. +CONFIG_RTC_DRV_CMOS=y
  18333. +CONFIG_RTC_DRV_DS1307=m
  18334. +CONFIG_RTC_DRV_DS1511=m
  18335. +CONFIG_RTC_DRV_DS1553=m
  18336. +CONFIG_RTC_DRV_DS1672=m
  18337. +CONFIG_RTC_DRV_DS1742=m
  18338. +CONFIG_RTC_DRV_DS1374=m
  18339. +# CONFIG_RTC_DRV_EP93XX is not set
  18340. +CONFIG_RTC_DRV_FM3130=m
  18341. +CONFIG_RTC_DRV_ISL1208=m
  18342. +CONFIG_RTC_DRV_M41T80=m
  18343. +CONFIG_RTC_DRV_M41T80_WDT=y
  18344. +CONFIG_RTC_DRV_M48T59=m
  18345. +CONFIG_RTC_DRV_MAX6900=m
  18346. +# CONFIG_RTC_DRV_M48T86 is not set
  18347. +CONFIG_RTC_DRV_PCF2127=m
  18348. +CONFIG_RTC_DRV_PCF8563=m
  18349. +CONFIG_RTC_DRV_PCF8583=m
  18350. +CONFIG_RTC_DRV_RS5C372=m
  18351. +# CONFIG_RTC_DRV_SA1100 is not set
  18352. +# CONFIG_RTC_DRV_TEST is not set
  18353. +CONFIG_RTC_DRV_X1205=m
  18354. +CONFIG_RTC_DRV_V3020=m
  18355. +CONFIG_RTC_DRV_DS2404=m
  18356. +CONFIG_RTC_DRV_STK17TA8=m
  18357. +# CONFIG_RTC_DRV_S35390A is not set
  18358. +CONFIG_RTC_DRV_RX8581=m
  18359. +CONFIG_RTC_DRV_RX8025=m
  18360. +CONFIG_RTC_DRV_DS1286=m
  18361. +CONFIG_RTC_DRV_M48T35=m
  18362. +CONFIG_RTC_DRV_BQ4802=m
  18363. +CONFIG_RTC_DRV_WM8350=m
  18364. +# CONFIG_RTC_DRV_AB3100 is not set
  18365. +CONFIG_RTC_DRV_WM831X=m
  18366. +CONFIG_RTC_DRV_BQ32K=m
  18367. +CONFIG_RTC_DRV_MSM6242=m
  18368. +CONFIG_RTC_DRV_RP5C01=m
  18369. +CONFIG_RTC_DRV_EM3027=m
  18370. +CONFIG_RTC_DRV_RV3029C2=m
  18371. +CONFIG_RTC_DRV_PCF50633=m
  18372. +CONFIG_RTC_DRV_DS3232=m
  18373. +CONFIG_RTC_DRV_ISL12022=m
  18374. +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
  18375. +# CONFIG_RTC_DRV_MOXART is not set
  18376. +# CONFIG_RTC_DRV_ISL12057 is not set
  18377. +
  18378. +CONFIG_R3964=m
  18379. +# CONFIG_APPLICOM is not set
  18380. +# CONFIG_SONYPI is not set
  18381. +
  18382. +#
  18383. +# Ftape, the floppy tape device driver
  18384. +#
  18385. +CONFIG_AGP=y
  18386. +CONFIG_AGP_ALI=y
  18387. +CONFIG_AGP_ATI=y
  18388. +CONFIG_AGP_AMD=y
  18389. +CONFIG_AGP_AMD64=y
  18390. +CONFIG_AGP_INTEL=y
  18391. +CONFIG_AGP_NVIDIA=y
  18392. +CONFIG_AGP_SIS=y
  18393. +CONFIG_AGP_SWORKS=y
  18394. +CONFIG_AGP_VIA=y
  18395. +CONFIG_AGP_EFFICEON=y
  18396. +
  18397. +CONFIG_VGA_ARB=y
  18398. +CONFIG_VGA_ARB_MAX_GPUS=16
  18399. +
  18400. +# CONFIG_STUB_POULSBO is not set
  18401. +
  18402. +#
  18403. +# PCMCIA character devices
  18404. +#
  18405. +# CONFIG_SYNCLINK_CS is not set
  18406. +
  18407. +CONFIG_CARDMAN_4000=m
  18408. +CONFIG_CARDMAN_4040=m
  18409. +
  18410. +CONFIG_MWAVE=m
  18411. +CONFIG_RAW_DRIVER=y
  18412. +CONFIG_MAX_RAW_DEVS=8192
  18413. +CONFIG_HANGCHECK_TIMER=m
  18414. +
  18415. +CONFIG_MEDIA_PCI_SUPPORT=y
  18416. +#
  18417. +# Multimedia devices
  18418. +#
  18419. +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
  18420. +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
  18421. +CONFIG_MEDIA_RC_SUPPORT=y
  18422. +CONFIG_MEDIA_CONTROLLER=y
  18423. +CONFIG_VIDEO_DEV=m
  18424. +# CONFIG_VIDEO_ADV_DEBUG is not set
  18425. +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
  18426. +CONFIG_VIDEO_V4L2=y
  18427. +CONFIG_VIDEO_V4L2_SUBDEV_API=y
  18428. +# CONFIG_VIDEO_VIVI is not set
  18429. +# CONFIG_USB_SI4713 is not set
  18430. +# CONFIG_PLATFORM_SI4713 is not set
  18431. +# CONFIG_I2C_SI4713 is not set
  18432. +# CONFIG_USB_RAREMONO is not set
  18433. +
  18434. +#
  18435. +# Video For Linux
  18436. +#
  18437. +
  18438. +#
  18439. +# Video Adapters
  18440. +#
  18441. +CONFIG_V4L_USB_DRIVERS=y
  18442. +CONFIG_VIDEO_CAPTURE_DRIVERS=y
  18443. +CONFIG_V4L_PCI_DRIVERS=y
  18444. +CONFIG_VIDEO_AU0828=m
  18445. +CONFIG_VIDEO_AU0828_V4L2=y
  18446. +CONFIG_VIDEO_BT848=m
  18447. +CONFIG_VIDEO_BT848_DVB=y
  18448. +CONFIG_VIDEO_BWQCAM=m
  18449. +CONFIG_VIDEO_SR030PC30=m
  18450. +CONFIG_VIDEO_NOON010PC30=m
  18451. +CONFIG_VIDEO_CAFE_CCIC=m
  18452. +# CONFIG_VIDEO_CPIA is not set
  18453. +CONFIG_VIDEO_CPIA2=m
  18454. +CONFIG_VIDEO_CQCAM=m
  18455. +CONFIG_VIDEO_CX23885=m
  18456. +CONFIG_MEDIA_ALTERA_CI=m
  18457. +CONFIG_VIDEO_CX18=m
  18458. +CONFIG_VIDEO_CX18_ALSA=m
  18459. +CONFIG_VIDEO_CX88=m
  18460. +CONFIG_VIDEO_CX88_DVB=m
  18461. +CONFIG_VIDEO_CX88_ALSA=m
  18462. +CONFIG_VIDEO_CX88_BLACKBIRD=m
  18463. +CONFIG_VIDEO_CX88_ENABLE_VP3054=y
  18464. +CONFIG_VIDEO_CX88_VP3054=m
  18465. +CONFIG_VIDEO_EM28XX=m
  18466. +CONFIG_VIDEO_EM28XX_V4L2=m
  18467. +CONFIG_VIDEO_EM28XX_ALSA=m
  18468. +CONFIG_VIDEO_EM28XX_DVB=m
  18469. +CONFIG_VIDEO_EM28XX_RC=y
  18470. +CONFIG_VIDEO_CX231XX=m
  18471. +CONFIG_VIDEO_CX231XX_ALSA=m
  18472. +CONFIG_VIDEO_CX231XX_DVB=m
  18473. +CONFIG_VIDEO_CX231XX_RC=y
  18474. +CONFIG_VIDEO_HEXIUM_ORION=m
  18475. +CONFIG_VIDEO_HEXIUM_GEMINI=m
  18476. +CONFIG_VIDEO_IVTV=m
  18477. +# CONFIG_VIDEO_IVTV_ALSA is not set
  18478. +CONFIG_VIDEO_MEYE=m
  18479. +CONFIG_VIDEO_MXB=m
  18480. +CONFIG_VIDEO_PVRUSB2_DVB=y
  18481. +# CONFIG_VIDEO_PMS is not set
  18482. +CONFIG_VIDEO_HDPVR=m
  18483. +CONFIG_VIDEO_SAA6588=m
  18484. +CONFIG_VIDEO_SAA7134=m
  18485. +CONFIG_VIDEO_SAA7134_ALSA=m
  18486. +CONFIG_VIDEO_SAA7134_DVB=m
  18487. +CONFIG_VIDEO_SAA7134_RC=y
  18488. +CONFIG_VIDEO_USBVISION=m
  18489. +CONFIG_VIDEO_STK1160_COMMON=m
  18490. +CONFIG_VIDEO_STK1160=m
  18491. +CONFIG_VIDEO_STK1160_AC97=y
  18492. +CONFIG_VIDEO_W9966=m
  18493. +CONFIG_VIDEO_ZORAN=m
  18494. +CONFIG_VIDEO_ZORAN_AVS6EYES=m
  18495. +CONFIG_VIDEO_ZORAN_BUZ=m
  18496. +CONFIG_VIDEO_ZORAN_DC10=m
  18497. +CONFIG_VIDEO_ZORAN_DC30=m
  18498. +CONFIG_VIDEO_ZORAN_LML33=m
  18499. +CONFIG_VIDEO_ZORAN_LML33R10=m
  18500. +CONFIG_VIDEO_ZORAN_ZR36060=m
  18501. +# CONFIG_V4L_ISA_PARPORT_DRIVERS is not set
  18502. +CONFIG_VIDEO_FB_IVTV=m
  18503. +CONFIG_VIDEO_SAA7164=m
  18504. +CONFIG_VIDEO_TM6000=m
  18505. +CONFIG_VIDEO_TM6000_ALSA=m
  18506. +CONFIG_VIDEO_TM6000_DVB=m
  18507. +CONFIG_VIDEO_TLG2300=m
  18508. +CONFIG_VIDEO_USBTV=m
  18509. +
  18510. +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
  18511. +
  18512. +#
  18513. +# Radio Adapters
  18514. +#
  18515. +CONFIG_RADIO_MAXIRADIO=m
  18516. +CONFIG_RADIO_SHARK=m
  18517. +CONFIG_RADIO_SHARK2=m
  18518. +CONFIG_RADIO_WL1273=m
  18519. +
  18520. +CONFIG_MEDIA_ATTACH=y
  18521. +
  18522. +#
  18523. +# V4L/DVB tuners
  18524. +# Selected automatically by not setting CONFIG_MEDIA_TUNER_CUSTOMISE
  18525. +#
  18526. +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
  18527. +
  18528. +#
  18529. +# Digital Video Broadcasting Devices
  18530. +#
  18531. +CONFIG_DVB_CAPTURE_DRIVERS=y
  18532. +CONFIG_DVB_CORE=m
  18533. +CONFIG_DVB_NET=y
  18534. +CONFIG_DVB_MAX_ADAPTERS=8
  18535. +CONFIG_DVB_DYNAMIC_MINORS=y
  18536. +
  18537. +#
  18538. +# DVB frontends
  18539. +# Selected automatically by not setting CONFIG_DVB_FE_CUSTOMISE
  18540. +#
  18541. +# CONFIG_DVB_FE_CUSTOMISE is not set
  18542. +
  18543. +#
  18544. +# Supported DVB bridge Modules
  18545. +#
  18546. +CONFIG_DVB_BT8XX=m
  18547. +CONFIG_DVB_BUDGET_CORE=m
  18548. +CONFIG_DVB_PLUTO2=m
  18549. +CONFIG_SMS_SIANO_MDTV=m
  18550. +CONFIG_SMS_SIANO_RC=y
  18551. +# CONFIG_SMS_SIANO_DEBUGFS is not set
  18552. +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
  18553. +CONFIG_SMS_USB_DRV=m
  18554. +CONFIG_SMS_SDIO_DRV=m
  18555. +CONFIG_DVB_TTUSB_DEC=m
  18556. +CONFIG_DVB_USB_DTV5100=m
  18557. +CONFIG_DVB_USB_AF9015=m
  18558. +CONFIG_DVB_USB_ANYSEE=m
  18559. +CONFIG_DVB_USB_DW2102=m
  18560. +CONFIG_DVB_USB_FRIIO=m
  18561. +CONFIG_DVB_USB_EC168=m
  18562. +CONFIG_DVB_USB_PCTV452E=m
  18563. +CONFIG_DVB_USB_IT913X=m
  18564. +CONFIG_DVB_USB_MXL111SF=m
  18565. +CONFIG_DVB_DM1105=m
  18566. +CONFIG_DVB_FIREDTV=m
  18567. +CONFIG_DVB_NGENE=m
  18568. +CONFIG_DVB_DDBRIDGE=m
  18569. +CONFIG_DVB_USB_TECHNISAT_USB2=m
  18570. +CONFIG_DVB_USB_V2=m
  18571. +
  18572. +CONFIG_DVB_AV7110=m
  18573. +CONFIG_DVB_AV7110_OSD=y
  18574. +CONFIG_DVB_BUDGET=m
  18575. +CONFIG_DVB_BUDGET_CI=m
  18576. +CONFIG_DVB_BUDGET_AV=m
  18577. +CONFIG_DVB_BUDGET_PATCH=m
  18578. +
  18579. +CONFIG_DVB_TTUSB_BUDGET=m
  18580. +
  18581. +CONFIG_DVB_USB_CINERGY_T2=m
  18582. +CONFIG_DVB_B2C2_FLEXCOP=m
  18583. +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set
  18584. +
  18585. +CONFIG_DVB_B2C2_FLEXCOP_PCI=m
  18586. +# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set
  18587. +CONFIG_DVB_B2C2_FLEXCOP_USB=m
  18588. +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
  18589. +CONFIG_DVB_USB=m
  18590. +# CONFIG_DVB_USB_DEBUG is not set
  18591. +CONFIG_DVB_USB_A800=m
  18592. +CONFIG_DVB_USB_AF9005=m
  18593. +CONFIG_DVB_USB_AF9005_REMOTE=m
  18594. +CONFIG_DVB_USB_AU6610=m
  18595. +CONFIG_DVB_USB_CXUSB=m
  18596. +CONFIG_DVB_USB_DIBUSB_MB=m
  18597. +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
  18598. +CONFIG_DVB_USB_DIBUSB_MC=m
  18599. +CONFIG_DVB_USB_DIB0700=m
  18600. +CONFIG_DVB_USB_DIGITV=m
  18601. +CONFIG_DVB_USB_DTT200U=m
  18602. +CONFIG_DVB_USB_GL861=m
  18603. +CONFIG_DVB_USB_GP8PSK=m
  18604. +CONFIG_DVB_USB_M920X=m
  18605. +CONFIG_DVB_USB_NOVA_T_USB2=m
  18606. +CONFIG_DVB_USB_CE6230=m
  18607. +CONFIG_DVB_USB_OPERA1=m
  18608. +CONFIG_DVB_USB_TTUSB2=m
  18609. +CONFIG_DVB_USB_UMT_010=m
  18610. +CONFIG_DVB_USB_VP702X=m
  18611. +CONFIG_DVB_USB_VP7045=m
  18612. +CONFIG_DVB_USB_AZ6027=m
  18613. +CONFIG_DVB_USB_AZ6007=m
  18614. +CONFIG_DVB_USB_LME2510=m
  18615. +CONFIG_DVB_USB_RTL28XXU=m
  18616. +CONFIG_DVB_USB_AF9035=m
  18617. +
  18618. +CONFIG_DVB_PT1=m
  18619. +
  18620. +CONFIG_MANTIS_CORE=m
  18621. +CONFIG_DVB_MANTIS=m
  18622. +CONFIG_DVB_HOPPER=m
  18623. +
  18624. +CONFIG_VIDEO_SAA7146=m
  18625. +CONFIG_VIDEO_SAA7146_VV=m
  18626. +CONFIG_VIDEO_TVP5150=m
  18627. +CONFIG_VIDEO_TUNER=m
  18628. +CONFIG_VIDEO_BTCX=m
  18629. +CONFIG_VIDEO_PVRUSB2=m
  18630. +CONFIG_VIDEO_PVRUSB2_SYSFS=y
  18631. +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
  18632. +
  18633. +CONFIG_RC_CORE=m
  18634. +CONFIG_RC_DECODERS=y
  18635. +CONFIG_LIRC=m
  18636. +CONFIG_RC_LOOPBACK=m
  18637. +CONFIG_RC_MAP=m
  18638. +CONFIG_RC_DEVICES=y
  18639. +CONFIG_RC_ATI_REMOTE=m
  18640. +CONFIG_IR_NEC_DECODER=m
  18641. +CONFIG_IR_RC5_DECODER=m
  18642. +CONFIG_IR_RC6_DECODER=m
  18643. +CONFIG_IR_JVC_DECODER=m
  18644. +CONFIG_IR_SONY_DECODER=m
  18645. +CONFIG_IR_RC5_SZ_DECODER=m
  18646. +CONFIG_IR_SANYO_DECODER=m
  18647. +CONFIG_IR_MCE_KBD_DECODER=m
  18648. +CONFIG_IR_LIRC_CODEC=m
  18649. +CONFIG_IR_IMON=m
  18650. +CONFIG_IR_MCEUSB=m
  18651. +CONFIG_IR_ITE_CIR=m
  18652. +CONFIG_IR_NUVOTON=m
  18653. +CONFIG_IR_FINTEK=m
  18654. +CONFIG_IR_REDRAT3=m
  18655. +CONFIG_IR_ENE=m
  18656. +CONFIG_IR_STREAMZAP=m
  18657. +CONFIG_IR_WINBOND_CIR=m
  18658. +CONFIG_IR_IGUANA=m
  18659. +CONFIG_IR_TTUSBIR=m
  18660. +CONFIG_IR_GPIO_CIR=m
  18661. +
  18662. +CONFIG_V4L_MEM2MEM_DRIVERS=y
  18663. +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
  18664. +# CONFIG_VIDEO_SH_VEU is not set
  18665. +# CONFIG_VIDEO_RENESAS_VSP1 is not set
  18666. +# CONFIG_V4L_TEST_DRIVERS is not set
  18667. +
  18668. +# CONFIG_VIDEO_MEM2MEM_TESTDEV is not set
  18669. +
  18670. +#
  18671. +# Broadcom Crystal HD video decoder driver
  18672. +#
  18673. +CONFIG_CRYSTALHD=m
  18674. +
  18675. +#
  18676. +# Graphics support
  18677. +#
  18678. +
  18679. +CONFIG_DISPLAY_SUPPORT=m
  18680. +CONFIG_VIDEO_OUTPUT_CONTROL=m
  18681. +
  18682. +#
  18683. +# Console display driver support
  18684. +#
  18685. +CONFIG_VGA_CONSOLE=y
  18686. +CONFIG_VGACON_SOFT_SCROLLBACK=y
  18687. +CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
  18688. +CONFIG_DUMMY_CONSOLE=y
  18689. +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
  18690. +
  18691. +#
  18692. +# Logo configuration
  18693. +#
  18694. +# CONFIG_LOGO_LINUX_MONO is not set
  18695. +# CONFIG_LOGO_LINUX_VGA16 is not set
  18696. +CONFIG_LOGO_LINUX_CLUT224=y
  18697. +
  18698. +#
  18699. +# Sound
  18700. +#
  18701. +
  18702. +#
  18703. +# Advanced Linux Sound Architecture
  18704. +#
  18705. +CONFIG_SOUND_OSS_CORE_PRECLAIM=y
  18706. +# CONFIG_SND_DEBUG_VERBOSE is not set
  18707. +CONFIG_SND_VERBOSE_PROCFS=y
  18708. +CONFIG_SND_SEQUENCER=y
  18709. +CONFIG_SND_HRTIMER=y
  18710. +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
  18711. +CONFIG_SND_SEQ_DUMMY=m
  18712. +CONFIG_SND_SEQUENCER_OSS=y
  18713. +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
  18714. +CONFIG_SND_OSSEMUL=y
  18715. +CONFIG_SND_MIXER_OSS=y
  18716. +CONFIG_SND_PCM_OSS=y
  18717. +CONFIG_SND_PCM_OSS_PLUGINS=y
  18718. +CONFIG_SND_RTCTIMER=y
  18719. +CONFIG_SND_DYNAMIC_MINORS=y
  18720. +CONFIG_SND_MAX_CARDS=32
  18721. +# CONFIG_SND_SUPPORT_OLD_API is not set
  18722. +
  18723. +#
  18724. +# Generic devices
  18725. +#
  18726. +CONFIG_SND_DUMMY=m
  18727. +CONFIG_SND_ALOOP=m
  18728. +CONFIG_SND_VIRMIDI=m
  18729. +CONFIG_SND_MTPAV=m
  18730. +CONFIG_SND_MTS64=m
  18731. +CONFIG_SND_SERIAL_U16550=m
  18732. +CONFIG_SND_MPU401=m
  18733. +CONFIG_SND_PORTMAN2X4=m
  18734. +CONFIG_SND_AC97_POWER_SAVE=y
  18735. +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0
  18736. +
  18737. +CONFIG_SND_DRIVERS=y
  18738. +
  18739. +#
  18740. +# ISA devices
  18741. +#
  18742. +CONFIG_SND_AD1889=m
  18743. +
  18744. +#
  18745. +# PCI devices
  18746. +#
  18747. +CONFIG_SND_PCI=y
  18748. +CONFIG_SND_ALI5451=m
  18749. +CONFIG_SND_ALS300=m
  18750. +CONFIG_SND_ALS4000=m
  18751. +CONFIG_SND_ATIIXP=m
  18752. +CONFIG_SND_ATIIXP_MODEM=m
  18753. +CONFIG_SND_AU8810=m
  18754. +CONFIG_SND_AU8820=m
  18755. +CONFIG_SND_AU8830=m
  18756. +# CONFIG_SND_AW2 is not set
  18757. +CONFIG_SND_AZT3328=m
  18758. +CONFIG_SND_BT87X=m
  18759. +# CONFIG_SND_BT87X_OVERCLOCK is not set
  18760. +CONFIG_SND_CA0106=m
  18761. +CONFIG_SND_CMIPCI=m
  18762. +CONFIG_SND_CS46XX=m
  18763. +CONFIG_SND_CS46XX_NEW_DSP=y
  18764. +CONFIG_SND_CS4281=m
  18765. +CONFIG_SND_CS5530=m
  18766. +CONFIG_SND_CS5535AUDIO=m
  18767. +CONFIG_SND_EMU10K1=m
  18768. +CONFIG_SND_EMU10K1X=m
  18769. +CONFIG_SND_ENS1370=m
  18770. +CONFIG_SND_ENS1371=m
  18771. +CONFIG_SND_ES1938=m
  18772. +CONFIG_SND_ES1968=m
  18773. +CONFIG_SND_ES1968_INPUT=y
  18774. +CONFIG_SND_ES1968_RADIO=y
  18775. +CONFIG_SND_FM801=m
  18776. +CONFIG_SND_FM801_TEA575X_BOOL=y
  18777. +CONFIG_SND_CTXFI=m
  18778. +CONFIG_SND_LX6464ES=m
  18779. +CONFIG_SND_HDA_INTEL=y
  18780. +CONFIG_SND_HDA_INPUT_BEEP=y
  18781. +CONFIG_SND_HDA_INPUT_BEEP_MODE=0
  18782. +CONFIG_SND_HDA_INPUT_JACK=y
  18783. +CONFIG_SND_HDA_PATCH_LOADER=y
  18784. +CONFIG_SND_HDA_HWDEP=y
  18785. +CONFIG_SND_HDA_CODEC_REALTEK=y
  18786. +CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS=y
  18787. +CONFIG_SND_HDA_CODEC_CA0110=y
  18788. +CONFIG_SND_HDA_CODEC_ANALOG=y
  18789. +CONFIG_SND_HDA_CODEC_SIGMATEL=y
  18790. +CONFIG_SND_HDA_CODEC_VIA=y
  18791. +CONFIG_SND_HDA_CODEC_CIRRUS=y
  18792. +CONFIG_SND_HDA_CODEC_CONEXANT=y
  18793. +CONFIG_SND_HDA_CODEC_CMEDIA=y
  18794. +CONFIG_SND_HDA_CODEC_SI3054=y
  18795. +CONFIG_SND_HDA_CODEC_HDMI=y
  18796. +CONFIG_SND_HDA_I915=y
  18797. +CONFIG_SND_HDA_CODEC_CA0132=y
  18798. +CONFIG_SND_HDA_CODEC_CA0132_DSP=y
  18799. +CONFIG_SND_HDA_GENERIC=y
  18800. +CONFIG_SND_HDA_POWER_SAVE=y
  18801. +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
  18802. +CONFIG_SND_HDA_RECONFIG=y
  18803. +CONFIG_SND_HDA_PREALLOC_SIZE=4096
  18804. +CONFIG_SND_HDSPM=m
  18805. +CONFIG_SND_ICE1712=m
  18806. +CONFIG_SND_ICE1724=m
  18807. +CONFIG_SND_INTEL8X0=y
  18808. +CONFIG_SND_INTEL8X0M=m
  18809. +CONFIG_SND_KORG1212=m
  18810. +CONFIG_SND_MAESTRO3=m
  18811. +CONFIG_SND_MAESTRO3_INPUT=y
  18812. +CONFIG_SND_MIXART=m
  18813. +CONFIG_SND_NM256=m
  18814. +CONFIG_SND_OXYGEN=m
  18815. +CONFIG_SND_RME32=m
  18816. +CONFIG_SND_PCSP=m
  18817. +CONFIG_SND_PCXHR=m
  18818. +CONFIG_SND_RIPTIDE=m
  18819. +CONFIG_SND_RME96=m
  18820. +CONFIG_SND_RME9652=m
  18821. +CONFIG_SND_SIS7019=m
  18822. +CONFIG_SND_SONICVIBES=m
  18823. +CONFIG_SND_HDSP=m
  18824. +CONFIG_SND_TRIDENT=m
  18825. +CONFIG_SND_VIA82XX=m
  18826. +CONFIG_SND_VIA82XX_MODEM=m
  18827. +CONFIG_SND_VIRTUOSO=m
  18828. +CONFIG_SND_VX222=m
  18829. +CONFIG_SND_YMFPCI=m
  18830. +CONFIG_SND_ASIHPI=m
  18831. +CONFIG_SND_LOLA=m
  18832. +
  18833. +#
  18834. +# ALSA USB devices
  18835. +#
  18836. +CONFIG_SND_USB=y
  18837. +CONFIG_SND_USB_CAIAQ=m
  18838. +CONFIG_SND_USB_CAIAQ_INPUT=y
  18839. +CONFIG_SND_USB_USX2Y=m
  18840. +CONFIG_SND_USB_US122L=m
  18841. +CONFIG_SND_USB_UA101=m
  18842. +CONFIG_SND_USB_6FIRE=m
  18843. +CONFIG_SND_USB_HIFACE=m
  18844. +
  18845. +#
  18846. +# PCMCIA devices
  18847. +#
  18848. +# CONFIG_SND_PCMCIA is not set
  18849. +
  18850. +CONFIG_SND_FIREWIRE=y
  18851. +CONFIG_SND_FIREWIRE_SPEAKERS=m
  18852. +CONFIG_SND_ISIGHT=m
  18853. +CONFIG_SND_SCS1X=m
  18854. +CONFIG_SND_DICE=m
  18855. +
  18856. +#
  18857. +# Open Sound System
  18858. +#
  18859. +# CONFIG_SOUND_PRIME is not set
  18860. +
  18861. +#
  18862. +# USB support
  18863. +#
  18864. +CONFIG_USB_SUPPORT=y
  18865. +# CONFIG_USB_DEBUG is not set
  18866. +
  18867. +# DEPRECATED: See bug 362221. Fix udev.
  18868. +# CONFIG_USB_DEVICE_CLASS is not set
  18869. +
  18870. +
  18871. +#
  18872. +# Miscellaneous USB options
  18873. +#
  18874. +
  18875. +# Deprecated.
  18876. +# CONFIG_USB_DEVICEFS is not set
  18877. +
  18878. +CONFIG_USB_DEFAULT_PERSIST=y
  18879. +# CONFIG_USB_DYNAMIC_MINORS is not set
  18880. +CONFIG_USB_SUSPEND=y
  18881. +
  18882. +#
  18883. +# USB Host Controller Drivers
  18884. +#
  18885. +CONFIG_USB_EHCI_ROOT_HUB_TT=y
  18886. +CONFIG_USB_EHCI_TT_NEWSCHED=y
  18887. +# CONFIG_USB_EHCI_MV is not set
  18888. +# CONFIG_USB_EHCI_HCD_PLATFORM is not set
  18889. +# CONFIG_USB_ISP116X_HCD is not set
  18890. +# CONFIG_USB_ISP1760_HCD is not set
  18891. +CONFIG_USB_ISP1362_HCD=m
  18892. +CONFIG_USB_FUSBH200_HCD=m
  18893. +# CONFIG_USB_FOTG210_HCD is not set
  18894. +# CONFIG_USB_GR_UDC is not set
  18895. +CONFIG_USB_OHCI_HCD=y
  18896. +CONFIG_USB_OHCI_HCD_PCI=y
  18897. +# CONFIG_USB_OHCI_HCD_SSB is not set
  18898. +# CONFIG_USB_HCD_TEST_MODE is not set
  18899. +# CONFIG_USB_OHCI_HCD_PLATFORM is not set
  18900. +CONFIG_USB_UHCI_HCD=y
  18901. +CONFIG_USB_SL811_HCD=m
  18902. +CONFIG_USB_SL811_HCD_ISO=y
  18903. +# CONFIG_USB_SL811_CS is not set
  18904. +# CONFIG_USB_R8A66597_HCD is not set
  18905. +CONFIG_USB_XHCI_HCD=y
  18906. +# CONFIG_USB_XHCI_HCD_DEBUGGING is not set
  18907. +
  18908. +#
  18909. +# USB Device Class drivers
  18910. +#
  18911. +
  18912. +#
  18913. +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
  18914. +#
  18915. +CONFIG_USB_ACM=m
  18916. +CONFIG_USB_PRINTER=m
  18917. +CONFIG_USB_WDM=m
  18918. +CONFIG_USB_TMC=m
  18919. +# CONFIG_BLK_DEV_UB is not set
  18920. +# CONFIG_USB_STORAGE_DEBUG is not set
  18921. +CONFIG_USB_STORAGE_CYPRESS_ATACB=m
  18922. +CONFIG_USB_STORAGE_DATAFAB=m
  18923. +CONFIG_USB_STORAGE_FREECOM=m
  18924. +CONFIG_USB_STORAGE_ISD200=m
  18925. +CONFIG_USB_STORAGE_SDDR09=m
  18926. +CONFIG_USB_STORAGE_SDDR55=m
  18927. +CONFIG_USB_STORAGE_JUMPSHOT=m
  18928. +CONFIG_USB_STORAGE_USBAT=y
  18929. +CONFIG_USB_STORAGE_ONETOUCH=m
  18930. +CONFIG_USB_STORAGE_ALAUDA=m
  18931. +CONFIG_USB_STORAGE_KARMA=m
  18932. +CONFIG_USB_STORAGE_REALTEK=m
  18933. +CONFIG_REALTEK_AUTOPM=y
  18934. +CONFIG_USB_STORAGE_ENE_UB6250=m
  18935. +# CONFIG_USB_LIBUSUAL is not set
  18936. +# CONFIG_USB_UAS is not set
  18937. +
  18938. +
  18939. +#
  18940. +# USB Human Interface Devices (HID)
  18941. +#
  18942. +CONFIG_USB_HID=y
  18943. +
  18944. +CONFIG_HID_SUPPORT=y
  18945. +
  18946. +CONFIG_HID=y
  18947. +CONFIG_I2C_HID=m
  18948. +CONFIG_HID_BATTERY_STRENGTH=y
  18949. +# debugging default is y upstream now
  18950. +CONFIG_HIDRAW=y
  18951. +CONFIG_UHID=m
  18952. +CONFIG_HID_PID=y
  18953. +CONFIG_LOGITECH_FF=y
  18954. +CONFIG_HID_LOGITECH_DJ=m
  18955. +CONFIG_LOGIWII_FF=y
  18956. +CONFIG_LOGIRUMBLEPAD2_FF=y
  18957. +CONFIG_PANTHERLORD_FF=y
  18958. +CONFIG_THRUSTMASTER_FF=y
  18959. +CONFIG_HID_WACOM=m
  18960. +CONFIG_HID_WACOM_POWER_SUPPLY=y
  18961. +CONFIG_ZEROPLUS_FF=y
  18962. +CONFIG_USB_HIDDEV=y
  18963. +CONFIG_USB_IDMOUSE=m
  18964. +CONFIG_DRAGONRISE_FF=y
  18965. +CONFIG_GREENASIA_FF=y
  18966. +CONFIG_SMARTJOYPLUS_FF=y
  18967. +CONFIG_LOGIG940_FF=y
  18968. +CONFIG_LOGIWHEELS_FF=y
  18969. +CONFIG_HID_MAGICMOUSE=y
  18970. +CONFIG_HID_MULTITOUCH=m
  18971. +CONFIG_HID_NTRIG=y
  18972. +CONFIG_HID_QUANTA=y
  18973. +CONFIG_HID_PRIMAX=m
  18974. +CONFIG_HID_PS3REMOTE=m
  18975. +CONFIG_HID_PRODIKEYS=m
  18976. +CONFIG_HID_DRAGONRISE=m
  18977. +CONFIG_HID_GYRATION=m
  18978. +CONFIG_HID_ICADE=m
  18979. +CONFIG_HID_TWINHAN=m
  18980. +CONFIG_HID_ORTEK=m
  18981. +CONFIG_HID_PANTHERLORD=m
  18982. +CONFIG_HID_PETALYNX=m
  18983. +CONFIG_HID_PICOLCD=m
  18984. +CONFIG_HID_RMI=m
  18985. +CONFIG_HID_ROCCAT=m
  18986. +CONFIG_HID_ROCCAT_KONE=m
  18987. +CONFIG_HID_SAMSUNG=m
  18988. +CONFIG_HID_SONY=m
  18989. +CONFIG_SONY_FF=y
  18990. +CONFIG_HID_SUNPLUS=m
  18991. +CONFIG_HID_STEELSERIES=m
  18992. +CONFIG_HID_GREENASIA=m
  18993. +CONFIG_HID_SMARTJOYPLUS=m
  18994. +CONFIG_HID_TOPSEED=m
  18995. +CONFIG_HID_THINGM=m
  18996. +CONFIG_HID_THRUSTMASTER=m
  18997. +CONFIG_HID_XINMO=m
  18998. +CONFIG_HID_ZEROPLUS=m
  18999. +CONFIG_HID_ZYDACRON=m
  19000. +CONFIG_HID_SENSOR_HUB=m
  19001. +CONFIG_HID_SENSOR_GYRO_3D=m
  19002. +CONFIG_HID_SENSOR_MAGNETOMETER_3D=m
  19003. +CONFIG_HID_SENSOR_ALS=m
  19004. +CONFIG_HID_SENSOR_ACCEL_3D=m
  19005. +CONFIG_HID_EMS_FF=m
  19006. +CONFIG_HID_ELECOM=m
  19007. +CONFIG_HID_ELO=m
  19008. +CONFIG_HID_UCLOGIC=m
  19009. +CONFIG_HID_WALTOP=m
  19010. +CONFIG_HID_ROCCAT_PYRA=m
  19011. +CONFIG_HID_ROCCAT_KONEPLUS=m
  19012. +CONFIG_HID_ACRUX=m
  19013. +CONFIG_HID_ACRUX_FF=y
  19014. +CONFIG_HID_KEYTOUCH=m
  19015. +CONFIG_HID_LCPOWER=m
  19016. +CONFIG_HID_LENOVO_TPKBD=m
  19017. +CONFIG_HID_ROCCAT_ARVO=m
  19018. +CONFIG_HID_ROCCAT_ISKU=m
  19019. +CONFIG_HID_ROCCAT_KOVAPLUS=m
  19020. +CONFIG_HID_HOLTEK=m
  19021. +CONFIG_HOLTEK_FF=y
  19022. +CONFIG_HID_HUION=m
  19023. +CONFIG_HID_SPEEDLINK=m
  19024. +CONFIG_HID_WIIMOTE=m
  19025. +CONFIG_HID_WIIMOTE_EXT=y
  19026. +CONFIG_HID_KYE=m
  19027. +CONFIG_HID_SAITEK=m
  19028. +CONFIG_HID_TIVO=m
  19029. +CONFIG_HID_GENERIC=y
  19030. +CONFIG_HID_AUREAL=m
  19031. +CONFIG_HID_APPLEIR=m
  19032. +
  19033. +
  19034. +#
  19035. +# USB Imaging devices
  19036. +#
  19037. +CONFIG_USB_MDC800=m
  19038. +CONFIG_USB_MICROTEK=m
  19039. +
  19040. +#
  19041. +# USB Multimedia devices
  19042. +#
  19043. +
  19044. +CONFIG_USB_DSBR=m
  19045. +# CONFIG_USB_ET61X251 is not set
  19046. +CONFIG_USB_M5602=m
  19047. +CONFIG_USB_STV06XX=m
  19048. +CONFIG_USB_GSPCA=m
  19049. +CONFIG_USB_GSPCA_MR97310A=m
  19050. +CONFIG_USB_GSPCA_BENQ=m
  19051. +CONFIG_USB_GSPCA_CONEX=m
  19052. +CONFIG_USB_GSPCA_CPIA1=m
  19053. +CONFIG_USB_GSPCA_ETOMS=m
  19054. +CONFIG_USB_GSPCA_FINEPIX=m
  19055. +CONFIG_USB_GSPCA_MARS=m
  19056. +CONFIG_USB_GSPCA_OV519=m
  19057. +CONFIG_USB_GSPCA_OV534=m
  19058. +CONFIG_USB_GSPCA_OV534_9=m
  19059. +CONFIG_USB_GSPCA_PAC207=m
  19060. +CONFIG_USB_GSPCA_PAC7311=m
  19061. +CONFIG_USB_GSPCA_SN9C2028=m
  19062. +CONFIG_USB_GSPCA_SN9C20X=m
  19063. +CONFIG_USB_GSPCA_SONIXB=m
  19064. +CONFIG_USB_GSPCA_SONIXJ=m
  19065. +CONFIG_USB_GSPCA_SPCA500=m
  19066. +CONFIG_USB_GSPCA_SPCA501=m
  19067. +CONFIG_USB_GSPCA_SPCA505=m
  19068. +CONFIG_USB_GSPCA_SPCA506=m
  19069. +CONFIG_USB_GSPCA_SPCA508=m
  19070. +CONFIG_USB_GSPCA_SPCA561=m
  19071. +CONFIG_USB_GSPCA_STK014=m
  19072. +CONFIG_USB_GSPCA_STK1135=m
  19073. +CONFIG_USB_GSPCA_SUNPLUS=m
  19074. +CONFIG_USB_GSPCA_T613=m
  19075. +CONFIG_USB_GSPCA_TOPRO=m
  19076. +CONFIG_USB_GSPCA_TV8532=m
  19077. +CONFIG_USB_GSPCA_VC032X=m
  19078. +CONFIG_USB_GSPCA_ZC3XX=m
  19079. +CONFIG_USB_GSPCA_SQ905=m
  19080. +CONFIG_USB_GSPCA_SQ905C=m
  19081. +CONFIG_USB_GSPCA_PAC7302=m
  19082. +CONFIG_USB_GSPCA_STV0680=m
  19083. +CONFIG_USB_GL860=m
  19084. +CONFIG_USB_GSPCA_JEILINJ=m
  19085. +CONFIG_USB_GSPCA_JL2005BCD=m
  19086. +CONFIG_USB_GSPCA_KONICA=m
  19087. +CONFIG_USB_GSPCA_XIRLINK_CIT=m
  19088. +CONFIG_USB_GSPCA_SPCA1528=m
  19089. +CONFIG_USB_GSPCA_SQ930X=m
  19090. +CONFIG_USB_GSPCA_NW80X=m
  19091. +CONFIG_USB_GSPCA_VICAM=m
  19092. +CONFIG_USB_GSPCA_KINECT=m
  19093. +CONFIG_USB_GSPCA_SE401=m
  19094. +
  19095. +CONFIG_USB_S2255=m
  19096. +# CONFIG_VIDEO_SH_MOBILE_CEU is not set
  19097. +# CONFIG_VIDEO_SH_MOBILE_CSI2 is not set
  19098. +# CONFIG_USB_SN9C102 is not set
  19099. +CONFIG_USB_ZR364XX=m
  19100. +
  19101. +#
  19102. +# USB Network adaptors
  19103. +#
  19104. +CONFIG_USB_CATC=m
  19105. +CONFIG_USB_HSO=m
  19106. +CONFIG_USB_KAWETH=m
  19107. +CONFIG_USB_PEGASUS=m
  19108. +CONFIG_USB_RTL8150=m
  19109. +CONFIG_USB_RTL8152=m
  19110. +CONFIG_USB_USBNET=m
  19111. +CONFIG_USB_SPEEDTOUCH=m
  19112. +CONFIG_USB_NET_AX8817X=m
  19113. +CONFIG_USB_NET_AX88179_178A=m
  19114. +CONFIG_USB_NET_DM9601=m
  19115. +CONFIG_USB_NET_SR9700=m
  19116. +CONFIG_USB_NET_SMSC95XX=m
  19117. +CONFIG_USB_NET_GL620A=m
  19118. +CONFIG_USB_NET_NET1080=m
  19119. +CONFIG_USB_NET_PLUSB=m
  19120. +CONFIG_USB_NET_MCS7830=m
  19121. +CONFIG_USB_NET_RNDIS_HOST=m
  19122. +CONFIG_USB_NET_CDC_SUBSET=m
  19123. +CONFIG_USB_NET_CDC_EEM=m
  19124. +CONFIG_USB_NET_CDC_NCM=m
  19125. +CONFIG_USB_NET_HUAWEI_CDC_NCM=m
  19126. +CONFIG_USB_NET_CDC_MBIM=m
  19127. +CONFIG_USB_NET_ZAURUS=m
  19128. +CONFIG_USB_NET_CX82310_ETH=m
  19129. +CONFIG_USB_NET_INT51X1=m
  19130. +CONFIG_USB_CDC_PHONET=m
  19131. +CONFIG_USB_IPHETH=m
  19132. +CONFIG_USB_SIERRA_NET=m
  19133. +CONFIG_USB_VL600=m
  19134. +
  19135. +#
  19136. +# USB Host-to-Host Cables
  19137. +#
  19138. +CONFIG_USB_AN2720=y
  19139. +CONFIG_USB_BELKIN=y
  19140. +
  19141. +#
  19142. +# Intelligent USB Devices/Gadgets
  19143. +#
  19144. +CONFIG_USB_ARMLINUX=y
  19145. +CONFIG_USB_EPSON2888=y
  19146. +CONFIG_USB_KC2190=y
  19147. +
  19148. +# CONFIG_USB_MUSB_HDRC is not set
  19149. +
  19150. +#
  19151. +# USB port drivers
  19152. +#
  19153. +CONFIG_USB_USS720=m
  19154. +
  19155. +#
  19156. +# USB Serial Converter support
  19157. +#
  19158. +CONFIG_USB_SERIAL=y
  19159. +CONFIG_USB_SERIAL_GENERIC=y
  19160. +CONFIG_USB_SERIAL_SIMPLE=m
  19161. +CONFIG_USB_SERIAL_AIRCABLE=m
  19162. +CONFIG_USB_SERIAL_ARK3116=m
  19163. +CONFIG_USB_SERIAL_BELKIN=m
  19164. +CONFIG_USB_SERIAL_CH341=m
  19165. +CONFIG_USB_SERIAL_CYPRESS_M8=m
  19166. +CONFIG_USB_SERIAL_CYBERJACK=m
  19167. +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
  19168. +CONFIG_USB_SERIAL_CP210X=m
  19169. +CONFIG_USB_SERIAL_QUALCOMM=m
  19170. +CONFIG_USB_SERIAL_SYMBOL=m
  19171. +CONFIG_USB_SERIAL_EDGEPORT=m
  19172. +CONFIG_USB_SERIAL_EDGEPORT_TI=m
  19173. +CONFIG_USB_SERIAL_EMPEG=m
  19174. +# CONFIG_USB_SERIAL_F81232 is not set
  19175. +CONFIG_USB_SERIAL_FTDI_SIO=m
  19176. +CONFIG_USB_SERIAL_FUNSOFT=m
  19177. +CONFIG_USB_SERIAL_GARMIN=m
  19178. +CONFIG_USB_SERIAL_HP4X=m
  19179. +CONFIG_USB_SERIAL_IPAQ=m
  19180. +CONFIG_USB_SERIAL_IPW=m
  19181. +CONFIG_USB_SERIAL_IR=m
  19182. +CONFIG_USB_SERIAL_IUU=m
  19183. +CONFIG_USB_SERIAL_KEYSPAN_PDA=m
  19184. +CONFIG_USB_SERIAL_KEYSPAN=m
  19185. +CONFIG_USB_SERIAL_KEYSPAN_MPR=y
  19186. +CONFIG_USB_SERIAL_KEYSPAN_USA28=y
  19187. +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
  19188. +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
  19189. +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
  19190. +CONFIG_USB_SERIAL_KEYSPAN_USA19=y
  19191. +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
  19192. +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
  19193. +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
  19194. +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
  19195. +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
  19196. +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
  19197. +CONFIG_USB_SERIAL_KLSI=m
  19198. +CONFIG_USB_SERIAL_KOBIL_SCT=m
  19199. +CONFIG_USB_SERIAL_MCT_U232=m
  19200. +# CONFIG_USB_SERIAL_METRO is not set
  19201. +CONFIG_USB_SERIAL_MOS7720=m
  19202. +CONFIG_USB_SERIAL_MOS7715_PARPORT=y
  19203. +# CONFIG_USB_SERIAL_ZIO is not set
  19204. +# CONFIG_USB_SERIAL_WISHBONE is not set
  19205. +# CONFIG_USB_SERIAL_ZTE is not set
  19206. +CONFIG_USB_SERIAL_MOS7840=m
  19207. +CONFIG_USB_SERIAL_MOTOROLA=m
  19208. +# CONFIG_USB_SERIAL_MXUPORT is not set
  19209. +CONFIG_USB_SERIAL_NAVMAN=m
  19210. +CONFIG_USB_SERIAL_OPTION=m
  19211. +CONFIG_USB_SERIAL_OTI6858=m
  19212. +CONFIG_USB_SERIAL_OPTICON=m
  19213. +CONFIG_USB_SERIAL_OMNINET=m
  19214. +CONFIG_USB_SERIAL_PL2303=m
  19215. +# CONFIG_USB_SERIAL_QUATECH2 is not set
  19216. +CONFIG_USB_SERIAL_SAFE=m
  19217. +CONFIG_USB_SERIAL_SAFE_PADDED=y
  19218. +CONFIG_USB_SERIAL_SIERRAWIRELESS=m
  19219. +CONFIG_USB_SERIAL_SIEMENS_MPI=m
  19220. +CONFIG_USB_SERIAL_SPCP8X5=m
  19221. +CONFIG_USB_SERIAL_TI=m
  19222. +CONFIG_USB_SERIAL_VISOR=m
  19223. +CONFIG_USB_SERIAL_WHITEHEAT=m
  19224. +CONFIG_USB_SERIAL_XIRCOM=m
  19225. +CONFIG_USB_SERIAL_QCAUX=m
  19226. +CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m
  19227. +CONFIG_USB_SERIAL_XSENS_MT=m
  19228. +CONFIG_USB_SERIAL_DEBUG=m
  19229. +CONFIG_USB_SERIAL_SSU100=m
  19230. +CONFIG_USB_SERIAL_QT2=m
  19231. +CONFIG_USB_SERIAL_FLASHLOADER=m
  19232. +CONFIG_USB_SERIAL_SUUNTO=m
  19233. +CONFIG_USB_SERIAL_CONSOLE=y
  19234. +
  19235. +CONFIG_USB_EZUSB=y
  19236. +CONFIG_USB_EMI62=m
  19237. +CONFIG_USB_LED=m
  19238. +# CONFIG_USB_CYPRESS_CY7C63 is not set
  19239. +
  19240. +#
  19241. +# USB Miscellaneous drivers
  19242. +#
  19243. +
  19244. +CONFIG_USB_ADUTUX=m
  19245. +CONFIG_USB_SEVSEG=m
  19246. +CONFIG_USB_ALI_M5632=y
  19247. +CONFIG_USB_APPLEDISPLAY=m
  19248. +
  19249. +# Physical Layer USB driver
  19250. +# CONFIG_USB_OTG_FSM is not set
  19251. +
  19252. +# CONFIG_GENERIC_PHY is not set
  19253. +# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set
  19254. +# CONFIG_PHY_EXYNOS_DP_VIDEO is not set
  19255. +# CONFIG_OMAP_USB2 is not set
  19256. +# CONFIG_OMAP_USB3 is not set
  19257. +# CONFIG_OMAP_CONTROL_USB is not set
  19258. +# CONFIG_AM335X_PHY_USB is not set
  19259. +# CONFIG_SAMSUNG_USBPHY is not set
  19260. +# CONFIG_SAMSUNG_USB2PHY is not set
  19261. +# CONFIG_SAMSUNG_USB3PHY is not set
  19262. +# CONFIG_BCM_KONA_USB2_PHY is not set
  19263. +CONFIG_USB_RCAR_PHY=m
  19264. +CONFIG_USB_ATM=m
  19265. +CONFIG_USB_CXACRU=m
  19266. +# CONFIG_USB_C67X00_HCD is not set
  19267. +# CONFIG_USB_CYTHERM is not set
  19268. +CONFIG_USB_EMI26=m
  19269. +CONFIG_USB_FTDI_ELAN=m
  19270. +CONFIG_USB_FILE_STORAGE=m
  19271. +# CONFIG_USB_FILE_STORAGE_TEST is not set
  19272. +# CONFIG_USB_DWC3 is not set
  19273. +# CONFIG_USB_GADGETFS is not set
  19274. +# CONFIG_USB_OXU210HP_HCD is not set
  19275. +CONFIG_USB_IOWARRIOR=m
  19276. +CONFIG_USB_ISIGHTFW=m
  19277. +CONFIG_USB_YUREX=m
  19278. +CONFIG_USB_EZUSB_FX2=m
  19279. +CONFIG_USB_HSIC_USB3503=m
  19280. +CONFIG_USB_LCD=m
  19281. +CONFIG_USB_LD=m
  19282. +CONFIG_USB_LEGOTOWER=m
  19283. +CONFIG_USB_MON=y
  19284. +CONFIG_USB_PWC=m
  19285. +CONFIG_USB_PWC_INPUT_EVDEV=y
  19286. +# CONFIG_USB_PWC_DEBUG is not set
  19287. +# CONFIG_USB_RIO500 is not set
  19288. +CONFIG_USB_SISUSBVGA=m
  19289. +CONFIG_USB_SISUSBVGA_CON=y
  19290. +CONFIG_RADIO_SI470X=y
  19291. +CONFIG_USB_KEENE=m
  19292. +CONFIG_USB_MA901=m
  19293. +CONFIG_USB_SI470X=m
  19294. +CONFIG_I2C_SI470X=m
  19295. +CONFIG_RADIO_SI4713=m
  19296. +# CONFIG_RADIO_TEF6862 is not set
  19297. +CONFIG_USB_MR800=m
  19298. +CONFIG_USB_STKWEBCAM=m
  19299. +# CONFIG_USB_TEST is not set
  19300. +# CONFIG_USB_EHSET_TEST_FIXTURE is not set
  19301. +CONFIG_USB_TRANCEVIBRATOR=m
  19302. +CONFIG_USB_U132_HCD=m
  19303. +CONFIG_USB_UEAGLEATM=m
  19304. +CONFIG_USB_XUSBATM=m
  19305. +
  19306. +# CONFIG_USB_DWC2 is not set
  19307. +
  19308. +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
  19309. +
  19310. +# CONFIG_USB_ISP1301 is not set
  19311. +
  19312. +# CONFIG_USB_OTG is not set
  19313. +
  19314. +#
  19315. +# Sonics Silicon Backplane
  19316. +#
  19317. +CONFIG_SSB=m
  19318. +CONFIG_SSB_PCIHOST=y
  19319. +CONFIG_SSB_SDIOHOST=y
  19320. +CONFIG_SSB_PCMCIAHOST=y
  19321. +# CONFIG_SSB_SILENT is not set
  19322. +# CONFIG_SSB_DEBUG is not set
  19323. +CONFIG_SSB_DRIVER_PCICORE=y
  19324. +CONFIG_SSB_DRIVER_GPIO=y
  19325. +
  19326. +# Multifunction USB devices
  19327. +# CONFIG_MFD_PCF50633 is not set
  19328. +CONFIG_PCF50633_ADC=m
  19329. +CONFIG_PCF50633_GPIO=m
  19330. +# CONFIG_AB3100_CORE is not set
  19331. +CONFIG_INPUT_PCF50633_PMU=m
  19332. +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
  19333. +
  19334. +CONFIG_MFD_SUPPORT=y
  19335. +CONFIG_MFD_VX855=m
  19336. +CONFIG_MFD_SM501=m
  19337. +CONFIG_MFD_SM501_GPIO=y
  19338. +CONFIG_MFD_RTSX_PCI=m
  19339. +# CONFIG_MFD_TI_AM335X_TSCADC is not set
  19340. +CONFIG_MFD_VIPERBOARD=m
  19341. +# CONFIG_MFD_RETU is not set
  19342. +# CONFIG_MFD_TC6393XB is not set
  19343. +# CONFIG_MFD_WM8400 is not set
  19344. +# CONFIG_MFD_WM8350_I2C is not set
  19345. +# CONFIG_MFD_WM8350 is not set
  19346. +# CONFIG_MFD_WM831X is not set
  19347. +# CONFIG_AB3100_OTP is not set
  19348. +# CONFIG_MFD_TIMBERDALE is not set
  19349. +# CONFIG_MFD_WM8994 is not set
  19350. +# CONFIG_MFD_88PM860X is not set
  19351. +# CONFIG_LPC_SCH is not set
  19352. +# CONFIG_LPC_ICH is not set
  19353. +# CONFIG_HTC_I2CPLD is not set
  19354. +# CONFIG_MFD_MAX8925 is not set
  19355. +# CONFIG_MFD_ASIC3 is not set
  19356. +# CONFIG_MFD_AS3722 is not set
  19357. +# CONFIG_HTC_EGPIO is not set
  19358. +# CONFIG_TPS6507X is not set
  19359. +# CONFIG_ABX500_CORE is not set
  19360. +# CONFIG_MFD_RDC321X is not set
  19361. +# CONFIG_MFD_JANZ_CMODIO is not set
  19362. +# CONFIG_MFD_KEMPLD is not set
  19363. +# CONFIG_MFD_WM831X_I2C is not set
  19364. +# CONFIG_MFD_CS5535 is not set
  19365. +# CONFIG_MFD_STMPE is not set
  19366. +# CONFIG_MFD_MAX8998 is not set
  19367. +# CONFIG_MFD_TPS6586X is not set
  19368. +# CONFIG_MFD_TC3589X is not set
  19369. +# CONFIG_MFD_WL1273_CORE is not set
  19370. +# CONFIG_MFD_TPS65217 is not set
  19371. +# CONFIG_MFD_LM3533 is not set
  19372. +# CONFIG_MFD_ARIZONA is not set
  19373. +# CONFIG_MFD_ARIZONA_I2C is not set
  19374. +# CONFIG_MFD_CROS_EC is not set
  19375. +# CONFIG_MFD_TPS65912 is not set
  19376. +# CONFIG_MFD_SYSCON is not set
  19377. +# CONFIG_MFD_DA9063 is not set
  19378. +# CONFIG_MFD_LP3943 is not set
  19379. +
  19380. +#
  19381. +# File systems
  19382. +#
  19383. +CONFIG_MISC_FILESYSTEMS=y
  19384. +
  19385. +# ext4 is used for ext2 and ext3 filesystems
  19386. +CONFIG_JBD2=y
  19387. +CONFIG_FS_MBCACHE=y
  19388. +CONFIG_REISERFS_FS=m
  19389. +# CONFIG_REISERFS_CHECK is not set
  19390. +CONFIG_REISERFS_PROC_INFO=y
  19391. +CONFIG_REISERFS_FS_XATTR=y
  19392. +CONFIG_REISERFS_FS_POSIX_ACL=y
  19393. +CONFIG_REISERFS_FS_SECURITY=y
  19394. +CONFIG_JFS_FS=m
  19395. +# CONFIG_JFS_DEBUG is not set
  19396. +# CONFIG_JFS_STATISTICS is not set
  19397. +CONFIG_JFS_POSIX_ACL=y
  19398. +CONFIG_JFS_SECURITY=y
  19399. +CONFIG_XFS_FS=m
  19400. +# CONFIG_XFS_DEBUG is not set
  19401. +# CONFIG_XFS_RT is not set
  19402. +CONFIG_XFS_QUOTA=y
  19403. +CONFIG_XFS_POSIX_ACL=y
  19404. +CONFIG_MINIX_FS=m
  19405. +CONFIG_ROMFS_FS=m
  19406. +# CONFIG_QFMT_V1 is not set
  19407. +CONFIG_QFMT_V2=y
  19408. +CONFIG_QUOTACTL=y
  19409. +CONFIG_DNOTIFY=y
  19410. +# Autofsv3 is obsolete.
  19411. +# systemd is dependant upon AUTOFS, so build it in.
  19412. +# CONFIG_EXOFS_FS is not set
  19413. +# CONFIG_EXOFS_DEBUG is not set
  19414. +CONFIG_NILFS2_FS=m
  19415. +# CONFIG_LOGFS is not set
  19416. +CONFIG_CEPH_FS=m
  19417. +CONFIG_CEPH_FSCACHE=y
  19418. +CONFIG_BLK_DEV_RBD=m
  19419. +CONFIG_CEPH_LIB=m
  19420. +CONFIG_CEPH_FS_POSIX_ACL=y
  19421. +# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set
  19422. +
  19423. +CONFIG_FSCACHE=m
  19424. +CONFIG_FSCACHE_STATS=y
  19425. +# CONFIG_FSCACHE_HISTOGRAM is not set
  19426. +# CONFIG_FSCACHE_DEBUG is not set
  19427. +CONFIG_FSCACHE_OBJECT_LIST=y
  19428. +
  19429. +CONFIG_CACHEFILES=m
  19430. +# CONFIG_CACHEFILES_DEBUG is not set
  19431. +# CONFIG_CACHEFILES_HISTOGRAM is not set
  19432. +
  19433. +#
  19434. +# CD-ROM/DVD Filesystems
  19435. +#
  19436. +
  19437. +#
  19438. +# DOS/FAT/NT Filesystems
  19439. +#
  19440. +CONFIG_FAT_FS=m
  19441. +CONFIG_FAT_DEFAULT_CODEPAGE=437
  19442. +CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
  19443. +# CONFIG_NTFS_FS is not set
  19444. +
  19445. +#
  19446. +# Pseudo filesystems
  19447. +#
  19448. +CONFIG_PROC_FS=y
  19449. +CONFIG_PROC_KCORE=y
  19450. +CONFIG_PROC_VMCORE=y
  19451. +CONFIG_TMPFS_POSIX_ACL=y
  19452. +CONFIG_TMPFS_XATTR=y
  19453. +CONFIG_HUGETLBFS=y
  19454. +CONFIG_HUGETLB_PAGE=y
  19455. +# CONFIG_DEBUG_FS is not set
  19456. +
  19457. +#
  19458. +# Miscellaneous filesystems
  19459. +#
  19460. +# CONFIG_ADFS_FS is not set
  19461. +CONFIG_AFFS_FS=m
  19462. +CONFIG_ECRYPT_FS=m
  19463. +# CONFIG_ECRYPT_FS_MESSAGING is not set
  19464. +CONFIG_HFS_FS=m
  19465. +CONFIG_HFSPLUS_FS=m
  19466. +# CONFIG_HFSPLUS_FS_POSIX_ACL is not set
  19467. +CONFIG_BEFS_FS=m
  19468. +# CONFIG_BEFS_DEBUG is not set
  19469. +# CONFIG_BFS_FS is not set
  19470. +# CONFIG_EFS_FS is not set
  19471. +
  19472. +CONFIG_CRAMFS=m
  19473. +CONFIG_SQUASHFS=m
  19474. +CONFIG_SQUASHFS_XATTR=y
  19475. +CONFIG_SQUASHFS_LZO=y
  19476. +CONFIG_SQUASHFS_XZ=y
  19477. +CONFIG_SQUASHFS_ZLIB=y
  19478. +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
  19479. +# CONFIG_SQUASHFS_EMBEDDED is not set
  19480. +# CONFIG_VXFS_FS is not set
  19481. +# CONFIG_HPFS_FS is not set
  19482. +# CONFIG_QNX4FS_FS is not set
  19483. +# CONFIG_QNX6FS_FS is not set
  19484. +CONFIG_SYSV_FS=m
  19485. +CONFIG_UFS_FS=m
  19486. +# CONFIG_UFS_FS_WRITE is not set
  19487. +# CONFIG_UFS_DEBUG is not set
  19488. +CONFIG_9P_FS=m
  19489. +CONFIG_9P_FSCACHE=y
  19490. +CONFIG_9P_FS_POSIX_ACL=y
  19491. +CONFIG_9P_FS_SECURITY=y
  19492. +# CONFIG_OMFS_FS is not set
  19493. +CONFIG_CUSE=m
  19494. +# CONFIG_F2FS_FS is not set
  19495. +
  19496. +#
  19497. +# Network File Systems
  19498. +#
  19499. +CONFIG_NETWORK_FILESYSTEMS=y
  19500. +# CONFIG_NFS_V2 is not set
  19501. +CONFIG_NFS_V3=y
  19502. +CONFIG_NFS_SWAP=y
  19503. +CONFIG_NFS_V4_1=y
  19504. +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
  19505. +# CONFIG_NFS_V4_1_MIGRATION is not set
  19506. +CONFIG_NFS_V4_2=y
  19507. +CONFIG_NFSD=m
  19508. +CONFIG_NFSD_V3=y
  19509. +CONFIG_NFSD_V3_ACL=y
  19510. +CONFIG_NFSD_V4=y
  19511. +CONFIG_NFSD_V4_SECURITY_LABEL=y
  19512. +CONFIG_NFS_FSCACHE=y
  19513. +# CONFIG_NFS_USE_LEGACY_DNS is not set
  19514. +CONFIG_PNFS_OBJLAYOUT=m
  19515. +CONFIG_PNFS_BLOCK=m
  19516. +CONFIG_LOCKD=m
  19517. +CONFIG_LOCKD_V4=y
  19518. +CONFIG_EXPORTFS=y
  19519. +CONFIG_SUNRPC=m
  19520. +CONFIG_SUNRPC_GSS=m
  19521. +CONFIG_SUNRPC_XPRT_RDMA=m
  19522. +CONFIG_SUNRPC_DEBUG=y
  19523. +CONFIG_RPCSEC_GSS_KRB5=m
  19524. +CONFIG_CIFS=m
  19525. +CONFIG_CIFS_STATS=y
  19526. +# CONFIG_CIFS_STATS2 is not set
  19527. +CONFIG_CIFS_SMB2=y
  19528. +CONFIG_CIFS_UPCALL=y
  19529. +CONFIG_CIFS_XATTR=y
  19530. +CONFIG_CIFS_POSIX=y
  19531. +CONFIG_CIFS_FSCACHE=y
  19532. +CONFIG_CIFS_ACL=y
  19533. +CONFIG_CIFS_WEAK_PW_HASH=y
  19534. +CONFIG_CIFS_DEBUG=y
  19535. +# CONFIG_CIFS_DEBUG2 is not set
  19536. +CONFIG_CIFS_DFS_UPCALL=y
  19537. +CONFIG_CIFS_NFSD_EXPORT=y
  19538. +CONFIG_NCP_FS=m
  19539. +CONFIG_NCPFS_PACKET_SIGNING=y
  19540. +CONFIG_NCPFS_IOCTL_LOCKING=y
  19541. +CONFIG_NCPFS_STRONG=y
  19542. +CONFIG_NCPFS_NFS_NS=y
  19543. +CONFIG_NCPFS_OS2_NS=y
  19544. +CONFIG_NCPFS_SMALLDOS=y
  19545. +CONFIG_NCPFS_NLS=y
  19546. +CONFIG_NCPFS_EXTRAS=y
  19547. +CONFIG_CODA_FS=m
  19548. +# CONFIG_AFS_FS is not set
  19549. +# CONFIG_AF_RXRPC is not set
  19550. +
  19551. +CONFIG_OCFS2_FS=m
  19552. +# CONFIG_OCFS2_DEBUG_FS is not set
  19553. +# CONFIG_OCFS2_DEBUG_MASKLOG is not set
  19554. +CONFIG_OCFS2_FS_O2CB=m
  19555. +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
  19556. +# CONFIG_OCFS2_FS_STATS is not set
  19557. +
  19558. +CONFIG_BTRFS_FS=m
  19559. +CONFIG_BTRFS_FS_POSIX_ACL=y
  19560. +# Maybe see if we want this on for debug kernels?
  19561. +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
  19562. +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
  19563. +# CONFIG_BTRFS_DEBUG is not set
  19564. +# CONFIG_BTRFS_ASSERT is not set
  19565. +
  19566. +CONFIG_CONFIGFS_FS=y
  19567. +
  19568. +CONFIG_DLM=m
  19569. +CONFIG_DLM_DEBUG=y
  19570. +CONFIG_GFS2_FS=m
  19571. +CONFIG_GFS2_FS_LOCKING_DLM=y
  19572. +
  19573. +
  19574. +CONFIG_UBIFS_FS_XATTR=y
  19575. +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
  19576. +# CONFIG_UBIFS_FS_DEBUG is not set
  19577. +
  19578. +#
  19579. +# Partition Types
  19580. +#
  19581. +CONFIG_PARTITION_ADVANCED=y
  19582. +# CONFIG_ACORN_PARTITION is not set
  19583. +CONFIG_AIX_PARTITION=y
  19584. +CONFIG_AMIGA_PARTITION=y
  19585. +# CONFIG_ATARI_PARTITION is not set
  19586. +CONFIG_BSD_DISKLABEL=y
  19587. +CONFIG_EFI_PARTITION=y
  19588. +CONFIG_KARMA_PARTITION=y
  19589. +CONFIG_LDM_PARTITION=y
  19590. +# CONFIG_LDM_DEBUG is not set
  19591. +CONFIG_MAC_PARTITION=y
  19592. +CONFIG_MSDOS_PARTITION=y
  19593. +CONFIG_MINIX_SUBPARTITION=y
  19594. +CONFIG_OSF_PARTITION=y
  19595. +CONFIG_SGI_PARTITION=y
  19596. +CONFIG_SOLARIS_X86_PARTITION=y
  19597. +CONFIG_SUN_PARTITION=y
  19598. +# CONFIG_SYSV68_PARTITION is not set
  19599. +CONFIG_UNIXWARE_DISKLABEL=y
  19600. +# CONFIG_ULTRIX_PARTITION is not set
  19601. +# CONFIG_CMDLINE_PARTITION is not set
  19602. +
  19603. +CONFIG_NLS=y
  19604. +
  19605. +#
  19606. +# Native Language Support
  19607. +#
  19608. +CONFIG_NLS_CODEPAGE_737=m
  19609. +CONFIG_NLS_CODEPAGE_775=m
  19610. +CONFIG_NLS_CODEPAGE_850=m
  19611. +CONFIG_NLS_CODEPAGE_852=m
  19612. +CONFIG_NLS_CODEPAGE_855=m
  19613. +CONFIG_NLS_CODEPAGE_857=m
  19614. +CONFIG_NLS_CODEPAGE_860=m
  19615. +CONFIG_NLS_CODEPAGE_861=m
  19616. +CONFIG_NLS_CODEPAGE_862=m
  19617. +CONFIG_NLS_CODEPAGE_863=m
  19618. +CONFIG_NLS_CODEPAGE_864=m
  19619. +CONFIG_NLS_CODEPAGE_865=m
  19620. +CONFIG_NLS_CODEPAGE_866=m
  19621. +CONFIG_NLS_CODEPAGE_869=m
  19622. +CONFIG_NLS_CODEPAGE_936=m
  19623. +CONFIG_NLS_CODEPAGE_950=m
  19624. +CONFIG_NLS_CODEPAGE_932=m
  19625. +CONFIG_NLS_CODEPAGE_949=m
  19626. +CONFIG_NLS_CODEPAGE_874=m
  19627. +CONFIG_NLS_ISO8859_8=m
  19628. +CONFIG_NLS_CODEPAGE_1250=m
  19629. +CONFIG_NLS_CODEPAGE_1251=m
  19630. +CONFIG_NLS_ISO8859_2=m
  19631. +CONFIG_NLS_ISO8859_3=m
  19632. +CONFIG_NLS_ISO8859_4=m
  19633. +CONFIG_NLS_ISO8859_5=m
  19634. +CONFIG_NLS_ISO8859_6=m
  19635. +CONFIG_NLS_ISO8859_7=m
  19636. +CONFIG_NLS_ISO8859_9=m
  19637. +CONFIG_NLS_ISO8859_13=m
  19638. +CONFIG_NLS_ISO8859_14=m
  19639. +CONFIG_NLS_KOI8_R=m
  19640. +CONFIG_NLS_KOI8_U=m
  19641. +CONFIG_NLS_MAC_ROMAN=m
  19642. +CONFIG_NLS_MAC_CELTIC=m
  19643. +CONFIG_NLS_MAC_CENTEURO=m
  19644. +CONFIG_NLS_MAC_CROATIAN=m
  19645. +CONFIG_NLS_MAC_CYRILLIC=m
  19646. +CONFIG_NLS_MAC_GAELIC=m
  19647. +CONFIG_NLS_MAC_GREEK=m
  19648. +CONFIG_NLS_MAC_ICELAND=m
  19649. +CONFIG_NLS_MAC_INUIT=m
  19650. +CONFIG_NLS_MAC_ROMANIAN=m
  19651. +CONFIG_NLS_MAC_TURKISH=m
  19652. +
  19653. +#
  19654. +# Profiling support
  19655. +#
  19656. +CONFIG_PROFILING=y
  19657. +CONFIG_OPROFILE=m
  19658. +CONFIG_OPROFILE_EVENT_MULTIPLEX=y
  19659. +
  19660. +#
  19661. +# Kernel hacking
  19662. +#
  19663. +CONFIG_DEBUG_KERNEL=y
  19664. +CONFIG_FRAME_WARN=1024
  19665. +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x0
  19666. +# CONFIG_DEBUG_INFO is not set
  19667. +CONFIG_FRAME_POINTER=y
  19668. +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
  19669. +# CONFIG_DEBUG_DRIVER is not set
  19670. +CONFIG_HEADERS_CHECK=y
  19671. +# CONFIG_LKDTM is not set
  19672. +# CONFIG_NOTIFIER_ERROR_INJECTION is not set
  19673. +# CONFIG_READABLE_ASM is not set
  19674. +
  19675. +# CONFIG_RT_MUTEX_TESTER is not set
  19676. +# CONFIG_DEBUG_LOCKDEP is not set
  19677. +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
  19678. +
  19679. +# DEBUG options that don't get enabled/disabled with 'make debug/release'
  19680. +
  19681. +# This generates a huge amount of dmesg spew
  19682. +# CONFIG_DEBUG_KOBJECT is not set
  19683. +#
  19684. +# This breaks booting until the module patches are in-tree
  19685. +# CONFIG_DEBUG_KOBJECT_RELEASE is not set
  19686. +#
  19687. +#
  19688. +# These debug options are deliberatly left on (even in 'make release' kernels).
  19689. +# They aren't that much of a performance impact, and the value
  19690. +# from getting useful bug-reports makes it worth leaving them on.
  19691. +# CONFIG_DEBUG_HIGHMEM is not set
  19692. +# CONFIG_DEBUG_SHIRQ is not set
  19693. +CONFIG_BOOT_PRINTK_DELAY=y
  19694. +CONFIG_DEBUG_DEVRES=y
  19695. +CONFIG_DEBUG_RODATA_TEST=y
  19696. +CONFIG_DEBUG_NX_TEST=m
  19697. +CONFIG_DEBUG_SET_MODULE_RONX=y
  19698. +CONFIG_DEBUG_BOOT_PARAMS=y
  19699. +# CONFIG_DEBUG_VM is not set
  19700. +# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
  19701. +CONFIG_LOCKUP_DETECTOR=y
  19702. +# CONFIG_DEBUG_INFO_REDUCED is not set
  19703. +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
  19704. +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
  19705. +# CONFIG_PANIC_ON_OOPS is not set
  19706. +CONFIG_PANIC_TIMEOUT=0
  19707. +CONFIG_ATOMIC64_SELFTEST=y
  19708. +CONFIG_MEMORY_FAILURE=y
  19709. +CONFIG_HWPOISON_INJECT=m
  19710. +CONFIG_CROSS_MEMORY_ATTACH=y
  19711. +# CONFIG_DEBUG_SECTION_MISMATCH is not set
  19712. +# CONFIG_BACKTRACE_SELF_TEST is not set
  19713. +CONFIG_RESOURCE_COUNTERS=y
  19714. +# CONFIG_DEBUG_VIRTUAL is not set
  19715. +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
  19716. +CONFIG_EARLY_PRINTK_DBGP=y
  19717. +# CONFIG_PAGE_POISONING is not set
  19718. +# CONFIG_CRASH_DUMP is not set
  19719. +# CONFIG_CRASH is not set
  19720. +# CONFIG_GCOV_KERNEL is not set
  19721. +# CONFIG_RAMOOPS is not set
  19722. +
  19723. +
  19724. +#
  19725. +# Security options
  19726. +#
  19727. +CONFIG_SECURITY=y
  19728. +# CONFIG_SECURITY_DMESG_RESTRICT is not set
  19729. +CONFIG_SECURITY_NETWORK=y
  19730. +CONFIG_SECURITY_NETWORK_XFRM=y
  19731. +# CONFIG_SECURITY_PATH is not set
  19732. +CONFIG_SECURITY_SELINUX=y
  19733. +CONFIG_SECURITY_SELINUX_BOOTPARAM=y
  19734. +CONFIG_SECURITY_SELINUX_DISABLE=y
  19735. +CONFIG_SECURITY_SELINUX_DEVELOP=y
  19736. +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
  19737. +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
  19738. +CONFIG_SECURITY_SELINUX_AVC_STATS=y
  19739. +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
  19740. +# CONFIG_SECURITY_SMACK is not set
  19741. +# CONFIG_SECURITY_TOMOYO is not set
  19742. +# CONFIG_SECURITY_APPARMOR is not set
  19743. +# CONFIG_SECURITY_YAMA is not set
  19744. +CONFIG_AUDIT=y
  19745. +CONFIG_AUDITSYSCALL=y
  19746. +# http://lists.fedoraproject.org/pipermail/kernel/2013-February/004125.html
  19747. +CONFIG_AUDIT_LOGINUID_IMMUTABLE=y
  19748. +
  19749. +CONFIG_SECCOMP=y
  19750. +
  19751. +# CONFIG_SSBI is not set
  19752. +
  19753. +#
  19754. +# Cryptographic options
  19755. +#
  19756. +CONFIG_CRYPTO=y
  19757. +CONFIG_CRYPTO_FIPS=y
  19758. +CONFIG_CRYPTO_USER_API_HASH=y
  19759. +CONFIG_CRYPTO_USER_API_SKCIPHER=y
  19760. +CONFIG_CRYPTO_MANAGER=y
  19761. +# Note, CONFIG_CRYPTO_MANAGER_DISABLE_TESTS needs to be unset, or FIPS will be disabled.
  19762. +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
  19763. +CONFIG_CRYPTO_HW=y
  19764. +CONFIG_CRYPTO_BLKCIPHER=y
  19765. +# CONFIG_CRYPTO_CRYPTD is not set
  19766. +CONFIG_CRYPTO_AES=y
  19767. +CONFIG_CRYPTO_ARC4=m
  19768. +CONFIG_CRYPTO_ANUBIS=m
  19769. +CONFIG_CRYPTO_AUTHENC=m
  19770. +CONFIG_CRYPTO_CAST5=m
  19771. +CONFIG_CRYPTO_CAST6=m
  19772. +CONFIG_CRYPTO_CRC32C=y
  19773. +CONFIG_CRYPTO_CRC32=m
  19774. +CONFIG_CRYPTO_CTR=y
  19775. +CONFIG_CRYPTO_DEFLATE=m
  19776. +CONFIG_CRYPTO_FCRYPT=m
  19777. +CONFIG_CRYPTO_GF128MUL=m
  19778. +CONFIG_CRYPTO_CMAC=m
  19779. +CONFIG_CRYPTO_HMAC=y
  19780. +CONFIG_CRYPTO_KHAZAD=m
  19781. +CONFIG_CRYPTO_LZO=m
  19782. +CONFIG_CRYPTO_LZ4=m
  19783. +CONFIG_CRYPTO_LZ4HC=m
  19784. +CONFIG_CRYPTO_NULL=m
  19785. +CONFIG_CRYPTO_PCBC=m
  19786. +CONFIG_CRYPTO_SALSA20=m
  19787. +CONFIG_CRYPTO_SALSA20_586=m
  19788. +CONFIG_CRYPTO_SEED=m
  19789. +CONFIG_CRYPTO_SEQIV=m
  19790. +CONFIG_CRYPTO_SERPENT=m
  19791. +CONFIG_CRYPTO_TEA=m
  19792. +CONFIG_CRYPTO_XCBC=m
  19793. +CONFIG_CRYPTO_VMAC=m
  19794. +CONFIG_CRYPTO_CRC32C_INTEL=m
  19795. +CONFIG_CRYPTO_GHASH=m
  19796. +CONFIG_CRYPTO_DEV_HIFN_795X=m
  19797. +CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y
  19798. +CONFIG_CRYPTO_PCRYPT=m
  19799. +
  19800. +
  19801. +
  19802. +# Random number generation
  19803. +
  19804. +#
  19805. +# Library routines
  19806. +#
  19807. +CONFIG_CRC16=y
  19808. +CONFIG_CRC32=m
  19809. +# CONFIG_CRC32_SELFTEST is not set
  19810. +CONFIG_CRC_ITU_T=m
  19811. +CONFIG_CRC8=m
  19812. +# CONFIG_RANDOM32_SELFTEST is not set
  19813. +CONFIG_CORDIC=m
  19814. +# CONFIG_DDR is not set
  19815. +
  19816. +CONFIG_CRYPTO_ZLIB=m
  19817. +CONFIG_ZLIB_INFLATE=y
  19818. +CONFIG_ZLIB_DEFLATE=m
  19819. +
  19820. +CONFIG_INITRAMFS_SOURCE=""
  19821. +CONFIG_KEYS=y
  19822. +CONFIG_PERSISTENT_KEYRINGS=y
  19823. +CONFIG_BIG_KEYS=y
  19824. +CONFIG_TRUSTED_KEYS=m
  19825. +CONFIG_ENCRYPTED_KEYS=m
  19826. +CONFIG_KEYS_DEBUG_PROC_KEYS=y
  19827. +CONFIG_CDROM_PKTCDVD=m
  19828. +CONFIG_CDROM_PKTCDVD_BUFFERS=8
  19829. +# CONFIG_CDROM_PKTCDVD_WCACHE is not set
  19830. +
  19831. +CONFIG_ATA_OVER_ETH=m
  19832. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  19833. +CONFIG_BACKLIGHT_CLASS_DEVICE=m
  19834. +# CONFIG_BACKLIGHT_GENERIC is not set
  19835. +CONFIG_BACKLIGHT_PROGEAR=m
  19836. +
  19837. +CONFIG_LCD_CLASS_DEVICE=m
  19838. +CONFIG_LCD_PLATFORM=m
  19839. +
  19840. +CONFIG_FAIR_GROUP_SCHED=y
  19841. +CONFIG_CFS_BANDWIDTH=y
  19842. +CONFIG_SCHED_OMIT_FRAME_POINTER=y
  19843. +CONFIG_RT_GROUP_SCHED=y
  19844. +CONFIG_SCHED_AUTOGROUP=y
  19845. +
  19846. +CONFIG_CPUSETS=y
  19847. +CONFIG_PROC_PID_CPUSET=y
  19848. +
  19849. +# CONFIG_CGROUP_DEBUG is not set
  19850. +CONFIG_CGROUP_CPUACCT=y
  19851. +CONFIG_CGROUP_DEVICE=y
  19852. +CONFIG_CGROUP_FREEZER=y
  19853. +CONFIG_CGROUP_SCHED=y
  19854. +CONFIG_MEMCG=y
  19855. +CONFIG_MEMCG_SWAP=y
  19856. +CONFIG_MEMCG_SWAP_ENABLED=y
  19857. +CONFIG_MEMCG_KMEM=y
  19858. +# CONFIG_CGROUP_HUGETLB is not set
  19859. +CONFIG_CGROUP_PERF=y
  19860. +CONFIG_CGROUP_NET_PRIO=m
  19861. +# CONFIG_CGROUP_NET_CLASSID is not set
  19862. +CONFIG_BLK_CGROUP=y
  19863. +
  19864. +# CONFIG_SYSFS_DEPRECATED is not set
  19865. +# CONFIG_SYSFS_DEPRECATED_V2 is not set
  19866. +
  19867. +CONFIG_PRINTK_TIME=y
  19868. +
  19869. +CONFIG_ENABLE_MUST_CHECK=y
  19870. +# CONFIG_ENABLE_WARN_DEPRECATED is not set
  19871. +
  19872. +CONFIG_KEXEC=y
  19873. +
  19874. +CONFIG_HWMON=y
  19875. +# CONFIG_HWMON_DEBUG_CHIP is not set
  19876. +CONFIG_THERMAL_HWMON=y
  19877. +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
  19878. +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
  19879. +CONFIG_THERMAL_GOV_FAIR_SHARE=y
  19880. +# CONFIG_THERMAL_GOV_USER_SPACE is not set
  19881. +CONFIG_THERMAL_GOV_STEP_WISE=y
  19882. +# CONFIG_THERMAL_EMULATION is not set
  19883. +# CONFIG_THERMAL_OF is not set
  19884. +
  19885. +CONFIG_INOTIFY=y
  19886. +CONFIG_INOTIFY_USER=y
  19887. +
  19888. +#
  19889. +# Bus devices
  19890. +#
  19891. +# CONFIG_OMAP_OCP2SCP is not set
  19892. +CONFIG_PROC_EVENTS=y
  19893. +
  19894. +CONFIG_IBMASR=m
  19895. +
  19896. +CONFIG_PM=y
  19897. +CONFIG_PM_STD_PARTITION=""
  19898. +# CONFIG_DPM_WATCHDOG is not set # revisit this in debug
  19899. +CONFIG_PM_TRACE=y
  19900. +CONFIG_PM_TRACE_RTC=y
  19901. +# CONFIG_PM_OPP is not set
  19902. +# CONFIG_PM_AUTOSLEEP is not set
  19903. +# CONFIG_PM_WAKELOCKS is not set
  19904. +CONFIG_HIBERNATION=y
  19905. +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
  19906. +CONFIG_SUSPEND=y
  19907. +
  19908. +CONFIG_CPU_FREQ_TABLE=y
  19909. +CONFIG_CPU_FREQ_STAT=m
  19910. +CONFIG_CPU_FREQ_STAT_DETAILS=y
  19911. +
  19912. +
  19913. +CONFIG_NET_VENDOR_SMC=y
  19914. +# CONFIG_IBMTR is not set
  19915. +# CONFIG_SKISA is not set
  19916. +# CONFIG_PROTEON is not set
  19917. +# CONFIG_SMCTR is not set
  19918. +
  19919. +# CONFIG_MOUSE_ATIXL is not set
  19920. +
  19921. +# CONFIG_MEDIA_PARPORT_SUPPORT is not set
  19922. +
  19923. +CONFIG_RADIO_TEA5764=m
  19924. +CONFIG_RADIO_SAA7706H=m
  19925. +CONFIG_RADIO_CADET=m
  19926. +CONFIG_RADIO_RTRACK=m
  19927. +CONFIG_RADIO_RTRACK2=m
  19928. +CONFIG_RADIO_AZTECH=m
  19929. +CONFIG_RADIO_GEMTEK=m
  19930. +CONFIG_RADIO_SF16FMI=m
  19931. +CONFIG_RADIO_SF16FMR2=m
  19932. +CONFIG_RADIO_TERRATEC=m
  19933. +CONFIG_RADIO_TRUST=m
  19934. +CONFIG_RADIO_TYPHOON=m
  19935. +CONFIG_RADIO_ZOLTRIX=m
  19936. +
  19937. +CONFIG_SND_DARLA20=m
  19938. +CONFIG_SND_GINA20=m
  19939. +CONFIG_SND_LAYLA20=m
  19940. +CONFIG_SND_DARLA24=m
  19941. +CONFIG_SND_GINA24=m
  19942. +CONFIG_SND_LAYLA24=m
  19943. +CONFIG_SND_MONA=m
  19944. +CONFIG_SND_MIA=m
  19945. +CONFIG_SND_ECHO3G=m
  19946. +CONFIG_SND_INDIGO=m
  19947. +CONFIG_SND_INDIGOIO=m
  19948. +CONFIG_SND_INDIGODJ=m
  19949. +CONFIG_SND_INDIGOIOX=m
  19950. +CONFIG_SND_INDIGODJX=m
  19951. +
  19952. +CONFIG_BALLOON_COMPACTION=y
  19953. +CONFIG_COMPACTION=y
  19954. +CONFIG_MIGRATION=y
  19955. +CONFIG_BOUNCE=y
  19956. +# CONFIG_LEDS_AMS_DELTA is not set
  19957. +# CONFIG_LEDS_LOCOMO is not set
  19958. +# CONFIG_LEDS_NET48XX is not set
  19959. +# CONFIG_LEDS_NET5501 is not set
  19960. +# CONFIG_LEDS_PCA9532 is not set
  19961. +# CONFIG_LEDS_PCA955X is not set
  19962. +# CONFIG_LEDS_BD2802 is not set
  19963. +# CONFIG_LEDS_S3C24XX is not set
  19964. +# CONFIG_LEDS_PCA9633 is not set
  19965. +CONFIG_LEDS_DELL_NETBOOKS=m
  19966. +# CONFIG_LEDS_TCA6507 is not set
  19967. +# CONFIG_LEDS_LM355x is not set
  19968. +# CONFIG_LEDS_OT200 is not set
  19969. +# CONFIG_LEDS_PWM is not set
  19970. +# CONFIG_LEDS_LP8501 is not set
  19971. +# CONFIG_LEDS_PCA963X is not set
  19972. +# CONFIG_LEDS_PCA9685 is not set
  19973. +CONFIG_LEDS_TRIGGER_TIMER=m
  19974. +CONFIG_LEDS_TRIGGER_ONESHOT=m
  19975. +CONFIG_LEDS_TRIGGER_IDE_DISK=y
  19976. +CONFIG_LEDS_TRIGGER_HEARTBEAT=m
  19977. +CONFIG_LEDS_TRIGGER_BACKLIGHT=m
  19978. +# CONFIG_LEDS_TRIGGER_CPU is not set
  19979. +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
  19980. +CONFIG_LEDS_TRIGGER_TRANSIENT=m
  19981. +CONFIG_LEDS_TRIGGER_CAMERA=m
  19982. +CONFIG_LEDS_ALIX2=m
  19983. +CONFIG_LEDS_CLEVO_MAIL=m
  19984. +CONFIG_LEDS_INTEL_SS4200=m
  19985. +CONFIG_LEDS_LM3530=m
  19986. +# CONFIG_LEDS_LM3642 is not set
  19987. +CONFIG_LEDS_LM3556=m
  19988. +CONFIG_LEDS_BLINKM=m
  19989. +CONFIG_LEDS_LP3944=m
  19990. +CONFIG_LEDS_LP5521=m
  19991. +CONFIG_LEDS_LP5523=m
  19992. +CONFIG_LEDS_LP5562=m
  19993. +CONFIG_LEDS_LT3593=m
  19994. +CONFIG_LEDS_REGULATOR=m
  19995. +CONFIG_LEDS_WM8350=m
  19996. +CONFIG_LEDS_WM831X_STATUS=m
  19997. +
  19998. +CONFIG_DMA_ENGINE=y
  19999. +CONFIG_DW_DMAC_CORE=m
  20000. +CONFIG_DW_DMAC=m
  20001. +CONFIG_DW_DMAC_PCI=m
  20002. +# CONFIG_DW_DMAC_BIG_ENDIAN_IO is not set
  20003. +# CONFIG_TIMB_DMA is not set
  20004. +# CONFIG_DMATEST is not set
  20005. +CONFIG_ASYNC_TX_DMA=y
  20006. +
  20007. +CONFIG_UNUSED_SYMBOLS=y
  20008. +
  20009. +CONFIG_UPROBE_EVENT=y
  20010. +
  20011. +CONFIG_DYNAMIC_FTRACE=y
  20012. +# CONFIG_IRQSOFF_TRACER is not set
  20013. +CONFIG_SCHED_TRACER=y
  20014. +CONFIG_CONTEXT_SWITCH_TRACER=y
  20015. +CONFIG_TRACER_SNAPSHOT=y
  20016. +# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set
  20017. +CONFIG_FTRACE_SYSCALLS=y
  20018. +CONFIG_FTRACE_MCOUNT_RECORD=y
  20019. +# CONFIG_FTRACE_STARTUP_TEST is not set
  20020. +# CONFIG_TRACE_BRANCH_PROFILING is not set
  20021. +CONFIG_FUNCTION_PROFILER=y
  20022. +CONFIG_RING_BUFFER_BENCHMARK=m
  20023. +# CONFIG_RING_BUFFER_STARTUP_TEST is not set
  20024. +# CONFIG_RBTREE_TEST is not set
  20025. +# CONFIG_INTERVAL_TREE_TEST is not set
  20026. +CONFIG_FUNCTION_TRACER=y
  20027. +CONFIG_STACK_TRACER=y
  20028. +# CONFIG_FUNCTION_GRAPH_TRACER is not set
  20029. +
  20030. +CONFIG_KPROBES=y
  20031. +CONFIG_KPROBE_EVENT=y
  20032. +# CONFIG_KPROBES_SANITY_TEST is not set
  20033. +CONFIG_JUMP_LABEL=y
  20034. +CONFIG_OPTPROBES=y
  20035. +
  20036. +CONFIG_HZ_1000=y
  20037. +
  20038. +CONFIG_TIMER_STATS=y
  20039. +CONFIG_PERF_COUNTERS=y
  20040. +
  20041. +# Auxillary displays
  20042. +CONFIG_KS0108=m
  20043. +CONFIG_KS0108_PORT=0x378
  20044. +CONFIG_KS0108_DELAY=2
  20045. +CONFIG_CFAG12864B=y
  20046. +CONFIG_CFAG12864B_RATE=20
  20047. +
  20048. +# CONFIG_PHANTOM is not set
  20049. +
  20050. +# CONFIG_POWER_SUPPLY_DEBUG is not set
  20051. +
  20052. +# CONFIG_TEST_POWER is not set
  20053. +CONFIG_APM_POWER=m
  20054. +# CONFIG_GENERIC_ADC_BATTERY is not set
  20055. +# CONFIG_WM831X_POWER is not set
  20056. +
  20057. +# CONFIG_BATTERY_DS2760 is not set
  20058. +# CONFIG_BATTERY_DS2781 is not set
  20059. +# CONFIG_BATTERY_DS2782 is not set
  20060. +# CONFIG_BATTERY_SBS is not set
  20061. +# CONFIG_BATTERY_BQ20Z75 is not set
  20062. +# CONFIG_BATTERY_DS2780 is not set
  20063. +# CONFIG_BATTERY_BQ27x00 is not set
  20064. +# CONFIG_BATTERY_MAX17040 is not set
  20065. +# CONFIG_BATTERY_MAX17042 is not set
  20066. +# CONFIG_BATTERY_GOLDFISH is not set
  20067. +
  20068. +# CONFIG_CHARGER_ISP1704 is not set
  20069. +# CONFIG_CHARGER_MAX8903 is not set
  20070. +# CONFIG_CHARGER_LP8727 is not set
  20071. +# CONFIG_CHARGER_GPIO is not set
  20072. +# CONFIG_CHARGER_PCF50633 is not set
  20073. +# CONFIG_CHARGER_BQ2415X is not set
  20074. +# CONFIG_CHARGER_BQ24190 is not set
  20075. +# CONFIG_CHARGER_BQ24735 is not set
  20076. +CONFIG_POWER_RESET=y
  20077. +
  20078. +# CONFIG_PDA_POWER is not set
  20079. +
  20080. +CONFIG_AUXDISPLAY=y
  20081. +
  20082. +CONFIG_UIO=m
  20083. +CONFIG_UIO_CIF=m
  20084. +# CONFIG_UIO_PDRV is not set
  20085. +# CONFIG_UIO_PDRV_GENIRQ is not set
  20086. +# CONFIG_UIO_DMEM_GENIRQ is not set
  20087. +CONFIG_UIO_AEC=m
  20088. +CONFIG_UIO_SERCOS3=m
  20089. +CONFIG_UIO_PCI_GENERIC=m
  20090. +# CONFIG_UIO_NETX is not set
  20091. +# CONFIG_UIO_MF624 is not set
  20092. +
  20093. +CONFIG_VFIO=m
  20094. +CONFIG_VFIO_IOMMU_TYPE1=m
  20095. +CONFIG_VFIO_PCI=m
  20096. +
  20097. +
  20098. +# LIRC
  20099. +CONFIG_LIRC_STAGING=y
  20100. +CONFIG_LIRC_BT829=m
  20101. +CONFIG_LIRC_IGORPLUGUSB=m
  20102. +CONFIG_LIRC_IMON=m
  20103. +CONFIG_LIRC_ZILOG=m
  20104. +CONFIG_LIRC_PARALLEL=m
  20105. +CONFIG_LIRC_SERIAL=m
  20106. +CONFIG_LIRC_SERIAL_TRANSMITTER=y
  20107. +CONFIG_LIRC_SASEM=m
  20108. +CONFIG_LIRC_SIR=m
  20109. +CONFIG_LIRC_TTUSBIR=m
  20110. +
  20111. +# CONFIG_SAMPLES is not set
  20112. +
  20113. +
  20114. +CONFIG_NOZOMI=m
  20115. +# CONFIG_TPS65010 is not set
  20116. +
  20117. +CONFIG_INPUT_APANEL=m
  20118. +CONFIG_INPUT_GP2A=m
  20119. +# CONFIG_INPUT_GPIO_TILT_POLLED is not set
  20120. +# CONFIG_INPUT_GPIO_BEEPER is not set
  20121. +
  20122. +# CONFIG_INTEL_MENLOW is not set
  20123. +CONFIG_ENCLOSURE_SERVICES=m
  20124. +CONFIG_IPWIRELESS=m
  20125. +
  20126. +# CONFIG_BLK_DEV_XIP is not set
  20127. +CONFIG_MEMSTICK=m
  20128. +# CONFIG_MEMSTICK_DEBUG is not set
  20129. +# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
  20130. +CONFIG_MSPRO_BLOCK=m
  20131. +# CONFIG_MS_BLOCK is not set
  20132. +CONFIG_MEMSTICK_TIFM_MS=m
  20133. +CONFIG_MEMSTICK_JMICRON_38X=m
  20134. +CONFIG_MEMSTICK_R592=m
  20135. +CONFIG_MEMSTICK_REALTEK_PCI=m
  20136. +
  20137. +CONFIG_ACCESSIBILITY=y
  20138. +CONFIG_A11Y_BRAILLE_CONSOLE=y
  20139. +
  20140. +# CONFIG_HTC_PASIC3 is not set
  20141. +
  20142. +# MT9V022_PCA9536_SWITCH is not set
  20143. +
  20144. +CONFIG_OPTIMIZE_INLINING=y
  20145. +
  20146. +# FIXME: This should be x86/ia64 only
  20147. +# CONFIG_HP_ILO is not set
  20148. +
  20149. +CONFIG_GPIOLIB=y
  20150. +# CONFIG_PINCTRL is not set
  20151. +# CONFIG_DEBUG_PINCTRL is not set
  20152. +# CONFIG_PINMUX is not set
  20153. +# CONFIG_PINCONF is not set
  20154. +
  20155. +CONFIG_NET_DSA=m
  20156. +CONFIG_NET_DSA_MV88E6060=m
  20157. +CONFIG_NET_DSA_MV88E6131=m
  20158. +CONFIG_NET_DSA_MV88E6123_61_65=m
  20159. +
  20160. +# Used by Maemo, we don't care.
  20161. +# CONFIG_PHONET is not set
  20162. +
  20163. +# CONFIG_ICS932S401 is not set
  20164. +# CONFIG_ATMEL_SSC is not set
  20165. +
  20166. +# CONFIG_C2PORT is not set
  20167. +
  20168. +# CONFIG_REGULATOR_DEBUG is not set
  20169. +
  20170. +CONFIG_WM8350_POWER=m
  20171. +
  20172. +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
  20173. +
  20174. +CONFIG_USB_WUSB=m
  20175. +CONFIG_USB_WUSB_CBAF=m
  20176. +# CONFIG_USB_WUSB_CBAF_DEBUG is not set
  20177. +CONFIG_USB_WHCI_HCD=m
  20178. +CONFIG_USB_HWA_HCD=m
  20179. +# CONFIG_USB_HCD_BCMA is not set
  20180. +# CONFIG_USB_HCD_SSB is not set
  20181. +
  20182. +CONFIG_UWB=m
  20183. +CONFIG_UWB_HWA=m
  20184. +CONFIG_UWB_WHCI=m
  20185. +CONFIG_UWB_I1480U=m
  20186. +
  20187. +# CONFIG_ANDROID is not set
  20188. +CONFIG_STAGING_MEDIA=y
  20189. +# CONFIG_DVB_AS102 is not set
  20190. +# CONFIG_ET131X is not set
  20191. +# CONFIG_SLICOSS is not set
  20192. +# CONFIG_WLAGS49_H2 is not set
  20193. +# CONFIG_WLAGS49_H25 is not set
  20194. +# CONFIG_VIDEO_DT3155 is not set
  20195. +# CONFIG_TI_ST is not set
  20196. +# CONFIG_FB_XGI is not set
  20197. +# CONFIG_VIDEO_GO7007 is not set
  20198. +# CONFIG_I2C_BCM2048 is not set
  20199. +# CONFIG_VIDEO_TCM825X is not set
  20200. +# CONFIG_VIDEO_OMAP4 is not set
  20201. +# CONFIG_USB_MSI3101 is not set
  20202. +# CONFIG_DT3155 is not set
  20203. +# CONFIG_W35UND is not set
  20204. +# CONFIG_PRISM2_USB is not set
  20205. +# CONFIG_ECHO is not set
  20206. +CONFIG_USB_ATMEL=m
  20207. +# CONFIG_COMEDI is not set
  20208. +# CONFIG_ASUS_OLED is not set
  20209. +# CONFIG_PANEL is not set
  20210. +# CONFIG_TRANZPORT is not set
  20211. +# CONFIG_POHMELFS is not set
  20212. +# CONFIG_IDE_PHISON is not set
  20213. +# CONFIG_LINE6_USB is not set
  20214. +# CONFIG_VME_BUS is not set
  20215. +# CONFIG_RAR_REGISTER is not set
  20216. +# CONFIG_VT6656 is not set
  20217. +# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
  20218. +# Larry Finger maintains these (rhbz 913753)
  20219. +CONFIG_RTLLIB=m
  20220. +CONFIG_RTLLIB_CRYPTO_CCMP=m
  20221. +CONFIG_RTLLIB_CRYPTO_TKIP=m
  20222. +CONFIG_RTLLIB_CRYPTO_WEP=m
  20223. +CONFIG_RTL8192E=m
  20224. +# CONFIG_INPUT_GPIO is not set
  20225. +# CONFIG_VIDEO_CX25821 is not set
  20226. +# CONFIG_R8187SE is not set
  20227. +# CONFIG_R8188EU is not set
  20228. +# CONFIG_R8821AE is not set
  20229. +# CONFIG_RTL8192U is not set
  20230. +# CONFIG_FB_SM7XX is not set
  20231. +# CONFIG_SPECTRA is not set
  20232. +# CONFIG_EASYCAP is not set
  20233. +# CONFIG_SOLO6X10 is not set
  20234. +# CONFIG_ACPI_QUICKSTART is not set
  20235. +# CONFIG_LTE_GDM724X is not set
  20236. +CONFIG_R8712U=m # Larry Finger maintains this (rhbz 699618)
  20237. +# CONFIG_R8712_AP is not set
  20238. +# CONFIG_ATH6K_LEGACY is not set
  20239. +# CONFIG_USB_ENESTORAGE is not set
  20240. +# CONFIG_BCM_WIMAX is not set
  20241. +# CONFIG_USB_BTMTK is not set
  20242. +# CONFIG_FT1000 is not set
  20243. +# CONFIG_SPEAKUP is not set
  20244. +# CONFIG_DX_SEP is not set
  20245. +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
  20246. +# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
  20247. +# CONFIG_RTS_PSTOR is not set
  20248. +CONFIG_ALTERA_STAPL=m
  20249. +# CONFIG_DVB_CXD2099 is not set
  20250. +# CONFIG_USBIP_CORE is not set
  20251. +# CONFIG_INTEL_MEI is not set
  20252. +# CONFIG_ZCACHE is not set
  20253. +# CONFIG_RTS5139 is not set
  20254. +# CONFIG_NVEC_LEDS is not set
  20255. +# CONFIG_VT6655 is not set
  20256. +# CONFIG_RAMSTER is not set
  20257. +# CONFIG_USB_WPAN_HCD is not set
  20258. +# CONFIG_WIMAX_GDM72XX is not set
  20259. +# CONFIG_IPACK_BUS is not set
  20260. +# CONFIG_CSR_WIFI is not set
  20261. +# CONFIG_ZCACHE2 is not set
  20262. +# CONFIG_NET_VENDOR_SILICOM is not set
  20263. +# CONFIG_SBYPASS is not set
  20264. +# CONFIG_BPCTL is not set
  20265. +# CONFIG_CED1401 is not set
  20266. +# CONFIG_DGRP is not set
  20267. +# CONFIG_SB105X is not set
  20268. +# CONFIG_LUSTRE_FS is not set
  20269. +# CONFIG_XILLYBUS is not set
  20270. +# CONFIG_DGAP is not set
  20271. +# CONFIG_DGNC is not set
  20272. +# CONFIG_RTS5208 is not set
  20273. +# END OF STAGING
  20274. +
  20275. +#
  20276. +# Remoteproc drivers (EXPERIMENTAL)
  20277. +#
  20278. +# CONFIG_STE_MODEM_RPROC is not set
  20279. +
  20280. +CONFIG_LIBFC=m
  20281. +CONFIG_LIBFCOE=m
  20282. +CONFIG_FCOE=m
  20283. +CONFIG_FCOE_FNIC=m
  20284. +
  20285. +
  20286. +# CONFIG_IMA is not set
  20287. +CONFIG_IMA_MEASURE_PCR_IDX=10
  20288. +CONFIG_IMA_AUDIT=y
  20289. +CONFIG_IMA_LSM_RULES=y
  20290. +
  20291. +# CONFIG_EVM is not set
  20292. +# CONFIG_PWM_PCA9685 is not set
  20293. +
  20294. +CONFIG_LSM_MMAP_MIN_ADDR=65536
  20295. +
  20296. +CONFIG_STRIP_ASM_SYMS=y
  20297. +
  20298. +# CONFIG_RCU_FANOUT_EXACT is not set
  20299. +# FIXME: Revisit FAST_NO_HZ after it's fixed
  20300. +# CONFIG_RCU_FAST_NO_HZ is not set
  20301. +# CONFIG_RCU_NOCB_CPU is not set
  20302. +CONFIG_RCU_CPU_STALL_TIMEOUT=60
  20303. +# CONFIG_RCU_TORTURE_TEST is not set
  20304. +# CONFIG_RCU_TRACE is not set
  20305. +# CONFIG_RCU_CPU_STALL_INFO is not set
  20306. +# CONFIG_RCU_USER_QS is not set
  20307. +
  20308. +CONFIG_KSM=y
  20309. +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
  20310. +
  20311. +CONFIG_FSNOTIFY=y
  20312. +CONFIG_FANOTIFY=y
  20313. +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
  20314. +
  20315. +CONFIG_IEEE802154=m
  20316. +CONFIG_IEEE802154_6LOWPAN=m
  20317. +CONFIG_IEEE802154_DRIVERS=m
  20318. +CONFIG_IEEE802154_FAKEHARD=m
  20319. +CONFIG_IEEE802154_FAKELB=m
  20320. +
  20321. +CONFIG_MAC802154=m
  20322. +CONFIG_NET_MPLS_GSO=m
  20323. +
  20324. +# CONFIG_HSR is not set
  20325. +
  20326. +# CONFIG_EXTCON is not set
  20327. +# CONFIG_EXTCON_ADC_JACK is not set
  20328. +# CONFIG_MEMORY is not set
  20329. +
  20330. +CONFIG_PPS=m
  20331. +# CONFIG_PPS_CLIENT_KTIMER is not set
  20332. +CONFIG_PPS_CLIENT_LDISC=m
  20333. +# CONFIG_PPS_DEBUG is not set
  20334. +CONFIG_PPS_CLIENT_PARPORT=m
  20335. +CONFIG_PPS_GENERATOR_PARPORT=m
  20336. +CONFIG_PPS_CLIENT_GPIO=m
  20337. +CONFIG_NTP_PPS=y
  20338. +
  20339. +CONFIG_PTP_1588_CLOCK=m
  20340. +CONFIG_PTP_1588_CLOCK_PCH=m
  20341. +
  20342. +CONFIG_CLEANCACHE=y
  20343. +CONFIG_FRONTSWAP=y
  20344. +CONFIG_ZSWAP=y
  20345. +CONFIG_ZSMALLOC=y
  20346. +# CONFIG_PGTABLE_MAPPING is not set
  20347. +
  20348. +# CONFIG_MDIO_GPIO is not set
  20349. +# CONFIG_KEYBOARD_GPIO_POLLED is not set
  20350. +# CONFIG_MOUSE_GPIO is not set
  20351. +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
  20352. +# CONFIG_I2C_DESIGNWARE_PCI is not set
  20353. +# CONFIG_I2C_GPIO is not set
  20354. +# CONFIG_DEBUG_GPIO is not set
  20355. +# CONFIG_GPIO_GENERIC_PLATFORM is not set
  20356. +# CONFIG_GPIO_CS5535 is not set
  20357. +# CONFIG_GPIO_IT8761E is not set
  20358. +# CONFIG SB105x is not set
  20359. +# CONFIG_GPIO_TS5500 is not set
  20360. +CONFIG_GPIO_VIPERBOARD=m
  20361. +# CONFIG_UCB1400_CORE is not set
  20362. +# CONFIG_TPS6105X is not set
  20363. +# CONFIG_RADIO_MIROPCM20 is not set
  20364. +# CONFIG_USB_GPIO_VBUS is not set
  20365. +# CONFIG_GPIO_SCH is not set
  20366. +# CONFIG_GPIO_LANGWELL is not set
  20367. +# CONFIG_GPIO_RDC321X is not set
  20368. +# CONFIG_GPIO_VX855 is not set
  20369. +# CONFIG_GPIO_PCH is not set
  20370. +# CONFIG_GPIO_ML_IOH is not set
  20371. +# CONFIG_GPIO_AMD8111 is not set
  20372. +# CONFIG_GPIO_BT8XX is not set
  20373. +# CONFIG_GPIO_GRGPIO is not set
  20374. +# CONFIG_GPIO_PL061 is not set
  20375. +# CONFIG_GPIO_BCM_KONA is not set
  20376. +# CONFIG_GPIO_SCH311X is not set
  20377. +CONFIG_GPIO_MAX730X=m
  20378. +CONFIG_GPIO_MAX7300=m
  20379. +CONFIG_GPIO_MAX732X=m
  20380. +CONFIG_GPIO_PCF857X=m
  20381. +CONFIG_GPIO_SX150X=y
  20382. +CONFIG_GPIO_ADP5588=m
  20383. +CONFIG_GPIO_ADNP=m
  20384. +CONFIG_GPIO_MAX7301=m
  20385. +CONFIG_GPIO_MCP23S08=m
  20386. +CONFIG_GPIO_MC33880=m
  20387. +CONFIG_GPIO_74X164=m
  20388. +
  20389. +# FIXME: Why?
  20390. +CONFIG_EVENT_POWER_TRACING_DEPRECATED=y
  20391. +
  20392. +CONFIG_TEST_KSTRTOX=y
  20393. +CONFIG_XZ_DEC=y
  20394. +CONFIG_XZ_DEC_X86=y
  20395. +CONFIG_XZ_DEC_POWERPC=y
  20396. +# CONFIG_XZ_DEC_IA64 is not set
  20397. +CONFIG_XZ_DEC_ARM=y
  20398. +# CONFIG_XZ_DEC_ARMTHUMB is not set
  20399. +# CONFIG_XZ_DEC_SPARC is not set
  20400. +# CONFIG_XZ_DEC_TEST is not set
  20401. +
  20402. +# CONFIG_POWER_AVS is not set
  20403. +
  20404. +CONFIG_TARGET_CORE=m
  20405. +CONFIG_ISCSI_TARGET=m
  20406. +CONFIG_LOOPBACK_TARGET=m
  20407. +CONFIG_SBP_TARGET=m
  20408. +CONFIG_TCM_IBLOCK=m
  20409. +CONFIG_TCM_FILEIO=m
  20410. +CONFIG_TCM_PSCSI=m
  20411. +CONFIG_TCM_FC=m
  20412. +
  20413. +CONFIG_HWSPINLOCK=m
  20414. +
  20415. +CONFIG_PSTORE=y
  20416. +CONFIG_PSTORE_RAM=m
  20417. +# CONFIG_PSTORE_CONSOLE is not set
  20418. +# CONFIG_PSTORE_FTRACE is not set
  20419. +
  20420. +# CONFIG_TEST_MODULE is not set
  20421. +# CONFIG_TEST_USER_COPY is not set
  20422. +
  20423. +# CONFIG_AVERAGE is not set
  20424. +# CONFIG_VMXNET3 is not set
  20425. +
  20426. +# CONFIG_SIGMA is not set
  20427. +
  20428. +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
  20429. +
  20430. +CONFIG_BCMA=m
  20431. +CONFIG_BCMA_BLOCKIO=y
  20432. +CONFIG_BCMA_HOST_PCI_POSSIBLE=y
  20433. +CONFIG_BCMA_HOST_PCI=y
  20434. +# CONFIG_BCMA_HOST_SOC is not set
  20435. +CONFIG_BCMA_DRIVER_GMAC_CMN=y
  20436. +CONFIG_BCMA_DRIVER_GPIO=y
  20437. +# CONFIG_BCMA_DEBUG is not set
  20438. +
  20439. +# CONFIG_GOOGLE_FIRMWARE is not set
  20440. +# CONFIG_INTEL_MID_PTI is not set
  20441. +
  20442. +# CONFIG_MAILBOX is not set
  20443. +
  20444. +CONFIG_FMC=m
  20445. +CONFIG_FMC_FAKEDEV=m
  20446. +CONFIG_FMC_TRIVIAL=m
  20447. +CONFIG_FMC_WRITE_EEPROM=m
  20448. +CONFIG_FMC_CHARDEV=m
  20449. +
  20450. +# CONFIG_GENWQE is not set
  20451. +
  20452. +# CONFIG_POWERCAP is not set
  20453. +
  20454. +# CONFIG_HSI is not set
  20455. +
  20456. +
  20457. +# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set
  20458. +
  20459. +# CONFIG_PM_DEVFREQ is not set
  20460. +# CONFIG_MODULE_SIG is not set
  20461. +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set
  20462. +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
  20463. +# CONFIG_MODULE_VERIFY_ELF is not set
  20464. +# CONFIG_CRYPTO_KEY_TYPE is not set
  20465. +# CONFIG_PGP_LIBRARY is not set
  20466. +# CONFIG_PGP_PRELOAD is not set
  20467. +# CONFIG_LOCALVERSION_AUTO is not set
  20468. +CONFIG_PROC_DEVICETREE=y
  20469. +
  20470. diff -Nur linux-3.14.15/arch/arm/configs/imx_v7_defconfig linux-linaro-stable-mx6/arch/arm/configs/imx_v7_defconfig
  20471. --- linux-3.14.15/arch/arm/configs/imx_v7_defconfig 1970-01-01 01:00:00.000000000 +0100
  20472. +++ linux-linaro-stable-mx6/arch/arm/configs/imx_v7_defconfig 2014-08-20 19:31:39.968842564 +0200
  20473. @@ -0,0 +1,343 @@
  20474. +# CONFIG_LOCALVERSION_AUTO is not set
  20475. +CONFIG_KERNEL_LZO=y
  20476. +CONFIG_SYSVIPC=y
  20477. +CONFIG_NO_HZ=y
  20478. +CONFIG_HIGH_RES_TIMERS=y
  20479. +CONFIG_LOG_BUF_SHIFT=18
  20480. +CONFIG_CGROUPS=y
  20481. +CONFIG_RELAY=y
  20482. +CONFIG_BLK_DEV_INITRD=y
  20483. +CONFIG_EXPERT=y
  20484. +CONFIG_PERF_EVENTS=y
  20485. +# CONFIG_SLUB_DEBUG is not set
  20486. +# CONFIG_COMPAT_BRK is not set
  20487. +CONFIG_MODULES=y
  20488. +CONFIG_MODULE_UNLOAD=y
  20489. +CONFIG_MODVERSIONS=y
  20490. +CONFIG_MODULE_SRCVERSION_ALL=y
  20491. +# CONFIG_BLK_DEV_BSG is not set
  20492. +CONFIG_GPIO_PCA953X=y
  20493. +CONFIG_ARCH_MXC=y
  20494. +CONFIG_MXC_DEBUG_BOARD=y
  20495. +CONFIG_MACH_IMX51_DT=y
  20496. +CONFIG_MACH_EUKREA_CPUIMX51SD=y
  20497. +CONFIG_SOC_IMX53=y
  20498. +CONFIG_SOC_IMX6Q=y
  20499. +CONFIG_SOC_IMX6SL=y
  20500. +CONFIG_SOC_VF610=y
  20501. +# CONFIG_SWP_EMULATE is not set
  20502. +CONFIG_SMP=y
  20503. +CONFIG_VMSPLIT_2G=y
  20504. +CONFIG_PREEMPT=y
  20505. +CONFIG_AEABI=y
  20506. +# CONFIG_OABI_COMPAT is not set
  20507. +CONFIG_HIGHMEM=y
  20508. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  20509. +CONFIG_CPU_FREQ=y
  20510. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  20511. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  20512. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  20513. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  20514. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  20515. +CONFIG_ARM_IMX6_CPUFREQ=y
  20516. +CONFIG_CPU_IDLE=y
  20517. +CONFIG_VFP=y
  20518. +CONFIG_NEON=y
  20519. +CONFIG_BINFMT_MISC=m
  20520. +CONFIG_PM_RUNTIME=y
  20521. +CONFIG_PM_DEBUG=y
  20522. +CONFIG_PM_TEST_SUSPEND=y
  20523. +CONFIG_NET=y
  20524. +CONFIG_PACKET=y
  20525. +CONFIG_UNIX=y
  20526. +CONFIG_INET=y
  20527. +CONFIG_IP_PNP=y
  20528. +CONFIG_IP_PNP_DHCP=y
  20529. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  20530. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  20531. +# CONFIG_INET_XFRM_MODE_BEET is not set
  20532. +# CONFIG_INET_LRO is not set
  20533. +CONFIG_IPV6=y
  20534. +CONFIG_NETFILTER=y
  20535. +CONFIG_VLAN_8021Q=y
  20536. +# CONFIG_WIRELESS is not set
  20537. +CONFIG_DEVTMPFS=y
  20538. +CONFIG_DEVTMPFS_MOUNT=y
  20539. +# CONFIG_STANDALONE is not set
  20540. +CONFIG_CMA=y
  20541. +CONFIG_CMA_SIZE_MBYTES=320
  20542. +CONFIG_IMX_WEIM=y
  20543. +CONFIG_CONNECTOR=y
  20544. +CONFIG_MTD=y
  20545. +CONFIG_MTD_CMDLINE_PARTS=y
  20546. +CONFIG_MTD_BLOCK=y
  20547. +CONFIG_MTD_CFI=y
  20548. +CONFIG_MTD_JEDECPROBE=y
  20549. +CONFIG_MTD_CFI_INTELEXT=y
  20550. +CONFIG_MTD_CFI_AMDSTD=y
  20551. +CONFIG_MTD_CFI_STAA=y
  20552. +CONFIG_MTD_PHYSMAP_OF=y
  20553. +CONFIG_MTD_DATAFLASH=y
  20554. +CONFIG_MTD_M25P80=y
  20555. +CONFIG_MTD_SST25L=y
  20556. +CONFIG_MTD_NAND=y
  20557. +CONFIG_MTD_NAND_GPMI_NAND=y
  20558. +CONFIG_MTD_NAND_MXC=y
  20559. +CONFIG_MTD_UBI=y
  20560. +CONFIG_BLK_DEV_LOOP=y
  20561. +CONFIG_BLK_DEV_RAM=y
  20562. +CONFIG_BLK_DEV_RAM_SIZE=65536
  20563. +CONFIG_EEPROM_AT24=y
  20564. +CONFIG_EEPROM_AT25=y
  20565. +# CONFIG_SCSI_PROC_FS is not set
  20566. +CONFIG_BLK_DEV_SD=y
  20567. +CONFIG_SCSI_MULTI_LUN=y
  20568. +CONFIG_SCSI_CONSTANTS=y
  20569. +CONFIG_SCSI_LOGGING=y
  20570. +CONFIG_SCSI_SCAN_ASYNC=y
  20571. +# CONFIG_SCSI_LOWLEVEL is not set
  20572. +CONFIG_ATA=y
  20573. +CONFIG_SATA_AHCI_PLATFORM=y
  20574. +CONFIG_AHCI_IMX=y
  20575. +CONFIG_PATA_IMX=y
  20576. +CONFIG_NETDEVICES=y
  20577. +# CONFIG_NET_VENDOR_BROADCOM is not set
  20578. +CONFIG_CS89x0=y
  20579. +CONFIG_CS89x0_PLATFORM=y
  20580. +# CONFIG_NET_VENDOR_FARADAY is not set
  20581. +# CONFIG_NET_VENDOR_INTEL is not set
  20582. +# CONFIG_NET_VENDOR_MARVELL is not set
  20583. +# CONFIG_NET_VENDOR_MICREL is not set
  20584. +# CONFIG_NET_VENDOR_MICROCHIP is not set
  20585. +# CONFIG_NET_VENDOR_NATSEMI is not set
  20586. +# CONFIG_NET_VENDOR_SEEQ is not set
  20587. +CONFIG_SMC91X=y
  20588. +CONFIG_SMC911X=y
  20589. +CONFIG_SMSC911X=y
  20590. +# CONFIG_NET_VENDOR_STMICRO is not set
  20591. +# CONFIG_WLAN is not set
  20592. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  20593. +CONFIG_INPUT_EVDEV=y
  20594. +CONFIG_INPUT_EVBUG=m
  20595. +CONFIG_KEYBOARD_GPIO=y
  20596. +CONFIG_KEYBOARD_IMX=y
  20597. +CONFIG_MOUSE_PS2=m
  20598. +CONFIG_MOUSE_PS2_ELANTECH=y
  20599. +CONFIG_INPUT_TOUCHSCREEN=y
  20600. +CONFIG_TOUCHSCREEN_EGALAX=y
  20601. +CONFIG_TOUCHSCREEN_EGALAX_SINGLE_TOUCH=y
  20602. +CONFIG_TOUCHSCREEN_MAX11801=y
  20603. +CONFIG_TOUCHSCREEN_MC13783=y
  20604. +CONFIG_INPUT_MISC=y
  20605. +CONFIG_INPUT_MMA8450=y
  20606. +CONFIG_INPUT_ISL29023=y
  20607. +CONFIG_SERIO_SERPORT=m
  20608. +CONFIG_VT_HW_CONSOLE_BINDING=y
  20609. +# CONFIG_LEGACY_PTYS is not set
  20610. +# CONFIG_DEVKMEM is not set
  20611. +CONFIG_SERIAL_IMX=y
  20612. +CONFIG_SERIAL_IMX_CONSOLE=y
  20613. +CONFIG_SERIAL_FSL_LPUART=y
  20614. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  20615. +CONFIG_FSL_OTP=y
  20616. +# CONFIG_I2C_COMPAT is not set
  20617. +CONFIG_I2C_CHARDEV=y
  20618. +# CONFIG_I2C_HELPER_AUTO is not set
  20619. +CONFIG_I2C_ALGOPCF=m
  20620. +CONFIG_I2C_ALGOPCA=m
  20621. +CONFIG_I2C_IMX=y
  20622. +CONFIG_SPI=y
  20623. +CONFIG_SPI_IMX=y
  20624. +CONFIG_GPIO_SYSFS=y
  20625. +CONFIG_POWER_SUPPLY=y
  20626. +CONFIG_SABRESD_MAX8903=y
  20627. +CONFIG_IMX6_USB_CHARGER=y
  20628. +CONFIG_SENSORS_MAG3110=y
  20629. +CONFIG_THERMAL=y
  20630. +CONFIG_CPU_THERMAL=y
  20631. +CONFIG_IMX_THERMAL=y
  20632. +CONFIG_DEVICE_THERMAL=y
  20633. +CONFIG_WATCHDOG=y
  20634. +CONFIG_IMX2_WDT=y
  20635. +CONFIG_MFD_DA9052_I2C=y
  20636. +CONFIG_MFD_MC13XXX_SPI=y
  20637. +CONFIG_MFD_MC13XXX_I2C=y
  20638. +CONFIG_MFD_SI476X_CORE=y
  20639. +CONFIG_REGULATOR=y
  20640. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  20641. +CONFIG_REGULATOR_DA9052=y
  20642. +CONFIG_REGULATOR_ANATOP=y
  20643. +CONFIG_REGULATOR_MC13783=y
  20644. +CONFIG_REGULATOR_MC13892=y
  20645. +CONFIG_REGULATOR_PFUZE100=y
  20646. +CONFIG_MEDIA_SUPPORT=y
  20647. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  20648. +CONFIG_MEDIA_RADIO_SUPPORT=y
  20649. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  20650. +CONFIG_MEDIA_USB_SUPPORT=y
  20651. +CONFIG_USB_VIDEO_CLASS=m
  20652. +CONFIG_V4L_PLATFORM_DRIVERS=y
  20653. +CONFIG_VIDEO_MXC_OUTPUT=y
  20654. +CONFIG_VIDEO_MXC_CAPTURE=m
  20655. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  20656. +CONFIG_MXC_CAMERA_OV5640=m
  20657. +CONFIG_MXC_CAMERA_OV5642=m
  20658. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  20659. +CONFIG_MXC_TVIN_ADV7180=m
  20660. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  20661. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  20662. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  20663. +CONFIG_SOC_CAMERA=y
  20664. +CONFIG_VIDEO_MX3=y
  20665. +CONFIG_RADIO_SI476X=y
  20666. +CONFIG_SOC_CAMERA_OV2640=y
  20667. +CONFIG_DRM=y
  20668. +CONFIG_DRM_VIVANTE=y
  20669. +CONFIG_FB=y
  20670. +CONFIG_FB_MXS=y
  20671. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  20672. +CONFIG_LCD_CLASS_DEVICE=y
  20673. +CONFIG_LCD_L4F00242T03=y
  20674. +CONFIG_LCD_PLATFORM=y
  20675. +CONFIG_BACKLIGHT_CLASS_DEVICE=y
  20676. +CONFIG_BACKLIGHT_PWM=y
  20677. +CONFIG_FB_MXC_SYNC_PANEL=y
  20678. +CONFIG_FB_MXC_LDB=y
  20679. +CONFIG_FB_MXC_MIPI_DSI=y
  20680. +CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
  20681. +CONFIG_FB_MXC_HDMI=y
  20682. +CONFIG_FRAMEBUFFER_CONSOLE=y
  20683. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  20684. +CONFIG_FONTS=y
  20685. +CONFIG_FONT_8x8=y
  20686. +CONFIG_FONT_8x16=y
  20687. +CONFIG_LOGO=y
  20688. +CONFIG_SOUND=y
  20689. +CONFIG_SND=y
  20690. +CONFIG_SND_USB_AUDIO=m
  20691. +CONFIG_SND_SOC=y
  20692. +CONFIG_SND_IMX_SOC=y
  20693. +CONFIG_SND_SOC_EUKREA_TLV320=y
  20694. +CONFIG_SND_SOC_IMX_CS42888=y
  20695. +CONFIG_SND_SOC_IMX_WM8962=y
  20696. +CONFIG_SND_SOC_IMX_SGTL5000=y
  20697. +CONFIG_SND_SOC_IMX_SPDIF=y
  20698. +CONFIG_SND_SOC_IMX_MC13783=y
  20699. +CONFIG_SND_SOC_IMX_HDMI=y
  20700. +CONFIG_SND_SOC_IMX_SI476X=y
  20701. +CONFIG_USB=y
  20702. +CONFIG_USB_EHCI_HCD=y
  20703. +CONFIG_USB_STORAGE=y
  20704. +CONFIG_USB_CHIPIDEA=y
  20705. +CONFIG_USB_CHIPIDEA_UDC=y
  20706. +CONFIG_USB_CHIPIDEA_HOST=y
  20707. +CONFIG_USB_PHY=y
  20708. +CONFIG_NOP_USB_XCEIV=y
  20709. +CONFIG_USB_MXS_PHY=y
  20710. +CONFIG_USB_GADGET=y
  20711. +CONFIG_USB_ZERO=m
  20712. +CONFIG_USB_ETH=m
  20713. +CONFIG_USB_MASS_STORAGE=m
  20714. +CONFIG_USB_G_SERIAL=m
  20715. +CONFIG_MMC=y
  20716. +CONFIG_MMC_UNSAFE_RESUME=y
  20717. +CONFIG_MMC_SDHCI=y
  20718. +CONFIG_MMC_SDHCI_PLTFM=y
  20719. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  20720. +CONFIG_MXC_IPU=y
  20721. +CONFIG_MXC_GPU_VIV=y
  20722. +CONFIG_MXC_ASRC=y
  20723. +CONFIG_MXC_MIPI_CSI2=y
  20724. +CONFIG_MXC_MLB150=m
  20725. +CONFIG_NEW_LEDS=y
  20726. +CONFIG_LEDS_CLASS=y
  20727. +CONFIG_LEDS_GPIO=y
  20728. +CONFIG_LEDS_TRIGGERS=y
  20729. +CONFIG_LEDS_TRIGGER_GPIO=y
  20730. +CONFIG_RTC_CLASS=y
  20731. +CONFIG_RTC_INTF_DEV_UIE_EMUL=y
  20732. +CONFIG_RTC_DRV_MC13XXX=y
  20733. +CONFIG_RTC_DRV_MXC=y
  20734. +CONFIG_RTC_DRV_SNVS=y
  20735. +CONFIG_DMADEVICES=y
  20736. +CONFIG_MXC_PXP_V2=y
  20737. +CONFIG_IMX_SDMA=y
  20738. +CONFIG_MXS_DMA=y
  20739. +CONFIG_STAGING=y
  20740. +CONFIG_COMMON_CLK_DEBUG=y
  20741. +# CONFIG_IOMMU_SUPPORT is not set
  20742. +CONFIG_PWM=y
  20743. +CONFIG_PWM_IMX=y
  20744. +CONFIG_EXT2_FS=y
  20745. +CONFIG_EXT2_FS_XATTR=y
  20746. +CONFIG_EXT2_FS_POSIX_ACL=y
  20747. +CONFIG_EXT2_FS_SECURITY=y
  20748. +CONFIG_EXT3_FS=y
  20749. +CONFIG_EXT3_FS_POSIX_ACL=y
  20750. +CONFIG_EXT3_FS_SECURITY=y
  20751. +CONFIG_EXT4_FS=y
  20752. +CONFIG_EXT4_FS_POSIX_ACL=y
  20753. +CONFIG_EXT4_FS_SECURITY=y
  20754. +CONFIG_QUOTA=y
  20755. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  20756. +# CONFIG_PRINT_QUOTA_WARNING is not set
  20757. +CONFIG_AUTOFS4_FS=y
  20758. +CONFIG_FUSE_FS=y
  20759. +CONFIG_ISO9660_FS=m
  20760. +CONFIG_JOLIET=y
  20761. +CONFIG_ZISOFS=y
  20762. +CONFIG_UDF_FS=m
  20763. +CONFIG_MSDOS_FS=m
  20764. +CONFIG_VFAT_FS=y
  20765. +CONFIG_TMPFS=y
  20766. +CONFIG_JFFS2_FS=y
  20767. +CONFIG_UBIFS_FS=y
  20768. +CONFIG_NFS_FS=y
  20769. +CONFIG_NFS_V3_ACL=y
  20770. +CONFIG_NFS_V4=y
  20771. +CONFIG_ROOT_NFS=y
  20772. +CONFIG_NLS_DEFAULT="cp437"
  20773. +CONFIG_NLS_CODEPAGE_437=y
  20774. +CONFIG_NLS_ASCII=y
  20775. +CONFIG_NLS_ISO8859_1=y
  20776. +CONFIG_NLS_ISO8859_15=m
  20777. +CONFIG_NLS_UTF8=y
  20778. +CONFIG_MAGIC_SYSRQ=y
  20779. +# CONFIG_SCHED_DEBUG is not set
  20780. +# CONFIG_DEBUG_BUGVERBOSE is not set
  20781. +# CONFIG_FTRACE is not set
  20782. +CONFIG_SECURITYFS=y
  20783. +CONFIG_CRYPTO_USER=y
  20784. +CONFIG_CRYPTO_TEST=m
  20785. +CONFIG_CRYPTO_CCM=y
  20786. +CONFIG_CRYPTO_GCM=y
  20787. +CONFIG_CRYPTO_CBC=y
  20788. +CONFIG_CRYPTO_CTS=y
  20789. +CONFIG_CRYPTO_ECB=y
  20790. +CONFIG_CRYPTO_LRW=y
  20791. +CONFIG_CRYPTO_XTS=y
  20792. +CONFIG_CRYPTO_MD4=y
  20793. +CONFIG_CRYPTO_MD5=y
  20794. +CONFIG_CRYPTO_MICHAEL_MIC=y
  20795. +CONFIG_CRYPTO_RMD128=y
  20796. +CONFIG_CRYPTO_RMD160=y
  20797. +CONFIG_CRYPTO_RMD256=y
  20798. +CONFIG_CRYPTO_RMD320=y
  20799. +CONFIG_CRYPTO_SHA1=y
  20800. +CONFIG_CRYPTO_SHA256=y
  20801. +CONFIG_CRYPTO_SHA512=y
  20802. +CONFIG_CRYPTO_TGR192=y
  20803. +CONFIG_CRYPTO_WP512=y
  20804. +CONFIG_CRYPTO_BLOWFISH=y
  20805. +CONFIG_CRYPTO_CAMELLIA=y
  20806. +CONFIG_CRYPTO_DES=y
  20807. +CONFIG_CRYPTO_TWOFISH=y
  20808. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  20809. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  20810. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  20811. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  20812. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  20813. +CONFIG_CRC_CCITT=m
  20814. +CONFIG_CRC_T10DIF=y
  20815. +CONFIG_CRC7=m
  20816. +CONFIG_LIBCRC32C=m
  20817. diff -Nur linux-3.14.15/arch/arm/configs/imx_v7_mfg_defconfig linux-linaro-stable-mx6/arch/arm/configs/imx_v7_mfg_defconfig
  20818. --- linux-3.14.15/arch/arm/configs/imx_v7_mfg_defconfig 1970-01-01 01:00:00.000000000 +0100
  20819. +++ linux-linaro-stable-mx6/arch/arm/configs/imx_v7_mfg_defconfig 2014-08-20 19:31:39.968842564 +0200
  20820. @@ -0,0 +1,341 @@
  20821. +CONFIG_KERNEL_LZO=y
  20822. +CONFIG_SYSVIPC=y
  20823. +CONFIG_NO_HZ=y
  20824. +CONFIG_HIGH_RES_TIMERS=y
  20825. +CONFIG_IKCONFIG=y
  20826. +CONFIG_IKCONFIG_PROC=y
  20827. +CONFIG_LOG_BUF_SHIFT=18
  20828. +CONFIG_CGROUPS=y
  20829. +CONFIG_RELAY=y
  20830. +CONFIG_BLK_DEV_INITRD=y
  20831. +CONFIG_EXPERT=y
  20832. +CONFIG_PERF_EVENTS=y
  20833. +# CONFIG_SLUB_DEBUG is not set
  20834. +# CONFIG_COMPAT_BRK is not set
  20835. +CONFIG_MODULES=y
  20836. +CONFIG_MODULE_UNLOAD=y
  20837. +CONFIG_MODVERSIONS=y
  20838. +CONFIG_MODULE_SRCVERSION_ALL=y
  20839. +# CONFIG_BLK_DEV_BSG is not set
  20840. +CONFIG_GPIO_PCA953X=y
  20841. +CONFIG_ARCH_MXC=y
  20842. +CONFIG_MXC_DEBUG_BOARD=y
  20843. +CONFIG_MACH_IMX51_DT=y
  20844. +CONFIG_MACH_EUKREA_CPUIMX51SD=y
  20845. +CONFIG_SOC_IMX53=y
  20846. +CONFIG_SOC_IMX6Q=y
  20847. +CONFIG_SOC_IMX6SL=y
  20848. +CONFIG_SOC_VF610=y
  20849. +# CONFIG_SWP_EMULATE is not set
  20850. +CONFIG_SMP=y
  20851. +CONFIG_VMSPLIT_2G=y
  20852. +CONFIG_PREEMPT_VOLUNTARY=y
  20853. +CONFIG_AEABI=y
  20854. +# CONFIG_OABI_COMPAT is not set
  20855. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  20856. +CONFIG_CPU_FREQ=y
  20857. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  20858. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  20859. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  20860. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  20861. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  20862. +CONFIG_ARM_IMX6_CPUFREQ=y
  20863. +CONFIG_CPU_IDLE=y
  20864. +CONFIG_VFP=y
  20865. +CONFIG_NEON=y
  20866. +CONFIG_BINFMT_MISC=m
  20867. +CONFIG_PM_RUNTIME=y
  20868. +CONFIG_PM_DEBUG=y
  20869. +CONFIG_PM_TEST_SUSPEND=y
  20870. +CONFIG_NET=y
  20871. +CONFIG_PACKET=y
  20872. +CONFIG_UNIX=y
  20873. +CONFIG_INET=y
  20874. +CONFIG_IP_PNP=y
  20875. +CONFIG_IP_PNP_DHCP=y
  20876. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  20877. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  20878. +# CONFIG_INET_XFRM_MODE_BEET is not set
  20879. +# CONFIG_INET_LRO is not set
  20880. +CONFIG_IPV6=y
  20881. +CONFIG_NETFILTER=y
  20882. +CONFIG_VLAN_8021Q=y
  20883. +CONFIG_CFG80211=y
  20884. +CONFIG_CFG80211_WEXT=y
  20885. +CONFIG_MAC80211=y
  20886. +CONFIG_DEVTMPFS=y
  20887. +CONFIG_DEVTMPFS_MOUNT=y
  20888. +# CONFIG_STANDALONE is not set
  20889. +CONFIG_CMA=y
  20890. +CONFIG_CMA_SIZE_MBYTES=320
  20891. +CONFIG_IMX_WEIM=y
  20892. +CONFIG_CONNECTOR=y
  20893. +CONFIG_MTD=y
  20894. +CONFIG_MTD_CMDLINE_PARTS=y
  20895. +CONFIG_MTD_BLOCK=y
  20896. +CONFIG_MTD_CFI=y
  20897. +CONFIG_MTD_JEDECPROBE=y
  20898. +CONFIG_MTD_CFI_INTELEXT=y
  20899. +CONFIG_MTD_CFI_AMDSTD=y
  20900. +CONFIG_MTD_CFI_STAA=y
  20901. +CONFIG_MTD_PHYSMAP_OF=y
  20902. +CONFIG_MTD_DATAFLASH=y
  20903. +CONFIG_MTD_M25P80=y
  20904. +CONFIG_MTD_SST25L=y
  20905. +CONFIG_MTD_NAND=y
  20906. +CONFIG_MTD_NAND_GPMI_NAND=y
  20907. +CONFIG_MTD_NAND_MXC=y
  20908. +CONFIG_MTD_UBI=y
  20909. +CONFIG_BLK_DEV_LOOP=y
  20910. +CONFIG_BLK_DEV_RAM=y
  20911. +CONFIG_BLK_DEV_RAM_SIZE=65536
  20912. +CONFIG_EEPROM_AT24=y
  20913. +CONFIG_EEPROM_AT25=y
  20914. +# CONFIG_SCSI_PROC_FS is not set
  20915. +CONFIG_BLK_DEV_SD=y
  20916. +CONFIG_SCSI_MULTI_LUN=y
  20917. +CONFIG_SCSI_CONSTANTS=y
  20918. +CONFIG_SCSI_LOGGING=y
  20919. +CONFIG_SCSI_SCAN_ASYNC=y
  20920. +# CONFIG_SCSI_LOWLEVEL is not set
  20921. +CONFIG_ATA=y
  20922. +CONFIG_SATA_AHCI_PLATFORM=y
  20923. +CONFIG_AHCI_IMX=y
  20924. +CONFIG_PATA_IMX=y
  20925. +CONFIG_NETDEVICES=y
  20926. +# CONFIG_NET_VENDOR_BROADCOM is not set
  20927. +CONFIG_CS89x0=y
  20928. +CONFIG_CS89x0_PLATFORM=y
  20929. +# CONFIG_NET_VENDOR_FARADAY is not set
  20930. +# CONFIG_NET_VENDOR_INTEL is not set
  20931. +# CONFIG_NET_VENDOR_MARVELL is not set
  20932. +# CONFIG_NET_VENDOR_MICREL is not set
  20933. +# CONFIG_NET_VENDOR_MICROCHIP is not set
  20934. +# CONFIG_NET_VENDOR_NATSEMI is not set
  20935. +# CONFIG_NET_VENDOR_SEEQ is not set
  20936. +CONFIG_SMC91X=y
  20937. +CONFIG_SMC911X=y
  20938. +CONFIG_SMSC911X=y
  20939. +# CONFIG_NET_VENDOR_STMICRO is not set
  20940. +CONFIG_ATH_CARDS=y
  20941. +CONFIG_ATH6KL=m
  20942. +CONFIG_ATH6KL_SDIO=m
  20943. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  20944. +CONFIG_INPUT_EVDEV=y
  20945. +CONFIG_INPUT_EVBUG=m
  20946. +CONFIG_KEYBOARD_GPIO=y
  20947. +CONFIG_KEYBOARD_IMX=y
  20948. +CONFIG_MOUSE_PS2=m
  20949. +CONFIG_MOUSE_PS2_ELANTECH=y
  20950. +CONFIG_INPUT_TOUCHSCREEN=y
  20951. +CONFIG_TOUCHSCREEN_EGALAX=y
  20952. +CONFIG_TOUCHSCREEN_ELAN=y
  20953. +CONFIG_TOUCHSCREEN_MAX11801=y
  20954. +CONFIG_TOUCHSCREEN_MC13783=y
  20955. +CONFIG_INPUT_MISC=y
  20956. +CONFIG_INPUT_MMA8450=y
  20957. +CONFIG_INPUT_ISL29023=y
  20958. +CONFIG_SERIO_SERPORT=m
  20959. +CONFIG_VT_HW_CONSOLE_BINDING=y
  20960. +# CONFIG_LEGACY_PTYS is not set
  20961. +# CONFIG_DEVKMEM is not set
  20962. +CONFIG_SERIAL_IMX=y
  20963. +CONFIG_SERIAL_IMX_CONSOLE=y
  20964. +CONFIG_SERIAL_FSL_LPUART=y
  20965. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  20966. +CONFIG_FSL_OTP=y
  20967. +# CONFIG_I2C_COMPAT is not set
  20968. +CONFIG_I2C_CHARDEV=y
  20969. +# CONFIG_I2C_HELPER_AUTO is not set
  20970. +CONFIG_I2C_ALGOPCF=m
  20971. +CONFIG_I2C_ALGOPCA=m
  20972. +CONFIG_I2C_IMX=y
  20973. +CONFIG_SPI=y
  20974. +CONFIG_SPI_IMX=y
  20975. +CONFIG_GPIO_SYSFS=y
  20976. +CONFIG_POWER_SUPPLY=y
  20977. +CONFIG_SABRESD_MAX8903=y
  20978. +CONFIG_SENSORS_MAX17135=y
  20979. +CONFIG_SENSORS_MAG3110=y
  20980. +CONFIG_THERMAL=y
  20981. +CONFIG_CPU_THERMAL=y
  20982. +CONFIG_IMX_THERMAL=y
  20983. +CONFIG_DEVICE_THERMAL=y
  20984. +CONFIG_WATCHDOG=y
  20985. +CONFIG_IMX2_WDT=y
  20986. +CONFIG_MFD_DA9052_I2C=y
  20987. +CONFIG_MFD_MC13XXX_SPI=y
  20988. +CONFIG_MFD_MC13XXX_I2C=y
  20989. +CONFIG_MFD_MAX17135=y
  20990. +CONFIG_MFD_SI476X_CORE=y
  20991. +CONFIG_REGULATOR=y
  20992. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  20993. +CONFIG_REGULATOR_DA9052=y
  20994. +CONFIG_REGULATOR_ANATOP=y
  20995. +CONFIG_REGULATOR_MC13783=y
  20996. +CONFIG_REGULATOR_MC13892=y
  20997. +CONFIG_REGULATOR_MAX17135=y
  20998. +CONFIG_REGULATOR_PFUZE100=y
  20999. +CONFIG_MEDIA_SUPPORT=y
  21000. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  21001. +CONFIG_MEDIA_RADIO_SUPPORT=y
  21002. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  21003. +CONFIG_MEDIA_USB_SUPPORT=y
  21004. +CONFIG_USB_VIDEO_CLASS=m
  21005. +CONFIG_V4L_PLATFORM_DRIVERS=y
  21006. +CONFIG_VIDEO_MXC_OUTPUT=y
  21007. +CONFIG_VIDEO_MXC_CAPTURE=m
  21008. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  21009. +CONFIG_MXC_CAMERA_OV5640=m
  21010. +CONFIG_MXC_CAMERA_OV5642=m
  21011. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  21012. +CONFIG_MXC_TVIN_ADV7180=m
  21013. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  21014. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  21015. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  21016. +CONFIG_SOC_CAMERA=y
  21017. +CONFIG_VIDEO_MX3=y
  21018. +CONFIG_RADIO_SI476X=y
  21019. +CONFIG_SOC_CAMERA_OV2640=y
  21020. +CONFIG_DRM=y
  21021. +CONFIG_DRM_VIVANTE=y
  21022. +CONFIG_FB=y
  21023. +CONFIG_FB_MXS=y
  21024. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  21025. +CONFIG_LCD_CLASS_DEVICE=y
  21026. +CONFIG_LCD_L4F00242T03=y
  21027. +CONFIG_LCD_PLATFORM=y
  21028. +CONFIG_BACKLIGHT_CLASS_DEVICE=y
  21029. +CONFIG_BACKLIGHT_PWM=y
  21030. +CONFIG_FB_MXC_SYNC_PANEL=y
  21031. +CONFIG_FB_MXC_LDB=y
  21032. +CONFIG_FB_MXC_MIPI_DSI=y
  21033. +CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
  21034. +CONFIG_FB_MXC_HDMI=y
  21035. +CONFIG_FB_MXC_EINK_PANEL=y
  21036. +CONFIG_FB_MXS_SII902X=y
  21037. +CONFIG_FRAMEBUFFER_CONSOLE=y
  21038. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  21039. +CONFIG_FONTS=y
  21040. +CONFIG_FONT_8x8=y
  21041. +CONFIG_FONT_8x16=y
  21042. +CONFIG_LOGO=y
  21043. +CONFIG_SOUND=y
  21044. +CONFIG_SND=y
  21045. +CONFIG_SND_USB_AUDIO=m
  21046. +CONFIG_SND_SOC=y
  21047. +CONFIG_SND_IMX_SOC=y
  21048. +CONFIG_SND_SOC_EUKREA_TLV320=y
  21049. +CONFIG_SND_SOC_IMX_CS42888=y
  21050. +CONFIG_SND_SOC_IMX_WM8962=y
  21051. +CONFIG_SND_SOC_IMX_SGTL5000=y
  21052. +CONFIG_SND_SOC_IMX_SPDIF=y
  21053. +CONFIG_SND_SOC_IMX_MC13783=y
  21054. +CONFIG_SND_SOC_IMX_HDMI=y
  21055. +CONFIG_SND_SOC_IMX_SI476X=y
  21056. +CONFIG_USB=y
  21057. +CONFIG_USB_EHCI_HCD=y
  21058. +CONFIG_USB_STORAGE=y
  21059. +CONFIG_USB_CHIPIDEA=y
  21060. +CONFIG_USB_CHIPIDEA_UDC=y
  21061. +CONFIG_USB_CHIPIDEA_HOST=y
  21062. +CONFIG_USB_PHY=y
  21063. +CONFIG_USB_MXS_PHY=y
  21064. +CONFIG_USB_GADGET=y
  21065. +# CONFIG_USB_ZERO is not set
  21066. +# CONFIG_USB_AUDIO is not set
  21067. +# CONFIG_USB_ETH is not set
  21068. +# CONFIG_USB_G_NCM is not set
  21069. +# CONFIG_USB_GADGETFS is not set
  21070. +# CONFIG_USB_FUNCTIONFS is not set
  21071. +CONFIG_USB_MASS_STORAGE=y
  21072. +CONFIG_FSL_UTP=y
  21073. +# CONFIG_USB_G_SERIAL is not set
  21074. +# CONFIG_USB_MIDI_GADGET is not set
  21075. +# CONFIG_USB_G_PRINTER is not set
  21076. +# CONFIG_USB_CDC_COMPOSITE is not set
  21077. +# CONFIG_USB_G_ACM_MS is not set
  21078. +# CONFIG_USB_G_MULTI is not set
  21079. +# CONFIG_USB_G_HID is not set
  21080. +# CONFIG_USB_G_DBGP is not set
  21081. +# CONFIG_USB_G_WEBCAM is not set
  21082. +CONFIG_MMC=y
  21083. +CONFIG_MMC_UNSAFE_RESUME=y
  21084. +CONFIG_MMC_SDHCI=y
  21085. +CONFIG_MMC_SDHCI_PLTFM=y
  21086. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  21087. +CONFIG_MXC_IPU=y
  21088. +CONFIG_MXC_GPU_VIV=y
  21089. +CONFIG_MXC_ASRC=y
  21090. +CONFIG_MXC_MIPI_CSI2=y
  21091. +CONFIG_NEW_LEDS=y
  21092. +CONFIG_LEDS_CLASS=y
  21093. +CONFIG_RTC_CLASS=y
  21094. +CONFIG_RTC_INTF_DEV_UIE_EMUL=y
  21095. +CONFIG_RTC_DRV_MC13XXX=y
  21096. +CONFIG_RTC_DRV_MXC=y
  21097. +CONFIG_RTC_DRV_SNVS=y
  21098. +CONFIG_DMADEVICES=y
  21099. +CONFIG_MXC_PXP_V2=y
  21100. +CONFIG_IMX_SDMA=y
  21101. +CONFIG_MXS_DMA=y
  21102. +CONFIG_STAGING=y
  21103. +CONFIG_COMMON_CLK_DEBUG=y
  21104. +# CONFIG_IOMMU_SUPPORT is not set
  21105. +CONFIG_PWM=y
  21106. +CONFIG_PWM_IMX=y
  21107. +CONFIG_EXT2_FS=y
  21108. +CONFIG_EXT2_FS_XATTR=y
  21109. +CONFIG_EXT2_FS_POSIX_ACL=y
  21110. +CONFIG_EXT2_FS_SECURITY=y
  21111. +CONFIG_EXT3_FS=y
  21112. +CONFIG_EXT3_FS_POSIX_ACL=y
  21113. +CONFIG_EXT3_FS_SECURITY=y
  21114. +CONFIG_EXT4_FS=y
  21115. +CONFIG_EXT4_FS_POSIX_ACL=y
  21116. +CONFIG_EXT4_FS_SECURITY=y
  21117. +CONFIG_QUOTA=y
  21118. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  21119. +# CONFIG_PRINT_QUOTA_WARNING is not set
  21120. +CONFIG_AUTOFS4_FS=y
  21121. +CONFIG_FUSE_FS=y
  21122. +CONFIG_ISO9660_FS=m
  21123. +CONFIG_JOLIET=y
  21124. +CONFIG_ZISOFS=y
  21125. +CONFIG_UDF_FS=m
  21126. +CONFIG_MSDOS_FS=m
  21127. +CONFIG_VFAT_FS=y
  21128. +CONFIG_TMPFS=y
  21129. +CONFIG_JFFS2_FS=y
  21130. +CONFIG_UBIFS_FS=y
  21131. +CONFIG_NFS_FS=y
  21132. +CONFIG_NFS_V3_ACL=y
  21133. +CONFIG_NFS_V4=y
  21134. +CONFIG_ROOT_NFS=y
  21135. +CONFIG_NLS_DEFAULT="cp437"
  21136. +CONFIG_NLS_CODEPAGE_437=y
  21137. +CONFIG_NLS_ASCII=y
  21138. +CONFIG_NLS_ISO8859_1=y
  21139. +CONFIG_NLS_ISO8859_15=m
  21140. +CONFIG_NLS_UTF8=y
  21141. +CONFIG_MAGIC_SYSRQ=y
  21142. +# CONFIG_SCHED_DEBUG is not set
  21143. +# CONFIG_DEBUG_BUGVERBOSE is not set
  21144. +# CONFIG_FTRACE is not set
  21145. +CONFIG_SECURITYFS=y
  21146. +CONFIG_CRYPTO_USER=y
  21147. +CONFIG_CRYPTO_CCM=y
  21148. +CONFIG_CRYPTO_GCM=y
  21149. +CONFIG_CRYPTO_CBC=y
  21150. +CONFIG_CRYPTO_CTS=y
  21151. +CONFIG_CRYPTO_ECB=y
  21152. +CONFIG_CRYPTO_LRW=y
  21153. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  21154. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  21155. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  21156. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  21157. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  21158. +CONFIG_CRC_CCITT=m
  21159. +CONFIG_CRC_T10DIF=y
  21160. +CONFIG_CRC7=m
  21161. +CONFIG_LIBCRC32C=m
  21162. diff -Nur linux-3.14.15/arch/arm/include/asm/arch_timer.h linux-linaro-stable-mx6/arch/arm/include/asm/arch_timer.h
  21163. --- linux-3.14.15/arch/arm/include/asm/arch_timer.h 2014-07-31 23:51:43.000000000 +0200
  21164. +++ linux-linaro-stable-mx6/arch/arm/include/asm/arch_timer.h 2014-08-20 19:31:39.980842616 +0200
  21165. @@ -107,7 +107,6 @@
  21166. /* Also disable virtual event stream */
  21167. cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
  21168. | ARCH_TIMER_USR_VT_ACCESS_EN
  21169. - | ARCH_TIMER_VIRT_EVT_EN
  21170. | ARCH_TIMER_USR_VCT_ACCESS_EN
  21171. | ARCH_TIMER_USR_PCT_ACCESS_EN);
  21172. arch_timer_set_cntkctl(cntkctl);
  21173. diff -Nur linux-3.14.15/arch/arm/include/asm/atomic.h linux-linaro-stable-mx6/arch/arm/include/asm/atomic.h
  21174. --- linux-3.14.15/arch/arm/include/asm/atomic.h 2014-07-31 23:51:43.000000000 +0200
  21175. +++ linux-linaro-stable-mx6/arch/arm/include/asm/atomic.h 2014-08-20 19:31:39.980842616 +0200
  21176. @@ -60,6 +60,7 @@
  21177. int result;
  21178. smp_mb();
  21179. + prefetchw(&v->counter);
  21180. __asm__ __volatile__("@ atomic_add_return\n"
  21181. "1: ldrex %0, [%3]\n"
  21182. @@ -99,6 +100,7 @@
  21183. int result;
  21184. smp_mb();
  21185. + prefetchw(&v->counter);
  21186. __asm__ __volatile__("@ atomic_sub_return\n"
  21187. "1: ldrex %0, [%3]\n"
  21188. @@ -121,6 +123,7 @@
  21189. unsigned long res;
  21190. smp_mb();
  21191. + prefetchw(&ptr->counter);
  21192. do {
  21193. __asm__ __volatile__("@ atomic_cmpxchg\n"
  21194. @@ -138,6 +141,33 @@
  21195. return oldval;
  21196. }
  21197. +static inline int __atomic_add_unless(atomic_t *v, int a, int u)
  21198. +{
  21199. + int oldval, newval;
  21200. + unsigned long tmp;
  21201. +
  21202. + smp_mb();
  21203. + prefetchw(&v->counter);
  21204. +
  21205. + __asm__ __volatile__ ("@ atomic_add_unless\n"
  21206. +"1: ldrex %0, [%4]\n"
  21207. +" teq %0, %5\n"
  21208. +" beq 2f\n"
  21209. +" add %1, %0, %6\n"
  21210. +" strex %2, %1, [%4]\n"
  21211. +" teq %2, #0\n"
  21212. +" bne 1b\n"
  21213. +"2:"
  21214. + : "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter)
  21215. + : "r" (&v->counter), "r" (u), "r" (a)
  21216. + : "cc");
  21217. +
  21218. + if (oldval != u)
  21219. + smp_mb();
  21220. +
  21221. + return oldval;
  21222. +}
  21223. +
  21224. #else /* ARM_ARCH_6 */
  21225. #ifdef CONFIG_SMP
  21226. @@ -186,10 +216,6 @@
  21227. return ret;
  21228. }
  21229. -#endif /* __LINUX_ARM_ARCH__ */
  21230. -
  21231. -#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
  21232. -
  21233. static inline int __atomic_add_unless(atomic_t *v, int a, int u)
  21234. {
  21235. int c, old;
  21236. @@ -200,6 +226,10 @@
  21237. return c;
  21238. }
  21239. +#endif /* __LINUX_ARM_ARCH__ */
  21240. +
  21241. +#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
  21242. +
  21243. #define atomic_inc(v) atomic_add(1, v)
  21244. #define atomic_dec(v) atomic_sub(1, v)
  21245. @@ -299,6 +329,7 @@
  21246. unsigned long tmp;
  21247. smp_mb();
  21248. + prefetchw(&v->counter);
  21249. __asm__ __volatile__("@ atomic64_add_return\n"
  21250. "1: ldrexd %0, %H0, [%3]\n"
  21251. @@ -340,6 +371,7 @@
  21252. unsigned long tmp;
  21253. smp_mb();
  21254. + prefetchw(&v->counter);
  21255. __asm__ __volatile__("@ atomic64_sub_return\n"
  21256. "1: ldrexd %0, %H0, [%3]\n"
  21257. @@ -364,6 +396,7 @@
  21258. unsigned long res;
  21259. smp_mb();
  21260. + prefetchw(&ptr->counter);
  21261. do {
  21262. __asm__ __volatile__("@ atomic64_cmpxchg\n"
  21263. @@ -388,6 +421,7 @@
  21264. unsigned long tmp;
  21265. smp_mb();
  21266. + prefetchw(&ptr->counter);
  21267. __asm__ __volatile__("@ atomic64_xchg\n"
  21268. "1: ldrexd %0, %H0, [%3]\n"
  21269. @@ -409,6 +443,7 @@
  21270. unsigned long tmp;
  21271. smp_mb();
  21272. + prefetchw(&v->counter);
  21273. __asm__ __volatile__("@ atomic64_dec_if_positive\n"
  21274. "1: ldrexd %0, %H0, [%3]\n"
  21275. @@ -436,6 +471,7 @@
  21276. int ret = 1;
  21277. smp_mb();
  21278. + prefetchw(&v->counter);
  21279. __asm__ __volatile__("@ atomic64_add_unless\n"
  21280. "1: ldrexd %0, %H0, [%4]\n"
  21281. diff -Nur linux-3.14.15/arch/arm/include/asm/cmpxchg.h linux-linaro-stable-mx6/arch/arm/include/asm/cmpxchg.h
  21282. --- linux-3.14.15/arch/arm/include/asm/cmpxchg.h 2014-07-31 23:51:43.000000000 +0200
  21283. +++ linux-linaro-stable-mx6/arch/arm/include/asm/cmpxchg.h 2014-08-20 19:31:39.980842616 +0200
  21284. @@ -2,6 +2,7 @@
  21285. #define __ASM_ARM_CMPXCHG_H
  21286. #include <linux/irqflags.h>
  21287. +#include <linux/prefetch.h>
  21288. #include <asm/barrier.h>
  21289. #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
  21290. @@ -35,6 +36,7 @@
  21291. #endif
  21292. smp_mb();
  21293. + prefetchw((const void *)ptr);
  21294. switch (size) {
  21295. #if __LINUX_ARM_ARCH__ >= 6
  21296. @@ -138,6 +140,8 @@
  21297. {
  21298. unsigned long oldval, res;
  21299. + prefetchw((const void *)ptr);
  21300. +
  21301. switch (size) {
  21302. #ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
  21303. case 1:
  21304. @@ -230,6 +234,8 @@
  21305. unsigned long long oldval;
  21306. unsigned long res;
  21307. + prefetchw(ptr);
  21308. +
  21309. __asm__ __volatile__(
  21310. "1: ldrexd %1, %H1, [%3]\n"
  21311. " teq %1, %4\n"
  21312. diff -Nur linux-3.14.15/arch/arm/include/asm/ftrace.h linux-linaro-stable-mx6/arch/arm/include/asm/ftrace.h
  21313. --- linux-3.14.15/arch/arm/include/asm/ftrace.h 2014-07-31 23:51:43.000000000 +0200
  21314. +++ linux-linaro-stable-mx6/arch/arm/include/asm/ftrace.h 2014-08-20 19:31:39.980842616 +0200
  21315. @@ -52,15 +52,7 @@
  21316. #endif
  21317. -#define HAVE_ARCH_CALLER_ADDR
  21318. -
  21319. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  21320. -#define CALLER_ADDR1 ((unsigned long)return_address(1))
  21321. -#define CALLER_ADDR2 ((unsigned long)return_address(2))
  21322. -#define CALLER_ADDR3 ((unsigned long)return_address(3))
  21323. -#define CALLER_ADDR4 ((unsigned long)return_address(4))
  21324. -#define CALLER_ADDR5 ((unsigned long)return_address(5))
  21325. -#define CALLER_ADDR6 ((unsigned long)return_address(6))
  21326. +#define ftrace_return_address(n) return_address(n)
  21327. #endif /* ifndef __ASSEMBLY__ */
  21328. diff -Nur linux-3.14.15/arch/arm/include/asm/futex.h linux-linaro-stable-mx6/arch/arm/include/asm/futex.h
  21329. --- linux-3.14.15/arch/arm/include/asm/futex.h 2014-07-31 23:51:43.000000000 +0200
  21330. +++ linux-linaro-stable-mx6/arch/arm/include/asm/futex.h 2014-08-20 19:31:39.980842616 +0200
  21331. @@ -23,6 +23,7 @@
  21332. #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
  21333. smp_mb(); \
  21334. + prefetchw(uaddr); \
  21335. __asm__ __volatile__( \
  21336. "1: ldrex %1, [%3]\n" \
  21337. " " insn "\n" \
  21338. @@ -46,6 +47,8 @@
  21339. return -EFAULT;
  21340. smp_mb();
  21341. + /* Prefetching cannot fault */
  21342. + prefetchw(uaddr);
  21343. __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
  21344. "1: ldrex %1, [%4]\n"
  21345. " teq %1, %2\n"
  21346. diff -Nur linux-3.14.15/arch/arm/include/asm/glue-cache.h linux-linaro-stable-mx6/arch/arm/include/asm/glue-cache.h
  21347. --- linux-3.14.15/arch/arm/include/asm/glue-cache.h 2014-07-31 23:51:43.000000000 +0200
  21348. +++ linux-linaro-stable-mx6/arch/arm/include/asm/glue-cache.h 2014-08-20 19:31:39.980842616 +0200
  21349. @@ -102,19 +102,19 @@
  21350. #endif
  21351. #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
  21352. -# ifdef _CACHE
  21353. +//# ifdef _CACHE
  21354. # define MULTI_CACHE 1
  21355. -# else
  21356. -# define _CACHE v6
  21357. -# endif
  21358. +//# else
  21359. +//# define _CACHE v6
  21360. +//# endif
  21361. #endif
  21362. #if defined(CONFIG_CPU_V7)
  21363. -# ifdef _CACHE
  21364. +//# ifdef _CACHE
  21365. # define MULTI_CACHE 1
  21366. -# else
  21367. -# define _CACHE v7
  21368. -# endif
  21369. +//# else
  21370. +//# define _CACHE v7
  21371. +//# endif
  21372. #endif
  21373. #if defined(CONFIG_CPU_V7M)
  21374. diff -Nur linux-3.14.15/arch/arm/include/asm/hardware/cache-l2x0.h linux-linaro-stable-mx6/arch/arm/include/asm/hardware/cache-l2x0.h
  21375. --- linux-3.14.15/arch/arm/include/asm/hardware/cache-l2x0.h 2014-07-31 23:51:43.000000000 +0200
  21376. +++ linux-linaro-stable-mx6/arch/arm/include/asm/hardware/cache-l2x0.h 2014-08-20 19:31:39.980842616 +0200
  21377. @@ -26,8 +26,8 @@
  21378. #define L2X0_CACHE_TYPE 0x004
  21379. #define L2X0_CTRL 0x100
  21380. #define L2X0_AUX_CTRL 0x104
  21381. -#define L2X0_TAG_LATENCY_CTRL 0x108
  21382. -#define L2X0_DATA_LATENCY_CTRL 0x10C
  21383. +#define L310_TAG_LATENCY_CTRL 0x108
  21384. +#define L310_DATA_LATENCY_CTRL 0x10C
  21385. #define L2X0_EVENT_CNT_CTRL 0x200
  21386. #define L2X0_EVENT_CNT1_CFG 0x204
  21387. #define L2X0_EVENT_CNT0_CFG 0x208
  21388. @@ -54,53 +54,93 @@
  21389. #define L2X0_LOCKDOWN_WAY_D_BASE 0x900
  21390. #define L2X0_LOCKDOWN_WAY_I_BASE 0x904
  21391. #define L2X0_LOCKDOWN_STRIDE 0x08
  21392. -#define L2X0_ADDR_FILTER_START 0xC00
  21393. -#define L2X0_ADDR_FILTER_END 0xC04
  21394. +#define L310_ADDR_FILTER_START 0xC00
  21395. +#define L310_ADDR_FILTER_END 0xC04
  21396. #define L2X0_TEST_OPERATION 0xF00
  21397. #define L2X0_LINE_DATA 0xF10
  21398. #define L2X0_LINE_TAG 0xF30
  21399. #define L2X0_DEBUG_CTRL 0xF40
  21400. -#define L2X0_PREFETCH_CTRL 0xF60
  21401. -#define L2X0_POWER_CTRL 0xF80
  21402. -#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1)
  21403. -#define L2X0_STNDBY_MODE_EN (1 << 0)
  21404. +#define L310_PREFETCH_CTRL 0xF60
  21405. +#define L310_POWER_CTRL 0xF80
  21406. +#define L310_DYNAMIC_CLK_GATING_EN (1 << 1)
  21407. +#define L310_STNDBY_MODE_EN (1 << 0)
  21408. /* Registers shifts and masks */
  21409. #define L2X0_CACHE_ID_PART_MASK (0xf << 6)
  21410. #define L2X0_CACHE_ID_PART_L210 (1 << 6)
  21411. +#define L2X0_CACHE_ID_PART_L220 (2 << 6)
  21412. #define L2X0_CACHE_ID_PART_L310 (3 << 6)
  21413. #define L2X0_CACHE_ID_RTL_MASK 0x3f
  21414. -#define L2X0_CACHE_ID_RTL_R0P0 0x0
  21415. -#define L2X0_CACHE_ID_RTL_R1P0 0x2
  21416. -#define L2X0_CACHE_ID_RTL_R2P0 0x4
  21417. -#define L2X0_CACHE_ID_RTL_R3P0 0x5
  21418. -#define L2X0_CACHE_ID_RTL_R3P1 0x6
  21419. -#define L2X0_CACHE_ID_RTL_R3P2 0x8
  21420. -
  21421. -#define L2X0_AUX_CTRL_MASK 0xc0000fff
  21422. +#define L210_CACHE_ID_RTL_R0P2_02 0x00
  21423. +#define L210_CACHE_ID_RTL_R0P1 0x01
  21424. +#define L210_CACHE_ID_RTL_R0P2_01 0x02
  21425. +#define L210_CACHE_ID_RTL_R0P3 0x03
  21426. +#define L210_CACHE_ID_RTL_R0P4 0x0b
  21427. +#define L210_CACHE_ID_RTL_R0P5 0x0f
  21428. +#define L220_CACHE_ID_RTL_R1P7_01REL0 0x06
  21429. +#define L310_CACHE_ID_RTL_R0P0 0x00
  21430. +#define L310_CACHE_ID_RTL_R1P0 0x02
  21431. +#define L310_CACHE_ID_RTL_R2P0 0x04
  21432. +#define L310_CACHE_ID_RTL_R3P0 0x05
  21433. +#define L310_CACHE_ID_RTL_R3P1 0x06
  21434. +#define L310_CACHE_ID_RTL_R3P1_50REL0 0x07
  21435. +#define L310_CACHE_ID_RTL_R3P2 0x08
  21436. +#define L310_CACHE_ID_RTL_R3P3 0x09
  21437. +
  21438. +/* L2C auxiliary control register - bits common to L2C-210/220/310 */
  21439. +#define L2C_AUX_CTRL_WAY_SIZE_SHIFT 17
  21440. +#define L2C_AUX_CTRL_WAY_SIZE_MASK (7 << 17)
  21441. +#define L2C_AUX_CTRL_WAY_SIZE(n) ((n) << 17)
  21442. +#define L2C_AUX_CTRL_EVTMON_ENABLE BIT(20)
  21443. +#define L2C_AUX_CTRL_PARITY_ENABLE BIT(21)
  21444. +#define L2C_AUX_CTRL_SHARED_OVERRIDE BIT(22)
  21445. +/* L2C-210/220 common bits */
  21446. #define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT 0
  21447. -#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK 0x7
  21448. +#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK (7 << 0)
  21449. #define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT 3
  21450. -#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK (0x7 << 3)
  21451. +#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK (7 << 3)
  21452. #define L2X0_AUX_CTRL_TAG_LATENCY_SHIFT 6
  21453. -#define L2X0_AUX_CTRL_TAG_LATENCY_MASK (0x7 << 6)
  21454. +#define L2X0_AUX_CTRL_TAG_LATENCY_MASK (7 << 6)
  21455. #define L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT 9
  21456. -#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK (0x7 << 9)
  21457. -#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16
  21458. -#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17
  21459. -#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17)
  21460. -#define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22
  21461. -#define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26
  21462. -#define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27
  21463. -#define L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT 28
  21464. -#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29
  21465. -#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30
  21466. -
  21467. -#define L2X0_LATENCY_CTRL_SETUP_SHIFT 0
  21468. -#define L2X0_LATENCY_CTRL_RD_SHIFT 4
  21469. -#define L2X0_LATENCY_CTRL_WR_SHIFT 8
  21470. -
  21471. -#define L2X0_ADDR_FILTER_EN 1
  21472. +#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK (7 << 9)
  21473. +#define L2X0_AUX_CTRL_ASSOC_SHIFT 13
  21474. +#define L2X0_AUX_CTRL_ASSOC_MASK (15 << 13)
  21475. +/* L2C-210 specific bits */
  21476. +#define L210_AUX_CTRL_WRAP_DISABLE BIT(12)
  21477. +#define L210_AUX_CTRL_WA_OVERRIDE BIT(23)
  21478. +#define L210_AUX_CTRL_EXCLUSIVE_ABORT BIT(24)
  21479. +/* L2C-220 specific bits */
  21480. +#define L220_AUX_CTRL_EXCLUSIVE_CACHE BIT(12)
  21481. +#define L220_AUX_CTRL_FWA_SHIFT 23
  21482. +#define L220_AUX_CTRL_FWA_MASK (3 << 23)
  21483. +#define L220_AUX_CTRL_NS_LOCKDOWN BIT(26)
  21484. +#define L220_AUX_CTRL_NS_INT_CTRL BIT(27)
  21485. +/* L2C-310 specific bits */
  21486. +#define L310_AUX_CTRL_FULL_LINE_ZERO BIT(0) /* R2P0+ */
  21487. +#define L310_AUX_CTRL_HIGHPRIO_SO_DEV BIT(10) /* R2P0+ */
  21488. +#define L310_AUX_CTRL_STORE_LIMITATION BIT(11) /* R2P0+ */
  21489. +#define L310_AUX_CTRL_EXCLUSIVE_CACHE BIT(12)
  21490. +#define L310_AUX_CTRL_ASSOCIATIVITY_16 BIT(16)
  21491. +#define L310_AUX_CTRL_CACHE_REPLACE_RR BIT(25) /* R2P0+ */
  21492. +#define L310_AUX_CTRL_NS_LOCKDOWN BIT(26)
  21493. +#define L310_AUX_CTRL_NS_INT_CTRL BIT(27)
  21494. +#define L310_AUX_CTRL_DATA_PREFETCH BIT(28)
  21495. +#define L310_AUX_CTRL_INSTR_PREFETCH BIT(29)
  21496. +#define L310_AUX_CTRL_EARLY_BRESP BIT(30) /* R2P0+ */
  21497. +
  21498. +#define L310_LATENCY_CTRL_SETUP(n) ((n) << 0)
  21499. +#define L310_LATENCY_CTRL_RD(n) ((n) << 4)
  21500. +#define L310_LATENCY_CTRL_WR(n) ((n) << 8)
  21501. +
  21502. +#define L310_ADDR_FILTER_EN 1
  21503. +
  21504. +#define L310_PREFETCH_CTRL_OFFSET_MASK 0x1f
  21505. +#define L310_PREFETCH_CTRL_DBL_LINEFILL_INCR BIT(23)
  21506. +#define L310_PREFETCH_CTRL_PREFETCH_DROP BIT(24)
  21507. +#define L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP BIT(27)
  21508. +#define L310_PREFETCH_CTRL_DATA_PREFETCH BIT(28)
  21509. +#define L310_PREFETCH_CTRL_INSTR_PREFETCH BIT(29)
  21510. +#define L310_PREFETCH_CTRL_DBL_LINEFILL BIT(30)
  21511. #define L2X0_CTRL_EN 1
  21512. diff -Nur linux-3.14.15/arch/arm/include/asm/outercache.h linux-linaro-stable-mx6/arch/arm/include/asm/outercache.h
  21513. --- linux-3.14.15/arch/arm/include/asm/outercache.h 2014-07-31 23:51:43.000000000 +0200
  21514. +++ linux-linaro-stable-mx6/arch/arm/include/asm/outercache.h 2014-08-20 19:31:39.996842683 +0200
  21515. @@ -21,6 +21,7 @@
  21516. #ifndef __ASM_OUTERCACHE_H
  21517. #define __ASM_OUTERCACHE_H
  21518. +#include <linux/bug.h>
  21519. #include <linux/types.h>
  21520. struct outer_cache_fns {
  21521. @@ -28,53 +29,84 @@
  21522. void (*clean_range)(unsigned long, unsigned long);
  21523. void (*flush_range)(unsigned long, unsigned long);
  21524. void (*flush_all)(void);
  21525. - void (*inv_all)(void);
  21526. void (*disable)(void);
  21527. #ifdef CONFIG_OUTER_CACHE_SYNC
  21528. void (*sync)(void);
  21529. #endif
  21530. - void (*set_debug)(unsigned long);
  21531. void (*resume)(void);
  21532. +
  21533. + /* This is an ARM L2C thing */
  21534. + void (*write_sec)(unsigned long, unsigned);
  21535. };
  21536. extern struct outer_cache_fns outer_cache;
  21537. #ifdef CONFIG_OUTER_CACHE
  21538. -
  21539. +/**
  21540. + * outer_inv_range - invalidate range of outer cache lines
  21541. + * @start: starting physical address, inclusive
  21542. + * @end: end physical address, exclusive
  21543. + */
  21544. static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
  21545. {
  21546. if (outer_cache.inv_range)
  21547. outer_cache.inv_range(start, end);
  21548. }
  21549. +
  21550. +/**
  21551. + * outer_clean_range - clean dirty outer cache lines
  21552. + * @start: starting physical address, inclusive
  21553. + * @end: end physical address, exclusive
  21554. + */
  21555. static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
  21556. {
  21557. if (outer_cache.clean_range)
  21558. outer_cache.clean_range(start, end);
  21559. }
  21560. +
  21561. +/**
  21562. + * outer_flush_range - clean and invalidate outer cache lines
  21563. + * @start: starting physical address, inclusive
  21564. + * @end: end physical address, exclusive
  21565. + */
  21566. static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
  21567. {
  21568. if (outer_cache.flush_range)
  21569. outer_cache.flush_range(start, end);
  21570. }
  21571. +/**
  21572. + * outer_flush_all - clean and invalidate all cache lines in the outer cache
  21573. + *
  21574. + * Note: depending on implementation, this may not be atomic - it must
  21575. + * only be called with interrupts disabled and no other active outer
  21576. + * cache masters.
  21577. + *
  21578. + * It is intended that this function is only used by implementations
  21579. + * needing to override the outer_cache.disable() method due to security.
  21580. + * (Some implementations perform this as a clean followed by an invalidate.)
  21581. + */
  21582. static inline void outer_flush_all(void)
  21583. {
  21584. if (outer_cache.flush_all)
  21585. outer_cache.flush_all();
  21586. }
  21587. -static inline void outer_inv_all(void)
  21588. -{
  21589. - if (outer_cache.inv_all)
  21590. - outer_cache.inv_all();
  21591. -}
  21592. -
  21593. -static inline void outer_disable(void)
  21594. -{
  21595. - if (outer_cache.disable)
  21596. - outer_cache.disable();
  21597. -}
  21598. -
  21599. +/**
  21600. + * outer_disable - clean, invalidate and disable the outer cache
  21601. + *
  21602. + * Disable the outer cache, ensuring that any data contained in the outer
  21603. + * cache is pushed out to lower levels of system memory. The note and
  21604. + * conditions above concerning outer_flush_all() applies here.
  21605. + */
  21606. +extern void outer_disable(void);
  21607. +
  21608. +/**
  21609. + * outer_resume - restore the cache configuration and re-enable outer cache
  21610. + *
  21611. + * Restore any configuration that the cache had when previously enabled,
  21612. + * and re-enable the outer cache.
  21613. + */
  21614. static inline void outer_resume(void)
  21615. {
  21616. if (outer_cache.resume)
  21617. @@ -90,13 +122,18 @@
  21618. static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
  21619. { }
  21620. static inline void outer_flush_all(void) { }
  21621. -static inline void outer_inv_all(void) { }
  21622. static inline void outer_disable(void) { }
  21623. static inline void outer_resume(void) { }
  21624. #endif
  21625. #ifdef CONFIG_OUTER_CACHE_SYNC
  21626. +/**
  21627. + * outer_sync - perform a sync point for outer cache
  21628. + *
  21629. + * Ensure that all outer cache operations are complete and any store
  21630. + * buffers are drained.
  21631. + */
  21632. static inline void outer_sync(void)
  21633. {
  21634. if (outer_cache.sync)
  21635. diff -Nur linux-3.14.15/arch/arm/include/asm/pmu.h linux-linaro-stable-mx6/arch/arm/include/asm/pmu.h
  21636. --- linux-3.14.15/arch/arm/include/asm/pmu.h 2014-07-31 23:51:43.000000000 +0200
  21637. +++ linux-linaro-stable-mx6/arch/arm/include/asm/pmu.h 2014-08-20 19:23:45.610811908 +0200
  21638. @@ -62,9 +62,19 @@
  21639. raw_spinlock_t pmu_lock;
  21640. };
  21641. +struct cpupmu_regs {
  21642. + u32 pmc;
  21643. + u32 pmcntenset;
  21644. + u32 pmuseren;
  21645. + u32 pmintenset;
  21646. + u32 pmxevttype[8];
  21647. + u32 pmxevtcnt[8];
  21648. +};
  21649. +
  21650. struct arm_pmu {
  21651. struct pmu pmu;
  21652. cpumask_t active_irqs;
  21653. + cpumask_t valid_cpus;
  21654. char *name;
  21655. irqreturn_t (*handle_irq)(int irq_num, void *dev);
  21656. void (*enable)(struct perf_event *event);
  21657. @@ -81,6 +91,8 @@
  21658. int (*request_irq)(struct arm_pmu *, irq_handler_t handler);
  21659. void (*free_irq)(struct arm_pmu *);
  21660. int (*map_event)(struct perf_event *event);
  21661. + void (*save_regs)(struct arm_pmu *, struct cpupmu_regs *);
  21662. + void (*restore_regs)(struct arm_pmu *, struct cpupmu_regs *);
  21663. int num_events;
  21664. atomic_t active_events;
  21665. struct mutex reserve_mutex;
  21666. diff -Nur linux-3.14.15/arch/arm/include/asm/psci.h linux-linaro-stable-mx6/arch/arm/include/asm/psci.h
  21667. --- linux-3.14.15/arch/arm/include/asm/psci.h 2014-07-31 23:51:43.000000000 +0200
  21668. +++ linux-linaro-stable-mx6/arch/arm/include/asm/psci.h 2014-08-20 19:31:40.000842701 +0200
  21669. @@ -16,6 +16,10 @@
  21670. #define PSCI_POWER_STATE_TYPE_STANDBY 0
  21671. #define PSCI_POWER_STATE_TYPE_POWER_DOWN 1
  21672. +#define PSCI_POWER_STATE_AFFINITY_LEVEL0 0
  21673. +#define PSCI_POWER_STATE_AFFINITY_LEVEL1 1
  21674. +#define PSCI_POWER_STATE_AFFINITY_LEVEL2 2
  21675. +#define PSCI_POWER_STATE_AFFINITY_LEVEL3 3
  21676. struct psci_power_state {
  21677. u16 id;
  21678. @@ -42,4 +46,12 @@
  21679. static inline bool psci_smp_available(void) { return false; }
  21680. #endif
  21681. +#ifdef CONFIG_ARM_PSCI
  21682. +extern int psci_probe(void);
  21683. +#else
  21684. +static inline int psci_probe(void)
  21685. +{
  21686. + return -ENODEV;
  21687. +}
  21688. +#endif
  21689. #endif /* __ASM_ARM_PSCI_H */
  21690. diff -Nur linux-3.14.15/arch/arm/include/asm/topology.h linux-linaro-stable-mx6/arch/arm/include/asm/topology.h
  21691. --- linux-3.14.15/arch/arm/include/asm/topology.h 2014-07-31 23:51:43.000000000 +0200
  21692. +++ linux-linaro-stable-mx6/arch/arm/include/asm/topology.h 2014-08-20 19:31:40.004842719 +0200
  21693. @@ -26,11 +26,14 @@
  21694. void init_cpu_topology(void);
  21695. void store_cpu_topology(unsigned int cpuid);
  21696. const struct cpumask *cpu_coregroup_mask(int cpu);
  21697. +int cluster_to_logical_mask(unsigned int socket_id, cpumask_t *cluster_mask);
  21698. #else
  21699. static inline void init_cpu_topology(void) { }
  21700. static inline void store_cpu_topology(unsigned int cpuid) { }
  21701. +static inline int cluster_to_logical_mask(unsigned int socket_id,
  21702. + cpumask_t *cluster_mask) { return -EINVAL; }
  21703. #endif
  21704. diff -Nur linux-3.14.15/arch/arm/Kconfig linux-linaro-stable-mx6/arch/arm/Kconfig
  21705. --- linux-3.14.15/arch/arm/Kconfig 2014-07-31 23:51:43.000000000 +0200
  21706. +++ linux-linaro-stable-mx6/arch/arm/Kconfig 2014-08-20 19:31:39.796841825 +0200
  21707. @@ -1216,19 +1216,6 @@
  21708. register of the Cortex-A9 which reduces the linefill issuing
  21709. capabilities of the processor.
  21710. -config PL310_ERRATA_588369
  21711. - bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
  21712. - depends on CACHE_L2X0
  21713. - help
  21714. - The PL310 L2 cache controller implements three types of Clean &
  21715. - Invalidate maintenance operations: by Physical Address
  21716. - (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
  21717. - They are architecturally defined to behave as the execution of a
  21718. - clean operation followed immediately by an invalidate operation,
  21719. - both performing to the same memory location. This functionality
  21720. - is not correctly implemented in PL310 as clean lines are not
  21721. - invalidated as a result of these operations.
  21722. -
  21723. config ARM_ERRATA_643719
  21724. bool "ARM errata: LoUIS bit field in CLIDR register is incorrect"
  21725. depends on CPU_V7 && SMP
  21726. @@ -1251,17 +1238,6 @@
  21727. tables. The workaround changes the TLB flushing routines to invalidate
  21728. entries regardless of the ASID.
  21729. -config PL310_ERRATA_727915
  21730. - bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
  21731. - depends on CACHE_L2X0
  21732. - help
  21733. - PL310 implements the Clean & Invalidate by Way L2 cache maintenance
  21734. - operation (offset 0x7FC). This operation runs in background so that
  21735. - PL310 can handle normal accesses while it is in progress. Under very
  21736. - rare circumstances, due to this erratum, write data can be lost when
  21737. - PL310 treats a cacheable write transaction during a Clean &
  21738. - Invalidate by Way operation.
  21739. -
  21740. config ARM_ERRATA_743622
  21741. bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption"
  21742. depends on CPU_V7
  21743. @@ -1287,21 +1263,6 @@
  21744. operation is received by a CPU before the ICIALLUIS has completed,
  21745. potentially leading to corrupted entries in the cache or TLB.
  21746. -config PL310_ERRATA_753970
  21747. - bool "PL310 errata: cache sync operation may be faulty"
  21748. - depends on CACHE_PL310
  21749. - help
  21750. - This option enables the workaround for the 753970 PL310 (r3p0) erratum.
  21751. -
  21752. - Under some condition the effect of cache sync operation on
  21753. - the store buffer still remains when the operation completes.
  21754. - This means that the store buffer is always asked to drain and
  21755. - this prevents it from merging any further writes. The workaround
  21756. - is to replace the normal offset of cache sync operation (0x730)
  21757. - by another offset targeting an unmapped PL310 register 0x740.
  21758. - This has the same effect as the cache sync operation: store buffer
  21759. - drain and waiting for all buffers empty.
  21760. -
  21761. config ARM_ERRATA_754322
  21762. bool "ARM errata: possible faulty MMU translations following an ASID switch"
  21763. depends on CPU_V7
  21764. @@ -1350,18 +1311,6 @@
  21765. relevant cache maintenance functions and sets a specific bit
  21766. in the diagnostic control register of the SCU.
  21767. -config PL310_ERRATA_769419
  21768. - bool "PL310 errata: no automatic Store Buffer drain"
  21769. - depends on CACHE_L2X0
  21770. - help
  21771. - On revisions of the PL310 prior to r3p2, the Store Buffer does
  21772. - not automatically drain. This can cause normal, non-cacheable
  21773. - writes to be retained when the memory system is idle, leading
  21774. - to suboptimal I/O performance for drivers using coherent DMA.
  21775. - This option adds a write barrier to the cpu_idle loop so that,
  21776. - on systems with an outer cache, the store buffer is drained
  21777. - explicitly.
  21778. -
  21779. config ARM_ERRATA_775420
  21780. bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock"
  21781. depends on CPU_V7
  21782. @@ -1391,6 +1340,29 @@
  21783. loop buffer may deliver incorrect instructions. This
  21784. workaround disables the loop buffer to avoid the erratum.
  21785. +config ARM_ERRATA_794072
  21786. + bool "ARM errata: A short loop including a DMB instruction might cause a denial of service"
  21787. + depends on CPU_V7 && SMP
  21788. + help
  21789. + This option enables the workaround for the 794072 Cortex-A9
  21790. + (all revisions). A processor which continuously executes a short
  21791. + loop containing a DMB instruction might prevent a CP15 operation
  21792. + broadcast by another processor making further progress, causing
  21793. + a denial of service. This erratum can be worked around by setting
  21794. + bit[4] of the undocumented Diagnostic Control Register to 1.
  21795. +
  21796. +config ARM_ERRATA_761320
  21797. + bool "Full cache line writes to the same memory region from at least two processors might deadlock processor"
  21798. + depends on CPU_V7 && SMP
  21799. + help
  21800. + This option enables the workaround for the 761320 Cortex-A9 (r0..r3).
  21801. + Under very rare circumstances, full cache line writes
  21802. + from (at least) 2 processors on cache lines in hazard with
  21803. + other requests may cause arbitration issues in the SCU,
  21804. + leading to processor deadlock. This erratum can be
  21805. + worked around by setting bit[21] of the undocumented
  21806. + Diagnostic Control Register to 1.
  21807. +
  21808. endmenu
  21809. source "arch/arm/common/Kconfig"
  21810. @@ -1835,6 +1807,7 @@
  21811. range 11 64 if ARCH_SHMOBILE_LEGACY
  21812. default "12" if SOC_AM33XX
  21813. default "9" if SA1111 || ARCH_EFM32
  21814. + default "14" if ARCH_MXC
  21815. default "11"
  21816. help
  21817. The kernel memory allocator divides physically contiguous memory
  21818. diff -Nur linux-3.14.15/arch/arm/kernel/perf_event.c linux-linaro-stable-mx6/arch/arm/kernel/perf_event.c
  21819. --- linux-3.14.15/arch/arm/kernel/perf_event.c 2014-07-31 23:51:43.000000000 +0200
  21820. +++ linux-linaro-stable-mx6/arch/arm/kernel/perf_event.c 2014-08-20 19:31:40.024842805 +0200
  21821. @@ -12,6 +12,7 @@
  21822. */
  21823. #define pr_fmt(fmt) "hw perfevents: " fmt
  21824. +#include <linux/cpumask.h>
  21825. #include <linux/kernel.h>
  21826. #include <linux/platform_device.h>
  21827. #include <linux/pm_runtime.h>
  21828. @@ -86,6 +87,9 @@
  21829. return armpmu_map_cache_event(cache_map, config);
  21830. case PERF_TYPE_RAW:
  21831. return armpmu_map_raw_event(raw_event_mask, config);
  21832. + default:
  21833. + if (event->attr.type >= PERF_TYPE_MAX)
  21834. + return armpmu_map_raw_event(raw_event_mask, config);
  21835. }
  21836. return -ENOENT;
  21837. @@ -159,6 +163,8 @@
  21838. struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
  21839. struct hw_perf_event *hwc = &event->hw;
  21840. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21841. + return;
  21842. /*
  21843. * ARM pmu always has to update the counter, so ignore
  21844. * PERF_EF_UPDATE, see comments in armpmu_start().
  21845. @@ -175,6 +181,8 @@
  21846. struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
  21847. struct hw_perf_event *hwc = &event->hw;
  21848. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21849. + return;
  21850. /*
  21851. * ARM pmu always has to reprogram the period, so ignore
  21852. * PERF_EF_RELOAD, see the comment below.
  21853. @@ -202,6 +210,9 @@
  21854. struct hw_perf_event *hwc = &event->hw;
  21855. int idx = hwc->idx;
  21856. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21857. + return;
  21858. +
  21859. armpmu_stop(event, PERF_EF_UPDATE);
  21860. hw_events->events[idx] = NULL;
  21861. clear_bit(idx, hw_events->used_mask);
  21862. @@ -218,6 +229,10 @@
  21863. int idx;
  21864. int err = 0;
  21865. + /* An event following a process won't be stopped earlier */
  21866. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21867. + return 0;
  21868. +
  21869. perf_pmu_disable(event->pmu);
  21870. /* If we don't have a space for the counter then finish early. */
  21871. @@ -419,6 +434,10 @@
  21872. int err = 0;
  21873. atomic_t *active_events = &armpmu->active_events;
  21874. + if (event->cpu != -1 &&
  21875. + !cpumask_test_cpu(event->cpu, &armpmu->valid_cpus))
  21876. + return -ENOENT;
  21877. +
  21878. /* does not support taken branch sampling */
  21879. if (has_branch_stack(event))
  21880. return -EOPNOTSUPP;
  21881. diff -Nur linux-3.14.15/arch/arm/kernel/perf_event_cpu.c linux-linaro-stable-mx6/arch/arm/kernel/perf_event_cpu.c
  21882. --- linux-3.14.15/arch/arm/kernel/perf_event_cpu.c 2014-07-31 23:51:43.000000000 +0200
  21883. +++ linux-linaro-stable-mx6/arch/arm/kernel/perf_event_cpu.c 2014-08-20 19:31:40.024842805 +0200
  21884. @@ -19,6 +19,7 @@
  21885. #define pr_fmt(fmt) "CPU PMU: " fmt
  21886. #include <linux/bitmap.h>
  21887. +#include <linux/cpu_pm.h>
  21888. #include <linux/export.h>
  21889. #include <linux/kernel.h>
  21890. #include <linux/of.h>
  21891. @@ -31,33 +32,36 @@
  21892. #include <asm/pmu.h>
  21893. /* Set at runtime when we know what CPU type we are. */
  21894. -static struct arm_pmu *cpu_pmu;
  21895. +static DEFINE_PER_CPU(struct arm_pmu *, cpu_pmu);
  21896. static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
  21897. static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
  21898. static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
  21899. +static DEFINE_PER_CPU(struct cpupmu_regs, cpu_pmu_regs);
  21900. +
  21901. /*
  21902. * Despite the names, these two functions are CPU-specific and are used
  21903. * by the OProfile/perf code.
  21904. */
  21905. const char *perf_pmu_name(void)
  21906. {
  21907. - if (!cpu_pmu)
  21908. + struct arm_pmu *pmu = per_cpu(cpu_pmu, 0);
  21909. + if (!pmu)
  21910. return NULL;
  21911. - return cpu_pmu->name;
  21912. + return pmu->name;
  21913. }
  21914. EXPORT_SYMBOL_GPL(perf_pmu_name);
  21915. int perf_num_counters(void)
  21916. {
  21917. - int max_events = 0;
  21918. + struct arm_pmu *pmu = per_cpu(cpu_pmu, 0);
  21919. - if (cpu_pmu != NULL)
  21920. - max_events = cpu_pmu->num_events;
  21921. + if (!pmu)
  21922. + return 0;
  21923. - return max_events;
  21924. + return pmu->num_events;
  21925. }
  21926. EXPORT_SYMBOL_GPL(perf_num_counters);
  21927. @@ -75,11 +79,13 @@
  21928. {
  21929. int i, irq, irqs;
  21930. struct platform_device *pmu_device = cpu_pmu->plat_device;
  21931. + int cpu = -1;
  21932. irqs = min(pmu_device->num_resources, num_possible_cpus());
  21933. for (i = 0; i < irqs; ++i) {
  21934. - if (!cpumask_test_and_clear_cpu(i, &cpu_pmu->active_irqs))
  21935. + cpu = cpumask_next(cpu, &cpu_pmu->valid_cpus);
  21936. + if (!cpumask_test_and_clear_cpu(cpu, &cpu_pmu->active_irqs))
  21937. continue;
  21938. irq = platform_get_irq(pmu_device, i);
  21939. if (irq >= 0)
  21940. @@ -91,6 +97,7 @@
  21941. {
  21942. int i, err, irq, irqs;
  21943. struct platform_device *pmu_device = cpu_pmu->plat_device;
  21944. + int cpu = -1;
  21945. if (!pmu_device)
  21946. return -ENODEV;
  21947. @@ -103,6 +110,7 @@
  21948. for (i = 0; i < irqs; ++i) {
  21949. err = 0;
  21950. + cpu = cpumask_next(cpu, &cpu_pmu->valid_cpus);
  21951. irq = platform_get_irq(pmu_device, i);
  21952. if (irq < 0)
  21953. continue;
  21954. @@ -112,7 +120,7 @@
  21955. * assume that we're running on a uniprocessor machine and
  21956. * continue. Otherwise, continue without this interrupt.
  21957. */
  21958. - if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
  21959. + if (irq_set_affinity(irq, cpumask_of(cpu)) && irqs > 1) {
  21960. pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
  21961. irq, i);
  21962. continue;
  21963. @@ -127,7 +135,7 @@
  21964. return err;
  21965. }
  21966. - cpumask_set_cpu(i, &cpu_pmu->active_irqs);
  21967. + cpumask_set_cpu(cpu, &cpu_pmu->active_irqs);
  21968. }
  21969. return 0;
  21970. @@ -136,7 +144,7 @@
  21971. static void cpu_pmu_init(struct arm_pmu *cpu_pmu)
  21972. {
  21973. int cpu;
  21974. - for_each_possible_cpu(cpu) {
  21975. + for_each_cpu_mask(cpu, cpu_pmu->valid_cpus) {
  21976. struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu);
  21977. events->events = per_cpu(hw_events, cpu);
  21978. events->used_mask = per_cpu(used_mask, cpu);
  21979. @@ -149,7 +157,7 @@
  21980. /* Ensure the PMU has sane values out of reset. */
  21981. if (cpu_pmu->reset)
  21982. - on_each_cpu(cpu_pmu->reset, cpu_pmu, 1);
  21983. + on_each_cpu_mask(&cpu_pmu->valid_cpus, cpu_pmu->reset, cpu_pmu, 1);
  21984. }
  21985. /*
  21986. @@ -161,21 +169,46 @@
  21987. static int cpu_pmu_notify(struct notifier_block *b, unsigned long action,
  21988. void *hcpu)
  21989. {
  21990. + struct arm_pmu *pmu = per_cpu(cpu_pmu, (long)hcpu);
  21991. +
  21992. if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
  21993. return NOTIFY_DONE;
  21994. - if (cpu_pmu && cpu_pmu->reset)
  21995. - cpu_pmu->reset(cpu_pmu);
  21996. + if (pmu && pmu->reset)
  21997. + pmu->reset(pmu);
  21998. else
  21999. return NOTIFY_DONE;
  22000. return NOTIFY_OK;
  22001. }
  22002. +static int cpu_pmu_pm_notify(struct notifier_block *b,
  22003. + unsigned long action, void *hcpu)
  22004. +{
  22005. + int cpu = smp_processor_id();
  22006. + struct arm_pmu *pmu = per_cpu(cpu_pmu, cpu);
  22007. + struct cpupmu_regs *pmuregs = &per_cpu(cpu_pmu_regs, cpu);
  22008. +
  22009. + if (!pmu)
  22010. + return NOTIFY_DONE;
  22011. +
  22012. + if (action == CPU_PM_ENTER && pmu->save_regs) {
  22013. + pmu->save_regs(pmu, pmuregs);
  22014. + } else if (action == CPU_PM_EXIT && pmu->restore_regs) {
  22015. + pmu->restore_regs(pmu, pmuregs);
  22016. + }
  22017. +
  22018. + return NOTIFY_OK;
  22019. +}
  22020. +
  22021. static struct notifier_block cpu_pmu_hotplug_notifier = {
  22022. .notifier_call = cpu_pmu_notify,
  22023. };
  22024. +static struct notifier_block cpu_pmu_pm_notifier = {
  22025. + .notifier_call = cpu_pmu_pm_notify,
  22026. +};
  22027. +
  22028. /*
  22029. * PMU platform driver and devicetree bindings.
  22030. */
  22031. @@ -247,6 +280,9 @@
  22032. }
  22033. }
  22034. + /* assume PMU support all the CPUs in this case */
  22035. + cpumask_setall(&pmu->valid_cpus);
  22036. +
  22037. put_cpu();
  22038. return ret;
  22039. }
  22040. @@ -254,15 +290,10 @@
  22041. static int cpu_pmu_device_probe(struct platform_device *pdev)
  22042. {
  22043. const struct of_device_id *of_id;
  22044. - const int (*init_fn)(struct arm_pmu *);
  22045. struct device_node *node = pdev->dev.of_node;
  22046. struct arm_pmu *pmu;
  22047. - int ret = -ENODEV;
  22048. -
  22049. - if (cpu_pmu) {
  22050. - pr_info("attempt to register multiple PMU devices!");
  22051. - return -ENOSPC;
  22052. - }
  22053. + int ret = 0;
  22054. + int cpu;
  22055. pmu = kzalloc(sizeof(struct arm_pmu), GFP_KERNEL);
  22056. if (!pmu) {
  22057. @@ -271,8 +302,28 @@
  22058. }
  22059. if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) {
  22060. - init_fn = of_id->data;
  22061. - ret = init_fn(pmu);
  22062. + smp_call_func_t init_fn = (smp_call_func_t)of_id->data;
  22063. + struct device_node *ncluster;
  22064. + int cluster = -1;
  22065. + cpumask_t sibling_mask;
  22066. +
  22067. + ncluster = of_parse_phandle(node, "cluster", 0);
  22068. + if (ncluster) {
  22069. + int len;
  22070. + const u32 *hwid;
  22071. + hwid = of_get_property(ncluster, "reg", &len);
  22072. + if (hwid && len == 4)
  22073. + cluster = be32_to_cpup(hwid);
  22074. + }
  22075. + /* set sibling mask to all cpu mask if socket is not specified */
  22076. + if (cluster == -1 ||
  22077. + cluster_to_logical_mask(cluster, &sibling_mask))
  22078. + cpumask_setall(&sibling_mask);
  22079. +
  22080. + smp_call_function_any(&sibling_mask, init_fn, pmu, 1);
  22081. +
  22082. + /* now set the valid_cpus after init */
  22083. + cpumask_copy(&pmu->valid_cpus, &sibling_mask);
  22084. } else {
  22085. ret = probe_current_pmu(pmu);
  22086. }
  22087. @@ -282,10 +333,12 @@
  22088. goto out_free;
  22089. }
  22090. - cpu_pmu = pmu;
  22091. - cpu_pmu->plat_device = pdev;
  22092. - cpu_pmu_init(cpu_pmu);
  22093. - ret = armpmu_register(cpu_pmu, PERF_TYPE_RAW);
  22094. + for_each_cpu_mask(cpu, pmu->valid_cpus)
  22095. + per_cpu(cpu_pmu, cpu) = pmu;
  22096. +
  22097. + pmu->plat_device = pdev;
  22098. + cpu_pmu_init(pmu);
  22099. + ret = armpmu_register(pmu, -1);
  22100. if (!ret)
  22101. return 0;
  22102. @@ -314,9 +367,17 @@
  22103. if (err)
  22104. return err;
  22105. + err = cpu_pm_register_notifier(&cpu_pmu_pm_notifier);
  22106. + if (err) {
  22107. + unregister_cpu_notifier(&cpu_pmu_hotplug_notifier);
  22108. + return err;
  22109. + }
  22110. +
  22111. err = platform_driver_register(&cpu_pmu_driver);
  22112. - if (err)
  22113. + if (err) {
  22114. + cpu_pm_unregister_notifier(&cpu_pmu_pm_notifier);
  22115. unregister_cpu_notifier(&cpu_pmu_hotplug_notifier);
  22116. + }
  22117. return err;
  22118. }
  22119. diff -Nur linux-3.14.15/arch/arm/kernel/perf_event_v7.c linux-linaro-stable-mx6/arch/arm/kernel/perf_event_v7.c
  22120. --- linux-3.14.15/arch/arm/kernel/perf_event_v7.c 2014-07-31 23:51:43.000000000 +0200
  22121. +++ linux-linaro-stable-mx6/arch/arm/kernel/perf_event_v7.c 2014-08-20 19:23:45.650812079 +0200
  22122. @@ -950,6 +950,51 @@
  22123. }
  22124. #endif
  22125. +static void armv7pmu_save_regs(struct arm_pmu *cpu_pmu,
  22126. + struct cpupmu_regs *regs)
  22127. +{
  22128. + unsigned int cnt;
  22129. + asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (regs->pmc));
  22130. + if (!(regs->pmc & ARMV7_PMNC_E))
  22131. + return;
  22132. +
  22133. + asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (regs->pmcntenset));
  22134. + asm volatile("mrc p15, 0, %0, c9, c14, 0" : "=r" (regs->pmuseren));
  22135. + asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (regs->pmintenset));
  22136. + asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (regs->pmxevtcnt[0]));
  22137. + for (cnt = ARMV7_IDX_COUNTER0;
  22138. + cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
  22139. + armv7_pmnc_select_counter(cnt);
  22140. + asm volatile("mrc p15, 0, %0, c9, c13, 1"
  22141. + : "=r"(regs->pmxevttype[cnt]));
  22142. + asm volatile("mrc p15, 0, %0, c9, c13, 2"
  22143. + : "=r"(regs->pmxevtcnt[cnt]));
  22144. + }
  22145. + return;
  22146. +}
  22147. +
  22148. +static void armv7pmu_restore_regs(struct arm_pmu *cpu_pmu,
  22149. + struct cpupmu_regs *regs)
  22150. +{
  22151. + unsigned int cnt;
  22152. + if (!(regs->pmc & ARMV7_PMNC_E))
  22153. + return;
  22154. +
  22155. + asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (regs->pmcntenset));
  22156. + asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r" (regs->pmuseren));
  22157. + asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (regs->pmintenset));
  22158. + asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (regs->pmxevtcnt[0]));
  22159. + for (cnt = ARMV7_IDX_COUNTER0;
  22160. + cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
  22161. + armv7_pmnc_select_counter(cnt);
  22162. + asm volatile("mcr p15, 0, %0, c9, c13, 1"
  22163. + : : "r"(regs->pmxevttype[cnt]));
  22164. + asm volatile("mcr p15, 0, %0, c9, c13, 2"
  22165. + : : "r"(regs->pmxevtcnt[cnt]));
  22166. + }
  22167. + asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (regs->pmc));
  22168. +}
  22169. +
  22170. static void armv7pmu_enable_event(struct perf_event *event)
  22171. {
  22172. unsigned long flags;
  22173. @@ -1223,6 +1268,8 @@
  22174. cpu_pmu->start = armv7pmu_start;
  22175. cpu_pmu->stop = armv7pmu_stop;
  22176. cpu_pmu->reset = armv7pmu_reset;
  22177. + cpu_pmu->save_regs = armv7pmu_save_regs;
  22178. + cpu_pmu->restore_regs = armv7pmu_restore_regs;
  22179. cpu_pmu->max_period = (1LLU << 32) - 1;
  22180. };
  22181. @@ -1240,7 +1287,7 @@
  22182. static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
  22183. {
  22184. armv7pmu_init(cpu_pmu);
  22185. - cpu_pmu->name = "ARMv7 Cortex-A8";
  22186. + cpu_pmu->name = "ARMv7_Cortex_A8";
  22187. cpu_pmu->map_event = armv7_a8_map_event;
  22188. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22189. return 0;
  22190. @@ -1249,7 +1296,7 @@
  22191. static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
  22192. {
  22193. armv7pmu_init(cpu_pmu);
  22194. - cpu_pmu->name = "ARMv7 Cortex-A9";
  22195. + cpu_pmu->name = "ARMv7_Cortex_A9";
  22196. cpu_pmu->map_event = armv7_a9_map_event;
  22197. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22198. return 0;
  22199. @@ -1258,7 +1305,7 @@
  22200. static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
  22201. {
  22202. armv7pmu_init(cpu_pmu);
  22203. - cpu_pmu->name = "ARMv7 Cortex-A5";
  22204. + cpu_pmu->name = "ARMv7_Cortex_A5";
  22205. cpu_pmu->map_event = armv7_a5_map_event;
  22206. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22207. return 0;
  22208. @@ -1267,7 +1314,7 @@
  22209. static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
  22210. {
  22211. armv7pmu_init(cpu_pmu);
  22212. - cpu_pmu->name = "ARMv7 Cortex-A15";
  22213. + cpu_pmu->name = "ARMv7_Cortex_A15";
  22214. cpu_pmu->map_event = armv7_a15_map_event;
  22215. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22216. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  22217. @@ -1277,7 +1324,7 @@
  22218. static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
  22219. {
  22220. armv7pmu_init(cpu_pmu);
  22221. - cpu_pmu->name = "ARMv7 Cortex-A7";
  22222. + cpu_pmu->name = "ARMv7_Cortex_A7";
  22223. cpu_pmu->map_event = armv7_a7_map_event;
  22224. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22225. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  22226. diff -Nur linux-3.14.15/arch/arm/kernel/process.c linux-linaro-stable-mx6/arch/arm/kernel/process.c
  22227. --- linux-3.14.15/arch/arm/kernel/process.c 2014-07-31 23:51:43.000000000 +0200
  22228. +++ linux-linaro-stable-mx6/arch/arm/kernel/process.c 2014-08-20 19:31:40.024842805 +0200
  22229. @@ -172,8 +172,10 @@
  22230. */
  22231. void arch_cpu_idle(void)
  22232. {
  22233. + idle_notifier_call_chain(IDLE_START);
  22234. if (cpuidle_idle_call())
  22235. default_idle();
  22236. + idle_notifier_call_chain(IDLE_END);
  22237. }
  22238. /*
  22239. diff -Nur linux-3.14.15/arch/arm/kernel/psci.c linux-linaro-stable-mx6/arch/arm/kernel/psci.c
  22240. --- linux-3.14.15/arch/arm/kernel/psci.c 2014-07-31 23:51:43.000000000 +0200
  22241. +++ linux-linaro-stable-mx6/arch/arm/kernel/psci.c 2014-08-20 19:31:40.028842822 +0200
  22242. @@ -42,6 +42,7 @@
  22243. #define PSCI_RET_EOPNOTSUPP -1
  22244. #define PSCI_RET_EINVAL -2
  22245. #define PSCI_RET_EPERM -3
  22246. +#define PSCI_RET_EALREADYON -4
  22247. static int psci_to_linux_errno(int errno)
  22248. {
  22249. @@ -54,6 +55,8 @@
  22250. return -EINVAL;
  22251. case PSCI_RET_EPERM:
  22252. return -EPERM;
  22253. + case PSCI_RET_EALREADYON:
  22254. + return -EAGAIN;
  22255. };
  22256. return -EINVAL;
  22257. @@ -153,7 +156,7 @@
  22258. return psci_to_linux_errno(err);
  22259. }
  22260. -static const struct of_device_id psci_of_match[] __initconst = {
  22261. +static const struct of_device_id psci_of_match[] = {
  22262. { .compatible = "arm,psci", },
  22263. {},
  22264. };
  22265. @@ -208,3 +211,16 @@
  22266. of_node_put(np);
  22267. return;
  22268. }
  22269. +
  22270. +int psci_probe(void)
  22271. +{
  22272. + struct device_node *np;
  22273. + int ret = -ENODEV;
  22274. +
  22275. + np = of_find_matching_node(NULL, psci_of_match);
  22276. + if (np)
  22277. + ret = 0;
  22278. +
  22279. + of_node_put(np);
  22280. + return ret;
  22281. +}
  22282. diff -Nur linux-3.14.15/arch/arm/kernel/setup.c linux-linaro-stable-mx6/arch/arm/kernel/setup.c
  22283. --- linux-3.14.15/arch/arm/kernel/setup.c 2014-07-31 23:51:43.000000000 +0200
  22284. +++ linux-linaro-stable-mx6/arch/arm/kernel/setup.c 2014-08-20 19:31:40.032842839 +0200
  22285. @@ -273,6 +273,19 @@
  22286. int aliasing_icache;
  22287. unsigned int id_reg, num_sets, line_size;
  22288. +#ifdef CONFIG_BIG_LITTLE
  22289. + /*
  22290. + * We expect a combination of Cortex-A15 and Cortex-A7 cores.
  22291. + * A7 = VIPT aliasing I-cache
  22292. + * A15 = PIPT (non-aliasing) I-cache
  22293. + * To cater for this discrepancy, let's assume aliasing I-cache
  22294. + * all the time. This means unneeded extra work on the A15 but
  22295. + * only ptrace is affected which is not performance critical.
  22296. + */
  22297. + if ((read_cpuid_id() & 0xff0ffff0) == 0x410fc0f0)
  22298. + return 1;
  22299. +#endif
  22300. +
  22301. /* PIPT caches never alias. */
  22302. if (icache_is_pipt())
  22303. return 0;
  22304. diff -Nur linux-3.14.15/arch/arm/kernel/topology.c linux-linaro-stable-mx6/arch/arm/kernel/topology.c
  22305. --- linux-3.14.15/arch/arm/kernel/topology.c 2014-07-31 23:51:43.000000000 +0200
  22306. +++ linux-linaro-stable-mx6/arch/arm/kernel/topology.c 2014-08-20 19:31:40.032842839 +0200
  22307. @@ -267,6 +267,33 @@
  22308. }
  22309. /*
  22310. + * cluster_to_logical_mask - return cpu logical mask of CPUs in a cluster
  22311. + * @socket_id: cluster HW identifier
  22312. + * @cluster_mask: the cpumask location to be initialized, modified by the
  22313. + * function only if return value == 0
  22314. + *
  22315. + * Return:
  22316. + *
  22317. + * 0 on success
  22318. + * -EINVAL if cluster_mask is NULL or there is no record matching socket_id
  22319. + */
  22320. +int cluster_to_logical_mask(unsigned int socket_id, cpumask_t *cluster_mask)
  22321. +{
  22322. + int cpu;
  22323. +
  22324. + if (!cluster_mask)
  22325. + return -EINVAL;
  22326. +
  22327. + for_each_online_cpu(cpu)
  22328. + if (socket_id == topology_physical_package_id(cpu)) {
  22329. + cpumask_copy(cluster_mask, topology_core_cpumask(cpu));
  22330. + return 0;
  22331. + }
  22332. +
  22333. + return -EINVAL;
  22334. +}
  22335. +
  22336. +/*
  22337. * init_cpu_topology is called at boot when only one cpu is running
  22338. * which prevent simultaneous write access to cpu_topology array
  22339. */
  22340. diff -Nur linux-3.14.15/arch/arm/lib/bitops.h linux-linaro-stable-mx6/arch/arm/lib/bitops.h
  22341. --- linux-3.14.15/arch/arm/lib/bitops.h 2014-07-31 23:51:43.000000000 +0200
  22342. +++ linux-linaro-stable-mx6/arch/arm/lib/bitops.h 2014-08-20 19:31:40.036842855 +0200
  22343. @@ -37,6 +37,11 @@
  22344. add r1, r1, r0, lsl #2 @ Get word offset
  22345. mov r3, r2, lsl r3 @ create mask
  22346. smp_dmb
  22347. +#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
  22348. + .arch_extension mp
  22349. + ALT_SMP(W(pldw) [r1])
  22350. + ALT_UP(W(nop))
  22351. +#endif
  22352. 1: ldrex r2, [r1]
  22353. ands r0, r2, r3 @ save old value of bit
  22354. \instr r2, r2, r3 @ toggle bit
  22355. diff -Nur linux-3.14.15/arch/arm/mach-berlin/berlin.c linux-linaro-stable-mx6/arch/arm/mach-berlin/berlin.c
  22356. --- linux-3.14.15/arch/arm/mach-berlin/berlin.c 2014-07-31 23:51:43.000000000 +0200
  22357. +++ linux-linaro-stable-mx6/arch/arm/mach-berlin/berlin.c 2014-08-20 19:31:40.044842889 +0200
  22358. @@ -24,7 +24,7 @@
  22359. * with DT probing for L2CCs, berlin_init_machine can be removed.
  22360. * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
  22361. */
  22362. - l2x0_of_init(0x70c00000, 0xfeffffff);
  22363. + l2x0_of_init(0x30c00000, 0xfeffffff);
  22364. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  22365. }
  22366. diff -Nur linux-3.14.15/arch/arm/mach-cns3xxx/core.c linux-linaro-stable-mx6/arch/arm/mach-cns3xxx/core.c
  22367. --- linux-3.14.15/arch/arm/mach-cns3xxx/core.c 2014-07-31 23:51:43.000000000 +0200
  22368. +++ linux-linaro-stable-mx6/arch/arm/mach-cns3xxx/core.c 2014-08-20 19:31:40.048842908 +0200
  22369. @@ -240,9 +240,9 @@
  22370. *
  22371. * 1 cycle of latency for setup, read and write accesses
  22372. */
  22373. - val = readl(base + L2X0_TAG_LATENCY_CTRL);
  22374. + val = readl(base + L310_TAG_LATENCY_CTRL);
  22375. val &= 0xfffff888;
  22376. - writel(val, base + L2X0_TAG_LATENCY_CTRL);
  22377. + writel(val, base + L310_TAG_LATENCY_CTRL);
  22378. /*
  22379. * Data RAM Control register
  22380. @@ -253,12 +253,12 @@
  22381. *
  22382. * 1 cycle of latency for setup, read and write accesses
  22383. */
  22384. - val = readl(base + L2X0_DATA_LATENCY_CTRL);
  22385. + val = readl(base + L310_DATA_LATENCY_CTRL);
  22386. val &= 0xfffff888;
  22387. - writel(val, base + L2X0_DATA_LATENCY_CTRL);
  22388. + writel(val, base + L310_DATA_LATENCY_CTRL);
  22389. /* 32 KiB, 8-way, parity disable */
  22390. - l2x0_init(base, 0x00540000, 0xfe000fff);
  22391. + l2x0_init(base, 0x00500000, 0xfe0f0fff);
  22392. }
  22393. #endif /* CONFIG_CACHE_L2X0 */
  22394. diff -Nur linux-3.14.15/arch/arm/mach-exynos/common.c linux-linaro-stable-mx6/arch/arm/mach-exynos/common.c
  22395. --- linux-3.14.15/arch/arm/mach-exynos/common.c 2014-07-31 23:51:43.000000000 +0200
  22396. +++ linux-linaro-stable-mx6/arch/arm/mach-exynos/common.c 2014-08-20 19:31:40.072843010 +0200
  22397. @@ -45,9 +45,6 @@
  22398. #include "common.h"
  22399. #include "regs-pmu.h"
  22400. -#define L2_AUX_VAL 0x7C470001
  22401. -#define L2_AUX_MASK 0xC200ffff
  22402. -
  22403. static const char name_exynos4210[] = "EXYNOS4210";
  22404. static const char name_exynos4212[] = "EXYNOS4212";
  22405. static const char name_exynos4412[] = "EXYNOS4412";
  22406. @@ -400,7 +397,7 @@
  22407. {
  22408. int ret;
  22409. - ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
  22410. + ret = l2x0_of_init(0x3c400001, 0xc20fffff);
  22411. if (ret)
  22412. return ret;
  22413. diff -Nur linux-3.14.15/arch/arm/mach-highbank/highbank.c linux-linaro-stable-mx6/arch/arm/mach-highbank/highbank.c
  22414. --- linux-3.14.15/arch/arm/mach-highbank/highbank.c 2014-07-31 23:51:43.000000000 +0200
  22415. +++ linux-linaro-stable-mx6/arch/arm/mach-highbank/highbank.c 2014-08-20 19:31:40.076843028 +0200
  22416. @@ -20,7 +20,7 @@
  22417. #include <linux/input.h>
  22418. #include <linux/io.h>
  22419. #include <linux/irqchip.h>
  22420. -#include <linux/mailbox.h>
  22421. +#include <linux/pl320-ipc.h>
  22422. #include <linux/of.h>
  22423. #include <linux/of_irq.h>
  22424. #include <linux/of_platform.h>
  22425. @@ -51,11 +51,13 @@
  22426. }
  22427. -static void highbank_l2x0_disable(void)
  22428. +static void highbank_l2c310_write_sec(unsigned long val, unsigned reg)
  22429. {
  22430. - outer_flush_all();
  22431. - /* Disable PL310 L2 Cache controller */
  22432. - highbank_smc1(0x102, 0x0);
  22433. + if (reg == L2X0_CTRL)
  22434. + highbank_smc1(0x102, val);
  22435. + else
  22436. + WARN_ONCE(1, "Highbank L2C310: ignoring write to reg 0x%x\n",
  22437. + reg);
  22438. }
  22439. static void __init highbank_init_irq(void)
  22440. @@ -66,11 +68,9 @@
  22441. highbank_scu_map_io();
  22442. /* Enable PL310 L2 Cache controller */
  22443. - if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
  22444. - of_find_compatible_node(NULL, NULL, "arm,pl310-cache")) {
  22445. - highbank_smc1(0x102, 0x1);
  22446. - l2x0_of_init(0, ~0UL);
  22447. - outer_cache.disable = highbank_l2x0_disable;
  22448. + if (IS_ENABLED(CONFIG_CACHE_L2X0)) {
  22449. + outer_cache.write_sec = highbank_l2c310_write_sec;
  22450. + l2x0_of_init(0, ~0);
  22451. }
  22452. }
  22453. diff -Nur linux-3.14.15/arch/arm/mach-imx/anatop.c linux-linaro-stable-mx6/arch/arm/mach-imx/anatop.c
  22454. --- linux-3.14.15/arch/arm/mach-imx/anatop.c 2014-07-31 23:51:43.000000000 +0200
  22455. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/anatop.c 2014-08-20 19:31:40.080843045 +0200
  22456. @@ -9,6 +9,7 @@
  22457. * http://www.gnu.org/copyleft/gpl.html
  22458. */
  22459. +#include <linux/delay.h>
  22460. #include <linux/err.h>
  22461. #include <linux/io.h>
  22462. #include <linux/of.h>
  22463. @@ -35,6 +36,10 @@
  22464. #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000
  22465. #define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000
  22466. +#define ANADIG_REG_TARG_MASK 0x1f
  22467. +#define ANADIG_REG1_TARG_SHIFT 9 /* VDDPU */
  22468. +#define ANADIG_REG2_TARG_SHIFT 18 /* VDDSOC */
  22469. +
  22470. static struct regmap *anatop;
  22471. static void imx_anatop_enable_weak2p5(bool enable)
  22472. @@ -78,6 +83,28 @@
  22473. BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
  22474. }
  22475. +void imx_anatop_pu_enable(bool enable)
  22476. +{
  22477. + u32 val;
  22478. +
  22479. + regmap_read(anatop, ANADIG_REG_CORE, &val);
  22480. + val &= ANADIG_REG_TARG_MASK << ANADIG_REG2_TARG_SHIFT;
  22481. + /*
  22482. + * set pu regulator only in LDO_BYPASS mode(know by VDDSOC reg 0x1f),
  22483. + * else handled by anatop regulator driver.
  22484. + */
  22485. + if (((val >> (ANADIG_REG2_TARG_SHIFT)) & ANADIG_REG_TARG_MASK)
  22486. + == ANADIG_REG_TARG_MASK) {
  22487. + if (enable) {
  22488. + regmap_write(anatop, ANADIG_REG_CORE + REG_SET,
  22489. + ANADIG_REG_TARG_MASK << ANADIG_REG1_TARG_SHIFT);
  22490. + udelay(70); /* bypass need 70us to be stable */
  22491. + } else {
  22492. + regmap_write(anatop, ANADIG_REG_CORE + REG_CLR,
  22493. + ANADIG_REG_TARG_MASK << ANADIG_REG1_TARG_SHIFT);
  22494. + }
  22495. + }
  22496. +}
  22497. void __init imx_init_revision_from_anatop(void)
  22498. {
  22499. struct device_node *np;
  22500. @@ -104,6 +131,15 @@
  22501. case 2:
  22502. revision = IMX_CHIP_REVISION_1_2;
  22503. break;
  22504. + case 3:
  22505. + revision = IMX_CHIP_REVISION_1_3;
  22506. + break;
  22507. + case 4:
  22508. + revision = IMX_CHIP_REVISION_1_4;
  22509. + break;
  22510. + case 5:
  22511. + revision = IMX_CHIP_REVISION_1_5;
  22512. + break;
  22513. default:
  22514. revision = IMX_CHIP_REVISION_UNKNOWN;
  22515. }
  22516. diff -Nur linux-3.14.15/arch/arm/mach-imx/busfreq_ddr3.c linux-linaro-stable-mx6/arch/arm/mach-imx/busfreq_ddr3.c
  22517. --- linux-3.14.15/arch/arm/mach-imx/busfreq_ddr3.c 1970-01-01 01:00:00.000000000 +0100
  22518. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/busfreq_ddr3.c 2014-08-20 19:31:40.080843045 +0200
  22519. @@ -0,0 +1,471 @@
  22520. +/*
  22521. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  22522. + */
  22523. +
  22524. +/*
  22525. + * The code contained herein is licensed under the GNU General Public
  22526. + * License. You may obtain a copy of the GNU General Public License
  22527. + * Version 2 or later at the following locations:
  22528. + *
  22529. + * http://www.opensource.org/licenses/gpl-license.html
  22530. + * http://www.gnu.org/copyleft/gpl.html
  22531. + */
  22532. +
  22533. +/*!
  22534. + * @file busfreq_ddr3.c
  22535. + *
  22536. + * @brief iMX6 DDR3 frequency change specific file.
  22537. + *
  22538. + * @ingroup PM
  22539. + */
  22540. +#include <asm/cacheflush.h>
  22541. +#include <asm/fncpy.h>
  22542. +#include <asm/io.h>
  22543. +#include <asm/mach/map.h>
  22544. +#include <asm/mach-types.h>
  22545. +#include <asm/tlb.h>
  22546. +#include <linux/clk.h>
  22547. +#include <linux/cpumask.h>
  22548. +#include <linux/delay.h>
  22549. +#include <linux/genalloc.h>
  22550. +#include <linux/interrupt.h>
  22551. +#include <linux/irqchip/arm-gic.h>
  22552. +#include <linux/kernel.h>
  22553. +#include <linux/mutex.h>
  22554. +#include <linux/of.h>
  22555. +#include <linux/of_address.h>
  22556. +#include <linux/of_device.h>
  22557. +#include <linux/platform_device.h>
  22558. +#include <linux/proc_fs.h>
  22559. +#include <linux/sched.h>
  22560. +#include <linux/smp.h>
  22561. +
  22562. +#include "hardware.h"
  22563. +
  22564. +/* DDR settings */
  22565. +static unsigned long (*iram_ddr_settings)[2];
  22566. +static unsigned long (*normal_mmdc_settings)[2];
  22567. +static unsigned long (*iram_iomux_settings)[2];
  22568. +static void __iomem *mmdc_base;
  22569. +static void __iomem *iomux_base;
  22570. +static void __iomem *ccm_base;
  22571. +static void __iomem *l2_base;
  22572. +static void __iomem *gic_dist_base;
  22573. +static u32 *irqs_used;
  22574. +
  22575. +static void *ddr_freq_change_iram_base;
  22576. +static int ddr_settings_size;
  22577. +static int iomux_settings_size;
  22578. +static volatile unsigned int cpus_in_wfe;
  22579. +static volatile bool wait_for_ddr_freq_update;
  22580. +static int curr_ddr_rate;
  22581. +
  22582. +void (*mx6_change_ddr_freq)(u32 freq, void *ddr_settings,
  22583. + bool dll_mode, void *iomux_offsets) = NULL;
  22584. +
  22585. +extern unsigned int ddr_med_rate;
  22586. +extern unsigned int ddr_normal_rate;
  22587. +extern int low_bus_freq_mode;
  22588. +extern int audio_bus_freq_mode;
  22589. +extern void mx6_ddr3_freq_change(u32 freq, void *ddr_settings,
  22590. + bool dll_mode, void *iomux_offsets);
  22591. +
  22592. +#define MIN_DLL_ON_FREQ 333000000
  22593. +#define MAX_DLL_OFF_FREQ 125000000
  22594. +#define DDR_FREQ_CHANGE_SIZE 0x2000
  22595. +
  22596. +unsigned long ddr3_dll_mx6q[][2] = {
  22597. + {0x0c, 0x0},
  22598. + {0x10, 0x0},
  22599. + {0x1C, 0x04088032},
  22600. + {0x1C, 0x0408803a},
  22601. + {0x1C, 0x08408030},
  22602. + {0x1C, 0x08408038},
  22603. + {0x818, 0x0},
  22604. +};
  22605. +
  22606. +unsigned long ddr3_calibration[][2] = {
  22607. + {0x83c, 0x0},
  22608. + {0x840, 0x0},
  22609. + {0x483c, 0x0},
  22610. + {0x4840, 0x0},
  22611. + {0x848, 0x0},
  22612. + {0x4848, 0x0},
  22613. + {0x850, 0x0},
  22614. + {0x4850, 0x0},
  22615. +};
  22616. +
  22617. +unsigned long ddr3_dll_mx6dl[][2] = {
  22618. + {0x0c, 0x0},
  22619. + {0x10, 0x0},
  22620. + {0x1C, 0x04008032},
  22621. + {0x1C, 0x0400803a},
  22622. + {0x1C, 0x07208030},
  22623. + {0x1C, 0x07208038},
  22624. + {0x818, 0x0},
  22625. +};
  22626. +
  22627. +unsigned long iomux_offsets_mx6q[][2] = {
  22628. + {0x5A8, 0x0},
  22629. + {0x5B0, 0x0},
  22630. + {0x524, 0x0},
  22631. + {0x51C, 0x0},
  22632. + {0x518, 0x0},
  22633. + {0x50C, 0x0},
  22634. + {0x5B8, 0x0},
  22635. + {0x5C0, 0x0},
  22636. +};
  22637. +
  22638. +unsigned long iomux_offsets_mx6dl[][2] = {
  22639. + {0x4BC, 0x0},
  22640. + {0x4C0, 0x0},
  22641. + {0x4C4, 0x0},
  22642. + {0x4C8, 0x0},
  22643. + {0x4CC, 0x0},
  22644. + {0x4D0, 0x0},
  22645. + {0x4D4, 0x0},
  22646. + {0x4D8, 0x0},
  22647. +};
  22648. +
  22649. +unsigned long ddr3_400[][2] = {
  22650. + {0x83c, 0x42490249},
  22651. + {0x840, 0x02470247},
  22652. + {0x483c, 0x42570257},
  22653. + {0x4840, 0x02400240},
  22654. + {0x848, 0x4039363C},
  22655. + {0x4848, 0x3A39333F},
  22656. + {0x850, 0x38414441},
  22657. + {0x4850, 0x472D4833}
  22658. +};
  22659. +
  22660. +int can_change_ddr_freq(void)
  22661. +{
  22662. + return 1;
  22663. +}
  22664. +
  22665. +/*
  22666. + * each active core apart from the one changing
  22667. + * the DDR frequency will execute this function.
  22668. + * the rest of the cores have to remain in WFE
  22669. + * state until the frequency is changed.
  22670. + */
  22671. +irqreturn_t wait_in_wfe_irq(int irq, void *dev_id)
  22672. +{
  22673. + u32 me = smp_processor_id();
  22674. +
  22675. + *((char *)(&cpus_in_wfe) + (u8)me) = 0xff;
  22676. +
  22677. + while (wait_for_ddr_freq_update)
  22678. + wfe();
  22679. +
  22680. + *((char *)(&cpus_in_wfe) + (u8)me) = 0;
  22681. +
  22682. + return IRQ_HANDLED;
  22683. +}
  22684. +
  22685. +/* change the DDR frequency. */
  22686. +int update_ddr_freq(int ddr_rate)
  22687. +{
  22688. + int i, j;
  22689. + unsigned int reg;
  22690. + bool dll_off = false;
  22691. + unsigned int online_cpus = 0;
  22692. + int cpu = 0;
  22693. + int me;
  22694. +
  22695. + if (!can_change_ddr_freq())
  22696. + return -1;
  22697. +
  22698. + if (ddr_rate == curr_ddr_rate)
  22699. + return 0;
  22700. +
  22701. + pr_debug("Bus freq set to %d start...\n", ddr_rate);
  22702. +
  22703. + if (low_bus_freq_mode || audio_bus_freq_mode)
  22704. + dll_off = true;
  22705. +
  22706. + iram_ddr_settings[0][0] = ddr_settings_size;
  22707. + iram_iomux_settings[0][0] = iomux_settings_size;
  22708. + if (ddr_rate == ddr_med_rate && cpu_is_imx6q()) {
  22709. + for (i = 0; i < ARRAY_SIZE(ddr3_dll_mx6q); i++) {
  22710. + iram_ddr_settings[i + 1][0] =
  22711. + normal_mmdc_settings[i][0];
  22712. + iram_ddr_settings[i + 1][1] =
  22713. + normal_mmdc_settings[i][1];
  22714. + }
  22715. + for (j = 0, i = ARRAY_SIZE(ddr3_dll_mx6q);
  22716. + i < iram_ddr_settings[0][0]; j++, i++) {
  22717. + iram_ddr_settings[i + 1][0] =
  22718. + ddr3_400[j][0];
  22719. + iram_ddr_settings[i + 1][1] =
  22720. + ddr3_400[j][1];
  22721. + }
  22722. + } else if (ddr_rate == ddr_normal_rate) {
  22723. + for (i = 0; i < iram_ddr_settings[0][0]; i++) {
  22724. + iram_ddr_settings[i + 1][0] =
  22725. + normal_mmdc_settings[i][0];
  22726. + iram_ddr_settings[i + 1][1] =
  22727. + normal_mmdc_settings[i][1];
  22728. + }
  22729. + }
  22730. +
  22731. + /* ensure that all Cores are in WFE. */
  22732. + local_irq_disable();
  22733. +
  22734. + me = smp_processor_id();
  22735. +
  22736. + *((char *)(&cpus_in_wfe) + (u8)me) = 0xff;
  22737. + wait_for_ddr_freq_update = true;
  22738. + for_each_online_cpu(cpu) {
  22739. + *((char *)(&online_cpus) + (u8)cpu) = 0xff;
  22740. + if (cpu != me) {
  22741. + /* set the interrupt to be pending in the GIC. */
  22742. + reg = 1 << (irqs_used[cpu] % 32);
  22743. + writel_relaxed(reg, gic_dist_base + GIC_DIST_PENDING_SET
  22744. + + (irqs_used[cpu] / 32) * 4);
  22745. + }
  22746. + }
  22747. + while (cpus_in_wfe != online_cpus)
  22748. + udelay(5);
  22749. +
  22750. + /*
  22751. + * Flush the TLB, to ensure no TLB maintenance occurs
  22752. + * when DDR is in self-refresh.
  22753. + */
  22754. + local_flush_tlb_all();
  22755. + /* Now we can change the DDR frequency. */
  22756. + mx6_change_ddr_freq(ddr_rate, iram_ddr_settings,
  22757. + dll_off, iram_iomux_settings);
  22758. +
  22759. + curr_ddr_rate = ddr_rate;
  22760. +
  22761. + /* DDR frequency change is done . */
  22762. + wait_for_ddr_freq_update = false;
  22763. +
  22764. + /* wake up all the cores. */
  22765. + sev();
  22766. +
  22767. + *((char *)(&cpus_in_wfe) + (u8)me) = 0;
  22768. +
  22769. + local_irq_enable();
  22770. +
  22771. + pr_debug("Bus freq set to %d done!\n", ddr_rate);
  22772. +
  22773. + return 0;
  22774. +}
  22775. +
  22776. +int init_mmdc_ddr3_settings(struct platform_device *busfreq_pdev)
  22777. +{
  22778. + struct device *dev = &busfreq_pdev->dev;
  22779. + struct platform_device *ocram_dev;
  22780. + unsigned int iram_paddr;
  22781. + int i, err;
  22782. + u32 cpu;
  22783. + struct device_node *node;
  22784. + struct gen_pool *iram_pool;
  22785. +
  22786. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-mmdc-combine");
  22787. + if (!node) {
  22788. + pr_err("failed to find imx6q-mmdc device tree data!\n");
  22789. + return -EINVAL;
  22790. + }
  22791. + mmdc_base = of_iomap(node, 0);
  22792. + WARN(!mmdc_base, "unable to map mmdc registers\n");
  22793. +
  22794. + node = NULL;
  22795. + if (cpu_is_imx6q())
  22796. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-iomuxc");
  22797. + if (cpu_is_imx6dl())
  22798. + node = of_find_compatible_node(NULL, NULL,
  22799. + "fsl,imx6dl-iomuxc");
  22800. + if (!node) {
  22801. + pr_err("failed to find imx6q-iomux device tree data!\n");
  22802. + return -EINVAL;
  22803. + }
  22804. + iomux_base = of_iomap(node, 0);
  22805. + WARN(!iomux_base, "unable to map iomux registers\n");
  22806. +
  22807. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
  22808. + if (!node) {
  22809. + pr_err("failed to find imx6q-ccm device tree data!\n");
  22810. + return -EINVAL;
  22811. + }
  22812. + ccm_base = of_iomap(node, 0);
  22813. + WARN(!ccm_base, "unable to map mmdc registers\n");
  22814. +
  22815. + node = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
  22816. + if (!node) {
  22817. + pr_err("failed to find imx6q-pl310-cache device tree data!\n");
  22818. + return -EINVAL;
  22819. + }
  22820. + l2_base = of_iomap(node, 0);
  22821. + WARN(!ccm_base, "unable to map mmdc registers\n");
  22822. +
  22823. + node = NULL;
  22824. + node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic");
  22825. + if (!node) {
  22826. + pr_err("failed to find imx6q-a9-gic device tree data!\n");
  22827. + return -EINVAL;
  22828. + }
  22829. + gic_dist_base = of_iomap(node, 0);
  22830. + WARN(!gic_dist_base, "unable to map gic dist registers\n");
  22831. +
  22832. + if (cpu_is_imx6q())
  22833. + ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6q) +
  22834. + ARRAY_SIZE(ddr3_calibration);
  22835. + if (cpu_is_imx6dl())
  22836. + ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6dl) +
  22837. + ARRAY_SIZE(ddr3_calibration);
  22838. +
  22839. + normal_mmdc_settings = kmalloc((ddr_settings_size * 8), GFP_KERNEL);
  22840. + if (cpu_is_imx6q()) {
  22841. + memcpy(normal_mmdc_settings, ddr3_dll_mx6q,
  22842. + sizeof(ddr3_dll_mx6q));
  22843. + memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6q)),
  22844. + ddr3_calibration, sizeof(ddr3_calibration));
  22845. + }
  22846. + if (cpu_is_imx6dl()) {
  22847. + memcpy(normal_mmdc_settings, ddr3_dll_mx6dl,
  22848. + sizeof(ddr3_dll_mx6dl));
  22849. + memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6dl)),
  22850. + ddr3_calibration, sizeof(ddr3_calibration));
  22851. + }
  22852. + /* store the original DDR settings at boot. */
  22853. + for (i = 0; i < ddr_settings_size; i++) {
  22854. + /*
  22855. + * writes via command mode register cannot be read back.
  22856. + * hence hardcode them in the initial static array.
  22857. + * this may require modification on a per customer basis.
  22858. + */
  22859. + if (normal_mmdc_settings[i][0] != 0x1C)
  22860. + normal_mmdc_settings[i][1] =
  22861. + readl_relaxed(mmdc_base
  22862. + + normal_mmdc_settings[i][0]);
  22863. + }
  22864. +
  22865. + irqs_used = devm_kzalloc(dev, sizeof(u32) * num_present_cpus(),
  22866. + GFP_KERNEL);
  22867. +
  22868. + for_each_online_cpu(cpu) {
  22869. + int irq;
  22870. +
  22871. + /*
  22872. + * set up a reserved interrupt to get all
  22873. + * the active cores into a WFE state
  22874. + * before changing the DDR frequency.
  22875. + */
  22876. + irq = platform_get_irq(busfreq_pdev, cpu);
  22877. + err = request_irq(irq, wait_in_wfe_irq,
  22878. + IRQF_PERCPU, "mmdc_1", NULL);
  22879. + if (err) {
  22880. + dev_err(dev,
  22881. + "Busfreq:request_irq failed %d, err = %d\n",
  22882. + irq, err);
  22883. + return err;
  22884. + }
  22885. + err = irq_set_affinity(irq, cpumask_of(cpu));
  22886. + if (err) {
  22887. + dev_err(dev,
  22888. + "Busfreq: Cannot set irq affinity irq=%d,\n",
  22889. + irq);
  22890. + return err;
  22891. + }
  22892. + irqs_used[cpu] = irq;
  22893. + }
  22894. +
  22895. + node = NULL;
  22896. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  22897. + if (!node) {
  22898. + dev_err(dev, "%s: failed to find ocram node\n",
  22899. + __func__);
  22900. + return -EINVAL;
  22901. + }
  22902. +
  22903. + ocram_dev = of_find_device_by_node(node);
  22904. + if (!ocram_dev) {
  22905. + dev_err(dev, "failed to find ocram device!\n");
  22906. + return -EINVAL;
  22907. + }
  22908. +
  22909. + iram_pool = dev_get_gen_pool(&ocram_dev->dev);
  22910. + if (!iram_pool) {
  22911. + dev_err(dev, "iram pool unavailable!\n");
  22912. + return -EINVAL;
  22913. + }
  22914. +
  22915. + iomux_settings_size = ARRAY_SIZE(iomux_offsets_mx6q);
  22916. + iram_iomux_settings = gen_pool_alloc(iram_pool,
  22917. + (iomux_settings_size * 8) + 8);
  22918. + if (!iram_iomux_settings) {
  22919. + dev_err(dev, "unable to alloc iram for IOMUX settings!\n");
  22920. + return -ENOMEM;
  22921. + }
  22922. +
  22923. + /*
  22924. + * Allocate extra space to store the number of entries in the
  22925. + * ddr_settings plus 4 extra regsiter information that needs
  22926. + * to be passed to the frequency change code.
  22927. + * sizeof(iram_ddr_settings) = sizeof(ddr_settings) +
  22928. + * entries in ddr_settings + 16.
  22929. + * The last 4 enties store the addresses of the registers:
  22930. + * CCM_BASE_ADDR
  22931. + * MMDC_BASE_ADDR
  22932. + * IOMUX_BASE_ADDR
  22933. + * L2X0_BASE_ADDR
  22934. + */
  22935. + iram_ddr_settings = gen_pool_alloc(iram_pool,
  22936. + (ddr_settings_size * 8) + 8 + 32);
  22937. + if (!iram_ddr_settings) {
  22938. + dev_err(dev, "unable to alloc iram for ddr settings!\n");
  22939. + return -ENOMEM;
  22940. + }
  22941. + i = ddr_settings_size + 1;
  22942. + iram_ddr_settings[i][0] = (unsigned long)mmdc_base;
  22943. + iram_ddr_settings[i+1][0] = (unsigned long)ccm_base;
  22944. + iram_ddr_settings[i+2][0] = (unsigned long)iomux_base;
  22945. + iram_ddr_settings[i+3][0] = (unsigned long)l2_base;
  22946. +
  22947. + if (cpu_is_imx6q()) {
  22948. + /* store the IOMUX settings at boot. */
  22949. + for (i = 0; i < iomux_settings_size; i++) {
  22950. + iomux_offsets_mx6q[i][1] =
  22951. + readl_relaxed(iomux_base +
  22952. + iomux_offsets_mx6q[i][0]);
  22953. + iram_iomux_settings[i+1][0] = iomux_offsets_mx6q[i][0];
  22954. + iram_iomux_settings[i+1][1] = iomux_offsets_mx6q[i][1];
  22955. + }
  22956. + }
  22957. +
  22958. + if (cpu_is_imx6dl()) {
  22959. + for (i = 0; i < iomux_settings_size; i++) {
  22960. + iomux_offsets_mx6dl[i][1] =
  22961. + readl_relaxed(iomux_base +
  22962. + iomux_offsets_mx6dl[i][0]);
  22963. + iram_iomux_settings[i+1][0] = iomux_offsets_mx6dl[i][0];
  22964. + iram_iomux_settings[i+1][1] = iomux_offsets_mx6dl[i][1];
  22965. + }
  22966. + }
  22967. +
  22968. + ddr_freq_change_iram_base = gen_pool_alloc(iram_pool,
  22969. + DDR_FREQ_CHANGE_SIZE);
  22970. + if (!ddr_freq_change_iram_base) {
  22971. + dev_err(dev, "Cannot alloc iram for ddr freq change code!\n");
  22972. + return -ENOMEM;
  22973. + }
  22974. +
  22975. + iram_paddr = gen_pool_virt_to_phys(iram_pool,
  22976. + (unsigned long)ddr_freq_change_iram_base);
  22977. + /*
  22978. + * Need to remap the area here since we want
  22979. + * the memory region to be executable.
  22980. + */
  22981. + ddr_freq_change_iram_base = __arm_ioremap(iram_paddr,
  22982. + DDR_FREQ_CHANGE_SIZE,
  22983. + MT_MEMORY_RWX_NONCACHED);
  22984. + mx6_change_ddr_freq = (void *)fncpy(ddr_freq_change_iram_base,
  22985. + &mx6_ddr3_freq_change, DDR_FREQ_CHANGE_SIZE);
  22986. +
  22987. + curr_ddr_rate = ddr_normal_rate;
  22988. +
  22989. + return 0;
  22990. +}
  22991. diff -Nur linux-3.14.15/arch/arm/mach-imx/busfreq-imx6.c linux-linaro-stable-mx6/arch/arm/mach-imx/busfreq-imx6.c
  22992. --- linux-3.14.15/arch/arm/mach-imx/busfreq-imx6.c 1970-01-01 01:00:00.000000000 +0100
  22993. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/busfreq-imx6.c 2014-08-20 19:31:40.080843045 +0200
  22994. @@ -0,0 +1,952 @@
  22995. +/*
  22996. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  22997. + *
  22998. + * This program is free software; you can redistribute it and/or modify
  22999. + * it under the terms of the GNU General Public License as published by
  23000. + * the Free Software Foundation; either version 2 of the License, or
  23001. + * (at your option) any later version.
  23002. +
  23003. + * This program is distributed in the hope that it will be useful,
  23004. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23005. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23006. + * GNU General Public License for more details.
  23007. +
  23008. + * You should have received a copy of the GNU General Public License along
  23009. + * with this program; if not, write to the Free Software Foundation, Inc.,
  23010. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  23011. + */
  23012. +
  23013. +/*!
  23014. + * @file busfreq-imx6.c
  23015. + *
  23016. + * @brief A common API for the Freescale Semiconductor iMX6 Busfreq API
  23017. + *
  23018. + * The APIs are for setting bus frequency to different values based on the
  23019. + * highest freqeuncy requested.
  23020. + *
  23021. + * @ingroup PM
  23022. + */
  23023. +
  23024. +#include <asm/cacheflush.h>
  23025. +#include <asm/io.h>
  23026. +#include <asm/mach/map.h>
  23027. +#include <asm/mach-types.h>
  23028. +#include <asm/tlb.h>
  23029. +#include <linux/busfreq-imx6.h>
  23030. +#include <linux/clk.h>
  23031. +#include <linux/clk-provider.h>
  23032. +#include <linux/delay.h>
  23033. +#include <linux/module.h>
  23034. +#include <linux/mutex.h>
  23035. +#include <linux/of.h>
  23036. +#include <linux/platform_device.h>
  23037. +#include <linux/proc_fs.h>
  23038. +#include <linux/reboot.h>
  23039. +#include <linux/regulator/consumer.h>
  23040. +#include <linux/sched.h>
  23041. +#include <linux/suspend.h>
  23042. +#include "hardware.h"
  23043. +
  23044. +#define LPAPM_CLK 24000000
  23045. +#define DDR3_AUDIO_CLK 50000000
  23046. +#define LPDDR2_AUDIO_CLK 100000000
  23047. +
  23048. +int high_bus_freq_mode;
  23049. +int med_bus_freq_mode;
  23050. +int audio_bus_freq_mode;
  23051. +int low_bus_freq_mode;
  23052. +int ultra_low_bus_freq_mode;
  23053. +unsigned int ddr_med_rate;
  23054. +unsigned int ddr_normal_rate;
  23055. +
  23056. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23057. +static int bus_freq_scaling_initialized;
  23058. +static struct device *busfreq_dev;
  23059. +static int busfreq_suspended;
  23060. +static u32 org_arm_rate;
  23061. +static int bus_freq_scaling_is_active;
  23062. +static int high_bus_count, med_bus_count, audio_bus_count, low_bus_count;
  23063. +static unsigned int ddr_low_rate;
  23064. +
  23065. +extern int init_mmdc_lpddr2_settings(struct platform_device *dev);
  23066. +extern int init_mmdc_ddr3_settings(struct platform_device *dev);
  23067. +extern int update_ddr_freq(int ddr_rate);
  23068. +extern int update_lpddr2_freq(int ddr_rate);
  23069. +
  23070. +DEFINE_MUTEX(bus_freq_mutex);
  23071. +static DEFINE_SPINLOCK(freq_lock);
  23072. +
  23073. +static struct clk *pll2_400;
  23074. +static struct clk *periph_clk;
  23075. +static struct clk *periph_pre_clk;
  23076. +static struct clk *periph_clk2_sel;
  23077. +static struct clk *periph_clk2;
  23078. +static struct clk *osc_clk;
  23079. +static struct clk *cpu_clk;
  23080. +static struct clk *pll3;
  23081. +static struct clk *pll2;
  23082. +static struct clk *pll2_200;
  23083. +static struct clk *pll1_sys;
  23084. +static struct clk *periph2_clk;
  23085. +static struct clk *ocram_clk;
  23086. +static struct clk *ahb_clk;
  23087. +static struct clk *pll1_sw_clk;
  23088. +static struct clk *periph2_pre_clk;
  23089. +static struct clk *periph2_clk2_sel;
  23090. +static struct clk *periph2_clk2;
  23091. +static struct clk *step_clk;
  23092. +static struct clk *axi_sel_clk;
  23093. +static struct clk *pll3_pfd1_540m;
  23094. +
  23095. +static u32 pll2_org_rate;
  23096. +static struct delayed_work low_bus_freq_handler;
  23097. +static struct delayed_work bus_freq_daemon;
  23098. +
  23099. +static void enter_lpm_imx6sl(void)
  23100. +{
  23101. + unsigned long flags;
  23102. +
  23103. + if (high_bus_freq_mode) {
  23104. + pll2_org_rate = clk_get_rate(pll2);
  23105. + /* Set periph_clk to be sourced from OSC_CLK */
  23106. + clk_set_parent(periph_clk2_sel, osc_clk);
  23107. + clk_set_parent(periph_clk, periph_clk2);
  23108. + /* Ensure AHB/AXI clks are at 24MHz. */
  23109. + clk_set_rate(ahb_clk, LPAPM_CLK);
  23110. + clk_set_rate(ocram_clk, LPAPM_CLK);
  23111. + }
  23112. + if (audio_bus_count) {
  23113. + /* Set AHB to 8MHz to lower pwer.*/
  23114. + clk_set_rate(ahb_clk, LPAPM_CLK / 3);
  23115. +
  23116. + /* Set up DDR to 100MHz. */
  23117. + spin_lock_irqsave(&freq_lock, flags);
  23118. + update_lpddr2_freq(LPDDR2_AUDIO_CLK);
  23119. + spin_unlock_irqrestore(&freq_lock, flags);
  23120. +
  23121. + /* Fix the clock tree in kernel */
  23122. + clk_set_rate(pll2, pll2_org_rate);
  23123. + clk_set_parent(periph2_pre_clk, pll2_200);
  23124. + clk_set_parent(periph2_clk, periph2_pre_clk);
  23125. +
  23126. + if (low_bus_freq_mode || ultra_low_bus_freq_mode) {
  23127. + /*
  23128. + * Swtich ARM to run off PLL2_PFD2_400MHz
  23129. + * since DDR is anyway at 100MHz.
  23130. + */
  23131. + clk_set_parent(step_clk, pll2_400);
  23132. + clk_set_parent(pll1_sw_clk, step_clk);
  23133. + /*
  23134. + * Ensure that the clock will be
  23135. + * at original speed.
  23136. + */
  23137. + clk_set_rate(cpu_clk, org_arm_rate);
  23138. + }
  23139. + low_bus_freq_mode = 0;
  23140. + ultra_low_bus_freq_mode = 0;
  23141. + audio_bus_freq_mode = 1;
  23142. + } else {
  23143. + u32 arm_div, pll1_rate;
  23144. + org_arm_rate = clk_get_rate(cpu_clk);
  23145. + if (low_bus_freq_mode && low_bus_count == 0) {
  23146. + /*
  23147. + * We are already in DDR @ 24MHz state, but
  23148. + * no one but ARM needs the DDR. In this case,
  23149. + * we can lower the DDR freq to 1MHz when ARM
  23150. + * enters WFI in this state. Keep track of this state.
  23151. + */
  23152. + ultra_low_bus_freq_mode = 1;
  23153. + low_bus_freq_mode = 0;
  23154. + audio_bus_freq_mode = 0;
  23155. + } else {
  23156. + if (!ultra_low_bus_freq_mode && !low_bus_freq_mode) {
  23157. + /*
  23158. + * Set DDR to 24MHz.
  23159. + * Since we are going to bypass PLL2,
  23160. + * we need to move ARM clk off PLL2_PFD2
  23161. + * to PLL1. Make sure the PLL1 is running
  23162. + * at the lowest possible freq.
  23163. + */
  23164. + clk_set_rate(pll1_sys,
  23165. + clk_round_rate(pll1_sys, org_arm_rate));
  23166. + pll1_rate = clk_get_rate(pll1_sys);
  23167. + arm_div = pll1_rate / org_arm_rate + 1;
  23168. + /*
  23169. + * Ensure ARM CLK is lower before
  23170. + * changing the parent.
  23171. + */
  23172. + clk_set_rate(cpu_clk, org_arm_rate / arm_div);
  23173. + /* Now set the ARM clk parent to PLL1_SYS. */
  23174. + clk_set_parent(pll1_sw_clk, pll1_sys);
  23175. +
  23176. + /*
  23177. + * Set STEP_CLK back to OSC to save power and
  23178. + * also to maintain the parent.The WFI iram code
  23179. + * will switch step_clk to osc, but the clock API
  23180. + * is not aware of the change and when a new request
  23181. + * to change the step_clk parent to pll2_pfd2_400M
  23182. + * is requested sometime later, the change is ignored.
  23183. + */
  23184. + clk_set_parent(step_clk, osc_clk);
  23185. + /* Now set DDR to 24MHz. */
  23186. + spin_lock_irqsave(&freq_lock, flags);
  23187. + update_lpddr2_freq(LPAPM_CLK);
  23188. + spin_unlock_irqrestore(&freq_lock, flags);
  23189. +
  23190. + /*
  23191. + * Fix the clock tree in kernel.
  23192. + * Make sure PLL2 rate is updated as it gets
  23193. + * bypassed in the DDR freq change code.
  23194. + */
  23195. + clk_set_rate(pll2, LPAPM_CLK);
  23196. + clk_set_parent(periph2_clk2_sel, pll2);
  23197. + clk_set_parent(periph2_clk, periph2_clk2_sel);
  23198. +
  23199. + }
  23200. + if (low_bus_count == 0) {
  23201. + ultra_low_bus_freq_mode = 1;
  23202. + low_bus_freq_mode = 0;
  23203. + } else {
  23204. + ultra_low_bus_freq_mode = 0;
  23205. + low_bus_freq_mode = 1;
  23206. + }
  23207. + audio_bus_freq_mode = 0;
  23208. + }
  23209. + }
  23210. +}
  23211. +
  23212. +static void exit_lpm_imx6sl(void)
  23213. +{
  23214. + unsigned long flags;
  23215. +
  23216. + spin_lock_irqsave(&freq_lock, flags);
  23217. + /* Change DDR freq in IRAM. */
  23218. + update_lpddr2_freq(ddr_normal_rate);
  23219. + spin_unlock_irqrestore(&freq_lock, flags);
  23220. +
  23221. + /*
  23222. + * Fix the clock tree in kernel.
  23223. + * Make sure PLL2 rate is updated as it gets
  23224. + * un-bypassed in the DDR freq change code.
  23225. + */
  23226. + clk_set_rate(pll2, pll2_org_rate);
  23227. + clk_set_parent(periph2_pre_clk, pll2_400);
  23228. + clk_set_parent(periph2_clk, periph2_pre_clk);
  23229. +
  23230. + /* Ensure that periph_clk is sourced from PLL2_400. */
  23231. + clk_set_parent(periph_pre_clk, pll2_400);
  23232. + /*
  23233. + * Before switching the perhiph_clk, ensure that the
  23234. + * AHB/AXI will not be too fast.
  23235. + */
  23236. + clk_set_rate(ahb_clk, LPAPM_CLK / 3);
  23237. + clk_set_rate(ocram_clk, LPAPM_CLK / 2);
  23238. + clk_set_parent(periph_clk, periph_pre_clk);
  23239. +
  23240. + if (low_bus_freq_mode || ultra_low_bus_freq_mode) {
  23241. + /* Move ARM from PLL1_SW_CLK to PLL2_400. */
  23242. + clk_set_parent(step_clk, pll2_400);
  23243. + clk_set_parent(pll1_sw_clk, step_clk);
  23244. + clk_set_rate(cpu_clk, org_arm_rate);
  23245. + ultra_low_bus_freq_mode = 0;
  23246. + }
  23247. +}
  23248. +
  23249. +int reduce_bus_freq(void)
  23250. +{
  23251. + int ret = 0;
  23252. + clk_prepare_enable(pll3);
  23253. + if (cpu_is_imx6sl())
  23254. + enter_lpm_imx6sl();
  23255. + else {
  23256. + if (cpu_is_imx6dl() && (clk_get_parent(axi_sel_clk)
  23257. + != periph_clk))
  23258. + /* Set axi to periph_clk */
  23259. + clk_set_parent(axi_sel_clk, periph_clk);
  23260. +
  23261. + if (audio_bus_count) {
  23262. + /* Need to ensure that PLL2_PFD_400M is kept ON. */
  23263. + clk_prepare_enable(pll2_400);
  23264. + update_ddr_freq(DDR3_AUDIO_CLK);
  23265. + /* Make sure periph clk's parent also got updated */
  23266. + ret = clk_set_parent(periph_clk2_sel, pll3);
  23267. + if (ret)
  23268. + dev_WARN(busfreq_dev,
  23269. + "%s: %d: clk set parent fail!\n",
  23270. + __func__, __LINE__);
  23271. + ret = clk_set_parent(periph_pre_clk, pll2_200);
  23272. + if (ret)
  23273. + dev_WARN(busfreq_dev,
  23274. + "%s: %d: clk set parent fail!\n",
  23275. + __func__, __LINE__);
  23276. + ret = clk_set_parent(periph_clk, periph_pre_clk);
  23277. + if (ret)
  23278. + dev_WARN(busfreq_dev,
  23279. + "%s: %d: clk set parent fail!\n",
  23280. + __func__, __LINE__);
  23281. + audio_bus_freq_mode = 1;
  23282. + low_bus_freq_mode = 0;
  23283. + } else {
  23284. + update_ddr_freq(LPAPM_CLK);
  23285. + /* Make sure periph clk's parent also got updated */
  23286. + ret = clk_set_parent(periph_clk2_sel, osc_clk);
  23287. + if (ret)
  23288. + dev_WARN(busfreq_dev,
  23289. + "%s: %d: clk set parent fail!\n",
  23290. + __func__, __LINE__);
  23291. + /* Set periph_clk parent to OSC via periph_clk2_sel */
  23292. + ret = clk_set_parent(periph_clk, periph_clk2);
  23293. + if (ret)
  23294. + dev_WARN(busfreq_dev,
  23295. + "%s: %d: clk set parent fail!\n",
  23296. + __func__, __LINE__);
  23297. + if (audio_bus_freq_mode)
  23298. + clk_disable_unprepare(pll2_400);
  23299. + low_bus_freq_mode = 1;
  23300. + audio_bus_freq_mode = 0;
  23301. + }
  23302. + }
  23303. + clk_disable_unprepare(pll3);
  23304. +
  23305. + med_bus_freq_mode = 0;
  23306. + high_bus_freq_mode = 0;
  23307. +
  23308. + if (audio_bus_freq_mode)
  23309. + dev_dbg(busfreq_dev, "Bus freq set to audio mode. Count:\
  23310. + high %d, med %d, audio %d\n",
  23311. + high_bus_count, med_bus_count, audio_bus_count);
  23312. + if (low_bus_freq_mode)
  23313. + dev_dbg(busfreq_dev, "Bus freq set to low mode. Count:\
  23314. + high %d, med %d, audio %d\n",
  23315. + high_bus_count, med_bus_count, audio_bus_count);
  23316. +
  23317. + return ret;
  23318. +}
  23319. +
  23320. +static void reduce_bus_freq_handler(struct work_struct *work)
  23321. +{
  23322. + mutex_lock(&bus_freq_mutex);
  23323. +
  23324. + reduce_bus_freq();
  23325. +
  23326. + mutex_unlock(&bus_freq_mutex);
  23327. +}
  23328. +
  23329. +/*
  23330. + * Set the DDR, AHB to 24MHz.
  23331. + * This mode will be activated only when none of the modules that
  23332. + * need a higher DDR or AHB frequency are active.
  23333. + */
  23334. +int set_low_bus_freq(void)
  23335. +{
  23336. + if (busfreq_suspended)
  23337. + return 0;
  23338. +
  23339. + if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
  23340. + return 0;
  23341. +
  23342. + /*
  23343. + * Check to see if we need to got from
  23344. + * low bus freq mode to audio bus freq mode.
  23345. + * If so, the change needs to be done immediately.
  23346. + */
  23347. + if (audio_bus_count && (low_bus_freq_mode || ultra_low_bus_freq_mode))
  23348. + reduce_bus_freq();
  23349. + else
  23350. + /*
  23351. + * Don't lower the frequency immediately. Instead
  23352. + * scheduled a delayed work and drop the freq if
  23353. + * the conditions still remain the same.
  23354. + */
  23355. + schedule_delayed_work(&low_bus_freq_handler,
  23356. + usecs_to_jiffies(3000000));
  23357. + return 0;
  23358. +}
  23359. +
  23360. +/*
  23361. + * Set the DDR to either 528MHz or 400MHz for iMX6qd
  23362. + * or 400MHz for iMX6dl.
  23363. + */
  23364. +int set_high_bus_freq(int high_bus_freq)
  23365. +{
  23366. + int ret = 0;
  23367. + struct clk *periph_clk_parent;
  23368. +
  23369. + if (bus_freq_scaling_initialized && bus_freq_scaling_is_active)
  23370. + cancel_delayed_work_sync(&low_bus_freq_handler);
  23371. +
  23372. + if (busfreq_suspended)
  23373. + return 0;
  23374. +
  23375. + if (cpu_is_imx6q())
  23376. + periph_clk_parent = pll2;
  23377. + else
  23378. + periph_clk_parent = pll2_400;
  23379. +
  23380. + if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
  23381. + return 0;
  23382. +
  23383. + if (high_bus_freq_mode)
  23384. + return 0;
  23385. +
  23386. + /* medium bus freq is only supported for MX6DQ */
  23387. + if (med_bus_freq_mode && !high_bus_freq)
  23388. + return 0;
  23389. +
  23390. + clk_prepare_enable(pll3);
  23391. + if (cpu_is_imx6sl())
  23392. + exit_lpm_imx6sl();
  23393. + else {
  23394. + if (high_bus_freq) {
  23395. + update_ddr_freq(ddr_normal_rate);
  23396. + /* Make sure periph clk's parent also got updated */
  23397. + ret = clk_set_parent(periph_clk2_sel, pll3);
  23398. + if (ret)
  23399. + dev_WARN(busfreq_dev,
  23400. + "%s: %d: clk set parent fail!\n",
  23401. + __func__, __LINE__);
  23402. + ret = clk_set_parent(periph_pre_clk, periph_clk_parent);
  23403. + if (ret)
  23404. + dev_WARN(busfreq_dev,
  23405. + "%s: %d: clk set parent fail!\n",
  23406. + __func__, __LINE__);
  23407. + ret = clk_set_parent(periph_clk, periph_pre_clk);
  23408. + if (ret)
  23409. + dev_WARN(busfreq_dev,
  23410. + "%s: %d: clk set parent fail!\n",
  23411. + __func__, __LINE__);
  23412. + if (cpu_is_imx6dl() && (clk_get_parent(axi_sel_clk)
  23413. + != pll3_pfd1_540m))
  23414. + /* Set axi to pll3_pfd1_540m */
  23415. + clk_set_parent(axi_sel_clk, pll3_pfd1_540m);
  23416. + } else {
  23417. + update_ddr_freq(ddr_med_rate);
  23418. + /* Make sure periph clk's parent also got updated */
  23419. + ret = clk_set_parent(periph_clk2_sel, pll3);
  23420. + if (ret)
  23421. + dev_WARN(busfreq_dev,
  23422. + "%s: %d: clk set parent fail!\n",
  23423. + __func__, __LINE__);
  23424. + ret = clk_set_parent(periph_pre_clk, pll2_400);
  23425. + if (ret)
  23426. + dev_WARN(busfreq_dev,
  23427. + "%s: %d: clk set parent fail!\n",
  23428. + __func__, __LINE__);
  23429. + ret = clk_set_parent(periph_clk, periph_pre_clk);
  23430. + if (ret)
  23431. + dev_WARN(busfreq_dev,
  23432. + "%s: %d: clk set parent fail!\n",
  23433. + __func__, __LINE__);
  23434. + }
  23435. + if (audio_bus_freq_mode)
  23436. + clk_disable_unprepare(pll2_400);
  23437. + }
  23438. +
  23439. + high_bus_freq_mode = 1;
  23440. + med_bus_freq_mode = 0;
  23441. + low_bus_freq_mode = 0;
  23442. + audio_bus_freq_mode = 0;
  23443. +
  23444. + clk_disable_unprepare(pll3);
  23445. +
  23446. + if (high_bus_freq_mode)
  23447. + dev_dbg(busfreq_dev, "Bus freq set to high mode. Count:\
  23448. + high %d, med %d, audio %d\n",
  23449. + high_bus_count, med_bus_count, audio_bus_count);
  23450. + if (med_bus_freq_mode)
  23451. + dev_dbg(busfreq_dev, "Bus freq set to med mode. Count:\
  23452. + high %d, med %d, audio %d\n",
  23453. + high_bus_count, med_bus_count, audio_bus_count);
  23454. +
  23455. + return 0;
  23456. +}
  23457. +#endif
  23458. +
  23459. +void request_bus_freq(enum bus_freq_mode mode)
  23460. +{
  23461. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23462. + mutex_lock(&bus_freq_mutex);
  23463. +
  23464. + if (mode == BUS_FREQ_HIGH)
  23465. + high_bus_count++;
  23466. + else if (mode == BUS_FREQ_MED)
  23467. + med_bus_count++;
  23468. + else if (mode == BUS_FREQ_AUDIO)
  23469. + audio_bus_count++;
  23470. + else if (mode == BUS_FREQ_LOW)
  23471. + low_bus_count++;
  23472. +
  23473. + if (busfreq_suspended || !bus_freq_scaling_initialized ||
  23474. + !bus_freq_scaling_is_active) {
  23475. + mutex_unlock(&bus_freq_mutex);
  23476. + return;
  23477. + }
  23478. + cancel_delayed_work_sync(&low_bus_freq_handler);
  23479. +
  23480. + if (cpu_is_imx6dl()) {
  23481. + /* No support for medium setpoint on MX6DL. */
  23482. + if (mode == BUS_FREQ_MED) {
  23483. + high_bus_count++;
  23484. + mode = BUS_FREQ_HIGH;
  23485. + }
  23486. + }
  23487. +
  23488. + if ((mode == BUS_FREQ_HIGH) && (!high_bus_freq_mode)) {
  23489. + set_high_bus_freq(1);
  23490. + mutex_unlock(&bus_freq_mutex);
  23491. + return;
  23492. + }
  23493. +
  23494. + if ((mode == BUS_FREQ_MED) && (!high_bus_freq_mode) &&
  23495. + (!med_bus_freq_mode)) {
  23496. + set_high_bus_freq(0);
  23497. + mutex_unlock(&bus_freq_mutex);
  23498. + return;
  23499. + }
  23500. + if ((mode == BUS_FREQ_AUDIO) && (!high_bus_freq_mode) &&
  23501. + (!med_bus_freq_mode) && (!audio_bus_freq_mode)) {
  23502. + set_low_bus_freq();
  23503. + mutex_unlock(&bus_freq_mutex);
  23504. + return;
  23505. + }
  23506. + mutex_unlock(&bus_freq_mutex);
  23507. +#endif
  23508. + return;
  23509. +}
  23510. +EXPORT_SYMBOL(request_bus_freq);
  23511. +
  23512. +void release_bus_freq(enum bus_freq_mode mode)
  23513. +{
  23514. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23515. + mutex_lock(&bus_freq_mutex);
  23516. +
  23517. + if (mode == BUS_FREQ_HIGH) {
  23518. + if (high_bus_count == 0) {
  23519. + dev_err(busfreq_dev, "high bus count mismatch!\n");
  23520. + dump_stack();
  23521. + mutex_unlock(&bus_freq_mutex);
  23522. + return;
  23523. + }
  23524. + high_bus_count--;
  23525. + } else if (mode == BUS_FREQ_MED) {
  23526. + if (med_bus_count == 0) {
  23527. + dev_err(busfreq_dev, "med bus count mismatch!\n");
  23528. + dump_stack();
  23529. + mutex_unlock(&bus_freq_mutex);
  23530. + return;
  23531. + }
  23532. + med_bus_count--;
  23533. + } else if (mode == BUS_FREQ_AUDIO) {
  23534. + if (audio_bus_count == 0) {
  23535. + dev_err(busfreq_dev, "audio bus count mismatch!\n");
  23536. + dump_stack();
  23537. + mutex_unlock(&bus_freq_mutex);
  23538. + return;
  23539. + }
  23540. + audio_bus_count--;
  23541. + } else if (mode == BUS_FREQ_LOW) {
  23542. + if (low_bus_count == 0) {
  23543. + dev_err(busfreq_dev, "low bus count mismatch!\n");
  23544. + dump_stack();
  23545. + mutex_unlock(&bus_freq_mutex);
  23546. + return;
  23547. + }
  23548. + low_bus_count--;
  23549. + }
  23550. +
  23551. + if (busfreq_suspended || !bus_freq_scaling_initialized ||
  23552. + !bus_freq_scaling_is_active) {
  23553. + mutex_unlock(&bus_freq_mutex);
  23554. + return;
  23555. + }
  23556. +
  23557. + if (cpu_is_imx6dl()) {
  23558. + /* No support for medium setpoint on MX6DL. */
  23559. + if (mode == BUS_FREQ_MED) {
  23560. + high_bus_count--;
  23561. + mode = BUS_FREQ_HIGH;
  23562. + }
  23563. + }
  23564. +
  23565. + if ((!audio_bus_freq_mode) && (high_bus_count == 0) &&
  23566. + (med_bus_count == 0) && (audio_bus_count != 0)) {
  23567. + set_low_bus_freq();
  23568. + mutex_unlock(&bus_freq_mutex);
  23569. + return;
  23570. + }
  23571. + if ((!low_bus_freq_mode) && (high_bus_count == 0) &&
  23572. + (med_bus_count == 0) && (audio_bus_count == 0) &&
  23573. + (low_bus_count != 0)) {
  23574. + set_low_bus_freq();
  23575. + mutex_unlock(&bus_freq_mutex);
  23576. + return;
  23577. + }
  23578. + if ((!ultra_low_bus_freq_mode) && (high_bus_count == 0) &&
  23579. + (med_bus_count == 0) && (audio_bus_count == 0) &&
  23580. + (low_bus_count == 0)) {
  23581. + set_low_bus_freq();
  23582. + mutex_unlock(&bus_freq_mutex);
  23583. + return;
  23584. + }
  23585. +
  23586. + mutex_unlock(&bus_freq_mutex);
  23587. +#endif
  23588. + return;
  23589. +}
  23590. +EXPORT_SYMBOL(release_bus_freq);
  23591. +
  23592. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23593. +static void bus_freq_daemon_handler(struct work_struct *work)
  23594. +{
  23595. + mutex_lock(&bus_freq_mutex);
  23596. + if ((!low_bus_freq_mode) && (high_bus_count == 0) &&
  23597. + (med_bus_count == 0) && (audio_bus_count == 0))
  23598. + set_low_bus_freq();
  23599. + mutex_unlock(&bus_freq_mutex);
  23600. +}
  23601. +
  23602. +static ssize_t bus_freq_scaling_enable_show(struct device *dev,
  23603. + struct device_attribute *attr, char *buf)
  23604. +{
  23605. + if (bus_freq_scaling_is_active)
  23606. + return sprintf(buf, "Bus frequency scaling is enabled\n");
  23607. + else
  23608. + return sprintf(buf, "Bus frequency scaling is disabled\n");
  23609. +}
  23610. +
  23611. +static ssize_t bus_freq_scaling_enable_store(struct device *dev,
  23612. + struct device_attribute *attr,
  23613. + const char *buf, size_t size)
  23614. +{
  23615. + if (strncmp(buf, "1", 1) == 0) {
  23616. + bus_freq_scaling_is_active = 1;
  23617. + set_high_bus_freq(1);
  23618. + /*
  23619. + * We set bus freq to highest at the beginning,
  23620. + * so we use this daemon thread to make sure system
  23621. + * can enter low bus mode if
  23622. + * there is no high bus request pending
  23623. + */
  23624. + schedule_delayed_work(&bus_freq_daemon,
  23625. + usecs_to_jiffies(5000000));
  23626. + } else if (strncmp(buf, "0", 1) == 0) {
  23627. + if (bus_freq_scaling_is_active)
  23628. + set_high_bus_freq(1);
  23629. + bus_freq_scaling_is_active = 0;
  23630. + }
  23631. + return size;
  23632. +}
  23633. +
  23634. +static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event,
  23635. + void *dummy)
  23636. +{
  23637. + mutex_lock(&bus_freq_mutex);
  23638. +
  23639. + if (event == PM_SUSPEND_PREPARE) {
  23640. + high_bus_count++;
  23641. + set_high_bus_freq(1);
  23642. + busfreq_suspended = 1;
  23643. + } else if (event == PM_POST_SUSPEND) {
  23644. + busfreq_suspended = 0;
  23645. + high_bus_count--;
  23646. + schedule_delayed_work(&bus_freq_daemon,
  23647. + usecs_to_jiffies(5000000));
  23648. + }
  23649. +
  23650. + mutex_unlock(&bus_freq_mutex);
  23651. +
  23652. + return NOTIFY_OK;
  23653. +}
  23654. +
  23655. +static int busfreq_reboot_notifier_event(struct notifier_block *this,
  23656. + unsigned long event, void *ptr)
  23657. +{
  23658. + /* System is rebooting. Set the system into high_bus_freq_mode. */
  23659. + request_bus_freq(BUS_FREQ_HIGH);
  23660. +
  23661. + return 0;
  23662. +}
  23663. +
  23664. +static struct notifier_block imx_bus_freq_pm_notifier = {
  23665. + .notifier_call = bus_freq_pm_notify,
  23666. +};
  23667. +
  23668. +static struct notifier_block imx_busfreq_reboot_notifier = {
  23669. + .notifier_call = busfreq_reboot_notifier_event,
  23670. +};
  23671. +
  23672. +
  23673. +static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show,
  23674. + bus_freq_scaling_enable_store);
  23675. +#endif
  23676. +
  23677. +/*!
  23678. + * This is the probe routine for the bus frequency driver.
  23679. + *
  23680. + * @param pdev The platform device structure
  23681. + *
  23682. + * @return The function returns 0 on success
  23683. + *
  23684. + */
  23685. +
  23686. +static int busfreq_probe(struct platform_device *pdev)
  23687. +{
  23688. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23689. + u32 err;
  23690. +
  23691. + busfreq_dev = &pdev->dev;
  23692. +
  23693. + pll2_400 = devm_clk_get(&pdev->dev, "pll2_pfd2_396m");
  23694. + if (IS_ERR(pll2_400)) {
  23695. + dev_err(busfreq_dev, "%s: failed to get pll2_pfd2_396m\n",
  23696. + __func__);
  23697. + return PTR_ERR(pll2_400);
  23698. + }
  23699. +
  23700. + pll2_200 = devm_clk_get(&pdev->dev, "pll2_198m");
  23701. + if (IS_ERR(pll2_200)) {
  23702. + dev_err(busfreq_dev, "%s: failed to get pll2_198m\n",
  23703. + __func__);
  23704. + return PTR_ERR(pll2_200);
  23705. + }
  23706. +
  23707. + pll2 = devm_clk_get(&pdev->dev, "pll2_bus");
  23708. + if (IS_ERR(pll2)) {
  23709. + dev_err(busfreq_dev, "%s: failed to get pll2_bus\n",
  23710. + __func__);
  23711. + return PTR_ERR(pll2);
  23712. + }
  23713. +
  23714. + cpu_clk = devm_clk_get(&pdev->dev, "arm");
  23715. + if (IS_ERR(cpu_clk)) {
  23716. + dev_err(busfreq_dev, "%s: failed to get cpu_clk\n",
  23717. + __func__);
  23718. + return PTR_ERR(cpu_clk);
  23719. + }
  23720. +
  23721. + pll3 = devm_clk_get(&pdev->dev, "pll3_usb_otg");
  23722. + if (IS_ERR(pll3)) {
  23723. + dev_err(busfreq_dev, "%s: failed to get pll3_usb_otg\n",
  23724. + __func__);
  23725. + return PTR_ERR(pll3);
  23726. + }
  23727. +
  23728. + periph_clk = devm_clk_get(&pdev->dev, "periph");
  23729. + if (IS_ERR(periph_clk)) {
  23730. + dev_err(busfreq_dev, "%s: failed to get periph\n",
  23731. + __func__);
  23732. + return PTR_ERR(periph_clk);
  23733. + }
  23734. +
  23735. + periph_pre_clk = devm_clk_get(&pdev->dev, "periph_pre");
  23736. + if (IS_ERR(periph_pre_clk)) {
  23737. + dev_err(busfreq_dev, "%s: failed to get periph_pre\n",
  23738. + __func__);
  23739. + return PTR_ERR(periph_pre_clk);
  23740. + }
  23741. +
  23742. + periph_clk2 = devm_clk_get(&pdev->dev, "periph_clk2");
  23743. + if (IS_ERR(periph_clk2)) {
  23744. + dev_err(busfreq_dev, "%s: failed to get periph_clk2\n",
  23745. + __func__);
  23746. + return PTR_ERR(periph_clk2);
  23747. + }
  23748. +
  23749. + periph_clk2_sel = devm_clk_get(&pdev->dev, "periph_clk2_sel");
  23750. + if (IS_ERR(periph_clk2_sel)) {
  23751. + dev_err(busfreq_dev, "%s: failed to get periph_clk2_sel\n",
  23752. + __func__);
  23753. + return PTR_ERR(periph_clk2_sel);
  23754. + }
  23755. +
  23756. + osc_clk = devm_clk_get(&pdev->dev, "osc");
  23757. + if (IS_ERR(osc_clk)) {
  23758. + dev_err(busfreq_dev, "%s: failed to get osc_clk\n",
  23759. + __func__);
  23760. + return PTR_ERR(osc_clk);
  23761. + }
  23762. +
  23763. + if (cpu_is_imx6dl()) {
  23764. + axi_sel_clk = devm_clk_get(&pdev->dev, "axi_sel");
  23765. + if (IS_ERR(axi_sel_clk)) {
  23766. + dev_err(busfreq_dev, "%s: failed to get axi_sel_clk\n",
  23767. + __func__);
  23768. + return PTR_ERR(axi_sel_clk);
  23769. + }
  23770. +
  23771. + pll3_pfd1_540m = devm_clk_get(&pdev->dev, "pll3_pfd1_540m");
  23772. + if (IS_ERR(pll3_pfd1_540m)) {
  23773. + dev_err(busfreq_dev,
  23774. + "%s: failed to get pll3_pfd1_540m\n", __func__);
  23775. + return PTR_ERR(pll3_pfd1_540m);
  23776. + }
  23777. + }
  23778. +
  23779. + if (cpu_is_imx6sl()) {
  23780. + pll1_sys = devm_clk_get(&pdev->dev, "pll1_sys");
  23781. + if (IS_ERR(pll1_sys)) {
  23782. + dev_err(busfreq_dev, "%s: failed to get pll1_sys\n",
  23783. + __func__);
  23784. + return PTR_ERR(pll1_sys);
  23785. + }
  23786. +
  23787. + ahb_clk = devm_clk_get(&pdev->dev, "ahb");
  23788. + if (IS_ERR(ahb_clk)) {
  23789. + dev_err(busfreq_dev, "%s: failed to get ahb_clk\n",
  23790. + __func__);
  23791. + return PTR_ERR(ahb_clk);
  23792. + }
  23793. +
  23794. + ocram_clk = devm_clk_get(&pdev->dev, "ocram");
  23795. + if (IS_ERR(ocram_clk)) {
  23796. + dev_err(busfreq_dev, "%s: failed to get ocram_clk\n",
  23797. + __func__);
  23798. + return PTR_ERR(ocram_clk);
  23799. + }
  23800. +
  23801. + pll1_sw_clk = devm_clk_get(&pdev->dev, "pll1_sw");
  23802. + if (IS_ERR(pll1_sw_clk)) {
  23803. + dev_err(busfreq_dev, "%s: failed to get pll1_sw_clk\n",
  23804. + __func__);
  23805. + return PTR_ERR(pll1_sw_clk);
  23806. + }
  23807. +
  23808. + periph2_clk = devm_clk_get(&pdev->dev, "periph2");
  23809. + if (IS_ERR(periph2_clk)) {
  23810. + dev_err(busfreq_dev, "%s: failed to get periph2\n",
  23811. + __func__);
  23812. + return PTR_ERR(periph2_clk);
  23813. + }
  23814. +
  23815. + periph2_pre_clk = devm_clk_get(&pdev->dev, "periph2_pre");
  23816. + if (IS_ERR(periph2_pre_clk)) {
  23817. + dev_err(busfreq_dev,
  23818. + "%s: failed to get periph2_pre_clk\n",
  23819. + __func__);
  23820. + return PTR_ERR(periph2_pre_clk);
  23821. + }
  23822. +
  23823. + periph2_clk2 = devm_clk_get(&pdev->dev, "periph2_clk2");
  23824. + if (IS_ERR(periph2_clk2)) {
  23825. + dev_err(busfreq_dev,
  23826. + "%s: failed to get periph2_clk2\n",
  23827. + __func__);
  23828. + return PTR_ERR(periph2_clk2);
  23829. + }
  23830. +
  23831. + periph2_clk2_sel = devm_clk_get(&pdev->dev, "periph2_clk2_sel");
  23832. + if (IS_ERR(periph2_clk2_sel)) {
  23833. + dev_err(busfreq_dev,
  23834. + "%s: failed to get periph2_clk2_sel\n",
  23835. + __func__);
  23836. + return PTR_ERR(periph2_clk2_sel);
  23837. + }
  23838. +
  23839. + step_clk = devm_clk_get(&pdev->dev, "step");
  23840. + if (IS_ERR(step_clk)) {
  23841. + dev_err(busfreq_dev,
  23842. + "%s: failed to get step_clk\n",
  23843. + __func__);
  23844. + return PTR_ERR(periph2_clk2_sel);
  23845. + }
  23846. +
  23847. + }
  23848. +
  23849. + err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
  23850. + if (err) {
  23851. + dev_err(busfreq_dev,
  23852. + "Unable to register sysdev entry for BUSFREQ");
  23853. + return err;
  23854. + }
  23855. +
  23856. + if (of_property_read_u32(pdev->dev.of_node, "fsl,max_ddr_freq",
  23857. + &ddr_normal_rate)) {
  23858. + dev_err(busfreq_dev, "max_ddr_freq entry missing\n");
  23859. + return -EINVAL;
  23860. + }
  23861. +#endif
  23862. +
  23863. + high_bus_freq_mode = 1;
  23864. + med_bus_freq_mode = 0;
  23865. + low_bus_freq_mode = 0;
  23866. + audio_bus_freq_mode = 0;
  23867. + ultra_low_bus_freq_mode = 0;
  23868. +
  23869. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23870. + bus_freq_scaling_is_active = 1;
  23871. + bus_freq_scaling_initialized = 1;
  23872. +
  23873. + ddr_low_rate = LPAPM_CLK;
  23874. + if (cpu_is_imx6q()) {
  23875. + if (of_property_read_u32(pdev->dev.of_node, "fsl,med_ddr_freq",
  23876. + &ddr_med_rate)) {
  23877. + dev_info(busfreq_dev,
  23878. + "DDR medium rate not supported.\n");
  23879. + ddr_med_rate = ddr_normal_rate;
  23880. + }
  23881. + }
  23882. +
  23883. + INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler);
  23884. + INIT_DELAYED_WORK(&bus_freq_daemon, bus_freq_daemon_handler);
  23885. + register_pm_notifier(&imx_bus_freq_pm_notifier);
  23886. + register_reboot_notifier(&imx_busfreq_reboot_notifier);
  23887. +
  23888. + if (cpu_is_imx6sl())
  23889. + err = init_mmdc_lpddr2_settings(pdev);
  23890. + else
  23891. + err = init_mmdc_ddr3_settings(pdev);
  23892. + if (err) {
  23893. + dev_err(busfreq_dev, "Busfreq init of MMDC failed\n");
  23894. + return err;
  23895. + }
  23896. +#endif
  23897. + return 0;
  23898. +}
  23899. +
  23900. +static const struct of_device_id imx6_busfreq_ids[] = {
  23901. + { .compatible = "fsl,imx6_busfreq", },
  23902. + { /* sentinel */ }
  23903. +};
  23904. +
  23905. +static struct platform_driver busfreq_driver = {
  23906. + .driver = {
  23907. + .name = "imx6_busfreq",
  23908. + .owner = THIS_MODULE,
  23909. + .of_match_table = imx6_busfreq_ids,
  23910. + },
  23911. + .probe = busfreq_probe,
  23912. +};
  23913. +
  23914. +/*!
  23915. + * Initialise the busfreq_driver.
  23916. + *
  23917. + * @return The function always returns 0.
  23918. + */
  23919. +
  23920. +static int __init busfreq_init(void)
  23921. +{
  23922. + if (platform_driver_register(&busfreq_driver) != 0)
  23923. + return -ENODEV;
  23924. +
  23925. + printk(KERN_INFO "Bus freq driver module loaded\n");
  23926. +
  23927. + return 0;
  23928. +}
  23929. +
  23930. +static void __exit busfreq_cleanup(void)
  23931. +{
  23932. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23933. + sysfs_remove_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
  23934. +
  23935. + bus_freq_scaling_initialized = 0;
  23936. +#endif
  23937. + /* Unregister the device structure */
  23938. + platform_driver_unregister(&busfreq_driver);
  23939. +}
  23940. +
  23941. +module_init(busfreq_init);
  23942. +module_exit(busfreq_cleanup);
  23943. +
  23944. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  23945. +MODULE_DESCRIPTION("BusFreq driver");
  23946. +MODULE_LICENSE("GPL");
  23947. diff -Nur linux-3.14.15/arch/arm/mach-imx/busfreq_lpddr2.c linux-linaro-stable-mx6/arch/arm/mach-imx/busfreq_lpddr2.c
  23948. --- linux-3.14.15/arch/arm/mach-imx/busfreq_lpddr2.c 1970-01-01 01:00:00.000000000 +0100
  23949. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/busfreq_lpddr2.c 2014-08-20 19:31:40.080843045 +0200
  23950. @@ -0,0 +1,183 @@
  23951. +/*
  23952. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  23953. + */
  23954. +
  23955. +/*
  23956. + * The code contained herein is licensed under the GNU General Public
  23957. + * License. You may obtain a copy of the GNU General Public License
  23958. + * Version 2 or later at the following locations:
  23959. + *
  23960. + * http://www.opensource.org/licenses/gpl-license.html
  23961. + * http://www.gnu.org/copyleft/gpl.html
  23962. + */
  23963. +
  23964. +/*!
  23965. + * @file busfreq_lpddr2.c
  23966. + *
  23967. + * @brief iMX6 LPDDR2 frequency change specific file.
  23968. + *
  23969. + * @ingroup PM
  23970. + */
  23971. +#include <asm/cacheflush.h>
  23972. +#include <asm/fncpy.h>
  23973. +#include <asm/io.h>
  23974. +#include <asm/mach/map.h>
  23975. +#include <asm/mach-types.h>
  23976. +#include <asm/tlb.h>
  23977. +#include <linux/clk.h>
  23978. +#include <linux/cpumask.h>
  23979. +#include <linux/delay.h>
  23980. +#include <linux/genalloc.h>
  23981. +#include <linux/interrupt.h>
  23982. +#include <linux/irqchip/arm-gic.h>
  23983. +#include <linux/kernel.h>
  23984. +#include <linux/mutex.h>
  23985. +#include <linux/of.h>
  23986. +#include <linux/of_address.h>
  23987. +#include <linux/of_device.h>
  23988. +#include <linux/platform_device.h>
  23989. +#include <linux/proc_fs.h>
  23990. +#include <linux/sched.h>
  23991. +#include <linux/smp.h>
  23992. +
  23993. +#include "hardware.h"
  23994. +
  23995. +/* DDR settings */
  23996. +static void __iomem *mmdc_base;
  23997. +static void __iomem *anatop_base;
  23998. +static void __iomem *ccm_base;
  23999. +static void __iomem *l2_base;
  24000. +static struct device *busfreq_dev;
  24001. +static void *ddr_freq_change_iram_base;
  24002. +static int curr_ddr_rate;
  24003. +
  24004. +unsigned long reg_addrs[4];
  24005. +
  24006. +void (*mx6_change_lpddr2_freq)(u32 ddr_freq, int bus_freq_mode,
  24007. + void *iram_addr) = NULL;
  24008. +
  24009. +extern unsigned int ddr_normal_rate;
  24010. +extern int low_bus_freq_mode;
  24011. +extern int ultra_low_bus_freq_mode;
  24012. +extern void mx6_lpddr2_freq_change(u32 freq, int bus_freq_mode,
  24013. + void *iram_addr);
  24014. +
  24015. +
  24016. +#define LPDDR2_FREQ_CHANGE_SIZE 0x1000
  24017. +
  24018. +
  24019. +/* change the DDR frequency. */
  24020. +int update_lpddr2_freq(int ddr_rate)
  24021. +{
  24022. + if (ddr_rate == curr_ddr_rate)
  24023. + return 0;
  24024. +
  24025. + dev_dbg(busfreq_dev, "\nBus freq set to %d start...\n", ddr_rate);
  24026. +
  24027. + /*
  24028. + * Flush the TLB, to ensure no TLB maintenance occurs
  24029. + * when DDR is in self-refresh.
  24030. + */
  24031. + local_flush_tlb_all();
  24032. + /* Now change DDR frequency. */
  24033. + mx6_change_lpddr2_freq(ddr_rate,
  24034. + (low_bus_freq_mode | ultra_low_bus_freq_mode),
  24035. + reg_addrs);
  24036. +
  24037. + curr_ddr_rate = ddr_rate;
  24038. +
  24039. + dev_dbg(busfreq_dev, "\nBus freq set to %d done...\n", ddr_rate);
  24040. +
  24041. + return 0;
  24042. +}
  24043. +
  24044. +int init_mmdc_lpddr2_settings(struct platform_device *busfreq_pdev)
  24045. +{
  24046. + struct platform_device *ocram_dev;
  24047. + unsigned int iram_paddr;
  24048. + struct device_node *node;
  24049. + struct gen_pool *iram_pool;
  24050. +
  24051. + busfreq_dev = &busfreq_pdev->dev;
  24052. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-mmdc");
  24053. + if (!node) {
  24054. + printk(KERN_ERR "failed to find imx6sl-mmdc device tree data!\n");
  24055. + return -EINVAL;
  24056. + }
  24057. + mmdc_base = of_iomap(node, 0);
  24058. + WARN(!mmdc_base, "unable to map mmdc registers\n");
  24059. +
  24060. + node = NULL;
  24061. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-ccm");
  24062. + if (!node) {
  24063. + printk(KERN_ERR "failed to find imx6sl-ccm device tree data!\n");
  24064. + return -EINVAL;
  24065. + }
  24066. + ccm_base = of_iomap(node, 0);
  24067. + WARN(!ccm_base, "unable to map ccm registers\n");
  24068. +
  24069. + node = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
  24070. + if (!node) {
  24071. + printk(KERN_ERR "failed to find imx6sl-pl310-cache device tree data!\n");
  24072. + return -EINVAL;
  24073. + }
  24074. + l2_base = of_iomap(node, 0);
  24075. + WARN(!l2_base, "unable to map PL310 registers\n");
  24076. +
  24077. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
  24078. + if (!node) {
  24079. + printk(KERN_ERR "failed to find imx6sl-pl310-cache device tree data!\n");
  24080. + return -EINVAL;
  24081. + }
  24082. + anatop_base = of_iomap(node, 0);
  24083. + WARN(!anatop_base, "unable to map anatop registers\n");
  24084. +
  24085. + node = NULL;
  24086. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  24087. + if (!node) {
  24088. + dev_err(busfreq_dev, "%s: failed to find ocram node\n",
  24089. + __func__);
  24090. + return -EINVAL;
  24091. + }
  24092. +
  24093. + ocram_dev = of_find_device_by_node(node);
  24094. + if (!ocram_dev) {
  24095. + dev_err(busfreq_dev, "failed to find ocram device!\n");
  24096. + return -EINVAL;
  24097. + }
  24098. +
  24099. + iram_pool = dev_get_gen_pool(&ocram_dev->dev);
  24100. + if (!iram_pool) {
  24101. + dev_err(busfreq_dev, "iram pool unavailable!\n");
  24102. + return -EINVAL;
  24103. + }
  24104. +
  24105. + reg_addrs[0] = (unsigned long)anatop_base;
  24106. + reg_addrs[1] = (unsigned long)ccm_base;
  24107. + reg_addrs[2] = (unsigned long)mmdc_base;
  24108. + reg_addrs[3] = (unsigned long)l2_base;
  24109. +
  24110. + ddr_freq_change_iram_base = (void *)gen_pool_alloc(iram_pool,
  24111. + LPDDR2_FREQ_CHANGE_SIZE);
  24112. + if (!ddr_freq_change_iram_base) {
  24113. + dev_err(busfreq_dev,
  24114. + "Cannot alloc iram for ddr freq change code!\n");
  24115. + return -ENOMEM;
  24116. + }
  24117. +
  24118. + iram_paddr = gen_pool_virt_to_phys(iram_pool,
  24119. + (unsigned long)ddr_freq_change_iram_base);
  24120. + /*
  24121. + * Need to remap the area here since we want
  24122. + * the memory region to be executable.
  24123. + */
  24124. + ddr_freq_change_iram_base = __arm_ioremap(iram_paddr,
  24125. + LPDDR2_FREQ_CHANGE_SIZE,
  24126. + MT_MEMORY_RWX_NONCACHED);
  24127. + mx6_change_lpddr2_freq = (void *)fncpy(ddr_freq_change_iram_base,
  24128. + &mx6_lpddr2_freq_change, LPDDR2_FREQ_CHANGE_SIZE);
  24129. +
  24130. + curr_ddr_rate = ddr_normal_rate;
  24131. +
  24132. + return 0;
  24133. +}
  24134. diff -Nur linux-3.14.15/arch/arm/mach-imx/clk.h linux-linaro-stable-mx6/arch/arm/mach-imx/clk.h
  24135. --- linux-3.14.15/arch/arm/mach-imx/clk.h 2014-07-31 23:51:43.000000000 +0200
  24136. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/clk.h 2014-08-20 19:31:40.084843062 +0200
  24137. @@ -23,7 +23,8 @@
  24138. };
  24139. struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
  24140. - const char *parent_name, void __iomem *base, u32 div_mask);
  24141. + const char *parent_name, void __iomem *base,
  24142. + u32 div_mask, bool always_on);
  24143. struct clk *clk_register_gate2(struct device *dev, const char *name,
  24144. const char *parent_name, unsigned long flags,
  24145. diff -Nur linux-3.14.15/arch/arm/mach-imx/clk-imx6q.c linux-linaro-stable-mx6/arch/arm/mach-imx/clk-imx6q.c
  24146. --- linux-3.14.15/arch/arm/mach-imx/clk-imx6q.c 2014-07-31 23:51:43.000000000 +0200
  24147. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/clk-imx6q.c 2014-08-20 19:31:40.084843062 +0200
  24148. @@ -1,5 +1,5 @@
  24149. /*
  24150. - * Copyright 2011-2013 Freescale Semiconductor, Inc.
  24151. + * Copyright 2011-2014 Freescale Semiconductor, Inc.
  24152. * Copyright 2011 Linaro Ltd.
  24153. *
  24154. * The code contained herein is licensed under the GNU General Public
  24155. @@ -24,6 +24,8 @@
  24156. #include "common.h"
  24157. #include "hardware.h"
  24158. +#define CCM_CCGR_OFFSET(index) (index * 2)
  24159. +
  24160. static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
  24161. static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
  24162. static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
  24163. @@ -39,6 +41,8 @@
  24164. static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", };
  24165. static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
  24166. static const char *ldb_di_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
  24167. +static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
  24168. +static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
  24169. static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
  24170. static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
  24171. static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
  24172. @@ -72,6 +76,10 @@
  24173. "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
  24174. "pcie_ref", "sata_ref",
  24175. };
  24176. +static const char *pll_av_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
  24177. +static void __iomem *anatop_base;
  24178. +static void __iomem *ccm_base;
  24179. +
  24180. enum mx6q_clks {
  24181. dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
  24182. @@ -88,11 +96,11 @@
  24183. periph_clk2, periph2_clk2, ipg, ipg_per, esai_pred, esai_podf,
  24184. asrc_pred, asrc_podf, spdif_pred, spdif_podf, can_root, ecspi_root,
  24185. gpu2d_core_podf, gpu3d_core_podf, gpu3d_shader, ipu1_podf, ipu2_podf,
  24186. - ldb_di0_podf, ldb_di1_podf, ipu1_di0_pre, ipu1_di1_pre, ipu2_di0_pre,
  24187. - ipu2_di1_pre, hsi_tx_podf, ssi1_pred, ssi1_podf, ssi2_pred, ssi2_podf,
  24188. - ssi3_pred, ssi3_podf, uart_serial_podf, usdhc1_podf, usdhc2_podf,
  24189. - usdhc3_podf, usdhc4_podf, enfc_pred, enfc_podf, emi_podf,
  24190. - emi_slow_podf, vpu_axi_podf, cko1_podf, axi, mmdc_ch0_axi_podf,
  24191. + ldb_di0_podf_unused, ldb_di1_podf_unused, ipu1_di0_pre, ipu1_di1_pre,
  24192. + ipu2_di0_pre, ipu2_di1_pre, hsi_tx_podf, ssi1_pred, ssi1_podf,
  24193. + ssi2_pred, ssi2_podf, ssi3_pred, ssi3_podf, uart_serial_podf,
  24194. + usdhc1_podf, usdhc2_podf, usdhc3_podf, usdhc4_podf, enfc_pred, enfc_podf,
  24195. + emi_podf, emi_slow_podf, vpu_axi_podf, cko1_podf, axi, mmdc_ch0_axi_podf,
  24196. mmdc_ch1_axi_podf, arm, ahb, apbh_dma, asrc, can1_ipg, can1_serial,
  24197. can2_ipg, can2_serial, ecspi1, ecspi2, ecspi3, ecspi4, ecspi5, enet,
  24198. esai, gpt_ipg, gpt_ipg_per, gpu2d_core, gpu3d_core, hdmi_iahb,
  24199. @@ -107,7 +115,10 @@
  24200. sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
  24201. usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow,
  24202. spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, pll4_audio_div,
  24203. - lvds1_sel, lvds2_sel, lvds1_gate, lvds2_gate, clk_max
  24204. + lvds1_sel, lvds2_sel, lvds1_gate, lvds2_gate, gpt_3m, video_27m,
  24205. + ldb_di0_div_7, ldb_di1_div_7, ldb_di0_div_sel, ldb_di1_div_sel,
  24206. + caam_mem, caam_aclk, caam_ipg, epit1, epit2, tzasc2, lvds1_in, lvds1_out,
  24207. + pll4_sel, lvds2_in, lvds2_out, anaclk1, anaclk2, clk_max
  24208. };
  24209. static struct clk *clk[clk_max];
  24210. @@ -140,20 +151,131 @@
  24211. { /* sentinel */ }
  24212. };
  24213. +static void init_ldb_clks(enum mx6q_clks new_parent)
  24214. +{
  24215. + u32 reg;
  24216. +
  24217. + /*
  24218. + * Need to follow a strict procedure when changing the LDB
  24219. + * clock, else we can introduce a glitch. Things to keep in
  24220. + * mind:
  24221. + * 1. The current and new parent clocks must be disabled.
  24222. + * 2. The default clock for ldb_dio_clk is mmdc_ch1 which has
  24223. + * no CG bit.
  24224. + * 3. In the RTL implementation of the LDB_DI_CLK_SEL mux
  24225. + * the top four options are in one mux and the PLL3 option along
  24226. + * with another option is in the second mux. There is third mux
  24227. + * used to decide between the first and second mux.
  24228. + * The code below switches the parent to the bottom mux first
  24229. + * and then manipulates the top mux. This ensures that no glitch
  24230. + * will enter the divider.
  24231. + *
  24232. + * Need to disable MMDC_CH1 clock manually as there is no CG bit
  24233. + * for this clock. The only way to disable this clock is to move
  24234. + * it topll3_sw_clk and then to disable pll3_sw_clk
  24235. + * Make sure periph2_clk2_sel is set to pll3_sw_clk
  24236. + */
  24237. + reg = readl_relaxed(ccm_base + 0x18);
  24238. + reg &= ~(1 << 20);
  24239. + writel_relaxed(reg, ccm_base + 0x18);
  24240. +
  24241. + /*
  24242. + * Set MMDC_CH1 mask bit.
  24243. + */
  24244. + reg = readl_relaxed(ccm_base + 0x4);
  24245. + reg |= 1 << 16;
  24246. + writel_relaxed(reg, ccm_base + 0x4);
  24247. +
  24248. + /*
  24249. + * Set the periph2_clk_sel to the top mux so that
  24250. + * mmdc_ch1 is from pll3_sw_clk.
  24251. + */
  24252. + reg = readl_relaxed(ccm_base + 0x14);
  24253. + reg |= 1 << 26;
  24254. + writel_relaxed(reg, ccm_base + 0x14);
  24255. +
  24256. + /*
  24257. + * Wait for the clock switch.
  24258. + */
  24259. + while (readl_relaxed(ccm_base + 0x48))
  24260. + ;
  24261. +
  24262. + /*
  24263. + * Disable pll3_sw_clk by selecting the bypass clock source.
  24264. + */
  24265. + reg = readl_relaxed(ccm_base + 0xc);
  24266. + reg |= 1 << 0;
  24267. + writel_relaxed(reg, ccm_base + 0xc);
  24268. +
  24269. + /*
  24270. + * Set the ldb_di0_clk and ldb_di1_clk to 111b.
  24271. + */
  24272. + reg = readl_relaxed(ccm_base + 0x2c);
  24273. + reg |= ((7 << 9) | (7 << 12));
  24274. + writel_relaxed(reg, ccm_base + 0x2c);
  24275. +
  24276. + /*
  24277. + * Set the ldb_di0_clk and ldb_di1_clk to 100b.
  24278. + */
  24279. + reg = readl_relaxed(ccm_base + 0x2c);
  24280. + reg &= ~((7 << 9) | (7 << 12));
  24281. + reg |= ((4 << 9) | (4 << 12));
  24282. + writel_relaxed(reg, ccm_base + 0x2c);
  24283. +
  24284. + /*
  24285. + * Perform the LDB parent clock switch.
  24286. + */
  24287. + clk_set_parent(clk[ldb_di0_sel], clk[new_parent]);
  24288. + clk_set_parent(clk[ldb_di1_sel], clk[new_parent]);
  24289. +
  24290. + /*
  24291. + * Unbypass pll3_sw_clk.
  24292. + */
  24293. + reg = readl_relaxed(ccm_base + 0xc);
  24294. + reg &= ~(1 << 0);
  24295. + writel_relaxed(reg, ccm_base + 0xc);
  24296. +
  24297. + /*
  24298. + * Set the periph2_clk_sel back to the bottom mux so that
  24299. + * mmdc_ch1 is from its original parent.
  24300. + */
  24301. + reg = readl_relaxed(ccm_base + 0x14);
  24302. + reg &= ~(1 << 26);
  24303. + writel_relaxed(reg, ccm_base + 0x14);
  24304. +
  24305. + /*
  24306. + * Wait for the clock switch.
  24307. + */
  24308. + while (readl_relaxed(ccm_base + 0x48))
  24309. + ;
  24310. +
  24311. + /*
  24312. + * Clear MMDC_CH1 mask bit.
  24313. + */
  24314. + reg = readl_relaxed(ccm_base + 0x4);
  24315. + reg &= ~(1 << 16);
  24316. + writel_relaxed(reg, ccm_base + 0x4);
  24317. +
  24318. +}
  24319. +
  24320. static void __init imx6q_clocks_init(struct device_node *ccm_node)
  24321. {
  24322. struct device_node *np;
  24323. void __iomem *base;
  24324. int i, irq;
  24325. int ret;
  24326. + u32 reg;
  24327. clk[dummy] = imx_clk_fixed("dummy", 0);
  24328. clk[ckil] = imx_obtain_fixed_clock("ckil", 0);
  24329. clk[ckih] = imx_obtain_fixed_clock("ckih1", 0);
  24330. clk[osc] = imx_obtain_fixed_clock("osc", 0);
  24331. + /* Clock source from external clock via ANACLK1/2 PADs */
  24332. + clk[anaclk1] = imx_obtain_fixed_clock("anaclk1", 0);
  24333. + clk[anaclk2] = imx_obtain_fixed_clock("anaclk2", 0);
  24334. np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
  24335. - base = of_iomap(np, 0);
  24336. + anatop_base = base = of_iomap(np, 0);
  24337. WARN_ON(!base);
  24338. /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
  24339. @@ -165,13 +287,18 @@
  24340. };
  24341. /* type name parent_name base div_mask */
  24342. - clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
  24343. - clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
  24344. - clk[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3);
  24345. - clk[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f);
  24346. - clk[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
  24347. - clk[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
  24348. - clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3);
  24349. + clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f, false);
  24350. + clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1, false);
  24351. + clk[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3, false);
  24352. + clk[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "pll4_sel", base + 0x70, 0x7f, false);
  24353. + clk[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f, false);
  24354. + clk[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3, false);
  24355. + clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3, false);
  24356. +
  24357. + /* name reg shift width parent_names num_parents */
  24358. + clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24359. + clk[lvds2_sel] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24360. + clk[pll4_sel] = imx_clk_mux("pll4_sel", base + 0x70, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
  24361. /*
  24362. * Bit 20 is the reserved and read-only bit, we do this only for:
  24363. @@ -191,6 +318,11 @@
  24364. clk[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
  24365. clk[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
  24366. + /* NOTICE: The gate of the lvds1/2 in/out is used to select the clk direction */
  24367. + clk[lvds1_in] = imx_clk_gate("lvds1_in", "anaclk1", base + 0x160, 12);
  24368. + clk[lvds2_in] = imx_clk_gate("lvds2_in", "anaclk2", base + 0x160, 13);
  24369. + clk[lvds1_out] = imx_clk_gate("lvds1_out", "lvds1_sel", base + 0x160, 10);
  24370. + clk[lvds2_out] = imx_clk_gate("lvds2_out", "lvds2_sel", base + 0x160, 11);
  24371. clk[sata_ref_100m] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
  24372. clk[pcie_ref_125m] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
  24373. @@ -199,18 +331,6 @@
  24374. base + 0xe0, 0, 2, 0, clk_enet_ref_table,
  24375. &imx_ccm_lock);
  24376. - clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24377. - clk[lvds2_sel] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24378. -
  24379. - /*
  24380. - * lvds1_gate and lvds2_gate are pseudo-gates. Both can be
  24381. - * independently configured as clock inputs or outputs. We treat
  24382. - * the "output_enable" bit as a gate, even though it's really just
  24383. - * enabling clock output.
  24384. - */
  24385. - clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "dummy", base + 0x160, 10);
  24386. - clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "dummy", base + 0x160, 11);
  24387. -
  24388. /* name parent_name reg idx */
  24389. clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
  24390. clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
  24391. @@ -226,6 +346,8 @@
  24392. clk[pll3_80m] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
  24393. clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
  24394. clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2);
  24395. + clk[gpt_3m] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
  24396. + clk[video_27m] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20);
  24397. clk[pll4_post_div] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
  24398. clk[pll4_audio_div] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
  24399. @@ -233,7 +355,7 @@
  24400. clk[pll5_video_div] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
  24401. np = ccm_node;
  24402. - base = of_iomap(np, 0);
  24403. + ccm_base = base = of_iomap(np, 0);
  24404. WARN_ON(!base);
  24405. imx6q_pm_set_ccm_base(base);
  24406. @@ -258,14 +380,16 @@
  24407. clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
  24408. clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
  24409. clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
  24410. - clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
  24411. - clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
  24412. - clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
  24413. - clk[ipu2_di1_pre_sel] = imx_clk_mux("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
  24414. - clk[ipu1_di0_sel] = imx_clk_mux("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels));
  24415. - clk[ipu1_di1_sel] = imx_clk_mux("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels));
  24416. - clk[ipu2_di0_sel] = imx_clk_mux("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels));
  24417. - clk[ipu2_di1_sel] = imx_clk_mux("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels));
  24418. + clk[ldb_di0_div_sel] = imx_clk_mux_flags("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels), CLK_SET_RATE_PARENT);
  24419. + clk[ldb_di1_div_sel] = imx_clk_mux_flags("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels), CLK_SET_RATE_PARENT);
  24420. + clk[ipu1_di0_pre_sel] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
  24421. + clk[ipu1_di1_pre_sel] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
  24422. + clk[ipu2_di0_pre_sel] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
  24423. + clk[ipu2_di1_pre_sel] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
  24424. + clk[ipu1_di0_sel] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT);
  24425. + clk[ipu1_di1_sel] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT);
  24426. + clk[ipu2_di0_sel] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT);
  24427. + clk[ipu2_di1_sel] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT);
  24428. clk[hsi_tx_sel] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels));
  24429. clk[pcie_axi_sel] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
  24430. clk[ssi1_sel] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
  24431. @@ -307,9 +431,9 @@
  24432. clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
  24433. clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
  24434. clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
  24435. - clk[ldb_di0_podf] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
  24436. + clk[ldb_di0_div_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7);
  24437. clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
  24438. - clk[ldb_di1_podf] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0);
  24439. + clk[ldb_di1_div_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7);
  24440. clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3);
  24441. clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3);
  24442. clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3);
  24443. @@ -344,6 +468,9 @@
  24444. /* name parent_name reg shift */
  24445. clk[apbh_dma] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4);
  24446. clk[asrc] = imx_clk_gate2("asrc", "asrc_podf", base + 0x68, 6);
  24447. + clk[caam_mem] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8);
  24448. + clk[caam_aclk] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
  24449. + clk[caam_ipg] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
  24450. clk[can1_ipg] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
  24451. clk[can1_serial] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16);
  24452. clk[can2_ipg] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
  24453. @@ -354,6 +481,8 @@
  24454. clk[ecspi4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
  24455. clk[ecspi5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8);
  24456. clk[enet] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
  24457. + clk[epit1] = imx_clk_gate2("epit1", "ipg", base + 0x6c, 12);
  24458. + clk[epit2] = imx_clk_gate2("epit2", "ipg", base + 0x6c, 14);
  24459. clk[esai] = imx_clk_gate2("esai", "esai_podf", base + 0x6c, 16);
  24460. clk[gpt_ipg] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
  24461. clk[gpt_ipg_per] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
  24462. @@ -373,15 +502,16 @@
  24463. clk[i2c3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10);
  24464. clk[iim] = imx_clk_gate2("iim", "ipg", base + 0x70, 12);
  24465. clk[enfc] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14);
  24466. + clk[tzasc2] = imx_clk_gate2("tzasc2", "mmdc_ch0_axi_podf", base + 0x70, 24);
  24467. clk[vdoa] = imx_clk_gate2("vdoa", "vdo_axi", base + 0x70, 26);
  24468. clk[ipu1] = imx_clk_gate2("ipu1", "ipu1_podf", base + 0x74, 0);
  24469. clk[ipu1_di0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", base + 0x74, 2);
  24470. clk[ipu1_di1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4);
  24471. clk[ipu2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6);
  24472. clk[ipu2_di0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8);
  24473. - clk[ldb_di0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12);
  24474. - clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14);
  24475. clk[ipu2_di1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10);
  24476. + clk[ldb_di0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12);
  24477. + clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_div_sel", base + 0x74, 14);
  24478. clk[hsi_tx] = imx_clk_gate2("hsi_tx", "hsi_tx_podf", base + 0x74, 16);
  24479. if (cpu_is_imx6dl())
  24480. /*
  24481. @@ -413,6 +543,9 @@
  24482. clk[ssi1_ipg] = imx_clk_gate2("ssi1_ipg", "ipg", base + 0x7c, 18);
  24483. clk[ssi2_ipg] = imx_clk_gate2("ssi2_ipg", "ipg", base + 0x7c, 20);
  24484. clk[ssi3_ipg] = imx_clk_gate2("ssi3_ipg", "ipg", base + 0x7c, 22);
  24485. + clk[ssi1] = imx_clk_gate2("ssi1", "ssi1_podf", base + 0x7c, 18);
  24486. + clk[ssi2] = imx_clk_gate2("ssi2", "ssi2_podf", base + 0x7c, 20);
  24487. + clk[ssi3] = imx_clk_gate2("ssi3", "ssi3_podf", base + 0x7c, 22);
  24488. clk[uart_ipg] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
  24489. clk[uart_serial] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26);
  24490. clk[usboh3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
  24491. @@ -431,25 +564,79 @@
  24492. pr_err("i.MX6q clk %d: register failed with %ld\n",
  24493. i, PTR_ERR(clk[i]));
  24494. + /* Initialize clock gate status */
  24495. + writel_relaxed(1 << CCM_CCGR_OFFSET(11) |
  24496. + 3 << CCM_CCGR_OFFSET(1) |
  24497. + 3 << CCM_CCGR_OFFSET(0), base + 0x68);
  24498. + if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0)
  24499. + writel_relaxed(3 << CCM_CCGR_OFFSET(11) |
  24500. + 3 << CCM_CCGR_OFFSET(10), base + 0x6c);
  24501. + else
  24502. + writel_relaxed(3 << CCM_CCGR_OFFSET(10), base + 0x6c);
  24503. + writel_relaxed(1 << CCM_CCGR_OFFSET(12) |
  24504. + 3 << CCM_CCGR_OFFSET(11) |
  24505. + 3 << CCM_CCGR_OFFSET(10) |
  24506. + 3 << CCM_CCGR_OFFSET(9) |
  24507. + 3 << CCM_CCGR_OFFSET(8), base + 0x70);
  24508. + writel_relaxed(3 << CCM_CCGR_OFFSET(14) |
  24509. + 1 << CCM_CCGR_OFFSET(13) |
  24510. + 3 << CCM_CCGR_OFFSET(12) |
  24511. + 1 << CCM_CCGR_OFFSET(11) |
  24512. + 3 << CCM_CCGR_OFFSET(10), base + 0x74);
  24513. + writel_relaxed(3 << CCM_CCGR_OFFSET(7) |
  24514. + 3 << CCM_CCGR_OFFSET(6) |
  24515. + 3 << CCM_CCGR_OFFSET(4), base + 0x78);
  24516. + writel_relaxed(1 << CCM_CCGR_OFFSET(0), base + 0x7c);
  24517. + writel_relaxed(0, base + 0x80);
  24518. +
  24519. + /* Make sure PFDs are disabled at boot. */
  24520. + reg = readl_relaxed(anatop_base + 0x100);
  24521. + /* Cannot disable pll2_pfd2_396M, as it is the MMDC clock in iMX6DL */
  24522. + if (cpu_is_imx6dl())
  24523. + reg |= 0x80008080;
  24524. + else
  24525. + reg |= 0x80808080;
  24526. + writel_relaxed(reg, anatop_base + 0x100);
  24527. +
  24528. + /* Disable PLL3 PFDs. */
  24529. + reg = readl_relaxed(anatop_base + 0xF0);
  24530. + reg |= 0x80808080;
  24531. + writel_relaxed(reg, anatop_base + 0xF0);
  24532. +
  24533. + /* Make sure PLLs is disabled */
  24534. + reg = readl_relaxed(anatop_base + 0xA0);
  24535. + reg &= ~(1 << 13);
  24536. + writel_relaxed(reg, anatop_base + 0xA0);
  24537. +
  24538. clk_data.clks = clk;
  24539. clk_data.clk_num = ARRAY_SIZE(clk);
  24540. of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
  24541. clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0");
  24542. clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
  24543. + clk_register_clkdev(clk[gpt_3m], "gpt_3m", "imx-gpt.0");
  24544. clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL);
  24545. clk_register_clkdev(clk[ahb], "ahb", NULL);
  24546. clk_register_clkdev(clk[cko1], "cko1", NULL);
  24547. clk_register_clkdev(clk[arm], NULL, "cpu0");
  24548. - clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL);
  24549. - clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL);
  24550. + clk_register_clkdev(clk[pll4_audio_div], "pll4_audio_div", NULL);
  24551. + clk_register_clkdev(clk[pll4_sel], "pll4_sel", NULL);
  24552. + clk_register_clkdev(clk[lvds2_in], "lvds2_in", NULL);
  24553. + clk_register_clkdev(clk[esai], "esai", NULL);
  24554. - if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
  24555. - cpu_is_imx6dl()) {
  24556. - clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
  24557. - clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
  24558. + if (cpu_is_imx6dl()) {
  24559. + clk_set_parent(clk[ipu1_sel], clk[pll3_pfd1_540m]);
  24560. }
  24561. + clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]);
  24562. + clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]);
  24563. + clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]);
  24564. + clk_set_parent(clk[ipu2_di1_pre_sel], clk[pll5_video_div]);
  24565. + clk_set_parent(clk[ipu1_di0_sel], clk[ipu1_di0_pre]);
  24566. + clk_set_parent(clk[ipu1_di1_sel], clk[ipu1_di1_pre]);
  24567. + clk_set_parent(clk[ipu2_di0_sel], clk[ipu2_di0_pre]);
  24568. + clk_set_parent(clk[ipu2_di1_sel], clk[ipu2_di1_pre]);
  24569. +
  24570. /*
  24571. * The gpmi needs 100MHz frequency in the EDO/Sync mode,
  24572. * We can not get the 100MHz from the pll2_pfd0_352m.
  24573. @@ -457,6 +644,19 @@
  24574. */
  24575. clk_set_parent(clk[enfc_sel], clk[pll2_pfd2_396m]);
  24576. + /* Set the parent clks of PCIe lvds1 and pcie_axi to be sata ref, axi */
  24577. + if (clk_set_parent(clk[lvds1_sel], clk[sata_ref]))
  24578. + pr_err("Failed to set PCIe bus parent clk.\n");
  24579. + if (clk_set_parent(clk[pcie_axi_sel], clk[axi]))
  24580. + pr_err("Failed to set PCIe parent clk.\n");
  24581. +
  24582. + /* gpu clock initilazation */
  24583. + clk_set_parent(clk[gpu3d_shader_sel], clk[pll2_pfd1_594m]);
  24584. + clk_set_rate(clk[gpu3d_shader], 594000000);
  24585. + clk_set_parent(clk[gpu3d_core_sel], clk[mmdc_ch0_axi]);
  24586. + clk_set_rate(clk[gpu3d_core], 528000000);
  24587. + clk_set_parent(clk[gpu2d_core_sel], clk[pll3_usb_otg]);
  24588. +
  24589. for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
  24590. clk_prepare_enable(clk[clks_init_on[i]]);
  24591. @@ -465,6 +665,25 @@
  24592. clk_prepare_enable(clk[usbphy2_gate]);
  24593. }
  24594. + /* ipu clock initialization */
  24595. + init_ldb_clks(pll2_pfd0_352m);
  24596. + clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]);
  24597. + clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]);
  24598. + clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]);
  24599. + clk_set_parent(clk[ipu2_di1_pre_sel], clk[pll5_video_div]);
  24600. + clk_set_parent(clk[ipu1_di0_sel], clk[ipu1_di0_pre]);
  24601. + clk_set_parent(clk[ipu1_di1_sel], clk[ipu1_di1_pre]);
  24602. + clk_set_parent(clk[ipu2_di0_sel], clk[ipu2_di0_pre]);
  24603. + clk_set_parent(clk[ipu2_di1_sel], clk[ipu2_di1_pre]);
  24604. + if (cpu_is_imx6dl()) {
  24605. + clk_set_rate(clk[pll3_pfd1_540m], 540000000);
  24606. + clk_set_parent(clk[ipu1_sel], clk[pll3_pfd1_540m]);
  24607. + clk_set_parent(clk[axi_sel], clk[pll3_pfd1_540m]);
  24608. + } else if (cpu_is_imx6q()) {
  24609. + clk_set_parent(clk[ipu1_sel], clk[mmdc_ch0_axi]);
  24610. + clk_set_parent(clk[ipu2_sel], clk[mmdc_ch0_axi]);
  24611. + }
  24612. +
  24613. /*
  24614. * Let's initially set up CLKO with OSC24M, since this configuration
  24615. * is widely used by imx6q board designs to clock audio codec.
  24616. @@ -482,6 +701,18 @@
  24617. if (IS_ENABLED(CONFIG_PCI_IMX6))
  24618. clk_set_parent(clk[lvds1_sel], clk[sata_ref]);
  24619. + /* Audio clocks */
  24620. + clk_set_parent(clk[ssi1_sel], clk[pll4_audio_div]);
  24621. + clk_set_parent(clk[ssi2_sel], clk[pll4_audio_div]);
  24622. + clk_set_parent(clk[ssi3_sel], clk[pll4_audio_div]);
  24623. + clk_set_parent(clk[esai_sel], clk[pll4_audio_div]);
  24624. + clk_set_parent(clk[spdif_sel], clk[pll3_pfd3_454m]);
  24625. + clk_set_parent(clk[asrc_sel], clk[pll3_usb_otg]);
  24626. + clk_set_rate(clk[asrc_sel], 7500000);
  24627. +
  24628. + /* Set pll4_audio to a value that can derive 5K-88.2KHz and 8K-96KHz */
  24629. + clk_set_rate(clk[pll4_audio_div], 541900800);
  24630. +
  24631. /* Set initial power mode */
  24632. imx6q_set_lpm(WAIT_CLOCKED);
  24633. diff -Nur linux-3.14.15/arch/arm/mach-imx/clk-imx6sl.c linux-linaro-stable-mx6/arch/arm/mach-imx/clk-imx6sl.c
  24634. --- linux-3.14.15/arch/arm/mach-imx/clk-imx6sl.c 2014-07-31 23:51:43.000000000 +0200
  24635. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/clk-imx6sl.c 2014-08-20 19:31:40.084843062 +0200
  24636. @@ -7,9 +7,29 @@
  24637. *
  24638. */
  24639. +#define CCM_CCDR_OFFSET 0x4
  24640. +#define ANATOP_PLL_USB1 0x10
  24641. +#define ANATOP_PLL_USB2 0x20
  24642. +#define ANATOP_PLL_ENET 0xE0
  24643. +#define ANATOP_PLL_BYPASS_OFFSET (1 << 16)
  24644. +#define ANATOP_PLL_ENABLE_OFFSET (1 << 13)
  24645. +#define ANATOP_PLL_POWER_OFFSET (1 << 12)
  24646. +#define ANATOP_PFD_480n_OFFSET 0xf0
  24647. +#define ANATOP_PFD_528n_OFFSET 0x100
  24648. +#define PFD0_CLKGATE (1 << 7)
  24649. +#define PFD1_CLK_GATE (1 << 15)
  24650. +#define PFD2_CLK_GATE (1 << 23)
  24651. +#define PFD3_CLK_GATE (1 << 31)
  24652. +#define CCDR_CH0_HS_BYP 17
  24653. +#define OSC_RATE 24000000
  24654. +
  24655. +#define CCM_CCGR_OFFSET(index) (index * 2)
  24656. +
  24657. #include <linux/clk.h>
  24658. #include <linux/clkdev.h>
  24659. #include <linux/err.h>
  24660. +#include <linux/init.h>
  24661. +#include <linux/io.h>
  24662. #include <linux/of.h>
  24663. #include <linux/of_address.h>
  24664. #include <linux/of_irq.h>
  24665. @@ -18,6 +38,7 @@
  24666. #include "clk.h"
  24667. #include "common.h"
  24668. +static bool uart_from_osc;
  24669. static const char const *step_sels[] = { "osc", "pll2_pfd2", };
  24670. static const char const *pll1_sw_sels[] = { "pll1_sys", "step", };
  24671. static const char const *ocram_alt_sels[] = { "pll2_pfd2", "pll3_pfd1", };
  24672. @@ -25,8 +46,8 @@
  24673. static const char const *pre_periph_sels[] = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", };
  24674. static const char const *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", };
  24675. static const char const *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
  24676. -static const char const *periph_sels[] = { "pre_periph_sel", "periph_clk2_podf", };
  24677. -static const char const *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2_podf", };
  24678. +static const char const *periph_sels[] = { "pre_periph_sel", "periph_clk2", };
  24679. +static const char const *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2", };
  24680. static const char const *csi_lcdif_sels[] = { "mmdc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
  24681. static const char const *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", };
  24682. static const char const *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", };
  24683. @@ -38,7 +59,7 @@
  24684. static const char const *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", };
  24685. static const char const *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", };
  24686. static const char const *ecspi_sels[] = { "pll3_60m", "osc", };
  24687. -static const char const *uart_sels[] = { "pll3_80m", "osc", };
  24688. +static const char const *uart_sels[] = { "pll3_80m", "uart_osc_4M", };
  24689. static struct clk_div_table clk_enet_ref_table[] = {
  24690. { .val = 0, .div = 20, },
  24691. @@ -65,6 +86,80 @@
  24692. static struct clk *clks[IMX6SL_CLK_END];
  24693. static struct clk_onecell_data clk_data;
  24694. +static u32 cur_arm_podf;
  24695. +static u32 pll1_org_rate;
  24696. +
  24697. +extern int low_bus_freq_mode;
  24698. +extern int audio_bus_freq_mode;
  24699. +
  24700. +/*
  24701. + * On MX6SL, need to ensure that the ARM:IPG clock ratio is maintained
  24702. + * within 12:5 when the clocks to ARM are gated when the SOC enters
  24703. + * WAIT mode. This is necessary to avoid WAIT mode issue (an early
  24704. + * interrupt waking up the ARM).
  24705. + * This function will set the ARM clk to max value within the 12:5 limit.
  24706. + */
  24707. +void imx6sl_set_wait_clk(bool enter)
  24708. +{
  24709. + u32 parent_rate;
  24710. +
  24711. + if (enter) {
  24712. + u32 wait_podf;
  24713. + u32 new_parent_rate = OSC_RATE;
  24714. + u32 ipg_rate = clk_get_rate(clks[IMX6SL_CLK_IPG]);
  24715. + u32 max_arm_wait_clk = (12 * ipg_rate) / 5;
  24716. + parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
  24717. + cur_arm_podf = parent_rate / clk_get_rate(clks[IMX6SL_CLK_ARM]);
  24718. + if (low_bus_freq_mode) {
  24719. + /*
  24720. + * IPG clk is at 12MHz at this point, we can only run
  24721. + * ARM at a max of 28.8MHz. So we need to set ARM
  24722. + * to run from the 24MHz OSC, as there is no way to
  24723. + * get 28.8MHz when ARM is sourced from PLL1.
  24724. + */
  24725. + clk_set_parent(clks[IMX6SL_CLK_STEP],
  24726. + clks[IMX6SL_CLK_OSC]);
  24727. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW],
  24728. + clks[IMX6SL_CLK_STEP]);
  24729. + } else if (audio_bus_freq_mode) {
  24730. + /*
  24731. + * In this mode ARM is from PLL2_PFD2 (396MHz),
  24732. + * but IPG is at 12MHz. Need to switch ARM to run
  24733. + * from the bypassed PLL1 clocks so that we can run
  24734. + * ARM at 24MHz.
  24735. + */
  24736. + pll1_org_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SYS]);
  24737. + /* Ensure PLL1 is at 24MHz. */
  24738. + clk_set_rate(clks[IMX6SL_CLK_PLL1_SYS], OSC_RATE);
  24739. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW], clks[IMX6SL_CLK_PLL1_SYS]);
  24740. + } else
  24741. + new_parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
  24742. + wait_podf = (new_parent_rate + max_arm_wait_clk - 1) /
  24743. + max_arm_wait_clk;
  24744. +
  24745. + clk_set_rate(clks[IMX6SL_CLK_ARM], new_parent_rate / wait_podf);
  24746. + } else {
  24747. + if (low_bus_freq_mode)
  24748. + /* Move ARM back to PLL1. */
  24749. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW],
  24750. + clks[IMX6SL_CLK_PLL1_SYS]);
  24751. + else if (audio_bus_freq_mode) {
  24752. + /* Move ARM back to PLL2_PFD2 via STEP_CLK. */
  24753. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW], clks[IMX6SL_CLK_STEP]);
  24754. + clk_set_rate(clks[IMX6SL_CLK_PLL1_SYS], pll1_org_rate);
  24755. + }
  24756. + parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
  24757. + clk_set_rate(clks[IMX6SL_CLK_ARM], parent_rate / cur_arm_podf);
  24758. + }
  24759. +}
  24760. +
  24761. +static int __init setup_uart_clk(char *uart_rate)
  24762. +{
  24763. + uart_from_osc = true;
  24764. + return 1;
  24765. +}
  24766. +
  24767. +__setup("uart_at_4M", setup_uart_clk);
  24768. static void __init imx6sl_clocks_init(struct device_node *ccm_node)
  24769. {
  24770. @@ -72,6 +167,8 @@
  24771. void __iomem *base;
  24772. int irq;
  24773. int i;
  24774. + int ret;
  24775. + u32 reg;
  24776. clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
  24777. clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
  24778. @@ -82,13 +179,18 @@
  24779. WARN_ON(!base);
  24780. /* type name parent base div_mask */
  24781. - clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
  24782. - clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
  24783. - clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3);
  24784. - clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f);
  24785. - clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
  24786. - clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
  24787. - clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3);
  24788. + clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f, true);
  24789. + clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1, true);
  24790. + clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3, false);
  24791. + clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f, false);
  24792. + clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f, false);
  24793. + clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3, false);
  24794. + clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3, false);
  24795. +
  24796. + /* Ensure the AHB clk is at 132MHz. */
  24797. + ret = clk_set_rate(clks[IMX6SL_CLK_AHB], 132000000);
  24798. + if (ret)
  24799. + pr_warn("%s: failed to set AHB clock rate %d\n", __func__, ret);
  24800. /*
  24801. * usbphy1 and usbphy2 are implemented as dummy gates using reserve
  24802. @@ -118,11 +220,36 @@
  24803. clks[IMX6SL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", base + 0xf0, 2);
  24804. clks[IMX6SL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", base + 0xf0, 3);
  24805. - /* name parent_name mult div */
  24806. - clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2);
  24807. - clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
  24808. - clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
  24809. - clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
  24810. + /* name parent_name mult div */
  24811. + clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2);
  24812. + clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
  24813. + clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
  24814. + clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
  24815. + clks[IMX6SL_CLK_UART_OSC_4M] = imx_clk_fixed_factor("uart_osc_4M", "osc", 1, 6);
  24816. +
  24817. + /* Ensure all PFDs but PLL2_PFD2 are disabled. */
  24818. + reg = readl_relaxed(base + ANATOP_PFD_480n_OFFSET);
  24819. + reg |= (PFD0_CLKGATE | PFD1_CLK_GATE | PFD2_CLK_GATE | PFD3_CLK_GATE);
  24820. + writel_relaxed(reg, base + ANATOP_PFD_480n_OFFSET);
  24821. + reg = readl_relaxed(base + ANATOP_PFD_528n_OFFSET);
  24822. + reg |= (PFD0_CLKGATE | PFD1_CLK_GATE);
  24823. + writel_relaxed(reg, base + ANATOP_PFD_528n_OFFSET);
  24824. +
  24825. + /* Ensure Unused PLLs are disabled. */
  24826. + reg = readl_relaxed(base + ANATOP_PLL_USB1);
  24827. + reg |= ANATOP_PLL_BYPASS_OFFSET;
  24828. + reg &= ~(ANATOP_PLL_ENABLE_OFFSET | ANATOP_PLL_POWER_OFFSET);
  24829. + writel_relaxed(reg, base + ANATOP_PLL_USB1);
  24830. +
  24831. + reg = readl_relaxed(base + ANATOP_PLL_USB2);
  24832. + reg |= ANATOP_PLL_BYPASS_OFFSET;
  24833. + reg &= ~(ANATOP_PLL_ENABLE_OFFSET | ANATOP_PLL_POWER_OFFSET);
  24834. + writel_relaxed(reg, base + ANATOP_PLL_USB2);
  24835. +
  24836. + reg = readl_relaxed(base + ANATOP_PLL_ENET);
  24837. + reg |= (ANATOP_PLL_BYPASS_OFFSET | ANATOP_PLL_POWER_OFFSET);
  24838. + reg &= ~ANATOP_PLL_ENABLE_OFFSET;
  24839. + writel_relaxed(reg, base + ANATOP_PLL_ENET);
  24840. np = ccm_node;
  24841. base = of_iomap(np, 0);
  24842. @@ -158,7 +285,7 @@
  24843. clks[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_mux("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels));
  24844. clks[IMX6SL_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
  24845. clks[IMX6SL_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
  24846. - clks[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
  24847. + clks[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux_flags("extern_audio_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels), CLK_SET_RATE_PARENT);
  24848. clks[IMX6SL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
  24849. clks[IMX6SL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
  24850. @@ -168,8 +295,8 @@
  24851. /* name parent_name reg shift width */
  24852. clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3);
  24853. - clks[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3);
  24854. - clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3);
  24855. + clks[IMX6SL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
  24856. + clks[IMX6SL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
  24857. clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
  24858. clks[IMX6SL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
  24859. clks[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3);
  24860. @@ -251,6 +378,25 @@
  24861. pr_err("i.MX6SL clk %d: register failed with %ld\n",
  24862. i, PTR_ERR(clks[i]));
  24863. + /* Initialize clock gate status */
  24864. + writel_relaxed(1 << CCM_CCGR_OFFSET(11) |
  24865. + 3 << CCM_CCGR_OFFSET(1) |
  24866. + 3 << CCM_CCGR_OFFSET(0), base + 0x68);
  24867. + writel_relaxed(3 << CCM_CCGR_OFFSET(10), base + 0x6c);
  24868. + writel_relaxed(1 << CCM_CCGR_OFFSET(11) |
  24869. + 3 << CCM_CCGR_OFFSET(10) |
  24870. + 3 << CCM_CCGR_OFFSET(9) |
  24871. + 3 << CCM_CCGR_OFFSET(8), base + 0x70);
  24872. + writel_relaxed(3 << CCM_CCGR_OFFSET(14) |
  24873. + 3 << CCM_CCGR_OFFSET(13) |
  24874. + 3 << CCM_CCGR_OFFSET(12) |
  24875. + 3 << CCM_CCGR_OFFSET(11) |
  24876. + 3 << CCM_CCGR_OFFSET(10), base + 0x74);
  24877. + writel_relaxed(3 << CCM_CCGR_OFFSET(7) |
  24878. + 3 << CCM_CCGR_OFFSET(4), base + 0x78);
  24879. + writel_relaxed(1 << CCM_CCGR_OFFSET(0), base + 0x7c);
  24880. + writel_relaxed(0, base + 0x80);
  24881. +
  24882. clk_data.clks = clks;
  24883. clk_data.clk_num = ARRAY_SIZE(clks);
  24884. of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
  24885. @@ -258,17 +404,58 @@
  24886. clk_register_clkdev(clks[IMX6SL_CLK_GPT], "ipg", "imx-gpt.0");
  24887. clk_register_clkdev(clks[IMX6SL_CLK_GPT_SERIAL], "per", "imx-gpt.0");
  24888. + /*
  24889. + * Make sure the ARM clk is enabled to maintain the correct usecount
  24890. + * and enabling/disabling of parent PLLs.
  24891. + */
  24892. + ret = clk_prepare_enable(clks[IMX6SL_CLK_ARM]);
  24893. + if (ret)
  24894. + pr_warn("%s: failed to enable ARM core clock %d\n",
  24895. + __func__, ret);
  24896. +
  24897. + /*
  24898. + * Make sure the MMDC clk is enabled to maintain the correct usecount
  24899. + * and enabling/disabling of parent PLLs.
  24900. + */
  24901. + ret = clk_prepare_enable(clks[IMX6SL_CLK_MMDC_ROOT]);
  24902. + if (ret)
  24903. + pr_warn("%s: failed to enable MMDC clock %d\n",
  24904. + __func__, ret);
  24905. +
  24906. if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
  24907. clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]);
  24908. clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]);
  24909. }
  24910. + clk_set_parent(clks[IMX6SL_CLK_GPU2D_OVG_SEL],
  24911. + clks[IMX6SL_CLK_PLL2_BUS]);
  24912. + clk_set_parent(clks[IMX6SL_CLK_GPU2D_SEL], clks[IMX6SL_CLK_PLL2_BUS]);
  24913. +
  24914. /* Audio-related clocks configuration */
  24915. clk_set_parent(clks[IMX6SL_CLK_SPDIF0_SEL], clks[IMX6SL_CLK_PLL3_PFD3]);
  24916. + /* set extern_audio to be sourced from PLL4/audio PLL */
  24917. + clk_set_parent(clks[IMX6SL_CLK_EXTERN_AUDIO_SEL], clks[IMX6SL_CLK_PLL4_AUDIO_DIV]);
  24918. + /* set extern_audio to 24MHz */
  24919. + clk_set_rate(clks[IMX6SL_CLK_PLL4_AUDIO], 24000000);
  24920. + clk_set_rate(clks[IMX6SL_CLK_EXTERN_AUDIO], 24000000);
  24921. +
  24922. + /* set SSI2 parent to PLL4 */
  24923. + clk_set_parent(clks[IMX6SL_CLK_SSI2_SEL], clks[IMX6SL_CLK_PLL4_AUDIO_DIV]);
  24924. + clk_set_rate(clks[IMX6SL_CLK_SSI2], 24000000);
  24925. +
  24926. /* Set initial power mode */
  24927. imx6q_set_lpm(WAIT_CLOCKED);
  24928. + /* Ensure that CH0 handshake is bypassed. */
  24929. + reg = readl_relaxed(base + CCM_CCDR_OFFSET);
  24930. + reg |= 1 << CCDR_CH0_HS_BYP;
  24931. + writel_relaxed(reg, base + CCM_CCDR_OFFSET);
  24932. +
  24933. + /* Set the UART parent if needed. */
  24934. + if (uart_from_osc)
  24935. + ret = clk_set_parent(clks[IMX6SL_CLK_UART_SEL], clks[IMX6SL_CLK_UART_OSC_4M]);
  24936. +
  24937. np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpt");
  24938. base = of_iomap(np, 0);
  24939. WARN_ON(!base);
  24940. diff -Nur linux-3.14.15/arch/arm/mach-imx/clk-pfd.c linux-linaro-stable-mx6/arch/arm/mach-imx/clk-pfd.c
  24941. --- linux-3.14.15/arch/arm/mach-imx/clk-pfd.c 2014-07-31 23:51:43.000000000 +0200
  24942. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/clk-pfd.c 2014-08-20 19:31:40.084843062 +0200
  24943. @@ -1,5 +1,5 @@
  24944. /*
  24945. - * Copyright 2012 Freescale Semiconductor, Inc.
  24946. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  24947. * Copyright 2012 Linaro Ltd.
  24948. *
  24949. * The code contained herein is licensed under the GNU General Public
  24950. @@ -17,6 +17,8 @@
  24951. #include <linux/err.h>
  24952. #include "clk.h"
  24953. +#define BYPASS_RATE 24000000
  24954. +
  24955. /**
  24956. * struct clk_pfd - IMX PFD clock
  24957. * @clk_hw: clock source
  24958. @@ -62,9 +64,14 @@
  24959. u64 tmp = parent_rate;
  24960. u8 frac = (readl_relaxed(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
  24961. - tmp *= 18;
  24962. - do_div(tmp, frac);
  24963. -
  24964. + /*
  24965. + * If the parent PLL is in bypass state, the PFDs
  24966. + * are also in bypass state.
  24967. + */
  24968. + if (tmp != BYPASS_RATE) {
  24969. + tmp *= 18;
  24970. + do_div(tmp, frac);
  24971. + }
  24972. return tmp;
  24973. }
  24974. @@ -74,17 +81,22 @@
  24975. u64 tmp = *prate;
  24976. u8 frac;
  24977. - tmp = tmp * 18 + rate / 2;
  24978. - do_div(tmp, rate);
  24979. - frac = tmp;
  24980. - if (frac < 12)
  24981. - frac = 12;
  24982. - else if (frac > 35)
  24983. - frac = 35;
  24984. - tmp = *prate;
  24985. - tmp *= 18;
  24986. - do_div(tmp, frac);
  24987. -
  24988. + /*
  24989. + * If the parent PLL is in bypass state, the PFDs
  24990. + * are also in bypass state.
  24991. + */
  24992. + if (tmp != BYPASS_RATE) {
  24993. + tmp = tmp * 18 + rate / 2;
  24994. + do_div(tmp, rate);
  24995. + frac = tmp;
  24996. + if (frac < 12)
  24997. + frac = 12;
  24998. + else if (frac > 35)
  24999. + frac = 35;
  25000. + tmp = *prate;
  25001. + tmp *= 18;
  25002. + do_div(tmp, frac);
  25003. + }
  25004. return tmp;
  25005. }
  25006. @@ -95,6 +107,9 @@
  25007. u64 tmp = parent_rate;
  25008. u8 frac;
  25009. + if (tmp == BYPASS_RATE)
  25010. + return 0;
  25011. +
  25012. tmp = tmp * 18 + rate / 2;
  25013. do_div(tmp, rate);
  25014. frac = tmp;
  25015. diff -Nur linux-3.14.15/arch/arm/mach-imx/clk-pllv3.c linux-linaro-stable-mx6/arch/arm/mach-imx/clk-pllv3.c
  25016. --- linux-3.14.15/arch/arm/mach-imx/clk-pllv3.c 2014-07-31 23:51:43.000000000 +0200
  25017. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/clk-pllv3.c 2014-08-20 19:31:40.084843062 +0200
  25018. @@ -26,12 +26,15 @@
  25019. #define BM_PLL_ENABLE (0x1 << 13)
  25020. #define BM_PLL_BYPASS (0x1 << 16)
  25021. #define BM_PLL_LOCK (0x1 << 31)
  25022. +#define BYPASS_RATE 24000000
  25023. +#define BYPASS_MASK 0x10000
  25024. /**
  25025. * struct clk_pllv3 - IMX PLL clock version 3
  25026. * @clk_hw: clock source
  25027. * @base: base address of PLL registers
  25028. * @powerup_set: set POWER bit to power up the PLL
  25029. + * @always_on : Leave the PLL powered up all the time.
  25030. * @div_mask: mask of divider bits
  25031. *
  25032. * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3
  25033. @@ -41,7 +44,9 @@
  25034. struct clk_hw hw;
  25035. void __iomem *base;
  25036. bool powerup_set;
  25037. + bool always_on;
  25038. u32 div_mask;
  25039. + u32 rate_req;
  25040. };
  25041. #define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
  25042. @@ -61,54 +66,53 @@
  25043. break;
  25044. if (time_after(jiffies, timeout))
  25045. break;
  25046. - usleep_range(50, 500);
  25047. + udelay(100);
  25048. } while (1);
  25049. return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
  25050. }
  25051. -static int clk_pllv3_prepare(struct clk_hw *hw)
  25052. +static int clk_pllv3_power_up_down(struct clk_hw *hw, bool enable)
  25053. {
  25054. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25055. - u32 val;
  25056. - int ret;
  25057. -
  25058. - val = readl_relaxed(pll->base);
  25059. - if (pll->powerup_set)
  25060. - val |= BM_PLL_POWER;
  25061. - else
  25062. - val &= ~BM_PLL_POWER;
  25063. - writel_relaxed(val, pll->base);
  25064. -
  25065. - ret = clk_pllv3_wait_lock(pll);
  25066. - if (ret)
  25067. - return ret;
  25068. + u32 val, ret = 0;
  25069. - val = readl_relaxed(pll->base);
  25070. - val &= ~BM_PLL_BYPASS;
  25071. - writel_relaxed(val, pll->base);
  25072. -
  25073. - return 0;
  25074. -}
  25075. + if (enable) {
  25076. + val = readl_relaxed(pll->base);
  25077. + val &= ~BM_PLL_BYPASS;
  25078. + if (pll->powerup_set)
  25079. + val |= BM_PLL_POWER;
  25080. + else
  25081. + val &= ~BM_PLL_POWER;
  25082. + writel_relaxed(val, pll->base);
  25083. +
  25084. + ret = clk_pllv3_wait_lock(pll);
  25085. + } else {
  25086. + val = readl_relaxed(pll->base);
  25087. + val |= BM_PLL_BYPASS;
  25088. + if (pll->powerup_set)
  25089. + val &= ~BM_PLL_POWER;
  25090. + else
  25091. + val |= BM_PLL_POWER;
  25092. + writel_relaxed(val, pll->base);
  25093. + }
  25094. -static void clk_pllv3_unprepare(struct clk_hw *hw)
  25095. -{
  25096. - struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25097. - u32 val;
  25098. + if (!ret) {
  25099. + val = readl_relaxed(pll->base);
  25100. + val &= ~BM_PLL_BYPASS;
  25101. + writel_relaxed(val, pll->base);
  25102. + }
  25103. - val = readl_relaxed(pll->base);
  25104. - val |= BM_PLL_BYPASS;
  25105. - if (pll->powerup_set)
  25106. - val &= ~BM_PLL_POWER;
  25107. - else
  25108. - val |= BM_PLL_POWER;
  25109. - writel_relaxed(val, pll->base);
  25110. + return ret;
  25111. }
  25112. static int clk_pllv3_enable(struct clk_hw *hw)
  25113. {
  25114. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25115. u32 val;
  25116. +
  25117. + if (pll->rate_req != BYPASS_RATE)
  25118. + clk_pllv3_power_up_down(hw, true);
  25119. val = readl_relaxed(pll->base);
  25120. val |= BM_PLL_ENABLE;
  25121. @@ -123,8 +127,12 @@
  25122. u32 val;
  25123. val = readl_relaxed(pll->base);
  25124. - val &= ~BM_PLL_ENABLE;
  25125. + if (!pll->always_on)
  25126. + val &= ~BM_PLL_ENABLE;
  25127. writel_relaxed(val, pll->base);
  25128. +
  25129. + if (pll->rate_req != BYPASS_RATE)
  25130. + clk_pllv3_power_up_down(hw, false);
  25131. }
  25132. static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
  25133. @@ -132,8 +140,15 @@
  25134. {
  25135. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25136. u32 div = readl_relaxed(pll->base) & pll->div_mask;
  25137. + u32 bypass = readl_relaxed(pll->base) & BYPASS_MASK;
  25138. + u32 rate;
  25139. +
  25140. + if (pll->rate_req == BYPASS_RATE && bypass)
  25141. + rate = BYPASS_RATE;
  25142. + else
  25143. + rate = (div == 1) ? parent_rate * 22 : parent_rate * 20;
  25144. - return (div == 1) ? parent_rate * 22 : parent_rate * 20;
  25145. + return rate;
  25146. }
  25147. static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
  25148. @@ -141,6 +156,10 @@
  25149. {
  25150. unsigned long parent_rate = *prate;
  25151. + /* If the PLL is bypassed, its rate is 24MHz. */
  25152. + if (rate == BYPASS_RATE)
  25153. + return BYPASS_RATE;
  25154. +
  25155. return (rate >= parent_rate * 22) ? parent_rate * 22 :
  25156. parent_rate * 20;
  25157. }
  25158. @@ -151,6 +170,22 @@
  25159. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25160. u32 val, div;
  25161. + pll->rate_req = rate;
  25162. + val = readl_relaxed(pll->base);
  25163. +
  25164. + /* If the PLL is bypassed, its rate is 24MHz. */
  25165. + if (rate == BYPASS_RATE) {
  25166. + /* Set the bypass bit. */
  25167. + val |= BM_PLL_BYPASS;
  25168. + /* Power down the PLL. */
  25169. + if (pll->powerup_set)
  25170. + val &= ~BM_PLL_POWER;
  25171. + else
  25172. + val |= BM_PLL_POWER;
  25173. + writel_relaxed(val, pll->base);
  25174. +
  25175. + return 0;
  25176. + }
  25177. if (rate == parent_rate * 22)
  25178. div = 1;
  25179. else if (rate == parent_rate * 20)
  25180. @@ -167,8 +202,6 @@
  25181. }
  25182. static const struct clk_ops clk_pllv3_ops = {
  25183. - .prepare = clk_pllv3_prepare,
  25184. - .unprepare = clk_pllv3_unprepare,
  25185. .enable = clk_pllv3_enable,
  25186. .disable = clk_pllv3_disable,
  25187. .recalc_rate = clk_pllv3_recalc_rate,
  25188. @@ -181,6 +214,10 @@
  25189. {
  25190. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25191. u32 div = readl_relaxed(pll->base) & pll->div_mask;
  25192. + u32 bypass = readl_relaxed(pll->base) & BYPASS_MASK;
  25193. +
  25194. + if (pll->rate_req == BYPASS_RATE && bypass)
  25195. + return BYPASS_RATE;
  25196. return parent_rate * div / 2;
  25197. }
  25198. @@ -193,6 +230,9 @@
  25199. unsigned long max_rate = parent_rate * 108 / 2;
  25200. u32 div;
  25201. + if (rate == BYPASS_RATE)
  25202. + return BYPASS_RATE;
  25203. +
  25204. if (rate > max_rate)
  25205. rate = max_rate;
  25206. else if (rate < min_rate)
  25207. @@ -210,9 +250,26 @@
  25208. unsigned long max_rate = parent_rate * 108 / 2;
  25209. u32 val, div;
  25210. - if (rate < min_rate || rate > max_rate)
  25211. + if (rate != BYPASS_RATE && (rate < min_rate || rate > max_rate))
  25212. return -EINVAL;
  25213. + pll->rate_req = rate;
  25214. + val = readl_relaxed(pll->base);
  25215. +
  25216. + if (rate == BYPASS_RATE) {
  25217. + /*
  25218. + * Set the PLL in bypass mode if rate requested is
  25219. + * BYPASS_RATE.
  25220. + */
  25221. + val |= BM_PLL_BYPASS;
  25222. + /* Power down the PLL. */
  25223. + if (pll->powerup_set)
  25224. + val &= ~BM_PLL_POWER;
  25225. + else
  25226. + val |= BM_PLL_POWER;
  25227. + writel_relaxed(val, pll->base);
  25228. + return 0;
  25229. + }
  25230. div = rate * 2 / parent_rate;
  25231. val = readl_relaxed(pll->base);
  25232. val &= ~pll->div_mask;
  25233. @@ -223,8 +280,6 @@
  25234. }
  25235. static const struct clk_ops clk_pllv3_sys_ops = {
  25236. - .prepare = clk_pllv3_prepare,
  25237. - .unprepare = clk_pllv3_unprepare,
  25238. .enable = clk_pllv3_enable,
  25239. .disable = clk_pllv3_disable,
  25240. .recalc_rate = clk_pllv3_sys_recalc_rate,
  25241. @@ -239,6 +294,10 @@
  25242. u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
  25243. u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
  25244. u32 div = readl_relaxed(pll->base) & pll->div_mask;
  25245. + u32 bypass = readl_relaxed(pll->base) & BYPASS_MASK;
  25246. +
  25247. + if (pll->rate_req == BYPASS_RATE && bypass)
  25248. + return BYPASS_RATE;
  25249. return (parent_rate * div) + ((parent_rate / mfd) * mfn);
  25250. }
  25251. @@ -253,6 +312,9 @@
  25252. u32 mfn, mfd = 1000000;
  25253. s64 temp64;
  25254. + if (rate == BYPASS_RATE)
  25255. + return BYPASS_RATE;
  25256. +
  25257. if (rate > max_rate)
  25258. rate = max_rate;
  25259. else if (rate < min_rate)
  25260. @@ -273,13 +335,36 @@
  25261. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25262. unsigned long min_rate = parent_rate * 27;
  25263. unsigned long max_rate = parent_rate * 54;
  25264. - u32 val, div;
  25265. + u32 val, newval, div;
  25266. u32 mfn, mfd = 1000000;
  25267. s64 temp64;
  25268. + int ret;
  25269. - if (rate < min_rate || rate > max_rate)
  25270. + if (rate != BYPASS_RATE && (rate < min_rate || rate > max_rate))
  25271. return -EINVAL;
  25272. + pll->rate_req = rate;
  25273. + val = readl_relaxed(pll->base);
  25274. +
  25275. + if (rate == BYPASS_RATE) {
  25276. + /*
  25277. + * Set the PLL in bypass mode if rate requested is
  25278. + * BYPASS_RATE.
  25279. + */
  25280. + /* Bypass the PLL */
  25281. + val |= BM_PLL_BYPASS;
  25282. + /* Power down the PLL. */
  25283. + if (pll->powerup_set)
  25284. + val &= ~BM_PLL_POWER;
  25285. + else
  25286. + val |= BM_PLL_POWER;
  25287. + writel_relaxed(val, pll->base);
  25288. + return 0;
  25289. + }
  25290. + /* Else clear the bypass bit. */
  25291. + val &= ~BM_PLL_BYPASS;
  25292. + writel_relaxed(val, pll->base);
  25293. +
  25294. div = rate / parent_rate;
  25295. temp64 = (u64) (rate - div * parent_rate);
  25296. temp64 *= mfd;
  25297. @@ -287,18 +372,30 @@
  25298. mfn = temp64;
  25299. val = readl_relaxed(pll->base);
  25300. - val &= ~pll->div_mask;
  25301. - val |= div;
  25302. - writel_relaxed(val, pll->base);
  25303. +
  25304. + /* set the PLL into bypass mode */
  25305. + newval = val | BM_PLL_BYPASS;
  25306. + writel_relaxed(newval, pll->base);
  25307. +
  25308. + /* configure the new frequency */
  25309. + newval &= ~pll->div_mask;
  25310. + newval |= div;
  25311. + writel_relaxed(newval, pll->base);
  25312. writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
  25313. - writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
  25314. + writel(mfd, pll->base + PLL_DENOM_OFFSET);
  25315. - return clk_pllv3_wait_lock(pll);
  25316. + ret = clk_pllv3_wait_lock(pll);
  25317. + if (ret == 0 && val & BM_PLL_POWER) {
  25318. + /* only if it locked can we switch back to the PLL */
  25319. + newval &= ~BM_PLL_BYPASS;
  25320. + newval |= val & BM_PLL_BYPASS;
  25321. + writel(newval, pll->base);
  25322. + }
  25323. +
  25324. + return ret;
  25325. }
  25326. static const struct clk_ops clk_pllv3_av_ops = {
  25327. - .prepare = clk_pllv3_prepare,
  25328. - .unprepare = clk_pllv3_unprepare,
  25329. .enable = clk_pllv3_enable,
  25330. .disable = clk_pllv3_disable,
  25331. .recalc_rate = clk_pllv3_av_recalc_rate,
  25332. @@ -313,8 +410,6 @@
  25333. }
  25334. static const struct clk_ops clk_pllv3_enet_ops = {
  25335. - .prepare = clk_pllv3_prepare,
  25336. - .unprepare = clk_pllv3_unprepare,
  25337. .enable = clk_pllv3_enable,
  25338. .disable = clk_pllv3_disable,
  25339. .recalc_rate = clk_pllv3_enet_recalc_rate,
  25340. @@ -322,7 +417,7 @@
  25341. struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
  25342. const char *parent_name, void __iomem *base,
  25343. - u32 div_mask)
  25344. + u32 div_mask, bool always_on)
  25345. {
  25346. struct clk_pllv3 *pll;
  25347. const struct clk_ops *ops;
  25348. @@ -352,6 +447,7 @@
  25349. }
  25350. pll->base = base;
  25351. pll->div_mask = div_mask;
  25352. + pll->always_on = always_on;
  25353. init.name = name;
  25354. init.ops = ops;
  25355. diff -Nur linux-3.14.15/arch/arm/mach-imx/common.h linux-linaro-stable-mx6/arch/arm/mach-imx/common.h
  25356. --- linux-3.14.15/arch/arm/mach-imx/common.h 2014-07-31 23:51:43.000000000 +0200
  25357. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/common.h 2014-08-20 19:31:40.084843062 +0200
  25358. @@ -1,5 +1,5 @@
  25359. /*
  25360. - * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  25361. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  25362. */
  25363. /*
  25364. @@ -116,7 +116,6 @@
  25365. void imx_set_cpu_jump(int cpu, void *jump_addr);
  25366. u32 imx_get_cpu_arg(int cpu);
  25367. void imx_set_cpu_arg(int cpu, u32 arg);
  25368. -void v7_cpu_resume(void);
  25369. #ifdef CONFIG_SMP
  25370. void v7_secondary_startup(void);
  25371. void imx_scu_map_io(void);
  25372. @@ -129,7 +128,7 @@
  25373. #endif
  25374. void imx_src_init(void);
  25375. void imx_gpc_init(void);
  25376. -void imx_gpc_pre_suspend(void);
  25377. +void imx_gpc_pre_suspend(bool arm_power_off);
  25378. void imx_gpc_post_resume(void);
  25379. void imx_gpc_mask_all(void);
  25380. void imx_gpc_restore_all(void);
  25381. @@ -138,14 +137,28 @@
  25382. void imx_anatop_init(void);
  25383. void imx_anatop_pre_suspend(void);
  25384. void imx_anatop_post_resume(void);
  25385. +void imx_anatop_pu_enable(bool enable);
  25386. int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
  25387. -void imx6q_set_chicken_bit(void);
  25388. +void imx6q_set_cache_lpm_in_wait(bool enable);
  25389. +void imx6sl_set_wait_clk(bool enter);
  25390. +void imx6_enet_mac_init(const char *compatible);
  25391. void imx_cpu_die(unsigned int cpu);
  25392. int imx_cpu_kill(unsigned int cpu);
  25393. +#ifdef CONFIG_SUSPEND
  25394. +void v7_cpu_resume(void);
  25395. +void imx6_suspend(void __iomem *ocram_vbase);
  25396. +#else
  25397. +static inline void v7_cpu_resume(void) {}
  25398. +static inline void imx6_suspend(void __iomem *ocram_vbase) {}
  25399. +#endif
  25400. +
  25401. void imx6q_pm_init(void);
  25402. +void imx6dl_pm_init(void);
  25403. +void imx6sl_pm_init(void);
  25404. void imx6q_pm_set_ccm_base(void __iomem *base);
  25405. +
  25406. #ifdef CONFIG_PM
  25407. void imx5_pm_init(void);
  25408. #else
  25409. diff -Nur linux-3.14.15/arch/arm/mach-imx/cpuidle.h linux-linaro-stable-mx6/arch/arm/mach-imx/cpuidle.h
  25410. --- linux-3.14.15/arch/arm/mach-imx/cpuidle.h 2014-07-31 23:51:43.000000000 +0200
  25411. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/cpuidle.h 2014-08-20 19:23:45.798812710 +0200
  25412. @@ -1,5 +1,5 @@
  25413. /*
  25414. - * Copyright 2012 Freescale Semiconductor, Inc.
  25415. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  25416. * Copyright 2012 Linaro Ltd.
  25417. *
  25418. * The code contained herein is licensed under the GNU General Public
  25419. @@ -13,6 +13,7 @@
  25420. #ifdef CONFIG_CPU_IDLE
  25421. extern int imx5_cpuidle_init(void);
  25422. extern int imx6q_cpuidle_init(void);
  25423. +extern int imx6sl_cpuidle_init(void);
  25424. #else
  25425. static inline int imx5_cpuidle_init(void)
  25426. {
  25427. @@ -22,4 +23,8 @@
  25428. {
  25429. return 0;
  25430. }
  25431. +static inline int imx6sl_cpuidle_init(void)
  25432. +{
  25433. + return 0;
  25434. +}
  25435. #endif
  25436. diff -Nur linux-3.14.15/arch/arm/mach-imx/cpuidle-imx6q.c linux-linaro-stable-mx6/arch/arm/mach-imx/cpuidle-imx6q.c
  25437. --- linux-3.14.15/arch/arm/mach-imx/cpuidle-imx6q.c 2014-07-31 23:51:43.000000000 +0200
  25438. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/cpuidle-imx6q.c 2014-08-20 19:31:40.084843062 +0200
  25439. @@ -1,5 +1,5 @@
  25440. /*
  25441. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  25442. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  25443. *
  25444. * This program is free software; you can redistribute it and/or modify
  25445. * it under the terms of the GNU General Public License version 2 as
  25446. @@ -68,8 +68,8 @@
  25447. /* Need to enable SCU standby for entering WAIT modes */
  25448. imx_scu_standby_enable();
  25449. - /* Set chicken bit to get a reliable WAIT mode support */
  25450. - imx6q_set_chicken_bit();
  25451. + /* Set cache lpm bit for reliable WAIT mode support */
  25452. + imx6q_set_cache_lpm_in_wait(true);
  25453. return cpuidle_register(&imx6q_cpuidle_driver, NULL);
  25454. }
  25455. diff -Nur linux-3.14.15/arch/arm/mach-imx/cpuidle-imx6sl.c linux-linaro-stable-mx6/arch/arm/mach-imx/cpuidle-imx6sl.c
  25456. --- linux-3.14.15/arch/arm/mach-imx/cpuidle-imx6sl.c 1970-01-01 01:00:00.000000000 +0100
  25457. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/cpuidle-imx6sl.c 2014-08-20 19:31:40.084843062 +0200
  25458. @@ -0,0 +1,149 @@
  25459. +/*
  25460. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  25461. + *
  25462. + * This program is free software; you can redistribute it and/or modify
  25463. + * it under the terms of the GNU General Public License version 2 as
  25464. + * published by the Free Software Foundation.
  25465. + */
  25466. +
  25467. +#include <linux/cpuidle.h>
  25468. +#include <linux/genalloc.h>
  25469. +#include <linux/module.h>
  25470. +#include <linux/of.h>
  25471. +#include <linux/of_address.h>
  25472. +#include <linux/of_device.h>
  25473. +#include <asm/cpuidle.h>
  25474. +#include <asm/fncpy.h>
  25475. +#include <asm/mach/map.h>
  25476. +#include <asm/proc-fns.h>
  25477. +#include <asm/tlb.h>
  25478. +
  25479. +#include "common.h"
  25480. +#include "cpuidle.h"
  25481. +
  25482. +extern u32 audio_bus_freq_mode;
  25483. +extern u32 ultra_low_bus_freq_mode;
  25484. +extern unsigned long reg_addrs[];
  25485. +extern void imx6sl_low_power_wfi(void);
  25486. +
  25487. +static void __iomem *iomux_base;
  25488. +static void *wfi_iram_base;
  25489. +
  25490. +void (*imx6sl_wfi_in_iram_fn)(void *wfi_iram_base,
  25491. + void *iomux_addr, void *regs_addr, u32 audio_mode) = NULL;
  25492. +
  25493. +#define WFI_IN_IRAM_SIZE 0x1000
  25494. +
  25495. +static int imx6sl_enter_wait(struct cpuidle_device *dev,
  25496. + struct cpuidle_driver *drv, int index)
  25497. +{
  25498. + imx6q_set_lpm(WAIT_UNCLOCKED);
  25499. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  25500. + if (ultra_low_bus_freq_mode || audio_bus_freq_mode) {
  25501. + /*
  25502. + * Flush the TLB, to ensure no TLB maintenance occurs
  25503. + * when DDR is in self-refresh.
  25504. + */
  25505. + local_flush_tlb_all();
  25506. + /*
  25507. + * Run WFI code from IRAM.
  25508. + * Drop the DDR freq to 1MHz and AHB to 3MHz
  25509. + * Also float DDR IO pads.
  25510. + */
  25511. + imx6sl_wfi_in_iram_fn(wfi_iram_base, iomux_base, reg_addrs, audio_bus_freq_mode);
  25512. + }
  25513. + else
  25514. +#endif
  25515. + {
  25516. + imx6sl_set_wait_clk(true);
  25517. + cpu_do_idle();
  25518. + imx6sl_set_wait_clk(false);
  25519. + }
  25520. + imx6q_set_lpm(WAIT_CLOCKED);
  25521. +
  25522. + return index;
  25523. +}
  25524. +
  25525. +static struct cpuidle_driver imx6sl_cpuidle_driver = {
  25526. + .name = "imx6sl_cpuidle",
  25527. + .owner = THIS_MODULE,
  25528. + .states = {
  25529. + /* WFI */
  25530. + ARM_CPUIDLE_WFI_STATE,
  25531. + /* WAIT */
  25532. + {
  25533. + .exit_latency = 50,
  25534. + .target_residency = 75,
  25535. + .flags = CPUIDLE_FLAG_TIME_VALID |
  25536. + CPUIDLE_FLAG_TIMER_STOP,
  25537. + .enter = imx6sl_enter_wait,
  25538. + .name = "WAIT",
  25539. + .desc = "Clock off",
  25540. + },
  25541. + },
  25542. + .state_count = 2,
  25543. + .safe_state_index = 0,
  25544. +};
  25545. +
  25546. +int __init imx6sl_cpuidle_init(void)
  25547. +{
  25548. + struct platform_device *ocram_dev;
  25549. + unsigned int iram_paddr;
  25550. + struct device_node *node;
  25551. + struct gen_pool *iram_pool;
  25552. +
  25553. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-iomuxc");
  25554. + if (!node) {
  25555. + pr_err("failed to find imx6sl-iomuxc device tree data!\n");
  25556. + return -EINVAL;
  25557. + }
  25558. + iomux_base = of_iomap(node, 0);
  25559. + WARN(!iomux_base, "unable to map iomux registers\n");
  25560. +
  25561. + node = NULL;
  25562. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  25563. + if (!node) {
  25564. + pr_err("%s: failed to find ocram node\n",
  25565. + __func__);
  25566. + return -EINVAL;
  25567. + }
  25568. +
  25569. + ocram_dev = of_find_device_by_node(node);
  25570. + if (!ocram_dev) {
  25571. + pr_err("failed to find ocram device!\n");
  25572. + return -EINVAL;
  25573. + }
  25574. +
  25575. + iram_pool = dev_get_gen_pool(&ocram_dev->dev);
  25576. + if (!iram_pool) {
  25577. + pr_err("iram pool unavailable!\n");
  25578. + return -EINVAL;
  25579. + }
  25580. + /*
  25581. + * Allocate IRAM memory when ARM executes WFI in
  25582. + * ultra_low_power_mode.
  25583. + */
  25584. + wfi_iram_base = (void *)gen_pool_alloc(iram_pool,
  25585. + WFI_IN_IRAM_SIZE);
  25586. + if (!wfi_iram_base) {
  25587. + pr_err("Cannot alloc iram for wfi code!\n");
  25588. + return -ENOMEM;
  25589. + }
  25590. +
  25591. + iram_paddr = gen_pool_virt_to_phys(iram_pool,
  25592. + (unsigned long)wfi_iram_base);
  25593. + /*
  25594. + * Need to remap the area here since we want
  25595. + * the memory region to be executable.
  25596. + */
  25597. + wfi_iram_base = __arm_ioremap(iram_paddr,
  25598. + WFI_IN_IRAM_SIZE,
  25599. + MT_MEMORY_RWX_NONCACHED);
  25600. + if (!wfi_iram_base)
  25601. + pr_err("wfi_ram_base NOT remapped\n");
  25602. +
  25603. + imx6sl_wfi_in_iram_fn = (void *)fncpy(wfi_iram_base,
  25604. + &imx6sl_low_power_wfi, WFI_IN_IRAM_SIZE);
  25605. +
  25606. + return cpuidle_register(&imx6sl_cpuidle_driver, NULL);
  25607. +}
  25608. diff -Nur linux-3.14.15/arch/arm/mach-imx/ddr3_freq_imx6.S linux-linaro-stable-mx6/arch/arm/mach-imx/ddr3_freq_imx6.S
  25609. --- linux-3.14.15/arch/arm/mach-imx/ddr3_freq_imx6.S 1970-01-01 01:00:00.000000000 +0100
  25610. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/ddr3_freq_imx6.S 2014-08-20 19:23:45.798812710 +0200
  25611. @@ -0,0 +1,893 @@
  25612. +/*
  25613. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  25614. + *
  25615. + * This program is free software; you can redistribute it and/or modify
  25616. + * it under the terms of the GNU General Public License as published by
  25617. + * the Free Software Foundation; either version 2 of the License, or
  25618. + * (at your option) any later version.
  25619. +
  25620. + * This program is distributed in the hope that it will be useful,
  25621. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25622. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25623. + * GNU General Public License for more details.
  25624. +
  25625. + * You should have received a copy of the GNU General Public License along
  25626. + * with this program; if not, write to the Free Software Foundation, Inc.,
  25627. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  25628. + */
  25629. +
  25630. +#include <linux/linkage.h>
  25631. +
  25632. +#define MMDC0_MDPDC 0x4
  25633. +#define MMDC0_MDCF0 0x0c
  25634. +#define MMDC0_MDCF1 0x10
  25635. +#define MMDC0_MDMISC 0x18
  25636. +#define MMDC0_MDSCR 0x1c
  25637. +#define MMDC0_MAPSR 0x404
  25638. +#define MMDC0_MADPCR0 0x410
  25639. +#define MMDC0_MPZQHWCTRL 0x800
  25640. +#define MMDC1_MPZQHWCTRL 0x4800
  25641. +#define MMDC0_MPODTCTRL 0x818
  25642. +#define MMDC1_MPODTCTRL 0x4818
  25643. +#define MMDC0_MPDGCTRL0 0x83c
  25644. +#define MMDC1_MPDGCTRL0 0x483c
  25645. +#define MMDC0_MPMUR0 0x8b8
  25646. +#define MMDC1_MPMUR0 0x48b8
  25647. +
  25648. +#define CCM_CBCDR 0x14
  25649. +#define CCM_CBCMR 0x18
  25650. +#define CCM_CSCMR1 0x1c
  25651. +#define CCM_CDHIPR 0x48
  25652. +
  25653. +#define L2_CACHE_SYNC 0x730
  25654. +
  25655. + .align 3
  25656. +
  25657. + .macro switch_to_528MHz
  25658. +
  25659. + /* check if periph_clk_sel is already set */
  25660. + ldr r0, [r6, #CCM_CBCDR]
  25661. + and r0, r0, #(1 << 25)
  25662. + cmp r0, #(1 << 25)
  25663. + beq set_ahb_podf_before_switch
  25664. +
  25665. + /* change periph_clk to be sourced from pll3_clk. */
  25666. + ldr r0, [r6, #CCM_CBCMR]
  25667. + bic r0, r0, #(3 << 12)
  25668. + str r0, [r6, #CCM_CBCMR]
  25669. +
  25670. + ldr r0, [r6, #CCM_CBCDR]
  25671. + bic r0, r0, #(0x38 << 20)
  25672. + str r0, [r6, #CCM_CBCDR]
  25673. +
  25674. + /*
  25675. + * set the AHB dividers before the switch,
  25676. + * don't change AXI clock divider,
  25677. + * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
  25678. + */
  25679. + ldr r0, [r6, #CCM_CBCDR]
  25680. + ldr r2, =0x3f1f00
  25681. + bic r0, r0, r2
  25682. + orr r0, r0, #0xd00
  25683. + orr r0, r0, #(1 << 16)
  25684. + str r0, [r6, #CCM_CBCDR]
  25685. +
  25686. +wait_div_update528:
  25687. + ldr r0, [r6, #CCM_CDHIPR]
  25688. + cmp r0, #0
  25689. + bne wait_div_update528
  25690. +
  25691. + /* now switch periph_clk to pll3_main_clk. */
  25692. + ldr r0, [r6, #CCM_CBCDR]
  25693. + orr r0, r0, #(1 << 25)
  25694. + str r0, [r6, #CCM_CBCDR]
  25695. +
  25696. +periph_clk_switch3:
  25697. + ldr r0, [r6, #CCM_CDHIPR]
  25698. + cmp r0, #0
  25699. + bne periph_clk_switch3
  25700. +
  25701. + b switch_pre_periph_clk_528
  25702. +
  25703. +set_ahb_podf_before_switch:
  25704. + /*
  25705. + * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
  25706. + */
  25707. + ldr r0, [r6, #CCM_CBCDR]
  25708. + ldr r2, =0x3f1f00
  25709. + bic r0, r0, r2
  25710. + orr r0, r0, #0xd00
  25711. + orr r0, r0, #(1 << 16)
  25712. + str r0, [r6, #CCM_CBCDR]
  25713. +
  25714. +wait_div_update528_1:
  25715. + ldr r0, [r6, #CCM_CDHIPR]
  25716. + cmp r0, #0
  25717. + bne wait_div_update528_1
  25718. +
  25719. +switch_pre_periph_clk_528:
  25720. +
  25721. + /* now switch pre_periph_clk to PLL2_528MHz. */
  25722. + ldr r0, [r6, #CCM_CBCMR]
  25723. + bic r0, r0, #(0xc << 16)
  25724. + str r0, [r6, #CCM_CBCMR]
  25725. +
  25726. + /* now switch periph_clk back. */
  25727. + ldr r0, [r6, #CCM_CBCDR]
  25728. + bic r0, r0, #(1 << 25)
  25729. + str r0, [r6, #CCM_CBCDR]
  25730. +
  25731. +periph_clk_switch4:
  25732. + ldr r0, [r6, #CCM_CDHIPR]
  25733. + cmp r0, #0
  25734. + bne periph_clk_switch4
  25735. +
  25736. + .endm
  25737. +
  25738. + .macro switch_to_400MHz
  25739. +
  25740. + /* check if periph_clk_sel is already set. */
  25741. + ldr r0, [r6, #CCM_CBCDR]
  25742. + and r0, r0, #(1 << 25)
  25743. + cmp r0, #(1 << 25)
  25744. + beq set_ahb_podf_before_switch1
  25745. +
  25746. + /* change periph_clk to be sourced from pll3_clk. */
  25747. + ldr r0, [r6, #CCM_CBCMR]
  25748. + bic r0, r0, #(3 << 12)
  25749. + str r0, [r6, #CCM_CBCMR]
  25750. +
  25751. + ldr r0, [r6, #CCM_CBCDR]
  25752. + bic r0, r0, #(0x38 << 24)
  25753. + str r0, [r6, #CCM_CBCDR]
  25754. +
  25755. + /* now switch periph_clk to pll3_main_clk. */
  25756. + ldr r0, [r6, #CCM_CBCDR]
  25757. + orr r0, r0, #(1 << 25)
  25758. + str r0, [r6, #CCM_CBCDR]
  25759. +
  25760. +periph_clk_switch5:
  25761. + ldr r0, [r6, #CCM_CDHIPR]
  25762. + cmp r0, #0
  25763. + bne periph_clk_switch5
  25764. +
  25765. + b switch_pre_periph_clk_400
  25766. +
  25767. +set_ahb_podf_before_switch1:
  25768. + /*
  25769. + * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
  25770. + */
  25771. + ldr r0, [r6, #CCM_CBCDR]
  25772. + ldr r2, =0x3f1f00
  25773. + bic r0, r0, r2
  25774. + orr r0, r0, #(0x9 << 8)
  25775. + orr r0, r0, #(1 << 16)
  25776. + str r0, [r6, #CCM_CBCDR]
  25777. +
  25778. +wait_div_update400_1:
  25779. + ldr r0, [r6, #CCM_CDHIPR]
  25780. + cmp r0, #0
  25781. + bne wait_div_update400_1
  25782. +
  25783. +switch_pre_periph_clk_400:
  25784. +
  25785. + /* now switch pre_periph_clk to PFD_400MHz. */
  25786. + ldr r0, [r6, #CCM_CBCMR]
  25787. + bic r0, r0, #(0xc << 16)
  25788. + orr r0, r0, #(0x4 << 16)
  25789. + str r0, [r6, #CCM_CBCMR]
  25790. +
  25791. + /* now switch periph_clk back. */
  25792. + ldr r0, [r6, #CCM_CBCDR]
  25793. + bic r0, r0, #(1 << 25)
  25794. + str r0, [r6, #CCM_CBCDR]
  25795. +
  25796. +periph_clk_switch6:
  25797. + ldr r0, [r6, #CCM_CDHIPR]
  25798. + cmp r0, #0
  25799. + bne periph_clk_switch6
  25800. +
  25801. + /*
  25802. + * change AHB divider so that we are at 400/3=133MHz.
  25803. + * don't change AXI clock divider.
  25804. + * set the MMDC_DIV=1, AXI_DIV=2, AHB_DIV=3,
  25805. + */
  25806. + ldr r0, [r6, #CCM_CBCDR]
  25807. + ldr r2, =0x3f1f00
  25808. + bic r0, r0, r2
  25809. + orr r0, r0, #(0x9 << 8)
  25810. + orr r0, r0, #(1 << 16)
  25811. + str r0, [r6, #CCM_CBCDR]
  25812. +
  25813. +wait_div_update400_2:
  25814. + ldr r0, [r6, #CCM_CDHIPR]
  25815. + cmp r0, #0
  25816. + bne wait_div_update400_2
  25817. +
  25818. + .endm
  25819. +
  25820. + .macro switch_to_50MHz
  25821. +
  25822. + /* check if periph_clk_sel is already set. */
  25823. + ldr r0, [r6, #CCM_CBCDR]
  25824. + and r0, r0, #(1 << 25)
  25825. + cmp r0, #(1 << 25)
  25826. + beq switch_pre_periph_clk_50
  25827. +
  25828. + /*
  25829. + * set the periph_clk to be sourced from PLL2_PFD_200M
  25830. + * change periph_clk to be sourced from pll3_clk.
  25831. + * ensure PLL3 is the source and set the divider to 1.
  25832. + */
  25833. + ldr r0, [r6, #CCM_CBCMR]
  25834. + bic r0, r0, #(0x3 << 12)
  25835. + str r0, [r6, #CCM_CBCMR]
  25836. +
  25837. + ldr r0, [r6, #CCM_CBCDR]
  25838. + bic r0, r0, #(0x38 << 24)
  25839. + str r0, [r6, #CCM_CBCDR]
  25840. +
  25841. + /* now switch periph_clk to pll3_main_clk. */
  25842. + ldr r0, [r6, #CCM_CBCDR]
  25843. + orr r0, r0, #(1 << 25)
  25844. + str r0, [r6, #CCM_CBCDR]
  25845. +
  25846. +periph_clk_switch_50:
  25847. + ldr r0, [r6, #CCM_CDHIPR]
  25848. + cmp r0, #0
  25849. + bne periph_clk_switch_50
  25850. +
  25851. +switch_pre_periph_clk_50:
  25852. +
  25853. + /* now switch pre_periph_clk to PFD_200MHz. */
  25854. + ldr r0, [r6, #CCM_CBCMR]
  25855. + orr r0, r0, #(0xc << 16)
  25856. + str r0, [r6, #CCM_CBCMR]
  25857. +
  25858. + /*
  25859. + * set the MMDC_DIV=4, AXI_DIV = 4, AHB_DIV=8,
  25860. + */
  25861. + ldr r0, [r6, #CCM_CBCDR]
  25862. + ldr r2, =0x3f1f00
  25863. + bic r0, r0, r2
  25864. + orr r0, r0, #(0x18 << 16)
  25865. + orr r0, r0, #(0x3 << 16)
  25866. +
  25867. + /*
  25868. + * if changing AHB divider remember to change
  25869. + * the IPGPER divider too below.
  25870. + */
  25871. + orr r0, r0, #0x1d00
  25872. + str r0, [r6, #CCM_CBCDR]
  25873. +
  25874. +wait_div_update_50:
  25875. + ldr r0, [r6, #CCM_CDHIPR]
  25876. + cmp r0, #0
  25877. + bne wait_div_update_50
  25878. +
  25879. + /* now switch periph_clk back. */
  25880. + ldr r0, [r6, #CCM_CBCDR]
  25881. + bic r0, r0, #(1 << 25)
  25882. + str r0, [r6, #CCM_CBCDR]
  25883. +
  25884. +periph_clk_switch2:
  25885. + ldr r0, [r6, #CCM_CDHIPR]
  25886. + cmp r0, #0
  25887. + bne periph_clk_switch2
  25888. +
  25889. + .endm
  25890. +
  25891. + .macro switch_to_24MHz
  25892. + /*
  25893. + * change the freq now try setting DDR to 24MHz.
  25894. + * source it from the periph_clk2 ensure the
  25895. + * periph_clk2 is sourced from 24MHz and the
  25896. + * divider is 1.
  25897. + */
  25898. +
  25899. + ldr r0, [r6, #CCM_CBCMR]
  25900. + bic r0, r0, #(0x3 << 12)
  25901. + orr r0, r0, #(1 << 12)
  25902. + str r0, [r6, #CCM_CBCMR]
  25903. +
  25904. + ldr r0, [r6, #CCM_CBCDR]
  25905. + bic r0, r0, #(0x38 << 24)
  25906. + str r0, [r6, #CCM_CBCDR]
  25907. +
  25908. + /* now switch periph_clk to 24MHz. */
  25909. + ldr r0, [r6, #CCM_CBCDR]
  25910. + orr r0, r0, #(1 << 25)
  25911. + str r0, [r6, #CCM_CBCDR]
  25912. +
  25913. +periph_clk_switch1:
  25914. + ldr r0, [r6, #CCM_CDHIPR]
  25915. + cmp r0, #0
  25916. + bne periph_clk_switch1
  25917. +
  25918. + /* change all the dividers to 1. */
  25919. + ldr r0, [r6, #CCM_CBCDR]
  25920. + ldr r2, =0x3f1f00
  25921. + bic r0, r0, r2
  25922. + orr r0, r0, #(1 << 8)
  25923. + str r0, [r6, #CCM_CBCDR]
  25924. +
  25925. + /* Wait for the divider to change. */
  25926. +wait_div_update:
  25927. + ldr r0, [r6, #CCM_CDHIPR]
  25928. + cmp r0, #0
  25929. + bne wait_div_update
  25930. +
  25931. + .endm
  25932. +
  25933. +/*
  25934. + * mx6_ddr3_freq_change
  25935. + *
  25936. + * idle the processor (eg, wait for interrupt).
  25937. + * make sure DDR is in self-refresh.
  25938. + * IRQs are already disabled.
  25939. + */
  25940. +ENTRY(mx6_ddr3_freq_change)
  25941. +
  25942. + stmfd sp!, {r4-r12}
  25943. +
  25944. + /*
  25945. + * r5 -> mmdc_base
  25946. + * r6 -> ccm_base
  25947. + * r7 -> iomux_base
  25948. + * r12 -> l2_base
  25949. + */
  25950. + mov r4, r0
  25951. + mov r8, r1
  25952. + mov r9, r2
  25953. + mov r11, r3
  25954. +
  25955. + /*
  25956. + * Get the addresses of the registers.
  25957. + * They are last few entries in the
  25958. + * ddr_settings parameter.
  25959. + * The first entry contains the count,
  25960. + * and each entry is 2 words.
  25961. + */
  25962. + ldr r0, [r1]
  25963. + add r0, r0, #1
  25964. + lsl r0, r0, #3
  25965. + add r1, r0, r1
  25966. + /* mmdc_base. */
  25967. + ldr r5, [r1]
  25968. + add r1, #8
  25969. + /* ccm_base */
  25970. + ldr r6, [r1]
  25971. + add r1, #8
  25972. + /*iomux_base */
  25973. + ldr r7, [r1]
  25974. + add r1, #8
  25975. + /*l2_base */
  25976. + ldr r12, [r1]
  25977. +
  25978. +ddr_freq_change:
  25979. + /*
  25980. + * make sure no TLB miss will occur when
  25981. + * the DDR is in self refresh. invalidate
  25982. + * TLB single entry to ensure that the
  25983. + * address is not already in the TLB.
  25984. + */
  25985. +
  25986. + adr r10, ddr_freq_change
  25987. +
  25988. + ldr r2, [r6]
  25989. + ldr r2, [r5]
  25990. + ldr r2, [r7]
  25991. + ldr r2, [r8]
  25992. + ldr r2, [r10]
  25993. + ldr r2, [r11]
  25994. + ldr r2, [r12]
  25995. +
  25996. +#ifdef CONFIG_CACHE_L2X0
  25997. + /*
  25998. + * Make sure the L2 buffers are drained.
  25999. + * Sync operation on L2 drains the buffers.
  26000. + */
  26001. + mov r1, #0x0
  26002. + str r1, [r12, #L2_CACHE_SYNC]
  26003. +#endif
  26004. +
  26005. + /* disable automatic power saving. */
  26006. + ldr r0, [r5, #MMDC0_MAPSR]
  26007. + orr r0, r0, #0x01
  26008. + str r0, [r5, #MMDC0_MAPSR]
  26009. +
  26010. + /* disable MMDC power down timer. */
  26011. + ldr r0, [r5, #MMDC0_MDPDC]
  26012. + bic r0, r0, #(0xff << 8)
  26013. + str r0, [r5, #MMDC0_MDPDC]
  26014. +
  26015. + /* delay for a while */
  26016. + ldr r1, =4
  26017. +delay1:
  26018. + ldr r2, =0
  26019. +cont1:
  26020. + ldr r0, [r5, r2]
  26021. + add r2, r2, #4
  26022. + cmp r2, #16
  26023. + bne cont1
  26024. + sub r1, r1, #1
  26025. + cmp r1, #0
  26026. + bgt delay1
  26027. +
  26028. + /* set CON_REG */
  26029. + ldr r0, =0x8000
  26030. + str r0, [r5, #MMDC0_MDSCR]
  26031. +poll_conreq_set_1:
  26032. + ldr r0, [r5, #MMDC0_MDSCR]
  26033. + and r0, r0, #(0x4 << 12)
  26034. + cmp r0, #(0x4 << 12)
  26035. + bne poll_conreq_set_1
  26036. +
  26037. + ldr r0, =0x00008010
  26038. + str r0, [r5, #MMDC0_MDSCR]
  26039. + ldr r0, =0x00008018
  26040. + str r0, [r5, #MMDC0_MDSCR]
  26041. +
  26042. + /*
  26043. + * if requested frequency is greater than
  26044. + * 300MHz go to DLL on mode.
  26045. + */
  26046. + ldr r1, =300000000
  26047. + cmp r4, r1
  26048. + bge dll_on_mode
  26049. +
  26050. +dll_off_mode:
  26051. +
  26052. + /* if DLL is currently on, turn it off. */
  26053. + cmp r9, #1
  26054. + beq continue_dll_off_1
  26055. +
  26056. + ldr r0, =0x00018031
  26057. + str r0, [r5, #MMDC0_MDSCR]
  26058. +
  26059. + ldr r0, =0x00018039
  26060. + str r0, [r5, #MMDC0_MDSCR]
  26061. +
  26062. + ldr r1, =10
  26063. +delay1a:
  26064. + ldr r2, =0
  26065. +cont1a:
  26066. + ldr r0, [r5, r2]
  26067. + add r2, r2, #4
  26068. + cmp r2, #16
  26069. + bne cont1a
  26070. + sub r1, r1, #1
  26071. + cmp r1, #0
  26072. + bgt delay1a
  26073. +
  26074. +continue_dll_off_1:
  26075. + /* set DVFS - enter self refresh mode */
  26076. + ldr r0, [r5, #MMDC0_MAPSR]
  26077. + orr r0, r0, #(1 << 21)
  26078. + str r0, [r5, #MMDC0_MAPSR]
  26079. +
  26080. + /* de-assert con_req */
  26081. + mov r0, #0x0
  26082. + str r0, [r5, #MMDC0_MDSCR]
  26083. +
  26084. +poll_dvfs_set_1:
  26085. + ldr r0, [r5, #MMDC0_MAPSR]
  26086. + and r0, r0, #(1 << 25)
  26087. + cmp r0, #(1 << 25)
  26088. + bne poll_dvfs_set_1
  26089. +
  26090. + ldr r1, =24000000
  26091. + cmp r4, r1
  26092. + beq switch_freq_24
  26093. +
  26094. + switch_to_50MHz
  26095. + b continue_dll_off_2
  26096. +
  26097. +switch_freq_24:
  26098. + switch_to_24MHz
  26099. +
  26100. +continue_dll_off_2:
  26101. +
  26102. + /* set SBS - block ddr accesses */
  26103. + ldr r0, [r5, #MMDC0_MADPCR0]
  26104. + orr r0, r0, #(1 << 8)
  26105. + str r0, [r5, #MMDC0_MADPCR0]
  26106. +
  26107. + /* clear DVFS - exit from self refresh mode */
  26108. + ldr r0, [r5, #MMDC0_MAPSR]
  26109. + bic r0, r0, #(1 << 21)
  26110. + str r0, [r5, #MMDC0_MAPSR]
  26111. +
  26112. +poll_dvfs_clear_1:
  26113. + ldr r0, [r5, #MMDC0_MAPSR]
  26114. + and r0, r0, #(1 << 25)
  26115. + cmp r0, #(1 << 25)
  26116. + beq poll_dvfs_clear_1
  26117. +
  26118. + /* if DLL was previously on, continue DLL off routine. */
  26119. + cmp r9, #1
  26120. + beq continue_dll_off_3
  26121. +
  26122. + ldr r0, =0x00018031
  26123. + str r0, [r5, #MMDC0_MDSCR]
  26124. +
  26125. + ldr r0, =0x00018039
  26126. + str r0, [r5, #MMDC0_MDSCR]
  26127. +
  26128. + ldr r0, =0x08208030
  26129. + str r0, [r5, #MMDC0_MDSCR]
  26130. +
  26131. + ldr r0, =0x08208038
  26132. + str r0, [r5, #MMDC0_MDSCR]
  26133. +
  26134. + ldr r0, =0x00088032
  26135. + str r0, [r5, #MMDC0_MDSCR]
  26136. +
  26137. + ldr r0, =0x0008803A
  26138. + str r0, [r5, #MMDC0_MDSCR]
  26139. +
  26140. + /* delay for a while. */
  26141. + ldr r1, =4
  26142. +delay_1:
  26143. + ldr r2, =0
  26144. +cont_1:
  26145. + ldr r0, [r5, r2]
  26146. + add r2, r2, #4
  26147. + cmp r2, #16
  26148. + bne cont_1
  26149. + sub r1, r1, #1
  26150. + cmp r1, #0
  26151. + bgt delay_1
  26152. +
  26153. + ldr r0, [r5, #MMDC0_MDCF0]
  26154. + bic r0, r0, #0xf
  26155. + orr r0, r0, #0x3
  26156. + str r0, [r5, #MMDC0_MDCF0]
  26157. +
  26158. + ldr r0, [r5, #MMDC0_MDCF1]
  26159. + bic r0, r0, #0x7
  26160. + orr r0, r0, #0x4
  26161. + str r0, [r5, #MMDC0_MDCF1]
  26162. +
  26163. + ldr r0, =0x00091680
  26164. + str r0, [r5, #MMDC0_MDMISC]
  26165. +
  26166. + /* enable dqs pull down in the IOMUX. */
  26167. + ldr r1, [r11]
  26168. + add r11, r11, #8
  26169. + ldr r2, =0x3028
  26170. +update_iomux:
  26171. + ldr r0, [r11, #0x0]
  26172. + ldr r3, [r7, r0]
  26173. + bic r3, r3, r2
  26174. + orr r3, r3, #(0x3 << 12)
  26175. + orr r3, r3, #0x28
  26176. + str r3, [r7, r0]
  26177. + add r11, r11, #8
  26178. + sub r1, r1, #1
  26179. + cmp r1, #0
  26180. + bgt update_iomux
  26181. +
  26182. + /* ODT disabled. */
  26183. + ldr r0, =0x0
  26184. + ldr r2, =MMDC0_MPODTCTRL
  26185. + str r0, [r5, r2]
  26186. + ldr r2, =MMDC1_MPODTCTRL
  26187. + str r0, [r5, r2]
  26188. +
  26189. + /* DQS gating disabled. */
  26190. + ldr r2, =MMDC0_MPDGCTRL0
  26191. + ldr r0, [r5, r2]
  26192. + orr r0, r0, #(1 << 29)
  26193. + str r0, [r5, r2]
  26194. +
  26195. + ldr r2, =MMDC1_MPDGCTRL0
  26196. + ldr r0, [r5, r2]
  26197. + orr r0, r0, #(0x1 << 29)
  26198. + str r0, [r5, r2]
  26199. +
  26200. + /* MMDC0_MAPSR adopt power down enable. */
  26201. + ldr r0, [r5, #MMDC0_MAPSR]
  26202. + bic r0, r0, #0x01
  26203. + str r0, [r5, #MMDC0_MAPSR]
  26204. +
  26205. + /* frc_msr + mu bypass */
  26206. + ldr r0, =0x00000060
  26207. + str r0, [r5, #MMDC0_MPMUR0]
  26208. + ldr r2, =MMDC1_MPMUR0
  26209. + str r0, [r5, r2]
  26210. + ldr r0, =0x00000460
  26211. + str r0, [r5, #MMDC0_MPMUR0]
  26212. + ldr r2, =MMDC1_MPMUR0
  26213. + str r0, [r5, r2]
  26214. + ldr r0, =0x00000c60
  26215. + str r0, [r5, #MMDC0_MPMUR0]
  26216. + ldr r2, =MMDC1_MPMUR0
  26217. + str r0, [r5, r2]
  26218. +
  26219. +continue_dll_off_3:
  26220. + /* clear SBS - unblock accesses to DDR. */
  26221. + ldr r0, [r5, #MMDC0_MADPCR0]
  26222. + bic r0, r0, #(0x1 << 8)
  26223. + str r0, [r5, #MMDC0_MADPCR0]
  26224. +
  26225. + mov r0, #0x0
  26226. + str r0, [r5, #MMDC0_MDSCR]
  26227. +poll_conreq_clear_1:
  26228. + ldr r0, [r5, #MMDC0_MDSCR]
  26229. + and r0, r0, #(0x4 << 12)
  26230. + cmp r0, #(0x4 << 12)
  26231. + beq poll_conreq_clear_1
  26232. +
  26233. + b done
  26234. +
  26235. +dll_on_mode:
  26236. + /* assert DVFS - enter self refresh mode. */
  26237. + ldr r0, [r5, #MMDC0_MAPSR]
  26238. + orr r0, r0, #(1 << 21)
  26239. + str r0, [r5, #MMDC0_MAPSR]
  26240. +
  26241. + /* de-assert CON_REQ. */
  26242. + mov r0, #0x0
  26243. + str r0, [r5, #MMDC0_MDSCR]
  26244. +
  26245. + /* poll DVFS ack. */
  26246. +poll_dvfs_set_2:
  26247. + ldr r0, [r5, #MMDC0_MAPSR]
  26248. + and r0, r0, #(1 << 25)
  26249. + cmp r0, #(1 << 25)
  26250. + bne poll_dvfs_set_2
  26251. +
  26252. + ldr r1, =528000000
  26253. + cmp r4, r1
  26254. + beq switch_freq_528
  26255. +
  26256. + switch_to_400MHz
  26257. +
  26258. + b continue_dll_on
  26259. +
  26260. +switch_freq_528:
  26261. + switch_to_528MHz
  26262. +
  26263. +continue_dll_on:
  26264. +
  26265. + /* set SBS step-by-step mode. */
  26266. + ldr r0, [r5, #MMDC0_MADPCR0]
  26267. + orr r0, r0, #( 1 << 8)
  26268. + str r0, [r5, #MMDC0_MADPCR0]
  26269. +
  26270. + /* clear DVFS - exit self refresh mode. */
  26271. + ldr r0, [r5, #MMDC0_MAPSR]
  26272. + bic r0, r0, #(1 << 21)
  26273. + str r0, [r5, #MMDC0_MAPSR]
  26274. +
  26275. +poll_dvfs_clear_2:
  26276. + ldr r0, [r5, #MMDC0_MAPSR]
  26277. + and r0, r0, #(1 << 25)
  26278. + cmp r0, #(1 << 25)
  26279. + beq poll_dvfs_clear_2
  26280. +
  26281. + /* if DLL is currently off, turn it back on. */
  26282. + cmp r9, #0
  26283. + beq update_calibration_only
  26284. +
  26285. + ldr r0, =0xa5390003
  26286. + str r0, [r5, #MMDC0_MPZQHWCTRL]
  26287. + ldr r2, =MMDC1_MPZQHWCTRL
  26288. + str r0, [r5, r2]
  26289. +
  26290. + /* enable DQS gating. */
  26291. + ldr r2, =MMDC0_MPDGCTRL0
  26292. + ldr r0, [r5, r2]
  26293. + bic r0, r0, #(1 << 29)
  26294. + str r0, [r5, r2]
  26295. +
  26296. + ldr r2, =MMDC1_MPDGCTRL0
  26297. + ldr r0, [r5, r2]
  26298. + bic r0, r0, #(1 << 29)
  26299. + str r0, [r5, r2]
  26300. +
  26301. + /* force measure. */
  26302. + ldr r0, =0x00000800
  26303. + str r0, [r5, #MMDC0_MPMUR0]
  26304. + ldr r2, =MMDC1_MPMUR0
  26305. + str r0, [r5, r2]
  26306. +
  26307. + /* delay for while. */
  26308. + ldr r1, =4
  26309. +delay5:
  26310. + ldr r2, =0
  26311. +cont5:
  26312. + ldr r0, [r5, r2]
  26313. + add r2, r2, #4
  26314. + cmp r2, #16
  26315. + bne cont5
  26316. + sub r1, r1, #1
  26317. + cmp r1, #0
  26318. + bgt delay5
  26319. +
  26320. + /* disable dqs pull down in the IOMUX. */
  26321. + ldr r1, [r11]
  26322. + add r11, r11, #8
  26323. +update_iomux1:
  26324. + ldr r0, [r11, #0x0]
  26325. + ldr r3, [r11, #0x4]
  26326. + str r3, [r7, r0]
  26327. + add r11, r11, #8
  26328. + sub r1, r1, #1
  26329. + cmp r1, #0
  26330. + bgt update_iomux1
  26331. +
  26332. + /* config MMDC timings to 528MHz. */
  26333. + ldr r9, [r8]
  26334. + add r8, r8, #8
  26335. + ldr r0, [r8, #0x0]
  26336. + ldr r3, [r8, #0x4]
  26337. + str r3, [r5, r0]
  26338. + add r8, r8, #8
  26339. +
  26340. + ldr r0, [r8, #0x0]
  26341. + ldr r3, [r8, #0x4]
  26342. + str r3, [r5, r0]
  26343. + add r8, r8, #8
  26344. +
  26345. + /* update MISC register: WALAT, RALAT */
  26346. + ldr r0, =0x00081740
  26347. + str r0, [r5, #MMDC0_MDMISC]
  26348. +
  26349. + /* configure ddr devices to dll on, odt. */
  26350. + ldr r0, =0x00028031
  26351. + str r0, [r5, #MMDC0_MDSCR]
  26352. +
  26353. + ldr r0, =0x00028039
  26354. + str r0, [r5, #MMDC0_MDSCR]
  26355. +
  26356. + /* delay for while. */
  26357. + ldr r1, =4
  26358. +delay7:
  26359. + ldr r2, =0
  26360. +cont7:
  26361. + ldr r0, [r5, r2]
  26362. + add r2, r2, #4
  26363. + cmp r2, #16
  26364. + bne cont7
  26365. + sub r1, r1, #1
  26366. + cmp r1, #0
  26367. + bgt delay7
  26368. +
  26369. + /* reset dll. */
  26370. + ldr r0, =0x09208030
  26371. + str r0, [r5, #MMDC0_MDSCR]
  26372. +
  26373. + ldr r0, =0x09208038
  26374. + str r0, [r5, #MMDC0_MDSCR]
  26375. +
  26376. + /* delay for while. */
  26377. + ldr r1, =100
  26378. +delay8:
  26379. + ldr r2, =0
  26380. +cont8:
  26381. + ldr r0, [r5, r2]
  26382. + add r2, r2, #4
  26383. + cmp r2, #16
  26384. + bne cont8
  26385. + sub r1, r1, #1
  26386. + cmp r1, #0
  26387. + bgt delay8
  26388. +
  26389. + ldr r0, [r8, #0x0]
  26390. + ldr r3, [r8, #0x4]
  26391. + str r3, [r5, r0]
  26392. + add r8, r8, #8
  26393. +
  26394. + ldr r0, [r8, #0x0]
  26395. + ldr r3, [r8, #0x4]
  26396. + str r3, [r5, r0]
  26397. + add r8, r8, #8
  26398. +
  26399. + ldr r0, =0x00428031
  26400. + str r0, [r5, #MMDC0_MDSCR]
  26401. +
  26402. + ldr r0, =0x00428039
  26403. + str r0, [r5, #MMDC0_MDSCR]
  26404. +
  26405. + ldr r0, [r8, #0x0]
  26406. + ldr r3, [r8, #0x4]
  26407. + str r3, [r5, r0]
  26408. + add r8, r8, #8
  26409. +
  26410. + ldr r0, [r8, #0x0]
  26411. + ldr r3, [r8, #0x4]
  26412. + str r3, [r5, r0]
  26413. + add r8, r8, #8
  26414. +
  26415. + /* issue a zq command. */
  26416. + ldr r0, =0x04008040
  26417. + str r0, [r5, #MMDC0_MDSCR]
  26418. +
  26419. + ldr r0, =0x04008048
  26420. + str r0, [r5, #MMDC0_MDSCR]
  26421. +
  26422. + /* MMDC ODT enable. */
  26423. + ldr r0, [r8, #0x0]
  26424. + ldr r3, [r8, #0x4]
  26425. + str r3, [r5, r0]
  26426. + add r8, r8, #8
  26427. +
  26428. + ldr r2, =0x4818
  26429. + str r0, [r5, r2]
  26430. +
  26431. + /* delay for while. */
  26432. + ldr r1, =40
  26433. +delay15:
  26434. + ldr r2, =0
  26435. +cont15:
  26436. + ldr r0, [r5, r2]
  26437. + add r2, r2, #4
  26438. + cmp r2, #16
  26439. + bne cont15
  26440. + sub r1, r1, #1
  26441. + cmp r1, #0
  26442. + bgt delay15
  26443. +
  26444. + /* MMDC0_MAPSR adopt power down enable. */
  26445. + ldr r0, [r5, #MMDC0_MAPSR]
  26446. + bic r0, r0, #0x01
  26447. + str r0, [r5, #MMDC0_MAPSR]
  26448. +
  26449. + /* enable MMDC power down timer. */
  26450. + ldr r0, [r5, #MMDC0_MDPDC]
  26451. + orr r0, r0, #(0x55 << 8)
  26452. + str r0, [r5, #MMDC0_MDPDC]
  26453. +
  26454. + b update_calibration
  26455. +
  26456. +update_calibration_only:
  26457. + ldr r1, [r8]
  26458. + sub r1, r1, #7
  26459. + add r8, r8, #64
  26460. + b update_calib
  26461. +
  26462. +update_calibration:
  26463. + /* write the new calibration values. */
  26464. + mov r1, r9
  26465. + sub r1, r1, #7
  26466. +
  26467. +update_calib:
  26468. + ldr r0, [r8, #0x0]
  26469. + ldr r3, [r8, #0x4]
  26470. + str r3, [r5, r0]
  26471. + add r8, r8, #8
  26472. + sub r1, r1, #1
  26473. + cmp r1, #0
  26474. + bgt update_calib
  26475. +
  26476. + /* perform a force measurement. */
  26477. + ldr r0, =0x800
  26478. + str r0, [r5, #MMDC0_MPMUR0]
  26479. + ldr r2, =MMDC1_MPMUR0
  26480. + str r0, [r5, r2]
  26481. +
  26482. + /* clear SBS - unblock DDR accesses. */
  26483. + ldr r0, [r5, #MMDC0_MADPCR0]
  26484. + bic r0, r0, #(1 << 8)
  26485. + str r0, [r5, #MMDC0_MADPCR0]
  26486. +
  26487. + mov r0, #0x0
  26488. + str r0, [r5, #MMDC0_MDSCR]
  26489. +poll_conreq_clear_2:
  26490. + ldr r0, [r5, #MMDC0_MDSCR]
  26491. + and r0, r0, #(0x4 << 12)
  26492. + cmp r0, #(0x4 << 12)
  26493. + beq poll_conreq_clear_2
  26494. +
  26495. +done:
  26496. + /* restore registers */
  26497. +
  26498. + ldmfd sp!, {r4-r12}
  26499. + mov pc, lr
  26500. +
  26501. + .type mx6_do_ddr3_freq_change, #object
  26502. +ENTRY(mx6_do_ddr_freq_change)
  26503. + .word mx6_ddr3_freq_change
  26504. + .size mx6_ddr3_freq_change, . - mx6_ddr3_freq_change
  26505. diff -Nur linux-3.14.15/arch/arm/mach-imx/gpc.c linux-linaro-stable-mx6/arch/arm/mach-imx/gpc.c
  26506. --- linux-3.14.15/arch/arm/mach-imx/gpc.c 2014-07-31 23:51:43.000000000 +0200
  26507. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/gpc.c 2014-08-20 19:31:40.084843062 +0200
  26508. @@ -10,30 +10,69 @@
  26509. * http://www.gnu.org/copyleft/gpl.html
  26510. */
  26511. +#include <linux/clk.h>
  26512. +#include <linux/delay.h>
  26513. #include <linux/io.h>
  26514. #include <linux/irq.h>
  26515. +#include <linux/module.h>
  26516. #include <linux/of.h>
  26517. #include <linux/of_address.h>
  26518. #include <linux/of_irq.h>
  26519. +#include <linux/platform_device.h>
  26520. #include <linux/irqchip/arm-gic.h>
  26521. +#include <linux/regulator/consumer.h>
  26522. +#include <linux/regulator/driver.h>
  26523. +#include <linux/regulator/machine.h>
  26524. #include "common.h"
  26525. +#include "hardware.h"
  26526. #define GPC_IMR1 0x008
  26527. #define GPC_PGC_CPU_PDN 0x2a0
  26528. +#define GPC_PGC_GPU_PDN 0x260
  26529. +#define GPC_PGC_GPU_PUPSCR 0x264
  26530. +#define GPC_PGC_GPU_PDNSCR 0x268
  26531. +#define GPC_PGC_GPU_SW_SHIFT 0
  26532. +#define GPC_PGC_GPU_SW_MASK 0x3f
  26533. +#define GPC_PGC_GPU_SW2ISO_SHIFT 8
  26534. +#define GPC_PGC_GPU_SW2ISO_MASK 0x3f
  26535. +#define GPC_PGC_CPU_PUPSCR 0x2a4
  26536. +#define GPC_PGC_CPU_PDNSCR 0x2a8
  26537. +#define GPC_PGC_CPU_SW_SHIFT 0
  26538. +#define GPC_PGC_CPU_SW_MASK 0x3f
  26539. +#define GPC_PGC_CPU_SW2ISO_SHIFT 8
  26540. +#define GPC_PGC_CPU_SW2ISO_MASK 0x3f
  26541. +#define GPC_CNTR 0x0
  26542. +#define GPC_CNTR_PU_UP_REQ_SHIFT 0x1
  26543. +#define GPC_CNTR_PU_DOWN_REQ_SHIFT 0x0
  26544. #define IMR_NUM 4
  26545. static void __iomem *gpc_base;
  26546. static u32 gpc_wake_irqs[IMR_NUM];
  26547. static u32 gpc_saved_imrs[IMR_NUM];
  26548. +static struct clk *gpu3d_clk, *gpu3d_shader_clk, *gpu2d_clk, *gpu2d_axi_clk;
  26549. +static struct clk *openvg_axi_clk, *vpu_clk, *ipg_clk;
  26550. +static struct device *gpc_dev;
  26551. +struct regulator *pu_reg;
  26552. +struct notifier_block nb;
  26553. +static struct regulator_dev *pu_dummy_regulator_rdev;
  26554. +static struct regulator_init_data pu_dummy_initdata = {
  26555. + .constraints = {
  26556. + .max_uV = 1450000, /* allign with real max of anatop */
  26557. + .valid_ops_mask = REGULATOR_CHANGE_STATUS |
  26558. + REGULATOR_CHANGE_VOLTAGE,
  26559. + },
  26560. +};
  26561. +static int pu_dummy_enable;
  26562. -void imx_gpc_pre_suspend(void)
  26563. +void imx_gpc_pre_suspend(bool arm_power_off)
  26564. {
  26565. void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
  26566. int i;
  26567. - /* Tell GPC to power off ARM core when suspend */
  26568. - writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
  26569. + if (arm_power_off)
  26570. + /* Tell GPC to power off ARM core when suspend */
  26571. + writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
  26572. for (i = 0; i < IMR_NUM; i++) {
  26573. gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
  26574. @@ -120,10 +159,119 @@
  26575. writel_relaxed(val, reg);
  26576. }
  26577. +static void imx_pu_clk(bool enable)
  26578. +{
  26579. + if (enable) {
  26580. + if (cpu_is_imx6sl()) {
  26581. + clk_prepare_enable(gpu2d_clk);
  26582. + clk_prepare_enable(openvg_axi_clk);
  26583. + } else {
  26584. + clk_prepare_enable(vpu_clk);
  26585. + clk_prepare_enable(gpu3d_clk);
  26586. + clk_prepare_enable(gpu3d_shader_clk);
  26587. + clk_prepare_enable(gpu2d_clk);
  26588. + clk_prepare_enable(gpu2d_axi_clk);
  26589. + clk_prepare_enable(openvg_axi_clk);
  26590. + }
  26591. + } else {
  26592. + if (cpu_is_imx6sl()) {
  26593. + clk_disable_unprepare(gpu2d_clk);
  26594. + clk_disable_unprepare(openvg_axi_clk);
  26595. + } else {
  26596. + clk_disable_unprepare(openvg_axi_clk);
  26597. + clk_disable_unprepare(gpu2d_axi_clk);
  26598. + clk_disable_unprepare(gpu2d_clk);
  26599. + clk_disable_unprepare(gpu3d_shader_clk);
  26600. + clk_disable_unprepare(gpu3d_clk);
  26601. + clk_disable_unprepare(vpu_clk);
  26602. + }
  26603. + }
  26604. +}
  26605. +
  26606. +static void imx_gpc_pu_enable(bool enable)
  26607. +{
  26608. + u32 rate, delay_us;
  26609. + u32 gpu_pupscr_sw2iso, gpu_pdnscr_iso2sw;
  26610. + u32 gpu_pupscr_sw, gpu_pdnscr_iso;
  26611. +
  26612. + /* get ipg clk rate for PGC delay */
  26613. + rate = clk_get_rate(ipg_clk);
  26614. +
  26615. + if (enable) {
  26616. + imx_anatop_pu_enable(true);
  26617. + /*
  26618. + * need to add necessary delay between powering up PU LDO and
  26619. + * disabling PU isolation in PGC, the counter of PU isolation
  26620. + * is based on ipg clk.
  26621. + */
  26622. + gpu_pupscr_sw2iso = (readl_relaxed(gpc_base +
  26623. + GPC_PGC_GPU_PUPSCR) >> GPC_PGC_GPU_SW2ISO_SHIFT)
  26624. + & GPC_PGC_GPU_SW2ISO_MASK;
  26625. + gpu_pupscr_sw = (readl_relaxed(gpc_base +
  26626. + GPC_PGC_GPU_PUPSCR) >> GPC_PGC_GPU_SW_SHIFT)
  26627. + & GPC_PGC_GPU_SW_MASK;
  26628. + delay_us = (gpu_pupscr_sw2iso + gpu_pupscr_sw) * 1000000
  26629. + / rate + 1;
  26630. + udelay(delay_us);
  26631. +
  26632. + imx_pu_clk(true);
  26633. + writel_relaxed(1, gpc_base + GPC_PGC_GPU_PDN);
  26634. + writel_relaxed(1 << GPC_CNTR_PU_UP_REQ_SHIFT,
  26635. + gpc_base + GPC_CNTR);
  26636. + while (readl_relaxed(gpc_base + GPC_CNTR) &
  26637. + (1 << GPC_CNTR_PU_UP_REQ_SHIFT))
  26638. + ;
  26639. + imx_pu_clk(false);
  26640. + } else {
  26641. + writel_relaxed(1, gpc_base + GPC_PGC_GPU_PDN);
  26642. + writel_relaxed(1 << GPC_CNTR_PU_DOWN_REQ_SHIFT,
  26643. + gpc_base + GPC_CNTR);
  26644. + while (readl_relaxed(gpc_base + GPC_CNTR) &
  26645. + (1 << GPC_CNTR_PU_DOWN_REQ_SHIFT))
  26646. + ;
  26647. + /*
  26648. + * need to add necessary delay between enabling PU isolation
  26649. + * in PGC and powering down PU LDO , the counter of PU isolation
  26650. + * is based on ipg clk.
  26651. + */
  26652. + gpu_pdnscr_iso2sw = (readl_relaxed(gpc_base +
  26653. + GPC_PGC_GPU_PDNSCR) >> GPC_PGC_GPU_SW2ISO_SHIFT)
  26654. + & GPC_PGC_GPU_SW2ISO_MASK;
  26655. + gpu_pdnscr_iso = (readl_relaxed(gpc_base +
  26656. + GPC_PGC_GPU_PDNSCR) >> GPC_PGC_GPU_SW_SHIFT)
  26657. + & GPC_PGC_GPU_SW_MASK;
  26658. + delay_us = (gpu_pdnscr_iso2sw + gpu_pdnscr_iso) * 1000000
  26659. + / rate + 1;
  26660. + udelay(delay_us);
  26661. + imx_anatop_pu_enable(false);
  26662. + }
  26663. +}
  26664. +
  26665. +static int imx_gpc_regulator_notify(struct notifier_block *nb,
  26666. + unsigned long event,
  26667. + void *ignored)
  26668. +{
  26669. + switch (event) {
  26670. + case REGULATOR_EVENT_PRE_DISABLE:
  26671. + imx_gpc_pu_enable(false);
  26672. + break;
  26673. + case REGULATOR_EVENT_ENABLE:
  26674. + imx_gpc_pu_enable(true);
  26675. + break;
  26676. + default:
  26677. + break;
  26678. + }
  26679. +
  26680. + return NOTIFY_OK;
  26681. +}
  26682. +
  26683. void __init imx_gpc_init(void)
  26684. {
  26685. struct device_node *np;
  26686. int i;
  26687. + u32 val;
  26688. + u32 cpu_pupscr_sw2iso, cpu_pupscr_sw;
  26689. + u32 cpu_pdnscr_iso2sw, cpu_pdnscr_iso;
  26690. np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
  26691. gpc_base = of_iomap(np, 0);
  26692. @@ -137,4 +285,190 @@
  26693. gic_arch_extn.irq_mask = imx_gpc_irq_mask;
  26694. gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
  26695. gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
  26696. +
  26697. + /*
  26698. + * If there are CPU isolation timing settings in dts,
  26699. + * update them according to dts, otherwise, keep them
  26700. + * with default value in registers.
  26701. + */
  26702. + cpu_pupscr_sw2iso = cpu_pupscr_sw =
  26703. + cpu_pdnscr_iso2sw = cpu_pdnscr_iso = 0;
  26704. +
  26705. + /* Read CPU isolation setting for GPC */
  26706. + of_property_read_u32(np, "fsl,cpu_pupscr_sw2iso", &cpu_pupscr_sw2iso);
  26707. + of_property_read_u32(np, "fsl,cpu_pupscr_sw", &cpu_pupscr_sw);
  26708. + of_property_read_u32(np, "fsl,cpu_pdnscr_iso2sw", &cpu_pdnscr_iso2sw);
  26709. + of_property_read_u32(np, "fsl,cpu_pdnscr_iso", &cpu_pdnscr_iso);
  26710. +
  26711. + /* Update CPU PUPSCR timing if it is defined in dts */
  26712. + val = readl_relaxed(gpc_base + GPC_PGC_CPU_PUPSCR);
  26713. + if (cpu_pupscr_sw2iso)
  26714. + val &= ~(GPC_PGC_CPU_SW2ISO_MASK << GPC_PGC_CPU_SW2ISO_SHIFT);
  26715. + if (cpu_pupscr_sw)
  26716. + val &= ~(GPC_PGC_CPU_SW_MASK << GPC_PGC_CPU_SW_SHIFT);
  26717. + val |= cpu_pupscr_sw2iso << GPC_PGC_CPU_SW2ISO_SHIFT;
  26718. + val |= cpu_pupscr_sw << GPC_PGC_CPU_SW_SHIFT;
  26719. + writel_relaxed(val, gpc_base + GPC_PGC_CPU_PUPSCR);
  26720. +
  26721. + /* Update CPU PDNSCR timing if it is defined in dts */
  26722. + val = readl_relaxed(gpc_base + GPC_PGC_CPU_PDNSCR);
  26723. + if (cpu_pdnscr_iso2sw)
  26724. + val &= ~(GPC_PGC_CPU_SW2ISO_MASK << GPC_PGC_CPU_SW2ISO_SHIFT);
  26725. + if (cpu_pdnscr_iso)
  26726. + val &= ~(GPC_PGC_CPU_SW_MASK << GPC_PGC_CPU_SW_SHIFT);
  26727. + val |= cpu_pdnscr_iso2sw << GPC_PGC_CPU_SW2ISO_SHIFT;
  26728. + val |= cpu_pdnscr_iso << GPC_PGC_CPU_SW_SHIFT;
  26729. + writel_relaxed(val, gpc_base + GPC_PGC_CPU_PDNSCR);
  26730. +}
  26731. +
  26732. +static int imx_pureg_set_voltage(struct regulator_dev *reg, int min_uV,
  26733. + int max_uV, unsigned *selector)
  26734. +{
  26735. + return 0;
  26736. +}
  26737. +
  26738. +static int imx_pureg_enable(struct regulator_dev *rdev)
  26739. +{
  26740. + pu_dummy_enable = 1;
  26741. +
  26742. + return 0;
  26743. +}
  26744. +
  26745. +static int imx_pureg_disable(struct regulator_dev *rdev)
  26746. +{
  26747. + pu_dummy_enable = 0;
  26748. +
  26749. + return 0;
  26750. }
  26751. +
  26752. +static int imx_pureg_is_enable(struct regulator_dev *rdev)
  26753. +{
  26754. + return pu_dummy_enable;
  26755. +}
  26756. +
  26757. +static int imx_pureg_list_voltage(struct regulator_dev *rdev,
  26758. + unsigned int selector)
  26759. +{
  26760. + return 0;
  26761. +}
  26762. +
  26763. +static struct regulator_ops pu_dummy_ops = {
  26764. + .set_voltage = imx_pureg_set_voltage,
  26765. + .enable = imx_pureg_enable,
  26766. + .disable = imx_pureg_disable,
  26767. + .is_enabled = imx_pureg_is_enable,
  26768. + .list_voltage = imx_pureg_list_voltage,
  26769. +};
  26770. +
  26771. +static struct regulator_desc pu_dummy_desc = {
  26772. + .name = "pureg-dummy",
  26773. + .id = -1,
  26774. + .type = REGULATOR_VOLTAGE,
  26775. + .owner = THIS_MODULE,
  26776. + .ops = &pu_dummy_ops,
  26777. +};
  26778. +
  26779. +static int pu_dummy_probe(struct platform_device *pdev)
  26780. +{
  26781. + struct regulator_config config = { };
  26782. + int ret;
  26783. +
  26784. + config.dev = &pdev->dev;
  26785. + config.init_data = &pu_dummy_initdata;
  26786. + config.of_node = pdev->dev.of_node;
  26787. +
  26788. + pu_dummy_regulator_rdev = regulator_register(&pu_dummy_desc, &config);
  26789. + if (IS_ERR(pu_dummy_regulator_rdev)) {
  26790. + ret = PTR_ERR(pu_dummy_regulator_rdev);
  26791. + dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
  26792. + return ret;
  26793. + }
  26794. +
  26795. + return 0;
  26796. +}
  26797. +
  26798. +static const struct of_device_id imx_pudummy_ids[] = {
  26799. + { .compatible = "fsl,imx6-dummy-pureg" },
  26800. +};
  26801. +MODULE_DEVICE_TABLE(of, imx_pudummy_ids);
  26802. +
  26803. +static struct platform_driver pu_dummy_driver = {
  26804. + .probe = pu_dummy_probe,
  26805. + .driver = {
  26806. + .name = "pu-dummy",
  26807. + .owner = THIS_MODULE,
  26808. + .of_match_table = imx_pudummy_ids,
  26809. + },
  26810. +};
  26811. +
  26812. +static int imx_gpc_probe(struct platform_device *pdev)
  26813. +{
  26814. + int ret;
  26815. +
  26816. + gpc_dev = &pdev->dev;
  26817. +
  26818. + pu_reg = devm_regulator_get(gpc_dev, "pu");
  26819. + if (IS_ERR(pu_reg)) {
  26820. + ret = PTR_ERR(pu_reg);
  26821. + dev_info(gpc_dev, "pu regulator not ready.\n");
  26822. + return ret;
  26823. + }
  26824. + nb.notifier_call = &imx_gpc_regulator_notify;
  26825. +
  26826. + /* Get gpu&vpu clk for power up PU by GPC */
  26827. + if (cpu_is_imx6sl()) {
  26828. + gpu2d_clk = devm_clk_get(gpc_dev, "gpu2d_podf");
  26829. + openvg_axi_clk = devm_clk_get(gpc_dev, "gpu2d_ovg");
  26830. + ipg_clk = devm_clk_get(gpc_dev, "ipg");
  26831. + if (IS_ERR(gpu2d_clk) || IS_ERR(openvg_axi_clk)
  26832. + || IS_ERR(ipg_clk)) {
  26833. + dev_err(gpc_dev, "failed to get clk!\n");
  26834. + return -ENOENT;
  26835. + }
  26836. + } else {
  26837. + gpu3d_clk = devm_clk_get(gpc_dev, "gpu3d_core");
  26838. + gpu3d_shader_clk = devm_clk_get(gpc_dev, "gpu3d_shader");
  26839. + gpu2d_clk = devm_clk_get(gpc_dev, "gpu2d_core");
  26840. + gpu2d_axi_clk = devm_clk_get(gpc_dev, "gpu2d_axi");
  26841. + openvg_axi_clk = devm_clk_get(gpc_dev, "openvg_axi");
  26842. + vpu_clk = devm_clk_get(gpc_dev, "vpu_axi");
  26843. + ipg_clk = devm_clk_get(gpc_dev, "ipg");
  26844. + if (IS_ERR(gpu3d_clk) || IS_ERR(gpu3d_shader_clk)
  26845. + || IS_ERR(gpu2d_clk) || IS_ERR(gpu2d_axi_clk)
  26846. + || IS_ERR(openvg_axi_clk) || IS_ERR(vpu_clk)
  26847. + || IS_ERR(ipg_clk)) {
  26848. + dev_err(gpc_dev, "failed to get clk!\n");
  26849. + return -ENOENT;
  26850. + }
  26851. + }
  26852. +
  26853. + ret = regulator_register_notifier(pu_reg, &nb);
  26854. + if (ret) {
  26855. + dev_err(gpc_dev,
  26856. + "regulator notifier request failed\n");
  26857. + return ret;
  26858. + }
  26859. +
  26860. + return 0;
  26861. +}
  26862. +
  26863. +static const struct of_device_id imx_gpc_ids[] = {
  26864. + { .compatible = "fsl,imx6q-gpc" },
  26865. +};
  26866. +MODULE_DEVICE_TABLE(of, imx_gpc_ids);
  26867. +
  26868. +static struct platform_driver imx_gpc_platdrv = {
  26869. + .driver = {
  26870. + .name = "imx-gpc",
  26871. + .owner = THIS_MODULE,
  26872. + .of_match_table = imx_gpc_ids,
  26873. + },
  26874. + .probe = imx_gpc_probe,
  26875. +};
  26876. +module_platform_driver(imx_gpc_platdrv);
  26877. +
  26878. +module_platform_driver(pu_dummy_driver);
  26879. +
  26880. +MODULE_AUTHOR("Anson Huang <b20788@freescale.com>");
  26881. +MODULE_DESCRIPTION("Freescale i.MX GPC driver");
  26882. +MODULE_LICENSE("GPL");
  26883. diff -Nur linux-3.14.15/arch/arm/mach-imx/hardware.h linux-linaro-stable-mx6/arch/arm/mach-imx/hardware.h
  26884. --- linux-3.14.15/arch/arm/mach-imx/hardware.h 2014-07-31 23:51:43.000000000 +0200
  26885. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/hardware.h 2014-08-20 19:31:40.084843062 +0200
  26886. @@ -1,5 +1,5 @@
  26887. /*
  26888. - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
  26889. + * Copyright 2004-2007, 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  26890. * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
  26891. *
  26892. * This program is free software; you can redistribute it and/or
  26893. @@ -20,7 +20,9 @@
  26894. #ifndef __ASM_ARCH_MXC_HARDWARE_H__
  26895. #define __ASM_ARCH_MXC_HARDWARE_H__
  26896. +#ifndef __ASSEMBLY__
  26897. #include <asm/io.h>
  26898. +#endif
  26899. #include <asm/sizes.h>
  26900. #define addr_in_module(addr, mod) \
  26901. diff -Nur linux-3.14.15/arch/arm/mach-imx/headsmp.S linux-linaro-stable-mx6/arch/arm/mach-imx/headsmp.S
  26902. --- linux-3.14.15/arch/arm/mach-imx/headsmp.S 2014-07-31 23:51:43.000000000 +0200
  26903. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/headsmp.S 2014-08-20 19:31:40.084843062 +0200
  26904. @@ -12,8 +12,6 @@
  26905. #include <linux/linkage.h>
  26906. #include <linux/init.h>
  26907. -#include <asm/asm-offsets.h>
  26908. -#include <asm/hardware/cache-l2x0.h>
  26909. .section ".text.head", "ax"
  26910. @@ -35,37 +33,3 @@
  26911. b secondary_startup
  26912. ENDPROC(v7_secondary_startup)
  26913. #endif
  26914. -
  26915. -#ifdef CONFIG_ARM_CPU_SUSPEND
  26916. -/*
  26917. - * The following code must assume it is running from physical address
  26918. - * where absolute virtual addresses to the data section have to be
  26919. - * turned into relative ones.
  26920. - */
  26921. -
  26922. -#ifdef CONFIG_CACHE_L2X0
  26923. - .macro pl310_resume
  26924. - adr r0, l2x0_saved_regs_offset
  26925. - ldr r2, [r0]
  26926. - add r2, r2, r0
  26927. - ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0
  26928. - ldr r1, [r2, #L2X0_R_AUX_CTRL] @ get aux_ctrl value
  26929. - str r1, [r0, #L2X0_AUX_CTRL] @ restore aux_ctrl
  26930. - mov r1, #0x1
  26931. - str r1, [r0, #L2X0_CTRL] @ re-enable L2
  26932. - .endm
  26933. -
  26934. -l2x0_saved_regs_offset:
  26935. - .word l2x0_saved_regs - .
  26936. -
  26937. -#else
  26938. - .macro pl310_resume
  26939. - .endm
  26940. -#endif
  26941. -
  26942. -ENTRY(v7_cpu_resume)
  26943. - bl v7_invalidate_l1
  26944. - pl310_resume
  26945. - b cpu_resume
  26946. -ENDPROC(v7_cpu_resume)
  26947. -#endif
  26948. diff -Nur linux-3.14.15/arch/arm/mach-imx/imx6sl_wfi.S linux-linaro-stable-mx6/arch/arm/mach-imx/imx6sl_wfi.S
  26949. --- linux-3.14.15/arch/arm/mach-imx/imx6sl_wfi.S 1970-01-01 01:00:00.000000000 +0100
  26950. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/imx6sl_wfi.S 2014-08-20 19:23:45.806812745 +0200
  26951. @@ -0,0 +1,639 @@
  26952. +/*
  26953. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  26954. + *
  26955. + * This program is free software; you can redistribute it and/or modify
  26956. + * it under the terms of the GNU General Public License as published by
  26957. + * the Free Software Foundation; either version 2 of the License, or
  26958. + * (at your option) any later version.
  26959. +
  26960. + * This program is distributed in the hope that it will be useful,
  26961. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26962. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26963. + * GNU General Public License for more details.
  26964. +
  26965. + * You should have received a copy of the GNU General Public License along
  26966. + * with this program; if not, write to the Free Software Foundation, Inc.,
  26967. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  26968. + */
  26969. +
  26970. +#include <linux/linkage.h>
  26971. +#define IRAM_WAIT_SIZE (1 << 11)
  26972. +
  26973. + .macro sl_ddr_io_save
  26974. +
  26975. + ldr r4, [r1, #0x30c] /* DRAM_DQM0 */
  26976. + ldr r5, [r1, #0x310] /* DRAM_DQM1 */
  26977. + ldr r6, [r1, #0x314] /* DRAM_DQM2 */
  26978. + ldr r7, [r1, #0x318] /* DRAM_DQM3 */
  26979. + stmfd r9!, {r4-r7}
  26980. +
  26981. + ldr r4, [r1, #0x5c4] /* GPR_B0DS */
  26982. + ldr r5, [r1, #0x5cc] /* GPR_B1DS */
  26983. + ldr r6, [r1, #0x5d4] /* GPR_B2DS */
  26984. + ldr r7, [r1, #0x5d8] /* GPR_B3DS */
  26985. + stmfd r9!, {r4-r7}
  26986. +
  26987. + ldr r4, [r1, #0x300] /* DRAM_CAS */
  26988. + ldr r5, [r1, #0x31c] /* DRAM_RAS */
  26989. + ldr r6, [r1, #0x338] /* DRAM_SDCLK_0 */
  26990. + ldr r7, [r1, #0x5ac] /* GPR_ADDS*/
  26991. + stmfd r9!, {r4-r7}
  26992. +
  26993. + ldr r4, [r1, #0x5b0] /* DDRMODE_CTL */
  26994. + ldr r5, [r1, #0x5c0] /* DDRMODE */
  26995. + ldr r6, [r1, #0x33c] /* DRAM_SODT0*/
  26996. + ldr r7, [r1, #0x340] /* DRAM_SODT1*/
  26997. + stmfd r9!, {r4-r7}
  26998. +
  26999. + ldr r4, [r1, #0x330] /* DRAM_SDCKE0 */
  27000. + ldr r5, [r1, #0x334] /* DRAM_SDCKE1 */
  27001. + ldr r6, [r1, #0x320] /* DRAM_RESET */
  27002. + stmfd r9!, {r4-r6}
  27003. +
  27004. + .endm
  27005. +
  27006. + .macro sl_ddr_io_restore
  27007. +
  27008. + /*
  27009. + * r9 points to IRAM stack.
  27010. + * r1 points to IOMUX base address.
  27011. + * r8 points to MMDC base address.
  27012. + */
  27013. + ldmea r9!, {r4-r7}
  27014. + str r4, [r1, #0x30c] /* DRAM_DQM0 */
  27015. + str r5, [r1, #0x310] /* DRAM_DQM1 */
  27016. + str r6, [r1, #0x314] /* DRAM_DQM2 */
  27017. + str r7, [r1, #0x318] /* DRAM_DQM3 */
  27018. +
  27019. + ldmea r9!, {r4-r7}
  27020. + str r4, [r1, #0x5c4] /* GPR_B0DS */
  27021. + str r5, [r1, #0x5cc] /* GPR_B1DS */
  27022. + str r6, [r1, #0x5d4] /* GPR_B2DS */
  27023. + str r7, [r1, #0x5d8] /* GPR_B3DS */
  27024. +
  27025. + ldmea r9!, {r4-r7}
  27026. + str r4, [r1, #0x300] /* DRAM_CAS */
  27027. + str r5, [r1, #0x31c] /* DRAM_RAS */
  27028. + str r6, [r1, #0x338] /* DRAM_SDCLK_0 */
  27029. + str r7, [r1, #0x5ac] /* GPR_ADDS*/
  27030. +
  27031. + ldmea r9!, {r4-r7}
  27032. + str r4, [r1, #0x5b0] /* DDRMODE_CTL */
  27033. + str r5, [r1, #0x5c0] /* DDRMODE */
  27034. + str r6, [r1, #0x33c] /* DRAM_SODT0*/
  27035. + str r7, [r1, #0x340] /* DRAM_SODT1*/
  27036. +
  27037. + ldmea r9!, {r4-r6}
  27038. + str r4, [r1, #0x330] /* DRAM_SDCKE0 */
  27039. + str r5, [r1, #0x334] /* DRAM_SDCKE1 */
  27040. + str r6, [r1, #0x320] /* DRAM_RESET */
  27041. +
  27042. + /*
  27043. + * Need to reset the FIFO to avoid MMDC lockup
  27044. + * caused because of floating/changing the
  27045. + * configuration of many DDR IO pads.
  27046. + */
  27047. + ldr r7, =0x83c
  27048. + ldr r6, [r8, r7]
  27049. + orr r6, r6, #0x80000000
  27050. + str r6, [r8, r7]
  27051. +fifo_reset1_wait:
  27052. + ldr r6, [r8, r7]
  27053. + and r6, r6, #0x80000000
  27054. + cmp r6, #0
  27055. + bne fifo_reset1_wait
  27056. +
  27057. + /* reset FIFO a second time */
  27058. + ldr r6, [r8, r7]
  27059. + orr r6, r6, #0x80000000
  27060. + str r6, [r8, r7]
  27061. +fifo_reset2_wait:
  27062. + ldr r6, [r8, r7]
  27063. + and r6, r6, #0x80000000
  27064. + cmp r6, #0
  27065. + bne fifo_reset2_wait
  27066. +
  27067. + .endm
  27068. +
  27069. + .macro sl_ddr_io_set_lpm
  27070. +
  27071. + mov r4, #0
  27072. + str r4, [r1, #0x30c] /* DRAM_DQM0 */
  27073. + str r4, [r1, #0x310] /* DRAM_DQM1 */
  27074. + str r4, [r1, #0x314] /* DRAM_DQM2 */
  27075. + str r4, [r1, #0x318] /* DRAM_DQM3 */
  27076. +
  27077. + str r4, [r1, #0x5c4] /* GPR_B0DS */
  27078. + str r4, [r1, #0x5cc] /* GPR_B1DS */
  27079. + str r4, [r1, #0x5d4] /* GPR_B2DS */
  27080. + str r4, [r1, #0x5d8] /* GPR_B3DS */
  27081. +
  27082. + str r4, [r1, #0x300] /* DRAM_CAS */
  27083. + str r4, [r1, #0x31c] /* DRAM_RAS */
  27084. + str r4, [r1, #0x338] /* DRAM_SDCLK_0 */
  27085. + str r4, [r1, #0x5ac] /* GPR_ADDS*/
  27086. +
  27087. + str r4, [r1, #0x5b0] /* DDRMODE_CTL */
  27088. + str r4, [r1, #0x5c0] /* DDRMODE */
  27089. + str r4, [r1, #0x33c] /* DRAM_SODT0*/
  27090. + str r4, [r1, #0x340] /* DRAM_SODT1*/
  27091. +
  27092. + mov r4, #0x80000
  27093. + str r4, [r1, #0x320] /* DRAM_RESET */
  27094. + mov r4, #0x1000
  27095. + str r4, [r1, #0x330] /* DRAM_SDCKE0 */
  27096. + str r4, [r1, #0x334] /* DRAM_SDCKE1 */
  27097. +
  27098. + .endm
  27099. +
  27100. +/*
  27101. + * imx6sl_low_power_wfi
  27102. + *
  27103. + * Idle the processor (eg, wait for interrupt).
  27104. + * Make sure DDR is in self-refresh.
  27105. + * IRQs are already disabled.
  27106. + * r0: WFI IRAMcode base address.
  27107. + * r1: IOMUX base address
  27108. + * r2: Base address of CCM, ANATOP and MMDC
  27109. + * r3: 1 if in audio_bus_freq_mode
  27110. + */
  27111. + .align 3
  27112. +ENTRY(imx6sl_low_power_wfi)
  27113. +
  27114. + push {r4-r11}
  27115. +
  27116. +mx6sl_lpm_wfi:
  27117. + /* Store audio_bus_freq_mode */
  27118. + mov r11, r3
  27119. +
  27120. + mov r4,r2
  27121. + /* Get the IRAM data storage address. */
  27122. + mov r10, r0
  27123. + mov r9, r0 /* get suspend_iram_base */
  27124. + add r9, r9, #IRAM_WAIT_SIZE
  27125. +
  27126. + /* Anatop Base address in r3. */
  27127. + ldr r3, [r4]
  27128. + /* CCM Base Address in r2 */
  27129. + ldr r2, [r4, #0x4]
  27130. + /* MMDC Base Address in r8 */
  27131. + ldr r8, [r4, #0x8]
  27132. + /* L2 Base Address in r7 */
  27133. + ldr r7, [r4, #0xC]
  27134. +
  27135. + ldr r6, [r8]
  27136. + ldr r6, [r3]
  27137. + ldr r6, [r2]
  27138. + ldr r6, [r1]
  27139. +
  27140. + /* Store the original ARM PODF. */
  27141. + ldr r0, [r2, #0x10]
  27142. +
  27143. + /* Drain all the L1 buffers. */
  27144. + dsb
  27145. +
  27146. +#ifdef CONFIG_CACHE_L2X0
  27147. + /*
  27148. + * Need to make sure the buffers in L2 are drained.
  27149. + * Performing a sync operation does this.
  27150. + */
  27151. + mov r6, #0x0
  27152. + str r6, [r7, #0x730]
  27153. +#endif
  27154. +
  27155. + /*
  27156. + * The second dsb might be needed to keep cache sync (device write)
  27157. + * ordering with the memory accesses before it.
  27158. + */
  27159. + dsb
  27160. + isb
  27161. +
  27162. + /* Save the DDR IO state. */
  27163. + sl_ddr_io_save
  27164. +
  27165. + /* Disable Automatic power savings. */
  27166. + ldr r6, [r8, #0x404]
  27167. + orr r6, r6, #0x01
  27168. + str r6, [r8, #0x404]
  27169. +
  27170. + /* Make the DDR explicitly enter self-refresh. */
  27171. + ldr r6, [r8, #0x404]
  27172. + orr r6, r6, #0x200000
  27173. + str r6, [r8, #0x404]
  27174. +
  27175. +poll_dvfs_set_1:
  27176. + ldr r6, [r8, #0x404]
  27177. + and r6, r6, #0x2000000
  27178. + cmp r6, #0x2000000
  27179. + bne poll_dvfs_set_1
  27180. +
  27181. + /* set SBS step-by-step mode */
  27182. + ldr r6, [r8, #0x410]
  27183. + orr r6, r6, #0x100
  27184. + str r6, [r8, #0x410]
  27185. +
  27186. + cmp r11, #1
  27187. + beq audio_mode
  27188. + /*
  27189. + * Now set DDR rate to 1MHz.
  27190. + * DDR is from bypassed PLL2 on periph2_clk2 path.
  27191. + * Set the periph2_clk2_podf to divide by 8.
  27192. + */
  27193. + ldr r6, [r2, #0x14]
  27194. + orr r6, r6, #0x07
  27195. + str r6, [r2, #0x14]
  27196. +
  27197. + /* Now set MMDC PODF to divide by 3. */
  27198. + ldr r6, [r2, #0x14]
  27199. + bic r6, r6, #0x38
  27200. + orr r6, r6, #0x10
  27201. + str r6, [r2, #0x14]
  27202. + b mmdc_podf
  27203. +
  27204. +audio_mode:
  27205. + /* MMDC is from PLL2_200M.
  27206. + * Set the mmdc_podf to div by 8.
  27207. + */
  27208. + ldr r6, [r2, #0x14]
  27209. + orr r6, r6, #0x38
  27210. + str r6, [r2, #0x14]
  27211. +
  27212. + /* Loop till podf is accepted. */
  27213. +mmdc_podf:
  27214. + ldr r6, [r2, #0x48]
  27215. + cmp r6, #0x0
  27216. + bne mmdc_podf
  27217. +
  27218. + /* Set the DDR IO in LPM state. */
  27219. + sl_ddr_io_set_lpm
  27220. +
  27221. + cmp r11, #1
  27222. + beq do_audio_arm_clk
  27223. +
  27224. + /*
  27225. + * Check if none of the PLLs are
  27226. + * locked, except PLL1 which will get
  27227. + * bypassed below.
  27228. + * We should not be here if PLL2 is not
  27229. + * bypassed.
  27230. + */
  27231. + ldr r7, =1
  27232. + /* USB1 PLL3 */
  27233. + ldr r6, [r3, #0x10]
  27234. + and r6, r6, #0x80000000
  27235. + cmp r6, #0x80000000
  27236. + beq no_analog_saving
  27237. +
  27238. + /* USB2 PLL7 */
  27239. + ldr r6, [r3, #0x20]
  27240. + and r6, r6, #0x80000000
  27241. + cmp r6, #0x80000000
  27242. + beq no_analog_saving
  27243. +
  27244. + /* Audio PLL4 */
  27245. + ldr r6, [r3, #0x70]
  27246. + and r6, r6, #0x80000000
  27247. + cmp r6, #0x80000000
  27248. + beq no_analog_saving
  27249. +
  27250. + /* Video PLL5 */
  27251. + ldr r6, [r3, #0xA0]
  27252. + and r6, r6, #0x80000000
  27253. + cmp r6, #0x80000000
  27254. + beq no_analog_saving
  27255. +
  27256. + /* ENET PLL8 */
  27257. + ldr r6, [r3, #0xE0]
  27258. + and r6, r6, #0x80000000
  27259. + cmp r6, #0x80000000
  27260. + beq no_analog_saving
  27261. +
  27262. + b cont
  27263. +
  27264. +no_analog_saving:
  27265. + ldr r7, =0
  27266. +
  27267. +cont:
  27268. + /* Set the AHB to 3MHz. AXI to 3MHz. */
  27269. + ldr r9, [r2, #0x14]
  27270. + mov r6, r9
  27271. + orr r6, r6, #0x1c00
  27272. + orr r6, r6, #0x70000
  27273. + str r6, [r2, #0x14]
  27274. +
  27275. + /* Loop till podf is accepted. */
  27276. +ahb_podf:
  27277. + ldr r6, [r2, #0x48]
  27278. + cmp r6, #0x0
  27279. + bne podf_loop
  27280. +
  27281. + /*
  27282. + * Now set ARM to 24MHz.
  27283. + * Move ARM to be sourced from STEP_CLK
  27284. + * after setting STEP_CLK to 24MHz.
  27285. + */
  27286. + ldr r6, [r2, #0xc]
  27287. + bic r6, r6, #0x100
  27288. + str r6, [r2, #0x0c]
  27289. + /* Now PLL1_SW_CLK to step_clk. */
  27290. + ldr r6, [r2, #0x0c]
  27291. + orr r6, r6, #0x4
  27292. + str r6, [r2, #0x0c]
  27293. +
  27294. + /* Bypass PLL1 and power it down. */
  27295. + ldr r6, =(1 << 16)
  27296. + orr r6, r6, #0x1000
  27297. + str r6, [r3, #0x04]
  27298. +
  27299. + /*
  27300. + * Set the ARM PODF to divide by 8.
  27301. + * IPG is at 1.5MHz here, we need ARM to
  27302. + * run at the 12:5 ratio (WAIT mode issue).
  27303. + */
  27304. + ldr r6, =0x7
  27305. + str r6, [r2, #0x10]
  27306. +
  27307. + /* Loop till podf is accepted. */
  27308. +podf_loop:
  27309. + ldr r6, [r2, #0x48]
  27310. + cmp r6, #0x0
  27311. + bne podf_loop
  27312. +
  27313. + /*
  27314. + * Check if we can save some
  27315. + * power in the Analog section.
  27316. + */
  27317. + cmp r7, #0x1
  27318. + bne do_wfi
  27319. +
  27320. + /* Disable 1p1 brown out. */
  27321. + ldr r6, [r3, #0x110]
  27322. + bic r6, r6, #0x2
  27323. + str r6, [r3, #0x110]
  27324. +
  27325. + /* Enable the weak 2P5 */
  27326. + ldr r6, [r3, #0x130]
  27327. + orr r6, r6, #0x40000
  27328. + str r6, [r3, #0x130]
  27329. +
  27330. + /* Disable main 2p5. */
  27331. + ldr r6, [r3, #0x130]
  27332. + bic r6, r6, #0x1
  27333. + str r6, [r3, #0x130]
  27334. +
  27335. + /*
  27336. + * Set the OSC bias current to -37.5%
  27337. + * to drop the power on VDDHIGH.
  27338. + */
  27339. + ldr r6, [r3, #0x150]
  27340. + orr r6, r6, #0xC000
  27341. + str r6, [r3, #0x150]
  27342. +
  27343. + /* Enable low power bandgap */
  27344. + ldr r6, [r3, #0x260]
  27345. + orr r6, r6, #0x20
  27346. + str r6, [r3, #0x260]
  27347. +
  27348. + /*
  27349. + * Turn off the bias current
  27350. + * from the regular bandgap.
  27351. + */
  27352. + ldr r6, [r3, #0x260]
  27353. + orr r6, r6, #0x80
  27354. + str r6, [r3, #0x260]
  27355. +
  27356. + /*
  27357. + * Clear the REFTOP_SELFBIASOFF,
  27358. + * self-bias circuit of the band gap.
  27359. + * Per RM, should be cleared when
  27360. + * band gap is powered down.
  27361. + */
  27362. + ldr r6, [r3, #0x150]
  27363. + bic r6, r6, #0x8
  27364. + str r6, [r3, #0x150]
  27365. +
  27366. + /* Power down the regular bandgap. */
  27367. + ldr r6, [r3, #0x150]
  27368. + orr r6, r6, #0x1
  27369. + str r6, [r3, #0x150]
  27370. +
  27371. + b do_wfi
  27372. +
  27373. +do_audio_arm_clk:
  27374. + /*
  27375. + * ARM is from PLL2_PFD2_400M here.
  27376. + * Switch ARM to bypassed PLL1.
  27377. + */
  27378. + ldr r6, [r2, #0xC]
  27379. + bic r6, r6, #0x4
  27380. + str r6, [r2, #0xC]
  27381. +
  27382. + /*
  27383. + * Set the ARM_PODF to divide by 2
  27384. + * as IPG is at 4MHz, we cannot run
  27385. + * ARM_CLK above 9.6MHz when
  27386. + * system enters WAIT mode.
  27387. + */
  27388. + ldr r6, =0x2
  27389. + str r6, [r2, #0x10]
  27390. +
  27391. + /* Loop till podf is accepted. */
  27392. +podf_loop_audio:
  27393. + ldr r6, [r2, #0x48]
  27394. + cmp r6, #0x0
  27395. + bne podf_loop_audio
  27396. +
  27397. +do_wfi:
  27398. + /* Now do WFI. */
  27399. + wfi
  27400. +
  27401. + /* Set original ARM PODF back. */
  27402. + str r0, [r2, #0x10]
  27403. +
  27404. + /* Loop till podf is accepted. */
  27405. +podf_loop1:
  27406. + ldr r6, [r2, #0x48]
  27407. + cmp r6, #0x0
  27408. + bne podf_loop1
  27409. +
  27410. + cmp r11, #1
  27411. + beq audio_arm_clk_restore
  27412. +
  27413. + /*
  27414. + * Check if powered down
  27415. + * analog components.
  27416. + */
  27417. + cmp r7, #0x1
  27418. + bne skip_analog_restore
  27419. +
  27420. + /* Power up the regular bandgap. */
  27421. + ldr r6, [r3, #0x150]
  27422. + bic r6, r6, #0x1
  27423. + str r6, [r3, #0x150]
  27424. +
  27425. + /*
  27426. + * Turn on the bias current
  27427. + * from the regular bandgap.
  27428. + */
  27429. + ldr r6, [r3, #0x260]
  27430. + bic r6, r6, #0x80
  27431. + str r6, [r3, #0x260]
  27432. +
  27433. + /* Disable the low power bandgap */
  27434. + ldr r6, [r3, #0x260]
  27435. + bic r6, r6, #0x20
  27436. + str r6, [r3, #0x260]
  27437. +
  27438. + /*
  27439. + * Set the OSC bias current to max
  27440. + * value for normal operation.
  27441. + */
  27442. + ldr r6, [r3, #0x150]
  27443. + bic r6, r6, #0xC000
  27444. + str r6, [r3, #0x150]
  27445. +
  27446. + /* Enable main 2p5. */
  27447. + ldr r6, [r3, #0x130]
  27448. + orr r6, r6, #0x1
  27449. + str r6, [r3, #0x130]
  27450. +
  27451. + /* Ensure the 2P5 is up. */
  27452. +loop_2p5:
  27453. + ldr r6, [r3, #0x130]
  27454. + and r6, r6, #0x20000
  27455. + cmp r6, #0x20000
  27456. + bne loop_2p5
  27457. +
  27458. + /* Disable the weak 2P5 */
  27459. + ldr r6, [r3, #0x130]
  27460. + bic r6, r6, #0x40000
  27461. + str r6, [r3, #0x130]
  27462. +
  27463. + /* Enable 1p1 brown out. */
  27464. + ldr r6, [r3, #0x110]
  27465. + orr r6, r6, #0x2
  27466. + str r6, [r3, #0x110]
  27467. +
  27468. +skip_analog_restore:
  27469. +
  27470. + /* Power up PLL1 and un-bypass it. */
  27471. + ldr r6, =(1 << 12)
  27472. + str r6, [r3, #0x08]
  27473. +
  27474. + /* Wait for PLL1 to relock. */
  27475. +wait_for_pll_lock:
  27476. + ldr r6, [r3, #0x0]
  27477. + and r6, r6, #0x80000000
  27478. + cmp r6, #0x80000000
  27479. + bne wait_for_pll_lock
  27480. +
  27481. + ldr r6, =(1 << 16)
  27482. + str r6, [r3, #0x08]
  27483. +
  27484. + /* Set PLL1_sw_clk back to PLL1. */
  27485. + ldr r6, [r2, #0x0c]
  27486. + bic r6, r6, #0x4
  27487. + str r6, [r2, #0xc]
  27488. +
  27489. + /* Restore AHB/AXI back. */
  27490. + str r9, [r2, #0x14]
  27491. +
  27492. + /* Loop till podf is accepted. */
  27493. +ahb_podf1:
  27494. + ldr r6, [r2, #0x48]
  27495. + cmp r6, #0x0
  27496. + bne podf_loop1
  27497. +
  27498. + b wfi_restore
  27499. +
  27500. + audio_arm_clk_restore:
  27501. + /* Move ARM back to PLL2_PFD2_400M */
  27502. + ldr r6, [r2, #0xC]
  27503. + orr r6, r6, #0x4
  27504. + str r6, [r2, #0xC]
  27505. +
  27506. +wfi_restore:
  27507. + /* get suspend_iram_base */
  27508. + mov r9, r10
  27509. + add r9, r9, #IRAM_WAIT_SIZE
  27510. +
  27511. + /* Restore the DDR IO before exiting self-refresh. */
  27512. + sl_ddr_io_restore
  27513. +
  27514. + /*
  27515. + * Set MMDC back to 24MHz.
  27516. + * Set periph2_clk2_podf to divide by 1
  27517. + * Now set MMDC PODF to divide by 1.
  27518. + */
  27519. + ldr r6, [r2, #0x14]
  27520. + bic r6, r6, #0x3f
  27521. + str r6, [r2, #0x14]
  27522. +
  27523. +mmdc_podf1:
  27524. + ldr r6, [r2, #0x48]
  27525. + cmp r6, #0x0
  27526. + bne mmdc_podf1
  27527. +
  27528. + /* clear DVFS - exit from self refresh mode */
  27529. + ldr r6, [r8, #0x404]
  27530. + bic r6, r6, #0x200000
  27531. + str r6, [r8, #0x404]
  27532. +
  27533. +poll_dvfs_clear_1:
  27534. + ldr r6, [r8, #0x404]
  27535. + and r6, r6, #0x2000000
  27536. + cmp r6, #0x2000000
  27537. + beq poll_dvfs_clear_1
  27538. +
  27539. + /*
  27540. + * Add these nops so that the
  27541. + * prefetcher will not try to get
  27542. + * any instructions from DDR.
  27543. + * The prefetch depth is about 23
  27544. + * on A9, so adding 25 nops.
  27545. + */
  27546. + nop
  27547. + nop
  27548. + nop
  27549. + nop
  27550. + nop
  27551. +
  27552. + nop
  27553. + nop
  27554. + nop
  27555. + nop
  27556. + nop
  27557. +
  27558. + nop
  27559. + nop
  27560. + nop
  27561. + nop
  27562. + nop
  27563. +
  27564. + nop
  27565. + nop
  27566. + nop
  27567. + nop
  27568. + nop
  27569. +
  27570. + nop
  27571. + nop
  27572. + nop
  27573. + nop
  27574. + nop
  27575. +
  27576. + /* Enable Automatic power savings. */
  27577. + ldr r6, [r8, #0x404]
  27578. + bic r6, r6, #0x01
  27579. + str r6, [r8, #0x404]
  27580. +
  27581. + /* clear SBS - unblock DDR accesses */
  27582. + ldr r6, [r8, #0x410]
  27583. + bic r6, r6, #0x100
  27584. + str r6, [r8, #0x410]
  27585. +
  27586. +
  27587. + pop {r4-r11}
  27588. +
  27589. + /* Restore registers */
  27590. + mov pc, lr
  27591. diff -Nur linux-3.14.15/arch/arm/mach-imx/Kconfig linux-linaro-stable-mx6/arch/arm/mach-imx/Kconfig
  27592. --- linux-3.14.15/arch/arm/mach-imx/Kconfig 2014-07-31 23:51:43.000000000 +0200
  27593. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/Kconfig 2014-08-20 19:31:40.080843045 +0200
  27594. @@ -1,5 +1,6 @@
  27595. config ARCH_MXC
  27596. bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
  27597. + select ARCH_HAS_RESET_CONTROLLER
  27598. select ARCH_REQUIRE_GPIOLIB
  27599. select ARM_CPU_SUSPEND if PM
  27600. select ARM_PATCH_PHYS_VIRT
  27601. @@ -13,6 +14,7 @@
  27602. select PINCTRL
  27603. select SOC_BUS
  27604. select SPARSE_IRQ
  27605. + select SRAM
  27606. select USE_OF
  27607. help
  27608. Support for Freescale MXC/iMX-based family of processors
  27609. @@ -63,7 +65,6 @@
  27610. config HAVE_IMX_SRC
  27611. def_bool y if SMP
  27612. - select ARCH_HAS_RESET_CONTROLLER
  27613. config IMX_HAVE_IOMUX_V1
  27614. bool
  27615. @@ -791,6 +792,8 @@
  27616. select ARM_ERRATA_754322
  27617. select ARM_ERRATA_764369 if SMP
  27618. select ARM_ERRATA_775420
  27619. + select ARM_ERRATA_794072 if SMP
  27620. + select ARM_ERRATA_761320 if SMP
  27621. select ARM_GIC
  27622. select CPU_V7
  27623. select HAVE_ARM_SCU if SMP
  27624. @@ -803,11 +806,13 @@
  27625. select MFD_SYSCON
  27626. select MIGHT_HAVE_PCI
  27627. select PCI_DOMAINS if PCI
  27628. + select ARCH_SUPPORTS_MSI
  27629. select PINCTRL_IMX6Q
  27630. select PL310_ERRATA_588369 if CACHE_PL310
  27631. select PL310_ERRATA_727915 if CACHE_PL310
  27632. select PL310_ERRATA_769419 if CACHE_PL310
  27633. select PM_OPP if PM
  27634. + select ZONE_DMA
  27635. help
  27636. This enables support for Freescale i.MX6 Quad processor.
  27637. diff -Nur linux-3.14.15/arch/arm/mach-imx/lpddr2_freq_imx6.S linux-linaro-stable-mx6/arch/arm/mach-imx/lpddr2_freq_imx6.S
  27638. --- linux-3.14.15/arch/arm/mach-imx/lpddr2_freq_imx6.S 1970-01-01 01:00:00.000000000 +0100
  27639. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/lpddr2_freq_imx6.S 2014-08-20 19:23:45.806812745 +0200
  27640. @@ -0,0 +1,484 @@
  27641. +/*
  27642. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  27643. + *
  27644. + * This program is free software; you can redistribute it and/or modify
  27645. + * it under the terms of the GNU General Public License as published by
  27646. + * the Free Software Foundation; either version 2 of the License, or
  27647. + * (at your option) any later version.
  27648. +
  27649. + * This program is distributed in the hope that it will be useful,
  27650. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27651. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27652. + * GNU General Public License for more details.
  27653. +
  27654. + * You should have received a copy of the GNU General Public License along
  27655. + * with this program; if not, write to the Free Software Foundation, Inc.,
  27656. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  27657. + */
  27658. +
  27659. +#include <linux/linkage.h>
  27660. +
  27661. + .macro mx6sl_switch_to_24MHz
  27662. +
  27663. + /*
  27664. + * Set MMDC clock to be sourced from PLL3.
  27665. + * Ensure first periph2_clk2 is sourced from PLL3.
  27666. + * Set the PERIPH2_CLK2_PODF to divide by 2.
  27667. + */
  27668. + ldr r6, [r2, #0x14]
  27669. + bic r6, r6, #0x7
  27670. + orr r6, r6, #0x1
  27671. + str r6, [r2, #0x14]
  27672. +
  27673. + /* Select PLL3 to source MMDC. */
  27674. + ldr r6, [r2, #0x18]
  27675. + bic r6, r6, #0x100000
  27676. + str r6, [r2, #0x18]
  27677. +
  27678. + /* Swtich periph2_clk_sel to run from PLL3. */
  27679. + ldr r6, [r2, #0x14]
  27680. + orr r6, r6, #0x4000000
  27681. + str r6, [r2, #0x14]
  27682. +
  27683. +periph2_clk_switch1:
  27684. + ldr r6, [r2, #0x48]
  27685. + cmp r6, #0
  27686. + bne periph2_clk_switch1
  27687. +
  27688. + /*
  27689. + * Need to clock gate the 528 PFDs before
  27690. + * powering down PLL2.
  27691. + * Only the PLL2_PFD2_400M should be ON
  27692. + * at this time, so only clock gate that one.
  27693. + */
  27694. + ldr r6, [r3, #0x100]
  27695. + orr r6, r6, #0x800000
  27696. + str r6, [r3, #0x100]
  27697. +
  27698. + /*
  27699. + * Set PLL2 to bypass state. We should be here
  27700. + * only if MMDC is not sourced from PLL2.
  27701. + */
  27702. + ldr r6, [r3, #0x30]
  27703. + orr r6, r6, #0x10000
  27704. + str r6, [r3, #0x30]
  27705. +
  27706. + ldr r6, [r3, #0x30]
  27707. + orr r6, r6, #0x1000
  27708. + str r6, [r3, #0x30]
  27709. +
  27710. + /* Ensure pre_periph2_clk_mux is set to pll2 */
  27711. + ldr r6, [r2, #0x18]
  27712. + bic r6, r6, #0x600000
  27713. + str r6, [r2, #0x18]
  27714. +
  27715. + /* Set MMDC clock to be sourced from the bypassed PLL2. */
  27716. + ldr r6, [r2, #0x14]
  27717. + bic r6, r6, #0x4000000
  27718. + str r6, [r2, #0x14]
  27719. +
  27720. +periph2_clk_switch2:
  27721. + ldr r6, [r2, #0x48]
  27722. + cmp r6, #0
  27723. + bne periph2_clk_switch2
  27724. +
  27725. + /*
  27726. + * Now move MMDC back to periph2_clk2 source.
  27727. + * after selecting PLL2 as the option.
  27728. + * Select PLL2 as the source.
  27729. + */
  27730. + ldr r6, [r2, #0x18]
  27731. + orr r6, r6, #0x100000
  27732. + str r6, [r2, #0x18]
  27733. +
  27734. + /* set periph2_clk2_podf to divide by 1. */
  27735. + ldr r6, [r2, #0x14]
  27736. + bic r6, r6, #0x7
  27737. + str r6, [r2, #0x14]
  27738. +
  27739. + /* Now move periph2_clk to periph2_clk2 source */
  27740. + ldr r6, [r2, #0x14]
  27741. + orr r6, r6, #0x4000000
  27742. + str r6, [r2, #0x14]
  27743. +
  27744. +periph2_clk_switch3:
  27745. + ldr r6, [r2, #0x48]
  27746. + cmp r6, #0
  27747. + bne periph2_clk_switch3
  27748. +
  27749. + /* Now set the MMDC PODF back to 1.*/
  27750. + ldr r6, [r2, #0x14]
  27751. + bic r6, r6, #0x38
  27752. + str r6, [r2, #0x14]
  27753. +
  27754. +mmdc_podf0:
  27755. + ldr r6, [r2, #0x48]
  27756. + cmp r6, #0
  27757. + bne mmdc_podf0
  27758. +
  27759. + .endm
  27760. +
  27761. + .macro ddr_switch_400MHz
  27762. +
  27763. + /* Set MMDC divider first, in case PLL3 is at 480MHz. */
  27764. + ldr r6, [r3, #0x10]
  27765. + and r6, r6, #0x10000
  27766. + cmp r6, #0x10000
  27767. + beq pll3_in_bypass
  27768. +
  27769. + /* Set MMDC divder to divide by 2. */
  27770. + ldr r6, [r2, #0x14]
  27771. + bic r6, r6, #0x38
  27772. + orr r6, r6, #0x8
  27773. + str r6, [r2, #0x14]
  27774. +
  27775. +mmdc_podf:
  27776. + ldr r6, [r2, #0x48]
  27777. + cmp r6, #0
  27778. + bne mmdc_podf
  27779. +
  27780. +pll3_in_bypass:
  27781. + /*
  27782. + * Check if we are switching between
  27783. + * 400Mhz <-> 100MHz.If so, we should
  27784. + * try to source MMDC from PLL2_200M.
  27785. + */
  27786. + cmp r1, #0
  27787. + beq not_low_bus_freq
  27788. +
  27789. + /* Ensure that MMDC is sourced from PLL2 mux first. */
  27790. + ldr r6, [r2, #0x14]
  27791. + bic r6, r6, #0x4000000
  27792. + str r6, [r2, #0x14]
  27793. +
  27794. +periph2_clk_switch4:
  27795. + ldr r6, [r2, #0x48]
  27796. + cmp r6, #0
  27797. + bne periph2_clk_switch4
  27798. +
  27799. +not_low_bus_freq:
  27800. + /* Now ensure periph2_clk2_sel mux is set to PLL3 */
  27801. + ldr r6, [r2, #0x18]
  27802. + bic r6, r6, #0x100000
  27803. + str r6, [r2, #0x18]
  27804. +
  27805. + /* Now switch MMDC to PLL3. */
  27806. + ldr r6, [r2, #0x14]
  27807. + orr r6, r6, #0x4000000
  27808. + str r6, [r2, #0x14]
  27809. +
  27810. +periph2_clk_switch5:
  27811. + ldr r6, [r2, #0x48]
  27812. + cmp r6, #0
  27813. + bne periph2_clk_switch5
  27814. +
  27815. + /*
  27816. + * Check if PLL2 is already unlocked.
  27817. + * If so do nothing with PLL2.
  27818. + */
  27819. + cmp r1, #0
  27820. + beq pll2_already_on
  27821. +
  27822. + /* Now power up PLL2 and unbypass it. */
  27823. + ldr r6, [r3, #0x30]
  27824. + bic r6, r6, #0x1000
  27825. + str r6, [r3, #0x30]
  27826. +
  27827. + /* Make sure PLL2 has locked.*/
  27828. +wait_for_pll_lock:
  27829. + ldr r6, [r3, #0x30]
  27830. + and r6, r6, #0x80000000
  27831. + cmp r6, #0x80000000
  27832. + bne wait_for_pll_lock
  27833. +
  27834. + ldr r6, [r3, #0x30]
  27835. + bic r6, r6, #0x10000
  27836. + str r6, [r3, #0x30]
  27837. +
  27838. + /*
  27839. + * Need to enable the 528 PFDs after
  27840. + * powering up PLL2.
  27841. + * Only the PLL2_PFD2_400M should be ON
  27842. + * as it feeds the MMDC. Rest should have
  27843. + * been managed by clock code.
  27844. + */
  27845. + ldr r6, [r3, #0x100]
  27846. + bic r6, r6, #0x800000
  27847. + str r6, [r3, #0x100]
  27848. +
  27849. +pll2_already_on:
  27850. + /*
  27851. + * Now switch MMDC clk back to pll2_mux option.
  27852. + * Ensure pre_periph2_clk2 is set to pll2_pfd_400M.
  27853. + * If switching to audio DDR freq, set the
  27854. + * pre_periph2_clk2 to PLL2_PFD_200M
  27855. + */
  27856. + ldr r6, =400000000
  27857. + cmp r6, r0
  27858. + bne use_pll2_pfd_200M
  27859. +
  27860. + ldr r6, [r2, #0x18]
  27861. + bic r6, r6, #0x600000
  27862. + orr r6, r6, #0x200000
  27863. + str r6, [r2, #0x18]
  27864. + ldr r6, =400000000
  27865. + b cont2
  27866. +
  27867. +use_pll2_pfd_200M:
  27868. + ldr r6, [r2, #0x18]
  27869. + orr r6, r6, #0x600000
  27870. + str r6, [r2, #0x18]
  27871. + ldr r6, =200000000
  27872. +
  27873. +cont2:
  27874. + ldr r4, [r2, #0x14]
  27875. + bic r4, r4, #0x4000000
  27876. + str r4, [r2, #0x14]
  27877. +
  27878. +periph2_clk_switch6:
  27879. + ldr r4, [r2, #0x48]
  27880. + cmp r4, #0
  27881. + bne periph2_clk_switch6
  27882. +
  27883. +change_divider_only:
  27884. + /*
  27885. + * Calculate the MMDC divider
  27886. + * based on the requested freq.
  27887. + */
  27888. + ldr r4, =0
  27889. +Loop2:
  27890. + sub r6, r6, r0
  27891. + cmp r6, r0
  27892. + blt Div_Found
  27893. + add r4, r4, #1
  27894. + bgt Loop2
  27895. +
  27896. + /* Shift divider into correct offset. */
  27897. + lsl r4, r4, #3
  27898. +Div_Found:
  27899. + /* Set the MMDC PODF. */
  27900. + ldr r6, [r2, #0x14]
  27901. + bic r6, r6, #0x38
  27902. + orr r6, r6, r4
  27903. + str r6, [r2, #0x14]
  27904. +
  27905. +mmdc_podf1:
  27906. + ldr r6, [r2, #0x48]
  27907. + cmp r6, #0
  27908. + bne mmdc_podf1
  27909. +
  27910. + .endm
  27911. +
  27912. + .macro mmdc_clk_lower_100MHz
  27913. +
  27914. + /*
  27915. + * Prior to reducing the DDR frequency (at 528/400 MHz),
  27916. + * read the Measure unit count bits (MU_UNIT_DEL_NUM)
  27917. + */
  27918. + ldr r5, =0x8B8
  27919. + ldr r6, [r8, r5]
  27920. + /* Original MU unit count */
  27921. + mov r6, r6, LSR #16
  27922. + ldr r4, =0x3FF
  27923. + and r6, r6, r4
  27924. + /* Original MU unit count * 2 */
  27925. + mov r7, r6, LSL #1
  27926. + /*
  27927. + * Bypass the automatic measure unit when below 100 MHz
  27928. + * by setting the Measure unit bypass enable bit (MU_BYP_EN)
  27929. + */
  27930. + ldr r6, [r8, r5]
  27931. + orr r6, r6, #0x400
  27932. + str r6, [r8, r5]
  27933. + /*
  27934. + * Double the measure count value read in step 1 and program it in the
  27935. + * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit
  27936. + * Register for the reduced frequency operation below 100 MHz
  27937. + */
  27938. + ldr r6, [r8, r5]
  27939. + ldr r4, =0x3FF
  27940. + bic r6, r6, r4
  27941. + orr r6, r6, r7
  27942. + str r6, [r8, r5]
  27943. + /* Now perform a Force Measurement. */
  27944. + ldr r6, [r8, r5]
  27945. + orr r6, r6, #0x800
  27946. + str r6, [r8, r5]
  27947. + /* Wait for FRC_MSR to clear. */
  27948. +force_measure:
  27949. + ldr r6, [r8, r5]
  27950. + and r6, r6, #0x800
  27951. + cmp r6, #0x0
  27952. + bne force_measure
  27953. +
  27954. + .endm
  27955. +
  27956. + .macro mmdc_clk_above_100MHz
  27957. +
  27958. + /* Make sure that the PHY measurement unit is NOT in bypass mode */
  27959. + ldr r5, =0x8B8
  27960. + ldr r6, [r8, r5]
  27961. + bic r6, r6, #0x400
  27962. + str r6, [r8, r5]
  27963. + /* Now perform a Force Measurement. */
  27964. + ldr r6, [r8, r5]
  27965. + orr r6, r6, #0x800
  27966. + str r6, [r8, r5]
  27967. + /* Wait for FRC_MSR to clear. */
  27968. +force_measure1:
  27969. + ldr r6, [r8, r5]
  27970. + and r6, r6, #0x800
  27971. + cmp r6, #0x0
  27972. + bne force_measure1
  27973. + .endm
  27974. +
  27975. +/*
  27976. + * mx6_lpddr2_freq_change
  27977. + *
  27978. + * Make sure DDR is in self-refresh.
  27979. + * IRQs are already disabled.
  27980. + * r0 : DDR freq.
  27981. + * r1: low_bus_freq_mode flag
  27982. + * r2: Pointer to array containing addresses of registers.
  27983. + */
  27984. + .align 3
  27985. +ENTRY(mx6_lpddr2_freq_change)
  27986. +
  27987. + push {r4-r10}
  27988. +
  27989. + mov r4, r2
  27990. + ldr r3, [r4] @ANATOP_BASE_ADDR
  27991. + ldr r2, [r4, #0x4] @CCM_BASE_ADDR
  27992. + ldr r8, [r4, #0x8] @MMDC_P0_BASE_ADDR
  27993. + ldr r7, [r4, #0xC] @L2_BASE_ADDR
  27994. +
  27995. +lpddr2_freq_change:
  27996. + adr r9, lpddr2_freq_change
  27997. +
  27998. + /* Prime all TLB entries. */
  27999. + ldr r6, [r9]
  28000. + ldr r6, [r8]
  28001. + ldr r6, [r3]
  28002. + ldr r6, [r2]
  28003. +
  28004. + /* Drain all the L1 buffers. */
  28005. + dsb
  28006. +
  28007. +#ifdef CONFIG_CACHE_L2X0
  28008. + /*
  28009. + * Need to make sure the buffers in L2 are drained.
  28010. + * Performing a sync operation does this.
  28011. + */
  28012. + mov r6, #0x0
  28013. + str r6, [r7, #0x730]
  28014. +#endif
  28015. +
  28016. + /*
  28017. + * The second dsb might be needed to keep cache sync (device write)
  28018. + * ordering with the memory accesses before it.
  28019. + */
  28020. + dsb
  28021. + isb
  28022. +
  28023. + /* Disable Automatic power savings. */
  28024. + ldr r6, [r8, #0x404]
  28025. + orr r6, r6, #0x01
  28026. + str r6, [r8, #0x404]
  28027. +
  28028. + /* MMDC0_MDPDC disable power down timer */
  28029. + ldr r6, [r8, #0x4]
  28030. + bic r6, r6, #0xff00
  28031. + str r6, [r8, #0x4]
  28032. +
  28033. + /* Delay for a while */
  28034. + ldr r10, =10
  28035. +delay1:
  28036. + ldr r7, =0
  28037. +cont1:
  28038. + ldr r6, [r8, r7]
  28039. + add r7, r7, #4
  28040. + cmp r7, #16
  28041. + bne cont1
  28042. + sub r10, r10, #1
  28043. + cmp r10, #0
  28044. + bgt delay1
  28045. +
  28046. + /* Make the DDR explicitly enter self-refresh. */
  28047. + ldr r6, [r8, #0x404]
  28048. + orr r6, r6, #0x200000
  28049. + str r6, [r8, #0x404]
  28050. +
  28051. +poll_dvfs_set_1:
  28052. + ldr r6, [r8, #0x404]
  28053. + and r6, r6, #0x2000000
  28054. + cmp r6, #0x2000000
  28055. + bne poll_dvfs_set_1
  28056. +
  28057. + /* set SBS step-by-step mode */
  28058. + ldr r6, [r8, #0x410]
  28059. + orr r6, r6, #0x100
  28060. + str r6, [r8, #0x410]
  28061. +
  28062. + ldr r10, =100000000
  28063. + cmp r0, r10
  28064. + bgt set_ddr_mu_above_100
  28065. + mmdc_clk_lower_100MHz
  28066. +
  28067. +set_ddr_mu_above_100:
  28068. + ldr r10, =24000000
  28069. + cmp r0, r10
  28070. + beq set_to_24MHz
  28071. +
  28072. + ddr_switch_400MHz
  28073. +
  28074. + ldr r10,=100000000
  28075. + cmp r0, r10
  28076. + blt done
  28077. + mmdc_clk_above_100MHz
  28078. +
  28079. + b done
  28080. +
  28081. +set_to_24MHz:
  28082. + mx6sl_switch_to_24MHz
  28083. +
  28084. +done:
  28085. + /* clear DVFS - exit from self refresh mode */
  28086. + ldr r6, [r8, #0x404]
  28087. + bic r6, r6, #0x200000
  28088. + str r6, [r8, #0x404]
  28089. +
  28090. +poll_dvfs_clear_1:
  28091. + ldr r6, [r8, #0x404]
  28092. + and r6, r6, #0x2000000
  28093. + cmp r6, #0x2000000
  28094. + beq poll_dvfs_clear_1
  28095. +
  28096. + /* Enable Automatic power savings. */
  28097. + ldr r6, [r8, #0x404]
  28098. + bic r6, r6, #0x01
  28099. + str r6, [r8, #0x404]
  28100. +
  28101. + ldr r10, =24000000
  28102. + cmp r0, r10
  28103. + beq skip_power_down
  28104. +
  28105. + /* Enable MMDC power down timer. */
  28106. + ldr r6, [r8, #0x4]
  28107. + orr r6, r6, #0x5500
  28108. + str r6, [r8, #0x4]
  28109. +
  28110. +skip_power_down:
  28111. + /* clear SBS - unblock DDR accesses */
  28112. + ldr r6, [r8, #0x410]
  28113. + bic r6, r6, #0x100
  28114. + str r6, [r8, #0x410]
  28115. +
  28116. + pop {r4-r10}
  28117. +
  28118. + /* Restore registers */
  28119. + mov pc, lr
  28120. +
  28121. + .type mx6_lpddr2_do_iram, #object
  28122. +ENTRY(mx6_lpddr2_do_iram)
  28123. + .word mx6_lpddr2_freq_change
  28124. + .size mx6_lpddr2_freq_change, . - mx6_lpddr2_freq_change
  28125. diff -Nur linux-3.14.15/arch/arm/mach-imx/mach-imx6q.c linux-linaro-stable-mx6/arch/arm/mach-imx/mach-imx6q.c
  28126. --- linux-3.14.15/arch/arm/mach-imx/mach-imx6q.c 2014-07-31 23:51:43.000000000 +0200
  28127. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/mach-imx6q.c 2014-08-20 19:31:40.088843079 +0200
  28128. @@ -1,5 +1,5 @@
  28129. /*
  28130. - * Copyright 2011-2013 Freescale Semiconductor, Inc.
  28131. + * Copyright 2011-2014 Freescale Semiconductor, Inc.
  28132. * Copyright 2011 Linaro Ltd.
  28133. *
  28134. * The code contained herein is licensed under the GNU General Public
  28135. @@ -15,6 +15,7 @@
  28136. #include <linux/cpu.h>
  28137. #include <linux/delay.h>
  28138. #include <linux/export.h>
  28139. +#include <linux/gpio.h>
  28140. #include <linux/init.h>
  28141. #include <linux/io.h>
  28142. #include <linux/irq.h>
  28143. @@ -22,15 +23,18 @@
  28144. #include <linux/of.h>
  28145. #include <linux/of_address.h>
  28146. #include <linux/of_irq.h>
  28147. +#include <linux/of_gpio.h>
  28148. #include <linux/of_platform.h>
  28149. #include <linux/pm_opp.h>
  28150. #include <linux/pci.h>
  28151. #include <linux/phy.h>
  28152. +#include <linux/pm_opp.h>
  28153. #include <linux/reboot.h>
  28154. #include <linux/regmap.h>
  28155. #include <linux/micrel_phy.h>
  28156. #include <linux/mfd/syscon.h>
  28157. #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  28158. +#include <linux/of_net.h>
  28159. #include <asm/mach/arch.h>
  28160. #include <asm/mach/map.h>
  28161. #include <asm/system_misc.h>
  28162. @@ -194,6 +198,101 @@
  28163. }
  28164. +static void __init imx6q_csi_mux_init(void)
  28165. +{
  28166. + /*
  28167. + * MX6Q SabreSD board:
  28168. + * IPU1 CSI0 connects to parallel interface.
  28169. + * Set GPR1 bit 19 to 0x1.
  28170. + *
  28171. + * MX6DL SabreSD board:
  28172. + * IPU1 CSI0 connects to parallel interface.
  28173. + * Set GPR13 bit 0-2 to 0x4.
  28174. + * IPU1 CSI1 connects to MIPI CSI2 virtual channel 1.
  28175. + * Set GPR13 bit 3-5 to 0x1.
  28176. + */
  28177. + struct regmap *gpr;
  28178. +
  28179. + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  28180. + if (!IS_ERR(gpr)) {
  28181. + if (of_machine_is_compatible("fsl,imx6q-sabresd") ||
  28182. + of_machine_is_compatible("fsl,imx6q-sabreauto"))
  28183. + regmap_update_bits(gpr, IOMUXC_GPR1, 1 << 19, 1 << 19);
  28184. + else if (of_machine_is_compatible("fsl,imx6dl-sabresd") ||
  28185. + of_machine_is_compatible("fsl,imx6dl-sabreauto"))
  28186. + regmap_update_bits(gpr, IOMUXC_GPR13, 0x3F, 0x0C);
  28187. + } else {
  28188. + pr_err("%s(): failed to find fsl,imx6q-iomux-gpr regmap\n",
  28189. + __func__);
  28190. + }
  28191. +}
  28192. +
  28193. +#define OCOTP_MACn(n) (0x00000620 + (n) * 0x10)
  28194. +void __init imx6_enet_mac_init(const char *compatible)
  28195. +{
  28196. + struct device_node *ocotp_np, *enet_np;
  28197. + void __iomem *base;
  28198. + struct property *newmac;
  28199. + u32 macaddr_low, macaddr_high;
  28200. + u8 *macaddr;
  28201. +
  28202. + enet_np = of_find_compatible_node(NULL, NULL, compatible);
  28203. + if (!enet_np)
  28204. + return;
  28205. +
  28206. + if (of_get_mac_address(enet_np))
  28207. + goto put_enet_node;
  28208. +
  28209. + ocotp_np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
  28210. + if (!ocotp_np) {
  28211. + pr_warn("failed to find ocotp node\n");
  28212. + goto put_enet_node;
  28213. + }
  28214. +
  28215. + base = of_iomap(ocotp_np, 0);
  28216. + if (!base) {
  28217. + pr_warn("failed to map ocotp\n");
  28218. + goto put_ocotp_node;
  28219. + }
  28220. +
  28221. + macaddr_high = readl_relaxed(base + OCOTP_MACn(0));
  28222. + macaddr_low = readl_relaxed(base + OCOTP_MACn(1));
  28223. +
  28224. + newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL);
  28225. + if (!newmac)
  28226. + goto put_ocotp_node;
  28227. +
  28228. + newmac->value = newmac + 1;
  28229. + newmac->length = 6;
  28230. + newmac->name = kstrdup("local-mac-address", GFP_KERNEL);
  28231. + if (!newmac->name) {
  28232. + kfree(newmac);
  28233. + goto put_ocotp_node;
  28234. + }
  28235. +
  28236. + macaddr = newmac->value;
  28237. + macaddr[5] = macaddr_high & 0xff;
  28238. + macaddr[4] = (macaddr_high >> 8) & 0xff;
  28239. + macaddr[3] = (macaddr_high >> 16) & 0xff;
  28240. + macaddr[2] = (macaddr_high >> 24) & 0xff;
  28241. + macaddr[1] = macaddr_low & 0xff;
  28242. + macaddr[0] = (macaddr_low >> 8) & 0xff;
  28243. +
  28244. + of_update_property(enet_np, newmac);
  28245. +
  28246. +put_ocotp_node:
  28247. + of_node_put(ocotp_np);
  28248. +put_enet_node:
  28249. + of_node_put(enet_np);
  28250. +}
  28251. +
  28252. +static inline void imx6q_enet_init(void)
  28253. +{
  28254. + imx6_enet_mac_init("fsl,imx6q-fec");
  28255. + imx6q_enet_phy_init();
  28256. + imx6q_1588_init();
  28257. +}
  28258. +
  28259. static void __init imx6q_init_machine(void)
  28260. {
  28261. struct device *parent;
  28262. @@ -207,20 +306,22 @@
  28263. if (parent == NULL)
  28264. pr_warn("failed to initialize soc device\n");
  28265. - imx6q_enet_phy_init();
  28266. -
  28267. of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
  28268. + imx6q_enet_init();
  28269. imx_anatop_init();
  28270. - imx6q_pm_init();
  28271. - imx6q_1588_init();
  28272. + cpu_is_imx6q() ? imx6q_pm_init() : imx6dl_pm_init();
  28273. + imx6q_csi_mux_init();
  28274. }
  28275. #define OCOTP_CFG3 0x440
  28276. #define OCOTP_CFG3_SPEED_SHIFT 16
  28277. #define OCOTP_CFG3_SPEED_1P2GHZ 0x3
  28278. +#define OCOTP_CFG3_SPEED_1GHZ 0x2
  28279. +#define OCOTP_CFG3_SPEED_850MHZ 0x1
  28280. +#define OCOTP_CFG3_SPEED_800MHZ 0x0
  28281. -static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev)
  28282. +static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
  28283. {
  28284. struct device_node *np;
  28285. void __iomem *base;
  28286. @@ -238,11 +339,31 @@
  28287. goto put_node;
  28288. }
  28289. + /*
  28290. + * SPEED_GRADING[1:0] defines the max speed of ARM:
  28291. + * 2b'11: 1200000000Hz; -- i.MX6Q only.
  28292. + * 2b'10: 1000000000Hz;
  28293. + * 2b'01: 850000000Hz; -- i.MX6Q Only, exclusive with 1GHz.
  28294. + * 2b'00: 800000000Hz;
  28295. + * We need to set the max speed of ARM according to fuse map.
  28296. + */
  28297. +
  28298. val = readl_relaxed(base + OCOTP_CFG3);
  28299. val >>= OCOTP_CFG3_SPEED_SHIFT;
  28300. - if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ)
  28301. - if (dev_pm_opp_disable(cpu_dev, 1200000000))
  28302. - pr_warn("failed to disable 1.2 GHz OPP\n");
  28303. + if (cpu_is_imx6q()) {
  28304. + if ((val & 0x3) < OCOTP_CFG3_SPEED_1P2GHZ)
  28305. + if (dev_pm_opp_disable(cpu_dev, 1200000000))
  28306. + pr_warn("failed to disable 1.2 GHz OPP\n");
  28307. + }
  28308. + if ((val & 0x3) < OCOTP_CFG3_SPEED_1GHZ)
  28309. + if (dev_pm_opp_disable(cpu_dev, 996000000))
  28310. + pr_warn("failed to disable 1 GHz OPP\n");
  28311. + if (cpu_is_imx6q()) {
  28312. + if ((val & 0x3) < OCOTP_CFG3_SPEED_850MHZ ||
  28313. + (val & 0x3) == OCOTP_CFG3_SPEED_1GHZ)
  28314. + if (dev_pm_opp_disable(cpu_dev, 852000000))
  28315. + pr_warn("failed to disable 850 MHz OPP\n");
  28316. + }
  28317. put_node:
  28318. of_node_put(np);
  28319. @@ -268,29 +389,70 @@
  28320. goto put_node;
  28321. }
  28322. - imx6q_opp_check_1p2ghz(cpu_dev);
  28323. + imx6q_opp_check_speed_grading(cpu_dev);
  28324. put_node:
  28325. of_node_put(np);
  28326. }
  28327. +#define ESAI_AUDIO_MCLK 24576000
  28328. +
  28329. +static void __init imx6q_audio_lvds2_init(void)
  28330. +{
  28331. + struct clk *pll4_sel, *lvds2_in, *pll4_audio_div, *esai;
  28332. +
  28333. + pll4_audio_div = clk_get_sys(NULL, "pll4_audio_div");
  28334. + pll4_sel = clk_get_sys(NULL, "pll4_sel");
  28335. + lvds2_in = clk_get_sys(NULL, "lvds2_in");
  28336. + esai = clk_get_sys(NULL, "esai");
  28337. + if (IS_ERR(pll4_audio_div) || IS_ERR(pll4_sel) ||
  28338. + IS_ERR(lvds2_in) || IS_ERR(esai))
  28339. + return;
  28340. +
  28341. + if (clk_get_rate(lvds2_in) != ESAI_AUDIO_MCLK)
  28342. + return;
  28343. +
  28344. + clk_set_parent(pll4_sel, lvds2_in);
  28345. + clk_set_rate(pll4_audio_div, 786432000);
  28346. + clk_set_rate(esai, ESAI_AUDIO_MCLK);
  28347. +}
  28348. +
  28349. static struct platform_device imx6q_cpufreq_pdev = {
  28350. - .name = "imx6q-cpufreq",
  28351. + .name = "imx6-cpufreq",
  28352. };
  28353. static void __init imx6q_init_late(void)
  28354. {
  28355. + struct regmap *gpr;
  28356. +
  28357. + /*
  28358. + * Need to force IOMUXC irq pending to meet CCM low power mode
  28359. + * restriction, this is recommended by hardware team.
  28360. + */
  28361. + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  28362. + if (!IS_ERR(gpr))
  28363. + regmap_update_bits(gpr, IOMUXC_GPR1,
  28364. + IMX6Q_GPR1_GINT_MASK,
  28365. + IMX6Q_GPR1_GINT_ASSERT);
  28366. +
  28367. /*
  28368. * WAIT mode is broken on TO 1.0 and 1.1, so there is no point
  28369. * to run cpuidle on them.
  28370. */
  28371. - if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
  28372. + if ((cpu_is_imx6q() && imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
  28373. + || (cpu_is_imx6dl() && imx_get_soc_revision() >
  28374. + IMX_CHIP_REVISION_1_0))
  28375. imx6q_cpuidle_init();
  28376. - if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
  28377. + if (IS_ENABLED(CONFIG_ARM_IMX6_CPUFREQ)) {
  28378. imx6q_opp_init();
  28379. platform_device_register(&imx6q_cpufreq_pdev);
  28380. }
  28381. +
  28382. + if (of_machine_is_compatible("fsl,imx6q-sabreauto")
  28383. + || of_machine_is_compatible("fsl,imx6dl-sabreauto")) {
  28384. + imx6q_audio_lvds2_init();
  28385. + }
  28386. }
  28387. static void __init imx6q_map_io(void)
  28388. @@ -315,6 +477,12 @@
  28389. };
  28390. DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
  28391. + /*
  28392. + * i.MX6Q/DL maps system memory at 0x10000000 (offset 256MiB), and
  28393. + * GPU has a limit on physical address that it accesses, which must
  28394. + * be below 2GiB.
  28395. + */
  28396. + .dma_zone_size = (SZ_2G - SZ_256M),
  28397. .smp = smp_ops(imx_smp_ops),
  28398. .map_io = imx6q_map_io,
  28399. .init_irq = imx6q_init_irq,
  28400. diff -Nur linux-3.14.15/arch/arm/mach-imx/mach-imx6sl.c linux-linaro-stable-mx6/arch/arm/mach-imx/mach-imx6sl.c
  28401. --- linux-3.14.15/arch/arm/mach-imx/mach-imx6sl.c 2014-07-31 23:51:43.000000000 +0200
  28402. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/mach-imx6sl.c 2014-08-20 19:31:40.088843079 +0200
  28403. @@ -17,8 +17,9 @@
  28404. #include <asm/mach/map.h>
  28405. #include "common.h"
  28406. +#include "cpuidle.h"
  28407. -static void __init imx6sl_fec_init(void)
  28408. +static void __init imx6sl_fec_clk_init(void)
  28409. {
  28410. struct regmap *gpr;
  28411. @@ -34,8 +35,17 @@
  28412. }
  28413. }
  28414. +static inline void imx6sl_fec_init(void)
  28415. +{
  28416. + imx6sl_fec_clk_init();
  28417. + imx6_enet_mac_init("fsl,imx6sl-fec");
  28418. +}
  28419. +
  28420. static void __init imx6sl_init_late(void)
  28421. {
  28422. + /* Init CPUIDLE */
  28423. + imx6sl_cpuidle_init();
  28424. +
  28425. /* imx6sl reuses imx6q cpufreq driver */
  28426. if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
  28427. platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
  28428. @@ -55,8 +65,7 @@
  28429. imx6sl_fec_init();
  28430. imx_anatop_init();
  28431. - /* Reuse imx6q pm code */
  28432. - imx6q_pm_init();
  28433. + imx6sl_pm_init();
  28434. }
  28435. static void __init imx6sl_init_irq(void)
  28436. diff -Nur linux-3.14.15/arch/arm/mach-imx/mach-vf610.c linux-linaro-stable-mx6/arch/arm/mach-imx/mach-vf610.c
  28437. --- linux-3.14.15/arch/arm/mach-imx/mach-vf610.c 2014-07-31 23:51:43.000000000 +0200
  28438. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/mach-vf610.c 2014-08-20 19:31:40.088843079 +0200
  28439. @@ -22,7 +22,7 @@
  28440. static void __init vf610_init_irq(void)
  28441. {
  28442. - l2x0_of_init(0, ~0UL);
  28443. + l2x0_of_init(0, ~0);
  28444. irqchip_init();
  28445. }
  28446. diff -Nur linux-3.14.15/arch/arm/mach-imx/Makefile linux-linaro-stable-mx6/arch/arm/mach-imx/Makefile
  28447. --- linux-3.14.15/arch/arm/mach-imx/Makefile 2014-07-31 23:51:43.000000000 +0200
  28448. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/Makefile 2014-08-20 19:31:40.080843045 +0200
  28449. @@ -30,6 +30,7 @@
  28450. ifeq ($(CONFIG_CPU_IDLE),y)
  28451. obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
  28452. obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
  28453. +obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
  28454. endif
  28455. ifdef CONFIG_SND_IMX_SOC
  28456. @@ -101,9 +102,18 @@
  28457. obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
  28458. obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
  28459. -obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
  28460. -# i.MX6SL reuses i.MX6Q code
  28461. -obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o
  28462. +AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
  28463. +obj-$(CONFIG_PM) += suspend-imx6.o pm-imx6.o headsmp.o
  28464. +
  28465. +obj-y += busfreq-imx6.o
  28466. +ifeq ($(CONFIG_ARM_IMX6_CPUFREQ),y)
  28467. +obj-$(CONFIG_SOC_IMX6Q) += ddr3_freq_imx6.o busfreq_ddr3.o
  28468. +obj-$(CONFIG_SOC_IMX6SL) += lpddr2_freq_imx6.o busfreq_lpddr2.o
  28469. +endif
  28470. +ifeq ($(CONFIG_CPU_IDLE), y)
  28471. +obj-$(CONFIG_SOC_IMX6SL) += imx6sl_wfi.o
  28472. +endif
  28473. +
  28474. # i.MX5 based machines
  28475. obj-$(CONFIG_MACH_MX51_BABBAGE) += mach-mx51_babbage.o
  28476. diff -Nur linux-3.14.15/arch/arm/mach-imx/mx6.h linux-linaro-stable-mx6/arch/arm/mach-imx/mx6.h
  28477. --- linux-3.14.15/arch/arm/mach-imx/mx6.h 1970-01-01 01:00:00.000000000 +0100
  28478. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/mx6.h 2014-08-20 19:23:45.814812779 +0200
  28479. @@ -0,0 +1,35 @@
  28480. +/*
  28481. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  28482. + */
  28483. +
  28484. +/*
  28485. + * This program is free software; you can redistribute it and/or modify
  28486. + * it under the terms of the GNU General Public License version 2 as
  28487. + * published by the Free Software Foundation.
  28488. + */
  28489. +
  28490. +#ifndef __ASM_ARCH_MXC_IOMAP_H__
  28491. +#define __ASM_ARCH_MXC_IOMAP_H__
  28492. +
  28493. +#define MX6Q_IO_P2V(x) IMX_IO_P2V(x)
  28494. +#define MX6Q_IO_ADDRESS(x) IOMEM(MX6Q_IO_P2V(x))
  28495. +
  28496. +#define MX6Q_L2_BASE_ADDR 0x00a02000
  28497. +#define MX6Q_L2_SIZE 0x1000
  28498. +#define MX6Q_IOMUXC_BASE_ADDR 0x020e0000
  28499. +#define MX6Q_IOMUXC_SIZE 0x4000
  28500. +#define MX6Q_SRC_BASE_ADDR 0x020d8000
  28501. +#define MX6Q_SRC_SIZE 0x4000
  28502. +#define MX6Q_CCM_BASE_ADDR 0x020c4000
  28503. +#define MX6Q_CCM_SIZE 0x4000
  28504. +#define MX6Q_ANATOP_BASE_ADDR 0x020c8000
  28505. +#define MX6Q_ANATOP_SIZE 0x1000
  28506. +#define MX6Q_GPC_BASE_ADDR 0x020dc000
  28507. +#define MX6Q_GPC_SIZE 0x4000
  28508. +#define MX6Q_MMDC_P0_BASE_ADDR 0x021b0000
  28509. +#define MX6Q_MMDC_P0_SIZE 0x4000
  28510. +#define MX6Q_MMDC_P1_BASE_ADDR 0x021b4000
  28511. +#define MX6Q_MMDC_P1_SIZE 0x4000
  28512. +
  28513. +#define MX6_SUSPEND_IRAM_SIZE 0x1000
  28514. +#endif
  28515. diff -Nur linux-3.14.15/arch/arm/mach-imx/mxc.h linux-linaro-stable-mx6/arch/arm/mach-imx/mxc.h
  28516. --- linux-3.14.15/arch/arm/mach-imx/mxc.h 2014-07-31 23:51:43.000000000 +0200
  28517. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/mxc.h 2014-08-20 19:31:40.092843095 +0200
  28518. @@ -42,6 +42,8 @@
  28519. #define IMX_CHIP_REVISION_1_1 0x11
  28520. #define IMX_CHIP_REVISION_1_2 0x12
  28521. #define IMX_CHIP_REVISION_1_3 0x13
  28522. +#define IMX_CHIP_REVISION_1_4 0x14
  28523. +#define IMX_CHIP_REVISION_1_5 0x15
  28524. #define IMX_CHIP_REVISION_2_0 0x20
  28525. #define IMX_CHIP_REVISION_2_1 0x21
  28526. #define IMX_CHIP_REVISION_2_2 0x22
  28527. @@ -177,6 +179,7 @@
  28528. extern struct cpu_op *(*get_cpu_op)(int *op);
  28529. #endif
  28530. +#define cpu_is_imx6() (cpu_is_imx6q() || cpu_is_imx6dl() || cpu_is_imx6sl())
  28531. #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35())
  28532. #define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27())
  28533. diff -Nur linux-3.14.15/arch/arm/mach-imx/pm-imx6.c linux-linaro-stable-mx6/arch/arm/mach-imx/pm-imx6.c
  28534. --- linux-3.14.15/arch/arm/mach-imx/pm-imx6.c 1970-01-01 01:00:00.000000000 +0100
  28535. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/pm-imx6.c 2014-08-20 19:31:40.092843095 +0200
  28536. @@ -0,0 +1,580 @@
  28537. +/*
  28538. + * Copyright 2011-2014 Freescale Semiconductor, Inc.
  28539. + * Copyright 2011 Linaro Ltd.
  28540. + *
  28541. + * The code contained herein is licensed under the GNU General Public
  28542. + * License. You may obtain a copy of the GNU General Public License
  28543. + * Version 2 or later at the following locations:
  28544. + *
  28545. + * http://www.opensource.org/licenses/gpl-license.html
  28546. + * http://www.gnu.org/copyleft/gpl.html
  28547. + */
  28548. +
  28549. +#include <linux/delay.h>
  28550. +#include <linux/init.h>
  28551. +#include <linux/io.h>
  28552. +#include <linux/irq.h>
  28553. +#include <linux/genalloc.h>
  28554. +#include <linux/mfd/syscon.h>
  28555. +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  28556. +#include <linux/of.h>
  28557. +#include <linux/of_address.h>
  28558. +#include <linux/of_platform.h>
  28559. +#include <linux/regmap.h>
  28560. +#include <linux/suspend.h>
  28561. +#include <linux/regmap.h>
  28562. +#include <linux/mfd/syscon.h>
  28563. +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  28564. +#include <asm/cacheflush.h>
  28565. +#include <asm/fncpy.h>
  28566. +#include <asm/proc-fns.h>
  28567. +#include <asm/suspend.h>
  28568. +#include <asm/tlb.h>
  28569. +
  28570. +#include "common.h"
  28571. +#include "hardware.h"
  28572. +
  28573. +#define CCR 0x0
  28574. +#define BM_CCR_WB_COUNT (0x7 << 16)
  28575. +#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
  28576. +#define BM_CCR_RBC_EN (0x1 << 27)
  28577. +
  28578. +#define CLPCR 0x54
  28579. +#define BP_CLPCR_LPM 0
  28580. +#define BM_CLPCR_LPM (0x3 << 0)
  28581. +#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
  28582. +#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
  28583. +#define BM_CLPCR_SBYOS (0x1 << 6)
  28584. +#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
  28585. +#define BM_CLPCR_VSTBY (0x1 << 8)
  28586. +#define BP_CLPCR_STBY_COUNT 9
  28587. +#define BM_CLPCR_STBY_COUNT (0x3 << 9)
  28588. +#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
  28589. +#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
  28590. +#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
  28591. +#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
  28592. +#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
  28593. +#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
  28594. +#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
  28595. +#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
  28596. +#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
  28597. +#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
  28598. +#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
  28599. +
  28600. +#define CGPR 0x64
  28601. +#define BM_CGPR_INT_MEM_CLK_LPM (0x1 << 17)
  28602. +
  28603. +#define MX6Q_SUSPEND_OCRAM_SIZE 0x1000
  28604. +#define MX6_MAX_MMDC_IO_NUM 33
  28605. +
  28606. +static void __iomem *ccm_base;
  28607. +static void __iomem *suspend_ocram_base;
  28608. +static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
  28609. +
  28610. +/*
  28611. + * suspend ocram space layout:
  28612. + * ======================== high address ======================
  28613. + * .
  28614. + * .
  28615. + * .
  28616. + * ^
  28617. + * ^
  28618. + * ^
  28619. + * imx6_suspend code
  28620. + * PM_INFO structure(imx6_cpu_pm_info)
  28621. + * ======================== low address =======================
  28622. + */
  28623. +
  28624. +struct imx6_pm_base {
  28625. + phys_addr_t pbase;
  28626. + void __iomem *vbase;
  28627. +};
  28628. +
  28629. +struct imx6_pm_socdata {
  28630. + u32 cpu_type;
  28631. + const char *mmdc_compat;
  28632. + const char *src_compat;
  28633. + const char *iomuxc_compat;
  28634. + const char *gpc_compat;
  28635. + const u32 mmdc_io_num;
  28636. + const u32 *mmdc_io_offset;
  28637. +};
  28638. +
  28639. +static const u32 imx6q_mmdc_io_offset[] __initconst = {
  28640. + 0x5ac, 0x5b4, 0x528, 0x520, /* DQM0 ~ DQM3 */
  28641. + 0x514, 0x510, 0x5bc, 0x5c4, /* DQM4 ~ DQM7 */
  28642. + 0x56c, 0x578, 0x588, 0x594, /* CAS, RAS, SDCLK_0, SDCLK_1 */
  28643. + 0x5a8, 0x5b0, 0x524, 0x51c, /* SDQS0 ~ SDQS3 */
  28644. + 0x518, 0x50c, 0x5b8, 0x5c0, /* SDQS4 ~ SDQS7 */
  28645. + 0x784, 0x788, 0x794, 0x79c, /* GPR_B0DS ~ GPR_B3DS */
  28646. + 0x7a0, 0x7a4, 0x7a8, 0x748, /* GPR_B4DS ~ GPR_B7DS */
  28647. + 0x59c, 0x5a0, 0x750, 0x774, /* SODT0, SODT1, MODE_CTL, MODE */
  28648. + 0x74c, /* GPR_ADDS */
  28649. +};
  28650. +
  28651. +static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
  28652. + .cpu_type = MXC_CPU_IMX6Q,
  28653. + .mmdc_compat = "fsl,imx6q-mmdc",
  28654. + .src_compat = "fsl,imx6q-src",
  28655. + .iomuxc_compat = "fsl,imx6q-iomuxc",
  28656. + .gpc_compat = "fsl,imx6q-gpc",
  28657. + .mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset),
  28658. + .mmdc_io_offset = imx6q_mmdc_io_offset,
  28659. +};
  28660. +
  28661. +/*
  28662. + * This structure is for passing necessary data for low level ocram
  28663. + * suspend code(arch/arm/mach-imx/suspend-imx6.S), if this struct
  28664. + * definition is changed, the offset definition in
  28665. + * arch/arm/mach-imx/suspend-imx6.S must be also changed accordingly,
  28666. + * otherwise, the suspend to ocram function will be broken!
  28667. + */
  28668. +struct imx6_cpu_pm_info {
  28669. + phys_addr_t pbase; /* The physical address of pm_info. */
  28670. + phys_addr_t resume_addr; /* The physical resume address for asm code */
  28671. + u32 cpu_type;
  28672. + u32 pm_info_size; /* Size of pm_info. */
  28673. + struct imx6_pm_base mmdc_base;
  28674. + struct imx6_pm_base src_base;
  28675. + struct imx6_pm_base iomuxc_base;
  28676. + struct imx6_pm_base ccm_base;
  28677. + struct imx6_pm_base gpc_base;
  28678. + struct imx6_pm_base l2_base;
  28679. + u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
  28680. + u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2]; /* To save offset and value */
  28681. +} __aligned(8);
  28682. +
  28683. +void imx6q_set_cache_lpm_in_wait(bool enable)
  28684. +{
  28685. + if ((cpu_is_imx6q() && imx_get_soc_revision() >
  28686. + IMX_CHIP_REVISION_1_1) ||
  28687. + (cpu_is_imx6dl() && imx_get_soc_revision() >
  28688. + IMX_CHIP_REVISION_1_0)) {
  28689. + u32 val;
  28690. +
  28691. + val = readl_relaxed(ccm_base + CGPR);
  28692. + if (enable)
  28693. + val |= BM_CGPR_INT_MEM_CLK_LPM;
  28694. + else
  28695. + val &= ~BM_CGPR_INT_MEM_CLK_LPM;
  28696. + writel_relaxed(val, ccm_base + CGPR);
  28697. + }
  28698. +}
  28699. +
  28700. +static void imx6q_enable_rbc(bool enable)
  28701. +{
  28702. + u32 val;
  28703. +
  28704. + /*
  28705. + * need to mask all interrupts in GPC before
  28706. + * operating RBC configurations
  28707. + */
  28708. + imx_gpc_mask_all();
  28709. +
  28710. + /* configure RBC enable bit */
  28711. + val = readl_relaxed(ccm_base + CCR);
  28712. + val &= ~BM_CCR_RBC_EN;
  28713. + val |= enable ? BM_CCR_RBC_EN : 0;
  28714. + writel_relaxed(val, ccm_base + CCR);
  28715. +
  28716. + /* configure RBC count */
  28717. + val = readl_relaxed(ccm_base + CCR);
  28718. + val &= ~BM_CCR_RBC_BYPASS_COUNT;
  28719. + val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
  28720. + writel(val, ccm_base + CCR);
  28721. +
  28722. + /*
  28723. + * need to delay at least 2 cycles of CKIL(32K)
  28724. + * due to hardware design requirement, which is
  28725. + * ~61us, here we use 65us for safe
  28726. + */
  28727. + udelay(65);
  28728. +
  28729. + /* restore GPC interrupt mask settings */
  28730. + imx_gpc_restore_all();
  28731. +}
  28732. +
  28733. +static void imx6q_enable_wb(bool enable)
  28734. +{
  28735. + u32 val;
  28736. +
  28737. + /* configure well bias enable bit */
  28738. + val = readl_relaxed(ccm_base + CLPCR);
  28739. + val &= ~BM_CLPCR_WB_PER_AT_LPM;
  28740. + val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
  28741. + writel_relaxed(val, ccm_base + CLPCR);
  28742. +
  28743. + /* configure well bias count */
  28744. + val = readl_relaxed(ccm_base + CCR);
  28745. + val &= ~BM_CCR_WB_COUNT;
  28746. + val |= enable ? BM_CCR_WB_COUNT : 0;
  28747. + writel_relaxed(val, ccm_base + CCR);
  28748. +}
  28749. +
  28750. +int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
  28751. +{
  28752. + struct irq_desc *iomuxc_irq_desc;
  28753. + u32 val = readl_relaxed(ccm_base + CLPCR);
  28754. +
  28755. + val &= ~BM_CLPCR_LPM;
  28756. + switch (mode) {
  28757. + case WAIT_CLOCKED:
  28758. + break;
  28759. + case WAIT_UNCLOCKED:
  28760. + val |= 0x1 << BP_CLPCR_LPM;
  28761. + val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
  28762. + val &= ~BM_CLPCR_VSTBY;
  28763. + val &= ~BM_CLPCR_SBYOS;
  28764. + if (cpu_is_imx6sl())
  28765. + val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
  28766. + else
  28767. + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  28768. + break;
  28769. + case STOP_POWER_ON:
  28770. + val |= 0x2 << BP_CLPCR_LPM;
  28771. + val &= ~BM_CLPCR_VSTBY;
  28772. + val &= ~BM_CLPCR_SBYOS;
  28773. + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  28774. + break;
  28775. + case WAIT_UNCLOCKED_POWER_OFF:
  28776. + val |= 0x1 << BP_CLPCR_LPM;
  28777. + val &= ~BM_CLPCR_VSTBY;
  28778. + val &= ~BM_CLPCR_SBYOS;
  28779. + break;
  28780. + case STOP_POWER_OFF:
  28781. + val |= 0x2 << BP_CLPCR_LPM;
  28782. + val |= 0x3 << BP_CLPCR_STBY_COUNT;
  28783. + val |= BM_CLPCR_VSTBY;
  28784. + val |= BM_CLPCR_SBYOS;
  28785. + if (cpu_is_imx6sl()) {
  28786. + val |= BM_CLPCR_BYPASS_PMIC_READY;
  28787. + val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
  28788. + } else {
  28789. + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  28790. + }
  28791. + break;
  28792. + default:
  28793. + return -EINVAL;
  28794. + }
  28795. +
  28796. + /*
  28797. + * ERR007265: CCM: When improper low-power sequence is used,
  28798. + * the SoC enters low power mode before the ARM core executes WFI.
  28799. + *
  28800. + * Software workaround:
  28801. + * 1) Software should trigger IRQ #32 (IOMUX) to be always pending
  28802. + * by setting IOMUX_GPR1_GINT.
  28803. + * 2) Software should then unmask IRQ #32 in GPC before setting CCM
  28804. + * Low-Power mode.
  28805. + * 3) Software should mask IRQ #32 right after CCM Low-Power mode
  28806. + * is set (set bits 0-1 of CCM_CLPCR).
  28807. + */
  28808. + iomuxc_irq_desc = irq_to_desc(32);
  28809. + imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data);
  28810. + writel_relaxed(val, ccm_base + CLPCR);
  28811. + imx_gpc_irq_mask(&iomuxc_irq_desc->irq_data);
  28812. +
  28813. + return 0;
  28814. +}
  28815. +
  28816. +static int imx6q_suspend_finish(unsigned long val)
  28817. +{
  28818. + if (!imx6_suspend_in_ocram_fn) {
  28819. + cpu_do_idle();
  28820. + } else {
  28821. + /*
  28822. + * call low level suspend function in ocram,
  28823. + * as we need to float DDR IO.
  28824. + */
  28825. + local_flush_tlb_all();
  28826. + imx6_suspend_in_ocram_fn(suspend_ocram_base);
  28827. + }
  28828. +
  28829. + return 0;
  28830. +}
  28831. +
  28832. +static int imx6q_pm_enter(suspend_state_t state)
  28833. +{
  28834. + struct regmap *g;
  28835. +
  28836. + /*
  28837. + * L2 can exit by 'reset' or Inband beacon (from remote EP)
  28838. + * toggling phy_powerdown has same effect as 'inband beacon'
  28839. + * So, toggle bit18 of GPR1, used as a workaround of errata
  28840. + * "PCIe PCIe does not support L2 Power Down"
  28841. + */
  28842. + if (IS_ENABLED(CONFIG_PCI_IMX6)) {
  28843. + g = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  28844. + if (IS_ERR(g)) {
  28845. + pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n");
  28846. + return PTR_ERR(g);
  28847. + }
  28848. + regmap_update_bits(g, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD,
  28849. + IMX6Q_GPR1_PCIE_TEST_PD);
  28850. + }
  28851. +
  28852. + switch (state) {
  28853. + case PM_SUSPEND_STANDBY:
  28854. + imx6q_set_lpm(STOP_POWER_ON);
  28855. + imx6q_set_cache_lpm_in_wait(true);
  28856. + imx_gpc_pre_suspend(false);
  28857. + if (cpu_is_imx6sl())
  28858. + imx6sl_set_wait_clk(true);
  28859. + /* Zzz ... */
  28860. + cpu_do_idle();
  28861. + if (cpu_is_imx6sl())
  28862. + imx6sl_set_wait_clk(false);
  28863. + imx_gpc_post_resume();
  28864. + imx6q_set_lpm(WAIT_CLOCKED);
  28865. + break;
  28866. + case PM_SUSPEND_MEM:
  28867. + imx6q_set_cache_lpm_in_wait(false);
  28868. + imx6q_set_lpm(STOP_POWER_OFF);
  28869. + imx6q_enable_wb(true);
  28870. + /*
  28871. + * For suspend into ocram, asm code already take care of
  28872. + * RBC setting, so we do NOT need to do that here.
  28873. + */
  28874. + if (!imx6_suspend_in_ocram_fn)
  28875. + imx6q_enable_rbc(true);
  28876. + imx_gpc_pre_suspend(true);
  28877. + imx_anatop_pre_suspend();
  28878. + imx_set_cpu_jump(0, v7_cpu_resume);
  28879. + /* Zzz ... */
  28880. + cpu_suspend(0, imx6q_suspend_finish);
  28881. + if (cpu_is_imx6q() || cpu_is_imx6dl())
  28882. + imx_smp_prepare();
  28883. + imx_anatop_post_resume();
  28884. + imx_gpc_post_resume();
  28885. + imx6q_enable_wb(false);
  28886. + imx6q_set_lpm(WAIT_CLOCKED);
  28887. + break;
  28888. + default:
  28889. + return -EINVAL;
  28890. + }
  28891. +
  28892. + /*
  28893. + * L2 can exit by 'reset' or Inband beacon (from remote EP)
  28894. + * toggling phy_powerdown has same effect as 'inband beacon'
  28895. + * So, toggle bit18 of GPR1, used as a workaround of errata
  28896. + * "PCIe PCIe does not support L2 Power Down"
  28897. + */
  28898. + if (IS_ENABLED(CONFIG_PCI_IMX6)) {
  28899. + regmap_update_bits(g, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD,
  28900. + !IMX6Q_GPR1_PCIE_TEST_PD);
  28901. + }
  28902. +
  28903. + return 0;
  28904. +}
  28905. +
  28906. +static int imx6q_pm_valid(suspend_state_t state)
  28907. +{
  28908. + return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM);
  28909. +}
  28910. +
  28911. +static const struct platform_suspend_ops imx6q_pm_ops = {
  28912. + .enter = imx6q_pm_enter,
  28913. + .valid = imx6q_pm_valid,
  28914. +};
  28915. +
  28916. +void __init imx6q_pm_set_ccm_base(void __iomem *base)
  28917. +{
  28918. + ccm_base = base;
  28919. +}
  28920. +
  28921. +static int __init imx6_pm_get_base(struct imx6_pm_base *base,
  28922. + const char *compat)
  28923. +{
  28924. + struct device_node *node;
  28925. + struct resource res;
  28926. + int ret = 0;
  28927. +
  28928. + node = of_find_compatible_node(NULL, NULL, compat);
  28929. + if (!node) {
  28930. + ret = -ENODEV;
  28931. + goto out;
  28932. + }
  28933. +
  28934. + ret = of_address_to_resource(node, 0, &res);
  28935. + if (ret)
  28936. + goto put_node;
  28937. +
  28938. + base->pbase = res.start;
  28939. + base->vbase = ioremap(res.start, resource_size(&res));
  28940. + if (!base->vbase)
  28941. + ret = -ENOMEM;
  28942. +
  28943. +put_node:
  28944. + of_node_put(node);
  28945. +out:
  28946. + return ret;
  28947. +}
  28948. +
  28949. +static int __init imx6q_ocram_suspend_init(const struct imx6_pm_socdata
  28950. + *socdata)
  28951. +{
  28952. + phys_addr_t ocram_pbase;
  28953. + struct device_node *node;
  28954. + struct platform_device *pdev;
  28955. + struct imx6_cpu_pm_info *pm_info;
  28956. + struct gen_pool *ocram_pool;
  28957. + unsigned long ocram_base;
  28958. + int i, ret = 0;
  28959. + const u32 *mmdc_offset_array;
  28960. +
  28961. + if (!socdata) {
  28962. + pr_warn("%s: invalid argument!\n", __func__);
  28963. + return -EINVAL;
  28964. + }
  28965. +
  28966. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  28967. + if (!node) {
  28968. + pr_warn("%s: failed to find ocram node!\n", __func__);
  28969. + return -ENODEV;
  28970. + }
  28971. +
  28972. + pdev = of_find_device_by_node(node);
  28973. + if (!pdev) {
  28974. + pr_warn("%s: failed to find ocram device!\n", __func__);
  28975. + ret = -ENODEV;
  28976. + goto put_node;
  28977. + }
  28978. +
  28979. + ocram_pool = dev_get_gen_pool(&pdev->dev);
  28980. + if (!ocram_pool) {
  28981. + pr_warn("%s: ocram pool unavailable!\n", __func__);
  28982. + ret = -ENODEV;
  28983. + goto put_node;
  28984. + }
  28985. +
  28986. + ocram_base = gen_pool_alloc(ocram_pool, MX6Q_SUSPEND_OCRAM_SIZE);
  28987. + if (!ocram_base) {
  28988. + pr_warn("%s: unable to alloc ocram!\n", __func__);
  28989. + ret = -ENOMEM;
  28990. + goto put_node;
  28991. + }
  28992. +
  28993. + ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);
  28994. +
  28995. + suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
  28996. + MX6Q_SUSPEND_OCRAM_SIZE, false);
  28997. +
  28998. + pm_info = suspend_ocram_base;
  28999. + pm_info->pbase = ocram_pbase;
  29000. + pm_info->resume_addr = virt_to_phys(v7_cpu_resume);
  29001. + pm_info->pm_info_size = sizeof(*pm_info);
  29002. +
  29003. + /*
  29004. + * ccm physical address is not used by asm code currently,
  29005. + * so get ccm virtual address directly, as we already have
  29006. + * it from ccm driver.
  29007. + */
  29008. + pm_info->ccm_base.vbase = ccm_base;
  29009. +
  29010. + ret = imx6_pm_get_base(&pm_info->mmdc_base, socdata->mmdc_compat);
  29011. + if (ret) {
  29012. + pr_warn("%s: failed to get mmdc base %d!\n", __func__, ret);
  29013. + goto put_node;
  29014. + }
  29015. +
  29016. + ret = imx6_pm_get_base(&pm_info->src_base, socdata->src_compat);
  29017. + if (ret) {
  29018. + pr_warn("%s: failed to get src base %d!\n", __func__, ret);
  29019. + goto src_map_failed;
  29020. + }
  29021. +
  29022. + ret = imx6_pm_get_base(&pm_info->iomuxc_base, socdata->iomuxc_compat);
  29023. + if (ret) {
  29024. + pr_warn("%s: failed to get iomuxc base %d!\n", __func__, ret);
  29025. + goto iomuxc_map_failed;
  29026. + }
  29027. +
  29028. + ret = imx6_pm_get_base(&pm_info->gpc_base, socdata->gpc_compat);
  29029. + if (ret) {
  29030. + pr_warn("%s: failed to get gpc base %d!\n", __func__, ret);
  29031. + goto gpc_map_failed;
  29032. + }
  29033. +
  29034. + ret = imx6_pm_get_base(&pm_info->l2_base, "arm,pl310-cache");
  29035. + if (ret) {
  29036. + pr_warn("%s: failed to get pl310-cache base %d!\n",
  29037. + __func__, ret);
  29038. + goto pl310_cache_map_failed;
  29039. + }
  29040. +
  29041. + pm_info->cpu_type = socdata->cpu_type;
  29042. + pm_info->mmdc_io_num = socdata->mmdc_io_num;
  29043. + mmdc_offset_array = socdata->mmdc_io_offset;
  29044. +
  29045. + for (i = 0; i < pm_info->mmdc_io_num; i++) {
  29046. + pm_info->mmdc_io_val[i][0] =
  29047. + mmdc_offset_array[i];
  29048. + pm_info->mmdc_io_val[i][1] =
  29049. + readl_relaxed(pm_info->iomuxc_base.vbase +
  29050. + mmdc_offset_array[i]);
  29051. + }
  29052. +
  29053. + imx6_suspend_in_ocram_fn = fncpy(
  29054. + suspend_ocram_base + sizeof(*pm_info),
  29055. + &imx6_suspend,
  29056. + MX6Q_SUSPEND_OCRAM_SIZE - sizeof(*pm_info));
  29057. +
  29058. + goto put_node;
  29059. +
  29060. +pl310_cache_map_failed:
  29061. + iounmap(&pm_info->gpc_base.vbase);
  29062. +gpc_map_failed:
  29063. + iounmap(&pm_info->iomuxc_base.vbase);
  29064. +iomuxc_map_failed:
  29065. + iounmap(&pm_info->src_base.vbase);
  29066. +src_map_failed:
  29067. + iounmap(&pm_info->mmdc_base.vbase);
  29068. +put_node:
  29069. + of_node_put(node);
  29070. +
  29071. + return ret;
  29072. +}
  29073. +
  29074. +static void __init imx6_pm_common_init(const struct imx6_pm_socdata
  29075. + *socdata)
  29076. +{
  29077. + struct regmap *gpr;
  29078. + int ret;
  29079. +
  29080. + WARN_ON(!ccm_base);
  29081. +
  29082. + ret = imx6q_ocram_suspend_init(socdata);
  29083. + if (ret)
  29084. + pr_warn("%s: failed to initialize ocram suspend %d!\n",
  29085. + __func__, ret);
  29086. +
  29087. + /*
  29088. + * This is for SW workaround step #1 of ERR007265, see comments
  29089. + * in imx6q_set_lpm for details of this errata.
  29090. + * Force IOMUXC irq pending, so that the interrupt to GPC can be
  29091. + * used to deassert dsm_request signal when the signal gets
  29092. + * asserted unexpectedly.
  29093. + */
  29094. + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  29095. + if (!IS_ERR(gpr))
  29096. + regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT_MASK,
  29097. + IMX6Q_GPR1_GINT_MASK);
  29098. +
  29099. +
  29100. + suspend_set_ops(&imx6q_pm_ops);
  29101. +}
  29102. +
  29103. +void __init imx6q_pm_init(void)
  29104. +{
  29105. + imx6_pm_common_init(&imx6q_pm_data);
  29106. +}
  29107. +
  29108. +void __init imx6dl_pm_init(void)
  29109. +{
  29110. + imx6_pm_common_init(NULL);
  29111. +}
  29112. +
  29113. +void __init imx6sl_pm_init(void)
  29114. +{
  29115. + imx6_pm_common_init(NULL);
  29116. +}
  29117. diff -Nur linux-3.14.15/arch/arm/mach-imx/pm-imx6q.c linux-linaro-stable-mx6/arch/arm/mach-imx/pm-imx6q.c
  29118. --- linux-3.14.15/arch/arm/mach-imx/pm-imx6q.c 2014-07-31 23:51:43.000000000 +0200
  29119. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/pm-imx6q.c 1970-01-01 01:00:00.000000000 +0100
  29120. @@ -1,241 +0,0 @@
  29121. -/*
  29122. - * Copyright 2011-2013 Freescale Semiconductor, Inc.
  29123. - * Copyright 2011 Linaro Ltd.
  29124. - *
  29125. - * The code contained herein is licensed under the GNU General Public
  29126. - * License. You may obtain a copy of the GNU General Public License
  29127. - * Version 2 or later at the following locations:
  29128. - *
  29129. - * http://www.opensource.org/licenses/gpl-license.html
  29130. - * http://www.gnu.org/copyleft/gpl.html
  29131. - */
  29132. -
  29133. -#include <linux/delay.h>
  29134. -#include <linux/init.h>
  29135. -#include <linux/io.h>
  29136. -#include <linux/irq.h>
  29137. -#include <linux/mfd/syscon.h>
  29138. -#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  29139. -#include <linux/of.h>
  29140. -#include <linux/of_address.h>
  29141. -#include <linux/regmap.h>
  29142. -#include <linux/suspend.h>
  29143. -#include <asm/cacheflush.h>
  29144. -#include <asm/proc-fns.h>
  29145. -#include <asm/suspend.h>
  29146. -#include <asm/hardware/cache-l2x0.h>
  29147. -
  29148. -#include "common.h"
  29149. -#include "hardware.h"
  29150. -
  29151. -#define CCR 0x0
  29152. -#define BM_CCR_WB_COUNT (0x7 << 16)
  29153. -#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
  29154. -#define BM_CCR_RBC_EN (0x1 << 27)
  29155. -
  29156. -#define CLPCR 0x54
  29157. -#define BP_CLPCR_LPM 0
  29158. -#define BM_CLPCR_LPM (0x3 << 0)
  29159. -#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
  29160. -#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
  29161. -#define BM_CLPCR_SBYOS (0x1 << 6)
  29162. -#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
  29163. -#define BM_CLPCR_VSTBY (0x1 << 8)
  29164. -#define BP_CLPCR_STBY_COUNT 9
  29165. -#define BM_CLPCR_STBY_COUNT (0x3 << 9)
  29166. -#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
  29167. -#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
  29168. -#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
  29169. -#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
  29170. -#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
  29171. -#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
  29172. -#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
  29173. -#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
  29174. -#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
  29175. -#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
  29176. -#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
  29177. -
  29178. -#define CGPR 0x64
  29179. -#define BM_CGPR_CHICKEN_BIT (0x1 << 17)
  29180. -
  29181. -static void __iomem *ccm_base;
  29182. -
  29183. -void imx6q_set_chicken_bit(void)
  29184. -{
  29185. - u32 val = readl_relaxed(ccm_base + CGPR);
  29186. -
  29187. - val |= BM_CGPR_CHICKEN_BIT;
  29188. - writel_relaxed(val, ccm_base + CGPR);
  29189. -}
  29190. -
  29191. -static void imx6q_enable_rbc(bool enable)
  29192. -{
  29193. - u32 val;
  29194. -
  29195. - /*
  29196. - * need to mask all interrupts in GPC before
  29197. - * operating RBC configurations
  29198. - */
  29199. - imx_gpc_mask_all();
  29200. -
  29201. - /* configure RBC enable bit */
  29202. - val = readl_relaxed(ccm_base + CCR);
  29203. - val &= ~BM_CCR_RBC_EN;
  29204. - val |= enable ? BM_CCR_RBC_EN : 0;
  29205. - writel_relaxed(val, ccm_base + CCR);
  29206. -
  29207. - /* configure RBC count */
  29208. - val = readl_relaxed(ccm_base + CCR);
  29209. - val &= ~BM_CCR_RBC_BYPASS_COUNT;
  29210. - val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
  29211. - writel(val, ccm_base + CCR);
  29212. -
  29213. - /*
  29214. - * need to delay at least 2 cycles of CKIL(32K)
  29215. - * due to hardware design requirement, which is
  29216. - * ~61us, here we use 65us for safe
  29217. - */
  29218. - udelay(65);
  29219. -
  29220. - /* restore GPC interrupt mask settings */
  29221. - imx_gpc_restore_all();
  29222. -}
  29223. -
  29224. -static void imx6q_enable_wb(bool enable)
  29225. -{
  29226. - u32 val;
  29227. -
  29228. - /* configure well bias enable bit */
  29229. - val = readl_relaxed(ccm_base + CLPCR);
  29230. - val &= ~BM_CLPCR_WB_PER_AT_LPM;
  29231. - val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
  29232. - writel_relaxed(val, ccm_base + CLPCR);
  29233. -
  29234. - /* configure well bias count */
  29235. - val = readl_relaxed(ccm_base + CCR);
  29236. - val &= ~BM_CCR_WB_COUNT;
  29237. - val |= enable ? BM_CCR_WB_COUNT : 0;
  29238. - writel_relaxed(val, ccm_base + CCR);
  29239. -}
  29240. -
  29241. -int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
  29242. -{
  29243. - struct irq_desc *iomuxc_irq_desc;
  29244. - u32 val = readl_relaxed(ccm_base + CLPCR);
  29245. -
  29246. - val &= ~BM_CLPCR_LPM;
  29247. - switch (mode) {
  29248. - case WAIT_CLOCKED:
  29249. - break;
  29250. - case WAIT_UNCLOCKED:
  29251. - val |= 0x1 << BP_CLPCR_LPM;
  29252. - val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
  29253. - break;
  29254. - case STOP_POWER_ON:
  29255. - val |= 0x2 << BP_CLPCR_LPM;
  29256. - break;
  29257. - case WAIT_UNCLOCKED_POWER_OFF:
  29258. - val |= 0x1 << BP_CLPCR_LPM;
  29259. - val &= ~BM_CLPCR_VSTBY;
  29260. - val &= ~BM_CLPCR_SBYOS;
  29261. - break;
  29262. - case STOP_POWER_OFF:
  29263. - val |= 0x2 << BP_CLPCR_LPM;
  29264. - val |= 0x3 << BP_CLPCR_STBY_COUNT;
  29265. - val |= BM_CLPCR_VSTBY;
  29266. - val |= BM_CLPCR_SBYOS;
  29267. - if (cpu_is_imx6sl()) {
  29268. - val |= BM_CLPCR_BYPASS_PMIC_READY;
  29269. - val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
  29270. - } else {
  29271. - val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  29272. - }
  29273. - break;
  29274. - default:
  29275. - return -EINVAL;
  29276. - }
  29277. -
  29278. - /*
  29279. - * ERR007265: CCM: When improper low-power sequence is used,
  29280. - * the SoC enters low power mode before the ARM core executes WFI.
  29281. - *
  29282. - * Software workaround:
  29283. - * 1) Software should trigger IRQ #32 (IOMUX) to be always pending
  29284. - * by setting IOMUX_GPR1_GINT.
  29285. - * 2) Software should then unmask IRQ #32 in GPC before setting CCM
  29286. - * Low-Power mode.
  29287. - * 3) Software should mask IRQ #32 right after CCM Low-Power mode
  29288. - * is set (set bits 0-1 of CCM_CLPCR).
  29289. - */
  29290. - iomuxc_irq_desc = irq_to_desc(32);
  29291. - imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data);
  29292. - writel_relaxed(val, ccm_base + CLPCR);
  29293. - imx_gpc_irq_mask(&iomuxc_irq_desc->irq_data);
  29294. -
  29295. - return 0;
  29296. -}
  29297. -
  29298. -static int imx6q_suspend_finish(unsigned long val)
  29299. -{
  29300. - cpu_do_idle();
  29301. - return 0;
  29302. -}
  29303. -
  29304. -static int imx6q_pm_enter(suspend_state_t state)
  29305. -{
  29306. - switch (state) {
  29307. - case PM_SUSPEND_MEM:
  29308. - imx6q_set_lpm(STOP_POWER_OFF);
  29309. - imx6q_enable_wb(true);
  29310. - imx6q_enable_rbc(true);
  29311. - imx_gpc_pre_suspend();
  29312. - imx_anatop_pre_suspend();
  29313. - imx_set_cpu_jump(0, v7_cpu_resume);
  29314. - /* Zzz ... */
  29315. - cpu_suspend(0, imx6q_suspend_finish);
  29316. - if (cpu_is_imx6q() || cpu_is_imx6dl())
  29317. - imx_smp_prepare();
  29318. - imx_anatop_post_resume();
  29319. - imx_gpc_post_resume();
  29320. - imx6q_enable_rbc(false);
  29321. - imx6q_enable_wb(false);
  29322. - imx6q_set_lpm(WAIT_CLOCKED);
  29323. - break;
  29324. - default:
  29325. - return -EINVAL;
  29326. - }
  29327. -
  29328. - return 0;
  29329. -}
  29330. -
  29331. -static const struct platform_suspend_ops imx6q_pm_ops = {
  29332. - .enter = imx6q_pm_enter,
  29333. - .valid = suspend_valid_only_mem,
  29334. -};
  29335. -
  29336. -void __init imx6q_pm_set_ccm_base(void __iomem *base)
  29337. -{
  29338. - ccm_base = base;
  29339. -}
  29340. -
  29341. -void __init imx6q_pm_init(void)
  29342. -{
  29343. - struct regmap *gpr;
  29344. -
  29345. - WARN_ON(!ccm_base);
  29346. -
  29347. - /*
  29348. - * This is for SW workaround step #1 of ERR007265, see comments
  29349. - * in imx6q_set_lpm for details of this errata.
  29350. - * Force IOMUXC irq pending, so that the interrupt to GPC can be
  29351. - * used to deassert dsm_request signal when the signal gets
  29352. - * asserted unexpectedly.
  29353. - */
  29354. - gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  29355. - if (!IS_ERR(gpr))
  29356. - regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
  29357. - IMX6Q_GPR1_GINT);
  29358. -
  29359. -
  29360. - suspend_set_ops(&imx6q_pm_ops);
  29361. -}
  29362. diff -Nur linux-3.14.15/arch/arm/mach-imx/suspend-imx6.S linux-linaro-stable-mx6/arch/arm/mach-imx/suspend-imx6.S
  29363. --- linux-3.14.15/arch/arm/mach-imx/suspend-imx6.S 1970-01-01 01:00:00.000000000 +0100
  29364. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/suspend-imx6.S 2014-08-20 19:31:40.092843095 +0200
  29365. @@ -0,0 +1,306 @@
  29366. +/*
  29367. + * Copyright 2014 Freescale Semiconductor, Inc.
  29368. + *
  29369. + * The code contained herein is licensed under the GNU General Public
  29370. + * License. You may obtain a copy of the GNU General Public License
  29371. + * Version 2 or later at the following locations:
  29372. + *
  29373. + * http://www.opensource.org/licenses/gpl-license.html
  29374. + * http://www.gnu.org/copyleft/gpl.html
  29375. + */
  29376. +
  29377. +#include <linux/linkage.h>
  29378. +#include <asm/asm-offsets.h>
  29379. +#include <asm/hardware/cache-l2x0.h>
  29380. +#include "hardware.h"
  29381. +
  29382. +/*
  29383. + * ==================== low level suspend ====================
  29384. + *
  29385. + * Better to follow below rules to use ARM registers:
  29386. + * r0: pm_info structure address;
  29387. + * r1 ~ r4: for saving pm_info members;
  29388. + * r5 ~ r10: free registers;
  29389. + * r11: io base address.
  29390. + *
  29391. + * suspend ocram space layout:
  29392. + * ======================== high address ======================
  29393. + * .
  29394. + * .
  29395. + * .
  29396. + * ^
  29397. + * ^
  29398. + * ^
  29399. + * imx6_suspend code
  29400. + * PM_INFO structure(imx6_cpu_pm_info)
  29401. + * ======================== low address =======================
  29402. + */
  29403. +
  29404. +/*
  29405. + * Below offsets are based on struct imx6_cpu_pm_info
  29406. + * which defined in arch/arm/mach-imx/pm-imx6q.c, this
  29407. + * structure contains necessary pm info for low level
  29408. + * suspend related code.
  29409. + */
  29410. +#define PM_INFO_PBASE_OFFSET 0x0
  29411. +#define PM_INFO_RESUME_ADDR_OFFSET 0x4
  29412. +#define PM_INFO_CPU_TYPE_OFFSET 0x8
  29413. +#define PM_INFO_PM_INFO_SIZE_OFFSET 0xC
  29414. +#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
  29415. +#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
  29416. +#define PM_INFO_MX6Q_SRC_P_OFFSET 0x18
  29417. +#define PM_INFO_MX6Q_SRC_V_OFFSET 0x1C
  29418. +#define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x20
  29419. +#define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x24
  29420. +#define PM_INFO_MX6Q_CCM_P_OFFSET 0x28
  29421. +#define PM_INFO_MX6Q_CCM_V_OFFSET 0x2C
  29422. +#define PM_INFO_MX6Q_GPC_P_OFFSET 0x30
  29423. +#define PM_INFO_MX6Q_GPC_V_OFFSET 0x34
  29424. +#define PM_INFO_MX6Q_L2_P_OFFSET 0x38
  29425. +#define PM_INFO_MX6Q_L2_V_OFFSET 0x3C
  29426. +#define PM_INFO_MMDC_IO_NUM_OFFSET 0x40
  29427. +#define PM_INFO_MMDC_IO_VAL_OFFSET 0x44
  29428. +
  29429. +#define MX6Q_SRC_GPR1 0x20
  29430. +#define MX6Q_SRC_GPR2 0x24
  29431. +#define MX6Q_MMDC_MAPSR 0x404
  29432. +#define MX6Q_GPC_IMR1 0x08
  29433. +#define MX6Q_GPC_IMR2 0x0c
  29434. +#define MX6Q_GPC_IMR3 0x10
  29435. +#define MX6Q_GPC_IMR4 0x14
  29436. +#define MX6Q_CCM_CCR 0x0
  29437. +
  29438. + .align 3
  29439. +
  29440. + .macro sync_l2_cache
  29441. +
  29442. + /* sync L2 cache to drain L2's buffers to DRAM. */
  29443. +#ifdef CONFIG_CACHE_L2X0
  29444. + ldr r11, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
  29445. + mov r6, #0x0
  29446. + str r6, [r11, #L2X0_CACHE_SYNC]
  29447. +1:
  29448. + ldr r6, [r11, #L2X0_CACHE_SYNC]
  29449. + ands r6, r6, #0x1
  29450. + bne 1b
  29451. +#endif
  29452. +
  29453. + .endm
  29454. +
  29455. + .macro resume_mmdc
  29456. +
  29457. + /* restore MMDC IO */
  29458. + cmp r5, #0x0
  29459. + ldreq r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
  29460. + ldrne r11, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
  29461. +
  29462. + ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
  29463. + ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
  29464. + add r7, r7, r0
  29465. +1:
  29466. + ldr r8, [r7], #0x4
  29467. + ldr r9, [r7], #0x4
  29468. + str r9, [r11, r8]
  29469. + subs r6, r6, #0x1
  29470. + bne 1b
  29471. +
  29472. + cmp r5, #0x0
  29473. + ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
  29474. + ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
  29475. +
  29476. + /* let DDR out of self-refresh */
  29477. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29478. + bic r7, r7, #(1 << 21)
  29479. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29480. +2:
  29481. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29482. + ands r7, r7, #(1 << 25)
  29483. + bne 2b
  29484. +
  29485. + /* enable DDR auto power saving */
  29486. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29487. + bic r7, r7, #0x1
  29488. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29489. +
  29490. + .endm
  29491. +
  29492. +ENTRY(imx6_suspend)
  29493. + ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
  29494. + ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
  29495. + ldr r3, [r0, #PM_INFO_CPU_TYPE_OFFSET]
  29496. + ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
  29497. +
  29498. + /*
  29499. + * counting the resume address in iram
  29500. + * to set it in SRC register.
  29501. + */
  29502. + ldr r6, =imx6_suspend
  29503. + ldr r7, =resume
  29504. + sub r7, r7, r6
  29505. + add r8, r1, r4
  29506. + add r9, r8, r7
  29507. +
  29508. + /*
  29509. + * make sure TLB contain the addr we want,
  29510. + * as we will access them after MMDC IO floated.
  29511. + */
  29512. +
  29513. + ldr r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
  29514. + ldr r6, [r11, #0x0]
  29515. + ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
  29516. + ldr r6, [r11, #0x0]
  29517. + ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
  29518. + ldr r6, [r11, #0x0]
  29519. +
  29520. + /* use r11 to store the IO address */
  29521. + ldr r11, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
  29522. + /* store physical resume addr and pm_info address. */
  29523. + str r9, [r11, #MX6Q_SRC_GPR1]
  29524. + str r1, [r11, #MX6Q_SRC_GPR2]
  29525. +
  29526. + /* need to sync L2 cache before DSM. */
  29527. + sync_l2_cache
  29528. +
  29529. + ldr r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
  29530. + /*
  29531. + * put DDR explicitly into self-refresh and
  29532. + * disable automatic power savings.
  29533. + */
  29534. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29535. + orr r7, r7, #0x1
  29536. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29537. +
  29538. + /* make the DDR explicitly enter self-refresh. */
  29539. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29540. + orr r7, r7, #(1 << 21)
  29541. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29542. +
  29543. +poll_dvfs_set:
  29544. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29545. + ands r7, r7, #(1 << 25)
  29546. + beq poll_dvfs_set
  29547. +
  29548. + ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
  29549. + ldr r6, =0x0
  29550. + ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
  29551. + ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
  29552. + add r8, r8, r0
  29553. +set_mmdc_io_lpm:
  29554. + ldr r9, [r8], #0x8
  29555. + str r6, [r11, r9]
  29556. + subs r7, r7, #0x1
  29557. + bne set_mmdc_io_lpm
  29558. +
  29559. + /*
  29560. + * mask all GPC interrupts before
  29561. + * enabling the RBC counters to
  29562. + * avoid the counter starting too
  29563. + * early if an interupt is already
  29564. + * pending.
  29565. + */
  29566. + ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
  29567. + ldr r6, [r11, #MX6Q_GPC_IMR1]
  29568. + ldr r7, [r11, #MX6Q_GPC_IMR2]
  29569. + ldr r8, [r11, #MX6Q_GPC_IMR3]
  29570. + ldr r9, [r11, #MX6Q_GPC_IMR4]
  29571. +
  29572. + ldr r10, =0xffffffff
  29573. + str r10, [r11, #MX6Q_GPC_IMR1]
  29574. + str r10, [r11, #MX6Q_GPC_IMR2]
  29575. + str r10, [r11, #MX6Q_GPC_IMR3]
  29576. + str r10, [r11, #MX6Q_GPC_IMR4]
  29577. +
  29578. + /*
  29579. + * enable the RBC bypass counter here
  29580. + * to hold off the interrupts. RBC counter
  29581. + * = 32 (1ms), Minimum RBC delay should be
  29582. + * 400us for the analog LDOs to power down.
  29583. + */
  29584. + ldr r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
  29585. + ldr r10, [r11, #MX6Q_CCM_CCR]
  29586. + bic r10, r10, #(0x3f << 21)
  29587. + orr r10, r10, #(0x20 << 21)
  29588. + str r10, [r11, #MX6Q_CCM_CCR]
  29589. +
  29590. + /* enable the counter. */
  29591. + ldr r10, [r11, #MX6Q_CCM_CCR]
  29592. + orr r10, r10, #(0x1 << 27)
  29593. + str r10, [r11, #MX6Q_CCM_CCR]
  29594. +
  29595. + /* unmask all the GPC interrupts. */
  29596. + ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
  29597. + str r6, [r11, #MX6Q_GPC_IMR1]
  29598. + str r7, [r11, #MX6Q_GPC_IMR2]
  29599. + str r8, [r11, #MX6Q_GPC_IMR3]
  29600. + str r9, [r11, #MX6Q_GPC_IMR4]
  29601. +
  29602. + /*
  29603. + * now delay for a short while (3usec)
  29604. + * ARM is at 1GHz at this point
  29605. + * so a short loop should be enough.
  29606. + * this delay is required to ensure that
  29607. + * the RBC counter can start counting in
  29608. + * case an interrupt is already pending
  29609. + * or in case an interrupt arrives just
  29610. + * as ARM is about to assert DSM_request.
  29611. + */
  29612. + ldr r6, =2000
  29613. +rbc_loop:
  29614. + subs r6, r6, #0x1
  29615. + bne rbc_loop
  29616. +
  29617. + /* Zzz, enter stop mode */
  29618. + wfi
  29619. + nop
  29620. + nop
  29621. + nop
  29622. + nop
  29623. +
  29624. + /*
  29625. + * run to here means there is pending
  29626. + * wakeup source, system should auto
  29627. + * resume, we need to restore MMDC IO first
  29628. + */
  29629. + mov r5, #0x0
  29630. + resume_mmdc
  29631. +
  29632. + /* return to suspend finish */
  29633. + mov pc, lr
  29634. +
  29635. +resume:
  29636. + /* invalidate L1 I-cache first */
  29637. + mov r6, #0x0
  29638. + mcr p15, 0, r6, c7, c5, 0
  29639. + mcr p15, 0, r6, c7, c5, 6
  29640. + /* enable the Icache and branch prediction */
  29641. + mov r6, #0x1800
  29642. + mcr p15, 0, r6, c1, c0, 0
  29643. + isb
  29644. +
  29645. + /* get physical resume address from pm_info. */
  29646. + ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
  29647. + /* clear core0's entry and parameter */
  29648. + ldr r11, [r0, #PM_INFO_MX6Q_SRC_P_OFFSET]
  29649. + mov r7, #0x0
  29650. + str r7, [r11, #MX6Q_SRC_GPR1]
  29651. + str r7, [r11, #MX6Q_SRC_GPR2]
  29652. +
  29653. + mov r5, #0x1
  29654. + resume_mmdc
  29655. +
  29656. + mov pc, lr
  29657. +ENDPROC(imx6_suspend)
  29658. +
  29659. +/*
  29660. + * The following code must assume it is running from physical address
  29661. + * where absolute virtual addresses to the data section have to be
  29662. + * turned into relative ones.
  29663. + */
  29664. +
  29665. +ENTRY(v7_cpu_resume)
  29666. + bl v7_invalidate_l1
  29667. +#ifdef CONFIG_CACHE_L2X0
  29668. + bl l2c310_early_resume
  29669. +#endif
  29670. + b cpu_resume
  29671. +ENDPROC(v7_cpu_resume)
  29672. diff -Nur linux-3.14.15/arch/arm/mach-imx/system.c linux-linaro-stable-mx6/arch/arm/mach-imx/system.c
  29673. --- linux-3.14.15/arch/arm/mach-imx/system.c 2014-07-31 23:51:43.000000000 +0200
  29674. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/system.c 2014-08-20 19:31:40.092843095 +0200
  29675. @@ -34,6 +34,7 @@
  29676. static void __iomem *wdog_base;
  29677. static struct clk *wdog_clk;
  29678. +static u32 wdog_source = 1; /* use WDOG1 default */
  29679. /*
  29680. * Reset the system. It is called by machine_restart().
  29681. @@ -47,6 +48,15 @@
  29682. if (cpu_is_mx1())
  29683. wcr_enable = (1 << 0);
  29684. + /*
  29685. + * Some i.MX6 boards use WDOG2 to reset external pmic in bypass mode,
  29686. + * so do WDOG2 reset here. Do not set SRS, since we will
  29687. + * trigger external POR later. Use WDOG1 to reset in ldo-enable
  29688. + * mode. You can set it by "fsl,wdog-reset" in dts.
  29689. + */
  29690. + else if (wdog_source == 2 && (cpu_is_imx6q() || cpu_is_imx6dl() ||
  29691. + cpu_is_imx6sl()))
  29692. + wcr_enable = 0x14;
  29693. else
  29694. wcr_enable = (1 << 2);
  29695. @@ -90,12 +100,29 @@
  29696. void __init mxc_arch_reset_init_dt(void)
  29697. {
  29698. - struct device_node *np;
  29699. + struct device_node *np = NULL;
  29700. +
  29701. + if (cpu_is_imx6q() || cpu_is_imx6dl())
  29702. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
  29703. + else if (cpu_is_imx6sl())
  29704. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpc");
  29705. +
  29706. + if (np)
  29707. + of_property_read_u32(np, "fsl,wdog-reset", &wdog_source);
  29708. + pr_info("Use WDOG%d as reset source\n", wdog_source);
  29709. np = of_find_compatible_node(NULL, NULL, "fsl,imx21-wdt");
  29710. wdog_base = of_iomap(np, 0);
  29711. WARN_ON(!wdog_base);
  29712. + /* Some i.MX6 boards use WDOG2 to reset board in ldo-bypass mode */
  29713. + if (wdog_source == 2 && (cpu_is_imx6q() || cpu_is_imx6dl() ||
  29714. + cpu_is_imx6sl())) {
  29715. + np = of_find_compatible_node(np, NULL, "fsl,imx21-wdt");
  29716. + wdog_base = of_iomap(np, 0);
  29717. + WARN_ON(!wdog_base);
  29718. + }
  29719. +
  29720. wdog_clk = of_clk_get(np, 0);
  29721. if (IS_ERR(wdog_clk)) {
  29722. pr_warn("%s: failed to get wdog clock\n", __func__);
  29723. @@ -124,7 +151,7 @@
  29724. }
  29725. /* Configure the L2 PREFETCH and POWER registers */
  29726. - val = readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
  29727. + val = readl_relaxed(l2x0_base + L310_PREFETCH_CTRL);
  29728. val |= 0x70800000;
  29729. /*
  29730. * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
  29731. @@ -137,14 +164,12 @@
  29732. */
  29733. if (cpu_is_imx6q())
  29734. val &= ~(1 << 30 | 1 << 23);
  29735. - writel_relaxed(val, l2x0_base + L2X0_PREFETCH_CTRL);
  29736. - val = L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN;
  29737. - writel_relaxed(val, l2x0_base + L2X0_POWER_CTRL);
  29738. + writel_relaxed(val, l2x0_base + L310_PREFETCH_CTRL);
  29739. iounmap(l2x0_base);
  29740. of_node_put(np);
  29741. out:
  29742. - l2x0_of_init(0, ~0UL);
  29743. + l2x0_of_init(0, ~0);
  29744. }
  29745. #endif
  29746. diff -Nur linux-3.14.15/arch/arm/mach-imx/time.c linux-linaro-stable-mx6/arch/arm/mach-imx/time.c
  29747. --- linux-3.14.15/arch/arm/mach-imx/time.c 2014-07-31 23:51:43.000000000 +0200
  29748. +++ linux-linaro-stable-mx6/arch/arm/mach-imx/time.c 2014-08-20 19:31:40.092843095 +0200
  29749. @@ -60,7 +60,11 @@
  29750. #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */
  29751. #define V2_TCTL_CLK_IPG (1 << 6)
  29752. #define V2_TCTL_CLK_PER (2 << 6)
  29753. +#define V2_TCTL_CLK_OSC_DIV8 (5 << 6)
  29754. +#define V2_TCTL_CLK_OSC (7 << 6)
  29755. +#define V2_TCTL_24MEN (1 << 10)
  29756. #define V2_TCTL_FRR (1 << 9)
  29757. +#define V2_TPRER_PRE24M 12
  29758. #define V2_IR 0x0c
  29759. #define V2_TSTAT 0x08
  29760. #define V2_TSTAT_OF1 (1 << 0)
  29761. @@ -277,11 +281,20 @@
  29762. void __init mxc_timer_init(void __iomem *base, int irq)
  29763. {
  29764. - uint32_t tctl_val;
  29765. + uint32_t tctl_val, tprer_val;
  29766. struct clk *timer_clk;
  29767. struct clk *timer_ipg_clk;
  29768. - timer_clk = clk_get_sys("imx-gpt.0", "per");
  29769. + /*
  29770. + * gpt clk source from 24M OSC on imx6q > TO1.0 and
  29771. + * imx6dl, others from per clk.
  29772. + */
  29773. + if ((cpu_is_imx6q() && imx_get_soc_revision() > IMX_CHIP_REVISION_1_0)
  29774. + || cpu_is_imx6dl())
  29775. + timer_clk = clk_get_sys("imx-gpt.0", "gpt_3m");
  29776. + else
  29777. + timer_clk = clk_get_sys("imx-gpt.0", "per");
  29778. +
  29779. if (IS_ERR(timer_clk)) {
  29780. pr_err("i.MX timer: unable to get clk\n");
  29781. return;
  29782. @@ -302,10 +315,24 @@
  29783. __raw_writel(0, timer_base + MXC_TCTL);
  29784. __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
  29785. - if (timer_is_v2())
  29786. - tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
  29787. - else
  29788. + if (timer_is_v2()) {
  29789. + if ((cpu_is_imx6q() && imx_get_soc_revision() >
  29790. + IMX_CHIP_REVISION_1_0) || cpu_is_imx6dl()) {
  29791. + tctl_val = V2_TCTL_CLK_OSC_DIV8 | V2_TCTL_FRR |
  29792. + V2_TCTL_WAITEN | MXC_TCTL_TEN;
  29793. + if (cpu_is_imx6dl()) {
  29794. + /* 24 / 8 = 3 MHz */
  29795. + tprer_val = 7 << V2_TPRER_PRE24M;
  29796. + __raw_writel(tprer_val, timer_base + MXC_TPRER);
  29797. + tctl_val |= V2_TCTL_24MEN;
  29798. + }
  29799. + } else {
  29800. + tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR |
  29801. + V2_TCTL_WAITEN | MXC_TCTL_TEN;
  29802. + }
  29803. + } else {
  29804. tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
  29805. + }
  29806. __raw_writel(tctl_val, timer_base + MXC_TCTL);
  29807. diff -Nur linux-3.14.15/arch/arm/mach-nomadik/cpu-8815.c linux-linaro-stable-mx6/arch/arm/mach-nomadik/cpu-8815.c
  29808. --- linux-3.14.15/arch/arm/mach-nomadik/cpu-8815.c 2014-07-31 23:51:43.000000000 +0200
  29809. +++ linux-linaro-stable-mx6/arch/arm/mach-nomadik/cpu-8815.c 2014-08-20 19:31:40.228843679 +0200
  29810. @@ -147,7 +147,7 @@
  29811. {
  29812. #ifdef CONFIG_CACHE_L2X0
  29813. /* At full speed latency must be >=2, so 0x249 in low bits */
  29814. - l2x0_of_init(0x00730249, 0xfe000fff);
  29815. + l2x0_of_init(0x00700249, 0xfe0fefff);
  29816. #endif
  29817. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  29818. }
  29819. diff -Nur linux-3.14.15/arch/arm/mach-omap2/common.h linux-linaro-stable-mx6/arch/arm/mach-omap2/common.h
  29820. --- linux-3.14.15/arch/arm/mach-omap2/common.h 2014-07-31 23:51:43.000000000 +0200
  29821. +++ linux-linaro-stable-mx6/arch/arm/mach-omap2/common.h 2014-08-20 19:31:40.268843852 +0200
  29822. @@ -91,6 +91,7 @@
  29823. extern void omap3_secure_sync32k_timer_init(void);
  29824. extern void omap3_gptimer_timer_init(void);
  29825. extern void omap4_local_timer_init(void);
  29826. +int omap_l2_cache_init(void);
  29827. extern void omap5_realtime_timer_init(void);
  29828. void omap2420_init_early(void);
  29829. diff -Nur linux-3.14.15/arch/arm/mach-omap2/io.c linux-linaro-stable-mx6/arch/arm/mach-omap2/io.c
  29830. --- linux-3.14.15/arch/arm/mach-omap2/io.c 2014-07-31 23:51:43.000000000 +0200
  29831. +++ linux-linaro-stable-mx6/arch/arm/mach-omap2/io.c 2014-08-20 19:31:40.280843902 +0200
  29832. @@ -608,6 +608,7 @@
  29833. am43xx_clockdomains_init();
  29834. am43xx_hwmod_init();
  29835. omap_hwmod_init_postsetup();
  29836. + omap_l2_cache_init();
  29837. omap_clk_soc_init = am43xx_dt_clk_init;
  29838. }
  29839. @@ -639,6 +640,7 @@
  29840. omap44xx_clockdomains_init();
  29841. omap44xx_hwmod_init();
  29842. omap_hwmod_init_postsetup();
  29843. + omap_l2_cache_init();
  29844. omap_clk_soc_init = omap4xxx_dt_clk_init;
  29845. }
  29846. diff -Nur linux-3.14.15/arch/arm/mach-omap2/Kconfig linux-linaro-stable-mx6/arch/arm/mach-omap2/Kconfig
  29847. --- linux-3.14.15/arch/arm/mach-omap2/Kconfig 2014-07-31 23:51:43.000000000 +0200
  29848. +++ linux-linaro-stable-mx6/arch/arm/mach-omap2/Kconfig 2014-08-20 19:31:40.232843696 +0200
  29849. @@ -78,6 +78,7 @@
  29850. select MULTI_IRQ_HANDLER
  29851. select ARM_GIC
  29852. select MACH_OMAP_GENERIC
  29853. + select MIGHT_HAVE_CACHE_L2X0
  29854. config SOC_DRA7XX
  29855. bool "TI DRA7XX"
  29856. diff -Nur linux-3.14.15/arch/arm/mach-omap2/omap4-common.c linux-linaro-stable-mx6/arch/arm/mach-omap2/omap4-common.c
  29857. --- linux-3.14.15/arch/arm/mach-omap2/omap4-common.c 2014-07-31 23:51:43.000000000 +0200
  29858. +++ linux-linaro-stable-mx6/arch/arm/mach-omap2/omap4-common.c 2014-08-20 19:31:40.280843902 +0200
  29859. @@ -166,75 +166,57 @@
  29860. return l2cache_base;
  29861. }
  29862. -static void omap4_l2x0_disable(void)
  29863. +static void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
  29864. {
  29865. - outer_flush_all();
  29866. - /* Disable PL310 L2 Cache controller */
  29867. - omap_smc1(0x102, 0x0);
  29868. -}
  29869. + unsigned smc_op;
  29870. -static void omap4_l2x0_set_debug(unsigned long val)
  29871. -{
  29872. - /* Program PL310 L2 Cache controller debug register */
  29873. - omap_smc1(0x100, val);
  29874. + switch (reg) {
  29875. + case L2X0_CTRL:
  29876. + smc_op = OMAP4_MON_L2X0_CTRL_INDEX;
  29877. + break;
  29878. +
  29879. + case L2X0_AUX_CTRL:
  29880. + smc_op = OMAP4_MON_L2X0_AUXCTRL_INDEX;
  29881. + break;
  29882. +
  29883. + case L2X0_DEBUG_CTRL:
  29884. + smc_op = OMAP4_MON_L2X0_DBG_CTRL_INDEX;
  29885. + break;
  29886. +
  29887. + case L310_PREFETCH_CTRL:
  29888. + smc_op = OMAP4_MON_L2X0_PREFETCH_INDEX;
  29889. + break;
  29890. +
  29891. + default:
  29892. + WARN_ONCE(1, "OMAP L2C310: ignoring write to reg 0x%x\n", reg);
  29893. + return;
  29894. + }
  29895. +
  29896. + omap_smc1(smc_op, val);
  29897. }
  29898. -static int __init omap_l2_cache_init(void)
  29899. +int __init omap_l2_cache_init(void)
  29900. {
  29901. - u32 aux_ctrl = 0;
  29902. -
  29903. - /*
  29904. - * To avoid code running on other OMAPs in
  29905. - * multi-omap builds
  29906. - */
  29907. - if (!cpu_is_omap44xx())
  29908. - return -ENODEV;
  29909. + u32 aux_ctrl;
  29910. /* Static mapping, never released */
  29911. l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
  29912. if (WARN_ON(!l2cache_base))
  29913. return -ENOMEM;
  29914. - /*
  29915. - * 16-way associativity, parity disabled
  29916. - * Way size - 32KB (es1.0)
  29917. - * Way size - 64KB (es2.0 +)
  29918. - */
  29919. - aux_ctrl = ((1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT) |
  29920. - (0x1 << 25) |
  29921. - (0x1 << L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT) |
  29922. - (0x1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT));
  29923. -
  29924. - if (omap_rev() == OMAP4430_REV_ES1_0) {
  29925. - aux_ctrl |= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT;
  29926. - } else {
  29927. - aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
  29928. - (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
  29929. - (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
  29930. - (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
  29931. - (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT));
  29932. - }
  29933. - if (omap_rev() != OMAP4430_REV_ES1_0)
  29934. - omap_smc1(0x109, aux_ctrl);
  29935. -
  29936. - /* Enable PL310 L2 Cache controller */
  29937. - omap_smc1(0x102, 0x1);
  29938. + /* 16-way associativity, parity disabled, way size - 64KB (es2.0 +) */
  29939. + aux_ctrl = L2C_AUX_CTRL_SHARED_OVERRIDE |
  29940. + L310_AUX_CTRL_DATA_PREFETCH |
  29941. + L310_AUX_CTRL_INSTR_PREFETCH;
  29942. + outer_cache.write_sec = omap4_l2c310_write_sec;
  29943. if (of_have_populated_dt())
  29944. - l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
  29945. + l2x0_of_init(aux_ctrl, 0xcf9fffff);
  29946. else
  29947. - l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK);
  29948. -
  29949. - /*
  29950. - * Override default outer_cache.disable with a OMAP4
  29951. - * specific one
  29952. - */
  29953. - outer_cache.disable = omap4_l2x0_disable;
  29954. - outer_cache.set_debug = omap4_l2x0_set_debug;
  29955. + l2x0_init(l2cache_base, aux_ctrl, 0xcf9fffff);
  29956. return 0;
  29957. }
  29958. -omap_early_initcall(omap_l2_cache_init);
  29959. #endif
  29960. void __iomem *omap4_get_sar_ram_base(void)
  29961. diff -Nur linux-3.14.15/arch/arm/mach-omap2/omap-mpuss-lowpower.c linux-linaro-stable-mx6/arch/arm/mach-omap2/omap-mpuss-lowpower.c
  29962. --- linux-3.14.15/arch/arm/mach-omap2/omap-mpuss-lowpower.c 2014-07-31 23:51:43.000000000 +0200
  29963. +++ linux-linaro-stable-mx6/arch/arm/mach-omap2/omap-mpuss-lowpower.c 2014-08-20 19:31:40.280843902 +0200
  29964. @@ -187,19 +187,15 @@
  29965. * in every restore MPUSS OFF path.
  29966. */
  29967. #ifdef CONFIG_CACHE_L2X0
  29968. -static void save_l2x0_context(void)
  29969. +static void __init save_l2x0_context(void)
  29970. {
  29971. - u32 val;
  29972. - void __iomem *l2x0_base = omap4_get_l2cache_base();
  29973. - if (l2x0_base) {
  29974. - val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
  29975. - __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
  29976. - val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL);
  29977. - __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
  29978. - }
  29979. + __raw_writel(l2x0_saved_regs.aux_ctrl,
  29980. + sar_base + L2X0_AUXCTRL_OFFSET);
  29981. + __raw_writel(l2x0_saved_regs.prefetch_ctrl,
  29982. + sar_base + L2X0_PREFETCH_CTRL_OFFSET);
  29983. }
  29984. #else
  29985. -static void save_l2x0_context(void)
  29986. +static void __init save_l2x0_context(void)
  29987. {}
  29988. #endif
  29989. diff -Nur linux-3.14.15/arch/arm/mach-prima2/l2x0.c linux-linaro-stable-mx6/arch/arm/mach-prima2/l2x0.c
  29990. --- linux-3.14.15/arch/arm/mach-prima2/l2x0.c 2014-07-31 23:51:43.000000000 +0200
  29991. +++ linux-linaro-stable-mx6/arch/arm/mach-prima2/l2x0.c 2014-08-20 19:31:40.304844006 +0200
  29992. @@ -8,43 +8,10 @@
  29993. #include <linux/init.h>
  29994. #include <linux/kernel.h>
  29995. -#include <linux/of.h>
  29996. #include <asm/hardware/cache-l2x0.h>
  29997. -struct l2x0_aux
  29998. -{
  29999. - u32 val;
  30000. - u32 mask;
  30001. -};
  30002. -
  30003. -static struct l2x0_aux prima2_l2x0_aux __initconst = {
  30004. - .val = 2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT,
  30005. - .mask = 0,
  30006. -};
  30007. -
  30008. -static struct l2x0_aux marco_l2x0_aux __initconst = {
  30009. - .val = (2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
  30010. - (1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT),
  30011. - .mask = L2X0_AUX_CTRL_MASK,
  30012. -};
  30013. -
  30014. -static struct of_device_id sirf_l2x0_ids[] __initconst = {
  30015. - { .compatible = "sirf,prima2-pl310-cache", .data = &prima2_l2x0_aux, },
  30016. - { .compatible = "sirf,marco-pl310-cache", .data = &marco_l2x0_aux, },
  30017. - {},
  30018. -};
  30019. -
  30020. static int __init sirfsoc_l2x0_init(void)
  30021. {
  30022. - struct device_node *np;
  30023. - const struct l2x0_aux *aux;
  30024. -
  30025. - np = of_find_matching_node(NULL, sirf_l2x0_ids);
  30026. - if (np) {
  30027. - aux = of_match_node(sirf_l2x0_ids, np)->data;
  30028. - return l2x0_of_init(aux->val, aux->mask);
  30029. - }
  30030. -
  30031. - return 0;
  30032. + return l2x0_of_init(0, ~0);
  30033. }
  30034. early_initcall(sirfsoc_l2x0_init);
  30035. diff -Nur linux-3.14.15/arch/arm/mach-prima2/pm.c linux-linaro-stable-mx6/arch/arm/mach-prima2/pm.c
  30036. --- linux-3.14.15/arch/arm/mach-prima2/pm.c 2014-07-31 23:51:43.000000000 +0200
  30037. +++ linux-linaro-stable-mx6/arch/arm/mach-prima2/pm.c 2014-08-20 19:31:40.304844006 +0200
  30038. @@ -71,7 +71,6 @@
  30039. case PM_SUSPEND_MEM:
  30040. sirfsoc_pre_suspend_power_off();
  30041. - outer_flush_all();
  30042. outer_disable();
  30043. /* go zzz */
  30044. cpu_suspend(0, sirfsoc_finish_suspend);
  30045. diff -Nur linux-3.14.15/arch/arm/mach-realview/realview_eb.c linux-linaro-stable-mx6/arch/arm/mach-realview/realview_eb.c
  30046. --- linux-3.14.15/arch/arm/mach-realview/realview_eb.c 2014-07-31 23:51:43.000000000 +0200
  30047. +++ linux-linaro-stable-mx6/arch/arm/mach-realview/realview_eb.c 2014-08-20 19:31:40.320844075 +0200
  30048. @@ -442,8 +442,13 @@
  30049. realview_eb11mp_fixup();
  30050. #ifdef CONFIG_CACHE_L2X0
  30051. - /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
  30052. - * Bits: .... ...0 0111 1001 0000 .... .... .... */
  30053. + /*
  30054. + * The PL220 needs to be manually configured as the hardware
  30055. + * doesn't report the correct sizes.
  30056. + * 1MB (128KB/way), 8-way associativity, event monitor and
  30057. + * parity enabled, ignore share bit, no force write allocate
  30058. + * Bits: .... ...0 0111 1001 0000 .... .... ....
  30059. + */
  30060. l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
  30061. #endif
  30062. platform_device_register(&pmu_device);
  30063. diff -Nur linux-3.14.15/arch/arm/mach-realview/realview_pb1176.c linux-linaro-stable-mx6/arch/arm/mach-realview/realview_pb1176.c
  30064. --- linux-3.14.15/arch/arm/mach-realview/realview_pb1176.c 2014-07-31 23:51:43.000000000 +0200
  30065. +++ linux-linaro-stable-mx6/arch/arm/mach-realview/realview_pb1176.c 2014-08-20 19:31:40.320844075 +0200
  30066. @@ -355,7 +355,13 @@
  30067. int i;
  30068. #ifdef CONFIG_CACHE_L2X0
  30069. - /* 128Kb (16Kb/way) 8-way associativity. evmon/parity/share enabled. */
  30070. + /*
  30071. + * The PL220 needs to be manually configured as the hardware
  30072. + * doesn't report the correct sizes.
  30073. + * 128kB (16kB/way), 8-way associativity, event monitor and
  30074. + * parity enabled, ignore share bit, no force write allocate
  30075. + * Bits: .... ...0 0111 0011 0000 .... .... ....
  30076. + */
  30077. l2x0_init(__io_address(REALVIEW_PB1176_L220_BASE), 0x00730000, 0xfe000fff);
  30078. #endif
  30079. diff -Nur linux-3.14.15/arch/arm/mach-realview/realview_pb11mp.c linux-linaro-stable-mx6/arch/arm/mach-realview/realview_pb11mp.c
  30080. --- linux-3.14.15/arch/arm/mach-realview/realview_pb11mp.c 2014-07-31 23:51:43.000000000 +0200
  30081. +++ linux-linaro-stable-mx6/arch/arm/mach-realview/realview_pb11mp.c 2014-08-20 19:31:40.320844075 +0200
  30082. @@ -337,8 +337,13 @@
  30083. int i;
  30084. #ifdef CONFIG_CACHE_L2X0
  30085. - /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
  30086. - * Bits: .... ...0 0111 1001 0000 .... .... .... */
  30087. + /*
  30088. + * The PL220 needs to be manually configured as the hardware
  30089. + * doesn't report the correct sizes.
  30090. + * 1MB (128KB/way), 8-way associativity, event monitor and
  30091. + * parity enabled, ignore share bit, no force write allocate
  30092. + * Bits: .... ...0 0111 1001 0000 .... .... ....
  30093. + */
  30094. l2x0_init(__io_address(REALVIEW_TC11MP_L220_BASE), 0x00790000, 0xfe000fff);
  30095. #endif
  30096. diff -Nur linux-3.14.15/arch/arm/mach-realview/realview_pbx.c linux-linaro-stable-mx6/arch/arm/mach-realview/realview_pbx.c
  30097. --- linux-3.14.15/arch/arm/mach-realview/realview_pbx.c 2014-07-31 23:51:43.000000000 +0200
  30098. +++ linux-linaro-stable-mx6/arch/arm/mach-realview/realview_pbx.c 2014-08-20 19:31:40.320844075 +0200
  30099. @@ -370,8 +370,8 @@
  30100. __io_address(REALVIEW_PBX_TILE_L220_BASE);
  30101. /* set RAM latencies to 1 cycle for eASIC */
  30102. - writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
  30103. - writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
  30104. + writel(0, l2x0_base + L310_TAG_LATENCY_CTRL);
  30105. + writel(0, l2x0_base + L310_DATA_LATENCY_CTRL);
  30106. /* 16KB way size, 8-way associativity, parity disabled
  30107. * Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... */
  30108. diff -Nur linux-3.14.15/arch/arm/mach-rockchip/rockchip.c linux-linaro-stable-mx6/arch/arm/mach-rockchip/rockchip.c
  30109. --- linux-3.14.15/arch/arm/mach-rockchip/rockchip.c 2014-07-31 23:51:43.000000000 +0200
  30110. +++ linux-linaro-stable-mx6/arch/arm/mach-rockchip/rockchip.c 2014-08-20 19:31:40.320844075 +0200
  30111. @@ -25,7 +25,7 @@
  30112. static void __init rockchip_dt_init(void)
  30113. {
  30114. - l2x0_of_init(0, ~0UL);
  30115. + l2x0_of_init(0, ~0);
  30116. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  30117. }
  30118. diff -Nur linux-3.14.15/arch/arm/mach-shmobile/board-armadillo800eva.c linux-linaro-stable-mx6/arch/arm/mach-shmobile/board-armadillo800eva.c
  30119. --- linux-3.14.15/arch/arm/mach-shmobile/board-armadillo800eva.c 2014-07-31 23:51:43.000000000 +0200
  30120. +++ linux-linaro-stable-mx6/arch/arm/mach-shmobile/board-armadillo800eva.c 2014-08-20 19:31:40.356844228 +0200
  30121. @@ -1270,8 +1270,8 @@
  30122. #ifdef CONFIG_CACHE_L2X0
  30123. - /* Early BRESP enable, Shared attribute override enable, 32K*8way */
  30124. - l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
  30125. + /* Shared attribute override enable, 32K*8way */
  30126. + l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
  30127. #endif
  30128. i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
  30129. diff -Nur linux-3.14.15/arch/arm/mach-shmobile/board-armadillo800eva-reference.c linux-linaro-stable-mx6/arch/arm/mach-shmobile/board-armadillo800eva-reference.c
  30130. --- linux-3.14.15/arch/arm/mach-shmobile/board-armadillo800eva-reference.c 2014-07-31 23:51:43.000000000 +0200
  30131. +++ linux-linaro-stable-mx6/arch/arm/mach-shmobile/board-armadillo800eva-reference.c 2014-08-20 19:31:40.356844228 +0200
  30132. @@ -164,8 +164,8 @@
  30133. r8a7740_meram_workaround();
  30134. #ifdef CONFIG_CACHE_L2X0
  30135. - /* Early BRESP enable, Shared attribute override enable, 32K*8way */
  30136. - l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
  30137. + /* Shared attribute override enable, 32K*8way */
  30138. + l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
  30139. #endif
  30140. r8a7740_add_standard_devices_dt();
  30141. diff -Nur linux-3.14.15/arch/arm/mach-shmobile/board-kzm9g.c linux-linaro-stable-mx6/arch/arm/mach-shmobile/board-kzm9g.c
  30142. --- linux-3.14.15/arch/arm/mach-shmobile/board-kzm9g.c 2014-07-31 23:51:43.000000000 +0200
  30143. +++ linux-linaro-stable-mx6/arch/arm/mach-shmobile/board-kzm9g.c 2014-08-20 19:31:40.364844264 +0200
  30144. @@ -878,8 +878,8 @@
  30145. gpio_request_one(223, GPIOF_IN, NULL); /* IRQ8 */
  30146. #ifdef CONFIG_CACHE_L2X0
  30147. - /* Early BRESP enable, Shared attribute override enable, 64K*8way */
  30148. - l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);
  30149. + /* Shared attribute override enable, 64K*8way */
  30150. + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
  30151. #endif
  30152. i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
  30153. diff -Nur linux-3.14.15/arch/arm/mach-shmobile/board-kzm9g-reference.c linux-linaro-stable-mx6/arch/arm/mach-shmobile/board-kzm9g-reference.c
  30154. --- linux-3.14.15/arch/arm/mach-shmobile/board-kzm9g-reference.c 2014-07-31 23:51:43.000000000 +0200
  30155. +++ linux-linaro-stable-mx6/arch/arm/mach-shmobile/board-kzm9g-reference.c 2014-08-20 19:31:40.360844246 +0200
  30156. @@ -36,8 +36,8 @@
  30157. sh73a0_add_standard_devices_dt();
  30158. #ifdef CONFIG_CACHE_L2X0
  30159. - /* Early BRESP enable, Shared attribute override enable, 64K*8way */
  30160. - l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);
  30161. + /* Shared attribute override enable, 64K*8way */
  30162. + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
  30163. #endif
  30164. }
  30165. diff -Nur linux-3.14.15/arch/arm/mach-shmobile/setup-r8a7778.c linux-linaro-stable-mx6/arch/arm/mach-shmobile/setup-r8a7778.c
  30166. --- linux-3.14.15/arch/arm/mach-shmobile/setup-r8a7778.c 2014-07-31 23:51:43.000000000 +0200
  30167. +++ linux-linaro-stable-mx6/arch/arm/mach-shmobile/setup-r8a7778.c 2014-08-20 19:31:40.392844384 +0200
  30168. @@ -298,10 +298,10 @@
  30169. void __iomem *base = ioremap_nocache(0xf0100000, 0x1000);
  30170. if (base) {
  30171. /*
  30172. - * Early BRESP enable, Shared attribute override enable, 64K*16way
  30173. + * Shared attribute override enable, 64K*16way
  30174. * don't call iounmap(base)
  30175. */
  30176. - l2x0_init(base, 0x40470000, 0x82000fff);
  30177. + l2x0_init(base, 0x00400000, 0xc20f0fff);
  30178. }
  30179. #endif
  30180. diff -Nur linux-3.14.15/arch/arm/mach-shmobile/setup-r8a7779.c linux-linaro-stable-mx6/arch/arm/mach-shmobile/setup-r8a7779.c
  30181. --- linux-3.14.15/arch/arm/mach-shmobile/setup-r8a7779.c 2014-07-31 23:51:43.000000000 +0200
  30182. +++ linux-linaro-stable-mx6/arch/arm/mach-shmobile/setup-r8a7779.c 2014-08-20 19:31:40.392844384 +0200
  30183. @@ -700,8 +700,8 @@
  30184. void __init r8a7779_add_standard_devices(void)
  30185. {
  30186. #ifdef CONFIG_CACHE_L2X0
  30187. - /* Early BRESP enable, Shared attribute override enable, 64K*16way */
  30188. - l2x0_init(IOMEM(0xf0100000), 0x40470000, 0x82000fff);
  30189. + /* Shared attribute override enable, 64K*16way */
  30190. + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
  30191. #endif
  30192. r8a7779_pm_init();
  30193. diff -Nur linux-3.14.15/arch/arm/mach-socfpga/socfpga.c linux-linaro-stable-mx6/arch/arm/mach-socfpga/socfpga.c
  30194. --- linux-3.14.15/arch/arm/mach-socfpga/socfpga.c 2014-07-31 23:51:43.000000000 +0200
  30195. +++ linux-linaro-stable-mx6/arch/arm/mach-socfpga/socfpga.c 2014-08-20 19:31:40.404844435 +0200
  30196. @@ -104,7 +104,7 @@
  30197. static void __init socfpga_cyclone5_init(void)
  30198. {
  30199. - l2x0_of_init(0, ~0UL);
  30200. + l2x0_of_init(0, ~0);
  30201. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  30202. socfpga_init_clocks();
  30203. }
  30204. diff -Nur linux-3.14.15/arch/arm/mach-spear/platsmp.c linux-linaro-stable-mx6/arch/arm/mach-spear/platsmp.c
  30205. --- linux-3.14.15/arch/arm/mach-spear/platsmp.c 2014-07-31 23:51:43.000000000 +0200
  30206. +++ linux-linaro-stable-mx6/arch/arm/mach-spear/platsmp.c 2014-08-20 19:31:40.404844435 +0200
  30207. @@ -20,6 +20,18 @@
  30208. #include <mach/spear.h>
  30209. #include "generic.h"
  30210. +/*
  30211. + * Write pen_release in a way that is guaranteed to be visible to all
  30212. + * observers, irrespective of whether they're taking part in coherency
  30213. + * or not. This is necessary for the hotplug code to work reliably.
  30214. + */
  30215. +static void write_pen_release(int val)
  30216. +{
  30217. + pen_release = val;
  30218. + smp_wmb();
  30219. + sync_cache_w(&pen_release);
  30220. +}
  30221. +
  30222. static DEFINE_SPINLOCK(boot_lock);
  30223. static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
  30224. @@ -30,8 +42,7 @@
  30225. * let the primary processor know we're out of the
  30226. * pen, then head off into the C entry point
  30227. */
  30228. - pen_release = -1;
  30229. - smp_wmb();
  30230. + write_pen_release(-1);
  30231. /*
  30232. * Synchronise with the boot thread.
  30233. @@ -58,9 +69,7 @@
  30234. * Note that "pen_release" is the hardware CPU ID, whereas
  30235. * "cpu" is Linux's internal ID.
  30236. */
  30237. - pen_release = cpu;
  30238. - flush_cache_all();
  30239. - outer_flush_all();
  30240. + write_pen_release(cpu);
  30241. timeout = jiffies + (1 * HZ);
  30242. while (time_before(jiffies, timeout)) {
  30243. diff -Nur linux-3.14.15/arch/arm/mach-spear/spear13xx.c linux-linaro-stable-mx6/arch/arm/mach-spear/spear13xx.c
  30244. --- linux-3.14.15/arch/arm/mach-spear/spear13xx.c 2014-07-31 23:51:43.000000000 +0200
  30245. +++ linux-linaro-stable-mx6/arch/arm/mach-spear/spear13xx.c 2014-08-20 19:31:40.404844435 +0200
  30246. @@ -38,15 +38,15 @@
  30247. if (!IS_ENABLED(CONFIG_CACHE_L2X0))
  30248. return;
  30249. - writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL);
  30250. + writel_relaxed(0x06, VA_L2CC_BASE + L310_PREFETCH_CTRL);
  30251. /*
  30252. * Program following latencies in order to make
  30253. * SPEAr1340 work at 600 MHz
  30254. */
  30255. - writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL);
  30256. - writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL);
  30257. - l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff);
  30258. + writel_relaxed(0x221, VA_L2CC_BASE + L310_TAG_LATENCY_CTRL);
  30259. + writel_relaxed(0x441, VA_L2CC_BASE + L310_DATA_LATENCY_CTRL);
  30260. + l2x0_init(VA_L2CC_BASE, 0x30a00001, 0xfe0fffff);
  30261. }
  30262. /*
  30263. diff -Nur linux-3.14.15/arch/arm/mach-sti/board-dt.c linux-linaro-stable-mx6/arch/arm/mach-sti/board-dt.c
  30264. --- linux-3.14.15/arch/arm/mach-sti/board-dt.c 2014-07-31 23:51:43.000000000 +0200
  30265. +++ linux-linaro-stable-mx6/arch/arm/mach-sti/board-dt.c 2014-08-20 19:31:40.404844435 +0200
  30266. @@ -16,15 +16,9 @@
  30267. void __init stih41x_l2x0_init(void)
  30268. {
  30269. - u32 way_size = 0x4;
  30270. - u32 aux_ctrl;
  30271. - /* may be this can be encoded in macros like BIT*() */
  30272. - aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
  30273. - (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
  30274. - (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
  30275. - (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
  30276. -
  30277. - l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
  30278. + l2x0_of_init(L2C_AUX_CTRL_SHARED_OVERRIDE |
  30279. + L310_AUX_CTRL_DATA_PREFETCH |
  30280. + L310_AUX_CTRL_INSTR_PREFETCH, 0xc00f0fff);
  30281. }
  30282. static void __init stih41x_machine_init(void)
  30283. diff -Nur linux-3.14.15/arch/arm/mach-tegra/pm.h linux-linaro-stable-mx6/arch/arm/mach-tegra/pm.h
  30284. --- linux-3.14.15/arch/arm/mach-tegra/pm.h 2014-07-31 23:51:43.000000000 +0200
  30285. +++ linux-linaro-stable-mx6/arch/arm/mach-tegra/pm.h 2014-08-20 19:31:40.408844453 +0200
  30286. @@ -35,8 +35,6 @@
  30287. void tegra30_lp1_iram_hook(void);
  30288. void tegra30_sleep_core_init(void);
  30289. -extern unsigned long l2x0_saved_regs_addr;
  30290. -
  30291. void tegra_clear_cpu_in_lp2(void);
  30292. bool tegra_set_cpu_in_lp2(void);
  30293. diff -Nur linux-3.14.15/arch/arm/mach-tegra/reset-handler.S linux-linaro-stable-mx6/arch/arm/mach-tegra/reset-handler.S
  30294. --- linux-3.14.15/arch/arm/mach-tegra/reset-handler.S 2014-07-31 23:51:43.000000000 +0200
  30295. +++ linux-linaro-stable-mx6/arch/arm/mach-tegra/reset-handler.S 2014-08-20 19:31:40.412844470 +0200
  30296. @@ -19,7 +19,6 @@
  30297. #include <asm/cache.h>
  30298. #include <asm/asm-offsets.h>
  30299. -#include <asm/hardware/cache-l2x0.h>
  30300. #include "flowctrl.h"
  30301. #include "fuse.h"
  30302. @@ -78,8 +77,10 @@
  30303. str r1, [r0]
  30304. #endif
  30305. +#ifdef CONFIG_CACHE_L2X0
  30306. /* L2 cache resume & re-enable */
  30307. - l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr
  30308. + bl l2c310_early_resume
  30309. +#endif
  30310. end_ca9_scu_l2_resume:
  30311. mov32 r9, 0xc0f
  30312. cmp r8, r9
  30313. @@ -89,12 +90,6 @@
  30314. ENDPROC(tegra_resume)
  30315. #endif
  30316. -#ifdef CONFIG_CACHE_L2X0
  30317. - .globl l2x0_saved_regs_addr
  30318. -l2x0_saved_regs_addr:
  30319. - .long 0
  30320. -#endif
  30321. -
  30322. .align L1_CACHE_SHIFT
  30323. ENTRY(__tegra_cpu_reset_handler_start)
  30324. diff -Nur linux-3.14.15/arch/arm/mach-tegra/sleep.h linux-linaro-stable-mx6/arch/arm/mach-tegra/sleep.h
  30325. --- linux-3.14.15/arch/arm/mach-tegra/sleep.h 2014-07-31 23:51:43.000000000 +0200
  30326. +++ linux-linaro-stable-mx6/arch/arm/mach-tegra/sleep.h 2014-08-20 19:31:40.412844470 +0200
  30327. @@ -120,37 +120,6 @@
  30328. mov \tmp1, \tmp1, lsr #8
  30329. .endm
  30330. -/* Macro to resume & re-enable L2 cache */
  30331. -#ifndef L2X0_CTRL_EN
  30332. -#define L2X0_CTRL_EN 1
  30333. -#endif
  30334. -
  30335. -#ifdef CONFIG_CACHE_L2X0
  30336. -.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
  30337. - W(adr) \tmp1, \phys_l2x0_saved_regs
  30338. - ldr \tmp1, [\tmp1]
  30339. - ldr \tmp2, [\tmp1, #L2X0_R_PHY_BASE]
  30340. - ldr \tmp3, [\tmp2, #L2X0_CTRL]
  30341. - tst \tmp3, #L2X0_CTRL_EN
  30342. - bne exit_l2_resume
  30343. - ldr \tmp3, [\tmp1, #L2X0_R_TAG_LATENCY]
  30344. - str \tmp3, [\tmp2, #L2X0_TAG_LATENCY_CTRL]
  30345. - ldr \tmp3, [\tmp1, #L2X0_R_DATA_LATENCY]
  30346. - str \tmp3, [\tmp2, #L2X0_DATA_LATENCY_CTRL]
  30347. - ldr \tmp3, [\tmp1, #L2X0_R_PREFETCH_CTRL]
  30348. - str \tmp3, [\tmp2, #L2X0_PREFETCH_CTRL]
  30349. - ldr \tmp3, [\tmp1, #L2X0_R_PWR_CTRL]
  30350. - str \tmp3, [\tmp2, #L2X0_POWER_CTRL]
  30351. - ldr \tmp3, [\tmp1, #L2X0_R_AUX_CTRL]
  30352. - str \tmp3, [\tmp2, #L2X0_AUX_CTRL]
  30353. - mov \tmp3, #L2X0_CTRL_EN
  30354. - str \tmp3, [\tmp2, #L2X0_CTRL]
  30355. -exit_l2_resume:
  30356. -.endm
  30357. -#else /* CONFIG_CACHE_L2X0 */
  30358. -.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
  30359. -.endm
  30360. -#endif /* CONFIG_CACHE_L2X0 */
  30361. #else
  30362. void tegra_pen_lock(void);
  30363. void tegra_pen_unlock(void);
  30364. diff -Nur linux-3.14.15/arch/arm/mach-tegra/tegra.c linux-linaro-stable-mx6/arch/arm/mach-tegra/tegra.c
  30365. --- linux-3.14.15/arch/arm/mach-tegra/tegra.c 2014-07-31 23:51:43.000000000 +0200
  30366. +++ linux-linaro-stable-mx6/arch/arm/mach-tegra/tegra.c 2014-08-20 19:31:40.412844470 +0200
  30367. @@ -73,27 +73,7 @@
  30368. static void __init tegra_init_cache(void)
  30369. {
  30370. #ifdef CONFIG_CACHE_L2X0
  30371. - static const struct of_device_id pl310_ids[] __initconst = {
  30372. - { .compatible = "arm,pl310-cache", },
  30373. - {}
  30374. - };
  30375. -
  30376. - struct device_node *np;
  30377. - int ret;
  30378. - void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
  30379. - u32 aux_ctrl, cache_type;
  30380. -
  30381. - np = of_find_matching_node(NULL, pl310_ids);
  30382. - if (!np)
  30383. - return;
  30384. -
  30385. - cache_type = readl(p + L2X0_CACHE_TYPE);
  30386. - aux_ctrl = (cache_type & 0x700) << (17-8);
  30387. - aux_ctrl |= 0x7C400001;
  30388. -
  30389. - ret = l2x0_of_init(aux_ctrl, 0x8200c3fe);
  30390. - if (!ret)
  30391. - l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs);
  30392. + l2x0_of_init(0x3c400001, 0xc20fc3fe);
  30393. #endif
  30394. }
  30395. diff -Nur linux-3.14.15/arch/arm/mach-ux500/board-mop500-audio.c linux-linaro-stable-mx6/arch/arm/mach-ux500/board-mop500-audio.c
  30396. --- linux-3.14.15/arch/arm/mach-ux500/board-mop500-audio.c 2014-07-31 23:51:43.000000000 +0200
  30397. +++ linux-linaro-stable-mx6/arch/arm/mach-ux500/board-mop500-audio.c 2014-08-20 19:31:40.412844470 +0200
  30398. @@ -9,7 +9,6 @@
  30399. #include <linux/gpio.h>
  30400. #include <linux/platform_data/dma-ste-dma40.h>
  30401. -#include "irqs.h"
  30402. #include <linux/platform_data/asoc-ux500-msp.h>
  30403. #include "ste-dma40-db8500.h"
  30404. diff -Nur linux-3.14.15/arch/arm/mach-ux500/cache-l2x0.c linux-linaro-stable-mx6/arch/arm/mach-ux500/cache-l2x0.c
  30405. --- linux-3.14.15/arch/arm/mach-ux500/cache-l2x0.c 2014-07-31 23:51:43.000000000 +0200
  30406. +++ linux-linaro-stable-mx6/arch/arm/mach-ux500/cache-l2x0.c 2014-08-20 19:31:40.416844487 +0200
  30407. @@ -35,10 +35,16 @@
  30408. return 0;
  30409. }
  30410. -static int __init ux500_l2x0_init(void)
  30411. +static void ux500_l2c310_write_sec(unsigned long val, unsigned reg)
  30412. {
  30413. - u32 aux_val = 0x3e000000;
  30414. + /*
  30415. + * We can't write to secure registers as we are in non-secure
  30416. + * mode, until we have some SMI service available.
  30417. + */
  30418. +}
  30419. +static int __init ux500_l2x0_init(void)
  30420. +{
  30421. if (cpu_is_u8500_family() || cpu_is_ux540_family())
  30422. l2x0_base = __io_address(U8500_L2CC_BASE);
  30423. else
  30424. @@ -48,28 +54,12 @@
  30425. /* Unlock before init */
  30426. ux500_l2x0_unlock();
  30427. - /* DBx540's L2 has 128KB way size */
  30428. - if (cpu_is_ux540_family())
  30429. - /* 128KB way size */
  30430. - aux_val |= (0x4 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
  30431. - else
  30432. - /* 64KB way size */
  30433. - aux_val |= (0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
  30434. + outer_cache.write_sec = ux500_l2c310_write_sec;
  30435. - /* 64KB way size, 8 way associativity, force WA */
  30436. if (of_have_populated_dt())
  30437. - l2x0_of_init(aux_val, 0xc0000fff);
  30438. + l2x0_of_init(0, ~0);
  30439. else
  30440. - l2x0_init(l2x0_base, aux_val, 0xc0000fff);
  30441. -
  30442. - /*
  30443. - * We can't disable l2 as we are in non secure mode, currently
  30444. - * this seems be called only during kexec path. So let's
  30445. - * override outer.disable with nasty assignment until we have
  30446. - * some SMI service available.
  30447. - */
  30448. - outer_cache.disable = NULL;
  30449. - outer_cache.set_debug = NULL;
  30450. + l2x0_init(l2x0_base, 0, ~0);
  30451. return 0;
  30452. }
  30453. diff -Nur linux-3.14.15/arch/arm/mach-ux500/cpu-db8500.c linux-linaro-stable-mx6/arch/arm/mach-ux500/cpu-db8500.c
  30454. --- linux-3.14.15/arch/arm/mach-ux500/cpu-db8500.c 2014-07-31 23:51:43.000000000 +0200
  30455. +++ linux-linaro-stable-mx6/arch/arm/mach-ux500/cpu-db8500.c 2014-08-20 19:31:40.416844487 +0200
  30456. @@ -27,7 +27,6 @@
  30457. #include <asm/mach/map.h>
  30458. #include "setup.h"
  30459. -#include "irqs.h"
  30460. #include "board-mop500-regulators.h"
  30461. #include "board-mop500.h"
  30462. @@ -35,14 +34,11 @@
  30463. #include "id.h"
  30464. struct ab8500_platform_data ab8500_platdata = {
  30465. - .irq_base = MOP500_AB8500_IRQ_BASE,
  30466. .regulator = &ab8500_regulator_plat_data,
  30467. };
  30468. struct prcmu_pdata db8500_prcmu_pdata = {
  30469. .ab_platdata = &ab8500_platdata,
  30470. - .ab_irq = IRQ_DB8500_AB8500,
  30471. - .irq_base = IRQ_PRCMU_BASE,
  30472. .version_offset = DB8500_PRCMU_FW_VERSION_OFFSET,
  30473. .legacy_offset = DB8500_PRCMU_LEGACY_OFFSET,
  30474. };
  30475. diff -Nur linux-3.14.15/arch/arm/mach-ux500/irqs-board-mop500.h linux-linaro-stable-mx6/arch/arm/mach-ux500/irqs-board-mop500.h
  30476. --- linux-3.14.15/arch/arm/mach-ux500/irqs-board-mop500.h 2014-07-31 23:51:43.000000000 +0200
  30477. +++ linux-linaro-stable-mx6/arch/arm/mach-ux500/irqs-board-mop500.h 1970-01-01 01:00:00.000000000 +0100
  30478. @@ -1,55 +0,0 @@
  30479. -/*
  30480. - * Copyright (C) ST-Ericsson SA 2010
  30481. - *
  30482. - * Author: Rabin Vincent <rabin.vincent@stericsson.com>
  30483. - * License terms: GNU General Public License (GPL) version 2
  30484. - */
  30485. -
  30486. -#ifndef __MACH_IRQS_BOARD_MOP500_H
  30487. -#define __MACH_IRQS_BOARD_MOP500_H
  30488. -
  30489. -/* Number of AB8500 irqs is taken from header file */
  30490. -#include <linux/mfd/abx500/ab8500.h>
  30491. -
  30492. -#define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START
  30493. -#define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \
  30494. - + AB8500_MAX_NR_IRQS)
  30495. -
  30496. -/* TC35892 */
  30497. -#define TC35892_NR_INTERNAL_IRQS 8
  30498. -#define TC35892_INT_GPIO(x) (TC35892_NR_INTERNAL_IRQS + (x))
  30499. -#define TC35892_NR_GPIOS 24
  30500. -#define TC35892_NR_IRQS TC35892_INT_GPIO(TC35892_NR_GPIOS)
  30501. -
  30502. -#define MOP500_EGPIO_NR_IRQS TC35892_NR_IRQS
  30503. -
  30504. -#define MOP500_EGPIO_IRQ_BASE MOP500_AB8500_IRQ_END
  30505. -#define MOP500_EGPIO_IRQ_END (MOP500_EGPIO_IRQ_BASE \
  30506. - + MOP500_EGPIO_NR_IRQS)
  30507. -/* STMPE1601 irqs */
  30508. -#define STMPE_NR_INTERNAL_IRQS 9
  30509. -#define STMPE_INT_GPIO(x) (STMPE_NR_INTERNAL_IRQS + (x))
  30510. -#define STMPE_NR_GPIOS 24
  30511. -#define STMPE_NR_IRQS STMPE_INT_GPIO(STMPE_NR_GPIOS)
  30512. -
  30513. -#define MOP500_STMPE1601_IRQBASE MOP500_EGPIO_IRQ_END
  30514. -#define MOP500_STMPE1601_IRQ(x) (MOP500_STMPE1601_IRQBASE + (x))
  30515. -
  30516. -#define MOP500_STMPE1601_IRQ_END \
  30517. - MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS)
  30518. -
  30519. -#define MOP500_NR_IRQS MOP500_STMPE1601_IRQ_END
  30520. -
  30521. -#define MOP500_IRQ_END MOP500_NR_IRQS
  30522. -
  30523. -/*
  30524. - * We may have several boards, but only one will run at a
  30525. - * time, so the one with most IRQs will bump this ahead,
  30526. - * but the IRQ_BOARD_START remains the same for either board.
  30527. - */
  30528. -#if MOP500_IRQ_END > IRQ_BOARD_END
  30529. -#undef IRQ_BOARD_END
  30530. -#define IRQ_BOARD_END MOP500_IRQ_END
  30531. -#endif
  30532. -
  30533. -#endif
  30534. diff -Nur linux-3.14.15/arch/arm/mach-ux500/irqs-db8500.h linux-linaro-stable-mx6/arch/arm/mach-ux500/irqs-db8500.h
  30535. --- linux-3.14.15/arch/arm/mach-ux500/irqs-db8500.h 2014-07-31 23:51:43.000000000 +0200
  30536. +++ linux-linaro-stable-mx6/arch/arm/mach-ux500/irqs-db8500.h 1970-01-01 01:00:00.000000000 +0100
  30537. @@ -1,125 +0,0 @@
  30538. -/*
  30539. - * Copyright (C) ST-Ericsson SA 2010
  30540. - *
  30541. - * Author: Rabin Vincent <rabin.vincent@stericsson.com>
  30542. - * License terms: GNU General Public License (GPL) version 2
  30543. - */
  30544. -
  30545. -#ifndef __MACH_IRQS_DB8500_H
  30546. -#define __MACH_IRQS_DB8500_H
  30547. -
  30548. -#define IRQ_DB8500_MTU0 (IRQ_SHPI_START + 4)
  30549. -#define IRQ_DB8500_SPI2 (IRQ_SHPI_START + 6)
  30550. -#define IRQ_DB8500_PMU (IRQ_SHPI_START + 7)
  30551. -#define IRQ_DB8500_SPI0 (IRQ_SHPI_START + 8)
  30552. -#define IRQ_DB8500_RTT (IRQ_SHPI_START + 9)
  30553. -#define IRQ_DB8500_PKA (IRQ_SHPI_START + 10)
  30554. -#define IRQ_DB8500_UART0 (IRQ_SHPI_START + 11)
  30555. -#define IRQ_DB8500_I2C3 (IRQ_SHPI_START + 12)
  30556. -#define IRQ_DB8500_L2CC (IRQ_SHPI_START + 13)
  30557. -#define IRQ_DB8500_SSP0 (IRQ_SHPI_START + 14)
  30558. -#define IRQ_DB8500_CRYP1 (IRQ_SHPI_START + 15)
  30559. -#define IRQ_DB8500_MSP1_RX (IRQ_SHPI_START + 16)
  30560. -#define IRQ_DB8500_MTU1 (IRQ_SHPI_START + 17)
  30561. -#define IRQ_DB8500_RTC (IRQ_SHPI_START + 18)
  30562. -#define IRQ_DB8500_UART1 (IRQ_SHPI_START + 19)
  30563. -#define IRQ_DB8500_USB_WAKEUP (IRQ_SHPI_START + 20)
  30564. -#define IRQ_DB8500_I2C0 (IRQ_SHPI_START + 21)
  30565. -#define IRQ_DB8500_I2C1 (IRQ_SHPI_START + 22)
  30566. -#define IRQ_DB8500_USBOTG (IRQ_SHPI_START + 23)
  30567. -#define IRQ_DB8500_DMA_SECURE (IRQ_SHPI_START + 24)
  30568. -#define IRQ_DB8500_DMA (IRQ_SHPI_START + 25)
  30569. -#define IRQ_DB8500_UART2 (IRQ_SHPI_START + 26)
  30570. -#define IRQ_DB8500_ICN_PMU1 (IRQ_SHPI_START + 27)
  30571. -#define IRQ_DB8500_ICN_PMU2 (IRQ_SHPI_START + 28)
  30572. -#define IRQ_DB8500_HSIR_EXCEP (IRQ_SHPI_START + 29)
  30573. -#define IRQ_DB8500_MSP0 (IRQ_SHPI_START + 31)
  30574. -#define IRQ_DB8500_HSIR_CH0_OVRRUN (IRQ_SHPI_START + 32)
  30575. -#define IRQ_DB8500_HSIR_CH1_OVRRUN (IRQ_SHPI_START + 33)
  30576. -#define IRQ_DB8500_HSIR_CH2_OVRRUN (IRQ_SHPI_START + 34)
  30577. -#define IRQ_DB8500_HSIR_CH3_OVRRUN (IRQ_SHPI_START + 35)
  30578. -#define IRQ_DB8500_HSIR_CH4_OVRRUN (IRQ_SHPI_START + 36)
  30579. -#define IRQ_DB8500_HSIR_CH5_OVRRUN (IRQ_SHPI_START + 37)
  30580. -#define IRQ_DB8500_HSIR_CH6_OVRRUN (IRQ_SHPI_START + 38)
  30581. -#define IRQ_DB8500_HSIR_CH7_OVRRUN (IRQ_SHPI_START + 39)
  30582. -#define IRQ_DB8500_AB8500 (IRQ_SHPI_START + 40)
  30583. -#define IRQ_DB8500_SDMMC2 (IRQ_SHPI_START + 41)
  30584. -#define IRQ_DB8500_SIA (IRQ_SHPI_START + 42)
  30585. -#define IRQ_DB8500_SIA2 (IRQ_SHPI_START + 43)
  30586. -#define IRQ_DB8500_SVA (IRQ_SHPI_START + 44)
  30587. -#define IRQ_DB8500_SVA2 (IRQ_SHPI_START + 45)
  30588. -#define IRQ_DB8500_PRCMU0 (IRQ_SHPI_START + 46)
  30589. -#define IRQ_DB8500_PRCMU1 (IRQ_SHPI_START + 47)
  30590. -#define IRQ_DB8500_DISP (IRQ_SHPI_START + 48)
  30591. -#define IRQ_DB8500_SPI3 (IRQ_SHPI_START + 49)
  30592. -#define IRQ_DB8500_SDMMC1 (IRQ_SHPI_START + 50)
  30593. -#define IRQ_DB8500_I2C4 (IRQ_SHPI_START + 51)
  30594. -#define IRQ_DB8500_SSP1 (IRQ_SHPI_START + 52)
  30595. -#define IRQ_DB8500_SKE (IRQ_SHPI_START + 53)
  30596. -#define IRQ_DB8500_KB (IRQ_SHPI_START + 54)
  30597. -#define IRQ_DB8500_I2C2 (IRQ_SHPI_START + 55)
  30598. -#define IRQ_DB8500_B2R2 (IRQ_SHPI_START + 56)
  30599. -#define IRQ_DB8500_CRYP0 (IRQ_SHPI_START + 57)
  30600. -#define IRQ_DB8500_SDMMC3 (IRQ_SHPI_START + 59)
  30601. -#define IRQ_DB8500_SDMMC0 (IRQ_SHPI_START + 60)
  30602. -#define IRQ_DB8500_HSEM (IRQ_SHPI_START + 61)
  30603. -#define IRQ_DB8500_MSP1 (IRQ_SHPI_START + 62)
  30604. -#define IRQ_DB8500_SBAG (IRQ_SHPI_START + 63)
  30605. -#define IRQ_DB8500_SPI1 (IRQ_SHPI_START + 96)
  30606. -#define IRQ_DB8500_SRPTIMER (IRQ_SHPI_START + 97)
  30607. -#define IRQ_DB8500_MSP2 (IRQ_SHPI_START + 98)
  30608. -#define IRQ_DB8500_SDMMC4 (IRQ_SHPI_START + 99)
  30609. -#define IRQ_DB8500_SDMMC5 (IRQ_SHPI_START + 100)
  30610. -#define IRQ_DB8500_HSIRD0 (IRQ_SHPI_START + 104)
  30611. -#define IRQ_DB8500_HSIRD1 (IRQ_SHPI_START + 105)
  30612. -#define IRQ_DB8500_HSITD0 (IRQ_SHPI_START + 106)
  30613. -#define IRQ_DB8500_HSITD1 (IRQ_SHPI_START + 107)
  30614. -#define IRQ_DB8500_CTI0 (IRQ_SHPI_START + 108)
  30615. -#define IRQ_DB8500_CTI1 (IRQ_SHPI_START + 109)
  30616. -#define IRQ_DB8500_ICN_ERR (IRQ_SHPI_START + 110)
  30617. -#define IRQ_DB8500_MALI_PPMMU (IRQ_SHPI_START + 112)
  30618. -#define IRQ_DB8500_MALI_PP (IRQ_SHPI_START + 113)
  30619. -#define IRQ_DB8500_MALI_GPMMU (IRQ_SHPI_START + 114)
  30620. -#define IRQ_DB8500_MALI_GP (IRQ_SHPI_START + 115)
  30621. -#define IRQ_DB8500_MALI (IRQ_SHPI_START + 116)
  30622. -#define IRQ_DB8500_PRCMU_SEM (IRQ_SHPI_START + 118)
  30623. -#define IRQ_DB8500_GPIO0 (IRQ_SHPI_START + 119)
  30624. -#define IRQ_DB8500_GPIO1 (IRQ_SHPI_START + 120)
  30625. -#define IRQ_DB8500_GPIO2 (IRQ_SHPI_START + 121)
  30626. -#define IRQ_DB8500_GPIO3 (IRQ_SHPI_START + 122)
  30627. -#define IRQ_DB8500_GPIO4 (IRQ_SHPI_START + 123)
  30628. -#define IRQ_DB8500_GPIO5 (IRQ_SHPI_START + 124)
  30629. -#define IRQ_DB8500_GPIO6 (IRQ_SHPI_START + 125)
  30630. -#define IRQ_DB8500_GPIO7 (IRQ_SHPI_START + 126)
  30631. -#define IRQ_DB8500_GPIO8 (IRQ_SHPI_START + 127)
  30632. -
  30633. -#define IRQ_CA_WAKE_REQ_ED (IRQ_SHPI_START + 71)
  30634. -#define IRQ_AC_READ_NOTIFICATION_0_ED (IRQ_SHPI_START + 66)
  30635. -#define IRQ_AC_READ_NOTIFICATION_1_ED (IRQ_SHPI_START + 64)
  30636. -#define IRQ_CA_MSG_PEND_NOTIFICATION_0_ED (IRQ_SHPI_START + 67)
  30637. -#define IRQ_CA_MSG_PEND_NOTIFICATION_1_ED (IRQ_SHPI_START + 65)
  30638. -
  30639. -#define IRQ_CA_WAKE_REQ_V1 (IRQ_SHPI_START + 83)
  30640. -#define IRQ_AC_READ_NOTIFICATION_0_V1 (IRQ_SHPI_START + 78)
  30641. -#define IRQ_AC_READ_NOTIFICATION_1_V1 (IRQ_SHPI_START + 76)
  30642. -#define IRQ_CA_MSG_PEND_NOTIFICATION_0_V1 (IRQ_SHPI_START + 79)
  30643. -#define IRQ_CA_MSG_PEND_NOTIFICATION_1_V1 (IRQ_SHPI_START + 77)
  30644. -
  30645. -#ifdef CONFIG_UX500_SOC_DB8500
  30646. -
  30647. -/* Virtual interrupts corresponding to the PRCMU wakeups. */
  30648. -#define IRQ_PRCMU_BASE IRQ_SOC_START
  30649. -#define IRQ_PRCMU_END (IRQ_PRCMU_BASE + 23)
  30650. -
  30651. -/*
  30652. - * We may have several SoCs, but only one will run at a
  30653. - * time, so the one with most IRQs will bump this ahead,
  30654. - * but the IRQ_SOC_START remains the same for either SoC.
  30655. - */
  30656. -#if IRQ_SOC_END < IRQ_PRCMU_END
  30657. -#undef IRQ_SOC_END
  30658. -#define IRQ_SOC_END IRQ_PRCMU_END
  30659. -#endif
  30660. -
  30661. -#endif /* CONFIG_UX500_SOC_DB8500 */
  30662. -#endif
  30663. diff -Nur linux-3.14.15/arch/arm/mach-ux500/irqs.h linux-linaro-stable-mx6/arch/arm/mach-ux500/irqs.h
  30664. --- linux-3.14.15/arch/arm/mach-ux500/irqs.h 2014-07-31 23:51:43.000000000 +0200
  30665. +++ linux-linaro-stable-mx6/arch/arm/mach-ux500/irqs.h 1970-01-01 01:00:00.000000000 +0100
  30666. @@ -1,49 +0,0 @@
  30667. -/*
  30668. - * Copyright (C) 2008 STMicroelectronics
  30669. - * Copyright (C) 2009 ST-Ericsson.
  30670. - *
  30671. - * This program is free software; you can redistribute it and/or modify
  30672. - * it under the terms of the GNU General Public License as published by
  30673. - * the Free Software Foundation; either version 2 of the License, or
  30674. - * (at your option) any later version.
  30675. - */
  30676. -#ifndef ASM_ARCH_IRQS_H
  30677. -#define ASM_ARCH_IRQS_H
  30678. -
  30679. -#define IRQ_LOCALTIMER 29
  30680. -#define IRQ_LOCALWDOG 30
  30681. -
  30682. -/* Shared Peripheral Interrupt (SHPI) */
  30683. -#define IRQ_SHPI_START 32
  30684. -
  30685. -/*
  30686. - * MTU0 preserved for now until plat-nomadik is taught not to use it. Don't
  30687. - * add any other IRQs here, use the irqs-dbx500.h files.
  30688. - */
  30689. -#define IRQ_MTU0 (IRQ_SHPI_START + 4)
  30690. -
  30691. -#define DBX500_NR_INTERNAL_IRQS 166
  30692. -
  30693. -/* After chip-specific IRQ numbers we have the GPIO ones */
  30694. -#define NOMADIK_NR_GPIO 288
  30695. -#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + DBX500_NR_INTERNAL_IRQS)
  30696. -#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - DBX500_NR_INTERNAL_IRQS)
  30697. -#define IRQ_GPIO_END NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
  30698. -
  30699. -#define IRQ_SOC_START IRQ_GPIO_END
  30700. -/* This will be overridden by SoC-specific irq headers */
  30701. -#define IRQ_SOC_END IRQ_SOC_START
  30702. -
  30703. -#include "irqs-db8500.h"
  30704. -
  30705. -#define IRQ_BOARD_START IRQ_SOC_END
  30706. -/* This will be overridden by board-specific irq headers */
  30707. -#define IRQ_BOARD_END IRQ_BOARD_START
  30708. -
  30709. -#ifdef CONFIG_MACH_MOP500
  30710. -#include "irqs-board-mop500.h"
  30711. -#endif
  30712. -
  30713. -#define UX500_NR_IRQS IRQ_BOARD_END
  30714. -
  30715. -#endif /* ASM_ARCH_IRQS_H */
  30716. diff -Nur linux-3.14.15/arch/arm/mach-vexpress/ct-ca9x4.c linux-linaro-stable-mx6/arch/arm/mach-vexpress/ct-ca9x4.c
  30717. --- linux-3.14.15/arch/arm/mach-vexpress/ct-ca9x4.c 2014-07-31 23:51:43.000000000 +0200
  30718. +++ linux-linaro-stable-mx6/arch/arm/mach-vexpress/ct-ca9x4.c 2014-08-20 19:31:40.416844487 +0200
  30719. @@ -45,6 +45,23 @@
  30720. iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
  30721. }
  30722. +static void __init ca9x4_l2_init(void)
  30723. +{
  30724. +#ifdef CONFIG_CACHE_L2X0
  30725. + void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
  30726. +
  30727. + if (l2x0_base) {
  30728. + /* set RAM latencies to 1 cycle for this core tile. */
  30729. + writel(0, l2x0_base + L310_TAG_LATENCY_CTRL);
  30730. + writel(0, l2x0_base + L310_DATA_LATENCY_CTRL);
  30731. +
  30732. + l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
  30733. + } else {
  30734. + pr_err("L2C: unable to map L2 cache controller\n");
  30735. + }
  30736. +#endif
  30737. +}
  30738. +
  30739. #ifdef CONFIG_HAVE_ARM_TWD
  30740. static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, A9_MPCORE_TWD, IRQ_LOCALTIMER);
  30741. @@ -63,6 +80,7 @@
  30742. gic_init(0, 29, ioremap(A9_MPCORE_GIC_DIST, SZ_4K),
  30743. ioremap(A9_MPCORE_GIC_CPU, SZ_256));
  30744. ca9x4_twd_init();
  30745. + ca9x4_l2_init();
  30746. }
  30747. static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
  30748. @@ -141,16 +159,6 @@
  30749. {
  30750. int i;
  30751. -#ifdef CONFIG_CACHE_L2X0
  30752. - void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
  30753. -
  30754. - /* set RAM latencies to 1 cycle for this core tile. */
  30755. - writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
  30756. - writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
  30757. -
  30758. - l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
  30759. -#endif
  30760. -
  30761. for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
  30762. amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
  30763. diff -Nur linux-3.14.15/arch/arm/mach-vexpress/dcscb.c linux-linaro-stable-mx6/arch/arm/mach-vexpress/dcscb.c
  30764. --- linux-3.14.15/arch/arm/mach-vexpress/dcscb.c 2014-07-31 23:51:43.000000000 +0200
  30765. +++ linux-linaro-stable-mx6/arch/arm/mach-vexpress/dcscb.c 2014-08-20 19:23:46.262814691 +0200
  30766. @@ -23,6 +23,7 @@
  30767. #include <asm/cacheflush.h>
  30768. #include <asm/cputype.h>
  30769. #include <asm/cp15.h>
  30770. +#include <asm/psci.h>
  30771. #define RST_HOLD0 0x0
  30772. @@ -193,6 +194,12 @@
  30773. unsigned int cfg;
  30774. int ret;
  30775. + ret = psci_probe();
  30776. + if (!ret) {
  30777. + pr_debug("psci found. Aborting native init\n");
  30778. + return -ENODEV;
  30779. + }
  30780. +
  30781. if (!cci_probed())
  30782. return -ENODEV;
  30783. diff -Nur linux-3.14.15/arch/arm/mach-vexpress/Kconfig linux-linaro-stable-mx6/arch/arm/mach-vexpress/Kconfig
  30784. --- linux-3.14.15/arch/arm/mach-vexpress/Kconfig 2014-07-31 23:51:43.000000000 +0200
  30785. +++ linux-linaro-stable-mx6/arch/arm/mach-vexpress/Kconfig 2014-08-20 19:31:40.416844487 +0200
  30786. @@ -55,6 +55,7 @@
  30787. config ARCH_VEXPRESS_CA9X4
  30788. bool "Versatile Express Cortex-A9x4 tile"
  30789. + select ARM_ERRATA_643719
  30790. config ARCH_VEXPRESS_DCSCB
  30791. bool "Dual Cluster System Control Block (DCSCB) support"
  30792. diff -Nur linux-3.14.15/arch/arm/mach-vexpress/Makefile linux-linaro-stable-mx6/arch/arm/mach-vexpress/Makefile
  30793. --- linux-3.14.15/arch/arm/mach-vexpress/Makefile 2014-07-31 23:51:43.000000000 +0200
  30794. +++ linux-linaro-stable-mx6/arch/arm/mach-vexpress/Makefile 2014-08-20 19:31:40.416844487 +0200
  30795. @@ -8,8 +8,15 @@
  30796. obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
  30797. obj-$(CONFIG_ARCH_VEXPRESS_DCSCB) += dcscb.o dcscb_setup.o
  30798. CFLAGS_dcscb.o += -march=armv7-a
  30799. +CFLAGS_REMOVE_dcscb.o = -pg
  30800. obj-$(CONFIG_ARCH_VEXPRESS_SPC) += spc.o
  30801. +CFLAGS_REMOVE_spc.o = -pg
  30802. obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o
  30803. CFLAGS_tc2_pm.o += -march=armv7-a
  30804. +CFLAGS_REMOVE_tc2_pm.o = -pg
  30805. +ifeq ($(CONFIG_ARCH_VEXPRESS_TC2_PM),y)
  30806. +obj-$(CONFIG_ARM_PSCI) += tc2_pm_psci.o
  30807. +CFLAGS_REMOVE_tc2_pm_psci.o = -pg
  30808. +endif
  30809. obj-$(CONFIG_SMP) += platsmp.o
  30810. obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
  30811. diff -Nur linux-3.14.15/arch/arm/mach-vexpress/spc.c linux-linaro-stable-mx6/arch/arm/mach-vexpress/spc.c
  30812. --- linux-3.14.15/arch/arm/mach-vexpress/spc.c 2014-07-31 23:51:43.000000000 +0200
  30813. +++ linux-linaro-stable-mx6/arch/arm/mach-vexpress/spc.c 2014-08-20 19:31:40.416844487 +0200
  30814. @@ -392,7 +392,7 @@
  30815. * +--------------------------+
  30816. * | 31 20 | 19 0 |
  30817. * +--------------------------+
  30818. - * | u_volt | freq(kHz) |
  30819. + * | m_volt | freq(kHz) |
  30820. * +--------------------------+
  30821. */
  30822. #define MULT_FACTOR 20
  30823. @@ -414,7 +414,7 @@
  30824. ret = ve_spc_read_sys_cfg(SYSCFG_SCC, off, &data);
  30825. if (!ret) {
  30826. opps->freq = (data & FREQ_MASK) * MULT_FACTOR;
  30827. - opps->u_volt = data >> VOLT_SHIFT;
  30828. + opps->u_volt = (data >> VOLT_SHIFT) * 1000;
  30829. } else {
  30830. break;
  30831. }
  30832. diff -Nur linux-3.14.15/arch/arm/mach-vexpress/tc2_pm.c linux-linaro-stable-mx6/arch/arm/mach-vexpress/tc2_pm.c
  30833. --- linux-3.14.15/arch/arm/mach-vexpress/tc2_pm.c 2014-07-31 23:51:43.000000000 +0200
  30834. +++ linux-linaro-stable-mx6/arch/arm/mach-vexpress/tc2_pm.c 2014-08-20 19:31:40.416844487 +0200
  30835. @@ -27,6 +27,7 @@
  30836. #include <asm/cacheflush.h>
  30837. #include <asm/cputype.h>
  30838. #include <asm/cp15.h>
  30839. +#include <asm/psci.h>
  30840. #include <linux/arm-cci.h>
  30841. @@ -329,6 +330,12 @@
  30842. u32 a15_cluster_id, a7_cluster_id, sys_info;
  30843. struct device_node *np;
  30844. + ret = psci_probe();
  30845. + if (!ret) {
  30846. + pr_debug("psci found. Aborting native init\n");
  30847. + return -ENODEV;
  30848. + }
  30849. +
  30850. /*
  30851. * The power management-related features are hidden behind
  30852. * SCC registers. We need to extract runtime information like
  30853. diff -Nur linux-3.14.15/arch/arm/mach-vexpress/tc2_pm_psci.c linux-linaro-stable-mx6/arch/arm/mach-vexpress/tc2_pm_psci.c
  30854. --- linux-3.14.15/arch/arm/mach-vexpress/tc2_pm_psci.c 1970-01-01 01:00:00.000000000 +0100
  30855. +++ linux-linaro-stable-mx6/arch/arm/mach-vexpress/tc2_pm_psci.c 2014-08-20 19:31:40.416844487 +0200
  30856. @@ -0,0 +1,173 @@
  30857. +/*
  30858. + * arch/arm/mach-vexpress/tc2_pm_psci.c - TC2 PSCI support
  30859. + *
  30860. + * Created by: Achin Gupta, December 2012
  30861. + * Copyright: (C) 2012 ARM Limited
  30862. + *
  30863. + * Some portions of this file were originally written by Nicolas Pitre
  30864. + * Copyright: (C) 2012 Linaro Limited
  30865. + *
  30866. + * This program is free software; you can redistribute it and/or modify
  30867. + * it under the terms of the GNU General Public License version 2 as
  30868. + * published by the Free Software Foundation.
  30869. + */
  30870. +
  30871. +#include <linux/init.h>
  30872. +#include <linux/kernel.h>
  30873. +#include <linux/of.h>
  30874. +#include <linux/spinlock.h>
  30875. +#include <linux/errno.h>
  30876. +
  30877. +#include <asm/mcpm.h>
  30878. +#include <asm/proc-fns.h>
  30879. +#include <asm/cacheflush.h>
  30880. +#include <asm/psci.h>
  30881. +#include <asm/atomic.h>
  30882. +#include <asm/cputype.h>
  30883. +#include <asm/cp15.h>
  30884. +
  30885. +#include <mach/motherboard.h>
  30886. +
  30887. +#include <linux/vexpress.h>
  30888. +
  30889. +/*
  30890. + * Platform specific state id understood by the firmware and used to
  30891. + * program the power controller
  30892. + */
  30893. +#define PSCI_POWER_STATE_ID 0
  30894. +
  30895. +#define TC2_CLUSTERS 2
  30896. +#define TC2_MAX_CPUS_PER_CLUSTER 3
  30897. +
  30898. +static atomic_t tc2_pm_use_count[TC2_MAX_CPUS_PER_CLUSTER][TC2_CLUSTERS];
  30899. +
  30900. +static int tc2_pm_psci_power_up(unsigned int cpu, unsigned int cluster)
  30901. +{
  30902. + unsigned int mpidr = (cluster << 8) | cpu;
  30903. + int ret = 0;
  30904. +
  30905. + BUG_ON(!psci_ops.cpu_on);
  30906. +
  30907. + switch (atomic_inc_return(&tc2_pm_use_count[cpu][cluster])) {
  30908. + case 1:
  30909. + /*
  30910. + * This is a request to power up a cpu that linux thinks has
  30911. + * been powered down. Retries are needed if the firmware has
  30912. + * seen the power down request as yet.
  30913. + */
  30914. + do
  30915. + ret = psci_ops.cpu_on(mpidr,
  30916. + virt_to_phys(mcpm_entry_point));
  30917. + while (ret == -EAGAIN);
  30918. +
  30919. + return ret;
  30920. + case 2:
  30921. + /* This power up request has overtaken a power down request */
  30922. + return ret;
  30923. + default:
  30924. + /* Any other value is a bug */
  30925. + BUG();
  30926. + }
  30927. +}
  30928. +
  30929. +static void tc2_pm_psci_power_down(void)
  30930. +{
  30931. + struct psci_power_state power_state;
  30932. + unsigned int mpidr, cpu, cluster;
  30933. +
  30934. + mpidr = read_cpuid_mpidr();
  30935. + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
  30936. + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
  30937. +
  30938. + BUG_ON(!psci_ops.cpu_off);
  30939. +
  30940. + switch (atomic_dec_return(&tc2_pm_use_count[cpu][cluster])) {
  30941. + case 1:
  30942. + /*
  30943. + * Overtaken by a power up. Flush caches, exit coherency,
  30944. + * return & fake a reset
  30945. + */
  30946. + set_cr(get_cr() & ~CR_C);
  30947. +
  30948. + flush_cache_louis();
  30949. +
  30950. + asm volatile ("clrex");
  30951. + set_auxcr(get_auxcr() & ~(1 << 6));
  30952. +
  30953. + return;
  30954. + case 0:
  30955. + /* A normal request to possibly power down the cluster */
  30956. + power_state.id = PSCI_POWER_STATE_ID;
  30957. + power_state.type = PSCI_POWER_STATE_TYPE_POWER_DOWN;
  30958. + power_state.affinity_level = PSCI_POWER_STATE_AFFINITY_LEVEL1;
  30959. +
  30960. + psci_ops.cpu_off(power_state);
  30961. +
  30962. + /* On success this function never returns */
  30963. + default:
  30964. + /* Any other value is a bug */
  30965. + BUG();
  30966. + }
  30967. +}
  30968. +
  30969. +static void tc2_pm_psci_suspend(u64 unused)
  30970. +{
  30971. + struct psci_power_state power_state;
  30972. +
  30973. + BUG_ON(!psci_ops.cpu_suspend);
  30974. +
  30975. + /* On TC2 always attempt to power down the cluster */
  30976. + power_state.id = PSCI_POWER_STATE_ID;
  30977. + power_state.type = PSCI_POWER_STATE_TYPE_POWER_DOWN;
  30978. + power_state.affinity_level = PSCI_POWER_STATE_AFFINITY_LEVEL1;
  30979. +
  30980. + psci_ops.cpu_suspend(power_state, virt_to_phys(mcpm_entry_point));
  30981. +
  30982. + /* On success this function never returns */
  30983. + BUG();
  30984. +}
  30985. +
  30986. +static const struct mcpm_platform_ops tc2_pm_power_ops = {
  30987. + .power_up = tc2_pm_psci_power_up,
  30988. + .power_down = tc2_pm_psci_power_down,
  30989. + .suspend = tc2_pm_psci_suspend,
  30990. +};
  30991. +
  30992. +static void __init tc2_pm_usage_count_init(void)
  30993. +{
  30994. + unsigned int mpidr, cpu, cluster;
  30995. +
  30996. + mpidr = read_cpuid_mpidr();
  30997. + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
  30998. + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
  30999. +
  31000. + pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
  31001. + BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
  31002. +
  31003. + atomic_set(&tc2_pm_use_count[cpu][cluster], 1);
  31004. +}
  31005. +
  31006. +static int __init tc2_pm_psci_init(void)
  31007. +{
  31008. + int ret;
  31009. +
  31010. + ret = psci_probe();
  31011. + if (ret) {
  31012. + pr_debug("psci not found. Aborting psci init\n");
  31013. + return -ENODEV;
  31014. + }
  31015. +
  31016. + if (!of_machine_is_compatible("arm,vexpress,v2p-ca15_a7"))
  31017. + return -ENODEV;
  31018. +
  31019. + tc2_pm_usage_count_init();
  31020. +
  31021. + ret = mcpm_platform_register(&tc2_pm_power_ops);
  31022. + if (!ret)
  31023. + ret = mcpm_sync_init(NULL);
  31024. + if (!ret)
  31025. + pr_info("TC2 power management using PSCI initialized\n");
  31026. + return ret;
  31027. +}
  31028. +
  31029. +early_initcall(tc2_pm_psci_init);
  31030. diff -Nur linux-3.14.15/arch/arm/mach-vexpress/v2m.c linux-linaro-stable-mx6/arch/arm/mach-vexpress/v2m.c
  31031. --- linux-3.14.15/arch/arm/mach-vexpress/v2m.c 2014-07-31 23:51:43.000000000 +0200
  31032. +++ linux-linaro-stable-mx6/arch/arm/mach-vexpress/v2m.c 2014-08-20 19:31:40.416844487 +0200
  31033. @@ -7,6 +7,7 @@
  31034. #include <linux/io.h>
  31035. #include <linux/smp.h>
  31036. #include <linux/init.h>
  31037. +#include <linux/memblock.h>
  31038. #include <linux/of_address.h>
  31039. #include <linux/of_fdt.h>
  31040. #include <linux/of_irq.h>
  31041. @@ -369,6 +370,31 @@
  31042. .init_machine = v2m_init,
  31043. MACHINE_END
  31044. +static void __init v2m_dt_hdlcd_init(void)
  31045. +{
  31046. + struct device_node *node;
  31047. + int len, na, ns;
  31048. + const __be32 *prop;
  31049. + phys_addr_t fb_base, fb_size;
  31050. +
  31051. + node = of_find_compatible_node(NULL, NULL, "arm,hdlcd");
  31052. + if (!node)
  31053. + return;
  31054. +
  31055. + na = of_n_addr_cells(node);
  31056. + ns = of_n_size_cells(node);
  31057. +
  31058. + prop = of_get_property(node, "framebuffer", &len);
  31059. + if (WARN_ON(!prop || len < (na + ns) * sizeof(*prop)))
  31060. + return;
  31061. +
  31062. + fb_base = of_read_number(prop, na);
  31063. + fb_size = of_read_number(prop + na, ns);
  31064. +
  31065. + if (WARN_ON(memblock_remove(fb_base, fb_size)))
  31066. + return;
  31067. +};
  31068. +
  31069. static struct map_desc v2m_rs1_io_desc __initdata = {
  31070. .virtual = V2M_PERIPH,
  31071. .pfn = __phys_to_pfn(0x1c000000),
  31072. @@ -421,6 +447,8 @@
  31073. }
  31074. versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000);
  31075. +
  31076. + v2m_dt_hdlcd_init();
  31077. }
  31078. static const struct of_device_id v2m_dt_bus_match[] __initconst = {
  31079. diff -Nur linux-3.14.15/arch/arm/mach-zynq/common.c linux-linaro-stable-mx6/arch/arm/mach-zynq/common.c
  31080. --- linux-3.14.15/arch/arm/mach-zynq/common.c 2014-07-31 23:51:43.000000000 +0200
  31081. +++ linux-linaro-stable-mx6/arch/arm/mach-zynq/common.c 2014-08-20 19:31:40.420844504 +0200
  31082. @@ -67,7 +67,7 @@
  31083. /*
  31084. * 64KB way size, 8-way associativity, parity disabled
  31085. */
  31086. - l2x0_of_init(0x02060000, 0xF0F0FFFF);
  31087. + l2x0_of_init(0x02000000, 0xf0ffffff);
  31088. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  31089. diff -Nur linux-3.14.15/arch/arm/mm/cache-feroceon-l2.c linux-linaro-stable-mx6/arch/arm/mm/cache-feroceon-l2.c
  31090. --- linux-3.14.15/arch/arm/mm/cache-feroceon-l2.c 2014-07-31 23:51:43.000000000 +0200
  31091. +++ linux-linaro-stable-mx6/arch/arm/mm/cache-feroceon-l2.c 2014-08-20 19:31:40.420844504 +0200
  31092. @@ -343,7 +343,6 @@
  31093. outer_cache.inv_range = feroceon_l2_inv_range;
  31094. outer_cache.clean_range = feroceon_l2_clean_range;
  31095. outer_cache.flush_range = feroceon_l2_flush_range;
  31096. - outer_cache.inv_all = l2_inv_all;
  31097. enable_l2();
  31098. diff -Nur linux-3.14.15/arch/arm/mm/cache-l2x0.c linux-linaro-stable-mx6/arch/arm/mm/cache-l2x0.c
  31099. --- linux-3.14.15/arch/arm/mm/cache-l2x0.c 2014-07-31 23:51:43.000000000 +0200
  31100. +++ linux-linaro-stable-mx6/arch/arm/mm/cache-l2x0.c 2014-08-20 19:31:40.420844504 +0200
  31101. @@ -16,18 +16,33 @@
  31102. * along with this program; if not, write to the Free Software
  31103. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  31104. */
  31105. +#include <linux/cpu.h>
  31106. #include <linux/err.h>
  31107. #include <linux/init.h>
  31108. +#include <linux/smp.h>
  31109. #include <linux/spinlock.h>
  31110. #include <linux/io.h>
  31111. #include <linux/of.h>
  31112. #include <linux/of_address.h>
  31113. #include <asm/cacheflush.h>
  31114. +#include <asm/cp15.h>
  31115. +#include <asm/cputype.h>
  31116. #include <asm/hardware/cache-l2x0.h>
  31117. #include "cache-tauros3.h"
  31118. #include "cache-aurora-l2.h"
  31119. +struct l2c_init_data {
  31120. + const char *type;
  31121. + unsigned way_size_0;
  31122. + unsigned num_lock;
  31123. + void (*of_parse)(const struct device_node *, u32 *, u32 *);
  31124. + void (*enable)(void __iomem *, u32, unsigned);
  31125. + void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
  31126. + void (*save)(void __iomem *);
  31127. + struct outer_cache_fns outer_cache;
  31128. +};
  31129. +
  31130. #define CACHE_LINE_SIZE 32
  31131. static void __iomem *l2x0_base;
  31132. @@ -36,96 +51,116 @@
  31133. static u32 l2x0_size;
  31134. static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
  31135. -/* Aurora don't have the cache ID register available, so we have to
  31136. - * pass it though the device tree */
  31137. -static u32 cache_id_part_number_from_dt;
  31138. -
  31139. struct l2x0_regs l2x0_saved_regs;
  31140. -struct l2x0_of_data {
  31141. - void (*setup)(const struct device_node *, u32 *, u32 *);
  31142. - void (*save)(void);
  31143. - struct outer_cache_fns outer_cache;
  31144. -};
  31145. -
  31146. -static bool of_init = false;
  31147. -
  31148. -static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
  31149. +/*
  31150. + * Common code for all cache controllers.
  31151. + */
  31152. +static inline void l2c_wait_mask(void __iomem *reg, unsigned long mask)
  31153. {
  31154. /* wait for cache operation by line or way to complete */
  31155. while (readl_relaxed(reg) & mask)
  31156. cpu_relax();
  31157. }
  31158. -#ifdef CONFIG_CACHE_PL310
  31159. -static inline void cache_wait(void __iomem *reg, unsigned long mask)
  31160. +/*
  31161. + * By default, we write directly to secure registers. Platforms must
  31162. + * override this if they are running non-secure.
  31163. + */
  31164. +static void l2c_write_sec(unsigned long val, void __iomem *base, unsigned reg)
  31165. {
  31166. - /* cache operations by line are atomic on PL310 */
  31167. + if (val == readl_relaxed(base + reg))
  31168. + return;
  31169. + if (outer_cache.write_sec)
  31170. + outer_cache.write_sec(val, reg);
  31171. + else
  31172. + writel_relaxed(val, base + reg);
  31173. }
  31174. -#else
  31175. -#define cache_wait cache_wait_way
  31176. -#endif
  31177. -static inline void cache_sync(void)
  31178. +/*
  31179. + * This should only be called when we have a requirement that the
  31180. + * register be written due to a work-around, as platforms running
  31181. + * in non-secure mode may not be able to access this register.
  31182. + */
  31183. +static inline void l2c_set_debug(void __iomem *base, unsigned long val)
  31184. {
  31185. - void __iomem *base = l2x0_base;
  31186. -
  31187. - writel_relaxed(0, base + sync_reg_offset);
  31188. - cache_wait(base + L2X0_CACHE_SYNC, 1);
  31189. + l2c_write_sec(val, base, L2X0_DEBUG_CTRL);
  31190. }
  31191. -static inline void l2x0_clean_line(unsigned long addr)
  31192. +static void __l2c_op_way(void __iomem *reg)
  31193. {
  31194. - void __iomem *base = l2x0_base;
  31195. - cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
  31196. - writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
  31197. + writel_relaxed(l2x0_way_mask, reg);
  31198. + l2c_wait_mask(reg, l2x0_way_mask);
  31199. }
  31200. -static inline void l2x0_inv_line(unsigned long addr)
  31201. +static inline void l2c_unlock(void __iomem *base, unsigned num)
  31202. {
  31203. - void __iomem *base = l2x0_base;
  31204. - cache_wait(base + L2X0_INV_LINE_PA, 1);
  31205. - writel_relaxed(addr, base + L2X0_INV_LINE_PA);
  31206. + unsigned i;
  31207. +
  31208. + for (i = 0; i < num; i++) {
  31209. + writel_relaxed(0, base + L2X0_LOCKDOWN_WAY_D_BASE +
  31210. + i * L2X0_LOCKDOWN_STRIDE);
  31211. + writel_relaxed(0, base + L2X0_LOCKDOWN_WAY_I_BASE +
  31212. + i * L2X0_LOCKDOWN_STRIDE);
  31213. + }
  31214. }
  31215. -#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
  31216. -static inline void debug_writel(unsigned long val)
  31217. +/*
  31218. + * Enable the L2 cache controller. This function must only be
  31219. + * called when the cache controller is known to be disabled.
  31220. + */
  31221. +static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
  31222. {
  31223. - if (outer_cache.set_debug)
  31224. - outer_cache.set_debug(val);
  31225. + unsigned long flags;
  31226. +
  31227. + l2c_write_sec(aux, base, L2X0_AUX_CTRL);
  31228. +
  31229. + l2c_unlock(base, num_lock);
  31230. +
  31231. + local_irq_save(flags);
  31232. + __l2c_op_way(base + L2X0_INV_WAY);
  31233. + writel_relaxed(0, base + sync_reg_offset);
  31234. + l2c_wait_mask(base + sync_reg_offset, 1);
  31235. + local_irq_restore(flags);
  31236. +
  31237. + l2c_write_sec(L2X0_CTRL_EN, base, L2X0_CTRL);
  31238. }
  31239. -static void pl310_set_debug(unsigned long val)
  31240. +static void l2c_disable(void)
  31241. {
  31242. - writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
  31243. + void __iomem *base = l2x0_base;
  31244. +
  31245. + outer_cache.flush_all();
  31246. + l2c_write_sec(0, base, L2X0_CTRL);
  31247. + dsb(st);
  31248. }
  31249. -#else
  31250. -/* Optimised out for non-errata case */
  31251. -static inline void debug_writel(unsigned long val)
  31252. +
  31253. +#ifdef CONFIG_CACHE_PL310
  31254. +static inline void cache_wait(void __iomem *reg, unsigned long mask)
  31255. {
  31256. + /* cache operations by line are atomic on PL310 */
  31257. }
  31258. -
  31259. -#define pl310_set_debug NULL
  31260. +#else
  31261. +#define cache_wait l2c_wait_mask
  31262. #endif
  31263. -#ifdef CONFIG_PL310_ERRATA_588369
  31264. -static inline void l2x0_flush_line(unsigned long addr)
  31265. +static inline void cache_sync(void)
  31266. {
  31267. void __iomem *base = l2x0_base;
  31268. - /* Clean by PA followed by Invalidate by PA */
  31269. - cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
  31270. - writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
  31271. - cache_wait(base + L2X0_INV_LINE_PA, 1);
  31272. - writel_relaxed(addr, base + L2X0_INV_LINE_PA);
  31273. + writel_relaxed(0, base + sync_reg_offset);
  31274. + cache_wait(base + L2X0_CACHE_SYNC, 1);
  31275. }
  31276. -#else
  31277. -static inline void l2x0_flush_line(unsigned long addr)
  31278. +#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
  31279. +static inline void debug_writel(unsigned long val)
  31280. +{
  31281. + l2c_set_debug(l2x0_base, val);
  31282. +}
  31283. +#else
  31284. +/* Optimised out for non-errata case */
  31285. +static inline void debug_writel(unsigned long val)
  31286. {
  31287. - void __iomem *base = l2x0_base;
  31288. - cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31289. - writel_relaxed(addr, base + L2X0_CLEAN_INV_LINE_PA);
  31290. }
  31291. #endif
  31292. @@ -141,8 +176,7 @@
  31293. static void __l2x0_flush_all(void)
  31294. {
  31295. debug_writel(0x03);
  31296. - writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
  31297. - cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
  31298. + __l2c_op_way(l2x0_base + L2X0_CLEAN_INV_WAY);
  31299. cache_sync();
  31300. debug_writel(0x00);
  31301. }
  31302. @@ -157,274 +191,882 @@
  31303. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31304. }
  31305. -static void l2x0_clean_all(void)
  31306. +static void l2x0_disable(void)
  31307. {
  31308. unsigned long flags;
  31309. - /* clean all ways */
  31310. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31311. - writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
  31312. - cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
  31313. - cache_sync();
  31314. + __l2x0_flush_all();
  31315. + l2c_write_sec(0, l2x0_base, L2X0_CTRL);
  31316. + dsb(st);
  31317. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31318. }
  31319. -static void l2x0_inv_all(void)
  31320. +static void l2c_save(void __iomem *base)
  31321. {
  31322. - unsigned long flags;
  31323. + l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  31324. +}
  31325. - /* invalidate all ways */
  31326. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31327. - /* Invalidating when L2 is enabled is a nono */
  31328. - BUG_ON(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN);
  31329. - writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
  31330. - cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
  31331. - cache_sync();
  31332. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31333. +/*
  31334. + * L2C-210 specific code.
  31335. + *
  31336. + * The L2C-2x0 PA, set/way and sync operations are atomic, but we must
  31337. + * ensure that no background operation is running. The way operations
  31338. + * are all background tasks.
  31339. + *
  31340. + * While a background operation is in progress, any new operation is
  31341. + * ignored (unspecified whether this causes an error.) Thankfully, not
  31342. + * used on SMP.
  31343. + *
  31344. + * Never has a different sync register other than L2X0_CACHE_SYNC, but
  31345. + * we use sync_reg_offset here so we can share some of this with L2C-310.
  31346. + */
  31347. +static void __l2c210_cache_sync(void __iomem *base)
  31348. +{
  31349. + writel_relaxed(0, base + sync_reg_offset);
  31350. }
  31351. -static void l2x0_inv_range(unsigned long start, unsigned long end)
  31352. +static void __l2c210_op_pa_range(void __iomem *reg, unsigned long start,
  31353. + unsigned long end)
  31354. +{
  31355. + while (start < end) {
  31356. + writel_relaxed(start, reg);
  31357. + start += CACHE_LINE_SIZE;
  31358. + }
  31359. +}
  31360. +
  31361. +static void l2c210_inv_range(unsigned long start, unsigned long end)
  31362. {
  31363. void __iomem *base = l2x0_base;
  31364. - unsigned long flags;
  31365. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31366. if (start & (CACHE_LINE_SIZE - 1)) {
  31367. start &= ~(CACHE_LINE_SIZE - 1);
  31368. - debug_writel(0x03);
  31369. - l2x0_flush_line(start);
  31370. - debug_writel(0x00);
  31371. + writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
  31372. start += CACHE_LINE_SIZE;
  31373. }
  31374. if (end & (CACHE_LINE_SIZE - 1)) {
  31375. end &= ~(CACHE_LINE_SIZE - 1);
  31376. - debug_writel(0x03);
  31377. - l2x0_flush_line(end);
  31378. - debug_writel(0x00);
  31379. + writel_relaxed(end, base + L2X0_CLEAN_INV_LINE_PA);
  31380. }
  31381. + __l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
  31382. + __l2c210_cache_sync(base);
  31383. +}
  31384. +
  31385. +static void l2c210_clean_range(unsigned long start, unsigned long end)
  31386. +{
  31387. + void __iomem *base = l2x0_base;
  31388. +
  31389. + start &= ~(CACHE_LINE_SIZE - 1);
  31390. + __l2c210_op_pa_range(base + L2X0_CLEAN_LINE_PA, start, end);
  31391. + __l2c210_cache_sync(base);
  31392. +}
  31393. +
  31394. +static void l2c210_flush_range(unsigned long start, unsigned long end)
  31395. +{
  31396. + void __iomem *base = l2x0_base;
  31397. +
  31398. + start &= ~(CACHE_LINE_SIZE - 1);
  31399. + __l2c210_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA, start, end);
  31400. + __l2c210_cache_sync(base);
  31401. +}
  31402. +
  31403. +static void l2c210_flush_all(void)
  31404. +{
  31405. + void __iomem *base = l2x0_base;
  31406. +
  31407. + BUG_ON(!irqs_disabled());
  31408. +
  31409. + __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
  31410. + __l2c210_cache_sync(base);
  31411. +}
  31412. +
  31413. +static void l2c210_sync(void)
  31414. +{
  31415. + __l2c210_cache_sync(l2x0_base);
  31416. +}
  31417. +
  31418. +static void l2c210_resume(void)
  31419. +{
  31420. + void __iomem *base = l2x0_base;
  31421. +
  31422. + if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
  31423. + l2c_enable(base, l2x0_saved_regs.aux_ctrl, 1);
  31424. +}
  31425. +
  31426. +static const struct l2c_init_data l2c210_data __initconst = {
  31427. + .type = "L2C-210",
  31428. + .way_size_0 = SZ_8K,
  31429. + .num_lock = 1,
  31430. + .enable = l2c_enable,
  31431. + .save = l2c_save,
  31432. + .outer_cache = {
  31433. + .inv_range = l2c210_inv_range,
  31434. + .clean_range = l2c210_clean_range,
  31435. + .flush_range = l2c210_flush_range,
  31436. + .flush_all = l2c210_flush_all,
  31437. + .disable = l2c_disable,
  31438. + .sync = l2c210_sync,
  31439. + .resume = l2c210_resume,
  31440. + },
  31441. +};
  31442. +
  31443. +/*
  31444. + * L2C-220 specific code.
  31445. + *
  31446. + * All operations are background operations: they have to be waited for.
  31447. + * Conflicting requests generate a slave error (which will cause an
  31448. + * imprecise abort.) Never uses sync_reg_offset, so we hard-code the
  31449. + * sync register here.
  31450. + *
  31451. + * However, we can re-use the l2c210_resume call.
  31452. + */
  31453. +static inline void __l2c220_cache_sync(void __iomem *base)
  31454. +{
  31455. + writel_relaxed(0, base + L2X0_CACHE_SYNC);
  31456. + l2c_wait_mask(base + L2X0_CACHE_SYNC, 1);
  31457. +}
  31458. +
  31459. +static void l2c220_op_way(void __iomem *base, unsigned reg)
  31460. +{
  31461. + unsigned long flags;
  31462. +
  31463. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31464. + __l2c_op_way(base + reg);
  31465. + __l2c220_cache_sync(base);
  31466. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31467. +}
  31468. +
  31469. +static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long start,
  31470. + unsigned long end, unsigned long flags)
  31471. +{
  31472. + raw_spinlock_t *lock = &l2x0_lock;
  31473. +
  31474. while (start < end) {
  31475. unsigned long blk_end = start + min(end - start, 4096UL);
  31476. while (start < blk_end) {
  31477. - l2x0_inv_line(start);
  31478. + l2c_wait_mask(reg, 1);
  31479. + writel_relaxed(start, reg);
  31480. start += CACHE_LINE_SIZE;
  31481. }
  31482. if (blk_end < end) {
  31483. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31484. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31485. + raw_spin_unlock_irqrestore(lock, flags);
  31486. + raw_spin_lock_irqsave(lock, flags);
  31487. }
  31488. }
  31489. - cache_wait(base + L2X0_INV_LINE_PA, 1);
  31490. - cache_sync();
  31491. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31492. +
  31493. + return flags;
  31494. }
  31495. -static void l2x0_clean_range(unsigned long start, unsigned long end)
  31496. +static void l2c220_inv_range(unsigned long start, unsigned long end)
  31497. {
  31498. void __iomem *base = l2x0_base;
  31499. unsigned long flags;
  31500. - if ((end - start) >= l2x0_size) {
  31501. - l2x0_clean_all();
  31502. - return;
  31503. - }
  31504. -
  31505. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31506. - start &= ~(CACHE_LINE_SIZE - 1);
  31507. - while (start < end) {
  31508. - unsigned long blk_end = start + min(end - start, 4096UL);
  31509. -
  31510. - while (start < blk_end) {
  31511. - l2x0_clean_line(start);
  31512. + if ((start | end) & (CACHE_LINE_SIZE - 1)) {
  31513. + if (start & (CACHE_LINE_SIZE - 1)) {
  31514. + start &= ~(CACHE_LINE_SIZE - 1);
  31515. + writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
  31516. start += CACHE_LINE_SIZE;
  31517. }
  31518. - if (blk_end < end) {
  31519. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31520. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31521. + if (end & (CACHE_LINE_SIZE - 1)) {
  31522. + end &= ~(CACHE_LINE_SIZE - 1);
  31523. + l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31524. + writel_relaxed(end, base + L2X0_CLEAN_INV_LINE_PA);
  31525. }
  31526. }
  31527. - cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
  31528. - cache_sync();
  31529. +
  31530. + flags = l2c220_op_pa_range(base + L2X0_INV_LINE_PA,
  31531. + start, end, flags);
  31532. + l2c_wait_mask(base + L2X0_INV_LINE_PA, 1);
  31533. + __l2c220_cache_sync(base);
  31534. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31535. }
  31536. -static void l2x0_flush_range(unsigned long start, unsigned long end)
  31537. +static void l2c220_clean_range(unsigned long start, unsigned long end)
  31538. {
  31539. void __iomem *base = l2x0_base;
  31540. unsigned long flags;
  31541. + start &= ~(CACHE_LINE_SIZE - 1);
  31542. if ((end - start) >= l2x0_size) {
  31543. - l2x0_flush_all();
  31544. + l2c220_op_way(base, L2X0_CLEAN_WAY);
  31545. return;
  31546. }
  31547. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31548. + flags = l2c220_op_pa_range(base + L2X0_CLEAN_LINE_PA,
  31549. + start, end, flags);
  31550. + l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31551. + __l2c220_cache_sync(base);
  31552. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31553. +}
  31554. +
  31555. +static void l2c220_flush_range(unsigned long start, unsigned long end)
  31556. +{
  31557. + void __iomem *base = l2x0_base;
  31558. + unsigned long flags;
  31559. +
  31560. start &= ~(CACHE_LINE_SIZE - 1);
  31561. + if ((end - start) >= l2x0_size) {
  31562. + l2c220_op_way(base, L2X0_CLEAN_INV_WAY);
  31563. + return;
  31564. + }
  31565. +
  31566. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31567. + flags = l2c220_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA,
  31568. + start, end, flags);
  31569. + l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31570. + __l2c220_cache_sync(base);
  31571. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31572. +}
  31573. +
  31574. +static void l2c220_flush_all(void)
  31575. +{
  31576. + l2c220_op_way(l2x0_base, L2X0_CLEAN_INV_WAY);
  31577. +}
  31578. +
  31579. +static void l2c220_sync(void)
  31580. +{
  31581. + unsigned long flags;
  31582. +
  31583. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31584. + __l2c220_cache_sync(l2x0_base);
  31585. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31586. +}
  31587. +
  31588. +static void l2c220_enable(void __iomem *base, u32 aux, unsigned num_lock)
  31589. +{
  31590. + /*
  31591. + * Always enable non-secure access to the lockdown registers -
  31592. + * we write to them as part of the L2C enable sequence so they
  31593. + * need to be accessible.
  31594. + */
  31595. + aux |= L220_AUX_CTRL_NS_LOCKDOWN;
  31596. +
  31597. + l2c_enable(base, aux, num_lock);
  31598. +}
  31599. +
  31600. +static const struct l2c_init_data l2c220_data = {
  31601. + .type = "L2C-220",
  31602. + .way_size_0 = SZ_8K,
  31603. + .num_lock = 1,
  31604. + .enable = l2c220_enable,
  31605. + .save = l2c_save,
  31606. + .outer_cache = {
  31607. + .inv_range = l2c220_inv_range,
  31608. + .clean_range = l2c220_clean_range,
  31609. + .flush_range = l2c220_flush_range,
  31610. + .flush_all = l2c220_flush_all,
  31611. + .disable = l2c_disable,
  31612. + .sync = l2c220_sync,
  31613. + .resume = l2c210_resume,
  31614. + },
  31615. +};
  31616. +
  31617. +/*
  31618. + * L2C-310 specific code.
  31619. + *
  31620. + * Very similar to L2C-210, the PA, set/way and sync operations are atomic,
  31621. + * and the way operations are all background tasks. However, issuing an
  31622. + * operation while a background operation is in progress results in a
  31623. + * SLVERR response. We can reuse:
  31624. + *
  31625. + * __l2c210_cache_sync (using sync_reg_offset)
  31626. + * l2c210_sync
  31627. + * l2c210_inv_range (if 588369 is not applicable)
  31628. + * l2c210_clean_range
  31629. + * l2c210_flush_range (if 588369 is not applicable)
  31630. + * l2c210_flush_all (if 727915 is not applicable)
  31631. + *
  31632. + * Errata:
  31633. + * 588369: PL310 R0P0->R1P0, fixed R2P0.
  31634. + * Affects: all clean+invalidate operations
  31635. + * clean and invalidate skips the invalidate step, so we need to issue
  31636. + * separate operations. We also require the above debug workaround
  31637. + * enclosing this code fragment on affected parts. On unaffected parts,
  31638. + * we must not use this workaround without the debug register writes
  31639. + * to avoid exposing a problem similar to 727915.
  31640. + *
  31641. + * 727915: PL310 R2P0->R3P0, fixed R3P1.
  31642. + * Affects: clean+invalidate by way
  31643. + * clean and invalidate by way runs in the background, and a store can
  31644. + * hit the line between the clean operation and invalidate operation,
  31645. + * resulting in the store being lost.
  31646. + *
  31647. + * 752271: PL310 R3P0->R3P1-50REL0, fixed R3P2.
  31648. + * Affects: 8x64-bit (double fill) line fetches
  31649. + * double fill line fetches can fail to cause dirty data to be evicted
  31650. + * from the cache before the new data overwrites the second line.
  31651. + *
  31652. + * 753970: PL310 R3P0, fixed R3P1.
  31653. + * Affects: sync
  31654. + * prevents merging writes after the sync operation, until another L2C
  31655. + * operation is performed (or a number of other conditions.)
  31656. + *
  31657. + * 769419: PL310 R0P0->R3P1, fixed R3P2.
  31658. + * Affects: store buffer
  31659. + * store buffer is not automatically drained.
  31660. + */
  31661. +static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
  31662. +{
  31663. + void __iomem *base = l2x0_base;
  31664. +
  31665. + if ((start | end) & (CACHE_LINE_SIZE - 1)) {
  31666. + unsigned long flags;
  31667. +
  31668. + /* Erratum 588369 for both clean+invalidate operations */
  31669. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31670. + l2c_set_debug(base, 0x03);
  31671. +
  31672. + if (start & (CACHE_LINE_SIZE - 1)) {
  31673. + start &= ~(CACHE_LINE_SIZE - 1);
  31674. + writel_relaxed(start, base + L2X0_CLEAN_LINE_PA);
  31675. + writel_relaxed(start, base + L2X0_INV_LINE_PA);
  31676. + start += CACHE_LINE_SIZE;
  31677. + }
  31678. +
  31679. + if (end & (CACHE_LINE_SIZE - 1)) {
  31680. + end &= ~(CACHE_LINE_SIZE - 1);
  31681. + writel_relaxed(end, base + L2X0_CLEAN_LINE_PA);
  31682. + writel_relaxed(end, base + L2X0_INV_LINE_PA);
  31683. + }
  31684. +
  31685. + l2c_set_debug(base, 0x00);
  31686. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31687. + }
  31688. +
  31689. + __l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
  31690. + __l2c210_cache_sync(base);
  31691. +}
  31692. +
  31693. +static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
  31694. +{
  31695. + raw_spinlock_t *lock = &l2x0_lock;
  31696. + unsigned long flags;
  31697. + void __iomem *base = l2x0_base;
  31698. +
  31699. + raw_spin_lock_irqsave(lock, flags);
  31700. while (start < end) {
  31701. unsigned long blk_end = start + min(end - start, 4096UL);
  31702. - debug_writel(0x03);
  31703. + l2c_set_debug(base, 0x03);
  31704. while (start < blk_end) {
  31705. - l2x0_flush_line(start);
  31706. + writel_relaxed(start, base + L2X0_CLEAN_LINE_PA);
  31707. + writel_relaxed(start, base + L2X0_INV_LINE_PA);
  31708. start += CACHE_LINE_SIZE;
  31709. }
  31710. - debug_writel(0x00);
  31711. + l2c_set_debug(base, 0x00);
  31712. if (blk_end < end) {
  31713. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31714. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31715. + raw_spin_unlock_irqrestore(lock, flags);
  31716. + raw_spin_lock_irqsave(lock, flags);
  31717. }
  31718. }
  31719. - cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31720. - cache_sync();
  31721. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31722. + raw_spin_unlock_irqrestore(lock, flags);
  31723. + __l2c210_cache_sync(base);
  31724. }
  31725. -static void l2x0_disable(void)
  31726. +static void l2c310_flush_all_erratum(void)
  31727. {
  31728. + void __iomem *base = l2x0_base;
  31729. unsigned long flags;
  31730. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31731. - __l2x0_flush_all();
  31732. - writel_relaxed(0, l2x0_base + L2X0_CTRL);
  31733. - dsb(st);
  31734. + l2c_set_debug(base, 0x03);
  31735. + __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
  31736. + l2c_set_debug(base, 0x00);
  31737. + __l2c210_cache_sync(base);
  31738. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31739. }
  31740. -static void l2x0_unlock(u32 cache_id)
  31741. +static void __init l2c310_save(void __iomem *base)
  31742. {
  31743. - int lockregs;
  31744. - int i;
  31745. + unsigned revision;
  31746. - switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
  31747. - case L2X0_CACHE_ID_PART_L310:
  31748. - lockregs = 8;
  31749. - break;
  31750. - case AURORA_CACHE_ID:
  31751. - lockregs = 4;
  31752. + l2c_save(base);
  31753. +
  31754. + l2x0_saved_regs.tag_latency = readl_relaxed(base +
  31755. + L310_TAG_LATENCY_CTRL);
  31756. + l2x0_saved_regs.data_latency = readl_relaxed(base +
  31757. + L310_DATA_LATENCY_CTRL);
  31758. + l2x0_saved_regs.filter_end = readl_relaxed(base +
  31759. + L310_ADDR_FILTER_END);
  31760. + l2x0_saved_regs.filter_start = readl_relaxed(base +
  31761. + L310_ADDR_FILTER_START);
  31762. +
  31763. + revision = readl_relaxed(base + L2X0_CACHE_ID) &
  31764. + L2X0_CACHE_ID_RTL_MASK;
  31765. +
  31766. + /* From r2p0, there is Prefetch offset/control register */
  31767. + if (revision >= L310_CACHE_ID_RTL_R2P0)
  31768. + l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base +
  31769. + L310_PREFETCH_CTRL);
  31770. +
  31771. + /* From r3p0, there is Power control register */
  31772. + if (revision >= L310_CACHE_ID_RTL_R3P0)
  31773. + l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
  31774. + L310_POWER_CTRL);
  31775. +}
  31776. +
  31777. +static void l2c310_resume(void)
  31778. +{
  31779. + void __iomem *base = l2x0_base;
  31780. +
  31781. + if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  31782. + unsigned revision;
  31783. +
  31784. + /* restore pl310 setup */
  31785. + writel_relaxed(l2x0_saved_regs.tag_latency,
  31786. + base + L310_TAG_LATENCY_CTRL);
  31787. + writel_relaxed(l2x0_saved_regs.data_latency,
  31788. + base + L310_DATA_LATENCY_CTRL);
  31789. + writel_relaxed(l2x0_saved_regs.filter_end,
  31790. + base + L310_ADDR_FILTER_END);
  31791. + writel_relaxed(l2x0_saved_regs.filter_start,
  31792. + base + L310_ADDR_FILTER_START);
  31793. +
  31794. + revision = readl_relaxed(base + L2X0_CACHE_ID) &
  31795. + L2X0_CACHE_ID_RTL_MASK;
  31796. +
  31797. + if (revision >= L310_CACHE_ID_RTL_R2P0)
  31798. + l2c_write_sec(l2x0_saved_regs.prefetch_ctrl, base,
  31799. + L310_PREFETCH_CTRL);
  31800. + if (revision >= L310_CACHE_ID_RTL_R3P0)
  31801. + l2c_write_sec(l2x0_saved_regs.pwr_ctrl, base,
  31802. + L310_POWER_CTRL);
  31803. +
  31804. + l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
  31805. +
  31806. + /* Re-enable full-line-of-zeros for Cortex-A9 */
  31807. + if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
  31808. + set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
  31809. + }
  31810. +}
  31811. +
  31812. +static int l2c310_cpu_enable_flz(struct notifier_block *nb, unsigned long act, void *data)
  31813. +{
  31814. + switch (act & ~CPU_TASKS_FROZEN) {
  31815. + case CPU_STARTING:
  31816. + set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
  31817. break;
  31818. - default:
  31819. - /* L210 and unknown types */
  31820. - lockregs = 1;
  31821. + case CPU_DYING:
  31822. + set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
  31823. break;
  31824. }
  31825. + return NOTIFY_OK;
  31826. +}
  31827. - for (i = 0; i < lockregs; i++) {
  31828. - writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
  31829. - i * L2X0_LOCKDOWN_STRIDE);
  31830. - writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE +
  31831. - i * L2X0_LOCKDOWN_STRIDE);
  31832. +static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
  31833. +{
  31834. + unsigned rev = readl_relaxed(base + L2X0_CACHE_ID) & L2X0_CACHE_ID_PART_MASK;
  31835. + bool cortex_a9 = read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9;
  31836. +
  31837. + if (rev >= L310_CACHE_ID_RTL_R2P0) {
  31838. + if (cortex_a9) {
  31839. + aux |= L310_AUX_CTRL_EARLY_BRESP;
  31840. + pr_info("L2C-310 enabling early BRESP for Cortex-A9\n");
  31841. + } else if (aux & L310_AUX_CTRL_EARLY_BRESP) {
  31842. + pr_warn("L2C-310 early BRESP only supported with Cortex-A9\n");
  31843. + aux &= ~L310_AUX_CTRL_EARLY_BRESP;
  31844. + }
  31845. + }
  31846. +
  31847. + if (cortex_a9) {
  31848. + u32 aux_cur = readl_relaxed(base + L2X0_AUX_CTRL);
  31849. + u32 acr = get_auxcr();
  31850. +
  31851. + pr_debug("Cortex-A9 ACR=0x%08x\n", acr);
  31852. +
  31853. + if (acr & BIT(3) && !(aux_cur & L310_AUX_CTRL_FULL_LINE_ZERO))
  31854. + pr_err("L2C-310: full line of zeros enabled in Cortex-A9 but not L2C-310 - invalid\n");
  31855. +
  31856. + if (aux & L310_AUX_CTRL_FULL_LINE_ZERO && !(acr & BIT(3)))
  31857. + pr_err("L2C-310: enabling full line of zeros but not enabled in Cortex-A9\n");
  31858. +
  31859. + if (!(aux & L310_AUX_CTRL_FULL_LINE_ZERO) && !outer_cache.write_sec) {
  31860. + aux |= L310_AUX_CTRL_FULL_LINE_ZERO;
  31861. + pr_info("L2C-310 full line of zeros enabled for Cortex-A9\n");
  31862. + }
  31863. + } else if (aux & (L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP)) {
  31864. + pr_err("L2C-310: disabling Cortex-A9 specific feature bits\n");
  31865. + aux &= ~(L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP);
  31866. + }
  31867. +
  31868. + if (aux & (L310_AUX_CTRL_DATA_PREFETCH | L310_AUX_CTRL_INSTR_PREFETCH)) {
  31869. + u32 prefetch = readl_relaxed(base + L310_PREFETCH_CTRL);
  31870. +
  31871. + pr_info("L2C-310 %s%s prefetch enabled, offset %u lines\n",
  31872. + aux & L310_AUX_CTRL_INSTR_PREFETCH ? "I" : "",
  31873. + aux & L310_AUX_CTRL_DATA_PREFETCH ? "D" : "",
  31874. + 1 + (prefetch & L310_PREFETCH_CTRL_OFFSET_MASK));
  31875. + }
  31876. +
  31877. + /* r3p0 or later has power control register */
  31878. + if (rev >= L310_CACHE_ID_RTL_R3P0) {
  31879. + u32 power_ctrl;
  31880. +
  31881. + l2c_write_sec(L310_DYNAMIC_CLK_GATING_EN | L310_STNDBY_MODE_EN,
  31882. + base, L310_POWER_CTRL);
  31883. + power_ctrl = readl_relaxed(base + L310_POWER_CTRL);
  31884. + pr_info("L2C-310 dynamic clock gating %sabled, standby mode %sabled\n",
  31885. + power_ctrl & L310_DYNAMIC_CLK_GATING_EN ? "en" : "dis",
  31886. + power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis");
  31887. + }
  31888. +
  31889. + /*
  31890. + * Always enable non-secure access to the lockdown registers -
  31891. + * we write to them as part of the L2C enable sequence so they
  31892. + * need to be accessible.
  31893. + */
  31894. + aux |= L310_AUX_CTRL_NS_LOCKDOWN;
  31895. +
  31896. + l2c_enable(base, aux, num_lock);
  31897. +
  31898. + if (aux & L310_AUX_CTRL_FULL_LINE_ZERO) {
  31899. + set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
  31900. + cpu_notifier(l2c310_cpu_enable_flz, 0);
  31901. }
  31902. }
  31903. -void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
  31904. +static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
  31905. + struct outer_cache_fns *fns)
  31906. {
  31907. - u32 aux;
  31908. - u32 cache_id;
  31909. - u32 way_size = 0;
  31910. - int ways;
  31911. - int way_size_shift = L2X0_WAY_SIZE_SHIFT;
  31912. - const char *type;
  31913. + unsigned revision = cache_id & L2X0_CACHE_ID_RTL_MASK;
  31914. + const char *errata[8];
  31915. + unsigned n = 0;
  31916. - l2x0_base = base;
  31917. - if (cache_id_part_number_from_dt)
  31918. - cache_id = cache_id_part_number_from_dt;
  31919. - else
  31920. - cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
  31921. - aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  31922. + if (IS_ENABLED(CONFIG_PL310_ERRATA_588369) &&
  31923. + revision < L310_CACHE_ID_RTL_R2P0 &&
  31924. + /* For bcm compatibility */
  31925. + fns->inv_range == l2c210_inv_range) {
  31926. + fns->inv_range = l2c310_inv_range_erratum;
  31927. + fns->flush_range = l2c310_flush_range_erratum;
  31928. + errata[n++] = "588369";
  31929. + }
  31930. +
  31931. + if (IS_ENABLED(CONFIG_PL310_ERRATA_727915) &&
  31932. + revision >= L310_CACHE_ID_RTL_R2P0 &&
  31933. + revision < L310_CACHE_ID_RTL_R3P1) {
  31934. + fns->flush_all = l2c310_flush_all_erratum;
  31935. + errata[n++] = "727915";
  31936. + }
  31937. +
  31938. + if (revision >= L310_CACHE_ID_RTL_R3P0 &&
  31939. + revision < L310_CACHE_ID_RTL_R3P2) {
  31940. + u32 val = readl_relaxed(base + L310_PREFETCH_CTRL);
  31941. + /* I don't think bit23 is required here... but iMX6 does so */
  31942. + if (val & (BIT(30) | BIT(23))) {
  31943. + val &= ~(BIT(30) | BIT(23));
  31944. + l2c_write_sec(val, base, L310_PREFETCH_CTRL);
  31945. + errata[n++] = "752271";
  31946. + }
  31947. + }
  31948. +
  31949. + if (IS_ENABLED(CONFIG_PL310_ERRATA_753970) &&
  31950. + revision == L310_CACHE_ID_RTL_R3P0) {
  31951. + sync_reg_offset = L2X0_DUMMY_REG;
  31952. + errata[n++] = "753970";
  31953. + }
  31954. +
  31955. + if (IS_ENABLED(CONFIG_PL310_ERRATA_769419))
  31956. + errata[n++] = "769419";
  31957. +
  31958. + if (n) {
  31959. + unsigned i;
  31960. +
  31961. + pr_info("L2C-310 errat%s", n > 1 ? "a" : "um");
  31962. + for (i = 0; i < n; i++)
  31963. + pr_cont(" %s", errata[i]);
  31964. + pr_cont(" enabled\n");
  31965. + }
  31966. +}
  31967. +
  31968. +static void l2c310_disable(void)
  31969. +{
  31970. + /*
  31971. + * If full-line-of-zeros is enabled, we must first disable it in the
  31972. + * Cortex-A9 auxiliary control register before disabling the L2 cache.
  31973. + */
  31974. + if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
  31975. + set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
  31976. + l2c_disable();
  31977. +}
  31978. +
  31979. +static const struct l2c_init_data l2c310_init_fns __initconst = {
  31980. + .type = "L2C-310",
  31981. + .way_size_0 = SZ_8K,
  31982. + .num_lock = 8,
  31983. + .enable = l2c310_enable,
  31984. + .fixup = l2c310_fixup,
  31985. + .save = l2c310_save,
  31986. + .outer_cache = {
  31987. + .inv_range = l2c210_inv_range,
  31988. + .clean_range = l2c210_clean_range,
  31989. + .flush_range = l2c210_flush_range,
  31990. + .flush_all = l2c210_flush_all,
  31991. + .disable = l2c310_disable,
  31992. + .sync = l2c210_sync,
  31993. + .resume = l2c310_resume,
  31994. + },
  31995. +};
  31996. +
  31997. +static void __init __l2c_init(const struct l2c_init_data *data,
  31998. + u32 aux_val, u32 aux_mask, u32 cache_id)
  31999. +{
  32000. + struct outer_cache_fns fns;
  32001. + unsigned way_size_bits, ways;
  32002. + u32 aux, old_aux;
  32003. +
  32004. + /*
  32005. + * Sanity check the aux values. aux_mask is the bits we preserve
  32006. + * from reading the hardware register, and aux_val is the bits we
  32007. + * set.
  32008. + */
  32009. + if (aux_val & aux_mask)
  32010. + pr_alert("L2C: platform provided aux values permit register corruption.\n");
  32011. +
  32012. + old_aux = aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32013. aux &= aux_mask;
  32014. aux |= aux_val;
  32015. + if (old_aux != aux)
  32016. + pr_warn("L2C: DT/platform modifies aux control register: 0x%08x -> 0x%08x\n",
  32017. + old_aux, aux);
  32018. +
  32019. /* Determine the number of ways */
  32020. switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
  32021. case L2X0_CACHE_ID_PART_L310:
  32022. + if ((aux_val | ~aux_mask) & (L2C_AUX_CTRL_WAY_SIZE_MASK | L310_AUX_CTRL_ASSOCIATIVITY_16))
  32023. + pr_warn("L2C: DT/platform tries to modify or specify cache size\n");
  32024. if (aux & (1 << 16))
  32025. ways = 16;
  32026. else
  32027. ways = 8;
  32028. - type = "L310";
  32029. -#ifdef CONFIG_PL310_ERRATA_753970
  32030. - /* Unmapped register. */
  32031. - sync_reg_offset = L2X0_DUMMY_REG;
  32032. -#endif
  32033. - if ((cache_id & L2X0_CACHE_ID_RTL_MASK) <= L2X0_CACHE_ID_RTL_R3P0)
  32034. - outer_cache.set_debug = pl310_set_debug;
  32035. break;
  32036. +
  32037. case L2X0_CACHE_ID_PART_L210:
  32038. + case L2X0_CACHE_ID_PART_L220:
  32039. ways = (aux >> 13) & 0xf;
  32040. - type = "L210";
  32041. break;
  32042. case AURORA_CACHE_ID:
  32043. - sync_reg_offset = AURORA_SYNC_REG;
  32044. ways = (aux >> 13) & 0xf;
  32045. ways = 2 << ((ways + 1) >> 2);
  32046. - way_size_shift = AURORA_WAY_SIZE_SHIFT;
  32047. - type = "Aurora";
  32048. break;
  32049. +
  32050. default:
  32051. /* Assume unknown chips have 8 ways */
  32052. ways = 8;
  32053. - type = "L2x0 series";
  32054. break;
  32055. }
  32056. l2x0_way_mask = (1 << ways) - 1;
  32057. /*
  32058. - * L2 cache Size = Way size * Number of ways
  32059. + * way_size_0 is the size that a way_size value of zero would be
  32060. + * given the calculation: way_size = way_size_0 << way_size_bits.
  32061. + * So, if way_size_bits=0 is reserved, but way_size_bits=1 is 16k,
  32062. + * then way_size_0 would be 8k.
  32063. + *
  32064. + * L2 cache size = number of ways * way size.
  32065. + */
  32066. + way_size_bits = (aux & L2C_AUX_CTRL_WAY_SIZE_MASK) >>
  32067. + L2C_AUX_CTRL_WAY_SIZE_SHIFT;
  32068. + l2x0_size = ways * (data->way_size_0 << way_size_bits);
  32069. +
  32070. + fns = data->outer_cache;
  32071. + fns.write_sec = outer_cache.write_sec;
  32072. + if (data->fixup)
  32073. + data->fixup(l2x0_base, cache_id, &fns);
  32074. +
  32075. + /*
  32076. + * Check if l2x0 controller is already enabled. If we are booting
  32077. + * in non-secure mode accessing the below registers will fault.
  32078. */
  32079. - way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
  32080. - way_size = 1 << (way_size + way_size_shift);
  32081. + if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
  32082. + data->enable(l2x0_base, aux, data->num_lock);
  32083. - l2x0_size = ways * way_size * SZ_1K;
  32084. + outer_cache = fns;
  32085. /*
  32086. - * Check if l2x0 controller is already enabled.
  32087. - * If you are booting from non-secure mode
  32088. - * accessing the below registers will fault.
  32089. + * It is strange to save the register state before initialisation,
  32090. + * but hey, this is what the DT implementations decided to do.
  32091. */
  32092. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32093. - /* Make sure that I&D is not locked down when starting */
  32094. - l2x0_unlock(cache_id);
  32095. + if (data->save)
  32096. + data->save(l2x0_base);
  32097. +
  32098. + /* Re-read it in case some bits are reserved. */
  32099. + aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32100. +
  32101. + pr_info("%s cache controller enabled, %d ways, %d kB\n",
  32102. + data->type, ways, l2x0_size >> 10);
  32103. + pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
  32104. + data->type, cache_id, aux);
  32105. +}
  32106. - /* l2x0 controller is disabled */
  32107. - writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
  32108. +void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
  32109. +{
  32110. + const struct l2c_init_data *data;
  32111. + u32 cache_id;
  32112. - l2x0_inv_all();
  32113. + l2x0_base = base;
  32114. - /* enable L2X0 */
  32115. - writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
  32116. + cache_id = readl_relaxed(base + L2X0_CACHE_ID);
  32117. +
  32118. + switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
  32119. + default:
  32120. + case L2X0_CACHE_ID_PART_L210:
  32121. + data = &l2c210_data;
  32122. + break;
  32123. +
  32124. + case L2X0_CACHE_ID_PART_L220:
  32125. + data = &l2c220_data;
  32126. + break;
  32127. +
  32128. + case L2X0_CACHE_ID_PART_L310:
  32129. + data = &l2c310_init_fns;
  32130. + break;
  32131. }
  32132. - /* Re-read it in case some bits are reserved. */
  32133. - aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32134. + __l2c_init(data, aux_val, aux_mask, cache_id);
  32135. +}
  32136. +
  32137. +#ifdef CONFIG_OF
  32138. +static int l2_wt_override;
  32139. +
  32140. +/* Aurora don't have the cache ID register available, so we have to
  32141. + * pass it though the device tree */
  32142. +static u32 cache_id_part_number_from_dt;
  32143. +
  32144. +static void __init l2x0_of_parse(const struct device_node *np,
  32145. + u32 *aux_val, u32 *aux_mask)
  32146. +{
  32147. + u32 data[2] = { 0, 0 };
  32148. + u32 tag = 0;
  32149. + u32 dirty = 0;
  32150. + u32 val = 0, mask = 0;
  32151. +
  32152. + of_property_read_u32(np, "arm,tag-latency", &tag);
  32153. + if (tag) {
  32154. + mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
  32155. + val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
  32156. + }
  32157. +
  32158. + of_property_read_u32_array(np, "arm,data-latency",
  32159. + data, ARRAY_SIZE(data));
  32160. + if (data[0] && data[1]) {
  32161. + mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
  32162. + L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
  32163. + val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
  32164. + ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
  32165. + }
  32166. +
  32167. + of_property_read_u32(np, "arm,dirty-latency", &dirty);
  32168. + if (dirty) {
  32169. + mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
  32170. + val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
  32171. + }
  32172. - /* Save the value for resuming. */
  32173. - l2x0_saved_regs.aux_ctrl = aux;
  32174. + *aux_val &= ~mask;
  32175. + *aux_val |= val;
  32176. + *aux_mask &= ~mask;
  32177. +}
  32178. +
  32179. +static const struct l2c_init_data of_l2c210_data __initconst = {
  32180. + .type = "L2C-210",
  32181. + .way_size_0 = SZ_8K,
  32182. + .num_lock = 1,
  32183. + .of_parse = l2x0_of_parse,
  32184. + .enable = l2c_enable,
  32185. + .save = l2c_save,
  32186. + .outer_cache = {
  32187. + .inv_range = l2c210_inv_range,
  32188. + .clean_range = l2c210_clean_range,
  32189. + .flush_range = l2c210_flush_range,
  32190. + .flush_all = l2c210_flush_all,
  32191. + .disable = l2c_disable,
  32192. + .sync = l2c210_sync,
  32193. + .resume = l2c210_resume,
  32194. + },
  32195. +};
  32196. +
  32197. +static const struct l2c_init_data of_l2c220_data __initconst = {
  32198. + .type = "L2C-220",
  32199. + .way_size_0 = SZ_8K,
  32200. + .num_lock = 1,
  32201. + .of_parse = l2x0_of_parse,
  32202. + .enable = l2c220_enable,
  32203. + .save = l2c_save,
  32204. + .outer_cache = {
  32205. + .inv_range = l2c220_inv_range,
  32206. + .clean_range = l2c220_clean_range,
  32207. + .flush_range = l2c220_flush_range,
  32208. + .flush_all = l2c220_flush_all,
  32209. + .disable = l2c_disable,
  32210. + .sync = l2c220_sync,
  32211. + .resume = l2c210_resume,
  32212. + },
  32213. +};
  32214. +
  32215. +static void __init l2c310_of_parse(const struct device_node *np,
  32216. + u32 *aux_val, u32 *aux_mask)
  32217. +{
  32218. + u32 data[3] = { 0, 0, 0 };
  32219. + u32 tag[3] = { 0, 0, 0 };
  32220. + u32 filter[2] = { 0, 0 };
  32221. +
  32222. + of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
  32223. + if (tag[0] && tag[1] && tag[2])
  32224. + writel_relaxed(
  32225. + L310_LATENCY_CTRL_RD(tag[0] - 1) |
  32226. + L310_LATENCY_CTRL_WR(tag[1] - 1) |
  32227. + L310_LATENCY_CTRL_SETUP(tag[2] - 1),
  32228. + l2x0_base + L310_TAG_LATENCY_CTRL);
  32229. +
  32230. + of_property_read_u32_array(np, "arm,data-latency",
  32231. + data, ARRAY_SIZE(data));
  32232. + if (data[0] && data[1] && data[2])
  32233. + writel_relaxed(
  32234. + L310_LATENCY_CTRL_RD(data[0] - 1) |
  32235. + L310_LATENCY_CTRL_WR(data[1] - 1) |
  32236. + L310_LATENCY_CTRL_SETUP(data[2] - 1),
  32237. + l2x0_base + L310_DATA_LATENCY_CTRL);
  32238. - if (!of_init) {
  32239. - outer_cache.inv_range = l2x0_inv_range;
  32240. - outer_cache.clean_range = l2x0_clean_range;
  32241. - outer_cache.flush_range = l2x0_flush_range;
  32242. - outer_cache.sync = l2x0_cache_sync;
  32243. - outer_cache.flush_all = l2x0_flush_all;
  32244. - outer_cache.inv_all = l2x0_inv_all;
  32245. - outer_cache.disable = l2x0_disable;
  32246. - }
  32247. -
  32248. - pr_info("%s cache controller enabled\n", type);
  32249. - pr_info("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d kB\n",
  32250. - ways, cache_id, aux, l2x0_size >> 10);
  32251. + of_property_read_u32_array(np, "arm,filter-ranges",
  32252. + filter, ARRAY_SIZE(filter));
  32253. + if (filter[1]) {
  32254. + writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
  32255. + l2x0_base + L310_ADDR_FILTER_END);
  32256. + writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L310_ADDR_FILTER_EN,
  32257. + l2x0_base + L310_ADDR_FILTER_START);
  32258. + }
  32259. }
  32260. -#ifdef CONFIG_OF
  32261. -static int l2_wt_override;
  32262. +static const struct l2c_init_data of_l2c310_data __initconst = {
  32263. + .type = "L2C-310",
  32264. + .way_size_0 = SZ_8K,
  32265. + .num_lock = 8,
  32266. + .of_parse = l2c310_of_parse,
  32267. + .enable = l2c310_enable,
  32268. + .fixup = l2c310_fixup,
  32269. + .save = l2c310_save,
  32270. + .outer_cache = {
  32271. + .inv_range = l2c210_inv_range,
  32272. + .clean_range = l2c210_clean_range,
  32273. + .flush_range = l2c210_flush_range,
  32274. + .flush_all = l2c210_flush_all,
  32275. + .disable = l2c310_disable,
  32276. + .sync = l2c210_sync,
  32277. + .resume = l2c310_resume,
  32278. + },
  32279. +};
  32280. /*
  32281. * Note that the end addresses passed to Linux primitives are
  32282. @@ -524,6 +1166,100 @@
  32283. }
  32284. }
  32285. +static void aurora_save(void __iomem *base)
  32286. +{
  32287. + l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL);
  32288. + l2x0_saved_regs.aux_ctrl = readl_relaxed(base + L2X0_AUX_CTRL);
  32289. +}
  32290. +
  32291. +static void aurora_resume(void)
  32292. +{
  32293. + void __iomem *base = l2x0_base;
  32294. +
  32295. + if (!(readl(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32296. + writel_relaxed(l2x0_saved_regs.aux_ctrl, base + L2X0_AUX_CTRL);
  32297. + writel_relaxed(l2x0_saved_regs.ctrl, base + L2X0_CTRL);
  32298. + }
  32299. +}
  32300. +
  32301. +/*
  32302. + * For Aurora cache in no outer mode, enable via the CP15 coprocessor
  32303. + * broadcasting of cache commands to L2.
  32304. + */
  32305. +static void __init aurora_enable_no_outer(void __iomem *base, u32 aux,
  32306. + unsigned num_lock)
  32307. +{
  32308. + u32 u;
  32309. +
  32310. + asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u));
  32311. + u |= AURORA_CTRL_FW; /* Set the FW bit */
  32312. + asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u));
  32313. +
  32314. + isb();
  32315. +
  32316. + l2c_enable(base, aux, num_lock);
  32317. +}
  32318. +
  32319. +static void __init aurora_fixup(void __iomem *base, u32 cache_id,
  32320. + struct outer_cache_fns *fns)
  32321. +{
  32322. + sync_reg_offset = AURORA_SYNC_REG;
  32323. +}
  32324. +
  32325. +static void __init aurora_of_parse(const struct device_node *np,
  32326. + u32 *aux_val, u32 *aux_mask)
  32327. +{
  32328. + u32 val = AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU;
  32329. + u32 mask = AURORA_ACR_REPLACEMENT_MASK;
  32330. +
  32331. + of_property_read_u32(np, "cache-id-part",
  32332. + &cache_id_part_number_from_dt);
  32333. +
  32334. + /* Determine and save the write policy */
  32335. + l2_wt_override = of_property_read_bool(np, "wt-override");
  32336. +
  32337. + if (l2_wt_override) {
  32338. + val |= AURORA_ACR_FORCE_WRITE_THRO_POLICY;
  32339. + mask |= AURORA_ACR_FORCE_WRITE_POLICY_MASK;
  32340. + }
  32341. +
  32342. + *aux_val &= ~mask;
  32343. + *aux_val |= val;
  32344. + *aux_mask &= ~mask;
  32345. +}
  32346. +
  32347. +static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
  32348. + .type = "Aurora",
  32349. + .way_size_0 = SZ_4K,
  32350. + .num_lock = 4,
  32351. + .of_parse = aurora_of_parse,
  32352. + .enable = l2c_enable,
  32353. + .fixup = aurora_fixup,
  32354. + .save = aurora_save,
  32355. + .outer_cache = {
  32356. + .inv_range = aurora_inv_range,
  32357. + .clean_range = aurora_clean_range,
  32358. + .flush_range = aurora_flush_range,
  32359. + .flush_all = l2x0_flush_all,
  32360. + .disable = l2x0_disable,
  32361. + .sync = l2x0_cache_sync,
  32362. + .resume = aurora_resume,
  32363. + },
  32364. +};
  32365. +
  32366. +static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
  32367. + .type = "Aurora",
  32368. + .way_size_0 = SZ_4K,
  32369. + .num_lock = 4,
  32370. + .of_parse = aurora_of_parse,
  32371. + .enable = aurora_enable_no_outer,
  32372. + .fixup = aurora_fixup,
  32373. + .save = aurora_save,
  32374. + .outer_cache = {
  32375. + .resume = aurora_resume,
  32376. + },
  32377. +};
  32378. +
  32379. /*
  32380. * For certain Broadcom SoCs, depending on the address range, different offsets
  32381. * need to be added to the address before passing it to L2 for
  32382. @@ -588,16 +1324,16 @@
  32383. /* normal case, no cross section between start and end */
  32384. if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
  32385. - l2x0_inv_range(new_start, new_end);
  32386. + l2c210_inv_range(new_start, new_end);
  32387. return;
  32388. }
  32389. /* They cross sections, so it can only be a cross from section
  32390. * 2 to section 3
  32391. */
  32392. - l2x0_inv_range(new_start,
  32393. + l2c210_inv_range(new_start,
  32394. bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
  32395. - l2x0_inv_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32396. + l2c210_inv_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32397. new_end);
  32398. }
  32399. @@ -610,26 +1346,21 @@
  32400. if (unlikely(end <= start))
  32401. return;
  32402. - if ((end - start) >= l2x0_size) {
  32403. - l2x0_clean_all();
  32404. - return;
  32405. - }
  32406. -
  32407. new_start = bcm_l2_phys_addr(start);
  32408. new_end = bcm_l2_phys_addr(end);
  32409. /* normal case, no cross section between start and end */
  32410. if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
  32411. - l2x0_clean_range(new_start, new_end);
  32412. + l2c210_clean_range(new_start, new_end);
  32413. return;
  32414. }
  32415. /* They cross sections, so it can only be a cross from section
  32416. * 2 to section 3
  32417. */
  32418. - l2x0_clean_range(new_start,
  32419. + l2c210_clean_range(new_start,
  32420. bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
  32421. - l2x0_clean_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32422. + l2c210_clean_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32423. new_end);
  32424. }
  32425. @@ -643,7 +1374,7 @@
  32426. return;
  32427. if ((end - start) >= l2x0_size) {
  32428. - l2x0_flush_all();
  32429. + outer_cache.flush_all();
  32430. return;
  32431. }
  32432. @@ -652,283 +1383,67 @@
  32433. /* normal case, no cross section between start and end */
  32434. if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
  32435. - l2x0_flush_range(new_start, new_end);
  32436. + l2c210_flush_range(new_start, new_end);
  32437. return;
  32438. }
  32439. /* They cross sections, so it can only be a cross from section
  32440. * 2 to section 3
  32441. */
  32442. - l2x0_flush_range(new_start,
  32443. + l2c210_flush_range(new_start,
  32444. bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
  32445. - l2x0_flush_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32446. + l2c210_flush_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32447. new_end);
  32448. }
  32449. -static void __init l2x0_of_setup(const struct device_node *np,
  32450. - u32 *aux_val, u32 *aux_mask)
  32451. -{
  32452. - u32 data[2] = { 0, 0 };
  32453. - u32 tag = 0;
  32454. - u32 dirty = 0;
  32455. - u32 val = 0, mask = 0;
  32456. -
  32457. - of_property_read_u32(np, "arm,tag-latency", &tag);
  32458. - if (tag) {
  32459. - mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
  32460. - val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
  32461. - }
  32462. -
  32463. - of_property_read_u32_array(np, "arm,data-latency",
  32464. - data, ARRAY_SIZE(data));
  32465. - if (data[0] && data[1]) {
  32466. - mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
  32467. - L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
  32468. - val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
  32469. - ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
  32470. - }
  32471. -
  32472. - of_property_read_u32(np, "arm,dirty-latency", &dirty);
  32473. - if (dirty) {
  32474. - mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
  32475. - val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
  32476. - }
  32477. -
  32478. - *aux_val &= ~mask;
  32479. - *aux_val |= val;
  32480. - *aux_mask &= ~mask;
  32481. -}
  32482. -
  32483. -static void __init pl310_of_setup(const struct device_node *np,
  32484. - u32 *aux_val, u32 *aux_mask)
  32485. -{
  32486. - u32 data[3] = { 0, 0, 0 };
  32487. - u32 tag[3] = { 0, 0, 0 };
  32488. - u32 filter[2] = { 0, 0 };
  32489. -
  32490. - of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
  32491. - if (tag[0] && tag[1] && tag[2])
  32492. - writel_relaxed(
  32493. - ((tag[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
  32494. - ((tag[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
  32495. - ((tag[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
  32496. - l2x0_base + L2X0_TAG_LATENCY_CTRL);
  32497. -
  32498. - of_property_read_u32_array(np, "arm,data-latency",
  32499. - data, ARRAY_SIZE(data));
  32500. - if (data[0] && data[1] && data[2])
  32501. - writel_relaxed(
  32502. - ((data[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
  32503. - ((data[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
  32504. - ((data[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
  32505. - l2x0_base + L2X0_DATA_LATENCY_CTRL);
  32506. -
  32507. - of_property_read_u32_array(np, "arm,filter-ranges",
  32508. - filter, ARRAY_SIZE(filter));
  32509. - if (filter[1]) {
  32510. - writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
  32511. - l2x0_base + L2X0_ADDR_FILTER_END);
  32512. - writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L2X0_ADDR_FILTER_EN,
  32513. - l2x0_base + L2X0_ADDR_FILTER_START);
  32514. - }
  32515. -}
  32516. -
  32517. -static void __init pl310_save(void)
  32518. -{
  32519. - u32 l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
  32520. - L2X0_CACHE_ID_RTL_MASK;
  32521. -
  32522. - l2x0_saved_regs.tag_latency = readl_relaxed(l2x0_base +
  32523. - L2X0_TAG_LATENCY_CTRL);
  32524. - l2x0_saved_regs.data_latency = readl_relaxed(l2x0_base +
  32525. - L2X0_DATA_LATENCY_CTRL);
  32526. - l2x0_saved_regs.filter_end = readl_relaxed(l2x0_base +
  32527. - L2X0_ADDR_FILTER_END);
  32528. - l2x0_saved_regs.filter_start = readl_relaxed(l2x0_base +
  32529. - L2X0_ADDR_FILTER_START);
  32530. -
  32531. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) {
  32532. - /*
  32533. - * From r2p0, there is Prefetch offset/control register
  32534. - */
  32535. - l2x0_saved_regs.prefetch_ctrl = readl_relaxed(l2x0_base +
  32536. - L2X0_PREFETCH_CTRL);
  32537. - /*
  32538. - * From r3p0, there is Power control register
  32539. - */
  32540. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0)
  32541. - l2x0_saved_regs.pwr_ctrl = readl_relaxed(l2x0_base +
  32542. - L2X0_POWER_CTRL);
  32543. - }
  32544. -}
  32545. +/* Broadcom L2C-310 start from ARMs R3P2 or later, and require no fixups */
  32546. +static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
  32547. + .type = "BCM-L2C-310",
  32548. + .way_size_0 = SZ_8K,
  32549. + .num_lock = 8,
  32550. + .of_parse = l2c310_of_parse,
  32551. + .enable = l2c310_enable,
  32552. + .save = l2c310_save,
  32553. + .outer_cache = {
  32554. + .inv_range = bcm_inv_range,
  32555. + .clean_range = bcm_clean_range,
  32556. + .flush_range = bcm_flush_range,
  32557. + .flush_all = l2c210_flush_all,
  32558. + .disable = l2c310_disable,
  32559. + .sync = l2c210_sync,
  32560. + .resume = l2c310_resume,
  32561. + },
  32562. +};
  32563. -static void aurora_save(void)
  32564. +static void __init tauros3_save(void __iomem *base)
  32565. {
  32566. - l2x0_saved_regs.ctrl = readl_relaxed(l2x0_base + L2X0_CTRL);
  32567. - l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32568. -}
  32569. + l2c_save(base);
  32570. -static void __init tauros3_save(void)
  32571. -{
  32572. l2x0_saved_regs.aux2_ctrl =
  32573. - readl_relaxed(l2x0_base + TAUROS3_AUX2_CTRL);
  32574. + readl_relaxed(base + TAUROS3_AUX2_CTRL);
  32575. l2x0_saved_regs.prefetch_ctrl =
  32576. - readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
  32577. -}
  32578. -
  32579. -static void l2x0_resume(void)
  32580. -{
  32581. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32582. - /* restore aux ctrl and enable l2 */
  32583. - l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID));
  32584. -
  32585. - writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base +
  32586. - L2X0_AUX_CTRL);
  32587. -
  32588. - l2x0_inv_all();
  32589. -
  32590. - writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
  32591. - }
  32592. -}
  32593. -
  32594. -static void pl310_resume(void)
  32595. -{
  32596. - u32 l2x0_revision;
  32597. -
  32598. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32599. - /* restore pl310 setup */
  32600. - writel_relaxed(l2x0_saved_regs.tag_latency,
  32601. - l2x0_base + L2X0_TAG_LATENCY_CTRL);
  32602. - writel_relaxed(l2x0_saved_regs.data_latency,
  32603. - l2x0_base + L2X0_DATA_LATENCY_CTRL);
  32604. - writel_relaxed(l2x0_saved_regs.filter_end,
  32605. - l2x0_base + L2X0_ADDR_FILTER_END);
  32606. - writel_relaxed(l2x0_saved_regs.filter_start,
  32607. - l2x0_base + L2X0_ADDR_FILTER_START);
  32608. -
  32609. - l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
  32610. - L2X0_CACHE_ID_RTL_MASK;
  32611. -
  32612. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) {
  32613. - writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
  32614. - l2x0_base + L2X0_PREFETCH_CTRL);
  32615. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0)
  32616. - writel_relaxed(l2x0_saved_regs.pwr_ctrl,
  32617. - l2x0_base + L2X0_POWER_CTRL);
  32618. - }
  32619. - }
  32620. -
  32621. - l2x0_resume();
  32622. -}
  32623. -
  32624. -static void aurora_resume(void)
  32625. -{
  32626. - if (!(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32627. - writel_relaxed(l2x0_saved_regs.aux_ctrl,
  32628. - l2x0_base + L2X0_AUX_CTRL);
  32629. - writel_relaxed(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL);
  32630. - }
  32631. + readl_relaxed(base + L310_PREFETCH_CTRL);
  32632. }
  32633. static void tauros3_resume(void)
  32634. {
  32635. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32636. + void __iomem *base = l2x0_base;
  32637. +
  32638. + if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32639. writel_relaxed(l2x0_saved_regs.aux2_ctrl,
  32640. - l2x0_base + TAUROS3_AUX2_CTRL);
  32641. + base + TAUROS3_AUX2_CTRL);
  32642. writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
  32643. - l2x0_base + L2X0_PREFETCH_CTRL);
  32644. - }
  32645. -
  32646. - l2x0_resume();
  32647. -}
  32648. -
  32649. -static void __init aurora_broadcast_l2_commands(void)
  32650. -{
  32651. - __u32 u;
  32652. - /* Enable Broadcasting of cache commands to L2*/
  32653. - __asm__ __volatile__("mrc p15, 1, %0, c15, c2, 0" : "=r"(u));
  32654. - u |= AURORA_CTRL_FW; /* Set the FW bit */
  32655. - __asm__ __volatile__("mcr p15, 1, %0, c15, c2, 0\n" : : "r"(u));
  32656. - isb();
  32657. -}
  32658. -
  32659. -static void __init aurora_of_setup(const struct device_node *np,
  32660. - u32 *aux_val, u32 *aux_mask)
  32661. -{
  32662. - u32 val = AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU;
  32663. - u32 mask = AURORA_ACR_REPLACEMENT_MASK;
  32664. + base + L310_PREFETCH_CTRL);
  32665. - of_property_read_u32(np, "cache-id-part",
  32666. - &cache_id_part_number_from_dt);
  32667. -
  32668. - /* Determine and save the write policy */
  32669. - l2_wt_override = of_property_read_bool(np, "wt-override");
  32670. -
  32671. - if (l2_wt_override) {
  32672. - val |= AURORA_ACR_FORCE_WRITE_THRO_POLICY;
  32673. - mask |= AURORA_ACR_FORCE_WRITE_POLICY_MASK;
  32674. + l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
  32675. }
  32676. -
  32677. - *aux_val &= ~mask;
  32678. - *aux_val |= val;
  32679. - *aux_mask &= ~mask;
  32680. }
  32681. -static const struct l2x0_of_data pl310_data = {
  32682. - .setup = pl310_of_setup,
  32683. - .save = pl310_save,
  32684. - .outer_cache = {
  32685. - .resume = pl310_resume,
  32686. - .inv_range = l2x0_inv_range,
  32687. - .clean_range = l2x0_clean_range,
  32688. - .flush_range = l2x0_flush_range,
  32689. - .sync = l2x0_cache_sync,
  32690. - .flush_all = l2x0_flush_all,
  32691. - .inv_all = l2x0_inv_all,
  32692. - .disable = l2x0_disable,
  32693. - },
  32694. -};
  32695. -
  32696. -static const struct l2x0_of_data l2x0_data = {
  32697. - .setup = l2x0_of_setup,
  32698. - .save = NULL,
  32699. - .outer_cache = {
  32700. - .resume = l2x0_resume,
  32701. - .inv_range = l2x0_inv_range,
  32702. - .clean_range = l2x0_clean_range,
  32703. - .flush_range = l2x0_flush_range,
  32704. - .sync = l2x0_cache_sync,
  32705. - .flush_all = l2x0_flush_all,
  32706. - .inv_all = l2x0_inv_all,
  32707. - .disable = l2x0_disable,
  32708. - },
  32709. -};
  32710. -
  32711. -static const struct l2x0_of_data aurora_with_outer_data = {
  32712. - .setup = aurora_of_setup,
  32713. - .save = aurora_save,
  32714. - .outer_cache = {
  32715. - .resume = aurora_resume,
  32716. - .inv_range = aurora_inv_range,
  32717. - .clean_range = aurora_clean_range,
  32718. - .flush_range = aurora_flush_range,
  32719. - .sync = l2x0_cache_sync,
  32720. - .flush_all = l2x0_flush_all,
  32721. - .inv_all = l2x0_inv_all,
  32722. - .disable = l2x0_disable,
  32723. - },
  32724. -};
  32725. -
  32726. -static const struct l2x0_of_data aurora_no_outer_data = {
  32727. - .setup = aurora_of_setup,
  32728. - .save = aurora_save,
  32729. - .outer_cache = {
  32730. - .resume = aurora_resume,
  32731. - },
  32732. -};
  32733. -
  32734. -static const struct l2x0_of_data tauros3_data = {
  32735. - .setup = NULL,
  32736. +static const struct l2c_init_data of_tauros3_data __initconst = {
  32737. + .type = "Tauros3",
  32738. + .way_size_0 = SZ_8K,
  32739. + .num_lock = 8,
  32740. + .enable = l2c_enable,
  32741. .save = tauros3_save,
  32742. /* Tauros3 broadcasts L1 cache operations to L2 */
  32743. .outer_cache = {
  32744. @@ -936,43 +1451,26 @@
  32745. },
  32746. };
  32747. -static const struct l2x0_of_data bcm_l2x0_data = {
  32748. - .setup = pl310_of_setup,
  32749. - .save = pl310_save,
  32750. - .outer_cache = {
  32751. - .resume = pl310_resume,
  32752. - .inv_range = bcm_inv_range,
  32753. - .clean_range = bcm_clean_range,
  32754. - .flush_range = bcm_flush_range,
  32755. - .sync = l2x0_cache_sync,
  32756. - .flush_all = l2x0_flush_all,
  32757. - .inv_all = l2x0_inv_all,
  32758. - .disable = l2x0_disable,
  32759. - },
  32760. -};
  32761. -
  32762. +#define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns }
  32763. static const struct of_device_id l2x0_ids[] __initconst = {
  32764. - { .compatible = "arm,l210-cache", .data = (void *)&l2x0_data },
  32765. - { .compatible = "arm,l220-cache", .data = (void *)&l2x0_data },
  32766. - { .compatible = "arm,pl310-cache", .data = (void *)&pl310_data },
  32767. - { .compatible = "bcm,bcm11351-a2-pl310-cache", /* deprecated name */
  32768. - .data = (void *)&bcm_l2x0_data},
  32769. - { .compatible = "brcm,bcm11351-a2-pl310-cache",
  32770. - .data = (void *)&bcm_l2x0_data},
  32771. - { .compatible = "marvell,aurora-outer-cache",
  32772. - .data = (void *)&aurora_with_outer_data},
  32773. - { .compatible = "marvell,aurora-system-cache",
  32774. - .data = (void *)&aurora_no_outer_data},
  32775. - { .compatible = "marvell,tauros3-cache",
  32776. - .data = (void *)&tauros3_data },
  32777. + L2C_ID("arm,l210-cache", of_l2c210_data),
  32778. + L2C_ID("arm,l220-cache", of_l2c220_data),
  32779. + L2C_ID("arm,pl310-cache", of_l2c310_data),
  32780. + L2C_ID("brcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
  32781. + L2C_ID("marvell,aurora-outer-cache", of_aurora_with_outer_data),
  32782. + L2C_ID("marvell,aurora-system-cache", of_aurora_no_outer_data),
  32783. + L2C_ID("marvell,tauros3-cache", of_tauros3_data),
  32784. + /* Deprecated IDs */
  32785. + L2C_ID("bcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
  32786. {}
  32787. };
  32788. int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
  32789. {
  32790. + const struct l2c_init_data *data;
  32791. struct device_node *np;
  32792. - const struct l2x0_of_data *data;
  32793. struct resource res;
  32794. + u32 cache_id, old_aux;
  32795. np = of_find_matching_node(NULL, l2x0_ids);
  32796. if (!np)
  32797. @@ -989,23 +1487,29 @@
  32798. data = of_match_node(l2x0_ids, np)->data;
  32799. - /* L2 configuration can only be changed if the cache is disabled */
  32800. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32801. - if (data->setup)
  32802. - data->setup(np, &aux_val, &aux_mask);
  32803. -
  32804. - /* For aurora cache in no outer mode select the
  32805. - * correct mode using the coprocessor*/
  32806. - if (data == &aurora_no_outer_data)
  32807. - aurora_broadcast_l2_commands();
  32808. + old_aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32809. + if (old_aux != ((old_aux & aux_mask) | aux_val)) {
  32810. + pr_warn("L2C: platform modifies aux control register: 0x%08x -> 0x%08x\n",
  32811. + old_aux, (old_aux & aux_mask) | aux_val);
  32812. + } else if (aux_mask != ~0U && aux_val != 0) {
  32813. + pr_alert("L2C: platform provided aux values match the hardware, so have no effect. Please remove them.\n");
  32814. }
  32815. - if (data->save)
  32816. - data->save();
  32817. + /* All L2 caches are unified, so this property should be specified */
  32818. + if (!of_property_read_bool(np, "cache-unified"))
  32819. + pr_err("L2C: device tree omits to specify unified cache\n");
  32820. +
  32821. + /* L2 configuration can only be changed if the cache is disabled */
  32822. + if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
  32823. + if (data->of_parse)
  32824. + data->of_parse(np, &aux_val, &aux_mask);
  32825. +
  32826. + if (cache_id_part_number_from_dt)
  32827. + cache_id = cache_id_part_number_from_dt;
  32828. + else
  32829. + cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
  32830. - of_init = true;
  32831. - memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache));
  32832. - l2x0_init(l2x0_base, aux_val, aux_mask);
  32833. + __l2c_init(data, aux_val, aux_mask, cache_id);
  32834. return 0;
  32835. }
  32836. diff -Nur linux-3.14.15/arch/arm/mm/fault.c linux-linaro-stable-mx6/arch/arm/mm/fault.c
  32837. --- linux-3.14.15/arch/arm/mm/fault.c 2014-07-31 23:51:43.000000000 +0200
  32838. +++ linux-linaro-stable-mx6/arch/arm/mm/fault.c 2014-08-20 19:31:40.428844537 +0200
  32839. @@ -449,8 +449,16 @@
  32840. if (pud_none(*pud_k))
  32841. goto bad_area;
  32842. - if (!pud_present(*pud))
  32843. + if (!pud_present(*pud)) {
  32844. set_pud(pud, *pud_k);
  32845. + /*
  32846. + * There is a small window during free_pgtables() where the
  32847. + * user *pud entry is 0 but the TLB has not been invalidated
  32848. + * and we get a level 2 (pmd) translation fault caused by the
  32849. + * intermediate TLB caching of the old level 1 (pud) entry.
  32850. + */
  32851. + flush_tlb_kernel_page(addr);
  32852. + }
  32853. pmd = pmd_offset(pud, addr);
  32854. pmd_k = pmd_offset(pud_k, addr);
  32855. @@ -473,8 +481,9 @@
  32856. #endif
  32857. if (pmd_none(pmd_k[index]))
  32858. goto bad_area;
  32859. + if (!pmd_present(pmd[index]))
  32860. + copy_pmd(pmd, pmd_k);
  32861. - copy_pmd(pmd, pmd_k);
  32862. return 0;
  32863. bad_area:
  32864. diff -Nur linux-3.14.15/arch/arm/mm/Kconfig linux-linaro-stable-mx6/arch/arm/mm/Kconfig
  32865. --- linux-3.14.15/arch/arm/mm/Kconfig 2014-07-31 23:51:43.000000000 +0200
  32866. +++ linux-linaro-stable-mx6/arch/arm/mm/Kconfig 2014-08-20 19:31:40.420844504 +0200
  32867. @@ -897,6 +897,57 @@
  32868. This option enables optimisations for the PL310 cache
  32869. controller.
  32870. +config PL310_ERRATA_588369
  32871. + bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
  32872. + depends on CACHE_L2X0
  32873. + help
  32874. + The PL310 L2 cache controller implements three types of Clean &
  32875. + Invalidate maintenance operations: by Physical Address
  32876. + (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
  32877. + They are architecturally defined to behave as the execution of a
  32878. + clean operation followed immediately by an invalidate operation,
  32879. + both performing to the same memory location. This functionality
  32880. + is not correctly implemented in PL310 as clean lines are not
  32881. + invalidated as a result of these operations.
  32882. +
  32883. +config PL310_ERRATA_727915
  32884. + bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
  32885. + depends on CACHE_L2X0
  32886. + help
  32887. + PL310 implements the Clean & Invalidate by Way L2 cache maintenance
  32888. + operation (offset 0x7FC). This operation runs in background so that
  32889. + PL310 can handle normal accesses while it is in progress. Under very
  32890. + rare circumstances, due to this erratum, write data can be lost when
  32891. + PL310 treats a cacheable write transaction during a Clean &
  32892. + Invalidate by Way operation.
  32893. +
  32894. +config PL310_ERRATA_753970
  32895. + bool "PL310 errata: cache sync operation may be faulty"
  32896. + depends on CACHE_PL310
  32897. + help
  32898. + This option enables the workaround for the 753970 PL310 (r3p0) erratum.
  32899. +
  32900. + Under some condition the effect of cache sync operation on
  32901. + the store buffer still remains when the operation completes.
  32902. + This means that the store buffer is always asked to drain and
  32903. + this prevents it from merging any further writes. The workaround
  32904. + is to replace the normal offset of cache sync operation (0x730)
  32905. + by another offset targeting an unmapped PL310 register 0x740.
  32906. + This has the same effect as the cache sync operation: store buffer
  32907. + drain and waiting for all buffers empty.
  32908. +
  32909. +config PL310_ERRATA_769419
  32910. + bool "PL310 errata: no automatic Store Buffer drain"
  32911. + depends on CACHE_L2X0
  32912. + help
  32913. + On revisions of the PL310 prior to r3p2, the Store Buffer does
  32914. + not automatically drain. This can cause normal, non-cacheable
  32915. + writes to be retained when the memory system is idle, leading
  32916. + to suboptimal I/O performance for drivers using coherent DMA.
  32917. + This option adds a write barrier to the cpu_idle loop so that,
  32918. + on systems with an outer cache, the store buffer is drained
  32919. + explicitly.
  32920. +
  32921. config CACHE_TAUROS2
  32922. bool "Enable the Tauros2 L2 cache controller"
  32923. depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
  32924. diff -Nur linux-3.14.15/arch/arm/mm/l2c-common.c linux-linaro-stable-mx6/arch/arm/mm/l2c-common.c
  32925. --- linux-3.14.15/arch/arm/mm/l2c-common.c 1970-01-01 01:00:00.000000000 +0100
  32926. +++ linux-linaro-stable-mx6/arch/arm/mm/l2c-common.c 2014-08-20 19:31:40.436844573 +0200
  32927. @@ -0,0 +1,20 @@
  32928. +/*
  32929. + * Copyright (C) 2010 ARM Ltd.
  32930. + * Written by Catalin Marinas <catalin.marinas@arm.com>
  32931. + *
  32932. + * This program is free software; you can redistribute it and/or modify
  32933. + * it under the terms of the GNU General Public License version 2 as
  32934. + * published by the Free Software Foundation.
  32935. + */
  32936. +#include <linux/bug.h>
  32937. +#include <linux/smp.h>
  32938. +#include <asm/outercache.h>
  32939. +
  32940. +void outer_disable(void)
  32941. +{
  32942. + WARN_ON(!irqs_disabled());
  32943. + WARN_ON(num_online_cpus() > 1);
  32944. +
  32945. + if (outer_cache.disable)
  32946. + outer_cache.disable();
  32947. +}
  32948. diff -Nur linux-3.14.15/arch/arm/mm/l2c-l2x0-resume.S linux-linaro-stable-mx6/arch/arm/mm/l2c-l2x0-resume.S
  32949. --- linux-3.14.15/arch/arm/mm/l2c-l2x0-resume.S 1970-01-01 01:00:00.000000000 +0100
  32950. +++ linux-linaro-stable-mx6/arch/arm/mm/l2c-l2x0-resume.S 2014-08-20 19:31:40.436844573 +0200
  32951. @@ -0,0 +1,58 @@
  32952. +/*
  32953. + * L2C-310 early resume code. This can be used by platforms to restore
  32954. + * the settings of their L2 cache controller before restoring the
  32955. + * processor state.
  32956. + *
  32957. + * This code can only be used to if you are running in the secure world.
  32958. + */
  32959. +#include <linux/linkage.h>
  32960. +#include <asm/hardware/cache-l2x0.h>
  32961. +
  32962. + .text
  32963. +
  32964. +ENTRY(l2c310_early_resume)
  32965. + adr r0, 1f
  32966. + ldr r2, [r0]
  32967. + add r0, r2, r0
  32968. +
  32969. + ldmia r0, {r1, r2, r3, r4, r5, r6, r7, r8}
  32970. + @ r1 = phys address of L2C-310 controller
  32971. + @ r2 = aux_ctrl
  32972. + @ r3 = tag_latency
  32973. + @ r4 = data_latency
  32974. + @ r5 = filter_start
  32975. + @ r6 = filter_end
  32976. + @ r7 = prefetch_ctrl
  32977. + @ r8 = pwr_ctrl
  32978. +
  32979. + @ Check that the address has been initialised
  32980. + teq r1, #0
  32981. + moveq pc, lr
  32982. +
  32983. + @ The prefetch and power control registers are revision dependent
  32984. + @ and can be written whether or not the L2 cache is enabled
  32985. + ldr r0, [r1, #L2X0_CACHE_ID]
  32986. + and r0, r0, #L2X0_CACHE_ID_RTL_MASK
  32987. + cmp r0, #L310_CACHE_ID_RTL_R2P0
  32988. + strcs r7, [r1, #L310_PREFETCH_CTRL]
  32989. + cmp r0, #L310_CACHE_ID_RTL_R3P0
  32990. + strcs r8, [r1, #L310_POWER_CTRL]
  32991. +
  32992. + @ Don't setup the L2 cache if it is already enabled
  32993. + ldr r0, [r1, #L2X0_CTRL]
  32994. + tst r0, #L2X0_CTRL_EN
  32995. + movne pc, lr
  32996. +
  32997. + str r3, [r1, #L310_TAG_LATENCY_CTRL]
  32998. + str r4, [r1, #L310_DATA_LATENCY_CTRL]
  32999. + str r6, [r1, #L310_ADDR_FILTER_END]
  33000. + str r5, [r1, #L310_ADDR_FILTER_START]
  33001. +
  33002. + str r2, [r1, #L2X0_AUX_CTRL]
  33003. + mov r9, #L2X0_CTRL_EN
  33004. + str r9, [r1, #L2X0_CTRL]
  33005. + mov pc, lr
  33006. +ENDPROC(l2c310_early_resume)
  33007. +
  33008. + .align
  33009. +1: .long l2x0_saved_regs - .
  33010. diff -Nur linux-3.14.15/arch/arm/mm/Makefile linux-linaro-stable-mx6/arch/arm/mm/Makefile
  33011. --- linux-3.14.15/arch/arm/mm/Makefile 2014-07-31 23:51:43.000000000 +0200
  33012. +++ linux-linaro-stable-mx6/arch/arm/mm/Makefile 2014-08-20 19:31:40.420844504 +0200
  33013. @@ -95,7 +95,8 @@
  33014. AFLAGS_proc-v6.o :=-Wa,-march=armv6
  33015. AFLAGS_proc-v7.o :=-Wa,-march=armv7-a
  33016. +obj-$(CONFIG_OUTER_CACHE) += l2c-common.o
  33017. obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o
  33018. -obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
  33019. +obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o l2c-l2x0-resume.o
  33020. obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o
  33021. obj-$(CONFIG_CACHE_TAUROS2) += cache-tauros2.o
  33022. diff -Nur linux-3.14.15/arch/arm/mm/proc-v7.S linux-linaro-stable-mx6/arch/arm/mm/proc-v7.S
  33023. --- linux-3.14.15/arch/arm/mm/proc-v7.S 2014-07-31 23:51:43.000000000 +0200
  33024. +++ linux-linaro-stable-mx6/arch/arm/mm/proc-v7.S 2014-08-20 19:31:40.460844676 +0200
  33025. @@ -336,6 +336,17 @@
  33026. mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
  33027. 1:
  33028. #endif
  33029. +#ifdef CONFIG_ARM_ERRATA_794072
  33030. + mrc p15, 0, r10, c15, c0, 1 @ read diagnostic register
  33031. + orr r10, r10, #1 << 4 @ set bit #4
  33032. + mcr p15, 0, r10, c15, c0, 1 @ write diagnostic register
  33033. +#endif
  33034. +#ifdef CONFIG_ARM_ERRATA_761320
  33035. + cmp r6, #0x40 @ present prior to r4p0
  33036. + mrclt p15, 0, r10, c15, c0, 1 @ read diagnostic register
  33037. + orrlt r10, r10, #1 << 21 @ set bit #21
  33038. + mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
  33039. +#endif
  33040. /* Cortex-A15 Errata */
  33041. 3: ldr r10, =0x00000c0f @ Cortex-A15 primary part number
  33042. diff -Nur linux-3.14.15/arch/arm64/boot/dts/apm-mustang.dts linux-linaro-stable-mx6/arch/arm64/boot/dts/apm-mustang.dts
  33043. --- linux-3.14.15/arch/arm64/boot/dts/apm-mustang.dts 2014-07-31 23:51:43.000000000 +0200
  33044. +++ linux-linaro-stable-mx6/arch/arm64/boot/dts/apm-mustang.dts 2014-08-20 19:31:40.540845019 +0200
  33045. @@ -24,3 +24,7 @@
  33046. reg = < 0x1 0x00000000 0x0 0x80000000 >; /* Updated by bootloader */
  33047. };
  33048. };
  33049. +
  33050. +&serial0 {
  33051. + status = "ok";
  33052. +};
  33053. diff -Nur linux-3.14.15/arch/arm64/boot/dts/apm-storm.dtsi linux-linaro-stable-mx6/arch/arm64/boot/dts/apm-storm.dtsi
  33054. --- linux-3.14.15/arch/arm64/boot/dts/apm-storm.dtsi 2014-07-31 23:51:43.000000000 +0200
  33055. +++ linux-linaro-stable-mx6/arch/arm64/boot/dts/apm-storm.dtsi 2014-08-20 19:31:40.540845019 +0200
  33056. @@ -176,16 +176,226 @@
  33057. reg-names = "csr-reg";
  33058. clock-output-names = "eth8clk";
  33059. };
  33060. +
  33061. + sataphy1clk: sataphy1clk@1f21c000 {
  33062. + compatible = "apm,xgene-device-clock";
  33063. + #clock-cells = <1>;
  33064. + clocks = <&socplldiv2 0>;
  33065. + reg = <0x0 0x1f21c000 0x0 0x1000>;
  33066. + reg-names = "csr-reg";
  33067. + clock-output-names = "sataphy1clk";
  33068. + status = "disabled";
  33069. + csr-offset = <0x4>;
  33070. + csr-mask = <0x00>;
  33071. + enable-offset = <0x0>;
  33072. + enable-mask = <0x06>;
  33073. + };
  33074. +
  33075. + sataphy2clk: sataphy1clk@1f22c000 {
  33076. + compatible = "apm,xgene-device-clock";
  33077. + #clock-cells = <1>;
  33078. + clocks = <&socplldiv2 0>;
  33079. + reg = <0x0 0x1f22c000 0x0 0x1000>;
  33080. + reg-names = "csr-reg";
  33081. + clock-output-names = "sataphy2clk";
  33082. + status = "ok";
  33083. + csr-offset = <0x4>;
  33084. + csr-mask = <0x3a>;
  33085. + enable-offset = <0x0>;
  33086. + enable-mask = <0x06>;
  33087. + };
  33088. +
  33089. + sataphy3clk: sataphy1clk@1f23c000 {
  33090. + compatible = "apm,xgene-device-clock";
  33091. + #clock-cells = <1>;
  33092. + clocks = <&socplldiv2 0>;
  33093. + reg = <0x0 0x1f23c000 0x0 0x1000>;
  33094. + reg-names = "csr-reg";
  33095. + clock-output-names = "sataphy3clk";
  33096. + status = "ok";
  33097. + csr-offset = <0x4>;
  33098. + csr-mask = <0x3a>;
  33099. + enable-offset = <0x0>;
  33100. + enable-mask = <0x06>;
  33101. + };
  33102. +
  33103. + sata01clk: sata01clk@1f21c000 {
  33104. + compatible = "apm,xgene-device-clock";
  33105. + #clock-cells = <1>;
  33106. + clocks = <&socplldiv2 0>;
  33107. + reg = <0x0 0x1f21c000 0x0 0x1000>;
  33108. + reg-names = "csr-reg";
  33109. + clock-output-names = "sata01clk";
  33110. + csr-offset = <0x4>;
  33111. + csr-mask = <0x05>;
  33112. + enable-offset = <0x0>;
  33113. + enable-mask = <0x39>;
  33114. + };
  33115. +
  33116. + sata23clk: sata23clk@1f22c000 {
  33117. + compatible = "apm,xgene-device-clock";
  33118. + #clock-cells = <1>;
  33119. + clocks = <&socplldiv2 0>;
  33120. + reg = <0x0 0x1f22c000 0x0 0x1000>;
  33121. + reg-names = "csr-reg";
  33122. + clock-output-names = "sata23clk";
  33123. + csr-offset = <0x4>;
  33124. + csr-mask = <0x05>;
  33125. + enable-offset = <0x0>;
  33126. + enable-mask = <0x39>;
  33127. + };
  33128. +
  33129. + sata45clk: sata45clk@1f23c000 {
  33130. + compatible = "apm,xgene-device-clock";
  33131. + #clock-cells = <1>;
  33132. + clocks = <&socplldiv2 0>;
  33133. + reg = <0x0 0x1f23c000 0x0 0x1000>;
  33134. + reg-names = "csr-reg";
  33135. + clock-output-names = "sata45clk";
  33136. + csr-offset = <0x4>;
  33137. + csr-mask = <0x05>;
  33138. + enable-offset = <0x0>;
  33139. + enable-mask = <0x39>;
  33140. + };
  33141. +
  33142. + rtcclk: rtcclk@17000000 {
  33143. + compatible = "apm,xgene-device-clock";
  33144. + #clock-cells = <1>;
  33145. + clocks = <&socplldiv2 0>;
  33146. + reg = <0x0 0x17000000 0x0 0x2000>;
  33147. + reg-names = "csr-reg";
  33148. + csr-offset = <0xc>;
  33149. + csr-mask = <0x2>;
  33150. + enable-offset = <0x10>;
  33151. + enable-mask = <0x2>;
  33152. + clock-output-names = "rtcclk";
  33153. + };
  33154. };
  33155. serial0: serial@1c020000 {
  33156. + status = "disabled";
  33157. device_type = "serial";
  33158. - compatible = "ns16550";
  33159. + compatible = "ns16550a";
  33160. reg = <0 0x1c020000 0x0 0x1000>;
  33161. reg-shift = <2>;
  33162. clock-frequency = <10000000>; /* Updated by bootloader */
  33163. interrupt-parent = <&gic>;
  33164. interrupts = <0x0 0x4c 0x4>;
  33165. };
  33166. +
  33167. + serial1: serial@1c021000 {
  33168. + status = "disabled";
  33169. + device_type = "serial";
  33170. + compatible = "ns16550a";
  33171. + reg = <0 0x1c021000 0x0 0x1000>;
  33172. + reg-shift = <2>;
  33173. + clock-frequency = <10000000>; /* Updated by bootloader */
  33174. + interrupt-parent = <&gic>;
  33175. + interrupts = <0x0 0x4d 0x4>;
  33176. + };
  33177. +
  33178. + serial2: serial@1c022000 {
  33179. + status = "disabled";
  33180. + device_type = "serial";
  33181. + compatible = "ns16550a";
  33182. + reg = <0 0x1c022000 0x0 0x1000>;
  33183. + reg-shift = <2>;
  33184. + clock-frequency = <10000000>; /* Updated by bootloader */
  33185. + interrupt-parent = <&gic>;
  33186. + interrupts = <0x0 0x4e 0x4>;
  33187. + };
  33188. +
  33189. + serial3: serial@1c023000 {
  33190. + status = "disabled";
  33191. + device_type = "serial";
  33192. + compatible = "ns16550a";
  33193. + reg = <0 0x1c023000 0x0 0x1000>;
  33194. + reg-shift = <2>;
  33195. + clock-frequency = <10000000>; /* Updated by bootloader */
  33196. + interrupt-parent = <&gic>;
  33197. + interrupts = <0x0 0x4f 0x4>;
  33198. + };
  33199. +
  33200. + phy1: phy@1f21a000 {
  33201. + compatible = "apm,xgene-phy";
  33202. + reg = <0x0 0x1f21a000 0x0 0x100>;
  33203. + #phy-cells = <1>;
  33204. + clocks = <&sataphy1clk 0>;
  33205. + status = "disabled";
  33206. + apm,tx-boost-gain = <30 30 30 30 30 30>;
  33207. + apm,tx-eye-tuning = <2 10 10 2 10 10>;
  33208. + };
  33209. +
  33210. + phy2: phy@1f22a000 {
  33211. + compatible = "apm,xgene-phy";
  33212. + reg = <0x0 0x1f22a000 0x0 0x100>;
  33213. + #phy-cells = <1>;
  33214. + clocks = <&sataphy2clk 0>;
  33215. + status = "ok";
  33216. + apm,tx-boost-gain = <30 30 30 30 30 30>;
  33217. + apm,tx-eye-tuning = <1 10 10 2 10 10>;
  33218. + };
  33219. +
  33220. + phy3: phy@1f23a000 {
  33221. + compatible = "apm,xgene-phy";
  33222. + reg = <0x0 0x1f23a000 0x0 0x100>;
  33223. + #phy-cells = <1>;
  33224. + clocks = <&sataphy3clk 0>;
  33225. + status = "ok";
  33226. + apm,tx-boost-gain = <31 31 31 31 31 31>;
  33227. + apm,tx-eye-tuning = <2 10 10 2 10 10>;
  33228. + };
  33229. +
  33230. + sata1: sata@1a000000 {
  33231. + compatible = "apm,xgene-ahci";
  33232. + reg = <0x0 0x1a000000 0x0 0x1000>,
  33233. + <0x0 0x1f210000 0x0 0x1000>,
  33234. + <0x0 0x1f21d000 0x0 0x1000>,
  33235. + <0x0 0x1f21e000 0x0 0x1000>,
  33236. + <0x0 0x1f217000 0x0 0x1000>;
  33237. + interrupts = <0x0 0x86 0x4>;
  33238. + dma-coherent;
  33239. + status = "disabled";
  33240. + clocks = <&sata01clk 0>;
  33241. + phys = <&phy1 0>;
  33242. + phy-names = "sata-phy";
  33243. + };
  33244. +
  33245. + sata2: sata@1a400000 {
  33246. + compatible = "apm,xgene-ahci";
  33247. + reg = <0x0 0x1a400000 0x0 0x1000>,
  33248. + <0x0 0x1f220000 0x0 0x1000>,
  33249. + <0x0 0x1f22d000 0x0 0x1000>,
  33250. + <0x0 0x1f22e000 0x0 0x1000>,
  33251. + <0x0 0x1f227000 0x0 0x1000>;
  33252. + interrupts = <0x0 0x87 0x4>;
  33253. + dma-coherent;
  33254. + status = "ok";
  33255. + clocks = <&sata23clk 0>;
  33256. + phys = <&phy2 0>;
  33257. + phy-names = "sata-phy";
  33258. + };
  33259. +
  33260. + sata3: sata@1a800000 {
  33261. + compatible = "apm,xgene-ahci";
  33262. + reg = <0x0 0x1a800000 0x0 0x1000>,
  33263. + <0x0 0x1f230000 0x0 0x1000>,
  33264. + <0x0 0x1f23d000 0x0 0x1000>,
  33265. + <0x0 0x1f23e000 0x0 0x1000>;
  33266. + interrupts = <0x0 0x88 0x4>;
  33267. + dma-coherent;
  33268. + status = "ok";
  33269. + clocks = <&sata45clk 0>;
  33270. + phys = <&phy3 0>;
  33271. + phy-names = "sata-phy";
  33272. + };
  33273. +
  33274. + rtc: rtc@10510000 {
  33275. + compatible = "apm,xgene-rtc";
  33276. + reg = <0x0 0x10510000 0x0 0x400>;
  33277. + interrupts = <0x0 0x46 0x4>;
  33278. + #clock-cells = <1>;
  33279. + clocks = <&rtcclk 0>;
  33280. + };
  33281. };
  33282. };
  33283. diff -Nur linux-3.14.15/arch/arm64/boot/dts/clcd-panels.dtsi linux-linaro-stable-mx6/arch/arm64/boot/dts/clcd-panels.dtsi
  33284. --- linux-3.14.15/arch/arm64/boot/dts/clcd-panels.dtsi 1970-01-01 01:00:00.000000000 +0100
  33285. +++ linux-linaro-stable-mx6/arch/arm64/boot/dts/clcd-panels.dtsi 2014-08-20 19:31:40.540845019 +0200
  33286. @@ -0,0 +1,52 @@
  33287. +/*
  33288. + * ARM Ltd. Versatile Express
  33289. + *
  33290. + */
  33291. +
  33292. +/ {
  33293. + panels {
  33294. + panel@0 {
  33295. + compatible = "panel";
  33296. + mode = "VGA";
  33297. + refresh = <60>;
  33298. + xres = <640>;
  33299. + yres = <480>;
  33300. + pixclock = <39721>;
  33301. + left_margin = <40>;
  33302. + right_margin = <24>;
  33303. + upper_margin = <32>;
  33304. + lower_margin = <11>;
  33305. + hsync_len = <96>;
  33306. + vsync_len = <2>;
  33307. + sync = <0>;
  33308. + vmode = "FB_VMODE_NONINTERLACED";
  33309. +
  33310. + tim2 = "TIM2_BCD", "TIM2_IPC";
  33311. + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
  33312. + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
  33313. + bpp = <16>;
  33314. + };
  33315. +
  33316. + panel@1 {
  33317. + compatible = "panel";
  33318. + mode = "XVGA";
  33319. + refresh = <60>;
  33320. + xres = <1024>;
  33321. + yres = <768>;
  33322. + pixclock = <15748>;
  33323. + left_margin = <152>;
  33324. + right_margin = <48>;
  33325. + upper_margin = <23>;
  33326. + lower_margin = <3>;
  33327. + hsync_len = <104>;
  33328. + vsync_len = <4>;
  33329. + sync = <0>;
  33330. + vmode = "FB_VMODE_NONINTERLACED";
  33331. +
  33332. + tim2 = "TIM2_BCD", "TIM2_IPC";
  33333. + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
  33334. + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
  33335. + bpp = <16>;
  33336. + };
  33337. + };
  33338. +};
  33339. diff -Nur linux-3.14.15/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts linux-linaro-stable-mx6/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts
  33340. --- linux-3.14.15/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts 1970-01-01 01:00:00.000000000 +0100
  33341. +++ linux-linaro-stable-mx6/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts 2014-08-20 19:31:40.540845019 +0200
  33342. @@ -0,0 +1,266 @@
  33343. +/*
  33344. + * Copyright (c) 2013, ARM Limited. All rights reserved.
  33345. + *
  33346. + * Redistribution and use in source and binary forms, with or without
  33347. + * modification, are permitted provided that the following conditions are met:
  33348. + *
  33349. + * Redistributions of source code must retain the above copyright notice, this
  33350. + * list of conditions and the following disclaimer.
  33351. + *
  33352. + * Redistributions in binary form must reproduce the above copyright notice,
  33353. + * this list of conditions and the following disclaimer in the documentation
  33354. + * and/or other materials provided with the distribution.
  33355. + *
  33356. + * Neither the name of ARM nor the names of its contributors may be used
  33357. + * to endorse or promote products derived from this software without specific
  33358. + * prior written permission.
  33359. + *
  33360. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  33361. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33362. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33363. + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  33364. + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33365. + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33366. + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33367. + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33368. + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33369. + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33370. + * POSSIBILITY OF SUCH DAMAGE.
  33371. + */
  33372. +
  33373. +/dts-v1/;
  33374. +
  33375. +/memreserve/ 0x80000000 0x00010000;
  33376. +
  33377. +/ {
  33378. +};
  33379. +
  33380. +/ {
  33381. + model = "FVP Base";
  33382. + compatible = "arm,vfp-base", "arm,vexpress";
  33383. + interrupt-parent = <&gic>;
  33384. + #address-cells = <2>;
  33385. + #size-cells = <2>;
  33386. +
  33387. + chosen { };
  33388. +
  33389. + aliases {
  33390. + serial0 = &v2m_serial0;
  33391. + serial1 = &v2m_serial1;
  33392. + serial2 = &v2m_serial2;
  33393. + serial3 = &v2m_serial3;
  33394. + };
  33395. +
  33396. + psci {
  33397. + compatible = "arm,psci";
  33398. + method = "smc";
  33399. + cpu_suspend = <0xc4000001>;
  33400. + cpu_off = <0x84000002>;
  33401. + cpu_on = <0xc4000003>;
  33402. + };
  33403. +
  33404. + cpus {
  33405. + #address-cells = <2>;
  33406. + #size-cells = <0>;
  33407. +
  33408. + big0: cpu@0 {
  33409. + device_type = "cpu";
  33410. + compatible = "arm,cortex-a57", "arm,armv8";
  33411. + reg = <0x0 0x0>;
  33412. + enable-method = "psci";
  33413. + clock-frequency = <1000000>;
  33414. + };
  33415. + big1: cpu@1 {
  33416. + device_type = "cpu";
  33417. + compatible = "arm,cortex-a57", "arm,armv8";
  33418. + reg = <0x0 0x1>;
  33419. + enable-method = "psci";
  33420. + clock-frequency = <1000000>;
  33421. + };
  33422. + big2: cpu@2 {
  33423. + device_type = "cpu";
  33424. + compatible = "arm,cortex-a57", "arm,armv8";
  33425. + reg = <0x0 0x2>;
  33426. + enable-method = "psci";
  33427. + clock-frequency = <1000000>;
  33428. + };
  33429. + big3: cpu@3 {
  33430. + device_type = "cpu";
  33431. + compatible = "arm,cortex-a57", "arm,armv8";
  33432. + reg = <0x0 0x3>;
  33433. + enable-method = "psci";
  33434. + clock-frequency = <1000000>;
  33435. + };
  33436. + little0: cpu@100 {
  33437. + device_type = "cpu";
  33438. + compatible = "arm,cortex-a53", "arm,armv8";
  33439. + reg = <0x0 0x100>;
  33440. + enable-method = "psci";
  33441. + clock-frequency = <1000000>;
  33442. + };
  33443. + little1: cpu@101 {
  33444. + device_type = "cpu";
  33445. + compatible = "arm,cortex-a53", "arm,armv8";
  33446. + reg = <0x0 0x101>;
  33447. + enable-method = "psci";
  33448. + clock-frequency = <1000000>;
  33449. + };
  33450. + little2: cpu@102 {
  33451. + device_type = "cpu";
  33452. + compatible = "arm,cortex-a53", "arm,armv8";
  33453. + reg = <0x0 0x102>;
  33454. + enable-method = "psci";
  33455. + clock-frequency = <1000000>;
  33456. + };
  33457. + little3: cpu@103 {
  33458. + device_type = "cpu";
  33459. + compatible = "arm,cortex-a53", "arm,armv8";
  33460. + reg = <0x0 0x103>;
  33461. + enable-method = "psci";
  33462. + clock-frequency = <1000000>;
  33463. + };
  33464. +
  33465. + cpu-map {
  33466. + cluster0 {
  33467. + core0 {
  33468. + cpu = <&big0>;
  33469. + };
  33470. + core1 {
  33471. + cpu = <&big1>;
  33472. + };
  33473. + core2 {
  33474. + cpu = <&big2>;
  33475. + };
  33476. + core3 {
  33477. + cpu = <&big3>;
  33478. + };
  33479. + };
  33480. + cluster1 {
  33481. + core0 {
  33482. + cpu = <&little0>;
  33483. + };
  33484. + core1 {
  33485. + cpu = <&little1>;
  33486. + };
  33487. + core2 {
  33488. + cpu = <&little2>;
  33489. + };
  33490. + core3 {
  33491. + cpu = <&little3>;
  33492. + };
  33493. + };
  33494. + };
  33495. + };
  33496. +
  33497. + memory@80000000 {
  33498. + device_type = "memory";
  33499. + reg = <0x00000000 0x80000000 0 0x80000000>,
  33500. + <0x00000008 0x80000000 0 0x80000000>;
  33501. + };
  33502. +
  33503. + gic: interrupt-controller@2f000000 {
  33504. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  33505. + #interrupt-cells = <3>;
  33506. + #address-cells = <0>;
  33507. + interrupt-controller;
  33508. + reg = <0x0 0x2f000000 0 0x10000>,
  33509. + <0x0 0x2c000000 0 0x2000>,
  33510. + <0x0 0x2c010000 0 0x2000>,
  33511. + <0x0 0x2c02F000 0 0x2000>;
  33512. + interrupts = <1 9 0xf04>;
  33513. + };
  33514. +
  33515. + timer {
  33516. + compatible = "arm,armv8-timer";
  33517. + interrupts = <1 13 0xff01>,
  33518. + <1 14 0xff01>,
  33519. + <1 11 0xff01>,
  33520. + <1 10 0xff01>;
  33521. + clock-frequency = <100000000>;
  33522. + };
  33523. +
  33524. + timer@2a810000 {
  33525. + compatible = "arm,armv7-timer-mem";
  33526. + reg = <0x0 0x2a810000 0x0 0x10000>;
  33527. + clock-frequency = <100000000>;
  33528. + #address-cells = <2>;
  33529. + #size-cells = <2>;
  33530. + ranges;
  33531. + frame@2a820000 {
  33532. + frame-number = <0>;
  33533. + interrupts = <0 25 4>;
  33534. + reg = <0x0 0x2a820000 0x0 0x10000>;
  33535. + };
  33536. + };
  33537. +
  33538. + pmu {
  33539. + compatible = "arm,armv8-pmuv3";
  33540. + interrupts = <0 60 4>,
  33541. + <0 61 4>,
  33542. + <0 62 4>,
  33543. + <0 63 4>;
  33544. + };
  33545. +
  33546. + smb {
  33547. + compatible = "simple-bus";
  33548. +
  33549. + #address-cells = <2>;
  33550. + #size-cells = <1>;
  33551. + ranges = <0 0 0 0x08000000 0x04000000>,
  33552. + <1 0 0 0x14000000 0x04000000>,
  33553. + <2 0 0 0x18000000 0x04000000>,
  33554. + <3 0 0 0x1c000000 0x04000000>,
  33555. + <4 0 0 0x0c000000 0x04000000>,
  33556. + <5 0 0 0x10000000 0x04000000>;
  33557. +
  33558. + #interrupt-cells = <1>;
  33559. + interrupt-map-mask = <0 0 63>;
  33560. + interrupt-map = <0 0 0 &gic 0 0 4>,
  33561. + <0 0 1 &gic 0 1 4>,
  33562. + <0 0 2 &gic 0 2 4>,
  33563. + <0 0 3 &gic 0 3 4>,
  33564. + <0 0 4 &gic 0 4 4>,
  33565. + <0 0 5 &gic 0 5 4>,
  33566. + <0 0 6 &gic 0 6 4>,
  33567. + <0 0 7 &gic 0 7 4>,
  33568. + <0 0 8 &gic 0 8 4>,
  33569. + <0 0 9 &gic 0 9 4>,
  33570. + <0 0 10 &gic 0 10 4>,
  33571. + <0 0 11 &gic 0 11 4>,
  33572. + <0 0 12 &gic 0 12 4>,
  33573. + <0 0 13 &gic 0 13 4>,
  33574. + <0 0 14 &gic 0 14 4>,
  33575. + <0 0 15 &gic 0 15 4>,
  33576. + <0 0 16 &gic 0 16 4>,
  33577. + <0 0 17 &gic 0 17 4>,
  33578. + <0 0 18 &gic 0 18 4>,
  33579. + <0 0 19 &gic 0 19 4>,
  33580. + <0 0 20 &gic 0 20 4>,
  33581. + <0 0 21 &gic 0 21 4>,
  33582. + <0 0 22 &gic 0 22 4>,
  33583. + <0 0 23 &gic 0 23 4>,
  33584. + <0 0 24 &gic 0 24 4>,
  33585. + <0 0 25 &gic 0 25 4>,
  33586. + <0 0 26 &gic 0 26 4>,
  33587. + <0 0 27 &gic 0 27 4>,
  33588. + <0 0 28 &gic 0 28 4>,
  33589. + <0 0 29 &gic 0 29 4>,
  33590. + <0 0 30 &gic 0 30 4>,
  33591. + <0 0 31 &gic 0 31 4>,
  33592. + <0 0 32 &gic 0 32 4>,
  33593. + <0 0 33 &gic 0 33 4>,
  33594. + <0 0 34 &gic 0 34 4>,
  33595. + <0 0 35 &gic 0 35 4>,
  33596. + <0 0 36 &gic 0 36 4>,
  33597. + <0 0 37 &gic 0 37 4>,
  33598. + <0 0 38 &gic 0 38 4>,
  33599. + <0 0 39 &gic 0 39 4>,
  33600. + <0 0 40 &gic 0 40 4>,
  33601. + <0 0 41 &gic 0 41 4>,
  33602. + <0 0 42 &gic 0 42 4>;
  33603. +
  33604. + /include/ "rtsm_ve-motherboard.dtsi"
  33605. + };
  33606. +};
  33607. +
  33608. +/include/ "clcd-panels.dtsi"
  33609. diff -Nur linux-3.14.15/arch/arm64/boot/dts/juno.dts linux-linaro-stable-mx6/arch/arm64/boot/dts/juno.dts
  33610. --- linux-3.14.15/arch/arm64/boot/dts/juno.dts 1970-01-01 01:00:00.000000000 +0100
  33611. +++ linux-linaro-stable-mx6/arch/arm64/boot/dts/juno.dts 2014-08-20 19:31:40.540845019 +0200
  33612. @@ -0,0 +1,498 @@
  33613. +/*
  33614. + * ARM Ltd. Juno Plaform
  33615. + *
  33616. + * Fast Models FVP v2 support
  33617. + */
  33618. +
  33619. +/dts-v1/;
  33620. +
  33621. +#include <dt-bindings/interrupt-controller/arm-gic.h>
  33622. +
  33623. +/ {
  33624. + model = "Juno";
  33625. + compatible = "arm,juno", "arm,vexpress";
  33626. + interrupt-parent = <&gic>;
  33627. + #address-cells = <2>;
  33628. + #size-cells = <2>;
  33629. +
  33630. + aliases {
  33631. + serial0 = &soc_uart0;
  33632. + };
  33633. +
  33634. + cpus {
  33635. + #address-cells = <2>;
  33636. + #size-cells = <0>;
  33637. +
  33638. + cpu@100 {
  33639. + device_type = "cpu";
  33640. + compatible = "arm,cortex-a53","arm,armv8";
  33641. + reg = <0x0 0x100>;
  33642. + enable-method = "psci";
  33643. + };
  33644. +
  33645. + cpu@101 {
  33646. + device_type = "cpu";
  33647. + compatible = "arm,cortex-a53","arm,armv8";
  33648. + reg = <0x0 0x101>;
  33649. + enable-method = "psci";
  33650. + };
  33651. +
  33652. + cpu@102 {
  33653. + device_type = "cpu";
  33654. + compatible = "arm,cortex-a53","arm,armv8";
  33655. + reg = <0x0 0x102>;
  33656. + enable-method = "psci";
  33657. + };
  33658. +
  33659. + cpu@103 {
  33660. + device_type = "cpu";
  33661. + compatible = "arm,cortex-a53","arm,armv8";
  33662. + reg = <0x0 0x103>;
  33663. + enable-method = "psci";
  33664. + };
  33665. +
  33666. + cpu@0 {
  33667. + device_type = "cpu";
  33668. + compatible = "arm,cortex-a57","arm,armv8";
  33669. + reg = <0x0 0x0>;
  33670. + enable-method = "psci";
  33671. + };
  33672. +
  33673. + cpu@1 {
  33674. + device_type = "cpu";
  33675. + compatible = "arm,cortex-a57","arm,armv8";
  33676. + reg = <0x0 0x1>;
  33677. + enable-method = "psci";
  33678. + };
  33679. + };
  33680. +
  33681. + memory@80000000 {
  33682. + device_type = "memory";
  33683. + reg = <0x00000000 0x80000000 0x0 0x80000000>,
  33684. + <0x00000008 0x80000000 0x1 0x80000000>;
  33685. + };
  33686. +
  33687. + /* memory@14000000 {
  33688. + device_type = "memory";
  33689. + reg = <0x00000000 0x14000000 0x0 0x02000000>;
  33690. + }; */
  33691. +
  33692. + gic: interrupt-controller@2c001000 {
  33693. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  33694. + #interrupt-cells = <3>;
  33695. + #address-cells = <0>;
  33696. + interrupt-controller;
  33697. + reg = <0x0 0x2c010000 0 0x1000>,
  33698. + <0x0 0x2c02f000 0 0x1000>,
  33699. + <0x0 0x2c04f000 0 0x2000>,
  33700. + <0x0 0x2c06f000 0 0x2000>;
  33701. + interrupts = <GIC_PPI 9 0xf04>;
  33702. + };
  33703. +
  33704. + msi0: msi@2c1c0000 {
  33705. + compatible = "arm,gic-msi";
  33706. + reg = <0x0 0x2c1c0000 0 0x10000
  33707. + 0x0 0x2c1d0000 0 0x10000
  33708. + 0x0 0x2c1e0000 0 0x10000
  33709. + 0x0 0x2c1f0000 0 0x10000>;
  33710. + };
  33711. +
  33712. + timer {
  33713. + compatible = "arm,armv8-timer";
  33714. + interrupts = <GIC_PPI 13 0xff01>,
  33715. + <GIC_PPI 14 0xff01>,
  33716. + <GIC_PPI 11 0xff01>,
  33717. + <GIC_PPI 10 0xff01>;
  33718. + };
  33719. +
  33720. + pmu {
  33721. + compatible = "arm,armv8-pmuv3";
  33722. + interrupts = <GIC_SPI 60 4>,
  33723. + <GIC_SPI 61 4>,
  33724. + <GIC_SPI 62 4>,
  33725. + <GIC_SPI 63 4>;
  33726. + };
  33727. +
  33728. + psci {
  33729. + compatible = "arm,psci";
  33730. + method = "smc";
  33731. + cpu_suspend = <0xC4000001>;
  33732. + cpu_off = <0x84000002>;
  33733. + cpu_on = <0xC4000003>;
  33734. + migrate = <0xC4000005>;
  33735. + };
  33736. +
  33737. + pci0: pci@30000000 {
  33738. + compatible = "arm,pcie-xr3";
  33739. + device_type = "pci";
  33740. + reg = <0 0x7ff30000 0 0x1000
  33741. + 0 0x7ff20000 0 0x10000
  33742. + 0 0x40000000 0 0x10000000>;
  33743. + bus-range = <0 255>;
  33744. + #address-cells = <3>;
  33745. + #size-cells = <2>;
  33746. + ranges = <0x01000000 0x0 0x00000000 0x00 0x5ff00000 0x0 0x00100000
  33747. + 0x02000000 0x0 0x00000000 0x40 0x00000000 0x0 0x80000000
  33748. + 0x42000000 0x0 0x80000000 0x40 0x80000000 0x0 0x80000000>;
  33749. + #interrupt-cells = <1>;
  33750. + interrupt-map-mask = <0 0 0 7>;
  33751. + interrupt-map = <0 0 0 1 &gic 0 136 4
  33752. + 0 0 0 2 &gic 0 137 4
  33753. + 0 0 0 3 &gic 0 138 4
  33754. + 0 0 0 4 &gic 0 139 4>;
  33755. + };
  33756. +
  33757. + scpi: scpi@2b1f0000 {
  33758. + compatible = "arm,scpi-mhu";
  33759. + reg = <0x0 0x2b1f0000 0x0 0x10000>, /* MHU registers */
  33760. + <0x0 0x2e000000 0x0 0x10000>; /* Payload area */
  33761. + interrupts = <0 36 4>, /* low priority interrupt */
  33762. + <0 35 4>, /* high priority interrupt */
  33763. + <0 37 4>; /* secure channel interrupt */
  33764. + #clock-cells = <1>;
  33765. + clock-output-names = "a57", "a53", "gpu", "hdlcd0", "hdlcd1";
  33766. + };
  33767. +
  33768. + hdlcd0_osc: scpi_osc@3 {
  33769. + compatible = "arm,scpi-osc";
  33770. + #clock-cells = <0>;
  33771. + clocks = <&scpi 3>;
  33772. + frequency-range = <23000000 210000000>;
  33773. + clock-output-names = "pxlclk0";
  33774. + };
  33775. +
  33776. + hdlcd1_osc: scpi_osc@4 {
  33777. + compatible = "arm,scpi-osc";
  33778. + #clock-cells = <0>;
  33779. + clocks = <&scpi 4>;
  33780. + frequency-range = <23000000 210000000>;
  33781. + clock-output-names = "pxlclk1";
  33782. + };
  33783. +
  33784. + soc_uartclk: refclk72738khz {
  33785. + compatible = "fixed-clock";
  33786. + #clock-cells = <0>;
  33787. + clock-frequency = <7273800>;
  33788. + clock-output-names = "juno:uartclk";
  33789. + };
  33790. +
  33791. + soc_refclk24mhz: clk24mhz {
  33792. + compatible = "fixed-clock";
  33793. + #clock-cells = <0>;
  33794. + clock-frequency = <24000000>;
  33795. + clock-output-names = "juno:clk24mhz";
  33796. + };
  33797. +
  33798. + mb_eth25mhz: clk25mhz {
  33799. + compatible = "fixed-clock";
  33800. + #clock-cells = <0>;
  33801. + clock-frequency = <25000000>;
  33802. + clock-output-names = "ethclk25mhz";
  33803. + };
  33804. +
  33805. + soc_usb48mhz: clk48mhz {
  33806. + compatible = "fixed-clock";
  33807. + #clock-cells = <0>;
  33808. + clock-frequency = <48000000>;
  33809. + clock-output-names = "clk48mhz";
  33810. + };
  33811. +
  33812. + soc_smc50mhz: clk50mhz {
  33813. + compatible = "fixed-clock";
  33814. + #clock-cells = <0>;
  33815. + clock-frequency = <50000000>;
  33816. + clock-output-names = "smc_clk";
  33817. + };
  33818. +
  33819. + soc_refclk100mhz: refclk100mhz {
  33820. + compatible = "fixed-clock";
  33821. + #clock-cells = <0>;
  33822. + clock-frequency = <100000000>;
  33823. + clock-output-names = "apb_pclk";
  33824. + };
  33825. +
  33826. + soc_faxiclk: refclk533mhz {
  33827. + compatible = "fixed-clock";
  33828. + #clock-cells = <0>;
  33829. + clock-frequency = <533000000>;
  33830. + clock-output-names = "faxi_clk";
  33831. + };
  33832. +
  33833. + soc_fixed_3v3: fixedregulator@0 {
  33834. + compatible = "regulator-fixed";
  33835. + regulator-name = "3V3";
  33836. + regulator-min-microvolt = <3300000>;
  33837. + regulator-max-microvolt = <3300000>;
  33838. + regulator-always-on;
  33839. + };
  33840. +
  33841. + memory-controller@7ffd0000 {
  33842. + compatible = "arm,pl354", "arm,primecell";
  33843. + reg = <0 0x7ffd0000 0 0x1000>;
  33844. + interrupts = <0 86 4>,
  33845. + <0 87 4>;
  33846. + clocks = <&soc_smc50mhz>;
  33847. + clock-names = "apb_pclk";
  33848. + chip5-memwidth = <16>;
  33849. + };
  33850. +
  33851. + dma0: dma@0x7ff00000 {
  33852. + compatible = "arm,pl330", "arm,primecell";
  33853. + reg = <0x0 0x7ff00000 0 0x1000>;
  33854. + interrupts = <0 95 4>,
  33855. + <0 88 4>,
  33856. + <0 89 4>,
  33857. + <0 90 4>,
  33858. + <0 91 4>,
  33859. + <0 108 4>,
  33860. + <0 109 4>,
  33861. + <0 110 4>,
  33862. + <0 111 4>;
  33863. + #dma-cells = <1>;
  33864. + #dma-channels = <8>;
  33865. + #dma-requests = <32>;
  33866. + clocks = <&soc_faxiclk>;
  33867. + clock-names = "apb_pclk";
  33868. + };
  33869. +
  33870. + soc_uart0: uart@7ff80000 {
  33871. + compatible = "arm,pl011", "arm,primecell";
  33872. + reg = <0x0 0x7ff80000 0x0 0x1000>;
  33873. + interrupts = <0 83 4>;
  33874. + clocks = <&soc_uartclk>, <&soc_refclk100mhz>;
  33875. + clock-names = "uartclk", "apb_pclk";
  33876. + dmas = <&dma0 1
  33877. + &dma0 2>;
  33878. + dma-names = "rx", "tx";
  33879. + };
  33880. +
  33881. + /* this UART is reserved for secure software.
  33882. + soc_uart1: uart@7ff70000 {
  33883. + compatible = "arm,pl011", "arm,primecell";
  33884. + reg = <0x0 0x7ff70000 0x0 0x1000>;
  33885. + interrupts = <0 84 4>;
  33886. + clocks = <&soc_uartclk>, <&soc_refclk100mhz>;
  33887. + clock-names = "uartclk", "apb_pclk";
  33888. + }; */
  33889. +
  33890. + ulpi_phy: phy@0 {
  33891. + compatible = "phy-ulpi-generic";
  33892. + reg = <0x0 0x94 0x0 0x4>;
  33893. + phy-id = <0>;
  33894. + };
  33895. +
  33896. + ehci@7ffc0000 {
  33897. + compatible = "snps,ehci-h20ahb";
  33898. + /* compatible = "arm,h20ahb-ehci"; */
  33899. + reg = <0x0 0x7ffc0000 0x0 0x10000>;
  33900. + interrupts = <0 117 4>;
  33901. + clocks = <&soc_usb48mhz>;
  33902. + clock-names = "otg";
  33903. + phys = <&ulpi_phy>;
  33904. + };
  33905. +
  33906. + ohci@0x7ffb0000 {
  33907. + compatible = "generic-ohci";
  33908. + reg = <0x0 0x7ffb0000 0x0 0x10000>;
  33909. + interrupts = <0 116 4>;
  33910. + clocks = <&soc_usb48mhz>;
  33911. + clock-names = "otg";
  33912. + };
  33913. +
  33914. + i2c@0x7ffa0000 {
  33915. + #address-cells = <1>;
  33916. + #size-cells = <0>;
  33917. + compatible = "snps,designware-i2c";
  33918. + reg = <0x0 0x7ffa0000 0x0 0x1000>;
  33919. + interrupts = <0 104 4>;
  33920. + clock-frequency = <400000>;
  33921. + i2c-sda-hold-time-ns = <500>;
  33922. + clocks = <&soc_smc50mhz>;
  33923. +
  33924. + dvi0: dvi-transmitter@70 {
  33925. + compatible = "nxp,tda998x";
  33926. + reg = <0x70>;
  33927. + };
  33928. +
  33929. + dvi1: dvi-transmitter@71 {
  33930. + compatible = "nxp,tda998x";
  33931. + reg = <0x71>;
  33932. + };
  33933. + };
  33934. +
  33935. + /* mmci@1c050000 {
  33936. + compatible = "arm,pl180", "arm,primecell";
  33937. + reg = <0x0 0x1c050000 0x0 0x1000>;
  33938. + interrupts = <0 73 4>,
  33939. + <0 74 4>;
  33940. + max-frequency = <12000000>;
  33941. + vmmc-supply = <&soc_fixed_3v3>;
  33942. + clocks = <&soc_refclk24mhz>, <&soc_refclk100mhz>;
  33943. + clock-names = "mclk", "apb_pclk";
  33944. + }; */
  33945. +
  33946. + hdlcd@7ff60000 {
  33947. + compatible = "arm,hdlcd";
  33948. + reg = <0 0x7ff60000 0 0x1000>;
  33949. + interrupts = <0 85 4>;
  33950. + clocks = <&hdlcd0_osc>;
  33951. + clock-names = "pxlclk";
  33952. + i2c-slave = <&dvi0>;
  33953. +
  33954. + /* display-timings {
  33955. + native-mode = <&timing0>;
  33956. + timing0: timing@0 {
  33957. + /* 1024 x 768 framebufer, standard VGA timings * /
  33958. + clock-frequency = <65000>;
  33959. + hactive = <1024>;
  33960. + vactive = <768>;
  33961. + hfront-porch = <24>;
  33962. + hback-porch = <160>;
  33963. + hsync-len = <136>;
  33964. + vfront-porch = <3>;
  33965. + vback-porch = <29>;
  33966. + vsync-len = <6>;
  33967. + };
  33968. + }; */
  33969. + };
  33970. +
  33971. + hdlcd@7ff50000 {
  33972. + compatible = "arm,hdlcd";
  33973. + reg = <0 0x7ff50000 0 0x1000>;
  33974. + interrupts = <0 93 4>;
  33975. + clocks = <&hdlcd1_osc>;
  33976. + clock-names = "pxlclk";
  33977. + i2c-slave = <&dvi1>;
  33978. +
  33979. + display-timings {
  33980. + native-mode = <&timing1>;
  33981. + timing1: timing@1 {
  33982. + /* 1024 x 768 framebufer, standard VGA timings */
  33983. + clock-frequency = <65000>;
  33984. + hactive = <1024>;
  33985. + vactive = <768>;
  33986. + hfront-porch = <24>;
  33987. + hback-porch = <160>;
  33988. + hsync-len = <136>;
  33989. + vfront-porch = <3>;
  33990. + vback-porch = <29>;
  33991. + vsync-len = <6>;
  33992. + };
  33993. + };
  33994. + };
  33995. +
  33996. + smb {
  33997. + compatible = "simple-bus";
  33998. + #address-cells = <2>;
  33999. + #size-cells = <1>;
  34000. + ranges = <0 0 0 0x08000000 0x04000000>,
  34001. + <1 0 0 0x14000000 0x04000000>,
  34002. + <2 0 0 0x18000000 0x04000000>,
  34003. + <3 0 0 0x1c000000 0x04000000>,
  34004. + <4 0 0 0x0c000000 0x04000000>,
  34005. + <5 0 0 0x10000000 0x04000000>;
  34006. +
  34007. + #interrupt-cells = <1>;
  34008. + interrupt-map-mask = <0 0 15>;
  34009. + interrupt-map = <0 0 0 &gic 0 68 4>,
  34010. + <0 0 1 &gic 0 69 4>,
  34011. + <0 0 2 &gic 0 70 4>,
  34012. + <0 0 3 &gic 0 160 4>,
  34013. + <0 0 4 &gic 0 161 4>,
  34014. + <0 0 5 &gic 0 162 4>,
  34015. + <0 0 6 &gic 0 163 4>,
  34016. + <0 0 7 &gic 0 164 4>,
  34017. + <0 0 8 &gic 0 165 4>,
  34018. + <0 0 9 &gic 0 166 4>,
  34019. + <0 0 10 &gic 0 167 4>,
  34020. + <0 0 11 &gic 0 168 4>,
  34021. + <0 0 12 &gic 0 169 4>;
  34022. +
  34023. + motherboard {
  34024. + model = "V2M-Juno";
  34025. + arm,hbi = <0x252>;
  34026. + arm,vexpress,site = <0>;
  34027. + arm,v2m-memory-map = "rs1";
  34028. + compatible = "arm,vexpress,v2p-p1", "simple-bus";
  34029. + #address-cells = <2>; /* SMB chipselect number and offset */
  34030. + #size-cells = <1>;
  34031. + #interrupt-cells = <1>;
  34032. + ranges;
  34033. +
  34034. + usb@5,00000000 {
  34035. + compatible = "nxp,usb-isp1763";
  34036. + reg = <5 0x00000000 0x20000>;
  34037. + bus-width = <16>;
  34038. + interrupts = <4>;
  34039. + };
  34040. +
  34041. + ethernet@2,00000000 {
  34042. + compatible = "smsc,lan9118", "smsc,lan9115";
  34043. + reg = <2 0x00000000 0x10000>;
  34044. + interrupts = <3>;
  34045. + phy-mode = "mii";
  34046. + reg-io-width = <4>;
  34047. + smsc,irq-active-high;
  34048. + smsc,irq-push-pull;
  34049. + clocks = <&mb_eth25mhz>;
  34050. + vdd33a-supply = <&soc_fixed_3v3>; /* change this */
  34051. + vddvario-supply = <&soc_fixed_3v3>; /* and this */
  34052. + };
  34053. +
  34054. + iofpga@3,00000000 {
  34055. + compatible = "arm,amba-bus", "simple-bus";
  34056. + #address-cells = <1>;
  34057. + #size-cells = <1>;
  34058. + ranges = <0 3 0 0x200000>;
  34059. +
  34060. + kmi@060000 {
  34061. + compatible = "arm,pl050", "arm,primecell";
  34062. + reg = <0x060000 0x1000>;
  34063. + interrupts = <8>;
  34064. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34065. + clock-names = "KMIREFCLK", "apb_pclk";
  34066. + };
  34067. +
  34068. + kmi@070000 {
  34069. + compatible = "arm,pl050", "arm,primecell";
  34070. + reg = <0x070000 0x1000>;
  34071. + interrupts = <8>;
  34072. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34073. + clock-names = "KMIREFCLK", "apb_pclk";
  34074. + };
  34075. +
  34076. + wdt@0f0000 {
  34077. + compatible = "arm,sp805", "arm,primecell";
  34078. + reg = <0x0f0000 0x10000>;
  34079. + interrupts = <7>;
  34080. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34081. + clock-names = "wdogclk", "apb_pclk";
  34082. + };
  34083. +
  34084. + v2m_timer01: timer@110000 {
  34085. + compatible = "arm,sp804", "arm,primecell";
  34086. + reg = <0x110000 0x10000>;
  34087. + interrupts = <9>;
  34088. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34089. + clock-names = "timclken1", "apb_pclk";
  34090. + };
  34091. +
  34092. + v2m_timer23: timer@120000 {
  34093. + compatible = "arm,sp804", "arm,primecell";
  34094. + reg = <0x120000 0x10000>;
  34095. + interrupts = <9>;
  34096. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34097. + clock-names = "timclken1", "apb_pclk";
  34098. + };
  34099. +
  34100. + rtc@170000 {
  34101. + compatible = "arm,pl031", "arm,primecell";
  34102. + reg = <0x170000 0x10000>;
  34103. + interrupts = <0>;
  34104. + clocks = <&soc_smc50mhz>;
  34105. + clock-names = "apb_pclk";
  34106. + };
  34107. + };
  34108. + };
  34109. + };
  34110. +};
  34111. diff -Nur linux-3.14.15/arch/arm64/boot/dts/Makefile linux-linaro-stable-mx6/arch/arm64/boot/dts/Makefile
  34112. --- linux-3.14.15/arch/arm64/boot/dts/Makefile 2014-07-31 23:51:43.000000000 +0200
  34113. +++ linux-linaro-stable-mx6/arch/arm64/boot/dts/Makefile 2014-08-20 19:31:40.540845019 +0200
  34114. @@ -1,5 +1,7 @@
  34115. -dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb
  34116. +dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb \
  34117. + fvp-base-gicv2-psci.dtb
  34118. dtb-$(CONFIG_ARCH_XGENE) += apm-mustang.dtb
  34119. +dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb
  34120. targets += dtbs
  34121. targets += $(dtb-y)
  34122. diff -Nur linux-3.14.15/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts linux-linaro-stable-mx6/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts
  34123. --- linux-3.14.15/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts 2014-07-31 23:51:43.000000000 +0200
  34124. +++ linux-linaro-stable-mx6/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts 2014-08-20 19:31:40.540845019 +0200
  34125. @@ -157,3 +157,5 @@
  34126. /include/ "rtsm_ve-motherboard.dtsi"
  34127. };
  34128. };
  34129. +
  34130. +/include/ "clcd-panels.dtsi"
  34131. diff -Nur linux-3.14.15/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi linux-linaro-stable-mx6/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi
  34132. --- linux-3.14.15/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi 2014-07-31 23:51:43.000000000 +0200
  34133. +++ linux-linaro-stable-mx6/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi 2014-08-20 19:23:46.326814964 +0200
  34134. @@ -182,6 +182,9 @@
  34135. interrupts = <14>;
  34136. clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
  34137. clock-names = "clcdclk", "apb_pclk";
  34138. + mode = "XVGA";
  34139. + use_dma = <0>;
  34140. + framebuffer = <0x18000000 0x00180000>;
  34141. };
  34142. virtio_block@0130000 {
  34143. diff -Nur linux-3.14.15/arch/arm64/crypto/aes-ce-ccm-core.S linux-linaro-stable-mx6/arch/arm64/crypto/aes-ce-ccm-core.S
  34144. --- linux-3.14.15/arch/arm64/crypto/aes-ce-ccm-core.S 1970-01-01 01:00:00.000000000 +0100
  34145. +++ linux-linaro-stable-mx6/arch/arm64/crypto/aes-ce-ccm-core.S 2014-08-20 19:31:40.540845019 +0200
  34146. @@ -0,0 +1,222 @@
  34147. +/*
  34148. + * aesce-ccm-core.S - AES-CCM transform for ARMv8 with Crypto Extensions
  34149. + *
  34150. + * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  34151. + *
  34152. + * This program is free software; you can redistribute it and/or modify
  34153. + * it under the terms of the GNU General Public License version 2 as
  34154. + * published by the Free Software Foundation.
  34155. + */
  34156. +
  34157. +#include <linux/linkage.h>
  34158. +
  34159. + .text
  34160. + .arch armv8-a+crypto
  34161. +
  34162. + /*
  34163. + * void ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
  34164. + * u32 *macp, u8 const rk[], u32 rounds);
  34165. + */
  34166. +ENTRY(ce_aes_ccm_auth_data)
  34167. + ldr w8, [x3] /* leftover from prev round? */
  34168. + ld1 {v0.2d}, [x0] /* load mac */
  34169. + cbz w8, 1f
  34170. + sub w8, w8, #16
  34171. + eor v1.16b, v1.16b, v1.16b
  34172. +0: ldrb w7, [x1], #1 /* get 1 byte of input */
  34173. + subs w2, w2, #1
  34174. + add w8, w8, #1
  34175. + ins v1.b[0], w7
  34176. + ext v1.16b, v1.16b, v1.16b, #1 /* rotate in the input bytes */
  34177. + beq 8f /* out of input? */
  34178. + cbnz w8, 0b
  34179. + eor v0.16b, v0.16b, v1.16b
  34180. +1: ld1 {v3.2d}, [x4] /* load first round key */
  34181. + prfm pldl1strm, [x1]
  34182. + cmp w5, #12 /* which key size? */
  34183. + add x6, x4, #16
  34184. + sub w7, w5, #2 /* modified # of rounds */
  34185. + bmi 2f
  34186. + bne 5f
  34187. + mov v5.16b, v3.16b
  34188. + b 4f
  34189. +2: mov v4.16b, v3.16b
  34190. + ld1 {v5.2d}, [x6], #16 /* load 2nd round key */
  34191. +3: aese v0.16b, v4.16b
  34192. + aesmc v0.16b, v0.16b
  34193. +4: ld1 {v3.2d}, [x6], #16 /* load next round key */
  34194. + aese v0.16b, v5.16b
  34195. + aesmc v0.16b, v0.16b
  34196. +5: ld1 {v4.2d}, [x6], #16 /* load next round key */
  34197. + subs w7, w7, #3
  34198. + aese v0.16b, v3.16b
  34199. + aesmc v0.16b, v0.16b
  34200. + ld1 {v5.2d}, [x6], #16 /* load next round key */
  34201. + bpl 3b
  34202. + aese v0.16b, v4.16b
  34203. + subs w2, w2, #16 /* last data? */
  34204. + eor v0.16b, v0.16b, v5.16b /* final round */
  34205. + bmi 6f
  34206. + ld1 {v1.16b}, [x1], #16 /* load next input block */
  34207. + eor v0.16b, v0.16b, v1.16b /* xor with mac */
  34208. + bne 1b
  34209. +6: st1 {v0.2d}, [x0] /* store mac */
  34210. + beq 10f
  34211. + adds w2, w2, #16
  34212. + beq 10f
  34213. + mov w8, w2
  34214. +7: ldrb w7, [x1], #1
  34215. + umov w6, v0.b[0]
  34216. + eor w6, w6, w7
  34217. + strb w6, [x0], #1
  34218. + subs w2, w2, #1
  34219. + beq 10f
  34220. + ext v0.16b, v0.16b, v0.16b, #1 /* rotate out the mac bytes */
  34221. + b 7b
  34222. +8: mov w7, w8
  34223. + add w8, w8, #16
  34224. +9: ext v1.16b, v1.16b, v1.16b, #1
  34225. + adds w7, w7, #1
  34226. + bne 9b
  34227. + eor v0.16b, v0.16b, v1.16b
  34228. + st1 {v0.2d}, [x0]
  34229. +10: str w8, [x3]
  34230. + ret
  34231. +ENDPROC(ce_aes_ccm_auth_data)
  34232. +
  34233. + /*
  34234. + * void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u8 const rk[],
  34235. + * u32 rounds);
  34236. + */
  34237. +ENTRY(ce_aes_ccm_final)
  34238. + ld1 {v3.2d}, [x2], #16 /* load first round key */
  34239. + ld1 {v0.2d}, [x0] /* load mac */
  34240. + cmp w3, #12 /* which key size? */
  34241. + sub w3, w3, #2 /* modified # of rounds */
  34242. + ld1 {v1.2d}, [x1] /* load 1st ctriv */
  34243. + bmi 0f
  34244. + bne 3f
  34245. + mov v5.16b, v3.16b
  34246. + b 2f
  34247. +0: mov v4.16b, v3.16b
  34248. +1: ld1 {v5.2d}, [x2], #16 /* load next round key */
  34249. + aese v0.16b, v4.16b
  34250. + aese v1.16b, v4.16b
  34251. + aesmc v0.16b, v0.16b
  34252. + aesmc v1.16b, v1.16b
  34253. +2: ld1 {v3.2d}, [x2], #16 /* load next round key */
  34254. + aese v0.16b, v5.16b
  34255. + aese v1.16b, v5.16b
  34256. + aesmc v0.16b, v0.16b
  34257. + aesmc v1.16b, v1.16b
  34258. +3: ld1 {v4.2d}, [x2], #16 /* load next round key */
  34259. + subs w3, w3, #3
  34260. + aese v0.16b, v3.16b
  34261. + aese v1.16b, v3.16b
  34262. + aesmc v0.16b, v0.16b
  34263. + aesmc v1.16b, v1.16b
  34264. + bpl 1b
  34265. + aese v0.16b, v4.16b
  34266. + aese v1.16b, v4.16b
  34267. + /* final round key cancels out */
  34268. + eor v0.16b, v0.16b, v1.16b /* en-/decrypt the mac */
  34269. + st1 {v0.2d}, [x0] /* store result */
  34270. + ret
  34271. +ENDPROC(ce_aes_ccm_final)
  34272. +
  34273. + .macro aes_ccm_do_crypt,enc
  34274. + ldr x8, [x6, #8] /* load lower ctr */
  34275. + ld1 {v0.2d}, [x5] /* load mac */
  34276. + rev x8, x8 /* keep swabbed ctr in reg */
  34277. +0: /* outer loop */
  34278. + ld1 {v1.1d}, [x6] /* load upper ctr */
  34279. + prfm pldl1strm, [x1]
  34280. + add x8, x8, #1
  34281. + rev x9, x8
  34282. + cmp w4, #12 /* which key size? */
  34283. + sub w7, w4, #2 /* get modified # of rounds */
  34284. + ins v1.d[1], x9 /* no carry in lower ctr */
  34285. + ld1 {v3.2d}, [x3] /* load first round key */
  34286. + add x10, x3, #16
  34287. + bmi 1f
  34288. + bne 4f
  34289. + mov v5.16b, v3.16b
  34290. + b 3f
  34291. +1: mov v4.16b, v3.16b
  34292. + ld1 {v5.2d}, [x10], #16 /* load 2nd round key */
  34293. +2: /* inner loop: 3 rounds, 2x interleaved */
  34294. + aese v0.16b, v4.16b
  34295. + aese v1.16b, v4.16b
  34296. + aesmc v0.16b, v0.16b
  34297. + aesmc v1.16b, v1.16b
  34298. +3: ld1 {v3.2d}, [x10], #16 /* load next round key */
  34299. + aese v0.16b, v5.16b
  34300. + aese v1.16b, v5.16b
  34301. + aesmc v0.16b, v0.16b
  34302. + aesmc v1.16b, v1.16b
  34303. +4: ld1 {v4.2d}, [x10], #16 /* load next round key */
  34304. + subs w7, w7, #3
  34305. + aese v0.16b, v3.16b
  34306. + aese v1.16b, v3.16b
  34307. + aesmc v0.16b, v0.16b
  34308. + aesmc v1.16b, v1.16b
  34309. + ld1 {v5.2d}, [x10], #16 /* load next round key */
  34310. + bpl 2b
  34311. + aese v0.16b, v4.16b
  34312. + aese v1.16b, v4.16b
  34313. + subs w2, w2, #16
  34314. + bmi 6f /* partial block? */
  34315. + ld1 {v2.16b}, [x1], #16 /* load next input block */
  34316. + .if \enc == 1
  34317. + eor v2.16b, v2.16b, v5.16b /* final round enc+mac */
  34318. + eor v1.16b, v1.16b, v2.16b /* xor with crypted ctr */
  34319. + .else
  34320. + eor v2.16b, v2.16b, v1.16b /* xor with crypted ctr */
  34321. + eor v1.16b, v2.16b, v5.16b /* final round enc */
  34322. + .endif
  34323. + eor v0.16b, v0.16b, v2.16b /* xor mac with pt ^ rk[last] */
  34324. + st1 {v1.16b}, [x0], #16 /* write output block */
  34325. + bne 0b
  34326. + rev x8, x8
  34327. + st1 {v0.2d}, [x5] /* store mac */
  34328. + str x8, [x6, #8] /* store lsb end of ctr (BE) */
  34329. +5: ret
  34330. +
  34331. +6: eor v0.16b, v0.16b, v5.16b /* final round mac */
  34332. + eor v1.16b, v1.16b, v5.16b /* final round enc */
  34333. + st1 {v0.2d}, [x5] /* store mac */
  34334. + add w2, w2, #16 /* process partial tail block */
  34335. +7: ldrb w9, [x1], #1 /* get 1 byte of input */
  34336. + umov w6, v1.b[0] /* get top crypted ctr byte */
  34337. + umov w7, v0.b[0] /* get top mac byte */
  34338. + .if \enc == 1
  34339. + eor w7, w7, w9
  34340. + eor w9, w9, w6
  34341. + .else
  34342. + eor w9, w9, w6
  34343. + eor w7, w7, w9
  34344. + .endif
  34345. + strb w9, [x0], #1 /* store out byte */
  34346. + strb w7, [x5], #1 /* store mac byte */
  34347. + subs w2, w2, #1
  34348. + beq 5b
  34349. + ext v0.16b, v0.16b, v0.16b, #1 /* shift out mac byte */
  34350. + ext v1.16b, v1.16b, v1.16b, #1 /* shift out ctr byte */
  34351. + b 7b
  34352. + .endm
  34353. +
  34354. + /*
  34355. + * void ce_aes_ccm_encrypt(u8 out[], u8 const in[], u32 cbytes,
  34356. + * u8 const rk[], u32 rounds, u8 mac[],
  34357. + * u8 ctr[]);
  34358. + * void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes,
  34359. + * u8 const rk[], u32 rounds, u8 mac[],
  34360. + * u8 ctr[]);
  34361. + */
  34362. +ENTRY(ce_aes_ccm_encrypt)
  34363. + aes_ccm_do_crypt 1
  34364. +ENDPROC(ce_aes_ccm_encrypt)
  34365. +
  34366. +ENTRY(ce_aes_ccm_decrypt)
  34367. + aes_ccm_do_crypt 0
  34368. +ENDPROC(ce_aes_ccm_decrypt)
  34369. diff -Nur linux-3.14.15/arch/arm64/crypto/aes-ce-ccm-glue.c linux-linaro-stable-mx6/arch/arm64/crypto/aes-ce-ccm-glue.c
  34370. --- linux-3.14.15/arch/arm64/crypto/aes-ce-ccm-glue.c 1970-01-01 01:00:00.000000000 +0100
  34371. +++ linux-linaro-stable-mx6/arch/arm64/crypto/aes-ce-ccm-glue.c 2014-08-20 19:31:40.540845019 +0200
  34372. @@ -0,0 +1,297 @@
  34373. +/*
  34374. + * aes-ccm-glue.c - AES-CCM transform for ARMv8 with Crypto Extensions
  34375. + *
  34376. + * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  34377. + *
  34378. + * This program is free software; you can redistribute it and/or modify
  34379. + * it under the terms of the GNU General Public License version 2 as
  34380. + * published by the Free Software Foundation.
  34381. + */
  34382. +
  34383. +#include <asm/neon.h>
  34384. +#include <asm/unaligned.h>
  34385. +#include <crypto/aes.h>
  34386. +#include <crypto/algapi.h>
  34387. +#include <crypto/scatterwalk.h>
  34388. +#include <linux/crypto.h>
  34389. +#include <linux/module.h>
  34390. +
  34391. +static int num_rounds(struct crypto_aes_ctx *ctx)
  34392. +{
  34393. + /*
  34394. + * # of rounds specified by AES:
  34395. + * 128 bit key 10 rounds
  34396. + * 192 bit key 12 rounds
  34397. + * 256 bit key 14 rounds
  34398. + * => n byte key => 6 + (n/4) rounds
  34399. + */
  34400. + return 6 + ctx->key_length / 4;
  34401. +}
  34402. +
  34403. +asmlinkage void ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
  34404. + u32 *macp, u32 const rk[], u32 rounds);
  34405. +
  34406. +asmlinkage void ce_aes_ccm_encrypt(u8 out[], u8 const in[], u32 cbytes,
  34407. + u32 const rk[], u32 rounds, u8 mac[],
  34408. + u8 ctr[]);
  34409. +
  34410. +asmlinkage void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes,
  34411. + u32 const rk[], u32 rounds, u8 mac[],
  34412. + u8 ctr[]);
  34413. +
  34414. +asmlinkage void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u32 const rk[],
  34415. + u32 rounds);
  34416. +
  34417. +static int ccm_setkey(struct crypto_aead *tfm, const u8 *in_key,
  34418. + unsigned int key_len)
  34419. +{
  34420. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(tfm);
  34421. + int ret;
  34422. +
  34423. + ret = crypto_aes_expand_key(ctx, in_key, key_len);
  34424. + if (!ret)
  34425. + return 0;
  34426. +
  34427. + tfm->base.crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  34428. + return -EINVAL;
  34429. +}
  34430. +
  34431. +static int ccm_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
  34432. +{
  34433. + if ((authsize & 1) || authsize < 4)
  34434. + return -EINVAL;
  34435. + return 0;
  34436. +}
  34437. +
  34438. +static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen)
  34439. +{
  34440. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34441. + __be32 *n = (__be32 *)&maciv[AES_BLOCK_SIZE - 8];
  34442. + u32 l = req->iv[0] + 1;
  34443. +
  34444. + /* verify that CCM dimension 'L' is set correctly in the IV */
  34445. + if (l < 2 || l > 8)
  34446. + return -EINVAL;
  34447. +
  34448. + /* verify that msglen can in fact be represented in L bytes */
  34449. + if (l < 4 && msglen >> (8 * l))
  34450. + return -EOVERFLOW;
  34451. +
  34452. + /*
  34453. + * Even if the CCM spec allows L values of up to 8, the Linux cryptoapi
  34454. + * uses a u32 type to represent msglen so the top 4 bytes are always 0.
  34455. + */
  34456. + n[0] = 0;
  34457. + n[1] = cpu_to_be32(msglen);
  34458. +
  34459. + memcpy(maciv, req->iv, AES_BLOCK_SIZE - l);
  34460. +
  34461. + /*
  34462. + * Meaning of byte 0 according to CCM spec (RFC 3610/NIST 800-38C)
  34463. + * - bits 0..2 : max # of bytes required to represent msglen, minus 1
  34464. + * (already set by caller)
  34465. + * - bits 3..5 : size of auth tag (1 => 4 bytes, 2 => 6 bytes, etc)
  34466. + * - bit 6 : indicates presence of authenticate-only data
  34467. + */
  34468. + maciv[0] |= (crypto_aead_authsize(aead) - 2) << 2;
  34469. + if (req->assoclen)
  34470. + maciv[0] |= 0x40;
  34471. +
  34472. + memset(&req->iv[AES_BLOCK_SIZE - l], 0, l);
  34473. + return 0;
  34474. +}
  34475. +
  34476. +static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
  34477. +{
  34478. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34479. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead);
  34480. + struct __packed { __be16 l; __be32 h; u16 len; } ltag;
  34481. + struct scatter_walk walk;
  34482. + u32 len = req->assoclen;
  34483. + u32 macp = 0;
  34484. +
  34485. + /* prepend the AAD with a length tag */
  34486. + if (len < 0xff00) {
  34487. + ltag.l = cpu_to_be16(len);
  34488. + ltag.len = 2;
  34489. + } else {
  34490. + ltag.l = cpu_to_be16(0xfffe);
  34491. + put_unaligned_be32(len, &ltag.h);
  34492. + ltag.len = 6;
  34493. + }
  34494. +
  34495. + ce_aes_ccm_auth_data(mac, (u8 *)&ltag, ltag.len, &macp, ctx->key_enc,
  34496. + num_rounds(ctx));
  34497. + scatterwalk_start(&walk, req->assoc);
  34498. +
  34499. + do {
  34500. + u32 n = scatterwalk_clamp(&walk, len);
  34501. + u8 *p;
  34502. +
  34503. + if (!n) {
  34504. + scatterwalk_start(&walk, sg_next(walk.sg));
  34505. + n = scatterwalk_clamp(&walk, len);
  34506. + }
  34507. + p = scatterwalk_map(&walk);
  34508. + ce_aes_ccm_auth_data(mac, p, n, &macp, ctx->key_enc,
  34509. + num_rounds(ctx));
  34510. + len -= n;
  34511. +
  34512. + scatterwalk_unmap(p);
  34513. + scatterwalk_advance(&walk, n);
  34514. + scatterwalk_done(&walk, 0, len);
  34515. + } while (len);
  34516. +}
  34517. +
  34518. +static int ccm_encrypt(struct aead_request *req)
  34519. +{
  34520. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34521. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead);
  34522. + struct blkcipher_desc desc = { .info = req->iv };
  34523. + struct blkcipher_walk walk;
  34524. + u8 __aligned(8) mac[AES_BLOCK_SIZE];
  34525. + u8 buf[AES_BLOCK_SIZE];
  34526. + u32 len = req->cryptlen;
  34527. + int err;
  34528. +
  34529. + err = ccm_init_mac(req, mac, len);
  34530. + if (err)
  34531. + return err;
  34532. +
  34533. + kernel_neon_begin_partial(6);
  34534. +
  34535. + if (req->assoclen)
  34536. + ccm_calculate_auth_mac(req, mac);
  34537. +
  34538. + /* preserve the original iv for the final round */
  34539. + memcpy(buf, req->iv, AES_BLOCK_SIZE);
  34540. +
  34541. + blkcipher_walk_init(&walk, req->dst, req->src, len);
  34542. + err = blkcipher_aead_walk_virt_block(&desc, &walk, aead,
  34543. + AES_BLOCK_SIZE);
  34544. +
  34545. + while (walk.nbytes) {
  34546. + u32 tail = walk.nbytes % AES_BLOCK_SIZE;
  34547. +
  34548. + if (walk.nbytes == len)
  34549. + tail = 0;
  34550. +
  34551. + ce_aes_ccm_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  34552. + walk.nbytes - tail, ctx->key_enc,
  34553. + num_rounds(ctx), mac, walk.iv);
  34554. +
  34555. + len -= walk.nbytes - tail;
  34556. + err = blkcipher_walk_done(&desc, &walk, tail);
  34557. + }
  34558. + if (!err)
  34559. + ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
  34560. +
  34561. + kernel_neon_end();
  34562. +
  34563. + if (err)
  34564. + return err;
  34565. +
  34566. + /* copy authtag to end of dst */
  34567. + scatterwalk_map_and_copy(mac, req->dst, req->cryptlen,
  34568. + crypto_aead_authsize(aead), 1);
  34569. +
  34570. + return 0;
  34571. +}
  34572. +
  34573. +static int ccm_decrypt(struct aead_request *req)
  34574. +{
  34575. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34576. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead);
  34577. + unsigned int authsize = crypto_aead_authsize(aead);
  34578. + struct blkcipher_desc desc = { .info = req->iv };
  34579. + struct blkcipher_walk walk;
  34580. + u8 __aligned(8) mac[AES_BLOCK_SIZE];
  34581. + u8 buf[AES_BLOCK_SIZE];
  34582. + u32 len = req->cryptlen - authsize;
  34583. + int err;
  34584. +
  34585. + err = ccm_init_mac(req, mac, len);
  34586. + if (err)
  34587. + return err;
  34588. +
  34589. + kernel_neon_begin_partial(6);
  34590. +
  34591. + if (req->assoclen)
  34592. + ccm_calculate_auth_mac(req, mac);
  34593. +
  34594. + /* preserve the original iv for the final round */
  34595. + memcpy(buf, req->iv, AES_BLOCK_SIZE);
  34596. +
  34597. + blkcipher_walk_init(&walk, req->dst, req->src, len);
  34598. + err = blkcipher_aead_walk_virt_block(&desc, &walk, aead,
  34599. + AES_BLOCK_SIZE);
  34600. +
  34601. + while (walk.nbytes) {
  34602. + u32 tail = walk.nbytes % AES_BLOCK_SIZE;
  34603. +
  34604. + if (walk.nbytes == len)
  34605. + tail = 0;
  34606. +
  34607. + ce_aes_ccm_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  34608. + walk.nbytes - tail, ctx->key_enc,
  34609. + num_rounds(ctx), mac, walk.iv);
  34610. +
  34611. + len -= walk.nbytes - tail;
  34612. + err = blkcipher_walk_done(&desc, &walk, tail);
  34613. + }
  34614. + if (!err)
  34615. + ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
  34616. +
  34617. + kernel_neon_end();
  34618. +
  34619. + if (err)
  34620. + return err;
  34621. +
  34622. + /* compare calculated auth tag with the stored one */
  34623. + scatterwalk_map_and_copy(buf, req->src, req->cryptlen - authsize,
  34624. + authsize, 0);
  34625. +
  34626. + if (memcmp(mac, buf, authsize))
  34627. + return -EBADMSG;
  34628. + return 0;
  34629. +}
  34630. +
  34631. +static struct crypto_alg ccm_aes_alg = {
  34632. + .cra_name = "ccm(aes)",
  34633. + .cra_driver_name = "ccm-aes-ce",
  34634. + .cra_priority = 300,
  34635. + .cra_flags = CRYPTO_ALG_TYPE_AEAD,
  34636. + .cra_blocksize = 1,
  34637. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  34638. + .cra_alignmask = 7,
  34639. + .cra_type = &crypto_aead_type,
  34640. + .cra_module = THIS_MODULE,
  34641. + .cra_aead = {
  34642. + .ivsize = AES_BLOCK_SIZE,
  34643. + .maxauthsize = AES_BLOCK_SIZE,
  34644. + .setkey = ccm_setkey,
  34645. + .setauthsize = ccm_setauthsize,
  34646. + .encrypt = ccm_encrypt,
  34647. + .decrypt = ccm_decrypt,
  34648. + }
  34649. +};
  34650. +
  34651. +static int __init aes_mod_init(void)
  34652. +{
  34653. + if (!(elf_hwcap & HWCAP_AES))
  34654. + return -ENODEV;
  34655. + return crypto_register_alg(&ccm_aes_alg);
  34656. +}
  34657. +
  34658. +static void __exit aes_mod_exit(void)
  34659. +{
  34660. + crypto_unregister_alg(&ccm_aes_alg);
  34661. +}
  34662. +
  34663. +module_init(aes_mod_init);
  34664. +module_exit(aes_mod_exit);
  34665. +
  34666. +MODULE_DESCRIPTION("Synchronous AES in CCM mode using ARMv8 Crypto Extensions");
  34667. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  34668. +MODULE_LICENSE("GPL v2");
  34669. +MODULE_ALIAS("ccm(aes)");
  34670. diff -Nur linux-3.14.15/arch/arm64/crypto/aes-ce-cipher.c linux-linaro-stable-mx6/arch/arm64/crypto/aes-ce-cipher.c
  34671. --- linux-3.14.15/arch/arm64/crypto/aes-ce-cipher.c 1970-01-01 01:00:00.000000000 +0100
  34672. +++ linux-linaro-stable-mx6/arch/arm64/crypto/aes-ce-cipher.c 2014-08-20 19:31:40.540845019 +0200
  34673. @@ -0,0 +1,155 @@
  34674. +/*
  34675. + * aes-ce-cipher.c - core AES cipher using ARMv8 Crypto Extensions
  34676. + *
  34677. + * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  34678. + *
  34679. + * This program is free software; you can redistribute it and/or modify
  34680. + * it under the terms of the GNU General Public License version 2 as
  34681. + * published by the Free Software Foundation.
  34682. + */
  34683. +
  34684. +#include <asm/neon.h>
  34685. +#include <crypto/aes.h>
  34686. +#include <linux/cpufeature.h>
  34687. +#include <linux/crypto.h>
  34688. +#include <linux/module.h>
  34689. +
  34690. +MODULE_DESCRIPTION("Synchronous AES cipher using ARMv8 Crypto Extensions");
  34691. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  34692. +MODULE_LICENSE("GPL v2");
  34693. +
  34694. +struct aes_block {
  34695. + u8 b[AES_BLOCK_SIZE];
  34696. +};
  34697. +
  34698. +static int num_rounds(struct crypto_aes_ctx *ctx)
  34699. +{
  34700. + /*
  34701. + * # of rounds specified by AES:
  34702. + * 128 bit key 10 rounds
  34703. + * 192 bit key 12 rounds
  34704. + * 256 bit key 14 rounds
  34705. + * => n byte key => 6 + (n/4) rounds
  34706. + */
  34707. + return 6 + ctx->key_length / 4;
  34708. +}
  34709. +
  34710. +static void aes_cipher_encrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[])
  34711. +{
  34712. + struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
  34713. + struct aes_block *out = (struct aes_block *)dst;
  34714. + struct aes_block const *in = (struct aes_block *)src;
  34715. + void *dummy0;
  34716. + int dummy1;
  34717. +
  34718. + kernel_neon_begin_partial(4);
  34719. +
  34720. + __asm__(" ld1 {v0.16b}, %[in] ;"
  34721. + " ld1 {v1.2d}, [%[key]], #16 ;"
  34722. + " cmp %w[rounds], #10 ;"
  34723. + " bmi 0f ;"
  34724. + " bne 3f ;"
  34725. + " mov v3.16b, v1.16b ;"
  34726. + " b 2f ;"
  34727. + "0: mov v2.16b, v1.16b ;"
  34728. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34729. + "1: aese v0.16b, v2.16b ;"
  34730. + " aesmc v0.16b, v0.16b ;"
  34731. + "2: ld1 {v1.2d}, [%[key]], #16 ;"
  34732. + " aese v0.16b, v3.16b ;"
  34733. + " aesmc v0.16b, v0.16b ;"
  34734. + "3: ld1 {v2.2d}, [%[key]], #16 ;"
  34735. + " subs %w[rounds], %w[rounds], #3 ;"
  34736. + " aese v0.16b, v1.16b ;"
  34737. + " aesmc v0.16b, v0.16b ;"
  34738. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34739. + " bpl 1b ;"
  34740. + " aese v0.16b, v2.16b ;"
  34741. + " eor v0.16b, v0.16b, v3.16b ;"
  34742. + " st1 {v0.16b}, %[out] ;"
  34743. +
  34744. + : [out] "=Q"(*out),
  34745. + [key] "=r"(dummy0),
  34746. + [rounds] "=r"(dummy1)
  34747. + : [in] "Q"(*in),
  34748. + "1"(ctx->key_enc),
  34749. + "2"(num_rounds(ctx) - 2)
  34750. + : "cc");
  34751. +
  34752. + kernel_neon_end();
  34753. +}
  34754. +
  34755. +static void aes_cipher_decrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[])
  34756. +{
  34757. + struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
  34758. + struct aes_block *out = (struct aes_block *)dst;
  34759. + struct aes_block const *in = (struct aes_block *)src;
  34760. + void *dummy0;
  34761. + int dummy1;
  34762. +
  34763. + kernel_neon_begin_partial(4);
  34764. +
  34765. + __asm__(" ld1 {v0.16b}, %[in] ;"
  34766. + " ld1 {v1.2d}, [%[key]], #16 ;"
  34767. + " cmp %w[rounds], #10 ;"
  34768. + " bmi 0f ;"
  34769. + " bne 3f ;"
  34770. + " mov v3.16b, v1.16b ;"
  34771. + " b 2f ;"
  34772. + "0: mov v2.16b, v1.16b ;"
  34773. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34774. + "1: aesd v0.16b, v2.16b ;"
  34775. + " aesimc v0.16b, v0.16b ;"
  34776. + "2: ld1 {v1.2d}, [%[key]], #16 ;"
  34777. + " aesd v0.16b, v3.16b ;"
  34778. + " aesimc v0.16b, v0.16b ;"
  34779. + "3: ld1 {v2.2d}, [%[key]], #16 ;"
  34780. + " subs %w[rounds], %w[rounds], #3 ;"
  34781. + " aesd v0.16b, v1.16b ;"
  34782. + " aesimc v0.16b, v0.16b ;"
  34783. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34784. + " bpl 1b ;"
  34785. + " aesd v0.16b, v2.16b ;"
  34786. + " eor v0.16b, v0.16b, v3.16b ;"
  34787. + " st1 {v0.16b}, %[out] ;"
  34788. +
  34789. + : [out] "=Q"(*out),
  34790. + [key] "=r"(dummy0),
  34791. + [rounds] "=r"(dummy1)
  34792. + : [in] "Q"(*in),
  34793. + "1"(ctx->key_dec),
  34794. + "2"(num_rounds(ctx) - 2)
  34795. + : "cc");
  34796. +
  34797. + kernel_neon_end();
  34798. +}
  34799. +
  34800. +static struct crypto_alg aes_alg = {
  34801. + .cra_name = "aes",
  34802. + .cra_driver_name = "aes-ce",
  34803. + .cra_priority = 300,
  34804. + .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
  34805. + .cra_blocksize = AES_BLOCK_SIZE,
  34806. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  34807. + .cra_module = THIS_MODULE,
  34808. + .cra_cipher = {
  34809. + .cia_min_keysize = AES_MIN_KEY_SIZE,
  34810. + .cia_max_keysize = AES_MAX_KEY_SIZE,
  34811. + .cia_setkey = crypto_aes_set_key,
  34812. + .cia_encrypt = aes_cipher_encrypt,
  34813. + .cia_decrypt = aes_cipher_decrypt
  34814. + }
  34815. +};
  34816. +
  34817. +static int __init aes_mod_init(void)
  34818. +{
  34819. + return crypto_register_alg(&aes_alg);
  34820. +}
  34821. +
  34822. +static void __exit aes_mod_exit(void)
  34823. +{
  34824. + crypto_unregister_alg(&aes_alg);
  34825. +}
  34826. +
  34827. +module_cpu_feature_match(AES, aes_mod_init);
  34828. +module_exit(aes_mod_exit);
  34829. diff -Nur linux-3.14.15/arch/arm64/crypto/aes-ce.S linux-linaro-stable-mx6/arch/arm64/crypto/aes-ce.S
  34830. --- linux-3.14.15/arch/arm64/crypto/aes-ce.S 1970-01-01 01:00:00.000000000 +0100
  34831. +++ linux-linaro-stable-mx6/arch/arm64/crypto/aes-ce.S 2014-08-20 19:31:40.540845019 +0200
  34832. @@ -0,0 +1,133 @@
  34833. +/*
  34834. + * linux/arch/arm64/crypto/aes-ce.S - AES cipher for ARMv8 with
  34835. + * Crypto Extensions
  34836. + *
  34837. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  34838. + *
  34839. + * This program is free software; you can redistribute it and/or modify
  34840. + * it under the terms of the GNU General Public License version 2 as
  34841. + * published by the Free Software Foundation.
  34842. + */
  34843. +
  34844. +#include <linux/linkage.h>
  34845. +
  34846. +#define AES_ENTRY(func) ENTRY(ce_ ## func)
  34847. +#define AES_ENDPROC(func) ENDPROC(ce_ ## func)
  34848. +
  34849. + .arch armv8-a+crypto
  34850. +
  34851. + /* preload all round keys */
  34852. + .macro load_round_keys, rounds, rk
  34853. + cmp \rounds, #12
  34854. + blo 2222f /* 128 bits */
  34855. + beq 1111f /* 192 bits */
  34856. + ld1 {v17.16b-v18.16b}, [\rk], #32
  34857. +1111: ld1 {v19.16b-v20.16b}, [\rk], #32
  34858. +2222: ld1 {v21.16b-v24.16b}, [\rk], #64
  34859. + ld1 {v25.16b-v28.16b}, [\rk], #64
  34860. + ld1 {v29.16b-v31.16b}, [\rk]
  34861. + .endm
  34862. +
  34863. + /* prepare for encryption with key in rk[] */
  34864. + .macro enc_prepare, rounds, rk, ignore
  34865. + load_round_keys \rounds, \rk
  34866. + .endm
  34867. +
  34868. + /* prepare for encryption (again) but with new key in rk[] */
  34869. + .macro enc_switch_key, rounds, rk, ignore
  34870. + load_round_keys \rounds, \rk
  34871. + .endm
  34872. +
  34873. + /* prepare for decryption with key in rk[] */
  34874. + .macro dec_prepare, rounds, rk, ignore
  34875. + load_round_keys \rounds, \rk
  34876. + .endm
  34877. +
  34878. + .macro do_enc_Nx, de, mc, k, i0, i1, i2, i3
  34879. + aes\de \i0\().16b, \k\().16b
  34880. + .ifnb \i1
  34881. + aes\de \i1\().16b, \k\().16b
  34882. + .ifnb \i3
  34883. + aes\de \i2\().16b, \k\().16b
  34884. + aes\de \i3\().16b, \k\().16b
  34885. + .endif
  34886. + .endif
  34887. + aes\mc \i0\().16b, \i0\().16b
  34888. + .ifnb \i1
  34889. + aes\mc \i1\().16b, \i1\().16b
  34890. + .ifnb \i3
  34891. + aes\mc \i2\().16b, \i2\().16b
  34892. + aes\mc \i3\().16b, \i3\().16b
  34893. + .endif
  34894. + .endif
  34895. + .endm
  34896. +
  34897. + /* up to 4 interleaved encryption rounds with the same round key */
  34898. + .macro round_Nx, enc, k, i0, i1, i2, i3
  34899. + .ifc \enc, e
  34900. + do_enc_Nx e, mc, \k, \i0, \i1, \i2, \i3
  34901. + .else
  34902. + do_enc_Nx d, imc, \k, \i0, \i1, \i2, \i3
  34903. + .endif
  34904. + .endm
  34905. +
  34906. + /* up to 4 interleaved final rounds */
  34907. + .macro fin_round_Nx, de, k, k2, i0, i1, i2, i3
  34908. + aes\de \i0\().16b, \k\().16b
  34909. + .ifnb \i1
  34910. + aes\de \i1\().16b, \k\().16b
  34911. + .ifnb \i3
  34912. + aes\de \i2\().16b, \k\().16b
  34913. + aes\de \i3\().16b, \k\().16b
  34914. + .endif
  34915. + .endif
  34916. + eor \i0\().16b, \i0\().16b, \k2\().16b
  34917. + .ifnb \i1
  34918. + eor \i1\().16b, \i1\().16b, \k2\().16b
  34919. + .ifnb \i3
  34920. + eor \i2\().16b, \i2\().16b, \k2\().16b
  34921. + eor \i3\().16b, \i3\().16b, \k2\().16b
  34922. + .endif
  34923. + .endif
  34924. + .endm
  34925. +
  34926. + /* up to 4 interleaved blocks */
  34927. + .macro do_block_Nx, enc, rounds, i0, i1, i2, i3
  34928. + cmp \rounds, #12
  34929. + blo 2222f /* 128 bits */
  34930. + beq 1111f /* 192 bits */
  34931. + round_Nx \enc, v17, \i0, \i1, \i2, \i3
  34932. + round_Nx \enc, v18, \i0, \i1, \i2, \i3
  34933. +1111: round_Nx \enc, v19, \i0, \i1, \i2, \i3
  34934. + round_Nx \enc, v20, \i0, \i1, \i2, \i3
  34935. +2222: .irp key, v21, v22, v23, v24, v25, v26, v27, v28, v29
  34936. + round_Nx \enc, \key, \i0, \i1, \i2, \i3
  34937. + .endr
  34938. + fin_round_Nx \enc, v30, v31, \i0, \i1, \i2, \i3
  34939. + .endm
  34940. +
  34941. + .macro encrypt_block, in, rounds, t0, t1, t2
  34942. + do_block_Nx e, \rounds, \in
  34943. + .endm
  34944. +
  34945. + .macro encrypt_block2x, i0, i1, rounds, t0, t1, t2
  34946. + do_block_Nx e, \rounds, \i0, \i1
  34947. + .endm
  34948. +
  34949. + .macro encrypt_block4x, i0, i1, i2, i3, rounds, t0, t1, t2
  34950. + do_block_Nx e, \rounds, \i0, \i1, \i2, \i3
  34951. + .endm
  34952. +
  34953. + .macro decrypt_block, in, rounds, t0, t1, t2
  34954. + do_block_Nx d, \rounds, \in
  34955. + .endm
  34956. +
  34957. + .macro decrypt_block2x, i0, i1, rounds, t0, t1, t2
  34958. + do_block_Nx d, \rounds, \i0, \i1
  34959. + .endm
  34960. +
  34961. + .macro decrypt_block4x, i0, i1, i2, i3, rounds, t0, t1, t2
  34962. + do_block_Nx d, \rounds, \i0, \i1, \i2, \i3
  34963. + .endm
  34964. +
  34965. +#include "aes-modes.S"
  34966. diff -Nur linux-3.14.15/arch/arm64/crypto/aes-glue.c linux-linaro-stable-mx6/arch/arm64/crypto/aes-glue.c
  34967. --- linux-3.14.15/arch/arm64/crypto/aes-glue.c 1970-01-01 01:00:00.000000000 +0100
  34968. +++ linux-linaro-stable-mx6/arch/arm64/crypto/aes-glue.c 2014-08-20 19:31:40.540845019 +0200
  34969. @@ -0,0 +1,446 @@
  34970. +/*
  34971. + * linux/arch/arm64/crypto/aes-glue.c - wrapper code for ARMv8 AES
  34972. + *
  34973. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  34974. + *
  34975. + * This program is free software; you can redistribute it and/or modify
  34976. + * it under the terms of the GNU General Public License version 2 as
  34977. + * published by the Free Software Foundation.
  34978. + */
  34979. +
  34980. +#include <asm/neon.h>
  34981. +#include <asm/hwcap.h>
  34982. +#include <crypto/aes.h>
  34983. +#include <crypto/ablk_helper.h>
  34984. +#include <crypto/algapi.h>
  34985. +#include <linux/module.h>
  34986. +#include <linux/cpufeature.h>
  34987. +
  34988. +#ifdef USE_V8_CRYPTO_EXTENSIONS
  34989. +#define MODE "ce"
  34990. +#define PRIO 300
  34991. +#define aes_ecb_encrypt ce_aes_ecb_encrypt
  34992. +#define aes_ecb_decrypt ce_aes_ecb_decrypt
  34993. +#define aes_cbc_encrypt ce_aes_cbc_encrypt
  34994. +#define aes_cbc_decrypt ce_aes_cbc_decrypt
  34995. +#define aes_ctr_encrypt ce_aes_ctr_encrypt
  34996. +#define aes_xts_encrypt ce_aes_xts_encrypt
  34997. +#define aes_xts_decrypt ce_aes_xts_decrypt
  34998. +MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
  34999. +#else
  35000. +#define MODE "neon"
  35001. +#define PRIO 200
  35002. +#define aes_ecb_encrypt neon_aes_ecb_encrypt
  35003. +#define aes_ecb_decrypt neon_aes_ecb_decrypt
  35004. +#define aes_cbc_encrypt neon_aes_cbc_encrypt
  35005. +#define aes_cbc_decrypt neon_aes_cbc_decrypt
  35006. +#define aes_ctr_encrypt neon_aes_ctr_encrypt
  35007. +#define aes_xts_encrypt neon_aes_xts_encrypt
  35008. +#define aes_xts_decrypt neon_aes_xts_decrypt
  35009. +MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 NEON");
  35010. +MODULE_ALIAS("ecb(aes)");
  35011. +MODULE_ALIAS("cbc(aes)");
  35012. +MODULE_ALIAS("ctr(aes)");
  35013. +MODULE_ALIAS("xts(aes)");
  35014. +#endif
  35015. +
  35016. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  35017. +MODULE_LICENSE("GPL v2");
  35018. +
  35019. +/* defined in aes-modes.S */
  35020. +asmlinkage void aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[],
  35021. + int rounds, int blocks, int first);
  35022. +asmlinkage void aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[],
  35023. + int rounds, int blocks, int first);
  35024. +
  35025. +asmlinkage void aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[],
  35026. + int rounds, int blocks, u8 iv[], int first);
  35027. +asmlinkage void aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
  35028. + int rounds, int blocks, u8 iv[], int first);
  35029. +
  35030. +asmlinkage void aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
  35031. + int rounds, int blocks, u8 ctr[], int first);
  35032. +
  35033. +asmlinkage void aes_xts_encrypt(u8 out[], u8 const in[], u8 const rk1[],
  35034. + int rounds, int blocks, u8 const rk2[], u8 iv[],
  35035. + int first);
  35036. +asmlinkage void aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[],
  35037. + int rounds, int blocks, u8 const rk2[], u8 iv[],
  35038. + int first);
  35039. +
  35040. +struct crypto_aes_xts_ctx {
  35041. + struct crypto_aes_ctx key1;
  35042. + struct crypto_aes_ctx __aligned(8) key2;
  35043. +};
  35044. +
  35045. +static int xts_set_key(struct crypto_tfm *tfm, const u8 *in_key,
  35046. + unsigned int key_len)
  35047. +{
  35048. + struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
  35049. + int ret;
  35050. +
  35051. + ret = crypto_aes_expand_key(&ctx->key1, in_key, key_len / 2);
  35052. + if (!ret)
  35053. + ret = crypto_aes_expand_key(&ctx->key2, &in_key[key_len / 2],
  35054. + key_len / 2);
  35055. + if (!ret)
  35056. + return 0;
  35057. +
  35058. + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  35059. + return -EINVAL;
  35060. +}
  35061. +
  35062. +static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35063. + struct scatterlist *src, unsigned int nbytes)
  35064. +{
  35065. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35066. + int err, first, rounds = 6 + ctx->key_length / 4;
  35067. + struct blkcipher_walk walk;
  35068. + unsigned int blocks;
  35069. +
  35070. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35071. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35072. + err = blkcipher_walk_virt(desc, &walk);
  35073. +
  35074. + kernel_neon_begin();
  35075. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35076. + aes_ecb_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35077. + (u8 *)ctx->key_enc, rounds, blocks, first);
  35078. + err = blkcipher_walk_done(desc, &walk, 0);
  35079. + }
  35080. + kernel_neon_end();
  35081. + return err;
  35082. +}
  35083. +
  35084. +static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35085. + struct scatterlist *src, unsigned int nbytes)
  35086. +{
  35087. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35088. + int err, first, rounds = 6 + ctx->key_length / 4;
  35089. + struct blkcipher_walk walk;
  35090. + unsigned int blocks;
  35091. +
  35092. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35093. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35094. + err = blkcipher_walk_virt(desc, &walk);
  35095. +
  35096. + kernel_neon_begin();
  35097. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35098. + aes_ecb_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35099. + (u8 *)ctx->key_dec, rounds, blocks, first);
  35100. + err = blkcipher_walk_done(desc, &walk, 0);
  35101. + }
  35102. + kernel_neon_end();
  35103. + return err;
  35104. +}
  35105. +
  35106. +static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35107. + struct scatterlist *src, unsigned int nbytes)
  35108. +{
  35109. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35110. + int err, first, rounds = 6 + ctx->key_length / 4;
  35111. + struct blkcipher_walk walk;
  35112. + unsigned int blocks;
  35113. +
  35114. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35115. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35116. + err = blkcipher_walk_virt(desc, &walk);
  35117. +
  35118. + kernel_neon_begin();
  35119. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35120. + aes_cbc_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35121. + (u8 *)ctx->key_enc, rounds, blocks, walk.iv,
  35122. + first);
  35123. + err = blkcipher_walk_done(desc, &walk, 0);
  35124. + }
  35125. + kernel_neon_end();
  35126. + return err;
  35127. +}
  35128. +
  35129. +static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35130. + struct scatterlist *src, unsigned int nbytes)
  35131. +{
  35132. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35133. + int err, first, rounds = 6 + ctx->key_length / 4;
  35134. + struct blkcipher_walk walk;
  35135. + unsigned int blocks;
  35136. +
  35137. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35138. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35139. + err = blkcipher_walk_virt(desc, &walk);
  35140. +
  35141. + kernel_neon_begin();
  35142. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35143. + aes_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35144. + (u8 *)ctx->key_dec, rounds, blocks, walk.iv,
  35145. + first);
  35146. + err = blkcipher_walk_done(desc, &walk, 0);
  35147. + }
  35148. + kernel_neon_end();
  35149. + return err;
  35150. +}
  35151. +
  35152. +static int ctr_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35153. + struct scatterlist *src, unsigned int nbytes)
  35154. +{
  35155. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35156. + int err, first, rounds = 6 + ctx->key_length / 4;
  35157. + struct blkcipher_walk walk;
  35158. + int blocks;
  35159. +
  35160. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35161. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35162. + err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE);
  35163. +
  35164. + first = 1;
  35165. + kernel_neon_begin();
  35166. + while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
  35167. + aes_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35168. + (u8 *)ctx->key_enc, rounds, blocks, walk.iv,
  35169. + first);
  35170. + first = 0;
  35171. + nbytes -= blocks * AES_BLOCK_SIZE;
  35172. + if (nbytes && nbytes == walk.nbytes % AES_BLOCK_SIZE)
  35173. + break;
  35174. + err = blkcipher_walk_done(desc, &walk,
  35175. + walk.nbytes % AES_BLOCK_SIZE);
  35176. + }
  35177. + if (nbytes) {
  35178. + u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
  35179. + u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
  35180. + u8 __aligned(8) tail[AES_BLOCK_SIZE];
  35181. +
  35182. + /*
  35183. + * Minimum alignment is 8 bytes, so if nbytes is <= 8, we need
  35184. + * to tell aes_ctr_encrypt() to only read half a block.
  35185. + */
  35186. + blocks = (nbytes <= 8) ? -1 : 1;
  35187. +
  35188. + aes_ctr_encrypt(tail, tsrc, (u8 *)ctx->key_enc, rounds,
  35189. + blocks, walk.iv, first);
  35190. + memcpy(tdst, tail, nbytes);
  35191. + err = blkcipher_walk_done(desc, &walk, 0);
  35192. + }
  35193. + kernel_neon_end();
  35194. +
  35195. + return err;
  35196. +}
  35197. +
  35198. +static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35199. + struct scatterlist *src, unsigned int nbytes)
  35200. +{
  35201. + struct crypto_aes_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35202. + int err, first, rounds = 6 + ctx->key1.key_length / 4;
  35203. + struct blkcipher_walk walk;
  35204. + unsigned int blocks;
  35205. +
  35206. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35207. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35208. + err = blkcipher_walk_virt(desc, &walk);
  35209. +
  35210. + kernel_neon_begin();
  35211. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35212. + aes_xts_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35213. + (u8 *)ctx->key1.key_enc, rounds, blocks,
  35214. + (u8 *)ctx->key2.key_enc, walk.iv, first);
  35215. + err = blkcipher_walk_done(desc, &walk, 0);
  35216. + }
  35217. + kernel_neon_end();
  35218. +
  35219. + return err;
  35220. +}
  35221. +
  35222. +static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35223. + struct scatterlist *src, unsigned int nbytes)
  35224. +{
  35225. + struct crypto_aes_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35226. + int err, first, rounds = 6 + ctx->key1.key_length / 4;
  35227. + struct blkcipher_walk walk;
  35228. + unsigned int blocks;
  35229. +
  35230. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35231. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35232. + err = blkcipher_walk_virt(desc, &walk);
  35233. +
  35234. + kernel_neon_begin();
  35235. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35236. + aes_xts_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35237. + (u8 *)ctx->key1.key_dec, rounds, blocks,
  35238. + (u8 *)ctx->key2.key_enc, walk.iv, first);
  35239. + err = blkcipher_walk_done(desc, &walk, 0);
  35240. + }
  35241. + kernel_neon_end();
  35242. +
  35243. + return err;
  35244. +}
  35245. +
  35246. +static struct crypto_alg aes_algs[] = { {
  35247. + .cra_name = "__ecb-aes-" MODE,
  35248. + .cra_driver_name = "__driver-ecb-aes-" MODE,
  35249. + .cra_priority = 0,
  35250. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35251. + .cra_blocksize = AES_BLOCK_SIZE,
  35252. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  35253. + .cra_alignmask = 7,
  35254. + .cra_type = &crypto_blkcipher_type,
  35255. + .cra_module = THIS_MODULE,
  35256. + .cra_blkcipher = {
  35257. + .min_keysize = AES_MIN_KEY_SIZE,
  35258. + .max_keysize = AES_MAX_KEY_SIZE,
  35259. + .ivsize = AES_BLOCK_SIZE,
  35260. + .setkey = crypto_aes_set_key,
  35261. + .encrypt = ecb_encrypt,
  35262. + .decrypt = ecb_decrypt,
  35263. + },
  35264. +}, {
  35265. + .cra_name = "__cbc-aes-" MODE,
  35266. + .cra_driver_name = "__driver-cbc-aes-" MODE,
  35267. + .cra_priority = 0,
  35268. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35269. + .cra_blocksize = AES_BLOCK_SIZE,
  35270. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  35271. + .cra_alignmask = 7,
  35272. + .cra_type = &crypto_blkcipher_type,
  35273. + .cra_module = THIS_MODULE,
  35274. + .cra_blkcipher = {
  35275. + .min_keysize = AES_MIN_KEY_SIZE,
  35276. + .max_keysize = AES_MAX_KEY_SIZE,
  35277. + .ivsize = AES_BLOCK_SIZE,
  35278. + .setkey = crypto_aes_set_key,
  35279. + .encrypt = cbc_encrypt,
  35280. + .decrypt = cbc_decrypt,
  35281. + },
  35282. +}, {
  35283. + .cra_name = "__ctr-aes-" MODE,
  35284. + .cra_driver_name = "__driver-ctr-aes-" MODE,
  35285. + .cra_priority = 0,
  35286. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35287. + .cra_blocksize = 1,
  35288. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  35289. + .cra_alignmask = 7,
  35290. + .cra_type = &crypto_blkcipher_type,
  35291. + .cra_module = THIS_MODULE,
  35292. + .cra_blkcipher = {
  35293. + .min_keysize = AES_MIN_KEY_SIZE,
  35294. + .max_keysize = AES_MAX_KEY_SIZE,
  35295. + .ivsize = AES_BLOCK_SIZE,
  35296. + .setkey = crypto_aes_set_key,
  35297. + .encrypt = ctr_encrypt,
  35298. + .decrypt = ctr_encrypt,
  35299. + },
  35300. +}, {
  35301. + .cra_name = "__xts-aes-" MODE,
  35302. + .cra_driver_name = "__driver-xts-aes-" MODE,
  35303. + .cra_priority = 0,
  35304. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35305. + .cra_blocksize = AES_BLOCK_SIZE,
  35306. + .cra_ctxsize = sizeof(struct crypto_aes_xts_ctx),
  35307. + .cra_alignmask = 7,
  35308. + .cra_type = &crypto_blkcipher_type,
  35309. + .cra_module = THIS_MODULE,
  35310. + .cra_blkcipher = {
  35311. + .min_keysize = 2 * AES_MIN_KEY_SIZE,
  35312. + .max_keysize = 2 * AES_MAX_KEY_SIZE,
  35313. + .ivsize = AES_BLOCK_SIZE,
  35314. + .setkey = xts_set_key,
  35315. + .encrypt = xts_encrypt,
  35316. + .decrypt = xts_decrypt,
  35317. + },
  35318. +}, {
  35319. + .cra_name = "ecb(aes)",
  35320. + .cra_driver_name = "ecb-aes-" MODE,
  35321. + .cra_priority = PRIO,
  35322. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35323. + .cra_blocksize = AES_BLOCK_SIZE,
  35324. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35325. + .cra_alignmask = 7,
  35326. + .cra_type = &crypto_ablkcipher_type,
  35327. + .cra_module = THIS_MODULE,
  35328. + .cra_init = ablk_init,
  35329. + .cra_exit = ablk_exit,
  35330. + .cra_ablkcipher = {
  35331. + .min_keysize = AES_MIN_KEY_SIZE,
  35332. + .max_keysize = AES_MAX_KEY_SIZE,
  35333. + .ivsize = AES_BLOCK_SIZE,
  35334. + .setkey = ablk_set_key,
  35335. + .encrypt = ablk_encrypt,
  35336. + .decrypt = ablk_decrypt,
  35337. + }
  35338. +}, {
  35339. + .cra_name = "cbc(aes)",
  35340. + .cra_driver_name = "cbc-aes-" MODE,
  35341. + .cra_priority = PRIO,
  35342. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35343. + .cra_blocksize = AES_BLOCK_SIZE,
  35344. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35345. + .cra_alignmask = 7,
  35346. + .cra_type = &crypto_ablkcipher_type,
  35347. + .cra_module = THIS_MODULE,
  35348. + .cra_init = ablk_init,
  35349. + .cra_exit = ablk_exit,
  35350. + .cra_ablkcipher = {
  35351. + .min_keysize = AES_MIN_KEY_SIZE,
  35352. + .max_keysize = AES_MAX_KEY_SIZE,
  35353. + .ivsize = AES_BLOCK_SIZE,
  35354. + .setkey = ablk_set_key,
  35355. + .encrypt = ablk_encrypt,
  35356. + .decrypt = ablk_decrypt,
  35357. + }
  35358. +}, {
  35359. + .cra_name = "ctr(aes)",
  35360. + .cra_driver_name = "ctr-aes-" MODE,
  35361. + .cra_priority = PRIO,
  35362. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35363. + .cra_blocksize = 1,
  35364. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35365. + .cra_alignmask = 7,
  35366. + .cra_type = &crypto_ablkcipher_type,
  35367. + .cra_module = THIS_MODULE,
  35368. + .cra_init = ablk_init,
  35369. + .cra_exit = ablk_exit,
  35370. + .cra_ablkcipher = {
  35371. + .min_keysize = AES_MIN_KEY_SIZE,
  35372. + .max_keysize = AES_MAX_KEY_SIZE,
  35373. + .ivsize = AES_BLOCK_SIZE,
  35374. + .setkey = ablk_set_key,
  35375. + .encrypt = ablk_encrypt,
  35376. + .decrypt = ablk_decrypt,
  35377. + }
  35378. +}, {
  35379. + .cra_name = "xts(aes)",
  35380. + .cra_driver_name = "xts-aes-" MODE,
  35381. + .cra_priority = PRIO,
  35382. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35383. + .cra_blocksize = AES_BLOCK_SIZE,
  35384. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35385. + .cra_alignmask = 7,
  35386. + .cra_type = &crypto_ablkcipher_type,
  35387. + .cra_module = THIS_MODULE,
  35388. + .cra_init = ablk_init,
  35389. + .cra_exit = ablk_exit,
  35390. + .cra_ablkcipher = {
  35391. + .min_keysize = 2 * AES_MIN_KEY_SIZE,
  35392. + .max_keysize = 2 * AES_MAX_KEY_SIZE,
  35393. + .ivsize = AES_BLOCK_SIZE,
  35394. + .setkey = ablk_set_key,
  35395. + .encrypt = ablk_encrypt,
  35396. + .decrypt = ablk_decrypt,
  35397. + }
  35398. +} };
  35399. +
  35400. +static int __init aes_init(void)
  35401. +{
  35402. + return crypto_register_algs(aes_algs, ARRAY_SIZE(aes_algs));
  35403. +}
  35404. +
  35405. +static void __exit aes_exit(void)
  35406. +{
  35407. + crypto_unregister_algs(aes_algs, ARRAY_SIZE(aes_algs));
  35408. +}
  35409. +
  35410. +#ifdef USE_V8_CRYPTO_EXTENSIONS
  35411. +module_cpu_feature_match(AES, aes_init);
  35412. +#else
  35413. +module_init(aes_init);
  35414. +#endif
  35415. +module_exit(aes_exit);
  35416. diff -Nur linux-3.14.15/arch/arm64/crypto/aes-modes.S linux-linaro-stable-mx6/arch/arm64/crypto/aes-modes.S
  35417. --- linux-3.14.15/arch/arm64/crypto/aes-modes.S 1970-01-01 01:00:00.000000000 +0100
  35418. +++ linux-linaro-stable-mx6/arch/arm64/crypto/aes-modes.S 2014-08-20 19:31:40.540845019 +0200
  35419. @@ -0,0 +1,532 @@
  35420. +/*
  35421. + * linux/arch/arm64/crypto/aes-modes.S - chaining mode wrappers for AES
  35422. + *
  35423. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  35424. + *
  35425. + * This program is free software; you can redistribute it and/or modify
  35426. + * it under the terms of the GNU General Public License version 2 as
  35427. + * published by the Free Software Foundation.
  35428. + */
  35429. +
  35430. +/* included by aes-ce.S and aes-neon.S */
  35431. +
  35432. + .text
  35433. + .align 4
  35434. +
  35435. +/*
  35436. + * There are several ways to instantiate this code:
  35437. + * - no interleave, all inline
  35438. + * - 2-way interleave, 2x calls out of line (-DINTERLEAVE=2)
  35439. + * - 2-way interleave, all inline (-DINTERLEAVE=2 -DINTERLEAVE_INLINE)
  35440. + * - 4-way interleave, 4x calls out of line (-DINTERLEAVE=4)
  35441. + * - 4-way interleave, all inline (-DINTERLEAVE=4 -DINTERLEAVE_INLINE)
  35442. + *
  35443. + * Macros imported by this code:
  35444. + * - enc_prepare - setup NEON registers for encryption
  35445. + * - dec_prepare - setup NEON registers for decryption
  35446. + * - enc_switch_key - change to new key after having prepared for encryption
  35447. + * - encrypt_block - encrypt a single block
  35448. + * - decrypt block - decrypt a single block
  35449. + * - encrypt_block2x - encrypt 2 blocks in parallel (if INTERLEAVE == 2)
  35450. + * - decrypt_block2x - decrypt 2 blocks in parallel (if INTERLEAVE == 2)
  35451. + * - encrypt_block4x - encrypt 4 blocks in parallel (if INTERLEAVE == 4)
  35452. + * - decrypt_block4x - decrypt 4 blocks in parallel (if INTERLEAVE == 4)
  35453. + */
  35454. +
  35455. +#if defined(INTERLEAVE) && !defined(INTERLEAVE_INLINE)
  35456. +#define FRAME_PUSH stp x29, x30, [sp,#-16]! ; mov x29, sp
  35457. +#define FRAME_POP ldp x29, x30, [sp],#16
  35458. +
  35459. +#if INTERLEAVE == 2
  35460. +
  35461. +aes_encrypt_block2x:
  35462. + encrypt_block2x v0, v1, w3, x2, x6, w7
  35463. + ret
  35464. +ENDPROC(aes_encrypt_block2x)
  35465. +
  35466. +aes_decrypt_block2x:
  35467. + decrypt_block2x v0, v1, w3, x2, x6, w7
  35468. + ret
  35469. +ENDPROC(aes_decrypt_block2x)
  35470. +
  35471. +#elif INTERLEAVE == 4
  35472. +
  35473. +aes_encrypt_block4x:
  35474. + encrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35475. + ret
  35476. +ENDPROC(aes_encrypt_block4x)
  35477. +
  35478. +aes_decrypt_block4x:
  35479. + decrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35480. + ret
  35481. +ENDPROC(aes_decrypt_block4x)
  35482. +
  35483. +#else
  35484. +#error INTERLEAVE should equal 2 or 4
  35485. +#endif
  35486. +
  35487. + .macro do_encrypt_block2x
  35488. + bl aes_encrypt_block2x
  35489. + .endm
  35490. +
  35491. + .macro do_decrypt_block2x
  35492. + bl aes_decrypt_block2x
  35493. + .endm
  35494. +
  35495. + .macro do_encrypt_block4x
  35496. + bl aes_encrypt_block4x
  35497. + .endm
  35498. +
  35499. + .macro do_decrypt_block4x
  35500. + bl aes_decrypt_block4x
  35501. + .endm
  35502. +
  35503. +#else
  35504. +#define FRAME_PUSH
  35505. +#define FRAME_POP
  35506. +
  35507. + .macro do_encrypt_block2x
  35508. + encrypt_block2x v0, v1, w3, x2, x6, w7
  35509. + .endm
  35510. +
  35511. + .macro do_decrypt_block2x
  35512. + decrypt_block2x v0, v1, w3, x2, x6, w7
  35513. + .endm
  35514. +
  35515. + .macro do_encrypt_block4x
  35516. + encrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35517. + .endm
  35518. +
  35519. + .macro do_decrypt_block4x
  35520. + decrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35521. + .endm
  35522. +
  35523. +#endif
  35524. +
  35525. + /*
  35526. + * aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35527. + * int blocks, int first)
  35528. + * aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35529. + * int blocks, int first)
  35530. + */
  35531. +
  35532. +AES_ENTRY(aes_ecb_encrypt)
  35533. + FRAME_PUSH
  35534. + cbz w5, .LecbencloopNx
  35535. +
  35536. + enc_prepare w3, x2, x5
  35537. +
  35538. +.LecbencloopNx:
  35539. +#if INTERLEAVE >= 2
  35540. + subs w4, w4, #INTERLEAVE
  35541. + bmi .Lecbenc1x
  35542. +#if INTERLEAVE == 2
  35543. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 pt blocks */
  35544. + do_encrypt_block2x
  35545. + st1 {v0.16b-v1.16b}, [x0], #32
  35546. +#else
  35547. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 pt blocks */
  35548. + do_encrypt_block4x
  35549. + st1 {v0.16b-v3.16b}, [x0], #64
  35550. +#endif
  35551. + b .LecbencloopNx
  35552. +.Lecbenc1x:
  35553. + adds w4, w4, #INTERLEAVE
  35554. + beq .Lecbencout
  35555. +#endif
  35556. +.Lecbencloop:
  35557. + ld1 {v0.16b}, [x1], #16 /* get next pt block */
  35558. + encrypt_block v0, w3, x2, x5, w6
  35559. + st1 {v0.16b}, [x0], #16
  35560. + subs w4, w4, #1
  35561. + bne .Lecbencloop
  35562. +.Lecbencout:
  35563. + FRAME_POP
  35564. + ret
  35565. +AES_ENDPROC(aes_ecb_encrypt)
  35566. +
  35567. +
  35568. +AES_ENTRY(aes_ecb_decrypt)
  35569. + FRAME_PUSH
  35570. + cbz w5, .LecbdecloopNx
  35571. +
  35572. + dec_prepare w3, x2, x5
  35573. +
  35574. +.LecbdecloopNx:
  35575. +#if INTERLEAVE >= 2
  35576. + subs w4, w4, #INTERLEAVE
  35577. + bmi .Lecbdec1x
  35578. +#if INTERLEAVE == 2
  35579. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 ct blocks */
  35580. + do_decrypt_block2x
  35581. + st1 {v0.16b-v1.16b}, [x0], #32
  35582. +#else
  35583. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  35584. + do_decrypt_block4x
  35585. + st1 {v0.16b-v3.16b}, [x0], #64
  35586. +#endif
  35587. + b .LecbdecloopNx
  35588. +.Lecbdec1x:
  35589. + adds w4, w4, #INTERLEAVE
  35590. + beq .Lecbdecout
  35591. +#endif
  35592. +.Lecbdecloop:
  35593. + ld1 {v0.16b}, [x1], #16 /* get next ct block */
  35594. + decrypt_block v0, w3, x2, x5, w6
  35595. + st1 {v0.16b}, [x0], #16
  35596. + subs w4, w4, #1
  35597. + bne .Lecbdecloop
  35598. +.Lecbdecout:
  35599. + FRAME_POP
  35600. + ret
  35601. +AES_ENDPROC(aes_ecb_decrypt)
  35602. +
  35603. +
  35604. + /*
  35605. + * aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35606. + * int blocks, u8 iv[], int first)
  35607. + * aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35608. + * int blocks, u8 iv[], int first)
  35609. + */
  35610. +
  35611. +AES_ENTRY(aes_cbc_encrypt)
  35612. + cbz w6, .Lcbcencloop
  35613. +
  35614. + ld1 {v0.16b}, [x5] /* get iv */
  35615. + enc_prepare w3, x2, x5
  35616. +
  35617. +.Lcbcencloop:
  35618. + ld1 {v1.16b}, [x1], #16 /* get next pt block */
  35619. + eor v0.16b, v0.16b, v1.16b /* ..and xor with iv */
  35620. + encrypt_block v0, w3, x2, x5, w6
  35621. + st1 {v0.16b}, [x0], #16
  35622. + subs w4, w4, #1
  35623. + bne .Lcbcencloop
  35624. + ret
  35625. +AES_ENDPROC(aes_cbc_encrypt)
  35626. +
  35627. +
  35628. +AES_ENTRY(aes_cbc_decrypt)
  35629. + FRAME_PUSH
  35630. + cbz w6, .LcbcdecloopNx
  35631. +
  35632. + ld1 {v7.16b}, [x5] /* get iv */
  35633. + dec_prepare w3, x2, x5
  35634. +
  35635. +.LcbcdecloopNx:
  35636. +#if INTERLEAVE >= 2
  35637. + subs w4, w4, #INTERLEAVE
  35638. + bmi .Lcbcdec1x
  35639. +#if INTERLEAVE == 2
  35640. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 ct blocks */
  35641. + mov v2.16b, v0.16b
  35642. + mov v3.16b, v1.16b
  35643. + do_decrypt_block2x
  35644. + eor v0.16b, v0.16b, v7.16b
  35645. + eor v1.16b, v1.16b, v2.16b
  35646. + mov v7.16b, v3.16b
  35647. + st1 {v0.16b-v1.16b}, [x0], #32
  35648. +#else
  35649. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  35650. + mov v4.16b, v0.16b
  35651. + mov v5.16b, v1.16b
  35652. + mov v6.16b, v2.16b
  35653. + do_decrypt_block4x
  35654. + sub x1, x1, #16
  35655. + eor v0.16b, v0.16b, v7.16b
  35656. + eor v1.16b, v1.16b, v4.16b
  35657. + ld1 {v7.16b}, [x1], #16 /* reload 1 ct block */
  35658. + eor v2.16b, v2.16b, v5.16b
  35659. + eor v3.16b, v3.16b, v6.16b
  35660. + st1 {v0.16b-v3.16b}, [x0], #64
  35661. +#endif
  35662. + b .LcbcdecloopNx
  35663. +.Lcbcdec1x:
  35664. + adds w4, w4, #INTERLEAVE
  35665. + beq .Lcbcdecout
  35666. +#endif
  35667. +.Lcbcdecloop:
  35668. + ld1 {v1.16b}, [x1], #16 /* get next ct block */
  35669. + mov v0.16b, v1.16b /* ...and copy to v0 */
  35670. + decrypt_block v0, w3, x2, x5, w6
  35671. + eor v0.16b, v0.16b, v7.16b /* xor with iv => pt */
  35672. + mov v7.16b, v1.16b /* ct is next iv */
  35673. + st1 {v0.16b}, [x0], #16
  35674. + subs w4, w4, #1
  35675. + bne .Lcbcdecloop
  35676. +.Lcbcdecout:
  35677. + FRAME_POP
  35678. + ret
  35679. +AES_ENDPROC(aes_cbc_decrypt)
  35680. +
  35681. +
  35682. + /*
  35683. + * aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35684. + * int blocks, u8 ctr[], int first)
  35685. + */
  35686. +
  35687. +AES_ENTRY(aes_ctr_encrypt)
  35688. + FRAME_PUSH
  35689. + cbnz w6, .Lctrfirst /* 1st time around? */
  35690. + umov x5, v4.d[1] /* keep swabbed ctr in reg */
  35691. + rev x5, x5
  35692. +#if INTERLEAVE >= 2
  35693. + cmn w5, w4 /* 32 bit overflow? */
  35694. + bcs .Lctrinc
  35695. + add x5, x5, #1 /* increment BE ctr */
  35696. + b .LctrincNx
  35697. +#else
  35698. + b .Lctrinc
  35699. +#endif
  35700. +.Lctrfirst:
  35701. + enc_prepare w3, x2, x6
  35702. + ld1 {v4.16b}, [x5]
  35703. + umov x5, v4.d[1] /* keep swabbed ctr in reg */
  35704. + rev x5, x5
  35705. +#if INTERLEAVE >= 2
  35706. + cmn w5, w4 /* 32 bit overflow? */
  35707. + bcs .Lctrloop
  35708. +.LctrloopNx:
  35709. + subs w4, w4, #INTERLEAVE
  35710. + bmi .Lctr1x
  35711. +#if INTERLEAVE == 2
  35712. + mov v0.8b, v4.8b
  35713. + mov v1.8b, v4.8b
  35714. + rev x7, x5
  35715. + add x5, x5, #1
  35716. + ins v0.d[1], x7
  35717. + rev x7, x5
  35718. + add x5, x5, #1
  35719. + ins v1.d[1], x7
  35720. + ld1 {v2.16b-v3.16b}, [x1], #32 /* get 2 input blocks */
  35721. + do_encrypt_block2x
  35722. + eor v0.16b, v0.16b, v2.16b
  35723. + eor v1.16b, v1.16b, v3.16b
  35724. + st1 {v0.16b-v1.16b}, [x0], #32
  35725. +#else
  35726. + ldr q8, =0x30000000200000001 /* addends 1,2,3[,0] */
  35727. + dup v7.4s, w5
  35728. + mov v0.16b, v4.16b
  35729. + add v7.4s, v7.4s, v8.4s
  35730. + mov v1.16b, v4.16b
  35731. + rev32 v8.16b, v7.16b
  35732. + mov v2.16b, v4.16b
  35733. + mov v3.16b, v4.16b
  35734. + mov v1.s[3], v8.s[0]
  35735. + mov v2.s[3], v8.s[1]
  35736. + mov v3.s[3], v8.s[2]
  35737. + ld1 {v5.16b-v7.16b}, [x1], #48 /* get 3 input blocks */
  35738. + do_encrypt_block4x
  35739. + eor v0.16b, v5.16b, v0.16b
  35740. + ld1 {v5.16b}, [x1], #16 /* get 1 input block */
  35741. + eor v1.16b, v6.16b, v1.16b
  35742. + eor v2.16b, v7.16b, v2.16b
  35743. + eor v3.16b, v5.16b, v3.16b
  35744. + st1 {v0.16b-v3.16b}, [x0], #64
  35745. + add x5, x5, #INTERLEAVE
  35746. +#endif
  35747. + cbz w4, .LctroutNx
  35748. +.LctrincNx:
  35749. + rev x7, x5
  35750. + ins v4.d[1], x7
  35751. + b .LctrloopNx
  35752. +.LctroutNx:
  35753. + sub x5, x5, #1
  35754. + rev x7, x5
  35755. + ins v4.d[1], x7
  35756. + b .Lctrout
  35757. +.Lctr1x:
  35758. + adds w4, w4, #INTERLEAVE
  35759. + beq .Lctrout
  35760. +#endif
  35761. +.Lctrloop:
  35762. + mov v0.16b, v4.16b
  35763. + encrypt_block v0, w3, x2, x6, w7
  35764. + subs w4, w4, #1
  35765. + bmi .Lctrhalfblock /* blocks < 0 means 1/2 block */
  35766. + ld1 {v3.16b}, [x1], #16
  35767. + eor v3.16b, v0.16b, v3.16b
  35768. + st1 {v3.16b}, [x0], #16
  35769. + beq .Lctrout
  35770. +.Lctrinc:
  35771. + adds x5, x5, #1 /* increment BE ctr */
  35772. + rev x7, x5
  35773. + ins v4.d[1], x7
  35774. + bcc .Lctrloop /* no overflow? */
  35775. + umov x7, v4.d[0] /* load upper word of ctr */
  35776. + rev x7, x7 /* ... to handle the carry */
  35777. + add x7, x7, #1
  35778. + rev x7, x7
  35779. + ins v4.d[0], x7
  35780. + b .Lctrloop
  35781. +.Lctrhalfblock:
  35782. + ld1 {v3.8b}, [x1]
  35783. + eor v3.8b, v0.8b, v3.8b
  35784. + st1 {v3.8b}, [x0]
  35785. +.Lctrout:
  35786. + FRAME_POP
  35787. + ret
  35788. +AES_ENDPROC(aes_ctr_encrypt)
  35789. + .ltorg
  35790. +
  35791. +
  35792. + /*
  35793. + * aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
  35794. + * int blocks, u8 const rk2[], u8 iv[], int first)
  35795. + * aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
  35796. + * int blocks, u8 const rk2[], u8 iv[], int first)
  35797. + */
  35798. +
  35799. + .macro next_tweak, out, in, const, tmp
  35800. + sshr \tmp\().2d, \in\().2d, #63
  35801. + and \tmp\().16b, \tmp\().16b, \const\().16b
  35802. + add \out\().2d, \in\().2d, \in\().2d
  35803. + ext \tmp\().16b, \tmp\().16b, \tmp\().16b, #8
  35804. + eor \out\().16b, \out\().16b, \tmp\().16b
  35805. + .endm
  35806. +
  35807. +.Lxts_mul_x:
  35808. + .word 1, 0, 0x87, 0
  35809. +
  35810. +AES_ENTRY(aes_xts_encrypt)
  35811. + FRAME_PUSH
  35812. + cbz w7, .LxtsencloopNx
  35813. +
  35814. + ld1 {v4.16b}, [x6]
  35815. + enc_prepare w3, x5, x6
  35816. + encrypt_block v4, w3, x5, x6, w7 /* first tweak */
  35817. + enc_switch_key w3, x2, x6
  35818. + ldr q7, .Lxts_mul_x
  35819. + b .LxtsencNx
  35820. +
  35821. +.LxtsencloopNx:
  35822. + ldr q7, .Lxts_mul_x
  35823. + next_tweak v4, v4, v7, v8
  35824. +.LxtsencNx:
  35825. +#if INTERLEAVE >= 2
  35826. + subs w4, w4, #INTERLEAVE
  35827. + bmi .Lxtsenc1x
  35828. +#if INTERLEAVE == 2
  35829. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 pt blocks */
  35830. + next_tweak v5, v4, v7, v8
  35831. + eor v0.16b, v0.16b, v4.16b
  35832. + eor v1.16b, v1.16b, v5.16b
  35833. + do_encrypt_block2x
  35834. + eor v0.16b, v0.16b, v4.16b
  35835. + eor v1.16b, v1.16b, v5.16b
  35836. + st1 {v0.16b-v1.16b}, [x0], #32
  35837. + cbz w4, .LxtsencoutNx
  35838. + next_tweak v4, v5, v7, v8
  35839. + b .LxtsencNx
  35840. +.LxtsencoutNx:
  35841. + mov v4.16b, v5.16b
  35842. + b .Lxtsencout
  35843. +#else
  35844. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 pt blocks */
  35845. + next_tweak v5, v4, v7, v8
  35846. + eor v0.16b, v0.16b, v4.16b
  35847. + next_tweak v6, v5, v7, v8
  35848. + eor v1.16b, v1.16b, v5.16b
  35849. + eor v2.16b, v2.16b, v6.16b
  35850. + next_tweak v7, v6, v7, v8
  35851. + eor v3.16b, v3.16b, v7.16b
  35852. + do_encrypt_block4x
  35853. + eor v3.16b, v3.16b, v7.16b
  35854. + eor v0.16b, v0.16b, v4.16b
  35855. + eor v1.16b, v1.16b, v5.16b
  35856. + eor v2.16b, v2.16b, v6.16b
  35857. + st1 {v0.16b-v3.16b}, [x0], #64
  35858. + mov v4.16b, v7.16b
  35859. + cbz w4, .Lxtsencout
  35860. + b .LxtsencloopNx
  35861. +#endif
  35862. +.Lxtsenc1x:
  35863. + adds w4, w4, #INTERLEAVE
  35864. + beq .Lxtsencout
  35865. +#endif
  35866. +.Lxtsencloop:
  35867. + ld1 {v1.16b}, [x1], #16
  35868. + eor v0.16b, v1.16b, v4.16b
  35869. + encrypt_block v0, w3, x2, x6, w7
  35870. + eor v0.16b, v0.16b, v4.16b
  35871. + st1 {v0.16b}, [x0], #16
  35872. + subs w4, w4, #1
  35873. + beq .Lxtsencout
  35874. + next_tweak v4, v4, v7, v8
  35875. + b .Lxtsencloop
  35876. +.Lxtsencout:
  35877. + FRAME_POP
  35878. + ret
  35879. +AES_ENDPROC(aes_xts_encrypt)
  35880. +
  35881. +
  35882. +AES_ENTRY(aes_xts_decrypt)
  35883. + FRAME_PUSH
  35884. + cbz w7, .LxtsdecloopNx
  35885. +
  35886. + ld1 {v4.16b}, [x6]
  35887. + enc_prepare w3, x5, x6
  35888. + encrypt_block v4, w3, x5, x6, w7 /* first tweak */
  35889. + dec_prepare w3, x2, x6
  35890. + ldr q7, .Lxts_mul_x
  35891. + b .LxtsdecNx
  35892. +
  35893. +.LxtsdecloopNx:
  35894. + ldr q7, .Lxts_mul_x
  35895. + next_tweak v4, v4, v7, v8
  35896. +.LxtsdecNx:
  35897. +#if INTERLEAVE >= 2
  35898. + subs w4, w4, #INTERLEAVE
  35899. + bmi .Lxtsdec1x
  35900. +#if INTERLEAVE == 2
  35901. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 ct blocks */
  35902. + next_tweak v5, v4, v7, v8
  35903. + eor v0.16b, v0.16b, v4.16b
  35904. + eor v1.16b, v1.16b, v5.16b
  35905. + do_decrypt_block2x
  35906. + eor v0.16b, v0.16b, v4.16b
  35907. + eor v1.16b, v1.16b, v5.16b
  35908. + st1 {v0.16b-v1.16b}, [x0], #32
  35909. + cbz w4, .LxtsdecoutNx
  35910. + next_tweak v4, v5, v7, v8
  35911. + b .LxtsdecNx
  35912. +.LxtsdecoutNx:
  35913. + mov v4.16b, v5.16b
  35914. + b .Lxtsdecout
  35915. +#else
  35916. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  35917. + next_tweak v5, v4, v7, v8
  35918. + eor v0.16b, v0.16b, v4.16b
  35919. + next_tweak v6, v5, v7, v8
  35920. + eor v1.16b, v1.16b, v5.16b
  35921. + eor v2.16b, v2.16b, v6.16b
  35922. + next_tweak v7, v6, v7, v8
  35923. + eor v3.16b, v3.16b, v7.16b
  35924. + do_decrypt_block4x
  35925. + eor v3.16b, v3.16b, v7.16b
  35926. + eor v0.16b, v0.16b, v4.16b
  35927. + eor v1.16b, v1.16b, v5.16b
  35928. + eor v2.16b, v2.16b, v6.16b
  35929. + st1 {v0.16b-v3.16b}, [x0], #64
  35930. + mov v4.16b, v7.16b
  35931. + cbz w4, .Lxtsdecout
  35932. + b .LxtsdecloopNx
  35933. +#endif
  35934. +.Lxtsdec1x:
  35935. + adds w4, w4, #INTERLEAVE
  35936. + beq .Lxtsdecout
  35937. +#endif
  35938. +.Lxtsdecloop:
  35939. + ld1 {v1.16b}, [x1], #16
  35940. + eor v0.16b, v1.16b, v4.16b
  35941. + decrypt_block v0, w3, x2, x6, w7
  35942. + eor v0.16b, v0.16b, v4.16b
  35943. + st1 {v0.16b}, [x0], #16
  35944. + subs w4, w4, #1
  35945. + beq .Lxtsdecout
  35946. + next_tweak v4, v4, v7, v8
  35947. + b .Lxtsdecloop
  35948. +.Lxtsdecout:
  35949. + FRAME_POP
  35950. + ret
  35951. +AES_ENDPROC(aes_xts_decrypt)
  35952. diff -Nur linux-3.14.15/arch/arm64/crypto/aes-neon.S linux-linaro-stable-mx6/arch/arm64/crypto/aes-neon.S
  35953. --- linux-3.14.15/arch/arm64/crypto/aes-neon.S 1970-01-01 01:00:00.000000000 +0100
  35954. +++ linux-linaro-stable-mx6/arch/arm64/crypto/aes-neon.S 2014-08-20 19:31:40.544845035 +0200
  35955. @@ -0,0 +1,382 @@
  35956. +/*
  35957. + * linux/arch/arm64/crypto/aes-neon.S - AES cipher for ARMv8 NEON
  35958. + *
  35959. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  35960. + *
  35961. + * This program is free software; you can redistribute it and/or modify
  35962. + * it under the terms of the GNU General Public License version 2 as
  35963. + * published by the Free Software Foundation.
  35964. + */
  35965. +
  35966. +#include <linux/linkage.h>
  35967. +
  35968. +#define AES_ENTRY(func) ENTRY(neon_ ## func)
  35969. +#define AES_ENDPROC(func) ENDPROC(neon_ ## func)
  35970. +
  35971. + /* multiply by polynomial 'x' in GF(2^8) */
  35972. + .macro mul_by_x, out, in, temp, const
  35973. + sshr \temp, \in, #7
  35974. + add \out, \in, \in
  35975. + and \temp, \temp, \const
  35976. + eor \out, \out, \temp
  35977. + .endm
  35978. +
  35979. + /* preload the entire Sbox */
  35980. + .macro prepare, sbox, shiftrows, temp
  35981. + adr \temp, \sbox
  35982. + movi v12.16b, #0x40
  35983. + ldr q13, \shiftrows
  35984. + movi v14.16b, #0x1b
  35985. + ld1 {v16.16b-v19.16b}, [\temp], #64
  35986. + ld1 {v20.16b-v23.16b}, [\temp], #64
  35987. + ld1 {v24.16b-v27.16b}, [\temp], #64
  35988. + ld1 {v28.16b-v31.16b}, [\temp]
  35989. + .endm
  35990. +
  35991. + /* do preload for encryption */
  35992. + .macro enc_prepare, ignore0, ignore1, temp
  35993. + prepare .LForward_Sbox, .LForward_ShiftRows, \temp
  35994. + .endm
  35995. +
  35996. + .macro enc_switch_key, ignore0, ignore1, temp
  35997. + /* do nothing */
  35998. + .endm
  35999. +
  36000. + /* do preload for decryption */
  36001. + .macro dec_prepare, ignore0, ignore1, temp
  36002. + prepare .LReverse_Sbox, .LReverse_ShiftRows, \temp
  36003. + .endm
  36004. +
  36005. + /* apply SubBytes transformation using the the preloaded Sbox */
  36006. + .macro sub_bytes, in
  36007. + sub v9.16b, \in\().16b, v12.16b
  36008. + tbl \in\().16b, {v16.16b-v19.16b}, \in\().16b
  36009. + sub v10.16b, v9.16b, v12.16b
  36010. + tbx \in\().16b, {v20.16b-v23.16b}, v9.16b
  36011. + sub v11.16b, v10.16b, v12.16b
  36012. + tbx \in\().16b, {v24.16b-v27.16b}, v10.16b
  36013. + tbx \in\().16b, {v28.16b-v31.16b}, v11.16b
  36014. + .endm
  36015. +
  36016. + /* apply MixColumns transformation */
  36017. + .macro mix_columns, in
  36018. + mul_by_x v10.16b, \in\().16b, v9.16b, v14.16b
  36019. + rev32 v8.8h, \in\().8h
  36020. + eor \in\().16b, v10.16b, \in\().16b
  36021. + shl v9.4s, v8.4s, #24
  36022. + shl v11.4s, \in\().4s, #24
  36023. + sri v9.4s, v8.4s, #8
  36024. + sri v11.4s, \in\().4s, #8
  36025. + eor v9.16b, v9.16b, v8.16b
  36026. + eor v10.16b, v10.16b, v9.16b
  36027. + eor \in\().16b, v10.16b, v11.16b
  36028. + .endm
  36029. +
  36030. + /* Inverse MixColumns: pre-multiply by { 5, 0, 4, 0 } */
  36031. + .macro inv_mix_columns, in
  36032. + mul_by_x v11.16b, \in\().16b, v10.16b, v14.16b
  36033. + mul_by_x v11.16b, v11.16b, v10.16b, v14.16b
  36034. + eor \in\().16b, \in\().16b, v11.16b
  36035. + rev32 v11.8h, v11.8h
  36036. + eor \in\().16b, \in\().16b, v11.16b
  36037. + mix_columns \in
  36038. + .endm
  36039. +
  36040. + .macro do_block, enc, in, rounds, rk, rkp, i
  36041. + ld1 {v15.16b}, [\rk]
  36042. + add \rkp, \rk, #16
  36043. + mov \i, \rounds
  36044. +1111: eor \in\().16b, \in\().16b, v15.16b /* ^round key */
  36045. + tbl \in\().16b, {\in\().16b}, v13.16b /* ShiftRows */
  36046. + sub_bytes \in
  36047. + ld1 {v15.16b}, [\rkp], #16
  36048. + subs \i, \i, #1
  36049. + beq 2222f
  36050. + .if \enc == 1
  36051. + mix_columns \in
  36052. + .else
  36053. + inv_mix_columns \in
  36054. + .endif
  36055. + b 1111b
  36056. +2222: eor \in\().16b, \in\().16b, v15.16b /* ^round key */
  36057. + .endm
  36058. +
  36059. + .macro encrypt_block, in, rounds, rk, rkp, i
  36060. + do_block 1, \in, \rounds, \rk, \rkp, \i
  36061. + .endm
  36062. +
  36063. + .macro decrypt_block, in, rounds, rk, rkp, i
  36064. + do_block 0, \in, \rounds, \rk, \rkp, \i
  36065. + .endm
  36066. +
  36067. + /*
  36068. + * Interleaved versions: functionally equivalent to the
  36069. + * ones above, but applied to 2 or 4 AES states in parallel.
  36070. + */
  36071. +
  36072. + .macro sub_bytes_2x, in0, in1
  36073. + sub v8.16b, \in0\().16b, v12.16b
  36074. + sub v9.16b, \in1\().16b, v12.16b
  36075. + tbl \in0\().16b, {v16.16b-v19.16b}, \in0\().16b
  36076. + tbl \in1\().16b, {v16.16b-v19.16b}, \in1\().16b
  36077. + sub v10.16b, v8.16b, v12.16b
  36078. + sub v11.16b, v9.16b, v12.16b
  36079. + tbx \in0\().16b, {v20.16b-v23.16b}, v8.16b
  36080. + tbx \in1\().16b, {v20.16b-v23.16b}, v9.16b
  36081. + sub v8.16b, v10.16b, v12.16b
  36082. + sub v9.16b, v11.16b, v12.16b
  36083. + tbx \in0\().16b, {v24.16b-v27.16b}, v10.16b
  36084. + tbx \in1\().16b, {v24.16b-v27.16b}, v11.16b
  36085. + tbx \in0\().16b, {v28.16b-v31.16b}, v8.16b
  36086. + tbx \in1\().16b, {v28.16b-v31.16b}, v9.16b
  36087. + .endm
  36088. +
  36089. + .macro sub_bytes_4x, in0, in1, in2, in3
  36090. + sub v8.16b, \in0\().16b, v12.16b
  36091. + tbl \in0\().16b, {v16.16b-v19.16b}, \in0\().16b
  36092. + sub v9.16b, \in1\().16b, v12.16b
  36093. + tbl \in1\().16b, {v16.16b-v19.16b}, \in1\().16b
  36094. + sub v10.16b, \in2\().16b, v12.16b
  36095. + tbl \in2\().16b, {v16.16b-v19.16b}, \in2\().16b
  36096. + sub v11.16b, \in3\().16b, v12.16b
  36097. + tbl \in3\().16b, {v16.16b-v19.16b}, \in3\().16b
  36098. + tbx \in0\().16b, {v20.16b-v23.16b}, v8.16b
  36099. + tbx \in1\().16b, {v20.16b-v23.16b}, v9.16b
  36100. + sub v8.16b, v8.16b, v12.16b
  36101. + tbx \in2\().16b, {v20.16b-v23.16b}, v10.16b
  36102. + sub v9.16b, v9.16b, v12.16b
  36103. + tbx \in3\().16b, {v20.16b-v23.16b}, v11.16b
  36104. + sub v10.16b, v10.16b, v12.16b
  36105. + tbx \in0\().16b, {v24.16b-v27.16b}, v8.16b
  36106. + sub v11.16b, v11.16b, v12.16b
  36107. + tbx \in1\().16b, {v24.16b-v27.16b}, v9.16b
  36108. + sub v8.16b, v8.16b, v12.16b
  36109. + tbx \in2\().16b, {v24.16b-v27.16b}, v10.16b
  36110. + sub v9.16b, v9.16b, v12.16b
  36111. + tbx \in3\().16b, {v24.16b-v27.16b}, v11.16b
  36112. + sub v10.16b, v10.16b, v12.16b
  36113. + tbx \in0\().16b, {v28.16b-v31.16b}, v8.16b
  36114. + sub v11.16b, v11.16b, v12.16b
  36115. + tbx \in1\().16b, {v28.16b-v31.16b}, v9.16b
  36116. + tbx \in2\().16b, {v28.16b-v31.16b}, v10.16b
  36117. + tbx \in3\().16b, {v28.16b-v31.16b}, v11.16b
  36118. + .endm
  36119. +
  36120. + .macro mul_by_x_2x, out0, out1, in0, in1, tmp0, tmp1, const
  36121. + sshr \tmp0\().16b, \in0\().16b, #7
  36122. + add \out0\().16b, \in0\().16b, \in0\().16b
  36123. + sshr \tmp1\().16b, \in1\().16b, #7
  36124. + and \tmp0\().16b, \tmp0\().16b, \const\().16b
  36125. + add \out1\().16b, \in1\().16b, \in1\().16b
  36126. + and \tmp1\().16b, \tmp1\().16b, \const\().16b
  36127. + eor \out0\().16b, \out0\().16b, \tmp0\().16b
  36128. + eor \out1\().16b, \out1\().16b, \tmp1\().16b
  36129. + .endm
  36130. +
  36131. + .macro mix_columns_2x, in0, in1
  36132. + mul_by_x_2x v8, v9, \in0, \in1, v10, v11, v14
  36133. + rev32 v10.8h, \in0\().8h
  36134. + rev32 v11.8h, \in1\().8h
  36135. + eor \in0\().16b, v8.16b, \in0\().16b
  36136. + eor \in1\().16b, v9.16b, \in1\().16b
  36137. + shl v12.4s, v10.4s, #24
  36138. + shl v13.4s, v11.4s, #24
  36139. + eor v8.16b, v8.16b, v10.16b
  36140. + sri v12.4s, v10.4s, #8
  36141. + shl v10.4s, \in0\().4s, #24
  36142. + eor v9.16b, v9.16b, v11.16b
  36143. + sri v13.4s, v11.4s, #8
  36144. + shl v11.4s, \in1\().4s, #24
  36145. + sri v10.4s, \in0\().4s, #8
  36146. + eor \in0\().16b, v8.16b, v12.16b
  36147. + sri v11.4s, \in1\().4s, #8
  36148. + eor \in1\().16b, v9.16b, v13.16b
  36149. + eor \in0\().16b, v10.16b, \in0\().16b
  36150. + eor \in1\().16b, v11.16b, \in1\().16b
  36151. + .endm
  36152. +
  36153. + .macro inv_mix_cols_2x, in0, in1
  36154. + mul_by_x_2x v8, v9, \in0, \in1, v10, v11, v14
  36155. + mul_by_x_2x v8, v9, v8, v9, v10, v11, v14
  36156. + eor \in0\().16b, \in0\().16b, v8.16b
  36157. + eor \in1\().16b, \in1\().16b, v9.16b
  36158. + rev32 v8.8h, v8.8h
  36159. + rev32 v9.8h, v9.8h
  36160. + eor \in0\().16b, \in0\().16b, v8.16b
  36161. + eor \in1\().16b, \in1\().16b, v9.16b
  36162. + mix_columns_2x \in0, \in1
  36163. + .endm
  36164. +
  36165. + .macro inv_mix_cols_4x, in0, in1, in2, in3
  36166. + mul_by_x_2x v8, v9, \in0, \in1, v10, v11, v14
  36167. + mul_by_x_2x v10, v11, \in2, \in3, v12, v13, v14
  36168. + mul_by_x_2x v8, v9, v8, v9, v12, v13, v14
  36169. + mul_by_x_2x v10, v11, v10, v11, v12, v13, v14
  36170. + eor \in0\().16b, \in0\().16b, v8.16b
  36171. + eor \in1\().16b, \in1\().16b, v9.16b
  36172. + eor \in2\().16b, \in2\().16b, v10.16b
  36173. + eor \in3\().16b, \in3\().16b, v11.16b
  36174. + rev32 v8.8h, v8.8h
  36175. + rev32 v9.8h, v9.8h
  36176. + rev32 v10.8h, v10.8h
  36177. + rev32 v11.8h, v11.8h
  36178. + eor \in0\().16b, \in0\().16b, v8.16b
  36179. + eor \in1\().16b, \in1\().16b, v9.16b
  36180. + eor \in2\().16b, \in2\().16b, v10.16b
  36181. + eor \in3\().16b, \in3\().16b, v11.16b
  36182. + mix_columns_2x \in0, \in1
  36183. + mix_columns_2x \in2, \in3
  36184. + .endm
  36185. +
  36186. + .macro do_block_2x, enc, in0, in1 rounds, rk, rkp, i
  36187. + ld1 {v15.16b}, [\rk]
  36188. + add \rkp, \rk, #16
  36189. + mov \i, \rounds
  36190. +1111: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36191. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36192. + sub_bytes_2x \in0, \in1
  36193. + tbl \in0\().16b, {\in0\().16b}, v13.16b /* ShiftRows */
  36194. + tbl \in1\().16b, {\in1\().16b}, v13.16b /* ShiftRows */
  36195. + ld1 {v15.16b}, [\rkp], #16
  36196. + subs \i, \i, #1
  36197. + beq 2222f
  36198. + .if \enc == 1
  36199. + mix_columns_2x \in0, \in1
  36200. + ldr q13, .LForward_ShiftRows
  36201. + .else
  36202. + inv_mix_cols_2x \in0, \in1
  36203. + ldr q13, .LReverse_ShiftRows
  36204. + .endif
  36205. + movi v12.16b, #0x40
  36206. + b 1111b
  36207. +2222: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36208. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36209. + .endm
  36210. +
  36211. + .macro do_block_4x, enc, in0, in1, in2, in3, rounds, rk, rkp, i
  36212. + ld1 {v15.16b}, [\rk]
  36213. + add \rkp, \rk, #16
  36214. + mov \i, \rounds
  36215. +1111: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36216. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36217. + eor \in2\().16b, \in2\().16b, v15.16b /* ^round key */
  36218. + eor \in3\().16b, \in3\().16b, v15.16b /* ^round key */
  36219. + sub_bytes_4x \in0, \in1, \in2, \in3
  36220. + tbl \in0\().16b, {\in0\().16b}, v13.16b /* ShiftRows */
  36221. + tbl \in1\().16b, {\in1\().16b}, v13.16b /* ShiftRows */
  36222. + tbl \in2\().16b, {\in2\().16b}, v13.16b /* ShiftRows */
  36223. + tbl \in3\().16b, {\in3\().16b}, v13.16b /* ShiftRows */
  36224. + ld1 {v15.16b}, [\rkp], #16
  36225. + subs \i, \i, #1
  36226. + beq 2222f
  36227. + .if \enc == 1
  36228. + mix_columns_2x \in0, \in1
  36229. + mix_columns_2x \in2, \in3
  36230. + ldr q13, .LForward_ShiftRows
  36231. + .else
  36232. + inv_mix_cols_4x \in0, \in1, \in2, \in3
  36233. + ldr q13, .LReverse_ShiftRows
  36234. + .endif
  36235. + movi v12.16b, #0x40
  36236. + b 1111b
  36237. +2222: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36238. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36239. + eor \in2\().16b, \in2\().16b, v15.16b /* ^round key */
  36240. + eor \in3\().16b, \in3\().16b, v15.16b /* ^round key */
  36241. + .endm
  36242. +
  36243. + .macro encrypt_block2x, in0, in1, rounds, rk, rkp, i
  36244. + do_block_2x 1, \in0, \in1, \rounds, \rk, \rkp, \i
  36245. + .endm
  36246. +
  36247. + .macro decrypt_block2x, in0, in1, rounds, rk, rkp, i
  36248. + do_block_2x 0, \in0, \in1, \rounds, \rk, \rkp, \i
  36249. + .endm
  36250. +
  36251. + .macro encrypt_block4x, in0, in1, in2, in3, rounds, rk, rkp, i
  36252. + do_block_4x 1, \in0, \in1, \in2, \in3, \rounds, \rk, \rkp, \i
  36253. + .endm
  36254. +
  36255. + .macro decrypt_block4x, in0, in1, in2, in3, rounds, rk, rkp, i
  36256. + do_block_4x 0, \in0, \in1, \in2, \in3, \rounds, \rk, \rkp, \i
  36257. + .endm
  36258. +
  36259. +#include "aes-modes.S"
  36260. +
  36261. + .text
  36262. + .align 4
  36263. +.LForward_ShiftRows:
  36264. + .byte 0x0, 0x5, 0xa, 0xf, 0x4, 0x9, 0xe, 0x3
  36265. + .byte 0x8, 0xd, 0x2, 0x7, 0xc, 0x1, 0x6, 0xb
  36266. +
  36267. +.LReverse_ShiftRows:
  36268. + .byte 0x0, 0xd, 0xa, 0x7, 0x4, 0x1, 0xe, 0xb
  36269. + .byte 0x8, 0x5, 0x2, 0xf, 0xc, 0x9, 0x6, 0x3
  36270. +
  36271. +.LForward_Sbox:
  36272. + .byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
  36273. + .byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
  36274. + .byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
  36275. + .byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
  36276. + .byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
  36277. + .byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
  36278. + .byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
  36279. + .byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
  36280. + .byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
  36281. + .byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
  36282. + .byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
  36283. + .byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
  36284. + .byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
  36285. + .byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
  36286. + .byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
  36287. + .byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
  36288. + .byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
  36289. + .byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
  36290. + .byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
  36291. + .byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
  36292. + .byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
  36293. + .byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
  36294. + .byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
  36295. + .byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
  36296. + .byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
  36297. + .byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
  36298. + .byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
  36299. + .byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
  36300. + .byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
  36301. + .byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
  36302. + .byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
  36303. + .byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
  36304. +
  36305. +.LReverse_Sbox:
  36306. + .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
  36307. + .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
  36308. + .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
  36309. + .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
  36310. + .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
  36311. + .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
  36312. + .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
  36313. + .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
  36314. + .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
  36315. + .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
  36316. + .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
  36317. + .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
  36318. + .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
  36319. + .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
  36320. + .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
  36321. + .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
  36322. + .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
  36323. + .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
  36324. + .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
  36325. + .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
  36326. + .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
  36327. + .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
  36328. + .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
  36329. + .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
  36330. + .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
  36331. + .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
  36332. + .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
  36333. + .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
  36334. + .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
  36335. + .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
  36336. + .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
  36337. + .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
  36338. diff -Nur linux-3.14.15/arch/arm64/crypto/ghash-ce-core.S linux-linaro-stable-mx6/arch/arm64/crypto/ghash-ce-core.S
  36339. --- linux-3.14.15/arch/arm64/crypto/ghash-ce-core.S 1970-01-01 01:00:00.000000000 +0100
  36340. +++ linux-linaro-stable-mx6/arch/arm64/crypto/ghash-ce-core.S 2014-08-20 19:31:40.544845035 +0200
  36341. @@ -0,0 +1,79 @@
  36342. +/*
  36343. + * Accelerated GHASH implementation with ARMv8 PMULL instructions.
  36344. + *
  36345. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  36346. + *
  36347. + * This program is free software; you can redistribute it and/or modify it
  36348. + * under the terms of the GNU General Public License version 2 as published
  36349. + * by the Free Software Foundation.
  36350. + */
  36351. +
  36352. +#include <linux/linkage.h>
  36353. +#include <asm/assembler.h>
  36354. +
  36355. + SHASH .req v0
  36356. + SHASH2 .req v1
  36357. + T1 .req v2
  36358. + T2 .req v3
  36359. + MASK .req v4
  36360. + XL .req v5
  36361. + XM .req v6
  36362. + XH .req v7
  36363. + IN1 .req v7
  36364. +
  36365. + .text
  36366. + .arch armv8-a+crypto
  36367. +
  36368. + /*
  36369. + * void pmull_ghash_update(int blocks, u64 dg[], const char *src,
  36370. + * struct ghash_key const *k, const char *head)
  36371. + */
  36372. +ENTRY(pmull_ghash_update)
  36373. + ld1 {SHASH.16b}, [x3]
  36374. + ld1 {XL.16b}, [x1]
  36375. + movi MASK.16b, #0xe1
  36376. + ext SHASH2.16b, SHASH.16b, SHASH.16b, #8
  36377. + shl MASK.2d, MASK.2d, #57
  36378. + eor SHASH2.16b, SHASH2.16b, SHASH.16b
  36379. +
  36380. + /* do the head block first, if supplied */
  36381. + cbz x4, 0f
  36382. + ld1 {T1.2d}, [x4]
  36383. + b 1f
  36384. +
  36385. +0: ld1 {T1.2d}, [x2], #16
  36386. + sub w0, w0, #1
  36387. +
  36388. +1: /* multiply XL by SHASH in GF(2^128) */
  36389. +CPU_LE( rev64 T1.16b, T1.16b )
  36390. +
  36391. + ext T2.16b, XL.16b, XL.16b, #8
  36392. + ext IN1.16b, T1.16b, T1.16b, #8
  36393. + eor T1.16b, T1.16b, T2.16b
  36394. + eor XL.16b, XL.16b, IN1.16b
  36395. +
  36396. + pmull2 XH.1q, SHASH.2d, XL.2d // a1 * b1
  36397. + eor T1.16b, T1.16b, XL.16b
  36398. + pmull XL.1q, SHASH.1d, XL.1d // a0 * b0
  36399. + pmull XM.1q, SHASH2.1d, T1.1d // (a1 + a0)(b1 + b0)
  36400. +
  36401. + ext T1.16b, XL.16b, XH.16b, #8
  36402. + eor T2.16b, XL.16b, XH.16b
  36403. + eor XM.16b, XM.16b, T1.16b
  36404. + eor XM.16b, XM.16b, T2.16b
  36405. + pmull T2.1q, XL.1d, MASK.1d
  36406. +
  36407. + mov XH.d[0], XM.d[1]
  36408. + mov XM.d[1], XL.d[0]
  36409. +
  36410. + eor XL.16b, XM.16b, T2.16b
  36411. + ext T2.16b, XL.16b, XL.16b, #8
  36412. + pmull XL.1q, XL.1d, MASK.1d
  36413. + eor T2.16b, T2.16b, XH.16b
  36414. + eor XL.16b, XL.16b, T2.16b
  36415. +
  36416. + cbnz w0, 0b
  36417. +
  36418. + st1 {XL.16b}, [x1]
  36419. + ret
  36420. +ENDPROC(pmull_ghash_update)
  36421. diff -Nur linux-3.14.15/arch/arm64/crypto/ghash-ce-glue.c linux-linaro-stable-mx6/arch/arm64/crypto/ghash-ce-glue.c
  36422. --- linux-3.14.15/arch/arm64/crypto/ghash-ce-glue.c 1970-01-01 01:00:00.000000000 +0100
  36423. +++ linux-linaro-stable-mx6/arch/arm64/crypto/ghash-ce-glue.c 2014-08-20 19:31:40.544845035 +0200
  36424. @@ -0,0 +1,156 @@
  36425. +/*
  36426. + * Accelerated GHASH implementation with ARMv8 PMULL instructions.
  36427. + *
  36428. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  36429. + *
  36430. + * This program is free software; you can redistribute it and/or modify it
  36431. + * under the terms of the GNU General Public License version 2 as published
  36432. + * by the Free Software Foundation.
  36433. + */
  36434. +
  36435. +#include <asm/neon.h>
  36436. +#include <asm/unaligned.h>
  36437. +#include <crypto/internal/hash.h>
  36438. +#include <linux/cpufeature.h>
  36439. +#include <linux/crypto.h>
  36440. +#include <linux/module.h>
  36441. +
  36442. +MODULE_DESCRIPTION("GHASH secure hash using ARMv8 Crypto Extensions");
  36443. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  36444. +MODULE_LICENSE("GPL v2");
  36445. +
  36446. +#define GHASH_BLOCK_SIZE 16
  36447. +#define GHASH_DIGEST_SIZE 16
  36448. +
  36449. +struct ghash_key {
  36450. + u64 a;
  36451. + u64 b;
  36452. +};
  36453. +
  36454. +struct ghash_desc_ctx {
  36455. + u64 digest[GHASH_DIGEST_SIZE/sizeof(u64)];
  36456. + u8 buf[GHASH_BLOCK_SIZE];
  36457. + u32 count;
  36458. +};
  36459. +
  36460. +asmlinkage void pmull_ghash_update(int blocks, u64 dg[], const char *src,
  36461. + struct ghash_key const *k, const char *head);
  36462. +
  36463. +static int ghash_init(struct shash_desc *desc)
  36464. +{
  36465. + struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
  36466. +
  36467. + *ctx = (struct ghash_desc_ctx){};
  36468. + return 0;
  36469. +}
  36470. +
  36471. +static int ghash_update(struct shash_desc *desc, const u8 *src,
  36472. + unsigned int len)
  36473. +{
  36474. + struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
  36475. + unsigned int partial = ctx->count % GHASH_BLOCK_SIZE;
  36476. +
  36477. + ctx->count += len;
  36478. +
  36479. + if ((partial + len) >= GHASH_BLOCK_SIZE) {
  36480. + struct ghash_key *key = crypto_shash_ctx(desc->tfm);
  36481. + int blocks;
  36482. +
  36483. + if (partial) {
  36484. + int p = GHASH_BLOCK_SIZE - partial;
  36485. +
  36486. + memcpy(ctx->buf + partial, src, p);
  36487. + src += p;
  36488. + len -= p;
  36489. + }
  36490. +
  36491. + blocks = len / GHASH_BLOCK_SIZE;
  36492. + len %= GHASH_BLOCK_SIZE;
  36493. +
  36494. + kernel_neon_begin_partial(8);
  36495. + pmull_ghash_update(blocks, ctx->digest, src, key,
  36496. + partial ? ctx->buf : NULL);
  36497. + kernel_neon_end();
  36498. + src += blocks * GHASH_BLOCK_SIZE;
  36499. + partial = 0;
  36500. + }
  36501. + if (len)
  36502. + memcpy(ctx->buf + partial, src, len);
  36503. + return 0;
  36504. +}
  36505. +
  36506. +static int ghash_final(struct shash_desc *desc, u8 *dst)
  36507. +{
  36508. + struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
  36509. + unsigned int partial = ctx->count % GHASH_BLOCK_SIZE;
  36510. +
  36511. + if (partial) {
  36512. + struct ghash_key *key = crypto_shash_ctx(desc->tfm);
  36513. +
  36514. + memset(ctx->buf + partial, 0, GHASH_BLOCK_SIZE - partial);
  36515. +
  36516. + kernel_neon_begin_partial(8);
  36517. + pmull_ghash_update(1, ctx->digest, ctx->buf, key, NULL);
  36518. + kernel_neon_end();
  36519. + }
  36520. + put_unaligned_be64(ctx->digest[1], dst);
  36521. + put_unaligned_be64(ctx->digest[0], dst + 8);
  36522. +
  36523. + *ctx = (struct ghash_desc_ctx){};
  36524. + return 0;
  36525. +}
  36526. +
  36527. +static int ghash_setkey(struct crypto_shash *tfm,
  36528. + const u8 *inkey, unsigned int keylen)
  36529. +{
  36530. + struct ghash_key *key = crypto_shash_ctx(tfm);
  36531. + u64 a, b;
  36532. +
  36533. + if (keylen != GHASH_BLOCK_SIZE) {
  36534. + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
  36535. + return -EINVAL;
  36536. + }
  36537. +
  36538. + /* perform multiplication by 'x' in GF(2^128) */
  36539. + b = get_unaligned_be64(inkey);
  36540. + a = get_unaligned_be64(inkey + 8);
  36541. +
  36542. + key->a = (a << 1) | (b >> 63);
  36543. + key->b = (b << 1) | (a >> 63);
  36544. +
  36545. + if (b >> 63)
  36546. + key->b ^= 0xc200000000000000UL;
  36547. +
  36548. + return 0;
  36549. +}
  36550. +
  36551. +static struct shash_alg ghash_alg = {
  36552. + .digestsize = GHASH_DIGEST_SIZE,
  36553. + .init = ghash_init,
  36554. + .update = ghash_update,
  36555. + .final = ghash_final,
  36556. + .setkey = ghash_setkey,
  36557. + .descsize = sizeof(struct ghash_desc_ctx),
  36558. + .base = {
  36559. + .cra_name = "ghash",
  36560. + .cra_driver_name = "ghash-ce",
  36561. + .cra_priority = 200,
  36562. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  36563. + .cra_blocksize = GHASH_BLOCK_SIZE,
  36564. + .cra_ctxsize = sizeof(struct ghash_key),
  36565. + .cra_module = THIS_MODULE,
  36566. + },
  36567. +};
  36568. +
  36569. +static int __init ghash_ce_mod_init(void)
  36570. +{
  36571. + return crypto_register_shash(&ghash_alg);
  36572. +}
  36573. +
  36574. +static void __exit ghash_ce_mod_exit(void)
  36575. +{
  36576. + crypto_unregister_shash(&ghash_alg);
  36577. +}
  36578. +
  36579. +module_cpu_feature_match(PMULL, ghash_ce_mod_init);
  36580. +module_exit(ghash_ce_mod_exit);
  36581. diff -Nur linux-3.14.15/arch/arm64/crypto/Kconfig linux-linaro-stable-mx6/arch/arm64/crypto/Kconfig
  36582. --- linux-3.14.15/arch/arm64/crypto/Kconfig 1970-01-01 01:00:00.000000000 +0100
  36583. +++ linux-linaro-stable-mx6/arch/arm64/crypto/Kconfig 2014-08-20 19:31:40.540845019 +0200
  36584. @@ -0,0 +1,53 @@
  36585. +
  36586. +menuconfig ARM64_CRYPTO
  36587. + bool "ARM64 Accelerated Cryptographic Algorithms"
  36588. + depends on ARM64
  36589. + help
  36590. + Say Y here to choose from a selection of cryptographic algorithms
  36591. + implemented using ARM64 specific CPU features or instructions.
  36592. +
  36593. +if ARM64_CRYPTO
  36594. +
  36595. +config CRYPTO_SHA1_ARM64_CE
  36596. + tristate "SHA-1 digest algorithm (ARMv8 Crypto Extensions)"
  36597. + depends on ARM64 && KERNEL_MODE_NEON
  36598. + select CRYPTO_HASH
  36599. +
  36600. +config CRYPTO_SHA2_ARM64_CE
  36601. + tristate "SHA-224/SHA-256 digest algorithm (ARMv8 Crypto Extensions)"
  36602. + depends on ARM64 && KERNEL_MODE_NEON
  36603. + select CRYPTO_HASH
  36604. +
  36605. +config CRYPTO_GHASH_ARM64_CE
  36606. + tristate "GHASH (for GCM chaining mode) using ARMv8 Crypto Extensions"
  36607. + depends on ARM64 && KERNEL_MODE_NEON
  36608. + select CRYPTO_HASH
  36609. +
  36610. +config CRYPTO_AES_ARM64_CE
  36611. + tristate "AES core cipher using ARMv8 Crypto Extensions"
  36612. + depends on ARM64 && KERNEL_MODE_NEON
  36613. + select CRYPTO_ALGAPI
  36614. + select CRYPTO_AES
  36615. +
  36616. +config CRYPTO_AES_ARM64_CE_CCM
  36617. + tristate "AES in CCM mode using ARMv8 Crypto Extensions"
  36618. + depends on ARM64 && KERNEL_MODE_NEON
  36619. + select CRYPTO_ALGAPI
  36620. + select CRYPTO_AES
  36621. + select CRYPTO_AEAD
  36622. +
  36623. +config CRYPTO_AES_ARM64_CE_BLK
  36624. + tristate "AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions"
  36625. + depends on ARM64 && KERNEL_MODE_NEON
  36626. + select CRYPTO_BLKCIPHER
  36627. + select CRYPTO_AES
  36628. + select CRYPTO_ABLK_HELPER
  36629. +
  36630. +config CRYPTO_AES_ARM64_NEON_BLK
  36631. + tristate "AES in ECB/CBC/CTR/XTS modes using NEON instructions"
  36632. + depends on ARM64 && KERNEL_MODE_NEON
  36633. + select CRYPTO_BLKCIPHER
  36634. + select CRYPTO_AES
  36635. + select CRYPTO_ABLK_HELPER
  36636. +
  36637. +endif
  36638. diff -Nur linux-3.14.15/arch/arm64/crypto/Makefile linux-linaro-stable-mx6/arch/arm64/crypto/Makefile
  36639. --- linux-3.14.15/arch/arm64/crypto/Makefile 1970-01-01 01:00:00.000000000 +0100
  36640. +++ linux-linaro-stable-mx6/arch/arm64/crypto/Makefile 2014-08-20 19:31:40.540845019 +0200
  36641. @@ -0,0 +1,38 @@
  36642. +#
  36643. +# linux/arch/arm64/crypto/Makefile
  36644. +#
  36645. +# Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  36646. +#
  36647. +# This program is free software; you can redistribute it and/or modify
  36648. +# it under the terms of the GNU General Public License version 2 as
  36649. +# published by the Free Software Foundation.
  36650. +#
  36651. +
  36652. +obj-$(CONFIG_CRYPTO_SHA1_ARM64_CE) += sha1-ce.o
  36653. +sha1-ce-y := sha1-ce-glue.o sha1-ce-core.o
  36654. +
  36655. +obj-$(CONFIG_CRYPTO_SHA2_ARM64_CE) += sha2-ce.o
  36656. +sha2-ce-y := sha2-ce-glue.o sha2-ce-core.o
  36657. +
  36658. +obj-$(CONFIG_CRYPTO_GHASH_ARM64_CE) += ghash-ce.o
  36659. +ghash-ce-y := ghash-ce-glue.o ghash-ce-core.o
  36660. +
  36661. +obj-$(CONFIG_CRYPTO_AES_ARM64_CE) += aes-ce-cipher.o
  36662. +CFLAGS_aes-ce-cipher.o += -march=armv8-a+crypto
  36663. +
  36664. +obj-$(CONFIG_CRYPTO_AES_ARM64_CE_CCM) += aes-ce-ccm.o
  36665. +aes-ce-ccm-y := aes-ce-ccm-glue.o aes-ce-ccm-core.o
  36666. +
  36667. +obj-$(CONFIG_CRYPTO_AES_ARM64_CE_BLK) += aes-ce-blk.o
  36668. +aes-ce-blk-y := aes-glue-ce.o aes-ce.o
  36669. +
  36670. +obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o
  36671. +aes-neon-blk-y := aes-glue-neon.o aes-neon.o
  36672. +
  36673. +AFLAGS_aes-ce.o := -DINTERLEAVE=2 -DINTERLEAVE_INLINE
  36674. +AFLAGS_aes-neon.o := -DINTERLEAVE=4
  36675. +
  36676. +CFLAGS_aes-glue-ce.o := -DUSE_V8_CRYPTO_EXTENSIONS
  36677. +
  36678. +$(obj)/aes-glue-%.o: $(src)/aes-glue.c FORCE
  36679. + $(call if_changed_dep,cc_o_c)
  36680. diff -Nur linux-3.14.15/arch/arm64/crypto/sha1-ce-core.S linux-linaro-stable-mx6/arch/arm64/crypto/sha1-ce-core.S
  36681. --- linux-3.14.15/arch/arm64/crypto/sha1-ce-core.S 1970-01-01 01:00:00.000000000 +0100
  36682. +++ linux-linaro-stable-mx6/arch/arm64/crypto/sha1-ce-core.S 2014-08-20 19:31:40.544845035 +0200
  36683. @@ -0,0 +1,153 @@
  36684. +/*
  36685. + * sha1-ce-core.S - SHA-1 secure hash using ARMv8 Crypto Extensions
  36686. + *
  36687. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  36688. + *
  36689. + * This program is free software; you can redistribute it and/or modify
  36690. + * it under the terms of the GNU General Public License version 2 as
  36691. + * published by the Free Software Foundation.
  36692. + */
  36693. +
  36694. +#include <linux/linkage.h>
  36695. +#include <asm/assembler.h>
  36696. +
  36697. + .text
  36698. + .arch armv8-a+crypto
  36699. +
  36700. + k0 .req v0
  36701. + k1 .req v1
  36702. + k2 .req v2
  36703. + k3 .req v3
  36704. +
  36705. + t0 .req v4
  36706. + t1 .req v5
  36707. +
  36708. + dga .req q6
  36709. + dgav .req v6
  36710. + dgb .req s7
  36711. + dgbv .req v7
  36712. +
  36713. + dg0q .req q12
  36714. + dg0s .req s12
  36715. + dg0v .req v12
  36716. + dg1s .req s13
  36717. + dg1v .req v13
  36718. + dg2s .req s14
  36719. +
  36720. + .macro add_only, op, ev, rc, s0, dg1
  36721. + .ifc \ev, ev
  36722. + add t1.4s, v\s0\().4s, \rc\().4s
  36723. + sha1h dg2s, dg0s
  36724. + .ifnb \dg1
  36725. + sha1\op dg0q, \dg1, t0.4s
  36726. + .else
  36727. + sha1\op dg0q, dg1s, t0.4s
  36728. + .endif
  36729. + .else
  36730. + .ifnb \s0
  36731. + add t0.4s, v\s0\().4s, \rc\().4s
  36732. + .endif
  36733. + sha1h dg1s, dg0s
  36734. + sha1\op dg0q, dg2s, t1.4s
  36735. + .endif
  36736. + .endm
  36737. +
  36738. + .macro add_update, op, ev, rc, s0, s1, s2, s3, dg1
  36739. + sha1su0 v\s0\().4s, v\s1\().4s, v\s2\().4s
  36740. + add_only \op, \ev, \rc, \s1, \dg1
  36741. + sha1su1 v\s0\().4s, v\s3\().4s
  36742. + .endm
  36743. +
  36744. + /*
  36745. + * The SHA1 round constants
  36746. + */
  36747. + .align 4
  36748. +.Lsha1_rcon:
  36749. + .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
  36750. +
  36751. + /*
  36752. + * void sha1_ce_transform(int blocks, u8 const *src, u32 *state,
  36753. + * u8 *head, long bytes)
  36754. + */
  36755. +ENTRY(sha1_ce_transform)
  36756. + /* load round constants */
  36757. + adr x6, .Lsha1_rcon
  36758. + ld1r {k0.4s}, [x6], #4
  36759. + ld1r {k1.4s}, [x6], #4
  36760. + ld1r {k2.4s}, [x6], #4
  36761. + ld1r {k3.4s}, [x6]
  36762. +
  36763. + /* load state */
  36764. + ldr dga, [x2]
  36765. + ldr dgb, [x2, #16]
  36766. +
  36767. + /* load partial state (if supplied) */
  36768. + cbz x3, 0f
  36769. + ld1 {v8.4s-v11.4s}, [x3]
  36770. + b 1f
  36771. +
  36772. + /* load input */
  36773. +0: ld1 {v8.4s-v11.4s}, [x1], #64
  36774. + sub w0, w0, #1
  36775. +
  36776. +1:
  36777. +CPU_LE( rev32 v8.16b, v8.16b )
  36778. +CPU_LE( rev32 v9.16b, v9.16b )
  36779. +CPU_LE( rev32 v10.16b, v10.16b )
  36780. +CPU_LE( rev32 v11.16b, v11.16b )
  36781. +
  36782. +2: add t0.4s, v8.4s, k0.4s
  36783. + mov dg0v.16b, dgav.16b
  36784. +
  36785. + add_update c, ev, k0, 8, 9, 10, 11, dgb
  36786. + add_update c, od, k0, 9, 10, 11, 8
  36787. + add_update c, ev, k0, 10, 11, 8, 9
  36788. + add_update c, od, k0, 11, 8, 9, 10
  36789. + add_update c, ev, k1, 8, 9, 10, 11
  36790. +
  36791. + add_update p, od, k1, 9, 10, 11, 8
  36792. + add_update p, ev, k1, 10, 11, 8, 9
  36793. + add_update p, od, k1, 11, 8, 9, 10
  36794. + add_update p, ev, k1, 8, 9, 10, 11
  36795. + add_update p, od, k2, 9, 10, 11, 8
  36796. +
  36797. + add_update m, ev, k2, 10, 11, 8, 9
  36798. + add_update m, od, k2, 11, 8, 9, 10
  36799. + add_update m, ev, k2, 8, 9, 10, 11
  36800. + add_update m, od, k2, 9, 10, 11, 8
  36801. + add_update m, ev, k3, 10, 11, 8, 9
  36802. +
  36803. + add_update p, od, k3, 11, 8, 9, 10
  36804. + add_only p, ev, k3, 9
  36805. + add_only p, od, k3, 10
  36806. + add_only p, ev, k3, 11
  36807. + add_only p, od
  36808. +
  36809. + /* update state */
  36810. + add dgbv.2s, dgbv.2s, dg1v.2s
  36811. + add dgav.4s, dgav.4s, dg0v.4s
  36812. +
  36813. + cbnz w0, 0b
  36814. +
  36815. + /*
  36816. + * Final block: add padding and total bit count.
  36817. + * Skip if we have no total byte count in x4. In that case, the input
  36818. + * size was not a round multiple of the block size, and the padding is
  36819. + * handled by the C code.
  36820. + */
  36821. + cbz x4, 3f
  36822. + movi v9.2d, #0
  36823. + mov x8, #0x80000000
  36824. + movi v10.2d, #0
  36825. + ror x7, x4, #29 // ror(lsl(x4, 3), 32)
  36826. + fmov d8, x8
  36827. + mov x4, #0
  36828. + mov v11.d[0], xzr
  36829. + mov v11.d[1], x7
  36830. + b 2b
  36831. +
  36832. + /* store new state */
  36833. +3: str dga, [x2]
  36834. + str dgb, [x2, #16]
  36835. + ret
  36836. +ENDPROC(sha1_ce_transform)
  36837. diff -Nur linux-3.14.15/arch/arm64/crypto/sha1-ce-glue.c linux-linaro-stable-mx6/arch/arm64/crypto/sha1-ce-glue.c
  36838. --- linux-3.14.15/arch/arm64/crypto/sha1-ce-glue.c 1970-01-01 01:00:00.000000000 +0100
  36839. +++ linux-linaro-stable-mx6/arch/arm64/crypto/sha1-ce-glue.c 2014-08-20 19:31:40.544845035 +0200
  36840. @@ -0,0 +1,174 @@
  36841. +/*
  36842. + * sha1-ce-glue.c - SHA-1 secure hash using ARMv8 Crypto Extensions
  36843. + *
  36844. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  36845. + *
  36846. + * This program is free software; you can redistribute it and/or modify
  36847. + * it under the terms of the GNU General Public License version 2 as
  36848. + * published by the Free Software Foundation.
  36849. + */
  36850. +
  36851. +#include <asm/neon.h>
  36852. +#include <asm/unaligned.h>
  36853. +#include <crypto/internal/hash.h>
  36854. +#include <crypto/sha.h>
  36855. +#include <linux/cpufeature.h>
  36856. +#include <linux/crypto.h>
  36857. +#include <linux/module.h>
  36858. +
  36859. +MODULE_DESCRIPTION("SHA1 secure hash using ARMv8 Crypto Extensions");
  36860. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  36861. +MODULE_LICENSE("GPL v2");
  36862. +
  36863. +asmlinkage void sha1_ce_transform(int blocks, u8 const *src, u32 *state,
  36864. + u8 *head, long bytes);
  36865. +
  36866. +static int sha1_init(struct shash_desc *desc)
  36867. +{
  36868. + struct sha1_state *sctx = shash_desc_ctx(desc);
  36869. +
  36870. + *sctx = (struct sha1_state){
  36871. + .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
  36872. + };
  36873. + return 0;
  36874. +}
  36875. +
  36876. +static int sha1_update(struct shash_desc *desc, const u8 *data,
  36877. + unsigned int len)
  36878. +{
  36879. + struct sha1_state *sctx = shash_desc_ctx(desc);
  36880. + unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
  36881. +
  36882. + sctx->count += len;
  36883. +
  36884. + if ((partial + len) >= SHA1_BLOCK_SIZE) {
  36885. + int blocks;
  36886. +
  36887. + if (partial) {
  36888. + int p = SHA1_BLOCK_SIZE - partial;
  36889. +
  36890. + memcpy(sctx->buffer + partial, data, p);
  36891. + data += p;
  36892. + len -= p;
  36893. + }
  36894. +
  36895. + blocks = len / SHA1_BLOCK_SIZE;
  36896. + len %= SHA1_BLOCK_SIZE;
  36897. +
  36898. + kernel_neon_begin_partial(16);
  36899. + sha1_ce_transform(blocks, data, sctx->state,
  36900. + partial ? sctx->buffer : NULL, 0);
  36901. + kernel_neon_end();
  36902. +
  36903. + data += blocks * SHA1_BLOCK_SIZE;
  36904. + partial = 0;
  36905. + }
  36906. + if (len)
  36907. + memcpy(sctx->buffer + partial, data, len);
  36908. + return 0;
  36909. +}
  36910. +
  36911. +static int sha1_final(struct shash_desc *desc, u8 *out)
  36912. +{
  36913. + static const u8 padding[SHA1_BLOCK_SIZE] = { 0x80, };
  36914. +
  36915. + struct sha1_state *sctx = shash_desc_ctx(desc);
  36916. + __be64 bits = cpu_to_be64(sctx->count << 3);
  36917. + __be32 *dst = (__be32 *)out;
  36918. + int i;
  36919. +
  36920. + u32 padlen = SHA1_BLOCK_SIZE
  36921. + - ((sctx->count + sizeof(bits)) % SHA1_BLOCK_SIZE);
  36922. +
  36923. + sha1_update(desc, padding, padlen);
  36924. + sha1_update(desc, (const u8 *)&bits, sizeof(bits));
  36925. +
  36926. + for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++)
  36927. + put_unaligned_be32(sctx->state[i], dst++);
  36928. +
  36929. + *sctx = (struct sha1_state){};
  36930. + return 0;
  36931. +}
  36932. +
  36933. +static int sha1_finup(struct shash_desc *desc, const u8 *data,
  36934. + unsigned int len, u8 *out)
  36935. +{
  36936. + struct sha1_state *sctx = shash_desc_ctx(desc);
  36937. + __be32 *dst = (__be32 *)out;
  36938. + int blocks;
  36939. + int i;
  36940. +
  36941. + if (sctx->count || !len || (len % SHA1_BLOCK_SIZE)) {
  36942. + sha1_update(desc, data, len);
  36943. + return sha1_final(desc, out);
  36944. + }
  36945. +
  36946. + /*
  36947. + * Use a fast path if the input is a multiple of 64 bytes. In
  36948. + * this case, there is no need to copy data around, and we can
  36949. + * perform the entire digest calculation in a single invocation
  36950. + * of sha1_ce_transform()
  36951. + */
  36952. + blocks = len / SHA1_BLOCK_SIZE;
  36953. +
  36954. + kernel_neon_begin_partial(16);
  36955. + sha1_ce_transform(blocks, data, sctx->state, NULL, len);
  36956. + kernel_neon_end();
  36957. +
  36958. + for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++)
  36959. + put_unaligned_be32(sctx->state[i], dst++);
  36960. +
  36961. + *sctx = (struct sha1_state){};
  36962. + return 0;
  36963. +}
  36964. +
  36965. +static int sha1_export(struct shash_desc *desc, void *out)
  36966. +{
  36967. + struct sha1_state *sctx = shash_desc_ctx(desc);
  36968. + struct sha1_state *dst = out;
  36969. +
  36970. + *dst = *sctx;
  36971. + return 0;
  36972. +}
  36973. +
  36974. +static int sha1_import(struct shash_desc *desc, const void *in)
  36975. +{
  36976. + struct sha1_state *sctx = shash_desc_ctx(desc);
  36977. + struct sha1_state const *src = in;
  36978. +
  36979. + *sctx = *src;
  36980. + return 0;
  36981. +}
  36982. +
  36983. +static struct shash_alg alg = {
  36984. + .init = sha1_init,
  36985. + .update = sha1_update,
  36986. + .final = sha1_final,
  36987. + .finup = sha1_finup,
  36988. + .export = sha1_export,
  36989. + .import = sha1_import,
  36990. + .descsize = sizeof(struct sha1_state),
  36991. + .digestsize = SHA1_DIGEST_SIZE,
  36992. + .statesize = sizeof(struct sha1_state),
  36993. + .base = {
  36994. + .cra_name = "sha1",
  36995. + .cra_driver_name = "sha1-ce",
  36996. + .cra_priority = 200,
  36997. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  36998. + .cra_blocksize = SHA1_BLOCK_SIZE,
  36999. + .cra_module = THIS_MODULE,
  37000. + }
  37001. +};
  37002. +
  37003. +static int __init sha1_ce_mod_init(void)
  37004. +{
  37005. + return crypto_register_shash(&alg);
  37006. +}
  37007. +
  37008. +static void __exit sha1_ce_mod_fini(void)
  37009. +{
  37010. + crypto_unregister_shash(&alg);
  37011. +}
  37012. +
  37013. +module_cpu_feature_match(SHA1, sha1_ce_mod_init);
  37014. +module_exit(sha1_ce_mod_fini);
  37015. diff -Nur linux-3.14.15/arch/arm64/crypto/sha2-ce-core.S linux-linaro-stable-mx6/arch/arm64/crypto/sha2-ce-core.S
  37016. --- linux-3.14.15/arch/arm64/crypto/sha2-ce-core.S 1970-01-01 01:00:00.000000000 +0100
  37017. +++ linux-linaro-stable-mx6/arch/arm64/crypto/sha2-ce-core.S 2014-08-20 19:31:40.544845035 +0200
  37018. @@ -0,0 +1,156 @@
  37019. +/*
  37020. + * sha2-ce-core.S - core SHA-224/SHA-256 transform using v8 Crypto Extensions
  37021. + *
  37022. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  37023. + *
  37024. + * This program is free software; you can redistribute it and/or modify
  37025. + * it under the terms of the GNU General Public License version 2 as
  37026. + * published by the Free Software Foundation.
  37027. + */
  37028. +
  37029. +#include <linux/linkage.h>
  37030. +#include <asm/assembler.h>
  37031. +
  37032. + .text
  37033. + .arch armv8-a+crypto
  37034. +
  37035. + dga .req q20
  37036. + dgav .req v20
  37037. + dgb .req q21
  37038. + dgbv .req v21
  37039. +
  37040. + t0 .req v22
  37041. + t1 .req v23
  37042. +
  37043. + dg0q .req q24
  37044. + dg0v .req v24
  37045. + dg1q .req q25
  37046. + dg1v .req v25
  37047. + dg2q .req q26
  37048. + dg2v .req v26
  37049. +
  37050. + .macro add_only, ev, rc, s0
  37051. + mov dg2v.16b, dg0v.16b
  37052. + .ifeq \ev
  37053. + add t1.4s, v\s0\().4s, \rc\().4s
  37054. + sha256h dg0q, dg1q, t0.4s
  37055. + sha256h2 dg1q, dg2q, t0.4s
  37056. + .else
  37057. + .ifnb \s0
  37058. + add t0.4s, v\s0\().4s, \rc\().4s
  37059. + .endif
  37060. + sha256h dg0q, dg1q, t1.4s
  37061. + sha256h2 dg1q, dg2q, t1.4s
  37062. + .endif
  37063. + .endm
  37064. +
  37065. + .macro add_update, ev, rc, s0, s1, s2, s3
  37066. + sha256su0 v\s0\().4s, v\s1\().4s
  37067. + add_only \ev, \rc, \s1
  37068. + sha256su1 v\s0\().4s, v\s2\().4s, v\s3\().4s
  37069. + .endm
  37070. +
  37071. + /*
  37072. + * The SHA-256 round constants
  37073. + */
  37074. + .align 4
  37075. +.Lsha2_rcon:
  37076. + .word 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
  37077. + .word 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
  37078. + .word 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
  37079. + .word 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
  37080. + .word 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
  37081. + .word 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
  37082. + .word 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
  37083. + .word 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
  37084. + .word 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
  37085. + .word 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
  37086. + .word 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
  37087. + .word 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
  37088. + .word 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
  37089. + .word 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
  37090. + .word 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
  37091. + .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
  37092. +
  37093. + /*
  37094. + * void sha2_ce_transform(int blocks, u8 const *src, u32 *state,
  37095. + * u8 *head, long bytes)
  37096. + */
  37097. +ENTRY(sha2_ce_transform)
  37098. + /* load round constants */
  37099. + adr x8, .Lsha2_rcon
  37100. + ld1 { v0.4s- v3.4s}, [x8], #64
  37101. + ld1 { v4.4s- v7.4s}, [x8], #64
  37102. + ld1 { v8.4s-v11.4s}, [x8], #64
  37103. + ld1 {v12.4s-v15.4s}, [x8]
  37104. +
  37105. + /* load state */
  37106. + ldp dga, dgb, [x2]
  37107. +
  37108. + /* load partial input (if supplied) */
  37109. + cbz x3, 0f
  37110. + ld1 {v16.4s-v19.4s}, [x3]
  37111. + b 1f
  37112. +
  37113. + /* load input */
  37114. +0: ld1 {v16.4s-v19.4s}, [x1], #64
  37115. + sub w0, w0, #1
  37116. +
  37117. +1:
  37118. +CPU_LE( rev32 v16.16b, v16.16b )
  37119. +CPU_LE( rev32 v17.16b, v17.16b )
  37120. +CPU_LE( rev32 v18.16b, v18.16b )
  37121. +CPU_LE( rev32 v19.16b, v19.16b )
  37122. +
  37123. +2: add t0.4s, v16.4s, v0.4s
  37124. + mov dg0v.16b, dgav.16b
  37125. + mov dg1v.16b, dgbv.16b
  37126. +
  37127. + add_update 0, v1, 16, 17, 18, 19
  37128. + add_update 1, v2, 17, 18, 19, 16
  37129. + add_update 0, v3, 18, 19, 16, 17
  37130. + add_update 1, v4, 19, 16, 17, 18
  37131. +
  37132. + add_update 0, v5, 16, 17, 18, 19
  37133. + add_update 1, v6, 17, 18, 19, 16
  37134. + add_update 0, v7, 18, 19, 16, 17
  37135. + add_update 1, v8, 19, 16, 17, 18
  37136. +
  37137. + add_update 0, v9, 16, 17, 18, 19
  37138. + add_update 1, v10, 17, 18, 19, 16
  37139. + add_update 0, v11, 18, 19, 16, 17
  37140. + add_update 1, v12, 19, 16, 17, 18
  37141. +
  37142. + add_only 0, v13, 17
  37143. + add_only 1, v14, 18
  37144. + add_only 0, v15, 19
  37145. + add_only 1
  37146. +
  37147. + /* update state */
  37148. + add dgav.4s, dgav.4s, dg0v.4s
  37149. + add dgbv.4s, dgbv.4s, dg1v.4s
  37150. +
  37151. + /* handled all input blocks? */
  37152. + cbnz w0, 0b
  37153. +
  37154. + /*
  37155. + * Final block: add padding and total bit count.
  37156. + * Skip if we have no total byte count in x4. In that case, the input
  37157. + * size was not a round multiple of the block size, and the padding is
  37158. + * handled by the C code.
  37159. + */
  37160. + cbz x4, 3f
  37161. + movi v17.2d, #0
  37162. + mov x8, #0x80000000
  37163. + movi v18.2d, #0
  37164. + ror x7, x4, #29 // ror(lsl(x4, 3), 32)
  37165. + fmov d16, x8
  37166. + mov x4, #0
  37167. + mov v19.d[0], xzr
  37168. + mov v19.d[1], x7
  37169. + b 2b
  37170. +
  37171. + /* store new state */
  37172. +3: stp dga, dgb, [x2]
  37173. + ret
  37174. +ENDPROC(sha2_ce_transform)
  37175. diff -Nur linux-3.14.15/arch/arm64/crypto/sha2-ce-glue.c linux-linaro-stable-mx6/arch/arm64/crypto/sha2-ce-glue.c
  37176. --- linux-3.14.15/arch/arm64/crypto/sha2-ce-glue.c 1970-01-01 01:00:00.000000000 +0100
  37177. +++ linux-linaro-stable-mx6/arch/arm64/crypto/sha2-ce-glue.c 2014-08-20 19:31:40.544845035 +0200
  37178. @@ -0,0 +1,255 @@
  37179. +/*
  37180. + * sha2-ce-glue.c - SHA-224/SHA-256 using ARMv8 Crypto Extensions
  37181. + *
  37182. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  37183. + *
  37184. + * This program is free software; you can redistribute it and/or modify
  37185. + * it under the terms of the GNU General Public License version 2 as
  37186. + * published by the Free Software Foundation.
  37187. + */
  37188. +
  37189. +#include <asm/neon.h>
  37190. +#include <asm/unaligned.h>
  37191. +#include <crypto/internal/hash.h>
  37192. +#include <crypto/sha.h>
  37193. +#include <linux/cpufeature.h>
  37194. +#include <linux/crypto.h>
  37195. +#include <linux/module.h>
  37196. +
  37197. +MODULE_DESCRIPTION("SHA-224/SHA-256 secure hash using ARMv8 Crypto Extensions");
  37198. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  37199. +MODULE_LICENSE("GPL v2");
  37200. +
  37201. +asmlinkage int sha2_ce_transform(int blocks, u8 const *src, u32 *state,
  37202. + u8 *head, long bytes);
  37203. +
  37204. +static int sha224_init(struct shash_desc *desc)
  37205. +{
  37206. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37207. +
  37208. + *sctx = (struct sha256_state){
  37209. + .state = {
  37210. + SHA224_H0, SHA224_H1, SHA224_H2, SHA224_H3,
  37211. + SHA224_H4, SHA224_H5, SHA224_H6, SHA224_H7,
  37212. + }
  37213. + };
  37214. + return 0;
  37215. +}
  37216. +
  37217. +static int sha256_init(struct shash_desc *desc)
  37218. +{
  37219. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37220. +
  37221. + *sctx = (struct sha256_state){
  37222. + .state = {
  37223. + SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3,
  37224. + SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7,
  37225. + }
  37226. + };
  37227. + return 0;
  37228. +}
  37229. +
  37230. +static int sha2_update(struct shash_desc *desc, const u8 *data,
  37231. + unsigned int len)
  37232. +{
  37233. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37234. + unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
  37235. +
  37236. + sctx->count += len;
  37237. +
  37238. + if ((partial + len) >= SHA256_BLOCK_SIZE) {
  37239. + int blocks;
  37240. +
  37241. + if (partial) {
  37242. + int p = SHA256_BLOCK_SIZE - partial;
  37243. +
  37244. + memcpy(sctx->buf + partial, data, p);
  37245. + data += p;
  37246. + len -= p;
  37247. + }
  37248. +
  37249. + blocks = len / SHA256_BLOCK_SIZE;
  37250. + len %= SHA256_BLOCK_SIZE;
  37251. +
  37252. + kernel_neon_begin_partial(28);
  37253. + sha2_ce_transform(blocks, data, sctx->state,
  37254. + partial ? sctx->buf : NULL, 0);
  37255. + kernel_neon_end();
  37256. +
  37257. + data += blocks * SHA256_BLOCK_SIZE;
  37258. + partial = 0;
  37259. + }
  37260. + if (len)
  37261. + memcpy(sctx->buf + partial, data, len);
  37262. + return 0;
  37263. +}
  37264. +
  37265. +static void sha2_final(struct shash_desc *desc)
  37266. +{
  37267. + static const u8 padding[SHA256_BLOCK_SIZE] = { 0x80, };
  37268. +
  37269. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37270. + __be64 bits = cpu_to_be64(sctx->count << 3);
  37271. + u32 padlen = SHA256_BLOCK_SIZE
  37272. + - ((sctx->count + sizeof(bits)) % SHA256_BLOCK_SIZE);
  37273. +
  37274. + sha2_update(desc, padding, padlen);
  37275. + sha2_update(desc, (const u8 *)&bits, sizeof(bits));
  37276. +}
  37277. +
  37278. +static int sha224_final(struct shash_desc *desc, u8 *out)
  37279. +{
  37280. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37281. + __be32 *dst = (__be32 *)out;
  37282. + int i;
  37283. +
  37284. + sha2_final(desc);
  37285. +
  37286. + for (i = 0; i < SHA224_DIGEST_SIZE / sizeof(__be32); i++)
  37287. + put_unaligned_be32(sctx->state[i], dst++);
  37288. +
  37289. + *sctx = (struct sha256_state){};
  37290. + return 0;
  37291. +}
  37292. +
  37293. +static int sha256_final(struct shash_desc *desc, u8 *out)
  37294. +{
  37295. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37296. + __be32 *dst = (__be32 *)out;
  37297. + int i;
  37298. +
  37299. + sha2_final(desc);
  37300. +
  37301. + for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(__be32); i++)
  37302. + put_unaligned_be32(sctx->state[i], dst++);
  37303. +
  37304. + *sctx = (struct sha256_state){};
  37305. + return 0;
  37306. +}
  37307. +
  37308. +static void sha2_finup(struct shash_desc *desc, const u8 *data,
  37309. + unsigned int len)
  37310. +{
  37311. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37312. + int blocks;
  37313. +
  37314. + if (sctx->count || !len || (len % SHA256_BLOCK_SIZE)) {
  37315. + sha2_update(desc, data, len);
  37316. + sha2_final(desc);
  37317. + return;
  37318. + }
  37319. +
  37320. + /*
  37321. + * Use a fast path if the input is a multiple of 64 bytes. In
  37322. + * this case, there is no need to copy data around, and we can
  37323. + * perform the entire digest calculation in a single invocation
  37324. + * of sha2_ce_transform()
  37325. + */
  37326. + blocks = len / SHA256_BLOCK_SIZE;
  37327. +
  37328. + kernel_neon_begin_partial(28);
  37329. + sha2_ce_transform(blocks, data, sctx->state, NULL, len);
  37330. + kernel_neon_end();
  37331. + data += blocks * SHA256_BLOCK_SIZE;
  37332. +}
  37333. +
  37334. +static int sha224_finup(struct shash_desc *desc, const u8 *data,
  37335. + unsigned int len, u8 *out)
  37336. +{
  37337. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37338. + __be32 *dst = (__be32 *)out;
  37339. + int i;
  37340. +
  37341. + sha2_finup(desc, data, len);
  37342. +
  37343. + for (i = 0; i < SHA224_DIGEST_SIZE / sizeof(__be32); i++)
  37344. + put_unaligned_be32(sctx->state[i], dst++);
  37345. +
  37346. + *sctx = (struct sha256_state){};
  37347. + return 0;
  37348. +}
  37349. +
  37350. +static int sha256_finup(struct shash_desc *desc, const u8 *data,
  37351. + unsigned int len, u8 *out)
  37352. +{
  37353. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37354. + __be32 *dst = (__be32 *)out;
  37355. + int i;
  37356. +
  37357. + sha2_finup(desc, data, len);
  37358. +
  37359. + for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(__be32); i++)
  37360. + put_unaligned_be32(sctx->state[i], dst++);
  37361. +
  37362. + *sctx = (struct sha256_state){};
  37363. + return 0;
  37364. +}
  37365. +
  37366. +static int sha2_export(struct shash_desc *desc, void *out)
  37367. +{
  37368. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37369. + struct sha256_state *dst = out;
  37370. +
  37371. + *dst = *sctx;
  37372. + return 0;
  37373. +}
  37374. +
  37375. +static int sha2_import(struct shash_desc *desc, const void *in)
  37376. +{
  37377. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37378. + struct sha256_state const *src = in;
  37379. +
  37380. + *sctx = *src;
  37381. + return 0;
  37382. +}
  37383. +
  37384. +static struct shash_alg algs[] = { {
  37385. + .init = sha224_init,
  37386. + .update = sha2_update,
  37387. + .final = sha224_final,
  37388. + .finup = sha224_finup,
  37389. + .export = sha2_export,
  37390. + .import = sha2_import,
  37391. + .descsize = sizeof(struct sha256_state),
  37392. + .digestsize = SHA224_DIGEST_SIZE,
  37393. + .statesize = sizeof(struct sha256_state),
  37394. + .base = {
  37395. + .cra_name = "sha224",
  37396. + .cra_driver_name = "sha224-ce",
  37397. + .cra_priority = 200,
  37398. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  37399. + .cra_blocksize = SHA256_BLOCK_SIZE,
  37400. + .cra_module = THIS_MODULE,
  37401. + }
  37402. +}, {
  37403. + .init = sha256_init,
  37404. + .update = sha2_update,
  37405. + .final = sha256_final,
  37406. + .finup = sha256_finup,
  37407. + .export = sha2_export,
  37408. + .import = sha2_import,
  37409. + .descsize = sizeof(struct sha256_state),
  37410. + .digestsize = SHA256_DIGEST_SIZE,
  37411. + .statesize = sizeof(struct sha256_state),
  37412. + .base = {
  37413. + .cra_name = "sha256",
  37414. + .cra_driver_name = "sha256-ce",
  37415. + .cra_priority = 200,
  37416. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  37417. + .cra_blocksize = SHA256_BLOCK_SIZE,
  37418. + .cra_module = THIS_MODULE,
  37419. + }
  37420. +} };
  37421. +
  37422. +static int __init sha2_ce_mod_init(void)
  37423. +{
  37424. + return crypto_register_shashes(algs, ARRAY_SIZE(algs));
  37425. +}
  37426. +
  37427. +static void __exit sha2_ce_mod_fini(void)
  37428. +{
  37429. + crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
  37430. +}
  37431. +
  37432. +module_cpu_feature_match(SHA2, sha2_ce_mod_init);
  37433. +module_exit(sha2_ce_mod_fini);
  37434. diff -Nur linux-3.14.15/arch/arm64/include/asm/bL_switcher.h linux-linaro-stable-mx6/arch/arm64/include/asm/bL_switcher.h
  37435. --- linux-3.14.15/arch/arm64/include/asm/bL_switcher.h 1970-01-01 01:00:00.000000000 +0100
  37436. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/bL_switcher.h 2014-08-20 19:31:40.544845035 +0200
  37437. @@ -0,0 +1,54 @@
  37438. +/*
  37439. + * Based on the stubs for the ARM implementation which is:
  37440. + *
  37441. + * Created by: Nicolas Pitre, April 2012
  37442. + * Copyright: (C) 2012-2013 Linaro Limited
  37443. + *
  37444. + * This program is free software; you can redistribute it and/or modify
  37445. + * it under the terms of the GNU General Public License version 2 as
  37446. + * published by the Free Software Foundation.
  37447. + */
  37448. +
  37449. +#ifndef ASM_BL_SWITCHER_H
  37450. +#define ASM_BL_SWITCHER_H
  37451. +
  37452. +#include <linux/notifier.h>
  37453. +#include <linux/types.h>
  37454. +
  37455. +typedef void (*bL_switch_completion_handler)(void *cookie);
  37456. +
  37457. +static inline int bL_switch_request(unsigned int cpu,
  37458. + unsigned int new_cluster_id)
  37459. +{
  37460. + return -ENOTSUPP;
  37461. +}
  37462. +
  37463. +/*
  37464. + * Register here to be notified about runtime enabling/disabling of
  37465. + * the switcher.
  37466. + *
  37467. + * The notifier chain is called with the switcher activation lock held:
  37468. + * the switcher will not be enabled or disabled during callbacks.
  37469. + * Callbacks must not call bL_switcher_{get,put}_enabled().
  37470. + */
  37471. +#define BL_NOTIFY_PRE_ENABLE 0
  37472. +#define BL_NOTIFY_POST_ENABLE 1
  37473. +#define BL_NOTIFY_PRE_DISABLE 2
  37474. +#define BL_NOTIFY_POST_DISABLE 3
  37475. +
  37476. +static inline int bL_switcher_register_notifier(struct notifier_block *nb)
  37477. +{
  37478. + return 0;
  37479. +}
  37480. +
  37481. +static inline int bL_switcher_unregister_notifier(struct notifier_block *nb)
  37482. +{
  37483. + return 0;
  37484. +}
  37485. +
  37486. +static inline bool bL_switcher_get_enabled(void) { return false; }
  37487. +static inline void bL_switcher_put_enabled(void) { }
  37488. +static inline int bL_switcher_trace_trigger(void) { return 0; }
  37489. +static inline int bL_switcher_get_logical_index(u32 mpidr) { return -EUNATCH; }
  37490. +
  37491. +#endif
  37492. diff -Nur linux-3.14.15/arch/arm64/include/asm/cacheflush.h linux-linaro-stable-mx6/arch/arm64/include/asm/cacheflush.h
  37493. --- linux-3.14.15/arch/arm64/include/asm/cacheflush.h 2014-07-31 23:51:43.000000000 +0200
  37494. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/cacheflush.h 2014-08-20 19:31:40.544845035 +0200
  37495. @@ -85,6 +85,13 @@
  37496. }
  37497. /*
  37498. + * Cache maintenance functions used by the DMA API. No to be used directly.
  37499. + */
  37500. +extern void __dma_map_area(const void *, size_t, int);
  37501. +extern void __dma_unmap_area(const void *, size_t, int);
  37502. +extern void __dma_flush_range(const void *, const void *);
  37503. +
  37504. +/*
  37505. * Copy user data from/to a page which is mapped into a different
  37506. * processes address space. Really, we want to allow our "user
  37507. * space" model to handle this.
  37508. diff -Nur linux-3.14.15/arch/arm64/include/asm/compat.h linux-linaro-stable-mx6/arch/arm64/include/asm/compat.h
  37509. --- linux-3.14.15/arch/arm64/include/asm/compat.h 2014-07-31 23:51:43.000000000 +0200
  37510. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/compat.h 2014-08-20 19:31:40.548845053 +0200
  37511. @@ -228,7 +228,7 @@
  37512. return (u32)(unsigned long)uptr;
  37513. }
  37514. -#define compat_user_stack_pointer() (current_pt_regs()->compat_sp)
  37515. +#define compat_user_stack_pointer() (user_stack_pointer(current_pt_regs()))
  37516. static inline void __user *arch_compat_alloc_user_space(long len)
  37517. {
  37518. @@ -305,11 +305,6 @@
  37519. #else /* !CONFIG_COMPAT */
  37520. -static inline int is_compat_task(void)
  37521. -{
  37522. - return 0;
  37523. -}
  37524. -
  37525. static inline int is_compat_thread(struct thread_info *thread)
  37526. {
  37527. return 0;
  37528. diff -Nur linux-3.14.15/arch/arm64/include/asm/cpufeature.h linux-linaro-stable-mx6/arch/arm64/include/asm/cpufeature.h
  37529. --- linux-3.14.15/arch/arm64/include/asm/cpufeature.h 1970-01-01 01:00:00.000000000 +0100
  37530. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/cpufeature.h 2014-08-20 19:31:40.548845053 +0200
  37531. @@ -0,0 +1,29 @@
  37532. +/*
  37533. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  37534. + *
  37535. + * This program is free software; you can redistribute it and/or modify
  37536. + * it under the terms of the GNU General Public License version 2 as
  37537. + * published by the Free Software Foundation.
  37538. + */
  37539. +
  37540. +#ifndef __ASM_CPUFEATURE_H
  37541. +#define __ASM_CPUFEATURE_H
  37542. +
  37543. +#include <asm/hwcap.h>
  37544. +
  37545. +/*
  37546. + * In the arm64 world (as in the ARM world), elf_hwcap is used both internally
  37547. + * in the kernel and for user space to keep track of which optional features
  37548. + * are supported by the current system. So let's map feature 'x' to HWCAP_x.
  37549. + * Note that HWCAP_x constants are bit fields so we need to take the log.
  37550. + */
  37551. +
  37552. +#define MAX_CPU_FEATURES (8 * sizeof(elf_hwcap))
  37553. +#define cpu_feature(x) ilog2(HWCAP_ ## x)
  37554. +
  37555. +static inline bool cpu_have_feature(unsigned int num)
  37556. +{
  37557. + return elf_hwcap & (1UL << num);
  37558. +}
  37559. +
  37560. +#endif
  37561. diff -Nur linux-3.14.15/arch/arm64/include/asm/debug-monitors.h linux-linaro-stable-mx6/arch/arm64/include/asm/debug-monitors.h
  37562. --- linux-3.14.15/arch/arm64/include/asm/debug-monitors.h 2014-07-31 23:51:43.000000000 +0200
  37563. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/debug-monitors.h 2014-08-20 19:31:40.548845053 +0200
  37564. @@ -26,6 +26,53 @@
  37565. #define DBG_ESR_EVT_HWWP 0x2
  37566. #define DBG_ESR_EVT_BRK 0x6
  37567. +/*
  37568. + * Break point instruction encoding
  37569. + */
  37570. +#define BREAK_INSTR_SIZE 4
  37571. +
  37572. +/*
  37573. + * ESR values expected for dynamic and compile time BRK instruction
  37574. + */
  37575. +#define DBG_ESR_VAL_BRK(x) (0xf2000000 | ((x) & 0xfffff))
  37576. +
  37577. +/*
  37578. + * #imm16 values used for BRK instruction generation
  37579. + * Allowed values for kgbd are 0x400 - 0x7ff
  37580. + * 0x400: for dynamic BRK instruction
  37581. + * 0x401: for compile time BRK instruction
  37582. + */
  37583. +#define KGDB_DYN_DGB_BRK_IMM 0x400
  37584. +#define KDBG_COMPILED_DBG_BRK_IMM 0x401
  37585. +
  37586. +/*
  37587. + * BRK instruction encoding
  37588. + * The #imm16 value should be placed at bits[20:5] within BRK ins
  37589. + */
  37590. +#define AARCH64_BREAK_MON 0xd4200000
  37591. +
  37592. +/*
  37593. + * Extract byte from BRK instruction
  37594. + */
  37595. +#define KGDB_DYN_DGB_BRK_INS_BYTE(x) \
  37596. + ((((AARCH64_BREAK_MON) & 0xffe0001f) >> (x * 8)) & 0xff)
  37597. +
  37598. +/*
  37599. + * Extract byte from BRK #imm16
  37600. + */
  37601. +#define KGBD_DYN_DGB_BRK_IMM_BYTE(x) \
  37602. + (((((KGDB_DYN_DGB_BRK_IMM) & 0xffff) << 5) >> (x * 8)) & 0xff)
  37603. +
  37604. +#define KGDB_DYN_DGB_BRK_BYTE(x) \
  37605. + (KGDB_DYN_DGB_BRK_INS_BYTE(x) | KGBD_DYN_DGB_BRK_IMM_BYTE(x))
  37606. +
  37607. +#define KGDB_DYN_BRK_INS_BYTE0 KGDB_DYN_DGB_BRK_BYTE(0)
  37608. +#define KGDB_DYN_BRK_INS_BYTE1 KGDB_DYN_DGB_BRK_BYTE(1)
  37609. +#define KGDB_DYN_BRK_INS_BYTE2 KGDB_DYN_DGB_BRK_BYTE(2)
  37610. +#define KGDB_DYN_BRK_INS_BYTE3 KGDB_DYN_DGB_BRK_BYTE(3)
  37611. +
  37612. +#define CACHE_FLUSH_IS_SAFE 1
  37613. +
  37614. enum debug_el {
  37615. DBG_ACTIVE_EL0 = 0,
  37616. DBG_ACTIVE_EL1,
  37617. @@ -43,23 +90,6 @@
  37618. #ifndef __ASSEMBLY__
  37619. struct task_struct;
  37620. -#define local_dbg_save(flags) \
  37621. - do { \
  37622. - typecheck(unsigned long, flags); \
  37623. - asm volatile( \
  37624. - "mrs %0, daif // local_dbg_save\n" \
  37625. - "msr daifset, #8" \
  37626. - : "=r" (flags) : : "memory"); \
  37627. - } while (0)
  37628. -
  37629. -#define local_dbg_restore(flags) \
  37630. - do { \
  37631. - typecheck(unsigned long, flags); \
  37632. - asm volatile( \
  37633. - "msr daif, %0 // local_dbg_restore\n" \
  37634. - : : "r" (flags) : "memory"); \
  37635. - } while (0)
  37636. -
  37637. #define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
  37638. #define DBG_HOOK_HANDLED 0
  37639. diff -Nur linux-3.14.15/arch/arm64/include/asm/dma-mapping.h linux-linaro-stable-mx6/arch/arm64/include/asm/dma-mapping.h
  37640. --- linux-3.14.15/arch/arm64/include/asm/dma-mapping.h 2014-07-31 23:51:43.000000000 +0200
  37641. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/dma-mapping.h 2014-08-20 19:31:40.552845071 +0200
  37642. @@ -28,6 +28,8 @@
  37643. #define DMA_ERROR_CODE (~(dma_addr_t)0)
  37644. extern struct dma_map_ops *dma_ops;
  37645. +extern struct dma_map_ops coherent_swiotlb_dma_ops;
  37646. +extern struct dma_map_ops noncoherent_swiotlb_dma_ops;
  37647. static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
  37648. {
  37649. @@ -45,6 +47,11 @@
  37650. return __generic_dma_ops(dev);
  37651. }
  37652. +static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
  37653. +{
  37654. + dev->archdata.dma_ops = ops;
  37655. +}
  37656. +
  37657. #include <asm-generic/dma-mapping-common.h>
  37658. static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
  37659. diff -Nur linux-3.14.15/arch/arm64/include/asm/ftrace.h linux-linaro-stable-mx6/arch/arm64/include/asm/ftrace.h
  37660. --- linux-3.14.15/arch/arm64/include/asm/ftrace.h 1970-01-01 01:00:00.000000000 +0100
  37661. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/ftrace.h 2014-08-20 19:31:40.556845089 +0200
  37662. @@ -0,0 +1,59 @@
  37663. +/*
  37664. + * arch/arm64/include/asm/ftrace.h
  37665. + *
  37666. + * Copyright (C) 2013 Linaro Limited
  37667. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  37668. + *
  37669. + * This program is free software; you can redistribute it and/or modify
  37670. + * it under the terms of the GNU General Public License version 2 as
  37671. + * published by the Free Software Foundation.
  37672. + */
  37673. +#ifndef __ASM_FTRACE_H
  37674. +#define __ASM_FTRACE_H
  37675. +
  37676. +#include <asm/insn.h>
  37677. +
  37678. +#define MCOUNT_ADDR ((unsigned long)_mcount)
  37679. +#define MCOUNT_INSN_SIZE AARCH64_INSN_SIZE
  37680. +
  37681. +#ifndef __ASSEMBLY__
  37682. +#include <linux/compat.h>
  37683. +
  37684. +extern void _mcount(unsigned long);
  37685. +extern void *return_address(unsigned int);
  37686. +
  37687. +struct dyn_arch_ftrace {
  37688. + /* No extra data needed for arm64 */
  37689. +};
  37690. +
  37691. +extern unsigned long ftrace_graph_call;
  37692. +
  37693. +static inline unsigned long ftrace_call_adjust(unsigned long addr)
  37694. +{
  37695. + /*
  37696. + * addr is the address of the mcount call instruction.
  37697. + * recordmcount does the necessary offset calculation.
  37698. + */
  37699. + return addr;
  37700. +}
  37701. +
  37702. +#define ftrace_return_address(n) return_address(n)
  37703. +
  37704. +/*
  37705. + * Because AArch32 mode does not share the same syscall table with AArch64,
  37706. + * tracing compat syscalls may result in reporting bogus syscalls or even
  37707. + * hang-up, so just do not trace them.
  37708. + * See kernel/trace/trace_syscalls.c
  37709. + *
  37710. + * x86 code says:
  37711. + * If the user realy wants these, then they should use the
  37712. + * raw syscall tracepoints with filtering.
  37713. + */
  37714. +#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
  37715. +static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
  37716. +{
  37717. + return is_compat_task();
  37718. +}
  37719. +#endif /* ifndef __ASSEMBLY__ */
  37720. +
  37721. +#endif /* __ASM_FTRACE_H */
  37722. diff -Nur linux-3.14.15/arch/arm64/include/asm/hwcap.h linux-linaro-stable-mx6/arch/arm64/include/asm/hwcap.h
  37723. --- linux-3.14.15/arch/arm64/include/asm/hwcap.h 2014-07-31 23:51:43.000000000 +0200
  37724. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/hwcap.h 2014-08-20 19:31:40.560845104 +0200
  37725. @@ -32,6 +32,12 @@
  37726. #define COMPAT_HWCAP_IDIV (COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT)
  37727. #define COMPAT_HWCAP_EVTSTRM (1 << 21)
  37728. +#define COMPAT_HWCAP2_AES (1 << 0)
  37729. +#define COMPAT_HWCAP2_PMULL (1 << 1)
  37730. +#define COMPAT_HWCAP2_SHA1 (1 << 2)
  37731. +#define COMPAT_HWCAP2_SHA2 (1 << 3)
  37732. +#define COMPAT_HWCAP2_CRC32 (1 << 4)
  37733. +
  37734. #ifndef __ASSEMBLY__
  37735. /*
  37736. * This yields a mask that user programs can use to figure out what
  37737. @@ -41,7 +47,8 @@
  37738. #ifdef CONFIG_COMPAT
  37739. #define COMPAT_ELF_HWCAP (compat_elf_hwcap)
  37740. -extern unsigned int compat_elf_hwcap;
  37741. +#define COMPAT_ELF_HWCAP2 (compat_elf_hwcap2)
  37742. +extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
  37743. #endif
  37744. extern unsigned long elf_hwcap;
  37745. diff -Nur linux-3.14.15/arch/arm64/include/asm/insn.h linux-linaro-stable-mx6/arch/arm64/include/asm/insn.h
  37746. --- linux-3.14.15/arch/arm64/include/asm/insn.h 2014-07-31 23:51:43.000000000 +0200
  37747. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/insn.h 2014-08-20 19:31:40.560845104 +0200
  37748. @@ -16,11 +16,14 @@
  37749. */
  37750. #ifndef __ASM_INSN_H
  37751. #define __ASM_INSN_H
  37752. +
  37753. #include <linux/types.h>
  37754. /* A64 instructions are always 32 bits. */
  37755. #define AARCH64_INSN_SIZE 4
  37756. +#ifndef __ASSEMBLY__
  37757. +
  37758. /*
  37759. * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
  37760. * Section C3.1 "A64 instruction index by encoding":
  37761. @@ -105,4 +108,6 @@
  37762. int aarch64_insn_patch_text_sync(void *addrs[], u32 insns[], int cnt);
  37763. int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
  37764. +#endif /* __ASSEMBLY__ */
  37765. +
  37766. #endif /* __ASM_INSN_H */
  37767. diff -Nur linux-3.14.15/arch/arm64/include/asm/irqflags.h linux-linaro-stable-mx6/arch/arm64/include/asm/irqflags.h
  37768. --- linux-3.14.15/arch/arm64/include/asm/irqflags.h 2014-07-31 23:51:43.000000000 +0200
  37769. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/irqflags.h 2014-08-20 19:31:40.560845104 +0200
  37770. @@ -90,5 +90,28 @@
  37771. return flags & PSR_I_BIT;
  37772. }
  37773. +/*
  37774. + * save and restore debug state
  37775. + */
  37776. +#define local_dbg_save(flags) \
  37777. + do { \
  37778. + typecheck(unsigned long, flags); \
  37779. + asm volatile( \
  37780. + "mrs %0, daif // local_dbg_save\n" \
  37781. + "msr daifset, #8" \
  37782. + : "=r" (flags) : : "memory"); \
  37783. + } while (0)
  37784. +
  37785. +#define local_dbg_restore(flags) \
  37786. + do { \
  37787. + typecheck(unsigned long, flags); \
  37788. + asm volatile( \
  37789. + "msr daif, %0 // local_dbg_restore\n" \
  37790. + : : "r" (flags) : "memory"); \
  37791. + } while (0)
  37792. +
  37793. +#define local_dbg_enable() asm("msr daifclr, #8" : : : "memory")
  37794. +#define local_dbg_disable() asm("msr daifset, #8" : : : "memory")
  37795. +
  37796. #endif
  37797. #endif
  37798. diff -Nur linux-3.14.15/arch/arm64/include/asm/Kbuild linux-linaro-stable-mx6/arch/arm64/include/asm/Kbuild
  37799. --- linux-3.14.15/arch/arm64/include/asm/Kbuild 2014-07-31 23:51:43.000000000 +0200
  37800. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/Kbuild 2014-08-20 19:31:40.544845035 +0200
  37801. @@ -35,6 +35,7 @@
  37802. generic-y += sembuf.h
  37803. generic-y += serial.h
  37804. generic-y += shmbuf.h
  37805. +generic-y += simd.h
  37806. generic-y += sizes.h
  37807. generic-y += socket.h
  37808. generic-y += sockios.h
  37809. diff -Nur linux-3.14.15/arch/arm64/include/asm/kgdb.h linux-linaro-stable-mx6/arch/arm64/include/asm/kgdb.h
  37810. --- linux-3.14.15/arch/arm64/include/asm/kgdb.h 1970-01-01 01:00:00.000000000 +0100
  37811. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/kgdb.h 2014-08-20 19:31:40.564845121 +0200
  37812. @@ -0,0 +1,84 @@
  37813. +/*
  37814. + * AArch64 KGDB support
  37815. + *
  37816. + * Based on arch/arm/include/kgdb.h
  37817. + *
  37818. + * Copyright (C) 2013 Cavium Inc.
  37819. + * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>
  37820. + *
  37821. + * This program is free software; you can redistribute it and/or modify
  37822. + * it under the terms of the GNU General Public License version 2 as
  37823. + * published by the Free Software Foundation.
  37824. + *
  37825. + * This program is distributed in the hope that it will be useful,
  37826. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  37827. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  37828. + * GNU General Public License for more details.
  37829. + *
  37830. + * You should have received a copy of the GNU General Public License
  37831. + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  37832. + */
  37833. +
  37834. +#ifndef __ARM_KGDB_H
  37835. +#define __ARM_KGDB_H
  37836. +
  37837. +#include <linux/ptrace.h>
  37838. +#include <asm/debug-monitors.h>
  37839. +
  37840. +#ifndef __ASSEMBLY__
  37841. +
  37842. +static inline void arch_kgdb_breakpoint(void)
  37843. +{
  37844. + asm ("brk %0" : : "I" (KDBG_COMPILED_DBG_BRK_IMM));
  37845. +}
  37846. +
  37847. +extern void kgdb_handle_bus_error(void);
  37848. +extern int kgdb_fault_expected;
  37849. +
  37850. +#endif /* !__ASSEMBLY__ */
  37851. +
  37852. +/*
  37853. + * gdb is expecting the following registers layout.
  37854. + *
  37855. + * General purpose regs:
  37856. + * r0-r30: 64 bit
  37857. + * sp,pc : 64 bit
  37858. + * pstate : 64 bit
  37859. + * Total: 34
  37860. + * FPU regs:
  37861. + * f0-f31: 128 bit
  37862. + * Total: 32
  37863. + * Extra regs
  37864. + * fpsr & fpcr: 32 bit
  37865. + * Total: 2
  37866. + *
  37867. + */
  37868. +
  37869. +#define _GP_REGS 34
  37870. +#define _FP_REGS 32
  37871. +#define _EXTRA_REGS 2
  37872. +/*
  37873. + * general purpose registers size in bytes.
  37874. + * pstate is only 4 bytes. subtract 4 bytes
  37875. + */
  37876. +#define GP_REG_BYTES (_GP_REGS * 8)
  37877. +#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS)
  37878. +
  37879. +/*
  37880. + * Size of I/O buffer for gdb packet.
  37881. + * considering to hold all register contents, size is set
  37882. + */
  37883. +
  37884. +#define BUFMAX 2048
  37885. +
  37886. +/*
  37887. + * Number of bytes required for gdb_regs buffer.
  37888. + * _GP_REGS: 8 bytes, _FP_REGS: 16 bytes and _EXTRA_REGS: 4 bytes each
  37889. + * GDB fails to connect for size beyond this with error
  37890. + * "'g' packet reply is too long"
  37891. + */
  37892. +
  37893. +#define NUMREGBYTES ((_GP_REGS * 8) + (_FP_REGS * 16) + \
  37894. + (_EXTRA_REGS * 4))
  37895. +
  37896. +#endif /* __ASM_KGDB_H */
  37897. diff -Nur linux-3.14.15/arch/arm64/include/asm/page.h linux-linaro-stable-mx6/arch/arm64/include/asm/page.h
  37898. --- linux-3.14.15/arch/arm64/include/asm/page.h 2014-07-31 23:51:43.000000000 +0200
  37899. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/page.h 2014-08-20 19:31:40.572845156 +0200
  37900. @@ -31,6 +31,15 @@
  37901. /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
  37902. #define __HAVE_ARCH_GATE_AREA 1
  37903. +/*
  37904. + * The idmap and swapper page tables need some space reserved in the kernel
  37905. + * image. The idmap only requires a pgd and a next level table to (section) map
  37906. + * the kernel, while the swapper also maps the FDT and requires an additional
  37907. + * table to map an early UART. See __create_page_tables for more information.
  37908. + */
  37909. +#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
  37910. +#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
  37911. +
  37912. #ifndef __ASSEMBLY__
  37913. #ifdef CONFIG_ARM64_64K_PAGES
  37914. diff -Nur linux-3.14.15/arch/arm64/include/asm/pgtable.h linux-linaro-stable-mx6/arch/arm64/include/asm/pgtable.h
  37915. --- linux-3.14.15/arch/arm64/include/asm/pgtable.h 2014-07-31 23:51:43.000000000 +0200
  37916. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/pgtable.h 2014-08-20 19:31:40.580845192 +0200
  37917. @@ -227,36 +227,36 @@
  37918. #define __HAVE_ARCH_PTE_SPECIAL
  37919. -/*
  37920. - * Software PMD bits for THP
  37921. - */
  37922. +static inline pte_t pmd_pte(pmd_t pmd)
  37923. +{
  37924. + return __pte(pmd_val(pmd));
  37925. +}
  37926. -#define PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55)
  37927. -#define PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 57)
  37928. +static inline pmd_t pte_pmd(pte_t pte)
  37929. +{
  37930. + return __pmd(pte_val(pte));
  37931. +}
  37932. /*
  37933. * THP definitions.
  37934. */
  37935. -#define pmd_young(pmd) (pmd_val(pmd) & PMD_SECT_AF)
  37936. -
  37937. -#define __HAVE_ARCH_PMD_WRITE
  37938. -#define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY))
  37939. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  37940. #define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
  37941. -#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
  37942. +#define pmd_trans_splitting(pmd) pte_special(pmd_pte(pmd))
  37943. #endif
  37944. -#define PMD_BIT_FUNC(fn,op) \
  37945. -static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
  37946. +#define pmd_young(pmd) pte_young(pmd_pte(pmd))
  37947. +#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
  37948. +#define pmd_mksplitting(pmd) pte_pmd(pte_mkspecial(pmd_pte(pmd)))
  37949. +#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
  37950. +#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
  37951. +#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
  37952. +#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
  37953. +#define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) &= ~PMD_TYPE_MASK))
  37954. -PMD_BIT_FUNC(wrprotect, |= PMD_SECT_RDONLY);
  37955. -PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF);
  37956. -PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING);
  37957. -PMD_BIT_FUNC(mkwrite, &= ~PMD_SECT_RDONLY);
  37958. -PMD_BIT_FUNC(mkdirty, |= PMD_SECT_DIRTY);
  37959. -PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
  37960. -PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
  37961. +#define __HAVE_ARCH_PMD_WRITE
  37962. +#define pmd_write(pmd) pte_write(pmd_pte(pmd))
  37963. #define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
  37964. @@ -266,16 +266,7 @@
  37965. #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
  37966. -static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
  37967. -{
  37968. - const pmdval_t mask = PMD_SECT_USER | PMD_SECT_PXN | PMD_SECT_UXN |
  37969. - PMD_SECT_RDONLY | PMD_SECT_PROT_NONE |
  37970. - PMD_SECT_VALID;
  37971. - pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
  37972. - return pmd;
  37973. -}
  37974. -
  37975. -#define set_pmd_at(mm, addr, pmdp, pmd) set_pmd(pmdp, pmd)
  37976. +#define set_pmd_at(mm, addr, pmdp, pmd) set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd))
  37977. static inline int has_transparent_hugepage(void)
  37978. {
  37979. @@ -383,12 +374,14 @@
  37980. return pte;
  37981. }
  37982. +static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
  37983. +{
  37984. + return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
  37985. +}
  37986. +
  37987. extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
  37988. extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
  37989. -#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
  37990. -#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
  37991. -
  37992. /*
  37993. * Encode and decode a swap entry:
  37994. * bits 0-1: present (must be zero)
  37995. diff -Nur linux-3.14.15/arch/arm64/include/asm/ptrace.h linux-linaro-stable-mx6/arch/arm64/include/asm/ptrace.h
  37996. --- linux-3.14.15/arch/arm64/include/asm/ptrace.h 2014-07-31 23:51:43.000000000 +0200
  37997. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/ptrace.h 2014-08-20 19:31:40.580845192 +0200
  37998. @@ -68,6 +68,7 @@
  37999. /* Architecturally defined mapping between AArch32 and AArch64 registers */
  38000. #define compat_usr(x) regs[(x)]
  38001. +#define compat_fp regs[11]
  38002. #define compat_sp regs[13]
  38003. #define compat_lr regs[14]
  38004. #define compat_sp_hyp regs[15]
  38005. @@ -132,7 +133,12 @@
  38006. (!((regs)->pstate & PSR_F_BIT))
  38007. #define user_stack_pointer(regs) \
  38008. - ((regs)->sp)
  38009. + (!compat_user_mode(regs)) ? ((regs)->sp) : ((regs)->compat_sp)
  38010. +
  38011. +static inline unsigned long regs_return_value(struct pt_regs *regs)
  38012. +{
  38013. + return regs->regs[0];
  38014. +}
  38015. /*
  38016. * Are the current registers suitable for user mode? (used to maintain
  38017. @@ -164,7 +170,7 @@
  38018. return 0;
  38019. }
  38020. -#define instruction_pointer(regs) (regs)->pc
  38021. +#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
  38022. #ifdef CONFIG_SMP
  38023. extern unsigned long profile_pc(struct pt_regs *regs);
  38024. diff -Nur linux-3.14.15/arch/arm64/include/asm/syscall.h linux-linaro-stable-mx6/arch/arm64/include/asm/syscall.h
  38025. --- linux-3.14.15/arch/arm64/include/asm/syscall.h 2014-07-31 23:51:43.000000000 +0200
  38026. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/syscall.h 2014-08-20 19:31:40.588845224 +0200
  38027. @@ -18,6 +18,7 @@
  38028. #include <linux/err.h>
  38029. +extern const void *sys_call_table[];
  38030. static inline int syscall_get_nr(struct task_struct *task,
  38031. struct pt_regs *regs)
  38032. diff -Nur linux-3.14.15/arch/arm64/include/asm/thread_info.h linux-linaro-stable-mx6/arch/arm64/include/asm/thread_info.h
  38033. --- linux-3.14.15/arch/arm64/include/asm/thread_info.h 2014-07-31 23:51:43.000000000 +0200
  38034. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/thread_info.h 2014-08-20 19:31:40.588845224 +0200
  38035. @@ -91,6 +91,9 @@
  38036. /*
  38037. * thread information flags:
  38038. * TIF_SYSCALL_TRACE - syscall trace active
  38039. + * TIF_SYSCALL_TRACEPOINT - syscall tracepoint for ftrace
  38040. + * TIF_SYSCALL_AUDIT - syscall auditing
  38041. + * TIF_SECOMP - syscall secure computing
  38042. * TIF_SIGPENDING - signal pending
  38043. * TIF_NEED_RESCHED - rescheduling necessary
  38044. * TIF_NOTIFY_RESUME - callback before returning to user
  38045. @@ -101,6 +104,9 @@
  38046. #define TIF_NEED_RESCHED 1
  38047. #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
  38048. #define TIF_SYSCALL_TRACE 8
  38049. +#define TIF_SYSCALL_AUDIT 9
  38050. +#define TIF_SYSCALL_TRACEPOINT 10
  38051. +#define TIF_SECCOMP 11
  38052. #define TIF_POLLING_NRFLAG 16
  38053. #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
  38054. #define TIF_FREEZE 19
  38055. @@ -112,10 +118,17 @@
  38056. #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
  38057. #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
  38058. #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
  38059. +#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
  38060. +#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
  38061. +#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
  38062. +#define _TIF_SECCOMP (1 << TIF_SECCOMP)
  38063. #define _TIF_32BIT (1 << TIF_32BIT)
  38064. #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
  38065. _TIF_NOTIFY_RESUME)
  38066. +#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
  38067. + _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
  38068. +
  38069. #endif /* __KERNEL__ */
  38070. #endif /* __ASM_THREAD_INFO_H */
  38071. diff -Nur linux-3.14.15/arch/arm64/include/asm/topology.h linux-linaro-stable-mx6/arch/arm64/include/asm/topology.h
  38072. --- linux-3.14.15/arch/arm64/include/asm/topology.h 1970-01-01 01:00:00.000000000 +0100
  38073. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/topology.h 2014-08-20 19:31:40.592845242 +0200
  38074. @@ -0,0 +1,70 @@
  38075. +#ifndef __ASM_TOPOLOGY_H
  38076. +#define __ASM_TOPOLOGY_H
  38077. +
  38078. +#ifdef CONFIG_SMP
  38079. +
  38080. +#include <linux/cpumask.h>
  38081. +
  38082. +struct cpu_topology {
  38083. + int thread_id;
  38084. + int core_id;
  38085. + int cluster_id;
  38086. + cpumask_t thread_sibling;
  38087. + cpumask_t core_sibling;
  38088. +};
  38089. +
  38090. +extern struct cpu_topology cpu_topology[NR_CPUS];
  38091. +
  38092. +#define topology_physical_package_id(cpu) (cpu_topology[cpu].cluster_id)
  38093. +#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
  38094. +#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
  38095. +#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)
  38096. +
  38097. +#define mc_capable() (cpu_topology[0].cluster_id != -1)
  38098. +#define smt_capable() (cpu_topology[0].thread_id != -1)
  38099. +
  38100. +void init_cpu_topology(void);
  38101. +void store_cpu_topology(unsigned int cpuid);
  38102. +const struct cpumask *cpu_coregroup_mask(int cpu);
  38103. +
  38104. +#ifdef CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE
  38105. +/* Common values for CPUs */
  38106. +#ifndef SD_CPU_INIT
  38107. +#define SD_CPU_INIT (struct sched_domain) { \
  38108. + .min_interval = 1, \
  38109. + .max_interval = 4, \
  38110. + .busy_factor = 64, \
  38111. + .imbalance_pct = 125, \
  38112. + .cache_nice_tries = 1, \
  38113. + .busy_idx = 2, \
  38114. + .idle_idx = 1, \
  38115. + .newidle_idx = 0, \
  38116. + .wake_idx = 0, \
  38117. + .forkexec_idx = 0, \
  38118. + \
  38119. + .flags = 0*SD_LOAD_BALANCE \
  38120. + | 1*SD_BALANCE_NEWIDLE \
  38121. + | 1*SD_BALANCE_EXEC \
  38122. + | 1*SD_BALANCE_FORK \
  38123. + | 0*SD_BALANCE_WAKE \
  38124. + | 1*SD_WAKE_AFFINE \
  38125. + | 0*SD_SHARE_CPUPOWER \
  38126. + | 0*SD_SHARE_PKG_RESOURCES \
  38127. + | 0*SD_SERIALIZE \
  38128. + , \
  38129. + .last_balance = jiffies, \
  38130. + .balance_interval = 1, \
  38131. +}
  38132. +#endif
  38133. +#endif /* CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE */
  38134. +
  38135. +#else
  38136. +
  38137. +static inline void init_cpu_topology(void) { }
  38138. +static inline void store_cpu_topology(unsigned int cpuid) { }
  38139. +
  38140. +#endif
  38141. +
  38142. +#include <asm-generic/topology.h>
  38143. +
  38144. +#endif /* _ASM_ARM_TOPOLOGY_H */
  38145. diff -Nur linux-3.14.15/arch/arm64/include/asm/unistd.h linux-linaro-stable-mx6/arch/arm64/include/asm/unistd.h
  38146. --- linux-3.14.15/arch/arm64/include/asm/unistd.h 2014-07-31 23:51:43.000000000 +0200
  38147. +++ linux-linaro-stable-mx6/arch/arm64/include/asm/unistd.h 2014-08-20 19:31:40.592845242 +0200
  38148. @@ -28,3 +28,5 @@
  38149. #endif
  38150. #define __ARCH_WANT_SYS_CLONE
  38151. #include <uapi/asm/unistd.h>
  38152. +
  38153. +#define NR_syscalls (__NR_syscalls)
  38154. diff -Nur linux-3.14.15/arch/arm64/include/uapi/asm/Kbuild linux-linaro-stable-mx6/arch/arm64/include/uapi/asm/Kbuild
  38155. --- linux-3.14.15/arch/arm64/include/uapi/asm/Kbuild 2014-07-31 23:51:43.000000000 +0200
  38156. +++ linux-linaro-stable-mx6/arch/arm64/include/uapi/asm/Kbuild 2014-08-20 19:31:40.596845260 +0200
  38157. @@ -9,6 +9,7 @@
  38158. header-y += fcntl.h
  38159. header-y += hwcap.h
  38160. header-y += kvm_para.h
  38161. +header-y += perf_regs.h
  38162. header-y += param.h
  38163. header-y += ptrace.h
  38164. header-y += setup.h
  38165. diff -Nur linux-3.14.15/arch/arm64/include/uapi/asm/perf_regs.h linux-linaro-stable-mx6/arch/arm64/include/uapi/asm/perf_regs.h
  38166. --- linux-3.14.15/arch/arm64/include/uapi/asm/perf_regs.h 1970-01-01 01:00:00.000000000 +0100
  38167. +++ linux-linaro-stable-mx6/arch/arm64/include/uapi/asm/perf_regs.h 2014-08-20 19:31:40.600845277 +0200
  38168. @@ -0,0 +1,40 @@
  38169. +#ifndef _ASM_ARM64_PERF_REGS_H
  38170. +#define _ASM_ARM64_PERF_REGS_H
  38171. +
  38172. +enum perf_event_arm_regs {
  38173. + PERF_REG_ARM64_X0,
  38174. + PERF_REG_ARM64_X1,
  38175. + PERF_REG_ARM64_X2,
  38176. + PERF_REG_ARM64_X3,
  38177. + PERF_REG_ARM64_X4,
  38178. + PERF_REG_ARM64_X5,
  38179. + PERF_REG_ARM64_X6,
  38180. + PERF_REG_ARM64_X7,
  38181. + PERF_REG_ARM64_X8,
  38182. + PERF_REG_ARM64_X9,
  38183. + PERF_REG_ARM64_X10,
  38184. + PERF_REG_ARM64_X11,
  38185. + PERF_REG_ARM64_X12,
  38186. + PERF_REG_ARM64_X13,
  38187. + PERF_REG_ARM64_X14,
  38188. + PERF_REG_ARM64_X15,
  38189. + PERF_REG_ARM64_X16,
  38190. + PERF_REG_ARM64_X17,
  38191. + PERF_REG_ARM64_X18,
  38192. + PERF_REG_ARM64_X19,
  38193. + PERF_REG_ARM64_X20,
  38194. + PERF_REG_ARM64_X21,
  38195. + PERF_REG_ARM64_X22,
  38196. + PERF_REG_ARM64_X23,
  38197. + PERF_REG_ARM64_X24,
  38198. + PERF_REG_ARM64_X25,
  38199. + PERF_REG_ARM64_X26,
  38200. + PERF_REG_ARM64_X27,
  38201. + PERF_REG_ARM64_X28,
  38202. + PERF_REG_ARM64_X29,
  38203. + PERF_REG_ARM64_LR,
  38204. + PERF_REG_ARM64_SP,
  38205. + PERF_REG_ARM64_PC,
  38206. + PERF_REG_ARM64_MAX,
  38207. +};
  38208. +#endif /* _ASM_ARM64_PERF_REGS_H */
  38209. diff -Nur linux-3.14.15/arch/arm64/Kconfig linux-linaro-stable-mx6/arch/arm64/Kconfig
  38210. --- linux-3.14.15/arch/arm64/Kconfig 2014-07-31 23:51:43.000000000 +0200
  38211. +++ linux-linaro-stable-mx6/arch/arm64/Kconfig 2014-08-20 19:31:40.480844761 +0200
  38212. @@ -4,6 +4,7 @@
  38213. select ARCH_USE_CMPXCHG_LOCKREF
  38214. select ARCH_SUPPORTS_ATOMIC_RMW
  38215. select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
  38216. + select ARCH_HAS_OPP
  38217. select ARCH_WANT_OPTIONAL_GPIOLIB
  38218. select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
  38219. select ARCH_WANT_FRAME_POINTERS
  38220. @@ -17,6 +18,7 @@
  38221. select DCACHE_WORD_ACCESS
  38222. select GENERIC_CLOCKEVENTS
  38223. select GENERIC_CLOCKEVENTS_BROADCAST if SMP
  38224. + select GENERIC_CPU_AUTOPROBE
  38225. select GENERIC_IOMAP
  38226. select GENERIC_IRQ_PROBE
  38227. select GENERIC_IRQ_SHOW
  38228. @@ -27,18 +29,27 @@
  38229. select GENERIC_TIME_VSYSCALL
  38230. select HARDIRQS_SW_RESEND
  38231. select HAVE_ARCH_JUMP_LABEL
  38232. + select HAVE_ARCH_KGDB
  38233. select HAVE_ARCH_TRACEHOOK
  38234. + select HAVE_C_RECORDMCOUNT
  38235. select HAVE_DEBUG_BUGVERBOSE
  38236. select HAVE_DEBUG_KMEMLEAK
  38237. select HAVE_DMA_API_DEBUG
  38238. select HAVE_DMA_ATTRS
  38239. select HAVE_DMA_CONTIGUOUS
  38240. select HAVE_EFFICIENT_UNALIGNED_ACCESS
  38241. + select HAVE_DYNAMIC_FTRACE
  38242. + select HAVE_FTRACE_MCOUNT_RECORD
  38243. + select HAVE_FUNCTION_TRACER
  38244. + select HAVE_FUNCTION_GRAPH_TRACER
  38245. select HAVE_GENERIC_DMA_COHERENT
  38246. select HAVE_HW_BREAKPOINT if PERF_EVENTS
  38247. select HAVE_MEMBLOCK
  38248. select HAVE_PATA_PLATFORM
  38249. select HAVE_PERF_EVENTS
  38250. + select HAVE_PERF_REGS
  38251. + select HAVE_PERF_USER_STACK_DUMP
  38252. + select HAVE_SYSCALL_TRACEPOINTS
  38253. select IRQ_DOMAIN
  38254. select MODULES_USE_ELF_RELA
  38255. select NO_BOOTMEM
  38256. @@ -86,7 +97,7 @@
  38257. config GENERIC_CALIBRATE_DELAY
  38258. def_bool y
  38259. -config ZONE_DMA32
  38260. +config ZONE_DMA
  38261. def_bool y
  38262. config ARCH_DMA_ADDR_T_64BIT
  38263. @@ -165,6 +176,134 @@
  38264. If you don't know what to do here, say N.
  38265. +config SCHED_MC
  38266. + bool "Multi-core scheduler support"
  38267. + depends on SMP
  38268. + help
  38269. + Multi-core scheduler support improves the CPU scheduler's decision
  38270. + making when dealing with multi-core CPU chips at a cost of slightly
  38271. + increased overhead in some places. If unsure say N here.
  38272. +
  38273. +config SCHED_SMT
  38274. + bool "SMT scheduler support"
  38275. + depends on SMP
  38276. + help
  38277. + Improves the CPU scheduler's decision making when dealing with
  38278. + MultiThreading at a cost of slightly increased overhead in some
  38279. + places. If unsure say N here.
  38280. +
  38281. +config SCHED_MC
  38282. + bool "Multi-core scheduler support"
  38283. + depends on ARM_CPU_TOPOLOGY
  38284. + help
  38285. + Multi-core scheduler support improves the CPU scheduler's decision
  38286. + making when dealing with multi-core CPU chips at a cost of slightly
  38287. + increased overhead in some places. If unsure say N here.
  38288. +
  38289. +config SCHED_SMT
  38290. + bool "SMT scheduler support"
  38291. + depends on ARM_CPU_TOPOLOGY
  38292. + help
  38293. + Improves the CPU scheduler's decision making when dealing with
  38294. + MultiThreading at a cost of slightly increased overhead in some
  38295. + places. If unsure say N here.
  38296. +
  38297. +config DISABLE_CPU_SCHED_DOMAIN_BALANCE
  38298. + bool "(EXPERIMENTAL) Disable CPU level scheduler load-balancing"
  38299. + help
  38300. + Disables scheduler load-balancing at CPU sched domain level.
  38301. +
  38302. +config SCHED_HMP
  38303. + bool "(EXPERIMENTAL) Heterogenous multiprocessor scheduling"
  38304. + depends on DISABLE_CPU_SCHED_DOMAIN_BALANCE && SCHED_MC && FAIR_GROUP_SCHED && !SCHED_AUTOGROUP
  38305. + help
  38306. + Experimental scheduler optimizations for heterogeneous platforms.
  38307. + Attempts to introspectively select task affinity to optimize power
  38308. + and performance. Basic support for multiple (>2) cpu types is in place,
  38309. + but it has only been tested with two types of cpus.
  38310. + There is currently no support for migration of task groups, hence
  38311. + !SCHED_AUTOGROUP. Furthermore, normal load-balancing must be disabled
  38312. + between cpus of different type (DISABLE_CPU_SCHED_DOMAIN_BALANCE).
  38313. +
  38314. +config SCHED_HMP_PRIO_FILTER
  38315. + bool "(EXPERIMENTAL) Filter HMP migrations by task priority"
  38316. + depends on SCHED_HMP
  38317. + help
  38318. + Enables task priority based HMP migration filter. Any task with
  38319. + a NICE value above the threshold will always be on low-power cpus
  38320. + with less compute capacity.
  38321. +
  38322. +config SCHED_HMP_PRIO_FILTER_VAL
  38323. + int "NICE priority threshold"
  38324. + default 5
  38325. + depends on SCHED_HMP_PRIO_FILTER
  38326. +
  38327. +config HMP_FAST_CPU_MASK
  38328. + string "HMP scheduler fast CPU mask"
  38329. + depends on SCHED_HMP
  38330. + help
  38331. + Leave empty to use device tree information.
  38332. + Specify the cpuids of the fast CPUs in the system as a list string,
  38333. + e.g. cpuid 0+1 should be specified as 0-1.
  38334. +
  38335. +config HMP_SLOW_CPU_MASK
  38336. + string "HMP scheduler slow CPU mask"
  38337. + depends on SCHED_HMP
  38338. + help
  38339. + Leave empty to use device tree information.
  38340. + Specify the cpuids of the slow CPUs in the system as a list string,
  38341. + e.g. cpuid 0+1 should be specified as 0-1.
  38342. +
  38343. +config HMP_VARIABLE_SCALE
  38344. + bool "Allows changing the load tracking scale through sysfs"
  38345. + depends on SCHED_HMP
  38346. + help
  38347. + When turned on, this option exports the thresholds and load average
  38348. + period value for the load tracking patches through sysfs.
  38349. + The values can be modified to change the rate of load accumulation
  38350. + and the thresholds used for HMP migration.
  38351. + The load_avg_period_ms is the time in ms to reach a load average of
  38352. + 0.5 for an idle task of 0 load average ratio that start a busy loop.
  38353. + The up_threshold and down_threshold is the value to go to a faster
  38354. + CPU or to go back to a slower cpu.
  38355. + The {up,down}_threshold are devided by 1024 before being compared
  38356. + to the load average.
  38357. + For examples, with load_avg_period_ms = 128 and up_threshold = 512,
  38358. + a running task with a load of 0 will be migrated to a bigger CPU after
  38359. + 128ms, because after 128ms its load_avg_ratio is 0.5 and the real
  38360. + up_threshold is 0.5.
  38361. + This patch has the same behavior as changing the Y of the load
  38362. + average computation to
  38363. + (1002/1024)^(LOAD_AVG_PERIOD/load_avg_period_ms)
  38364. + but it remove intermadiate overflows in computation.
  38365. +
  38366. +config HMP_FREQUENCY_INVARIANT_SCALE
  38367. + bool "(EXPERIMENTAL) Frequency-Invariant Tracked Load for HMP"
  38368. + depends on HMP_VARIABLE_SCALE && CPU_FREQ
  38369. + help
  38370. + Scales the current load contribution in line with the frequency
  38371. + of the CPU that the task was executed on.
  38372. + In this version, we use a simple linear scale derived from the
  38373. + maximum frequency reported by CPUFreq.
  38374. + Restricting tracked load to be scaled by the CPU's frequency
  38375. + represents the consumption of possible compute capacity
  38376. + (rather than consumption of actual instantaneous capacity as
  38377. + normal) and allows the HMP migration's simple threshold
  38378. + migration strategy to interact more predictably with CPUFreq's
  38379. + asynchronous compute capacity changes.
  38380. +
  38381. +config SCHED_HMP_LITTLE_PACKING
  38382. + bool "Small task packing for HMP"
  38383. + depends on SCHED_HMP
  38384. + default n
  38385. + help
  38386. + Allows the HMP Scheduler to pack small tasks into CPUs in the
  38387. + smallest HMP domain.
  38388. + Controlled by two sysfs files in sys/kernel/hmp.
  38389. + packing_enable: 1 to enable, 0 to disable packing. Default 1.
  38390. + packing_limit: runqueue load ratio where a RQ is considered
  38391. + to be full. Default is NICE_0_LOAD * 9/8.
  38392. +
  38393. config NR_CPUS
  38394. int "Maximum number of CPUs (2-32)"
  38395. range 2 32
  38396. @@ -317,5 +456,8 @@
  38397. source "security/Kconfig"
  38398. source "crypto/Kconfig"
  38399. +if CRYPTO
  38400. +source "arch/arm64/crypto/Kconfig"
  38401. +endif
  38402. source "lib/Kconfig"
  38403. diff -Nur linux-3.14.15/arch/arm64/kernel/arm64ksyms.c linux-linaro-stable-mx6/arch/arm64/kernel/arm64ksyms.c
  38404. --- linux-3.14.15/arch/arm64/kernel/arm64ksyms.c 2014-07-31 23:51:43.000000000 +0200
  38405. +++ linux-linaro-stable-mx6/arch/arm64/kernel/arm64ksyms.c 2014-08-20 19:31:40.600845277 +0200
  38406. @@ -56,3 +56,7 @@
  38407. EXPORT_SYMBOL(test_and_clear_bit);
  38408. EXPORT_SYMBOL(change_bit);
  38409. EXPORT_SYMBOL(test_and_change_bit);
  38410. +
  38411. +#ifdef CONFIG_FUNCTION_TRACER
  38412. +EXPORT_SYMBOL(_mcount);
  38413. +#endif
  38414. diff -Nur linux-3.14.15/arch/arm64/kernel/debug-monitors.c linux-linaro-stable-mx6/arch/arm64/kernel/debug-monitors.c
  38415. --- linux-3.14.15/arch/arm64/kernel/debug-monitors.c 2014-07-31 23:51:43.000000000 +0200
  38416. +++ linux-linaro-stable-mx6/arch/arm64/kernel/debug-monitors.c 2014-08-20 19:31:40.600845277 +0200
  38417. @@ -138,6 +138,7 @@
  38418. {
  38419. asm volatile("msr oslar_el1, %0" : : "r" (0));
  38420. isb();
  38421. + local_dbg_enable();
  38422. }
  38423. static int os_lock_notify(struct notifier_block *self,
  38424. @@ -314,9 +315,6 @@
  38425. if (call_break_hook(regs, esr) == DBG_HOOK_HANDLED)
  38426. return 0;
  38427. - pr_warn("unexpected brk exception at %lx, esr=0x%x\n",
  38428. - (long)instruction_pointer(regs), esr);
  38429. -
  38430. if (!user_mode(regs))
  38431. return -EFAULT;
  38432. diff -Nur linux-3.14.15/arch/arm64/kernel/entry-ftrace.S linux-linaro-stable-mx6/arch/arm64/kernel/entry-ftrace.S
  38433. --- linux-3.14.15/arch/arm64/kernel/entry-ftrace.S 1970-01-01 01:00:00.000000000 +0100
  38434. +++ linux-linaro-stable-mx6/arch/arm64/kernel/entry-ftrace.S 2014-08-20 19:31:40.600845277 +0200
  38435. @@ -0,0 +1,218 @@
  38436. +/*
  38437. + * arch/arm64/kernel/entry-ftrace.S
  38438. + *
  38439. + * Copyright (C) 2013 Linaro Limited
  38440. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  38441. + *
  38442. + * This program is free software; you can redistribute it and/or modify
  38443. + * it under the terms of the GNU General Public License version 2 as
  38444. + * published by the Free Software Foundation.
  38445. + */
  38446. +
  38447. +#include <linux/linkage.h>
  38448. +#include <asm/ftrace.h>
  38449. +#include <asm/insn.h>
  38450. +
  38451. +/*
  38452. + * Gcc with -pg will put the following code in the beginning of each function:
  38453. + * mov x0, x30
  38454. + * bl _mcount
  38455. + * [function's body ...]
  38456. + * "bl _mcount" may be replaced to "bl ftrace_caller" or NOP if dynamic
  38457. + * ftrace is enabled.
  38458. + *
  38459. + * Please note that x0 as an argument will not be used here because we can
  38460. + * get lr(x30) of instrumented function at any time by winding up call stack
  38461. + * as long as the kernel is compiled without -fomit-frame-pointer.
  38462. + * (or CONFIG_FRAME_POINTER, this is forced on arm64)
  38463. + *
  38464. + * stack layout after mcount_enter in _mcount():
  38465. + *
  38466. + * current sp/fp => 0:+-----+
  38467. + * in _mcount() | x29 | -> instrumented function's fp
  38468. + * +-----+
  38469. + * | x30 | -> _mcount()'s lr (= instrumented function's pc)
  38470. + * old sp => +16:+-----+
  38471. + * when instrumented | |
  38472. + * function calls | ... |
  38473. + * _mcount() | |
  38474. + * | |
  38475. + * instrumented => +xx:+-----+
  38476. + * function's fp | x29 | -> parent's fp
  38477. + * +-----+
  38478. + * | x30 | -> instrumented function's lr (= parent's pc)
  38479. + * +-----+
  38480. + * | ... |
  38481. + */
  38482. +
  38483. + .macro mcount_enter
  38484. + stp x29, x30, [sp, #-16]!
  38485. + mov x29, sp
  38486. + .endm
  38487. +
  38488. + .macro mcount_exit
  38489. + ldp x29, x30, [sp], #16
  38490. + ret
  38491. + .endm
  38492. +
  38493. + .macro mcount_adjust_addr rd, rn
  38494. + sub \rd, \rn, #AARCH64_INSN_SIZE
  38495. + .endm
  38496. +
  38497. + /* for instrumented function's parent */
  38498. + .macro mcount_get_parent_fp reg
  38499. + ldr \reg, [x29]
  38500. + ldr \reg, [\reg]
  38501. + .endm
  38502. +
  38503. + /* for instrumented function */
  38504. + .macro mcount_get_pc0 reg
  38505. + mcount_adjust_addr \reg, x30
  38506. + .endm
  38507. +
  38508. + .macro mcount_get_pc reg
  38509. + ldr \reg, [x29, #8]
  38510. + mcount_adjust_addr \reg, \reg
  38511. + .endm
  38512. +
  38513. + .macro mcount_get_lr reg
  38514. + ldr \reg, [x29]
  38515. + ldr \reg, [\reg, #8]
  38516. + mcount_adjust_addr \reg, \reg
  38517. + .endm
  38518. +
  38519. + .macro mcount_get_lr_addr reg
  38520. + ldr \reg, [x29]
  38521. + add \reg, \reg, #8
  38522. + .endm
  38523. +
  38524. +#ifndef CONFIG_DYNAMIC_FTRACE
  38525. +/*
  38526. + * void _mcount(unsigned long return_address)
  38527. + * @return_address: return address to instrumented function
  38528. + *
  38529. + * This function makes calls, if enabled, to:
  38530. + * - tracer function to probe instrumented function's entry,
  38531. + * - ftrace_graph_caller to set up an exit hook
  38532. + */
  38533. +ENTRY(_mcount)
  38534. +#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
  38535. + ldr x0, =ftrace_trace_stop
  38536. + ldr x0, [x0] // if ftrace_trace_stop
  38537. + ret // return;
  38538. +#endif
  38539. + mcount_enter
  38540. +
  38541. + ldr x0, =ftrace_trace_function
  38542. + ldr x2, [x0]
  38543. + adr x0, ftrace_stub
  38544. + cmp x0, x2 // if (ftrace_trace_function
  38545. + b.eq skip_ftrace_call // != ftrace_stub) {
  38546. +
  38547. + mcount_get_pc x0 // function's pc
  38548. + mcount_get_lr x1 // function's lr (= parent's pc)
  38549. + blr x2 // (*ftrace_trace_function)(pc, lr);
  38550. +
  38551. +#ifndef CONFIG_FUNCTION_GRAPH_TRACER
  38552. +skip_ftrace_call: // return;
  38553. + mcount_exit // }
  38554. +#else
  38555. + mcount_exit // return;
  38556. + // }
  38557. +skip_ftrace_call:
  38558. + ldr x1, =ftrace_graph_return
  38559. + ldr x2, [x1] // if ((ftrace_graph_return
  38560. + cmp x0, x2 // != ftrace_stub)
  38561. + b.ne ftrace_graph_caller
  38562. +
  38563. + ldr x1, =ftrace_graph_entry // || (ftrace_graph_entry
  38564. + ldr x2, [x1] // != ftrace_graph_entry_stub))
  38565. + ldr x0, =ftrace_graph_entry_stub
  38566. + cmp x0, x2
  38567. + b.ne ftrace_graph_caller // ftrace_graph_caller();
  38568. +
  38569. + mcount_exit
  38570. +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  38571. +ENDPROC(_mcount)
  38572. +
  38573. +#else /* CONFIG_DYNAMIC_FTRACE */
  38574. +/*
  38575. + * _mcount() is used to build the kernel with -pg option, but all the branch
  38576. + * instructions to _mcount() are replaced to NOP initially at kernel start up,
  38577. + * and later on, NOP to branch to ftrace_caller() when enabled or branch to
  38578. + * NOP when disabled per-function base.
  38579. + */
  38580. +ENTRY(_mcount)
  38581. + ret
  38582. +ENDPROC(_mcount)
  38583. +
  38584. +/*
  38585. + * void ftrace_caller(unsigned long return_address)
  38586. + * @return_address: return address to instrumented function
  38587. + *
  38588. + * This function is a counterpart of _mcount() in 'static' ftrace, and
  38589. + * makes calls to:
  38590. + * - tracer function to probe instrumented function's entry,
  38591. + * - ftrace_graph_caller to set up an exit hook
  38592. + */
  38593. +ENTRY(ftrace_caller)
  38594. + mcount_enter
  38595. +
  38596. + mcount_get_pc0 x0 // function's pc
  38597. + mcount_get_lr x1 // function's lr
  38598. +
  38599. + .global ftrace_call
  38600. +ftrace_call: // tracer(pc, lr);
  38601. + nop // This will be replaced with "bl xxx"
  38602. + // where xxx can be any kind of tracer.
  38603. +
  38604. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  38605. + .global ftrace_graph_call
  38606. +ftrace_graph_call: // ftrace_graph_caller();
  38607. + nop // If enabled, this will be replaced
  38608. + // "b ftrace_graph_caller"
  38609. +#endif
  38610. +
  38611. + mcount_exit
  38612. +ENDPROC(ftrace_caller)
  38613. +#endif /* CONFIG_DYNAMIC_FTRACE */
  38614. +
  38615. +ENTRY(ftrace_stub)
  38616. + ret
  38617. +ENDPROC(ftrace_stub)
  38618. +
  38619. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  38620. +/*
  38621. + * void ftrace_graph_caller(void)
  38622. + *
  38623. + * Called from _mcount() or ftrace_caller() when function_graph tracer is
  38624. + * selected.
  38625. + * This function w/ prepare_ftrace_return() fakes link register's value on
  38626. + * the call stack in order to intercept instrumented function's return path
  38627. + * and run return_to_handler() later on its exit.
  38628. + */
  38629. +ENTRY(ftrace_graph_caller)
  38630. + mcount_get_lr_addr x0 // pointer to function's saved lr
  38631. + mcount_get_pc x1 // function's pc
  38632. + mcount_get_parent_fp x2 // parent's fp
  38633. + bl prepare_ftrace_return // prepare_ftrace_return(&lr, pc, fp)
  38634. +
  38635. + mcount_exit
  38636. +ENDPROC(ftrace_graph_caller)
  38637. +
  38638. +/*
  38639. + * void return_to_handler(void)
  38640. + *
  38641. + * Run ftrace_return_to_handler() before going back to parent.
  38642. + * @fp is checked against the value passed by ftrace_graph_caller()
  38643. + * only when CONFIG_FUNCTION_GRAPH_FP_TEST is enabled.
  38644. + */
  38645. +ENTRY(return_to_handler)
  38646. + str x0, [sp, #-16]!
  38647. + mov x0, x29 // parent's fp
  38648. + bl ftrace_return_to_handler// addr = ftrace_return_to_hander(fp);
  38649. + mov x30, x0 // restore the original return address
  38650. + ldr x0, [sp], #16
  38651. + ret
  38652. +END(return_to_handler)
  38653. +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  38654. diff -Nur linux-3.14.15/arch/arm64/kernel/entry.S linux-linaro-stable-mx6/arch/arm64/kernel/entry.S
  38655. --- linux-3.14.15/arch/arm64/kernel/entry.S 2014-07-31 23:51:43.000000000 +0200
  38656. +++ linux-linaro-stable-mx6/arch/arm64/kernel/entry.S 2014-08-20 19:31:40.600845277 +0200
  38657. @@ -630,8 +630,9 @@
  38658. enable_irq
  38659. get_thread_info tsk
  38660. - ldr x16, [tsk, #TI_FLAGS] // check for syscall tracing
  38661. - tbnz x16, #TIF_SYSCALL_TRACE, __sys_trace // are we tracing syscalls?
  38662. + ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks
  38663. + tst x16, #_TIF_SYSCALL_WORK
  38664. + b.ne __sys_trace
  38665. adr lr, ret_fast_syscall // return address
  38666. cmp scno, sc_nr // check upper syscall limit
  38667. b.hs ni_sys
  38668. @@ -647,9 +648,8 @@
  38669. * switches, and waiting for our parent to respond.
  38670. */
  38671. __sys_trace:
  38672. - mov x1, sp
  38673. - mov w0, #0 // trace entry
  38674. - bl syscall_trace
  38675. + mov x0, sp
  38676. + bl syscall_trace_enter
  38677. adr lr, __sys_trace_return // return address
  38678. uxtw scno, w0 // syscall number (possibly new)
  38679. mov x1, sp // pointer to regs
  38680. @@ -664,9 +664,8 @@
  38681. __sys_trace_return:
  38682. str x0, [sp] // save returned x0
  38683. - mov x1, sp
  38684. - mov w0, #1 // trace exit
  38685. - bl syscall_trace
  38686. + mov x0, sp
  38687. + bl syscall_trace_exit
  38688. b ret_to_user
  38689. /*
  38690. diff -Nur linux-3.14.15/arch/arm64/kernel/ftrace.c linux-linaro-stable-mx6/arch/arm64/kernel/ftrace.c
  38691. --- linux-3.14.15/arch/arm64/kernel/ftrace.c 1970-01-01 01:00:00.000000000 +0100
  38692. +++ linux-linaro-stable-mx6/arch/arm64/kernel/ftrace.c 2014-08-20 19:31:40.600845277 +0200
  38693. @@ -0,0 +1,177 @@
  38694. +/*
  38695. + * arch/arm64/kernel/ftrace.c
  38696. + *
  38697. + * Copyright (C) 2013 Linaro Limited
  38698. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  38699. + *
  38700. + * This program is free software; you can redistribute it and/or modify
  38701. + * it under the terms of the GNU General Public License version 2 as
  38702. + * published by the Free Software Foundation.
  38703. + */
  38704. +
  38705. +#include <linux/ftrace.h>
  38706. +#include <linux/swab.h>
  38707. +#include <linux/uaccess.h>
  38708. +
  38709. +#include <asm/cacheflush.h>
  38710. +#include <asm/ftrace.h>
  38711. +#include <asm/insn.h>
  38712. +
  38713. +#ifdef CONFIG_DYNAMIC_FTRACE
  38714. +/*
  38715. + * Replace a single instruction, which may be a branch or NOP.
  38716. + * If @validate == true, a replaced instruction is checked against 'old'.
  38717. + */
  38718. +static int ftrace_modify_code(unsigned long pc, u32 old, u32 new,
  38719. + bool validate)
  38720. +{
  38721. + u32 replaced;
  38722. +
  38723. + /*
  38724. + * Note:
  38725. + * Due to modules and __init, code can disappear and change,
  38726. + * we need to protect against faulting as well as code changing.
  38727. + * We do this by aarch64_insn_*() which use the probe_kernel_*().
  38728. + *
  38729. + * No lock is held here because all the modifications are run
  38730. + * through stop_machine().
  38731. + */
  38732. + if (validate) {
  38733. + if (aarch64_insn_read((void *)pc, &replaced))
  38734. + return -EFAULT;
  38735. +
  38736. + if (replaced != old)
  38737. + return -EINVAL;
  38738. + }
  38739. + if (aarch64_insn_patch_text_nosync((void *)pc, new))
  38740. + return -EPERM;
  38741. +
  38742. + return 0;
  38743. +}
  38744. +
  38745. +/*
  38746. + * Replace tracer function in ftrace_caller()
  38747. + */
  38748. +int ftrace_update_ftrace_func(ftrace_func_t func)
  38749. +{
  38750. + unsigned long pc;
  38751. + u32 new;
  38752. +
  38753. + pc = (unsigned long)&ftrace_call;
  38754. + new = aarch64_insn_gen_branch_imm(pc, (unsigned long)func, true);
  38755. +
  38756. + return ftrace_modify_code(pc, 0, new, false);
  38757. +}
  38758. +
  38759. +/*
  38760. + * Turn on the call to ftrace_caller() in instrumented function
  38761. + */
  38762. +int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
  38763. +{
  38764. + unsigned long pc = rec->ip;
  38765. + u32 old, new;
  38766. +
  38767. + old = aarch64_insn_gen_nop();
  38768. + new = aarch64_insn_gen_branch_imm(pc, addr, true);
  38769. +
  38770. + return ftrace_modify_code(pc, old, new, true);
  38771. +}
  38772. +
  38773. +/*
  38774. + * Turn off the call to ftrace_caller() in instrumented function
  38775. + */
  38776. +int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
  38777. + unsigned long addr)
  38778. +{
  38779. + unsigned long pc = rec->ip;
  38780. + u32 old, new;
  38781. +
  38782. + old = aarch64_insn_gen_branch_imm(pc, addr, true);
  38783. + new = aarch64_insn_gen_nop();
  38784. +
  38785. + return ftrace_modify_code(pc, old, new, true);
  38786. +}
  38787. +
  38788. +int __init ftrace_dyn_arch_init(void *data)
  38789. +{
  38790. + *(unsigned long *)data = 0;
  38791. + return 0;
  38792. +}
  38793. +#endif /* CONFIG_DYNAMIC_FTRACE */
  38794. +
  38795. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  38796. +/*
  38797. + * function_graph tracer expects ftrace_return_to_handler() to be called
  38798. + * on the way back to parent. For this purpose, this function is called
  38799. + * in _mcount() or ftrace_caller() to replace return address (*parent) on
  38800. + * the call stack to return_to_handler.
  38801. + *
  38802. + * Note that @frame_pointer is used only for sanity check later.
  38803. + */
  38804. +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
  38805. + unsigned long frame_pointer)
  38806. +{
  38807. + unsigned long return_hooker = (unsigned long)&return_to_handler;
  38808. + unsigned long old;
  38809. + struct ftrace_graph_ent trace;
  38810. + int err;
  38811. +
  38812. + if (unlikely(atomic_read(&current->tracing_graph_pause)))
  38813. + return;
  38814. +
  38815. + /*
  38816. + * Note:
  38817. + * No protection against faulting at *parent, which may be seen
  38818. + * on other archs. It's unlikely on AArch64.
  38819. + */
  38820. + old = *parent;
  38821. + *parent = return_hooker;
  38822. +
  38823. + trace.func = self_addr;
  38824. + trace.depth = current->curr_ret_stack + 1;
  38825. +
  38826. + /* Only trace if the calling function expects to */
  38827. + if (!ftrace_graph_entry(&trace)) {
  38828. + *parent = old;
  38829. + return;
  38830. + }
  38831. +
  38832. + err = ftrace_push_return_trace(old, self_addr, &trace.depth,
  38833. + frame_pointer);
  38834. + if (err == -EBUSY) {
  38835. + *parent = old;
  38836. + return;
  38837. + }
  38838. +}
  38839. +
  38840. +#ifdef CONFIG_DYNAMIC_FTRACE
  38841. +/*
  38842. + * Turn on/off the call to ftrace_graph_caller() in ftrace_caller()
  38843. + * depending on @enable.
  38844. + */
  38845. +static int ftrace_modify_graph_caller(bool enable)
  38846. +{
  38847. + unsigned long pc = (unsigned long)&ftrace_graph_call;
  38848. + u32 branch, nop;
  38849. +
  38850. + branch = aarch64_insn_gen_branch_imm(pc,
  38851. + (unsigned long)ftrace_graph_caller, false);
  38852. + nop = aarch64_insn_gen_nop();
  38853. +
  38854. + if (enable)
  38855. + return ftrace_modify_code(pc, nop, branch, true);
  38856. + else
  38857. + return ftrace_modify_code(pc, branch, nop, true);
  38858. +}
  38859. +
  38860. +int ftrace_enable_ftrace_graph_caller(void)
  38861. +{
  38862. + return ftrace_modify_graph_caller(true);
  38863. +}
  38864. +
  38865. +int ftrace_disable_ftrace_graph_caller(void)
  38866. +{
  38867. + return ftrace_modify_graph_caller(false);
  38868. +}
  38869. +#endif /* CONFIG_DYNAMIC_FTRACE */
  38870. +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  38871. diff -Nur linux-3.14.15/arch/arm64/kernel/head.S linux-linaro-stable-mx6/arch/arm64/kernel/head.S
  38872. --- linux-3.14.15/arch/arm64/kernel/head.S 2014-07-31 23:51:43.000000000 +0200
  38873. +++ linux-linaro-stable-mx6/arch/arm64/kernel/head.S 2014-08-20 19:31:40.600845277 +0200
  38874. @@ -26,6 +26,7 @@
  38875. #include <asm/assembler.h>
  38876. #include <asm/ptrace.h>
  38877. #include <asm/asm-offsets.h>
  38878. +#include <asm/cache.h>
  38879. #include <asm/cputype.h>
  38880. #include <asm/memory.h>
  38881. #include <asm/thread_info.h>
  38882. @@ -34,29 +35,17 @@
  38883. #include <asm/page.h>
  38884. #include <asm/virt.h>
  38885. -/*
  38886. - * swapper_pg_dir is the virtual address of the initial page table. We place
  38887. - * the page tables 3 * PAGE_SIZE below KERNEL_RAM_VADDR. The idmap_pg_dir has
  38888. - * 2 pages and is placed below swapper_pg_dir.
  38889. - */
  38890. #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
  38891. #if (KERNEL_RAM_VADDR & 0xfffff) != 0x80000
  38892. #error KERNEL_RAM_VADDR must start at 0xXXX80000
  38893. #endif
  38894. -#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
  38895. -#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
  38896. -
  38897. - .globl swapper_pg_dir
  38898. - .equ swapper_pg_dir, KERNEL_RAM_VADDR - SWAPPER_DIR_SIZE
  38899. -
  38900. - .globl idmap_pg_dir
  38901. - .equ idmap_pg_dir, swapper_pg_dir - IDMAP_DIR_SIZE
  38902. -
  38903. - .macro pgtbl, ttb0, ttb1, phys
  38904. - add \ttb1, \phys, #TEXT_OFFSET - SWAPPER_DIR_SIZE
  38905. - sub \ttb0, \ttb1, #IDMAP_DIR_SIZE
  38906. + .macro pgtbl, ttb0, ttb1, virt_to_phys
  38907. + ldr \ttb1, =swapper_pg_dir
  38908. + ldr \ttb0, =idmap_pg_dir
  38909. + add \ttb1, \ttb1, \virt_to_phys
  38910. + add \ttb0, \ttb0, \virt_to_phys
  38911. .endm
  38912. #ifdef CONFIG_ARM64_64K_PAGES
  38913. @@ -229,7 +218,11 @@
  38914. cmp w20, #BOOT_CPU_MODE_EL2
  38915. b.ne 1f
  38916. add x1, x1, #4
  38917. -1: str w20, [x1] // This CPU has booted in EL1
  38918. +1: dc cvac, x1 // Clean potentially dirty cache line
  38919. + dsb sy
  38920. + str w20, [x1] // This CPU has booted in EL1
  38921. + dc civac, x1 // Clean&invalidate potentially stale cache line
  38922. + dsb sy
  38923. ret
  38924. ENDPROC(set_cpu_boot_mode_flag)
  38925. @@ -240,8 +233,9 @@
  38926. * This is not in .bss, because we set it sufficiently early that the boot-time
  38927. * zeroing of .bss would clobber it.
  38928. */
  38929. - .pushsection .data
  38930. + .pushsection .data..cacheline_aligned
  38931. ENTRY(__boot_cpu_mode)
  38932. + .align L1_CACHE_SHIFT
  38933. .long BOOT_CPU_MODE_EL2
  38934. .long 0
  38935. .popsection
  38936. @@ -298,7 +292,7 @@
  38937. mov x23, x0 // x23=current cpu_table
  38938. cbz x23, __error_p // invalid processor (x23=0)?
  38939. - pgtbl x25, x26, x24 // x25=TTBR0, x26=TTBR1
  38940. + pgtbl x25, x26, x28 // x25=TTBR0, x26=TTBR1
  38941. ldr x12, [x23, #CPU_INFO_SETUP]
  38942. add x12, x12, x28 // __virt_to_phys
  38943. blr x12 // initialise processor
  38944. @@ -340,8 +334,13 @@
  38945. * x27 = *virtual* address to jump to upon completion
  38946. *
  38947. * other registers depend on the function called upon completion
  38948. + *
  38949. + * We align the entire function to the smallest power of two larger than it to
  38950. + * ensure it fits within a single block map entry. Otherwise were PHYS_OFFSET
  38951. + * close to the end of a 512MB or 1GB block we might require an additional
  38952. + * table to map the entire function.
  38953. */
  38954. - .align 6
  38955. + .align 4
  38956. __turn_mmu_on:
  38957. msr sctlr_el1, x0
  38958. isb
  38959. @@ -384,26 +383,18 @@
  38960. * Preserves: tbl, flags
  38961. * Corrupts: phys, start, end, pstate
  38962. */
  38963. - .macro create_block_map, tbl, flags, phys, start, end, idmap=0
  38964. + .macro create_block_map, tbl, flags, phys, start, end
  38965. lsr \phys, \phys, #BLOCK_SHIFT
  38966. - .if \idmap
  38967. - and \start, \phys, #PTRS_PER_PTE - 1 // table index
  38968. - .else
  38969. lsr \start, \start, #BLOCK_SHIFT
  38970. and \start, \start, #PTRS_PER_PTE - 1 // table index
  38971. - .endif
  38972. orr \phys, \flags, \phys, lsl #BLOCK_SHIFT // table entry
  38973. - .ifnc \start,\end
  38974. lsr \end, \end, #BLOCK_SHIFT
  38975. and \end, \end, #PTRS_PER_PTE - 1 // table end index
  38976. - .endif
  38977. 9999: str \phys, [\tbl, \start, lsl #3] // store the entry
  38978. - .ifnc \start,\end
  38979. add \start, \start, #1 // next entry
  38980. add \phys, \phys, #BLOCK_SIZE // next block
  38981. cmp \start, \end
  38982. b.ls 9999b
  38983. - .endif
  38984. .endm
  38985. /*
  38986. @@ -415,7 +406,16 @@
  38987. * - UART mapping if CONFIG_EARLY_PRINTK is enabled (TTBR1)
  38988. */
  38989. __create_page_tables:
  38990. - pgtbl x25, x26, x24 // idmap_pg_dir and swapper_pg_dir addresses
  38991. + pgtbl x25, x26, x28 // idmap_pg_dir and swapper_pg_dir addresses
  38992. + mov x27, lr
  38993. +
  38994. + /*
  38995. + * Invalidate the idmap and swapper page tables to avoid potential
  38996. + * dirty cache lines being evicted.
  38997. + */
  38998. + mov x0, x25
  38999. + add x1, x26, #SWAPPER_DIR_SIZE
  39000. + bl __inval_cache_range
  39001. /*
  39002. * Clear the idmap and swapper page tables.
  39003. @@ -435,9 +435,13 @@
  39004. * Create the identity mapping.
  39005. */
  39006. add x0, x25, #PAGE_SIZE // section table address
  39007. - adr x3, __turn_mmu_on // virtual/physical address
  39008. + ldr x3, =KERNEL_START
  39009. + add x3, x3, x28 // __pa(KERNEL_START)
  39010. create_pgd_entry x25, x0, x3, x5, x6
  39011. - create_block_map x0, x7, x3, x5, x5, idmap=1
  39012. + ldr x6, =KERNEL_END
  39013. + mov x5, x3 // __pa(KERNEL_START)
  39014. + add x6, x6, x28 // __pa(KERNEL_END)
  39015. + create_block_map x0, x7, x3, x5, x6
  39016. /*
  39017. * Map the kernel image (starting with PHYS_OFFSET).
  39018. @@ -445,7 +449,7 @@
  39019. add x0, x26, #PAGE_SIZE // section table address
  39020. mov x5, #PAGE_OFFSET
  39021. create_pgd_entry x26, x0, x5, x3, x6
  39022. - ldr x6, =KERNEL_END - 1
  39023. + ldr x6, =KERNEL_END
  39024. mov x3, x24 // phys offset
  39025. create_block_map x0, x7, x3, x5, x6
  39026. @@ -474,6 +478,17 @@
  39027. add x0, x26, #2 * PAGE_SIZE // section table address
  39028. create_pgd_entry x26, x0, x5, x6, x7
  39029. #endif
  39030. +
  39031. + /*
  39032. + * Since the page tables have been populated with non-cacheable
  39033. + * accesses (MMU disabled), invalidate the idmap and swapper page
  39034. + * tables again to remove any speculatively loaded cache lines.
  39035. + */
  39036. + mov x0, x25
  39037. + add x1, x26, #SWAPPER_DIR_SIZE
  39038. + bl __inval_cache_range
  39039. +
  39040. + mov lr, x27
  39041. ret
  39042. ENDPROC(__create_page_tables)
  39043. .ltorg
  39044. @@ -483,7 +498,7 @@
  39045. __switch_data:
  39046. .quad __mmap_switched
  39047. .quad __bss_start // x6
  39048. - .quad _end // x7
  39049. + .quad __bss_stop // x7
  39050. .quad processor_id // x4
  39051. .quad __fdt_pointer // x5
  39052. .quad memstart_addr // x6
  39053. diff -Nur linux-3.14.15/arch/arm64/kernel/hw_breakpoint.c linux-linaro-stable-mx6/arch/arm64/kernel/hw_breakpoint.c
  39054. --- linux-3.14.15/arch/arm64/kernel/hw_breakpoint.c 2014-07-31 23:51:43.000000000 +0200
  39055. +++ linux-linaro-stable-mx6/arch/arm64/kernel/hw_breakpoint.c 2014-08-20 19:31:40.600845277 +0200
  39056. @@ -20,6 +20,7 @@
  39057. #define pr_fmt(fmt) "hw-breakpoint: " fmt
  39058. +#include <linux/compat.h>
  39059. #include <linux/cpu_pm.h>
  39060. #include <linux/errno.h>
  39061. #include <linux/hw_breakpoint.h>
  39062. @@ -27,7 +28,6 @@
  39063. #include <linux/ptrace.h>
  39064. #include <linux/smp.h>
  39065. -#include <asm/compat.h>
  39066. #include <asm/current.h>
  39067. #include <asm/debug-monitors.h>
  39068. #include <asm/hw_breakpoint.h>
  39069. diff -Nur linux-3.14.15/arch/arm64/kernel/kgdb.c linux-linaro-stable-mx6/arch/arm64/kernel/kgdb.c
  39070. --- linux-3.14.15/arch/arm64/kernel/kgdb.c 1970-01-01 01:00:00.000000000 +0100
  39071. +++ linux-linaro-stable-mx6/arch/arm64/kernel/kgdb.c 2014-08-20 19:31:40.600845277 +0200
  39072. @@ -0,0 +1,336 @@
  39073. +/*
  39074. + * AArch64 KGDB support
  39075. + *
  39076. + * Based on arch/arm/kernel/kgdb.c
  39077. + *
  39078. + * Copyright (C) 2013 Cavium Inc.
  39079. + * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>
  39080. + *
  39081. + * This program is free software; you can redistribute it and/or modify
  39082. + * it under the terms of the GNU General Public License version 2 as
  39083. + * published by the Free Software Foundation.
  39084. + *
  39085. + * This program is distributed in the hope that it will be useful,
  39086. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  39087. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  39088. + * GNU General Public License for more details.
  39089. + *
  39090. + * You should have received a copy of the GNU General Public License
  39091. + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  39092. + */
  39093. +
  39094. +#include <linux/irq.h>
  39095. +#include <linux/kdebug.h>
  39096. +#include <linux/kgdb.h>
  39097. +#include <asm/traps.h>
  39098. +
  39099. +struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
  39100. + { "x0", 8, offsetof(struct pt_regs, regs[0])},
  39101. + { "x1", 8, offsetof(struct pt_regs, regs[1])},
  39102. + { "x2", 8, offsetof(struct pt_regs, regs[2])},
  39103. + { "x3", 8, offsetof(struct pt_regs, regs[3])},
  39104. + { "x4", 8, offsetof(struct pt_regs, regs[4])},
  39105. + { "x5", 8, offsetof(struct pt_regs, regs[5])},
  39106. + { "x6", 8, offsetof(struct pt_regs, regs[6])},
  39107. + { "x7", 8, offsetof(struct pt_regs, regs[7])},
  39108. + { "x8", 8, offsetof(struct pt_regs, regs[8])},
  39109. + { "x9", 8, offsetof(struct pt_regs, regs[9])},
  39110. + { "x10", 8, offsetof(struct pt_regs, regs[10])},
  39111. + { "x11", 8, offsetof(struct pt_regs, regs[11])},
  39112. + { "x12", 8, offsetof(struct pt_regs, regs[12])},
  39113. + { "x13", 8, offsetof(struct pt_regs, regs[13])},
  39114. + { "x14", 8, offsetof(struct pt_regs, regs[14])},
  39115. + { "x15", 8, offsetof(struct pt_regs, regs[15])},
  39116. + { "x16", 8, offsetof(struct pt_regs, regs[16])},
  39117. + { "x17", 8, offsetof(struct pt_regs, regs[17])},
  39118. + { "x18", 8, offsetof(struct pt_regs, regs[18])},
  39119. + { "x19", 8, offsetof(struct pt_regs, regs[19])},
  39120. + { "x20", 8, offsetof(struct pt_regs, regs[20])},
  39121. + { "x21", 8, offsetof(struct pt_regs, regs[21])},
  39122. + { "x22", 8, offsetof(struct pt_regs, regs[22])},
  39123. + { "x23", 8, offsetof(struct pt_regs, regs[23])},
  39124. + { "x24", 8, offsetof(struct pt_regs, regs[24])},
  39125. + { "x25", 8, offsetof(struct pt_regs, regs[25])},
  39126. + { "x26", 8, offsetof(struct pt_regs, regs[26])},
  39127. + { "x27", 8, offsetof(struct pt_regs, regs[27])},
  39128. + { "x28", 8, offsetof(struct pt_regs, regs[28])},
  39129. + { "x29", 8, offsetof(struct pt_regs, regs[29])},
  39130. + { "x30", 8, offsetof(struct pt_regs, regs[30])},
  39131. + { "sp", 8, offsetof(struct pt_regs, sp)},
  39132. + { "pc", 8, offsetof(struct pt_regs, pc)},
  39133. + { "pstate", 8, offsetof(struct pt_regs, pstate)},
  39134. + { "v0", 16, -1 },
  39135. + { "v1", 16, -1 },
  39136. + { "v2", 16, -1 },
  39137. + { "v3", 16, -1 },
  39138. + { "v4", 16, -1 },
  39139. + { "v5", 16, -1 },
  39140. + { "v6", 16, -1 },
  39141. + { "v7", 16, -1 },
  39142. + { "v8", 16, -1 },
  39143. + { "v9", 16, -1 },
  39144. + { "v10", 16, -1 },
  39145. + { "v11", 16, -1 },
  39146. + { "v12", 16, -1 },
  39147. + { "v13", 16, -1 },
  39148. + { "v14", 16, -1 },
  39149. + { "v15", 16, -1 },
  39150. + { "v16", 16, -1 },
  39151. + { "v17", 16, -1 },
  39152. + { "v18", 16, -1 },
  39153. + { "v19", 16, -1 },
  39154. + { "v20", 16, -1 },
  39155. + { "v21", 16, -1 },
  39156. + { "v22", 16, -1 },
  39157. + { "v23", 16, -1 },
  39158. + { "v24", 16, -1 },
  39159. + { "v25", 16, -1 },
  39160. + { "v26", 16, -1 },
  39161. + { "v27", 16, -1 },
  39162. + { "v28", 16, -1 },
  39163. + { "v29", 16, -1 },
  39164. + { "v30", 16, -1 },
  39165. + { "v31", 16, -1 },
  39166. + { "fpsr", 4, -1 },
  39167. + { "fpcr", 4, -1 },
  39168. +};
  39169. +
  39170. +char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
  39171. +{
  39172. + if (regno >= DBG_MAX_REG_NUM || regno < 0)
  39173. + return NULL;
  39174. +
  39175. + if (dbg_reg_def[regno].offset != -1)
  39176. + memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
  39177. + dbg_reg_def[regno].size);
  39178. + else
  39179. + memset(mem, 0, dbg_reg_def[regno].size);
  39180. + return dbg_reg_def[regno].name;
  39181. +}
  39182. +
  39183. +int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
  39184. +{
  39185. + if (regno >= DBG_MAX_REG_NUM || regno < 0)
  39186. + return -EINVAL;
  39187. +
  39188. + if (dbg_reg_def[regno].offset != -1)
  39189. + memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
  39190. + dbg_reg_def[regno].size);
  39191. + return 0;
  39192. +}
  39193. +
  39194. +void
  39195. +sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
  39196. +{
  39197. + struct pt_regs *thread_regs;
  39198. +
  39199. + /* Initialize to zero */
  39200. + memset((char *)gdb_regs, 0, NUMREGBYTES);
  39201. + thread_regs = task_pt_regs(task);
  39202. + memcpy((void *)gdb_regs, (void *)thread_regs->regs, GP_REG_BYTES);
  39203. +}
  39204. +
  39205. +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
  39206. +{
  39207. + regs->pc = pc;
  39208. +}
  39209. +
  39210. +static int compiled_break;
  39211. +
  39212. +static void kgdb_arch_update_addr(struct pt_regs *regs,
  39213. + char *remcom_in_buffer)
  39214. +{
  39215. + unsigned long addr;
  39216. + char *ptr;
  39217. +
  39218. + ptr = &remcom_in_buffer[1];
  39219. + if (kgdb_hex2long(&ptr, &addr))
  39220. + kgdb_arch_set_pc(regs, addr);
  39221. + else if (compiled_break == 1)
  39222. + kgdb_arch_set_pc(regs, regs->pc + 4);
  39223. +
  39224. + compiled_break = 0;
  39225. +}
  39226. +
  39227. +int kgdb_arch_handle_exception(int exception_vector, int signo,
  39228. + int err_code, char *remcom_in_buffer,
  39229. + char *remcom_out_buffer,
  39230. + struct pt_regs *linux_regs)
  39231. +{
  39232. + int err;
  39233. +
  39234. + switch (remcom_in_buffer[0]) {
  39235. + case 'D':
  39236. + case 'k':
  39237. + /*
  39238. + * Packet D (Detach), k (kill). No special handling
  39239. + * is required here. Handle same as c packet.
  39240. + */
  39241. + case 'c':
  39242. + /*
  39243. + * Packet c (Continue) to continue executing.
  39244. + * Set pc to required address.
  39245. + * Try to read optional parameter and set pc.
  39246. + * If this was a compiled breakpoint, we need to move
  39247. + * to the next instruction else we will just breakpoint
  39248. + * over and over again.
  39249. + */
  39250. + kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
  39251. + atomic_set(&kgdb_cpu_doing_single_step, -1);
  39252. + kgdb_single_step = 0;
  39253. +
  39254. + /*
  39255. + * Received continue command, disable single step
  39256. + */
  39257. + if (kernel_active_single_step())
  39258. + kernel_disable_single_step();
  39259. +
  39260. + err = 0;
  39261. + break;
  39262. + case 's':
  39263. + /*
  39264. + * Update step address value with address passed
  39265. + * with step packet.
  39266. + * On debug exception return PC is copied to ELR
  39267. + * So just update PC.
  39268. + * If no step address is passed, resume from the address
  39269. + * pointed by PC. Do not update PC
  39270. + */
  39271. + kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
  39272. + atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id());
  39273. + kgdb_single_step = 1;
  39274. +
  39275. + /*
  39276. + * Enable single step handling
  39277. + */
  39278. + if (!kernel_active_single_step())
  39279. + kernel_enable_single_step(linux_regs);
  39280. + err = 0;
  39281. + break;
  39282. + default:
  39283. + err = -1;
  39284. + }
  39285. + return err;
  39286. +}
  39287. +
  39288. +static int kgdb_brk_fn(struct pt_regs *regs, unsigned int esr)
  39289. +{
  39290. + kgdb_handle_exception(1, SIGTRAP, 0, regs);
  39291. + return 0;
  39292. +}
  39293. +
  39294. +static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
  39295. +{
  39296. + compiled_break = 1;
  39297. + kgdb_handle_exception(1, SIGTRAP, 0, regs);
  39298. +
  39299. + return 0;
  39300. +}
  39301. +
  39302. +static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
  39303. +{
  39304. + kgdb_handle_exception(1, SIGTRAP, 0, regs);
  39305. + return 0;
  39306. +}
  39307. +
  39308. +static struct break_hook kgdb_brkpt_hook = {
  39309. + .esr_mask = 0xffffffff,
  39310. + .esr_val = DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM),
  39311. + .fn = kgdb_brk_fn
  39312. +};
  39313. +
  39314. +static struct break_hook kgdb_compiled_brkpt_hook = {
  39315. + .esr_mask = 0xffffffff,
  39316. + .esr_val = DBG_ESR_VAL_BRK(KDBG_COMPILED_DBG_BRK_IMM),
  39317. + .fn = kgdb_compiled_brk_fn
  39318. +};
  39319. +
  39320. +static struct step_hook kgdb_step_hook = {
  39321. + .fn = kgdb_step_brk_fn
  39322. +};
  39323. +
  39324. +static void kgdb_call_nmi_hook(void *ignored)
  39325. +{
  39326. + kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
  39327. +}
  39328. +
  39329. +void kgdb_roundup_cpus(unsigned long flags)
  39330. +{
  39331. + local_irq_enable();
  39332. + smp_call_function(kgdb_call_nmi_hook, NULL, 0);
  39333. + local_irq_disable();
  39334. +}
  39335. +
  39336. +static int __kgdb_notify(struct die_args *args, unsigned long cmd)
  39337. +{
  39338. + struct pt_regs *regs = args->regs;
  39339. +
  39340. + if (kgdb_handle_exception(1, args->signr, cmd, regs))
  39341. + return NOTIFY_DONE;
  39342. + return NOTIFY_STOP;
  39343. +}
  39344. +
  39345. +static int
  39346. +kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
  39347. +{
  39348. + unsigned long flags;
  39349. + int ret;
  39350. +
  39351. + local_irq_save(flags);
  39352. + ret = __kgdb_notify(ptr, cmd);
  39353. + local_irq_restore(flags);
  39354. +
  39355. + return ret;
  39356. +}
  39357. +
  39358. +static struct notifier_block kgdb_notifier = {
  39359. + .notifier_call = kgdb_notify,
  39360. + /*
  39361. + * Want to be lowest priority
  39362. + */
  39363. + .priority = -INT_MAX,
  39364. +};
  39365. +
  39366. +/*
  39367. + * kgdb_arch_init - Perform any architecture specific initalization.
  39368. + * This function will handle the initalization of any architecture
  39369. + * specific callbacks.
  39370. + */
  39371. +int kgdb_arch_init(void)
  39372. +{
  39373. + int ret = register_die_notifier(&kgdb_notifier);
  39374. +
  39375. + if (ret != 0)
  39376. + return ret;
  39377. +
  39378. + register_break_hook(&kgdb_brkpt_hook);
  39379. + register_break_hook(&kgdb_compiled_brkpt_hook);
  39380. + register_step_hook(&kgdb_step_hook);
  39381. + return 0;
  39382. +}
  39383. +
  39384. +/*
  39385. + * kgdb_arch_exit - Perform any architecture specific uninitalization.
  39386. + * This function will handle the uninitalization of any architecture
  39387. + * specific callbacks, for dynamic registration and unregistration.
  39388. + */
  39389. +void kgdb_arch_exit(void)
  39390. +{
  39391. + unregister_break_hook(&kgdb_brkpt_hook);
  39392. + unregister_break_hook(&kgdb_compiled_brkpt_hook);
  39393. + unregister_step_hook(&kgdb_step_hook);
  39394. + unregister_die_notifier(&kgdb_notifier);
  39395. +}
  39396. +
  39397. +/*
  39398. + * ARM instructions are always in LE.
  39399. + * Break instruction is encoded in LE format
  39400. + */
  39401. +struct kgdb_arch arch_kgdb_ops = {
  39402. + .gdb_bpt_instr = {
  39403. + KGDB_DYN_BRK_INS_BYTE0,
  39404. + KGDB_DYN_BRK_INS_BYTE1,
  39405. + KGDB_DYN_BRK_INS_BYTE2,
  39406. + KGDB_DYN_BRK_INS_BYTE3,
  39407. + }
  39408. +};
  39409. diff -Nur linux-3.14.15/arch/arm64/kernel/Makefile linux-linaro-stable-mx6/arch/arm64/kernel/Makefile
  39410. --- linux-3.14.15/arch/arm64/kernel/Makefile 2014-07-31 23:51:43.000000000 +0200
  39411. +++ linux-linaro-stable-mx6/arch/arm64/kernel/Makefile 2014-08-20 19:31:40.600845277 +0200
  39412. @@ -5,21 +5,29 @@
  39413. CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
  39414. AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
  39415. +CFLAGS_REMOVE_ftrace.o = -pg
  39416. +CFLAGS_REMOVE_insn.o = -pg
  39417. +CFLAGS_REMOVE_return_address.o = -pg
  39418. +
  39419. # Object file lists.
  39420. arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \
  39421. entry-fpsimd.o process.o ptrace.o setup.o signal.o \
  39422. sys.o stacktrace.o time.o traps.o io.o vdso.o \
  39423. - hyp-stub.o psci.o cpu_ops.o insn.o
  39424. + hyp-stub.o psci.o cpu_ops.o insn.o return_address.o
  39425. arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
  39426. sys_compat.o
  39427. +arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
  39428. arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
  39429. +arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o topology.o
  39430. arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o
  39431. +arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
  39432. arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
  39433. -arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
  39434. +arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
  39435. arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  39436. arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o
  39437. arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
  39438. +arm64-obj-$(CONFIG_KGDB) += kgdb.o
  39439. obj-y += $(arm64-obj-y) vdso/
  39440. obj-m += $(arm64-obj-m)
  39441. diff -Nur linux-3.14.15/arch/arm64/kernel/perf_event.c linux-linaro-stable-mx6/arch/arm64/kernel/perf_event.c
  39442. --- linux-3.14.15/arch/arm64/kernel/perf_event.c 2014-07-31 23:51:43.000000000 +0200
  39443. +++ linux-linaro-stable-mx6/arch/arm64/kernel/perf_event.c 2014-08-20 19:31:40.600845277 +0200
  39444. @@ -1348,8 +1348,8 @@
  39445. * Callchain handling code.
  39446. */
  39447. struct frame_tail {
  39448. - struct frame_tail __user *fp;
  39449. - unsigned long lr;
  39450. + struct frame_tail __user *fp;
  39451. + unsigned long lr;
  39452. } __attribute__((packed));
  39453. /*
  39454. @@ -1386,22 +1386,84 @@
  39455. return buftail.fp;
  39456. }
  39457. +#ifdef CONFIG_COMPAT
  39458. +/*
  39459. + * The registers we're interested in are at the end of the variable
  39460. + * length saved register structure. The fp points at the end of this
  39461. + * structure so the address of this struct is:
  39462. + * (struct compat_frame_tail *)(xxx->fp)-1
  39463. + *
  39464. + * This code has been adapted from the ARM OProfile support.
  39465. + */
  39466. +struct compat_frame_tail {
  39467. + compat_uptr_t fp; /* a (struct compat_frame_tail *) in compat mode */
  39468. + u32 sp;
  39469. + u32 lr;
  39470. +} __attribute__((packed));
  39471. +
  39472. +static struct compat_frame_tail __user *
  39473. +compat_user_backtrace(struct compat_frame_tail __user *tail,
  39474. + struct perf_callchain_entry *entry)
  39475. +{
  39476. + struct compat_frame_tail buftail;
  39477. + unsigned long err;
  39478. +
  39479. + /* Also check accessibility of one struct frame_tail beyond */
  39480. + if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
  39481. + return NULL;
  39482. +
  39483. + pagefault_disable();
  39484. + err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail));
  39485. + pagefault_enable();
  39486. +
  39487. + if (err)
  39488. + return NULL;
  39489. +
  39490. + perf_callchain_store(entry, buftail.lr);
  39491. +
  39492. + /*
  39493. + * Frame pointers should strictly progress back up the stack
  39494. + * (towards higher addresses).
  39495. + */
  39496. + if (tail + 1 >= (struct compat_frame_tail __user *)
  39497. + compat_ptr(buftail.fp))
  39498. + return NULL;
  39499. +
  39500. + return (struct compat_frame_tail __user *)compat_ptr(buftail.fp) - 1;
  39501. +}
  39502. +#endif /* CONFIG_COMPAT */
  39503. +
  39504. void perf_callchain_user(struct perf_callchain_entry *entry,
  39505. struct pt_regs *regs)
  39506. {
  39507. - struct frame_tail __user *tail;
  39508. -
  39509. if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
  39510. /* We don't support guest os callchain now */
  39511. return;
  39512. }
  39513. perf_callchain_store(entry, regs->pc);
  39514. - tail = (struct frame_tail __user *)regs->regs[29];
  39515. - while (entry->nr < PERF_MAX_STACK_DEPTH &&
  39516. - tail && !((unsigned long)tail & 0xf))
  39517. - tail = user_backtrace(tail, entry);
  39518. + if (!compat_user_mode(regs)) {
  39519. + /* AARCH64 mode */
  39520. + struct frame_tail __user *tail;
  39521. +
  39522. + tail = (struct frame_tail __user *)regs->regs[29];
  39523. +
  39524. + while (entry->nr < PERF_MAX_STACK_DEPTH &&
  39525. + tail && !((unsigned long)tail & 0xf))
  39526. + tail = user_backtrace(tail, entry);
  39527. + } else {
  39528. +#ifdef CONFIG_COMPAT
  39529. + /* AARCH32 compat mode */
  39530. + struct compat_frame_tail __user *tail;
  39531. +
  39532. + tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
  39533. +
  39534. + while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
  39535. + tail && !((unsigned long)tail & 0x3))
  39536. + tail = compat_user_backtrace(tail, entry);
  39537. +#endif
  39538. + }
  39539. }
  39540. /*
  39541. @@ -1429,6 +1491,7 @@
  39542. frame.fp = regs->regs[29];
  39543. frame.sp = regs->sp;
  39544. frame.pc = regs->pc;
  39545. +
  39546. walk_stackframe(&frame, callchain_trace, entry);
  39547. }
  39548. diff -Nur linux-3.14.15/arch/arm64/kernel/perf_regs.c linux-linaro-stable-mx6/arch/arm64/kernel/perf_regs.c
  39549. --- linux-3.14.15/arch/arm64/kernel/perf_regs.c 1970-01-01 01:00:00.000000000 +0100
  39550. +++ linux-linaro-stable-mx6/arch/arm64/kernel/perf_regs.c 2014-08-20 19:31:40.600845277 +0200
  39551. @@ -0,0 +1,46 @@
  39552. +#include <linux/errno.h>
  39553. +#include <linux/kernel.h>
  39554. +#include <linux/perf_event.h>
  39555. +#include <linux/bug.h>
  39556. +
  39557. +#include <asm/compat.h>
  39558. +#include <asm/perf_regs.h>
  39559. +#include <asm/ptrace.h>
  39560. +
  39561. +u64 perf_reg_value(struct pt_regs *regs, int idx)
  39562. +{
  39563. + if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
  39564. + return 0;
  39565. +
  39566. + /*
  39567. + * Compat (i.e. 32 bit) mode:
  39568. + * - PC has been set in the pt_regs struct in kernel_entry,
  39569. + * - Handle SP and LR here.
  39570. + */
  39571. + if (compat_user_mode(regs)) {
  39572. + if ((u32)idx == PERF_REG_ARM64_SP)
  39573. + return regs->compat_sp;
  39574. + if ((u32)idx == PERF_REG_ARM64_LR)
  39575. + return regs->compat_lr;
  39576. + }
  39577. +
  39578. + return regs->regs[idx];
  39579. +}
  39580. +
  39581. +#define REG_RESERVED (~((1ULL << PERF_REG_ARM64_MAX) - 1))
  39582. +
  39583. +int perf_reg_validate(u64 mask)
  39584. +{
  39585. + if (!mask || mask & REG_RESERVED)
  39586. + return -EINVAL;
  39587. +
  39588. + return 0;
  39589. +}
  39590. +
  39591. +u64 perf_reg_abi(struct task_struct *task)
  39592. +{
  39593. + if (is_compat_thread(task_thread_info(task)))
  39594. + return PERF_SAMPLE_REGS_ABI_32;
  39595. + else
  39596. + return PERF_SAMPLE_REGS_ABI_64;
  39597. +}
  39598. diff -Nur linux-3.14.15/arch/arm64/kernel/process.c linux-linaro-stable-mx6/arch/arm64/kernel/process.c
  39599. --- linux-3.14.15/arch/arm64/kernel/process.c 2014-07-31 23:51:43.000000000 +0200
  39600. +++ linux-linaro-stable-mx6/arch/arm64/kernel/process.c 2014-08-20 19:31:40.600845277 +0200
  39601. @@ -20,6 +20,7 @@
  39602. #include <stdarg.h>
  39603. +#include <linux/compat.h>
  39604. #include <linux/export.h>
  39605. #include <linux/sched.h>
  39606. #include <linux/kernel.h>
  39607. diff -Nur linux-3.14.15/arch/arm64/kernel/ptrace.c linux-linaro-stable-mx6/arch/arm64/kernel/ptrace.c
  39608. --- linux-3.14.15/arch/arm64/kernel/ptrace.c 2014-07-31 23:51:43.000000000 +0200
  39609. +++ linux-linaro-stable-mx6/arch/arm64/kernel/ptrace.c 2014-08-20 19:31:40.604845294 +0200
  39610. @@ -19,6 +19,7 @@
  39611. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  39612. */
  39613. +#include <linux/compat.h>
  39614. #include <linux/kernel.h>
  39615. #include <linux/sched.h>
  39616. #include <linux/mm.h>
  39617. @@ -41,6 +42,9 @@
  39618. #include <asm/traps.h>
  39619. #include <asm/system_misc.h>
  39620. +#define CREATE_TRACE_POINTS
  39621. +#include <trace/events/syscalls.h>
  39622. +
  39623. /*
  39624. * TODO: does not yet catch signals sent when the child dies.
  39625. * in exit.c or in signal.c.
  39626. @@ -1072,35 +1076,49 @@
  39627. return ptrace_request(child, request, addr, data);
  39628. }
  39629. -asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
  39630. +enum ptrace_syscall_dir {
  39631. + PTRACE_SYSCALL_ENTER = 0,
  39632. + PTRACE_SYSCALL_EXIT,
  39633. +};
  39634. +
  39635. +static void tracehook_report_syscall(struct pt_regs *regs,
  39636. + enum ptrace_syscall_dir dir)
  39637. {
  39638. + int regno;
  39639. unsigned long saved_reg;
  39640. - if (!test_thread_flag(TIF_SYSCALL_TRACE))
  39641. - return regs->syscallno;
  39642. -
  39643. - if (is_compat_task()) {
  39644. - /* AArch32 uses ip (r12) for scratch */
  39645. - saved_reg = regs->regs[12];
  39646. - regs->regs[12] = dir;
  39647. - } else {
  39648. - /*
  39649. - * Save X7. X7 is used to denote syscall entry/exit:
  39650. - * X7 = 0 -> entry, = 1 -> exit
  39651. - */
  39652. - saved_reg = regs->regs[7];
  39653. - regs->regs[7] = dir;
  39654. - }
  39655. + /*
  39656. + * A scratch register (ip(r12) on AArch32, x7 on AArch64) is
  39657. + * used to denote syscall entry/exit:
  39658. + */
  39659. + regno = (is_compat_task() ? 12 : 7);
  39660. + saved_reg = regs->regs[regno];
  39661. + regs->regs[regno] = dir;
  39662. - if (dir)
  39663. + if (dir == PTRACE_SYSCALL_EXIT)
  39664. tracehook_report_syscall_exit(regs, 0);
  39665. else if (tracehook_report_syscall_entry(regs))
  39666. regs->syscallno = ~0UL;
  39667. - if (is_compat_task())
  39668. - regs->regs[12] = saved_reg;
  39669. - else
  39670. - regs->regs[7] = saved_reg;
  39671. + regs->regs[regno] = saved_reg;
  39672. +}
  39673. +
  39674. +asmlinkage int syscall_trace_enter(struct pt_regs *regs)
  39675. +{
  39676. + if (test_thread_flag(TIF_SYSCALL_TRACE))
  39677. + tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
  39678. +
  39679. + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
  39680. + trace_sys_enter(regs, regs->syscallno);
  39681. return regs->syscallno;
  39682. }
  39683. +
  39684. +asmlinkage void syscall_trace_exit(struct pt_regs *regs)
  39685. +{
  39686. + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
  39687. + trace_sys_exit(regs, regs_return_value(regs));
  39688. +
  39689. + if (test_thread_flag(TIF_SYSCALL_TRACE))
  39690. + tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
  39691. +}
  39692. diff -Nur linux-3.14.15/arch/arm64/kernel/return_address.c linux-linaro-stable-mx6/arch/arm64/kernel/return_address.c
  39693. --- linux-3.14.15/arch/arm64/kernel/return_address.c 1970-01-01 01:00:00.000000000 +0100
  39694. +++ linux-linaro-stable-mx6/arch/arm64/kernel/return_address.c 2014-08-20 19:31:40.604845294 +0200
  39695. @@ -0,0 +1,55 @@
  39696. +/*
  39697. + * arch/arm64/kernel/return_address.c
  39698. + *
  39699. + * Copyright (C) 2013 Linaro Limited
  39700. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  39701. + *
  39702. + * This program is free software; you can redistribute it and/or modify
  39703. + * it under the terms of the GNU General Public License version 2 as
  39704. + * published by the Free Software Foundation.
  39705. + */
  39706. +
  39707. +#include <linux/export.h>
  39708. +#include <linux/ftrace.h>
  39709. +
  39710. +#include <asm/stacktrace.h>
  39711. +
  39712. +struct return_address_data {
  39713. + unsigned int level;
  39714. + void *addr;
  39715. +};
  39716. +
  39717. +static int save_return_addr(struct stackframe *frame, void *d)
  39718. +{
  39719. + struct return_address_data *data = d;
  39720. +
  39721. + if (!data->level) {
  39722. + data->addr = (void *)frame->pc;
  39723. + return 1;
  39724. + } else {
  39725. + --data->level;
  39726. + return 0;
  39727. + }
  39728. +}
  39729. +
  39730. +void *return_address(unsigned int level)
  39731. +{
  39732. + struct return_address_data data;
  39733. + struct stackframe frame;
  39734. + register unsigned long current_sp asm ("sp");
  39735. +
  39736. + data.level = level + 2;
  39737. + data.addr = NULL;
  39738. +
  39739. + frame.fp = (unsigned long)__builtin_frame_address(0);
  39740. + frame.sp = current_sp;
  39741. + frame.pc = (unsigned long)return_address; /* dummy */
  39742. +
  39743. + walk_stackframe(&frame, save_return_addr, &data);
  39744. +
  39745. + if (!data.level)
  39746. + return data.addr;
  39747. + else
  39748. + return NULL;
  39749. +}
  39750. +EXPORT_SYMBOL_GPL(return_address);
  39751. diff -Nur linux-3.14.15/arch/arm64/kernel/setup.c linux-linaro-stable-mx6/arch/arm64/kernel/setup.c
  39752. --- linux-3.14.15/arch/arm64/kernel/setup.c 2014-07-31 23:51:43.000000000 +0200
  39753. +++ linux-linaro-stable-mx6/arch/arm64/kernel/setup.c 2014-08-20 19:31:40.604845294 +0200
  39754. @@ -69,6 +69,7 @@
  39755. COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\
  39756. COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV)
  39757. unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT;
  39758. +unsigned int compat_elf_hwcap2 __read_mostly;
  39759. #endif
  39760. static const char *cpu_name;
  39761. @@ -242,6 +243,38 @@
  39762. block = (features >> 16) & 0xf;
  39763. if (block && !(block & 0x8))
  39764. elf_hwcap |= HWCAP_CRC32;
  39765. +
  39766. +#ifdef CONFIG_COMPAT
  39767. + /*
  39768. + * ID_ISAR5_EL1 carries similar information as above, but pertaining to
  39769. + * the Aarch32 32-bit execution state.
  39770. + */
  39771. + features = read_cpuid(ID_ISAR5_EL1);
  39772. + block = (features >> 4) & 0xf;
  39773. + if (!(block & 0x8)) {
  39774. + switch (block) {
  39775. + default:
  39776. + case 2:
  39777. + compat_elf_hwcap2 |= COMPAT_HWCAP2_PMULL;
  39778. + case 1:
  39779. + compat_elf_hwcap2 |= COMPAT_HWCAP2_AES;
  39780. + case 0:
  39781. + break;
  39782. + }
  39783. + }
  39784. +
  39785. + block = (features >> 8) & 0xf;
  39786. + if (block && !(block & 0x8))
  39787. + compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA1;
  39788. +
  39789. + block = (features >> 12) & 0xf;
  39790. + if (block && !(block & 0x8))
  39791. + compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA2;
  39792. +
  39793. + block = (features >> 16) & 0xf;
  39794. + if (block && !(block & 0x8))
  39795. + compat_elf_hwcap2 |= COMPAT_HWCAP2_CRC32;
  39796. +#endif
  39797. }
  39798. static void __init setup_machine_fdt(phys_addr_t dt_phys)
  39799. @@ -360,7 +393,7 @@
  39800. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  39801. return 0;
  39802. }
  39803. -arch_initcall(arm64_device_init);
  39804. +arch_initcall_sync(arm64_device_init);
  39805. static DEFINE_PER_CPU(struct cpu, cpu_data);
  39806. diff -Nur linux-3.14.15/arch/arm64/kernel/signal.c linux-linaro-stable-mx6/arch/arm64/kernel/signal.c
  39807. --- linux-3.14.15/arch/arm64/kernel/signal.c 2014-07-31 23:51:43.000000000 +0200
  39808. +++ linux-linaro-stable-mx6/arch/arm64/kernel/signal.c 2014-08-20 19:31:40.604845294 +0200
  39809. @@ -17,6 +17,7 @@
  39810. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  39811. */
  39812. +#include <linux/compat.h>
  39813. #include <linux/errno.h>
  39814. #include <linux/signal.h>
  39815. #include <linux/personality.h>
  39816. @@ -25,7 +26,6 @@
  39817. #include <linux/tracehook.h>
  39818. #include <linux/ratelimit.h>
  39819. -#include <asm/compat.h>
  39820. #include <asm/debug-monitors.h>
  39821. #include <asm/elf.h>
  39822. #include <asm/cacheflush.h>
  39823. diff -Nur linux-3.14.15/arch/arm64/kernel/smp.c linux-linaro-stable-mx6/arch/arm64/kernel/smp.c
  39824. --- linux-3.14.15/arch/arm64/kernel/smp.c 2014-07-31 23:51:43.000000000 +0200
  39825. +++ linux-linaro-stable-mx6/arch/arm64/kernel/smp.c 2014-08-20 19:31:40.604845294 +0200
  39826. @@ -114,6 +114,11 @@
  39827. return ret;
  39828. }
  39829. +static void smp_store_cpu_info(unsigned int cpuid)
  39830. +{
  39831. + store_cpu_topology(cpuid);
  39832. +}
  39833. +
  39834. /*
  39835. * This is the secondary CPU boot entry. We're using this CPUs
  39836. * idle thread stack, but a set of temporary page tables.
  39837. @@ -152,6 +157,8 @@
  39838. */
  39839. notify_cpu_starting(cpu);
  39840. + smp_store_cpu_info(cpu);
  39841. +
  39842. /*
  39843. * OK, now it's safe to let the boot CPU continue. Wait for
  39844. * the CPU migration code to notice that the CPU is online
  39845. @@ -390,6 +397,10 @@
  39846. int err;
  39847. unsigned int cpu, ncores = num_possible_cpus();
  39848. + init_cpu_topology();
  39849. +
  39850. + smp_store_cpu_info(smp_processor_id());
  39851. +
  39852. /*
  39853. * are we trying to boot more cores than exist?
  39854. */
  39855. diff -Nur linux-3.14.15/arch/arm64/kernel/stacktrace.c linux-linaro-stable-mx6/arch/arm64/kernel/stacktrace.c
  39856. --- linux-3.14.15/arch/arm64/kernel/stacktrace.c 2014-07-31 23:51:43.000000000 +0200
  39857. +++ linux-linaro-stable-mx6/arch/arm64/kernel/stacktrace.c 2014-08-20 19:31:40.604845294 +0200
  39858. @@ -35,7 +35,7 @@
  39859. * ldp x29, x30, [sp]
  39860. * add sp, sp, #0x10
  39861. */
  39862. -int unwind_frame(struct stackframe *frame)
  39863. +int notrace unwind_frame(struct stackframe *frame)
  39864. {
  39865. unsigned long high, low;
  39866. unsigned long fp = frame->fp;
  39867. diff -Nur linux-3.14.15/arch/arm64/kernel/topology.c linux-linaro-stable-mx6/arch/arm64/kernel/topology.c
  39868. --- linux-3.14.15/arch/arm64/kernel/topology.c 1970-01-01 01:00:00.000000000 +0100
  39869. +++ linux-linaro-stable-mx6/arch/arm64/kernel/topology.c 2014-08-20 19:31:40.608845311 +0200
  39870. @@ -0,0 +1,558 @@
  39871. +/*
  39872. + * arch/arm64/kernel/topology.c
  39873. + *
  39874. + * Copyright (C) 2011,2013,2014 Linaro Limited.
  39875. + *
  39876. + * Based on the arm32 version written by Vincent Guittot in turn based on
  39877. + * arch/sh/kernel/topology.c
  39878. + *
  39879. + * This file is subject to the terms and conditions of the GNU General Public
  39880. + * License. See the file "COPYING" in the main directory of this archive
  39881. + * for more details.
  39882. + */
  39883. +
  39884. +#include <linux/cpu.h>
  39885. +#include <linux/cpumask.h>
  39886. +#include <linux/init.h>
  39887. +#include <linux/percpu.h>
  39888. +#include <linux/node.h>
  39889. +#include <linux/nodemask.h>
  39890. +#include <linux/of.h>
  39891. +#include <linux/sched.h>
  39892. +#include <linux/slab.h>
  39893. +
  39894. +#include <asm/topology.h>
  39895. +
  39896. +/*
  39897. + * cpu power table
  39898. + * This per cpu data structure describes the relative capacity of each core.
  39899. + * On a heteregenous system, cores don't have the same computation capacity
  39900. + * and we reflect that difference in the cpu_power field so the scheduler can
  39901. + * take this difference into account during load balance. A per cpu structure
  39902. + * is preferred because each CPU updates its own cpu_power field during the
  39903. + * load balance except for idle cores. One idle core is selected to run the
  39904. + * rebalance_domains for all idle cores and the cpu_power can be updated
  39905. + * during this sequence.
  39906. + */
  39907. +static DEFINE_PER_CPU(unsigned long, cpu_scale);
  39908. +
  39909. +unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu)
  39910. +{
  39911. + return per_cpu(cpu_scale, cpu);
  39912. +}
  39913. +
  39914. +static void set_power_scale(unsigned int cpu, unsigned long power)
  39915. +{
  39916. + per_cpu(cpu_scale, cpu) = power;
  39917. +}
  39918. +
  39919. +static int __init get_cpu_for_node(struct device_node *node)
  39920. +{
  39921. + struct device_node *cpu_node;
  39922. + int cpu;
  39923. +
  39924. + cpu_node = of_parse_phandle(node, "cpu", 0);
  39925. + if (!cpu_node)
  39926. + return -1;
  39927. +
  39928. + for_each_possible_cpu(cpu) {
  39929. + if (of_get_cpu_node(cpu, NULL) == cpu_node) {
  39930. + of_node_put(cpu_node);
  39931. + return cpu;
  39932. + }
  39933. + }
  39934. +
  39935. + pr_crit("Unable to find CPU node for %s\n", cpu_node->full_name);
  39936. +
  39937. + of_node_put(cpu_node);
  39938. + return -1;
  39939. +}
  39940. +
  39941. +static int __init parse_core(struct device_node *core, int cluster_id,
  39942. + int core_id)
  39943. +{
  39944. + char name[10];
  39945. + bool leaf = true;
  39946. + int i = 0;
  39947. + int cpu;
  39948. + struct device_node *t;
  39949. +
  39950. + do {
  39951. + snprintf(name, sizeof(name), "thread%d", i);
  39952. + t = of_get_child_by_name(core, name);
  39953. + if (t) {
  39954. + leaf = false;
  39955. + cpu = get_cpu_for_node(t);
  39956. + if (cpu >= 0) {
  39957. + cpu_topology[cpu].cluster_id = cluster_id;
  39958. + cpu_topology[cpu].core_id = core_id;
  39959. + cpu_topology[cpu].thread_id = i;
  39960. + } else {
  39961. + pr_err("%s: Can't get CPU for thread\n",
  39962. + t->full_name);
  39963. + of_node_put(t);
  39964. + return -EINVAL;
  39965. + }
  39966. + of_node_put(t);
  39967. + }
  39968. + i++;
  39969. + } while (t);
  39970. +
  39971. + cpu = get_cpu_for_node(core);
  39972. + if (cpu >= 0) {
  39973. + if (!leaf) {
  39974. + pr_err("%s: Core has both threads and CPU\n",
  39975. + core->full_name);
  39976. + return -EINVAL;
  39977. + }
  39978. +
  39979. + cpu_topology[cpu].cluster_id = cluster_id;
  39980. + cpu_topology[cpu].core_id = core_id;
  39981. + } else if (leaf) {
  39982. + pr_err("%s: Can't get CPU for leaf core\n", core->full_name);
  39983. + return -EINVAL;
  39984. + }
  39985. +
  39986. + return 0;
  39987. +}
  39988. +
  39989. +static int __init parse_cluster(struct device_node *cluster, int depth)
  39990. +{
  39991. + char name[10];
  39992. + bool leaf = true;
  39993. + bool has_cores = false;
  39994. + struct device_node *c;
  39995. + static int cluster_id __initdata;
  39996. + int core_id = 0;
  39997. + int i, ret;
  39998. +
  39999. + /*
  40000. + * First check for child clusters; we currently ignore any
  40001. + * information about the nesting of clusters and present the
  40002. + * scheduler with a flat list of them.
  40003. + */
  40004. + i = 0;
  40005. + do {
  40006. + snprintf(name, sizeof(name), "cluster%d", i);
  40007. + c = of_get_child_by_name(cluster, name);
  40008. + if (c) {
  40009. + leaf = false;
  40010. + ret = parse_cluster(c, depth + 1);
  40011. + of_node_put(c);
  40012. + if (ret != 0)
  40013. + return ret;
  40014. + }
  40015. + i++;
  40016. + } while (c);
  40017. +
  40018. + /* Now check for cores */
  40019. + i = 0;
  40020. + do {
  40021. + snprintf(name, sizeof(name), "core%d", i);
  40022. + c = of_get_child_by_name(cluster, name);
  40023. + if (c) {
  40024. + has_cores = true;
  40025. +
  40026. + if (depth == 0) {
  40027. + pr_err("%s: cpu-map children should be clusters\n",
  40028. + c->full_name);
  40029. + of_node_put(c);
  40030. + return -EINVAL;
  40031. + }
  40032. +
  40033. + if (leaf) {
  40034. + ret = parse_core(c, cluster_id, core_id++);
  40035. + } else {
  40036. + pr_err("%s: Non-leaf cluster with core %s\n",
  40037. + cluster->full_name, name);
  40038. + ret = -EINVAL;
  40039. + }
  40040. +
  40041. + of_node_put(c);
  40042. + if (ret != 0)
  40043. + return ret;
  40044. + }
  40045. + i++;
  40046. + } while (c);
  40047. +
  40048. + if (leaf && !has_cores)
  40049. + pr_warn("%s: empty cluster\n", cluster->full_name);
  40050. +
  40051. + if (leaf)
  40052. + cluster_id++;
  40053. +
  40054. + return 0;
  40055. +}
  40056. +
  40057. +struct cpu_efficiency {
  40058. + const char *compatible;
  40059. + unsigned long efficiency;
  40060. +};
  40061. +
  40062. +/*
  40063. + * Table of relative efficiency of each processors
  40064. + * The efficiency value must fit in 20bit and the final
  40065. + * cpu_scale value must be in the range
  40066. + * 0 < cpu_scale < 3*SCHED_POWER_SCALE/2
  40067. + * in order to return at most 1 when DIV_ROUND_CLOSEST
  40068. + * is used to compute the capacity of a CPU.
  40069. + * Processors that are not defined in the table,
  40070. + * use the default SCHED_POWER_SCALE value for cpu_scale.
  40071. + */
  40072. +static const struct cpu_efficiency table_efficiency[] = {
  40073. + { "arm,cortex-a57", 3891 },
  40074. + { "arm,cortex-a53", 2048 },
  40075. + { NULL, },
  40076. +};
  40077. +
  40078. +static unsigned long *__cpu_capacity;
  40079. +#define cpu_capacity(cpu) __cpu_capacity[cpu]
  40080. +
  40081. +static unsigned long middle_capacity = 1;
  40082. +
  40083. +/*
  40084. + * Iterate all CPUs' descriptor in DT and compute the efficiency
  40085. + * (as per table_efficiency). Also calculate a middle efficiency
  40086. + * as close as possible to (max{eff_i} - min{eff_i}) / 2
  40087. + * This is later used to scale the cpu_power field such that an
  40088. + * 'average' CPU is of middle power. Also see the comments near
  40089. + * table_efficiency[] and update_cpu_power().
  40090. + */
  40091. +static int __init parse_dt_topology(void)
  40092. +{
  40093. + struct device_node *cn, *map;
  40094. + int ret = 0;
  40095. + int cpu;
  40096. +
  40097. + cn = of_find_node_by_path("/cpus");
  40098. + if (!cn) {
  40099. + pr_err("No CPU information found in DT\n");
  40100. + return 0;
  40101. + }
  40102. +
  40103. + /*
  40104. + * When topology is provided cpu-map is essentially a root
  40105. + * cluster with restricted subnodes.
  40106. + */
  40107. + map = of_get_child_by_name(cn, "cpu-map");
  40108. + if (!map)
  40109. + goto out;
  40110. +
  40111. + ret = parse_cluster(map, 0);
  40112. + if (ret != 0)
  40113. + goto out_map;
  40114. +
  40115. + /*
  40116. + * Check that all cores are in the topology; the SMP code will
  40117. + * only mark cores described in the DT as possible.
  40118. + */
  40119. + for_each_possible_cpu(cpu) {
  40120. + if (cpu_topology[cpu].cluster_id == -1) {
  40121. + pr_err("CPU%d: No topology information specified\n",
  40122. + cpu);
  40123. + ret = -EINVAL;
  40124. + }
  40125. + }
  40126. +
  40127. +out_map:
  40128. + of_node_put(map);
  40129. +out:
  40130. + of_node_put(cn);
  40131. + return ret;
  40132. +}
  40133. +
  40134. +static void __init parse_dt_cpu_power(void)
  40135. +{
  40136. + const struct cpu_efficiency *cpu_eff;
  40137. + struct device_node *cn;
  40138. + unsigned long min_capacity = ULONG_MAX;
  40139. + unsigned long max_capacity = 0;
  40140. + unsigned long capacity = 0;
  40141. + int cpu;
  40142. +
  40143. + __cpu_capacity = kcalloc(nr_cpu_ids, sizeof(*__cpu_capacity),
  40144. + GFP_NOWAIT);
  40145. +
  40146. + for_each_possible_cpu(cpu) {
  40147. + const u32 *rate;
  40148. + int len;
  40149. +
  40150. + /* Too early to use cpu->of_node */
  40151. + cn = of_get_cpu_node(cpu, NULL);
  40152. + if (!cn) {
  40153. + pr_err("Missing device node for CPU %d\n", cpu);
  40154. + continue;
  40155. + }
  40156. +
  40157. + for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
  40158. + if (of_device_is_compatible(cn, cpu_eff->compatible))
  40159. + break;
  40160. +
  40161. + if (cpu_eff->compatible == NULL) {
  40162. + pr_warn("%s: Unknown CPU type\n", cn->full_name);
  40163. + continue;
  40164. + }
  40165. +
  40166. + rate = of_get_property(cn, "clock-frequency", &len);
  40167. + if (!rate || len != 4) {
  40168. + pr_err("%s: Missing clock-frequency property\n",
  40169. + cn->full_name);
  40170. + continue;
  40171. + }
  40172. +
  40173. + capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
  40174. +
  40175. + /* Save min capacity of the system */
  40176. + if (capacity < min_capacity)
  40177. + min_capacity = capacity;
  40178. +
  40179. + /* Save max capacity of the system */
  40180. + if (capacity > max_capacity)
  40181. + max_capacity = capacity;
  40182. +
  40183. + cpu_capacity(cpu) = capacity;
  40184. + }
  40185. +
  40186. + /* If min and max capacities are equal we bypass the update of the
  40187. + * cpu_scale because all CPUs have the same capacity. Otherwise, we
  40188. + * compute a middle_capacity factor that will ensure that the capacity
  40189. + * of an 'average' CPU of the system will be as close as possible to
  40190. + * SCHED_POWER_SCALE, which is the default value, but with the
  40191. + * constraint explained near table_efficiency[].
  40192. + */
  40193. + if (min_capacity == max_capacity)
  40194. + return;
  40195. + else if (4 * max_capacity < (3 * (max_capacity + min_capacity)))
  40196. + middle_capacity = (min_capacity + max_capacity)
  40197. + >> (SCHED_POWER_SHIFT+1);
  40198. + else
  40199. + middle_capacity = ((max_capacity / 3)
  40200. + >> (SCHED_POWER_SHIFT-1)) + 1;
  40201. +}
  40202. +
  40203. +/*
  40204. + * Look for a customed capacity of a CPU in the cpu_topo_data table during the
  40205. + * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
  40206. + * function returns directly for SMP system.
  40207. + */
  40208. +static void update_cpu_power(unsigned int cpu)
  40209. +{
  40210. + if (!cpu_capacity(cpu))
  40211. + return;
  40212. +
  40213. + set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity);
  40214. +
  40215. + pr_info("CPU%u: update cpu_power %lu\n",
  40216. + cpu, arch_scale_freq_power(NULL, cpu));
  40217. +}
  40218. +
  40219. +/*
  40220. + * cpu topology table
  40221. + */
  40222. +struct cpu_topology cpu_topology[NR_CPUS];
  40223. +EXPORT_SYMBOL_GPL(cpu_topology);
  40224. +
  40225. +const struct cpumask *cpu_coregroup_mask(int cpu)
  40226. +{
  40227. + return &cpu_topology[cpu].core_sibling;
  40228. +}
  40229. +
  40230. +static void update_siblings_masks(unsigned int cpuid)
  40231. +{
  40232. + struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
  40233. + int cpu;
  40234. +
  40235. + if (cpuid_topo->cluster_id == -1) {
  40236. + /*
  40237. + * DT does not contain topology information for this cpu.
  40238. + */
  40239. + pr_debug("CPU%u: No topology information configured\n", cpuid);
  40240. + return;
  40241. + }
  40242. +
  40243. + /* update core and thread sibling masks */
  40244. + for_each_possible_cpu(cpu) {
  40245. + cpu_topo = &cpu_topology[cpu];
  40246. +
  40247. + if (cpuid_topo->cluster_id != cpu_topo->cluster_id)
  40248. + continue;
  40249. +
  40250. + cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
  40251. + if (cpu != cpuid)
  40252. + cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
  40253. +
  40254. + if (cpuid_topo->core_id != cpu_topo->core_id)
  40255. + continue;
  40256. +
  40257. + cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
  40258. + if (cpu != cpuid)
  40259. + cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
  40260. + }
  40261. +}
  40262. +
  40263. +void store_cpu_topology(unsigned int cpuid)
  40264. +{
  40265. + update_siblings_masks(cpuid);
  40266. + update_cpu_power(cpuid);
  40267. +}
  40268. +
  40269. +#ifdef CONFIG_SCHED_HMP
  40270. +
  40271. +/*
  40272. + * Retrieve logical cpu index corresponding to a given MPIDR[23:0]
  40273. + * - mpidr: MPIDR[23:0] to be used for the look-up
  40274. + *
  40275. + * Returns the cpu logical index or -EINVAL on look-up error
  40276. + */
  40277. +static inline int get_logical_index(u32 mpidr)
  40278. +{
  40279. + int cpu;
  40280. + for (cpu = 0; cpu < nr_cpu_ids; cpu++)
  40281. + if (cpu_logical_map(cpu) == mpidr)
  40282. + return cpu;
  40283. + return -EINVAL;
  40284. +}
  40285. +
  40286. +static const char * const little_cores[] = {
  40287. + "arm,cortex-a53",
  40288. + NULL,
  40289. +};
  40290. +
  40291. +static bool is_little_cpu(struct device_node *cn)
  40292. +{
  40293. + const char * const *lc;
  40294. + for (lc = little_cores; *lc; lc++)
  40295. + if (of_device_is_compatible(cn, *lc))
  40296. + return true;
  40297. + return false;
  40298. +}
  40299. +
  40300. +void __init arch_get_fast_and_slow_cpus(struct cpumask *fast,
  40301. + struct cpumask *slow)
  40302. +{
  40303. + struct device_node *cn = NULL;
  40304. + int cpu;
  40305. +
  40306. + cpumask_clear(fast);
  40307. + cpumask_clear(slow);
  40308. +
  40309. + /*
  40310. + * Use the config options if they are given. This helps testing
  40311. + * HMP scheduling on systems without a big.LITTLE architecture.
  40312. + */
  40313. + if (strlen(CONFIG_HMP_FAST_CPU_MASK) && strlen(CONFIG_HMP_SLOW_CPU_MASK)) {
  40314. + if (cpulist_parse(CONFIG_HMP_FAST_CPU_MASK, fast))
  40315. + WARN(1, "Failed to parse HMP fast cpu mask!\n");
  40316. + if (cpulist_parse(CONFIG_HMP_SLOW_CPU_MASK, slow))
  40317. + WARN(1, "Failed to parse HMP slow cpu mask!\n");
  40318. + return;
  40319. + }
  40320. +
  40321. + /*
  40322. + * Else, parse device tree for little cores.
  40323. + */
  40324. + while ((cn = of_find_node_by_type(cn, "cpu"))) {
  40325. +
  40326. + const u32 *mpidr;
  40327. + int len;
  40328. +
  40329. + mpidr = of_get_property(cn, "reg", &len);
  40330. + if (!mpidr || len != 8) {
  40331. + pr_err("%s missing reg property\n", cn->full_name);
  40332. + continue;
  40333. + }
  40334. +
  40335. + cpu = get_logical_index(be32_to_cpup(mpidr+1));
  40336. + if (cpu == -EINVAL) {
  40337. + pr_err("couldn't get logical index for mpidr %x\n",
  40338. + be32_to_cpup(mpidr+1));
  40339. + break;
  40340. + }
  40341. +
  40342. + if (is_little_cpu(cn))
  40343. + cpumask_set_cpu(cpu, slow);
  40344. + else
  40345. + cpumask_set_cpu(cpu, fast);
  40346. + }
  40347. +
  40348. + if (!cpumask_empty(fast) && !cpumask_empty(slow))
  40349. + return;
  40350. +
  40351. + /*
  40352. + * We didn't find both big and little cores so let's call all cores
  40353. + * fast as this will keep the system running, with all cores being
  40354. + * treated equal.
  40355. + */
  40356. + cpumask_setall(fast);
  40357. + cpumask_clear(slow);
  40358. +}
  40359. +
  40360. +struct cpumask hmp_slow_cpu_mask;
  40361. +
  40362. +void __init arch_get_hmp_domains(struct list_head *hmp_domains_list)
  40363. +{
  40364. + struct cpumask hmp_fast_cpu_mask;
  40365. + struct hmp_domain *domain;
  40366. +
  40367. + arch_get_fast_and_slow_cpus(&hmp_fast_cpu_mask, &hmp_slow_cpu_mask);
  40368. +
  40369. + /*
  40370. + * Initialize hmp_domains
  40371. + * Must be ordered with respect to compute capacity.
  40372. + * Fastest domain at head of list.
  40373. + */
  40374. + if(!cpumask_empty(&hmp_slow_cpu_mask)) {
  40375. + domain = (struct hmp_domain *)
  40376. + kmalloc(sizeof(struct hmp_domain), GFP_KERNEL);
  40377. + cpumask_copy(&domain->possible_cpus, &hmp_slow_cpu_mask);
  40378. + cpumask_and(&domain->cpus, cpu_online_mask, &domain->possible_cpus);
  40379. + list_add(&domain->hmp_domains, hmp_domains_list);
  40380. + }
  40381. + domain = (struct hmp_domain *)
  40382. + kmalloc(sizeof(struct hmp_domain), GFP_KERNEL);
  40383. + cpumask_copy(&domain->possible_cpus, &hmp_fast_cpu_mask);
  40384. + cpumask_and(&domain->cpus, cpu_online_mask, &domain->possible_cpus);
  40385. + list_add(&domain->hmp_domains, hmp_domains_list);
  40386. +}
  40387. +#endif /* CONFIG_SCHED_HMP */
  40388. +
  40389. +static void __init reset_cpu_topology(void)
  40390. +{
  40391. + unsigned int cpu;
  40392. +
  40393. + for_each_possible_cpu(cpu) {
  40394. + struct cpu_topology *cpu_topo = &cpu_topology[cpu];
  40395. +
  40396. + cpu_topo->thread_id = -1;
  40397. + cpu_topo->core_id = 0;
  40398. + cpu_topo->cluster_id = -1;
  40399. +
  40400. + cpumask_clear(&cpu_topo->core_sibling);
  40401. + cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
  40402. + cpumask_clear(&cpu_topo->thread_sibling);
  40403. + cpumask_set_cpu(cpu, &cpu_topo->thread_sibling);
  40404. + }
  40405. +}
  40406. +
  40407. +static void __init reset_cpu_power(void)
  40408. +{
  40409. + unsigned int cpu;
  40410. +
  40411. + for_each_possible_cpu(cpu)
  40412. + set_power_scale(cpu, SCHED_POWER_SCALE);
  40413. +}
  40414. +
  40415. +void __init init_cpu_topology(void)
  40416. +{
  40417. + reset_cpu_topology();
  40418. +
  40419. + /*
  40420. + * Discard anything that was parsed if we hit an error so we
  40421. + * don't use partial information.
  40422. + */
  40423. + if (parse_dt_topology())
  40424. + reset_cpu_topology();
  40425. +
  40426. + reset_cpu_power();
  40427. + parse_dt_cpu_power();
  40428. +}
  40429. diff -Nur linux-3.14.15/arch/arm64/kernel/vdso/Makefile linux-linaro-stable-mx6/arch/arm64/kernel/vdso/Makefile
  40430. --- linux-3.14.15/arch/arm64/kernel/vdso/Makefile 2014-07-31 23:51:43.000000000 +0200
  40431. +++ linux-linaro-stable-mx6/arch/arm64/kernel/vdso/Makefile 2014-08-20 19:31:40.608845311 +0200
  40432. @@ -47,9 +47,9 @@
  40433. $(call if_changed_dep,vdsoas)
  40434. # Actual build commands
  40435. -quiet_cmd_vdsold = VDSOL $@
  40436. +quiet_cmd_vdsold = VDSOL $@
  40437. cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@
  40438. -quiet_cmd_vdsoas = VDSOA $@
  40439. +quiet_cmd_vdsoas = VDSOA $@
  40440. cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
  40441. # Install commands for the unstripped file
  40442. diff -Nur linux-3.14.15/arch/arm64/kernel/vdso.c linux-linaro-stable-mx6/arch/arm64/kernel/vdso.c
  40443. --- linux-3.14.15/arch/arm64/kernel/vdso.c 2014-07-31 23:51:43.000000000 +0200
  40444. +++ linux-linaro-stable-mx6/arch/arm64/kernel/vdso.c 2014-08-20 19:31:40.608845311 +0200
  40445. @@ -156,11 +156,12 @@
  40446. int uses_interp)
  40447. {
  40448. struct mm_struct *mm = current->mm;
  40449. - unsigned long vdso_base, vdso_mapping_len;
  40450. + unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
  40451. int ret;
  40452. + vdso_text_len = vdso_pages << PAGE_SHIFT;
  40453. /* Be sure to map the data page */
  40454. - vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
  40455. + vdso_mapping_len = vdso_text_len + PAGE_SIZE;
  40456. down_write(&mm->mmap_sem);
  40457. vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
  40458. @@ -170,35 +171,52 @@
  40459. }
  40460. mm->context.vdso = (void *)vdso_base;
  40461. - ret = install_special_mapping(mm, vdso_base, vdso_mapping_len,
  40462. + ret = install_special_mapping(mm, vdso_base, vdso_text_len,
  40463. VM_READ|VM_EXEC|
  40464. VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
  40465. vdso_pagelist);
  40466. - if (ret) {
  40467. - mm->context.vdso = NULL;
  40468. + if (ret)
  40469. + goto up_fail;
  40470. +
  40471. + vdso_base += vdso_text_len;
  40472. + ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
  40473. + VM_READ|VM_MAYREAD,
  40474. + vdso_pagelist + vdso_pages);
  40475. + if (ret)
  40476. goto up_fail;
  40477. - }
  40478. -up_fail:
  40479. up_write(&mm->mmap_sem);
  40480. + return 0;
  40481. +up_fail:
  40482. + mm->context.vdso = NULL;
  40483. + up_write(&mm->mmap_sem);
  40484. return ret;
  40485. }
  40486. const char *arch_vma_name(struct vm_area_struct *vma)
  40487. {
  40488. + unsigned long vdso_text;
  40489. +
  40490. + if (!vma->vm_mm)
  40491. + return NULL;
  40492. +
  40493. + vdso_text = (unsigned long)vma->vm_mm->context.vdso;
  40494. +
  40495. /*
  40496. * We can re-use the vdso pointer in mm_context_t for identifying
  40497. * the vectors page for compat applications. The vDSO will always
  40498. * sit above TASK_UNMAPPED_BASE and so we don't need to worry about
  40499. * it conflicting with the vectors base.
  40500. */
  40501. - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) {
  40502. + if (vma->vm_start == vdso_text) {
  40503. #ifdef CONFIG_COMPAT
  40504. if (vma->vm_start == AARCH32_VECTORS_BASE)
  40505. return "[vectors]";
  40506. #endif
  40507. return "[vdso]";
  40508. + } else if (vma->vm_start == (vdso_text + (vdso_pages << PAGE_SHIFT))) {
  40509. + return "[vvar]";
  40510. }
  40511. return NULL;
  40512. diff -Nur linux-3.14.15/arch/arm64/kernel/vmlinux.lds.S linux-linaro-stable-mx6/arch/arm64/kernel/vmlinux.lds.S
  40513. --- linux-3.14.15/arch/arm64/kernel/vmlinux.lds.S 2014-07-31 23:51:43.000000000 +0200
  40514. +++ linux-linaro-stable-mx6/arch/arm64/kernel/vmlinux.lds.S 2014-08-20 19:31:40.608845311 +0200
  40515. @@ -104,6 +104,13 @@
  40516. _edata = .;
  40517. BSS_SECTION(0, 0, 0)
  40518. +
  40519. + . = ALIGN(PAGE_SIZE);
  40520. + idmap_pg_dir = .;
  40521. + . += IDMAP_DIR_SIZE;
  40522. + swapper_pg_dir = .;
  40523. + . += SWAPPER_DIR_SIZE;
  40524. +
  40525. _end = .;
  40526. STABS_DEBUG
  40527. diff -Nur linux-3.14.15/arch/arm64/Makefile linux-linaro-stable-mx6/arch/arm64/Makefile
  40528. --- linux-3.14.15/arch/arm64/Makefile 2014-07-31 23:51:43.000000000 +0200
  40529. +++ linux-linaro-stable-mx6/arch/arm64/Makefile 2014-08-20 19:31:40.480844761 +0200
  40530. @@ -45,6 +45,7 @@
  40531. core-y += arch/arm64/kernel/ arch/arm64/mm/
  40532. core-$(CONFIG_KVM) += arch/arm64/kvm/
  40533. core-$(CONFIG_XEN) += arch/arm64/xen/
  40534. +core-$(CONFIG_CRYPTO) += arch/arm64/crypto/
  40535. libs-y := arch/arm64/lib/ $(libs-y)
  40536. libs-y += $(LIBGCC)
  40537. diff -Nur linux-3.14.15/arch/arm64/mm/cache.S linux-linaro-stable-mx6/arch/arm64/mm/cache.S
  40538. --- linux-3.14.15/arch/arm64/mm/cache.S 2014-07-31 23:51:43.000000000 +0200
  40539. +++ linux-linaro-stable-mx6/arch/arm64/mm/cache.S 2014-08-20 19:31:40.612845327 +0200
  40540. @@ -30,7 +30,7 @@
  40541. *
  40542. * Corrupted registers: x0-x7, x9-x11
  40543. */
  40544. -ENTRY(__flush_dcache_all)
  40545. +__flush_dcache_all:
  40546. dsb sy // ensure ordering with previous memory accesses
  40547. mrs x0, clidr_el1 // read clidr
  40548. and x3, x0, #0x7000000 // extract loc from clidr
  40549. @@ -166,3 +166,97 @@
  40550. dsb sy
  40551. ret
  40552. ENDPROC(__flush_dcache_area)
  40553. +
  40554. +/*
  40555. + * __inval_cache_range(start, end)
  40556. + * - start - start address of region
  40557. + * - end - end address of region
  40558. + */
  40559. +ENTRY(__inval_cache_range)
  40560. + /* FALLTHROUGH */
  40561. +
  40562. +/*
  40563. + * __dma_inv_range(start, end)
  40564. + * - start - virtual start address of region
  40565. + * - end - virtual end address of region
  40566. + */
  40567. +__dma_inv_range:
  40568. + dcache_line_size x2, x3
  40569. + sub x3, x2, #1
  40570. + tst x1, x3 // end cache line aligned?
  40571. + bic x1, x1, x3
  40572. + b.eq 1f
  40573. + dc civac, x1 // clean & invalidate D / U line
  40574. +1: tst x0, x3 // start cache line aligned?
  40575. + bic x0, x0, x3
  40576. + b.eq 2f
  40577. + dc civac, x0 // clean & invalidate D / U line
  40578. + b 3f
  40579. +2: dc ivac, x0 // invalidate D / U line
  40580. +3: add x0, x0, x2
  40581. + cmp x0, x1
  40582. + b.lo 2b
  40583. + dsb sy
  40584. + ret
  40585. +ENDPROC(__inval_cache_range)
  40586. +ENDPROC(__dma_inv_range)
  40587. +
  40588. +/*
  40589. + * __dma_clean_range(start, end)
  40590. + * - start - virtual start address of region
  40591. + * - end - virtual end address of region
  40592. + */
  40593. +__dma_clean_range:
  40594. + dcache_line_size x2, x3
  40595. + sub x3, x2, #1
  40596. + bic x0, x0, x3
  40597. +1: dc cvac, x0 // clean D / U line
  40598. + add x0, x0, x2
  40599. + cmp x0, x1
  40600. + b.lo 1b
  40601. + dsb sy
  40602. + ret
  40603. +ENDPROC(__dma_clean_range)
  40604. +
  40605. +/*
  40606. + * __dma_flush_range(start, end)
  40607. + * - start - virtual start address of region
  40608. + * - end - virtual end address of region
  40609. + */
  40610. +ENTRY(__dma_flush_range)
  40611. + dcache_line_size x2, x3
  40612. + sub x3, x2, #1
  40613. + bic x0, x0, x3
  40614. +1: dc civac, x0 // clean & invalidate D / U line
  40615. + add x0, x0, x2
  40616. + cmp x0, x1
  40617. + b.lo 1b
  40618. + dsb sy
  40619. + ret
  40620. +ENDPROC(__dma_flush_range)
  40621. +
  40622. +/*
  40623. + * __dma_map_area(start, size, dir)
  40624. + * - start - kernel virtual start address
  40625. + * - size - size of region
  40626. + * - dir - DMA direction
  40627. + */
  40628. +ENTRY(__dma_map_area)
  40629. + add x1, x1, x0
  40630. + cmp w2, #DMA_FROM_DEVICE
  40631. + b.eq __dma_inv_range
  40632. + b __dma_clean_range
  40633. +ENDPROC(__dma_map_area)
  40634. +
  40635. +/*
  40636. + * __dma_unmap_area(start, size, dir)
  40637. + * - start - kernel virtual start address
  40638. + * - size - size of region
  40639. + * - dir - DMA direction
  40640. + */
  40641. +ENTRY(__dma_unmap_area)
  40642. + add x1, x1, x0
  40643. + cmp w2, #DMA_TO_DEVICE
  40644. + b.ne __dma_inv_range
  40645. + ret
  40646. +ENDPROC(__dma_unmap_area)
  40647. diff -Nur linux-3.14.15/arch/arm64/mm/copypage.c linux-linaro-stable-mx6/arch/arm64/mm/copypage.c
  40648. --- linux-3.14.15/arch/arm64/mm/copypage.c 2014-07-31 23:51:43.000000000 +0200
  40649. +++ linux-linaro-stable-mx6/arch/arm64/mm/copypage.c 2014-08-20 19:31:40.612845327 +0200
  40650. @@ -27,8 +27,10 @@
  40651. copy_page(kto, kfrom);
  40652. __flush_dcache_area(kto, PAGE_SIZE);
  40653. }
  40654. +EXPORT_SYMBOL_GPL(__cpu_copy_user_page);
  40655. void __cpu_clear_user_page(void *kaddr, unsigned long vaddr)
  40656. {
  40657. clear_page(kaddr);
  40658. }
  40659. +EXPORT_SYMBOL_GPL(__cpu_clear_user_page);
  40660. diff -Nur linux-3.14.15/arch/arm64/mm/dma-mapping.c linux-linaro-stable-mx6/arch/arm64/mm/dma-mapping.c
  40661. --- linux-3.14.15/arch/arm64/mm/dma-mapping.c 2014-07-31 23:51:43.000000000 +0200
  40662. +++ linux-linaro-stable-mx6/arch/arm64/mm/dma-mapping.c 2014-08-20 19:31:40.612845327 +0200
  40663. @@ -22,26 +22,39 @@
  40664. #include <linux/slab.h>
  40665. #include <linux/dma-mapping.h>
  40666. #include <linux/dma-contiguous.h>
  40667. +#include <linux/of.h>
  40668. +#include <linux/platform_device.h>
  40669. #include <linux/vmalloc.h>
  40670. #include <linux/swiotlb.h>
  40671. +#include <linux/amba/bus.h>
  40672. #include <asm/cacheflush.h>
  40673. struct dma_map_ops *dma_ops;
  40674. EXPORT_SYMBOL(dma_ops);
  40675. -static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size,
  40676. - dma_addr_t *dma_handle, gfp_t flags,
  40677. - struct dma_attrs *attrs)
  40678. +static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
  40679. + bool coherent)
  40680. +{
  40681. + if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
  40682. + return pgprot_writecombine(prot);
  40683. + else if (!coherent)
  40684. + return pgprot_dmacoherent(prot);
  40685. + return prot;
  40686. +}
  40687. +
  40688. +static void *__dma_alloc_coherent(struct device *dev, size_t size,
  40689. + dma_addr_t *dma_handle, gfp_t flags,
  40690. + struct dma_attrs *attrs)
  40691. {
  40692. if (dev == NULL) {
  40693. WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
  40694. return NULL;
  40695. }
  40696. - if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
  40697. + if (IS_ENABLED(CONFIG_ZONE_DMA) &&
  40698. dev->coherent_dma_mask <= DMA_BIT_MASK(32))
  40699. - flags |= GFP_DMA32;
  40700. + flags |= GFP_DMA;
  40701. if (IS_ENABLED(CONFIG_DMA_CMA)) {
  40702. struct page *page;
  40703. @@ -58,9 +71,9 @@
  40704. }
  40705. }
  40706. -static void arm64_swiotlb_free_coherent(struct device *dev, size_t size,
  40707. - void *vaddr, dma_addr_t dma_handle,
  40708. - struct dma_attrs *attrs)
  40709. +static void __dma_free_coherent(struct device *dev, size_t size,
  40710. + void *vaddr, dma_addr_t dma_handle,
  40711. + struct dma_attrs *attrs)
  40712. {
  40713. if (dev == NULL) {
  40714. WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
  40715. @@ -78,9 +91,212 @@
  40716. }
  40717. }
  40718. -static struct dma_map_ops arm64_swiotlb_dma_ops = {
  40719. - .alloc = arm64_swiotlb_alloc_coherent,
  40720. - .free = arm64_swiotlb_free_coherent,
  40721. +static void *__dma_alloc_noncoherent(struct device *dev, size_t size,
  40722. + dma_addr_t *dma_handle, gfp_t flags,
  40723. + struct dma_attrs *attrs)
  40724. +{
  40725. + struct page *page, **map;
  40726. + void *ptr, *coherent_ptr;
  40727. + int order, i;
  40728. +
  40729. + size = PAGE_ALIGN(size);
  40730. + order = get_order(size);
  40731. +
  40732. + ptr = __dma_alloc_coherent(dev, size, dma_handle, flags, attrs);
  40733. + if (!ptr)
  40734. + goto no_mem;
  40735. + map = kmalloc(sizeof(struct page *) << order, flags & ~GFP_DMA);
  40736. + if (!map)
  40737. + goto no_map;
  40738. +
  40739. + /* remove any dirty cache lines on the kernel alias */
  40740. + __dma_flush_range(ptr, ptr + size);
  40741. +
  40742. + /* create a coherent mapping */
  40743. + page = virt_to_page(ptr);
  40744. + for (i = 0; i < (size >> PAGE_SHIFT); i++)
  40745. + map[i] = page + i;
  40746. + coherent_ptr = vmap(map, size >> PAGE_SHIFT, VM_MAP,
  40747. + __get_dma_pgprot(attrs, pgprot_default, false));
  40748. + kfree(map);
  40749. + if (!coherent_ptr)
  40750. + goto no_map;
  40751. +
  40752. + return coherent_ptr;
  40753. +
  40754. +no_map:
  40755. + __dma_free_coherent(dev, size, ptr, *dma_handle, attrs);
  40756. +no_mem:
  40757. + *dma_handle = ~0;
  40758. + return NULL;
  40759. +}
  40760. +
  40761. +static void __dma_free_noncoherent(struct device *dev, size_t size,
  40762. + void *vaddr, dma_addr_t dma_handle,
  40763. + struct dma_attrs *attrs)
  40764. +{
  40765. + void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
  40766. +
  40767. + vunmap(vaddr);
  40768. + __dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
  40769. +}
  40770. +
  40771. +static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
  40772. + unsigned long offset, size_t size,
  40773. + enum dma_data_direction dir,
  40774. + struct dma_attrs *attrs)
  40775. +{
  40776. + dma_addr_t dev_addr;
  40777. +
  40778. + dev_addr = swiotlb_map_page(dev, page, offset, size, dir, attrs);
  40779. + __dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40780. +
  40781. + return dev_addr;
  40782. +}
  40783. +
  40784. +
  40785. +static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
  40786. + size_t size, enum dma_data_direction dir,
  40787. + struct dma_attrs *attrs)
  40788. +{
  40789. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40790. + swiotlb_unmap_page(dev, dev_addr, size, dir, attrs);
  40791. +}
  40792. +
  40793. +static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
  40794. + int nelems, enum dma_data_direction dir,
  40795. + struct dma_attrs *attrs)
  40796. +{
  40797. + struct scatterlist *sg;
  40798. + int i, ret;
  40799. +
  40800. + ret = swiotlb_map_sg_attrs(dev, sgl, nelems, dir, attrs);
  40801. + for_each_sg(sgl, sg, ret, i)
  40802. + __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  40803. + sg->length, dir);
  40804. +
  40805. + return ret;
  40806. +}
  40807. +
  40808. +static void __swiotlb_unmap_sg_attrs(struct device *dev,
  40809. + struct scatterlist *sgl, int nelems,
  40810. + enum dma_data_direction dir,
  40811. + struct dma_attrs *attrs)
  40812. +{
  40813. + struct scatterlist *sg;
  40814. + int i;
  40815. +
  40816. + for_each_sg(sgl, sg, nelems, i)
  40817. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  40818. + sg->length, dir);
  40819. + swiotlb_unmap_sg_attrs(dev, sgl, nelems, dir, attrs);
  40820. +}
  40821. +
  40822. +static void __swiotlb_sync_single_for_cpu(struct device *dev,
  40823. + dma_addr_t dev_addr, size_t size,
  40824. + enum dma_data_direction dir)
  40825. +{
  40826. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40827. + swiotlb_sync_single_for_cpu(dev, dev_addr, size, dir);
  40828. +}
  40829. +
  40830. +static void __swiotlb_sync_single_for_device(struct device *dev,
  40831. + dma_addr_t dev_addr, size_t size,
  40832. + enum dma_data_direction dir)
  40833. +{
  40834. + swiotlb_sync_single_for_device(dev, dev_addr, size, dir);
  40835. + __dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40836. +}
  40837. +
  40838. +static void __swiotlb_sync_sg_for_cpu(struct device *dev,
  40839. + struct scatterlist *sgl, int nelems,
  40840. + enum dma_data_direction dir)
  40841. +{
  40842. + struct scatterlist *sg;
  40843. + int i;
  40844. +
  40845. + for_each_sg(sgl, sg, nelems, i)
  40846. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  40847. + sg->length, dir);
  40848. + swiotlb_sync_sg_for_cpu(dev, sgl, nelems, dir);
  40849. +}
  40850. +
  40851. +static void __swiotlb_sync_sg_for_device(struct device *dev,
  40852. + struct scatterlist *sgl, int nelems,
  40853. + enum dma_data_direction dir)
  40854. +{
  40855. + struct scatterlist *sg;
  40856. + int i;
  40857. +
  40858. + swiotlb_sync_sg_for_device(dev, sgl, nelems, dir);
  40859. + for_each_sg(sgl, sg, nelems, i)
  40860. + __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  40861. + sg->length, dir);
  40862. +}
  40863. +
  40864. +/* vma->vm_page_prot must be set appropriately before calling this function */
  40865. +static int __dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
  40866. + void *cpu_addr, dma_addr_t dma_addr, size_t size)
  40867. +{
  40868. + int ret = -ENXIO;
  40869. + unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >>
  40870. + PAGE_SHIFT;
  40871. + unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
  40872. + unsigned long pfn = dma_to_phys(dev, dma_addr) >> PAGE_SHIFT;
  40873. + unsigned long off = vma->vm_pgoff;
  40874. +
  40875. + if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
  40876. + return ret;
  40877. +
  40878. + if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) {
  40879. + ret = remap_pfn_range(vma, vma->vm_start,
  40880. + pfn + off,
  40881. + vma->vm_end - vma->vm_start,
  40882. + vma->vm_page_prot);
  40883. + }
  40884. +
  40885. + return ret;
  40886. +}
  40887. +
  40888. +static int __swiotlb_mmap_noncoherent(struct device *dev,
  40889. + struct vm_area_struct *vma,
  40890. + void *cpu_addr, dma_addr_t dma_addr, size_t size,
  40891. + struct dma_attrs *attrs)
  40892. +{
  40893. + vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, false);
  40894. + return __dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
  40895. +}
  40896. +
  40897. +static int __swiotlb_mmap_coherent(struct device *dev,
  40898. + struct vm_area_struct *vma,
  40899. + void *cpu_addr, dma_addr_t dma_addr, size_t size,
  40900. + struct dma_attrs *attrs)
  40901. +{
  40902. + /* Just use whatever page_prot attributes were specified */
  40903. + return __dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
  40904. +}
  40905. +
  40906. +struct dma_map_ops noncoherent_swiotlb_dma_ops = {
  40907. + .alloc = __dma_alloc_noncoherent,
  40908. + .free = __dma_free_noncoherent,
  40909. + .mmap = __swiotlb_mmap_noncoherent,
  40910. + .map_page = __swiotlb_map_page,
  40911. + .unmap_page = __swiotlb_unmap_page,
  40912. + .map_sg = __swiotlb_map_sg_attrs,
  40913. + .unmap_sg = __swiotlb_unmap_sg_attrs,
  40914. + .sync_single_for_cpu = __swiotlb_sync_single_for_cpu,
  40915. + .sync_single_for_device = __swiotlb_sync_single_for_device,
  40916. + .sync_sg_for_cpu = __swiotlb_sync_sg_for_cpu,
  40917. + .sync_sg_for_device = __swiotlb_sync_sg_for_device,
  40918. + .dma_supported = swiotlb_dma_supported,
  40919. + .mapping_error = swiotlb_dma_mapping_error,
  40920. +};
  40921. +EXPORT_SYMBOL(noncoherent_swiotlb_dma_ops);
  40922. +
  40923. +struct dma_map_ops coherent_swiotlb_dma_ops = {
  40924. + .alloc = __dma_alloc_coherent,
  40925. + .free = __dma_free_coherent,
  40926. + .mmap = __swiotlb_mmap_coherent,
  40927. .map_page = swiotlb_map_page,
  40928. .unmap_page = swiotlb_unmap_page,
  40929. .map_sg = swiotlb_map_sg_attrs,
  40930. @@ -92,12 +308,47 @@
  40931. .dma_supported = swiotlb_dma_supported,
  40932. .mapping_error = swiotlb_dma_mapping_error,
  40933. };
  40934. +EXPORT_SYMBOL(coherent_swiotlb_dma_ops);
  40935. -void __init arm64_swiotlb_init(void)
  40936. +static int dma_bus_notifier(struct notifier_block *nb,
  40937. + unsigned long event, void *_dev)
  40938. {
  40939. - dma_ops = &arm64_swiotlb_dma_ops;
  40940. - swiotlb_init(1);
  40941. + struct device *dev = _dev;
  40942. +
  40943. + if (event != BUS_NOTIFY_ADD_DEVICE)
  40944. + return NOTIFY_DONE;
  40945. +
  40946. + if (of_property_read_bool(dev->of_node, "dma-coherent"))
  40947. + set_dma_ops(dev, &coherent_swiotlb_dma_ops);
  40948. +
  40949. + return NOTIFY_OK;
  40950. +}
  40951. +
  40952. +static struct notifier_block platform_bus_nb = {
  40953. + .notifier_call = dma_bus_notifier,
  40954. +};
  40955. +
  40956. +static struct notifier_block amba_bus_nb = {
  40957. + .notifier_call = dma_bus_notifier,
  40958. +};
  40959. +
  40960. +extern int swiotlb_late_init_with_default_size(size_t default_size);
  40961. +
  40962. +static int __init swiotlb_late_init(void)
  40963. +{
  40964. + size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT);
  40965. +
  40966. + /*
  40967. + * These must be registered before of_platform_populate().
  40968. + */
  40969. + bus_register_notifier(&platform_bus_type, &platform_bus_nb);
  40970. + bus_register_notifier(&amba_bustype, &amba_bus_nb);
  40971. +
  40972. + dma_ops = &noncoherent_swiotlb_dma_ops;
  40973. +
  40974. + return swiotlb_late_init_with_default_size(swiotlb_size);
  40975. }
  40976. +arch_initcall(swiotlb_late_init);
  40977. #define PREALLOC_DMA_DEBUG_ENTRIES 4096
  40978. diff -Nur linux-3.14.15/arch/arm64/mm/init.c linux-linaro-stable-mx6/arch/arm64/mm/init.c
  40979. --- linux-3.14.15/arch/arm64/mm/init.c 2014-07-31 23:51:43.000000000 +0200
  40980. +++ linux-linaro-stable-mx6/arch/arm64/mm/init.c 2014-08-20 19:31:40.616845345 +0200
  40981. @@ -30,6 +30,7 @@
  40982. #include <linux/memblock.h>
  40983. #include <linux/sort.h>
  40984. #include <linux/of_fdt.h>
  40985. +#include <linux/dma-mapping.h>
  40986. #include <linux/dma-contiguous.h>
  40987. #include <asm/sections.h>
  40988. @@ -59,22 +60,22 @@
  40989. early_param("initrd", early_initrd);
  40990. #endif
  40991. -#define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT)
  40992. -
  40993. static void __init zone_sizes_init(unsigned long min, unsigned long max)
  40994. {
  40995. struct memblock_region *reg;
  40996. unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
  40997. - unsigned long max_dma32 = min;
  40998. + unsigned long max_dma = min;
  40999. memset(zone_size, 0, sizeof(zone_size));
  41000. -#ifdef CONFIG_ZONE_DMA32
  41001. /* 4GB maximum for 32-bit only capable devices */
  41002. - max_dma32 = max(min, min(max, MAX_DMA32_PFN));
  41003. - zone_size[ZONE_DMA32] = max_dma32 - min;
  41004. -#endif
  41005. - zone_size[ZONE_NORMAL] = max - max_dma32;
  41006. + if (IS_ENABLED(CONFIG_ZONE_DMA)) {
  41007. + unsigned long max_dma_phys =
  41008. + (unsigned long)dma_to_phys(NULL, DMA_BIT_MASK(32) + 1);
  41009. + max_dma = max(min, min(max, max_dma_phys >> PAGE_SHIFT));
  41010. + zone_size[ZONE_DMA] = max_dma - min;
  41011. + }
  41012. + zone_size[ZONE_NORMAL] = max - max_dma;
  41013. memcpy(zhole_size, zone_size, sizeof(zhole_size));
  41014. @@ -84,15 +85,15 @@
  41015. if (start >= max)
  41016. continue;
  41017. -#ifdef CONFIG_ZONE_DMA32
  41018. - if (start < max_dma32) {
  41019. - unsigned long dma_end = min(end, max_dma32);
  41020. - zhole_size[ZONE_DMA32] -= dma_end - start;
  41021. +
  41022. + if (IS_ENABLED(CONFIG_ZONE_DMA) && start < max_dma) {
  41023. + unsigned long dma_end = min(end, max_dma);
  41024. + zhole_size[ZONE_DMA] -= dma_end - start;
  41025. }
  41026. -#endif
  41027. - if (end > max_dma32) {
  41028. +
  41029. + if (end > max_dma) {
  41030. unsigned long normal_end = min(end, max);
  41031. - unsigned long normal_start = max(start, max_dma32);
  41032. + unsigned long normal_start = max(start, max_dma);
  41033. zhole_size[ZONE_NORMAL] -= normal_end - normal_start;
  41034. }
  41035. }
  41036. @@ -127,20 +128,16 @@
  41037. {
  41038. u64 *reserve_map, base, size;
  41039. - /* Register the kernel text, kernel data and initrd with memblock */
  41040. + /*
  41041. + * Register the kernel text, kernel data, initrd, and initial
  41042. + * pagetables with memblock.
  41043. + */
  41044. memblock_reserve(__pa(_text), _end - _text);
  41045. #ifdef CONFIG_BLK_DEV_INITRD
  41046. if (initrd_start)
  41047. memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
  41048. #endif
  41049. - /*
  41050. - * Reserve the page tables. These are already in use,
  41051. - * and can only be in node 0.
  41052. - */
  41053. - memblock_reserve(__pa(swapper_pg_dir), SWAPPER_DIR_SIZE);
  41054. - memblock_reserve(__pa(idmap_pg_dir), IDMAP_DIR_SIZE);
  41055. -
  41056. /* Reserve the dtb region */
  41057. memblock_reserve(virt_to_phys(initial_boot_params),
  41058. be32_to_cpu(initial_boot_params->totalsize));
  41059. @@ -261,8 +258,6 @@
  41060. */
  41061. void __init mem_init(void)
  41062. {
  41063. - arm64_swiotlb_init();
  41064. -
  41065. max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
  41066. #ifndef CONFIG_SPARSEMEM_VMEMMAP
  41067. diff -Nur linux-3.14.15/arch/arm64/mm/proc.S linux-linaro-stable-mx6/arch/arm64/mm/proc.S
  41068. --- linux-3.14.15/arch/arm64/mm/proc.S 2014-07-31 23:51:43.000000000 +0200
  41069. +++ linux-linaro-stable-mx6/arch/arm64/mm/proc.S 2014-08-20 19:31:40.616845345 +0200
  41070. @@ -173,12 +173,6 @@
  41071. * value of the SCTLR_EL1 register.
  41072. */
  41073. ENTRY(__cpu_setup)
  41074. - /*
  41075. - * Preserve the link register across the function call.
  41076. - */
  41077. - mov x28, lr
  41078. - bl __flush_dcache_all
  41079. - mov lr, x28
  41080. ic iallu // I+BTB cache invalidate
  41081. tlbi vmalle1is // invalidate I + D TLBs
  41082. dsb sy
  41083. diff -Nur linux-3.14.15/arch/avr32/kernel/cpu.c linux-linaro-stable-mx6/arch/avr32/kernel/cpu.c
  41084. --- linux-3.14.15/arch/avr32/kernel/cpu.c 2014-07-31 23:51:43.000000000 +0200
  41085. +++ linux-linaro-stable-mx6/arch/avr32/kernel/cpu.c 2014-08-20 19:31:40.624845380 +0200
  41086. @@ -39,10 +39,12 @@
  41087. size_t count)
  41088. {
  41089. unsigned long val;
  41090. - char *endp;
  41091. + int ret;
  41092. - val = simple_strtoul(buf, &endp, 0);
  41093. - if (endp == buf || val > 0x3f)
  41094. + ret = kstrtoul(buf, 0, &val);
  41095. + if (ret)
  41096. + return ret;
  41097. + if (val > 0x3f)
  41098. return -EINVAL;
  41099. val = (val << 12) | (sysreg_read(PCCR) & 0xfffc0fff);
  41100. sysreg_write(PCCR, val);
  41101. @@ -61,11 +63,11 @@
  41102. const char *buf, size_t count)
  41103. {
  41104. unsigned long val;
  41105. - char *endp;
  41106. + int ret;
  41107. - val = simple_strtoul(buf, &endp, 0);
  41108. - if (endp == buf)
  41109. - return -EINVAL;
  41110. + ret = kstrtoul(buf, 0, &val);
  41111. + if (ret)
  41112. + return ret;
  41113. sysreg_write(PCNT0, val);
  41114. return count;
  41115. @@ -84,10 +86,12 @@
  41116. size_t count)
  41117. {
  41118. unsigned long val;
  41119. - char *endp;
  41120. + int ret;
  41121. - val = simple_strtoul(buf, &endp, 0);
  41122. - if (endp == buf || val > 0x3f)
  41123. + ret = kstrtoul(buf, 0, &val);
  41124. + if (ret)
  41125. + return ret;
  41126. + if (val > 0x3f)
  41127. return -EINVAL;
  41128. val = (val << 18) | (sysreg_read(PCCR) & 0xff03ffff);
  41129. sysreg_write(PCCR, val);
  41130. @@ -106,11 +110,11 @@
  41131. size_t count)
  41132. {
  41133. unsigned long val;
  41134. - char *endp;
  41135. + int ret;
  41136. - val = simple_strtoul(buf, &endp, 0);
  41137. - if (endp == buf)
  41138. - return -EINVAL;
  41139. + ret = kstrtoul(buf, 0, &val);
  41140. + if (ret)
  41141. + return ret;
  41142. sysreg_write(PCNT1, val);
  41143. return count;
  41144. @@ -129,11 +133,11 @@
  41145. size_t count)
  41146. {
  41147. unsigned long val;
  41148. - char *endp;
  41149. + int ret;
  41150. - val = simple_strtoul(buf, &endp, 0);
  41151. - if (endp == buf)
  41152. - return -EINVAL;
  41153. + ret = kstrtoul(buf, 0, &val);
  41154. + if (ret)
  41155. + return ret;
  41156. sysreg_write(PCCNT, val);
  41157. return count;
  41158. @@ -152,11 +156,11 @@
  41159. size_t count)
  41160. {
  41161. unsigned long pccr, val;
  41162. - char *endp;
  41163. + int ret;
  41164. - val = simple_strtoul(buf, &endp, 0);
  41165. - if (endp == buf)
  41166. - return -EINVAL;
  41167. + ret = kstrtoul(buf, 0, &val);
  41168. + if (ret)
  41169. + return ret;
  41170. if (val)
  41171. val = 1;
  41172. diff -Nur linux-3.14.15/arch/blackfin/include/asm/ftrace.h linux-linaro-stable-mx6/arch/blackfin/include/asm/ftrace.h
  41173. --- linux-3.14.15/arch/blackfin/include/asm/ftrace.h 2014-07-31 23:51:43.000000000 +0200
  41174. +++ linux-linaro-stable-mx6/arch/blackfin/include/asm/ftrace.h 2014-08-20 19:31:40.632845414 +0200
  41175. @@ -66,16 +66,7 @@
  41176. #endif /* CONFIG_FRAME_POINTER */
  41177. -#define HAVE_ARCH_CALLER_ADDR
  41178. -
  41179. -/* inline function or macro may lead to unexpected result */
  41180. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  41181. -#define CALLER_ADDR1 ((unsigned long)return_address(1))
  41182. -#define CALLER_ADDR2 ((unsigned long)return_address(2))
  41183. -#define CALLER_ADDR3 ((unsigned long)return_address(3))
  41184. -#define CALLER_ADDR4 ((unsigned long)return_address(4))
  41185. -#define CALLER_ADDR5 ((unsigned long)return_address(5))
  41186. -#define CALLER_ADDR6 ((unsigned long)return_address(6))
  41187. +#define ftrace_return_address(n) return_address(n)
  41188. #endif /* __ASSEMBLY__ */
  41189. diff -Nur linux-3.14.15/arch/hexagon/include/asm/elf.h linux-linaro-stable-mx6/arch/hexagon/include/asm/elf.h
  41190. --- linux-3.14.15/arch/hexagon/include/asm/elf.h 2014-07-31 23:51:43.000000000 +0200
  41191. +++ linux-linaro-stable-mx6/arch/hexagon/include/asm/elf.h 2014-08-20 19:31:40.728845826 +0200
  41192. @@ -1,7 +1,7 @@
  41193. /*
  41194. * ELF definitions for the Hexagon architecture
  41195. *
  41196. - * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  41197. + * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  41198. *
  41199. * This program is free software; you can redistribute it and/or modify
  41200. * it under the terms of the GNU General Public License version 2 and
  41201. diff -Nur linux-3.14.15/arch/parisc/include/asm/ftrace.h linux-linaro-stable-mx6/arch/parisc/include/asm/ftrace.h
  41202. --- linux-3.14.15/arch/parisc/include/asm/ftrace.h 2014-07-31 23:51:43.000000000 +0200
  41203. +++ linux-linaro-stable-mx6/arch/parisc/include/asm/ftrace.h 2014-08-20 19:31:41.312848333 +0200
  41204. @@ -24,15 +24,7 @@
  41205. extern unsigned long return_address(unsigned int);
  41206. -#define HAVE_ARCH_CALLER_ADDR
  41207. -
  41208. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  41209. -#define CALLER_ADDR1 return_address(1)
  41210. -#define CALLER_ADDR2 return_address(2)
  41211. -#define CALLER_ADDR3 return_address(3)
  41212. -#define CALLER_ADDR4 return_address(4)
  41213. -#define CALLER_ADDR5 return_address(5)
  41214. -#define CALLER_ADDR6 return_address(6)
  41215. +#define ftrace_return_address(n) return_address(n)
  41216. #endif /* __ASSEMBLY__ */
  41217. diff -Nur linux-3.14.15/arch/parisc/include/uapi/asm/signal.h linux-linaro-stable-mx6/arch/parisc/include/uapi/asm/signal.h
  41218. --- linux-3.14.15/arch/parisc/include/uapi/asm/signal.h 2014-07-31 23:51:43.000000000 +0200
  41219. +++ linux-linaro-stable-mx6/arch/parisc/include/uapi/asm/signal.h 2014-08-20 19:23:48.390823776 +0200
  41220. @@ -69,6 +69,8 @@
  41221. #define SA_NOMASK SA_NODEFER
  41222. #define SA_ONESHOT SA_RESETHAND
  41223. +#define SA_RESTORER 0x04000000 /* obsolete -- ignored */
  41224. +
  41225. #define MINSIGSTKSZ 2048
  41226. #define SIGSTKSZ 8192
  41227. diff -Nur linux-3.14.15/arch/s390/include/asm/cio.h linux-linaro-stable-mx6/arch/s390/include/asm/cio.h
  41228. --- linux-3.14.15/arch/s390/include/asm/cio.h 2014-07-31 23:51:43.000000000 +0200
  41229. +++ linux-linaro-stable-mx6/arch/s390/include/asm/cio.h 2014-08-20 19:31:41.684849930 +0200
  41230. @@ -199,7 +199,7 @@
  41231. /**
  41232. * struct irb - interruption response block
  41233. * @scsw: subchannel status word
  41234. - * @esw: extened status word
  41235. + * @esw: extended status word
  41236. * @ecw: extended control word
  41237. *
  41238. * The irb that is handed to the device driver when an interrupt occurs. For
  41239. diff -Nur linux-3.14.15/arch/s390/kernel/ptrace.c linux-linaro-stable-mx6/arch/s390/kernel/ptrace.c
  41240. --- linux-3.14.15/arch/s390/kernel/ptrace.c 2014-07-31 23:51:43.000000000 +0200
  41241. +++ linux-linaro-stable-mx6/arch/s390/kernel/ptrace.c 2014-08-20 19:31:41.708850033 +0200
  41242. @@ -323,14 +323,9 @@
  41243. unsigned long mask = PSW_MASK_USER;
  41244. mask |= is_ri_task(child) ? PSW_MASK_RI : 0;
  41245. - if ((data ^ PSW_USER_BITS) & ~mask)
  41246. - /* Invalid psw mask. */
  41247. - return -EINVAL;
  41248. - if ((data & PSW_MASK_ASC) == PSW_ASC_HOME)
  41249. - /* Invalid address-space-control bits */
  41250. + if ((data & ~mask) != PSW_USER_BITS)
  41251. return -EINVAL;
  41252. if ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))
  41253. - /* Invalid addressing mode bits */
  41254. return -EINVAL;
  41255. }
  41256. *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
  41257. @@ -666,12 +661,9 @@
  41258. mask |= is_ri_task(child) ? PSW32_MASK_RI : 0;
  41259. /* Build a 64 bit psw mask from 31 bit mask. */
  41260. - if ((tmp ^ PSW32_USER_BITS) & ~mask)
  41261. + if ((tmp & ~mask) != PSW32_USER_BITS)
  41262. /* Invalid psw mask. */
  41263. return -EINVAL;
  41264. - if ((data & PSW32_MASK_ASC) == PSW32_ASC_HOME)
  41265. - /* Invalid address-space-control bits */
  41266. - return -EINVAL;
  41267. regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
  41268. (regs->psw.mask & PSW_MASK_BA) |
  41269. (__u64)(tmp & mask) << 32;
  41270. diff -Nur linux-3.14.15/arch/sh/include/asm/ftrace.h linux-linaro-stable-mx6/arch/sh/include/asm/ftrace.h
  41271. --- linux-3.14.15/arch/sh/include/asm/ftrace.h 2014-07-31 23:51:43.000000000 +0200
  41272. +++ linux-linaro-stable-mx6/arch/sh/include/asm/ftrace.h 2014-08-20 19:31:41.796850411 +0200
  41273. @@ -40,15 +40,7 @@
  41274. /* arch/sh/kernel/return_address.c */
  41275. extern void *return_address(unsigned int);
  41276. -#define HAVE_ARCH_CALLER_ADDR
  41277. -
  41278. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  41279. -#define CALLER_ADDR1 ((unsigned long)return_address(1))
  41280. -#define CALLER_ADDR2 ((unsigned long)return_address(2))
  41281. -#define CALLER_ADDR3 ((unsigned long)return_address(3))
  41282. -#define CALLER_ADDR4 ((unsigned long)return_address(4))
  41283. -#define CALLER_ADDR5 ((unsigned long)return_address(5))
  41284. -#define CALLER_ADDR6 ((unsigned long)return_address(6))
  41285. +#define ftrace_return_address(n) return_address(n)
  41286. #endif /* __ASSEMBLY__ */
  41287. diff -Nur linux-3.14.15/arch/x86/boot/header.S linux-linaro-stable-mx6/arch/x86/boot/header.S
  41288. --- linux-3.14.15/arch/x86/boot/header.S 2014-07-31 23:51:43.000000000 +0200
  41289. +++ linux-linaro-stable-mx6/arch/x86/boot/header.S 2014-08-20 19:31:41.936851012 +0200
  41290. @@ -91,9 +91,10 @@
  41291. .section ".bsdata", "a"
  41292. bugger_off_msg:
  41293. - .ascii "Use a boot loader.\r\n"
  41294. + .ascii "Direct floppy boot is not supported. "
  41295. + .ascii "Use a boot loader program instead.\r\n"
  41296. .ascii "\n"
  41297. - .ascii "Remove disk and press any key to reboot...\r\n"
  41298. + .ascii "Remove disk and press any key to reboot ...\r\n"
  41299. .byte 0
  41300. #ifdef CONFIG_EFI_STUB
  41301. @@ -107,7 +108,7 @@
  41302. #else
  41303. .word 0x8664 # x86-64
  41304. #endif
  41305. - .word 4 # nr_sections
  41306. + .word 3 # nr_sections
  41307. .long 0 # TimeDateStamp
  41308. .long 0 # PointerToSymbolTable
  41309. .long 1 # NumberOfSymbols
  41310. @@ -249,25 +250,6 @@
  41311. .word 0 # NumberOfLineNumbers
  41312. .long 0x60500020 # Characteristics (section flags)
  41313. - #
  41314. - # The offset & size fields are filled in by build.c.
  41315. - #
  41316. - .ascii ".bss"
  41317. - .byte 0
  41318. - .byte 0
  41319. - .byte 0
  41320. - .byte 0
  41321. - .long 0
  41322. - .long 0x0
  41323. - .long 0 # Size of initialized data
  41324. - # on disk
  41325. - .long 0x0
  41326. - .long 0 # PointerToRelocations
  41327. - .long 0 # PointerToLineNumbers
  41328. - .word 0 # NumberOfRelocations
  41329. - .word 0 # NumberOfLineNumbers
  41330. - .long 0xc8000080 # Characteristics (section flags)
  41331. -
  41332. #endif /* CONFIG_EFI_STUB */
  41333. # Kernel attributes; used by setup. This is part 1 of the
  41334. diff -Nur linux-3.14.15/arch/x86/boot/tools/build.c linux-linaro-stable-mx6/arch/x86/boot/tools/build.c
  41335. --- linux-3.14.15/arch/x86/boot/tools/build.c 2014-07-31 23:51:43.000000000 +0200
  41336. +++ linux-linaro-stable-mx6/arch/x86/boot/tools/build.c 2014-08-20 19:31:41.936851012 +0200
  41337. @@ -142,7 +142,7 @@
  41338. #ifdef CONFIG_EFI_STUB
  41339. -static void update_pecoff_section_header_fields(char *section_name, u32 vma, u32 size, u32 datasz, u32 offset)
  41340. +static void update_pecoff_section_header(char *section_name, u32 offset, u32 size)
  41341. {
  41342. unsigned int pe_header;
  41343. unsigned short num_sections;
  41344. @@ -163,10 +163,10 @@
  41345. put_unaligned_le32(size, section + 0x8);
  41346. /* section header vma field */
  41347. - put_unaligned_le32(vma, section + 0xc);
  41348. + put_unaligned_le32(offset, section + 0xc);
  41349. /* section header 'size of initialised data' field */
  41350. - put_unaligned_le32(datasz, section + 0x10);
  41351. + put_unaligned_le32(size, section + 0x10);
  41352. /* section header 'file offset' field */
  41353. put_unaligned_le32(offset, section + 0x14);
  41354. @@ -178,11 +178,6 @@
  41355. }
  41356. }
  41357. -static void update_pecoff_section_header(char *section_name, u32 offset, u32 size)
  41358. -{
  41359. - update_pecoff_section_header_fields(section_name, offset, size, size, offset);
  41360. -}
  41361. -
  41362. static void update_pecoff_setup_and_reloc(unsigned int size)
  41363. {
  41364. u32 setup_offset = 0x200;
  41365. @@ -207,6 +202,9 @@
  41366. pe_header = get_unaligned_le32(&buf[0x3c]);
  41367. + /* Size of image */
  41368. + put_unaligned_le32(file_sz, &buf[pe_header + 0x50]);
  41369. +
  41370. /*
  41371. * Size of code: Subtract the size of the first sector (512 bytes)
  41372. * which includes the header.
  41373. @@ -221,22 +219,6 @@
  41374. update_pecoff_section_header(".text", text_start, text_sz);
  41375. }
  41376. -static void update_pecoff_bss(unsigned int file_sz, unsigned int init_sz)
  41377. -{
  41378. - unsigned int pe_header;
  41379. - unsigned int bss_sz = init_sz - file_sz;
  41380. -
  41381. - pe_header = get_unaligned_le32(&buf[0x3c]);
  41382. -
  41383. - /* Size of uninitialized data */
  41384. - put_unaligned_le32(bss_sz, &buf[pe_header + 0x24]);
  41385. -
  41386. - /* Size of image */
  41387. - put_unaligned_le32(init_sz, &buf[pe_header + 0x50]);
  41388. -
  41389. - update_pecoff_section_header_fields(".bss", file_sz, bss_sz, 0, 0);
  41390. -}
  41391. -
  41392. #endif /* CONFIG_EFI_STUB */
  41393. @@ -288,9 +270,6 @@
  41394. int fd;
  41395. void *kernel;
  41396. u32 crc = 0xffffffffUL;
  41397. -#ifdef CONFIG_EFI_STUB
  41398. - unsigned int init_sz;
  41399. -#endif
  41400. /* Defaults for old kernel */
  41401. #ifdef CONFIG_X86_32
  41402. @@ -364,9 +343,7 @@
  41403. put_unaligned_le32(sys_size, &buf[0x1f4]);
  41404. #ifdef CONFIG_EFI_STUB
  41405. - update_pecoff_text(setup_sectors * 512, i + (sys_size * 16));
  41406. - init_sz = get_unaligned_le32(&buf[0x260]);
  41407. - update_pecoff_bss(i + (sys_size * 16), init_sz);
  41408. + update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz));
  41409. #ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
  41410. efi_stub_entry -= 0x200;
  41411. diff -Nur linux-3.14.15/arch/x86/kernel/entry_32.S linux-linaro-stable-mx6/arch/x86/kernel/entry_32.S
  41412. --- linux-3.14.15/arch/x86/kernel/entry_32.S 2014-07-31 23:51:43.000000000 +0200
  41413. +++ linux-linaro-stable-mx6/arch/x86/kernel/entry_32.S 2014-08-20 19:31:42.004851304 +0200
  41414. @@ -433,8 +433,8 @@
  41415. cmpl $(NR_syscalls), %eax
  41416. jae sysenter_badsys
  41417. call *sys_call_table(,%eax,4)
  41418. -sysenter_after_call:
  41419. movl %eax,PT_EAX(%esp)
  41420. +sysenter_after_call:
  41421. LOCKDEP_SYS_EXIT
  41422. DISABLE_INTERRUPTS(CLBR_ANY)
  41423. TRACE_IRQS_OFF
  41424. @@ -514,7 +514,6 @@
  41425. jae syscall_badsys
  41426. syscall_call:
  41427. call *sys_call_table(,%eax,4)
  41428. -syscall_after_call:
  41429. movl %eax,PT_EAX(%esp) # store the return value
  41430. syscall_exit:
  41431. LOCKDEP_SYS_EXIT
  41432. @@ -684,12 +683,12 @@
  41433. END(syscall_fault)
  41434. syscall_badsys:
  41435. - movl $-ENOSYS,%eax
  41436. - jmp syscall_after_call
  41437. + movl $-ENOSYS,PT_EAX(%esp)
  41438. + jmp syscall_exit
  41439. END(syscall_badsys)
  41440. sysenter_badsys:
  41441. - movl $-ENOSYS,%eax
  41442. + movl $-ENOSYS,PT_EAX(%esp)
  41443. jmp sysenter_after_call
  41444. END(syscall_badsys)
  41445. CFI_ENDPROC
  41446. diff -Nur linux-3.14.15/block/bfq-cgroup.c linux-linaro-stable-mx6/block/bfq-cgroup.c
  41447. --- linux-3.14.15/block/bfq-cgroup.c 1970-01-01 01:00:00.000000000 +0100
  41448. +++ linux-linaro-stable-mx6/block/bfq-cgroup.c 2014-08-20 19:31:42.192852109 +0200
  41449. @@ -0,0 +1,932 @@
  41450. +/*
  41451. + * BFQ: CGROUPS support.
  41452. + *
  41453. + * Based on ideas and code from CFQ:
  41454. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  41455. + *
  41456. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  41457. + * Paolo Valente <paolo.valente@unimore.it>
  41458. + *
  41459. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  41460. + *
  41461. + * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
  41462. + * file.
  41463. + */
  41464. +
  41465. +#ifdef CONFIG_CGROUP_BFQIO
  41466. +
  41467. +static DEFINE_MUTEX(bfqio_mutex);
  41468. +
  41469. +static bool bfqio_is_removed(struct bfqio_cgroup *bgrp)
  41470. +{
  41471. + return bgrp ? !bgrp->online : false;
  41472. +}
  41473. +
  41474. +static struct bfqio_cgroup bfqio_root_cgroup = {
  41475. + .weight = BFQ_DEFAULT_GRP_WEIGHT,
  41476. + .ioprio = BFQ_DEFAULT_GRP_IOPRIO,
  41477. + .ioprio_class = BFQ_DEFAULT_GRP_CLASS,
  41478. +};
  41479. +
  41480. +static inline void bfq_init_entity(struct bfq_entity *entity,
  41481. + struct bfq_group *bfqg)
  41482. +{
  41483. + entity->weight = entity->new_weight;
  41484. + entity->orig_weight = entity->new_weight;
  41485. + entity->ioprio = entity->new_ioprio;
  41486. + entity->ioprio_class = entity->new_ioprio_class;
  41487. + entity->parent = bfqg->my_entity;
  41488. + entity->sched_data = &bfqg->sched_data;
  41489. +}
  41490. +
  41491. +static struct bfqio_cgroup *css_to_bfqio(struct cgroup_subsys_state *css)
  41492. +{
  41493. + return css ? container_of(css, struct bfqio_cgroup, css) : NULL;
  41494. +}
  41495. +
  41496. +/*
  41497. + * Search the bfq_group for bfqd into the hash table (by now only a list)
  41498. + * of bgrp. Must be called under rcu_read_lock().
  41499. + */
  41500. +static struct bfq_group *bfqio_lookup_group(struct bfqio_cgroup *bgrp,
  41501. + struct bfq_data *bfqd)
  41502. +{
  41503. + struct bfq_group *bfqg;
  41504. + void *key;
  41505. +
  41506. + hlist_for_each_entry_rcu(bfqg, &bgrp->group_data, group_node) {
  41507. + key = rcu_dereference(bfqg->bfqd);
  41508. + if (key == bfqd)
  41509. + return bfqg;
  41510. + }
  41511. +
  41512. + return NULL;
  41513. +}
  41514. +
  41515. +static inline void bfq_group_init_entity(struct bfqio_cgroup *bgrp,
  41516. + struct bfq_group *bfqg)
  41517. +{
  41518. + struct bfq_entity *entity = &bfqg->entity;
  41519. +
  41520. + /*
  41521. + * If the weight of the entity has never been set via the sysfs
  41522. + * interface, then bgrp->weight == 0. In this case we initialize
  41523. + * the weight from the current ioprio value. Otherwise, the group
  41524. + * weight, if set, has priority over the ioprio value.
  41525. + */
  41526. + if (bgrp->weight == 0) {
  41527. + entity->new_weight = bfq_ioprio_to_weight(bgrp->ioprio);
  41528. + entity->new_ioprio = bgrp->ioprio;
  41529. + } else {
  41530. + entity->new_weight = bgrp->weight;
  41531. + entity->new_ioprio = bfq_weight_to_ioprio(bgrp->weight);
  41532. + }
  41533. + entity->orig_weight = entity->weight = entity->new_weight;
  41534. + entity->ioprio = entity->new_ioprio;
  41535. + entity->ioprio_class = entity->new_ioprio_class = bgrp->ioprio_class;
  41536. + entity->my_sched_data = &bfqg->sched_data;
  41537. + bfqg->active_entities = 0;
  41538. +}
  41539. +
  41540. +static inline void bfq_group_set_parent(struct bfq_group *bfqg,
  41541. + struct bfq_group *parent)
  41542. +{
  41543. + struct bfq_entity *entity;
  41544. +
  41545. + BUG_ON(parent == NULL);
  41546. + BUG_ON(bfqg == NULL);
  41547. +
  41548. + entity = &bfqg->entity;
  41549. + entity->parent = parent->my_entity;
  41550. + entity->sched_data = &parent->sched_data;
  41551. +}
  41552. +
  41553. +/**
  41554. + * bfq_group_chain_alloc - allocate a chain of groups.
  41555. + * @bfqd: queue descriptor.
  41556. + * @css: the leaf cgroup_subsys_state this chain starts from.
  41557. + *
  41558. + * Allocate a chain of groups starting from the one belonging to
  41559. + * @cgroup up to the root cgroup. Stop if a cgroup on the chain
  41560. + * to the root has already an allocated group on @bfqd.
  41561. + */
  41562. +static struct bfq_group *bfq_group_chain_alloc(struct bfq_data *bfqd,
  41563. + struct cgroup_subsys_state *css)
  41564. +{
  41565. + struct bfqio_cgroup *bgrp;
  41566. + struct bfq_group *bfqg, *prev = NULL, *leaf = NULL;
  41567. +
  41568. + for (; css != NULL; css = css->parent) {
  41569. + bgrp = css_to_bfqio(css);
  41570. +
  41571. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  41572. + if (bfqg != NULL) {
  41573. + /*
  41574. + * All the cgroups in the path from there to the
  41575. + * root must have a bfq_group for bfqd, so we don't
  41576. + * need any more allocations.
  41577. + */
  41578. + break;
  41579. + }
  41580. +
  41581. + bfqg = kzalloc(sizeof(*bfqg), GFP_ATOMIC);
  41582. + if (bfqg == NULL)
  41583. + goto cleanup;
  41584. +
  41585. + bfq_group_init_entity(bgrp, bfqg);
  41586. + bfqg->my_entity = &bfqg->entity;
  41587. +
  41588. + if (leaf == NULL) {
  41589. + leaf = bfqg;
  41590. + prev = leaf;
  41591. + } else {
  41592. + bfq_group_set_parent(prev, bfqg);
  41593. + /*
  41594. + * Build a list of allocated nodes using the bfqd
  41595. + * filed, that is still unused and will be
  41596. + * initialized only after the node will be
  41597. + * connected.
  41598. + */
  41599. + prev->bfqd = bfqg;
  41600. + prev = bfqg;
  41601. + }
  41602. + }
  41603. +
  41604. + return leaf;
  41605. +
  41606. +cleanup:
  41607. + while (leaf != NULL) {
  41608. + prev = leaf;
  41609. + leaf = leaf->bfqd;
  41610. + kfree(prev);
  41611. + }
  41612. +
  41613. + return NULL;
  41614. +}
  41615. +
  41616. +/**
  41617. + * bfq_group_chain_link - link an allocated group chain to a cgroup
  41618. + * hierarchy.
  41619. + * @bfqd: the queue descriptor.
  41620. + * @css: the leaf cgroup_subsys_state to start from.
  41621. + * @leaf: the leaf group (to be associated to @cgroup).
  41622. + *
  41623. + * Try to link a chain of groups to a cgroup hierarchy, connecting the
  41624. + * nodes bottom-up, so we can be sure that when we find a cgroup in the
  41625. + * hierarchy that already as a group associated to @bfqd all the nodes
  41626. + * in the path to the root cgroup have one too.
  41627. + *
  41628. + * On locking: the queue lock protects the hierarchy (there is a hierarchy
  41629. + * per device) while the bfqio_cgroup lock protects the list of groups
  41630. + * belonging to the same cgroup.
  41631. + */
  41632. +static void bfq_group_chain_link(struct bfq_data *bfqd,
  41633. + struct cgroup_subsys_state *css,
  41634. + struct bfq_group *leaf)
  41635. +{
  41636. + struct bfqio_cgroup *bgrp;
  41637. + struct bfq_group *bfqg, *next, *prev = NULL;
  41638. + unsigned long flags;
  41639. +
  41640. + assert_spin_locked(bfqd->queue->queue_lock);
  41641. +
  41642. + for (; css != NULL && leaf != NULL; css = css->parent) {
  41643. + bgrp = css_to_bfqio(css);
  41644. + next = leaf->bfqd;
  41645. +
  41646. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  41647. + BUG_ON(bfqg != NULL);
  41648. +
  41649. + spin_lock_irqsave(&bgrp->lock, flags);
  41650. +
  41651. + rcu_assign_pointer(leaf->bfqd, bfqd);
  41652. + hlist_add_head_rcu(&leaf->group_node, &bgrp->group_data);
  41653. + hlist_add_head(&leaf->bfqd_node, &bfqd->group_list);
  41654. +
  41655. + spin_unlock_irqrestore(&bgrp->lock, flags);
  41656. +
  41657. + prev = leaf;
  41658. + leaf = next;
  41659. + }
  41660. +
  41661. + BUG_ON(css == NULL && leaf != NULL);
  41662. + if (css != NULL && prev != NULL) {
  41663. + bgrp = css_to_bfqio(css);
  41664. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  41665. + bfq_group_set_parent(prev, bfqg);
  41666. + }
  41667. +}
  41668. +
  41669. +/**
  41670. + * bfq_find_alloc_group - return the group associated to @bfqd in @cgroup.
  41671. + * @bfqd: queue descriptor.
  41672. + * @cgroup: cgroup being searched for.
  41673. + *
  41674. + * Return a group associated to @bfqd in @cgroup, allocating one if
  41675. + * necessary. When a group is returned all the cgroups in the path
  41676. + * to the root have a group associated to @bfqd.
  41677. + *
  41678. + * If the allocation fails, return the root group: this breaks guarantees
  41679. + * but is a safe fallback. If this loss becomes a problem it can be
  41680. + * mitigated using the equivalent weight (given by the product of the
  41681. + * weights of the groups in the path from @group to the root) in the
  41682. + * root scheduler.
  41683. + *
  41684. + * We allocate all the missing nodes in the path from the leaf cgroup
  41685. + * to the root and we connect the nodes only after all the allocations
  41686. + * have been successful.
  41687. + */
  41688. +static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd,
  41689. + struct cgroup_subsys_state *css)
  41690. +{
  41691. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  41692. + struct bfq_group *bfqg;
  41693. +
  41694. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  41695. + if (bfqg != NULL)
  41696. + return bfqg;
  41697. +
  41698. + bfqg = bfq_group_chain_alloc(bfqd, css);
  41699. + if (bfqg != NULL)
  41700. + bfq_group_chain_link(bfqd, css, bfqg);
  41701. + else
  41702. + bfqg = bfqd->root_group;
  41703. +
  41704. + return bfqg;
  41705. +}
  41706. +
  41707. +/**
  41708. + * bfq_bfqq_move - migrate @bfqq to @bfqg.
  41709. + * @bfqd: queue descriptor.
  41710. + * @bfqq: the queue to move.
  41711. + * @entity: @bfqq's entity.
  41712. + * @bfqg: the group to move to.
  41713. + *
  41714. + * Move @bfqq to @bfqg, deactivating it from its old group and reactivating
  41715. + * it on the new one. Avoid putting the entity on the old group idle tree.
  41716. + *
  41717. + * Must be called under the queue lock; the cgroup owning @bfqg must
  41718. + * not disappear (by now this just means that we are called under
  41719. + * rcu_read_lock()).
  41720. + */
  41721. +static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  41722. + struct bfq_entity *entity, struct bfq_group *bfqg)
  41723. +{
  41724. + int busy, resume;
  41725. +
  41726. + busy = bfq_bfqq_busy(bfqq);
  41727. + resume = !RB_EMPTY_ROOT(&bfqq->sort_list);
  41728. +
  41729. + BUG_ON(resume && !entity->on_st);
  41730. + BUG_ON(busy && !resume && entity->on_st &&
  41731. + bfqq != bfqd->in_service_queue);
  41732. +
  41733. + if (busy) {
  41734. + BUG_ON(atomic_read(&bfqq->ref) < 2);
  41735. +
  41736. + if (!resume)
  41737. + bfq_del_bfqq_busy(bfqd, bfqq, 0);
  41738. + else
  41739. + bfq_deactivate_bfqq(bfqd, bfqq, 0);
  41740. + } else if (entity->on_st)
  41741. + bfq_put_idle_entity(bfq_entity_service_tree(entity), entity);
  41742. +
  41743. + /*
  41744. + * Here we use a reference to bfqg. We don't need a refcounter
  41745. + * as the cgroup reference will not be dropped, so that its
  41746. + * destroy() callback will not be invoked.
  41747. + */
  41748. + entity->parent = bfqg->my_entity;
  41749. + entity->sched_data = &bfqg->sched_data;
  41750. +
  41751. + if (busy && resume)
  41752. + bfq_activate_bfqq(bfqd, bfqq);
  41753. +
  41754. + if (bfqd->in_service_queue == NULL && !bfqd->rq_in_driver)
  41755. + bfq_schedule_dispatch(bfqd);
  41756. +}
  41757. +
  41758. +/**
  41759. + * __bfq_bic_change_cgroup - move @bic to @cgroup.
  41760. + * @bfqd: the queue descriptor.
  41761. + * @bic: the bic to move.
  41762. + * @cgroup: the cgroup to move to.
  41763. + *
  41764. + * Move bic to cgroup, assuming that bfqd->queue is locked; the caller
  41765. + * has to make sure that the reference to cgroup is valid across the call.
  41766. + *
  41767. + * NOTE: an alternative approach might have been to store the current
  41768. + * cgroup in bfqq and getting a reference to it, reducing the lookup
  41769. + * time here, at the price of slightly more complex code.
  41770. + */
  41771. +static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
  41772. + struct bfq_io_cq *bic,
  41773. + struct cgroup_subsys_state *css)
  41774. +{
  41775. + struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0);
  41776. + struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1);
  41777. + struct bfq_entity *entity;
  41778. + struct bfq_group *bfqg;
  41779. + struct bfqio_cgroup *bgrp;
  41780. +
  41781. + bgrp = css_to_bfqio(css);
  41782. +
  41783. + bfqg = bfq_find_alloc_group(bfqd, css);
  41784. + if (async_bfqq != NULL) {
  41785. + entity = &async_bfqq->entity;
  41786. +
  41787. + if (entity->sched_data != &bfqg->sched_data) {
  41788. + bic_set_bfqq(bic, NULL, 0);
  41789. + bfq_log_bfqq(bfqd, async_bfqq,
  41790. + "bic_change_group: %p %d",
  41791. + async_bfqq, atomic_read(&async_bfqq->ref));
  41792. + bfq_put_queue(async_bfqq);
  41793. + }
  41794. + }
  41795. +
  41796. + if (sync_bfqq != NULL) {
  41797. + entity = &sync_bfqq->entity;
  41798. + if (entity->sched_data != &bfqg->sched_data)
  41799. + bfq_bfqq_move(bfqd, sync_bfqq, entity, bfqg);
  41800. + }
  41801. +
  41802. + return bfqg;
  41803. +}
  41804. +
  41805. +/**
  41806. + * bfq_bic_change_cgroup - move @bic to @cgroup.
  41807. + * @bic: the bic being migrated.
  41808. + * @cgroup: the destination cgroup.
  41809. + *
  41810. + * When the task owning @bic is moved to @cgroup, @bic is immediately
  41811. + * moved into its new parent group.
  41812. + */
  41813. +static void bfq_bic_change_cgroup(struct bfq_io_cq *bic,
  41814. + struct cgroup_subsys_state *css)
  41815. +{
  41816. + struct bfq_data *bfqd;
  41817. + unsigned long uninitialized_var(flags);
  41818. +
  41819. + bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data),
  41820. + &flags);
  41821. + if (bfqd != NULL) {
  41822. + __bfq_bic_change_cgroup(bfqd, bic, css);
  41823. + bfq_put_bfqd_unlock(bfqd, &flags);
  41824. + }
  41825. +}
  41826. +
  41827. +/**
  41828. + * bfq_bic_update_cgroup - update the cgroup of @bic.
  41829. + * @bic: the @bic to update.
  41830. + *
  41831. + * Make sure that @bic is enqueued in the cgroup of the current task.
  41832. + * We need this in addition to moving bics during the cgroup attach
  41833. + * phase because the task owning @bic could be at its first disk
  41834. + * access or we may end up in the root cgroup as the result of a
  41835. + * memory allocation failure and here we try to move to the right
  41836. + * group.
  41837. + *
  41838. + * Must be called under the queue lock. It is safe to use the returned
  41839. + * value even after the rcu_read_unlock() as the migration/destruction
  41840. + * paths act under the queue lock too. IOW it is impossible to race with
  41841. + * group migration/destruction and end up with an invalid group as:
  41842. + * a) here cgroup has not yet been destroyed, nor its destroy callback
  41843. + * has started execution, as current holds a reference to it,
  41844. + * b) if it is destroyed after rcu_read_unlock() [after current is
  41845. + * migrated to a different cgroup] its attach() callback will have
  41846. + * taken care of remove all the references to the old cgroup data.
  41847. + */
  41848. +static struct bfq_group *bfq_bic_update_cgroup(struct bfq_io_cq *bic)
  41849. +{
  41850. + struct bfq_data *bfqd = bic_to_bfqd(bic);
  41851. + struct bfq_group *bfqg;
  41852. + struct cgroup_subsys_state *css;
  41853. +
  41854. + BUG_ON(bfqd == NULL);
  41855. +
  41856. + rcu_read_lock();
  41857. + css = task_css(current, bfqio_subsys_id);
  41858. + bfqg = __bfq_bic_change_cgroup(bfqd, bic, css);
  41859. + rcu_read_unlock();
  41860. +
  41861. + return bfqg;
  41862. +}
  41863. +
  41864. +/**
  41865. + * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st.
  41866. + * @st: the service tree being flushed.
  41867. + */
  41868. +static inline void bfq_flush_idle_tree(struct bfq_service_tree *st)
  41869. +{
  41870. + struct bfq_entity *entity = st->first_idle;
  41871. +
  41872. + for (; entity != NULL; entity = st->first_idle)
  41873. + __bfq_deactivate_entity(entity, 0);
  41874. +}
  41875. +
  41876. +/**
  41877. + * bfq_reparent_leaf_entity - move leaf entity to the root_group.
  41878. + * @bfqd: the device data structure with the root group.
  41879. + * @entity: the entity to move.
  41880. + */
  41881. +static inline void bfq_reparent_leaf_entity(struct bfq_data *bfqd,
  41882. + struct bfq_entity *entity)
  41883. +{
  41884. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  41885. +
  41886. + BUG_ON(bfqq == NULL);
  41887. + bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group);
  41888. + return;
  41889. +}
  41890. +
  41891. +/**
  41892. + * bfq_reparent_active_entities - move to the root group all active
  41893. + * entities.
  41894. + * @bfqd: the device data structure with the root group.
  41895. + * @bfqg: the group to move from.
  41896. + * @st: the service tree with the entities.
  41897. + *
  41898. + * Needs queue_lock to be taken and reference to be valid over the call.
  41899. + */
  41900. +static inline void bfq_reparent_active_entities(struct bfq_data *bfqd,
  41901. + struct bfq_group *bfqg,
  41902. + struct bfq_service_tree *st)
  41903. +{
  41904. + struct rb_root *active = &st->active;
  41905. + struct bfq_entity *entity = NULL;
  41906. +
  41907. + if (!RB_EMPTY_ROOT(&st->active))
  41908. + entity = bfq_entity_of(rb_first(active));
  41909. +
  41910. + for (; entity != NULL; entity = bfq_entity_of(rb_first(active)))
  41911. + bfq_reparent_leaf_entity(bfqd, entity);
  41912. +
  41913. + if (bfqg->sched_data.in_service_entity != NULL)
  41914. + bfq_reparent_leaf_entity(bfqd,
  41915. + bfqg->sched_data.in_service_entity);
  41916. +
  41917. + return;
  41918. +}
  41919. +
  41920. +/**
  41921. + * bfq_destroy_group - destroy @bfqg.
  41922. + * @bgrp: the bfqio_cgroup containing @bfqg.
  41923. + * @bfqg: the group being destroyed.
  41924. + *
  41925. + * Destroy @bfqg, making sure that it is not referenced from its parent.
  41926. + */
  41927. +static void bfq_destroy_group(struct bfqio_cgroup *bgrp, struct bfq_group *bfqg)
  41928. +{
  41929. + struct bfq_data *bfqd;
  41930. + struct bfq_service_tree *st;
  41931. + struct bfq_entity *entity = bfqg->my_entity;
  41932. + unsigned long uninitialized_var(flags);
  41933. + int i;
  41934. +
  41935. + hlist_del(&bfqg->group_node);
  41936. +
  41937. + /*
  41938. + * Empty all service_trees belonging to this group before
  41939. + * deactivating the group itself.
  41940. + */
  41941. + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) {
  41942. + st = bfqg->sched_data.service_tree + i;
  41943. +
  41944. + /*
  41945. + * The idle tree may still contain bfq_queues belonging
  41946. + * to exited task because they never migrated to a different
  41947. + * cgroup from the one being destroyed now. No one else
  41948. + * can access them so it's safe to act without any lock.
  41949. + */
  41950. + bfq_flush_idle_tree(st);
  41951. +
  41952. + /*
  41953. + * It may happen that some queues are still active
  41954. + * (busy) upon group destruction (if the corresponding
  41955. + * processes have been forced to terminate). We move
  41956. + * all the leaf entities corresponding to these queues
  41957. + * to the root_group.
  41958. + * Also, it may happen that the group has an entity
  41959. + * in service, which is disconnected from the active
  41960. + * tree: it must be moved, too.
  41961. + * There is no need to put the sync queues, as the
  41962. + * scheduler has taken no reference.
  41963. + */
  41964. + bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags);
  41965. + if (bfqd != NULL) {
  41966. + bfq_reparent_active_entities(bfqd, bfqg, st);
  41967. + bfq_put_bfqd_unlock(bfqd, &flags);
  41968. + }
  41969. + BUG_ON(!RB_EMPTY_ROOT(&st->active));
  41970. + BUG_ON(!RB_EMPTY_ROOT(&st->idle));
  41971. + }
  41972. + BUG_ON(bfqg->sched_data.next_in_service != NULL);
  41973. + BUG_ON(bfqg->sched_data.in_service_entity != NULL);
  41974. +
  41975. + /*
  41976. + * We may race with device destruction, take extra care when
  41977. + * dereferencing bfqg->bfqd.
  41978. + */
  41979. + bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags);
  41980. + if (bfqd != NULL) {
  41981. + hlist_del(&bfqg->bfqd_node);
  41982. + __bfq_deactivate_entity(entity, 0);
  41983. + bfq_put_async_queues(bfqd, bfqg);
  41984. + bfq_put_bfqd_unlock(bfqd, &flags);
  41985. + }
  41986. + BUG_ON(entity->tree != NULL);
  41987. +
  41988. + /*
  41989. + * No need to defer the kfree() to the end of the RCU grace
  41990. + * period: we are called from the destroy() callback of our
  41991. + * cgroup, so we can be sure that no one is a) still using
  41992. + * this cgroup or b) doing lookups in it.
  41993. + */
  41994. + kfree(bfqg);
  41995. +}
  41996. +
  41997. +static void bfq_end_wr_async(struct bfq_data *bfqd)
  41998. +{
  41999. + struct hlist_node *tmp;
  42000. + struct bfq_group *bfqg;
  42001. +
  42002. + hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node)
  42003. + bfq_end_wr_async_queues(bfqd, bfqg);
  42004. + bfq_end_wr_async_queues(bfqd, bfqd->root_group);
  42005. +}
  42006. +
  42007. +/**
  42008. + * bfq_disconnect_groups - disconnect @bfqd from all its groups.
  42009. + * @bfqd: the device descriptor being exited.
  42010. + *
  42011. + * When the device exits we just make sure that no lookup can return
  42012. + * the now unused group structures. They will be deallocated on cgroup
  42013. + * destruction.
  42014. + */
  42015. +static void bfq_disconnect_groups(struct bfq_data *bfqd)
  42016. +{
  42017. + struct hlist_node *tmp;
  42018. + struct bfq_group *bfqg;
  42019. +
  42020. + bfq_log(bfqd, "disconnect_groups beginning");
  42021. + hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) {
  42022. + hlist_del(&bfqg->bfqd_node);
  42023. +
  42024. + __bfq_deactivate_entity(bfqg->my_entity, 0);
  42025. +
  42026. + /*
  42027. + * Don't remove from the group hash, just set an
  42028. + * invalid key. No lookups can race with the
  42029. + * assignment as bfqd is being destroyed; this
  42030. + * implies also that new elements cannot be added
  42031. + * to the list.
  42032. + */
  42033. + rcu_assign_pointer(bfqg->bfqd, NULL);
  42034. +
  42035. + bfq_log(bfqd, "disconnect_groups: put async for group %p",
  42036. + bfqg);
  42037. + bfq_put_async_queues(bfqd, bfqg);
  42038. + }
  42039. +}
  42040. +
  42041. +static inline void bfq_free_root_group(struct bfq_data *bfqd)
  42042. +{
  42043. + struct bfqio_cgroup *bgrp = &bfqio_root_cgroup;
  42044. + struct bfq_group *bfqg = bfqd->root_group;
  42045. +
  42046. + bfq_put_async_queues(bfqd, bfqg);
  42047. +
  42048. + spin_lock_irq(&bgrp->lock);
  42049. + hlist_del_rcu(&bfqg->group_node);
  42050. + spin_unlock_irq(&bgrp->lock);
  42051. +
  42052. + /*
  42053. + * No need to synchronize_rcu() here: since the device is gone
  42054. + * there cannot be any read-side access to its root_group.
  42055. + */
  42056. + kfree(bfqg);
  42057. +}
  42058. +
  42059. +static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node)
  42060. +{
  42061. + struct bfq_group *bfqg;
  42062. + struct bfqio_cgroup *bgrp;
  42063. + int i;
  42064. +
  42065. + bfqg = kzalloc_node(sizeof(*bfqg), GFP_KERNEL, node);
  42066. + if (bfqg == NULL)
  42067. + return NULL;
  42068. +
  42069. + bfqg->entity.parent = NULL;
  42070. + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++)
  42071. + bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT;
  42072. +
  42073. + bgrp = &bfqio_root_cgroup;
  42074. + spin_lock_irq(&bgrp->lock);
  42075. + rcu_assign_pointer(bfqg->bfqd, bfqd);
  42076. + hlist_add_head_rcu(&bfqg->group_node, &bgrp->group_data);
  42077. + spin_unlock_irq(&bgrp->lock);
  42078. +
  42079. + return bfqg;
  42080. +}
  42081. +
  42082. +#define SHOW_FUNCTION(__VAR) \
  42083. +static u64 bfqio_cgroup_##__VAR##_read(struct cgroup_subsys_state *css, \
  42084. + struct cftype *cftype) \
  42085. +{ \
  42086. + struct bfqio_cgroup *bgrp = css_to_bfqio(css); \
  42087. + u64 ret = -ENODEV; \
  42088. + \
  42089. + mutex_lock(&bfqio_mutex); \
  42090. + if (bfqio_is_removed(bgrp)) \
  42091. + goto out_unlock; \
  42092. + \
  42093. + spin_lock_irq(&bgrp->lock); \
  42094. + ret = bgrp->__VAR; \
  42095. + spin_unlock_irq(&bgrp->lock); \
  42096. + \
  42097. +out_unlock: \
  42098. + mutex_unlock(&bfqio_mutex); \
  42099. + return ret; \
  42100. +}
  42101. +
  42102. +SHOW_FUNCTION(weight);
  42103. +SHOW_FUNCTION(ioprio);
  42104. +SHOW_FUNCTION(ioprio_class);
  42105. +#undef SHOW_FUNCTION
  42106. +
  42107. +#define STORE_FUNCTION(__VAR, __MIN, __MAX) \
  42108. +static int bfqio_cgroup_##__VAR##_write(struct cgroup_subsys_state *css,\
  42109. + struct cftype *cftype, \
  42110. + u64 val) \
  42111. +{ \
  42112. + struct bfqio_cgroup *bgrp = css_to_bfqio(css); \
  42113. + struct bfq_group *bfqg; \
  42114. + int ret = -EINVAL; \
  42115. + \
  42116. + if (val < (__MIN) || val > (__MAX)) \
  42117. + return ret; \
  42118. + \
  42119. + ret = -ENODEV; \
  42120. + mutex_lock(&bfqio_mutex); \
  42121. + if (bfqio_is_removed(bgrp)) \
  42122. + goto out_unlock; \
  42123. + ret = 0; \
  42124. + \
  42125. + spin_lock_irq(&bgrp->lock); \
  42126. + bgrp->__VAR = (unsigned short)val; \
  42127. + hlist_for_each_entry(bfqg, &bgrp->group_data, group_node) { \
  42128. + /* \
  42129. + * Setting the ioprio_changed flag of the entity \
  42130. + * to 1 with new_##__VAR == ##__VAR would re-set \
  42131. + * the value of the weight to its ioprio mapping. \
  42132. + * Set the flag only if necessary. \
  42133. + */ \
  42134. + if ((unsigned short)val != bfqg->entity.new_##__VAR) { \
  42135. + bfqg->entity.new_##__VAR = (unsigned short)val; \
  42136. + /* \
  42137. + * Make sure that the above new value has been \
  42138. + * stored in bfqg->entity.new_##__VAR before \
  42139. + * setting the ioprio_changed flag. In fact, \
  42140. + * this flag may be read asynchronously (in \
  42141. + * critical sections protected by a different \
  42142. + * lock than that held here), and finding this \
  42143. + * flag set may cause the execution of the code \
  42144. + * for updating parameters whose value may \
  42145. + * depend also on bfqg->entity.new_##__VAR (in \
  42146. + * __bfq_entity_update_weight_prio). \
  42147. + * This barrier makes sure that the new value \
  42148. + * of bfqg->entity.new_##__VAR is correctly \
  42149. + * seen in that code. \
  42150. + */ \
  42151. + smp_wmb(); \
  42152. + bfqg->entity.ioprio_changed = 1; \
  42153. + } \
  42154. + } \
  42155. + spin_unlock_irq(&bgrp->lock); \
  42156. + \
  42157. +out_unlock: \
  42158. + mutex_unlock(&bfqio_mutex); \
  42159. + return ret; \
  42160. +}
  42161. +
  42162. +STORE_FUNCTION(weight, BFQ_MIN_WEIGHT, BFQ_MAX_WEIGHT);
  42163. +STORE_FUNCTION(ioprio, 0, IOPRIO_BE_NR - 1);
  42164. +STORE_FUNCTION(ioprio_class, IOPRIO_CLASS_RT, IOPRIO_CLASS_IDLE);
  42165. +#undef STORE_FUNCTION
  42166. +
  42167. +static struct cftype bfqio_files[] = {
  42168. + {
  42169. + .name = "weight",
  42170. + .read_u64 = bfqio_cgroup_weight_read,
  42171. + .write_u64 = bfqio_cgroup_weight_write,
  42172. + },
  42173. + {
  42174. + .name = "ioprio",
  42175. + .read_u64 = bfqio_cgroup_ioprio_read,
  42176. + .write_u64 = bfqio_cgroup_ioprio_write,
  42177. + },
  42178. + {
  42179. + .name = "ioprio_class",
  42180. + .read_u64 = bfqio_cgroup_ioprio_class_read,
  42181. + .write_u64 = bfqio_cgroup_ioprio_class_write,
  42182. + },
  42183. + { }, /* terminate */
  42184. +};
  42185. +
  42186. +static struct cgroup_subsys_state *bfqio_create(struct cgroup_subsys_state
  42187. + *parent_css)
  42188. +{
  42189. + struct bfqio_cgroup *bgrp;
  42190. +
  42191. + if (parent_css != NULL) {
  42192. + bgrp = kzalloc(sizeof(*bgrp), GFP_KERNEL);
  42193. + if (bgrp == NULL)
  42194. + return ERR_PTR(-ENOMEM);
  42195. + } else
  42196. + bgrp = &bfqio_root_cgroup;
  42197. +
  42198. + spin_lock_init(&bgrp->lock);
  42199. + INIT_HLIST_HEAD(&bgrp->group_data);
  42200. + bgrp->ioprio = BFQ_DEFAULT_GRP_IOPRIO;
  42201. + bgrp->ioprio_class = BFQ_DEFAULT_GRP_CLASS;
  42202. +
  42203. + return &bgrp->css;
  42204. +}
  42205. +
  42206. +/*
  42207. + * We cannot support shared io contexts, as we have no means to support
  42208. + * two tasks with the same ioc in two different groups without major rework
  42209. + * of the main bic/bfqq data structures. By now we allow a task to change
  42210. + * its cgroup only if it's the only owner of its ioc; the drawback of this
  42211. + * behavior is that a group containing a task that forked using CLONE_IO
  42212. + * will not be destroyed until the tasks sharing the ioc die.
  42213. + */
  42214. +static int bfqio_can_attach(struct cgroup_subsys_state *css,
  42215. + struct cgroup_taskset *tset)
  42216. +{
  42217. + struct task_struct *task;
  42218. + struct io_context *ioc;
  42219. + int ret = 0;
  42220. +
  42221. + cgroup_taskset_for_each(task, css, tset) {
  42222. + /*
  42223. + * task_lock() is needed to avoid races with
  42224. + * exit_io_context()
  42225. + */
  42226. + task_lock(task);
  42227. + ioc = task->io_context;
  42228. + if (ioc != NULL && atomic_read(&ioc->nr_tasks) > 1)
  42229. + /*
  42230. + * ioc == NULL means that the task is either too
  42231. + * young or exiting: if it has still no ioc the
  42232. + * ioc can't be shared, if the task is exiting the
  42233. + * attach will fail anyway, no matter what we
  42234. + * return here.
  42235. + */
  42236. + ret = -EINVAL;
  42237. + task_unlock(task);
  42238. + if (ret)
  42239. + break;
  42240. + }
  42241. +
  42242. + return ret;
  42243. +}
  42244. +
  42245. +static void bfqio_attach(struct cgroup_subsys_state *css,
  42246. + struct cgroup_taskset *tset)
  42247. +{
  42248. + struct task_struct *task;
  42249. + struct io_context *ioc;
  42250. + struct io_cq *icq;
  42251. +
  42252. + /*
  42253. + * IMPORTANT NOTE: The move of more than one process at a time to a
  42254. + * new group has not yet been tested.
  42255. + */
  42256. + cgroup_taskset_for_each(task, css, tset) {
  42257. + ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE);
  42258. + if (ioc) {
  42259. + /*
  42260. + * Handle cgroup change here.
  42261. + */
  42262. + rcu_read_lock();
  42263. + hlist_for_each_entry_rcu(icq, &ioc->icq_list, ioc_node)
  42264. + if (!strncmp(
  42265. + icq->q->elevator->type->elevator_name,
  42266. + "bfq", ELV_NAME_MAX))
  42267. + bfq_bic_change_cgroup(icq_to_bic(icq),
  42268. + css);
  42269. + rcu_read_unlock();
  42270. + put_io_context(ioc);
  42271. + }
  42272. + }
  42273. +}
  42274. +
  42275. +static void bfqio_destroy(struct cgroup_subsys_state *css)
  42276. +{
  42277. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  42278. + struct hlist_node *tmp;
  42279. + struct bfq_group *bfqg;
  42280. +
  42281. + /*
  42282. + * Since we are destroying the cgroup, there are no more tasks
  42283. + * referencing it, and all the RCU grace periods that may have
  42284. + * referenced it are ended (as the destruction of the parent
  42285. + * cgroup is RCU-safe); bgrp->group_data will not be accessed by
  42286. + * anything else and we don't need any synchronization.
  42287. + */
  42288. + hlist_for_each_entry_safe(bfqg, tmp, &bgrp->group_data, group_node)
  42289. + bfq_destroy_group(bgrp, bfqg);
  42290. +
  42291. + BUG_ON(!hlist_empty(&bgrp->group_data));
  42292. +
  42293. + kfree(bgrp);
  42294. +}
  42295. +
  42296. +static int bfqio_css_online(struct cgroup_subsys_state *css)
  42297. +{
  42298. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  42299. +
  42300. + mutex_lock(&bfqio_mutex);
  42301. + bgrp->online = true;
  42302. + mutex_unlock(&bfqio_mutex);
  42303. +
  42304. + return 0;
  42305. +}
  42306. +
  42307. +static void bfqio_css_offline(struct cgroup_subsys_state *css)
  42308. +{
  42309. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  42310. +
  42311. + mutex_lock(&bfqio_mutex);
  42312. + bgrp->online = false;
  42313. + mutex_unlock(&bfqio_mutex);
  42314. +}
  42315. +
  42316. +struct cgroup_subsys bfqio_subsys = {
  42317. + .name = "bfqio",
  42318. + .css_alloc = bfqio_create,
  42319. + .css_online = bfqio_css_online,
  42320. + .css_offline = bfqio_css_offline,
  42321. + .can_attach = bfqio_can_attach,
  42322. + .attach = bfqio_attach,
  42323. + .css_free = bfqio_destroy,
  42324. + .subsys_id = bfqio_subsys_id,
  42325. + .base_cftypes = bfqio_files,
  42326. +};
  42327. +#else
  42328. +static inline void bfq_init_entity(struct bfq_entity *entity,
  42329. + struct bfq_group *bfqg)
  42330. +{
  42331. + entity->weight = entity->new_weight;
  42332. + entity->orig_weight = entity->new_weight;
  42333. + entity->ioprio = entity->new_ioprio;
  42334. + entity->ioprio_class = entity->new_ioprio_class;
  42335. + entity->sched_data = &bfqg->sched_data;
  42336. +}
  42337. +
  42338. +static inline struct bfq_group *
  42339. +bfq_bic_update_cgroup(struct bfq_io_cq *bic)
  42340. +{
  42341. + struct bfq_data *bfqd = bic_to_bfqd(bic);
  42342. + return bfqd->root_group;
  42343. +}
  42344. +
  42345. +static inline void bfq_bfqq_move(struct bfq_data *bfqd,
  42346. + struct bfq_queue *bfqq,
  42347. + struct bfq_entity *entity,
  42348. + struct bfq_group *bfqg)
  42349. +{
  42350. +}
  42351. +
  42352. +static void bfq_end_wr_async(struct bfq_data *bfqd)
  42353. +{
  42354. + bfq_end_wr_async_queues(bfqd, bfqd->root_group);
  42355. +}
  42356. +
  42357. +static inline void bfq_disconnect_groups(struct bfq_data *bfqd)
  42358. +{
  42359. + bfq_put_async_queues(bfqd, bfqd->root_group);
  42360. +}
  42361. +
  42362. +static inline void bfq_free_root_group(struct bfq_data *bfqd)
  42363. +{
  42364. + kfree(bfqd->root_group);
  42365. +}
  42366. +
  42367. +static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node)
  42368. +{
  42369. + struct bfq_group *bfqg;
  42370. + int i;
  42371. +
  42372. + bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node);
  42373. + if (bfqg == NULL)
  42374. + return NULL;
  42375. +
  42376. + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++)
  42377. + bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT;
  42378. +
  42379. + return bfqg;
  42380. +}
  42381. +#endif
  42382. diff -Nur linux-3.14.15/block/bfq.h linux-linaro-stable-mx6/block/bfq.h
  42383. --- linux-3.14.15/block/bfq.h 1970-01-01 01:00:00.000000000 +0100
  42384. +++ linux-linaro-stable-mx6/block/bfq.h 2014-08-20 19:31:42.192852109 +0200
  42385. @@ -0,0 +1,770 @@
  42386. +/*
  42387. + * BFQ-v7r5 for 3.14.0: data structures and common functions prototypes.
  42388. + *
  42389. + * Based on ideas and code from CFQ:
  42390. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  42391. + *
  42392. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  42393. + * Paolo Valente <paolo.valente@unimore.it>
  42394. + *
  42395. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  42396. + */
  42397. +
  42398. +#ifndef _BFQ_H
  42399. +#define _BFQ_H
  42400. +
  42401. +#include <linux/blktrace_api.h>
  42402. +#include <linux/hrtimer.h>
  42403. +#include <linux/ioprio.h>
  42404. +#include <linux/rbtree.h>
  42405. +
  42406. +#define BFQ_IOPRIO_CLASSES 3
  42407. +#define BFQ_CL_IDLE_TIMEOUT (HZ/5)
  42408. +
  42409. +#define BFQ_MIN_WEIGHT 1
  42410. +#define BFQ_MAX_WEIGHT 1000
  42411. +
  42412. +#define BFQ_DEFAULT_GRP_WEIGHT 10
  42413. +#define BFQ_DEFAULT_GRP_IOPRIO 0
  42414. +#define BFQ_DEFAULT_GRP_CLASS IOPRIO_CLASS_BE
  42415. +
  42416. +struct bfq_entity;
  42417. +
  42418. +/**
  42419. + * struct bfq_service_tree - per ioprio_class service tree.
  42420. + * @active: tree for active entities (i.e., those backlogged).
  42421. + * @idle: tree for idle entities (i.e., those not backlogged, with V <= F_i).
  42422. + * @first_idle: idle entity with minimum F_i.
  42423. + * @last_idle: idle entity with maximum F_i.
  42424. + * @vtime: scheduler virtual time.
  42425. + * @wsum: scheduler weight sum; active and idle entities contribute to it.
  42426. + *
  42427. + * Each service tree represents a B-WF2Q+ scheduler on its own. Each
  42428. + * ioprio_class has its own independent scheduler, and so its own
  42429. + * bfq_service_tree. All the fields are protected by the queue lock
  42430. + * of the containing bfqd.
  42431. + */
  42432. +struct bfq_service_tree {
  42433. + struct rb_root active;
  42434. + struct rb_root idle;
  42435. +
  42436. + struct bfq_entity *first_idle;
  42437. + struct bfq_entity *last_idle;
  42438. +
  42439. + u64 vtime;
  42440. + unsigned long wsum;
  42441. +};
  42442. +
  42443. +/**
  42444. + * struct bfq_sched_data - multi-class scheduler.
  42445. + * @in_service_entity: entity in service.
  42446. + * @next_in_service: head-of-the-line entity in the scheduler.
  42447. + * @service_tree: array of service trees, one per ioprio_class.
  42448. + *
  42449. + * bfq_sched_data is the basic scheduler queue. It supports three
  42450. + * ioprio_classes, and can be used either as a toplevel queue or as
  42451. + * an intermediate queue on a hierarchical setup.
  42452. + * @next_in_service points to the active entity of the sched_data
  42453. + * service trees that will be scheduled next.
  42454. + *
  42455. + * The supported ioprio_classes are the same as in CFQ, in descending
  42456. + * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE.
  42457. + * Requests from higher priority queues are served before all the
  42458. + * requests from lower priority queues; among requests of the same
  42459. + * queue requests are served according to B-WF2Q+.
  42460. + * All the fields are protected by the queue lock of the containing bfqd.
  42461. + */
  42462. +struct bfq_sched_data {
  42463. + struct bfq_entity *in_service_entity;
  42464. + struct bfq_entity *next_in_service;
  42465. + struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES];
  42466. +};
  42467. +
  42468. +/**
  42469. + * struct bfq_weight_counter - counter of the number of all active entities
  42470. + * with a given weight.
  42471. + * @weight: weight of the entities that this counter refers to.
  42472. + * @num_active: number of active entities with this weight.
  42473. + * @weights_node: weights tree member (see bfq_data's @queue_weights_tree
  42474. + * and @group_weights_tree).
  42475. + */
  42476. +struct bfq_weight_counter {
  42477. + short int weight;
  42478. + unsigned int num_active;
  42479. + struct rb_node weights_node;
  42480. +};
  42481. +
  42482. +/**
  42483. + * struct bfq_entity - schedulable entity.
  42484. + * @rb_node: service_tree member.
  42485. + * @weight_counter: pointer to the weight counter associated with this entity.
  42486. + * @on_st: flag, true if the entity is on a tree (either the active or
  42487. + * the idle one of its service_tree).
  42488. + * @finish: B-WF2Q+ finish timestamp (aka F_i).
  42489. + * @start: B-WF2Q+ start timestamp (aka S_i).
  42490. + * @tree: tree the entity is enqueued into; %NULL if not on a tree.
  42491. + * @min_start: minimum start time of the (active) subtree rooted at
  42492. + * this entity; used for O(log N) lookups into active trees.
  42493. + * @service: service received during the last round of service.
  42494. + * @budget: budget used to calculate F_i; F_i = S_i + @budget / @weight.
  42495. + * @weight: weight of the queue
  42496. + * @parent: parent entity, for hierarchical scheduling.
  42497. + * @my_sched_data: for non-leaf nodes in the cgroup hierarchy, the
  42498. + * associated scheduler queue, %NULL on leaf nodes.
  42499. + * @sched_data: the scheduler queue this entity belongs to.
  42500. + * @ioprio: the ioprio in use.
  42501. + * @new_weight: when a weight change is requested, the new weight value.
  42502. + * @orig_weight: original weight, used to implement weight boosting
  42503. + * @new_ioprio: when an ioprio change is requested, the new ioprio value.
  42504. + * @ioprio_class: the ioprio_class in use.
  42505. + * @new_ioprio_class: when an ioprio_class change is requested, the new
  42506. + * ioprio_class value.
  42507. + * @ioprio_changed: flag, true when the user requested a weight, ioprio or
  42508. + * ioprio_class change.
  42509. + *
  42510. + * A bfq_entity is used to represent either a bfq_queue (leaf node in the
  42511. + * cgroup hierarchy) or a bfq_group into the upper level scheduler. Each
  42512. + * entity belongs to the sched_data of the parent group in the cgroup
  42513. + * hierarchy. Non-leaf entities have also their own sched_data, stored
  42514. + * in @my_sched_data.
  42515. + *
  42516. + * Each entity stores independently its priority values; this would
  42517. + * allow different weights on different devices, but this
  42518. + * functionality is not exported to userspace by now. Priorities and
  42519. + * weights are updated lazily, first storing the new values into the
  42520. + * new_* fields, then setting the @ioprio_changed flag. As soon as
  42521. + * there is a transition in the entity state that allows the priority
  42522. + * update to take place the effective and the requested priority
  42523. + * values are synchronized.
  42524. + *
  42525. + * Unless cgroups are used, the weight value is calculated from the
  42526. + * ioprio to export the same interface as CFQ. When dealing with
  42527. + * ``well-behaved'' queues (i.e., queues that do not spend too much
  42528. + * time to consume their budget and have true sequential behavior, and
  42529. + * when there are no external factors breaking anticipation) the
  42530. + * relative weights at each level of the cgroups hierarchy should be
  42531. + * guaranteed. All the fields are protected by the queue lock of the
  42532. + * containing bfqd.
  42533. + */
  42534. +struct bfq_entity {
  42535. + struct rb_node rb_node;
  42536. + struct bfq_weight_counter *weight_counter;
  42537. +
  42538. + int on_st;
  42539. +
  42540. + u64 finish;
  42541. + u64 start;
  42542. +
  42543. + struct rb_root *tree;
  42544. +
  42545. + u64 min_start;
  42546. +
  42547. + unsigned long service, budget;
  42548. + unsigned short weight, new_weight;
  42549. + unsigned short orig_weight;
  42550. +
  42551. + struct bfq_entity *parent;
  42552. +
  42553. + struct bfq_sched_data *my_sched_data;
  42554. + struct bfq_sched_data *sched_data;
  42555. +
  42556. + unsigned short ioprio, new_ioprio;
  42557. + unsigned short ioprio_class, new_ioprio_class;
  42558. +
  42559. + int ioprio_changed;
  42560. +};
  42561. +
  42562. +struct bfq_group;
  42563. +
  42564. +/**
  42565. + * struct bfq_queue - leaf schedulable entity.
  42566. + * @ref: reference counter.
  42567. + * @bfqd: parent bfq_data.
  42568. + * @new_bfqq: shared bfq_queue if queue is cooperating with
  42569. + * one or more other queues.
  42570. + * @pos_node: request-position tree member (see bfq_data's @rq_pos_tree).
  42571. + * @pos_root: request-position tree root (see bfq_data's @rq_pos_tree).
  42572. + * @sort_list: sorted list of pending requests.
  42573. + * @next_rq: if fifo isn't expired, next request to serve.
  42574. + * @queued: nr of requests queued in @sort_list.
  42575. + * @allocated: currently allocated requests.
  42576. + * @meta_pending: pending metadata requests.
  42577. + * @fifo: fifo list of requests in sort_list.
  42578. + * @entity: entity representing this queue in the scheduler.
  42579. + * @max_budget: maximum budget allowed from the feedback mechanism.
  42580. + * @budget_timeout: budget expiration (in jiffies).
  42581. + * @dispatched: number of requests on the dispatch list or inside driver.
  42582. + * @flags: status flags.
  42583. + * @bfqq_list: node for active/idle bfqq list inside our bfqd.
  42584. + * @seek_samples: number of seeks sampled
  42585. + * @seek_total: sum of the distances of the seeks sampled
  42586. + * @seek_mean: mean seek distance
  42587. + * @last_request_pos: position of the last request enqueued
  42588. + * @requests_within_timer: number of consecutive pairs of request completion
  42589. + * and arrival, such that the queue becomes idle
  42590. + * after the completion, but the next request arrives
  42591. + * within an idle time slice; used only if the queue's
  42592. + * IO_bound has been cleared.
  42593. + * @pid: pid of the process owning the queue, used for logging purposes.
  42594. + * @last_wr_start_finish: start time of the current weight-raising period if
  42595. + * the @bfq-queue is being weight-raised, otherwise
  42596. + * finish time of the last weight-raising period
  42597. + * @wr_cur_max_time: current max raising time for this queue
  42598. + * @soft_rt_next_start: minimum time instant such that, only if a new
  42599. + * request is enqueued after this time instant in an
  42600. + * idle @bfq_queue with no outstanding requests, then
  42601. + * the task associated with the queue it is deemed as
  42602. + * soft real-time (see the comments to the function
  42603. + * bfq_bfqq_softrt_next_start())
  42604. + * @last_idle_bklogged: time of the last transition of the @bfq_queue from
  42605. + * idle to backlogged
  42606. + * @service_from_backlogged: cumulative service received from the @bfq_queue
  42607. + * since the last transition from idle to
  42608. + * backlogged
  42609. + * @bic: pointer to the bfq_io_cq owning the bfq_queue, set to %NULL if the
  42610. + * queue is shared
  42611. + *
  42612. + * A bfq_queue is a leaf request queue; it can be associated with an
  42613. + * io_context or more, if it is async or shared between cooperating
  42614. + * processes. @cgroup holds a reference to the cgroup, to be sure that it
  42615. + * does not disappear while a bfqq still references it (mostly to avoid
  42616. + * races between request issuing and task migration followed by cgroup
  42617. + * destruction).
  42618. + * All the fields are protected by the queue lock of the containing bfqd.
  42619. + */
  42620. +struct bfq_queue {
  42621. + atomic_t ref;
  42622. + struct bfq_data *bfqd;
  42623. +
  42624. + /* fields for cooperating queues handling */
  42625. + struct bfq_queue *new_bfqq;
  42626. + struct rb_node pos_node;
  42627. + struct rb_root *pos_root;
  42628. +
  42629. + struct rb_root sort_list;
  42630. + struct request *next_rq;
  42631. + int queued[2];
  42632. + int allocated[2];
  42633. + int meta_pending;
  42634. + struct list_head fifo;
  42635. +
  42636. + struct bfq_entity entity;
  42637. +
  42638. + unsigned long max_budget;
  42639. + unsigned long budget_timeout;
  42640. +
  42641. + int dispatched;
  42642. +
  42643. + unsigned int flags;
  42644. +
  42645. + struct list_head bfqq_list;
  42646. +
  42647. + unsigned int seek_samples;
  42648. + u64 seek_total;
  42649. + sector_t seek_mean;
  42650. + sector_t last_request_pos;
  42651. +
  42652. + unsigned int requests_within_timer;
  42653. +
  42654. + pid_t pid;
  42655. + struct bfq_io_cq *bic;
  42656. +
  42657. + /* weight-raising fields */
  42658. + unsigned long wr_cur_max_time;
  42659. + unsigned long soft_rt_next_start;
  42660. + unsigned long last_wr_start_finish;
  42661. + unsigned int wr_coeff;
  42662. + unsigned long last_idle_bklogged;
  42663. + unsigned long service_from_backlogged;
  42664. +};
  42665. +
  42666. +/**
  42667. + * struct bfq_ttime - per process thinktime stats.
  42668. + * @ttime_total: total process thinktime
  42669. + * @ttime_samples: number of thinktime samples
  42670. + * @ttime_mean: average process thinktime
  42671. + */
  42672. +struct bfq_ttime {
  42673. + unsigned long last_end_request;
  42674. +
  42675. + unsigned long ttime_total;
  42676. + unsigned long ttime_samples;
  42677. + unsigned long ttime_mean;
  42678. +};
  42679. +
  42680. +/**
  42681. + * struct bfq_io_cq - per (request_queue, io_context) structure.
  42682. + * @icq: associated io_cq structure
  42683. + * @bfqq: array of two process queues, the sync and the async
  42684. + * @ttime: associated @bfq_ttime struct
  42685. + * @wr_time_left: snapshot of the time left before weight raising ends
  42686. + * for the sync queue associated to this process; this
  42687. + * snapshot is taken to remember this value while the weight
  42688. + * raising is suspended because the queue is merged with a
  42689. + * shared queue, and is used to set @raising_cur_max_time
  42690. + * when the queue is split from the shared queue and its
  42691. + * weight is raised again
  42692. + * @saved_idle_window: same purpose as the previous field for the idle
  42693. + * window
  42694. + * @saved_IO_bound: same purpose as the previous two fields for the I/O
  42695. + * bound classification of a queue
  42696. + * @cooperations: counter of consecutive successful queue merges underwent
  42697. + * by any of the process' @bfq_queues
  42698. + * @failed_cooperations: counter of consecutive failed queue merges of any
  42699. + * of the process' @bfq_queues
  42700. + */
  42701. +struct bfq_io_cq {
  42702. + struct io_cq icq; /* must be the first member */
  42703. + struct bfq_queue *bfqq[2];
  42704. + struct bfq_ttime ttime;
  42705. + int ioprio;
  42706. +
  42707. + unsigned int wr_time_left;
  42708. + unsigned int saved_idle_window;
  42709. + unsigned int saved_IO_bound;
  42710. +
  42711. + unsigned int cooperations;
  42712. + unsigned int failed_cooperations;
  42713. +};
  42714. +
  42715. +enum bfq_device_speed {
  42716. + BFQ_BFQD_FAST,
  42717. + BFQ_BFQD_SLOW,
  42718. +};
  42719. +
  42720. +/**
  42721. + * struct bfq_data - per device data structure.
  42722. + * @queue: request queue for the managed device.
  42723. + * @root_group: root bfq_group for the device.
  42724. + * @rq_pos_tree: rbtree sorted by next_request position, used when
  42725. + * determining if two or more queues have interleaving
  42726. + * requests (see bfq_close_cooperator()).
  42727. + * @active_numerous_groups: number of bfq_groups containing more than one
  42728. + * active @bfq_entity.
  42729. + * @queue_weights_tree: rbtree of weight counters of @bfq_queues, sorted by
  42730. + * weight. Used to keep track of whether all @bfq_queues
  42731. + * have the same weight. The tree contains one counter
  42732. + * for each distinct weight associated to some active
  42733. + * and not weight-raised @bfq_queue (see the comments to
  42734. + * the functions bfq_weights_tree_[add|remove] for
  42735. + * further details).
  42736. + * @group_weights_tree: rbtree of non-queue @bfq_entity weight counters, sorted
  42737. + * by weight. Used to keep track of whether all
  42738. + * @bfq_groups have the same weight. The tree contains
  42739. + * one counter for each distinct weight associated to
  42740. + * some active @bfq_group (see the comments to the
  42741. + * functions bfq_weights_tree_[add|remove] for further
  42742. + * details).
  42743. + * @busy_queues: number of bfq_queues containing requests (including the
  42744. + * queue in service, even if it is idling).
  42745. + * @busy_in_flight_queues: number of @bfq_queues containing pending or
  42746. + * in-flight requests, plus the @bfq_queue in
  42747. + * service, even if idle but waiting for the
  42748. + * possible arrival of its next sync request. This
  42749. + * field is updated only if the device is rotational,
  42750. + * but used only if the device is also NCQ-capable.
  42751. + * The reason why the field is updated also for non-
  42752. + * NCQ-capable rotational devices is related to the
  42753. + * fact that the value of @hw_tag may be set also
  42754. + * later than when busy_in_flight_queues may need to
  42755. + * be incremented for the first time(s). Taking also
  42756. + * this possibility into account, to avoid unbalanced
  42757. + * increments/decrements, would imply more overhead
  42758. + * than just updating busy_in_flight_queues
  42759. + * regardless of the value of @hw_tag.
  42760. + * @const_seeky_busy_in_flight_queues: number of constantly-seeky @bfq_queues
  42761. + * (that is, seeky queues that expired
  42762. + * for budget timeout at least once)
  42763. + * containing pending or in-flight
  42764. + * requests, including the in-service
  42765. + * @bfq_queue if constantly seeky. This
  42766. + * field is updated only if the device
  42767. + * is rotational, but used only if the
  42768. + * device is also NCQ-capable (see the
  42769. + * comments to @busy_in_flight_queues).
  42770. + * @wr_busy_queues: number of weight-raised busy @bfq_queues.
  42771. + * @queued: number of queued requests.
  42772. + * @rq_in_driver: number of requests dispatched and waiting for completion.
  42773. + * @sync_flight: number of sync requests in the driver.
  42774. + * @max_rq_in_driver: max number of reqs in driver in the last
  42775. + * @hw_tag_samples completed requests.
  42776. + * @hw_tag_samples: nr of samples used to calculate hw_tag.
  42777. + * @hw_tag: flag set to one if the driver is showing a queueing behavior.
  42778. + * @budgets_assigned: number of budgets assigned.
  42779. + * @idle_slice_timer: timer set when idling for the next sequential request
  42780. + * from the queue in service.
  42781. + * @unplug_work: delayed work to restart dispatching on the request queue.
  42782. + * @in_service_queue: bfq_queue in service.
  42783. + * @in_service_bic: bfq_io_cq (bic) associated with the @in_service_queue.
  42784. + * @last_position: on-disk position of the last served request.
  42785. + * @last_budget_start: beginning of the last budget.
  42786. + * @last_idling_start: beginning of the last idle slice.
  42787. + * @peak_rate: peak transfer rate observed for a budget.
  42788. + * @peak_rate_samples: number of samples used to calculate @peak_rate.
  42789. + * @bfq_max_budget: maximum budget allotted to a bfq_queue before
  42790. + * rescheduling.
  42791. + * @group_list: list of all the bfq_groups active on the device.
  42792. + * @active_list: list of all the bfq_queues active on the device.
  42793. + * @idle_list: list of all the bfq_queues idle on the device.
  42794. + * @bfq_quantum: max number of requests dispatched per dispatch round.
  42795. + * @bfq_fifo_expire: timeout for async/sync requests; when it expires
  42796. + * requests are served in fifo order.
  42797. + * @bfq_back_penalty: weight of backward seeks wrt forward ones.
  42798. + * @bfq_back_max: maximum allowed backward seek.
  42799. + * @bfq_slice_idle: maximum idling time.
  42800. + * @bfq_user_max_budget: user-configured max budget value
  42801. + * (0 for auto-tuning).
  42802. + * @bfq_max_budget_async_rq: maximum budget (in nr of requests) allotted to
  42803. + * async queues.
  42804. + * @bfq_timeout: timeout for bfq_queues to consume their budget; used to
  42805. + * to prevent seeky queues to impose long latencies to well
  42806. + * behaved ones (this also implies that seeky queues cannot
  42807. + * receive guarantees in the service domain; after a timeout
  42808. + * they are charged for the whole allocated budget, to try
  42809. + * to preserve a behavior reasonably fair among them, but
  42810. + * without service-domain guarantees).
  42811. + * @bfq_coop_thresh: number of queue merges after which a @bfq_queue is
  42812. + * no more granted any weight-raising.
  42813. + * @bfq_failed_cooperations: number of consecutive failed cooperation
  42814. + * chances after which weight-raising is restored
  42815. + * to a queue subject to more than bfq_coop_thresh
  42816. + * queue merges.
  42817. + * @bfq_requests_within_timer: number of consecutive requests that must be
  42818. + * issued within the idle time slice to set
  42819. + * again idling to a queue which was marked as
  42820. + * non-I/O-bound (see the definition of the
  42821. + * IO_bound flag for further details).
  42822. + * @bfq_wr_coeff: Maximum factor by which the weight of a weight-raised
  42823. + * queue is multiplied
  42824. + * @bfq_wr_max_time: maximum duration of a weight-raising period (jiffies)
  42825. + * @bfq_wr_rt_max_time: maximum duration for soft real-time processes
  42826. + * @bfq_wr_min_idle_time: minimum idle period after which weight-raising
  42827. + * may be reactivated for a queue (in jiffies)
  42828. + * @bfq_wr_min_inter_arr_async: minimum period between request arrivals
  42829. + * after which weight-raising may be
  42830. + * reactivated for an already busy queue
  42831. + * (in jiffies)
  42832. + * @bfq_wr_max_softrt_rate: max service-rate for a soft real-time queue,
  42833. + * sectors per seconds
  42834. + * @RT_prod: cached value of the product R*T used for computing the maximum
  42835. + * duration of the weight raising automatically
  42836. + * @device_speed: device-speed class for the low-latency heuristic
  42837. + * @oom_bfqq: fallback dummy bfqq for extreme OOM conditions
  42838. + *
  42839. + * All the fields are protected by the @queue lock.
  42840. + */
  42841. +struct bfq_data {
  42842. + struct request_queue *queue;
  42843. +
  42844. + struct bfq_group *root_group;
  42845. + struct rb_root rq_pos_tree;
  42846. +
  42847. +#ifdef CONFIG_CGROUP_BFQIO
  42848. + int active_numerous_groups;
  42849. +#endif
  42850. +
  42851. + struct rb_root queue_weights_tree;
  42852. + struct rb_root group_weights_tree;
  42853. +
  42854. + int busy_queues;
  42855. + int busy_in_flight_queues;
  42856. + int const_seeky_busy_in_flight_queues;
  42857. + int wr_busy_queues;
  42858. + int queued;
  42859. + int rq_in_driver;
  42860. + int sync_flight;
  42861. +
  42862. + int max_rq_in_driver;
  42863. + int hw_tag_samples;
  42864. + int hw_tag;
  42865. +
  42866. + int budgets_assigned;
  42867. +
  42868. + struct timer_list idle_slice_timer;
  42869. + struct work_struct unplug_work;
  42870. +
  42871. + struct bfq_queue *in_service_queue;
  42872. + struct bfq_io_cq *in_service_bic;
  42873. +
  42874. + sector_t last_position;
  42875. +
  42876. + ktime_t last_budget_start;
  42877. + ktime_t last_idling_start;
  42878. + int peak_rate_samples;
  42879. + u64 peak_rate;
  42880. + unsigned long bfq_max_budget;
  42881. +
  42882. + struct hlist_head group_list;
  42883. + struct list_head active_list;
  42884. + struct list_head idle_list;
  42885. +
  42886. + unsigned int bfq_quantum;
  42887. + unsigned int bfq_fifo_expire[2];
  42888. + unsigned int bfq_back_penalty;
  42889. + unsigned int bfq_back_max;
  42890. + unsigned int bfq_slice_idle;
  42891. + u64 bfq_class_idle_last_service;
  42892. +
  42893. + unsigned int bfq_user_max_budget;
  42894. + unsigned int bfq_max_budget_async_rq;
  42895. + unsigned int bfq_timeout[2];
  42896. +
  42897. + unsigned int bfq_coop_thresh;
  42898. + unsigned int bfq_failed_cooperations;
  42899. + unsigned int bfq_requests_within_timer;
  42900. +
  42901. + bool low_latency;
  42902. +
  42903. + /* parameters of the low_latency heuristics */
  42904. + unsigned int bfq_wr_coeff;
  42905. + unsigned int bfq_wr_max_time;
  42906. + unsigned int bfq_wr_rt_max_time;
  42907. + unsigned int bfq_wr_min_idle_time;
  42908. + unsigned long bfq_wr_min_inter_arr_async;
  42909. + unsigned int bfq_wr_max_softrt_rate;
  42910. + u64 RT_prod;
  42911. + enum bfq_device_speed device_speed;
  42912. +
  42913. + struct bfq_queue oom_bfqq;
  42914. +};
  42915. +
  42916. +enum bfqq_state_flags {
  42917. + BFQ_BFQQ_FLAG_busy = 0, /* has requests or is in service */
  42918. + BFQ_BFQQ_FLAG_wait_request, /* waiting for a request */
  42919. + BFQ_BFQQ_FLAG_must_alloc, /* must be allowed rq alloc */
  42920. + BFQ_BFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */
  42921. + BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */
  42922. + BFQ_BFQQ_FLAG_prio_changed, /* task priority has changed */
  42923. + BFQ_BFQQ_FLAG_sync, /* synchronous queue */
  42924. + BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */
  42925. + BFQ_BFQQ_FLAG_IO_bound, /*
  42926. + * bfqq has timed-out at least once
  42927. + * having consumed at most 2/10 of
  42928. + * its budget
  42929. + */
  42930. + BFQ_BFQQ_FLAG_constantly_seeky, /*
  42931. + * bfqq has proved to be slow and
  42932. + * seeky until budget timeout
  42933. + */
  42934. + BFQ_BFQQ_FLAG_softrt_update, /*
  42935. + * may need softrt-next-start
  42936. + * update
  42937. + */
  42938. + BFQ_BFQQ_FLAG_coop, /* bfqq is shared */
  42939. + BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be split */
  42940. + BFQ_BFQQ_FLAG_just_split, /* queue has just been split */
  42941. +};
  42942. +
  42943. +#define BFQ_BFQQ_FNS(name) \
  42944. +static inline void bfq_mark_bfqq_##name(struct bfq_queue *bfqq) \
  42945. +{ \
  42946. + (bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name); \
  42947. +} \
  42948. +static inline void bfq_clear_bfqq_##name(struct bfq_queue *bfqq) \
  42949. +{ \
  42950. + (bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name); \
  42951. +} \
  42952. +static inline int bfq_bfqq_##name(const struct bfq_queue *bfqq) \
  42953. +{ \
  42954. + return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \
  42955. +}
  42956. +
  42957. +BFQ_BFQQ_FNS(busy);
  42958. +BFQ_BFQQ_FNS(wait_request);
  42959. +BFQ_BFQQ_FNS(must_alloc);
  42960. +BFQ_BFQQ_FNS(fifo_expire);
  42961. +BFQ_BFQQ_FNS(idle_window);
  42962. +BFQ_BFQQ_FNS(prio_changed);
  42963. +BFQ_BFQQ_FNS(sync);
  42964. +BFQ_BFQQ_FNS(budget_new);
  42965. +BFQ_BFQQ_FNS(IO_bound);
  42966. +BFQ_BFQQ_FNS(constantly_seeky);
  42967. +BFQ_BFQQ_FNS(coop);
  42968. +BFQ_BFQQ_FNS(split_coop);
  42969. +BFQ_BFQQ_FNS(just_split);
  42970. +BFQ_BFQQ_FNS(softrt_update);
  42971. +#undef BFQ_BFQQ_FNS
  42972. +
  42973. +/* Logging facilities. */
  42974. +#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \
  42975. + blk_add_trace_msg((bfqd)->queue, "bfq%d " fmt, (bfqq)->pid, ##args)
  42976. +
  42977. +#define bfq_log(bfqd, fmt, args...) \
  42978. + blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args)
  42979. +
  42980. +/* Expiration reasons. */
  42981. +enum bfqq_expiration {
  42982. + BFQ_BFQQ_TOO_IDLE = 0, /*
  42983. + * queue has been idling for
  42984. + * too long
  42985. + */
  42986. + BFQ_BFQQ_BUDGET_TIMEOUT, /* budget took too long to be used */
  42987. + BFQ_BFQQ_BUDGET_EXHAUSTED, /* budget consumed */
  42988. + BFQ_BFQQ_NO_MORE_REQUESTS, /* the queue has no more requests */
  42989. +};
  42990. +
  42991. +#ifdef CONFIG_CGROUP_BFQIO
  42992. +/**
  42993. + * struct bfq_group - per (device, cgroup) data structure.
  42994. + * @entity: schedulable entity to insert into the parent group sched_data.
  42995. + * @sched_data: own sched_data, to contain child entities (they may be
  42996. + * both bfq_queues and bfq_groups).
  42997. + * @group_node: node to be inserted into the bfqio_cgroup->group_data
  42998. + * list of the containing cgroup's bfqio_cgroup.
  42999. + * @bfqd_node: node to be inserted into the @bfqd->group_list list
  43000. + * of the groups active on the same device; used for cleanup.
  43001. + * @bfqd: the bfq_data for the device this group acts upon.
  43002. + * @async_bfqq: array of async queues for all the tasks belonging to
  43003. + * the group, one queue per ioprio value per ioprio_class,
  43004. + * except for the idle class that has only one queue.
  43005. + * @async_idle_bfqq: async queue for the idle class (ioprio is ignored).
  43006. + * @my_entity: pointer to @entity, %NULL for the toplevel group; used
  43007. + * to avoid too many special cases during group creation/
  43008. + * migration.
  43009. + * @active_entities: number of active entities belonging to the group;
  43010. + * unused for the root group. Used to know whether there
  43011. + * are groups with more than one active @bfq_entity
  43012. + * (see the comments to the function
  43013. + * bfq_bfqq_must_not_expire()).
  43014. + *
  43015. + * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup
  43016. + * there is a set of bfq_groups, each one collecting the lower-level
  43017. + * entities belonging to the group that are acting on the same device.
  43018. + *
  43019. + * Locking works as follows:
  43020. + * o @group_node is protected by the bfqio_cgroup lock, and is accessed
  43021. + * via RCU from its readers.
  43022. + * o @bfqd is protected by the queue lock, RCU is used to access it
  43023. + * from the readers.
  43024. + * o All the other fields are protected by the @bfqd queue lock.
  43025. + */
  43026. +struct bfq_group {
  43027. + struct bfq_entity entity;
  43028. + struct bfq_sched_data sched_data;
  43029. +
  43030. + struct hlist_node group_node;
  43031. + struct hlist_node bfqd_node;
  43032. +
  43033. + void *bfqd;
  43034. +
  43035. + struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR];
  43036. + struct bfq_queue *async_idle_bfqq;
  43037. +
  43038. + struct bfq_entity *my_entity;
  43039. +
  43040. + int active_entities;
  43041. +};
  43042. +
  43043. +/**
  43044. + * struct bfqio_cgroup - bfq cgroup data structure.
  43045. + * @css: subsystem state for bfq in the containing cgroup.
  43046. + * @online: flag marked when the subsystem is inserted.
  43047. + * @weight: cgroup weight.
  43048. + * @ioprio: cgroup ioprio.
  43049. + * @ioprio_class: cgroup ioprio_class.
  43050. + * @lock: spinlock that protects @ioprio, @ioprio_class and @group_data.
  43051. + * @group_data: list containing the bfq_group belonging to this cgroup.
  43052. + *
  43053. + * @group_data is accessed using RCU, with @lock protecting the updates,
  43054. + * @ioprio and @ioprio_class are protected by @lock.
  43055. + */
  43056. +struct bfqio_cgroup {
  43057. + struct cgroup_subsys_state css;
  43058. + bool online;
  43059. +
  43060. + unsigned short weight, ioprio, ioprio_class;
  43061. +
  43062. + spinlock_t lock;
  43063. + struct hlist_head group_data;
  43064. +};
  43065. +#else
  43066. +struct bfq_group {
  43067. + struct bfq_sched_data sched_data;
  43068. +
  43069. + struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR];
  43070. + struct bfq_queue *async_idle_bfqq;
  43071. +};
  43072. +#endif
  43073. +
  43074. +static inline struct bfq_service_tree *
  43075. +bfq_entity_service_tree(struct bfq_entity *entity)
  43076. +{
  43077. + struct bfq_sched_data *sched_data = entity->sched_data;
  43078. + unsigned int idx = entity->ioprio_class - 1;
  43079. +
  43080. + BUG_ON(idx >= BFQ_IOPRIO_CLASSES);
  43081. + BUG_ON(sched_data == NULL);
  43082. +
  43083. + return sched_data->service_tree + idx;
  43084. +}
  43085. +
  43086. +static inline struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic,
  43087. + int is_sync)
  43088. +{
  43089. + return bic->bfqq[!!is_sync];
  43090. +}
  43091. +
  43092. +static inline void bic_set_bfqq(struct bfq_io_cq *bic,
  43093. + struct bfq_queue *bfqq, int is_sync)
  43094. +{
  43095. + bic->bfqq[!!is_sync] = bfqq;
  43096. +}
  43097. +
  43098. +static inline struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic)
  43099. +{
  43100. + return bic->icq.q->elevator->elevator_data;
  43101. +}
  43102. +
  43103. +/**
  43104. + * bfq_get_bfqd_locked - get a lock to a bfqd using a RCU protected pointer.
  43105. + * @ptr: a pointer to a bfqd.
  43106. + * @flags: storage for the flags to be saved.
  43107. + *
  43108. + * This function allows bfqg->bfqd to be protected by the
  43109. + * queue lock of the bfqd they reference; the pointer is dereferenced
  43110. + * under RCU, so the storage for bfqd is assured to be safe as long
  43111. + * as the RCU read side critical section does not end. After the
  43112. + * bfqd->queue->queue_lock is taken the pointer is rechecked, to be
  43113. + * sure that no other writer accessed it. If we raced with a writer,
  43114. + * the function returns NULL, with the queue unlocked, otherwise it
  43115. + * returns the dereferenced pointer, with the queue locked.
  43116. + */
  43117. +static inline struct bfq_data *bfq_get_bfqd_locked(void **ptr,
  43118. + unsigned long *flags)
  43119. +{
  43120. + struct bfq_data *bfqd;
  43121. +
  43122. + rcu_read_lock();
  43123. + bfqd = rcu_dereference(*(struct bfq_data **)ptr);
  43124. +
  43125. + if (bfqd != NULL) {
  43126. + spin_lock_irqsave(bfqd->queue->queue_lock, *flags);
  43127. + if (*ptr == bfqd)
  43128. + goto out;
  43129. + spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags);
  43130. + }
  43131. +
  43132. + bfqd = NULL;
  43133. +out:
  43134. + rcu_read_unlock();
  43135. + return bfqd;
  43136. +}
  43137. +
  43138. +static inline void bfq_put_bfqd_unlock(struct bfq_data *bfqd,
  43139. + unsigned long *flags)
  43140. +{
  43141. + spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags);
  43142. +}
  43143. +
  43144. +static void bfq_changed_ioprio(struct bfq_io_cq *bic);
  43145. +static void bfq_put_queue(struct bfq_queue *bfqq);
  43146. +static void bfq_dispatch_insert(struct request_queue *q, struct request *rq);
  43147. +static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
  43148. + struct bfq_group *bfqg, int is_sync,
  43149. + struct bfq_io_cq *bic, gfp_t gfp_mask);
  43150. +static void bfq_end_wr_async_queues(struct bfq_data *bfqd,
  43151. + struct bfq_group *bfqg);
  43152. +static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg);
  43153. +static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq);
  43154. +
  43155. +#endif /* _BFQ_H */
  43156. diff -Nur linux-3.14.15/block/bfq-ioc.c linux-linaro-stable-mx6/block/bfq-ioc.c
  43157. --- linux-3.14.15/block/bfq-ioc.c 1970-01-01 01:00:00.000000000 +0100
  43158. +++ linux-linaro-stable-mx6/block/bfq-ioc.c 2014-08-20 19:31:42.192852109 +0200
  43159. @@ -0,0 +1,36 @@
  43160. +/*
  43161. + * BFQ: I/O context handling.
  43162. + *
  43163. + * Based on ideas and code from CFQ:
  43164. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  43165. + *
  43166. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  43167. + * Paolo Valente <paolo.valente@unimore.it>
  43168. + *
  43169. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  43170. + */
  43171. +
  43172. +/**
  43173. + * icq_to_bic - convert iocontext queue structure to bfq_io_cq.
  43174. + * @icq: the iocontext queue.
  43175. + */
  43176. +static inline struct bfq_io_cq *icq_to_bic(struct io_cq *icq)
  43177. +{
  43178. + /* bic->icq is the first member, %NULL will convert to %NULL */
  43179. + return container_of(icq, struct bfq_io_cq, icq);
  43180. +}
  43181. +
  43182. +/**
  43183. + * bfq_bic_lookup - search into @ioc a bic associated to @bfqd.
  43184. + * @bfqd: the lookup key.
  43185. + * @ioc: the io_context of the process doing I/O.
  43186. + *
  43187. + * Queue lock must be held.
  43188. + */
  43189. +static inline struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd,
  43190. + struct io_context *ioc)
  43191. +{
  43192. + if (ioc)
  43193. + return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue));
  43194. + return NULL;
  43195. +}
  43196. diff -Nur linux-3.14.15/block/bfq-iosched.c linux-linaro-stable-mx6/block/bfq-iosched.c
  43197. --- linux-3.14.15/block/bfq-iosched.c 1970-01-01 01:00:00.000000000 +0100
  43198. +++ linux-linaro-stable-mx6/block/bfq-iosched.c 2014-08-20 19:31:42.192852109 +0200
  43199. @@ -0,0 +1,3919 @@
  43200. +/*
  43201. + * Budget Fair Queueing (BFQ) disk scheduler.
  43202. + *
  43203. + * Based on ideas and code from CFQ:
  43204. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  43205. + *
  43206. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  43207. + * Paolo Valente <paolo.valente@unimore.it>
  43208. + *
  43209. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  43210. + *
  43211. + * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
  43212. + * file.
  43213. + *
  43214. + * BFQ is a proportional-share storage-I/O scheduling algorithm based on
  43215. + * the slice-by-slice service scheme of CFQ. But BFQ assigns budgets,
  43216. + * measured in number of sectors, to processes instead of time slices. The
  43217. + * device is not granted to the in-service process for a given time slice,
  43218. + * but until it has exhausted its assigned budget. This change from the time
  43219. + * to the service domain allows BFQ to distribute the device throughput
  43220. + * among processes as desired, without any distortion due to ZBR, workload
  43221. + * fluctuations or other factors. BFQ uses an ad hoc internal scheduler,
  43222. + * called B-WF2Q+, to schedule processes according to their budgets. More
  43223. + * precisely, BFQ schedules queues associated to processes. Thanks to the
  43224. + * accurate policy of B-WF2Q+, BFQ can afford to assign high budgets to
  43225. + * I/O-bound processes issuing sequential requests (to boost the
  43226. + * throughput), and yet guarantee a low latency to interactive and soft
  43227. + * real-time applications.
  43228. + *
  43229. + * BFQ is described in [1], where also a reference to the initial, more
  43230. + * theoretical paper on BFQ can be found. The interested reader can find
  43231. + * in the latter paper full details on the main algorithm, as well as
  43232. + * formulas of the guarantees and formal proofs of all the properties.
  43233. + * With respect to the version of BFQ presented in these papers, this
  43234. + * implementation adds a few more heuristics, such as the one that
  43235. + * guarantees a low latency to soft real-time applications, and a
  43236. + * hierarchical extension based on H-WF2Q+.
  43237. + *
  43238. + * B-WF2Q+ is based on WF2Q+, that is described in [2], together with
  43239. + * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N)
  43240. + * complexity derives from the one introduced with EEVDF in [3].
  43241. + *
  43242. + * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness
  43243. + * with the BFQ Disk I/O Scheduler'',
  43244. + * Proceedings of the 5th Annual International Systems and Storage
  43245. + * Conference (SYSTOR '12), June 2012.
  43246. + *
  43247. + * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf
  43248. + *
  43249. + * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing
  43250. + * Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689,
  43251. + * Oct 1997.
  43252. + *
  43253. + * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz
  43254. + *
  43255. + * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline
  43256. + * First: A Flexible and Accurate Mechanism for Proportional Share
  43257. + * Resource Allocation,'' technical report.
  43258. + *
  43259. + * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf
  43260. + */
  43261. +#include <linux/module.h>
  43262. +#include <linux/slab.h>
  43263. +#include <linux/blkdev.h>
  43264. +#include <linux/cgroup.h>
  43265. +#include <linux/elevator.h>
  43266. +#include <linux/jiffies.h>
  43267. +#include <linux/rbtree.h>
  43268. +#include <linux/ioprio.h>
  43269. +#include "bfq.h"
  43270. +#include "blk.h"
  43271. +
  43272. +/* Max number of dispatches in one round of service. */
  43273. +static const int bfq_quantum = 4;
  43274. +
  43275. +/* Expiration time of sync (0) and async (1) requests, in jiffies. */
  43276. +static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
  43277. +
  43278. +/* Maximum backwards seek, in KiB. */
  43279. +static const int bfq_back_max = 16 * 1024;
  43280. +
  43281. +/* Penalty of a backwards seek, in number of sectors. */
  43282. +static const int bfq_back_penalty = 2;
  43283. +
  43284. +/* Idling period duration, in jiffies. */
  43285. +static int bfq_slice_idle = HZ / 125;
  43286. +
  43287. +/* Default maximum budget values, in sectors and number of requests. */
  43288. +static const int bfq_default_max_budget = 16 * 1024;
  43289. +static const int bfq_max_budget_async_rq = 4;
  43290. +
  43291. +/*
  43292. + * Async to sync throughput distribution is controlled as follows:
  43293. + * when an async request is served, the entity is charged the number
  43294. + * of sectors of the request, multiplied by the factor below
  43295. + */
  43296. +static const int bfq_async_charge_factor = 10;
  43297. +
  43298. +/* Default timeout values, in jiffies, approximating CFQ defaults. */
  43299. +static const int bfq_timeout_sync = HZ / 8;
  43300. +static int bfq_timeout_async = HZ / 25;
  43301. +
  43302. +struct kmem_cache *bfq_pool;
  43303. +
  43304. +/* Below this threshold (in ms), we consider thinktime immediate. */
  43305. +#define BFQ_MIN_TT 2
  43306. +
  43307. +/* hw_tag detection: parallel requests threshold and min samples needed. */
  43308. +#define BFQ_HW_QUEUE_THRESHOLD 4
  43309. +#define BFQ_HW_QUEUE_SAMPLES 32
  43310. +
  43311. +#define BFQQ_SEEK_THR (sector_t)(8 * 1024)
  43312. +#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR)
  43313. +
  43314. +/* Min samples used for peak rate estimation (for autotuning). */
  43315. +#define BFQ_PEAK_RATE_SAMPLES 32
  43316. +
  43317. +/* Shift used for peak rate fixed precision calculations. */
  43318. +#define BFQ_RATE_SHIFT 16
  43319. +
  43320. +/*
  43321. + * By default, BFQ computes the duration of the weight raising for
  43322. + * interactive applications automatically, using the following formula:
  43323. + * duration = (R / r) * T, where r is the peak rate of the device, and
  43324. + * R and T are two reference parameters.
  43325. + * In particular, R is the peak rate of the reference device (see below),
  43326. + * and T is a reference time: given the systems that are likely to be
  43327. + * installed on the reference device according to its speed class, T is
  43328. + * about the maximum time needed, under BFQ and while reading two files in
  43329. + * parallel, to load typical large applications on these systems.
  43330. + * In practice, the slower/faster the device at hand is, the more/less it
  43331. + * takes to load applications with respect to the reference device.
  43332. + * Accordingly, the longer/shorter BFQ grants weight raising to interactive
  43333. + * applications.
  43334. + *
  43335. + * BFQ uses four different reference pairs (R, T), depending on:
  43336. + * . whether the device is rotational or non-rotational;
  43337. + * . whether the device is slow, such as old or portable HDDs, as well as
  43338. + * SD cards, or fast, such as newer HDDs and SSDs.
  43339. + *
  43340. + * The device's speed class is dynamically (re)detected in
  43341. + * bfq_update_peak_rate() every time the estimated peak rate is updated.
  43342. + *
  43343. + * In the following definitions, R_slow[0]/R_fast[0] and T_slow[0]/T_fast[0]
  43344. + * are the reference values for a slow/fast rotational device, whereas
  43345. + * R_slow[1]/R_fast[1] and T_slow[1]/T_fast[1] are the reference values for
  43346. + * a slow/fast non-rotational device. Finally, device_speed_thresh are the
  43347. + * thresholds used to switch between speed classes.
  43348. + * Both the reference peak rates and the thresholds are measured in
  43349. + * sectors/usec, left-shifted by BFQ_RATE_SHIFT.
  43350. + */
  43351. +static int R_slow[2] = {1536, 10752};
  43352. +static int R_fast[2] = {17415, 34791};
  43353. +/*
  43354. + * To improve readability, a conversion function is used to initialize the
  43355. + * following arrays, which entails that they can be initialized only in a
  43356. + * function.
  43357. + */
  43358. +static int T_slow[2];
  43359. +static int T_fast[2];
  43360. +static int device_speed_thresh[2];
  43361. +
  43362. +#define BFQ_SERVICE_TREE_INIT ((struct bfq_service_tree) \
  43363. + { RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 })
  43364. +
  43365. +#define RQ_BIC(rq) ((struct bfq_io_cq *) (rq)->elv.priv[0])
  43366. +#define RQ_BFQQ(rq) ((rq)->elv.priv[1])
  43367. +
  43368. +static inline void bfq_schedule_dispatch(struct bfq_data *bfqd);
  43369. +
  43370. +#include "bfq-ioc.c"
  43371. +#include "bfq-sched.c"
  43372. +#include "bfq-cgroup.c"
  43373. +
  43374. +#define bfq_class_idle(bfqq) ((bfqq)->entity.ioprio_class ==\
  43375. + IOPRIO_CLASS_IDLE)
  43376. +#define bfq_class_rt(bfqq) ((bfqq)->entity.ioprio_class ==\
  43377. + IOPRIO_CLASS_RT)
  43378. +
  43379. +#define bfq_sample_valid(samples) ((samples) > 80)
  43380. +
  43381. +/*
  43382. + * We regard a request as SYNC, if either it's a read or has the SYNC bit
  43383. + * set (in which case it could also be a direct WRITE).
  43384. + */
  43385. +static inline int bfq_bio_sync(struct bio *bio)
  43386. +{
  43387. + if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC))
  43388. + return 1;
  43389. +
  43390. + return 0;
  43391. +}
  43392. +
  43393. +/*
  43394. + * Scheduler run of queue, if there are requests pending and no one in the
  43395. + * driver that will restart queueing.
  43396. + */
  43397. +static inline void bfq_schedule_dispatch(struct bfq_data *bfqd)
  43398. +{
  43399. + if (bfqd->queued != 0) {
  43400. + bfq_log(bfqd, "schedule dispatch");
  43401. + kblockd_schedule_work(bfqd->queue, &bfqd->unplug_work);
  43402. + }
  43403. +}
  43404. +
  43405. +/*
  43406. + * Lifted from AS - choose which of rq1 and rq2 that is best served now.
  43407. + * We choose the request that is closesr to the head right now. Distance
  43408. + * behind the head is penalized and only allowed to a certain extent.
  43409. + */
  43410. +static struct request *bfq_choose_req(struct bfq_data *bfqd,
  43411. + struct request *rq1,
  43412. + struct request *rq2,
  43413. + sector_t last)
  43414. +{
  43415. + sector_t s1, s2, d1 = 0, d2 = 0;
  43416. + unsigned long back_max;
  43417. +#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */
  43418. +#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */
  43419. + unsigned wrap = 0; /* bit mask: requests behind the disk head? */
  43420. +
  43421. + if (rq1 == NULL || rq1 == rq2)
  43422. + return rq2;
  43423. + if (rq2 == NULL)
  43424. + return rq1;
  43425. +
  43426. + if (rq_is_sync(rq1) && !rq_is_sync(rq2))
  43427. + return rq1;
  43428. + else if (rq_is_sync(rq2) && !rq_is_sync(rq1))
  43429. + return rq2;
  43430. + if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META))
  43431. + return rq1;
  43432. + else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META))
  43433. + return rq2;
  43434. +
  43435. + s1 = blk_rq_pos(rq1);
  43436. + s2 = blk_rq_pos(rq2);
  43437. +
  43438. + /*
  43439. + * By definition, 1KiB is 2 sectors.
  43440. + */
  43441. + back_max = bfqd->bfq_back_max * 2;
  43442. +
  43443. + /*
  43444. + * Strict one way elevator _except_ in the case where we allow
  43445. + * short backward seeks which are biased as twice the cost of a
  43446. + * similar forward seek.
  43447. + */
  43448. + if (s1 >= last)
  43449. + d1 = s1 - last;
  43450. + else if (s1 + back_max >= last)
  43451. + d1 = (last - s1) * bfqd->bfq_back_penalty;
  43452. + else
  43453. + wrap |= BFQ_RQ1_WRAP;
  43454. +
  43455. + if (s2 >= last)
  43456. + d2 = s2 - last;
  43457. + else if (s2 + back_max >= last)
  43458. + d2 = (last - s2) * bfqd->bfq_back_penalty;
  43459. + else
  43460. + wrap |= BFQ_RQ2_WRAP;
  43461. +
  43462. + /* Found required data */
  43463. +
  43464. + /*
  43465. + * By doing switch() on the bit mask "wrap" we avoid having to
  43466. + * check two variables for all permutations: --> faster!
  43467. + */
  43468. + switch (wrap) {
  43469. + case 0: /* common case for CFQ: rq1 and rq2 not wrapped */
  43470. + if (d1 < d2)
  43471. + return rq1;
  43472. + else if (d2 < d1)
  43473. + return rq2;
  43474. + else {
  43475. + if (s1 >= s2)
  43476. + return rq1;
  43477. + else
  43478. + return rq2;
  43479. + }
  43480. +
  43481. + case BFQ_RQ2_WRAP:
  43482. + return rq1;
  43483. + case BFQ_RQ1_WRAP:
  43484. + return rq2;
  43485. + case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */
  43486. + default:
  43487. + /*
  43488. + * Since both rqs are wrapped,
  43489. + * start with the one that's further behind head
  43490. + * (--> only *one* back seek required),
  43491. + * since back seek takes more time than forward.
  43492. + */
  43493. + if (s1 <= s2)
  43494. + return rq1;
  43495. + else
  43496. + return rq2;
  43497. + }
  43498. +}
  43499. +
  43500. +static struct bfq_queue *
  43501. +bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root,
  43502. + sector_t sector, struct rb_node **ret_parent,
  43503. + struct rb_node ***rb_link)
  43504. +{
  43505. + struct rb_node **p, *parent;
  43506. + struct bfq_queue *bfqq = NULL;
  43507. +
  43508. + parent = NULL;
  43509. + p = &root->rb_node;
  43510. + while (*p) {
  43511. + struct rb_node **n;
  43512. +
  43513. + parent = *p;
  43514. + bfqq = rb_entry(parent, struct bfq_queue, pos_node);
  43515. +
  43516. + /*
  43517. + * Sort strictly based on sector. Smallest to the left,
  43518. + * largest to the right.
  43519. + */
  43520. + if (sector > blk_rq_pos(bfqq->next_rq))
  43521. + n = &(*p)->rb_right;
  43522. + else if (sector < blk_rq_pos(bfqq->next_rq))
  43523. + n = &(*p)->rb_left;
  43524. + else
  43525. + break;
  43526. + p = n;
  43527. + bfqq = NULL;
  43528. + }
  43529. +
  43530. + *ret_parent = parent;
  43531. + if (rb_link)
  43532. + *rb_link = p;
  43533. +
  43534. + bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d",
  43535. + (long long unsigned)sector,
  43536. + bfqq != NULL ? bfqq->pid : 0);
  43537. +
  43538. + return bfqq;
  43539. +}
  43540. +
  43541. +static void bfq_rq_pos_tree_add(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  43542. +{
  43543. + struct rb_node **p, *parent;
  43544. + struct bfq_queue *__bfqq;
  43545. +
  43546. + if (bfqq->pos_root != NULL) {
  43547. + rb_erase(&bfqq->pos_node, bfqq->pos_root);
  43548. + bfqq->pos_root = NULL;
  43549. + }
  43550. +
  43551. + if (bfq_class_idle(bfqq))
  43552. + return;
  43553. + if (!bfqq->next_rq)
  43554. + return;
  43555. +
  43556. + bfqq->pos_root = &bfqd->rq_pos_tree;
  43557. + __bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root,
  43558. + blk_rq_pos(bfqq->next_rq), &parent, &p);
  43559. + if (__bfqq == NULL) {
  43560. + rb_link_node(&bfqq->pos_node, parent, p);
  43561. + rb_insert_color(&bfqq->pos_node, bfqq->pos_root);
  43562. + } else
  43563. + bfqq->pos_root = NULL;
  43564. +}
  43565. +
  43566. +/*
  43567. + * Tell whether there are active queues or groups with differentiated weights.
  43568. + */
  43569. +static inline bool bfq_differentiated_weights(struct bfq_data *bfqd)
  43570. +{
  43571. + BUG_ON(!bfqd->hw_tag);
  43572. + /*
  43573. + * For weights to differ, at least one of the trees must contain
  43574. + * at least two nodes.
  43575. + */
  43576. + return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) &&
  43577. + (bfqd->queue_weights_tree.rb_node->rb_left ||
  43578. + bfqd->queue_weights_tree.rb_node->rb_right)
  43579. +#ifdef CONFIG_CGROUP_BFQIO
  43580. + ) ||
  43581. + (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) &&
  43582. + (bfqd->group_weights_tree.rb_node->rb_left ||
  43583. + bfqd->group_weights_tree.rb_node->rb_right)
  43584. +#endif
  43585. + );
  43586. +}
  43587. +
  43588. +/*
  43589. + * If the weight-counter tree passed as input contains no counter for
  43590. + * the weight of the input entity, then add that counter; otherwise just
  43591. + * increment the existing counter.
  43592. + *
  43593. + * Note that weight-counter trees contain few nodes in mostly symmetric
  43594. + * scenarios. For example, if all queues have the same weight, then the
  43595. + * weight-counter tree for the queues may contain at most one node.
  43596. + * This holds even if low_latency is on, because weight-raised queues
  43597. + * are not inserted in the tree.
  43598. + * In most scenarios, the rate at which nodes are created/destroyed
  43599. + * should be low too.
  43600. + */
  43601. +static void bfq_weights_tree_add(struct bfq_data *bfqd,
  43602. + struct bfq_entity *entity,
  43603. + struct rb_root *root)
  43604. +{
  43605. + struct rb_node **new = &(root->rb_node), *parent = NULL;
  43606. +
  43607. + /*
  43608. + * Do not insert if:
  43609. + * - the device does not support queueing;
  43610. + * - the entity is already associated with a counter, which happens if:
  43611. + * 1) the entity is associated with a queue, 2) a request arrival
  43612. + * has caused the queue to become both non-weight-raised, and hence
  43613. + * change its weight, and backlogged; in this respect, each
  43614. + * of the two events causes an invocation of this function,
  43615. + * 3) this is the invocation of this function caused by the second
  43616. + * event. This second invocation is actually useless, and we handle
  43617. + * this fact by exiting immediately. More efficient or clearer
  43618. + * solutions might possibly be adopted.
  43619. + */
  43620. + if (!bfqd->hw_tag || entity->weight_counter)
  43621. + return;
  43622. +
  43623. + while (*new) {
  43624. + struct bfq_weight_counter *__counter = container_of(*new,
  43625. + struct bfq_weight_counter,
  43626. + weights_node);
  43627. + parent = *new;
  43628. +
  43629. + if (entity->weight == __counter->weight) {
  43630. + entity->weight_counter = __counter;
  43631. + goto inc_counter;
  43632. + }
  43633. + if (entity->weight < __counter->weight)
  43634. + new = &((*new)->rb_left);
  43635. + else
  43636. + new = &((*new)->rb_right);
  43637. + }
  43638. +
  43639. + entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter),
  43640. + GFP_ATOMIC);
  43641. + entity->weight_counter->weight = entity->weight;
  43642. + rb_link_node(&entity->weight_counter->weights_node, parent, new);
  43643. + rb_insert_color(&entity->weight_counter->weights_node, root);
  43644. +
  43645. +inc_counter:
  43646. + entity->weight_counter->num_active++;
  43647. +}
  43648. +
  43649. +/*
  43650. + * Decrement the weight counter associated with the entity, and, if the
  43651. + * counter reaches 0, remove the counter from the tree.
  43652. + * See the comments to the function bfq_weights_tree_add() for considerations
  43653. + * about overhead.
  43654. + */
  43655. +static void bfq_weights_tree_remove(struct bfq_data *bfqd,
  43656. + struct bfq_entity *entity,
  43657. + struct rb_root *root)
  43658. +{
  43659. + /*
  43660. + * Check whether the entity is actually associated with a counter.
  43661. + * In fact, the device may not be considered NCQ-capable for a while,
  43662. + * which implies that no insertion in the weight trees is performed,
  43663. + * after which the device may start to be deemed NCQ-capable, and hence
  43664. + * this function may start to be invoked. This may cause the function
  43665. + * to be invoked for entities that are not associated with any counter.
  43666. + */
  43667. + if (!entity->weight_counter)
  43668. + return;
  43669. +
  43670. + BUG_ON(RB_EMPTY_ROOT(root));
  43671. + BUG_ON(entity->weight_counter->weight != entity->weight);
  43672. +
  43673. + BUG_ON(!entity->weight_counter->num_active);
  43674. + entity->weight_counter->num_active--;
  43675. + if (entity->weight_counter->num_active > 0)
  43676. + goto reset_entity_pointer;
  43677. +
  43678. + rb_erase(&entity->weight_counter->weights_node, root);
  43679. + kfree(entity->weight_counter);
  43680. +
  43681. +reset_entity_pointer:
  43682. + entity->weight_counter = NULL;
  43683. +}
  43684. +
  43685. +static struct request *bfq_find_next_rq(struct bfq_data *bfqd,
  43686. + struct bfq_queue *bfqq,
  43687. + struct request *last)
  43688. +{
  43689. + struct rb_node *rbnext = rb_next(&last->rb_node);
  43690. + struct rb_node *rbprev = rb_prev(&last->rb_node);
  43691. + struct request *next = NULL, *prev = NULL;
  43692. +
  43693. + BUG_ON(RB_EMPTY_NODE(&last->rb_node));
  43694. +
  43695. + if (rbprev != NULL)
  43696. + prev = rb_entry_rq(rbprev);
  43697. +
  43698. + if (rbnext != NULL)
  43699. + next = rb_entry_rq(rbnext);
  43700. + else {
  43701. + rbnext = rb_first(&bfqq->sort_list);
  43702. + if (rbnext && rbnext != &last->rb_node)
  43703. + next = rb_entry_rq(rbnext);
  43704. + }
  43705. +
  43706. + return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last));
  43707. +}
  43708. +
  43709. +/* see the definition of bfq_async_charge_factor for details */
  43710. +static inline unsigned long bfq_serv_to_charge(struct request *rq,
  43711. + struct bfq_queue *bfqq)
  43712. +{
  43713. + return blk_rq_sectors(rq) *
  43714. + (1 + ((!bfq_bfqq_sync(bfqq)) * (bfqq->wr_coeff == 1) *
  43715. + bfq_async_charge_factor));
  43716. +}
  43717. +
  43718. +/**
  43719. + * bfq_updated_next_req - update the queue after a new next_rq selection.
  43720. + * @bfqd: the device data the queue belongs to.
  43721. + * @bfqq: the queue to update.
  43722. + *
  43723. + * If the first request of a queue changes we make sure that the queue
  43724. + * has enough budget to serve at least its first request (if the
  43725. + * request has grown). We do this because if the queue has not enough
  43726. + * budget for its first request, it has to go through two dispatch
  43727. + * rounds to actually get it dispatched.
  43728. + */
  43729. +static void bfq_updated_next_req(struct bfq_data *bfqd,
  43730. + struct bfq_queue *bfqq)
  43731. +{
  43732. + struct bfq_entity *entity = &bfqq->entity;
  43733. + struct bfq_service_tree *st = bfq_entity_service_tree(entity);
  43734. + struct request *next_rq = bfqq->next_rq;
  43735. + unsigned long new_budget;
  43736. +
  43737. + if (next_rq == NULL)
  43738. + return;
  43739. +
  43740. + if (bfqq == bfqd->in_service_queue)
  43741. + /*
  43742. + * In order not to break guarantees, budgets cannot be
  43743. + * changed after an entity has been selected.
  43744. + */
  43745. + return;
  43746. +
  43747. + BUG_ON(entity->tree != &st->active);
  43748. + BUG_ON(entity == entity->sched_data->in_service_entity);
  43749. +
  43750. + new_budget = max_t(unsigned long, bfqq->max_budget,
  43751. + bfq_serv_to_charge(next_rq, bfqq));
  43752. + if (entity->budget != new_budget) {
  43753. + entity->budget = new_budget;
  43754. + bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu",
  43755. + new_budget);
  43756. + bfq_activate_bfqq(bfqd, bfqq);
  43757. + }
  43758. +}
  43759. +
  43760. +static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd)
  43761. +{
  43762. + u64 dur;
  43763. +
  43764. + if (bfqd->bfq_wr_max_time > 0)
  43765. + return bfqd->bfq_wr_max_time;
  43766. +
  43767. + dur = bfqd->RT_prod;
  43768. + do_div(dur, bfqd->peak_rate);
  43769. +
  43770. + return dur;
  43771. +}
  43772. +
  43773. +static inline unsigned
  43774. +bfq_bfqq_cooperations(struct bfq_queue *bfqq)
  43775. +{
  43776. + return bfqq->bic ? bfqq->bic->cooperations : 0;
  43777. +}
  43778. +
  43779. +static inline void
  43780. +bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
  43781. +{
  43782. + if (bic->saved_idle_window)
  43783. + bfq_mark_bfqq_idle_window(bfqq);
  43784. + else
  43785. + bfq_clear_bfqq_idle_window(bfqq);
  43786. + if (bic->saved_IO_bound)
  43787. + bfq_mark_bfqq_IO_bound(bfqq);
  43788. + else
  43789. + bfq_clear_bfqq_IO_bound(bfqq);
  43790. + if (bic->wr_time_left && bfqq->bfqd->low_latency &&
  43791. + bic->cooperations < bfqq->bfqd->bfq_coop_thresh) {
  43792. + /*
  43793. + * Start a weight raising period with the duration given by
  43794. + * the raising_time_left snapshot.
  43795. + */
  43796. + if (bfq_bfqq_busy(bfqq))
  43797. + bfqq->bfqd->wr_busy_queues++;
  43798. + bfqq->wr_coeff = bfqq->bfqd->bfq_wr_coeff;
  43799. + bfqq->wr_cur_max_time = bic->wr_time_left;
  43800. + bfqq->last_wr_start_finish = jiffies;
  43801. + bfqq->entity.ioprio_changed = 1;
  43802. + }
  43803. + /*
  43804. + * Clear wr_time_left to prevent bfq_bfqq_save_state() from
  43805. + * getting confused about the queue's need of a weight-raising
  43806. + * period.
  43807. + */
  43808. + bic->wr_time_left = 0;
  43809. +}
  43810. +
  43811. +/*
  43812. + * Must be called with the queue_lock held.
  43813. + */
  43814. +static int bfqq_process_refs(struct bfq_queue *bfqq)
  43815. +{
  43816. + int process_refs, io_refs;
  43817. +
  43818. + io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE];
  43819. + process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st;
  43820. + BUG_ON(process_refs < 0);
  43821. + return process_refs;
  43822. +}
  43823. +
  43824. +static void bfq_add_request(struct request *rq)
  43825. +{
  43826. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  43827. + struct bfq_entity *entity = &bfqq->entity;
  43828. + struct bfq_data *bfqd = bfqq->bfqd;
  43829. + struct request *next_rq, *prev;
  43830. + unsigned long old_wr_coeff = bfqq->wr_coeff;
  43831. + int idle_for_long_time = 0;
  43832. +
  43833. + bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq));
  43834. + bfqq->queued[rq_is_sync(rq)]++;
  43835. + bfqd->queued++;
  43836. +
  43837. + elv_rb_add(&bfqq->sort_list, rq);
  43838. +
  43839. + /*
  43840. + * Check if this request is a better next-serve candidate.
  43841. + */
  43842. + prev = bfqq->next_rq;
  43843. + next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position);
  43844. + BUG_ON(next_rq == NULL);
  43845. + bfqq->next_rq = next_rq;
  43846. +
  43847. + /*
  43848. + * Adjust priority tree position, if next_rq changes.
  43849. + */
  43850. + if (prev != bfqq->next_rq)
  43851. + bfq_rq_pos_tree_add(bfqd, bfqq);
  43852. +
  43853. + if (!bfq_bfqq_busy(bfqq)) {
  43854. + int soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 &&
  43855. + bfq_bfqq_cooperations(bfqq) < bfqd->bfq_coop_thresh &&
  43856. + time_is_before_jiffies(bfqq->soft_rt_next_start);
  43857. + idle_for_long_time = bfq_bfqq_cooperations(bfqq) <
  43858. + bfqd->bfq_coop_thresh &&
  43859. + time_is_before_jiffies(
  43860. + bfqq->budget_timeout +
  43861. + bfqd->bfq_wr_min_idle_time);
  43862. + entity->budget = max_t(unsigned long, bfqq->max_budget,
  43863. + bfq_serv_to_charge(next_rq, bfqq));
  43864. +
  43865. + if (!bfq_bfqq_IO_bound(bfqq)) {
  43866. + if (time_before(jiffies,
  43867. + RQ_BIC(rq)->ttime.last_end_request +
  43868. + bfqd->bfq_slice_idle)) {
  43869. + bfqq->requests_within_timer++;
  43870. + if (bfqq->requests_within_timer >=
  43871. + bfqd->bfq_requests_within_timer)
  43872. + bfq_mark_bfqq_IO_bound(bfqq);
  43873. + } else
  43874. + bfqq->requests_within_timer = 0;
  43875. + }
  43876. +
  43877. + if (!bfqd->low_latency)
  43878. + goto add_bfqq_busy;
  43879. +
  43880. + if (bfq_bfqq_just_split(bfqq))
  43881. + goto set_ioprio_changed;
  43882. +
  43883. + /*
  43884. + * If the queue:
  43885. + * - is not being boosted,
  43886. + * - has been idle for enough time,
  43887. + * - is not a sync queue or is linked to a bfq_io_cq (it is
  43888. + * shared "for its nature" or it is not shared and its
  43889. + * requests have not been redirected to a shared queue)
  43890. + * start a weight-raising period.
  43891. + */
  43892. + if (old_wr_coeff == 1 && (idle_for_long_time || soft_rt) &&
  43893. + (!bfq_bfqq_sync(bfqq) || bfqq->bic != NULL)) {
  43894. + bfqq->wr_coeff = bfqd->bfq_wr_coeff;
  43895. + if (idle_for_long_time)
  43896. + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
  43897. + else
  43898. + bfqq->wr_cur_max_time =
  43899. + bfqd->bfq_wr_rt_max_time;
  43900. + bfq_log_bfqq(bfqd, bfqq,
  43901. + "wrais starting at %lu, rais_max_time %u",
  43902. + jiffies,
  43903. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  43904. + } else if (old_wr_coeff > 1) {
  43905. + if (idle_for_long_time)
  43906. + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
  43907. + else if (bfq_bfqq_cooperations(bfqq) >=
  43908. + bfqd->bfq_coop_thresh ||
  43909. + (bfqq->wr_cur_max_time ==
  43910. + bfqd->bfq_wr_rt_max_time &&
  43911. + !soft_rt)) {
  43912. + bfqq->wr_coeff = 1;
  43913. + bfq_log_bfqq(bfqd, bfqq,
  43914. + "wrais ending at %lu, rais_max_time %u",
  43915. + jiffies,
  43916. + jiffies_to_msecs(bfqq->
  43917. + wr_cur_max_time));
  43918. + } else if (time_before(
  43919. + bfqq->last_wr_start_finish +
  43920. + bfqq->wr_cur_max_time,
  43921. + jiffies +
  43922. + bfqd->bfq_wr_rt_max_time) &&
  43923. + soft_rt) {
  43924. + /*
  43925. + *
  43926. + * The remaining weight-raising time is lower
  43927. + * than bfqd->bfq_wr_rt_max_time, which means
  43928. + * that the application is enjoying weight
  43929. + * raising either because deemed soft-rt in
  43930. + * the near past, or because deemed interactive
  43931. + * a long ago.
  43932. + * In both cases, resetting now the current
  43933. + * remaining weight-raising time for the
  43934. + * application to the weight-raising duration
  43935. + * for soft rt applications would not cause any
  43936. + * latency increase for the application (as the
  43937. + * new duration would be higher than the
  43938. + * remaining time).
  43939. + *
  43940. + * In addition, the application is now meeting
  43941. + * the requirements for being deemed soft rt.
  43942. + * In the end we can correctly and safely
  43943. + * (re)charge the weight-raising duration for
  43944. + * the application with the weight-raising
  43945. + * duration for soft rt applications.
  43946. + *
  43947. + * In particular, doing this recharge now, i.e.,
  43948. + * before the weight-raising period for the
  43949. + * application finishes, reduces the probability
  43950. + * of the following negative scenario:
  43951. + * 1) the weight of a soft rt application is
  43952. + * raised at startup (as for any newly
  43953. + * created application),
  43954. + * 2) since the application is not interactive,
  43955. + * at a certain time weight-raising is
  43956. + * stopped for the application,
  43957. + * 3) at that time the application happens to
  43958. + * still have pending requests, and hence
  43959. + * is destined to not have a chance to be
  43960. + * deemed soft rt before these requests are
  43961. + * completed (see the comments to the
  43962. + * function bfq_bfqq_softrt_next_start()
  43963. + * for details on soft rt detection),
  43964. + * 4) these pending requests experience a high
  43965. + * latency because the application is not
  43966. + * weight-raised while they are pending.
  43967. + */
  43968. + bfqq->last_wr_start_finish = jiffies;
  43969. + bfqq->wr_cur_max_time =
  43970. + bfqd->bfq_wr_rt_max_time;
  43971. + }
  43972. + }
  43973. +set_ioprio_changed:
  43974. + if (old_wr_coeff != bfqq->wr_coeff)
  43975. + entity->ioprio_changed = 1;
  43976. +add_bfqq_busy:
  43977. + bfqq->last_idle_bklogged = jiffies;
  43978. + bfqq->service_from_backlogged = 0;
  43979. + bfq_clear_bfqq_softrt_update(bfqq);
  43980. + bfq_add_bfqq_busy(bfqd, bfqq);
  43981. + } else {
  43982. + if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) &&
  43983. + time_is_before_jiffies(
  43984. + bfqq->last_wr_start_finish +
  43985. + bfqd->bfq_wr_min_inter_arr_async)) {
  43986. + bfqq->wr_coeff = bfqd->bfq_wr_coeff;
  43987. + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
  43988. +
  43989. + bfqd->wr_busy_queues++;
  43990. + entity->ioprio_changed = 1;
  43991. + bfq_log_bfqq(bfqd, bfqq,
  43992. + "non-idle wrais starting at %lu, rais_max_time %u",
  43993. + jiffies,
  43994. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  43995. + }
  43996. + if (prev != bfqq->next_rq)
  43997. + bfq_updated_next_req(bfqd, bfqq);
  43998. + }
  43999. +
  44000. + if (bfqd->low_latency &&
  44001. + (old_wr_coeff == 1 || bfqq->wr_coeff == 1 ||
  44002. + idle_for_long_time))
  44003. + bfqq->last_wr_start_finish = jiffies;
  44004. +}
  44005. +
  44006. +static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd,
  44007. + struct bio *bio)
  44008. +{
  44009. + struct task_struct *tsk = current;
  44010. + struct bfq_io_cq *bic;
  44011. + struct bfq_queue *bfqq;
  44012. +
  44013. + bic = bfq_bic_lookup(bfqd, tsk->io_context);
  44014. + if (bic == NULL)
  44015. + return NULL;
  44016. +
  44017. + bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio));
  44018. + if (bfqq != NULL)
  44019. + return elv_rb_find(&bfqq->sort_list, bio_end_sector(bio));
  44020. +
  44021. + return NULL;
  44022. +}
  44023. +
  44024. +static void bfq_activate_request(struct request_queue *q, struct request *rq)
  44025. +{
  44026. + struct bfq_data *bfqd = q->elevator->elevator_data;
  44027. +
  44028. + bfqd->rq_in_driver++;
  44029. + bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
  44030. + bfq_log(bfqd, "activate_request: new bfqd->last_position %llu",
  44031. + (long long unsigned)bfqd->last_position);
  44032. +}
  44033. +
  44034. +static inline void bfq_deactivate_request(struct request_queue *q,
  44035. + struct request *rq)
  44036. +{
  44037. + struct bfq_data *bfqd = q->elevator->elevator_data;
  44038. +
  44039. + BUG_ON(bfqd->rq_in_driver == 0);
  44040. + bfqd->rq_in_driver--;
  44041. +}
  44042. +
  44043. +static void bfq_remove_request(struct request *rq)
  44044. +{
  44045. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  44046. + struct bfq_data *bfqd = bfqq->bfqd;
  44047. + const int sync = rq_is_sync(rq);
  44048. +
  44049. + if (bfqq->next_rq == rq) {
  44050. + bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq);
  44051. + bfq_updated_next_req(bfqd, bfqq);
  44052. + }
  44053. +
  44054. + list_del_init(&rq->queuelist);
  44055. + BUG_ON(bfqq->queued[sync] == 0);
  44056. + bfqq->queued[sync]--;
  44057. + bfqd->queued--;
  44058. + elv_rb_del(&bfqq->sort_list, rq);
  44059. +
  44060. + if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
  44061. + if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue)
  44062. + bfq_del_bfqq_busy(bfqd, bfqq, 1);
  44063. + /*
  44064. + * Remove queue from request-position tree as it is empty.
  44065. + */
  44066. + if (bfqq->pos_root != NULL) {
  44067. + rb_erase(&bfqq->pos_node, bfqq->pos_root);
  44068. + bfqq->pos_root = NULL;
  44069. + }
  44070. + }
  44071. +
  44072. + if (rq->cmd_flags & REQ_META) {
  44073. + BUG_ON(bfqq->meta_pending == 0);
  44074. + bfqq->meta_pending--;
  44075. + }
  44076. +}
  44077. +
  44078. +static int bfq_merge(struct request_queue *q, struct request **req,
  44079. + struct bio *bio)
  44080. +{
  44081. + struct bfq_data *bfqd = q->elevator->elevator_data;
  44082. + struct request *__rq;
  44083. +
  44084. + __rq = bfq_find_rq_fmerge(bfqd, bio);
  44085. + if (__rq != NULL && elv_rq_merge_ok(__rq, bio)) {
  44086. + *req = __rq;
  44087. + return ELEVATOR_FRONT_MERGE;
  44088. + }
  44089. +
  44090. + return ELEVATOR_NO_MERGE;
  44091. +}
  44092. +
  44093. +static void bfq_merged_request(struct request_queue *q, struct request *req,
  44094. + int type)
  44095. +{
  44096. + if (type == ELEVATOR_FRONT_MERGE &&
  44097. + rb_prev(&req->rb_node) &&
  44098. + blk_rq_pos(req) <
  44099. + blk_rq_pos(container_of(rb_prev(&req->rb_node),
  44100. + struct request, rb_node))) {
  44101. + struct bfq_queue *bfqq = RQ_BFQQ(req);
  44102. + struct bfq_data *bfqd = bfqq->bfqd;
  44103. + struct request *prev, *next_rq;
  44104. +
  44105. + /* Reposition request in its sort_list */
  44106. + elv_rb_del(&bfqq->sort_list, req);
  44107. + elv_rb_add(&bfqq->sort_list, req);
  44108. + /* Choose next request to be served for bfqq */
  44109. + prev = bfqq->next_rq;
  44110. + next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req,
  44111. + bfqd->last_position);
  44112. + BUG_ON(next_rq == NULL);
  44113. + bfqq->next_rq = next_rq;
  44114. + /*
  44115. + * If next_rq changes, update both the queue's budget to
  44116. + * fit the new request and the queue's position in its
  44117. + * rq_pos_tree.
  44118. + */
  44119. + if (prev != bfqq->next_rq) {
  44120. + bfq_updated_next_req(bfqd, bfqq);
  44121. + bfq_rq_pos_tree_add(bfqd, bfqq);
  44122. + }
  44123. + }
  44124. +}
  44125. +
  44126. +static void bfq_merged_requests(struct request_queue *q, struct request *rq,
  44127. + struct request *next)
  44128. +{
  44129. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  44130. +
  44131. + /*
  44132. + * Reposition in fifo if next is older than rq.
  44133. + */
  44134. + if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) &&
  44135. + time_before(rq_fifo_time(next), rq_fifo_time(rq))) {
  44136. + list_move(&rq->queuelist, &next->queuelist);
  44137. + rq_set_fifo_time(rq, rq_fifo_time(next));
  44138. + }
  44139. +
  44140. + if (bfqq->next_rq == next)
  44141. + bfqq->next_rq = rq;
  44142. +
  44143. + bfq_remove_request(next);
  44144. +}
  44145. +
  44146. +/* Must be called with bfqq != NULL */
  44147. +static inline void bfq_bfqq_end_wr(struct bfq_queue *bfqq)
  44148. +{
  44149. + BUG_ON(bfqq == NULL);
  44150. + if (bfq_bfqq_busy(bfqq))
  44151. + bfqq->bfqd->wr_busy_queues--;
  44152. + bfqq->wr_coeff = 1;
  44153. + bfqq->wr_cur_max_time = 0;
  44154. + /* Trigger a weight change on the next activation of the queue */
  44155. + bfqq->entity.ioprio_changed = 1;
  44156. +}
  44157. +
  44158. +static void bfq_end_wr_async_queues(struct bfq_data *bfqd,
  44159. + struct bfq_group *bfqg)
  44160. +{
  44161. + int i, j;
  44162. +
  44163. + for (i = 0; i < 2; i++)
  44164. + for (j = 0; j < IOPRIO_BE_NR; j++)
  44165. + if (bfqg->async_bfqq[i][j] != NULL)
  44166. + bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]);
  44167. + if (bfqg->async_idle_bfqq != NULL)
  44168. + bfq_bfqq_end_wr(bfqg->async_idle_bfqq);
  44169. +}
  44170. +
  44171. +static void bfq_end_wr(struct bfq_data *bfqd)
  44172. +{
  44173. + struct bfq_queue *bfqq;
  44174. +
  44175. + spin_lock_irq(bfqd->queue->queue_lock);
  44176. +
  44177. + list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list)
  44178. + bfq_bfqq_end_wr(bfqq);
  44179. + list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list)
  44180. + bfq_bfqq_end_wr(bfqq);
  44181. + bfq_end_wr_async(bfqd);
  44182. +
  44183. + spin_unlock_irq(bfqd->queue->queue_lock);
  44184. +}
  44185. +
  44186. +static inline sector_t bfq_io_struct_pos(void *io_struct, bool request)
  44187. +{
  44188. + if (request)
  44189. + return blk_rq_pos(io_struct);
  44190. + else
  44191. + return ((struct bio *)io_struct)->bi_iter.bi_sector;
  44192. +}
  44193. +
  44194. +static inline sector_t bfq_dist_from(sector_t pos1,
  44195. + sector_t pos2)
  44196. +{
  44197. + if (pos1 >= pos2)
  44198. + return pos1 - pos2;
  44199. + else
  44200. + return pos2 - pos1;
  44201. +}
  44202. +
  44203. +static inline int bfq_rq_close_to_sector(void *io_struct, bool request,
  44204. + sector_t sector)
  44205. +{
  44206. + return bfq_dist_from(bfq_io_struct_pos(io_struct, request), sector) <=
  44207. + BFQQ_SEEK_THR;
  44208. +}
  44209. +
  44210. +static struct bfq_queue *bfqq_close(struct bfq_data *bfqd, sector_t sector)
  44211. +{
  44212. + struct rb_root *root = &bfqd->rq_pos_tree;
  44213. + struct rb_node *parent, *node;
  44214. + struct bfq_queue *__bfqq;
  44215. +
  44216. + if (RB_EMPTY_ROOT(root))
  44217. + return NULL;
  44218. +
  44219. + /*
  44220. + * First, if we find a request starting at the end of the last
  44221. + * request, choose it.
  44222. + */
  44223. + __bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL);
  44224. + if (__bfqq != NULL)
  44225. + return __bfqq;
  44226. +
  44227. + /*
  44228. + * If the exact sector wasn't found, the parent of the NULL leaf
  44229. + * will contain the closest sector (rq_pos_tree sorted by
  44230. + * next_request position).
  44231. + */
  44232. + __bfqq = rb_entry(parent, struct bfq_queue, pos_node);
  44233. + if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector))
  44234. + return __bfqq;
  44235. +
  44236. + if (blk_rq_pos(__bfqq->next_rq) < sector)
  44237. + node = rb_next(&__bfqq->pos_node);
  44238. + else
  44239. + node = rb_prev(&__bfqq->pos_node);
  44240. + if (node == NULL)
  44241. + return NULL;
  44242. +
  44243. + __bfqq = rb_entry(node, struct bfq_queue, pos_node);
  44244. + if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector))
  44245. + return __bfqq;
  44246. +
  44247. + return NULL;
  44248. +}
  44249. +
  44250. +/*
  44251. + * bfqd - obvious
  44252. + * cur_bfqq - passed in so that we don't decide that the current queue
  44253. + * is closely cooperating with itself
  44254. + * sector - used as a reference point to search for a close queue
  44255. + */
  44256. +static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd,
  44257. + struct bfq_queue *cur_bfqq,
  44258. + sector_t sector)
  44259. +{
  44260. + struct bfq_queue *bfqq;
  44261. +
  44262. + if (bfq_class_idle(cur_bfqq))
  44263. + return NULL;
  44264. + if (!bfq_bfqq_sync(cur_bfqq))
  44265. + return NULL;
  44266. + if (BFQQ_SEEKY(cur_bfqq))
  44267. + return NULL;
  44268. +
  44269. + /* If device has only one backlogged bfq_queue, don't search. */
  44270. + if (bfqd->busy_queues == 1)
  44271. + return NULL;
  44272. +
  44273. + /*
  44274. + * We should notice if some of the queues are cooperating, e.g.
  44275. + * working closely on the same area of the disk. In that case,
  44276. + * we can group them together and don't waste time idling.
  44277. + */
  44278. + bfqq = bfqq_close(bfqd, sector);
  44279. + if (bfqq == NULL || bfqq == cur_bfqq)
  44280. + return NULL;
  44281. +
  44282. + /*
  44283. + * Do not merge queues from different bfq_groups.
  44284. + */
  44285. + if (bfqq->entity.parent != cur_bfqq->entity.parent)
  44286. + return NULL;
  44287. +
  44288. + /*
  44289. + * It only makes sense to merge sync queues.
  44290. + */
  44291. + if (!bfq_bfqq_sync(bfqq))
  44292. + return NULL;
  44293. + if (BFQQ_SEEKY(bfqq))
  44294. + return NULL;
  44295. +
  44296. + /*
  44297. + * Do not merge queues of different priority classes.
  44298. + */
  44299. + if (bfq_class_rt(bfqq) != bfq_class_rt(cur_bfqq))
  44300. + return NULL;
  44301. +
  44302. + return bfqq;
  44303. +}
  44304. +
  44305. +static struct bfq_queue *
  44306. +bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
  44307. +{
  44308. + int process_refs, new_process_refs;
  44309. + struct bfq_queue *__bfqq;
  44310. +
  44311. + /*
  44312. + * If there are no process references on the new_bfqq, then it is
  44313. + * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain
  44314. + * may have dropped their last reference (not just their last process
  44315. + * reference).
  44316. + */
  44317. + if (!bfqq_process_refs(new_bfqq))
  44318. + return NULL;
  44319. +
  44320. + /* Avoid a circular list and skip interim queue merges. */
  44321. + while ((__bfqq = new_bfqq->new_bfqq)) {
  44322. + if (__bfqq == bfqq)
  44323. + return NULL;
  44324. + new_bfqq = __bfqq;
  44325. + }
  44326. +
  44327. + process_refs = bfqq_process_refs(bfqq);
  44328. + new_process_refs = bfqq_process_refs(new_bfqq);
  44329. + /*
  44330. + * If the process for the bfqq has gone away, there is no
  44331. + * sense in merging the queues.
  44332. + */
  44333. + if (process_refs == 0 || new_process_refs == 0)
  44334. + return NULL;
  44335. +
  44336. + bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d",
  44337. + new_bfqq->pid);
  44338. +
  44339. + /*
  44340. + * Merging is just a redirection: the requests of the process
  44341. + * owning one of the two queues are redirected to the other queue.
  44342. + * The latter queue, in its turn, is set as shared if this is the
  44343. + * first time that the requests of some process are redirected to
  44344. + * it.
  44345. + *
  44346. + * We redirect bfqq to new_bfqq and not the opposite, because we
  44347. + * are in the context of the process owning bfqq, hence we have
  44348. + * the io_cq of this process. So we can immediately configure this
  44349. + * io_cq to redirect the requests of the process to new_bfqq.
  44350. + *
  44351. + * NOTE, even if new_bfqq coincides with the in-service queue, the
  44352. + * io_cq of new_bfqq is not available, because, if the in-service
  44353. + * queue is shared, bfqd->in_service_bic may not point to the
  44354. + * io_cq of the in-service queue.
  44355. + * Redirecting the requests of the process owning bfqq to the
  44356. + * currently in-service queue is in any case the best option, as
  44357. + * we feed the in-service queue with new requests close to the
  44358. + * last request served and, by doing so, hopefully increase the
  44359. + * throughput.
  44360. + */
  44361. + bfqq->new_bfqq = new_bfqq;
  44362. + atomic_add(process_refs, &new_bfqq->ref);
  44363. + return new_bfqq;
  44364. +}
  44365. +
  44366. +/*
  44367. + * Attempt to schedule a merge of bfqq with the currently in-service queue
  44368. + * or with a close queue among the scheduled queues.
  44369. + * Return NULL if no merge was scheduled, a pointer to the shared bfq_queue
  44370. + * structure otherwise.
  44371. + */
  44372. +static struct bfq_queue *
  44373. +bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  44374. + void *io_struct, bool request)
  44375. +{
  44376. + struct bfq_queue *in_service_bfqq, *new_bfqq;
  44377. +
  44378. + if (bfqq->new_bfqq)
  44379. + return bfqq->new_bfqq;
  44380. +
  44381. + if (!io_struct)
  44382. + return NULL;
  44383. +
  44384. + in_service_bfqq = bfqd->in_service_queue;
  44385. +
  44386. + if (in_service_bfqq == NULL || in_service_bfqq == bfqq ||
  44387. + !bfqd->in_service_bic)
  44388. + goto check_scheduled;
  44389. +
  44390. + if (bfq_class_idle(in_service_bfqq) || bfq_class_idle(bfqq))
  44391. + goto check_scheduled;
  44392. +
  44393. + if (bfq_class_rt(in_service_bfqq) != bfq_class_rt(bfqq))
  44394. + goto check_scheduled;
  44395. +
  44396. + if (in_service_bfqq->entity.parent != bfqq->entity.parent)
  44397. + goto check_scheduled;
  44398. +
  44399. + if (bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) &&
  44400. + bfq_bfqq_sync(in_service_bfqq) && bfq_bfqq_sync(bfqq)) {
  44401. + new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq);
  44402. + if (new_bfqq != NULL)
  44403. + return new_bfqq; /* Merge with in-service queue */
  44404. + }
  44405. +
  44406. + /*
  44407. + * Check whether there is a cooperator among currently scheduled
  44408. + * queues. The only thing we need is that the bio/request is not
  44409. + * NULL, as we need it to establish whether a cooperator exists.
  44410. + */
  44411. +check_scheduled:
  44412. + new_bfqq = bfq_close_cooperator(bfqd, bfqq,
  44413. + bfq_io_struct_pos(io_struct, request));
  44414. + if (new_bfqq)
  44415. + return bfq_setup_merge(bfqq, new_bfqq);
  44416. +
  44417. + return NULL;
  44418. +}
  44419. +
  44420. +static inline void
  44421. +bfq_bfqq_save_state(struct bfq_queue *bfqq)
  44422. +{
  44423. + /*
  44424. + * If bfqq->bic == NULL, the queue is already shared or its requests
  44425. + * have already been redirected to a shared queue; both idle window
  44426. + * and weight raising state have already been saved. Do nothing.
  44427. + */
  44428. + if (bfqq->bic == NULL)
  44429. + return;
  44430. + if (bfqq->bic->wr_time_left)
  44431. + /*
  44432. + * This is the queue of a just-started process, and would
  44433. + * deserve weight raising: we set wr_time_left to the full
  44434. + * weight-raising duration to trigger weight-raising when
  44435. + * and if the queue is split and the first request of the
  44436. + * queue is enqueued.
  44437. + */
  44438. + bfqq->bic->wr_time_left = bfq_wr_duration(bfqq->bfqd);
  44439. + else if (bfqq->wr_coeff > 1) {
  44440. + unsigned long wr_duration =
  44441. + jiffies - bfqq->last_wr_start_finish;
  44442. + /*
  44443. + * It may happen that a queue's weight raising period lasts
  44444. + * longer than its wr_cur_max_time, as weight raising is
  44445. + * handled only when a request is enqueued or dispatched (it
  44446. + * does not use any timer). If the weight raising period is
  44447. + * about to end, don't save it.
  44448. + */
  44449. + if (bfqq->wr_cur_max_time <= wr_duration)
  44450. + bfqq->bic->wr_time_left = 0;
  44451. + else
  44452. + bfqq->bic->wr_time_left =
  44453. + bfqq->wr_cur_max_time - wr_duration;
  44454. + /*
  44455. + * The bfq_queue is becoming shared or the requests of the
  44456. + * process owning the queue are being redirected to a shared
  44457. + * queue. Stop the weight raising period of the queue, as in
  44458. + * both cases it should not be owned by an interactive or
  44459. + * soft real-time application.
  44460. + */
  44461. + bfq_bfqq_end_wr(bfqq);
  44462. + } else
  44463. + bfqq->bic->wr_time_left = 0;
  44464. + bfqq->bic->saved_idle_window = bfq_bfqq_idle_window(bfqq);
  44465. + bfqq->bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq);
  44466. + bfqq->bic->cooperations++;
  44467. + bfqq->bic->failed_cooperations = 0;
  44468. +}
  44469. +
  44470. +static inline void
  44471. +bfq_get_bic_reference(struct bfq_queue *bfqq)
  44472. +{
  44473. + /*
  44474. + * If bfqq->bic has a non-NULL value, the bic to which it belongs
  44475. + * is about to begin using a shared bfq_queue.
  44476. + */
  44477. + if (bfqq->bic)
  44478. + atomic_long_inc(&bfqq->bic->icq.ioc->refcount);
  44479. +}
  44480. +
  44481. +static void
  44482. +bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
  44483. + struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
  44484. +{
  44485. + bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu",
  44486. + (long unsigned)new_bfqq->pid);
  44487. + /* Save weight raising and idle window of the merged queues */
  44488. + bfq_bfqq_save_state(bfqq);
  44489. + bfq_bfqq_save_state(new_bfqq);
  44490. + if (bfq_bfqq_IO_bound(bfqq))
  44491. + bfq_mark_bfqq_IO_bound(new_bfqq);
  44492. + bfq_clear_bfqq_IO_bound(bfqq);
  44493. + /*
  44494. + * Grab a reference to the bic, to prevent it from being destroyed
  44495. + * before being possibly touched by a bfq_split_bfqq().
  44496. + */
  44497. + bfq_get_bic_reference(bfqq);
  44498. + bfq_get_bic_reference(new_bfqq);
  44499. + /*
  44500. + * Merge queues (that is, let bic redirect its requests to new_bfqq)
  44501. + */
  44502. + bic_set_bfqq(bic, new_bfqq, 1);
  44503. + bfq_mark_bfqq_coop(new_bfqq);
  44504. + /*
  44505. + * new_bfqq now belongs to at least two bics (it is a shared queue):
  44506. + * set new_bfqq->bic to NULL. bfqq either:
  44507. + * - does not belong to any bic any more, and hence bfqq->bic must
  44508. + * be set to NULL, or
  44509. + * - is a queue whose owning bics have already been redirected to a
  44510. + * different queue, hence the queue is destined to not belong to
  44511. + * any bic soon and bfqq->bic is already NULL (therefore the next
  44512. + * assignment causes no harm).
  44513. + */
  44514. + new_bfqq->bic = NULL;
  44515. + bfqq->bic = NULL;
  44516. + bfq_put_queue(bfqq);
  44517. +}
  44518. +
  44519. +static inline void bfq_bfqq_increase_failed_cooperations(struct bfq_queue *bfqq)
  44520. +{
  44521. + struct bfq_io_cq *bic = bfqq->bic;
  44522. + struct bfq_data *bfqd = bfqq->bfqd;
  44523. +
  44524. + if (bic && bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh) {
  44525. + bic->failed_cooperations++;
  44526. + if (bic->failed_cooperations >= bfqd->bfq_failed_cooperations)
  44527. + bic->cooperations = 0;
  44528. + }
  44529. +}
  44530. +
  44531. +static int bfq_allow_merge(struct request_queue *q, struct request *rq,
  44532. + struct bio *bio)
  44533. +{
  44534. + struct bfq_data *bfqd = q->elevator->elevator_data;
  44535. + struct bfq_io_cq *bic;
  44536. + struct bfq_queue *bfqq, *new_bfqq;
  44537. +
  44538. + /*
  44539. + * Disallow merge of a sync bio into an async request.
  44540. + */
  44541. + if (bfq_bio_sync(bio) && !rq_is_sync(rq))
  44542. + return 0;
  44543. +
  44544. + /*
  44545. + * Lookup the bfqq that this bio will be queued with. Allow
  44546. + * merge only if rq is queued there.
  44547. + * Queue lock is held here.
  44548. + */
  44549. + bic = bfq_bic_lookup(bfqd, current->io_context);
  44550. + if (bic == NULL)
  44551. + return 0;
  44552. +
  44553. + bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio));
  44554. + /*
  44555. + * We take advantage of this function to perform an early merge
  44556. + * of the queues of possible cooperating processes.
  44557. + */
  44558. + if (bfqq != NULL) {
  44559. + new_bfqq = bfq_setup_cooperator(bfqd, bfqq, bio, false);
  44560. + if (new_bfqq != NULL) {
  44561. + bfq_merge_bfqqs(bfqd, bic, bfqq, new_bfqq);
  44562. + /*
  44563. + * If we get here, the bio will be queued in the
  44564. + * shared queue, i.e., new_bfqq, so use new_bfqq
  44565. + * to decide whether bio and rq can be merged.
  44566. + */
  44567. + bfqq = new_bfqq;
  44568. + } else
  44569. + bfq_bfqq_increase_failed_cooperations(bfqq);
  44570. + }
  44571. +
  44572. + return bfqq == RQ_BFQQ(rq);
  44573. +}
  44574. +
  44575. +static void __bfq_set_in_service_queue(struct bfq_data *bfqd,
  44576. + struct bfq_queue *bfqq)
  44577. +{
  44578. + if (bfqq != NULL) {
  44579. + bfq_mark_bfqq_must_alloc(bfqq);
  44580. + bfq_mark_bfqq_budget_new(bfqq);
  44581. + bfq_clear_bfqq_fifo_expire(bfqq);
  44582. +
  44583. + bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8;
  44584. +
  44585. + bfq_log_bfqq(bfqd, bfqq,
  44586. + "set_in_service_queue, cur-budget = %lu",
  44587. + bfqq->entity.budget);
  44588. + }
  44589. +
  44590. + bfqd->in_service_queue = bfqq;
  44591. +}
  44592. +
  44593. +/*
  44594. + * Get and set a new queue for service.
  44595. + */
  44596. +static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd)
  44597. +{
  44598. + struct bfq_queue *bfqq = bfq_get_next_queue(bfqd);
  44599. +
  44600. + __bfq_set_in_service_queue(bfqd, bfqq);
  44601. + return bfqq;
  44602. +}
  44603. +
  44604. +/*
  44605. + * If enough samples have been computed, return the current max budget
  44606. + * stored in bfqd, which is dynamically updated according to the
  44607. + * estimated disk peak rate; otherwise return the default max budget
  44608. + */
  44609. +static inline unsigned long bfq_max_budget(struct bfq_data *bfqd)
  44610. +{
  44611. + if (bfqd->budgets_assigned < 194)
  44612. + return bfq_default_max_budget;
  44613. + else
  44614. + return bfqd->bfq_max_budget;
  44615. +}
  44616. +
  44617. +/*
  44618. + * Return min budget, which is a fraction of the current or default
  44619. + * max budget (trying with 1/32)
  44620. + */
  44621. +static inline unsigned long bfq_min_budget(struct bfq_data *bfqd)
  44622. +{
  44623. + if (bfqd->budgets_assigned < 194)
  44624. + return bfq_default_max_budget / 32;
  44625. + else
  44626. + return bfqd->bfq_max_budget / 32;
  44627. +}
  44628. +
  44629. +static void bfq_arm_slice_timer(struct bfq_data *bfqd)
  44630. +{
  44631. + struct bfq_queue *bfqq = bfqd->in_service_queue;
  44632. + struct bfq_io_cq *bic;
  44633. + unsigned long sl;
  44634. +
  44635. + BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
  44636. +
  44637. + /* Processes have exited, don't wait. */
  44638. + bic = bfqd->in_service_bic;
  44639. + if (bic == NULL || atomic_read(&bic->icq.ioc->active_ref) == 0)
  44640. + return;
  44641. +
  44642. + bfq_mark_bfqq_wait_request(bfqq);
  44643. +
  44644. + /*
  44645. + * We don't want to idle for seeks, but we do want to allow
  44646. + * fair distribution of slice time for a process doing back-to-back
  44647. + * seeks. So allow a little bit of time for him to submit a new rq.
  44648. + *
  44649. + * To prevent processes with (partly) seeky workloads from
  44650. + * being too ill-treated, grant them a small fraction of the
  44651. + * assigned budget before reducing the waiting time to
  44652. + * BFQ_MIN_TT. This happened to help reduce latency.
  44653. + */
  44654. + sl = bfqd->bfq_slice_idle;
  44655. + /*
  44656. + * Unless the queue is being weight-raised, grant only minimum idle
  44657. + * time if the queue either has been seeky for long enough or has
  44658. + * already proved to be constantly seeky.
  44659. + */
  44660. + if (bfq_sample_valid(bfqq->seek_samples) &&
  44661. + ((BFQQ_SEEKY(bfqq) && bfqq->entity.service >
  44662. + bfq_max_budget(bfqq->bfqd) / 8) ||
  44663. + bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1)
  44664. + sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT));
  44665. + else if (bfqq->wr_coeff > 1)
  44666. + sl = sl * 3;
  44667. + bfqd->last_idling_start = ktime_get();
  44668. + mod_timer(&bfqd->idle_slice_timer, jiffies + sl);
  44669. + bfq_log(bfqd, "arm idle: %u/%u ms",
  44670. + jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle));
  44671. +}
  44672. +
  44673. +/*
  44674. + * Set the maximum time for the in-service queue to consume its
  44675. + * budget. This prevents seeky processes from lowering the disk
  44676. + * throughput (always guaranteed with a time slice scheme as in CFQ).
  44677. + */
  44678. +static void bfq_set_budget_timeout(struct bfq_data *bfqd)
  44679. +{
  44680. + struct bfq_queue *bfqq = bfqd->in_service_queue;
  44681. + unsigned int timeout_coeff;
  44682. + if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time)
  44683. + timeout_coeff = 1;
  44684. + else
  44685. + timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight;
  44686. +
  44687. + bfqd->last_budget_start = ktime_get();
  44688. +
  44689. + bfq_clear_bfqq_budget_new(bfqq);
  44690. + bfqq->budget_timeout = jiffies +
  44691. + bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff;
  44692. +
  44693. + bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u",
  44694. + jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] *
  44695. + timeout_coeff));
  44696. +}
  44697. +
  44698. +/*
  44699. + * Move request from internal lists to the request queue dispatch list.
  44700. + */
  44701. +static void bfq_dispatch_insert(struct request_queue *q, struct request *rq)
  44702. +{
  44703. + struct bfq_data *bfqd = q->elevator->elevator_data;
  44704. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  44705. +
  44706. + /*
  44707. + * For consistency, the next instruction should have been executed
  44708. + * after removing the request from the queue and dispatching it.
  44709. + * We execute instead this instruction before bfq_remove_request()
  44710. + * (and hence introduce a temporary inconsistency), for efficiency.
  44711. + * In fact, in a forced_dispatch, this prevents two counters related
  44712. + * to bfqq->dispatched to risk to be uselessly decremented if bfqq
  44713. + * is not in service, and then to be incremented again after
  44714. + * incrementing bfqq->dispatched.
  44715. + */
  44716. + bfqq->dispatched++;
  44717. + bfq_remove_request(rq);
  44718. + elv_dispatch_sort(q, rq);
  44719. +
  44720. + if (bfq_bfqq_sync(bfqq))
  44721. + bfqd->sync_flight++;
  44722. +}
  44723. +
  44724. +/*
  44725. + * Return expired entry, or NULL to just start from scratch in rbtree.
  44726. + */
  44727. +static struct request *bfq_check_fifo(struct bfq_queue *bfqq)
  44728. +{
  44729. + struct request *rq = NULL;
  44730. +
  44731. + if (bfq_bfqq_fifo_expire(bfqq))
  44732. + return NULL;
  44733. +
  44734. + bfq_mark_bfqq_fifo_expire(bfqq);
  44735. +
  44736. + if (list_empty(&bfqq->fifo))
  44737. + return NULL;
  44738. +
  44739. + rq = rq_entry_fifo(bfqq->fifo.next);
  44740. +
  44741. + if (time_before(jiffies, rq_fifo_time(rq)))
  44742. + return NULL;
  44743. +
  44744. + return rq;
  44745. +}
  44746. +
  44747. +static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq)
  44748. +{
  44749. + struct bfq_entity *entity = &bfqq->entity;
  44750. + return entity->budget - entity->service;
  44751. +}
  44752. +
  44753. +static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  44754. +{
  44755. + BUG_ON(bfqq != bfqd->in_service_queue);
  44756. +
  44757. + __bfq_bfqd_reset_in_service(bfqd);
  44758. +
  44759. + /*
  44760. + * If this bfqq is shared between multiple processes, check
  44761. + * to make sure that those processes are still issuing I/Os
  44762. + * within the mean seek distance. If not, it may be time to
  44763. + * break the queues apart again.
  44764. + */
  44765. + if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq))
  44766. + bfq_mark_bfqq_split_coop(bfqq);
  44767. +
  44768. + if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
  44769. + /*
  44770. + * Overloading budget_timeout field to store the time
  44771. + * at which the queue remains with no backlog; used by
  44772. + * the weight-raising mechanism.
  44773. + */
  44774. + bfqq->budget_timeout = jiffies;
  44775. + bfq_del_bfqq_busy(bfqd, bfqq, 1);
  44776. + } else {
  44777. + bfq_activate_bfqq(bfqd, bfqq);
  44778. + /*
  44779. + * Resort priority tree of potential close cooperators.
  44780. + */
  44781. + bfq_rq_pos_tree_add(bfqd, bfqq);
  44782. + }
  44783. +}
  44784. +
  44785. +/**
  44786. + * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior.
  44787. + * @bfqd: device data.
  44788. + * @bfqq: queue to update.
  44789. + * @reason: reason for expiration.
  44790. + *
  44791. + * Handle the feedback on @bfqq budget. See the body for detailed
  44792. + * comments.
  44793. + */
  44794. +static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd,
  44795. + struct bfq_queue *bfqq,
  44796. + enum bfqq_expiration reason)
  44797. +{
  44798. + struct request *next_rq;
  44799. + unsigned long budget, min_budget;
  44800. +
  44801. + budget = bfqq->max_budget;
  44802. + min_budget = bfq_min_budget(bfqd);
  44803. +
  44804. + BUG_ON(bfqq != bfqd->in_service_queue);
  44805. +
  44806. + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %lu, budg left %lu",
  44807. + bfqq->entity.budget, bfq_bfqq_budget_left(bfqq));
  44808. + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %lu, min budg %lu",
  44809. + budget, bfq_min_budget(bfqd));
  44810. + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d",
  44811. + bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue));
  44812. +
  44813. + if (bfq_bfqq_sync(bfqq)) {
  44814. + switch (reason) {
  44815. + /*
  44816. + * Caveat: in all the following cases we trade latency
  44817. + * for throughput.
  44818. + */
  44819. + case BFQ_BFQQ_TOO_IDLE:
  44820. + /*
  44821. + * This is the only case where we may reduce
  44822. + * the budget: if there is no request of the
  44823. + * process still waiting for completion, then
  44824. + * we assume (tentatively) that the timer has
  44825. + * expired because the batch of requests of
  44826. + * the process could have been served with a
  44827. + * smaller budget. Hence, betting that
  44828. + * process will behave in the same way when it
  44829. + * becomes backlogged again, we reduce its
  44830. + * next budget. As long as we guess right,
  44831. + * this budget cut reduces the latency
  44832. + * experienced by the process.
  44833. + *
  44834. + * However, if there are still outstanding
  44835. + * requests, then the process may have not yet
  44836. + * issued its next request just because it is
  44837. + * still waiting for the completion of some of
  44838. + * the still outstanding ones. So in this
  44839. + * subcase we do not reduce its budget, on the
  44840. + * contrary we increase it to possibly boost
  44841. + * the throughput, as discussed in the
  44842. + * comments to the BUDGET_TIMEOUT case.
  44843. + */
  44844. + if (bfqq->dispatched > 0) /* still outstanding reqs */
  44845. + budget = min(budget * 2, bfqd->bfq_max_budget);
  44846. + else {
  44847. + if (budget > 5 * min_budget)
  44848. + budget -= 4 * min_budget;
  44849. + else
  44850. + budget = min_budget;
  44851. + }
  44852. + break;
  44853. + case BFQ_BFQQ_BUDGET_TIMEOUT:
  44854. + /*
  44855. + * We double the budget here because: 1) it
  44856. + * gives the chance to boost the throughput if
  44857. + * this is not a seeky process (which may have
  44858. + * bumped into this timeout because of, e.g.,
  44859. + * ZBR), 2) together with charge_full_budget
  44860. + * it helps give seeky processes higher
  44861. + * timestamps, and hence be served less
  44862. + * frequently.
  44863. + */
  44864. + budget = min(budget * 2, bfqd->bfq_max_budget);
  44865. + break;
  44866. + case BFQ_BFQQ_BUDGET_EXHAUSTED:
  44867. + /*
  44868. + * The process still has backlog, and did not
  44869. + * let either the budget timeout or the disk
  44870. + * idling timeout expire. Hence it is not
  44871. + * seeky, has a short thinktime and may be
  44872. + * happy with a higher budget too. So
  44873. + * definitely increase the budget of this good
  44874. + * candidate to boost the disk throughput.
  44875. + */
  44876. + budget = min(budget * 4, bfqd->bfq_max_budget);
  44877. + break;
  44878. + case BFQ_BFQQ_NO_MORE_REQUESTS:
  44879. + /*
  44880. + * Leave the budget unchanged.
  44881. + */
  44882. + default:
  44883. + return;
  44884. + }
  44885. + } else /* async queue */
  44886. + /* async queues get always the maximum possible budget
  44887. + * (their ability to dispatch is limited by
  44888. + * @bfqd->bfq_max_budget_async_rq).
  44889. + */
  44890. + budget = bfqd->bfq_max_budget;
  44891. +
  44892. + bfqq->max_budget = budget;
  44893. +
  44894. + if (bfqd->budgets_assigned >= 194 && bfqd->bfq_user_max_budget == 0 &&
  44895. + bfqq->max_budget > bfqd->bfq_max_budget)
  44896. + bfqq->max_budget = bfqd->bfq_max_budget;
  44897. +
  44898. + /*
  44899. + * Make sure that we have enough budget for the next request.
  44900. + * Since the finish time of the bfqq must be kept in sync with
  44901. + * the budget, be sure to call __bfq_bfqq_expire() after the
  44902. + * update.
  44903. + */
  44904. + next_rq = bfqq->next_rq;
  44905. + if (next_rq != NULL)
  44906. + bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget,
  44907. + bfq_serv_to_charge(next_rq, bfqq));
  44908. + else
  44909. + bfqq->entity.budget = bfqq->max_budget;
  44910. +
  44911. + bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %lu",
  44912. + next_rq != NULL ? blk_rq_sectors(next_rq) : 0,
  44913. + bfqq->entity.budget);
  44914. +}
  44915. +
  44916. +static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout)
  44917. +{
  44918. + unsigned long max_budget;
  44919. +
  44920. + /*
  44921. + * The max_budget calculated when autotuning is equal to the
  44922. + * amount of sectors transfered in timeout_sync at the
  44923. + * estimated peak rate.
  44924. + */
  44925. + max_budget = (unsigned long)(peak_rate * 1000 *
  44926. + timeout >> BFQ_RATE_SHIFT);
  44927. +
  44928. + return max_budget;
  44929. +}
  44930. +
  44931. +/*
  44932. + * In addition to updating the peak rate, checks whether the process
  44933. + * is "slow", and returns 1 if so. This slow flag is used, in addition
  44934. + * to the budget timeout, to reduce the amount of service provided to
  44935. + * seeky processes, and hence reduce their chances to lower the
  44936. + * throughput. See the code for more details.
  44937. + */
  44938. +static int bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  44939. + int compensate, enum bfqq_expiration reason)
  44940. +{
  44941. + u64 bw, usecs, expected, timeout;
  44942. + ktime_t delta;
  44943. + int update = 0;
  44944. +
  44945. + if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq))
  44946. + return 0;
  44947. +
  44948. + if (compensate)
  44949. + delta = bfqd->last_idling_start;
  44950. + else
  44951. + delta = ktime_get();
  44952. + delta = ktime_sub(delta, bfqd->last_budget_start);
  44953. + usecs = ktime_to_us(delta);
  44954. +
  44955. + /* Don't trust short/unrealistic values. */
  44956. + if (usecs < 100 || usecs >= LONG_MAX)
  44957. + return 0;
  44958. +
  44959. + /*
  44960. + * Calculate the bandwidth for the last slice. We use a 64 bit
  44961. + * value to store the peak rate, in sectors per usec in fixed
  44962. + * point math. We do so to have enough precision in the estimate
  44963. + * and to avoid overflows.
  44964. + */
  44965. + bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT;
  44966. + do_div(bw, (unsigned long)usecs);
  44967. +
  44968. + timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]);
  44969. +
  44970. + /*
  44971. + * Use only long (> 20ms) intervals to filter out spikes for
  44972. + * the peak rate estimation.
  44973. + */
  44974. + if (usecs > 20000) {
  44975. + if (bw > bfqd->peak_rate ||
  44976. + (!BFQQ_SEEKY(bfqq) &&
  44977. + reason == BFQ_BFQQ_BUDGET_TIMEOUT)) {
  44978. + bfq_log(bfqd, "measured bw =%llu", bw);
  44979. + /*
  44980. + * To smooth oscillations use a low-pass filter with
  44981. + * alpha=7/8, i.e.,
  44982. + * new_rate = (7/8) * old_rate + (1/8) * bw
  44983. + */
  44984. + do_div(bw, 8);
  44985. + if (bw == 0)
  44986. + return 0;
  44987. + bfqd->peak_rate *= 7;
  44988. + do_div(bfqd->peak_rate, 8);
  44989. + bfqd->peak_rate += bw;
  44990. + update = 1;
  44991. + bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate);
  44992. + }
  44993. +
  44994. + update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1;
  44995. +
  44996. + if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES)
  44997. + bfqd->peak_rate_samples++;
  44998. +
  44999. + if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES &&
  45000. + update) {
  45001. + int dev_type = blk_queue_nonrot(bfqd->queue);
  45002. + if (bfqd->bfq_user_max_budget == 0) {
  45003. + bfqd->bfq_max_budget =
  45004. + bfq_calc_max_budget(bfqd->peak_rate,
  45005. + timeout);
  45006. + bfq_log(bfqd, "new max_budget=%lu",
  45007. + bfqd->bfq_max_budget);
  45008. + }
  45009. + if (bfqd->device_speed == BFQ_BFQD_FAST &&
  45010. + bfqd->peak_rate < device_speed_thresh[dev_type]) {
  45011. + bfqd->device_speed = BFQ_BFQD_SLOW;
  45012. + bfqd->RT_prod = R_slow[dev_type] *
  45013. + T_slow[dev_type];
  45014. + } else if (bfqd->device_speed == BFQ_BFQD_SLOW &&
  45015. + bfqd->peak_rate > device_speed_thresh[dev_type]) {
  45016. + bfqd->device_speed = BFQ_BFQD_FAST;
  45017. + bfqd->RT_prod = R_fast[dev_type] *
  45018. + T_fast[dev_type];
  45019. + }
  45020. + }
  45021. + }
  45022. +
  45023. + /*
  45024. + * If the process has been served for a too short time
  45025. + * interval to let its possible sequential accesses prevail on
  45026. + * the initial seek time needed to move the disk head on the
  45027. + * first sector it requested, then give the process a chance
  45028. + * and for the moment return false.
  45029. + */
  45030. + if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8)
  45031. + return 0;
  45032. +
  45033. + /*
  45034. + * A process is considered ``slow'' (i.e., seeky, so that we
  45035. + * cannot treat it fairly in the service domain, as it would
  45036. + * slow down too much the other processes) if, when a slice
  45037. + * ends for whatever reason, it has received service at a
  45038. + * rate that would not be high enough to complete the budget
  45039. + * before the budget timeout expiration.
  45040. + */
  45041. + expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT;
  45042. +
  45043. + /*
  45044. + * Caveat: processes doing IO in the slower disk zones will
  45045. + * tend to be slow(er) even if not seeky. And the estimated
  45046. + * peak rate will actually be an average over the disk
  45047. + * surface. Hence, to not be too harsh with unlucky processes,
  45048. + * we keep a budget/3 margin of safety before declaring a
  45049. + * process slow.
  45050. + */
  45051. + return expected > (4 * bfqq->entity.budget) / 3;
  45052. +}
  45053. +
  45054. +/*
  45055. + * To be deemed as soft real-time, an application must meet two
  45056. + * requirements. First, the application must not require an average
  45057. + * bandwidth higher than the approximate bandwidth required to playback or
  45058. + * record a compressed high-definition video.
  45059. + * The next function is invoked on the completion of the last request of a
  45060. + * batch, to compute the next-start time instant, soft_rt_next_start, such
  45061. + * that, if the next request of the application does not arrive before
  45062. + * soft_rt_next_start, then the above requirement on the bandwidth is met.
  45063. + *
  45064. + * The second requirement is that the request pattern of the application is
  45065. + * isochronous, i.e., that, after issuing a request or a batch of requests,
  45066. + * the application stops issuing new requests until all its pending requests
  45067. + * have been completed. After that, the application may issue a new batch,
  45068. + * and so on.
  45069. + * For this reason the next function is invoked to compute
  45070. + * soft_rt_next_start only for applications that meet this requirement,
  45071. + * whereas soft_rt_next_start is set to infinity for applications that do
  45072. + * not.
  45073. + *
  45074. + * Unfortunately, even a greedy application may happen to behave in an
  45075. + * isochronous way if the CPU load is high. In fact, the application may
  45076. + * stop issuing requests while the CPUs are busy serving other processes,
  45077. + * then restart, then stop again for a while, and so on. In addition, if
  45078. + * the disk achieves a low enough throughput with the request pattern
  45079. + * issued by the application (e.g., because the request pattern is random
  45080. + * and/or the device is slow), then the application may meet the above
  45081. + * bandwidth requirement too. To prevent such a greedy application to be
  45082. + * deemed as soft real-time, a further rule is used in the computation of
  45083. + * soft_rt_next_start: soft_rt_next_start must be higher than the current
  45084. + * time plus the maximum time for which the arrival of a request is waited
  45085. + * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle.
  45086. + * This filters out greedy applications, as the latter issue instead their
  45087. + * next request as soon as possible after the last one has been completed
  45088. + * (in contrast, when a batch of requests is completed, a soft real-time
  45089. + * application spends some time processing data).
  45090. + *
  45091. + * Unfortunately, the last filter may easily generate false positives if
  45092. + * only bfqd->bfq_slice_idle is used as a reference time interval and one
  45093. + * or both the following cases occur:
  45094. + * 1) HZ is so low that the duration of a jiffy is comparable to or higher
  45095. + * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with
  45096. + * HZ=100.
  45097. + * 2) jiffies, instead of increasing at a constant rate, may stop increasing
  45098. + * for a while, then suddenly 'jump' by several units to recover the lost
  45099. + * increments. This seems to happen, e.g., inside virtual machines.
  45100. + * To address this issue, we do not use as a reference time interval just
  45101. + * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In
  45102. + * particular we add the minimum number of jiffies for which the filter
  45103. + * seems to be quite precise also in embedded systems and KVM/QEMU virtual
  45104. + * machines.
  45105. + */
  45106. +static inline unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd,
  45107. + struct bfq_queue *bfqq)
  45108. +{
  45109. + return max(bfqq->last_idle_bklogged +
  45110. + HZ * bfqq->service_from_backlogged /
  45111. + bfqd->bfq_wr_max_softrt_rate,
  45112. + jiffies + bfqq->bfqd->bfq_slice_idle + 4);
  45113. +}
  45114. +
  45115. +/*
  45116. + * Return the largest-possible time instant such that, for as long as possible,
  45117. + * the current time will be lower than this time instant according to the macro
  45118. + * time_is_before_jiffies().
  45119. + */
  45120. +static inline unsigned long bfq_infinity_from_now(unsigned long now)
  45121. +{
  45122. + return now + ULONG_MAX / 2;
  45123. +}
  45124. +
  45125. +/**
  45126. + * bfq_bfqq_expire - expire a queue.
  45127. + * @bfqd: device owning the queue.
  45128. + * @bfqq: the queue to expire.
  45129. + * @compensate: if true, compensate for the time spent idling.
  45130. + * @reason: the reason causing the expiration.
  45131. + *
  45132. + *
  45133. + * If the process associated to the queue is slow (i.e., seeky), or in
  45134. + * case of budget timeout, or, finally, if it is async, we
  45135. + * artificially charge it an entire budget (independently of the
  45136. + * actual service it received). As a consequence, the queue will get
  45137. + * higher timestamps than the correct ones upon reactivation, and
  45138. + * hence it will be rescheduled as if it had received more service
  45139. + * than what it actually received. In the end, this class of processes
  45140. + * will receive less service in proportion to how slowly they consume
  45141. + * their budgets (and hence how seriously they tend to lower the
  45142. + * throughput).
  45143. + *
  45144. + * In contrast, when a queue expires because it has been idling for
  45145. + * too much or because it exhausted its budget, we do not touch the
  45146. + * amount of service it has received. Hence when the queue will be
  45147. + * reactivated and its timestamps updated, the latter will be in sync
  45148. + * with the actual service received by the queue until expiration.
  45149. + *
  45150. + * Charging a full budget to the first type of queues and the exact
  45151. + * service to the others has the effect of using the WF2Q+ policy to
  45152. + * schedule the former on a timeslice basis, without violating the
  45153. + * service domain guarantees of the latter.
  45154. + */
  45155. +static void bfq_bfqq_expire(struct bfq_data *bfqd,
  45156. + struct bfq_queue *bfqq,
  45157. + int compensate,
  45158. + enum bfqq_expiration reason)
  45159. +{
  45160. + int slow;
  45161. + BUG_ON(bfqq != bfqd->in_service_queue);
  45162. +
  45163. + /* Update disk peak rate for autotuning and check whether the
  45164. + * process is slow (see bfq_update_peak_rate).
  45165. + */
  45166. + slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason);
  45167. +
  45168. + /*
  45169. + * As above explained, 'punish' slow (i.e., seeky), timed-out
  45170. + * and async queues, to favor sequential sync workloads.
  45171. + *
  45172. + * Processes doing I/O in the slower disk zones will tend to be
  45173. + * slow(er) even if not seeky. Hence, since the estimated peak
  45174. + * rate is actually an average over the disk surface, these
  45175. + * processes may timeout just for bad luck. To avoid punishing
  45176. + * them we do not charge a full budget to a process that
  45177. + * succeeded in consuming at least 2/3 of its budget.
  45178. + */
  45179. + if (slow || (reason == BFQ_BFQQ_BUDGET_TIMEOUT &&
  45180. + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3))
  45181. + bfq_bfqq_charge_full_budget(bfqq);
  45182. +
  45183. + bfqq->service_from_backlogged += bfqq->entity.service;
  45184. +
  45185. + if (BFQQ_SEEKY(bfqq) && reason == BFQ_BFQQ_BUDGET_TIMEOUT &&
  45186. + !bfq_bfqq_constantly_seeky(bfqq)) {
  45187. + bfq_mark_bfqq_constantly_seeky(bfqq);
  45188. + if (!blk_queue_nonrot(bfqd->queue))
  45189. + bfqd->const_seeky_busy_in_flight_queues++;
  45190. + }
  45191. +
  45192. + if (reason == BFQ_BFQQ_TOO_IDLE &&
  45193. + bfqq->entity.service <= 2 * bfqq->entity.budget / 10 )
  45194. + bfq_clear_bfqq_IO_bound(bfqq);
  45195. +
  45196. + if (bfqd->low_latency && bfqq->wr_coeff == 1)
  45197. + bfqq->last_wr_start_finish = jiffies;
  45198. +
  45199. + if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 &&
  45200. + RB_EMPTY_ROOT(&bfqq->sort_list)) {
  45201. + /*
  45202. + * If we get here, and there are no outstanding requests,
  45203. + * then the request pattern is isochronous (see the comments
  45204. + * to the function bfq_bfqq_softrt_next_start()). Hence we
  45205. + * can compute soft_rt_next_start. If, instead, the queue
  45206. + * still has outstanding requests, then we have to wait
  45207. + * for the completion of all the outstanding requests to
  45208. + * discover whether the request pattern is actually
  45209. + * isochronous.
  45210. + */
  45211. + if (bfqq->dispatched == 0)
  45212. + bfqq->soft_rt_next_start =
  45213. + bfq_bfqq_softrt_next_start(bfqd, bfqq);
  45214. + else {
  45215. + /*
  45216. + * The application is still waiting for the
  45217. + * completion of one or more requests:
  45218. + * prevent it from possibly being incorrectly
  45219. + * deemed as soft real-time by setting its
  45220. + * soft_rt_next_start to infinity. In fact,
  45221. + * without this assignment, the application
  45222. + * would be incorrectly deemed as soft
  45223. + * real-time if:
  45224. + * 1) it issued a new request before the
  45225. + * completion of all its in-flight
  45226. + * requests, and
  45227. + * 2) at that time, its soft_rt_next_start
  45228. + * happened to be in the past.
  45229. + */
  45230. + bfqq->soft_rt_next_start =
  45231. + bfq_infinity_from_now(jiffies);
  45232. + /*
  45233. + * Schedule an update of soft_rt_next_start to when
  45234. + * the task may be discovered to be isochronous.
  45235. + */
  45236. + bfq_mark_bfqq_softrt_update(bfqq);
  45237. + }
  45238. + }
  45239. +
  45240. + bfq_log_bfqq(bfqd, bfqq,
  45241. + "expire (%d, slow %d, num_disp %d, idle_win %d)", reason,
  45242. + slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq));
  45243. +
  45244. + /*
  45245. + * Increase, decrease or leave budget unchanged according to
  45246. + * reason.
  45247. + */
  45248. + __bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
  45249. + __bfq_bfqq_expire(bfqd, bfqq);
  45250. +}
  45251. +
  45252. +/*
  45253. + * Budget timeout is not implemented through a dedicated timer, but
  45254. + * just checked on request arrivals and completions, as well as on
  45255. + * idle timer expirations.
  45256. + */
  45257. +static int bfq_bfqq_budget_timeout(struct bfq_queue *bfqq)
  45258. +{
  45259. + if (bfq_bfqq_budget_new(bfqq) ||
  45260. + time_before(jiffies, bfqq->budget_timeout))
  45261. + return 0;
  45262. + return 1;
  45263. +}
  45264. +
  45265. +/*
  45266. + * If we expire a queue that is waiting for the arrival of a new
  45267. + * request, we may prevent the fictitious timestamp back-shifting that
  45268. + * allows the guarantees of the queue to be preserved (see [1] for
  45269. + * this tricky aspect). Hence we return true only if this condition
  45270. + * does not hold, or if the queue is slow enough to deserve only to be
  45271. + * kicked off for preserving a high throughput.
  45272. +*/
  45273. +static inline int bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq)
  45274. +{
  45275. + bfq_log_bfqq(bfqq->bfqd, bfqq,
  45276. + "may_budget_timeout: wait_request %d left %d timeout %d",
  45277. + bfq_bfqq_wait_request(bfqq),
  45278. + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3,
  45279. + bfq_bfqq_budget_timeout(bfqq));
  45280. +
  45281. + return (!bfq_bfqq_wait_request(bfqq) ||
  45282. + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3)
  45283. + &&
  45284. + bfq_bfqq_budget_timeout(bfqq);
  45285. +}
  45286. +
  45287. +/*
  45288. + * Device idling is allowed only for the queues for which this function
  45289. + * returns true. For this reason, the return value of this function plays a
  45290. + * critical role for both throughput boosting and service guarantees. The
  45291. + * return value is computed through a logical expression. In this rather
  45292. + * long comment, we try to briefly describe all the details and motivations
  45293. + * behind the components of this logical expression.
  45294. + *
  45295. + * First, the expression may be true only for sync queues. Besides, if
  45296. + * bfqq is also being weight-raised, then the expression always evaluates
  45297. + * to true, as device idling is instrumental for preserving low-latency
  45298. + * guarantees (see [1]). Otherwise, the expression evaluates to true only
  45299. + * if bfqq has a non-null idle window and at least one of the following
  45300. + * two conditions holds. The first condition is that the device is not
  45301. + * performing NCQ, because idling the device most certainly boosts the
  45302. + * throughput if this condition holds and bfqq has been granted a non-null
  45303. + * idle window. The second compound condition is made of the logical AND of
  45304. + * two components.
  45305. + *
  45306. + * The first component is true only if there is no weight-raised busy
  45307. + * queue. This guarantees that the device is not idled for a sync non-
  45308. + * weight-raised queue when there are busy weight-raised queues. The former
  45309. + * is then expired immediately if empty. Combined with the timestamping
  45310. + * rules of BFQ (see [1] for details), this causes sync non-weight-raised
  45311. + * queues to get a lower number of requests served, and hence to ask for a
  45312. + * lower number of requests from the request pool, before the busy weight-
  45313. + * raised queues get served again.
  45314. + *
  45315. + * This is beneficial for the processes associated with weight-raised
  45316. + * queues, when the request pool is saturated (e.g., in the presence of
  45317. + * write hogs). In fact, if the processes associated with the other queues
  45318. + * ask for requests at a lower rate, then weight-raised processes have a
  45319. + * higher probability to get a request from the pool immediately (or at
  45320. + * least soon) when they need one. Hence they have a higher probability to
  45321. + * actually get a fraction of the disk throughput proportional to their
  45322. + * high weight. This is especially true with NCQ-capable drives, which
  45323. + * enqueue several requests in advance and further reorder internally-
  45324. + * queued requests.
  45325. + *
  45326. + * In the end, mistreating non-weight-raised queues when there are busy
  45327. + * weight-raised queues seems to mitigate starvation problems in the
  45328. + * presence of heavy write workloads and NCQ, and hence to guarantee a
  45329. + * higher application and system responsiveness in these hostile scenarios.
  45330. + *
  45331. + * If the first component of the compound condition is instead true, i.e.,
  45332. + * there is no weight-raised busy queue, then the second component of the
  45333. + * compound condition takes into account service-guarantee and throughput
  45334. + * issues related to NCQ (recall that the compound condition is evaluated
  45335. + * only if the device is detected as supporting NCQ).
  45336. + *
  45337. + * As for service guarantees, allowing the drive to enqueue more than one
  45338. + * request at a time, and hence delegating de facto final scheduling
  45339. + * decisions to the drive's internal scheduler, causes loss of control on
  45340. + * the actual request service order. In this respect, when the drive is
  45341. + * allowed to enqueue more than one request at a time, the service
  45342. + * distribution enforced by the drive's internal scheduler is likely to
  45343. + * coincide with the desired device-throughput distribution only in the
  45344. + * following, perfectly symmetric, scenario:
  45345. + * 1) all active queues have the same weight,
  45346. + * 2) all active groups at the same level in the groups tree have the same
  45347. + * weight,
  45348. + * 3) all active groups at the same level in the groups tree have the same
  45349. + * number of children.
  45350. + *
  45351. + * Even in such a scenario, sequential I/O may still receive a preferential
  45352. + * treatment, but this is not likely to be a big issue with flash-based
  45353. + * devices, because of their non-dramatic loss of throughput with random
  45354. + * I/O. Things do differ with HDDs, for which additional care is taken, as
  45355. + * explained after completing the discussion for flash-based devices.
  45356. + *
  45357. + * Unfortunately, keeping the necessary state for evaluating exactly the
  45358. + * above symmetry conditions would be quite complex and time-consuming.
  45359. + * Therefore BFQ evaluates instead the following stronger sub-conditions,
  45360. + * for which it is much easier to maintain the needed state:
  45361. + * 1) all active queues have the same weight,
  45362. + * 2) all active groups have the same weight,
  45363. + * 3) all active groups have at most one active child each.
  45364. + * In particular, the last two conditions are always true if hierarchical
  45365. + * support and the cgroups interface are not enabled, hence no state needs
  45366. + * to be maintained in this case.
  45367. + *
  45368. + * According to the above considerations, the second component of the
  45369. + * compound condition evaluates to true if any of the above symmetry
  45370. + * sub-condition does not hold, or the device is not flash-based. Therefore,
  45371. + * if also the first component is true, then idling is allowed for a sync
  45372. + * queue. These are the only sub-conditions considered if the device is
  45373. + * flash-based, as, for such a device, it is sensible to force idling only
  45374. + * for service-guarantee issues. In fact, as for throughput, idling
  45375. + * NCQ-capable flash-based devices would not boost the throughput even
  45376. + * with sequential I/O; rather it would lower the throughput in proportion
  45377. + * to how fast the device is. In the end, (only) if all the three
  45378. + * sub-conditions hold and the device is flash-based, the compound
  45379. + * condition evaluates to false and therefore no idling is performed.
  45380. + *
  45381. + * As already said, things change with a rotational device, where idling
  45382. + * boosts the throughput with sequential I/O (even with NCQ). Hence, for
  45383. + * such a device the second component of the compound condition evaluates
  45384. + * to true also if the following additional sub-condition does not hold:
  45385. + * the queue is constantly seeky. Unfortunately, this different behavior
  45386. + * with respect to flash-based devices causes an additional asymmetry: if
  45387. + * some sync queues enjoy idling and some other sync queues do not, then
  45388. + * the latter get a low share of the device throughput, simply because the
  45389. + * former get many requests served after being set as in service, whereas
  45390. + * the latter do not. As a consequence, to guarantee the desired throughput
  45391. + * distribution, on HDDs the compound expression evaluates to true (and
  45392. + * hence device idling is performed) also if the following last symmetry
  45393. + * condition does not hold: no other queue is benefiting from idling. Also
  45394. + * this last condition is actually replaced with a simpler-to-maintain and
  45395. + * stronger condition: there is no busy queue which is not constantly seeky
  45396. + * (and hence may also benefit from idling).
  45397. + *
  45398. + * To sum up, when all the required symmetry and throughput-boosting
  45399. + * sub-conditions hold, the second component of the compound condition
  45400. + * evaluates to false, and hence no idling is performed. This helps to
  45401. + * keep the drives' internal queues full on NCQ-capable devices, and hence
  45402. + * to boost the throughput, without causing 'almost' any loss of service
  45403. + * guarantees. The 'almost' follows from the fact that, if the internal
  45404. + * queue of one such device is filled while all the sub-conditions hold,
  45405. + * but at some point in time some sub-condition stops to hold, then it may
  45406. + * become impossible to let requests be served in the new desired order
  45407. + * until all the requests already queued in the device have been served.
  45408. + */
  45409. +static inline bool bfq_bfqq_must_not_expire(struct bfq_queue *bfqq)
  45410. +{
  45411. + struct bfq_data *bfqd = bfqq->bfqd;
  45412. +#ifdef CONFIG_CGROUP_BFQIO
  45413. +#define symmetric_scenario (!bfqd->active_numerous_groups && \
  45414. + !bfq_differentiated_weights(bfqd))
  45415. +#else
  45416. +#define symmetric_scenario (!bfq_differentiated_weights(bfqd))
  45417. +#endif
  45418. +#define cond_for_seeky_on_ncq_hdd (bfq_bfqq_constantly_seeky(bfqq) && \
  45419. + bfqd->busy_in_flight_queues == \
  45420. + bfqd->const_seeky_busy_in_flight_queues)
  45421. +/*
  45422. + * Condition for expiring a non-weight-raised queue (and hence not idling
  45423. + * the device).
  45424. + */
  45425. +#define cond_for_expiring_non_wr (bfqd->hw_tag && \
  45426. + (bfqd->wr_busy_queues > 0 || \
  45427. + (symmetric_scenario && \
  45428. + (blk_queue_nonrot(bfqd->queue) || \
  45429. + cond_for_seeky_on_ncq_hdd))))
  45430. +
  45431. + return bfq_bfqq_sync(bfqq) &&
  45432. + (bfq_bfqq_IO_bound(bfqq) || bfqq->wr_coeff > 1) &&
  45433. + (bfqq->wr_coeff > 1 ||
  45434. + (bfq_bfqq_idle_window(bfqq) &&
  45435. + !cond_for_expiring_non_wr)
  45436. + );
  45437. +}
  45438. +
  45439. +/*
  45440. + * If the in-service queue is empty but sync, and the function
  45441. + * bfq_bfqq_must_not_expire returns true, then:
  45442. + * 1) the queue must remain in service and cannot be expired, and
  45443. + * 2) the disk must be idled to wait for the possible arrival of a new
  45444. + * request for the queue.
  45445. + * See the comments to the function bfq_bfqq_must_not_expire for the reasons
  45446. + * why performing device idling is the best choice to boost the throughput
  45447. + * and preserve service guarantees when bfq_bfqq_must_not_expire itself
  45448. + * returns true.
  45449. + */
  45450. +static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq)
  45451. +{
  45452. + struct bfq_data *bfqd = bfqq->bfqd;
  45453. +
  45454. + return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 &&
  45455. + bfq_bfqq_must_not_expire(bfqq);
  45456. +}
  45457. +
  45458. +/*
  45459. + * Select a queue for service. If we have a current queue in service,
  45460. + * check whether to continue servicing it, or retrieve and set a new one.
  45461. + */
  45462. +static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
  45463. +{
  45464. + struct bfq_queue *bfqq;
  45465. + struct request *next_rq;
  45466. + enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT;
  45467. +
  45468. + bfqq = bfqd->in_service_queue;
  45469. + if (bfqq == NULL)
  45470. + goto new_queue;
  45471. +
  45472. + bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue");
  45473. +
  45474. + if (bfq_may_expire_for_budg_timeout(bfqq) &&
  45475. + !timer_pending(&bfqd->idle_slice_timer) &&
  45476. + !bfq_bfqq_must_idle(bfqq))
  45477. + goto expire;
  45478. +
  45479. + next_rq = bfqq->next_rq;
  45480. + /*
  45481. + * If bfqq has requests queued and it has enough budget left to
  45482. + * serve them, keep the queue, otherwise expire it.
  45483. + */
  45484. + if (next_rq != NULL) {
  45485. + if (bfq_serv_to_charge(next_rq, bfqq) >
  45486. + bfq_bfqq_budget_left(bfqq)) {
  45487. + reason = BFQ_BFQQ_BUDGET_EXHAUSTED;
  45488. + goto expire;
  45489. + } else {
  45490. + /*
  45491. + * The idle timer may be pending because we may
  45492. + * not disable disk idling even when a new request
  45493. + * arrives.
  45494. + */
  45495. + if (timer_pending(&bfqd->idle_slice_timer)) {
  45496. + /*
  45497. + * If we get here: 1) at least a new request
  45498. + * has arrived but we have not disabled the
  45499. + * timer because the request was too small,
  45500. + * 2) then the block layer has unplugged
  45501. + * the device, causing the dispatch to be
  45502. + * invoked.
  45503. + *
  45504. + * Since the device is unplugged, now the
  45505. + * requests are probably large enough to
  45506. + * provide a reasonable throughput.
  45507. + * So we disable idling.
  45508. + */
  45509. + bfq_clear_bfqq_wait_request(bfqq);
  45510. + del_timer(&bfqd->idle_slice_timer);
  45511. + }
  45512. + goto keep_queue;
  45513. + }
  45514. + }
  45515. +
  45516. + /*
  45517. + * No requests pending. If the in-service queue still has requests
  45518. + * in flight (possibly waiting for a completion) or is idling for a
  45519. + * new request, then keep it.
  45520. + */
  45521. + if (timer_pending(&bfqd->idle_slice_timer) ||
  45522. + (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq))) {
  45523. + bfqq = NULL;
  45524. + goto keep_queue;
  45525. + }
  45526. +
  45527. + reason = BFQ_BFQQ_NO_MORE_REQUESTS;
  45528. +expire:
  45529. + bfq_bfqq_expire(bfqd, bfqq, 0, reason);
  45530. +new_queue:
  45531. + bfqq = bfq_set_in_service_queue(bfqd);
  45532. + bfq_log(bfqd, "select_queue: new queue %d returned",
  45533. + bfqq != NULL ? bfqq->pid : 0);
  45534. +keep_queue:
  45535. + return bfqq;
  45536. +}
  45537. +
  45538. +static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  45539. +{
  45540. + struct bfq_entity *entity = &bfqq->entity;
  45541. + if (bfqq->wr_coeff > 1) { /* queue is being weight-raised */
  45542. + bfq_log_bfqq(bfqd, bfqq,
  45543. + "raising period dur %u/%u msec, old coeff %u, w %d(%d)",
  45544. + jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish),
  45545. + jiffies_to_msecs(bfqq->wr_cur_max_time),
  45546. + bfqq->wr_coeff,
  45547. + bfqq->entity.weight, bfqq->entity.orig_weight);
  45548. +
  45549. + BUG_ON(bfqq != bfqd->in_service_queue && entity->weight !=
  45550. + entity->orig_weight * bfqq->wr_coeff);
  45551. + if (entity->ioprio_changed)
  45552. + bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change");
  45553. +
  45554. + /*
  45555. + * If too much time has elapsed from the beginning
  45556. + * of this weight-raising period, or the queue has
  45557. + * exceeded the acceptable number of cooperations,
  45558. + * stop it.
  45559. + */
  45560. + if (bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh ||
  45561. + time_is_before_jiffies(bfqq->last_wr_start_finish +
  45562. + bfqq->wr_cur_max_time)) {
  45563. + bfqq->last_wr_start_finish = jiffies;
  45564. + bfq_log_bfqq(bfqd, bfqq,
  45565. + "wrais ending at %lu, rais_max_time %u",
  45566. + bfqq->last_wr_start_finish,
  45567. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  45568. + bfq_bfqq_end_wr(bfqq);
  45569. + }
  45570. + }
  45571. + /* Update weight both if it must be raised and if it must be lowered */
  45572. + if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1))
  45573. + __bfq_entity_update_weight_prio(
  45574. + bfq_entity_service_tree(entity),
  45575. + entity);
  45576. +}
  45577. +
  45578. +/*
  45579. + * Dispatch one request from bfqq, moving it to the request queue
  45580. + * dispatch list.
  45581. + */
  45582. +static int bfq_dispatch_request(struct bfq_data *bfqd,
  45583. + struct bfq_queue *bfqq)
  45584. +{
  45585. + int dispatched = 0;
  45586. + struct request *rq;
  45587. + unsigned long service_to_charge;
  45588. +
  45589. + BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
  45590. +
  45591. + /* Follow expired path, else get first next available. */
  45592. + rq = bfq_check_fifo(bfqq);
  45593. + if (rq == NULL)
  45594. + rq = bfqq->next_rq;
  45595. + service_to_charge = bfq_serv_to_charge(rq, bfqq);
  45596. +
  45597. + if (service_to_charge > bfq_bfqq_budget_left(bfqq)) {
  45598. + /*
  45599. + * This may happen if the next rq is chosen in fifo order
  45600. + * instead of sector order. The budget is properly
  45601. + * dimensioned to be always sufficient to serve the next
  45602. + * request only if it is chosen in sector order. The reason
  45603. + * is that it would be quite inefficient and little useful
  45604. + * to always make sure that the budget is large enough to
  45605. + * serve even the possible next rq in fifo order.
  45606. + * In fact, requests are seldom served in fifo order.
  45607. + *
  45608. + * Expire the queue for budget exhaustion, and make sure
  45609. + * that the next act_budget is enough to serve the next
  45610. + * request, even if it comes from the fifo expired path.
  45611. + */
  45612. + bfqq->next_rq = rq;
  45613. + /*
  45614. + * Since this dispatch is failed, make sure that
  45615. + * a new one will be performed
  45616. + */
  45617. + if (!bfqd->rq_in_driver)
  45618. + bfq_schedule_dispatch(bfqd);
  45619. + goto expire;
  45620. + }
  45621. +
  45622. + /* Finally, insert request into driver dispatch list. */
  45623. + bfq_bfqq_served(bfqq, service_to_charge);
  45624. + bfq_dispatch_insert(bfqd->queue, rq);
  45625. +
  45626. + bfq_update_wr_data(bfqd, bfqq);
  45627. +
  45628. + bfq_log_bfqq(bfqd, bfqq,
  45629. + "dispatched %u sec req (%llu), budg left %lu",
  45630. + blk_rq_sectors(rq),
  45631. + (long long unsigned)blk_rq_pos(rq),
  45632. + bfq_bfqq_budget_left(bfqq));
  45633. +
  45634. + dispatched++;
  45635. +
  45636. + if (bfqd->in_service_bic == NULL) {
  45637. + atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount);
  45638. + bfqd->in_service_bic = RQ_BIC(rq);
  45639. + }
  45640. +
  45641. + if (bfqd->busy_queues > 1 && ((!bfq_bfqq_sync(bfqq) &&
  45642. + dispatched >= bfqd->bfq_max_budget_async_rq) ||
  45643. + bfq_class_idle(bfqq)))
  45644. + goto expire;
  45645. +
  45646. + return dispatched;
  45647. +
  45648. +expire:
  45649. + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_EXHAUSTED);
  45650. + return dispatched;
  45651. +}
  45652. +
  45653. +static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq)
  45654. +{
  45655. + int dispatched = 0;
  45656. +
  45657. + while (bfqq->next_rq != NULL) {
  45658. + bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq);
  45659. + dispatched++;
  45660. + }
  45661. +
  45662. + BUG_ON(!list_empty(&bfqq->fifo));
  45663. + return dispatched;
  45664. +}
  45665. +
  45666. +/*
  45667. + * Drain our current requests.
  45668. + * Used for barriers and when switching io schedulers on-the-fly.
  45669. + */
  45670. +static int bfq_forced_dispatch(struct bfq_data *bfqd)
  45671. +{
  45672. + struct bfq_queue *bfqq, *n;
  45673. + struct bfq_service_tree *st;
  45674. + int dispatched = 0;
  45675. +
  45676. + bfqq = bfqd->in_service_queue;
  45677. + if (bfqq != NULL)
  45678. + __bfq_bfqq_expire(bfqd, bfqq);
  45679. +
  45680. + /*
  45681. + * Loop through classes, and be careful to leave the scheduler
  45682. + * in a consistent state, as feedback mechanisms and vtime
  45683. + * updates cannot be disabled during the process.
  45684. + */
  45685. + list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) {
  45686. + st = bfq_entity_service_tree(&bfqq->entity);
  45687. +
  45688. + dispatched += __bfq_forced_dispatch_bfqq(bfqq);
  45689. + bfqq->max_budget = bfq_max_budget(bfqd);
  45690. +
  45691. + bfq_forget_idle(st);
  45692. + }
  45693. +
  45694. + BUG_ON(bfqd->busy_queues != 0);
  45695. +
  45696. + return dispatched;
  45697. +}
  45698. +
  45699. +static int bfq_dispatch_requests(struct request_queue *q, int force)
  45700. +{
  45701. + struct bfq_data *bfqd = q->elevator->elevator_data;
  45702. + struct bfq_queue *bfqq;
  45703. + int max_dispatch;
  45704. +
  45705. + bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues);
  45706. + if (bfqd->busy_queues == 0)
  45707. + return 0;
  45708. +
  45709. + if (unlikely(force))
  45710. + return bfq_forced_dispatch(bfqd);
  45711. +
  45712. + bfqq = bfq_select_queue(bfqd);
  45713. + if (bfqq == NULL)
  45714. + return 0;
  45715. +
  45716. + max_dispatch = bfqd->bfq_quantum;
  45717. + if (bfq_class_idle(bfqq))
  45718. + max_dispatch = 1;
  45719. +
  45720. + if (!bfq_bfqq_sync(bfqq))
  45721. + max_dispatch = bfqd->bfq_max_budget_async_rq;
  45722. +
  45723. + if (bfqq->dispatched >= max_dispatch) {
  45724. + if (bfqd->busy_queues > 1)
  45725. + return 0;
  45726. + if (bfqq->dispatched >= 4 * max_dispatch)
  45727. + return 0;
  45728. + }
  45729. +
  45730. + if (bfqd->sync_flight != 0 && !bfq_bfqq_sync(bfqq))
  45731. + return 0;
  45732. +
  45733. + bfq_clear_bfqq_wait_request(bfqq);
  45734. + BUG_ON(timer_pending(&bfqd->idle_slice_timer));
  45735. +
  45736. + if (!bfq_dispatch_request(bfqd, bfqq))
  45737. + return 0;
  45738. +
  45739. + bfq_log_bfqq(bfqd, bfqq, "dispatched one request of %d (max_disp %d)",
  45740. + bfqq->pid, max_dispatch);
  45741. +
  45742. + return 1;
  45743. +}
  45744. +
  45745. +/*
  45746. + * Task holds one reference to the queue, dropped when task exits. Each rq
  45747. + * in-flight on this queue also holds a reference, dropped when rq is freed.
  45748. + *
  45749. + * Queue lock must be held here.
  45750. + */
  45751. +static void bfq_put_queue(struct bfq_queue *bfqq)
  45752. +{
  45753. + struct bfq_data *bfqd = bfqq->bfqd;
  45754. +
  45755. + BUG_ON(atomic_read(&bfqq->ref) <= 0);
  45756. +
  45757. + bfq_log_bfqq(bfqd, bfqq, "put_queue: %p %d", bfqq,
  45758. + atomic_read(&bfqq->ref));
  45759. + if (!atomic_dec_and_test(&bfqq->ref))
  45760. + return;
  45761. +
  45762. + BUG_ON(rb_first(&bfqq->sort_list) != NULL);
  45763. + BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0);
  45764. + BUG_ON(bfqq->entity.tree != NULL);
  45765. + BUG_ON(bfq_bfqq_busy(bfqq));
  45766. + BUG_ON(bfqd->in_service_queue == bfqq);
  45767. +
  45768. + bfq_log_bfqq(bfqd, bfqq, "put_queue: %p freed", bfqq);
  45769. +
  45770. + kmem_cache_free(bfq_pool, bfqq);
  45771. +}
  45772. +
  45773. +static void bfq_put_cooperator(struct bfq_queue *bfqq)
  45774. +{
  45775. + struct bfq_queue *__bfqq, *next;
  45776. +
  45777. + /*
  45778. + * If this queue was scheduled to merge with another queue, be
  45779. + * sure to drop the reference taken on that queue (and others in
  45780. + * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs.
  45781. + */
  45782. + __bfqq = bfqq->new_bfqq;
  45783. + while (__bfqq) {
  45784. + if (__bfqq == bfqq)
  45785. + break;
  45786. + next = __bfqq->new_bfqq;
  45787. + bfq_put_queue(__bfqq);
  45788. + __bfqq = next;
  45789. + }
  45790. +}
  45791. +
  45792. +static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  45793. +{
  45794. + if (bfqq == bfqd->in_service_queue) {
  45795. + __bfq_bfqq_expire(bfqd, bfqq);
  45796. + bfq_schedule_dispatch(bfqd);
  45797. + }
  45798. +
  45799. + bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq,
  45800. + atomic_read(&bfqq->ref));
  45801. +
  45802. + bfq_put_cooperator(bfqq);
  45803. +
  45804. + bfq_put_queue(bfqq);
  45805. +}
  45806. +
  45807. +static inline void bfq_init_icq(struct io_cq *icq)
  45808. +{
  45809. + struct bfq_io_cq *bic = icq_to_bic(icq);
  45810. +
  45811. + bic->ttime.last_end_request = jiffies;
  45812. + /*
  45813. + * A newly created bic indicates that the process has just
  45814. + * started doing I/O, and is probably mapping into memory its
  45815. + * executable and libraries: it definitely needs weight raising.
  45816. + * There is however the possibility that the process performs,
  45817. + * for a while, I/O close to some other process. EQM intercepts
  45818. + * this behavior and may merge the queue corresponding to the
  45819. + * process with some other queue, BEFORE the weight of the queue
  45820. + * is raised. Merged queues are not weight-raised (they are assumed
  45821. + * to belong to processes that benefit only from high throughput).
  45822. + * If the merge is basically the consequence of an accident, then
  45823. + * the queue will be split soon and will get back its old weight.
  45824. + * It is then important to write down somewhere that this queue
  45825. + * does need weight raising, even if it did not make it to get its
  45826. + * weight raised before being merged. To this purpose, we overload
  45827. + * the field raising_time_left and assign 1 to it, to mark the queue
  45828. + * as needing weight raising.
  45829. + */
  45830. + bic->wr_time_left = 1;
  45831. +}
  45832. +
  45833. +static void bfq_exit_icq(struct io_cq *icq)
  45834. +{
  45835. + struct bfq_io_cq *bic = icq_to_bic(icq);
  45836. + struct bfq_data *bfqd = bic_to_bfqd(bic);
  45837. +
  45838. + if (bic->bfqq[BLK_RW_ASYNC]) {
  45839. + bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_ASYNC]);
  45840. + bic->bfqq[BLK_RW_ASYNC] = NULL;
  45841. + }
  45842. +
  45843. + if (bic->bfqq[BLK_RW_SYNC]) {
  45844. + /*
  45845. + * If the bic is using a shared queue, put the reference
  45846. + * taken on the io_context when the bic started using a
  45847. + * shared bfq_queue.
  45848. + */
  45849. + if (bfq_bfqq_coop(bic->bfqq[BLK_RW_SYNC]))
  45850. + put_io_context(icq->ioc);
  45851. + bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]);
  45852. + bic->bfqq[BLK_RW_SYNC] = NULL;
  45853. + }
  45854. +}
  45855. +
  45856. +/*
  45857. + * Update the entity prio values; note that the new values will not
  45858. + * be used until the next (re)activation.
  45859. + */
  45860. +static void bfq_init_prio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
  45861. +{
  45862. + struct task_struct *tsk = current;
  45863. + int ioprio_class;
  45864. +
  45865. + if (!bfq_bfqq_prio_changed(bfqq))
  45866. + return;
  45867. +
  45868. + ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio);
  45869. + switch (ioprio_class) {
  45870. + default:
  45871. + dev_err(bfqq->bfqd->queue->backing_dev_info.dev,
  45872. + "bfq: bad prio %x\n", ioprio_class);
  45873. + case IOPRIO_CLASS_NONE:
  45874. + /*
  45875. + * No prio set, inherit CPU scheduling settings.
  45876. + */
  45877. + bfqq->entity.new_ioprio = task_nice_ioprio(tsk);
  45878. + bfqq->entity.new_ioprio_class = task_nice_ioclass(tsk);
  45879. + break;
  45880. + case IOPRIO_CLASS_RT:
  45881. + bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
  45882. + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_RT;
  45883. + break;
  45884. + case IOPRIO_CLASS_BE:
  45885. + bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
  45886. + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_BE;
  45887. + break;
  45888. + case IOPRIO_CLASS_IDLE:
  45889. + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_IDLE;
  45890. + bfqq->entity.new_ioprio = 7;
  45891. + bfq_clear_bfqq_idle_window(bfqq);
  45892. + break;
  45893. + }
  45894. +
  45895. + bfqq->entity.ioprio_changed = 1;
  45896. +
  45897. + bfq_clear_bfqq_prio_changed(bfqq);
  45898. +}
  45899. +
  45900. +static void bfq_changed_ioprio(struct bfq_io_cq *bic)
  45901. +{
  45902. + struct bfq_data *bfqd;
  45903. + struct bfq_queue *bfqq, *new_bfqq;
  45904. + struct bfq_group *bfqg;
  45905. + unsigned long uninitialized_var(flags);
  45906. + int ioprio = bic->icq.ioc->ioprio;
  45907. +
  45908. + bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data),
  45909. + &flags);
  45910. + /*
  45911. + * This condition may trigger on a newly created bic, be sure to
  45912. + * drop the lock before returning.
  45913. + */
  45914. + if (unlikely(bfqd == NULL) || likely(bic->ioprio == ioprio))
  45915. + goto out;
  45916. +
  45917. + bfqq = bic->bfqq[BLK_RW_ASYNC];
  45918. + if (bfqq != NULL) {
  45919. + bfqg = container_of(bfqq->entity.sched_data, struct bfq_group,
  45920. + sched_data);
  45921. + new_bfqq = bfq_get_queue(bfqd, bfqg, BLK_RW_ASYNC, bic,
  45922. + GFP_ATOMIC);
  45923. + if (new_bfqq != NULL) {
  45924. + bic->bfqq[BLK_RW_ASYNC] = new_bfqq;
  45925. + bfq_log_bfqq(bfqd, bfqq,
  45926. + "changed_ioprio: bfqq %p %d",
  45927. + bfqq, atomic_read(&bfqq->ref));
  45928. + bfq_put_queue(bfqq);
  45929. + }
  45930. + }
  45931. +
  45932. + bfqq = bic->bfqq[BLK_RW_SYNC];
  45933. + if (bfqq != NULL)
  45934. + bfq_mark_bfqq_prio_changed(bfqq);
  45935. +
  45936. + bic->ioprio = ioprio;
  45937. +
  45938. +out:
  45939. + bfq_put_bfqd_unlock(bfqd, &flags);
  45940. +}
  45941. +
  45942. +static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  45943. + pid_t pid, int is_sync)
  45944. +{
  45945. + RB_CLEAR_NODE(&bfqq->entity.rb_node);
  45946. + INIT_LIST_HEAD(&bfqq->fifo);
  45947. +
  45948. + atomic_set(&bfqq->ref, 0);
  45949. + bfqq->bfqd = bfqd;
  45950. +
  45951. + bfq_mark_bfqq_prio_changed(bfqq);
  45952. +
  45953. + if (is_sync) {
  45954. + if (!bfq_class_idle(bfqq))
  45955. + bfq_mark_bfqq_idle_window(bfqq);
  45956. + bfq_mark_bfqq_sync(bfqq);
  45957. + }
  45958. + bfq_mark_bfqq_IO_bound(bfqq);
  45959. +
  45960. + /* Tentative initial value to trade off between thr and lat */
  45961. + bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3;
  45962. + bfqq->pid = pid;
  45963. +
  45964. + bfqq->wr_coeff = 1;
  45965. + bfqq->last_wr_start_finish = 0;
  45966. + /*
  45967. + * Set to the value for which bfqq will not be deemed as
  45968. + * soft rt when it becomes backlogged.
  45969. + */
  45970. + bfqq->soft_rt_next_start = bfq_infinity_from_now(jiffies);
  45971. +}
  45972. +
  45973. +static struct bfq_queue *bfq_find_alloc_queue(struct bfq_data *bfqd,
  45974. + struct bfq_group *bfqg,
  45975. + int is_sync,
  45976. + struct bfq_io_cq *bic,
  45977. + gfp_t gfp_mask)
  45978. +{
  45979. + struct bfq_queue *bfqq, *new_bfqq = NULL;
  45980. +
  45981. +retry:
  45982. + /* bic always exists here */
  45983. + bfqq = bic_to_bfqq(bic, is_sync);
  45984. +
  45985. + /*
  45986. + * Always try a new alloc if we fall back to the OOM bfqq
  45987. + * originally, since it should just be a temporary situation.
  45988. + */
  45989. + if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) {
  45990. + bfqq = NULL;
  45991. + if (new_bfqq != NULL) {
  45992. + bfqq = new_bfqq;
  45993. + new_bfqq = NULL;
  45994. + } else if (gfp_mask & __GFP_WAIT) {
  45995. + spin_unlock_irq(bfqd->queue->queue_lock);
  45996. + new_bfqq = kmem_cache_alloc_node(bfq_pool,
  45997. + gfp_mask | __GFP_ZERO,
  45998. + bfqd->queue->node);
  45999. + spin_lock_irq(bfqd->queue->queue_lock);
  46000. + if (new_bfqq != NULL)
  46001. + goto retry;
  46002. + } else {
  46003. + bfqq = kmem_cache_alloc_node(bfq_pool,
  46004. + gfp_mask | __GFP_ZERO,
  46005. + bfqd->queue->node);
  46006. + }
  46007. +
  46008. + if (bfqq != NULL) {
  46009. + bfq_init_bfqq(bfqd, bfqq, current->pid, is_sync);
  46010. + bfq_log_bfqq(bfqd, bfqq, "allocated");
  46011. + } else {
  46012. + bfqq = &bfqd->oom_bfqq;
  46013. + bfq_log_bfqq(bfqd, bfqq, "using oom bfqq");
  46014. + }
  46015. +
  46016. + bfq_init_prio_data(bfqq, bic);
  46017. + bfq_init_entity(&bfqq->entity, bfqg);
  46018. + }
  46019. +
  46020. + if (new_bfqq != NULL)
  46021. + kmem_cache_free(bfq_pool, new_bfqq);
  46022. +
  46023. + return bfqq;
  46024. +}
  46025. +
  46026. +static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd,
  46027. + struct bfq_group *bfqg,
  46028. + int ioprio_class, int ioprio)
  46029. +{
  46030. + switch (ioprio_class) {
  46031. + case IOPRIO_CLASS_RT:
  46032. + return &bfqg->async_bfqq[0][ioprio];
  46033. + case IOPRIO_CLASS_NONE:
  46034. + ioprio = IOPRIO_NORM;
  46035. + /* fall through */
  46036. + case IOPRIO_CLASS_BE:
  46037. + return &bfqg->async_bfqq[1][ioprio];
  46038. + case IOPRIO_CLASS_IDLE:
  46039. + return &bfqg->async_idle_bfqq;
  46040. + default:
  46041. + BUG();
  46042. + }
  46043. +}
  46044. +
  46045. +static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
  46046. + struct bfq_group *bfqg, int is_sync,
  46047. + struct bfq_io_cq *bic, gfp_t gfp_mask)
  46048. +{
  46049. + const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
  46050. + const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio);
  46051. + struct bfq_queue **async_bfqq = NULL;
  46052. + struct bfq_queue *bfqq = NULL;
  46053. +
  46054. + if (!is_sync) {
  46055. + async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class,
  46056. + ioprio);
  46057. + bfqq = *async_bfqq;
  46058. + }
  46059. +
  46060. + if (bfqq == NULL)
  46061. + bfqq = bfq_find_alloc_queue(bfqd, bfqg, is_sync, bic, gfp_mask);
  46062. +
  46063. + /*
  46064. + * Pin the queue now that it's allocated, scheduler exit will
  46065. + * prune it.
  46066. + */
  46067. + if (!is_sync && *async_bfqq == NULL) {
  46068. + atomic_inc(&bfqq->ref);
  46069. + bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d",
  46070. + bfqq, atomic_read(&bfqq->ref));
  46071. + *async_bfqq = bfqq;
  46072. + }
  46073. +
  46074. + atomic_inc(&bfqq->ref);
  46075. + bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq,
  46076. + atomic_read(&bfqq->ref));
  46077. + return bfqq;
  46078. +}
  46079. +
  46080. +static void bfq_update_io_thinktime(struct bfq_data *bfqd,
  46081. + struct bfq_io_cq *bic)
  46082. +{
  46083. + unsigned long elapsed = jiffies - bic->ttime.last_end_request;
  46084. + unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle);
  46085. +
  46086. + bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8;
  46087. + bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8;
  46088. + bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) /
  46089. + bic->ttime.ttime_samples;
  46090. +}
  46091. +
  46092. +static void bfq_update_io_seektime(struct bfq_data *bfqd,
  46093. + struct bfq_queue *bfqq,
  46094. + struct request *rq)
  46095. +{
  46096. + sector_t sdist;
  46097. + u64 total;
  46098. +
  46099. + if (bfqq->last_request_pos < blk_rq_pos(rq))
  46100. + sdist = blk_rq_pos(rq) - bfqq->last_request_pos;
  46101. + else
  46102. + sdist = bfqq->last_request_pos - blk_rq_pos(rq);
  46103. +
  46104. + /*
  46105. + * Don't allow the seek distance to get too large from the
  46106. + * odd fragment, pagein, etc.
  46107. + */
  46108. + if (bfqq->seek_samples == 0) /* first request, not really a seek */
  46109. + sdist = 0;
  46110. + else if (bfqq->seek_samples <= 60) /* second & third seek */
  46111. + sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024);
  46112. + else
  46113. + sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64);
  46114. +
  46115. + bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8;
  46116. + bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8;
  46117. + total = bfqq->seek_total + (bfqq->seek_samples/2);
  46118. + do_div(total, bfqq->seek_samples);
  46119. + bfqq->seek_mean = (sector_t)total;
  46120. +
  46121. + bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist,
  46122. + (u64)bfqq->seek_mean);
  46123. +}
  46124. +
  46125. +/*
  46126. + * Disable idle window if the process thinks too long or seeks so much that
  46127. + * it doesn't matter.
  46128. + */
  46129. +static void bfq_update_idle_window(struct bfq_data *bfqd,
  46130. + struct bfq_queue *bfqq,
  46131. + struct bfq_io_cq *bic)
  46132. +{
  46133. + int enable_idle;
  46134. +
  46135. + /* Don't idle for async or idle io prio class. */
  46136. + if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq))
  46137. + return;
  46138. +
  46139. + /* Idle window just restored, statistics are meaningless. */
  46140. + if (bfq_bfqq_just_split(bfqq))
  46141. + return;
  46142. +
  46143. + enable_idle = bfq_bfqq_idle_window(bfqq);
  46144. +
  46145. + if (atomic_read(&bic->icq.ioc->active_ref) == 0 ||
  46146. + bfqd->bfq_slice_idle == 0 ||
  46147. + (bfqd->hw_tag && BFQQ_SEEKY(bfqq) &&
  46148. + bfqq->wr_coeff == 1))
  46149. + enable_idle = 0;
  46150. + else if (bfq_sample_valid(bic->ttime.ttime_samples)) {
  46151. + if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle &&
  46152. + bfqq->wr_coeff == 1)
  46153. + enable_idle = 0;
  46154. + else
  46155. + enable_idle = 1;
  46156. + }
  46157. + bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d",
  46158. + enable_idle);
  46159. +
  46160. + if (enable_idle)
  46161. + bfq_mark_bfqq_idle_window(bfqq);
  46162. + else
  46163. + bfq_clear_bfqq_idle_window(bfqq);
  46164. +}
  46165. +
  46166. +/*
  46167. + * Called when a new fs request (rq) is added to bfqq. Check if there's
  46168. + * something we should do about it.
  46169. + */
  46170. +static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  46171. + struct request *rq)
  46172. +{
  46173. + struct bfq_io_cq *bic = RQ_BIC(rq);
  46174. +
  46175. + if (rq->cmd_flags & REQ_META)
  46176. + bfqq->meta_pending++;
  46177. +
  46178. + bfq_update_io_thinktime(bfqd, bic);
  46179. + bfq_update_io_seektime(bfqd, bfqq, rq);
  46180. + if (!BFQQ_SEEKY(bfqq) && bfq_bfqq_constantly_seeky(bfqq)) {
  46181. + bfq_clear_bfqq_constantly_seeky(bfqq);
  46182. + if (!blk_queue_nonrot(bfqd->queue)) {
  46183. + BUG_ON(!bfqd->const_seeky_busy_in_flight_queues);
  46184. + bfqd->const_seeky_busy_in_flight_queues--;
  46185. + }
  46186. + }
  46187. + if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 ||
  46188. + !BFQQ_SEEKY(bfqq))
  46189. + bfq_update_idle_window(bfqd, bfqq, bic);
  46190. + bfq_clear_bfqq_just_split(bfqq);
  46191. +
  46192. + bfq_log_bfqq(bfqd, bfqq,
  46193. + "rq_enqueued: idle_window=%d (seeky %d, mean %llu)",
  46194. + bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq),
  46195. + (long long unsigned)bfqq->seek_mean);
  46196. +
  46197. + bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
  46198. +
  46199. + if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) {
  46200. + int small_req = bfqq->queued[rq_is_sync(rq)] == 1 &&
  46201. + blk_rq_sectors(rq) < 32;
  46202. + int budget_timeout = bfq_bfqq_budget_timeout(bfqq);
  46203. +
  46204. + /*
  46205. + * There is just this request queued: if the request
  46206. + * is small and the queue is not to be expired, then
  46207. + * just exit.
  46208. + *
  46209. + * In this way, if the disk is being idled to wait for
  46210. + * a new request from the in-service queue, we avoid
  46211. + * unplugging the device and committing the disk to serve
  46212. + * just a small request. On the contrary, we wait for
  46213. + * the block layer to decide when to unplug the device:
  46214. + * hopefully, new requests will be merged to this one
  46215. + * quickly, then the device will be unplugged and
  46216. + * larger requests will be dispatched.
  46217. + */
  46218. + if (small_req && !budget_timeout)
  46219. + return;
  46220. +
  46221. + /*
  46222. + * A large enough request arrived, or the queue is to
  46223. + * be expired: in both cases disk idling is to be
  46224. + * stopped, so clear wait_request flag and reset
  46225. + * timer.
  46226. + */
  46227. + bfq_clear_bfqq_wait_request(bfqq);
  46228. + del_timer(&bfqd->idle_slice_timer);
  46229. +
  46230. + /*
  46231. + * The queue is not empty, because a new request just
  46232. + * arrived. Hence we can safely expire the queue, in
  46233. + * case of budget timeout, without risking that the
  46234. + * timestamps of the queue are not updated correctly.
  46235. + * See [1] for more details.
  46236. + */
  46237. + if (budget_timeout)
  46238. + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT);
  46239. +
  46240. + /*
  46241. + * Let the request rip immediately, or let a new queue be
  46242. + * selected if bfqq has just been expired.
  46243. + */
  46244. + __blk_run_queue(bfqd->queue);
  46245. + }
  46246. +}
  46247. +
  46248. +static void bfq_insert_request(struct request_queue *q, struct request *rq)
  46249. +{
  46250. + struct bfq_data *bfqd = q->elevator->elevator_data;
  46251. + struct bfq_queue *bfqq = RQ_BFQQ(rq), *new_bfqq;
  46252. +
  46253. + assert_spin_locked(bfqd->queue->queue_lock);
  46254. +
  46255. + /*
  46256. + * An unplug may trigger a requeue of a request from the device
  46257. + * driver: make sure we are in process context while trying to
  46258. + * merge two bfq_queues.
  46259. + */
  46260. + if (!in_interrupt()) {
  46261. + new_bfqq = bfq_setup_cooperator(bfqd, bfqq, rq, true);
  46262. + if (new_bfqq != NULL) {
  46263. + if (bic_to_bfqq(RQ_BIC(rq), 1) != bfqq)
  46264. + new_bfqq = bic_to_bfqq(RQ_BIC(rq), 1);
  46265. + /*
  46266. + * Release the request's reference to the old bfqq
  46267. + * and make sure one is taken to the shared queue.
  46268. + */
  46269. + new_bfqq->allocated[rq_data_dir(rq)]++;
  46270. + bfqq->allocated[rq_data_dir(rq)]--;
  46271. + atomic_inc(&new_bfqq->ref);
  46272. + bfq_put_queue(bfqq);
  46273. + if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq)
  46274. + bfq_merge_bfqqs(bfqd, RQ_BIC(rq),
  46275. + bfqq, new_bfqq);
  46276. + rq->elv.priv[1] = new_bfqq;
  46277. + bfqq = new_bfqq;
  46278. + } else
  46279. + bfq_bfqq_increase_failed_cooperations(bfqq);
  46280. + }
  46281. +
  46282. + bfq_init_prio_data(bfqq, RQ_BIC(rq));
  46283. +
  46284. + bfq_add_request(rq);
  46285. +
  46286. + /*
  46287. + * Here a newly-created bfq_queue has already started a weight-raising
  46288. + * period: clear raising_time_left to prevent bfq_bfqq_save_state()
  46289. + * from assigning it a full weight-raising period. See the detailed
  46290. + * comments about this field in bfq_init_icq().
  46291. + */
  46292. + if (bfqq->bic != NULL)
  46293. + bfqq->bic->wr_time_left = 0;
  46294. + rq_set_fifo_time(rq, jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]);
  46295. + list_add_tail(&rq->queuelist, &bfqq->fifo);
  46296. +
  46297. + bfq_rq_enqueued(bfqd, bfqq, rq);
  46298. +}
  46299. +
  46300. +static void bfq_update_hw_tag(struct bfq_data *bfqd)
  46301. +{
  46302. + bfqd->max_rq_in_driver = max(bfqd->max_rq_in_driver,
  46303. + bfqd->rq_in_driver);
  46304. +
  46305. + if (bfqd->hw_tag == 1)
  46306. + return;
  46307. +
  46308. + /*
  46309. + * This sample is valid if the number of outstanding requests
  46310. + * is large enough to allow a queueing behavior. Note that the
  46311. + * sum is not exact, as it's not taking into account deactivated
  46312. + * requests.
  46313. + */
  46314. + if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD)
  46315. + return;
  46316. +
  46317. + if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES)
  46318. + return;
  46319. +
  46320. + bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD;
  46321. + bfqd->max_rq_in_driver = 0;
  46322. + bfqd->hw_tag_samples = 0;
  46323. +}
  46324. +
  46325. +static void bfq_completed_request(struct request_queue *q, struct request *rq)
  46326. +{
  46327. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  46328. + struct bfq_data *bfqd = bfqq->bfqd;
  46329. + bool sync = bfq_bfqq_sync(bfqq);
  46330. +
  46331. + bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)",
  46332. + blk_rq_sectors(rq), sync);
  46333. +
  46334. + bfq_update_hw_tag(bfqd);
  46335. +
  46336. + BUG_ON(!bfqd->rq_in_driver);
  46337. + BUG_ON(!bfqq->dispatched);
  46338. + bfqd->rq_in_driver--;
  46339. + bfqq->dispatched--;
  46340. +
  46341. + if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) {
  46342. + bfq_weights_tree_remove(bfqd, &bfqq->entity,
  46343. + &bfqd->queue_weights_tree);
  46344. + if (!blk_queue_nonrot(bfqd->queue)) {
  46345. + BUG_ON(!bfqd->busy_in_flight_queues);
  46346. + bfqd->busy_in_flight_queues--;
  46347. + if (bfq_bfqq_constantly_seeky(bfqq)) {
  46348. + BUG_ON(!bfqd->
  46349. + const_seeky_busy_in_flight_queues);
  46350. + bfqd->const_seeky_busy_in_flight_queues--;
  46351. + }
  46352. + }
  46353. + }
  46354. +
  46355. + if (sync) {
  46356. + bfqd->sync_flight--;
  46357. + RQ_BIC(rq)->ttime.last_end_request = jiffies;
  46358. + }
  46359. +
  46360. + /*
  46361. + * If we are waiting to discover whether the request pattern of the
  46362. + * task associated with the queue is actually isochronous, and
  46363. + * both requisites for this condition to hold are satisfied, then
  46364. + * compute soft_rt_next_start (see the comments to the function
  46365. + * bfq_bfqq_softrt_next_start()).
  46366. + */
  46367. + if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 &&
  46368. + RB_EMPTY_ROOT(&bfqq->sort_list))
  46369. + bfqq->soft_rt_next_start =
  46370. + bfq_bfqq_softrt_next_start(bfqd, bfqq);
  46371. +
  46372. + /*
  46373. + * If this is the in-service queue, check if it needs to be expired,
  46374. + * or if we want to idle in case it has no pending requests.
  46375. + */
  46376. + if (bfqd->in_service_queue == bfqq) {
  46377. + if (bfq_bfqq_budget_new(bfqq))
  46378. + bfq_set_budget_timeout(bfqd);
  46379. +
  46380. + if (bfq_bfqq_must_idle(bfqq)) {
  46381. + bfq_arm_slice_timer(bfqd);
  46382. + goto out;
  46383. + } else if (bfq_may_expire_for_budg_timeout(bfqq))
  46384. + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT);
  46385. + else if (RB_EMPTY_ROOT(&bfqq->sort_list) &&
  46386. + (bfqq->dispatched == 0 ||
  46387. + !bfq_bfqq_must_not_expire(bfqq)))
  46388. + bfq_bfqq_expire(bfqd, bfqq, 0,
  46389. + BFQ_BFQQ_NO_MORE_REQUESTS);
  46390. + }
  46391. +
  46392. + if (!bfqd->rq_in_driver)
  46393. + bfq_schedule_dispatch(bfqd);
  46394. +
  46395. +out:
  46396. + return;
  46397. +}
  46398. +
  46399. +static inline int __bfq_may_queue(struct bfq_queue *bfqq)
  46400. +{
  46401. + if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) {
  46402. + bfq_clear_bfqq_must_alloc(bfqq);
  46403. + return ELV_MQUEUE_MUST;
  46404. + }
  46405. +
  46406. + return ELV_MQUEUE_MAY;
  46407. +}
  46408. +
  46409. +static int bfq_may_queue(struct request_queue *q, int rw)
  46410. +{
  46411. + struct bfq_data *bfqd = q->elevator->elevator_data;
  46412. + struct task_struct *tsk = current;
  46413. + struct bfq_io_cq *bic;
  46414. + struct bfq_queue *bfqq;
  46415. +
  46416. + /*
  46417. + * Don't force setup of a queue from here, as a call to may_queue
  46418. + * does not necessarily imply that a request actually will be
  46419. + * queued. So just lookup a possibly existing queue, or return
  46420. + * 'may queue' if that fails.
  46421. + */
  46422. + bic = bfq_bic_lookup(bfqd, tsk->io_context);
  46423. + if (bic == NULL)
  46424. + return ELV_MQUEUE_MAY;
  46425. +
  46426. + bfqq = bic_to_bfqq(bic, rw_is_sync(rw));
  46427. + if (bfqq != NULL) {
  46428. + bfq_init_prio_data(bfqq, bic);
  46429. +
  46430. + return __bfq_may_queue(bfqq);
  46431. + }
  46432. +
  46433. + return ELV_MQUEUE_MAY;
  46434. +}
  46435. +
  46436. +/*
  46437. + * Queue lock held here.
  46438. + */
  46439. +static void bfq_put_request(struct request *rq)
  46440. +{
  46441. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  46442. +
  46443. + if (bfqq != NULL) {
  46444. + const int rw = rq_data_dir(rq);
  46445. +
  46446. + BUG_ON(!bfqq->allocated[rw]);
  46447. + bfqq->allocated[rw]--;
  46448. +
  46449. + rq->elv.priv[0] = NULL;
  46450. + rq->elv.priv[1] = NULL;
  46451. +
  46452. + bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d",
  46453. + bfqq, atomic_read(&bfqq->ref));
  46454. + bfq_put_queue(bfqq);
  46455. + }
  46456. +}
  46457. +
  46458. +/*
  46459. + * Returns NULL if a new bfqq should be allocated, or the old bfqq if this
  46460. + * was the last process referring to said bfqq.
  46461. + */
  46462. +static struct bfq_queue *
  46463. +bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
  46464. +{
  46465. + bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
  46466. +
  46467. + put_io_context(bic->icq.ioc);
  46468. +
  46469. + if (bfqq_process_refs(bfqq) == 1) {
  46470. + bfqq->pid = current->pid;
  46471. + bfq_clear_bfqq_coop(bfqq);
  46472. + bfq_clear_bfqq_split_coop(bfqq);
  46473. + return bfqq;
  46474. + }
  46475. +
  46476. + bic_set_bfqq(bic, NULL, 1);
  46477. +
  46478. + bfq_put_cooperator(bfqq);
  46479. +
  46480. + bfq_put_queue(bfqq);
  46481. + return NULL;
  46482. +}
  46483. +
  46484. +/*
  46485. + * Allocate bfq data structures associated with this request.
  46486. + */
  46487. +static int bfq_set_request(struct request_queue *q, struct request *rq,
  46488. + struct bio *bio, gfp_t gfp_mask)
  46489. +{
  46490. + struct bfq_data *bfqd = q->elevator->elevator_data;
  46491. + struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq);
  46492. + const int rw = rq_data_dir(rq);
  46493. + const int is_sync = rq_is_sync(rq);
  46494. + struct bfq_queue *bfqq;
  46495. + struct bfq_group *bfqg;
  46496. + unsigned long flags;
  46497. + bool split = false;
  46498. +
  46499. + might_sleep_if(gfp_mask & __GFP_WAIT);
  46500. +
  46501. + bfq_changed_ioprio(bic);
  46502. +
  46503. + spin_lock_irqsave(q->queue_lock, flags);
  46504. +
  46505. + if (bic == NULL)
  46506. + goto queue_fail;
  46507. +
  46508. + bfqg = bfq_bic_update_cgroup(bic);
  46509. +
  46510. +new_queue:
  46511. + bfqq = bic_to_bfqq(bic, is_sync);
  46512. + if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) {
  46513. + bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic, gfp_mask);
  46514. + bic_set_bfqq(bic, bfqq, is_sync);
  46515. + } else {
  46516. + /* If the queue was seeky for too long, break it apart. */
  46517. + if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) {
  46518. + bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq");
  46519. + bfqq = bfq_split_bfqq(bic, bfqq);
  46520. + split = true;
  46521. + if (!bfqq)
  46522. + goto new_queue;
  46523. + }
  46524. + }
  46525. +
  46526. + bfqq->allocated[rw]++;
  46527. + atomic_inc(&bfqq->ref);
  46528. + bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq,
  46529. + atomic_read(&bfqq->ref));
  46530. +
  46531. + rq->elv.priv[0] = bic;
  46532. + rq->elv.priv[1] = bfqq;
  46533. +
  46534. + /*
  46535. + * If a bfq_queue has only one process reference, it is owned
  46536. + * by only one bfq_io_cq: we can set the bic field of the
  46537. + * bfq_queue to the address of that structure. Also, if the
  46538. + * queue has just been split, mark a flag so that the
  46539. + * information is available to the other scheduler hooks.
  46540. + */
  46541. + if (bfqq_process_refs(bfqq) == 1) {
  46542. + bfqq->bic = bic;
  46543. + if (split) {
  46544. + bfq_mark_bfqq_just_split(bfqq);
  46545. + /*
  46546. + * If the queue has just been split from a shared
  46547. + * queue, restore the idle window and the possible
  46548. + * weight raising period.
  46549. + */
  46550. + bfq_bfqq_resume_state(bfqq, bic);
  46551. + }
  46552. + }
  46553. +
  46554. + spin_unlock_irqrestore(q->queue_lock, flags);
  46555. +
  46556. + return 0;
  46557. +
  46558. +queue_fail:
  46559. + bfq_schedule_dispatch(bfqd);
  46560. + spin_unlock_irqrestore(q->queue_lock, flags);
  46561. +
  46562. + return 1;
  46563. +}
  46564. +
  46565. +static void bfq_kick_queue(struct work_struct *work)
  46566. +{
  46567. + struct bfq_data *bfqd =
  46568. + container_of(work, struct bfq_data, unplug_work);
  46569. + struct request_queue *q = bfqd->queue;
  46570. +
  46571. + spin_lock_irq(q->queue_lock);
  46572. + __blk_run_queue(q);
  46573. + spin_unlock_irq(q->queue_lock);
  46574. +}
  46575. +
  46576. +/*
  46577. + * Handler of the expiration of the timer running if the in-service queue
  46578. + * is idling inside its time slice.
  46579. + */
  46580. +static void bfq_idle_slice_timer(unsigned long data)
  46581. +{
  46582. + struct bfq_data *bfqd = (struct bfq_data *)data;
  46583. + struct bfq_queue *bfqq;
  46584. + unsigned long flags;
  46585. + enum bfqq_expiration reason;
  46586. +
  46587. + spin_lock_irqsave(bfqd->queue->queue_lock, flags);
  46588. +
  46589. + bfqq = bfqd->in_service_queue;
  46590. + /*
  46591. + * Theoretical race here: the in-service queue can be NULL or
  46592. + * different from the queue that was idling if the timer handler
  46593. + * spins on the queue_lock and a new request arrives for the
  46594. + * current queue and there is a full dispatch cycle that changes
  46595. + * the in-service queue. This can hardly happen, but in the worst
  46596. + * case we just expire a queue too early.
  46597. + */
  46598. + if (bfqq != NULL) {
  46599. + bfq_log_bfqq(bfqd, bfqq, "slice_timer expired");
  46600. + if (bfq_bfqq_budget_timeout(bfqq))
  46601. + /*
  46602. + * Also here the queue can be safely expired
  46603. + * for budget timeout without wasting
  46604. + * guarantees
  46605. + */
  46606. + reason = BFQ_BFQQ_BUDGET_TIMEOUT;
  46607. + else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0)
  46608. + /*
  46609. + * The queue may not be empty upon timer expiration,
  46610. + * because we may not disable the timer when the
  46611. + * first request of the in-service queue arrives
  46612. + * during disk idling.
  46613. + */
  46614. + reason = BFQ_BFQQ_TOO_IDLE;
  46615. + else
  46616. + goto schedule_dispatch;
  46617. +
  46618. + bfq_bfqq_expire(bfqd, bfqq, 1, reason);
  46619. + }
  46620. +
  46621. +schedule_dispatch:
  46622. + bfq_schedule_dispatch(bfqd);
  46623. +
  46624. + spin_unlock_irqrestore(bfqd->queue->queue_lock, flags);
  46625. +}
  46626. +
  46627. +static void bfq_shutdown_timer_wq(struct bfq_data *bfqd)
  46628. +{
  46629. + del_timer_sync(&bfqd->idle_slice_timer);
  46630. + cancel_work_sync(&bfqd->unplug_work);
  46631. +}
  46632. +
  46633. +static inline void __bfq_put_async_bfqq(struct bfq_data *bfqd,
  46634. + struct bfq_queue **bfqq_ptr)
  46635. +{
  46636. + struct bfq_group *root_group = bfqd->root_group;
  46637. + struct bfq_queue *bfqq = *bfqq_ptr;
  46638. +
  46639. + bfq_log(bfqd, "put_async_bfqq: %p", bfqq);
  46640. + if (bfqq != NULL) {
  46641. + bfq_bfqq_move(bfqd, bfqq, &bfqq->entity, root_group);
  46642. + bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d",
  46643. + bfqq, atomic_read(&bfqq->ref));
  46644. + bfq_put_queue(bfqq);
  46645. + *bfqq_ptr = NULL;
  46646. + }
  46647. +}
  46648. +
  46649. +/*
  46650. + * Release all the bfqg references to its async queues. If we are
  46651. + * deallocating the group these queues may still contain requests, so
  46652. + * we reparent them to the root cgroup (i.e., the only one that will
  46653. + * exist for sure until all the requests on a device are gone).
  46654. + */
  46655. +static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg)
  46656. +{
  46657. + int i, j;
  46658. +
  46659. + for (i = 0; i < 2; i++)
  46660. + for (j = 0; j < IOPRIO_BE_NR; j++)
  46661. + __bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]);
  46662. +
  46663. + __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq);
  46664. +}
  46665. +
  46666. +static void bfq_exit_queue(struct elevator_queue *e)
  46667. +{
  46668. + struct bfq_data *bfqd = e->elevator_data;
  46669. + struct request_queue *q = bfqd->queue;
  46670. + struct bfq_queue *bfqq, *n;
  46671. +
  46672. + bfq_shutdown_timer_wq(bfqd);
  46673. +
  46674. + spin_lock_irq(q->queue_lock);
  46675. +
  46676. + BUG_ON(bfqd->in_service_queue != NULL);
  46677. + list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list)
  46678. + bfq_deactivate_bfqq(bfqd, bfqq, 0);
  46679. +
  46680. + bfq_disconnect_groups(bfqd);
  46681. + spin_unlock_irq(q->queue_lock);
  46682. +
  46683. + bfq_shutdown_timer_wq(bfqd);
  46684. +
  46685. + synchronize_rcu();
  46686. +
  46687. + BUG_ON(timer_pending(&bfqd->idle_slice_timer));
  46688. +
  46689. + bfq_free_root_group(bfqd);
  46690. + kfree(bfqd);
  46691. +}
  46692. +
  46693. +static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
  46694. +{
  46695. + struct bfq_group *bfqg;
  46696. + struct bfq_data *bfqd;
  46697. + struct elevator_queue *eq;
  46698. +
  46699. + eq = elevator_alloc(q, e);
  46700. + if (eq == NULL)
  46701. + return -ENOMEM;
  46702. +
  46703. + bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node);
  46704. + if (bfqd == NULL) {
  46705. + kobject_put(&eq->kobj);
  46706. + return -ENOMEM;
  46707. + }
  46708. + eq->elevator_data = bfqd;
  46709. +
  46710. + /*
  46711. + * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues.
  46712. + * Grab a permanent reference to it, so that the normal code flow
  46713. + * will not attempt to free it.
  46714. + */
  46715. + bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, 1, 0);
  46716. + atomic_inc(&bfqd->oom_bfqq.ref);
  46717. +
  46718. + bfqd->queue = q;
  46719. +
  46720. + spin_lock_irq(q->queue_lock);
  46721. + q->elevator = eq;
  46722. + spin_unlock_irq(q->queue_lock);
  46723. +
  46724. + bfqg = bfq_alloc_root_group(bfqd, q->node);
  46725. + if (bfqg == NULL) {
  46726. + kfree(bfqd);
  46727. + kobject_put(&eq->kobj);
  46728. + return -ENOMEM;
  46729. + }
  46730. +
  46731. + bfqd->root_group = bfqg;
  46732. +#ifdef CONFIG_CGROUP_BFQIO
  46733. + bfqd->active_numerous_groups = 0;
  46734. +#endif
  46735. +
  46736. + init_timer(&bfqd->idle_slice_timer);
  46737. + bfqd->idle_slice_timer.function = bfq_idle_slice_timer;
  46738. + bfqd->idle_slice_timer.data = (unsigned long)bfqd;
  46739. +
  46740. + bfqd->rq_pos_tree = RB_ROOT;
  46741. + bfqd->queue_weights_tree = RB_ROOT;
  46742. + bfqd->group_weights_tree = RB_ROOT;
  46743. +
  46744. + INIT_WORK(&bfqd->unplug_work, bfq_kick_queue);
  46745. +
  46746. + INIT_LIST_HEAD(&bfqd->active_list);
  46747. + INIT_LIST_HEAD(&bfqd->idle_list);
  46748. +
  46749. + bfqd->hw_tag = -1;
  46750. +
  46751. + bfqd->bfq_max_budget = bfq_default_max_budget;
  46752. +
  46753. + bfqd->bfq_quantum = bfq_quantum;
  46754. + bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0];
  46755. + bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1];
  46756. + bfqd->bfq_back_max = bfq_back_max;
  46757. + bfqd->bfq_back_penalty = bfq_back_penalty;
  46758. + bfqd->bfq_slice_idle = bfq_slice_idle;
  46759. + bfqd->bfq_class_idle_last_service = 0;
  46760. + bfqd->bfq_max_budget_async_rq = bfq_max_budget_async_rq;
  46761. + bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async;
  46762. + bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync;
  46763. +
  46764. + bfqd->bfq_coop_thresh = 2;
  46765. + bfqd->bfq_failed_cooperations = 7000;
  46766. + bfqd->bfq_requests_within_timer = 120;
  46767. +
  46768. + bfqd->low_latency = true;
  46769. +
  46770. + bfqd->bfq_wr_coeff = 20;
  46771. + bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300);
  46772. + bfqd->bfq_wr_max_time = 0;
  46773. + bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000);
  46774. + bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500);
  46775. + bfqd->bfq_wr_max_softrt_rate = 7000; /*
  46776. + * Approximate rate required
  46777. + * to playback or record a
  46778. + * high-definition compressed
  46779. + * video.
  46780. + */
  46781. + bfqd->wr_busy_queues = 0;
  46782. + bfqd->busy_in_flight_queues = 0;
  46783. + bfqd->const_seeky_busy_in_flight_queues = 0;
  46784. +
  46785. + /*
  46786. + * Begin by assuming, optimistically, that the device peak rate is
  46787. + * equal to the highest reference rate.
  46788. + */
  46789. + bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] *
  46790. + T_fast[blk_queue_nonrot(bfqd->queue)];
  46791. + bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)];
  46792. + bfqd->device_speed = BFQ_BFQD_FAST;
  46793. +
  46794. + return 0;
  46795. +}
  46796. +
  46797. +static void bfq_slab_kill(void)
  46798. +{
  46799. + if (bfq_pool != NULL)
  46800. + kmem_cache_destroy(bfq_pool);
  46801. +}
  46802. +
  46803. +static int __init bfq_slab_setup(void)
  46804. +{
  46805. + bfq_pool = KMEM_CACHE(bfq_queue, 0);
  46806. + if (bfq_pool == NULL)
  46807. + return -ENOMEM;
  46808. + return 0;
  46809. +}
  46810. +
  46811. +static ssize_t bfq_var_show(unsigned int var, char *page)
  46812. +{
  46813. + return sprintf(page, "%d\n", var);
  46814. +}
  46815. +
  46816. +static ssize_t bfq_var_store(unsigned long *var, const char *page,
  46817. + size_t count)
  46818. +{
  46819. + unsigned long new_val;
  46820. + int ret = kstrtoul(page, 10, &new_val);
  46821. +
  46822. + if (ret == 0)
  46823. + *var = new_val;
  46824. +
  46825. + return count;
  46826. +}
  46827. +
  46828. +static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page)
  46829. +{
  46830. + struct bfq_data *bfqd = e->elevator_data;
  46831. + return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ?
  46832. + jiffies_to_msecs(bfqd->bfq_wr_max_time) :
  46833. + jiffies_to_msecs(bfq_wr_duration(bfqd)));
  46834. +}
  46835. +
  46836. +static ssize_t bfq_weights_show(struct elevator_queue *e, char *page)
  46837. +{
  46838. + struct bfq_queue *bfqq;
  46839. + struct bfq_data *bfqd = e->elevator_data;
  46840. + ssize_t num_char = 0;
  46841. +
  46842. + num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n",
  46843. + bfqd->queued);
  46844. +
  46845. + spin_lock_irq(bfqd->queue->queue_lock);
  46846. +
  46847. + num_char += sprintf(page + num_char, "Active:\n");
  46848. + list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) {
  46849. + num_char += sprintf(page + num_char,
  46850. + "pid%d: weight %hu, nr_queued %d %d, dur %d/%u\n",
  46851. + bfqq->pid,
  46852. + bfqq->entity.weight,
  46853. + bfqq->queued[0],
  46854. + bfqq->queued[1],
  46855. + jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish),
  46856. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  46857. + }
  46858. +
  46859. + num_char += sprintf(page + num_char, "Idle:\n");
  46860. + list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) {
  46861. + num_char += sprintf(page + num_char,
  46862. + "pid%d: weight %hu, dur %d/%u\n",
  46863. + bfqq->pid,
  46864. + bfqq->entity.weight,
  46865. + jiffies_to_msecs(jiffies -
  46866. + bfqq->last_wr_start_finish),
  46867. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  46868. + }
  46869. +
  46870. + spin_unlock_irq(bfqd->queue->queue_lock);
  46871. +
  46872. + return num_char;
  46873. +}
  46874. +
  46875. +#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
  46876. +static ssize_t __FUNC(struct elevator_queue *e, char *page) \
  46877. +{ \
  46878. + struct bfq_data *bfqd = e->elevator_data; \
  46879. + unsigned int __data = __VAR; \
  46880. + if (__CONV) \
  46881. + __data = jiffies_to_msecs(__data); \
  46882. + return bfq_var_show(__data, (page)); \
  46883. +}
  46884. +SHOW_FUNCTION(bfq_quantum_show, bfqd->bfq_quantum, 0);
  46885. +SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 1);
  46886. +SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1);
  46887. +SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0);
  46888. +SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0);
  46889. +SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1);
  46890. +SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0);
  46891. +SHOW_FUNCTION(bfq_max_budget_async_rq_show,
  46892. + bfqd->bfq_max_budget_async_rq, 0);
  46893. +SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout[BLK_RW_SYNC], 1);
  46894. +SHOW_FUNCTION(bfq_timeout_async_show, bfqd->bfq_timeout[BLK_RW_ASYNC], 1);
  46895. +SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0);
  46896. +SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0);
  46897. +SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1);
  46898. +SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1);
  46899. +SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async,
  46900. + 1);
  46901. +SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0);
  46902. +#undef SHOW_FUNCTION
  46903. +
  46904. +#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \
  46905. +static ssize_t \
  46906. +__FUNC(struct elevator_queue *e, const char *page, size_t count) \
  46907. +{ \
  46908. + struct bfq_data *bfqd = e->elevator_data; \
  46909. + unsigned long uninitialized_var(__data); \
  46910. + int ret = bfq_var_store(&__data, (page), count); \
  46911. + if (__data < (MIN)) \
  46912. + __data = (MIN); \
  46913. + else if (__data > (MAX)) \
  46914. + __data = (MAX); \
  46915. + if (__CONV) \
  46916. + *(__PTR) = msecs_to_jiffies(__data); \
  46917. + else \
  46918. + *(__PTR) = __data; \
  46919. + return ret; \
  46920. +}
  46921. +STORE_FUNCTION(bfq_quantum_store, &bfqd->bfq_quantum, 1, INT_MAX, 0);
  46922. +STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1,
  46923. + INT_MAX, 1);
  46924. +STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1,
  46925. + INT_MAX, 1);
  46926. +STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0);
  46927. +STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1,
  46928. + INT_MAX, 0);
  46929. +STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1);
  46930. +STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq,
  46931. + 1, INT_MAX, 0);
  46932. +STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0,
  46933. + INT_MAX, 1);
  46934. +STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0);
  46935. +STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1);
  46936. +STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX,
  46937. + 1);
  46938. +STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0,
  46939. + INT_MAX, 1);
  46940. +STORE_FUNCTION(bfq_wr_min_inter_arr_async_store,
  46941. + &bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1);
  46942. +STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0,
  46943. + INT_MAX, 0);
  46944. +#undef STORE_FUNCTION
  46945. +
  46946. +/* do nothing for the moment */
  46947. +static ssize_t bfq_weights_store(struct elevator_queue *e,
  46948. + const char *page, size_t count)
  46949. +{
  46950. + return count;
  46951. +}
  46952. +
  46953. +static inline unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd)
  46954. +{
  46955. + u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]);
  46956. +
  46957. + if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES)
  46958. + return bfq_calc_max_budget(bfqd->peak_rate, timeout);
  46959. + else
  46960. + return bfq_default_max_budget;
  46961. +}
  46962. +
  46963. +static ssize_t bfq_max_budget_store(struct elevator_queue *e,
  46964. + const char *page, size_t count)
  46965. +{
  46966. + struct bfq_data *bfqd = e->elevator_data;
  46967. + unsigned long uninitialized_var(__data);
  46968. + int ret = bfq_var_store(&__data, (page), count);
  46969. +
  46970. + if (__data == 0)
  46971. + bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd);
  46972. + else {
  46973. + if (__data > INT_MAX)
  46974. + __data = INT_MAX;
  46975. + bfqd->bfq_max_budget = __data;
  46976. + }
  46977. +
  46978. + bfqd->bfq_user_max_budget = __data;
  46979. +
  46980. + return ret;
  46981. +}
  46982. +
  46983. +static ssize_t bfq_timeout_sync_store(struct elevator_queue *e,
  46984. + const char *page, size_t count)
  46985. +{
  46986. + struct bfq_data *bfqd = e->elevator_data;
  46987. + unsigned long uninitialized_var(__data);
  46988. + int ret = bfq_var_store(&__data, (page), count);
  46989. +
  46990. + if (__data < 1)
  46991. + __data = 1;
  46992. + else if (__data > INT_MAX)
  46993. + __data = INT_MAX;
  46994. +
  46995. + bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data);
  46996. + if (bfqd->bfq_user_max_budget == 0)
  46997. + bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd);
  46998. +
  46999. + return ret;
  47000. +}
  47001. +
  47002. +static ssize_t bfq_low_latency_store(struct elevator_queue *e,
  47003. + const char *page, size_t count)
  47004. +{
  47005. + struct bfq_data *bfqd = e->elevator_data;
  47006. + unsigned long uninitialized_var(__data);
  47007. + int ret = bfq_var_store(&__data, (page), count);
  47008. +
  47009. + if (__data > 1)
  47010. + __data = 1;
  47011. + if (__data == 0 && bfqd->low_latency != 0)
  47012. + bfq_end_wr(bfqd);
  47013. + bfqd->low_latency = __data;
  47014. +
  47015. + return ret;
  47016. +}
  47017. +
  47018. +#define BFQ_ATTR(name) \
  47019. + __ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store)
  47020. +
  47021. +static struct elv_fs_entry bfq_attrs[] = {
  47022. + BFQ_ATTR(quantum),
  47023. + BFQ_ATTR(fifo_expire_sync),
  47024. + BFQ_ATTR(fifo_expire_async),
  47025. + BFQ_ATTR(back_seek_max),
  47026. + BFQ_ATTR(back_seek_penalty),
  47027. + BFQ_ATTR(slice_idle),
  47028. + BFQ_ATTR(max_budget),
  47029. + BFQ_ATTR(max_budget_async_rq),
  47030. + BFQ_ATTR(timeout_sync),
  47031. + BFQ_ATTR(timeout_async),
  47032. + BFQ_ATTR(low_latency),
  47033. + BFQ_ATTR(wr_coeff),
  47034. + BFQ_ATTR(wr_max_time),
  47035. + BFQ_ATTR(wr_rt_max_time),
  47036. + BFQ_ATTR(wr_min_idle_time),
  47037. + BFQ_ATTR(wr_min_inter_arr_async),
  47038. + BFQ_ATTR(wr_max_softrt_rate),
  47039. + BFQ_ATTR(weights),
  47040. + __ATTR_NULL
  47041. +};
  47042. +
  47043. +static struct elevator_type iosched_bfq = {
  47044. + .ops = {
  47045. + .elevator_merge_fn = bfq_merge,
  47046. + .elevator_merged_fn = bfq_merged_request,
  47047. + .elevator_merge_req_fn = bfq_merged_requests,
  47048. + .elevator_allow_merge_fn = bfq_allow_merge,
  47049. + .elevator_dispatch_fn = bfq_dispatch_requests,
  47050. + .elevator_add_req_fn = bfq_insert_request,
  47051. + .elevator_activate_req_fn = bfq_activate_request,
  47052. + .elevator_deactivate_req_fn = bfq_deactivate_request,
  47053. + .elevator_completed_req_fn = bfq_completed_request,
  47054. + .elevator_former_req_fn = elv_rb_former_request,
  47055. + .elevator_latter_req_fn = elv_rb_latter_request,
  47056. + .elevator_init_icq_fn = bfq_init_icq,
  47057. + .elevator_exit_icq_fn = bfq_exit_icq,
  47058. + .elevator_set_req_fn = bfq_set_request,
  47059. + .elevator_put_req_fn = bfq_put_request,
  47060. + .elevator_may_queue_fn = bfq_may_queue,
  47061. + .elevator_init_fn = bfq_init_queue,
  47062. + .elevator_exit_fn = bfq_exit_queue,
  47063. + },
  47064. + .icq_size = sizeof(struct bfq_io_cq),
  47065. + .icq_align = __alignof__(struct bfq_io_cq),
  47066. + .elevator_attrs = bfq_attrs,
  47067. + .elevator_name = "bfq",
  47068. + .elevator_owner = THIS_MODULE,
  47069. +};
  47070. +
  47071. +static int __init bfq_init(void)
  47072. +{
  47073. + /*
  47074. + * Can be 0 on HZ < 1000 setups.
  47075. + */
  47076. + if (bfq_slice_idle == 0)
  47077. + bfq_slice_idle = 1;
  47078. +
  47079. + if (bfq_timeout_async == 0)
  47080. + bfq_timeout_async = 1;
  47081. +
  47082. + if (bfq_slab_setup())
  47083. + return -ENOMEM;
  47084. +
  47085. + /*
  47086. + * Times to load large popular applications for the typical systems
  47087. + * installed on the reference devices (see the comments before the
  47088. + * definitions of the two arrays).
  47089. + */
  47090. + T_slow[0] = msecs_to_jiffies(2600);
  47091. + T_slow[1] = msecs_to_jiffies(1000);
  47092. + T_fast[0] = msecs_to_jiffies(5500);
  47093. + T_fast[1] = msecs_to_jiffies(2000);
  47094. +
  47095. + /*
  47096. + * Thresholds that determine the switch between speed classes (see
  47097. + * the comments before the definition of the array).
  47098. + */
  47099. + device_speed_thresh[0] = (R_fast[0] + R_slow[0]) / 2;
  47100. + device_speed_thresh[1] = (R_fast[1] + R_slow[1]) / 2;
  47101. +
  47102. + elv_register(&iosched_bfq);
  47103. + pr_info("BFQ I/O-scheduler version: v7r5");
  47104. +
  47105. + return 0;
  47106. +}
  47107. +
  47108. +static void __exit bfq_exit(void)
  47109. +{
  47110. + elv_unregister(&iosched_bfq);
  47111. + bfq_slab_kill();
  47112. +}
  47113. +
  47114. +module_init(bfq_init);
  47115. +module_exit(bfq_exit);
  47116. +
  47117. +MODULE_AUTHOR("Fabio Checconi, Paolo Valente");
  47118. +MODULE_LICENSE("GPL");
  47119. diff -Nur linux-3.14.15/block/bfq-sched.c linux-linaro-stable-mx6/block/bfq-sched.c
  47120. --- linux-3.14.15/block/bfq-sched.c 1970-01-01 01:00:00.000000000 +0100
  47121. +++ linux-linaro-stable-mx6/block/bfq-sched.c 2014-08-20 19:31:42.192852109 +0200
  47122. @@ -0,0 +1,1179 @@
  47123. +/*
  47124. + * BFQ: Hierarchical B-WF2Q+ scheduler.
  47125. + *
  47126. + * Based on ideas and code from CFQ:
  47127. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  47128. + *
  47129. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  47130. + * Paolo Valente <paolo.valente@unimore.it>
  47131. + *
  47132. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  47133. + */
  47134. +
  47135. +#ifdef CONFIG_CGROUP_BFQIO
  47136. +#define for_each_entity(entity) \
  47137. + for (; entity != NULL; entity = entity->parent)
  47138. +
  47139. +#define for_each_entity_safe(entity, parent) \
  47140. + for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
  47141. +
  47142. +static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
  47143. + int extract,
  47144. + struct bfq_data *bfqd);
  47145. +
  47146. +static inline void bfq_update_budget(struct bfq_entity *next_in_service)
  47147. +{
  47148. + struct bfq_entity *bfqg_entity;
  47149. + struct bfq_group *bfqg;
  47150. + struct bfq_sched_data *group_sd;
  47151. +
  47152. + BUG_ON(next_in_service == NULL);
  47153. +
  47154. + group_sd = next_in_service->sched_data;
  47155. +
  47156. + bfqg = container_of(group_sd, struct bfq_group, sched_data);
  47157. + /*
  47158. + * bfq_group's my_entity field is not NULL only if the group
  47159. + * is not the root group. We must not touch the root entity
  47160. + * as it must never become an in-service entity.
  47161. + */
  47162. + bfqg_entity = bfqg->my_entity;
  47163. + if (bfqg_entity != NULL)
  47164. + bfqg_entity->budget = next_in_service->budget;
  47165. +}
  47166. +
  47167. +static int bfq_update_next_in_service(struct bfq_sched_data *sd)
  47168. +{
  47169. + struct bfq_entity *next_in_service;
  47170. +
  47171. + if (sd->in_service_entity != NULL)
  47172. + /* will update/requeue at the end of service */
  47173. + return 0;
  47174. +
  47175. + /*
  47176. + * NOTE: this can be improved in many ways, such as returning
  47177. + * 1 (and thus propagating upwards the update) only when the
  47178. + * budget changes, or caching the bfqq that will be scheduled
  47179. + * next from this subtree. By now we worry more about
  47180. + * correctness than about performance...
  47181. + */
  47182. + next_in_service = bfq_lookup_next_entity(sd, 0, NULL);
  47183. + sd->next_in_service = next_in_service;
  47184. +
  47185. + if (next_in_service != NULL)
  47186. + bfq_update_budget(next_in_service);
  47187. +
  47188. + return 1;
  47189. +}
  47190. +
  47191. +static inline void bfq_check_next_in_service(struct bfq_sched_data *sd,
  47192. + struct bfq_entity *entity)
  47193. +{
  47194. + BUG_ON(sd->next_in_service != entity);
  47195. +}
  47196. +#else
  47197. +#define for_each_entity(entity) \
  47198. + for (; entity != NULL; entity = NULL)
  47199. +
  47200. +#define for_each_entity_safe(entity, parent) \
  47201. + for (parent = NULL; entity != NULL; entity = parent)
  47202. +
  47203. +static inline int bfq_update_next_in_service(struct bfq_sched_data *sd)
  47204. +{
  47205. + return 0;
  47206. +}
  47207. +
  47208. +static inline void bfq_check_next_in_service(struct bfq_sched_data *sd,
  47209. + struct bfq_entity *entity)
  47210. +{
  47211. +}
  47212. +
  47213. +static inline void bfq_update_budget(struct bfq_entity *next_in_service)
  47214. +{
  47215. +}
  47216. +#endif
  47217. +
  47218. +/*
  47219. + * Shift for timestamp calculations. This actually limits the maximum
  47220. + * service allowed in one timestamp delta (small shift values increase it),
  47221. + * the maximum total weight that can be used for the queues in the system
  47222. + * (big shift values increase it), and the period of virtual time
  47223. + * wraparounds.
  47224. + */
  47225. +#define WFQ_SERVICE_SHIFT 22
  47226. +
  47227. +/**
  47228. + * bfq_gt - compare two timestamps.
  47229. + * @a: first ts.
  47230. + * @b: second ts.
  47231. + *
  47232. + * Return @a > @b, dealing with wrapping correctly.
  47233. + */
  47234. +static inline int bfq_gt(u64 a, u64 b)
  47235. +{
  47236. + return (s64)(a - b) > 0;
  47237. +}
  47238. +
  47239. +static inline struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity)
  47240. +{
  47241. + struct bfq_queue *bfqq = NULL;
  47242. +
  47243. + BUG_ON(entity == NULL);
  47244. +
  47245. + if (entity->my_sched_data == NULL)
  47246. + bfqq = container_of(entity, struct bfq_queue, entity);
  47247. +
  47248. + return bfqq;
  47249. +}
  47250. +
  47251. +
  47252. +/**
  47253. + * bfq_delta - map service into the virtual time domain.
  47254. + * @service: amount of service.
  47255. + * @weight: scale factor (weight of an entity or weight sum).
  47256. + */
  47257. +static inline u64 bfq_delta(unsigned long service,
  47258. + unsigned long weight)
  47259. +{
  47260. + u64 d = (u64)service << WFQ_SERVICE_SHIFT;
  47261. +
  47262. + do_div(d, weight);
  47263. + return d;
  47264. +}
  47265. +
  47266. +/**
  47267. + * bfq_calc_finish - assign the finish time to an entity.
  47268. + * @entity: the entity to act upon.
  47269. + * @service: the service to be charged to the entity.
  47270. + */
  47271. +static inline void bfq_calc_finish(struct bfq_entity *entity,
  47272. + unsigned long service)
  47273. +{
  47274. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47275. +
  47276. + BUG_ON(entity->weight == 0);
  47277. +
  47278. + entity->finish = entity->start +
  47279. + bfq_delta(service, entity->weight);
  47280. +
  47281. + if (bfqq != NULL) {
  47282. + bfq_log_bfqq(bfqq->bfqd, bfqq,
  47283. + "calc_finish: serv %lu, w %d",
  47284. + service, entity->weight);
  47285. + bfq_log_bfqq(bfqq->bfqd, bfqq,
  47286. + "calc_finish: start %llu, finish %llu, delta %llu",
  47287. + entity->start, entity->finish,
  47288. + bfq_delta(service, entity->weight));
  47289. + }
  47290. +}
  47291. +
  47292. +/**
  47293. + * bfq_entity_of - get an entity from a node.
  47294. + * @node: the node field of the entity.
  47295. + *
  47296. + * Convert a node pointer to the relative entity. This is used only
  47297. + * to simplify the logic of some functions and not as the generic
  47298. + * conversion mechanism because, e.g., in the tree walking functions,
  47299. + * the check for a %NULL value would be redundant.
  47300. + */
  47301. +static inline struct bfq_entity *bfq_entity_of(struct rb_node *node)
  47302. +{
  47303. + struct bfq_entity *entity = NULL;
  47304. +
  47305. + if (node != NULL)
  47306. + entity = rb_entry(node, struct bfq_entity, rb_node);
  47307. +
  47308. + return entity;
  47309. +}
  47310. +
  47311. +/**
  47312. + * bfq_extract - remove an entity from a tree.
  47313. + * @root: the tree root.
  47314. + * @entity: the entity to remove.
  47315. + */
  47316. +static inline void bfq_extract(struct rb_root *root,
  47317. + struct bfq_entity *entity)
  47318. +{
  47319. + BUG_ON(entity->tree != root);
  47320. +
  47321. + entity->tree = NULL;
  47322. + rb_erase(&entity->rb_node, root);
  47323. +}
  47324. +
  47325. +/**
  47326. + * bfq_idle_extract - extract an entity from the idle tree.
  47327. + * @st: the service tree of the owning @entity.
  47328. + * @entity: the entity being removed.
  47329. + */
  47330. +static void bfq_idle_extract(struct bfq_service_tree *st,
  47331. + struct bfq_entity *entity)
  47332. +{
  47333. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47334. + struct rb_node *next;
  47335. +
  47336. + BUG_ON(entity->tree != &st->idle);
  47337. +
  47338. + if (entity == st->first_idle) {
  47339. + next = rb_next(&entity->rb_node);
  47340. + st->first_idle = bfq_entity_of(next);
  47341. + }
  47342. +
  47343. + if (entity == st->last_idle) {
  47344. + next = rb_prev(&entity->rb_node);
  47345. + st->last_idle = bfq_entity_of(next);
  47346. + }
  47347. +
  47348. + bfq_extract(&st->idle, entity);
  47349. +
  47350. + if (bfqq != NULL)
  47351. + list_del(&bfqq->bfqq_list);
  47352. +}
  47353. +
  47354. +/**
  47355. + * bfq_insert - generic tree insertion.
  47356. + * @root: tree root.
  47357. + * @entity: entity to insert.
  47358. + *
  47359. + * This is used for the idle and the active tree, since they are both
  47360. + * ordered by finish time.
  47361. + */
  47362. +static void bfq_insert(struct rb_root *root, struct bfq_entity *entity)
  47363. +{
  47364. + struct bfq_entity *entry;
  47365. + struct rb_node **node = &root->rb_node;
  47366. + struct rb_node *parent = NULL;
  47367. +
  47368. + BUG_ON(entity->tree != NULL);
  47369. +
  47370. + while (*node != NULL) {
  47371. + parent = *node;
  47372. + entry = rb_entry(parent, struct bfq_entity, rb_node);
  47373. +
  47374. + if (bfq_gt(entry->finish, entity->finish))
  47375. + node = &parent->rb_left;
  47376. + else
  47377. + node = &parent->rb_right;
  47378. + }
  47379. +
  47380. + rb_link_node(&entity->rb_node, parent, node);
  47381. + rb_insert_color(&entity->rb_node, root);
  47382. +
  47383. + entity->tree = root;
  47384. +}
  47385. +
  47386. +/**
  47387. + * bfq_update_min - update the min_start field of a entity.
  47388. + * @entity: the entity to update.
  47389. + * @node: one of its children.
  47390. + *
  47391. + * This function is called when @entity may store an invalid value for
  47392. + * min_start due to updates to the active tree. The function assumes
  47393. + * that the subtree rooted at @node (which may be its left or its right
  47394. + * child) has a valid min_start value.
  47395. + */
  47396. +static inline void bfq_update_min(struct bfq_entity *entity,
  47397. + struct rb_node *node)
  47398. +{
  47399. + struct bfq_entity *child;
  47400. +
  47401. + if (node != NULL) {
  47402. + child = rb_entry(node, struct bfq_entity, rb_node);
  47403. + if (bfq_gt(entity->min_start, child->min_start))
  47404. + entity->min_start = child->min_start;
  47405. + }
  47406. +}
  47407. +
  47408. +/**
  47409. + * bfq_update_active_node - recalculate min_start.
  47410. + * @node: the node to update.
  47411. + *
  47412. + * @node may have changed position or one of its children may have moved,
  47413. + * this function updates its min_start value. The left and right subtrees
  47414. + * are assumed to hold a correct min_start value.
  47415. + */
  47416. +static inline void bfq_update_active_node(struct rb_node *node)
  47417. +{
  47418. + struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node);
  47419. +
  47420. + entity->min_start = entity->start;
  47421. + bfq_update_min(entity, node->rb_right);
  47422. + bfq_update_min(entity, node->rb_left);
  47423. +}
  47424. +
  47425. +/**
  47426. + * bfq_update_active_tree - update min_start for the whole active tree.
  47427. + * @node: the starting node.
  47428. + *
  47429. + * @node must be the deepest modified node after an update. This function
  47430. + * updates its min_start using the values held by its children, assuming
  47431. + * that they did not change, and then updates all the nodes that may have
  47432. + * changed in the path to the root. The only nodes that may have changed
  47433. + * are the ones in the path or their siblings.
  47434. + */
  47435. +static void bfq_update_active_tree(struct rb_node *node)
  47436. +{
  47437. + struct rb_node *parent;
  47438. +
  47439. +up:
  47440. + bfq_update_active_node(node);
  47441. +
  47442. + parent = rb_parent(node);
  47443. + if (parent == NULL)
  47444. + return;
  47445. +
  47446. + if (node == parent->rb_left && parent->rb_right != NULL)
  47447. + bfq_update_active_node(parent->rb_right);
  47448. + else if (parent->rb_left != NULL)
  47449. + bfq_update_active_node(parent->rb_left);
  47450. +
  47451. + node = parent;
  47452. + goto up;
  47453. +}
  47454. +
  47455. +static void bfq_weights_tree_add(struct bfq_data *bfqd,
  47456. + struct bfq_entity *entity,
  47457. + struct rb_root *root);
  47458. +
  47459. +static void bfq_weights_tree_remove(struct bfq_data *bfqd,
  47460. + struct bfq_entity *entity,
  47461. + struct rb_root *root);
  47462. +
  47463. +
  47464. +/**
  47465. + * bfq_active_insert - insert an entity in the active tree of its
  47466. + * group/device.
  47467. + * @st: the service tree of the entity.
  47468. + * @entity: the entity being inserted.
  47469. + *
  47470. + * The active tree is ordered by finish time, but an extra key is kept
  47471. + * per each node, containing the minimum value for the start times of
  47472. + * its children (and the node itself), so it's possible to search for
  47473. + * the eligible node with the lowest finish time in logarithmic time.
  47474. + */
  47475. +static void bfq_active_insert(struct bfq_service_tree *st,
  47476. + struct bfq_entity *entity)
  47477. +{
  47478. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47479. + struct rb_node *node = &entity->rb_node;
  47480. +#ifdef CONFIG_CGROUP_BFQIO
  47481. + struct bfq_sched_data *sd = NULL;
  47482. + struct bfq_group *bfqg = NULL;
  47483. + struct bfq_data *bfqd = NULL;
  47484. +#endif
  47485. +
  47486. + bfq_insert(&st->active, entity);
  47487. +
  47488. + if (node->rb_left != NULL)
  47489. + node = node->rb_left;
  47490. + else if (node->rb_right != NULL)
  47491. + node = node->rb_right;
  47492. +
  47493. + bfq_update_active_tree(node);
  47494. +
  47495. +#ifdef CONFIG_CGROUP_BFQIO
  47496. + sd = entity->sched_data;
  47497. + bfqg = container_of(sd, struct bfq_group, sched_data);
  47498. + BUG_ON(!bfqg);
  47499. + bfqd = (struct bfq_data *)bfqg->bfqd;
  47500. +#endif
  47501. + if (bfqq != NULL)
  47502. + list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list);
  47503. +#ifdef CONFIG_CGROUP_BFQIO
  47504. + else { /* bfq_group */
  47505. + BUG_ON(!bfqd);
  47506. + bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree);
  47507. + }
  47508. + if (bfqg != bfqd->root_group) {
  47509. + BUG_ON(!bfqg);
  47510. + BUG_ON(!bfqd);
  47511. + bfqg->active_entities++;
  47512. + if (bfqg->active_entities == 2)
  47513. + bfqd->active_numerous_groups++;
  47514. + }
  47515. +#endif
  47516. +}
  47517. +
  47518. +/**
  47519. + * bfq_ioprio_to_weight - calc a weight from an ioprio.
  47520. + * @ioprio: the ioprio value to convert.
  47521. + */
  47522. +static inline unsigned short bfq_ioprio_to_weight(int ioprio)
  47523. +{
  47524. + BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR);
  47525. + return IOPRIO_BE_NR - ioprio;
  47526. +}
  47527. +
  47528. +/**
  47529. + * bfq_weight_to_ioprio - calc an ioprio from a weight.
  47530. + * @weight: the weight value to convert.
  47531. + *
  47532. + * To preserve as mush as possible the old only-ioprio user interface,
  47533. + * 0 is used as an escape ioprio value for weights (numerically) equal or
  47534. + * larger than IOPRIO_BE_NR
  47535. + */
  47536. +static inline unsigned short bfq_weight_to_ioprio(int weight)
  47537. +{
  47538. + BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT);
  47539. + return IOPRIO_BE_NR - weight < 0 ? 0 : IOPRIO_BE_NR - weight;
  47540. +}
  47541. +
  47542. +static inline void bfq_get_entity(struct bfq_entity *entity)
  47543. +{
  47544. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47545. +
  47546. + if (bfqq != NULL) {
  47547. + atomic_inc(&bfqq->ref);
  47548. + bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d",
  47549. + bfqq, atomic_read(&bfqq->ref));
  47550. + }
  47551. +}
  47552. +
  47553. +/**
  47554. + * bfq_find_deepest - find the deepest node that an extraction can modify.
  47555. + * @node: the node being removed.
  47556. + *
  47557. + * Do the first step of an extraction in an rb tree, looking for the
  47558. + * node that will replace @node, and returning the deepest node that
  47559. + * the following modifications to the tree can touch. If @node is the
  47560. + * last node in the tree return %NULL.
  47561. + */
  47562. +static struct rb_node *bfq_find_deepest(struct rb_node *node)
  47563. +{
  47564. + struct rb_node *deepest;
  47565. +
  47566. + if (node->rb_right == NULL && node->rb_left == NULL)
  47567. + deepest = rb_parent(node);
  47568. + else if (node->rb_right == NULL)
  47569. + deepest = node->rb_left;
  47570. + else if (node->rb_left == NULL)
  47571. + deepest = node->rb_right;
  47572. + else {
  47573. + deepest = rb_next(node);
  47574. + if (deepest->rb_right != NULL)
  47575. + deepest = deepest->rb_right;
  47576. + else if (rb_parent(deepest) != node)
  47577. + deepest = rb_parent(deepest);
  47578. + }
  47579. +
  47580. + return deepest;
  47581. +}
  47582. +
  47583. +/**
  47584. + * bfq_active_extract - remove an entity from the active tree.
  47585. + * @st: the service_tree containing the tree.
  47586. + * @entity: the entity being removed.
  47587. + */
  47588. +static void bfq_active_extract(struct bfq_service_tree *st,
  47589. + struct bfq_entity *entity)
  47590. +{
  47591. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47592. + struct rb_node *node;
  47593. +#ifdef CONFIG_CGROUP_BFQIO
  47594. + struct bfq_sched_data *sd = NULL;
  47595. + struct bfq_group *bfqg = NULL;
  47596. + struct bfq_data *bfqd = NULL;
  47597. +#endif
  47598. +
  47599. + node = bfq_find_deepest(&entity->rb_node);
  47600. + bfq_extract(&st->active, entity);
  47601. +
  47602. + if (node != NULL)
  47603. + bfq_update_active_tree(node);
  47604. +
  47605. +#ifdef CONFIG_CGROUP_BFQIO
  47606. + sd = entity->sched_data;
  47607. + bfqg = container_of(sd, struct bfq_group, sched_data);
  47608. + BUG_ON(!bfqg);
  47609. + bfqd = (struct bfq_data *)bfqg->bfqd;
  47610. +#endif
  47611. + if (bfqq != NULL)
  47612. + list_del(&bfqq->bfqq_list);
  47613. +#ifdef CONFIG_CGROUP_BFQIO
  47614. + else { /* bfq_group */
  47615. + BUG_ON(!bfqd);
  47616. + bfq_weights_tree_remove(bfqd, entity,
  47617. + &bfqd->group_weights_tree);
  47618. + }
  47619. + if (bfqg != bfqd->root_group) {
  47620. + BUG_ON(!bfqg);
  47621. + BUG_ON(!bfqd);
  47622. + BUG_ON(!bfqg->active_entities);
  47623. + bfqg->active_entities--;
  47624. + if (bfqg->active_entities == 1) {
  47625. + BUG_ON(!bfqd->active_numerous_groups);
  47626. + bfqd->active_numerous_groups--;
  47627. + }
  47628. + }
  47629. +#endif
  47630. +}
  47631. +
  47632. +/**
  47633. + * bfq_idle_insert - insert an entity into the idle tree.
  47634. + * @st: the service tree containing the tree.
  47635. + * @entity: the entity to insert.
  47636. + */
  47637. +static void bfq_idle_insert(struct bfq_service_tree *st,
  47638. + struct bfq_entity *entity)
  47639. +{
  47640. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47641. + struct bfq_entity *first_idle = st->first_idle;
  47642. + struct bfq_entity *last_idle = st->last_idle;
  47643. +
  47644. + if (first_idle == NULL || bfq_gt(first_idle->finish, entity->finish))
  47645. + st->first_idle = entity;
  47646. + if (last_idle == NULL || bfq_gt(entity->finish, last_idle->finish))
  47647. + st->last_idle = entity;
  47648. +
  47649. + bfq_insert(&st->idle, entity);
  47650. +
  47651. + if (bfqq != NULL)
  47652. + list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list);
  47653. +}
  47654. +
  47655. +/**
  47656. + * bfq_forget_entity - remove an entity from the wfq trees.
  47657. + * @st: the service tree.
  47658. + * @entity: the entity being removed.
  47659. + *
  47660. + * Update the device status and forget everything about @entity, putting
  47661. + * the device reference to it, if it is a queue. Entities belonging to
  47662. + * groups are not refcounted.
  47663. + */
  47664. +static void bfq_forget_entity(struct bfq_service_tree *st,
  47665. + struct bfq_entity *entity)
  47666. +{
  47667. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47668. + struct bfq_sched_data *sd;
  47669. +
  47670. + BUG_ON(!entity->on_st);
  47671. +
  47672. + entity->on_st = 0;
  47673. + st->wsum -= entity->weight;
  47674. + if (bfqq != NULL) {
  47675. + sd = entity->sched_data;
  47676. + bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d",
  47677. + bfqq, atomic_read(&bfqq->ref));
  47678. + bfq_put_queue(bfqq);
  47679. + }
  47680. +}
  47681. +
  47682. +/**
  47683. + * bfq_put_idle_entity - release the idle tree ref of an entity.
  47684. + * @st: service tree for the entity.
  47685. + * @entity: the entity being released.
  47686. + */
  47687. +static void bfq_put_idle_entity(struct bfq_service_tree *st,
  47688. + struct bfq_entity *entity)
  47689. +{
  47690. + bfq_idle_extract(st, entity);
  47691. + bfq_forget_entity(st, entity);
  47692. +}
  47693. +
  47694. +/**
  47695. + * bfq_forget_idle - update the idle tree if necessary.
  47696. + * @st: the service tree to act upon.
  47697. + *
  47698. + * To preserve the global O(log N) complexity we only remove one entry here;
  47699. + * as the idle tree will not grow indefinitely this can be done safely.
  47700. + */
  47701. +static void bfq_forget_idle(struct bfq_service_tree *st)
  47702. +{
  47703. + struct bfq_entity *first_idle = st->first_idle;
  47704. + struct bfq_entity *last_idle = st->last_idle;
  47705. +
  47706. + if (RB_EMPTY_ROOT(&st->active) && last_idle != NULL &&
  47707. + !bfq_gt(last_idle->finish, st->vtime)) {
  47708. + /*
  47709. + * Forget the whole idle tree, increasing the vtime past
  47710. + * the last finish time of idle entities.
  47711. + */
  47712. + st->vtime = last_idle->finish;
  47713. + }
  47714. +
  47715. + if (first_idle != NULL && !bfq_gt(first_idle->finish, st->vtime))
  47716. + bfq_put_idle_entity(st, first_idle);
  47717. +}
  47718. +
  47719. +static struct bfq_service_tree *
  47720. +__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
  47721. + struct bfq_entity *entity)
  47722. +{
  47723. + struct bfq_service_tree *new_st = old_st;
  47724. +
  47725. + if (entity->ioprio_changed) {
  47726. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47727. + unsigned short prev_weight, new_weight;
  47728. + struct bfq_data *bfqd = NULL;
  47729. + struct rb_root *root;
  47730. +#ifdef CONFIG_CGROUP_BFQIO
  47731. + struct bfq_sched_data *sd;
  47732. + struct bfq_group *bfqg;
  47733. +#endif
  47734. +
  47735. + if (bfqq != NULL)
  47736. + bfqd = bfqq->bfqd;
  47737. +#ifdef CONFIG_CGROUP_BFQIO
  47738. + else {
  47739. + sd = entity->my_sched_data;
  47740. + bfqg = container_of(sd, struct bfq_group, sched_data);
  47741. + BUG_ON(!bfqg);
  47742. + bfqd = (struct bfq_data *)bfqg->bfqd;
  47743. + BUG_ON(!bfqd);
  47744. + }
  47745. +#endif
  47746. +
  47747. + BUG_ON(old_st->wsum < entity->weight);
  47748. + old_st->wsum -= entity->weight;
  47749. +
  47750. + if (entity->new_weight != entity->orig_weight) {
  47751. + entity->orig_weight = entity->new_weight;
  47752. + entity->ioprio =
  47753. + bfq_weight_to_ioprio(entity->orig_weight);
  47754. + } else if (entity->new_ioprio != entity->ioprio) {
  47755. + entity->ioprio = entity->new_ioprio;
  47756. + entity->orig_weight =
  47757. + bfq_ioprio_to_weight(entity->ioprio);
  47758. + } else
  47759. + entity->new_weight = entity->orig_weight =
  47760. + bfq_ioprio_to_weight(entity->ioprio);
  47761. +
  47762. + entity->ioprio_class = entity->new_ioprio_class;
  47763. + entity->ioprio_changed = 0;
  47764. +
  47765. + /*
  47766. + * NOTE: here we may be changing the weight too early,
  47767. + * this will cause unfairness. The correct approach
  47768. + * would have required additional complexity to defer
  47769. + * weight changes to the proper time instants (i.e.,
  47770. + * when entity->finish <= old_st->vtime).
  47771. + */
  47772. + new_st = bfq_entity_service_tree(entity);
  47773. +
  47774. + prev_weight = entity->weight;
  47775. + new_weight = entity->orig_weight *
  47776. + (bfqq != NULL ? bfqq->wr_coeff : 1);
  47777. + /*
  47778. + * If the weight of the entity changes, remove the entity
  47779. + * from its old weight counter (if there is a counter
  47780. + * associated with the entity), and add it to the counter
  47781. + * associated with its new weight.
  47782. + */
  47783. + if (prev_weight != new_weight) {
  47784. + root = bfqq ? &bfqd->queue_weights_tree :
  47785. + &bfqd->group_weights_tree;
  47786. + bfq_weights_tree_remove(bfqd, entity, root);
  47787. + }
  47788. + entity->weight = new_weight;
  47789. + /*
  47790. + * Add the entity to its weights tree only if it is
  47791. + * not associated with a weight-raised queue.
  47792. + */
  47793. + if (prev_weight != new_weight &&
  47794. + (bfqq ? bfqq->wr_coeff == 1 : 1))
  47795. + /* If we get here, root has been initialized. */
  47796. + bfq_weights_tree_add(bfqd, entity, root);
  47797. +
  47798. + new_st->wsum += entity->weight;
  47799. +
  47800. + if (new_st != old_st)
  47801. + entity->start = new_st->vtime;
  47802. + }
  47803. +
  47804. + return new_st;
  47805. +}
  47806. +
  47807. +/**
  47808. + * bfq_bfqq_served - update the scheduler status after selection for
  47809. + * service.
  47810. + * @bfqq: the queue being served.
  47811. + * @served: bytes to transfer.
  47812. + *
  47813. + * NOTE: this can be optimized, as the timestamps of upper level entities
  47814. + * are synchronized every time a new bfqq is selected for service. By now,
  47815. + * we keep it to better check consistency.
  47816. + */
  47817. +static void bfq_bfqq_served(struct bfq_queue *bfqq, unsigned long served)
  47818. +{
  47819. + struct bfq_entity *entity = &bfqq->entity;
  47820. + struct bfq_service_tree *st;
  47821. +
  47822. + for_each_entity(entity) {
  47823. + st = bfq_entity_service_tree(entity);
  47824. +
  47825. + entity->service += served;
  47826. + BUG_ON(entity->service > entity->budget);
  47827. + BUG_ON(st->wsum == 0);
  47828. +
  47829. + st->vtime += bfq_delta(served, st->wsum);
  47830. + bfq_forget_idle(st);
  47831. + }
  47832. + bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %lu secs", served);
  47833. +}
  47834. +
  47835. +/**
  47836. + * bfq_bfqq_charge_full_budget - set the service to the entity budget.
  47837. + * @bfqq: the queue that needs a service update.
  47838. + *
  47839. + * When it's not possible to be fair in the service domain, because
  47840. + * a queue is not consuming its budget fast enough (the meaning of
  47841. + * fast depends on the timeout parameter), we charge it a full
  47842. + * budget. In this way we should obtain a sort of time-domain
  47843. + * fairness among all the seeky/slow queues.
  47844. + */
  47845. +static inline void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq)
  47846. +{
  47847. + struct bfq_entity *entity = &bfqq->entity;
  47848. +
  47849. + bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget");
  47850. +
  47851. + bfq_bfqq_served(bfqq, entity->budget - entity->service);
  47852. +}
  47853. +
  47854. +/**
  47855. + * __bfq_activate_entity - activate an entity.
  47856. + * @entity: the entity being activated.
  47857. + *
  47858. + * Called whenever an entity is activated, i.e., it is not active and one
  47859. + * of its children receives a new request, or has to be reactivated due to
  47860. + * budget exhaustion. It uses the current budget of the entity (and the
  47861. + * service received if @entity is active) of the queue to calculate its
  47862. + * timestamps.
  47863. + */
  47864. +static void __bfq_activate_entity(struct bfq_entity *entity)
  47865. +{
  47866. + struct bfq_sched_data *sd = entity->sched_data;
  47867. + struct bfq_service_tree *st = bfq_entity_service_tree(entity);
  47868. +
  47869. + if (entity == sd->in_service_entity) {
  47870. + BUG_ON(entity->tree != NULL);
  47871. + /*
  47872. + * If we are requeueing the current entity we have
  47873. + * to take care of not charging to it service it has
  47874. + * not received.
  47875. + */
  47876. + bfq_calc_finish(entity, entity->service);
  47877. + entity->start = entity->finish;
  47878. + sd->in_service_entity = NULL;
  47879. + } else if (entity->tree == &st->active) {
  47880. + /*
  47881. + * Requeueing an entity due to a change of some
  47882. + * next_in_service entity below it. We reuse the
  47883. + * old start time.
  47884. + */
  47885. + bfq_active_extract(st, entity);
  47886. + } else if (entity->tree == &st->idle) {
  47887. + /*
  47888. + * Must be on the idle tree, bfq_idle_extract() will
  47889. + * check for that.
  47890. + */
  47891. + bfq_idle_extract(st, entity);
  47892. + entity->start = bfq_gt(st->vtime, entity->finish) ?
  47893. + st->vtime : entity->finish;
  47894. + } else {
  47895. + /*
  47896. + * The finish time of the entity may be invalid, and
  47897. + * it is in the past for sure, otherwise the queue
  47898. + * would have been on the idle tree.
  47899. + */
  47900. + entity->start = st->vtime;
  47901. + st->wsum += entity->weight;
  47902. + bfq_get_entity(entity);
  47903. +
  47904. + BUG_ON(entity->on_st);
  47905. + entity->on_st = 1;
  47906. + }
  47907. +
  47908. + st = __bfq_entity_update_weight_prio(st, entity);
  47909. + bfq_calc_finish(entity, entity->budget);
  47910. + bfq_active_insert(st, entity);
  47911. +}
  47912. +
  47913. +/**
  47914. + * bfq_activate_entity - activate an entity and its ancestors if necessary.
  47915. + * @entity: the entity to activate.
  47916. + *
  47917. + * Activate @entity and all the entities on the path from it to the root.
  47918. + */
  47919. +static void bfq_activate_entity(struct bfq_entity *entity)
  47920. +{
  47921. + struct bfq_sched_data *sd;
  47922. +
  47923. + for_each_entity(entity) {
  47924. + __bfq_activate_entity(entity);
  47925. +
  47926. + sd = entity->sched_data;
  47927. + if (!bfq_update_next_in_service(sd))
  47928. + /*
  47929. + * No need to propagate the activation to the
  47930. + * upper entities, as they will be updated when
  47931. + * the in-service entity is rescheduled.
  47932. + */
  47933. + break;
  47934. + }
  47935. +}
  47936. +
  47937. +/**
  47938. + * __bfq_deactivate_entity - deactivate an entity from its service tree.
  47939. + * @entity: the entity to deactivate.
  47940. + * @requeue: if false, the entity will not be put into the idle tree.
  47941. + *
  47942. + * Deactivate an entity, independently from its previous state. If the
  47943. + * entity was not on a service tree just return, otherwise if it is on
  47944. + * any scheduler tree, extract it from that tree, and if necessary
  47945. + * and if the caller did not specify @requeue, put it on the idle tree.
  47946. + *
  47947. + * Return %1 if the caller should update the entity hierarchy, i.e.,
  47948. + * if the entity was in service or if it was the next_in_service for
  47949. + * its sched_data; return %0 otherwise.
  47950. + */
  47951. +static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
  47952. +{
  47953. + struct bfq_sched_data *sd = entity->sched_data;
  47954. + struct bfq_service_tree *st = bfq_entity_service_tree(entity);
  47955. + int was_in_service = entity == sd->in_service_entity;
  47956. + int ret = 0;
  47957. +
  47958. + if (!entity->on_st)
  47959. + return 0;
  47960. +
  47961. + BUG_ON(was_in_service && entity->tree != NULL);
  47962. +
  47963. + if (was_in_service) {
  47964. + bfq_calc_finish(entity, entity->service);
  47965. + sd->in_service_entity = NULL;
  47966. + } else if (entity->tree == &st->active)
  47967. + bfq_active_extract(st, entity);
  47968. + else if (entity->tree == &st->idle)
  47969. + bfq_idle_extract(st, entity);
  47970. + else if (entity->tree != NULL)
  47971. + BUG();
  47972. +
  47973. + if (was_in_service || sd->next_in_service == entity)
  47974. + ret = bfq_update_next_in_service(sd);
  47975. +
  47976. + if (!requeue || !bfq_gt(entity->finish, st->vtime))
  47977. + bfq_forget_entity(st, entity);
  47978. + else
  47979. + bfq_idle_insert(st, entity);
  47980. +
  47981. + BUG_ON(sd->in_service_entity == entity);
  47982. + BUG_ON(sd->next_in_service == entity);
  47983. +
  47984. + return ret;
  47985. +}
  47986. +
  47987. +/**
  47988. + * bfq_deactivate_entity - deactivate an entity.
  47989. + * @entity: the entity to deactivate.
  47990. + * @requeue: true if the entity can be put on the idle tree
  47991. + */
  47992. +static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
  47993. +{
  47994. + struct bfq_sched_data *sd;
  47995. + struct bfq_entity *parent;
  47996. +
  47997. + for_each_entity_safe(entity, parent) {
  47998. + sd = entity->sched_data;
  47999. +
  48000. + if (!__bfq_deactivate_entity(entity, requeue))
  48001. + /*
  48002. + * The parent entity is still backlogged, and
  48003. + * we don't need to update it as it is still
  48004. + * in service.
  48005. + */
  48006. + break;
  48007. +
  48008. + if (sd->next_in_service != NULL)
  48009. + /*
  48010. + * The parent entity is still backlogged and
  48011. + * the budgets on the path towards the root
  48012. + * need to be updated.
  48013. + */
  48014. + goto update;
  48015. +
  48016. + /*
  48017. + * If we reach there the parent is no more backlogged and
  48018. + * we want to propagate the dequeue upwards.
  48019. + */
  48020. + requeue = 1;
  48021. + }
  48022. +
  48023. + return;
  48024. +
  48025. +update:
  48026. + entity = parent;
  48027. + for_each_entity(entity) {
  48028. + __bfq_activate_entity(entity);
  48029. +
  48030. + sd = entity->sched_data;
  48031. + if (!bfq_update_next_in_service(sd))
  48032. + break;
  48033. + }
  48034. +}
  48035. +
  48036. +/**
  48037. + * bfq_update_vtime - update vtime if necessary.
  48038. + * @st: the service tree to act upon.
  48039. + *
  48040. + * If necessary update the service tree vtime to have at least one
  48041. + * eligible entity, skipping to its start time. Assumes that the
  48042. + * active tree of the device is not empty.
  48043. + *
  48044. + * NOTE: this hierarchical implementation updates vtimes quite often,
  48045. + * we may end up with reactivated processes getting timestamps after a
  48046. + * vtime skip done because we needed a ->first_active entity on some
  48047. + * intermediate node.
  48048. + */
  48049. +static void bfq_update_vtime(struct bfq_service_tree *st)
  48050. +{
  48051. + struct bfq_entity *entry;
  48052. + struct rb_node *node = st->active.rb_node;
  48053. +
  48054. + entry = rb_entry(node, struct bfq_entity, rb_node);
  48055. + if (bfq_gt(entry->min_start, st->vtime)) {
  48056. + st->vtime = entry->min_start;
  48057. + bfq_forget_idle(st);
  48058. + }
  48059. +}
  48060. +
  48061. +/**
  48062. + * bfq_first_active_entity - find the eligible entity with
  48063. + * the smallest finish time
  48064. + * @st: the service tree to select from.
  48065. + *
  48066. + * This function searches the first schedulable entity, starting from the
  48067. + * root of the tree and going on the left every time on this side there is
  48068. + * a subtree with at least one eligible (start >= vtime) entity. The path on
  48069. + * the right is followed only if a) the left subtree contains no eligible
  48070. + * entities and b) no eligible entity has been found yet.
  48071. + */
  48072. +static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
  48073. +{
  48074. + struct bfq_entity *entry, *first = NULL;
  48075. + struct rb_node *node = st->active.rb_node;
  48076. +
  48077. + while (node != NULL) {
  48078. + entry = rb_entry(node, struct bfq_entity, rb_node);
  48079. +left:
  48080. + if (!bfq_gt(entry->start, st->vtime))
  48081. + first = entry;
  48082. +
  48083. + BUG_ON(bfq_gt(entry->min_start, st->vtime));
  48084. +
  48085. + if (node->rb_left != NULL) {
  48086. + entry = rb_entry(node->rb_left,
  48087. + struct bfq_entity, rb_node);
  48088. + if (!bfq_gt(entry->min_start, st->vtime)) {
  48089. + node = node->rb_left;
  48090. + goto left;
  48091. + }
  48092. + }
  48093. + if (first != NULL)
  48094. + break;
  48095. + node = node->rb_right;
  48096. + }
  48097. +
  48098. + BUG_ON(first == NULL && !RB_EMPTY_ROOT(&st->active));
  48099. + return first;
  48100. +}
  48101. +
  48102. +/**
  48103. + * __bfq_lookup_next_entity - return the first eligible entity in @st.
  48104. + * @st: the service tree.
  48105. + *
  48106. + * Update the virtual time in @st and return the first eligible entity
  48107. + * it contains.
  48108. + */
  48109. +static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
  48110. + bool force)
  48111. +{
  48112. + struct bfq_entity *entity, *new_next_in_service = NULL;
  48113. +
  48114. + if (RB_EMPTY_ROOT(&st->active))
  48115. + return NULL;
  48116. +
  48117. + bfq_update_vtime(st);
  48118. + entity = bfq_first_active_entity(st);
  48119. + BUG_ON(bfq_gt(entity->start, st->vtime));
  48120. +
  48121. + /*
  48122. + * If the chosen entity does not match with the sched_data's
  48123. + * next_in_service and we are forcedly serving the IDLE priority
  48124. + * class tree, bubble up budget update.
  48125. + */
  48126. + if (unlikely(force && entity != entity->sched_data->next_in_service)) {
  48127. + new_next_in_service = entity;
  48128. + for_each_entity(new_next_in_service)
  48129. + bfq_update_budget(new_next_in_service);
  48130. + }
  48131. +
  48132. + return entity;
  48133. +}
  48134. +
  48135. +/**
  48136. + * bfq_lookup_next_entity - return the first eligible entity in @sd.
  48137. + * @sd: the sched_data.
  48138. + * @extract: if true the returned entity will be also extracted from @sd.
  48139. + *
  48140. + * NOTE: since we cache the next_in_service entity at each level of the
  48141. + * hierarchy, the complexity of the lookup can be decreased with
  48142. + * absolutely no effort just returning the cached next_in_service value;
  48143. + * we prefer to do full lookups to test the consistency of * the data
  48144. + * structures.
  48145. + */
  48146. +static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
  48147. + int extract,
  48148. + struct bfq_data *bfqd)
  48149. +{
  48150. + struct bfq_service_tree *st = sd->service_tree;
  48151. + struct bfq_entity *entity;
  48152. + int i = 0;
  48153. +
  48154. + BUG_ON(sd->in_service_entity != NULL);
  48155. +
  48156. + if (bfqd != NULL &&
  48157. + jiffies - bfqd->bfq_class_idle_last_service > BFQ_CL_IDLE_TIMEOUT) {
  48158. + entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1,
  48159. + true);
  48160. + if (entity != NULL) {
  48161. + i = BFQ_IOPRIO_CLASSES - 1;
  48162. + bfqd->bfq_class_idle_last_service = jiffies;
  48163. + sd->next_in_service = entity;
  48164. + }
  48165. + }
  48166. + for (; i < BFQ_IOPRIO_CLASSES; i++) {
  48167. + entity = __bfq_lookup_next_entity(st + i, false);
  48168. + if (entity != NULL) {
  48169. + if (extract) {
  48170. + bfq_check_next_in_service(sd, entity);
  48171. + bfq_active_extract(st + i, entity);
  48172. + sd->in_service_entity = entity;
  48173. + sd->next_in_service = NULL;
  48174. + }
  48175. + break;
  48176. + }
  48177. + }
  48178. +
  48179. + return entity;
  48180. +}
  48181. +
  48182. +/*
  48183. + * Get next queue for service.
  48184. + */
  48185. +static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
  48186. +{
  48187. + struct bfq_entity *entity = NULL;
  48188. + struct bfq_sched_data *sd;
  48189. + struct bfq_queue *bfqq;
  48190. +
  48191. + BUG_ON(bfqd->in_service_queue != NULL);
  48192. +
  48193. + if (bfqd->busy_queues == 0)
  48194. + return NULL;
  48195. +
  48196. + sd = &bfqd->root_group->sched_data;
  48197. + for (; sd != NULL; sd = entity->my_sched_data) {
  48198. + entity = bfq_lookup_next_entity(sd, 1, bfqd);
  48199. + BUG_ON(entity == NULL);
  48200. + entity->service = 0;
  48201. + }
  48202. +
  48203. + bfqq = bfq_entity_to_bfqq(entity);
  48204. + BUG_ON(bfqq == NULL);
  48205. +
  48206. + return bfqq;
  48207. +}
  48208. +
  48209. +static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
  48210. +{
  48211. + if (bfqd->in_service_bic != NULL) {
  48212. + put_io_context(bfqd->in_service_bic->icq.ioc);
  48213. + bfqd->in_service_bic = NULL;
  48214. + }
  48215. +
  48216. + bfqd->in_service_queue = NULL;
  48217. + del_timer(&bfqd->idle_slice_timer);
  48218. +}
  48219. +
  48220. +static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  48221. + int requeue)
  48222. +{
  48223. + struct bfq_entity *entity = &bfqq->entity;
  48224. +
  48225. + if (bfqq == bfqd->in_service_queue)
  48226. + __bfq_bfqd_reset_in_service(bfqd);
  48227. +
  48228. + bfq_deactivate_entity(entity, requeue);
  48229. +}
  48230. +
  48231. +static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  48232. +{
  48233. + struct bfq_entity *entity = &bfqq->entity;
  48234. +
  48235. + bfq_activate_entity(entity);
  48236. +}
  48237. +
  48238. +/*
  48239. + * Called when the bfqq no longer has requests pending, remove it from
  48240. + * the service tree.
  48241. + */
  48242. +static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  48243. + int requeue)
  48244. +{
  48245. + BUG_ON(!bfq_bfqq_busy(bfqq));
  48246. + BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
  48247. +
  48248. + bfq_log_bfqq(bfqd, bfqq, "del from busy");
  48249. +
  48250. + bfq_clear_bfqq_busy(bfqq);
  48251. +
  48252. + BUG_ON(bfqd->busy_queues == 0);
  48253. + bfqd->busy_queues--;
  48254. +
  48255. + if (!bfqq->dispatched) {
  48256. + bfq_weights_tree_remove(bfqd, &bfqq->entity,
  48257. + &bfqd->queue_weights_tree);
  48258. + if (!blk_queue_nonrot(bfqd->queue)) {
  48259. + BUG_ON(!bfqd->busy_in_flight_queues);
  48260. + bfqd->busy_in_flight_queues--;
  48261. + if (bfq_bfqq_constantly_seeky(bfqq)) {
  48262. + BUG_ON(!bfqd->
  48263. + const_seeky_busy_in_flight_queues);
  48264. + bfqd->const_seeky_busy_in_flight_queues--;
  48265. + }
  48266. + }
  48267. + }
  48268. + if (bfqq->wr_coeff > 1)
  48269. + bfqd->wr_busy_queues--;
  48270. +
  48271. + bfq_deactivate_bfqq(bfqd, bfqq, requeue);
  48272. +}
  48273. +
  48274. +/*
  48275. + * Called when an inactive queue receives a new request.
  48276. + */
  48277. +static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  48278. +{
  48279. + BUG_ON(bfq_bfqq_busy(bfqq));
  48280. + BUG_ON(bfqq == bfqd->in_service_queue);
  48281. +
  48282. + bfq_log_bfqq(bfqd, bfqq, "add to busy");
  48283. +
  48284. + bfq_activate_bfqq(bfqd, bfqq);
  48285. +
  48286. + bfq_mark_bfqq_busy(bfqq);
  48287. + bfqd->busy_queues++;
  48288. +
  48289. + if (!bfqq->dispatched) {
  48290. + if (bfqq->wr_coeff == 1)
  48291. + bfq_weights_tree_add(bfqd, &bfqq->entity,
  48292. + &bfqd->queue_weights_tree);
  48293. + if (!blk_queue_nonrot(bfqd->queue)) {
  48294. + bfqd->busy_in_flight_queues++;
  48295. + if (bfq_bfqq_constantly_seeky(bfqq))
  48296. + bfqd->const_seeky_busy_in_flight_queues++;
  48297. + }
  48298. + }
  48299. + if (bfqq->wr_coeff > 1)
  48300. + bfqd->wr_busy_queues++;
  48301. +}
  48302. diff -Nur linux-3.14.15/block/blk-cgroup.c linux-linaro-stable-mx6/block/blk-cgroup.c
  48303. --- linux-3.14.15/block/blk-cgroup.c 2014-07-31 23:51:43.000000000 +0200
  48304. +++ linux-linaro-stable-mx6/block/blk-cgroup.c 2014-08-20 19:31:42.192852109 +0200
  48305. @@ -859,13 +859,6 @@
  48306. {
  48307. lockdep_assert_held(q->queue_lock);
  48308. - /*
  48309. - * @q could be exiting and already have destroyed all blkgs as
  48310. - * indicated by NULL root_blkg. If so, don't confuse policies.
  48311. - */
  48312. - if (!q->root_blkg)
  48313. - return;
  48314. -
  48315. blk_throtl_drain(q);
  48316. }
  48317. diff -Nur linux-3.14.15/block/blk-core.c linux-linaro-stable-mx6/block/blk-core.c
  48318. --- linux-3.14.15/block/blk-core.c 2014-07-31 23:51:43.000000000 +0200
  48319. +++ linux-linaro-stable-mx6/block/blk-core.c 2014-08-20 19:31:42.192852109 +0200
  48320. @@ -1928,7 +1928,7 @@
  48321. * in some cases below, so export this function.
  48322. * Request stacking drivers like request-based dm may change the queue
  48323. * limits while requests are in the queue (e.g. dm's table swapping).
  48324. - * Such request stacking drivers should check those requests agaist
  48325. + * Such request stacking drivers should check those requests against
  48326. * the new queue limits again when they dispatch those requests,
  48327. * although such checkings are also done against the old queue limits
  48328. * when submitting requests.
  48329. diff -Nur linux-3.14.15/block/blk-map.c linux-linaro-stable-mx6/block/blk-map.c
  48330. --- linux-3.14.15/block/blk-map.c 2014-07-31 23:51:43.000000000 +0200
  48331. +++ linux-linaro-stable-mx6/block/blk-map.c 2014-08-20 19:31:42.196852127 +0200
  48332. @@ -285,7 +285,7 @@
  48333. *
  48334. * Description:
  48335. * Data will be mapped directly if possible. Otherwise a bounce
  48336. - * buffer is used. Can be called multple times to append multple
  48337. + * buffer is used. Can be called multiple times to append multiple
  48338. * buffers.
  48339. */
  48340. int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
  48341. diff -Nur linux-3.14.15/block/blk-tag.c linux-linaro-stable-mx6/block/blk-tag.c
  48342. --- linux-3.14.15/block/blk-tag.c 2014-07-31 23:51:43.000000000 +0200
  48343. +++ linux-linaro-stable-mx6/block/blk-tag.c 2014-08-20 19:31:42.200852145 +0200
  48344. @@ -27,15 +27,18 @@
  48345. EXPORT_SYMBOL(blk_queue_find_tag);
  48346. /**
  48347. - * blk_free_tags - release a given set of tag maintenance info
  48348. + * __blk_free_tags - release a given set of tag maintenance info
  48349. * @bqt: the tag map to free
  48350. *
  48351. - * Drop the reference count on @bqt and frees it when the last reference
  48352. - * is dropped.
  48353. + * Tries to free the specified @bqt. Returns true if it was
  48354. + * actually freed and false if there are still references using it
  48355. */
  48356. -void blk_free_tags(struct blk_queue_tag *bqt)
  48357. +static int __blk_free_tags(struct blk_queue_tag *bqt)
  48358. {
  48359. - if (atomic_dec_and_test(&bqt->refcnt)) {
  48360. + int retval;
  48361. +
  48362. + retval = atomic_dec_and_test(&bqt->refcnt);
  48363. + if (retval) {
  48364. BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
  48365. bqt->max_depth);
  48366. @@ -47,8 +50,9 @@
  48367. kfree(bqt);
  48368. }
  48369. +
  48370. + return retval;
  48371. }
  48372. -EXPORT_SYMBOL(blk_free_tags);
  48373. /**
  48374. * __blk_queue_free_tags - release tag maintenance info
  48375. @@ -65,13 +69,28 @@
  48376. if (!bqt)
  48377. return;
  48378. - blk_free_tags(bqt);
  48379. + __blk_free_tags(bqt);
  48380. q->queue_tags = NULL;
  48381. queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q);
  48382. }
  48383. /**
  48384. + * blk_free_tags - release a given set of tag maintenance info
  48385. + * @bqt: the tag map to free
  48386. + *
  48387. + * For externally managed @bqt frees the map. Callers of this
  48388. + * function must guarantee to have released all the queues that
  48389. + * might have been using this tag map.
  48390. + */
  48391. +void blk_free_tags(struct blk_queue_tag *bqt)
  48392. +{
  48393. + if (unlikely(!__blk_free_tags(bqt)))
  48394. + BUG();
  48395. +}
  48396. +EXPORT_SYMBOL(blk_free_tags);
  48397. +
  48398. +/**
  48399. * blk_queue_free_tags - release tag maintenance info
  48400. * @q: the request queue for the device
  48401. *
  48402. diff -Nur linux-3.14.15/block/compat_ioctl.c linux-linaro-stable-mx6/block/compat_ioctl.c
  48403. --- linux-3.14.15/block/compat_ioctl.c 2014-07-31 23:51:43.000000000 +0200
  48404. +++ linux-linaro-stable-mx6/block/compat_ioctl.c 2014-08-20 19:31:42.204852163 +0200
  48405. @@ -690,7 +690,6 @@
  48406. case BLKROSET:
  48407. case BLKDISCARD:
  48408. case BLKSECDISCARD:
  48409. - case BLKZEROOUT:
  48410. /*
  48411. * the ones below are implemented in blkdev_locked_ioctl,
  48412. * but we call blkdev_ioctl, which gets the lock for us
  48413. diff -Nur linux-3.14.15/block/Kconfig.iosched linux-linaro-stable-mx6/block/Kconfig.iosched
  48414. --- linux-3.14.15/block/Kconfig.iosched 2014-07-31 23:51:43.000000000 +0200
  48415. +++ linux-linaro-stable-mx6/block/Kconfig.iosched 2014-08-20 19:31:42.188852092 +0200
  48416. @@ -39,6 +39,27 @@
  48417. ---help---
  48418. Enable group IO scheduling in CFQ.
  48419. +config IOSCHED_BFQ
  48420. + tristate "BFQ I/O scheduler"
  48421. + default n
  48422. + ---help---
  48423. + The BFQ I/O scheduler tries to distribute bandwidth among
  48424. + all processes according to their weights.
  48425. + It aims at distributing the bandwidth as desired, independently of
  48426. + the disk parameters and with any workload. It also tries to
  48427. + guarantee low latency to interactive and soft real-time
  48428. + applications. If compiled built-in (saying Y here), BFQ can
  48429. + be configured to support hierarchical scheduling.
  48430. +
  48431. +config CGROUP_BFQIO
  48432. + bool "BFQ hierarchical scheduling support"
  48433. + depends on CGROUPS && IOSCHED_BFQ=y
  48434. + default n
  48435. + ---help---
  48436. + Enable hierarchical scheduling in BFQ, using the cgroups
  48437. + filesystem interface. The name of the subsystem will be
  48438. + bfqio.
  48439. +
  48440. choice
  48441. prompt "Default I/O scheduler"
  48442. default DEFAULT_CFQ
  48443. @@ -52,6 +73,16 @@
  48444. config DEFAULT_CFQ
  48445. bool "CFQ" if IOSCHED_CFQ=y
  48446. + config DEFAULT_BFQ
  48447. + bool "BFQ" if IOSCHED_BFQ=y
  48448. + help
  48449. + Selects BFQ as the default I/O scheduler which will be
  48450. + used by default for all block devices.
  48451. + The BFQ I/O scheduler aims at distributing the bandwidth
  48452. + as desired, independently of the disk parameters and with
  48453. + any workload. It also tries to guarantee low latency to
  48454. + interactive and soft real-time applications.
  48455. +
  48456. config DEFAULT_NOOP
  48457. bool "No-op"
  48458. @@ -61,6 +92,7 @@
  48459. string
  48460. default "deadline" if DEFAULT_DEADLINE
  48461. default "cfq" if DEFAULT_CFQ
  48462. + default "bfq" if DEFAULT_BFQ
  48463. default "noop" if DEFAULT_NOOP
  48464. endmenu
  48465. diff -Nur linux-3.14.15/block/Makefile linux-linaro-stable-mx6/block/Makefile
  48466. --- linux-3.14.15/block/Makefile 2014-07-31 23:51:43.000000000 +0200
  48467. +++ linux-linaro-stable-mx6/block/Makefile 2014-08-20 19:31:42.188852092 +0200
  48468. @@ -16,6 +16,7 @@
  48469. obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
  48470. obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
  48471. obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
  48472. +obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o
  48473. obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
  48474. obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o
  48475. diff -Nur linux-3.14.15/crypto/blkcipher.c linux-linaro-stable-mx6/crypto/blkcipher.c
  48476. --- linux-3.14.15/crypto/blkcipher.c 2014-07-31 23:51:43.000000000 +0200
  48477. +++ linux-linaro-stable-mx6/crypto/blkcipher.c 2014-08-20 19:31:42.212852195 +0200
  48478. @@ -70,14 +70,12 @@
  48479. return max(start, end_page);
  48480. }
  48481. -static inline unsigned int blkcipher_done_slow(struct crypto_blkcipher *tfm,
  48482. - struct blkcipher_walk *walk,
  48483. +static inline unsigned int blkcipher_done_slow(struct blkcipher_walk *walk,
  48484. unsigned int bsize)
  48485. {
  48486. u8 *addr;
  48487. - unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
  48488. - addr = (u8 *)ALIGN((unsigned long)walk->buffer, alignmask + 1);
  48489. + addr = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
  48490. addr = blkcipher_get_spot(addr, bsize);
  48491. scatterwalk_copychunks(addr, &walk->out, bsize, 1);
  48492. return bsize;
  48493. @@ -105,7 +103,6 @@
  48494. int blkcipher_walk_done(struct blkcipher_desc *desc,
  48495. struct blkcipher_walk *walk, int err)
  48496. {
  48497. - struct crypto_blkcipher *tfm = desc->tfm;
  48498. unsigned int nbytes = 0;
  48499. if (likely(err >= 0)) {
  48500. @@ -117,7 +114,7 @@
  48501. err = -EINVAL;
  48502. goto err;
  48503. } else
  48504. - n = blkcipher_done_slow(tfm, walk, n);
  48505. + n = blkcipher_done_slow(walk, n);
  48506. nbytes = walk->total - n;
  48507. err = 0;
  48508. @@ -136,7 +133,7 @@
  48509. }
  48510. if (walk->iv != desc->info)
  48511. - memcpy(desc->info, walk->iv, crypto_blkcipher_ivsize(tfm));
  48512. + memcpy(desc->info, walk->iv, walk->ivsize);
  48513. if (walk->buffer != walk->page)
  48514. kfree(walk->buffer);
  48515. if (walk->page)
  48516. @@ -226,22 +223,20 @@
  48517. static int blkcipher_walk_next(struct blkcipher_desc *desc,
  48518. struct blkcipher_walk *walk)
  48519. {
  48520. - struct crypto_blkcipher *tfm = desc->tfm;
  48521. - unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
  48522. unsigned int bsize;
  48523. unsigned int n;
  48524. int err;
  48525. n = walk->total;
  48526. - if (unlikely(n < crypto_blkcipher_blocksize(tfm))) {
  48527. + if (unlikely(n < walk->cipher_blocksize)) {
  48528. desc->flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
  48529. return blkcipher_walk_done(desc, walk, -EINVAL);
  48530. }
  48531. walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY |
  48532. BLKCIPHER_WALK_DIFF);
  48533. - if (!scatterwalk_aligned(&walk->in, alignmask) ||
  48534. - !scatterwalk_aligned(&walk->out, alignmask)) {
  48535. + if (!scatterwalk_aligned(&walk->in, walk->alignmask) ||
  48536. + !scatterwalk_aligned(&walk->out, walk->alignmask)) {
  48537. walk->flags |= BLKCIPHER_WALK_COPY;
  48538. if (!walk->page) {
  48539. walk->page = (void *)__get_free_page(GFP_ATOMIC);
  48540. @@ -250,12 +245,12 @@
  48541. }
  48542. }
  48543. - bsize = min(walk->blocksize, n);
  48544. + bsize = min(walk->walk_blocksize, n);
  48545. n = scatterwalk_clamp(&walk->in, n);
  48546. n = scatterwalk_clamp(&walk->out, n);
  48547. if (unlikely(n < bsize)) {
  48548. - err = blkcipher_next_slow(desc, walk, bsize, alignmask);
  48549. + err = blkcipher_next_slow(desc, walk, bsize, walk->alignmask);
  48550. goto set_phys_lowmem;
  48551. }
  48552. @@ -277,28 +272,26 @@
  48553. return err;
  48554. }
  48555. -static inline int blkcipher_copy_iv(struct blkcipher_walk *walk,
  48556. - struct crypto_blkcipher *tfm,
  48557. - unsigned int alignmask)
  48558. -{
  48559. - unsigned bs = walk->blocksize;
  48560. - unsigned int ivsize = crypto_blkcipher_ivsize(tfm);
  48561. - unsigned aligned_bs = ALIGN(bs, alignmask + 1);
  48562. - unsigned int size = aligned_bs * 2 + ivsize + max(aligned_bs, ivsize) -
  48563. - (alignmask + 1);
  48564. +static inline int blkcipher_copy_iv(struct blkcipher_walk *walk)
  48565. +{
  48566. + unsigned bs = walk->walk_blocksize;
  48567. + unsigned aligned_bs = ALIGN(bs, walk->alignmask + 1);
  48568. + unsigned int size = aligned_bs * 2 +
  48569. + walk->ivsize + max(aligned_bs, walk->ivsize) -
  48570. + (walk->alignmask + 1);
  48571. u8 *iv;
  48572. - size += alignmask & ~(crypto_tfm_ctx_alignment() - 1);
  48573. + size += walk->alignmask & ~(crypto_tfm_ctx_alignment() - 1);
  48574. walk->buffer = kmalloc(size, GFP_ATOMIC);
  48575. if (!walk->buffer)
  48576. return -ENOMEM;
  48577. - iv = (u8 *)ALIGN((unsigned long)walk->buffer, alignmask + 1);
  48578. + iv = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
  48579. iv = blkcipher_get_spot(iv, bs) + aligned_bs;
  48580. iv = blkcipher_get_spot(iv, bs) + aligned_bs;
  48581. - iv = blkcipher_get_spot(iv, ivsize);
  48582. + iv = blkcipher_get_spot(iv, walk->ivsize);
  48583. - walk->iv = memcpy(iv, walk->iv, ivsize);
  48584. + walk->iv = memcpy(iv, walk->iv, walk->ivsize);
  48585. return 0;
  48586. }
  48587. @@ -306,7 +299,10 @@
  48588. struct blkcipher_walk *walk)
  48589. {
  48590. walk->flags &= ~BLKCIPHER_WALK_PHYS;
  48591. - walk->blocksize = crypto_blkcipher_blocksize(desc->tfm);
  48592. + walk->walk_blocksize = crypto_blkcipher_blocksize(desc->tfm);
  48593. + walk->cipher_blocksize = walk->walk_blocksize;
  48594. + walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
  48595. + walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
  48596. return blkcipher_walk_first(desc, walk);
  48597. }
  48598. EXPORT_SYMBOL_GPL(blkcipher_walk_virt);
  48599. @@ -315,7 +311,10 @@
  48600. struct blkcipher_walk *walk)
  48601. {
  48602. walk->flags |= BLKCIPHER_WALK_PHYS;
  48603. - walk->blocksize = crypto_blkcipher_blocksize(desc->tfm);
  48604. + walk->walk_blocksize = crypto_blkcipher_blocksize(desc->tfm);
  48605. + walk->cipher_blocksize = walk->walk_blocksize;
  48606. + walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
  48607. + walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
  48608. return blkcipher_walk_first(desc, walk);
  48609. }
  48610. EXPORT_SYMBOL_GPL(blkcipher_walk_phys);
  48611. @@ -323,9 +322,6 @@
  48612. static int blkcipher_walk_first(struct blkcipher_desc *desc,
  48613. struct blkcipher_walk *walk)
  48614. {
  48615. - struct crypto_blkcipher *tfm = desc->tfm;
  48616. - unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
  48617. -
  48618. if (WARN_ON_ONCE(in_irq()))
  48619. return -EDEADLK;
  48620. @@ -335,8 +331,8 @@
  48621. walk->buffer = NULL;
  48622. walk->iv = desc->info;
  48623. - if (unlikely(((unsigned long)walk->iv & alignmask))) {
  48624. - int err = blkcipher_copy_iv(walk, tfm, alignmask);
  48625. + if (unlikely(((unsigned long)walk->iv & walk->alignmask))) {
  48626. + int err = blkcipher_copy_iv(walk);
  48627. if (err)
  48628. return err;
  48629. }
  48630. @@ -353,11 +349,28 @@
  48631. unsigned int blocksize)
  48632. {
  48633. walk->flags &= ~BLKCIPHER_WALK_PHYS;
  48634. - walk->blocksize = blocksize;
  48635. + walk->walk_blocksize = blocksize;
  48636. + walk->cipher_blocksize = crypto_blkcipher_blocksize(desc->tfm);
  48637. + walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
  48638. + walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
  48639. return blkcipher_walk_first(desc, walk);
  48640. }
  48641. EXPORT_SYMBOL_GPL(blkcipher_walk_virt_block);
  48642. +int blkcipher_aead_walk_virt_block(struct blkcipher_desc *desc,
  48643. + struct blkcipher_walk *walk,
  48644. + struct crypto_aead *tfm,
  48645. + unsigned int blocksize)
  48646. +{
  48647. + walk->flags &= ~BLKCIPHER_WALK_PHYS;
  48648. + walk->walk_blocksize = blocksize;
  48649. + walk->cipher_blocksize = crypto_aead_blocksize(tfm);
  48650. + walk->ivsize = crypto_aead_ivsize(tfm);
  48651. + walk->alignmask = crypto_aead_alignmask(tfm);
  48652. + return blkcipher_walk_first(desc, walk);
  48653. +}
  48654. +EXPORT_SYMBOL_GPL(blkcipher_aead_walk_virt_block);
  48655. +
  48656. static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key,
  48657. unsigned int keylen)
  48658. {
  48659. diff -Nur linux-3.14.15/crypto/tcrypt.c linux-linaro-stable-mx6/crypto/tcrypt.c
  48660. --- linux-3.14.15/crypto/tcrypt.c 2014-07-31 23:51:43.000000000 +0200
  48661. +++ linux-linaro-stable-mx6/crypto/tcrypt.c 2014-08-20 19:31:42.216852212 +0200
  48662. @@ -33,6 +33,7 @@
  48663. #include <linux/jiffies.h>
  48664. #include <linux/timex.h>
  48665. #include <linux/interrupt.h>
  48666. +#include <linux/sched.h>
  48667. #include "tcrypt.h"
  48668. #include "internal.h"
  48669. @@ -447,6 +448,7 @@
  48670. goto out;
  48671. }
  48672. + schedule();
  48673. printk("test %u (%d bit key, %d byte blocks): ", i,
  48674. *keysize * 8, *b_size);
  48675. @@ -713,6 +715,7 @@
  48676. if (speed[i].klen)
  48677. crypto_hash_setkey(tfm, tvmem[0], speed[i].klen);
  48678. + schedule();
  48679. printk(KERN_INFO "test%3u "
  48680. "(%5u byte blocks,%5u bytes per update,%4u updates): ",
  48681. i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
  48682. @@ -953,6 +956,7 @@
  48683. break;
  48684. }
  48685. + schedule();
  48686. pr_info("test%3u "
  48687. "(%5u byte blocks,%5u bytes per update,%4u updates): ",
  48688. i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
  48689. @@ -1118,6 +1122,7 @@
  48690. goto out_free_req;
  48691. }
  48692. + schedule();
  48693. pr_info("test %u (%d bit key, %d byte blocks): ", i,
  48694. *keysize * 8, *b_size);
  48695. @@ -1199,6 +1204,7 @@
  48696. printk("alg %s ", *name);
  48697. printk(crypto_has_alg(*name, 0, 0) ?
  48698. "found\n" : "not found\n");
  48699. + schedule();
  48700. name++;
  48701. }
  48702. }
  48703. diff -Nur linux-3.14.15/Documentation/ABI/testing/sysfs-class-net-statistics linux-linaro-stable-mx6/Documentation/ABI/testing/sysfs-class-net-statistics
  48704. --- linux-3.14.15/Documentation/ABI/testing/sysfs-class-net-statistics 1970-01-01 01:00:00.000000000 +0100
  48705. +++ linux-linaro-stable-mx6/Documentation/ABI/testing/sysfs-class-net-statistics 2014-08-20 19:31:39.048838615 +0200
  48706. @@ -0,0 +1,201 @@
  48707. +What: /sys/class/<iface>/statistics/collisions
  48708. +Date: April 2005
  48709. +KernelVersion: 2.6.12
  48710. +Contact: netdev@vger.kernel.org
  48711. +Description:
  48712. + Indicates the number of collisions seen by this network device.
  48713. + This value might not be relevant with all MAC layers.
  48714. +
  48715. +What: /sys/class/<iface>/statistics/multicast
  48716. +Date: April 2005
  48717. +KernelVersion: 2.6.12
  48718. +Contact: netdev@vger.kernel.org
  48719. +Description:
  48720. + Indicates the number of multicast packets received by this
  48721. + network device.
  48722. +
  48723. +What: /sys/class/<iface>/statistics/rx_bytes
  48724. +Date: April 2005
  48725. +KernelVersion: 2.6.12
  48726. +Contact: netdev@vger.kernel.org
  48727. +Description:
  48728. + Indicates the number of bytes received by this network device.
  48729. + See the network driver for the exact meaning of when this
  48730. + value is incremented.
  48731. +
  48732. +What: /sys/class/<iface>/statistics/rx_compressed
  48733. +Date: April 2005
  48734. +KernelVersion: 2.6.12
  48735. +Contact: netdev@vger.kernel.org
  48736. +Description:
  48737. + Indicates the number of compressed packets received by this
  48738. + network device. This value might only be relevant for interfaces
  48739. + that support packet compression (e.g: PPP).
  48740. +
  48741. +What: /sys/class/<iface>/statistics/rx_crc_errors
  48742. +Date: April 2005
  48743. +KernelVersion: 2.6.12
  48744. +Contact: netdev@vger.kernel.org
  48745. +Description:
  48746. + Indicates the number of packets received with a CRC (FCS) error
  48747. + by this network device. Note that the specific meaning might
  48748. + depend on the MAC layer used by the interface.
  48749. +
  48750. +What: /sys/class/<iface>/statistics/rx_dropped
  48751. +Date: April 2005
  48752. +KernelVersion: 2.6.12
  48753. +Contact: netdev@vger.kernel.org
  48754. +Description:
  48755. + Indicates the number of packets received by the network device
  48756. + but dropped, that are not forwarded to the upper layers for
  48757. + packet processing. See the network driver for the exact
  48758. + meaning of this value.
  48759. +
  48760. +What: /sys/class/<iface>/statistics/rx_fifo_errors
  48761. +Date: April 2005
  48762. +KernelVersion: 2.6.12
  48763. +Contact: netdev@vger.kernel.org
  48764. +Description:
  48765. + Indicates the number of receive FIFO errors seen by this
  48766. + network device. See the network driver for the exact
  48767. + meaning of this value.
  48768. +
  48769. +What: /sys/class/<iface>/statistics/rx_frame_errors
  48770. +Date: April 2005
  48771. +KernelVersion: 2.6.12
  48772. +Contact: netdev@vger.kernel.org
  48773. +Description:
  48774. + Indicates the number of received frames with error, such as
  48775. + alignment errors. Note that the specific meaning depends on
  48776. + on the MAC layer protocol used. See the network driver for
  48777. + the exact meaning of this value.
  48778. +
  48779. +What: /sys/class/<iface>/statistics/rx_length_errors
  48780. +Date: April 2005
  48781. +KernelVersion: 2.6.12
  48782. +Contact: netdev@vger.kernel.org
  48783. +Description:
  48784. + Indicates the number of received error packet with a length
  48785. + error, oversized or undersized. See the network driver for the
  48786. + exact meaning of this value.
  48787. +
  48788. +What: /sys/class/<iface>/statistics/rx_missed_errors
  48789. +Date: April 2005
  48790. +KernelVersion: 2.6.12
  48791. +Contact: netdev@vger.kernel.org
  48792. +Description:
  48793. + Indicates the number of received packets that have been missed
  48794. + due to lack of capacity in the receive side. See the network
  48795. + driver for the exact meaning of this value.
  48796. +
  48797. +What: /sys/class/<iface>/statistics/rx_over_errors
  48798. +Date: April 2005
  48799. +KernelVersion: 2.6.12
  48800. +Contact: netdev@vger.kernel.org
  48801. +Description:
  48802. + Indicates the number of received packets that are oversized
  48803. + compared to what the network device is configured to accept
  48804. + (e.g: larger than MTU). See the network driver for the exact
  48805. + meaning of this value.
  48806. +
  48807. +What: /sys/class/<iface>/statistics/rx_packets
  48808. +Date: April 2005
  48809. +KernelVersion: 2.6.12
  48810. +Contact: netdev@vger.kernel.org
  48811. +Description:
  48812. + Indicates the total number of good packets received by this
  48813. + network device.
  48814. +
  48815. +What: /sys/class/<iface>/statistics/tx_aborted_errors
  48816. +Date: April 2005
  48817. +KernelVersion: 2.6.12
  48818. +Contact: netdev@vger.kernel.org
  48819. +Description:
  48820. + Indicates the number of packets that have been aborted
  48821. + during transmission by a network device (e.g: because of
  48822. + a medium collision). See the network driver for the exact
  48823. + meaning of this value.
  48824. +
  48825. +What: /sys/class/<iface>/statistics/tx_bytes
  48826. +Date: April 2005
  48827. +KernelVersion: 2.6.12
  48828. +Contact: netdev@vger.kernel.org
  48829. +Description:
  48830. + Indicates the number of bytes transmitted by a network
  48831. + device. See the network driver for the exact meaning of this
  48832. + value, in particular whether this accounts for all successfully
  48833. + transmitted packets or all packets that have been queued for
  48834. + transmission.
  48835. +
  48836. +What: /sys/class/<iface>/statistics/tx_carrier_errors
  48837. +Date: April 2005
  48838. +KernelVersion: 2.6.12
  48839. +Contact: netdev@vger.kernel.org
  48840. +Description:
  48841. + Indicates the number of packets that could not be transmitted
  48842. + because of carrier errors (e.g: physical link down). See the
  48843. + network driver for the exact meaning of this value.
  48844. +
  48845. +What: /sys/class/<iface>/statistics/tx_compressed
  48846. +Date: April 2005
  48847. +KernelVersion: 2.6.12
  48848. +Contact: netdev@vger.kernel.org
  48849. +Description:
  48850. + Indicates the number of transmitted compressed packets. Note
  48851. + this might only be relevant for devices that support
  48852. + compression (e.g: PPP).
  48853. +
  48854. +What: /sys/class/<iface>/statistics/tx_dropped
  48855. +Date: April 2005
  48856. +KernelVersion: 2.6.12
  48857. +Contact: netdev@vger.kernel.org
  48858. +Description:
  48859. + Indicates the number of packets dropped during transmission.
  48860. + See the driver for the exact reasons as to why the packets were
  48861. + dropped.
  48862. +
  48863. +What: /sys/class/<iface>/statistics/tx_errors
  48864. +Date: April 2005
  48865. +KernelVersion: 2.6.12
  48866. +Contact: netdev@vger.kernel.org
  48867. +Description:
  48868. + Indicates the number of packets in error during transmission by
  48869. + a network device. See the driver for the exact reasons as to
  48870. + why the packets were dropped.
  48871. +
  48872. +What: /sys/class/<iface>/statistics/tx_fifo_errors
  48873. +Date: April 2005
  48874. +KernelVersion: 2.6.12
  48875. +Contact: netdev@vger.kernel.org
  48876. +Description:
  48877. + Indicates the number of packets having caused a transmit
  48878. + FIFO error. See the driver for the exact reasons as to why the
  48879. + packets were dropped.
  48880. +
  48881. +What: /sys/class/<iface>/statistics/tx_heartbeat_errors
  48882. +Date: April 2005
  48883. +KernelVersion: 2.6.12
  48884. +Contact: netdev@vger.kernel.org
  48885. +Description:
  48886. + Indicates the number of packets transmitted that have been
  48887. + reported as heartbeat errors. See the driver for the exact
  48888. + reasons as to why the packets were dropped.
  48889. +
  48890. +What: /sys/class/<iface>/statistics/tx_packets
  48891. +Date: April 2005
  48892. +KernelVersion: 2.6.12
  48893. +Contact: netdev@vger.kernel.org
  48894. +Description:
  48895. + Indicates the number of packets transmitted by a network
  48896. + device. See the driver for whether this reports the number of all
  48897. + attempted or successful transmissions.
  48898. +
  48899. +What: /sys/class/<iface>/statistics/tx_window_errors
  48900. +Date: April 2005
  48901. +KernelVersion: 2.6.12
  48902. +Contact: netdev@vger.kernel.org
  48903. +Description:
  48904. + Indicates the number of packets not successfully transmitted
  48905. + due to a window collision. The specific meaning depends on the
  48906. + MAC layer used. On Ethernet this is usually used to report
  48907. + late collisions errors.
  48908. diff -Nur linux-3.14.15/Documentation/arm64/booting.txt linux-linaro-stable-mx6/Documentation/arm64/booting.txt
  48909. --- linux-3.14.15/Documentation/arm64/booting.txt 2014-07-31 23:51:43.000000000 +0200
  48910. +++ linux-linaro-stable-mx6/Documentation/arm64/booting.txt 2014-08-20 19:31:39.096838821 +0200
  48911. @@ -111,8 +111,14 @@
  48912. - Caches, MMUs
  48913. The MMU must be off.
  48914. Instruction cache may be on or off.
  48915. - Data cache must be off and invalidated.
  48916. - External caches (if present) must be configured and disabled.
  48917. + The address range corresponding to the loaded kernel image must be
  48918. + cleaned to the PoC. In the presence of a system cache or other
  48919. + coherent masters with caches enabled, this will typically require
  48920. + cache maintenance by VA rather than set/way operations.
  48921. + System caches which respect the architected cache maintenance by VA
  48922. + operations must be configured and may be enabled.
  48923. + System caches which do not respect architected cache maintenance by VA
  48924. + operations (not recommended) must be configured and disabled.
  48925. - Architected timers
  48926. CNTFRQ must be programmed with the timer frequency and CNTVOFF must
  48927. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt
  48928. --- linux-3.14.15/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt 1970-01-01 01:00:00.000000000 +0100
  48929. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt 2014-08-20 19:23:45.070809603 +0200
  48930. @@ -0,0 +1,64 @@
  48931. +Freescale Busfreq driver
  48932. +
  48933. +It is a generic driver that manages the frequency of the DDR, AHB and AXI buses in the iMX6x architecture.
  48934. +It works for both SMP and UP systems and for both DDR3 and LPDDR2 memory types.
  48935. +
  48936. +Required properties are listed below:
  48937. +- compatible: should be "fsl,imx6_busfreq"
  48938. +- clocks: Lists the various clocks used by the busfreq driver
  48939. +- interrupts - Lists the interrupts used by the busfreq driver. This is needed only for SMP architecutre.
  48940. +- fsl,max_ddr_freq - The max ddr freq for this chip
  48941. +
  48942. +Examples:
  48943. +For SOC imx6q.dtsi:
  48944. + busfreq { /* BUSFREQ */
  48945. + compatible = "fsl,imx6_busfreq";
  48946. + clocks = <&clks 171>, <&clks 6>, <&clks 11>, <&clks 104>, <&clks 172>, <&clks 58>,
  48947. + <&clks 18>, <&clks 60>, <&clks 20>, <&clks 3>;
  48948. + clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
  48949. + "periph_pre", "periph_clk2", "periph_clk2_sel", "osc";
  48950. + interrupts = <0 107 0x04>, <0 112 0x4>, <0 113 0x4>, <0 114 0x4>;
  48951. + interrupt-names = "irq_busfreq_0", "irq_busfreq_1", "irq_busfreq_2", "irq_busfreq_3";
  48952. + fsl,max_ddr_freq = <528000000>;
  48953. + };
  48954. +
  48955. +The Freescale Busfreq driver supports the following setpoints for the DDR freq:
  48956. +enum bus_freq_mode {
  48957. + BUS_FREQ_HIGH, -> The max freq the SOC supports
  48958. + BUS_FREQ_MED, -> Medium setpoint (ex 400MHz for DDR3 when the max is 528MHz)
  48959. + BUS_FREQ_AUDIO, -> Audio playback freq (50MHz)
  48960. + BUS_FREQ_LOW, -> Low power IDLE freq (24MHz)
  48961. +};
  48962. +
  48963. +Currently the Freescale Busfreq driver implementation requires drivers to call the following APIs:
  48964. +1. request_bus_freq(enum bus_freq_mode):
  48965. + The driver is requesting the system and ddr freq to be set to the requested value. The driver should call this
  48966. + API before it even enables its clocks.
  48967. +
  48968. +2. release_bus_freq(enum bus_freq_mode):
  48969. + The driver no longer needs the system and ddr freq at the required value. The driver should call this API after
  48970. + its work is done and it has disabled its clocks.
  48971. +
  48972. +Examples:
  48973. +In the IPU driver, the requesting and releasing of the required bus frequency is tied into the runtime PM implementation:
  48974. +
  48975. +int ipu_runtime_suspend(struct device *dev)
  48976. +{
  48977. + release_bus_freq(BUS_FREQ_HIGH);
  48978. + dev_dbg(dev, "ipu busfreq high release.\n");
  48979. +
  48980. + return 0;
  48981. +}
  48982. +
  48983. +int ipu_runtime_resume(struct device *dev)
  48984. +{
  48985. + request_bus_freq(BUS_FREQ_HIGH);
  48986. + dev_dbg(dev, "ipu busfreq high requst.\n");
  48987. +
  48988. + return 0;
  48989. +}
  48990. +
  48991. +static const struct dev_pm_ops ipu_pm_ops = {
  48992. + SET_RUNTIME_PM_OPS(ipu_runtime_suspend, ipu_runtime_resume, NULL)
  48993. + SET_SYSTEM_SLEEP_PM_OPS(ipu_suspend, ipu_resume)
  48994. +};
  48995. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/arm/imx/gpc.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/arm/imx/gpc.txt
  48996. --- linux-3.14.15/Documentation/devicetree/bindings/arm/imx/gpc.txt 1970-01-01 01:00:00.000000000 +0100
  48997. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/arm/imx/gpc.txt 2014-08-20 19:23:45.070809603 +0200
  48998. @@ -0,0 +1,20 @@
  48999. +Freescale imx GPC bindings
  49000. +
  49001. +Optional properties:
  49002. +- fsl,cpu_pupscr_sw2iso: for powering up CPU, number of 32K clock cycle PGC will wait before negating isolation signal.
  49003. +- fsl,cpu_pupscr_sw: for powering up CPU, number of 32K clock cycle PGC will wait before asserting isolation signal.
  49004. +- fsl,cpu_pdnscr_iso2sw: for powering down CPU, number of ipg clock cycle PGC will wait before negating isolation signal.
  49005. +- fsl,cpu_pdnscr_iso: for powering down CPU, number of ipg clock cycle PGC will wait before asserting isolation signal.
  49006. +
  49007. +These properties are for adjusting the GPC PGC CPU power up/down setting, if there is no such property in dts, then default
  49008. +value in GPC PGC registers will be used.
  49009. +
  49010. +
  49011. +Example:
  49012. +
  49013. + &gpc {
  49014. + fsl,cpu_pupscr_sw2iso = <0xf>;
  49015. + fsl,cpu_pupscr_sw = <0xf>;
  49016. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  49017. + fsl,cpu_pdnscr_iso = <0x1>;
  49018. + };
  49019. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/arm/pmu.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/arm/pmu.txt
  49020. --- linux-3.14.15/Documentation/devicetree/bindings/arm/pmu.txt 2014-07-31 23:51:43.000000000 +0200
  49021. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/arm/pmu.txt 2014-08-20 19:31:39.232839404 +0200
  49022. @@ -17,6 +17,9 @@
  49023. "arm,arm1176-pmu"
  49024. "arm,arm1136-pmu"
  49025. - interrupts : 1 combined interrupt or 1 per core.
  49026. +- cluster : a phandle to the cluster to which it belongs
  49027. + If there are more than one cluster with same CPU type
  49028. + then there should be separate PMU nodes per cluster.
  49029. Example:
  49030. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/ata/ahci-platform.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/ata/ahci-platform.txt
  49031. --- linux-3.14.15/Documentation/devicetree/bindings/ata/ahci-platform.txt 2014-07-31 23:51:43.000000000 +0200
  49032. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/ata/ahci-platform.txt 2014-08-20 19:31:39.232839404 +0200
  49033. @@ -4,12 +4,19 @@
  49034. Each SATA controller should have its own node.
  49035. Required properties:
  49036. -- compatible : compatible list, contains "snps,spear-ahci"
  49037. +- compatible : compatible list, contains "snps,spear-ahci",
  49038. + "fsl,imx53-ahci" or "fsl,imx6q-ahci"
  49039. - interrupts : <interrupt mapping for SATA IRQ>
  49040. - reg : <registers mapping>
  49041. Optional properties:
  49042. - dma-coherent : Present if dma operations are coherent
  49043. +- clocks : a list of phandle + clock specifier pairs
  49044. +- target-supply : regulator for SATA target power
  49045. +
  49046. +"fsl,imx53-ahci", "fsl,imx6q-ahci" required properties:
  49047. +- clocks : must contain the sata, sata_ref and ahb clocks
  49048. +- clock-names : must contain "ahb" for the ahb clock
  49049. Example:
  49050. sata@ffe08000 {
  49051. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/clock/imx6q-clock.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/clock/imx6q-clock.txt
  49052. --- linux-3.14.15/Documentation/devicetree/bindings/clock/imx6q-clock.txt 2014-07-31 23:51:43.000000000 +0200
  49053. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/clock/imx6q-clock.txt 2014-08-20 19:31:39.240839439 +0200
  49054. @@ -89,8 +89,6 @@
  49055. gpu3d_shader 74
  49056. ipu1_podf 75
  49057. ipu2_podf 76
  49058. - ldb_di0_podf 77
  49059. - ldb_di1_podf 78
  49060. ipu1_di0_pre 79
  49061. ipu1_di1_pre 80
  49062. ipu2_di0_pre 81
  49063. @@ -220,6 +218,20 @@
  49064. lvds2_sel 205
  49065. lvds1_gate 206
  49066. lvds2_gate 207
  49067. + gpt_3m 208
  49068. + video_27m 209
  49069. + ldb_di0_div_7 210
  49070. + ldb_di1_div_7 211
  49071. + ldb_di0_div_sel 212
  49072. + ldb_di1_div_sel 213
  49073. + caam_mem 214
  49074. + caam_aclk 215
  49075. + caam_ipg 216
  49076. + epit1 217
  49077. + epit2 218
  49078. + tzasc2 219
  49079. + lvds1_in 220
  49080. + lvds1_out 221
  49081. Examples:
  49082. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
  49083. --- linux-3.14.15/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt 2014-07-31 23:51:43.000000000 +0200
  49084. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt 2014-08-20 19:31:39.244839456 +0200
  49085. @@ -47,6 +47,7 @@
  49086. 20 ASRC
  49087. 21 ESAI
  49088. 22 SSI Dual FIFO (needs firmware ver >= 2)
  49089. + 23 HDMI Audio
  49090. The third cell specifies the transfer priority as below.
  49091. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt
  49092. --- linux-3.14.15/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt 1970-01-01 01:00:00.000000000 +0100
  49093. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt 2014-08-20 19:23:45.106809757 +0200
  49094. @@ -0,0 +1,146 @@
  49095. +* FSL IPUv3 Display/FB
  49096. +
  49097. +The FSL IPUv3 is Image Processing Unit version 3, a part of video and graphics
  49098. +subsystem in an application processor. The goal of the IPU is to provide
  49099. +comprehensive support for the flow of data from an image sensor or/and to a
  49100. +display device.
  49101. +
  49102. +Two IPU units are on the imx6q SOC while only one IPU unit on the imx6dl SOC.
  49103. +Each IPU unit has two display interfaces.
  49104. +
  49105. +For LDB/LVDS panel, there are two LVDS channels(LVDS0 and LVDS1) which can
  49106. +transfer video data, these two channels can be used as
  49107. +split/dual/single/separate mode.
  49108. +-split mode means display data from DI0 or DI1 will send to both channels
  49109. + LVDS0+LVDS1.
  49110. +-dual mode means display data from DI0 or DI1 will be duplicated on LVDS0
  49111. + and LVDS1, it said, LVDS0 and LVDS1 has the same content.
  49112. +-single mode means only work for DI0/DI1->LVDS0 or DI0/DI1->LVDS1.
  49113. +-separate mode means you can make DI0/DI1->LVDS0 and DI0/DI1->LVDS1 work
  49114. + at the same time.
  49115. + "ldb=spl0/1" -- split mode on DI0/1
  49116. + "ldb=dul0/1" -- dual mode on DI0/1
  49117. + "ldb=sin0/1" -- single mode on LVDS0/1
  49118. + "ldb=sep0/1" -- separate mode begin from LVDS0/1
  49119. +
  49120. +Required properties for IPU:
  49121. +- bypass_reset :Bypass reset to avoid display channel being.
  49122. + stopped by probe since it may start to work in bootloader: 0 or 1.
  49123. +- compatible : should be "fsl,imx6q-ipu".
  49124. +- reg : the register address range.
  49125. +- interrupts : the error and sync interrupts request.
  49126. +- clocks : the clock sources that it depends on.
  49127. +- clock-names: the related clock names.
  49128. +- resets : IPU reset specifier. See reset.txt and fsl,imx-src.txt in
  49129. + Documentation/devicetree/bindings/reset/ for details.
  49130. +
  49131. +Required properties for fb:
  49132. +- compatible : should be "fsl,mxc_sdc_fb".
  49133. +- disp_dev : display device: "ldb", "lcd", "hdmi", "mipi_dsi".
  49134. +- mode_str : video mode string: "LDB-XGA" or "LDB-1080P60" for ldb,
  49135. + "CLAA-WVGA" for lcd, "TRULY-WVGA" for TRULY mipi_dsi lcd panel,
  49136. + "1920x1080M@60" for hdmi.
  49137. +- default_bpp : default bits per pixel: 8/16/24/32
  49138. +- int_clk : use internal clock as pixel clock: 0 or 1
  49139. +- late_init : to avoid display channel being re-initialized
  49140. + as we've probably setup the channel in bootloader: 0 or 1
  49141. +- interface_pix_fmt : display interface pixel format as below:
  49142. + RGB666 IPU_PIX_FMT_RGB666
  49143. + RGB565 IPU_PIX_FMT_RGB565
  49144. + RGB24 IPU_PIX_FMT_RGB24
  49145. + BGR24 IPU_PIX_FMT_BGR24
  49146. + GBR24 IPU_PIX_FMT_GBR24
  49147. + YUV444 IPU_PIX_FMT_YUV444
  49148. + LVDS666 IPU_PIX_FMT_LVDS666
  49149. + YUYV IPU_PIX_FMT_YUYV
  49150. + UYVY IPU_PIX_FMT_UYVY
  49151. + YVYV IPU_PIX_FMT_YVYU
  49152. + VYUY IPU_PIX_FMT_VYUY
  49153. +
  49154. +Required properties for display:
  49155. +- compatible : should be "fsl,lcd" for lcd panel, "fsl,imx6q-ldb" for ldb
  49156. +- reg : the register address range if necessary to have.
  49157. +- interrupts : the error and sync interrupts if necessary to have.
  49158. +- clocks : the clock sources that it depends on if necessary to have.
  49159. +- clock-names: the related clock names if necessary to have.
  49160. +- ipu_id : ipu id for the first display device: 0 or 1
  49161. +- disp_id : display interface id for the first display interface: 0 or 1
  49162. +- default_ifmt : save as above display interface pixel format for lcd
  49163. +- pinctrl-names : should be "default"
  49164. +- pinctrl-0 : should be pinctrl_ipu1_1 or pinctrl_ipu2_1, which depends on the
  49165. + IPU connected.
  49166. +- sec_ipu_id : secondary ipu id for the second display device(ldb only): 0 or 1
  49167. +- sec_disp_id : secondary display interface id for the second display
  49168. + device(ldb only): 0 or 1
  49169. +- ext_ref : reference resistor select for ldb only: 0 or 1
  49170. +- mode : ldb mode as below:
  49171. + spl0 LDB_SPL_DI0
  49172. + spl1 LDB_SPL_DI1
  49173. + dul0 LDB_DUL_DI0
  49174. + dul1 LDB_DUL_DI1
  49175. + sin0 LDB_SIN0
  49176. + sin1 LDB_SIN1
  49177. + sep0 LDB_SEP0
  49178. + sep1 LDB_SEP1
  49179. +- gpr : the mux controller for the display engine's display interfaces and the display encoder
  49180. + (only valid for mipi dsi now).
  49181. +- disp-power-on-supply : the regulator to control display panel's power.
  49182. + (only valid for mipi dsi now).
  49183. +- resets : the gpio pin to reset the display device(only valid for mipi display panel now).
  49184. +- lcd_panel : the video mode name for the display device(only valid for mipi display panel now).
  49185. +- dev_id : the display engine's identity within the system, which intends to replace ipu_id
  49186. + (only valid for mipi dsi now).
  49187. +
  49188. +Example for IPU:
  49189. + ipu1: ipu@02400000 {
  49190. + compatible = "fsl,imx6q-ipu";
  49191. + reg = <0x02400000 0x400000>;
  49192. + interrupts = <0 6 0x4 0 5 0x4>;
  49193. + clocks = <&clks 130>, <&clks 131>, <&clks 132>,
  49194. + <&clks 39>, <&clks 40>,
  49195. + <&clks 135>, <&clks 136>;
  49196. + clock-names = "bus", "di0", "di1",
  49197. + "di0_sel", "di1_sel",
  49198. + "ldb_di0", "ldb_di1";
  49199. + resets = <&src 2>;
  49200. + bypass_reset = <0>;
  49201. + };
  49202. +
  49203. +Example for fb:
  49204. + fb0 {
  49205. + compatible = "fsl,mxc_sdc_fb";
  49206. + disp_dev = "ldb";
  49207. + interface_pix_fmt = "RGB666";
  49208. + mode_str ="LDB-XGA";
  49209. + default_bpp = <16>;
  49210. + int_clk = <0>;
  49211. + late_init = <0>;
  49212. + status = "okay";
  49213. + };
  49214. +
  49215. +Example for ldb display:
  49216. + ldb@020e0000 {
  49217. + ipu_id = <1>;
  49218. + disp_id = <0>;
  49219. + ext_ref = <1>;
  49220. + mode = "sep0";
  49221. + sec_ipu_id = <1>;
  49222. + sec_disp_id = <1>;
  49223. + status = "okay";
  49224. + };
  49225. +
  49226. +Example for mipi dsi display:
  49227. + mipi_dsi: mipi@021e0000 {
  49228. + compatible = "fsl,imx6q-mipi-dsi";
  49229. + reg = <0x021e0000 0x4000>;
  49230. + interrupts = <0 102 0x04>;
  49231. + gpr = <&gpr>;
  49232. + clocks = <&clks 138>, <&clks 204>;
  49233. + clock-names = "mipi_pllref_clk", "mipi_cfg_clk";
  49234. + dev_id = <0>;
  49235. + disp_id = <0>;
  49236. + lcd_panel = "TRULY-WVGA";
  49237. + disp-power-on-supply = <&reg_mipi_dsi_pwr_on>
  49238. + resets = <&mipi_dsi_reset>;
  49239. + status = "okay";
  49240. + };
  49241. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/leds/leds-pwm.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/leds/leds-pwm.txt
  49242. --- linux-3.14.15/Documentation/devicetree/bindings/leds/leds-pwm.txt 2014-07-31 23:51:43.000000000 +0200
  49243. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/leds/leds-pwm.txt 2014-08-20 19:31:39.284839627 +0200
  49244. @@ -13,6 +13,8 @@
  49245. For the pwms and pwm-names property please refer to:
  49246. Documentation/devicetree/bindings/pwm/pwm.txt
  49247. - max-brightness : Maximum brightness possible for the LED
  49248. +- active-low : (optional) For PWMs where the LED is wired to supply
  49249. + rather than ground.
  49250. - label : (optional)
  49251. see Documentation/devicetree/bindings/leds/common.txt
  49252. - linux,default-trigger : (optional)
  49253. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/mailbox/mailbox.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/mailbox/mailbox.txt
  49254. --- linux-3.14.15/Documentation/devicetree/bindings/mailbox/mailbox.txt 1970-01-01 01:00:00.000000000 +0100
  49255. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/mailbox/mailbox.txt 2014-08-20 19:31:39.284839627 +0200
  49256. @@ -0,0 +1,33 @@
  49257. +* Generic Mailbox Controller and client driver bindings
  49258. +
  49259. +Generic binding to provide a way for Mailbox controller drivers to
  49260. +assign appropriate mailbox channel to client drivers.
  49261. +
  49262. +* Mailbox Controller
  49263. +
  49264. +Required property:
  49265. +- #mbox-cells: Must be at least 1. Number of cells in a mailbox
  49266. + specifier.
  49267. +
  49268. +Example:
  49269. + mailbox: mailbox {
  49270. + ...
  49271. + #mbox-cells = <1>;
  49272. + };
  49273. +
  49274. +
  49275. +* Mailbox Client
  49276. +
  49277. +Required property:
  49278. +- mbox: List of phandle and mailbox channel specifier.
  49279. +
  49280. +- mbox-names: List of identifier strings for each mailbox channel
  49281. + required by the client.
  49282. +
  49283. +Example:
  49284. + pwr_cntrl: power {
  49285. + ...
  49286. + mbox-names = "pwr-ctrl", "rpc";
  49287. + mbox = <&mailbox 0
  49288. + &mailbox 1>;
  49289. + };
  49290. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/mlb/mlb150.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/mlb/mlb150.txt
  49291. --- linux-3.14.15/Documentation/devicetree/bindings/mlb/mlb150.txt 1970-01-01 01:00:00.000000000 +0100
  49292. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/mlb/mlb150.txt 2014-08-20 19:23:45.146809927 +0200
  49293. @@ -0,0 +1,22 @@
  49294. +* Freescale Media Local Bus Host Controller (MLB) for i.MX6Q/DL
  49295. +
  49296. +The Media Local Bus Host Controller on Freescale i.MX family
  49297. +provides an interface for MOST network.
  49298. +
  49299. +Required properties:
  49300. +- compatible : Should be "fsl,<chip>-mlb150"
  49301. +- reg : Should contain mlb registers location and length
  49302. +- interrupts : Should contain mlb interrupt
  49303. +- clocks: Should contain the mlb clock sources
  49304. +- clock-names: Should be the names of mlb clock sources
  49305. +- iram : phandle pointing to the SRAM device node
  49306. +
  49307. +Examples:
  49308. +mlb@0218c000 {
  49309. + compatible = "fsl,imx6q-mlb150";
  49310. + reg = <0x0218c000 0x4000>;
  49311. + interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
  49312. + clocks = <&clks 139>, <&clks 175>;
  49313. + clock-names = "mlb", "pll8_mlb";
  49314. + iram = <&ocram>;
  49315. +};
  49316. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/mmc/mmc.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/mmc/mmc.txt
  49317. --- linux-3.14.15/Documentation/devicetree/bindings/mmc/mmc.txt 2014-07-31 23:51:43.000000000 +0200
  49318. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/mmc/mmc.txt 2014-08-20 19:31:39.304839713 +0200
  49319. @@ -5,6 +5,8 @@
  49320. Interpreted by the OF core:
  49321. - reg: Registers location and length.
  49322. - interrupts: Interrupts used by the MMC controller.
  49323. +- clocks: Clocks needed for the host controller, if any.
  49324. +- clock-names: Goes with clocks above.
  49325. Card detection:
  49326. If no property below is supplied, host native card detect is used.
  49327. @@ -30,6 +32,15 @@
  49328. - cap-sdio-irq: enable SDIO IRQ signalling on this interface
  49329. - full-pwr-cycle: full power cycle of the card is supported
  49330. +Card power and reset control:
  49331. +The following properties can be specified for cases where the MMC
  49332. +peripheral needs additional reset, regulator and clock lines. It is for
  49333. +example common for WiFi/BT adapters to have these separate from the main
  49334. +MMC bus:
  49335. + - card-reset-gpios: Specify GPIOs for card reset (reset active low)
  49336. + - card-external-vcc-supply: Regulator to drive (independent) card VCC
  49337. + - clock with name "card_ext_clock": External clock provided to the card
  49338. +
  49339. *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
  49340. polarity properties, we have to fix the meaning of the "normal" and "inverted"
  49341. line levels. We choose to follow the SDHCI standard, which specifies both those
  49342. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
  49343. --- linux-3.14.15/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt 2014-07-31 23:51:43.000000000 +0200
  49344. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt 2014-08-20 19:31:39.344839885 +0200
  49345. @@ -71,6 +71,13 @@
  49346. name for integer state ID 0, list entry 1 for state ID 1, and
  49347. so on.
  49348. +pinctrl-assert-gpios:
  49349. + List of phandles, each pointing at a GPIO which is used by some
  49350. + board design to steer pins between two peripherals on the board.
  49351. + It plays like a board level pin multiplexer to choose different
  49352. + functions for given pins by pulling up/down the GPIOs. See
  49353. + bindings/gpio/gpio.txt for details of how to specify GPIO.
  49354. +
  49355. For example:
  49356. /* For a client device requiring named states */
  49357. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/reset/gpio-reset.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/reset/gpio-reset.txt
  49358. --- linux-3.14.15/Documentation/devicetree/bindings/reset/gpio-reset.txt 1970-01-01 01:00:00.000000000 +0100
  49359. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/reset/gpio-reset.txt 2014-08-20 19:23:45.166810012 +0200
  49360. @@ -0,0 +1,35 @@
  49361. +GPIO reset controller
  49362. +=====================
  49363. +
  49364. +A GPIO reset controller controls a single GPIO that is connected to the reset
  49365. +pin of a peripheral IC. Please also refer to reset.txt in this directory for
  49366. +common reset controller binding usage.
  49367. +
  49368. +Required properties:
  49369. +- compatible: Should be "gpio-reset"
  49370. +- reset-gpios: A gpio used as reset line. The gpio specifier for this property
  49371. + depends on the gpio controller that provides the gpio.
  49372. +- #reset-cells: 0, see below
  49373. +
  49374. +Optional properties:
  49375. +- reset-delay-us: delay in microseconds. The gpio reset line will be asserted for
  49376. + this duration to reset.
  49377. +- initially-in-reset: boolean. If not set, the initial state should be a
  49378. + deasserted reset line. If this property exists, the
  49379. + reset line should be kept in reset.
  49380. +
  49381. +example:
  49382. +
  49383. +sii902x_reset: gpio-reset {
  49384. + compatible = "gpio-reset";
  49385. + reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
  49386. + reset-delay-us = <10000>;
  49387. + initially-in-reset;
  49388. + #reset-cells = <0>;
  49389. +};
  49390. +
  49391. +/* Device with nRESET pin connected to GPIO5_0 */
  49392. +sii902x@39 {
  49393. + /* ... */
  49394. + resets = <&sii902x_reset>; /* active-low GPIO5_0, 10 ms delay */
  49395. +};
  49396. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/sound/cs42888.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/sound/cs42888.txt
  49397. --- linux-3.14.15/Documentation/devicetree/bindings/sound/cs42888.txt 1970-01-01 01:00:00.000000000 +0100
  49398. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/sound/cs42888.txt 2014-08-20 19:23:45.170810029 +0200
  49399. @@ -0,0 +1,29 @@
  49400. +CS42888 audio CODEC
  49401. +
  49402. +This device supports I2C only.
  49403. +
  49404. +Required properties:
  49405. +
  49406. + - compatible: "cirrus,cs42888"
  49407. + - reg: the I2C address of the device.
  49408. + - clocks: Phandle to the clock node.
  49409. + - clock-names: Contains name for each entry in clocks.
  49410. + "codec_osc" : the external oscillator.
  49411. + "esai" : the hckt clock from esai.
  49412. + - <name>-supply: Phandle to the regulator <name>.
  49413. +
  49414. +Note: cs42888 needs a regulators node and a clocks node.
  49415. +
  49416. +Example:
  49417. +In this case, the clock is external oscillator.
  49418. +
  49419. +codec: cs42888@48 {
  49420. + compatible = "cirrus,cs42888";
  49421. + reg = <0x048>;
  49422. + clocks = <&codec_osc 0>;
  49423. + clock-names = "codec_osc";
  49424. + VA-supply = <&reg_audio>;
  49425. + VD-supply = <&reg_audio>;
  49426. + VLS-supply = <&reg_audio>;
  49427. + VLC-supply = <&reg_audio>;
  49428. +};
  49429. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt
  49430. --- linux-3.14.15/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt 1970-01-01 01:00:00.000000000 +0100
  49431. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt 2014-08-20 19:23:45.170810029 +0200
  49432. @@ -0,0 +1,23 @@
  49433. +* Freescale Asynchronous Sample Rate Converter (ASRC)
  49434. +
  49435. +This document is for asrc p2p node. p2p is one of asrc mode. asrc p2p depend on
  49436. +MXC_ASRC.
  49437. +
  49438. +Required properties:
  49439. + - compatible: Should be "fsl,<chip>-asrc-p2p".
  49440. + - fsl,output-rate: the output rate of asrc p2p. which can be <32000> to <192000>,
  49441. + - fsl,output-width: the output width of asrc p2p. which can be <16>, <24>.
  49442. + - fsl,asrc-dma-rx-events: The rx dma event of the asrc, <a b c> corresponding
  49443. + to 3 pair of asrc.
  49444. + - fsl,asrc-dma-tx-events: The tx dma event of the esai, <a b c> corresponding
  49445. + to 3 pair of asrc.
  49446. +
  49447. +Example:
  49448. +asrc_p2p: asrc_p2p {
  49449. + compatible = "fsl,imx6q-asrc-p2p";
  49450. + fsl,output-rate = <48000>;
  49451. + fsl,output-width = <16>;
  49452. + fsl,asrc-dma-rx-events = <17 18 19>;
  49453. + fsl,asrc-dma-tx-events = <20 21 22>;
  49454. + status = "okay";
  49455. +};
  49456. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt
  49457. --- linux-3.14.15/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt 1970-01-01 01:00:00.000000000 +0100
  49458. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt 2014-08-20 19:23:45.170810029 +0200
  49459. @@ -0,0 +1,25 @@
  49460. +Freescale i.MX audio complex with CS42888 codec
  49461. +
  49462. +Required properties:
  49463. +- compatible : "fsl,imx-audio-cs42888"
  49464. +- model : The user-visible name of this sound complex
  49465. +- esai-controller : The phandle of the i.MX SSI controller
  49466. +- audio-codec : The phandle of the CS42888 audio codec
  49467. +
  49468. +Optional properties:
  49469. +- asrc-controller : The phandle of the i.MX ASRC controller
  49470. +- audio-routing : A list of the connections between audio components.
  49471. + Each entry is a pair of strings, the first being the connection's sink,
  49472. + the second being the connection's source. Valid names could be power
  49473. + supplies, CS42888 pins, and the jacks on the board:
  49474. +
  49475. +Example:
  49476. +
  49477. +sound {
  49478. + compatible = "fsl,imx6q-sabresd-wm8962",
  49479. + "fsl,imx-audio-wm8962";
  49480. + model = "cs42888-audio";
  49481. + esai-controller = <&esai>;
  49482. + asrc-controller = <&asrc_p2p>;
  49483. + audio-codec = <&codec>;
  49484. +};
  49485. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
  49486. --- linux-3.14.15/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt 2014-07-31 23:51:43.000000000 +0200
  49487. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt 2014-08-20 19:23:45.170810029 +0200
  49488. @@ -24,6 +24,12 @@
  49489. Note: The AUDMUX port numbering should start at 1, which is consistent with
  49490. hardware manual.
  49491. +Optional properties:
  49492. +- hp-det-gpios : The gpio pin to detect plug in/out event that happens to
  49493. + Headphone jack.
  49494. +- mic-det-gpios: The gpio pin to detect plug in/out event that happens to
  49495. + Microphone jack.
  49496. +
  49497. Example:
  49498. sound {
  49499. @@ -43,4 +49,6 @@
  49500. "DMICDAT", "DMIC";
  49501. mux-int-port = <2>;
  49502. mux-ext-port = <3>;
  49503. + hp-det-gpios = <&gpio7 8 1>;
  49504. + mic-det-gpios = <&gpio1 9 1>;
  49505. };
  49506. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/sound/wm8962.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/sound/wm8962.txt
  49507. --- linux-3.14.15/Documentation/devicetree/bindings/sound/wm8962.txt 2014-07-31 23:51:43.000000000 +0200
  49508. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/sound/wm8962.txt 2014-08-20 19:23:45.170810029 +0200
  49509. @@ -13,6 +13,14 @@
  49510. of R51 (Class D Control 2) gets set, indicating that the speaker is
  49511. in mono mode.
  49512. + - amic-mono: This is a boolean property. If present, indicating that the
  49513. + analog micphone is hardware mono input, the driver would enable monomix
  49514. + for it.
  49515. +
  49516. + - dmic-mono: This is a boolean property. If present, indicating that the
  49517. + digital micphone is hardware mono input, the driver would enable monomix
  49518. + for it.
  49519. +
  49520. - mic-cfg : Default register value for R48 (Additional Control 4).
  49521. If absent, the default should be the register default.
  49522. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/usb/mxs-phy.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/usb/mxs-phy.txt
  49523. --- linux-3.14.15/Documentation/devicetree/bindings/usb/mxs-phy.txt 2014-07-31 23:51:43.000000000 +0200
  49524. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/usb/mxs-phy.txt 2014-08-20 19:23:45.178810064 +0200
  49525. @@ -1,13 +1,16 @@
  49526. * Freescale MXS USB Phy Device
  49527. Required properties:
  49528. -- compatible: Should be "fsl,imx23-usbphy"
  49529. +- compatible: "fsl,imx23-usbphy" for imx23 and imx28, "fsl,imx6q-usbphy"
  49530. +for imx6dq and imx6dl, "fsl,imx6sl-usbphy" for imx6sl
  49531. - reg: Should contain registers location and length
  49532. - interrupts: Should contain phy interrupt
  49533. +- fsl,anatop: phandle for anatop register, it is only for imx6 SoC series
  49534. Example:
  49535. usbphy1: usbphy@020c9000 {
  49536. compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
  49537. reg = <0x020c9000 0x1000>;
  49538. interrupts = <0 44 0x04>;
  49539. + fsl,anatop = <&anatop>;
  49540. };
  49541. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt
  49542. --- linux-3.14.15/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt 1970-01-01 01:00:00.000000000 +0100
  49543. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt 2014-08-20 19:23:45.190810115 +0200
  49544. @@ -0,0 +1,61 @@
  49545. +* Freescale CMOS Sensor Interface (CSI) V4L2 Capture
  49546. +
  49547. +Required properties for CSI
  49548. +- compatible: "fsl,<soc>-csi". Supported chip includes imx6sl
  49549. +- reg: Address and length of the register set for CSI
  49550. +- interrupts: Should contain CSI interrupts
  49551. +
  49552. +Required properties for v4l2_capture
  49553. +- compatible: should be "fsl,<soc>-csi-v4l2", supported socs include imx6sl
  49554. +
  49555. +Required properties for sensor
  49556. +- compatible: "<vendor>,<sensor>"
  49557. + please check the supported sensor in the Supported Sensor fields.
  49558. +- reg: sensor I2C slave address
  49559. +- pinctrl-names: should be "default" for parallel sensor
  49560. +- pinctrl-0: should depend on the connection between sensor and i.MX
  49561. + connection between sensor and i.MX could be only legacy parallel on i.MX6SL
  49562. +- clocks: should be the clock source provided to sensor.
  49563. +- clock-names: should be "csi_mclk"
  49564. +- AVDD-supply: set according to the board.
  49565. +- DVDD-supply: set according to the board.
  49566. +- pwn-gpios: set according to the board.
  49567. +- rst-gpios: set according to the board.
  49568. +- csi_id: csi id for v4l2 capture device
  49569. + should be 0 for i.MX6SL
  49570. +- mclk: should the value of mclk clock send out the sensor. unit is Hz.
  49571. +- mclk_source: should be 0 for i.MX6SL
  49572. +
  49573. +Supported Sensor
  49574. +- ovti, ov5640
  49575. +
  49576. +Example for CSI:
  49577. + csi: csi@020e4000 {
  49578. + compatible = "fsl,imx6sl-csi";
  49579. + reg = <0x020e4000 0x4000>;
  49580. + interrupts = <0 7 0x04>;
  49581. + status = "disabled";
  49582. + };
  49583. +
  49584. +Examples for v4l2_capture:
  49585. + csi_v4l2_cap {
  49586. + compatible = "fsl,imx6q-v4l2-capture";
  49587. + status = "okay";
  49588. + };
  49589. +
  49590. +Examples for sensors:
  49591. + ov564x: ov564x@3c {
  49592. + compatible = "ovti,ov564x";
  49593. + reg = <0x3c>;
  49594. + pinctrl-names = "default";
  49595. + pinctrl-0 = <&pinctrl_csi_0>;
  49596. + clocks = <&clks IMX6SL_CLK_CSI>;
  49597. + clock-names = "csi_mclk";
  49598. + AVDD-supply = <&vgen6_reg>; /* 2.8v */
  49599. + DVDD-supply = <&vgen2_reg>; /* 1.5v*/
  49600. + pwn-gpios = <&gpio1 25 1>;
  49601. + rst-gpios = <&gpio1 26 0>;
  49602. + csi_id = <0>;
  49603. + mclk = <24000000>;
  49604. + mclk_source = <0>;
  49605. + };
  49606. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt
  49607. --- linux-3.14.15/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt 1970-01-01 01:00:00.000000000 +0100
  49608. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt 2014-08-20 19:31:39.440840296 +0200
  49609. @@ -0,0 +1,42 @@
  49610. +* Freescale MIPI CSI2 Controller for i.MX6DQ/i.MX6SDL
  49611. +
  49612. +Required properties for mipi csi2 controller:
  49613. +- compatible: should be "fsl,imx6q-mipi-csi2"
  49614. +- reg: <base addr, range> contains mipi csi2 register base address and range
  49615. +- interrupts: <type num flag> where type is a interrupt type, num is the
  49616. + interrupt number and flag is a field that level/trigger information for
  49617. + the interrupt.
  49618. +- clocks: the clock sources that mipi csi2 depends on.
  49619. +- clock-names: the name is related to the clock source one by one.
  49620. +- status: should be set to "disable".
  49621. +
  49622. +Required properties for mipi csi2 on specified board:
  49623. +- ipu_id: ipu id which mipi csi2 connected to.
  49624. + should be 0 or 1 for i.MX6DQ; should be 0 for i.MX6SDL
  49625. +- csi_id: csi id which mipi csi2 connected to.
  49626. + should be 0 or 1 for i.MX6DQ/i.MX6SDL
  49627. +- v_channel: virtual channel which send to MIPI CSI2 controller
  49628. + should keep consistent with the input MIPI signal.
  49629. +- lanes: data lanes of input MIPI signal. The maximum data lanes is 4.
  49630. + should keep consistent with the input MIPI signal.
  49631. +- status: should be set to "okay".
  49632. +
  49633. +Examples:
  49634. +for SOC imx6qdl.dtsi:
  49635. + mipi_csi@021dc000 {
  49636. + compatible = "fsl,imx6q-mipi-csi2";
  49637. + reg = <0x021dc000 0x4000>;
  49638. + interrupts = <0 100 0x04>, <0 101 0x04>;
  49639. + clocks = <&clks 138>, <&clks 53>, <&clks 204>;
  49640. + clock-names = "dphy_clk", "pixel_clk", "cfg_clk";
  49641. + status = "disabled";
  49642. + };
  49643. +
  49644. +for board imx6qdl-sabresd.dtsi:
  49645. + mipi_csi@021dc000 {
  49646. + status = "okay";
  49647. + ipu_id = <0>;
  49648. + csi_id = <1>;
  49649. + v_channel = <0>;
  49650. + lanes = <2>;
  49651. + };
  49652. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/video/fsl,pxp.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/video/fsl,pxp.txt
  49653. --- linux-3.14.15/Documentation/devicetree/bindings/video/fsl,pxp.txt 1970-01-01 01:00:00.000000000 +0100
  49654. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/video/fsl,pxp.txt 2014-08-20 19:23:45.190810115 +0200
  49655. @@ -0,0 +1,30 @@
  49656. +* Freescale PxP Controller for i.MX6DL, i.MX6SL
  49657. +
  49658. +Required properties for PxP controller:
  49659. +- compatible: should be "fsl,<soc>-pxp-dma"
  49660. +- reg: <base addr, range> contains pxp register base address and range
  49661. +- interrupts: <type num flag> where type is an interrupt type, num is the
  49662. + interrupt number and flag is a field that level/trigger information for
  49663. + the interrupt.
  49664. +- clocks: the clock sources that pxp depends on.
  49665. +- clock-names: the name is related to the clock source
  49666. +
  49667. +Required properties for pxp on specified board:
  49668. +- status: should be set to "okay" if want to use PxP
  49669. +
  49670. +Examples:
  49671. +for SOC imx6dl.dtsi:
  49672. + pxp@020f0000 {
  49673. + compatible = "fsl,imx6dl-pxp-dma";
  49674. + reg = <0x020f0000 0x4000>;
  49675. + interrupts = <0 98 0x04>;
  49676. + clocks = <&clks 133>;
  49677. + clock-names = "pxp-axi";
  49678. + status = "disabled";
  49679. + };
  49680. +
  49681. +
  49682. +for board imx6dl-sabresd.dts:
  49683. + &pxp {
  49684. + status = "okay";
  49685. + };
  49686. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt
  49687. --- linux-3.14.15/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt 1970-01-01 01:00:00.000000000 +0100
  49688. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt 2014-08-20 19:23:45.190810115 +0200
  49689. @@ -0,0 +1,102 @@
  49690. +* Freescale V4L2 Capture for i.MX6DQ/i.MX6SDL
  49691. +
  49692. +Required board properties for IPUv3 capture:
  49693. +- clocks: should include the clock provided by i.MX6 to sensor
  49694. +- clock-names: sensor clock's name should be "ipux_csiy"
  49695. + x should be 1 or 2 for i.MX6DQ; should be 1 for i.MX6SDL
  49696. + y is 0 or 1 for i.MX6DQ/i.MX6SDL
  49697. +Note: other detailed information for IPUv3, please refer to
  49698. +Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt
  49699. +
  49700. +Required properties for v4l2_capture
  49701. +- compatible: should be "fsl,imx6q-v4l2-capture"
  49702. +- ipu_id: ipu id for v4l2 capture device
  49703. + should be 0 or 1 for i.MX6DQ; should be 0 for i.MX6SDL
  49704. +- csi_id: csi id for v4l2 capture device
  49705. + should be 0 or 1 for i.MX6DQ/i.MX6SDL
  49706. +- mclk_source: should be 0 or 1. two mclk sources at most now
  49707. +- status: should be set to "okay" to enable this device
  49708. +
  49709. +Required properties for sensor
  49710. +- compatible: "<vendor>,<sensor>"
  49711. + please check the supported sensor in the Supported Sensor fields.
  49712. +- reg: sensor I2C slave address
  49713. +- pinctrl-names: should be "default" for parallel sensor
  49714. +- pinctrl-0: should depend on the connection between sensor and i.MX
  49715. + connection between sensor and i.MX could be MIPI-CSI2 or legacy parallel
  49716. +- clocks: should be the clock source provided to sensor.
  49717. +- clock-names: should be "csi_mclk"
  49718. +- DOVDD-supply: set according to the board.
  49719. +- AVDD-supply: set according to the board.
  49720. +- DVDD-supply: set according to the board.
  49721. +- pwn-gpios: set according to the board.
  49722. +- rst-gpios: set according to the board.
  49723. +- csi_id: csi id for v4l2 capture device
  49724. + should be 0 or 1 for i.MX6DQ/i.MX6SDL.
  49725. +- mclk: should the value of mclk clock send out the sensor. unit is Hz.
  49726. +- mclk_source: should be 0 or 1 and should be the same as the setting in
  49727. + v4l2_capture.
  49728. +- cvbs: 1 for CVBS input, 0 YPbPr input. This property is only needed for
  49729. + adv7180 tv decoder.
  49730. +
  49731. +Supported Sensor
  49732. +- ov5640
  49733. +- ov5642
  49734. +- ov5640_mipi
  49735. +- adv7180
  49736. +
  49737. +
  49738. +Example for IPUv3 including capture settings on imx6q-sabresd.dts:
  49739. + ipu1: ipu@02400000 { /* IPU1 */
  49740. + compatible = "fsl,imx6q-ipuv3";
  49741. + reg = <0x02400000 0x400000>;
  49742. + interrupts = <0 5 0x04>, < 0 6 0x04>;
  49743. + clocks = <&clks 130>, <&clks 131>, <&clks 132>, <&clks 39>, <&clks 40>, <&clks 169>;
  49744. + clock-names = "ipu1", "ipu1_di0", "ipu1_di1", "ipu1_di0_sel", "ipu1_di1_sel", "ipu1_csi0";
  49745. + status = "disabled";
  49746. + };
  49747. +
  49748. +Examples for v4l2_capture:
  49749. + v4l2_cap {
  49750. + compatible = "fsl,imx6q-v4l2-capture";
  49751. + ipu_id = <0>;
  49752. + csi_id = <0>;
  49753. + mclk_source = <0>;
  49754. + status = "okay";
  49755. + };
  49756. +
  49757. +Examples for sensors:
  49758. + ov5642: ov5642@3c {
  49759. + compatible = "ovti,ov5642";
  49760. + reg = <0x3c>;
  49761. + pinctrl-names = "default";
  49762. + pinctrl-0 = <&pinctrl_ipu1_2>;
  49763. + clocks = <&clks 201>;
  49764. + clock-names = "csi_mclk";
  49765. + DOVDD-supply = <&vgen4_reg>; /* 1.8v */
  49766. + AVDD-supply = <&vgen3_reg>; /* 2.8v, on rev C board is VGEN3 */
  49767. + DVDD-supply = <&vgen2_reg>; /* 1.5v*/
  49768. + pwn-gpios = <&gpio1 16 1>; /* active low: SD1_DAT0 */
  49769. + rst-gpios = <&gpio1 17 0>; /* active high: SD1_DAT1 */
  49770. + csi_id = <0>;
  49771. + mclk = <24000000>;
  49772. + mclk_source = <0>;
  49773. + };
  49774. +
  49775. + adv7180: adv7180@21 {
  49776. + compatible = "adv,adv7180";
  49777. + reg = <0x21>;
  49778. + pinctrl-names = "default";
  49779. + pinctrl-0 = <&pinctrl_ipu1_3>;
  49780. + clocks = <&clks 201>;
  49781. + clock-names = "csi_mclk";
  49782. + DOVDD-supply = <&reg_3p3v>; /* 3.3v, enabled via 2.8 VGEN6 */
  49783. + AVDD-supply = <&reg_3p3v>; /* 1.8v */
  49784. + DVDD-supply = <&reg_3p3v>; /* 1.8v */
  49785. + PVDD-supply = <&reg_3p3v>; /* 1.8v */
  49786. + pwn-gpios = <&max7310_b 2 0>;
  49787. + csi_id = <0>;
  49788. + mclk = <24000000>;
  49789. + mclk_source = <0>;
  49790. + cvbs = <1>;
  49791. + };
  49792. diff -Nur linux-3.14.15/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt linux-linaro-stable-mx6/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt
  49793. --- linux-3.14.15/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt 1970-01-01 01:00:00.000000000 +0100
  49794. +++ linux-linaro-stable-mx6/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt 2014-08-20 19:23:45.190810115 +0200
  49795. @@ -0,0 +1,20 @@
  49796. +Device-Tree bindings for hdmi video driver
  49797. +
  49798. +Required properties:
  49799. +- compatible: value should be "fsl,imx6q-hdmi-video".
  49800. +- fsl,hdcp: define the property in dts, hdmi driver will initalize for hdcp,
  49801. + otherwise hdcp function will not supported.
  49802. +- fsl,phy_reg_vlev: hdmi phy register,Voltage Level Control Register offset 0x0e,
  49803. + adjust hdmi phy signal voltage level.
  49804. +- fsl,phy_reg_cksymtx: hdmi phy register, clock symbol and transmitter control
  49805. + register offset 0x09, adjust hdmi signal pre-emphasis.
  49806. +
  49807. +Example:
  49808. +
  49809. + hdmi_video {
  49810. + compatible = "fsl,imx6q-hdmi-video";
  49811. + fsl,hdcp;
  49812. + fsl,phy_reg_vlev = <0x0294>;
  49813. + fsl,phy_reg_cksymtx = <0x800d>;
  49814. + };
  49815. +
  49816. diff -Nur linux-3.14.15/Documentation/filesystems/hfsplus.txt linux-linaro-stable-mx6/Documentation/filesystems/hfsplus.txt
  49817. --- linux-3.14.15/Documentation/filesystems/hfsplus.txt 2014-07-31 23:51:43.000000000 +0200
  49818. +++ linux-linaro-stable-mx6/Documentation/filesystems/hfsplus.txt 2014-08-20 19:31:39.464840400 +0200
  49819. @@ -56,4 +56,4 @@
  49820. kernel source: <file:fs/hfsplus>
  49821. -Apple Technote 1150 http://developer.apple.com/technotes/tn/tn1150.html
  49822. +Apple Technote 1150 https://developer.apple.com/legacy/library/technotes/tn/tn1150.html
  49823. diff -Nur linux-3.14.15/Documentation/networking/gianfar.txt linux-linaro-stable-mx6/Documentation/networking/gianfar.txt
  49824. --- linux-3.14.15/Documentation/networking/gianfar.txt 2014-07-31 23:51:43.000000000 +0200
  49825. +++ linux-linaro-stable-mx6/Documentation/networking/gianfar.txt 2014-08-20 19:31:39.528840676 +0200
  49826. @@ -1,38 +1,8 @@
  49827. The Gianfar Ethernet Driver
  49828. -Sysfs File description
  49829. Author: Andy Fleming <afleming@freescale.com>
  49830. Updated: 2005-07-28
  49831. -SYSFS
  49832. -
  49833. -Several of the features of the gianfar driver are controlled
  49834. -through sysfs files. These are:
  49835. -
  49836. -bd_stash:
  49837. -To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
  49838. -bd_stash, echo 'off' or '0' to disable
  49839. -
  49840. -rx_stash_len:
  49841. -To stash the first n bytes of the packet in L2, echo the number
  49842. -of bytes to buf_stash_len. echo 0 to disable.
  49843. -
  49844. -WARNING: You could really screw these up if you set them too low or high!
  49845. -fifo_threshold:
  49846. -To change the number of bytes the controller needs in the
  49847. -fifo before it starts transmission, echo the number of bytes to
  49848. -fifo_thresh. Range should be 0-511.
  49849. -
  49850. -fifo_starve:
  49851. -When the FIFO has less than this many bytes during a transmit, it
  49852. -enters starve mode, and increases the priority of TX memory
  49853. -transactions. To change, echo the number of bytes to
  49854. -fifo_starve. Range should be 0-511.
  49855. -
  49856. -fifo_starve_off:
  49857. -Once in starve mode, the FIFO remains there until it has this
  49858. -many bytes. To change, echo the number of bytes to
  49859. -fifo_starve_off. Range should be 0-511.
  49860. CHECKSUM OFFLOADING
  49861. diff -Nur linux-3.14.15/drivers/ata/acard-ahci.c linux-linaro-stable-mx6/drivers/ata/acard-ahci.c
  49862. --- linux-3.14.15/drivers/ata/acard-ahci.c 2014-07-31 23:51:43.000000000 +0200
  49863. +++ linux-linaro-stable-mx6/drivers/ata/acard-ahci.c 2014-08-20 19:31:42.312852626 +0200
  49864. @@ -36,7 +36,6 @@
  49865. #include <linux/kernel.h>
  49866. #include <linux/module.h>
  49867. #include <linux/pci.h>
  49868. -#include <linux/init.h>
  49869. #include <linux/blkdev.h>
  49870. #include <linux/delay.h>
  49871. #include <linux/interrupt.h>
  49872. diff -Nur linux-3.14.15/drivers/ata/ahci.c linux-linaro-stable-mx6/drivers/ata/ahci.c
  49873. --- linux-3.14.15/drivers/ata/ahci.c 2014-07-31 23:51:43.000000000 +0200
  49874. +++ linux-linaro-stable-mx6/drivers/ata/ahci.c 2014-08-20 19:31:42.312852626 +0200
  49875. @@ -35,7 +35,6 @@
  49876. #include <linux/kernel.h>
  49877. #include <linux/module.h>
  49878. #include <linux/pci.h>
  49879. -#include <linux/init.h>
  49880. #include <linux/blkdev.h>
  49881. #include <linux/delay.h>
  49882. #include <linux/interrupt.h>
  49883. @@ -457,7 +456,6 @@
  49884. /* Promise */
  49885. { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */
  49886. - { PCI_VDEVICE(PROMISE, 0x3781), board_ahci }, /* FastTrak TX8660 ahci-mode */
  49887. /* Asmedia */
  49888. { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */
  49889. @@ -583,6 +581,7 @@
  49890. unsigned long deadline)
  49891. {
  49892. struct ata_port *ap = link->ap;
  49893. + struct ahci_host_priv *hpriv = ap->host->private_data;
  49894. bool online;
  49895. int rc;
  49896. @@ -593,7 +592,7 @@
  49897. rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
  49898. deadline, &online, NULL);
  49899. - ahci_start_engine(ap);
  49900. + hpriv->start_engine(ap);
  49901. DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
  49902. @@ -608,6 +607,7 @@
  49903. {
  49904. struct ata_port *ap = link->ap;
  49905. struct ahci_port_priv *pp = ap->private_data;
  49906. + struct ahci_host_priv *hpriv = ap->host->private_data;
  49907. u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
  49908. struct ata_taskfile tf;
  49909. bool online;
  49910. @@ -623,7 +623,7 @@
  49911. rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
  49912. deadline, &online, NULL);
  49913. - ahci_start_engine(ap);
  49914. + hpriv->start_engine(ap);
  49915. /* The pseudo configuration device on SIMG4726 attached to
  49916. * ASUS P5W-DH Deluxe doesn't send signature FIS after
  49917. @@ -1119,6 +1119,17 @@
  49918. return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
  49919. }
  49920. +static bool ahci_broken_devslp(struct pci_dev *pdev)
  49921. +{
  49922. + /* device with broken DEVSLP but still showing SDS capability */
  49923. + static const struct pci_device_id ids[] = {
  49924. + { PCI_VDEVICE(INTEL, 0x0f23)}, /* Valleyview SoC */
  49925. + {}
  49926. + };
  49927. +
  49928. + return pci_match_id(ids, pdev);
  49929. +}
  49930. +
  49931. #ifdef CONFIG_ATA_ACPI
  49932. static void ahci_gtf_filter_workaround(struct ata_host *host)
  49933. {
  49934. @@ -1370,6 +1381,10 @@
  49935. hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar];
  49936. + /* must set flag prior to save config in order to take effect */
  49937. + if (ahci_broken_devslp(pdev))
  49938. + hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
  49939. +
  49940. /* save initial config */
  49941. ahci_pci_save_initial_config(pdev, hpriv);
  49942. diff -Nur linux-3.14.15/drivers/ata/ahci.h linux-linaro-stable-mx6/drivers/ata/ahci.h
  49943. --- linux-3.14.15/drivers/ata/ahci.h 2014-07-31 23:51:43.000000000 +0200
  49944. +++ linux-linaro-stable-mx6/drivers/ata/ahci.h 2014-08-20 19:31:42.312852626 +0200
  49945. @@ -37,6 +37,8 @@
  49946. #include <linux/clk.h>
  49947. #include <linux/libata.h>
  49948. +#include <linux/phy/phy.h>
  49949. +#include <linux/regulator/consumer.h>
  49950. /* Enclosure Management Control */
  49951. #define EM_CTRL_MSG_TYPE 0x000f0000
  49952. @@ -51,6 +53,7 @@
  49953. enum {
  49954. AHCI_MAX_PORTS = 32,
  49955. + AHCI_MAX_CLKS = 3,
  49956. AHCI_MAX_SG = 168, /* hardware max is 64K */
  49957. AHCI_DMA_BOUNDARY = 0xffffffff,
  49958. AHCI_MAX_CMDS = 32,
  49959. @@ -233,6 +236,8 @@
  49960. port start (wait until
  49961. error-handling stage) */
  49962. AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */
  49963. + AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */
  49964. + AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */
  49965. /* ap->flags bits */
  49966. @@ -322,8 +327,17 @@
  49967. u32 em_loc; /* enclosure management location */
  49968. u32 em_buf_sz; /* EM buffer size in byte */
  49969. u32 em_msg_type; /* EM message type */
  49970. - struct clk *clk; /* Only for platforms supporting clk */
  49971. + bool got_runtime_pm; /* Did we do pm_runtime_get? */
  49972. + struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
  49973. + struct regulator *target_pwr; /* Optional */
  49974. + struct phy *phy; /* If platform uses phy */
  49975. void *plat_data; /* Other platform data */
  49976. + /*
  49977. + * Optional ahci_start_engine override, if not set this gets set to the
  49978. + * default ahci_start_engine during ahci_save_initial_config, this can
  49979. + * be overridden anytime before the host is activated.
  49980. + */
  49981. + void (*start_engine)(struct ata_port *ap);
  49982. };
  49983. extern int ahci_ignore_sss;
  49984. diff -Nur linux-3.14.15/drivers/ata/ahci_imx.c linux-linaro-stable-mx6/drivers/ata/ahci_imx.c
  49985. --- linux-3.14.15/drivers/ata/ahci_imx.c 2014-07-31 23:51:43.000000000 +0200
  49986. +++ linux-linaro-stable-mx6/drivers/ata/ahci_imx.c 2014-08-20 19:31:42.312852626 +0200
  49987. @@ -26,12 +26,29 @@
  49988. #include <linux/mfd/syscon.h>
  49989. #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  49990. #include <linux/libata.h>
  49991. +#include <linux/busfreq-imx6.h>
  49992. #include "ahci.h"
  49993. enum {
  49994. - PORT_PHY_CTL = 0x178, /* Port0 PHY Control */
  49995. - PORT_PHY_CTL_PDDQ_LOC = 0x100000, /* PORT_PHY_CTL bits */
  49996. - HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
  49997. + /* Timer 1-ms Register */
  49998. + IMX_TIMER1MS = 0x00e0,
  49999. + /* Port0 PHY Control Register */
  50000. + IMX_P0PHYCR = 0x0178,
  50001. + IMX_P0PHYCR_TEST_PDDQ = 1 << 20,
  50002. + IMX_P0PHYCR_CR_READ = 1 << 19,
  50003. + IMX_P0PHYCR_CR_WRITE = 1 << 18,
  50004. + IMX_P0PHYCR_CR_CAP_DATA = 1 << 17,
  50005. + IMX_P0PHYCR_CR_CAP_ADDR = 1 << 16,
  50006. + /* Port0 PHY Status Register */
  50007. + IMX_P0PHYSR = 0x017c,
  50008. + IMX_P0PHYSR_CR_ACK = 1 << 18,
  50009. + IMX_P0PHYSR_CR_DATA_OUT = 0xffff << 0,
  50010. + /* Lane0 Output Status Register */
  50011. + IMX_LANE0_OUT_STAT = 0x2003,
  50012. + IMX_LANE0_OUT_STAT_RX_PLL_STATE = 1 << 1,
  50013. + /* Clock Reset Register */
  50014. + IMX_CLOCK_RESET = 0x7f3f,
  50015. + IMX_CLOCK_RESET_RESET = 1 << 0,
  50016. };
  50017. enum ahci_imx_type {
  50018. @@ -42,62 +59,230 @@
  50019. struct imx_ahci_priv {
  50020. struct platform_device *ahci_pdev;
  50021. enum ahci_imx_type type;
  50022. -
  50023. - /* i.MX53 clock */
  50024. - struct clk *sata_gate_clk;
  50025. - /* Common clock */
  50026. - struct clk *sata_ref_clk;
  50027. struct clk *ahb_clk;
  50028. -
  50029. struct regmap *gpr;
  50030. bool no_device;
  50031. bool first_time;
  50032. + u32 phy_params;
  50033. };
  50034. static int ahci_imx_hotplug;
  50035. module_param_named(hotplug, ahci_imx_hotplug, int, 0644);
  50036. MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)");
  50037. -static int imx_sata_clock_enable(struct device *dev)
  50038. +static void ahci_imx_host_stop(struct ata_host *host);
  50039. +
  50040. +static int imx_phy_crbit_assert(void __iomem *mmio, u32 bit, bool assert)
  50041. +{
  50042. + int timeout = 10;
  50043. + u32 crval;
  50044. + u32 srval;
  50045. +
  50046. + /* Assert or deassert the bit */
  50047. + crval = readl(mmio + IMX_P0PHYCR);
  50048. + if (assert)
  50049. + crval |= bit;
  50050. + else
  50051. + crval &= ~bit;
  50052. + writel(crval, mmio + IMX_P0PHYCR);
  50053. +
  50054. + /* Wait for the cr_ack signal */
  50055. + do {
  50056. + srval = readl(mmio + IMX_P0PHYSR);
  50057. + if ((assert ? srval : ~srval) & IMX_P0PHYSR_CR_ACK)
  50058. + break;
  50059. + usleep_range(100, 200);
  50060. + } while (--timeout);
  50061. +
  50062. + return timeout ? 0 : -ETIMEDOUT;
  50063. +}
  50064. +
  50065. +static int imx_phy_reg_addressing(u16 addr, void __iomem *mmio)
  50066. {
  50067. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  50068. + u32 crval = addr;
  50069. int ret;
  50070. - if (imxpriv->type == AHCI_IMX53) {
  50071. - ret = clk_prepare_enable(imxpriv->sata_gate_clk);
  50072. - if (ret < 0) {
  50073. - dev_err(dev, "prepare-enable sata_gate clock err:%d\n",
  50074. - ret);
  50075. - return ret;
  50076. - }
  50077. + /* Supply the address on cr_data_in */
  50078. + writel(crval, mmio + IMX_P0PHYCR);
  50079. +
  50080. + /* Assert the cr_cap_addr signal */
  50081. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, true);
  50082. + if (ret)
  50083. + return ret;
  50084. +
  50085. + /* Deassert cr_cap_addr */
  50086. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, false);
  50087. + if (ret)
  50088. + return ret;
  50089. +
  50090. + return 0;
  50091. +}
  50092. +
  50093. +static int imx_phy_reg_write(u16 val, void __iomem *mmio)
  50094. +{
  50095. + u32 crval = val;
  50096. + int ret;
  50097. +
  50098. + /* Supply the data on cr_data_in */
  50099. + writel(crval, mmio + IMX_P0PHYCR);
  50100. +
  50101. + /* Assert the cr_cap_data signal */
  50102. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, true);
  50103. + if (ret)
  50104. + return ret;
  50105. +
  50106. + /* Deassert cr_cap_data */
  50107. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, false);
  50108. + if (ret)
  50109. + return ret;
  50110. +
  50111. + if (val & IMX_CLOCK_RESET_RESET) {
  50112. + /*
  50113. + * In case we're resetting the phy, it's unable to acknowledge,
  50114. + * so we return immediately here.
  50115. + */
  50116. + crval |= IMX_P0PHYCR_CR_WRITE;
  50117. + writel(crval, mmio + IMX_P0PHYCR);
  50118. + goto out;
  50119. }
  50120. - ret = clk_prepare_enable(imxpriv->sata_ref_clk);
  50121. - if (ret < 0) {
  50122. - dev_err(dev, "prepare-enable sata_ref clock err:%d\n",
  50123. - ret);
  50124. - goto clk_err;
  50125. + /* Assert the cr_write signal */
  50126. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, true);
  50127. + if (ret)
  50128. + return ret;
  50129. +
  50130. + /* Deassert cr_write */
  50131. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, false);
  50132. + if (ret)
  50133. + return ret;
  50134. +
  50135. +out:
  50136. + return 0;
  50137. +}
  50138. +
  50139. +static int imx_phy_reg_read(u16 *val, void __iomem *mmio)
  50140. +{
  50141. + int ret;
  50142. +
  50143. + /* Assert the cr_read signal */
  50144. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, true);
  50145. + if (ret)
  50146. + return ret;
  50147. +
  50148. + /* Capture the data from cr_data_out[] */
  50149. + *val = readl(mmio + IMX_P0PHYSR) & IMX_P0PHYSR_CR_DATA_OUT;
  50150. +
  50151. + /* Deassert cr_read */
  50152. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, false);
  50153. + if (ret)
  50154. + return ret;
  50155. +
  50156. + return 0;
  50157. +}
  50158. +
  50159. +static int imx_sata_phy_reset(struct ahci_host_priv *hpriv)
  50160. +{
  50161. + void __iomem *mmio = hpriv->mmio;
  50162. + int timeout = 10;
  50163. + u16 val;
  50164. + int ret;
  50165. +
  50166. + /* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */
  50167. + ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio);
  50168. + if (ret)
  50169. + return ret;
  50170. + ret = imx_phy_reg_write(IMX_CLOCK_RESET_RESET, mmio);
  50171. + if (ret)
  50172. + return ret;
  50173. +
  50174. + /* Wait for PHY RX_PLL to be stable */
  50175. + do {
  50176. + usleep_range(100, 200);
  50177. + ret = imx_phy_reg_addressing(IMX_LANE0_OUT_STAT, mmio);
  50178. + if (ret)
  50179. + return ret;
  50180. + ret = imx_phy_reg_read(&val, mmio);
  50181. + if (ret)
  50182. + return ret;
  50183. + if (val & IMX_LANE0_OUT_STAT_RX_PLL_STATE)
  50184. + break;
  50185. + } while (--timeout);
  50186. +
  50187. + return timeout ? 0 : -ETIMEDOUT;
  50188. +}
  50189. +
  50190. +static int imx_sata_enable(struct ahci_host_priv *hpriv)
  50191. +{
  50192. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  50193. + struct device *dev = &imxpriv->ahci_pdev->dev;
  50194. + int ret;
  50195. +
  50196. + if (imxpriv->no_device)
  50197. + return 0;
  50198. +
  50199. + if (hpriv->target_pwr) {
  50200. + ret = regulator_enable(hpriv->target_pwr);
  50201. + if (ret)
  50202. + return ret;
  50203. }
  50204. + request_bus_freq(BUS_FREQ_HIGH);
  50205. +
  50206. + ret = ahci_platform_enable_clks(hpriv);
  50207. + if (ret < 0)
  50208. + goto disable_regulator;
  50209. +
  50210. if (imxpriv->type == AHCI_IMX6Q) {
  50211. + /*
  50212. + * set PHY Paremeters, two steps to configure the GPR13,
  50213. + * one write for rest of parameters, mask of first write
  50214. + * is 0x07ffffff, and the other one write for setting
  50215. + * the mpll_clk_en.
  50216. + */
  50217. + regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  50218. + IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK |
  50219. + IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK |
  50220. + IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK |
  50221. + IMX6Q_GPR13_SATA_SPD_MODE_MASK |
  50222. + IMX6Q_GPR13_SATA_MPLL_SS_EN |
  50223. + IMX6Q_GPR13_SATA_TX_ATTEN_MASK |
  50224. + IMX6Q_GPR13_SATA_TX_BOOST_MASK |
  50225. + IMX6Q_GPR13_SATA_TX_LVL_MASK |
  50226. + IMX6Q_GPR13_SATA_MPLL_CLK_EN |
  50227. + IMX6Q_GPR13_SATA_TX_EDGE_RATE,
  50228. + imxpriv->phy_params);
  50229. regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  50230. IMX6Q_GPR13_SATA_MPLL_CLK_EN,
  50231. IMX6Q_GPR13_SATA_MPLL_CLK_EN);
  50232. +
  50233. + usleep_range(100, 200);
  50234. +
  50235. + ret = imx_sata_phy_reset(hpriv);
  50236. + if (ret) {
  50237. + dev_err(dev, "failed to reset phy: %d\n", ret);
  50238. + goto disable_regulator;
  50239. + }
  50240. }
  50241. usleep_range(1000, 2000);
  50242. return 0;
  50243. -clk_err:
  50244. - if (imxpriv->type == AHCI_IMX53)
  50245. - clk_disable_unprepare(imxpriv->sata_gate_clk);
  50246. +disable_regulator:
  50247. + release_bus_freq(BUS_FREQ_HIGH);
  50248. +
  50249. + if (hpriv->target_pwr)
  50250. + regulator_disable(hpriv->target_pwr);
  50251. +
  50252. return ret;
  50253. }
  50254. -static void imx_sata_clock_disable(struct device *dev)
  50255. +static void imx_sata_disable(struct ahci_host_priv *hpriv)
  50256. {
  50257. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  50258. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  50259. +
  50260. + if (imxpriv->no_device)
  50261. + return;
  50262. if (imxpriv->type == AHCI_IMX6Q) {
  50263. regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  50264. @@ -105,10 +290,12 @@
  50265. !IMX6Q_GPR13_SATA_MPLL_CLK_EN);
  50266. }
  50267. - clk_disable_unprepare(imxpriv->sata_ref_clk);
  50268. + ahci_platform_disable_clks(hpriv);
  50269. - if (imxpriv->type == AHCI_IMX53)
  50270. - clk_disable_unprepare(imxpriv->sata_gate_clk);
  50271. + release_bus_freq(BUS_FREQ_HIGH);
  50272. +
  50273. + if (hpriv->target_pwr)
  50274. + regulator_disable(hpriv->target_pwr);
  50275. }
  50276. static void ahci_imx_error_handler(struct ata_port *ap)
  50277. @@ -118,7 +305,7 @@
  50278. struct ata_host *host = dev_get_drvdata(ap->dev);
  50279. struct ahci_host_priv *hpriv = host->private_data;
  50280. void __iomem *mmio = hpriv->mmio;
  50281. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent);
  50282. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  50283. ahci_error_handler(ap);
  50284. @@ -134,17 +321,23 @@
  50285. * without full reset once the pddq mode is enabled making it
  50286. * impossible to use as part of libata LPM.
  50287. */
  50288. - reg_val = readl(mmio + PORT_PHY_CTL);
  50289. - writel(reg_val | PORT_PHY_CTL_PDDQ_LOC, mmio + PORT_PHY_CTL);
  50290. - imx_sata_clock_disable(ap->dev);
  50291. + reg_val = readl(mmio + IMX_P0PHYCR);
  50292. + writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR);
  50293. + imx_sata_disable(hpriv);
  50294. imxpriv->no_device = true;
  50295. +
  50296. + dev_info(ap->dev, "no device found, disabling link.\n");
  50297. + dev_info(ap->dev, "pass " MODULE_PARAM_PREFIX
  50298. + ".hotplug=1 to enable hotplug\n");
  50299. }
  50300. static int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
  50301. unsigned long deadline)
  50302. {
  50303. struct ata_port *ap = link->ap;
  50304. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent);
  50305. + struct ata_host *host = dev_get_drvdata(ap->dev);
  50306. + struct ahci_host_priv *hpriv = host->private_data;
  50307. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  50308. int ret = -EIO;
  50309. if (imxpriv->type == AHCI_IMX53)
  50310. @@ -156,7 +349,8 @@
  50311. }
  50312. static struct ata_port_operations ahci_imx_ops = {
  50313. - .inherits = &ahci_platform_ops,
  50314. + .inherits = &ahci_ops,
  50315. + .host_stop = ahci_imx_host_stop,
  50316. .error_handler = ahci_imx_error_handler,
  50317. .softreset = ahci_imx_softreset,
  50318. };
  50319. @@ -168,234 +362,306 @@
  50320. .port_ops = &ahci_imx_ops,
  50321. };
  50322. -static int imx_sata_init(struct device *dev, void __iomem *mmio)
  50323. -{
  50324. - int ret = 0;
  50325. - unsigned int reg_val;
  50326. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  50327. -
  50328. - ret = imx_sata_clock_enable(dev);
  50329. - if (ret < 0)
  50330. - return ret;
  50331. +static const struct of_device_id imx_ahci_of_match[] = {
  50332. + { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
  50333. + { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
  50334. + {},
  50335. +};
  50336. +MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
  50337. - /*
  50338. - * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
  50339. - * and IP vendor specific register HOST_TIMER1MS.
  50340. - * Configure CAP_SSS (support stagered spin up).
  50341. - * Implement the port0.
  50342. - * Get the ahb clock rate, and configure the TIMER1MS register.
  50343. - */
  50344. - reg_val = readl(mmio + HOST_CAP);
  50345. - if (!(reg_val & HOST_CAP_SSS)) {
  50346. - reg_val |= HOST_CAP_SSS;
  50347. - writel(reg_val, mmio + HOST_CAP);
  50348. - }
  50349. - reg_val = readl(mmio + HOST_PORTS_IMPL);
  50350. - if (!(reg_val & 0x1)) {
  50351. - reg_val |= 0x1;
  50352. - writel(reg_val, mmio + HOST_PORTS_IMPL);
  50353. - }
  50354. +struct reg_value {
  50355. + u32 of_value;
  50356. + u32 reg_value;
  50357. +};
  50358. - reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
  50359. - writel(reg_val, mmio + HOST_TIMER1MS);
  50360. +struct reg_property {
  50361. + const char *name;
  50362. + const struct reg_value *values;
  50363. + size_t num_values;
  50364. + u32 def_value;
  50365. + u32 set_value;
  50366. +};
  50367. - return 0;
  50368. -}
  50369. +static const struct reg_value gpr13_tx_level[] = {
  50370. + { 937, IMX6Q_GPR13_SATA_TX_LVL_0_937_V },
  50371. + { 947, IMX6Q_GPR13_SATA_TX_LVL_0_947_V },
  50372. + { 957, IMX6Q_GPR13_SATA_TX_LVL_0_957_V },
  50373. + { 966, IMX6Q_GPR13_SATA_TX_LVL_0_966_V },
  50374. + { 976, IMX6Q_GPR13_SATA_TX_LVL_0_976_V },
  50375. + { 986, IMX6Q_GPR13_SATA_TX_LVL_0_986_V },
  50376. + { 996, IMX6Q_GPR13_SATA_TX_LVL_0_996_V },
  50377. + { 1005, IMX6Q_GPR13_SATA_TX_LVL_1_005_V },
  50378. + { 1015, IMX6Q_GPR13_SATA_TX_LVL_1_015_V },
  50379. + { 1025, IMX6Q_GPR13_SATA_TX_LVL_1_025_V },
  50380. + { 1035, IMX6Q_GPR13_SATA_TX_LVL_1_035_V },
  50381. + { 1045, IMX6Q_GPR13_SATA_TX_LVL_1_045_V },
  50382. + { 1054, IMX6Q_GPR13_SATA_TX_LVL_1_054_V },
  50383. + { 1064, IMX6Q_GPR13_SATA_TX_LVL_1_064_V },
  50384. + { 1074, IMX6Q_GPR13_SATA_TX_LVL_1_074_V },
  50385. + { 1084, IMX6Q_GPR13_SATA_TX_LVL_1_084_V },
  50386. + { 1094, IMX6Q_GPR13_SATA_TX_LVL_1_094_V },
  50387. + { 1104, IMX6Q_GPR13_SATA_TX_LVL_1_104_V },
  50388. + { 1113, IMX6Q_GPR13_SATA_TX_LVL_1_113_V },
  50389. + { 1123, IMX6Q_GPR13_SATA_TX_LVL_1_123_V },
  50390. + { 1133, IMX6Q_GPR13_SATA_TX_LVL_1_133_V },
  50391. + { 1143, IMX6Q_GPR13_SATA_TX_LVL_1_143_V },
  50392. + { 1152, IMX6Q_GPR13_SATA_TX_LVL_1_152_V },
  50393. + { 1162, IMX6Q_GPR13_SATA_TX_LVL_1_162_V },
  50394. + { 1172, IMX6Q_GPR13_SATA_TX_LVL_1_172_V },
  50395. + { 1182, IMX6Q_GPR13_SATA_TX_LVL_1_182_V },
  50396. + { 1191, IMX6Q_GPR13_SATA_TX_LVL_1_191_V },
  50397. + { 1201, IMX6Q_GPR13_SATA_TX_LVL_1_201_V },
  50398. + { 1211, IMX6Q_GPR13_SATA_TX_LVL_1_211_V },
  50399. + { 1221, IMX6Q_GPR13_SATA_TX_LVL_1_221_V },
  50400. + { 1230, IMX6Q_GPR13_SATA_TX_LVL_1_230_V },
  50401. + { 1240, IMX6Q_GPR13_SATA_TX_LVL_1_240_V }
  50402. +};
  50403. -static void imx_sata_exit(struct device *dev)
  50404. -{
  50405. - imx_sata_clock_disable(dev);
  50406. -}
  50407. +static const struct reg_value gpr13_tx_boost[] = {
  50408. + { 0, IMX6Q_GPR13_SATA_TX_BOOST_0_00_DB },
  50409. + { 370, IMX6Q_GPR13_SATA_TX_BOOST_0_37_DB },
  50410. + { 740, IMX6Q_GPR13_SATA_TX_BOOST_0_74_DB },
  50411. + { 1110, IMX6Q_GPR13_SATA_TX_BOOST_1_11_DB },
  50412. + { 1480, IMX6Q_GPR13_SATA_TX_BOOST_1_48_DB },
  50413. + { 1850, IMX6Q_GPR13_SATA_TX_BOOST_1_85_DB },
  50414. + { 2220, IMX6Q_GPR13_SATA_TX_BOOST_2_22_DB },
  50415. + { 2590, IMX6Q_GPR13_SATA_TX_BOOST_2_59_DB },
  50416. + { 2960, IMX6Q_GPR13_SATA_TX_BOOST_2_96_DB },
  50417. + { 3330, IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB },
  50418. + { 3700, IMX6Q_GPR13_SATA_TX_BOOST_3_70_DB },
  50419. + { 4070, IMX6Q_GPR13_SATA_TX_BOOST_4_07_DB },
  50420. + { 4440, IMX6Q_GPR13_SATA_TX_BOOST_4_44_DB },
  50421. + { 4810, IMX6Q_GPR13_SATA_TX_BOOST_4_81_DB },
  50422. + { 5280, IMX6Q_GPR13_SATA_TX_BOOST_5_28_DB },
  50423. + { 5750, IMX6Q_GPR13_SATA_TX_BOOST_5_75_DB }
  50424. +};
  50425. -static int imx_ahci_suspend(struct device *dev)
  50426. -{
  50427. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  50428. +static const struct reg_value gpr13_tx_atten[] = {
  50429. + { 8, IMX6Q_GPR13_SATA_TX_ATTEN_8_16 },
  50430. + { 9, IMX6Q_GPR13_SATA_TX_ATTEN_9_16 },
  50431. + { 10, IMX6Q_GPR13_SATA_TX_ATTEN_10_16 },
  50432. + { 12, IMX6Q_GPR13_SATA_TX_ATTEN_12_16 },
  50433. + { 14, IMX6Q_GPR13_SATA_TX_ATTEN_14_16 },
  50434. + { 16, IMX6Q_GPR13_SATA_TX_ATTEN_16_16 },
  50435. +};
  50436. - /*
  50437. - * If no_device is set, The CLKs had been gated off in the
  50438. - * initialization so don't do it again here.
  50439. - */
  50440. - if (!imxpriv->no_device)
  50441. - imx_sata_clock_disable(dev);
  50442. +static const struct reg_value gpr13_rx_eq[] = {
  50443. + { 500, IMX6Q_GPR13_SATA_RX_EQ_VAL_0_5_DB },
  50444. + { 1000, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_0_DB },
  50445. + { 1500, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_5_DB },
  50446. + { 2000, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_0_DB },
  50447. + { 2500, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_5_DB },
  50448. + { 3000, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB },
  50449. + { 3500, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_5_DB },
  50450. + { 4000, IMX6Q_GPR13_SATA_RX_EQ_VAL_4_0_DB },
  50451. +};
  50452. - return 0;
  50453. -}
  50454. +static const struct reg_property gpr13_props[] = {
  50455. + {
  50456. + .name = "fsl,transmit-level-mV",
  50457. + .values = gpr13_tx_level,
  50458. + .num_values = ARRAY_SIZE(gpr13_tx_level),
  50459. + .def_value = IMX6Q_GPR13_SATA_TX_LVL_1_025_V,
  50460. + }, {
  50461. + .name = "fsl,transmit-boost-mdB",
  50462. + .values = gpr13_tx_boost,
  50463. + .num_values = ARRAY_SIZE(gpr13_tx_boost),
  50464. + .def_value = IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB,
  50465. + }, {
  50466. + .name = "fsl,transmit-atten-16ths",
  50467. + .values = gpr13_tx_atten,
  50468. + .num_values = ARRAY_SIZE(gpr13_tx_atten),
  50469. + .def_value = IMX6Q_GPR13_SATA_TX_ATTEN_9_16,
  50470. + }, {
  50471. + .name = "fsl,receive-eq-mdB",
  50472. + .values = gpr13_rx_eq,
  50473. + .num_values = ARRAY_SIZE(gpr13_rx_eq),
  50474. + .def_value = IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB,
  50475. + }, {
  50476. + .name = "fsl,no-spread-spectrum",
  50477. + .def_value = IMX6Q_GPR13_SATA_MPLL_SS_EN,
  50478. + .set_value = 0,
  50479. + },
  50480. +};
  50481. -static int imx_ahci_resume(struct device *dev)
  50482. +static u32 imx_ahci_parse_props(struct device *dev,
  50483. + const struct reg_property *prop, size_t num)
  50484. {
  50485. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  50486. - int ret = 0;
  50487. -
  50488. - if (!imxpriv->no_device)
  50489. - ret = imx_sata_clock_enable(dev);
  50490. + struct device_node *np = dev->of_node;
  50491. + u32 reg_value = 0;
  50492. + int i, j;
  50493. +
  50494. + for (i = 0; i < num; i++, prop++) {
  50495. + u32 of_val;
  50496. +
  50497. + if (prop->num_values == 0) {
  50498. + if (of_property_read_bool(np, prop->name))
  50499. + reg_value |= prop->set_value;
  50500. + else
  50501. + reg_value |= prop->def_value;
  50502. + continue;
  50503. + }
  50504. - return ret;
  50505. -}
  50506. + if (of_property_read_u32(np, prop->name, &of_val)) {
  50507. + dev_info(dev, "%s not specified, using %08x\n",
  50508. + prop->name, prop->def_value);
  50509. + reg_value |= prop->def_value;
  50510. + continue;
  50511. + }
  50512. -static struct ahci_platform_data imx_sata_pdata = {
  50513. - .init = imx_sata_init,
  50514. - .exit = imx_sata_exit,
  50515. - .ata_port_info = &ahci_imx_port_info,
  50516. - .suspend = imx_ahci_suspend,
  50517. - .resume = imx_ahci_resume,
  50518. + for (j = 0; j < prop->num_values; j++) {
  50519. + if (prop->values[j].of_value == of_val) {
  50520. + dev_info(dev, "%s value %u, using %08x\n",
  50521. + prop->name, of_val, prop->values[j].reg_value);
  50522. + reg_value |= prop->values[j].reg_value;
  50523. + break;
  50524. + }
  50525. + }
  50526. -};
  50527. + if (j == prop->num_values) {
  50528. + dev_err(dev, "DT property %s is not a valid value\n",
  50529. + prop->name);
  50530. + reg_value |= prop->def_value;
  50531. + }
  50532. + }
  50533. -static const struct of_device_id imx_ahci_of_match[] = {
  50534. - { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
  50535. - { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
  50536. - {},
  50537. -};
  50538. -MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
  50539. + return reg_value;
  50540. +}
  50541. static int imx_ahci_probe(struct platform_device *pdev)
  50542. {
  50543. struct device *dev = &pdev->dev;
  50544. - struct resource *mem, *irq, res[2];
  50545. const struct of_device_id *of_id;
  50546. - enum ahci_imx_type type;
  50547. - const struct ahci_platform_data *pdata = NULL;
  50548. + struct ahci_host_priv *hpriv;
  50549. struct imx_ahci_priv *imxpriv;
  50550. - struct device *ahci_dev;
  50551. - struct platform_device *ahci_pdev;
  50552. + unsigned int reg_val;
  50553. int ret;
  50554. of_id = of_match_device(imx_ahci_of_match, dev);
  50555. if (!of_id)
  50556. return -EINVAL;
  50557. - type = (enum ahci_imx_type)of_id->data;
  50558. - pdata = &imx_sata_pdata;
  50559. -
  50560. imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
  50561. - if (!imxpriv) {
  50562. - dev_err(dev, "can't alloc ahci_host_priv\n");
  50563. + if (!imxpriv)
  50564. return -ENOMEM;
  50565. - }
  50566. -
  50567. - ahci_pdev = platform_device_alloc("ahci", -1);
  50568. - if (!ahci_pdev)
  50569. - return -ENODEV;
  50570. -
  50571. - ahci_dev = &ahci_pdev->dev;
  50572. - ahci_dev->parent = dev;
  50573. + imxpriv->ahci_pdev = pdev;
  50574. imxpriv->no_device = false;
  50575. imxpriv->first_time = true;
  50576. - imxpriv->type = type;
  50577. -
  50578. + imxpriv->type = (enum ahci_imx_type)of_id->data;
  50579. imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
  50580. if (IS_ERR(imxpriv->ahb_clk)) {
  50581. dev_err(dev, "can't get ahb clock.\n");
  50582. - ret = PTR_ERR(imxpriv->ahb_clk);
  50583. - goto err_out;
  50584. - }
  50585. -
  50586. - if (type == AHCI_IMX53) {
  50587. - imxpriv->sata_gate_clk = devm_clk_get(dev, "sata_gate");
  50588. - if (IS_ERR(imxpriv->sata_gate_clk)) {
  50589. - dev_err(dev, "can't get sata_gate clock.\n");
  50590. - ret = PTR_ERR(imxpriv->sata_gate_clk);
  50591. - goto err_out;
  50592. - }
  50593. - }
  50594. -
  50595. - imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
  50596. - if (IS_ERR(imxpriv->sata_ref_clk)) {
  50597. - dev_err(dev, "can't get sata_ref clock.\n");
  50598. - ret = PTR_ERR(imxpriv->sata_ref_clk);
  50599. - goto err_out;
  50600. + return PTR_ERR(imxpriv->ahb_clk);
  50601. }
  50602. - imxpriv->ahci_pdev = ahci_pdev;
  50603. - platform_set_drvdata(pdev, imxpriv);
  50604. -
  50605. - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  50606. - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  50607. - if (!mem || !irq) {
  50608. - dev_err(dev, "no mmio/irq resource\n");
  50609. - ret = -ENOMEM;
  50610. - goto err_out;
  50611. - }
  50612. -
  50613. - res[0] = *mem;
  50614. - res[1] = *irq;
  50615. -
  50616. - ahci_dev->coherent_dma_mask = DMA_BIT_MASK(32);
  50617. - ahci_dev->dma_mask = &ahci_dev->coherent_dma_mask;
  50618. - ahci_dev->of_node = dev->of_node;
  50619. + if (imxpriv->type == AHCI_IMX6Q) {
  50620. + u32 reg_value;
  50621. - if (type == AHCI_IMX6Q) {
  50622. imxpriv->gpr = syscon_regmap_lookup_by_compatible(
  50623. "fsl,imx6q-iomuxc-gpr");
  50624. if (IS_ERR(imxpriv->gpr)) {
  50625. dev_err(dev,
  50626. "failed to find fsl,imx6q-iomux-gpr regmap\n");
  50627. - ret = PTR_ERR(imxpriv->gpr);
  50628. - goto err_out;
  50629. + return PTR_ERR(imxpriv->gpr);
  50630. }
  50631. - /*
  50632. - * Set PHY Paremeters, two steps to configure the GPR13,
  50633. - * one write for rest of parameters, mask of first write
  50634. - * is 0x07fffffe, and the other one write for setting
  50635. - * the mpll_clk_en happens in imx_sata_clock_enable().
  50636. - */
  50637. - regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  50638. - IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK |
  50639. - IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK |
  50640. - IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK |
  50641. - IMX6Q_GPR13_SATA_SPD_MODE_MASK |
  50642. - IMX6Q_GPR13_SATA_MPLL_SS_EN |
  50643. - IMX6Q_GPR13_SATA_TX_ATTEN_MASK |
  50644. - IMX6Q_GPR13_SATA_TX_BOOST_MASK |
  50645. - IMX6Q_GPR13_SATA_TX_LVL_MASK |
  50646. - IMX6Q_GPR13_SATA_MPLL_CLK_EN |
  50647. - IMX6Q_GPR13_SATA_TX_EDGE_RATE,
  50648. - IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB |
  50649. + reg_value = imx_ahci_parse_props(dev, gpr13_props,
  50650. + ARRAY_SIZE(gpr13_props));
  50651. +
  50652. + imxpriv->phy_params =
  50653. IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
  50654. IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
  50655. IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
  50656. - IMX6Q_GPR13_SATA_MPLL_SS_EN |
  50657. - IMX6Q_GPR13_SATA_TX_ATTEN_9_16 |
  50658. - IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB |
  50659. - IMX6Q_GPR13_SATA_TX_LVL_1_025_V);
  50660. + reg_value;
  50661. }
  50662. - ret = platform_device_add_resources(ahci_pdev, res, 2);
  50663. + hpriv = ahci_platform_get_resources(pdev);
  50664. + if (IS_ERR(hpriv))
  50665. + return PTR_ERR(hpriv);
  50666. +
  50667. + hpriv->plat_data = imxpriv;
  50668. +
  50669. + ret = imx_sata_enable(hpriv);
  50670. if (ret)
  50671. - goto err_out;
  50672. + return ret;
  50673. - ret = platform_device_add_data(ahci_pdev, pdata, sizeof(*pdata));
  50674. + /*
  50675. + * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
  50676. + * and IP vendor specific register IMX_TIMER1MS.
  50677. + * Configure CAP_SSS (support stagered spin up).
  50678. + * Implement the port0.
  50679. + * Get the ahb clock rate, and configure the TIMER1MS register.
  50680. + */
  50681. + reg_val = readl(hpriv->mmio + HOST_CAP);
  50682. + if (!(reg_val & HOST_CAP_SSS)) {
  50683. + reg_val |= HOST_CAP_SSS;
  50684. + writel(reg_val, hpriv->mmio + HOST_CAP);
  50685. + }
  50686. + reg_val = readl(hpriv->mmio + HOST_PORTS_IMPL);
  50687. + if (!(reg_val & 0x1)) {
  50688. + reg_val |= 0x1;
  50689. + writel(reg_val, hpriv->mmio + HOST_PORTS_IMPL);
  50690. + }
  50691. +
  50692. + reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
  50693. + writel(reg_val, hpriv->mmio + IMX_TIMER1MS);
  50694. +
  50695. + ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
  50696. + 0, 0, 0);
  50697. if (ret)
  50698. - goto err_out;
  50699. + imx_sata_disable(hpriv);
  50700. +
  50701. + return ret;
  50702. +}
  50703. - ret = platform_device_add(ahci_pdev);
  50704. - if (ret) {
  50705. -err_out:
  50706. - platform_device_put(ahci_pdev);
  50707. +static void ahci_imx_host_stop(struct ata_host *host)
  50708. +{
  50709. + struct ahci_host_priv *hpriv = host->private_data;
  50710. +
  50711. + imx_sata_disable(hpriv);
  50712. +}
  50713. +
  50714. +#ifdef CONFIG_PM_SLEEP
  50715. +static int imx_ahci_suspend(struct device *dev)
  50716. +{
  50717. + struct ata_host *host = dev_get_drvdata(dev);
  50718. + struct ahci_host_priv *hpriv = host->private_data;
  50719. + int ret;
  50720. +
  50721. + ret = ahci_platform_suspend_host(dev);
  50722. + if (ret)
  50723. return ret;
  50724. - }
  50725. +
  50726. + imx_sata_disable(hpriv);
  50727. return 0;
  50728. }
  50729. -static int imx_ahci_remove(struct platform_device *pdev)
  50730. +static int imx_ahci_resume(struct device *dev)
  50731. {
  50732. - struct imx_ahci_priv *imxpriv = platform_get_drvdata(pdev);
  50733. - struct platform_device *ahci_pdev = imxpriv->ahci_pdev;
  50734. + struct ata_host *host = dev_get_drvdata(dev);
  50735. + struct ahci_host_priv *hpriv = host->private_data;
  50736. + int ret;
  50737. - platform_device_unregister(ahci_pdev);
  50738. - return 0;
  50739. + ret = imx_sata_enable(hpriv);
  50740. + if (ret)
  50741. + return ret;
  50742. +
  50743. + return ahci_platform_resume_host(dev);
  50744. }
  50745. +#endif
  50746. +
  50747. +static SIMPLE_DEV_PM_OPS(ahci_imx_pm_ops, imx_ahci_suspend, imx_ahci_resume);
  50748. static struct platform_driver imx_ahci_driver = {
  50749. .probe = imx_ahci_probe,
  50750. - .remove = imx_ahci_remove,
  50751. + .remove = ata_platform_remove_one,
  50752. .driver = {
  50753. .name = "ahci-imx",
  50754. .owner = THIS_MODULE,
  50755. .of_match_table = imx_ahci_of_match,
  50756. + .pm = &ahci_imx_pm_ops,
  50757. },
  50758. };
  50759. module_platform_driver(imx_ahci_driver);
  50760. diff -Nur linux-3.14.15/drivers/ata/ahci_platform.c linux-linaro-stable-mx6/drivers/ata/ahci_platform.c
  50761. --- linux-3.14.15/drivers/ata/ahci_platform.c 2014-07-31 23:51:43.000000000 +0200
  50762. +++ linux-linaro-stable-mx6/drivers/ata/ahci_platform.c 2014-08-20 19:31:42.312852626 +0200
  50763. @@ -12,135 +12,36 @@
  50764. * any later version.
  50765. */
  50766. -#include <linux/clk.h>
  50767. #include <linux/kernel.h>
  50768. -#include <linux/gfp.h>
  50769. #include <linux/module.h>
  50770. #include <linux/pm.h>
  50771. -#include <linux/init.h>
  50772. -#include <linux/interrupt.h>
  50773. #include <linux/device.h>
  50774. #include <linux/platform_device.h>
  50775. #include <linux/libata.h>
  50776. #include <linux/ahci_platform.h>
  50777. #include "ahci.h"
  50778. -static void ahci_host_stop(struct ata_host *host);
  50779. -
  50780. -enum ahci_type {
  50781. - AHCI, /* standard platform ahci */
  50782. - IMX53_AHCI, /* ahci on i.mx53 */
  50783. - STRICT_AHCI, /* delayed DMA engine start */
  50784. -};
  50785. -
  50786. -static struct platform_device_id ahci_devtype[] = {
  50787. - {
  50788. - .name = "ahci",
  50789. - .driver_data = AHCI,
  50790. - }, {
  50791. - .name = "imx53-ahci",
  50792. - .driver_data = IMX53_AHCI,
  50793. - }, {
  50794. - .name = "strict-ahci",
  50795. - .driver_data = STRICT_AHCI,
  50796. - }, {
  50797. - /* sentinel */
  50798. - }
  50799. -};
  50800. -MODULE_DEVICE_TABLE(platform, ahci_devtype);
  50801. -
  50802. -struct ata_port_operations ahci_platform_ops = {
  50803. - .inherits = &ahci_ops,
  50804. - .host_stop = ahci_host_stop,
  50805. -};
  50806. -EXPORT_SYMBOL_GPL(ahci_platform_ops);
  50807. -
  50808. -static struct ata_port_operations ahci_platform_retry_srst_ops = {
  50809. - .inherits = &ahci_pmp_retry_srst_ops,
  50810. - .host_stop = ahci_host_stop,
  50811. -};
  50812. -
  50813. -static const struct ata_port_info ahci_port_info[] = {
  50814. - /* by features */
  50815. - [AHCI] = {
  50816. - .flags = AHCI_FLAG_COMMON,
  50817. - .pio_mask = ATA_PIO4,
  50818. - .udma_mask = ATA_UDMA6,
  50819. - .port_ops = &ahci_platform_ops,
  50820. - },
  50821. - [IMX53_AHCI] = {
  50822. - .flags = AHCI_FLAG_COMMON,
  50823. - .pio_mask = ATA_PIO4,
  50824. - .udma_mask = ATA_UDMA6,
  50825. - .port_ops = &ahci_platform_retry_srst_ops,
  50826. - },
  50827. - [STRICT_AHCI] = {
  50828. - AHCI_HFLAGS (AHCI_HFLAG_DELAY_ENGINE),
  50829. - .flags = AHCI_FLAG_COMMON,
  50830. - .pio_mask = ATA_PIO4,
  50831. - .udma_mask = ATA_UDMA6,
  50832. - .port_ops = &ahci_platform_ops,
  50833. - },
  50834. -};
  50835. -
  50836. -static struct scsi_host_template ahci_platform_sht = {
  50837. - AHCI_SHT("ahci_platform"),
  50838. +static const struct ata_port_info ahci_port_info = {
  50839. + .flags = AHCI_FLAG_COMMON,
  50840. + .pio_mask = ATA_PIO4,
  50841. + .udma_mask = ATA_UDMA6,
  50842. + .port_ops = &ahci_platform_ops,
  50843. };
  50844. static int ahci_probe(struct platform_device *pdev)
  50845. {
  50846. struct device *dev = &pdev->dev;
  50847. struct ahci_platform_data *pdata = dev_get_platdata(dev);
  50848. - const struct platform_device_id *id = platform_get_device_id(pdev);
  50849. - struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0];
  50850. - const struct ata_port_info *ppi[] = { &pi, NULL };
  50851. struct ahci_host_priv *hpriv;
  50852. - struct ata_host *host;
  50853. - struct resource *mem;
  50854. - int irq;
  50855. - int n_ports;
  50856. - int i;
  50857. int rc;
  50858. - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  50859. - if (!mem) {
  50860. - dev_err(dev, "no mmio space\n");
  50861. - return -EINVAL;
  50862. - }
  50863. -
  50864. - irq = platform_get_irq(pdev, 0);
  50865. - if (irq <= 0) {
  50866. - dev_err(dev, "no irq\n");
  50867. - return -EINVAL;
  50868. - }
  50869. -
  50870. - if (pdata && pdata->ata_port_info)
  50871. - pi = *pdata->ata_port_info;
  50872. -
  50873. - hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
  50874. - if (!hpriv) {
  50875. - dev_err(dev, "can't alloc ahci_host_priv\n");
  50876. - return -ENOMEM;
  50877. - }
  50878. -
  50879. - hpriv->flags |= (unsigned long)pi.private_data;
  50880. + hpriv = ahci_platform_get_resources(pdev);
  50881. + if (IS_ERR(hpriv))
  50882. + return PTR_ERR(hpriv);
  50883. - hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
  50884. - if (!hpriv->mmio) {
  50885. - dev_err(dev, "can't map %pR\n", mem);
  50886. - return -ENOMEM;
  50887. - }
  50888. -
  50889. - hpriv->clk = clk_get(dev, NULL);
  50890. - if (IS_ERR(hpriv->clk)) {
  50891. - dev_err(dev, "can't get clock\n");
  50892. - } else {
  50893. - rc = clk_prepare_enable(hpriv->clk);
  50894. - if (rc) {
  50895. - dev_err(dev, "clock prepare enable failed");
  50896. - goto free_clk;
  50897. - }
  50898. - }
  50899. + rc = ahci_platform_enable_resources(hpriv);
  50900. + if (rc)
  50901. + return rc;
  50902. /*
  50903. * Some platforms might need to prepare for mmio region access,
  50904. @@ -151,69 +52,10 @@
  50905. if (pdata && pdata->init) {
  50906. rc = pdata->init(dev, hpriv->mmio);
  50907. if (rc)
  50908. - goto disable_unprepare_clk;
  50909. - }
  50910. -
  50911. - ahci_save_initial_config(dev, hpriv,
  50912. - pdata ? pdata->force_port_map : 0,
  50913. - pdata ? pdata->mask_port_map : 0);
  50914. -
  50915. - /* prepare host */
  50916. - if (hpriv->cap & HOST_CAP_NCQ)
  50917. - pi.flags |= ATA_FLAG_NCQ;
  50918. -
  50919. - if (hpriv->cap & HOST_CAP_PMP)
  50920. - pi.flags |= ATA_FLAG_PMP;
  50921. -
  50922. - ahci_set_em_messages(hpriv, &pi);
  50923. -
  50924. - /* CAP.NP sometimes indicate the index of the last enabled
  50925. - * port, at other times, that of the last possible port, so
  50926. - * determining the maximum port number requires looking at
  50927. - * both CAP.NP and port_map.
  50928. - */
  50929. - n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
  50930. -
  50931. - host = ata_host_alloc_pinfo(dev, ppi, n_ports);
  50932. - if (!host) {
  50933. - rc = -ENOMEM;
  50934. - goto pdata_exit;
  50935. + goto disable_resources;
  50936. }
  50937. - host->private_data = hpriv;
  50938. -
  50939. - if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
  50940. - host->flags |= ATA_HOST_PARALLEL_SCAN;
  50941. - else
  50942. - dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
  50943. -
  50944. - if (pi.flags & ATA_FLAG_EM)
  50945. - ahci_reset_em(host);
  50946. -
  50947. - for (i = 0; i < host->n_ports; i++) {
  50948. - struct ata_port *ap = host->ports[i];
  50949. -
  50950. - ata_port_desc(ap, "mmio %pR", mem);
  50951. - ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
  50952. -
  50953. - /* set enclosure management message type */
  50954. - if (ap->flags & ATA_FLAG_EM)
  50955. - ap->em_message_type = hpriv->em_msg_type;
  50956. -
  50957. - /* disabled/not-implemented port */
  50958. - if (!(hpriv->port_map & (1 << i)))
  50959. - ap->ops = &ata_dummy_port_ops;
  50960. - }
  50961. -
  50962. - rc = ahci_reset_controller(host);
  50963. - if (rc)
  50964. - goto pdata_exit;
  50965. -
  50966. - ahci_init_controller(host);
  50967. - ahci_print_info(host, "platform");
  50968. -
  50969. - rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
  50970. - &ahci_platform_sht);
  50971. + rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, 0, 0, 0);
  50972. if (rc)
  50973. goto pdata_exit;
  50974. @@ -221,115 +63,19 @@
  50975. pdata_exit:
  50976. if (pdata && pdata->exit)
  50977. pdata->exit(dev);
  50978. -disable_unprepare_clk:
  50979. - if (!IS_ERR(hpriv->clk))
  50980. - clk_disable_unprepare(hpriv->clk);
  50981. -free_clk:
  50982. - if (!IS_ERR(hpriv->clk))
  50983. - clk_put(hpriv->clk);
  50984. - return rc;
  50985. -}
  50986. -
  50987. -static void ahci_host_stop(struct ata_host *host)
  50988. -{
  50989. - struct device *dev = host->dev;
  50990. - struct ahci_platform_data *pdata = dev_get_platdata(dev);
  50991. - struct ahci_host_priv *hpriv = host->private_data;
  50992. -
  50993. - if (pdata && pdata->exit)
  50994. - pdata->exit(dev);
  50995. -
  50996. - if (!IS_ERR(hpriv->clk)) {
  50997. - clk_disable_unprepare(hpriv->clk);
  50998. - clk_put(hpriv->clk);
  50999. - }
  51000. -}
  51001. -
  51002. -#ifdef CONFIG_PM_SLEEP
  51003. -static int ahci_suspend(struct device *dev)
  51004. -{
  51005. - struct ahci_platform_data *pdata = dev_get_platdata(dev);
  51006. - struct ata_host *host = dev_get_drvdata(dev);
  51007. - struct ahci_host_priv *hpriv = host->private_data;
  51008. - void __iomem *mmio = hpriv->mmio;
  51009. - u32 ctl;
  51010. - int rc;
  51011. -
  51012. - if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
  51013. - dev_err(dev, "firmware update required for suspend/resume\n");
  51014. - return -EIO;
  51015. - }
  51016. -
  51017. - /*
  51018. - * AHCI spec rev1.1 section 8.3.3:
  51019. - * Software must disable interrupts prior to requesting a
  51020. - * transition of the HBA to D3 state.
  51021. - */
  51022. - ctl = readl(mmio + HOST_CTL);
  51023. - ctl &= ~HOST_IRQ_EN;
  51024. - writel(ctl, mmio + HOST_CTL);
  51025. - readl(mmio + HOST_CTL); /* flush */
  51026. -
  51027. - rc = ata_host_suspend(host, PMSG_SUSPEND);
  51028. - if (rc)
  51029. - return rc;
  51030. -
  51031. - if (pdata && pdata->suspend)
  51032. - return pdata->suspend(dev);
  51033. -
  51034. - if (!IS_ERR(hpriv->clk))
  51035. - clk_disable_unprepare(hpriv->clk);
  51036. -
  51037. - return 0;
  51038. -}
  51039. -
  51040. -static int ahci_resume(struct device *dev)
  51041. -{
  51042. - struct ahci_platform_data *pdata = dev_get_platdata(dev);
  51043. - struct ata_host *host = dev_get_drvdata(dev);
  51044. - struct ahci_host_priv *hpriv = host->private_data;
  51045. - int rc;
  51046. -
  51047. - if (!IS_ERR(hpriv->clk)) {
  51048. - rc = clk_prepare_enable(hpriv->clk);
  51049. - if (rc) {
  51050. - dev_err(dev, "clock prepare enable failed");
  51051. - return rc;
  51052. - }
  51053. - }
  51054. -
  51055. - if (pdata && pdata->resume) {
  51056. - rc = pdata->resume(dev);
  51057. - if (rc)
  51058. - goto disable_unprepare_clk;
  51059. - }
  51060. -
  51061. - if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
  51062. - rc = ahci_reset_controller(host);
  51063. - if (rc)
  51064. - goto disable_unprepare_clk;
  51065. -
  51066. - ahci_init_controller(host);
  51067. - }
  51068. -
  51069. - ata_host_resume(host);
  51070. -
  51071. - return 0;
  51072. -
  51073. -disable_unprepare_clk:
  51074. - if (!IS_ERR(hpriv->clk))
  51075. - clk_disable_unprepare(hpriv->clk);
  51076. -
  51077. +disable_resources:
  51078. + ahci_platform_disable_resources(hpriv);
  51079. return rc;
  51080. }
  51081. -#endif
  51082. -static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
  51083. +static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
  51084. + ahci_platform_resume);
  51085. static const struct of_device_id ahci_of_match[] = {
  51086. { .compatible = "snps,spear-ahci", },
  51087. { .compatible = "snps,exynos5440-ahci", },
  51088. { .compatible = "ibm,476gtr-ahci", },
  51089. + { .compatible = "snps,dwc-ahci", },
  51090. {},
  51091. };
  51092. MODULE_DEVICE_TABLE(of, ahci_of_match);
  51093. @@ -343,7 +89,6 @@
  51094. .of_match_table = ahci_of_match,
  51095. .pm = &ahci_pm_ops,
  51096. },
  51097. - .id_table = ahci_devtype,
  51098. };
  51099. module_platform_driver(ahci_driver);
  51100. diff -Nur linux-3.14.15/drivers/ata/ata_generic.c linux-linaro-stable-mx6/drivers/ata/ata_generic.c
  51101. --- linux-3.14.15/drivers/ata/ata_generic.c 2014-07-31 23:51:43.000000000 +0200
  51102. +++ linux-linaro-stable-mx6/drivers/ata/ata_generic.c 2014-08-20 19:31:42.312852626 +0200
  51103. @@ -19,7 +19,6 @@
  51104. #include <linux/kernel.h>
  51105. #include <linux/module.h>
  51106. #include <linux/pci.h>
  51107. -#include <linux/init.h>
  51108. #include <linux/blkdev.h>
  51109. #include <linux/delay.h>
  51110. #include <scsi/scsi_host.h>
  51111. diff -Nur linux-3.14.15/drivers/ata/Kconfig linux-linaro-stable-mx6/drivers/ata/Kconfig
  51112. --- linux-3.14.15/drivers/ata/Kconfig 2014-07-31 23:51:43.000000000 +0200
  51113. +++ linux-linaro-stable-mx6/drivers/ata/Kconfig 2014-08-20 19:31:42.312852626 +0200
  51114. @@ -99,7 +99,7 @@
  51115. config AHCI_IMX
  51116. tristate "Freescale i.MX AHCI SATA support"
  51117. - depends on SATA_AHCI_PLATFORM && MFD_SYSCON
  51118. + depends on MFD_SYSCON
  51119. help
  51120. This option enables support for the Freescale i.MX SoC's
  51121. onboard AHCI SATA.
  51122. diff -Nur linux-3.14.15/drivers/ata/libahci.c linux-linaro-stable-mx6/drivers/ata/libahci.c
  51123. --- linux-3.14.15/drivers/ata/libahci.c 2014-07-31 23:51:43.000000000 +0200
  51124. +++ linux-linaro-stable-mx6/drivers/ata/libahci.c 2014-08-20 19:31:42.316852643 +0200
  51125. @@ -35,7 +35,6 @@
  51126. #include <linux/kernel.h>
  51127. #include <linux/gfp.h>
  51128. #include <linux/module.h>
  51129. -#include <linux/init.h>
  51130. #include <linux/blkdev.h>
  51131. #include <linux/delay.h>
  51132. #include <linux/interrupt.h>
  51133. @@ -394,6 +393,9 @@
  51134. *
  51135. * If inconsistent, config values are fixed up by this function.
  51136. *
  51137. + * If it is not set already this function sets hpriv->start_engine to
  51138. + * ahci_start_engine.
  51139. + *
  51140. * LOCKING:
  51141. * None.
  51142. */
  51143. @@ -450,11 +452,23 @@
  51144. cap &= ~HOST_CAP_SNTF;
  51145. }
  51146. + if ((cap2 & HOST_CAP2_SDS) && (hpriv->flags & AHCI_HFLAG_NO_DEVSLP)) {
  51147. + dev_info(dev,
  51148. + "controller can't do DEVSLP, turning off\n");
  51149. + cap2 &= ~HOST_CAP2_SDS;
  51150. + cap2 &= ~HOST_CAP2_SADM;
  51151. + }
  51152. +
  51153. if (!(cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_YES_FBS)) {
  51154. dev_info(dev, "controller can do FBS, turning on CAP_FBS\n");
  51155. cap |= HOST_CAP_FBS;
  51156. }
  51157. + if ((cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_NO_FBS)) {
  51158. + dev_info(dev, "controller can't do FBS, turning off CAP_FBS\n");
  51159. + cap &= ~HOST_CAP_FBS;
  51160. + }
  51161. +
  51162. if (force_port_map && port_map != force_port_map) {
  51163. dev_info(dev, "forcing port_map 0x%x -> 0x%x\n",
  51164. port_map, force_port_map);
  51165. @@ -500,6 +514,9 @@
  51166. hpriv->cap = cap;
  51167. hpriv->cap2 = cap2;
  51168. hpriv->port_map = port_map;
  51169. +
  51170. + if (!hpriv->start_engine)
  51171. + hpriv->start_engine = ahci_start_engine;
  51172. }
  51173. EXPORT_SYMBOL_GPL(ahci_save_initial_config);
  51174. @@ -766,7 +783,7 @@
  51175. /* enable DMA */
  51176. if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE))
  51177. - ahci_start_engine(ap);
  51178. + hpriv->start_engine(ap);
  51179. /* turn on LEDs */
  51180. if (ap->flags & ATA_FLAG_EM) {
  51181. @@ -1234,7 +1251,7 @@
  51182. /* restart engine */
  51183. out_restart:
  51184. - ahci_start_engine(ap);
  51185. + hpriv->start_engine(ap);
  51186. return rc;
  51187. }
  51188. EXPORT_SYMBOL_GPL(ahci_kick_engine);
  51189. @@ -1426,6 +1443,7 @@
  51190. const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
  51191. struct ata_port *ap = link->ap;
  51192. struct ahci_port_priv *pp = ap->private_data;
  51193. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51194. u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
  51195. struct ata_taskfile tf;
  51196. bool online;
  51197. @@ -1443,7 +1461,7 @@
  51198. rc = sata_link_hardreset(link, timing, deadline, &online,
  51199. ahci_check_ready);
  51200. - ahci_start_engine(ap);
  51201. + hpriv->start_engine(ap);
  51202. if (online)
  51203. *class = ahci_dev_classify(ap);
  51204. @@ -2007,10 +2025,12 @@
  51205. void ahci_error_handler(struct ata_port *ap)
  51206. {
  51207. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51208. +
  51209. if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
  51210. /* restart engine */
  51211. ahci_stop_engine(ap);
  51212. - ahci_start_engine(ap);
  51213. + hpriv->start_engine(ap);
  51214. }
  51215. sata_pmp_error_handler(ap);
  51216. @@ -2031,6 +2051,7 @@
  51217. static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
  51218. {
  51219. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51220. void __iomem *port_mmio = ahci_port_base(ap);
  51221. struct ata_device *dev = ap->link.device;
  51222. u32 devslp, dm, dito, mdat, deto;
  51223. @@ -2094,7 +2115,7 @@
  51224. PORT_DEVSLP_ADSE);
  51225. writel(devslp, port_mmio + PORT_DEVSLP);
  51226. - ahci_start_engine(ap);
  51227. + hpriv->start_engine(ap);
  51228. /* enable device sleep feature for the drive */
  51229. err_mask = ata_dev_set_feature(dev,
  51230. @@ -2106,6 +2127,7 @@
  51231. static void ahci_enable_fbs(struct ata_port *ap)
  51232. {
  51233. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51234. struct ahci_port_priv *pp = ap->private_data;
  51235. void __iomem *port_mmio = ahci_port_base(ap);
  51236. u32 fbs;
  51237. @@ -2134,11 +2156,12 @@
  51238. } else
  51239. dev_err(ap->host->dev, "Failed to enable FBS\n");
  51240. - ahci_start_engine(ap);
  51241. + hpriv->start_engine(ap);
  51242. }
  51243. static void ahci_disable_fbs(struct ata_port *ap)
  51244. {
  51245. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51246. struct ahci_port_priv *pp = ap->private_data;
  51247. void __iomem *port_mmio = ahci_port_base(ap);
  51248. u32 fbs;
  51249. @@ -2166,7 +2189,7 @@
  51250. pp->fbs_enabled = false;
  51251. }
  51252. - ahci_start_engine(ap);
  51253. + hpriv->start_engine(ap);
  51254. }
  51255. static void ahci_pmp_attach(struct ata_port *ap)
  51256. diff -Nur linux-3.14.15/drivers/ata/libahci_platform.c linux-linaro-stable-mx6/drivers/ata/libahci_platform.c
  51257. --- linux-3.14.15/drivers/ata/libahci_platform.c 1970-01-01 01:00:00.000000000 +0100
  51258. +++ linux-linaro-stable-mx6/drivers/ata/libahci_platform.c 2014-08-20 19:31:42.316852643 +0200
  51259. @@ -0,0 +1,544 @@
  51260. +/*
  51261. + * AHCI SATA platform library
  51262. + *
  51263. + * Copyright 2004-2005 Red Hat, Inc.
  51264. + * Jeff Garzik <jgarzik@pobox.com>
  51265. + * Copyright 2010 MontaVista Software, LLC.
  51266. + * Anton Vorontsov <avorontsov@ru.mvista.com>
  51267. + *
  51268. + * This program is free software; you can redistribute it and/or modify
  51269. + * it under the terms of the GNU General Public License as published by
  51270. + * the Free Software Foundation; either version 2, or (at your option)
  51271. + * any later version.
  51272. + */
  51273. +
  51274. +#include <linux/clk.h>
  51275. +#include <linux/kernel.h>
  51276. +#include <linux/gfp.h>
  51277. +#include <linux/module.h>
  51278. +#include <linux/pm.h>
  51279. +#include <linux/interrupt.h>
  51280. +#include <linux/device.h>
  51281. +#include <linux/platform_device.h>
  51282. +#include <linux/libata.h>
  51283. +#include <linux/ahci_platform.h>
  51284. +#include <linux/phy/phy.h>
  51285. +#include <linux/pm_runtime.h>
  51286. +#include "ahci.h"
  51287. +
  51288. +static void ahci_host_stop(struct ata_host *host);
  51289. +
  51290. +struct ata_port_operations ahci_platform_ops = {
  51291. + .inherits = &ahci_ops,
  51292. + .host_stop = ahci_host_stop,
  51293. +};
  51294. +EXPORT_SYMBOL_GPL(ahci_platform_ops);
  51295. +
  51296. +static struct scsi_host_template ahci_platform_sht = {
  51297. + AHCI_SHT("ahci_platform"),
  51298. +};
  51299. +
  51300. +/**
  51301. + * ahci_platform_enable_clks - Enable platform clocks
  51302. + * @hpriv: host private area to store config values
  51303. + *
  51304. + * This function enables all the clks found in hpriv->clks, starting at
  51305. + * index 0. If any clk fails to enable it disables all the clks already
  51306. + * enabled in reverse order, and then returns an error.
  51307. + *
  51308. + * RETURNS:
  51309. + * 0 on success otherwise a negative error code
  51310. + */
  51311. +int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
  51312. +{
  51313. + int c, rc;
  51314. +
  51315. + for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) {
  51316. + rc = clk_prepare_enable(hpriv->clks[c]);
  51317. + if (rc)
  51318. + goto disable_unprepare_clk;
  51319. + }
  51320. + return 0;
  51321. +
  51322. +disable_unprepare_clk:
  51323. + while (--c >= 0)
  51324. + clk_disable_unprepare(hpriv->clks[c]);
  51325. + return rc;
  51326. +}
  51327. +EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
  51328. +
  51329. +/**
  51330. + * ahci_platform_disable_clks - Disable platform clocks
  51331. + * @hpriv: host private area to store config values
  51332. + *
  51333. + * This function disables all the clks found in hpriv->clks, in reverse
  51334. + * order of ahci_platform_enable_clks (starting at the end of the array).
  51335. + */
  51336. +void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
  51337. +{
  51338. + int c;
  51339. +
  51340. + for (c = AHCI_MAX_CLKS - 1; c >= 0; c--)
  51341. + if (hpriv->clks[c])
  51342. + clk_disable_unprepare(hpriv->clks[c]);
  51343. +}
  51344. +EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
  51345. +
  51346. +/**
  51347. + * ahci_platform_enable_resources - Enable platform resources
  51348. + * @hpriv: host private area to store config values
  51349. + *
  51350. + * This function enables all ahci_platform managed resources in the
  51351. + * following order:
  51352. + * 1) Regulator
  51353. + * 2) Clocks (through ahci_platform_enable_clks)
  51354. + * 3) Phy
  51355. + *
  51356. + * If resource enabling fails at any point the previous enabled resources
  51357. + * are disabled in reverse order.
  51358. + *
  51359. + * RETURNS:
  51360. + * 0 on success otherwise a negative error code
  51361. + */
  51362. +int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
  51363. +{
  51364. + int rc;
  51365. +
  51366. + if (hpriv->target_pwr) {
  51367. + rc = regulator_enable(hpriv->target_pwr);
  51368. + if (rc)
  51369. + return rc;
  51370. + }
  51371. +
  51372. + rc = ahci_platform_enable_clks(hpriv);
  51373. + if (rc)
  51374. + goto disable_regulator;
  51375. +
  51376. + if (hpriv->phy) {
  51377. + rc = phy_init(hpriv->phy);
  51378. + if (rc)
  51379. + goto disable_clks;
  51380. +
  51381. + rc = phy_power_on(hpriv->phy);
  51382. + if (rc) {
  51383. + phy_exit(hpriv->phy);
  51384. + goto disable_clks;
  51385. + }
  51386. + }
  51387. +
  51388. + return 0;
  51389. +
  51390. +disable_clks:
  51391. + ahci_platform_disable_clks(hpriv);
  51392. +
  51393. +disable_regulator:
  51394. + if (hpriv->target_pwr)
  51395. + regulator_disable(hpriv->target_pwr);
  51396. + return rc;
  51397. +}
  51398. +EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
  51399. +
  51400. +/**
  51401. + * ahci_platform_disable_resources - Disable platform resources
  51402. + * @hpriv: host private area to store config values
  51403. + *
  51404. + * This function disables all ahci_platform managed resources in the
  51405. + * following order:
  51406. + * 1) Phy
  51407. + * 2) Clocks (through ahci_platform_disable_clks)
  51408. + * 3) Regulator
  51409. + */
  51410. +void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
  51411. +{
  51412. + if (hpriv->phy) {
  51413. + phy_power_off(hpriv->phy);
  51414. + phy_exit(hpriv->phy);
  51415. + }
  51416. +
  51417. + ahci_platform_disable_clks(hpriv);
  51418. +
  51419. + if (hpriv->target_pwr)
  51420. + regulator_disable(hpriv->target_pwr);
  51421. +}
  51422. +EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
  51423. +
  51424. +static void ahci_platform_put_resources(struct device *dev, void *res)
  51425. +{
  51426. + struct ahci_host_priv *hpriv = res;
  51427. + int c;
  51428. +
  51429. + if (hpriv->got_runtime_pm) {
  51430. + pm_runtime_put_sync(dev);
  51431. + pm_runtime_disable(dev);
  51432. + }
  51433. +
  51434. + for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
  51435. + clk_put(hpriv->clks[c]);
  51436. +}
  51437. +
  51438. +/**
  51439. + * ahci_platform_get_resources - Get platform resources
  51440. + * @pdev: platform device to get resources for
  51441. + *
  51442. + * This function allocates an ahci_host_priv struct, and gets the following
  51443. + * resources, storing a reference to them inside the returned struct:
  51444. + *
  51445. + * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
  51446. + * 2) regulator for controlling the targets power (optional)
  51447. + * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
  51448. + * or for non devicetree enabled platforms a single clock
  51449. + * 4) phy (optional)
  51450. + *
  51451. + * RETURNS:
  51452. + * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
  51453. + */
  51454. +struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
  51455. +{
  51456. + struct device *dev = &pdev->dev;
  51457. + struct ahci_host_priv *hpriv;
  51458. + struct clk *clk;
  51459. + int i, rc = -ENOMEM;
  51460. +
  51461. + if (!devres_open_group(dev, NULL, GFP_KERNEL))
  51462. + return ERR_PTR(-ENOMEM);
  51463. +
  51464. + hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
  51465. + GFP_KERNEL);
  51466. + if (!hpriv)
  51467. + goto err_out;
  51468. +
  51469. + devres_add(dev, hpriv);
  51470. +
  51471. + hpriv->mmio = devm_ioremap_resource(dev,
  51472. + platform_get_resource(pdev, IORESOURCE_MEM, 0));
  51473. + if (IS_ERR(hpriv->mmio)) {
  51474. + dev_err(dev, "no mmio space\n");
  51475. + rc = PTR_ERR(hpriv->mmio);
  51476. + goto err_out;
  51477. + }
  51478. +
  51479. + hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
  51480. + if (IS_ERR(hpriv->target_pwr)) {
  51481. + rc = PTR_ERR(hpriv->target_pwr);
  51482. + if (rc == -EPROBE_DEFER)
  51483. + goto err_out;
  51484. + hpriv->target_pwr = NULL;
  51485. + }
  51486. +
  51487. + for (i = 0; i < AHCI_MAX_CLKS; i++) {
  51488. + /*
  51489. + * For now we must use clk_get(dev, NULL) for the first clock,
  51490. + * because some platforms (da850, spear13xx) are not yet
  51491. + * converted to use devicetree for clocks. For new platforms
  51492. + * this is equivalent to of_clk_get(dev->of_node, 0).
  51493. + */
  51494. + if (i == 0)
  51495. + clk = clk_get(dev, NULL);
  51496. + else
  51497. + clk = of_clk_get(dev->of_node, i);
  51498. +
  51499. + if (IS_ERR(clk)) {
  51500. + rc = PTR_ERR(clk);
  51501. + if (rc == -EPROBE_DEFER)
  51502. + goto err_out;
  51503. + break;
  51504. + }
  51505. + hpriv->clks[i] = clk;
  51506. + }
  51507. +
  51508. + hpriv->phy = devm_phy_get(dev, "sata-phy");
  51509. + if (IS_ERR(hpriv->phy)) {
  51510. + rc = PTR_ERR(hpriv->phy);
  51511. + switch (rc) {
  51512. + case -ENODEV:
  51513. + case -ENOSYS:
  51514. + /* continue normally */
  51515. + hpriv->phy = NULL;
  51516. + break;
  51517. +
  51518. + case -EPROBE_DEFER:
  51519. + goto err_out;
  51520. +
  51521. + default:
  51522. + dev_err(dev, "couldn't get sata-phy\n");
  51523. + goto err_out;
  51524. + }
  51525. + }
  51526. +
  51527. + pm_runtime_enable(dev);
  51528. + pm_runtime_get_sync(dev);
  51529. + hpriv->got_runtime_pm = true;
  51530. +
  51531. + devres_remove_group(dev, NULL);
  51532. + return hpriv;
  51533. +
  51534. +err_out:
  51535. + devres_release_group(dev, NULL);
  51536. + return ERR_PTR(rc);
  51537. +}
  51538. +EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
  51539. +
  51540. +/**
  51541. + * ahci_platform_init_host - Bring up an ahci-platform host
  51542. + * @pdev: platform device pointer for the host
  51543. + * @hpriv: ahci-host private data for the host
  51544. + * @pi_template: template for the ata_port_info to use
  51545. + * @host_flags: ahci host flags used in ahci_host_priv
  51546. + * @force_port_map: param passed to ahci_save_initial_config
  51547. + * @mask_port_map: param passed to ahci_save_initial_config
  51548. + *
  51549. + * This function does all the usual steps needed to bring up an
  51550. + * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
  51551. + * must be initialized / enabled before calling this.
  51552. + *
  51553. + * RETURNS:
  51554. + * 0 on success otherwise a negative error code
  51555. + */
  51556. +int ahci_platform_init_host(struct platform_device *pdev,
  51557. + struct ahci_host_priv *hpriv,
  51558. + const struct ata_port_info *pi_template,
  51559. + unsigned long host_flags,
  51560. + unsigned int force_port_map,
  51561. + unsigned int mask_port_map)
  51562. +{
  51563. + struct device *dev = &pdev->dev;
  51564. + struct ata_port_info pi = *pi_template;
  51565. + const struct ata_port_info *ppi[] = { &pi, NULL };
  51566. + struct ata_host *host;
  51567. + int i, irq, n_ports, rc;
  51568. +
  51569. + irq = platform_get_irq(pdev, 0);
  51570. + if (irq <= 0) {
  51571. + dev_err(dev, "no irq\n");
  51572. + return -EINVAL;
  51573. + }
  51574. +
  51575. + /* prepare host */
  51576. + pi.private_data = (void *)host_flags;
  51577. + hpriv->flags |= host_flags;
  51578. +
  51579. + ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
  51580. +
  51581. + if (hpriv->cap & HOST_CAP_NCQ)
  51582. + pi.flags |= ATA_FLAG_NCQ;
  51583. +
  51584. + if (hpriv->cap & HOST_CAP_PMP)
  51585. + pi.flags |= ATA_FLAG_PMP;
  51586. +
  51587. + ahci_set_em_messages(hpriv, &pi);
  51588. +
  51589. + /* CAP.NP sometimes indicate the index of the last enabled
  51590. + * port, at other times, that of the last possible port, so
  51591. + * determining the maximum port number requires looking at
  51592. + * both CAP.NP and port_map.
  51593. + */
  51594. + n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
  51595. +
  51596. + host = ata_host_alloc_pinfo(dev, ppi, n_ports);
  51597. + if (!host)
  51598. + return -ENOMEM;
  51599. +
  51600. + host->private_data = hpriv;
  51601. +
  51602. + if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
  51603. + host->flags |= ATA_HOST_PARALLEL_SCAN;
  51604. + else
  51605. + dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
  51606. +
  51607. + if (pi.flags & ATA_FLAG_EM)
  51608. + ahci_reset_em(host);
  51609. +
  51610. + for (i = 0; i < host->n_ports; i++) {
  51611. + struct ata_port *ap = host->ports[i];
  51612. +
  51613. + ata_port_desc(ap, "mmio %pR",
  51614. + platform_get_resource(pdev, IORESOURCE_MEM, 0));
  51615. + ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
  51616. +
  51617. + /* set enclosure management message type */
  51618. + if (ap->flags & ATA_FLAG_EM)
  51619. + ap->em_message_type = hpriv->em_msg_type;
  51620. +
  51621. + /* disabled/not-implemented port */
  51622. + if (!(hpriv->port_map & (1 << i)))
  51623. + ap->ops = &ata_dummy_port_ops;
  51624. + }
  51625. +
  51626. + rc = ahci_reset_controller(host);
  51627. + if (rc)
  51628. + return rc;
  51629. +
  51630. + ahci_init_controller(host);
  51631. + ahci_print_info(host, "platform");
  51632. +
  51633. + return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
  51634. + &ahci_platform_sht);
  51635. +}
  51636. +EXPORT_SYMBOL_GPL(ahci_platform_init_host);
  51637. +
  51638. +static void ahci_host_stop(struct ata_host *host)
  51639. +{
  51640. + struct device *dev = host->dev;
  51641. + struct ahci_platform_data *pdata = dev_get_platdata(dev);
  51642. + struct ahci_host_priv *hpriv = host->private_data;
  51643. +
  51644. + if (pdata && pdata->exit)
  51645. + pdata->exit(dev);
  51646. +
  51647. + ahci_platform_disable_resources(hpriv);
  51648. +}
  51649. +
  51650. +#ifdef CONFIG_PM_SLEEP
  51651. +/**
  51652. + * ahci_platform_suspend_host - Suspend an ahci-platform host
  51653. + * @dev: device pointer for the host
  51654. + *
  51655. + * This function does all the usual steps needed to suspend an
  51656. + * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
  51657. + * must be disabled after calling this.
  51658. + *
  51659. + * RETURNS:
  51660. + * 0 on success otherwise a negative error code
  51661. + */
  51662. +int ahci_platform_suspend_host(struct device *dev)
  51663. +{
  51664. + struct ata_host *host = dev_get_drvdata(dev);
  51665. + struct ahci_host_priv *hpriv = host->private_data;
  51666. + void __iomem *mmio = hpriv->mmio;
  51667. + u32 ctl;
  51668. +
  51669. + if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
  51670. + dev_err(dev, "firmware update required for suspend/resume\n");
  51671. + return -EIO;
  51672. + }
  51673. +
  51674. + /*
  51675. + * AHCI spec rev1.1 section 8.3.3:
  51676. + * Software must disable interrupts prior to requesting a
  51677. + * transition of the HBA to D3 state.
  51678. + */
  51679. + ctl = readl(mmio + HOST_CTL);
  51680. + ctl &= ~HOST_IRQ_EN;
  51681. + writel(ctl, mmio + HOST_CTL);
  51682. + readl(mmio + HOST_CTL); /* flush */
  51683. +
  51684. + return ata_host_suspend(host, PMSG_SUSPEND);
  51685. +}
  51686. +EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
  51687. +
  51688. +/**
  51689. + * ahci_platform_resume_host - Resume an ahci-platform host
  51690. + * @dev: device pointer for the host
  51691. + *
  51692. + * This function does all the usual steps needed to resume an ahci-platform
  51693. + * host, note any necessary resources (ie clks, phy, etc.) must be
  51694. + * initialized / enabled before calling this.
  51695. + *
  51696. + * RETURNS:
  51697. + * 0 on success otherwise a negative error code
  51698. + */
  51699. +int ahci_platform_resume_host(struct device *dev)
  51700. +{
  51701. + struct ata_host *host = dev_get_drvdata(dev);
  51702. + int rc;
  51703. +
  51704. + if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
  51705. + rc = ahci_reset_controller(host);
  51706. + if (rc)
  51707. + return rc;
  51708. +
  51709. + ahci_init_controller(host);
  51710. + }
  51711. +
  51712. + ata_host_resume(host);
  51713. +
  51714. + return 0;
  51715. +}
  51716. +EXPORT_SYMBOL_GPL(ahci_platform_resume_host);
  51717. +
  51718. +/**
  51719. + * ahci_platform_suspend - Suspend an ahci-platform device
  51720. + * @dev: the platform device to suspend
  51721. + *
  51722. + * This function suspends the host associated with the device, followed by
  51723. + * disabling all the resources of the device.
  51724. + *
  51725. + * RETURNS:
  51726. + * 0 on success otherwise a negative error code
  51727. + */
  51728. +int ahci_platform_suspend(struct device *dev)
  51729. +{
  51730. + struct ahci_platform_data *pdata = dev_get_platdata(dev);
  51731. + struct ata_host *host = dev_get_drvdata(dev);
  51732. + struct ahci_host_priv *hpriv = host->private_data;
  51733. + int rc;
  51734. +
  51735. + rc = ahci_platform_suspend_host(dev);
  51736. + if (rc)
  51737. + return rc;
  51738. +
  51739. + if (pdata && pdata->suspend) {
  51740. + rc = pdata->suspend(dev);
  51741. + if (rc)
  51742. + goto resume_host;
  51743. + }
  51744. +
  51745. + ahci_platform_disable_resources(hpriv);
  51746. +
  51747. + return 0;
  51748. +
  51749. +resume_host:
  51750. + ahci_platform_resume_host(dev);
  51751. + return rc;
  51752. +}
  51753. +EXPORT_SYMBOL_GPL(ahci_platform_suspend);
  51754. +
  51755. +/**
  51756. + * ahci_platform_resume - Resume an ahci-platform device
  51757. + * @dev: the platform device to resume
  51758. + *
  51759. + * This function enables all the resources of the device followed by
  51760. + * resuming the host associated with the device.
  51761. + *
  51762. + * RETURNS:
  51763. + * 0 on success otherwise a negative error code
  51764. + */
  51765. +int ahci_platform_resume(struct device *dev)
  51766. +{
  51767. + struct ahci_platform_data *pdata = dev_get_platdata(dev);
  51768. + struct ata_host *host = dev_get_drvdata(dev);
  51769. + struct ahci_host_priv *hpriv = host->private_data;
  51770. + int rc;
  51771. +
  51772. + rc = ahci_platform_enable_resources(hpriv);
  51773. + if (rc)
  51774. + return rc;
  51775. +
  51776. + if (pdata && pdata->resume) {
  51777. + rc = pdata->resume(dev);
  51778. + if (rc)
  51779. + goto disable_resources;
  51780. + }
  51781. +
  51782. + rc = ahci_platform_resume_host(dev);
  51783. + if (rc)
  51784. + goto disable_resources;
  51785. +
  51786. + /* We resumed so update PM runtime state */
  51787. + pm_runtime_disable(dev);
  51788. + pm_runtime_set_active(dev);
  51789. + pm_runtime_enable(dev);
  51790. +
  51791. + return 0;
  51792. +
  51793. +disable_resources:
  51794. + ahci_platform_disable_resources(hpriv);
  51795. +
  51796. + return rc;
  51797. +}
  51798. +EXPORT_SYMBOL_GPL(ahci_platform_resume);
  51799. +#endif
  51800. +
  51801. +MODULE_DESCRIPTION("AHCI SATA platform library");
  51802. +MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
  51803. +MODULE_LICENSE("GPL");
  51804. diff -Nur linux-3.14.15/drivers/ata/libata-core.c linux-linaro-stable-mx6/drivers/ata/libata-core.c
  51805. --- linux-3.14.15/drivers/ata/libata-core.c 2014-07-31 23:51:43.000000000 +0200
  51806. +++ linux-linaro-stable-mx6/drivers/ata/libata-core.c 2014-08-20 19:31:42.316852643 +0200
  51807. @@ -1524,7 +1524,7 @@
  51808. * @dev: Device to which the command is sent
  51809. * @tf: Taskfile registers for the command and the result
  51810. * @cdb: CDB for packet command
  51811. - * @dma_dir: Data tranfer direction of the command
  51812. + * @dma_dir: Data transfer direction of the command
  51813. * @sgl: sg list for the data buffer of the command
  51814. * @n_elem: Number of sg entries
  51815. * @timeout: Timeout in msecs (0 for default)
  51816. @@ -1712,7 +1712,7 @@
  51817. * @dev: Device to which the command is sent
  51818. * @tf: Taskfile registers for the command and the result
  51819. * @cdb: CDB for packet command
  51820. - * @dma_dir: Data tranfer direction of the command
  51821. + * @dma_dir: Data transfer direction of the command
  51822. * @buf: Data buffer of the command
  51823. * @buflen: Length of data buffer
  51824. * @timeout: Timeout in msecs (0 for default)
  51825. @@ -4787,10 +4787,6 @@
  51826. * ata_qc_new - Request an available ATA command, for queueing
  51827. * @ap: target port
  51828. *
  51829. - * Some ATA host controllers may implement a queue depth which is less
  51830. - * than ATA_MAX_QUEUE. So we shouldn't allocate a tag which is beyond
  51831. - * the hardware limitation.
  51832. - *
  51833. * LOCKING:
  51834. * None.
  51835. */
  51836. @@ -4798,15 +4794,14 @@
  51837. static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
  51838. {
  51839. struct ata_queued_cmd *qc = NULL;
  51840. - unsigned int max_queue = ap->host->n_tags;
  51841. unsigned int i, tag;
  51842. /* no command while frozen */
  51843. if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
  51844. return NULL;
  51845. - for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
  51846. - tag = tag < max_queue ? tag : 0;
  51847. + for (i = 0; i < ATA_MAX_QUEUE; i++) {
  51848. + tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
  51849. /* the last tag is reserved for internal command. */
  51850. if (tag == ATA_TAG_INTERNAL)
  51851. @@ -6108,7 +6103,6 @@
  51852. {
  51853. spin_lock_init(&host->lock);
  51854. mutex_init(&host->eh_mutex);
  51855. - host->n_tags = ATA_MAX_QUEUE - 1;
  51856. host->dev = dev;
  51857. host->ops = ops;
  51858. }
  51859. @@ -6190,8 +6184,6 @@
  51860. {
  51861. int i, rc;
  51862. - host->n_tags = clamp(sht->can_queue, 1, ATA_MAX_QUEUE - 1);
  51863. -
  51864. /* host must have been started */
  51865. if (!(host->flags & ATA_HOST_STARTED)) {
  51866. dev_err(host->dev, "BUG: trying to register unstarted host\n");
  51867. diff -Nur linux-3.14.15/drivers/ata/Makefile linux-linaro-stable-mx6/drivers/ata/Makefile
  51868. --- linux-3.14.15/drivers/ata/Makefile 2014-07-31 23:51:43.000000000 +0200
  51869. +++ linux-linaro-stable-mx6/drivers/ata/Makefile 2014-08-20 19:31:42.312852626 +0200
  51870. @@ -4,13 +4,13 @@
  51871. # non-SFF interface
  51872. obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o
  51873. obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o
  51874. -obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
  51875. +obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o
  51876. obj-$(CONFIG_SATA_FSL) += sata_fsl.o
  51877. obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
  51878. obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
  51879. obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
  51880. obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
  51881. -obj-$(CONFIG_AHCI_IMX) += ahci_imx.o
  51882. +obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o
  51883. # SFF w/ custom DMA
  51884. obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
  51885. diff -Nur linux-3.14.15/drivers/ata/pata_acpi.c linux-linaro-stable-mx6/drivers/ata/pata_acpi.c
  51886. --- linux-3.14.15/drivers/ata/pata_acpi.c 2014-07-31 23:51:43.000000000 +0200
  51887. +++ linux-linaro-stable-mx6/drivers/ata/pata_acpi.c 2014-08-20 19:31:42.320852660 +0200
  51888. @@ -7,7 +7,6 @@
  51889. #include <linux/kernel.h>
  51890. #include <linux/module.h>
  51891. #include <linux/pci.h>
  51892. -#include <linux/init.h>
  51893. #include <linux/blkdev.h>
  51894. #include <linux/delay.h>
  51895. #include <linux/device.h>
  51896. diff -Nur linux-3.14.15/drivers/ata/pata_amd.c linux-linaro-stable-mx6/drivers/ata/pata_amd.c
  51897. --- linux-3.14.15/drivers/ata/pata_amd.c 2014-07-31 23:51:43.000000000 +0200
  51898. +++ linux-linaro-stable-mx6/drivers/ata/pata_amd.c 2014-08-20 19:31:42.320852660 +0200
  51899. @@ -17,7 +17,6 @@
  51900. #include <linux/kernel.h>
  51901. #include <linux/module.h>
  51902. #include <linux/pci.h>
  51903. -#include <linux/init.h>
  51904. #include <linux/blkdev.h>
  51905. #include <linux/delay.h>
  51906. #include <scsi/scsi_host.h>
  51907. diff -Nur linux-3.14.15/drivers/ata/pata_artop.c linux-linaro-stable-mx6/drivers/ata/pata_artop.c
  51908. --- linux-3.14.15/drivers/ata/pata_artop.c 2014-07-31 23:51:43.000000000 +0200
  51909. +++ linux-linaro-stable-mx6/drivers/ata/pata_artop.c 2014-08-20 19:31:42.320852660 +0200
  51910. @@ -19,7 +19,6 @@
  51911. #include <linux/kernel.h>
  51912. #include <linux/module.h>
  51913. #include <linux/pci.h>
  51914. -#include <linux/init.h>
  51915. #include <linux/blkdev.h>
  51916. #include <linux/delay.h>
  51917. #include <linux/device.h>
  51918. diff -Nur linux-3.14.15/drivers/ata/pata_at91.c linux-linaro-stable-mx6/drivers/ata/pata_at91.c
  51919. --- linux-3.14.15/drivers/ata/pata_at91.c 2014-07-31 23:51:43.000000000 +0200
  51920. +++ linux-linaro-stable-mx6/drivers/ata/pata_at91.c 2014-08-20 19:31:42.320852660 +0200
  51921. @@ -18,7 +18,6 @@
  51922. #include <linux/kernel.h>
  51923. #include <linux/module.h>
  51924. -#include <linux/init.h>
  51925. #include <linux/blkdev.h>
  51926. #include <linux/gfp.h>
  51927. #include <scsi/scsi_host.h>
  51928. diff -Nur linux-3.14.15/drivers/ata/pata_atiixp.c linux-linaro-stable-mx6/drivers/ata/pata_atiixp.c
  51929. --- linux-3.14.15/drivers/ata/pata_atiixp.c 2014-07-31 23:51:43.000000000 +0200
  51930. +++ linux-linaro-stable-mx6/drivers/ata/pata_atiixp.c 2014-08-20 19:31:42.320852660 +0200
  51931. @@ -15,7 +15,6 @@
  51932. #include <linux/kernel.h>
  51933. #include <linux/module.h>
  51934. #include <linux/pci.h>
  51935. -#include <linux/init.h>
  51936. #include <linux/blkdev.h>
  51937. #include <linux/delay.h>
  51938. #include <scsi/scsi_host.h>
  51939. diff -Nur linux-3.14.15/drivers/ata/pata_atp867x.c linux-linaro-stable-mx6/drivers/ata/pata_atp867x.c
  51940. --- linux-3.14.15/drivers/ata/pata_atp867x.c 2014-07-31 23:51:43.000000000 +0200
  51941. +++ linux-linaro-stable-mx6/drivers/ata/pata_atp867x.c 2014-08-20 19:31:42.320852660 +0200
  51942. @@ -29,7 +29,6 @@
  51943. #include <linux/kernel.h>
  51944. #include <linux/module.h>
  51945. #include <linux/pci.h>
  51946. -#include <linux/init.h>
  51947. #include <linux/blkdev.h>
  51948. #include <linux/delay.h>
  51949. #include <linux/device.h>
  51950. diff -Nur linux-3.14.15/drivers/ata/pata_cmd640.c linux-linaro-stable-mx6/drivers/ata/pata_cmd640.c
  51951. --- linux-3.14.15/drivers/ata/pata_cmd640.c 2014-07-31 23:51:43.000000000 +0200
  51952. +++ linux-linaro-stable-mx6/drivers/ata/pata_cmd640.c 2014-08-20 19:31:42.324852677 +0200
  51953. @@ -15,7 +15,6 @@
  51954. #include <linux/kernel.h>
  51955. #include <linux/module.h>
  51956. #include <linux/pci.h>
  51957. -#include <linux/init.h>
  51958. #include <linux/blkdev.h>
  51959. #include <linux/delay.h>
  51960. #include <linux/gfp.h>
  51961. diff -Nur linux-3.14.15/drivers/ata/pata_cmd64x.c linux-linaro-stable-mx6/drivers/ata/pata_cmd64x.c
  51962. --- linux-3.14.15/drivers/ata/pata_cmd64x.c 2014-07-31 23:51:43.000000000 +0200
  51963. +++ linux-linaro-stable-mx6/drivers/ata/pata_cmd64x.c 2014-08-20 19:31:42.324852677 +0200
  51964. @@ -26,7 +26,6 @@
  51965. #include <linux/kernel.h>
  51966. #include <linux/module.h>
  51967. #include <linux/pci.h>
  51968. -#include <linux/init.h>
  51969. #include <linux/blkdev.h>
  51970. #include <linux/delay.h>
  51971. #include <scsi/scsi_host.h>
  51972. diff -Nur linux-3.14.15/drivers/ata/pata_cs5520.c linux-linaro-stable-mx6/drivers/ata/pata_cs5520.c
  51973. --- linux-3.14.15/drivers/ata/pata_cs5520.c 2014-07-31 23:51:43.000000000 +0200
  51974. +++ linux-linaro-stable-mx6/drivers/ata/pata_cs5520.c 2014-08-20 19:31:42.324852677 +0200
  51975. @@ -34,7 +34,6 @@
  51976. #include <linux/kernel.h>
  51977. #include <linux/module.h>
  51978. #include <linux/pci.h>
  51979. -#include <linux/init.h>
  51980. #include <linux/blkdev.h>
  51981. #include <linux/delay.h>
  51982. #include <scsi/scsi_host.h>
  51983. diff -Nur linux-3.14.15/drivers/ata/pata_cs5530.c linux-linaro-stable-mx6/drivers/ata/pata_cs5530.c
  51984. --- linux-3.14.15/drivers/ata/pata_cs5530.c 2014-07-31 23:51:43.000000000 +0200
  51985. +++ linux-linaro-stable-mx6/drivers/ata/pata_cs5530.c 2014-08-20 19:31:42.324852677 +0200
  51986. @@ -26,7 +26,6 @@
  51987. #include <linux/kernel.h>
  51988. #include <linux/module.h>
  51989. #include <linux/pci.h>
  51990. -#include <linux/init.h>
  51991. #include <linux/blkdev.h>
  51992. #include <linux/delay.h>
  51993. #include <scsi/scsi_host.h>
  51994. diff -Nur linux-3.14.15/drivers/ata/pata_cs5535.c linux-linaro-stable-mx6/drivers/ata/pata_cs5535.c
  51995. --- linux-3.14.15/drivers/ata/pata_cs5535.c 2014-07-31 23:51:43.000000000 +0200
  51996. +++ linux-linaro-stable-mx6/drivers/ata/pata_cs5535.c 2014-08-20 19:31:42.324852677 +0200
  51997. @@ -31,7 +31,6 @@
  51998. #include <linux/kernel.h>
  51999. #include <linux/module.h>
  52000. #include <linux/pci.h>
  52001. -#include <linux/init.h>
  52002. #include <linux/blkdev.h>
  52003. #include <linux/delay.h>
  52004. #include <scsi/scsi_host.h>
  52005. diff -Nur linux-3.14.15/drivers/ata/pata_cs5536.c linux-linaro-stable-mx6/drivers/ata/pata_cs5536.c
  52006. --- linux-3.14.15/drivers/ata/pata_cs5536.c 2014-07-31 23:51:43.000000000 +0200
  52007. +++ linux-linaro-stable-mx6/drivers/ata/pata_cs5536.c 2014-08-20 19:31:42.324852677 +0200
  52008. @@ -33,7 +33,6 @@
  52009. #include <linux/kernel.h>
  52010. #include <linux/module.h>
  52011. #include <linux/pci.h>
  52012. -#include <linux/init.h>
  52013. #include <linux/blkdev.h>
  52014. #include <linux/delay.h>
  52015. #include <linux/libata.h>
  52016. diff -Nur linux-3.14.15/drivers/ata/pata_cypress.c linux-linaro-stable-mx6/drivers/ata/pata_cypress.c
  52017. --- linux-3.14.15/drivers/ata/pata_cypress.c 2014-07-31 23:51:43.000000000 +0200
  52018. +++ linux-linaro-stable-mx6/drivers/ata/pata_cypress.c 2014-08-20 19:31:42.324852677 +0200
  52019. @@ -11,7 +11,6 @@
  52020. #include <linux/kernel.h>
  52021. #include <linux/module.h>
  52022. #include <linux/pci.h>
  52023. -#include <linux/init.h>
  52024. #include <linux/blkdev.h>
  52025. #include <linux/delay.h>
  52026. #include <scsi/scsi_host.h>
  52027. diff -Nur linux-3.14.15/drivers/ata/pata_efar.c linux-linaro-stable-mx6/drivers/ata/pata_efar.c
  52028. --- linux-3.14.15/drivers/ata/pata_efar.c 2014-07-31 23:51:43.000000000 +0200
  52029. +++ linux-linaro-stable-mx6/drivers/ata/pata_efar.c 2014-08-20 19:31:42.324852677 +0200
  52030. @@ -14,7 +14,6 @@
  52031. #include <linux/kernel.h>
  52032. #include <linux/module.h>
  52033. #include <linux/pci.h>
  52034. -#include <linux/init.h>
  52035. #include <linux/blkdev.h>
  52036. #include <linux/delay.h>
  52037. #include <linux/device.h>
  52038. diff -Nur linux-3.14.15/drivers/ata/pata_ep93xx.c linux-linaro-stable-mx6/drivers/ata/pata_ep93xx.c
  52039. --- linux-3.14.15/drivers/ata/pata_ep93xx.c 2014-07-31 23:51:43.000000000 +0200
  52040. +++ linux-linaro-stable-mx6/drivers/ata/pata_ep93xx.c 2014-08-20 19:31:42.324852677 +0200
  52041. @@ -34,7 +34,6 @@
  52042. #include <linux/err.h>
  52043. #include <linux/kernel.h>
  52044. #include <linux/module.h>
  52045. -#include <linux/init.h>
  52046. #include <linux/blkdev.h>
  52047. #include <scsi/scsi_host.h>
  52048. #include <linux/ata.h>
  52049. diff -Nur linux-3.14.15/drivers/ata/pata_hpt366.c linux-linaro-stable-mx6/drivers/ata/pata_hpt366.c
  52050. --- linux-3.14.15/drivers/ata/pata_hpt366.c 2014-07-31 23:51:43.000000000 +0200
  52051. +++ linux-linaro-stable-mx6/drivers/ata/pata_hpt366.c 2014-08-20 19:31:42.324852677 +0200
  52052. @@ -19,7 +19,6 @@
  52053. #include <linux/kernel.h>
  52054. #include <linux/module.h>
  52055. #include <linux/pci.h>
  52056. -#include <linux/init.h>
  52057. #include <linux/blkdev.h>
  52058. #include <linux/delay.h>
  52059. #include <scsi/scsi_host.h>
  52060. diff -Nur linux-3.14.15/drivers/ata/pata_hpt37x.c linux-linaro-stable-mx6/drivers/ata/pata_hpt37x.c
  52061. --- linux-3.14.15/drivers/ata/pata_hpt37x.c 2014-07-31 23:51:43.000000000 +0200
  52062. +++ linux-linaro-stable-mx6/drivers/ata/pata_hpt37x.c 2014-08-20 19:31:42.324852677 +0200
  52063. @@ -19,7 +19,6 @@
  52064. #include <linux/kernel.h>
  52065. #include <linux/module.h>
  52066. #include <linux/pci.h>
  52067. -#include <linux/init.h>
  52068. #include <linux/blkdev.h>
  52069. #include <linux/delay.h>
  52070. #include <scsi/scsi_host.h>
  52071. diff -Nur linux-3.14.15/drivers/ata/pata_hpt3x2n.c linux-linaro-stable-mx6/drivers/ata/pata_hpt3x2n.c
  52072. --- linux-3.14.15/drivers/ata/pata_hpt3x2n.c 2014-07-31 23:51:43.000000000 +0200
  52073. +++ linux-linaro-stable-mx6/drivers/ata/pata_hpt3x2n.c 2014-08-20 19:31:42.324852677 +0200
  52074. @@ -20,7 +20,6 @@
  52075. #include <linux/kernel.h>
  52076. #include <linux/module.h>
  52077. #include <linux/pci.h>
  52078. -#include <linux/init.h>
  52079. #include <linux/blkdev.h>
  52080. #include <linux/delay.h>
  52081. #include <scsi/scsi_host.h>
  52082. diff -Nur linux-3.14.15/drivers/ata/pata_hpt3x3.c linux-linaro-stable-mx6/drivers/ata/pata_hpt3x3.c
  52083. --- linux-3.14.15/drivers/ata/pata_hpt3x3.c 2014-07-31 23:51:43.000000000 +0200
  52084. +++ linux-linaro-stable-mx6/drivers/ata/pata_hpt3x3.c 2014-08-20 19:31:42.324852677 +0200
  52085. @@ -16,7 +16,6 @@
  52086. #include <linux/kernel.h>
  52087. #include <linux/module.h>
  52088. #include <linux/pci.h>
  52089. -#include <linux/init.h>
  52090. #include <linux/blkdev.h>
  52091. #include <linux/delay.h>
  52092. #include <scsi/scsi_host.h>
  52093. diff -Nur linux-3.14.15/drivers/ata/pata_imx.c linux-linaro-stable-mx6/drivers/ata/pata_imx.c
  52094. --- linux-3.14.15/drivers/ata/pata_imx.c 2014-07-31 23:51:43.000000000 +0200
  52095. +++ linux-linaro-stable-mx6/drivers/ata/pata_imx.c 2014-08-20 19:31:42.324852677 +0200
  52096. @@ -15,7 +15,6 @@
  52097. */
  52098. #include <linux/kernel.h>
  52099. #include <linux/module.h>
  52100. -#include <linux/init.h>
  52101. #include <linux/blkdev.h>
  52102. #include <scsi/scsi_host.h>
  52103. #include <linux/ata.h>
  52104. diff -Nur linux-3.14.15/drivers/ata/pata_it8213.c linux-linaro-stable-mx6/drivers/ata/pata_it8213.c
  52105. --- linux-3.14.15/drivers/ata/pata_it8213.c 2014-07-31 23:51:43.000000000 +0200
  52106. +++ linux-linaro-stable-mx6/drivers/ata/pata_it8213.c 2014-08-20 19:31:42.328852693 +0200
  52107. @@ -10,7 +10,6 @@
  52108. #include <linux/kernel.h>
  52109. #include <linux/module.h>
  52110. #include <linux/pci.h>
  52111. -#include <linux/init.h>
  52112. #include <linux/blkdev.h>
  52113. #include <linux/delay.h>
  52114. #include <linux/device.h>
  52115. diff -Nur linux-3.14.15/drivers/ata/pata_it821x.c linux-linaro-stable-mx6/drivers/ata/pata_it821x.c
  52116. --- linux-3.14.15/drivers/ata/pata_it821x.c 2014-07-31 23:51:43.000000000 +0200
  52117. +++ linux-linaro-stable-mx6/drivers/ata/pata_it821x.c 2014-08-20 19:31:42.328852693 +0200
  52118. @@ -72,7 +72,6 @@
  52119. #include <linux/kernel.h>
  52120. #include <linux/module.h>
  52121. #include <linux/pci.h>
  52122. -#include <linux/init.h>
  52123. #include <linux/blkdev.h>
  52124. #include <linux/delay.h>
  52125. #include <linux/slab.h>
  52126. diff -Nur linux-3.14.15/drivers/ata/pata_jmicron.c linux-linaro-stable-mx6/drivers/ata/pata_jmicron.c
  52127. --- linux-3.14.15/drivers/ata/pata_jmicron.c 2014-07-31 23:51:43.000000000 +0200
  52128. +++ linux-linaro-stable-mx6/drivers/ata/pata_jmicron.c 2014-08-20 19:31:42.328852693 +0200
  52129. @@ -10,7 +10,6 @@
  52130. #include <linux/kernel.h>
  52131. #include <linux/module.h>
  52132. #include <linux/pci.h>
  52133. -#include <linux/init.h>
  52134. #include <linux/blkdev.h>
  52135. #include <linux/delay.h>
  52136. #include <linux/device.h>
  52137. diff -Nur linux-3.14.15/drivers/ata/pata_marvell.c linux-linaro-stable-mx6/drivers/ata/pata_marvell.c
  52138. --- linux-3.14.15/drivers/ata/pata_marvell.c 2014-07-31 23:51:43.000000000 +0200
  52139. +++ linux-linaro-stable-mx6/drivers/ata/pata_marvell.c 2014-08-20 19:31:42.328852693 +0200
  52140. @@ -11,7 +11,6 @@
  52141. #include <linux/kernel.h>
  52142. #include <linux/module.h>
  52143. #include <linux/pci.h>
  52144. -#include <linux/init.h>
  52145. #include <linux/blkdev.h>
  52146. #include <linux/delay.h>
  52147. #include <linux/device.h>
  52148. diff -Nur linux-3.14.15/drivers/ata/pata_mpiix.c linux-linaro-stable-mx6/drivers/ata/pata_mpiix.c
  52149. --- linux-3.14.15/drivers/ata/pata_mpiix.c 2014-07-31 23:51:43.000000000 +0200
  52150. +++ linux-linaro-stable-mx6/drivers/ata/pata_mpiix.c 2014-08-20 19:31:42.328852693 +0200
  52151. @@ -28,7 +28,6 @@
  52152. #include <linux/kernel.h>
  52153. #include <linux/module.h>
  52154. #include <linux/pci.h>
  52155. -#include <linux/init.h>
  52156. #include <linux/blkdev.h>
  52157. #include <linux/delay.h>
  52158. #include <scsi/scsi_host.h>
  52159. diff -Nur linux-3.14.15/drivers/ata/pata_netcell.c linux-linaro-stable-mx6/drivers/ata/pata_netcell.c
  52160. --- linux-3.14.15/drivers/ata/pata_netcell.c 2014-07-31 23:51:43.000000000 +0200
  52161. +++ linux-linaro-stable-mx6/drivers/ata/pata_netcell.c 2014-08-20 19:31:42.328852693 +0200
  52162. @@ -7,7 +7,6 @@
  52163. #include <linux/kernel.h>
  52164. #include <linux/module.h>
  52165. #include <linux/pci.h>
  52166. -#include <linux/init.h>
  52167. #include <linux/blkdev.h>
  52168. #include <linux/delay.h>
  52169. #include <linux/device.h>
  52170. diff -Nur linux-3.14.15/drivers/ata/pata_ninja32.c linux-linaro-stable-mx6/drivers/ata/pata_ninja32.c
  52171. --- linux-3.14.15/drivers/ata/pata_ninja32.c 2014-07-31 23:51:43.000000000 +0200
  52172. +++ linux-linaro-stable-mx6/drivers/ata/pata_ninja32.c 2014-08-20 19:31:42.328852693 +0200
  52173. @@ -37,7 +37,6 @@
  52174. #include <linux/kernel.h>
  52175. #include <linux/module.h>
  52176. #include <linux/pci.h>
  52177. -#include <linux/init.h>
  52178. #include <linux/blkdev.h>
  52179. #include <linux/delay.h>
  52180. #include <scsi/scsi_host.h>
  52181. diff -Nur linux-3.14.15/drivers/ata/pata_ns87410.c linux-linaro-stable-mx6/drivers/ata/pata_ns87410.c
  52182. --- linux-3.14.15/drivers/ata/pata_ns87410.c 2014-07-31 23:51:43.000000000 +0200
  52183. +++ linux-linaro-stable-mx6/drivers/ata/pata_ns87410.c 2014-08-20 19:31:42.328852693 +0200
  52184. @@ -20,7 +20,6 @@
  52185. #include <linux/kernel.h>
  52186. #include <linux/module.h>
  52187. #include <linux/pci.h>
  52188. -#include <linux/init.h>
  52189. #include <linux/blkdev.h>
  52190. #include <linux/delay.h>
  52191. #include <scsi/scsi_host.h>
  52192. diff -Nur linux-3.14.15/drivers/ata/pata_ns87415.c linux-linaro-stable-mx6/drivers/ata/pata_ns87415.c
  52193. --- linux-3.14.15/drivers/ata/pata_ns87415.c 2014-07-31 23:51:43.000000000 +0200
  52194. +++ linux-linaro-stable-mx6/drivers/ata/pata_ns87415.c 2014-08-20 19:31:42.328852693 +0200
  52195. @@ -25,7 +25,6 @@
  52196. #include <linux/kernel.h>
  52197. #include <linux/module.h>
  52198. #include <linux/pci.h>
  52199. -#include <linux/init.h>
  52200. #include <linux/blkdev.h>
  52201. #include <linux/delay.h>
  52202. #include <linux/device.h>
  52203. diff -Nur linux-3.14.15/drivers/ata/pata_oldpiix.c linux-linaro-stable-mx6/drivers/ata/pata_oldpiix.c
  52204. --- linux-3.14.15/drivers/ata/pata_oldpiix.c 2014-07-31 23:51:43.000000000 +0200
  52205. +++ linux-linaro-stable-mx6/drivers/ata/pata_oldpiix.c 2014-08-20 19:31:42.328852693 +0200
  52206. @@ -16,7 +16,6 @@
  52207. #include <linux/kernel.h>
  52208. #include <linux/module.h>
  52209. #include <linux/pci.h>
  52210. -#include <linux/init.h>
  52211. #include <linux/blkdev.h>
  52212. #include <linux/delay.h>
  52213. #include <linux/device.h>
  52214. diff -Nur linux-3.14.15/drivers/ata/pata_opti.c linux-linaro-stable-mx6/drivers/ata/pata_opti.c
  52215. --- linux-3.14.15/drivers/ata/pata_opti.c 2014-07-31 23:51:43.000000000 +0200
  52216. +++ linux-linaro-stable-mx6/drivers/ata/pata_opti.c 2014-08-20 19:31:42.328852693 +0200
  52217. @@ -26,7 +26,6 @@
  52218. #include <linux/kernel.h>
  52219. #include <linux/module.h>
  52220. #include <linux/pci.h>
  52221. -#include <linux/init.h>
  52222. #include <linux/blkdev.h>
  52223. #include <linux/delay.h>
  52224. #include <scsi/scsi_host.h>
  52225. diff -Nur linux-3.14.15/drivers/ata/pata_optidma.c linux-linaro-stable-mx6/drivers/ata/pata_optidma.c
  52226. --- linux-3.14.15/drivers/ata/pata_optidma.c 2014-07-31 23:51:43.000000000 +0200
  52227. +++ linux-linaro-stable-mx6/drivers/ata/pata_optidma.c 2014-08-20 19:31:42.328852693 +0200
  52228. @@ -25,7 +25,6 @@
  52229. #include <linux/kernel.h>
  52230. #include <linux/module.h>
  52231. #include <linux/pci.h>
  52232. -#include <linux/init.h>
  52233. #include <linux/blkdev.h>
  52234. #include <linux/delay.h>
  52235. #include <scsi/scsi_host.h>
  52236. diff -Nur linux-3.14.15/drivers/ata/pata_pcmcia.c linux-linaro-stable-mx6/drivers/ata/pata_pcmcia.c
  52237. --- linux-3.14.15/drivers/ata/pata_pcmcia.c 2014-07-31 23:51:43.000000000 +0200
  52238. +++ linux-linaro-stable-mx6/drivers/ata/pata_pcmcia.c 2014-08-20 19:31:42.328852693 +0200
  52239. @@ -26,7 +26,6 @@
  52240. #include <linux/kernel.h>
  52241. #include <linux/module.h>
  52242. -#include <linux/init.h>
  52243. #include <linux/blkdev.h>
  52244. #include <linux/delay.h>
  52245. #include <linux/slab.h>
  52246. diff -Nur linux-3.14.15/drivers/ata/pata_pdc2027x.c linux-linaro-stable-mx6/drivers/ata/pata_pdc2027x.c
  52247. --- linux-3.14.15/drivers/ata/pata_pdc2027x.c 2014-07-31 23:51:43.000000000 +0200
  52248. +++ linux-linaro-stable-mx6/drivers/ata/pata_pdc2027x.c 2014-08-20 19:31:42.332852711 +0200
  52249. @@ -25,7 +25,6 @@
  52250. #include <linux/kernel.h>
  52251. #include <linux/module.h>
  52252. #include <linux/pci.h>
  52253. -#include <linux/init.h>
  52254. #include <linux/blkdev.h>
  52255. #include <linux/delay.h>
  52256. #include <linux/device.h>
  52257. diff -Nur linux-3.14.15/drivers/ata/pata_pdc202xx_old.c linux-linaro-stable-mx6/drivers/ata/pata_pdc202xx_old.c
  52258. --- linux-3.14.15/drivers/ata/pata_pdc202xx_old.c 2014-07-31 23:51:43.000000000 +0200
  52259. +++ linux-linaro-stable-mx6/drivers/ata/pata_pdc202xx_old.c 2014-08-20 19:31:42.332852711 +0200
  52260. @@ -15,7 +15,6 @@
  52261. #include <linux/kernel.h>
  52262. #include <linux/module.h>
  52263. #include <linux/pci.h>
  52264. -#include <linux/init.h>
  52265. #include <linux/blkdev.h>
  52266. #include <linux/delay.h>
  52267. #include <scsi/scsi_host.h>
  52268. diff -Nur linux-3.14.15/drivers/ata/pata_piccolo.c linux-linaro-stable-mx6/drivers/ata/pata_piccolo.c
  52269. --- linux-3.14.15/drivers/ata/pata_piccolo.c 2014-07-31 23:51:43.000000000 +0200
  52270. +++ linux-linaro-stable-mx6/drivers/ata/pata_piccolo.c 2014-08-20 19:31:42.332852711 +0200
  52271. @@ -18,7 +18,6 @@
  52272. #include <linux/kernel.h>
  52273. #include <linux/module.h>
  52274. #include <linux/pci.h>
  52275. -#include <linux/init.h>
  52276. #include <linux/blkdev.h>
  52277. #include <linux/delay.h>
  52278. #include <scsi/scsi_host.h>
  52279. diff -Nur linux-3.14.15/drivers/ata/pata_platform.c linux-linaro-stable-mx6/drivers/ata/pata_platform.c
  52280. --- linux-3.14.15/drivers/ata/pata_platform.c 2014-07-31 23:51:43.000000000 +0200
  52281. +++ linux-linaro-stable-mx6/drivers/ata/pata_platform.c 2014-08-20 19:31:42.332852711 +0200
  52282. @@ -13,7 +13,6 @@
  52283. */
  52284. #include <linux/kernel.h>
  52285. #include <linux/module.h>
  52286. -#include <linux/init.h>
  52287. #include <linux/blkdev.h>
  52288. #include <scsi/scsi_host.h>
  52289. #include <linux/ata.h>
  52290. diff -Nur linux-3.14.15/drivers/ata/pata_pxa.c linux-linaro-stable-mx6/drivers/ata/pata_pxa.c
  52291. --- linux-3.14.15/drivers/ata/pata_pxa.c 2014-07-31 23:51:43.000000000 +0200
  52292. +++ linux-linaro-stable-mx6/drivers/ata/pata_pxa.c 2014-08-20 19:31:42.332852711 +0200
  52293. @@ -20,7 +20,6 @@
  52294. #include <linux/kernel.h>
  52295. #include <linux/module.h>
  52296. -#include <linux/init.h>
  52297. #include <linux/blkdev.h>
  52298. #include <linux/ata.h>
  52299. #include <linux/libata.h>
  52300. diff -Nur linux-3.14.15/drivers/ata/pata_radisys.c linux-linaro-stable-mx6/drivers/ata/pata_radisys.c
  52301. --- linux-3.14.15/drivers/ata/pata_radisys.c 2014-07-31 23:51:43.000000000 +0200
  52302. +++ linux-linaro-stable-mx6/drivers/ata/pata_radisys.c 2014-08-20 19:31:42.332852711 +0200
  52303. @@ -15,7 +15,6 @@
  52304. #include <linux/kernel.h>
  52305. #include <linux/module.h>
  52306. #include <linux/pci.h>
  52307. -#include <linux/init.h>
  52308. #include <linux/blkdev.h>
  52309. #include <linux/delay.h>
  52310. #include <linux/device.h>
  52311. diff -Nur linux-3.14.15/drivers/ata/pata_rdc.c linux-linaro-stable-mx6/drivers/ata/pata_rdc.c
  52312. --- linux-3.14.15/drivers/ata/pata_rdc.c 2014-07-31 23:51:43.000000000 +0200
  52313. +++ linux-linaro-stable-mx6/drivers/ata/pata_rdc.c 2014-08-20 19:31:42.332852711 +0200
  52314. @@ -24,7 +24,6 @@
  52315. #include <linux/kernel.h>
  52316. #include <linux/module.h>
  52317. #include <linux/pci.h>
  52318. -#include <linux/init.h>
  52319. #include <linux/blkdev.h>
  52320. #include <linux/delay.h>
  52321. #include <linux/device.h>
  52322. diff -Nur linux-3.14.15/drivers/ata/pata_rz1000.c linux-linaro-stable-mx6/drivers/ata/pata_rz1000.c
  52323. --- linux-3.14.15/drivers/ata/pata_rz1000.c 2014-07-31 23:51:43.000000000 +0200
  52324. +++ linux-linaro-stable-mx6/drivers/ata/pata_rz1000.c 2014-08-20 19:31:42.332852711 +0200
  52325. @@ -14,7 +14,6 @@
  52326. #include <linux/kernel.h>
  52327. #include <linux/module.h>
  52328. #include <linux/pci.h>
  52329. -#include <linux/init.h>
  52330. #include <linux/blkdev.h>
  52331. #include <linux/delay.h>
  52332. #include <scsi/scsi_host.h>
  52333. diff -Nur linux-3.14.15/drivers/ata/pata_sc1200.c linux-linaro-stable-mx6/drivers/ata/pata_sc1200.c
  52334. --- linux-3.14.15/drivers/ata/pata_sc1200.c 2014-07-31 23:51:43.000000000 +0200
  52335. +++ linux-linaro-stable-mx6/drivers/ata/pata_sc1200.c 2014-08-20 19:31:42.336852729 +0200
  52336. @@ -32,7 +32,6 @@
  52337. #include <linux/kernel.h>
  52338. #include <linux/module.h>
  52339. #include <linux/pci.h>
  52340. -#include <linux/init.h>
  52341. #include <linux/blkdev.h>
  52342. #include <linux/delay.h>
  52343. #include <scsi/scsi_host.h>
  52344. diff -Nur linux-3.14.15/drivers/ata/pata_scc.c linux-linaro-stable-mx6/drivers/ata/pata_scc.c
  52345. --- linux-3.14.15/drivers/ata/pata_scc.c 2014-07-31 23:51:43.000000000 +0200
  52346. +++ linux-linaro-stable-mx6/drivers/ata/pata_scc.c 2014-08-20 19:31:42.336852729 +0200
  52347. @@ -35,7 +35,6 @@
  52348. #include <linux/kernel.h>
  52349. #include <linux/module.h>
  52350. #include <linux/pci.h>
  52351. -#include <linux/init.h>
  52352. #include <linux/blkdev.h>
  52353. #include <linux/delay.h>
  52354. #include <linux/device.h>
  52355. diff -Nur linux-3.14.15/drivers/ata/pata_sch.c linux-linaro-stable-mx6/drivers/ata/pata_sch.c
  52356. --- linux-3.14.15/drivers/ata/pata_sch.c 2014-07-31 23:51:43.000000000 +0200
  52357. +++ linux-linaro-stable-mx6/drivers/ata/pata_sch.c 2014-08-20 19:31:42.336852729 +0200
  52358. @@ -27,7 +27,6 @@
  52359. #include <linux/kernel.h>
  52360. #include <linux/module.h>
  52361. #include <linux/pci.h>
  52362. -#include <linux/init.h>
  52363. #include <linux/blkdev.h>
  52364. #include <linux/delay.h>
  52365. #include <linux/device.h>
  52366. diff -Nur linux-3.14.15/drivers/ata/pata_serverworks.c linux-linaro-stable-mx6/drivers/ata/pata_serverworks.c
  52367. --- linux-3.14.15/drivers/ata/pata_serverworks.c 2014-07-31 23:51:43.000000000 +0200
  52368. +++ linux-linaro-stable-mx6/drivers/ata/pata_serverworks.c 2014-08-20 19:31:42.336852729 +0200
  52369. @@ -34,7 +34,6 @@
  52370. #include <linux/kernel.h>
  52371. #include <linux/module.h>
  52372. #include <linux/pci.h>
  52373. -#include <linux/init.h>
  52374. #include <linux/blkdev.h>
  52375. #include <linux/delay.h>
  52376. #include <scsi/scsi_host.h>
  52377. diff -Nur linux-3.14.15/drivers/ata/pata_sil680.c linux-linaro-stable-mx6/drivers/ata/pata_sil680.c
  52378. --- linux-3.14.15/drivers/ata/pata_sil680.c 2014-07-31 23:51:43.000000000 +0200
  52379. +++ linux-linaro-stable-mx6/drivers/ata/pata_sil680.c 2014-08-20 19:31:42.340852746 +0200
  52380. @@ -25,7 +25,6 @@
  52381. #include <linux/kernel.h>
  52382. #include <linux/module.h>
  52383. #include <linux/pci.h>
  52384. -#include <linux/init.h>
  52385. #include <linux/blkdev.h>
  52386. #include <linux/delay.h>
  52387. #include <scsi/scsi_host.h>
  52388. diff -Nur linux-3.14.15/drivers/ata/pata_sis.c linux-linaro-stable-mx6/drivers/ata/pata_sis.c
  52389. --- linux-3.14.15/drivers/ata/pata_sis.c 2014-07-31 23:51:43.000000000 +0200
  52390. +++ linux-linaro-stable-mx6/drivers/ata/pata_sis.c 2014-08-20 19:31:42.340852746 +0200
  52391. @@ -26,7 +26,6 @@
  52392. #include <linux/kernel.h>
  52393. #include <linux/module.h>
  52394. #include <linux/pci.h>
  52395. -#include <linux/init.h>
  52396. #include <linux/blkdev.h>
  52397. #include <linux/delay.h>
  52398. #include <linux/device.h>
  52399. diff -Nur linux-3.14.15/drivers/ata/pata_sl82c105.c linux-linaro-stable-mx6/drivers/ata/pata_sl82c105.c
  52400. --- linux-3.14.15/drivers/ata/pata_sl82c105.c 2014-07-31 23:51:43.000000000 +0200
  52401. +++ linux-linaro-stable-mx6/drivers/ata/pata_sl82c105.c 2014-08-20 19:31:42.340852746 +0200
  52402. @@ -19,7 +19,6 @@
  52403. #include <linux/kernel.h>
  52404. #include <linux/module.h>
  52405. #include <linux/pci.h>
  52406. -#include <linux/init.h>
  52407. #include <linux/blkdev.h>
  52408. #include <linux/delay.h>
  52409. #include <scsi/scsi_host.h>
  52410. diff -Nur linux-3.14.15/drivers/ata/pata_triflex.c linux-linaro-stable-mx6/drivers/ata/pata_triflex.c
  52411. --- linux-3.14.15/drivers/ata/pata_triflex.c 2014-07-31 23:51:43.000000000 +0200
  52412. +++ linux-linaro-stable-mx6/drivers/ata/pata_triflex.c 2014-08-20 19:31:42.340852746 +0200
  52413. @@ -36,7 +36,6 @@
  52414. #include <linux/kernel.h>
  52415. #include <linux/module.h>
  52416. #include <linux/pci.h>
  52417. -#include <linux/init.h>
  52418. #include <linux/blkdev.h>
  52419. #include <linux/delay.h>
  52420. #include <scsi/scsi_host.h>
  52421. diff -Nur linux-3.14.15/drivers/ata/pata_via.c linux-linaro-stable-mx6/drivers/ata/pata_via.c
  52422. --- linux-3.14.15/drivers/ata/pata_via.c 2014-07-31 23:51:43.000000000 +0200
  52423. +++ linux-linaro-stable-mx6/drivers/ata/pata_via.c 2014-08-20 19:31:42.344852763 +0200
  52424. @@ -55,7 +55,6 @@
  52425. #include <linux/kernel.h>
  52426. #include <linux/module.h>
  52427. #include <linux/pci.h>
  52428. -#include <linux/init.h>
  52429. #include <linux/blkdev.h>
  52430. #include <linux/delay.h>
  52431. #include <linux/gfp.h>
  52432. diff -Nur linux-3.14.15/drivers/ata/pdc_adma.c linux-linaro-stable-mx6/drivers/ata/pdc_adma.c
  52433. --- linux-3.14.15/drivers/ata/pdc_adma.c 2014-07-31 23:51:43.000000000 +0200
  52434. +++ linux-linaro-stable-mx6/drivers/ata/pdc_adma.c 2014-08-20 19:31:42.344852763 +0200
  52435. @@ -36,7 +36,6 @@
  52436. #include <linux/module.h>
  52437. #include <linux/gfp.h>
  52438. #include <linux/pci.h>
  52439. -#include <linux/init.h>
  52440. #include <linux/blkdev.h>
  52441. #include <linux/delay.h>
  52442. #include <linux/interrupt.h>
  52443. diff -Nur linux-3.14.15/drivers/ata/sata_dwc_460ex.c linux-linaro-stable-mx6/drivers/ata/sata_dwc_460ex.c
  52444. --- linux-3.14.15/drivers/ata/sata_dwc_460ex.c 2014-07-31 23:51:43.000000000 +0200
  52445. +++ linux-linaro-stable-mx6/drivers/ata/sata_dwc_460ex.c 2014-08-20 19:31:42.344852763 +0200
  52446. @@ -29,7 +29,6 @@
  52447. #include <linux/kernel.h>
  52448. #include <linux/module.h>
  52449. -#include <linux/init.h>
  52450. #include <linux/device.h>
  52451. #include <linux/of_address.h>
  52452. #include <linux/of_irq.h>
  52453. diff -Nur linux-3.14.15/drivers/ata/sata_highbank.c linux-linaro-stable-mx6/drivers/ata/sata_highbank.c
  52454. --- linux-3.14.15/drivers/ata/sata_highbank.c 2014-07-31 23:51:43.000000000 +0200
  52455. +++ linux-linaro-stable-mx6/drivers/ata/sata_highbank.c 2014-08-20 19:31:42.348852780 +0200
  52456. @@ -19,7 +19,6 @@
  52457. #include <linux/kernel.h>
  52458. #include <linux/gfp.h>
  52459. #include <linux/module.h>
  52460. -#include <linux/init.h>
  52461. #include <linux/types.h>
  52462. #include <linux/err.h>
  52463. #include <linux/io.h>
  52464. @@ -403,6 +402,7 @@
  52465. static const unsigned long timing[] = { 5, 100, 500};
  52466. struct ata_port *ap = link->ap;
  52467. struct ahci_port_priv *pp = ap->private_data;
  52468. + struct ahci_host_priv *hpriv = ap->host->private_data;
  52469. u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
  52470. struct ata_taskfile tf;
  52471. bool online;
  52472. @@ -431,7 +431,7 @@
  52473. break;
  52474. } while (!online && retry--);
  52475. - ahci_start_engine(ap);
  52476. + hpriv->start_engine(ap);
  52477. if (online)
  52478. *class = ahci_dev_classify(ap);
  52479. diff -Nur linux-3.14.15/drivers/ata/sata_nv.c linux-linaro-stable-mx6/drivers/ata/sata_nv.c
  52480. --- linux-3.14.15/drivers/ata/sata_nv.c 2014-07-31 23:51:43.000000000 +0200
  52481. +++ linux-linaro-stable-mx6/drivers/ata/sata_nv.c 2014-08-20 19:31:42.352852797 +0200
  52482. @@ -40,7 +40,6 @@
  52483. #include <linux/module.h>
  52484. #include <linux/gfp.h>
  52485. #include <linux/pci.h>
  52486. -#include <linux/init.h>
  52487. #include <linux/blkdev.h>
  52488. #include <linux/delay.h>
  52489. #include <linux/interrupt.h>
  52490. diff -Nur linux-3.14.15/drivers/ata/sata_promise.c linux-linaro-stable-mx6/drivers/ata/sata_promise.c
  52491. --- linux-3.14.15/drivers/ata/sata_promise.c 2014-07-31 23:51:43.000000000 +0200
  52492. +++ linux-linaro-stable-mx6/drivers/ata/sata_promise.c 2014-08-20 19:31:42.352852797 +0200
  52493. @@ -35,7 +35,6 @@
  52494. #include <linux/module.h>
  52495. #include <linux/gfp.h>
  52496. #include <linux/pci.h>
  52497. -#include <linux/init.h>
  52498. #include <linux/blkdev.h>
  52499. #include <linux/delay.h>
  52500. #include <linux/interrupt.h>
  52501. diff -Nur linux-3.14.15/drivers/ata/sata_qstor.c linux-linaro-stable-mx6/drivers/ata/sata_qstor.c
  52502. --- linux-3.14.15/drivers/ata/sata_qstor.c 2014-07-31 23:51:43.000000000 +0200
  52503. +++ linux-linaro-stable-mx6/drivers/ata/sata_qstor.c 2014-08-20 19:31:42.352852797 +0200
  52504. @@ -31,7 +31,6 @@
  52505. #include <linux/module.h>
  52506. #include <linux/gfp.h>
  52507. #include <linux/pci.h>
  52508. -#include <linux/init.h>
  52509. #include <linux/blkdev.h>
  52510. #include <linux/delay.h>
  52511. #include <linux/interrupt.h>
  52512. diff -Nur linux-3.14.15/drivers/ata/sata_sil.c linux-linaro-stable-mx6/drivers/ata/sata_sil.c
  52513. --- linux-3.14.15/drivers/ata/sata_sil.c 2014-07-31 23:51:43.000000000 +0200
  52514. +++ linux-linaro-stable-mx6/drivers/ata/sata_sil.c 2014-08-20 19:31:42.356852813 +0200
  52515. @@ -37,7 +37,6 @@
  52516. #include <linux/kernel.h>
  52517. #include <linux/module.h>
  52518. #include <linux/pci.h>
  52519. -#include <linux/init.h>
  52520. #include <linux/blkdev.h>
  52521. #include <linux/delay.h>
  52522. #include <linux/interrupt.h>
  52523. diff -Nur linux-3.14.15/drivers/ata/sata_sis.c linux-linaro-stable-mx6/drivers/ata/sata_sis.c
  52524. --- linux-3.14.15/drivers/ata/sata_sis.c 2014-07-31 23:51:43.000000000 +0200
  52525. +++ linux-linaro-stable-mx6/drivers/ata/sata_sis.c 2014-08-20 19:31:42.360852831 +0200
  52526. @@ -33,7 +33,6 @@
  52527. #include <linux/kernel.h>
  52528. #include <linux/module.h>
  52529. #include <linux/pci.h>
  52530. -#include <linux/init.h>
  52531. #include <linux/blkdev.h>
  52532. #include <linux/delay.h>
  52533. #include <linux/interrupt.h>
  52534. diff -Nur linux-3.14.15/drivers/ata/sata_svw.c linux-linaro-stable-mx6/drivers/ata/sata_svw.c
  52535. --- linux-3.14.15/drivers/ata/sata_svw.c 2014-07-31 23:51:43.000000000 +0200
  52536. +++ linux-linaro-stable-mx6/drivers/ata/sata_svw.c 2014-08-20 19:31:42.360852831 +0200
  52537. @@ -39,7 +39,6 @@
  52538. #include <linux/kernel.h>
  52539. #include <linux/module.h>
  52540. #include <linux/pci.h>
  52541. -#include <linux/init.h>
  52542. #include <linux/blkdev.h>
  52543. #include <linux/delay.h>
  52544. #include <linux/interrupt.h>
  52545. diff -Nur linux-3.14.15/drivers/ata/sata_sx4.c linux-linaro-stable-mx6/drivers/ata/sata_sx4.c
  52546. --- linux-3.14.15/drivers/ata/sata_sx4.c 2014-07-31 23:51:43.000000000 +0200
  52547. +++ linux-linaro-stable-mx6/drivers/ata/sata_sx4.c 2014-08-20 19:31:42.360852831 +0200
  52548. @@ -82,7 +82,6 @@
  52549. #include <linux/module.h>
  52550. #include <linux/pci.h>
  52551. #include <linux/slab.h>
  52552. -#include <linux/init.h>
  52553. #include <linux/blkdev.h>
  52554. #include <linux/delay.h>
  52555. #include <linux/interrupt.h>
  52556. diff -Nur linux-3.14.15/drivers/ata/sata_uli.c linux-linaro-stable-mx6/drivers/ata/sata_uli.c
  52557. --- linux-3.14.15/drivers/ata/sata_uli.c 2014-07-31 23:51:43.000000000 +0200
  52558. +++ linux-linaro-stable-mx6/drivers/ata/sata_uli.c 2014-08-20 19:31:42.360852831 +0200
  52559. @@ -28,7 +28,6 @@
  52560. #include <linux/module.h>
  52561. #include <linux/gfp.h>
  52562. #include <linux/pci.h>
  52563. -#include <linux/init.h>
  52564. #include <linux/blkdev.h>
  52565. #include <linux/delay.h>
  52566. #include <linux/interrupt.h>
  52567. diff -Nur linux-3.14.15/drivers/ata/sata_via.c linux-linaro-stable-mx6/drivers/ata/sata_via.c
  52568. --- linux-3.14.15/drivers/ata/sata_via.c 2014-07-31 23:51:43.000000000 +0200
  52569. +++ linux-linaro-stable-mx6/drivers/ata/sata_via.c 2014-08-20 19:31:42.364852849 +0200
  52570. @@ -36,7 +36,6 @@
  52571. #include <linux/kernel.h>
  52572. #include <linux/module.h>
  52573. #include <linux/pci.h>
  52574. -#include <linux/init.h>
  52575. #include <linux/blkdev.h>
  52576. #include <linux/delay.h>
  52577. #include <linux/device.h>
  52578. diff -Nur linux-3.14.15/drivers/ata/sata_vsc.c linux-linaro-stable-mx6/drivers/ata/sata_vsc.c
  52579. --- linux-3.14.15/drivers/ata/sata_vsc.c 2014-07-31 23:51:43.000000000 +0200
  52580. +++ linux-linaro-stable-mx6/drivers/ata/sata_vsc.c 2014-08-20 19:31:42.364852849 +0200
  52581. @@ -37,7 +37,6 @@
  52582. #include <linux/kernel.h>
  52583. #include <linux/module.h>
  52584. #include <linux/pci.h>
  52585. -#include <linux/init.h>
  52586. #include <linux/blkdev.h>
  52587. #include <linux/delay.h>
  52588. #include <linux/interrupt.h>
  52589. diff -Nur linux-3.14.15/drivers/base/bus.c linux-linaro-stable-mx6/drivers/base/bus.c
  52590. --- linux-3.14.15/drivers/base/bus.c 2014-07-31 23:51:43.000000000 +0200
  52591. +++ linux-linaro-stable-mx6/drivers/base/bus.c 2014-08-20 19:31:42.368852866 +0200
  52592. @@ -1218,7 +1218,7 @@
  52593. * with the name of the subsystem. The root device can carry subsystem-
  52594. * wide attributes. All registered devices are below this single root
  52595. * device and are named after the subsystem with a simple enumeration
  52596. - * number appended. The registered devices are not explicitely named;
  52597. + * number appended. The registered devices are not explicitly named;
  52598. * only 'id' in the device needs to be set.
  52599. *
  52600. * Do not use this interface for anything new, it exists for compatibility
  52601. diff -Nur linux-3.14.15/drivers/base/cpu.c linux-linaro-stable-mx6/drivers/base/cpu.c
  52602. --- linux-3.14.15/drivers/base/cpu.c 2014-07-31 23:51:43.000000000 +0200
  52603. +++ linux-linaro-stable-mx6/drivers/base/cpu.c 2014-08-20 19:31:42.368852866 +0200
  52604. @@ -15,6 +15,7 @@
  52605. #include <linux/percpu.h>
  52606. #include <linux/acpi.h>
  52607. #include <linux/of.h>
  52608. +#include <linux/cpufeature.h>
  52609. #include "base.h"
  52610. @@ -286,6 +287,45 @@
  52611. */
  52612. }
  52613. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  52614. +#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
  52615. +static ssize_t print_cpu_modalias(struct device *dev,
  52616. + struct device_attribute *attr,
  52617. + char *buf)
  52618. +{
  52619. + ssize_t n;
  52620. + u32 i;
  52621. +
  52622. + n = sprintf(buf, "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:",
  52623. + CPU_FEATURE_TYPEVAL);
  52624. +
  52625. + for (i = 0; i < MAX_CPU_FEATURES; i++)
  52626. + if (cpu_have_feature(i)) {
  52627. + if (PAGE_SIZE < n + sizeof(",XXXX\n")) {
  52628. + WARN(1, "CPU features overflow page\n");
  52629. + break;
  52630. + }
  52631. + n += sprintf(&buf[n], ",%04X", i);
  52632. + }
  52633. + buf[n++] = '\n';
  52634. + return n;
  52635. +}
  52636. +#else
  52637. +#define print_cpu_modalias arch_print_cpu_modalias
  52638. +#endif
  52639. +
  52640. +static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
  52641. +{
  52642. + char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
  52643. + if (buf) {
  52644. + print_cpu_modalias(NULL, NULL, buf);
  52645. + add_uevent_var(env, "MODALIAS=%s", buf);
  52646. + kfree(buf);
  52647. + }
  52648. + return 0;
  52649. +}
  52650. +#endif
  52651. +
  52652. /*
  52653. * register_cpu - Setup a sysfs device for a CPU.
  52654. * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
  52655. @@ -306,8 +346,8 @@
  52656. cpu->dev.offline_disabled = !cpu->hotpluggable;
  52657. cpu->dev.offline = !cpu_online(num);
  52658. cpu->dev.of_node = of_get_cpu_node(num, NULL);
  52659. -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
  52660. - cpu->dev.bus->uevent = arch_cpu_uevent;
  52661. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  52662. + cpu->dev.bus->uevent = cpu_uevent;
  52663. #endif
  52664. cpu->dev.groups = common_cpu_attr_groups;
  52665. if (cpu->hotpluggable)
  52666. @@ -330,8 +370,8 @@
  52667. }
  52668. EXPORT_SYMBOL_GPL(get_cpu_device);
  52669. -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
  52670. -static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL);
  52671. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  52672. +static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
  52673. #endif
  52674. static struct attribute *cpu_root_attrs[] = {
  52675. @@ -344,7 +384,7 @@
  52676. &cpu_attrs[2].attr.attr,
  52677. &dev_attr_kernel_max.attr,
  52678. &dev_attr_offline.attr,
  52679. -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
  52680. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  52681. &dev_attr_modalias.attr,
  52682. #endif
  52683. NULL
  52684. diff -Nur linux-3.14.15/drivers/base/dma-buf.c linux-linaro-stable-mx6/drivers/base/dma-buf.c
  52685. --- linux-3.14.15/drivers/base/dma-buf.c 2014-07-31 23:51:43.000000000 +0200
  52686. +++ linux-linaro-stable-mx6/drivers/base/dma-buf.c 2014-08-20 19:31:42.372852883 +0200
  52687. @@ -251,9 +251,8 @@
  52688. * @dmabuf: [in] buffer to attach device to.
  52689. * @dev: [in] device to be attached.
  52690. *
  52691. - * Returns struct dma_buf_attachment * for this attachment; may return negative
  52692. - * error codes.
  52693. - *
  52694. + * Returns struct dma_buf_attachment * for this attachment; returns ERR_PTR on
  52695. + * error.
  52696. */
  52697. struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
  52698. struct device *dev)
  52699. @@ -319,9 +318,8 @@
  52700. * @attach: [in] attachment whose scatterlist is to be returned
  52701. * @direction: [in] direction of DMA transfer
  52702. *
  52703. - * Returns sg_table containing the scatterlist to be returned; may return NULL
  52704. - * or ERR_PTR.
  52705. - *
  52706. + * Returns sg_table containing the scatterlist to be returned; returns ERR_PTR
  52707. + * on error.
  52708. */
  52709. struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
  52710. enum dma_data_direction direction)
  52711. @@ -334,6 +332,8 @@
  52712. return ERR_PTR(-EINVAL);
  52713. sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction);
  52714. + if (!sg_table)
  52715. + sg_table = ERR_PTR(-ENOMEM);
  52716. return sg_table;
  52717. }
  52718. @@ -544,6 +544,8 @@
  52719. * These calls are optional in drivers. The intended use for them
  52720. * is for mapping objects linear in kernel space for high use objects.
  52721. * Please attempt to use kmap/kunmap before thinking about these interfaces.
  52722. + *
  52723. + * Returns NULL on error.
  52724. */
  52725. void *dma_buf_vmap(struct dma_buf *dmabuf)
  52726. {
  52727. @@ -566,7 +568,9 @@
  52728. BUG_ON(dmabuf->vmap_ptr);
  52729. ptr = dmabuf->ops->vmap(dmabuf);
  52730. - if (IS_ERR_OR_NULL(ptr))
  52731. + if (WARN_ON_ONCE(IS_ERR(ptr)))
  52732. + ptr = NULL;
  52733. + if (!ptr)
  52734. goto out_unlock;
  52735. dmabuf->vmap_ptr = ptr;
  52736. diff -Nur linux-3.14.15/drivers/base/Kconfig linux-linaro-stable-mx6/drivers/base/Kconfig
  52737. --- linux-3.14.15/drivers/base/Kconfig 2014-07-31 23:51:43.000000000 +0200
  52738. +++ linux-linaro-stable-mx6/drivers/base/Kconfig 2014-08-20 19:31:42.368852866 +0200
  52739. @@ -185,6 +185,14 @@
  52740. bool
  52741. default n
  52742. +config HAVE_CPU_AUTOPROBE
  52743. + def_bool ARCH_HAS_CPU_AUTOPROBE
  52744. +
  52745. +config GENERIC_CPU_AUTOPROBE
  52746. + bool
  52747. + depends on !ARCH_HAS_CPU_AUTOPROBE
  52748. + select HAVE_CPU_AUTOPROBE
  52749. +
  52750. config SOC_BUS
  52751. bool
  52752. diff -Nur linux-3.14.15/drivers/base/platform.c linux-linaro-stable-mx6/drivers/base/platform.c
  52753. --- linux-3.14.15/drivers/base/platform.c 2014-07-31 23:51:43.000000000 +0200
  52754. +++ linux-linaro-stable-mx6/drivers/base/platform.c 2014-08-20 19:31:42.372852883 +0200
  52755. @@ -89,13 +89,8 @@
  52756. return dev->archdata.irqs[num];
  52757. #else
  52758. struct resource *r;
  52759. - if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) {
  52760. - int ret;
  52761. -
  52762. - ret = of_irq_get(dev->dev.of_node, num);
  52763. - if (ret >= 0 || ret == -EPROBE_DEFER)
  52764. - return ret;
  52765. - }
  52766. + if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node)
  52767. + return of_irq_get(dev->dev.of_node, num);
  52768. r = platform_get_resource(dev, IORESOURCE_IRQ, num);
  52769. diff -Nur linux-3.14.15/drivers/bus/arm-cci.c linux-linaro-stable-mx6/drivers/bus/arm-cci.c
  52770. --- linux-3.14.15/drivers/bus/arm-cci.c 2014-07-31 23:51:43.000000000 +0200
  52771. +++ linux-linaro-stable-mx6/drivers/bus/arm-cci.c 2014-08-20 19:31:42.416853073 +0200
  52772. @@ -26,6 +26,7 @@
  52773. #include <asm/cacheflush.h>
  52774. #include <asm/irq_regs.h>
  52775. +#include <asm/psci.h>
  52776. #include <asm/pmu.h>
  52777. #include <asm/smp_plat.h>
  52778. @@ -544,6 +545,7 @@
  52779. cci_pmu->plat_device = pdev;
  52780. cci_pmu->num_events = pmu_get_max_counters();
  52781. + cpumask_setall(&cci_pmu->valid_cpus);
  52782. return armpmu_register(cci_pmu, -1);
  52783. }
  52784. @@ -969,6 +971,11 @@
  52785. const char *match_str;
  52786. bool is_ace;
  52787. + if (psci_probe() == 0) {
  52788. + pr_debug("psci found. Aborting cci probe\n");
  52789. + return -ENODEV;
  52790. + }
  52791. +
  52792. np = of_find_matching_node(NULL, arm_cci_matches);
  52793. if (!np)
  52794. return -ENODEV;
  52795. diff -Nur linux-3.14.15/drivers/char/fsl_otp.c linux-linaro-stable-mx6/drivers/char/fsl_otp.c
  52796. --- linux-3.14.15/drivers/char/fsl_otp.c 1970-01-01 01:00:00.000000000 +0100
  52797. +++ linux-linaro-stable-mx6/drivers/char/fsl_otp.c 2014-08-20 19:23:50.574833100 +0200
  52798. @@ -0,0 +1,299 @@
  52799. +/*
  52800. + * Freescale On-Chip OTP driver
  52801. + *
  52802. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  52803. + *
  52804. + * This program is free software; you can redistribute it and/or modify
  52805. + * it under the terms of the GNU General Public License as published by
  52806. + * the Free Software Foundation; either version 2 of the License, or
  52807. + * (at your option) any later version.
  52808. + *
  52809. + * This program is distributed in the hope that it will be useful,
  52810. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  52811. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  52812. + * GNU General Public License for more details.
  52813. + *
  52814. + * You should have received a copy of the GNU General Public License
  52815. + * along with this program; if not, write to the Free Software
  52816. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  52817. + */
  52818. +
  52819. +#include <linux/clk.h>
  52820. +#include <linux/delay.h>
  52821. +#include <linux/err.h>
  52822. +#include <linux/init.h>
  52823. +#include <linux/io.h>
  52824. +#include <linux/kobject.h>
  52825. +#include <linux/module.h>
  52826. +#include <linux/mutex.h>
  52827. +#include <linux/of.h>
  52828. +#include <linux/platform_device.h>
  52829. +#include <linux/slab.h>
  52830. +#include <linux/sysfs.h>
  52831. +
  52832. +#define HW_OCOTP_CTRL 0x00000000
  52833. +#define HW_OCOTP_CTRL_SET 0x00000004
  52834. +#define BP_OCOTP_CTRL_WR_UNLOCK 16
  52835. +#define BM_OCOTP_CTRL_WR_UNLOCK 0xFFFF0000
  52836. +#define BM_OCOTP_CTRL_RELOAD_SHADOWS 0x00000400
  52837. +#define BM_OCOTP_CTRL_ERROR 0x00000200
  52838. +#define BM_OCOTP_CTRL_BUSY 0x00000100
  52839. +#define BP_OCOTP_CTRL_ADDR 0
  52840. +#define BM_OCOTP_CTRL_ADDR 0x0000007F
  52841. +
  52842. +#define HW_OCOTP_TIMING 0x00000010
  52843. +#define BP_OCOTP_TIMING_STROBE_READ 16
  52844. +#define BM_OCOTP_TIMING_STROBE_READ 0x003F0000
  52845. +#define BP_OCOTP_TIMING_RELAX 12
  52846. +#define BM_OCOTP_TIMING_RELAX 0x0000F000
  52847. +#define BP_OCOTP_TIMING_STROBE_PROG 0
  52848. +#define BM_OCOTP_TIMING_STROBE_PROG 0x00000FFF
  52849. +
  52850. +#define HW_OCOTP_DATA 0x00000020
  52851. +
  52852. +#define HW_OCOTP_CUST_N(n) (0x00000400 + (n) * 0x10)
  52853. +#define BF(value, field) (((value) << BP_##field) & BM_##field)
  52854. +
  52855. +#define DEF_RELAX 20 /* > 16.5ns */
  52856. +
  52857. +#define BANK(a, b, c, d, e, f, g, h) { \
  52858. + "HW_OCOTP_"#a, "HW_OCOTP_"#b, "HW_OCOTP_"#c, "HW_OCOTP_"#d, \
  52859. + "HW_OCOTP_"#e, "HW_OCOTP_"#f, "HW_OCOTP_"#g, "HW_OCOTP_"#h, \
  52860. +}
  52861. +
  52862. +static const char *imx6q_otp_desc[16][8] = {
  52863. + BANK(LOCK, CFG0, CFG1, CFG2, CFG3, CFG4, CFG5, CFG6),
  52864. + BANK(MEM0, MEM1, MEM2, MEM3, MEM4, ANA0, ANA1, ANA2),
  52865. + BANK(OTPMK0, OTPMK1, OTPMK2, OTPMK3, OTPMK4, OTPMK5, OTPMK6, OTPMK7),
  52866. + BANK(SRK0, SRK1, SRK2, SRK3, SRK4, SRK5, SRK6, SRK7),
  52867. + BANK(RESP0, HSJC_RESP1, MAC0, MAC1, HDCP_KSV0, HDCP_KSV1, GP1, GP2),
  52868. + BANK(DTCP_KEY0, DTCP_KEY1, DTCP_KEY2, DTCP_KEY3, DTCP_KEY4, MISC_CONF, FIELD_RETURN, SRK_REVOKE),
  52869. + BANK(HDCP_KEY0, HDCP_KEY1, HDCP_KEY2, HDCP_KEY3, HDCP_KEY4, HDCP_KEY5, HDCP_KEY6, HDCP_KEY7),
  52870. + BANK(HDCP_KEY8, HDCP_KEY9, HDCP_KEY10, HDCP_KEY11, HDCP_KEY12, HDCP_KEY13, HDCP_KEY14, HDCP_KEY15),
  52871. + BANK(HDCP_KEY16, HDCP_KEY17, HDCP_KEY18, HDCP_KEY19, HDCP_KEY20, HDCP_KEY21, HDCP_KEY22, HDCP_KEY23),
  52872. + BANK(HDCP_KEY24, HDCP_KEY25, HDCP_KEY26, HDCP_KEY27, HDCP_KEY28, HDCP_KEY29, HDCP_KEY30, HDCP_KEY31),
  52873. + BANK(HDCP_KEY32, HDCP_KEY33, HDCP_KEY34, HDCP_KEY35, HDCP_KEY36, HDCP_KEY37, HDCP_KEY38, HDCP_KEY39),
  52874. + BANK(HDCP_KEY40, HDCP_KEY41, HDCP_KEY42, HDCP_KEY43, HDCP_KEY44, HDCP_KEY45, HDCP_KEY46, HDCP_KEY47),
  52875. + BANK(HDCP_KEY48, HDCP_KEY49, HDCP_KEY50, HDCP_KEY51, HDCP_KEY52, HDCP_KEY53, HDCP_KEY54, HDCP_KEY55),
  52876. + BANK(HDCP_KEY56, HDCP_KEY57, HDCP_KEY58, HDCP_KEY59, HDCP_KEY60, HDCP_KEY61, HDCP_KEY62, HDCP_KEY63),
  52877. + BANK(HDCP_KEY64, HDCP_KEY65, HDCP_KEY66, HDCP_KEY67, HDCP_KEY68, HDCP_KEY69, HDCP_KEY70, HDCP_KEY71),
  52878. + BANK(CRC0, CRC1, CRC2, CRC3, CRC4, CRC5, CRC6, CRC7),
  52879. +};
  52880. +
  52881. +static DEFINE_MUTEX(otp_mutex);
  52882. +static void __iomem *otp_base;
  52883. +static struct clk *otp_clk;
  52884. +struct kobject *otp_kobj;
  52885. +struct kobj_attribute *otp_kattr;
  52886. +struct attribute_group *otp_attr_group;
  52887. +
  52888. +static void set_otp_timing(void)
  52889. +{
  52890. + unsigned long clk_rate = 0;
  52891. + unsigned long strobe_read, relex, strobe_prog;
  52892. + u32 timing = 0;
  52893. +
  52894. + clk_rate = clk_get_rate(otp_clk);
  52895. +
  52896. + /* do optimization for too many zeros */
  52897. + relex = clk_rate / (1000000000 / DEF_RELAX) - 1;
  52898. + strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
  52899. + strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
  52900. +
  52901. + timing = BF(relex, OCOTP_TIMING_RELAX);
  52902. + timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
  52903. + timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
  52904. +
  52905. + __raw_writel(timing, otp_base + HW_OCOTP_TIMING);
  52906. +}
  52907. +
  52908. +static int otp_wait_busy(u32 flags)
  52909. +{
  52910. + int count;
  52911. + u32 c;
  52912. +
  52913. + for (count = 10000; count >= 0; count--) {
  52914. + c = __raw_readl(otp_base + HW_OCOTP_CTRL);
  52915. + if (!(c & (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR | flags)))
  52916. + break;
  52917. + cpu_relax();
  52918. + }
  52919. +
  52920. + if (count < 0)
  52921. + return -ETIMEDOUT;
  52922. +
  52923. + return 0;
  52924. +}
  52925. +
  52926. +static ssize_t fsl_otp_show(struct kobject *kobj, struct kobj_attribute *attr,
  52927. + char *buf)
  52928. +{
  52929. + unsigned int index = attr - otp_kattr;
  52930. + u32 value = 0;
  52931. + int ret;
  52932. +
  52933. + ret = clk_prepare_enable(otp_clk);
  52934. + if (ret)
  52935. + return 0;
  52936. +
  52937. + mutex_lock(&otp_mutex);
  52938. +
  52939. + set_otp_timing();
  52940. + ret = otp_wait_busy(0);
  52941. + if (ret)
  52942. + goto out;
  52943. +
  52944. + value = __raw_readl(otp_base + HW_OCOTP_CUST_N(index));
  52945. +
  52946. +out:
  52947. + mutex_unlock(&otp_mutex);
  52948. + clk_disable_unprepare(otp_clk);
  52949. + return ret ? 0 : sprintf(buf, "0x%x\n", value);
  52950. +}
  52951. +
  52952. +static int otp_write_bits(int addr, u32 data, u32 magic)
  52953. +{
  52954. + u32 c; /* for control register */
  52955. +
  52956. + /* init the control register */
  52957. + c = __raw_readl(otp_base + HW_OCOTP_CTRL);
  52958. + c &= ~BM_OCOTP_CTRL_ADDR;
  52959. + c |= BF(addr, OCOTP_CTRL_ADDR);
  52960. + c |= BF(magic, OCOTP_CTRL_WR_UNLOCK);
  52961. + __raw_writel(c, otp_base + HW_OCOTP_CTRL);
  52962. +
  52963. + /* init the data register */
  52964. + __raw_writel(data, otp_base + HW_OCOTP_DATA);
  52965. + otp_wait_busy(0);
  52966. +
  52967. + mdelay(2); /* Write Postamble */
  52968. +
  52969. + return 0;
  52970. +}
  52971. +
  52972. +static ssize_t fsl_otp_store(struct kobject *kobj, struct kobj_attribute *attr,
  52973. + const char *buf, size_t count)
  52974. +{
  52975. + unsigned int index = attr - otp_kattr;
  52976. + u32 value;
  52977. + int ret;
  52978. +
  52979. + sscanf(buf, "0x%x", &value);
  52980. +
  52981. + ret = clk_prepare_enable(otp_clk);
  52982. + if (ret)
  52983. + return 0;
  52984. +
  52985. + mutex_lock(&otp_mutex);
  52986. +
  52987. + set_otp_timing();
  52988. + ret = otp_wait_busy(0);
  52989. + if (ret)
  52990. + goto out;
  52991. +
  52992. + otp_write_bits(index, value, 0x3e77);
  52993. +
  52994. + /* Reload all the shadow registers */
  52995. + __raw_writel(BM_OCOTP_CTRL_RELOAD_SHADOWS,
  52996. + otp_base + HW_OCOTP_CTRL_SET);
  52997. + udelay(1);
  52998. + otp_wait_busy(BM_OCOTP_CTRL_RELOAD_SHADOWS);
  52999. +
  53000. +out:
  53001. + mutex_unlock(&otp_mutex);
  53002. + clk_disable_unprepare(otp_clk);
  53003. + return ret ? 0 : count;
  53004. +}
  53005. +
  53006. +static int fsl_otp_probe(struct platform_device *pdev)
  53007. +{
  53008. + struct resource *res;
  53009. + struct attribute **attrs;
  53010. + const char **desc;
  53011. + int i, num;
  53012. + int ret;
  53013. +
  53014. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  53015. + otp_base = devm_ioremap_resource(&pdev->dev, res);
  53016. + if (IS_ERR(otp_base)) {
  53017. + ret = PTR_ERR(otp_base);
  53018. + dev_err(&pdev->dev, "failed to ioremap resource: %d\n", ret);
  53019. + return ret;
  53020. + }
  53021. +
  53022. + otp_clk = devm_clk_get(&pdev->dev, NULL);
  53023. + if (IS_ERR(otp_clk)) {
  53024. + ret = PTR_ERR(otp_clk);
  53025. + dev_err(&pdev->dev, "failed to get clock: %d\n", ret);
  53026. + return ret;
  53027. + }
  53028. +
  53029. + desc = (const char **) imx6q_otp_desc;
  53030. + num = sizeof(imx6q_otp_desc) / sizeof(void *);
  53031. +
  53032. + /* The last one is NULL, which is used to detect the end */
  53033. + attrs = devm_kzalloc(&pdev->dev, (num + 1) * sizeof(*attrs),
  53034. + GFP_KERNEL);
  53035. + otp_kattr = devm_kzalloc(&pdev->dev, num * sizeof(*otp_kattr),
  53036. + GFP_KERNEL);
  53037. + otp_attr_group = devm_kzalloc(&pdev->dev, sizeof(*otp_attr_group),
  53038. + GFP_KERNEL);
  53039. + if (!attrs || !otp_kattr || !otp_attr_group)
  53040. + return -ENOMEM;
  53041. +
  53042. + for (i = 0; i < num; i++) {
  53043. + sysfs_attr_init(&otp_kattr[i].attr);
  53044. + otp_kattr[i].attr.name = desc[i];
  53045. + otp_kattr[i].attr.mode = 0600;
  53046. + otp_kattr[i].show = fsl_otp_show;
  53047. + otp_kattr[i].store = fsl_otp_store;
  53048. + attrs[i] = &otp_kattr[i].attr;
  53049. + }
  53050. + otp_attr_group->attrs = attrs;
  53051. +
  53052. + otp_kobj = kobject_create_and_add("fsl_otp", NULL);
  53053. + if (!otp_kobj) {
  53054. + dev_err(&pdev->dev, "failed to add kobject\n");
  53055. + return -ENOMEM;
  53056. + }
  53057. +
  53058. + ret = sysfs_create_group(otp_kobj, otp_attr_group);
  53059. + if (ret) {
  53060. + dev_err(&pdev->dev, "failed to create sysfs group: %d\n", ret);
  53061. + kobject_put(otp_kobj);
  53062. + return ret;
  53063. + }
  53064. +
  53065. + mutex_init(&otp_mutex);
  53066. +
  53067. + return 0;
  53068. +}
  53069. +
  53070. +static int fsl_otp_remove(struct platform_device *pdev)
  53071. +{
  53072. + sysfs_remove_group(otp_kobj, otp_attr_group);
  53073. + kobject_put(otp_kobj);
  53074. +
  53075. + return 0;
  53076. +}
  53077. +
  53078. +static const struct of_device_id fsl_otp_dt_ids[] = {
  53079. + { .compatible = "fsl,imx6q-ocotp", },
  53080. + { /* sentinel */ }
  53081. +};
  53082. +MODULE_DEVICE_TABLE(of, fsl_otp_dt_ids);
  53083. +
  53084. +static struct platform_driver fsl_otp_driver = {
  53085. + .driver = {
  53086. + .name = "imx-ocotp",
  53087. + .owner = THIS_MODULE,
  53088. + .of_match_table = fsl_otp_dt_ids,
  53089. + },
  53090. + .probe = fsl_otp_probe,
  53091. + .remove = fsl_otp_remove,
  53092. +};
  53093. +module_platform_driver(fsl_otp_driver);
  53094. +
  53095. +MODULE_LICENSE("GPL");
  53096. +MODULE_AUTHOR("Huang Shijie <b32955@freescale.com>");
  53097. +MODULE_DESCRIPTION("Freescale i.MX OCOTP driver");
  53098. diff -Nur linux-3.14.15/drivers/char/Kconfig linux-linaro-stable-mx6/drivers/char/Kconfig
  53099. --- linux-3.14.15/drivers/char/Kconfig 2014-07-31 23:51:43.000000000 +0200
  53100. +++ linux-linaro-stable-mx6/drivers/char/Kconfig 2014-08-20 19:31:42.416853073 +0200
  53101. @@ -82,6 +82,21 @@
  53102. If unsure, say N.
  53103. +config FSL_OTP
  53104. + tristate "Freescale On-Chip OTP Memory Support"
  53105. + depends on HAS_IOMEM && OF
  53106. + help
  53107. + If you say Y here, you will get support for a character device
  53108. + interface into the One Time Programmable memory pages that are
  53109. + stored on the some Freescale i.MX processors. This will not get
  53110. + you access to the secure memory pages however. You will need to
  53111. + write your own secure code and reader for that.
  53112. +
  53113. + To compile this driver as a module, choose M here: the module
  53114. + will be called fsl_otp.
  53115. +
  53116. + If unsure, it is safe to say Y.
  53117. +
  53118. config PRINTER
  53119. tristate "Parallel printer support"
  53120. depends on PARPORT
  53121. diff -Nur linux-3.14.15/drivers/char/Makefile linux-linaro-stable-mx6/drivers/char/Makefile
  53122. --- linux-3.14.15/drivers/char/Makefile 2014-07-31 23:51:43.000000000 +0200
  53123. +++ linux-linaro-stable-mx6/drivers/char/Makefile 2014-08-20 19:31:42.416853073 +0200
  53124. @@ -16,6 +16,7 @@
  53125. obj-$(CONFIG_IBM_BSR) += bsr.o
  53126. obj-$(CONFIG_SGI_MBCS) += mbcs.o
  53127. obj-$(CONFIG_BFIN_OTP) += bfin-otp.o
  53128. +obj-$(CONFIG_FSL_OTP) += fsl_otp.o
  53129. obj-$(CONFIG_PRINTER) += lp.o
  53130. diff -Nur linux-3.14.15/drivers/cpufreq/cpufreq_interactive.c linux-linaro-stable-mx6/drivers/cpufreq/cpufreq_interactive.c
  53131. --- linux-3.14.15/drivers/cpufreq/cpufreq_interactive.c 1970-01-01 01:00:00.000000000 +0100
  53132. +++ linux-linaro-stable-mx6/drivers/cpufreq/cpufreq_interactive.c 2014-08-20 19:31:42.688854238 +0200
  53133. @@ -0,0 +1,1349 @@
  53134. +/*
  53135. + * drivers/cpufreq/cpufreq_interactive.c
  53136. + *
  53137. + * Copyright (C) 2010 Google, Inc.
  53138. + *
  53139. + * This software is licensed under the terms of the GNU General Public
  53140. + * License version 2, as published by the Free Software Foundation, and
  53141. + * may be copied, distributed, and modified under those terms.
  53142. + *
  53143. + * This program is distributed in the hope that it will be useful,
  53144. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  53145. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  53146. + * GNU General Public License for more details.
  53147. + *
  53148. + * Author: Mike Chan (mike@android.com)
  53149. + *
  53150. + */
  53151. +
  53152. +#include <linux/cpu.h>
  53153. +#include <linux/cpumask.h>
  53154. +#include <linux/cpufreq.h>
  53155. +#include <linux/module.h>
  53156. +#include <linux/moduleparam.h>
  53157. +#include <linux/rwsem.h>
  53158. +#include <linux/sched.h>
  53159. +#include <linux/sched/rt.h>
  53160. +#include <linux/tick.h>
  53161. +#include <linux/time.h>
  53162. +#include <linux/timer.h>
  53163. +#include <linux/workqueue.h>
  53164. +#include <linux/kthread.h>
  53165. +#include <linux/slab.h>
  53166. +
  53167. +#define CREATE_TRACE_POINTS
  53168. +#include <trace/events/cpufreq_interactive.h>
  53169. +
  53170. +struct cpufreq_interactive_cpuinfo {
  53171. + struct timer_list cpu_timer;
  53172. + struct timer_list cpu_slack_timer;
  53173. + spinlock_t load_lock; /* protects the next 4 fields */
  53174. + u64 time_in_idle;
  53175. + u64 time_in_idle_timestamp;
  53176. + u64 cputime_speedadj;
  53177. + u64 cputime_speedadj_timestamp;
  53178. + struct cpufreq_policy *policy;
  53179. + struct cpufreq_frequency_table *freq_table;
  53180. + unsigned int target_freq;
  53181. + unsigned int floor_freq;
  53182. + u64 floor_validate_time;
  53183. + u64 hispeed_validate_time;
  53184. + struct rw_semaphore enable_sem;
  53185. + int governor_enabled;
  53186. +};
  53187. +
  53188. +static DEFINE_PER_CPU(struct cpufreq_interactive_cpuinfo, cpuinfo);
  53189. +
  53190. +/* realtime thread handles frequency scaling */
  53191. +static struct task_struct *speedchange_task;
  53192. +static cpumask_t speedchange_cpumask;
  53193. +static spinlock_t speedchange_cpumask_lock;
  53194. +static struct mutex gov_lock;
  53195. +
  53196. +/* Target load. Lower values result in higher CPU speeds. */
  53197. +#define DEFAULT_TARGET_LOAD 90
  53198. +static unsigned int default_target_loads[] = {DEFAULT_TARGET_LOAD};
  53199. +
  53200. +#define DEFAULT_TIMER_RATE (20 * USEC_PER_MSEC)
  53201. +#define DEFAULT_ABOVE_HISPEED_DELAY DEFAULT_TIMER_RATE
  53202. +static unsigned int default_above_hispeed_delay[] = {
  53203. + DEFAULT_ABOVE_HISPEED_DELAY };
  53204. +
  53205. +struct cpufreq_interactive_tunables {
  53206. + int usage_count;
  53207. + /* Hi speed to bump to from lo speed when load burst (default max) */
  53208. + unsigned int hispeed_freq;
  53209. + /* Go to hi speed when CPU load at or above this value. */
  53210. +#define DEFAULT_GO_HISPEED_LOAD 99
  53211. + unsigned long go_hispeed_load;
  53212. + /* Target load. Lower values result in higher CPU speeds. */
  53213. + spinlock_t target_loads_lock;
  53214. + unsigned int *target_loads;
  53215. + int ntarget_loads;
  53216. + /*
  53217. + * The minimum amount of time to spend at a frequency before we can ramp
  53218. + * down.
  53219. + */
  53220. +#define DEFAULT_MIN_SAMPLE_TIME (80 * USEC_PER_MSEC)
  53221. + unsigned long min_sample_time;
  53222. + /*
  53223. + * The sample rate of the timer used to increase frequency
  53224. + */
  53225. + unsigned long timer_rate;
  53226. + /*
  53227. + * Wait this long before raising speed above hispeed, by default a
  53228. + * single timer interval.
  53229. + */
  53230. + spinlock_t above_hispeed_delay_lock;
  53231. + unsigned int *above_hispeed_delay;
  53232. + int nabove_hispeed_delay;
  53233. + /* Non-zero means indefinite speed boost active */
  53234. + int boost_val;
  53235. + /* Duration of a boot pulse in usecs */
  53236. + int boostpulse_duration_val;
  53237. + /* End time of boost pulse in ktime converted to usecs */
  53238. + u64 boostpulse_endtime;
  53239. + /*
  53240. + * Max additional time to wait in idle, beyond timer_rate, at speeds
  53241. + * above minimum before wakeup to reduce speed, or -1 if unnecessary.
  53242. + */
  53243. +#define DEFAULT_TIMER_SLACK (4 * DEFAULT_TIMER_RATE)
  53244. + int timer_slack_val;
  53245. + bool io_is_busy;
  53246. +};
  53247. +
  53248. +/* For cases where we have single governor instance for system */
  53249. +struct cpufreq_interactive_tunables *common_tunables;
  53250. +
  53251. +static struct attribute_group *get_sysfs_attr(void);
  53252. +
  53253. +static void cpufreq_interactive_timer_resched(
  53254. + struct cpufreq_interactive_cpuinfo *pcpu)
  53255. +{
  53256. + struct cpufreq_interactive_tunables *tunables =
  53257. + pcpu->policy->governor_data;
  53258. + unsigned long expires;
  53259. + unsigned long flags;
  53260. +
  53261. + spin_lock_irqsave(&pcpu->load_lock, flags);
  53262. + pcpu->time_in_idle =
  53263. + get_cpu_idle_time(smp_processor_id(),
  53264. + &pcpu->time_in_idle_timestamp,
  53265. + tunables->io_is_busy);
  53266. + pcpu->cputime_speedadj = 0;
  53267. + pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp;
  53268. + expires = jiffies + usecs_to_jiffies(tunables->timer_rate);
  53269. + mod_timer_pinned(&pcpu->cpu_timer, expires);
  53270. +
  53271. + if (tunables->timer_slack_val >= 0 &&
  53272. + pcpu->target_freq > pcpu->policy->min) {
  53273. + expires += usecs_to_jiffies(tunables->timer_slack_val);
  53274. + mod_timer_pinned(&pcpu->cpu_slack_timer, expires);
  53275. + }
  53276. +
  53277. + spin_unlock_irqrestore(&pcpu->load_lock, flags);
  53278. +}
  53279. +
  53280. +/* The caller shall take enable_sem write semaphore to avoid any timer race.
  53281. + * The cpu_timer and cpu_slack_timer must be deactivated when calling this
  53282. + * function.
  53283. + */
  53284. +static void cpufreq_interactive_timer_start(
  53285. + struct cpufreq_interactive_tunables *tunables, int cpu)
  53286. +{
  53287. + struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu);
  53288. + unsigned long expires = jiffies +
  53289. + usecs_to_jiffies(tunables->timer_rate);
  53290. + unsigned long flags;
  53291. +
  53292. + pcpu->cpu_timer.expires = expires;
  53293. + add_timer_on(&pcpu->cpu_timer, cpu);
  53294. + if (tunables->timer_slack_val >= 0 &&
  53295. + pcpu->target_freq > pcpu->policy->min) {
  53296. + expires += usecs_to_jiffies(tunables->timer_slack_val);
  53297. + pcpu->cpu_slack_timer.expires = expires;
  53298. + add_timer_on(&pcpu->cpu_slack_timer, cpu);
  53299. + }
  53300. +
  53301. + spin_lock_irqsave(&pcpu->load_lock, flags);
  53302. + pcpu->time_in_idle =
  53303. + get_cpu_idle_time(cpu, &pcpu->time_in_idle_timestamp,
  53304. + tunables->io_is_busy);
  53305. + pcpu->cputime_speedadj = 0;
  53306. + pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp;
  53307. + spin_unlock_irqrestore(&pcpu->load_lock, flags);
  53308. +}
  53309. +
  53310. +static unsigned int freq_to_above_hispeed_delay(
  53311. + struct cpufreq_interactive_tunables *tunables,
  53312. + unsigned int freq)
  53313. +{
  53314. + int i;
  53315. + unsigned int ret;
  53316. + unsigned long flags;
  53317. +
  53318. + spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
  53319. +
  53320. + for (i = 0; i < tunables->nabove_hispeed_delay - 1 &&
  53321. + freq >= tunables->above_hispeed_delay[i+1]; i += 2)
  53322. + ;
  53323. +
  53324. + ret = tunables->above_hispeed_delay[i];
  53325. + spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
  53326. + return ret;
  53327. +}
  53328. +
  53329. +static unsigned int freq_to_targetload(
  53330. + struct cpufreq_interactive_tunables *tunables, unsigned int freq)
  53331. +{
  53332. + int i;
  53333. + unsigned int ret;
  53334. + unsigned long flags;
  53335. +
  53336. + spin_lock_irqsave(&tunables->target_loads_lock, flags);
  53337. +
  53338. + for (i = 0; i < tunables->ntarget_loads - 1 &&
  53339. + freq >= tunables->target_loads[i+1]; i += 2)
  53340. + ;
  53341. +
  53342. + ret = tunables->target_loads[i];
  53343. + spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
  53344. + return ret;
  53345. +}
  53346. +
  53347. +/*
  53348. + * If increasing frequencies never map to a lower target load then
  53349. + * choose_freq() will find the minimum frequency that does not exceed its
  53350. + * target load given the current load.
  53351. + */
  53352. +static unsigned int choose_freq(struct cpufreq_interactive_cpuinfo *pcpu,
  53353. + unsigned int loadadjfreq)
  53354. +{
  53355. + unsigned int freq = pcpu->policy->cur;
  53356. + unsigned int prevfreq, freqmin, freqmax;
  53357. + unsigned int tl;
  53358. + int index;
  53359. +
  53360. + freqmin = 0;
  53361. + freqmax = UINT_MAX;
  53362. +
  53363. + do {
  53364. + prevfreq = freq;
  53365. + tl = freq_to_targetload(pcpu->policy->governor_data, freq);
  53366. +
  53367. + /*
  53368. + * Find the lowest frequency where the computed load is less
  53369. + * than or equal to the target load.
  53370. + */
  53371. +
  53372. + if (cpufreq_frequency_table_target(
  53373. + pcpu->policy, pcpu->freq_table, loadadjfreq / tl,
  53374. + CPUFREQ_RELATION_L, &index))
  53375. + break;
  53376. + freq = pcpu->freq_table[index].frequency;
  53377. +
  53378. + if (freq > prevfreq) {
  53379. + /* The previous frequency is too low. */
  53380. + freqmin = prevfreq;
  53381. +
  53382. + if (freq >= freqmax) {
  53383. + /*
  53384. + * Find the highest frequency that is less
  53385. + * than freqmax.
  53386. + */
  53387. + if (cpufreq_frequency_table_target(
  53388. + pcpu->policy, pcpu->freq_table,
  53389. + freqmax - 1, CPUFREQ_RELATION_H,
  53390. + &index))
  53391. + break;
  53392. + freq = pcpu->freq_table[index].frequency;
  53393. +
  53394. + if (freq == freqmin) {
  53395. + /*
  53396. + * The first frequency below freqmax
  53397. + * has already been found to be too
  53398. + * low. freqmax is the lowest speed
  53399. + * we found that is fast enough.
  53400. + */
  53401. + freq = freqmax;
  53402. + break;
  53403. + }
  53404. + }
  53405. + } else if (freq < prevfreq) {
  53406. + /* The previous frequency is high enough. */
  53407. + freqmax = prevfreq;
  53408. +
  53409. + if (freq <= freqmin) {
  53410. + /*
  53411. + * Find the lowest frequency that is higher
  53412. + * than freqmin.
  53413. + */
  53414. + if (cpufreq_frequency_table_target(
  53415. + pcpu->policy, pcpu->freq_table,
  53416. + freqmin + 1, CPUFREQ_RELATION_L,
  53417. + &index))
  53418. + break;
  53419. + freq = pcpu->freq_table[index].frequency;
  53420. +
  53421. + /*
  53422. + * If freqmax is the first frequency above
  53423. + * freqmin then we have already found that
  53424. + * this speed is fast enough.
  53425. + */
  53426. + if (freq == freqmax)
  53427. + break;
  53428. + }
  53429. + }
  53430. +
  53431. + /* If same frequency chosen as previous then done. */
  53432. + } while (freq != prevfreq);
  53433. +
  53434. + return freq;
  53435. +}
  53436. +
  53437. +static u64 update_load(int cpu)
  53438. +{
  53439. + struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu);
  53440. + struct cpufreq_interactive_tunables *tunables =
  53441. + pcpu->policy->governor_data;
  53442. + u64 now;
  53443. + u64 now_idle;
  53444. + unsigned int delta_idle;
  53445. + unsigned int delta_time;
  53446. + u64 active_time;
  53447. +
  53448. + now_idle = get_cpu_idle_time(cpu, &now, tunables->io_is_busy);
  53449. + delta_idle = (unsigned int)(now_idle - pcpu->time_in_idle);
  53450. + delta_time = (unsigned int)(now - pcpu->time_in_idle_timestamp);
  53451. +
  53452. + if (delta_time <= delta_idle)
  53453. + active_time = 0;
  53454. + else
  53455. + active_time = delta_time - delta_idle;
  53456. +
  53457. + pcpu->cputime_speedadj += active_time * pcpu->policy->cur;
  53458. +
  53459. + pcpu->time_in_idle = now_idle;
  53460. + pcpu->time_in_idle_timestamp = now;
  53461. + return now;
  53462. +}
  53463. +
  53464. +static void cpufreq_interactive_timer(unsigned long data)
  53465. +{
  53466. + u64 now;
  53467. + unsigned int delta_time;
  53468. + u64 cputime_speedadj;
  53469. + int cpu_load;
  53470. + struct cpufreq_interactive_cpuinfo *pcpu =
  53471. + &per_cpu(cpuinfo, data);
  53472. + struct cpufreq_interactive_tunables *tunables =
  53473. + pcpu->policy->governor_data;
  53474. + unsigned int new_freq;
  53475. + unsigned int loadadjfreq;
  53476. + unsigned int index;
  53477. + unsigned long flags;
  53478. + bool boosted;
  53479. +
  53480. + if (!down_read_trylock(&pcpu->enable_sem))
  53481. + return;
  53482. + if (!pcpu->governor_enabled)
  53483. + goto exit;
  53484. +
  53485. + spin_lock_irqsave(&pcpu->load_lock, flags);
  53486. + now = update_load(data);
  53487. + delta_time = (unsigned int)(now - pcpu->cputime_speedadj_timestamp);
  53488. + cputime_speedadj = pcpu->cputime_speedadj;
  53489. + spin_unlock_irqrestore(&pcpu->load_lock, flags);
  53490. +
  53491. + if (WARN_ON_ONCE(!delta_time))
  53492. + goto rearm;
  53493. +
  53494. + do_div(cputime_speedadj, delta_time);
  53495. + loadadjfreq = (unsigned int)cputime_speedadj * 100;
  53496. + cpu_load = loadadjfreq / pcpu->target_freq;
  53497. + boosted = tunables->boost_val || now < tunables->boostpulse_endtime;
  53498. +
  53499. + if (cpu_load >= tunables->go_hispeed_load || boosted) {
  53500. + if (pcpu->target_freq < tunables->hispeed_freq) {
  53501. + new_freq = tunables->hispeed_freq;
  53502. + } else {
  53503. + new_freq = choose_freq(pcpu, loadadjfreq);
  53504. +
  53505. + if (new_freq < tunables->hispeed_freq)
  53506. + new_freq = tunables->hispeed_freq;
  53507. + }
  53508. + } else {
  53509. + new_freq = choose_freq(pcpu, loadadjfreq);
  53510. + }
  53511. +
  53512. + if (pcpu->target_freq >= tunables->hispeed_freq &&
  53513. + new_freq > pcpu->target_freq &&
  53514. + now - pcpu->hispeed_validate_time <
  53515. + freq_to_above_hispeed_delay(tunables, pcpu->target_freq)) {
  53516. + trace_cpufreq_interactive_notyet(
  53517. + data, cpu_load, pcpu->target_freq,
  53518. + pcpu->policy->cur, new_freq);
  53519. + goto rearm;
  53520. + }
  53521. +
  53522. + pcpu->hispeed_validate_time = now;
  53523. +
  53524. + if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table,
  53525. + new_freq, CPUFREQ_RELATION_L,
  53526. + &index))
  53527. + goto rearm;
  53528. +
  53529. + new_freq = pcpu->freq_table[index].frequency;
  53530. +
  53531. + /*
  53532. + * Do not scale below floor_freq unless we have been at or above the
  53533. + * floor frequency for the minimum sample time since last validated.
  53534. + */
  53535. + if (new_freq < pcpu->floor_freq) {
  53536. + if (now - pcpu->floor_validate_time <
  53537. + tunables->min_sample_time) {
  53538. + trace_cpufreq_interactive_notyet(
  53539. + data, cpu_load, pcpu->target_freq,
  53540. + pcpu->policy->cur, new_freq);
  53541. + goto rearm;
  53542. + }
  53543. + }
  53544. +
  53545. + /*
  53546. + * Update the timestamp for checking whether speed has been held at
  53547. + * or above the selected frequency for a minimum of min_sample_time,
  53548. + * if not boosted to hispeed_freq. If boosted to hispeed_freq then we
  53549. + * allow the speed to drop as soon as the boostpulse duration expires
  53550. + * (or the indefinite boost is turned off).
  53551. + */
  53552. +
  53553. + if (!boosted || new_freq > tunables->hispeed_freq) {
  53554. + pcpu->floor_freq = new_freq;
  53555. + pcpu->floor_validate_time = now;
  53556. + }
  53557. +
  53558. + if (pcpu->target_freq == new_freq) {
  53559. + trace_cpufreq_interactive_already(
  53560. + data, cpu_load, pcpu->target_freq,
  53561. + pcpu->policy->cur, new_freq);
  53562. + goto rearm_if_notmax;
  53563. + }
  53564. +
  53565. + trace_cpufreq_interactive_target(data, cpu_load, pcpu->target_freq,
  53566. + pcpu->policy->cur, new_freq);
  53567. +
  53568. + pcpu->target_freq = new_freq;
  53569. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  53570. + cpumask_set_cpu(data, &speedchange_cpumask);
  53571. + spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
  53572. + wake_up_process(speedchange_task);
  53573. +
  53574. +rearm_if_notmax:
  53575. + /*
  53576. + * Already set max speed and don't see a need to change that,
  53577. + * wait until next idle to re-evaluate, don't need timer.
  53578. + */
  53579. + if (pcpu->target_freq == pcpu->policy->max)
  53580. + goto exit;
  53581. +
  53582. +rearm:
  53583. + if (!timer_pending(&pcpu->cpu_timer))
  53584. + cpufreq_interactive_timer_resched(pcpu);
  53585. +
  53586. +exit:
  53587. + up_read(&pcpu->enable_sem);
  53588. + return;
  53589. +}
  53590. +
  53591. +static void cpufreq_interactive_idle_start(void)
  53592. +{
  53593. + struct cpufreq_interactive_cpuinfo *pcpu =
  53594. + &per_cpu(cpuinfo, smp_processor_id());
  53595. + int pending;
  53596. +
  53597. + if (!down_read_trylock(&pcpu->enable_sem))
  53598. + return;
  53599. + if (!pcpu->governor_enabled) {
  53600. + up_read(&pcpu->enable_sem);
  53601. + return;
  53602. + }
  53603. +
  53604. + pending = timer_pending(&pcpu->cpu_timer);
  53605. +
  53606. + if (pcpu->target_freq != pcpu->policy->min) {
  53607. + /*
  53608. + * Entering idle while not at lowest speed. On some
  53609. + * platforms this can hold the other CPU(s) at that speed
  53610. + * even though the CPU is idle. Set a timer to re-evaluate
  53611. + * speed so this idle CPU doesn't hold the other CPUs above
  53612. + * min indefinitely. This should probably be a quirk of
  53613. + * the CPUFreq driver.
  53614. + */
  53615. + if (!pending)
  53616. + cpufreq_interactive_timer_resched(pcpu);
  53617. + }
  53618. +
  53619. + up_read(&pcpu->enable_sem);
  53620. +}
  53621. +
  53622. +static void cpufreq_interactive_idle_end(void)
  53623. +{
  53624. + struct cpufreq_interactive_cpuinfo *pcpu =
  53625. + &per_cpu(cpuinfo, smp_processor_id());
  53626. +
  53627. + if (!down_read_trylock(&pcpu->enable_sem))
  53628. + return;
  53629. + if (!pcpu->governor_enabled) {
  53630. + up_read(&pcpu->enable_sem);
  53631. + return;
  53632. + }
  53633. +
  53634. + /* Arm the timer for 1-2 ticks later if not already. */
  53635. + if (!timer_pending(&pcpu->cpu_timer)) {
  53636. + cpufreq_interactive_timer_resched(pcpu);
  53637. + } else if (time_after_eq(jiffies, pcpu->cpu_timer.expires)) {
  53638. + del_timer(&pcpu->cpu_timer);
  53639. + del_timer(&pcpu->cpu_slack_timer);
  53640. + cpufreq_interactive_timer(smp_processor_id());
  53641. + }
  53642. +
  53643. + up_read(&pcpu->enable_sem);
  53644. +}
  53645. +
  53646. +static int cpufreq_interactive_speedchange_task(void *data)
  53647. +{
  53648. + unsigned int cpu;
  53649. + cpumask_t tmp_mask;
  53650. + unsigned long flags;
  53651. + struct cpufreq_interactive_cpuinfo *pcpu;
  53652. +
  53653. + while (1) {
  53654. + set_current_state(TASK_INTERRUPTIBLE);
  53655. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  53656. +
  53657. + if (cpumask_empty(&speedchange_cpumask)) {
  53658. + spin_unlock_irqrestore(&speedchange_cpumask_lock,
  53659. + flags);
  53660. + schedule();
  53661. +
  53662. + if (kthread_should_stop())
  53663. + break;
  53664. +
  53665. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  53666. + }
  53667. +
  53668. + set_current_state(TASK_RUNNING);
  53669. + tmp_mask = speedchange_cpumask;
  53670. + cpumask_clear(&speedchange_cpumask);
  53671. + spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
  53672. +
  53673. + for_each_cpu(cpu, &tmp_mask) {
  53674. + unsigned int j;
  53675. + unsigned int max_freq = 0;
  53676. +
  53677. + pcpu = &per_cpu(cpuinfo, cpu);
  53678. + if (!down_read_trylock(&pcpu->enable_sem))
  53679. + continue;
  53680. + if (!pcpu->governor_enabled) {
  53681. + up_read(&pcpu->enable_sem);
  53682. + continue;
  53683. + }
  53684. +
  53685. + for_each_cpu(j, pcpu->policy->cpus) {
  53686. + struct cpufreq_interactive_cpuinfo *pjcpu =
  53687. + &per_cpu(cpuinfo, j);
  53688. +
  53689. + if (pjcpu->target_freq > max_freq)
  53690. + max_freq = pjcpu->target_freq;
  53691. + }
  53692. +
  53693. + if (max_freq != pcpu->policy->cur)
  53694. + __cpufreq_driver_target(pcpu->policy,
  53695. + max_freq,
  53696. + CPUFREQ_RELATION_H);
  53697. + trace_cpufreq_interactive_setspeed(cpu,
  53698. + pcpu->target_freq,
  53699. + pcpu->policy->cur);
  53700. +
  53701. + up_read(&pcpu->enable_sem);
  53702. + }
  53703. + }
  53704. +
  53705. + return 0;
  53706. +}
  53707. +
  53708. +static void cpufreq_interactive_boost(void)
  53709. +{
  53710. + int i;
  53711. + int anyboost = 0;
  53712. + unsigned long flags;
  53713. + struct cpufreq_interactive_cpuinfo *pcpu;
  53714. + struct cpufreq_interactive_tunables *tunables;
  53715. +
  53716. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  53717. +
  53718. + for_each_online_cpu(i) {
  53719. + pcpu = &per_cpu(cpuinfo, i);
  53720. + tunables = pcpu->policy->governor_data;
  53721. +
  53722. + if (pcpu->target_freq < tunables->hispeed_freq) {
  53723. + pcpu->target_freq = tunables->hispeed_freq;
  53724. + cpumask_set_cpu(i, &speedchange_cpumask);
  53725. + pcpu->hispeed_validate_time =
  53726. + ktime_to_us(ktime_get());
  53727. + anyboost = 1;
  53728. + }
  53729. +
  53730. + /*
  53731. + * Set floor freq and (re)start timer for when last
  53732. + * validated.
  53733. + */
  53734. +
  53735. + pcpu->floor_freq = tunables->hispeed_freq;
  53736. + pcpu->floor_validate_time = ktime_to_us(ktime_get());
  53737. + }
  53738. +
  53739. + spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
  53740. +
  53741. + if (anyboost)
  53742. + wake_up_process(speedchange_task);
  53743. +}
  53744. +
  53745. +static int cpufreq_interactive_notifier(
  53746. + struct notifier_block *nb, unsigned long val, void *data)
  53747. +{
  53748. + struct cpufreq_freqs *freq = data;
  53749. + struct cpufreq_interactive_cpuinfo *pcpu;
  53750. + int cpu;
  53751. + unsigned long flags;
  53752. +
  53753. + if (val == CPUFREQ_POSTCHANGE) {
  53754. + pcpu = &per_cpu(cpuinfo, freq->cpu);
  53755. + if (!down_read_trylock(&pcpu->enable_sem))
  53756. + return 0;
  53757. + if (!pcpu->governor_enabled) {
  53758. + up_read(&pcpu->enable_sem);
  53759. + return 0;
  53760. + }
  53761. +
  53762. + for_each_cpu(cpu, pcpu->policy->cpus) {
  53763. + struct cpufreq_interactive_cpuinfo *pjcpu =
  53764. + &per_cpu(cpuinfo, cpu);
  53765. + if (cpu != freq->cpu) {
  53766. + if (!down_read_trylock(&pjcpu->enable_sem))
  53767. + continue;
  53768. + if (!pjcpu->governor_enabled) {
  53769. + up_read(&pjcpu->enable_sem);
  53770. + continue;
  53771. + }
  53772. + }
  53773. + spin_lock_irqsave(&pjcpu->load_lock, flags);
  53774. + update_load(cpu);
  53775. + spin_unlock_irqrestore(&pjcpu->load_lock, flags);
  53776. + if (cpu != freq->cpu)
  53777. + up_read(&pjcpu->enable_sem);
  53778. + }
  53779. +
  53780. + up_read(&pcpu->enable_sem);
  53781. + }
  53782. + return 0;
  53783. +}
  53784. +
  53785. +static struct notifier_block cpufreq_notifier_block = {
  53786. + .notifier_call = cpufreq_interactive_notifier,
  53787. +};
  53788. +
  53789. +static unsigned int *get_tokenized_data(const char *buf, int *num_tokens)
  53790. +{
  53791. + const char *cp;
  53792. + int i;
  53793. + int ntokens = 1;
  53794. + unsigned int *tokenized_data;
  53795. + int err = -EINVAL;
  53796. +
  53797. + cp = buf;
  53798. + while ((cp = strpbrk(cp + 1, " :")))
  53799. + ntokens++;
  53800. +
  53801. + if (!(ntokens & 0x1))
  53802. + goto err;
  53803. +
  53804. + tokenized_data = kmalloc(ntokens * sizeof(unsigned int), GFP_KERNEL);
  53805. + if (!tokenized_data) {
  53806. + err = -ENOMEM;
  53807. + goto err;
  53808. + }
  53809. +
  53810. + cp = buf;
  53811. + i = 0;
  53812. + while (i < ntokens) {
  53813. + if (sscanf(cp, "%u", &tokenized_data[i++]) != 1)
  53814. + goto err_kfree;
  53815. +
  53816. + cp = strpbrk(cp, " :");
  53817. + if (!cp)
  53818. + break;
  53819. + cp++;
  53820. + }
  53821. +
  53822. + if (i != ntokens)
  53823. + goto err_kfree;
  53824. +
  53825. + *num_tokens = ntokens;
  53826. + return tokenized_data;
  53827. +
  53828. +err_kfree:
  53829. + kfree(tokenized_data);
  53830. +err:
  53831. + return ERR_PTR(err);
  53832. +}
  53833. +
  53834. +static ssize_t show_target_loads(
  53835. + struct cpufreq_interactive_tunables *tunables,
  53836. + char *buf)
  53837. +{
  53838. + int i;
  53839. + ssize_t ret = 0;
  53840. + unsigned long flags;
  53841. +
  53842. + spin_lock_irqsave(&tunables->target_loads_lock, flags);
  53843. +
  53844. + for (i = 0; i < tunables->ntarget_loads; i++)
  53845. + ret += sprintf(buf + ret, "%u%s", tunables->target_loads[i],
  53846. + i & 0x1 ? ":" : " ");
  53847. +
  53848. + sprintf(buf + ret - 1, "\n");
  53849. + spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
  53850. + return ret;
  53851. +}
  53852. +
  53853. +static ssize_t store_target_loads(
  53854. + struct cpufreq_interactive_tunables *tunables,
  53855. + const char *buf, size_t count)
  53856. +{
  53857. + int ntokens;
  53858. + unsigned int *new_target_loads = NULL;
  53859. + unsigned long flags;
  53860. +
  53861. + new_target_loads = get_tokenized_data(buf, &ntokens);
  53862. + if (IS_ERR(new_target_loads))
  53863. + return PTR_RET(new_target_loads);
  53864. +
  53865. + spin_lock_irqsave(&tunables->target_loads_lock, flags);
  53866. + if (tunables->target_loads != default_target_loads)
  53867. + kfree(tunables->target_loads);
  53868. + tunables->target_loads = new_target_loads;
  53869. + tunables->ntarget_loads = ntokens;
  53870. + spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
  53871. + return count;
  53872. +}
  53873. +
  53874. +static ssize_t show_above_hispeed_delay(
  53875. + struct cpufreq_interactive_tunables *tunables, char *buf)
  53876. +{
  53877. + int i;
  53878. + ssize_t ret = 0;
  53879. + unsigned long flags;
  53880. +
  53881. + spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
  53882. +
  53883. + for (i = 0; i < tunables->nabove_hispeed_delay; i++)
  53884. + ret += sprintf(buf + ret, "%u%s",
  53885. + tunables->above_hispeed_delay[i],
  53886. + i & 0x1 ? ":" : " ");
  53887. +
  53888. + sprintf(buf + ret - 1, "\n");
  53889. + spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
  53890. + return ret;
  53891. +}
  53892. +
  53893. +static ssize_t store_above_hispeed_delay(
  53894. + struct cpufreq_interactive_tunables *tunables,
  53895. + const char *buf, size_t count)
  53896. +{
  53897. + int ntokens;
  53898. + unsigned int *new_above_hispeed_delay = NULL;
  53899. + unsigned long flags;
  53900. +
  53901. + new_above_hispeed_delay = get_tokenized_data(buf, &ntokens);
  53902. + if (IS_ERR(new_above_hispeed_delay))
  53903. + return PTR_RET(new_above_hispeed_delay);
  53904. +
  53905. + spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
  53906. + if (tunables->above_hispeed_delay != default_above_hispeed_delay)
  53907. + kfree(tunables->above_hispeed_delay);
  53908. + tunables->above_hispeed_delay = new_above_hispeed_delay;
  53909. + tunables->nabove_hispeed_delay = ntokens;
  53910. + spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
  53911. + return count;
  53912. +
  53913. +}
  53914. +
  53915. +static ssize_t show_hispeed_freq(struct cpufreq_interactive_tunables *tunables,
  53916. + char *buf)
  53917. +{
  53918. + return sprintf(buf, "%u\n", tunables->hispeed_freq);
  53919. +}
  53920. +
  53921. +static ssize_t store_hispeed_freq(struct cpufreq_interactive_tunables *tunables,
  53922. + const char *buf, size_t count)
  53923. +{
  53924. + int ret;
  53925. + long unsigned int val;
  53926. +
  53927. + ret = strict_strtoul(buf, 0, &val);
  53928. + if (ret < 0)
  53929. + return ret;
  53930. + tunables->hispeed_freq = val;
  53931. + return count;
  53932. +}
  53933. +
  53934. +static ssize_t show_go_hispeed_load(struct cpufreq_interactive_tunables
  53935. + *tunables, char *buf)
  53936. +{
  53937. + return sprintf(buf, "%lu\n", tunables->go_hispeed_load);
  53938. +}
  53939. +
  53940. +static ssize_t store_go_hispeed_load(struct cpufreq_interactive_tunables
  53941. + *tunables, const char *buf, size_t count)
  53942. +{
  53943. + int ret;
  53944. + unsigned long val;
  53945. +
  53946. + ret = strict_strtoul(buf, 0, &val);
  53947. + if (ret < 0)
  53948. + return ret;
  53949. + tunables->go_hispeed_load = val;
  53950. + return count;
  53951. +}
  53952. +
  53953. +static ssize_t show_min_sample_time(struct cpufreq_interactive_tunables
  53954. + *tunables, char *buf)
  53955. +{
  53956. + return sprintf(buf, "%lu\n", tunables->min_sample_time);
  53957. +}
  53958. +
  53959. +static ssize_t store_min_sample_time(struct cpufreq_interactive_tunables
  53960. + *tunables, const char *buf, size_t count)
  53961. +{
  53962. + int ret;
  53963. + unsigned long val;
  53964. +
  53965. + ret = strict_strtoul(buf, 0, &val);
  53966. + if (ret < 0)
  53967. + return ret;
  53968. + tunables->min_sample_time = val;
  53969. + return count;
  53970. +}
  53971. +
  53972. +static ssize_t show_timer_rate(struct cpufreq_interactive_tunables *tunables,
  53973. + char *buf)
  53974. +{
  53975. + return sprintf(buf, "%lu\n", tunables->timer_rate);
  53976. +}
  53977. +
  53978. +static ssize_t store_timer_rate(struct cpufreq_interactive_tunables *tunables,
  53979. + const char *buf, size_t count)
  53980. +{
  53981. + int ret;
  53982. + unsigned long val;
  53983. +
  53984. + ret = strict_strtoul(buf, 0, &val);
  53985. + if (ret < 0)
  53986. + return ret;
  53987. + tunables->timer_rate = val;
  53988. + return count;
  53989. +}
  53990. +
  53991. +static ssize_t show_timer_slack(struct cpufreq_interactive_tunables *tunables,
  53992. + char *buf)
  53993. +{
  53994. + return sprintf(buf, "%d\n", tunables->timer_slack_val);
  53995. +}
  53996. +
  53997. +static ssize_t store_timer_slack(struct cpufreq_interactive_tunables *tunables,
  53998. + const char *buf, size_t count)
  53999. +{
  54000. + int ret;
  54001. + unsigned long val;
  54002. +
  54003. + ret = kstrtol(buf, 10, &val);
  54004. + if (ret < 0)
  54005. + return ret;
  54006. +
  54007. + tunables->timer_slack_val = val;
  54008. + return count;
  54009. +}
  54010. +
  54011. +static ssize_t show_boost(struct cpufreq_interactive_tunables *tunables,
  54012. + char *buf)
  54013. +{
  54014. + return sprintf(buf, "%d\n", tunables->boost_val);
  54015. +}
  54016. +
  54017. +static ssize_t store_boost(struct cpufreq_interactive_tunables *tunables,
  54018. + const char *buf, size_t count)
  54019. +{
  54020. + int ret;
  54021. + unsigned long val;
  54022. +
  54023. + ret = kstrtoul(buf, 0, &val);
  54024. + if (ret < 0)
  54025. + return ret;
  54026. +
  54027. + tunables->boost_val = val;
  54028. +
  54029. + if (tunables->boost_val) {
  54030. + trace_cpufreq_interactive_boost("on");
  54031. + cpufreq_interactive_boost();
  54032. + } else {
  54033. + trace_cpufreq_interactive_unboost("off");
  54034. + }
  54035. +
  54036. + return count;
  54037. +}
  54038. +
  54039. +static ssize_t store_boostpulse(struct cpufreq_interactive_tunables *tunables,
  54040. + const char *buf, size_t count)
  54041. +{
  54042. + int ret;
  54043. + unsigned long val;
  54044. +
  54045. + ret = kstrtoul(buf, 0, &val);
  54046. + if (ret < 0)
  54047. + return ret;
  54048. +
  54049. + tunables->boostpulse_endtime = ktime_to_us(ktime_get()) +
  54050. + tunables->boostpulse_duration_val;
  54051. + trace_cpufreq_interactive_boost("pulse");
  54052. + cpufreq_interactive_boost();
  54053. + return count;
  54054. +}
  54055. +
  54056. +static ssize_t show_boostpulse_duration(struct cpufreq_interactive_tunables
  54057. + *tunables, char *buf)
  54058. +{
  54059. + return sprintf(buf, "%d\n", tunables->boostpulse_duration_val);
  54060. +}
  54061. +
  54062. +static ssize_t store_boostpulse_duration(struct cpufreq_interactive_tunables
  54063. + *tunables, const char *buf, size_t count)
  54064. +{
  54065. + int ret;
  54066. + unsigned long val;
  54067. +
  54068. + ret = kstrtoul(buf, 0, &val);
  54069. + if (ret < 0)
  54070. + return ret;
  54071. +
  54072. + tunables->boostpulse_duration_val = val;
  54073. + return count;
  54074. +}
  54075. +
  54076. +static ssize_t show_io_is_busy(struct cpufreq_interactive_tunables *tunables,
  54077. + char *buf)
  54078. +{
  54079. + return sprintf(buf, "%u\n", tunables->io_is_busy);
  54080. +}
  54081. +
  54082. +static ssize_t store_io_is_busy(struct cpufreq_interactive_tunables *tunables,
  54083. + const char *buf, size_t count)
  54084. +{
  54085. + int ret;
  54086. + unsigned long val;
  54087. +
  54088. + ret = kstrtoul(buf, 0, &val);
  54089. + if (ret < 0)
  54090. + return ret;
  54091. + tunables->io_is_busy = val;
  54092. + return count;
  54093. +}
  54094. +
  54095. +/*
  54096. + * Create show/store routines
  54097. + * - sys: One governor instance for complete SYSTEM
  54098. + * - pol: One governor instance per struct cpufreq_policy
  54099. + */
  54100. +#define show_gov_pol_sys(file_name) \
  54101. +static ssize_t show_##file_name##_gov_sys \
  54102. +(struct kobject *kobj, struct attribute *attr, char *buf) \
  54103. +{ \
  54104. + return show_##file_name(common_tunables, buf); \
  54105. +} \
  54106. + \
  54107. +static ssize_t show_##file_name##_gov_pol \
  54108. +(struct cpufreq_policy *policy, char *buf) \
  54109. +{ \
  54110. + return show_##file_name(policy->governor_data, buf); \
  54111. +}
  54112. +
  54113. +#define store_gov_pol_sys(file_name) \
  54114. +static ssize_t store_##file_name##_gov_sys \
  54115. +(struct kobject *kobj, struct attribute *attr, const char *buf, \
  54116. + size_t count) \
  54117. +{ \
  54118. + return store_##file_name(common_tunables, buf, count); \
  54119. +} \
  54120. + \
  54121. +static ssize_t store_##file_name##_gov_pol \
  54122. +(struct cpufreq_policy *policy, const char *buf, size_t count) \
  54123. +{ \
  54124. + return store_##file_name(policy->governor_data, buf, count); \
  54125. +}
  54126. +
  54127. +#define show_store_gov_pol_sys(file_name) \
  54128. +show_gov_pol_sys(file_name); \
  54129. +store_gov_pol_sys(file_name)
  54130. +
  54131. +show_store_gov_pol_sys(target_loads);
  54132. +show_store_gov_pol_sys(above_hispeed_delay);
  54133. +show_store_gov_pol_sys(hispeed_freq);
  54134. +show_store_gov_pol_sys(go_hispeed_load);
  54135. +show_store_gov_pol_sys(min_sample_time);
  54136. +show_store_gov_pol_sys(timer_rate);
  54137. +show_store_gov_pol_sys(timer_slack);
  54138. +show_store_gov_pol_sys(boost);
  54139. +store_gov_pol_sys(boostpulse);
  54140. +show_store_gov_pol_sys(boostpulse_duration);
  54141. +show_store_gov_pol_sys(io_is_busy);
  54142. +
  54143. +#define gov_sys_attr_rw(_name) \
  54144. +static struct global_attr _name##_gov_sys = \
  54145. +__ATTR(_name, 0644, show_##_name##_gov_sys, store_##_name##_gov_sys)
  54146. +
  54147. +#define gov_pol_attr_rw(_name) \
  54148. +static struct freq_attr _name##_gov_pol = \
  54149. +__ATTR(_name, 0644, show_##_name##_gov_pol, store_##_name##_gov_pol)
  54150. +
  54151. +#define gov_sys_pol_attr_rw(_name) \
  54152. + gov_sys_attr_rw(_name); \
  54153. + gov_pol_attr_rw(_name)
  54154. +
  54155. +gov_sys_pol_attr_rw(target_loads);
  54156. +gov_sys_pol_attr_rw(above_hispeed_delay);
  54157. +gov_sys_pol_attr_rw(hispeed_freq);
  54158. +gov_sys_pol_attr_rw(go_hispeed_load);
  54159. +gov_sys_pol_attr_rw(min_sample_time);
  54160. +gov_sys_pol_attr_rw(timer_rate);
  54161. +gov_sys_pol_attr_rw(timer_slack);
  54162. +gov_sys_pol_attr_rw(boost);
  54163. +gov_sys_pol_attr_rw(boostpulse_duration);
  54164. +gov_sys_pol_attr_rw(io_is_busy);
  54165. +
  54166. +static struct global_attr boostpulse_gov_sys =
  54167. + __ATTR(boostpulse, 0200, NULL, store_boostpulse_gov_sys);
  54168. +
  54169. +static struct freq_attr boostpulse_gov_pol =
  54170. + __ATTR(boostpulse, 0200, NULL, store_boostpulse_gov_pol);
  54171. +
  54172. +/* One Governor instance for entire system */
  54173. +static struct attribute *interactive_attributes_gov_sys[] = {
  54174. + &target_loads_gov_sys.attr,
  54175. + &above_hispeed_delay_gov_sys.attr,
  54176. + &hispeed_freq_gov_sys.attr,
  54177. + &go_hispeed_load_gov_sys.attr,
  54178. + &min_sample_time_gov_sys.attr,
  54179. + &timer_rate_gov_sys.attr,
  54180. + &timer_slack_gov_sys.attr,
  54181. + &boost_gov_sys.attr,
  54182. + &boostpulse_gov_sys.attr,
  54183. + &boostpulse_duration_gov_sys.attr,
  54184. + &io_is_busy_gov_sys.attr,
  54185. + NULL,
  54186. +};
  54187. +
  54188. +static struct attribute_group interactive_attr_group_gov_sys = {
  54189. + .attrs = interactive_attributes_gov_sys,
  54190. + .name = "interactive",
  54191. +};
  54192. +
  54193. +/* Per policy governor instance */
  54194. +static struct attribute *interactive_attributes_gov_pol[] = {
  54195. + &target_loads_gov_pol.attr,
  54196. + &above_hispeed_delay_gov_pol.attr,
  54197. + &hispeed_freq_gov_pol.attr,
  54198. + &go_hispeed_load_gov_pol.attr,
  54199. + &min_sample_time_gov_pol.attr,
  54200. + &timer_rate_gov_pol.attr,
  54201. + &timer_slack_gov_pol.attr,
  54202. + &boost_gov_pol.attr,
  54203. + &boostpulse_gov_pol.attr,
  54204. + &boostpulse_duration_gov_pol.attr,
  54205. + &io_is_busy_gov_pol.attr,
  54206. + NULL,
  54207. +};
  54208. +
  54209. +static struct attribute_group interactive_attr_group_gov_pol = {
  54210. + .attrs = interactive_attributes_gov_pol,
  54211. + .name = "interactive",
  54212. +};
  54213. +
  54214. +static struct attribute_group *get_sysfs_attr(void)
  54215. +{
  54216. + if (have_governor_per_policy())
  54217. + return &interactive_attr_group_gov_pol;
  54218. + else
  54219. + return &interactive_attr_group_gov_sys;
  54220. +}
  54221. +
  54222. +static int cpufreq_interactive_idle_notifier(struct notifier_block *nb,
  54223. + unsigned long val,
  54224. + void *data)
  54225. +{
  54226. + switch (val) {
  54227. + case IDLE_START:
  54228. + cpufreq_interactive_idle_start();
  54229. + break;
  54230. + case IDLE_END:
  54231. + cpufreq_interactive_idle_end();
  54232. + break;
  54233. + }
  54234. +
  54235. + return 0;
  54236. +}
  54237. +
  54238. +static struct notifier_block cpufreq_interactive_idle_nb = {
  54239. + .notifier_call = cpufreq_interactive_idle_notifier,
  54240. +};
  54241. +
  54242. +static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
  54243. + unsigned int event)
  54244. +{
  54245. + int rc;
  54246. + unsigned int j;
  54247. + struct cpufreq_interactive_cpuinfo *pcpu;
  54248. + struct cpufreq_frequency_table *freq_table;
  54249. + struct cpufreq_interactive_tunables *tunables;
  54250. +
  54251. + if (have_governor_per_policy())
  54252. + tunables = policy->governor_data;
  54253. + else
  54254. + tunables = common_tunables;
  54255. +
  54256. + WARN_ON(!tunables && (event != CPUFREQ_GOV_POLICY_INIT));
  54257. +
  54258. + switch (event) {
  54259. + case CPUFREQ_GOV_POLICY_INIT:
  54260. + if (have_governor_per_policy()) {
  54261. + WARN_ON(tunables);
  54262. + } else if (tunables) {
  54263. + tunables->usage_count++;
  54264. + policy->governor_data = tunables;
  54265. + return 0;
  54266. + }
  54267. +
  54268. + tunables = kzalloc(sizeof(*tunables), GFP_KERNEL);
  54269. + if (!tunables) {
  54270. + pr_err("%s: POLICY_INIT: kzalloc failed\n", __func__);
  54271. + return -ENOMEM;
  54272. + }
  54273. +
  54274. + tunables->usage_count = 1;
  54275. + tunables->above_hispeed_delay = default_above_hispeed_delay;
  54276. + tunables->nabove_hispeed_delay =
  54277. + ARRAY_SIZE(default_above_hispeed_delay);
  54278. + tunables->go_hispeed_load = DEFAULT_GO_HISPEED_LOAD;
  54279. + tunables->target_loads = default_target_loads;
  54280. + tunables->ntarget_loads = ARRAY_SIZE(default_target_loads);
  54281. + tunables->min_sample_time = DEFAULT_MIN_SAMPLE_TIME;
  54282. + tunables->timer_rate = DEFAULT_TIMER_RATE;
  54283. + tunables->boostpulse_duration_val = DEFAULT_MIN_SAMPLE_TIME;
  54284. + tunables->timer_slack_val = DEFAULT_TIMER_SLACK;
  54285. +
  54286. + spin_lock_init(&tunables->target_loads_lock);
  54287. + spin_lock_init(&tunables->above_hispeed_delay_lock);
  54288. +
  54289. + policy->governor_data = tunables;
  54290. + if (!have_governor_per_policy()) {
  54291. + common_tunables = tunables;
  54292. + WARN_ON(cpufreq_get_global_kobject());
  54293. + }
  54294. +
  54295. + rc = sysfs_create_group(get_governor_parent_kobj(policy),
  54296. + get_sysfs_attr());
  54297. + if (rc) {
  54298. + kfree(tunables);
  54299. + policy->governor_data = NULL;
  54300. + if (!have_governor_per_policy())
  54301. + common_tunables = NULL;
  54302. + return rc;
  54303. + }
  54304. +
  54305. + if (!policy->governor->initialized) {
  54306. + idle_notifier_register(&cpufreq_interactive_idle_nb);
  54307. + cpufreq_register_notifier(&cpufreq_notifier_block,
  54308. + CPUFREQ_TRANSITION_NOTIFIER);
  54309. + }
  54310. +
  54311. + break;
  54312. +
  54313. + case CPUFREQ_GOV_POLICY_EXIT:
  54314. + if (!--tunables->usage_count) {
  54315. + sysfs_remove_group(get_governor_parent_kobj(policy),
  54316. + get_sysfs_attr());
  54317. +
  54318. + if (!have_governor_per_policy())
  54319. + cpufreq_put_global_kobject();
  54320. +
  54321. + if (policy->governor->initialized == 1) {
  54322. + cpufreq_unregister_notifier(&cpufreq_notifier_block,
  54323. + CPUFREQ_TRANSITION_NOTIFIER);
  54324. + idle_notifier_unregister(&cpufreq_interactive_idle_nb);
  54325. + }
  54326. +
  54327. + kfree(tunables);
  54328. + common_tunables = NULL;
  54329. + }
  54330. +
  54331. + policy->governor_data = NULL;
  54332. + break;
  54333. +
  54334. + case CPUFREQ_GOV_START:
  54335. + mutex_lock(&gov_lock);
  54336. +
  54337. + freq_table = cpufreq_frequency_get_table(policy->cpu);
  54338. + if (!tunables->hispeed_freq)
  54339. + tunables->hispeed_freq = policy->max;
  54340. +
  54341. + for_each_cpu(j, policy->cpus) {
  54342. + pcpu = &per_cpu(cpuinfo, j);
  54343. + pcpu->policy = policy;
  54344. + pcpu->target_freq = policy->cur;
  54345. + pcpu->freq_table = freq_table;
  54346. + pcpu->floor_freq = pcpu->target_freq;
  54347. + pcpu->floor_validate_time =
  54348. + ktime_to_us(ktime_get());
  54349. + pcpu->hispeed_validate_time =
  54350. + pcpu->floor_validate_time;
  54351. + down_write(&pcpu->enable_sem);
  54352. + del_timer_sync(&pcpu->cpu_timer);
  54353. + del_timer_sync(&pcpu->cpu_slack_timer);
  54354. + cpufreq_interactive_timer_start(tunables, j);
  54355. + pcpu->governor_enabled = 1;
  54356. + up_write(&pcpu->enable_sem);
  54357. + }
  54358. +
  54359. + mutex_unlock(&gov_lock);
  54360. + break;
  54361. +
  54362. + case CPUFREQ_GOV_STOP:
  54363. + mutex_lock(&gov_lock);
  54364. + for_each_cpu(j, policy->cpus) {
  54365. + pcpu = &per_cpu(cpuinfo, j);
  54366. + down_write(&pcpu->enable_sem);
  54367. + pcpu->governor_enabled = 0;
  54368. + del_timer_sync(&pcpu->cpu_timer);
  54369. + del_timer_sync(&pcpu->cpu_slack_timer);
  54370. + up_write(&pcpu->enable_sem);
  54371. + }
  54372. +
  54373. + mutex_unlock(&gov_lock);
  54374. + break;
  54375. +
  54376. + case CPUFREQ_GOV_LIMITS:
  54377. + if (policy->max < policy->cur)
  54378. + __cpufreq_driver_target(policy,
  54379. + policy->max, CPUFREQ_RELATION_H);
  54380. + else if (policy->min > policy->cur)
  54381. + __cpufreq_driver_target(policy,
  54382. + policy->min, CPUFREQ_RELATION_L);
  54383. + for_each_cpu(j, policy->cpus) {
  54384. + pcpu = &per_cpu(cpuinfo, j);
  54385. +
  54386. + /* hold write semaphore to avoid race */
  54387. + down_write(&pcpu->enable_sem);
  54388. + if (pcpu->governor_enabled == 0) {
  54389. + up_write(&pcpu->enable_sem);
  54390. + continue;
  54391. + }
  54392. +
  54393. + /* update target_freq firstly */
  54394. + if (policy->max < pcpu->target_freq)
  54395. + pcpu->target_freq = policy->max;
  54396. + else if (policy->min > pcpu->target_freq)
  54397. + pcpu->target_freq = policy->min;
  54398. +
  54399. + /* Reschedule timer.
  54400. + * Delete the timers, else the timer callback may
  54401. + * return without re-arm the timer when failed
  54402. + * acquire the semaphore. This race may cause timer
  54403. + * stopped unexpectedly.
  54404. + */
  54405. + del_timer_sync(&pcpu->cpu_timer);
  54406. + del_timer_sync(&pcpu->cpu_slack_timer);
  54407. + cpufreq_interactive_timer_start(tunables, j);
  54408. + up_write(&pcpu->enable_sem);
  54409. + }
  54410. + break;
  54411. + }
  54412. + return 0;
  54413. +}
  54414. +
  54415. +#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE
  54416. +static
  54417. +#endif
  54418. +struct cpufreq_governor cpufreq_gov_interactive = {
  54419. + .name = "interactive",
  54420. + .governor = cpufreq_governor_interactive,
  54421. + .max_transition_latency = 10000000,
  54422. + .owner = THIS_MODULE,
  54423. +};
  54424. +
  54425. +static void cpufreq_interactive_nop_timer(unsigned long data)
  54426. +{
  54427. +}
  54428. +
  54429. +static int __init cpufreq_interactive_init(void)
  54430. +{
  54431. + unsigned int i;
  54432. + struct cpufreq_interactive_cpuinfo *pcpu;
  54433. + struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
  54434. +
  54435. + /* Initalize per-cpu timers */
  54436. + for_each_possible_cpu(i) {
  54437. + pcpu = &per_cpu(cpuinfo, i);
  54438. + init_timer_deferrable(&pcpu->cpu_timer);
  54439. + pcpu->cpu_timer.function = cpufreq_interactive_timer;
  54440. + pcpu->cpu_timer.data = i;
  54441. + init_timer(&pcpu->cpu_slack_timer);
  54442. + pcpu->cpu_slack_timer.function = cpufreq_interactive_nop_timer;
  54443. + spin_lock_init(&pcpu->load_lock);
  54444. + init_rwsem(&pcpu->enable_sem);
  54445. + }
  54446. +
  54447. + spin_lock_init(&speedchange_cpumask_lock);
  54448. + mutex_init(&gov_lock);
  54449. + speedchange_task =
  54450. + kthread_create(cpufreq_interactive_speedchange_task, NULL,
  54451. + "cfinteractive");
  54452. + if (IS_ERR(speedchange_task))
  54453. + return PTR_ERR(speedchange_task);
  54454. +
  54455. + sched_setscheduler_nocheck(speedchange_task, SCHED_FIFO, &param);
  54456. + get_task_struct(speedchange_task);
  54457. +
  54458. + /* NB: wake up so the thread does not look hung to the freezer */
  54459. + wake_up_process(speedchange_task);
  54460. +
  54461. + return cpufreq_register_governor(&cpufreq_gov_interactive);
  54462. +}
  54463. +
  54464. +#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE
  54465. +fs_initcall(cpufreq_interactive_init);
  54466. +#else
  54467. +module_init(cpufreq_interactive_init);
  54468. +#endif
  54469. +
  54470. +static void __exit cpufreq_interactive_exit(void)
  54471. +{
  54472. + cpufreq_unregister_governor(&cpufreq_gov_interactive);
  54473. + kthread_stop(speedchange_task);
  54474. + put_task_struct(speedchange_task);
  54475. +}
  54476. +
  54477. +module_exit(cpufreq_interactive_exit);
  54478. +
  54479. +MODULE_AUTHOR("Mike Chan <mike@android.com>");
  54480. +MODULE_DESCRIPTION("'cpufreq_interactive' - A cpufreq governor for "
  54481. + "Latency sensitive workloads");
  54482. +MODULE_LICENSE("GPL");
  54483. diff -Nur linux-3.14.15/drivers/cpufreq/highbank-cpufreq.c linux-linaro-stable-mx6/drivers/cpufreq/highbank-cpufreq.c
  54484. --- linux-3.14.15/drivers/cpufreq/highbank-cpufreq.c 2014-07-31 23:51:43.000000000 +0200
  54485. +++ linux-linaro-stable-mx6/drivers/cpufreq/highbank-cpufreq.c 2014-08-20 19:31:42.692854256 +0200
  54486. @@ -19,7 +19,7 @@
  54487. #include <linux/cpu.h>
  54488. #include <linux/err.h>
  54489. #include <linux/of.h>
  54490. -#include <linux/mailbox.h>
  54491. +#include <linux/pl320-ipc.h>
  54492. #include <linux/platform_device.h>
  54493. #define HB_CPUFREQ_CHANGE_NOTE 0x80000001
  54494. diff -Nur linux-3.14.15/drivers/cpufreq/imx6-cpufreq.c linux-linaro-stable-mx6/drivers/cpufreq/imx6-cpufreq.c
  54495. --- linux-3.14.15/drivers/cpufreq/imx6-cpufreq.c 1970-01-01 01:00:00.000000000 +0100
  54496. +++ linux-linaro-stable-mx6/drivers/cpufreq/imx6-cpufreq.c 2014-08-20 19:31:42.696854274 +0200
  54497. @@ -0,0 +1,393 @@
  54498. +/*
  54499. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  54500. + *
  54501. + * This program is free software; you can redistribute it and/or modify
  54502. + * it under the terms of the GNU General Public License version 2 as
  54503. + * published by the Free Software Foundation.
  54504. + */
  54505. +
  54506. +#include <linux/busfreq-imx6.h>
  54507. +#include <linux/clk.h>
  54508. +#include <linux/cpu.h>
  54509. +#include <linux/cpufreq.h>
  54510. +#include <linux/delay.h>
  54511. +#include <linux/err.h>
  54512. +#include <linux/module.h>
  54513. +#include <linux/of.h>
  54514. +#include <linux/pm_opp.h>
  54515. +#include <linux/platform_device.h>
  54516. +#include <linux/regulator/consumer.h>
  54517. +#include <linux/suspend.h>
  54518. +
  54519. +#define PU_SOC_VOLTAGE_NORMAL 1250000
  54520. +#define PU_SOC_VOLTAGE_HIGH 1275000
  54521. +#define FREQ_1P2_GHZ 1200000000
  54522. +
  54523. +static struct regulator *arm_reg;
  54524. +static struct regulator *pu_reg;
  54525. +static struct regulator *soc_reg;
  54526. +
  54527. +static struct clk *arm_clk;
  54528. +static struct clk *pll1_sys_clk;
  54529. +static struct clk *pll1_sw_clk;
  54530. +static struct clk *step_clk;
  54531. +static struct clk *pll2_pfd2_396m_clk;
  54532. +
  54533. +static struct device *cpu_dev;
  54534. +static struct cpufreq_frequency_table *freq_table;
  54535. +static unsigned int transition_latency;
  54536. +static struct mutex set_cpufreq_lock;
  54537. +
  54538. +static u32 *imx6_soc_volt;
  54539. +static u32 soc_opp_count;
  54540. +
  54541. +static int imx6_set_target(struct cpufreq_policy *policy, unsigned int index)
  54542. +{
  54543. + struct dev_pm_opp *opp;
  54544. + unsigned long freq_hz, volt, volt_old;
  54545. + unsigned int old_freq, new_freq;
  54546. + int ret;
  54547. +
  54548. + mutex_lock(&set_cpufreq_lock);
  54549. +
  54550. + new_freq = freq_table[index].frequency;
  54551. + freq_hz = new_freq * 1000;
  54552. + old_freq = clk_get_rate(arm_clk) / 1000;
  54553. +
  54554. + rcu_read_lock();
  54555. + opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
  54556. + if (IS_ERR(opp)) {
  54557. + rcu_read_unlock();
  54558. + dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
  54559. + ret = PTR_ERR(opp);
  54560. + goto unlock;
  54561. + }
  54562. +
  54563. + volt = dev_pm_opp_get_voltage(opp);
  54564. + rcu_read_unlock();
  54565. + volt_old = regulator_get_voltage(arm_reg);
  54566. +
  54567. + dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
  54568. + old_freq / 1000, volt_old / 1000,
  54569. + new_freq / 1000, volt / 1000);
  54570. +
  54571. + /*
  54572. + * CPU freq is increasing, so need to ensure
  54573. + * that bus frequency is increased too.
  54574. + */
  54575. + if (old_freq == freq_table[0].frequency)
  54576. + request_bus_freq(BUS_FREQ_HIGH);
  54577. +
  54578. + /* scaling up? scale voltage before frequency */
  54579. + if (new_freq > old_freq) {
  54580. + if (regulator_is_enabled(pu_reg)) {
  54581. + ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  54582. + if (ret) {
  54583. + dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
  54584. + goto unlock;
  54585. + }
  54586. + }
  54587. + ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  54588. + if (ret) {
  54589. + dev_err(cpu_dev, "failed to scale vddsoc up: %d\n", ret);
  54590. + goto unlock;
  54591. + }
  54592. + ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  54593. + if (ret) {
  54594. + dev_err(cpu_dev,
  54595. + "failed to scale vddarm up: %d\n", ret);
  54596. + goto unlock;
  54597. + }
  54598. + }
  54599. +
  54600. + /*
  54601. + * The setpoints are selected per PLL/PDF frequencies, so we need to
  54602. + * reprogram PLL for frequency scaling. The procedure of reprogramming
  54603. + * PLL1 is as below.
  54604. + *
  54605. + * - Enable pll2_pfd2_396m_clk and reparent pll1_sw_clk to it
  54606. + * - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it
  54607. + * - Disable pll2_pfd2_396m_clk
  54608. + */
  54609. + clk_set_parent(step_clk, pll2_pfd2_396m_clk);
  54610. + clk_set_parent(pll1_sw_clk, step_clk);
  54611. + if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) {
  54612. + clk_set_rate(pll1_sys_clk, new_freq * 1000);
  54613. + clk_set_parent(pll1_sw_clk, pll1_sys_clk);
  54614. + }
  54615. +
  54616. + /* Ensure the arm clock divider is what we expect */
  54617. + ret = clk_set_rate(arm_clk, new_freq * 1000);
  54618. + if (ret) {
  54619. + dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
  54620. + regulator_set_voltage_tol(arm_reg, volt_old, 0);
  54621. + goto unlock;
  54622. + }
  54623. +
  54624. + /* scaling down? scale voltage after frequency */
  54625. + if (new_freq < old_freq) {
  54626. + ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  54627. + if (ret) {
  54628. + dev_warn(cpu_dev,
  54629. + "failed to scale vddarm down: %d\n", ret);
  54630. + ret = 0;
  54631. + }
  54632. + ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  54633. + if (ret) {
  54634. + dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);
  54635. + ret = 0;
  54636. + }
  54637. + if (regulator_is_enabled(pu_reg)) {
  54638. + ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  54639. + if (ret) {
  54640. + dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
  54641. + ret = 0;
  54642. + }
  54643. + }
  54644. + }
  54645. +
  54646. + if (policy->cur == freq_table[0].frequency)
  54647. + release_bus_freq(BUS_FREQ_HIGH);
  54648. +
  54649. +unlock:
  54650. + mutex_unlock(&set_cpufreq_lock);
  54651. + return ret;
  54652. +}
  54653. +
  54654. +static int imx6_cpufreq_init(struct cpufreq_policy *policy)
  54655. +{
  54656. + policy->clk = arm_clk;
  54657. +
  54658. + if (policy->cur > freq_table[0].frequency)
  54659. + request_bus_freq(BUS_FREQ_HIGH);
  54660. +
  54661. + return cpufreq_generic_init(policy, freq_table, transition_latency);
  54662. +}
  54663. +
  54664. +static struct cpufreq_driver imx6_cpufreq_driver = {
  54665. + .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
  54666. + .verify = cpufreq_generic_frequency_table_verify,
  54667. + .target_index = imx6_set_target,
  54668. + .get = cpufreq_generic_get,
  54669. + .init = imx6_cpufreq_init,
  54670. + .exit = cpufreq_generic_exit,
  54671. + .name = "imx6-cpufreq",
  54672. + .attr = cpufreq_generic_attr,
  54673. +};
  54674. +
  54675. +static int imx6_cpufreq_pm_notify(struct notifier_block *nb,
  54676. + unsigned long event, void *dummy)
  54677. +{
  54678. + struct cpufreq_policy *data = cpufreq_cpu_get(0);
  54679. + static u32 cpufreq_policy_min_pre_suspend;
  54680. +
  54681. + /*
  54682. + * During suspend/resume, When cpufreq driver try to increase
  54683. + * voltage/freq, it needs to control I2C/SPI to communicate
  54684. + * with external PMIC to adjust voltage, but these I2C/SPI
  54685. + * devices may be already suspended, to avoid such scenario,
  54686. + * we just increase cpufreq to highest setpoint before suspend.
  54687. + */
  54688. + switch (event) {
  54689. + case PM_SUSPEND_PREPARE:
  54690. + cpufreq_policy_min_pre_suspend = data->user_policy.min;
  54691. + data->user_policy.min = data->user_policy.max;
  54692. + break;
  54693. + case PM_POST_SUSPEND:
  54694. + data->user_policy.min = cpufreq_policy_min_pre_suspend;
  54695. + break;
  54696. + default:
  54697. + break;
  54698. + }
  54699. +
  54700. + cpufreq_update_policy(0);
  54701. +
  54702. + return NOTIFY_OK;
  54703. +}
  54704. +
  54705. +static struct notifier_block imx6_cpufreq_pm_notifier = {
  54706. + .notifier_call = imx6_cpufreq_pm_notify,
  54707. +};
  54708. +
  54709. +static int imx6_cpufreq_probe(struct platform_device *pdev)
  54710. +{
  54711. + struct device_node *np;
  54712. + struct dev_pm_opp *opp;
  54713. + unsigned long min_volt, max_volt;
  54714. + int num, ret;
  54715. + const struct property *prop;
  54716. + const __be32 *val;
  54717. + u32 nr, i, j;
  54718. +
  54719. + cpu_dev = get_cpu_device(0);
  54720. + if (!cpu_dev) {
  54721. + pr_err("failed to get cpu0 device\n");
  54722. + return -ENODEV;
  54723. + }
  54724. +
  54725. + np = of_node_get(cpu_dev->of_node);
  54726. + if (!np) {
  54727. + dev_err(cpu_dev, "failed to find cpu0 node\n");
  54728. + return -ENOENT;
  54729. + }
  54730. +
  54731. + arm_clk = devm_clk_get(cpu_dev, "arm");
  54732. + pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
  54733. + pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
  54734. + step_clk = devm_clk_get(cpu_dev, "step");
  54735. + pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m");
  54736. + if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
  54737. + IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
  54738. + dev_err(cpu_dev, "failed to get clocks\n");
  54739. + ret = -ENOENT;
  54740. + goto put_node;
  54741. + }
  54742. +
  54743. + arm_reg = devm_regulator_get(cpu_dev, "arm");
  54744. + pu_reg = devm_regulator_get(cpu_dev, "pu");
  54745. + soc_reg = devm_regulator_get(cpu_dev, "soc");
  54746. + if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
  54747. + dev_err(cpu_dev, "failed to get regulators\n");
  54748. + ret = -ENOENT;
  54749. + goto put_node;
  54750. + }
  54751. +
  54752. + /*
  54753. + * We expect an OPP table supplied by platform.
  54754. + * Just, incase the platform did not supply the OPP
  54755. + * table, it will try to get it.
  54756. + */
  54757. + num = dev_pm_opp_get_opp_count(cpu_dev);
  54758. + if (num < 0) {
  54759. + ret = of_init_opp_table(cpu_dev);
  54760. + if (ret < 0) {
  54761. + dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
  54762. + goto put_node;
  54763. + }
  54764. +
  54765. + num = dev_pm_opp_get_opp_count(cpu_dev);
  54766. + if (num < 0) {
  54767. + ret = num;
  54768. + dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
  54769. + goto put_node;
  54770. + }
  54771. + }
  54772. +
  54773. + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
  54774. + if (ret) {
  54775. + dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
  54776. + goto put_node;
  54777. + }
  54778. +
  54779. + /* Make imx6_soc_volt array's size same as arm opp number */
  54780. + imx6_soc_volt = devm_kzalloc(cpu_dev, sizeof(*imx6_soc_volt) * num, GFP_KERNEL);
  54781. + if (imx6_soc_volt == NULL) {
  54782. + ret = -ENOMEM;
  54783. + goto free_freq_table;
  54784. + }
  54785. +
  54786. + prop = of_find_property(np, "fsl,soc-operating-points", NULL);
  54787. + if (!prop || !prop->value)
  54788. + goto soc_opp_out;
  54789. +
  54790. + /*
  54791. + * Each OPP is a set of tuples consisting of frequency and
  54792. + * voltage like <freq-kHz vol-uV>.
  54793. + */
  54794. + nr = prop->length / sizeof(u32);
  54795. + if (nr % 2 || (nr / 2) < num)
  54796. + goto soc_opp_out;
  54797. +
  54798. + for (j = 0; j < num; j++) {
  54799. + val = prop->value;
  54800. + for (i = 0; i < nr / 2; i++) {
  54801. + unsigned long freq = be32_to_cpup(val++);
  54802. + unsigned long volt = be32_to_cpup(val++);
  54803. + if (freq_table[j].frequency == freq) {
  54804. + imx6_soc_volt[soc_opp_count++] = volt;
  54805. + break;
  54806. + }
  54807. + }
  54808. + }
  54809. +
  54810. +soc_opp_out:
  54811. + /* use fixed soc opp volt if no valid soc opp info found in dtb */
  54812. + if (soc_opp_count != num) {
  54813. + dev_warn(cpu_dev, "can NOT find valid fsl,soc-operating-points property in dtb, use default value!\n");
  54814. + for (j = 0; j < num; j++)
  54815. + imx6_soc_volt[j] = PU_SOC_VOLTAGE_NORMAL;
  54816. + if (freq_table[num - 1].frequency * 1000 == FREQ_1P2_GHZ)
  54817. + imx6_soc_volt[num - 1] = PU_SOC_VOLTAGE_HIGH;
  54818. + }
  54819. +
  54820. + if (of_property_read_u32(np, "clock-latency", &transition_latency))
  54821. + transition_latency = CPUFREQ_ETERNAL;
  54822. +
  54823. + /*
  54824. + * Calculate the ramp time for max voltage change in the
  54825. + * VDDSOC and VDDPU regulators.
  54826. + */
  54827. + ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  54828. + if (ret > 0)
  54829. + transition_latency += ret * 1000;
  54830. + ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  54831. + if (ret > 0)
  54832. + transition_latency += ret * 1000;
  54833. +
  54834. + /*
  54835. + * OPP is maintained in order of increasing frequency, and
  54836. + * freq_table initialised from OPP is therefore sorted in the
  54837. + * same order.
  54838. + */
  54839. + rcu_read_lock();
  54840. + opp = dev_pm_opp_find_freq_exact(cpu_dev,
  54841. + freq_table[0].frequency * 1000, true);
  54842. + min_volt = dev_pm_opp_get_voltage(opp);
  54843. + opp = dev_pm_opp_find_freq_exact(cpu_dev,
  54844. + freq_table[--num].frequency * 1000, true);
  54845. + max_volt = dev_pm_opp_get_voltage(opp);
  54846. + rcu_read_unlock();
  54847. + ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt);
  54848. + if (ret > 0)
  54849. + transition_latency += ret * 1000;
  54850. +
  54851. + mutex_init(&set_cpufreq_lock);
  54852. + register_pm_notifier(&imx6_cpufreq_pm_notifier);
  54853. +
  54854. + ret = cpufreq_register_driver(&imx6_cpufreq_driver);
  54855. + if (ret) {
  54856. + dev_err(cpu_dev, "failed register driver: %d\n", ret);
  54857. + goto free_freq_table;
  54858. + }
  54859. +
  54860. + of_node_put(np);
  54861. + return 0;
  54862. +
  54863. +free_freq_table:
  54864. + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  54865. +put_node:
  54866. + of_node_put(np);
  54867. + return ret;
  54868. +}
  54869. +
  54870. +static int imx6_cpufreq_remove(struct platform_device *pdev)
  54871. +{
  54872. + cpufreq_unregister_driver(&imx6_cpufreq_driver);
  54873. + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  54874. +
  54875. + return 0;
  54876. +}
  54877. +
  54878. +static struct platform_driver imx6_cpufreq_platdrv = {
  54879. + .driver = {
  54880. + .name = "imx6-cpufreq",
  54881. + .owner = THIS_MODULE,
  54882. + },
  54883. + .probe = imx6_cpufreq_probe,
  54884. + .remove = imx6_cpufreq_remove,
  54885. +};
  54886. +module_platform_driver(imx6_cpufreq_platdrv);
  54887. +
  54888. +MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
  54889. +MODULE_DESCRIPTION("Freescale i.MX6Q cpufreq driver");
  54890. +MODULE_LICENSE("GPL");
  54891. diff -Nur linux-3.14.15/drivers/cpufreq/imx6q-cpufreq.c linux-linaro-stable-mx6/drivers/cpufreq/imx6q-cpufreq.c
  54892. --- linux-3.14.15/drivers/cpufreq/imx6q-cpufreq.c 2014-07-31 23:51:43.000000000 +0200
  54893. +++ linux-linaro-stable-mx6/drivers/cpufreq/imx6q-cpufreq.c 1970-01-01 01:00:00.000000000 +0100
  54894. @@ -1,330 +0,0 @@
  54895. -/*
  54896. - * Copyright (C) 2013 Freescale Semiconductor, Inc.
  54897. - *
  54898. - * This program is free software; you can redistribute it and/or modify
  54899. - * it under the terms of the GNU General Public License version 2 as
  54900. - * published by the Free Software Foundation.
  54901. - */
  54902. -
  54903. -#include <linux/clk.h>
  54904. -#include <linux/cpu.h>
  54905. -#include <linux/cpufreq.h>
  54906. -#include <linux/delay.h>
  54907. -#include <linux/err.h>
  54908. -#include <linux/module.h>
  54909. -#include <linux/of.h>
  54910. -#include <linux/pm_opp.h>
  54911. -#include <linux/platform_device.h>
  54912. -#include <linux/regulator/consumer.h>
  54913. -
  54914. -#define PU_SOC_VOLTAGE_NORMAL 1250000
  54915. -#define PU_SOC_VOLTAGE_HIGH 1275000
  54916. -#define FREQ_1P2_GHZ 1200000000
  54917. -
  54918. -static struct regulator *arm_reg;
  54919. -static struct regulator *pu_reg;
  54920. -static struct regulator *soc_reg;
  54921. -
  54922. -static struct clk *arm_clk;
  54923. -static struct clk *pll1_sys_clk;
  54924. -static struct clk *pll1_sw_clk;
  54925. -static struct clk *step_clk;
  54926. -static struct clk *pll2_pfd2_396m_clk;
  54927. -
  54928. -static struct device *cpu_dev;
  54929. -static struct cpufreq_frequency_table *freq_table;
  54930. -static unsigned int transition_latency;
  54931. -
  54932. -static u32 *imx6_soc_volt;
  54933. -static u32 soc_opp_count;
  54934. -
  54935. -static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
  54936. -{
  54937. - struct dev_pm_opp *opp;
  54938. - unsigned long freq_hz, volt, volt_old;
  54939. - unsigned int old_freq, new_freq;
  54940. - int ret;
  54941. -
  54942. - new_freq = freq_table[index].frequency;
  54943. - freq_hz = new_freq * 1000;
  54944. - old_freq = clk_get_rate(arm_clk) / 1000;
  54945. -
  54946. - rcu_read_lock();
  54947. - opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
  54948. - if (IS_ERR(opp)) {
  54949. - rcu_read_unlock();
  54950. - dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
  54951. - return PTR_ERR(opp);
  54952. - }
  54953. -
  54954. - volt = dev_pm_opp_get_voltage(opp);
  54955. - rcu_read_unlock();
  54956. - volt_old = regulator_get_voltage(arm_reg);
  54957. -
  54958. - dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
  54959. - old_freq / 1000, volt_old / 1000,
  54960. - new_freq / 1000, volt / 1000);
  54961. -
  54962. - /* scaling up? scale voltage before frequency */
  54963. - if (new_freq > old_freq) {
  54964. - ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  54965. - if (ret) {
  54966. - dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
  54967. - return ret;
  54968. - }
  54969. - ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  54970. - if (ret) {
  54971. - dev_err(cpu_dev, "failed to scale vddsoc up: %d\n", ret);
  54972. - return ret;
  54973. - }
  54974. - ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  54975. - if (ret) {
  54976. - dev_err(cpu_dev,
  54977. - "failed to scale vddarm up: %d\n", ret);
  54978. - return ret;
  54979. - }
  54980. - }
  54981. -
  54982. - /*
  54983. - * The setpoints are selected per PLL/PDF frequencies, so we need to
  54984. - * reprogram PLL for frequency scaling. The procedure of reprogramming
  54985. - * PLL1 is as below.
  54986. - *
  54987. - * - Enable pll2_pfd2_396m_clk and reparent pll1_sw_clk to it
  54988. - * - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it
  54989. - * - Disable pll2_pfd2_396m_clk
  54990. - */
  54991. - clk_set_parent(step_clk, pll2_pfd2_396m_clk);
  54992. - clk_set_parent(pll1_sw_clk, step_clk);
  54993. - if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) {
  54994. - clk_set_rate(pll1_sys_clk, new_freq * 1000);
  54995. - clk_set_parent(pll1_sw_clk, pll1_sys_clk);
  54996. - }
  54997. -
  54998. - /* Ensure the arm clock divider is what we expect */
  54999. - ret = clk_set_rate(arm_clk, new_freq * 1000);
  55000. - if (ret) {
  55001. - dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
  55002. - regulator_set_voltage_tol(arm_reg, volt_old, 0);
  55003. - return ret;
  55004. - }
  55005. -
  55006. - /* scaling down? scale voltage after frequency */
  55007. - if (new_freq < old_freq) {
  55008. - ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  55009. - if (ret) {
  55010. - dev_warn(cpu_dev,
  55011. - "failed to scale vddarm down: %d\n", ret);
  55012. - ret = 0;
  55013. - }
  55014. - ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  55015. - if (ret) {
  55016. - dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);
  55017. - ret = 0;
  55018. - }
  55019. - ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  55020. - if (ret) {
  55021. - dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
  55022. - ret = 0;
  55023. - }
  55024. - }
  55025. -
  55026. - return 0;
  55027. -}
  55028. -
  55029. -static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
  55030. -{
  55031. - policy->clk = arm_clk;
  55032. - return cpufreq_generic_init(policy, freq_table, transition_latency);
  55033. -}
  55034. -
  55035. -static struct cpufreq_driver imx6q_cpufreq_driver = {
  55036. - .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
  55037. - .verify = cpufreq_generic_frequency_table_verify,
  55038. - .target_index = imx6q_set_target,
  55039. - .get = cpufreq_generic_get,
  55040. - .init = imx6q_cpufreq_init,
  55041. - .exit = cpufreq_generic_exit,
  55042. - .name = "imx6q-cpufreq",
  55043. - .attr = cpufreq_generic_attr,
  55044. -};
  55045. -
  55046. -static int imx6q_cpufreq_probe(struct platform_device *pdev)
  55047. -{
  55048. - struct device_node *np;
  55049. - struct dev_pm_opp *opp;
  55050. - unsigned long min_volt, max_volt;
  55051. - int num, ret;
  55052. - const struct property *prop;
  55053. - const __be32 *val;
  55054. - u32 nr, i, j;
  55055. -
  55056. - cpu_dev = get_cpu_device(0);
  55057. - if (!cpu_dev) {
  55058. - pr_err("failed to get cpu0 device\n");
  55059. - return -ENODEV;
  55060. - }
  55061. -
  55062. - np = of_node_get(cpu_dev->of_node);
  55063. - if (!np) {
  55064. - dev_err(cpu_dev, "failed to find cpu0 node\n");
  55065. - return -ENOENT;
  55066. - }
  55067. -
  55068. - arm_clk = devm_clk_get(cpu_dev, "arm");
  55069. - pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
  55070. - pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
  55071. - step_clk = devm_clk_get(cpu_dev, "step");
  55072. - pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m");
  55073. - if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
  55074. - IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
  55075. - dev_err(cpu_dev, "failed to get clocks\n");
  55076. - ret = -ENOENT;
  55077. - goto put_node;
  55078. - }
  55079. -
  55080. - arm_reg = devm_regulator_get(cpu_dev, "arm");
  55081. - pu_reg = devm_regulator_get(cpu_dev, "pu");
  55082. - soc_reg = devm_regulator_get(cpu_dev, "soc");
  55083. - if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
  55084. - dev_err(cpu_dev, "failed to get regulators\n");
  55085. - ret = -ENOENT;
  55086. - goto put_node;
  55087. - }
  55088. -
  55089. - /*
  55090. - * We expect an OPP table supplied by platform.
  55091. - * Just, incase the platform did not supply the OPP
  55092. - * table, it will try to get it.
  55093. - */
  55094. - num = dev_pm_opp_get_opp_count(cpu_dev);
  55095. - if (num < 0) {
  55096. - ret = of_init_opp_table(cpu_dev);
  55097. - if (ret < 0) {
  55098. - dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
  55099. - goto put_node;
  55100. - }
  55101. -
  55102. - num = dev_pm_opp_get_opp_count(cpu_dev);
  55103. - if (num < 0) {
  55104. - ret = num;
  55105. - dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
  55106. - goto put_node;
  55107. - }
  55108. - }
  55109. -
  55110. - ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
  55111. - if (ret) {
  55112. - dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
  55113. - goto put_node;
  55114. - }
  55115. -
  55116. - /* Make imx6_soc_volt array's size same as arm opp number */
  55117. - imx6_soc_volt = devm_kzalloc(cpu_dev, sizeof(*imx6_soc_volt) * num, GFP_KERNEL);
  55118. - if (imx6_soc_volt == NULL) {
  55119. - ret = -ENOMEM;
  55120. - goto free_freq_table;
  55121. - }
  55122. -
  55123. - prop = of_find_property(np, "fsl,soc-operating-points", NULL);
  55124. - if (!prop || !prop->value)
  55125. - goto soc_opp_out;
  55126. -
  55127. - /*
  55128. - * Each OPP is a set of tuples consisting of frequency and
  55129. - * voltage like <freq-kHz vol-uV>.
  55130. - */
  55131. - nr = prop->length / sizeof(u32);
  55132. - if (nr % 2 || (nr / 2) < num)
  55133. - goto soc_opp_out;
  55134. -
  55135. - for (j = 0; j < num; j++) {
  55136. - val = prop->value;
  55137. - for (i = 0; i < nr / 2; i++) {
  55138. - unsigned long freq = be32_to_cpup(val++);
  55139. - unsigned long volt = be32_to_cpup(val++);
  55140. - if (freq_table[j].frequency == freq) {
  55141. - imx6_soc_volt[soc_opp_count++] = volt;
  55142. - break;
  55143. - }
  55144. - }
  55145. - }
  55146. -
  55147. -soc_opp_out:
  55148. - /* use fixed soc opp volt if no valid soc opp info found in dtb */
  55149. - if (soc_opp_count != num) {
  55150. - dev_warn(cpu_dev, "can NOT find valid fsl,soc-operating-points property in dtb, use default value!\n");
  55151. - for (j = 0; j < num; j++)
  55152. - imx6_soc_volt[j] = PU_SOC_VOLTAGE_NORMAL;
  55153. - if (freq_table[num - 1].frequency * 1000 == FREQ_1P2_GHZ)
  55154. - imx6_soc_volt[num - 1] = PU_SOC_VOLTAGE_HIGH;
  55155. - }
  55156. -
  55157. - if (of_property_read_u32(np, "clock-latency", &transition_latency))
  55158. - transition_latency = CPUFREQ_ETERNAL;
  55159. -
  55160. - /*
  55161. - * Calculate the ramp time for max voltage change in the
  55162. - * VDDSOC and VDDPU regulators.
  55163. - */
  55164. - ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  55165. - if (ret > 0)
  55166. - transition_latency += ret * 1000;
  55167. - ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  55168. - if (ret > 0)
  55169. - transition_latency += ret * 1000;
  55170. -
  55171. - /*
  55172. - * OPP is maintained in order of increasing frequency, and
  55173. - * freq_table initialised from OPP is therefore sorted in the
  55174. - * same order.
  55175. - */
  55176. - rcu_read_lock();
  55177. - opp = dev_pm_opp_find_freq_exact(cpu_dev,
  55178. - freq_table[0].frequency * 1000, true);
  55179. - min_volt = dev_pm_opp_get_voltage(opp);
  55180. - opp = dev_pm_opp_find_freq_exact(cpu_dev,
  55181. - freq_table[--num].frequency * 1000, true);
  55182. - max_volt = dev_pm_opp_get_voltage(opp);
  55183. - rcu_read_unlock();
  55184. - ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt);
  55185. - if (ret > 0)
  55186. - transition_latency += ret * 1000;
  55187. -
  55188. - ret = cpufreq_register_driver(&imx6q_cpufreq_driver);
  55189. - if (ret) {
  55190. - dev_err(cpu_dev, "failed register driver: %d\n", ret);
  55191. - goto free_freq_table;
  55192. - }
  55193. -
  55194. - of_node_put(np);
  55195. - return 0;
  55196. -
  55197. -free_freq_table:
  55198. - dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  55199. -put_node:
  55200. - of_node_put(np);
  55201. - return ret;
  55202. -}
  55203. -
  55204. -static int imx6q_cpufreq_remove(struct platform_device *pdev)
  55205. -{
  55206. - cpufreq_unregister_driver(&imx6q_cpufreq_driver);
  55207. - dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  55208. -
  55209. - return 0;
  55210. -}
  55211. -
  55212. -static struct platform_driver imx6q_cpufreq_platdrv = {
  55213. - .driver = {
  55214. - .name = "imx6q-cpufreq",
  55215. - .owner = THIS_MODULE,
  55216. - },
  55217. - .probe = imx6q_cpufreq_probe,
  55218. - .remove = imx6q_cpufreq_remove,
  55219. -};
  55220. -module_platform_driver(imx6q_cpufreq_platdrv);
  55221. -
  55222. -MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
  55223. -MODULE_DESCRIPTION("Freescale i.MX6Q cpufreq driver");
  55224. -MODULE_LICENSE("GPL");
  55225. diff -Nur linux-3.14.15/drivers/cpufreq/Kconfig linux-linaro-stable-mx6/drivers/cpufreq/Kconfig
  55226. --- linux-3.14.15/drivers/cpufreq/Kconfig 2014-07-31 23:51:43.000000000 +0200
  55227. +++ linux-linaro-stable-mx6/drivers/cpufreq/Kconfig 2014-08-20 19:31:42.684854222 +0200
  55228. @@ -91,6 +91,15 @@
  55229. governor. If unsure have a look at the help section of the
  55230. driver. Fallback governor will be the performance governor.
  55231. +config CPU_FREQ_DEFAULT_GOV_INTERACTIVE
  55232. + bool "interactive"
  55233. + select CPU_FREQ_GOV_INTERACTIVE
  55234. + help
  55235. + Use the CPUFreq governor 'interactive' as default. This allows
  55236. + you to get a full dynamic cpu frequency capable system by simply
  55237. + loading your cpufreq low-level hardware driver, using the
  55238. + 'interactive' governor for latency-sensitive workloads.
  55239. +
  55240. config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
  55241. bool "conservative"
  55242. select CPU_FREQ_GOV_CONSERVATIVE
  55243. @@ -157,6 +166,24 @@
  55244. For details, take a look at linux/Documentation/cpu-freq.
  55245. + If in doubt, say N.
  55246. +
  55247. +config CPU_FREQ_GOV_INTERACTIVE
  55248. + tristate "'interactive' cpufreq policy governor"
  55249. + default n
  55250. + help
  55251. + 'interactive' - This driver adds a dynamic cpufreq policy governor
  55252. + designed for latency-sensitive workloads.
  55253. +
  55254. + This governor attempts to reduce the latency of clock
  55255. + increases so that the system is more responsive to
  55256. + interactive workloads.
  55257. +
  55258. + To compile this driver as a module, choose M here: the
  55259. + module will be called cpufreq_interactive.
  55260. +
  55261. + For details, take a look at linux/Documentation/cpu-freq.
  55262. +
  55263. If in doubt, say N.
  55264. config CPU_FREQ_GOV_CONSERVATIVE
  55265. diff -Nur linux-3.14.15/drivers/cpufreq/Kconfig.arm linux-linaro-stable-mx6/drivers/cpufreq/Kconfig.arm
  55266. --- linux-3.14.15/drivers/cpufreq/Kconfig.arm 2014-07-31 23:51:43.000000000 +0200
  55267. +++ linux-linaro-stable-mx6/drivers/cpufreq/Kconfig.arm 2014-08-20 19:31:42.684854222 +0200
  55268. @@ -4,7 +4,8 @@
  55269. config ARM_BIG_LITTLE_CPUFREQ
  55270. tristate "Generic ARM big LITTLE CPUfreq driver"
  55271. - depends on ARM && BIG_LITTLE && ARM_CPU_TOPOLOGY && HAVE_CLK
  55272. + depends on (BIG_LITTLE && ARM_CPU_TOPOLOGY) || (ARM64 && SMP)
  55273. + depends on HAVE_CLK
  55274. select PM_OPP
  55275. help
  55276. This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
  55277. @@ -95,7 +96,7 @@
  55278. If in doubt, say N.
  55279. -config ARM_IMX6Q_CPUFREQ
  55280. +config ARM_IMX6_CPUFREQ
  55281. tristate "Freescale i.MX6 cpufreq support"
  55282. depends on ARCH_MXC
  55283. depends on REGULATOR_ANATOP
  55284. diff -Nur linux-3.14.15/drivers/cpufreq/Makefile linux-linaro-stable-mx6/drivers/cpufreq/Makefile
  55285. --- linux-3.14.15/drivers/cpufreq/Makefile 2014-07-31 23:51:43.000000000 +0200
  55286. +++ linux-linaro-stable-mx6/drivers/cpufreq/Makefile 2014-08-20 19:31:42.684854222 +0200
  55287. @@ -8,6 +8,7 @@
  55288. obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
  55289. obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
  55290. obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o
  55291. +obj-$(CONFIG_CPU_FREQ_GOV_INTERACTIVE) += cpufreq_interactive.o
  55292. obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o
  55293. obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o
  55294. @@ -55,7 +56,7 @@
  55295. obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o
  55296. obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o
  55297. obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o
  55298. -obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
  55299. +obj-$(CONFIG_ARM_IMX6_CPUFREQ) += imx6-cpufreq.o
  55300. obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o
  55301. obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
  55302. obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
  55303. diff -Nur linux-3.14.15/drivers/crypto/caam/secvio.c linux-linaro-stable-mx6/drivers/crypto/caam/secvio.c
  55304. --- linux-3.14.15/drivers/crypto/caam/secvio.c 1970-01-01 01:00:00.000000000 +0100
  55305. +++ linux-linaro-stable-mx6/drivers/crypto/caam/secvio.c 2014-08-20 19:31:42.792854686 +0200
  55306. @@ -0,0 +1,335 @@
  55307. +
  55308. +/*
  55309. + * CAAM/SEC 4.x Security Violation Handler
  55310. + * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
  55311. + */
  55312. +
  55313. +#include "compat.h"
  55314. +#include "intern.h"
  55315. +#include "secvio.h"
  55316. +#include "regs.h"
  55317. +
  55318. +/*
  55319. + * These names are associated with each violation handler.
  55320. + * The source names were taken from MX6, and are based on recommendations
  55321. + * for most common SoCs.
  55322. + */
  55323. +static const u8 *violation_src_name[] = {
  55324. + "CAAM Security Violation",
  55325. + "JTAG Alarm",
  55326. + "Watchdog",
  55327. + "(reserved)",
  55328. + "External Boot",
  55329. + "Tamper Detect",
  55330. +};
  55331. +
  55332. +/* Top-level security violation interrupt */
  55333. +static irqreturn_t caam_secvio_interrupt(int irq, void *snvsdev)
  55334. +{
  55335. + struct device *dev = snvsdev;
  55336. + struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
  55337. + u32 irqstate;
  55338. +
  55339. + /* Check the HP secvio status register */
  55340. + irqstate = rd_reg32(&svpriv->svregs->hp.secvio_status) |
  55341. + HP_SECVIOST_SECVIOMASK;
  55342. +
  55343. + if (!irqstate)
  55344. + return IRQ_NONE;
  55345. +
  55346. + /* Mask out one or more causes for deferred service */
  55347. + clrbits32(&svpriv->svregs->hp.secvio_int_ctl, irqstate);
  55348. +
  55349. + /* Now ACK causes */
  55350. + setbits32(&svpriv->svregs->hp.secvio_status, irqstate);
  55351. +
  55352. + /* And run deferred service */
  55353. + preempt_disable();
  55354. + tasklet_schedule(&svpriv->irqtask[smp_processor_id()]);
  55355. + preempt_enable();
  55356. +
  55357. + return IRQ_HANDLED;
  55358. +}
  55359. +
  55360. +/* Deferred service handler. Tasklet arg is simply the SNVS dev */
  55361. +static void caam_secvio_dispatch(unsigned long indev)
  55362. +{
  55363. + struct device *dev = (struct device *)indev;
  55364. + struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
  55365. + unsigned long flags, cause;
  55366. + int i;
  55367. +
  55368. +
  55369. + /*
  55370. + * Capture the interrupt cause, using masked interrupts as
  55371. + * identification. This only works if all are enabled; if
  55372. + * this changes in the future, a "cause queue" will have to
  55373. + * be built
  55374. + */
  55375. + cause = rd_reg32(&svpriv->svregs->hp.secvio_int_ctl) &
  55376. + (HP_SECVIO_INTEN_SRC5 | HP_SECVIO_INTEN_SRC4 |
  55377. + HP_SECVIO_INTEN_SRC3 | HP_SECVIO_INTEN_SRC2 |
  55378. + HP_SECVIO_INTEN_SRC1 | HP_SECVIO_INTEN_SRC0);
  55379. +
  55380. + /* Look through causes, call each handler if exists */
  55381. + for (i = 0; i < MAX_SECVIO_SOURCES; i++)
  55382. + if (cause & (1 << i)) {
  55383. + spin_lock_irqsave(&svpriv->svlock, flags);
  55384. + svpriv->intsrc[i].handler(dev, i,
  55385. + svpriv->intsrc[i].ext);
  55386. + spin_unlock_irqrestore(&svpriv->svlock, flags);
  55387. + };
  55388. +
  55389. + /* Re-enable now-serviced interrupts */
  55390. + setbits32(&svpriv->svregs->hp.secvio_int_ctl, cause);
  55391. +}
  55392. +
  55393. +/*
  55394. + * Default cause handler, used in lieu of an application-defined handler.
  55395. + * All it does at this time is print a console message. It could force a halt.
  55396. + */
  55397. +static void caam_secvio_default(struct device *dev, u32 cause, void *ext)
  55398. +{
  55399. + struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
  55400. +
  55401. + dev_err(dev, "Unhandled Security Violation Interrupt %d = %s\n",
  55402. + cause, svpriv->intsrc[cause].intname);
  55403. +}
  55404. +
  55405. +/*
  55406. + * Install an application-defined handler for a specified cause
  55407. + * Arguments:
  55408. + * - dev points to SNVS-owning device
  55409. + * - cause interrupt source cause
  55410. + * - handler application-defined handler, gets called with dev
  55411. + * source cause, and locally-defined handler argument
  55412. + * - cause_description points to a string to override the default cause
  55413. + * name, this can be used as an alternate for error
  55414. + * messages and such. If left NULL, the default
  55415. + * description string is used.
  55416. + * - ext pointer to any extra data needed by the handler.
  55417. + */
  55418. +int caam_secvio_install_handler(struct device *dev, enum secvio_cause cause,
  55419. + void (*handler)(struct device *dev, u32 cause,
  55420. + void *ext),
  55421. + u8 *cause_description, void *ext)
  55422. +{
  55423. + unsigned long flags;
  55424. + struct caam_drv_private_secvio *svpriv;
  55425. +
  55426. + svpriv = dev_get_drvdata(dev);
  55427. +
  55428. + if ((handler == NULL) || (cause > SECVIO_CAUSE_SOURCE_5))
  55429. + return -EINVAL;
  55430. +
  55431. + spin_lock_irqsave(&svpriv->svlock, flags);
  55432. + svpriv->intsrc[cause].handler = handler;
  55433. + if (cause_description != NULL)
  55434. + svpriv->intsrc[cause].intname = cause_description;
  55435. + if (ext != NULL)
  55436. + svpriv->intsrc[cause].ext = ext;
  55437. + spin_unlock_irqrestore(&svpriv->svlock, flags);
  55438. +
  55439. + return 0;
  55440. +}
  55441. +EXPORT_SYMBOL(caam_secvio_install_handler);
  55442. +
  55443. +/*
  55444. + * Remove an application-defined handler for a specified cause (and, by
  55445. + * implication, restore the "default".
  55446. + * Arguments:
  55447. + * - dev points to SNVS-owning device
  55448. + * - cause interrupt source cause
  55449. + */
  55450. +int caam_secvio_remove_handler(struct device *dev, enum secvio_cause cause)
  55451. +{
  55452. + unsigned long flags;
  55453. + struct caam_drv_private_secvio *svpriv;
  55454. +
  55455. + svpriv = dev_get_drvdata(dev);
  55456. +
  55457. + if (cause > SECVIO_CAUSE_SOURCE_5)
  55458. + return -EINVAL;
  55459. +
  55460. + spin_lock_irqsave(&svpriv->svlock, flags);
  55461. + svpriv->intsrc[cause].intname = violation_src_name[cause];
  55462. + svpriv->intsrc[cause].handler = caam_secvio_default;
  55463. + svpriv->intsrc[cause].ext = NULL;
  55464. + spin_unlock_irqrestore(&svpriv->svlock, flags);
  55465. + return 0;
  55466. +}
  55467. +EXPORT_SYMBOL(caam_secvio_remove_handler);
  55468. +
  55469. +int caam_secvio_startup(struct platform_device *pdev)
  55470. +{
  55471. + struct device *ctrldev, *svdev;
  55472. + struct caam_drv_private *ctrlpriv;
  55473. + struct caam_drv_private_secvio *svpriv;
  55474. + struct platform_device *svpdev;
  55475. + struct device_node *np;
  55476. + const void *prop;
  55477. + int i, error, secvio_inten_src;
  55478. +
  55479. + ctrldev = &pdev->dev;
  55480. + ctrlpriv = dev_get_drvdata(ctrldev);
  55481. + /*
  55482. + * Set up the private block for secure memory
  55483. + * Only one instance is possible
  55484. + */
  55485. + svpriv = kzalloc(sizeof(struct caam_drv_private_secvio), GFP_KERNEL);
  55486. + if (svpriv == NULL) {
  55487. + dev_err(ctrldev, "can't alloc private mem for secvio\n");
  55488. + return -ENOMEM;
  55489. + }
  55490. + svpriv->parentdev = ctrldev;
  55491. +
  55492. + /* Create the security violation dev */
  55493. +#ifdef CONFIG_OF
  55494. +
  55495. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-secvio");
  55496. + if (!np)
  55497. + return -ENODEV;
  55498. +
  55499. + ctrlpriv->secvio_irq = of_irq_to_resource(np, 0, NULL);
  55500. +
  55501. + prop = of_get_property(np, "secvio_src", NULL);
  55502. + if (prop)
  55503. + secvio_inten_src = of_read_ulong(prop, 1);
  55504. + else
  55505. + secvio_inten_src = HP_SECVIO_INTEN_ALL;
  55506. +
  55507. + printk(KERN_ERR "secvio_inten_src = %x\n", secvio_inten_src);
  55508. +
  55509. + svpdev = of_platform_device_create(np, NULL, ctrldev);
  55510. + if (!svpdev)
  55511. + return -ENODEV;
  55512. +
  55513. +#else
  55514. + svpdev = platform_device_register_data(ctrldev, "caam_secvio", 0,
  55515. + svpriv,
  55516. + sizeof(struct caam_drv_private_secvio));
  55517. +
  55518. + secvio_inten_src = HP_SECVIO_INTEN_ALL;
  55519. +#endif
  55520. + if (svpdev == NULL) {
  55521. + kfree(svpriv);
  55522. + return -EINVAL;
  55523. + }
  55524. + svdev = &svpdev->dev;
  55525. + dev_set_drvdata(svdev, svpriv);
  55526. + ctrlpriv->secviodev = svdev;
  55527. + svpriv->svregs = ctrlpriv->snvs;
  55528. +
  55529. + /*
  55530. + * Now we have all the dev data set up. Init interrupt
  55531. + * source descriptions
  55532. + */
  55533. + for (i = 0; i < MAX_SECVIO_SOURCES; i++) {
  55534. + svpriv->intsrc[i].intname = violation_src_name[i];
  55535. + svpriv->intsrc[i].handler = caam_secvio_default;
  55536. + }
  55537. +
  55538. + /* Connect main handler */
  55539. + for_each_possible_cpu(i)
  55540. + tasklet_init(&svpriv->irqtask[i], caam_secvio_dispatch,
  55541. + (unsigned long)svdev);
  55542. +
  55543. + error = request_irq(ctrlpriv->secvio_irq, caam_secvio_interrupt,
  55544. + IRQF_SHARED, "caam_secvio", svdev);
  55545. + if (error) {
  55546. + dev_err(svdev, "can't connect secvio interrupt\n");
  55547. + irq_dispose_mapping(ctrlpriv->secvio_irq);
  55548. + ctrlpriv->secvio_irq = 0;
  55549. + return -EINVAL;
  55550. + }
  55551. +
  55552. + /* Enable all sources */
  55553. + wr_reg32(&svpriv->svregs->hp.secvio_int_ctl, secvio_inten_src);
  55554. +
  55555. + dev_info(svdev, "security violation service handlers armed\n");
  55556. +
  55557. + return 0;
  55558. +}
  55559. +
  55560. +void caam_secvio_shutdown(struct platform_device *pdev)
  55561. +{
  55562. + struct device *ctrldev, *svdev;
  55563. + struct caam_drv_private *priv;
  55564. + struct caam_drv_private_secvio *svpriv;
  55565. + int i;
  55566. +
  55567. + ctrldev = &pdev->dev;
  55568. + priv = dev_get_drvdata(ctrldev);
  55569. + svdev = priv->secviodev;
  55570. + svpriv = dev_get_drvdata(svdev);
  55571. +
  55572. + /* Shut off all sources */
  55573. +
  55574. + wr_reg32(&svpriv->svregs->hp.secvio_int_ctl, 0);
  55575. +
  55576. + /* Remove tasklets and release interrupt */
  55577. + for_each_possible_cpu(i)
  55578. + tasklet_kill(&svpriv->irqtask[i]);
  55579. +
  55580. + free_irq(priv->secvio_irq, svdev);
  55581. +
  55582. + kfree(svpriv);
  55583. +}
  55584. +
  55585. +
  55586. +#ifdef CONFIG_OF
  55587. +static void __exit caam_secvio_exit(void)
  55588. +{
  55589. + struct device_node *dev_node;
  55590. + struct platform_device *pdev;
  55591. +
  55592. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  55593. + if (!dev_node) {
  55594. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  55595. + if (!dev_node)
  55596. + return;
  55597. + }
  55598. +
  55599. + pdev = of_find_device_by_node(dev_node);
  55600. + if (!pdev)
  55601. + return;
  55602. +
  55603. + of_node_get(dev_node);
  55604. +
  55605. + caam_secvio_shutdown(pdev);
  55606. +
  55607. +}
  55608. +
  55609. +static int __init caam_secvio_init(void)
  55610. +{
  55611. + struct device_node *dev_node;
  55612. + struct platform_device *pdev;
  55613. +
  55614. + /*
  55615. + * Do of_find_compatible_node() then of_find_device_by_node()
  55616. + * once a functional device tree is available
  55617. + */
  55618. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  55619. + if (!dev_node) {
  55620. + dev_node = of_find_compatible_node(NULL, NULL,
  55621. + "arm,imx6-caam-secvio");
  55622. + if (!dev_node)
  55623. + return -ENODEV;
  55624. + }
  55625. +
  55626. + pdev = of_find_device_by_node(dev_node);
  55627. + if (!pdev)
  55628. + return -ENODEV;
  55629. +
  55630. + of_node_put(dev_node);
  55631. +
  55632. + return caam_secvio_startup(pdev);
  55633. +}
  55634. +
  55635. +module_init(caam_secvio_init);
  55636. +module_exit(caam_secvio_exit);
  55637. +
  55638. +MODULE_LICENSE("Dual BSD/GPL");
  55639. +MODULE_DESCRIPTION("FSL CAAM/SNVS Security Violation Handler");
  55640. +MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
  55641. +#endif
  55642. diff -Nur linux-3.14.15/drivers/crypto/caam/secvio.h linux-linaro-stable-mx6/drivers/crypto/caam/secvio.h
  55643. --- linux-3.14.15/drivers/crypto/caam/secvio.h 1970-01-01 01:00:00.000000000 +0100
  55644. +++ linux-linaro-stable-mx6/drivers/crypto/caam/secvio.h 2014-08-20 19:23:50.790834021 +0200
  55645. @@ -0,0 +1,64 @@
  55646. +
  55647. +/*
  55648. + * CAAM Security Violation Handler
  55649. + * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
  55650. + */
  55651. +
  55652. +#ifndef SECVIO_H
  55653. +#define SECVIO_H
  55654. +
  55655. +#include "snvsregs.h"
  55656. +
  55657. +
  55658. +/*
  55659. + * Defines the published interfaces to install/remove application-specified
  55660. + * handlers for catching violations
  55661. + */
  55662. +
  55663. +#define MAX_SECVIO_SOURCES 6
  55664. +
  55665. +/* these are the untranslated causes */
  55666. +enum secvio_cause {
  55667. + SECVIO_CAUSE_SOURCE_0,
  55668. + SECVIO_CAUSE_SOURCE_1,
  55669. + SECVIO_CAUSE_SOURCE_2,
  55670. + SECVIO_CAUSE_SOURCE_3,
  55671. + SECVIO_CAUSE_SOURCE_4,
  55672. + SECVIO_CAUSE_SOURCE_5
  55673. +};
  55674. +
  55675. +/* These are common "recommended" cause definitions for most devices */
  55676. +#define SECVIO_CAUSE_CAAM_VIOLATION SECVIO_CAUSE_SOURCE_0
  55677. +#define SECVIO_CAUSE JTAG_ALARM SECVIO_CAUSE_SOURCE_1
  55678. +#define SECVIO_CAUSE_WATCHDOG SECVIO_CAUSE_SOURCE_2
  55679. +#define SECVIO_CAUSE_EXTERNAL_BOOT SECVIO_CAUSE_SOURCE_4
  55680. +#define SECVIO_CAUSE_TAMPER_DETECT SECVIO_CAUSE_SOURCE_5
  55681. +
  55682. +int caam_secvio_install_handler(struct device *dev, enum secvio_cause cause,
  55683. + void (*handler)(struct device *dev, u32 cause,
  55684. + void *ext),
  55685. + u8 *cause_description, void *ext);
  55686. +int caam_secvio_remove_handler(struct device *dev, enum secvio_cause cause);
  55687. +
  55688. +/*
  55689. + * Private data definitions for the secvio "driver"
  55690. + */
  55691. +
  55692. +struct secvio_int_src {
  55693. + const u8 *intname; /* Points to a descriptive name for source */
  55694. + void *ext; /* Extended data to pass to the handler */
  55695. + void (*handler)(struct device *dev, u32 cause, void *ext);
  55696. +};
  55697. +
  55698. +struct caam_drv_private_secvio {
  55699. + struct device *parentdev; /* points back to the controller */
  55700. + spinlock_t svlock ____cacheline_aligned;
  55701. + struct tasklet_struct irqtask[NR_CPUS];
  55702. + struct snvs_full __iomem *svregs; /* both HP and LP domains */
  55703. +
  55704. + /* Registered handlers for each violation */
  55705. + struct secvio_int_src intsrc[MAX_SECVIO_SOURCES];
  55706. +
  55707. +};
  55708. +
  55709. +#endif /* SECVIO_H */
  55710. diff -Nur linux-3.14.15/drivers/crypto/caam/sm.h linux-linaro-stable-mx6/drivers/crypto/caam/sm.h
  55711. --- linux-3.14.15/drivers/crypto/caam/sm.h 1970-01-01 01:00:00.000000000 +0100
  55712. +++ linux-linaro-stable-mx6/drivers/crypto/caam/sm.h 2014-08-20 19:23:50.790834021 +0200
  55713. @@ -0,0 +1,88 @@
  55714. +
  55715. +/*
  55716. + * CAAM Secure Memory/Keywrap API Definitions
  55717. + * Copyright (C) 2008-2013 Freescale Semiconductor, Inc.
  55718. + */
  55719. +
  55720. +#ifndef SM_H
  55721. +#define SM_H
  55722. +
  55723. +
  55724. +/* Storage access permissions */
  55725. +#define SM_PERM_READ 0x01
  55726. +#define SM_PERM_WRITE 0x02
  55727. +#define SM_PERM_BLOB 0x03
  55728. +
  55729. +
  55730. +/* Keystore maintenance functions */
  55731. +void sm_init_keystore(struct device *dev);
  55732. +u32 sm_detect_keystore_units(struct device *dev);
  55733. +int sm_establish_keystore(struct device *dev, u32 unit);
  55734. +void sm_release_keystore(struct device *dev, u32 unit);
  55735. +void caam_sm_shutdown(struct platform_device *pdev);
  55736. +int caam_sm_example_init(struct platform_device *pdev);
  55737. +
  55738. +/* Keystore accessor functions */
  55739. +extern int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size,
  55740. + u32 *slot);
  55741. +extern int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot);
  55742. +extern int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
  55743. + const u8 *key_data, u32 key_length);
  55744. +extern int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
  55745. + u32 key_length, u8 *key_data);
  55746. +extern int sm_keystore_slot_encapsulate(struct device *dev, u32 unit,
  55747. + u32 inslot, u32 outslot, u16 secretlen,
  55748. + u8 *keymod, u16 keymodlen);
  55749. +extern int sm_keystore_slot_decapsulate(struct device *dev, u32 unit,
  55750. + u32 inslot, u32 outslot, u16 secretlen,
  55751. + u8 *keymod, u16 keymodlen);
  55752. +
  55753. +/* Data structure to hold per-slot information */
  55754. +struct keystore_data_slot_info {
  55755. + u8 allocated; /* Track slot assignments */
  55756. + u32 key_length; /* Size of the key */
  55757. +};
  55758. +
  55759. +/* Data structure to hold keystore information */
  55760. +struct keystore_data {
  55761. + void *base_address; /* Base of the Secure Partition */
  55762. + u32 slot_count; /* Number of slots in the keystore */
  55763. + struct keystore_data_slot_info *slot; /* Per-slot information */
  55764. +};
  55765. +
  55766. +/* store the detected attributes of a secure memory page */
  55767. +struct sm_page_descriptor {
  55768. + u16 phys_pagenum; /* may be discontiguous */
  55769. + u16 own_part; /* Owning partition */
  55770. + void *pg_base; /* Calculated virtual address */
  55771. + struct keystore_data *ksdata;
  55772. +};
  55773. +
  55774. +struct caam_drv_private_sm {
  55775. + struct device *parentdev; /* this ends up as the controller */
  55776. + struct device *smringdev; /* ring that owns this instance */
  55777. + spinlock_t kslock ____cacheline_aligned;
  55778. +
  55779. + /* Default parameters for geometry */
  55780. + u32 max_pages; /* maximum pages this instance can support */
  55781. + u32 top_partition; /* highest partition number in this instance */
  55782. + u32 top_page; /* highest page number in this instance */
  55783. + u32 page_size; /* page size */
  55784. + u32 slot_size; /* selected size of each storage block */
  55785. +
  55786. + /* Partition/Page Allocation Map */
  55787. + u32 localpages; /* Number of pages we can access */
  55788. + struct sm_page_descriptor *pagedesc; /* Allocated per-page */
  55789. +
  55790. + /* Installed handlers for keystore access */
  55791. + int (*data_init)(struct device *dev, u32 unit);
  55792. + void (*data_cleanup)(struct device *dev, u32 unit);
  55793. + int (*slot_alloc)(struct device *dev, u32 unit, u32 size, u32 *slot);
  55794. + int (*slot_dealloc)(struct device *dev, u32 unit, u32 slot);
  55795. + void *(*slot_get_address)(struct device *dev, u32 unit, u32 handle);
  55796. + u32 (*slot_get_base)(struct device *dev, u32 unit, u32 handle);
  55797. + u32 (*slot_get_offset)(struct device *dev, u32 unit, u32 handle);
  55798. + u32 (*slot_get_slot_size)(struct device *dev, u32 unit, u32 handle);
  55799. +};
  55800. +
  55801. +#endif /* SM_H */
  55802. diff -Nur linux-3.14.15/drivers/crypto/caam/sm_store.c linux-linaro-stable-mx6/drivers/crypto/caam/sm_store.c
  55803. --- linux-3.14.15/drivers/crypto/caam/sm_store.c 1970-01-01 01:00:00.000000000 +0100
  55804. +++ linux-linaro-stable-mx6/drivers/crypto/caam/sm_store.c 2014-08-20 19:23:50.790834021 +0200
  55805. @@ -0,0 +1,896 @@
  55806. +
  55807. +/*
  55808. + * CAAM Secure Memory Storage Interface
  55809. + * Copyright (C) 2008-2013 Freescale Semiconductor, Inc.
  55810. + *
  55811. + * Loosely based on the SHW Keystore API for SCC/SCC2
  55812. + * Experimental implementation and NOT intended for upstream use. Expect
  55813. + * this interface to be amended significantly in the future once it becomes
  55814. + * integrated into live applications.
  55815. + *
  55816. + * Known issues:
  55817. + *
  55818. + * - Executes one instance of an secure memory "driver". This is tied to the
  55819. + * fact that job rings can't run as standalone instances in the present
  55820. + * configuration.
  55821. + *
  55822. + * - It does not expose a userspace interface. The value of a userspace
  55823. + * interface for access to secrets is a point for further architectural
  55824. + * discussion.
  55825. + *
  55826. + * - Partition/permission management is not part of this interface. It
  55827. + * depends on some level of "knowledge" agreed upon between bootloader,
  55828. + * provisioning applications, and OS-hosted software (which uses this
  55829. + * driver).
  55830. + *
  55831. + * - No means of identifying the location or purpose of secrets managed by
  55832. + * this interface exists; "slot location" and format of a given secret
  55833. + * needs to be agreed upon between bootloader, provisioner, and OS-hosted
  55834. + * application.
  55835. + */
  55836. +
  55837. +#include "compat.h"
  55838. +#include "regs.h"
  55839. +#include "jr.h"
  55840. +#include "desc.h"
  55841. +#include "intern.h"
  55842. +#include "error.h"
  55843. +#include "sm.h"
  55844. +
  55845. +#ifdef SM_DEBUG_CONT
  55846. +void sm_show_page(struct device *dev, struct sm_page_descriptor *pgdesc)
  55847. +{
  55848. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  55849. + u32 i, *smdata;
  55850. +
  55851. + dev_info(dev, "physical page %d content at 0x%08x\n",
  55852. + pgdesc->phys_pagenum, pgdesc->pg_base);
  55853. + smdata = pgdesc->pg_base;
  55854. + for (i = 0; i < (smpriv->page_size / sizeof(u32)); i += 4)
  55855. + dev_info(dev, "[0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n",
  55856. + (u32)&smdata[i], smdata[i], smdata[i+1], smdata[i+2],
  55857. + smdata[i+3]);
  55858. +}
  55859. +#endif
  55860. +
  55861. +/*
  55862. + * Construct a secure memory blob encapsulation job descriptor
  55863. + *
  55864. + * - desc pointer to hold new (to be allocated) pointer to the generated
  55865. + * descriptor for later use. Calling thread can kfree the
  55866. + * descriptor after execution.
  55867. + * - keymod Physical pointer to key modifier (contiguous piece).
  55868. + * - keymodsz Size of key modifier in bytes (should normally be 8).
  55869. + * - secretbuf Physical pointer (within an accessible secure memory page)
  55870. + * of the secret to be encapsulated.
  55871. + * - outbuf Physical pointer (within an accessible secure memory page)
  55872. + * of the encapsulated output. This will be larger than the
  55873. + * input secret because of the added encapsulation data.
  55874. + * - secretsz Size of input secret, in bytes.
  55875. + * - auth If nonzero, use AES-CCM for encapsulation, else use ECB
  55876. + *
  55877. + * Note: this uses 32-bit pointers at present
  55878. + */
  55879. +#define INITIAL_DESCSZ 16 /* size of tmp buffer for descriptor const. */
  55880. +static int blob_encap_desc(u32 **desc, dma_addr_t keymod, u16 keymodsz,
  55881. + dma_addr_t secretbuf, dma_addr_t outbuf,
  55882. + u16 secretsz, bool auth)
  55883. +{
  55884. + u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
  55885. + u16 dsize, idx;
  55886. +
  55887. + memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
  55888. + idx = 1;
  55889. +
  55890. + /* Load key modifier */
  55891. + tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY |
  55892. + ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK) |
  55893. + (keymodsz & LDST_LEN_MASK);
  55894. +
  55895. + tmpdesc[idx++] = (u32)keymod;
  55896. +
  55897. + /* Encapsulate to secure memory */
  55898. + tmpdesc[idx++] = CMD_SEQ_IN_PTR | secretsz;
  55899. + tmpdesc[idx++] = (u32)secretbuf;
  55900. +
  55901. + /* Add space for BKEK and MAC tag */
  55902. + tmpdesc[idx++] = CMD_SEQ_IN_PTR | (secretsz + (32 + 16));
  55903. +
  55904. + tmpdesc[idx++] = (u32)outbuf;
  55905. + tmpdesc[idx] = CMD_OPERATION | OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB |
  55906. + OP_PCL_BLOB_PTXT_SECMEM;
  55907. + if (auth)
  55908. + tmpdesc[idx] |= OP_PCL_BLOB_EKT;
  55909. +
  55910. + idx++;
  55911. + tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
  55912. + dsize = idx * sizeof(u32);
  55913. +
  55914. + tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
  55915. + if (tdesc == NULL)
  55916. + return 0;
  55917. +
  55918. + memcpy(tdesc, tmpdesc, dsize);
  55919. + *desc = tdesc;
  55920. + return dsize;
  55921. +}
  55922. +
  55923. +/*
  55924. + * Construct a secure memory blob decapsulation job descriptor
  55925. + *
  55926. + * - desc pointer to hold new (to be allocated) pointer to the generated
  55927. + * descriptor for later use. Calling thread can kfree the
  55928. + * descriptor after execution.
  55929. + * - keymod Physical pointer to key modifier (contiguous piece).
  55930. + * - keymodsz Size of key modifier in bytes (should normally be 16).
  55931. + * - blobbuf Physical pointer (within an accessible secure memory page)
  55932. + * of the blob to be decapsulated.
  55933. + * - outbuf Physical pointer (within an accessible secure memory page)
  55934. + * of the decapsulated output.
  55935. + * - secretsz Size of input blob, in bytes.
  55936. + * - auth If nonzero, assume AES-CCM for decapsulation, else use ECB
  55937. + *
  55938. + * Note: this uses 32-bit pointers at present
  55939. + */
  55940. +static int blob_decap_desc(u32 **desc, dma_addr_t keymod, u16 keymodsz,
  55941. + dma_addr_t blobbuf, dma_addr_t outbuf,
  55942. + u16 blobsz, bool auth)
  55943. +{
  55944. + u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
  55945. + u16 dsize, idx;
  55946. +
  55947. + memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
  55948. + idx = 1;
  55949. +
  55950. + /* Load key modifier */
  55951. + tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY |
  55952. + ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK) |
  55953. + (keymodsz & LDST_LEN_MASK);
  55954. +
  55955. + tmpdesc[idx++] = (u32)keymod;
  55956. +
  55957. + /* Compensate BKEK + MAC tag */
  55958. + tmpdesc[idx++] = CMD_SEQ_IN_PTR | (blobsz + 32 + 16);
  55959. +
  55960. + tmpdesc[idx++] = (u32)blobbuf;
  55961. + tmpdesc[idx++] = CMD_SEQ_OUT_PTR | blobsz;
  55962. + tmpdesc[idx++] = (u32)outbuf;
  55963. +
  55964. + /* Decapsulate from secure memory partition to black blob */
  55965. + tmpdesc[idx] = CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB |
  55966. + OP_PCL_BLOB_PTXT_SECMEM | OP_PCL_BLOB_BLACK;
  55967. + if (auth)
  55968. + tmpdesc[idx] |= OP_PCL_BLOB_EKT;
  55969. +
  55970. + idx++;
  55971. + tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
  55972. + dsize = idx * sizeof(u32);
  55973. +
  55974. + tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
  55975. + if (tdesc == NULL)
  55976. + return 0;
  55977. +
  55978. + memcpy(tdesc, tmpdesc, dsize);
  55979. + *desc = tdesc;
  55980. + return dsize;
  55981. +}
  55982. +
  55983. +/*
  55984. + * Pseudo-synchronous ring access functions for carrying out key
  55985. + * encapsulation and decapsulation
  55986. + */
  55987. +
  55988. +struct sm_key_job_result {
  55989. + int error;
  55990. + struct completion completion;
  55991. +};
  55992. +
  55993. +void sm_key_job_done(struct device *dev, u32 *desc, u32 err, void *context)
  55994. +{
  55995. + struct sm_key_job_result *res = context;
  55996. +
  55997. + res->error = err; /* save off the error for postprocessing */
  55998. + complete(&res->completion); /* mark us complete */
  55999. +}
  56000. +
  56001. +static int sm_key_job(struct device *ksdev, u32 *jobdesc)
  56002. +{
  56003. + struct sm_key_job_result testres;
  56004. + struct caam_drv_private_sm *kspriv;
  56005. + int rtn = 0;
  56006. +
  56007. + kspriv = dev_get_drvdata(ksdev);
  56008. +
  56009. + init_completion(&testres.completion);
  56010. +
  56011. + rtn = caam_jr_enqueue(kspriv->smringdev, jobdesc, sm_key_job_done,
  56012. + &testres);
  56013. + if (!rtn) {
  56014. + wait_for_completion_interruptible(&testres.completion);
  56015. + rtn = testres.error;
  56016. + }
  56017. + return rtn;
  56018. +}
  56019. +
  56020. +/*
  56021. + * Following section establishes the default methods for keystore access
  56022. + * They are NOT intended for use external to this module
  56023. + *
  56024. + * In the present version, these are the only means for the higher-level
  56025. + * interface to deal with the mechanics of accessing the phyiscal keystore
  56026. + */
  56027. +
  56028. +
  56029. +int slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot)
  56030. +{
  56031. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56032. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  56033. + u32 i;
  56034. +#ifdef SM_DEBUG
  56035. + dev_info(dev, "slot_alloc(): requesting slot for %d bytes\n", size);
  56036. +#endif
  56037. +
  56038. + if (size > smpriv->slot_size)
  56039. + return -EKEYREJECTED;
  56040. +
  56041. + for (i = 0; i < ksdata->slot_count; i++) {
  56042. + if (ksdata->slot[i].allocated == 0) {
  56043. + ksdata->slot[i].allocated = 1;
  56044. + (*slot) = i;
  56045. +#ifdef SM_DEBUG
  56046. + dev_info(dev, "slot_alloc(): new slot %d allocated\n",
  56047. + *slot);
  56048. +#endif
  56049. + return 0;
  56050. + }
  56051. + }
  56052. +
  56053. + return -ENOSPC;
  56054. +}
  56055. +EXPORT_SYMBOL(slot_alloc);
  56056. +
  56057. +int slot_dealloc(struct device *dev, u32 unit, u32 slot)
  56058. +{
  56059. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56060. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  56061. + u8 __iomem *slotdata;
  56062. +
  56063. +#ifdef SM_DEBUG
  56064. + dev_info(dev, "slot_dealloc(): releasing slot %d\n", slot);
  56065. +#endif
  56066. + if (slot >= ksdata->slot_count)
  56067. + return -EINVAL;
  56068. + slotdata = ksdata->base_address + slot * smpriv->slot_size;
  56069. +
  56070. + if (ksdata->slot[slot].allocated == 1) {
  56071. + /* Forcibly overwrite the data from the keystore */
  56072. + memset(ksdata->base_address + slot * smpriv->slot_size, 0,
  56073. + smpriv->slot_size);
  56074. +
  56075. + ksdata->slot[slot].allocated = 0;
  56076. +#ifdef SM_DEBUG
  56077. + dev_info(dev, "slot_dealloc(): slot %d released\n", slot);
  56078. +#endif
  56079. + return 0;
  56080. + }
  56081. +
  56082. + return -EINVAL;
  56083. +}
  56084. +EXPORT_SYMBOL(slot_dealloc);
  56085. +
  56086. +void *slot_get_address(struct device *dev, u32 unit, u32 slot)
  56087. +{
  56088. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56089. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  56090. +
  56091. + if (slot >= ksdata->slot_count)
  56092. + return NULL;
  56093. +
  56094. +#ifdef SM_DEBUG
  56095. + dev_info(dev, "slot_get_address(): slot %d is 0x%08x\n", slot,
  56096. + (u32)ksdata->base_address + slot * smpriv->slot_size);
  56097. +#endif
  56098. +
  56099. + return ksdata->base_address + slot * smpriv->slot_size;
  56100. +}
  56101. +
  56102. +u32 slot_get_base(struct device *dev, u32 unit, u32 slot)
  56103. +{
  56104. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56105. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  56106. +
  56107. + /*
  56108. + * There could potentially be more than one secure partition object
  56109. + * associated with this keystore. For now, there is just one.
  56110. + */
  56111. +
  56112. + (void)slot;
  56113. +
  56114. +#ifdef SM_DEBUG
  56115. + dev_info(dev, "slot_get_base(): slot %d = 0x%08x\n",
  56116. + slot, (u32)ksdata->base_address);
  56117. +#endif
  56118. +
  56119. + return (u32)(ksdata->base_address);
  56120. +}
  56121. +
  56122. +u32 slot_get_offset(struct device *dev, u32 unit, u32 slot)
  56123. +{
  56124. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56125. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  56126. +
  56127. + if (slot >= ksdata->slot_count)
  56128. + return -EINVAL;
  56129. +
  56130. +#ifdef SM_DEBUG
  56131. + dev_info(dev, "slot_get_offset(): slot %d = %d\n", slot,
  56132. + slot * smpriv->slot_size);
  56133. +#endif
  56134. +
  56135. + return slot * smpriv->slot_size;
  56136. +}
  56137. +
  56138. +u32 slot_get_slot_size(struct device *dev, u32 unit, u32 slot)
  56139. +{
  56140. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56141. +
  56142. +
  56143. +#ifdef SM_DEBUG
  56144. + dev_info(dev, "slot_get_slot_size(): slot %d = %d\n", slot,
  56145. + smpriv->slot_size);
  56146. +#endif
  56147. + /* All slots are the same size in the default implementation */
  56148. + return smpriv->slot_size;
  56149. +}
  56150. +
  56151. +
  56152. +
  56153. +int kso_init_data(struct device *dev, u32 unit)
  56154. +{
  56155. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56156. + int retval = -EINVAL;
  56157. + struct keystore_data *keystore_data = NULL;
  56158. + u32 slot_count;
  56159. + u32 keystore_data_size;
  56160. +
  56161. + /*
  56162. + * Calculate the required size of the keystore data structure, based
  56163. + * on the number of keys that can fit in the partition.
  56164. + */
  56165. + slot_count = smpriv->page_size / smpriv->slot_size;
  56166. +#ifdef SM_DEBUG
  56167. + dev_info(dev, "kso_init_data: %d slots initializing\n", slot_count);
  56168. +#endif
  56169. +
  56170. + keystore_data_size = sizeof(struct keystore_data) +
  56171. + slot_count *
  56172. + sizeof(struct keystore_data_slot_info);
  56173. +
  56174. + keystore_data = kzalloc(keystore_data_size, GFP_KERNEL);
  56175. +
  56176. + if (keystore_data == NULL) {
  56177. + retval = -ENOSPC;
  56178. + goto out;
  56179. + }
  56180. +
  56181. +#ifdef SM_DEBUG
  56182. + dev_info(dev, "kso_init_data: keystore data size = %d\n",
  56183. + keystore_data_size);
  56184. +#endif
  56185. +
  56186. + /*
  56187. + * Place the slot information structure directly after the keystore data
  56188. + * structure.
  56189. + */
  56190. + keystore_data->slot = (struct keystore_data_slot_info *)
  56191. + (keystore_data + 1);
  56192. + keystore_data->slot_count = slot_count;
  56193. +
  56194. + smpriv->pagedesc[unit].ksdata = keystore_data;
  56195. + smpriv->pagedesc[unit].ksdata->base_address =
  56196. + smpriv->pagedesc[unit].pg_base;
  56197. +
  56198. + retval = 0;
  56199. +
  56200. +out:
  56201. + if (retval != 0)
  56202. + if (keystore_data != NULL)
  56203. + kfree(keystore_data);
  56204. +
  56205. +
  56206. + return retval;
  56207. +}
  56208. +
  56209. +void kso_cleanup_data(struct device *dev, u32 unit)
  56210. +{
  56211. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56212. + struct keystore_data *keystore_data = NULL;
  56213. +
  56214. + if (smpriv->pagedesc[unit].ksdata != NULL)
  56215. + keystore_data = smpriv->pagedesc[unit].ksdata;
  56216. +
  56217. + /* Release the allocated keystore management data */
  56218. + kfree(smpriv->pagedesc[unit].ksdata);
  56219. +
  56220. + return;
  56221. +}
  56222. +
  56223. +
  56224. +
  56225. +/*
  56226. + * Keystore management section
  56227. + */
  56228. +
  56229. +void sm_init_keystore(struct device *dev)
  56230. +{
  56231. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56232. +
  56233. + smpriv->data_init = kso_init_data;
  56234. + smpriv->data_cleanup = kso_cleanup_data;
  56235. + smpriv->slot_alloc = slot_alloc;
  56236. + smpriv->slot_dealloc = slot_dealloc;
  56237. + smpriv->slot_get_address = slot_get_address;
  56238. + smpriv->slot_get_base = slot_get_base;
  56239. + smpriv->slot_get_offset = slot_get_offset;
  56240. + smpriv->slot_get_slot_size = slot_get_slot_size;
  56241. +#ifdef SM_DEBUG
  56242. + dev_info(dev, "sm_init_keystore(): handlers installed\n");
  56243. +#endif
  56244. +}
  56245. +EXPORT_SYMBOL(sm_init_keystore);
  56246. +
  56247. +/* Return available pages/units */
  56248. +u32 sm_detect_keystore_units(struct device *dev)
  56249. +{
  56250. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56251. +
  56252. + return smpriv->localpages;
  56253. +}
  56254. +EXPORT_SYMBOL(sm_detect_keystore_units);
  56255. +
  56256. +/*
  56257. + * Do any keystore specific initializations
  56258. + */
  56259. +int sm_establish_keystore(struct device *dev, u32 unit)
  56260. +{
  56261. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56262. +
  56263. +#ifdef SM_DEBUG
  56264. + dev_info(dev, "sm_establish_keystore(): unit %d initializing\n", unit);
  56265. +#endif
  56266. +
  56267. + if (smpriv->data_init == NULL)
  56268. + return -EINVAL;
  56269. +
  56270. + /* Call the data_init function for any user setup */
  56271. + return smpriv->data_init(dev, unit);
  56272. +}
  56273. +EXPORT_SYMBOL(sm_establish_keystore);
  56274. +
  56275. +void sm_release_keystore(struct device *dev, u32 unit)
  56276. +{
  56277. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56278. +
  56279. +#ifdef SM_DEBUG
  56280. + dev_info(dev, "sm_establish_keystore(): unit %d releasing\n", unit);
  56281. +#endif
  56282. + if ((smpriv != NULL) && (smpriv->data_cleanup != NULL))
  56283. + smpriv->data_cleanup(dev, unit);
  56284. +
  56285. + return;
  56286. +}
  56287. +EXPORT_SYMBOL(sm_release_keystore);
  56288. +
  56289. +/*
  56290. + * Subsequent interfacce (sm_keystore_*) forms the accessor interfacce to
  56291. + * the keystore
  56292. + */
  56293. +int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot)
  56294. +{
  56295. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56296. + int retval = -EINVAL;
  56297. +
  56298. + spin_lock(&smpriv->kslock);
  56299. +
  56300. + if ((smpriv->slot_alloc == NULL) ||
  56301. + (smpriv->pagedesc[unit].ksdata == NULL))
  56302. + goto out;
  56303. +
  56304. + retval = smpriv->slot_alloc(dev, unit, size, slot);
  56305. +
  56306. +out:
  56307. + spin_unlock(&smpriv->kslock);
  56308. + return retval;
  56309. +}
  56310. +EXPORT_SYMBOL(sm_keystore_slot_alloc);
  56311. +
  56312. +int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot)
  56313. +{
  56314. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56315. + int retval = -EINVAL;
  56316. +
  56317. + spin_lock(&smpriv->kslock);
  56318. +
  56319. + if ((smpriv->slot_alloc == NULL) ||
  56320. + (smpriv->pagedesc[unit].ksdata == NULL))
  56321. + goto out;
  56322. +
  56323. + retval = smpriv->slot_dealloc(dev, unit, slot);
  56324. +out:
  56325. + spin_unlock(&smpriv->kslock);
  56326. + return retval;
  56327. +}
  56328. +EXPORT_SYMBOL(sm_keystore_slot_dealloc);
  56329. +
  56330. +int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
  56331. + const u8 *key_data, u32 key_length)
  56332. +{
  56333. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56334. + int retval = -EINVAL;
  56335. + u32 slot_size;
  56336. + u32 i;
  56337. + u8 __iomem *slot_location;
  56338. +
  56339. + spin_lock(&smpriv->kslock);
  56340. +
  56341. + slot_size = smpriv->slot_get_slot_size(dev, unit, slot);
  56342. +
  56343. + if (key_length > slot_size) {
  56344. + retval = -EFBIG;
  56345. + goto out;
  56346. + }
  56347. +
  56348. + slot_location = smpriv->slot_get_address(dev, unit, slot);
  56349. +
  56350. + for (i = 0; i < key_length; i++)
  56351. + slot_location[i] = key_data[i];
  56352. +
  56353. + retval = 0;
  56354. +
  56355. +out:
  56356. + spin_unlock(&smpriv->kslock);
  56357. + return retval;
  56358. +}
  56359. +EXPORT_SYMBOL(sm_keystore_slot_load);
  56360. +
  56361. +int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
  56362. + u32 key_length, u8 *key_data)
  56363. +{
  56364. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56365. + int retval = -EINVAL;
  56366. + u8 __iomem *slot_addr;
  56367. + u32 slot_size;
  56368. +
  56369. + spin_lock(&smpriv->kslock);
  56370. +
  56371. + slot_addr = smpriv->slot_get_address(dev, unit, slot);
  56372. + slot_size = smpriv->slot_get_slot_size(dev, unit, slot);
  56373. +
  56374. + if (key_length > slot_size) {
  56375. + retval = -EKEYREJECTED;
  56376. + goto out;
  56377. + }
  56378. +
  56379. + memcpy(key_data, slot_addr, key_length);
  56380. + retval = 0;
  56381. +
  56382. +out:
  56383. + spin_unlock(&smpriv->kslock);
  56384. + return retval;
  56385. +}
  56386. +EXPORT_SYMBOL(sm_keystore_slot_read);
  56387. +
  56388. +int sm_keystore_slot_encapsulate(struct device *dev, u32 unit, u32 inslot,
  56389. + u32 outslot, u16 secretlen, u8 *keymod,
  56390. + u16 keymodlen)
  56391. +{
  56392. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56393. + int retval = 0;
  56394. + u32 slot_length, dsize, jstat;
  56395. + u32 __iomem *encapdesc = NULL;
  56396. + u8 __iomem *lkeymod, *inpslotaddr, *outslotaddr;
  56397. + dma_addr_t keymod_dma;
  56398. +
  56399. + /* Ensure that the full blob will fit in the key slot */
  56400. + slot_length = smpriv->slot_get_slot_size(dev, unit, outslot);
  56401. + if ((secretlen + 48) > slot_length)
  56402. + goto out;
  56403. +
  56404. + /* Get the base addresses of both keystore slots */
  56405. + inpslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, inslot);
  56406. + outslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, outslot);
  56407. +
  56408. + /* Build the key modifier */
  56409. + lkeymod = kmalloc(keymodlen, GFP_KERNEL | GFP_DMA);
  56410. + memcpy(lkeymod, keymod, keymodlen);
  56411. + keymod_dma = dma_map_single(dev, lkeymod, keymodlen, DMA_TO_DEVICE);
  56412. + dma_sync_single_for_device(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  56413. +
  56414. + /* Build the encapsulation job descriptor */
  56415. + dsize = blob_encap_desc(&encapdesc, keymod_dma, keymodlen,
  56416. + __pa(inpslotaddr), __pa(outslotaddr),
  56417. + secretlen, 0);
  56418. + if (!dsize) {
  56419. + dev_err(dev, "can't alloc an encap descriptor\n");
  56420. + retval = -ENOMEM;
  56421. + goto out;
  56422. + }
  56423. + jstat = sm_key_job(dev, encapdesc);
  56424. +
  56425. + dma_unmap_single(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  56426. + kfree(encapdesc);
  56427. +
  56428. +out:
  56429. + return retval;
  56430. +
  56431. +}
  56432. +EXPORT_SYMBOL(sm_keystore_slot_encapsulate);
  56433. +
  56434. +int sm_keystore_slot_decapsulate(struct device *dev, u32 unit, u32 inslot,
  56435. + u32 outslot, u16 secretlen, u8 *keymod,
  56436. + u16 keymodlen)
  56437. +{
  56438. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56439. + int retval = 0;
  56440. + u32 slot_length, dsize, jstat;
  56441. + u32 __iomem *decapdesc = NULL;
  56442. + u8 __iomem *lkeymod, *inpslotaddr, *outslotaddr;
  56443. + dma_addr_t keymod_dma;
  56444. +
  56445. + /* Ensure that the decap data will fit in the key slot */
  56446. + slot_length = smpriv->slot_get_slot_size(dev, unit, outslot);
  56447. + if (secretlen > slot_length)
  56448. + goto out;
  56449. +
  56450. + /* Get the base addresses of both keystore slots */
  56451. + inpslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, inslot);
  56452. + outslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, outslot);
  56453. +
  56454. + /* Build the key modifier */
  56455. + lkeymod = kmalloc(keymodlen, GFP_KERNEL | GFP_DMA);
  56456. + memcpy(lkeymod, keymod, keymodlen);
  56457. + keymod_dma = dma_map_single(dev, lkeymod, keymodlen, DMA_TO_DEVICE);
  56458. + dma_sync_single_for_device(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  56459. +
  56460. + /* Build the decapsulation job descriptor */
  56461. + dsize = blob_decap_desc(&decapdesc, keymod_dma, keymodlen,
  56462. + __pa(inpslotaddr), __pa(outslotaddr),
  56463. + secretlen, 0);
  56464. + if (!dsize) {
  56465. + dev_err(dev, "can't alloc a decap descriptor\n");
  56466. + retval = -ENOMEM;
  56467. + goto out;
  56468. + }
  56469. + jstat = sm_key_job(dev, decapdesc);
  56470. +
  56471. + dma_unmap_single(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  56472. + kfree(decapdesc);
  56473. +
  56474. +out:
  56475. + return retval;
  56476. +
  56477. +}
  56478. +EXPORT_SYMBOL(sm_keystore_slot_decapsulate);
  56479. +
  56480. +
  56481. +/*
  56482. + * Initialization/shutdown subsystem
  56483. + * Assumes statically-invoked startup/shutdown from the controller driver
  56484. + * for the present time, to be reworked when a device tree becomes
  56485. + * available. This code will not modularize in present form.
  56486. + *
  56487. + * Also, simply uses ring 0 for execution at the present
  56488. + */
  56489. +
  56490. +int caam_sm_startup(struct platform_device *pdev)
  56491. +{
  56492. + struct device *ctrldev, *smdev;
  56493. + struct caam_drv_private *ctrlpriv;
  56494. + struct caam_drv_private_sm *smpriv;
  56495. + struct caam_drv_private_jr *jrpriv; /* need this for reg page */
  56496. + struct platform_device *sm_pdev;
  56497. + struct sm_page_descriptor *lpagedesc;
  56498. + u32 page, pgstat, lpagect, detectedpage;
  56499. +
  56500. + struct device_node *np;
  56501. + ctrldev = &pdev->dev;
  56502. + ctrlpriv = dev_get_drvdata(ctrldev);
  56503. +
  56504. + /*
  56505. + * Set up the private block for secure memory
  56506. + * Only one instance is possible
  56507. + */
  56508. + smpriv = kzalloc(sizeof(struct caam_drv_private_sm), GFP_KERNEL);
  56509. + if (smpriv == NULL) {
  56510. + dev_err(ctrldev, "can't alloc private mem for secure memory\n");
  56511. + return -ENOMEM;
  56512. + }
  56513. + smpriv->parentdev = ctrldev; /* copy of parent dev is handy */
  56514. +
  56515. + /* Create the dev */
  56516. +#ifdef CONFIG_OF
  56517. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm");
  56518. + sm_pdev = of_platform_device_create(np, "caam_sm", ctrldev);
  56519. +#else
  56520. + sm_pdev = platform_device_register_data(ctrldev, "caam_sm", 0,
  56521. + smpriv,
  56522. + sizeof(struct caam_drv_private_sm));
  56523. +#endif
  56524. + if (sm_pdev == NULL) {
  56525. + kfree(smpriv);
  56526. + return -EINVAL;
  56527. + }
  56528. + smdev = &sm_pdev->dev;
  56529. + dev_set_drvdata(smdev, smpriv);
  56530. + ctrlpriv->smdev = smdev;
  56531. +
  56532. + /*
  56533. + * Collect configuration limit data for reference
  56534. + * This batch comes from the partition data/vid registers in perfmon
  56535. + */
  56536. + smpriv->max_pages = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
  56537. + & SMPART_MAX_NUMPG_MASK) >>
  56538. + SMPART_MAX_NUMPG_SHIFT) + 1;
  56539. + smpriv->top_partition = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
  56540. + & SMPART_MAX_PNUM_MASK) >>
  56541. + SMPART_MAX_PNUM_SHIFT) + 1;
  56542. + smpriv->top_page = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
  56543. + & SMPART_MAX_PG_MASK) >> SMPART_MAX_PG_SHIFT) + 1;
  56544. + smpriv->page_size = 1024 << ((rd_reg32(&ctrlpriv->ctrl->perfmon.smvid)
  56545. + & SMVID_PG_SIZE_MASK) >> SMVID_PG_SIZE_SHIFT);
  56546. + smpriv->slot_size = 1 << CONFIG_CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE;
  56547. +
  56548. +#ifdef SM_DEBUG
  56549. + dev_info(smdev, "max pages = %d, top partition = %d\n",
  56550. + smpriv->max_pages, smpriv->top_partition);
  56551. + dev_info(smdev, "top page = %d, page size = %d (total = %d)\n",
  56552. + smpriv->top_page, smpriv->page_size,
  56553. + smpriv->top_page * smpriv->page_size);
  56554. + dev_info(smdev, "selected slot size = %d\n", smpriv->slot_size);
  56555. +#endif
  56556. +
  56557. + /*
  56558. + * Now probe for partitions/pages to which we have access. Note that
  56559. + * these have likely been set up by a bootloader or platform
  56560. + * provisioning application, so we have to assume that we "inherit"
  56561. + * a configuration and work within the constraints of what it might be.
  56562. + *
  56563. + * Assume use of the zeroth ring in the present iteration (until
  56564. + * we can divorce the controller and ring drivers, and then assign
  56565. + * an SM instance to any ring instance).
  56566. + */
  56567. + smpriv->smringdev = ctrlpriv->jrdev[0];
  56568. + jrpriv = dev_get_drvdata(smpriv->smringdev);
  56569. + lpagect = 0;
  56570. + lpagedesc = kzalloc(sizeof(struct sm_page_descriptor)
  56571. + * smpriv->max_pages, GFP_KERNEL);
  56572. + if (lpagedesc == NULL) {
  56573. + kfree(smpriv);
  56574. + return -ENOMEM;
  56575. + }
  56576. +
  56577. + for (page = 0; page < smpriv->max_pages; page++) {
  56578. + wr_reg32(&jrpriv->rregs->sm_cmd,
  56579. + ((page << SMC_PAGE_SHIFT) & SMC_PAGE_MASK) |
  56580. + (SMC_CMD_PAGE_INQUIRY & SMC_CMD_MASK));
  56581. + pgstat = rd_reg32(&jrpriv->rregs->sm_status);
  56582. + if (((pgstat & SMCS_PGWON_MASK) >> SMCS_PGOWN_SHIFT)
  56583. + == SMCS_PGOWN_OWNED) { /* our page? */
  56584. + lpagedesc[page].phys_pagenum =
  56585. + (pgstat & SMCS_PAGE_MASK) >> SMCS_PAGE_SHIFT;
  56586. + lpagedesc[page].own_part =
  56587. + (pgstat & SMCS_PART_SHIFT) >> SMCS_PART_MASK;
  56588. + lpagedesc[page].pg_base = ctrlpriv->sm_base +
  56589. + ((smpriv->page_size * page) / sizeof(u32));
  56590. + lpagect++;
  56591. +#ifdef SM_DEBUG
  56592. + dev_info(smdev,
  56593. + "physical page %d, owning partition = %d\n",
  56594. + lpagedesc[page].phys_pagenum,
  56595. + lpagedesc[page].own_part);
  56596. +#endif
  56597. + }
  56598. + }
  56599. +
  56600. + smpriv->pagedesc = kzalloc(sizeof(struct sm_page_descriptor) * lpagect,
  56601. + GFP_KERNEL);
  56602. + if (smpriv->pagedesc == NULL) {
  56603. + kfree(lpagedesc);
  56604. + kfree(smpriv);
  56605. + return -ENOMEM;
  56606. + }
  56607. + smpriv->localpages = lpagect;
  56608. +
  56609. + detectedpage = 0;
  56610. + for (page = 0; page < smpriv->max_pages; page++) {
  56611. + if (lpagedesc[page].pg_base != NULL) { /* e.g. live entry */
  56612. + memcpy(&smpriv->pagedesc[detectedpage],
  56613. + &lpagedesc[page],
  56614. + sizeof(struct sm_page_descriptor));
  56615. +#ifdef SM_DEBUG_CONT
  56616. + sm_show_page(smdev, &smpriv->pagedesc[detectedpage]);
  56617. +#endif
  56618. + detectedpage++;
  56619. + }
  56620. + }
  56621. +
  56622. + kfree(lpagedesc);
  56623. +
  56624. + sm_init_keystore(smdev);
  56625. +
  56626. + return 0;
  56627. +}
  56628. +
  56629. +void caam_sm_shutdown(struct platform_device *pdev)
  56630. +{
  56631. + struct device *ctrldev, *smdev;
  56632. + struct caam_drv_private *priv;
  56633. + struct caam_drv_private_sm *smpriv;
  56634. +
  56635. + ctrldev = &pdev->dev;
  56636. + priv = dev_get_drvdata(ctrldev);
  56637. + smdev = priv->smdev;
  56638. + smpriv = dev_get_drvdata(smdev);
  56639. +
  56640. + kfree(smpriv->pagedesc);
  56641. + kfree(smpriv);
  56642. +}
  56643. +EXPORT_SYMBOL(caam_sm_shutdown);
  56644. +#ifdef CONFIG_OF
  56645. +static void __exit caam_sm_exit(void)
  56646. +{
  56647. + struct device_node *dev_node;
  56648. + struct platform_device *pdev;
  56649. +
  56650. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  56651. + if (!dev_node) {
  56652. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  56653. + if (!dev_node)
  56654. + return;
  56655. + }
  56656. +
  56657. + pdev = of_find_device_by_node(dev_node);
  56658. + if (!pdev)
  56659. + return;
  56660. +
  56661. + of_node_put(dev_node);
  56662. +
  56663. + caam_sm_shutdown(pdev);
  56664. +
  56665. + return;
  56666. +}
  56667. +
  56668. +static int __init caam_sm_init(void)
  56669. +{
  56670. + struct device_node *dev_node;
  56671. + struct platform_device *pdev;
  56672. +
  56673. + /*
  56674. + * Do of_find_compatible_node() then of_find_device_by_node()
  56675. + * once a functional device tree is available
  56676. + */
  56677. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  56678. + if (!dev_node) {
  56679. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  56680. + if (!dev_node)
  56681. + return -ENODEV;
  56682. + }
  56683. +
  56684. + pdev = of_find_device_by_node(dev_node);
  56685. + if (!pdev)
  56686. + return -ENODEV;
  56687. +
  56688. + of_node_get(dev_node);
  56689. +
  56690. + caam_sm_startup(pdev);
  56691. +
  56692. + return 0;
  56693. +}
  56694. +
  56695. +module_init(caam_sm_init);
  56696. +module_exit(caam_sm_exit);
  56697. +
  56698. +MODULE_LICENSE("Dual BSD/GPL");
  56699. +MODULE_DESCRIPTION("FSL CAAM Secure Memory / Keystore");
  56700. +MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
  56701. +#endif
  56702. diff -Nur linux-3.14.15/drivers/crypto/caam/sm_test.c linux-linaro-stable-mx6/drivers/crypto/caam/sm_test.c
  56703. --- linux-3.14.15/drivers/crypto/caam/sm_test.c 1970-01-01 01:00:00.000000000 +0100
  56704. +++ linux-linaro-stable-mx6/drivers/crypto/caam/sm_test.c 2014-08-20 19:23:50.790834021 +0200
  56705. @@ -0,0 +1,844 @@
  56706. +/*
  56707. + * Secure Memory / Keystore Exemplification Module
  56708. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  56709. + *
  56710. + * Serves as a functional example, and as a self-contained unit test for
  56711. + * the functionality contained in sm_store.c.
  56712. + *
  56713. + * The example function, caam_sm_example_init(), runs a thread that:
  56714. + *
  56715. + * - initializes a set of fixed keys
  56716. + * - stores one copy in clear buffers
  56717. + * - stores them again in secure memory
  56718. + * - extracts stored keys back out for use
  56719. + * - intializes 3 data buffers for a test:
  56720. + * (1) containing cleartext
  56721. + * (2) to hold ciphertext encrypted with an extracted black key
  56722. + * (3) to hold extracted cleartext decrypted with an equivalent clear key
  56723. + *
  56724. + * The function then builds simple job descriptors that reference the key
  56725. + * material and buffers as initialized, and executes an encryption job
  56726. + * with a black key, and a decryption job using a the same key held in the
  56727. + * clear. The output of the decryption job is compared to the original
  56728. + * cleartext; if they don't compare correctly, one can assume a key problem
  56729. + * exists, where the function will exit with an error.
  56730. + *
  56731. + * This module can use a substantial amount of refactoring, which may occur
  56732. + * after the API gets some mileage. Furthermore, expect this module to
  56733. + * eventually disappear once the API is integrated into "real" software.
  56734. + */
  56735. +
  56736. +#include "compat.h"
  56737. +#include "intern.h"
  56738. +#include "desc.h"
  56739. +#include "error.h"
  56740. +#include "jr.h"
  56741. +#include "sm.h"
  56742. +
  56743. +static u8 skeymod[] = {
  56744. + 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
  56745. + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
  56746. +};
  56747. +static u8 symkey[] = {
  56748. + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  56749. + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  56750. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  56751. + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
  56752. +};
  56753. +
  56754. +static u8 symdata[] = {
  56755. + 0x00, 0x01, 0x02, 0x03, 0x04, 0x0f, 0x06, 0x07,
  56756. + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  56757. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  56758. + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  56759. + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  56760. + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  56761. + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  56762. + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  56763. + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  56764. + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  56765. + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
  56766. + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
  56767. + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  56768. + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
  56769. + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
  56770. + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
  56771. + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  56772. + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
  56773. + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  56774. + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
  56775. + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
  56776. + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  56777. + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
  56778. + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
  56779. + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
  56780. + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  56781. + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
  56782. + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
  56783. + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
  56784. + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
  56785. + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  56786. + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
  56787. +};
  56788. +
  56789. +static int mk_job_desc(u32 *desc, dma_addr_t key, u16 keysz, dma_addr_t indata,
  56790. + dma_addr_t outdata, u16 sz, u32 cipherdir, u32 keymode)
  56791. +{
  56792. + desc[1] = CMD_KEY | CLASS_1 | (keysz & KEY_LENGTH_MASK) | keymode;
  56793. + desc[2] = (u32)key;
  56794. + desc[3] = CMD_OPERATION | OP_TYPE_CLASS1_ALG | OP_ALG_AAI_ECB |
  56795. + cipherdir;
  56796. + desc[4] = CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 |
  56797. + FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1 | sz;
  56798. + desc[5] = (u32)indata;
  56799. + desc[6] = CMD_FIFO_STORE | FIFOST_TYPE_MESSAGE_DATA | sz;
  56800. + desc[7] = (u32)outdata;
  56801. +
  56802. + desc[0] = CMD_DESC_HDR | HDR_ONE | (8 & HDR_DESCLEN_MASK);
  56803. + return 8 * sizeof(u32);
  56804. +}
  56805. +
  56806. +struct exec_test_result {
  56807. + int error;
  56808. + struct completion completion;
  56809. +};
  56810. +
  56811. +void exec_test_done(struct device *dev, u32 *desc, u32 err, void *context)
  56812. +{
  56813. + struct exec_test_result *res = context;
  56814. +
  56815. + if (err) {
  56816. + char tmp[CAAM_ERROR_STR_MAX];
  56817. + dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err));
  56818. + }
  56819. +
  56820. + res->error = err;
  56821. + complete(&res->completion);
  56822. +}
  56823. +
  56824. +static int exec_test_job(struct device *ksdev, u32 *jobdesc)
  56825. +{
  56826. + struct exec_test_result testres;
  56827. + struct caam_drv_private_sm *kspriv;
  56828. + int rtn = 0;
  56829. +
  56830. + kspriv = dev_get_drvdata(ksdev);
  56831. +
  56832. + init_completion(&testres.completion);
  56833. +
  56834. + rtn = caam_jr_enqueue(kspriv->smringdev, jobdesc, exec_test_done,
  56835. + &testres);
  56836. + if (!rtn) {
  56837. + wait_for_completion_interruptible(&testres.completion);
  56838. + rtn = testres.error;
  56839. + }
  56840. + return rtn;
  56841. +}
  56842. +
  56843. +
  56844. +int caam_sm_example_init(struct platform_device *pdev)
  56845. +{
  56846. + struct device *ctrldev, *ksdev;
  56847. + struct caam_drv_private *ctrlpriv;
  56848. + struct caam_drv_private_sm *kspriv;
  56849. + u32 unit, units, jdescsz;
  56850. + int stat, jstat, rtnval = 0;
  56851. + u8 __iomem *syminp, *symint, *symout = NULL;
  56852. + dma_addr_t syminp_dma, symint_dma, symout_dma;
  56853. + u8 __iomem *black_key_des, *black_key_aes128;
  56854. + u8 __iomem *black_key_aes256;
  56855. + dma_addr_t black_key_des_dma, black_key_aes128_dma;
  56856. + dma_addr_t black_key_aes256_dma;
  56857. + u8 __iomem *clear_key_des, *clear_key_aes128, *clear_key_aes256;
  56858. + dma_addr_t clear_key_des_dma, clear_key_aes128_dma;
  56859. + dma_addr_t clear_key_aes256_dma;
  56860. + u32 __iomem *jdesc;
  56861. + u32 keyslot_des, keyslot_aes128, keyslot_aes256 = 0;
  56862. +
  56863. + jdesc = NULL;
  56864. + black_key_des = black_key_aes128 = black_key_aes256 = NULL;
  56865. + clear_key_des = clear_key_aes128 = clear_key_aes256 = NULL;
  56866. +
  56867. + /* We can lose this cruft once we can get a pdev by name */
  56868. + ctrldev = &pdev->dev;
  56869. + ctrlpriv = dev_get_drvdata(ctrldev);
  56870. + ksdev = ctrlpriv->smdev;
  56871. + kspriv = dev_get_drvdata(ksdev);
  56872. + if (kspriv == NULL)
  56873. + return -ENODEV;
  56874. +
  56875. + /* Now that we have the dev for the single SM instance, connect */
  56876. +#ifdef SM_TEST_DETAIL
  56877. + dev_info(ksdev, "caam_sm_test_init() running\n");
  56878. +#endif
  56879. + /* Probe to see what keystores are available to us */
  56880. + units = sm_detect_keystore_units(ksdev);
  56881. + if (!units)
  56882. + dev_err(ksdev, "caam_sm_test: no keystore units available\n");
  56883. +
  56884. + /*
  56885. + * MX6 bootloader stores some stuff in unit 0, so let's
  56886. + * use 1 or above
  56887. + */
  56888. + if (units < 2) {
  56889. + dev_err(ksdev, "caam_sm_test: insufficient keystore units\n");
  56890. + return -ENODEV;
  56891. + }
  56892. + unit = 1;
  56893. +
  56894. +#ifdef SM_TEST_DETAIL
  56895. + dev_info(ksdev, "caam_sm_test: %d keystore units available\n", units);
  56896. +#endif
  56897. +
  56898. + /* Initialize/Establish Keystore */
  56899. + sm_establish_keystore(ksdev, unit); /* Initalize store in #1 */
  56900. +
  56901. + /*
  56902. + * Top of main test thread
  56903. + */
  56904. +
  56905. + /* Allocate test data blocks (input, intermediate, output) */
  56906. + syminp = kmalloc(256, GFP_KERNEL | GFP_DMA);
  56907. + symint = kmalloc(256, GFP_KERNEL | GFP_DMA);
  56908. + symout = kmalloc(256, GFP_KERNEL | GFP_DMA);
  56909. + if ((syminp == NULL) || (symint == NULL) || (symout == NULL)) {
  56910. + rtnval = -ENOMEM;
  56911. + dev_err(ksdev, "caam_sm_test: can't get test data buffers\n");
  56912. + goto freemem;
  56913. + }
  56914. +
  56915. + /* Allocate storage for 3 black keys: encapsulated 8, 16, 32 */
  56916. + black_key_des = kmalloc(16, GFP_KERNEL | GFP_DMA); /* padded to 16... */
  56917. + black_key_aes128 = kmalloc(16, GFP_KERNEL | GFP_DMA);
  56918. + black_key_aes256 = kmalloc(16, GFP_KERNEL | GFP_DMA);
  56919. + if ((black_key_des == NULL) || (black_key_aes128 == NULL) ||
  56920. + (black_key_aes256 == NULL)) {
  56921. + rtnval = -ENOMEM;
  56922. + dev_err(ksdev, "caam_sm_test: can't black key buffers\n");
  56923. + goto freemem;
  56924. + }
  56925. +
  56926. + clear_key_des = kmalloc(8, GFP_KERNEL | GFP_DMA);
  56927. + clear_key_aes128 = kmalloc(16, GFP_KERNEL | GFP_DMA);
  56928. + clear_key_aes256 = kmalloc(32, GFP_KERNEL | GFP_DMA);
  56929. + if ((clear_key_des == NULL) || (clear_key_aes128 == NULL) ||
  56930. + (clear_key_aes256 == NULL)) {
  56931. + rtnval = -ENOMEM;
  56932. + dev_err(ksdev, "caam_sm_test: can't get clear key buffers\n");
  56933. + goto freemem;
  56934. + }
  56935. +
  56936. + /* Allocate storage for job descriptor */
  56937. + jdesc = kmalloc(8 * sizeof(u32), GFP_KERNEL | GFP_DMA);
  56938. + if (jdesc == NULL) {
  56939. + rtnval = -ENOMEM;
  56940. + dev_err(ksdev, "caam_sm_test: can't get descriptor buffers\n");
  56941. + goto freemem;
  56942. + }
  56943. +
  56944. +#ifdef SM_TEST_DETAIL
  56945. + dev_info(ksdev, "caam_sm_test: all buffers allocated\n");
  56946. +#endif
  56947. +
  56948. + /* Load up input data block, clear outputs */
  56949. + memcpy(syminp, symdata, 256);
  56950. + memset(symint, 0, 256);
  56951. + memset(symout, 0, 256);
  56952. +#ifdef SM_TEST_DETAIL
  56953. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  56954. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  56955. + syminp[0], syminp[1], syminp[2], syminp[3],
  56956. + syminp[4], syminp[5], syminp[6], syminp[7]);
  56957. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  56958. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  56959. + symint[0], symint[1], symint[2], symint[3],
  56960. + symint[4], symint[5], symint[6], symint[7]);
  56961. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  56962. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  56963. + symout[0], symout[1], symout[2], symout[3],
  56964. + symout[4], symout[5], symout[6], symout[7]);
  56965. +
  56966. + dev_info(ksdev, "caam_sm_test: data buffers initialized\n");
  56967. +#endif
  56968. +
  56969. + /* Load up clear keys */
  56970. + memcpy(clear_key_des, symkey, 8);
  56971. + memcpy(clear_key_aes128, symkey, 16);
  56972. + memcpy(clear_key_aes256, symkey, 32);
  56973. +
  56974. +#ifdef SM_TEST_DETAIL
  56975. + dev_info(ksdev, "caam_sm_test: all clear keys loaded\n");
  56976. +#endif
  56977. +
  56978. + /*
  56979. + * Place clear keys in keystore.
  56980. + * All the interesting stuff happens here.
  56981. + */
  56982. + /* 8 bit DES key */
  56983. + stat = sm_keystore_slot_alloc(ksdev, unit, 8, &keyslot_des);
  56984. + if (stat)
  56985. + goto freemem;
  56986. +#ifdef SM_TEST_DETAIL
  56987. + dev_info(ksdev, "caam_sm_test: 8 byte key slot in %d\n", keyslot_des);
  56988. +#endif
  56989. + stat = sm_keystore_slot_load(ksdev, unit, keyslot_des, clear_key_des,
  56990. + 8);
  56991. + if (stat) {
  56992. +#ifdef SM_TEST_DETAIL
  56993. + dev_info(ksdev, "caam_sm_test: can't load 8 byte key in %d\n",
  56994. + keyslot_des);
  56995. +#endif
  56996. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  56997. + goto freemem;
  56998. + }
  56999. +
  57000. + /* 16 bit AES key */
  57001. + stat = sm_keystore_slot_alloc(ksdev, unit, 16, &keyslot_aes128);
  57002. + if (stat) {
  57003. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  57004. + goto freemem;
  57005. + }
  57006. +#ifdef SM_TEST_DETAIL
  57007. + dev_info(ksdev, "caam_sm_test: 16 byte key slot in %d\n",
  57008. + keyslot_aes128);
  57009. +#endif
  57010. + stat = sm_keystore_slot_load(ksdev, unit, keyslot_aes128,
  57011. + clear_key_aes128, 16);
  57012. + if (stat) {
  57013. +#ifdef SM_TEST_DETAIL
  57014. + dev_info(ksdev, "caam_sm_test: can't load 16 byte key in %d\n",
  57015. + keyslot_aes128);
  57016. +#endif
  57017. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  57018. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  57019. + goto freemem;
  57020. + }
  57021. +
  57022. + /* 32 bit AES key */
  57023. + stat = sm_keystore_slot_alloc(ksdev, unit, 32, &keyslot_aes256);
  57024. + if (stat) {
  57025. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  57026. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  57027. + goto freemem;
  57028. + }
  57029. +#ifdef SM_TEST_DETAIL
  57030. + dev_info(ksdev, "caam_sm_test: 32 byte key slot in %d\n",
  57031. + keyslot_aes256);
  57032. +#endif
  57033. + stat = sm_keystore_slot_load(ksdev, unit, keyslot_aes256,
  57034. + clear_key_aes256, 32);
  57035. + if (stat) {
  57036. +#ifdef SM_TEST_DETAIL
  57037. + dev_info(ksdev, "caam_sm_test: can't load 32 byte key in %d\n",
  57038. + keyslot_aes128);
  57039. +#endif
  57040. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes256);
  57041. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  57042. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  57043. + goto freemem;
  57044. + }
  57045. +
  57046. + /* Encapsulate all keys as SM blobs */
  57047. + stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_des,
  57048. + keyslot_des, 8, skeymod, 8);
  57049. + if (stat) {
  57050. + dev_info(ksdev, "caam_sm_test: can't encapsulate DES key\n");
  57051. + goto freekeys;
  57052. + }
  57053. +
  57054. + stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_aes128,
  57055. + keyslot_aes128, 16, skeymod, 8);
  57056. + if (stat) {
  57057. + dev_info(ksdev, "caam_sm_test: can't encapsulate AES128 key\n");
  57058. + goto freekeys;
  57059. + }
  57060. +
  57061. + stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_aes256,
  57062. + keyslot_aes256, 32, skeymod, 8);
  57063. + if (stat) {
  57064. + dev_info(ksdev, "caam_sm_test: can't encapsulate AES256 key\n");
  57065. + goto freekeys;
  57066. + }
  57067. +
  57068. + /* Now decapsulate as black key blobs */
  57069. + stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_des,
  57070. + keyslot_des, 8, skeymod, 8);
  57071. + if (stat) {
  57072. + dev_info(ksdev, "caam_sm_test: can't decapsulate DES key\n");
  57073. + goto freekeys;
  57074. + }
  57075. +
  57076. + stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_aes128,
  57077. + keyslot_aes128, 16, skeymod, 8);
  57078. + if (stat) {
  57079. + dev_info(ksdev, "caam_sm_test: can't decapsulate AES128 key\n");
  57080. + goto freekeys;
  57081. + }
  57082. +
  57083. + stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_aes256,
  57084. + keyslot_aes256, 32, skeymod, 8);
  57085. + if (stat) {
  57086. + dev_info(ksdev, "caam_sm_test: can't decapsulate AES128 key\n");
  57087. + goto freekeys;
  57088. + }
  57089. +
  57090. + /* Extract 8/16/32 byte black keys */
  57091. + sm_keystore_slot_read(ksdev, unit, keyslot_des, 8, black_key_des);
  57092. + sm_keystore_slot_read(ksdev, unit, keyslot_aes128, 16,
  57093. + black_key_aes128);
  57094. + sm_keystore_slot_read(ksdev, unit, keyslot_aes256, 32,
  57095. + black_key_aes256);
  57096. +
  57097. +#ifdef SM_TEST_DETAIL
  57098. + dev_info(ksdev, "caam_sm_test: all black keys extracted\n");
  57099. +#endif
  57100. +
  57101. + /* DES encrypt using 8 byte black key */
  57102. + black_key_des_dma = dma_map_single(ksdev, black_key_des, 8,
  57103. + DMA_TO_DEVICE);
  57104. + dma_sync_single_for_device(ksdev, black_key_des_dma, 8, DMA_TO_DEVICE);
  57105. + syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
  57106. + dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57107. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
  57108. +
  57109. + jdescsz = mk_job_desc(jdesc, black_key_des_dma, 8, syminp_dma,
  57110. + symint_dma, 256,
  57111. + OP_ALG_ENCRYPT | OP_ALG_ALGSEL_DES, 0);
  57112. +
  57113. +#ifdef SM_TEST_DETAIL
  57114. + dev_info(ksdev, "jobdesc:\n");
  57115. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57116. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57117. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57118. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57119. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57120. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57121. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57122. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57123. +#endif
  57124. +
  57125. + jstat = exec_test_job(ksdev, jdesc);
  57126. +
  57127. + dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57128. + dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57129. + dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57130. + dma_unmap_single(ksdev, black_key_des_dma, 8, DMA_TO_DEVICE);
  57131. +
  57132. +#ifdef SM_TEST_DETAIL
  57133. + dev_info(ksdev, "input block:\n");
  57134. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57135. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57136. + syminp[0], syminp[1], syminp[2], syminp[3],
  57137. + syminp[4], syminp[5], syminp[6], syminp[7]);
  57138. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57139. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57140. + syminp[8], syminp[9], syminp[10], syminp[11],
  57141. + syminp[12], syminp[13], syminp[14], syminp[15]);
  57142. + dev_info(ksdev, "intermediate block:\n");
  57143. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57144. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57145. + symint[0], symint[1], symint[2], symint[3],
  57146. + symint[4], symint[5], symint[6], symint[7]);
  57147. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57148. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57149. + symint[8], symint[9], symint[10], symint[11],
  57150. + symint[12], symint[13], symint[14], symint[15]);
  57151. + dev_info(ksdev, "caam_sm_test: encrypt cycle with 8 byte key\n");
  57152. +#endif
  57153. +
  57154. + /* DES decrypt using 8 byte clear key */
  57155. + clear_key_des_dma = dma_map_single(ksdev, clear_key_des, 8,
  57156. + DMA_TO_DEVICE);
  57157. + dma_sync_single_for_device(ksdev, clear_key_des_dma, 8, DMA_TO_DEVICE);
  57158. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
  57159. + dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57160. + symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
  57161. +
  57162. + jdescsz = mk_job_desc(jdesc, clear_key_des_dma, 8, symint_dma,
  57163. + symout_dma, 256,
  57164. + OP_ALG_DECRYPT | OP_ALG_ALGSEL_DES, 0);
  57165. +
  57166. +#ifdef SM_TEST_DETAIL
  57167. + dev_info(ksdev, "jobdesc:\n");
  57168. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57169. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57170. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57171. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57172. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57173. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57174. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57175. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57176. +#endif
  57177. +
  57178. + jstat = exec_test_job(ksdev, jdesc);
  57179. +
  57180. + dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57181. + dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57182. + dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57183. + dma_unmap_single(ksdev, clear_key_des_dma, 8, DMA_TO_DEVICE);
  57184. +
  57185. +#ifdef SM_TEST_DETAIL
  57186. + dev_info(ksdev, "intermediate block:\n");
  57187. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57188. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57189. + symint[0], symint[1], symint[2], symint[3],
  57190. + symint[4], symint[5], symint[6], symint[7]);
  57191. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57192. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57193. + symint[8], symint[9], symint[10], symint[11],
  57194. + symint[12], symint[13], symint[14], symint[15]);
  57195. + dev_info(ksdev, "decrypted block:\n");
  57196. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57197. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57198. + symout[0], symout[1], symout[2], symout[3],
  57199. + symout[4], symout[5], symout[6], symout[7]);
  57200. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57201. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57202. + symout[8], symout[9], symout[10], symout[11],
  57203. + symout[12], symout[13], symout[14], symout[15]);
  57204. + dev_info(ksdev, "caam_sm_test: decrypt cycle with 8 byte key\n");
  57205. +#endif
  57206. +
  57207. + /* Check result */
  57208. + if (memcmp(symout, syminp, 256)) {
  57209. + dev_info(ksdev, "caam_sm_test: 8-byte key test mismatch\n");
  57210. + rtnval = -1;
  57211. + goto freekeys;
  57212. + } else
  57213. + dev_info(ksdev, "caam_sm_test: 8-byte key test match OK\n");
  57214. +
  57215. + /* AES-128 encrypt using 16 byte black key */
  57216. + black_key_aes128_dma = dma_map_single(ksdev, black_key_aes128, 16,
  57217. + DMA_TO_DEVICE);
  57218. + dma_sync_single_for_device(ksdev, black_key_aes128_dma, 16,
  57219. + DMA_TO_DEVICE);
  57220. + syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
  57221. + dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57222. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
  57223. +
  57224. + jdescsz = mk_job_desc(jdesc, black_key_aes128_dma, 16, syminp_dma,
  57225. + symint_dma, 256,
  57226. + OP_ALG_ENCRYPT | OP_ALG_ALGSEL_AES, 0);
  57227. +
  57228. +#ifdef SM_TEST_DETAIL
  57229. + dev_info(ksdev, "jobdesc:\n");
  57230. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57231. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57232. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57233. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57234. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57235. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57236. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57237. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57238. +#endif
  57239. +
  57240. + jstat = exec_test_job(ksdev, jdesc);
  57241. +
  57242. + dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57243. + dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57244. + dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57245. + dma_unmap_single(ksdev, black_key_aes128_dma, 16, DMA_TO_DEVICE);
  57246. +
  57247. +#ifdef SM_TEST_DETAIL
  57248. + dev_info(ksdev, "input block:\n");
  57249. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57250. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57251. + syminp[0], syminp[1], syminp[2], syminp[3],
  57252. + syminp[4], syminp[5], syminp[6], syminp[7]);
  57253. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57254. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57255. + syminp[8], syminp[9], syminp[10], syminp[11],
  57256. + syminp[12], syminp[13], syminp[14], syminp[15]);
  57257. + dev_info(ksdev, "intermediate block:\n");
  57258. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57259. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57260. + symint[0], symint[1], symint[2], symint[3],
  57261. + symint[4], symint[5], symint[6], symint[7]);
  57262. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57263. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57264. + symint[8], symint[9], symint[10], symint[11],
  57265. + symint[12], symint[13], symint[14], symint[15]);
  57266. + dev_info(ksdev, "caam_sm_test: encrypt cycle with 16 byte key\n");
  57267. +#endif
  57268. +
  57269. + /* AES-128 decrypt using 16 byte clear key */
  57270. + clear_key_aes128_dma = dma_map_single(ksdev, clear_key_aes128, 16,
  57271. + DMA_TO_DEVICE);
  57272. + dma_sync_single_for_device(ksdev, clear_key_aes128_dma, 16,
  57273. + DMA_TO_DEVICE);
  57274. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
  57275. + dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57276. + symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
  57277. +
  57278. + jdescsz = mk_job_desc(jdesc, clear_key_aes128_dma, 16, symint_dma,
  57279. + symout_dma, 256,
  57280. + OP_ALG_DECRYPT | OP_ALG_ALGSEL_AES, 0);
  57281. +
  57282. +#ifdef SM_TEST_DETAIL
  57283. + dev_info(ksdev, "jobdesc:\n");
  57284. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57285. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57286. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57287. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57288. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57289. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57290. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57291. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57292. +#endif
  57293. + jstat = exec_test_job(ksdev, jdesc);
  57294. +
  57295. + dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57296. + dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57297. + dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57298. + dma_unmap_single(ksdev, clear_key_aes128_dma, 16, DMA_TO_DEVICE);
  57299. +
  57300. +#ifdef SM_TEST_DETAIL
  57301. + dev_info(ksdev, "intermediate block:\n");
  57302. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57303. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57304. + symint[0], symint[1], symint[2], symint[3],
  57305. + symint[4], symint[5], symint[6], symint[7]);
  57306. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57307. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57308. + symint[8], symint[9], symint[10], symint[11],
  57309. + symint[12], symint[13], symint[14], symint[15]);
  57310. + dev_info(ksdev, "decrypted block:\n");
  57311. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57312. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57313. + symout[0], symout[1], symout[2], symout[3],
  57314. + symout[4], symout[5], symout[6], symout[7]);
  57315. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57316. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57317. + symout[8], symout[9], symout[10], symout[11],
  57318. + symout[12], symout[13], symout[14], symout[15]);
  57319. + dev_info(ksdev, "caam_sm_test: decrypt cycle with 16 byte key\n");
  57320. +#endif
  57321. +
  57322. + /* Check result */
  57323. + if (memcmp(symout, syminp, 256)) {
  57324. + dev_info(ksdev, "caam_sm_test: 16-byte key test mismatch\n");
  57325. + rtnval = -1;
  57326. + goto freekeys;
  57327. + } else
  57328. + dev_info(ksdev, "caam_sm_test: 16-byte key test match OK\n");
  57329. +
  57330. + /* AES-256 encrypt using 32 byte black key */
  57331. + black_key_aes256_dma = dma_map_single(ksdev, black_key_aes256, 32,
  57332. + DMA_TO_DEVICE);
  57333. + dma_sync_single_for_device(ksdev, black_key_aes256_dma, 32,
  57334. + DMA_TO_DEVICE);
  57335. + syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
  57336. + dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57337. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
  57338. +
  57339. + jdescsz = mk_job_desc(jdesc, black_key_aes256_dma, 32, syminp_dma,
  57340. + symint_dma, 256,
  57341. + OP_ALG_ENCRYPT | OP_ALG_ALGSEL_AES, 0);
  57342. +
  57343. +#ifdef SM_TEST_DETAIL
  57344. + dev_info(ksdev, "jobdesc:\n");
  57345. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57346. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57347. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57348. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57349. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57350. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57351. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57352. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57353. +#endif
  57354. +
  57355. + jstat = exec_test_job(ksdev, jdesc);
  57356. +
  57357. + dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57358. + dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57359. + dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57360. + dma_unmap_single(ksdev, black_key_aes256_dma, 32, DMA_TO_DEVICE);
  57361. +
  57362. +#ifdef SM_TEST_DETAIL
  57363. + dev_info(ksdev, "input block:\n");
  57364. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57365. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57366. + syminp[0], syminp[1], syminp[2], syminp[3],
  57367. + syminp[4], syminp[5], syminp[6], syminp[7]);
  57368. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57369. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57370. + syminp[8], syminp[9], syminp[10], syminp[11],
  57371. + syminp[12], syminp[13], syminp[14], syminp[15]);
  57372. + dev_info(ksdev, "intermediate block:\n");
  57373. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57374. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57375. + symint[0], symint[1], symint[2], symint[3],
  57376. + symint[4], symint[5], symint[6], symint[7]);
  57377. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57378. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57379. + symint[8], symint[9], symint[10], symint[11],
  57380. + symint[12], symint[13], symint[14], symint[15]);
  57381. + dev_info(ksdev, "caam_sm_test: encrypt cycle with 32 byte key\n");
  57382. +#endif
  57383. +
  57384. + /* AES-256 decrypt using 32-byte black key */
  57385. + clear_key_aes256_dma = dma_map_single(ksdev, clear_key_aes256, 32,
  57386. + DMA_TO_DEVICE);
  57387. + dma_sync_single_for_device(ksdev, clear_key_aes256_dma, 32,
  57388. + DMA_TO_DEVICE);
  57389. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
  57390. + dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57391. + symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
  57392. +
  57393. + jdescsz = mk_job_desc(jdesc, clear_key_aes256_dma, 32, symint_dma,
  57394. + symout_dma, 256,
  57395. + OP_ALG_DECRYPT | OP_ALG_ALGSEL_AES, 0);
  57396. +
  57397. +#ifdef SM_TEST_DETAIL
  57398. + dev_info(ksdev, "jobdesc:\n");
  57399. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57400. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57401. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57402. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57403. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57404. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57405. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57406. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57407. +#endif
  57408. +
  57409. + jstat = exec_test_job(ksdev, jdesc);
  57410. +
  57411. + dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57412. + dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57413. + dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57414. + dma_unmap_single(ksdev, clear_key_aes256_dma, 32, DMA_TO_DEVICE);
  57415. +
  57416. +#ifdef SM_TEST_DETAIL
  57417. + dev_info(ksdev, "intermediate block:\n");
  57418. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57419. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57420. + symint[0], symint[1], symint[2], symint[3],
  57421. + symint[4], symint[5], symint[6], symint[7]);
  57422. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57423. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57424. + symint[8], symint[9], symint[10], symint[11],
  57425. + symint[12], symint[13], symint[14], symint[15]);
  57426. + dev_info(ksdev, "decrypted block:\n");
  57427. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57428. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57429. + symout[0], symout[1], symout[2], symout[3],
  57430. + symout[4], symout[5], symout[6], symout[7]);
  57431. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57432. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57433. + symout[8], symout[9], symout[10], symout[11],
  57434. + symout[12], symout[13], symout[14], symout[15]);
  57435. + dev_info(ksdev, "caam_sm_test: decrypt cycle with 32 byte key\n");
  57436. +#endif
  57437. +
  57438. + /* Check result */
  57439. + if (memcmp(symout, syminp, 256)) {
  57440. + dev_info(ksdev, "caam_sm_test: 32-byte key test mismatch\n");
  57441. + rtnval = -1;
  57442. + goto freekeys;
  57443. + } else
  57444. + dev_info(ksdev, "caam_sm_test: 32-byte key test match OK\n");
  57445. +
  57446. +
  57447. + /* Remove 8/16/32 byte keys from keystore */
  57448. +freekeys:
  57449. + stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  57450. + if (stat)
  57451. + dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
  57452. + keyslot_des);
  57453. +
  57454. + stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  57455. + if (stat)
  57456. + dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
  57457. + keyslot_aes128);
  57458. +
  57459. + stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes256);
  57460. + if (stat)
  57461. + dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
  57462. + keyslot_aes256);
  57463. +
  57464. +
  57465. + /* Free resources */
  57466. +freemem:
  57467. +#ifdef SM_TEST_DETAIL
  57468. + dev_info(ksdev, "caam_sm_test: cleaning up\n");
  57469. +#endif
  57470. + kfree(syminp);
  57471. + kfree(symint);
  57472. + kfree(symout);
  57473. + kfree(clear_key_des);
  57474. + kfree(clear_key_aes128);
  57475. + kfree(clear_key_aes256);
  57476. + kfree(black_key_des);
  57477. + kfree(black_key_aes128);
  57478. + kfree(black_key_aes256);
  57479. + kfree(jdesc);
  57480. +
  57481. + /* Disconnect from keystore and leave */
  57482. + sm_release_keystore(ksdev, unit);
  57483. +
  57484. + return rtnval;
  57485. +}
  57486. +EXPORT_SYMBOL(caam_sm_example_init);
  57487. +
  57488. +void caam_sm_example_shutdown(void)
  57489. +{
  57490. + /* unused in present version */
  57491. + struct device_node *dev_node;
  57492. + struct platform_device *pdev;
  57493. +
  57494. + /*
  57495. + * Do of_find_compatible_node() then of_find_device_by_node()
  57496. + * once a functional device tree is available
  57497. + */
  57498. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  57499. + if (!dev_node) {
  57500. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  57501. + if (!dev_node)
  57502. + return;
  57503. + }
  57504. +
  57505. + pdev = of_find_device_by_node(dev_node);
  57506. + if (!pdev)
  57507. + return;
  57508. +
  57509. + of_node_get(dev_node);
  57510. +
  57511. +}
  57512. +
  57513. +static int __init caam_sm_test_init(void)
  57514. +{
  57515. + struct device_node *dev_node;
  57516. + struct platform_device *pdev;
  57517. +
  57518. + /*
  57519. + * Do of_find_compatible_node() then of_find_device_by_node()
  57520. + * once a functional device tree is available
  57521. + */
  57522. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  57523. + if (!dev_node) {
  57524. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  57525. + if (!dev_node)
  57526. + return -ENODEV;
  57527. + }
  57528. +
  57529. + pdev = of_find_device_by_node(dev_node);
  57530. + if (!pdev)
  57531. + return -ENODEV;
  57532. +
  57533. + of_node_put(dev_node);
  57534. +
  57535. + caam_sm_example_init(pdev);
  57536. +
  57537. + return 0;
  57538. +}
  57539. +
  57540. +
  57541. +/* Module-based initialization needs to wait for dev tree */
  57542. +#ifdef CONFIG_OF
  57543. +module_init(caam_sm_test_init);
  57544. +module_exit(caam_sm_example_shutdown);
  57545. +
  57546. +MODULE_LICENSE("Dual BSD/GPL");
  57547. +MODULE_DESCRIPTION("FSL CAAM Keystore Usage Example");
  57548. +MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
  57549. +#endif
  57550. diff -Nur linux-3.14.15/drivers/crypto/caam/snvsregs.h linux-linaro-stable-mx6/drivers/crypto/caam/snvsregs.h
  57551. --- linux-3.14.15/drivers/crypto/caam/snvsregs.h 1970-01-01 01:00:00.000000000 +0100
  57552. +++ linux-linaro-stable-mx6/drivers/crypto/caam/snvsregs.h 2014-08-20 19:23:50.790834021 +0200
  57553. @@ -0,0 +1,237 @@
  57554. +/*
  57555. + * SNVS hardware register-level view
  57556. + *
  57557. + * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
  57558. + */
  57559. +
  57560. +#ifndef SNVSREGS_H
  57561. +#define SNVSREGS_H
  57562. +
  57563. +#include <linux/types.h>
  57564. +#include <linux/io.h>
  57565. +
  57566. +/*
  57567. + * SNVS High Power Domain
  57568. + * Includes security violations, HA counter, RTC, alarm
  57569. + */
  57570. +struct snvs_hp {
  57571. + u32 lock;
  57572. + u32 cmd;
  57573. + u32 ctl;
  57574. + u32 secvio_int_en; /* Security Violation Interrupt Enable */
  57575. + u32 secvio_int_ctl; /* Security Violation Interrupt Control */
  57576. + u32 status;
  57577. + u32 secvio_status; /* Security Violation Status */
  57578. + u32 ha_counteriv; /* High Assurance Counter IV */
  57579. + u32 ha_counter; /* High Assurance Counter */
  57580. + u32 rtc_msb; /* Real Time Clock/Counter MSB */
  57581. + u32 rtc_lsb; /* Real Time Counter LSB */
  57582. + u32 time_alarm_msb; /* Time Alarm MSB */
  57583. + u32 time_alarm_lsb; /* Time Alarm LSB */
  57584. +};
  57585. +
  57586. +#define HP_LOCK_HAC_LCK 0x00040000
  57587. +#define HP_LOCK_HPSICR_LCK 0x00020000
  57588. +#define HP_LOCK_HPSVCR_LCK 0x00010000
  57589. +#define HP_LOCK_MKEYSEL_LCK 0x00000200
  57590. +#define HP_LOCK_TAMPCFG_LCK 0x00000100
  57591. +#define HP_LOCK_TAMPFLT_LCK 0x00000080
  57592. +#define HP_LOCK_SECVIO_LCK 0x00000040
  57593. +#define HP_LOCK_GENP_LCK 0x00000020
  57594. +#define HP_LOCK_MONOCTR_LCK 0x00000010
  57595. +#define HP_LOCK_CALIB_LCK 0x00000008
  57596. +#define HP_LOCK_SRTC_LCK 0x00000004
  57597. +#define HP_LOCK_ZMK_RD_LCK 0x00000002
  57598. +#define HP_LOCK_ZMK_WT_LCK 0x00000001
  57599. +
  57600. +#define HP_CMD_NONPRIV_AXS 0x80000000
  57601. +#define HP_CMD_HAC_STOP 0x00080000
  57602. +#define HP_CMD_HAC_CLEAR 0x00040000
  57603. +#define HP_CMD_HAC_LOAD 0x00020000
  57604. +#define HP_CMD_HAC_CFG_EN 0x00010000
  57605. +#define HP_CMD_SNVS_MSTR_KEY 0x00002000
  57606. +#define HP_CMD_PROG_ZMK 0x00001000
  57607. +#define HP_CMD_SW_LPSV 0x00000400
  57608. +#define HP_CMD_SW_FSV 0x00000200
  57609. +#define HP_CMD_SW_SV 0x00000100
  57610. +#define HP_CMD_LP_SWR_DIS 0x00000020
  57611. +#define HP_CMD_LP_SWR 0x00000010
  57612. +#define HP_CMD_SSM_SFNS_DIS 0x00000004
  57613. +#define HP_CMD_SSM_ST_DIS 0x00000002
  57614. +#define HP_CMD_SMM_ST 0x00000001
  57615. +
  57616. +#define HP_CTL_TIME_SYNC 0x00010000
  57617. +#define HP_CTL_CAL_VAL_SHIFT 10
  57618. +#define HP_CTL_CAL_VAL_MASK (0x1f << HP_CTL_CALIB_SHIFT)
  57619. +#define HP_CTL_CALIB_EN 0x00000100
  57620. +#define HP_CTL_PI_FREQ_SHIFT 4
  57621. +#define HP_CTL_PI_FREQ_MASK (0xf << HP_CTL_PI_FREQ_SHIFT)
  57622. +#define HP_CTL_PI_EN 0x00000008
  57623. +#define HP_CTL_TIMEALARM_EN 0x00000002
  57624. +#define HP_CTL_RTC_EN 0x00000001
  57625. +
  57626. +#define HP_SECVIO_INTEN_EN 0x10000000
  57627. +#define HP_SECVIO_INTEN_SRC5 0x00000020
  57628. +#define HP_SECVIO_INTEN_SRC4 0x00000010
  57629. +#define HP_SECVIO_INTEN_SRC3 0x00000008
  57630. +#define HP_SECVIO_INTEN_SRC2 0x00000004
  57631. +#define HP_SECVIO_INTEN_SRC1 0x00000002
  57632. +#define HP_SECVIO_INTEN_SRC0 0x00000001
  57633. +#define HP_SECVIO_INTEN_ALL 0x8000003f
  57634. +
  57635. +#define HP_SECVIO_ICTL_CFG_SHIFT 30
  57636. +#define HP_SECVIO_ICTL_CFG_MASK (0x3 << HP_SECVIO_ICTL_CFG_SHIFT)
  57637. +#define HP_SECVIO_ICTL_CFG5_SHIFT 5
  57638. +#define HP_SECVIO_ICTL_CFG5_MASK (0x3 << HP_SECVIO_ICTL_CFG5_SHIFT)
  57639. +#define HP_SECVIO_ICTL_CFG_DISABLE 0
  57640. +#define HP_SECVIO_ICTL_CFG_NONFATAL 1
  57641. +#define HP_SECVIO_ICTL_CFG_FATAL 2
  57642. +#define HP_SECVIO_ICTL_CFG4_FATAL 0x00000010
  57643. +#define HP_SECVIO_ICTL_CFG3_FATAL 0x00000008
  57644. +#define HP_SECVIO_ICTL_CFG2_FATAL 0x00000004
  57645. +#define HP_SECVIO_ICTL_CFG1_FATAL 0x00000002
  57646. +#define HP_SECVIO_ICTL_CFG0_FATAL 0x00000001
  57647. +
  57648. +#define HP_STATUS_ZMK_ZERO 0x80000000
  57649. +#define HP_STATUS_OTPMK_ZERO 0x08000000
  57650. +#define HP_STATUS_OTPMK_SYN_SHIFT 16
  57651. +#define HP_STATUS_OTPMK_SYN_MASK (0x1ff << HP_STATUS_OTPMK_SYN_SHIFT)
  57652. +#define HP_STATUS_SSM_ST_SHIFT 8
  57653. +#define HP_STATUS_SSM_ST_MASK (0xf << HP_STATUS_SSM_ST_SHIFT)
  57654. +#define HP_STATUS_SSM_ST_INIT 0
  57655. +#define HP_STATUS_SSM_ST_HARDFAIL 1
  57656. +#define HP_STATUS_SSM_ST_SOFTFAIL 3
  57657. +#define HP_STATUS_SSM_ST_INITINT 8
  57658. +#define HP_STATUS_SSM_ST_CHECK 9
  57659. +#define HP_STATUS_SSM_ST_NONSECURE 11
  57660. +#define HP_STATUS_SSM_ST_TRUSTED 13
  57661. +#define HP_STATUS_SSM_ST_SECURE 15
  57662. +
  57663. +#define HP_SECVIOST_ZMK_ECC_FAIL 0x08000000 /* write to clear */
  57664. +#define HP_SECVIOST_ZMK_SYN_SHIFT 16
  57665. +#define HP_SECVIOST_ZMK_SYN_MASK (0x1ff << HP_SECVIOST_ZMK_SYN_SHIFT)
  57666. +#define HP_SECVIOST_SECVIO5 0x00000020
  57667. +#define HP_SECVIOST_SECVIO4 0x00000010
  57668. +#define HP_SECVIOST_SECVIO3 0x00000008
  57669. +#define HP_SECVIOST_SECVIO2 0x00000004
  57670. +#define HP_SECVIOST_SECVIO1 0x00000002
  57671. +#define HP_SECVIOST_SECVIO0 0x00000001
  57672. +#define HP_SECVIOST_SECVIOMASK 0x0000003f
  57673. +
  57674. +/*
  57675. + * SNVS Low Power Domain
  57676. + * Includes glitch detector, SRTC, alarm, monotonic counter, ZMK
  57677. + */
  57678. +struct snvs_lp {
  57679. + u32 lock;
  57680. + u32 ctl;
  57681. + u32 mstr_key_ctl; /* Master Key Control */
  57682. + u32 secvio_ctl; /* Security Violation Control */
  57683. + u32 tamper_filt_cfg; /* Tamper Glitch Filters Configuration */
  57684. + u32 tamper_det_cfg; /* Tamper Detectors Configuration */
  57685. + u32 status;
  57686. + u32 srtc_msb; /* Secure Real Time Clock/Counter MSB */
  57687. + u32 srtc_lsb; /* Secure Real Time Clock/Counter LSB */
  57688. + u32 time_alarm; /* Time Alarm */
  57689. + u32 smc_msb; /* Secure Monotonic Counter MSB */
  57690. + u32 smc_lsb; /* Secure Monotonic Counter LSB */
  57691. + u32 pwr_glitch_det; /* Power Glitch Detector */
  57692. + u32 gen_purpose;
  57693. + u32 zmk[8]; /* Zeroizable Master Key */
  57694. +};
  57695. +
  57696. +#define LP_LOCK_MKEYSEL_LCK 0x00000200
  57697. +#define LP_LOCK_TAMPDET_LCK 0x00000100
  57698. +#define LP_LOCK_TAMPFLT_LCK 0x00000080
  57699. +#define LP_LOCK_SECVIO_LCK 0x00000040
  57700. +#define LP_LOCK_GENP_LCK 0x00000020
  57701. +#define LP_LOCK_MONOCTR_LCK 0x00000010
  57702. +#define LP_LOCK_CALIB_LCK 0x00000008
  57703. +#define LP_LOCK_SRTC_LCK 0x00000004
  57704. +#define LP_LOCK_ZMK_RD_LCK 0x00000002
  57705. +#define LP_LOCK_ZMK_WT_LCK 0x00000001
  57706. +
  57707. +#define LP_CTL_CAL_VAL_SHIFT 10
  57708. +#define LP_CTL_CAL_VAL_MASK (0x1f << LP_CTL_CAL_VAL_SHIFT)
  57709. +#define LP_CTL_CALIB_EN 0x00000100
  57710. +#define LP_CTL_SRTC_INVAL_EN 0x00000010
  57711. +#define LP_CTL_WAKE_INT_EN 0x00000008
  57712. +#define LP_CTL_MONOCTR_EN 0x00000004
  57713. +#define LP_CTL_TIMEALARM_EN 0x00000002
  57714. +#define LP_CTL_SRTC_EN 0x00000001
  57715. +
  57716. +#define LP_MKEYCTL_ZMKECC_SHIFT 8
  57717. +#define LP_MKEYCTL_ZMKECC_MASK (0xff << LP_MKEYCTL_ZMKECC_SHIFT)
  57718. +#define LP_MKEYCTL_ZMKECC_EN 0x00000010
  57719. +#define LP_MKEYCTL_ZMKECC_VAL 0x00000008
  57720. +#define LP_MKEYCTL_ZMKECC_PROG 0x00000004
  57721. +#define LP_MKEYCTL_MKSEL_SHIFT 0
  57722. +#define LP_MKEYCTL_MKSEL_MASK (3 << LP_MKEYCTL_MKSEL_SHIFT)
  57723. +#define LP_MKEYCTL_MK_OTP 0
  57724. +#define LP_MKEYCTL_MK_ZMK 2
  57725. +#define LP_MKEYCTL_MK_COMB 3
  57726. +
  57727. +#define LP_SECVIO_CTL_SRC5 0x20
  57728. +#define LP_SECVIO_CTL_SRC4 0x10
  57729. +#define LP_SECVIO_CTL_SRC3 0x08
  57730. +#define LP_SECVIO_CTL_SRC2 0x04
  57731. +#define LP_SECVIO_CTL_SRC1 0x02
  57732. +#define LP_SECVIO_CTL_SRC0 0x01
  57733. +
  57734. +#define LP_TAMPFILT_EXT2_EN 0x80000000
  57735. +#define LP_TAMPFILT_EXT2_SHIFT 24
  57736. +#define LP_TAMPFILT_EXT2_MASK (0x1f << LP_TAMPFILT_EXT2_SHIFT)
  57737. +#define LP_TAMPFILT_EXT1_EN 0x00800000
  57738. +#define LP_TAMPFILT_EXT1_SHIFT 16
  57739. +#define LP_TAMPFILT_EXT1_MASK (0x1f << LP_TAMPFILT_EXT1_SHIFT)
  57740. +#define LP_TAMPFILT_WM_EN 0x00000080
  57741. +#define LP_TAMPFILT_WM_SHIFT 0
  57742. +#define LP_TAMPFILT_WM_MASK (0x1f << LP_TAMPFILT_WM_SHIFT)
  57743. +
  57744. +#define LP_TAMPDET_OSC_BPS 0x10000000
  57745. +#define LP_TAMPDET_VRC_SHIFT 24
  57746. +#define LP_TAMPDET_VRC_MASK (3 << LP_TAMPFILT_VRC_SHIFT)
  57747. +#define LP_TAMPDET_HTDC_SHIFT 20
  57748. +#define LP_TAMPDET_HTDC_MASK (3 << LP_TAMPFILT_HTDC_SHIFT)
  57749. +#define LP_TAMPDET_LTDC_SHIFT 16
  57750. +#define LP_TAMPDET_LTDC_MASK (3 << LP_TAMPFILT_LTDC_SHIFT)
  57751. +#define LP_TAMPDET_POR_OBS 0x00008000
  57752. +#define LP_TAMPDET_PFD_OBS 0x00004000
  57753. +#define LP_TAMPDET_ET2_EN 0x00000400
  57754. +#define LP_TAMPDET_ET1_EN 0x00000200
  57755. +#define LP_TAMPDET_WMT2_EN 0x00000100
  57756. +#define LP_TAMPDET_WMT1_EN 0x00000080
  57757. +#define LP_TAMPDET_VT_EN 0x00000040
  57758. +#define LP_TAMPDET_TT_EN 0x00000020
  57759. +#define LP_TAMPDET_CT_EN 0x00000010
  57760. +#define LP_TAMPDET_MCR_EN 0x00000004
  57761. +#define LP_TAMPDET_SRTCR_EN 0x00000002
  57762. +
  57763. +#define LP_STATUS_SECURE
  57764. +#define LP_STATUS_NONSECURE
  57765. +#define LP_STATUS_SCANEXIT 0x00100000 /* all write 1 clear here on */
  57766. +#define LP_STATUS_EXT_SECVIO 0x00010000
  57767. +#define LP_STATUS_ET2 0x00000400
  57768. +#define LP_STATUS_ET1 0x00000200
  57769. +#define LP_STATUS_WMT2 0x00000100
  57770. +#define LP_STATUS_WMT1 0x00000080
  57771. +#define LP_STATUS_VTD 0x00000040
  57772. +#define LP_STATUS_TTD 0x00000020
  57773. +#define LP_STATUS_CTD 0x00000010
  57774. +#define LP_STATUS_PGD 0x00000008
  57775. +#define LP_STATUS_MCR 0x00000004
  57776. +#define LP_STATUS_SRTCR 0x00000002
  57777. +#define LP_STATUS_LPTA 0x00000001
  57778. +
  57779. +/* Full SNVS register page, including version/options */
  57780. +struct snvs_full {
  57781. + struct snvs_hp hp;
  57782. + struct snvs_lp lp;
  57783. + u32 rsvd[731]; /* deadspace 0x08c-0xbf7 */
  57784. +
  57785. + /* Version / Revision / Option ID space - end of register page */
  57786. + u32 vid; /* 0xbf8 HP Version ID (VID 1) */
  57787. + u32 opt_rev; /* 0xbfc HP Options / Revision (VID 2) */
  57788. +};
  57789. +
  57790. +#endif /* SNVSREGS_H */
  57791. diff -Nur linux-3.14.15/drivers/dma/imx-sdma.c linux-linaro-stable-mx6/drivers/dma/imx-sdma.c
  57792. --- linux-3.14.15/drivers/dma/imx-sdma.c 2014-07-31 23:51:43.000000000 +0200
  57793. +++ linux-linaro-stable-mx6/drivers/dma/imx-sdma.c 2014-08-20 19:31:42.816854789 +0200
  57794. @@ -29,6 +29,7 @@
  57795. #include <linux/semaphore.h>
  57796. #include <linux/spinlock.h>
  57797. #include <linux/device.h>
  57798. +#include <linux/genalloc.h>
  57799. #include <linux/dma-mapping.h>
  57800. #include <linux/firmware.h>
  57801. #include <linux/slab.h>
  57802. @@ -232,6 +233,14 @@
  57803. struct sdma_engine;
  57804. +enum sdma_mode {
  57805. + SDMA_MODE_INVALID = 0,
  57806. + SDMA_MODE_LOOP,
  57807. + SDMA_MODE_NORMAL,
  57808. + SDMA_MODE_P2P,
  57809. + SDMA_MODE_NO_BD,
  57810. +};
  57811. +
  57812. /**
  57813. * struct sdma_channel - housekeeping for a SDMA channel
  57814. *
  57815. @@ -244,6 +253,7 @@
  57816. * @word_size peripheral access size
  57817. * @buf_tail ID of the buffer that was processed
  57818. * @num_bd max NUM_BD. number of descriptors currently handling
  57819. + * @bd_iram flag indicating the memory location of buffer descriptor
  57820. */
  57821. struct sdma_channel {
  57822. struct sdma_engine *sdma;
  57823. @@ -255,14 +265,19 @@
  57824. enum dma_slave_buswidth word_size;
  57825. unsigned int buf_tail;
  57826. unsigned int num_bd;
  57827. + unsigned int period_len;
  57828. struct sdma_buffer_descriptor *bd;
  57829. dma_addr_t bd_phys;
  57830. + bool bd_iram;
  57831. unsigned int pc_from_device, pc_to_device;
  57832. - unsigned long flags;
  57833. - dma_addr_t per_address;
  57834. + unsigned int device_to_device;
  57835. + unsigned int other_script;
  57836. + enum sdma_mode mode;
  57837. + dma_addr_t per_address, per_address2;
  57838. unsigned long event_mask[2];
  57839. unsigned long watermark_level;
  57840. u32 shp_addr, per_addr;
  57841. + u32 data_addr1, data_addr2;
  57842. struct dma_chan chan;
  57843. spinlock_t lock;
  57844. struct dma_async_tx_descriptor desc;
  57845. @@ -272,8 +287,6 @@
  57846. struct tasklet_struct tasklet;
  57847. };
  57848. -#define IMX_DMA_SG_LOOP BIT(0)
  57849. -
  57850. #define MAX_DMA_CHANNELS 32
  57851. #define MXC_SDMA_DEFAULT_PRIORITY 1
  57852. #define MXC_SDMA_MIN_PRIORITY 1
  57853. @@ -325,6 +338,7 @@
  57854. spinlock_t channel_0_lock;
  57855. u32 script_number;
  57856. struct sdma_script_start_addrs *script_addrs;
  57857. + struct gen_pool *iram_pool;
  57858. const struct sdma_driver_data *drvdata;
  57859. };
  57860. @@ -540,12 +554,14 @@
  57861. dma_addr_t buf_phys;
  57862. int ret;
  57863. unsigned long flags;
  57864. + bool use_iram = true;
  57865. - buf_virt = dma_alloc_coherent(NULL,
  57866. - size,
  57867. - &buf_phys, GFP_KERNEL);
  57868. + buf_virt = gen_pool_dma_alloc(sdma->iram_pool, size, &buf_phys);
  57869. if (!buf_virt) {
  57870. - return -ENOMEM;
  57871. + use_iram = false;
  57872. + buf_virt = dma_alloc_coherent(NULL, size, &buf_phys, GFP_KERNEL);
  57873. + if (!buf_virt)
  57874. + return -ENOMEM;
  57875. }
  57876. spin_lock_irqsave(&sdma->channel_0_lock, flags);
  57877. @@ -562,7 +578,10 @@
  57878. spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
  57879. - dma_free_coherent(NULL, size, buf_virt, buf_phys);
  57880. + if (use_iram)
  57881. + gen_pool_free(sdma->iram_pool, (unsigned long)buf_virt, size);
  57882. + else
  57883. + dma_free_coherent(NULL, size, buf_virt, buf_phys);
  57884. return ret;
  57885. }
  57886. @@ -593,6 +612,12 @@
  57887. static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
  57888. {
  57889. + if (sdmac->desc.callback)
  57890. + sdmac->desc.callback(sdmac->desc.callback_param);
  57891. +}
  57892. +
  57893. +static void sdma_update_channel_loop(struct sdma_channel *sdmac)
  57894. +{
  57895. struct sdma_buffer_descriptor *bd;
  57896. /*
  57897. @@ -607,15 +632,10 @@
  57898. if (bd->mode.status & BD_RROR)
  57899. sdmac->status = DMA_ERROR;
  57900. - else
  57901. - sdmac->status = DMA_IN_PROGRESS;
  57902. bd->mode.status |= BD_DONE;
  57903. sdmac->buf_tail++;
  57904. sdmac->buf_tail %= sdmac->num_bd;
  57905. -
  57906. - if (sdmac->desc.callback)
  57907. - sdmac->desc.callback(sdmac->desc.callback_param);
  57908. }
  57909. }
  57910. @@ -647,14 +667,31 @@
  57911. sdmac->desc.callback(sdmac->desc.callback_param);
  57912. }
  57913. +static void sdma_handle_other_intr(struct sdma_channel *sdmac)
  57914. +{
  57915. + if (sdmac->desc.callback)
  57916. + sdmac->desc.callback(sdmac->desc.callback_param);
  57917. +}
  57918. +
  57919. static void sdma_tasklet(unsigned long data)
  57920. {
  57921. struct sdma_channel *sdmac = (struct sdma_channel *) data;
  57922. + struct sdma_engine *sdma = sdmac->sdma;
  57923. - if (sdmac->flags & IMX_DMA_SG_LOOP)
  57924. + switch (sdmac->mode) {
  57925. + case SDMA_MODE_LOOP:
  57926. sdma_handle_channel_loop(sdmac);
  57927. - else
  57928. + break;
  57929. + case SDMA_MODE_NORMAL:
  57930. mxc_sdma_handle_channel_normal(sdmac);
  57931. + break;
  57932. + case SDMA_MODE_NO_BD:
  57933. + sdma_handle_other_intr(sdmac);
  57934. + break;
  57935. + default:
  57936. + dev_err(sdma->dev, "invalid SDMA MODE!\n");
  57937. + break;
  57938. + }
  57939. }
  57940. static irqreturn_t sdma_int_handler(int irq, void *dev_id)
  57941. @@ -671,6 +708,9 @@
  57942. int channel = fls(stat) - 1;
  57943. struct sdma_channel *sdmac = &sdma->channel[channel];
  57944. + if (sdmac->mode & SDMA_MODE_LOOP)
  57945. + sdma_update_channel_loop(sdmac);
  57946. +
  57947. tasklet_schedule(&sdmac->tasklet);
  57948. __clear_bit(channel, &stat);
  57949. @@ -692,9 +732,12 @@
  57950. * two peripherals or memory-to-memory transfers
  57951. */
  57952. int per_2_per = 0, emi_2_emi = 0;
  57953. + int other = 0;
  57954. sdmac->pc_from_device = 0;
  57955. sdmac->pc_to_device = 0;
  57956. + sdmac->device_to_device = 0;
  57957. + sdmac->other_script = 0;
  57958. switch (peripheral_type) {
  57959. case IMX_DMATYPE_MEMORY:
  57960. @@ -740,8 +783,8 @@
  57961. emi_2_per = sdma->script_addrs->mcu_2_shp_addr;
  57962. break;
  57963. case IMX_DMATYPE_ASRC:
  57964. - per_2_emi = sdma->script_addrs->asrc_2_mcu_addr;
  57965. - emi_2_per = sdma->script_addrs->asrc_2_mcu_addr;
  57966. + per_2_emi = sdma->script_addrs->shp_2_mcu_addr;
  57967. + emi_2_per = sdma->script_addrs->mcu_2_shp_addr;
  57968. per_2_per = sdma->script_addrs->per_2_per_addr;
  57969. break;
  57970. case IMX_DMATYPE_MSHC:
  57971. @@ -758,12 +801,17 @@
  57972. case IMX_DMATYPE_IPU_MEMORY:
  57973. emi_2_per = sdma->script_addrs->ext_mem_2_ipu_addr;
  57974. break;
  57975. + case IMX_DMATYPE_HDMI:
  57976. + other = sdma->script_addrs->hdmi_dma_addr;
  57977. + break;
  57978. default:
  57979. break;
  57980. }
  57981. sdmac->pc_from_device = per_2_emi;
  57982. sdmac->pc_to_device = emi_2_per;
  57983. + sdmac->device_to_device = per_2_per;
  57984. + sdmac->other_script = other;
  57985. }
  57986. static int sdma_load_context(struct sdma_channel *sdmac)
  57987. @@ -776,11 +824,14 @@
  57988. int ret;
  57989. unsigned long flags;
  57990. - if (sdmac->direction == DMA_DEV_TO_MEM) {
  57991. + if (sdmac->direction == DMA_DEV_TO_MEM)
  57992. load_address = sdmac->pc_from_device;
  57993. - } else {
  57994. + else if (sdmac->direction == DMA_DEV_TO_DEV)
  57995. + load_address = sdmac->device_to_device;
  57996. + else if (sdmac->direction == DMA_MEM_TO_DEV)
  57997. load_address = sdmac->pc_to_device;
  57998. - }
  57999. + else
  58000. + load_address = sdmac->other_script;
  58001. if (load_address < 0)
  58002. return load_address;
  58003. @@ -800,11 +851,16 @@
  58004. /* Send by context the event mask,base address for peripheral
  58005. * and watermark level
  58006. */
  58007. - context->gReg[0] = sdmac->event_mask[1];
  58008. - context->gReg[1] = sdmac->event_mask[0];
  58009. - context->gReg[2] = sdmac->per_addr;
  58010. - context->gReg[6] = sdmac->shp_addr;
  58011. - context->gReg[7] = sdmac->watermark_level;
  58012. + if (sdmac->peripheral_type == IMX_DMATYPE_HDMI) {
  58013. + context->gReg[4] = sdmac->data_addr1;
  58014. + context->gReg[6] = sdmac->data_addr2;
  58015. + } else {
  58016. + context->gReg[0] = sdmac->event_mask[1];
  58017. + context->gReg[1] = sdmac->event_mask[0];
  58018. + context->gReg[2] = sdmac->per_addr;
  58019. + context->gReg[6] = sdmac->shp_addr;
  58020. + context->gReg[7] = sdmac->watermark_level;
  58021. + }
  58022. bd0->mode.command = C0_SETDM;
  58023. bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
  58024. @@ -829,6 +885,7 @@
  58025. static int sdma_config_channel(struct sdma_channel *sdmac)
  58026. {
  58027. + struct imx_dma_data *data = sdmac->chan.private;
  58028. int ret;
  58029. sdma_disable_channel(sdmac);
  58030. @@ -837,12 +894,19 @@
  58031. sdmac->event_mask[1] = 0;
  58032. sdmac->shp_addr = 0;
  58033. sdmac->per_addr = 0;
  58034. + sdmac->data_addr1 = 0;
  58035. + sdmac->data_addr2 = 0;
  58036. if (sdmac->event_id0) {
  58037. if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
  58038. return -EINVAL;
  58039. sdma_event_enable(sdmac, sdmac->event_id0);
  58040. }
  58041. + if (sdmac->event_id1) {
  58042. + if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events)
  58043. + return -EINVAL;
  58044. + sdma_event_enable(sdmac, sdmac->event_id1);
  58045. + }
  58046. switch (sdmac->peripheral_type) {
  58047. case IMX_DMATYPE_DSP:
  58048. @@ -862,19 +926,75 @@
  58049. (sdmac->peripheral_type != IMX_DMATYPE_DSP)) {
  58050. /* Handle multiple event channels differently */
  58051. if (sdmac->event_id1) {
  58052. - sdmac->event_mask[1] = BIT(sdmac->event_id1 % 32);
  58053. - if (sdmac->event_id1 > 31)
  58054. - __set_bit(31, &sdmac->watermark_level);
  58055. - sdmac->event_mask[0] = BIT(sdmac->event_id0 % 32);
  58056. - if (sdmac->event_id0 > 31)
  58057. - __set_bit(30, &sdmac->watermark_level);
  58058. + if (sdmac->event_id0 > 31) {
  58059. + sdmac->event_mask[0] |= 0;
  58060. + __set_bit(28, &sdmac->watermark_level);
  58061. + sdmac->event_mask[1] |=
  58062. + BIT(sdmac->event_id0 % 32);
  58063. + } else {
  58064. + sdmac->event_mask[1] |= 0;
  58065. + sdmac->event_mask[0] |=
  58066. + BIT(sdmac->event_id0 % 32);
  58067. + }
  58068. + if (sdmac->event_id1 > 31) {
  58069. + sdmac->event_mask[0] |= 0;
  58070. + __set_bit(29, &sdmac->watermark_level);
  58071. + sdmac->event_mask[1] |=
  58072. + BIT(sdmac->event_id1 % 32);
  58073. + } else {
  58074. + sdmac->event_mask[1] |= 0;
  58075. + sdmac->event_mask[0] |=
  58076. + BIT(sdmac->event_id1 % 32);
  58077. + }
  58078. + /* BIT 11:
  58079. + * 1 : Source on SPBA
  58080. + * 0 : Source on AIPS
  58081. + */
  58082. + __set_bit(11, &sdmac->watermark_level);
  58083. + /* BIT 12:
  58084. + * 1 : Destination on SPBA
  58085. + * 0 : Destination on AIPS
  58086. + */
  58087. + __set_bit(12, &sdmac->watermark_level);
  58088. + __set_bit(31, &sdmac->watermark_level);
  58089. + /* BIT 31:
  58090. + * 1 : Amount of samples to be transferred is
  58091. + * unknown and script will keep on transferring
  58092. + * samples as long as both events are detected
  58093. + * and script must be manually stopped by the
  58094. + * application.
  58095. + * 0 : The amount of samples to be is equal to
  58096. + * the count field of mode word
  58097. + * */
  58098. + __set_bit(25, &sdmac->watermark_level);
  58099. + __clear_bit(24, &sdmac->watermark_level);
  58100. } else {
  58101. - __set_bit(sdmac->event_id0, sdmac->event_mask);
  58102. + if (sdmac->event_id0 > 31) {
  58103. + sdmac->event_mask[0] = 0;
  58104. + sdmac->event_mask[1] |=
  58105. + BIT(sdmac->event_id0 % 32);
  58106. + } else {
  58107. + sdmac->event_mask[0] |=
  58108. + BIT(sdmac->event_id0 % 32);
  58109. + sdmac->event_mask[1] = 0;
  58110. + }
  58111. }
  58112. /* Watermark Level */
  58113. sdmac->watermark_level |= sdmac->watermark_level;
  58114. /* Address */
  58115. - sdmac->shp_addr = sdmac->per_address;
  58116. + if (sdmac->direction == DMA_DEV_TO_DEV) {
  58117. + sdmac->shp_addr = sdmac->per_address2;
  58118. + sdmac->per_addr = sdmac->per_address;
  58119. + } else if (sdmac->direction == DMA_TRANS_NONE) {
  58120. + if (sdmac->peripheral_type != IMX_DMATYPE_HDMI ||
  58121. + !data->data_addr1 || !data->data_addr2)
  58122. + return -EINVAL;
  58123. + sdmac->data_addr1 = *(u32 *)data->data_addr1;
  58124. + sdmac->data_addr2 = *(u32 *)data->data_addr2;
  58125. + sdmac->watermark_level = 0;
  58126. + } else {
  58127. + sdmac->shp_addr = sdmac->per_address;
  58128. + }
  58129. } else {
  58130. sdmac->watermark_level = 0; /* FIXME: M3_BASE_ADDRESS */
  58131. }
  58132. @@ -906,10 +1026,15 @@
  58133. int channel = sdmac->channel;
  58134. int ret = -EBUSY;
  58135. - sdmac->bd = dma_alloc_coherent(NULL, PAGE_SIZE, &sdmac->bd_phys, GFP_KERNEL);
  58136. + sdmac->bd_iram = true;
  58137. + sdmac->bd = gen_pool_dma_alloc(sdma->iram_pool, PAGE_SIZE, &sdmac->bd_phys);
  58138. if (!sdmac->bd) {
  58139. - ret = -ENOMEM;
  58140. - goto out;
  58141. + sdmac->bd_iram = false;
  58142. + sdmac->bd = dma_alloc_coherent(NULL, PAGE_SIZE, &sdmac->bd_phys, GFP_KERNEL);
  58143. + if (!sdmac->bd) {
  58144. + ret = -ENOMEM;
  58145. + goto out;
  58146. + }
  58147. }
  58148. memset(sdmac->bd, 0, PAGE_SIZE);
  58149. @@ -967,7 +1092,8 @@
  58150. }
  58151. sdmac->peripheral_type = data->peripheral_type;
  58152. - sdmac->event_id0 = data->dma_request;
  58153. + sdmac->event_id0 = data->dma_request0;
  58154. + sdmac->event_id1 = data->dma_request1;
  58155. clk_enable(sdmac->sdma->clk_ipg);
  58156. clk_enable(sdmac->sdma->clk_ahb);
  58157. @@ -985,6 +1111,9 @@
  58158. /* txd.flags will be overwritten in prep funcs */
  58159. sdmac->desc.flags = DMA_CTRL_ACK;
  58160. + /* Set SDMA channel mode to unvalid to avoid misconfig */
  58161. + sdmac->mode = SDMA_MODE_INVALID;
  58162. +
  58163. return 0;
  58164. }
  58165. @@ -1005,7 +1134,10 @@
  58166. sdma_set_channel_priority(sdmac, 0);
  58167. - dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys);
  58168. + if (sdmac->bd_iram)
  58169. + gen_pool_free(sdma->iram_pool, (unsigned long)sdmac->bd, PAGE_SIZE);
  58170. + else
  58171. + dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys);
  58172. clk_disable(sdma->clk_ipg);
  58173. clk_disable(sdma->clk_ahb);
  58174. @@ -1026,7 +1158,7 @@
  58175. return NULL;
  58176. sdmac->status = DMA_IN_PROGRESS;
  58177. - sdmac->flags = 0;
  58178. + sdmac->mode = SDMA_MODE_NORMAL;
  58179. sdmac->buf_tail = 0;
  58180. @@ -1119,9 +1251,9 @@
  58181. {
  58182. struct sdma_channel *sdmac = to_sdma_chan(chan);
  58183. struct sdma_engine *sdma = sdmac->sdma;
  58184. - int num_periods = buf_len / period_len;
  58185. int channel = sdmac->channel;
  58186. int ret, i = 0, buf = 0;
  58187. + int num_periods;
  58188. dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
  58189. @@ -1131,13 +1263,35 @@
  58190. sdmac->status = DMA_IN_PROGRESS;
  58191. sdmac->buf_tail = 0;
  58192. + sdmac->period_len = period_len;
  58193. - sdmac->flags |= IMX_DMA_SG_LOOP;
  58194. sdmac->direction = direction;
  58195. +
  58196. + switch (sdmac->direction) {
  58197. + case DMA_DEV_TO_DEV:
  58198. + sdmac->mode = SDMA_MODE_P2P;
  58199. + break;
  58200. + case DMA_TRANS_NONE:
  58201. + sdmac->mode = SDMA_MODE_NO_BD;
  58202. + break;
  58203. + case DMA_MEM_TO_DEV:
  58204. + case DMA_DEV_TO_MEM:
  58205. + sdmac->mode = SDMA_MODE_LOOP;
  58206. + break;
  58207. + default:
  58208. + dev_err(sdma->dev, "invalid SDMA direction %d\n", direction);
  58209. + return NULL;
  58210. + }
  58211. +
  58212. ret = sdma_load_context(sdmac);
  58213. if (ret)
  58214. goto err_out;
  58215. + if (period_len)
  58216. + num_periods = buf_len / period_len;
  58217. + else
  58218. + return &sdmac->desc;
  58219. +
  58220. if (num_periods > NUM_BD) {
  58221. dev_err(sdma->dev, "SDMA channel %d: maximum number of sg exceeded: %d > %d\n",
  58222. channel, num_periods, NUM_BD);
  58223. @@ -1202,18 +1356,31 @@
  58224. sdma_disable_channel(sdmac);
  58225. return 0;
  58226. case DMA_SLAVE_CONFIG:
  58227. - if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
  58228. + if (dmaengine_cfg->direction == DMA_DEV_TO_DEV) {
  58229. + sdmac->per_address = dmaengine_cfg->src_addr;
  58230. + sdmac->per_address2 = dmaengine_cfg->dst_addr;
  58231. + sdmac->watermark_level = 0;
  58232. + sdmac->watermark_level |=
  58233. + dmaengine_cfg->src_maxburst;
  58234. + sdmac->watermark_level |=
  58235. + dmaengine_cfg->dst_maxburst << 16;
  58236. + sdmac->word_size = dmaengine_cfg->dst_addr_width;
  58237. + } else if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
  58238. sdmac->per_address = dmaengine_cfg->src_addr;
  58239. sdmac->watermark_level = dmaengine_cfg->src_maxburst *
  58240. dmaengine_cfg->src_addr_width;
  58241. sdmac->word_size = dmaengine_cfg->src_addr_width;
  58242. - } else {
  58243. + } else if (dmaengine_cfg->direction == DMA_MEM_TO_DEV) {
  58244. sdmac->per_address = dmaengine_cfg->dst_addr;
  58245. sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
  58246. dmaengine_cfg->dst_addr_width;
  58247. sdmac->word_size = dmaengine_cfg->dst_addr_width;
  58248. }
  58249. sdmac->direction = dmaengine_cfg->direction;
  58250. + if (dmaengine_cfg->dma_request0)
  58251. + sdmac->event_id0 = dmaengine_cfg->dma_request0;
  58252. + if (dmaengine_cfg->dma_request1)
  58253. + sdmac->event_id1 = dmaengine_cfg->dma_request1;
  58254. return sdma_config_channel(sdmac);
  58255. default:
  58256. return -ENOSYS;
  58257. @@ -1227,9 +1394,15 @@
  58258. struct dma_tx_state *txstate)
  58259. {
  58260. struct sdma_channel *sdmac = to_sdma_chan(chan);
  58261. + u32 residue;
  58262. +
  58263. + if (sdmac->mode & SDMA_MODE_LOOP)
  58264. + residue = (sdmac->num_bd - sdmac->buf_tail) * sdmac->period_len;
  58265. + else
  58266. + residue = sdmac->chn_count - sdmac->chn_real_count;
  58267. dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie,
  58268. - sdmac->chn_count - sdmac->chn_real_count);
  58269. + residue);
  58270. return sdmac->status;
  58271. }
  58272. @@ -1285,7 +1458,10 @@
  58273. goto err_firmware;
  58274. switch (header->version_major) {
  58275. case 1:
  58276. - sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
  58277. + if (header->version_minor > 0)
  58278. + sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
  58279. + else
  58280. + sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
  58281. break;
  58282. case 2:
  58283. sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
  58284. @@ -1331,7 +1507,7 @@
  58285. static int __init sdma_init(struct sdma_engine *sdma)
  58286. {
  58287. - int i, ret;
  58288. + int i, ret, ccbsize;
  58289. dma_addr_t ccb_phys;
  58290. clk_enable(sdma->clk_ipg);
  58291. @@ -1340,14 +1516,17 @@
  58292. /* Be sure SDMA has not started yet */
  58293. writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
  58294. - sdma->channel_control = dma_alloc_coherent(NULL,
  58295. - MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control) +
  58296. - sizeof(struct sdma_context_data),
  58297. - &ccb_phys, GFP_KERNEL);
  58298. + ccbsize = MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control)
  58299. + + sizeof(struct sdma_context_data);
  58300. + sdma->channel_control = gen_pool_dma_alloc(sdma->iram_pool, ccbsize, &ccb_phys);
  58301. if (!sdma->channel_control) {
  58302. - ret = -ENOMEM;
  58303. - goto err_dma_alloc;
  58304. + sdma->channel_control = dma_alloc_coherent(NULL, ccbsize,
  58305. + &ccb_phys, GFP_KERNEL);
  58306. + if (!sdma->channel_control) {
  58307. + ret = -ENOMEM;
  58308. + goto err_dma_alloc;
  58309. + }
  58310. }
  58311. sdma->context = (void *)sdma->channel_control +
  58312. @@ -1422,9 +1601,10 @@
  58313. if (dma_spec->args_count != 3)
  58314. return NULL;
  58315. - data.dma_request = dma_spec->args[0];
  58316. + data.dma_request0 = dma_spec->args[0];
  58317. data.peripheral_type = dma_spec->args[1];
  58318. data.priority = dma_spec->args[2];
  58319. + data.dma_request1 = 0;
  58320. return dma_request_channel(mask, sdma_filter_fn, &data);
  58321. }
  58322. @@ -1542,6 +1722,11 @@
  58323. &sdma->dma_device.channels);
  58324. }
  58325. + if (np)
  58326. + sdma->iram_pool = of_get_named_gen_pool(np, "iram", 0);
  58327. + if (!sdma->iram_pool)
  58328. + dev_warn(&pdev->dev, "no iram assigned, using external mem\n");
  58329. +
  58330. ret = sdma_init(sdma);
  58331. if (ret)
  58332. goto err_init;
  58333. diff -Nur linux-3.14.15/drivers/dma/Kconfig linux-linaro-stable-mx6/drivers/dma/Kconfig
  58334. --- linux-3.14.15/drivers/dma/Kconfig 2014-07-31 23:51:43.000000000 +0200
  58335. +++ linux-linaro-stable-mx6/drivers/dma/Kconfig 2014-08-20 19:31:42.808854753 +0200
  58336. @@ -137,6 +137,19 @@
  58337. To avoid bloating the irq_desc[] array we allocate a sufficient
  58338. number of IRQ slots and map them dynamically to specific sources.
  58339. +config MXC_PXP_V2
  58340. + bool "MXC PxP V2 support"
  58341. + depends on ARM
  58342. + select DMA_ENGINE
  58343. + help
  58344. + Support the PxP (Pixel Pipeline) on i.MX6 DualLite and i.MX6 SoloLite.
  58345. + If unsure, select N.
  58346. +
  58347. +config MXC_PXP_CLIENT_DEVICE
  58348. + bool "MXC PxP Client Device"
  58349. + default y
  58350. + depends on MXC_PXP_V2
  58351. +
  58352. config TXX9_DMAC
  58353. tristate "Toshiba TXx9 SoC DMA support"
  58354. depends on MACH_TX49XX || MACH_TX39XX
  58355. diff -Nur linux-3.14.15/drivers/dma/Makefile linux-linaro-stable-mx6/drivers/dma/Makefile
  58356. --- linux-3.14.15/drivers/dma/Makefile 2014-07-31 23:51:43.000000000 +0200
  58357. +++ linux-linaro-stable-mx6/drivers/dma/Makefile 2014-08-20 19:31:42.808854753 +0200
  58358. @@ -18,6 +18,7 @@
  58359. obj-$(CONFIG_DW_DMAC_CORE) += dw/
  58360. obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
  58361. obj-$(CONFIG_MX3_IPU) += ipu/
  58362. +obj-$(CONFIG_MXC_PXP_V2) += pxp/
  58363. obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
  58364. obj-$(CONFIG_SH_DMAE_BASE) += sh/
  58365. obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
  58366. diff -Nur linux-3.14.15/drivers/dma/pxp/Makefile linux-linaro-stable-mx6/drivers/dma/pxp/Makefile
  58367. --- linux-3.14.15/drivers/dma/pxp/Makefile 1970-01-01 01:00:00.000000000 +0100
  58368. +++ linux-linaro-stable-mx6/drivers/dma/pxp/Makefile 2014-08-20 19:23:50.894834465 +0200
  58369. @@ -0,0 +1,2 @@
  58370. +obj-$(CONFIG_MXC_PXP_V2) += pxp_dma_v2.o
  58371. +obj-$(CONFIG_MXC_PXP_CLIENT_DEVICE) += pxp_device.o
  58372. diff -Nur linux-3.14.15/drivers/dma/pxp/pxp_device.c linux-linaro-stable-mx6/drivers/dma/pxp/pxp_device.c
  58373. --- linux-3.14.15/drivers/dma/pxp/pxp_device.c 1970-01-01 01:00:00.000000000 +0100
  58374. +++ linux-linaro-stable-mx6/drivers/dma/pxp/pxp_device.c 2014-08-20 19:31:42.824854823 +0200
  58375. @@ -0,0 +1,765 @@
  58376. +/*
  58377. + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  58378. + *
  58379. + * This program is free software; you can redistribute it and/or modify
  58380. + * it under the terms of the GNU General Public License as published by
  58381. + * the Free Software Foundation; either version 2 of the License, or
  58382. + * (at your option) any later version.
  58383. + *
  58384. + * This program is distributed in the hope that it will be useful,
  58385. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  58386. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  58387. + * GNU General Public License for more details.
  58388. + *
  58389. + * You should have received a copy of the GNU General Public License
  58390. + * along with this program; if not, write to the Free Software
  58391. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  58392. + *
  58393. + */
  58394. +#include <linux/interrupt.h>
  58395. +#include <linux/miscdevice.h>
  58396. +#include <linux/platform_device.h>
  58397. +#include <linux/fs.h>
  58398. +#include <linux/slab.h>
  58399. +#include <linux/uaccess.h>
  58400. +#include <linux/delay.h>
  58401. +#include <linux/dmaengine.h>
  58402. +#include <linux/dma-mapping.h>
  58403. +#include <linux/sched.h>
  58404. +#include <linux/module.h>
  58405. +#include <linux/pxp_device.h>
  58406. +#include <linux/atomic.h>
  58407. +#include <linux/platform_data/dma-imx.h>
  58408. +
  58409. +#define BUFFER_HASH_ORDER 4
  58410. +
  58411. +static struct pxp_buffer_hash bufhash;
  58412. +static struct pxp_irq_info irq_info[NR_PXP_VIRT_CHANNEL];
  58413. +
  58414. +static int pxp_ht_create(struct pxp_buffer_hash *hash, int order)
  58415. +{
  58416. + unsigned long i;
  58417. + unsigned long table_size;
  58418. +
  58419. + table_size = 1U << order;
  58420. +
  58421. + hash->order = order;
  58422. + hash->hash_table = kmalloc(sizeof(*hash->hash_table) * table_size, GFP_KERNEL);
  58423. +
  58424. + if (!hash->hash_table) {
  58425. + pr_err("%s: Out of memory for hash table\n", __func__);
  58426. + return -ENOMEM;
  58427. + }
  58428. +
  58429. + for (i = 0; i < table_size; i++)
  58430. + INIT_HLIST_HEAD(&hash->hash_table[i]);
  58431. +
  58432. + return 0;
  58433. +}
  58434. +
  58435. +static int pxp_ht_insert_item(struct pxp_buffer_hash *hash,
  58436. + struct pxp_buf_obj *new)
  58437. +{
  58438. + unsigned long hashkey;
  58439. + struct hlist_head *h_list;
  58440. +
  58441. + hashkey = hash_long(new->offset >> PAGE_SHIFT, hash->order);
  58442. + h_list = &hash->hash_table[hashkey];
  58443. +
  58444. + spin_lock(&hash->hash_lock);
  58445. + hlist_add_head_rcu(&new->item, h_list);
  58446. + spin_unlock(&hash->hash_lock);
  58447. +
  58448. + return 0;
  58449. +}
  58450. +
  58451. +static int pxp_ht_remove_item(struct pxp_buffer_hash *hash,
  58452. + struct pxp_buf_obj *obj)
  58453. +{
  58454. + spin_lock(&hash->hash_lock);
  58455. + hlist_del_init_rcu(&obj->item);
  58456. + spin_unlock(&hash->hash_lock);
  58457. + return 0;
  58458. +}
  58459. +
  58460. +static struct hlist_node *pxp_ht_find_key(struct pxp_buffer_hash *hash,
  58461. + unsigned long key)
  58462. +{
  58463. + struct pxp_buf_obj *entry;
  58464. + struct hlist_head *h_list;
  58465. + unsigned long hashkey;
  58466. +
  58467. + hashkey = hash_long(key, hash->order);
  58468. + h_list = &hash->hash_table[hashkey];
  58469. +
  58470. + hlist_for_each_entry_rcu(entry, h_list, item) {
  58471. + if (entry->offset >> PAGE_SHIFT == key)
  58472. + return &entry->item;
  58473. + }
  58474. +
  58475. + return NULL;
  58476. +}
  58477. +
  58478. +static void pxp_ht_destroy(struct pxp_buffer_hash *hash)
  58479. +{
  58480. + kfree(hash->hash_table);
  58481. + hash->hash_table = NULL;
  58482. +}
  58483. +
  58484. +static int pxp_buffer_handle_create(struct pxp_file *file_priv,
  58485. + struct pxp_buf_obj *obj,
  58486. + uint32_t *handlep)
  58487. +{
  58488. + int ret;
  58489. +
  58490. + idr_preload(GFP_KERNEL);
  58491. + spin_lock(&file_priv->buffer_lock);
  58492. +
  58493. + ret = idr_alloc(&file_priv->buffer_idr, obj, 1, 0, GFP_NOWAIT);
  58494. +
  58495. + spin_unlock(&file_priv->buffer_lock);
  58496. + idr_preload_end();
  58497. +
  58498. + if (ret < 0)
  58499. + return ret;
  58500. +
  58501. + *handlep = ret;
  58502. +
  58503. + return 0;
  58504. +}
  58505. +
  58506. +static struct pxp_buf_obj *
  58507. +pxp_buffer_object_lookup(struct pxp_file *file_priv,
  58508. + uint32_t handle)
  58509. +{
  58510. + struct pxp_buf_obj *obj;
  58511. +
  58512. + spin_lock(&file_priv->buffer_lock);
  58513. +
  58514. + obj = idr_find(&file_priv->buffer_idr, handle);
  58515. + if (!obj) {
  58516. + spin_unlock(&file_priv->buffer_lock);
  58517. + return NULL;
  58518. + }
  58519. +
  58520. + spin_unlock(&file_priv->buffer_lock);
  58521. +
  58522. + return obj;
  58523. +}
  58524. +
  58525. +static int pxp_buffer_handle_delete(struct pxp_file *file_priv,
  58526. + uint32_t handle)
  58527. +{
  58528. + struct pxp_buf_obj *obj;
  58529. +
  58530. + spin_lock(&file_priv->buffer_lock);
  58531. +
  58532. + obj = idr_find(&file_priv->buffer_idr, handle);
  58533. + if (!obj) {
  58534. + spin_unlock(&file_priv->buffer_lock);
  58535. + return -EINVAL;
  58536. + }
  58537. +
  58538. + idr_remove(&file_priv->buffer_idr, handle);
  58539. + spin_unlock(&file_priv->buffer_lock);
  58540. +
  58541. + return 0;
  58542. +}
  58543. +
  58544. +static int pxp_channel_handle_create(struct pxp_file *file_priv,
  58545. + struct pxp_chan_obj *obj,
  58546. + uint32_t *handlep)
  58547. +{
  58548. + int ret;
  58549. +
  58550. + idr_preload(GFP_KERNEL);
  58551. + spin_lock(&file_priv->channel_lock);
  58552. +
  58553. + ret = idr_alloc(&file_priv->channel_idr, obj, 0, 0, GFP_NOWAIT);
  58554. +
  58555. + spin_unlock(&file_priv->channel_lock);
  58556. + idr_preload_end();
  58557. +
  58558. + if (ret < 0)
  58559. + return ret;
  58560. +
  58561. + *handlep = ret;
  58562. +
  58563. + return 0;
  58564. +}
  58565. +
  58566. +static struct pxp_chan_obj *
  58567. +pxp_channel_object_lookup(struct pxp_file *file_priv,
  58568. + uint32_t handle)
  58569. +{
  58570. + struct pxp_chan_obj *obj;
  58571. +
  58572. + spin_lock(&file_priv->channel_lock);
  58573. +
  58574. + obj = idr_find(&file_priv->channel_idr, handle);
  58575. + if (!obj) {
  58576. + spin_unlock(&file_priv->channel_lock);
  58577. + return NULL;
  58578. + }
  58579. +
  58580. + spin_unlock(&file_priv->channel_lock);
  58581. +
  58582. + return obj;
  58583. +}
  58584. +
  58585. +static int pxp_channel_handle_delete(struct pxp_file *file_priv,
  58586. + uint32_t handle)
  58587. +{
  58588. + struct pxp_chan_obj *obj;
  58589. +
  58590. + spin_lock(&file_priv->channel_lock);
  58591. +
  58592. + obj = idr_find(&file_priv->channel_idr, handle);
  58593. + if (!obj) {
  58594. + spin_unlock(&file_priv->channel_lock);
  58595. + return -EINVAL;
  58596. + }
  58597. +
  58598. + idr_remove(&file_priv->channel_idr, handle);
  58599. + spin_unlock(&file_priv->channel_lock);
  58600. +
  58601. + return 0;
  58602. +}
  58603. +
  58604. +static int pxp_alloc_dma_buffer(struct pxp_buf_obj *obj)
  58605. +{
  58606. + obj->virtual = dma_alloc_coherent(NULL, PAGE_ALIGN(obj->size),
  58607. + (dma_addr_t *) (&obj->offset),
  58608. + GFP_DMA | GFP_KERNEL);
  58609. + pr_debug("[ALLOC] mem alloc phys_addr = 0x%lx\n", obj->offset);
  58610. +
  58611. + if (obj->virtual == NULL) {
  58612. + printk(KERN_ERR "Physical memory allocation error!\n");
  58613. + return -1;
  58614. + }
  58615. +
  58616. + return 0;
  58617. +}
  58618. +
  58619. +static void pxp_free_dma_buffer(struct pxp_buf_obj *obj)
  58620. +{
  58621. + if (obj->virtual != NULL) {
  58622. + dma_free_coherent(0, PAGE_ALIGN(obj->size),
  58623. + obj->virtual, (dma_addr_t)obj->offset);
  58624. + }
  58625. +}
  58626. +
  58627. +static int
  58628. +pxp_buffer_object_free(int id, void *ptr, void *data)
  58629. +{
  58630. + struct pxp_file *file_priv = data;
  58631. + struct pxp_buf_obj *obj = ptr;
  58632. + int ret;
  58633. +
  58634. + ret = pxp_buffer_handle_delete(file_priv, obj->handle);
  58635. + if (ret < 0)
  58636. + return ret;
  58637. +
  58638. + pxp_ht_remove_item(&bufhash, obj);
  58639. + pxp_free_dma_buffer(obj);
  58640. + kfree(obj);
  58641. +
  58642. + return 0;
  58643. +}
  58644. +
  58645. +static int
  58646. +pxp_channel_object_free(int id, void *ptr, void *data)
  58647. +{
  58648. + struct pxp_file *file_priv = data;
  58649. + struct pxp_chan_obj *obj = ptr;
  58650. + int chan_id;
  58651. +
  58652. + chan_id = obj->chan->chan_id;
  58653. + wait_event(irq_info[chan_id].waitq,
  58654. + atomic_read(&irq_info[chan_id].irq_pending) == 0);
  58655. +
  58656. + pxp_channel_handle_delete(file_priv, obj->handle);
  58657. + dma_release_channel(obj->chan);
  58658. + kfree(obj);
  58659. +
  58660. + return 0;
  58661. +}
  58662. +
  58663. +static void pxp_free_buffers(struct pxp_file *file_priv)
  58664. +{
  58665. + idr_for_each(&file_priv->buffer_idr,
  58666. + &pxp_buffer_object_free, file_priv);
  58667. + idr_destroy(&file_priv->buffer_idr);
  58668. +}
  58669. +
  58670. +static void pxp_free_channels(struct pxp_file *file_priv)
  58671. +{
  58672. + idr_for_each(&file_priv->channel_idr,
  58673. + &pxp_channel_object_free, file_priv);
  58674. + idr_destroy(&file_priv->channel_idr);
  58675. +}
  58676. +
  58677. +/* Callback function triggered after PxP receives an EOF interrupt */
  58678. +static void pxp_dma_done(void *arg)
  58679. +{
  58680. + struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
  58681. + struct dma_chan *chan = tx_desc->txd.chan;
  58682. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  58683. + int chan_id = pxp_chan->dma_chan.chan_id;
  58684. +
  58685. + pr_debug("DMA Done ISR, chan_id %d\n", chan_id);
  58686. +
  58687. + atomic_dec(&irq_info[chan_id].irq_pending);
  58688. + irq_info[chan_id].hist_status = tx_desc->hist_status;
  58689. +
  58690. + wake_up(&(irq_info[chan_id].waitq));
  58691. +}
  58692. +
  58693. +static int pxp_ioc_config_chan(struct pxp_file *priv, unsigned long arg)
  58694. +{
  58695. + struct scatterlist sg[3];
  58696. + struct pxp_tx_desc *desc;
  58697. + struct dma_async_tx_descriptor *txd;
  58698. + struct pxp_config_data pxp_conf;
  58699. + dma_cookie_t cookie;
  58700. + int handle, chan_id;
  58701. + int i, length, ret;
  58702. + struct dma_chan *chan;
  58703. + struct pxp_chan_obj *obj;
  58704. +
  58705. + ret = copy_from_user(&pxp_conf,
  58706. + (struct pxp_config_data *)arg,
  58707. + sizeof(struct pxp_config_data));
  58708. + if (ret)
  58709. + return -EFAULT;
  58710. +
  58711. + handle = pxp_conf.handle;
  58712. + obj = pxp_channel_object_lookup(priv, handle);
  58713. + if (!obj)
  58714. + return -EINVAL;
  58715. + chan = obj->chan;
  58716. + chan_id = chan->chan_id;
  58717. +
  58718. + sg_init_table(sg, 3);
  58719. +
  58720. + txd = chan->device->device_prep_slave_sg(chan,
  58721. + sg, 3,
  58722. + DMA_TO_DEVICE,
  58723. + DMA_PREP_INTERRUPT,
  58724. + NULL);
  58725. + if (!txd) {
  58726. + pr_err("Error preparing a DMA transaction descriptor.\n");
  58727. + return -EIO;
  58728. + }
  58729. +
  58730. + txd->callback_param = txd;
  58731. + txd->callback = pxp_dma_done;
  58732. +
  58733. + desc = to_tx_desc(txd);
  58734. +
  58735. + length = desc->len;
  58736. + for (i = 0; i < length; i++) {
  58737. + if (i == 0) { /* S0 */
  58738. + memcpy(&desc->proc_data,
  58739. + &pxp_conf.proc_data,
  58740. + sizeof(struct pxp_proc_data));
  58741. + memcpy(&desc->layer_param.s0_param,
  58742. + &pxp_conf.s0_param,
  58743. + sizeof(struct pxp_layer_param));
  58744. + } else if (i == 1) { /* Output */
  58745. + memcpy(&desc->layer_param.out_param,
  58746. + &pxp_conf.out_param,
  58747. + sizeof(struct pxp_layer_param));
  58748. + } else {
  58749. + /* OverLay */
  58750. + memcpy(&desc->layer_param.ol_param,
  58751. + &pxp_conf.ol_param,
  58752. + sizeof(struct pxp_layer_param));
  58753. + }
  58754. +
  58755. + desc = desc->next;
  58756. + }
  58757. +
  58758. + cookie = txd->tx_submit(txd);
  58759. + if (cookie < 0) {
  58760. + pr_err("Error tx_submit\n");
  58761. + return -EIO;
  58762. + }
  58763. +
  58764. + atomic_inc(&irq_info[chan_id].irq_pending);
  58765. +
  58766. + return 0;
  58767. +}
  58768. +
  58769. +static int pxp_device_open(struct inode *inode, struct file *filp)
  58770. +{
  58771. + struct pxp_file *priv;
  58772. +
  58773. + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  58774. +
  58775. + if (!priv)
  58776. + return -ENOMEM;
  58777. +
  58778. + filp->private_data = priv;
  58779. + priv->filp = filp;
  58780. +
  58781. + idr_init(&priv->buffer_idr);
  58782. + spin_lock_init(&priv->buffer_lock);
  58783. +
  58784. + idr_init(&priv->channel_idr);
  58785. + spin_lock_init(&priv->channel_lock);
  58786. +
  58787. + return 0;
  58788. +}
  58789. +
  58790. +static int pxp_device_release(struct inode *inode, struct file *filp)
  58791. +{
  58792. + struct pxp_file *priv = filp->private_data;
  58793. +
  58794. + if (priv) {
  58795. + pxp_free_channels(priv);
  58796. + pxp_free_buffers(priv);
  58797. + kfree(priv);
  58798. + filp->private_data = NULL;
  58799. + }
  58800. +
  58801. + return 0;
  58802. +}
  58803. +
  58804. +static int pxp_device_mmap(struct file *file, struct vm_area_struct *vma)
  58805. +{
  58806. + int request_size;
  58807. + struct hlist_node *node;
  58808. + struct pxp_buf_obj *obj;
  58809. +
  58810. + request_size = vma->vm_end - vma->vm_start;
  58811. +
  58812. + pr_debug("start=0x%x, pgoff=0x%x, size=0x%x\n",
  58813. + (unsigned int)(vma->vm_start), (unsigned int)(vma->vm_pgoff),
  58814. + request_size);
  58815. +
  58816. + node = pxp_ht_find_key(&bufhash, vma->vm_pgoff);
  58817. + if (!node)
  58818. + return -EINVAL;
  58819. +
  58820. + obj = list_entry(node, struct pxp_buf_obj, item);
  58821. + if (obj->offset + (obj->size >> PAGE_SHIFT) <
  58822. + (vma->vm_pgoff + vma_pages(vma)))
  58823. + return -ENOMEM;
  58824. +
  58825. + switch (obj->mem_type) {
  58826. + case MEMORY_TYPE_UNCACHED:
  58827. + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  58828. + break;
  58829. + case MEMORY_TYPE_WC:
  58830. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  58831. + break;
  58832. + case MEMORY_TYPE_CACHED:
  58833. + break;
  58834. + default:
  58835. + pr_err("%s: invalid memory type!\n", __func__);
  58836. + return -EINVAL;
  58837. + }
  58838. +
  58839. + return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  58840. + request_size, vma->vm_page_prot) ? -EAGAIN : 0;
  58841. +}
  58842. +
  58843. +static bool chan_filter(struct dma_chan *chan, void *arg)
  58844. +{
  58845. + if (imx_dma_is_pxp(chan))
  58846. + return true;
  58847. + else
  58848. + return false;
  58849. +}
  58850. +
  58851. +static long pxp_device_ioctl(struct file *filp,
  58852. + unsigned int cmd, unsigned long arg)
  58853. +{
  58854. + int ret = 0;
  58855. + struct pxp_file *file_priv = filp->private_data;
  58856. +
  58857. + switch (cmd) {
  58858. + case PXP_IOC_GET_CHAN:
  58859. + {
  58860. + int ret;
  58861. + struct dma_chan *chan = NULL;
  58862. + dma_cap_mask_t mask;
  58863. + struct pxp_chan_obj *obj = NULL;
  58864. +
  58865. + pr_debug("drv: PXP_IOC_GET_CHAN Line %d\n", __LINE__);
  58866. +
  58867. + dma_cap_zero(mask);
  58868. + dma_cap_set(DMA_SLAVE, mask);
  58869. + dma_cap_set(DMA_PRIVATE, mask);
  58870. +
  58871. + chan = dma_request_channel(mask, chan_filter, NULL);
  58872. + if (!chan) {
  58873. + pr_err("Unsccessfully received channel!\n");
  58874. + return -EBUSY;
  58875. + }
  58876. +
  58877. + pr_debug("Successfully received channel."
  58878. + "chan_id %d\n", chan->chan_id);
  58879. +
  58880. + obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  58881. + if (!obj) {
  58882. + dma_release_channel(chan);
  58883. + return -ENOMEM;
  58884. + }
  58885. + obj->chan = chan;
  58886. +
  58887. + ret = pxp_channel_handle_create(file_priv, obj,
  58888. + &obj->handle);
  58889. + if (ret) {
  58890. + dma_release_channel(chan);
  58891. + kfree(obj);
  58892. + return ret;
  58893. + }
  58894. +
  58895. + init_waitqueue_head(&(irq_info[chan->chan_id].waitq));
  58896. + if (put_user(obj->handle, (u32 __user *) arg)) {
  58897. + pxp_channel_handle_delete(file_priv, obj->handle);
  58898. + dma_release_channel(chan);
  58899. + kfree(obj);
  58900. + return -EFAULT;
  58901. + }
  58902. +
  58903. + break;
  58904. + }
  58905. + case PXP_IOC_PUT_CHAN:
  58906. + {
  58907. + int handle;
  58908. + struct pxp_chan_obj *obj;
  58909. +
  58910. + if (get_user(handle, (u32 __user *) arg))
  58911. + return -EFAULT;
  58912. +
  58913. + pr_debug("%d release handle %d\n", __LINE__, handle);
  58914. +
  58915. + obj = pxp_channel_object_lookup(file_priv, handle);
  58916. + if (!obj)
  58917. + return -EINVAL;
  58918. +
  58919. + pxp_channel_handle_delete(file_priv, obj->handle);
  58920. + dma_release_channel(obj->chan);
  58921. + kfree(obj);
  58922. +
  58923. + break;
  58924. + }
  58925. + case PXP_IOC_CONFIG_CHAN:
  58926. + {
  58927. + int ret;
  58928. +
  58929. + ret = pxp_ioc_config_chan(file_priv, arg);
  58930. + if (ret)
  58931. + return ret;
  58932. +
  58933. + break;
  58934. + }
  58935. + case PXP_IOC_START_CHAN:
  58936. + {
  58937. + int handle;
  58938. + struct pxp_chan_obj *obj = NULL;
  58939. +
  58940. + if (get_user(handle, (u32 __user *) arg))
  58941. + return -EFAULT;
  58942. +
  58943. + obj = pxp_channel_object_lookup(file_priv, handle);
  58944. + if (!obj)
  58945. + return -EINVAL;
  58946. +
  58947. + dma_async_issue_pending(obj->chan);
  58948. +
  58949. + break;
  58950. + }
  58951. + case PXP_IOC_GET_PHYMEM:
  58952. + {
  58953. + struct pxp_mem_desc buffer;
  58954. + struct pxp_buf_obj *obj;
  58955. +
  58956. + ret = copy_from_user(&buffer,
  58957. + (struct pxp_mem_desc *)arg,
  58958. + sizeof(struct pxp_mem_desc));
  58959. + if (ret)
  58960. + return -EFAULT;
  58961. +
  58962. + pr_debug("[ALLOC] mem alloc size = 0x%x\n",
  58963. + buffer.size);
  58964. +
  58965. + obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  58966. + if (!obj)
  58967. + return -ENOMEM;
  58968. + obj->size = buffer.size;
  58969. + obj->mem_type = buffer.mtype;
  58970. +
  58971. + ret = pxp_alloc_dma_buffer(obj);
  58972. + if (ret == -1) {
  58973. + printk(KERN_ERR
  58974. + "Physical memory allocation error!\n");
  58975. + kfree(obj);
  58976. + return ret;
  58977. + }
  58978. +
  58979. + ret = pxp_buffer_handle_create(file_priv, obj, &obj->handle);
  58980. + if (ret) {
  58981. + pxp_free_dma_buffer(obj);
  58982. + kfree(obj);
  58983. + return ret;
  58984. + }
  58985. + buffer.handle = obj->handle;
  58986. + buffer.phys_addr = obj->offset;
  58987. +
  58988. + ret = copy_to_user((void __user *)arg, &buffer,
  58989. + sizeof(struct pxp_mem_desc));
  58990. + if (ret) {
  58991. + pxp_buffer_handle_delete(file_priv, buffer.handle);
  58992. + pxp_free_dma_buffer(obj);
  58993. + kfree(obj);
  58994. + return -EFAULT;
  58995. + }
  58996. +
  58997. + pxp_ht_insert_item(&bufhash, obj);
  58998. +
  58999. + break;
  59000. + }
  59001. + case PXP_IOC_PUT_PHYMEM:
  59002. + {
  59003. + struct pxp_mem_desc pxp_mem;
  59004. + struct pxp_buf_obj *obj;
  59005. +
  59006. + ret = copy_from_user(&pxp_mem,
  59007. + (struct pxp_mem_desc *)arg,
  59008. + sizeof(struct pxp_mem_desc));
  59009. + if (ret)
  59010. + return -EACCES;
  59011. +
  59012. + obj = pxp_buffer_object_lookup(file_priv, pxp_mem.handle);
  59013. + if (!obj)
  59014. + return -EINVAL;
  59015. +
  59016. + ret = pxp_buffer_handle_delete(file_priv, obj->handle);
  59017. + if (ret)
  59018. + return ret;
  59019. +
  59020. + pxp_ht_remove_item(&bufhash, obj);
  59021. + pxp_free_dma_buffer(obj);
  59022. + kfree(obj);
  59023. +
  59024. + break;
  59025. + }
  59026. + case PXP_IOC_FLUSH_PHYMEM:
  59027. + {
  59028. + int ret;
  59029. + struct pxp_mem_flush flush;
  59030. + struct pxp_buf_obj *obj;
  59031. +
  59032. + ret = copy_from_user(&flush,
  59033. + (struct pxp_mem_flush *)arg,
  59034. + sizeof(struct pxp_mem_flush));
  59035. + if (ret)
  59036. + return -EACCES;
  59037. +
  59038. + obj = pxp_buffer_object_lookup(file_priv, flush.handle);
  59039. + if (!obj)
  59040. + return -EINVAL;
  59041. +
  59042. + switch (flush.type) {
  59043. + case CACHE_CLEAN:
  59044. + dma_sync_single_for_device(NULL, obj->offset,
  59045. + obj->size, DMA_TO_DEVICE);
  59046. + break;
  59047. + case CACHE_INVALIDATE:
  59048. + dma_sync_single_for_device(NULL, obj->offset,
  59049. + obj->size, DMA_FROM_DEVICE);
  59050. + break;
  59051. + case CACHE_FLUSH:
  59052. + dma_sync_single_for_device(NULL, obj->offset,
  59053. + obj->size, DMA_TO_DEVICE);
  59054. + dma_sync_single_for_device(NULL, obj->offset,
  59055. + obj->size, DMA_FROM_DEVICE);
  59056. + break;
  59057. + default:
  59058. + pr_err("%s: invalid cache flush type\n", __func__);
  59059. + return -EINVAL;
  59060. + }
  59061. +
  59062. + break;
  59063. + }
  59064. + case PXP_IOC_WAIT4CMPLT:
  59065. + {
  59066. + struct pxp_chan_handle chan_handle;
  59067. + int ret, chan_id, handle;
  59068. + struct pxp_chan_obj *obj = NULL;
  59069. +
  59070. + ret = copy_from_user(&chan_handle,
  59071. + (struct pxp_chan_handle *)arg,
  59072. + sizeof(struct pxp_chan_handle));
  59073. + if (ret)
  59074. + return -EFAULT;
  59075. +
  59076. + handle = chan_handle.handle;
  59077. + obj = pxp_channel_object_lookup(file_priv, handle);
  59078. + if (!obj)
  59079. + return -EINVAL;
  59080. + chan_id = obj->chan->chan_id;
  59081. +
  59082. + ret = wait_event_interruptible
  59083. + (irq_info[chan_id].waitq,
  59084. + (atomic_read(&irq_info[chan_id].irq_pending) == 0));
  59085. + if (ret < 0) {
  59086. + printk(KERN_WARNING
  59087. + "WAIT4CMPLT: signal received.\n");
  59088. + return -ERESTARTSYS;
  59089. + }
  59090. +
  59091. + chan_handle.hist_status = irq_info[chan_id].hist_status;
  59092. + ret = copy_to_user((struct pxp_chan_handle *)arg,
  59093. + &chan_handle,
  59094. + sizeof(struct pxp_chan_handle));
  59095. + if (ret)
  59096. + return -EFAULT;
  59097. + break;
  59098. + }
  59099. + default:
  59100. + break;
  59101. + }
  59102. +
  59103. + return 0;
  59104. +}
  59105. +
  59106. +static const struct file_operations pxp_device_fops = {
  59107. + .open = pxp_device_open,
  59108. + .release = pxp_device_release,
  59109. + .unlocked_ioctl = pxp_device_ioctl,
  59110. + .mmap = pxp_device_mmap,
  59111. +};
  59112. +
  59113. +static struct miscdevice pxp_device_miscdev = {
  59114. + .minor = MISC_DYNAMIC_MINOR,
  59115. + .name = "pxp_device",
  59116. + .fops = &pxp_device_fops,
  59117. +};
  59118. +
  59119. +int register_pxp_device(void)
  59120. +{
  59121. + int ret;
  59122. +
  59123. + ret = misc_register(&pxp_device_miscdev);
  59124. + if (ret)
  59125. + return ret;
  59126. +
  59127. + ret = pxp_ht_create(&bufhash, BUFFER_HASH_ORDER);
  59128. + if (ret)
  59129. + return ret;
  59130. + spin_lock_init(&(bufhash.hash_lock));
  59131. +
  59132. + pr_debug("PxP_Device registered Successfully\n");
  59133. + return 0;
  59134. +}
  59135. +
  59136. +void unregister_pxp_device(void)
  59137. +{
  59138. + pxp_ht_destroy(&bufhash);
  59139. + misc_deregister(&pxp_device_miscdev);
  59140. +}
  59141. diff -Nur linux-3.14.15/drivers/dma/pxp/pxp_dma_v2.c linux-linaro-stable-mx6/drivers/dma/pxp/pxp_dma_v2.c
  59142. --- linux-3.14.15/drivers/dma/pxp/pxp_dma_v2.c 1970-01-01 01:00:00.000000000 +0100
  59143. +++ linux-linaro-stable-mx6/drivers/dma/pxp/pxp_dma_v2.c 2014-08-20 19:31:42.824854823 +0200
  59144. @@ -0,0 +1,1854 @@
  59145. +/*
  59146. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
  59147. + *
  59148. + * This program is free software; you can redistribute it and/or modify
  59149. + * it under the terms of the GNU General Public License as published by
  59150. + * the Free Software Foundation; either version 2 of the License, or
  59151. + * (at your option) any later version.
  59152. + *
  59153. + * This program is distributed in the hope that it will be useful,
  59154. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  59155. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  59156. + * GNU General Public License for more details.
  59157. + *
  59158. + * You should have received a copy of the GNU General Public License
  59159. + * along with this program; if not, write to the Free Software
  59160. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  59161. + *
  59162. + */
  59163. +/*
  59164. + * Based on STMP378X PxP driver
  59165. + * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
  59166. + */
  59167. +
  59168. +#include <linux/dma-mapping.h>
  59169. +#include <linux/init.h>
  59170. +#include <linux/interrupt.h>
  59171. +#include <linux/io.h>
  59172. +#include <linux/kernel.h>
  59173. +#include <linux/module.h>
  59174. +#include <linux/mutex.h>
  59175. +#include <linux/platform_device.h>
  59176. +#include <linux/slab.h>
  59177. +#include <linux/vmalloc.h>
  59178. +#include <linux/dmaengine.h>
  59179. +#include <linux/pxp_dma.h>
  59180. +#include <linux/timer.h>
  59181. +#include <linux/clk.h>
  59182. +#include <linux/workqueue.h>
  59183. +#include <linux/sched.h>
  59184. +#include <linux/of.h>
  59185. +#include <linux/kthread.h>
  59186. +
  59187. +#include "regs-pxp_v2.h"
  59188. +
  59189. +#define PXP_DOWNSCALE_THRESHOLD 0x4000
  59190. +
  59191. +static LIST_HEAD(head);
  59192. +static int timeout_in_ms = 600;
  59193. +static unsigned int block_size;
  59194. +static struct kmem_cache *tx_desc_cache;
  59195. +
  59196. +struct pxp_dma {
  59197. + struct dma_device dma;
  59198. +};
  59199. +
  59200. +struct pxps {
  59201. + struct platform_device *pdev;
  59202. + struct clk *clk;
  59203. + void __iomem *base;
  59204. + int irq; /* PXP IRQ to the CPU */
  59205. +
  59206. + spinlock_t lock;
  59207. + struct mutex clk_mutex;
  59208. + int clk_stat;
  59209. +#define CLK_STAT_OFF 0
  59210. +#define CLK_STAT_ON 1
  59211. + int pxp_ongoing;
  59212. + int lut_state;
  59213. +
  59214. + struct device *dev;
  59215. + struct pxp_dma pxp_dma;
  59216. + struct pxp_channel channel[NR_PXP_VIRT_CHANNEL];
  59217. + struct work_struct work;
  59218. +
  59219. + /* describes most recent processing configuration */
  59220. + struct pxp_config_data pxp_conf_state;
  59221. +
  59222. + /* to turn clock off when pxp is inactive */
  59223. + struct timer_list clk_timer;
  59224. +
  59225. + /* for pxp config dispatch asynchronously*/
  59226. + struct task_struct *dispatch;
  59227. + wait_queue_head_t thread_waitq;
  59228. + struct completion complete;
  59229. +};
  59230. +
  59231. +#define to_pxp_dma(d) container_of(d, struct pxp_dma, dma)
  59232. +#define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
  59233. +#define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
  59234. +#define to_pxp(id) container_of(id, struct pxps, pxp_dma)
  59235. +
  59236. +#define PXP_DEF_BUFS 2
  59237. +#define PXP_MIN_PIX 8
  59238. +
  59239. +static uint32_t pxp_s0_formats[] = {
  59240. + PXP_PIX_FMT_RGB32,
  59241. + PXP_PIX_FMT_RGB565,
  59242. + PXP_PIX_FMT_RGB555,
  59243. + PXP_PIX_FMT_YUV420P,
  59244. + PXP_PIX_FMT_YUV422P,
  59245. +};
  59246. +
  59247. +/*
  59248. + * PXP common functions
  59249. + */
  59250. +static void dump_pxp_reg(struct pxps *pxp)
  59251. +{
  59252. + dev_dbg(pxp->dev, "PXP_CTRL 0x%x",
  59253. + __raw_readl(pxp->base + HW_PXP_CTRL));
  59254. + dev_dbg(pxp->dev, "PXP_STAT 0x%x",
  59255. + __raw_readl(pxp->base + HW_PXP_STAT));
  59256. + dev_dbg(pxp->dev, "PXP_OUT_CTRL 0x%x",
  59257. + __raw_readl(pxp->base + HW_PXP_OUT_CTRL));
  59258. + dev_dbg(pxp->dev, "PXP_OUT_BUF 0x%x",
  59259. + __raw_readl(pxp->base + HW_PXP_OUT_BUF));
  59260. + dev_dbg(pxp->dev, "PXP_OUT_BUF2 0x%x",
  59261. + __raw_readl(pxp->base + HW_PXP_OUT_BUF2));
  59262. + dev_dbg(pxp->dev, "PXP_OUT_PITCH 0x%x",
  59263. + __raw_readl(pxp->base + HW_PXP_OUT_PITCH));
  59264. + dev_dbg(pxp->dev, "PXP_OUT_LRC 0x%x",
  59265. + __raw_readl(pxp->base + HW_PXP_OUT_LRC));
  59266. + dev_dbg(pxp->dev, "PXP_OUT_PS_ULC 0x%x",
  59267. + __raw_readl(pxp->base + HW_PXP_OUT_PS_ULC));
  59268. + dev_dbg(pxp->dev, "PXP_OUT_PS_LRC 0x%x",
  59269. + __raw_readl(pxp->base + HW_PXP_OUT_PS_LRC));
  59270. + dev_dbg(pxp->dev, "PXP_OUT_AS_ULC 0x%x",
  59271. + __raw_readl(pxp->base + HW_PXP_OUT_AS_ULC));
  59272. + dev_dbg(pxp->dev, "PXP_OUT_AS_LRC 0x%x",
  59273. + __raw_readl(pxp->base + HW_PXP_OUT_AS_LRC));
  59274. + dev_dbg(pxp->dev, "PXP_PS_CTRL 0x%x",
  59275. + __raw_readl(pxp->base + HW_PXP_PS_CTRL));
  59276. + dev_dbg(pxp->dev, "PXP_PS_BUF 0x%x",
  59277. + __raw_readl(pxp->base + HW_PXP_PS_BUF));
  59278. + dev_dbg(pxp->dev, "PXP_PS_UBUF 0x%x",
  59279. + __raw_readl(pxp->base + HW_PXP_PS_UBUF));
  59280. + dev_dbg(pxp->dev, "PXP_PS_VBUF 0x%x",
  59281. + __raw_readl(pxp->base + HW_PXP_PS_VBUF));
  59282. + dev_dbg(pxp->dev, "PXP_PS_PITCH 0x%x",
  59283. + __raw_readl(pxp->base + HW_PXP_PS_PITCH));
  59284. + dev_dbg(pxp->dev, "PXP_PS_BACKGROUND 0x%x",
  59285. + __raw_readl(pxp->base + HW_PXP_PS_BACKGROUND));
  59286. + dev_dbg(pxp->dev, "PXP_PS_SCALE 0x%x",
  59287. + __raw_readl(pxp->base + HW_PXP_PS_SCALE));
  59288. + dev_dbg(pxp->dev, "PXP_PS_OFFSET 0x%x",
  59289. + __raw_readl(pxp->base + HW_PXP_PS_OFFSET));
  59290. + dev_dbg(pxp->dev, "PXP_PS_CLRKEYLOW 0x%x",
  59291. + __raw_readl(pxp->base + HW_PXP_PS_CLRKEYLOW));
  59292. + dev_dbg(pxp->dev, "PXP_PS_CLRKEYHIGH 0x%x",
  59293. + __raw_readl(pxp->base + HW_PXP_PS_CLRKEYHIGH));
  59294. + dev_dbg(pxp->dev, "PXP_AS_CTRL 0x%x",
  59295. + __raw_readl(pxp->base + HW_PXP_AS_CTRL));
  59296. + dev_dbg(pxp->dev, "PXP_AS_BUF 0x%x",
  59297. + __raw_readl(pxp->base + HW_PXP_AS_BUF));
  59298. + dev_dbg(pxp->dev, "PXP_AS_PITCH 0x%x",
  59299. + __raw_readl(pxp->base + HW_PXP_AS_PITCH));
  59300. + dev_dbg(pxp->dev, "PXP_AS_CLRKEYLOW 0x%x",
  59301. + __raw_readl(pxp->base + HW_PXP_AS_CLRKEYLOW));
  59302. + dev_dbg(pxp->dev, "PXP_AS_CLRKEYHIGH 0x%x",
  59303. + __raw_readl(pxp->base + HW_PXP_AS_CLRKEYHIGH));
  59304. + dev_dbg(pxp->dev, "PXP_CSC1_COEF0 0x%x",
  59305. + __raw_readl(pxp->base + HW_PXP_CSC1_COEF0));
  59306. + dev_dbg(pxp->dev, "PXP_CSC1_COEF1 0x%x",
  59307. + __raw_readl(pxp->base + HW_PXP_CSC1_COEF1));
  59308. + dev_dbg(pxp->dev, "PXP_CSC1_COEF2 0x%x",
  59309. + __raw_readl(pxp->base + HW_PXP_CSC1_COEF2));
  59310. + dev_dbg(pxp->dev, "PXP_CSC2_CTRL 0x%x",
  59311. + __raw_readl(pxp->base + HW_PXP_CSC2_CTRL));
  59312. + dev_dbg(pxp->dev, "PXP_CSC2_COEF0 0x%x",
  59313. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF0));
  59314. + dev_dbg(pxp->dev, "PXP_CSC2_COEF1 0x%x",
  59315. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF1));
  59316. + dev_dbg(pxp->dev, "PXP_CSC2_COEF2 0x%x",
  59317. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF2));
  59318. + dev_dbg(pxp->dev, "PXP_CSC2_COEF3 0x%x",
  59319. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF3));
  59320. + dev_dbg(pxp->dev, "PXP_CSC2_COEF4 0x%x",
  59321. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF4));
  59322. + dev_dbg(pxp->dev, "PXP_CSC2_COEF5 0x%x",
  59323. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF5));
  59324. + dev_dbg(pxp->dev, "PXP_LUT_CTRL 0x%x",
  59325. + __raw_readl(pxp->base + HW_PXP_LUT_CTRL));
  59326. + dev_dbg(pxp->dev, "PXP_LUT_ADDR 0x%x",
  59327. + __raw_readl(pxp->base + HW_PXP_LUT_ADDR));
  59328. + dev_dbg(pxp->dev, "PXP_LUT_DATA 0x%x",
  59329. + __raw_readl(pxp->base + HW_PXP_LUT_DATA));
  59330. + dev_dbg(pxp->dev, "PXP_LUT_EXTMEM 0x%x",
  59331. + __raw_readl(pxp->base + HW_PXP_LUT_EXTMEM));
  59332. + dev_dbg(pxp->dev, "PXP_CFA 0x%x",
  59333. + __raw_readl(pxp->base + HW_PXP_CFA));
  59334. + dev_dbg(pxp->dev, "PXP_HIST_CTRL 0x%x",
  59335. + __raw_readl(pxp->base + HW_PXP_HIST_CTRL));
  59336. + dev_dbg(pxp->dev, "PXP_HIST2_PARAM 0x%x",
  59337. + __raw_readl(pxp->base + HW_PXP_HIST2_PARAM));
  59338. + dev_dbg(pxp->dev, "PXP_HIST4_PARAM 0x%x",
  59339. + __raw_readl(pxp->base + HW_PXP_HIST4_PARAM));
  59340. + dev_dbg(pxp->dev, "PXP_HIST8_PARAM0 0x%x",
  59341. + __raw_readl(pxp->base + HW_PXP_HIST8_PARAM0));
  59342. + dev_dbg(pxp->dev, "PXP_HIST8_PARAM1 0x%x",
  59343. + __raw_readl(pxp->base + HW_PXP_HIST8_PARAM1));
  59344. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM0 0x%x",
  59345. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM0));
  59346. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM1 0x%x",
  59347. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM1));
  59348. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM2 0x%x",
  59349. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM2));
  59350. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM3 0x%x",
  59351. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM3));
  59352. + dev_dbg(pxp->dev, "PXP_POWER 0x%x",
  59353. + __raw_readl(pxp->base + HW_PXP_POWER));
  59354. + dev_dbg(pxp->dev, "PXP_NEXT 0x%x",
  59355. + __raw_readl(pxp->base + HW_PXP_NEXT));
  59356. + dev_dbg(pxp->dev, "PXP_DEBUGCTRL 0x%x",
  59357. + __raw_readl(pxp->base + HW_PXP_DEBUGCTRL));
  59358. + dev_dbg(pxp->dev, "PXP_DEBUG 0x%x",
  59359. + __raw_readl(pxp->base + HW_PXP_DEBUG));
  59360. + dev_dbg(pxp->dev, "PXP_VERSION 0x%x",
  59361. + __raw_readl(pxp->base + HW_PXP_VERSION));
  59362. +}
  59363. +
  59364. +static bool is_yuv(u32 pix_fmt)
  59365. +{
  59366. + if ((pix_fmt == PXP_PIX_FMT_YUYV) |
  59367. + (pix_fmt == PXP_PIX_FMT_UYVY) |
  59368. + (pix_fmt == PXP_PIX_FMT_YVYU) |
  59369. + (pix_fmt == PXP_PIX_FMT_VYUY) |
  59370. + (pix_fmt == PXP_PIX_FMT_Y41P) |
  59371. + (pix_fmt == PXP_PIX_FMT_YUV444) |
  59372. + (pix_fmt == PXP_PIX_FMT_NV12) |
  59373. + (pix_fmt == PXP_PIX_FMT_NV16) |
  59374. + (pix_fmt == PXP_PIX_FMT_NV61) |
  59375. + (pix_fmt == PXP_PIX_FMT_GREY) |
  59376. + (pix_fmt == PXP_PIX_FMT_GY04) |
  59377. + (pix_fmt == PXP_PIX_FMT_YVU410P) |
  59378. + (pix_fmt == PXP_PIX_FMT_YUV410P) |
  59379. + (pix_fmt == PXP_PIX_FMT_YVU420P) |
  59380. + (pix_fmt == PXP_PIX_FMT_YUV420P) |
  59381. + (pix_fmt == PXP_PIX_FMT_YUV420P2) |
  59382. + (pix_fmt == PXP_PIX_FMT_YVU422P) |
  59383. + (pix_fmt == PXP_PIX_FMT_YUV422P)) {
  59384. + return true;
  59385. + } else {
  59386. + return false;
  59387. + }
  59388. +}
  59389. +
  59390. +static void pxp_set_ctrl(struct pxps *pxp)
  59391. +{
  59392. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59393. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  59394. + u32 ctrl;
  59395. + u32 fmt_ctrl;
  59396. + int need_swap = 0; /* to support YUYV and YVYU formats */
  59397. +
  59398. + /* Configure S0 input format */
  59399. + switch (pxp_conf->s0_param.pixel_fmt) {
  59400. + case PXP_PIX_FMT_RGB32:
  59401. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB888;
  59402. + break;
  59403. + case PXP_PIX_FMT_RGB565:
  59404. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB565;
  59405. + break;
  59406. + case PXP_PIX_FMT_RGB555:
  59407. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB555;
  59408. + break;
  59409. + case PXP_PIX_FMT_YUV420P:
  59410. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
  59411. + break;
  59412. + case PXP_PIX_FMT_YVU420P:
  59413. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
  59414. + break;
  59415. + case PXP_PIX_FMT_GREY:
  59416. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y8;
  59417. + break;
  59418. + case PXP_PIX_FMT_GY04:
  59419. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y4;
  59420. + break;
  59421. + case PXP_PIX_FMT_YUV422P:
  59422. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV422;
  59423. + break;
  59424. + case PXP_PIX_FMT_UYVY:
  59425. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
  59426. + break;
  59427. + case PXP_PIX_FMT_YUYV:
  59428. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
  59429. + need_swap = 1;
  59430. + break;
  59431. + case PXP_PIX_FMT_VYUY:
  59432. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
  59433. + break;
  59434. + case PXP_PIX_FMT_YVYU:
  59435. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
  59436. + need_swap = 1;
  59437. + break;
  59438. + case PXP_PIX_FMT_NV12:
  59439. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P420;
  59440. + break;
  59441. + case PXP_PIX_FMT_NV21:
  59442. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P420;
  59443. + break;
  59444. + case PXP_PIX_FMT_NV16:
  59445. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P422;
  59446. + break;
  59447. + case PXP_PIX_FMT_NV61:
  59448. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P422;
  59449. + break;
  59450. + default:
  59451. + fmt_ctrl = 0;
  59452. + }
  59453. +
  59454. + ctrl = BF_PXP_PS_CTRL_FORMAT(fmt_ctrl) | BF_PXP_PS_CTRL_SWAP(need_swap);
  59455. + __raw_writel(ctrl, pxp->base + HW_PXP_PS_CTRL_SET);
  59456. +
  59457. + /* Configure output format based on out_channel format */
  59458. + switch (pxp_conf->out_param.pixel_fmt) {
  59459. + case PXP_PIX_FMT_RGB32:
  59460. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888;
  59461. + break;
  59462. + case PXP_PIX_FMT_BGRA32:
  59463. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__ARGB8888;
  59464. + break;
  59465. + case PXP_PIX_FMT_RGB24:
  59466. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888P;
  59467. + break;
  59468. + case PXP_PIX_FMT_RGB565:
  59469. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB565;
  59470. + break;
  59471. + case PXP_PIX_FMT_RGB555:
  59472. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB555;
  59473. + break;
  59474. + case PXP_PIX_FMT_GREY:
  59475. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y8;
  59476. + break;
  59477. + case PXP_PIX_FMT_GY04:
  59478. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y4;
  59479. + break;
  59480. + case PXP_PIX_FMT_UYVY:
  59481. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__UYVY1P422;
  59482. + break;
  59483. + case PXP_PIX_FMT_VYUY:
  59484. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__VYUY1P422;
  59485. + break;
  59486. + case PXP_PIX_FMT_NV12:
  59487. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P420;
  59488. + break;
  59489. + case PXP_PIX_FMT_NV21:
  59490. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P420;
  59491. + break;
  59492. + case PXP_PIX_FMT_NV16:
  59493. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P422;
  59494. + break;
  59495. + case PXP_PIX_FMT_NV61:
  59496. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P422;
  59497. + break;
  59498. + default:
  59499. + fmt_ctrl = 0;
  59500. + }
  59501. +
  59502. + ctrl = BF_PXP_OUT_CTRL_FORMAT(fmt_ctrl);
  59503. + __raw_writel(ctrl, pxp->base + HW_PXP_OUT_CTRL);
  59504. +
  59505. + ctrl = 0;
  59506. + if (proc_data->scaling)
  59507. + ;
  59508. + if (proc_data->vflip)
  59509. + ctrl |= BM_PXP_CTRL_VFLIP;
  59510. + if (proc_data->hflip)
  59511. + ctrl |= BM_PXP_CTRL_HFLIP;
  59512. + if (proc_data->rotate) {
  59513. + ctrl |= BF_PXP_CTRL_ROTATE(proc_data->rotate / 90);
  59514. + if (proc_data->rot_pos)
  59515. + ctrl |= BM_PXP_CTRL_ROT_POS;
  59516. + }
  59517. +
  59518. + /* In default, the block size is set to 8x8
  59519. + * But block size can be set to 16x16 due to
  59520. + * blocksize variable modification
  59521. + */
  59522. + ctrl |= block_size << 23;
  59523. +
  59524. + __raw_writel(ctrl, pxp->base + HW_PXP_CTRL);
  59525. +}
  59526. +
  59527. +static int pxp_start(struct pxps *pxp)
  59528. +{
  59529. + __raw_writel(BM_PXP_CTRL_IRQ_ENABLE, pxp->base + HW_PXP_CTRL_SET);
  59530. + __raw_writel(BM_PXP_CTRL_ENABLE, pxp->base + HW_PXP_CTRL_SET);
  59531. + dump_pxp_reg(pxp);
  59532. +
  59533. + return 0;
  59534. +}
  59535. +
  59536. +static void pxp_set_outbuf(struct pxps *pxp)
  59537. +{
  59538. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59539. + struct pxp_layer_param *out_params = &pxp_conf->out_param;
  59540. +
  59541. + __raw_writel(out_params->paddr, pxp->base + HW_PXP_OUT_BUF);
  59542. +
  59543. + __raw_writel(BF_PXP_OUT_LRC_X(out_params->width - 1) |
  59544. + BF_PXP_OUT_LRC_Y(out_params->height - 1),
  59545. + pxp->base + HW_PXP_OUT_LRC);
  59546. +
  59547. + if (out_params->pixel_fmt == PXP_PIX_FMT_RGB24) {
  59548. + __raw_writel(out_params->stride * 3,
  59549. + pxp->base + HW_PXP_OUT_PITCH);
  59550. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_BGRA32 ||
  59551. + out_params->pixel_fmt == PXP_PIX_FMT_RGB32) {
  59552. + __raw_writel(out_params->stride << 2,
  59553. + pxp->base + HW_PXP_OUT_PITCH);
  59554. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_RGB565) {
  59555. + __raw_writel(out_params->stride << 1,
  59556. + pxp->base + HW_PXP_OUT_PITCH);
  59557. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
  59558. + (out_params->pixel_fmt == PXP_PIX_FMT_VYUY)) {
  59559. + __raw_writel(out_params->stride << 1,
  59560. + pxp->base + HW_PXP_OUT_PITCH);
  59561. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_GREY ||
  59562. + out_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
  59563. + out_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
  59564. + out_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
  59565. + out_params->pixel_fmt == PXP_PIX_FMT_NV61) {
  59566. + __raw_writel(out_params->stride,
  59567. + pxp->base + HW_PXP_OUT_PITCH);
  59568. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_GY04) {
  59569. + __raw_writel(out_params->stride >> 1,
  59570. + pxp->base + HW_PXP_OUT_PITCH);
  59571. + } else {
  59572. + __raw_writel(0, pxp->base + HW_PXP_OUT_PITCH);
  59573. + }
  59574. +
  59575. + /* set global alpha if necessary */
  59576. + if (out_params->global_alpha_enable) {
  59577. + __raw_writel(out_params->global_alpha << 24,
  59578. + pxp->base + HW_PXP_OUT_CTRL_SET);
  59579. + __raw_writel(BM_PXP_OUT_CTRL_ALPHA_OUTPUT,
  59580. + pxp->base + HW_PXP_OUT_CTRL_SET);
  59581. + }
  59582. +}
  59583. +
  59584. +static void pxp_set_s0colorkey(struct pxps *pxp)
  59585. +{
  59586. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59587. + struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  59588. +
  59589. + /* Low and high are set equal. V4L does not allow a chromakey range */
  59590. + if (s0_params->color_key_enable == 0 || s0_params->color_key == -1) {
  59591. + /* disable color key */
  59592. + __raw_writel(0xFFFFFF, pxp->base + HW_PXP_PS_CLRKEYLOW);
  59593. + __raw_writel(0, pxp->base + HW_PXP_PS_CLRKEYHIGH);
  59594. + } else {
  59595. + __raw_writel(s0_params->color_key,
  59596. + pxp->base + HW_PXP_PS_CLRKEYLOW);
  59597. + __raw_writel(s0_params->color_key,
  59598. + pxp->base + HW_PXP_PS_CLRKEYHIGH);
  59599. + }
  59600. +}
  59601. +
  59602. +static void pxp_set_olcolorkey(int layer_no, struct pxps *pxp)
  59603. +{
  59604. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59605. + struct pxp_layer_param *ol_params = &pxp_conf->ol_param[layer_no];
  59606. +
  59607. + /* Low and high are set equal. V4L does not allow a chromakey range */
  59608. + if (ol_params->color_key_enable != 0 && ol_params->color_key != -1) {
  59609. + __raw_writel(ol_params->color_key,
  59610. + pxp->base + HW_PXP_AS_CLRKEYLOW);
  59611. + __raw_writel(ol_params->color_key,
  59612. + pxp->base + HW_PXP_AS_CLRKEYHIGH);
  59613. + } else {
  59614. + /* disable color key */
  59615. + __raw_writel(0xFFFFFF, pxp->base + HW_PXP_AS_CLRKEYLOW);
  59616. + __raw_writel(0, pxp->base + HW_PXP_AS_CLRKEYHIGH);
  59617. + }
  59618. +}
  59619. +
  59620. +static void pxp_set_oln(int layer_no, struct pxps *pxp)
  59621. +{
  59622. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59623. + struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
  59624. + dma_addr_t phys_addr = olparams_data->paddr;
  59625. + u32 pitch = olparams_data->stride ? olparams_data->stride :
  59626. + olparams_data->width;
  59627. +
  59628. + __raw_writel(phys_addr, pxp->base + HW_PXP_AS_BUF);
  59629. +
  59630. + /* Fixme */
  59631. + if (olparams_data->width == 0 && olparams_data->height == 0) {
  59632. + __raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_AS_ULC);
  59633. + __raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_LRC);
  59634. + } else {
  59635. + __raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_ULC);
  59636. + if (pxp_conf->proc_data.rotate == 90 ||
  59637. + pxp_conf->proc_data.rotate == 270) {
  59638. + if (pxp_conf->proc_data.rot_pos == 1) {
  59639. + __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->height - 1) |
  59640. + BF_PXP_OUT_AS_LRC_Y(olparams_data->width - 1),
  59641. + pxp->base + HW_PXP_OUT_AS_LRC);
  59642. + } else {
  59643. + __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width - 1) |
  59644. + BF_PXP_OUT_AS_LRC_Y(olparams_data->height - 1),
  59645. + pxp->base + HW_PXP_OUT_AS_LRC);
  59646. + }
  59647. + } else {
  59648. + __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width - 1) |
  59649. + BF_PXP_OUT_AS_LRC_Y(olparams_data->height - 1),
  59650. + pxp->base + HW_PXP_OUT_AS_LRC);
  59651. + }
  59652. + }
  59653. +
  59654. + if ((olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) |
  59655. + (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB32)) {
  59656. + __raw_writel(pitch << 2,
  59657. + pxp->base + HW_PXP_AS_PITCH);
  59658. + } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) {
  59659. + __raw_writel(pitch << 1,
  59660. + pxp->base + HW_PXP_AS_PITCH);
  59661. + } else {
  59662. + __raw_writel(0, pxp->base + HW_PXP_AS_PITCH);
  59663. + }
  59664. +}
  59665. +
  59666. +static void pxp_set_olparam(int layer_no, struct pxps *pxp)
  59667. +{
  59668. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59669. + struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
  59670. + u32 olparam;
  59671. +
  59672. + olparam = BF_PXP_AS_CTRL_ALPHA(olparams_data->global_alpha);
  59673. + if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB32) {
  59674. + olparam |=
  59675. + BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB888);
  59676. + } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) {
  59677. + olparam |=
  59678. + BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__ARGB8888);
  59679. + if (!olparams_data->combine_enable) {
  59680. + olparam |=
  59681. + BF_PXP_AS_CTRL_ALPHA_CTRL
  59682. + (BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs);
  59683. + olparam |= 0x3 << 16;
  59684. + }
  59685. + } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) {
  59686. + olparam |=
  59687. + BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB565);
  59688. + }
  59689. + if (olparams_data->global_alpha_enable) {
  59690. + if (olparams_data->global_override) {
  59691. + olparam |=
  59692. + BF_PXP_AS_CTRL_ALPHA_CTRL
  59693. + (BV_PXP_AS_CTRL_ALPHA_CTRL__Override);
  59694. + } else {
  59695. + olparam |=
  59696. + BF_PXP_AS_CTRL_ALPHA_CTRL
  59697. + (BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply);
  59698. + }
  59699. + if (olparams_data->alpha_invert)
  59700. + olparam |= BM_PXP_AS_CTRL_ALPHA_INVERT;
  59701. + }
  59702. + if (olparams_data->color_key_enable)
  59703. + olparam |= BM_PXP_AS_CTRL_ENABLE_COLORKEY;
  59704. +
  59705. + __raw_writel(olparam, pxp->base + HW_PXP_AS_CTRL);
  59706. +}
  59707. +
  59708. +static void pxp_set_s0param(struct pxps *pxp)
  59709. +{
  59710. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59711. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  59712. + u32 s0param;
  59713. +
  59714. + /* contains the coordinate for the PS in the OUTPUT buffer. */
  59715. + if ((pxp_conf->s0_param).width == 0 &&
  59716. + (pxp_conf->s0_param).height == 0) {
  59717. + __raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_PS_ULC);
  59718. + __raw_writel(0x0, pxp->base + HW_PXP_OUT_PS_LRC);
  59719. + } else {
  59720. + s0param = BF_PXP_OUT_PS_ULC_X(proc_data->drect.left);
  59721. + s0param |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.top);
  59722. + __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_ULC);
  59723. + s0param = BF_PXP_OUT_PS_LRC_X(proc_data->drect.left +
  59724. + proc_data->drect.width - 1);
  59725. + s0param |= BF_PXP_OUT_PS_LRC_Y(proc_data->drect.top +
  59726. + proc_data->drect.height - 1);
  59727. + __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_LRC);
  59728. + }
  59729. +}
  59730. +
  59731. +/* crop behavior is re-designed in h/w. */
  59732. +static void pxp_set_s0crop(struct pxps *pxp)
  59733. +{
  59734. + /*
  59735. + * place-holder, it's implemented in other functions in this driver.
  59736. + * Refer to "Clipping source images" section in RM for detail.
  59737. + */
  59738. +}
  59739. +
  59740. +static int pxp_set_scaling(struct pxps *pxp)
  59741. +{
  59742. + int ret = 0;
  59743. + u32 xscale, yscale, s0scale;
  59744. + u32 decx, decy, xdec = 0, ydec = 0;
  59745. + struct pxp_proc_data *proc_data = &pxp->pxp_conf_state.proc_data;
  59746. +
  59747. + if (((proc_data->srect.width == proc_data->drect.width) &&
  59748. + (proc_data->srect.height == proc_data->drect.height)) ||
  59749. + ((proc_data->srect.width == 0) && (proc_data->srect.height == 0))) {
  59750. + proc_data->scaling = 0;
  59751. + __raw_writel(0x10001000, pxp->base + HW_PXP_PS_SCALE);
  59752. + __raw_writel(0, pxp->base + HW_PXP_PS_CTRL);
  59753. + goto out;
  59754. + }
  59755. +
  59756. + proc_data->scaling = 1;
  59757. + decx = proc_data->srect.width / proc_data->drect.width;
  59758. + decy = proc_data->srect.height / proc_data->drect.height;
  59759. + if (decx > 0) {
  59760. + if (decx >= 2 && decx < 4) {
  59761. + decx = 2;
  59762. + xdec = 1;
  59763. + } else if (decx >= 4 && decx < 8) {
  59764. + decx = 4;
  59765. + xdec = 2;
  59766. + } else if (decx >= 8) {
  59767. + decx = 8;
  59768. + xdec = 3;
  59769. + }
  59770. + xscale = proc_data->srect.width * 0x1000 /
  59771. + (proc_data->drect.width * decx);
  59772. + } else
  59773. + xscale = proc_data->srect.width * 0x1000 /
  59774. + proc_data->drect.width;
  59775. + if (decy > 0) {
  59776. + if (decy >= 2 && decy < 4) {
  59777. + decy = 2;
  59778. + ydec = 1;
  59779. + } else if (decy >= 4 && decy < 8) {
  59780. + decy = 4;
  59781. + ydec = 2;
  59782. + } else if (decy >= 8) {
  59783. + decy = 8;
  59784. + ydec = 3;
  59785. + }
  59786. + yscale = proc_data->srect.height * 0x1000 /
  59787. + (proc_data->drect.height * decy);
  59788. + } else
  59789. + yscale = proc_data->srect.height * 0x1000 /
  59790. + proc_data->drect.height;
  59791. +
  59792. + __raw_writel((xdec << 10) | (ydec << 8), pxp->base + HW_PXP_PS_CTRL);
  59793. +
  59794. + if (xscale > PXP_DOWNSCALE_THRESHOLD)
  59795. + xscale = PXP_DOWNSCALE_THRESHOLD;
  59796. + if (yscale > PXP_DOWNSCALE_THRESHOLD)
  59797. + yscale = PXP_DOWNSCALE_THRESHOLD;
  59798. + s0scale = BF_PXP_PS_SCALE_YSCALE(yscale) |
  59799. + BF_PXP_PS_SCALE_XSCALE(xscale);
  59800. + __raw_writel(s0scale, pxp->base + HW_PXP_PS_SCALE);
  59801. +
  59802. +out:
  59803. + pxp_set_ctrl(pxp);
  59804. +
  59805. + return ret;
  59806. +}
  59807. +
  59808. +static void pxp_set_bg(struct pxps *pxp)
  59809. +{
  59810. + __raw_writel(pxp->pxp_conf_state.proc_data.bgcolor,
  59811. + pxp->base + HW_PXP_PS_BACKGROUND);
  59812. +}
  59813. +
  59814. +static void pxp_set_lut(struct pxps *pxp)
  59815. +{
  59816. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59817. + int lut_op = pxp_conf->proc_data.lut_transform;
  59818. + u32 reg_val;
  59819. + int i;
  59820. + bool use_cmap = (lut_op & PXP_LUT_USE_CMAP) ? true : false;
  59821. + u8 *cmap = pxp_conf->proc_data.lut_map;
  59822. + u32 entry_src;
  59823. + u32 pix_val;
  59824. + u8 entry[4];
  59825. +
  59826. + /*
  59827. + * If LUT already configured as needed, return...
  59828. + * Unless CMAP is needed and it has been updated.
  59829. + */
  59830. + if ((pxp->lut_state == lut_op) &&
  59831. + !(use_cmap && pxp_conf->proc_data.lut_map_updated))
  59832. + return;
  59833. +
  59834. + if (lut_op == PXP_LUT_NONE) {
  59835. + __raw_writel(BM_PXP_LUT_CTRL_BYPASS,
  59836. + pxp->base + HW_PXP_LUT_CTRL);
  59837. + } else if (((lut_op & PXP_LUT_INVERT) != 0)
  59838. + && ((lut_op & PXP_LUT_BLACK_WHITE) != 0)) {
  59839. + /* Fill out LUT table with inverted monochromized values */
  59840. +
  59841. + /* clear bypass bit, set lookup mode & out mode */
  59842. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  59843. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  59844. + BF_PXP_LUT_CTRL_OUT_MODE
  59845. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  59846. + pxp->base + HW_PXP_LUT_CTRL);
  59847. +
  59848. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  59849. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  59850. +
  59851. + /* LUT address pointer auto-increments after each data write */
  59852. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  59853. + for (i = 0; i < 4; i++) {
  59854. + entry_src = use_cmap ?
  59855. + cmap[pix_val + i] : pix_val + i;
  59856. + entry[i] = (entry_src < 0x80) ? 0xFF : 0x00;
  59857. + }
  59858. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  59859. + (entry[1] << 8) | entry[0];
  59860. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  59861. + }
  59862. + } else if ((lut_op & PXP_LUT_INVERT) != 0) {
  59863. + /* Fill out LUT table with 8-bit inverted values */
  59864. +
  59865. + /* clear bypass bit, set lookup mode & out mode */
  59866. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  59867. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  59868. + BF_PXP_LUT_CTRL_OUT_MODE
  59869. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  59870. + pxp->base + HW_PXP_LUT_CTRL);
  59871. +
  59872. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  59873. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  59874. +
  59875. + /* LUT address pointer auto-increments after each data write */
  59876. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  59877. + for (i = 0; i < 4; i++) {
  59878. + entry_src = use_cmap ?
  59879. + cmap[pix_val + i] : pix_val + i;
  59880. + entry[i] = ~entry_src & 0xFF;
  59881. + }
  59882. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  59883. + (entry[1] << 8) | entry[0];
  59884. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  59885. + }
  59886. + } else if ((lut_op & PXP_LUT_BLACK_WHITE) != 0) {
  59887. + /* Fill out LUT table with 8-bit monochromized values */
  59888. +
  59889. + /* clear bypass bit, set lookup mode & out mode */
  59890. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  59891. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  59892. + BF_PXP_LUT_CTRL_OUT_MODE
  59893. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  59894. + pxp->base + HW_PXP_LUT_CTRL);
  59895. +
  59896. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  59897. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  59898. +
  59899. + /* LUT address pointer auto-increments after each data write */
  59900. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  59901. + for (i = 0; i < 4; i++) {
  59902. + entry_src = use_cmap ?
  59903. + cmap[pix_val + i] : pix_val + i;
  59904. + entry[i] = (entry_src < 0x80) ? 0x00 : 0xFF;
  59905. + }
  59906. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  59907. + (entry[1] << 8) | entry[0];
  59908. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  59909. + }
  59910. + } else if (use_cmap) {
  59911. + /* Fill out LUT table using colormap values */
  59912. +
  59913. + /* clear bypass bit, set lookup mode & out mode */
  59914. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  59915. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  59916. + BF_PXP_LUT_CTRL_OUT_MODE
  59917. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  59918. + pxp->base + HW_PXP_LUT_CTRL);
  59919. +
  59920. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  59921. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  59922. +
  59923. + /* LUT address pointer auto-increments after each data write */
  59924. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  59925. + for (i = 0; i < 4; i++)
  59926. + entry[i] = cmap[pix_val + i];
  59927. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  59928. + (entry[1] << 8) | entry[0];
  59929. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  59930. + }
  59931. + }
  59932. +
  59933. + pxp->lut_state = lut_op;
  59934. +}
  59935. +
  59936. +static void pxp_set_csc(struct pxps *pxp)
  59937. +{
  59938. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59939. + struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  59940. + struct pxp_layer_param *ol_params = &pxp_conf->ol_param[0];
  59941. + struct pxp_layer_param *out_params = &pxp_conf->out_param;
  59942. +
  59943. + bool input_is_YUV = is_yuv(s0_params->pixel_fmt);
  59944. + bool output_is_YUV = is_yuv(out_params->pixel_fmt);
  59945. +
  59946. + if (input_is_YUV && output_is_YUV) {
  59947. + /*
  59948. + * Input = YUV, Output = YUV
  59949. + * No CSC unless we need to do combining
  59950. + */
  59951. + if (ol_params->combine_enable) {
  59952. + /* Must convert to RGB for combining with RGB overlay */
  59953. +
  59954. + /* CSC1 - YUV->RGB */
  59955. + __raw_writel(0x04030000, pxp->base + HW_PXP_CSC1_COEF0);
  59956. + __raw_writel(0x01230208, pxp->base + HW_PXP_CSC1_COEF1);
  59957. + __raw_writel(0x076b079c, pxp->base + HW_PXP_CSC1_COEF2);
  59958. +
  59959. + /* CSC2 - RGB->YUV */
  59960. + __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
  59961. + __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
  59962. + __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
  59963. + __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
  59964. + __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
  59965. + __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
  59966. + __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
  59967. + } else {
  59968. + /* Input & Output both YUV, so bypass both CSCs */
  59969. +
  59970. + /* CSC1 - Bypass */
  59971. + __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  59972. +
  59973. + /* CSC2 - Bypass */
  59974. + __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  59975. + }
  59976. + } else if (input_is_YUV && !output_is_YUV) {
  59977. + /*
  59978. + * Input = YUV, Output = RGB
  59979. + * Use CSC1 to convert to RGB
  59980. + */
  59981. +
  59982. + /* CSC1 - YUV->RGB */
  59983. + __raw_writel(0x84ab01f0, pxp->base + HW_PXP_CSC1_COEF0);
  59984. + __raw_writel(0x01980204, pxp->base + HW_PXP_CSC1_COEF1);
  59985. + __raw_writel(0x0730079c, pxp->base + HW_PXP_CSC1_COEF2);
  59986. +
  59987. + /* CSC2 - Bypass */
  59988. + __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  59989. + } else if (!input_is_YUV && output_is_YUV) {
  59990. + /*
  59991. + * Input = RGB, Output = YUV
  59992. + * Use CSC2 to convert to YUV
  59993. + */
  59994. +
  59995. + /* CSC1 - Bypass */
  59996. + __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  59997. +
  59998. + /* CSC2 - RGB->YUV */
  59999. + __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
  60000. + __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
  60001. + __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
  60002. + __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
  60003. + __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
  60004. + __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
  60005. + __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
  60006. + } else {
  60007. + /*
  60008. + * Input = RGB, Output = RGB
  60009. + * Input & Output both RGB, so bypass both CSCs
  60010. + */
  60011. +
  60012. + /* CSC1 - Bypass */
  60013. + __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  60014. +
  60015. + /* CSC2 - Bypass */
  60016. + __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  60017. + }
  60018. +
  60019. + /* YCrCb colorspace */
  60020. + /* Not sure when we use this...no YCrCb formats are defined for PxP */
  60021. + /*
  60022. + __raw_writel(0x84ab01f0, HW_PXP_CSCCOEFF0_ADDR);
  60023. + __raw_writel(0x01230204, HW_PXP_CSCCOEFF1_ADDR);
  60024. + __raw_writel(0x0730079c, HW_PXP_CSCCOEFF2_ADDR);
  60025. + */
  60026. +
  60027. +}
  60028. +
  60029. +static void pxp_set_s0buf(struct pxps *pxp)
  60030. +{
  60031. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  60032. + struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  60033. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  60034. + dma_addr_t Y, U, V;
  60035. + dma_addr_t Y1, U1, V1;
  60036. + u32 offset, bpp = 1;
  60037. + u32 pitch = s0_params->stride ? s0_params->stride :
  60038. + s0_params->width;
  60039. +
  60040. + Y = s0_params->paddr;
  60041. +
  60042. + if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB565)
  60043. + bpp = 2;
  60044. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB32)
  60045. + bpp = 4;
  60046. + offset = (proc_data->srect.top * s0_params->width +
  60047. + proc_data->srect.left) * bpp;
  60048. + /* clipping or cropping */
  60049. + Y1 = Y + offset;
  60050. + __raw_writel(Y1, pxp->base + HW_PXP_PS_BUF);
  60051. + if ((s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P) ||
  60052. + (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) ||
  60053. + (s0_params->pixel_fmt == PXP_PIX_FMT_GREY) ||
  60054. + (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)) {
  60055. + /* Set to 1 if YUV format is 4:2:2 rather than 4:2:0 */
  60056. + int s = 2;
  60057. + if (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)
  60058. + s = 1;
  60059. +
  60060. + offset = proc_data->srect.top * s0_params->width / 4 +
  60061. + proc_data->srect.left / 2;
  60062. + U = Y + (s0_params->width * s0_params->height);
  60063. + U1 = U + offset;
  60064. + V = U + ((s0_params->width * s0_params->height) >> s);
  60065. + V1 = V + offset;
  60066. + if (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) {
  60067. + __raw_writel(V1, pxp->base + HW_PXP_PS_UBUF);
  60068. + __raw_writel(U1, pxp->base + HW_PXP_PS_VBUF);
  60069. + } else {
  60070. + __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
  60071. + __raw_writel(V1, pxp->base + HW_PXP_PS_VBUF);
  60072. + }
  60073. + } else if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV12) ||
  60074. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV21) ||
  60075. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
  60076. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV61)) {
  60077. + int s = 2;
  60078. + if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
  60079. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV61))
  60080. + s = 1;
  60081. +
  60082. + offset = (proc_data->srect.top * s0_params->width +
  60083. + proc_data->srect.left) / s;
  60084. + U = Y + (s0_params->width * s0_params->height);
  60085. + U1 = U + offset;
  60086. +
  60087. + __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
  60088. + }
  60089. +
  60090. + /* TODO: only support RGB565, Y8, Y4, YUV420 */
  60091. + if (s0_params->pixel_fmt == PXP_PIX_FMT_GREY ||
  60092. + s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P ||
  60093. + s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P ||
  60094. + s0_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
  60095. + s0_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
  60096. + s0_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
  60097. + s0_params->pixel_fmt == PXP_PIX_FMT_NV61 ||
  60098. + s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P) {
  60099. + __raw_writel(pitch, pxp->base + HW_PXP_PS_PITCH);
  60100. + }
  60101. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_GY04)
  60102. + __raw_writel(pitch >> 1,
  60103. + pxp->base + HW_PXP_PS_PITCH);
  60104. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB32)
  60105. + __raw_writel(pitch << 2,
  60106. + pxp->base + HW_PXP_PS_PITCH);
  60107. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
  60108. + s0_params->pixel_fmt == PXP_PIX_FMT_YUYV ||
  60109. + s0_params->pixel_fmt == PXP_PIX_FMT_VYUY ||
  60110. + s0_params->pixel_fmt == PXP_PIX_FMT_YVYU)
  60111. + __raw_writel(pitch << 1,
  60112. + pxp->base + HW_PXP_PS_PITCH);
  60113. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB565)
  60114. + __raw_writel(pitch << 1,
  60115. + pxp->base + HW_PXP_PS_PITCH);
  60116. + else
  60117. + __raw_writel(0, pxp->base + HW_PXP_PS_PITCH);
  60118. +}
  60119. +
  60120. +/**
  60121. + * pxp_config() - configure PxP for a processing task
  60122. + * @pxps: PXP context.
  60123. + * @pxp_chan: PXP channel.
  60124. + * @return: 0 on success or negative error code on failure.
  60125. + */
  60126. +static int pxp_config(struct pxps *pxp, struct pxp_channel *pxp_chan)
  60127. +{
  60128. + struct pxp_config_data *pxp_conf_data = &pxp->pxp_conf_state;
  60129. + int ol_nr;
  60130. + int i;
  60131. +
  60132. + /* Configure PxP regs */
  60133. + pxp_set_ctrl(pxp);
  60134. + pxp_set_s0param(pxp);
  60135. + pxp_set_s0crop(pxp);
  60136. + pxp_set_scaling(pxp);
  60137. + ol_nr = pxp_conf_data->layer_nr - 2;
  60138. + while (ol_nr > 0) {
  60139. + i = pxp_conf_data->layer_nr - 2 - ol_nr;
  60140. + pxp_set_oln(i, pxp);
  60141. + pxp_set_olparam(i, pxp);
  60142. + /* only the color key in higher overlay will take effect. */
  60143. + pxp_set_olcolorkey(i, pxp);
  60144. + ol_nr--;
  60145. + }
  60146. + pxp_set_s0colorkey(pxp);
  60147. + pxp_set_csc(pxp);
  60148. + pxp_set_bg(pxp);
  60149. + pxp_set_lut(pxp);
  60150. +
  60151. + pxp_set_s0buf(pxp);
  60152. + pxp_set_outbuf(pxp);
  60153. +
  60154. + return 0;
  60155. +}
  60156. +
  60157. +static void pxp_clk_enable(struct pxps *pxp)
  60158. +{
  60159. + mutex_lock(&pxp->clk_mutex);
  60160. +
  60161. + if (pxp->clk_stat == CLK_STAT_ON) {
  60162. + mutex_unlock(&pxp->clk_mutex);
  60163. + return;
  60164. + }
  60165. +
  60166. + clk_prepare_enable(pxp->clk);
  60167. + pxp->clk_stat = CLK_STAT_ON;
  60168. +
  60169. + mutex_unlock(&pxp->clk_mutex);
  60170. +}
  60171. +
  60172. +static void pxp_clk_disable(struct pxps *pxp)
  60173. +{
  60174. + unsigned long flags;
  60175. +
  60176. + mutex_lock(&pxp->clk_mutex);
  60177. +
  60178. + if (pxp->clk_stat == CLK_STAT_OFF) {
  60179. + mutex_unlock(&pxp->clk_mutex);
  60180. + return;
  60181. + }
  60182. +
  60183. + spin_lock_irqsave(&pxp->lock, flags);
  60184. + if ((pxp->pxp_ongoing == 0) && list_empty(&head)) {
  60185. + spin_unlock_irqrestore(&pxp->lock, flags);
  60186. + clk_disable_unprepare(pxp->clk);
  60187. + pxp->clk_stat = CLK_STAT_OFF;
  60188. + } else
  60189. + spin_unlock_irqrestore(&pxp->lock, flags);
  60190. +
  60191. + mutex_unlock(&pxp->clk_mutex);
  60192. +}
  60193. +
  60194. +static inline void clkoff_callback(struct work_struct *w)
  60195. +{
  60196. + struct pxps *pxp = container_of(w, struct pxps, work);
  60197. +
  60198. + pxp_clk_disable(pxp);
  60199. +}
  60200. +
  60201. +static void pxp_clkoff_timer(unsigned long arg)
  60202. +{
  60203. + struct pxps *pxp = (struct pxps *)arg;
  60204. +
  60205. + if ((pxp->pxp_ongoing == 0) && list_empty(&head))
  60206. + schedule_work(&pxp->work);
  60207. + else
  60208. + mod_timer(&pxp->clk_timer,
  60209. + jiffies + msecs_to_jiffies(timeout_in_ms));
  60210. +}
  60211. +
  60212. +static struct pxp_tx_desc *pxpdma_first_queued(struct pxp_channel *pxp_chan)
  60213. +{
  60214. + return list_entry(pxp_chan->queue.next, struct pxp_tx_desc, list);
  60215. +}
  60216. +
  60217. +/* called with pxp_chan->lock held */
  60218. +static void __pxpdma_dostart(struct pxp_channel *pxp_chan)
  60219. +{
  60220. + struct pxp_dma *pxp_dma = to_pxp_dma(pxp_chan->dma_chan.device);
  60221. + struct pxps *pxp = to_pxp(pxp_dma);
  60222. + struct pxp_tx_desc *desc;
  60223. + struct pxp_tx_desc *child;
  60224. + int i = 0;
  60225. +
  60226. + /* S0 */
  60227. + desc = list_first_entry(&head, struct pxp_tx_desc, list);
  60228. + memcpy(&pxp->pxp_conf_state.s0_param,
  60229. + &desc->layer_param.s0_param, sizeof(struct pxp_layer_param));
  60230. + memcpy(&pxp->pxp_conf_state.proc_data,
  60231. + &desc->proc_data, sizeof(struct pxp_proc_data));
  60232. +
  60233. + /* Save PxP configuration */
  60234. + list_for_each_entry(child, &desc->tx_list, list) {
  60235. + if (i == 0) { /* Output */
  60236. + memcpy(&pxp->pxp_conf_state.out_param,
  60237. + &child->layer_param.out_param,
  60238. + sizeof(struct pxp_layer_param));
  60239. + } else { /* Overlay */
  60240. + memcpy(&pxp->pxp_conf_state.ol_param[i - 1],
  60241. + &child->layer_param.ol_param,
  60242. + sizeof(struct pxp_layer_param));
  60243. + }
  60244. +
  60245. + i++;
  60246. + }
  60247. + pr_debug("%s:%d S0 w/h %d/%d paddr %08x\n", __func__, __LINE__,
  60248. + pxp->pxp_conf_state.s0_param.width,
  60249. + pxp->pxp_conf_state.s0_param.height,
  60250. + pxp->pxp_conf_state.s0_param.paddr);
  60251. + pr_debug("%s:%d OUT w/h %d/%d paddr %08x\n", __func__, __LINE__,
  60252. + pxp->pxp_conf_state.out_param.width,
  60253. + pxp->pxp_conf_state.out_param.height,
  60254. + pxp->pxp_conf_state.out_param.paddr);
  60255. +}
  60256. +
  60257. +static void pxpdma_dostart_work(struct pxps *pxp)
  60258. +{
  60259. + struct pxp_channel *pxp_chan = NULL;
  60260. + unsigned long flags;
  60261. + struct pxp_tx_desc *desc = NULL;
  60262. +
  60263. + spin_lock_irqsave(&pxp->lock, flags);
  60264. +
  60265. + desc = list_entry(head.next, struct pxp_tx_desc, list);
  60266. + pxp_chan = to_pxp_channel(desc->txd.chan);
  60267. +
  60268. + __pxpdma_dostart(pxp_chan);
  60269. +
  60270. + /* Configure PxP */
  60271. + pxp_config(pxp, pxp_chan);
  60272. +
  60273. + pxp_start(pxp);
  60274. +
  60275. + spin_unlock_irqrestore(&pxp->lock, flags);
  60276. +}
  60277. +
  60278. +static void pxpdma_dequeue(struct pxp_channel *pxp_chan, struct pxps *pxp)
  60279. +{
  60280. + unsigned long flags;
  60281. + struct pxp_tx_desc *desc = NULL;
  60282. +
  60283. + do {
  60284. + desc = pxpdma_first_queued(pxp_chan);
  60285. + spin_lock_irqsave(&pxp->lock, flags);
  60286. + list_move_tail(&desc->list, &head);
  60287. + spin_unlock_irqrestore(&pxp->lock, flags);
  60288. + } while (!list_empty(&pxp_chan->queue));
  60289. +}
  60290. +
  60291. +static dma_cookie_t pxp_tx_submit(struct dma_async_tx_descriptor *tx)
  60292. +{
  60293. + struct pxp_tx_desc *desc = to_tx_desc(tx);
  60294. + struct pxp_channel *pxp_chan = to_pxp_channel(tx->chan);
  60295. + dma_cookie_t cookie;
  60296. +
  60297. + dev_dbg(&pxp_chan->dma_chan.dev->device, "received TX\n");
  60298. +
  60299. + /* pxp_chan->lock can be taken under ichan->lock, but not v.v. */
  60300. + spin_lock(&pxp_chan->lock);
  60301. +
  60302. + cookie = pxp_chan->dma_chan.cookie;
  60303. +
  60304. + if (++cookie < 0)
  60305. + cookie = 1;
  60306. +
  60307. + /* from dmaengine.h: "last cookie value returned to client" */
  60308. + pxp_chan->dma_chan.cookie = cookie;
  60309. + tx->cookie = cookie;
  60310. +
  60311. + /* Here we add the tx descriptor to our PxP task queue. */
  60312. + list_add_tail(&desc->list, &pxp_chan->queue);
  60313. +
  60314. + spin_unlock(&pxp_chan->lock);
  60315. +
  60316. + dev_dbg(&pxp_chan->dma_chan.dev->device, "done TX\n");
  60317. +
  60318. + return cookie;
  60319. +}
  60320. +
  60321. +/**
  60322. + * pxp_init_channel() - initialize a PXP channel.
  60323. + * @pxp_dma: PXP DMA context.
  60324. + * @pchan: pointer to the channel object.
  60325. + * @return 0 on success or negative error code on failure.
  60326. + */
  60327. +static int pxp_init_channel(struct pxp_dma *pxp_dma,
  60328. + struct pxp_channel *pxp_chan)
  60329. +{
  60330. + int ret = 0;
  60331. +
  60332. + /*
  60333. + * We are using _virtual_ channel here.
  60334. + * Each channel contains all parameters of corresponding layers
  60335. + * for one transaction; each layer is represented as one descriptor
  60336. + * (i.e., pxp_tx_desc) here.
  60337. + */
  60338. +
  60339. + INIT_LIST_HEAD(&pxp_chan->queue);
  60340. +
  60341. + return ret;
  60342. +}
  60343. +
  60344. +static irqreturn_t pxp_irq(int irq, void *dev_id)
  60345. +{
  60346. + struct pxps *pxp = dev_id;
  60347. + struct pxp_channel *pxp_chan;
  60348. + struct pxp_tx_desc *desc;
  60349. + struct pxp_tx_desc *child, *_child;
  60350. + dma_async_tx_callback callback;
  60351. + void *callback_param;
  60352. + unsigned long flags;
  60353. + u32 hist_status;
  60354. +
  60355. + dump_pxp_reg(pxp);
  60356. +
  60357. + hist_status =
  60358. + __raw_readl(pxp->base + HW_PXP_HIST_CTRL) & BM_PXP_HIST_CTRL_STATUS;
  60359. +
  60360. + __raw_writel(BM_PXP_STAT_IRQ, pxp->base + HW_PXP_STAT_CLR);
  60361. +
  60362. + spin_lock_irqsave(&pxp->lock, flags);
  60363. +
  60364. + if (list_empty(&head)) {
  60365. + pxp->pxp_ongoing = 0;
  60366. + spin_unlock_irqrestore(&pxp->lock, flags);
  60367. + return IRQ_NONE;
  60368. + }
  60369. +
  60370. + /* Get descriptor and call callback */
  60371. + desc = list_entry(head.next, struct pxp_tx_desc, list);
  60372. + pxp_chan = to_pxp_channel(desc->txd.chan);
  60373. +
  60374. + pxp_chan->completed = desc->txd.cookie;
  60375. +
  60376. + callback = desc->txd.callback;
  60377. + callback_param = desc->txd.callback_param;
  60378. +
  60379. + /* Send histogram status back to caller */
  60380. + desc->hist_status = hist_status;
  60381. +
  60382. + if ((desc->txd.flags & DMA_PREP_INTERRUPT) && callback)
  60383. + callback(callback_param);
  60384. +
  60385. + pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  60386. +
  60387. + list_for_each_entry_safe(child, _child, &desc->tx_list, list) {
  60388. + list_del_init(&child->list);
  60389. + kmem_cache_free(tx_desc_cache, (void *)child);
  60390. + }
  60391. + list_del_init(&desc->list);
  60392. + kmem_cache_free(tx_desc_cache, (void *)desc);
  60393. +
  60394. + complete(&pxp->complete);
  60395. + pxp->pxp_ongoing = 0;
  60396. + mod_timer(&pxp->clk_timer, jiffies + msecs_to_jiffies(timeout_in_ms));
  60397. +
  60398. + spin_unlock_irqrestore(&pxp->lock, flags);
  60399. +
  60400. + return IRQ_HANDLED;
  60401. +}
  60402. +
  60403. +/* allocate/free dma tx descriptor dynamically*/
  60404. +static struct pxp_tx_desc *pxpdma_desc_alloc(struct pxp_channel *pxp_chan)
  60405. +{
  60406. + struct pxp_tx_desc *desc = NULL;
  60407. + struct dma_async_tx_descriptor *txd = NULL;
  60408. +
  60409. + desc = kmem_cache_alloc(tx_desc_cache, GFP_KERNEL | __GFP_ZERO);
  60410. + if (desc == NULL)
  60411. + return NULL;
  60412. +
  60413. + INIT_LIST_HEAD(&desc->list);
  60414. + INIT_LIST_HEAD(&desc->tx_list);
  60415. + txd = &desc->txd;
  60416. + dma_async_tx_descriptor_init(txd, &pxp_chan->dma_chan);
  60417. + txd->tx_submit = pxp_tx_submit;
  60418. +
  60419. + return desc;
  60420. +}
  60421. +
  60422. +/* Allocate and initialise a transfer descriptor. */
  60423. +static struct dma_async_tx_descriptor *pxp_prep_slave_sg(struct dma_chan *chan,
  60424. + struct scatterlist
  60425. + *sgl,
  60426. + unsigned int sg_len,
  60427. + enum
  60428. + dma_transfer_direction
  60429. + direction,
  60430. + unsigned long tx_flags,
  60431. + void *context)
  60432. +{
  60433. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60434. + struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  60435. + struct pxps *pxp = to_pxp(pxp_dma);
  60436. + struct pxp_tx_desc *desc = NULL;
  60437. + struct pxp_tx_desc *first = NULL, *prev = NULL;
  60438. + struct scatterlist *sg;
  60439. + dma_addr_t phys_addr;
  60440. + int i;
  60441. +
  60442. + if (direction != DMA_DEV_TO_MEM && direction != DMA_MEM_TO_DEV) {
  60443. + dev_err(chan->device->dev, "Invalid DMA direction %d!\n",
  60444. + direction);
  60445. + return NULL;
  60446. + }
  60447. +
  60448. + if (unlikely(sg_len < 2))
  60449. + return NULL;
  60450. +
  60451. + for_each_sg(sgl, sg, sg_len, i) {
  60452. + desc = pxpdma_desc_alloc(pxp_chan);
  60453. + if (!desc) {
  60454. + dev_err(chan->device->dev, "no enough memory to allocate tx descriptor\n");
  60455. + return NULL;
  60456. + }
  60457. +
  60458. + phys_addr = sg_dma_address(sg);
  60459. +
  60460. + if (!first) {
  60461. + first = desc;
  60462. +
  60463. + desc->layer_param.s0_param.paddr = phys_addr;
  60464. + } else {
  60465. + list_add_tail(&desc->list, &first->tx_list);
  60466. + prev->next = desc;
  60467. + desc->next = NULL;
  60468. +
  60469. + if (i == 1)
  60470. + desc->layer_param.out_param.paddr = phys_addr;
  60471. + else
  60472. + desc->layer_param.ol_param.paddr = phys_addr;
  60473. + }
  60474. +
  60475. + prev = desc;
  60476. + }
  60477. +
  60478. + pxp->pxp_conf_state.layer_nr = sg_len;
  60479. + first->txd.flags = tx_flags;
  60480. + first->len = sg_len;
  60481. + pr_debug("%s:%d first %p, first->len %d, flags %08x\n",
  60482. + __func__, __LINE__, first, first->len, first->txd.flags);
  60483. +
  60484. + return &first->txd;
  60485. +}
  60486. +
  60487. +static void pxp_issue_pending(struct dma_chan *chan)
  60488. +{
  60489. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60490. + struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  60491. + struct pxps *pxp = to_pxp(pxp_dma);
  60492. +
  60493. + spin_lock(&pxp_chan->lock);
  60494. +
  60495. + if (list_empty(&pxp_chan->queue)) {
  60496. + spin_unlock(&pxp_chan->lock);
  60497. + return;
  60498. + }
  60499. +
  60500. + pxpdma_dequeue(pxp_chan, pxp);
  60501. + pxp_chan->status = PXP_CHANNEL_READY;
  60502. +
  60503. + spin_unlock(&pxp_chan->lock);
  60504. +
  60505. + pxp_clk_enable(pxp);
  60506. + wake_up_interruptible(&pxp->thread_waitq);
  60507. +}
  60508. +
  60509. +static void __pxp_terminate_all(struct dma_chan *chan)
  60510. +{
  60511. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60512. +
  60513. + pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  60514. +}
  60515. +
  60516. +static int pxp_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
  60517. + unsigned long arg)
  60518. +{
  60519. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60520. +
  60521. + /* Only supports DMA_TERMINATE_ALL */
  60522. + if (cmd != DMA_TERMINATE_ALL)
  60523. + return -ENXIO;
  60524. +
  60525. + spin_lock(&pxp_chan->lock);
  60526. + __pxp_terminate_all(chan);
  60527. + spin_unlock(&pxp_chan->lock);
  60528. +
  60529. + return 0;
  60530. +}
  60531. +
  60532. +static int pxp_alloc_chan_resources(struct dma_chan *chan)
  60533. +{
  60534. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60535. + struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  60536. + int ret;
  60537. +
  60538. + /* dmaengine.c now guarantees to only offer free channels */
  60539. + BUG_ON(chan->client_count > 1);
  60540. + WARN_ON(pxp_chan->status != PXP_CHANNEL_FREE);
  60541. +
  60542. + chan->cookie = 1;
  60543. + pxp_chan->completed = -ENXIO;
  60544. +
  60545. + pr_debug("%s dma_chan.chan_id %d\n", __func__, chan->chan_id);
  60546. + ret = pxp_init_channel(pxp_dma, pxp_chan);
  60547. + if (ret < 0)
  60548. + goto err_chan;
  60549. +
  60550. + pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  60551. +
  60552. + dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
  60553. + chan->chan_id, pxp_chan->eof_irq);
  60554. +
  60555. + return ret;
  60556. +
  60557. +err_chan:
  60558. + return ret;
  60559. +}
  60560. +
  60561. +static void pxp_free_chan_resources(struct dma_chan *chan)
  60562. +{
  60563. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60564. +
  60565. + spin_lock(&pxp_chan->lock);
  60566. +
  60567. + __pxp_terminate_all(chan);
  60568. +
  60569. + pxp_chan->status = PXP_CHANNEL_FREE;
  60570. +
  60571. + spin_unlock(&pxp_chan->lock);
  60572. +}
  60573. +
  60574. +static enum dma_status pxp_tx_status(struct dma_chan *chan,
  60575. + dma_cookie_t cookie,
  60576. + struct dma_tx_state *txstate)
  60577. +{
  60578. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60579. +
  60580. + if (cookie != chan->cookie)
  60581. + return DMA_ERROR;
  60582. +
  60583. + if (txstate) {
  60584. + txstate->last = pxp_chan->completed;
  60585. + txstate->used = chan->cookie;
  60586. + txstate->residue = 0;
  60587. + }
  60588. + return DMA_COMPLETE;
  60589. +}
  60590. +
  60591. +static int pxp_hw_init(struct pxps *pxp)
  60592. +{
  60593. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  60594. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  60595. + u32 reg_val;
  60596. +
  60597. + /* Pull PxP out of reset */
  60598. + __raw_writel(0, pxp->base + HW_PXP_CTRL);
  60599. +
  60600. + /* Config defaults */
  60601. +
  60602. + /* Initialize non-channel-specific PxP parameters */
  60603. + proc_data->drect.left = proc_data->srect.left = 0;
  60604. + proc_data->drect.top = proc_data->srect.top = 0;
  60605. + proc_data->drect.width = proc_data->srect.width = 0;
  60606. + proc_data->drect.height = proc_data->srect.height = 0;
  60607. + proc_data->scaling = 0;
  60608. + proc_data->hflip = 0;
  60609. + proc_data->vflip = 0;
  60610. + proc_data->rotate = 0;
  60611. + proc_data->bgcolor = 0;
  60612. +
  60613. + /* Initialize S0 channel parameters */
  60614. + pxp_conf->s0_param.pixel_fmt = pxp_s0_formats[0];
  60615. + pxp_conf->s0_param.width = 0;
  60616. + pxp_conf->s0_param.height = 0;
  60617. + pxp_conf->s0_param.color_key = -1;
  60618. + pxp_conf->s0_param.color_key_enable = false;
  60619. +
  60620. + /* Initialize OL channel parameters */
  60621. + pxp_conf->ol_param[0].combine_enable = false;
  60622. + pxp_conf->ol_param[0].width = 0;
  60623. + pxp_conf->ol_param[0].height = 0;
  60624. + pxp_conf->ol_param[0].pixel_fmt = PXP_PIX_FMT_RGB565;
  60625. + pxp_conf->ol_param[0].color_key_enable = false;
  60626. + pxp_conf->ol_param[0].color_key = -1;
  60627. + pxp_conf->ol_param[0].global_alpha_enable = false;
  60628. + pxp_conf->ol_param[0].global_alpha = 0;
  60629. + pxp_conf->ol_param[0].local_alpha_enable = false;
  60630. +
  60631. + /* Initialize Output channel parameters */
  60632. + pxp_conf->out_param.width = 0;
  60633. + pxp_conf->out_param.height = 0;
  60634. + pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_RGB565;
  60635. +
  60636. + proc_data->overlay_state = 0;
  60637. +
  60638. + /* Write default h/w config */
  60639. + pxp_set_ctrl(pxp);
  60640. + pxp_set_s0param(pxp);
  60641. + pxp_set_s0crop(pxp);
  60642. + /*
  60643. + * simply program the ULC to a higher value than the LRC
  60644. + * to avoid any AS pixels to show up in the output buffer.
  60645. + */
  60646. + __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_OUT_AS_ULC);
  60647. + pxp_set_olparam(0, pxp);
  60648. + pxp_set_olcolorkey(0, pxp);
  60649. +
  60650. + pxp_set_s0colorkey(pxp);
  60651. + pxp_set_csc(pxp);
  60652. + pxp_set_bg(pxp);
  60653. + pxp_set_lut(pxp);
  60654. +
  60655. + /* One-time histogram configuration */
  60656. + reg_val =
  60657. + BF_PXP_HIST_CTRL_PANEL_MODE(BV_PXP_HIST_CTRL_PANEL_MODE__GRAY16);
  60658. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST_CTRL);
  60659. +
  60660. + reg_val = BF_PXP_HIST2_PARAM_VALUE0(0x00) |
  60661. + BF_PXP_HIST2_PARAM_VALUE1(0x00F);
  60662. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST2_PARAM);
  60663. +
  60664. + reg_val = BF_PXP_HIST4_PARAM_VALUE0(0x00) |
  60665. + BF_PXP_HIST4_PARAM_VALUE1(0x05) |
  60666. + BF_PXP_HIST4_PARAM_VALUE2(0x0A) | BF_PXP_HIST4_PARAM_VALUE3(0x0F);
  60667. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST4_PARAM);
  60668. +
  60669. + reg_val = BF_PXP_HIST8_PARAM0_VALUE0(0x00) |
  60670. + BF_PXP_HIST8_PARAM0_VALUE1(0x02) |
  60671. + BF_PXP_HIST8_PARAM0_VALUE2(0x04) | BF_PXP_HIST8_PARAM0_VALUE3(0x06);
  60672. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST8_PARAM0);
  60673. + reg_val = BF_PXP_HIST8_PARAM1_VALUE4(0x09) |
  60674. + BF_PXP_HIST8_PARAM1_VALUE5(0x0B) |
  60675. + BF_PXP_HIST8_PARAM1_VALUE6(0x0D) | BF_PXP_HIST8_PARAM1_VALUE7(0x0F);
  60676. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST8_PARAM1);
  60677. +
  60678. + reg_val = BF_PXP_HIST16_PARAM0_VALUE0(0x00) |
  60679. + BF_PXP_HIST16_PARAM0_VALUE1(0x01) |
  60680. + BF_PXP_HIST16_PARAM0_VALUE2(0x02) |
  60681. + BF_PXP_HIST16_PARAM0_VALUE3(0x03);
  60682. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM0);
  60683. + reg_val = BF_PXP_HIST16_PARAM1_VALUE4(0x04) |
  60684. + BF_PXP_HIST16_PARAM1_VALUE5(0x05) |
  60685. + BF_PXP_HIST16_PARAM1_VALUE6(0x06) |
  60686. + BF_PXP_HIST16_PARAM1_VALUE7(0x07);
  60687. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM1);
  60688. + reg_val = BF_PXP_HIST16_PARAM2_VALUE8(0x08) |
  60689. + BF_PXP_HIST16_PARAM2_VALUE9(0x09) |
  60690. + BF_PXP_HIST16_PARAM2_VALUE10(0x0A) |
  60691. + BF_PXP_HIST16_PARAM2_VALUE11(0x0B);
  60692. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM2);
  60693. + reg_val = BF_PXP_HIST16_PARAM3_VALUE12(0x0C) |
  60694. + BF_PXP_HIST16_PARAM3_VALUE13(0x0D) |
  60695. + BF_PXP_HIST16_PARAM3_VALUE14(0x0E) |
  60696. + BF_PXP_HIST16_PARAM3_VALUE15(0x0F);
  60697. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM3);
  60698. +
  60699. + return 0;
  60700. +}
  60701. +
  60702. +static int pxp_dma_init(struct pxps *pxp)
  60703. +{
  60704. + struct pxp_dma *pxp_dma = &pxp->pxp_dma;
  60705. + struct dma_device *dma = &pxp_dma->dma;
  60706. + int i;
  60707. +
  60708. + dma_cap_set(DMA_SLAVE, dma->cap_mask);
  60709. + dma_cap_set(DMA_PRIVATE, dma->cap_mask);
  60710. +
  60711. + /* Compulsory common fields */
  60712. + dma->dev = pxp->dev;
  60713. + dma->device_alloc_chan_resources = pxp_alloc_chan_resources;
  60714. + dma->device_free_chan_resources = pxp_free_chan_resources;
  60715. + dma->device_tx_status = pxp_tx_status;
  60716. + dma->device_issue_pending = pxp_issue_pending;
  60717. +
  60718. + /* Compulsory for DMA_SLAVE fields */
  60719. + dma->device_prep_slave_sg = pxp_prep_slave_sg;
  60720. + dma->device_control = pxp_control;
  60721. +
  60722. + /* Initialize PxP Channels */
  60723. + INIT_LIST_HEAD(&dma->channels);
  60724. + for (i = 0; i < NR_PXP_VIRT_CHANNEL; i++) {
  60725. + struct pxp_channel *pxp_chan = pxp->channel + i;
  60726. + struct dma_chan *dma_chan = &pxp_chan->dma_chan;
  60727. +
  60728. + spin_lock_init(&pxp_chan->lock);
  60729. +
  60730. + /* Only one EOF IRQ for PxP, shared by all channels */
  60731. + pxp_chan->eof_irq = pxp->irq;
  60732. + pxp_chan->status = PXP_CHANNEL_FREE;
  60733. + pxp_chan->completed = -ENXIO;
  60734. + snprintf(pxp_chan->eof_name, sizeof(pxp_chan->eof_name),
  60735. + "PXP EOF %d", i);
  60736. +
  60737. + dma_chan->device = &pxp_dma->dma;
  60738. + dma_chan->cookie = 1;
  60739. + dma_chan->chan_id = i;
  60740. + list_add_tail(&dma_chan->device_node, &dma->channels);
  60741. + }
  60742. +
  60743. + return dma_async_device_register(&pxp_dma->dma);
  60744. +}
  60745. +
  60746. +static ssize_t clk_off_timeout_show(struct device *dev,
  60747. + struct device_attribute *attr, char *buf)
  60748. +{
  60749. + return sprintf(buf, "%d\n", timeout_in_ms);
  60750. +}
  60751. +
  60752. +static ssize_t clk_off_timeout_store(struct device *dev,
  60753. + struct device_attribute *attr,
  60754. + const char *buf, size_t count)
  60755. +{
  60756. + int val;
  60757. + if (sscanf(buf, "%d", &val) > 0) {
  60758. + timeout_in_ms = val;
  60759. + return count;
  60760. + }
  60761. + return -EINVAL;
  60762. +}
  60763. +
  60764. +static DEVICE_ATTR(clk_off_timeout, 0644, clk_off_timeout_show,
  60765. + clk_off_timeout_store);
  60766. +
  60767. +static ssize_t block_size_show(struct device *dev,
  60768. + struct device_attribute *attr,
  60769. + char *buf)
  60770. +{
  60771. + return sprintf(buf, "%d\n", block_size);
  60772. +}
  60773. +
  60774. +static ssize_t block_size_store(struct device *dev,
  60775. + struct device_attribute *attr,
  60776. + const char *buf, size_t count)
  60777. +{
  60778. + char **last = NULL;
  60779. +
  60780. + block_size = simple_strtoul(buf, last, 0);
  60781. + if (block_size > 1)
  60782. + block_size = 1;
  60783. +
  60784. + return count;
  60785. +}
  60786. +static DEVICE_ATTR(block_size, S_IWUSR | S_IRUGO,
  60787. + block_size_show, block_size_store);
  60788. +
  60789. +static const struct of_device_id imx_pxpdma_dt_ids[] = {
  60790. + { .compatible = "fsl,imx6dl-pxp-dma", },
  60791. + { /* sentinel */ }
  60792. +};
  60793. +MODULE_DEVICE_TABLE(of, imx_pxpdma_dt_ids);
  60794. +
  60795. +static int has_pending_task(struct pxps *pxp, struct pxp_channel *task)
  60796. +{
  60797. + int found;
  60798. + unsigned long flags;
  60799. +
  60800. + spin_lock_irqsave(&pxp->lock, flags);
  60801. + found = !list_empty(&head);
  60802. + spin_unlock_irqrestore(&pxp->lock, flags);
  60803. +
  60804. + return found;
  60805. +}
  60806. +
  60807. +static int pxp_dispatch_thread(void *argv)
  60808. +{
  60809. + struct pxps *pxp = (struct pxps *)argv;
  60810. + struct pxp_channel *pending = NULL;
  60811. + unsigned long flags;
  60812. +
  60813. + while (!kthread_should_stop()) {
  60814. + int ret;
  60815. + ret = wait_event_interruptible(pxp->thread_waitq,
  60816. + has_pending_task(pxp, pending));
  60817. + if (signal_pending(current))
  60818. + continue;
  60819. +
  60820. + if (kthread_should_stop())
  60821. + break;
  60822. +
  60823. + spin_lock_irqsave(&pxp->lock, flags);
  60824. + pxp->pxp_ongoing = 1;
  60825. + spin_unlock_irqrestore(&pxp->lock, flags);
  60826. + init_completion(&pxp->complete);
  60827. + pxpdma_dostart_work(pxp);
  60828. + ret = wait_for_completion_timeout(&pxp->complete, 2 * HZ);
  60829. + if (ret == 0) {
  60830. + printk(KERN_EMERG "%s: task is timeout\n\n", __func__);
  60831. + break;
  60832. + }
  60833. + }
  60834. +
  60835. + return 0;
  60836. +}
  60837. +
  60838. +static int pxp_probe(struct platform_device *pdev)
  60839. +{
  60840. + struct pxps *pxp;
  60841. + struct resource *res;
  60842. + int irq;
  60843. + int err = 0;
  60844. +
  60845. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  60846. + irq = platform_get_irq(pdev, 0);
  60847. + if (!res || irq < 0) {
  60848. + err = -ENODEV;
  60849. + goto exit;
  60850. + }
  60851. +
  60852. + pxp = devm_kzalloc(&pdev->dev, sizeof(*pxp), GFP_KERNEL);
  60853. + if (!pxp) {
  60854. + dev_err(&pdev->dev, "failed to allocate control object\n");
  60855. + err = -ENOMEM;
  60856. + goto exit;
  60857. + }
  60858. +
  60859. + pxp->dev = &pdev->dev;
  60860. +
  60861. + platform_set_drvdata(pdev, pxp);
  60862. + pxp->irq = irq;
  60863. +
  60864. + pxp->pxp_ongoing = 0;
  60865. + pxp->lut_state = 0;
  60866. +
  60867. + spin_lock_init(&pxp->lock);
  60868. + mutex_init(&pxp->clk_mutex);
  60869. +
  60870. + pxp->base = devm_request_and_ioremap(&pdev->dev, res);
  60871. + if (pxp->base == NULL) {
  60872. + dev_err(&pdev->dev, "Couldn't ioremap regs\n");
  60873. + err = -ENODEV;
  60874. + goto exit;
  60875. + }
  60876. +
  60877. + pxp->pdev = pdev;
  60878. +
  60879. + pxp->clk = devm_clk_get(&pdev->dev, "pxp-axi");
  60880. + clk_prepare_enable(pxp->clk);
  60881. +
  60882. + err = pxp_hw_init(pxp);
  60883. + clk_disable_unprepare(pxp->clk);
  60884. + if (err) {
  60885. + dev_err(&pdev->dev, "failed to initialize hardware\n");
  60886. + goto exit;
  60887. + }
  60888. +
  60889. + err = devm_request_irq(&pdev->dev, pxp->irq, pxp_irq, 0,
  60890. + "pxp-dmaengine", pxp);
  60891. + if (err)
  60892. + goto exit;
  60893. + /* Initialize DMA engine */
  60894. + err = pxp_dma_init(pxp);
  60895. + if (err < 0)
  60896. + goto exit;
  60897. +
  60898. + if (device_create_file(&pdev->dev, &dev_attr_clk_off_timeout)) {
  60899. + dev_err(&pdev->dev,
  60900. + "Unable to create file from clk_off_timeout\n");
  60901. + goto exit;
  60902. + }
  60903. +
  60904. + device_create_file(&pdev->dev, &dev_attr_block_size);
  60905. + dump_pxp_reg(pxp);
  60906. +
  60907. + INIT_WORK(&pxp->work, clkoff_callback);
  60908. + init_timer(&pxp->clk_timer);
  60909. + pxp->clk_timer.function = pxp_clkoff_timer;
  60910. + pxp->clk_timer.data = (unsigned long)pxp;
  60911. +
  60912. + /* allocate a kernel thread to dispatch pxp conf */
  60913. + pxp->dispatch = kthread_run(pxp_dispatch_thread, pxp, "pxp_dispatch");
  60914. + if (IS_ERR(pxp->dispatch)) {
  60915. + err = PTR_ERR(pxp->dispatch);
  60916. + goto exit;
  60917. + }
  60918. + init_waitqueue_head(&pxp->thread_waitq);
  60919. + tx_desc_cache = kmem_cache_create("tx_desc", sizeof(struct pxp_tx_desc),
  60920. + 0, SLAB_HWCACHE_ALIGN, NULL);
  60921. + if (!tx_desc_cache) {
  60922. + err = -ENOMEM;
  60923. + goto exit;
  60924. + }
  60925. +
  60926. + register_pxp_device();
  60927. +
  60928. +exit:
  60929. + if (err)
  60930. + dev_err(&pdev->dev, "Exiting (unsuccessfully) pxp_probe()\n");
  60931. + return err;
  60932. +}
  60933. +
  60934. +static int pxp_remove(struct platform_device *pdev)
  60935. +{
  60936. + struct pxps *pxp = platform_get_drvdata(pdev);
  60937. +
  60938. + unregister_pxp_device();
  60939. + kmem_cache_destroy(tx_desc_cache);
  60940. + kthread_stop(pxp->dispatch);
  60941. + cancel_work_sync(&pxp->work);
  60942. + del_timer_sync(&pxp->clk_timer);
  60943. + clk_disable_unprepare(pxp->clk);
  60944. + device_remove_file(&pdev->dev, &dev_attr_clk_off_timeout);
  60945. + device_remove_file(&pdev->dev, &dev_attr_block_size);
  60946. + dma_async_device_unregister(&(pxp->pxp_dma.dma));
  60947. +
  60948. + return 0;
  60949. +}
  60950. +
  60951. +#ifdef CONFIG_PM
  60952. +static int pxp_suspend(struct platform_device *pdev, pm_message_t state)
  60953. +{
  60954. + struct pxps *pxp = platform_get_drvdata(pdev);
  60955. +
  60956. + pxp_clk_enable(pxp);
  60957. + while (__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_ENABLE)
  60958. + ;
  60959. +
  60960. + __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL);
  60961. + pxp_clk_disable(pxp);
  60962. +
  60963. + return 0;
  60964. +}
  60965. +
  60966. +static int pxp_resume(struct platform_device *pdev)
  60967. +{
  60968. + struct pxps *pxp = platform_get_drvdata(pdev);
  60969. +
  60970. + pxp_clk_enable(pxp);
  60971. + /* Pull PxP out of reset */
  60972. + __raw_writel(0, pxp->base + HW_PXP_CTRL);
  60973. + pxp_clk_disable(pxp);
  60974. +
  60975. + return 0;
  60976. +}
  60977. +#else
  60978. +#define pxp_suspend NULL
  60979. +#define pxp_resume NULL
  60980. +#endif
  60981. +
  60982. +static struct platform_driver pxp_driver = {
  60983. + .driver = {
  60984. + .name = "imx-pxp",
  60985. + .of_match_table = of_match_ptr(imx_pxpdma_dt_ids),
  60986. + },
  60987. + .probe = pxp_probe,
  60988. + .remove = pxp_remove,
  60989. + .suspend = pxp_suspend,
  60990. + .resume = pxp_resume,
  60991. +};
  60992. +
  60993. +module_platform_driver(pxp_driver);
  60994. +
  60995. +
  60996. +MODULE_DESCRIPTION("i.MX PxP driver");
  60997. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  60998. +MODULE_LICENSE("GPL");
  60999. diff -Nur linux-3.14.15/drivers/dma/pxp/regs-pxp_v2.h linux-linaro-stable-mx6/drivers/dma/pxp/regs-pxp_v2.h
  61000. --- linux-3.14.15/drivers/dma/pxp/regs-pxp_v2.h 1970-01-01 01:00:00.000000000 +0100
  61001. +++ linux-linaro-stable-mx6/drivers/dma/pxp/regs-pxp_v2.h 2014-08-20 19:23:50.894834465 +0200
  61002. @@ -0,0 +1,1152 @@
  61003. +/*
  61004. + * Freescale PXP Register Definitions
  61005. + *
  61006. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  61007. + *
  61008. + * This program is free software; you can redistribute it and/or modify
  61009. + * it under the terms of the GNU General Public License as published by
  61010. + * the Free Software Foundation; either version 2 of the License, or
  61011. + * (at your option) any later version.
  61012. + *
  61013. + * This program is distributed in the hope that it will be useful,
  61014. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  61015. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  61016. + * GNU General Public License for more details.
  61017. + *
  61018. + * You should have received a copy of the GNU General Public License
  61019. + * along with this program; if not, write to the Free Software
  61020. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  61021. + *
  61022. + * This file is created by xml file. Don't Edit it.
  61023. + *
  61024. + * Xml Revision: 1.29
  61025. + * Template revision: 1.3
  61026. + */
  61027. +
  61028. +#ifndef __ARCH_ARM___PXP_H
  61029. +#define __ARCH_ARM___PXP_H
  61030. +
  61031. +#define HW_PXP_CTRL (0x00000000)
  61032. +#define HW_PXP_CTRL_SET (0x00000004)
  61033. +#define HW_PXP_CTRL_CLR (0x00000008)
  61034. +#define HW_PXP_CTRL_TOG (0x0000000c)
  61035. +
  61036. +#define BM_PXP_CTRL_SFTRST 0x80000000
  61037. +#define BM_PXP_CTRL_CLKGATE 0x40000000
  61038. +#define BM_PXP_CTRL_RSVD4 0x20000000
  61039. +#define BM_PXP_CTRL_EN_REPEAT 0x10000000
  61040. +#define BP_PXP_CTRL_RSVD3 26
  61041. +#define BM_PXP_CTRL_RSVD3 0x0C000000
  61042. +#define BF_PXP_CTRL_RSVD3(v) \
  61043. + (((v) << 26) & BM_PXP_CTRL_RSVD3)
  61044. +#define BP_PXP_CTRL_INTERLACED_INPUT 24
  61045. +#define BM_PXP_CTRL_INTERLACED_INPUT 0x03000000
  61046. +#define BF_PXP_CTRL_INTERLACED_INPUT(v) \
  61047. + (((v) << 24) & BM_PXP_CTRL_INTERLACED_INPUT)
  61048. +#define BV_PXP_CTRL_INTERLACED_INPUT__PROGRESSIVE 0x0
  61049. +#define BV_PXP_CTRL_INTERLACED_INPUT__FIELD0 0x2
  61050. +#define BV_PXP_CTRL_INTERLACED_INPUT__FIELD1 0x3
  61051. +#define BM_PXP_CTRL_BLOCK_SIZE 0x00800000
  61052. +#define BV_PXP_CTRL_BLOCK_SIZE__8X8 0x0
  61053. +#define BV_PXP_CTRL_BLOCK_SIZE__16X16 0x1
  61054. +#define BM_PXP_CTRL_ROT_POS 0x00400000
  61055. +#define BM_PXP_CTRL_IN_PLACE 0x00200000
  61056. +#define BP_PXP_CTRL_RSVD1 12
  61057. +#define BM_PXP_CTRL_RSVD1 0x001FF000
  61058. +#define BF_PXP_CTRL_RSVD1(v) \
  61059. + (((v) << 12) & BM_PXP_CTRL_RSVD1)
  61060. +#define BM_PXP_CTRL_VFLIP 0x00000800
  61061. +#define BM_PXP_CTRL_HFLIP 0x00000400
  61062. +#define BP_PXP_CTRL_ROTATE 8
  61063. +#define BM_PXP_CTRL_ROTATE 0x00000300
  61064. +#define BF_PXP_CTRL_ROTATE(v) \
  61065. + (((v) << 8) & BM_PXP_CTRL_ROTATE)
  61066. +#define BV_PXP_CTRL_ROTATE__ROT_0 0x0
  61067. +#define BV_PXP_CTRL_ROTATE__ROT_90 0x1
  61068. +#define BV_PXP_CTRL_ROTATE__ROT_180 0x2
  61069. +#define BV_PXP_CTRL_ROTATE__ROT_270 0x3
  61070. +#define BP_PXP_CTRL_RSVD0 5
  61071. +#define BM_PXP_CTRL_RSVD0 0x000000E0
  61072. +#define BF_PXP_CTRL_RSVD0(v) \
  61073. + (((v) << 5) & BM_PXP_CTRL_RSVD0)
  61074. +#define BM_PXP_CTRL_ENABLE_LCD_HANDSHAKE 0x00000010
  61075. +#define BM_PXP_CTRL_LUT_DMA_IRQ_ENABLE 0x00000008
  61076. +#define BM_PXP_CTRL_NEXT_IRQ_ENABLE 0x00000004
  61077. +#define BM_PXP_CTRL_IRQ_ENABLE 0x00000002
  61078. +#define BM_PXP_CTRL_ENABLE 0x00000001
  61079. +
  61080. +#define HW_PXP_STAT (0x00000010)
  61081. +#define HW_PXP_STAT_SET (0x00000014)
  61082. +#define HW_PXP_STAT_CLR (0x00000018)
  61083. +#define HW_PXP_STAT_TOG (0x0000001c)
  61084. +
  61085. +#define BP_PXP_STAT_BLOCKX 24
  61086. +#define BM_PXP_STAT_BLOCKX 0xFF000000
  61087. +#define BF_PXP_STAT_BLOCKX(v) \
  61088. + (((v) << 24) & BM_PXP_STAT_BLOCKX)
  61089. +#define BP_PXP_STAT_BLOCKY 16
  61090. +#define BM_PXP_STAT_BLOCKY 0x00FF0000
  61091. +#define BF_PXP_STAT_BLOCKY(v) \
  61092. + (((v) << 16) & BM_PXP_STAT_BLOCKY)
  61093. +#define BP_PXP_STAT_RSVD2 9
  61094. +#define BM_PXP_STAT_RSVD2 0x0000FE00
  61095. +#define BF_PXP_STAT_RSVD2(v) \
  61096. + (((v) << 9) & BM_PXP_STAT_RSVD2)
  61097. +#define BM_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ 0x00000100
  61098. +#define BP_PXP_STAT_AXI_ERROR_ID 4
  61099. +#define BM_PXP_STAT_AXI_ERROR_ID 0x000000F0
  61100. +#define BF_PXP_STAT_AXI_ERROR_ID(v) \
  61101. + (((v) << 4) & BM_PXP_STAT_AXI_ERROR_ID)
  61102. +#define BM_PXP_STAT_NEXT_IRQ 0x00000008
  61103. +#define BM_PXP_STAT_AXI_READ_ERROR 0x00000004
  61104. +#define BM_PXP_STAT_AXI_WRITE_ERROR 0x00000002
  61105. +#define BM_PXP_STAT_IRQ 0x00000001
  61106. +
  61107. +#define HW_PXP_OUT_CTRL (0x00000020)
  61108. +#define HW_PXP_OUT_CTRL_SET (0x00000024)
  61109. +#define HW_PXP_OUT_CTRL_CLR (0x00000028)
  61110. +#define HW_PXP_OUT_CTRL_TOG (0x0000002c)
  61111. +
  61112. +#define BP_PXP_OUT_CTRL_ALPHA 24
  61113. +#define BM_PXP_OUT_CTRL_ALPHA 0xFF000000
  61114. +#define BF_PXP_OUT_CTRL_ALPHA(v) \
  61115. + (((v) << 24) & BM_PXP_OUT_CTRL_ALPHA)
  61116. +#define BM_PXP_OUT_CTRL_ALPHA_OUTPUT 0x00800000
  61117. +#define BP_PXP_OUT_CTRL_RSVD1 10
  61118. +#define BM_PXP_OUT_CTRL_RSVD1 0x007FFC00
  61119. +#define BF_PXP_OUT_CTRL_RSVD1(v) \
  61120. + (((v) << 10) & BM_PXP_OUT_CTRL_RSVD1)
  61121. +#define BP_PXP_OUT_CTRL_INTERLACED_OUTPUT 8
  61122. +#define BM_PXP_OUT_CTRL_INTERLACED_OUTPUT 0x00000300
  61123. +#define BF_PXP_OUT_CTRL_INTERLACED_OUTPUT(v) \
  61124. + (((v) << 8) & BM_PXP_OUT_CTRL_INTERLACED_OUTPUT)
  61125. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__PROGRESSIVE 0x0
  61126. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD0 0x1
  61127. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD1 0x2
  61128. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__INTERLACED 0x3
  61129. +#define BP_PXP_OUT_CTRL_RSVD0 5
  61130. +#define BM_PXP_OUT_CTRL_RSVD0 0x000000E0
  61131. +#define BF_PXP_OUT_CTRL_RSVD0(v) \
  61132. + (((v) << 5) & BM_PXP_OUT_CTRL_RSVD0)
  61133. +#define BP_PXP_OUT_CTRL_FORMAT 0
  61134. +#define BM_PXP_OUT_CTRL_FORMAT 0x0000001F
  61135. +#define BF_PXP_OUT_CTRL_FORMAT(v) \
  61136. + (((v) << 0) & BM_PXP_OUT_CTRL_FORMAT)
  61137. +#define BV_PXP_OUT_CTRL_FORMAT__ARGB8888 0x0
  61138. +#define BV_PXP_OUT_CTRL_FORMAT__RGB888 0x4
  61139. +#define BV_PXP_OUT_CTRL_FORMAT__RGB888P 0x5
  61140. +#define BV_PXP_OUT_CTRL_FORMAT__ARGB1555 0x8
  61141. +#define BV_PXP_OUT_CTRL_FORMAT__ARGB4444 0x9
  61142. +#define BV_PXP_OUT_CTRL_FORMAT__RGB555 0xC
  61143. +#define BV_PXP_OUT_CTRL_FORMAT__RGB444 0xD
  61144. +#define BV_PXP_OUT_CTRL_FORMAT__RGB565 0xE
  61145. +#define BV_PXP_OUT_CTRL_FORMAT__YUV1P444 0x10
  61146. +#define BV_PXP_OUT_CTRL_FORMAT__UYVY1P422 0x12
  61147. +#define BV_PXP_OUT_CTRL_FORMAT__VYUY1P422 0x13
  61148. +#define BV_PXP_OUT_CTRL_FORMAT__Y8 0x14
  61149. +#define BV_PXP_OUT_CTRL_FORMAT__Y4 0x15
  61150. +#define BV_PXP_OUT_CTRL_FORMAT__YUV2P422 0x18
  61151. +#define BV_PXP_OUT_CTRL_FORMAT__YUV2P420 0x19
  61152. +#define BV_PXP_OUT_CTRL_FORMAT__YVU2P422 0x1A
  61153. +#define BV_PXP_OUT_CTRL_FORMAT__YVU2P420 0x1B
  61154. +
  61155. +#define HW_PXP_OUT_BUF (0x00000030)
  61156. +
  61157. +#define BP_PXP_OUT_BUF_ADDR 0
  61158. +#define BM_PXP_OUT_BUF_ADDR 0xFFFFFFFF
  61159. +#define BF_PXP_OUT_BUF_ADDR(v) (v)
  61160. +
  61161. +#define HW_PXP_OUT_BUF2 (0x00000040)
  61162. +
  61163. +#define BP_PXP_OUT_BUF2_ADDR 0
  61164. +#define BM_PXP_OUT_BUF2_ADDR 0xFFFFFFFF
  61165. +#define BF_PXP_OUT_BUF2_ADDR(v) (v)
  61166. +
  61167. +#define HW_PXP_OUT_PITCH (0x00000050)
  61168. +
  61169. +#define BP_PXP_OUT_PITCH_RSVD 16
  61170. +#define BM_PXP_OUT_PITCH_RSVD 0xFFFF0000
  61171. +#define BF_PXP_OUT_PITCH_RSVD(v) \
  61172. + (((v) << 16) & BM_PXP_OUT_PITCH_RSVD)
  61173. +#define BP_PXP_OUT_PITCH_PITCH 0
  61174. +#define BM_PXP_OUT_PITCH_PITCH 0x0000FFFF
  61175. +#define BF_PXP_OUT_PITCH_PITCH(v) \
  61176. + (((v) << 0) & BM_PXP_OUT_PITCH_PITCH)
  61177. +
  61178. +#define HW_PXP_OUT_LRC (0x00000060)
  61179. +
  61180. +#define BP_PXP_OUT_LRC_RSVD1 30
  61181. +#define BM_PXP_OUT_LRC_RSVD1 0xC0000000
  61182. +#define BF_PXP_OUT_LRC_RSVD1(v) \
  61183. + (((v) << 30) & BM_PXP_OUT_LRC_RSVD1)
  61184. +#define BP_PXP_OUT_LRC_X 16
  61185. +#define BM_PXP_OUT_LRC_X 0x3FFF0000
  61186. +#define BF_PXP_OUT_LRC_X(v) \
  61187. + (((v) << 16) & BM_PXP_OUT_LRC_X)
  61188. +#define BP_PXP_OUT_LRC_RSVD0 14
  61189. +#define BM_PXP_OUT_LRC_RSVD0 0x0000C000
  61190. +#define BF_PXP_OUT_LRC_RSVD0(v) \
  61191. + (((v) << 14) & BM_PXP_OUT_LRC_RSVD0)
  61192. +#define BP_PXP_OUT_LRC_Y 0
  61193. +#define BM_PXP_OUT_LRC_Y 0x00003FFF
  61194. +#define BF_PXP_OUT_LRC_Y(v) \
  61195. + (((v) << 0) & BM_PXP_OUT_LRC_Y)
  61196. +
  61197. +#define HW_PXP_OUT_PS_ULC (0x00000070)
  61198. +
  61199. +#define BP_PXP_OUT_PS_ULC_RSVD1 30
  61200. +#define BM_PXP_OUT_PS_ULC_RSVD1 0xC0000000
  61201. +#define BF_PXP_OUT_PS_ULC_RSVD1(v) \
  61202. + (((v) << 30) & BM_PXP_OUT_PS_ULC_RSVD1)
  61203. +#define BP_PXP_OUT_PS_ULC_X 16
  61204. +#define BM_PXP_OUT_PS_ULC_X 0x3FFF0000
  61205. +#define BF_PXP_OUT_PS_ULC_X(v) \
  61206. + (((v) << 16) & BM_PXP_OUT_PS_ULC_X)
  61207. +#define BP_PXP_OUT_PS_ULC_RSVD0 14
  61208. +#define BM_PXP_OUT_PS_ULC_RSVD0 0x0000C000
  61209. +#define BF_PXP_OUT_PS_ULC_RSVD0(v) \
  61210. + (((v) << 14) & BM_PXP_OUT_PS_ULC_RSVD0)
  61211. +#define BP_PXP_OUT_PS_ULC_Y 0
  61212. +#define BM_PXP_OUT_PS_ULC_Y 0x00003FFF
  61213. +#define BF_PXP_OUT_PS_ULC_Y(v) \
  61214. + (((v) << 0) & BM_PXP_OUT_PS_ULC_Y)
  61215. +
  61216. +#define HW_PXP_OUT_PS_LRC (0x00000080)
  61217. +
  61218. +#define BP_PXP_OUT_PS_LRC_RSVD1 30
  61219. +#define BM_PXP_OUT_PS_LRC_RSVD1 0xC0000000
  61220. +#define BF_PXP_OUT_PS_LRC_RSVD1(v) \
  61221. + (((v) << 30) & BM_PXP_OUT_PS_LRC_RSVD1)
  61222. +#define BP_PXP_OUT_PS_LRC_X 16
  61223. +#define BM_PXP_OUT_PS_LRC_X 0x3FFF0000
  61224. +#define BF_PXP_OUT_PS_LRC_X(v) \
  61225. + (((v) << 16) & BM_PXP_OUT_PS_LRC_X)
  61226. +#define BP_PXP_OUT_PS_LRC_RSVD0 14
  61227. +#define BM_PXP_OUT_PS_LRC_RSVD0 0x0000C000
  61228. +#define BF_PXP_OUT_PS_LRC_RSVD0(v) \
  61229. + (((v) << 14) & BM_PXP_OUT_PS_LRC_RSVD0)
  61230. +#define BP_PXP_OUT_PS_LRC_Y 0
  61231. +#define BM_PXP_OUT_PS_LRC_Y 0x00003FFF
  61232. +#define BF_PXP_OUT_PS_LRC_Y(v) \
  61233. + (((v) << 0) & BM_PXP_OUT_PS_LRC_Y)
  61234. +
  61235. +#define HW_PXP_OUT_AS_ULC (0x00000090)
  61236. +
  61237. +#define BP_PXP_OUT_AS_ULC_RSVD1 30
  61238. +#define BM_PXP_OUT_AS_ULC_RSVD1 0xC0000000
  61239. +#define BF_PXP_OUT_AS_ULC_RSVD1(v) \
  61240. + (((v) << 30) & BM_PXP_OUT_AS_ULC_RSVD1)
  61241. +#define BP_PXP_OUT_AS_ULC_X 16
  61242. +#define BM_PXP_OUT_AS_ULC_X 0x3FFF0000
  61243. +#define BF_PXP_OUT_AS_ULC_X(v) \
  61244. + (((v) << 16) & BM_PXP_OUT_AS_ULC_X)
  61245. +#define BP_PXP_OUT_AS_ULC_RSVD0 14
  61246. +#define BM_PXP_OUT_AS_ULC_RSVD0 0x0000C000
  61247. +#define BF_PXP_OUT_AS_ULC_RSVD0(v) \
  61248. + (((v) << 14) & BM_PXP_OUT_AS_ULC_RSVD0)
  61249. +#define BP_PXP_OUT_AS_ULC_Y 0
  61250. +#define BM_PXP_OUT_AS_ULC_Y 0x00003FFF
  61251. +#define BF_PXP_OUT_AS_ULC_Y(v) \
  61252. + (((v) << 0) & BM_PXP_OUT_AS_ULC_Y)
  61253. +
  61254. +#define HW_PXP_OUT_AS_LRC (0x000000a0)
  61255. +
  61256. +#define BP_PXP_OUT_AS_LRC_RSVD1 30
  61257. +#define BM_PXP_OUT_AS_LRC_RSVD1 0xC0000000
  61258. +#define BF_PXP_OUT_AS_LRC_RSVD1(v) \
  61259. + (((v) << 30) & BM_PXP_OUT_AS_LRC_RSVD1)
  61260. +#define BP_PXP_OUT_AS_LRC_X 16
  61261. +#define BM_PXP_OUT_AS_LRC_X 0x3FFF0000
  61262. +#define BF_PXP_OUT_AS_LRC_X(v) \
  61263. + (((v) << 16) & BM_PXP_OUT_AS_LRC_X)
  61264. +#define BP_PXP_OUT_AS_LRC_RSVD0 14
  61265. +#define BM_PXP_OUT_AS_LRC_RSVD0 0x0000C000
  61266. +#define BF_PXP_OUT_AS_LRC_RSVD0(v) \
  61267. + (((v) << 14) & BM_PXP_OUT_AS_LRC_RSVD0)
  61268. +#define BP_PXP_OUT_AS_LRC_Y 0
  61269. +#define BM_PXP_OUT_AS_LRC_Y 0x00003FFF
  61270. +#define BF_PXP_OUT_AS_LRC_Y(v) \
  61271. + (((v) << 0) & BM_PXP_OUT_AS_LRC_Y)
  61272. +
  61273. +#define HW_PXP_PS_CTRL (0x000000b0)
  61274. +#define HW_PXP_PS_CTRL_SET (0x000000b4)
  61275. +#define HW_PXP_PS_CTRL_CLR (0x000000b8)
  61276. +#define HW_PXP_PS_CTRL_TOG (0x000000bc)
  61277. +
  61278. +#define BP_PXP_PS_CTRL_RSVD1 12
  61279. +#define BM_PXP_PS_CTRL_RSVD1 0xFFFFF000
  61280. +#define BF_PXP_PS_CTRL_RSVD1(v) \
  61281. + (((v) << 12) & BM_PXP_PS_CTRL_RSVD1)
  61282. +#define BP_PXP_PS_CTRL_DECX 10
  61283. +#define BM_PXP_PS_CTRL_DECX 0x00000C00
  61284. +#define BF_PXP_PS_CTRL_DECX(v) \
  61285. + (((v) << 10) & BM_PXP_PS_CTRL_DECX)
  61286. +#define BV_PXP_PS_CTRL_DECX__DISABLE 0x0
  61287. +#define BV_PXP_PS_CTRL_DECX__DECX2 0x1
  61288. +#define BV_PXP_PS_CTRL_DECX__DECX4 0x2
  61289. +#define BV_PXP_PS_CTRL_DECX__DECX8 0x3
  61290. +#define BP_PXP_PS_CTRL_DECY 8
  61291. +#define BM_PXP_PS_CTRL_DECY 0x00000300
  61292. +#define BF_PXP_PS_CTRL_DECY(v) \
  61293. + (((v) << 8) & BM_PXP_PS_CTRL_DECY)
  61294. +#define BV_PXP_PS_CTRL_DECY__DISABLE 0x0
  61295. +#define BV_PXP_PS_CTRL_DECY__DECY2 0x1
  61296. +#define BV_PXP_PS_CTRL_DECY__DECY4 0x2
  61297. +#define BV_PXP_PS_CTRL_DECY__DECY8 0x3
  61298. +#define BP_PXP_PS_CTRL_SWAP 5
  61299. +#define BM_PXP_PS_CTRL_SWAP 0x000000E0
  61300. +#define BF_PXP_PS_CTRL_SWAP(v) \
  61301. + (((v) << 5) & BM_PXP_PS_CTRL_SWAP)
  61302. +#define BP_PXP_PS_CTRL_FORMAT 0
  61303. +#define BM_PXP_PS_CTRL_FORMAT 0x0000001F
  61304. +#define BF_PXP_PS_CTRL_FORMAT(v) \
  61305. + (((v) << 0) & BM_PXP_PS_CTRL_FORMAT)
  61306. +#define BV_PXP_PS_CTRL_FORMAT__RGB888 0x4
  61307. +#define BV_PXP_PS_CTRL_FORMAT__RGB555 0xC
  61308. +#define BV_PXP_PS_CTRL_FORMAT__RGB444 0xD
  61309. +#define BV_PXP_PS_CTRL_FORMAT__RGB565 0xE
  61310. +#define BV_PXP_PS_CTRL_FORMAT__YUV1P444 0x10
  61311. +#define BV_PXP_PS_CTRL_FORMAT__UYVY1P422 0x12
  61312. +#define BV_PXP_PS_CTRL_FORMAT__VYUY1P422 0x13
  61313. +#define BV_PXP_PS_CTRL_FORMAT__Y8 0x14
  61314. +#define BV_PXP_PS_CTRL_FORMAT__Y4 0x15
  61315. +#define BV_PXP_PS_CTRL_FORMAT__YUV2P422 0x18
  61316. +#define BV_PXP_PS_CTRL_FORMAT__YUV2P420 0x19
  61317. +#define BV_PXP_PS_CTRL_FORMAT__YVU2P422 0x1A
  61318. +#define BV_PXP_PS_CTRL_FORMAT__YVU2P420 0x1B
  61319. +#define BV_PXP_PS_CTRL_FORMAT__YUV422 0x1E
  61320. +#define BV_PXP_PS_CTRL_FORMAT__YUV420 0x1F
  61321. +
  61322. +#define HW_PXP_PS_BUF (0x000000c0)
  61323. +
  61324. +#define BP_PXP_PS_BUF_ADDR 0
  61325. +#define BM_PXP_PS_BUF_ADDR 0xFFFFFFFF
  61326. +#define BF_PXP_PS_BUF_ADDR(v) (v)
  61327. +
  61328. +#define HW_PXP_PS_UBUF (0x000000d0)
  61329. +
  61330. +#define BP_PXP_PS_UBUF_ADDR 0
  61331. +#define BM_PXP_PS_UBUF_ADDR 0xFFFFFFFF
  61332. +#define BF_PXP_PS_UBUF_ADDR(v) (v)
  61333. +
  61334. +#define HW_PXP_PS_VBUF (0x000000e0)
  61335. +
  61336. +#define BP_PXP_PS_VBUF_ADDR 0
  61337. +#define BM_PXP_PS_VBUF_ADDR 0xFFFFFFFF
  61338. +#define BF_PXP_PS_VBUF_ADDR(v) (v)
  61339. +
  61340. +#define HW_PXP_PS_PITCH (0x000000f0)
  61341. +
  61342. +#define BP_PXP_PS_PITCH_RSVD 16
  61343. +#define BM_PXP_PS_PITCH_RSVD 0xFFFF0000
  61344. +#define BF_PXP_PS_PITCH_RSVD(v) \
  61345. + (((v) << 16) & BM_PXP_PS_PITCH_RSVD)
  61346. +#define BP_PXP_PS_PITCH_PITCH 0
  61347. +#define BM_PXP_PS_PITCH_PITCH 0x0000FFFF
  61348. +#define BF_PXP_PS_PITCH_PITCH(v) \
  61349. + (((v) << 0) & BM_PXP_PS_PITCH_PITCH)
  61350. +
  61351. +#define HW_PXP_PS_BACKGROUND (0x00000100)
  61352. +
  61353. +#define BP_PXP_PS_BACKGROUND_RSVD 24
  61354. +#define BM_PXP_PS_BACKGROUND_RSVD 0xFF000000
  61355. +#define BF_PXP_PS_BACKGROUND_RSVD(v) \
  61356. + (((v) << 24) & BM_PXP_PS_BACKGROUND_RSVD)
  61357. +#define BP_PXP_PS_BACKGROUND_COLOR 0
  61358. +#define BM_PXP_PS_BACKGROUND_COLOR 0x00FFFFFF
  61359. +#define BF_PXP_PS_BACKGROUND_COLOR(v) \
  61360. + (((v) << 0) & BM_PXP_PS_BACKGROUND_COLOR)
  61361. +
  61362. +#define HW_PXP_PS_SCALE (0x00000110)
  61363. +
  61364. +#define BM_PXP_PS_SCALE_RSVD2 0x80000000
  61365. +#define BP_PXP_PS_SCALE_YSCALE 16
  61366. +#define BM_PXP_PS_SCALE_YSCALE 0x7FFF0000
  61367. +#define BF_PXP_PS_SCALE_YSCALE(v) \
  61368. + (((v) << 16) & BM_PXP_PS_SCALE_YSCALE)
  61369. +#define BM_PXP_PS_SCALE_RSVD1 0x00008000
  61370. +#define BP_PXP_PS_SCALE_XSCALE 0
  61371. +#define BM_PXP_PS_SCALE_XSCALE 0x00007FFF
  61372. +#define BF_PXP_PS_SCALE_XSCALE(v) \
  61373. + (((v) << 0) & BM_PXP_PS_SCALE_XSCALE)
  61374. +
  61375. +#define HW_PXP_PS_OFFSET (0x00000120)
  61376. +
  61377. +#define BP_PXP_PS_OFFSET_RSVD2 28
  61378. +#define BM_PXP_PS_OFFSET_RSVD2 0xF0000000
  61379. +#define BF_PXP_PS_OFFSET_RSVD2(v) \
  61380. + (((v) << 28) & BM_PXP_PS_OFFSET_RSVD2)
  61381. +#define BP_PXP_PS_OFFSET_YOFFSET 16
  61382. +#define BM_PXP_PS_OFFSET_YOFFSET 0x0FFF0000
  61383. +#define BF_PXP_PS_OFFSET_YOFFSET(v) \
  61384. + (((v) << 16) & BM_PXP_PS_OFFSET_YOFFSET)
  61385. +#define BP_PXP_PS_OFFSET_RSVD1 12
  61386. +#define BM_PXP_PS_OFFSET_RSVD1 0x0000F000
  61387. +#define BF_PXP_PS_OFFSET_RSVD1(v) \
  61388. + (((v) << 12) & BM_PXP_PS_OFFSET_RSVD1)
  61389. +#define BP_PXP_PS_OFFSET_XOFFSET 0
  61390. +#define BM_PXP_PS_OFFSET_XOFFSET 0x00000FFF
  61391. +#define BF_PXP_PS_OFFSET_XOFFSET(v) \
  61392. + (((v) << 0) & BM_PXP_PS_OFFSET_XOFFSET)
  61393. +
  61394. +#define HW_PXP_PS_CLRKEYLOW (0x00000130)
  61395. +
  61396. +#define BP_PXP_PS_CLRKEYLOW_RSVD1 24
  61397. +#define BM_PXP_PS_CLRKEYLOW_RSVD1 0xFF000000
  61398. +#define BF_PXP_PS_CLRKEYLOW_RSVD1(v) \
  61399. + (((v) << 24) & BM_PXP_PS_CLRKEYLOW_RSVD1)
  61400. +#define BP_PXP_PS_CLRKEYLOW_PIXEL 0
  61401. +#define BM_PXP_PS_CLRKEYLOW_PIXEL 0x00FFFFFF
  61402. +#define BF_PXP_PS_CLRKEYLOW_PIXEL(v) \
  61403. + (((v) << 0) & BM_PXP_PS_CLRKEYLOW_PIXEL)
  61404. +
  61405. +#define HW_PXP_PS_CLRKEYHIGH (0x00000140)
  61406. +
  61407. +#define BP_PXP_PS_CLRKEYHIGH_RSVD1 24
  61408. +#define BM_PXP_PS_CLRKEYHIGH_RSVD1 0xFF000000
  61409. +#define BF_PXP_PS_CLRKEYHIGH_RSVD1(v) \
  61410. + (((v) << 24) & BM_PXP_PS_CLRKEYHIGH_RSVD1)
  61411. +#define BP_PXP_PS_CLRKEYHIGH_PIXEL 0
  61412. +#define BM_PXP_PS_CLRKEYHIGH_PIXEL 0x00FFFFFF
  61413. +#define BF_PXP_PS_CLRKEYHIGH_PIXEL(v) \
  61414. + (((v) << 0) & BM_PXP_PS_CLRKEYHIGH_PIXEL)
  61415. +
  61416. +#define HW_PXP_AS_CTRL (0x00000150)
  61417. +
  61418. +#define BP_PXP_AS_CTRL_RSVD1 21
  61419. +#define BM_PXP_AS_CTRL_RSVD1 0xFFE00000
  61420. +#define BF_PXP_AS_CTRL_RSVD1(v) \
  61421. + (((v) << 21) & BM_PXP_AS_CTRL_RSVD1)
  61422. +#define BM_PXP_AS_CTRL_ALPHA_INVERT 0x00100000
  61423. +#define BP_PXP_AS_CTRL_ROP 16
  61424. +#define BM_PXP_AS_CTRL_ROP 0x000F0000
  61425. +#define BF_PXP_AS_CTRL_ROP(v) \
  61426. + (((v) << 16) & BM_PXP_AS_CTRL_ROP)
  61427. +#define BV_PXP_AS_CTRL_ROP__MASKAS 0x0
  61428. +#define BV_PXP_AS_CTRL_ROP__MASKNOTAS 0x1
  61429. +#define BV_PXP_AS_CTRL_ROP__MASKASNOT 0x2
  61430. +#define BV_PXP_AS_CTRL_ROP__MERGEAS 0x3
  61431. +#define BV_PXP_AS_CTRL_ROP__MERGENOTAS 0x4
  61432. +#define BV_PXP_AS_CTRL_ROP__MERGEASNOT 0x5
  61433. +#define BV_PXP_AS_CTRL_ROP__NOTCOPYAS 0x6
  61434. +#define BV_PXP_AS_CTRL_ROP__NOT 0x7
  61435. +#define BV_PXP_AS_CTRL_ROP__NOTMASKAS 0x8
  61436. +#define BV_PXP_AS_CTRL_ROP__NOTMERGEAS 0x9
  61437. +#define BV_PXP_AS_CTRL_ROP__XORAS 0xA
  61438. +#define BV_PXP_AS_CTRL_ROP__NOTXORAS 0xB
  61439. +#define BP_PXP_AS_CTRL_ALPHA 8
  61440. +#define BM_PXP_AS_CTRL_ALPHA 0x0000FF00
  61441. +#define BF_PXP_AS_CTRL_ALPHA(v) \
  61442. + (((v) << 8) & BM_PXP_AS_CTRL_ALPHA)
  61443. +#define BP_PXP_AS_CTRL_FORMAT 4
  61444. +#define BM_PXP_AS_CTRL_FORMAT 0x000000F0
  61445. +#define BF_PXP_AS_CTRL_FORMAT(v) \
  61446. + (((v) << 4) & BM_PXP_AS_CTRL_FORMAT)
  61447. +#define BV_PXP_AS_CTRL_FORMAT__ARGB8888 0x0
  61448. +#define BV_PXP_AS_CTRL_FORMAT__RGB888 0x4
  61449. +#define BV_PXP_AS_CTRL_FORMAT__ARGB1555 0x8
  61450. +#define BV_PXP_AS_CTRL_FORMAT__ARGB4444 0x9
  61451. +#define BV_PXP_AS_CTRL_FORMAT__RGB555 0xC
  61452. +#define BV_PXP_AS_CTRL_FORMAT__RGB444 0xD
  61453. +#define BV_PXP_AS_CTRL_FORMAT__RGB565 0xE
  61454. +#define BM_PXP_AS_CTRL_ENABLE_COLORKEY 0x00000008
  61455. +#define BP_PXP_AS_CTRL_ALPHA_CTRL 1
  61456. +#define BM_PXP_AS_CTRL_ALPHA_CTRL 0x00000006
  61457. +#define BF_PXP_AS_CTRL_ALPHA_CTRL(v) \
  61458. + (((v) << 1) & BM_PXP_AS_CTRL_ALPHA_CTRL)
  61459. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Embedded 0x0
  61460. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Override 0x1
  61461. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply 0x2
  61462. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs 0x3
  61463. +#define BM_PXP_AS_CTRL_RSVD0 0x00000001
  61464. +
  61465. +#define HW_PXP_AS_BUF (0x00000160)
  61466. +
  61467. +#define BP_PXP_AS_BUF_ADDR 0
  61468. +#define BM_PXP_AS_BUF_ADDR 0xFFFFFFFF
  61469. +#define BF_PXP_AS_BUF_ADDR(v) (v)
  61470. +
  61471. +#define HW_PXP_AS_PITCH (0x00000170)
  61472. +
  61473. +#define BP_PXP_AS_PITCH_RSVD 16
  61474. +#define BM_PXP_AS_PITCH_RSVD 0xFFFF0000
  61475. +#define BF_PXP_AS_PITCH_RSVD(v) \
  61476. + (((v) << 16) & BM_PXP_AS_PITCH_RSVD)
  61477. +#define BP_PXP_AS_PITCH_PITCH 0
  61478. +#define BM_PXP_AS_PITCH_PITCH 0x0000FFFF
  61479. +#define BF_PXP_AS_PITCH_PITCH(v) \
  61480. + (((v) << 0) & BM_PXP_AS_PITCH_PITCH)
  61481. +
  61482. +#define HW_PXP_AS_CLRKEYLOW (0x00000180)
  61483. +
  61484. +#define BP_PXP_AS_CLRKEYLOW_RSVD1 24
  61485. +#define BM_PXP_AS_CLRKEYLOW_RSVD1 0xFF000000
  61486. +#define BF_PXP_AS_CLRKEYLOW_RSVD1(v) \
  61487. + (((v) << 24) & BM_PXP_AS_CLRKEYLOW_RSVD1)
  61488. +#define BP_PXP_AS_CLRKEYLOW_PIXEL 0
  61489. +#define BM_PXP_AS_CLRKEYLOW_PIXEL 0x00FFFFFF
  61490. +#define BF_PXP_AS_CLRKEYLOW_PIXEL(v) \
  61491. + (((v) << 0) & BM_PXP_AS_CLRKEYLOW_PIXEL)
  61492. +
  61493. +#define HW_PXP_AS_CLRKEYHIGH (0x00000190)
  61494. +
  61495. +#define BP_PXP_AS_CLRKEYHIGH_RSVD1 24
  61496. +#define BM_PXP_AS_CLRKEYHIGH_RSVD1 0xFF000000
  61497. +#define BF_PXP_AS_CLRKEYHIGH_RSVD1(v) \
  61498. + (((v) << 24) & BM_PXP_AS_CLRKEYHIGH_RSVD1)
  61499. +#define BP_PXP_AS_CLRKEYHIGH_PIXEL 0
  61500. +#define BM_PXP_AS_CLRKEYHIGH_PIXEL 0x00FFFFFF
  61501. +#define BF_PXP_AS_CLRKEYHIGH_PIXEL(v) \
  61502. + (((v) << 0) & BM_PXP_AS_CLRKEYHIGH_PIXEL)
  61503. +
  61504. +#define HW_PXP_CSC1_COEF0 (0x000001a0)
  61505. +
  61506. +#define BM_PXP_CSC1_COEF0_YCBCR_MODE 0x80000000
  61507. +#define BM_PXP_CSC1_COEF0_BYPASS 0x40000000
  61508. +#define BM_PXP_CSC1_COEF0_RSVD1 0x20000000
  61509. +#define BP_PXP_CSC1_COEF0_C0 18
  61510. +#define BM_PXP_CSC1_COEF0_C0 0x1FFC0000
  61511. +#define BF_PXP_CSC1_COEF0_C0(v) \
  61512. + (((v) << 18) & BM_PXP_CSC1_COEF0_C0)
  61513. +#define BP_PXP_CSC1_COEF0_UV_OFFSET 9
  61514. +#define BM_PXP_CSC1_COEF0_UV_OFFSET 0x0003FE00
  61515. +#define BF_PXP_CSC1_COEF0_UV_OFFSET(v) \
  61516. + (((v) << 9) & BM_PXP_CSC1_COEF0_UV_OFFSET)
  61517. +#define BP_PXP_CSC1_COEF0_Y_OFFSET 0
  61518. +#define BM_PXP_CSC1_COEF0_Y_OFFSET 0x000001FF
  61519. +#define BF_PXP_CSC1_COEF0_Y_OFFSET(v) \
  61520. + (((v) << 0) & BM_PXP_CSC1_COEF0_Y_OFFSET)
  61521. +
  61522. +#define HW_PXP_CSC1_COEF1 (0x000001b0)
  61523. +
  61524. +#define BP_PXP_CSC1_COEF1_RSVD1 27
  61525. +#define BM_PXP_CSC1_COEF1_RSVD1 0xF8000000
  61526. +#define BF_PXP_CSC1_COEF1_RSVD1(v) \
  61527. + (((v) << 27) & BM_PXP_CSC1_COEF1_RSVD1)
  61528. +#define BP_PXP_CSC1_COEF1_C1 16
  61529. +#define BM_PXP_CSC1_COEF1_C1 0x07FF0000
  61530. +#define BF_PXP_CSC1_COEF1_C1(v) \
  61531. + (((v) << 16) & BM_PXP_CSC1_COEF1_C1)
  61532. +#define BP_PXP_CSC1_COEF1_RSVD0 11
  61533. +#define BM_PXP_CSC1_COEF1_RSVD0 0x0000F800
  61534. +#define BF_PXP_CSC1_COEF1_RSVD0(v) \
  61535. + (((v) << 11) & BM_PXP_CSC1_COEF1_RSVD0)
  61536. +#define BP_PXP_CSC1_COEF1_C4 0
  61537. +#define BM_PXP_CSC1_COEF1_C4 0x000007FF
  61538. +#define BF_PXP_CSC1_COEF1_C4(v) \
  61539. + (((v) << 0) & BM_PXP_CSC1_COEF1_C4)
  61540. +
  61541. +#define HW_PXP_CSC1_COEF2 (0x000001c0)
  61542. +
  61543. +#define BP_PXP_CSC1_COEF2_RSVD1 27
  61544. +#define BM_PXP_CSC1_COEF2_RSVD1 0xF8000000
  61545. +#define BF_PXP_CSC1_COEF2_RSVD1(v) \
  61546. + (((v) << 27) & BM_PXP_CSC1_COEF2_RSVD1)
  61547. +#define BP_PXP_CSC1_COEF2_C2 16
  61548. +#define BM_PXP_CSC1_COEF2_C2 0x07FF0000
  61549. +#define BF_PXP_CSC1_COEF2_C2(v) \
  61550. + (((v) << 16) & BM_PXP_CSC1_COEF2_C2)
  61551. +#define BP_PXP_CSC1_COEF2_RSVD0 11
  61552. +#define BM_PXP_CSC1_COEF2_RSVD0 0x0000F800
  61553. +#define BF_PXP_CSC1_COEF2_RSVD0(v) \
  61554. + (((v) << 11) & BM_PXP_CSC1_COEF2_RSVD0)
  61555. +#define BP_PXP_CSC1_COEF2_C3 0
  61556. +#define BM_PXP_CSC1_COEF2_C3 0x000007FF
  61557. +#define BF_PXP_CSC1_COEF2_C3(v) \
  61558. + (((v) << 0) & BM_PXP_CSC1_COEF2_C3)
  61559. +
  61560. +#define HW_PXP_CSC2_CTRL (0x000001d0)
  61561. +
  61562. +#define BP_PXP_CSC2_CTRL_RSVD 3
  61563. +#define BM_PXP_CSC2_CTRL_RSVD 0xFFFFFFF8
  61564. +#define BF_PXP_CSC2_CTRL_RSVD(v) \
  61565. + (((v) << 3) & BM_PXP_CSC2_CTRL_RSVD)
  61566. +#define BP_PXP_CSC2_CTRL_CSC_MODE 1
  61567. +#define BM_PXP_CSC2_CTRL_CSC_MODE 0x00000006
  61568. +#define BF_PXP_CSC2_CTRL_CSC_MODE(v) \
  61569. + (((v) << 1) & BM_PXP_CSC2_CTRL_CSC_MODE)
  61570. +#define BV_PXP_CSC2_CTRL_CSC_MODE__YUV2RGB 0x0
  61571. +#define BV_PXP_CSC2_CTRL_CSC_MODE__YCbCr2RGB 0x1
  61572. +#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YUV 0x2
  61573. +#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YCbCr 0x3
  61574. +#define BM_PXP_CSC2_CTRL_BYPASS 0x00000001
  61575. +
  61576. +#define HW_PXP_CSC2_COEF0 (0x000001e0)
  61577. +
  61578. +#define BP_PXP_CSC2_COEF0_RSVD1 27
  61579. +#define BM_PXP_CSC2_COEF0_RSVD1 0xF8000000
  61580. +#define BF_PXP_CSC2_COEF0_RSVD1(v) \
  61581. + (((v) << 27) & BM_PXP_CSC2_COEF0_RSVD1)
  61582. +#define BP_PXP_CSC2_COEF0_A2 16
  61583. +#define BM_PXP_CSC2_COEF0_A2 0x07FF0000
  61584. +#define BF_PXP_CSC2_COEF0_A2(v) \
  61585. + (((v) << 16) & BM_PXP_CSC2_COEF0_A2)
  61586. +#define BP_PXP_CSC2_COEF0_RSVD0 11
  61587. +#define BM_PXP_CSC2_COEF0_RSVD0 0x0000F800
  61588. +#define BF_PXP_CSC2_COEF0_RSVD0(v) \
  61589. + (((v) << 11) & BM_PXP_CSC2_COEF0_RSVD0)
  61590. +#define BP_PXP_CSC2_COEF0_A1 0
  61591. +#define BM_PXP_CSC2_COEF0_A1 0x000007FF
  61592. +#define BF_PXP_CSC2_COEF0_A1(v) \
  61593. + (((v) << 0) & BM_PXP_CSC2_COEF0_A1)
  61594. +
  61595. +#define HW_PXP_CSC2_COEF1 (0x000001f0)
  61596. +
  61597. +#define BP_PXP_CSC2_COEF1_RSVD1 27
  61598. +#define BM_PXP_CSC2_COEF1_RSVD1 0xF8000000
  61599. +#define BF_PXP_CSC2_COEF1_RSVD1(v) \
  61600. + (((v) << 27) & BM_PXP_CSC2_COEF1_RSVD1)
  61601. +#define BP_PXP_CSC2_COEF1_B1 16
  61602. +#define BM_PXP_CSC2_COEF1_B1 0x07FF0000
  61603. +#define BF_PXP_CSC2_COEF1_B1(v) \
  61604. + (((v) << 16) & BM_PXP_CSC2_COEF1_B1)
  61605. +#define BP_PXP_CSC2_COEF1_RSVD0 11
  61606. +#define BM_PXP_CSC2_COEF1_RSVD0 0x0000F800
  61607. +#define BF_PXP_CSC2_COEF1_RSVD0(v) \
  61608. + (((v) << 11) & BM_PXP_CSC2_COEF1_RSVD0)
  61609. +#define BP_PXP_CSC2_COEF1_A3 0
  61610. +#define BM_PXP_CSC2_COEF1_A3 0x000007FF
  61611. +#define BF_PXP_CSC2_COEF1_A3(v) \
  61612. + (((v) << 0) & BM_PXP_CSC2_COEF1_A3)
  61613. +
  61614. +#define HW_PXP_CSC2_COEF2 (0x00000200)
  61615. +
  61616. +#define BP_PXP_CSC2_COEF2_RSVD1 27
  61617. +#define BM_PXP_CSC2_COEF2_RSVD1 0xF8000000
  61618. +#define BF_PXP_CSC2_COEF2_RSVD1(v) \
  61619. + (((v) << 27) & BM_PXP_CSC2_COEF2_RSVD1)
  61620. +#define BP_PXP_CSC2_COEF2_B3 16
  61621. +#define BM_PXP_CSC2_COEF2_B3 0x07FF0000
  61622. +#define BF_PXP_CSC2_COEF2_B3(v) \
  61623. + (((v) << 16) & BM_PXP_CSC2_COEF2_B3)
  61624. +#define BP_PXP_CSC2_COEF2_RSVD0 11
  61625. +#define BM_PXP_CSC2_COEF2_RSVD0 0x0000F800
  61626. +#define BF_PXP_CSC2_COEF2_RSVD0(v) \
  61627. + (((v) << 11) & BM_PXP_CSC2_COEF2_RSVD0)
  61628. +#define BP_PXP_CSC2_COEF2_B2 0
  61629. +#define BM_PXP_CSC2_COEF2_B2 0x000007FF
  61630. +#define BF_PXP_CSC2_COEF2_B2(v) \
  61631. + (((v) << 0) & BM_PXP_CSC2_COEF2_B2)
  61632. +
  61633. +#define HW_PXP_CSC2_COEF3 (0x00000210)
  61634. +
  61635. +#define BP_PXP_CSC2_COEF3_RSVD1 27
  61636. +#define BM_PXP_CSC2_COEF3_RSVD1 0xF8000000
  61637. +#define BF_PXP_CSC2_COEF3_RSVD1(v) \
  61638. + (((v) << 27) & BM_PXP_CSC2_COEF3_RSVD1)
  61639. +#define BP_PXP_CSC2_COEF3_C2 16
  61640. +#define BM_PXP_CSC2_COEF3_C2 0x07FF0000
  61641. +#define BF_PXP_CSC2_COEF3_C2(v) \
  61642. + (((v) << 16) & BM_PXP_CSC2_COEF3_C2)
  61643. +#define BP_PXP_CSC2_COEF3_RSVD0 11
  61644. +#define BM_PXP_CSC2_COEF3_RSVD0 0x0000F800
  61645. +#define BF_PXP_CSC2_COEF3_RSVD0(v) \
  61646. + (((v) << 11) & BM_PXP_CSC2_COEF3_RSVD0)
  61647. +#define BP_PXP_CSC2_COEF3_C1 0
  61648. +#define BM_PXP_CSC2_COEF3_C1 0x000007FF
  61649. +#define BF_PXP_CSC2_COEF3_C1(v) \
  61650. + (((v) << 0) & BM_PXP_CSC2_COEF3_C1)
  61651. +
  61652. +#define HW_PXP_CSC2_COEF4 (0x00000220)
  61653. +
  61654. +#define BP_PXP_CSC2_COEF4_RSVD1 25
  61655. +#define BM_PXP_CSC2_COEF4_RSVD1 0xFE000000
  61656. +#define BF_PXP_CSC2_COEF4_RSVD1(v) \
  61657. + (((v) << 25) & BM_PXP_CSC2_COEF4_RSVD1)
  61658. +#define BP_PXP_CSC2_COEF4_D1 16
  61659. +#define BM_PXP_CSC2_COEF4_D1 0x01FF0000
  61660. +#define BF_PXP_CSC2_COEF4_D1(v) \
  61661. + (((v) << 16) & BM_PXP_CSC2_COEF4_D1)
  61662. +#define BP_PXP_CSC2_COEF4_RSVD0 11
  61663. +#define BM_PXP_CSC2_COEF4_RSVD0 0x0000F800
  61664. +#define BF_PXP_CSC2_COEF4_RSVD0(v) \
  61665. + (((v) << 11) & BM_PXP_CSC2_COEF4_RSVD0)
  61666. +#define BP_PXP_CSC2_COEF4_C3 0
  61667. +#define BM_PXP_CSC2_COEF4_C3 0x000007FF
  61668. +#define BF_PXP_CSC2_COEF4_C3(v) \
  61669. + (((v) << 0) & BM_PXP_CSC2_COEF4_C3)
  61670. +
  61671. +#define HW_PXP_CSC2_COEF5 (0x00000230)
  61672. +
  61673. +#define BP_PXP_CSC2_COEF5_RSVD1 25
  61674. +#define BM_PXP_CSC2_COEF5_RSVD1 0xFE000000
  61675. +#define BF_PXP_CSC2_COEF5_RSVD1(v) \
  61676. + (((v) << 25) & BM_PXP_CSC2_COEF5_RSVD1)
  61677. +#define BP_PXP_CSC2_COEF5_D3 16
  61678. +#define BM_PXP_CSC2_COEF5_D3 0x01FF0000
  61679. +#define BF_PXP_CSC2_COEF5_D3(v) \
  61680. + (((v) << 16) & BM_PXP_CSC2_COEF5_D3)
  61681. +#define BP_PXP_CSC2_COEF5_RSVD0 9
  61682. +#define BM_PXP_CSC2_COEF5_RSVD0 0x0000FE00
  61683. +#define BF_PXP_CSC2_COEF5_RSVD0(v) \
  61684. + (((v) << 9) & BM_PXP_CSC2_COEF5_RSVD0)
  61685. +#define BP_PXP_CSC2_COEF5_D2 0
  61686. +#define BM_PXP_CSC2_COEF5_D2 0x000001FF
  61687. +#define BF_PXP_CSC2_COEF5_D2(v) \
  61688. + (((v) << 0) & BM_PXP_CSC2_COEF5_D2)
  61689. +
  61690. +#define HW_PXP_LUT_CTRL (0x00000240)
  61691. +
  61692. +#define BM_PXP_LUT_CTRL_BYPASS 0x80000000
  61693. +#define BP_PXP_LUT_CTRL_RSVD3 26
  61694. +#define BM_PXP_LUT_CTRL_RSVD3 0x7C000000
  61695. +#define BF_PXP_LUT_CTRL_RSVD3(v) \
  61696. + (((v) << 26) & BM_PXP_LUT_CTRL_RSVD3)
  61697. +#define BP_PXP_LUT_CTRL_LOOKUP_MODE 24
  61698. +#define BM_PXP_LUT_CTRL_LOOKUP_MODE 0x03000000
  61699. +#define BF_PXP_LUT_CTRL_LOOKUP_MODE(v) \
  61700. + (((v) << 24) & BM_PXP_LUT_CTRL_LOOKUP_MODE)
  61701. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__CACHE_RGB565 0x0
  61702. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8 0x1
  61703. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB444 0x2
  61704. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB454 0x3
  61705. +#define BP_PXP_LUT_CTRL_RSVD2 18
  61706. +#define BM_PXP_LUT_CTRL_RSVD2 0x00FC0000
  61707. +#define BF_PXP_LUT_CTRL_RSVD2(v) \
  61708. + (((v) << 18) & BM_PXP_LUT_CTRL_RSVD2)
  61709. +#define BP_PXP_LUT_CTRL_OUT_MODE 16
  61710. +#define BM_PXP_LUT_CTRL_OUT_MODE 0x00030000
  61711. +#define BF_PXP_LUT_CTRL_OUT_MODE(v) \
  61712. + (((v) << 16) & BM_PXP_LUT_CTRL_OUT_MODE)
  61713. +#define BV_PXP_LUT_CTRL_OUT_MODE__RESERVED 0x0
  61714. +#define BV_PXP_LUT_CTRL_OUT_MODE__Y8 0x1
  61715. +#define BV_PXP_LUT_CTRL_OUT_MODE__RGBW4444CFA 0x2
  61716. +#define BV_PXP_LUT_CTRL_OUT_MODE__RGB888 0x3
  61717. +#define BP_PXP_LUT_CTRL_RSVD1 11
  61718. +#define BM_PXP_LUT_CTRL_RSVD1 0x0000F800
  61719. +#define BF_PXP_LUT_CTRL_RSVD1(v) \
  61720. + (((v) << 11) & BM_PXP_LUT_CTRL_RSVD1)
  61721. +#define BM_PXP_LUT_CTRL_SEL_8KB 0x00000400
  61722. +#define BM_PXP_LUT_CTRL_LRU_UPD 0x00000200
  61723. +#define BM_PXP_LUT_CTRL_INVALID 0x00000100
  61724. +#define BP_PXP_LUT_CTRL_RSVD0 1
  61725. +#define BM_PXP_LUT_CTRL_RSVD0 0x000000FE
  61726. +#define BF_PXP_LUT_CTRL_RSVD0(v) \
  61727. + (((v) << 1) & BM_PXP_LUT_CTRL_RSVD0)
  61728. +#define BM_PXP_LUT_CTRL_DMA_START 0x00000001
  61729. +
  61730. +#define HW_PXP_LUT_ADDR (0x00000250)
  61731. +
  61732. +#define BM_PXP_LUT_ADDR_RSVD2 0x80000000
  61733. +#define BP_PXP_LUT_ADDR_NUM_BYTES 16
  61734. +#define BM_PXP_LUT_ADDR_NUM_BYTES 0x7FFF0000
  61735. +#define BF_PXP_LUT_ADDR_NUM_BYTES(v) \
  61736. + (((v) << 16) & BM_PXP_LUT_ADDR_NUM_BYTES)
  61737. +#define BP_PXP_LUT_ADDR_RSVD1 14
  61738. +#define BM_PXP_LUT_ADDR_RSVD1 0x0000C000
  61739. +#define BF_PXP_LUT_ADDR_RSVD1(v) \
  61740. + (((v) << 14) & BM_PXP_LUT_ADDR_RSVD1)
  61741. +#define BP_PXP_LUT_ADDR_ADDR 0
  61742. +#define BM_PXP_LUT_ADDR_ADDR 0x00003FFF
  61743. +#define BF_PXP_LUT_ADDR_ADDR(v) \
  61744. + (((v) << 0) & BM_PXP_LUT_ADDR_ADDR)
  61745. +
  61746. +#define HW_PXP_LUT_DATA (0x00000260)
  61747. +
  61748. +#define BP_PXP_LUT_DATA_DATA 0
  61749. +#define BM_PXP_LUT_DATA_DATA 0xFFFFFFFF
  61750. +#define BF_PXP_LUT_DATA_DATA(v) (v)
  61751. +
  61752. +#define HW_PXP_LUT_EXTMEM (0x00000270)
  61753. +
  61754. +#define BP_PXP_LUT_EXTMEM_ADDR 0
  61755. +#define BM_PXP_LUT_EXTMEM_ADDR 0xFFFFFFFF
  61756. +#define BF_PXP_LUT_EXTMEM_ADDR(v) (v)
  61757. +
  61758. +#define HW_PXP_CFA (0x00000280)
  61759. +
  61760. +#define BP_PXP_CFA_DATA 0
  61761. +#define BM_PXP_CFA_DATA 0xFFFFFFFF
  61762. +#define BF_PXP_CFA_DATA(v) (v)
  61763. +
  61764. +#define HW_PXP_HIST_CTRL (0x00000290)
  61765. +
  61766. +#define BP_PXP_HIST_CTRL_RSVD 6
  61767. +#define BM_PXP_HIST_CTRL_RSVD 0xFFFFFFC0
  61768. +#define BF_PXP_HIST_CTRL_RSVD(v) \
  61769. + (((v) << 6) & BM_PXP_HIST_CTRL_RSVD)
  61770. +#define BP_PXP_HIST_CTRL_PANEL_MODE 4
  61771. +#define BM_PXP_HIST_CTRL_PANEL_MODE 0x00000030
  61772. +#define BF_PXP_HIST_CTRL_PANEL_MODE(v) \
  61773. + (((v) << 4) & BM_PXP_HIST_CTRL_PANEL_MODE)
  61774. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY4 0x0
  61775. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY8 0x1
  61776. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY16 0x2
  61777. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY32 0x3
  61778. +#define BP_PXP_HIST_CTRL_STATUS 0
  61779. +#define BM_PXP_HIST_CTRL_STATUS 0x0000000F
  61780. +#define BF_PXP_HIST_CTRL_STATUS(v) \
  61781. + (((v) << 0) & BM_PXP_HIST_CTRL_STATUS)
  61782. +
  61783. +#define HW_PXP_HIST2_PARAM (0x000002a0)
  61784. +
  61785. +#define BP_PXP_HIST2_PARAM_RSVD 16
  61786. +#define BM_PXP_HIST2_PARAM_RSVD 0xFFFF0000
  61787. +#define BF_PXP_HIST2_PARAM_RSVD(v) \
  61788. + (((v) << 16) & BM_PXP_HIST2_PARAM_RSVD)
  61789. +#define BP_PXP_HIST2_PARAM_RSVD1 13
  61790. +#define BM_PXP_HIST2_PARAM_RSVD1 0x0000E000
  61791. +#define BF_PXP_HIST2_PARAM_RSVD1(v) \
  61792. + (((v) << 13) & BM_PXP_HIST2_PARAM_RSVD1)
  61793. +#define BP_PXP_HIST2_PARAM_VALUE1 8
  61794. +#define BM_PXP_HIST2_PARAM_VALUE1 0x00001F00
  61795. +#define BF_PXP_HIST2_PARAM_VALUE1(v) \
  61796. + (((v) << 8) & BM_PXP_HIST2_PARAM_VALUE1)
  61797. +#define BP_PXP_HIST2_PARAM_RSVD0 5
  61798. +#define BM_PXP_HIST2_PARAM_RSVD0 0x000000E0
  61799. +#define BF_PXP_HIST2_PARAM_RSVD0(v) \
  61800. + (((v) << 5) & BM_PXP_HIST2_PARAM_RSVD0)
  61801. +#define BP_PXP_HIST2_PARAM_VALUE0 0
  61802. +#define BM_PXP_HIST2_PARAM_VALUE0 0x0000001F
  61803. +#define BF_PXP_HIST2_PARAM_VALUE0(v) \
  61804. + (((v) << 0) & BM_PXP_HIST2_PARAM_VALUE0)
  61805. +
  61806. +#define HW_PXP_HIST4_PARAM (0x000002b0)
  61807. +
  61808. +#define BP_PXP_HIST4_PARAM_RSVD3 29
  61809. +#define BM_PXP_HIST4_PARAM_RSVD3 0xE0000000
  61810. +#define BF_PXP_HIST4_PARAM_RSVD3(v) \
  61811. + (((v) << 29) & BM_PXP_HIST4_PARAM_RSVD3)
  61812. +#define BP_PXP_HIST4_PARAM_VALUE3 24
  61813. +#define BM_PXP_HIST4_PARAM_VALUE3 0x1F000000
  61814. +#define BF_PXP_HIST4_PARAM_VALUE3(v) \
  61815. + (((v) << 24) & BM_PXP_HIST4_PARAM_VALUE3)
  61816. +#define BP_PXP_HIST4_PARAM_RSVD2 21
  61817. +#define BM_PXP_HIST4_PARAM_RSVD2 0x00E00000
  61818. +#define BF_PXP_HIST4_PARAM_RSVD2(v) \
  61819. + (((v) << 21) & BM_PXP_HIST4_PARAM_RSVD2)
  61820. +#define BP_PXP_HIST4_PARAM_VALUE2 16
  61821. +#define BM_PXP_HIST4_PARAM_VALUE2 0x001F0000
  61822. +#define BF_PXP_HIST4_PARAM_VALUE2(v) \
  61823. + (((v) << 16) & BM_PXP_HIST4_PARAM_VALUE2)
  61824. +#define BP_PXP_HIST4_PARAM_RSVD1 13
  61825. +#define BM_PXP_HIST4_PARAM_RSVD1 0x0000E000
  61826. +#define BF_PXP_HIST4_PARAM_RSVD1(v) \
  61827. + (((v) << 13) & BM_PXP_HIST4_PARAM_RSVD1)
  61828. +#define BP_PXP_HIST4_PARAM_VALUE1 8
  61829. +#define BM_PXP_HIST4_PARAM_VALUE1 0x00001F00
  61830. +#define BF_PXP_HIST4_PARAM_VALUE1(v) \
  61831. + (((v) << 8) & BM_PXP_HIST4_PARAM_VALUE1)
  61832. +#define BP_PXP_HIST4_PARAM_RSVD0 5
  61833. +#define BM_PXP_HIST4_PARAM_RSVD0 0x000000E0
  61834. +#define BF_PXP_HIST4_PARAM_RSVD0(v) \
  61835. + (((v) << 5) & BM_PXP_HIST4_PARAM_RSVD0)
  61836. +#define BP_PXP_HIST4_PARAM_VALUE0 0
  61837. +#define BM_PXP_HIST4_PARAM_VALUE0 0x0000001F
  61838. +#define BF_PXP_HIST4_PARAM_VALUE0(v) \
  61839. + (((v) << 0) & BM_PXP_HIST4_PARAM_VALUE0)
  61840. +
  61841. +#define HW_PXP_HIST8_PARAM0 (0x000002c0)
  61842. +
  61843. +#define BP_PXP_HIST8_PARAM0_RSVD3 29
  61844. +#define BM_PXP_HIST8_PARAM0_RSVD3 0xE0000000
  61845. +#define BF_PXP_HIST8_PARAM0_RSVD3(v) \
  61846. + (((v) << 29) & BM_PXP_HIST8_PARAM0_RSVD3)
  61847. +#define BP_PXP_HIST8_PARAM0_VALUE3 24
  61848. +#define BM_PXP_HIST8_PARAM0_VALUE3 0x1F000000
  61849. +#define BF_PXP_HIST8_PARAM0_VALUE3(v) \
  61850. + (((v) << 24) & BM_PXP_HIST8_PARAM0_VALUE3)
  61851. +#define BP_PXP_HIST8_PARAM0_RSVD2 21
  61852. +#define BM_PXP_HIST8_PARAM0_RSVD2 0x00E00000
  61853. +#define BF_PXP_HIST8_PARAM0_RSVD2(v) \
  61854. + (((v) << 21) & BM_PXP_HIST8_PARAM0_RSVD2)
  61855. +#define BP_PXP_HIST8_PARAM0_VALUE2 16
  61856. +#define BM_PXP_HIST8_PARAM0_VALUE2 0x001F0000
  61857. +#define BF_PXP_HIST8_PARAM0_VALUE2(v) \
  61858. + (((v) << 16) & BM_PXP_HIST8_PARAM0_VALUE2)
  61859. +#define BP_PXP_HIST8_PARAM0_RSVD1 13
  61860. +#define BM_PXP_HIST8_PARAM0_RSVD1 0x0000E000
  61861. +#define BF_PXP_HIST8_PARAM0_RSVD1(v) \
  61862. + (((v) << 13) & BM_PXP_HIST8_PARAM0_RSVD1)
  61863. +#define BP_PXP_HIST8_PARAM0_VALUE1 8
  61864. +#define BM_PXP_HIST8_PARAM0_VALUE1 0x00001F00
  61865. +#define BF_PXP_HIST8_PARAM0_VALUE1(v) \
  61866. + (((v) << 8) & BM_PXP_HIST8_PARAM0_VALUE1)
  61867. +#define BP_PXP_HIST8_PARAM0_RSVD0 5
  61868. +#define BM_PXP_HIST8_PARAM0_RSVD0 0x000000E0
  61869. +#define BF_PXP_HIST8_PARAM0_RSVD0(v) \
  61870. + (((v) << 5) & BM_PXP_HIST8_PARAM0_RSVD0)
  61871. +#define BP_PXP_HIST8_PARAM0_VALUE0 0
  61872. +#define BM_PXP_HIST8_PARAM0_VALUE0 0x0000001F
  61873. +#define BF_PXP_HIST8_PARAM0_VALUE0(v) \
  61874. + (((v) << 0) & BM_PXP_HIST8_PARAM0_VALUE0)
  61875. +
  61876. +#define HW_PXP_HIST8_PARAM1 (0x000002d0)
  61877. +
  61878. +#define BP_PXP_HIST8_PARAM1_RSVD7 29
  61879. +#define BM_PXP_HIST8_PARAM1_RSVD7 0xE0000000
  61880. +#define BF_PXP_HIST8_PARAM1_RSVD7(v) \
  61881. + (((v) << 29) & BM_PXP_HIST8_PARAM1_RSVD7)
  61882. +#define BP_PXP_HIST8_PARAM1_VALUE7 24
  61883. +#define BM_PXP_HIST8_PARAM1_VALUE7 0x1F000000
  61884. +#define BF_PXP_HIST8_PARAM1_VALUE7(v) \
  61885. + (((v) << 24) & BM_PXP_HIST8_PARAM1_VALUE7)
  61886. +#define BP_PXP_HIST8_PARAM1_RSVD6 21
  61887. +#define BM_PXP_HIST8_PARAM1_RSVD6 0x00E00000
  61888. +#define BF_PXP_HIST8_PARAM1_RSVD6(v) \
  61889. + (((v) << 21) & BM_PXP_HIST8_PARAM1_RSVD6)
  61890. +#define BP_PXP_HIST8_PARAM1_VALUE6 16
  61891. +#define BM_PXP_HIST8_PARAM1_VALUE6 0x001F0000
  61892. +#define BF_PXP_HIST8_PARAM1_VALUE6(v) \
  61893. + (((v) << 16) & BM_PXP_HIST8_PARAM1_VALUE6)
  61894. +#define BP_PXP_HIST8_PARAM1_RSVD5 13
  61895. +#define BM_PXP_HIST8_PARAM1_RSVD5 0x0000E000
  61896. +#define BF_PXP_HIST8_PARAM1_RSVD5(v) \
  61897. + (((v) << 13) & BM_PXP_HIST8_PARAM1_RSVD5)
  61898. +#define BP_PXP_HIST8_PARAM1_VALUE5 8
  61899. +#define BM_PXP_HIST8_PARAM1_VALUE5 0x00001F00
  61900. +#define BF_PXP_HIST8_PARAM1_VALUE5(v) \
  61901. + (((v) << 8) & BM_PXP_HIST8_PARAM1_VALUE5)
  61902. +#define BP_PXP_HIST8_PARAM1_RSVD4 5
  61903. +#define BM_PXP_HIST8_PARAM1_RSVD4 0x000000E0
  61904. +#define BF_PXP_HIST8_PARAM1_RSVD4(v) \
  61905. + (((v) << 5) & BM_PXP_HIST8_PARAM1_RSVD4)
  61906. +#define BP_PXP_HIST8_PARAM1_VALUE4 0
  61907. +#define BM_PXP_HIST8_PARAM1_VALUE4 0x0000001F
  61908. +#define BF_PXP_HIST8_PARAM1_VALUE4(v) \
  61909. + (((v) << 0) & BM_PXP_HIST8_PARAM1_VALUE4)
  61910. +
  61911. +#define HW_PXP_HIST16_PARAM0 (0x000002e0)
  61912. +
  61913. +#define BP_PXP_HIST16_PARAM0_RSVD3 29
  61914. +#define BM_PXP_HIST16_PARAM0_RSVD3 0xE0000000
  61915. +#define BF_PXP_HIST16_PARAM0_RSVD3(v) \
  61916. + (((v) << 29) & BM_PXP_HIST16_PARAM0_RSVD3)
  61917. +#define BP_PXP_HIST16_PARAM0_VALUE3 24
  61918. +#define BM_PXP_HIST16_PARAM0_VALUE3 0x1F000000
  61919. +#define BF_PXP_HIST16_PARAM0_VALUE3(v) \
  61920. + (((v) << 24) & BM_PXP_HIST16_PARAM0_VALUE3)
  61921. +#define BP_PXP_HIST16_PARAM0_RSVD2 21
  61922. +#define BM_PXP_HIST16_PARAM0_RSVD2 0x00E00000
  61923. +#define BF_PXP_HIST16_PARAM0_RSVD2(v) \
  61924. + (((v) << 21) & BM_PXP_HIST16_PARAM0_RSVD2)
  61925. +#define BP_PXP_HIST16_PARAM0_VALUE2 16
  61926. +#define BM_PXP_HIST16_PARAM0_VALUE2 0x001F0000
  61927. +#define BF_PXP_HIST16_PARAM0_VALUE2(v) \
  61928. + (((v) << 16) & BM_PXP_HIST16_PARAM0_VALUE2)
  61929. +#define BP_PXP_HIST16_PARAM0_RSVD1 13
  61930. +#define BM_PXP_HIST16_PARAM0_RSVD1 0x0000E000
  61931. +#define BF_PXP_HIST16_PARAM0_RSVD1(v) \
  61932. + (((v) << 13) & BM_PXP_HIST16_PARAM0_RSVD1)
  61933. +#define BP_PXP_HIST16_PARAM0_VALUE1 8
  61934. +#define BM_PXP_HIST16_PARAM0_VALUE1 0x00001F00
  61935. +#define BF_PXP_HIST16_PARAM0_VALUE1(v) \
  61936. + (((v) << 8) & BM_PXP_HIST16_PARAM0_VALUE1)
  61937. +#define BP_PXP_HIST16_PARAM0_RSVD0 5
  61938. +#define BM_PXP_HIST16_PARAM0_RSVD0 0x000000E0
  61939. +#define BF_PXP_HIST16_PARAM0_RSVD0(v) \
  61940. + (((v) << 5) & BM_PXP_HIST16_PARAM0_RSVD0)
  61941. +#define BP_PXP_HIST16_PARAM0_VALUE0 0
  61942. +#define BM_PXP_HIST16_PARAM0_VALUE0 0x0000001F
  61943. +#define BF_PXP_HIST16_PARAM0_VALUE0(v) \
  61944. + (((v) << 0) & BM_PXP_HIST16_PARAM0_VALUE0)
  61945. +
  61946. +#define HW_PXP_HIST16_PARAM1 (0x000002f0)
  61947. +
  61948. +#define BP_PXP_HIST16_PARAM1_RSVD7 29
  61949. +#define BM_PXP_HIST16_PARAM1_RSVD7 0xE0000000
  61950. +#define BF_PXP_HIST16_PARAM1_RSVD7(v) \
  61951. + (((v) << 29) & BM_PXP_HIST16_PARAM1_RSVD7)
  61952. +#define BP_PXP_HIST16_PARAM1_VALUE7 24
  61953. +#define BM_PXP_HIST16_PARAM1_VALUE7 0x1F000000
  61954. +#define BF_PXP_HIST16_PARAM1_VALUE7(v) \
  61955. + (((v) << 24) & BM_PXP_HIST16_PARAM1_VALUE7)
  61956. +#define BP_PXP_HIST16_PARAM1_RSVD6 21
  61957. +#define BM_PXP_HIST16_PARAM1_RSVD6 0x00E00000
  61958. +#define BF_PXP_HIST16_PARAM1_RSVD6(v) \
  61959. + (((v) << 21) & BM_PXP_HIST16_PARAM1_RSVD6)
  61960. +#define BP_PXP_HIST16_PARAM1_VALUE6 16
  61961. +#define BM_PXP_HIST16_PARAM1_VALUE6 0x001F0000
  61962. +#define BF_PXP_HIST16_PARAM1_VALUE6(v) \
  61963. + (((v) << 16) & BM_PXP_HIST16_PARAM1_VALUE6)
  61964. +#define BP_PXP_HIST16_PARAM1_RSVD5 13
  61965. +#define BM_PXP_HIST16_PARAM1_RSVD5 0x0000E000
  61966. +#define BF_PXP_HIST16_PARAM1_RSVD5(v) \
  61967. + (((v) << 13) & BM_PXP_HIST16_PARAM1_RSVD5)
  61968. +#define BP_PXP_HIST16_PARAM1_VALUE5 8
  61969. +#define BM_PXP_HIST16_PARAM1_VALUE5 0x00001F00
  61970. +#define BF_PXP_HIST16_PARAM1_VALUE5(v) \
  61971. + (((v) << 8) & BM_PXP_HIST16_PARAM1_VALUE5)
  61972. +#define BP_PXP_HIST16_PARAM1_RSVD4 5
  61973. +#define BM_PXP_HIST16_PARAM1_RSVD4 0x000000E0
  61974. +#define BF_PXP_HIST16_PARAM1_RSVD4(v) \
  61975. + (((v) << 5) & BM_PXP_HIST16_PARAM1_RSVD4)
  61976. +#define BP_PXP_HIST16_PARAM1_VALUE4 0
  61977. +#define BM_PXP_HIST16_PARAM1_VALUE4 0x0000001F
  61978. +#define BF_PXP_HIST16_PARAM1_VALUE4(v) \
  61979. + (((v) << 0) & BM_PXP_HIST16_PARAM1_VALUE4)
  61980. +
  61981. +#define HW_PXP_HIST16_PARAM2 (0x00000300)
  61982. +
  61983. +#define BP_PXP_HIST16_PARAM2_RSVD11 29
  61984. +#define BM_PXP_HIST16_PARAM2_RSVD11 0xE0000000
  61985. +#define BF_PXP_HIST16_PARAM2_RSVD11(v) \
  61986. + (((v) << 29) & BM_PXP_HIST16_PARAM2_RSVD11)
  61987. +#define BP_PXP_HIST16_PARAM2_VALUE11 24
  61988. +#define BM_PXP_HIST16_PARAM2_VALUE11 0x1F000000
  61989. +#define BF_PXP_HIST16_PARAM2_VALUE11(v) \
  61990. + (((v) << 24) & BM_PXP_HIST16_PARAM2_VALUE11)
  61991. +#define BP_PXP_HIST16_PARAM2_RSVD10 21
  61992. +#define BM_PXP_HIST16_PARAM2_RSVD10 0x00E00000
  61993. +#define BF_PXP_HIST16_PARAM2_RSVD10(v) \
  61994. + (((v) << 21) & BM_PXP_HIST16_PARAM2_RSVD10)
  61995. +#define BP_PXP_HIST16_PARAM2_VALUE10 16
  61996. +#define BM_PXP_HIST16_PARAM2_VALUE10 0x001F0000
  61997. +#define BF_PXP_HIST16_PARAM2_VALUE10(v) \
  61998. + (((v) << 16) & BM_PXP_HIST16_PARAM2_VALUE10)
  61999. +#define BP_PXP_HIST16_PARAM2_RSVD9 13
  62000. +#define BM_PXP_HIST16_PARAM2_RSVD9 0x0000E000
  62001. +#define BF_PXP_HIST16_PARAM2_RSVD9(v) \
  62002. + (((v) << 13) & BM_PXP_HIST16_PARAM2_RSVD9)
  62003. +#define BP_PXP_HIST16_PARAM2_VALUE9 8
  62004. +#define BM_PXP_HIST16_PARAM2_VALUE9 0x00001F00
  62005. +#define BF_PXP_HIST16_PARAM2_VALUE9(v) \
  62006. + (((v) << 8) & BM_PXP_HIST16_PARAM2_VALUE9)
  62007. +#define BP_PXP_HIST16_PARAM2_RSVD8 5
  62008. +#define BM_PXP_HIST16_PARAM2_RSVD8 0x000000E0
  62009. +#define BF_PXP_HIST16_PARAM2_RSVD8(v) \
  62010. + (((v) << 5) & BM_PXP_HIST16_PARAM2_RSVD8)
  62011. +#define BP_PXP_HIST16_PARAM2_VALUE8 0
  62012. +#define BM_PXP_HIST16_PARAM2_VALUE8 0x0000001F
  62013. +#define BF_PXP_HIST16_PARAM2_VALUE8(v) \
  62014. + (((v) << 0) & BM_PXP_HIST16_PARAM2_VALUE8)
  62015. +
  62016. +#define HW_PXP_HIST16_PARAM3 (0x00000310)
  62017. +
  62018. +#define BP_PXP_HIST16_PARAM3_RSVD15 29
  62019. +#define BM_PXP_HIST16_PARAM3_RSVD15 0xE0000000
  62020. +#define BF_PXP_HIST16_PARAM3_RSVD15(v) \
  62021. + (((v) << 29) & BM_PXP_HIST16_PARAM3_RSVD15)
  62022. +#define BP_PXP_HIST16_PARAM3_VALUE15 24
  62023. +#define BM_PXP_HIST16_PARAM3_VALUE15 0x1F000000
  62024. +#define BF_PXP_HIST16_PARAM3_VALUE15(v) \
  62025. + (((v) << 24) & BM_PXP_HIST16_PARAM3_VALUE15)
  62026. +#define BP_PXP_HIST16_PARAM3_RSVD14 21
  62027. +#define BM_PXP_HIST16_PARAM3_RSVD14 0x00E00000
  62028. +#define BF_PXP_HIST16_PARAM3_RSVD14(v) \
  62029. + (((v) << 21) & BM_PXP_HIST16_PARAM3_RSVD14)
  62030. +#define BP_PXP_HIST16_PARAM3_VALUE14 16
  62031. +#define BM_PXP_HIST16_PARAM3_VALUE14 0x001F0000
  62032. +#define BF_PXP_HIST16_PARAM3_VALUE14(v) \
  62033. + (((v) << 16) & BM_PXP_HIST16_PARAM3_VALUE14)
  62034. +#define BP_PXP_HIST16_PARAM3_RSVD13 13
  62035. +#define BM_PXP_HIST16_PARAM3_RSVD13 0x0000E000
  62036. +#define BF_PXP_HIST16_PARAM3_RSVD13(v) \
  62037. + (((v) << 13) & BM_PXP_HIST16_PARAM3_RSVD13)
  62038. +#define BP_PXP_HIST16_PARAM3_VALUE13 8
  62039. +#define BM_PXP_HIST16_PARAM3_VALUE13 0x00001F00
  62040. +#define BF_PXP_HIST16_PARAM3_VALUE13(v) \
  62041. + (((v) << 8) & BM_PXP_HIST16_PARAM3_VALUE13)
  62042. +#define BP_PXP_HIST16_PARAM3_RSVD12 5
  62043. +#define BM_PXP_HIST16_PARAM3_RSVD12 0x000000E0
  62044. +#define BF_PXP_HIST16_PARAM3_RSVD12(v) \
  62045. + (((v) << 5) & BM_PXP_HIST16_PARAM3_RSVD12)
  62046. +#define BP_PXP_HIST16_PARAM3_VALUE12 0
  62047. +#define BM_PXP_HIST16_PARAM3_VALUE12 0x0000001F
  62048. +#define BF_PXP_HIST16_PARAM3_VALUE12(v) \
  62049. + (((v) << 0) & BM_PXP_HIST16_PARAM3_VALUE12)
  62050. +
  62051. +#define HW_PXP_POWER (0x00000320)
  62052. +
  62053. +#define BP_PXP_POWER_CTRL 12
  62054. +#define BM_PXP_POWER_CTRL 0xFFFFF000
  62055. +#define BF_PXP_POWER_CTRL(v) \
  62056. + (((v) << 12) & BM_PXP_POWER_CTRL)
  62057. +#define BP_PXP_POWER_ROT_MEM_LP_STATE 9
  62058. +#define BM_PXP_POWER_ROT_MEM_LP_STATE 0x00000E00
  62059. +#define BF_PXP_POWER_ROT_MEM_LP_STATE(v) \
  62060. + (((v) << 9) & BM_PXP_POWER_ROT_MEM_LP_STATE)
  62061. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__NONE 0x0
  62062. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__LS 0x1
  62063. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__DS 0x2
  62064. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__SD 0x4
  62065. +#define BP_PXP_POWER_LUT_LP_STATE_WAY1_BANKN 6
  62066. +#define BM_PXP_POWER_LUT_LP_STATE_WAY1_BANKN 0x000001C0
  62067. +#define BF_PXP_POWER_LUT_LP_STATE_WAY1_BANKN(v) \
  62068. + (((v) << 6) & BM_PXP_POWER_LUT_LP_STATE_WAY1_BANKN)
  62069. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__NONE 0x0
  62070. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__LS 0x1
  62071. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__DS 0x2
  62072. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__SD 0x4
  62073. +#define BP_PXP_POWER_LUT_LP_STATE_WAY0_BANKN 3
  62074. +#define BM_PXP_POWER_LUT_LP_STATE_WAY0_BANKN 0x00000038
  62075. +#define BF_PXP_POWER_LUT_LP_STATE_WAY0_BANKN(v) \
  62076. + (((v) << 3) & BM_PXP_POWER_LUT_LP_STATE_WAY0_BANKN)
  62077. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__NONE 0x0
  62078. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__LS 0x1
  62079. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__DS 0x2
  62080. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__SD 0x4
  62081. +#define BP_PXP_POWER_LUT_LP_STATE_WAY0_BANK0 0
  62082. +#define BM_PXP_POWER_LUT_LP_STATE_WAY0_BANK0 0x00000007
  62083. +#define BF_PXP_POWER_LUT_LP_STATE_WAY0_BANK0(v) \
  62084. + (((v) << 0) & BM_PXP_POWER_LUT_LP_STATE_WAY0_BANK0)
  62085. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__NONE 0x0
  62086. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__LS 0x1
  62087. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__DS 0x2
  62088. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__SD 0x4
  62089. +
  62090. +#define HW_PXP_NEXT (0x00000400)
  62091. +
  62092. +#define BP_PXP_NEXT_POINTER 2
  62093. +#define BM_PXP_NEXT_POINTER 0xFFFFFFFC
  62094. +#define BF_PXP_NEXT_POINTER(v) \
  62095. + (((v) << 2) & BM_PXP_NEXT_POINTER)
  62096. +#define BM_PXP_NEXT_RSVD 0x00000002
  62097. +#define BM_PXP_NEXT_ENABLED 0x00000001
  62098. +
  62099. +#define HW_PXP_DEBUGCTRL (0x00000410)
  62100. +
  62101. +#define BP_PXP_DEBUGCTRL_RSVD 12
  62102. +#define BM_PXP_DEBUGCTRL_RSVD 0xFFFFF000
  62103. +#define BF_PXP_DEBUGCTRL_RSVD(v) \
  62104. + (((v) << 12) & BM_PXP_DEBUGCTRL_RSVD)
  62105. +#define BP_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 8
  62106. +#define BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 0x00000F00
  62107. +#define BF_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT(v) \
  62108. + (((v) << 8) & BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT)
  62109. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__NONE 0x0
  62110. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MISS_CNT 0x1
  62111. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__HIT_CNT 0x2
  62112. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__LAT_CNT 0x4
  62113. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MAX_LAT 0x8
  62114. +#define BP_PXP_DEBUGCTRL_SELECT 0
  62115. +#define BM_PXP_DEBUGCTRL_SELECT 0x000000FF
  62116. +#define BF_PXP_DEBUGCTRL_SELECT(v) \
  62117. + (((v) << 0) & BM_PXP_DEBUGCTRL_SELECT)
  62118. +#define BV_PXP_DEBUGCTRL_SELECT__NONE 0x0
  62119. +#define BV_PXP_DEBUGCTRL_SELECT__CTRL 0x1
  62120. +#define BV_PXP_DEBUGCTRL_SELECT__PSBUF 0x2
  62121. +#define BV_PXP_DEBUGCTRL_SELECT__PSBAX 0x3
  62122. +#define BV_PXP_DEBUGCTRL_SELECT__PSBAY 0x4
  62123. +#define BV_PXP_DEBUGCTRL_SELECT__ASBUF 0x5
  62124. +#define BV_PXP_DEBUGCTRL_SELECT__ROTATION 0x6
  62125. +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF0 0x7
  62126. +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF1 0x8
  62127. +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF2 0x9
  62128. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_STAT 0x10
  62129. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_MISS 0x11
  62130. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_HIT 0x12
  62131. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_LAT 0x13
  62132. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_MAX_LAT 0x14
  62133. +
  62134. +#define HW_PXP_DEBUG (0x00000420)
  62135. +
  62136. +#define BP_PXP_DEBUG_DATA 0
  62137. +#define BM_PXP_DEBUG_DATA 0xFFFFFFFF
  62138. +#define BF_PXP_DEBUG_DATA(v) (v)
  62139. +
  62140. +#define HW_PXP_VERSION (0x00000430)
  62141. +
  62142. +#define BP_PXP_VERSION_MAJOR 24
  62143. +#define BM_PXP_VERSION_MAJOR 0xFF000000
  62144. +#define BF_PXP_VERSION_MAJOR(v) \
  62145. + (((v) << 24) & BM_PXP_VERSION_MAJOR)
  62146. +#define BP_PXP_VERSION_MINOR 16
  62147. +#define BM_PXP_VERSION_MINOR 0x00FF0000
  62148. +#define BF_PXP_VERSION_MINOR(v) \
  62149. + (((v) << 16) & BM_PXP_VERSION_MINOR)
  62150. +#define BP_PXP_VERSION_STEP 0
  62151. +#define BM_PXP_VERSION_STEP 0x0000FFFF
  62152. +#define BF_PXP_VERSION_STEP(v) \
  62153. + (((v) << 0) & BM_PXP_VERSION_STEP)
  62154. +#endif /* __ARCH_ARM___PXP_H */
  62155. diff -Nur linux-3.14.15/drivers/gpio/gpio-pca953x.c linux-linaro-stable-mx6/drivers/gpio/gpio-pca953x.c
  62156. --- linux-3.14.15/drivers/gpio/gpio-pca953x.c 2014-07-31 23:51:43.000000000 +0200
  62157. +++ linux-linaro-stable-mx6/drivers/gpio/gpio-pca953x.c 2014-08-20 19:31:42.948855355 +0200
  62158. @@ -19,6 +19,7 @@
  62159. #include <linux/irqdomain.h>
  62160. #include <linux/i2c.h>
  62161. #include <linux/platform_data/pca953x.h>
  62162. +#include <linux/reset.h>
  62163. #include <linux/slab.h>
  62164. #ifdef CONFIG_OF_GPIO
  62165. #include <linux/of_platform.h>
  62166. @@ -741,6 +742,10 @@
  62167. mutex_init(&chip->i2c_lock);
  62168. + ret = device_reset(&client->dev);
  62169. + if (ret == -ENODEV)
  62170. + return -EPROBE_DEFER;
  62171. +
  62172. /* initialize cached registers from their original values.
  62173. * we can't share this chip with another i2c master.
  62174. */
  62175. diff -Nur linux-3.14.15/drivers/gpu/drm/drm_crtc_helper.c linux-linaro-stable-mx6/drivers/gpu/drm/drm_crtc_helper.c
  62176. --- linux-3.14.15/drivers/gpu/drm/drm_crtc_helper.c 2014-07-31 23:51:43.000000000 +0200
  62177. +++ linux-linaro-stable-mx6/drivers/gpu/drm/drm_crtc_helper.c 2014-08-20 19:31:43.004855596 +0200
  62178. @@ -564,7 +564,7 @@
  62179. * Caller must hold mode config lock.
  62180. *
  62181. * Setup a new configuration, provided by the upper layers (either an ioctl call
  62182. - * from userspace or internally e.g. from the fbdev suppport code) in @set, and
  62183. + * from userspace or internally e.g. from the fbdev support code) in @set, and
  62184. * enable it. This is the main helper functions for drivers that implement
  62185. * kernel mode setting with the crtc helper functions and the assorted
  62186. * ->prepare(), ->modeset() and ->commit() helper callbacks.
  62187. diff -Nur linux-3.14.15/drivers/gpu/drm/drm_prime.c linux-linaro-stable-mx6/drivers/gpu/drm/drm_prime.c
  62188. --- linux-3.14.15/drivers/gpu/drm/drm_prime.c 2014-07-31 23:51:43.000000000 +0200
  62189. +++ linux-linaro-stable-mx6/drivers/gpu/drm/drm_prime.c 2014-08-20 19:31:43.024855681 +0200
  62190. @@ -471,7 +471,7 @@
  62191. get_dma_buf(dma_buf);
  62192. sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
  62193. - if (IS_ERR_OR_NULL(sgt)) {
  62194. + if (IS_ERR(sgt)) {
  62195. ret = PTR_ERR(sgt);
  62196. goto fail_detach;
  62197. }
  62198. diff -Nur linux-3.14.15/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c linux-linaro-stable-mx6/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
  62199. --- linux-3.14.15/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 2014-07-31 23:51:43.000000000 +0200
  62200. +++ linux-linaro-stable-mx6/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 2014-08-20 19:31:43.032855716 +0200
  62201. @@ -224,7 +224,7 @@
  62202. get_dma_buf(dma_buf);
  62203. sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
  62204. - if (IS_ERR_OR_NULL(sgt)) {
  62205. + if (IS_ERR(sgt)) {
  62206. ret = PTR_ERR(sgt);
  62207. goto err_buf_detach;
  62208. }
  62209. diff -Nur linux-3.14.15/drivers/gpu/drm/Kconfig linux-linaro-stable-mx6/drivers/gpu/drm/Kconfig
  62210. --- linux-3.14.15/drivers/gpu/drm/Kconfig 2014-07-31 23:51:43.000000000 +0200
  62211. +++ linux-linaro-stable-mx6/drivers/gpu/drm/Kconfig 2014-08-20 19:31:42.988855528 +0200
  62212. @@ -166,6 +166,13 @@
  62213. Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
  62214. chipset. If M is selected the module will be called savage.
  62215. +config DRM_VIVANTE
  62216. + tristate "Vivante GCCore"
  62217. + depends on DRM
  62218. + help
  62219. + Choose this option if you have a Vivante graphics card.
  62220. + If M is selected, the module will be called vivante.
  62221. +
  62222. source "drivers/gpu/drm/exynos/Kconfig"
  62223. source "drivers/gpu/drm/vmwgfx/Kconfig"
  62224. diff -Nur linux-3.14.15/drivers/gpu/drm/Makefile linux-linaro-stable-mx6/drivers/gpu/drm/Makefile
  62225. --- linux-3.14.15/drivers/gpu/drm/Makefile 2014-07-31 23:51:43.000000000 +0200
  62226. +++ linux-linaro-stable-mx6/drivers/gpu/drm/Makefile 2014-08-20 19:31:42.988855528 +0200
  62227. @@ -1,3 +1,24 @@
  62228. +##############################################################################
  62229. +#
  62230. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  62231. +#
  62232. +# This program is free software; you can redistribute it and/or modify
  62233. +# it under the terms of the GNU General Public License as published by
  62234. +# the Free Software Foundation; either version 2 of the license, or
  62235. +# (at your option) any later version.
  62236. +#
  62237. +# This program is distributed in the hope that it will be useful,
  62238. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  62239. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  62240. +# GNU General Public License for more details.
  62241. +#
  62242. +# You should have received a copy of the GNU General Public License
  62243. +# along with this program; if not write to the Free Software
  62244. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  62245. +#
  62246. +##############################################################################
  62247. +
  62248. +
  62249. #
  62250. # Makefile for the drm device driver. This driver provides support for the
  62251. # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
  62252. @@ -35,6 +56,7 @@
  62253. obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
  62254. obj-$(CONFIG_DRM_USB) += drm_usb.o
  62255. obj-$(CONFIG_DRM_TTM) += ttm/
  62256. +obj-$(CONFIG_DRM_VIVANTE) += vivante/
  62257. obj-$(CONFIG_DRM_TDFX) += tdfx/
  62258. obj-$(CONFIG_DRM_R128) += r128/
  62259. obj-$(CONFIG_DRM_RADEON)+= radeon/
  62260. diff -Nur linux-3.14.15/drivers/gpu/drm/radeon/cik.c linux-linaro-stable-mx6/drivers/gpu/drm/radeon/cik.c
  62261. --- linux-3.14.15/drivers/gpu/drm/radeon/cik.c 2014-07-31 23:51:43.000000000 +0200
  62262. +++ linux-linaro-stable-mx6/drivers/gpu/drm/radeon/cik.c 2014-08-20 19:31:43.456857536 +0200
  62263. @@ -2219,7 +2219,6 @@
  62264. gb_tile_moden = 0;
  62265. break;
  62266. }
  62267. - rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden;
  62268. WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
  62269. }
  62270. } else if (num_pipe_configs == 8) {
  62271. @@ -7271,7 +7270,6 @@
  62272. tmp = RREG32(IH_RB_CNTL);
  62273. tmp |= IH_WPTR_OVERFLOW_CLEAR;
  62274. WREG32(IH_RB_CNTL, tmp);
  62275. - wptr &= ~RB_OVERFLOW;
  62276. }
  62277. return (wptr & rdev->ih.ptr_mask);
  62278. }
  62279. diff -Nur linux-3.14.15/drivers/gpu/drm/radeon/evergreen.c linux-linaro-stable-mx6/drivers/gpu/drm/radeon/evergreen.c
  62280. --- linux-3.14.15/drivers/gpu/drm/radeon/evergreen.c 2014-07-31 23:51:43.000000000 +0200
  62281. +++ linux-linaro-stable-mx6/drivers/gpu/drm/radeon/evergreen.c 2014-08-20 19:31:43.472857603 +0200
  62282. @@ -4763,7 +4763,6 @@
  62283. tmp = RREG32(IH_RB_CNTL);
  62284. tmp |= IH_WPTR_OVERFLOW_CLEAR;
  62285. WREG32(IH_RB_CNTL, tmp);
  62286. - wptr &= ~RB_OVERFLOW;
  62287. }
  62288. return (wptr & rdev->ih.ptr_mask);
  62289. }
  62290. diff -Nur linux-3.14.15/drivers/gpu/drm/radeon/r600.c linux-linaro-stable-mx6/drivers/gpu/drm/radeon/r600.c
  62291. --- linux-3.14.15/drivers/gpu/drm/radeon/r600.c 2014-07-31 23:51:43.000000000 +0200
  62292. +++ linux-linaro-stable-mx6/drivers/gpu/drm/radeon/r600.c 2014-08-20 19:31:43.496857707 +0200
  62293. @@ -3795,7 +3795,6 @@
  62294. tmp = RREG32(IH_RB_CNTL);
  62295. tmp |= IH_WPTR_OVERFLOW_CLEAR;
  62296. WREG32(IH_RB_CNTL, tmp);
  62297. - wptr &= ~RB_OVERFLOW;
  62298. }
  62299. return (wptr & rdev->ih.ptr_mask);
  62300. }
  62301. diff -Nur linux-3.14.15/drivers/gpu/drm/radeon/si.c linux-linaro-stable-mx6/drivers/gpu/drm/radeon/si.c
  62302. --- linux-3.14.15/drivers/gpu/drm/radeon/si.c 2014-07-31 23:51:43.000000000 +0200
  62303. +++ linux-linaro-stable-mx6/drivers/gpu/drm/radeon/si.c 2014-08-20 19:31:43.540857895 +0200
  62304. @@ -6098,7 +6098,6 @@
  62305. tmp = RREG32(IH_RB_CNTL);
  62306. tmp |= IH_WPTR_OVERFLOW_CLEAR;
  62307. WREG32(IH_RB_CNTL, tmp);
  62308. - wptr &= ~RB_OVERFLOW;
  62309. }
  62310. return (wptr & rdev->ih.ptr_mask);
  62311. }
  62312. diff -Nur linux-3.14.15/drivers/gpu/drm/vivante/Makefile linux-linaro-stable-mx6/drivers/gpu/drm/vivante/Makefile
  62313. --- linux-3.14.15/drivers/gpu/drm/vivante/Makefile 1970-01-01 01:00:00.000000000 +0100
  62314. +++ linux-linaro-stable-mx6/drivers/gpu/drm/vivante/Makefile 2014-08-20 19:23:51.450836839 +0200
  62315. @@ -0,0 +1,29 @@
  62316. +##############################################################################
  62317. +#
  62318. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  62319. +#
  62320. +# This program is free software; you can redistribute it and/or modify
  62321. +# it under the terms of the GNU General Public License as published by
  62322. +# the Free Software Foundation; either version 2 of the license, or
  62323. +# (at your option) any later version.
  62324. +#
  62325. +# This program is distributed in the hope that it will be useful,
  62326. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  62327. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  62328. +# GNU General Public License for more details.
  62329. +#
  62330. +# You should have received a copy of the GNU General Public License
  62331. +# along with this program; if not write to the Free Software
  62332. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  62333. +#
  62334. +##############################################################################
  62335. +
  62336. +
  62337. +#
  62338. +# Makefile for the drm device driver. This driver provides support for the
  62339. +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
  62340. +
  62341. +ccflags-y := -Iinclude/drm
  62342. +vivante-y := vivante_drv.o
  62343. +
  62344. +obj-$(CONFIG_DRM_VIVANTE) += vivante.o
  62345. diff -Nur linux-3.14.15/drivers/gpu/drm/vivante/vivante_drv.c linux-linaro-stable-mx6/drivers/gpu/drm/vivante/vivante_drv.c
  62346. --- linux-3.14.15/drivers/gpu/drm/vivante/vivante_drv.c 1970-01-01 01:00:00.000000000 +0100
  62347. +++ linux-linaro-stable-mx6/drivers/gpu/drm/vivante/vivante_drv.c 2014-08-20 19:31:43.580858068 +0200
  62348. @@ -0,0 +1,108 @@
  62349. +/****************************************************************************
  62350. +*
  62351. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  62352. +*
  62353. +* This program is free software; you can redistribute it and/or modify
  62354. +* it under the terms of the GNU General Public License as published by
  62355. +* the Free Software Foundation; either version 2 of the license, or
  62356. +* (at your option) any later version.
  62357. +*
  62358. +* This program is distributed in the hope that it will be useful,
  62359. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  62360. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  62361. +* GNU General Public License for more details.
  62362. +*
  62363. +* You should have received a copy of the GNU General Public License
  62364. +* along with this program; if not write to the Free Software
  62365. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  62366. +*
  62367. +*****************************************************************************/
  62368. +
  62369. +
  62370. +/* vivante_drv.c -- vivante driver -*- linux-c -*-
  62371. + *
  62372. + *
  62373. + * Permission is hereby granted, free of charge, to any person obtaining a
  62374. + * copy of this software and associated documentation files (the "Software"),
  62375. + * to deal in the Software without restriction, including without limitation
  62376. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  62377. + * and/or sell copies of the Software, and to permit persons to whom the
  62378. + * Software is furnished to do so, subject to the following conditions:
  62379. + *
  62380. + * The above copyright notice and this permission notice (including the next
  62381. + * paragraph) shall be included in all copies or substantial portions of the
  62382. + * Software.
  62383. + *
  62384. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  62385. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  62386. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  62387. + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  62388. + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  62389. + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  62390. + * DEALINGS IN THE SOFTWARE.
  62391. + *
  62392. + * Authors:
  62393. + * Rickard E. (Rik) Faith <faith@valinux.com>
  62394. + * Daryll Strauss <daryll@valinux.com>
  62395. + * Gareth Hughes <gareth@valinux.com>
  62396. + */
  62397. +
  62398. +#include <linux/version.h>
  62399. +#include <linux/module.h>
  62400. +
  62401. +#include "drmP.h"
  62402. +#include "vivante_drv.h"
  62403. +
  62404. +#include "drm_pciids.h"
  62405. +
  62406. +static char platformdevicename[] = "Vivante GCCore";
  62407. +static struct platform_device *pplatformdev;
  62408. +
  62409. +static const struct file_operations viv_driver_fops = {
  62410. + .owner = THIS_MODULE,
  62411. + .open = drm_open,
  62412. + .release = drm_release,
  62413. + .unlocked_ioctl = drm_ioctl,
  62414. + .mmap = drm_mmap,
  62415. + .poll = drm_poll,
  62416. + .llseek = noop_llseek,
  62417. +};
  62418. +
  62419. +static struct drm_driver driver = {
  62420. + .fops = &viv_driver_fops,
  62421. + .name = DRIVER_NAME,
  62422. + .desc = DRIVER_DESC,
  62423. + .date = DRIVER_DATE,
  62424. + .major = DRIVER_MAJOR,
  62425. + .minor = DRIVER_MINOR,
  62426. + .patchlevel = DRIVER_PATCHLEVEL,
  62427. +};
  62428. +
  62429. +static int __init vivante_init(void)
  62430. +{
  62431. + int retcode;
  62432. +
  62433. + pplatformdev = platform_device_register_simple(platformdevicename,
  62434. + -1, NULL, 0);
  62435. + if (pplatformdev == NULL)
  62436. + printk(KERN_ERR"Platform device is null\n");
  62437. +
  62438. + retcode = drm_platform_init(&driver, pplatformdev);
  62439. +
  62440. + return retcode;
  62441. +}
  62442. +
  62443. +static void __exit vivante_exit(void)
  62444. +{
  62445. + if (pplatformdev) {
  62446. + platform_device_unregister(pplatformdev);
  62447. + pplatformdev = NULL;
  62448. + }
  62449. +}
  62450. +
  62451. +module_init(vivante_init);
  62452. +module_exit(vivante_exit);
  62453. +
  62454. +MODULE_AUTHOR(DRIVER_AUTHOR);
  62455. +MODULE_DESCRIPTION(DRIVER_DESC);
  62456. +MODULE_LICENSE("GPL and additional rights");
  62457. diff -Nur linux-3.14.15/drivers/gpu/drm/vivante/vivante_drv.h linux-linaro-stable-mx6/drivers/gpu/drm/vivante/vivante_drv.h
  62458. --- linux-3.14.15/drivers/gpu/drm/vivante/vivante_drv.h 1970-01-01 01:00:00.000000000 +0100
  62459. +++ linux-linaro-stable-mx6/drivers/gpu/drm/vivante/vivante_drv.h 2014-08-20 19:23:51.450836839 +0200
  62460. @@ -0,0 +1,66 @@
  62461. +/****************************************************************************
  62462. +*
  62463. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  62464. +*
  62465. +* This program is free software; you can redistribute it and/or modify
  62466. +* it under the terms of the GNU General Public License as published by
  62467. +* the Free Software Foundation; either version 2 of the license, or
  62468. +* (at your option) any later version.
  62469. +*
  62470. +* This program is distributed in the hope that it will be useful,
  62471. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  62472. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  62473. +* GNU General Public License for more details.
  62474. +*
  62475. +* You should have received a copy of the GNU General Public License
  62476. +* along with this program; if not write to the Free Software
  62477. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  62478. +*
  62479. +*****************************************************************************/
  62480. +
  62481. +
  62482. +/* vivante_drv.h -- Vivante DRM template customization -*- linux-c -*-
  62483. + * Created: Wed Feb 14 12:32:32 2012 by John Zhao
  62484. + */
  62485. +/*
  62486. + *
  62487. + * Permission is hereby granted, free of charge, to any person obtaining a
  62488. + * copy of this software and associated documentation files (the "Software"),
  62489. + * to deal in the Software without restriction, including without limitation
  62490. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  62491. + * and/or sell copies of the Software, and to permit persons to whom the
  62492. + * Software is furnished to do so, subject to the following conditions:
  62493. + *
  62494. + * The above copyright notice and this permission notice (including the next
  62495. + * paragraph) shall be included in all copies or substantial portions of the
  62496. + * Software.
  62497. + *
  62498. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  62499. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  62500. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  62501. + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  62502. + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  62503. + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  62504. + * OTHER DEALINGS IN THE SOFTWARE.
  62505. + *
  62506. + * Authors:
  62507. + * Gareth Hughes <gareth@valinux.com>
  62508. + */
  62509. +
  62510. +#ifndef __VIVANTE_DRV_H__
  62511. +#define __VIVANTE_DRV_H__
  62512. +
  62513. +/* General customization:
  62514. + */
  62515. +
  62516. +#define DRIVER_AUTHOR "Vivante Inc."
  62517. +
  62518. +#define DRIVER_NAME "vivante"
  62519. +#define DRIVER_DESC "Vivante GCCore"
  62520. +#define DRIVER_DATE "20120216"
  62521. +
  62522. +#define DRIVER_MAJOR 1
  62523. +#define DRIVER_MINOR 0
  62524. +#define DRIVER_PATCHLEVEL 0
  62525. +
  62526. +#endif
  62527. diff -Nur linux-3.14.15/drivers/hwmon/Kconfig linux-linaro-stable-mx6/drivers/hwmon/Kconfig
  62528. --- linux-3.14.15/drivers/hwmon/Kconfig 2014-07-31 23:51:43.000000000 +0200
  62529. +++ linux-linaro-stable-mx6/drivers/hwmon/Kconfig 2014-08-20 19:31:43.636858307 +0200
  62530. @@ -1584,4 +1584,19 @@
  62531. endif # ACPI
  62532. +config SENSORS_MAG3110
  62533. + tristate "Freescale MAG3110 e-compass sensor"
  62534. + depends on I2C && SYSFS
  62535. + help
  62536. + If you say yes here you get support for the Freescale MAG3110
  62537. + e-compass sensor.
  62538. + This driver can also be built as a module. If so, the module
  62539. + will be called mag3110.
  62540. +
  62541. +config MXC_MMA8451
  62542. + tristate "MMA8451 device driver"
  62543. + depends on I2C
  62544. + depends on INPUT_POLLDEV
  62545. + default y
  62546. +
  62547. endif # HWMON
  62548. diff -Nur linux-3.14.15/drivers/hwmon/mag3110.c linux-linaro-stable-mx6/drivers/hwmon/mag3110.c
  62549. --- linux-3.14.15/drivers/hwmon/mag3110.c 1970-01-01 01:00:00.000000000 +0100
  62550. +++ linux-linaro-stable-mx6/drivers/hwmon/mag3110.c 2014-08-20 19:23:51.638837642 +0200
  62551. @@ -0,0 +1,611 @@
  62552. +/*
  62553. + *
  62554. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  62555. + *
  62556. + * This program is free software; you can redistribute it and/or modify
  62557. + * it under the terms of the GNU General Public License as published by
  62558. + * the Free Software Foundation; either version 2 of the License, or
  62559. + * (at your option) any later version.
  62560. +
  62561. + * This program is distributed in the hope that it will be useful,
  62562. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  62563. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  62564. + * GNU General Public License for more details.
  62565. +
  62566. + * You should have received a copy of the GNU General Public License along
  62567. + * with this program; if not, write to the Free Software Foundation, Inc.,
  62568. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  62569. + */
  62570. +
  62571. +#include <linux/module.h>
  62572. +#include <linux/kernel.h>
  62573. +#include <linux/slab.h>
  62574. +#include <linux/interrupt.h>
  62575. +#include <linux/delay.h>
  62576. +#include <linux/i2c.h>
  62577. +#include <linux/irq.h>
  62578. +#include <linux/platform_device.h>
  62579. +#include <linux/input-polldev.h>
  62580. +#include <linux/hwmon.h>
  62581. +#include <linux/input.h>
  62582. +#include <linux/wait.h>
  62583. +#include <linux/workqueue.h>
  62584. +#include <linux/of.h>
  62585. +#include <linux/regulator/consumer.h>
  62586. +
  62587. +#define MAG3110_DRV_NAME "mag3110"
  62588. +#define MAG3110_ID 0xC4
  62589. +#define MAG3110_XYZ_DATA_LEN 6
  62590. +#define MAG3110_STATUS_ZYXDR 0x08
  62591. +
  62592. +#define MAG3110_AC_MASK (0x01)
  62593. +#define MAG3110_AC_OFFSET 0
  62594. +#define MAG3110_DR_MODE_MASK (0x7 << 5)
  62595. +#define MAG3110_DR_MODE_OFFSET 5
  62596. +#define MAG3110_IRQ_USED 0
  62597. +
  62598. +#define POLL_INTERVAL_MAX 500
  62599. +#define POLL_INTERVAL 100
  62600. +#define INT_TIMEOUT 1000
  62601. +#define DEFAULT_POSITION 2
  62602. +/* register enum for mag3110 registers */
  62603. +enum {
  62604. + MAG3110_DR_STATUS = 0x00,
  62605. + MAG3110_OUT_X_MSB,
  62606. + MAG3110_OUT_X_LSB,
  62607. + MAG3110_OUT_Y_MSB,
  62608. + MAG3110_OUT_Y_LSB,
  62609. + MAG3110_OUT_Z_MSB,
  62610. + MAG3110_OUT_Z_LSB,
  62611. + MAG3110_WHO_AM_I,
  62612. +
  62613. + MAG3110_OFF_X_MSB,
  62614. + MAG3110_OFF_X_LSB,
  62615. + MAG3110_OFF_Y_MSB,
  62616. + MAG3110_OFF_Y_LSB,
  62617. + MAG3110_OFF_Z_MSB,
  62618. + MAG3110_OFF_Z_LSB,
  62619. +
  62620. + MAG3110_DIE_TEMP,
  62621. +
  62622. + MAG3110_CTRL_REG1 = 0x10,
  62623. + MAG3110_CTRL_REG2,
  62624. +};
  62625. +enum {
  62626. + MAG_STANDBY,
  62627. + MAG_ACTIVED
  62628. +};
  62629. +struct mag3110_data {
  62630. + struct i2c_client *client;
  62631. + struct input_polled_dev *poll_dev;
  62632. + struct device *hwmon_dev;
  62633. + wait_queue_head_t waitq;
  62634. + bool data_ready;
  62635. + u8 ctl_reg1;
  62636. + int active;
  62637. + int position;
  62638. +};
  62639. +static short MAGHAL[8][3][3] = {
  62640. + { {0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
  62641. + { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} },
  62642. + { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} },
  62643. + { {-1, 0, 0}, {0, -1, 0}, {0, 0, 1} },
  62644. +
  62645. + { {0, 1, 0}, {1, 0, 0}, {0, 0, -1} },
  62646. + { {1, 0, 0}, {0, -1, 0}, {0, 0, -1} },
  62647. + { {0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
  62648. + { {-1, 0, 0}, {0, 1, 0}, {0, 0, -1} },
  62649. +};
  62650. +
  62651. +static struct mag3110_data *mag3110_pdata;
  62652. +/*!
  62653. + * This function do one mag3110 register read.
  62654. + */
  62655. +static DEFINE_MUTEX(mag3110_lock);
  62656. +static int mag3110_adjust_position(short *x, short *y, short *z)
  62657. +{
  62658. + short rawdata[3], data[3];
  62659. + int i, j;
  62660. + int position = mag3110_pdata->position;
  62661. + if (position < 0 || position > 7)
  62662. + position = 0;
  62663. + rawdata[0] = *x;
  62664. + rawdata[1] = *y;
  62665. + rawdata[2] = *z;
  62666. + for (i = 0; i < 3; i++) {
  62667. + data[i] = 0;
  62668. + for (j = 0; j < 3; j++)
  62669. + data[i] += rawdata[j] * MAGHAL[position][i][j];
  62670. + }
  62671. + *x = data[0];
  62672. + *y = data[1];
  62673. + *z = data[2];
  62674. + return 0;
  62675. +}
  62676. +
  62677. +static int mag3110_read_reg(struct i2c_client *client, u8 reg)
  62678. +{
  62679. + return i2c_smbus_read_byte_data(client, reg);
  62680. +}
  62681. +
  62682. +/*!
  62683. + * This function do one mag3110 register write.
  62684. + */
  62685. +static int mag3110_write_reg(struct i2c_client *client, u8 reg, char value)
  62686. +{
  62687. + int ret;
  62688. +
  62689. + ret = i2c_smbus_write_byte_data(client, reg, value);
  62690. + if (ret < 0)
  62691. + dev_err(&client->dev, "i2c write failed\n");
  62692. + return ret;
  62693. +}
  62694. +
  62695. +/*!
  62696. + * This function do multiple mag3110 registers read.
  62697. + */
  62698. +static int mag3110_read_block_data(struct i2c_client *client, u8 reg,
  62699. + int count, u8 *addr)
  62700. +{
  62701. + if (i2c_smbus_read_i2c_block_data(client, reg, count, addr) < count) {
  62702. + dev_err(&client->dev, "i2c block read failed\n");
  62703. + return -1;
  62704. + }
  62705. +
  62706. + return count;
  62707. +}
  62708. +
  62709. +/*
  62710. + * Initialization function
  62711. + */
  62712. +static int mag3110_init_client(struct i2c_client *client)
  62713. +{
  62714. + int val, ret;
  62715. +
  62716. + /* enable automatic resets */
  62717. + val = 0x80;
  62718. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG2, val);
  62719. +
  62720. + /* set default data rate to 10HZ */
  62721. + val = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  62722. + val |= (0x0 << MAG3110_DR_MODE_OFFSET);
  62723. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, val);
  62724. +
  62725. + return ret;
  62726. +}
  62727. +
  62728. +/***************************************************************
  62729. +*
  62730. +* read sensor data from mag3110
  62731. +*
  62732. +***************************************************************/
  62733. +static int mag3110_read_data(short *x, short *y, short *z)
  62734. +{
  62735. + struct mag3110_data *data;
  62736. + int retry = 3;
  62737. + u8 tmp_data[MAG3110_XYZ_DATA_LEN];
  62738. + int result;
  62739. + if (!mag3110_pdata || mag3110_pdata->active == MAG_STANDBY)
  62740. + return -EINVAL;
  62741. +
  62742. + data = mag3110_pdata;
  62743. +#if MAG3110_IRQ_USED
  62744. + if (!wait_event_interruptible_timeout
  62745. + (data->waitq, data->data_ready != 0,
  62746. + msecs_to_jiffies(INT_TIMEOUT))) {
  62747. + dev_dbg(&data->client->dev, "interrupt not received\n");
  62748. + return -ETIME;
  62749. + }
  62750. +#else
  62751. + do {
  62752. + msleep(1);
  62753. + result = i2c_smbus_read_byte_data(data->client,
  62754. + MAG3110_DR_STATUS);
  62755. + retry--;
  62756. + } while (!(result & MAG3110_STATUS_ZYXDR) && retry > 0);
  62757. + /* Clear data_ready flag after data is read out */
  62758. + if (retry == 0)
  62759. + return -EINVAL;
  62760. +#endif
  62761. +
  62762. + data->data_ready = 0;
  62763. +
  62764. + if (mag3110_read_block_data(data->client,
  62765. + MAG3110_OUT_X_MSB, MAG3110_XYZ_DATA_LEN,
  62766. + tmp_data) < 0)
  62767. + return -1;
  62768. +
  62769. + *x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
  62770. + *y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
  62771. + *z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
  62772. +
  62773. + return 0;
  62774. +}
  62775. +
  62776. +static void report_abs(void)
  62777. +{
  62778. + struct input_dev *idev;
  62779. + short x, y, z;
  62780. +
  62781. + mutex_lock(&mag3110_lock);
  62782. + if (mag3110_read_data(&x, &y, &z) != 0)
  62783. + goto out;
  62784. + mag3110_adjust_position(&x, &y, &z);
  62785. + idev = mag3110_pdata->poll_dev->input;
  62786. + input_report_abs(idev, ABS_X, x);
  62787. + input_report_abs(idev, ABS_Y, y);
  62788. + input_report_abs(idev, ABS_Z, z);
  62789. + input_sync(idev);
  62790. +out:
  62791. + mutex_unlock(&mag3110_lock);
  62792. +}
  62793. +
  62794. +static void mag3110_dev_poll(struct input_polled_dev *dev)
  62795. +{
  62796. + report_abs();
  62797. +}
  62798. +
  62799. +#if MAG3110_IRQ_USED
  62800. +static irqreturn_t mag3110_irq_handler(int irq, void *dev_id)
  62801. +{
  62802. + mag3110_pdata->data_ready = 1;
  62803. + wake_up_interruptible(&mag3110_pdata->waitq);
  62804. +
  62805. + return IRQ_HANDLED;
  62806. +}
  62807. +#endif
  62808. +static ssize_t mag3110_enable_show(struct device *dev,
  62809. + struct device_attribute *attr, char *buf)
  62810. +{
  62811. + struct i2c_client *client;
  62812. + int val;
  62813. + mutex_lock(&mag3110_lock);
  62814. + client = mag3110_pdata->client;
  62815. + val = mag3110_read_reg(client, MAG3110_CTRL_REG1) & MAG3110_AC_MASK;
  62816. +
  62817. + mutex_unlock(&mag3110_lock);
  62818. + return sprintf(buf, "%d\n", val);
  62819. +}
  62820. +
  62821. +static ssize_t mag3110_enable_store(struct device *dev,
  62822. + struct device_attribute *attr,
  62823. + const char *buf, size_t count)
  62824. +{
  62825. + struct i2c_client *client;
  62826. + int reg, ret;
  62827. + long enable;
  62828. + u8 tmp_data[MAG3110_XYZ_DATA_LEN];
  62829. +
  62830. + ret = strict_strtol(buf, 10, &enable);
  62831. + if (ret) {
  62832. + dev_err(dev, "string to long error\n");
  62833. + return ret;
  62834. + }
  62835. +
  62836. + mutex_lock(&mag3110_lock);
  62837. + client = mag3110_pdata->client;
  62838. + reg = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  62839. + if (enable && mag3110_pdata->active == MAG_STANDBY) {
  62840. + reg |= MAG3110_AC_MASK;
  62841. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
  62842. + if (!ret)
  62843. + mag3110_pdata->active = MAG_ACTIVED;
  62844. + } else if (!enable && mag3110_pdata->active == MAG_ACTIVED) {
  62845. + reg &= ~MAG3110_AC_MASK;
  62846. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
  62847. + if (!ret)
  62848. + mag3110_pdata->active = MAG_STANDBY;
  62849. + }
  62850. +
  62851. + if (mag3110_pdata->active == MAG_ACTIVED) {
  62852. + msleep(100);
  62853. + /* Read out MSB data to clear interrupt flag automatically */
  62854. + mag3110_read_block_data(client, MAG3110_OUT_X_MSB,
  62855. + MAG3110_XYZ_DATA_LEN, tmp_data);
  62856. + }
  62857. + mutex_unlock(&mag3110_lock);
  62858. + return count;
  62859. +}
  62860. +
  62861. +static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
  62862. + mag3110_enable_show, mag3110_enable_store);
  62863. +
  62864. +static ssize_t mag3110_dr_mode_show(struct device *dev,
  62865. + struct device_attribute *attr, char *buf)
  62866. +{
  62867. + struct i2c_client *client;
  62868. + int val;
  62869. +
  62870. + client = mag3110_pdata->client;
  62871. + val = (mag3110_read_reg(client, MAG3110_CTRL_REG1)
  62872. + & MAG3110_DR_MODE_MASK) >> MAG3110_DR_MODE_OFFSET;
  62873. +
  62874. + return sprintf(buf, "%d\n", val);
  62875. +}
  62876. +
  62877. +static ssize_t mag3110_dr_mode_store(struct device *dev,
  62878. + struct device_attribute *attr,
  62879. + const char *buf, size_t count)
  62880. +{
  62881. + struct i2c_client *client;
  62882. + int reg, ret;
  62883. + unsigned long val;
  62884. +
  62885. + /* This must be done when mag3110 is disabled */
  62886. + if ((strict_strtoul(buf, 10, &val) < 0) || (val > 7))
  62887. + return -EINVAL;
  62888. +
  62889. + client = mag3110_pdata->client;
  62890. + reg = mag3110_read_reg(client, MAG3110_CTRL_REG1) &
  62891. + ~MAG3110_DR_MODE_MASK;
  62892. + reg |= (val << MAG3110_DR_MODE_OFFSET);
  62893. + /* MAG3110_CTRL_REG1 bit 5-7: data rate mode */
  62894. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
  62895. + if (ret < 0)
  62896. + return ret;
  62897. +
  62898. + return count;
  62899. +}
  62900. +
  62901. +static DEVICE_ATTR(dr_mode, S_IWUSR | S_IRUGO,
  62902. + mag3110_dr_mode_show, mag3110_dr_mode_store);
  62903. +
  62904. +static ssize_t mag3110_position_show(struct device *dev,
  62905. + struct device_attribute *attr, char *buf)
  62906. +{
  62907. + int val;
  62908. + mutex_lock(&mag3110_lock);
  62909. + val = mag3110_pdata->position;
  62910. + mutex_unlock(&mag3110_lock);
  62911. + return sprintf(buf, "%d\n", val);
  62912. +}
  62913. +
  62914. +static ssize_t mag3110_position_store(struct device *dev,
  62915. + struct device_attribute *attr,
  62916. + const char *buf, size_t count)
  62917. +{
  62918. + long position;
  62919. + int ret;
  62920. + ret = strict_strtol(buf, 10, &position);
  62921. + if (ret) {
  62922. + dev_err(dev, "string to long error\n");
  62923. + return ret;
  62924. + }
  62925. +
  62926. + mutex_lock(&mag3110_lock);
  62927. + mag3110_pdata->position = (int)position;
  62928. + mutex_unlock(&mag3110_lock);
  62929. + return count;
  62930. +}
  62931. +
  62932. +static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
  62933. + mag3110_position_show, mag3110_position_store);
  62934. +
  62935. +static struct attribute *mag3110_attributes[] = {
  62936. + &dev_attr_enable.attr,
  62937. + &dev_attr_dr_mode.attr,
  62938. + &dev_attr_position.attr,
  62939. + NULL
  62940. +};
  62941. +
  62942. +static const struct attribute_group mag3110_attr_group = {
  62943. + .attrs = mag3110_attributes,
  62944. +};
  62945. +
  62946. +static int mag3110_probe(struct i2c_client *client,
  62947. + const struct i2c_device_id *id)
  62948. +{
  62949. + struct i2c_adapter *adapter;
  62950. + struct input_dev *idev;
  62951. + struct mag3110_data *data;
  62952. + int ret = 0;
  62953. + struct regulator *vdd, *vdd_io;
  62954. + u32 pos = 0;
  62955. + struct device_node *of_node = client->dev.of_node;
  62956. + vdd = NULL;
  62957. + vdd_io = NULL;
  62958. +
  62959. + vdd = devm_regulator_get(&client->dev, "vdd");
  62960. + if (!IS_ERR(vdd)) {
  62961. + ret = regulator_enable(vdd);
  62962. + if (ret) {
  62963. + dev_err(&client->dev, "vdd set voltage error\n");
  62964. + return ret;
  62965. + }
  62966. + }
  62967. +
  62968. + vdd_io = devm_regulator_get(&client->dev, "vddio");
  62969. + if (!IS_ERR(vdd_io)) {
  62970. + ret = regulator_enable(vdd_io);
  62971. + if (ret) {
  62972. + dev_err(&client->dev, "vddio set voltage error\n");
  62973. + return ret;
  62974. + }
  62975. + }
  62976. +
  62977. + adapter = to_i2c_adapter(client->dev.parent);
  62978. + if (!i2c_check_functionality(adapter,
  62979. + I2C_FUNC_SMBUS_BYTE |
  62980. + I2C_FUNC_SMBUS_BYTE_DATA |
  62981. + I2C_FUNC_SMBUS_I2C_BLOCK))
  62982. + return -EIO;
  62983. +
  62984. + dev_info(&client->dev, "check mag3110 chip ID\n");
  62985. + ret = mag3110_read_reg(client, MAG3110_WHO_AM_I);
  62986. +
  62987. + if (MAG3110_ID != ret) {
  62988. + dev_err(&client->dev,
  62989. + "read chip ID 0x%x is not equal to 0x%x!\n", ret,
  62990. + MAG3110_ID);
  62991. + return -EINVAL;
  62992. + }
  62993. + data = kzalloc(sizeof(struct mag3110_data), GFP_KERNEL);
  62994. + if (!data)
  62995. + return -ENOMEM;
  62996. + data->client = client;
  62997. + i2c_set_clientdata(client, data);
  62998. + /* Init queue */
  62999. + init_waitqueue_head(&data->waitq);
  63000. +
  63001. + data->hwmon_dev = hwmon_device_register(&client->dev);
  63002. + if (IS_ERR(data->hwmon_dev)) {
  63003. + dev_err(&client->dev, "hwmon register failed!\n");
  63004. + ret = PTR_ERR(data->hwmon_dev);
  63005. + goto error_rm_dev_sysfs;
  63006. + }
  63007. +
  63008. + /*input poll device register */
  63009. + data->poll_dev = input_allocate_polled_device();
  63010. + if (!data->poll_dev) {
  63011. + dev_err(&client->dev, "alloc poll device failed!\n");
  63012. + ret = -ENOMEM;
  63013. + goto error_rm_hwmon_dev;
  63014. + }
  63015. + data->poll_dev->poll = mag3110_dev_poll;
  63016. + data->poll_dev->poll_interval = POLL_INTERVAL;
  63017. + data->poll_dev->poll_interval_max = POLL_INTERVAL_MAX;
  63018. + idev = data->poll_dev->input;
  63019. + idev->name = MAG3110_DRV_NAME;
  63020. + idev->id.bustype = BUS_I2C;
  63021. + idev->evbit[0] = BIT_MASK(EV_ABS);
  63022. + input_set_abs_params(idev, ABS_X, -15000, 15000, 0, 0);
  63023. + input_set_abs_params(idev, ABS_Y, -15000, 15000, 0, 0);
  63024. + input_set_abs_params(idev, ABS_Z, -15000, 15000, 0, 0);
  63025. + ret = input_register_polled_device(data->poll_dev);
  63026. + if (ret) {
  63027. + dev_err(&client->dev, "register poll device failed!\n");
  63028. + goto error_free_poll_dev;
  63029. + }
  63030. +
  63031. + /*create device group in sysfs as user interface */
  63032. + ret = sysfs_create_group(&idev->dev.kobj, &mag3110_attr_group);
  63033. + if (ret) {
  63034. + dev_err(&client->dev, "create device file failed!\n");
  63035. + ret = -EINVAL;
  63036. + goto error_rm_poll_dev;
  63037. + }
  63038. + /* set irq type to edge rising */
  63039. +#if MAG3110_IRQ_USED
  63040. + ret = request_irq(client->irq, mag3110_irq_handler,
  63041. + IRQF_TRIGGER_RISING, client->dev.driver->name, idev);
  63042. + if (ret < 0) {
  63043. + dev_err(&client->dev, "failed to register irq %d!\n",
  63044. + client->irq);
  63045. + goto error_rm_dev_sysfs;
  63046. + }
  63047. +#endif
  63048. + /* Initialize mag3110 chip */
  63049. + mag3110_init_client(client);
  63050. + mag3110_pdata = data;
  63051. + mag3110_pdata->active = MAG_STANDBY;
  63052. + ret = of_property_read_u32(of_node, "position", &pos);
  63053. + if (ret)
  63054. + pos = DEFAULT_POSITION;
  63055. + mag3110_pdata->position = (int)pos;
  63056. + dev_info(&client->dev, "mag3110 is probed\n");
  63057. + return 0;
  63058. +error_rm_dev_sysfs:
  63059. + sysfs_remove_group(&client->dev.kobj, &mag3110_attr_group);
  63060. +error_rm_poll_dev:
  63061. + input_unregister_polled_device(data->poll_dev);
  63062. +error_free_poll_dev:
  63063. + input_free_polled_device(data->poll_dev);
  63064. +error_rm_hwmon_dev:
  63065. + hwmon_device_unregister(data->hwmon_dev);
  63066. +
  63067. + kfree(data);
  63068. + mag3110_pdata = NULL;
  63069. +
  63070. + return ret;
  63071. +}
  63072. +
  63073. +static int mag3110_remove(struct i2c_client *client)
  63074. +{
  63075. + struct mag3110_data *data;
  63076. + int ret;
  63077. +
  63078. + data = i2c_get_clientdata(client);
  63079. +
  63080. + data->ctl_reg1 = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  63081. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
  63082. + data->ctl_reg1 & ~MAG3110_AC_MASK);
  63083. +
  63084. + free_irq(client->irq, data);
  63085. + input_unregister_polled_device(data->poll_dev);
  63086. + input_free_polled_device(data->poll_dev);
  63087. + hwmon_device_unregister(data->hwmon_dev);
  63088. + sysfs_remove_group(&client->dev.kobj, &mag3110_attr_group);
  63089. + kfree(data);
  63090. + mag3110_pdata = NULL;
  63091. +
  63092. + return ret;
  63093. +}
  63094. +
  63095. +#ifdef CONFIG_PM
  63096. +static int mag3110_suspend(struct i2c_client *client, pm_message_t mesg)
  63097. +{
  63098. + int ret = 0;
  63099. + struct mag3110_data *data = i2c_get_clientdata(client);
  63100. + if (data->active == MAG_ACTIVED) {
  63101. + data->ctl_reg1 = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  63102. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
  63103. + data->ctl_reg1 & ~MAG3110_AC_MASK);
  63104. + }
  63105. + return ret;
  63106. +}
  63107. +
  63108. +static int mag3110_resume(struct i2c_client *client)
  63109. +{
  63110. + int ret = 0;
  63111. + u8 tmp_data[MAG3110_XYZ_DATA_LEN];
  63112. + struct mag3110_data *data = i2c_get_clientdata(client);
  63113. + if (data->active == MAG_ACTIVED) {
  63114. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
  63115. + data->ctl_reg1);
  63116. +
  63117. + if (data->ctl_reg1 & MAG3110_AC_MASK) {
  63118. + /* Read out MSB data to clear interrupt
  63119. + flag automatically */
  63120. + mag3110_read_block_data(client, MAG3110_OUT_X_MSB,
  63121. + MAG3110_XYZ_DATA_LEN, tmp_data);
  63122. + }
  63123. + }
  63124. + return ret;
  63125. +}
  63126. +
  63127. +#else
  63128. +#define mag3110_suspend NULL
  63129. +#define mag3110_resume NULL
  63130. +#endif /* CONFIG_PM */
  63131. +
  63132. +static const struct i2c_device_id mag3110_id[] = {
  63133. + {MAG3110_DRV_NAME, 0},
  63134. + {}
  63135. +};
  63136. +
  63137. +MODULE_DEVICE_TABLE(i2c, mag3110_id);
  63138. +static struct i2c_driver mag3110_driver = {
  63139. + .driver = {.name = MAG3110_DRV_NAME,
  63140. + .owner = THIS_MODULE,},
  63141. + .suspend = mag3110_suspend,
  63142. + .resume = mag3110_resume,
  63143. + .probe = mag3110_probe,
  63144. + .remove = mag3110_remove,
  63145. + .id_table = mag3110_id,
  63146. +};
  63147. +
  63148. +static int __init mag3110_init(void)
  63149. +{
  63150. + return i2c_add_driver(&mag3110_driver);
  63151. +}
  63152. +
  63153. +static void __exit mag3110_exit(void)
  63154. +{
  63155. + i2c_del_driver(&mag3110_driver);
  63156. +}
  63157. +
  63158. +module_init(mag3110_init);
  63159. +module_exit(mag3110_exit);
  63160. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  63161. +MODULE_DESCRIPTION("Freescale mag3110 3-axis magnetometer driver");
  63162. +MODULE_LICENSE("GPL");
  63163. diff -Nur linux-3.14.15/drivers/hwmon/Makefile linux-linaro-stable-mx6/drivers/hwmon/Makefile
  63164. --- linux-3.14.15/drivers/hwmon/Makefile 2014-07-31 23:51:43.000000000 +0200
  63165. +++ linux-linaro-stable-mx6/drivers/hwmon/Makefile 2014-08-20 19:31:43.636858307 +0200
  63166. @@ -142,6 +142,8 @@
  63167. obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o
  63168. obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
  63169. obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
  63170. +obj-$(CONFIG_SENSORS_MAG3110) += mag3110.o
  63171. +obj-$(CONFIG_MXC_MMA8451) += mxc_mma8451.o
  63172. obj-$(CONFIG_PMBUS) += pmbus/
  63173. diff -Nur linux-3.14.15/drivers/hwmon/mxc_mma8451.c linux-linaro-stable-mx6/drivers/hwmon/mxc_mma8451.c
  63174. --- linux-3.14.15/drivers/hwmon/mxc_mma8451.c 1970-01-01 01:00:00.000000000 +0100
  63175. +++ linux-linaro-stable-mx6/drivers/hwmon/mxc_mma8451.c 2014-08-20 19:31:43.672858463 +0200
  63176. @@ -0,0 +1,598 @@
  63177. +/*
  63178. + * mma8451.c - Linux kernel modules for 3-Axis Orientation/Motion
  63179. + * Detection Sensor
  63180. + *
  63181. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  63182. + *
  63183. + * This program is free software; you can redistribute it and/or modify
  63184. + * it under the terms of the GNU General Public License as published by
  63185. + * the Free Software Foundation; either version 2 of the License, or
  63186. + * (at your option) any later version.
  63187. + *
  63188. + * This program is distributed in the hope that it will be useful,
  63189. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  63190. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  63191. + * GNU General Public License for more details.
  63192. + *
  63193. + * You should have received a copy of the GNU General Public License
  63194. + * along with this program; if not, write to the Free Software
  63195. + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  63196. + */
  63197. +
  63198. +#include <linux/module.h>
  63199. +#include <linux/init.h>
  63200. +#include <linux/slab.h>
  63201. +#include <linux/i2c.h>
  63202. +#include <linux/pm.h>
  63203. +#include <linux/mutex.h>
  63204. +#include <linux/delay.h>
  63205. +#include <linux/interrupt.h>
  63206. +#include <linux/irq.h>
  63207. +#include <linux/hwmon-sysfs.h>
  63208. +#include <linux/err.h>
  63209. +#include <linux/hwmon.h>
  63210. +#include <linux/input-polldev.h>
  63211. +#include <linux/of.h>
  63212. +#include <linux/regulator/consumer.h>
  63213. +
  63214. +#define MMA8451_I2C_ADDR 0x1C
  63215. +#define MMA8451_ID 0x1A
  63216. +#define MMA8452_ID 0x2A
  63217. +#define MMA8453_ID 0x3A
  63218. +
  63219. +#define POLL_INTERVAL_MIN 1
  63220. +#define POLL_INTERVAL_MAX 500
  63221. +#define POLL_INTERVAL 100 /* msecs */
  63222. +#define INPUT_FUZZ 32
  63223. +#define INPUT_FLAT 32
  63224. +#define MODE_CHANGE_DELAY_MS 100
  63225. +
  63226. +#define MMA8451_STATUS_ZYXDR 0x08
  63227. +#define MMA8451_BUF_SIZE 7
  63228. +#define DEFAULT_POSITION 0
  63229. +
  63230. +/* register enum for mma8451 registers */
  63231. +enum {
  63232. + MMA8451_STATUS = 0x00,
  63233. + MMA8451_OUT_X_MSB,
  63234. + MMA8451_OUT_X_LSB,
  63235. + MMA8451_OUT_Y_MSB,
  63236. + MMA8451_OUT_Y_LSB,
  63237. + MMA8451_OUT_Z_MSB,
  63238. + MMA8451_OUT_Z_LSB,
  63239. +
  63240. + MMA8451_F_SETUP = 0x09,
  63241. + MMA8451_TRIG_CFG,
  63242. + MMA8451_SYSMOD,
  63243. + MMA8451_INT_SOURCE,
  63244. + MMA8451_WHO_AM_I,
  63245. + MMA8451_XYZ_DATA_CFG,
  63246. + MMA8451_HP_FILTER_CUTOFF,
  63247. +
  63248. + MMA8451_PL_STATUS,
  63249. + MMA8451_PL_CFG,
  63250. + MMA8451_PL_COUNT,
  63251. + MMA8451_PL_BF_ZCOMP,
  63252. + MMA8451_P_L_THS_REG,
  63253. +
  63254. + MMA8451_FF_MT_CFG,
  63255. + MMA8451_FF_MT_SRC,
  63256. + MMA8451_FF_MT_THS,
  63257. + MMA8451_FF_MT_COUNT,
  63258. +
  63259. + MMA8451_TRANSIENT_CFG = 0x1D,
  63260. + MMA8451_TRANSIENT_SRC,
  63261. + MMA8451_TRANSIENT_THS,
  63262. + MMA8451_TRANSIENT_COUNT,
  63263. +
  63264. + MMA8451_PULSE_CFG,
  63265. + MMA8451_PULSE_SRC,
  63266. + MMA8451_PULSE_THSX,
  63267. + MMA8451_PULSE_THSY,
  63268. + MMA8451_PULSE_THSZ,
  63269. + MMA8451_PULSE_TMLT,
  63270. + MMA8451_PULSE_LTCY,
  63271. + MMA8451_PULSE_WIND,
  63272. +
  63273. + MMA8451_ASLP_COUNT,
  63274. + MMA8451_CTRL_REG1,
  63275. + MMA8451_CTRL_REG2,
  63276. + MMA8451_CTRL_REG3,
  63277. + MMA8451_CTRL_REG4,
  63278. + MMA8451_CTRL_REG5,
  63279. +
  63280. + MMA8451_OFF_X,
  63281. + MMA8451_OFF_Y,
  63282. + MMA8451_OFF_Z,
  63283. +
  63284. + MMA8451_REG_END,
  63285. +};
  63286. +
  63287. +/* The sensitivity is represented in counts/g. In 2g mode the
  63288. +sensitivity is 1024 counts/g. In 4g mode the sensitivity is 512
  63289. +counts/g and in 8g mode the sensitivity is 256 counts/g.
  63290. + */
  63291. +enum {
  63292. + MODE_2G = 0,
  63293. + MODE_4G,
  63294. + MODE_8G,
  63295. +};
  63296. +
  63297. +enum {
  63298. + MMA_STANDBY = 0,
  63299. + MMA_ACTIVED,
  63300. +};
  63301. +
  63302. +/* mma8451 status */
  63303. +struct mma8451_status {
  63304. + u8 mode;
  63305. + u8 ctl_reg1;
  63306. + int active;
  63307. + int position;
  63308. +};
  63309. +
  63310. +static struct mma8451_status mma_status;
  63311. +static struct input_polled_dev *mma8451_idev;
  63312. +static struct device *hwmon_dev;
  63313. +static struct i2c_client *mma8451_i2c_client;
  63314. +
  63315. +static int senstive_mode = MODE_2G;
  63316. +static int ACCHAL[8][3][3] = {
  63317. + { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} },
  63318. + { {-1, 0, 0}, {0, -1, 0}, {0, 0, 1} },
  63319. + { {0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
  63320. + { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} },
  63321. +
  63322. + { {0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
  63323. + { {-1, 0, 0}, {0, 1, 0}, {0, 0, -1} },
  63324. + { {0, 1, 0}, {1, 0, 0}, {0, 0, -1} },
  63325. + { {1, 0, 0}, {0, -1, 0}, {0, 0, -1} },
  63326. +};
  63327. +
  63328. +static DEFINE_MUTEX(mma8451_lock);
  63329. +static int mma8451_adjust_position(short *x, short *y, short *z)
  63330. +{
  63331. + short rawdata[3], data[3];
  63332. + int i, j;
  63333. + int position = mma_status.position;
  63334. + if (position < 0 || position > 7)
  63335. + position = 0;
  63336. + rawdata[0] = *x;
  63337. + rawdata[1] = *y;
  63338. + rawdata[2] = *z;
  63339. + for (i = 0; i < 3; i++) {
  63340. + data[i] = 0;
  63341. + for (j = 0; j < 3; j++)
  63342. + data[i] += rawdata[j] * ACCHAL[position][i][j];
  63343. + }
  63344. + *x = data[0];
  63345. + *y = data[1];
  63346. + *z = data[2];
  63347. + return 0;
  63348. +}
  63349. +
  63350. +static int mma8451_change_mode(struct i2c_client *client, int mode)
  63351. +{
  63352. + int result;
  63353. +
  63354. + mma_status.ctl_reg1 = 0;
  63355. + result = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, 0);
  63356. + if (result < 0)
  63357. + goto out;
  63358. + mma_status.active = MMA_STANDBY;
  63359. +
  63360. + result = i2c_smbus_write_byte_data(client, MMA8451_XYZ_DATA_CFG,
  63361. + mode);
  63362. + if (result < 0)
  63363. + goto out;
  63364. + mdelay(MODE_CHANGE_DELAY_MS);
  63365. + mma_status.mode = mode;
  63366. +
  63367. + return 0;
  63368. +out:
  63369. + dev_err(&client->dev, "error when init mma8451:(%d)", result);
  63370. + return result;
  63371. +}
  63372. +
  63373. +static int mma8451_read_data(short *x, short *y, short *z)
  63374. +{
  63375. + u8 tmp_data[MMA8451_BUF_SIZE];
  63376. + int ret;
  63377. +
  63378. + ret = i2c_smbus_read_i2c_block_data(mma8451_i2c_client,
  63379. + MMA8451_OUT_X_MSB, 7, tmp_data);
  63380. + if (ret < MMA8451_BUF_SIZE) {
  63381. + dev_err(&mma8451_i2c_client->dev, "i2c block read failed\n");
  63382. + return -EIO;
  63383. + }
  63384. +
  63385. + *x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
  63386. + *y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
  63387. + *z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
  63388. + return 0;
  63389. +}
  63390. +
  63391. +static void report_abs(void)
  63392. +{
  63393. + short x, y, z;
  63394. + int result;
  63395. + int retry = 3;
  63396. +
  63397. + mutex_lock(&mma8451_lock);
  63398. + if (mma_status.active == MMA_STANDBY)
  63399. + goto out;
  63400. + /* wait for the data ready */
  63401. + do {
  63402. + result = i2c_smbus_read_byte_data(mma8451_i2c_client,
  63403. + MMA8451_STATUS);
  63404. + retry--;
  63405. + msleep(1);
  63406. + } while (!(result & MMA8451_STATUS_ZYXDR) && retry > 0);
  63407. + if (retry == 0)
  63408. + goto out;
  63409. + if (mma8451_read_data(&x, &y, &z) != 0)
  63410. + goto out;
  63411. + mma8451_adjust_position(&x, &y, &z);
  63412. + input_report_abs(mma8451_idev->input, ABS_X, x);
  63413. + input_report_abs(mma8451_idev->input, ABS_Y, y);
  63414. + input_report_abs(mma8451_idev->input, ABS_Z, z);
  63415. + input_sync(mma8451_idev->input);
  63416. +out:
  63417. + mutex_unlock(&mma8451_lock);
  63418. +}
  63419. +
  63420. +static void mma8451_dev_poll(struct input_polled_dev *dev)
  63421. +{
  63422. + report_abs();
  63423. +}
  63424. +
  63425. +static ssize_t mma8451_enable_show(struct device *dev,
  63426. + struct device_attribute *attr, char *buf)
  63427. +{
  63428. + struct i2c_client *client;
  63429. + u8 val;
  63430. + int enable;
  63431. +
  63432. + mutex_lock(&mma8451_lock);
  63433. + client = mma8451_i2c_client;
  63434. + val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
  63435. + if ((val & 0x01) && mma_status.active == MMA_ACTIVED)
  63436. + enable = 1;
  63437. + else
  63438. + enable = 0;
  63439. + mutex_unlock(&mma8451_lock);
  63440. + return sprintf(buf, "%d\n", enable);
  63441. +}
  63442. +
  63443. +static ssize_t mma8451_enable_store(struct device *dev,
  63444. + struct device_attribute *attr,
  63445. + const char *buf, size_t count)
  63446. +{
  63447. + struct i2c_client *client;
  63448. + int ret;
  63449. + unsigned long enable;
  63450. + u8 val = 0;
  63451. +
  63452. + ret = strict_strtoul(buf, 10, &enable);
  63453. + if (ret) {
  63454. + dev_err(dev, "string transform error\n");
  63455. + return ret;
  63456. + }
  63457. +
  63458. + mutex_lock(&mma8451_lock);
  63459. + client = mma8451_i2c_client;
  63460. + enable = (enable > 0) ? 1 : 0;
  63461. + if (enable && mma_status.active == MMA_STANDBY) {
  63462. + val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
  63463. + ret =
  63464. + i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  63465. + val | 0x01);
  63466. + if (!ret)
  63467. + mma_status.active = MMA_ACTIVED;
  63468. +
  63469. + } else if (enable == 0 && mma_status.active == MMA_ACTIVED) {
  63470. + val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
  63471. + ret =
  63472. + i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  63473. + val & 0xFE);
  63474. + if (!ret)
  63475. + mma_status.active = MMA_STANDBY;
  63476. +
  63477. + }
  63478. + mutex_unlock(&mma8451_lock);
  63479. + return count;
  63480. +}
  63481. +
  63482. +static ssize_t mma8451_position_show(struct device *dev,
  63483. + struct device_attribute *attr, char *buf)
  63484. +{
  63485. + int position = 0;
  63486. + mutex_lock(&mma8451_lock);
  63487. + position = mma_status.position;
  63488. + mutex_unlock(&mma8451_lock);
  63489. + return sprintf(buf, "%d\n", position);
  63490. +}
  63491. +
  63492. +static ssize_t mma8451_position_store(struct device *dev,
  63493. + struct device_attribute *attr,
  63494. + const char *buf, size_t count)
  63495. +{
  63496. + unsigned long position;
  63497. + int ret;
  63498. + ret = strict_strtoul(buf, 10, &position);
  63499. + if (ret) {
  63500. + dev_err(dev, "string transform error\n");
  63501. + return ret;
  63502. + }
  63503. +
  63504. + mutex_lock(&mma8451_lock);
  63505. + mma_status.position = (int)position;
  63506. + mutex_unlock(&mma8451_lock);
  63507. + return count;
  63508. +}
  63509. +
  63510. +static ssize_t mma8451_scalemode_show(struct device *dev,
  63511. + struct device_attribute *attr,
  63512. + char *buf)
  63513. +{
  63514. + int mode = 0;
  63515. + mutex_lock(&mma8451_lock);
  63516. + mode = (int)mma_status.mode;
  63517. + mutex_unlock(&mma8451_lock);
  63518. +
  63519. + return sprintf(buf, "%d\n", mode);
  63520. +}
  63521. +
  63522. +static ssize_t mma8451_scalemode_store(struct device *dev,
  63523. + struct device_attribute *attr,
  63524. + const char *buf, size_t count)
  63525. +{
  63526. + unsigned long mode;
  63527. + int ret, active_save;
  63528. + struct i2c_client *client = mma8451_i2c_client;
  63529. +
  63530. + ret = strict_strtoul(buf, 10, &mode);
  63531. + if (ret) {
  63532. + dev_err(dev, "string transform error\n");
  63533. + goto out;
  63534. + }
  63535. +
  63536. + if (mode > MODE_8G) {
  63537. + dev_warn(dev, "not supported mode\n");
  63538. + ret = count;
  63539. + goto out;
  63540. + }
  63541. +
  63542. + mutex_lock(&mma8451_lock);
  63543. + if (mode == mma_status.mode) {
  63544. + ret = count;
  63545. + goto out_unlock;
  63546. + }
  63547. +
  63548. + active_save = mma_status.active;
  63549. + ret = mma8451_change_mode(client, mode);
  63550. + if (ret)
  63551. + goto out_unlock;
  63552. +
  63553. + if (active_save == MMA_ACTIVED) {
  63554. + ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, 1);
  63555. +
  63556. + if (ret)
  63557. + goto out_unlock;
  63558. + mma_status.active = active_save;
  63559. + }
  63560. +
  63561. +out_unlock:
  63562. + mutex_unlock(&mma8451_lock);
  63563. +out:
  63564. + return ret;
  63565. +}
  63566. +
  63567. +static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
  63568. + mma8451_enable_show, mma8451_enable_store);
  63569. +static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
  63570. + mma8451_position_show, mma8451_position_store);
  63571. +static DEVICE_ATTR(scalemode, S_IWUSR | S_IRUGO,
  63572. + mma8451_scalemode_show, mma8451_scalemode_store);
  63573. +
  63574. +static struct attribute *mma8451_attributes[] = {
  63575. + &dev_attr_enable.attr,
  63576. + &dev_attr_position.attr,
  63577. + &dev_attr_scalemode.attr,
  63578. + NULL
  63579. +};
  63580. +
  63581. +static const struct attribute_group mma8451_attr_group = {
  63582. + .attrs = mma8451_attributes,
  63583. +};
  63584. +
  63585. +static int mma8451_probe(struct i2c_client *client,
  63586. + const struct i2c_device_id *id)
  63587. +{
  63588. + int result, client_id;
  63589. + struct input_dev *idev;
  63590. + struct i2c_adapter *adapter;
  63591. + u32 pos;
  63592. + struct device_node *of_node = client->dev.of_node;
  63593. + struct regulator *vdd, *vdd_io;
  63594. +
  63595. + mma8451_i2c_client = client;
  63596. +
  63597. + vdd = devm_regulator_get(&client->dev, "vdd");
  63598. + if (!IS_ERR(vdd)) {
  63599. + result = regulator_enable(vdd);
  63600. + if (result) {
  63601. + dev_err(&client->dev, "vdd set voltage error\n");
  63602. + return result;
  63603. + }
  63604. + }
  63605. +
  63606. + vdd_io = devm_regulator_get(&client->dev, "vddio");
  63607. + if (!IS_ERR(vdd_io)) {
  63608. + result = regulator_enable(vdd_io);
  63609. + if (result) {
  63610. + dev_err(&client->dev, "vddio set voltage error\n");
  63611. + return result;
  63612. + }
  63613. + }
  63614. +
  63615. + adapter = to_i2c_adapter(client->dev.parent);
  63616. + result = i2c_check_functionality(adapter,
  63617. + I2C_FUNC_SMBUS_BYTE |
  63618. + I2C_FUNC_SMBUS_BYTE_DATA);
  63619. + if (!result)
  63620. + goto err_out;
  63621. +
  63622. + client_id = i2c_smbus_read_byte_data(client, MMA8451_WHO_AM_I);
  63623. + if (client_id != MMA8451_ID && client_id != MMA8452_ID
  63624. + && client_id != MMA8453_ID) {
  63625. + dev_err(&client->dev,
  63626. + "read chip ID 0x%x is not equal to 0x%x or 0x%x!\n",
  63627. + result, MMA8451_ID, MMA8452_ID);
  63628. + result = -EINVAL;
  63629. + goto err_out;
  63630. + }
  63631. +
  63632. + /* Initialize the MMA8451 chip */
  63633. + result = mma8451_change_mode(client, senstive_mode);
  63634. + if (result) {
  63635. + dev_err(&client->dev,
  63636. + "error when init mma8451 chip:(%d)\n", result);
  63637. + goto err_out;
  63638. + }
  63639. +
  63640. + hwmon_dev = hwmon_device_register(&client->dev);
  63641. + if (!hwmon_dev) {
  63642. + result = -ENOMEM;
  63643. + dev_err(&client->dev, "error when register hwmon device\n");
  63644. + goto err_out;
  63645. + }
  63646. +
  63647. + mma8451_idev = input_allocate_polled_device();
  63648. + if (!mma8451_idev) {
  63649. + result = -ENOMEM;
  63650. + dev_err(&client->dev, "alloc poll device failed!\n");
  63651. + goto err_alloc_poll_device;
  63652. + }
  63653. + mma8451_idev->poll = mma8451_dev_poll;
  63654. + mma8451_idev->poll_interval = POLL_INTERVAL;
  63655. + mma8451_idev->poll_interval_min = POLL_INTERVAL_MIN;
  63656. + mma8451_idev->poll_interval_max = POLL_INTERVAL_MAX;
  63657. + idev = mma8451_idev->input;
  63658. + idev->name = "mma845x";
  63659. + idev->id.bustype = BUS_I2C;
  63660. + idev->evbit[0] = BIT_MASK(EV_ABS);
  63661. +
  63662. + input_set_abs_params(idev, ABS_X, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
  63663. + input_set_abs_params(idev, ABS_Y, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
  63664. + input_set_abs_params(idev, ABS_Z, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
  63665. +
  63666. + result = input_register_polled_device(mma8451_idev);
  63667. + if (result) {
  63668. + dev_err(&client->dev, "register poll device failed!\n");
  63669. + goto err_register_polled_device;
  63670. + }
  63671. + result = sysfs_create_group(&idev->dev.kobj, &mma8451_attr_group);
  63672. + if (result) {
  63673. + dev_err(&client->dev, "create device file failed!\n");
  63674. + result = -EINVAL;
  63675. + goto err_register_polled_device;
  63676. + }
  63677. +
  63678. + result = of_property_read_u32(of_node, "position", &pos);
  63679. + if (result)
  63680. + pos = DEFAULT_POSITION;
  63681. + mma_status.position = (int)pos;
  63682. +
  63683. + return 0;
  63684. +err_register_polled_device:
  63685. + input_free_polled_device(mma8451_idev);
  63686. +err_alloc_poll_device:
  63687. + hwmon_device_unregister(&client->dev);
  63688. +err_out:
  63689. + return result;
  63690. +}
  63691. +
  63692. +static int mma8451_stop_chip(struct i2c_client *client)
  63693. +{
  63694. + int ret = 0;
  63695. + if (mma_status.active == MMA_ACTIVED) {
  63696. + mma_status.ctl_reg1 = i2c_smbus_read_byte_data(client,
  63697. + MMA8451_CTRL_REG1);
  63698. + ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  63699. + mma_status.ctl_reg1 & 0xFE);
  63700. + }
  63701. + return ret;
  63702. +}
  63703. +
  63704. +static int mma8451_remove(struct i2c_client *client)
  63705. +{
  63706. + int ret;
  63707. + ret = mma8451_stop_chip(client);
  63708. + hwmon_device_unregister(hwmon_dev);
  63709. +
  63710. + return ret;
  63711. +}
  63712. +
  63713. +#ifdef CONFIG_PM_SLEEP
  63714. +static int mma8451_suspend(struct device *dev)
  63715. +{
  63716. + struct i2c_client *client = to_i2c_client(dev);
  63717. +
  63718. + return mma8451_stop_chip(client);
  63719. +}
  63720. +
  63721. +static int mma8451_resume(struct device *dev)
  63722. +{
  63723. + int ret = 0;
  63724. + struct i2c_client *client = to_i2c_client(dev);
  63725. + if (mma_status.active == MMA_ACTIVED)
  63726. + ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  63727. + mma_status.ctl_reg1);
  63728. + return ret;
  63729. +
  63730. +}
  63731. +#endif
  63732. +
  63733. +static const struct i2c_device_id mma8451_id[] = {
  63734. + {"mma8451", 0},
  63735. +};
  63736. +
  63737. +MODULE_DEVICE_TABLE(i2c, mma8451_id);
  63738. +
  63739. +static SIMPLE_DEV_PM_OPS(mma8451_pm_ops, mma8451_suspend, mma8451_resume);
  63740. +static struct i2c_driver mma8451_driver = {
  63741. + .driver = {
  63742. + .name = "mma8451",
  63743. + .owner = THIS_MODULE,
  63744. + .pm = &mma8451_pm_ops,
  63745. + },
  63746. + .probe = mma8451_probe,
  63747. + .remove = mma8451_remove,
  63748. + .id_table = mma8451_id,
  63749. +};
  63750. +
  63751. +static int __init mma8451_init(void)
  63752. +{
  63753. + /* register driver */
  63754. + int res;
  63755. +
  63756. + res = i2c_add_driver(&mma8451_driver);
  63757. + if (res < 0) {
  63758. + printk(KERN_INFO "add mma8451 i2c driver failed\n");
  63759. + return -ENODEV;
  63760. + }
  63761. + return res;
  63762. +}
  63763. +
  63764. +static void __exit mma8451_exit(void)
  63765. +{
  63766. + i2c_del_driver(&mma8451_driver);
  63767. +}
  63768. +
  63769. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  63770. +MODULE_DESCRIPTION("MMA8451 3-Axis Orientation/Motion Detection Sensor driver");
  63771. +MODULE_LICENSE("GPL");
  63772. +
  63773. +module_init(mma8451_init);
  63774. +module_exit(mma8451_exit);
  63775. diff -Nur linux-3.14.15/drivers/hwmon/smsc47m192.c linux-linaro-stable-mx6/drivers/hwmon/smsc47m192.c
  63776. --- linux-3.14.15/drivers/hwmon/smsc47m192.c 2014-07-31 23:51:43.000000000 +0200
  63777. +++ linux-linaro-stable-mx6/drivers/hwmon/smsc47m192.c 2014-08-20 19:23:51.682837830 +0200
  63778. @@ -86,7 +86,7 @@
  63779. */
  63780. static inline s8 TEMP_TO_REG(int val)
  63781. {
  63782. - return SCALE(clamp_val(val, -128000, 127000), 1, 1000);
  63783. + return clamp_val(SCALE(val, 1, 1000), -128000, 127000);
  63784. }
  63785. static inline int TEMP_FROM_REG(s8 val)
  63786. @@ -384,8 +384,6 @@
  63787. err = kstrtoul(buf, 10, &val);
  63788. if (err)
  63789. return err;
  63790. - if (val > 255)
  63791. - return -EINVAL;
  63792. data->vrm = val;
  63793. return count;
  63794. diff -Nur linux-3.14.15/drivers/i2c/busses/i2c-imx.c linux-linaro-stable-mx6/drivers/i2c/busses/i2c-imx.c
  63795. --- linux-3.14.15/drivers/i2c/busses/i2c-imx.c 2014-07-31 23:51:43.000000000 +0200
  63796. +++ linux-linaro-stable-mx6/drivers/i2c/busses/i2c-imx.c 2014-08-20 19:31:43.692858550 +0200
  63797. @@ -184,6 +184,9 @@
  63798. int stopped;
  63799. unsigned int ifdr; /* IMX_I2C_IFDR */
  63800. const struct imx_i2c_hwdata *hwdata;
  63801. +
  63802. + unsigned int cur_clk;
  63803. + unsigned int bitrate;
  63804. };
  63805. static const struct imx_i2c_hwdata imx1_i2c_hwdata = {
  63806. @@ -305,6 +308,51 @@
  63807. return 0;
  63808. }
  63809. +static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx)
  63810. +{
  63811. + struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div;
  63812. + unsigned ndivs = i2c_imx->hwdata->ndivs;
  63813. + unsigned int i2c_clk_rate;
  63814. + unsigned int div;
  63815. + int i;
  63816. +
  63817. + /* Divider value calculation */
  63818. + i2c_clk_rate = clk_get_rate(i2c_imx->clk);
  63819. + if (i2c_imx->cur_clk == i2c_clk_rate)
  63820. + return;
  63821. + else
  63822. + i2c_imx->cur_clk = i2c_clk_rate;
  63823. +
  63824. + div = (i2c_clk_rate + i2c_imx->bitrate - 1) / i2c_imx->bitrate;
  63825. + if (div < i2c_clk_div[0].div)
  63826. + i = 0;
  63827. + else if (div > i2c_clk_div[ndivs - 1].div)
  63828. + i = ndivs - 1;
  63829. + else
  63830. + for (i = 0; i2c_clk_div[i].div < div; i++)
  63831. + ;
  63832. +
  63833. + /* Store divider value */
  63834. + i2c_imx->ifdr = imx_i2c_clk_div[i].val;
  63835. +
  63836. + /*
  63837. + * There dummy delay is calculated.
  63838. + * It should be about one I2C clock period long.
  63839. + * This delay is used in I2C bus disable function
  63840. + * to fix chip hardware bug.
  63841. + */
  63842. + i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div
  63843. + + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
  63844. +
  63845. + /* dev_dbg() can't be used, because adapter is not yet registered */
  63846. +#ifdef CONFIG_I2C_DEBUG_BUS
  63847. + dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
  63848. + __func__, i2c_clk_rate, div);
  63849. + dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
  63850. + __func__, i2c_clk_div[i].val, i2c_clk_div[i].div);
  63851. +#endif
  63852. +}
  63853. +
  63854. static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
  63855. {
  63856. unsigned int temp = 0;
  63857. @@ -312,6 +360,7 @@
  63858. dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
  63859. + i2c_imx_set_clk(i2c_imx);
  63860. result = clk_prepare_enable(i2c_imx->clk);
  63861. if (result)
  63862. return result;
  63863. @@ -367,45 +416,6 @@
  63864. clk_disable_unprepare(i2c_imx->clk);
  63865. }
  63866. -static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
  63867. - unsigned int rate)
  63868. -{
  63869. - struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div;
  63870. - unsigned int i2c_clk_rate;
  63871. - unsigned int div;
  63872. - int i;
  63873. -
  63874. - /* Divider value calculation */
  63875. - i2c_clk_rate = clk_get_rate(i2c_imx->clk);
  63876. - div = (i2c_clk_rate + rate - 1) / rate;
  63877. - if (div < i2c_clk_div[0].div)
  63878. - i = 0;
  63879. - else if (div > i2c_clk_div[i2c_imx->hwdata->ndivs - 1].div)
  63880. - i = i2c_imx->hwdata->ndivs - 1;
  63881. - else
  63882. - for (i = 0; i2c_clk_div[i].div < div; i++);
  63883. -
  63884. - /* Store divider value */
  63885. - i2c_imx->ifdr = i2c_clk_div[i].val;
  63886. -
  63887. - /*
  63888. - * There dummy delay is calculated.
  63889. - * It should be about one I2C clock period long.
  63890. - * This delay is used in I2C bus disable function
  63891. - * to fix chip hardware bug.
  63892. - */
  63893. - i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div
  63894. - + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
  63895. -
  63896. - /* dev_dbg() can't be used, because adapter is not yet registered */
  63897. -#ifdef CONFIG_I2C_DEBUG_BUS
  63898. - dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
  63899. - __func__, i2c_clk_rate, div);
  63900. - dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
  63901. - __func__, i2c_clk_div[i].val, i2c_clk_div[i].div);
  63902. -#endif
  63903. -}
  63904. -
  63905. static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
  63906. {
  63907. struct imx_i2c_struct *i2c_imx = dev_id;
  63908. @@ -600,7 +610,6 @@
  63909. struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
  63910. void __iomem *base;
  63911. int irq, ret;
  63912. - u32 bitrate;
  63913. dev_dbg(&pdev->dev, "<%s>\n", __func__);
  63914. @@ -664,12 +673,12 @@
  63915. i2c_set_adapdata(&i2c_imx->adapter, i2c_imx);
  63916. /* Set up clock divider */
  63917. - bitrate = IMX_I2C_BIT_RATE;
  63918. + i2c_imx->bitrate = IMX_I2C_BIT_RATE;
  63919. ret = of_property_read_u32(pdev->dev.of_node,
  63920. - "clock-frequency", &bitrate);
  63921. + "clock-frequency", &i2c_imx->bitrate);
  63922. if (ret < 0 && pdata && pdata->bitrate)
  63923. - bitrate = pdata->bitrate;
  63924. - i2c_imx_set_clk(i2c_imx, bitrate);
  63925. + i2c_imx->bitrate = pdata->bitrate;
  63926. + i2c_imx_set_clk(i2c_imx);
  63927. /* Set up chip registers to defaults */
  63928. imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
  63929. diff -Nur linux-3.14.15/drivers/input/input.c linux-linaro-stable-mx6/drivers/input/input.c
  63930. --- linux-3.14.15/drivers/input/input.c 2014-07-31 23:51:43.000000000 +0200
  63931. +++ linux-linaro-stable-mx6/drivers/input/input.c 2014-08-20 19:31:43.972859750 +0200
  63932. @@ -257,10 +257,9 @@
  63933. }
  63934. static int input_get_disposition(struct input_dev *dev,
  63935. - unsigned int type, unsigned int code, int *pval)
  63936. + unsigned int type, unsigned int code, int value)
  63937. {
  63938. int disposition = INPUT_IGNORE_EVENT;
  63939. - int value = *pval;
  63940. switch (type) {
  63941. @@ -358,7 +357,6 @@
  63942. break;
  63943. }
  63944. - *pval = value;
  63945. return disposition;
  63946. }
  63947. @@ -367,7 +365,7 @@
  63948. {
  63949. int disposition;
  63950. - disposition = input_get_disposition(dev, type, code, &value);
  63951. + disposition = input_get_disposition(dev, type, code, value);
  63952. if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
  63953. dev->event(dev, type, code, value);
  63954. diff -Nur linux-3.14.15/drivers/input/keyboard/gpio_keys.c linux-linaro-stable-mx6/drivers/input/keyboard/gpio_keys.c
  63955. --- linux-3.14.15/drivers/input/keyboard/gpio_keys.c 2014-07-31 23:51:43.000000000 +0200
  63956. +++ linux-linaro-stable-mx6/drivers/input/keyboard/gpio_keys.c 2014-08-20 19:31:43.980859786 +0200
  63957. @@ -3,6 +3,7 @@
  63958. *
  63959. * Copyright 2005 Phil Blundell
  63960. * Copyright 2010, 2011 David Jander <david@protonic.nl>
  63961. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  63962. *
  63963. * This program is free software; you can redistribute it and/or modify
  63964. * it under the terms of the GNU General Public License version 2 as
  63965. @@ -473,6 +474,8 @@
  63966. isr = gpio_keys_gpio_isr;
  63967. irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
  63968. + if (bdata->button->wakeup)
  63969. + irqflags |= IRQF_NO_SUSPEND;
  63970. } else {
  63971. if (!button->irq) {
  63972. diff -Nur linux-3.14.15/drivers/input/keyboard/imx_keypad.c linux-linaro-stable-mx6/drivers/input/keyboard/imx_keypad.c
  63973. --- linux-3.14.15/drivers/input/keyboard/imx_keypad.c 2014-07-31 23:51:43.000000000 +0200
  63974. +++ linux-linaro-stable-mx6/drivers/input/keyboard/imx_keypad.c 2014-08-20 19:31:43.980859786 +0200
  63975. @@ -1,6 +1,7 @@
  63976. /*
  63977. * Driver for the IMX keypad port.
  63978. * Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
  63979. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  63980. *
  63981. * This program is free software; you can redistribute it and/or modify
  63982. * it under the terms of the GNU General Public License version 2 as
  63983. @@ -548,6 +549,8 @@
  63984. if (device_may_wakeup(&pdev->dev))
  63985. enable_irq_wake(kbd->irq);
  63986. + else
  63987. + pinctrl_pm_select_sleep_state(dev);
  63988. return 0;
  63989. }
  63990. @@ -561,6 +564,8 @@
  63991. if (device_may_wakeup(&pdev->dev))
  63992. disable_irq_wake(kbd->irq);
  63993. + else
  63994. + pinctrl_pm_select_default_state(dev);
  63995. mutex_lock(&input_dev->mutex);
  63996. diff -Nur linux-3.14.15/drivers/input/misc/mma8450.c linux-linaro-stable-mx6/drivers/input/misc/mma8450.c
  63997. --- linux-3.14.15/drivers/input/misc/mma8450.c 2014-07-31 23:51:43.000000000 +0200
  63998. +++ linux-linaro-stable-mx6/drivers/input/misc/mma8450.c 2014-08-20 19:31:44.000859871 +0200
  63999. @@ -1,7 +1,7 @@
  64000. /*
  64001. * Driver for Freescale's 3-Axis Accelerometer MMA8450
  64002. *
  64003. - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
  64004. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  64005. *
  64006. * This program is free software; you can redistribute it and/or modify
  64007. * it under the terms of the GNU General Public License as published by
  64008. @@ -25,6 +25,7 @@
  64009. #include <linux/i2c.h>
  64010. #include <linux/input-polldev.h>
  64011. #include <linux/of_device.h>
  64012. +#include <linux/mutex.h>
  64013. #define MMA8450_DRV_NAME "mma8450"
  64014. @@ -51,11 +52,22 @@
  64015. #define MMA8450_CTRL_REG1 0x38
  64016. #define MMA8450_CTRL_REG2 0x39
  64017. +#define MMA8450_ID 0xC6
  64018. +#define MMA8450_WHO_AM_I 0x0F
  64019. +
  64020. +enum {
  64021. + MODE_STANDBY = 0,
  64022. + MODE_2G,
  64023. + MODE_4G,
  64024. + MODE_8G,
  64025. +};
  64026. /* mma8450 status */
  64027. struct mma8450 {
  64028. struct i2c_client *client;
  64029. struct input_polled_dev *idev;
  64030. + struct mutex mma8450_lock;
  64031. + u8 mode;
  64032. };
  64033. static int mma8450_read(struct mma8450 *m, unsigned off)
  64034. @@ -112,16 +124,19 @@
  64035. int ret;
  64036. u8 buf[6];
  64037. - ret = mma8450_read(m, MMA8450_STATUS);
  64038. - if (ret < 0)
  64039. - return;
  64040. + mutex_lock(&m->mma8450_lock);
  64041. - if (!(ret & MMA8450_STATUS_ZXYDR))
  64042. + ret = mma8450_read(m, MMA8450_STATUS);
  64043. + if (ret < 0 || !(ret & MMA8450_STATUS_ZXYDR)) {
  64044. + mutex_unlock(&m->mma8450_lock);
  64045. return;
  64046. + }
  64047. ret = mma8450_read_block(m, MMA8450_OUT_X_LSB, buf, sizeof(buf));
  64048. - if (ret < 0)
  64049. + if (ret < 0) {
  64050. + mutex_unlock(&m->mma8450_lock);
  64051. return;
  64052. + }
  64053. x = ((int)(s8)buf[1] << 4) | (buf[0] & 0xf);
  64054. y = ((int)(s8)buf[3] << 4) | (buf[2] & 0xf);
  64055. @@ -131,10 +146,12 @@
  64056. input_report_abs(dev->input, ABS_Y, y);
  64057. input_report_abs(dev->input, ABS_Z, z);
  64058. input_sync(dev->input);
  64059. +
  64060. + mutex_unlock(&m->mma8450_lock);
  64061. }
  64062. /* Initialize the MMA8450 chip */
  64063. -static void mma8450_open(struct input_polled_dev *dev)
  64064. +static s32 mma8450_open(struct input_polled_dev *dev)
  64065. {
  64066. struct mma8450 *m = dev->private;
  64067. int err;
  64068. @@ -142,18 +159,20 @@
  64069. /* enable all events from X/Y/Z, no FIFO */
  64070. err = mma8450_write(m, MMA8450_XYZ_DATA_CFG, 0x07);
  64071. if (err)
  64072. - return;
  64073. + return err;
  64074. /*
  64075. * Sleep mode poll rate - 50Hz
  64076. * System output data rate - 400Hz
  64077. - * Full scale selection - Active, +/- 2G
  64078. + * Standby mode
  64079. */
  64080. - err = mma8450_write(m, MMA8450_CTRL_REG1, 0x01);
  64081. - if (err < 0)
  64082. - return;
  64083. -
  64084. + err = mma8450_write(m, MMA8450_CTRL_REG1, MODE_STANDBY);
  64085. + if (err)
  64086. + return err;
  64087. + m->mode = MODE_STANDBY;
  64088. msleep(MODE_CHANGE_DELAY_MS);
  64089. +
  64090. + return 0;
  64091. }
  64092. static void mma8450_close(struct input_polled_dev *dev)
  64093. @@ -164,6 +183,76 @@
  64094. mma8450_write(m, MMA8450_CTRL_REG2, 0x01);
  64095. }
  64096. +static ssize_t mma8450_scalemode_show(struct device *dev,
  64097. + struct device_attribute *attr,
  64098. + char *buf)
  64099. +{
  64100. + int mode = 0;
  64101. + struct mma8450 *m;
  64102. + struct i2c_client *client = to_i2c_client(dev);
  64103. +
  64104. + m = i2c_get_clientdata(client);
  64105. +
  64106. + mutex_lock(&m->mma8450_lock);
  64107. + mode = (int)m->mode;
  64108. + mutex_unlock(&m->mma8450_lock);
  64109. +
  64110. + return sprintf(buf, "%d\n", mode);
  64111. +}
  64112. +
  64113. +static ssize_t mma8450_scalemode_store(struct device *dev,
  64114. + struct device_attribute *attr,
  64115. + const char *buf, size_t count)
  64116. +{
  64117. + unsigned long mode;
  64118. + int ret;
  64119. + struct mma8450 *m = NULL;
  64120. + struct i2c_client *client = to_i2c_client(dev);
  64121. +
  64122. + ret = strict_strtoul(buf, 10, &mode);
  64123. + if (ret) {
  64124. + dev_err(dev, "string transform error\n");
  64125. + return ret;
  64126. + }
  64127. +
  64128. + if (mode > MODE_8G) {
  64129. + dev_warn(dev, "not supported mode %d\n", (int)mode);
  64130. + return count;
  64131. + }
  64132. +
  64133. + m = i2c_get_clientdata(client);
  64134. +
  64135. + mutex_lock(&m->mma8450_lock);
  64136. + if (mode == m->mode) {
  64137. + mutex_unlock(&m->mma8450_lock);
  64138. + return count;
  64139. + }
  64140. +
  64141. + ret = mma8450_write(m, MMA8450_CTRL_REG1, mode);
  64142. + if (ret < 0) {
  64143. + mutex_unlock(&m->mma8450_lock);
  64144. + return ret;
  64145. + }
  64146. +
  64147. + msleep(MODE_CHANGE_DELAY_MS);
  64148. + m->mode = (u8)mode;
  64149. + mutex_unlock(&m->mma8450_lock);
  64150. +
  64151. + return count;
  64152. +}
  64153. +
  64154. +static DEVICE_ATTR(scalemode, S_IWUSR | S_IRUGO,
  64155. + mma8450_scalemode_show, mma8450_scalemode_store);
  64156. +
  64157. +static struct attribute *mma8450_attributes[] = {
  64158. + &dev_attr_scalemode.attr,
  64159. + NULL
  64160. +};
  64161. +
  64162. +static const struct attribute_group mma8450_attr_group = {
  64163. + .attrs = mma8450_attributes,
  64164. +};
  64165. +
  64166. /*
  64167. * I2C init/probing/exit functions
  64168. */
  64169. @@ -172,7 +261,25 @@
  64170. {
  64171. struct input_polled_dev *idev;
  64172. struct mma8450 *m;
  64173. - int err;
  64174. + int err, client_id;
  64175. + struct i2c_adapter *adapter = NULL;
  64176. +
  64177. + adapter = to_i2c_adapter(c->dev.parent);
  64178. + err = i2c_check_functionality(adapter,
  64179. + I2C_FUNC_SMBUS_BYTE |
  64180. + I2C_FUNC_SMBUS_BYTE_DATA);
  64181. + if (!err)
  64182. + goto err_out;
  64183. +
  64184. + client_id = i2c_smbus_read_byte_data(c, MMA8450_WHO_AM_I);
  64185. +
  64186. + if (MMA8450_ID != client_id) {
  64187. + dev_err(&c->dev,
  64188. + "read chip ID 0x%x is not equal to 0x%x!\n", client_id,
  64189. + MMA8450_ID);
  64190. + err = -EINVAL;
  64191. + goto err_out;
  64192. + }
  64193. m = kzalloc(sizeof(struct mma8450), GFP_KERNEL);
  64194. idev = input_allocate_polled_device();
  64195. @@ -183,6 +290,7 @@
  64196. m->client = c;
  64197. m->idev = idev;
  64198. + i2c_set_clientdata(c, m);
  64199. idev->private = m;
  64200. idev->input->name = MMA8450_DRV_NAME;
  64201. @@ -190,8 +298,6 @@
  64202. idev->poll = mma8450_poll;
  64203. idev->poll_interval = POLL_INTERVAL;
  64204. idev->poll_interval_max = POLL_INTERVAL_MAX;
  64205. - idev->open = mma8450_open;
  64206. - idev->close = mma8450_close;
  64207. __set_bit(EV_ABS, idev->input->evbit);
  64208. input_set_abs_params(idev->input, ABS_X, -2048, 2047, 32, 32);
  64209. @@ -206,11 +312,32 @@
  64210. i2c_set_clientdata(c, m);
  64211. + mutex_init(&m->mma8450_lock);
  64212. +
  64213. + err = mma8450_open(idev);
  64214. + if (err) {
  64215. + dev_err(&c->dev, "failed to initialize mma8450\n");
  64216. + goto err_unreg_dev;
  64217. + }
  64218. +
  64219. + err = sysfs_create_group(&c->dev.kobj, &mma8450_attr_group);
  64220. + if (err) {
  64221. + dev_err(&c->dev, "create device file failed!\n");
  64222. + err = -EINVAL;
  64223. + goto err_close;
  64224. + }
  64225. +
  64226. return 0;
  64227. +err_close:
  64228. + mma8450_close(idev);
  64229. +err_unreg_dev:
  64230. + mutex_destroy(&m->mma8450_lock);
  64231. + input_unregister_polled_device(idev);
  64232. err_free_mem:
  64233. input_free_polled_device(idev);
  64234. kfree(m);
  64235. +err_out:
  64236. return err;
  64237. }
  64238. @@ -219,6 +346,9 @@
  64239. struct mma8450 *m = i2c_get_clientdata(c);
  64240. struct input_polled_dev *idev = m->idev;
  64241. + sysfs_remove_group(&c->dev.kobj, &mma8450_attr_group);
  64242. + mma8450_close(idev);
  64243. + mutex_destroy(&m->mma8450_lock);
  64244. input_unregister_polled_device(idev);
  64245. input_free_polled_device(idev);
  64246. kfree(m);
  64247. diff -Nur linux-3.14.15/drivers/input/mouse/synaptics.c linux-linaro-stable-mx6/drivers/input/mouse/synaptics.c
  64248. --- linux-3.14.15/drivers/input/mouse/synaptics.c 2014-07-31 23:51:43.000000000 +0200
  64249. +++ linux-linaro-stable-mx6/drivers/input/mouse/synaptics.c 2014-08-20 19:31:44.020859956 +0200
  64250. @@ -132,8 +132,7 @@
  64251. 1232, 5710, 1156, 4696
  64252. },
  64253. {
  64254. - (const char * const []){"LEN0034", "LEN0036", "LEN2002",
  64255. - "LEN2004", NULL},
  64256. + (const char * const []){"LEN0034", "LEN0036", "LEN2004", NULL},
  64257. 1024, 5112, 2024, 4832
  64258. },
  64259. {
  64260. @@ -169,7 +168,7 @@
  64261. "LEN0049",
  64262. "LEN2000",
  64263. "LEN2001", /* Edge E431 */
  64264. - "LEN2002", /* Edge E531 */
  64265. + "LEN2002",
  64266. "LEN2003",
  64267. "LEN2004", /* L440 */
  64268. "LEN2005",
  64269. diff -Nur linux-3.14.15/drivers/input/sparse-keymap.c linux-linaro-stable-mx6/drivers/input/sparse-keymap.c
  64270. --- linux-3.14.15/drivers/input/sparse-keymap.c 2014-07-31 23:51:43.000000000 +0200
  64271. +++ linux-linaro-stable-mx6/drivers/input/sparse-keymap.c 2014-08-20 19:31:44.024859975 +0200
  64272. @@ -236,7 +236,7 @@
  64273. * in an input device that was set up by sparse_keymap_setup().
  64274. * NOTE: It is safe to cal this function while input device is
  64275. * still registered (however the drivers should care not to try to
  64276. - * use freed keymap and thus have to shut off interrups/polling
  64277. + * use freed keymap and thus have to shut off interrupts/polling
  64278. * before freeing the keymap).
  64279. */
  64280. void sparse_keymap_free(struct input_dev *dev)
  64281. diff -Nur linux-3.14.15/drivers/Kconfig linux-linaro-stable-mx6/drivers/Kconfig
  64282. --- linux-3.14.15/drivers/Kconfig 2014-07-31 23:51:43.000000000 +0200
  64283. +++ linux-linaro-stable-mx6/drivers/Kconfig 2014-08-20 19:31:42.224852248 +0200
  64284. @@ -96,6 +96,8 @@
  64285. source "drivers/memstick/Kconfig"
  64286. +source "drivers/mxc/Kconfig"
  64287. +
  64288. source "drivers/leds/Kconfig"
  64289. source "drivers/accessibility/Kconfig"
  64290. diff -Nur linux-3.14.15/drivers/leds/leds-gpio.c linux-linaro-stable-mx6/drivers/leds/leds-gpio.c
  64291. --- linux-3.14.15/drivers/leds/leds-gpio.c 2014-07-31 23:51:43.000000000 +0200
  64292. +++ linux-linaro-stable-mx6/drivers/leds/leds-gpio.c 2014-08-20 19:31:44.600862447 +0200
  64293. @@ -3,7 +3,7 @@
  64294. *
  64295. * Copyright (C) 2007 8D Technologies inc.
  64296. * Raphael Assenat <raph@8d.com>
  64297. - * Copyright (C) 2008 Freescale Semiconductor, Inc.
  64298. + * Copyright (C) 2008, 2014 Freescale Semiconductor, Inc.
  64299. *
  64300. * This program is free software; you can redistribute it and/or modify
  64301. * it under the terms of the GNU General Public License version 2 as
  64302. @@ -203,6 +203,8 @@
  64303. else
  64304. led.default_state = LEDS_GPIO_DEFSTATE_OFF;
  64305. }
  64306. + if (of_get_property(child, "retain-state-suspended", NULL))
  64307. + led.retain_state_suspended = 1;
  64308. ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
  64309. &pdev->dev, NULL);
  64310. diff -Nur linux-3.14.15/drivers/leds/leds-pwm.c linux-linaro-stable-mx6/drivers/leds/leds-pwm.c
  64311. --- linux-3.14.15/drivers/leds/leds-pwm.c 2014-07-31 23:51:43.000000000 +0200
  64312. +++ linux-linaro-stable-mx6/drivers/leds/leds-pwm.c 2014-08-20 19:31:44.604862464 +0200
  64313. @@ -70,6 +70,10 @@
  64314. duty *= brightness;
  64315. do_div(duty, max);
  64316. +
  64317. + if (led_dat->active_low)
  64318. + duty = led_dat->period - duty;
  64319. +
  64320. led_dat->duty = duty;
  64321. if (led_dat->can_sleep)
  64322. @@ -93,55 +97,75 @@
  64323. }
  64324. }
  64325. -static int led_pwm_create_of(struct platform_device *pdev,
  64326. - struct led_pwm_priv *priv)
  64327. +static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
  64328. + struct led_pwm *led, struct device_node *child)
  64329. {
  64330. - struct device_node *child;
  64331. + struct led_pwm_data *led_data = &priv->leds[priv->num_leds];
  64332. int ret;
  64333. - for_each_child_of_node(pdev->dev.of_node, child) {
  64334. - struct led_pwm_data *led_dat = &priv->leds[priv->num_leds];
  64335. + led_data->active_low = led->active_low;
  64336. + led_data->period = led->pwm_period_ns;
  64337. + led_data->cdev.name = led->name;
  64338. + led_data->cdev.default_trigger = led->default_trigger;
  64339. + led_data->cdev.brightness_set = led_pwm_set;
  64340. + led_data->cdev.brightness = LED_OFF;
  64341. + led_data->cdev.max_brightness = led->max_brightness;
  64342. + led_data->cdev.flags = LED_CORE_SUSPENDRESUME;
  64343. +
  64344. + if (child)
  64345. + led_data->pwm = devm_of_pwm_get(dev, child, NULL);
  64346. + else
  64347. + led_data->pwm = devm_pwm_get(dev, led->name);
  64348. + if (IS_ERR(led_data->pwm)) {
  64349. + ret = PTR_ERR(led_data->pwm);
  64350. + dev_err(dev, "unable to request PWM for %s: %d\n",
  64351. + led->name, ret);
  64352. + return ret;
  64353. + }
  64354. - led_dat->cdev.name = of_get_property(child, "label",
  64355. - NULL) ? : child->name;
  64356. + if (child)
  64357. + led_data->period = pwm_get_period(led_data->pwm);
  64358. - led_dat->pwm = devm_of_pwm_get(&pdev->dev, child, NULL);
  64359. - if (IS_ERR(led_dat->pwm)) {
  64360. - dev_err(&pdev->dev, "unable to request PWM for %s\n",
  64361. - led_dat->cdev.name);
  64362. - ret = PTR_ERR(led_dat->pwm);
  64363. - goto err;
  64364. - }
  64365. - /* Get the period from PWM core when n*/
  64366. - led_dat->period = pwm_get_period(led_dat->pwm);
  64367. + led_data->can_sleep = pwm_can_sleep(led_data->pwm);
  64368. + if (led_data->can_sleep)
  64369. + INIT_WORK(&led_data->work, led_pwm_work);
  64370. - led_dat->cdev.default_trigger = of_get_property(child,
  64371. + ret = led_classdev_register(dev, &led_data->cdev);
  64372. + if (ret == 0) {
  64373. + priv->num_leds++;
  64374. + } else {
  64375. + dev_err(dev, "failed to register PWM led for %s: %d\n",
  64376. + led->name, ret);
  64377. + }
  64378. +
  64379. + return ret;
  64380. +}
  64381. +
  64382. +static int led_pwm_create_of(struct device *dev, struct led_pwm_priv *priv)
  64383. +{
  64384. + struct device_node *child;
  64385. + struct led_pwm led;
  64386. + int ret = 0;
  64387. +
  64388. + memset(&led, 0, sizeof(led));
  64389. +
  64390. + for_each_child_of_node(dev->of_node, child) {
  64391. + led.name = of_get_property(child, "label", NULL) ? :
  64392. + child->name;
  64393. +
  64394. + led.default_trigger = of_get_property(child,
  64395. "linux,default-trigger", NULL);
  64396. + led.active_low = of_property_read_bool(child, "active-low");
  64397. of_property_read_u32(child, "max-brightness",
  64398. - &led_dat->cdev.max_brightness);
  64399. + &led.max_brightness);
  64400. - led_dat->cdev.brightness_set = led_pwm_set;
  64401. - led_dat->cdev.brightness = LED_OFF;
  64402. - led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
  64403. -
  64404. - led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
  64405. - if (led_dat->can_sleep)
  64406. - INIT_WORK(&led_dat->work, led_pwm_work);
  64407. -
  64408. - ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
  64409. - if (ret < 0) {
  64410. - dev_err(&pdev->dev, "failed to register for %s\n",
  64411. - led_dat->cdev.name);
  64412. + ret = led_pwm_add(dev, priv, &led, child);
  64413. + if (ret) {
  64414. of_node_put(child);
  64415. - goto err;
  64416. + break;
  64417. }
  64418. - priv->num_leds++;
  64419. }
  64420. - return 0;
  64421. -err:
  64422. - led_pwm_cleanup(priv);
  64423. -
  64424. return ret;
  64425. }
  64426. @@ -167,51 +191,23 @@
  64427. if (pdata) {
  64428. for (i = 0; i < count; i++) {
  64429. - struct led_pwm *cur_led = &pdata->leds[i];
  64430. - struct led_pwm_data *led_dat = &priv->leds[i];
  64431. -
  64432. - led_dat->pwm = devm_pwm_get(&pdev->dev, cur_led->name);
  64433. - if (IS_ERR(led_dat->pwm)) {
  64434. - ret = PTR_ERR(led_dat->pwm);
  64435. - dev_err(&pdev->dev,
  64436. - "unable to request PWM for %s\n",
  64437. - cur_led->name);
  64438. - goto err;
  64439. - }
  64440. -
  64441. - led_dat->cdev.name = cur_led->name;
  64442. - led_dat->cdev.default_trigger = cur_led->default_trigger;
  64443. - led_dat->active_low = cur_led->active_low;
  64444. - led_dat->period = cur_led->pwm_period_ns;
  64445. - led_dat->cdev.brightness_set = led_pwm_set;
  64446. - led_dat->cdev.brightness = LED_OFF;
  64447. - led_dat->cdev.max_brightness = cur_led->max_brightness;
  64448. - led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
  64449. -
  64450. - led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
  64451. - if (led_dat->can_sleep)
  64452. - INIT_WORK(&led_dat->work, led_pwm_work);
  64453. -
  64454. - ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
  64455. - if (ret < 0)
  64456. - goto err;
  64457. + ret = led_pwm_add(&pdev->dev, priv, &pdata->leds[i],
  64458. + NULL);
  64459. + if (ret)
  64460. + break;
  64461. }
  64462. - priv->num_leds = count;
  64463. } else {
  64464. - ret = led_pwm_create_of(pdev, priv);
  64465. - if (ret)
  64466. - return ret;
  64467. + ret = led_pwm_create_of(&pdev->dev, priv);
  64468. + }
  64469. +
  64470. + if (ret) {
  64471. + led_pwm_cleanup(priv);
  64472. + return ret;
  64473. }
  64474. platform_set_drvdata(pdev, priv);
  64475. return 0;
  64476. -
  64477. -err:
  64478. - priv->num_leds = i;
  64479. - led_pwm_cleanup(priv);
  64480. -
  64481. - return ret;
  64482. }
  64483. static int led_pwm_remove(struct platform_device *pdev)
  64484. diff -Nur linux-3.14.15/drivers/mailbox/mailbox.c linux-linaro-stable-mx6/drivers/mailbox/mailbox.c
  64485. --- linux-3.14.15/drivers/mailbox/mailbox.c 1970-01-01 01:00:00.000000000 +0100
  64486. +++ linux-linaro-stable-mx6/drivers/mailbox/mailbox.c 2014-08-20 19:31:44.616862515 +0200
  64487. @@ -0,0 +1,488 @@
  64488. +/*
  64489. + * Mailbox: Common code for Mailbox controllers and users
  64490. + *
  64491. + * Copyright (C) 2014 Linaro Ltd.
  64492. + * Author: Jassi Brar <jassisinghbrar@gmail.com>
  64493. + *
  64494. + * This program is free software; you can redistribute it and/or modify
  64495. + * it under the terms of the GNU General Public License version 2 as
  64496. + * published by the Free Software Foundation.
  64497. + */
  64498. +
  64499. +#include <linux/interrupt.h>
  64500. +#include <linux/spinlock.h>
  64501. +#include <linux/mutex.h>
  64502. +#include <linux/delay.h>
  64503. +#include <linux/slab.h>
  64504. +#include <linux/err.h>
  64505. +#include <linux/module.h>
  64506. +#include <linux/device.h>
  64507. +#include <linux/mailbox_client.h>
  64508. +#include <linux/mailbox_controller.h>
  64509. +
  64510. +#define TXDONE_BY_IRQ (1 << 0) /* controller has remote RTR irq */
  64511. +#define TXDONE_BY_POLL (1 << 1) /* controller can read status of last TX */
  64512. +#define TXDONE_BY_ACK (1 << 2) /* S/W ACK recevied by Client ticks the TX */
  64513. +
  64514. +static LIST_HEAD(mbox_cons);
  64515. +static DEFINE_MUTEX(con_mutex);
  64516. +
  64517. +static int _add_to_rbuf(struct mbox_chan *chan, void *mssg)
  64518. +{
  64519. + int idx;
  64520. + unsigned long flags;
  64521. +
  64522. + spin_lock_irqsave(&chan->lock, flags);
  64523. +
  64524. + /* See if there is any space left */
  64525. + if (chan->msg_count == MBOX_TX_QUEUE_LEN) {
  64526. + spin_unlock_irqrestore(&chan->lock, flags);
  64527. + return -ENOMEM;
  64528. + }
  64529. +
  64530. + idx = chan->msg_free;
  64531. + chan->msg_data[idx] = mssg;
  64532. + chan->msg_count++;
  64533. +
  64534. + if (idx == MBOX_TX_QUEUE_LEN - 1)
  64535. + chan->msg_free = 0;
  64536. + else
  64537. + chan->msg_free++;
  64538. +
  64539. + spin_unlock_irqrestore(&chan->lock, flags);
  64540. +
  64541. + return idx;
  64542. +}
  64543. +
  64544. +static void _msg_submit(struct mbox_chan *chan)
  64545. +{
  64546. + unsigned count, idx;
  64547. + unsigned long flags;
  64548. + void *data;
  64549. + int err;
  64550. +
  64551. + spin_lock_irqsave(&chan->lock, flags);
  64552. +
  64553. + if (!chan->msg_count || chan->active_req) {
  64554. + spin_unlock_irqrestore(&chan->lock, flags);
  64555. + return;
  64556. + }
  64557. +
  64558. + count = chan->msg_count;
  64559. + idx = chan->msg_free;
  64560. + if (idx >= count)
  64561. + idx -= count;
  64562. + else
  64563. + idx += MBOX_TX_QUEUE_LEN - count;
  64564. +
  64565. + data = chan->msg_data[idx];
  64566. +
  64567. + /* Try to submit a message to the MBOX controller */
  64568. + err = chan->mbox->ops->send_data(chan, data);
  64569. + if (!err) {
  64570. + chan->active_req = data;
  64571. + chan->msg_count--;
  64572. + }
  64573. +
  64574. + spin_unlock_irqrestore(&chan->lock, flags);
  64575. +}
  64576. +
  64577. +static void tx_tick(struct mbox_chan *chan, int r)
  64578. +{
  64579. + unsigned long flags;
  64580. + void *mssg;
  64581. +
  64582. + spin_lock_irqsave(&chan->lock, flags);
  64583. + mssg = chan->active_req;
  64584. + chan->active_req = NULL;
  64585. + spin_unlock_irqrestore(&chan->lock, flags);
  64586. +
  64587. + /* Submit next message */
  64588. + _msg_submit(chan);
  64589. +
  64590. + /* Notify the client */
  64591. + if (chan->cl->tx_block)
  64592. + complete(&chan->tx_complete);
  64593. + else if (mssg && chan->cl->tx_done)
  64594. + chan->cl->tx_done(chan->cl, mssg, r);
  64595. +}
  64596. +
  64597. +static void poll_txdone(unsigned long data)
  64598. +{
  64599. + struct mbox_controller *mbox = (struct mbox_controller *)data;
  64600. + bool txdone, resched = false;
  64601. + int i;
  64602. +
  64603. + for (i = 0; i < mbox->num_chans; i++) {
  64604. + struct mbox_chan *chan = &mbox->chans[i];
  64605. +
  64606. + if (chan->active_req && chan->cl) {
  64607. + resched = true;
  64608. + txdone = chan->mbox->ops->last_tx_done(chan);
  64609. + if (txdone)
  64610. + tx_tick(chan, 0);
  64611. + }
  64612. + }
  64613. +
  64614. + if (resched)
  64615. + mod_timer(&mbox->poll,
  64616. + jiffies + msecs_to_jiffies(mbox->period));
  64617. +}
  64618. +
  64619. +/**
  64620. + * mbox_chan_received_data - A way for controller driver to push data
  64621. + * received from remote to the upper layer.
  64622. + * @chan: Pointer to the mailbox channel on which RX happened.
  64623. + * @data: Client specific message typecasted as void *
  64624. + *
  64625. + * After startup and before shutdown any data received on the chan
  64626. + * is passed on to the API via atomic mbox_chan_received_data().
  64627. + * The controller should ACK the RX only after this call returns.
  64628. + */
  64629. +void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)
  64630. +{
  64631. + /* No buffering the received data */
  64632. + if (chan->cl->rx_callback)
  64633. + chan->cl->rx_callback(chan->cl, mssg);
  64634. +}
  64635. +EXPORT_SYMBOL_GPL(mbox_chan_received_data);
  64636. +
  64637. +/**
  64638. + * mbox_chan_txdone - A way for controller driver to notify the
  64639. + * framework that the last TX has completed.
  64640. + * @chan: Pointer to the mailbox chan on which TX happened.
  64641. + * @r: Status of last TX - OK or ERROR
  64642. + *
  64643. + * The controller that has IRQ for TX ACK calls this atomic API
  64644. + * to tick the TX state machine. It works only if txdone_irq
  64645. + * is set by the controller.
  64646. + */
  64647. +void mbox_chan_txdone(struct mbox_chan *chan, int r)
  64648. +{
  64649. + if (unlikely(!(chan->txdone_method & TXDONE_BY_IRQ))) {
  64650. + pr_err("Controller can't run the TX ticker\n");
  64651. + return;
  64652. + }
  64653. +
  64654. + tx_tick(chan, r);
  64655. +}
  64656. +EXPORT_SYMBOL_GPL(mbox_chan_txdone);
  64657. +
  64658. +/**
  64659. + * mbox_client_txdone - The way for a client to run the TX state machine.
  64660. + * @chan: Mailbox channel assigned to this client.
  64661. + * @r: Success status of last transmission.
  64662. + *
  64663. + * The client/protocol had received some 'ACK' packet and it notifies
  64664. + * the API that the last packet was sent successfully. This only works
  64665. + * if the controller can't sense TX-Done.
  64666. + */
  64667. +void mbox_client_txdone(struct mbox_chan *chan, int r)
  64668. +{
  64669. + if (unlikely(!(chan->txdone_method & TXDONE_BY_ACK))) {
  64670. + pr_err("Client can't run the TX ticker\n");
  64671. + return;
  64672. + }
  64673. +
  64674. + tx_tick(chan, r);
  64675. +}
  64676. +EXPORT_SYMBOL_GPL(mbox_client_txdone);
  64677. +
  64678. +/**
  64679. + * mbox_client_peek_data - A way for client driver to pull data
  64680. + * received from remote by the controller.
  64681. + * @chan: Mailbox channel assigned to this client.
  64682. + *
  64683. + * A poke to controller driver for any received data.
  64684. + * The data is actually passed onto client via the
  64685. + * mbox_chan_received_data()
  64686. + * The call can be made from atomic context, so the controller's
  64687. + * implementation of peek_data() must not sleep.
  64688. + *
  64689. + * Return: True, if controller has, and is going to push after this,
  64690. + * some data.
  64691. + * False, if controller doesn't have any data to be read.
  64692. + */
  64693. +bool mbox_client_peek_data(struct mbox_chan *chan)
  64694. +{
  64695. + if (chan->mbox->ops->peek_data)
  64696. + return chan->mbox->ops->peek_data(chan);
  64697. +
  64698. + return false;
  64699. +}
  64700. +EXPORT_SYMBOL_GPL(mbox_client_peek_data);
  64701. +
  64702. +/**
  64703. + * mbox_send_message - For client to submit a message to be
  64704. + * sent to the remote.
  64705. + * @chan: Mailbox channel assigned to this client.
  64706. + * @mssg: Client specific message typecasted.
  64707. + *
  64708. + * For client to submit data to the controller destined for a remote
  64709. + * processor. If the client had set 'tx_block', the call will return
  64710. + * either when the remote receives the data or when 'tx_tout' millisecs
  64711. + * run out.
  64712. + * In non-blocking mode, the requests are buffered by the API and a
  64713. + * non-negative token is returned for each queued request. If the request
  64714. + * is not queued, a negative token is returned. Upon failure or successful
  64715. + * TX, the API calls 'tx_done' from atomic context, from which the client
  64716. + * could submit yet another request.
  64717. + * In blocking mode, 'tx_done' is not called, effectively making the
  64718. + * queue length 1.
  64719. + * The pointer to message should be preserved until it is sent
  64720. + * over the chan, i.e, tx_done() is made.
  64721. + * This function could be called from atomic context as it simply
  64722. + * queues the data and returns a token against the request.
  64723. + *
  64724. + * Return: Non-negative integer for successful submission (non-blocking mode)
  64725. + * or transmission over chan (blocking mode).
  64726. + * Negative value denotes failure.
  64727. + */
  64728. +int mbox_send_message(struct mbox_chan *chan, void *mssg)
  64729. +{
  64730. + int t;
  64731. +
  64732. + if (!chan || !chan->cl)
  64733. + return -EINVAL;
  64734. +
  64735. + t = _add_to_rbuf(chan, mssg);
  64736. + if (t < 0) {
  64737. + pr_err("Try increasing MBOX_TX_QUEUE_LEN\n");
  64738. + return t;
  64739. + }
  64740. +
  64741. + _msg_submit(chan);
  64742. +
  64743. + reinit_completion(&chan->tx_complete);
  64744. +
  64745. + if (chan->txdone_method == TXDONE_BY_POLL)
  64746. + poll_txdone((unsigned long)chan->mbox);
  64747. +
  64748. + if (chan->cl->tx_block && chan->active_req) {
  64749. + unsigned long wait;
  64750. + int ret;
  64751. +
  64752. + if (!chan->cl->tx_tout) /* wait for ever */
  64753. + wait = msecs_to_jiffies(3600000);
  64754. + else
  64755. + wait = msecs_to_jiffies(chan->cl->tx_tout);
  64756. +
  64757. + ret = wait_for_completion_timeout(&chan->tx_complete, wait);
  64758. + if (ret == 0) {
  64759. + t = -EIO;
  64760. + tx_tick(chan, -EIO);
  64761. + }
  64762. + }
  64763. +
  64764. + return t;
  64765. +}
  64766. +EXPORT_SYMBOL_GPL(mbox_send_message);
  64767. +
  64768. +/**
  64769. + * mbox_request_channel - Request a mailbox channel.
  64770. + * @cl: Identity of the client requesting the channel.
  64771. + *
  64772. + * The Client specifies its requirements and capabilities while asking for
  64773. + * a mailbox channel. It can't be called from atomic context.
  64774. + * The channel is exclusively allocated and can't be used by another
  64775. + * client before the owner calls mbox_free_channel.
  64776. + * After assignment, any packet received on this channel will be
  64777. + * handed over to the client via the 'rx_callback'.
  64778. + * The framework holds reference to the client, so the mbox_client
  64779. + * structure shouldn't be modified until the mbox_free_channel returns.
  64780. + *
  64781. + * Return: Pointer to the channel assigned to the client if successful.
  64782. + * ERR_PTR for request failure.
  64783. + */
  64784. +struct mbox_chan *mbox_request_channel(struct mbox_client *cl)
  64785. +{
  64786. + struct device *dev = cl->dev;
  64787. + struct mbox_controller *mbox;
  64788. + struct of_phandle_args spec;
  64789. + struct mbox_chan *chan;
  64790. + unsigned long flags;
  64791. + int count, i, ret;
  64792. +
  64793. + if (!dev || !dev->of_node) {
  64794. + pr_err("%s: No owner device node\n", __func__);
  64795. + return ERR_PTR(-ENODEV);
  64796. + }
  64797. +
  64798. + count = of_property_count_strings(dev->of_node, "mbox-names");
  64799. + if (count < 0) {
  64800. + pr_err("%s: mbox-names property of node '%s' missing\n",
  64801. + __func__, dev->of_node->full_name);
  64802. + return ERR_PTR(-ENODEV);
  64803. + }
  64804. +
  64805. + mutex_lock(&con_mutex);
  64806. +
  64807. + ret = -ENODEV;
  64808. + for (i = 0; i < count; i++) {
  64809. + const char *s;
  64810. +
  64811. + if (of_property_read_string_index(dev->of_node,
  64812. + "mbox-names", i, &s))
  64813. + continue;
  64814. +
  64815. + if (strcmp(cl->chan_name, s))
  64816. + continue;
  64817. +
  64818. + if (of_parse_phandle_with_args(dev->of_node,
  64819. + "mbox", "#mbox-cells", i, &spec))
  64820. + continue;
  64821. +
  64822. + chan = NULL;
  64823. + list_for_each_entry(mbox, &mbox_cons, node)
  64824. + if (mbox->dev->of_node == spec.np) {
  64825. + chan = mbox->of_xlate(mbox, &spec);
  64826. + break;
  64827. + }
  64828. +
  64829. + of_node_put(spec.np);
  64830. +
  64831. + if (!chan)
  64832. + continue;
  64833. +
  64834. + ret = -EBUSY;
  64835. + if (!chan->cl && try_module_get(mbox->dev->driver->owner))
  64836. + break;
  64837. + }
  64838. +
  64839. + if (i == count) {
  64840. + mutex_unlock(&con_mutex);
  64841. + return ERR_PTR(ret);
  64842. + }
  64843. +
  64844. + spin_lock_irqsave(&chan->lock, flags);
  64845. + chan->msg_free = 0;
  64846. + chan->msg_count = 0;
  64847. + chan->active_req = NULL;
  64848. + chan->cl = cl;
  64849. + init_completion(&chan->tx_complete);
  64850. +
  64851. + if (chan->txdone_method == TXDONE_BY_POLL
  64852. + && cl->knows_txdone)
  64853. + chan->txdone_method |= TXDONE_BY_ACK;
  64854. + spin_unlock_irqrestore(&chan->lock, flags);
  64855. +
  64856. + ret = chan->mbox->ops->startup(chan);
  64857. + if (ret) {
  64858. + pr_err("Unable to startup the chan (%d)\n", ret);
  64859. + mbox_free_channel(chan);
  64860. + chan = ERR_PTR(ret);
  64861. + }
  64862. +
  64863. + mutex_unlock(&con_mutex);
  64864. + return chan;
  64865. +}
  64866. +EXPORT_SYMBOL_GPL(mbox_request_channel);
  64867. +
  64868. +/**
  64869. + * mbox_free_channel - The client relinquishes control of a mailbox
  64870. + * channel by this call.
  64871. + * @chan: The mailbox channel to be freed.
  64872. + */
  64873. +void mbox_free_channel(struct mbox_chan *chan)
  64874. +{
  64875. + unsigned long flags;
  64876. +
  64877. + if (!chan || !chan->cl)
  64878. + return;
  64879. +
  64880. + chan->mbox->ops->shutdown(chan);
  64881. +
  64882. + /* The queued TX requests are simply aborted, no callbacks are made */
  64883. + spin_lock_irqsave(&chan->lock, flags);
  64884. + chan->cl = NULL;
  64885. + chan->active_req = NULL;
  64886. + if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK))
  64887. + chan->txdone_method = TXDONE_BY_POLL;
  64888. +
  64889. + module_put(chan->mbox->dev->driver->owner);
  64890. + spin_unlock_irqrestore(&chan->lock, flags);
  64891. +}
  64892. +EXPORT_SYMBOL_GPL(mbox_free_channel);
  64893. +
  64894. +static struct mbox_chan *
  64895. +of_mbox_index_xlate(struct mbox_controller *mbox,
  64896. + const struct of_phandle_args *sp)
  64897. +{
  64898. + int ind = sp->args[0];
  64899. +
  64900. + if (ind >= mbox->num_chans)
  64901. + return NULL;
  64902. +
  64903. + return &mbox->chans[ind];
  64904. +}
  64905. +
  64906. +/**
  64907. + * mbox_controller_register - Register the mailbox controller
  64908. + * @mbox: Pointer to the mailbox controller.
  64909. + *
  64910. + * The controller driver registers its communication chans
  64911. + */
  64912. +int mbox_controller_register(struct mbox_controller *mbox)
  64913. +{
  64914. + int i, txdone;
  64915. +
  64916. + /* Sanity check */
  64917. + if (!mbox || !mbox->dev || !mbox->ops || !mbox->num_chans)
  64918. + return -EINVAL;
  64919. +
  64920. + if (mbox->txdone_irq)
  64921. + txdone = TXDONE_BY_IRQ;
  64922. + else if (mbox->txdone_poll)
  64923. + txdone = TXDONE_BY_POLL;
  64924. + else /* It has to be ACK then */
  64925. + txdone = TXDONE_BY_ACK;
  64926. +
  64927. + if (txdone == TXDONE_BY_POLL) {
  64928. + mbox->poll.function = &poll_txdone;
  64929. + mbox->poll.data = (unsigned long)mbox;
  64930. + init_timer(&mbox->poll);
  64931. + }
  64932. +
  64933. + for (i = 0; i < mbox->num_chans; i++) {
  64934. + struct mbox_chan *chan = &mbox->chans[i];
  64935. + chan->cl = NULL;
  64936. + chan->mbox = mbox;
  64937. + chan->txdone_method = txdone;
  64938. + spin_lock_init(&chan->lock);
  64939. + }
  64940. +
  64941. + if (!mbox->of_xlate)
  64942. + mbox->of_xlate = of_mbox_index_xlate;
  64943. +
  64944. + mutex_lock(&con_mutex);
  64945. + list_add_tail(&mbox->node, &mbox_cons);
  64946. + mutex_unlock(&con_mutex);
  64947. +
  64948. + return 0;
  64949. +}
  64950. +EXPORT_SYMBOL_GPL(mbox_controller_register);
  64951. +
  64952. +/**
  64953. + * mbox_controller_unregister - UnRegister the mailbox controller
  64954. + * @mbox: Pointer to the mailbox controller.
  64955. + */
  64956. +void mbox_controller_unregister(struct mbox_controller *mbox)
  64957. +{
  64958. + int i;
  64959. +
  64960. + if (!mbox)
  64961. + return;
  64962. +
  64963. + mutex_lock(&con_mutex);
  64964. +
  64965. + list_del(&mbox->node);
  64966. +
  64967. + for (i = 0; i < mbox->num_chans; i++)
  64968. + mbox_free_channel(&mbox->chans[i]);
  64969. +
  64970. + if (mbox->txdone_poll)
  64971. + del_timer_sync(&mbox->poll);
  64972. +
  64973. + mutex_unlock(&con_mutex);
  64974. +}
  64975. +EXPORT_SYMBOL_GPL(mbox_controller_unregister);
  64976. diff -Nur linux-3.14.15/drivers/mailbox/Makefile linux-linaro-stable-mx6/drivers/mailbox/Makefile
  64977. --- linux-3.14.15/drivers/mailbox/Makefile 2014-07-31 23:51:43.000000000 +0200
  64978. +++ linux-linaro-stable-mx6/drivers/mailbox/Makefile 2014-08-20 19:31:44.612862497 +0200
  64979. @@ -1,3 +1,7 @@
  64980. +# Generic MAILBOX API
  64981. +
  64982. +obj-$(CONFIG_MAILBOX) += mailbox.o
  64983. +
  64984. obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
  64985. obj-$(CONFIG_OMAP_MBOX) += omap-mailbox.o
  64986. diff -Nur linux-3.14.15/drivers/mailbox/pl320-ipc.c linux-linaro-stable-mx6/drivers/mailbox/pl320-ipc.c
  64987. --- linux-3.14.15/drivers/mailbox/pl320-ipc.c 2014-07-31 23:51:43.000000000 +0200
  64988. +++ linux-linaro-stable-mx6/drivers/mailbox/pl320-ipc.c 2014-08-20 19:31:44.620862533 +0200
  64989. @@ -26,7 +26,7 @@
  64990. #include <linux/device.h>
  64991. #include <linux/amba/bus.h>
  64992. -#include <linux/mailbox.h>
  64993. +#include <linux/pl320-ipc.h>
  64994. #define IPCMxSOURCE(m) ((m) * 0x40)
  64995. #define IPCMxDSET(m) (((m) * 0x40) + 0x004)
  64996. diff -Nur linux-3.14.15/drivers/Makefile linux-linaro-stable-mx6/drivers/Makefile
  64997. --- linux-3.14.15/drivers/Makefile 2014-07-31 23:51:43.000000000 +0200
  64998. +++ linux-linaro-stable-mx6/drivers/Makefile 2014-08-20 19:31:42.224852248 +0200
  64999. @@ -111,6 +111,7 @@
  65000. obj-$(CONFIG_CPU_FREQ) += cpufreq/
  65001. obj-$(CONFIG_CPU_IDLE) += cpuidle/
  65002. obj-y += mmc/
  65003. +obj-$(CONFIG_ARCH_MXC) += mxc/
  65004. obj-$(CONFIG_MEMSTICK) += memstick/
  65005. obj-y += leds/
  65006. obj-$(CONFIG_INFINIBAND) += infiniband/
  65007. diff -Nur linux-3.14.15/drivers/media/dvb-frontends/tda10071.c linux-linaro-stable-mx6/drivers/media/dvb-frontends/tda10071.c
  65008. --- linux-3.14.15/drivers/media/dvb-frontends/tda10071.c 2014-07-31 23:51:43.000000000 +0200
  65009. +++ linux-linaro-stable-mx6/drivers/media/dvb-frontends/tda10071.c 2014-08-20 19:31:45.104864610 +0200
  65010. @@ -667,7 +667,6 @@
  65011. struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  65012. int ret, i;
  65013. u8 mode, rolloff, pilot, inversion, div;
  65014. - fe_modulation_t modulation;
  65015. dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d modulation=%d " \
  65016. "frequency=%d symbol_rate=%d inversion=%d pilot=%d " \
  65017. @@ -702,13 +701,10 @@
  65018. switch (c->delivery_system) {
  65019. case SYS_DVBS:
  65020. - modulation = QPSK;
  65021. rolloff = 0;
  65022. pilot = 2;
  65023. break;
  65024. case SYS_DVBS2:
  65025. - modulation = c->modulation;
  65026. -
  65027. switch (c->rolloff) {
  65028. case ROLLOFF_20:
  65029. rolloff = 2;
  65030. @@ -753,7 +749,7 @@
  65031. for (i = 0, mode = 0xff; i < ARRAY_SIZE(TDA10071_MODCOD); i++) {
  65032. if (c->delivery_system == TDA10071_MODCOD[i].delivery_system &&
  65033. - modulation == TDA10071_MODCOD[i].modulation &&
  65034. + c->modulation == TDA10071_MODCOD[i].modulation &&
  65035. c->fec_inner == TDA10071_MODCOD[i].fec) {
  65036. mode = TDA10071_MODCOD[i].val;
  65037. dev_dbg(&priv->i2c->dev, "%s: mode found=%02x\n",
  65038. diff -Nur linux-3.14.15/drivers/media/platform/Kconfig linux-linaro-stable-mx6/drivers/media/platform/Kconfig
  65039. --- linux-3.14.15/drivers/media/platform/Kconfig 2014-07-31 23:51:43.000000000 +0200
  65040. +++ linux-linaro-stable-mx6/drivers/media/platform/Kconfig 2014-08-20 19:31:45.424865984 +0200
  65041. @@ -115,6 +115,21 @@
  65042. To compile this driver as a module, choose M here: the module
  65043. will be called s3c-camif.
  65044. +config VIDEO_MXC_OUTPUT
  65045. + tristate "MXC Video For Linux Video Output"
  65046. + depends on VIDEO_DEV && ARCH_MXC && FB_MXC
  65047. + select VIDEOBUF_DMA_CONTIG
  65048. + ---help---
  65049. + This is the video4linux2 output driver based on MXC module.
  65050. +
  65051. +config VIDEO_MXC_CAPTURE
  65052. + tristate "MXC Video For Linux Video Capture"
  65053. + depends on VIDEO_V4L2 && VIDEO_V4L2_INT_DEVICE
  65054. + ---help---
  65055. + This is the video4linux2 capture driver based on i.MX video-in module.
  65056. +
  65057. +source "drivers/media/platform/mxc/capture/Kconfig"
  65058. +source "drivers/media/platform/mxc/output/Kconfig"
  65059. source "drivers/media/platform/soc_camera/Kconfig"
  65060. source "drivers/media/platform/exynos4-is/Kconfig"
  65061. source "drivers/media/platform/s5p-tv/Kconfig"
  65062. diff -Nur linux-3.14.15/drivers/media/platform/Makefile linux-linaro-stable-mx6/drivers/media/platform/Makefile
  65063. --- linux-3.14.15/drivers/media/platform/Makefile 2014-07-31 23:51:43.000000000 +0200
  65064. +++ linux-linaro-stable-mx6/drivers/media/platform/Makefile 2014-08-20 19:31:45.424865984 +0200
  65065. @@ -51,4 +51,7 @@
  65066. obj-$(CONFIG_ARCH_OMAP) += omap/
  65067. +obj-$(CONFIG_VIDEO_MXC_CAPTURE) += mxc/capture/
  65068. +obj-$(CONFIG_VIDEO_MXC_OUTPUT) += mxc/output/
  65069. +
  65070. ccflags-y += -I$(srctree)/drivers/media/i2c
  65071. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/adv7180.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/adv7180.c
  65072. --- linux-3.14.15/drivers/media/platform/mxc/capture/adv7180.c 1970-01-01 01:00:00.000000000 +0100
  65073. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/adv7180.c 2014-08-20 19:23:52.814842662 +0200
  65074. @@ -0,0 +1,1344 @@
  65075. +/*
  65076. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  65077. + */
  65078. +
  65079. +/*
  65080. + * The code contained herein is licensed under the GNU General Public
  65081. + * License. You may obtain a copy of the GNU General Public License
  65082. + * Version 2 or later at the following locations:
  65083. + *
  65084. + * http://www.opensource.org/licenses/gpl-license.html
  65085. + * http://www.gnu.org/copyleft/gpl.html
  65086. + */
  65087. +
  65088. +/*!
  65089. + * @file adv7180.c
  65090. + *
  65091. + * @brief Analog Device ADV7180 video decoder functions
  65092. + *
  65093. + * @ingroup Camera
  65094. + */
  65095. +
  65096. +#include <linux/clk.h>
  65097. +#include <linux/delay.h>
  65098. +#include <linux/device.h>
  65099. +#include <linux/i2c.h>
  65100. +#include <linux/init.h>
  65101. +#include <linux/module.h>
  65102. +#include <linux/of_device.h>
  65103. +#include <linux/of_gpio.h>
  65104. +#include <linux/pinctrl/consumer.h>
  65105. +#include <linux/regulator/consumer.h>
  65106. +#include <media/v4l2-chip-ident.h>
  65107. +#include <media/v4l2-int-device.h>
  65108. +#include "mxc_v4l2_capture.h"
  65109. +
  65110. +#define ADV7180_VOLTAGE_ANALOG 1800000
  65111. +#define ADV7180_VOLTAGE_DIGITAL_CORE 1800000
  65112. +#define ADV7180_VOLTAGE_DIGITAL_IO 3300000
  65113. +#define ADV7180_VOLTAGE_PLL 1800000
  65114. +
  65115. +static struct regulator *dvddio_regulator;
  65116. +static struct regulator *dvdd_regulator;
  65117. +static struct regulator *avdd_regulator;
  65118. +static struct regulator *pvdd_regulator;
  65119. +static int pwn_gpio;
  65120. +
  65121. +static int adv7180_probe(struct i2c_client *adapter,
  65122. + const struct i2c_device_id *id);
  65123. +static int adv7180_detach(struct i2c_client *client);
  65124. +
  65125. +static const struct i2c_device_id adv7180_id[] = {
  65126. + {"adv7180", 0},
  65127. + {},
  65128. +};
  65129. +
  65130. +MODULE_DEVICE_TABLE(i2c, adv7180_id);
  65131. +
  65132. +static struct i2c_driver adv7180_i2c_driver = {
  65133. + .driver = {
  65134. + .owner = THIS_MODULE,
  65135. + .name = "adv7180",
  65136. + },
  65137. + .probe = adv7180_probe,
  65138. + .remove = adv7180_detach,
  65139. + .id_table = adv7180_id,
  65140. +};
  65141. +
  65142. +/*!
  65143. + * Maintains the information on the current state of the sensor.
  65144. + */
  65145. +struct sensor {
  65146. + struct sensor_data sen;
  65147. + v4l2_std_id std_id;
  65148. +} adv7180_data;
  65149. +
  65150. +
  65151. +/*! List of input video formats supported. The video formats is corresponding
  65152. + * with v4l2 id in video_fmt_t
  65153. + */
  65154. +typedef enum {
  65155. + ADV7180_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
  65156. + ADV7180_PAL, /*!< (B, G, H, I, N)PAL video signal. */
  65157. + ADV7180_NOT_LOCKED, /*!< Not locked on a signal. */
  65158. +} video_fmt_idx;
  65159. +
  65160. +/*! Number of video standards supported (including 'not locked' signal). */
  65161. +#define ADV7180_STD_MAX (ADV7180_PAL + 1)
  65162. +
  65163. +/*! Video format structure. */
  65164. +typedef struct {
  65165. + int v4l2_id; /*!< Video for linux ID. */
  65166. + char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
  65167. + u16 raw_width; /*!< Raw width. */
  65168. + u16 raw_height; /*!< Raw height. */
  65169. + u16 active_width; /*!< Active width. */
  65170. + u16 active_height; /*!< Active height. */
  65171. +} video_fmt_t;
  65172. +
  65173. +/*! Description of video formats supported.
  65174. + *
  65175. + * PAL: raw=720x625, active=720x576.
  65176. + * NTSC: raw=720x525, active=720x480.
  65177. + */
  65178. +static video_fmt_t video_fmts[] = {
  65179. + { /*! NTSC */
  65180. + .v4l2_id = V4L2_STD_NTSC,
  65181. + .name = "NTSC",
  65182. + .raw_width = 720, /* SENS_FRM_WIDTH */
  65183. + .raw_height = 525, /* SENS_FRM_HEIGHT */
  65184. + .active_width = 720, /* ACT_FRM_WIDTH plus 1 */
  65185. + .active_height = 480, /* ACT_FRM_WIDTH plus 1 */
  65186. + },
  65187. + { /*! (B, G, H, I, N) PAL */
  65188. + .v4l2_id = V4L2_STD_PAL,
  65189. + .name = "PAL",
  65190. + .raw_width = 720,
  65191. + .raw_height = 625,
  65192. + .active_width = 720,
  65193. + .active_height = 576,
  65194. + },
  65195. + { /*! Unlocked standard */
  65196. + .v4l2_id = V4L2_STD_ALL,
  65197. + .name = "Autodetect",
  65198. + .raw_width = 720,
  65199. + .raw_height = 625,
  65200. + .active_width = 720,
  65201. + .active_height = 576,
  65202. + },
  65203. +};
  65204. +
  65205. +/*!* Standard index of ADV7180. */
  65206. +static video_fmt_idx video_idx = ADV7180_PAL;
  65207. +
  65208. +/*! @brief This mutex is used to provide mutual exclusion.
  65209. + *
  65210. + * Create a mutex that can be used to provide mutually exclusive
  65211. + * read/write access to the globally accessible data structures
  65212. + * and variables that were defined above.
  65213. + */
  65214. +static DEFINE_MUTEX(mutex);
  65215. +
  65216. +#define IF_NAME "adv7180"
  65217. +#define ADV7180_INPUT_CTL 0x00 /* Input Control */
  65218. +#define ADV7180_STATUS_1 0x10 /* Status #1 */
  65219. +#define ADV7180_BRIGHTNESS 0x0a /* Brightness */
  65220. +#define ADV7180_IDENT 0x11 /* IDENT */
  65221. +#define ADV7180_VSYNC_FIELD_CTL_1 0x31 /* VSYNC Field Control #1 */
  65222. +#define ADV7180_MANUAL_WIN_CTL 0x3d /* Manual Window Control */
  65223. +#define ADV7180_SD_SATURATION_CB 0xe3 /* SD Saturation Cb */
  65224. +#define ADV7180_SD_SATURATION_CR 0xe4 /* SD Saturation Cr */
  65225. +#define ADV7180_PWR_MNG 0x0f /* Power Management */
  65226. +
  65227. +/* supported controls */
  65228. +/* This hasn't been fully implemented yet.
  65229. + * This is how it should work, though. */
  65230. +static struct v4l2_queryctrl adv7180_qctrl[] = {
  65231. + {
  65232. + .id = V4L2_CID_BRIGHTNESS,
  65233. + .type = V4L2_CTRL_TYPE_INTEGER,
  65234. + .name = "Brightness",
  65235. + .minimum = 0, /* check this value */
  65236. + .maximum = 255, /* check this value */
  65237. + .step = 1, /* check this value */
  65238. + .default_value = 127, /* check this value */
  65239. + .flags = 0,
  65240. + }, {
  65241. + .id = V4L2_CID_SATURATION,
  65242. + .type = V4L2_CTRL_TYPE_INTEGER,
  65243. + .name = "Saturation",
  65244. + .minimum = 0, /* check this value */
  65245. + .maximum = 255, /* check this value */
  65246. + .step = 0x1, /* check this value */
  65247. + .default_value = 127, /* check this value */
  65248. + .flags = 0,
  65249. + }
  65250. +};
  65251. +
  65252. +static inline void adv7180_power_down(int enable)
  65253. +{
  65254. + gpio_set_value_cansleep(pwn_gpio, !enable);
  65255. + msleep(2);
  65256. +}
  65257. +
  65258. +static int adv7180_regulator_enable(struct device *dev)
  65259. +{
  65260. + int ret = 0;
  65261. +
  65262. + dvddio_regulator = devm_regulator_get(dev, "DOVDD");
  65263. +
  65264. + if (!IS_ERR(dvddio_regulator)) {
  65265. + regulator_set_voltage(dvddio_regulator,
  65266. + ADV7180_VOLTAGE_DIGITAL_IO,
  65267. + ADV7180_VOLTAGE_DIGITAL_IO);
  65268. + ret = regulator_enable(dvddio_regulator);
  65269. + if (ret) {
  65270. + dev_err(dev, "set io voltage failed\n");
  65271. + return ret;
  65272. + } else {
  65273. + dev_dbg(dev, "set io voltage ok\n");
  65274. + }
  65275. + } else {
  65276. + dev_warn(dev, "cannot get io voltage\n");
  65277. + }
  65278. +
  65279. + dvdd_regulator = devm_regulator_get(dev, "DVDD");
  65280. + if (!IS_ERR(dvdd_regulator)) {
  65281. + regulator_set_voltage(dvdd_regulator,
  65282. + ADV7180_VOLTAGE_DIGITAL_CORE,
  65283. + ADV7180_VOLTAGE_DIGITAL_CORE);
  65284. + ret = regulator_enable(dvdd_regulator);
  65285. + if (ret) {
  65286. + dev_err(dev, "set core voltage failed\n");
  65287. + return ret;
  65288. + } else {
  65289. + dev_dbg(dev, "set core voltage ok\n");
  65290. + }
  65291. + } else {
  65292. + dev_warn(dev, "cannot get core voltage\n");
  65293. + }
  65294. +
  65295. + avdd_regulator = devm_regulator_get(dev, "AVDD");
  65296. + if (!IS_ERR(avdd_regulator)) {
  65297. + regulator_set_voltage(avdd_regulator,
  65298. + ADV7180_VOLTAGE_ANALOG,
  65299. + ADV7180_VOLTAGE_ANALOG);
  65300. + ret = regulator_enable(avdd_regulator);
  65301. + if (ret) {
  65302. + dev_err(dev, "set analog voltage failed\n");
  65303. + return ret;
  65304. + } else {
  65305. + dev_dbg(dev, "set analog voltage ok\n");
  65306. + }
  65307. + } else {
  65308. + dev_warn(dev, "cannot get analog voltage\n");
  65309. + }
  65310. +
  65311. + pvdd_regulator = devm_regulator_get(dev, "PVDD");
  65312. + if (!IS_ERR(pvdd_regulator)) {
  65313. + regulator_set_voltage(pvdd_regulator,
  65314. + ADV7180_VOLTAGE_PLL,
  65315. + ADV7180_VOLTAGE_PLL);
  65316. + ret = regulator_enable(pvdd_regulator);
  65317. + if (ret) {
  65318. + dev_err(dev, "set pll voltage failed\n");
  65319. + return ret;
  65320. + } else {
  65321. + dev_dbg(dev, "set pll voltage ok\n");
  65322. + }
  65323. + } else {
  65324. + dev_warn(dev, "cannot get pll voltage\n");
  65325. + }
  65326. +
  65327. + return ret;
  65328. +}
  65329. +
  65330. +
  65331. +/***********************************************************************
  65332. + * I2C transfert.
  65333. + ***********************************************************************/
  65334. +
  65335. +/*! Read one register from a ADV7180 i2c slave device.
  65336. + *
  65337. + * @param *reg register in the device we wish to access.
  65338. + *
  65339. + * @return 0 if success, an error code otherwise.
  65340. + */
  65341. +static inline int adv7180_read(u8 reg)
  65342. +{
  65343. + int val;
  65344. +
  65345. + val = i2c_smbus_read_byte_data(adv7180_data.sen.i2c_client, reg);
  65346. + if (val < 0) {
  65347. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65348. + "%s:read reg error: reg=%2x\n", __func__, reg);
  65349. + return -1;
  65350. + }
  65351. + return val;
  65352. +}
  65353. +
  65354. +/*! Write one register of a ADV7180 i2c slave device.
  65355. + *
  65356. + * @param *reg register in the device we wish to access.
  65357. + *
  65358. + * @return 0 if success, an error code otherwise.
  65359. + */
  65360. +static int adv7180_write_reg(u8 reg, u8 val)
  65361. +{
  65362. + s32 ret;
  65363. +
  65364. + ret = i2c_smbus_write_byte_data(adv7180_data.sen.i2c_client, reg, val);
  65365. + if (ret < 0) {
  65366. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65367. + "%s:write reg error:reg=%2x,val=%2x\n", __func__,
  65368. + reg, val);
  65369. + return -1;
  65370. + }
  65371. + return 0;
  65372. +}
  65373. +
  65374. +/***********************************************************************
  65375. + * mxc_v4l2_capture interface.
  65376. + ***********************************************************************/
  65377. +
  65378. +/*!
  65379. + * Return attributes of current video standard.
  65380. + * Since this device autodetects the current standard, this function also
  65381. + * sets the values that need to be changed if the standard changes.
  65382. + * There is no set std equivalent function.
  65383. + *
  65384. + * @return None.
  65385. + */
  65386. +static void adv7180_get_std(v4l2_std_id *std)
  65387. +{
  65388. + int tmp;
  65389. + int idx;
  65390. +
  65391. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_get_std\n");
  65392. +
  65393. + /* Read the AD_RESULT to get the detect output video standard */
  65394. + tmp = adv7180_read(ADV7180_STATUS_1) & 0x70;
  65395. +
  65396. + mutex_lock(&mutex);
  65397. + if (tmp == 0x40) {
  65398. + /* PAL */
  65399. + *std = V4L2_STD_PAL;
  65400. + idx = ADV7180_PAL;
  65401. + } else if (tmp == 0) {
  65402. + /*NTSC*/
  65403. + *std = V4L2_STD_NTSC;
  65404. + idx = ADV7180_NTSC;
  65405. + } else {
  65406. + *std = V4L2_STD_ALL;
  65407. + idx = ADV7180_NOT_LOCKED;
  65408. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65409. + "Got invalid video standard!\n");
  65410. + }
  65411. + mutex_unlock(&mutex);
  65412. +
  65413. + /* This assumes autodetect which this device uses. */
  65414. + if (*std != adv7180_data.std_id) {
  65415. + video_idx = idx;
  65416. + adv7180_data.std_id = *std;
  65417. + adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
  65418. + adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
  65419. + }
  65420. +}
  65421. +
  65422. +/***********************************************************************
  65423. + * IOCTL Functions from v4l2_int_ioctl_desc.
  65424. + ***********************************************************************/
  65425. +
  65426. +/*!
  65427. + * ioctl_g_ifparm - V4L2 sensor interface handler for vidioc_int_g_ifparm_num
  65428. + * s: pointer to standard V4L2 device structure
  65429. + * p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure
  65430. + *
  65431. + * Gets slave interface parameters.
  65432. + * Calculates the required xclk value to support the requested
  65433. + * clock parameters in p. This value is returned in the p
  65434. + * parameter.
  65435. + *
  65436. + * vidioc_int_g_ifparm returns platform-specific information about the
  65437. + * interface settings used by the sensor.
  65438. + *
  65439. + * Called on open.
  65440. + */
  65441. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  65442. +{
  65443. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_ifparm\n");
  65444. +
  65445. + if (s == NULL) {
  65446. + pr_err(" ERROR!! no slave device set!\n");
  65447. + return -1;
  65448. + }
  65449. +
  65450. + /* Initialize structure to 0s then set any non-0 values. */
  65451. + memset(p, 0, sizeof(*p));
  65452. + p->if_type = V4L2_IF_TYPE_BT656; /* This is the only possibility. */
  65453. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  65454. + p->u.bt656.nobt_hs_inv = 1;
  65455. + p->u.bt656.bt_sync_correct = 1;
  65456. +
  65457. + /* ADV7180 has a dedicated clock so no clock settings needed. */
  65458. +
  65459. + return 0;
  65460. +}
  65461. +
  65462. +/*!
  65463. + * Sets the camera power.
  65464. + *
  65465. + * s pointer to the camera device
  65466. + * on if 1, power is to be turned on. 0 means power is to be turned off
  65467. + *
  65468. + * ioctl_s_power - V4L2 sensor interface handler for vidioc_int_s_power_num
  65469. + * @s: pointer to standard V4L2 device structure
  65470. + * @on: power state to which device is to be set
  65471. + *
  65472. + * Sets devices power state to requrested state, if possible.
  65473. + * This is called on open, close, suspend and resume.
  65474. + */
  65475. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  65476. +{
  65477. + struct sensor *sensor = s->priv;
  65478. +
  65479. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_s_power\n");
  65480. +
  65481. + if (on && !sensor->sen.on) {
  65482. + if (adv7180_write_reg(ADV7180_PWR_MNG, 0x04) != 0)
  65483. + return -EIO;
  65484. +
  65485. + /*
  65486. + * FIXME:Additional 400ms to wait the chip to be stable?
  65487. + * This is a workaround for preview scrolling issue.
  65488. + */
  65489. + msleep(400);
  65490. + } else if (!on && sensor->sen.on) {
  65491. + if (adv7180_write_reg(ADV7180_PWR_MNG, 0x24) != 0)
  65492. + return -EIO;
  65493. + }
  65494. +
  65495. + sensor->sen.on = on;
  65496. +
  65497. + return 0;
  65498. +}
  65499. +
  65500. +/*!
  65501. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  65502. + * @s: pointer to standard V4L2 device structure
  65503. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  65504. + *
  65505. + * Returns the sensor's video CAPTURE parameters.
  65506. + */
  65507. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  65508. +{
  65509. + struct sensor *sensor = s->priv;
  65510. + struct v4l2_captureparm *cparm = &a->parm.capture;
  65511. +
  65512. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_parm\n");
  65513. +
  65514. + switch (a->type) {
  65515. + /* These are all the possible cases. */
  65516. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  65517. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  65518. + memset(a, 0, sizeof(*a));
  65519. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  65520. + cparm->capability = sensor->sen.streamcap.capability;
  65521. + cparm->timeperframe = sensor->sen.streamcap.timeperframe;
  65522. + cparm->capturemode = sensor->sen.streamcap.capturemode;
  65523. + break;
  65524. +
  65525. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  65526. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  65527. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  65528. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  65529. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  65530. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  65531. + break;
  65532. +
  65533. + default:
  65534. + pr_debug("ioctl_g_parm:type is unknown %d\n", a->type);
  65535. + break;
  65536. + }
  65537. +
  65538. + return 0;
  65539. +}
  65540. +
  65541. +/*!
  65542. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  65543. + * @s: pointer to standard V4L2 device structure
  65544. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  65545. + *
  65546. + * Configures the sensor to use the input parameters, if possible. If
  65547. + * not possible, reverts to the old parameters and returns the
  65548. + * appropriate error code.
  65549. + *
  65550. + * This driver cannot change these settings.
  65551. + */
  65552. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  65553. +{
  65554. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_parm\n");
  65555. +
  65556. + switch (a->type) {
  65557. + /* These are all the possible cases. */
  65558. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  65559. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  65560. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  65561. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  65562. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  65563. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  65564. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  65565. + break;
  65566. +
  65567. + default:
  65568. + pr_debug(" type is unknown - %d\n", a->type);
  65569. + break;
  65570. + }
  65571. +
  65572. + return 0;
  65573. +}
  65574. +
  65575. +/*!
  65576. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  65577. + * @s: pointer to standard V4L2 device structure
  65578. + * @f: pointer to standard V4L2 v4l2_format structure
  65579. + *
  65580. + * Returns the sensor's current pixel format in the v4l2_format
  65581. + * parameter.
  65582. + */
  65583. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  65584. +{
  65585. + struct sensor *sensor = s->priv;
  65586. +
  65587. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_fmt_cap\n");
  65588. +
  65589. + switch (f->type) {
  65590. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  65591. + pr_debug(" Returning size of %dx%d\n",
  65592. + sensor->sen.pix.width, sensor->sen.pix.height);
  65593. + f->fmt.pix = sensor->sen.pix;
  65594. + break;
  65595. +
  65596. + case V4L2_BUF_TYPE_PRIVATE: {
  65597. + v4l2_std_id std;
  65598. + adv7180_get_std(&std);
  65599. + f->fmt.pix.pixelformat = (u32)std;
  65600. + }
  65601. + break;
  65602. +
  65603. + default:
  65604. + f->fmt.pix = sensor->sen.pix;
  65605. + break;
  65606. + }
  65607. +
  65608. + return 0;
  65609. +}
  65610. +
  65611. +/*!
  65612. + * ioctl_queryctrl - V4L2 sensor interface handler for VIDIOC_QUERYCTRL ioctl
  65613. + * @s: pointer to standard V4L2 device structure
  65614. + * @qc: standard V4L2 VIDIOC_QUERYCTRL ioctl structure
  65615. + *
  65616. + * If the requested control is supported, returns the control information
  65617. + * from the video_control[] array. Otherwise, returns -EINVAL if the
  65618. + * control is not supported.
  65619. + */
  65620. +static int ioctl_queryctrl(struct v4l2_int_device *s,
  65621. + struct v4l2_queryctrl *qc)
  65622. +{
  65623. + int i;
  65624. +
  65625. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_queryctrl\n");
  65626. +
  65627. + for (i = 0; i < ARRAY_SIZE(adv7180_qctrl); i++)
  65628. + if (qc->id && qc->id == adv7180_qctrl[i].id) {
  65629. + memcpy(qc, &(adv7180_qctrl[i]),
  65630. + sizeof(*qc));
  65631. + return 0;
  65632. + }
  65633. +
  65634. + return -EINVAL;
  65635. +}
  65636. +
  65637. +/*!
  65638. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  65639. + * @s: pointer to standard V4L2 device structure
  65640. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  65641. + *
  65642. + * If the requested control is supported, returns the control's current
  65643. + * value from the video_control[] array. Otherwise, returns -EINVAL
  65644. + * if the control is not supported.
  65645. + */
  65646. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  65647. +{
  65648. + int ret = 0;
  65649. + int sat = 0;
  65650. +
  65651. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_ctrl\n");
  65652. +
  65653. + switch (vc->id) {
  65654. + case V4L2_CID_BRIGHTNESS:
  65655. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65656. + " V4L2_CID_BRIGHTNESS\n");
  65657. + adv7180_data.sen.brightness = adv7180_read(ADV7180_BRIGHTNESS);
  65658. + vc->value = adv7180_data.sen.brightness;
  65659. + break;
  65660. + case V4L2_CID_CONTRAST:
  65661. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65662. + " V4L2_CID_CONTRAST\n");
  65663. + vc->value = adv7180_data.sen.contrast;
  65664. + break;
  65665. + case V4L2_CID_SATURATION:
  65666. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65667. + " V4L2_CID_SATURATION\n");
  65668. + sat = adv7180_read(ADV7180_SD_SATURATION_CB);
  65669. + adv7180_data.sen.saturation = sat;
  65670. + vc->value = adv7180_data.sen.saturation;
  65671. + break;
  65672. + case V4L2_CID_HUE:
  65673. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65674. + " V4L2_CID_HUE\n");
  65675. + vc->value = adv7180_data.sen.hue;
  65676. + break;
  65677. + case V4L2_CID_AUTO_WHITE_BALANCE:
  65678. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65679. + " V4L2_CID_AUTO_WHITE_BALANCE\n");
  65680. + break;
  65681. + case V4L2_CID_DO_WHITE_BALANCE:
  65682. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65683. + " V4L2_CID_DO_WHITE_BALANCE\n");
  65684. + break;
  65685. + case V4L2_CID_RED_BALANCE:
  65686. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65687. + " V4L2_CID_RED_BALANCE\n");
  65688. + vc->value = adv7180_data.sen.red;
  65689. + break;
  65690. + case V4L2_CID_BLUE_BALANCE:
  65691. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65692. + " V4L2_CID_BLUE_BALANCE\n");
  65693. + vc->value = adv7180_data.sen.blue;
  65694. + break;
  65695. + case V4L2_CID_GAMMA:
  65696. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65697. + " V4L2_CID_GAMMA\n");
  65698. + break;
  65699. + case V4L2_CID_EXPOSURE:
  65700. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65701. + " V4L2_CID_EXPOSURE\n");
  65702. + vc->value = adv7180_data.sen.ae_mode;
  65703. + break;
  65704. + case V4L2_CID_AUTOGAIN:
  65705. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65706. + " V4L2_CID_AUTOGAIN\n");
  65707. + break;
  65708. + case V4L2_CID_GAIN:
  65709. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65710. + " V4L2_CID_GAIN\n");
  65711. + break;
  65712. + case V4L2_CID_HFLIP:
  65713. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65714. + " V4L2_CID_HFLIP\n");
  65715. + break;
  65716. + case V4L2_CID_VFLIP:
  65717. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65718. + " V4L2_CID_VFLIP\n");
  65719. + break;
  65720. + default:
  65721. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65722. + " Default case\n");
  65723. + vc->value = 0;
  65724. + ret = -EPERM;
  65725. + break;
  65726. + }
  65727. +
  65728. + return ret;
  65729. +}
  65730. +
  65731. +/*!
  65732. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  65733. + * @s: pointer to standard V4L2 device structure
  65734. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  65735. + *
  65736. + * If the requested control is supported, sets the control's current
  65737. + * value in HW (and updates the video_control[] array). Otherwise,
  65738. + * returns -EINVAL if the control is not supported.
  65739. + */
  65740. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  65741. +{
  65742. + int retval = 0;
  65743. + u8 tmp;
  65744. +
  65745. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_ctrl\n");
  65746. +
  65747. + switch (vc->id) {
  65748. + case V4L2_CID_BRIGHTNESS:
  65749. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65750. + " V4L2_CID_BRIGHTNESS\n");
  65751. + tmp = vc->value;
  65752. + adv7180_write_reg(ADV7180_BRIGHTNESS, tmp);
  65753. + adv7180_data.sen.brightness = vc->value;
  65754. + break;
  65755. + case V4L2_CID_CONTRAST:
  65756. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65757. + " V4L2_CID_CONTRAST\n");
  65758. + break;
  65759. + case V4L2_CID_SATURATION:
  65760. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65761. + " V4L2_CID_SATURATION\n");
  65762. + tmp = vc->value;
  65763. + adv7180_write_reg(ADV7180_SD_SATURATION_CB, tmp);
  65764. + adv7180_write_reg(ADV7180_SD_SATURATION_CR, tmp);
  65765. + adv7180_data.sen.saturation = vc->value;
  65766. + break;
  65767. + case V4L2_CID_HUE:
  65768. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65769. + " V4L2_CID_HUE\n");
  65770. + break;
  65771. + case V4L2_CID_AUTO_WHITE_BALANCE:
  65772. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65773. + " V4L2_CID_AUTO_WHITE_BALANCE\n");
  65774. + break;
  65775. + case V4L2_CID_DO_WHITE_BALANCE:
  65776. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65777. + " V4L2_CID_DO_WHITE_BALANCE\n");
  65778. + break;
  65779. + case V4L2_CID_RED_BALANCE:
  65780. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65781. + " V4L2_CID_RED_BALANCE\n");
  65782. + break;
  65783. + case V4L2_CID_BLUE_BALANCE:
  65784. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65785. + " V4L2_CID_BLUE_BALANCE\n");
  65786. + break;
  65787. + case V4L2_CID_GAMMA:
  65788. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65789. + " V4L2_CID_GAMMA\n");
  65790. + break;
  65791. + case V4L2_CID_EXPOSURE:
  65792. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65793. + " V4L2_CID_EXPOSURE\n");
  65794. + break;
  65795. + case V4L2_CID_AUTOGAIN:
  65796. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65797. + " V4L2_CID_AUTOGAIN\n");
  65798. + break;
  65799. + case V4L2_CID_GAIN:
  65800. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65801. + " V4L2_CID_GAIN\n");
  65802. + break;
  65803. + case V4L2_CID_HFLIP:
  65804. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65805. + " V4L2_CID_HFLIP\n");
  65806. + break;
  65807. + case V4L2_CID_VFLIP:
  65808. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65809. + " V4L2_CID_VFLIP\n");
  65810. + break;
  65811. + default:
  65812. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65813. + " Default case\n");
  65814. + retval = -EPERM;
  65815. + break;
  65816. + }
  65817. +
  65818. + return retval;
  65819. +}
  65820. +
  65821. +/*!
  65822. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  65823. + * VIDIOC_ENUM_FRAMESIZES ioctl
  65824. + * @s: pointer to standard V4L2 device structure
  65825. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  65826. + *
  65827. + * Return 0 if successful, otherwise -EINVAL.
  65828. + */
  65829. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  65830. + struct v4l2_frmsizeenum *fsize)
  65831. +{
  65832. + if (fsize->index >= 1)
  65833. + return -EINVAL;
  65834. +
  65835. + fsize->discrete.width = video_fmts[video_idx].active_width;
  65836. + fsize->discrete.height = video_fmts[video_idx].active_height;
  65837. +
  65838. + return 0;
  65839. +}
  65840. +
  65841. +/*!
  65842. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  65843. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  65844. + * @s: pointer to standard V4L2 device structure
  65845. + * @id: pointer to int
  65846. + *
  65847. + * Return 0.
  65848. + */
  65849. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  65850. +{
  65851. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  65852. + V4L2_CHIP_MATCH_I2C_DRIVER;
  65853. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
  65854. + "adv7180_decoder");
  65855. + ((struct v4l2_dbg_chip_ident *)id)->ident = V4L2_IDENT_ADV7180;
  65856. +
  65857. + return 0;
  65858. +}
  65859. +
  65860. +/*!
  65861. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  65862. + * @s: pointer to standard V4L2 device structure
  65863. + */
  65864. +static int ioctl_init(struct v4l2_int_device *s)
  65865. +{
  65866. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_init\n");
  65867. + return 0;
  65868. +}
  65869. +
  65870. +/*!
  65871. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  65872. + * @s: pointer to standard V4L2 device structure
  65873. + *
  65874. + * Initialise the device when slave attaches to the master.
  65875. + */
  65876. +static int ioctl_dev_init(struct v4l2_int_device *s)
  65877. +{
  65878. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_dev_init\n");
  65879. + return 0;
  65880. +}
  65881. +
  65882. +/*!
  65883. + * This structure defines all the ioctls for this module.
  65884. + */
  65885. +static struct v4l2_int_ioctl_desc adv7180_ioctl_desc[] = {
  65886. +
  65887. + {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*)ioctl_dev_init},
  65888. +
  65889. + /*!
  65890. + * Delinitialise the dev. at slave detach.
  65891. + * The complement of ioctl_dev_init.
  65892. + */
  65893. +/* {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func *)ioctl_dev_exit}, */
  65894. +
  65895. + {vidioc_int_s_power_num, (v4l2_int_ioctl_func*)ioctl_s_power},
  65896. + {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*)ioctl_g_ifparm},
  65897. +/* {vidioc_int_g_needs_reset_num,
  65898. + (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
  65899. +/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
  65900. + {vidioc_int_init_num, (v4l2_int_ioctl_func*)ioctl_init},
  65901. +
  65902. + /*!
  65903. + * VIDIOC_ENUM_FMT ioctl for the CAPTURE buffer type.
  65904. + */
  65905. +/* {vidioc_int_enum_fmt_cap_num,
  65906. + (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap}, */
  65907. +
  65908. + /*!
  65909. + * VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type.
  65910. + * This ioctl is used to negotiate the image capture size and
  65911. + * pixel format without actually making it take effect.
  65912. + */
  65913. +/* {vidioc_int_try_fmt_cap_num,
  65914. + (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
  65915. +
  65916. + {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func*)ioctl_g_fmt_cap},
  65917. +
  65918. + /*!
  65919. + * If the requested format is supported, configures the HW to use that
  65920. + * format, returns error code if format not supported or HW can't be
  65921. + * correctly configured.
  65922. + */
  65923. +/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *)ioctl_s_fmt_cap}, */
  65924. +
  65925. + {vidioc_int_g_parm_num, (v4l2_int_ioctl_func*)ioctl_g_parm},
  65926. + {vidioc_int_s_parm_num, (v4l2_int_ioctl_func*)ioctl_s_parm},
  65927. + {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func*)ioctl_queryctrl},
  65928. + {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func*)ioctl_g_ctrl},
  65929. + {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func*)ioctl_s_ctrl},
  65930. + {vidioc_int_enum_framesizes_num,
  65931. + (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
  65932. + {vidioc_int_g_chip_ident_num,
  65933. + (v4l2_int_ioctl_func *)ioctl_g_chip_ident},
  65934. +};
  65935. +
  65936. +static struct v4l2_int_slave adv7180_slave = {
  65937. + .ioctls = adv7180_ioctl_desc,
  65938. + .num_ioctls = ARRAY_SIZE(adv7180_ioctl_desc),
  65939. +};
  65940. +
  65941. +static struct v4l2_int_device adv7180_int_device = {
  65942. + .module = THIS_MODULE,
  65943. + .name = "adv7180",
  65944. + .type = v4l2_int_type_slave,
  65945. + .u = {
  65946. + .slave = &adv7180_slave,
  65947. + },
  65948. +};
  65949. +
  65950. +
  65951. +/***********************************************************************
  65952. + * I2C client and driver.
  65953. + ***********************************************************************/
  65954. +
  65955. +/*! ADV7180 Reset function.
  65956. + *
  65957. + * @return None.
  65958. + */
  65959. +static void adv7180_hard_reset(bool cvbs)
  65960. +{
  65961. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65962. + "In adv7180:adv7180_hard_reset\n");
  65963. +
  65964. + if (cvbs) {
  65965. + /* Set CVBS input on AIN1 */
  65966. + adv7180_write_reg(ADV7180_INPUT_CTL, 0x00);
  65967. + } else {
  65968. + /*
  65969. + * Set YPbPr input on AIN1,4,5 and normal
  65970. + * operations(autodection of all stds).
  65971. + */
  65972. + adv7180_write_reg(ADV7180_INPUT_CTL, 0x09);
  65973. + }
  65974. +
  65975. + /* Datasheet recommends */
  65976. + adv7180_write_reg(0x01, 0xc8);
  65977. + adv7180_write_reg(0x02, 0x04);
  65978. + adv7180_write_reg(0x03, 0x00);
  65979. + adv7180_write_reg(0x04, 0x45);
  65980. + adv7180_write_reg(0x05, 0x00);
  65981. + adv7180_write_reg(0x06, 0x02);
  65982. + adv7180_write_reg(0x07, 0x7F);
  65983. + adv7180_write_reg(0x08, 0x80);
  65984. + adv7180_write_reg(0x0A, 0x00);
  65985. + adv7180_write_reg(0x0B, 0x00);
  65986. + adv7180_write_reg(0x0C, 0x36);
  65987. + adv7180_write_reg(0x0D, 0x7C);
  65988. + adv7180_write_reg(0x0E, 0x00);
  65989. + adv7180_write_reg(0x0F, 0x00);
  65990. + adv7180_write_reg(0x13, 0x00);
  65991. + adv7180_write_reg(0x14, 0x12);
  65992. + adv7180_write_reg(0x15, 0x00);
  65993. + adv7180_write_reg(0x16, 0x00);
  65994. + adv7180_write_reg(0x17, 0x01);
  65995. + adv7180_write_reg(0x18, 0x93);
  65996. + adv7180_write_reg(0xF1, 0x19);
  65997. + adv7180_write_reg(0x1A, 0x00);
  65998. + adv7180_write_reg(0x1B, 0x00);
  65999. + adv7180_write_reg(0x1C, 0x00);
  66000. + adv7180_write_reg(0x1D, 0x40);
  66001. + adv7180_write_reg(0x1E, 0x00);
  66002. + adv7180_write_reg(0x1F, 0x00);
  66003. + adv7180_write_reg(0x20, 0x00);
  66004. + adv7180_write_reg(0x21, 0x00);
  66005. + adv7180_write_reg(0x22, 0x00);
  66006. + adv7180_write_reg(0x23, 0xC0);
  66007. + adv7180_write_reg(0x24, 0x00);
  66008. + adv7180_write_reg(0x25, 0x00);
  66009. + adv7180_write_reg(0x26, 0x00);
  66010. + adv7180_write_reg(0x27, 0x58);
  66011. + adv7180_write_reg(0x28, 0x00);
  66012. + adv7180_write_reg(0x29, 0x00);
  66013. + adv7180_write_reg(0x2A, 0x00);
  66014. + adv7180_write_reg(0x2B, 0xE1);
  66015. + adv7180_write_reg(0x2C, 0xAE);
  66016. + adv7180_write_reg(0x2D, 0xF4);
  66017. + adv7180_write_reg(0x2E, 0x00);
  66018. + adv7180_write_reg(0x2F, 0xF0);
  66019. + adv7180_write_reg(0x30, 0x00);
  66020. + adv7180_write_reg(0x31, 0x12);
  66021. + adv7180_write_reg(0x32, 0x41);
  66022. + adv7180_write_reg(0x33, 0x84);
  66023. + adv7180_write_reg(0x34, 0x00);
  66024. + adv7180_write_reg(0x35, 0x02);
  66025. + adv7180_write_reg(0x36, 0x00);
  66026. + adv7180_write_reg(0x37, 0x01);
  66027. + adv7180_write_reg(0x38, 0x80);
  66028. + adv7180_write_reg(0x39, 0xC0);
  66029. + adv7180_write_reg(0x3A, 0x10);
  66030. + adv7180_write_reg(0x3B, 0x05);
  66031. + adv7180_write_reg(0x3C, 0x58);
  66032. + adv7180_write_reg(0x3D, 0xB2);
  66033. + adv7180_write_reg(0x3E, 0x64);
  66034. + adv7180_write_reg(0x3F, 0xE4);
  66035. + adv7180_write_reg(0x40, 0x90);
  66036. + adv7180_write_reg(0x41, 0x01);
  66037. + adv7180_write_reg(0x42, 0x7E);
  66038. + adv7180_write_reg(0x43, 0xA4);
  66039. + adv7180_write_reg(0x44, 0xFF);
  66040. + adv7180_write_reg(0x45, 0xB6);
  66041. + adv7180_write_reg(0x46, 0x12);
  66042. + adv7180_write_reg(0x48, 0x00);
  66043. + adv7180_write_reg(0x49, 0x00);
  66044. + adv7180_write_reg(0x4A, 0x00);
  66045. + adv7180_write_reg(0x4B, 0x00);
  66046. + adv7180_write_reg(0x4C, 0x00);
  66047. + adv7180_write_reg(0x4D, 0xEF);
  66048. + adv7180_write_reg(0x4E, 0x08);
  66049. + adv7180_write_reg(0x4F, 0x08);
  66050. + adv7180_write_reg(0x50, 0x08);
  66051. + adv7180_write_reg(0x51, 0x24);
  66052. + adv7180_write_reg(0x52, 0x0B);
  66053. + adv7180_write_reg(0x53, 0x4E);
  66054. + adv7180_write_reg(0x54, 0x80);
  66055. + adv7180_write_reg(0x55, 0x00);
  66056. + adv7180_write_reg(0x56, 0x10);
  66057. + adv7180_write_reg(0x57, 0x00);
  66058. + adv7180_write_reg(0x58, 0x00);
  66059. + adv7180_write_reg(0x59, 0x00);
  66060. + adv7180_write_reg(0x5A, 0x00);
  66061. + adv7180_write_reg(0x5B, 0x00);
  66062. + adv7180_write_reg(0x5C, 0x00);
  66063. + adv7180_write_reg(0x5D, 0x00);
  66064. + adv7180_write_reg(0x5E, 0x00);
  66065. + adv7180_write_reg(0x5F, 0x00);
  66066. + adv7180_write_reg(0x60, 0x00);
  66067. + adv7180_write_reg(0x61, 0x00);
  66068. + adv7180_write_reg(0x62, 0x20);
  66069. + adv7180_write_reg(0x63, 0x00);
  66070. + adv7180_write_reg(0x64, 0x00);
  66071. + adv7180_write_reg(0x65, 0x00);
  66072. + adv7180_write_reg(0x66, 0x00);
  66073. + adv7180_write_reg(0x67, 0x03);
  66074. + adv7180_write_reg(0x68, 0x01);
  66075. + adv7180_write_reg(0x69, 0x00);
  66076. + adv7180_write_reg(0x6A, 0x00);
  66077. + adv7180_write_reg(0x6B, 0xC0);
  66078. + adv7180_write_reg(0x6C, 0x00);
  66079. + adv7180_write_reg(0x6D, 0x00);
  66080. + adv7180_write_reg(0x6E, 0x00);
  66081. + adv7180_write_reg(0x6F, 0x00);
  66082. + adv7180_write_reg(0x70, 0x00);
  66083. + adv7180_write_reg(0x71, 0x00);
  66084. + adv7180_write_reg(0x72, 0x00);
  66085. + adv7180_write_reg(0x73, 0x10);
  66086. + adv7180_write_reg(0x74, 0x04);
  66087. + adv7180_write_reg(0x75, 0x01);
  66088. + adv7180_write_reg(0x76, 0x00);
  66089. + adv7180_write_reg(0x77, 0x3F);
  66090. + adv7180_write_reg(0x78, 0xFF);
  66091. + adv7180_write_reg(0x79, 0xFF);
  66092. + adv7180_write_reg(0x7A, 0xFF);
  66093. + adv7180_write_reg(0x7B, 0x1E);
  66094. + adv7180_write_reg(0x7C, 0xC0);
  66095. + adv7180_write_reg(0x7D, 0x00);
  66096. + adv7180_write_reg(0x7E, 0x00);
  66097. + adv7180_write_reg(0x7F, 0x00);
  66098. + adv7180_write_reg(0x80, 0x00);
  66099. + adv7180_write_reg(0x81, 0xC0);
  66100. + adv7180_write_reg(0x82, 0x04);
  66101. + adv7180_write_reg(0x83, 0x00);
  66102. + adv7180_write_reg(0x84, 0x0C);
  66103. + adv7180_write_reg(0x85, 0x02);
  66104. + adv7180_write_reg(0x86, 0x03);
  66105. + adv7180_write_reg(0x87, 0x63);
  66106. + adv7180_write_reg(0x88, 0x5A);
  66107. + adv7180_write_reg(0x89, 0x08);
  66108. + adv7180_write_reg(0x8A, 0x10);
  66109. + adv7180_write_reg(0x8B, 0x00);
  66110. + adv7180_write_reg(0x8C, 0x40);
  66111. + adv7180_write_reg(0x8D, 0x00);
  66112. + adv7180_write_reg(0x8E, 0x40);
  66113. + adv7180_write_reg(0x8F, 0x00);
  66114. + adv7180_write_reg(0x90, 0x00);
  66115. + adv7180_write_reg(0x91, 0x50);
  66116. + adv7180_write_reg(0x92, 0x00);
  66117. + adv7180_write_reg(0x93, 0x00);
  66118. + adv7180_write_reg(0x94, 0x00);
  66119. + adv7180_write_reg(0x95, 0x00);
  66120. + adv7180_write_reg(0x96, 0x00);
  66121. + adv7180_write_reg(0x97, 0xF0);
  66122. + adv7180_write_reg(0x98, 0x00);
  66123. + adv7180_write_reg(0x99, 0x00);
  66124. + adv7180_write_reg(0x9A, 0x00);
  66125. + adv7180_write_reg(0x9B, 0x00);
  66126. + adv7180_write_reg(0x9C, 0x00);
  66127. + adv7180_write_reg(0x9D, 0x00);
  66128. + adv7180_write_reg(0x9E, 0x00);
  66129. + adv7180_write_reg(0x9F, 0x00);
  66130. + adv7180_write_reg(0xA0, 0x00);
  66131. + adv7180_write_reg(0xA1, 0x00);
  66132. + adv7180_write_reg(0xA2, 0x00);
  66133. + adv7180_write_reg(0xA3, 0x00);
  66134. + adv7180_write_reg(0xA4, 0x00);
  66135. + adv7180_write_reg(0xA5, 0x00);
  66136. + adv7180_write_reg(0xA6, 0x00);
  66137. + adv7180_write_reg(0xA7, 0x00);
  66138. + adv7180_write_reg(0xA8, 0x00);
  66139. + adv7180_write_reg(0xA9, 0x00);
  66140. + adv7180_write_reg(0xAA, 0x00);
  66141. + adv7180_write_reg(0xAB, 0x00);
  66142. + adv7180_write_reg(0xAC, 0x00);
  66143. + adv7180_write_reg(0xAD, 0x00);
  66144. + adv7180_write_reg(0xAE, 0x60);
  66145. + adv7180_write_reg(0xAF, 0x00);
  66146. + adv7180_write_reg(0xB0, 0x00);
  66147. + adv7180_write_reg(0xB1, 0x60);
  66148. + adv7180_write_reg(0xB2, 0x1C);
  66149. + adv7180_write_reg(0xB3, 0x54);
  66150. + adv7180_write_reg(0xB4, 0x00);
  66151. + adv7180_write_reg(0xB5, 0x00);
  66152. + adv7180_write_reg(0xB6, 0x00);
  66153. + adv7180_write_reg(0xB7, 0x13);
  66154. + adv7180_write_reg(0xB8, 0x03);
  66155. + adv7180_write_reg(0xB9, 0x33);
  66156. + adv7180_write_reg(0xBF, 0x02);
  66157. + adv7180_write_reg(0xC0, 0x00);
  66158. + adv7180_write_reg(0xC1, 0x00);
  66159. + adv7180_write_reg(0xC2, 0x00);
  66160. + adv7180_write_reg(0xC3, 0x00);
  66161. + adv7180_write_reg(0xC4, 0x00);
  66162. + adv7180_write_reg(0xC5, 0x81);
  66163. + adv7180_write_reg(0xC6, 0x00);
  66164. + adv7180_write_reg(0xC7, 0x00);
  66165. + adv7180_write_reg(0xC8, 0x00);
  66166. + adv7180_write_reg(0xC9, 0x04);
  66167. + adv7180_write_reg(0xCC, 0x69);
  66168. + adv7180_write_reg(0xCD, 0x00);
  66169. + adv7180_write_reg(0xCE, 0x01);
  66170. + adv7180_write_reg(0xCF, 0xB4);
  66171. + adv7180_write_reg(0xD0, 0x00);
  66172. + adv7180_write_reg(0xD1, 0x10);
  66173. + adv7180_write_reg(0xD2, 0xFF);
  66174. + adv7180_write_reg(0xD3, 0xFF);
  66175. + adv7180_write_reg(0xD4, 0x7F);
  66176. + adv7180_write_reg(0xD5, 0x7F);
  66177. + adv7180_write_reg(0xD6, 0x3E);
  66178. + adv7180_write_reg(0xD7, 0x08);
  66179. + adv7180_write_reg(0xD8, 0x3C);
  66180. + adv7180_write_reg(0xD9, 0x08);
  66181. + adv7180_write_reg(0xDA, 0x3C);
  66182. + adv7180_write_reg(0xDB, 0x9B);
  66183. + adv7180_write_reg(0xDC, 0xAC);
  66184. + adv7180_write_reg(0xDD, 0x4C);
  66185. + adv7180_write_reg(0xDE, 0x00);
  66186. + adv7180_write_reg(0xDF, 0x00);
  66187. + adv7180_write_reg(0xE0, 0x14);
  66188. + adv7180_write_reg(0xE1, 0x80);
  66189. + adv7180_write_reg(0xE2, 0x80);
  66190. + adv7180_write_reg(0xE3, 0x80);
  66191. + adv7180_write_reg(0xE4, 0x80);
  66192. + adv7180_write_reg(0xE5, 0x25);
  66193. + adv7180_write_reg(0xE6, 0x44);
  66194. + adv7180_write_reg(0xE7, 0x63);
  66195. + adv7180_write_reg(0xE8, 0x65);
  66196. + adv7180_write_reg(0xE9, 0x14);
  66197. + adv7180_write_reg(0xEA, 0x63);
  66198. + adv7180_write_reg(0xEB, 0x55);
  66199. + adv7180_write_reg(0xEC, 0x55);
  66200. + adv7180_write_reg(0xEE, 0x00);
  66201. + adv7180_write_reg(0xEF, 0x4A);
  66202. + adv7180_write_reg(0xF0, 0x44);
  66203. + adv7180_write_reg(0xF1, 0x0C);
  66204. + adv7180_write_reg(0xF2, 0x32);
  66205. + adv7180_write_reg(0xF3, 0x00);
  66206. + adv7180_write_reg(0xF4, 0x3F);
  66207. + adv7180_write_reg(0xF5, 0xE0);
  66208. + adv7180_write_reg(0xF6, 0x69);
  66209. + adv7180_write_reg(0xF7, 0x10);
  66210. + adv7180_write_reg(0xF8, 0x00);
  66211. + adv7180_write_reg(0xF9, 0x03);
  66212. + adv7180_write_reg(0xFA, 0xFA);
  66213. + adv7180_write_reg(0xFB, 0x40);
  66214. +}
  66215. +
  66216. +/*! ADV7180 I2C attach function.
  66217. + *
  66218. + * @param *adapter struct i2c_adapter *.
  66219. + *
  66220. + * @return Error code indicating success or failure.
  66221. + */
  66222. +
  66223. +/*!
  66224. + * ADV7180 I2C probe function.
  66225. + * Function set in i2c_driver struct.
  66226. + * Called by insmod.
  66227. + *
  66228. + * @param *adapter I2C adapter descriptor.
  66229. + *
  66230. + * @return Error code indicating success or failure.
  66231. + */
  66232. +static int adv7180_probe(struct i2c_client *client,
  66233. + const struct i2c_device_id *id)
  66234. +{
  66235. + int rev_id;
  66236. + int ret = 0;
  66237. + u32 cvbs = true;
  66238. + struct pinctrl *pinctrl;
  66239. + struct device *dev = &client->dev;
  66240. +
  66241. + printk(KERN_ERR"DBG sensor data is at %p\n", &adv7180_data);
  66242. +
  66243. + /* ov5640 pinctrl */
  66244. + pinctrl = devm_pinctrl_get_select_default(dev);
  66245. + if (IS_ERR(pinctrl)) {
  66246. + dev_err(dev, "setup pinctrl failed\n");
  66247. + return PTR_ERR(pinctrl);
  66248. + }
  66249. +
  66250. + /* request power down pin */
  66251. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  66252. + if (!gpio_is_valid(pwn_gpio)) {
  66253. + dev_err(dev, "no sensor pwdn pin available\n");
  66254. + return -ENODEV;
  66255. + }
  66256. + ret = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  66257. + "adv7180_pwdn");
  66258. + if (ret < 0) {
  66259. + dev_err(dev, "no power pin available!\n");
  66260. + return ret;
  66261. + }
  66262. +
  66263. + adv7180_regulator_enable(dev);
  66264. +
  66265. + adv7180_power_down(0);
  66266. +
  66267. + msleep(1);
  66268. +
  66269. + /* Set initial values for the sensor struct. */
  66270. + memset(&adv7180_data, 0, sizeof(adv7180_data));
  66271. + adv7180_data.sen.i2c_client = client;
  66272. + adv7180_data.sen.streamcap.timeperframe.denominator = 30;
  66273. + adv7180_data.sen.streamcap.timeperframe.numerator = 1;
  66274. + adv7180_data.std_id = V4L2_STD_ALL;
  66275. + video_idx = ADV7180_NOT_LOCKED;
  66276. + adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
  66277. + adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
  66278. + adv7180_data.sen.pix.pixelformat = V4L2_PIX_FMT_UYVY; /* YUV422 */
  66279. + adv7180_data.sen.pix.priv = 1; /* 1 is used to indicate TV in */
  66280. + adv7180_data.sen.on = true;
  66281. +
  66282. + adv7180_data.sen.sensor_clk = devm_clk_get(dev, "csi_mclk");
  66283. + if (IS_ERR(adv7180_data.sen.sensor_clk)) {
  66284. + dev_err(dev, "get mclk failed\n");
  66285. + return PTR_ERR(adv7180_data.sen.sensor_clk);
  66286. + }
  66287. +
  66288. + ret = of_property_read_u32(dev->of_node, "mclk",
  66289. + &adv7180_data.sen.mclk);
  66290. + if (ret) {
  66291. + dev_err(dev, "mclk frequency is invalid\n");
  66292. + return ret;
  66293. + }
  66294. +
  66295. + ret = of_property_read_u32(
  66296. + dev->of_node, "mclk_source",
  66297. + (u32 *) &(adv7180_data.sen.mclk_source));
  66298. + if (ret) {
  66299. + dev_err(dev, "mclk_source invalid\n");
  66300. + return ret;
  66301. + }
  66302. +
  66303. + ret = of_property_read_u32(dev->of_node, "csi_id",
  66304. + &(adv7180_data.sen.csi));
  66305. + if (ret) {
  66306. + dev_err(dev, "csi_id invalid\n");
  66307. + return ret;
  66308. + }
  66309. +
  66310. + clk_prepare_enable(adv7180_data.sen.sensor_clk);
  66311. +
  66312. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  66313. + "%s:adv7180 probe i2c address is 0x%02X\n",
  66314. + __func__, adv7180_data.sen.i2c_client->addr);
  66315. +
  66316. + /*! Read the revision ID of the tvin chip */
  66317. + rev_id = adv7180_read(ADV7180_IDENT);
  66318. + dev_dbg(dev,
  66319. + "%s:Analog Device adv7%2X0 detected!\n", __func__,
  66320. + rev_id);
  66321. +
  66322. + ret = of_property_read_u32(dev->of_node, "cvbs", &(cvbs));
  66323. + if (ret) {
  66324. + dev_err(dev, "cvbs setting is not found\n");
  66325. + cvbs = true;
  66326. + }
  66327. +
  66328. + /*! ADV7180 initialization. */
  66329. + adv7180_hard_reset(cvbs);
  66330. +
  66331. + pr_debug(" type is %d (expect %d)\n",
  66332. + adv7180_int_device.type, v4l2_int_type_slave);
  66333. + pr_debug(" num ioctls is %d\n",
  66334. + adv7180_int_device.u.slave->num_ioctls);
  66335. +
  66336. + /* This function attaches this structure to the /dev/video0 device.
  66337. + * The pointer in priv points to the adv7180_data structure here.*/
  66338. + adv7180_int_device.priv = &adv7180_data;
  66339. + ret = v4l2_int_device_register(&adv7180_int_device);
  66340. +
  66341. + clk_disable_unprepare(adv7180_data.sen.sensor_clk);
  66342. +
  66343. + return ret;
  66344. +}
  66345. +
  66346. +/*!
  66347. + * ADV7180 I2C detach function.
  66348. + * Called on rmmod.
  66349. + *
  66350. + * @param *client struct i2c_client*.
  66351. + *
  66352. + * @return Error code indicating success or failure.
  66353. + */
  66354. +static int adv7180_detach(struct i2c_client *client)
  66355. +{
  66356. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  66357. + "%s:Removing %s video decoder @ 0x%02X from adapter %s\n",
  66358. + __func__, IF_NAME, client->addr << 1, client->adapter->name);
  66359. +
  66360. + /* Power down via i2c */
  66361. + adv7180_write_reg(ADV7180_PWR_MNG, 0x24);
  66362. +
  66363. + if (dvddio_regulator)
  66364. + regulator_disable(dvddio_regulator);
  66365. +
  66366. + if (dvdd_regulator)
  66367. + regulator_disable(dvdd_regulator);
  66368. +
  66369. + if (avdd_regulator)
  66370. + regulator_disable(avdd_regulator);
  66371. +
  66372. + if (pvdd_regulator)
  66373. + regulator_disable(pvdd_regulator);
  66374. +
  66375. + v4l2_int_device_unregister(&adv7180_int_device);
  66376. +
  66377. + return 0;
  66378. +}
  66379. +
  66380. +/*!
  66381. + * ADV7180 init function.
  66382. + * Called on insmod.
  66383. + *
  66384. + * @return Error code indicating success or failure.
  66385. + */
  66386. +static __init int adv7180_init(void)
  66387. +{
  66388. + u8 err = 0;
  66389. +
  66390. + pr_debug("In adv7180_init\n");
  66391. +
  66392. + /* Tells the i2c driver what functions to call for this driver. */
  66393. + err = i2c_add_driver(&adv7180_i2c_driver);
  66394. + if (err != 0)
  66395. + pr_err("%s:driver registration failed, error=%d\n",
  66396. + __func__, err);
  66397. +
  66398. + return err;
  66399. +}
  66400. +
  66401. +/*!
  66402. + * ADV7180 cleanup function.
  66403. + * Called on rmmod.
  66404. + *
  66405. + * @return Error code indicating success or failure.
  66406. + */
  66407. +static void __exit adv7180_clean(void)
  66408. +{
  66409. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_clean\n");
  66410. + i2c_del_driver(&adv7180_i2c_driver);
  66411. +}
  66412. +
  66413. +module_init(adv7180_init);
  66414. +module_exit(adv7180_clean);
  66415. +
  66416. +MODULE_AUTHOR("Freescale Semiconductor");
  66417. +MODULE_DESCRIPTION("Anolog Device ADV7180 video decoder driver");
  66418. +MODULE_LICENSE("GPL");
  66419. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/csi_v4l2_capture.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/csi_v4l2_capture.c
  66420. --- linux-3.14.15/drivers/media/platform/mxc/capture/csi_v4l2_capture.c 1970-01-01 01:00:00.000000000 +0100
  66421. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/csi_v4l2_capture.c 2014-08-20 19:23:52.814842662 +0200
  66422. @@ -0,0 +1,2047 @@
  66423. +/*
  66424. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  66425. + */
  66426. +
  66427. +/*
  66428. + * The code contained herein is licensed under the GNU General Public
  66429. + * License. You may obtain a copy of the GNU General Public License
  66430. + * Version 2 or later at the following locations:
  66431. + *
  66432. + * http://www.opensource.org/licenses/gpl-license.html
  66433. + * http://www.gnu.org/copyleft/gpl.html
  66434. + */
  66435. +
  66436. +/*!
  66437. + * @file drivers/media/video/mxc/capture/csi_v4l2_capture.c
  66438. + * This file is derived from mxc_v4l2_capture.c
  66439. + *
  66440. + * @brief Video For Linux 2 capture driver
  66441. + *
  66442. + * @ingroup MXC_V4L2_CAPTURE
  66443. + */
  66444. +#include <linux/version.h>
  66445. +#include <linux/module.h>
  66446. +#include <linux/init.h>
  66447. +#include <linux/platform_device.h>
  66448. +#include <linux/fs.h>
  66449. +#include <linux/slab.h>
  66450. +#include <linux/ctype.h>
  66451. +#include <linux/clk.h>
  66452. +#include <linux/io.h>
  66453. +#include <linux/semaphore.h>
  66454. +#include <linux/pagemap.h>
  66455. +#include <linux/vmalloc.h>
  66456. +#include <linux/types.h>
  66457. +#include <linux/fb.h>
  66458. +#include <linux/mxcfb.h>
  66459. +#include <linux/dma-mapping.h>
  66460. +#include <media/v4l2-ioctl.h>
  66461. +#include <media/v4l2-int-device.h>
  66462. +#include <media/v4l2-chip-ident.h>
  66463. +#include "mxc_v4l2_capture.h"
  66464. +#include "fsl_csi.h"
  66465. +
  66466. +static int video_nr = -1;
  66467. +static cam_data *g_cam;
  66468. +static int req_buf_number;
  66469. +
  66470. +static int csi_v4l2_master_attach(struct v4l2_int_device *slave);
  66471. +static void csi_v4l2_master_detach(struct v4l2_int_device *slave);
  66472. +static u8 camera_power(cam_data *cam, bool cameraOn);
  66473. +struct v4l2_crop crop_current;
  66474. +struct v4l2_window win_current;
  66475. +
  66476. +/*! Information about this driver. */
  66477. +static struct v4l2_int_master csi_v4l2_master = {
  66478. + .attach = csi_v4l2_master_attach,
  66479. + .detach = csi_v4l2_master_detach,
  66480. +};
  66481. +
  66482. +static struct v4l2_int_device csi_v4l2_int_device = {
  66483. + .module = THIS_MODULE,
  66484. + .name = "csi_v4l2_cap",
  66485. + .type = v4l2_int_type_master,
  66486. + .u = {
  66487. + .master = &csi_v4l2_master,
  66488. + },
  66489. +};
  66490. +
  66491. +static struct v4l2_queryctrl pxp_controls[] = {
  66492. + {
  66493. + .id = V4L2_CID_HFLIP,
  66494. + .type = V4L2_CTRL_TYPE_BOOLEAN,
  66495. + .name = "Horizontal Flip",
  66496. + .minimum = 0,
  66497. + .maximum = 1,
  66498. + .step = 1,
  66499. + .default_value = 0,
  66500. + .flags = 0,
  66501. + }, {
  66502. + .id = V4L2_CID_VFLIP,
  66503. + .type = V4L2_CTRL_TYPE_BOOLEAN,
  66504. + .name = "Vertical Flip",
  66505. + .minimum = 0,
  66506. + .maximum = 1,
  66507. + .step = 1,
  66508. + .default_value = 0,
  66509. + .flags = 0,
  66510. + }, {
  66511. + .id = V4L2_CID_PRIVATE_BASE,
  66512. + .type = V4L2_CTRL_TYPE_INTEGER,
  66513. + .name = "Rotation",
  66514. + .minimum = 0,
  66515. + .maximum = 270,
  66516. + .step = 90,
  66517. + .default_value = 0,
  66518. + .flags = 0,
  66519. + },
  66520. +};
  66521. +
  66522. +/* Callback function triggered after PxP receives an EOF interrupt */
  66523. +static void pxp_dma_done(void *arg)
  66524. +{
  66525. + struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
  66526. + struct dma_chan *chan = tx_desc->txd.chan;
  66527. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  66528. + cam_data *cam = pxp_chan->client;
  66529. +
  66530. + /* This call will signal wait_for_completion_timeout() */
  66531. + complete(&cam->pxp_tx_cmpl);
  66532. +}
  66533. +
  66534. +static bool chan_filter(struct dma_chan *chan, void *arg)
  66535. +{
  66536. + if (imx_dma_is_pxp(chan))
  66537. + return true;
  66538. + else
  66539. + return false;
  66540. +}
  66541. +
  66542. +/* Function to request PXP DMA channel */
  66543. +static int pxp_chan_init(cam_data *cam)
  66544. +{
  66545. + dma_cap_mask_t mask;
  66546. + struct dma_chan *chan;
  66547. +
  66548. + /* Request a free channel */
  66549. + dma_cap_zero(mask);
  66550. + dma_cap_set(DMA_SLAVE, mask);
  66551. + dma_cap_set(DMA_PRIVATE, mask);
  66552. + chan = dma_request_channel(mask, chan_filter, NULL);
  66553. + if (!chan) {
  66554. + pr_err("Unsuccessfully request channel!\n");
  66555. + return -EBUSY;
  66556. + }
  66557. +
  66558. + cam->pxp_chan = to_pxp_channel(chan);
  66559. + cam->pxp_chan->client = cam;
  66560. +
  66561. + init_completion(&cam->pxp_tx_cmpl);
  66562. +
  66563. + return 0;
  66564. +}
  66565. +
  66566. +/*
  66567. + * Function to call PxP DMA driver and send our new V4L2 buffer
  66568. + * through the PxP.
  66569. + * Note: This is a blocking call, so upon return the PxP tx should be complete.
  66570. + */
  66571. +static int pxp_process_update(cam_data *cam)
  66572. +{
  66573. + dma_cookie_t cookie;
  66574. + struct scatterlist *sg = cam->sg;
  66575. + struct dma_chan *dma_chan;
  66576. + struct pxp_tx_desc *desc;
  66577. + struct dma_async_tx_descriptor *txd;
  66578. + struct pxp_config_data *pxp_conf = &cam->pxp_conf;
  66579. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  66580. + int i, ret;
  66581. + int length;
  66582. +
  66583. + pr_debug("Starting PxP Send Buffer\n");
  66584. +
  66585. + /* First, check to see that we have acquired a PxP Channel object */
  66586. + if (cam->pxp_chan == NULL) {
  66587. + /*
  66588. + * PxP Channel has not yet been created and initialized,
  66589. + * so let's go ahead and try
  66590. + */
  66591. + ret = pxp_chan_init(cam);
  66592. + if (ret) {
  66593. + /*
  66594. + * PxP channel init failed, and we can't use the
  66595. + * PxP until the PxP DMA driver has loaded, so we abort
  66596. + */
  66597. + pr_err("PxP chan init failed\n");
  66598. + return -ENODEV;
  66599. + }
  66600. + }
  66601. +
  66602. + /*
  66603. + * Init completion, so that we can be properly informed of
  66604. + * the completion of the PxP task when it is done.
  66605. + */
  66606. + init_completion(&cam->pxp_tx_cmpl);
  66607. +
  66608. + dma_chan = &cam->pxp_chan->dma_chan;
  66609. +
  66610. + txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg, 2,
  66611. + DMA_TO_DEVICE,
  66612. + DMA_PREP_INTERRUPT,
  66613. + NULL);
  66614. + if (!txd) {
  66615. + pr_err("Error preparing a DMA transaction descriptor.\n");
  66616. + return -EIO;
  66617. + }
  66618. +
  66619. + txd->callback_param = txd;
  66620. + txd->callback = pxp_dma_done;
  66621. +
  66622. + /*
  66623. + * Configure PxP for processing of new v4l2 buf
  66624. + */
  66625. + pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_UYVY;
  66626. + pxp_conf->s0_param.color_key = -1;
  66627. + pxp_conf->s0_param.color_key_enable = false;
  66628. + pxp_conf->s0_param.width = cam->v2f.fmt.pix.width;
  66629. + pxp_conf->s0_param.height = cam->v2f.fmt.pix.height;
  66630. +
  66631. + pxp_conf->ol_param[0].combine_enable = false;
  66632. +
  66633. + proc_data->srect.top = 0;
  66634. + proc_data->srect.left = 0;
  66635. + proc_data->srect.width = pxp_conf->s0_param.width;
  66636. + proc_data->srect.height = pxp_conf->s0_param.height;
  66637. +
  66638. + if (crop_current.c.top != 0)
  66639. + proc_data->srect.top = crop_current.c.top;
  66640. + if (crop_current.c.left != 0)
  66641. + proc_data->srect.left = crop_current.c.left;
  66642. + if (crop_current.c.width != 0)
  66643. + proc_data->srect.width = crop_current.c.width;
  66644. + if (crop_current.c.height != 0)
  66645. + proc_data->srect.height = crop_current.c.height;
  66646. +
  66647. + proc_data->drect.left = 0;
  66648. + proc_data->drect.top = 0;
  66649. + proc_data->drect.width = proc_data->srect.width;
  66650. + proc_data->drect.height = proc_data->srect.height;
  66651. +
  66652. + if (win_current.w.left != 0)
  66653. + proc_data->drect.left = win_current.w.left;
  66654. + if (win_current.w.top != 0)
  66655. + proc_data->drect.top = win_current.w.top;
  66656. + if (win_current.w.width != 0)
  66657. + proc_data->drect.width = win_current.w.width;
  66658. + if (win_current.w.height != 0)
  66659. + proc_data->drect.height = win_current.w.height;
  66660. +
  66661. + pr_debug("srect l: %d, t: %d, w: %d, h: %d; "
  66662. + "drect l: %d, t: %d, w: %d, h: %d\n",
  66663. + proc_data->srect.left, proc_data->srect.top,
  66664. + proc_data->srect.width, proc_data->srect.height,
  66665. + proc_data->drect.left, proc_data->drect.top,
  66666. + proc_data->drect.width, proc_data->drect.height);
  66667. +
  66668. + pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_RGB565;
  66669. + pxp_conf->out_param.width = proc_data->drect.width;
  66670. + pxp_conf->out_param.height = proc_data->drect.height;
  66671. +
  66672. + if (cam->rotation % 180)
  66673. + pxp_conf->out_param.stride = pxp_conf->out_param.height;
  66674. + else
  66675. + pxp_conf->out_param.stride = pxp_conf->out_param.width;
  66676. +
  66677. + desc = to_tx_desc(txd);
  66678. + length = desc->len;
  66679. + for (i = 0; i < length; i++) {
  66680. + if (i == 0) {/* S0 */
  66681. + memcpy(&desc->proc_data, proc_data,
  66682. + sizeof(struct pxp_proc_data));
  66683. + pxp_conf->s0_param.paddr = sg_dma_address(&sg[0]);
  66684. + memcpy(&desc->layer_param.s0_param, &pxp_conf->s0_param,
  66685. + sizeof(struct pxp_layer_param));
  66686. + } else if (i == 1) {
  66687. + pxp_conf->out_param.paddr = sg_dma_address(&sg[1]);
  66688. + memcpy(&desc->layer_param.out_param,
  66689. + &pxp_conf->out_param,
  66690. + sizeof(struct pxp_layer_param));
  66691. + }
  66692. +
  66693. + desc = desc->next;
  66694. + }
  66695. +
  66696. + /* Submitting our TX starts the PxP processing task */
  66697. + cookie = txd->tx_submit(txd);
  66698. + if (cookie < 0) {
  66699. + pr_err("Error sending FB through PxP\n");
  66700. + return -EIO;
  66701. + }
  66702. +
  66703. + cam->txd = txd;
  66704. +
  66705. + /* trigger PxP */
  66706. + dma_async_issue_pending(dma_chan);
  66707. +
  66708. + return 0;
  66709. +}
  66710. +
  66711. +static int pxp_complete_update(cam_data *cam)
  66712. +{
  66713. + int ret;
  66714. + /*
  66715. + * Wait for completion event, which will be set
  66716. + * through our TX callback function.
  66717. + */
  66718. + ret = wait_for_completion_timeout(&cam->pxp_tx_cmpl, HZ / 10);
  66719. + if (ret <= 0) {
  66720. + pr_warning("PxP operation failed due to %s\n",
  66721. + ret < 0 ? "user interrupt" : "timeout");
  66722. + dma_release_channel(&cam->pxp_chan->dma_chan);
  66723. + cam->pxp_chan = NULL;
  66724. + return ret ? : -ETIMEDOUT;
  66725. + }
  66726. +
  66727. + dma_release_channel(&cam->pxp_chan->dma_chan);
  66728. + cam->pxp_chan = NULL;
  66729. +
  66730. + pr_debug("TX completed\n");
  66731. +
  66732. + return 0;
  66733. +}
  66734. +
  66735. +/*!
  66736. + * Camera V4l2 callback function.
  66737. + *
  66738. + * @param mask u32
  66739. + * @param dev void device structure
  66740. + *
  66741. + * @return none
  66742. + */
  66743. +static void camera_callback(u32 mask, void *dev)
  66744. +{
  66745. + struct mxc_v4l_frame *done_frame;
  66746. + struct mxc_v4l_frame *ready_frame;
  66747. + cam_data *cam;
  66748. +
  66749. + cam = (cam_data *) dev;
  66750. + if (cam == NULL)
  66751. + return;
  66752. +
  66753. + spin_lock(&cam->queue_int_lock);
  66754. + spin_lock(&cam->dqueue_int_lock);
  66755. + if (!list_empty(&cam->working_q)) {
  66756. + done_frame = list_entry(cam->working_q.next,
  66757. + struct mxc_v4l_frame, queue);
  66758. +
  66759. + if (done_frame->csi_buf_num != cam->ping_pong_csi)
  66760. + goto next;
  66761. +
  66762. + if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  66763. + done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE;
  66764. + done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  66765. +
  66766. + /* Added to the done queue */
  66767. + list_del(cam->working_q.next);
  66768. + list_add_tail(&done_frame->queue, &cam->done_q);
  66769. + cam->enc_counter++;
  66770. + wake_up_interruptible(&cam->enc_queue);
  66771. + } else {
  66772. + pr_err("ERROR: v4l2 capture: %s: "
  66773. + "buffer not queued\n", __func__);
  66774. + }
  66775. + }
  66776. +
  66777. +next:
  66778. + if (!list_empty(&cam->ready_q)) {
  66779. + ready_frame = list_entry(cam->ready_q.next,
  66780. + struct mxc_v4l_frame, queue);
  66781. + list_del(cam->ready_q.next);
  66782. + list_add_tail(&ready_frame->queue, &cam->working_q);
  66783. +
  66784. + __raw_writel(ready_frame->paddress,
  66785. + cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 :
  66786. + CSI_CSIDMASA_FB2);
  66787. + ready_frame->csi_buf_num = cam->ping_pong_csi;
  66788. + } else {
  66789. + __raw_writel(cam->dummy_frame.paddress,
  66790. + cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 :
  66791. + CSI_CSIDMASA_FB2);
  66792. + }
  66793. + spin_unlock(&cam->dqueue_int_lock);
  66794. + spin_unlock(&cam->queue_int_lock);
  66795. +
  66796. + return;
  66797. +}
  66798. +
  66799. +/*!
  66800. + * Make csi ready for capture image.
  66801. + *
  66802. + * @param cam structure cam_data *
  66803. + *
  66804. + * @return status 0 success
  66805. + */
  66806. +static int csi_cap_image(cam_data *cam)
  66807. +{
  66808. + unsigned int value;
  66809. +
  66810. + value = __raw_readl(CSI_CSICR3);
  66811. + __raw_writel(value | BIT_FRMCNT_RST, CSI_CSICR3);
  66812. + value = __raw_readl(CSI_CSISR);
  66813. + __raw_writel(value, CSI_CSISR);
  66814. +
  66815. + return 0;
  66816. +}
  66817. +
  66818. +/***************************************************************************
  66819. + * Functions for handling Frame buffers.
  66820. + **************************************************************************/
  66821. +
  66822. +/*!
  66823. + * Free frame buffers
  66824. + *
  66825. + * @param cam Structure cam_data *
  66826. + *
  66827. + * @return status 0 success.
  66828. + */
  66829. +static int csi_free_frame_buf(cam_data *cam)
  66830. +{
  66831. + int i;
  66832. +
  66833. + pr_debug("MVC: In %s\n", __func__);
  66834. +
  66835. + for (i = 0; i < FRAME_NUM; i++) {
  66836. + if (cam->frame[i].vaddress != 0) {
  66837. + dma_free_coherent(0, cam->frame[i].buffer.length,
  66838. + cam->frame[i].vaddress,
  66839. + cam->frame[i].paddress);
  66840. + cam->frame[i].vaddress = 0;
  66841. + }
  66842. + }
  66843. +
  66844. + if (cam->dummy_frame.vaddress != 0) {
  66845. + dma_free_coherent(0, cam->dummy_frame.buffer.length,
  66846. + cam->dummy_frame.vaddress,
  66847. + cam->dummy_frame.paddress);
  66848. + cam->dummy_frame.vaddress = 0;
  66849. + }
  66850. +
  66851. + return 0;
  66852. +}
  66853. +
  66854. +/*!
  66855. + * Allocate frame buffers
  66856. + *
  66857. + * @param cam Structure cam_data *
  66858. + * @param count int number of buffer need to allocated
  66859. + *
  66860. + * @return status -0 Successfully allocated a buffer, -ENOBUFS failed.
  66861. + */
  66862. +static int csi_allocate_frame_buf(cam_data *cam, int count)
  66863. +{
  66864. + int i;
  66865. +
  66866. + pr_debug("In MVC:%s- size=%d\n",
  66867. + __func__, cam->v2f.fmt.pix.sizeimage);
  66868. + for (i = 0; i < count; i++) {
  66869. + cam->frame[i].vaddress = dma_alloc_coherent(0, PAGE_ALIGN
  66870. + (cam->v2f.fmt.
  66871. + pix.sizeimage),
  66872. + &cam->frame[i].
  66873. + paddress,
  66874. + GFP_DMA |
  66875. + GFP_KERNEL);
  66876. + if (cam->frame[i].vaddress == 0) {
  66877. + pr_err("ERROR: v4l2 capture: "
  66878. + "%s failed.\n", __func__);
  66879. + csi_free_frame_buf(cam);
  66880. + return -ENOBUFS;
  66881. + }
  66882. + cam->frame[i].buffer.index = i;
  66883. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  66884. + cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  66885. + cam->frame[i].buffer.length = cam->v2f.fmt.pix.sizeimage;
  66886. + cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP;
  66887. + cam->frame[i].buffer.m.offset = cam->frame[i].paddress;
  66888. + cam->frame[i].index = i;
  66889. + cam->frame[i].csi_buf_num = 0;
  66890. + }
  66891. +
  66892. + return 0;
  66893. +}
  66894. +
  66895. +/*!
  66896. + * Free frame buffers status
  66897. + *
  66898. + * @param cam Structure cam_data *
  66899. + *
  66900. + * @return none
  66901. + */
  66902. +static void csi_free_frames(cam_data *cam)
  66903. +{
  66904. + int i;
  66905. +
  66906. + pr_debug("In MVC: %s\n", __func__);
  66907. +
  66908. + for (i = 0; i < FRAME_NUM; i++)
  66909. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  66910. +
  66911. + cam->enc_counter = 0;
  66912. + INIT_LIST_HEAD(&cam->ready_q);
  66913. + INIT_LIST_HEAD(&cam->working_q);
  66914. + INIT_LIST_HEAD(&cam->done_q);
  66915. +
  66916. + return;
  66917. +}
  66918. +
  66919. +/*!
  66920. + * Return the buffer status
  66921. + *
  66922. + * @param cam Structure cam_data *
  66923. + * @param buf Structure v4l2_buffer *
  66924. + *
  66925. + * @return status 0 success, EINVAL failed.
  66926. + */
  66927. +static int csi_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf)
  66928. +{
  66929. + pr_debug("In MVC: %s\n", __func__);
  66930. +
  66931. + if (buf->index < 0 || buf->index >= FRAME_NUM) {
  66932. + pr_err("ERROR: v4l2 capture: %s buffers "
  66933. + "not allocated\n", __func__);
  66934. + return -EINVAL;
  66935. + }
  66936. +
  66937. + memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf));
  66938. +
  66939. + return 0;
  66940. +}
  66941. +
  66942. +static int csi_v4l2_release_bufs(cam_data *cam)
  66943. +{
  66944. + pr_debug("In MVC:csi_v4l2_release_bufs\n");
  66945. + return 0;
  66946. +}
  66947. +
  66948. +static int csi_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf)
  66949. +{
  66950. + pr_debug("In MVC:csi_v4l2_prepare_bufs\n");
  66951. +
  66952. + if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length <
  66953. + cam->v2f.fmt.pix.sizeimage) {
  66954. + pr_err("ERROR: v4l2 capture: csi_v4l2_prepare_bufs buffers "
  66955. + "not allocated,index=%d, length=%d\n", buf->index,
  66956. + buf->length);
  66957. + return -EINVAL;
  66958. + }
  66959. +
  66960. + cam->frame[buf->index].buffer.index = buf->index;
  66961. + cam->frame[buf->index].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  66962. + cam->frame[buf->index].buffer.length = buf->length;
  66963. + cam->frame[buf->index].buffer.m.offset = cam->frame[buf->index].paddress
  66964. + = buf->m.offset;
  66965. + cam->frame[buf->index].buffer.type = buf->type;
  66966. + cam->frame[buf->index].buffer.memory = V4L2_MEMORY_USERPTR;
  66967. + cam->frame[buf->index].index = buf->index;
  66968. +
  66969. + return 0;
  66970. +}
  66971. +
  66972. +/*!
  66973. + * Indicates whether the palette is supported.
  66974. + *
  66975. + * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_UYVY or V4L2_PIX_FMT_YUV420
  66976. + *
  66977. + * @return 0 if failed
  66978. + */
  66979. +static inline int valid_mode(u32 palette)
  66980. +{
  66981. + return (palette == V4L2_PIX_FMT_RGB565) ||
  66982. + (palette == V4L2_PIX_FMT_YUYV) ||
  66983. + (palette == V4L2_PIX_FMT_UYVY) || (palette == V4L2_PIX_FMT_YUV420);
  66984. +}
  66985. +
  66986. +/*!
  66987. + * Start stream I/O
  66988. + *
  66989. + * @param cam structure cam_data *
  66990. + *
  66991. + * @return status 0 Success
  66992. + */
  66993. +static int csi_streamon(cam_data *cam)
  66994. +{
  66995. + struct mxc_v4l_frame *frame;
  66996. + unsigned long flags;
  66997. + unsigned long val;
  66998. + int timeout, timeout2;
  66999. +
  67000. + pr_debug("In MVC: %s\n", __func__);
  67001. +
  67002. + if (NULL == cam) {
  67003. + pr_err("ERROR: v4l2 capture: %s cam parameter is NULL\n",
  67004. + __func__);
  67005. + return -1;
  67006. + }
  67007. + cam->dummy_frame.vaddress = dma_alloc_coherent(0,
  67008. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  67009. + &cam->dummy_frame.paddress,
  67010. + GFP_DMA | GFP_KERNEL);
  67011. + if (cam->dummy_frame.vaddress == 0) {
  67012. + pr_err("ERROR: v4l2 capture: Allocate dummy frame "
  67013. + "failed.\n");
  67014. + return -ENOBUFS;
  67015. + }
  67016. + cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
  67017. + cam->dummy_frame.buffer.length = cam->v2f.fmt.pix.sizeimage;
  67018. + cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
  67019. +
  67020. + spin_lock_irqsave(&cam->queue_int_lock, flags);
  67021. + /* move the frame from readyq to workingq */
  67022. + if (list_empty(&cam->ready_q)) {
  67023. + pr_err("ERROR: v4l2 capture: %s: "
  67024. + "ready_q queue empty\n", __func__);
  67025. + spin_unlock_irqrestore(&cam->queue_int_lock, flags);
  67026. + return -1;
  67027. + }
  67028. + frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  67029. + list_del(cam->ready_q.next);
  67030. + list_add_tail(&frame->queue, &cam->working_q);
  67031. + __raw_writel(frame->paddress, CSI_CSIDMASA_FB1);
  67032. + frame->csi_buf_num = 1;
  67033. +
  67034. + if (list_empty(&cam->ready_q)) {
  67035. + pr_err("ERROR: v4l2 capture: %s: "
  67036. + "ready_q queue empty\n", __func__);
  67037. + spin_unlock_irqrestore(&cam->queue_int_lock, flags);
  67038. + return -1;
  67039. + }
  67040. + frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  67041. + list_del(cam->ready_q.next);
  67042. + list_add_tail(&frame->queue, &cam->working_q);
  67043. + __raw_writel(frame->paddress, CSI_CSIDMASA_FB2);
  67044. + frame->csi_buf_num = 2;
  67045. + spin_unlock_irqrestore(&cam->queue_int_lock, flags);
  67046. +
  67047. + cam->capture_pid = current->pid;
  67048. + cam->capture_on = true;
  67049. + csi_cap_image(cam);
  67050. +
  67051. + local_irq_save(flags);
  67052. + for (timeout = 1000000; timeout > 0; timeout--) {
  67053. + if (__raw_readl(CSI_CSISR) & BIT_SOF_INT) {
  67054. + val = __raw_readl(CSI_CSICR3);
  67055. + __raw_writel(val | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  67056. + for (timeout2 = 1000000; timeout2 > 0; timeout2--) {
  67057. + if (__raw_readl(CSI_CSICR3) &
  67058. + BIT_DMA_REFLASH_RFF)
  67059. + cpu_relax();
  67060. + else
  67061. + break;
  67062. + }
  67063. + if (timeout2 <= 0) {
  67064. + pr_err("timeout when wait for reflash done.\n");
  67065. + local_irq_restore(flags);
  67066. + return -ETIME;
  67067. + }
  67068. +
  67069. + csi_dmareq_rff_enable();
  67070. + csi_enable_int(1);
  67071. + break;
  67072. + } else
  67073. + cpu_relax();
  67074. + }
  67075. + if (timeout <= 0) {
  67076. + pr_err("timeout when wait for SOF\n");
  67077. + local_irq_restore(flags);
  67078. + return -ETIME;
  67079. + }
  67080. + local_irq_restore(flags);
  67081. +
  67082. + return 0;
  67083. +}
  67084. +
  67085. +/*!
  67086. + * Stop stream I/O
  67087. + *
  67088. + * @param cam structure cam_data *
  67089. + *
  67090. + * @return status 0 Success
  67091. + */
  67092. +static int csi_streamoff(cam_data *cam)
  67093. +{
  67094. + pr_debug("In MVC: %s\n", __func__);
  67095. +
  67096. + if (cam->capture_on == false)
  67097. + return 0;
  67098. +
  67099. + csi_dmareq_rff_disable();
  67100. + csi_disable_int();
  67101. + cam->capture_on = false;
  67102. +
  67103. + /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
  67104. + __raw_writel(0, CSI_CSIDMASA_FB1);
  67105. + __raw_writel(0, CSI_CSIDMASA_FB2);
  67106. +
  67107. + csi_free_frames(cam);
  67108. + csi_free_frame_buf(cam);
  67109. +
  67110. + return 0;
  67111. +}
  67112. +
  67113. +/*!
  67114. + * start the viewfinder job
  67115. + *
  67116. + * @param cam structure cam_data *
  67117. + *
  67118. + * @return status 0 Success
  67119. + */
  67120. +static int start_preview(cam_data *cam)
  67121. +{
  67122. + unsigned long fb_addr = (unsigned long)cam->v4l2_fb.base;
  67123. +
  67124. + __raw_writel(fb_addr, CSI_CSIDMASA_FB1);
  67125. + __raw_writel(fb_addr, CSI_CSIDMASA_FB2);
  67126. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  67127. +
  67128. + csi_enable_int(0);
  67129. +
  67130. + return 0;
  67131. +}
  67132. +
  67133. +/*!
  67134. + * shut down the viewfinder job
  67135. + *
  67136. + * @param cam structure cam_data *
  67137. + *
  67138. + * @return status 0 Success
  67139. + */
  67140. +static int stop_preview(cam_data *cam)
  67141. +{
  67142. + csi_disable_int();
  67143. +
  67144. + /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
  67145. + __raw_writel(0, CSI_CSIDMASA_FB1);
  67146. + __raw_writel(0, CSI_CSIDMASA_FB2);
  67147. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  67148. +
  67149. + return 0;
  67150. +}
  67151. +
  67152. +/***************************************************************************
  67153. + * VIDIOC Functions.
  67154. + **************************************************************************/
  67155. +
  67156. +/*!
  67157. + *
  67158. + * @param cam structure cam_data *
  67159. + *
  67160. + * @param f structure v4l2_format *
  67161. + *
  67162. + * @return status 0 success, EINVAL failed
  67163. + */
  67164. +static int csi_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f)
  67165. +{
  67166. + int retval = 0;
  67167. +
  67168. + switch (f->type) {
  67169. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  67170. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  67171. + f->fmt.pix = cam->v2f.fmt.pix;
  67172. + break;
  67173. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  67174. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  67175. + f->fmt.win = cam->win;
  67176. + break;
  67177. + default:
  67178. + pr_debug(" type is invalid\n");
  67179. + retval = -EINVAL;
  67180. + }
  67181. +
  67182. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  67183. + __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  67184. +
  67185. + return retval;
  67186. +}
  67187. +
  67188. +/*!
  67189. + * V4L2 - csi_v4l2_s_fmt function
  67190. + *
  67191. + * @param cam structure cam_data *
  67192. + *
  67193. + * @param f structure v4l2_format *
  67194. + *
  67195. + * @return status 0 success, EINVAL failed
  67196. + */
  67197. +static int csi_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
  67198. +{
  67199. + int retval = 0;
  67200. + int size = 0;
  67201. + int bytesperline = 0;
  67202. + int *width, *height;
  67203. +
  67204. + pr_debug("In MVC: %s\n", __func__);
  67205. +
  67206. + switch (f->type) {
  67207. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  67208. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  67209. + if (!valid_mode(f->fmt.pix.pixelformat)) {
  67210. + pr_err("ERROR: v4l2 capture: %s: format "
  67211. + "not supported\n", __func__);
  67212. + return -EINVAL;
  67213. + }
  67214. +
  67215. + /* Handle case where size requested is larger than cuurent
  67216. + * camera setting. */
  67217. + if ((f->fmt.pix.width > cam->crop_bounds.width)
  67218. + || (f->fmt.pix.height > cam->crop_bounds.height)) {
  67219. + /* Need the logic here, calling vidioc_s_param if
  67220. + * camera can change. */
  67221. + pr_debug("csi_v4l2_s_fmt size changed\n");
  67222. + }
  67223. + if (cam->rotation % 180) {
  67224. + height = &f->fmt.pix.width;
  67225. + width = &f->fmt.pix.height;
  67226. + } else {
  67227. + width = &f->fmt.pix.width;
  67228. + height = &f->fmt.pix.height;
  67229. + }
  67230. +
  67231. + if ((cam->crop_bounds.width / *width > 8) ||
  67232. + ((cam->crop_bounds.width / *width == 8) &&
  67233. + (cam->crop_bounds.width % *width))) {
  67234. + *width = cam->crop_bounds.width / 8;
  67235. + if (*width % 8)
  67236. + *width += 8 - *width % 8;
  67237. + pr_err("ERROR: v4l2 capture: width exceeds limit "
  67238. + "resize to %d.\n", *width);
  67239. + }
  67240. +
  67241. + if ((cam->crop_bounds.height / *height > 8) ||
  67242. + ((cam->crop_bounds.height / *height == 8) &&
  67243. + (cam->crop_bounds.height % *height))) {
  67244. + *height = cam->crop_bounds.height / 8;
  67245. + if (*height % 8)
  67246. + *height += 8 - *height % 8;
  67247. + pr_err("ERROR: v4l2 capture: height exceeds limit "
  67248. + "resize to %d.\n", *height);
  67249. + }
  67250. +
  67251. + switch (f->fmt.pix.pixelformat) {
  67252. + case V4L2_PIX_FMT_RGB565:
  67253. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  67254. + csi_init_format(V4L2_PIX_FMT_UYVY);
  67255. + csi_set_16bit_imagpara(f->fmt.pix.width,
  67256. + f->fmt.pix.height);
  67257. + bytesperline = f->fmt.pix.width * 2;
  67258. + break;
  67259. + case V4L2_PIX_FMT_UYVY:
  67260. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  67261. + csi_init_format(f->fmt.pix.pixelformat);
  67262. + csi_set_16bit_imagpara(f->fmt.pix.width,
  67263. + f->fmt.pix.height);
  67264. + bytesperline = f->fmt.pix.width * 2;
  67265. + break;
  67266. + case V4L2_PIX_FMT_YUYV:
  67267. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  67268. + csi_init_format(f->fmt.pix.pixelformat);
  67269. + csi_set_16bit_imagpara(f->fmt.pix.width,
  67270. + f->fmt.pix.height);
  67271. + bytesperline = f->fmt.pix.width * 2;
  67272. + break;
  67273. + case V4L2_PIX_FMT_YUV420:
  67274. + size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
  67275. + csi_set_12bit_imagpara(f->fmt.pix.width,
  67276. + f->fmt.pix.height);
  67277. + bytesperline = f->fmt.pix.width;
  67278. + break;
  67279. + case V4L2_PIX_FMT_YUV422P:
  67280. + case V4L2_PIX_FMT_RGB24:
  67281. + case V4L2_PIX_FMT_BGR24:
  67282. + case V4L2_PIX_FMT_BGR32:
  67283. + case V4L2_PIX_FMT_RGB32:
  67284. + case V4L2_PIX_FMT_NV12:
  67285. + default:
  67286. + pr_debug(" case not supported\n");
  67287. + break;
  67288. + }
  67289. +
  67290. + if (f->fmt.pix.bytesperline < bytesperline)
  67291. + f->fmt.pix.bytesperline = bytesperline;
  67292. + else
  67293. + bytesperline = f->fmt.pix.bytesperline;
  67294. +
  67295. + if (f->fmt.pix.sizeimage < size)
  67296. + f->fmt.pix.sizeimage = size;
  67297. + else
  67298. + size = f->fmt.pix.sizeimage;
  67299. +
  67300. + cam->v2f.fmt.pix = f->fmt.pix;
  67301. +
  67302. + if (cam->v2f.fmt.pix.priv != 0) {
  67303. + if (copy_from_user(&cam->offset,
  67304. + (void *)cam->v2f.fmt.pix.priv,
  67305. + sizeof(cam->offset))) {
  67306. + retval = -EFAULT;
  67307. + break;
  67308. + }
  67309. + }
  67310. + break;
  67311. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  67312. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  67313. + cam->win = f->fmt.win;
  67314. + win_current = f->fmt.win;
  67315. + size = win_current.w.width * win_current.w.height * 2;
  67316. + if (cam->v2f.fmt.pix.sizeimage < size)
  67317. + cam->v2f.fmt.pix.sizeimage = size;
  67318. +
  67319. + break;
  67320. + default:
  67321. + retval = -EINVAL;
  67322. + }
  67323. +
  67324. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  67325. + __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  67326. +
  67327. + return retval;
  67328. +}
  67329. +
  67330. +/*!
  67331. + * V4L2 - csi_v4l2_s_param function
  67332. + * Allows setting of capturemode and frame rate.
  67333. + *
  67334. + * @param cam structure cam_data *
  67335. + * @param parm structure v4l2_streamparm *
  67336. + *
  67337. + * @return status 0 success, EINVAL failed
  67338. + */
  67339. +static int csi_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
  67340. +{
  67341. + struct v4l2_ifparm ifparm;
  67342. + struct v4l2_format cam_fmt;
  67343. + struct v4l2_streamparm currentparm;
  67344. + int err = 0;
  67345. +
  67346. + pr_debug("In %s\n", __func__);
  67347. +
  67348. + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  67349. + pr_err(KERN_ERR "%s invalid type\n", __func__);
  67350. + return -EINVAL;
  67351. + }
  67352. +
  67353. + /* Stop the viewfinder */
  67354. + if (cam->overlay_on == true)
  67355. + stop_preview(cam);
  67356. +
  67357. + currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  67358. +
  67359. + /* First check that this device can support the changes requested. */
  67360. + err = vidioc_int_g_parm(cam->sensor, &currentparm);
  67361. + if (err) {
  67362. + pr_err("%s: vidioc_int_g_parm returned an error %d\n",
  67363. + __func__, err);
  67364. + goto exit;
  67365. + }
  67366. +
  67367. + pr_debug(" Current capabilities are %x\n",
  67368. + currentparm.parm.capture.capability);
  67369. + pr_debug(" Current capturemode is %d change to %d\n",
  67370. + currentparm.parm.capture.capturemode,
  67371. + parm->parm.capture.capturemode);
  67372. + pr_debug(" Current framerate is %d change to %d\n",
  67373. + currentparm.parm.capture.timeperframe.denominator,
  67374. + parm->parm.capture.timeperframe.denominator);
  67375. +
  67376. + err = vidioc_int_s_parm(cam->sensor, parm);
  67377. + if (err) {
  67378. + pr_err("%s: vidioc_int_s_parm returned an error %d\n",
  67379. + __func__, err);
  67380. + goto exit;
  67381. + }
  67382. +
  67383. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  67384. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  67385. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  67386. + pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n",
  67387. + cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
  67388. +
  67389. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  67390. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  67391. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  67392. + cam->crop_current.width = cam->crop_bounds.width;
  67393. + cam->crop_current.height = cam->crop_bounds.height;
  67394. +
  67395. +exit:
  67396. + return err;
  67397. +}
  67398. +
  67399. +static int pxp_set_cstate(cam_data *cam, struct v4l2_control *vc)
  67400. +{
  67401. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  67402. +
  67403. + if (vc->id == V4L2_CID_HFLIP) {
  67404. + proc_data->hflip = vc->value;
  67405. + } else if (vc->id == V4L2_CID_VFLIP) {
  67406. + proc_data->vflip = vc->value;
  67407. + } else if (vc->id == V4L2_CID_PRIVATE_BASE) {
  67408. + if (vc->value % 90)
  67409. + return -ERANGE;
  67410. + proc_data->rotate = vc->value;
  67411. + cam->rotation = vc->value;
  67412. + }
  67413. +
  67414. + return 0;
  67415. +}
  67416. +
  67417. +static int pxp_get_cstate(cam_data *cam, struct v4l2_control *vc)
  67418. +{
  67419. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  67420. +
  67421. + if (vc->id == V4L2_CID_HFLIP)
  67422. + vc->value = proc_data->hflip;
  67423. + else if (vc->id == V4L2_CID_VFLIP)
  67424. + vc->value = proc_data->vflip;
  67425. + else if (vc->id == V4L2_CID_PRIVATE_BASE)
  67426. + vc->value = proc_data->rotate;
  67427. +
  67428. + return 0;
  67429. +}
  67430. +
  67431. +
  67432. +/*!
  67433. + * Dequeue one V4L capture buffer
  67434. + *
  67435. + * @param cam structure cam_data *
  67436. + * @param buf structure v4l2_buffer *
  67437. + *
  67438. + * @return status 0 success, EINVAL invalid frame number
  67439. + * ETIME timeout, ERESTARTSYS interrupted by user
  67440. + */
  67441. +static int csi_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
  67442. +{
  67443. + int retval = 0;
  67444. + struct mxc_v4l_frame *frame;
  67445. + unsigned long lock_flags;
  67446. +
  67447. + if (!wait_event_interruptible_timeout(cam->enc_queue,
  67448. + cam->enc_counter != 0, 10 * HZ)) {
  67449. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout "
  67450. + "enc_counter %x\n", cam->enc_counter);
  67451. + return -ETIME;
  67452. + } else if (signal_pending(current)) {
  67453. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() "
  67454. + "interrupt received\n");
  67455. + return -ERESTARTSYS;
  67456. + }
  67457. +
  67458. + if (down_interruptible(&cam->busy_lock))
  67459. + return -EBUSY;
  67460. +
  67461. + spin_lock_irqsave(&cam->dqueue_int_lock, lock_flags);
  67462. +
  67463. + if (list_empty(&cam->done_q)) {
  67464. + spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
  67465. + up(&cam->busy_lock);
  67466. + return -EINVAL;
  67467. + }
  67468. +
  67469. + cam->enc_counter--;
  67470. +
  67471. + frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue);
  67472. + list_del(cam->done_q.next);
  67473. +
  67474. + if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) {
  67475. + frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE;
  67476. + } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  67477. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  67478. + "Buffer not filled.\n");
  67479. + frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  67480. + retval = -EINVAL;
  67481. + } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) {
  67482. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  67483. + "Buffer not queued.\n");
  67484. + retval = -EINVAL;
  67485. + }
  67486. +
  67487. + spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
  67488. +
  67489. + buf->bytesused = cam->v2f.fmt.pix.sizeimage;
  67490. + buf->index = frame->index;
  67491. + buf->flags = frame->buffer.flags;
  67492. + buf->m = cam->frame[frame->index].buffer.m;
  67493. +
  67494. + /*
  67495. + * Note:
  67496. + * If want to do preview on LCD, use PxP CSC to convert from UYVY
  67497. + * to RGB565; but for encoding, usually we don't use RGB format.
  67498. + */
  67499. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
  67500. + sg_dma_address(&cam->sg[0]) = buf->m.offset;
  67501. + sg_dma_address(&cam->sg[1]) =
  67502. + cam->frame[req_buf_number].paddress;
  67503. + retval = pxp_process_update(cam);
  67504. + if (retval) {
  67505. + pr_err("Unable to submit PxP update task.\n");
  67506. + return retval;
  67507. + }
  67508. + pxp_complete_update(cam);
  67509. + if (cam->frame[buf->index].vaddress)
  67510. + memcpy(cam->frame[buf->index].vaddress,
  67511. + cam->frame[req_buf_number].vaddress,
  67512. + cam->v2f.fmt.pix.sizeimage);
  67513. + }
  67514. + up(&cam->busy_lock);
  67515. +
  67516. + return retval;
  67517. +}
  67518. +
  67519. +/*!
  67520. + * V4L interface - open function
  67521. + *
  67522. + * @param file structure file *
  67523. + *
  67524. + * @return status 0 success, ENODEV invalid device instance,
  67525. + * ENODEV timeout, ERESTARTSYS interrupted by user
  67526. + */
  67527. +static int csi_v4l_open(struct file *file)
  67528. +{
  67529. + struct v4l2_ifparm ifparm;
  67530. + struct v4l2_format cam_fmt;
  67531. + struct video_device *dev = video_devdata(file);
  67532. + cam_data *cam = video_get_drvdata(dev);
  67533. + struct sensor_data *sensor;
  67534. + int err = 0;
  67535. +
  67536. + pr_debug(" device name is %s\n", dev->name);
  67537. +
  67538. + if (!cam) {
  67539. + pr_err("%s: Internal error, cam_data not found!\n", __func__);
  67540. + return -EBADF;
  67541. + }
  67542. +
  67543. + if (!cam->sensor) {
  67544. + pr_err("%s: Internal error, camera is not found!\n", __func__);
  67545. + return -EBADF;
  67546. + }
  67547. +
  67548. + sensor = cam->sensor->priv;
  67549. + if (!sensor) {
  67550. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  67551. + return -EBADF;
  67552. + }
  67553. +
  67554. + down(&cam->busy_lock);
  67555. + err = 0;
  67556. + if (signal_pending(current))
  67557. + goto oops;
  67558. +
  67559. + if (cam->open_count++ == 0) {
  67560. + wait_event_interruptible(cam->power_queue,
  67561. + cam->low_power == false);
  67562. +
  67563. + cam->enc_counter = 0;
  67564. + INIT_LIST_HEAD(&cam->ready_q);
  67565. + INIT_LIST_HEAD(&cam->working_q);
  67566. + INIT_LIST_HEAD(&cam->done_q);
  67567. +
  67568. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  67569. +
  67570. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  67571. + clk_prepare_enable(sensor->sensor_clk);
  67572. + vidioc_int_s_power(cam->sensor, 1);
  67573. + vidioc_int_init(cam->sensor);
  67574. + vidioc_int_dev_init(cam->sensor);
  67575. + }
  67576. +
  67577. + file->private_data = dev;
  67578. +
  67579. +oops:
  67580. + up(&cam->busy_lock);
  67581. + return err;
  67582. +}
  67583. +
  67584. +/*!
  67585. + * V4L interface - close function
  67586. + *
  67587. + * @param file struct file *
  67588. + *
  67589. + * @return 0 success
  67590. + */
  67591. +static int csi_v4l_close(struct file *file)
  67592. +{
  67593. + struct video_device *dev = video_devdata(file);
  67594. + int err = 0;
  67595. + cam_data *cam = video_get_drvdata(dev);
  67596. + struct sensor_data *sensor;
  67597. +
  67598. + pr_debug("In MVC:%s\n", __func__);
  67599. +
  67600. + if (!cam) {
  67601. + pr_err("%s: Internal error, cam_data not found!\n", __func__);
  67602. + return -EBADF;
  67603. + }
  67604. +
  67605. + if (!cam->sensor) {
  67606. + pr_err("%s: Internal error, camera is not found!\n", __func__);
  67607. + return -EBADF;
  67608. + }
  67609. +
  67610. + sensor = cam->sensor->priv;
  67611. + if (!sensor) {
  67612. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  67613. + return -EBADF;
  67614. + }
  67615. +
  67616. + /* for the case somebody hit the ctrl C */
  67617. + if (cam->overlay_pid == current->pid) {
  67618. + err = stop_preview(cam);
  67619. + cam->overlay_on = false;
  67620. + }
  67621. +
  67622. + if (--cam->open_count == 0) {
  67623. + wait_event_interruptible(cam->power_queue,
  67624. + cam->low_power == false);
  67625. + file->private_data = NULL;
  67626. + vidioc_int_s_power(cam->sensor, 0);
  67627. + clk_disable_unprepare(sensor->sensor_clk);
  67628. + }
  67629. +
  67630. + return err;
  67631. +}
  67632. +
  67633. +/*
  67634. + * V4L interface - read function
  67635. + *
  67636. + * @param file struct file *
  67637. + * @param read buf char *
  67638. + * @param count size_t
  67639. + * @param ppos structure loff_t *
  67640. + *
  67641. + * @return bytes read
  67642. + */
  67643. +static ssize_t csi_v4l_read(struct file *file, char *buf, size_t count,
  67644. + loff_t *ppos)
  67645. +{
  67646. + int err = 0;
  67647. + struct video_device *dev = video_devdata(file);
  67648. + cam_data *cam = video_get_drvdata(dev);
  67649. +
  67650. + if (down_interruptible(&cam->busy_lock))
  67651. + return -EINTR;
  67652. +
  67653. + /* Stop the viewfinder */
  67654. + if (cam->overlay_on == true)
  67655. + stop_preview(cam);
  67656. +
  67657. + if (cam->still_buf_vaddr == NULL) {
  67658. + cam->still_buf_vaddr = dma_alloc_coherent(0,
  67659. + PAGE_ALIGN
  67660. + (cam->v2f.fmt.
  67661. + pix.sizeimage),
  67662. + &cam->
  67663. + still_buf[0],
  67664. + GFP_DMA | GFP_KERNEL);
  67665. + if (cam->still_buf_vaddr == NULL) {
  67666. + pr_err("alloc dma memory failed\n");
  67667. + return -ENOMEM;
  67668. + }
  67669. + cam->still_counter = 0;
  67670. + __raw_writel(cam->still_buf[0], CSI_CSIDMASA_FB2);
  67671. + __raw_writel(cam->still_buf[0], CSI_CSIDMASA_FB1);
  67672. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF,
  67673. + CSI_CSICR3);
  67674. + __raw_writel(__raw_readl(CSI_CSISR), CSI_CSISR);
  67675. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_FRMCNT_RST,
  67676. + CSI_CSICR3);
  67677. + csi_enable_int(1);
  67678. + }
  67679. +
  67680. + wait_event_interruptible(cam->still_queue, cam->still_counter);
  67681. + csi_disable_int();
  67682. + err = copy_to_user(buf, cam->still_buf_vaddr,
  67683. + cam->v2f.fmt.pix.sizeimage);
  67684. +
  67685. + if (cam->still_buf_vaddr != NULL) {
  67686. + dma_free_coherent(0, PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  67687. + cam->still_buf_vaddr, cam->still_buf[0]);
  67688. + cam->still_buf[0] = 0;
  67689. + cam->still_buf_vaddr = NULL;
  67690. + }
  67691. +
  67692. + if (cam->overlay_on == true)
  67693. + start_preview(cam);
  67694. +
  67695. + up(&cam->busy_lock);
  67696. + if (err < 0)
  67697. + return err;
  67698. +
  67699. + return cam->v2f.fmt.pix.sizeimage - err;
  67700. +}
  67701. +
  67702. +/*!
  67703. + * V4L interface - ioctl function
  67704. + *
  67705. + * @param file struct file*
  67706. + *
  67707. + * @param ioctlnr unsigned int
  67708. + *
  67709. + * @param arg void*
  67710. + *
  67711. + * @return 0 success, ENODEV for invalid device instance,
  67712. + * -1 for other errors.
  67713. + */
  67714. +static long csi_v4l_do_ioctl(struct file *file,
  67715. + unsigned int ioctlnr, void *arg)
  67716. +{
  67717. + struct video_device *dev = video_devdata(file);
  67718. + cam_data *cam = video_get_drvdata(dev);
  67719. + int retval = 0;
  67720. + unsigned long lock_flags;
  67721. +
  67722. + pr_debug("In MVC: %s, %x\n", __func__, ioctlnr);
  67723. + wait_event_interruptible(cam->power_queue, cam->low_power == false);
  67724. + /* make this _really_ smp-safe */
  67725. + if (ioctlnr != VIDIOC_DQBUF)
  67726. + if (down_interruptible(&cam->busy_lock))
  67727. + return -EBUSY;
  67728. +
  67729. + switch (ioctlnr) {
  67730. + /*!
  67731. + * V4l2 VIDIOC_G_FMT ioctl
  67732. + */
  67733. + case VIDIOC_G_FMT:{
  67734. + struct v4l2_format *gf = arg;
  67735. + pr_debug(" case VIDIOC_G_FMT\n");
  67736. + retval = csi_v4l2_g_fmt(cam, gf);
  67737. + break;
  67738. + }
  67739. +
  67740. + /*!
  67741. + * V4l2 VIDIOC_S_FMT ioctl
  67742. + */
  67743. + case VIDIOC_S_FMT:{
  67744. + struct v4l2_format *sf = arg;
  67745. + pr_debug(" case VIDIOC_S_FMT\n");
  67746. + retval = csi_v4l2_s_fmt(cam, sf);
  67747. + vidioc_int_s_fmt_cap(cam->sensor, sf);
  67748. + break;
  67749. + }
  67750. +
  67751. + /*!
  67752. + * V4l2 VIDIOC_OVERLAY ioctl
  67753. + */
  67754. + case VIDIOC_OVERLAY:{
  67755. + int *on = arg;
  67756. + pr_debug(" case VIDIOC_OVERLAY\n");
  67757. + if (*on) {
  67758. + cam->overlay_on = true;
  67759. + cam->overlay_pid = current->pid;
  67760. + start_preview(cam);
  67761. + }
  67762. + if (!*on) {
  67763. + stop_preview(cam);
  67764. + cam->overlay_on = false;
  67765. + }
  67766. + break;
  67767. + }
  67768. +
  67769. + /*!
  67770. + * V4l2 VIDIOC_G_FBUF ioctl
  67771. + */
  67772. + case VIDIOC_G_FBUF:{
  67773. + struct v4l2_framebuffer *fb = arg;
  67774. + *fb = cam->v4l2_fb;
  67775. + fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
  67776. + break;
  67777. + }
  67778. +
  67779. + /*!
  67780. + * V4l2 VIDIOC_S_FBUF ioctl
  67781. + */
  67782. + case VIDIOC_S_FBUF:{
  67783. + struct v4l2_framebuffer *fb = arg;
  67784. + cam->v4l2_fb = *fb;
  67785. + break;
  67786. + }
  67787. +
  67788. + case VIDIOC_G_PARM:{
  67789. + struct v4l2_streamparm *parm = arg;
  67790. + pr_debug(" case VIDIOC_G_PARM\n");
  67791. + vidioc_int_g_parm(cam->sensor, parm);
  67792. + break;
  67793. + }
  67794. +
  67795. + case VIDIOC_S_PARM:{
  67796. + struct v4l2_streamparm *parm = arg;
  67797. + pr_debug(" case VIDIOC_S_PARM\n");
  67798. + retval = csi_v4l2_s_param(cam, parm);
  67799. + break;
  67800. + }
  67801. +
  67802. + case VIDIOC_QUERYCAP:{
  67803. + struct v4l2_capability *cap = arg;
  67804. + pr_debug(" case VIDIOC_QUERYCAP\n");
  67805. + strcpy(cap->driver, "csi_v4l2");
  67806. + cap->version = KERNEL_VERSION(0, 1, 11);
  67807. + cap->capabilities = V4L2_CAP_VIDEO_OVERLAY |
  67808. + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
  67809. + V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_READWRITE;
  67810. + cap->card[0] = '\0';
  67811. + cap->bus_info[0] = '\0';
  67812. + break;
  67813. + }
  67814. +
  67815. + case VIDIOC_CROPCAP:
  67816. + {
  67817. + struct v4l2_cropcap *cap = arg;
  67818. +
  67819. + if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  67820. + cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  67821. + retval = -EINVAL;
  67822. + break;
  67823. + }
  67824. + cap->bounds = cam->crop_bounds;
  67825. + cap->defrect = cam->crop_defrect;
  67826. + break;
  67827. + }
  67828. + case VIDIOC_S_CROP:
  67829. + {
  67830. + struct v4l2_crop *crop = arg;
  67831. + struct v4l2_rect *b = &cam->crop_bounds;
  67832. +
  67833. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  67834. + retval = -EINVAL;
  67835. + break;
  67836. + }
  67837. +
  67838. + crop->c.top = (crop->c.top < b->top) ? b->top
  67839. + : crop->c.top;
  67840. + if (crop->c.top > b->top + b->height)
  67841. + crop->c.top = b->top + b->height - 1;
  67842. + if (crop->c.height > b->top + b->height - crop->c.top)
  67843. + crop->c.height =
  67844. + b->top + b->height - crop->c.top;
  67845. +
  67846. + crop->c.left = (crop->c.left < b->left) ? b->left
  67847. + : crop->c.left;
  67848. + if (crop->c.left > b->left + b->width)
  67849. + crop->c.left = b->left + b->width - 1;
  67850. + if (crop->c.width > b->left - crop->c.left + b->width)
  67851. + crop->c.width =
  67852. + b->left - crop->c.left + b->width;
  67853. +
  67854. + crop->c.width -= crop->c.width % 8;
  67855. + crop->c.height -= crop->c.height % 8;
  67856. +
  67857. + crop_current.c = crop->c;
  67858. +
  67859. + break;
  67860. + }
  67861. + case VIDIOC_G_CROP:
  67862. + {
  67863. + struct v4l2_crop *crop = arg;
  67864. +
  67865. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  67866. + retval = -EINVAL;
  67867. + break;
  67868. + }
  67869. + crop->c = crop_current.c;
  67870. +
  67871. + break;
  67872. +
  67873. + }
  67874. + case VIDIOC_REQBUFS: {
  67875. + struct v4l2_requestbuffers *req = arg;
  67876. + pr_debug(" case VIDIOC_REQBUFS\n");
  67877. +
  67878. + if (req->count > FRAME_NUM) {
  67879. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  67880. + "not enough buffers\n");
  67881. + req->count = FRAME_NUM;
  67882. + }
  67883. +
  67884. + if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  67885. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  67886. + "wrong buffer type\n");
  67887. + retval = -EINVAL;
  67888. + break;
  67889. + }
  67890. +
  67891. + csi_streamoff(cam);
  67892. + if (req->memory & V4L2_MEMORY_MMAP) {
  67893. + csi_free_frame_buf(cam);
  67894. + retval = csi_allocate_frame_buf(cam, req->count + 1);
  67895. + req_buf_number = req->count;
  67896. + }
  67897. + break;
  67898. + }
  67899. +
  67900. + case VIDIOC_QUERYBUF: {
  67901. + struct v4l2_buffer *buf = arg;
  67902. + int index = buf->index;
  67903. + pr_debug(" case VIDIOC_QUERYBUF\n");
  67904. +
  67905. + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  67906. + retval = -EINVAL;
  67907. + break;
  67908. + }
  67909. +
  67910. + if (buf->memory & V4L2_MEMORY_MMAP) {
  67911. + memset(buf, 0, sizeof(buf));
  67912. + buf->index = index;
  67913. + }
  67914. +
  67915. + down(&cam->param_lock);
  67916. + if (buf->memory & V4L2_MEMORY_USERPTR) {
  67917. + csi_v4l2_release_bufs(cam);
  67918. + retval = csi_v4l2_prepare_bufs(cam, buf);
  67919. + }
  67920. + if (buf->memory & V4L2_MEMORY_MMAP)
  67921. + retval = csi_v4l2_buffer_status(cam, buf);
  67922. + up(&cam->param_lock);
  67923. + break;
  67924. + }
  67925. +
  67926. + case VIDIOC_QBUF: {
  67927. + struct v4l2_buffer *buf = arg;
  67928. + int index = buf->index;
  67929. + pr_debug(" case VIDIOC_QBUF\n");
  67930. +
  67931. + spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
  67932. + cam->frame[index].buffer.m.offset = buf->m.offset;
  67933. + if ((cam->frame[index].buffer.flags & 0x7) ==
  67934. + V4L2_BUF_FLAG_MAPPED) {
  67935. + cam->frame[index].buffer.flags |= V4L2_BUF_FLAG_QUEUED;
  67936. + list_add_tail(&cam->frame[index].queue, &cam->ready_q);
  67937. + } else if (cam->frame[index].buffer.flags &
  67938. + V4L2_BUF_FLAG_QUEUED) {
  67939. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  67940. + "buffer already queued\n");
  67941. + retval = -EINVAL;
  67942. + } else if (cam->frame[index].buffer.
  67943. + flags & V4L2_BUF_FLAG_DONE) {
  67944. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  67945. + "overwrite done buffer.\n");
  67946. + cam->frame[index].buffer.flags &=
  67947. + ~V4L2_BUF_FLAG_DONE;
  67948. + cam->frame[index].buffer.flags |=
  67949. + V4L2_BUF_FLAG_QUEUED;
  67950. + retval = -EINVAL;
  67951. + }
  67952. + buf->flags = cam->frame[index].buffer.flags;
  67953. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  67954. +
  67955. + break;
  67956. + }
  67957. +
  67958. + case VIDIOC_DQBUF: {
  67959. + struct v4l2_buffer *buf = arg;
  67960. + pr_debug(" case VIDIOC_DQBUF\n");
  67961. +
  67962. + retval = csi_v4l_dqueue(cam, buf);
  67963. +
  67964. + break;
  67965. + }
  67966. +
  67967. + case VIDIOC_STREAMON: {
  67968. + pr_debug(" case VIDIOC_STREAMON\n");
  67969. + retval = csi_streamon(cam);
  67970. + break;
  67971. + }
  67972. +
  67973. + case VIDIOC_STREAMOFF: {
  67974. + pr_debug(" case VIDIOC_STREAMOFF\n");
  67975. + retval = csi_streamoff(cam);
  67976. + break;
  67977. + }
  67978. + case VIDIOC_ENUM_FMT: {
  67979. + struct v4l2_fmtdesc *fmt = arg;
  67980. + if (cam->sensor)
  67981. + retval = vidioc_int_enum_fmt_cap(cam->sensor, fmt);
  67982. + else {
  67983. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  67984. + retval = -ENODEV;
  67985. + }
  67986. + break;
  67987. + }
  67988. + case VIDIOC_ENUM_FRAMESIZES: {
  67989. + struct v4l2_frmsizeenum *fsize = arg;
  67990. + if (cam->sensor)
  67991. + retval = vidioc_int_enum_framesizes(cam->sensor, fsize);
  67992. + else {
  67993. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  67994. + retval = -ENODEV;
  67995. + }
  67996. + break;
  67997. + }
  67998. + case VIDIOC_ENUM_FRAMEINTERVALS: {
  67999. + struct v4l2_frmivalenum *fival = arg;
  68000. + if (cam->sensor)
  68001. + retval = vidioc_int_enum_frameintervals(cam->sensor,
  68002. + fival);
  68003. + else {
  68004. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  68005. + retval = -ENODEV;
  68006. + }
  68007. + break;
  68008. + }
  68009. + case VIDIOC_DBG_G_CHIP_IDENT: {
  68010. + struct v4l2_dbg_chip_ident *p = arg;
  68011. + p->ident = V4L2_IDENT_NONE;
  68012. + p->revision = 0;
  68013. + if (cam->sensor)
  68014. + retval = vidioc_int_g_chip_ident(cam->sensor, (int *)p);
  68015. + else {
  68016. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  68017. + retval = -ENODEV;
  68018. + }
  68019. + break;
  68020. + }
  68021. +
  68022. + case VIDIOC_S_CTRL:
  68023. + {
  68024. + struct v4l2_control *vc = arg;
  68025. + int i;
  68026. +
  68027. + for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
  68028. + if (vc->id == pxp_controls[i].id) {
  68029. + if (vc->value < pxp_controls[i].minimum ||
  68030. + vc->value > pxp_controls[i].maximum) {
  68031. + retval = -ERANGE;
  68032. + break;
  68033. + }
  68034. + retval = pxp_set_cstate(cam, vc);
  68035. + break;
  68036. + }
  68037. +
  68038. + if (i >= ARRAY_SIZE(pxp_controls))
  68039. + retval = -EINVAL;
  68040. + break;
  68041. +
  68042. + }
  68043. + case VIDIOC_G_CTRL:
  68044. + {
  68045. + struct v4l2_control *vc = arg;
  68046. + int i;
  68047. +
  68048. + for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
  68049. + if (vc->id == pxp_controls[i].id) {
  68050. + retval = pxp_get_cstate(cam, vc);
  68051. + break;
  68052. + }
  68053. +
  68054. + if (i >= ARRAY_SIZE(pxp_controls))
  68055. + retval = -EINVAL;
  68056. + break;
  68057. + }
  68058. + case VIDIOC_QUERYCTRL:
  68059. + {
  68060. + struct v4l2_queryctrl *qc = arg;
  68061. + int i;
  68062. +
  68063. + for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
  68064. + if (qc->id && qc->id == pxp_controls[i].id) {
  68065. + memcpy(qc, &(pxp_controls[i]), sizeof(*qc));
  68066. + break;
  68067. + }
  68068. +
  68069. + if (i >= ARRAY_SIZE(pxp_controls))
  68070. + retval = -EINVAL;
  68071. + break;
  68072. + }
  68073. + case VIDIOC_G_STD:
  68074. + case VIDIOC_G_OUTPUT:
  68075. + case VIDIOC_S_OUTPUT:
  68076. + case VIDIOC_ENUMSTD:
  68077. + case VIDIOC_S_STD:
  68078. + case VIDIOC_TRY_FMT:
  68079. + case VIDIOC_ENUMINPUT:
  68080. + case VIDIOC_G_INPUT:
  68081. + case VIDIOC_S_INPUT:
  68082. + case VIDIOC_G_TUNER:
  68083. + case VIDIOC_S_TUNER:
  68084. + case VIDIOC_G_FREQUENCY:
  68085. + case VIDIOC_S_FREQUENCY:
  68086. + case VIDIOC_ENUMOUTPUT:
  68087. + default:
  68088. + pr_debug(" case not supported\n");
  68089. + retval = -EINVAL;
  68090. + break;
  68091. + }
  68092. +
  68093. + if (ioctlnr != VIDIOC_DQBUF)
  68094. + up(&cam->busy_lock);
  68095. + return retval;
  68096. +}
  68097. +
  68098. +/*
  68099. + * V4L interface - ioctl function
  68100. + *
  68101. + * @return None
  68102. + */
  68103. +static long csi_v4l_ioctl(struct file *file,
  68104. + unsigned int cmd, unsigned long arg)
  68105. +{
  68106. + return video_usercopy(file, cmd, arg, csi_v4l_do_ioctl);
  68107. +}
  68108. +
  68109. +/*!
  68110. + * V4L interface - mmap function
  68111. + *
  68112. + * @param file structure file *
  68113. + *
  68114. + * @param vma structure vm_area_struct *
  68115. + *
  68116. + * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error
  68117. + */
  68118. +static int csi_mmap(struct file *file, struct vm_area_struct *vma)
  68119. +{
  68120. + struct video_device *dev = video_devdata(file);
  68121. + unsigned long size;
  68122. + int res = 0;
  68123. + cam_data *cam = video_get_drvdata(dev);
  68124. +
  68125. + pr_debug("%s\n", __func__);
  68126. + pr_debug("\npgoff=0x%lx, start=0x%lx, end=0x%lx\n",
  68127. + vma->vm_pgoff, vma->vm_start, vma->vm_end);
  68128. +
  68129. + /* make this _really_ smp-safe */
  68130. + if (down_interruptible(&cam->busy_lock))
  68131. + return -EINTR;
  68132. +
  68133. + size = vma->vm_end - vma->vm_start;
  68134. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  68135. +
  68136. + if (remap_pfn_range(vma, vma->vm_start,
  68137. + vma->vm_pgoff, size, vma->vm_page_prot)) {
  68138. + pr_err("ERROR: v4l2 capture: %s : "
  68139. + "remap_pfn_range failed\n", __func__);
  68140. + res = -ENOBUFS;
  68141. + goto csi_mmap_exit;
  68142. + }
  68143. +
  68144. + vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
  68145. +
  68146. +csi_mmap_exit:
  68147. + up(&cam->busy_lock);
  68148. + return res;
  68149. +}
  68150. +
  68151. +/*!
  68152. + * This structure defines the functions to be called in this driver.
  68153. + */
  68154. +static struct v4l2_file_operations csi_v4l_fops = {
  68155. + .owner = THIS_MODULE,
  68156. + .open = csi_v4l_open,
  68157. + .release = csi_v4l_close,
  68158. + .read = csi_v4l_read,
  68159. + .ioctl = csi_v4l_ioctl,
  68160. + .mmap = csi_mmap,
  68161. +};
  68162. +
  68163. +static struct video_device csi_v4l_template = {
  68164. + .name = "Mx25 Camera",
  68165. + .fops = &csi_v4l_fops,
  68166. + .release = video_device_release,
  68167. +};
  68168. +
  68169. +/*!
  68170. + * initialize cam_data structure
  68171. + *
  68172. + * @param cam structure cam_data *
  68173. + *
  68174. + * @return status 0 Success
  68175. + */
  68176. +static void init_camera_struct(cam_data *cam)
  68177. +{
  68178. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  68179. + pr_debug("In MVC: %s\n", __func__);
  68180. +
  68181. + proc_data->hflip = 0;
  68182. + proc_data->vflip = 0;
  68183. + proc_data->rotate = 0;
  68184. + proc_data->bgcolor = 0;
  68185. +
  68186. + /* Default everything to 0 */
  68187. + memset(cam, 0, sizeof(cam_data));
  68188. +
  68189. + sema_init(&cam->param_lock, 1);
  68190. + sema_init(&cam->busy_lock, 1);
  68191. +
  68192. + cam->video_dev = video_device_alloc();
  68193. + if (cam->video_dev == NULL)
  68194. + return;
  68195. +
  68196. + *(cam->video_dev) = csi_v4l_template;
  68197. +
  68198. + video_set_drvdata(cam->video_dev, cam);
  68199. + cam->video_dev->minor = -1;
  68200. +
  68201. + init_waitqueue_head(&cam->enc_queue);
  68202. + init_waitqueue_head(&cam->still_queue);
  68203. +
  68204. + cam->streamparm.parm.capture.capturemode = 0;
  68205. +
  68206. + cam->standard.index = 0;
  68207. + cam->standard.id = V4L2_STD_UNKNOWN;
  68208. + cam->standard.frameperiod.denominator = 30;
  68209. + cam->standard.frameperiod.numerator = 1;
  68210. + cam->standard.framelines = 480;
  68211. + cam->standard_autodetect = true;
  68212. + cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  68213. + cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
  68214. + cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
  68215. + cam->overlay_on = false;
  68216. + cam->capture_on = false;
  68217. + cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
  68218. +
  68219. + cam->v2f.fmt.pix.sizeimage = 480 * 640 * 2;
  68220. + cam->v2f.fmt.pix.bytesperline = 640 * 2;
  68221. + cam->v2f.fmt.pix.width = 640;
  68222. + cam->v2f.fmt.pix.height = 480;
  68223. + cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
  68224. + cam->win.w.width = 160;
  68225. + cam->win.w.height = 160;
  68226. + cam->win.w.left = 0;
  68227. + cam->win.w.top = 0;
  68228. + cam->still_counter = 0;
  68229. + /* setup cropping */
  68230. + cam->crop_bounds.left = 0;
  68231. + cam->crop_bounds.width = 640;
  68232. + cam->crop_bounds.top = 0;
  68233. + cam->crop_bounds.height = 480;
  68234. + cam->crop_current = cam->crop_defrect = cam->crop_bounds;
  68235. +
  68236. + cam->enc_callback = camera_callback;
  68237. + csi_start_callback(cam);
  68238. + init_waitqueue_head(&cam->power_queue);
  68239. + spin_lock_init(&cam->queue_int_lock);
  68240. + spin_lock_init(&cam->dqueue_int_lock);
  68241. +}
  68242. +
  68243. +/*!
  68244. + * camera_power function
  68245. + * Turns Sensor power On/Off
  68246. + *
  68247. + * @param cam cam data struct
  68248. + * @param cameraOn true to turn camera on, false to turn off power.
  68249. + *
  68250. + * @return status
  68251. + */
  68252. +static u8 camera_power(cam_data *cam, bool cameraOn)
  68253. +{
  68254. + pr_debug("In MVC: %s on=%d\n", __func__, cameraOn);
  68255. +
  68256. + if (cameraOn == true) {
  68257. + vidioc_int_s_power(cam->sensor, 1);
  68258. + } else {
  68259. + vidioc_int_s_power(cam->sensor, 0);
  68260. + }
  68261. + return 0;
  68262. +}
  68263. +
  68264. +static const struct of_device_id imx_csi_v4l2_dt_ids[] = {
  68265. + { .compatible = "fsl,imx6sl-csi-v4l2", },
  68266. + { /* sentinel */ }
  68267. +};
  68268. +MODULE_DEVICE_TABLE(of, imx_csi_v4l2_dt_ids);
  68269. +
  68270. +static int csi_v4l2_probe(struct platform_device *pdev)
  68271. +{
  68272. + struct scatterlist *sg;
  68273. + u8 err = 0;
  68274. +
  68275. + /* Create g_cam and initialize it. */
  68276. + g_cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
  68277. + if (g_cam == NULL) {
  68278. + pr_err("ERROR: v4l2 capture: failed to register camera\n");
  68279. + err = -ENOMEM;
  68280. + goto out;
  68281. + }
  68282. + memset(&crop_current, 0, sizeof(crop_current));
  68283. + memset(&win_current, 0, sizeof(win_current));
  68284. + init_camera_struct(g_cam);
  68285. + platform_set_drvdata(pdev, (void *)g_cam);
  68286. +
  68287. + /* Set up the v4l2 device and register it */
  68288. + csi_v4l2_int_device.priv = g_cam;
  68289. + /* This function contains a bug that won't let this be rmmod'd. */
  68290. + v4l2_int_device_register(&csi_v4l2_int_device);
  68291. +
  68292. + /* register v4l video device */
  68293. + if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr)
  68294. + == -1) {
  68295. + kfree(g_cam);
  68296. + g_cam = NULL;
  68297. + pr_err("ERROR: v4l2 capture: video_register_device failed\n");
  68298. + err = -ENODEV;
  68299. + goto out;
  68300. + }
  68301. + pr_debug(" Video device registered: %s #%d\n",
  68302. + g_cam->video_dev->name, g_cam->video_dev->minor);
  68303. +
  68304. + g_cam->pxp_chan = NULL;
  68305. + /* Initialize Scatter-gather list containing 2 buffer addresses. */
  68306. + sg = g_cam->sg;
  68307. + sg_init_table(sg, 2);
  68308. +
  68309. +out:
  68310. + return err;
  68311. +}
  68312. +
  68313. +static int csi_v4l2_remove(struct platform_device *pdev)
  68314. +{
  68315. + if (g_cam->open_count) {
  68316. + pr_err("ERROR: v4l2 capture:camera open "
  68317. + "-- setting ops to NULL\n");
  68318. + } else {
  68319. + pr_info("V4L2 freeing image input device\n");
  68320. + v4l2_int_device_unregister(&csi_v4l2_int_device);
  68321. + csi_stop_callback(g_cam);
  68322. + video_unregister_device(g_cam->video_dev);
  68323. + platform_set_drvdata(pdev, NULL);
  68324. +
  68325. + kfree(g_cam);
  68326. + g_cam = NULL;
  68327. + }
  68328. +
  68329. + return 0;
  68330. +}
  68331. +
  68332. +/*!
  68333. + * This function is called to put the sensor in a low power state.
  68334. + * Refer to the document driver-model/driver.txt in the kernel source tree
  68335. + * for more information.
  68336. + *
  68337. + * @param pdev the device structure used to give information on which I2C
  68338. + * to suspend
  68339. + * @param state the power state the device is entering
  68340. + *
  68341. + * @return The function returns 0 on success and -1 on failure.
  68342. + */
  68343. +static int csi_v4l2_suspend(struct platform_device *pdev, pm_message_t state)
  68344. +{
  68345. + cam_data *cam = platform_get_drvdata(pdev);
  68346. +
  68347. + pr_debug("In MVC: %s\n", __func__);
  68348. +
  68349. + if (cam == NULL)
  68350. + return -1;
  68351. +
  68352. + cam->low_power = true;
  68353. +
  68354. + if (cam->overlay_on == true)
  68355. + stop_preview(cam);
  68356. +
  68357. + if (cam->capture_on == true || cam->overlay_on == true)
  68358. + camera_power(cam, false);
  68359. +
  68360. + return 0;
  68361. +}
  68362. +
  68363. +/*!
  68364. + * This function is called to bring the sensor back from a low power state.
  68365. + * Refer to the document driver-model/driver.txt in the kernel source tree
  68366. + * for more information.
  68367. + *
  68368. + * @param pdev the device structure
  68369. + *
  68370. + * @return The function returns 0 on success and -1 on failure
  68371. + */
  68372. +static int csi_v4l2_resume(struct platform_device *pdev)
  68373. +{
  68374. + cam_data *cam = platform_get_drvdata(pdev);
  68375. +
  68376. + pr_debug("In MVC: %s\n", __func__);
  68377. +
  68378. + if (cam == NULL)
  68379. + return -1;
  68380. +
  68381. + cam->low_power = false;
  68382. + wake_up_interruptible(&cam->power_queue);
  68383. + if (cam->capture_on == true || cam->overlay_on == true)
  68384. + camera_power(cam, true);
  68385. +
  68386. + if (cam->overlay_on == true)
  68387. + start_preview(cam);
  68388. +
  68389. + return 0;
  68390. +}
  68391. +
  68392. +/*!
  68393. + * This structure contains pointers to the power management callback functions.
  68394. + */
  68395. +static struct platform_driver csi_v4l2_driver = {
  68396. + .driver = {
  68397. + .name = "csi_v4l2",
  68398. + .of_match_table = of_match_ptr(imx_csi_v4l2_dt_ids),
  68399. + },
  68400. + .probe = csi_v4l2_probe,
  68401. + .remove = csi_v4l2_remove,
  68402. +#ifdef CONFIG_PM
  68403. + .suspend = csi_v4l2_suspend,
  68404. + .resume = csi_v4l2_resume,
  68405. +#endif
  68406. + .shutdown = NULL,
  68407. +};
  68408. +
  68409. +/*!
  68410. + * Initializes the camera driver.
  68411. + */
  68412. +static int csi_v4l2_master_attach(struct v4l2_int_device *slave)
  68413. +{
  68414. + cam_data *cam = slave->u.slave->master->priv;
  68415. + struct v4l2_format cam_fmt;
  68416. +
  68417. + pr_debug("In MVC: %s\n", __func__);
  68418. + pr_debug(" slave.name = %s\n", slave->name);
  68419. + pr_debug(" master.name = %s\n", slave->u.slave->master->name);
  68420. +
  68421. + cam->sensor = slave;
  68422. + if (slave == NULL) {
  68423. + pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
  68424. + return -1;
  68425. + }
  68426. +
  68427. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  68428. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  68429. +
  68430. + /* Used to detect TV in (type 1) vs. camera (type 0) */
  68431. + cam->device_type = cam_fmt.fmt.pix.priv;
  68432. +
  68433. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  68434. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  68435. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  68436. +
  68437. + /* This also is the max crop size for this device. */
  68438. + cam->crop_defrect.top = cam->crop_defrect.left = 0;
  68439. + cam->crop_defrect.width = cam_fmt.fmt.pix.width;
  68440. + cam->crop_defrect.height = cam_fmt.fmt.pix.height;
  68441. +
  68442. + /* At this point, this is also the current image size. */
  68443. + cam->crop_current.top = cam->crop_current.left = 0;
  68444. + cam->crop_current.width = cam_fmt.fmt.pix.width;
  68445. + cam->crop_current.height = cam_fmt.fmt.pix.height;
  68446. +
  68447. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  68448. + __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  68449. +
  68450. + return 0;
  68451. +}
  68452. +
  68453. +/*!
  68454. + * Disconnects the camera driver.
  68455. + */
  68456. +static void csi_v4l2_master_detach(struct v4l2_int_device *slave)
  68457. +{
  68458. + pr_debug("In MVC: %s\n", __func__);
  68459. +
  68460. + vidioc_int_dev_exit(slave);
  68461. +}
  68462. +
  68463. +module_platform_driver(csi_v4l2_driver);
  68464. +
  68465. +module_param(video_nr, int, 0444);
  68466. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  68467. +MODULE_DESCRIPTION("V4L2 capture driver for Mx25 based cameras");
  68468. +MODULE_LICENSE("GPL");
  68469. +MODULE_SUPPORTED_DEVICE("video");
  68470. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/fsl_csi.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/fsl_csi.c
  68471. --- linux-3.14.15/drivers/media/platform/mxc/capture/fsl_csi.c 1970-01-01 01:00:00.000000000 +0100
  68472. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/fsl_csi.c 2014-08-20 19:23:52.814842662 +0200
  68473. @@ -0,0 +1,302 @@
  68474. +/*
  68475. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  68476. + */
  68477. +
  68478. +/*
  68479. + * The code contained herein is licensed under the GNU General Public
  68480. + * License. You may obtain a copy of the GNU General Public License
  68481. + * Version 2 or later at the following locations:
  68482. + *
  68483. + * http://www.opensource.org/licenses/gpl-license.html
  68484. + * http://www.gnu.org/copyleft/gpl.html
  68485. + */
  68486. +
  68487. +/*!
  68488. + * @file fsl_csi.c, this file is derived from mx27_csi.c
  68489. + *
  68490. + * @brief mx25 CMOS Sensor interface functions
  68491. + *
  68492. + * @ingroup CSI
  68493. + */
  68494. +#include <linux/types.h>
  68495. +#include <linux/init.h>
  68496. +#include <linux/platform_device.h>
  68497. +#include <linux/device.h>
  68498. +#include <linux/err.h>
  68499. +#include <linux/interrupt.h>
  68500. +#include <linux/spinlock.h>
  68501. +#include <linux/module.h>
  68502. +#include <linux/clk.h>
  68503. +#include <linux/of.h>
  68504. +#include <linux/sched.h>
  68505. +
  68506. +#include "mxc_v4l2_capture.h"
  68507. +#include "fsl_csi.h"
  68508. +
  68509. +void __iomem *csi_regbase;
  68510. +EXPORT_SYMBOL(csi_regbase);
  68511. +static int irq_nr;
  68512. +static csi_irq_callback_t g_callback;
  68513. +static void *g_callback_data;
  68514. +
  68515. +static irqreturn_t csi_irq_handler(int irq, void *data)
  68516. +{
  68517. + cam_data *cam = (cam_data *) data;
  68518. + unsigned long status = __raw_readl(CSI_CSISR);
  68519. +
  68520. + __raw_writel(status, CSI_CSISR);
  68521. +
  68522. + if (status & BIT_HRESP_ERR_INT)
  68523. + pr_warning("Hresponse error is detected.\n");
  68524. +
  68525. + if (status & BIT_DMA_TSF_DONE_FB1) {
  68526. + if (cam->capture_on) {
  68527. + spin_lock(&cam->queue_int_lock);
  68528. + cam->ping_pong_csi = 1;
  68529. + spin_unlock(&cam->queue_int_lock);
  68530. + cam->enc_callback(0, cam);
  68531. + } else {
  68532. + cam->still_counter++;
  68533. + wake_up_interruptible(&cam->still_queue);
  68534. + }
  68535. + }
  68536. +
  68537. + if (status & BIT_DMA_TSF_DONE_FB2) {
  68538. + if (cam->capture_on) {
  68539. + spin_lock(&cam->queue_int_lock);
  68540. + cam->ping_pong_csi = 2;
  68541. + spin_unlock(&cam->queue_int_lock);
  68542. + cam->enc_callback(0, cam);
  68543. + } else {
  68544. + cam->still_counter++;
  68545. + wake_up_interruptible(&cam->still_queue);
  68546. + }
  68547. + }
  68548. +
  68549. + if (g_callback)
  68550. + g_callback(g_callback_data, status);
  68551. +
  68552. + pr_debug("CSI status = 0x%08lX\n", status);
  68553. +
  68554. + return IRQ_HANDLED;
  68555. +}
  68556. +
  68557. +static void csihw_reset_frame_count(void)
  68558. +{
  68559. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_FRMCNT_RST, CSI_CSICR3);
  68560. +}
  68561. +
  68562. +static void csihw_reset(void)
  68563. +{
  68564. + csihw_reset_frame_count();
  68565. + __raw_writel(CSICR1_RESET_VAL, CSI_CSICR1);
  68566. + __raw_writel(CSICR2_RESET_VAL, CSI_CSICR2);
  68567. + __raw_writel(CSICR3_RESET_VAL, CSI_CSICR3);
  68568. +}
  68569. +
  68570. +/*!
  68571. + * csi_init_interface
  68572. + * Init csi interface
  68573. + */
  68574. +void csi_init_interface(void)
  68575. +{
  68576. + unsigned int val = 0;
  68577. + unsigned int imag_para;
  68578. +
  68579. + val |= BIT_SOF_POL;
  68580. + val |= BIT_REDGE;
  68581. + val |= BIT_GCLK_MODE;
  68582. + val |= BIT_HSYNC_POL;
  68583. + val |= BIT_PACK_DIR;
  68584. + val |= BIT_FCC;
  68585. + val |= BIT_SWAP16_EN;
  68586. + val |= 1 << SHIFT_MCLKDIV;
  68587. + val |= BIT_MCLKEN;
  68588. + __raw_writel(val, CSI_CSICR1);
  68589. +
  68590. + imag_para = (640 << 16) | 960;
  68591. + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  68592. +
  68593. + val = 0x1010;
  68594. + val |= BIT_DMA_REFLASH_RFF;
  68595. + __raw_writel(val, CSI_CSICR3);
  68596. +}
  68597. +EXPORT_SYMBOL(csi_init_interface);
  68598. +
  68599. +void csi_init_format(int fmt)
  68600. +{
  68601. + unsigned int val;
  68602. +
  68603. + val = __raw_readl(CSI_CSICR1);
  68604. + if (fmt == V4L2_PIX_FMT_YUYV) {
  68605. + val &= ~BIT_PACK_DIR;
  68606. + val &= ~BIT_SWAP16_EN;
  68607. + } else if (fmt == V4L2_PIX_FMT_UYVY) {
  68608. + val |= BIT_PACK_DIR;
  68609. + val |= BIT_SWAP16_EN;
  68610. + } else
  68611. + pr_warning("unsupported format, old format remains.\n");
  68612. +
  68613. + __raw_writel(val, CSI_CSICR1);
  68614. +}
  68615. +EXPORT_SYMBOL(csi_init_format);
  68616. +
  68617. +/*!
  68618. + * csi_read_mclk_flag
  68619. + *
  68620. + * @return gcsi_mclk_source
  68621. + */
  68622. +int csi_read_mclk_flag(void)
  68623. +{
  68624. + return 0;
  68625. +}
  68626. +EXPORT_SYMBOL(csi_read_mclk_flag);
  68627. +
  68628. +void csi_start_callback(void *data)
  68629. +{
  68630. + cam_data *cam = (cam_data *) data;
  68631. +
  68632. + if (request_irq(irq_nr, csi_irq_handler, 0, "csi", cam) < 0)
  68633. + pr_debug("CSI error: irq request fail\n");
  68634. +
  68635. +}
  68636. +EXPORT_SYMBOL(csi_start_callback);
  68637. +
  68638. +void csi_stop_callback(void *data)
  68639. +{
  68640. + cam_data *cam = (cam_data *) data;
  68641. +
  68642. + free_irq(irq_nr, cam);
  68643. +}
  68644. +EXPORT_SYMBOL(csi_stop_callback);
  68645. +
  68646. +void csi_enable_int(int arg)
  68647. +{
  68648. + unsigned long cr1 = __raw_readl(CSI_CSICR1);
  68649. +
  68650. + cr1 |= BIT_SOF_INTEN;
  68651. + if (arg == 1) {
  68652. + /* still capture needs DMA intterrupt */
  68653. + cr1 |= BIT_FB1_DMA_DONE_INTEN;
  68654. + cr1 |= BIT_FB2_DMA_DONE_INTEN;
  68655. + }
  68656. + __raw_writel(cr1, CSI_CSICR1);
  68657. +}
  68658. +EXPORT_SYMBOL(csi_enable_int);
  68659. +
  68660. +void csi_disable_int(void)
  68661. +{
  68662. + unsigned long cr1 = __raw_readl(CSI_CSICR1);
  68663. +
  68664. + cr1 &= ~BIT_SOF_INTEN;
  68665. + cr1 &= ~BIT_FB1_DMA_DONE_INTEN;
  68666. + cr1 &= ~BIT_FB2_DMA_DONE_INTEN;
  68667. + __raw_writel(cr1, CSI_CSICR1);
  68668. +}
  68669. +EXPORT_SYMBOL(csi_disable_int);
  68670. +
  68671. +void csi_set_16bit_imagpara(int width, int height)
  68672. +{
  68673. + int imag_para = 0;
  68674. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  68675. +
  68676. + imag_para = (width << 16) | (height * 2);
  68677. + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  68678. +
  68679. + /* reflash the embeded DMA controller */
  68680. + __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  68681. +}
  68682. +EXPORT_SYMBOL(csi_set_16bit_imagpara);
  68683. +
  68684. +void csi_set_12bit_imagpara(int width, int height)
  68685. +{
  68686. + int imag_para = 0;
  68687. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  68688. +
  68689. + imag_para = (width << 16) | (height * 3 / 2);
  68690. + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  68691. +
  68692. + /* reflash the embeded DMA controller */
  68693. + __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  68694. +}
  68695. +EXPORT_SYMBOL(csi_set_12bit_imagpara);
  68696. +
  68697. +void csi_dmareq_rff_enable(void)
  68698. +{
  68699. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  68700. +
  68701. + cr3 |= BIT_DMA_REQ_EN_RFF;
  68702. + cr3 |= BIT_HRESP_ERR_EN;
  68703. + __raw_writel(cr3, CSI_CSICR3);
  68704. +}
  68705. +EXPORT_SYMBOL(csi_dmareq_rff_enable);
  68706. +
  68707. +void csi_dmareq_rff_disable(void)
  68708. +{
  68709. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  68710. +
  68711. + cr3 &= ~BIT_DMA_REQ_EN_RFF;
  68712. + cr3 &= ~BIT_HRESP_ERR_EN;
  68713. + __raw_writel(cr3, CSI_CSICR3);
  68714. +}
  68715. +EXPORT_SYMBOL(csi_dmareq_rff_disable);
  68716. +
  68717. +static const struct of_device_id fsl_csi_dt_ids[] = {
  68718. + { .compatible = "fsl,imx6sl-csi", },
  68719. + { /* sentinel */ }
  68720. +};
  68721. +MODULE_DEVICE_TABLE(of, fsl_csi_dt_ids);
  68722. +
  68723. +static int csi_probe(struct platform_device *pdev)
  68724. +{
  68725. + int ret = 0;
  68726. + struct resource *res;
  68727. +
  68728. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  68729. + if (!res) {
  68730. + dev_err(&pdev->dev, "No csi irq found.\n");
  68731. + ret = -ENODEV;
  68732. + goto err;
  68733. + }
  68734. + irq_nr = res->start;
  68735. +
  68736. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  68737. + if (!res) {
  68738. + dev_err(&pdev->dev, "No csi base address found.\n");
  68739. + ret = -ENODEV;
  68740. + goto err;
  68741. + }
  68742. + csi_regbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
  68743. + if (!csi_regbase) {
  68744. + dev_err(&pdev->dev, "ioremap failed with csi base\n");
  68745. + ret = -ENOMEM;
  68746. + goto err;
  68747. + }
  68748. +
  68749. + csihw_reset();
  68750. + csi_init_interface();
  68751. + csi_dmareq_rff_disable();
  68752. +
  68753. +err:
  68754. + return ret;
  68755. +}
  68756. +
  68757. +static int csi_remove(struct platform_device *pdev)
  68758. +{
  68759. + return 0;
  68760. +}
  68761. +
  68762. +static struct platform_driver csi_driver = {
  68763. + .driver = {
  68764. + .name = "fsl_csi",
  68765. + .of_match_table = of_match_ptr(fsl_csi_dt_ids),
  68766. + },
  68767. + .probe = csi_probe,
  68768. + .remove = csi_remove,
  68769. +};
  68770. +
  68771. +module_platform_driver(csi_driver);
  68772. +
  68773. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  68774. +MODULE_DESCRIPTION("fsl CSI driver");
  68775. +MODULE_LICENSE("GPL");
  68776. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/fsl_csi.h linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/fsl_csi.h
  68777. --- linux-3.14.15/drivers/media/platform/mxc/capture/fsl_csi.h 1970-01-01 01:00:00.000000000 +0100
  68778. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/fsl_csi.h 2014-08-20 19:23:52.814842662 +0200
  68779. @@ -0,0 +1,198 @@
  68780. +/*
  68781. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  68782. + */
  68783. +
  68784. +/*
  68785. + * The code contained herein is licensed under the GNU General Public
  68786. + * License. You may obtain a copy of the GNU General Public License
  68787. + * Version 2 or later at the following locations:
  68788. + *
  68789. + * http://www.opensource.org/licenses/gpl-license.html
  68790. + * http://www.gnu.org/copyleft/gpl.html
  68791. + */
  68792. +
  68793. +/*!
  68794. + * @file fsl_csi.h
  68795. + *
  68796. + * @brief mx25 CMOS Sensor interface functions
  68797. + *
  68798. + * @ingroup CSI
  68799. + */
  68800. +
  68801. +#ifndef MX25_CSI_H
  68802. +#define MX25_CSI_H
  68803. +
  68804. +#include <linux/io.h>
  68805. +
  68806. +/* reset values */
  68807. +#define CSICR1_RESET_VAL 0x40000800
  68808. +#define CSICR2_RESET_VAL 0x0
  68809. +#define CSICR3_RESET_VAL 0x0
  68810. +
  68811. +/* csi control reg 1 */
  68812. +#define BIT_SWAP16_EN (0x1 << 31)
  68813. +#define BIT_EXT_VSYNC (0x1 << 30)
  68814. +#define BIT_EOF_INT_EN (0x1 << 29)
  68815. +#define BIT_PRP_IF_EN (0x1 << 28)
  68816. +#define BIT_CCIR_MODE (0x1 << 27)
  68817. +#define BIT_COF_INT_EN (0x1 << 26)
  68818. +#define BIT_SF_OR_INTEN (0x1 << 25)
  68819. +#define BIT_RF_OR_INTEN (0x1 << 24)
  68820. +#define BIT_SFF_DMA_DONE_INTEN (0x1 << 22)
  68821. +#define BIT_STATFF_INTEN (0x1 << 21)
  68822. +#define BIT_FB2_DMA_DONE_INTEN (0x1 << 20)
  68823. +#define BIT_FB1_DMA_DONE_INTEN (0x1 << 19)
  68824. +#define BIT_RXFF_INTEN (0x1 << 18)
  68825. +#define BIT_SOF_POL (0x1 << 17)
  68826. +#define BIT_SOF_INTEN (0x1 << 16)
  68827. +#define BIT_MCLKDIV (0xF << 12)
  68828. +#define BIT_HSYNC_POL (0x1 << 11)
  68829. +#define BIT_CCIR_EN (0x1 << 10)
  68830. +#define BIT_MCLKEN (0x1 << 9)
  68831. +#define BIT_FCC (0x1 << 8)
  68832. +#define BIT_PACK_DIR (0x1 << 7)
  68833. +#define BIT_CLR_STATFIFO (0x1 << 6)
  68834. +#define BIT_CLR_RXFIFO (0x1 << 5)
  68835. +#define BIT_GCLK_MODE (0x1 << 4)
  68836. +#define BIT_INV_DATA (0x1 << 3)
  68837. +#define BIT_INV_PCLK (0x1 << 2)
  68838. +#define BIT_REDGE (0x1 << 1)
  68839. +#define BIT_PIXEL_BIT (0x1 << 0)
  68840. +
  68841. +#define SHIFT_MCLKDIV 12
  68842. +
  68843. +/* control reg 3 */
  68844. +#define BIT_FRMCNT (0xFFFF << 16)
  68845. +#define BIT_FRMCNT_RST (0x1 << 15)
  68846. +#define BIT_DMA_REFLASH_RFF (0x1 << 14)
  68847. +#define BIT_DMA_REFLASH_SFF (0x1 << 13)
  68848. +#define BIT_DMA_REQ_EN_RFF (0x1 << 12)
  68849. +#define BIT_DMA_REQ_EN_SFF (0x1 << 11)
  68850. +#define BIT_STATFF_LEVEL (0x7 << 8)
  68851. +#define BIT_HRESP_ERR_EN (0x1 << 7)
  68852. +#define BIT_RXFF_LEVEL (0x7 << 4)
  68853. +#define BIT_TWO_8BIT_SENSOR (0x1 << 3)
  68854. +#define BIT_ZERO_PACK_EN (0x1 << 2)
  68855. +#define BIT_ECC_INT_EN (0x1 << 1)
  68856. +#define BIT_ECC_AUTO_EN (0x1 << 0)
  68857. +
  68858. +#define SHIFT_FRMCNT 16
  68859. +
  68860. +/* csi status reg */
  68861. +#define BIT_SFF_OR_INT (0x1 << 25)
  68862. +#define BIT_RFF_OR_INT (0x1 << 24)
  68863. +#define BIT_DMA_TSF_DONE_SFF (0x1 << 22)
  68864. +#define BIT_STATFF_INT (0x1 << 21)
  68865. +#define BIT_DMA_TSF_DONE_FB2 (0x1 << 20)
  68866. +#define BIT_DMA_TSF_DONE_FB1 (0x1 << 19)
  68867. +#define BIT_RXFF_INT (0x1 << 18)
  68868. +#define BIT_EOF_INT (0x1 << 17)
  68869. +#define BIT_SOF_INT (0x1 << 16)
  68870. +#define BIT_F2_INT (0x1 << 15)
  68871. +#define BIT_F1_INT (0x1 << 14)
  68872. +#define BIT_COF_INT (0x1 << 13)
  68873. +#define BIT_HRESP_ERR_INT (0x1 << 7)
  68874. +#define BIT_ECC_INT (0x1 << 1)
  68875. +#define BIT_DRDY (0x1 << 0)
  68876. +
  68877. +#define CSI_MCLK_VF 1
  68878. +#define CSI_MCLK_ENC 2
  68879. +#define CSI_MCLK_RAW 4
  68880. +#define CSI_MCLK_I2C 8
  68881. +#endif
  68882. +
  68883. +extern void __iomem *csi_regbase;
  68884. +#define CSI_CSICR1 (csi_regbase)
  68885. +#define CSI_CSICR2 (csi_regbase + 0x4)
  68886. +#define CSI_CSICR3 (csi_regbase + 0x8)
  68887. +#define CSI_STATFIFO (csi_regbase + 0xC)
  68888. +#define CSI_CSIRXFIFO (csi_regbase + 0x10)
  68889. +#define CSI_CSIRXCNT (csi_regbase + 0x14)
  68890. +#define CSI_CSISR (csi_regbase + 0x18)
  68891. +
  68892. +#define CSI_CSIDBG (csi_regbase + 0x1C)
  68893. +#define CSI_CSIDMASA_STATFIFO (csi_regbase + 0x20)
  68894. +#define CSI_CSIDMATS_STATFIFO (csi_regbase + 0x24)
  68895. +#define CSI_CSIDMASA_FB1 (csi_regbase + 0x28)
  68896. +#define CSI_CSIDMASA_FB2 (csi_regbase + 0x2C)
  68897. +#define CSI_CSIFBUF_PARA (csi_regbase + 0x30)
  68898. +#define CSI_CSIIMAG_PARA (csi_regbase + 0x34)
  68899. +
  68900. +static inline void csi_clear_status(unsigned long status)
  68901. +{
  68902. + __raw_writel(status, CSI_CSISR);
  68903. +}
  68904. +
  68905. +struct csi_signal_cfg_t {
  68906. + unsigned data_width:3;
  68907. + unsigned clk_mode:2;
  68908. + unsigned ext_vsync:1;
  68909. + unsigned Vsync_pol:1;
  68910. + unsigned Hsync_pol:1;
  68911. + unsigned pixclk_pol:1;
  68912. + unsigned data_pol:1;
  68913. + unsigned sens_clksrc:1;
  68914. +};
  68915. +
  68916. +struct csi_config_t {
  68917. + /* control reg 1 */
  68918. + unsigned int swap16_en:1;
  68919. + unsigned int ext_vsync:1;
  68920. + unsigned int eof_int_en:1;
  68921. + unsigned int prp_if_en:1;
  68922. + unsigned int ccir_mode:1;
  68923. + unsigned int cof_int_en:1;
  68924. + unsigned int sf_or_inten:1;
  68925. + unsigned int rf_or_inten:1;
  68926. + unsigned int sff_dma_done_inten:1;
  68927. + unsigned int statff_inten:1;
  68928. + unsigned int fb2_dma_done_inten:1;
  68929. + unsigned int fb1_dma_done_inten:1;
  68930. + unsigned int rxff_inten:1;
  68931. + unsigned int sof_pol:1;
  68932. + unsigned int sof_inten:1;
  68933. + unsigned int mclkdiv:4;
  68934. + unsigned int hsync_pol:1;
  68935. + unsigned int ccir_en:1;
  68936. + unsigned int mclken:1;
  68937. + unsigned int fcc:1;
  68938. + unsigned int pack_dir:1;
  68939. + unsigned int gclk_mode:1;
  68940. + unsigned int inv_data:1;
  68941. + unsigned int inv_pclk:1;
  68942. + unsigned int redge:1;
  68943. + unsigned int pixel_bit:1;
  68944. +
  68945. + /* control reg 3 */
  68946. + unsigned int frmcnt:16;
  68947. + unsigned int frame_reset:1;
  68948. + unsigned int dma_reflash_rff:1;
  68949. + unsigned int dma_reflash_sff:1;
  68950. + unsigned int dma_req_en_rff:1;
  68951. + unsigned int dma_req_en_sff:1;
  68952. + unsigned int statff_level:3;
  68953. + unsigned int hresp_err_en:1;
  68954. + unsigned int rxff_level:3;
  68955. + unsigned int two_8bit_sensor:1;
  68956. + unsigned int zero_pack_en:1;
  68957. + unsigned int ecc_int_en:1;
  68958. + unsigned int ecc_auto_en:1;
  68959. + /* fifo counter */
  68960. + unsigned int rxcnt;
  68961. +};
  68962. +
  68963. +typedef void (*csi_irq_callback_t) (void *data, unsigned long status);
  68964. +
  68965. +void csi_init_interface(void);
  68966. +void csi_init_format(int fmt);
  68967. +void csi_set_16bit_imagpara(int width, int height);
  68968. +void csi_set_12bit_imagpara(int width, int height);
  68969. +int csi_read_mclk_flag(void);
  68970. +void csi_start_callback(void *data);
  68971. +void csi_stop_callback(void *data);
  68972. +void csi_enable_int(int arg);
  68973. +void csi_disable_int(void);
  68974. +void csi_mclk_enable(void);
  68975. +void csi_mclk_disable(void);
  68976. +void csi_dmareq_rff_enable(void);
  68977. +void csi_dmareq_rff_disable(void);
  68978. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c
  68979. --- linux-3.14.15/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c 1970-01-01 01:00:00.000000000 +0100
  68980. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c 2014-08-20 19:31:45.440866052 +0200
  68981. @@ -0,0 +1,546 @@
  68982. +
  68983. +/*
  68984. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  68985. + */
  68986. +
  68987. +/*
  68988. + * The code contained herein is licensed under the GNU General Public
  68989. + * License. You may obtain a copy of the GNU General Public License
  68990. + * Version 2 or later at the following locations:
  68991. + *
  68992. + * http://www.opensource.org/licenses/gpl-license.html
  68993. + * http://www.gnu.org/copyleft/gpl.html
  68994. + */
  68995. +
  68996. +/*!
  68997. + * @file ipu_bg_overlay_sdc_bg.c
  68998. + *
  68999. + * @brief IPU Use case for PRP-VF back-ground
  69000. + *
  69001. + * @ingroup IPU
  69002. + */
  69003. +#include <linux/module.h>
  69004. +#include <linux/dma-mapping.h>
  69005. +#include <linux/fb.h>
  69006. +#include <linux/ipu.h>
  69007. +#include <linux/mipi_csi2.h>
  69008. +#include "mxc_v4l2_capture.h"
  69009. +#include "ipu_prp_sw.h"
  69010. +
  69011. +static int csi_buffer_num;
  69012. +static u32 bpp, csi_mem_bufsize = 3;
  69013. +static u32 out_format;
  69014. +static struct ipu_soc *disp_ipu;
  69015. +static u32 offset;
  69016. +
  69017. +static void csi_buf_work_func(struct work_struct *work)
  69018. +{
  69019. + int err = 0;
  69020. + cam_data *cam =
  69021. + container_of(work, struct _cam_data, csi_work_struct);
  69022. +
  69023. + struct ipu_task task;
  69024. + memset(&task, 0, sizeof(task));
  69025. +
  69026. + if (csi_buffer_num)
  69027. + task.input.paddr = cam->vf_bufs[0];
  69028. + else
  69029. + task.input.paddr = cam->vf_bufs[1];
  69030. + task.input.width = cam->crop_current.width;
  69031. + task.input.height = cam->crop_current.height;
  69032. + task.input.format = IPU_PIX_FMT_UYVY;
  69033. +
  69034. + task.output.paddr = offset;
  69035. + task.output.width = cam->overlay_fb->var.xres;
  69036. + task.output.height = cam->overlay_fb->var.yres;
  69037. + task.output.format = out_format;
  69038. + task.output.rotate = cam->rotation;
  69039. + task.output.crop.pos.x = cam->win.w.left;
  69040. + task.output.crop.pos.y = cam->win.w.top;
  69041. + if (cam->win.w.width > 1024 || cam->win.w.height > 1024) {
  69042. + task.output.crop.w = cam->overlay_fb->var.xres;
  69043. + task.output.crop.h = cam->overlay_fb->var.yres;
  69044. + } else {
  69045. + task.output.crop.w = cam->win.w.width;
  69046. + task.output.crop.h = cam->win.w.height;
  69047. + }
  69048. +again:
  69049. + err = ipu_check_task(&task);
  69050. + if (err != IPU_CHECK_OK) {
  69051. + if (err > IPU_CHECK_ERR_MIN) {
  69052. + if (err == IPU_CHECK_ERR_SPLIT_INPUTW_OVER) {
  69053. + task.input.crop.w -= 8;
  69054. + goto again;
  69055. + }
  69056. + if (err == IPU_CHECK_ERR_SPLIT_INPUTH_OVER) {
  69057. + task.input.crop.h -= 8;
  69058. + goto again;
  69059. + }
  69060. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
  69061. + task.output.width -= 8;
  69062. + task.output.crop.w = task.output.width;
  69063. + goto again;
  69064. + }
  69065. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
  69066. + task.output.height -= 8;
  69067. + task.output.crop.h = task.output.height;
  69068. + goto again;
  69069. + }
  69070. + printk(KERN_ERR "check ipu taks fail\n");
  69071. + return;
  69072. + }
  69073. + printk(KERN_ERR "check ipu taks fail\n");
  69074. + return;
  69075. + }
  69076. + err = ipu_queue_task(&task);
  69077. + if (err < 0)
  69078. + printk(KERN_ERR "queue ipu task error\n");
  69079. +}
  69080. +
  69081. +static void get_disp_ipu(cam_data *cam)
  69082. +{
  69083. + if (cam->output > 2)
  69084. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  69085. + else
  69086. + disp_ipu = ipu_get_soc(0);
  69087. +}
  69088. +
  69089. +
  69090. +/*!
  69091. + * csi ENC callback function.
  69092. + *
  69093. + * @param irq int irq line
  69094. + * @param dev_id void * device id
  69095. + *
  69096. + * @return status IRQ_HANDLED for handled
  69097. + */
  69098. +static irqreturn_t csi_enc_callback(int irq, void *dev_id)
  69099. +{
  69100. + cam_data *cam = (cam_data *) dev_id;
  69101. +
  69102. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, csi_buffer_num);
  69103. + schedule_work(&cam->csi_work_struct);
  69104. + csi_buffer_num = (csi_buffer_num == 0) ? 1 : 0;
  69105. + return IRQ_HANDLED;
  69106. +}
  69107. +
  69108. +static int csi_enc_setup(cam_data *cam)
  69109. +{
  69110. + ipu_channel_params_t params;
  69111. + u32 pixel_fmt;
  69112. + int err = 0, sensor_protocol = 0;
  69113. +#ifdef CONFIG_MXC_MIPI_CSI2
  69114. + void *mipi_csi2_info;
  69115. + int ipu_id;
  69116. + int csi_id;
  69117. +#endif
  69118. +
  69119. + if (!cam) {
  69120. + printk(KERN_ERR "cam private is NULL\n");
  69121. + return -ENXIO;
  69122. + }
  69123. +
  69124. + memset(&params, 0, sizeof(ipu_channel_params_t));
  69125. + params.csi_mem.csi = cam->csi;
  69126. +
  69127. + sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
  69128. + switch (sensor_protocol) {
  69129. + case IPU_CSI_CLK_MODE_GATED_CLK:
  69130. + case IPU_CSI_CLK_MODE_NONGATED_CLK:
  69131. + case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
  69132. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
  69133. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
  69134. + params.csi_mem.interlaced = false;
  69135. + break;
  69136. + case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
  69137. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
  69138. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
  69139. + params.csi_mem.interlaced = true;
  69140. + break;
  69141. + default:
  69142. + printk(KERN_ERR "sensor protocol unsupported\n");
  69143. + return -EINVAL;
  69144. + }
  69145. +
  69146. +#ifdef CONFIG_MXC_MIPI_CSI2
  69147. + mipi_csi2_info = mipi_csi2_get_info();
  69148. +
  69149. + if (mipi_csi2_info) {
  69150. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  69151. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  69152. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  69153. +
  69154. + if (cam->ipu == ipu_get_soc(ipu_id)
  69155. + && cam->csi == csi_id) {
  69156. + params.csi_mem.mipi_en = true;
  69157. + params.csi_mem.mipi_vc =
  69158. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  69159. + params.csi_mem.mipi_id =
  69160. + mipi_csi2_get_datatype(mipi_csi2_info);
  69161. +
  69162. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  69163. + } else {
  69164. + params.csi_mem.mipi_en = false;
  69165. + params.csi_mem.mipi_vc = 0;
  69166. + params.csi_mem.mipi_id = 0;
  69167. + }
  69168. + } else {
  69169. + params.csi_mem.mipi_en = false;
  69170. + params.csi_mem.mipi_vc = 0;
  69171. + params.csi_mem.mipi_id = 0;
  69172. + }
  69173. + }
  69174. +#endif
  69175. +
  69176. + if (cam->vf_bufs_vaddr[0]) {
  69177. + dma_free_coherent(0, cam->vf_bufs_size[0],
  69178. + cam->vf_bufs_vaddr[0],
  69179. + (dma_addr_t) cam->vf_bufs[0]);
  69180. + }
  69181. + if (cam->vf_bufs_vaddr[1]) {
  69182. + dma_free_coherent(0, cam->vf_bufs_size[1],
  69183. + cam->vf_bufs_vaddr[1],
  69184. + (dma_addr_t) cam->vf_bufs[1]);
  69185. + }
  69186. + csi_mem_bufsize =
  69187. + cam->crop_current.width * cam->crop_current.height * 2;
  69188. + cam->vf_bufs_size[0] = PAGE_ALIGN(csi_mem_bufsize);
  69189. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  69190. + cam->vf_bufs_size[0],
  69191. + (dma_addr_t *) &
  69192. + cam->vf_bufs[0],
  69193. + GFP_DMA |
  69194. + GFP_KERNEL);
  69195. + if (cam->vf_bufs_vaddr[0] == NULL) {
  69196. + printk(KERN_ERR "Error to allocate vf buffer\n");
  69197. + err = -ENOMEM;
  69198. + goto out_2;
  69199. + }
  69200. + cam->vf_bufs_size[1] = PAGE_ALIGN(csi_mem_bufsize);
  69201. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  69202. + cam->vf_bufs_size[1],
  69203. + (dma_addr_t *) &
  69204. + cam->vf_bufs[1],
  69205. + GFP_DMA |
  69206. + GFP_KERNEL);
  69207. + if (cam->vf_bufs_vaddr[1] == NULL) {
  69208. + printk(KERN_ERR "Error to allocate vf buffer\n");
  69209. + err = -ENOMEM;
  69210. + goto out_1;
  69211. + }
  69212. + pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
  69213. +
  69214. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  69215. + if (err != 0) {
  69216. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  69217. + goto out_1;
  69218. + }
  69219. +
  69220. + pixel_fmt = IPU_PIX_FMT_UYVY;
  69221. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  69222. + pixel_fmt, cam->crop_current.width,
  69223. + cam->crop_current.height,
  69224. + cam->crop_current.width, IPU_ROTATE_NONE,
  69225. + cam->vf_bufs[0], cam->vf_bufs[1], 0,
  69226. + cam->offset.u_offset, cam->offset.u_offset);
  69227. + if (err != 0) {
  69228. + printk(KERN_ERR "CSI_MEM output buffer\n");
  69229. + goto out_1;
  69230. + }
  69231. + err = ipu_enable_channel(cam->ipu, CSI_MEM);
  69232. + if (err < 0) {
  69233. + printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
  69234. + goto out_1;
  69235. + }
  69236. +
  69237. + csi_buffer_num = 0;
  69238. +
  69239. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 0);
  69240. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 1);
  69241. + return err;
  69242. +out_1:
  69243. + if (cam->vf_bufs_vaddr[0]) {
  69244. + dma_free_coherent(0, cam->vf_bufs_size[0],
  69245. + cam->vf_bufs_vaddr[0],
  69246. + (dma_addr_t) cam->vf_bufs[0]);
  69247. + cam->vf_bufs_vaddr[0] = NULL;
  69248. + cam->vf_bufs[0] = 0;
  69249. + }
  69250. + if (cam->vf_bufs_vaddr[1]) {
  69251. + dma_free_coherent(0, cam->vf_bufs_size[1],
  69252. + cam->vf_bufs_vaddr[1],
  69253. + (dma_addr_t) cam->vf_bufs[1]);
  69254. + cam->vf_bufs_vaddr[1] = NULL;
  69255. + cam->vf_bufs[1] = 0;
  69256. + }
  69257. +out_2:
  69258. + return err;
  69259. +}
  69260. +
  69261. +/*!
  69262. + * Enable encoder task
  69263. + * @param private struct cam_data * mxc capture instance
  69264. + *
  69265. + * @return status
  69266. + */
  69267. +static int csi_enc_enabling_tasks(void *private)
  69268. +{
  69269. + cam_data *cam = (cam_data *) private;
  69270. + int err = 0;
  69271. +
  69272. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  69273. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  69274. + csi_enc_callback, 0, "Mxc Camera", cam);
  69275. + if (err != 0) {
  69276. + printk(KERN_ERR "Error registering CSI0_OUT_EOF irq\n");
  69277. + return err;
  69278. + }
  69279. +
  69280. + INIT_WORK(&cam->csi_work_struct, csi_buf_work_func);
  69281. +
  69282. + err = csi_enc_setup(cam);
  69283. + if (err != 0) {
  69284. + printk(KERN_ERR "csi_enc_setup %d\n", err);
  69285. + goto out1;
  69286. + }
  69287. +
  69288. + return err;
  69289. +out1:
  69290. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  69291. + return err;
  69292. +}
  69293. +
  69294. +/*!
  69295. + * bg_overlay_start - start the overlay task
  69296. + *
  69297. + * @param private cam_data * mxc v4l2 main structure
  69298. + *
  69299. + */
  69300. +static int bg_overlay_start(void *private)
  69301. +{
  69302. + cam_data *cam = (cam_data *) private;
  69303. + int err = 0;
  69304. +
  69305. + if (!cam) {
  69306. + printk(KERN_ERR "private is NULL\n");
  69307. + return -EIO;
  69308. + }
  69309. +
  69310. + if (cam->overlay_active == true) {
  69311. + pr_debug("already start.\n");
  69312. + return 0;
  69313. + }
  69314. +
  69315. + get_disp_ipu(cam);
  69316. +
  69317. + out_format = cam->v4l2_fb.fmt.pixelformat;
  69318. + if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR24) {
  69319. + bpp = 3, csi_mem_bufsize = 3;
  69320. + pr_info("BGR24\n");
  69321. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_RGB565) {
  69322. + bpp = 2, csi_mem_bufsize = 2;
  69323. + pr_info("RGB565\n");
  69324. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR32) {
  69325. + bpp = 4, csi_mem_bufsize = 4;
  69326. + pr_info("BGR32\n");
  69327. + } else {
  69328. + printk(KERN_ERR
  69329. + "unsupported fix format from the framebuffer.\n");
  69330. + return -EINVAL;
  69331. + }
  69332. +
  69333. + offset = cam->v4l2_fb.fmt.bytesperline * cam->win.w.top +
  69334. + csi_mem_bufsize * cam->win.w.left;
  69335. +
  69336. + if (cam->v4l2_fb.base == 0)
  69337. + printk(KERN_ERR "invalid frame buffer address.\n");
  69338. + else
  69339. + offset += (u32) cam->v4l2_fb.base;
  69340. +
  69341. + csi_mem_bufsize = cam->win.w.width * cam->win.w.height
  69342. + * csi_mem_bufsize;
  69343. +
  69344. + err = csi_enc_enabling_tasks(cam);
  69345. + if (err != 0) {
  69346. + printk(KERN_ERR "Error csi enc enable fail\n");
  69347. + return err;
  69348. + }
  69349. +
  69350. + cam->overlay_active = true;
  69351. + return err;
  69352. +}
  69353. +
  69354. +/*!
  69355. + * bg_overlay_stop - stop the overlay task
  69356. + *
  69357. + * @param private cam_data * mxc v4l2 main structure
  69358. + *
  69359. + */
  69360. +static int bg_overlay_stop(void *private)
  69361. +{
  69362. + int err = 0;
  69363. + cam_data *cam = (cam_data *) private;
  69364. +#ifdef CONFIG_MXC_MIPI_CSI2
  69365. + void *mipi_csi2_info;
  69366. + int ipu_id;
  69367. + int csi_id;
  69368. +#endif
  69369. +
  69370. + if (cam->overlay_active == false)
  69371. + return 0;
  69372. +
  69373. + err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
  69374. +
  69375. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  69376. +
  69377. + csi_buffer_num = 0;
  69378. +
  69379. +#ifdef CONFIG_MXC_MIPI_CSI2
  69380. + mipi_csi2_info = mipi_csi2_get_info();
  69381. +
  69382. + if (mipi_csi2_info) {
  69383. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  69384. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  69385. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  69386. +
  69387. + if (cam->ipu == ipu_get_soc(ipu_id)
  69388. + && cam->csi == csi_id)
  69389. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  69390. + }
  69391. + }
  69392. +#endif
  69393. +
  69394. + flush_work(&cam->csi_work_struct);
  69395. + cancel_work_sync(&cam->csi_work_struct);
  69396. +
  69397. + if (cam->vf_bufs_vaddr[0]) {
  69398. + dma_free_coherent(0, cam->vf_bufs_size[0],
  69399. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  69400. + cam->vf_bufs_vaddr[0] = NULL;
  69401. + cam->vf_bufs[0] = 0;
  69402. + }
  69403. + if (cam->vf_bufs_vaddr[1]) {
  69404. + dma_free_coherent(0, cam->vf_bufs_size[1],
  69405. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  69406. + cam->vf_bufs_vaddr[1] = NULL;
  69407. + cam->vf_bufs[1] = 0;
  69408. + }
  69409. + if (cam->rot_vf_bufs_vaddr[0]) {
  69410. + dma_free_coherent(0, cam->rot_vf_buf_size[0],
  69411. + cam->rot_vf_bufs_vaddr[0],
  69412. + cam->rot_vf_bufs[0]);
  69413. + cam->rot_vf_bufs_vaddr[0] = NULL;
  69414. + cam->rot_vf_bufs[0] = 0;
  69415. + }
  69416. + if (cam->rot_vf_bufs_vaddr[1]) {
  69417. + dma_free_coherent(0, cam->rot_vf_buf_size[1],
  69418. + cam->rot_vf_bufs_vaddr[1],
  69419. + cam->rot_vf_bufs[1]);
  69420. + cam->rot_vf_bufs_vaddr[1] = NULL;
  69421. + cam->rot_vf_bufs[1] = 0;
  69422. + }
  69423. +
  69424. + cam->overlay_active = false;
  69425. + return err;
  69426. +}
  69427. +
  69428. +/*!
  69429. + * Enable csi
  69430. + * @param private struct cam_data * mxc capture instance
  69431. + *
  69432. + * @return status
  69433. + */
  69434. +static int bg_overlay_enable_csi(void *private)
  69435. +{
  69436. + cam_data *cam = (cam_data *) private;
  69437. +
  69438. + return ipu_enable_csi(cam->ipu, cam->csi);
  69439. +}
  69440. +
  69441. +/*!
  69442. + * Disable csi
  69443. + * @param private struct cam_data * mxc capture instance
  69444. + *
  69445. + * @return status
  69446. + */
  69447. +static int bg_overlay_disable_csi(void *private)
  69448. +{
  69449. + cam_data *cam = (cam_data *) private;
  69450. +
  69451. + /* free csi eof irq firstly.
  69452. + * when disable csi, wait for idmac eof.
  69453. + * it requests eof irq again */
  69454. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  69455. +
  69456. + return ipu_disable_csi(cam->ipu, cam->csi);
  69457. +}
  69458. +
  69459. +/*!
  69460. + * function to select bg as the working path
  69461. + *
  69462. + * @param private cam_data * mxc v4l2 main structure
  69463. + *
  69464. + * @return status
  69465. + */
  69466. +int bg_overlay_sdc_select(void *private)
  69467. +{
  69468. + cam_data *cam = (cam_data *) private;
  69469. +
  69470. + if (cam) {
  69471. + cam->vf_start_sdc = bg_overlay_start;
  69472. + cam->vf_stop_sdc = bg_overlay_stop;
  69473. + cam->vf_enable_csi = bg_overlay_enable_csi;
  69474. + cam->vf_disable_csi = bg_overlay_disable_csi;
  69475. + cam->overlay_active = false;
  69476. + }
  69477. +
  69478. + return 0;
  69479. +}
  69480. +EXPORT_SYMBOL(bg_overlay_sdc_select);
  69481. +
  69482. +/*!
  69483. + * function to de-select bg as the working path
  69484. + *
  69485. + * @param private cam_data * mxc v4l2 main structure
  69486. + *
  69487. + * @return status
  69488. + */
  69489. +int bg_overlay_sdc_deselect(void *private)
  69490. +{
  69491. + cam_data *cam = (cam_data *) private;
  69492. +
  69493. + if (cam) {
  69494. + cam->vf_start_sdc = NULL;
  69495. + cam->vf_stop_sdc = NULL;
  69496. + cam->vf_enable_csi = NULL;
  69497. + cam->vf_disable_csi = NULL;
  69498. + }
  69499. + return 0;
  69500. +}
  69501. +EXPORT_SYMBOL(bg_overlay_sdc_deselect);
  69502. +
  69503. +/*!
  69504. + * Init background overlay task.
  69505. + *
  69506. + * @return Error code indicating success or failure
  69507. + */
  69508. +__init int bg_overlay_sdc_init(void)
  69509. +{
  69510. + return 0;
  69511. +}
  69512. +
  69513. +/*!
  69514. + * Deinit background overlay task.
  69515. + *
  69516. + * @return Error code indicating success or failure
  69517. + */
  69518. +void __exit bg_overlay_sdc_exit(void)
  69519. +{
  69520. +}
  69521. +
  69522. +module_init(bg_overlay_sdc_init);
  69523. +module_exit(bg_overlay_sdc_exit);
  69524. +
  69525. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  69526. +MODULE_DESCRIPTION("IPU PRP VF SDC Backgroud Driver");
  69527. +MODULE_LICENSE("GPL");
  69528. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/ipu_csi_enc.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_csi_enc.c
  69529. --- linux-3.14.15/drivers/media/platform/mxc/capture/ipu_csi_enc.c 1970-01-01 01:00:00.000000000 +0100
  69530. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_csi_enc.c 2014-08-20 19:31:45.440866052 +0200
  69531. @@ -0,0 +1,418 @@
  69532. +/*
  69533. + * Copyright 2009-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  69534. + */
  69535. +
  69536. +/*
  69537. + * The code contained herein is licensed under the GNU General Public
  69538. + * License. You may obtain a copy of the GNU General Public License
  69539. + * Version 2 or later at the following locations:
  69540. + *
  69541. + * http://www.opensource.org/licenses/gpl-license.html
  69542. + * http://www.gnu.org/copyleft/gpl.html
  69543. + */
  69544. +
  69545. +/*!
  69546. + * @file ipu_csi_enc.c
  69547. + *
  69548. + * @brief CSI Use case for video capture
  69549. + *
  69550. + * @ingroup IPU
  69551. + */
  69552. +
  69553. +#include <linux/module.h>
  69554. +#include <linux/platform_device.h>
  69555. +#include <linux/dma-mapping.h>
  69556. +#include <linux/ipu.h>
  69557. +#include <linux/mipi_csi2.h>
  69558. +#include "mxc_v4l2_capture.h"
  69559. +#include "ipu_prp_sw.h"
  69560. +
  69561. +#ifdef CAMERA_DBG
  69562. + #define CAMERA_TRACE(x) (printk)x
  69563. +#else
  69564. + #define CAMERA_TRACE(x)
  69565. +#endif
  69566. +
  69567. +/*
  69568. + * Function definitions
  69569. + */
  69570. +
  69571. +/*!
  69572. + * csi ENC callback function.
  69573. + *
  69574. + * @param irq int irq line
  69575. + * @param dev_id void * device id
  69576. + *
  69577. + * @return status IRQ_HANDLED for handled
  69578. + */
  69579. +static irqreturn_t csi_enc_callback(int irq, void *dev_id)
  69580. +{
  69581. + cam_data *cam = (cam_data *) dev_id;
  69582. +
  69583. + if (cam->enc_callback == NULL)
  69584. + return IRQ_HANDLED;
  69585. +
  69586. + cam->enc_callback(irq, dev_id);
  69587. + return IRQ_HANDLED;
  69588. +}
  69589. +
  69590. +/*!
  69591. + * CSI ENC enable channel setup function
  69592. + *
  69593. + * @param cam struct cam_data * mxc capture instance
  69594. + *
  69595. + * @return status
  69596. + */
  69597. +static int csi_enc_setup(cam_data *cam)
  69598. +{
  69599. + ipu_channel_params_t params;
  69600. + u32 pixel_fmt;
  69601. + int err = 0, sensor_protocol = 0;
  69602. + dma_addr_t dummy = cam->dummy_frame.buffer.m.offset;
  69603. +#ifdef CONFIG_MXC_MIPI_CSI2
  69604. + void *mipi_csi2_info;
  69605. + int ipu_id;
  69606. + int csi_id;
  69607. +#endif
  69608. +
  69609. + CAMERA_TRACE("In csi_enc_setup\n");
  69610. + if (!cam) {
  69611. + printk(KERN_ERR "cam private is NULL\n");
  69612. + return -ENXIO;
  69613. + }
  69614. +
  69615. + memset(&params, 0, sizeof(ipu_channel_params_t));
  69616. + params.csi_mem.csi = cam->csi;
  69617. +
  69618. + sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
  69619. + switch (sensor_protocol) {
  69620. + case IPU_CSI_CLK_MODE_GATED_CLK:
  69621. + case IPU_CSI_CLK_MODE_NONGATED_CLK:
  69622. + case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
  69623. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
  69624. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
  69625. + params.csi_mem.interlaced = false;
  69626. + break;
  69627. + case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
  69628. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
  69629. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
  69630. + params.csi_mem.interlaced = true;
  69631. + break;
  69632. + default:
  69633. + printk(KERN_ERR "sensor protocol unsupported\n");
  69634. + return -EINVAL;
  69635. + }
  69636. +
  69637. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
  69638. + pixel_fmt = IPU_PIX_FMT_YUV420P;
  69639. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420)
  69640. + pixel_fmt = IPU_PIX_FMT_YVU420P;
  69641. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P)
  69642. + pixel_fmt = IPU_PIX_FMT_YUV422P;
  69643. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
  69644. + pixel_fmt = IPU_PIX_FMT_UYVY;
  69645. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
  69646. + pixel_fmt = IPU_PIX_FMT_YUYV;
  69647. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)
  69648. + pixel_fmt = IPU_PIX_FMT_NV12;
  69649. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
  69650. + pixel_fmt = IPU_PIX_FMT_BGR24;
  69651. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
  69652. + pixel_fmt = IPU_PIX_FMT_RGB24;
  69653. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565)
  69654. + pixel_fmt = IPU_PIX_FMT_RGB565;
  69655. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32)
  69656. + pixel_fmt = IPU_PIX_FMT_BGR32;
  69657. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32)
  69658. + pixel_fmt = IPU_PIX_FMT_RGB32;
  69659. + else {
  69660. + printk(KERN_ERR "format not supported\n");
  69661. + return -EINVAL;
  69662. + }
  69663. +
  69664. +#ifdef CONFIG_MXC_MIPI_CSI2
  69665. + mipi_csi2_info = mipi_csi2_get_info();
  69666. +
  69667. + if (mipi_csi2_info) {
  69668. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  69669. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  69670. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  69671. +
  69672. + if (cam->ipu == ipu_get_soc(ipu_id)
  69673. + && cam->csi == csi_id) {
  69674. + params.csi_mem.mipi_en = true;
  69675. + params.csi_mem.mipi_vc =
  69676. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  69677. + params.csi_mem.mipi_id =
  69678. + mipi_csi2_get_datatype(mipi_csi2_info);
  69679. +
  69680. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  69681. + } else {
  69682. + params.csi_mem.mipi_en = false;
  69683. + params.csi_mem.mipi_vc = 0;
  69684. + params.csi_mem.mipi_id = 0;
  69685. + }
  69686. + } else {
  69687. + params.csi_mem.mipi_en = false;
  69688. + params.csi_mem.mipi_vc = 0;
  69689. + params.csi_mem.mipi_id = 0;
  69690. + }
  69691. + }
  69692. +#endif
  69693. +
  69694. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  69695. + if (err != 0) {
  69696. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  69697. + return err;
  69698. + }
  69699. +
  69700. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  69701. + pixel_fmt, cam->v2f.fmt.pix.width,
  69702. + cam->v2f.fmt.pix.height,
  69703. + cam->v2f.fmt.pix.bytesperline,
  69704. + IPU_ROTATE_NONE,
  69705. + dummy, dummy, 0,
  69706. + cam->offset.u_offset,
  69707. + cam->offset.v_offset);
  69708. + if (err != 0) {
  69709. + printk(KERN_ERR "CSI_MEM output buffer\n");
  69710. + return err;
  69711. + }
  69712. + err = ipu_enable_channel(cam->ipu, CSI_MEM);
  69713. + if (err < 0) {
  69714. + printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
  69715. + return err;
  69716. + }
  69717. +
  69718. + return err;
  69719. +}
  69720. +
  69721. +/*!
  69722. + * function to update physical buffer address for encorder IDMA channel
  69723. + *
  69724. + * @param eba physical buffer address for encorder IDMA channel
  69725. + * @param buffer_num int buffer 0 or buffer 1
  69726. + *
  69727. + * @return status
  69728. + */
  69729. +static int csi_enc_eba_update(struct ipu_soc *ipu, dma_addr_t eba,
  69730. + int *buffer_num)
  69731. +{
  69732. + int err = 0;
  69733. +
  69734. + pr_debug("eba %x\n", eba);
  69735. + err = ipu_update_channel_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  69736. + *buffer_num, eba);
  69737. + if (err != 0) {
  69738. + ipu_clear_buffer_ready(ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  69739. + *buffer_num);
  69740. +
  69741. + err = ipu_update_channel_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  69742. + *buffer_num, eba);
  69743. + if (err != 0) {
  69744. + pr_err("ERROR: v4l2 capture: fail to update "
  69745. + "buf%d\n", *buffer_num);
  69746. + return err;
  69747. + }
  69748. + }
  69749. +
  69750. + ipu_select_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num);
  69751. +
  69752. + *buffer_num = (*buffer_num == 0) ? 1 : 0;
  69753. +
  69754. + return 0;
  69755. +}
  69756. +
  69757. +/*!
  69758. + * Enable encoder task
  69759. + * @param private struct cam_data * mxc capture instance
  69760. + *
  69761. + * @return status
  69762. + */
  69763. +static int csi_enc_enabling_tasks(void *private)
  69764. +{
  69765. + cam_data *cam = (cam_data *) private;
  69766. + int err = 0;
  69767. + CAMERA_TRACE("IPU:In csi_enc_enabling_tasks\n");
  69768. +
  69769. + cam->dummy_frame.vaddress = dma_alloc_coherent(0,
  69770. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  69771. + &cam->dummy_frame.paddress,
  69772. + GFP_DMA | GFP_KERNEL);
  69773. + if (cam->dummy_frame.vaddress == 0) {
  69774. + pr_err("ERROR: v4l2 capture: Allocate dummy frame "
  69775. + "failed.\n");
  69776. + return -ENOBUFS;
  69777. + }
  69778. + cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
  69779. + cam->dummy_frame.buffer.length =
  69780. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  69781. + cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
  69782. +
  69783. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  69784. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  69785. + csi_enc_callback, 0, "Mxc Camera", cam);
  69786. + if (err != 0) {
  69787. + printk(KERN_ERR "Error registering rot irq\n");
  69788. + return err;
  69789. + }
  69790. +
  69791. + err = csi_enc_setup(cam);
  69792. + if (err != 0) {
  69793. + printk(KERN_ERR "csi_enc_setup %d\n", err);
  69794. + return err;
  69795. + }
  69796. +
  69797. + return err;
  69798. +}
  69799. +
  69800. +/*!
  69801. + * Disable encoder task
  69802. + * @param private struct cam_data * mxc capture instance
  69803. + *
  69804. + * @return int
  69805. + */
  69806. +static int csi_enc_disabling_tasks(void *private)
  69807. +{
  69808. + cam_data *cam = (cam_data *) private;
  69809. + int err = 0;
  69810. +#ifdef CONFIG_MXC_MIPI_CSI2
  69811. + void *mipi_csi2_info;
  69812. + int ipu_id;
  69813. + int csi_id;
  69814. +#endif
  69815. +
  69816. + err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
  69817. +
  69818. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  69819. +
  69820. + if (cam->dummy_frame.vaddress != 0) {
  69821. + dma_free_coherent(0, cam->dummy_frame.buffer.length,
  69822. + cam->dummy_frame.vaddress,
  69823. + cam->dummy_frame.paddress);
  69824. + cam->dummy_frame.vaddress = 0;
  69825. + }
  69826. +
  69827. +#ifdef CONFIG_MXC_MIPI_CSI2
  69828. + mipi_csi2_info = mipi_csi2_get_info();
  69829. +
  69830. + if (mipi_csi2_info) {
  69831. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  69832. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  69833. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  69834. +
  69835. + if (cam->ipu == ipu_get_soc(ipu_id)
  69836. + && cam->csi == csi_id)
  69837. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  69838. + }
  69839. + }
  69840. +#endif
  69841. +
  69842. + return err;
  69843. +}
  69844. +
  69845. +/*!
  69846. + * Enable csi
  69847. + * @param private struct cam_data * mxc capture instance
  69848. + *
  69849. + * @return status
  69850. + */
  69851. +static int csi_enc_enable_csi(void *private)
  69852. +{
  69853. + cam_data *cam = (cam_data *) private;
  69854. +
  69855. + return ipu_enable_csi(cam->ipu, cam->csi);
  69856. +}
  69857. +
  69858. +/*!
  69859. + * Disable csi
  69860. + * @param private struct cam_data * mxc capture instance
  69861. + *
  69862. + * @return status
  69863. + */
  69864. +static int csi_enc_disable_csi(void *private)
  69865. +{
  69866. + cam_data *cam = (cam_data *) private;
  69867. +
  69868. + /* free csi eof irq firstly.
  69869. + * when disable csi, wait for idmac eof.
  69870. + * it requests eof irq again */
  69871. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  69872. +
  69873. + return ipu_disable_csi(cam->ipu, cam->csi);
  69874. +}
  69875. +
  69876. +/*!
  69877. + * function to select CSI ENC as the working path
  69878. + *
  69879. + * @param private struct cam_data * mxc capture instance
  69880. + *
  69881. + * @return int
  69882. + */
  69883. +int csi_enc_select(void *private)
  69884. +{
  69885. + cam_data *cam = (cam_data *) private;
  69886. + int err = 0;
  69887. +
  69888. + if (cam) {
  69889. + cam->enc_update_eba = csi_enc_eba_update;
  69890. + cam->enc_enable = csi_enc_enabling_tasks;
  69891. + cam->enc_disable = csi_enc_disabling_tasks;
  69892. + cam->enc_enable_csi = csi_enc_enable_csi;
  69893. + cam->enc_disable_csi = csi_enc_disable_csi;
  69894. + } else {
  69895. + err = -EIO;
  69896. + }
  69897. +
  69898. + return err;
  69899. +}
  69900. +EXPORT_SYMBOL(csi_enc_select);
  69901. +
  69902. +/*!
  69903. + * function to de-select CSI ENC as the working path
  69904. + *
  69905. + * @param private struct cam_data * mxc capture instance
  69906. + *
  69907. + * @return int
  69908. + */
  69909. +int csi_enc_deselect(void *private)
  69910. +{
  69911. + cam_data *cam = (cam_data *) private;
  69912. + int err = 0;
  69913. +
  69914. + if (cam) {
  69915. + cam->enc_update_eba = NULL;
  69916. + cam->enc_enable = NULL;
  69917. + cam->enc_disable = NULL;
  69918. + cam->enc_enable_csi = NULL;
  69919. + cam->enc_disable_csi = NULL;
  69920. + }
  69921. +
  69922. + return err;
  69923. +}
  69924. +EXPORT_SYMBOL(csi_enc_deselect);
  69925. +
  69926. +/*!
  69927. + * Init the Encorder channels
  69928. + *
  69929. + * @return Error code indicating success or failure
  69930. + */
  69931. +__init int csi_enc_init(void)
  69932. +{
  69933. + return 0;
  69934. +}
  69935. +
  69936. +/*!
  69937. + * Deinit the Encorder channels
  69938. + *
  69939. + */
  69940. +void __exit csi_enc_exit(void)
  69941. +{
  69942. +}
  69943. +
  69944. +module_init(csi_enc_init);
  69945. +module_exit(csi_enc_exit);
  69946. +
  69947. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  69948. +MODULE_DESCRIPTION("CSI ENC Driver");
  69949. +MODULE_LICENSE("GPL");
  69950. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c
  69951. --- linux-3.14.15/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c 1970-01-01 01:00:00.000000000 +0100
  69952. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c 2014-08-20 19:31:45.440866052 +0200
  69953. @@ -0,0 +1,634 @@
  69954. +/*
  69955. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  69956. + */
  69957. +/* * The code contained herein is licensed under the GNU General Public
  69958. + * License. You may obtain a copy of the GNU General Public License
  69959. + * Version 2 or later at the following locations:
  69960. + *
  69961. + * http://www.opensource.org/licenses/gpl-license.html
  69962. + * http://www.gnu.org/copyleft/gpl.html
  69963. + */
  69964. +
  69965. +/*!
  69966. + * @file ipu_foreground_sdc.c
  69967. + *
  69968. + * @brief IPU Use case for PRP-VF
  69969. + *
  69970. + * @ingroup IPU
  69971. + */
  69972. +
  69973. +#include <linux/module.h>
  69974. +#include <linux/dma-mapping.h>
  69975. +#include <linux/console.h>
  69976. +#include <linux/ipu.h>
  69977. +#include <linux/mxcfb.h>
  69978. +#include <linux/mipi_csi2.h>
  69979. +
  69980. +#include "mxc_v4l2_capture.h"
  69981. +#include "ipu_prp_sw.h"
  69982. +
  69983. +#ifdef CAMERA_DBG
  69984. + #define CAMERA_TRACE(x) (printk)x
  69985. +#else
  69986. + #define CAMERA_TRACE(x)
  69987. +#endif
  69988. +
  69989. +static int csi_buffer_num, buffer_num;
  69990. +static u32 csi_mem_bufsize;
  69991. +static struct ipu_soc *disp_ipu;
  69992. +static struct fb_info *fbi;
  69993. +static struct fb_var_screeninfo fbvar;
  69994. +static u32 vf_out_format;
  69995. +static void csi_buf_work_func(struct work_struct *work)
  69996. +{
  69997. + int err = 0;
  69998. + cam_data *cam =
  69999. + container_of(work, struct _cam_data, csi_work_struct);
  70000. +
  70001. + struct ipu_task task;
  70002. + memset(&task, 0, sizeof(task));
  70003. +
  70004. + if (csi_buffer_num)
  70005. + task.input.paddr = cam->vf_bufs[0];
  70006. + else
  70007. + task.input.paddr = cam->vf_bufs[1];
  70008. + task.input.width = cam->crop_current.width;
  70009. + task.input.height = cam->crop_current.height;
  70010. + task.input.format = IPU_PIX_FMT_NV12;
  70011. +
  70012. + if (buffer_num == 0)
  70013. + task.output.paddr = fbi->fix.smem_start +
  70014. + (fbi->fix.line_length * fbvar.yres);
  70015. + else
  70016. + task.output.paddr = fbi->fix.smem_start;
  70017. + task.output.width = cam->win.w.width;
  70018. + task.output.height = cam->win.w.height;
  70019. + task.output.format = vf_out_format;
  70020. + task.output.rotate = cam->rotation;
  70021. +again:
  70022. + err = ipu_check_task(&task);
  70023. + if (err != IPU_CHECK_OK) {
  70024. + if (err > IPU_CHECK_ERR_MIN) {
  70025. + if (err == IPU_CHECK_ERR_SPLIT_INPUTW_OVER) {
  70026. + task.input.crop.w -= 8;
  70027. + goto again;
  70028. + }
  70029. + if (err == IPU_CHECK_ERR_SPLIT_INPUTH_OVER) {
  70030. + task.input.crop.h -= 8;
  70031. + goto again;
  70032. + }
  70033. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
  70034. + task.output.width -= 8;
  70035. + task.output.crop.w = task.output.width;
  70036. + goto again;
  70037. + }
  70038. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
  70039. + task.output.height -= 8;
  70040. + task.output.crop.h = task.output.height;
  70041. + goto again;
  70042. + }
  70043. + printk(KERN_ERR "check ipu taks fail\n");
  70044. + return;
  70045. + }
  70046. + printk(KERN_ERR "check ipu taks fail\n");
  70047. + return;
  70048. + }
  70049. + err = ipu_queue_task(&task);
  70050. + if (err < 0)
  70051. + printk(KERN_ERR "queue ipu task error\n");
  70052. + ipu_select_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER, buffer_num);
  70053. + buffer_num = (buffer_num == 0) ? 1 : 0;
  70054. +}
  70055. +
  70056. +static void get_disp_ipu(cam_data *cam)
  70057. +{
  70058. + if (cam->output > 2)
  70059. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  70060. + else
  70061. + disp_ipu = ipu_get_soc(0);
  70062. +}
  70063. +
  70064. +/*!
  70065. + * csi ENC callback function.
  70066. + *
  70067. + * @param irq int irq line
  70068. + * @param dev_id void * device id
  70069. + *
  70070. + * @return status IRQ_HANDLED for handled
  70071. + */
  70072. +static irqreturn_t csi_enc_callback(int irq, void *dev_id)
  70073. +{
  70074. + cam_data *cam = (cam_data *) dev_id;
  70075. +
  70076. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, csi_buffer_num);
  70077. + if ((cam->crop_current.width != cam->win.w.width) ||
  70078. + (cam->crop_current.height != cam->win.w.height) ||
  70079. + (vf_out_format != IPU_PIX_FMT_NV12) ||
  70080. + (cam->rotation >= IPU_ROTATE_VERT_FLIP))
  70081. + schedule_work(&cam->csi_work_struct);
  70082. + csi_buffer_num = (csi_buffer_num == 0) ? 1 : 0;
  70083. + return IRQ_HANDLED;
  70084. +}
  70085. +
  70086. +static int csi_enc_setup(cam_data *cam)
  70087. +{
  70088. + ipu_channel_params_t params;
  70089. + int err = 0, sensor_protocol = 0;
  70090. +#ifdef CONFIG_MXC_MIPI_CSI2
  70091. + void *mipi_csi2_info;
  70092. + int ipu_id;
  70093. + int csi_id;
  70094. +#endif
  70095. +
  70096. + CAMERA_TRACE("In csi_enc_setup\n");
  70097. + if (!cam) {
  70098. + printk(KERN_ERR "cam private is NULL\n");
  70099. + return -ENXIO;
  70100. + }
  70101. +
  70102. + memset(&params, 0, sizeof(ipu_channel_params_t));
  70103. + params.csi_mem.csi = cam->csi;
  70104. +
  70105. + sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
  70106. + switch (sensor_protocol) {
  70107. + case IPU_CSI_CLK_MODE_GATED_CLK:
  70108. + case IPU_CSI_CLK_MODE_NONGATED_CLK:
  70109. + case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
  70110. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
  70111. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
  70112. + params.csi_mem.interlaced = false;
  70113. + break;
  70114. + case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
  70115. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
  70116. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
  70117. + params.csi_mem.interlaced = true;
  70118. + break;
  70119. + default:
  70120. + printk(KERN_ERR "sensor protocol unsupported\n");
  70121. + return -EINVAL;
  70122. + }
  70123. +
  70124. +#ifdef CONFIG_MXC_MIPI_CSI2
  70125. + mipi_csi2_info = mipi_csi2_get_info();
  70126. +
  70127. + if (mipi_csi2_info) {
  70128. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  70129. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  70130. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  70131. +
  70132. + if (cam->ipu == ipu_get_soc(ipu_id)
  70133. + && cam->csi == csi_id) {
  70134. + params.csi_mem.mipi_en = true;
  70135. + params.csi_mem.mipi_vc =
  70136. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  70137. + params.csi_mem.mipi_id =
  70138. + mipi_csi2_get_datatype(mipi_csi2_info);
  70139. +
  70140. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  70141. + } else {
  70142. + params.csi_mem.mipi_en = false;
  70143. + params.csi_mem.mipi_vc = 0;
  70144. + params.csi_mem.mipi_id = 0;
  70145. + }
  70146. + } else {
  70147. + params.csi_mem.mipi_en = false;
  70148. + params.csi_mem.mipi_vc = 0;
  70149. + params.csi_mem.mipi_id = 0;
  70150. + }
  70151. + }
  70152. +#endif
  70153. +
  70154. + if (cam->vf_bufs_vaddr[0]) {
  70155. + dma_free_coherent(0, cam->vf_bufs_size[0],
  70156. + cam->vf_bufs_vaddr[0],
  70157. + (dma_addr_t) cam->vf_bufs[0]);
  70158. + }
  70159. + if (cam->vf_bufs_vaddr[1]) {
  70160. + dma_free_coherent(0, cam->vf_bufs_size[1],
  70161. + cam->vf_bufs_vaddr[1],
  70162. + (dma_addr_t) cam->vf_bufs[1]);
  70163. + }
  70164. + csi_mem_bufsize = cam->crop_current.width *
  70165. + cam->crop_current.height * 3/2;
  70166. + cam->vf_bufs_size[0] = PAGE_ALIGN(csi_mem_bufsize);
  70167. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  70168. + cam->vf_bufs_size[0],
  70169. + (dma_addr_t *) &
  70170. + cam->vf_bufs[0],
  70171. + GFP_DMA |
  70172. + GFP_KERNEL);
  70173. + if (cam->vf_bufs_vaddr[0] == NULL) {
  70174. + printk(KERN_ERR "Error to allocate vf buffer\n");
  70175. + err = -ENOMEM;
  70176. + goto out_2;
  70177. + }
  70178. + cam->vf_bufs_size[1] = PAGE_ALIGN(csi_mem_bufsize);
  70179. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  70180. + cam->vf_bufs_size[1],
  70181. + (dma_addr_t *) &
  70182. + cam->vf_bufs[1],
  70183. + GFP_DMA |
  70184. + GFP_KERNEL);
  70185. + if (cam->vf_bufs_vaddr[1] == NULL) {
  70186. + printk(KERN_ERR "Error to allocate vf buffer\n");
  70187. + err = -ENOMEM;
  70188. + goto out_1;
  70189. + }
  70190. + pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
  70191. +
  70192. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  70193. + if (err != 0) {
  70194. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  70195. + goto out_1;
  70196. + }
  70197. +
  70198. + if ((cam->crop_current.width == cam->win.w.width) &&
  70199. + (cam->crop_current.height == cam->win.w.height) &&
  70200. + (vf_out_format == IPU_PIX_FMT_NV12) &&
  70201. + (cam->rotation < IPU_ROTATE_VERT_FLIP)) {
  70202. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM,
  70203. + IPU_OUTPUT_BUFFER,
  70204. + IPU_PIX_FMT_NV12,
  70205. + cam->crop_current.width,
  70206. + cam->crop_current.height,
  70207. + cam->crop_current.width, IPU_ROTATE_NONE,
  70208. + fbi->fix.smem_start +
  70209. + (fbi->fix.line_length * fbvar.yres),
  70210. + fbi->fix.smem_start, 0,
  70211. + cam->offset.u_offset, cam->offset.u_offset);
  70212. + } else {
  70213. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM,
  70214. + IPU_OUTPUT_BUFFER,
  70215. + IPU_PIX_FMT_NV12,
  70216. + cam->crop_current.width,
  70217. + cam->crop_current.height,
  70218. + cam->crop_current.width, IPU_ROTATE_NONE,
  70219. + cam->vf_bufs[0], cam->vf_bufs[1], 0,
  70220. + cam->offset.u_offset, cam->offset.u_offset);
  70221. + }
  70222. + if (err != 0) {
  70223. + printk(KERN_ERR "CSI_MEM output buffer\n");
  70224. + goto out_1;
  70225. + }
  70226. + err = ipu_enable_channel(cam->ipu, CSI_MEM);
  70227. + if (err < 0) {
  70228. + printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
  70229. + goto out_1;
  70230. + }
  70231. +
  70232. + csi_buffer_num = 0;
  70233. +
  70234. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 0);
  70235. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 1);
  70236. + return err;
  70237. +out_1:
  70238. + if (cam->vf_bufs_vaddr[0]) {
  70239. + dma_free_coherent(0, cam->vf_bufs_size[0],
  70240. + cam->vf_bufs_vaddr[0],
  70241. + (dma_addr_t) cam->vf_bufs[0]);
  70242. + cam->vf_bufs_vaddr[0] = NULL;
  70243. + cam->vf_bufs[0] = 0;
  70244. + }
  70245. + if (cam->vf_bufs_vaddr[1]) {
  70246. + dma_free_coherent(0, cam->vf_bufs_size[1],
  70247. + cam->vf_bufs_vaddr[1],
  70248. + (dma_addr_t) cam->vf_bufs[1]);
  70249. + cam->vf_bufs_vaddr[1] = NULL;
  70250. + cam->vf_bufs[1] = 0;
  70251. + }
  70252. +out_2:
  70253. + return err;
  70254. +}
  70255. +
  70256. +/*!
  70257. + * Enable encoder task
  70258. + * @param private struct cam_data * mxc capture instance
  70259. + *
  70260. + * @return status
  70261. + */
  70262. +static int csi_enc_enabling_tasks(void *private)
  70263. +{
  70264. + cam_data *cam = (cam_data *) private;
  70265. + int err = 0;
  70266. + CAMERA_TRACE("IPU:In csi_enc_enabling_tasks\n");
  70267. +
  70268. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  70269. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  70270. + csi_enc_callback, 0, "Mxc Camera", cam);
  70271. + if (err != 0) {
  70272. + printk(KERN_ERR "Error registering CSI0_OUT_EOF irq\n");
  70273. + return err;
  70274. + }
  70275. +
  70276. + INIT_WORK(&cam->csi_work_struct, csi_buf_work_func);
  70277. +
  70278. + err = csi_enc_setup(cam);
  70279. + if (err != 0) {
  70280. + printk(KERN_ERR "csi_enc_setup %d\n", err);
  70281. + goto out1;
  70282. + }
  70283. +
  70284. + return err;
  70285. +out1:
  70286. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  70287. + return err;
  70288. +}
  70289. +
  70290. +/*
  70291. + * Function definitions
  70292. + */
  70293. +
  70294. +/*!
  70295. + * foreground_start - start the vf task
  70296. + *
  70297. + * @param private cam_data * mxc v4l2 main structure
  70298. + *
  70299. + */
  70300. +static int foreground_start(void *private)
  70301. +{
  70302. + cam_data *cam = (cam_data *) private;
  70303. + int err = 0, i = 0, screen_size;
  70304. + char *base;
  70305. +
  70306. + if (!cam) {
  70307. + printk(KERN_ERR "private is NULL\n");
  70308. + return -EIO;
  70309. + }
  70310. +
  70311. + if (cam->overlay_active == true) {
  70312. + pr_debug("already started.\n");
  70313. + return 0;
  70314. + }
  70315. +
  70316. + get_disp_ipu(cam);
  70317. +
  70318. + for (i = 0; i < num_registered_fb; i++) {
  70319. + char *idstr = registered_fb[i]->fix.id;
  70320. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  70321. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  70322. + fbi = registered_fb[i];
  70323. + break;
  70324. + }
  70325. + }
  70326. +
  70327. + if (fbi == NULL) {
  70328. + printk(KERN_ERR "DISP FG fb not found\n");
  70329. + return -EPERM;
  70330. + }
  70331. +
  70332. + fbvar = fbi->var;
  70333. +
  70334. + /* Store the overlay frame buffer's original std */
  70335. + cam->fb_origin_std = fbvar.nonstd;
  70336. +
  70337. + if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
  70338. + /* Use DP to do CSC so that we can get better performance */
  70339. + vf_out_format = IPU_PIX_FMT_NV12;
  70340. + fbvar.nonstd = vf_out_format;
  70341. + } else {
  70342. + vf_out_format = IPU_PIX_FMT_RGB565;
  70343. + fbvar.nonstd = 0;
  70344. + }
  70345. +
  70346. + fbvar.bits_per_pixel = 16;
  70347. + fbvar.xres = fbvar.xres_virtual = cam->win.w.width;
  70348. + fbvar.yres = cam->win.w.height;
  70349. + fbvar.yres_virtual = cam->win.w.height * 2;
  70350. + fbvar.yoffset = 0;
  70351. + fbvar.vmode &= ~FB_VMODE_YWRAP;
  70352. + fbvar.accel_flags = FB_ACCEL_DOUBLE_FLAG;
  70353. + fbvar.activate |= FB_ACTIVATE_FORCE;
  70354. + fb_set_var(fbi, &fbvar);
  70355. +
  70356. + ipu_disp_set_window_pos(disp_ipu, MEM_FG_SYNC, cam->win.w.left,
  70357. + cam->win.w.top);
  70358. +
  70359. + /* Fill black color for framebuffer */
  70360. + base = (char *) fbi->screen_base;
  70361. + screen_size = fbi->var.xres * fbi->var.yres;
  70362. + if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
  70363. + memset(base, 0, screen_size);
  70364. + base += screen_size;
  70365. + for (i = 0; i < screen_size / 2; i++, base++)
  70366. + *base = 0x80;
  70367. + } else {
  70368. + for (i = 0; i < screen_size * 2; i++, base++)
  70369. + *base = 0x00;
  70370. + }
  70371. +
  70372. + console_lock();
  70373. + fb_blank(fbi, FB_BLANK_UNBLANK);
  70374. + console_unlock();
  70375. +
  70376. + /* correct display ch buffer address */
  70377. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  70378. + 0, fbi->fix.smem_start +
  70379. + (fbi->fix.line_length * fbvar.yres));
  70380. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  70381. + 1, fbi->fix.smem_start);
  70382. +
  70383. + err = csi_enc_enabling_tasks(cam);
  70384. + if (err != 0) {
  70385. + printk(KERN_ERR "Error csi enc enable fail\n");
  70386. + return err;
  70387. + }
  70388. +
  70389. + cam->overlay_active = true;
  70390. + return err;
  70391. +
  70392. +}
  70393. +
  70394. +/*!
  70395. + * foreground_stop - stop the vf task
  70396. + *
  70397. + * @param private cam_data * mxc v4l2 main structure
  70398. + *
  70399. + */
  70400. +static int foreground_stop(void *private)
  70401. +{
  70402. + cam_data *cam = (cam_data *) private;
  70403. + int err = 0, i = 0;
  70404. + struct fb_info *fbi = NULL;
  70405. + struct fb_var_screeninfo fbvar;
  70406. +
  70407. +#ifdef CONFIG_MXC_MIPI_CSI2
  70408. + void *mipi_csi2_info;
  70409. + int ipu_id;
  70410. + int csi_id;
  70411. +#endif
  70412. +
  70413. + if (cam->overlay_active == false)
  70414. + return 0;
  70415. +
  70416. + err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
  70417. +
  70418. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  70419. +
  70420. + csi_buffer_num = 0;
  70421. + buffer_num = 0;
  70422. +
  70423. + for (i = 0; i < num_registered_fb; i++) {
  70424. + char *idstr = registered_fb[i]->fix.id;
  70425. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  70426. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  70427. + fbi = registered_fb[i];
  70428. + break;
  70429. + }
  70430. + }
  70431. +
  70432. + if (fbi == NULL) {
  70433. + printk(KERN_ERR "DISP FG fb not found\n");
  70434. + return -EPERM;
  70435. + }
  70436. +
  70437. + console_lock();
  70438. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  70439. + console_unlock();
  70440. +
  70441. + /* Set the overlay frame buffer std to what it is used to be */
  70442. + fbvar = fbi->var;
  70443. + fbvar.accel_flags = FB_ACCEL_TRIPLE_FLAG;
  70444. + fbvar.nonstd = cam->fb_origin_std;
  70445. + fbvar.activate |= FB_ACTIVATE_FORCE;
  70446. + fb_set_var(fbi, &fbvar);
  70447. +
  70448. +#ifdef CONFIG_MXC_MIPI_CSI2
  70449. + mipi_csi2_info = mipi_csi2_get_info();
  70450. +
  70451. + if (mipi_csi2_info) {
  70452. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  70453. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  70454. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  70455. +
  70456. + if (cam->ipu == ipu_get_soc(ipu_id)
  70457. + && cam->csi == csi_id)
  70458. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  70459. + }
  70460. + }
  70461. +#endif
  70462. +
  70463. + flush_work(&cam->csi_work_struct);
  70464. + cancel_work_sync(&cam->csi_work_struct);
  70465. +
  70466. + if (cam->vf_bufs_vaddr[0]) {
  70467. + dma_free_coherent(0, cam->vf_bufs_size[0],
  70468. + cam->vf_bufs_vaddr[0],
  70469. + (dma_addr_t) cam->vf_bufs[0]);
  70470. + cam->vf_bufs_vaddr[0] = NULL;
  70471. + cam->vf_bufs[0] = 0;
  70472. + }
  70473. + if (cam->vf_bufs_vaddr[1]) {
  70474. + dma_free_coherent(0, cam->vf_bufs_size[1],
  70475. + cam->vf_bufs_vaddr[1],
  70476. + (dma_addr_t) cam->vf_bufs[1]);
  70477. + cam->vf_bufs_vaddr[1] = NULL;
  70478. + cam->vf_bufs[1] = 0;
  70479. + }
  70480. +
  70481. + cam->overlay_active = false;
  70482. + return err;
  70483. +}
  70484. +
  70485. +/*!
  70486. + * Enable csi
  70487. + * @param private struct cam_data * mxc capture instance
  70488. + *
  70489. + * @return status
  70490. + */
  70491. +static int foreground_enable_csi(void *private)
  70492. +{
  70493. + cam_data *cam = (cam_data *) private;
  70494. +
  70495. + return ipu_enable_csi(cam->ipu, cam->csi);
  70496. +}
  70497. +
  70498. +/*!
  70499. + * Disable csi
  70500. + * @param private struct cam_data * mxc capture instance
  70501. + *
  70502. + * @return status
  70503. + */
  70504. +static int foreground_disable_csi(void *private)
  70505. +{
  70506. + cam_data *cam = (cam_data *) private;
  70507. +
  70508. + /* free csi eof irq firstly.
  70509. + * when disable csi, wait for idmac eof.
  70510. + * it requests eof irq again */
  70511. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  70512. +
  70513. + return ipu_disable_csi(cam->ipu, cam->csi);
  70514. +}
  70515. +
  70516. +/*!
  70517. + * function to select foreground as the working path
  70518. + *
  70519. + * @param private cam_data * mxc v4l2 main structure
  70520. + *
  70521. + * @return status
  70522. + */
  70523. +int foreground_sdc_select(void *private)
  70524. +{
  70525. + cam_data *cam;
  70526. + int err = 0;
  70527. + if (private) {
  70528. + cam = (cam_data *) private;
  70529. + cam->vf_start_sdc = foreground_start;
  70530. + cam->vf_stop_sdc = foreground_stop;
  70531. + cam->vf_enable_csi = foreground_enable_csi;
  70532. + cam->vf_disable_csi = foreground_disable_csi;
  70533. + cam->overlay_active = false;
  70534. + } else
  70535. + err = -EIO;
  70536. +
  70537. + return err;
  70538. +}
  70539. +EXPORT_SYMBOL(foreground_sdc_select);
  70540. +
  70541. +/*!
  70542. + * function to de-select foreground as the working path
  70543. + *
  70544. + * @param private cam_data * mxc v4l2 main structure
  70545. + *
  70546. + * @return int
  70547. + */
  70548. +int foreground_sdc_deselect(void *private)
  70549. +{
  70550. + cam_data *cam;
  70551. +
  70552. + if (private) {
  70553. + cam = (cam_data *) private;
  70554. + cam->vf_start_sdc = NULL;
  70555. + cam->vf_stop_sdc = NULL;
  70556. + cam->vf_enable_csi = NULL;
  70557. + cam->vf_disable_csi = NULL;
  70558. + }
  70559. + return 0;
  70560. +}
  70561. +EXPORT_SYMBOL(foreground_sdc_deselect);
  70562. +
  70563. +/*!
  70564. + * Init viewfinder task.
  70565. + *
  70566. + * @return Error code indicating success or failure
  70567. + */
  70568. +__init int foreground_sdc_init(void)
  70569. +{
  70570. + return 0;
  70571. +}
  70572. +
  70573. +/*!
  70574. + * Deinit viewfinder task.
  70575. + *
  70576. + * @return Error code indicating success or failure
  70577. + */
  70578. +void __exit foreground_sdc_exit(void)
  70579. +{
  70580. +}
  70581. +
  70582. +module_init(foreground_sdc_init);
  70583. +module_exit(foreground_sdc_exit);
  70584. +
  70585. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  70586. +MODULE_DESCRIPTION("IPU PRP VF SDC Driver");
  70587. +MODULE_LICENSE("GPL");
  70588. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/ipu_prp_enc.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_prp_enc.c
  70589. --- linux-3.14.15/drivers/media/platform/mxc/capture/ipu_prp_enc.c 1970-01-01 01:00:00.000000000 +0100
  70590. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_prp_enc.c 2014-08-20 19:31:45.440866052 +0200
  70591. @@ -0,0 +1,595 @@
  70592. +/*
  70593. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  70594. + */
  70595. +
  70596. +/*
  70597. + * The code contained herein is licensed under the GNU General Public
  70598. + * License. You may obtain a copy of the GNU General Public License
  70599. + * Version 2 or later at the following locations:
  70600. + *
  70601. + * http://www.opensource.org/licenses/gpl-license.html
  70602. + * http://www.gnu.org/copyleft/gpl.html
  70603. + */
  70604. +
  70605. +/*!
  70606. + * @file ipu_prp_enc.c
  70607. + *
  70608. + * @brief IPU Use case for PRP-ENC
  70609. + *
  70610. + * @ingroup IPU
  70611. + */
  70612. +
  70613. +#include <linux/module.h>
  70614. +#include <linux/dma-mapping.h>
  70615. +#include <linux/platform_device.h>
  70616. +#include <linux/ipu.h>
  70617. +#include <linux/mipi_csi2.h>
  70618. +#include "mxc_v4l2_capture.h"
  70619. +#include "ipu_prp_sw.h"
  70620. +
  70621. +#ifdef CAMERA_DBG
  70622. + #define CAMERA_TRACE(x) (printk)x
  70623. +#else
  70624. + #define CAMERA_TRACE(x)
  70625. +#endif
  70626. +
  70627. +static ipu_rotate_mode_t grotation = IPU_ROTATE_NONE;
  70628. +
  70629. +/*
  70630. + * Function definitions
  70631. + */
  70632. +
  70633. +/*!
  70634. + * IPU ENC callback function.
  70635. + *
  70636. + * @param irq int irq line
  70637. + * @param dev_id void * device id
  70638. + *
  70639. + * @return status IRQ_HANDLED for handled
  70640. + */
  70641. +static irqreturn_t prp_enc_callback(int irq, void *dev_id)
  70642. +{
  70643. + cam_data *cam = (cam_data *) dev_id;
  70644. +
  70645. + if (cam->enc_callback == NULL)
  70646. + return IRQ_HANDLED;
  70647. +
  70648. + cam->enc_callback(irq, dev_id);
  70649. +
  70650. + return IRQ_HANDLED;
  70651. +}
  70652. +
  70653. +/*!
  70654. + * PrpENC enable channel setup function
  70655. + *
  70656. + * @param cam struct cam_data * mxc capture instance
  70657. + *
  70658. + * @return status
  70659. + */
  70660. +static int prp_enc_setup(cam_data *cam)
  70661. +{
  70662. + ipu_channel_params_t enc;
  70663. + int err = 0;
  70664. + dma_addr_t dummy = cam->dummy_frame.buffer.m.offset;
  70665. +#ifdef CONFIG_MXC_MIPI_CSI2
  70666. + void *mipi_csi2_info;
  70667. + int ipu_id;
  70668. + int csi_id;
  70669. +#endif
  70670. +
  70671. + CAMERA_TRACE("In prp_enc_setup\n");
  70672. + if (!cam) {
  70673. + printk(KERN_ERR "cam private is NULL\n");
  70674. + return -ENXIO;
  70675. + }
  70676. + memset(&enc, 0, sizeof(ipu_channel_params_t));
  70677. +
  70678. + ipu_csi_get_window_size(cam->ipu, &enc.csi_prp_enc_mem.in_width,
  70679. + &enc.csi_prp_enc_mem.in_height, cam->csi);
  70680. +
  70681. + enc.csi_prp_enc_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
  70682. + enc.csi_prp_enc_mem.out_width = cam->v2f.fmt.pix.width;
  70683. + enc.csi_prp_enc_mem.out_height = cam->v2f.fmt.pix.height;
  70684. + enc.csi_prp_enc_mem.csi = cam->csi;
  70685. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  70686. + enc.csi_prp_enc_mem.out_width = cam->v2f.fmt.pix.height;
  70687. + enc.csi_prp_enc_mem.out_height = cam->v2f.fmt.pix.width;
  70688. + }
  70689. +
  70690. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
  70691. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUV420P;
  70692. + pr_info("YUV420\n");
  70693. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) {
  70694. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YVU420P;
  70695. + pr_info("YVU420\n");
  70696. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) {
  70697. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUV422P;
  70698. + pr_info("YUV422P\n");
  70699. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
  70700. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUYV;
  70701. + pr_info("YUYV\n");
  70702. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) {
  70703. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_UYVY;
  70704. + pr_info("UYVY\n");
  70705. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12) {
  70706. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_NV12;
  70707. + pr_info("NV12\n");
  70708. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) {
  70709. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_BGR24;
  70710. + pr_info("BGR24\n");
  70711. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
  70712. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB24;
  70713. + pr_info("RGB24\n");
  70714. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
  70715. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB565;
  70716. + pr_info("RGB565\n");
  70717. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32) {
  70718. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_BGR32;
  70719. + pr_info("BGR32\n");
  70720. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32) {
  70721. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB32;
  70722. + pr_info("RGB32\n");
  70723. + } else {
  70724. + printk(KERN_ERR "format not supported\n");
  70725. + return -EINVAL;
  70726. + }
  70727. +
  70728. +#ifdef CONFIG_MXC_MIPI_CSI2
  70729. + mipi_csi2_info = mipi_csi2_get_info();
  70730. +
  70731. + if (mipi_csi2_info) {
  70732. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  70733. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  70734. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  70735. +
  70736. + if (cam->ipu == ipu_get_soc(ipu_id)
  70737. + && cam->csi == csi_id) {
  70738. + enc.csi_prp_enc_mem.mipi_en = true;
  70739. + enc.csi_prp_enc_mem.mipi_vc =
  70740. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  70741. + enc.csi_prp_enc_mem.mipi_id =
  70742. + mipi_csi2_get_datatype(mipi_csi2_info);
  70743. +
  70744. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  70745. + } else {
  70746. + enc.csi_prp_enc_mem.mipi_en = false;
  70747. + enc.csi_prp_enc_mem.mipi_vc = 0;
  70748. + enc.csi_prp_enc_mem.mipi_id = 0;
  70749. + }
  70750. + } else {
  70751. + enc.csi_prp_enc_mem.mipi_en = false;
  70752. + enc.csi_prp_enc_mem.mipi_vc = 0;
  70753. + enc.csi_prp_enc_mem.mipi_id = 0;
  70754. + }
  70755. + }
  70756. +#endif
  70757. +
  70758. + err = ipu_init_channel(cam->ipu, CSI_PRP_ENC_MEM, &enc);
  70759. + if (err != 0) {
  70760. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  70761. + return err;
  70762. + }
  70763. +
  70764. + grotation = cam->rotation;
  70765. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  70766. + if (cam->rot_enc_bufs_vaddr[0]) {
  70767. + dma_free_coherent(0, cam->rot_enc_buf_size[0],
  70768. + cam->rot_enc_bufs_vaddr[0],
  70769. + cam->rot_enc_bufs[0]);
  70770. + }
  70771. + if (cam->rot_enc_bufs_vaddr[1]) {
  70772. + dma_free_coherent(0, cam->rot_enc_buf_size[1],
  70773. + cam->rot_enc_bufs_vaddr[1],
  70774. + cam->rot_enc_bufs[1]);
  70775. + }
  70776. + cam->rot_enc_buf_size[0] =
  70777. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  70778. + cam->rot_enc_bufs_vaddr[0] =
  70779. + (void *)dma_alloc_coherent(0, cam->rot_enc_buf_size[0],
  70780. + &cam->rot_enc_bufs[0],
  70781. + GFP_DMA | GFP_KERNEL);
  70782. + if (!cam->rot_enc_bufs_vaddr[0]) {
  70783. + printk(KERN_ERR "alloc enc_bufs0\n");
  70784. + return -ENOMEM;
  70785. + }
  70786. + cam->rot_enc_buf_size[1] =
  70787. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  70788. + cam->rot_enc_bufs_vaddr[1] =
  70789. + (void *)dma_alloc_coherent(0, cam->rot_enc_buf_size[1],
  70790. + &cam->rot_enc_bufs[1],
  70791. + GFP_DMA | GFP_KERNEL);
  70792. + if (!cam->rot_enc_bufs_vaddr[1]) {
  70793. + dma_free_coherent(0, cam->rot_enc_buf_size[0],
  70794. + cam->rot_enc_bufs_vaddr[0],
  70795. + cam->rot_enc_bufs[0]);
  70796. + cam->rot_enc_bufs_vaddr[0] = NULL;
  70797. + cam->rot_enc_bufs[0] = 0;
  70798. + printk(KERN_ERR "alloc enc_bufs1\n");
  70799. + return -ENOMEM;
  70800. + }
  70801. +
  70802. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  70803. + IPU_OUTPUT_BUFFER,
  70804. + enc.csi_prp_enc_mem.out_pixel_fmt,
  70805. + enc.csi_prp_enc_mem.out_width,
  70806. + enc.csi_prp_enc_mem.out_height,
  70807. + enc.csi_prp_enc_mem.out_width,
  70808. + IPU_ROTATE_NONE,
  70809. + cam->rot_enc_bufs[0],
  70810. + cam->rot_enc_bufs[1], 0, 0, 0);
  70811. + if (err != 0) {
  70812. + printk(KERN_ERR "CSI_PRP_ENC_MEM err\n");
  70813. + return err;
  70814. + }
  70815. +
  70816. + err = ipu_init_channel(cam->ipu, MEM_ROT_ENC_MEM, NULL);
  70817. + if (err != 0) {
  70818. + printk(KERN_ERR "MEM_ROT_ENC_MEM channel err\n");
  70819. + return err;
  70820. + }
  70821. +
  70822. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_ENC_MEM,
  70823. + IPU_INPUT_BUFFER,
  70824. + enc.csi_prp_enc_mem.out_pixel_fmt,
  70825. + enc.csi_prp_enc_mem.out_width,
  70826. + enc.csi_prp_enc_mem.out_height,
  70827. + enc.csi_prp_enc_mem.out_width,
  70828. + cam->rotation,
  70829. + cam->rot_enc_bufs[0],
  70830. + cam->rot_enc_bufs[1], 0, 0, 0);
  70831. + if (err != 0) {
  70832. + printk(KERN_ERR "MEM_ROT_ENC_MEM input buffer\n");
  70833. + return err;
  70834. + }
  70835. +
  70836. + err =
  70837. + ipu_init_channel_buffer(cam->ipu, MEM_ROT_ENC_MEM,
  70838. + IPU_OUTPUT_BUFFER,
  70839. + enc.csi_prp_enc_mem.out_pixel_fmt,
  70840. + enc.csi_prp_enc_mem.out_height,
  70841. + enc.csi_prp_enc_mem.out_width,
  70842. + cam->v2f.fmt.pix.bytesperline /
  70843. + bytes_per_pixel(enc.csi_prp_enc_mem.
  70844. + out_pixel_fmt),
  70845. + IPU_ROTATE_NONE,
  70846. + dummy, dummy, 0,
  70847. + cam->offset.u_offset,
  70848. + cam->offset.v_offset);
  70849. + if (err != 0) {
  70850. + printk(KERN_ERR "MEM_ROT_ENC_MEM output buffer\n");
  70851. + return err;
  70852. + }
  70853. +
  70854. + err = ipu_link_channels(cam->ipu,
  70855. + CSI_PRP_ENC_MEM, MEM_ROT_ENC_MEM);
  70856. + if (err < 0) {
  70857. + printk(KERN_ERR
  70858. + "link CSI_PRP_ENC_MEM-MEM_ROT_ENC_MEM\n");
  70859. + return err;
  70860. + }
  70861. +
  70862. + err = ipu_enable_channel(cam->ipu, CSI_PRP_ENC_MEM);
  70863. + if (err < 0) {
  70864. + printk(KERN_ERR "ipu_enable_channel CSI_PRP_ENC_MEM\n");
  70865. + return err;
  70866. + }
  70867. + err = ipu_enable_channel(cam->ipu, MEM_ROT_ENC_MEM);
  70868. + if (err < 0) {
  70869. + printk(KERN_ERR "ipu_enable_channel MEM_ROT_ENC_MEM\n");
  70870. + return err;
  70871. + }
  70872. +
  70873. + ipu_select_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  70874. + IPU_OUTPUT_BUFFER, 0);
  70875. + ipu_select_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  70876. + IPU_OUTPUT_BUFFER, 1);
  70877. + } else {
  70878. + err =
  70879. + ipu_init_channel_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  70880. + IPU_OUTPUT_BUFFER,
  70881. + enc.csi_prp_enc_mem.out_pixel_fmt,
  70882. + enc.csi_prp_enc_mem.out_width,
  70883. + enc.csi_prp_enc_mem.out_height,
  70884. + cam->v2f.fmt.pix.bytesperline /
  70885. + bytes_per_pixel(enc.csi_prp_enc_mem.
  70886. + out_pixel_fmt),
  70887. + cam->rotation,
  70888. + dummy, dummy, 0,
  70889. + cam->offset.u_offset,
  70890. + cam->offset.v_offset);
  70891. + if (err != 0) {
  70892. + printk(KERN_ERR "CSI_PRP_ENC_MEM output buffer\n");
  70893. + return err;
  70894. + }
  70895. + err = ipu_enable_channel(cam->ipu, CSI_PRP_ENC_MEM);
  70896. + if (err < 0) {
  70897. + printk(KERN_ERR "ipu_enable_channel CSI_PRP_ENC_MEM\n");
  70898. + return err;
  70899. + }
  70900. + }
  70901. +
  70902. + return err;
  70903. +}
  70904. +
  70905. +/*!
  70906. + * function to update physical buffer address for encorder IDMA channel
  70907. + *
  70908. + * @param eba physical buffer address for encorder IDMA channel
  70909. + * @param buffer_num int buffer 0 or buffer 1
  70910. + *
  70911. + * @return status
  70912. + */
  70913. +static int prp_enc_eba_update(struct ipu_soc *ipu, dma_addr_t eba,
  70914. + int *buffer_num)
  70915. +{
  70916. + int err = 0;
  70917. +
  70918. + pr_debug("eba %x\n", eba);
  70919. + if (grotation >= IPU_ROTATE_90_RIGHT) {
  70920. + err = ipu_update_channel_buffer(ipu, MEM_ROT_ENC_MEM,
  70921. + IPU_OUTPUT_BUFFER, *buffer_num,
  70922. + eba);
  70923. + } else {
  70924. + err = ipu_update_channel_buffer(ipu, CSI_PRP_ENC_MEM,
  70925. + IPU_OUTPUT_BUFFER, *buffer_num,
  70926. + eba);
  70927. + }
  70928. + if (err != 0) {
  70929. + if (grotation >= IPU_ROTATE_90_RIGHT) {
  70930. + ipu_clear_buffer_ready(ipu, MEM_ROT_ENC_MEM,
  70931. + IPU_OUTPUT_BUFFER,
  70932. + *buffer_num);
  70933. + err = ipu_update_channel_buffer(ipu, MEM_ROT_ENC_MEM,
  70934. + IPU_OUTPUT_BUFFER,
  70935. + *buffer_num,
  70936. + eba);
  70937. + } else {
  70938. + ipu_clear_buffer_ready(ipu, CSI_PRP_ENC_MEM,
  70939. + IPU_OUTPUT_BUFFER,
  70940. + *buffer_num);
  70941. + err = ipu_update_channel_buffer(ipu, CSI_PRP_ENC_MEM,
  70942. + IPU_OUTPUT_BUFFER,
  70943. + *buffer_num,
  70944. + eba);
  70945. + }
  70946. +
  70947. + if (err != 0) {
  70948. + pr_err("ERROR: v4l2 capture: fail to update "
  70949. + "buf%d\n", *buffer_num);
  70950. + return err;
  70951. + }
  70952. + }
  70953. +
  70954. + if (grotation >= IPU_ROTATE_90_RIGHT) {
  70955. + ipu_select_buffer(ipu, MEM_ROT_ENC_MEM, IPU_OUTPUT_BUFFER,
  70956. + *buffer_num);
  70957. + } else {
  70958. + ipu_select_buffer(ipu, CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER,
  70959. + *buffer_num);
  70960. + }
  70961. +
  70962. + *buffer_num = (*buffer_num == 0) ? 1 : 0;
  70963. + return 0;
  70964. +}
  70965. +
  70966. +/*!
  70967. + * Enable encoder task
  70968. + * @param private struct cam_data * mxc capture instance
  70969. + *
  70970. + * @return status
  70971. + */
  70972. +static int prp_enc_enabling_tasks(void *private)
  70973. +{
  70974. + cam_data *cam = (cam_data *) private;
  70975. + int err = 0;
  70976. + CAMERA_TRACE("IPU:In prp_enc_enabling_tasks\n");
  70977. +
  70978. + cam->dummy_frame.vaddress = dma_alloc_coherent(0,
  70979. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  70980. + &cam->dummy_frame.paddress,
  70981. + GFP_DMA | GFP_KERNEL);
  70982. + if (cam->dummy_frame.vaddress == 0) {
  70983. + pr_err("ERROR: v4l2 capture: Allocate dummy frame "
  70984. + "failed.\n");
  70985. + return -ENOBUFS;
  70986. + }
  70987. + cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
  70988. + cam->dummy_frame.buffer.length =
  70989. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  70990. + cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
  70991. +
  70992. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  70993. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_ENC_ROT_OUT_EOF,
  70994. + prp_enc_callback, 0, "Mxc Camera", cam);
  70995. + } else {
  70996. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_ENC_OUT_EOF,
  70997. + prp_enc_callback, 0, "Mxc Camera", cam);
  70998. + }
  70999. + if (err != 0) {
  71000. + printk(KERN_ERR "Error registering rot irq\n");
  71001. + return err;
  71002. + }
  71003. +
  71004. + err = prp_enc_setup(cam);
  71005. + if (err != 0) {
  71006. + printk(KERN_ERR "prp_enc_setup %d\n", err);
  71007. + return err;
  71008. + }
  71009. +
  71010. + return err;
  71011. +}
  71012. +
  71013. +/*!
  71014. + * Disable encoder task
  71015. + * @param private struct cam_data * mxc capture instance
  71016. + *
  71017. + * @return int
  71018. + */
  71019. +static int prp_enc_disabling_tasks(void *private)
  71020. +{
  71021. + cam_data *cam = (cam_data *) private;
  71022. + int err = 0;
  71023. +#ifdef CONFIG_MXC_MIPI_CSI2
  71024. + void *mipi_csi2_info;
  71025. + int ipu_id;
  71026. + int csi_id;
  71027. +#endif
  71028. +
  71029. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  71030. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_ENC_ROT_OUT_EOF, cam);
  71031. + ipu_unlink_channels(cam->ipu, CSI_PRP_ENC_MEM, MEM_ROT_ENC_MEM);
  71032. + }
  71033. +
  71034. + err = ipu_disable_channel(cam->ipu, CSI_PRP_ENC_MEM, true);
  71035. + if (cam->rotation >= IPU_ROTATE_90_RIGHT)
  71036. + err |= ipu_disable_channel(cam->ipu, MEM_ROT_ENC_MEM, true);
  71037. +
  71038. + ipu_uninit_channel(cam->ipu, CSI_PRP_ENC_MEM);
  71039. + if (cam->rotation >= IPU_ROTATE_90_RIGHT)
  71040. + ipu_uninit_channel(cam->ipu, MEM_ROT_ENC_MEM);
  71041. +
  71042. + if (cam->dummy_frame.vaddress != 0) {
  71043. + dma_free_coherent(0, cam->dummy_frame.buffer.length,
  71044. + cam->dummy_frame.vaddress,
  71045. + cam->dummy_frame.paddress);
  71046. + cam->dummy_frame.vaddress = 0;
  71047. + }
  71048. +
  71049. +#ifdef CONFIG_MXC_MIPI_CSI2
  71050. + mipi_csi2_info = mipi_csi2_get_info();
  71051. +
  71052. + if (mipi_csi2_info) {
  71053. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  71054. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  71055. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  71056. +
  71057. + if (cam->ipu == ipu_get_soc(ipu_id)
  71058. + && cam->csi == csi_id)
  71059. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  71060. + }
  71061. + }
  71062. +#endif
  71063. +
  71064. + return err;
  71065. +}
  71066. +
  71067. +/*!
  71068. + * Enable csi
  71069. + * @param private struct cam_data * mxc capture instance
  71070. + *
  71071. + * @return status
  71072. + */
  71073. +static int prp_enc_enable_csi(void *private)
  71074. +{
  71075. + cam_data *cam = (cam_data *) private;
  71076. +
  71077. + return ipu_enable_csi(cam->ipu, cam->csi);
  71078. +}
  71079. +
  71080. +/*!
  71081. + * Disable csi
  71082. + * @param private struct cam_data * mxc capture instance
  71083. + *
  71084. + * @return status
  71085. + */
  71086. +static int prp_enc_disable_csi(void *private)
  71087. +{
  71088. + cam_data *cam = (cam_data *) private;
  71089. +
  71090. + /* free csi eof irq firstly.
  71091. + * when disable csi, wait for idmac eof.
  71092. + * it requests eof irq again */
  71093. + if (cam->rotation < IPU_ROTATE_90_RIGHT)
  71094. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_ENC_OUT_EOF, cam);
  71095. +
  71096. + return ipu_disable_csi(cam->ipu, cam->csi);
  71097. +}
  71098. +
  71099. +/*!
  71100. + * function to select PRP-ENC as the working path
  71101. + *
  71102. + * @param private struct cam_data * mxc capture instance
  71103. + *
  71104. + * @return int
  71105. + */
  71106. +int prp_enc_select(void *private)
  71107. +{
  71108. + cam_data *cam = (cam_data *) private;
  71109. + int err = 0;
  71110. +
  71111. + if (cam) {
  71112. + cam->enc_update_eba = prp_enc_eba_update;
  71113. + cam->enc_enable = prp_enc_enabling_tasks;
  71114. + cam->enc_disable = prp_enc_disabling_tasks;
  71115. + cam->enc_enable_csi = prp_enc_enable_csi;
  71116. + cam->enc_disable_csi = prp_enc_disable_csi;
  71117. + } else {
  71118. + err = -EIO;
  71119. + }
  71120. +
  71121. + return err;
  71122. +}
  71123. +EXPORT_SYMBOL(prp_enc_select);
  71124. +
  71125. +/*!
  71126. + * function to de-select PRP-ENC as the working path
  71127. + *
  71128. + * @param private struct cam_data * mxc capture instance
  71129. + *
  71130. + * @return int
  71131. + */
  71132. +int prp_enc_deselect(void *private)
  71133. +{
  71134. + cam_data *cam = (cam_data *) private;
  71135. + int err = 0;
  71136. +
  71137. + if (cam) {
  71138. + cam->enc_update_eba = NULL;
  71139. + cam->enc_enable = NULL;
  71140. + cam->enc_disable = NULL;
  71141. + cam->enc_enable_csi = NULL;
  71142. + cam->enc_disable_csi = NULL;
  71143. + if (cam->rot_enc_bufs_vaddr[0]) {
  71144. + dma_free_coherent(0, cam->rot_enc_buf_size[0],
  71145. + cam->rot_enc_bufs_vaddr[0],
  71146. + cam->rot_enc_bufs[0]);
  71147. + cam->rot_enc_bufs_vaddr[0] = NULL;
  71148. + cam->rot_enc_bufs[0] = 0;
  71149. + }
  71150. + if (cam->rot_enc_bufs_vaddr[1]) {
  71151. + dma_free_coherent(0, cam->rot_enc_buf_size[1],
  71152. + cam->rot_enc_bufs_vaddr[1],
  71153. + cam->rot_enc_bufs[1]);
  71154. + cam->rot_enc_bufs_vaddr[1] = NULL;
  71155. + cam->rot_enc_bufs[1] = 0;
  71156. + }
  71157. + }
  71158. +
  71159. + return err;
  71160. +}
  71161. +EXPORT_SYMBOL(prp_enc_deselect);
  71162. +
  71163. +/*!
  71164. + * Init the Encorder channels
  71165. + *
  71166. + * @return Error code indicating success or failure
  71167. + */
  71168. +__init int prp_enc_init(void)
  71169. +{
  71170. + return 0;
  71171. +}
  71172. +
  71173. +/*!
  71174. + * Deinit the Encorder channels
  71175. + *
  71176. + */
  71177. +void __exit prp_enc_exit(void)
  71178. +{
  71179. +}
  71180. +
  71181. +module_init(prp_enc_init);
  71182. +module_exit(prp_enc_exit);
  71183. +
  71184. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  71185. +MODULE_DESCRIPTION("IPU PRP ENC Driver");
  71186. +MODULE_LICENSE("GPL");
  71187. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/ipu_prp_sw.h linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_prp_sw.h
  71188. --- linux-3.14.15/drivers/media/platform/mxc/capture/ipu_prp_sw.h 1970-01-01 01:00:00.000000000 +0100
  71189. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_prp_sw.h 2014-08-20 19:23:52.818842679 +0200
  71190. @@ -0,0 +1,43 @@
  71191. +/*
  71192. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  71193. + */
  71194. +
  71195. +/*
  71196. + * The code contained herein is licensed under the GNU General Public
  71197. + * License. You may obtain a copy of the GNU General Public License
  71198. + * Version 2 or later at the following locations:
  71199. + *
  71200. + * http://www.opensource.org/licenses/gpl-license.html
  71201. + * http://www.gnu.org/copyleft/gpl.html
  71202. + */
  71203. +
  71204. +/*!
  71205. + * @file ipu_prp_sw.h
  71206. + *
  71207. + * @brief This file contains the IPU PRP use case driver header.
  71208. + *
  71209. + * @ingroup IPU
  71210. + */
  71211. +
  71212. +#ifndef _INCLUDE_IPU__PRP_SW_H_
  71213. +#define _INCLUDE_IPU__PRP_SW_H_
  71214. +
  71215. +int csi_enc_select(void *private);
  71216. +int csi_enc_deselect(void *private);
  71217. +int prp_enc_select(void *private);
  71218. +int prp_enc_deselect(void *private);
  71219. +#ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  71220. +int prp_vf_sdc_select(void *private);
  71221. +int prp_vf_sdc_deselect(void *private);
  71222. +int prp_vf_sdc_select_bg(void *private);
  71223. +int prp_vf_sdc_deselect_bg(void *private);
  71224. +#else
  71225. +int foreground_sdc_select(void *private);
  71226. +int foreground_sdc_deselect(void *private);
  71227. +int bg_overlay_sdc_select(void *private);
  71228. +int bg_overlay_sdc_deselect(void *private);
  71229. +#endif
  71230. +int prp_still_select(void *private);
  71231. +int prp_still_deselect(void *private);
  71232. +
  71233. +#endif
  71234. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c
  71235. --- linux-3.14.15/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c 1970-01-01 01:00:00.000000000 +0100
  71236. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c 2014-08-20 19:31:45.440866052 +0200
  71237. @@ -0,0 +1,521 @@
  71238. +/*
  71239. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  71240. + */
  71241. +
  71242. +/*
  71243. + * The code contained herein is licensed under the GNU General Public
  71244. + * License. You may obtain a copy of the GNU General Public License
  71245. + * Version 2 or later at the following locations:
  71246. + *
  71247. + * http://www.opensource.org/licenses/gpl-license.html
  71248. + * http://www.gnu.org/copyleft/gpl.html
  71249. + */
  71250. +
  71251. +/*!
  71252. + * @file ipu_prp_vf_sdc_bg.c
  71253. + *
  71254. + * @brief IPU Use case for PRP-VF back-ground
  71255. + *
  71256. + * @ingroup IPU
  71257. + */
  71258. +#include <linux/dma-mapping.h>
  71259. +#include <linux/fb.h>
  71260. +#include <linux/ipu.h>
  71261. +#include <linux/module.h>
  71262. +#include <mach/mipi_csi2.h>
  71263. +#include "mxc_v4l2_capture.h"
  71264. +#include "ipu_prp_sw.h"
  71265. +
  71266. +static int buffer_num;
  71267. +static int buffer_ready;
  71268. +static struct ipu_soc *disp_ipu;
  71269. +
  71270. +static void get_disp_ipu(cam_data *cam)
  71271. +{
  71272. + if (cam->output > 2)
  71273. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  71274. + else
  71275. + disp_ipu = ipu_get_soc(0);
  71276. +}
  71277. +
  71278. +/*
  71279. + * Function definitions
  71280. + */
  71281. +
  71282. +/*!
  71283. + * SDC V-Sync callback function.
  71284. + *
  71285. + * @param irq int irq line
  71286. + * @param dev_id void * device id
  71287. + *
  71288. + * @return status IRQ_HANDLED for handled
  71289. + */
  71290. +static irqreturn_t prpvf_sdc_vsync_callback(int irq, void *dev_id)
  71291. +{
  71292. + cam_data *cam = dev_id;
  71293. + if (buffer_ready > 0) {
  71294. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71295. + IPU_OUTPUT_BUFFER, 0);
  71296. + buffer_ready--;
  71297. + }
  71298. +
  71299. + return IRQ_HANDLED;
  71300. +}
  71301. +
  71302. +/*!
  71303. + * VF EOF callback function.
  71304. + *
  71305. + * @param irq int irq line
  71306. + * @param dev_id void * device id
  71307. + *
  71308. + * @return status IRQ_HANDLED for handled
  71309. + */
  71310. +static irqreturn_t prpvf_vf_eof_callback(int irq, void *dev_id)
  71311. +{
  71312. + cam_data *cam = dev_id;
  71313. + pr_debug("buffer_ready %d buffer_num %d\n", buffer_ready, buffer_num);
  71314. +
  71315. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71316. + IPU_INPUT_BUFFER, buffer_num);
  71317. + buffer_num = (buffer_num == 0) ? 1 : 0;
  71318. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  71319. + IPU_OUTPUT_BUFFER, buffer_num);
  71320. + buffer_ready++;
  71321. + return IRQ_HANDLED;
  71322. +}
  71323. +
  71324. +/*!
  71325. + * prpvf_start - start the vf task
  71326. + *
  71327. + * @param private cam_data * mxc v4l2 main structure
  71328. + *
  71329. + */
  71330. +static int prpvf_start(void *private)
  71331. +{
  71332. + cam_data *cam = (cam_data *) private;
  71333. + ipu_channel_params_t vf;
  71334. + u32 format;
  71335. + u32 offset;
  71336. + u32 bpp, size = 3;
  71337. + int err = 0;
  71338. +#ifdef CONFIG_MXC_MIPI_CSI2
  71339. + void *mipi_csi2_info;
  71340. + int ipu_id;
  71341. + int csi_id;
  71342. +#endif
  71343. +
  71344. + if (!cam) {
  71345. + printk(KERN_ERR "private is NULL\n");
  71346. + return -EIO;
  71347. + }
  71348. +
  71349. + if (cam->overlay_active == true) {
  71350. + pr_debug("already start.\n");
  71351. + return 0;
  71352. + }
  71353. +
  71354. + get_disp_ipu(cam);
  71355. +
  71356. + format = cam->v4l2_fb.fmt.pixelformat;
  71357. + if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR24) {
  71358. + bpp = 3, size = 3;
  71359. + pr_info("BGR24\n");
  71360. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_RGB565) {
  71361. + bpp = 2, size = 2;
  71362. + pr_info("RGB565\n");
  71363. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR32) {
  71364. + bpp = 4, size = 4;
  71365. + pr_info("BGR32\n");
  71366. + } else {
  71367. + printk(KERN_ERR
  71368. + "unsupported fix format from the framebuffer.\n");
  71369. + return -EINVAL;
  71370. + }
  71371. +
  71372. + offset = cam->v4l2_fb.fmt.bytesperline * cam->win.w.top +
  71373. + size * cam->win.w.left;
  71374. +
  71375. + if (cam->v4l2_fb.base == 0)
  71376. + printk(KERN_ERR "invalid frame buffer address.\n");
  71377. + else
  71378. + offset += (u32) cam->v4l2_fb.base;
  71379. +
  71380. + memset(&vf, 0, sizeof(ipu_channel_params_t));
  71381. + ipu_csi_get_window_size(cam->ipu, &vf.csi_prp_vf_mem.in_width,
  71382. + &vf.csi_prp_vf_mem.in_height, cam->csi);
  71383. + vf.csi_prp_vf_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
  71384. + vf.csi_prp_vf_mem.out_width = cam->win.w.width;
  71385. + vf.csi_prp_vf_mem.out_height = cam->win.w.height;
  71386. + vf.csi_prp_vf_mem.csi = cam->csi;
  71387. + if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
  71388. + vf.csi_prp_vf_mem.out_width = cam->win.w.height;
  71389. + vf.csi_prp_vf_mem.out_height = cam->win.w.width;
  71390. + }
  71391. + vf.csi_prp_vf_mem.out_pixel_fmt = format;
  71392. + size = cam->win.w.width * cam->win.w.height * size;
  71393. +
  71394. +#ifdef CONFIG_MXC_MIPI_CSI2
  71395. + mipi_csi2_info = mipi_csi2_get_info();
  71396. +
  71397. + if (mipi_csi2_info) {
  71398. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  71399. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  71400. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  71401. +
  71402. + if (cam->ipu == ipu_get_soc(ipu_id)
  71403. + && cam->csi == csi_id) {
  71404. + vf.csi_prp_vf_mem.mipi_en = true;
  71405. + vf.csi_prp_vf_mem.mipi_vc =
  71406. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  71407. + vf.csi_prp_vf_mem.mipi_id =
  71408. + mipi_csi2_get_datatype(mipi_csi2_info);
  71409. +
  71410. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  71411. + } else {
  71412. + vf.csi_prp_vf_mem.mipi_en = false;
  71413. + vf.csi_prp_vf_mem.mipi_vc = 0;
  71414. + vf.csi_prp_vf_mem.mipi_id = 0;
  71415. + }
  71416. + } else {
  71417. + vf.csi_prp_vf_mem.mipi_en = false;
  71418. + vf.csi_prp_vf_mem.mipi_vc = 0;
  71419. + vf.csi_prp_vf_mem.mipi_id = 0;
  71420. + }
  71421. + }
  71422. +#endif
  71423. +
  71424. + err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
  71425. + if (err != 0)
  71426. + goto out_4;
  71427. +
  71428. + if (cam->vf_bufs_vaddr[0]) {
  71429. + dma_free_coherent(0, cam->vf_bufs_size[0],
  71430. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  71431. + }
  71432. + if (cam->vf_bufs_vaddr[1]) {
  71433. + dma_free_coherent(0, cam->vf_bufs_size[1],
  71434. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  71435. + }
  71436. + cam->vf_bufs_size[0] = PAGE_ALIGN(size);
  71437. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  71438. + cam->vf_bufs_size[0],
  71439. + &cam->vf_bufs[0],
  71440. + GFP_DMA |
  71441. + GFP_KERNEL);
  71442. + if (cam->vf_bufs_vaddr[0] == NULL) {
  71443. + printk(KERN_ERR "Error to allocate vf buffer\n");
  71444. + err = -ENOMEM;
  71445. + goto out_3;
  71446. + }
  71447. + cam->vf_bufs_size[1] = PAGE_ALIGN(size);
  71448. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  71449. + cam->vf_bufs_size[1],
  71450. + &cam->vf_bufs[1],
  71451. + GFP_DMA |
  71452. + GFP_KERNEL);
  71453. + if (cam->vf_bufs_vaddr[1] == NULL) {
  71454. + printk(KERN_ERR "Error to allocate vf buffer\n");
  71455. + err = -ENOMEM;
  71456. + goto out_3;
  71457. + }
  71458. +
  71459. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
  71460. + IPU_OUTPUT_BUFFER,
  71461. + format, vf.csi_prp_vf_mem.out_width,
  71462. + vf.csi_prp_vf_mem.out_height,
  71463. + vf.csi_prp_vf_mem.out_width,
  71464. + IPU_ROTATE_NONE,
  71465. + cam->vf_bufs[0],
  71466. + cam->vf_bufs[1],
  71467. + 0, 0, 0);
  71468. + if (err != 0) {
  71469. + printk(KERN_ERR "Error initializing CSI_PRP_VF_MEM\n");
  71470. + goto out_3;
  71471. + }
  71472. + err = ipu_init_channel(cam->ipu, MEM_ROT_VF_MEM, NULL);
  71473. + if (err != 0) {
  71474. + printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n");
  71475. + goto out_3;
  71476. + }
  71477. +
  71478. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71479. + IPU_INPUT_BUFFER,
  71480. + format, vf.csi_prp_vf_mem.out_width,
  71481. + vf.csi_prp_vf_mem.out_height,
  71482. + vf.csi_prp_vf_mem.out_width,
  71483. + cam->vf_rotation,
  71484. + cam->vf_bufs[0],
  71485. + cam->vf_bufs[1],
  71486. + 0, 0, 0);
  71487. + if (err != 0) {
  71488. + printk(KERN_ERR "Error MEM_ROT_VF_MEM input buffer\n");
  71489. + goto out_2;
  71490. + }
  71491. +
  71492. + if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
  71493. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71494. + IPU_OUTPUT_BUFFER,
  71495. + format,
  71496. + vf.csi_prp_vf_mem.out_height,
  71497. + vf.csi_prp_vf_mem.out_width,
  71498. + cam->overlay_fb->var.xres * bpp,
  71499. + IPU_ROTATE_NONE,
  71500. + offset, 0, 0, 0, 0);
  71501. +
  71502. + if (err != 0) {
  71503. + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
  71504. + goto out_2;
  71505. + }
  71506. + } else {
  71507. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71508. + IPU_OUTPUT_BUFFER,
  71509. + format,
  71510. + vf.csi_prp_vf_mem.out_width,
  71511. + vf.csi_prp_vf_mem.out_height,
  71512. + cam->overlay_fb->var.xres * bpp,
  71513. + IPU_ROTATE_NONE,
  71514. + offset, 0, 0, 0, 0);
  71515. + if (err != 0) {
  71516. + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
  71517. + goto out_2;
  71518. + }
  71519. + }
  71520. +
  71521. + ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF);
  71522. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF,
  71523. + prpvf_vf_eof_callback,
  71524. + 0, "Mxc Camera", cam);
  71525. + if (err != 0) {
  71526. + printk(KERN_ERR
  71527. + "Error registering IPU_IRQ_PRP_VF_OUT_EOF irq.\n");
  71528. + goto out_2;
  71529. + }
  71530. +
  71531. + ipu_clear_irq(disp_ipu, IPU_IRQ_BG_SF_END);
  71532. + err = ipu_request_irq(disp_ipu, IPU_IRQ_BG_SF_END,
  71533. + prpvf_sdc_vsync_callback,
  71534. + 0, "Mxc Camera", cam);
  71535. + if (err != 0) {
  71536. + printk(KERN_ERR "Error registering IPU_IRQ_BG_SF_END irq.\n");
  71537. + goto out_1;
  71538. + }
  71539. +
  71540. + ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
  71541. + ipu_enable_channel(cam->ipu, MEM_ROT_VF_MEM);
  71542. +
  71543. + buffer_num = 0;
  71544. + buffer_ready = 0;
  71545. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, 0);
  71546. +
  71547. + cam->overlay_active = true;
  71548. + return err;
  71549. +
  71550. +out_1:
  71551. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, NULL);
  71552. +out_2:
  71553. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  71554. +out_3:
  71555. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  71556. +out_4:
  71557. + if (cam->vf_bufs_vaddr[0]) {
  71558. + dma_free_coherent(0, cam->vf_bufs_size[0],
  71559. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  71560. + cam->vf_bufs_vaddr[0] = NULL;
  71561. + cam->vf_bufs[0] = 0;
  71562. + }
  71563. + if (cam->vf_bufs_vaddr[1]) {
  71564. + dma_free_coherent(0, cam->vf_bufs_size[1],
  71565. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  71566. + cam->vf_bufs_vaddr[1] = NULL;
  71567. + cam->vf_bufs[1] = 0;
  71568. + }
  71569. + if (cam->rot_vf_bufs_vaddr[0]) {
  71570. + dma_free_coherent(0, cam->rot_vf_buf_size[0],
  71571. + cam->rot_vf_bufs_vaddr[0],
  71572. + cam->rot_vf_bufs[0]);
  71573. + cam->rot_vf_bufs_vaddr[0] = NULL;
  71574. + cam->rot_vf_bufs[0] = 0;
  71575. + }
  71576. + if (cam->rot_vf_bufs_vaddr[1]) {
  71577. + dma_free_coherent(0, cam->rot_vf_buf_size[1],
  71578. + cam->rot_vf_bufs_vaddr[1],
  71579. + cam->rot_vf_bufs[1]);
  71580. + cam->rot_vf_bufs_vaddr[1] = NULL;
  71581. + cam->rot_vf_bufs[1] = 0;
  71582. + }
  71583. + return err;
  71584. +}
  71585. +
  71586. +/*!
  71587. + * prpvf_stop - stop the vf task
  71588. + *
  71589. + * @param private cam_data * mxc v4l2 main structure
  71590. + *
  71591. + */
  71592. +static int prpvf_stop(void *private)
  71593. +{
  71594. + cam_data *cam = (cam_data *) private;
  71595. +#ifdef CONFIG_MXC_MIPI_CSI2
  71596. + void *mipi_csi2_info;
  71597. + int ipu_id;
  71598. + int csi_id;
  71599. +#endif
  71600. +
  71601. + if (cam->overlay_active == false)
  71602. + return 0;
  71603. +
  71604. + ipu_free_irq(disp_ipu, IPU_IRQ_BG_SF_END, cam);
  71605. +
  71606. + ipu_disable_channel(cam->ipu, CSI_PRP_VF_MEM, true);
  71607. + ipu_disable_channel(cam->ipu, MEM_ROT_VF_MEM, true);
  71608. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  71609. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  71610. +
  71611. +#ifdef CONFIG_MXC_MIPI_CSI2
  71612. + mipi_csi2_info = mipi_csi2_get_info();
  71613. +
  71614. + if (mipi_csi2_info) {
  71615. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  71616. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  71617. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  71618. +
  71619. + if (cam->ipu == ipu_get_soc(ipu_id)
  71620. + && cam->csi == csi_id)
  71621. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  71622. + }
  71623. + }
  71624. +#endif
  71625. +
  71626. + if (cam->vf_bufs_vaddr[0]) {
  71627. + dma_free_coherent(0, cam->vf_bufs_size[0],
  71628. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  71629. + cam->vf_bufs_vaddr[0] = NULL;
  71630. + cam->vf_bufs[0] = 0;
  71631. + }
  71632. + if (cam->vf_bufs_vaddr[1]) {
  71633. + dma_free_coherent(0, cam->vf_bufs_size[1],
  71634. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  71635. + cam->vf_bufs_vaddr[1] = NULL;
  71636. + cam->vf_bufs[1] = 0;
  71637. + }
  71638. + if (cam->rot_vf_bufs_vaddr[0]) {
  71639. + dma_free_coherent(0, cam->rot_vf_buf_size[0],
  71640. + cam->rot_vf_bufs_vaddr[0],
  71641. + cam->rot_vf_bufs[0]);
  71642. + cam->rot_vf_bufs_vaddr[0] = NULL;
  71643. + cam->rot_vf_bufs[0] = 0;
  71644. + }
  71645. + if (cam->rot_vf_bufs_vaddr[1]) {
  71646. + dma_free_coherent(0, cam->rot_vf_buf_size[1],
  71647. + cam->rot_vf_bufs_vaddr[1],
  71648. + cam->rot_vf_bufs[1]);
  71649. + cam->rot_vf_bufs_vaddr[1] = NULL;
  71650. + cam->rot_vf_bufs[1] = 0;
  71651. + }
  71652. +
  71653. + buffer_num = 0;
  71654. + buffer_ready = 0;
  71655. + cam->overlay_active = false;
  71656. + return 0;
  71657. +}
  71658. +
  71659. +/*!
  71660. + * Enable csi
  71661. + * @param private struct cam_data * mxc capture instance
  71662. + *
  71663. + * @return status
  71664. + */
  71665. +static int prp_vf_enable_csi(void *private)
  71666. +{
  71667. + cam_data *cam = (cam_data *) private;
  71668. +
  71669. + return ipu_enable_csi(cam->ipu, cam->csi);
  71670. +}
  71671. +
  71672. +/*!
  71673. + * Disable csi
  71674. + * @param private struct cam_data * mxc capture instance
  71675. + *
  71676. + * @return status
  71677. + */
  71678. +static int prp_vf_disable_csi(void *private)
  71679. +{
  71680. + cam_data *cam = (cam_data *) private;
  71681. +
  71682. + /* free csi eof irq firstly.
  71683. + * when disable csi, wait for idmac eof.
  71684. + * it requests eof irq again */
  71685. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, cam);
  71686. +
  71687. + return ipu_disable_csi(cam->ipu, cam->csi);
  71688. +}
  71689. +
  71690. +/*!
  71691. + * function to select PRP-VF as the working path
  71692. + *
  71693. + * @param private cam_data * mxc v4l2 main structure
  71694. + *
  71695. + * @return status
  71696. + */
  71697. +int prp_vf_sdc_select_bg(void *private)
  71698. +{
  71699. + cam_data *cam = (cam_data *) private;
  71700. +
  71701. + if (cam) {
  71702. + cam->vf_start_sdc = prpvf_start;
  71703. + cam->vf_stop_sdc = prpvf_stop;
  71704. + cam->vf_enable_csi = prp_vf_enable_csi;
  71705. + cam->vf_disable_csi = prp_vf_disable_csi;
  71706. + cam->overlay_active = false;
  71707. + }
  71708. +
  71709. + return 0;
  71710. +}
  71711. +EXPORT_SYMBOL(prp_vf_sdc_select_bg);
  71712. +
  71713. +/*!
  71714. + * function to de-select PRP-VF as the working path
  71715. + *
  71716. + * @param private cam_data * mxc v4l2 main structure
  71717. + *
  71718. + * @return status
  71719. + */
  71720. +int prp_vf_sdc_deselect_bg(void *private)
  71721. +{
  71722. + cam_data *cam = (cam_data *) private;
  71723. +
  71724. + if (cam) {
  71725. + cam->vf_start_sdc = NULL;
  71726. + cam->vf_stop_sdc = NULL;
  71727. + cam->vf_enable_csi = NULL;
  71728. + cam->vf_disable_csi = NULL;
  71729. + }
  71730. + return 0;
  71731. +}
  71732. +EXPORT_SYMBOL(prp_vf_sdc_deselect_bg);
  71733. +
  71734. +/*!
  71735. + * Init viewfinder task.
  71736. + *
  71737. + * @return Error code indicating success or failure
  71738. + */
  71739. +__init int prp_vf_sdc_init_bg(void)
  71740. +{
  71741. + return 0;
  71742. +}
  71743. +
  71744. +/*!
  71745. + * Deinit viewfinder task.
  71746. + *
  71747. + * @return Error code indicating success or failure
  71748. + */
  71749. +void __exit prp_vf_sdc_exit_bg(void)
  71750. +{
  71751. +}
  71752. +
  71753. +module_init(prp_vf_sdc_init_bg);
  71754. +module_exit(prp_vf_sdc_exit_bg);
  71755. +
  71756. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  71757. +MODULE_DESCRIPTION("IPU PRP VF SDC Backgroud Driver");
  71758. +MODULE_LICENSE("GPL");
  71759. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c
  71760. --- linux-3.14.15/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c 1970-01-01 01:00:00.000000000 +0100
  71761. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c 2014-08-20 19:31:45.440866052 +0200
  71762. @@ -0,0 +1,582 @@
  71763. +/*
  71764. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  71765. + */
  71766. +/* * The code contained herein is licensed under the GNU General Public
  71767. + * License. You may obtain a copy of the GNU General Public License
  71768. + * Version 2 or later at the following locations:
  71769. + *
  71770. + * http://www.opensource.org/licenses/gpl-license.html
  71771. + * http://www.gnu.org/copyleft/gpl.html
  71772. + */
  71773. +
  71774. +/*!
  71775. + * @file ipu_prp_vf_sdc.c
  71776. + *
  71777. + * @brief IPU Use case for PRP-VF
  71778. + *
  71779. + * @ingroup IPU
  71780. + */
  71781. +
  71782. +#include <linux/dma-mapping.h>
  71783. +#include <linux/console.h>
  71784. +#include <linux/ipu.h>
  71785. +#include <linux/module.h>
  71786. +#include <linux/mxcfb.h>
  71787. +#include <mach/hardware.h>
  71788. +#include <mach/mipi_csi2.h>
  71789. +#include "mxc_v4l2_capture.h"
  71790. +#include "ipu_prp_sw.h"
  71791. +
  71792. +static int buffer_num;
  71793. +static struct ipu_soc *disp_ipu;
  71794. +
  71795. +static void get_disp_ipu(cam_data *cam)
  71796. +{
  71797. + if (cam->output > 2)
  71798. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  71799. + else
  71800. + disp_ipu = ipu_get_soc(0);
  71801. +}
  71802. +
  71803. +static irqreturn_t prpvf_rot_eof_callback(int irq, void *dev_id)
  71804. +{
  71805. + cam_data *cam = dev_id;
  71806. + pr_debug("buffer_num %d\n", buffer_num);
  71807. +
  71808. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  71809. + ipu_select_buffer(disp_ipu, MEM_FG_SYNC,
  71810. + IPU_INPUT_BUFFER, buffer_num);
  71811. + buffer_num = (buffer_num == 0) ? 1 : 0;
  71812. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71813. + IPU_OUTPUT_BUFFER, buffer_num);
  71814. + } else {
  71815. + ipu_select_buffer(disp_ipu, MEM_FG_SYNC,
  71816. + IPU_INPUT_BUFFER, buffer_num);
  71817. + buffer_num = (buffer_num == 0) ? 1 : 0;
  71818. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  71819. + IPU_OUTPUT_BUFFER, buffer_num);
  71820. + }
  71821. + return IRQ_HANDLED;
  71822. +}
  71823. +/*
  71824. + * Function definitions
  71825. + */
  71826. +
  71827. +/*!
  71828. + * prpvf_start - start the vf task
  71829. + *
  71830. + * @param private cam_data * mxc v4l2 main structure
  71831. + *
  71832. + */
  71833. +static int prpvf_start(void *private)
  71834. +{
  71835. + struct fb_var_screeninfo fbvar;
  71836. + struct fb_info *fbi = NULL;
  71837. + cam_data *cam = (cam_data *) private;
  71838. + ipu_channel_params_t vf;
  71839. + u32 vf_out_format = 0;
  71840. + u32 size = 2, temp = 0;
  71841. + int err = 0, i = 0;
  71842. + short *tmp, color;
  71843. +#ifdef CONFIG_MXC_MIPI_CSI2
  71844. + void *mipi_csi2_info;
  71845. + int ipu_id;
  71846. + int csi_id;
  71847. +#endif
  71848. +
  71849. + if (!cam) {
  71850. + printk(KERN_ERR "private is NULL\n");
  71851. + return -EIO;
  71852. + }
  71853. +
  71854. + if (cam->overlay_active == true) {
  71855. + pr_debug("already started.\n");
  71856. + return 0;
  71857. + }
  71858. +
  71859. + get_disp_ipu(cam);
  71860. +
  71861. + for (i = 0; i < num_registered_fb; i++) {
  71862. + char *idstr = registered_fb[i]->fix.id;
  71863. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  71864. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  71865. + fbi = registered_fb[i];
  71866. + break;
  71867. + }
  71868. + }
  71869. +
  71870. + if (fbi == NULL) {
  71871. + printk(KERN_ERR "DISP FG fb not found\n");
  71872. + return -EPERM;
  71873. + }
  71874. +
  71875. + fbvar = fbi->var;
  71876. +
  71877. + /* Store the overlay frame buffer's original std */
  71878. + cam->fb_origin_std = fbvar.nonstd;
  71879. +
  71880. + if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
  71881. + /* Use DP to do CSC so that we can get better performance */
  71882. + vf_out_format = IPU_PIX_FMT_UYVY;
  71883. + fbvar.nonstd = vf_out_format;
  71884. + color = 0x80;
  71885. + } else {
  71886. + vf_out_format = IPU_PIX_FMT_RGB565;
  71887. + fbvar.nonstd = 0;
  71888. + color = 0x0;
  71889. + }
  71890. +
  71891. + fbvar.bits_per_pixel = 16;
  71892. + fbvar.xres = fbvar.xres_virtual = cam->win.w.width;
  71893. + fbvar.yres = cam->win.w.height;
  71894. + fbvar.yres_virtual = cam->win.w.height * 2;
  71895. + fbvar.yoffset = 0;
  71896. + fbvar.accel_flags = FB_ACCEL_DOUBLE_FLAG;
  71897. + fbvar.activate |= FB_ACTIVATE_FORCE;
  71898. + fb_set_var(fbi, &fbvar);
  71899. +
  71900. + ipu_disp_set_window_pos(disp_ipu, MEM_FG_SYNC, cam->win.w.left,
  71901. + cam->win.w.top);
  71902. +
  71903. + /* Fill black color for framebuffer */
  71904. + tmp = (short *) fbi->screen_base;
  71905. + for (i = 0; i < (fbi->fix.line_length * fbi->var.yres)/2;
  71906. + i++, tmp++)
  71907. + *tmp = color;
  71908. +
  71909. + console_lock();
  71910. + fb_blank(fbi, FB_BLANK_UNBLANK);
  71911. + console_unlock();
  71912. +
  71913. + /* correct display ch buffer address */
  71914. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  71915. + 0, fbi->fix.smem_start +
  71916. + (fbi->fix.line_length * fbvar.yres));
  71917. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  71918. + 1, fbi->fix.smem_start);
  71919. +
  71920. + memset(&vf, 0, sizeof(ipu_channel_params_t));
  71921. + ipu_csi_get_window_size(cam->ipu, &vf.csi_prp_vf_mem.in_width,
  71922. + &vf.csi_prp_vf_mem.in_height, cam->csi);
  71923. + vf.csi_prp_vf_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
  71924. + vf.csi_prp_vf_mem.out_width = cam->win.w.width;
  71925. + vf.csi_prp_vf_mem.out_height = cam->win.w.height;
  71926. + vf.csi_prp_vf_mem.csi = cam->csi;
  71927. + if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
  71928. + vf.csi_prp_vf_mem.out_width = cam->win.w.height;
  71929. + vf.csi_prp_vf_mem.out_height = cam->win.w.width;
  71930. + }
  71931. + vf.csi_prp_vf_mem.out_pixel_fmt = vf_out_format;
  71932. + size = cam->win.w.width * cam->win.w.height * size;
  71933. +
  71934. +#ifdef CONFIG_MXC_MIPI_CSI2
  71935. + mipi_csi2_info = mipi_csi2_get_info();
  71936. +
  71937. + if (mipi_csi2_info) {
  71938. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  71939. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  71940. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  71941. +
  71942. + if (cam->ipu == ipu_get_soc(ipu_id)
  71943. + && cam->csi == csi_id) {
  71944. + vf.csi_prp_vf_mem.mipi_en = true;
  71945. + vf.csi_prp_vf_mem.mipi_vc =
  71946. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  71947. + vf.csi_prp_vf_mem.mipi_id =
  71948. + mipi_csi2_get_datatype(mipi_csi2_info);
  71949. +
  71950. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  71951. + } else {
  71952. + vf.csi_prp_vf_mem.mipi_en = false;
  71953. + vf.csi_prp_vf_mem.mipi_vc = 0;
  71954. + vf.csi_prp_vf_mem.mipi_id = 0;
  71955. + }
  71956. + } else {
  71957. + vf.csi_prp_vf_mem.mipi_en = false;
  71958. + vf.csi_prp_vf_mem.mipi_vc = 0;
  71959. + vf.csi_prp_vf_mem.mipi_id = 0;
  71960. + }
  71961. + }
  71962. +#endif
  71963. +
  71964. + err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
  71965. + if (err != 0)
  71966. + goto out_5;
  71967. +
  71968. + if (cam->vf_bufs_vaddr[0]) {
  71969. + dma_free_coherent(0, cam->vf_bufs_size[0],
  71970. + cam->vf_bufs_vaddr[0],
  71971. + (dma_addr_t) cam->vf_bufs[0]);
  71972. + }
  71973. + if (cam->vf_bufs_vaddr[1]) {
  71974. + dma_free_coherent(0, cam->vf_bufs_size[1],
  71975. + cam->vf_bufs_vaddr[1],
  71976. + (dma_addr_t) cam->vf_bufs[1]);
  71977. + }
  71978. + cam->vf_bufs_size[0] = PAGE_ALIGN(size);
  71979. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  71980. + cam->vf_bufs_size[0],
  71981. + (dma_addr_t *) &
  71982. + cam->vf_bufs[0],
  71983. + GFP_DMA |
  71984. + GFP_KERNEL);
  71985. + if (cam->vf_bufs_vaddr[0] == NULL) {
  71986. + printk(KERN_ERR "Error to allocate vf buffer\n");
  71987. + err = -ENOMEM;
  71988. + goto out_4;
  71989. + }
  71990. + cam->vf_bufs_size[1] = PAGE_ALIGN(size);
  71991. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  71992. + cam->vf_bufs_size[1],
  71993. + (dma_addr_t *) &
  71994. + cam->vf_bufs[1],
  71995. + GFP_DMA |
  71996. + GFP_KERNEL);
  71997. + if (cam->vf_bufs_vaddr[1] == NULL) {
  71998. + printk(KERN_ERR "Error to allocate vf buffer\n");
  71999. + err = -ENOMEM;
  72000. + goto out_3;
  72001. + }
  72002. + pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
  72003. +
  72004. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  72005. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
  72006. + IPU_OUTPUT_BUFFER,
  72007. + vf_out_format,
  72008. + vf.csi_prp_vf_mem.out_width,
  72009. + vf.csi_prp_vf_mem.out_height,
  72010. + vf.csi_prp_vf_mem.out_width,
  72011. + IPU_ROTATE_NONE,
  72012. + cam->vf_bufs[0], cam->vf_bufs[1],
  72013. + 0, 0, 0);
  72014. + if (err != 0)
  72015. + goto out_3;
  72016. +
  72017. + err = ipu_init_channel(cam->ipu, MEM_ROT_VF_MEM, NULL);
  72018. + if (err != 0) {
  72019. + printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n");
  72020. + goto out_3;
  72021. + }
  72022. +
  72023. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  72024. + IPU_INPUT_BUFFER,
  72025. + vf_out_format,
  72026. + vf.csi_prp_vf_mem.out_width,
  72027. + vf.csi_prp_vf_mem.out_height,
  72028. + vf.csi_prp_vf_mem.out_width,
  72029. + cam->vf_rotation,
  72030. + cam->vf_bufs[0],
  72031. + cam->vf_bufs[1],
  72032. + 0, 0, 0);
  72033. + if (err != 0) {
  72034. + printk(KERN_ERR "Error MEM_ROT_VF_MEM input buffer\n");
  72035. + goto out_2;
  72036. + }
  72037. +
  72038. + if (cam->vf_rotation < IPU_ROTATE_90_RIGHT) {
  72039. + temp = vf.csi_prp_vf_mem.out_width;
  72040. + vf.csi_prp_vf_mem.out_width =
  72041. + vf.csi_prp_vf_mem.out_height;
  72042. + vf.csi_prp_vf_mem.out_height = temp;
  72043. + }
  72044. +
  72045. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  72046. + IPU_OUTPUT_BUFFER,
  72047. + vf_out_format,
  72048. + vf.csi_prp_vf_mem.out_height,
  72049. + vf.csi_prp_vf_mem.out_width,
  72050. + vf.csi_prp_vf_mem.out_height,
  72051. + IPU_ROTATE_NONE,
  72052. + fbi->fix.smem_start +
  72053. + (fbi->fix.line_length *
  72054. + fbi->var.yres),
  72055. + fbi->fix.smem_start, 0, 0, 0);
  72056. +
  72057. + if (err != 0) {
  72058. + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
  72059. + goto out_2;
  72060. + }
  72061. +
  72062. + ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF);
  72063. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF,
  72064. + prpvf_rot_eof_callback,
  72065. + 0, "Mxc Camera", cam);
  72066. + if (err < 0) {
  72067. + printk(KERN_ERR "Error request irq:IPU_IRQ_PRP_VF_ROT_OUT_EOF\n");
  72068. + goto out_2;
  72069. + }
  72070. +
  72071. + err = ipu_link_channels(cam->ipu,
  72072. + CSI_PRP_VF_MEM, MEM_ROT_VF_MEM);
  72073. + if (err < 0) {
  72074. + printk(KERN_ERR
  72075. + "Error link CSI_PRP_VF_MEM-MEM_ROT_VF_MEM\n");
  72076. + goto out_1;
  72077. + }
  72078. +
  72079. + ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
  72080. + ipu_enable_channel(cam->ipu, MEM_ROT_VF_MEM);
  72081. +
  72082. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  72083. + IPU_OUTPUT_BUFFER, 0);
  72084. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  72085. + IPU_OUTPUT_BUFFER, 1);
  72086. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  72087. + IPU_OUTPUT_BUFFER, 0);
  72088. + } else {
  72089. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
  72090. + IPU_OUTPUT_BUFFER,
  72091. + vf_out_format, cam->win.w.width,
  72092. + cam->win.w.height,
  72093. + cam->win.w.width,
  72094. + cam->vf_rotation,
  72095. + fbi->fix.smem_start +
  72096. + (fbi->fix.line_length *
  72097. + fbi->var.yres),
  72098. + fbi->fix.smem_start, 0, 0, 0);
  72099. + if (err != 0) {
  72100. + printk(KERN_ERR "Error initializing CSI_PRP_VF_MEM\n");
  72101. + goto out_4;
  72102. + }
  72103. + ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF);
  72104. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF,
  72105. + prpvf_rot_eof_callback,
  72106. + 0, "Mxc Camera", cam);
  72107. + if (err < 0) {
  72108. + printk(KERN_ERR "Error request irq:IPU_IRQ_PRP_VF_OUT_EOF\n");
  72109. + goto out_4;
  72110. + }
  72111. +
  72112. + ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
  72113. +
  72114. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  72115. + IPU_OUTPUT_BUFFER, 0);
  72116. + }
  72117. +
  72118. + cam->overlay_active = true;
  72119. + return err;
  72120. +
  72121. +out_1:
  72122. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, NULL);
  72123. +out_2:
  72124. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP)
  72125. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  72126. +out_3:
  72127. + if (cam->vf_bufs_vaddr[0]) {
  72128. + dma_free_coherent(0, cam->vf_bufs_size[0],
  72129. + cam->vf_bufs_vaddr[0],
  72130. + (dma_addr_t) cam->vf_bufs[0]);
  72131. + cam->vf_bufs_vaddr[0] = NULL;
  72132. + cam->vf_bufs[0] = 0;
  72133. + }
  72134. + if (cam->vf_bufs_vaddr[1]) {
  72135. + dma_free_coherent(0, cam->vf_bufs_size[1],
  72136. + cam->vf_bufs_vaddr[1],
  72137. + (dma_addr_t) cam->vf_bufs[1]);
  72138. + cam->vf_bufs_vaddr[1] = NULL;
  72139. + cam->vf_bufs[1] = 0;
  72140. + }
  72141. +out_4:
  72142. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  72143. +out_5:
  72144. + return err;
  72145. +}
  72146. +
  72147. +/*!
  72148. + * prpvf_stop - stop the vf task
  72149. + *
  72150. + * @param private cam_data * mxc v4l2 main structure
  72151. + *
  72152. + */
  72153. +static int prpvf_stop(void *private)
  72154. +{
  72155. + cam_data *cam = (cam_data *) private;
  72156. + int err = 0, i = 0;
  72157. + struct fb_info *fbi = NULL;
  72158. + struct fb_var_screeninfo fbvar;
  72159. +#ifdef CONFIG_MXC_MIPI_CSI2
  72160. + void *mipi_csi2_info;
  72161. + int ipu_id;
  72162. + int csi_id;
  72163. +#endif
  72164. +
  72165. + if (cam->overlay_active == false)
  72166. + return 0;
  72167. +
  72168. + for (i = 0; i < num_registered_fb; i++) {
  72169. + char *idstr = registered_fb[i]->fix.id;
  72170. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  72171. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  72172. + fbi = registered_fb[i];
  72173. + break;
  72174. + }
  72175. + }
  72176. +
  72177. + if (fbi == NULL) {
  72178. + printk(KERN_ERR "DISP FG fb not found\n");
  72179. + return -EPERM;
  72180. + }
  72181. +
  72182. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  72183. + ipu_unlink_channels(cam->ipu, CSI_PRP_VF_MEM, MEM_ROT_VF_MEM);
  72184. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF, cam);
  72185. + }
  72186. + buffer_num = 0;
  72187. +
  72188. + ipu_disable_channel(cam->ipu, CSI_PRP_VF_MEM, true);
  72189. +
  72190. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  72191. + ipu_disable_channel(cam->ipu, MEM_ROT_VF_MEM, true);
  72192. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  72193. + }
  72194. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  72195. +
  72196. + console_lock();
  72197. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  72198. + console_unlock();
  72199. +
  72200. + /* Set the overlay frame buffer std to what it is used to be */
  72201. + fbvar = fbi->var;
  72202. + fbvar.accel_flags = FB_ACCEL_TRIPLE_FLAG;
  72203. + fbvar.nonstd = cam->fb_origin_std;
  72204. + fbvar.activate |= FB_ACTIVATE_FORCE;
  72205. + fb_set_var(fbi, &fbvar);
  72206. +
  72207. +#ifdef CONFIG_MXC_MIPI_CSI2
  72208. + mipi_csi2_info = mipi_csi2_get_info();
  72209. +
  72210. + if (mipi_csi2_info) {
  72211. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  72212. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  72213. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  72214. +
  72215. + if (cam->ipu == ipu_get_soc(ipu_id)
  72216. + && cam->csi == csi_id)
  72217. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  72218. + }
  72219. + }
  72220. +#endif
  72221. +
  72222. + if (cam->vf_bufs_vaddr[0]) {
  72223. + dma_free_coherent(0, cam->vf_bufs_size[0],
  72224. + cam->vf_bufs_vaddr[0],
  72225. + (dma_addr_t) cam->vf_bufs[0]);
  72226. + cam->vf_bufs_vaddr[0] = NULL;
  72227. + cam->vf_bufs[0] = 0;
  72228. + }
  72229. + if (cam->vf_bufs_vaddr[1]) {
  72230. + dma_free_coherent(0, cam->vf_bufs_size[1],
  72231. + cam->vf_bufs_vaddr[1],
  72232. + (dma_addr_t) cam->vf_bufs[1]);
  72233. + cam->vf_bufs_vaddr[1] = NULL;
  72234. + cam->vf_bufs[1] = 0;
  72235. + }
  72236. +
  72237. + cam->overlay_active = false;
  72238. + return err;
  72239. +}
  72240. +
  72241. +/*!
  72242. + * Enable csi
  72243. + * @param private struct cam_data * mxc capture instance
  72244. + *
  72245. + * @return status
  72246. + */
  72247. +static int prp_vf_enable_csi(void *private)
  72248. +{
  72249. + cam_data *cam = (cam_data *) private;
  72250. +
  72251. + return ipu_enable_csi(cam->ipu, cam->csi);
  72252. +}
  72253. +
  72254. +/*!
  72255. + * Disable csi
  72256. + * @param private struct cam_data * mxc capture instance
  72257. + *
  72258. + * @return status
  72259. + */
  72260. +static int prp_vf_disable_csi(void *private)
  72261. +{
  72262. + cam_data *cam = (cam_data *) private;
  72263. +
  72264. + /* free csi eof irq firstly.
  72265. + * when disable csi, wait for idmac eof.
  72266. + * it requests eof irq again */
  72267. + if (cam->vf_rotation < IPU_ROTATE_VERT_FLIP)
  72268. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, cam);
  72269. +
  72270. + return ipu_disable_csi(cam->ipu, cam->csi);
  72271. +}
  72272. +
  72273. +/*!
  72274. + * function to select PRP-VF as the working path
  72275. + *
  72276. + * @param private cam_data * mxc v4l2 main structure
  72277. + *
  72278. + * @return status
  72279. + */
  72280. +int prp_vf_sdc_select(void *private)
  72281. +{
  72282. + cam_data *cam;
  72283. + int err = 0;
  72284. + if (private) {
  72285. + cam = (cam_data *) private;
  72286. + cam->vf_start_sdc = prpvf_start;
  72287. + cam->vf_stop_sdc = prpvf_stop;
  72288. + cam->vf_enable_csi = prp_vf_enable_csi;
  72289. + cam->vf_disable_csi = prp_vf_disable_csi;
  72290. + cam->overlay_active = false;
  72291. + } else
  72292. + err = -EIO;
  72293. +
  72294. + return err;
  72295. +}
  72296. +EXPORT_SYMBOL(prp_vf_sdc_select);
  72297. +
  72298. +/*!
  72299. + * function to de-select PRP-VF as the working path
  72300. + *
  72301. + * @param private cam_data * mxc v4l2 main structure
  72302. + *
  72303. + * @return int
  72304. + */
  72305. +int prp_vf_sdc_deselect(void *private)
  72306. +{
  72307. + cam_data *cam;
  72308. +
  72309. + if (private) {
  72310. + cam = (cam_data *) private;
  72311. + cam->vf_start_sdc = NULL;
  72312. + cam->vf_stop_sdc = NULL;
  72313. + cam->vf_enable_csi = NULL;
  72314. + cam->vf_disable_csi = NULL;
  72315. + }
  72316. + return 0;
  72317. +}
  72318. +EXPORT_SYMBOL(prp_vf_sdc_deselect);
  72319. +
  72320. +/*!
  72321. + * Init viewfinder task.
  72322. + *
  72323. + * @return Error code indicating success or failure
  72324. + */
  72325. +__init int prp_vf_sdc_init(void)
  72326. +{
  72327. + return 0;
  72328. +}
  72329. +
  72330. +/*!
  72331. + * Deinit viewfinder task.
  72332. + *
  72333. + * @return Error code indicating success or failure
  72334. + */
  72335. +void __exit prp_vf_sdc_exit(void)
  72336. +{
  72337. +}
  72338. +
  72339. +module_init(prp_vf_sdc_init);
  72340. +module_exit(prp_vf_sdc_exit);
  72341. +
  72342. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  72343. +MODULE_DESCRIPTION("IPU PRP VF SDC Driver");
  72344. +MODULE_LICENSE("GPL");
  72345. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/ipu_still.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_still.c
  72346. --- linux-3.14.15/drivers/media/platform/mxc/capture/ipu_still.c 1970-01-01 01:00:00.000000000 +0100
  72347. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ipu_still.c 2014-08-20 19:23:52.818842679 +0200
  72348. @@ -0,0 +1,268 @@
  72349. +/*
  72350. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  72351. + */
  72352. +
  72353. +/*
  72354. + * The code contained herein is licensed under the GNU General Public
  72355. + * License. You may obtain a copy of the GNU General Public License
  72356. + * Version 2 or later at the following locations:
  72357. + *
  72358. + * http://www.opensource.org/licenses/gpl-license.html
  72359. + * http://www.gnu.org/copyleft/gpl.html
  72360. + */
  72361. +
  72362. +/*!
  72363. + * @file ipu_still.c
  72364. + *
  72365. + * @brief IPU Use case for still image capture
  72366. + *
  72367. + * @ingroup IPU
  72368. + */
  72369. +
  72370. +#include <linux/module.h>
  72371. +#include <linux/semaphore.h>
  72372. +#include <linux/sched.h>
  72373. +#include <linux/ipu.h>
  72374. +#include "mxc_v4l2_capture.h"
  72375. +#include "ipu_prp_sw.h"
  72376. +
  72377. +static int callback_eof_flag;
  72378. +#ifndef CONFIG_MXC_IPU_V1
  72379. +static int buffer_num;
  72380. +#endif
  72381. +
  72382. +#ifdef CONFIG_MXC_IPU_V1
  72383. +static int callback_flag;
  72384. +/*
  72385. + * Function definitions
  72386. + */
  72387. +/*!
  72388. + * CSI EOF callback function.
  72389. + *
  72390. + * @param irq int irq line
  72391. + * @param dev_id void * device id
  72392. + *
  72393. + * @return status IRQ_HANDLED for handled
  72394. + */
  72395. +static irqreturn_t prp_csi_eof_callback(int irq, void *dev_id)
  72396. +{
  72397. + cam_data *cam = devid;
  72398. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  72399. + callback_flag%2 ? 1 : 0);
  72400. + if (callback_flag == 0)
  72401. + ipu_enable_channel(cam->ipu, CSI_MEM);
  72402. +
  72403. + callback_flag++;
  72404. + return IRQ_HANDLED;
  72405. +}
  72406. +#endif
  72407. +
  72408. +/*!
  72409. + * CSI callback function.
  72410. + *
  72411. + * @param irq int irq line
  72412. + * @param dev_id void * device id
  72413. + *
  72414. + * @return status IRQ_HANDLED for handled
  72415. + */
  72416. +static irqreturn_t prp_still_callback(int irq, void *dev_id)
  72417. +{
  72418. + cam_data *cam = (cam_data *) dev_id;
  72419. +
  72420. + callback_eof_flag++;
  72421. + if (callback_eof_flag < 5) {
  72422. +#ifndef CONFIG_MXC_IPU_V1
  72423. + buffer_num = (buffer_num == 0) ? 1 : 0;
  72424. + ipu_select_buffer(cam->ipu, CSI_MEM,
  72425. + IPU_OUTPUT_BUFFER, buffer_num);
  72426. +#endif
  72427. + } else {
  72428. + cam->still_counter++;
  72429. + wake_up_interruptible(&cam->still_queue);
  72430. + }
  72431. +
  72432. + return IRQ_HANDLED;
  72433. +}
  72434. +
  72435. +/*!
  72436. + * start csi->mem task
  72437. + * @param private struct cam_data * mxc capture instance
  72438. + *
  72439. + * @return status
  72440. + */
  72441. +static int prp_still_start(void *private)
  72442. +{
  72443. + cam_data *cam = (cam_data *) private;
  72444. + u32 pixel_fmt;
  72445. + int err;
  72446. + ipu_channel_params_t params;
  72447. +
  72448. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
  72449. + pixel_fmt = IPU_PIX_FMT_YUV420P;
  72450. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)
  72451. + pixel_fmt = IPU_PIX_FMT_NV12;
  72452. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P)
  72453. + pixel_fmt = IPU_PIX_FMT_YUV422P;
  72454. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
  72455. + pixel_fmt = IPU_PIX_FMT_UYVY;
  72456. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
  72457. + pixel_fmt = IPU_PIX_FMT_YUYV;
  72458. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
  72459. + pixel_fmt = IPU_PIX_FMT_BGR24;
  72460. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
  72461. + pixel_fmt = IPU_PIX_FMT_RGB24;
  72462. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565)
  72463. + pixel_fmt = IPU_PIX_FMT_RGB565;
  72464. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32)
  72465. + pixel_fmt = IPU_PIX_FMT_BGR32;
  72466. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32)
  72467. + pixel_fmt = IPU_PIX_FMT_RGB32;
  72468. + else {
  72469. + printk(KERN_ERR "format not supported\n");
  72470. + return -EINVAL;
  72471. + }
  72472. +
  72473. + memset(&params, 0, sizeof(params));
  72474. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  72475. + if (err != 0)
  72476. + return err;
  72477. +
  72478. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  72479. + pixel_fmt, cam->v2f.fmt.pix.width,
  72480. + cam->v2f.fmt.pix.height,
  72481. + cam->v2f.fmt.pix.width, IPU_ROTATE_NONE,
  72482. + cam->still_buf[0], cam->still_buf[1], 0,
  72483. + 0, 0);
  72484. + if (err != 0)
  72485. + return err;
  72486. +
  72487. +#ifdef CONFIG_MXC_IPU_V1
  72488. + ipu_clear_irq(IPU_IRQ_SENSOR_OUT_EOF);
  72489. + err = ipu_request_irq(IPU_IRQ_SENSOR_OUT_EOF, prp_still_callback,
  72490. + 0, "Mxc Camera", cam);
  72491. + if (err != 0) {
  72492. + printk(KERN_ERR "Error registering irq.\n");
  72493. + return err;
  72494. + }
  72495. + callback_flag = 0;
  72496. + callback_eof_flag = 0;
  72497. + ipu_clear_irq(IPU_IRQ_SENSOR_EOF);
  72498. + err = ipu_request_irq(IPU_IRQ_SENSOR_EOF, prp_csi_eof_callback,
  72499. + 0, "Mxc Camera", cam);
  72500. + if (err != 0) {
  72501. + printk(KERN_ERR "Error IPU_IRQ_SENSOR_EOF\n");
  72502. + return err;
  72503. + }
  72504. +#else
  72505. + callback_eof_flag = 0;
  72506. + buffer_num = 0;
  72507. +
  72508. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  72509. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  72510. + prp_still_callback,
  72511. + 0, "Mxc Camera", cam);
  72512. + if (err != 0) {
  72513. + printk(KERN_ERR "Error registering irq.\n");
  72514. + return err;
  72515. + }
  72516. +
  72517. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 0);
  72518. + ipu_enable_channel(cam->ipu, CSI_MEM);
  72519. + ipu_enable_csi(cam->ipu, cam->csi);
  72520. +#endif
  72521. +
  72522. + return err;
  72523. +}
  72524. +
  72525. +/*!
  72526. + * stop csi->mem encoder task
  72527. + * @param private struct cam_data * mxc capture instance
  72528. + *
  72529. + * @return status
  72530. + */
  72531. +static int prp_still_stop(void *private)
  72532. +{
  72533. + cam_data *cam = (cam_data *) private;
  72534. + int err = 0;
  72535. +
  72536. +#ifdef CONFIG_MXC_IPU_V1
  72537. + ipu_free_irq(IPU_IRQ_SENSOR_EOF, NULL);
  72538. + ipu_free_irq(IPU_IRQ_SENSOR_OUT_EOF, cam);
  72539. +#else
  72540. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  72541. +#endif
  72542. +
  72543. + ipu_disable_csi(cam->ipu, cam->csi);
  72544. + ipu_disable_channel(cam->ipu, CSI_MEM, true);
  72545. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  72546. +
  72547. + return err;
  72548. +}
  72549. +
  72550. +/*!
  72551. + * function to select CSI_MEM as the working path
  72552. + *
  72553. + * @param private struct cam_data * mxc capture instance
  72554. + *
  72555. + * @return status
  72556. + */
  72557. +int prp_still_select(void *private)
  72558. +{
  72559. + cam_data *cam = (cam_data *) private;
  72560. +
  72561. + if (cam) {
  72562. + cam->csi_start = prp_still_start;
  72563. + cam->csi_stop = prp_still_stop;
  72564. + }
  72565. +
  72566. + return 0;
  72567. +}
  72568. +EXPORT_SYMBOL(prp_still_select);
  72569. +
  72570. +/*!
  72571. + * function to de-select CSI_MEM as the working path
  72572. + *
  72573. + * @param private struct cam_data * mxc capture instance
  72574. + *
  72575. + * @return status
  72576. + */
  72577. +int prp_still_deselect(void *private)
  72578. +{
  72579. + cam_data *cam = (cam_data *) private;
  72580. + int err = 0;
  72581. +
  72582. + err = prp_still_stop(cam);
  72583. +
  72584. + if (cam) {
  72585. + cam->csi_start = NULL;
  72586. + cam->csi_stop = NULL;
  72587. + }
  72588. +
  72589. + return err;
  72590. +}
  72591. +EXPORT_SYMBOL(prp_still_deselect);
  72592. +
  72593. +/*!
  72594. + * Init the Encorder channels
  72595. + *
  72596. + * @return Error code indicating success or failure
  72597. + */
  72598. +__init int prp_still_init(void)
  72599. +{
  72600. + return 0;
  72601. +}
  72602. +
  72603. +/*!
  72604. + * Deinit the Encorder channels
  72605. + *
  72606. + */
  72607. +void __exit prp_still_exit(void)
  72608. +{
  72609. +}
  72610. +
  72611. +module_init(prp_still_init);
  72612. +module_exit(prp_still_exit);
  72613. +
  72614. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  72615. +MODULE_DESCRIPTION("IPU PRP STILL IMAGE Driver");
  72616. +MODULE_LICENSE("GPL");
  72617. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/Kconfig linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/Kconfig
  72618. --- linux-3.14.15/drivers/media/platform/mxc/capture/Kconfig 1970-01-01 01:00:00.000000000 +0100
  72619. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/Kconfig 2014-08-20 19:23:52.798842594 +0200
  72620. @@ -0,0 +1,86 @@
  72621. +if VIDEO_MXC_CAPTURE
  72622. +
  72623. +menu "MXC Camera/V4L2 PRP Features support"
  72624. +config VIDEO_MXC_IPU_CAMERA
  72625. + bool
  72626. + depends on VIDEO_MXC_CAPTURE && MXC_IPU
  72627. + default y
  72628. +
  72629. +config VIDEO_MXC_CSI_CAMERA
  72630. + tristate "CSI camera support"
  72631. + depends on VIDEO_MXC_CAPTURE && VIDEO_V4L2
  72632. + ---help---
  72633. + This is the video4linux2 capture driver based on CSI module.
  72634. +
  72635. +config MXC_CAMERA_OV5640
  72636. + tristate "OmniVision ov5640 camera support"
  72637. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  72638. + ---help---
  72639. + If you plan to use the ov5640 Camera with your MXC system, say Y here.
  72640. +
  72641. +config MXC_CAMERA_OV5642
  72642. + tristate "OmniVision ov5642 camera support"
  72643. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  72644. + ---help---
  72645. + If you plan to use the ov5642 Camera with your MXC system, say Y here.
  72646. +
  72647. +config MXC_CAMERA_OV5640_MIPI
  72648. + tristate "OmniVision ov5640 camera support using mipi"
  72649. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  72650. + ---help---
  72651. + If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here.
  72652. +
  72653. +config MXC_TVIN_ADV7180
  72654. + tristate "Analog Device adv7180 TV Decoder Input support"
  72655. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  72656. + ---help---
  72657. + If you plan to use the adv7180 video decoder with your MXC system, say Y here.
  72658. +
  72659. +choice
  72660. + prompt "Select Overlay Rounting"
  72661. + default MXC_IPU_DEVICE_QUEUE_SDC
  72662. + depends on VIDEO_MXC_IPU_CAMERA && FB_MXC_SYNC_PANEL
  72663. +
  72664. +config MXC_IPU_DEVICE_QUEUE_SDC
  72665. + tristate "Queue ipu device for overlay library"
  72666. + depends on VIDEO_MXC_IPU_CAMERA
  72667. + ---help---
  72668. + Use case CSI->MEM->IPU DEVICE->SDC:
  72669. + Images from sensor will be frist recieved in memory,then
  72670. + queue to ipu device for processing if needed, and displaying
  72671. + it on synchronous display with SDC use case.
  72672. +
  72673. +config MXC_IPU_PRP_VF_SDC
  72674. + bool "Pre-Processor VF SDC library"
  72675. + depends on VIDEO_MXC_IPU_CAMERA
  72676. + ---help---
  72677. + Use case PRP_VF_SDC:
  72678. + Preprocessing image from smart sensor for viewfinder and
  72679. + displaying it on synchronous display with SDC use case.
  72680. + If SDC BG is selected, Rotation will not be supported.
  72681. + CSI -> IC (PRP VF) -> MEM
  72682. + MEM -> IC (ROT) -> MEM
  72683. + MEM -> SDC (FG/BG)
  72684. +
  72685. +endchoice
  72686. +
  72687. +config MXC_IPU_PRP_ENC
  72688. + tristate "Pre-processor Encoder library"
  72689. + depends on VIDEO_MXC_IPU_CAMERA
  72690. + default y
  72691. + ---help---
  72692. + Use case PRP_ENC:
  72693. + Preprocessing image from smart sensor for encoder.
  72694. + CSI -> IC (PRP ENC) -> MEM
  72695. +
  72696. +config MXC_IPU_CSI_ENC
  72697. + tristate "IPU CSI Encoder library"
  72698. + depends on VIDEO_MXC_IPU_CAMERA
  72699. + default y
  72700. + ---help---
  72701. + Use case IPU_CSI_ENC:
  72702. + Get raw image with CSI from smart sensor for encoder.
  72703. + CSI -> MEM
  72704. +endmenu
  72705. +
  72706. +endif
  72707. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/Makefile linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/Makefile
  72708. --- linux-3.14.15/drivers/media/platform/mxc/capture/Makefile 1970-01-01 01:00:00.000000000 +0100
  72709. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/Makefile 2014-08-20 19:23:52.798842594 +0200
  72710. @@ -0,0 +1,21 @@
  72711. +obj-$(CONFIG_VIDEO_MXC_CSI_CAMERA) += fsl_csi.o csi_v4l2_capture.o
  72712. +
  72713. +ifeq ($(CONFIG_VIDEO_MXC_IPU_CAMERA),y)
  72714. + obj-$(CONFIG_VIDEO_MXC_CAPTURE) += mxc_v4l2_capture.o
  72715. + obj-$(CONFIG_MXC_IPU_PRP_VF_SDC) += ipu_prp_vf_sdc.o ipu_prp_vf_sdc_bg.o
  72716. + obj-$(CONFIG_MXC_IPU_DEVICE_QUEUE_SDC) += ipu_fg_overlay_sdc.o ipu_bg_overlay_sdc.o
  72717. + obj-$(CONFIG_MXC_IPU_PRP_ENC) += ipu_prp_enc.o ipu_still.o
  72718. + obj-$(CONFIG_MXC_IPU_CSI_ENC) += ipu_csi_enc.o ipu_still.o
  72719. +endif
  72720. +
  72721. +ov5640_camera-objs := ov5640.o
  72722. +obj-$(CONFIG_MXC_CAMERA_OV5640) += ov5640_camera.o
  72723. +
  72724. +ov5642_camera-objs := ov5642.o
  72725. +obj-$(CONFIG_MXC_CAMERA_OV5642) += ov5642_camera.o
  72726. +
  72727. +ov5640_camera_mipi-objs := ov5640_mipi.o
  72728. +obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI) += ov5640_camera_mipi.o
  72729. +
  72730. +adv7180_tvin-objs := adv7180.o
  72731. +obj-$(CONFIG_MXC_TVIN_ADV7180) += adv7180_tvin.o
  72732. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c
  72733. --- linux-3.14.15/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c 1970-01-01 01:00:00.000000000 +0100
  72734. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c 2014-08-20 19:31:45.440866052 +0200
  72735. @@ -0,0 +1,3102 @@
  72736. +/*
  72737. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  72738. + */
  72739. +
  72740. +/*
  72741. + * The code contained herein is licensed under the GNU General Public
  72742. + * License. You may obtain a copy of the GNU General Public License
  72743. + * Version 2 or later at the following locations:
  72744. + *
  72745. + * http://www.opensource.org/licenses/gpl-license.html
  72746. + * http://www.gnu.org/copyleft/gpl.html
  72747. + */
  72748. +
  72749. +/*!
  72750. + * @file drivers/media/video/mxc/capture/mxc_v4l2_capture.c
  72751. + *
  72752. + * @brief Mxc Video For Linux 2 driver
  72753. + *
  72754. + * @ingroup MXC_V4L2_CAPTURE
  72755. + */
  72756. +#include <linux/version.h>
  72757. +#include <linux/module.h>
  72758. +#include <linux/init.h>
  72759. +#include <linux/platform_device.h>
  72760. +#include <linux/fs.h>
  72761. +#include <linux/slab.h>
  72762. +#include <linux/ctype.h>
  72763. +#include <linux/clk.h>
  72764. +#include <linux/io.h>
  72765. +#include <linux/semaphore.h>
  72766. +#include <linux/pagemap.h>
  72767. +#include <linux/vmalloc.h>
  72768. +#include <linux/types.h>
  72769. +#include <linux/fb.h>
  72770. +#include <linux/dma-mapping.h>
  72771. +#include <linux/delay.h>
  72772. +#include <linux/mxcfb.h>
  72773. +#include <linux/of_device.h>
  72774. +#include <media/v4l2-chip-ident.h>
  72775. +#include <media/v4l2-ioctl.h>
  72776. +#include <media/v4l2-int-device.h>
  72777. +#include <linux/fsl_devices.h>
  72778. +#include "mxc_v4l2_capture.h"
  72779. +#include "ipu_prp_sw.h"
  72780. +
  72781. +#define init_MUTEX(sem) sema_init(sem, 1)
  72782. +
  72783. +static struct platform_device_id imx_v4l2_devtype[] = {
  72784. + {
  72785. + .name = "v4l2-capture-imx5",
  72786. + .driver_data = IMX5_V4L2,
  72787. + }, {
  72788. + .name = "v4l2-capture-imx6",
  72789. + .driver_data = IMX6_V4L2,
  72790. + }, {
  72791. + /* sentinel */
  72792. + }
  72793. +};
  72794. +MODULE_DEVICE_TABLE(platform, imx_v4l2_devtype);
  72795. +
  72796. +static const struct of_device_id mxc_v4l2_dt_ids[] = {
  72797. + {
  72798. + .compatible = "fsl,imx6q-v4l2-capture",
  72799. + .data = &imx_v4l2_devtype[IMX6_V4L2],
  72800. + }, {
  72801. + /* sentinel */
  72802. + }
  72803. +};
  72804. +MODULE_DEVICE_TABLE(of, mxc_v4l2_dt_ids);
  72805. +
  72806. +static int video_nr = -1;
  72807. +
  72808. +/*! This data is used for the output to the display. */
  72809. +#define MXC_V4L2_CAPTURE_NUM_OUTPUTS 6
  72810. +#define MXC_V4L2_CAPTURE_NUM_INPUTS 2
  72811. +static struct v4l2_output mxc_capture_outputs[MXC_V4L2_CAPTURE_NUM_OUTPUTS] = {
  72812. + {
  72813. + .index = 0,
  72814. + .name = "DISP3 BG",
  72815. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72816. + .audioset = 0,
  72817. + .modulator = 0,
  72818. + .std = V4L2_STD_UNKNOWN,
  72819. + },
  72820. + {
  72821. + .index = 1,
  72822. + .name = "DISP3 BG - DI1",
  72823. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72824. + .audioset = 0,
  72825. + .modulator = 0,
  72826. + .std = V4L2_STD_UNKNOWN,
  72827. + },
  72828. + {
  72829. + .index = 2,
  72830. + .name = "DISP3 FG",
  72831. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72832. + .audioset = 0,
  72833. + .modulator = 0,
  72834. + .std = V4L2_STD_UNKNOWN,
  72835. + },
  72836. + {
  72837. + .index = 3,
  72838. + .name = "DISP4 BG",
  72839. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72840. + .audioset = 0,
  72841. + .modulator = 0,
  72842. + .std = V4L2_STD_UNKNOWN,
  72843. + },
  72844. + {
  72845. + .index = 4,
  72846. + .name = "DISP4 BG - DI1",
  72847. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72848. + .audioset = 0,
  72849. + .modulator = 0,
  72850. + .std = V4L2_STD_UNKNOWN,
  72851. + },
  72852. + {
  72853. + .index = 5,
  72854. + .name = "DISP4 FG",
  72855. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72856. + .audioset = 0,
  72857. + .modulator = 0,
  72858. + .std = V4L2_STD_UNKNOWN,
  72859. + },
  72860. +};
  72861. +
  72862. +static struct v4l2_input mxc_capture_inputs[MXC_V4L2_CAPTURE_NUM_INPUTS] = {
  72863. + {
  72864. + .index = 0,
  72865. + .name = "CSI IC MEM",
  72866. + .type = V4L2_INPUT_TYPE_CAMERA,
  72867. + .audioset = 0,
  72868. + .tuner = 0,
  72869. + .std = V4L2_STD_UNKNOWN,
  72870. + .status = 0,
  72871. + },
  72872. + {
  72873. + .index = 1,
  72874. + .name = "CSI MEM",
  72875. + .type = V4L2_INPUT_TYPE_CAMERA,
  72876. + .audioset = 0,
  72877. + .tuner = 0,
  72878. + .std = V4L2_STD_UNKNOWN,
  72879. + .status = V4L2_IN_ST_NO_POWER,
  72880. + },
  72881. +};
  72882. +
  72883. +/*! List of TV input video formats supported. The video formats is corresponding
  72884. + * to the v4l2_id in video_fmt_t.
  72885. + * Currently, only PAL and NTSC is supported. Needs to be expanded in the
  72886. + * future.
  72887. + */
  72888. +typedef enum {
  72889. + TV_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
  72890. + TV_PAL, /*!< (B, G, H, I, N)PAL video signal. */
  72891. + TV_NOT_LOCKED, /*!< Not locked on a signal. */
  72892. +} video_fmt_idx;
  72893. +
  72894. +/*! Number of video standards supported (including 'not locked' signal). */
  72895. +#define TV_STD_MAX (TV_NOT_LOCKED + 1)
  72896. +
  72897. +/*! Video format structure. */
  72898. +typedef struct {
  72899. + int v4l2_id; /*!< Video for linux ID. */
  72900. + char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
  72901. + u16 raw_width; /*!< Raw width. */
  72902. + u16 raw_height; /*!< Raw height. */
  72903. + u16 active_width; /*!< Active width. */
  72904. + u16 active_height; /*!< Active height. */
  72905. + u16 active_top; /*!< Active top. */
  72906. + u16 active_left; /*!< Active left. */
  72907. +} video_fmt_t;
  72908. +
  72909. +/*!
  72910. + * Description of video formats supported.
  72911. + *
  72912. + * PAL: raw=720x625, active=720x576.
  72913. + * NTSC: raw=720x525, active=720x480.
  72914. + */
  72915. +static video_fmt_t video_fmts[] = {
  72916. + { /*! NTSC */
  72917. + .v4l2_id = V4L2_STD_NTSC,
  72918. + .name = "NTSC",
  72919. + .raw_width = 720, /* SENS_FRM_WIDTH */
  72920. + .raw_height = 525, /* SENS_FRM_HEIGHT */
  72921. + .active_width = 720, /* ACT_FRM_WIDTH */
  72922. + .active_height = 480, /* ACT_FRM_HEIGHT */
  72923. + .active_top = 13,
  72924. + .active_left = 0,
  72925. + },
  72926. + { /*! (B, G, H, I, N) PAL */
  72927. + .v4l2_id = V4L2_STD_PAL,
  72928. + .name = "PAL",
  72929. + .raw_width = 720,
  72930. + .raw_height = 625,
  72931. + .active_width = 720,
  72932. + .active_height = 576,
  72933. + .active_top = 0,
  72934. + .active_left = 0,
  72935. + },
  72936. + { /*! Unlocked standard */
  72937. + .v4l2_id = V4L2_STD_ALL,
  72938. + .name = "Autodetect",
  72939. + .raw_width = 720,
  72940. + .raw_height = 625,
  72941. + .active_width = 720,
  72942. + .active_height = 576,
  72943. + .active_top = 0,
  72944. + .active_left = 0,
  72945. + },
  72946. +};
  72947. +
  72948. +/*!* Standard index of TV. */
  72949. +static video_fmt_idx video_index = TV_NOT_LOCKED;
  72950. +
  72951. +static int mxc_v4l2_master_attach(struct v4l2_int_device *slave);
  72952. +static void mxc_v4l2_master_detach(struct v4l2_int_device *slave);
  72953. +static int start_preview(cam_data *cam);
  72954. +static int stop_preview(cam_data *cam);
  72955. +
  72956. +/*! Information about this driver. */
  72957. +static struct v4l2_int_master mxc_v4l2_master = {
  72958. + .attach = mxc_v4l2_master_attach,
  72959. + .detach = mxc_v4l2_master_detach,
  72960. +};
  72961. +
  72962. +/***************************************************************************
  72963. + * Functions for handling Frame buffers.
  72964. + **************************************************************************/
  72965. +
  72966. +/*!
  72967. + * Free frame buffers
  72968. + *
  72969. + * @param cam Structure cam_data *
  72970. + *
  72971. + * @return status 0 success.
  72972. + */
  72973. +static int mxc_free_frame_buf(cam_data *cam)
  72974. +{
  72975. + int i;
  72976. +
  72977. + pr_debug("MVC: In mxc_free_frame_buf\n");
  72978. +
  72979. + for (i = 0; i < FRAME_NUM; i++) {
  72980. + if (cam->frame[i].vaddress != 0) {
  72981. + dma_free_coherent(0, cam->frame[i].buffer.length,
  72982. + cam->frame[i].vaddress,
  72983. + cam->frame[i].paddress);
  72984. + cam->frame[i].vaddress = 0;
  72985. + }
  72986. + }
  72987. +
  72988. + return 0;
  72989. +}
  72990. +
  72991. +/*!
  72992. + * Allocate frame buffers
  72993. + *
  72994. + * @param cam Structure cam_data*
  72995. + * @param count int number of buffer need to allocated
  72996. + *
  72997. + * @return status -0 Successfully allocated a buffer, -ENOBUFS failed.
  72998. + */
  72999. +static int mxc_allocate_frame_buf(cam_data *cam, int count)
  73000. +{
  73001. + int i;
  73002. +
  73003. + pr_debug("In MVC:mxc_allocate_frame_buf - size=%d\n",
  73004. + cam->v2f.fmt.pix.sizeimage);
  73005. +
  73006. + for (i = 0; i < count; i++) {
  73007. + cam->frame[i].vaddress =
  73008. + dma_alloc_coherent(0,
  73009. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  73010. + &cam->frame[i].paddress,
  73011. + GFP_DMA | GFP_KERNEL);
  73012. + if (cam->frame[i].vaddress == 0) {
  73013. + pr_err("ERROR: v4l2 capture: "
  73014. + "mxc_allocate_frame_buf failed.\n");
  73015. + mxc_free_frame_buf(cam);
  73016. + return -ENOBUFS;
  73017. + }
  73018. + cam->frame[i].buffer.index = i;
  73019. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  73020. + cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  73021. + cam->frame[i].buffer.length =
  73022. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  73023. + cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP;
  73024. + cam->frame[i].buffer.m.offset = cam->frame[i].paddress;
  73025. + cam->frame[i].index = i;
  73026. + }
  73027. +
  73028. + return 0;
  73029. +}
  73030. +
  73031. +/*!
  73032. + * Free frame buffers status
  73033. + *
  73034. + * @param cam Structure cam_data *
  73035. + *
  73036. + * @return none
  73037. + */
  73038. +static void mxc_free_frames(cam_data *cam)
  73039. +{
  73040. + int i;
  73041. +
  73042. + pr_debug("In MVC:mxc_free_frames\n");
  73043. +
  73044. + for (i = 0; i < FRAME_NUM; i++)
  73045. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  73046. +
  73047. + cam->enc_counter = 0;
  73048. + INIT_LIST_HEAD(&cam->ready_q);
  73049. + INIT_LIST_HEAD(&cam->working_q);
  73050. + INIT_LIST_HEAD(&cam->done_q);
  73051. +}
  73052. +
  73053. +/*!
  73054. + * Return the buffer status
  73055. + *
  73056. + * @param cam Structure cam_data *
  73057. + * @param buf Structure v4l2_buffer *
  73058. + *
  73059. + * @return status 0 success, EINVAL failed.
  73060. + */
  73061. +static int mxc_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf)
  73062. +{
  73063. + pr_debug("In MVC:mxc_v4l2_buffer_status\n");
  73064. +
  73065. + if (buf->index < 0 || buf->index >= FRAME_NUM) {
  73066. + pr_err("ERROR: v4l2 capture: mxc_v4l2_buffer_status buffers "
  73067. + "not allocated\n");
  73068. + return -EINVAL;
  73069. + }
  73070. +
  73071. + memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf));
  73072. + return 0;
  73073. +}
  73074. +
  73075. +static int mxc_v4l2_release_bufs(cam_data *cam)
  73076. +{
  73077. + pr_debug("In MVC:mxc_v4l2_release_bufs\n");
  73078. + return 0;
  73079. +}
  73080. +
  73081. +static int mxc_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf)
  73082. +{
  73083. + pr_debug("In MVC:mxc_v4l2_prepare_bufs\n");
  73084. +
  73085. + if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length <
  73086. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage)) {
  73087. + pr_err("ERROR: v4l2 capture: mxc_v4l2_prepare_bufs buffers "
  73088. + "not allocated,index=%d, length=%d\n", buf->index,
  73089. + buf->length);
  73090. + return -EINVAL;
  73091. + }
  73092. +
  73093. + cam->frame[buf->index].buffer.index = buf->index;
  73094. + cam->frame[buf->index].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  73095. + cam->frame[buf->index].buffer.length = buf->length;
  73096. + cam->frame[buf->index].buffer.m.offset = cam->frame[buf->index].paddress
  73097. + = buf->m.offset;
  73098. + cam->frame[buf->index].buffer.type = buf->type;
  73099. + cam->frame[buf->index].buffer.memory = V4L2_MEMORY_USERPTR;
  73100. + cam->frame[buf->index].index = buf->index;
  73101. +
  73102. + return 0;
  73103. +}
  73104. +
  73105. +/***************************************************************************
  73106. + * Functions for handling the video stream.
  73107. + **************************************************************************/
  73108. +
  73109. +/*!
  73110. + * Indicates whether the palette is supported.
  73111. + *
  73112. + * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_BGR24 or V4L2_PIX_FMT_BGR32
  73113. + *
  73114. + * @return 0 if failed
  73115. + */
  73116. +static inline int valid_mode(u32 palette)
  73117. +{
  73118. + return ((palette == V4L2_PIX_FMT_RGB565) ||
  73119. + (palette == V4L2_PIX_FMT_BGR24) ||
  73120. + (palette == V4L2_PIX_FMT_RGB24) ||
  73121. + (palette == V4L2_PIX_FMT_BGR32) ||
  73122. + (palette == V4L2_PIX_FMT_RGB32) ||
  73123. + (palette == V4L2_PIX_FMT_YUV422P) ||
  73124. + (palette == V4L2_PIX_FMT_UYVY) ||
  73125. + (palette == V4L2_PIX_FMT_YUYV) ||
  73126. + (palette == V4L2_PIX_FMT_YUV420) ||
  73127. + (palette == V4L2_PIX_FMT_YVU420) ||
  73128. + (palette == V4L2_PIX_FMT_NV12));
  73129. +}
  73130. +
  73131. +/*!
  73132. + * Start the encoder job
  73133. + *
  73134. + * @param cam structure cam_data *
  73135. + *
  73136. + * @return status 0 Success
  73137. + */
  73138. +static int mxc_streamon(cam_data *cam)
  73139. +{
  73140. + struct mxc_v4l_frame *frame;
  73141. + unsigned long lock_flags;
  73142. + int err = 0;
  73143. +
  73144. + pr_debug("In MVC:mxc_streamon\n");
  73145. +
  73146. + if (NULL == cam) {
  73147. + pr_err("ERROR! cam parameter is NULL\n");
  73148. + return -1;
  73149. + }
  73150. +
  73151. + if (cam->capture_on) {
  73152. + pr_err("ERROR: v4l2 capture: Capture stream has been turned "
  73153. + " on\n");
  73154. + return -1;
  73155. + }
  73156. +
  73157. + if (list_empty(&cam->ready_q)) {
  73158. + pr_err("ERROR: v4l2 capture: mxc_streamon buffer has not been "
  73159. + "queued yet\n");
  73160. + return -EINVAL;
  73161. + }
  73162. + if (cam->enc_update_eba &&
  73163. + cam->ready_q.prev == cam->ready_q.next) {
  73164. + pr_err("ERROR: v4l2 capture: mxc_streamon buffer need "
  73165. + "ping pong at least two buffers\n");
  73166. + return -EINVAL;
  73167. + }
  73168. +
  73169. + cam->capture_pid = current->pid;
  73170. +
  73171. + if (cam->overlay_on == true)
  73172. + stop_preview(cam);
  73173. +
  73174. + if (cam->enc_enable) {
  73175. + err = cam->enc_enable(cam);
  73176. + if (err != 0)
  73177. + return err;
  73178. + }
  73179. +
  73180. + spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
  73181. + cam->ping_pong_csi = 0;
  73182. + cam->local_buf_num = 0;
  73183. + if (cam->enc_update_eba) {
  73184. + frame =
  73185. + list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  73186. + list_del(cam->ready_q.next);
  73187. + list_add_tail(&frame->queue, &cam->working_q);
  73188. + frame->ipu_buf_num = cam->ping_pong_csi;
  73189. + err = cam->enc_update_eba(cam->ipu, frame->buffer.m.offset,
  73190. + &cam->ping_pong_csi);
  73191. +
  73192. + frame =
  73193. + list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  73194. + list_del(cam->ready_q.next);
  73195. + list_add_tail(&frame->queue, &cam->working_q);
  73196. + frame->ipu_buf_num = cam->ping_pong_csi;
  73197. + err |= cam->enc_update_eba(cam->ipu, frame->buffer.m.offset,
  73198. + &cam->ping_pong_csi);
  73199. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  73200. + } else {
  73201. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  73202. + return -EINVAL;
  73203. + }
  73204. +
  73205. + if (cam->overlay_on == true)
  73206. + start_preview(cam);
  73207. +
  73208. + if (cam->enc_enable_csi) {
  73209. + err = cam->enc_enable_csi(cam);
  73210. + if (err != 0)
  73211. + return err;
  73212. + }
  73213. +
  73214. + cam->capture_on = true;
  73215. +
  73216. + return err;
  73217. +}
  73218. +
  73219. +/*!
  73220. + * Shut down the encoder job
  73221. + *
  73222. + * @param cam structure cam_data *
  73223. + *
  73224. + * @return status 0 Success
  73225. + */
  73226. +static int mxc_streamoff(cam_data *cam)
  73227. +{
  73228. + int err = 0;
  73229. +
  73230. + pr_debug("In MVC:mxc_streamoff\n");
  73231. +
  73232. + if (cam->capture_on == false)
  73233. + return 0;
  73234. +
  73235. + /* For both CSI--MEM and CSI--IC--MEM
  73236. + * 1. wait for idmac eof
  73237. + * 2. disable csi first
  73238. + * 3. disable idmac
  73239. + * 4. disable smfc (CSI--MEM channel)
  73240. + */
  73241. + if (mxc_capture_inputs[cam->current_input].name != NULL) {
  73242. + if (cam->enc_disable_csi) {
  73243. + err = cam->enc_disable_csi(cam);
  73244. + if (err != 0)
  73245. + return err;
  73246. + }
  73247. + if (cam->enc_disable) {
  73248. + err = cam->enc_disable(cam);
  73249. + if (err != 0)
  73250. + return err;
  73251. + }
  73252. + }
  73253. +
  73254. + mxc_free_frames(cam);
  73255. + mxc_capture_inputs[cam->current_input].status |= V4L2_IN_ST_NO_POWER;
  73256. + cam->capture_on = false;
  73257. + return err;
  73258. +}
  73259. +
  73260. +/*!
  73261. + * Valid and adjust the overlay window size, position
  73262. + *
  73263. + * @param cam structure cam_data *
  73264. + * @param win struct v4l2_window *
  73265. + *
  73266. + * @return 0
  73267. + */
  73268. +static int verify_preview(cam_data *cam, struct v4l2_window *win)
  73269. +{
  73270. + int i = 0, width_bound = 0, height_bound = 0;
  73271. + int *width, *height;
  73272. + unsigned int ipu_ch = CHAN_NONE;
  73273. + struct fb_info *bg_fbi = NULL, *fbi = NULL;
  73274. + bool foregound_fb = false;
  73275. + mm_segment_t old_fs;
  73276. +
  73277. + pr_debug("In MVC: verify_preview\n");
  73278. +
  73279. + do {
  73280. + fbi = (struct fb_info *)registered_fb[i];
  73281. + if (fbi == NULL) {
  73282. + pr_err("ERROR: verify_preview frame buffer NULL.\n");
  73283. + return -1;
  73284. + }
  73285. +
  73286. + /* Which DI supports 2 layers? */
  73287. + if (((strncmp(fbi->fix.id, "DISP3 BG", 8) == 0) &&
  73288. + (cam->output < 3)) ||
  73289. + ((strncmp(fbi->fix.id, "DISP4 BG", 8) == 0) &&
  73290. + (cam->output >= 3))) {
  73291. + if (fbi->fbops->fb_ioctl) {
  73292. + old_fs = get_fs();
  73293. + set_fs(KERNEL_DS);
  73294. + fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_IPU_CHAN,
  73295. + (unsigned long)&ipu_ch);
  73296. + set_fs(old_fs);
  73297. + }
  73298. + if (ipu_ch == MEM_BG_SYNC) {
  73299. + bg_fbi = fbi;
  73300. + pr_debug("Found background frame buffer.\n");
  73301. + }
  73302. + }
  73303. +
  73304. + /* Found the frame buffer to preview on. */
  73305. + if (strcmp(fbi->fix.id,
  73306. + mxc_capture_outputs[cam->output].name) == 0) {
  73307. + if (((strcmp(fbi->fix.id, "DISP3 FG") == 0) &&
  73308. + (cam->output < 3)) ||
  73309. + ((strcmp(fbi->fix.id, "DISP4 FG") == 0) &&
  73310. + (cam->output >= 3)))
  73311. + foregound_fb = true;
  73312. +
  73313. + cam->overlay_fb = fbi;
  73314. + break;
  73315. + }
  73316. + } while (++i < FB_MAX);
  73317. +
  73318. + if (foregound_fb) {
  73319. + width_bound = bg_fbi->var.xres;
  73320. + height_bound = bg_fbi->var.yres;
  73321. +
  73322. + if (win->w.width + win->w.left > bg_fbi->var.xres ||
  73323. + win->w.height + win->w.top > bg_fbi->var.yres) {
  73324. + pr_err("ERROR: FG window position exceeds.\n");
  73325. + return -1;
  73326. + }
  73327. + } else {
  73328. + /* 4 bytes alignment for BG */
  73329. + width_bound = cam->overlay_fb->var.xres;
  73330. + height_bound = cam->overlay_fb->var.yres;
  73331. +
  73332. + if (cam->overlay_fb->var.bits_per_pixel == 24)
  73333. + win->w.left -= win->w.left % 4;
  73334. + else if (cam->overlay_fb->var.bits_per_pixel == 16)
  73335. + win->w.left -= win->w.left % 2;
  73336. +
  73337. + if (win->w.width + win->w.left > cam->overlay_fb->var.xres)
  73338. + win->w.width = cam->overlay_fb->var.xres - win->w.left;
  73339. + if (win->w.height + win->w.top > cam->overlay_fb->var.yres)
  73340. + win->w.height = cam->overlay_fb->var.yres - win->w.top;
  73341. + }
  73342. +
  73343. + /* stride line limitation */
  73344. + win->w.height -= win->w.height % 8;
  73345. + win->w.width -= win->w.width % 8;
  73346. +
  73347. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  73348. + height = &win->w.width;
  73349. + width = &win->w.height;
  73350. + } else {
  73351. + width = &win->w.width;
  73352. + height = &win->w.height;
  73353. + }
  73354. +
  73355. + if (*width == 0 || *height == 0) {
  73356. + pr_err("ERROR: v4l2 capture: width or height"
  73357. + " too small.\n");
  73358. + return -EINVAL;
  73359. + }
  73360. +
  73361. + if ((cam->crop_bounds.width / *width > 8) ||
  73362. + ((cam->crop_bounds.width / *width == 8) &&
  73363. + (cam->crop_bounds.width % *width))) {
  73364. + *width = cam->crop_bounds.width / 8;
  73365. + if (*width % 8)
  73366. + *width += 8 - *width % 8;
  73367. + if (*width + win->w.left > width_bound) {
  73368. + pr_err("ERROR: v4l2 capture: width exceeds "
  73369. + "resize limit.\n");
  73370. + return -1;
  73371. + }
  73372. + pr_err("ERROR: v4l2 capture: width exceeds limit. "
  73373. + "Resize to %d.\n",
  73374. + *width);
  73375. + }
  73376. +
  73377. + if ((cam->crop_bounds.height / *height > 8) ||
  73378. + ((cam->crop_bounds.height / *height == 8) &&
  73379. + (cam->crop_bounds.height % *height))) {
  73380. + *height = cam->crop_bounds.height / 8;
  73381. + if (*height % 8)
  73382. + *height += 8 - *height % 8;
  73383. + if (*height + win->w.top > height_bound) {
  73384. + pr_err("ERROR: v4l2 capture: height exceeds "
  73385. + "resize limit.\n");
  73386. + return -1;
  73387. + }
  73388. + pr_err("ERROR: v4l2 capture: height exceeds limit "
  73389. + "resize to %d.\n",
  73390. + *height);
  73391. + }
  73392. +
  73393. + return 0;
  73394. +}
  73395. +
  73396. +/*!
  73397. + * start the viewfinder job
  73398. + *
  73399. + * @param cam structure cam_data *
  73400. + *
  73401. + * @return status 0 Success
  73402. + */
  73403. +static int start_preview(cam_data *cam)
  73404. +{
  73405. + int err = 0;
  73406. +
  73407. + pr_debug("MVC: start_preview\n");
  73408. +
  73409. + if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
  73410. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  73411. + err = prp_vf_sdc_select(cam);
  73412. + #else
  73413. + err = foreground_sdc_select(cam);
  73414. + #endif
  73415. + else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
  73416. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  73417. + err = prp_vf_sdc_select_bg(cam);
  73418. + #else
  73419. + err = bg_overlay_sdc_select(cam);
  73420. + #endif
  73421. + if (err != 0)
  73422. + return err;
  73423. +
  73424. + if (cam->vf_start_sdc) {
  73425. + err = cam->vf_start_sdc(cam);
  73426. + if (err != 0)
  73427. + return err;
  73428. + }
  73429. +
  73430. + if (cam->vf_enable_csi)
  73431. + err = cam->vf_enable_csi(cam);
  73432. +
  73433. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  73434. + __func__,
  73435. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  73436. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  73437. + __func__,
  73438. + cam->crop_bounds.width, cam->crop_bounds.height);
  73439. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  73440. + __func__,
  73441. + cam->crop_defrect.width, cam->crop_defrect.height);
  73442. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  73443. + __func__,
  73444. + cam->crop_current.width, cam->crop_current.height);
  73445. +
  73446. + return err;
  73447. +}
  73448. +
  73449. +/*!
  73450. + * shut down the viewfinder job
  73451. + *
  73452. + * @param cam structure cam_data *
  73453. + *
  73454. + * @return status 0 Success
  73455. + */
  73456. +static int stop_preview(cam_data *cam)
  73457. +{
  73458. + int err = 0;
  73459. +
  73460. + if (cam->vf_disable_csi) {
  73461. + err = cam->vf_disable_csi(cam);
  73462. + if (err != 0)
  73463. + return err;
  73464. + }
  73465. +
  73466. + if (cam->vf_stop_sdc) {
  73467. + err = cam->vf_stop_sdc(cam);
  73468. + if (err != 0)
  73469. + return err;
  73470. + }
  73471. +
  73472. + if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
  73473. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  73474. + err = prp_vf_sdc_deselect(cam);
  73475. + #else
  73476. + err = foreground_sdc_deselect(cam);
  73477. + #endif
  73478. + else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
  73479. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  73480. + err = prp_vf_sdc_deselect_bg(cam);
  73481. + #else
  73482. + err = bg_overlay_sdc_deselect(cam);
  73483. + #endif
  73484. +
  73485. + return err;
  73486. +}
  73487. +
  73488. +/***************************************************************************
  73489. + * VIDIOC Functions.
  73490. + **************************************************************************/
  73491. +
  73492. +/*!
  73493. + * V4L2 - mxc_v4l2_g_fmt function
  73494. + *
  73495. + * @param cam structure cam_data *
  73496. + *
  73497. + * @param f structure v4l2_format *
  73498. + *
  73499. + * @return status 0 success, EINVAL failed
  73500. + */
  73501. +static int mxc_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f)
  73502. +{
  73503. + int retval = 0;
  73504. +
  73505. + pr_debug("In MVC: mxc_v4l2_g_fmt type=%d\n", f->type);
  73506. +
  73507. + switch (f->type) {
  73508. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  73509. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  73510. + f->fmt.pix = cam->v2f.fmt.pix;
  73511. + break;
  73512. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  73513. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  73514. + f->fmt.win = cam->win;
  73515. + break;
  73516. + default:
  73517. + pr_debug(" type is invalid\n");
  73518. + retval = -EINVAL;
  73519. + }
  73520. +
  73521. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  73522. + __func__,
  73523. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  73524. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  73525. + __func__,
  73526. + cam->crop_bounds.width, cam->crop_bounds.height);
  73527. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  73528. + __func__,
  73529. + cam->crop_defrect.width, cam->crop_defrect.height);
  73530. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  73531. + __func__,
  73532. + cam->crop_current.width, cam->crop_current.height);
  73533. +
  73534. + return retval;
  73535. +}
  73536. +
  73537. +/*!
  73538. + * V4L2 - mxc_v4l2_s_fmt function
  73539. + *
  73540. + * @param cam structure cam_data *
  73541. + *
  73542. + * @param f structure v4l2_format *
  73543. + *
  73544. + * @return status 0 success, EINVAL failed
  73545. + */
  73546. +static int mxc_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
  73547. +{
  73548. + int retval = 0;
  73549. + int size = 0;
  73550. + int bytesperline = 0;
  73551. + int *width, *height;
  73552. +
  73553. + pr_debug("In MVC: mxc_v4l2_s_fmt\n");
  73554. +
  73555. + switch (f->type) {
  73556. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  73557. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  73558. + if (!valid_mode(f->fmt.pix.pixelformat)) {
  73559. + pr_err("ERROR: v4l2 capture: mxc_v4l2_s_fmt: format "
  73560. + "not supported\n");
  73561. + return -EINVAL;
  73562. + }
  73563. +
  73564. + /*
  73565. + * Force the capture window resolution to be crop bounds
  73566. + * for CSI MEM input mode.
  73567. + */
  73568. + if (strcmp(mxc_capture_inputs[cam->current_input].name,
  73569. + "CSI MEM") == 0) {
  73570. + f->fmt.pix.width = cam->crop_current.width;
  73571. + f->fmt.pix.height = cam->crop_current.height;
  73572. + }
  73573. +
  73574. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  73575. + height = &f->fmt.pix.width;
  73576. + width = &f->fmt.pix.height;
  73577. + } else {
  73578. + width = &f->fmt.pix.width;
  73579. + height = &f->fmt.pix.height;
  73580. + }
  73581. +
  73582. + /* stride line limitation */
  73583. + *width -= *width % 8;
  73584. + *height -= *height % 8;
  73585. +
  73586. + if (*width == 0 || *height == 0) {
  73587. + pr_err("ERROR: v4l2 capture: width or height"
  73588. + " too small.\n");
  73589. + return -EINVAL;
  73590. + }
  73591. +
  73592. + if ((cam->crop_current.width / *width > 8) ||
  73593. + ((cam->crop_current.width / *width == 8) &&
  73594. + (cam->crop_current.width % *width))) {
  73595. + *width = cam->crop_current.width / 8;
  73596. + if (*width % 8)
  73597. + *width += 8 - *width % 8;
  73598. + pr_err("ERROR: v4l2 capture: width exceeds limit "
  73599. + "resize to %d.\n",
  73600. + *width);
  73601. + }
  73602. +
  73603. + if ((cam->crop_current.height / *height > 8) ||
  73604. + ((cam->crop_current.height / *height == 8) &&
  73605. + (cam->crop_current.height % *height))) {
  73606. + *height = cam->crop_current.height / 8;
  73607. + if (*height % 8)
  73608. + *height += 8 - *height % 8;
  73609. + pr_err("ERROR: v4l2 capture: height exceeds limit "
  73610. + "resize to %d.\n",
  73611. + *height);
  73612. + }
  73613. +
  73614. + switch (f->fmt.pix.pixelformat) {
  73615. + case V4L2_PIX_FMT_RGB565:
  73616. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  73617. + bytesperline = f->fmt.pix.width * 2;
  73618. + break;
  73619. + case V4L2_PIX_FMT_BGR24:
  73620. + size = f->fmt.pix.width * f->fmt.pix.height * 3;
  73621. + bytesperline = f->fmt.pix.width * 3;
  73622. + break;
  73623. + case V4L2_PIX_FMT_RGB24:
  73624. + size = f->fmt.pix.width * f->fmt.pix.height * 3;
  73625. + bytesperline = f->fmt.pix.width * 3;
  73626. + break;
  73627. + case V4L2_PIX_FMT_BGR32:
  73628. + size = f->fmt.pix.width * f->fmt.pix.height * 4;
  73629. + bytesperline = f->fmt.pix.width * 4;
  73630. + break;
  73631. + case V4L2_PIX_FMT_RGB32:
  73632. + size = f->fmt.pix.width * f->fmt.pix.height * 4;
  73633. + bytesperline = f->fmt.pix.width * 4;
  73634. + break;
  73635. + case V4L2_PIX_FMT_YUV422P:
  73636. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  73637. + bytesperline = f->fmt.pix.width;
  73638. + break;
  73639. + case V4L2_PIX_FMT_UYVY:
  73640. + case V4L2_PIX_FMT_YUYV:
  73641. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  73642. + bytesperline = f->fmt.pix.width * 2;
  73643. + break;
  73644. + case V4L2_PIX_FMT_YUV420:
  73645. + case V4L2_PIX_FMT_YVU420:
  73646. + size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
  73647. + bytesperline = f->fmt.pix.width;
  73648. + break;
  73649. + case V4L2_PIX_FMT_NV12:
  73650. + size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
  73651. + bytesperline = f->fmt.pix.width;
  73652. + break;
  73653. + default:
  73654. + break;
  73655. + }
  73656. +
  73657. + if (f->fmt.pix.bytesperline < bytesperline)
  73658. + f->fmt.pix.bytesperline = bytesperline;
  73659. + else
  73660. + bytesperline = f->fmt.pix.bytesperline;
  73661. +
  73662. + if (f->fmt.pix.sizeimage < size)
  73663. + f->fmt.pix.sizeimage = size;
  73664. + else
  73665. + size = f->fmt.pix.sizeimage;
  73666. +
  73667. + cam->v2f.fmt.pix = f->fmt.pix;
  73668. +
  73669. + if (cam->v2f.fmt.pix.priv != 0) {
  73670. + if (copy_from_user(&cam->offset,
  73671. + (void *)cam->v2f.fmt.pix.priv,
  73672. + sizeof(cam->offset))) {
  73673. + retval = -EFAULT;
  73674. + break;
  73675. + }
  73676. + }
  73677. + break;
  73678. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  73679. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  73680. + retval = verify_preview(cam, &f->fmt.win);
  73681. + cam->win = f->fmt.win;
  73682. + break;
  73683. + default:
  73684. + retval = -EINVAL;
  73685. + }
  73686. +
  73687. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  73688. + __func__,
  73689. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  73690. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  73691. + __func__,
  73692. + cam->crop_bounds.width, cam->crop_bounds.height);
  73693. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  73694. + __func__,
  73695. + cam->crop_defrect.width, cam->crop_defrect.height);
  73696. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  73697. + __func__,
  73698. + cam->crop_current.width, cam->crop_current.height);
  73699. +
  73700. + return retval;
  73701. +}
  73702. +
  73703. +/*!
  73704. + * get control param
  73705. + *
  73706. + * @param cam structure cam_data *
  73707. + *
  73708. + * @param c structure v4l2_control *
  73709. + *
  73710. + * @return status 0 success, EINVAL failed
  73711. + */
  73712. +static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
  73713. +{
  73714. + int status = 0;
  73715. +
  73716. + pr_debug("In MVC:mxc_v4l2_g_ctrl\n");
  73717. +
  73718. + /* probably don't need to store the values that can be retrieved,
  73719. + * locally, but they are for now. */
  73720. + switch (c->id) {
  73721. + case V4L2_CID_HFLIP:
  73722. + /* This is handled in the ipu. */
  73723. + if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
  73724. + c->value = 1;
  73725. + break;
  73726. + case V4L2_CID_VFLIP:
  73727. + /* This is handled in the ipu. */
  73728. + if (cam->rotation == IPU_ROTATE_VERT_FLIP)
  73729. + c->value = 1;
  73730. + break;
  73731. + case V4L2_CID_MXC_ROT:
  73732. + /* This is handled in the ipu. */
  73733. + c->value = cam->rotation;
  73734. + break;
  73735. + case V4L2_CID_BRIGHTNESS:
  73736. + if (cam->sensor) {
  73737. + c->value = cam->bright;
  73738. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73739. + cam->bright = c->value;
  73740. + } else {
  73741. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73742. + status = -ENODEV;
  73743. + }
  73744. + break;
  73745. + case V4L2_CID_HUE:
  73746. + if (cam->sensor) {
  73747. + c->value = cam->hue;
  73748. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73749. + cam->hue = c->value;
  73750. + } else {
  73751. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73752. + status = -ENODEV;
  73753. + }
  73754. + break;
  73755. + case V4L2_CID_CONTRAST:
  73756. + if (cam->sensor) {
  73757. + c->value = cam->contrast;
  73758. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73759. + cam->contrast = c->value;
  73760. + } else {
  73761. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73762. + status = -ENODEV;
  73763. + }
  73764. + break;
  73765. + case V4L2_CID_SATURATION:
  73766. + if (cam->sensor) {
  73767. + c->value = cam->saturation;
  73768. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73769. + cam->saturation = c->value;
  73770. + } else {
  73771. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73772. + status = -ENODEV;
  73773. + }
  73774. + break;
  73775. + case V4L2_CID_RED_BALANCE:
  73776. + if (cam->sensor) {
  73777. + c->value = cam->red;
  73778. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73779. + cam->red = c->value;
  73780. + } else {
  73781. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73782. + status = -ENODEV;
  73783. + }
  73784. + break;
  73785. + case V4L2_CID_BLUE_BALANCE:
  73786. + if (cam->sensor) {
  73787. + c->value = cam->blue;
  73788. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73789. + cam->blue = c->value;
  73790. + } else {
  73791. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73792. + status = -ENODEV;
  73793. + }
  73794. + break;
  73795. + case V4L2_CID_BLACK_LEVEL:
  73796. + if (cam->sensor) {
  73797. + c->value = cam->ae_mode;
  73798. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73799. + cam->ae_mode = c->value;
  73800. + } else {
  73801. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73802. + status = -ENODEV;
  73803. + }
  73804. + break;
  73805. + default:
  73806. + pr_err("ERROR: v4l2 capture: unsupported ioctrl!\n");
  73807. + }
  73808. +
  73809. + return status;
  73810. +}
  73811. +
  73812. +/*!
  73813. + * V4L2 - set_control function
  73814. + * V4L2_CID_PRIVATE_BASE is the extention for IPU preprocessing.
  73815. + * 0 for normal operation
  73816. + * 1 for vertical flip
  73817. + * 2 for horizontal flip
  73818. + * 3 for horizontal and vertical flip
  73819. + * 4 for 90 degree rotation
  73820. + * @param cam structure cam_data *
  73821. + *
  73822. + * @param c structure v4l2_control *
  73823. + *
  73824. + * @return status 0 success, EINVAL failed
  73825. + */
  73826. +static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
  73827. +{
  73828. + int i, ret = 0;
  73829. + int tmp_rotation = IPU_ROTATE_NONE;
  73830. + struct sensor_data *sensor_data;
  73831. +
  73832. + pr_debug("In MVC:mxc_v4l2_s_ctrl\n");
  73833. +
  73834. + switch (c->id) {
  73835. + case V4L2_CID_HFLIP:
  73836. + /* This is done by the IPU */
  73837. + if (c->value == 1) {
  73838. + if ((cam->rotation != IPU_ROTATE_VERT_FLIP) &&
  73839. + (cam->rotation != IPU_ROTATE_180))
  73840. + cam->rotation = IPU_ROTATE_HORIZ_FLIP;
  73841. + else
  73842. + cam->rotation = IPU_ROTATE_180;
  73843. + } else {
  73844. + if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
  73845. + cam->rotation = IPU_ROTATE_NONE;
  73846. + if (cam->rotation == IPU_ROTATE_180)
  73847. + cam->rotation = IPU_ROTATE_VERT_FLIP;
  73848. + }
  73849. + break;
  73850. + case V4L2_CID_VFLIP:
  73851. + /* This is done by the IPU */
  73852. + if (c->value == 1) {
  73853. + if ((cam->rotation != IPU_ROTATE_HORIZ_FLIP) &&
  73854. + (cam->rotation != IPU_ROTATE_180))
  73855. + cam->rotation = IPU_ROTATE_VERT_FLIP;
  73856. + else
  73857. + cam->rotation = IPU_ROTATE_180;
  73858. + } else {
  73859. + if (cam->rotation == IPU_ROTATE_VERT_FLIP)
  73860. + cam->rotation = IPU_ROTATE_NONE;
  73861. + if (cam->rotation == IPU_ROTATE_180)
  73862. + cam->rotation = IPU_ROTATE_HORIZ_FLIP;
  73863. + }
  73864. + break;
  73865. + case V4L2_CID_MXC_ROT:
  73866. + case V4L2_CID_MXC_VF_ROT:
  73867. + /* This is done by the IPU */
  73868. + switch (c->value) {
  73869. + case V4L2_MXC_ROTATE_NONE:
  73870. + tmp_rotation = IPU_ROTATE_NONE;
  73871. + break;
  73872. + case V4L2_MXC_ROTATE_VERT_FLIP:
  73873. + tmp_rotation = IPU_ROTATE_VERT_FLIP;
  73874. + break;
  73875. + case V4L2_MXC_ROTATE_HORIZ_FLIP:
  73876. + tmp_rotation = IPU_ROTATE_HORIZ_FLIP;
  73877. + break;
  73878. + case V4L2_MXC_ROTATE_180:
  73879. + tmp_rotation = IPU_ROTATE_180;
  73880. + break;
  73881. + case V4L2_MXC_ROTATE_90_RIGHT:
  73882. + tmp_rotation = IPU_ROTATE_90_RIGHT;
  73883. + break;
  73884. + case V4L2_MXC_ROTATE_90_RIGHT_VFLIP:
  73885. + tmp_rotation = IPU_ROTATE_90_RIGHT_VFLIP;
  73886. + break;
  73887. + case V4L2_MXC_ROTATE_90_RIGHT_HFLIP:
  73888. + tmp_rotation = IPU_ROTATE_90_RIGHT_HFLIP;
  73889. + break;
  73890. + case V4L2_MXC_ROTATE_90_LEFT:
  73891. + tmp_rotation = IPU_ROTATE_90_LEFT;
  73892. + break;
  73893. + default:
  73894. + ret = -EINVAL;
  73895. + }
  73896. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  73897. + if (c->id == V4L2_CID_MXC_VF_ROT)
  73898. + cam->vf_rotation = tmp_rotation;
  73899. + else
  73900. + cam->rotation = tmp_rotation;
  73901. + #else
  73902. + cam->rotation = tmp_rotation;
  73903. + #endif
  73904. +
  73905. + break;
  73906. + case V4L2_CID_HUE:
  73907. + if (cam->sensor) {
  73908. + cam->hue = c->value;
  73909. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73910. + } else {
  73911. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73912. + ret = -ENODEV;
  73913. + }
  73914. + break;
  73915. + case V4L2_CID_CONTRAST:
  73916. + if (cam->sensor) {
  73917. + cam->contrast = c->value;
  73918. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73919. + } else {
  73920. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73921. + ret = -ENODEV;
  73922. + }
  73923. + break;
  73924. + case V4L2_CID_BRIGHTNESS:
  73925. + if (cam->sensor) {
  73926. + cam->bright = c->value;
  73927. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73928. + } else {
  73929. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73930. + ret = -ENODEV;
  73931. + }
  73932. + break;
  73933. + case V4L2_CID_SATURATION:
  73934. + if (cam->sensor) {
  73935. + cam->saturation = c->value;
  73936. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73937. + } else {
  73938. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73939. + ret = -ENODEV;
  73940. + }
  73941. + break;
  73942. + case V4L2_CID_RED_BALANCE:
  73943. + if (cam->sensor) {
  73944. + cam->red = c->value;
  73945. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73946. + } else {
  73947. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73948. + ret = -ENODEV;
  73949. + }
  73950. + break;
  73951. + case V4L2_CID_BLUE_BALANCE:
  73952. + if (cam->sensor) {
  73953. + cam->blue = c->value;
  73954. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73955. + } else {
  73956. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73957. + ret = -ENODEV;
  73958. + }
  73959. + break;
  73960. + case V4L2_CID_EXPOSURE:
  73961. + if (cam->sensor) {
  73962. + cam->ae_mode = c->value;
  73963. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73964. + } else {
  73965. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73966. + ret = -ENODEV;
  73967. + }
  73968. + break;
  73969. + case V4L2_CID_MXC_FLASH:
  73970. +#ifdef CONFIG_MXC_IPU_V1
  73971. + ipu_csi_flash_strobe(true);
  73972. +#endif
  73973. + break;
  73974. + case V4L2_CID_MXC_SWITCH_CAM:
  73975. + if (cam->sensor == cam->all_sensors[c->value])
  73976. + break;
  73977. +
  73978. + /* power down other cameraes before enable new one */
  73979. + for (i = 0; i < cam->sensor_index; i++) {
  73980. + if (i != c->value) {
  73981. + vidioc_int_dev_exit(cam->all_sensors[i]);
  73982. + vidioc_int_s_power(cam->all_sensors[i], 0);
  73983. + if (cam->mclk_on[cam->mclk_source]) {
  73984. + ipu_csi_enable_mclk_if(cam->ipu,
  73985. + CSI_MCLK_I2C,
  73986. + cam->mclk_source,
  73987. + false, false);
  73988. + cam->mclk_on[cam->mclk_source] =
  73989. + false;
  73990. + }
  73991. + }
  73992. + }
  73993. + sensor_data = cam->all_sensors[c->value]->priv;
  73994. + if (sensor_data->io_init)
  73995. + sensor_data->io_init();
  73996. + cam->sensor = cam->all_sensors[c->value];
  73997. + cam->mclk_source = sensor_data->mclk_source;
  73998. + ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
  73999. + cam->mclk_source, true, true);
  74000. + cam->mclk_on[cam->mclk_source] = true;
  74001. + vidioc_int_s_power(cam->sensor, 1);
  74002. + vidioc_int_dev_init(cam->sensor);
  74003. + break;
  74004. + default:
  74005. + pr_debug(" default case\n");
  74006. + ret = -EINVAL;
  74007. + break;
  74008. + }
  74009. +
  74010. + return ret;
  74011. +}
  74012. +
  74013. +/*!
  74014. + * V4L2 - mxc_v4l2_s_param function
  74015. + * Allows setting of capturemode and frame rate.
  74016. + *
  74017. + * @param cam structure cam_data *
  74018. + * @param parm structure v4l2_streamparm *
  74019. + *
  74020. + * @return status 0 success, EINVAL failed
  74021. + */
  74022. +static int mxc_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
  74023. +{
  74024. + struct v4l2_ifparm ifparm;
  74025. + struct v4l2_format cam_fmt;
  74026. + struct v4l2_streamparm currentparm;
  74027. + ipu_csi_signal_cfg_t csi_param;
  74028. + u32 current_fps, parm_fps;
  74029. + int err = 0;
  74030. +
  74031. + pr_debug("In mxc_v4l2_s_param\n");
  74032. +
  74033. + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  74034. + pr_err(KERN_ERR "mxc_v4l2_s_param invalid type\n");
  74035. + return -EINVAL;
  74036. + }
  74037. +
  74038. + /* Stop the viewfinder */
  74039. + if (cam->overlay_on == true)
  74040. + stop_preview(cam);
  74041. +
  74042. + currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  74043. +
  74044. + /* First check that this device can support the changes requested. */
  74045. + err = vidioc_int_g_parm(cam->sensor, &currentparm);
  74046. + if (err) {
  74047. + pr_err("%s: vidioc_int_g_parm returned an error %d\n",
  74048. + __func__, err);
  74049. + goto exit;
  74050. + }
  74051. +
  74052. + current_fps = currentparm.parm.capture.timeperframe.denominator
  74053. + / currentparm.parm.capture.timeperframe.numerator;
  74054. + parm_fps = parm->parm.capture.timeperframe.denominator
  74055. + / parm->parm.capture.timeperframe.numerator;
  74056. +
  74057. + pr_debug(" Current capabilities are %x\n",
  74058. + currentparm.parm.capture.capability);
  74059. + pr_debug(" Current capturemode is %d change to %d\n",
  74060. + currentparm.parm.capture.capturemode,
  74061. + parm->parm.capture.capturemode);
  74062. + pr_debug(" Current framerate is %d change to %d\n",
  74063. + current_fps, parm_fps);
  74064. +
  74065. + /* This will change any camera settings needed. */
  74066. + err = vidioc_int_s_parm(cam->sensor, parm);
  74067. + if (err) {
  74068. + pr_err("%s: vidioc_int_s_parm returned an error %d\n",
  74069. + __func__, err);
  74070. + goto exit;
  74071. + }
  74072. +
  74073. + /* If resolution changed, need to re-program the CSI */
  74074. + /* Get new values. */
  74075. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  74076. +
  74077. + csi_param.data_width = 0;
  74078. + csi_param.clk_mode = 0;
  74079. + csi_param.ext_vsync = 0;
  74080. + csi_param.Vsync_pol = 0;
  74081. + csi_param.Hsync_pol = 0;
  74082. + csi_param.pixclk_pol = 0;
  74083. + csi_param.data_pol = 0;
  74084. + csi_param.sens_clksrc = 0;
  74085. + csi_param.pack_tight = 0;
  74086. + csi_param.force_eof = 0;
  74087. + csi_param.data_en_pol = 0;
  74088. + csi_param.data_fmt = 0;
  74089. + csi_param.csi = cam->csi;
  74090. + csi_param.mclk = 0;
  74091. +
  74092. + pr_debug(" clock_curr=mclk=%d\n", ifparm.u.bt656.clock_curr);
  74093. + if (ifparm.u.bt656.clock_curr == 0)
  74094. + csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_INTERLACED;
  74095. + else
  74096. + csi_param.clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;
  74097. +
  74098. + csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
  74099. +
  74100. + if (ifparm.u.bt656.mode == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT) {
  74101. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  74102. + } else if (ifparm.u.bt656.mode
  74103. + == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT) {
  74104. + csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
  74105. + } else {
  74106. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  74107. + }
  74108. +
  74109. + csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
  74110. + csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
  74111. + csi_param.ext_vsync = ifparm.u.bt656.bt_sync_correct;
  74112. +
  74113. + /* if the capturemode changed, the size bounds will have changed. */
  74114. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  74115. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  74116. + pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n",
  74117. + cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
  74118. +
  74119. + csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
  74120. +
  74121. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  74122. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  74123. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  74124. +
  74125. + /*
  74126. + * Set the default current cropped resolution to be the same with
  74127. + * the cropping boundary(except for tvin module).
  74128. + */
  74129. + if (cam->device_type != 1) {
  74130. + cam->crop_current.width = cam->crop_bounds.width;
  74131. + cam->crop_current.height = cam->crop_bounds.height;
  74132. + }
  74133. +
  74134. + /* This essentially loses the data at the left and bottom of the image
  74135. + * giving a digital zoom image, if crop_current is less than the full
  74136. + * size of the image. */
  74137. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  74138. + cam->crop_current.height, cam->csi);
  74139. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  74140. + cam->crop_current.top,
  74141. + cam->csi);
  74142. + ipu_csi_init_interface(cam->ipu, cam->crop_bounds.width,
  74143. + cam->crop_bounds.height,
  74144. + cam_fmt.fmt.pix.pixelformat, csi_param);
  74145. +
  74146. +
  74147. +exit:
  74148. + if (cam->overlay_on == true)
  74149. + start_preview(cam);
  74150. +
  74151. + return err;
  74152. +}
  74153. +
  74154. +/*!
  74155. + * V4L2 - mxc_v4l2_s_std function
  74156. + *
  74157. + * Sets the TV standard to be used.
  74158. + *
  74159. + * @param cam structure cam_data *
  74160. + * @param parm structure v4l2_streamparm *
  74161. + *
  74162. + * @return status 0 success, EINVAL failed
  74163. + */
  74164. +static int mxc_v4l2_s_std(cam_data *cam, v4l2_std_id e)
  74165. +{
  74166. + pr_debug("In mxc_v4l2_s_std %Lx\n", e);
  74167. +
  74168. + if (e == V4L2_STD_PAL) {
  74169. + pr_debug(" Setting standard to PAL %Lx\n", V4L2_STD_PAL);
  74170. + cam->standard.id = V4L2_STD_PAL;
  74171. + video_index = TV_PAL;
  74172. + } else if (e == V4L2_STD_NTSC) {
  74173. + pr_debug(" Setting standard to NTSC %Lx\n",
  74174. + V4L2_STD_NTSC);
  74175. + /* Get rid of the white dot line in NTSC signal input */
  74176. + cam->standard.id = V4L2_STD_NTSC;
  74177. + video_index = TV_NTSC;
  74178. + } else {
  74179. + cam->standard.id = V4L2_STD_ALL;
  74180. + video_index = TV_NOT_LOCKED;
  74181. + pr_err("ERROR: unrecognized std! %Lx (PAL=%Lx, NTSC=%Lx\n",
  74182. + e, V4L2_STD_PAL, V4L2_STD_NTSC);
  74183. + }
  74184. +
  74185. + cam->standard.index = video_index;
  74186. + strcpy(cam->standard.name, video_fmts[video_index].name);
  74187. + cam->crop_bounds.width = video_fmts[video_index].raw_width;
  74188. + cam->crop_bounds.height = video_fmts[video_index].raw_height;
  74189. + cam->crop_current.width = video_fmts[video_index].active_width;
  74190. + cam->crop_current.height = video_fmts[video_index].active_height;
  74191. + cam->crop_current.top = video_fmts[video_index].active_top;
  74192. + cam->crop_current.left = video_fmts[video_index].active_left;
  74193. +
  74194. + return 0;
  74195. +}
  74196. +
  74197. +/*!
  74198. + * V4L2 - mxc_v4l2_g_std function
  74199. + *
  74200. + * Gets the TV standard from the TV input device.
  74201. + *
  74202. + * @param cam structure cam_data *
  74203. + *
  74204. + * @param e structure v4l2_streamparm *
  74205. + *
  74206. + * @return status 0 success, EINVAL failed
  74207. + */
  74208. +static int mxc_v4l2_g_std(cam_data *cam, v4l2_std_id *e)
  74209. +{
  74210. + struct v4l2_format tv_fmt;
  74211. +
  74212. + pr_debug("In mxc_v4l2_g_std\n");
  74213. +
  74214. + if (cam->device_type == 1) {
  74215. + /* Use this function to get what the TV-In device detects the
  74216. + * format to be. pixelformat is used to return the std value
  74217. + * since the interface has no vidioc_g_std.*/
  74218. + tv_fmt.type = V4L2_BUF_TYPE_PRIVATE;
  74219. + vidioc_int_g_fmt_cap(cam->sensor, &tv_fmt);
  74220. +
  74221. + /* If the TV-in automatically detects the standard, then if it
  74222. + * changes, the settings need to change. */
  74223. + if (cam->standard_autodetect) {
  74224. + if (cam->standard.id != tv_fmt.fmt.pix.pixelformat) {
  74225. + pr_debug("MVC: mxc_v4l2_g_std: "
  74226. + "Changing standard\n");
  74227. + mxc_v4l2_s_std(cam, tv_fmt.fmt.pix.pixelformat);
  74228. + }
  74229. + }
  74230. +
  74231. + *e = tv_fmt.fmt.pix.pixelformat;
  74232. + }
  74233. +
  74234. + return 0;
  74235. +}
  74236. +
  74237. +/*!
  74238. + * Dequeue one V4L capture buffer
  74239. + *
  74240. + * @param cam structure cam_data *
  74241. + * @param buf structure v4l2_buffer *
  74242. + *
  74243. + * @return status 0 success, EINVAL invalid frame number,
  74244. + * ETIME timeout, ERESTARTSYS interrupted by user
  74245. + */
  74246. +static int mxc_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
  74247. +{
  74248. + int retval = 0;
  74249. + struct mxc_v4l_frame *frame;
  74250. + unsigned long lock_flags;
  74251. +
  74252. + pr_debug("In MVC:mxc_v4l_dqueue\n");
  74253. +
  74254. + if (!wait_event_interruptible_timeout(cam->enc_queue,
  74255. + cam->enc_counter != 0, 10 * HZ)) {
  74256. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout "
  74257. + "enc_counter %x\n",
  74258. + cam->enc_counter);
  74259. + return -ETIME;
  74260. + } else if (signal_pending(current)) {
  74261. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() "
  74262. + "interrupt received\n");
  74263. + return -ERESTARTSYS;
  74264. + }
  74265. +
  74266. + if (down_interruptible(&cam->busy_lock))
  74267. + return -EBUSY;
  74268. +
  74269. + spin_lock_irqsave(&cam->dqueue_int_lock, lock_flags);
  74270. + cam->enc_counter--;
  74271. +
  74272. + frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue);
  74273. + list_del(cam->done_q.next);
  74274. + if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) {
  74275. + frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE;
  74276. + } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  74277. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  74278. + "Buffer not filled.\n");
  74279. + frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  74280. + retval = -EINVAL;
  74281. + } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) {
  74282. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  74283. + "Buffer not queued.\n");
  74284. + retval = -EINVAL;
  74285. + }
  74286. +
  74287. + cam->frame[frame->index].buffer.field = cam->device_type ?
  74288. + V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
  74289. +
  74290. + buf->bytesused = cam->v2f.fmt.pix.sizeimage;
  74291. + buf->index = frame->index;
  74292. + buf->flags = frame->buffer.flags;
  74293. + buf->m = cam->frame[frame->index].buffer.m;
  74294. + buf->timestamp = cam->frame[frame->index].buffer.timestamp;
  74295. + buf->field = cam->frame[frame->index].buffer.field;
  74296. + spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
  74297. +
  74298. + up(&cam->busy_lock);
  74299. + return retval;
  74300. +}
  74301. +
  74302. +/*!
  74303. + * V4L interface - open function
  74304. + *
  74305. + * @param file structure file *
  74306. + *
  74307. + * @return status 0 success, ENODEV invalid device instance,
  74308. + * ENODEV timeout, ERESTARTSYS interrupted by user
  74309. + */
  74310. +static int mxc_v4l_open(struct file *file)
  74311. +{
  74312. + struct v4l2_ifparm ifparm;
  74313. + struct v4l2_format cam_fmt;
  74314. + ipu_csi_signal_cfg_t csi_param;
  74315. + struct video_device *dev = video_devdata(file);
  74316. + cam_data *cam = video_get_drvdata(dev);
  74317. + int err = 0;
  74318. + struct sensor_data *sensor;
  74319. +
  74320. + pr_debug("\nIn MVC: mxc_v4l_open\n");
  74321. + pr_debug(" device name is %s\n", dev->name);
  74322. +
  74323. + if (!cam) {
  74324. + pr_err("ERROR: v4l2 capture: Internal error, "
  74325. + "cam_data not found!\n");
  74326. + return -EBADF;
  74327. + }
  74328. +
  74329. + if (cam->sensor == NULL ||
  74330. + cam->sensor->type != v4l2_int_type_slave) {
  74331. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  74332. + return -EAGAIN;
  74333. + }
  74334. +
  74335. + sensor = cam->sensor->priv;
  74336. + if (!sensor) {
  74337. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  74338. + return -EBADF;
  74339. + }
  74340. +
  74341. + down(&cam->busy_lock);
  74342. + err = 0;
  74343. + if (signal_pending(current))
  74344. + goto oops;
  74345. +
  74346. + if (cam->open_count++ == 0) {
  74347. + wait_event_interruptible(cam->power_queue,
  74348. + cam->low_power == false);
  74349. +
  74350. + if (strcmp(mxc_capture_inputs[cam->current_input].name,
  74351. + "CSI MEM") == 0) {
  74352. +#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  74353. + err = csi_enc_select(cam);
  74354. +#endif
  74355. + } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
  74356. + "CSI IC MEM") == 0) {
  74357. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
  74358. + err = prp_enc_select(cam);
  74359. +#endif
  74360. + }
  74361. +
  74362. + cam->enc_counter = 0;
  74363. + INIT_LIST_HEAD(&cam->ready_q);
  74364. + INIT_LIST_HEAD(&cam->working_q);
  74365. + INIT_LIST_HEAD(&cam->done_q);
  74366. +
  74367. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  74368. +
  74369. + csi_param.sens_clksrc = 0;
  74370. +
  74371. + csi_param.clk_mode = 0;
  74372. + csi_param.data_pol = 0;
  74373. + csi_param.ext_vsync = 0;
  74374. +
  74375. + csi_param.pack_tight = 0;
  74376. + csi_param.force_eof = 0;
  74377. + csi_param.data_en_pol = 0;
  74378. +
  74379. + csi_param.mclk = ifparm.u.bt656.clock_curr;
  74380. +
  74381. + csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
  74382. +
  74383. + if (ifparm.u.bt656.mode
  74384. + == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT)
  74385. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  74386. + else if (ifparm.u.bt656.mode
  74387. + == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT)
  74388. + csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
  74389. + else
  74390. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  74391. +
  74392. +
  74393. + csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
  74394. + csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
  74395. +
  74396. + csi_param.csi = cam->csi;
  74397. +
  74398. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  74399. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  74400. +
  74401. + /* Reset the sizes. Needed to prevent carryover of last
  74402. + * operation.*/
  74403. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  74404. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  74405. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  74406. +
  74407. + /* This also is the max crop size for this device. */
  74408. + cam->crop_defrect.top = cam->crop_defrect.left = 0;
  74409. + cam->crop_defrect.width = cam_fmt.fmt.pix.width;
  74410. + cam->crop_defrect.height = cam_fmt.fmt.pix.height;
  74411. +
  74412. + /* At this point, this is also the current image size. */
  74413. + cam->crop_current.top = cam->crop_current.left = 0;
  74414. + cam->crop_current.width = cam_fmt.fmt.pix.width;
  74415. + cam->crop_current.height = cam_fmt.fmt.pix.height;
  74416. +
  74417. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  74418. + __func__,
  74419. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  74420. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  74421. + __func__,
  74422. + cam->crop_bounds.width, cam->crop_bounds.height);
  74423. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  74424. + __func__,
  74425. + cam->crop_defrect.width, cam->crop_defrect.height);
  74426. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  74427. + __func__,
  74428. + cam->crop_current.width, cam->crop_current.height);
  74429. +
  74430. + csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
  74431. + pr_debug("On Open: Input to ipu size is %d x %d\n",
  74432. + cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
  74433. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  74434. + cam->crop_current.height,
  74435. + cam->csi);
  74436. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  74437. + cam->crop_current.top,
  74438. + cam->csi);
  74439. + ipu_csi_init_interface(cam->ipu, cam->crop_bounds.width,
  74440. + cam->crop_bounds.height,
  74441. + cam_fmt.fmt.pix.pixelformat,
  74442. + csi_param);
  74443. + clk_prepare_enable(sensor->sensor_clk);
  74444. + vidioc_int_s_power(cam->sensor, 1);
  74445. + vidioc_int_init(cam->sensor);
  74446. + vidioc_int_dev_init(cam->sensor);
  74447. + }
  74448. +
  74449. + file->private_data = dev;
  74450. +
  74451. +oops:
  74452. + up(&cam->busy_lock);
  74453. + return err;
  74454. +}
  74455. +
  74456. +/*!
  74457. + * V4L interface - close function
  74458. + *
  74459. + * @param file struct file *
  74460. + *
  74461. + * @return 0 success
  74462. + */
  74463. +static int mxc_v4l_close(struct file *file)
  74464. +{
  74465. + struct video_device *dev = video_devdata(file);
  74466. + int err = 0;
  74467. + cam_data *cam = video_get_drvdata(dev);
  74468. + struct sensor_data *sensor;
  74469. + pr_debug("In MVC:mxc_v4l_close\n");
  74470. +
  74471. + if (!cam) {
  74472. + pr_err("ERROR: v4l2 capture: Internal error, "
  74473. + "cam_data not found!\n");
  74474. + return -EBADF;
  74475. + }
  74476. +
  74477. + if (!cam->sensor) {
  74478. + pr_err("%s: Internal error, camera is not found!\n", __func__);
  74479. + return -EBADF;
  74480. + }
  74481. +
  74482. + sensor = cam->sensor->priv;
  74483. + if (!sensor) {
  74484. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  74485. + return -EBADF;
  74486. + }
  74487. +
  74488. + down(&cam->busy_lock);
  74489. +
  74490. + /* for the case somebody hit the ctrl C */
  74491. + if (cam->overlay_pid == current->pid && cam->overlay_on) {
  74492. + err = stop_preview(cam);
  74493. + cam->overlay_on = false;
  74494. + }
  74495. + if (cam->capture_pid == current->pid) {
  74496. + err |= mxc_streamoff(cam);
  74497. + wake_up_interruptible(&cam->enc_queue);
  74498. + }
  74499. +
  74500. + if (--cam->open_count == 0) {
  74501. + vidioc_int_s_power(cam->sensor, 0);
  74502. + clk_disable_unprepare(sensor->sensor_clk);
  74503. + wait_event_interruptible(cam->power_queue,
  74504. + cam->low_power == false);
  74505. + pr_debug("mxc_v4l_close: release resource\n");
  74506. +
  74507. + if (strcmp(mxc_capture_inputs[cam->current_input].name,
  74508. + "CSI MEM") == 0) {
  74509. +#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  74510. + err |= csi_enc_deselect(cam);
  74511. +#endif
  74512. + } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
  74513. + "CSI IC MEM") == 0) {
  74514. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
  74515. + err |= prp_enc_deselect(cam);
  74516. +#endif
  74517. + }
  74518. +
  74519. + mxc_free_frame_buf(cam);
  74520. + file->private_data = NULL;
  74521. +
  74522. + /* capture off */
  74523. + wake_up_interruptible(&cam->enc_queue);
  74524. + mxc_free_frames(cam);
  74525. + cam->enc_counter++;
  74526. + }
  74527. +
  74528. + up(&cam->busy_lock);
  74529. +
  74530. + return err;
  74531. +}
  74532. +
  74533. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC) || \
  74534. + defined(CONFIG_MXC_IPU_PRP_ENC_MODULE) || \
  74535. + defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  74536. +/*
  74537. + * V4L interface - read function
  74538. + *
  74539. + * @param file struct file *
  74540. + * @param read buf char *
  74541. + * @param count size_t
  74542. + * @param ppos structure loff_t *
  74543. + *
  74544. + * @return bytes read
  74545. + */
  74546. +static ssize_t mxc_v4l_read(struct file *file, char *buf, size_t count,
  74547. + loff_t *ppos)
  74548. +{
  74549. + int err = 0;
  74550. + u8 *v_address[2];
  74551. + struct video_device *dev = video_devdata(file);
  74552. + cam_data *cam = video_get_drvdata(dev);
  74553. +
  74554. + if (down_interruptible(&cam->busy_lock))
  74555. + return -EINTR;
  74556. +
  74557. + /* Stop the viewfinder */
  74558. + if (cam->overlay_on == true)
  74559. + stop_preview(cam);
  74560. +
  74561. + v_address[0] = dma_alloc_coherent(0,
  74562. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  74563. + &cam->still_buf[0],
  74564. + GFP_DMA | GFP_KERNEL);
  74565. +
  74566. + v_address[1] = dma_alloc_coherent(0,
  74567. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  74568. + &cam->still_buf[1],
  74569. + GFP_DMA | GFP_KERNEL);
  74570. +
  74571. + if (!v_address[0] || !v_address[1]) {
  74572. + err = -ENOBUFS;
  74573. + goto exit0;
  74574. + }
  74575. +
  74576. + err = prp_still_select(cam);
  74577. + if (err != 0) {
  74578. + err = -EIO;
  74579. + goto exit0;
  74580. + }
  74581. +
  74582. + cam->still_counter = 0;
  74583. + err = cam->csi_start(cam);
  74584. + if (err != 0) {
  74585. + err = -EIO;
  74586. + goto exit1;
  74587. + }
  74588. +
  74589. + if (!wait_event_interruptible_timeout(cam->still_queue,
  74590. + cam->still_counter != 0,
  74591. + 10 * HZ)) {
  74592. + pr_err("ERROR: v4l2 capture: mxc_v4l_read timeout counter %x\n",
  74593. + cam->still_counter);
  74594. + err = -ETIME;
  74595. + goto exit1;
  74596. + }
  74597. + err = copy_to_user(buf, v_address[1], cam->v2f.fmt.pix.sizeimage);
  74598. +
  74599. +exit1:
  74600. + prp_still_deselect(cam);
  74601. +
  74602. +exit0:
  74603. + if (v_address[0] != 0)
  74604. + dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[0],
  74605. + cam->still_buf[0]);
  74606. + if (v_address[1] != 0)
  74607. + dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[1],
  74608. + cam->still_buf[1]);
  74609. +
  74610. + cam->still_buf[0] = cam->still_buf[1] = 0;
  74611. +
  74612. + if (cam->overlay_on == true)
  74613. + start_preview(cam);
  74614. +
  74615. + up(&cam->busy_lock);
  74616. + if (err < 0)
  74617. + return err;
  74618. +
  74619. + return cam->v2f.fmt.pix.sizeimage - err;
  74620. +}
  74621. +#endif
  74622. +
  74623. +/*!
  74624. + * V4L interface - ioctl function
  74625. + *
  74626. + * @param file struct file*
  74627. + *
  74628. + * @param ioctlnr unsigned int
  74629. + *
  74630. + * @param arg void*
  74631. + *
  74632. + * @return 0 success, ENODEV for invalid device instance,
  74633. + * -1 for other errors.
  74634. + */
  74635. +static long mxc_v4l_do_ioctl(struct file *file,
  74636. + unsigned int ioctlnr, void *arg)
  74637. +{
  74638. + struct video_device *dev = video_devdata(file);
  74639. + cam_data *cam = video_get_drvdata(dev);
  74640. + int retval = 0;
  74641. + unsigned long lock_flags;
  74642. +
  74643. + pr_debug("In MVC: mxc_v4l_do_ioctl %x\n", ioctlnr);
  74644. + wait_event_interruptible(cam->power_queue, cam->low_power == false);
  74645. + /* make this _really_ smp-safe */
  74646. + if (ioctlnr != VIDIOC_DQBUF)
  74647. + if (down_interruptible(&cam->busy_lock))
  74648. + return -EBUSY;
  74649. +
  74650. + switch (ioctlnr) {
  74651. + /*!
  74652. + * V4l2 VIDIOC_QUERYCAP ioctl
  74653. + */
  74654. + case VIDIOC_QUERYCAP: {
  74655. + struct v4l2_capability *cap = arg;
  74656. + pr_debug(" case VIDIOC_QUERYCAP\n");
  74657. + strcpy(cap->driver, "mxc_v4l2");
  74658. + cap->version = KERNEL_VERSION(0, 1, 11);
  74659. + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
  74660. + V4L2_CAP_VIDEO_OVERLAY |
  74661. + V4L2_CAP_STREAMING |
  74662. + V4L2_CAP_READWRITE;
  74663. + cap->card[0] = '\0';
  74664. + cap->bus_info[0] = '\0';
  74665. + break;
  74666. + }
  74667. +
  74668. + /*!
  74669. + * V4l2 VIDIOC_G_FMT ioctl
  74670. + */
  74671. + case VIDIOC_G_FMT: {
  74672. + struct v4l2_format *gf = arg;
  74673. + pr_debug(" case VIDIOC_G_FMT\n");
  74674. + retval = mxc_v4l2_g_fmt(cam, gf);
  74675. + break;
  74676. + }
  74677. +
  74678. + /*!
  74679. + * V4l2 VIDIOC_S_FMT ioctl
  74680. + */
  74681. + case VIDIOC_S_FMT: {
  74682. + struct v4l2_format *sf = arg;
  74683. + pr_debug(" case VIDIOC_S_FMT\n");
  74684. + retval = mxc_v4l2_s_fmt(cam, sf);
  74685. + break;
  74686. + }
  74687. +
  74688. + /*!
  74689. + * V4l2 VIDIOC_REQBUFS ioctl
  74690. + */
  74691. + case VIDIOC_REQBUFS: {
  74692. + struct v4l2_requestbuffers *req = arg;
  74693. + pr_debug(" case VIDIOC_REQBUFS\n");
  74694. +
  74695. + if (req->count > FRAME_NUM) {
  74696. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  74697. + "not enough buffers\n");
  74698. + req->count = FRAME_NUM;
  74699. + }
  74700. +
  74701. + if ((req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
  74702. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  74703. + "wrong buffer type\n");
  74704. + retval = -EINVAL;
  74705. + break;
  74706. + }
  74707. +
  74708. + mxc_streamoff(cam);
  74709. + if (req->memory & V4L2_MEMORY_MMAP) {
  74710. + mxc_free_frame_buf(cam);
  74711. + retval = mxc_allocate_frame_buf(cam, req->count);
  74712. + }
  74713. + break;
  74714. + }
  74715. +
  74716. + /*!
  74717. + * V4l2 VIDIOC_QUERYBUF ioctl
  74718. + */
  74719. + case VIDIOC_QUERYBUF: {
  74720. + struct v4l2_buffer *buf = arg;
  74721. + int index = buf->index;
  74722. + pr_debug(" case VIDIOC_QUERYBUF\n");
  74723. +
  74724. + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  74725. + pr_err("ERROR: v4l2 capture: "
  74726. + "VIDIOC_QUERYBUFS: "
  74727. + "wrong buffer type\n");
  74728. + retval = -EINVAL;
  74729. + break;
  74730. + }
  74731. +
  74732. + if (buf->memory & V4L2_MEMORY_MMAP) {
  74733. + memset(buf, 0, sizeof(buf));
  74734. + buf->index = index;
  74735. + }
  74736. +
  74737. + down(&cam->param_lock);
  74738. + if (buf->memory & V4L2_MEMORY_USERPTR) {
  74739. + mxc_v4l2_release_bufs(cam);
  74740. + retval = mxc_v4l2_prepare_bufs(cam, buf);
  74741. + }
  74742. +
  74743. + if (buf->memory & V4L2_MEMORY_MMAP)
  74744. + retval = mxc_v4l2_buffer_status(cam, buf);
  74745. + up(&cam->param_lock);
  74746. + break;
  74747. + }
  74748. +
  74749. + /*!
  74750. + * V4l2 VIDIOC_QBUF ioctl
  74751. + */
  74752. + case VIDIOC_QBUF: {
  74753. + struct v4l2_buffer *buf = arg;
  74754. + int index = buf->index;
  74755. + pr_debug(" case VIDIOC_QBUF\n");
  74756. +
  74757. + spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
  74758. + if ((cam->frame[index].buffer.flags & 0x7) ==
  74759. + V4L2_BUF_FLAG_MAPPED) {
  74760. + cam->frame[index].buffer.flags |=
  74761. + V4L2_BUF_FLAG_QUEUED;
  74762. + list_add_tail(&cam->frame[index].queue,
  74763. + &cam->ready_q);
  74764. + } else if (cam->frame[index].buffer.
  74765. + flags & V4L2_BUF_FLAG_QUEUED) {
  74766. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  74767. + "buffer already queued\n");
  74768. + retval = -EINVAL;
  74769. + } else if (cam->frame[index].buffer.
  74770. + flags & V4L2_BUF_FLAG_DONE) {
  74771. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  74772. + "overwrite done buffer.\n");
  74773. + cam->frame[index].buffer.flags &=
  74774. + ~V4L2_BUF_FLAG_DONE;
  74775. + cam->frame[index].buffer.flags |=
  74776. + V4L2_BUF_FLAG_QUEUED;
  74777. + retval = -EINVAL;
  74778. + }
  74779. +
  74780. + buf->flags = cam->frame[index].buffer.flags;
  74781. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  74782. + break;
  74783. + }
  74784. +
  74785. + /*!
  74786. + * V4l2 VIDIOC_DQBUF ioctl
  74787. + */
  74788. + case VIDIOC_DQBUF: {
  74789. + struct v4l2_buffer *buf = arg;
  74790. + pr_debug(" case VIDIOC_DQBUF\n");
  74791. +
  74792. + if ((cam->enc_counter == 0) &&
  74793. + (file->f_flags & O_NONBLOCK)) {
  74794. + retval = -EAGAIN;
  74795. + break;
  74796. + }
  74797. +
  74798. + retval = mxc_v4l_dqueue(cam, buf);
  74799. + break;
  74800. + }
  74801. +
  74802. + /*!
  74803. + * V4l2 VIDIOC_STREAMON ioctl
  74804. + */
  74805. + case VIDIOC_STREAMON: {
  74806. + pr_debug(" case VIDIOC_STREAMON\n");
  74807. + retval = mxc_streamon(cam);
  74808. + break;
  74809. + }
  74810. +
  74811. + /*!
  74812. + * V4l2 VIDIOC_STREAMOFF ioctl
  74813. + */
  74814. + case VIDIOC_STREAMOFF: {
  74815. + pr_debug(" case VIDIOC_STREAMOFF\n");
  74816. + retval = mxc_streamoff(cam);
  74817. + break;
  74818. + }
  74819. +
  74820. + /*!
  74821. + * V4l2 VIDIOC_G_CTRL ioctl
  74822. + */
  74823. + case VIDIOC_G_CTRL: {
  74824. + pr_debug(" case VIDIOC_G_CTRL\n");
  74825. + retval = mxc_v4l2_g_ctrl(cam, arg);
  74826. + break;
  74827. + }
  74828. +
  74829. + /*!
  74830. + * V4l2 VIDIOC_S_CTRL ioctl
  74831. + */
  74832. + case VIDIOC_S_CTRL: {
  74833. + pr_debug(" case VIDIOC_S_CTRL\n");
  74834. + retval = mxc_v4l2_s_ctrl(cam, arg);
  74835. + break;
  74836. + }
  74837. +
  74838. + /*!
  74839. + * V4l2 VIDIOC_CROPCAP ioctl
  74840. + */
  74841. + case VIDIOC_CROPCAP: {
  74842. + struct v4l2_cropcap *cap = arg;
  74843. + pr_debug(" case VIDIOC_CROPCAP\n");
  74844. + if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  74845. + cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  74846. + retval = -EINVAL;
  74847. + break;
  74848. + }
  74849. + cap->bounds = cam->crop_bounds;
  74850. + cap->defrect = cam->crop_defrect;
  74851. + break;
  74852. + }
  74853. +
  74854. + /*!
  74855. + * V4l2 VIDIOC_G_CROP ioctl
  74856. + */
  74857. + case VIDIOC_G_CROP: {
  74858. + struct v4l2_crop *crop = arg;
  74859. + pr_debug(" case VIDIOC_G_CROP\n");
  74860. +
  74861. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  74862. + crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  74863. + retval = -EINVAL;
  74864. + break;
  74865. + }
  74866. + crop->c = cam->crop_current;
  74867. + break;
  74868. + }
  74869. +
  74870. + /*!
  74871. + * V4l2 VIDIOC_S_CROP ioctl
  74872. + */
  74873. + case VIDIOC_S_CROP: {
  74874. + struct v4l2_crop *crop = arg;
  74875. + struct v4l2_rect *b = &cam->crop_bounds;
  74876. + pr_debug(" case VIDIOC_S_CROP\n");
  74877. +
  74878. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  74879. + crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  74880. + retval = -EINVAL;
  74881. + break;
  74882. + }
  74883. +
  74884. + crop->c.top = (crop->c.top < b->top) ? b->top
  74885. + : crop->c.top;
  74886. + if (crop->c.top > b->top + b->height)
  74887. + crop->c.top = b->top + b->height - 1;
  74888. + if (crop->c.height > b->top + b->height - crop->c.top)
  74889. + crop->c.height =
  74890. + b->top + b->height - crop->c.top;
  74891. +
  74892. + crop->c.left = (crop->c.left < b->left) ? b->left
  74893. + : crop->c.left;
  74894. + if (crop->c.left > b->left + b->width)
  74895. + crop->c.left = b->left + b->width - 1;
  74896. + if (crop->c.width > b->left - crop->c.left + b->width)
  74897. + crop->c.width =
  74898. + b->left - crop->c.left + b->width;
  74899. +
  74900. + crop->c.width -= crop->c.width % 8;
  74901. + crop->c.left -= crop->c.left % 4;
  74902. + cam->crop_current = crop->c;
  74903. +
  74904. + pr_debug(" Cropping Input to ipu size %d x %d\n",
  74905. + cam->crop_current.width,
  74906. + cam->crop_current.height);
  74907. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  74908. + cam->crop_current.height,
  74909. + cam->csi);
  74910. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  74911. + cam->crop_current.top,
  74912. + cam->csi);
  74913. + break;
  74914. + }
  74915. +
  74916. + /*!
  74917. + * V4l2 VIDIOC_OVERLAY ioctl
  74918. + */
  74919. + case VIDIOC_OVERLAY: {
  74920. + int *on = arg;
  74921. + pr_debug(" VIDIOC_OVERLAY on=%d\n", *on);
  74922. + if (*on) {
  74923. + cam->overlay_on = true;
  74924. + cam->overlay_pid = current->pid;
  74925. + retval = start_preview(cam);
  74926. + }
  74927. + if (!*on) {
  74928. + retval = stop_preview(cam);
  74929. + cam->overlay_on = false;
  74930. + }
  74931. + break;
  74932. + }
  74933. +
  74934. + /*!
  74935. + * V4l2 VIDIOC_G_FBUF ioctl
  74936. + */
  74937. + case VIDIOC_G_FBUF: {
  74938. + struct v4l2_framebuffer *fb = arg;
  74939. + pr_debug(" case VIDIOC_G_FBUF\n");
  74940. + *fb = cam->v4l2_fb;
  74941. + fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
  74942. + break;
  74943. + }
  74944. +
  74945. + /*!
  74946. + * V4l2 VIDIOC_S_FBUF ioctl
  74947. + */
  74948. + case VIDIOC_S_FBUF: {
  74949. + struct v4l2_framebuffer *fb = arg;
  74950. + pr_debug(" case VIDIOC_S_FBUF\n");
  74951. + cam->v4l2_fb = *fb;
  74952. + break;
  74953. + }
  74954. +
  74955. + case VIDIOC_G_PARM: {
  74956. + struct v4l2_streamparm *parm = arg;
  74957. + pr_debug(" case VIDIOC_G_PARM\n");
  74958. + if (cam->sensor)
  74959. + retval = vidioc_int_g_parm(cam->sensor, parm);
  74960. + else {
  74961. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  74962. + retval = -ENODEV;
  74963. + }
  74964. + break;
  74965. + }
  74966. +
  74967. + case VIDIOC_S_PARM: {
  74968. + struct v4l2_streamparm *parm = arg;
  74969. + pr_debug(" case VIDIOC_S_PARM\n");
  74970. + if (cam->sensor)
  74971. + retval = mxc_v4l2_s_param(cam, parm);
  74972. + else {
  74973. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  74974. + retval = -ENODEV;
  74975. + }
  74976. + break;
  74977. + }
  74978. +
  74979. + /* linux v4l2 bug, kernel c0485619 user c0405619 */
  74980. + case VIDIOC_ENUMSTD: {
  74981. + struct v4l2_standard *e = arg;
  74982. + pr_debug(" case VIDIOC_ENUMSTD\n");
  74983. + *e = cam->standard;
  74984. + break;
  74985. + }
  74986. +
  74987. + case VIDIOC_G_STD: {
  74988. + v4l2_std_id *e = arg;
  74989. + pr_debug(" case VIDIOC_G_STD\n");
  74990. + if (cam->sensor)
  74991. + retval = mxc_v4l2_g_std(cam, e);
  74992. + else {
  74993. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  74994. + retval = -ENODEV;
  74995. + }
  74996. + break;
  74997. + }
  74998. +
  74999. + case VIDIOC_S_STD: {
  75000. + v4l2_std_id *e = arg;
  75001. + pr_debug(" case VIDIOC_S_STD\n");
  75002. + retval = mxc_v4l2_s_std(cam, *e);
  75003. +
  75004. + break;
  75005. + }
  75006. +
  75007. + case VIDIOC_ENUMOUTPUT: {
  75008. + struct v4l2_output *output = arg;
  75009. + pr_debug(" case VIDIOC_ENUMOUTPUT\n");
  75010. + if (output->index >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
  75011. + retval = -EINVAL;
  75012. + break;
  75013. + }
  75014. + *output = mxc_capture_outputs[output->index];
  75015. +
  75016. + break;
  75017. + }
  75018. + case VIDIOC_G_OUTPUT: {
  75019. + int *p_output_num = arg;
  75020. + pr_debug(" case VIDIOC_G_OUTPUT\n");
  75021. + *p_output_num = cam->output;
  75022. + break;
  75023. + }
  75024. +
  75025. + case VIDIOC_S_OUTPUT: {
  75026. + int *p_output_num = arg;
  75027. + pr_debug(" case VIDIOC_S_OUTPUT\n");
  75028. + if (*p_output_num >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
  75029. + retval = -EINVAL;
  75030. + break;
  75031. + }
  75032. + cam->output = *p_output_num;
  75033. + break;
  75034. + }
  75035. +
  75036. + case VIDIOC_ENUMINPUT: {
  75037. + struct v4l2_input *input = arg;
  75038. + pr_debug(" case VIDIOC_ENUMINPUT\n");
  75039. + if (input->index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
  75040. + retval = -EINVAL;
  75041. + break;
  75042. + }
  75043. + *input = mxc_capture_inputs[input->index];
  75044. + break;
  75045. + }
  75046. +
  75047. + case VIDIOC_G_INPUT: {
  75048. + int *index = arg;
  75049. + pr_debug(" case VIDIOC_G_INPUT\n");
  75050. + *index = cam->current_input;
  75051. + break;
  75052. + }
  75053. +
  75054. + case VIDIOC_S_INPUT: {
  75055. + int *index = arg;
  75056. + pr_debug(" case VIDIOC_S_INPUT\n");
  75057. + if (*index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
  75058. + retval = -EINVAL;
  75059. + break;
  75060. + }
  75061. +
  75062. + if (*index == cam->current_input)
  75063. + break;
  75064. +
  75065. + if ((mxc_capture_inputs[cam->current_input].status &
  75066. + V4L2_IN_ST_NO_POWER) == 0) {
  75067. + retval = mxc_streamoff(cam);
  75068. + if (retval)
  75069. + break;
  75070. + mxc_capture_inputs[cam->current_input].status |=
  75071. + V4L2_IN_ST_NO_POWER;
  75072. + }
  75073. +
  75074. + if (strcmp(mxc_capture_inputs[*index].name, "CSI MEM") == 0) {
  75075. +#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  75076. + retval = csi_enc_select(cam);
  75077. + if (retval)
  75078. + break;
  75079. +#endif
  75080. + } else if (strcmp(mxc_capture_inputs[*index].name,
  75081. + "CSI IC MEM") == 0) {
  75082. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
  75083. + retval = prp_enc_select(cam);
  75084. + if (retval)
  75085. + break;
  75086. +#endif
  75087. + }
  75088. +
  75089. + mxc_capture_inputs[*index].status &= ~V4L2_IN_ST_NO_POWER;
  75090. + cam->current_input = *index;
  75091. + break;
  75092. + }
  75093. + case VIDIOC_ENUM_FMT: {
  75094. + struct v4l2_fmtdesc *f = arg;
  75095. + if (cam->sensor)
  75096. + retval = vidioc_int_enum_fmt_cap(cam->sensor, f);
  75097. + else {
  75098. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  75099. + retval = -ENODEV;
  75100. + }
  75101. + break;
  75102. + }
  75103. + case VIDIOC_ENUM_FRAMESIZES: {
  75104. + struct v4l2_frmsizeenum *fsize = arg;
  75105. + if (cam->sensor)
  75106. + retval = vidioc_int_enum_framesizes(cam->sensor, fsize);
  75107. + else {
  75108. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  75109. + retval = -ENODEV;
  75110. + }
  75111. + break;
  75112. + }
  75113. + case VIDIOC_DBG_G_CHIP_IDENT: {
  75114. + struct v4l2_dbg_chip_ident *p = arg;
  75115. + p->ident = V4L2_IDENT_NONE;
  75116. + p->revision = 0;
  75117. + if (cam->sensor)
  75118. + retval = vidioc_int_g_chip_ident(cam->sensor, (int *)p);
  75119. + else {
  75120. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  75121. + retval = -ENODEV;
  75122. + }
  75123. + break;
  75124. + }
  75125. + case VIDIOC_TRY_FMT:
  75126. + case VIDIOC_QUERYCTRL:
  75127. + case VIDIOC_G_TUNER:
  75128. + case VIDIOC_S_TUNER:
  75129. + case VIDIOC_G_FREQUENCY:
  75130. + case VIDIOC_S_FREQUENCY:
  75131. + default:
  75132. + pr_debug(" case default or not supported\n");
  75133. + retval = -EINVAL;
  75134. + break;
  75135. + }
  75136. +
  75137. + if (ioctlnr != VIDIOC_DQBUF)
  75138. + up(&cam->busy_lock);
  75139. + return retval;
  75140. +}
  75141. +
  75142. +/*
  75143. + * V4L interface - ioctl function
  75144. + *
  75145. + * @return None
  75146. + */
  75147. +static long mxc_v4l_ioctl(struct file *file, unsigned int cmd,
  75148. + unsigned long arg)
  75149. +{
  75150. + pr_debug("In MVC:mxc_v4l_ioctl\n");
  75151. + return video_usercopy(file, cmd, arg, mxc_v4l_do_ioctl);
  75152. +}
  75153. +
  75154. +/*!
  75155. + * V4L interface - mmap function
  75156. + *
  75157. + * @param file structure file *
  75158. + *
  75159. + * @param vma structure vm_area_struct *
  75160. + *
  75161. + * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error
  75162. + */
  75163. +static int mxc_mmap(struct file *file, struct vm_area_struct *vma)
  75164. +{
  75165. + struct video_device *dev = video_devdata(file);
  75166. + unsigned long size;
  75167. + int res = 0;
  75168. + cam_data *cam = video_get_drvdata(dev);
  75169. +
  75170. + pr_debug("In MVC:mxc_mmap\n");
  75171. + pr_debug(" pgoff=0x%lx, start=0x%lx, end=0x%lx\n",
  75172. + vma->vm_pgoff, vma->vm_start, vma->vm_end);
  75173. +
  75174. + /* make this _really_ smp-safe */
  75175. + if (down_interruptible(&cam->busy_lock))
  75176. + return -EINTR;
  75177. +
  75178. + size = vma->vm_end - vma->vm_start;
  75179. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  75180. +
  75181. + if (remap_pfn_range(vma, vma->vm_start,
  75182. + vma->vm_pgoff, size, vma->vm_page_prot)) {
  75183. + pr_err("ERROR: v4l2 capture: mxc_mmap: "
  75184. + "remap_pfn_range failed\n");
  75185. + res = -ENOBUFS;
  75186. + goto mxc_mmap_exit;
  75187. + }
  75188. +
  75189. + vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
  75190. +
  75191. +mxc_mmap_exit:
  75192. + up(&cam->busy_lock);
  75193. + return res;
  75194. +}
  75195. +
  75196. +/*!
  75197. + * V4L interface - poll function
  75198. + *
  75199. + * @param file structure file *
  75200. + *
  75201. + * @param wait structure poll_table_struct *
  75202. + *
  75203. + * @return status POLLIN | POLLRDNORM
  75204. + */
  75205. +static unsigned int mxc_poll(struct file *file, struct poll_table_struct *wait)
  75206. +{
  75207. + struct video_device *dev = video_devdata(file);
  75208. + cam_data *cam = video_get_drvdata(dev);
  75209. + wait_queue_head_t *queue = NULL;
  75210. + int res = POLLIN | POLLRDNORM;
  75211. +
  75212. + pr_debug("In MVC:mxc_poll\n");
  75213. +
  75214. + if (down_interruptible(&cam->busy_lock))
  75215. + return -EINTR;
  75216. +
  75217. + queue = &cam->enc_queue;
  75218. + poll_wait(file, queue, wait);
  75219. +
  75220. + up(&cam->busy_lock);
  75221. +
  75222. + return res;
  75223. +}
  75224. +
  75225. +/*!
  75226. + * This structure defines the functions to be called in this driver.
  75227. + */
  75228. +static struct v4l2_file_operations mxc_v4l_fops = {
  75229. + .owner = THIS_MODULE,
  75230. + .open = mxc_v4l_open,
  75231. + .release = mxc_v4l_close,
  75232. + .read = mxc_v4l_read,
  75233. + .ioctl = mxc_v4l_ioctl,
  75234. + .mmap = mxc_mmap,
  75235. + .poll = mxc_poll,
  75236. +};
  75237. +
  75238. +static struct video_device mxc_v4l_template = {
  75239. + .name = "Mxc Camera",
  75240. + .fops = &mxc_v4l_fops,
  75241. + .release = video_device_release,
  75242. +};
  75243. +
  75244. +/*!
  75245. + * This function can be used to release any platform data on closing.
  75246. + */
  75247. +static void camera_platform_release(struct device *device)
  75248. +{
  75249. +}
  75250. +
  75251. +/*!
  75252. + * Camera V4l2 callback function.
  75253. + *
  75254. + * @param mask u32
  75255. + *
  75256. + * @param dev void device structure
  75257. + *
  75258. + * @return status
  75259. + */
  75260. +static void camera_callback(u32 mask, void *dev)
  75261. +{
  75262. + struct mxc_v4l_frame *done_frame;
  75263. + struct mxc_v4l_frame *ready_frame;
  75264. + struct timeval cur_time;
  75265. +
  75266. + cam_data *cam = (cam_data *) dev;
  75267. + if (cam == NULL)
  75268. + return;
  75269. +
  75270. + pr_debug("In MVC:camera_callback\n");
  75271. +
  75272. + spin_lock(&cam->queue_int_lock);
  75273. + spin_lock(&cam->dqueue_int_lock);
  75274. + if (!list_empty(&cam->working_q)) {
  75275. + do_gettimeofday(&cur_time);
  75276. +
  75277. + done_frame = list_entry(cam->working_q.next,
  75278. + struct mxc_v4l_frame,
  75279. + queue);
  75280. +
  75281. + if (done_frame->ipu_buf_num != cam->local_buf_num)
  75282. + goto next;
  75283. +
  75284. + /*
  75285. + * Set the current time to done frame buffer's
  75286. + * timestamp. Users can use this information to judge
  75287. + * the frame's usage.
  75288. + */
  75289. + done_frame->buffer.timestamp = cur_time;
  75290. +
  75291. + if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  75292. + done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE;
  75293. + done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  75294. +
  75295. + /* Added to the done queue */
  75296. + list_del(cam->working_q.next);
  75297. + list_add_tail(&done_frame->queue, &cam->done_q);
  75298. +
  75299. + /* Wake up the queue */
  75300. + cam->enc_counter++;
  75301. + wake_up_interruptible(&cam->enc_queue);
  75302. + } else
  75303. + pr_err("ERROR: v4l2 capture: camera_callback: "
  75304. + "buffer not queued\n");
  75305. + }
  75306. +
  75307. +next:
  75308. + if (!list_empty(&cam->ready_q)) {
  75309. + ready_frame = list_entry(cam->ready_q.next,
  75310. + struct mxc_v4l_frame,
  75311. + queue);
  75312. + if (cam->enc_update_eba)
  75313. + if (cam->enc_update_eba(cam->ipu,
  75314. + ready_frame->buffer.m.offset,
  75315. + &cam->ping_pong_csi) == 0) {
  75316. + list_del(cam->ready_q.next);
  75317. + list_add_tail(&ready_frame->queue,
  75318. + &cam->working_q);
  75319. + ready_frame->ipu_buf_num = cam->local_buf_num;
  75320. + }
  75321. + } else {
  75322. + if (cam->enc_update_eba)
  75323. + cam->enc_update_eba(
  75324. + cam->ipu, cam->dummy_frame.buffer.m.offset,
  75325. + &cam->ping_pong_csi);
  75326. + }
  75327. +
  75328. + cam->local_buf_num = (cam->local_buf_num == 0) ? 1 : 0;
  75329. + spin_unlock(&cam->dqueue_int_lock);
  75330. + spin_unlock(&cam->queue_int_lock);
  75331. +
  75332. + return;
  75333. +}
  75334. +
  75335. +/*!
  75336. + * initialize cam_data structure
  75337. + *
  75338. + * @param cam structure cam_data *
  75339. + *
  75340. + * @return status 0 Success
  75341. + */
  75342. +static int init_camera_struct(cam_data *cam, struct platform_device *pdev)
  75343. +{
  75344. + const struct of_device_id *of_id =
  75345. + of_match_device(mxc_v4l2_dt_ids, &pdev->dev);
  75346. + struct device_node *np = pdev->dev.of_node;
  75347. + int ipu_id, csi_id, mclk_source;
  75348. + int ret = 0;
  75349. +
  75350. + pr_debug("In MVC: init_camera_struct\n");
  75351. +
  75352. + ret = of_property_read_u32(np, "ipu_id", &ipu_id);
  75353. + if (ret) {
  75354. + dev_err(&pdev->dev, "ipu_id missing or invalid\n");
  75355. + return ret;
  75356. + }
  75357. +
  75358. + ret = of_property_read_u32(np, "csi_id", &csi_id);
  75359. + if (ret) {
  75360. + dev_err(&pdev->dev, "csi_id missing or invalid\n");
  75361. + return ret;
  75362. + }
  75363. +
  75364. + ret = of_property_read_u32(np, "mclk_source", &mclk_source);
  75365. + if (ret) {
  75366. + dev_err(&pdev->dev, "sensor mclk missing or invalid\n");
  75367. + return ret;
  75368. + }
  75369. +
  75370. + /* Default everything to 0 */
  75371. + memset(cam, 0, sizeof(cam_data));
  75372. +
  75373. + /* get devtype to distinguish if the cpu is imx5 or imx6
  75374. + * IMX5_V4L2 specify the cpu is imx5
  75375. + * IMX6_V4L2 specify the cpu is imx6q or imx6sdl
  75376. + */
  75377. + if (of_id)
  75378. + pdev->id_entry = of_id->data;
  75379. + cam->devtype = pdev->id_entry->driver_data;
  75380. +
  75381. + cam->ipu = ipu_get_soc(ipu_id);
  75382. + if (cam->ipu == NULL) {
  75383. + pr_err("ERROR: v4l2 capture: failed to get ipu\n");
  75384. + return -EINVAL;
  75385. + } else if (cam->ipu == ERR_PTR(-ENODEV)) {
  75386. + pr_err("ERROR: v4l2 capture: get invalid ipu\n");
  75387. + return -ENODEV;
  75388. + }
  75389. +
  75390. + init_MUTEX(&cam->param_lock);
  75391. + init_MUTEX(&cam->busy_lock);
  75392. +
  75393. + cam->video_dev = video_device_alloc();
  75394. + if (cam->video_dev == NULL)
  75395. + return -ENODEV;
  75396. +
  75397. + *(cam->video_dev) = mxc_v4l_template;
  75398. +
  75399. + video_set_drvdata(cam->video_dev, cam);
  75400. + dev_set_drvdata(&pdev->dev, (void *)cam);
  75401. + cam->video_dev->minor = -1;
  75402. +
  75403. + init_waitqueue_head(&cam->enc_queue);
  75404. + init_waitqueue_head(&cam->still_queue);
  75405. +
  75406. + /* setup cropping */
  75407. + cam->crop_bounds.left = 0;
  75408. + cam->crop_bounds.width = 640;
  75409. + cam->crop_bounds.top = 0;
  75410. + cam->crop_bounds.height = 480;
  75411. + cam->crop_current = cam->crop_defrect = cam->crop_bounds;
  75412. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  75413. + cam->crop_current.height, cam->csi);
  75414. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  75415. + cam->crop_current.top, cam->csi);
  75416. + cam->streamparm.parm.capture.capturemode = 0;
  75417. +
  75418. + cam->standard.index = 0;
  75419. + cam->standard.id = V4L2_STD_UNKNOWN;
  75420. + cam->standard.frameperiod.denominator = 30;
  75421. + cam->standard.frameperiod.numerator = 1;
  75422. + cam->standard.framelines = 480;
  75423. + cam->standard_autodetect = true;
  75424. + cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  75425. + cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
  75426. + cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
  75427. + cam->overlay_on = false;
  75428. + cam->capture_on = false;
  75429. + cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
  75430. +
  75431. + cam->v2f.fmt.pix.sizeimage = 352 * 288 * 3 / 2;
  75432. + cam->v2f.fmt.pix.bytesperline = 288 * 3 / 2;
  75433. + cam->v2f.fmt.pix.width = 288;
  75434. + cam->v2f.fmt.pix.height = 352;
  75435. + cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
  75436. + cam->win.w.width = 160;
  75437. + cam->win.w.height = 160;
  75438. + cam->win.w.left = 0;
  75439. + cam->win.w.top = 0;
  75440. +
  75441. + cam->ipu_id = ipu_id;
  75442. + cam->csi = csi_id;
  75443. + cam->mclk_source = mclk_source;
  75444. + cam->mclk_on[cam->mclk_source] = false;
  75445. +
  75446. + cam->enc_callback = camera_callback;
  75447. + init_waitqueue_head(&cam->power_queue);
  75448. + spin_lock_init(&cam->queue_int_lock);
  75449. + spin_lock_init(&cam->dqueue_int_lock);
  75450. +
  75451. + cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);
  75452. + cam->self->module = THIS_MODULE;
  75453. + sprintf(cam->self->name, "mxc_v4l2_cap%d", cam->csi);
  75454. + cam->self->type = v4l2_int_type_master;
  75455. + cam->self->u.master = &mxc_v4l2_master;
  75456. +
  75457. + return 0;
  75458. +}
  75459. +
  75460. +static ssize_t show_streaming(struct device *dev,
  75461. + struct device_attribute *attr, char *buf)
  75462. +{
  75463. + struct video_device *video_dev = container_of(dev,
  75464. + struct video_device, dev);
  75465. + cam_data *cam = video_get_drvdata(video_dev);
  75466. +
  75467. + if (cam->capture_on)
  75468. + return sprintf(buf, "stream on\n");
  75469. + else
  75470. + return sprintf(buf, "stream off\n");
  75471. +}
  75472. +static DEVICE_ATTR(fsl_v4l2_capture_property, S_IRUGO, show_streaming, NULL);
  75473. +
  75474. +static ssize_t show_overlay(struct device *dev,
  75475. + struct device_attribute *attr, char *buf)
  75476. +{
  75477. + struct video_device *video_dev = container_of(dev,
  75478. + struct video_device, dev);
  75479. + cam_data *cam = video_get_drvdata(video_dev);
  75480. +
  75481. + if (cam->overlay_on)
  75482. + return sprintf(buf, "overlay on\n");
  75483. + else
  75484. + return sprintf(buf, "overlay off\n");
  75485. +}
  75486. +static DEVICE_ATTR(fsl_v4l2_overlay_property, S_IRUGO, show_overlay, NULL);
  75487. +
  75488. +static ssize_t show_csi(struct device *dev,
  75489. + struct device_attribute *attr, char *buf)
  75490. +{
  75491. + struct video_device *video_dev = container_of(dev,
  75492. + struct video_device, dev);
  75493. + cam_data *cam = video_get_drvdata(video_dev);
  75494. +
  75495. + return sprintf(buf, "ipu%d_csi%d\n", cam->ipu_id, cam->csi);
  75496. +}
  75497. +static DEVICE_ATTR(fsl_csi_property, S_IRUGO, show_csi, NULL);
  75498. +
  75499. +/*!
  75500. + * This function is called to probe the devices if registered.
  75501. + *
  75502. + * @param pdev the device structure used to give information on which device
  75503. + * to probe
  75504. + *
  75505. + * @return The function returns 0 on success and -1 on failure.
  75506. + */
  75507. +static int mxc_v4l2_probe(struct platform_device *pdev)
  75508. +{
  75509. + /* Create cam and initialize it. */
  75510. + cam_data *cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
  75511. + if (cam == NULL) {
  75512. + pr_err("ERROR: v4l2 capture: failed to register camera\n");
  75513. + return -1;
  75514. + }
  75515. +
  75516. + init_camera_struct(cam, pdev);
  75517. + pdev->dev.release = camera_platform_release;
  75518. +
  75519. + /* Set up the v4l2 device and register it*/
  75520. + cam->self->priv = cam;
  75521. + v4l2_int_device_register(cam->self);
  75522. +
  75523. + /* register v4l video device */
  75524. + if (video_register_device(cam->video_dev, VFL_TYPE_GRABBER, video_nr)
  75525. + == -1) {
  75526. + kfree(cam);
  75527. + cam = NULL;
  75528. + pr_err("ERROR: v4l2 capture: video_register_device failed\n");
  75529. + return -1;
  75530. + }
  75531. + pr_debug(" Video device registered: %s #%d\n",
  75532. + cam->video_dev->name, cam->video_dev->minor);
  75533. +
  75534. + if (device_create_file(&cam->video_dev->dev,
  75535. + &dev_attr_fsl_v4l2_capture_property))
  75536. + dev_err(&pdev->dev, "Error on creating sysfs file"
  75537. + " for capture\n");
  75538. +
  75539. + if (device_create_file(&cam->video_dev->dev,
  75540. + &dev_attr_fsl_v4l2_overlay_property))
  75541. + dev_err(&pdev->dev, "Error on creating sysfs file"
  75542. + " for overlay\n");
  75543. +
  75544. + if (device_create_file(&cam->video_dev->dev,
  75545. + &dev_attr_fsl_csi_property))
  75546. + dev_err(&pdev->dev, "Error on creating sysfs file"
  75547. + " for csi number\n");
  75548. +
  75549. + return 0;
  75550. +}
  75551. +
  75552. +/*!
  75553. + * This function is called to remove the devices when device unregistered.
  75554. + *
  75555. + * @param pdev the device structure used to give information on which device
  75556. + * to remove
  75557. + *
  75558. + * @return The function returns 0 on success and -1 on failure.
  75559. + */
  75560. +static int mxc_v4l2_remove(struct platform_device *pdev)
  75561. +{
  75562. + cam_data *cam = (cam_data *)platform_get_drvdata(pdev);
  75563. + if (cam->open_count) {
  75564. + pr_err("ERROR: v4l2 capture:camera open "
  75565. + "-- setting ops to NULL\n");
  75566. + return -EBUSY;
  75567. + } else {
  75568. + device_remove_file(&cam->video_dev->dev,
  75569. + &dev_attr_fsl_v4l2_capture_property);
  75570. + device_remove_file(&cam->video_dev->dev,
  75571. + &dev_attr_fsl_v4l2_overlay_property);
  75572. + device_remove_file(&cam->video_dev->dev,
  75573. + &dev_attr_fsl_csi_property);
  75574. +
  75575. + pr_info("V4L2 freeing image input device\n");
  75576. + v4l2_int_device_unregister(cam->self);
  75577. + video_unregister_device(cam->video_dev);
  75578. +
  75579. + mxc_free_frame_buf(cam);
  75580. + kfree(cam);
  75581. + }
  75582. +
  75583. + pr_info("V4L2 unregistering video\n");
  75584. + return 0;
  75585. +}
  75586. +
  75587. +/*!
  75588. + * This function is called to put the sensor in a low power state.
  75589. + * Refer to the document driver-model/driver.txt in the kernel source tree
  75590. + * for more information.
  75591. + *
  75592. + * @param pdev the device structure used to give information on which I2C
  75593. + * to suspend
  75594. + * @param state the power state the device is entering
  75595. + *
  75596. + * @return The function returns 0 on success and -1 on failure.
  75597. + */
  75598. +static int mxc_v4l2_suspend(struct platform_device *pdev, pm_message_t state)
  75599. +{
  75600. + cam_data *cam = platform_get_drvdata(pdev);
  75601. +
  75602. + pr_debug("In MVC:mxc_v4l2_suspend\n");
  75603. +
  75604. + if (cam == NULL)
  75605. + return -1;
  75606. +
  75607. + down(&cam->busy_lock);
  75608. +
  75609. + cam->low_power = true;
  75610. +
  75611. + if (cam->overlay_on == true)
  75612. + stop_preview(cam);
  75613. + if ((cam->capture_on == true) && cam->enc_disable)
  75614. + cam->enc_disable(cam);
  75615. +
  75616. + if (cam->sensor && cam->open_count) {
  75617. + if (cam->mclk_on[cam->mclk_source]) {
  75618. + ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
  75619. + cam->mclk_source,
  75620. + false, false);
  75621. + cam->mclk_on[cam->mclk_source] = false;
  75622. + }
  75623. + vidioc_int_s_power(cam->sensor, 0);
  75624. + }
  75625. +
  75626. + up(&cam->busy_lock);
  75627. +
  75628. + return 0;
  75629. +}
  75630. +
  75631. +/*!
  75632. + * This function is called to bring the sensor back from a low power state.
  75633. + * Refer to the document driver-model/driver.txt in the kernel source tree
  75634. + * for more information.
  75635. + *
  75636. + * @param pdev the device structure
  75637. + *
  75638. + * @return The function returns 0 on success and -1 on failure
  75639. + */
  75640. +static int mxc_v4l2_resume(struct platform_device *pdev)
  75641. +{
  75642. + cam_data *cam = platform_get_drvdata(pdev);
  75643. +
  75644. + pr_debug("In MVC:mxc_v4l2_resume\n");
  75645. +
  75646. + if (cam == NULL)
  75647. + return -1;
  75648. +
  75649. + down(&cam->busy_lock);
  75650. +
  75651. + cam->low_power = false;
  75652. + wake_up_interruptible(&cam->power_queue);
  75653. +
  75654. + if (cam->sensor && cam->open_count) {
  75655. + vidioc_int_s_power(cam->sensor, 1);
  75656. +
  75657. + if (!cam->mclk_on[cam->mclk_source]) {
  75658. + ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
  75659. + cam->mclk_source,
  75660. + true, true);
  75661. + cam->mclk_on[cam->mclk_source] = true;
  75662. + }
  75663. + }
  75664. +
  75665. + if (cam->overlay_on == true)
  75666. + start_preview(cam);
  75667. + if (cam->capture_on == true)
  75668. + mxc_streamon(cam);
  75669. +
  75670. + up(&cam->busy_lock);
  75671. +
  75672. + return 0;
  75673. +}
  75674. +
  75675. +/*!
  75676. + * This structure contains pointers to the power management callback functions.
  75677. + */
  75678. +static struct platform_driver mxc_v4l2_driver = {
  75679. + .driver = {
  75680. + .name = "mxc_v4l2_capture",
  75681. + .owner = THIS_MODULE,
  75682. + .of_match_table = mxc_v4l2_dt_ids,
  75683. + },
  75684. + .id_table = imx_v4l2_devtype,
  75685. + .probe = mxc_v4l2_probe,
  75686. + .remove = mxc_v4l2_remove,
  75687. + .suspend = mxc_v4l2_suspend,
  75688. + .resume = mxc_v4l2_resume,
  75689. + .shutdown = NULL,
  75690. +};
  75691. +
  75692. +/*!
  75693. + * Initializes the camera driver.
  75694. + */
  75695. +static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)
  75696. +{
  75697. + cam_data *cam = slave->u.slave->master->priv;
  75698. + struct v4l2_format cam_fmt;
  75699. + int i;
  75700. + struct sensor_data *sdata = slave->priv;
  75701. +
  75702. + pr_debug("In MVC: mxc_v4l2_master_attach\n");
  75703. + pr_debug(" slave.name = %s\n", slave->name);
  75704. + pr_debug(" master.name = %s\n", slave->u.slave->master->name);
  75705. +
  75706. + if (slave == NULL) {
  75707. + pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
  75708. + return -1;
  75709. + }
  75710. +
  75711. + if (sdata->csi != cam->csi) {
  75712. + pr_debug("%s: csi doesn't match\n", __func__);
  75713. + return -1;
  75714. + }
  75715. +
  75716. + cam->sensor = slave;
  75717. +
  75718. + if (cam->sensor_index < MXC_SENSOR_NUM) {
  75719. + cam->all_sensors[cam->sensor_index] = slave;
  75720. + cam->sensor_index++;
  75721. + } else {
  75722. + pr_err("ERROR: v4l2 capture: slave number exceeds the maximum.\n");
  75723. + return -1;
  75724. + }
  75725. +
  75726. + for (i = 0; i < cam->sensor_index; i++) {
  75727. + vidioc_int_dev_exit(cam->all_sensors[i]);
  75728. + vidioc_int_s_power(cam->all_sensors[i], 0);
  75729. + }
  75730. +
  75731. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  75732. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  75733. +
  75734. + /* Used to detect TV in (type 1) vs. camera (type 0)*/
  75735. + cam->device_type = cam_fmt.fmt.pix.priv;
  75736. +
  75737. + /* Set the input size to the ipu for this device */
  75738. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  75739. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  75740. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  75741. +
  75742. + /* This also is the max crop size for this device. */
  75743. + cam->crop_defrect.top = cam->crop_defrect.left = 0;
  75744. + cam->crop_defrect.width = cam_fmt.fmt.pix.width;
  75745. + cam->crop_defrect.height = cam_fmt.fmt.pix.height;
  75746. +
  75747. + /* At this point, this is also the current image size. */
  75748. + cam->crop_current.top = cam->crop_current.left = 0;
  75749. + cam->crop_current.width = cam_fmt.fmt.pix.width;
  75750. + cam->crop_current.height = cam_fmt.fmt.pix.height;
  75751. +
  75752. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  75753. + __func__,
  75754. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  75755. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  75756. + __func__,
  75757. + cam->crop_bounds.width, cam->crop_bounds.height);
  75758. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  75759. + __func__,
  75760. + cam->crop_defrect.width, cam->crop_defrect.height);
  75761. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  75762. + __func__,
  75763. + cam->crop_current.width, cam->crop_current.height);
  75764. +
  75765. + return 0;
  75766. +}
  75767. +
  75768. +/*!
  75769. + * Disconnects the camera driver.
  75770. + */
  75771. +static void mxc_v4l2_master_detach(struct v4l2_int_device *slave)
  75772. +{
  75773. + unsigned int i;
  75774. + cam_data *cam = slave->u.slave->master->priv;
  75775. +
  75776. + pr_debug("In MVC:mxc_v4l2_master_detach\n");
  75777. +
  75778. + if (cam->sensor_index > 1) {
  75779. + for (i = 0; i < cam->sensor_index; i++) {
  75780. + if (cam->all_sensors[i] != slave)
  75781. + continue;
  75782. + /* Move all the sensors behind this
  75783. + * sensor one step forward
  75784. + */
  75785. + for (; i <= MXC_SENSOR_NUM - 2; i++)
  75786. + cam->all_sensors[i] = cam->all_sensors[i+1];
  75787. + break;
  75788. + }
  75789. + /* Point current sensor to the last one */
  75790. + cam->sensor = cam->all_sensors[cam->sensor_index - 2];
  75791. + } else
  75792. + cam->sensor = NULL;
  75793. +
  75794. + cam->sensor_index--;
  75795. + vidioc_int_dev_exit(slave);
  75796. +}
  75797. +
  75798. +/*!
  75799. + * Entry point for the V4L2
  75800. + *
  75801. + * @return Error code indicating success or failure
  75802. + */
  75803. +static __init int camera_init(void)
  75804. +{
  75805. + u8 err = 0;
  75806. +
  75807. + pr_debug("In MVC:camera_init\n");
  75808. +
  75809. + /* Register the device driver structure. */
  75810. + err = platform_driver_register(&mxc_v4l2_driver);
  75811. + if (err != 0) {
  75812. + pr_err("ERROR: v4l2 capture:camera_init: "
  75813. + "platform_driver_register failed.\n");
  75814. + return err;
  75815. + }
  75816. +
  75817. + return err;
  75818. +}
  75819. +
  75820. +/*!
  75821. + * Exit and cleanup for the V4L2
  75822. + */
  75823. +static void __exit camera_exit(void)
  75824. +{
  75825. + pr_debug("In MVC: camera_exit\n");
  75826. +
  75827. + platform_driver_unregister(&mxc_v4l2_driver);
  75828. +}
  75829. +
  75830. +module_init(camera_init);
  75831. +module_exit(camera_exit);
  75832. +
  75833. +module_param(video_nr, int, 0444);
  75834. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  75835. +MODULE_DESCRIPTION("V4L2 capture driver for Mxc based cameras");
  75836. +MODULE_LICENSE("GPL");
  75837. +MODULE_SUPPORTED_DEVICE("video");
  75838. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
  75839. --- linux-3.14.15/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h 1970-01-01 01:00:00.000000000 +0100
  75840. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h 2014-08-20 19:23:52.818842679 +0200
  75841. @@ -0,0 +1,260 @@
  75842. +/*
  75843. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  75844. + */
  75845. +
  75846. +/*
  75847. + * The code contained herein is licensed under the GNU General Public
  75848. + * License. You may obtain a copy of the GNU General Public License
  75849. + * Version 2 or later at the following locations:
  75850. + *
  75851. + * http://www.opensource.org/licenses/gpl-license.html
  75852. + * http://www.gnu.org/copyleft/gpl.html
  75853. + */
  75854. +
  75855. +/*!
  75856. + * @defgroup MXC_V4L2_CAPTURE MXC V4L2 Video Capture Driver
  75857. + */
  75858. +/*!
  75859. + * @file mxc_v4l2_capture.h
  75860. + *
  75861. + * @brief mxc V4L2 capture device API Header file
  75862. + *
  75863. + * It include all the defines for frame operations, also three structure defines
  75864. + * use case ops structure, common v4l2 driver structure and frame structure.
  75865. + *
  75866. + * @ingroup MXC_V4L2_CAPTURE
  75867. + */
  75868. +#ifndef __MXC_V4L2_CAPTURE_H__
  75869. +#define __MXC_V4L2_CAPTURE_H__
  75870. +
  75871. +#include <linux/uaccess.h>
  75872. +#include <linux/list.h>
  75873. +#include <linux/mxc_v4l2.h>
  75874. +#include <linux/completion.h>
  75875. +#include <linux/dmaengine.h>
  75876. +#include <linux/pxp_dma.h>
  75877. +#include <linux/ipu-v3.h>
  75878. +#include <linux/platform_data/dma-imx.h>
  75879. +
  75880. +#include <media/v4l2-dev.h>
  75881. +#include <media/v4l2-int-device.h>
  75882. +
  75883. +
  75884. +#define FRAME_NUM 10
  75885. +#define MXC_SENSOR_NUM 2
  75886. +
  75887. +enum imx_v4l2_devtype {
  75888. + IMX5_V4L2,
  75889. + IMX6_V4L2,
  75890. +};
  75891. +
  75892. +/*!
  75893. + * v4l2 frame structure.
  75894. + */
  75895. +struct mxc_v4l_frame {
  75896. + u32 paddress;
  75897. + void *vaddress;
  75898. + int count;
  75899. + int width;
  75900. + int height;
  75901. +
  75902. + struct v4l2_buffer buffer;
  75903. + struct list_head queue;
  75904. + int index;
  75905. + union {
  75906. + int ipu_buf_num;
  75907. + int csi_buf_num;
  75908. + };
  75909. +};
  75910. +
  75911. +/* Only for old version. Will go away soon. */
  75912. +typedef struct {
  75913. + u8 clk_mode;
  75914. + u8 ext_vsync;
  75915. + u8 Vsync_pol;
  75916. + u8 Hsync_pol;
  75917. + u8 pixclk_pol;
  75918. + u8 data_pol;
  75919. + u8 data_width;
  75920. + u8 pack_tight;
  75921. + u8 force_eof;
  75922. + u8 data_en_pol;
  75923. + u16 width;
  75924. + u16 height;
  75925. + u32 pixel_fmt;
  75926. + u32 mclk;
  75927. + u16 active_width;
  75928. + u16 active_height;
  75929. +} sensor_interface;
  75930. +
  75931. +/* Sensor control function */
  75932. +/* Only for old version. Will go away soon. */
  75933. +struct camera_sensor {
  75934. + void (*set_color) (int bright, int saturation, int red, int green,
  75935. + int blue);
  75936. + void (*get_color) (int *bright, int *saturation, int *red, int *green,
  75937. + int *blue);
  75938. + void (*set_ae_mode) (int ae_mode);
  75939. + void (*get_ae_mode) (int *ae_mode);
  75940. + sensor_interface *(*config) (int *frame_rate, int high_quality);
  75941. + sensor_interface *(*reset) (void);
  75942. + void (*get_std) (v4l2_std_id *std);
  75943. + void (*set_std) (v4l2_std_id std);
  75944. + unsigned int csi;
  75945. +};
  75946. +
  75947. +/*!
  75948. + * common v4l2 driver structure.
  75949. + */
  75950. +typedef struct _cam_data {
  75951. + struct video_device *video_dev;
  75952. + int device_type;
  75953. +
  75954. + /* semaphore guard against SMP multithreading */
  75955. + struct semaphore busy_lock;
  75956. +
  75957. + int open_count;
  75958. +
  75959. + /* params lock for this camera */
  75960. + struct semaphore param_lock;
  75961. +
  75962. + /* Encoder */
  75963. + struct list_head ready_q;
  75964. + struct list_head done_q;
  75965. + struct list_head working_q;
  75966. + int ping_pong_csi;
  75967. + spinlock_t queue_int_lock;
  75968. + spinlock_t dqueue_int_lock;
  75969. + struct mxc_v4l_frame frame[FRAME_NUM];
  75970. + struct mxc_v4l_frame dummy_frame;
  75971. + wait_queue_head_t enc_queue;
  75972. + int enc_counter;
  75973. + dma_addr_t rot_enc_bufs[2];
  75974. + void *rot_enc_bufs_vaddr[2];
  75975. + int rot_enc_buf_size[2];
  75976. + enum v4l2_buf_type type;
  75977. +
  75978. + /* still image capture */
  75979. + wait_queue_head_t still_queue;
  75980. + int still_counter;
  75981. + dma_addr_t still_buf[2];
  75982. + void *still_buf_vaddr;
  75983. +
  75984. + /* overlay */
  75985. + struct v4l2_window win;
  75986. + struct v4l2_framebuffer v4l2_fb;
  75987. + dma_addr_t vf_bufs[2];
  75988. + void *vf_bufs_vaddr[2];
  75989. + int vf_bufs_size[2];
  75990. + dma_addr_t rot_vf_bufs[2];
  75991. + void *rot_vf_bufs_vaddr[2];
  75992. + int rot_vf_buf_size[2];
  75993. + bool overlay_active;
  75994. + int output;
  75995. + struct fb_info *overlay_fb;
  75996. + int fb_origin_std;
  75997. + struct work_struct csi_work_struct;
  75998. +
  75999. + /* v4l2 format */
  76000. + struct v4l2_format v2f;
  76001. + int rotation; /* for IPUv1 and IPUv3, this means encoder rotation */
  76002. + int vf_rotation; /* viewfinder rotation only for IPUv1 and IPUv3 */
  76003. + struct v4l2_mxc_offset offset;
  76004. +
  76005. + /* V4l2 control bit */
  76006. + int bright;
  76007. + int hue;
  76008. + int contrast;
  76009. + int saturation;
  76010. + int red;
  76011. + int green;
  76012. + int blue;
  76013. + int ae_mode;
  76014. +
  76015. + /* standard */
  76016. + struct v4l2_streamparm streamparm;
  76017. + struct v4l2_standard standard;
  76018. + bool standard_autodetect;
  76019. +
  76020. + /* crop */
  76021. + struct v4l2_rect crop_bounds;
  76022. + struct v4l2_rect crop_defrect;
  76023. + struct v4l2_rect crop_current;
  76024. +
  76025. + int (*enc_update_eba) (struct ipu_soc *ipu, dma_addr_t eba,
  76026. + int *bufferNum);
  76027. + int (*enc_enable) (void *private);
  76028. + int (*enc_disable) (void *private);
  76029. + int (*enc_enable_csi) (void *private);
  76030. + int (*enc_disable_csi) (void *private);
  76031. + void (*enc_callback) (u32 mask, void *dev);
  76032. + int (*vf_start_adc) (void *private);
  76033. + int (*vf_stop_adc) (void *private);
  76034. + int (*vf_start_sdc) (void *private);
  76035. + int (*vf_stop_sdc) (void *private);
  76036. + int (*vf_enable_csi) (void *private);
  76037. + int (*vf_disable_csi) (void *private);
  76038. + int (*csi_start) (void *private);
  76039. + int (*csi_stop) (void *private);
  76040. +
  76041. + /* misc status flag */
  76042. + bool overlay_on;
  76043. + bool capture_on;
  76044. + int overlay_pid;
  76045. + int capture_pid;
  76046. + bool low_power;
  76047. + wait_queue_head_t power_queue;
  76048. + unsigned int ipu_id;
  76049. + unsigned int csi;
  76050. + u8 mclk_source;
  76051. + bool mclk_on[2]; /* two mclk sources at most now */
  76052. + int current_input;
  76053. +
  76054. + int local_buf_num;
  76055. +
  76056. + /* camera sensor interface */
  76057. + struct camera_sensor *cam_sensor; /* old version */
  76058. + struct v4l2_int_device *all_sensors[MXC_SENSOR_NUM];
  76059. + struct v4l2_int_device *sensor;
  76060. + struct v4l2_int_device *self;
  76061. + int sensor_index;
  76062. + void *ipu;
  76063. + enum imx_v4l2_devtype devtype;
  76064. +
  76065. + /* v4l2 buf elements related to PxP DMA */
  76066. + struct completion pxp_tx_cmpl;
  76067. + struct pxp_channel *pxp_chan;
  76068. + struct pxp_config_data pxp_conf;
  76069. + struct dma_async_tx_descriptor *txd;
  76070. + dma_cookie_t cookie;
  76071. + struct scatterlist sg[2];
  76072. +} cam_data;
  76073. +
  76074. +struct sensor_data {
  76075. + const struct ov5642_platform_data *platform_data;
  76076. + struct v4l2_int_device *v4l2_int_device;
  76077. + struct i2c_client *i2c_client;
  76078. + struct v4l2_pix_format pix;
  76079. + struct v4l2_captureparm streamcap;
  76080. + bool on;
  76081. +
  76082. + /* control settings */
  76083. + int brightness;
  76084. + int hue;
  76085. + int contrast;
  76086. + int saturation;
  76087. + int red;
  76088. + int green;
  76089. + int blue;
  76090. + int ae_mode;
  76091. +
  76092. + u32 mclk;
  76093. + u8 mclk_source;
  76094. + struct clk *sensor_clk;
  76095. + int csi;
  76096. +
  76097. + void (*io_init)(void);
  76098. +};
  76099. +
  76100. +void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi);
  76101. +#endif /* __MXC_V4L2_CAPTURE_H__ */
  76102. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/ov5640.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ov5640.c
  76103. --- linux-3.14.15/drivers/media/platform/mxc/capture/ov5640.c 1970-01-01 01:00:00.000000000 +0100
  76104. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ov5640.c 2014-08-20 19:23:52.818842679 +0200
  76105. @@ -0,0 +1,1951 @@
  76106. +/*
  76107. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  76108. + */
  76109. +
  76110. +/*
  76111. + * This program is free software; you can redistribute it and/or modify
  76112. + * it under the terms of the GNU General Public License as published by
  76113. + * the Free Software Foundation; either version 2 of the License, or
  76114. + * (at your option) any later version.
  76115. +
  76116. + * This program is distributed in the hope that it will be useful,
  76117. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  76118. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  76119. + * GNU General Public License for more details.
  76120. +
  76121. + * You should have received a copy of the GNU General Public License along
  76122. + * with this program; if not, write to the Free Software Foundation, Inc.,
  76123. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  76124. + */
  76125. +
  76126. +#include <linux/clk.h>
  76127. +#include <linux/delay.h>
  76128. +#include <linux/device.h>
  76129. +#include <linux/i2c.h>
  76130. +#include <linux/init.h>
  76131. +#include <linux/module.h>
  76132. +#include <linux/of_device.h>
  76133. +#include <linux/of_gpio.h>
  76134. +#include <linux/pinctrl/consumer.h>
  76135. +#include <linux/regulator/consumer.h>
  76136. +#include <media/v4l2-chip-ident.h>
  76137. +#include <media/v4l2-int-device.h>
  76138. +#include "mxc_v4l2_capture.h"
  76139. +
  76140. +#define OV5640_VOLTAGE_ANALOG 2800000
  76141. +#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
  76142. +#define OV5640_VOLTAGE_DIGITAL_IO 1800000
  76143. +
  76144. +#define MIN_FPS 15
  76145. +#define MAX_FPS 30
  76146. +#define DEFAULT_FPS 30
  76147. +
  76148. +#define OV5640_XCLK_MIN 6000000
  76149. +#define OV5640_XCLK_MAX 24000000
  76150. +
  76151. +#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
  76152. +#define OV5640_CHIP_ID_LOW_BYTE 0x300B
  76153. +
  76154. +enum ov5640_mode {
  76155. + ov5640_mode_MIN = 0,
  76156. + ov5640_mode_VGA_640_480 = 0,
  76157. + ov5640_mode_QVGA_320_240 = 1,
  76158. + ov5640_mode_NTSC_720_480 = 2,
  76159. + ov5640_mode_PAL_720_576 = 3,
  76160. + ov5640_mode_720P_1280_720 = 4,
  76161. + ov5640_mode_1080P_1920_1080 = 5,
  76162. + ov5640_mode_QSXGA_2592_1944 = 6,
  76163. + ov5640_mode_QCIF_176_144 = 7,
  76164. + ov5640_mode_XGA_1024_768 = 8,
  76165. + ov5640_mode_MAX = 8
  76166. +};
  76167. +
  76168. +enum ov5640_frame_rate {
  76169. + ov5640_15_fps,
  76170. + ov5640_30_fps
  76171. +};
  76172. +
  76173. +static int ov5640_framerates[] = {
  76174. + [ov5640_15_fps] = 15,
  76175. + [ov5640_30_fps] = 30,
  76176. +};
  76177. +
  76178. +struct reg_value {
  76179. + u16 u16RegAddr;
  76180. + u8 u8Val;
  76181. + u8 u8Mask;
  76182. + u32 u32Delay_ms;
  76183. +};
  76184. +
  76185. +struct ov5640_mode_info {
  76186. + enum ov5640_mode mode;
  76187. + u32 width;
  76188. + u32 height;
  76189. + struct reg_value *init_data_ptr;
  76190. + u32 init_data_size;
  76191. +};
  76192. +
  76193. +/*!
  76194. + * Maintains the information on the current state of the sesor.
  76195. + */
  76196. +static struct sensor_data ov5640_data;
  76197. +static int pwn_gpio, rst_gpio;
  76198. +static int prev_sysclk;
  76199. +static int AE_Target = 52, night_mode;
  76200. +static int prev_HTS;
  76201. +static int AE_high, AE_low;
  76202. +
  76203. +static struct reg_value ov5640_global_init_setting[] = {
  76204. + {0x3008, 0x42, 0, 0},
  76205. + {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
  76206. + {0x3034, 0x1a, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0},
  76207. + {0x3630, 0x36, 0, 0}, {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0},
  76208. + {0x3633, 0x12, 0, 0}, {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0},
  76209. + {0x3703, 0x5a, 0, 0}, {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0},
  76210. + {0x370b, 0x60, 0, 0}, {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0},
  76211. + {0x3906, 0x10, 0, 0}, {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0},
  76212. + {0x3600, 0x08, 0, 0}, {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0},
  76213. + {0x3620, 0x52, 0, 0}, {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0},
  76214. + {0x3a13, 0x43, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  76215. + {0x3635, 0x13, 0, 0}, {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0},
  76216. + {0x3622, 0x01, 0, 0}, {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0},
  76217. + {0x3c05, 0x98, 0, 0}, {0x3c06, 0x00, 0, 0}, {0x3c07, 0x07, 0, 0},
  76218. + {0x3c08, 0x00, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0},
  76219. + {0x3c0b, 0x40, 0, 0}, {0x3810, 0x00, 0, 0}, {0x3811, 0x10, 0, 0},
  76220. + {0x3812, 0x00, 0, 0}, {0x3708, 0x64, 0, 0}, {0x4001, 0x02, 0, 0},
  76221. + {0x4005, 0x1a, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
  76222. + {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
  76223. + {0x501f, 0x00, 0, 0}, {0x440e, 0x00, 0, 0}, {0x5000, 0xa7, 0, 0},
  76224. + {0x3008, 0x02, 0, 0},
  76225. +};
  76226. +
  76227. +static struct reg_value ov5640_init_setting_30fps_VGA[] = {
  76228. + {0x3008, 0x42, 0, 0},
  76229. + {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
  76230. + {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0}, {0x3036, 0x46, 0, 0},
  76231. + {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
  76232. + {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
  76233. + {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
  76234. + {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
  76235. + {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
  76236. + {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
  76237. + {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
  76238. + {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
  76239. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
  76240. + {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
  76241. + {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
  76242. + {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
  76243. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  76244. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  76245. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  76246. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  76247. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  76248. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  76249. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  76250. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  76251. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  76252. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  76253. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  76254. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  76255. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  76256. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  76257. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
  76258. + {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
  76259. + {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
  76260. + {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
  76261. + {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  76262. + {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5000, 0xa7, 0, 0},
  76263. + {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0},
  76264. + {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  76265. + {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0},
  76266. + {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0}, {0x518a, 0x54, 0, 0},
  76267. + {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x50, 0, 0},
  76268. + {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0}, {0x5190, 0x46, 0, 0},
  76269. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  76270. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  76271. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x6c, 0, 0},
  76272. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x09, 0, 0},
  76273. + {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0}, {0x5381, 0x1e, 0, 0},
  76274. + {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0}, {0x5384, 0x0a, 0, 0},
  76275. + {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0},
  76276. + {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0},
  76277. + {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0},
  76278. + {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0},
  76279. + {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0},
  76280. + {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0},
  76281. + {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0}, {0x5481, 0x08, 0, 0},
  76282. + {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0}, {0x5484, 0x51, 0, 0},
  76283. + {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0}, {0x5487, 0x7d, 0, 0},
  76284. + {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0}, {0x548a, 0x9a, 0, 0},
  76285. + {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0}, {0x548d, 0xcd, 0, 0},
  76286. + {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0}, {0x5490, 0x1d, 0, 0},
  76287. + {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x10, 0, 0},
  76288. + {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0}, {0x558b, 0xf8, 0, 0},
  76289. + {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0}, {0x5802, 0x0f, 0, 0},
  76290. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0}, {0x5805, 0x26, 0, 0},
  76291. + {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0}, {0x5808, 0x05, 0, 0},
  76292. + {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0}, {0x580b, 0x0d, 0, 0},
  76293. + {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0}, {0x580e, 0x00, 0, 0},
  76294. + {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0}, {0x5811, 0x09, 0, 0},
  76295. + {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x00, 0, 0},
  76296. + {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0}, {0x5817, 0x08, 0, 0},
  76297. + {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0}, {0x581a, 0x05, 0, 0},
  76298. + {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0}, {0x581d, 0x0e, 0, 0},
  76299. + {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0}, {0x5820, 0x11, 0, 0},
  76300. + {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0}, {0x5823, 0x28, 0, 0},
  76301. + {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0}, {0x5826, 0x08, 0, 0},
  76302. + {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0}, {0x5829, 0x26, 0, 0},
  76303. + {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0}, {0x582c, 0x24, 0, 0},
  76304. + {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0}, {0x582f, 0x22, 0, 0},
  76305. + {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0}, {0x5832, 0x24, 0, 0},
  76306. + {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0}, {0x5835, 0x22, 0, 0},
  76307. + {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0}, {0x5838, 0x44, 0, 0},
  76308. + {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0}, {0x583b, 0x28, 0, 0},
  76309. + {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0}, {0x5025, 0x00, 0, 0},
  76310. + {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
  76311. + {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
  76312. + {0x3008, 0x02, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76313. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76314. +};
  76315. +
  76316. +static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
  76317. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76318. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76319. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76320. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76321. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
  76322. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  76323. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76324. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76325. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76326. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76327. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76328. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76329. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76330. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76331. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
  76332. +};
  76333. +
  76334. +static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
  76335. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76336. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76337. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76338. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76339. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
  76340. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  76341. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76342. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76343. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76344. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76345. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76346. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76347. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76348. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76349. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
  76350. +};
  76351. +
  76352. +static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
  76353. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76354. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76355. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76356. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76357. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
  76358. + {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
  76359. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76360. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76361. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76362. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76363. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76364. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76365. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76366. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76367. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76368. +};
  76369. +
  76370. +static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
  76371. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76372. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76373. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76374. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76375. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
  76376. + {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
  76377. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76378. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76379. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76380. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76381. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76382. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76383. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76384. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76385. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76386. +};
  76387. +
  76388. +static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
  76389. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76390. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76391. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76392. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
  76393. + {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  76394. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  76395. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76396. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76397. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76398. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76399. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76400. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76401. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76402. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76403. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76404. +};
  76405. +
  76406. +static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
  76407. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76408. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76409. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76410. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
  76411. + {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  76412. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  76413. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76414. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76415. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76416. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76417. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76418. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76419. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76420. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76421. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76422. +};
  76423. +
  76424. +static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
  76425. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76426. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76427. + {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76428. + {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
  76429. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  76430. + {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
  76431. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76432. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76433. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76434. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76435. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76436. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76437. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76438. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76439. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76440. +};
  76441. +
  76442. +static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
  76443. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76444. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76445. + {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76446. + {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
  76447. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  76448. + {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
  76449. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76450. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76451. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76452. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76453. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76454. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76455. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76456. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76457. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76458. +};
  76459. +
  76460. +static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
  76461. + {0x3035, 0x21, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
  76462. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  76463. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  76464. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  76465. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  76466. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  76467. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  76468. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
  76469. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
  76470. + {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
  76471. + {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
  76472. + {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
  76473. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  76474. + {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
  76475. + {0x3503, 0x00, 0, 0},
  76476. +};
  76477. +
  76478. +static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
  76479. + {0x3035, 0x41, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
  76480. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  76481. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  76482. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  76483. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  76484. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  76485. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  76486. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
  76487. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
  76488. + {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
  76489. + {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
  76490. + {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
  76491. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  76492. + {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
  76493. + {0x3503, 0x00, 0, 0},
  76494. +};
  76495. +
  76496. +static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
  76497. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76498. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76499. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76500. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76501. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
  76502. + {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
  76503. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76504. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76505. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76506. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76507. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76508. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76509. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76510. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76511. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76512. +};
  76513. +
  76514. +static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
  76515. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76516. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76517. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76518. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76519. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
  76520. + {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
  76521. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76522. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76523. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76524. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76525. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76526. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76527. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76528. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76529. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76530. +};
  76531. +
  76532. +static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
  76533. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76534. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76535. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76536. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76537. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
  76538. + {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
  76539. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76540. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76541. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76542. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76543. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76544. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76545. + {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
  76546. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76547. + {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
  76548. +};
  76549. +
  76550. +static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
  76551. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76552. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76553. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76554. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76555. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
  76556. + {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
  76557. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76558. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76559. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76560. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76561. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76562. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76563. + {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
  76564. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76565. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76566. +};
  76567. +
  76568. +
  76569. +static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
  76570. + {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
  76571. + {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
  76572. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0xee, 0, 0},
  76573. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x05, 0, 0},
  76574. + {0x3807, 0xc3, 0, 0}, {0x3808, 0x07, 0, 0}, {0x3809, 0x80, 0, 0},
  76575. + {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0}, {0x380c, 0x0b, 0, 0},
  76576. + {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
  76577. + {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
  76578. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
  76579. + {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
  76580. + {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76581. + {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
  76582. + {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
  76583. + {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76584. + {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
  76585. +};
  76586. +
  76587. +static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
  76588. + {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
  76589. + {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
  76590. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0},
  76591. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76592. + {0x3807, 0x9f, 0, 0}, {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0},
  76593. + {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0},
  76594. + {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
  76595. + {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
  76596. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
  76597. + {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
  76598. + {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76599. + {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
  76600. + {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
  76601. + {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76602. + {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
  76603. +};
  76604. +
  76605. +static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
  76606. + {
  76607. + {ov5640_mode_VGA_640_480, 640, 480,
  76608. + ov5640_setting_15fps_VGA_640_480,
  76609. + ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
  76610. + {ov5640_mode_QVGA_320_240, 320, 240,
  76611. + ov5640_setting_15fps_QVGA_320_240,
  76612. + ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
  76613. + {ov5640_mode_NTSC_720_480, 720, 480,
  76614. + ov5640_setting_15fps_NTSC_720_480,
  76615. + ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
  76616. + {ov5640_mode_PAL_720_576, 720, 576,
  76617. + ov5640_setting_15fps_PAL_720_576,
  76618. + ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
  76619. + {ov5640_mode_720P_1280_720, 1280, 720,
  76620. + ov5640_setting_15fps_720P_1280_720,
  76621. + ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
  76622. + {ov5640_mode_1080P_1920_1080, 1920, 1080,
  76623. + ov5640_setting_15fps_1080P_1920_1080,
  76624. + ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
  76625. + {ov5640_mode_QSXGA_2592_1944, 2592, 1944,
  76626. + ov5640_setting_15fps_QSXGA_2592_1944,
  76627. + ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
  76628. + {ov5640_mode_QCIF_176_144, 176, 144,
  76629. + ov5640_setting_15fps_QCIF_176_144,
  76630. + ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
  76631. + {ov5640_mode_XGA_1024_768, 1024, 768,
  76632. + ov5640_setting_15fps_XGA_1024_768,
  76633. + ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
  76634. + },
  76635. + {
  76636. + {ov5640_mode_VGA_640_480, 640, 480,
  76637. + ov5640_setting_30fps_VGA_640_480,
  76638. + ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
  76639. + {ov5640_mode_QVGA_320_240, 320, 240,
  76640. + ov5640_setting_30fps_QVGA_320_240,
  76641. + ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
  76642. + {ov5640_mode_NTSC_720_480, 720, 480,
  76643. + ov5640_setting_30fps_NTSC_720_480,
  76644. + ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
  76645. + {ov5640_mode_PAL_720_576, 720, 576,
  76646. + ov5640_setting_30fps_PAL_720_576,
  76647. + ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
  76648. + {ov5640_mode_720P_1280_720, 1280, 720,
  76649. + ov5640_setting_30fps_720P_1280_720,
  76650. + ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
  76651. + {ov5640_mode_1080P_1920_1080, 0, 0, NULL, 0},
  76652. + {ov5640_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
  76653. + {ov5640_mode_QCIF_176_144, 176, 144,
  76654. + ov5640_setting_30fps_QCIF_176_144,
  76655. + ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
  76656. + {ov5640_mode_XGA_1024_768, 1024, 768,
  76657. + ov5640_setting_30fps_XGA_1024_768,
  76658. + ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
  76659. + },
  76660. +};
  76661. +
  76662. +static struct regulator *io_regulator;
  76663. +static struct regulator *core_regulator;
  76664. +static struct regulator *analog_regulator;
  76665. +
  76666. +static int ov5640_probe(struct i2c_client *adapter,
  76667. + const struct i2c_device_id *device_id);
  76668. +static int ov5640_remove(struct i2c_client *client);
  76669. +
  76670. +static s32 ov5640_read_reg(u16 reg, u8 *val);
  76671. +static s32 ov5640_write_reg(u16 reg, u8 val);
  76672. +
  76673. +static const struct i2c_device_id ov5640_id[] = {
  76674. + {"ov5640", 0},
  76675. + {"ov564x", 0},
  76676. + {},
  76677. +};
  76678. +
  76679. +MODULE_DEVICE_TABLE(i2c, ov5640_id);
  76680. +
  76681. +static struct i2c_driver ov5640_i2c_driver = {
  76682. + .driver = {
  76683. + .owner = THIS_MODULE,
  76684. + .name = "ov5640",
  76685. + },
  76686. + .probe = ov5640_probe,
  76687. + .remove = ov5640_remove,
  76688. + .id_table = ov5640_id,
  76689. +};
  76690. +
  76691. +static inline void ov5640_power_down(int enable)
  76692. +{
  76693. + gpio_set_value(pwn_gpio, enable);
  76694. +
  76695. + msleep(2);
  76696. +}
  76697. +
  76698. +static inline void ov5640_reset(void)
  76699. +{
  76700. + /* camera reset */
  76701. + gpio_set_value(rst_gpio, 1);
  76702. +
  76703. + /* camera power down */
  76704. + gpio_set_value(pwn_gpio, 1);
  76705. + msleep(5);
  76706. + gpio_set_value(pwn_gpio, 0);
  76707. + msleep(5);
  76708. + gpio_set_value(rst_gpio, 0);
  76709. + msleep(1);
  76710. + gpio_set_value(rst_gpio, 1);
  76711. + msleep(5);
  76712. + gpio_set_value(pwn_gpio, 1);
  76713. +}
  76714. +
  76715. +static int ov5640_regulator_enable(struct device *dev)
  76716. +{
  76717. + int ret = 0;
  76718. +
  76719. + io_regulator = devm_regulator_get(dev, "DOVDD");
  76720. + if (!IS_ERR(io_regulator)) {
  76721. + regulator_set_voltage(io_regulator,
  76722. + OV5640_VOLTAGE_DIGITAL_IO,
  76723. + OV5640_VOLTAGE_DIGITAL_IO);
  76724. + ret = regulator_enable(io_regulator);
  76725. + if (ret) {
  76726. + dev_err(dev, "set io voltage failed\n");
  76727. + return ret;
  76728. + } else {
  76729. + dev_dbg(dev, "set io voltage ok\n");
  76730. + }
  76731. + } else {
  76732. + io_regulator = NULL;
  76733. + dev_warn(dev, "cannot get io voltage\n");
  76734. + }
  76735. +
  76736. + core_regulator = devm_regulator_get(dev, "DVDD");
  76737. + if (!IS_ERR(core_regulator)) {
  76738. + regulator_set_voltage(core_regulator,
  76739. + OV5640_VOLTAGE_DIGITAL_CORE,
  76740. + OV5640_VOLTAGE_DIGITAL_CORE);
  76741. + ret = regulator_enable(core_regulator);
  76742. + if (ret) {
  76743. + dev_err(dev, "set core voltage failed\n");
  76744. + return ret;
  76745. + } else {
  76746. + dev_dbg(dev, "set core voltage ok\n");
  76747. + }
  76748. + } else {
  76749. + core_regulator = NULL;
  76750. + dev_warn(dev, "cannot get core voltage\n");
  76751. + }
  76752. +
  76753. + analog_regulator = devm_regulator_get(dev, "AVDD");
  76754. + if (!IS_ERR(analog_regulator)) {
  76755. + regulator_set_voltage(analog_regulator,
  76756. + OV5640_VOLTAGE_ANALOG,
  76757. + OV5640_VOLTAGE_ANALOG);
  76758. + ret = regulator_enable(analog_regulator);
  76759. + if (ret) {
  76760. + dev_err(dev, "set analog voltage failed\n");
  76761. + return ret;
  76762. + } else {
  76763. + dev_dbg(dev, "set analog voltage ok\n");
  76764. + }
  76765. + } else {
  76766. + analog_regulator = NULL;
  76767. + dev_warn(dev, "cannot get analog voltage\n");
  76768. + }
  76769. +
  76770. + return ret;
  76771. +}
  76772. +
  76773. +static s32 ov5640_write_reg(u16 reg, u8 val)
  76774. +{
  76775. + u8 au8Buf[3] = {0};
  76776. +
  76777. + au8Buf[0] = reg >> 8;
  76778. + au8Buf[1] = reg & 0xff;
  76779. + au8Buf[2] = val;
  76780. +
  76781. + if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
  76782. + pr_err("%s:write reg error:reg=%x,val=%x\n",
  76783. + __func__, reg, val);
  76784. + return -1;
  76785. + }
  76786. +
  76787. + return 0;
  76788. +}
  76789. +
  76790. +static s32 ov5640_read_reg(u16 reg, u8 *val)
  76791. +{
  76792. + u8 au8RegBuf[2] = {0};
  76793. + u8 u8RdVal = 0;
  76794. +
  76795. + au8RegBuf[0] = reg >> 8;
  76796. + au8RegBuf[1] = reg & 0xff;
  76797. +
  76798. + if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
  76799. + pr_err("%s:write reg error:reg=%x\n",
  76800. + __func__, reg);
  76801. + return -1;
  76802. + }
  76803. +
  76804. + if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
  76805. + pr_err("%s:read reg error:reg=%x,val=%x\n",
  76806. + __func__, reg, u8RdVal);
  76807. + return -1;
  76808. + }
  76809. +
  76810. + *val = u8RdVal;
  76811. +
  76812. + return u8RdVal;
  76813. +}
  76814. +
  76815. +static void ov5640_soft_reset(void)
  76816. +{
  76817. + /* sysclk from pad */
  76818. + ov5640_write_reg(0x3103, 0x11);
  76819. +
  76820. + /* software reset */
  76821. + ov5640_write_reg(0x3008, 0x82);
  76822. +
  76823. + /* delay at least 5ms */
  76824. + msleep(10);
  76825. +}
  76826. +
  76827. +/* set sensor driver capability
  76828. + * 0x302c[7:6] - strength
  76829. + 00 - 1x
  76830. + 01 - 2x
  76831. + 10 - 3x
  76832. + 11 - 4x
  76833. + */
  76834. +static int ov5640_driver_capability(int strength)
  76835. +{
  76836. + u8 temp = 0;
  76837. +
  76838. + if (strength > 4 || strength < 1) {
  76839. + pr_err("The valid driver capability of ov5640 is 1x~4x\n");
  76840. + return -EINVAL;
  76841. + }
  76842. +
  76843. + ov5640_read_reg(0x302c, &temp);
  76844. +
  76845. + temp &= ~0xc0; /* clear [7:6] */
  76846. + temp |= ((strength - 1) << 6); /* set [7:6] */
  76847. +
  76848. + ov5640_write_reg(0x302c, temp);
  76849. +
  76850. + return 0;
  76851. +}
  76852. +
  76853. +/* calculate sysclk */
  76854. +static int ov5640_get_sysclk(void)
  76855. +{
  76856. + int xvclk = ov5640_data.mclk / 10000;
  76857. + int sysclk;
  76858. + int temp1, temp2;
  76859. + int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv, Bit_div2x, sclk_rdiv;
  76860. + int sclk_rdiv_map[] = {1, 2, 4, 8};
  76861. + u8 regval = 0;
  76862. +
  76863. + temp1 = ov5640_read_reg(0x3034, &regval);
  76864. + temp2 = temp1 & 0x0f;
  76865. + if (temp2 == 8 || temp2 == 10) {
  76866. + Bit_div2x = temp2 / 2;
  76867. + } else {
  76868. + pr_err("ov5640: unsupported bit mode %d\n", temp2);
  76869. + return -1;
  76870. + }
  76871. +
  76872. + temp1 = ov5640_read_reg(0x3035, &regval);
  76873. + SysDiv = temp1 >> 4;
  76874. + if (SysDiv == 0)
  76875. + SysDiv = 16;
  76876. +
  76877. + temp1 = ov5640_read_reg(0x3036, &regval);
  76878. + Multiplier = temp1;
  76879. + temp1 = ov5640_read_reg(0x3037, &regval);
  76880. + PreDiv = temp1 & 0x0f;
  76881. + Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
  76882. +
  76883. + temp1 = ov5640_read_reg(0x3108, &regval);
  76884. + temp2 = temp1 & 0x03;
  76885. +
  76886. + sclk_rdiv = sclk_rdiv_map[temp2];
  76887. + VCO = xvclk * Multiplier / PreDiv;
  76888. + sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
  76889. +
  76890. + return sysclk;
  76891. +}
  76892. +
  76893. +/* read HTS from register settings */
  76894. +static int ov5640_get_HTS(void)
  76895. +{
  76896. + int HTS;
  76897. + u8 temp = 0;
  76898. +
  76899. + HTS = ov5640_read_reg(0x380c, &temp);
  76900. + HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
  76901. + return HTS;
  76902. +}
  76903. +
  76904. +/* read VTS from register settings */
  76905. +static int ov5640_get_VTS(void)
  76906. +{
  76907. + int VTS;
  76908. + u8 temp = 0;
  76909. +
  76910. + VTS = ov5640_read_reg(0x380e, &temp);
  76911. + VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
  76912. +
  76913. + return VTS;
  76914. +}
  76915. +
  76916. +/* write VTS to registers */
  76917. +static int ov5640_set_VTS(int VTS)
  76918. +{
  76919. + int temp;
  76920. +
  76921. + temp = VTS & 0xff;
  76922. + ov5640_write_reg(0x380f, temp);
  76923. +
  76924. + temp = VTS>>8;
  76925. + ov5640_write_reg(0x380e, temp);
  76926. + return 0;
  76927. +}
  76928. +
  76929. +/* read shutter, in number of line period */
  76930. +static int ov5640_get_shutter(void)
  76931. +{
  76932. + int shutter;
  76933. + u8 regval;
  76934. +
  76935. + shutter = (ov5640_read_reg(0x03500, &regval) & 0x0f);
  76936. +
  76937. + shutter = (shutter<<8) + ov5640_read_reg(0x3501, &regval);
  76938. + shutter = (shutter<<4) + (ov5640_read_reg(0x3502, &regval)>>4);
  76939. +
  76940. + return shutter;
  76941. +}
  76942. +
  76943. +/* write shutter, in number of line period */
  76944. +static int ov5640_set_shutter(int shutter)
  76945. +{
  76946. + int temp;
  76947. +
  76948. + shutter = shutter & 0xffff;
  76949. + temp = shutter & 0x0f;
  76950. + temp = temp<<4;
  76951. + ov5640_write_reg(0x3502, temp);
  76952. +
  76953. + temp = shutter & 0xfff;
  76954. + temp = temp>>4;
  76955. + ov5640_write_reg(0x3501, temp);
  76956. +
  76957. + temp = shutter>>12;
  76958. + ov5640_write_reg(0x3500, temp);
  76959. +
  76960. + return 0;
  76961. +}
  76962. +
  76963. +/* read gain, 16 = 1x */
  76964. +static int ov5640_get_gain16(void)
  76965. +{
  76966. + int gain16;
  76967. + u8 regval;
  76968. +
  76969. + gain16 = ov5640_read_reg(0x350a, &regval) & 0x03;
  76970. + gain16 = (gain16<<8) + ov5640_read_reg(0x350b, &regval);
  76971. +
  76972. + return gain16;
  76973. +}
  76974. +
  76975. +/* write gain, 16 = 1x */
  76976. +static int ov5640_set_gain16(int gain16)
  76977. +{
  76978. + int temp;
  76979. +
  76980. + gain16 = gain16 & 0x3ff;
  76981. + temp = gain16 & 0xff;
  76982. +
  76983. + ov5640_write_reg(0x350b, temp);
  76984. + temp = gain16>>8;
  76985. +
  76986. + ov5640_write_reg(0x350a, temp);
  76987. + return 0;
  76988. +}
  76989. +
  76990. +/* get banding filter value */
  76991. +static int ov5640_get_light_freq(void)
  76992. +{
  76993. + int temp, temp1, light_frequency;
  76994. + u8 regval;
  76995. +
  76996. + temp = ov5640_read_reg(0x3c01, &regval);
  76997. + if (temp & 0x80) {
  76998. + /* manual */
  76999. + temp1 = ov5640_read_reg(0x3c00, &regval);
  77000. + if (temp1 & 0x04) {
  77001. + /* 50Hz */
  77002. + light_frequency = 50;
  77003. + } else {
  77004. + /* 60Hz */
  77005. + light_frequency = 60;
  77006. + }
  77007. + } else {
  77008. + /* auto */
  77009. + temp1 = ov5640_read_reg(0x3c0c, &regval);
  77010. + if (temp1 & 0x01) {
  77011. + /* 50Hz */
  77012. + light_frequency = 50;
  77013. + } else {
  77014. + /* 60Hz */
  77015. + light_frequency = 60;
  77016. + }
  77017. + }
  77018. +
  77019. + return light_frequency;
  77020. +}
  77021. +
  77022. +static void ov5640_set_bandingfilter(void)
  77023. +{
  77024. + int prev_VTS;
  77025. + int band_step60, max_band60, band_step50, max_band50;
  77026. +
  77027. + /* read preview PCLK */
  77028. + prev_sysclk = ov5640_get_sysclk();
  77029. +
  77030. + /* read preview HTS */
  77031. + prev_HTS = ov5640_get_HTS();
  77032. +
  77033. + /* read preview VTS */
  77034. + prev_VTS = ov5640_get_VTS();
  77035. +
  77036. + /* calculate banding filter */
  77037. + /* 60Hz */
  77038. + band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
  77039. + ov5640_write_reg(0x3a0a, (band_step60 >> 8));
  77040. + ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
  77041. +
  77042. + max_band60 = (int)((prev_VTS-4)/band_step60);
  77043. + ov5640_write_reg(0x3a0d, max_band60);
  77044. +
  77045. + /* 50Hz */
  77046. + band_step50 = prev_sysclk * 100/prev_HTS;
  77047. + ov5640_write_reg(0x3a08, (band_step50 >> 8));
  77048. + ov5640_write_reg(0x3a09, (band_step50 & 0xff));
  77049. +
  77050. + max_band50 = (int)((prev_VTS-4)/band_step50);
  77051. + ov5640_write_reg(0x3a0e, max_band50);
  77052. +}
  77053. +
  77054. +/* stable in high */
  77055. +static int ov5640_set_AE_target(int target)
  77056. +{
  77057. + int fast_high, fast_low;
  77058. +
  77059. + AE_low = target * 23 / 25; /* 0.92 */
  77060. + AE_high = target * 27 / 25; /* 1.08 */
  77061. + fast_high = AE_high << 1;
  77062. +
  77063. + if (fast_high > 255)
  77064. + fast_high = 255;
  77065. + fast_low = AE_low >> 1;
  77066. +
  77067. + ov5640_write_reg(0x3a0f, AE_high);
  77068. + ov5640_write_reg(0x3a10, AE_low);
  77069. + ov5640_write_reg(0x3a1b, AE_high);
  77070. + ov5640_write_reg(0x3a1e, AE_low);
  77071. + ov5640_write_reg(0x3a11, fast_high);
  77072. + ov5640_write_reg(0x3a1f, fast_low);
  77073. +
  77074. + return 0;
  77075. +}
  77076. +
  77077. +/* enable = 0 to turn off night mode
  77078. + enable = 1 to turn on night mode */
  77079. +static int ov5640_set_night_mode(int enable)
  77080. +{
  77081. + u8 mode;
  77082. +
  77083. + ov5640_read_reg(0x3a00, &mode);
  77084. +
  77085. + if (enable) {
  77086. + /* night mode on */
  77087. + mode |= 0x04;
  77088. + ov5640_write_reg(0x3a00, mode);
  77089. + } else {
  77090. + /* night mode off */
  77091. + mode &= 0xfb;
  77092. + ov5640_write_reg(0x3a00, mode);
  77093. + }
  77094. +
  77095. + return 0;
  77096. +}
  77097. +
  77098. +/* enable = 0 to turn off AEC/AGC
  77099. + enable = 1 to turn on AEC/AGC */
  77100. +void ov5640_turn_on_AE_AG(int enable)
  77101. +{
  77102. + u8 ae_ag_ctrl;
  77103. +
  77104. + ov5640_read_reg(0x3503, &ae_ag_ctrl);
  77105. + if (enable) {
  77106. + /* turn on auto AE/AG */
  77107. + ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
  77108. + } else {
  77109. + /* turn off AE/AG */
  77110. + ae_ag_ctrl = ae_ag_ctrl | 0x03;
  77111. + }
  77112. + ov5640_write_reg(0x3503, ae_ag_ctrl);
  77113. +}
  77114. +
  77115. +/* download ov5640 settings to sensor through i2c */
  77116. +static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
  77117. +{
  77118. + register u32 Delay_ms = 0;
  77119. + register u16 RegAddr = 0;
  77120. + register u8 Mask = 0;
  77121. + register u8 Val = 0;
  77122. + u8 RegVal = 0;
  77123. + int i, retval = 0;
  77124. +
  77125. + for (i = 0; i < ArySize; ++i, ++pModeSetting) {
  77126. + Delay_ms = pModeSetting->u32Delay_ms;
  77127. + RegAddr = pModeSetting->u16RegAddr;
  77128. + Val = pModeSetting->u8Val;
  77129. + Mask = pModeSetting->u8Mask;
  77130. +
  77131. + if (Mask) {
  77132. + retval = ov5640_read_reg(RegAddr, &RegVal);
  77133. + if (retval < 0)
  77134. + goto err;
  77135. +
  77136. + RegVal &= ~(u8)Mask;
  77137. + Val &= Mask;
  77138. + Val |= RegVal;
  77139. + }
  77140. +
  77141. + retval = ov5640_write_reg(RegAddr, Val);
  77142. + if (retval < 0)
  77143. + goto err;
  77144. +
  77145. + if (Delay_ms)
  77146. + msleep(Delay_ms);
  77147. + }
  77148. +err:
  77149. + return retval;
  77150. +}
  77151. +
  77152. +static int ov5640_init_mode(void)
  77153. +{
  77154. + struct reg_value *pModeSetting = NULL;
  77155. + int ArySize = 0, retval = 0;
  77156. +
  77157. + ov5640_soft_reset();
  77158. +
  77159. + pModeSetting = ov5640_global_init_setting;
  77160. + ArySize = ARRAY_SIZE(ov5640_global_init_setting);
  77161. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  77162. + if (retval < 0)
  77163. + goto err;
  77164. +
  77165. + pModeSetting = ov5640_init_setting_30fps_VGA;
  77166. + ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
  77167. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  77168. + if (retval < 0)
  77169. + goto err;
  77170. +
  77171. + /* change driver capability to 2x according to validation board.
  77172. + * if the image is not stable, please increase the driver strength.
  77173. + */
  77174. + ov5640_driver_capability(2);
  77175. + ov5640_set_bandingfilter();
  77176. + ov5640_set_AE_target(AE_Target);
  77177. + ov5640_set_night_mode(night_mode);
  77178. +
  77179. + /* skip 9 vysnc: start capture at 10th vsync */
  77180. + msleep(300);
  77181. +
  77182. + /* turn off night mode */
  77183. + night_mode = 0;
  77184. + ov5640_data.pix.width = 640;
  77185. + ov5640_data.pix.height = 480;
  77186. +err:
  77187. + return retval;
  77188. +}
  77189. +
  77190. +/* change to or back to subsampling mode set the mode directly
  77191. + * image size below 1280 * 960 is subsampling mode */
  77192. +static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
  77193. + enum ov5640_mode mode)
  77194. +{
  77195. + struct reg_value *pModeSetting = NULL;
  77196. + s32 ArySize = 0;
  77197. + int retval = 0;
  77198. +
  77199. + if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
  77200. + pr_err("Wrong ov5640 mode detected!\n");
  77201. + return -1;
  77202. + }
  77203. +
  77204. + pModeSetting = ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  77205. + ArySize =
  77206. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  77207. +
  77208. + ov5640_data.pix.width = ov5640_mode_info_data[frame_rate][mode].width;
  77209. + ov5640_data.pix.height = ov5640_mode_info_data[frame_rate][mode].height;
  77210. +
  77211. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  77212. + pModeSetting == NULL || ArySize == 0)
  77213. + return -EINVAL;
  77214. +
  77215. + /* set ov5640 to subsampling mode */
  77216. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  77217. +
  77218. + /* turn on AE AG for subsampling mode, in case the firmware didn't */
  77219. + ov5640_turn_on_AE_AG(1);
  77220. +
  77221. + /* calculate banding filter */
  77222. + ov5640_set_bandingfilter();
  77223. +
  77224. + /* set AE target */
  77225. + ov5640_set_AE_target(AE_Target);
  77226. +
  77227. + /* update night mode setting */
  77228. + ov5640_set_night_mode(night_mode);
  77229. +
  77230. + /* skip 9 vysnc: start capture at 10th vsync */
  77231. + if (mode == ov5640_mode_XGA_1024_768 && frame_rate == ov5640_30_fps) {
  77232. + pr_warning("ov5640: actual frame rate of XGA is 22.5fps\n");
  77233. + /* 1/22.5 * 9*/
  77234. + msleep(400);
  77235. + return retval;
  77236. + }
  77237. +
  77238. + if (frame_rate == ov5640_15_fps) {
  77239. + /* 1/15 * 9*/
  77240. + msleep(600);
  77241. + } else if (frame_rate == ov5640_30_fps) {
  77242. + /* 1/30 * 9*/
  77243. + msleep(300);
  77244. + }
  77245. +
  77246. + return retval;
  77247. +}
  77248. +
  77249. +/* change to scaling mode go through exposure calucation
  77250. + * image size above 1280 * 960 is scaling mode */
  77251. +static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
  77252. + enum ov5640_mode mode)
  77253. +{
  77254. + int prev_shutter, prev_gain16, average;
  77255. + int cap_shutter, cap_gain16;
  77256. + int cap_sysclk, cap_HTS, cap_VTS;
  77257. + int light_freq, cap_bandfilt, cap_maxband;
  77258. + long cap_gain16_shutter;
  77259. + u8 temp;
  77260. + struct reg_value *pModeSetting = NULL;
  77261. + s32 ArySize = 0;
  77262. + int retval = 0;
  77263. +
  77264. + /* check if the input mode and frame rate is valid */
  77265. + pModeSetting =
  77266. + ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  77267. + ArySize =
  77268. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  77269. +
  77270. + ov5640_data.pix.width =
  77271. + ov5640_mode_info_data[frame_rate][mode].width;
  77272. + ov5640_data.pix.height =
  77273. + ov5640_mode_info_data[frame_rate][mode].height;
  77274. +
  77275. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  77276. + pModeSetting == NULL || ArySize == 0)
  77277. + return -EINVAL;
  77278. +
  77279. + /* read preview shutter */
  77280. + prev_shutter = ov5640_get_shutter();
  77281. +
  77282. + /* read preview gain */
  77283. + prev_gain16 = ov5640_get_gain16();
  77284. +
  77285. + /* get average */
  77286. + average = ov5640_read_reg(0x56a1, &temp);
  77287. +
  77288. + /* turn off night mode for capture */
  77289. + ov5640_set_night_mode(0);
  77290. +
  77291. + /* turn off overlay */
  77292. + ov5640_write_reg(0x3022, 0x06);
  77293. +
  77294. + /* Write capture setting */
  77295. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  77296. + if (retval < 0)
  77297. + goto err;
  77298. +
  77299. + /* turn off AE AG when capture image. */
  77300. + ov5640_turn_on_AE_AG(0);
  77301. +
  77302. + /* read capture VTS */
  77303. + cap_VTS = ov5640_get_VTS();
  77304. + cap_HTS = ov5640_get_HTS();
  77305. + cap_sysclk = ov5640_get_sysclk();
  77306. +
  77307. + /* calculate capture banding filter */
  77308. + light_freq = ov5640_get_light_freq();
  77309. + if (light_freq == 60) {
  77310. + /* 60Hz */
  77311. + cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
  77312. + } else {
  77313. + /* 50Hz */
  77314. + cap_bandfilt = cap_sysclk * 100 / cap_HTS;
  77315. + }
  77316. + cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
  77317. + /* calculate capture shutter/gain16 */
  77318. + if (average > AE_low && average < AE_high) {
  77319. + /* in stable range */
  77320. + cap_gain16_shutter =
  77321. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
  77322. + prev_HTS/cap_HTS * AE_Target / average;
  77323. + } else {
  77324. + cap_gain16_shutter =
  77325. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
  77326. + prev_HTS/cap_HTS;
  77327. + }
  77328. +
  77329. + /* gain to shutter */
  77330. + if (cap_gain16_shutter < (cap_bandfilt * 16)) {
  77331. + /* shutter < 1/100 */
  77332. + cap_shutter = cap_gain16_shutter/16;
  77333. + if (cap_shutter < 1)
  77334. + cap_shutter = 1;
  77335. + cap_gain16 = cap_gain16_shutter/cap_shutter;
  77336. + if (cap_gain16 < 16)
  77337. + cap_gain16 = 16;
  77338. + } else {
  77339. + if (cap_gain16_shutter > (cap_bandfilt*cap_maxband*16)) {
  77340. + /* exposure reach max */
  77341. + cap_shutter = cap_bandfilt*cap_maxband;
  77342. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  77343. + } else {
  77344. + /* 1/100 < cap_shutter =< max, cap_shutter = n/100 */
  77345. + cap_shutter =
  77346. + ((int)(cap_gain16_shutter/16/cap_bandfilt))
  77347. + * cap_bandfilt;
  77348. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  77349. + }
  77350. + }
  77351. +
  77352. + /* write capture gain */
  77353. + ov5640_set_gain16(cap_gain16);
  77354. +
  77355. + /* write capture shutter */
  77356. + if (cap_shutter > (cap_VTS - 4)) {
  77357. + cap_VTS = cap_shutter + 4;
  77358. + ov5640_set_VTS(cap_VTS);
  77359. + }
  77360. +
  77361. + ov5640_set_shutter(cap_shutter);
  77362. +
  77363. + /* skip 2 vysnc: start capture at 3rd vsync
  77364. + * frame rate of QSXGA and 1080P is 7.5fps: 1/7.5 * 2
  77365. + */
  77366. + pr_warning("ov5640: the actual frame rate of %s is 7.5fps\n",
  77367. + mode == ov5640_mode_1080P_1920_1080 ? "1080P" : "QSXGA");
  77368. + msleep(267);
  77369. +err:
  77370. + return retval;
  77371. +}
  77372. +
  77373. +static int ov5640_change_mode(enum ov5640_frame_rate frame_rate,
  77374. + enum ov5640_mode mode)
  77375. +{
  77376. + int retval = 0;
  77377. +
  77378. + if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
  77379. + pr_err("Wrong ov5640 mode detected!\n");
  77380. + return -1;
  77381. + }
  77382. +
  77383. + if (mode == ov5640_mode_1080P_1920_1080 ||
  77384. + mode == ov5640_mode_QSXGA_2592_1944) {
  77385. + /* change to scaling mode go through exposure calucation
  77386. + * image size above 1280 * 960 is scaling mode */
  77387. + retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
  77388. + } else {
  77389. + /* change back to subsampling modem download firmware directly
  77390. + * image size below 1280 * 960 is subsampling mode */
  77391. + retval = ov5640_change_mode_direct(frame_rate, mode);
  77392. + }
  77393. +
  77394. + return retval;
  77395. +}
  77396. +
  77397. +/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
  77398. +
  77399. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  77400. +{
  77401. + if (s == NULL) {
  77402. + pr_err(" ERROR!! no slave device set!\n");
  77403. + return -1;
  77404. + }
  77405. +
  77406. + memset(p, 0, sizeof(*p));
  77407. + p->u.bt656.clock_curr = ov5640_data.mclk;
  77408. + pr_debug(" clock_curr=mclk=%d\n", ov5640_data.mclk);
  77409. + p->if_type = V4L2_IF_TYPE_BT656;
  77410. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  77411. + p->u.bt656.clock_min = OV5640_XCLK_MIN;
  77412. + p->u.bt656.clock_max = OV5640_XCLK_MAX;
  77413. + p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
  77414. +
  77415. + return 0;
  77416. +}
  77417. +
  77418. +/*!
  77419. + * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
  77420. + * @s: pointer to standard V4L2 device structure
  77421. + * @on: indicates power mode (on or off)
  77422. + *
  77423. + * Turns the power on or off, depending on the value of on and returns the
  77424. + * appropriate error code.
  77425. + */
  77426. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  77427. +{
  77428. + struct sensor_data *sensor = s->priv;
  77429. +
  77430. + if (on && !sensor->on) {
  77431. + if (io_regulator)
  77432. + if (regulator_enable(io_regulator) != 0)
  77433. + return -EIO;
  77434. + if (core_regulator)
  77435. + if (regulator_enable(core_regulator) != 0)
  77436. + return -EIO;
  77437. + if (analog_regulator)
  77438. + if (regulator_enable(analog_regulator) != 0)
  77439. + return -EIO;
  77440. + /* Make sure power on */
  77441. + ov5640_power_down(0);
  77442. + } else if (!on && sensor->on) {
  77443. + if (analog_regulator)
  77444. + regulator_disable(analog_regulator);
  77445. + if (core_regulator)
  77446. + regulator_disable(core_regulator);
  77447. + if (io_regulator)
  77448. + regulator_disable(io_regulator);
  77449. +
  77450. + ov5640_power_down(1);
  77451. +}
  77452. +
  77453. + sensor->on = on;
  77454. +
  77455. + return 0;
  77456. +}
  77457. +
  77458. +/*!
  77459. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  77460. + * @s: pointer to standard V4L2 device structure
  77461. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  77462. + *
  77463. + * Returns the sensor's video CAPTURE parameters.
  77464. + */
  77465. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  77466. +{
  77467. + struct sensor_data *sensor = s->priv;
  77468. + struct v4l2_captureparm *cparm = &a->parm.capture;
  77469. + int ret = 0;
  77470. +
  77471. + switch (a->type) {
  77472. + /* This is the only case currently handled. */
  77473. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  77474. + memset(a, 0, sizeof(*a));
  77475. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  77476. + cparm->capability = sensor->streamcap.capability;
  77477. + cparm->timeperframe = sensor->streamcap.timeperframe;
  77478. + cparm->capturemode = sensor->streamcap.capturemode;
  77479. + ret = 0;
  77480. + break;
  77481. +
  77482. + /* These are all the possible cases. */
  77483. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  77484. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  77485. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  77486. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  77487. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  77488. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  77489. + ret = -EINVAL;
  77490. + break;
  77491. +
  77492. + default:
  77493. + pr_debug(" type is unknown - %d\n", a->type);
  77494. + ret = -EINVAL;
  77495. + break;
  77496. + }
  77497. +
  77498. + return ret;
  77499. +}
  77500. +
  77501. +/*!
  77502. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  77503. + * @s: pointer to standard V4L2 device structure
  77504. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  77505. + *
  77506. + * Configures the sensor to use the input parameters, if possible. If
  77507. + * not possible, reverts to the old parameters and returns the
  77508. + * appropriate error code.
  77509. + */
  77510. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  77511. +{
  77512. + struct sensor_data *sensor = s->priv;
  77513. + struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
  77514. + u32 tgt_fps; /* target frames per secound */
  77515. + enum ov5640_frame_rate frame_rate;
  77516. + int ret = 0;
  77517. +
  77518. + /* Make sure power on */
  77519. + ov5640_power_down(0);
  77520. +
  77521. + switch (a->type) {
  77522. + /* This is the only case currently handled. */
  77523. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  77524. + /* Check that the new frame rate is allowed. */
  77525. + if ((timeperframe->numerator == 0) ||
  77526. + (timeperframe->denominator == 0)) {
  77527. + timeperframe->denominator = DEFAULT_FPS;
  77528. + timeperframe->numerator = 1;
  77529. + }
  77530. +
  77531. + tgt_fps = timeperframe->denominator /
  77532. + timeperframe->numerator;
  77533. +
  77534. + if (tgt_fps > MAX_FPS) {
  77535. + timeperframe->denominator = MAX_FPS;
  77536. + timeperframe->numerator = 1;
  77537. + } else if (tgt_fps < MIN_FPS) {
  77538. + timeperframe->denominator = MIN_FPS;
  77539. + timeperframe->numerator = 1;
  77540. + }
  77541. +
  77542. + /* Actual frame rate we use */
  77543. + tgt_fps = timeperframe->denominator /
  77544. + timeperframe->numerator;
  77545. +
  77546. + if (tgt_fps == 15)
  77547. + frame_rate = ov5640_15_fps;
  77548. + else if (tgt_fps == 30)
  77549. + frame_rate = ov5640_30_fps;
  77550. + else {
  77551. + pr_err(" The camera frame rate is not supported!\n");
  77552. + return -EINVAL;
  77553. + }
  77554. +
  77555. + ret = ov5640_change_mode(frame_rate,
  77556. + a->parm.capture.capturemode);
  77557. + if (ret < 0)
  77558. + return ret;
  77559. +
  77560. + sensor->streamcap.timeperframe = *timeperframe;
  77561. + sensor->streamcap.capturemode = a->parm.capture.capturemode;
  77562. +
  77563. + break;
  77564. +
  77565. + /* These are all the possible cases. */
  77566. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  77567. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  77568. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  77569. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  77570. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  77571. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  77572. + pr_debug(" type is not " \
  77573. + "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
  77574. + a->type);
  77575. + ret = -EINVAL;
  77576. + break;
  77577. +
  77578. + default:
  77579. + pr_debug(" type is unknown - %d\n", a->type);
  77580. + ret = -EINVAL;
  77581. + break;
  77582. + }
  77583. +
  77584. + return ret;
  77585. +}
  77586. +
  77587. +/*!
  77588. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  77589. + * @s: pointer to standard V4L2 device structure
  77590. + * @f: pointer to standard V4L2 v4l2_format structure
  77591. + *
  77592. + * Returns the sensor's current pixel format in the v4l2_format
  77593. + * parameter.
  77594. + */
  77595. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  77596. +{
  77597. + struct sensor_data *sensor = s->priv;
  77598. +
  77599. + f->fmt.pix = sensor->pix;
  77600. +
  77601. + return 0;
  77602. +}
  77603. +
  77604. +/*!
  77605. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  77606. + * @s: pointer to standard V4L2 device structure
  77607. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  77608. + *
  77609. + * If the requested control is supported, returns the control's current
  77610. + * value from the video_control[] array. Otherwise, returns -EINVAL
  77611. + * if the control is not supported.
  77612. + */
  77613. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  77614. +{
  77615. + int ret = 0;
  77616. +
  77617. + switch (vc->id) {
  77618. + case V4L2_CID_BRIGHTNESS:
  77619. + vc->value = ov5640_data.brightness;
  77620. + break;
  77621. + case V4L2_CID_HUE:
  77622. + vc->value = ov5640_data.hue;
  77623. + break;
  77624. + case V4L2_CID_CONTRAST:
  77625. + vc->value = ov5640_data.contrast;
  77626. + break;
  77627. + case V4L2_CID_SATURATION:
  77628. + vc->value = ov5640_data.saturation;
  77629. + break;
  77630. + case V4L2_CID_RED_BALANCE:
  77631. + vc->value = ov5640_data.red;
  77632. + break;
  77633. + case V4L2_CID_BLUE_BALANCE:
  77634. + vc->value = ov5640_data.blue;
  77635. + break;
  77636. + case V4L2_CID_EXPOSURE:
  77637. + vc->value = ov5640_data.ae_mode;
  77638. + break;
  77639. + default:
  77640. + ret = -EINVAL;
  77641. + }
  77642. +
  77643. + return ret;
  77644. +}
  77645. +
  77646. +/*!
  77647. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  77648. + * @s: pointer to standard V4L2 device structure
  77649. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  77650. + *
  77651. + * If the requested control is supported, sets the control's current
  77652. + * value in HW (and updates the video_control[] array). Otherwise,
  77653. + * returns -EINVAL if the control is not supported.
  77654. + */
  77655. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  77656. +{
  77657. + int retval = 0;
  77658. +
  77659. + pr_debug("In ov5640:ioctl_s_ctrl %d\n",
  77660. + vc->id);
  77661. +
  77662. + switch (vc->id) {
  77663. + case V4L2_CID_BRIGHTNESS:
  77664. + break;
  77665. + case V4L2_CID_CONTRAST:
  77666. + break;
  77667. + case V4L2_CID_SATURATION:
  77668. + break;
  77669. + case V4L2_CID_HUE:
  77670. + break;
  77671. + case V4L2_CID_AUTO_WHITE_BALANCE:
  77672. + break;
  77673. + case V4L2_CID_DO_WHITE_BALANCE:
  77674. + break;
  77675. + case V4L2_CID_RED_BALANCE:
  77676. + break;
  77677. + case V4L2_CID_BLUE_BALANCE:
  77678. + break;
  77679. + case V4L2_CID_GAMMA:
  77680. + break;
  77681. + case V4L2_CID_EXPOSURE:
  77682. + break;
  77683. + case V4L2_CID_AUTOGAIN:
  77684. + break;
  77685. + case V4L2_CID_GAIN:
  77686. + break;
  77687. + case V4L2_CID_HFLIP:
  77688. + break;
  77689. + case V4L2_CID_VFLIP:
  77690. + break;
  77691. + default:
  77692. + retval = -EPERM;
  77693. + break;
  77694. + }
  77695. +
  77696. + return retval;
  77697. +}
  77698. +
  77699. +/*!
  77700. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  77701. + * VIDIOC_ENUM_FRAMESIZES ioctl
  77702. + * @s: pointer to standard V4L2 device structure
  77703. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  77704. + *
  77705. + * Return 0 if successful, otherwise -EINVAL.
  77706. + */
  77707. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  77708. + struct v4l2_frmsizeenum *fsize)
  77709. +{
  77710. + if (fsize->index > ov5640_mode_MAX)
  77711. + return -EINVAL;
  77712. +
  77713. + fsize->pixel_format = ov5640_data.pix.pixelformat;
  77714. + fsize->discrete.width =
  77715. + max(ov5640_mode_info_data[0][fsize->index].width,
  77716. + ov5640_mode_info_data[1][fsize->index].width);
  77717. + fsize->discrete.height =
  77718. + max(ov5640_mode_info_data[0][fsize->index].height,
  77719. + ov5640_mode_info_data[1][fsize->index].height);
  77720. + return 0;
  77721. +}
  77722. +
  77723. +/*!
  77724. + * ioctl_enum_frameintervals - V4L2 sensor interface handler for
  77725. + * VIDIOC_ENUM_FRAMEINTERVALS ioctl
  77726. + * @s: pointer to standard V4L2 device structure
  77727. + * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
  77728. + *
  77729. + * Return 0 if successful, otherwise -EINVAL.
  77730. + */
  77731. +static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
  77732. + struct v4l2_frmivalenum *fival)
  77733. +{
  77734. + int i, j, count;
  77735. +
  77736. + if (fival->index < 0 || fival->index > ov5640_mode_MAX)
  77737. + return -EINVAL;
  77738. +
  77739. + if (fival->width == 0 || fival->height == 0 ||
  77740. + fival->pixel_format == 0) {
  77741. + pr_warning("Please assign pixelformat, width and height.\n");
  77742. + return -EINVAL;
  77743. + }
  77744. +
  77745. + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
  77746. + fival->discrete.numerator = 1;
  77747. +
  77748. + count = 0;
  77749. + for (i = 0; i < ARRAY_SIZE(ov5640_mode_info_data); i++) {
  77750. + for (j = 0; j < (ov5640_mode_MAX + 1); j++) {
  77751. + if (fival->pixel_format == ov5640_data.pix.pixelformat
  77752. + && fival->width == ov5640_mode_info_data[i][j].width
  77753. + && fival->height == ov5640_mode_info_data[i][j].height
  77754. + && ov5640_mode_info_data[i][j].init_data_ptr != NULL) {
  77755. + count++;
  77756. + }
  77757. + if (fival->index == (count - 1)) {
  77758. + fival->discrete.denominator =
  77759. + ov5640_framerates[i];
  77760. + return 0;
  77761. + }
  77762. + }
  77763. + }
  77764. +
  77765. + return -EINVAL;
  77766. +}
  77767. +
  77768. +/*!
  77769. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  77770. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  77771. + * @s: pointer to standard V4L2 device structure
  77772. + * @id: pointer to int
  77773. + *
  77774. + * Return 0.
  77775. + */
  77776. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  77777. +{
  77778. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  77779. + V4L2_CHIP_MATCH_I2C_DRIVER;
  77780. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name, "ov5640_camera");
  77781. +
  77782. + return 0;
  77783. +}
  77784. +
  77785. +/*!
  77786. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  77787. + * @s: pointer to standard V4L2 device structure
  77788. + */
  77789. +static int ioctl_init(struct v4l2_int_device *s)
  77790. +{
  77791. +
  77792. + return 0;
  77793. +}
  77794. +
  77795. +/*!
  77796. + * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
  77797. + * @s: pointer to standard V4L2 device structure
  77798. + * @fmt: pointer to standard V4L2 fmt description structure
  77799. + *
  77800. + * Return 0.
  77801. + */
  77802. +static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
  77803. + struct v4l2_fmtdesc *fmt)
  77804. +{
  77805. + if (fmt->index > ov5640_mode_MAX)
  77806. + return -EINVAL;
  77807. +
  77808. + fmt->pixelformat = ov5640_data.pix.pixelformat;
  77809. +
  77810. + return 0;
  77811. +}
  77812. +
  77813. +/*!
  77814. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  77815. + * @s: pointer to standard V4L2 device structure
  77816. + *
  77817. + * Initialise the device when slave attaches to the master.
  77818. + */
  77819. +static int ioctl_dev_init(struct v4l2_int_device *s)
  77820. +{
  77821. + struct sensor_data *sensor = s->priv;
  77822. + u32 tgt_xclk; /* target xclk */
  77823. + u32 tgt_fps; /* target frames per secound */
  77824. + enum ov5640_frame_rate frame_rate;
  77825. + int ret;
  77826. +
  77827. + ov5640_data.on = true;
  77828. +
  77829. + /* mclk */
  77830. + tgt_xclk = ov5640_data.mclk;
  77831. + tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
  77832. + tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
  77833. + ov5640_data.mclk = tgt_xclk;
  77834. +
  77835. + pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
  77836. + clk_set_rate(ov5640_data.sensor_clk, ov5640_data.mclk);
  77837. +
  77838. + /* Default camera frame rate is set in probe */
  77839. + tgt_fps = sensor->streamcap.timeperframe.denominator /
  77840. + sensor->streamcap.timeperframe.numerator;
  77841. +
  77842. + if (tgt_fps == 15)
  77843. + frame_rate = ov5640_15_fps;
  77844. + else if (tgt_fps == 30)
  77845. + frame_rate = ov5640_30_fps;
  77846. + else
  77847. + return -EINVAL; /* Only support 15fps or 30fps now. */
  77848. +
  77849. + ret = ov5640_init_mode();
  77850. + return ret;
  77851. +}
  77852. +
  77853. +/*!
  77854. + * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
  77855. + * @s: pointer to standard V4L2 device structure
  77856. + *
  77857. + * Delinitialise the device when slave detaches to the master.
  77858. + */
  77859. +static int ioctl_dev_exit(struct v4l2_int_device *s)
  77860. +{
  77861. + return 0;
  77862. +}
  77863. +
  77864. +/*!
  77865. + * This structure defines all the ioctls for this module and links them to the
  77866. + * enumeration.
  77867. + */
  77868. +static struct v4l2_int_ioctl_desc ov5640_ioctl_desc[] = {
  77869. + { vidioc_int_dev_init_num,
  77870. + (v4l2_int_ioctl_func *)ioctl_dev_init },
  77871. + { vidioc_int_dev_exit_num,
  77872. + ioctl_dev_exit},
  77873. + { vidioc_int_s_power_num,
  77874. + (v4l2_int_ioctl_func *)ioctl_s_power },
  77875. + { vidioc_int_g_ifparm_num,
  77876. + (v4l2_int_ioctl_func *)ioctl_g_ifparm },
  77877. + { vidioc_int_init_num,
  77878. + (v4l2_int_ioctl_func *)ioctl_init },
  77879. + { vidioc_int_enum_fmt_cap_num,
  77880. + (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
  77881. + { vidioc_int_g_fmt_cap_num,
  77882. + (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
  77883. + { vidioc_int_g_parm_num,
  77884. + (v4l2_int_ioctl_func *)ioctl_g_parm },
  77885. + { vidioc_int_s_parm_num,
  77886. + (v4l2_int_ioctl_func *)ioctl_s_parm },
  77887. + { vidioc_int_g_ctrl_num,
  77888. + (v4l2_int_ioctl_func *)ioctl_g_ctrl },
  77889. + { vidioc_int_s_ctrl_num,
  77890. + (v4l2_int_ioctl_func *)ioctl_s_ctrl },
  77891. + { vidioc_int_enum_framesizes_num,
  77892. + (v4l2_int_ioctl_func *)ioctl_enum_framesizes },
  77893. + { vidioc_int_enum_frameintervals_num,
  77894. + (v4l2_int_ioctl_func *)ioctl_enum_frameintervals },
  77895. + { vidioc_int_g_chip_ident_num,
  77896. + (v4l2_int_ioctl_func *)ioctl_g_chip_ident },
  77897. +};
  77898. +
  77899. +static struct v4l2_int_slave ov5640_slave = {
  77900. + .ioctls = ov5640_ioctl_desc,
  77901. + .num_ioctls = ARRAY_SIZE(ov5640_ioctl_desc),
  77902. +};
  77903. +
  77904. +static struct v4l2_int_device ov5640_int_device = {
  77905. + .module = THIS_MODULE,
  77906. + .name = "ov5640",
  77907. + .type = v4l2_int_type_slave,
  77908. + .u = {
  77909. + .slave = &ov5640_slave,
  77910. + },
  77911. +};
  77912. +
  77913. +/*!
  77914. + * ov5640 I2C probe function
  77915. + *
  77916. + * @param adapter struct i2c_adapter *
  77917. + * @return Error code indicating success or failure
  77918. + */
  77919. +static int ov5640_probe(struct i2c_client *client,
  77920. + const struct i2c_device_id *id)
  77921. +{
  77922. + struct pinctrl *pinctrl;
  77923. + struct device *dev = &client->dev;
  77924. + int retval;
  77925. + u8 chip_id_high, chip_id_low;
  77926. +
  77927. + /* ov5640 pinctrl */
  77928. + pinctrl = devm_pinctrl_get_select_default(dev);
  77929. + if (IS_ERR(pinctrl)) {
  77930. + dev_err(dev, "setup pinctrl failed\n");
  77931. + return PTR_ERR(pinctrl);
  77932. + }
  77933. +
  77934. + /* request power down pin */
  77935. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  77936. + if (!gpio_is_valid(pwn_gpio)) {
  77937. + dev_err(dev, "no sensor pwdn pin available\n");
  77938. + return -ENODEV;
  77939. + }
  77940. + retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  77941. + "ov5640_pwdn");
  77942. + if (retval < 0)
  77943. + return retval;
  77944. +
  77945. + /* request reset pin */
  77946. + rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
  77947. + if (!gpio_is_valid(rst_gpio)) {
  77948. + dev_err(dev, "no sensor reset pin available\n");
  77949. + return -EINVAL;
  77950. + }
  77951. + retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
  77952. + "ov5640_reset");
  77953. + if (retval < 0)
  77954. + return retval;
  77955. +
  77956. + /* Set initial values for the sensor struct. */
  77957. + memset(&ov5640_data, 0, sizeof(ov5640_data));
  77958. + ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
  77959. + if (IS_ERR(ov5640_data.sensor_clk)) {
  77960. + dev_err(dev, "get mclk failed\n");
  77961. + return PTR_ERR(ov5640_data.sensor_clk);
  77962. + }
  77963. +
  77964. + retval = of_property_read_u32(dev->of_node, "mclk",
  77965. + &ov5640_data.mclk);
  77966. + if (retval) {
  77967. + dev_err(dev, "mclk frequency is invalid\n");
  77968. + return retval;
  77969. + }
  77970. +
  77971. + retval = of_property_read_u32(dev->of_node, "mclk_source",
  77972. + (u32 *) &(ov5640_data.mclk_source));
  77973. + if (retval) {
  77974. + dev_err(dev, "mclk_source invalid\n");
  77975. + return retval;
  77976. + }
  77977. +
  77978. + retval = of_property_read_u32(dev->of_node, "csi_id",
  77979. + &(ov5640_data.csi));
  77980. + if (retval) {
  77981. + dev_err(dev, "csi_id invalid\n");
  77982. + return retval;
  77983. + }
  77984. +
  77985. + clk_prepare_enable(ov5640_data.sensor_clk);
  77986. +
  77987. + ov5640_data.io_init = ov5640_reset;
  77988. + ov5640_data.i2c_client = client;
  77989. + ov5640_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  77990. + ov5640_data.pix.width = 640;
  77991. + ov5640_data.pix.height = 480;
  77992. + ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
  77993. + V4L2_CAP_TIMEPERFRAME;
  77994. + ov5640_data.streamcap.capturemode = 0;
  77995. + ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
  77996. + ov5640_data.streamcap.timeperframe.numerator = 1;
  77997. +
  77998. + ov5640_regulator_enable(&client->dev);
  77999. +
  78000. + ov5640_reset();
  78001. +
  78002. + ov5640_power_down(0);
  78003. +
  78004. + retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
  78005. + if (retval < 0 || chip_id_high != 0x56) {
  78006. + clk_disable_unprepare(ov5640_data.sensor_clk);
  78007. + pr_warning("camera ov5640 is not found\n");
  78008. + return -ENODEV;
  78009. + }
  78010. + retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
  78011. + if (retval < 0 || chip_id_low != 0x40) {
  78012. + clk_disable_unprepare(ov5640_data.sensor_clk);
  78013. + pr_warning("camera ov5640 is not found\n");
  78014. + return -ENODEV;
  78015. + }
  78016. +
  78017. + ov5640_power_down(1);
  78018. +
  78019. + clk_disable_unprepare(ov5640_data.sensor_clk);
  78020. +
  78021. + ov5640_int_device.priv = &ov5640_data;
  78022. + retval = v4l2_int_device_register(&ov5640_int_device);
  78023. +
  78024. + pr_info("camera ov5640 is found\n");
  78025. + return retval;
  78026. +}
  78027. +
  78028. +/*!
  78029. + * ov5640 I2C detach function
  78030. + *
  78031. + * @param client struct i2c_client *
  78032. + * @return Error code indicating success or failure
  78033. + */
  78034. +static int ov5640_remove(struct i2c_client *client)
  78035. +{
  78036. + v4l2_int_device_unregister(&ov5640_int_device);
  78037. +
  78038. + if (analog_regulator)
  78039. + regulator_disable(analog_regulator);
  78040. +
  78041. + if (core_regulator)
  78042. + regulator_disable(core_regulator);
  78043. +
  78044. + if (io_regulator)
  78045. + regulator_disable(io_regulator);
  78046. +
  78047. + return 0;
  78048. +}
  78049. +
  78050. +module_i2c_driver(ov5640_i2c_driver);
  78051. +
  78052. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  78053. +MODULE_DESCRIPTION("OV5640 Camera Driver");
  78054. +MODULE_LICENSE("GPL");
  78055. +MODULE_VERSION("1.0");
  78056. +MODULE_ALIAS("CSI");
  78057. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/ov5640_mipi.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ov5640_mipi.c
  78058. --- linux-3.14.15/drivers/media/platform/mxc/capture/ov5640_mipi.c 1970-01-01 01:00:00.000000000 +0100
  78059. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ov5640_mipi.c 2014-08-20 19:23:52.818842679 +0200
  78060. @@ -0,0 +1,2104 @@
  78061. +/*
  78062. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  78063. + */
  78064. +
  78065. +/*
  78066. + * This program is free software; you can redistribute it and/or modify
  78067. + * it under the terms of the GNU General Public License as published by
  78068. + * the Free Software Foundation; either version 2 of the License, or
  78069. + * (at your option) any later version.
  78070. +
  78071. + * This program is distributed in the hope that it will be useful,
  78072. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  78073. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  78074. + * GNU General Public License for more details.
  78075. +
  78076. + * You should have received a copy of the GNU General Public License along
  78077. + * with this program; if not, write to the Free Software Foundation, Inc.,
  78078. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  78079. + */
  78080. +
  78081. +#include <linux/module.h>
  78082. +#include <linux/init.h>
  78083. +#include <linux/slab.h>
  78084. +#include <linux/ctype.h>
  78085. +#include <linux/types.h>
  78086. +#include <linux/delay.h>
  78087. +#include <linux/clk.h>
  78088. +#include <linux/of_device.h>
  78089. +#include <linux/i2c.h>
  78090. +#include <linux/of_gpio.h>
  78091. +#include <linux/pinctrl/consumer.h>
  78092. +#include <linux/regulator/consumer.h>
  78093. +#include <linux/fsl_devices.h>
  78094. +#include <linux/mipi_csi2.h>
  78095. +#include <media/v4l2-chip-ident.h>
  78096. +#include <media/v4l2-int-device.h>
  78097. +#include "mxc_v4l2_capture.h"
  78098. +
  78099. +#define OV5640_VOLTAGE_ANALOG 2800000
  78100. +#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
  78101. +#define OV5640_VOLTAGE_DIGITAL_IO 1800000
  78102. +
  78103. +#define MIN_FPS 15
  78104. +#define MAX_FPS 30
  78105. +#define DEFAULT_FPS 30
  78106. +
  78107. +#define OV5640_XCLK_MIN 6000000
  78108. +#define OV5640_XCLK_MAX 24000000
  78109. +
  78110. +#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
  78111. +#define OV5640_CHIP_ID_LOW_BYTE 0x300B
  78112. +
  78113. +enum ov5640_mode {
  78114. + ov5640_mode_MIN = 0,
  78115. + ov5640_mode_VGA_640_480 = 0,
  78116. + ov5640_mode_QVGA_320_240 = 1,
  78117. + ov5640_mode_NTSC_720_480 = 2,
  78118. + ov5640_mode_PAL_720_576 = 3,
  78119. + ov5640_mode_720P_1280_720 = 4,
  78120. + ov5640_mode_1080P_1920_1080 = 5,
  78121. + ov5640_mode_QSXGA_2592_1944 = 6,
  78122. + ov5640_mode_QCIF_176_144 = 7,
  78123. + ov5640_mode_XGA_1024_768 = 8,
  78124. + ov5640_mode_MAX = 8,
  78125. + ov5640_mode_INIT = 0xff, /*only for sensor init*/
  78126. +};
  78127. +
  78128. +enum ov5640_frame_rate {
  78129. + ov5640_15_fps,
  78130. + ov5640_30_fps
  78131. +};
  78132. +
  78133. +/* image size under 1280 * 960 are SUBSAMPLING
  78134. + * image size upper 1280 * 960 are SCALING
  78135. + */
  78136. +enum ov5640_downsize_mode {
  78137. + SUBSAMPLING,
  78138. + SCALING,
  78139. +};
  78140. +
  78141. +struct reg_value {
  78142. + u16 u16RegAddr;
  78143. + u8 u8Val;
  78144. + u8 u8Mask;
  78145. + u32 u32Delay_ms;
  78146. +};
  78147. +
  78148. +struct ov5640_mode_info {
  78149. + enum ov5640_mode mode;
  78150. + enum ov5640_downsize_mode dn_mode;
  78151. + u32 width;
  78152. + u32 height;
  78153. + struct reg_value *init_data_ptr;
  78154. + u32 init_data_size;
  78155. +};
  78156. +
  78157. +/*!
  78158. + * Maintains the information on the current state of the sesor.
  78159. + */
  78160. +static struct sensor_data ov5640_data;
  78161. +static int pwn_gpio, rst_gpio;
  78162. +
  78163. +static struct reg_value ov5640_init_setting_30fps_VGA[] = {
  78164. +
  78165. + {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
  78166. + {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
  78167. + {0x3034, 0x18, 0, 0}, {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0},
  78168. + {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
  78169. + {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
  78170. + {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
  78171. + {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
  78172. + {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
  78173. + {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
  78174. + {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
  78175. + {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
  78176. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
  78177. + {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
  78178. + {0x3c01, 0xa4, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
  78179. + {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
  78180. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78181. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78182. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78183. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78184. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78185. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  78186. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78187. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78188. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78189. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78190. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78191. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78192. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78193. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78194. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
  78195. + {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
  78196. + {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
  78197. + {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
  78198. + {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78199. + {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
  78200. + {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
  78201. + {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
  78202. + {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
  78203. + {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0},
  78204. + {0x518a, 0x54, 0, 0}, {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0},
  78205. + {0x518d, 0x50, 0, 0}, {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0},
  78206. + {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
  78207. + {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
  78208. + {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
  78209. + {0x5199, 0x6c, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
  78210. + {0x519c, 0x09, 0, 0}, {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0},
  78211. + {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
  78212. + {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
  78213. + {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
  78214. + {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
  78215. + {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
  78216. + {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
  78217. + {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
  78218. + {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
  78219. + {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
  78220. + {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
  78221. + {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
  78222. + {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
  78223. + {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
  78224. + {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
  78225. + {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
  78226. + {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
  78227. + {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
  78228. + {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
  78229. + {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
  78230. + {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
  78231. + {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
  78232. + {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
  78233. + {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
  78234. + {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
  78235. + {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
  78236. + {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
  78237. + {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
  78238. + {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
  78239. + {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
  78240. + {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
  78241. + {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
  78242. + {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
  78243. + {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
  78244. + {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
  78245. + {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
  78246. + {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
  78247. + {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
  78248. + {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
  78249. + {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3c00, 0x04, 0, 300},
  78250. +};
  78251. +
  78252. +static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
  78253. +
  78254. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78255. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78256. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78257. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78258. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78259. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78260. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  78261. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78262. + {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
  78263. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78264. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78265. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78266. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
  78267. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78268. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78269. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78270. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78271. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
  78272. +};
  78273. +
  78274. +static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
  78275. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78276. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78277. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78278. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78279. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78280. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78281. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  78282. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78283. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78284. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78285. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78286. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78287. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78288. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78289. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78290. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78291. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78292. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78293. +};
  78294. +
  78295. +static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
  78296. +
  78297. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78298. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78299. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78300. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78301. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78302. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78303. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  78304. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78305. + {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
  78306. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78307. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78308. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78309. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
  78310. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78311. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78312. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78313. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78314. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
  78315. + {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
  78316. + {0x380b, 0x00, 0, 0}, {0x3035, 0x12, 0, 0},
  78317. +};
  78318. +
  78319. +static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
  78320. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78321. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78322. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78323. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78324. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78325. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78326. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  78327. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78328. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78329. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78330. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78331. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78332. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78333. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78334. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78335. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78336. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78337. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3808, 0x04, 0, 0},
  78338. + {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0},
  78339. +};
  78340. +
  78341. +static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
  78342. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78343. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78344. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78345. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78346. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78347. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78348. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  78349. + {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78350. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78351. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78352. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78353. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78354. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78355. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78356. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78357. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78358. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78359. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78360. +};
  78361. +
  78362. +static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
  78363. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78364. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78365. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78366. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78367. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78368. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78369. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  78370. + {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78371. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78372. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78373. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78374. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78375. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78376. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78377. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78378. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78379. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78380. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78381. +};
  78382. +
  78383. +static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
  78384. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78385. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78386. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78387. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78388. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78389. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78390. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  78391. + {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78392. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78393. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78394. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78395. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78396. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78397. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78398. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78399. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78400. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78401. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78402. +};
  78403. +static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
  78404. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78405. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78406. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78407. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78408. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78409. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78410. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  78411. + {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78412. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78413. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78414. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78415. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78416. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78417. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78418. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78419. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78420. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78421. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78422. +};
  78423. +
  78424. +static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
  78425. + {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78426. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78427. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78428. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78429. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78430. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78431. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
  78432. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78433. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78434. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
  78435. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78436. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78437. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78438. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78439. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78440. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78441. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78442. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78443. +};
  78444. +
  78445. +static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
  78446. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78447. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78448. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78449. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78450. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78451. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78452. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
  78453. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78454. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78455. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
  78456. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78457. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78458. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78459. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78460. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78461. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78462. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78463. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78464. +};
  78465. +
  78466. +static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
  78467. + {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78468. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78469. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78470. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78471. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78472. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78473. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0},
  78474. + {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78475. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78476. + {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78477. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78478. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78479. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78480. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78481. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78482. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78483. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78484. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78485. +};
  78486. +
  78487. +static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
  78488. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78489. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78490. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78491. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78492. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78493. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78494. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0},
  78495. + {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78496. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78497. + {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78498. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78499. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78500. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78501. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78502. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78503. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78504. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78505. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78506. +};
  78507. +
  78508. +static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
  78509. + {0x3008, 0x42, 0, 0},
  78510. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
  78511. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78512. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78513. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78514. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  78515. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  78516. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  78517. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  78518. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
  78519. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  78520. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78521. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
  78522. + {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
  78523. + {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
  78524. + {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
  78525. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
  78526. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  78527. + {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0}, {0x4005, 0x1a, 0, 0},
  78528. + {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
  78529. +};
  78530. +
  78531. +static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
  78532. + {0x3035, 0x41, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
  78533. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78534. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78535. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78536. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  78537. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  78538. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  78539. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  78540. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
  78541. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  78542. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78543. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
  78544. + {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
  78545. + {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
  78546. + {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
  78547. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
  78548. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  78549. + {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
  78550. +};
  78551. +
  78552. +static struct reg_value ov5640_setting_30fps_1080P_1920_1080[] = {
  78553. + {0x3008, 0x42, 0, 0},
  78554. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
  78555. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78556. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
  78557. + {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78558. + {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
  78559. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
  78560. + {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
  78561. + {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
  78562. + {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
  78563. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  78564. + {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
  78565. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
  78566. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78567. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78568. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78569. + {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
  78570. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78571. + {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x11, 0, 0},
  78572. + {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
  78573. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78574. + {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
  78575. + {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
  78576. + {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
  78577. + {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
  78578. + {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
  78579. + {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
  78580. + {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
  78581. + {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
  78582. + {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
  78583. + {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
  78584. + {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
  78585. + {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0},
  78586. + {0x3503, 0, 0, 0},
  78587. +};
  78588. +
  78589. +static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
  78590. + {0x3008, 0x42, 0, 0},
  78591. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
  78592. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78593. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
  78594. + {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78595. + {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
  78596. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
  78597. + {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
  78598. + {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
  78599. + {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
  78600. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  78601. + {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
  78602. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
  78603. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78604. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78605. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78606. + {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
  78607. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78608. + {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x21, 0, 0},
  78609. + {0x3036, 0x54, 0, 1}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
  78610. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78611. + {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
  78612. + {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
  78613. + {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
  78614. + {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
  78615. + {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
  78616. + {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
  78617. + {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
  78618. + {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
  78619. + {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
  78620. + {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
  78621. + {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
  78622. + {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
  78623. +};
  78624. +
  78625. +static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
  78626. + {0x4202, 0x0f, 0, 0}, /* stream off the sensor */
  78627. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, /*disable flip*/
  78628. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
  78629. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78630. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
  78631. + {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78632. + {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
  78633. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
  78634. + {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
  78635. + {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
  78636. + {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
  78637. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  78638. + {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
  78639. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
  78640. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78641. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78642. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78643. + {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
  78644. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78645. + {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 70},
  78646. + {0x4202, 0x00, 0, 0}, /* stream on the sensor */
  78647. +};
  78648. +
  78649. +static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
  78650. + {
  78651. + {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
  78652. + ov5640_setting_15fps_VGA_640_480,
  78653. + ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
  78654. + {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
  78655. + ov5640_setting_15fps_QVGA_320_240,
  78656. + ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
  78657. + {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
  78658. + ov5640_setting_15fps_NTSC_720_480,
  78659. + ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
  78660. + {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576,
  78661. + ov5640_setting_15fps_PAL_720_576,
  78662. + ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
  78663. + {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
  78664. + ov5640_setting_15fps_720P_1280_720,
  78665. + ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
  78666. + {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
  78667. + ov5640_setting_15fps_1080P_1920_1080,
  78668. + ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
  78669. + {ov5640_mode_QSXGA_2592_1944, SCALING, 2592, 1944,
  78670. + ov5640_setting_15fps_QSXGA_2592_1944,
  78671. + ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
  78672. + {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144,
  78673. + ov5640_setting_15fps_QCIF_176_144,
  78674. + ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
  78675. + {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768,
  78676. + ov5640_setting_15fps_XGA_1024_768,
  78677. + ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
  78678. + },
  78679. + {
  78680. + {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
  78681. + ov5640_setting_30fps_VGA_640_480,
  78682. + ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
  78683. + {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
  78684. + ov5640_setting_30fps_QVGA_320_240,
  78685. + ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
  78686. + {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
  78687. + ov5640_setting_30fps_NTSC_720_480,
  78688. + ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
  78689. + {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576,
  78690. + ov5640_setting_30fps_PAL_720_576,
  78691. + ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
  78692. + {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
  78693. + ov5640_setting_30fps_720P_1280_720,
  78694. + ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
  78695. + {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
  78696. + ov5640_setting_30fps_1080P_1920_1080,
  78697. + ARRAY_SIZE(ov5640_setting_30fps_1080P_1920_1080)},
  78698. + {ov5640_mode_QSXGA_2592_1944, -1, 0, 0, NULL, 0},
  78699. + {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144,
  78700. + ov5640_setting_30fps_QCIF_176_144,
  78701. + ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
  78702. + {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768,
  78703. + ov5640_setting_30fps_XGA_1024_768,
  78704. + ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
  78705. + },
  78706. +};
  78707. +
  78708. +static struct regulator *io_regulator;
  78709. +static struct regulator *core_regulator;
  78710. +static struct regulator *analog_regulator;
  78711. +static struct regulator *gpo_regulator;
  78712. +
  78713. +static int ov5640_probe(struct i2c_client *adapter,
  78714. + const struct i2c_device_id *device_id);
  78715. +static int ov5640_remove(struct i2c_client *client);
  78716. +
  78717. +static s32 ov5640_read_reg(u16 reg, u8 *val);
  78718. +static s32 ov5640_write_reg(u16 reg, u8 val);
  78719. +
  78720. +static const struct i2c_device_id ov5640_id[] = {
  78721. + {"ov5640_mipi", 0},
  78722. + {},
  78723. +};
  78724. +
  78725. +MODULE_DEVICE_TABLE(i2c, ov5640_id);
  78726. +
  78727. +static struct i2c_driver ov5640_i2c_driver = {
  78728. + .driver = {
  78729. + .owner = THIS_MODULE,
  78730. + .name = "ov5640_mipi",
  78731. + },
  78732. + .probe = ov5640_probe,
  78733. + .remove = ov5640_remove,
  78734. + .id_table = ov5640_id,
  78735. +};
  78736. +
  78737. +static void ov5640_standby(s32 enable)
  78738. +{
  78739. + if (enable)
  78740. + gpio_set_value(pwn_gpio, 1);
  78741. + else
  78742. + gpio_set_value(pwn_gpio, 0);
  78743. +
  78744. + msleep(2);
  78745. +}
  78746. +
  78747. +static void ov5640_reset(void)
  78748. +{
  78749. + /* camera reset */
  78750. + gpio_set_value(rst_gpio, 1);
  78751. +
  78752. + /* camera power dowmn */
  78753. + gpio_set_value(pwn_gpio, 1);
  78754. + msleep(5);
  78755. +
  78756. + gpio_set_value(pwn_gpio, 0);
  78757. + msleep(5);
  78758. +
  78759. + gpio_set_value(rst_gpio, 0);
  78760. + msleep(1);
  78761. +
  78762. + gpio_set_value(rst_gpio, 1);
  78763. + msleep(5);
  78764. +
  78765. + gpio_set_value(pwn_gpio, 1);
  78766. +}
  78767. +
  78768. +static int ov5640_power_on(struct device *dev)
  78769. +{
  78770. + int ret = 0;
  78771. +
  78772. + io_regulator = devm_regulator_get(dev, "DOVDD");
  78773. + if (!IS_ERR(io_regulator)) {
  78774. + regulator_set_voltage(io_regulator,
  78775. + OV5640_VOLTAGE_DIGITAL_IO,
  78776. + OV5640_VOLTAGE_DIGITAL_IO);
  78777. + ret = regulator_enable(io_regulator);
  78778. + if (ret) {
  78779. + pr_err("%s:io set voltage error\n", __func__);
  78780. + return ret;
  78781. + } else {
  78782. + dev_dbg(dev,
  78783. + "%s:io set voltage ok\n", __func__);
  78784. + }
  78785. + } else {
  78786. + pr_err("%s: cannot get io voltage error\n", __func__);
  78787. + io_regulator = NULL;
  78788. + }
  78789. +
  78790. + core_regulator = devm_regulator_get(dev, "DVDD");
  78791. + if (!IS_ERR(core_regulator)) {
  78792. + regulator_set_voltage(core_regulator,
  78793. + OV5640_VOLTAGE_DIGITAL_CORE,
  78794. + OV5640_VOLTAGE_DIGITAL_CORE);
  78795. + ret = regulator_enable(core_regulator);
  78796. + if (ret) {
  78797. + pr_err("%s:core set voltage error\n", __func__);
  78798. + return ret;
  78799. + } else {
  78800. + dev_dbg(dev,
  78801. + "%s:core set voltage ok\n", __func__);
  78802. + }
  78803. + } else {
  78804. + core_regulator = NULL;
  78805. + pr_err("%s: cannot get core voltage error\n", __func__);
  78806. + }
  78807. +
  78808. + analog_regulator = devm_regulator_get(dev, "AVDD");
  78809. + if (!IS_ERR(analog_regulator)) {
  78810. + regulator_set_voltage(analog_regulator,
  78811. + OV5640_VOLTAGE_ANALOG,
  78812. + OV5640_VOLTAGE_ANALOG);
  78813. + ret = regulator_enable(analog_regulator);
  78814. + if (ret) {
  78815. + pr_err("%s:analog set voltage error\n",
  78816. + __func__);
  78817. + return ret;
  78818. + } else {
  78819. + dev_dbg(dev,
  78820. + "%s:analog set voltage ok\n", __func__);
  78821. + }
  78822. + } else {
  78823. + analog_regulator = NULL;
  78824. + pr_err("%s: cannot get analog voltage error\n", __func__);
  78825. + }
  78826. +
  78827. + return ret;
  78828. +}
  78829. +
  78830. +static s32 ov5640_write_reg(u16 reg, u8 val)
  78831. +{
  78832. + u8 au8Buf[3] = {0};
  78833. +
  78834. + au8Buf[0] = reg >> 8;
  78835. + au8Buf[1] = reg & 0xff;
  78836. + au8Buf[2] = val;
  78837. +
  78838. + if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
  78839. + pr_err("%s:write reg error:reg=%x,val=%x\n",
  78840. + __func__, reg, val);
  78841. + return -1;
  78842. + }
  78843. +
  78844. + return 0;
  78845. +}
  78846. +
  78847. +static s32 ov5640_read_reg(u16 reg, u8 *val)
  78848. +{
  78849. + u8 au8RegBuf[2] = {0};
  78850. + u8 u8RdVal = 0;
  78851. +
  78852. + au8RegBuf[0] = reg >> 8;
  78853. + au8RegBuf[1] = reg & 0xff;
  78854. +
  78855. + if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
  78856. + pr_err("%s:write reg error:reg=%x\n",
  78857. + __func__, reg);
  78858. + return -1;
  78859. + }
  78860. +
  78861. + if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
  78862. + pr_err("%s:read reg error:reg=%x,val=%x\n",
  78863. + __func__, reg, u8RdVal);
  78864. + return -1;
  78865. + }
  78866. +
  78867. + *val = u8RdVal;
  78868. +
  78869. + return u8RdVal;
  78870. +}
  78871. +
  78872. +static int prev_sysclk, prev_HTS;
  78873. +static int AE_low, AE_high, AE_Target = 52;
  78874. +
  78875. +void OV5640_stream_on(void)
  78876. +{
  78877. + ov5640_write_reg(0x4202, 0x00);
  78878. +}
  78879. +
  78880. +void OV5640_stream_off(void)
  78881. +{
  78882. + ov5640_write_reg(0x4202, 0x0f);
  78883. +}
  78884. +
  78885. +
  78886. +int OV5640_get_sysclk(void)
  78887. +{
  78888. + /* calculate sysclk */
  78889. + int xvclk = ov5640_data.mclk / 10000;
  78890. + int temp1, temp2;
  78891. + int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv;
  78892. + int Bit_div2x = 1, sclk_rdiv, sysclk;
  78893. + u8 temp;
  78894. +
  78895. + int sclk_rdiv_map[] = {1, 2, 4, 8};
  78896. +
  78897. + temp1 = ov5640_read_reg(0x3034, &temp);
  78898. + temp2 = temp1 & 0x0f;
  78899. + if (temp2 == 8 || temp2 == 10)
  78900. + Bit_div2x = temp2 / 2;
  78901. +
  78902. + temp1 = ov5640_read_reg(0x3035, &temp);
  78903. + SysDiv = temp1>>4;
  78904. + if (SysDiv == 0)
  78905. + SysDiv = 16;
  78906. +
  78907. + temp1 = ov5640_read_reg(0x3036, &temp);
  78908. + Multiplier = temp1;
  78909. +
  78910. + temp1 = ov5640_read_reg(0x3037, &temp);
  78911. + PreDiv = temp1 & 0x0f;
  78912. + Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
  78913. +
  78914. + temp1 = ov5640_read_reg(0x3108, &temp);
  78915. + temp2 = temp1 & 0x03;
  78916. + sclk_rdiv = sclk_rdiv_map[temp2];
  78917. +
  78918. + VCO = xvclk * Multiplier / PreDiv;
  78919. +
  78920. + sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
  78921. +
  78922. + return sysclk;
  78923. +}
  78924. +
  78925. +void OV5640_set_night_mode(void)
  78926. +{
  78927. + /* read HTS from register settings */
  78928. + u8 mode;
  78929. +
  78930. + ov5640_read_reg(0x3a00, &mode);
  78931. + mode &= 0xfb;
  78932. + ov5640_write_reg(0x3a00, mode);
  78933. +}
  78934. +
  78935. +int OV5640_get_HTS(void)
  78936. +{
  78937. + /* read HTS from register settings */
  78938. + int HTS;
  78939. + u8 temp;
  78940. +
  78941. + HTS = ov5640_read_reg(0x380c, &temp);
  78942. + HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
  78943. +
  78944. + return HTS;
  78945. +}
  78946. +
  78947. +int OV5640_get_VTS(void)
  78948. +{
  78949. + /* read VTS from register settings */
  78950. + int VTS;
  78951. + u8 temp;
  78952. +
  78953. + /* total vertical size[15:8] high byte */
  78954. + VTS = ov5640_read_reg(0x380e, &temp);
  78955. +
  78956. + VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
  78957. +
  78958. + return VTS;
  78959. +}
  78960. +
  78961. +int OV5640_set_VTS(int VTS)
  78962. +{
  78963. + /* write VTS to registers */
  78964. + int temp;
  78965. +
  78966. + temp = VTS & 0xff;
  78967. + ov5640_write_reg(0x380f, temp);
  78968. +
  78969. + temp = VTS>>8;
  78970. + ov5640_write_reg(0x380e, temp);
  78971. +
  78972. + return 0;
  78973. +}
  78974. +
  78975. +int OV5640_get_shutter(void)
  78976. +{
  78977. + /* read shutter, in number of line period */
  78978. + int shutter;
  78979. + u8 temp;
  78980. +
  78981. + shutter = (ov5640_read_reg(0x03500, &temp) & 0x0f);
  78982. + shutter = (shutter<<8) + ov5640_read_reg(0x3501, &temp);
  78983. + shutter = (shutter<<4) + (ov5640_read_reg(0x3502, &temp)>>4);
  78984. +
  78985. + return shutter;
  78986. +}
  78987. +
  78988. +int OV5640_set_shutter(int shutter)
  78989. +{
  78990. + /* write shutter, in number of line period */
  78991. + int temp;
  78992. +
  78993. + shutter = shutter & 0xffff;
  78994. +
  78995. + temp = shutter & 0x0f;
  78996. + temp = temp<<4;
  78997. + ov5640_write_reg(0x3502, temp);
  78998. +
  78999. + temp = shutter & 0xfff;
  79000. + temp = temp>>4;
  79001. + ov5640_write_reg(0x3501, temp);
  79002. +
  79003. + temp = shutter>>12;
  79004. + ov5640_write_reg(0x3500, temp);
  79005. +
  79006. + return 0;
  79007. +}
  79008. +
  79009. +int OV5640_get_gain16(void)
  79010. +{
  79011. + /* read gain, 16 = 1x */
  79012. + int gain16;
  79013. + u8 temp;
  79014. +
  79015. + gain16 = ov5640_read_reg(0x350a, &temp) & 0x03;
  79016. + gain16 = (gain16<<8) + ov5640_read_reg(0x350b, &temp);
  79017. +
  79018. + return gain16;
  79019. +}
  79020. +
  79021. +int OV5640_set_gain16(int gain16)
  79022. +{
  79023. + /* write gain, 16 = 1x */
  79024. + u8 temp;
  79025. + gain16 = gain16 & 0x3ff;
  79026. +
  79027. + temp = gain16 & 0xff;
  79028. + ov5640_write_reg(0x350b, temp);
  79029. +
  79030. + temp = gain16>>8;
  79031. + ov5640_write_reg(0x350a, temp);
  79032. +
  79033. + return 0;
  79034. +}
  79035. +
  79036. +int OV5640_get_light_freq(void)
  79037. +{
  79038. + /* get banding filter value */
  79039. + int temp, temp1, light_freq = 0;
  79040. + u8 tmp;
  79041. +
  79042. + temp = ov5640_read_reg(0x3c01, &tmp);
  79043. +
  79044. + if (temp & 0x80) {
  79045. + /* manual */
  79046. + temp1 = ov5640_read_reg(0x3c00, &tmp);
  79047. + if (temp1 & 0x04) {
  79048. + /* 50Hz */
  79049. + light_freq = 50;
  79050. + } else {
  79051. + /* 60Hz */
  79052. + light_freq = 60;
  79053. + }
  79054. + } else {
  79055. + /* auto */
  79056. + temp1 = ov5640_read_reg(0x3c0c, &tmp);
  79057. + if (temp1 & 0x01) {
  79058. + /* 50Hz */
  79059. + light_freq = 50;
  79060. + } else {
  79061. + /* 60Hz */
  79062. + }
  79063. + }
  79064. + return light_freq;
  79065. +}
  79066. +
  79067. +void OV5640_set_bandingfilter(void)
  79068. +{
  79069. + int prev_VTS;
  79070. + int band_step60, max_band60, band_step50, max_band50;
  79071. +
  79072. + /* read preview PCLK */
  79073. + prev_sysclk = OV5640_get_sysclk();
  79074. + /* read preview HTS */
  79075. + prev_HTS = OV5640_get_HTS();
  79076. +
  79077. + /* read preview VTS */
  79078. + prev_VTS = OV5640_get_VTS();
  79079. +
  79080. + /* calculate banding filter */
  79081. + /* 60Hz */
  79082. + band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
  79083. + ov5640_write_reg(0x3a0a, (band_step60 >> 8));
  79084. + ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
  79085. +
  79086. + max_band60 = (int)((prev_VTS-4)/band_step60);
  79087. + ov5640_write_reg(0x3a0d, max_band60);
  79088. +
  79089. + /* 50Hz */
  79090. + band_step50 = prev_sysclk * 100/prev_HTS;
  79091. + ov5640_write_reg(0x3a08, (band_step50 >> 8));
  79092. + ov5640_write_reg(0x3a09, (band_step50 & 0xff));
  79093. +
  79094. + max_band50 = (int)((prev_VTS-4)/band_step50);
  79095. + ov5640_write_reg(0x3a0e, max_band50);
  79096. +}
  79097. +
  79098. +int OV5640_set_AE_target(int target)
  79099. +{
  79100. + /* stable in high */
  79101. + int fast_high, fast_low;
  79102. + AE_low = target * 23 / 25; /* 0.92 */
  79103. + AE_high = target * 27 / 25; /* 1.08 */
  79104. +
  79105. + fast_high = AE_high<<1;
  79106. + if (fast_high > 255)
  79107. + fast_high = 255;
  79108. +
  79109. + fast_low = AE_low >> 1;
  79110. +
  79111. + ov5640_write_reg(0x3a0f, AE_high);
  79112. + ov5640_write_reg(0x3a10, AE_low);
  79113. + ov5640_write_reg(0x3a1b, AE_high);
  79114. + ov5640_write_reg(0x3a1e, AE_low);
  79115. + ov5640_write_reg(0x3a11, fast_high);
  79116. + ov5640_write_reg(0x3a1f, fast_low);
  79117. +
  79118. + return 0;
  79119. +}
  79120. +
  79121. +void OV5640_turn_on_AE_AG(int enable)
  79122. +{
  79123. + u8 ae_ag_ctrl;
  79124. +
  79125. + ov5640_read_reg(0x3503, &ae_ag_ctrl);
  79126. + if (enable) {
  79127. + /* turn on auto AE/AG */
  79128. + ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
  79129. + } else {
  79130. + /* turn off AE/AG */
  79131. + ae_ag_ctrl = ae_ag_ctrl | 0x03;
  79132. + }
  79133. + ov5640_write_reg(0x3503, ae_ag_ctrl);
  79134. +}
  79135. +
  79136. +bool binning_on(void)
  79137. +{
  79138. + u8 temp;
  79139. + ov5640_read_reg(0x3821, &temp);
  79140. + temp &= 0xfe;
  79141. + if (temp)
  79142. + return true;
  79143. + else
  79144. + return false;
  79145. +}
  79146. +
  79147. +static void ov5640_set_virtual_channel(int channel)
  79148. +{
  79149. + u8 channel_id;
  79150. +
  79151. + ov5640_read_reg(0x4814, &channel_id);
  79152. + channel_id &= ~(3 << 6);
  79153. + ov5640_write_reg(0x4814, channel_id | (channel << 6));
  79154. +}
  79155. +
  79156. +/* download ov5640 settings to sensor through i2c */
  79157. +static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
  79158. +{
  79159. + register u32 Delay_ms = 0;
  79160. + register u16 RegAddr = 0;
  79161. + register u8 Mask = 0;
  79162. + register u8 Val = 0;
  79163. + u8 RegVal = 0;
  79164. + int i, retval = 0;
  79165. +
  79166. + for (i = 0; i < ArySize; ++i, ++pModeSetting) {
  79167. + Delay_ms = pModeSetting->u32Delay_ms;
  79168. + RegAddr = pModeSetting->u16RegAddr;
  79169. + Val = pModeSetting->u8Val;
  79170. + Mask = pModeSetting->u8Mask;
  79171. +
  79172. + if (Mask) {
  79173. + retval = ov5640_read_reg(RegAddr, &RegVal);
  79174. + if (retval < 0)
  79175. + goto err;
  79176. +
  79177. + RegVal &= ~(u8)Mask;
  79178. + Val &= Mask;
  79179. + Val |= RegVal;
  79180. + }
  79181. +
  79182. + retval = ov5640_write_reg(RegAddr, Val);
  79183. + if (retval < 0)
  79184. + goto err;
  79185. +
  79186. + if (Delay_ms)
  79187. + msleep(Delay_ms);
  79188. + }
  79189. +err:
  79190. + return retval;
  79191. +}
  79192. +
  79193. +/* sensor changes between scaling and subsampling
  79194. + * go through exposure calcualtion
  79195. + */
  79196. +static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
  79197. + enum ov5640_mode mode)
  79198. +{
  79199. + struct reg_value *pModeSetting = NULL;
  79200. + s32 ArySize = 0;
  79201. + u8 average;
  79202. + int prev_shutter, prev_gain16;
  79203. + int cap_shutter, cap_gain16;
  79204. + int cap_sysclk, cap_HTS, cap_VTS;
  79205. + int light_freq, cap_bandfilt, cap_maxband;
  79206. + long cap_gain16_shutter;
  79207. + int retval = 0;
  79208. +
  79209. + /* check if the input mode and frame rate is valid */
  79210. + pModeSetting =
  79211. + ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  79212. + ArySize =
  79213. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  79214. +
  79215. + ov5640_data.pix.width =
  79216. + ov5640_mode_info_data[frame_rate][mode].width;
  79217. + ov5640_data.pix.height =
  79218. + ov5640_mode_info_data[frame_rate][mode].height;
  79219. +
  79220. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  79221. + pModeSetting == NULL || ArySize == 0)
  79222. + return -EINVAL;
  79223. +
  79224. + /* auto focus */
  79225. + /* OV5640_auto_focus();//if no af function, just skip it */
  79226. +
  79227. + /* turn off AE/AG */
  79228. + OV5640_turn_on_AE_AG(0);
  79229. +
  79230. + /* read preview shutter */
  79231. + prev_shutter = OV5640_get_shutter();
  79232. + if ((binning_on()) && (mode != ov5640_mode_720P_1280_720)
  79233. + && (mode != ov5640_mode_1080P_1920_1080))
  79234. + prev_shutter *= 2;
  79235. +
  79236. + /* read preview gain */
  79237. + prev_gain16 = OV5640_get_gain16();
  79238. +
  79239. + /* get average */
  79240. + ov5640_read_reg(0x56a1, &average);
  79241. +
  79242. + /* turn off night mode for capture */
  79243. + OV5640_set_night_mode();
  79244. +
  79245. + /* turn off overlay */
  79246. + /* ov5640_write_reg(0x3022, 0x06);//if no af function, just skip it */
  79247. +
  79248. + OV5640_stream_off();
  79249. +
  79250. + /* Write capture setting */
  79251. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79252. + if (retval < 0)
  79253. + goto err;
  79254. +
  79255. + /* read capture VTS */
  79256. + cap_VTS = OV5640_get_VTS();
  79257. + cap_HTS = OV5640_get_HTS();
  79258. + cap_sysclk = OV5640_get_sysclk();
  79259. +
  79260. + /* calculate capture banding filter */
  79261. + light_freq = OV5640_get_light_freq();
  79262. + if (light_freq == 60) {
  79263. + /* 60Hz */
  79264. + cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
  79265. + } else {
  79266. + /* 50Hz */
  79267. + cap_bandfilt = cap_sysclk * 100 / cap_HTS;
  79268. + }
  79269. + cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
  79270. +
  79271. + /* calculate capture shutter/gain16 */
  79272. + if (average > AE_low && average < AE_high) {
  79273. + /* in stable range */
  79274. + cap_gain16_shutter =
  79275. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
  79276. + * prev_HTS/cap_HTS * AE_Target / average;
  79277. + } else {
  79278. + cap_gain16_shutter =
  79279. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
  79280. + * prev_HTS/cap_HTS;
  79281. + }
  79282. +
  79283. + /* gain to shutter */
  79284. + if (cap_gain16_shutter < (cap_bandfilt * 16)) {
  79285. + /* shutter < 1/100 */
  79286. + cap_shutter = cap_gain16_shutter/16;
  79287. + if (cap_shutter < 1)
  79288. + cap_shutter = 1;
  79289. +
  79290. + cap_gain16 = cap_gain16_shutter/cap_shutter;
  79291. + if (cap_gain16 < 16)
  79292. + cap_gain16 = 16;
  79293. + } else {
  79294. + if (cap_gain16_shutter >
  79295. + (cap_bandfilt * cap_maxband * 16)) {
  79296. + /* exposure reach max */
  79297. + cap_shutter = cap_bandfilt * cap_maxband;
  79298. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  79299. + } else {
  79300. + /* 1/100 < (cap_shutter = n/100) =< max */
  79301. + cap_shutter =
  79302. + ((int) (cap_gain16_shutter/16 / cap_bandfilt))
  79303. + *cap_bandfilt;
  79304. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  79305. + }
  79306. + }
  79307. +
  79308. + /* write capture gain */
  79309. + OV5640_set_gain16(cap_gain16);
  79310. +
  79311. + /* write capture shutter */
  79312. + if (cap_shutter > (cap_VTS - 4)) {
  79313. + cap_VTS = cap_shutter + 4;
  79314. + OV5640_set_VTS(cap_VTS);
  79315. + }
  79316. + OV5640_set_shutter(cap_shutter);
  79317. +
  79318. + OV5640_stream_on();
  79319. +
  79320. +err:
  79321. + return retval;
  79322. +}
  79323. +
  79324. +/* if sensor changes inside scaling or subsampling
  79325. + * change mode directly
  79326. + * */
  79327. +static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
  79328. + enum ov5640_mode mode)
  79329. +{
  79330. + struct reg_value *pModeSetting = NULL;
  79331. + s32 ArySize = 0;
  79332. + int retval = 0;
  79333. +
  79334. + /* check if the input mode and frame rate is valid */
  79335. + pModeSetting =
  79336. + ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  79337. + ArySize =
  79338. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  79339. +
  79340. + ov5640_data.pix.width =
  79341. + ov5640_mode_info_data[frame_rate][mode].width;
  79342. + ov5640_data.pix.height =
  79343. + ov5640_mode_info_data[frame_rate][mode].height;
  79344. +
  79345. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  79346. + pModeSetting == NULL || ArySize == 0)
  79347. + return -EINVAL;
  79348. +
  79349. + /* turn off AE/AG */
  79350. + OV5640_turn_on_AE_AG(0);
  79351. +
  79352. + OV5640_stream_off();
  79353. +
  79354. + /* Write capture setting */
  79355. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79356. + if (retval < 0)
  79357. + goto err;
  79358. +
  79359. + OV5640_stream_on();
  79360. +
  79361. + OV5640_turn_on_AE_AG(1);
  79362. +
  79363. +err:
  79364. + return retval;
  79365. +}
  79366. +
  79367. +static int ov5640_init_mode(enum ov5640_frame_rate frame_rate,
  79368. + enum ov5640_mode mode, enum ov5640_mode orig_mode)
  79369. +{
  79370. + struct reg_value *pModeSetting = NULL;
  79371. + s32 ArySize = 0;
  79372. + int retval = 0;
  79373. + void *mipi_csi2_info;
  79374. + u32 mipi_reg, msec_wait4stable = 0;
  79375. + enum ov5640_downsize_mode dn_mode, orig_dn_mode;
  79376. +
  79377. + if ((mode > ov5640_mode_MAX || mode < ov5640_mode_MIN)
  79378. + && (mode != ov5640_mode_INIT)) {
  79379. + pr_err("Wrong ov5640 mode detected!\n");
  79380. + return -1;
  79381. + }
  79382. +
  79383. + mipi_csi2_info = mipi_csi2_get_info();
  79384. +
  79385. + /* initial mipi dphy */
  79386. + if (!mipi_csi2_info) {
  79387. + printk(KERN_ERR "%s() in %s: Fail to get mipi_csi2_info!\n",
  79388. + __func__, __FILE__);
  79389. + return -1;
  79390. + }
  79391. +
  79392. + if (!mipi_csi2_get_status(mipi_csi2_info))
  79393. + mipi_csi2_enable(mipi_csi2_info);
  79394. +
  79395. + if (!mipi_csi2_get_status(mipi_csi2_info)) {
  79396. + pr_err("Can not enable mipi csi2 driver!\n");
  79397. + return -1;
  79398. + }
  79399. +
  79400. + mipi_csi2_set_lanes(mipi_csi2_info);
  79401. +
  79402. + /*Only reset MIPI CSI2 HW at sensor initialize*/
  79403. + if (mode == ov5640_mode_INIT)
  79404. + mipi_csi2_reset(mipi_csi2_info);
  79405. +
  79406. + if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_UYVY)
  79407. + mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_YUV422);
  79408. + else if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_RGB565)
  79409. + mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_RGB565);
  79410. + else
  79411. + pr_err("currently this sensor format can not be supported!\n");
  79412. +
  79413. + dn_mode = ov5640_mode_info_data[frame_rate][mode].dn_mode;
  79414. + orig_dn_mode = ov5640_mode_info_data[frame_rate][orig_mode].dn_mode;
  79415. + if (mode == ov5640_mode_INIT) {
  79416. + pModeSetting = ov5640_init_setting_30fps_VGA;
  79417. + ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
  79418. +
  79419. + ov5640_data.pix.width = 640;
  79420. + ov5640_data.pix.height = 480;
  79421. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79422. + if (retval < 0)
  79423. + goto err;
  79424. +
  79425. + pModeSetting = ov5640_setting_30fps_VGA_640_480;
  79426. + ArySize = ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480);
  79427. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79428. + } else if ((dn_mode == SUBSAMPLING && orig_dn_mode == SCALING) ||
  79429. + (dn_mode == SCALING && orig_dn_mode == SUBSAMPLING)) {
  79430. + /* change between subsampling and scaling
  79431. + * go through exposure calucation */
  79432. + retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
  79433. + } else {
  79434. + /* change inside subsampling or scaling
  79435. + * download firmware directly */
  79436. + retval = ov5640_change_mode_direct(frame_rate, mode);
  79437. + }
  79438. +
  79439. + if (retval < 0)
  79440. + goto err;
  79441. +
  79442. + OV5640_set_AE_target(AE_Target);
  79443. + OV5640_get_light_freq();
  79444. + OV5640_set_bandingfilter();
  79445. + ov5640_set_virtual_channel(ov5640_data.csi);
  79446. +
  79447. + /* add delay to wait for sensor stable */
  79448. + if (mode == ov5640_mode_QSXGA_2592_1944) {
  79449. + /* dump the first two frames: 1/7.5*2
  79450. + * the frame rate of QSXGA is 7.5fps */
  79451. + msec_wait4stable = 267;
  79452. + } else if (frame_rate == ov5640_15_fps) {
  79453. + /* dump the first nine frames: 1/15*9 */
  79454. + msec_wait4stable = 600;
  79455. + } else if (frame_rate == ov5640_30_fps) {
  79456. + /* dump the first nine frames: 1/30*9 */
  79457. + msec_wait4stable = 300;
  79458. + }
  79459. + msleep(msec_wait4stable);
  79460. +
  79461. + if (mipi_csi2_info) {
  79462. + unsigned int i;
  79463. +
  79464. + i = 0;
  79465. +
  79466. + /* wait for mipi sensor ready */
  79467. + mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
  79468. + while ((mipi_reg == 0x200) && (i < 10)) {
  79469. + mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
  79470. + i++;
  79471. + msleep(10);
  79472. + }
  79473. +
  79474. + if (i >= 10) {
  79475. + pr_err("mipi csi2 can not receive sensor clk!\n");
  79476. + return -1;
  79477. + }
  79478. +
  79479. + i = 0;
  79480. +
  79481. + /* wait for mipi stable */
  79482. + mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
  79483. + while ((mipi_reg != 0x0) && (i < 10)) {
  79484. + mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
  79485. + i++;
  79486. + msleep(10);
  79487. + }
  79488. +
  79489. + if (i >= 10) {
  79490. + pr_err("mipi csi2 can not reveive data correctly!\n");
  79491. + return -1;
  79492. + }
  79493. + }
  79494. +err:
  79495. + return retval;
  79496. +}
  79497. +
  79498. +/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
  79499. +
  79500. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  79501. +{
  79502. + if (s == NULL) {
  79503. + pr_err(" ERROR!! no slave device set!\n");
  79504. + return -1;
  79505. + }
  79506. +
  79507. + memset(p, 0, sizeof(*p));
  79508. + p->u.bt656.clock_curr = ov5640_data.mclk;
  79509. + pr_debug(" clock_curr=mclk=%d\n", ov5640_data.mclk);
  79510. + p->if_type = V4L2_IF_TYPE_BT656;
  79511. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  79512. + p->u.bt656.clock_min = OV5640_XCLK_MIN;
  79513. + p->u.bt656.clock_max = OV5640_XCLK_MAX;
  79514. + p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
  79515. +
  79516. + return 0;
  79517. +}
  79518. +
  79519. +/*!
  79520. + * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
  79521. + * @s: pointer to standard V4L2 device structure
  79522. + * @on: indicates power mode (on or off)
  79523. + *
  79524. + * Turns the power on or off, depending on the value of on and returns the
  79525. + * appropriate error code.
  79526. + */
  79527. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  79528. +{
  79529. + struct sensor_data *sensor = s->priv;
  79530. +
  79531. + if (on && !sensor->on) {
  79532. + if (io_regulator)
  79533. + if (regulator_enable(io_regulator) != 0)
  79534. + return -EIO;
  79535. + if (core_regulator)
  79536. + if (regulator_enable(core_regulator) != 0)
  79537. + return -EIO;
  79538. + if (gpo_regulator)
  79539. + if (regulator_enable(gpo_regulator) != 0)
  79540. + return -EIO;
  79541. + if (analog_regulator)
  79542. + if (regulator_enable(analog_regulator) != 0)
  79543. + return -EIO;
  79544. + /* Make sure power on */
  79545. + ov5640_standby(0);
  79546. + } else if (!on && sensor->on) {
  79547. + if (analog_regulator)
  79548. + regulator_disable(analog_regulator);
  79549. + if (core_regulator)
  79550. + regulator_disable(core_regulator);
  79551. + if (io_regulator)
  79552. + regulator_disable(io_regulator);
  79553. + if (gpo_regulator)
  79554. + regulator_disable(gpo_regulator);
  79555. +
  79556. + ov5640_standby(1);
  79557. + }
  79558. +
  79559. + sensor->on = on;
  79560. +
  79561. + return 0;
  79562. +}
  79563. +
  79564. +/*!
  79565. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  79566. + * @s: pointer to standard V4L2 device structure
  79567. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  79568. + *
  79569. + * Returns the sensor's video CAPTURE parameters.
  79570. + */
  79571. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  79572. +{
  79573. + struct sensor_data *sensor = s->priv;
  79574. + struct v4l2_captureparm *cparm = &a->parm.capture;
  79575. + int ret = 0;
  79576. +
  79577. + switch (a->type) {
  79578. + /* This is the only case currently handled. */
  79579. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  79580. + memset(a, 0, sizeof(*a));
  79581. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  79582. + cparm->capability = sensor->streamcap.capability;
  79583. + cparm->timeperframe = sensor->streamcap.timeperframe;
  79584. + cparm->capturemode = sensor->streamcap.capturemode;
  79585. + ret = 0;
  79586. + break;
  79587. +
  79588. + /* These are all the possible cases. */
  79589. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  79590. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  79591. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  79592. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  79593. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  79594. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  79595. + ret = -EINVAL;
  79596. + break;
  79597. +
  79598. + default:
  79599. + pr_debug(" type is unknown - %d\n", a->type);
  79600. + ret = -EINVAL;
  79601. + break;
  79602. + }
  79603. +
  79604. + return ret;
  79605. +}
  79606. +
  79607. +/*!
  79608. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  79609. + * @s: pointer to standard V4L2 device structure
  79610. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  79611. + *
  79612. + * Configures the sensor to use the input parameters, if possible. If
  79613. + * not possible, reverts to the old parameters and returns the
  79614. + * appropriate error code.
  79615. + */
  79616. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  79617. +{
  79618. + struct sensor_data *sensor = s->priv;
  79619. + struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
  79620. + u32 tgt_fps; /* target frames per secound */
  79621. + enum ov5640_frame_rate frame_rate;
  79622. + enum ov5640_mode orig_mode;
  79623. + int ret = 0;
  79624. +
  79625. + /* Make sure power on */
  79626. + ov5640_standby(0);
  79627. +
  79628. + switch (a->type) {
  79629. + /* This is the only case currently handled. */
  79630. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  79631. + /* Check that the new frame rate is allowed. */
  79632. + if ((timeperframe->numerator == 0) ||
  79633. + (timeperframe->denominator == 0)) {
  79634. + timeperframe->denominator = DEFAULT_FPS;
  79635. + timeperframe->numerator = 1;
  79636. + }
  79637. +
  79638. + tgt_fps = timeperframe->denominator /
  79639. + timeperframe->numerator;
  79640. +
  79641. + if (tgt_fps > MAX_FPS) {
  79642. + timeperframe->denominator = MAX_FPS;
  79643. + timeperframe->numerator = 1;
  79644. + } else if (tgt_fps < MIN_FPS) {
  79645. + timeperframe->denominator = MIN_FPS;
  79646. + timeperframe->numerator = 1;
  79647. + }
  79648. +
  79649. + /* Actual frame rate we use */
  79650. + tgt_fps = timeperframe->denominator /
  79651. + timeperframe->numerator;
  79652. +
  79653. + if (tgt_fps == 15)
  79654. + frame_rate = ov5640_15_fps;
  79655. + else if (tgt_fps == 30)
  79656. + frame_rate = ov5640_30_fps;
  79657. + else {
  79658. + pr_err(" The camera frame rate is not supported!\n");
  79659. + return -EINVAL;
  79660. + }
  79661. +
  79662. + orig_mode = sensor->streamcap.capturemode;
  79663. + ret = ov5640_init_mode(frame_rate,
  79664. + (u32)a->parm.capture.capturemode, orig_mode);
  79665. + if (ret < 0)
  79666. + return ret;
  79667. +
  79668. + sensor->streamcap.timeperframe = *timeperframe;
  79669. + sensor->streamcap.capturemode =
  79670. + (u32)a->parm.capture.capturemode;
  79671. +
  79672. + break;
  79673. +
  79674. + /* These are all the possible cases. */
  79675. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  79676. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  79677. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  79678. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  79679. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  79680. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  79681. + pr_debug(" type is not " \
  79682. + "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
  79683. + a->type);
  79684. + ret = -EINVAL;
  79685. + break;
  79686. +
  79687. + default:
  79688. + pr_debug(" type is unknown - %d\n", a->type);
  79689. + ret = -EINVAL;
  79690. + break;
  79691. + }
  79692. +
  79693. + return ret;
  79694. +}
  79695. +
  79696. +/*!
  79697. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  79698. + * @s: pointer to standard V4L2 device structure
  79699. + * @f: pointer to standard V4L2 v4l2_format structure
  79700. + *
  79701. + * Returns the sensor's current pixel format in the v4l2_format
  79702. + * parameter.
  79703. + */
  79704. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  79705. +{
  79706. + struct sensor_data *sensor = s->priv;
  79707. +
  79708. + f->fmt.pix = sensor->pix;
  79709. +
  79710. + return 0;
  79711. +}
  79712. +
  79713. +/*!
  79714. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  79715. + * @s: pointer to standard V4L2 device structure
  79716. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  79717. + *
  79718. + * If the requested control is supported, returns the control's current
  79719. + * value from the video_control[] array. Otherwise, returns -EINVAL
  79720. + * if the control is not supported.
  79721. + */
  79722. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  79723. +{
  79724. + int ret = 0;
  79725. +
  79726. + switch (vc->id) {
  79727. + case V4L2_CID_BRIGHTNESS:
  79728. + vc->value = ov5640_data.brightness;
  79729. + break;
  79730. + case V4L2_CID_HUE:
  79731. + vc->value = ov5640_data.hue;
  79732. + break;
  79733. + case V4L2_CID_CONTRAST:
  79734. + vc->value = ov5640_data.contrast;
  79735. + break;
  79736. + case V4L2_CID_SATURATION:
  79737. + vc->value = ov5640_data.saturation;
  79738. + break;
  79739. + case V4L2_CID_RED_BALANCE:
  79740. + vc->value = ov5640_data.red;
  79741. + break;
  79742. + case V4L2_CID_BLUE_BALANCE:
  79743. + vc->value = ov5640_data.blue;
  79744. + break;
  79745. + case V4L2_CID_EXPOSURE:
  79746. + vc->value = ov5640_data.ae_mode;
  79747. + break;
  79748. + default:
  79749. + ret = -EINVAL;
  79750. + }
  79751. +
  79752. + return ret;
  79753. +}
  79754. +
  79755. +/*!
  79756. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  79757. + * @s: pointer to standard V4L2 device structure
  79758. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  79759. + *
  79760. + * If the requested control is supported, sets the control's current
  79761. + * value in HW (and updates the video_control[] array). Otherwise,
  79762. + * returns -EINVAL if the control is not supported.
  79763. + */
  79764. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  79765. +{
  79766. + int retval = 0;
  79767. +
  79768. + pr_debug("In ov5640:ioctl_s_ctrl %d\n",
  79769. + vc->id);
  79770. +
  79771. + switch (vc->id) {
  79772. + case V4L2_CID_BRIGHTNESS:
  79773. + break;
  79774. + case V4L2_CID_CONTRAST:
  79775. + break;
  79776. + case V4L2_CID_SATURATION:
  79777. + break;
  79778. + case V4L2_CID_HUE:
  79779. + break;
  79780. + case V4L2_CID_AUTO_WHITE_BALANCE:
  79781. + break;
  79782. + case V4L2_CID_DO_WHITE_BALANCE:
  79783. + break;
  79784. + case V4L2_CID_RED_BALANCE:
  79785. + break;
  79786. + case V4L2_CID_BLUE_BALANCE:
  79787. + break;
  79788. + case V4L2_CID_GAMMA:
  79789. + break;
  79790. + case V4L2_CID_EXPOSURE:
  79791. + break;
  79792. + case V4L2_CID_AUTOGAIN:
  79793. + break;
  79794. + case V4L2_CID_GAIN:
  79795. + break;
  79796. + case V4L2_CID_HFLIP:
  79797. + break;
  79798. + case V4L2_CID_VFLIP:
  79799. + break;
  79800. + default:
  79801. + retval = -EPERM;
  79802. + break;
  79803. + }
  79804. +
  79805. + return retval;
  79806. +}
  79807. +
  79808. +/*!
  79809. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  79810. + * VIDIOC_ENUM_FRAMESIZES ioctl
  79811. + * @s: pointer to standard V4L2 device structure
  79812. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  79813. + *
  79814. + * Return 0 if successful, otherwise -EINVAL.
  79815. + */
  79816. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  79817. + struct v4l2_frmsizeenum *fsize)
  79818. +{
  79819. + if (fsize->index > ov5640_mode_MAX)
  79820. + return -EINVAL;
  79821. +
  79822. + fsize->pixel_format = ov5640_data.pix.pixelformat;
  79823. + fsize->discrete.width =
  79824. + max(ov5640_mode_info_data[0][fsize->index].width,
  79825. + ov5640_mode_info_data[1][fsize->index].width);
  79826. + fsize->discrete.height =
  79827. + max(ov5640_mode_info_data[0][fsize->index].height,
  79828. + ov5640_mode_info_data[1][fsize->index].height);
  79829. + return 0;
  79830. +}
  79831. +
  79832. +/*!
  79833. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  79834. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  79835. + * @s: pointer to standard V4L2 device structure
  79836. + * @id: pointer to int
  79837. + *
  79838. + * Return 0.
  79839. + */
  79840. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  79841. +{
  79842. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  79843. + V4L2_CHIP_MATCH_I2C_DRIVER;
  79844. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
  79845. + "ov5640_mipi_camera");
  79846. +
  79847. + return 0;
  79848. +}
  79849. +
  79850. +/*!
  79851. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  79852. + * @s: pointer to standard V4L2 device structure
  79853. + */
  79854. +static int ioctl_init(struct v4l2_int_device *s)
  79855. +{
  79856. +
  79857. + return 0;
  79858. +}
  79859. +
  79860. +/*!
  79861. + * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
  79862. + * @s: pointer to standard V4L2 device structure
  79863. + * @fmt: pointer to standard V4L2 fmt description structure
  79864. + *
  79865. + * Return 0.
  79866. + */
  79867. +static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
  79868. + struct v4l2_fmtdesc *fmt)
  79869. +{
  79870. + if (fmt->index > ov5640_mode_MAX)
  79871. + return -EINVAL;
  79872. +
  79873. + fmt->pixelformat = ov5640_data.pix.pixelformat;
  79874. +
  79875. + return 0;
  79876. +}
  79877. +
  79878. +/*!
  79879. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  79880. + * @s: pointer to standard V4L2 device structure
  79881. + *
  79882. + * Initialise the device when slave attaches to the master.
  79883. + */
  79884. +static int ioctl_dev_init(struct v4l2_int_device *s)
  79885. +{
  79886. + struct sensor_data *sensor = s->priv;
  79887. + u32 tgt_xclk; /* target xclk */
  79888. + u32 tgt_fps; /* target frames per secound */
  79889. + int ret;
  79890. + enum ov5640_frame_rate frame_rate;
  79891. + void *mipi_csi2_info;
  79892. +
  79893. + ov5640_data.on = true;
  79894. +
  79895. + /* mclk */
  79896. + tgt_xclk = ov5640_data.mclk;
  79897. + tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
  79898. + tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
  79899. + ov5640_data.mclk = tgt_xclk;
  79900. +
  79901. + pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
  79902. +
  79903. + /* Default camera frame rate is set in probe */
  79904. + tgt_fps = sensor->streamcap.timeperframe.denominator /
  79905. + sensor->streamcap.timeperframe.numerator;
  79906. +
  79907. + if (tgt_fps == 15)
  79908. + frame_rate = ov5640_15_fps;
  79909. + else if (tgt_fps == 30)
  79910. + frame_rate = ov5640_30_fps;
  79911. + else
  79912. + return -EINVAL; /* Only support 15fps or 30fps now. */
  79913. +
  79914. + mipi_csi2_info = mipi_csi2_get_info();
  79915. +
  79916. + /* enable mipi csi2 */
  79917. + if (mipi_csi2_info)
  79918. + mipi_csi2_enable(mipi_csi2_info);
  79919. + else {
  79920. + printk(KERN_ERR "%s() in %s: Fail to get mipi_csi2_info!\n",
  79921. + __func__, __FILE__);
  79922. + return -EPERM;
  79923. + }
  79924. +
  79925. + ret = ov5640_init_mode(frame_rate, ov5640_mode_INIT, ov5640_mode_INIT);
  79926. +
  79927. + return ret;
  79928. +}
  79929. +
  79930. +/*!
  79931. + * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
  79932. + * @s: pointer to standard V4L2 device structure
  79933. + *
  79934. + * Delinitialise the device when slave detaches to the master.
  79935. + */
  79936. +static int ioctl_dev_exit(struct v4l2_int_device *s)
  79937. +{
  79938. + void *mipi_csi2_info;
  79939. +
  79940. + mipi_csi2_info = mipi_csi2_get_info();
  79941. +
  79942. + /* disable mipi csi2 */
  79943. + if (mipi_csi2_info)
  79944. + if (mipi_csi2_get_status(mipi_csi2_info))
  79945. + mipi_csi2_disable(mipi_csi2_info);
  79946. +
  79947. + return 0;
  79948. +}
  79949. +
  79950. +/*!
  79951. + * This structure defines all the ioctls for this module and links them to the
  79952. + * enumeration.
  79953. + */
  79954. +static struct v4l2_int_ioctl_desc ov5640_ioctl_desc[] = {
  79955. + {vidioc_int_dev_init_num, (v4l2_int_ioctl_func *) ioctl_dev_init},
  79956. + {vidioc_int_dev_exit_num, ioctl_dev_exit},
  79957. + {vidioc_int_s_power_num, (v4l2_int_ioctl_func *) ioctl_s_power},
  79958. + {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func *) ioctl_g_ifparm},
  79959. +/* {vidioc_int_g_needs_reset_num,
  79960. + (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
  79961. +/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
  79962. + {vidioc_int_init_num, (v4l2_int_ioctl_func *) ioctl_init},
  79963. + {vidioc_int_enum_fmt_cap_num,
  79964. + (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
  79965. +/* {vidioc_int_try_fmt_cap_num,
  79966. + (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
  79967. + {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
  79968. +/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_s_fmt_cap}, */
  79969. + {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
  79970. + {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
  79971. +/* {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func *)ioctl_queryctrl}, */
  79972. + {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
  79973. + {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
  79974. + {vidioc_int_enum_framesizes_num,
  79975. + (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
  79976. + {vidioc_int_g_chip_ident_num,
  79977. + (v4l2_int_ioctl_func *) ioctl_g_chip_ident},
  79978. +};
  79979. +
  79980. +static struct v4l2_int_slave ov5640_slave = {
  79981. + .ioctls = ov5640_ioctl_desc,
  79982. + .num_ioctls = ARRAY_SIZE(ov5640_ioctl_desc),
  79983. +};
  79984. +
  79985. +static struct v4l2_int_device ov5640_int_device = {
  79986. + .module = THIS_MODULE,
  79987. + .name = "ov5640",
  79988. + .type = v4l2_int_type_slave,
  79989. + .u = {
  79990. + .slave = &ov5640_slave,
  79991. + },
  79992. +};
  79993. +
  79994. +/*!
  79995. + * ov5640 I2C probe function
  79996. + *
  79997. + * @param adapter struct i2c_adapter *
  79998. + * @return Error code indicating success or failure
  79999. + */
  80000. +static int ov5640_probe(struct i2c_client *client,
  80001. + const struct i2c_device_id *id)
  80002. +{
  80003. + struct device *dev = &client->dev;
  80004. + int retval;
  80005. + u8 chip_id_high, chip_id_low;
  80006. +
  80007. + /* request power down pin */
  80008. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  80009. + if (!gpio_is_valid(pwn_gpio)) {
  80010. + dev_warn(dev, "no sensor pwdn pin available");
  80011. + return -EINVAL;
  80012. + }
  80013. + retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  80014. + "ov5640_mipi_pwdn");
  80015. + if (retval < 0)
  80016. + return retval;
  80017. +
  80018. + /* request reset pin */
  80019. + rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
  80020. + if (!gpio_is_valid(rst_gpio)) {
  80021. + dev_warn(dev, "no sensor reset pin available");
  80022. + return -EINVAL;
  80023. + }
  80024. + retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
  80025. + "ov5640_mipi_reset");
  80026. + if (retval < 0)
  80027. + return retval;
  80028. +
  80029. + /* Set initial values for the sensor struct. */
  80030. + memset(&ov5640_data, 0, sizeof(ov5640_data));
  80031. + ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
  80032. + if (IS_ERR(ov5640_data.sensor_clk)) {
  80033. + /* assuming clock enabled by default */
  80034. + ov5640_data.sensor_clk = NULL;
  80035. + dev_err(dev, "clock-frequency missing or invalid\n");
  80036. + return PTR_ERR(ov5640_data.sensor_clk);
  80037. + }
  80038. +
  80039. + retval = of_property_read_u32(dev->of_node, "mclk",
  80040. + &(ov5640_data.mclk));
  80041. + if (retval) {
  80042. + dev_err(dev, "mclk missing or invalid\n");
  80043. + return retval;
  80044. + }
  80045. +
  80046. + retval = of_property_read_u32(dev->of_node, "mclk_source",
  80047. + (u32 *) &(ov5640_data.mclk_source));
  80048. + if (retval) {
  80049. + dev_err(dev, "mclk_source missing or invalid\n");
  80050. + return retval;
  80051. + }
  80052. +
  80053. + retval = of_property_read_u32(dev->of_node, "csi_id",
  80054. + &(ov5640_data.csi));
  80055. + if (retval) {
  80056. + dev_err(dev, "csi id missing or invalid\n");
  80057. + return retval;
  80058. + }
  80059. +
  80060. + clk_prepare_enable(ov5640_data.sensor_clk);
  80061. +
  80062. + ov5640_data.io_init = ov5640_reset;
  80063. + ov5640_data.i2c_client = client;
  80064. + ov5640_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
  80065. + ov5640_data.pix.width = 640;
  80066. + ov5640_data.pix.height = 480;
  80067. + ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
  80068. + V4L2_CAP_TIMEPERFRAME;
  80069. + ov5640_data.streamcap.capturemode = 0;
  80070. + ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
  80071. + ov5640_data.streamcap.timeperframe.numerator = 1;
  80072. +
  80073. + ov5640_power_on(dev);
  80074. +
  80075. + ov5640_reset();
  80076. +
  80077. + ov5640_standby(0);
  80078. +
  80079. + retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
  80080. + if (retval < 0 || chip_id_high != 0x56) {
  80081. + pr_warning("camera ov5640_mipi is not found\n");
  80082. + clk_disable_unprepare(ov5640_data.sensor_clk);
  80083. + return -ENODEV;
  80084. + }
  80085. + retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
  80086. + if (retval < 0 || chip_id_low != 0x40) {
  80087. + pr_warning("camera ov5640_mipi is not found\n");
  80088. + clk_disable_unprepare(ov5640_data.sensor_clk);
  80089. + return -ENODEV;
  80090. + }
  80091. +
  80092. + ov5640_standby(1);
  80093. +
  80094. + ov5640_int_device.priv = &ov5640_data;
  80095. + retval = v4l2_int_device_register(&ov5640_int_device);
  80096. +
  80097. + clk_disable_unprepare(ov5640_data.sensor_clk);
  80098. +
  80099. + pr_info("camera ov5640_mipi is found\n");
  80100. + return retval;
  80101. +}
  80102. +
  80103. +/*!
  80104. + * ov5640 I2C detach function
  80105. + *
  80106. + * @param client struct i2c_client *
  80107. + * @return Error code indicating success or failure
  80108. + */
  80109. +static int ov5640_remove(struct i2c_client *client)
  80110. +{
  80111. + v4l2_int_device_unregister(&ov5640_int_device);
  80112. +
  80113. + if (gpo_regulator)
  80114. + regulator_disable(gpo_regulator);
  80115. +
  80116. + if (analog_regulator)
  80117. + regulator_disable(analog_regulator);
  80118. +
  80119. + if (core_regulator)
  80120. + regulator_disable(core_regulator);
  80121. +
  80122. + if (io_regulator)
  80123. + regulator_disable(io_regulator);
  80124. +
  80125. + return 0;
  80126. +}
  80127. +
  80128. +/*!
  80129. + * ov5640 init function
  80130. + * Called by insmod ov5640_camera.ko.
  80131. + *
  80132. + * @return Error code indicating success or failure
  80133. + */
  80134. +static __init int ov5640_init(void)
  80135. +{
  80136. + u8 err;
  80137. +
  80138. + err = i2c_add_driver(&ov5640_i2c_driver);
  80139. + if (err != 0)
  80140. + pr_err("%s:driver registration failed, error=%d\n",
  80141. + __func__, err);
  80142. +
  80143. + return err;
  80144. +}
  80145. +
  80146. +/*!
  80147. + * OV5640 cleanup function
  80148. + * Called on rmmod ov5640_camera.ko
  80149. + *
  80150. + * @return Error code indicating success or failure
  80151. + */
  80152. +static void __exit ov5640_clean(void)
  80153. +{
  80154. + i2c_del_driver(&ov5640_i2c_driver);
  80155. +}
  80156. +
  80157. +module_init(ov5640_init);
  80158. +module_exit(ov5640_clean);
  80159. +
  80160. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  80161. +MODULE_DESCRIPTION("OV5640 MIPI Camera Driver");
  80162. +MODULE_LICENSE("GPL");
  80163. +MODULE_VERSION("1.0");
  80164. +MODULE_ALIAS("CSI");
  80165. diff -Nur linux-3.14.15/drivers/media/platform/mxc/capture/ov5642.c linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ov5642.c
  80166. --- linux-3.14.15/drivers/media/platform/mxc/capture/ov5642.c 1970-01-01 01:00:00.000000000 +0100
  80167. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/capture/ov5642.c 2014-08-20 19:23:52.818842679 +0200
  80168. @@ -0,0 +1,4252 @@
  80169. +/*
  80170. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  80171. + */
  80172. +
  80173. +/*
  80174. + * This program is free software; you can redistribute it and/or modify
  80175. + * it under the terms of the GNU General Public License as published by
  80176. + * the Free Software Foundation; either version 2 of the License, or
  80177. + * (at your option) any later version.
  80178. +
  80179. + * This program is distributed in the hope that it will be useful,
  80180. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  80181. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  80182. + * GNU General Public License for more details.
  80183. +
  80184. + * You should have received a copy of the GNU General Public License along
  80185. + * with this program; if not, write to the Free Software Foundation, Inc.,
  80186. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  80187. + */
  80188. +
  80189. +#include <linux/module.h>
  80190. +#include <linux/init.h>
  80191. +#include <linux/slab.h>
  80192. +#include <linux/ctype.h>
  80193. +#include <linux/types.h>
  80194. +#include <linux/delay.h>
  80195. +#include <linux/clk.h>
  80196. +#include <linux/of_device.h>
  80197. +#include <linux/i2c.h>
  80198. +#include <linux/of_gpio.h>
  80199. +#include <linux/pinctrl/consumer.h>
  80200. +#include <linux/regulator/consumer.h>
  80201. +#include <linux/fsl_devices.h>
  80202. +#include <media/v4l2-chip-ident.h>
  80203. +#include <media/v4l2-int-device.h>
  80204. +#include "mxc_v4l2_capture.h"
  80205. +
  80206. +#define OV5642_VOLTAGE_ANALOG 2800000
  80207. +#define OV5642_VOLTAGE_DIGITAL_CORE 1500000
  80208. +#define OV5642_VOLTAGE_DIGITAL_IO 1800000
  80209. +
  80210. +#define MIN_FPS 15
  80211. +#define MAX_FPS 30
  80212. +#define DEFAULT_FPS 30
  80213. +
  80214. +#define OV5642_XCLK_MIN 6000000
  80215. +#define OV5642_XCLK_MAX 24000000
  80216. +
  80217. +#define OV5642_CHIP_ID_HIGH_BYTE 0x300A
  80218. +#define OV5642_CHIP_ID_LOW_BYTE 0x300B
  80219. +
  80220. +enum ov5642_mode {
  80221. + ov5642_mode_MIN = 0,
  80222. + ov5642_mode_VGA_640_480 = 0,
  80223. + ov5642_mode_QVGA_320_240 = 1,
  80224. + ov5642_mode_NTSC_720_480 = 2,
  80225. + ov5642_mode_PAL_720_576 = 3,
  80226. + ov5642_mode_720P_1280_720 = 4,
  80227. + ov5642_mode_1080P_1920_1080 = 5,
  80228. + ov5642_mode_QSXGA_2592_1944 = 6,
  80229. + ov5642_mode_QCIF_176_144 = 7,
  80230. + ov5642_mode_XGA_1024_768 = 8,
  80231. + ov5642_mode_MAX = 8
  80232. +};
  80233. +
  80234. +enum ov5642_frame_rate {
  80235. + ov5642_15_fps,
  80236. + ov5642_30_fps
  80237. +};
  80238. +
  80239. +static int ov5642_framerates[] = {
  80240. + [ov5642_15_fps] = 15,
  80241. + [ov5642_30_fps] = 30,
  80242. +};
  80243. +
  80244. +struct reg_value {
  80245. + u16 u16RegAddr;
  80246. + u8 u8Val;
  80247. + u8 u8Mask;
  80248. + u32 u32Delay_ms;
  80249. +};
  80250. +
  80251. +struct ov5642_mode_info {
  80252. + enum ov5642_mode mode;
  80253. + u32 width;
  80254. + u32 height;
  80255. + struct reg_value *init_data_ptr;
  80256. + u32 init_data_size;
  80257. +};
  80258. +
  80259. +/*!
  80260. + * Maintains the information on the current state of the sesor.
  80261. + */
  80262. +static struct sensor_data ov5642_data;
  80263. +static int pwn_gpio, rst_gpio;
  80264. +
  80265. +static struct reg_value ov5642_rot_none_VGA[] = {
  80266. + {0x3818, 0xc1, 0x00, 0x00}, {0x3621, 0x87, 0x00, 0x00},
  80267. +};
  80268. +
  80269. +static struct reg_value ov5642_rot_vert_flip_VGA[] = {
  80270. + {0x3818, 0x20, 0xbf, 0x00}, {0x3621, 0x20, 0xff, 0x00},
  80271. +};
  80272. +
  80273. +static struct reg_value ov5642_rot_horiz_flip_VGA[] = {
  80274. + {0x3818, 0x81, 0x00, 0x01}, {0x3621, 0xa7, 0x00, 0x00},
  80275. +};
  80276. +
  80277. +static struct reg_value ov5642_rot_180_VGA[] = {
  80278. + {0x3818, 0x60, 0xff, 0x00}, {0x3621, 0x00, 0xdf, 0x00},
  80279. +};
  80280. +
  80281. +
  80282. +static struct reg_value ov5642_rot_none_FULL[] = {
  80283. + {0x3818, 0xc0, 0x00, 0x00}, {0x3621, 0x09, 0x00, 0x00},
  80284. +};
  80285. +
  80286. +static struct reg_value ov5642_rot_vert_flip_FULL[] = {
  80287. + {0x3818, 0x20, 0xbf, 0x01}, {0x3621, 0x20, 0xff, 0x00},
  80288. +};
  80289. +
  80290. +static struct reg_value ov5642_rot_horiz_flip_FULL[] = {
  80291. + {0x3818, 0x80, 0x00, 0x01}, {0x3621, 0x29, 0x00, 0x00},
  80292. +};
  80293. +
  80294. +static struct reg_value ov5642_rot_180_FULL[] = {
  80295. + {0x3818, 0x60, 0xff, 0x00}, {0x3621, 0x00, 0xdf, 0x00},
  80296. +};
  80297. +
  80298. +
  80299. +static struct reg_value ov5642_initial_setting[] = {
  80300. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  80301. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  80302. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  80303. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  80304. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  80305. + {0x3010, 0x00, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  80306. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  80307. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  80308. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  80309. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  80310. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  80311. + {0x3606, 0x3f, 0, 0}, {0x3c00, 0x04, 0, 0}, {0x3c01, 0x80, 0, 0},
  80312. + {0x5000, 0x4f, 0, 0}, {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0},
  80313. + {0x5182, 0x00, 0, 0}, {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0},
  80314. + {0x5001, 0xff, 0, 0}, {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0},
  80315. + {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0},
  80316. + {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0},
  80317. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  80318. + {0x380b, 0xe0, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0},
  80319. + {0x501f, 0x00, 0, 0}, {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0},
  80320. + {0x3503, 0x07, 0, 0}, {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0},
  80321. + {0x350b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0},
  80322. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  80323. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0},
  80324. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80325. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  80326. + {0x3801, 0x80, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0},
  80327. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0},
  80328. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  80329. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  80330. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  80331. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  80332. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  80333. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  80334. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  80335. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  80336. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  80337. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  80338. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  80339. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  80340. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  80341. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  80342. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  80343. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  80344. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  80345. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x0b, 0, 0}, {0x3a02, 0x00, 0, 0},
  80346. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  80347. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  80348. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  80349. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  80350. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  80351. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  80352. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  80353. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  80354. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  80355. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  80356. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  80357. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  80358. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  80359. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  80360. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  80361. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  80362. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  80363. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  80364. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  80365. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  80366. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  80367. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  80368. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  80369. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  80370. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  80371. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  80372. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  80373. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  80374. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  80375. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  80376. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  80377. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  80378. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  80379. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  80380. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  80381. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  80382. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  80383. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  80384. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  80385. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  80386. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  80387. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  80388. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  80389. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  80390. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  80391. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  80392. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  80393. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  80394. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  80395. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  80396. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  80397. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  80398. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  80399. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  80400. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  80401. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  80402. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  80403. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  80404. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  80405. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  80406. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  80407. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  80408. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  80409. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  80410. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  80411. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  80412. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  80413. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  80414. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  80415. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  80416. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  80417. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  80418. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  80419. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  80420. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  80421. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  80422. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  80423. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  80424. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  80425. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  80426. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  80427. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  80428. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  80429. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  80430. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  80431. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  80432. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  80433. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  80434. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  80435. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  80436. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  80437. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  80438. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  80439. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  80440. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  80441. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  80442. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  80443. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  80444. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  80445. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  80446. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  80447. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  80448. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  80449. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  80450. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  80451. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  80452. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  80453. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  80454. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  80455. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  80456. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  80457. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  80458. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  80459. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  80460. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  80461. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  80462. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  80463. + {0x302b, 0x00, 0, 300},
  80464. +};
  80465. +
  80466. +static struct reg_value ov5642_setting_15fps_QCIF_176_144[] = {
  80467. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  80468. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  80469. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  80470. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  80471. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  80472. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  80473. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  80474. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  80475. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  80476. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  80477. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  80478. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  80479. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  80480. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  80481. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  80482. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  80483. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  80484. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  80485. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  80486. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  80487. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  80488. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  80489. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  80490. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  80491. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  80492. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  80493. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  80494. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  80495. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  80496. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  80497. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  80498. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  80499. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  80500. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  80501. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  80502. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  80503. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  80504. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  80505. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  80506. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  80507. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  80508. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  80509. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  80510. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  80511. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  80512. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  80513. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  80514. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  80515. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  80516. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  80517. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  80518. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  80519. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  80520. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  80521. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  80522. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  80523. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  80524. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  80525. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  80526. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  80527. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  80528. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  80529. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  80530. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  80531. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  80532. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  80533. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  80534. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  80535. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  80536. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  80537. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  80538. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  80539. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  80540. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  80541. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  80542. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  80543. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  80544. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  80545. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  80546. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  80547. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  80548. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  80549. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  80550. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  80551. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  80552. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  80553. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  80554. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  80555. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  80556. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  80557. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  80558. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  80559. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  80560. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  80561. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  80562. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  80563. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  80564. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  80565. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  80566. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  80567. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  80568. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  80569. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  80570. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  80571. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  80572. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  80573. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  80574. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  80575. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  80576. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  80577. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  80578. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  80579. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  80580. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  80581. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  80582. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  80583. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  80584. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  80585. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  80586. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  80587. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  80588. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  80589. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  80590. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  80591. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  80592. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  80593. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  80594. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  80595. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  80596. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  80597. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  80598. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  80599. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  80600. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  80601. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  80602. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  80603. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  80604. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  80605. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  80606. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  80607. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  80608. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  80609. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  80610. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  80611. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  80612. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  80613. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  80614. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  80615. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  80616. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  80617. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  80618. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  80619. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  80620. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  80621. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  80622. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  80623. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  80624. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  80625. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  80626. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  80627. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  80628. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  80629. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  80630. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  80631. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  80632. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  80633. + {0x380b, 0x90, 0, 0}, {0x3a00, 0x78, 0, 0},
  80634. +};
  80635. +
  80636. +static struct reg_value ov5642_setting_30fps_QCIF_176_144[] = {
  80637. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  80638. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  80639. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  80640. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  80641. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x10, 0, 0},
  80642. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  80643. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  80644. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  80645. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  80646. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  80647. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  80648. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  80649. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  80650. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  80651. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  80652. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  80653. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  80654. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  80655. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  80656. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  80657. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  80658. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  80659. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  80660. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  80661. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  80662. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  80663. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  80664. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  80665. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  80666. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  80667. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  80668. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  80669. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  80670. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  80671. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  80672. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  80673. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  80674. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  80675. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  80676. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  80677. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  80678. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  80679. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  80680. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  80681. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  80682. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  80683. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  80684. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  80685. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  80686. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  80687. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  80688. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  80689. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  80690. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  80691. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  80692. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  80693. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  80694. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  80695. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  80696. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  80697. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  80698. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  80699. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  80700. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  80701. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  80702. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  80703. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  80704. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  80705. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  80706. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  80707. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  80708. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  80709. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  80710. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  80711. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  80712. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  80713. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  80714. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  80715. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  80716. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  80717. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  80718. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  80719. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  80720. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  80721. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  80722. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  80723. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  80724. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  80725. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  80726. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  80727. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  80728. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  80729. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  80730. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  80731. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  80732. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  80733. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  80734. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  80735. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  80736. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  80737. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  80738. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  80739. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  80740. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  80741. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  80742. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  80743. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  80744. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  80745. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  80746. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  80747. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  80748. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  80749. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  80750. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  80751. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  80752. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  80753. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  80754. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  80755. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  80756. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  80757. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  80758. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  80759. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  80760. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  80761. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  80762. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  80763. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  80764. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  80765. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  80766. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  80767. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  80768. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  80769. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  80770. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  80771. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  80772. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  80773. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  80774. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  80775. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  80776. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  80777. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  80778. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  80779. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  80780. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  80781. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  80782. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  80783. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  80784. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  80785. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  80786. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  80787. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  80788. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  80789. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  80790. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  80791. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  80792. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  80793. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  80794. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  80795. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  80796. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  80797. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  80798. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  80799. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  80800. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  80801. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  80802. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  80803. + {0x380b, 0x90, 0, 0}, {0x3a00, 0x78, 0, 0},
  80804. +};
  80805. +
  80806. +static struct reg_value ov5642_setting_15fps_QSXGA_2592_1944[] = {
  80807. + {0x3503, 0x07, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0},
  80808. + {0x3002, 0x00, 0, 0}, {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
  80809. + {0x3005, 0xff, 0, 0}, {0x3006, 0xff, 0, 0}, {0x3007, 0x3f, 0, 0},
  80810. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3818, 0xc0, 0, 0},
  80811. + {0x3621, 0x09, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  80812. + {0x3602, 0xe4, 0, 0}, {0x3612, 0xac, 0, 0}, {0x3613, 0x44, 0, 0},
  80813. + {0x3622, 0x60, 0, 0}, {0x3623, 0x22, 0, 0}, {0x3604, 0x48, 0, 0},
  80814. + {0x3705, 0xda, 0, 0}, {0x370a, 0x80, 0, 0}, {0x3801, 0x95, 0, 0},
  80815. + {0x3803, 0x0e, 0, 0}, {0x3804, 0x0a, 0, 0}, {0x3805, 0x20, 0, 0},
  80816. + {0x3806, 0x07, 0, 0}, {0x3807, 0x98, 0, 0}, {0x3808, 0x0a, 0, 0},
  80817. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  80818. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  80819. + {0x380f, 0xd0, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3815, 0x44, 0, 0},
  80820. + {0x3824, 0x11, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  80821. + {0x3a00, 0x78, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  80822. + {0x5682, 0x0a, 0, 0}, {0x5683, 0x20, 0, 0}, {0x5686, 0x07, 0, 0},
  80823. + {0x5687, 0x98, 0, 0}, {0x5001, 0xff, 0, 0}, {0x589b, 0x00, 0, 0},
  80824. + {0x589a, 0xc0, 0, 0}, {0x4407, 0x04, 0, 0}, {0x3008, 0x02, 0, 0},
  80825. + {0x460b, 0x37, 0, 0}, {0x460c, 0x22, 0, 0}, {0x471d, 0x05, 0, 0},
  80826. + {0x4713, 0x03, 0, 0}, {0x471c, 0xd0, 0, 0}, {0x3815, 0x01, 0, 0},
  80827. + {0x501f, 0x00, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3819, 0x80, 0, 0},
  80828. + {0x5002, 0xe0, 0, 0}, {0x530a, 0x01, 0, 0}, {0x530d, 0x10, 0, 0},
  80829. + {0x530c, 0x04, 0, 0}, {0x5312, 0x20, 0, 0}, {0x5282, 0x01, 0, 0},
  80830. + {0x3010, 0x10, 0, 0}, {0x3012, 0x00, 0, 0},
  80831. +};
  80832. +
  80833. +
  80834. +static struct reg_value ov5642_setting_VGA_2_QVGA[] = {
  80835. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  80836. + {0x380b, 0xf0, 0, 0}, {0x3815, 0x04, 0, 0},
  80837. +};
  80838. +
  80839. +static struct reg_value ov5642_setting_QSXGA_2_VGA[] = {
  80840. + {0x3503, 0x00, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0},
  80841. + {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
  80842. + {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0},
  80843. + {0x3010, 0x00, 0, 0}, {0x3818, 0xc1, 0, 0}, {0x3621, 0x87, 0, 0},
  80844. + {0x350c, 0x03, 0, 0}, {0x350d, 0xe8, 0, 0}, {0x3602, 0xfc, 0, 0},
  80845. + {0x3612, 0xff, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3622, 0x60, 0, 0},
  80846. + {0x3623, 0x01, 0, 0}, {0x3604, 0x48, 0, 0}, {0x3705, 0xdb, 0, 0},
  80847. + {0x370a, 0x81, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  80848. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x3806, 0x03, 0, 0},
  80849. + {0x3807, 0xc0, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
  80850. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x0c, 0, 0},
  80851. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  80852. + {0x3810, 0x40, 0, 0}, {0x3815, 0x04, 0, 0}, {0x3824, 0x11, 0, 0},
  80853. + {0x3825, 0xb4, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3a00, 0x78, 0, 0},
  80854. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x5682, 0x05, 0, 0},
  80855. + {0x5683, 0x00, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0},
  80856. + {0x5001, 0xff, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  80857. + {0x4407, 0x0c, 0, 0}, {0x3008, 0x02, 0, 0}, {0x460b, 0x37, 0, 0},
  80858. + {0x460c, 0x22, 0, 0}, {0x471d, 0x05, 0, 0}, {0x4713, 0x02, 0, 0},
  80859. + {0x471c, 0xd0, 0, 0}, {0x3815, 0x04, 0, 0}, {0x501f, 0x00, 0, 0},
  80860. + {0x3002, 0x5c, 0, 0}, {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0},
  80861. + {0x530a, 0x01, 0, 0}, {0x530d, 0x0c, 0, 0}, {0x530c, 0x00, 0, 0},
  80862. + {0x5312, 0x40, 0, 0}, {0x5282, 0x00, 0, 0},
  80863. + {0x3012, 0x02, 0, 0}, {0x3010, 0x00, 0, 0},
  80864. +};
  80865. +
  80866. +static struct reg_value ov5642_setting_30fps_VGA_640_480[] = {
  80867. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  80868. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  80869. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  80870. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  80871. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  80872. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  80873. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  80874. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  80875. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  80876. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  80877. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  80878. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  80879. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  80880. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  80881. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  80882. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  80883. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  80884. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  80885. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  80886. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  80887. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  80888. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  80889. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  80890. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  80891. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80892. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  80893. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  80894. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  80895. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  80896. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  80897. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  80898. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  80899. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  80900. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  80901. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  80902. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  80903. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  80904. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  80905. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  80906. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  80907. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  80908. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  80909. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  80910. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  80911. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  80912. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  80913. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  80914. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  80915. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  80916. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80917. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  80918. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  80919. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  80920. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  80921. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  80922. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  80923. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  80924. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  80925. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  80926. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  80927. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  80928. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  80929. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  80930. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  80931. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  80932. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  80933. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  80934. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  80935. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  80936. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  80937. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  80938. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  80939. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  80940. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  80941. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  80942. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  80943. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  80944. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  80945. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  80946. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  80947. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  80948. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  80949. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  80950. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  80951. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  80952. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  80953. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  80954. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  80955. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  80956. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  80957. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  80958. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  80959. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  80960. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  80961. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  80962. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  80963. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  80964. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  80965. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  80966. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  80967. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  80968. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  80969. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  80970. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  80971. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  80972. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  80973. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  80974. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  80975. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  80976. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  80977. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  80978. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  80979. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  80980. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  80981. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  80982. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  80983. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  80984. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  80985. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  80986. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  80987. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  80988. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  80989. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  80990. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  80991. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  80992. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  80993. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  80994. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  80995. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  80996. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  80997. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  80998. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  80999. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81000. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81001. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81002. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81003. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81004. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81005. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81006. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81007. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  81008. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  81009. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  81010. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  81011. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  81012. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  81013. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  81014. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  81015. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  81016. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  81017. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  81018. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  81019. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  81020. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  81021. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  81022. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  81023. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  81024. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  81025. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  81026. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  81027. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  81028. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81029. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81030. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81031. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81032. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  81033. +};
  81034. +
  81035. +static struct reg_value ov5642_setting_15fps_VGA_640_480[] = {
  81036. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81037. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81038. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81039. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81040. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81041. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81042. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81043. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81044. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81045. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81046. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81047. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81048. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81049. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81050. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81051. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81052. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81053. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  81054. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81055. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81056. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81057. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  81058. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81059. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x07, 0, 0},
  81060. + {0x380f, 0xd0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81061. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81062. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81063. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  81064. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  81065. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  81066. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  81067. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81068. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81069. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81070. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81071. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81072. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81073. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81074. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81075. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81076. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81077. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81078. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81079. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81080. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81081. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81082. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81083. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81084. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81085. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81086. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81087. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81088. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81089. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81090. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81091. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81092. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81093. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81094. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81095. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81096. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81097. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81098. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81099. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81100. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81101. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81102. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81103. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81104. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81105. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81106. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81107. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81108. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81109. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81110. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81111. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81112. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81113. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81114. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81115. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81116. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81117. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81118. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81119. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81120. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81121. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81122. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81123. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81124. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81125. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81126. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81127. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81128. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81129. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81130. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81131. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81132. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81133. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81134. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81135. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81136. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81137. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81138. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81139. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81140. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81141. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81142. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81143. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81144. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81145. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81146. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81147. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  81148. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  81149. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  81150. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  81151. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  81152. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  81153. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  81154. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  81155. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  81156. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  81157. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  81158. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  81159. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  81160. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  81161. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  81162. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  81163. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  81164. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  81165. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  81166. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  81167. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  81168. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81169. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81170. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81171. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81172. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81173. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81174. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81175. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81176. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  81177. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  81178. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  81179. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  81180. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  81181. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  81182. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  81183. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  81184. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  81185. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  81186. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  81187. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  81188. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  81189. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  81190. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  81191. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  81192. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  81193. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  81194. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  81195. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  81196. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  81197. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81198. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81199. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81200. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81201. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  81202. +};
  81203. +
  81204. +
  81205. +static struct reg_value ov5642_setting_30fps_XGA_1024_768[] = {
  81206. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81207. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81208. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81209. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81210. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81211. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81212. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81213. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81214. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81215. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81216. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81217. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81218. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81219. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81220. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81221. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81222. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81223. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  81224. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81225. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81226. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81227. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  81228. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81229. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  81230. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81231. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81232. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81233. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  81234. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  81235. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  81236. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  81237. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81238. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81239. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81240. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81241. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81242. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81243. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81244. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81245. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81246. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81247. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81248. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81249. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81250. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81251. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81252. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81253. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81254. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81255. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81256. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81257. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81258. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81259. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81260. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81261. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81262. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81263. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81264. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81265. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81266. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81267. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81268. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81269. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81270. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81271. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81272. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81273. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81274. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81275. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81276. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81277. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81278. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81279. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81280. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81281. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81282. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81283. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81284. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81285. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81286. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81287. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81288. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81289. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81290. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81291. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81292. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81293. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81294. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81295. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81296. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81297. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81298. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81299. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81300. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81301. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81302. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81303. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81304. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81305. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81306. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81307. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81308. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81309. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81310. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81311. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81312. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81313. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81314. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81315. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81316. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81317. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  81318. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  81319. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  81320. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  81321. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  81322. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  81323. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  81324. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  81325. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  81326. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  81327. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  81328. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  81329. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  81330. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  81331. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  81332. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  81333. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  81334. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  81335. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  81336. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  81337. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  81338. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81339. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81340. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81341. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81342. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81343. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81344. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81345. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81346. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  81347. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  81348. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  81349. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  81350. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  81351. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  81352. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  81353. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  81354. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  81355. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  81356. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  81357. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  81358. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  81359. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  81360. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  81361. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  81362. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  81363. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  81364. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  81365. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  81366. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  81367. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81368. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81369. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81370. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81371. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  81372. + {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
  81373. + {0x380b, 0x00, 0, 0}, {0x3815, 0x02, 0, 0}, {0x302c, 0x60, 0x60, 0},
  81374. +};
  81375. +
  81376. +static struct reg_value ov5642_setting_15fps_XGA_1024_768[] = {
  81377. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81378. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81379. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81380. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81381. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81382. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81383. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81384. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81385. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81386. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81387. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81388. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81389. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81390. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81391. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81392. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81393. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81394. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  81395. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81396. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81397. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81398. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  81399. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81400. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x07, 0, 0},
  81401. + {0x380f, 0xd0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81402. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81403. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81404. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  81405. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  81406. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  81407. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  81408. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81409. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81410. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81411. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81412. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81413. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81414. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81415. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81416. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81417. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81418. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81419. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81420. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81421. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81422. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81423. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81424. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81425. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81426. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81427. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81428. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81429. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81430. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81431. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81432. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81433. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81434. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81435. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81436. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81437. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81438. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81439. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81440. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81441. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81442. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81443. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81444. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81445. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81446. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81447. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81448. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81449. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81450. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81451. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81452. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81453. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81454. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81455. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81456. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81457. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81458. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81459. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81460. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81461. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81462. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81463. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81464. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81465. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81466. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81467. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81468. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81469. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81470. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81471. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81472. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81473. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81474. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81475. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81476. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81477. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81478. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81479. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81480. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81481. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81482. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81483. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81484. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81485. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81486. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81487. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81488. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  81489. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  81490. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  81491. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  81492. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  81493. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  81494. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  81495. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  81496. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  81497. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  81498. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  81499. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  81500. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  81501. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  81502. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  81503. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  81504. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  81505. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  81506. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  81507. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  81508. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  81509. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81510. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81511. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81512. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81513. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81514. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81515. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81516. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81517. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  81518. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  81519. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  81520. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  81521. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  81522. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  81523. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  81524. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  81525. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  81526. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  81527. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  81528. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  81529. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  81530. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  81531. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  81532. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  81533. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  81534. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  81535. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  81536. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  81537. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  81538. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81539. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81540. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81541. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81542. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  81543. + {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
  81544. + {0x380b, 0x00, 0, 0}, {0x3815, 0x02, 0, 0}, {0x302c, 0x60, 0x60, 0},
  81545. +};
  81546. +
  81547. +static struct reg_value ov5642_setting_30fps_QVGA_320_240[] = {
  81548. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81549. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81550. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81551. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81552. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81553. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81554. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81555. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81556. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81557. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81558. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81559. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81560. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81561. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81562. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81563. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81564. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81565. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  81566. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81567. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81568. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81569. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  81570. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81571. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  81572. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81573. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81574. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81575. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  81576. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  81577. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  81578. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  81579. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81580. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81581. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81582. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81583. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81584. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81585. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81586. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81587. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81588. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81589. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81590. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81591. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81592. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81593. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81594. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81595. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81596. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81597. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81598. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81599. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81600. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81601. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81602. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81603. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81604. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81605. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81606. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81607. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81608. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81609. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81610. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81611. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81612. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81613. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81614. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81615. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81616. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81617. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81618. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81619. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81620. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81621. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81622. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81623. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81624. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81625. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81626. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81627. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81628. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81629. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81630. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81631. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81632. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81633. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81634. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81635. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81636. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81637. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81638. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81639. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81640. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81641. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81642. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81643. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81644. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81645. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81646. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81647. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81648. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81649. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81650. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81651. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81652. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81653. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81654. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81655. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81656. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81657. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81658. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81659. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  81660. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  81661. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  81662. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  81663. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  81664. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  81665. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  81666. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  81667. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  81668. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  81669. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  81670. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  81671. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  81672. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  81673. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  81674. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  81675. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  81676. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  81677. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  81678. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  81679. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  81680. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81681. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81682. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81683. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81684. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81685. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81686. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81687. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81688. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  81689. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  81690. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  81691. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  81692. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  81693. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  81694. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  81695. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  81696. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  81697. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  81698. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  81699. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  81700. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  81701. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  81702. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  81703. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  81704. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  81705. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  81706. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  81707. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  81708. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  81709. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81710. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81711. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81712. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81713. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3808, 0x01, 0, 0},
  81714. + {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0},
  81715. +};
  81716. +
  81717. +static struct reg_value ov5642_setting_30fps_NTSC_720_480[] = {
  81718. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81719. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81720. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81721. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81722. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81723. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81724. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81725. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81726. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81727. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81728. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81729. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81730. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81731. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81732. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81733. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81734. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81735. + {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  81736. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81737. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81738. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81739. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  81740. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81741. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  81742. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81743. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81744. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81745. + {0x3803, 0x08, 0, 0}, {0x3827, 0x3c, 0, 0}, {0x3810, 0x80, 0, 0},
  81746. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  81747. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0x58, 0, 0},
  81748. + {0x5686, 0x03, 0, 0}, {0x5687, 0x58, 0, 0}, {0x3a00, 0x78, 0, 0},
  81749. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81750. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81751. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81752. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81753. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81754. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81755. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81756. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81757. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81758. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81759. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81760. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81761. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81762. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81763. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81764. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81765. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81766. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81767. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81768. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81769. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81770. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81771. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81772. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81773. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81774. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81775. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81776. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81777. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81778. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81779. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81780. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81781. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81782. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81783. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81784. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81785. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81786. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81787. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81788. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81789. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81790. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81791. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81792. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81793. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81794. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81795. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81796. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81797. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81798. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81799. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81800. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81801. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81802. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81803. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81804. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81805. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81806. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81807. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81808. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81809. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81810. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81811. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81812. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81813. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81814. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81815. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81816. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81817. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81818. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81819. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81820. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81821. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81822. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81823. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81824. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81825. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81826. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81827. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81828. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81829. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  81830. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  81831. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  81832. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  81833. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  81834. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  81835. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  81836. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  81837. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  81838. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  81839. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  81840. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  81841. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  81842. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  81843. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  81844. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  81845. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  81846. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  81847. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  81848. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  81849. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  81850. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81851. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81852. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81853. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81854. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81855. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81856. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81857. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81858. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  81859. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  81860. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  81861. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  81862. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  81863. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  81864. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  81865. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  81866. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  81867. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  81868. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  81869. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  81870. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  81871. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  81872. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  81873. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  81874. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  81875. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  81876. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  81877. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  81878. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  81879. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81880. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81881. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81882. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81883. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  81884. + {0x302c, 0x60, 0x60, 0},
  81885. +};
  81886. +
  81887. +static struct reg_value ov5642_setting_30fps_PAL_720_576[] = {
  81888. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81889. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81890. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81891. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81892. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81893. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81894. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81895. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81896. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81897. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81898. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81899. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81900. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81901. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81902. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81903. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81904. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81905. + {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0},
  81906. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81907. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81908. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81909. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xd8, 0, 0},
  81910. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81911. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  81912. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81913. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81914. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81915. + {0x3803, 0x08, 0, 0}, {0x3827, 0x3c, 0, 0}, {0x3810, 0x80, 0, 0},
  81916. + {0x3804, 0x04, 0, 0}, {0x3805, 0xb0, 0, 0}, {0x5682, 0x04, 0, 0},
  81917. + {0x5683, 0xb0, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0x58, 0, 0},
  81918. + {0x5686, 0x03, 0, 0}, {0x5687, 0x58, 0, 0}, {0x3a00, 0x78, 0, 0},
  81919. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81920. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81921. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81922. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81923. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81924. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81925. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81926. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81927. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81928. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81929. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81930. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81931. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81932. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81933. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81934. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81935. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81936. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81937. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81938. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81939. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81940. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81941. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81942. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81943. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81944. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81945. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81946. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81947. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81948. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81949. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81950. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81951. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81952. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81953. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81954. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81955. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81956. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81957. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81958. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81959. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81960. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81961. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81962. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81963. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81964. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81965. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81966. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81967. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81968. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81969. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81970. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81971. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81972. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81973. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81974. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81975. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81976. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81977. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81978. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81979. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81980. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81981. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81982. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81983. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81984. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81985. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81986. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81987. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81988. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81989. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81990. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81991. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81992. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81993. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81994. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81995. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81996. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81997. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81998. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81999. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  82000. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  82001. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  82002. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  82003. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  82004. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  82005. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  82006. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  82007. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  82008. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  82009. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  82010. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  82011. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  82012. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  82013. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  82014. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  82015. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  82016. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  82017. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  82018. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  82019. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  82020. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  82021. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  82022. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  82023. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  82024. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  82025. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  82026. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  82027. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  82028. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  82029. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  82030. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  82031. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  82032. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  82033. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  82034. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  82035. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  82036. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  82037. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  82038. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  82039. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  82040. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  82041. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  82042. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  82043. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  82044. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  82045. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  82046. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  82047. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  82048. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  82049. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  82050. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  82051. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  82052. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  82053. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  82054. + {0x302c, 0x60, 0x60, 0},
  82055. +};
  82056. +
  82057. +static struct reg_value ov5642_setting_15fps_720P_1280_720[] = {
  82058. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82059. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82060. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
  82061. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
  82062. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
  82063. + {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
  82064. + {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
  82065. + {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
  82066. + {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
  82067. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82068. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
  82069. + {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
  82070. + {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
  82071. + {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
  82072. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  82073. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  82074. + {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
  82075. + {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
  82076. + {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
  82077. + {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
  82078. + {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
  82079. + {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
  82080. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82081. + {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
  82082. + {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
  82083. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
  82084. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
  82085. + {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
  82086. + {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  82087. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  82088. + {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
  82089. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
  82090. + {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  82091. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  82092. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  82093. + {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
  82094. + {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  82095. + {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
  82096. + {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
  82097. + {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  82098. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82099. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  82100. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  82101. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  82102. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  82103. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  82104. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  82105. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  82106. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  82107. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  82108. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  82109. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  82110. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  82111. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  82112. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  82113. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  82114. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  82115. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  82116. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  82117. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  82118. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  82119. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  82120. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  82121. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  82122. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  82123. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  82124. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  82125. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  82126. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  82127. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  82128. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  82129. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  82130. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  82131. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  82132. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  82133. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  82134. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  82135. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  82136. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  82137. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  82138. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  82139. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  82140. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  82141. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  82142. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  82143. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  82144. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  82145. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  82146. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  82147. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  82148. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  82149. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  82150. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  82151. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82152. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  82153. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  82154. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  82155. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  82156. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  82157. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  82158. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  82159. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  82160. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  82161. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  82162. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  82163. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  82164. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  82165. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  82166. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  82167. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  82168. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  82169. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  82170. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  82171. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  82172. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  82173. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  82174. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  82175. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  82176. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  82177. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  82178. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  82179. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  82180. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  82181. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  82182. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  82183. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  82184. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  82185. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  82186. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  82187. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  82188. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  82189. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  82190. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  82191. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  82192. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  82193. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  82194. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  82195. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  82196. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  82197. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  82198. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  82199. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  82200. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  82201. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  82202. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  82203. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  82204. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  82205. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  82206. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  82207. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  82208. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  82209. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  82210. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  82211. + {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x08, 0, 0},
  82212. + {0x350c, 0x02, 0, 0}, {0x350d, 0xe4, 0, 0}, {0x3621, 0xc9, 0, 0},
  82213. + {0x370a, 0x81, 0, 0}, {0x3803, 0x08, 0, 0}, {0x3804, 0x05, 0, 0},
  82214. + {0x3805, 0x00, 0, 0}, {0x3806, 0x02, 0, 0}, {0x3807, 0xd0, 0, 0},
  82215. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  82216. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x08, 0, 0}, {0x380d, 0x72, 0, 0},
  82217. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0xc0, 0, 0},
  82218. + {0x3818, 0xc9, 0, 0}, {0x381c, 0x10, 0, 0}, {0x381d, 0xa0, 0, 0},
  82219. + {0x381e, 0x05, 0, 0}, {0x381f, 0xb0, 0, 0}, {0x3820, 0x00, 0, 0},
  82220. + {0x3821, 0x00, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3a08, 0x1b, 0, 0},
  82221. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x17, 0, 0}, {0x3a0b, 0x20, 0, 0},
  82222. + {0x3a0d, 0x02, 0, 0}, {0x3a0e, 0x01, 0, 0}, {0x401c, 0x04, 0, 0},
  82223. + {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0}, {0x5686, 0x02, 0, 0},
  82224. + {0x5687, 0xcc, 0, 0}, {0x5001, 0x7f, 0, 0}, {0x589b, 0x06, 0, 0},
  82225. + {0x589a, 0xc5, 0, 0}, {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0},
  82226. + {0x460c, 0x20, 0, 0}, {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0},
  82227. + {0x471d, 0x05, 0, 0}, {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0},
  82228. + {0x501f, 0x00, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0},
  82229. + {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0}, {0x3010, 0x30, 0, 0},
  82230. + {0x3a08, 0x06, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x05, 0, 0},
  82231. + {0x3a0b, 0x50, 0, 0}, {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x07, 0, 0},
  82232. +};
  82233. +
  82234. +static struct reg_value ov5642_setting_30fps_720P_1280_720[] = {
  82235. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82236. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82237. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
  82238. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
  82239. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
  82240. + {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
  82241. + {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
  82242. + {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
  82243. + {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
  82244. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82245. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
  82246. + {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
  82247. + {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
  82248. + {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
  82249. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  82250. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  82251. + {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
  82252. + {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
  82253. + {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
  82254. + {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
  82255. + {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
  82256. + {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
  82257. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82258. + {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
  82259. + {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
  82260. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
  82261. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
  82262. + {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
  82263. + {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  82264. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  82265. + {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
  82266. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
  82267. + {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  82268. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  82269. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  82270. + {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
  82271. + {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  82272. + {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
  82273. + {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
  82274. + {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  82275. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82276. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  82277. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  82278. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  82279. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  82280. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  82281. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  82282. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  82283. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  82284. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  82285. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  82286. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  82287. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  82288. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  82289. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  82290. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  82291. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  82292. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  82293. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  82294. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  82295. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  82296. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  82297. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  82298. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  82299. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  82300. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  82301. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  82302. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  82303. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  82304. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  82305. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  82306. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  82307. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  82308. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  82309. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  82310. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  82311. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  82312. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  82313. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  82314. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  82315. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  82316. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  82317. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  82318. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  82319. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  82320. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  82321. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  82322. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  82323. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  82324. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  82325. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  82326. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  82327. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  82328. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82329. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  82330. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  82331. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  82332. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  82333. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  82334. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  82335. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  82336. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  82337. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  82338. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  82339. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  82340. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  82341. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  82342. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  82343. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  82344. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  82345. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  82346. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  82347. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  82348. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  82349. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  82350. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  82351. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  82352. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  82353. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  82354. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  82355. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  82356. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  82357. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  82358. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  82359. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  82360. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  82361. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  82362. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  82363. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  82364. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  82365. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  82366. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  82367. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  82368. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  82369. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  82370. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  82371. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  82372. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  82373. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  82374. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  82375. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  82376. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  82377. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  82378. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  82379. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  82380. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  82381. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  82382. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  82383. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  82384. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  82385. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  82386. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  82387. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  82388. + {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x08, 0, 0},
  82389. + {0x350c, 0x02, 0, 0}, {0x350d, 0xe4, 0, 0}, {0x3621, 0xc9, 0, 0},
  82390. + {0x370a, 0x81, 0, 0}, {0x3803, 0x08, 0, 0}, {0x3804, 0x05, 0, 0},
  82391. + {0x3805, 0x00, 0, 0}, {0x3806, 0x02, 0, 0}, {0x3807, 0xd0, 0, 0},
  82392. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  82393. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x08, 0, 0}, {0x380d, 0x72, 0, 0},
  82394. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0xc0, 0, 0},
  82395. + {0x3818, 0xc9, 0, 0}, {0x381c, 0x10, 0, 0}, {0x381d, 0xa0, 0, 0},
  82396. + {0x381e, 0x05, 0, 0}, {0x381f, 0xb0, 0, 0}, {0x3820, 0x00, 0, 0},
  82397. + {0x3821, 0x00, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3a08, 0x1b, 0, 0},
  82398. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x17, 0, 0}, {0x3a0b, 0x20, 0, 0},
  82399. + {0x3a0d, 0x02, 0, 0}, {0x3a0e, 0x01, 0, 0}, {0x401c, 0x04, 0, 0},
  82400. + {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0}, {0x5686, 0x02, 0, 0},
  82401. + {0x5687, 0xcc, 0, 0}, {0x5001, 0x7f, 0, 0}, {0x589b, 0x06, 0, 0},
  82402. + {0x589a, 0xc5, 0, 0}, {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0},
  82403. + {0x460c, 0x20, 0, 0}, {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0},
  82404. + {0x471d, 0x05, 0, 0}, {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0},
  82405. + {0x501f, 0x00, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0},
  82406. + {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0},
  82407. +};
  82408. +
  82409. +static struct reg_value ov5642_setting_15fps_1080P_1920_1080[] = {
  82410. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82411. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82412. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
  82413. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
  82414. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
  82415. + {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
  82416. + {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
  82417. + {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
  82418. + {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
  82419. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82420. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
  82421. + {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
  82422. + {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
  82423. + {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
  82424. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  82425. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  82426. + {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
  82427. + {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
  82428. + {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
  82429. + {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
  82430. + {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
  82431. + {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
  82432. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82433. + {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
  82434. + {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
  82435. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
  82436. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
  82437. + {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
  82438. + {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  82439. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  82440. + {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
  82441. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
  82442. + {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  82443. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  82444. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  82445. + {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
  82446. + {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  82447. + {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
  82448. + {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
  82449. + {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  82450. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82451. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  82452. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  82453. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  82454. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  82455. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  82456. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  82457. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  82458. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  82459. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  82460. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  82461. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  82462. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  82463. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  82464. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  82465. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  82466. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  82467. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  82468. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  82469. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  82470. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  82471. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  82472. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  82473. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  82474. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  82475. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  82476. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  82477. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  82478. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  82479. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  82480. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  82481. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  82482. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  82483. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  82484. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  82485. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  82486. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  82487. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  82488. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  82489. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  82490. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  82491. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  82492. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  82493. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  82494. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  82495. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  82496. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  82497. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  82498. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  82499. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  82500. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  82501. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  82502. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  82503. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82504. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  82505. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  82506. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  82507. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  82508. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  82509. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  82510. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  82511. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  82512. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  82513. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  82514. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  82515. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  82516. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  82517. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  82518. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  82519. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  82520. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  82521. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  82522. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  82523. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  82524. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  82525. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  82526. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  82527. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  82528. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  82529. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  82530. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  82531. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  82532. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  82533. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  82534. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  82535. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  82536. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  82537. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  82538. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  82539. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  82540. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  82541. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  82542. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  82543. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  82544. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  82545. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  82546. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  82547. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  82548. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  82549. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  82550. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  82551. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  82552. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  82553. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  82554. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  82555. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  82556. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  82557. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  82558. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  82559. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  82560. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  82561. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  82562. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  82563. + {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x07, 0, 0},
  82564. + {0x350c, 0x04, 0, 0}, {0x350d, 0x58, 0, 0}, {0x3801, 0x8a, 0, 0},
  82565. + {0x3803, 0x0a, 0, 0}, {0x3804, 0x07, 0, 0}, {0x3805, 0x80, 0, 0},
  82566. + {0x3806, 0x04, 0, 0}, {0x3807, 0x39, 0, 0}, {0x3808, 0x07, 0, 0},
  82567. + {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
  82568. + {0x380c, 0x09, 0, 0}, {0x380d, 0xd6, 0, 0}, {0x380e, 0x04, 0, 0},
  82569. + {0x380f, 0x58, 0, 0}, {0x381c, 0x11, 0, 0}, {0x381d, 0xba, 0, 0},
  82570. + {0x381e, 0x04, 0, 0}, {0x381f, 0x48, 0, 0}, {0x3820, 0x04, 0, 0},
  82571. + {0x3821, 0x18, 0, 0}, {0x3a08, 0x14, 0, 0}, {0x3a09, 0xe0, 0, 0},
  82572. + {0x3a0a, 0x11, 0, 0}, {0x3a0b, 0x60, 0, 0}, {0x3a0d, 0x04, 0, 0},
  82573. + {0x3a0e, 0x03, 0, 0}, {0x5682, 0x07, 0, 0}, {0x5683, 0x60, 0, 0},
  82574. + {0x5686, 0x04, 0, 0}, {0x5687, 0x1c, 0, 0}, {0x5001, 0x7f, 0, 0},
  82575. + {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0}, {0x460c, 0x20, 0, 0},
  82576. + {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0}, {0x471d, 0x05, 0, 0},
  82577. + {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0}, {0x501f, 0x00, 0, 0},
  82578. + {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3819, 0x80, 0, 0},
  82579. + {0x5002, 0xe0, 0, 0},
  82580. +};
  82581. +
  82582. +static struct reg_value ov5642_setting_15fps_QVGA_320_240[] = {
  82583. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82584. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82585. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  82586. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  82587. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  82588. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  82589. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  82590. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  82591. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  82592. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  82593. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  82594. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  82595. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82596. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  82597. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  82598. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  82599. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  82600. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  82601. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  82602. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  82603. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82604. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  82605. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  82606. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  82607. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  82608. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  82609. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  82610. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  82611. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  82612. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  82613. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  82614. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  82615. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  82616. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  82617. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  82618. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  82619. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82620. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  82621. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  82622. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  82623. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  82624. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  82625. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  82626. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  82627. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82628. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  82629. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  82630. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  82631. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  82632. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  82633. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  82634. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  82635. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  82636. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  82637. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  82638. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  82639. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  82640. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  82641. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  82642. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  82643. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  82644. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  82645. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  82646. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  82647. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  82648. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  82649. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  82650. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  82651. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  82652. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  82653. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  82654. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  82655. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  82656. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  82657. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  82658. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  82659. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  82660. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  82661. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  82662. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  82663. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  82664. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  82665. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  82666. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  82667. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  82668. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  82669. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  82670. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  82671. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  82672. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  82673. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  82674. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  82675. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  82676. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  82677. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  82678. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  82679. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  82680. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  82681. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  82682. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  82683. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  82684. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  82685. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  82686. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  82687. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  82688. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  82689. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  82690. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  82691. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  82692. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  82693. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  82694. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  82695. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  82696. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  82697. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  82698. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  82699. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  82700. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  82701. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  82702. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  82703. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  82704. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  82705. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  82706. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  82707. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  82708. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  82709. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  82710. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  82711. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  82712. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  82713. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  82714. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  82715. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  82716. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  82717. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  82718. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  82719. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  82720. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  82721. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  82722. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  82723. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  82724. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  82725. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  82726. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  82727. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  82728. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  82729. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  82730. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  82731. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  82732. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  82733. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  82734. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  82735. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  82736. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  82737. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  82738. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  82739. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  82740. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  82741. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  82742. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  82743. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  82744. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  82745. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  82746. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  82747. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  82748. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  82749. + {0x380b, 0xf0, 0, 0}, {0x3a00, 0x78, 0, 0},
  82750. +};
  82751. +
  82752. +static struct reg_value ov5642_setting_15fps_NTSC_720_480[] = {
  82753. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82754. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82755. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  82756. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  82757. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  82758. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  82759. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  82760. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  82761. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  82762. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  82763. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  82764. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  82765. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82766. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  82767. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  82768. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  82769. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  82770. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  82771. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  82772. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  82773. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82774. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  82775. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  82776. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  82777. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  82778. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  82779. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  82780. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  82781. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  82782. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  82783. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  82784. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  82785. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  82786. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  82787. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  82788. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  82789. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82790. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  82791. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  82792. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  82793. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  82794. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  82795. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  82796. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  82797. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82798. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  82799. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  82800. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  82801. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  82802. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  82803. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  82804. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  82805. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  82806. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  82807. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  82808. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  82809. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  82810. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  82811. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  82812. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  82813. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  82814. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  82815. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  82816. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  82817. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  82818. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  82819. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  82820. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  82821. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  82822. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  82823. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  82824. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  82825. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  82826. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  82827. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  82828. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  82829. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  82830. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  82831. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  82832. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  82833. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  82834. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  82835. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  82836. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  82837. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  82838. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  82839. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  82840. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  82841. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  82842. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  82843. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  82844. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  82845. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  82846. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  82847. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  82848. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  82849. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  82850. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  82851. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  82852. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  82853. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  82854. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  82855. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  82856. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  82857. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  82858. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  82859. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  82860. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  82861. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  82862. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  82863. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  82864. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  82865. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  82866. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  82867. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  82868. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  82869. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  82870. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  82871. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  82872. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  82873. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  82874. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  82875. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  82876. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  82877. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  82878. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  82879. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  82880. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  82881. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  82882. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  82883. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  82884. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  82885. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  82886. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  82887. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  82888. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  82889. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  82890. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  82891. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  82892. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  82893. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  82894. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  82895. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  82896. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  82897. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  82898. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  82899. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  82900. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  82901. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  82902. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  82903. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  82904. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  82905. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  82906. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  82907. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  82908. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  82909. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  82910. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  82911. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  82912. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  82913. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  82914. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  82915. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  82916. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  82917. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  82918. + {0x3824, 0x11, 0, 0}, {0x3825, 0xb4, 0, 0}, {0x3826, 0x00, 0, 0},
  82919. + {0x3827, 0x3d, 0, 0}, {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0},
  82920. + {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0}, {0x3808, 0x02, 0, 0},
  82921. + {0x3809, 0xd0, 0, 0}, {0x380A, 0x01, 0, 0}, {0x380B, 0xe0, 0, 0},
  82922. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x3806, 0x03, 0, 0},
  82923. + {0x3807, 0x55, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0x55, 0, 0},
  82924. + {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  82925. +};
  82926. +
  82927. +static struct reg_value ov5642_setting_15fps_PAL_720_576[] = {
  82928. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82929. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82930. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  82931. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  82932. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  82933. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  82934. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  82935. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  82936. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  82937. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  82938. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  82939. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  82940. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82941. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  82942. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  82943. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  82944. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  82945. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  82946. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  82947. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  82948. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82949. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  82950. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  82951. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  82952. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  82953. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  82954. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  82955. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  82956. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  82957. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  82958. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  82959. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  82960. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  82961. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  82962. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  82963. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  82964. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82965. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  82966. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  82967. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  82968. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  82969. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  82970. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  82971. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  82972. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82973. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  82974. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  82975. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  82976. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  82977. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  82978. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  82979. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  82980. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  82981. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  82982. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  82983. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  82984. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  82985. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  82986. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  82987. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  82988. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  82989. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  82990. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  82991. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  82992. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  82993. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  82994. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  82995. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  82996. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  82997. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  82998. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  82999. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  83000. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  83001. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  83002. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  83003. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  83004. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  83005. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  83006. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  83007. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  83008. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  83009. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  83010. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  83011. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  83012. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  83013. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  83014. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  83015. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  83016. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  83017. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  83018. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  83019. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  83020. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  83021. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  83022. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  83023. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  83024. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  83025. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  83026. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  83027. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  83028. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  83029. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  83030. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  83031. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  83032. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  83033. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  83034. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  83035. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  83036. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  83037. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  83038. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  83039. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  83040. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  83041. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  83042. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  83043. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  83044. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  83045. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  83046. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  83047. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  83048. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  83049. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  83050. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  83051. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  83052. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  83053. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  83054. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  83055. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  83056. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  83057. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  83058. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  83059. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  83060. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  83061. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  83062. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  83063. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  83064. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  83065. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  83066. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  83067. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  83068. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  83069. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  83070. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  83071. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  83072. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  83073. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  83074. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  83075. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  83076. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  83077. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  83078. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  83079. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  83080. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  83081. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  83082. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  83083. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  83084. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  83085. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  83086. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  83087. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  83088. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  83089. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  83090. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  83091. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  83092. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  83093. + {0x3824, 0x11, 0, 0}, {0x3825, 0xdc, 0, 0}, {0x3826, 0x00, 0, 0},
  83094. + {0x3827, 0x08, 0, 0}, {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0},
  83095. + {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0}, {0x3808, 0x02, 0, 0},
  83096. + {0x3809, 0xd0, 0, 0}, {0x380A, 0x02, 0, 0}, {0x380B, 0x40, 0, 0},
  83097. + {0x3804, 0x04, 0, 0}, {0x3805, 0xb0, 0, 0}, {0x3806, 0x03, 0, 0},
  83098. + {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0xc0, 0, 0},
  83099. + {0x5682, 0x04, 0, 0}, {0x5683, 0xb0, 0, 0},
  83100. +};
  83101. +
  83102. +static struct ov5642_mode_info ov5642_mode_info_data[2][ov5642_mode_MAX + 1] = {
  83103. + {
  83104. + {ov5642_mode_VGA_640_480, 640, 480,
  83105. + ov5642_setting_15fps_VGA_640_480,
  83106. + ARRAY_SIZE(ov5642_setting_15fps_VGA_640_480)},
  83107. + {ov5642_mode_QVGA_320_240, 320, 240,
  83108. + ov5642_setting_15fps_QVGA_320_240,
  83109. + ARRAY_SIZE(ov5642_setting_15fps_QVGA_320_240)},
  83110. + {ov5642_mode_NTSC_720_480, 720, 480,
  83111. + ov5642_setting_15fps_NTSC_720_480,
  83112. + ARRAY_SIZE(ov5642_setting_15fps_NTSC_720_480)},
  83113. + {ov5642_mode_PAL_720_576, 720, 576,
  83114. + ov5642_setting_15fps_PAL_720_576,
  83115. + ARRAY_SIZE(ov5642_setting_15fps_PAL_720_576)},
  83116. + {ov5642_mode_720P_1280_720, 1280, 720,
  83117. + ov5642_setting_15fps_720P_1280_720,
  83118. + ARRAY_SIZE(ov5642_setting_15fps_720P_1280_720)},
  83119. + {ov5642_mode_1080P_1920_1080, 1920, 1080,
  83120. + ov5642_setting_15fps_1080P_1920_1080,
  83121. + ARRAY_SIZE(ov5642_setting_15fps_1080P_1920_1080)},
  83122. + {ov5642_mode_QSXGA_2592_1944, 2592, 1944,
  83123. + ov5642_setting_15fps_QSXGA_2592_1944,
  83124. + ARRAY_SIZE(ov5642_setting_15fps_QSXGA_2592_1944)},
  83125. + {ov5642_mode_QCIF_176_144, 176, 144,
  83126. + ov5642_setting_15fps_QCIF_176_144,
  83127. + ARRAY_SIZE(ov5642_setting_15fps_QCIF_176_144)},
  83128. + {ov5642_mode_XGA_1024_768, 1024, 768,
  83129. + ov5642_setting_15fps_XGA_1024_768,
  83130. + ARRAY_SIZE(ov5642_setting_15fps_XGA_1024_768)},
  83131. + },
  83132. + {
  83133. + {ov5642_mode_VGA_640_480, 640, 480,
  83134. + ov5642_setting_30fps_VGA_640_480,
  83135. + ARRAY_SIZE(ov5642_setting_30fps_VGA_640_480)},
  83136. + {ov5642_mode_QVGA_320_240, 320, 240,
  83137. + ov5642_setting_30fps_QVGA_320_240,
  83138. + ARRAY_SIZE(ov5642_setting_30fps_QVGA_320_240)},
  83139. + {ov5642_mode_NTSC_720_480, 720, 480,
  83140. + ov5642_setting_30fps_NTSC_720_480,
  83141. + ARRAY_SIZE(ov5642_setting_30fps_NTSC_720_480)},
  83142. + {ov5642_mode_PAL_720_576, 720, 576,
  83143. + ov5642_setting_30fps_PAL_720_576,
  83144. + ARRAY_SIZE(ov5642_setting_30fps_PAL_720_576)},
  83145. + {ov5642_mode_720P_1280_720, 1280, 720,
  83146. + ov5642_setting_30fps_720P_1280_720,
  83147. + ARRAY_SIZE(ov5642_setting_30fps_720P_1280_720)},
  83148. + {ov5642_mode_1080P_1920_1080, 0, 0, NULL, 0},
  83149. + {ov5642_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
  83150. + {ov5642_mode_QCIF_176_144, 176, 144,
  83151. + ov5642_setting_30fps_QCIF_176_144,
  83152. + ARRAY_SIZE(ov5642_setting_30fps_QCIF_176_144)},
  83153. + {ov5642_mode_XGA_1024_768, 1024, 768,
  83154. + ov5642_setting_30fps_XGA_1024_768,
  83155. + ARRAY_SIZE(ov5642_setting_30fps_XGA_1024_768)},
  83156. + },
  83157. +};
  83158. +
  83159. +static struct regulator *io_regulator;
  83160. +static struct regulator *core_regulator;
  83161. +static struct regulator *analog_regulator;
  83162. +static struct regulator *gpo_regulator;
  83163. +
  83164. +static int ov5642_probe(struct i2c_client *adapter,
  83165. + const struct i2c_device_id *device_id);
  83166. +static int ov5642_remove(struct i2c_client *client);
  83167. +
  83168. +static s32 ov5642_read_reg(u16 reg, u8 *val);
  83169. +static s32 ov5642_write_reg(u16 reg, u8 val);
  83170. +
  83171. +static const struct i2c_device_id ov5642_id[] = {
  83172. + {"ov5642", 0},
  83173. + {"ov564x", 0},
  83174. + {},
  83175. +};
  83176. +
  83177. +MODULE_DEVICE_TABLE(i2c, ov5642_id);
  83178. +
  83179. +static struct i2c_driver ov5642_i2c_driver = {
  83180. + .driver = {
  83181. + .owner = THIS_MODULE,
  83182. + .name = "ov5642",
  83183. + },
  83184. + .probe = ov5642_probe,
  83185. + .remove = ov5642_remove,
  83186. + .id_table = ov5642_id,
  83187. +};
  83188. +
  83189. +static void ov5642_standby(s32 enable)
  83190. +{
  83191. + if (enable)
  83192. + gpio_set_value(pwn_gpio, 1);
  83193. + else
  83194. + gpio_set_value(pwn_gpio, 0);
  83195. +
  83196. + msleep(2);
  83197. +}
  83198. +
  83199. +static void ov5642_reset(void)
  83200. +{
  83201. + /* camera reset */
  83202. + gpio_set_value(rst_gpio, 1);
  83203. +
  83204. + /* camera power down */
  83205. + gpio_set_value(pwn_gpio, 1);
  83206. + msleep(5);
  83207. +
  83208. + gpio_set_value(pwn_gpio, 0);
  83209. + msleep(5);
  83210. +
  83211. + gpio_set_value(rst_gpio, 0);
  83212. + msleep(1);
  83213. +
  83214. + gpio_set_value(rst_gpio, 1);
  83215. + msleep(5);
  83216. +
  83217. + gpio_set_value(pwn_gpio, 1);
  83218. +}
  83219. +
  83220. +static int ov5642_power_on(struct device *dev)
  83221. +{
  83222. + int ret = 0;
  83223. +
  83224. + io_regulator = devm_regulator_get(dev, "DOVDD");
  83225. + if (!IS_ERR(io_regulator)) {
  83226. + regulator_set_voltage(io_regulator,
  83227. + OV5642_VOLTAGE_DIGITAL_IO,
  83228. + OV5642_VOLTAGE_DIGITAL_IO);
  83229. + ret = regulator_enable(io_regulator);
  83230. + if (ret) {
  83231. + pr_err("%s:io set voltage error\n", __func__);
  83232. + return ret;
  83233. + } else {
  83234. + dev_dbg(dev,
  83235. + "%s:io set voltage ok\n", __func__);
  83236. + }
  83237. + } else {
  83238. + pr_err("%s: cannot get io voltage error\n", __func__);
  83239. + io_regulator = NULL;
  83240. + }
  83241. +
  83242. + core_regulator = devm_regulator_get(dev, "DVDD");
  83243. + if (!IS_ERR(core_regulator)) {
  83244. + regulator_set_voltage(core_regulator,
  83245. + OV5642_VOLTAGE_DIGITAL_CORE,
  83246. + OV5642_VOLTAGE_DIGITAL_CORE);
  83247. + ret = regulator_enable(core_regulator);
  83248. + if (ret) {
  83249. + pr_err("%s:core set voltage error\n", __func__);
  83250. + return ret;
  83251. + } else {
  83252. + dev_dbg(dev,
  83253. + "%s:core set voltage ok\n", __func__);
  83254. + }
  83255. + } else {
  83256. + core_regulator = NULL;
  83257. + pr_err("%s: cannot get core voltage error\n", __func__);
  83258. + }
  83259. +
  83260. + analog_regulator = devm_regulator_get(dev, "AVDD");
  83261. + if (!IS_ERR(analog_regulator)) {
  83262. + regulator_set_voltage(analog_regulator,
  83263. + OV5642_VOLTAGE_ANALOG,
  83264. + OV5642_VOLTAGE_ANALOG);
  83265. + ret = regulator_enable(analog_regulator);
  83266. + if (ret) {
  83267. + pr_err("%s:analog set voltage error\n",
  83268. + __func__);
  83269. + return ret;
  83270. + } else {
  83271. + dev_dbg(dev,
  83272. + "%s:analog set voltage ok\n", __func__);
  83273. + }
  83274. + } else {
  83275. + analog_regulator = NULL;
  83276. + pr_err("%s: cannot get analog voltage error\n", __func__);
  83277. + }
  83278. +
  83279. + return ret;
  83280. +}
  83281. +
  83282. +static s32 ov5642_write_reg(u16 reg, u8 val)
  83283. +{
  83284. + u8 au8Buf[3] = {0};
  83285. +
  83286. + au8Buf[0] = reg >> 8;
  83287. + au8Buf[1] = reg & 0xff;
  83288. + au8Buf[2] = val;
  83289. +
  83290. + if (i2c_master_send(ov5642_data.i2c_client, au8Buf, 3) < 0) {
  83291. + pr_err("%s:write reg error:reg=%x,val=%x\n",
  83292. + __func__, reg, val);
  83293. + return -1;
  83294. + }
  83295. +
  83296. + return 0;
  83297. +}
  83298. +
  83299. +static s32 ov5642_read_reg(u16 reg, u8 *val)
  83300. +{
  83301. + u8 au8RegBuf[2] = {0};
  83302. + u8 u8RdVal = 0;
  83303. +
  83304. + au8RegBuf[0] = reg >> 8;
  83305. + au8RegBuf[1] = reg & 0xff;
  83306. +
  83307. + if (2 != i2c_master_send(ov5642_data.i2c_client, au8RegBuf, 2)) {
  83308. + pr_err("%s:write reg error:reg=%x\n",
  83309. + __func__, reg);
  83310. + return -1;
  83311. + }
  83312. +
  83313. + if (1 != i2c_master_recv(ov5642_data.i2c_client, &u8RdVal, 1)) {
  83314. + pr_err("%s:read reg error:reg=%x,val=%x\n",
  83315. + __func__, reg, u8RdVal);
  83316. + return -1;
  83317. + }
  83318. +
  83319. + *val = u8RdVal;
  83320. +
  83321. + return u8RdVal;
  83322. +}
  83323. +
  83324. +static int ov5642_set_rot_mode(struct reg_value *rot_mode)
  83325. +{
  83326. + s32 i = 0;
  83327. + s32 iModeSettingArySize = 2;
  83328. + register u32 Delay_ms = 0;
  83329. + register u16 RegAddr = 0;
  83330. + register u8 Mask = 0;
  83331. + register u8 Val = 0;
  83332. + u8 RegVal = 0;
  83333. + int retval = 0;
  83334. + for (i = 0; i < iModeSettingArySize; ++i, ++rot_mode) {
  83335. + Delay_ms = rot_mode->u32Delay_ms;
  83336. + RegAddr = rot_mode->u16RegAddr;
  83337. + Val = rot_mode->u8Val;
  83338. + Mask = rot_mode->u8Mask;
  83339. +
  83340. + if (Mask) {
  83341. + retval = ov5642_read_reg(RegAddr, &RegVal);
  83342. + if (retval < 0) {
  83343. + pr_err("%s, read reg 0x%x failed\n",
  83344. + __func__, RegAddr);
  83345. + goto err;
  83346. + }
  83347. +
  83348. + Val |= RegVal;
  83349. + Val &= Mask;
  83350. + }
  83351. +
  83352. + retval = ov5642_write_reg(RegAddr, Val);
  83353. + if (retval < 0) {
  83354. + pr_err("%s, write reg 0x%x failed\n",
  83355. + __func__, RegAddr);
  83356. + goto err;
  83357. + }
  83358. +
  83359. + if (Delay_ms)
  83360. + mdelay(Delay_ms);
  83361. + }
  83362. +err:
  83363. + return retval;
  83364. +}
  83365. +static int ov5642_init_mode(enum ov5642_frame_rate frame_rate,
  83366. + enum ov5642_mode mode);
  83367. +static int ov5642_write_snapshot_para(enum ov5642_frame_rate frame_rate,
  83368. + enum ov5642_mode mode);
  83369. +static int ov5642_change_mode(enum ov5642_frame_rate new_frame_rate,
  83370. + enum ov5642_frame_rate old_frame_rate,
  83371. + enum ov5642_mode new_mode,
  83372. + enum ov5642_mode orig_mode)
  83373. +{
  83374. + struct reg_value *pModeSetting = NULL;
  83375. + s32 i = 0;
  83376. + s32 iModeSettingArySize = 0;
  83377. + register u32 Delay_ms = 0;
  83378. + register u16 RegAddr = 0;
  83379. + register u8 Mask = 0;
  83380. + register u8 Val = 0;
  83381. + u8 RegVal = 0;
  83382. + int retval = 0;
  83383. +
  83384. + if (new_mode > ov5642_mode_MAX || new_mode < ov5642_mode_MIN) {
  83385. + pr_err("Wrong ov5642 mode detected!\n");
  83386. + return -1;
  83387. + }
  83388. +
  83389. + if ((new_frame_rate == old_frame_rate) &&
  83390. + (new_mode == ov5642_mode_VGA_640_480) &&
  83391. + (orig_mode == ov5642_mode_QSXGA_2592_1944)) {
  83392. + pModeSetting = ov5642_setting_QSXGA_2_VGA;
  83393. + iModeSettingArySize = ARRAY_SIZE(ov5642_setting_QSXGA_2_VGA);
  83394. + ov5642_data.pix.width = 640;
  83395. + ov5642_data.pix.height = 480;
  83396. + } else if ((new_frame_rate == old_frame_rate) &&
  83397. + (new_mode == ov5642_mode_QVGA_320_240) &&
  83398. + (orig_mode == ov5642_mode_VGA_640_480)) {
  83399. + pModeSetting = ov5642_setting_VGA_2_QVGA;
  83400. + iModeSettingArySize = ARRAY_SIZE(ov5642_setting_VGA_2_QVGA);
  83401. + ov5642_data.pix.width = 320;
  83402. + ov5642_data.pix.height = 240;
  83403. + } else {
  83404. + retval = ov5642_write_snapshot_para(new_frame_rate, new_mode);
  83405. + goto err;
  83406. + }
  83407. +
  83408. + if (ov5642_data.pix.width == 0 || ov5642_data.pix.height == 0 ||
  83409. + pModeSetting == NULL || iModeSettingArySize == 0)
  83410. + return -EINVAL;
  83411. +
  83412. + for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
  83413. + Delay_ms = pModeSetting->u32Delay_ms;
  83414. + RegAddr = pModeSetting->u16RegAddr;
  83415. + Val = pModeSetting->u8Val;
  83416. + Mask = pModeSetting->u8Mask;
  83417. +
  83418. + if (Mask) {
  83419. + retval = ov5642_read_reg(RegAddr, &RegVal);
  83420. + if (retval < 0) {
  83421. + pr_err("read reg error addr=0x%x", RegAddr);
  83422. + goto err;
  83423. + }
  83424. +
  83425. + RegVal &= ~(u8)Mask;
  83426. + Val &= Mask;
  83427. + Val |= RegVal;
  83428. + }
  83429. +
  83430. + retval = ov5642_write_reg(RegAddr, Val);
  83431. + if (retval < 0) {
  83432. + pr_err("write reg error addr=0x%x", RegAddr);
  83433. + goto err;
  83434. + }
  83435. +
  83436. + if (Delay_ms)
  83437. + msleep(Delay_ms);
  83438. + }
  83439. +err:
  83440. + return retval;
  83441. +}
  83442. +static int ov5642_init_mode(enum ov5642_frame_rate frame_rate,
  83443. + enum ov5642_mode mode)
  83444. +{
  83445. + struct reg_value *pModeSetting = NULL;
  83446. + s32 i = 0;
  83447. + s32 iModeSettingArySize = 0;
  83448. + register u32 Delay_ms = 0;
  83449. + register u16 RegAddr = 0;
  83450. + register u8 Mask = 0;
  83451. + register u8 Val = 0;
  83452. + u8 RegVal = 0;
  83453. + int retval = 0;
  83454. +
  83455. + if (mode > ov5642_mode_MAX || mode < ov5642_mode_MIN) {
  83456. + pr_err("Wrong ov5642 mode detected!\n");
  83457. + return -1;
  83458. + }
  83459. +
  83460. + pModeSetting = ov5642_mode_info_data[frame_rate][mode].init_data_ptr;
  83461. + iModeSettingArySize =
  83462. + ov5642_mode_info_data[frame_rate][mode].init_data_size;
  83463. +
  83464. + ov5642_data.pix.width = ov5642_mode_info_data[frame_rate][mode].width;
  83465. + ov5642_data.pix.height = ov5642_mode_info_data[frame_rate][mode].height;
  83466. +
  83467. + if (ov5642_data.pix.width == 0 || ov5642_data.pix.height == 0 ||
  83468. + pModeSetting == NULL || iModeSettingArySize == 0)
  83469. + return -EINVAL;
  83470. +
  83471. + for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
  83472. + Delay_ms = pModeSetting->u32Delay_ms;
  83473. + RegAddr = pModeSetting->u16RegAddr;
  83474. + Val = pModeSetting->u8Val;
  83475. + Mask = pModeSetting->u8Mask;
  83476. +
  83477. + if (Mask) {
  83478. + retval = ov5642_read_reg(RegAddr, &RegVal);
  83479. + if (retval < 0) {
  83480. + pr_err("read reg error addr=0x%x", RegAddr);
  83481. + goto err;
  83482. + }
  83483. +
  83484. + RegVal &= ~(u8)Mask;
  83485. + Val &= Mask;
  83486. + Val |= RegVal;
  83487. + }
  83488. +
  83489. + retval = ov5642_write_reg(RegAddr, Val);
  83490. + if (retval < 0) {
  83491. + pr_err("write reg error addr=0x%x", RegAddr);
  83492. + goto err;
  83493. + }
  83494. +
  83495. + if (Delay_ms)
  83496. + msleep(Delay_ms);
  83497. + }
  83498. +err:
  83499. + return retval;
  83500. +}
  83501. +
  83502. +static int ov5642_write_snapshot_para(enum ov5642_frame_rate frame_rate,
  83503. + enum ov5642_mode mode)
  83504. +{
  83505. + int ret = 0;
  83506. + bool m_60Hz = false;
  83507. + u16 cap_frame_rate = 50;
  83508. + u16 g_prev_frame_rate = 225;
  83509. +
  83510. + u8 ev_low, ev_mid, ev_high;
  83511. + u8 ret_l, ret_m, ret_h, gain, lines_10ms;
  83512. + u16 ulcap_ev, icap_gain, prev_maxlines;
  83513. + u32 ulcap_ev_gain, cap_maxlines, g_prev_ev;
  83514. +
  83515. + ov5642_write_reg(0x3503, 0x07);
  83516. +
  83517. + ret_h = ret_m = ret_l = 0;
  83518. + g_prev_ev = 0;
  83519. + ov5642_read_reg(0x3500, &ret_h);
  83520. + ov5642_read_reg(0x3501, &ret_m);
  83521. + ov5642_read_reg(0x3502, &ret_l);
  83522. + g_prev_ev = (ret_h << 12) + (ret_m << 4) + (ret_l >> 4);
  83523. +
  83524. + ret_h = ret_m = ret_l = 0;
  83525. + prev_maxlines = 0;
  83526. + ov5642_read_reg(0x380e, &ret_h);
  83527. + ov5642_read_reg(0x380f, &ret_l);
  83528. + prev_maxlines = (ret_h << 8) + ret_l;
  83529. + /*Read back AGC Gain for preview*/
  83530. + gain = 0;
  83531. + ov5642_read_reg(0x350b, &gain);
  83532. +
  83533. + ret = ov5642_init_mode(frame_rate, mode);
  83534. + if (ret < 0)
  83535. + return ret;
  83536. +
  83537. + ret_h = ret_m = ret_l = 0;
  83538. + ov5642_read_reg(0x380e, &ret_h);
  83539. + ov5642_read_reg(0x380f, &ret_l);
  83540. + cap_maxlines = (ret_h << 8) + ret_l;
  83541. + if (m_60Hz == true)
  83542. + lines_10ms = cap_frame_rate * cap_maxlines/12000;
  83543. + else
  83544. + lines_10ms = cap_frame_rate * cap_maxlines/10000;
  83545. +
  83546. + if (prev_maxlines == 0)
  83547. + prev_maxlines = 1;
  83548. +
  83549. + ulcap_ev = (g_prev_ev*(cap_frame_rate)*(cap_maxlines))/
  83550. + (((prev_maxlines)*(g_prev_frame_rate)));
  83551. + icap_gain = (gain & 0x0f) + 16;
  83552. + if (gain & 0x10)
  83553. + icap_gain = icap_gain << 1;
  83554. +
  83555. + if (gain & 0x20)
  83556. + icap_gain = icap_gain << 1;
  83557. +
  83558. + if (gain & 0x40)
  83559. + icap_gain = icap_gain << 1;
  83560. +
  83561. + if (gain & 0x80)
  83562. + icap_gain = icap_gain << 1;
  83563. +
  83564. + ulcap_ev_gain = 2 * ulcap_ev * icap_gain;
  83565. +
  83566. + if (ulcap_ev_gain < cap_maxlines*16) {
  83567. + ulcap_ev = ulcap_ev_gain/16;
  83568. + if (ulcap_ev > lines_10ms) {
  83569. + ulcap_ev /= lines_10ms;
  83570. + ulcap_ev *= lines_10ms;
  83571. + }
  83572. + } else
  83573. + ulcap_ev = cap_maxlines;
  83574. +
  83575. + if (ulcap_ev == 0)
  83576. + ulcap_ev = 1;
  83577. +
  83578. + icap_gain = (ulcap_ev_gain*2/ulcap_ev + 1)/2;
  83579. + ev_low = ((unsigned char)ulcap_ev)<<4;
  83580. + ev_mid = (unsigned char)(ulcap_ev >> 4) & 0xff;
  83581. + ev_high = (unsigned char)(ulcap_ev >> 12);
  83582. +
  83583. + gain = 0;
  83584. + if (icap_gain > 31) {
  83585. + gain |= 0x10;
  83586. + icap_gain = icap_gain >> 1;
  83587. + }
  83588. + if (icap_gain > 31) {
  83589. + gain |= 0x20;
  83590. + icap_gain = icap_gain >> 1;
  83591. + }
  83592. + if (icap_gain > 31) {
  83593. + gain |= 0x40;
  83594. + icap_gain = icap_gain >> 1;
  83595. + }
  83596. + if (icap_gain > 31) {
  83597. + gain |= 0x80;
  83598. + icap_gain = icap_gain >> 1;
  83599. + }
  83600. + if (icap_gain > 16)
  83601. + gain |= ((icap_gain - 16) & 0x0f);
  83602. +
  83603. + if (gain == 0x10)
  83604. + gain = 0x11;
  83605. +
  83606. + ov5642_write_reg(0x350b, gain);
  83607. + ov5642_write_reg(0x3502, ev_low);
  83608. + ov5642_write_reg(0x3501, ev_mid);
  83609. + ov5642_write_reg(0x3500, ev_high);
  83610. + msleep(500);
  83611. +
  83612. + return ret ;
  83613. +}
  83614. +
  83615. +
  83616. +/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
  83617. +
  83618. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  83619. +{
  83620. + if (s == NULL) {
  83621. + pr_err(" ERROR!! no slave device set!\n");
  83622. + return -1;
  83623. + }
  83624. +
  83625. + memset(p, 0, sizeof(*p));
  83626. + p->u.bt656.clock_curr = ov5642_data.mclk;
  83627. + pr_debug(" clock_curr=mclk=%d\n", ov5642_data.mclk);
  83628. + p->if_type = V4L2_IF_TYPE_BT656;
  83629. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  83630. + p->u.bt656.clock_min = OV5642_XCLK_MIN;
  83631. + p->u.bt656.clock_max = OV5642_XCLK_MAX;
  83632. + p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
  83633. +
  83634. + return 0;
  83635. +}
  83636. +
  83637. +/*!
  83638. + * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
  83639. + * @s: pointer to standard V4L2 device structure
  83640. + * @on: indicates power mode (on or off)
  83641. + *
  83642. + * Turns the power on or off, depending on the value of on and returns the
  83643. + * appropriate error code.
  83644. + */
  83645. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  83646. +{
  83647. + struct sensor_data *sensor = s->priv;
  83648. +
  83649. + if (on && !sensor->on) {
  83650. + if (io_regulator)
  83651. + if (regulator_enable(io_regulator) != 0)
  83652. + return -EIO;
  83653. + if (core_regulator)
  83654. + if (regulator_enable(core_regulator) != 0)
  83655. + return -EIO;
  83656. + if (gpo_regulator)
  83657. + if (regulator_enable(gpo_regulator) != 0)
  83658. + return -EIO;
  83659. + if (analog_regulator)
  83660. + if (regulator_enable(analog_regulator) != 0)
  83661. + return -EIO;
  83662. + /* Make sure power on */
  83663. + ov5642_standby(0);
  83664. + } else if (!on && sensor->on) {
  83665. + if (analog_regulator)
  83666. + regulator_disable(analog_regulator);
  83667. + if (core_regulator)
  83668. + regulator_disable(core_regulator);
  83669. + if (io_regulator)
  83670. + regulator_disable(io_regulator);
  83671. + if (gpo_regulator)
  83672. + regulator_disable(gpo_regulator);
  83673. +
  83674. + ov5642_standby(1);
  83675. + }
  83676. +
  83677. + sensor->on = on;
  83678. +
  83679. + return 0;
  83680. +}
  83681. +
  83682. +/*!
  83683. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  83684. + * @s: pointer to standard V4L2 device structure
  83685. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  83686. + *
  83687. + * Returns the sensor's video CAPTURE parameters.
  83688. + */
  83689. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  83690. +{
  83691. + struct sensor_data *sensor = s->priv;
  83692. + struct v4l2_captureparm *cparm = &a->parm.capture;
  83693. + int ret = 0;
  83694. +
  83695. + switch (a->type) {
  83696. + /* This is the only case currently handled. */
  83697. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  83698. + memset(a, 0, sizeof(*a));
  83699. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  83700. + cparm->capability = sensor->streamcap.capability;
  83701. + cparm->timeperframe = sensor->streamcap.timeperframe;
  83702. + cparm->capturemode = sensor->streamcap.capturemode;
  83703. + ret = 0;
  83704. + break;
  83705. +
  83706. + /* These are all the possible cases. */
  83707. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  83708. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  83709. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  83710. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  83711. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  83712. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  83713. + ret = -EINVAL;
  83714. + break;
  83715. +
  83716. + default:
  83717. + pr_debug(" type is unknown - %d\n", a->type);
  83718. + ret = -EINVAL;
  83719. + break;
  83720. + }
  83721. +
  83722. + return ret;
  83723. +}
  83724. +
  83725. +/*!
  83726. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  83727. + * @s: pointer to standard V4L2 device structure
  83728. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  83729. + *
  83730. + * Configures the sensor to use the input parameters, if possible. If
  83731. + * not possible, reverts to the old parameters and returns the
  83732. + * appropriate error code.
  83733. + */
  83734. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  83735. +{
  83736. + struct sensor_data *sensor = s->priv;
  83737. + struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
  83738. + u32 tgt_fps, old_fps; /* target frames per secound */
  83739. + enum ov5642_frame_rate new_frame_rate, old_frame_rate;
  83740. + int ret = 0;
  83741. +
  83742. + /* Make sure power on */
  83743. + ov5642_standby(0);
  83744. +
  83745. + switch (a->type) {
  83746. + /* This is the only case currently handled. */
  83747. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  83748. + /* Check that the new frame rate is allowed. */
  83749. + if ((timeperframe->numerator == 0) ||
  83750. + (timeperframe->denominator == 0)) {
  83751. + timeperframe->denominator = DEFAULT_FPS;
  83752. + timeperframe->numerator = 1;
  83753. + }
  83754. +
  83755. + tgt_fps = timeperframe->denominator /
  83756. + timeperframe->numerator;
  83757. +
  83758. + if (tgt_fps > MAX_FPS) {
  83759. + timeperframe->denominator = MAX_FPS;
  83760. + timeperframe->numerator = 1;
  83761. + } else if (tgt_fps < MIN_FPS) {
  83762. + timeperframe->denominator = MIN_FPS;
  83763. + timeperframe->numerator = 1;
  83764. + }
  83765. +
  83766. + /* Actual frame rate we use */
  83767. + tgt_fps = timeperframe->denominator /
  83768. + timeperframe->numerator;
  83769. +
  83770. + if (tgt_fps == 15)
  83771. + new_frame_rate = ov5642_15_fps;
  83772. + else if (tgt_fps == 30)
  83773. + new_frame_rate = ov5642_30_fps;
  83774. + else {
  83775. + pr_err(" The camera frame rate is not supported!\n");
  83776. + return -EINVAL;
  83777. + }
  83778. +
  83779. + if (sensor->streamcap.timeperframe.numerator != 0)
  83780. + old_fps = sensor->streamcap.timeperframe.denominator /
  83781. + sensor->streamcap.timeperframe.numerator;
  83782. + else
  83783. + old_fps = 30;
  83784. +
  83785. + if (old_fps == 15)
  83786. + old_frame_rate = ov5642_15_fps;
  83787. + else if (old_fps == 30)
  83788. + old_frame_rate = ov5642_30_fps;
  83789. + else {
  83790. + pr_warning(" No valid frame rate set!\n");
  83791. + old_frame_rate = ov5642_30_fps;
  83792. + }
  83793. +
  83794. + ret = ov5642_change_mode(new_frame_rate, old_frame_rate,
  83795. + a->parm.capture.capturemode,
  83796. + sensor->streamcap.capturemode);
  83797. + if (ret < 0)
  83798. + return ret;
  83799. +
  83800. + sensor->streamcap.timeperframe = *timeperframe;
  83801. + sensor->streamcap.capturemode =
  83802. + (u32)a->parm.capture.capturemode;
  83803. + break;
  83804. +
  83805. + /* These are all the possible cases. */
  83806. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  83807. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  83808. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  83809. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  83810. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  83811. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  83812. + pr_debug(" type is not " \
  83813. + "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
  83814. + a->type);
  83815. + ret = -EINVAL;
  83816. + break;
  83817. +
  83818. + default:
  83819. + pr_debug(" type is unknown - %d\n", a->type);
  83820. + ret = -EINVAL;
  83821. + break;
  83822. + }
  83823. +
  83824. + return ret;
  83825. +}
  83826. +
  83827. +/*!
  83828. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  83829. + * @s: pointer to standard V4L2 device structure
  83830. + * @f: pointer to standard V4L2 v4l2_format structure
  83831. + *
  83832. + * Returns the sensor's current pixel format in the v4l2_format
  83833. + * parameter.
  83834. + */
  83835. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  83836. +{
  83837. + struct sensor_data *sensor = s->priv;
  83838. +
  83839. + f->fmt.pix = sensor->pix;
  83840. +
  83841. + return 0;
  83842. +}
  83843. +
  83844. +/*!
  83845. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  83846. + * @s: pointer to standard V4L2 device structure
  83847. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  83848. + *
  83849. + * If the requested control is supported, returns the control's current
  83850. + * value from the video_control[] array. Otherwise, returns -EINVAL
  83851. + * if the control is not supported.
  83852. + */
  83853. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  83854. +{
  83855. + int ret = 0;
  83856. +
  83857. + switch (vc->id) {
  83858. + case V4L2_CID_BRIGHTNESS:
  83859. + vc->value = ov5642_data.brightness;
  83860. + break;
  83861. + case V4L2_CID_HUE:
  83862. + vc->value = ov5642_data.hue;
  83863. + break;
  83864. + case V4L2_CID_CONTRAST:
  83865. + vc->value = ov5642_data.contrast;
  83866. + break;
  83867. + case V4L2_CID_SATURATION:
  83868. + vc->value = ov5642_data.saturation;
  83869. + break;
  83870. + case V4L2_CID_RED_BALANCE:
  83871. + vc->value = ov5642_data.red;
  83872. + break;
  83873. + case V4L2_CID_BLUE_BALANCE:
  83874. + vc->value = ov5642_data.blue;
  83875. + break;
  83876. + case V4L2_CID_EXPOSURE:
  83877. + vc->value = ov5642_data.ae_mode;
  83878. + break;
  83879. + default:
  83880. + ret = -EINVAL;
  83881. + }
  83882. +
  83883. + return ret;
  83884. +}
  83885. +
  83886. +/*!
  83887. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  83888. + * @s: pointer to standard V4L2 device structure
  83889. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  83890. + *
  83891. + * If the requested control is supported, sets the control's current
  83892. + * value in HW (and updates the video_control[] array). Otherwise,
  83893. + * returns -EINVAL if the control is not supported.
  83894. + */
  83895. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  83896. +{
  83897. + int retval = 0;
  83898. + struct sensor_data *sensor = s->priv;
  83899. + __u32 captureMode = sensor->streamcap.capturemode;
  83900. + struct reg_value *rot_mode = NULL;
  83901. +
  83902. + pr_debug("In ov5642:ioctl_s_ctrl %d\n",
  83903. + vc->id);
  83904. +
  83905. + switch (vc->id) {
  83906. + case V4L2_CID_BRIGHTNESS:
  83907. + break;
  83908. + case V4L2_CID_CONTRAST:
  83909. + break;
  83910. + case V4L2_CID_SATURATION:
  83911. + break;
  83912. + case V4L2_CID_HUE:
  83913. + break;
  83914. + case V4L2_CID_AUTO_WHITE_BALANCE:
  83915. + break;
  83916. + case V4L2_CID_DO_WHITE_BALANCE:
  83917. + break;
  83918. + case V4L2_CID_RED_BALANCE:
  83919. + break;
  83920. + case V4L2_CID_BLUE_BALANCE:
  83921. + break;
  83922. + case V4L2_CID_GAMMA:
  83923. + break;
  83924. + case V4L2_CID_EXPOSURE:
  83925. + break;
  83926. + case V4L2_CID_AUTOGAIN:
  83927. + break;
  83928. + case V4L2_CID_GAIN:
  83929. + break;
  83930. + case V4L2_CID_HFLIP:
  83931. + break;
  83932. + case V4L2_CID_VFLIP:
  83933. + break;
  83934. + case V4L2_CID_MXC_ROT:
  83935. + case V4L2_CID_MXC_VF_ROT:
  83936. + switch (vc->value) {
  83937. + case V4L2_MXC_ROTATE_NONE:
  83938. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  83939. + rot_mode = ov5642_rot_none_FULL;
  83940. + else
  83941. + rot_mode = ov5642_rot_none_VGA;
  83942. +
  83943. + if (ov5642_set_rot_mode(rot_mode))
  83944. + retval = -EPERM;
  83945. + break;
  83946. + case V4L2_MXC_ROTATE_VERT_FLIP:
  83947. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  83948. + rot_mode = ov5642_rot_vert_flip_FULL;
  83949. + else
  83950. + rot_mode = ov5642_rot_vert_flip_VGA ;
  83951. +
  83952. + if (ov5642_set_rot_mode(rot_mode))
  83953. + retval = -EPERM;
  83954. + break;
  83955. + case V4L2_MXC_ROTATE_HORIZ_FLIP:
  83956. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  83957. + rot_mode = ov5642_rot_horiz_flip_FULL;
  83958. + else
  83959. + rot_mode = ov5642_rot_horiz_flip_VGA;
  83960. +
  83961. + if (ov5642_set_rot_mode(rot_mode))
  83962. + retval = -EPERM;
  83963. + break;
  83964. + case V4L2_MXC_ROTATE_180:
  83965. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  83966. + rot_mode = ov5642_rot_180_FULL;
  83967. + else
  83968. + rot_mode = ov5642_rot_180_VGA;
  83969. +
  83970. + if (ov5642_set_rot_mode(rot_mode))
  83971. + retval = -EPERM;
  83972. + break;
  83973. + default:
  83974. + retval = -EPERM;
  83975. + break;
  83976. + }
  83977. + break;
  83978. + default:
  83979. + retval = -EPERM;
  83980. + break;
  83981. + }
  83982. +
  83983. + return retval;
  83984. +}
  83985. +
  83986. +/*!
  83987. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  83988. + * VIDIOC_ENUM_FRAMESIZES ioctl
  83989. + * @s: pointer to standard V4L2 device structure
  83990. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  83991. + *
  83992. + * Return 0 if successful, otherwise -EINVAL.
  83993. + */
  83994. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  83995. + struct v4l2_frmsizeenum *fsize)
  83996. +{
  83997. + if (fsize->index > ov5642_mode_MAX)
  83998. + return -EINVAL;
  83999. +
  84000. + fsize->pixel_format = ov5642_data.pix.pixelformat;
  84001. + fsize->discrete.width =
  84002. + max(ov5642_mode_info_data[0][fsize->index].width,
  84003. + ov5642_mode_info_data[1][fsize->index].width);
  84004. + fsize->discrete.height =
  84005. + max(ov5642_mode_info_data[0][fsize->index].height,
  84006. + ov5642_mode_info_data[1][fsize->index].height);
  84007. + return 0;
  84008. +}
  84009. +
  84010. +/*!
  84011. + * ioctl_enum_frameintervals - V4L2 sensor interface handler for
  84012. + * VIDIOC_ENUM_FRAMEINTERVALS ioctl
  84013. + * @s: pointer to standard V4L2 device structure
  84014. + * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
  84015. + *
  84016. + * Return 0 if successful, otherwise -EINVAL.
  84017. + */
  84018. +static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
  84019. + struct v4l2_frmivalenum *fival)
  84020. +{
  84021. + int i, j, count;
  84022. +
  84023. + if (fival->index < 0 || fival->index > ov5642_mode_MAX)
  84024. + return -EINVAL;
  84025. +
  84026. + if (fival->pixel_format == 0 || fival->width == 0 ||
  84027. + fival->height == 0) {
  84028. + pr_warning("Please assign pixelformat, width and height.\n");
  84029. + return -EINVAL;
  84030. + }
  84031. +
  84032. + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
  84033. + fival->discrete.numerator = 1;
  84034. +
  84035. + count = 0;
  84036. + for (i = 0; i < ARRAY_SIZE(ov5642_mode_info_data); i++) {
  84037. + for (j = 0; j < (ov5642_mode_MAX + 1); j++) {
  84038. + if (fival->pixel_format == ov5642_data.pix.pixelformat
  84039. + && fival->width == ov5642_mode_info_data[i][j].width
  84040. + && fival->height == ov5642_mode_info_data[i][j].height
  84041. + && ov5642_mode_info_data[i][j].init_data_ptr != NULL) {
  84042. + count++;
  84043. + }
  84044. + if (fival->index == (count - 1)) {
  84045. + fival->discrete.denominator =
  84046. + ov5642_framerates[i];
  84047. + return 0;
  84048. + }
  84049. + }
  84050. + }
  84051. +
  84052. + return -EINVAL;
  84053. +}
  84054. +
  84055. +/*!
  84056. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  84057. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  84058. + * @s: pointer to standard V4L2 device structure
  84059. + * @id: pointer to int
  84060. + *
  84061. + * Return 0.
  84062. + */
  84063. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  84064. +{
  84065. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  84066. + V4L2_CHIP_MATCH_I2C_DRIVER;
  84067. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name, "ov5642_camera");
  84068. +
  84069. + return 0;
  84070. +}
  84071. +
  84072. +/*!
  84073. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  84074. + * @s: pointer to standard V4L2 device structure
  84075. + */
  84076. +static int ioctl_init(struct v4l2_int_device *s)
  84077. +{
  84078. +
  84079. + return 0;
  84080. +}
  84081. +
  84082. +/*!
  84083. + * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
  84084. + * @s: pointer to standard V4L2 device structure
  84085. + * @fmt: pointer to standard V4L2 fmt description structure
  84086. + *
  84087. + * Return 0.
  84088. + */
  84089. +static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
  84090. + struct v4l2_fmtdesc *fmt)
  84091. +{
  84092. + if (fmt->index > 0) /* only 1 pixelformat support so far */
  84093. + return -EINVAL;
  84094. +
  84095. + fmt->pixelformat = ov5642_data.pix.pixelformat;
  84096. +
  84097. + return 0;
  84098. +}
  84099. +
  84100. +/*!
  84101. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  84102. + * @s: pointer to standard V4L2 device structure
  84103. + *
  84104. + * Initialise the device when slave attaches to the master.
  84105. + */
  84106. +static int ioctl_dev_init(struct v4l2_int_device *s)
  84107. +{
  84108. + struct reg_value *pModeSetting = NULL;
  84109. + s32 i = 0;
  84110. + s32 iModeSettingArySize = 0;
  84111. + register u32 Delay_ms = 0;
  84112. + register u16 RegAddr = 0;
  84113. + register u8 Mask = 0;
  84114. + register u8 Val = 0;
  84115. + u8 RegVal = 0;
  84116. + int retval = 0;
  84117. +
  84118. + struct sensor_data *sensor = s->priv;
  84119. + u32 tgt_xclk; /* target xclk */
  84120. + u32 tgt_fps; /* target frames per secound */
  84121. + enum ov5642_frame_rate frame_rate;
  84122. +
  84123. + ov5642_data.on = true;
  84124. +
  84125. + /* mclk */
  84126. + tgt_xclk = ov5642_data.mclk;
  84127. + tgt_xclk = min(tgt_xclk, (u32)OV5642_XCLK_MAX);
  84128. + tgt_xclk = max(tgt_xclk, (u32)OV5642_XCLK_MIN);
  84129. + ov5642_data.mclk = tgt_xclk;
  84130. +
  84131. + pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
  84132. +
  84133. + /* Default camera frame rate is set in probe */
  84134. + tgt_fps = sensor->streamcap.timeperframe.denominator /
  84135. + sensor->streamcap.timeperframe.numerator;
  84136. +
  84137. + if (tgt_fps == 15)
  84138. + frame_rate = ov5642_15_fps;
  84139. + else if (tgt_fps == 30)
  84140. + frame_rate = ov5642_30_fps;
  84141. + else
  84142. + return -EINVAL; /* Only support 15fps or 30fps now. */
  84143. +
  84144. + pModeSetting = ov5642_initial_setting;
  84145. + iModeSettingArySize = ARRAY_SIZE(ov5642_initial_setting);
  84146. +
  84147. + for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
  84148. + Delay_ms = pModeSetting->u32Delay_ms;
  84149. + RegAddr = pModeSetting->u16RegAddr;
  84150. + Val = pModeSetting->u8Val;
  84151. + Mask = pModeSetting->u8Mask;
  84152. + if (Mask) {
  84153. + retval = ov5642_read_reg(RegAddr, &RegVal);
  84154. + if (retval < 0)
  84155. + goto err;
  84156. +
  84157. + RegVal &= ~(u8)Mask;
  84158. + Val &= Mask;
  84159. + Val |= RegVal;
  84160. + }
  84161. +
  84162. + retval = ov5642_write_reg(RegAddr, Val);
  84163. + if (retval < 0)
  84164. + goto err;
  84165. +
  84166. + if (Delay_ms)
  84167. + msleep(Delay_ms);
  84168. + }
  84169. +err:
  84170. + return retval;
  84171. +}
  84172. +
  84173. +/*!
  84174. + * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
  84175. + * @s: pointer to standard V4L2 device structure
  84176. + *
  84177. + * Delinitialise the device when slave detaches to the master.
  84178. + */
  84179. +static int ioctl_dev_exit(struct v4l2_int_device *s)
  84180. +{
  84181. + return 0;
  84182. +}
  84183. +
  84184. +/*!
  84185. + * This structure defines all the ioctls for this module and links them to the
  84186. + * enumeration.
  84187. + */
  84188. +static struct v4l2_int_ioctl_desc ov5642_ioctl_desc[] = {
  84189. + { vidioc_int_dev_init_num,
  84190. + (v4l2_int_ioctl_func *)ioctl_dev_init },
  84191. + { vidioc_int_dev_exit_num, ioctl_dev_exit},
  84192. + { vidioc_int_s_power_num,
  84193. + (v4l2_int_ioctl_func *)ioctl_s_power },
  84194. + { vidioc_int_g_ifparm_num,
  84195. + (v4l2_int_ioctl_func *)ioctl_g_ifparm },
  84196. +/* { vidioc_int_g_needs_reset_num,
  84197. + (v4l2_int_ioctl_func *)ioctl_g_needs_reset }, */
  84198. +/* { vidioc_int_reset_num,
  84199. + (v4l2_int_ioctl_func *)ioctl_reset }, */
  84200. + { vidioc_int_init_num,
  84201. + (v4l2_int_ioctl_func *)ioctl_init },
  84202. + { vidioc_int_enum_fmt_cap_num,
  84203. + (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
  84204. +/* { vidioc_int_try_fmt_cap_num,
  84205. + (v4l2_int_ioctl_func *)ioctl_try_fmt_cap }, */
  84206. + { vidioc_int_g_fmt_cap_num,
  84207. + (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
  84208. +/* { vidioc_int_s_fmt_cap_num,
  84209. + (v4l2_int_ioctl_func *)ioctl_s_fmt_cap }, */
  84210. + { vidioc_int_g_parm_num,
  84211. + (v4l2_int_ioctl_func *)ioctl_g_parm },
  84212. + { vidioc_int_s_parm_num,
  84213. + (v4l2_int_ioctl_func *)ioctl_s_parm },
  84214. +/* { vidioc_int_queryctrl_num,
  84215. + (v4l2_int_ioctl_func *)ioctl_queryctrl }, */
  84216. + { vidioc_int_g_ctrl_num,
  84217. + (v4l2_int_ioctl_func *)ioctl_g_ctrl },
  84218. + { vidioc_int_s_ctrl_num,
  84219. + (v4l2_int_ioctl_func *)ioctl_s_ctrl },
  84220. + { vidioc_int_enum_framesizes_num,
  84221. + (v4l2_int_ioctl_func *)ioctl_enum_framesizes },
  84222. + { vidioc_int_enum_frameintervals_num,
  84223. + (v4l2_int_ioctl_func *)ioctl_enum_frameintervals },
  84224. + { vidioc_int_g_chip_ident_num,
  84225. + (v4l2_int_ioctl_func *)ioctl_g_chip_ident },
  84226. +};
  84227. +
  84228. +static struct v4l2_int_slave ov5642_slave = {
  84229. + .ioctls = ov5642_ioctl_desc,
  84230. + .num_ioctls = ARRAY_SIZE(ov5642_ioctl_desc),
  84231. +};
  84232. +
  84233. +static struct v4l2_int_device ov5642_int_device = {
  84234. + .module = THIS_MODULE,
  84235. + .name = "ov5642",
  84236. + .type = v4l2_int_type_slave,
  84237. + .u = {
  84238. + .slave = &ov5642_slave,
  84239. + },
  84240. +};
  84241. +
  84242. +/*!
  84243. + * ov5642 I2C probe function
  84244. + *
  84245. + * @param adapter struct i2c_adapter *
  84246. + * @return Error code indicating success or failure
  84247. + */
  84248. +static int ov5642_probe(struct i2c_client *client,
  84249. + const struct i2c_device_id *id)
  84250. +{
  84251. + struct pinctrl *pinctrl;
  84252. + struct device *dev = &client->dev;
  84253. + int retval;
  84254. + u8 chip_id_high, chip_id_low;
  84255. +
  84256. + /* ov5642 pinctrl */
  84257. + pinctrl = devm_pinctrl_get_select_default(dev);
  84258. + if (IS_ERR(pinctrl)) {
  84259. + dev_err(dev, "ov5642 setup pinctrl failed!");
  84260. + return PTR_ERR(pinctrl);
  84261. + }
  84262. +
  84263. + /* request power down pin */
  84264. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  84265. + if (!gpio_is_valid(pwn_gpio)) {
  84266. + dev_warn(dev, "no sensor pwdn pin available");
  84267. + return -EINVAL;
  84268. + }
  84269. + retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  84270. + "ov5642_pwdn");
  84271. + if (retval < 0)
  84272. + return retval;
  84273. +
  84274. + /* request reset pin */
  84275. + rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
  84276. + if (!gpio_is_valid(rst_gpio)) {
  84277. + dev_warn(dev, "no sensor reset pin available");
  84278. + return -EINVAL;
  84279. + }
  84280. + retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
  84281. + "ov5642_reset");
  84282. + if (retval < 0)
  84283. + return retval;
  84284. +
  84285. + /* Set initial values for the sensor struct. */
  84286. + memset(&ov5642_data, 0, sizeof(ov5642_data));
  84287. + ov5642_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
  84288. + if (IS_ERR(ov5642_data.sensor_clk)) {
  84289. + /* assuming clock enabled by default */
  84290. + ov5642_data.sensor_clk = NULL;
  84291. + dev_err(dev, "clock-frequency missing or invalid\n");
  84292. + return PTR_ERR(ov5642_data.sensor_clk);
  84293. + }
  84294. +
  84295. + retval = of_property_read_u32(dev->of_node, "mclk",
  84296. + (u32 *) &(ov5642_data.mclk));
  84297. + if (retval) {
  84298. + dev_err(dev, "mclk missing or invalid\n");
  84299. + return retval;
  84300. + }
  84301. +
  84302. + retval = of_property_read_u32(dev->of_node, "mclk_source",
  84303. + (u32 *) &(ov5642_data.mclk_source));
  84304. + if (retval) {
  84305. + dev_err(dev, "mclk_source missing or invalid\n");
  84306. + return retval;
  84307. + }
  84308. +
  84309. + retval = of_property_read_u32(dev->of_node, "csi_id",
  84310. + &(ov5642_data.csi));
  84311. + if (retval) {
  84312. + dev_err(dev, "csi_id missing or invalid\n");
  84313. + return retval;
  84314. + }
  84315. +
  84316. + clk_prepare_enable(ov5642_data.sensor_clk);
  84317. +
  84318. + ov5642_data.io_init = ov5642_reset;
  84319. + ov5642_data.i2c_client = client;
  84320. + ov5642_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  84321. + ov5642_data.pix.width = 640;
  84322. + ov5642_data.pix.height = 480;
  84323. + ov5642_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
  84324. + V4L2_CAP_TIMEPERFRAME;
  84325. + ov5642_data.streamcap.capturemode = 0;
  84326. + ov5642_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
  84327. + ov5642_data.streamcap.timeperframe.numerator = 1;
  84328. +
  84329. + ov5642_power_on(&client->dev);
  84330. +
  84331. + ov5642_reset();
  84332. +
  84333. + ov5642_standby(0);
  84334. +
  84335. + retval = ov5642_read_reg(OV5642_CHIP_ID_HIGH_BYTE, &chip_id_high);
  84336. + if (retval < 0 || chip_id_high != 0x56) {
  84337. + pr_warning("camera ov5642 is not found\n");
  84338. + clk_disable_unprepare(ov5642_data.sensor_clk);
  84339. + return -ENODEV;
  84340. + }
  84341. + retval = ov5642_read_reg(OV5642_CHIP_ID_LOW_BYTE, &chip_id_low);
  84342. + if (retval < 0 || chip_id_low != 0x42) {
  84343. + pr_warning("camera ov5642 is not found\n");
  84344. + clk_disable_unprepare(ov5642_data.sensor_clk);
  84345. + return -ENODEV;
  84346. + }
  84347. +
  84348. + ov5642_standby(1);
  84349. +
  84350. + ov5642_int_device.priv = &ov5642_data;
  84351. + retval = v4l2_int_device_register(&ov5642_int_device);
  84352. +
  84353. + clk_disable_unprepare(ov5642_data.sensor_clk);
  84354. +
  84355. + pr_info("camera ov5642 is found\n");
  84356. + return retval;
  84357. +}
  84358. +
  84359. +/*!
  84360. + * ov5642 I2C detach function
  84361. + *
  84362. + * @param client struct i2c_client *
  84363. + * @return Error code indicating success or failure
  84364. + */
  84365. +static int ov5642_remove(struct i2c_client *client)
  84366. +{
  84367. + v4l2_int_device_unregister(&ov5642_int_device);
  84368. +
  84369. + if (gpo_regulator)
  84370. + regulator_disable(gpo_regulator);
  84371. +
  84372. + if (analog_regulator)
  84373. + regulator_disable(analog_regulator);
  84374. +
  84375. + if (core_regulator)
  84376. + regulator_disable(core_regulator);
  84377. +
  84378. + if (io_regulator)
  84379. + regulator_disable(io_regulator);
  84380. +
  84381. + return 0;
  84382. +}
  84383. +
  84384. +/*!
  84385. + * ov5642 init function
  84386. + * Called by insmod ov5642_camera.ko.
  84387. + *
  84388. + * @return Error code indicating success or failure
  84389. + */
  84390. +static __init int ov5642_init(void)
  84391. +{
  84392. + u8 err;
  84393. +
  84394. + err = i2c_add_driver(&ov5642_i2c_driver);
  84395. + if (err != 0)
  84396. + pr_err("%s:driver registration failed, error=%d\n",
  84397. + __func__, err);
  84398. +
  84399. + return err;
  84400. +}
  84401. +
  84402. +/*!
  84403. + * OV5642 cleanup function
  84404. + * Called on rmmod ov5642_camera.ko
  84405. + *
  84406. + * @return Error code indicating success or failure
  84407. + */
  84408. +static void __exit ov5642_clean(void)
  84409. +{
  84410. + i2c_del_driver(&ov5642_i2c_driver);
  84411. +}
  84412. +
  84413. +module_init(ov5642_init);
  84414. +module_exit(ov5642_clean);
  84415. +
  84416. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  84417. +MODULE_DESCRIPTION("OV5642 Camera Driver");
  84418. +MODULE_LICENSE("GPL");
  84419. +MODULE_VERSION("1.0");
  84420. +MODULE_ALIAS("CSI");
  84421. diff -Nur linux-3.14.15/drivers/media/platform/mxc/output/Kconfig linux-linaro-stable-mx6/drivers/media/platform/mxc/output/Kconfig
  84422. --- linux-3.14.15/drivers/media/platform/mxc/output/Kconfig 1970-01-01 01:00:00.000000000 +0100
  84423. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/output/Kconfig 2014-08-20 19:31:45.440866052 +0200
  84424. @@ -0,0 +1,5 @@
  84425. +config VIDEO_MXC_IPU_OUTPUT
  84426. + tristate "IPU v4l2 output support"
  84427. + depends on VIDEO_MXC_OUTPUT && MXC_IPU
  84428. + ---help---
  84429. + This is the video4linux2 driver for IPU post processing video output.
  84430. diff -Nur linux-3.14.15/drivers/media/platform/mxc/output/Makefile linux-linaro-stable-mx6/drivers/media/platform/mxc/output/Makefile
  84431. --- linux-3.14.15/drivers/media/platform/mxc/output/Makefile 1970-01-01 01:00:00.000000000 +0100
  84432. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/output/Makefile 2014-08-20 19:31:45.440866052 +0200
  84433. @@ -0,0 +1 @@
  84434. +obj-$(CONFIG_VIDEO_MXC_IPU_OUTPUT) += mxc_vout.o
  84435. diff -Nur linux-3.14.15/drivers/media/platform/mxc/output/mxc_vout.c linux-linaro-stable-mx6/drivers/media/platform/mxc/output/mxc_vout.c
  84436. --- linux-3.14.15/drivers/media/platform/mxc/output/mxc_vout.c 1970-01-01 01:00:00.000000000 +0100
  84437. +++ linux-linaro-stable-mx6/drivers/media/platform/mxc/output/mxc_vout.c 2014-08-20 19:23:52.818842679 +0200
  84438. @@ -0,0 +1,2265 @@
  84439. +/*
  84440. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  84441. + */
  84442. +
  84443. +/*
  84444. + * The code contained herein is licensed under the GNU General Public
  84445. + * License. You may obtain a copy of the GNU General Public License
  84446. + * Version 2 or later at the following locations:
  84447. + *
  84448. + * http://www.opensource.org/licenses/gpl-license.html
  84449. + * http://www.gnu.org/copyleft/gpl.html
  84450. + */
  84451. +
  84452. +#include <linux/console.h>
  84453. +#include <linux/dma-mapping.h>
  84454. +#include <linux/init.h>
  84455. +#include <linux/ipu-v3.h>
  84456. +#include <linux/module.h>
  84457. +#include <linux/mxcfb.h>
  84458. +#include <linux/mxc_v4l2.h>
  84459. +#include <linux/platform_device.h>
  84460. +#include <linux/sched.h>
  84461. +#include <linux/types.h>
  84462. +#include <linux/videodev2.h>
  84463. +#include <linux/vmalloc.h>
  84464. +
  84465. +#include <media/videobuf-dma-contig.h>
  84466. +#include <media/v4l2-device.h>
  84467. +#include <media/v4l2-ioctl.h>
  84468. +
  84469. +#define UYVY_BLACK (0x00800080)
  84470. +#define RGB_BLACK (0x0)
  84471. +#define UV_BLACK (0x80)
  84472. +#define Y_BLACK (0x0)
  84473. +
  84474. +#define MAX_FB_NUM 6
  84475. +#define FB_BUFS 3
  84476. +#define VDOA_FB_BUFS (FB_BUFS - 1)
  84477. +#define VALID_HEIGHT_1080P (1080)
  84478. +#define FRAME_HEIGHT_1080P (1088)
  84479. +#define FRAME_WIDTH_1080P (1920)
  84480. +#define CHECK_TILED_1080P_DISPLAY(vout) \
  84481. + ((((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12) || \
  84482. + ((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12F)) &&\
  84483. + ((vout)->task.input.width == FRAME_WIDTH_1080P) && \
  84484. + ((vout)->task.input.height == FRAME_HEIGHT_1080P) && \
  84485. + ((vout)->task.input.crop.w == FRAME_WIDTH_1080P) && \
  84486. + (((vout)->task.input.crop.h == FRAME_HEIGHT_1080P) || \
  84487. + ((vout)->task.input.crop.h == VALID_HEIGHT_1080P)) && \
  84488. + ((vout)->task.output.width == FRAME_WIDTH_1080P) && \
  84489. + ((vout)->task.output.height == VALID_HEIGHT_1080P) && \
  84490. + ((vout)->task.output.crop.w == FRAME_WIDTH_1080P) && \
  84491. + ((vout)->task.output.crop.h == VALID_HEIGHT_1080P))
  84492. +#define CHECK_TILED_1080P_STREAM(vout) \
  84493. + ((((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12) || \
  84494. + ((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12F)) &&\
  84495. + ((vout)->task.input.width == FRAME_WIDTH_1080P) && \
  84496. + ((vout)->task.input.crop.w == FRAME_WIDTH_1080P) && \
  84497. + ((vout)->task.input.height == FRAME_HEIGHT_1080P) && \
  84498. + ((vout)->task.input.crop.h == FRAME_HEIGHT_1080P))
  84499. +#define IS_PLANAR_PIXEL_FORMAT(format) \
  84500. + (format == IPU_PIX_FMT_NV12 || \
  84501. + format == IPU_PIX_FMT_YUV420P2 || \
  84502. + format == IPU_PIX_FMT_YUV420P || \
  84503. + format == IPU_PIX_FMT_YVU420P || \
  84504. + format == IPU_PIX_FMT_YUV422P || \
  84505. + format == IPU_PIX_FMT_YVU422P || \
  84506. + format == IPU_PIX_FMT_YUV444P)
  84507. +
  84508. +#define NSEC_PER_FRAME_30FPS (33333333)
  84509. +
  84510. +struct mxc_vout_fb {
  84511. + char *name;
  84512. + int ipu_id;
  84513. + struct v4l2_rect crop_bounds;
  84514. + unsigned int disp_fmt;
  84515. + bool disp_support_csc;
  84516. + bool disp_support_windows;
  84517. +};
  84518. +
  84519. +struct dma_mem {
  84520. + void *vaddr;
  84521. + dma_addr_t paddr;
  84522. + size_t size;
  84523. +};
  84524. +
  84525. +struct mxc_vout_output {
  84526. + int open_cnt;
  84527. + struct fb_info *fbi;
  84528. + unsigned long fb_smem_start;
  84529. + unsigned long fb_smem_len;
  84530. + struct video_device *vfd;
  84531. + struct mutex mutex;
  84532. + struct mutex task_lock;
  84533. + enum v4l2_buf_type type;
  84534. +
  84535. + struct videobuf_queue vbq;
  84536. + spinlock_t vbq_lock;
  84537. +
  84538. + struct list_head queue_list;
  84539. + struct list_head active_list;
  84540. +
  84541. + struct v4l2_rect crop_bounds;
  84542. + unsigned int disp_fmt;
  84543. + struct mxcfb_pos win_pos;
  84544. + bool disp_support_windows;
  84545. + bool disp_support_csc;
  84546. +
  84547. + bool fmt_init;
  84548. + bool release;
  84549. + bool linear_bypass_pp;
  84550. + bool vdoa_1080p;
  84551. + bool tiled_bypass_pp;
  84552. + struct v4l2_rect in_rect;
  84553. + struct ipu_task task;
  84554. + struct ipu_task vdoa_task;
  84555. + struct dma_mem vdoa_work;
  84556. + struct dma_mem vdoa_output[VDOA_FB_BUFS];
  84557. +
  84558. + bool timer_stop;
  84559. + struct hrtimer timer;
  84560. + struct workqueue_struct *v4l_wq;
  84561. + struct work_struct disp_work;
  84562. + unsigned long frame_count;
  84563. + unsigned long vdi_frame_cnt;
  84564. + ktime_t start_ktime;
  84565. +
  84566. + int ctrl_rotate;
  84567. + int ctrl_vflip;
  84568. + int ctrl_hflip;
  84569. +
  84570. + dma_addr_t disp_bufs[FB_BUFS];
  84571. +
  84572. + struct videobuf_buffer *pre1_vb;
  84573. + struct videobuf_buffer *pre2_vb;
  84574. +};
  84575. +
  84576. +struct mxc_vout_dev {
  84577. + struct device *dev;
  84578. + struct v4l2_device v4l2_dev;
  84579. + struct mxc_vout_output *out[MAX_FB_NUM];
  84580. + int out_num;
  84581. +};
  84582. +
  84583. +/* Driver Configuration macros */
  84584. +#define VOUT_NAME "mxc_vout"
  84585. +
  84586. +/* Variables configurable through module params*/
  84587. +static int debug;
  84588. +static int vdi_rate_double;
  84589. +static int video_nr = 16;
  84590. +
  84591. +/* Module parameters */
  84592. +module_param(video_nr, int, S_IRUGO);
  84593. +MODULE_PARM_DESC(video_nr, "video device numbers");
  84594. +module_param(debug, int, 0600);
  84595. +MODULE_PARM_DESC(debug, "Debug level (0-1)");
  84596. +module_param(vdi_rate_double, int, 0600);
  84597. +MODULE_PARM_DESC(vdi_rate_double, "vdi frame rate double on/off");
  84598. +
  84599. +static const struct v4l2_fmtdesc mxc_formats[] = {
  84600. + {
  84601. + .description = "RGB565",
  84602. + .pixelformat = V4L2_PIX_FMT_RGB565,
  84603. + },
  84604. + {
  84605. + .description = "BGR24",
  84606. + .pixelformat = V4L2_PIX_FMT_BGR24,
  84607. + },
  84608. + {
  84609. + .description = "RGB24",
  84610. + .pixelformat = V4L2_PIX_FMT_RGB24,
  84611. + },
  84612. + {
  84613. + .description = "RGB32",
  84614. + .pixelformat = V4L2_PIX_FMT_RGB32,
  84615. + },
  84616. + {
  84617. + .description = "BGR32",
  84618. + .pixelformat = V4L2_PIX_FMT_BGR32,
  84619. + },
  84620. + {
  84621. + .description = "NV12",
  84622. + .pixelformat = V4L2_PIX_FMT_NV12,
  84623. + },
  84624. + {
  84625. + .description = "UYVY",
  84626. + .pixelformat = V4L2_PIX_FMT_UYVY,
  84627. + },
  84628. + {
  84629. + .description = "YUYV",
  84630. + .pixelformat = V4L2_PIX_FMT_YUYV,
  84631. + },
  84632. + {
  84633. + .description = "YUV422 planar",
  84634. + .pixelformat = V4L2_PIX_FMT_YUV422P,
  84635. + },
  84636. + {
  84637. + .description = "YUV444",
  84638. + .pixelformat = V4L2_PIX_FMT_YUV444,
  84639. + },
  84640. + {
  84641. + .description = "YUV420",
  84642. + .pixelformat = V4L2_PIX_FMT_YUV420,
  84643. + },
  84644. + {
  84645. + .description = "YVU420",
  84646. + .pixelformat = V4L2_PIX_FMT_YVU420,
  84647. + },
  84648. + {
  84649. + .description = "TILED NV12P",
  84650. + .pixelformat = IPU_PIX_FMT_TILED_NV12,
  84651. + },
  84652. + {
  84653. + .description = "TILED NV12F",
  84654. + .pixelformat = IPU_PIX_FMT_TILED_NV12F,
  84655. + },
  84656. + {
  84657. + .description = "YUV444 planar",
  84658. + .pixelformat = IPU_PIX_FMT_YUV444P,
  84659. + },
  84660. +};
  84661. +
  84662. +#define NUM_MXC_VOUT_FORMATS (ARRAY_SIZE(mxc_formats))
  84663. +
  84664. +#define DEF_INPUT_WIDTH 320
  84665. +#define DEF_INPUT_HEIGHT 240
  84666. +
  84667. +static int mxc_vidioc_streamoff(struct file *file, void *fh,
  84668. + enum v4l2_buf_type i);
  84669. +
  84670. +static struct mxc_vout_fb g_fb_setting[MAX_FB_NUM];
  84671. +static int config_disp_output(struct mxc_vout_output *vout);
  84672. +static void release_disp_output(struct mxc_vout_output *vout);
  84673. +
  84674. +static unsigned int get_frame_size(struct mxc_vout_output *vout)
  84675. +{
  84676. + unsigned int size;
  84677. +
  84678. + if (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format)
  84679. + size = TILED_NV12_FRAME_SIZE(vout->task.input.width,
  84680. + vout->task.input.height);
  84681. + else if (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format) {
  84682. + size = TILED_NV12_FRAME_SIZE(vout->task.input.width,
  84683. + vout->task.input.height/2);
  84684. + size *= 2;
  84685. + } else
  84686. + size = vout->task.input.width * vout->task.input.height *
  84687. + fmt_to_bpp(vout->task.input.format)/8;
  84688. +
  84689. + return size;
  84690. +}
  84691. +
  84692. +static void free_dma_buf(struct mxc_vout_output *vout, struct dma_mem *buf)
  84693. +{
  84694. + dma_free_coherent(vout->vbq.dev, buf->size, buf->vaddr, buf->paddr);
  84695. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84696. + "free dma size:0x%x, paddr:0x%x\n",
  84697. + buf->size, buf->paddr);
  84698. + memset(buf, 0, sizeof(*buf));
  84699. +}
  84700. +
  84701. +static int alloc_dma_buf(struct mxc_vout_output *vout, struct dma_mem *buf)
  84702. +{
  84703. +
  84704. + buf->vaddr = dma_alloc_coherent(vout->vbq.dev, buf->size, &buf->paddr,
  84705. + GFP_DMA | GFP_KERNEL);
  84706. + if (!buf->vaddr) {
  84707. + v4l2_err(vout->vfd->v4l2_dev,
  84708. + "cannot get dma buf size:0x%x\n", buf->size);
  84709. + return -ENOMEM;
  84710. + }
  84711. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84712. + "alloc dma buf size:0x%x, paddr:0x%x\n", buf->size, buf->paddr);
  84713. + return 0;
  84714. +}
  84715. +
  84716. +static ipu_channel_t get_ipu_channel(struct fb_info *fbi)
  84717. +{
  84718. + ipu_channel_t ipu_ch = CHAN_NONE;
  84719. + mm_segment_t old_fs;
  84720. +
  84721. + if (fbi->fbops->fb_ioctl) {
  84722. + old_fs = get_fs();
  84723. + set_fs(KERNEL_DS);
  84724. + fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_IPU_CHAN,
  84725. + (unsigned long)&ipu_ch);
  84726. + set_fs(old_fs);
  84727. + }
  84728. +
  84729. + return ipu_ch;
  84730. +}
  84731. +
  84732. +static unsigned int get_ipu_fmt(struct fb_info *fbi)
  84733. +{
  84734. + mm_segment_t old_fs;
  84735. + unsigned int fb_fmt;
  84736. +
  84737. + if (fbi->fbops->fb_ioctl) {
  84738. + old_fs = get_fs();
  84739. + set_fs(KERNEL_DS);
  84740. + fbi->fbops->fb_ioctl(fbi, MXCFB_GET_DIFMT,
  84741. + (unsigned long)&fb_fmt);
  84742. + set_fs(old_fs);
  84743. + }
  84744. +
  84745. + return fb_fmt;
  84746. +}
  84747. +
  84748. +static void update_display_setting(void)
  84749. +{
  84750. + int i;
  84751. + struct fb_info *fbi;
  84752. + struct v4l2_rect bg_crop_bounds[2];
  84753. +
  84754. + for (i = 0; i < num_registered_fb; i++) {
  84755. + fbi = registered_fb[i];
  84756. +
  84757. + memset(&g_fb_setting[i], 0, sizeof(struct mxc_vout_fb));
  84758. +
  84759. + if (!strncmp(fbi->fix.id, "DISP3", 5))
  84760. + g_fb_setting[i].ipu_id = 0;
  84761. + else
  84762. + g_fb_setting[i].ipu_id = 1;
  84763. +
  84764. + g_fb_setting[i].name = fbi->fix.id;
  84765. + g_fb_setting[i].crop_bounds.left = 0;
  84766. + g_fb_setting[i].crop_bounds.top = 0;
  84767. + g_fb_setting[i].crop_bounds.width = fbi->var.xres;
  84768. + g_fb_setting[i].crop_bounds.height = fbi->var.yres;
  84769. + g_fb_setting[i].disp_fmt = get_ipu_fmt(fbi);
  84770. +
  84771. + if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
  84772. + bg_crop_bounds[g_fb_setting[i].ipu_id] =
  84773. + g_fb_setting[i].crop_bounds;
  84774. + g_fb_setting[i].disp_support_csc = true;
  84775. + } else if (get_ipu_channel(fbi) == MEM_FG_SYNC) {
  84776. + g_fb_setting[i].disp_support_csc = true;
  84777. + g_fb_setting[i].disp_support_windows = true;
  84778. + }
  84779. + }
  84780. +
  84781. + for (i = 0; i < num_registered_fb; i++) {
  84782. + fbi = registered_fb[i];
  84783. +
  84784. + if (get_ipu_channel(fbi) == MEM_FG_SYNC)
  84785. + g_fb_setting[i].crop_bounds =
  84786. + bg_crop_bounds[g_fb_setting[i].ipu_id];
  84787. + }
  84788. +}
  84789. +
  84790. +/* called after g_fb_setting filled by update_display_setting */
  84791. +static int update_setting_from_fbi(struct mxc_vout_output *vout,
  84792. + struct fb_info *fbi)
  84793. +{
  84794. + int i;
  84795. + bool found = false;
  84796. +
  84797. + for (i = 0; i < MAX_FB_NUM; i++) {
  84798. + if (g_fb_setting[i].name) {
  84799. + if (!strcmp(fbi->fix.id, g_fb_setting[i].name)) {
  84800. + vout->crop_bounds = g_fb_setting[i].crop_bounds;
  84801. + vout->disp_fmt = g_fb_setting[i].disp_fmt;
  84802. + vout->disp_support_csc =
  84803. + g_fb_setting[i].disp_support_csc;
  84804. + vout->disp_support_windows =
  84805. + g_fb_setting[i].disp_support_windows;
  84806. + found = true;
  84807. + break;
  84808. + }
  84809. + }
  84810. + }
  84811. +
  84812. + if (!found) {
  84813. + v4l2_err(vout->vfd->v4l2_dev, "can not find output\n");
  84814. + return -EINVAL;
  84815. + }
  84816. + strlcpy(vout->vfd->name, fbi->fix.id, sizeof(vout->vfd->name));
  84817. +
  84818. + memset(&vout->task, 0, sizeof(struct ipu_task));
  84819. +
  84820. + vout->task.input.width = DEF_INPUT_WIDTH;
  84821. + vout->task.input.height = DEF_INPUT_HEIGHT;
  84822. + vout->task.input.crop.pos.x = 0;
  84823. + vout->task.input.crop.pos.y = 0;
  84824. + vout->task.input.crop.w = DEF_INPUT_WIDTH;
  84825. + vout->task.input.crop.h = DEF_INPUT_HEIGHT;
  84826. +
  84827. + vout->task.output.width = vout->crop_bounds.width;
  84828. + vout->task.output.height = vout->crop_bounds.height;
  84829. + vout->task.output.crop.pos.x = 0;
  84830. + vout->task.output.crop.pos.y = 0;
  84831. + vout->task.output.crop.w = vout->crop_bounds.width;
  84832. + vout->task.output.crop.h = vout->crop_bounds.height;
  84833. + if (colorspaceofpixel(vout->disp_fmt) == YUV_CS)
  84834. + vout->task.output.format = IPU_PIX_FMT_UYVY;
  84835. + else
  84836. + vout->task.output.format = IPU_PIX_FMT_RGB565;
  84837. +
  84838. + return 0;
  84839. +}
  84840. +
  84841. +static inline unsigned long get_jiffies(struct timeval *t)
  84842. +{
  84843. + struct timeval cur;
  84844. +
  84845. + if (t->tv_usec >= 1000000) {
  84846. + t->tv_sec += t->tv_usec / 1000000;
  84847. + t->tv_usec = t->tv_usec % 1000000;
  84848. + }
  84849. +
  84850. + do_gettimeofday(&cur);
  84851. + if ((t->tv_sec < cur.tv_sec)
  84852. + || ((t->tv_sec == cur.tv_sec) && (t->tv_usec < cur.tv_usec)))
  84853. + return jiffies;
  84854. +
  84855. + if (t->tv_usec < cur.tv_usec) {
  84856. + cur.tv_sec = t->tv_sec - cur.tv_sec - 1;
  84857. + cur.tv_usec = t->tv_usec + 1000000 - cur.tv_usec;
  84858. + } else {
  84859. + cur.tv_sec = t->tv_sec - cur.tv_sec;
  84860. + cur.tv_usec = t->tv_usec - cur.tv_usec;
  84861. + }
  84862. +
  84863. + return jiffies + timeval_to_jiffies(&cur);
  84864. +}
  84865. +
  84866. +static bool deinterlace_3_field(struct mxc_vout_output *vout)
  84867. +{
  84868. + return (vout->task.input.deinterlace.enable &&
  84869. + (vout->task.input.deinterlace.motion != HIGH_MOTION));
  84870. +}
  84871. +
  84872. +static int set_field_fmt(struct mxc_vout_output *vout, enum v4l2_field field)
  84873. +{
  84874. + struct ipu_deinterlace *deinterlace = &vout->task.input.deinterlace;
  84875. +
  84876. + switch (field) {
  84877. + /* Images are in progressive format, not interlaced */
  84878. + case V4L2_FIELD_NONE:
  84879. + case V4L2_FIELD_ANY:
  84880. + deinterlace->enable = false;
  84881. + deinterlace->field_fmt = 0;
  84882. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "Progressive frame.\n");
  84883. + break;
  84884. + case V4L2_FIELD_INTERLACED_TB:
  84885. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84886. + "Enable deinterlace TB.\n");
  84887. + deinterlace->enable = true;
  84888. + deinterlace->field_fmt = IPU_DEINTERLACE_FIELD_TOP;
  84889. + break;
  84890. + case V4L2_FIELD_INTERLACED_BT:
  84891. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84892. + "Enable deinterlace BT.\n");
  84893. + deinterlace->enable = true;
  84894. + deinterlace->field_fmt = IPU_DEINTERLACE_FIELD_BOTTOM;
  84895. + break;
  84896. + default:
  84897. + v4l2_err(vout->vfd->v4l2_dev,
  84898. + "field format:%d not supported yet!\n", field);
  84899. + return -EINVAL;
  84900. + }
  84901. +
  84902. + if (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format) {
  84903. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84904. + "tiled fmt enable deinterlace.\n");
  84905. + deinterlace->enable = true;
  84906. + }
  84907. +
  84908. + if (deinterlace->enable && vdi_rate_double)
  84909. + deinterlace->field_fmt |= IPU_DEINTERLACE_RATE_EN;
  84910. +
  84911. + return 0;
  84912. +}
  84913. +
  84914. +static bool is_pp_bypass(struct mxc_vout_output *vout)
  84915. +{
  84916. + if ((IPU_PIX_FMT_TILED_NV12 == vout->task.input.format) ||
  84917. + (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format))
  84918. + return false;
  84919. + if ((vout->task.input.width == vout->task.output.width) &&
  84920. + (vout->task.input.height == vout->task.output.height) &&
  84921. + (vout->task.input.crop.w == vout->task.output.crop.w) &&
  84922. + (vout->task.input.crop.h == vout->task.output.crop.h) &&
  84923. + (vout->task.output.rotate < IPU_ROTATE_HORIZ_FLIP) &&
  84924. + !vout->task.input.deinterlace.enable) {
  84925. + if (vout->disp_support_csc)
  84926. + return true;
  84927. + else if (!need_csc(vout->task.input.format, vout->disp_fmt))
  84928. + return true;
  84929. + /*
  84930. + * input crop show to full output which can show based on
  84931. + * xres_virtual/yres_virtual
  84932. + */
  84933. + } else if ((vout->task.input.crop.w == vout->task.output.crop.w) &&
  84934. + (vout->task.output.crop.w == vout->task.output.width) &&
  84935. + (vout->task.input.crop.h == vout->task.output.crop.h) &&
  84936. + (vout->task.output.crop.h ==
  84937. + vout->task.output.height) &&
  84938. + (vout->task.output.rotate < IPU_ROTATE_HORIZ_FLIP) &&
  84939. + !vout->task.input.deinterlace.enable) {
  84940. + if (vout->disp_support_csc)
  84941. + return true;
  84942. + else if (!need_csc(vout->task.input.format, vout->disp_fmt))
  84943. + return true;
  84944. + }
  84945. + return false;
  84946. +}
  84947. +
  84948. +static void setup_buf_timer(struct mxc_vout_output *vout,
  84949. + struct videobuf_buffer *vb)
  84950. +{
  84951. + ktime_t expiry_time, now;
  84952. +
  84953. + /* if timestamp is 0, then default to 30fps */
  84954. + if ((vb->ts.tv_sec == 0) && (vb->ts.tv_usec == 0))
  84955. + expiry_time = ktime_add_ns(vout->start_ktime,
  84956. + NSEC_PER_FRAME_30FPS * vout->frame_count);
  84957. + else
  84958. + expiry_time = timeval_to_ktime(vb->ts);
  84959. +
  84960. + now = hrtimer_cb_get_time(&vout->timer);
  84961. + if ((now.tv64 > expiry_time.tv64)) {
  84962. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84963. + "warning: timer timeout already expired.\n");
  84964. + expiry_time = now;
  84965. + }
  84966. +
  84967. + hrtimer_start(&vout->timer, expiry_time, HRTIMER_MODE_ABS);
  84968. +
  84969. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "timer handler next "
  84970. + "schedule: %lldnsecs\n", expiry_time.tv64);
  84971. +}
  84972. +
  84973. +static int show_buf(struct mxc_vout_output *vout, int idx,
  84974. + struct ipu_pos *ipos)
  84975. +{
  84976. + struct fb_info *fbi = vout->fbi;
  84977. + struct fb_var_screeninfo var;
  84978. + int ret;
  84979. + u32 fb_base = 0;
  84980. +
  84981. + memcpy(&var, &fbi->var, sizeof(var));
  84982. +
  84983. + if (vout->linear_bypass_pp || vout->tiled_bypass_pp) {
  84984. + /*
  84985. + * crack fb base
  84986. + * NOTE: should not do other fb operation during v4l2
  84987. + */
  84988. + console_lock();
  84989. + fb_base = fbi->fix.smem_start;
  84990. + fbi->fix.smem_start = vout->task.output.paddr;
  84991. + fbi->var.yoffset = ipos->y + 1;
  84992. + var.xoffset = ipos->x;
  84993. + var.yoffset = ipos->y;
  84994. + var.vmode |= FB_VMODE_YWRAP;
  84995. + ret = fb_pan_display(fbi, &var);
  84996. + fbi->fix.smem_start = fb_base;
  84997. + console_unlock();
  84998. + } else {
  84999. + console_lock();
  85000. + var.yoffset = idx * fbi->var.yres;
  85001. + var.vmode &= ~FB_VMODE_YWRAP;
  85002. + ret = fb_pan_display(fbi, &var);
  85003. + console_unlock();
  85004. + }
  85005. +
  85006. + return ret;
  85007. +}
  85008. +
  85009. +static void disp_work_func(struct work_struct *work)
  85010. +{
  85011. + struct mxc_vout_output *vout =
  85012. + container_of(work, struct mxc_vout_output, disp_work);
  85013. + struct videobuf_queue *q = &vout->vbq;
  85014. + struct videobuf_buffer *vb, *vb_next = NULL;
  85015. + unsigned long flags = 0;
  85016. + struct ipu_pos ipos;
  85017. + int ret = 0;
  85018. + u32 in_fmt = 0;
  85019. + u32 vdi_cnt = 0;
  85020. + u32 vdi_frame;
  85021. + u32 index = 0;
  85022. + u32 ocrop_h = 0;
  85023. + u32 o_height = 0;
  85024. + u32 tiled_interlaced = 0;
  85025. + bool tiled_fmt = false;
  85026. +
  85027. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "disp work begin one frame\n");
  85028. +
  85029. + spin_lock_irqsave(q->irqlock, flags);
  85030. +
  85031. + if (list_empty(&vout->active_list)) {
  85032. + v4l2_warn(vout->vfd->v4l2_dev,
  85033. + "no entry in active_list, should not be here\n");
  85034. + spin_unlock_irqrestore(q->irqlock, flags);
  85035. + return;
  85036. + }
  85037. +
  85038. + vb = list_first_entry(&vout->active_list,
  85039. + struct videobuf_buffer, queue);
  85040. + ret = set_field_fmt(vout, vb->field);
  85041. + if (ret < 0) {
  85042. + spin_unlock_irqrestore(q->irqlock, flags);
  85043. + return;
  85044. + }
  85045. + if (deinterlace_3_field(vout)) {
  85046. + if (list_is_singular(&vout->active_list)) {
  85047. + if (list_empty(&vout->queue_list)) {
  85048. + vout->timer_stop = true;
  85049. + spin_unlock_irqrestore(q->irqlock, flags);
  85050. + v4l2_warn(vout->vfd->v4l2_dev,
  85051. + "no enough entry for 3 fields "
  85052. + "deinterlacer\n");
  85053. + return;
  85054. + }
  85055. +
  85056. + /*
  85057. + * We need to use the next vb even if it is
  85058. + * not on the active list.
  85059. + */
  85060. + vb_next = list_first_entry(&vout->queue_list,
  85061. + struct videobuf_buffer, queue);
  85062. + } else
  85063. + vb_next = list_first_entry(vout->active_list.next,
  85064. + struct videobuf_buffer, queue);
  85065. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85066. + "cur field_fmt:%d, next field_fmt:%d.\n",
  85067. + vb->field, vb_next->field);
  85068. + /* repeat the last field during field format changing */
  85069. + if ((vb->field != vb_next->field) &&
  85070. + (vb_next->field != V4L2_FIELD_NONE))
  85071. + vb_next = vb;
  85072. + }
  85073. +
  85074. + spin_unlock_irqrestore(q->irqlock, flags);
  85075. +
  85076. +vdi_frame_rate_double:
  85077. + mutex_lock(&vout->task_lock);
  85078. +
  85079. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85080. + "v4l2 frame_cnt:%ld, vb_field:%d, fmt:%d\n",
  85081. + vout->frame_count, vb->field,
  85082. + vout->task.input.deinterlace.field_fmt);
  85083. + if (vb->memory == V4L2_MEMORY_USERPTR)
  85084. + vout->task.input.paddr = vb->baddr;
  85085. + else
  85086. + vout->task.input.paddr = videobuf_to_dma_contig(vb);
  85087. +
  85088. + if (vout->task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN)
  85089. + index = vout->vdi_frame_cnt % FB_BUFS;
  85090. + else
  85091. + index = vout->frame_count % FB_BUFS;
  85092. + if (vout->linear_bypass_pp) {
  85093. + vout->task.output.paddr = vout->task.input.paddr;
  85094. + ipos.x = vout->task.input.crop.pos.x;
  85095. + ipos.y = vout->task.input.crop.pos.y;
  85096. + } else {
  85097. + if (deinterlace_3_field(vout)) {
  85098. + if (vb->memory == V4L2_MEMORY_USERPTR)
  85099. + vout->task.input.paddr_n = vb_next->baddr;
  85100. + else
  85101. + vout->task.input.paddr_n =
  85102. + videobuf_to_dma_contig(vb_next);
  85103. + }
  85104. + vout->task.output.paddr = vout->disp_bufs[index];
  85105. + if (vout->vdoa_1080p) {
  85106. + o_height = vout->task.output.height;
  85107. + ocrop_h = vout->task.output.crop.h;
  85108. + vout->task.output.height = FRAME_HEIGHT_1080P;
  85109. + vout->task.output.crop.h = FRAME_HEIGHT_1080P;
  85110. + }
  85111. + tiled_fmt =
  85112. + (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format) ||
  85113. + (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format);
  85114. + if (vout->tiled_bypass_pp) {
  85115. + ipos.x = vout->task.input.crop.pos.x;
  85116. + ipos.y = vout->task.input.crop.pos.y;
  85117. + } else if (tiled_fmt) {
  85118. + vout->vdoa_task.input.paddr = vout->task.input.paddr;
  85119. + if (deinterlace_3_field(vout))
  85120. + vout->vdoa_task.input.paddr_n =
  85121. + vout->task.input.paddr_n;
  85122. + vout->vdoa_task.output.paddr = vout->vdoa_work.paddr;
  85123. + ret = ipu_queue_task(&vout->vdoa_task);
  85124. + if (ret < 0) {
  85125. + mutex_unlock(&vout->task_lock);
  85126. + goto err;
  85127. + }
  85128. + vout->task.input.paddr = vout->vdoa_task.output.paddr;
  85129. + in_fmt = vout->task.input.format;
  85130. + vout->task.input.format = vout->vdoa_task.output.format;
  85131. + if (vout->task.input.deinterlace.enable) {
  85132. + tiled_interlaced = 1;
  85133. + vout->task.input.deinterlace.enable = 0;
  85134. + }
  85135. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85136. + "tiled queue task\n");
  85137. + }
  85138. + ret = ipu_queue_task(&vout->task);
  85139. + if ((!vout->tiled_bypass_pp) && tiled_fmt)
  85140. + vout->task.input.format = in_fmt;
  85141. + if (tiled_interlaced)
  85142. + vout->task.input.deinterlace.enable = 1;
  85143. + if (ret < 0) {
  85144. + mutex_unlock(&vout->task_lock);
  85145. + goto err;
  85146. + }
  85147. + if (vout->vdoa_1080p) {
  85148. + vout->task.output.crop.h = ocrop_h;
  85149. + vout->task.output.height = o_height;
  85150. + }
  85151. + }
  85152. +
  85153. + mutex_unlock(&vout->task_lock);
  85154. +
  85155. + ret = show_buf(vout, index, &ipos);
  85156. + if (ret < 0)
  85157. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85158. + "show buf with ret %d\n", ret);
  85159. +
  85160. + if (vout->task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN) {
  85161. + vdi_frame = vout->task.input.deinterlace.field_fmt
  85162. + & IPU_DEINTERLACE_RATE_FRAME1;
  85163. + if (vdi_frame)
  85164. + vout->task.input.deinterlace.field_fmt &=
  85165. + ~IPU_DEINTERLACE_RATE_FRAME1;
  85166. + else
  85167. + vout->task.input.deinterlace.field_fmt |=
  85168. + IPU_DEINTERLACE_RATE_FRAME1;
  85169. + vout->vdi_frame_cnt++;
  85170. + vdi_cnt++;
  85171. + if (vdi_cnt < IPU_DEINTERLACE_MAX_FRAME)
  85172. + goto vdi_frame_rate_double;
  85173. + }
  85174. + spin_lock_irqsave(q->irqlock, flags);
  85175. +
  85176. + list_del(&vb->queue);
  85177. +
  85178. + /*
  85179. + * The videobuf before the last one has been shown. Set
  85180. + * VIDEOBUF_DONE state here to avoid tearing issue in ic bypass
  85181. + * case, which makes sure a buffer being shown will not be
  85182. + * dequeued to be overwritten. It also brings side-effect that
  85183. + * the last 2 buffers can not be dequeued correctly, apps need
  85184. + * to take care of it.
  85185. + */
  85186. + if (vout->pre2_vb) {
  85187. + vout->pre2_vb->state = VIDEOBUF_DONE;
  85188. + wake_up_interruptible(&vout->pre2_vb->done);
  85189. + vout->pre2_vb = NULL;
  85190. + }
  85191. +
  85192. + if (vout->linear_bypass_pp) {
  85193. + vout->pre2_vb = vout->pre1_vb;
  85194. + vout->pre1_vb = vb;
  85195. + } else {
  85196. + if (vout->pre1_vb) {
  85197. + vout->pre1_vb->state = VIDEOBUF_DONE;
  85198. + wake_up_interruptible(&vout->pre1_vb->done);
  85199. + vout->pre1_vb = NULL;
  85200. + }
  85201. + vb->state = VIDEOBUF_DONE;
  85202. + wake_up_interruptible(&vb->done);
  85203. + }
  85204. +
  85205. + vout->frame_count++;
  85206. +
  85207. + /* pick next queue buf to setup timer */
  85208. + if (list_empty(&vout->queue_list))
  85209. + vout->timer_stop = true;
  85210. + else {
  85211. + vb = list_first_entry(&vout->queue_list,
  85212. + struct videobuf_buffer, queue);
  85213. + setup_buf_timer(vout, vb);
  85214. + }
  85215. +
  85216. + spin_unlock_irqrestore(q->irqlock, flags);
  85217. +
  85218. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "disp work finish one frame\n");
  85219. +
  85220. + return;
  85221. +err:
  85222. + v4l2_err(vout->vfd->v4l2_dev, "display work fail ret = %d\n", ret);
  85223. + vout->timer_stop = true;
  85224. + vb->state = VIDEOBUF_ERROR;
  85225. + return;
  85226. +}
  85227. +
  85228. +static enum hrtimer_restart mxc_vout_timer_handler(struct hrtimer *timer)
  85229. +{
  85230. + struct mxc_vout_output *vout = container_of(timer,
  85231. + struct mxc_vout_output,
  85232. + timer);
  85233. + struct videobuf_queue *q = &vout->vbq;
  85234. + struct videobuf_buffer *vb;
  85235. + unsigned long flags = 0;
  85236. +
  85237. + spin_lock_irqsave(q->irqlock, flags);
  85238. +
  85239. + /*
  85240. + * put first queued entry into active, if previous entry did not
  85241. + * finish, setup current entry's timer again.
  85242. + */
  85243. + if (list_empty(&vout->queue_list)) {
  85244. + spin_unlock_irqrestore(q->irqlock, flags);
  85245. + return HRTIMER_NORESTART;
  85246. + }
  85247. +
  85248. + /* move videobuf from queued list to active list */
  85249. + vb = list_first_entry(&vout->queue_list,
  85250. + struct videobuf_buffer, queue);
  85251. + list_del(&vb->queue);
  85252. + list_add_tail(&vb->queue, &vout->active_list);
  85253. +
  85254. + if (queue_work(vout->v4l_wq, &vout->disp_work) == 0) {
  85255. + v4l2_warn(vout->vfd->v4l2_dev,
  85256. + "disp work was in queue already, queue buf again next time\n");
  85257. + list_del(&vb->queue);
  85258. + list_add(&vb->queue, &vout->queue_list);
  85259. + spin_unlock_irqrestore(q->irqlock, flags);
  85260. + return HRTIMER_NORESTART;
  85261. + }
  85262. +
  85263. + vb->state = VIDEOBUF_ACTIVE;
  85264. +
  85265. + spin_unlock_irqrestore(q->irqlock, flags);
  85266. +
  85267. + return HRTIMER_NORESTART;
  85268. +}
  85269. +
  85270. +/* Video buffer call backs */
  85271. +
  85272. +/*
  85273. + * Buffer setup function is called by videobuf layer when REQBUF ioctl is
  85274. + * called. This is used to setup buffers and return size and count of
  85275. + * buffers allocated. After the call to this buffer, videobuf layer will
  85276. + * setup buffer queue depending on the size and count of buffers
  85277. + */
  85278. +static int mxc_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
  85279. + unsigned int *size)
  85280. +{
  85281. + struct mxc_vout_output *vout = q->priv_data;
  85282. + unsigned int frame_size;
  85283. +
  85284. + if (!vout)
  85285. + return -EINVAL;
  85286. +
  85287. + if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
  85288. + return -EINVAL;
  85289. +
  85290. + frame_size = get_frame_size(vout);
  85291. + *size = PAGE_ALIGN(frame_size);
  85292. +
  85293. + return 0;
  85294. +}
  85295. +
  85296. +/*
  85297. + * This function will be called when VIDIOC_QBUF ioctl is called.
  85298. + * It prepare buffers before give out for the display. This function
  85299. + * converts user space virtual address into physical address if userptr memory
  85300. + * exchange mechanism is used.
  85301. + */
  85302. +static int mxc_vout_buffer_prepare(struct videobuf_queue *q,
  85303. + struct videobuf_buffer *vb,
  85304. + enum v4l2_field field)
  85305. +{
  85306. + vb->state = VIDEOBUF_PREPARED;
  85307. + return 0;
  85308. +}
  85309. +
  85310. +/*
  85311. + * Buffer queue funtion will be called from the videobuf layer when _QBUF
  85312. + * ioctl is called. It is used to enqueue buffer, which is ready to be
  85313. + * displayed.
  85314. + * This function is protected by q->irqlock.
  85315. + */
  85316. +static void mxc_vout_buffer_queue(struct videobuf_queue *q,
  85317. + struct videobuf_buffer *vb)
  85318. +{
  85319. + struct mxc_vout_output *vout = q->priv_data;
  85320. + struct videobuf_buffer *active_vb;
  85321. +
  85322. + list_add_tail(&vb->queue, &vout->queue_list);
  85323. + vb->state = VIDEOBUF_QUEUED;
  85324. +
  85325. + if (vout->timer_stop) {
  85326. + if (deinterlace_3_field(vout) &&
  85327. + !list_empty(&vout->active_list)) {
  85328. + active_vb = list_first_entry(&vout->active_list,
  85329. + struct videobuf_buffer, queue);
  85330. + setup_buf_timer(vout, active_vb);
  85331. + } else {
  85332. + setup_buf_timer(vout, vb);
  85333. + }
  85334. + vout->timer_stop = false;
  85335. + }
  85336. +}
  85337. +
  85338. +/*
  85339. + * Buffer release function is called from videobuf layer to release buffer
  85340. + * which are already allocated
  85341. + */
  85342. +static void mxc_vout_buffer_release(struct videobuf_queue *q,
  85343. + struct videobuf_buffer *vb)
  85344. +{
  85345. + vb->state = VIDEOBUF_NEEDS_INIT;
  85346. +}
  85347. +
  85348. +static int mxc_vout_mmap(struct file *file, struct vm_area_struct *vma)
  85349. +{
  85350. + int ret;
  85351. + struct mxc_vout_output *vout = file->private_data;
  85352. +
  85353. + if (!vout)
  85354. + return -ENODEV;
  85355. +
  85356. + ret = videobuf_mmap_mapper(&vout->vbq, vma);
  85357. + if (ret < 0)
  85358. + v4l2_err(vout->vfd->v4l2_dev,
  85359. + "offset invalid [offset=0x%lx]\n",
  85360. + (vma->vm_pgoff << PAGE_SHIFT));
  85361. +
  85362. + return ret;
  85363. +}
  85364. +
  85365. +static int mxc_vout_release(struct file *file)
  85366. +{
  85367. + unsigned int ret = 0;
  85368. + struct videobuf_queue *q;
  85369. + struct mxc_vout_output *vout = file->private_data;
  85370. +
  85371. + if (!vout)
  85372. + return 0;
  85373. +
  85374. + if (--vout->open_cnt == 0) {
  85375. + q = &vout->vbq;
  85376. + if (q->streaming)
  85377. + mxc_vidioc_streamoff(file, vout, vout->type);
  85378. + else {
  85379. + release_disp_output(vout);
  85380. + videobuf_queue_cancel(q);
  85381. + }
  85382. + destroy_workqueue(vout->v4l_wq);
  85383. + ret = videobuf_mmap_free(q);
  85384. + }
  85385. +
  85386. + return ret;
  85387. +}
  85388. +
  85389. +static int mxc_vout_open(struct file *file)
  85390. +{
  85391. + struct mxc_vout_output *vout = NULL;
  85392. + int ret = 0;
  85393. +
  85394. + vout = video_drvdata(file);
  85395. +
  85396. + if (vout == NULL)
  85397. + return -ENODEV;
  85398. +
  85399. + if (vout->open_cnt++ == 0) {
  85400. + vout->ctrl_rotate = 0;
  85401. + vout->ctrl_vflip = 0;
  85402. + vout->ctrl_hflip = 0;
  85403. + update_display_setting();
  85404. + ret = update_setting_from_fbi(vout, vout->fbi);
  85405. + if (ret < 0)
  85406. + goto err;
  85407. +
  85408. + vout->v4l_wq = create_singlethread_workqueue("v4l2q");
  85409. + if (!vout->v4l_wq) {
  85410. + v4l2_err(vout->vfd->v4l2_dev,
  85411. + "Could not create work queue\n");
  85412. + ret = -ENOMEM;
  85413. + goto err;
  85414. + }
  85415. +
  85416. + INIT_WORK(&vout->disp_work, disp_work_func);
  85417. +
  85418. + INIT_LIST_HEAD(&vout->queue_list);
  85419. + INIT_LIST_HEAD(&vout->active_list);
  85420. +
  85421. + vout->fmt_init = false;
  85422. + vout->frame_count = 0;
  85423. + vout->vdi_frame_cnt = 0;
  85424. +
  85425. + vout->win_pos.x = 0;
  85426. + vout->win_pos.y = 0;
  85427. + vout->release = true;
  85428. + }
  85429. +
  85430. + file->private_data = vout;
  85431. +
  85432. +err:
  85433. + return ret;
  85434. +}
  85435. +
  85436. +/*
  85437. + * V4L2 ioctls
  85438. + */
  85439. +static int mxc_vidioc_querycap(struct file *file, void *fh,
  85440. + struct v4l2_capability *cap)
  85441. +{
  85442. + struct mxc_vout_output *vout = fh;
  85443. +
  85444. + strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
  85445. + strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
  85446. + cap->bus_info[0] = '\0';
  85447. + cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT;
  85448. +
  85449. + return 0;
  85450. +}
  85451. +
  85452. +static int mxc_vidioc_enum_fmt_vid_out(struct file *file, void *fh,
  85453. + struct v4l2_fmtdesc *fmt)
  85454. +{
  85455. + if (fmt->index >= NUM_MXC_VOUT_FORMATS)
  85456. + return -EINVAL;
  85457. +
  85458. + strlcpy(fmt->description, mxc_formats[fmt->index].description,
  85459. + sizeof(fmt->description));
  85460. + fmt->pixelformat = mxc_formats[fmt->index].pixelformat;
  85461. +
  85462. + return 0;
  85463. +}
  85464. +
  85465. +static int mxc_vidioc_g_fmt_vid_out(struct file *file, void *fh,
  85466. + struct v4l2_format *f)
  85467. +{
  85468. + struct mxc_vout_output *vout = fh;
  85469. + struct v4l2_rect rect;
  85470. +
  85471. + f->fmt.pix.width = vout->task.input.width;
  85472. + f->fmt.pix.height = vout->task.input.height;
  85473. + f->fmt.pix.pixelformat = vout->task.input.format;
  85474. + f->fmt.pix.sizeimage = get_frame_size(vout);
  85475. +
  85476. + if (f->fmt.pix.priv) {
  85477. + rect.left = vout->task.input.crop.pos.x;
  85478. + rect.top = vout->task.input.crop.pos.y;
  85479. + rect.width = vout->task.input.crop.w;
  85480. + rect.height = vout->task.input.crop.h;
  85481. + if (copy_to_user((void __user *)f->fmt.pix.priv,
  85482. + &rect, sizeof(rect)))
  85483. + return -EFAULT;
  85484. + }
  85485. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85486. + "frame_size:0x%x, pix_fmt:0x%x\n",
  85487. + f->fmt.pix.sizeimage,
  85488. + vout->task.input.format);
  85489. +
  85490. + return 0;
  85491. +}
  85492. +
  85493. +static inline int ipu_try_task(struct mxc_vout_output *vout)
  85494. +{
  85495. + int ret;
  85496. + struct ipu_task *task = &vout->task;
  85497. +
  85498. +again:
  85499. + ret = ipu_check_task(task);
  85500. + if (ret != IPU_CHECK_OK) {
  85501. + if (ret > IPU_CHECK_ERR_MIN) {
  85502. + if (ret == IPU_CHECK_ERR_SPLIT_INPUTW_OVER ||
  85503. + ret == IPU_CHECK_ERR_W_DOWNSIZE_OVER) {
  85504. + task->input.crop.w -= 8;
  85505. + goto again;
  85506. + }
  85507. + if (ret == IPU_CHECK_ERR_SPLIT_INPUTH_OVER ||
  85508. + ret == IPU_CHECK_ERR_H_DOWNSIZE_OVER) {
  85509. + task->input.crop.h -= 8;
  85510. + goto again;
  85511. + }
  85512. + if (ret == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
  85513. + if (vout->disp_support_windows) {
  85514. + task->output.width -= 8;
  85515. + task->output.crop.w =
  85516. + task->output.width;
  85517. + } else
  85518. + task->output.crop.w -= 8;
  85519. + goto again;
  85520. + }
  85521. + if (ret == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
  85522. + if (vout->disp_support_windows) {
  85523. + task->output.height -= 8;
  85524. + task->output.crop.h =
  85525. + task->output.height;
  85526. + } else
  85527. + task->output.crop.h -= 8;
  85528. + goto again;
  85529. + }
  85530. + ret = -EINVAL;
  85531. + }
  85532. + } else
  85533. + ret = 0;
  85534. +
  85535. + return ret;
  85536. +}
  85537. +
  85538. +static inline int vdoaipu_try_task(struct mxc_vout_output *vout)
  85539. +{
  85540. + int ret;
  85541. + int is_1080p_stream;
  85542. + size_t size;
  85543. + struct ipu_task *ipu_task = &vout->task;
  85544. + struct ipu_crop *icrop = &ipu_task->input.crop;
  85545. + struct ipu_task *vdoa_task = &vout->vdoa_task;
  85546. + u32 deinterlace = 0;
  85547. + u32 in_fmt;
  85548. +
  85549. + if (vout->task.input.deinterlace.enable)
  85550. + deinterlace = 1;
  85551. +
  85552. + memset(vdoa_task, 0, sizeof(*vdoa_task));
  85553. + vdoa_task->output.format = IPU_PIX_FMT_NV12;
  85554. + memcpy(&vdoa_task->input, &ipu_task->input,
  85555. + sizeof(ipu_task->input));
  85556. + if ((icrop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  85557. + (icrop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
  85558. + vdoa_task->input.crop.w =
  85559. + ALIGN(icrop->w, IPU_PIX_FMT_TILED_NV12_MBALIGN);
  85560. + vdoa_task->input.crop.h =
  85561. + ALIGN(icrop->h, IPU_PIX_FMT_TILED_NV12_MBALIGN);
  85562. + }
  85563. + vdoa_task->output.width = vdoa_task->input.crop.w;
  85564. + vdoa_task->output.height = vdoa_task->input.crop.h;
  85565. + vdoa_task->output.crop.w = vdoa_task->input.crop.w;
  85566. + vdoa_task->output.crop.h = vdoa_task->input.crop.h;
  85567. +
  85568. + size = PAGE_ALIGN(vdoa_task->input.crop.w *
  85569. + vdoa_task->input.crop.h *
  85570. + fmt_to_bpp(vdoa_task->output.format)/8);
  85571. + if (size > vout->vdoa_work.size) {
  85572. + if (vout->vdoa_work.vaddr)
  85573. + free_dma_buf(vout, &vout->vdoa_work);
  85574. + vout->vdoa_work.size = size;
  85575. + ret = alloc_dma_buf(vout, &vout->vdoa_work);
  85576. + if (ret < 0)
  85577. + return ret;
  85578. + }
  85579. + ret = ipu_check_task(vdoa_task);
  85580. + if (ret != IPU_CHECK_OK)
  85581. + return -EINVAL;
  85582. +
  85583. + is_1080p_stream = CHECK_TILED_1080P_STREAM(vout);
  85584. + if (is_1080p_stream)
  85585. + ipu_task->input.crop.h = VALID_HEIGHT_1080P;
  85586. + in_fmt = ipu_task->input.format;
  85587. + ipu_task->input.format = vdoa_task->output.format;
  85588. + ipu_task->input.height = vdoa_task->output.height;
  85589. + ipu_task->input.width = vdoa_task->output.width;
  85590. + if (deinterlace)
  85591. + ipu_task->input.deinterlace.enable = 0;
  85592. + ret = ipu_try_task(vout);
  85593. + if (deinterlace)
  85594. + ipu_task->input.deinterlace.enable = 1;
  85595. + ipu_task->input.format = in_fmt;
  85596. +
  85597. + return ret;
  85598. +}
  85599. +
  85600. +static int mxc_vout_try_task(struct mxc_vout_output *vout)
  85601. +{
  85602. + int ret = 0;
  85603. + struct ipu_output *output = &vout->task.output;
  85604. + struct ipu_input *input = &vout->task.input;
  85605. + struct ipu_crop *crop = &input->crop;
  85606. + u32 o_height = 0;
  85607. + u32 ocrop_h = 0;
  85608. + bool tiled_fmt = false;
  85609. + bool tiled_need_pp = false;
  85610. +
  85611. + vout->vdoa_1080p = CHECK_TILED_1080P_DISPLAY(vout);
  85612. + if (vout->vdoa_1080p) {
  85613. + input->crop.h = FRAME_HEIGHT_1080P;
  85614. + o_height = output->height;
  85615. + ocrop_h = output->crop.h;
  85616. + output->height = FRAME_HEIGHT_1080P;
  85617. + output->crop.h = FRAME_HEIGHT_1080P;
  85618. + }
  85619. +
  85620. + if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
  85621. + (IPU_PIX_FMT_TILED_NV12F == input->format)) {
  85622. + if ((input->width % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  85623. + (input->height % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  85624. + (crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  85625. + (crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
  85626. + v4l2_err(vout->vfd->v4l2_dev,
  85627. + "ERR: tiled fmt needs 16 pixel align.\n");
  85628. + return -EINVAL;
  85629. + }
  85630. + if ((crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  85631. + (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  85632. + tiled_need_pp = true;
  85633. + } else {
  85634. + crop->w -= crop->w % 8;
  85635. + crop->h -= crop->h % 8;
  85636. + }
  85637. + /* assume task.output already set by S_CROP */
  85638. + vout->linear_bypass_pp = is_pp_bypass(vout);
  85639. + if (vout->linear_bypass_pp) {
  85640. + v4l2_info(vout->vfd->v4l2_dev, "Bypass IC.\n");
  85641. + output->format = input->format;
  85642. + } else {
  85643. + /* if need CSC, choose IPU-DP or IPU_IC do it */
  85644. + if (vout->disp_support_csc) {
  85645. + if (colorspaceofpixel(input->format) == YUV_CS)
  85646. + output->format = IPU_PIX_FMT_UYVY;
  85647. + else
  85648. + output->format = IPU_PIX_FMT_RGB565;
  85649. + } else {
  85650. + if (colorspaceofpixel(vout->disp_fmt) == YUV_CS)
  85651. + output->format = IPU_PIX_FMT_UYVY;
  85652. + else
  85653. + output->format = IPU_PIX_FMT_RGB565;
  85654. + }
  85655. +
  85656. + vout->tiled_bypass_pp = false;
  85657. + if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
  85658. + (IPU_PIX_FMT_TILED_NV12F == input->format)) {
  85659. + /* check resize/rotate/flip, or csc task */
  85660. + if (!(tiled_need_pp ||
  85661. + (IPU_ROTATE_NONE != output->rotate) ||
  85662. + (input->crop.w != output->crop.w) ||
  85663. + (input->crop.h != output->crop.h) ||
  85664. + (!vout->disp_support_csc &&
  85665. + (colorspaceofpixel(vout->disp_fmt) == RGB_CS)))
  85666. + ) {
  85667. + /* IC bypass */
  85668. + output->format = IPU_PIX_FMT_NV12;
  85669. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85670. + "tiled bypass pp\n");
  85671. + vout->tiled_bypass_pp = true;
  85672. + }
  85673. + tiled_fmt = true;
  85674. + }
  85675. +
  85676. + if ((!vout->tiled_bypass_pp) && tiled_fmt)
  85677. + ret = vdoaipu_try_task(vout);
  85678. + else
  85679. + ret = ipu_try_task(vout);
  85680. + }
  85681. +
  85682. + if (vout->vdoa_1080p) {
  85683. + output->height = o_height;
  85684. + output->crop.h = ocrop_h;
  85685. + }
  85686. +
  85687. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85688. + "icrop.w:%u, icrop.h:%u, iw:%u, ih:%u,"
  85689. + "ocrop.w:%u, ocrop.h:%u, ow:%u, oh:%u\n",
  85690. + input->crop.w, input->crop.h,
  85691. + input->width, input->height,
  85692. + output->crop.w, output->crop.h,
  85693. + output->width, output->height);
  85694. + return ret;
  85695. +}
  85696. +
  85697. +static int mxc_vout_try_format(struct mxc_vout_output *vout,
  85698. + struct v4l2_format *f)
  85699. +{
  85700. + int ret = 0;
  85701. + struct v4l2_rect rect;
  85702. +
  85703. + if ((f->fmt.pix.field != V4L2_FIELD_NONE) &&
  85704. + (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format)) {
  85705. + v4l2_err(vout->vfd->v4l2_dev,
  85706. + "progressive tiled fmt should used V4L2_FIELD_NONE!\n");
  85707. + return -EINVAL;
  85708. + }
  85709. +
  85710. + if (f->fmt.pix.priv && copy_from_user(&rect,
  85711. + (void __user *)f->fmt.pix.priv, sizeof(rect)))
  85712. + return -EFAULT;
  85713. +
  85714. + vout->task.input.width = f->fmt.pix.width;
  85715. + vout->task.input.height = f->fmt.pix.height;
  85716. + vout->task.input.format = f->fmt.pix.pixelformat;
  85717. +
  85718. + ret = set_field_fmt(vout, f->fmt.pix.field);
  85719. + if (ret < 0)
  85720. + return ret;
  85721. +
  85722. + if (f->fmt.pix.priv) {
  85723. + vout->task.input.crop.pos.x = rect.left;
  85724. + vout->task.input.crop.pos.y = rect.top;
  85725. + vout->task.input.crop.w = rect.width;
  85726. + vout->task.input.crop.h = rect.height;
  85727. + } else {
  85728. + vout->task.input.crop.pos.x = 0;
  85729. + vout->task.input.crop.pos.y = 0;
  85730. + vout->task.input.crop.w = f->fmt.pix.width;
  85731. + vout->task.input.crop.h = f->fmt.pix.height;
  85732. + }
  85733. + memcpy(&vout->in_rect, &vout->task.input.crop, sizeof(vout->in_rect));
  85734. +
  85735. + ret = mxc_vout_try_task(vout);
  85736. + if (!ret) {
  85737. + if (f->fmt.pix.priv) {
  85738. + rect.width = vout->task.input.crop.w;
  85739. + rect.height = vout->task.input.crop.h;
  85740. + if (copy_to_user((void __user *)f->fmt.pix.priv,
  85741. + &rect, sizeof(rect)))
  85742. + ret = -EFAULT;
  85743. + } else {
  85744. + f->fmt.pix.width = vout->task.input.crop.w;
  85745. + f->fmt.pix.height = vout->task.input.crop.h;
  85746. + }
  85747. + }
  85748. +
  85749. + return ret;
  85750. +}
  85751. +
  85752. +static bool mxc_vout_need_fb_reconfig(struct mxc_vout_output *vout,
  85753. + struct mxc_vout_output *pre_vout)
  85754. +{
  85755. + if (!vout->vbq.streaming)
  85756. + return false;
  85757. +
  85758. + if (vout->tiled_bypass_pp)
  85759. + return true;
  85760. +
  85761. + if (vout->linear_bypass_pp != pre_vout->linear_bypass_pp)
  85762. + return true;
  85763. +
  85764. + /* cropped output resolution or format are changed */
  85765. + if (vout->task.output.format != pre_vout->task.output.format ||
  85766. + vout->task.output.crop.w != pre_vout->task.output.crop.w ||
  85767. + vout->task.output.crop.h != pre_vout->task.output.crop.h)
  85768. + return true;
  85769. +
  85770. + /* overlay: window position or resolution are changed */
  85771. + if (vout->disp_support_windows &&
  85772. + (vout->win_pos.x != pre_vout->win_pos.x ||
  85773. + vout->win_pos.y != pre_vout->win_pos.y ||
  85774. + vout->task.output.width != pre_vout->task.output.width ||
  85775. + vout->task.output.height != pre_vout->task.output.height))
  85776. + return true;
  85777. +
  85778. + /* background: cropped position is changed */
  85779. + if (!vout->disp_support_windows &&
  85780. + (vout->task.output.crop.pos.x !=
  85781. + pre_vout->task.output.crop.pos.x ||
  85782. + vout->task.output.crop.pos.y !=
  85783. + pre_vout->task.output.crop.pos.y))
  85784. + return true;
  85785. +
  85786. + return false;
  85787. +}
  85788. +
  85789. +static int mxc_vidioc_s_fmt_vid_out(struct file *file, void *fh,
  85790. + struct v4l2_format *f)
  85791. +{
  85792. + struct mxc_vout_output *vout = fh;
  85793. + int ret = 0;
  85794. +
  85795. + if (vout->vbq.streaming)
  85796. + return -EBUSY;
  85797. +
  85798. + mutex_lock(&vout->task_lock);
  85799. + ret = mxc_vout_try_format(vout, f);
  85800. + if (ret >= 0)
  85801. + vout->fmt_init = true;
  85802. + mutex_unlock(&vout->task_lock);
  85803. +
  85804. + return ret;
  85805. +}
  85806. +
  85807. +static int mxc_vidioc_cropcap(struct file *file, void *fh,
  85808. + struct v4l2_cropcap *cropcap)
  85809. +{
  85810. + struct mxc_vout_output *vout = fh;
  85811. +
  85812. + if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  85813. + return -EINVAL;
  85814. +
  85815. + cropcap->bounds = vout->crop_bounds;
  85816. + cropcap->defrect = vout->crop_bounds;
  85817. +
  85818. + return 0;
  85819. +}
  85820. +
  85821. +static int mxc_vidioc_g_crop(struct file *file, void *fh,
  85822. + struct v4l2_crop *crop)
  85823. +{
  85824. + struct mxc_vout_output *vout = fh;
  85825. +
  85826. + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  85827. + return -EINVAL;
  85828. +
  85829. + if (vout->disp_support_windows) {
  85830. + crop->c.left = vout->win_pos.x;
  85831. + crop->c.top = vout->win_pos.y;
  85832. + crop->c.width = vout->task.output.width;
  85833. + crop->c.height = vout->task.output.height;
  85834. + } else {
  85835. + if (vout->task.output.crop.w && vout->task.output.crop.h) {
  85836. + crop->c.left = vout->task.output.crop.pos.x;
  85837. + crop->c.top = vout->task.output.crop.pos.y;
  85838. + crop->c.width = vout->task.output.crop.w;
  85839. + crop->c.height = vout->task.output.crop.h;
  85840. + } else {
  85841. + crop->c.left = 0;
  85842. + crop->c.top = 0;
  85843. + crop->c.width = vout->task.output.width;
  85844. + crop->c.height = vout->task.output.height;
  85845. + }
  85846. + }
  85847. +
  85848. + return 0;
  85849. +}
  85850. +
  85851. +static int mxc_vidioc_s_crop(struct file *file, void *fh,
  85852. + const struct v4l2_crop *crop)
  85853. +{
  85854. + struct mxc_vout_output *vout = fh, *pre_vout;
  85855. + struct v4l2_rect *b = &vout->crop_bounds;
  85856. + struct v4l2_crop fix_up_crop;
  85857. + int ret = 0;
  85858. +
  85859. + memcpy(&fix_up_crop, crop, sizeof(*crop));
  85860. +
  85861. + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  85862. + return -EINVAL;
  85863. +
  85864. + if (crop->c.width < 0 || crop->c.height < 0)
  85865. + return -EINVAL;
  85866. +
  85867. + if (crop->c.width == 0)
  85868. + fix_up_crop.c.width = b->width - b->left;
  85869. + if (crop->c.height == 0)
  85870. + fix_up_crop.c.height = b->height - b->top;
  85871. +
  85872. + if (crop->c.top < b->top)
  85873. + fix_up_crop.c.top = b->top;
  85874. + if (crop->c.top >= b->top + b->height)
  85875. + fix_up_crop.c.top = b->top + b->height - 1;
  85876. + if (crop->c.height > b->top - crop->c.top + b->height)
  85877. + fix_up_crop.c.height =
  85878. + b->top - fix_up_crop.c.top + b->height;
  85879. +
  85880. + if (crop->c.left < b->left)
  85881. + fix_up_crop.c.left = b->left;
  85882. + if (crop->c.left >= b->left + b->width)
  85883. + fix_up_crop.c.left = b->left + b->width - 1;
  85884. + if (crop->c.width > b->left - crop->c.left + b->width)
  85885. + fix_up_crop.c.width =
  85886. + b->left - fix_up_crop.c.left + b->width;
  85887. +
  85888. + /* stride line limitation */
  85889. + fix_up_crop.c.height -= fix_up_crop.c.height % 8;
  85890. + fix_up_crop.c.width -= fix_up_crop.c.width % 8;
  85891. + if ((fix_up_crop.c.width <= 0) || (fix_up_crop.c.height <= 0) ||
  85892. + ((fix_up_crop.c.left + fix_up_crop.c.width) >
  85893. + (b->left + b->width)) ||
  85894. + ((fix_up_crop.c.top + fix_up_crop.c.height) >
  85895. + (b->top + b->height))) {
  85896. + v4l2_err(vout->vfd->v4l2_dev, "s_crop err: %d, %d, %d, %d",
  85897. + fix_up_crop.c.left, fix_up_crop.c.top,
  85898. + fix_up_crop.c.width, fix_up_crop.c.height);
  85899. + return -EINVAL;
  85900. + }
  85901. +
  85902. + /* the same setting, return */
  85903. + if (vout->disp_support_windows) {
  85904. + if ((vout->win_pos.x == fix_up_crop.c.left) &&
  85905. + (vout->win_pos.y == fix_up_crop.c.top) &&
  85906. + (vout->task.output.crop.w == fix_up_crop.c.width) &&
  85907. + (vout->task.output.crop.h == fix_up_crop.c.height))
  85908. + return 0;
  85909. + } else {
  85910. + if ((vout->task.output.crop.pos.x == fix_up_crop.c.left) &&
  85911. + (vout->task.output.crop.pos.y == fix_up_crop.c.top) &&
  85912. + (vout->task.output.crop.w == fix_up_crop.c.width) &&
  85913. + (vout->task.output.crop.h == fix_up_crop.c.height))
  85914. + return 0;
  85915. + }
  85916. +
  85917. + pre_vout = vmalloc(sizeof(*pre_vout));
  85918. + if (!pre_vout)
  85919. + return -ENOMEM;
  85920. +
  85921. + /* wait current work finish */
  85922. + if (vout->vbq.streaming)
  85923. + flush_workqueue(vout->v4l_wq);
  85924. +
  85925. + mutex_lock(&vout->task_lock);
  85926. +
  85927. + memcpy(pre_vout, vout, sizeof(*vout));
  85928. +
  85929. + if (vout->disp_support_windows) {
  85930. + vout->task.output.crop.pos.x = 0;
  85931. + vout->task.output.crop.pos.y = 0;
  85932. + vout->win_pos.x = fix_up_crop.c.left;
  85933. + vout->win_pos.y = fix_up_crop.c.top;
  85934. + vout->task.output.width = fix_up_crop.c.width;
  85935. + vout->task.output.height = fix_up_crop.c.height;
  85936. + } else {
  85937. + vout->task.output.crop.pos.x = fix_up_crop.c.left;
  85938. + vout->task.output.crop.pos.y = fix_up_crop.c.top;
  85939. + }
  85940. +
  85941. + vout->task.output.crop.w = fix_up_crop.c.width;
  85942. + vout->task.output.crop.h = fix_up_crop.c.height;
  85943. +
  85944. + /*
  85945. + * must S_CROP before S_FMT, for fist time S_CROP, will not check
  85946. + * ipu task, it will check in S_FMT, after S_FMT, S_CROP should
  85947. + * check ipu task too.
  85948. + */
  85949. + if (vout->fmt_init) {
  85950. + memcpy(&vout->task.input.crop, &vout->in_rect,
  85951. + sizeof(vout->in_rect));
  85952. + ret = mxc_vout_try_task(vout);
  85953. + if (ret < 0) {
  85954. + v4l2_err(vout->vfd->v4l2_dev,
  85955. + "vout check task failed\n");
  85956. + memcpy(vout, pre_vout, sizeof(*vout));
  85957. + goto done;
  85958. + }
  85959. +
  85960. + if (mxc_vout_need_fb_reconfig(vout, pre_vout)) {
  85961. + ret = config_disp_output(vout);
  85962. + if (ret < 0)
  85963. + v4l2_err(vout->vfd->v4l2_dev,
  85964. + "Config display output failed\n");
  85965. + }
  85966. + }
  85967. +
  85968. +done:
  85969. + vfree(pre_vout);
  85970. + mutex_unlock(&vout->task_lock);
  85971. +
  85972. + return ret;
  85973. +}
  85974. +
  85975. +static int mxc_vidioc_queryctrl(struct file *file, void *fh,
  85976. + struct v4l2_queryctrl *ctrl)
  85977. +{
  85978. + int ret = 0;
  85979. +
  85980. + switch (ctrl->id) {
  85981. + case V4L2_CID_ROTATE:
  85982. + ret = v4l2_ctrl_query_fill(ctrl, 0, 270, 90, 0);
  85983. + break;
  85984. + case V4L2_CID_VFLIP:
  85985. + ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
  85986. + break;
  85987. + case V4L2_CID_HFLIP:
  85988. + ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
  85989. + break;
  85990. + case V4L2_CID_MXC_MOTION:
  85991. + ret = v4l2_ctrl_query_fill(ctrl, 0, 2, 1, 0);
  85992. + break;
  85993. + default:
  85994. + ctrl->name[0] = '\0';
  85995. + ret = -EINVAL;
  85996. + }
  85997. + return ret;
  85998. +}
  85999. +
  86000. +static int mxc_vidioc_g_ctrl(struct file *file, void *fh,
  86001. + struct v4l2_control *ctrl)
  86002. +{
  86003. + int ret = 0;
  86004. + struct mxc_vout_output *vout = fh;
  86005. +
  86006. + switch (ctrl->id) {
  86007. + case V4L2_CID_ROTATE:
  86008. + ctrl->value = vout->ctrl_rotate;
  86009. + break;
  86010. + case V4L2_CID_VFLIP:
  86011. + ctrl->value = vout->ctrl_vflip;
  86012. + break;
  86013. + case V4L2_CID_HFLIP:
  86014. + ctrl->value = vout->ctrl_hflip;
  86015. + break;
  86016. + case V4L2_CID_MXC_MOTION:
  86017. + if (vout->task.input.deinterlace.enable)
  86018. + ctrl->value = vout->task.input.deinterlace.motion;
  86019. + else
  86020. + ctrl->value = 0;
  86021. + break;
  86022. + default:
  86023. + ret = -EINVAL;
  86024. + }
  86025. + return ret;
  86026. +}
  86027. +
  86028. +static void setup_task_rotation(struct mxc_vout_output *vout)
  86029. +{
  86030. + if (vout->ctrl_rotate == 0) {
  86031. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  86032. + vout->task.output.rotate = IPU_ROTATE_180;
  86033. + else if (vout->ctrl_vflip)
  86034. + vout->task.output.rotate = IPU_ROTATE_VERT_FLIP;
  86035. + else if (vout->ctrl_hflip)
  86036. + vout->task.output.rotate = IPU_ROTATE_HORIZ_FLIP;
  86037. + else
  86038. + vout->task.output.rotate = IPU_ROTATE_NONE;
  86039. + } else if (vout->ctrl_rotate == 90) {
  86040. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  86041. + vout->task.output.rotate = IPU_ROTATE_90_LEFT;
  86042. + else if (vout->ctrl_vflip)
  86043. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_VFLIP;
  86044. + else if (vout->ctrl_hflip)
  86045. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_HFLIP;
  86046. + else
  86047. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT;
  86048. + } else if (vout->ctrl_rotate == 180) {
  86049. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  86050. + vout->task.output.rotate = IPU_ROTATE_NONE;
  86051. + else if (vout->ctrl_vflip)
  86052. + vout->task.output.rotate = IPU_ROTATE_HORIZ_FLIP;
  86053. + else if (vout->ctrl_hflip)
  86054. + vout->task.output.rotate = IPU_ROTATE_VERT_FLIP;
  86055. + else
  86056. + vout->task.output.rotate = IPU_ROTATE_180;
  86057. + } else if (vout->ctrl_rotate == 270) {
  86058. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  86059. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT;
  86060. + else if (vout->ctrl_vflip)
  86061. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_HFLIP;
  86062. + else if (vout->ctrl_hflip)
  86063. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_VFLIP;
  86064. + else
  86065. + vout->task.output.rotate = IPU_ROTATE_90_LEFT;
  86066. + }
  86067. +}
  86068. +
  86069. +static int mxc_vidioc_s_ctrl(struct file *file, void *fh,
  86070. + struct v4l2_control *ctrl)
  86071. +{
  86072. + int ret = 0;
  86073. + struct mxc_vout_output *vout = fh, *pre_vout;
  86074. +
  86075. + pre_vout = vmalloc(sizeof(*pre_vout));
  86076. + if (!pre_vout)
  86077. + return -ENOMEM;
  86078. +
  86079. + /* wait current work finish */
  86080. + if (vout->vbq.streaming)
  86081. + flush_workqueue(vout->v4l_wq);
  86082. +
  86083. + mutex_lock(&vout->task_lock);
  86084. +
  86085. + memcpy(pre_vout, vout, sizeof(*vout));
  86086. +
  86087. + switch (ctrl->id) {
  86088. + case V4L2_CID_ROTATE:
  86089. + {
  86090. + vout->ctrl_rotate = (ctrl->value/90) * 90;
  86091. + if (vout->ctrl_rotate > 270)
  86092. + vout->ctrl_rotate = 270;
  86093. + setup_task_rotation(vout);
  86094. + break;
  86095. + }
  86096. + case V4L2_CID_VFLIP:
  86097. + {
  86098. + vout->ctrl_vflip = ctrl->value;
  86099. + setup_task_rotation(vout);
  86100. + break;
  86101. + }
  86102. + case V4L2_CID_HFLIP:
  86103. + {
  86104. + vout->ctrl_hflip = ctrl->value;
  86105. + setup_task_rotation(vout);
  86106. + break;
  86107. + }
  86108. + case V4L2_CID_MXC_MOTION:
  86109. + {
  86110. + vout->task.input.deinterlace.motion = ctrl->value;
  86111. + break;
  86112. + }
  86113. + default:
  86114. + ret = -EINVAL;
  86115. + goto done;
  86116. + }
  86117. +
  86118. + if (vout->fmt_init) {
  86119. + memcpy(&vout->task.input.crop, &vout->in_rect,
  86120. + sizeof(vout->in_rect));
  86121. + ret = mxc_vout_try_task(vout);
  86122. + if (ret < 0) {
  86123. + v4l2_err(vout->vfd->v4l2_dev,
  86124. + "vout check task failed\n");
  86125. + memcpy(vout, pre_vout, sizeof(*vout));
  86126. + goto done;
  86127. + }
  86128. +
  86129. + if (mxc_vout_need_fb_reconfig(vout, pre_vout)) {
  86130. + ret = config_disp_output(vout);
  86131. + if (ret < 0)
  86132. + v4l2_err(vout->vfd->v4l2_dev,
  86133. + "Config display output failed\n");
  86134. + }
  86135. + }
  86136. +
  86137. +done:
  86138. + vfree(pre_vout);
  86139. + mutex_unlock(&vout->task_lock);
  86140. +
  86141. + return ret;
  86142. +}
  86143. +
  86144. +static int mxc_vidioc_reqbufs(struct file *file, void *fh,
  86145. + struct v4l2_requestbuffers *req)
  86146. +{
  86147. + int ret = 0;
  86148. + struct mxc_vout_output *vout = fh;
  86149. + struct videobuf_queue *q = &vout->vbq;
  86150. +
  86151. + if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  86152. + return -EINVAL;
  86153. +
  86154. + /* should not be here after streaming, videobuf_reqbufs will control */
  86155. + mutex_lock(&vout->task_lock);
  86156. +
  86157. + ret = videobuf_reqbufs(q, req);
  86158. +
  86159. + mutex_unlock(&vout->task_lock);
  86160. + return ret;
  86161. +}
  86162. +
  86163. +static int mxc_vidioc_querybuf(struct file *file, void *fh,
  86164. + struct v4l2_buffer *b)
  86165. +{
  86166. + int ret;
  86167. + struct mxc_vout_output *vout = fh;
  86168. +
  86169. + ret = videobuf_querybuf(&vout->vbq, b);
  86170. + if (!ret) {
  86171. + /* return physical address */
  86172. + struct videobuf_buffer *vb = vout->vbq.bufs[b->index];
  86173. + if (b->flags & V4L2_BUF_FLAG_MAPPED)
  86174. + b->m.offset = videobuf_to_dma_contig(vb);
  86175. + }
  86176. +
  86177. + return ret;
  86178. +}
  86179. +
  86180. +static int mxc_vidioc_qbuf(struct file *file, void *fh,
  86181. + struct v4l2_buffer *buffer)
  86182. +{
  86183. + struct mxc_vout_output *vout = fh;
  86184. +
  86185. + return videobuf_qbuf(&vout->vbq, buffer);
  86186. +}
  86187. +
  86188. +static int mxc_vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
  86189. +{
  86190. + struct mxc_vout_output *vout = fh;
  86191. +
  86192. + if (!vout->vbq.streaming)
  86193. + return -EINVAL;
  86194. +
  86195. + if (file->f_flags & O_NONBLOCK)
  86196. + return videobuf_dqbuf(&vout->vbq, (struct v4l2_buffer *)b, 1);
  86197. + else
  86198. + return videobuf_dqbuf(&vout->vbq, (struct v4l2_buffer *)b, 0);
  86199. +}
  86200. +
  86201. +static int set_window_position(struct mxc_vout_output *vout,
  86202. + struct mxcfb_pos *pos)
  86203. +{
  86204. + struct fb_info *fbi = vout->fbi;
  86205. + mm_segment_t old_fs;
  86206. + int ret = 0;
  86207. +
  86208. + if (vout->disp_support_windows) {
  86209. + old_fs = get_fs();
  86210. + set_fs(KERNEL_DS);
  86211. + ret = fbi->fbops->fb_ioctl(fbi, MXCFB_SET_OVERLAY_POS,
  86212. + (unsigned long)pos);
  86213. + set_fs(old_fs);
  86214. + }
  86215. +
  86216. + return ret;
  86217. +}
  86218. +
  86219. +static int config_disp_output(struct mxc_vout_output *vout)
  86220. +{
  86221. + struct dma_mem *buf = NULL;
  86222. + struct fb_info *fbi = vout->fbi;
  86223. + struct fb_var_screeninfo var;
  86224. + struct mxcfb_pos pos;
  86225. + int i, fb_num, ret;
  86226. + u32 fb_base;
  86227. + u32 size;
  86228. + u32 display_buf_size;
  86229. + u32 *pixel = NULL;
  86230. + u32 color;
  86231. + int j;
  86232. +
  86233. + memcpy(&var, &fbi->var, sizeof(var));
  86234. + fb_base = fbi->fix.smem_start;
  86235. +
  86236. + var.xres = vout->task.output.width;
  86237. + var.yres = vout->task.output.height;
  86238. + if (vout->linear_bypass_pp || vout->tiled_bypass_pp) {
  86239. + fb_num = 1;
  86240. + /* input crop */
  86241. + if (vout->task.input.width > vout->task.output.width)
  86242. + var.xres_virtual = vout->task.input.width;
  86243. + else
  86244. + var.xres_virtual = var.xres;
  86245. + if (vout->task.input.height > vout->task.output.height)
  86246. + var.yres_virtual = vout->task.input.height;
  86247. + else
  86248. + var.yres_virtual = var.yres;
  86249. + var.rotate = vout->task.output.rotate;
  86250. + var.vmode |= FB_VMODE_YWRAP;
  86251. + } else {
  86252. + fb_num = FB_BUFS;
  86253. + var.xres_virtual = var.xres;
  86254. + var.yres_virtual = fb_num * var.yres;
  86255. + var.vmode &= ~FB_VMODE_YWRAP;
  86256. + }
  86257. + var.bits_per_pixel = fmt_to_bpp(vout->task.output.format);
  86258. + var.nonstd = vout->task.output.format;
  86259. +
  86260. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  86261. + "set display fb to %d %d\n",
  86262. + var.xres, var.yres);
  86263. +
  86264. + /*
  86265. + * To setup the overlay fb from scratch without
  86266. + * the last time overlay fb position or resolution's
  86267. + * impact, we take the following steps:
  86268. + * - blank fb
  86269. + * - set fb position to the starting point
  86270. + * - reconfigure fb
  86271. + * - set fb position to a specific point
  86272. + * - unblank fb
  86273. + * This procedure applies to non-overlay fbs as well.
  86274. + */
  86275. + console_lock();
  86276. + fbi->flags |= FBINFO_MISC_USEREVENT;
  86277. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  86278. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  86279. + console_unlock();
  86280. +
  86281. + pos.x = 0;
  86282. + pos.y = 0;
  86283. + ret = set_window_position(vout, &pos);
  86284. + if (ret < 0) {
  86285. + v4l2_err(vout->vfd->v4l2_dev, "failed to set fb position "
  86286. + "to starting point\n");
  86287. + return ret;
  86288. + }
  86289. +
  86290. + /* Init display channel through fb API */
  86291. + var.yoffset = 0;
  86292. + var.activate |= FB_ACTIVATE_FORCE;
  86293. + console_lock();
  86294. + fbi->flags |= FBINFO_MISC_USEREVENT;
  86295. + ret = fb_set_var(fbi, &var);
  86296. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  86297. + console_unlock();
  86298. + if (ret < 0) {
  86299. + v4l2_err(vout->vfd->v4l2_dev,
  86300. + "ERR:%s fb_set_var ret:%d\n", __func__, ret);
  86301. + return ret;
  86302. + }
  86303. +
  86304. + ret = set_window_position(vout, &vout->win_pos);
  86305. + if (ret < 0) {
  86306. + v4l2_err(vout->vfd->v4l2_dev, "failed to set fb position\n");
  86307. + return ret;
  86308. + }
  86309. +
  86310. + if (vout->linear_bypass_pp || vout->tiled_bypass_pp)
  86311. + display_buf_size = fbi->fix.line_length * fbi->var.yres_virtual;
  86312. + else
  86313. + display_buf_size = fbi->fix.line_length * fbi->var.yres;
  86314. + for (i = 0; i < fb_num; i++)
  86315. + vout->disp_bufs[i] = fbi->fix.smem_start + i * display_buf_size;
  86316. + if (vout->tiled_bypass_pp) {
  86317. + size = PAGE_ALIGN(vout->task.input.crop.w *
  86318. + vout->task.input.crop.h *
  86319. + fmt_to_bpp(vout->task.output.format)/8);
  86320. + if (size > vout->vdoa_output[0].size) {
  86321. + for (i = 0; i < VDOA_FB_BUFS; i++) {
  86322. + buf = &vout->vdoa_output[i];
  86323. + if (buf->vaddr)
  86324. + free_dma_buf(vout, buf);
  86325. + buf->size = size;
  86326. + ret = alloc_dma_buf(vout, buf);
  86327. + if (ret < 0)
  86328. + goto err;
  86329. + }
  86330. + }
  86331. + for (i = fb_num; i < (fb_num + VDOA_FB_BUFS); i++)
  86332. + vout->disp_bufs[i] =
  86333. + vout->vdoa_output[i - fb_num].paddr;
  86334. + }
  86335. + vout->fb_smem_len = fbi->fix.smem_len;
  86336. + vout->fb_smem_start = fbi->fix.smem_start;
  86337. + if (fb_base != fbi->fix.smem_start) {
  86338. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  86339. + "realloc fb mem size:0x%x@0x%lx,old paddr @0x%x\n",
  86340. + fbi->fix.smem_len, fbi->fix.smem_start, fb_base);
  86341. + }
  86342. +
  86343. + /* fill black when video config changed */
  86344. + color = colorspaceofpixel(vout->task.output.format) == YUV_CS ?
  86345. + UYVY_BLACK : RGB_BLACK;
  86346. + if (IS_PLANAR_PIXEL_FORMAT(vout->task.output.format)) {
  86347. + size = display_buf_size * 8 /
  86348. + fmt_to_bpp(vout->task.output.format);
  86349. + memset(fbi->screen_base, Y_BLACK, size);
  86350. + memset(fbi->screen_base + size, UV_BLACK,
  86351. + display_buf_size - size);
  86352. + } else {
  86353. + pixel = (u32 *)fbi->screen_base;
  86354. + for (i = 0; i < (display_buf_size >> 2); i++)
  86355. + *pixel++ = color;
  86356. + }
  86357. + console_lock();
  86358. + fbi->flags |= FBINFO_MISC_USEREVENT;
  86359. + ret = fb_blank(fbi, FB_BLANK_UNBLANK);
  86360. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  86361. + console_unlock();
  86362. + vout->release = false;
  86363. +
  86364. + return ret;
  86365. +err:
  86366. + for (j = i - 1; j >= 0; j--) {
  86367. + buf = &vout->vdoa_output[j];
  86368. + if (buf->vaddr)
  86369. + free_dma_buf(vout, buf);
  86370. + }
  86371. + return ret;
  86372. +}
  86373. +
  86374. +static inline void wait_for_vsync(struct mxc_vout_output *vout)
  86375. +{
  86376. + struct fb_info *fbi = vout->fbi;
  86377. + mm_segment_t old_fs;
  86378. +
  86379. + if (fbi->fbops->fb_ioctl) {
  86380. + old_fs = get_fs();
  86381. + set_fs(KERNEL_DS);
  86382. + fbi->fbops->fb_ioctl(fbi, MXCFB_WAIT_FOR_VSYNC,
  86383. + (unsigned long)NULL);
  86384. + set_fs(old_fs);
  86385. + }
  86386. +
  86387. + return;
  86388. +}
  86389. +
  86390. +static void release_disp_output(struct mxc_vout_output *vout)
  86391. +{
  86392. + struct fb_info *fbi = vout->fbi;
  86393. + struct mxcfb_pos pos;
  86394. +
  86395. + if (vout->release)
  86396. + return;
  86397. + console_lock();
  86398. + fbi->flags |= FBINFO_MISC_USEREVENT;
  86399. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  86400. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  86401. + console_unlock();
  86402. +
  86403. + /* restore pos to 0,0 avoid fb pan display hang? */
  86404. + pos.x = 0;
  86405. + pos.y = 0;
  86406. + set_window_position(vout, &pos);
  86407. +
  86408. + if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
  86409. + console_lock();
  86410. + fbi->fix.smem_start = vout->disp_bufs[0];
  86411. + fbi->flags |= FBINFO_MISC_USEREVENT;
  86412. + fb_blank(fbi, FB_BLANK_UNBLANK);
  86413. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  86414. + console_unlock();
  86415. +
  86416. + }
  86417. +
  86418. + vout->release = true;
  86419. +}
  86420. +
  86421. +static int mxc_vidioc_streamon(struct file *file, void *fh,
  86422. + enum v4l2_buf_type i)
  86423. +{
  86424. + struct mxc_vout_output *vout = fh;
  86425. + struct videobuf_queue *q = &vout->vbq;
  86426. + int ret;
  86427. +
  86428. + if (q->streaming) {
  86429. + v4l2_err(vout->vfd->v4l2_dev,
  86430. + "video output already run\n");
  86431. + ret = -EBUSY;
  86432. + goto done;
  86433. + }
  86434. +
  86435. + if (deinterlace_3_field(vout) && list_is_singular(&q->stream)) {
  86436. + v4l2_err(vout->vfd->v4l2_dev,
  86437. + "deinterlacing: need queue 2 frame before streamon\n");
  86438. + ret = -EINVAL;
  86439. + goto done;
  86440. + }
  86441. +
  86442. + ret = config_disp_output(vout);
  86443. + if (ret < 0) {
  86444. + v4l2_err(vout->vfd->v4l2_dev,
  86445. + "Config display output failed\n");
  86446. + goto done;
  86447. + }
  86448. +
  86449. + hrtimer_init(&vout->timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
  86450. + vout->timer.function = mxc_vout_timer_handler;
  86451. + vout->timer_stop = true;
  86452. +
  86453. + vout->start_ktime = hrtimer_cb_get_time(&vout->timer);
  86454. +
  86455. + vout->pre1_vb = NULL;
  86456. + vout->pre2_vb = NULL;
  86457. +
  86458. + ret = videobuf_streamon(q);
  86459. +done:
  86460. + return ret;
  86461. +}
  86462. +
  86463. +static int mxc_vidioc_streamoff(struct file *file, void *fh,
  86464. + enum v4l2_buf_type i)
  86465. +{
  86466. + struct mxc_vout_output *vout = fh;
  86467. + struct videobuf_queue *q = &vout->vbq;
  86468. + int ret = 0;
  86469. +
  86470. + if (q->streaming) {
  86471. + flush_workqueue(vout->v4l_wq);
  86472. +
  86473. + hrtimer_cancel(&vout->timer);
  86474. +
  86475. + /*
  86476. + * Wait for 2 vsyncs to make sure
  86477. + * frames are drained on triple
  86478. + * buffer.
  86479. + */
  86480. + wait_for_vsync(vout);
  86481. + wait_for_vsync(vout);
  86482. +
  86483. + release_disp_output(vout);
  86484. +
  86485. + ret = videobuf_streamoff(&vout->vbq);
  86486. + }
  86487. + INIT_LIST_HEAD(&vout->queue_list);
  86488. + INIT_LIST_HEAD(&vout->active_list);
  86489. +
  86490. + return ret;
  86491. +}
  86492. +
  86493. +static const struct v4l2_ioctl_ops mxc_vout_ioctl_ops = {
  86494. + .vidioc_querycap = mxc_vidioc_querycap,
  86495. + .vidioc_enum_fmt_vid_out = mxc_vidioc_enum_fmt_vid_out,
  86496. + .vidioc_g_fmt_vid_out = mxc_vidioc_g_fmt_vid_out,
  86497. + .vidioc_s_fmt_vid_out = mxc_vidioc_s_fmt_vid_out,
  86498. + .vidioc_cropcap = mxc_vidioc_cropcap,
  86499. + .vidioc_g_crop = mxc_vidioc_g_crop,
  86500. + .vidioc_s_crop = mxc_vidioc_s_crop,
  86501. + .vidioc_queryctrl = mxc_vidioc_queryctrl,
  86502. + .vidioc_g_ctrl = mxc_vidioc_g_ctrl,
  86503. + .vidioc_s_ctrl = mxc_vidioc_s_ctrl,
  86504. + .vidioc_reqbufs = mxc_vidioc_reqbufs,
  86505. + .vidioc_querybuf = mxc_vidioc_querybuf,
  86506. + .vidioc_qbuf = mxc_vidioc_qbuf,
  86507. + .vidioc_dqbuf = mxc_vidioc_dqbuf,
  86508. + .vidioc_streamon = mxc_vidioc_streamon,
  86509. + .vidioc_streamoff = mxc_vidioc_streamoff,
  86510. +};
  86511. +
  86512. +static const struct v4l2_file_operations mxc_vout_fops = {
  86513. + .owner = THIS_MODULE,
  86514. + .unlocked_ioctl = video_ioctl2,
  86515. + .mmap = mxc_vout_mmap,
  86516. + .open = mxc_vout_open,
  86517. + .release = mxc_vout_release,
  86518. +};
  86519. +
  86520. +static struct video_device mxc_vout_template = {
  86521. + .name = "MXC Video Output",
  86522. + .fops = &mxc_vout_fops,
  86523. + .ioctl_ops = &mxc_vout_ioctl_ops,
  86524. + .release = video_device_release,
  86525. +};
  86526. +
  86527. +static struct videobuf_queue_ops mxc_vout_vbq_ops = {
  86528. + .buf_setup = mxc_vout_buffer_setup,
  86529. + .buf_prepare = mxc_vout_buffer_prepare,
  86530. + .buf_release = mxc_vout_buffer_release,
  86531. + .buf_queue = mxc_vout_buffer_queue,
  86532. +};
  86533. +
  86534. +static void mxc_vout_free_output(struct mxc_vout_dev *dev)
  86535. +{
  86536. + int i;
  86537. + int j;
  86538. + struct mxc_vout_output *vout;
  86539. + struct video_device *vfd;
  86540. +
  86541. + for (i = 0; i < dev->out_num; i++) {
  86542. + vout = dev->out[i];
  86543. + vfd = vout->vfd;
  86544. + if (vout->vdoa_work.vaddr)
  86545. + free_dma_buf(vout, &vout->vdoa_work);
  86546. + for (j = 0; j < VDOA_FB_BUFS; j++) {
  86547. + if (vout->vdoa_output[j].vaddr)
  86548. + free_dma_buf(vout, &vout->vdoa_output[j]);
  86549. + }
  86550. + if (vfd) {
  86551. + if (!video_is_registered(vfd))
  86552. + video_device_release(vfd);
  86553. + else
  86554. + video_unregister_device(vfd);
  86555. + }
  86556. + kfree(vout);
  86557. + }
  86558. +}
  86559. +
  86560. +static int mxc_vout_setup_output(struct mxc_vout_dev *dev)
  86561. +{
  86562. + struct videobuf_queue *q;
  86563. + struct fb_info *fbi;
  86564. + struct mxc_vout_output *vout;
  86565. + int i, ret = 0;
  86566. +
  86567. + update_display_setting();
  86568. +
  86569. + /* all output/overlay based on fb */
  86570. + for (i = 0; i < num_registered_fb; i++) {
  86571. + fbi = registered_fb[i];
  86572. +
  86573. + vout = kzalloc(sizeof(struct mxc_vout_output), GFP_KERNEL);
  86574. + if (!vout) {
  86575. + ret = -ENOMEM;
  86576. + break;
  86577. + }
  86578. +
  86579. + dev->out[dev->out_num] = vout;
  86580. + dev->out_num++;
  86581. +
  86582. + vout->fbi = fbi;
  86583. + vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  86584. + vout->vfd = video_device_alloc();
  86585. + if (!vout->vfd) {
  86586. + ret = -ENOMEM;
  86587. + break;
  86588. + }
  86589. +
  86590. + *vout->vfd = mxc_vout_template;
  86591. + vout->vfd->debug = debug;
  86592. + vout->vfd->v4l2_dev = &dev->v4l2_dev;
  86593. + vout->vfd->lock = &vout->mutex;
  86594. + vout->vfd->vfl_dir = VFL_DIR_TX;
  86595. +
  86596. + mutex_init(&vout->mutex);
  86597. + mutex_init(&vout->task_lock);
  86598. +
  86599. + strlcpy(vout->vfd->name, fbi->fix.id, sizeof(vout->vfd->name));
  86600. +
  86601. + video_set_drvdata(vout->vfd, vout);
  86602. +
  86603. + if (video_register_device(vout->vfd,
  86604. + VFL_TYPE_GRABBER, video_nr + i) < 0) {
  86605. + ret = -ENODEV;
  86606. + break;
  86607. + }
  86608. +
  86609. + q = &vout->vbq;
  86610. + q->dev = dev->dev;
  86611. + spin_lock_init(&vout->vbq_lock);
  86612. + videobuf_queue_dma_contig_init(q, &mxc_vout_vbq_ops, q->dev,
  86613. + &vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
  86614. + sizeof(struct videobuf_buffer), vout, NULL);
  86615. +
  86616. + v4l2_info(vout->vfd->v4l2_dev, "V4L2 device registered as %s\n",
  86617. + video_device_node_name(vout->vfd));
  86618. +
  86619. + }
  86620. +
  86621. + return ret;
  86622. +}
  86623. +
  86624. +static int mxc_vout_probe(struct platform_device *pdev)
  86625. +{
  86626. + int ret;
  86627. + struct mxc_vout_dev *dev;
  86628. +
  86629. + dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  86630. + if (!dev)
  86631. + return -ENOMEM;
  86632. +
  86633. + dev->dev = &pdev->dev;
  86634. + dev->dev->dma_mask = kmalloc(sizeof(*dev->dev->dma_mask), GFP_KERNEL);
  86635. + *dev->dev->dma_mask = DMA_BIT_MASK(32);
  86636. + dev->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  86637. +
  86638. + ret = v4l2_device_register(dev->dev, &dev->v4l2_dev);
  86639. + if (ret) {
  86640. + dev_err(dev->dev, "v4l2_device_register failed\n");
  86641. + goto free_dev;
  86642. + }
  86643. +
  86644. + ret = mxc_vout_setup_output(dev);
  86645. + if (ret < 0)
  86646. + goto rel_vdev;
  86647. +
  86648. + return 0;
  86649. +
  86650. +rel_vdev:
  86651. + mxc_vout_free_output(dev);
  86652. + v4l2_device_unregister(&dev->v4l2_dev);
  86653. +free_dev:
  86654. + kfree(dev);
  86655. + return ret;
  86656. +}
  86657. +
  86658. +static int mxc_vout_remove(struct platform_device *pdev)
  86659. +{
  86660. + struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
  86661. + struct mxc_vout_dev *dev = container_of(v4l2_dev, struct
  86662. + mxc_vout_dev, v4l2_dev);
  86663. +
  86664. + mxc_vout_free_output(dev);
  86665. + v4l2_device_unregister(v4l2_dev);
  86666. + kfree(dev);
  86667. + return 0;
  86668. +}
  86669. +
  86670. +static const struct of_device_id mxc_v4l2_dt_ids[] = {
  86671. + { .compatible = "fsl,mxc_v4l2_output", },
  86672. + { /* sentinel */ }
  86673. +};
  86674. +
  86675. +static struct platform_driver mxc_vout_driver = {
  86676. + .driver = {
  86677. + .name = "mxc_v4l2_output",
  86678. + .of_match_table = mxc_v4l2_dt_ids,
  86679. + },
  86680. + .probe = mxc_vout_probe,
  86681. + .remove = mxc_vout_remove,
  86682. +};
  86683. +
  86684. +static int __init mxc_vout_init(void)
  86685. +{
  86686. + if (platform_driver_register(&mxc_vout_driver) != 0) {
  86687. + printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
  86688. + return -EINVAL;
  86689. + }
  86690. + return 0;
  86691. +}
  86692. +
  86693. +static void mxc_vout_cleanup(void)
  86694. +{
  86695. + platform_driver_unregister(&mxc_vout_driver);
  86696. +}
  86697. +
  86698. +module_init(mxc_vout_init);
  86699. +module_exit(mxc_vout_cleanup);
  86700. +
  86701. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  86702. +MODULE_DESCRIPTION("V4L2-driver for MXC video output");
  86703. +MODULE_LICENSE("GPL");
  86704. diff -Nur linux-3.14.15/drivers/media/usb/hdpvr/hdpvr-video.c linux-linaro-stable-mx6/drivers/media/usb/hdpvr/hdpvr-video.c
  86705. --- linux-3.14.15/drivers/media/usb/hdpvr/hdpvr-video.c 2014-07-31 23:51:43.000000000 +0200
  86706. +++ linux-linaro-stable-mx6/drivers/media/usb/hdpvr/hdpvr-video.c 2014-08-20 19:31:45.624866842 +0200
  86707. @@ -82,7 +82,7 @@
  86708. }
  86709. /*=========================================================================*/
  86710. -/* buffer bits */
  86711. +/* bufffer bits */
  86712. /* function expects dev->io_mutex to be hold by caller */
  86713. int hdpvr_cancel_queue(struct hdpvr_device *dev)
  86714. @@ -926,7 +926,7 @@
  86715. case V4L2_CID_MPEG_AUDIO_ENCODING:
  86716. if (dev->flags & HDPVR_FLAG_AC3_CAP) {
  86717. opt->audio_codec = ctrl->val;
  86718. - return hdpvr_set_audio(dev, opt->audio_input + 1,
  86719. + return hdpvr_set_audio(dev, opt->audio_input,
  86720. opt->audio_codec);
  86721. }
  86722. return 0;
  86723. @@ -1198,7 +1198,7 @@
  86724. v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
  86725. V4L2_CID_MPEG_AUDIO_ENCODING,
  86726. ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : V4L2_MPEG_AUDIO_ENCODING_AAC,
  86727. - 0x7, ac3 ? dev->options.audio_codec : V4L2_MPEG_AUDIO_ENCODING_AAC);
  86728. + 0x7, V4L2_MPEG_AUDIO_ENCODING_AAC);
  86729. v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
  86730. V4L2_CID_MPEG_VIDEO_ENCODING,
  86731. V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 0x3,
  86732. diff -Nur linux-3.14.15/drivers/media/v4l2-core/v4l2-dv-timings.c linux-linaro-stable-mx6/drivers/media/v4l2-core/v4l2-dv-timings.c
  86733. --- linux-3.14.15/drivers/media/v4l2-core/v4l2-dv-timings.c 2014-07-31 23:51:43.000000000 +0200
  86734. +++ linux-linaro-stable-mx6/drivers/media/v4l2-core/v4l2-dv-timings.c 2014-08-20 19:31:45.708867204 +0200
  86735. @@ -595,10 +595,10 @@
  86736. aspect.denominator = 9;
  86737. } else if (ratio == 34) {
  86738. aspect.numerator = 4;
  86739. - aspect.denominator = 3;
  86740. + aspect.numerator = 3;
  86741. } else if (ratio == 68) {
  86742. aspect.numerator = 15;
  86743. - aspect.denominator = 9;
  86744. + aspect.numerator = 9;
  86745. } else {
  86746. aspect.numerator = hor_landscape + 99;
  86747. aspect.denominator = 100;
  86748. diff -Nur linux-3.14.15/drivers/media/v4l2-core/videobuf2-dma-contig.c linux-linaro-stable-mx6/drivers/media/v4l2-core/videobuf2-dma-contig.c
  86749. --- linux-3.14.15/drivers/media/v4l2-core/videobuf2-dma-contig.c 2014-07-31 23:51:43.000000000 +0200
  86750. +++ linux-linaro-stable-mx6/drivers/media/v4l2-core/videobuf2-dma-contig.c 2014-08-20 19:31:45.708867204 +0200
  86751. @@ -719,7 +719,7 @@
  86752. /* get the associated scatterlist for this buffer */
  86753. sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
  86754. - if (IS_ERR_OR_NULL(sgt)) {
  86755. + if (IS_ERR(sgt)) {
  86756. pr_err("Error getting dmabuf scatterlist\n");
  86757. return -EINVAL;
  86758. }
  86759. diff -Nur linux-3.14.15/drivers/media/v4l2-core/videobuf-dma-contig.c linux-linaro-stable-mx6/drivers/media/v4l2-core/videobuf-dma-contig.c
  86760. --- linux-3.14.15/drivers/media/v4l2-core/videobuf-dma-contig.c 2014-07-31 23:51:43.000000000 +0200
  86761. +++ linux-linaro-stable-mx6/drivers/media/v4l2-core/videobuf-dma-contig.c 2014-08-20 19:31:45.708867204 +0200
  86762. @@ -304,7 +304,7 @@
  86763. /* Try to remap memory */
  86764. size = vma->vm_end - vma->vm_start;
  86765. - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  86766. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  86767. retval = vm_iomap_memory(vma, vma->vm_start, size);
  86768. if (retval) {
  86769. dev_err(q->dev, "mmap: remap failed with error %d. ",
  86770. diff -Nur linux-3.14.15/drivers/mfd/ab8500-core.c linux-linaro-stable-mx6/drivers/mfd/ab8500-core.c
  86771. --- linux-3.14.15/drivers/mfd/ab8500-core.c 2014-07-31 23:51:43.000000000 +0200
  86772. +++ linux-linaro-stable-mx6/drivers/mfd/ab8500-core.c 2014-08-20 19:31:45.720867254 +0200
  86773. @@ -592,7 +592,7 @@
  86774. /* If ->irq_base is zero this will give a linear mapping */
  86775. ab8500->domain = irq_domain_add_simple(NULL,
  86776. - num_irqs, ab8500->irq_base,
  86777. + num_irqs, 0,
  86778. &ab8500_irq_ops, ab8500);
  86779. if (!ab8500->domain) {
  86780. @@ -1583,14 +1583,13 @@
  86781. if (!ab8500)
  86782. return -ENOMEM;
  86783. - if (plat)
  86784. - ab8500->irq_base = plat->irq_base;
  86785. -
  86786. ab8500->dev = &pdev->dev;
  86787. resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  86788. - if (!resource)
  86789. + if (!resource) {
  86790. + dev_err(&pdev->dev, "no IRQ resource\n");
  86791. return -ENODEV;
  86792. + }
  86793. ab8500->irq = resource->start;
  86794. @@ -1612,8 +1611,10 @@
  86795. else {
  86796. ret = get_register_interruptible(ab8500, AB8500_MISC,
  86797. AB8500_IC_NAME_REG, &value);
  86798. - if (ret < 0)
  86799. + if (ret < 0) {
  86800. + dev_err(&pdev->dev, "could not probe HW\n");
  86801. return ret;
  86802. + }
  86803. ab8500->version = value;
  86804. }
  86805. @@ -1759,30 +1760,30 @@
  86806. if (is_ab9540(ab8500))
  86807. ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
  86808. ARRAY_SIZE(ab9540_devs), NULL,
  86809. - ab8500->irq_base, ab8500->domain);
  86810. + 0, ab8500->domain);
  86811. else if (is_ab8540(ab8500)) {
  86812. ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs,
  86813. ARRAY_SIZE(ab8540_devs), NULL,
  86814. - ab8500->irq_base, NULL);
  86815. + 0, ab8500->domain);
  86816. if (ret)
  86817. return ret;
  86818. if (is_ab8540_1p2_or_earlier(ab8500))
  86819. ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut1_devs,
  86820. ARRAY_SIZE(ab8540_cut1_devs), NULL,
  86821. - ab8500->irq_base, NULL);
  86822. + 0, ab8500->domain);
  86823. else /* ab8540 >= cut2 */
  86824. ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut2_devs,
  86825. ARRAY_SIZE(ab8540_cut2_devs), NULL,
  86826. - ab8500->irq_base, NULL);
  86827. + 0, ab8500->domain);
  86828. } else if (is_ab8505(ab8500))
  86829. ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs,
  86830. ARRAY_SIZE(ab8505_devs), NULL,
  86831. - ab8500->irq_base, ab8500->domain);
  86832. + 0, ab8500->domain);
  86833. else
  86834. ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
  86835. ARRAY_SIZE(ab8500_devs), NULL,
  86836. - ab8500->irq_base, ab8500->domain);
  86837. + 0, ab8500->domain);
  86838. if (ret)
  86839. return ret;
  86840. @@ -1790,7 +1791,7 @@
  86841. /* Add battery management devices */
  86842. ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,
  86843. ARRAY_SIZE(ab8500_bm_devs), NULL,
  86844. - ab8500->irq_base, ab8500->domain);
  86845. + 0, ab8500->domain);
  86846. if (ret)
  86847. dev_err(ab8500->dev, "error adding bm devices\n");
  86848. }
  86849. diff -Nur linux-3.14.15/drivers/mfd/db8500-prcmu.c linux-linaro-stable-mx6/drivers/mfd/db8500-prcmu.c
  86850. --- linux-3.14.15/drivers/mfd/db8500-prcmu.c 2014-07-31 23:51:43.000000000 +0200
  86851. +++ linux-linaro-stable-mx6/drivers/mfd/db8500-prcmu.c 2014-08-20 19:31:45.728867289 +0200
  86852. @@ -25,6 +25,7 @@
  86853. #include <linux/bitops.h>
  86854. #include <linux/fs.h>
  86855. #include <linux/of.h>
  86856. +#include <linux/of_irq.h>
  86857. #include <linux/platform_device.h>
  86858. #include <linux/uaccess.h>
  86859. #include <linux/mfd/core.h>
  86860. @@ -2678,16 +2679,12 @@
  86861. .xlate = irq_domain_xlate_twocell,
  86862. };
  86863. -static int db8500_irq_init(struct device_node *np, int irq_base)
  86864. +static int db8500_irq_init(struct device_node *np)
  86865. {
  86866. int i;
  86867. - /* In the device tree case, just take some IRQs */
  86868. - if (np)
  86869. - irq_base = 0;
  86870. -
  86871. db8500_irq_domain = irq_domain_add_simple(
  86872. - np, NUM_PRCMU_WAKEUPS, irq_base,
  86873. + np, NUM_PRCMU_WAKEUPS, 0,
  86874. &db8500_irq_ops, NULL);
  86875. if (!db8500_irq_domain) {
  86876. @@ -3114,10 +3111,10 @@
  86877. }
  86878. static int db8500_prcmu_register_ab8500(struct device *parent,
  86879. - struct ab8500_platform_data *pdata,
  86880. - int irq)
  86881. + struct ab8500_platform_data *pdata)
  86882. {
  86883. - struct resource ab8500_resource = DEFINE_RES_IRQ(irq);
  86884. + struct device_node *np;
  86885. + struct resource ab8500_resource;
  86886. struct mfd_cell ab8500_cell = {
  86887. .name = "ab8500-core",
  86888. .of_compatible = "stericsson,ab8500",
  86889. @@ -3128,6 +3125,20 @@
  86890. .num_resources = 1,
  86891. };
  86892. + if (!parent->of_node)
  86893. + return -ENODEV;
  86894. +
  86895. + /* Look up the device node, sneak the IRQ out of it */
  86896. + for_each_child_of_node(parent->of_node, np) {
  86897. + if (of_device_is_compatible(np, ab8500_cell.of_compatible))
  86898. + break;
  86899. + }
  86900. + if (!np) {
  86901. + dev_info(parent, "could not find AB8500 node in the device tree\n");
  86902. + return -ENODEV;
  86903. + }
  86904. + of_irq_to_resource_table(np, &ab8500_resource, 1);
  86905. +
  86906. return mfd_add_devices(parent, 0, &ab8500_cell, 1, NULL, 0, NULL);
  86907. }
  86908. @@ -3180,7 +3191,7 @@
  86909. goto no_irq_return;
  86910. }
  86911. - db8500_irq_init(np, pdata->irq_base);
  86912. + db8500_irq_init(np);
  86913. prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
  86914. @@ -3205,8 +3216,7 @@
  86915. }
  86916. }
  86917. - err = db8500_prcmu_register_ab8500(&pdev->dev, pdata->ab_platdata,
  86918. - pdata->ab_irq);
  86919. + err = db8500_prcmu_register_ab8500(&pdev->dev, pdata->ab_platdata);
  86920. if (err) {
  86921. mfd_remove_devices(&pdev->dev);
  86922. pr_err("prcmu: Failed to add ab8500 subdevice\n");
  86923. diff -Nur linux-3.14.15/drivers/mfd/Kconfig linux-linaro-stable-mx6/drivers/mfd/Kconfig
  86924. --- linux-3.14.15/drivers/mfd/Kconfig 2014-07-31 23:51:43.000000000 +0200
  86925. +++ linux-linaro-stable-mx6/drivers/mfd/Kconfig 2014-08-20 19:31:45.720867254 +0200
  86926. @@ -163,6 +163,14 @@
  86927. Additional drivers must be enabled in order to use the functionality
  86928. of the device.
  86929. +config MFD_MXC_HDMI
  86930. + tristate "Freescale HDMI Core"
  86931. + select MFD_CORE
  86932. + help
  86933. + This is the core driver for the Freescale i.MX6 on-chip HDMI.
  86934. + This MFD driver connects with the video and audio drivers for HDMI.
  86935. +
  86936. +
  86937. config MFD_MC13XXX
  86938. tristate
  86939. depends on (SPI_MASTER || I2C)
  86940. @@ -1226,3 +1234,4 @@
  86941. help
  86942. Platform configuration infrastructure for the ARM Ltd.
  86943. Versatile Express.
  86944. +
  86945. diff -Nur linux-3.14.15/drivers/mfd/Makefile linux-linaro-stable-mx6/drivers/mfd/Makefile
  86946. --- linux-3.14.15/drivers/mfd/Makefile 2014-07-31 23:51:43.000000000 +0200
  86947. +++ linux-linaro-stable-mx6/drivers/mfd/Makefile 2014-08-20 19:31:45.720867254 +0200
  86948. @@ -166,3 +166,4 @@
  86949. obj-$(CONFIG_MFD_AS3711) += as3711.o
  86950. obj-$(CONFIG_MFD_AS3722) += as3722.o
  86951. obj-$(CONFIG_MFD_STW481X) += stw481x.o
  86952. +obj-$(CONFIG_MFD_MXC_HDMI) += mxc-hdmi-core.o
  86953. diff -Nur linux-3.14.15/drivers/mfd/mxc-hdmi-core.c linux-linaro-stable-mx6/drivers/mfd/mxc-hdmi-core.c
  86954. --- linux-3.14.15/drivers/mfd/mxc-hdmi-core.c 1970-01-01 01:00:00.000000000 +0100
  86955. +++ linux-linaro-stable-mx6/drivers/mfd/mxc-hdmi-core.c 2014-08-20 19:31:45.760867426 +0200
  86956. @@ -0,0 +1,784 @@
  86957. +/*
  86958. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
  86959. + *
  86960. + * This program is free software; you can redistribute it and/or modify
  86961. + * it under the terms of the GNU General Public License as published by
  86962. + * the Free Software Foundation; either version 2 of the License, or
  86963. + * (at your option) any later version.
  86964. + *
  86965. + * This program is distributed in the hope that it will be useful,
  86966. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  86967. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  86968. + * GNU General Public License for more details.
  86969. + *
  86970. + * You should have received a copy of the GNU General Public License
  86971. + * along with this program; if not, write to the Free Software
  86972. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  86973. + *
  86974. + */
  86975. +#include <linux/kernel.h>
  86976. +#include <linux/module.h>
  86977. +#include <linux/init.h>
  86978. +#include <linux/slab.h>
  86979. +#include <linux/device.h>
  86980. +#include <linux/err.h>
  86981. +#include <linux/io.h>
  86982. +#include <linux/clk.h>
  86983. +#include <linux/spinlock.h>
  86984. +#include <linux/irq.h>
  86985. +#include <linux/interrupt.h>
  86986. +
  86987. +#include <linux/platform_device.h>
  86988. +#include <linux/regulator/machine.h>
  86989. +#include <asm/mach-types.h>
  86990. +
  86991. +#include <video/mxc_hdmi.h>
  86992. +#include <linux/ipu-v3.h>
  86993. +#include <video/mxc_edid.h>
  86994. +#include "../mxc/ipu3/ipu_prv.h"
  86995. +#include <linux/mfd/mxc-hdmi-core.h>
  86996. +#include <linux/of_device.h>
  86997. +#include <linux/mod_devicetable.h>
  86998. +#include <linux/mfd/mxc-hdmi-core.h>
  86999. +
  87000. +struct mxc_hdmi_data {
  87001. + struct platform_device *pdev;
  87002. + unsigned long __iomem *reg_base;
  87003. + unsigned long reg_phys_base;
  87004. + struct device *dev;
  87005. +};
  87006. +
  87007. +static void __iomem *hdmi_base;
  87008. +static struct clk *isfr_clk;
  87009. +static struct clk *iahb_clk;
  87010. +static spinlock_t irq_spinlock;
  87011. +static spinlock_t edid_spinlock;
  87012. +static unsigned int sample_rate;
  87013. +static unsigned long pixel_clk_rate;
  87014. +static struct clk *pixel_clk;
  87015. +static int hdmi_ratio;
  87016. +int mxc_hdmi_ipu_id;
  87017. +int mxc_hdmi_disp_id;
  87018. +static struct mxc_edid_cfg hdmi_core_edid_cfg;
  87019. +static int hdmi_core_init;
  87020. +static unsigned int hdmi_dma_running;
  87021. +static struct snd_pcm_substream *hdmi_audio_stream_playback;
  87022. +static unsigned int hdmi_cable_state;
  87023. +static unsigned int hdmi_blank_state;
  87024. +static unsigned int hdmi_abort_state;
  87025. +static spinlock_t hdmi_audio_lock, hdmi_blank_state_lock, hdmi_cable_state_lock;
  87026. +
  87027. +unsigned int hdmi_set_cable_state(unsigned int state)
  87028. +{
  87029. + unsigned long flags;
  87030. + struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
  87031. +
  87032. + spin_lock_irqsave(&hdmi_cable_state_lock, flags);
  87033. + hdmi_cable_state = state;
  87034. + spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
  87035. +
  87036. + if (check_hdmi_state() && substream && hdmi_abort_state) {
  87037. + hdmi_abort_state = 0;
  87038. + substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
  87039. + }
  87040. + return 0;
  87041. +}
  87042. +EXPORT_SYMBOL(hdmi_set_cable_state);
  87043. +
  87044. +unsigned int hdmi_set_blank_state(unsigned int state)
  87045. +{
  87046. + unsigned long flags;
  87047. + struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
  87048. +
  87049. + spin_lock_irqsave(&hdmi_blank_state_lock, flags);
  87050. + hdmi_blank_state = state;
  87051. + spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
  87052. +
  87053. + if (check_hdmi_state() && substream && hdmi_abort_state) {
  87054. + hdmi_abort_state = 0;
  87055. + substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
  87056. + }
  87057. + return 0;
  87058. +}
  87059. +EXPORT_SYMBOL(hdmi_set_blank_state);
  87060. +
  87061. +static void hdmi_audio_abort_stream(struct snd_pcm_substream *substream)
  87062. +{
  87063. + unsigned long flags;
  87064. +
  87065. + snd_pcm_stream_lock_irqsave(substream, flags);
  87066. +
  87067. + if (snd_pcm_running(substream)) {
  87068. + hdmi_abort_state = 1;
  87069. + substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
  87070. + }
  87071. +
  87072. + snd_pcm_stream_unlock_irqrestore(substream, flags);
  87073. +}
  87074. +
  87075. +int mxc_hdmi_abort_stream(void)
  87076. +{
  87077. + unsigned long flags;
  87078. + spin_lock_irqsave(&hdmi_audio_lock, flags);
  87079. + if (hdmi_audio_stream_playback)
  87080. + hdmi_audio_abort_stream(hdmi_audio_stream_playback);
  87081. + spin_unlock_irqrestore(&hdmi_audio_lock, flags);
  87082. +
  87083. + return 0;
  87084. +}
  87085. +EXPORT_SYMBOL(mxc_hdmi_abort_stream);
  87086. +
  87087. +int check_hdmi_state(void)
  87088. +{
  87089. + unsigned long flags1, flags2;
  87090. + unsigned int ret;
  87091. +
  87092. + spin_lock_irqsave(&hdmi_cable_state_lock, flags1);
  87093. + spin_lock_irqsave(&hdmi_blank_state_lock, flags2);
  87094. +
  87095. + ret = hdmi_cable_state && hdmi_blank_state;
  87096. +
  87097. + spin_unlock_irqrestore(&hdmi_blank_state_lock, flags2);
  87098. + spin_unlock_irqrestore(&hdmi_cable_state_lock, flags1);
  87099. +
  87100. + return ret;
  87101. +}
  87102. +EXPORT_SYMBOL(check_hdmi_state);
  87103. +
  87104. +int mxc_hdmi_register_audio(struct snd_pcm_substream *substream)
  87105. +{
  87106. + unsigned long flags, flags1;
  87107. + int ret = 0;
  87108. +
  87109. + snd_pcm_stream_lock_irqsave(substream, flags);
  87110. +
  87111. + if (substream && check_hdmi_state()) {
  87112. + spin_lock_irqsave(&hdmi_audio_lock, flags1);
  87113. + if (hdmi_audio_stream_playback) {
  87114. + pr_err("%s unconsist hdmi auido stream!\n", __func__);
  87115. + ret = -EINVAL;
  87116. + }
  87117. + hdmi_audio_stream_playback = substream;
  87118. + hdmi_abort_state = 0;
  87119. + spin_unlock_irqrestore(&hdmi_audio_lock, flags1);
  87120. + } else
  87121. + ret = -EINVAL;
  87122. +
  87123. + snd_pcm_stream_unlock_irqrestore(substream, flags);
  87124. +
  87125. + return ret;
  87126. +}
  87127. +EXPORT_SYMBOL(mxc_hdmi_register_audio);
  87128. +
  87129. +void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream)
  87130. +{
  87131. + unsigned long flags;
  87132. +
  87133. + spin_lock_irqsave(&hdmi_audio_lock, flags);
  87134. + hdmi_audio_stream_playback = NULL;
  87135. + hdmi_abort_state = 0;
  87136. + spin_unlock_irqrestore(&hdmi_audio_lock, flags);
  87137. +}
  87138. +EXPORT_SYMBOL(mxc_hdmi_unregister_audio);
  87139. +
  87140. +u8 hdmi_readb(unsigned int reg)
  87141. +{
  87142. + u8 value;
  87143. +
  87144. + value = __raw_readb(hdmi_base + reg);
  87145. +
  87146. + return value;
  87147. +}
  87148. +EXPORT_SYMBOL(hdmi_readb);
  87149. +
  87150. +#ifdef DEBUG
  87151. +static bool overflow_lo;
  87152. +static bool overflow_hi;
  87153. +
  87154. +bool hdmi_check_overflow(void)
  87155. +{
  87156. + u8 val, lo, hi;
  87157. +
  87158. + val = hdmi_readb(HDMI_IH_FC_STAT2);
  87159. + lo = (val & HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW) != 0;
  87160. + hi = (val & HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW) != 0;
  87161. +
  87162. + if ((lo != overflow_lo) || (hi != overflow_hi)) {
  87163. + pr_debug("%s LowPriority=%d HighPriority=%d <=======================\n",
  87164. + __func__, lo, hi);
  87165. + overflow_lo = lo;
  87166. + overflow_hi = hi;
  87167. + return true;
  87168. + }
  87169. + return false;
  87170. +}
  87171. +#else
  87172. +bool hdmi_check_overflow(void)
  87173. +{
  87174. + return false;
  87175. +}
  87176. +#endif
  87177. +EXPORT_SYMBOL(hdmi_check_overflow);
  87178. +
  87179. +void hdmi_writeb(u8 value, unsigned int reg)
  87180. +{
  87181. + hdmi_check_overflow();
  87182. + __raw_writeb(value, hdmi_base + reg);
  87183. + hdmi_check_overflow();
  87184. +}
  87185. +EXPORT_SYMBOL(hdmi_writeb);
  87186. +
  87187. +void hdmi_mask_writeb(u8 data, unsigned int reg, u8 shift, u8 mask)
  87188. +{
  87189. + u8 value = hdmi_readb(reg) & ~mask;
  87190. + value |= (data << shift) & mask;
  87191. + hdmi_writeb(value, reg);
  87192. +}
  87193. +EXPORT_SYMBOL(hdmi_mask_writeb);
  87194. +
  87195. +unsigned int hdmi_read4(unsigned int reg)
  87196. +{
  87197. + /* read a four byte address from registers */
  87198. + return (hdmi_readb(reg + 3) << 24) |
  87199. + (hdmi_readb(reg + 2) << 16) |
  87200. + (hdmi_readb(reg + 1) << 8) |
  87201. + hdmi_readb(reg);
  87202. +}
  87203. +EXPORT_SYMBOL(hdmi_read4);
  87204. +
  87205. +void hdmi_write4(unsigned int value, unsigned int reg)
  87206. +{
  87207. + /* write a four byte address to hdmi regs */
  87208. + hdmi_writeb(value & 0xff, reg);
  87209. + hdmi_writeb((value >> 8) & 0xff, reg + 1);
  87210. + hdmi_writeb((value >> 16) & 0xff, reg + 2);
  87211. + hdmi_writeb((value >> 24) & 0xff, reg + 3);
  87212. +}
  87213. +EXPORT_SYMBOL(hdmi_write4);
  87214. +
  87215. +static void initialize_hdmi_ih_mutes(void)
  87216. +{
  87217. + u8 ih_mute;
  87218. +
  87219. + /*
  87220. + * Boot up defaults are:
  87221. + * HDMI_IH_MUTE = 0x03 (disabled)
  87222. + * HDMI_IH_MUTE_* = 0x00 (enabled)
  87223. + */
  87224. +
  87225. + /* Disable top level interrupt bits in HDMI block */
  87226. + ih_mute = hdmi_readb(HDMI_IH_MUTE) |
  87227. + HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
  87228. + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
  87229. +
  87230. + hdmi_writeb(ih_mute, HDMI_IH_MUTE);
  87231. +
  87232. + /* by default mask all interrupts */
  87233. + hdmi_writeb(0xff, HDMI_VP_MASK);
  87234. + hdmi_writeb(0xff, HDMI_FC_MASK0);
  87235. + hdmi_writeb(0xff, HDMI_FC_MASK1);
  87236. + hdmi_writeb(0xff, HDMI_FC_MASK2);
  87237. + hdmi_writeb(0xff, HDMI_PHY_MASK0);
  87238. + hdmi_writeb(0xff, HDMI_PHY_I2CM_INT_ADDR);
  87239. + hdmi_writeb(0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
  87240. + hdmi_writeb(0xff, HDMI_AUD_INT);
  87241. + hdmi_writeb(0xff, HDMI_AUD_SPDIFINT);
  87242. + hdmi_writeb(0xff, HDMI_AUD_HBR_MASK);
  87243. + hdmi_writeb(0xff, HDMI_GP_MASK);
  87244. + hdmi_writeb(0xff, HDMI_A_APIINTMSK);
  87245. + hdmi_writeb(0xff, HDMI_CEC_MASK);
  87246. + hdmi_writeb(0xff, HDMI_I2CM_INT);
  87247. + hdmi_writeb(0xff, HDMI_I2CM_CTLINT);
  87248. +
  87249. + /* Disable interrupts in the IH_MUTE_* registers */
  87250. + hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT0);
  87251. + hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT1);
  87252. + hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT2);
  87253. + hdmi_writeb(0xff, HDMI_IH_MUTE_AS_STAT0);
  87254. + hdmi_writeb(0xff, HDMI_IH_MUTE_PHY_STAT0);
  87255. + hdmi_writeb(0xff, HDMI_IH_MUTE_I2CM_STAT0);
  87256. + hdmi_writeb(0xff, HDMI_IH_MUTE_CEC_STAT0);
  87257. + hdmi_writeb(0xff, HDMI_IH_MUTE_VP_STAT0);
  87258. + hdmi_writeb(0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
  87259. + hdmi_writeb(0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  87260. +
  87261. + /* Enable top level interrupt bits in HDMI block */
  87262. + ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
  87263. + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT);
  87264. + hdmi_writeb(ih_mute, HDMI_IH_MUTE);
  87265. +}
  87266. +
  87267. +static void hdmi_set_clock_regenerator_n(unsigned int value)
  87268. +{
  87269. + u8 val;
  87270. +
  87271. + if (!hdmi_dma_running) {
  87272. + hdmi_writeb(value & 0xff, HDMI_AUD_N1);
  87273. + hdmi_writeb(0, HDMI_AUD_N2);
  87274. + hdmi_writeb(0, HDMI_AUD_N3);
  87275. + }
  87276. +
  87277. + hdmi_writeb(value & 0xff, HDMI_AUD_N1);
  87278. + hdmi_writeb((value >> 8) & 0xff, HDMI_AUD_N2);
  87279. + hdmi_writeb((value >> 16) & 0x0f, HDMI_AUD_N3);
  87280. +
  87281. + /* nshift factor = 0 */
  87282. + val = hdmi_readb(HDMI_AUD_CTS3);
  87283. + val &= ~HDMI_AUD_CTS3_N_SHIFT_MASK;
  87284. + hdmi_writeb(val, HDMI_AUD_CTS3);
  87285. +}
  87286. +
  87287. +static void hdmi_set_clock_regenerator_cts(unsigned int cts)
  87288. +{
  87289. + u8 val;
  87290. +
  87291. + if (!hdmi_dma_running) {
  87292. + hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
  87293. + hdmi_writeb(0, HDMI_AUD_CTS2);
  87294. + hdmi_writeb(0, HDMI_AUD_CTS3);
  87295. + }
  87296. +
  87297. + /* Must be set/cleared first */
  87298. + val = hdmi_readb(HDMI_AUD_CTS3);
  87299. + val &= ~HDMI_AUD_CTS3_CTS_MANUAL;
  87300. + hdmi_writeb(val, HDMI_AUD_CTS3);
  87301. +
  87302. + hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
  87303. + hdmi_writeb((cts >> 8) & 0xff, HDMI_AUD_CTS2);
  87304. + hdmi_writeb(((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
  87305. + HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
  87306. +}
  87307. +
  87308. +static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
  87309. + unsigned int ratio)
  87310. +{
  87311. + unsigned int n = (128 * freq) / 1000;
  87312. +
  87313. + switch (freq) {
  87314. + case 32000:
  87315. + if (pixel_clk == 25174000)
  87316. + n = (ratio == 150) ? 9152 : 4576;
  87317. + else if (pixel_clk == 27020000)
  87318. + n = (ratio == 150) ? 8192 : 4096;
  87319. + else if (pixel_clk == 74170000 || pixel_clk == 148350000)
  87320. + n = 11648;
  87321. + else if (pixel_clk == 297000000)
  87322. + n = (ratio == 150) ? 6144 : 3072;
  87323. + else
  87324. + n = 4096;
  87325. + break;
  87326. +
  87327. + case 44100:
  87328. + if (pixel_clk == 25174000)
  87329. + n = 7007;
  87330. + else if (pixel_clk == 74170000)
  87331. + n = 17836;
  87332. + else if (pixel_clk == 148350000)
  87333. + n = (ratio == 150) ? 17836 : 8918;
  87334. + else if (pixel_clk == 297000000)
  87335. + n = (ratio == 150) ? 9408 : 4704;
  87336. + else
  87337. + n = 6272;
  87338. + break;
  87339. +
  87340. + case 48000:
  87341. + if (pixel_clk == 25174000)
  87342. + n = (ratio == 150) ? 9152 : 6864;
  87343. + else if (pixel_clk == 27020000)
  87344. + n = (ratio == 150) ? 8192 : 6144;
  87345. + else if (pixel_clk == 74170000)
  87346. + n = 11648;
  87347. + else if (pixel_clk == 148350000)
  87348. + n = (ratio == 150) ? 11648 : 5824;
  87349. + else if (pixel_clk == 297000000)
  87350. + n = (ratio == 150) ? 10240 : 5120;
  87351. + else
  87352. + n = 6144;
  87353. + break;
  87354. +
  87355. + case 88200:
  87356. + n = hdmi_compute_n(44100, pixel_clk, ratio) * 2;
  87357. + break;
  87358. +
  87359. + case 96000:
  87360. + n = hdmi_compute_n(48000, pixel_clk, ratio) * 2;
  87361. + break;
  87362. +
  87363. + case 176400:
  87364. + n = hdmi_compute_n(44100, pixel_clk, ratio) * 4;
  87365. + break;
  87366. +
  87367. + case 192000:
  87368. + n = hdmi_compute_n(48000, pixel_clk, ratio) * 4;
  87369. + break;
  87370. +
  87371. + default:
  87372. + break;
  87373. + }
  87374. +
  87375. + return n;
  87376. +}
  87377. +
  87378. +static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
  87379. + unsigned int ratio)
  87380. +{
  87381. + unsigned int cts = 0;
  87382. + switch (freq) {
  87383. + case 32000:
  87384. + if (pixel_clk == 297000000) {
  87385. + cts = 222750;
  87386. + break;
  87387. + } else if (pixel_clk == 25174000) {
  87388. + cts = 28125;
  87389. + break;
  87390. + }
  87391. + case 48000:
  87392. + case 96000:
  87393. + case 192000:
  87394. + switch (pixel_clk) {
  87395. + case 25200000:
  87396. + case 27000000:
  87397. + case 54000000:
  87398. + case 74250000:
  87399. + case 148500000:
  87400. + cts = pixel_clk / 1000;
  87401. + break;
  87402. + case 297000000:
  87403. + cts = 247500;
  87404. + break;
  87405. + case 25174000:
  87406. + cts = 28125l;
  87407. + break;
  87408. + /*
  87409. + * All other TMDS clocks are not supported by
  87410. + * DWC_hdmi_tx. The TMDS clocks divided or
  87411. + * multiplied by 1,001 coefficients are not
  87412. + * supported.
  87413. + */
  87414. + default:
  87415. + break;
  87416. + }
  87417. + break;
  87418. + case 44100:
  87419. + case 88200:
  87420. + case 176400:
  87421. + switch (pixel_clk) {
  87422. + case 25200000:
  87423. + cts = 28000;
  87424. + break;
  87425. + case 25174000:
  87426. + cts = 31250;
  87427. + break;
  87428. + case 27000000:
  87429. + cts = 30000;
  87430. + break;
  87431. + case 54000000:
  87432. + cts = 60000;
  87433. + break;
  87434. + case 74250000:
  87435. + cts = 82500;
  87436. + break;
  87437. + case 148500000:
  87438. + cts = 165000;
  87439. + break;
  87440. + case 297000000:
  87441. + cts = 247500;
  87442. + break;
  87443. + default:
  87444. + break;
  87445. + }
  87446. + break;
  87447. + default:
  87448. + break;
  87449. + }
  87450. + if (ratio == 100)
  87451. + return cts;
  87452. + else
  87453. + return (cts * ratio) / 100;
  87454. +}
  87455. +
  87456. +static void hdmi_set_clk_regenerator(void)
  87457. +{
  87458. + unsigned int clk_n, clk_cts;
  87459. +
  87460. + clk_n = hdmi_compute_n(sample_rate, pixel_clk_rate, hdmi_ratio);
  87461. + clk_cts = hdmi_compute_cts(sample_rate, pixel_clk_rate, hdmi_ratio);
  87462. +
  87463. + if (clk_cts == 0) {
  87464. + pr_debug("%s: pixel clock not supported: %d\n",
  87465. + __func__, (int)pixel_clk_rate);
  87466. + return;
  87467. + }
  87468. +
  87469. + pr_debug("%s: samplerate=%d ratio=%d pixelclk=%d N=%d cts=%d\n",
  87470. + __func__, sample_rate, hdmi_ratio, (int)pixel_clk_rate,
  87471. + clk_n, clk_cts);
  87472. +
  87473. + hdmi_set_clock_regenerator_cts(clk_cts);
  87474. + hdmi_set_clock_regenerator_n(clk_n);
  87475. +}
  87476. +
  87477. +static int hdmi_core_get_of_property(struct platform_device *pdev)
  87478. +{
  87479. + struct device_node *np = pdev->dev.of_node;
  87480. + int err;
  87481. + int ipu_id, disp_id;
  87482. +
  87483. + err = of_property_read_u32(np, "ipu_id", &ipu_id);
  87484. + if (err) {
  87485. + dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
  87486. + return err;
  87487. + }
  87488. + err = of_property_read_u32(np, "disp_id", &disp_id);
  87489. + if (err) {
  87490. + dev_dbg(&pdev->dev, "get of property disp_id fail\n");
  87491. + return err;
  87492. + }
  87493. +
  87494. + mxc_hdmi_ipu_id = ipu_id;
  87495. + mxc_hdmi_disp_id = disp_id;
  87496. +
  87497. + return err;
  87498. +}
  87499. +
  87500. +/* Need to run this before phy is enabled the first time to prevent
  87501. + * overflow condition in HDMI_IH_FC_STAT2 */
  87502. +void hdmi_init_clk_regenerator(void)
  87503. +{
  87504. + if (pixel_clk_rate == 0) {
  87505. + pixel_clk_rate = 74250000;
  87506. + hdmi_set_clk_regenerator();
  87507. + }
  87508. +}
  87509. +EXPORT_SYMBOL(hdmi_init_clk_regenerator);
  87510. +
  87511. +void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock)
  87512. +{
  87513. +
  87514. + /* Translate pixel clock in ps (pico seconds) to Hz */
  87515. + pixel_clk_rate = PICOS2KHZ(pixclock) * 1000UL;
  87516. + hdmi_set_clk_regenerator();
  87517. +}
  87518. +EXPORT_SYMBOL(hdmi_clk_regenerator_update_pixel_clock);
  87519. +
  87520. +void hdmi_set_dma_mode(unsigned int dma_running)
  87521. +{
  87522. + hdmi_dma_running = dma_running;
  87523. + hdmi_set_clk_regenerator();
  87524. +}
  87525. +EXPORT_SYMBOL(hdmi_set_dma_mode);
  87526. +
  87527. +void hdmi_set_sample_rate(unsigned int rate)
  87528. +{
  87529. + sample_rate = rate;
  87530. +}
  87531. +EXPORT_SYMBOL(hdmi_set_sample_rate);
  87532. +
  87533. +void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg)
  87534. +{
  87535. + unsigned long flags;
  87536. +
  87537. + spin_lock_irqsave(&edid_spinlock, flags);
  87538. + memcpy(&hdmi_core_edid_cfg, cfg, sizeof(struct mxc_edid_cfg));
  87539. + spin_unlock_irqrestore(&edid_spinlock, flags);
  87540. +}
  87541. +EXPORT_SYMBOL(hdmi_set_edid_cfg);
  87542. +
  87543. +void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg)
  87544. +{
  87545. + unsigned long flags;
  87546. +
  87547. + spin_lock_irqsave(&edid_spinlock, flags);
  87548. + memcpy(cfg, &hdmi_core_edid_cfg, sizeof(struct mxc_edid_cfg));
  87549. + spin_unlock_irqrestore(&edid_spinlock, flags);
  87550. +}
  87551. +EXPORT_SYMBOL(hdmi_get_edid_cfg);
  87552. +
  87553. +void hdmi_set_registered(int registered)
  87554. +{
  87555. + hdmi_core_init = registered;
  87556. +}
  87557. +EXPORT_SYMBOL(hdmi_set_registered);
  87558. +
  87559. +int hdmi_get_registered(void)
  87560. +{
  87561. + return hdmi_core_init;
  87562. +}
  87563. +EXPORT_SYMBOL(hdmi_get_registered);
  87564. +
  87565. +static int mxc_hdmi_core_probe(struct platform_device *pdev)
  87566. +{
  87567. + struct mxc_hdmi_data *hdmi_data;
  87568. + struct resource *res;
  87569. + unsigned long flags;
  87570. + int ret = 0;
  87571. +
  87572. +#ifdef DEBUG
  87573. + overflow_lo = false;
  87574. + overflow_hi = false;
  87575. +#endif
  87576. +
  87577. + hdmi_core_init = 0;
  87578. + hdmi_dma_running = 0;
  87579. +
  87580. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  87581. + if (!res)
  87582. + return -ENOENT;
  87583. +
  87584. + ret = hdmi_core_get_of_property(pdev);
  87585. + if (ret < 0) {
  87586. + dev_err(&pdev->dev, "get hdmi of property fail\n");
  87587. + return -ENOENT;
  87588. + }
  87589. +
  87590. + hdmi_data = devm_kzalloc(&pdev->dev, sizeof(struct mxc_hdmi_data), GFP_KERNEL);
  87591. + if (!hdmi_data) {
  87592. + dev_err(&pdev->dev, "Couldn't allocate mxc hdmi mfd device\n");
  87593. + return -ENOMEM;
  87594. + }
  87595. + hdmi_data->pdev = pdev;
  87596. +
  87597. + pixel_clk = NULL;
  87598. + sample_rate = 48000;
  87599. + pixel_clk_rate = 0;
  87600. + hdmi_ratio = 100;
  87601. +
  87602. + spin_lock_init(&irq_spinlock);
  87603. + spin_lock_init(&edid_spinlock);
  87604. +
  87605. +
  87606. + spin_lock_init(&hdmi_cable_state_lock);
  87607. + spin_lock_init(&hdmi_blank_state_lock);
  87608. + spin_lock_init(&hdmi_audio_lock);
  87609. +
  87610. + spin_lock_irqsave(&hdmi_cable_state_lock, flags);
  87611. + hdmi_cable_state = 0;
  87612. + spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
  87613. +
  87614. + spin_lock_irqsave(&hdmi_blank_state_lock, flags);
  87615. + hdmi_blank_state = 0;
  87616. + spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
  87617. +
  87618. + spin_lock_irqsave(&hdmi_audio_lock, flags);
  87619. + hdmi_audio_stream_playback = NULL;
  87620. + hdmi_abort_state = 0;
  87621. + spin_unlock_irqrestore(&hdmi_audio_lock, flags);
  87622. +
  87623. + isfr_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_isfr");
  87624. + if (IS_ERR(isfr_clk)) {
  87625. + ret = PTR_ERR(isfr_clk);
  87626. + dev_err(&hdmi_data->pdev->dev,
  87627. + "Unable to get HDMI isfr clk: %d\n", ret);
  87628. + goto eclkg;
  87629. + }
  87630. +
  87631. + ret = clk_prepare_enable(isfr_clk);
  87632. + if (ret < 0) {
  87633. + dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret);
  87634. + goto eclke;
  87635. + }
  87636. +
  87637. + pr_debug("%s isfr_clk:%d\n", __func__,
  87638. + (int)clk_get_rate(isfr_clk));
  87639. +
  87640. + iahb_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_iahb");
  87641. + if (IS_ERR(iahb_clk)) {
  87642. + ret = PTR_ERR(iahb_clk);
  87643. + dev_err(&hdmi_data->pdev->dev,
  87644. + "Unable to get HDMI iahb clk: %d\n", ret);
  87645. + goto eclkg2;
  87646. + }
  87647. +
  87648. + ret = clk_prepare_enable(iahb_clk);
  87649. + if (ret < 0) {
  87650. + dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret);
  87651. + goto eclke2;
  87652. + }
  87653. +
  87654. + hdmi_data->reg_phys_base = res->start;
  87655. + if (!request_mem_region(res->start, resource_size(res),
  87656. + dev_name(&pdev->dev))) {
  87657. + dev_err(&pdev->dev, "request_mem_region failed\n");
  87658. + ret = -EBUSY;
  87659. + goto emem;
  87660. + }
  87661. +
  87662. + hdmi_data->reg_base = ioremap(res->start, resource_size(res));
  87663. + if (!hdmi_data->reg_base) {
  87664. + dev_err(&pdev->dev, "ioremap failed\n");
  87665. + ret = -ENOMEM;
  87666. + goto eirq;
  87667. + }
  87668. + hdmi_base = hdmi_data->reg_base;
  87669. +
  87670. + pr_debug("\n%s hdmi hw base = 0x%08x\n\n", __func__, (int)res->start);
  87671. +
  87672. + initialize_hdmi_ih_mutes();
  87673. +
  87674. + /* Disable HDMI clocks until video/audio sub-drivers are initialized */
  87675. + clk_disable_unprepare(isfr_clk);
  87676. + clk_disable_unprepare(iahb_clk);
  87677. +
  87678. + /* Replace platform data coming in with a local struct */
  87679. + platform_set_drvdata(pdev, hdmi_data);
  87680. +
  87681. + return ret;
  87682. +
  87683. +eirq:
  87684. + release_mem_region(res->start, resource_size(res));
  87685. +emem:
  87686. + clk_disable_unprepare(iahb_clk);
  87687. +eclke2:
  87688. + clk_put(iahb_clk);
  87689. +eclkg2:
  87690. + clk_disable_unprepare(isfr_clk);
  87691. +eclke:
  87692. + clk_put(isfr_clk);
  87693. +eclkg:
  87694. + return ret;
  87695. +}
  87696. +
  87697. +
  87698. +static int __exit mxc_hdmi_core_remove(struct platform_device *pdev)
  87699. +{
  87700. + struct mxc_hdmi_data *hdmi_data = platform_get_drvdata(pdev);
  87701. + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  87702. +
  87703. + iounmap(hdmi_data->reg_base);
  87704. + release_mem_region(res->start, resource_size(res));
  87705. +
  87706. + return 0;
  87707. +}
  87708. +
  87709. +static const struct of_device_id imx_hdmi_dt_ids[] = {
  87710. + { .compatible = "fsl,imx6q-hdmi-core", },
  87711. + { .compatible = "fsl,imx6dl-hdmi-core", },
  87712. + { /* sentinel */ }
  87713. +};
  87714. +
  87715. +static struct platform_driver mxc_hdmi_core_driver = {
  87716. + .driver = {
  87717. + .name = "mxc_hdmi_core",
  87718. + .of_match_table = imx_hdmi_dt_ids,
  87719. + .owner = THIS_MODULE,
  87720. + },
  87721. + .remove = __exit_p(mxc_hdmi_core_remove),
  87722. +};
  87723. +
  87724. +static int __init mxc_hdmi_core_init(void)
  87725. +{
  87726. + return platform_driver_probe(&mxc_hdmi_core_driver,
  87727. + mxc_hdmi_core_probe);
  87728. +}
  87729. +
  87730. +static void __exit mxc_hdmi_core_exit(void)
  87731. +{
  87732. + platform_driver_unregister(&mxc_hdmi_core_driver);
  87733. +}
  87734. +
  87735. +subsys_initcall(mxc_hdmi_core_init);
  87736. +module_exit(mxc_hdmi_core_exit);
  87737. +
  87738. +MODULE_DESCRIPTION("Core driver for Freescale i.Mx on-chip HDMI");
  87739. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  87740. +MODULE_LICENSE("GPL");
  87741. diff -Nur linux-3.14.15/drivers/mfd/si476x-cmd.c linux-linaro-stable-mx6/drivers/mfd/si476x-cmd.c
  87742. --- linux-3.14.15/drivers/mfd/si476x-cmd.c 2014-07-31 23:51:43.000000000 +0200
  87743. +++ linux-linaro-stable-mx6/drivers/mfd/si476x-cmd.c 2014-08-20 19:23:53.302844746 +0200
  87744. @@ -303,13 +303,13 @@
  87745. * possible racing conditions when working in polling mode */
  87746. atomic_set(&core->cts, 0);
  87747. - /* if (unlikely(command == CMD_POWER_DOWN) */
  87748. - if (!wait_event_timeout(core->command,
  87749. - atomic_read(&core->cts),
  87750. - usecs_to_jiffies(usecs) + 1))
  87751. - dev_warn(&core->client->dev,
  87752. - "(%s) [CMD 0x%02x] Answer timeout.\n",
  87753. - __func__, command);
  87754. + if (!(command == CMD_POWER_DOWN))
  87755. + if (!wait_event_timeout(core->command,
  87756. + atomic_read(&core->cts),
  87757. + usecs_to_jiffies(usecs) + 1))
  87758. + dev_warn(&core->client->dev,
  87759. + "(%s) [CMD 0x%02x] Answer timeout.\n",
  87760. + __func__, command);
  87761. /*
  87762. When working in polling mode, for some reason the tuner will
  87763. diff -Nur linux-3.14.15/drivers/mfd/si476x-i2c.c linux-linaro-stable-mx6/drivers/mfd/si476x-i2c.c
  87764. --- linux-3.14.15/drivers/mfd/si476x-i2c.c 2014-07-31 23:51:43.000000000 +0200
  87765. +++ linux-linaro-stable-mx6/drivers/mfd/si476x-i2c.c 2014-08-20 19:31:45.776867496 +0200
  87766. @@ -303,7 +303,7 @@
  87767. */
  87768. udelay(100);
  87769. - err = si476x_core_start(core, false);
  87770. + err = si476x_core_start(core, true);
  87771. if (err < 0)
  87772. goto disable_regulators;
  87773. @@ -312,7 +312,7 @@
  87774. case SI476X_POWER_DOWN:
  87775. core->power_state = next_state;
  87776. - err = si476x_core_stop(core, false);
  87777. + err = si476x_core_stop(core, true);
  87778. if (err < 0)
  87779. core->power_state = SI476X_POWER_INCONSISTENT;
  87780. disable_regulators:
  87781. @@ -740,8 +740,15 @@
  87782. memcpy(&core->pinmux, &pdata->pinmux,
  87783. sizeof(struct si476x_pinmux));
  87784. } else {
  87785. - dev_err(&client->dev, "No platform data provided\n");
  87786. - return -EINVAL;
  87787. + dev_warn(&client->dev, "Using default platform data.\n");
  87788. + core->power_up_parameters.xcload = 0x28;
  87789. + core->power_up_parameters.func = SI476X_FUNC_FM_RECEIVER;
  87790. + core->power_up_parameters.freq = SI476X_FREQ_37P209375_MHZ;
  87791. + core->diversity_mode = SI476X_PHDIV_DISABLED;
  87792. + core->pinmux.dclk = SI476X_DCLK_DAUDIO;
  87793. + core->pinmux.dfs = SI476X_DFS_DAUDIO;
  87794. + core->pinmux.dout = SI476X_DOUT_I2S_OUTPUT;
  87795. + core->pinmux.xout = SI476X_XOUT_TRISTATE;
  87796. }
  87797. core->supplies[0].supply = "vd";
  87798. @@ -799,6 +806,10 @@
  87799. core->chip_id = id->driver_data;
  87800. + /* Power down si476x first */
  87801. + core->power_state = SI476X_POWER_UP_FULL;
  87802. + si476x_core_set_power_state(core, SI476X_POWER_DOWN);
  87803. +
  87804. rval = si476x_core_get_revision_info(core);
  87805. if (rval < 0) {
  87806. rval = -ENODEV;
  87807. diff -Nur linux-3.14.15/drivers/mfd/si476x-prop.c linux-linaro-stable-mx6/drivers/mfd/si476x-prop.c
  87808. --- linux-3.14.15/drivers/mfd/si476x-prop.c 2014-07-31 23:51:43.000000000 +0200
  87809. +++ linux-linaro-stable-mx6/drivers/mfd/si476x-prop.c 2014-08-20 19:23:53.302844746 +0200
  87810. @@ -217,15 +217,36 @@
  87811. return 0;
  87812. }
  87813. +static bool si476x_core_regmap_volatile_register(struct device *dev, unsigned int reg)
  87814. +{
  87815. + switch (reg) {
  87816. + case SI476X_PROP_DIGITAL_IO_OUTPUT_SAMPLE_RATE:
  87817. + case SI476X_PROP_DIGITAL_IO_OUTPUT_FORMAT:
  87818. + return false;
  87819. + default:
  87820. + return true;
  87821. + }
  87822. +
  87823. + return true;
  87824. +}
  87825. +
  87826. +/* These two register is used by the codec, so add reg_default here */
  87827. +static struct reg_default si476x_core_reg[] = {
  87828. + { 0x202, 0xBB80 },
  87829. + { 0x203, 0x1700 },
  87830. +};
  87831. static const struct regmap_config si476x_regmap_config = {
  87832. .reg_bits = 16,
  87833. .val_bits = 16,
  87834. .max_register = 0x4003,
  87835. + .reg_defaults = si476x_core_reg,
  87836. + .num_reg_defaults = ARRAY_SIZE(si476x_core_reg),
  87837. .writeable_reg = si476x_core_regmap_writable_register,
  87838. .readable_reg = si476x_core_regmap_readable_register,
  87839. + .volatile_reg = si476x_core_regmap_volatile_register,
  87840. .reg_read = si476x_core_regmap_read,
  87841. .reg_write = si476x_core_regmap_write,
  87842. diff -Nur linux-3.14.15/drivers/misc/sram.c linux-linaro-stable-mx6/drivers/misc/sram.c
  87843. --- linux-3.14.15/drivers/misc/sram.c 2014-07-31 23:51:43.000000000 +0200
  87844. +++ linux-linaro-stable-mx6/drivers/misc/sram.c 2014-08-20 19:31:45.936868182 +0200
  87845. @@ -29,7 +29,7 @@
  87846. #include <linux/spinlock.h>
  87847. #include <linux/genalloc.h>
  87848. -#define SRAM_GRANULARITY 32
  87849. +#define SRAM_GRANULARITY 4096
  87850. struct sram_dev {
  87851. struct gen_pool *pool;
  87852. diff -Nur linux-3.14.15/drivers/mmc/core/core.c linux-linaro-stable-mx6/drivers/mmc/core/core.c
  87853. --- linux-3.14.15/drivers/mmc/core/core.c 2014-07-31 23:51:43.000000000 +0200
  87854. +++ linux-linaro-stable-mx6/drivers/mmc/core/core.c 2014-08-20 19:31:45.948868233 +0200
  87855. @@ -13,11 +13,13 @@
  87856. #include <linux/module.h>
  87857. #include <linux/init.h>
  87858. #include <linux/interrupt.h>
  87859. +#include <linux/clk.h>
  87860. #include <linux/completion.h>
  87861. #include <linux/device.h>
  87862. #include <linux/delay.h>
  87863. #include <linux/pagemap.h>
  87864. #include <linux/err.h>
  87865. +#include <linux/gpio.h>
  87866. #include <linux/leds.h>
  87867. #include <linux/scatterlist.h>
  87868. #include <linux/log2.h>
  87869. @@ -1519,6 +1521,43 @@
  87870. mmc_host_clk_release(host);
  87871. }
  87872. +static void mmc_card_power_up(struct mmc_host *host)
  87873. +{
  87874. + int i;
  87875. + struct gpio_desc **gds = host->card_reset_gpios;
  87876. +
  87877. + for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
  87878. + if (gds[i]) {
  87879. + dev_dbg(host->parent, "Asserting reset line %d", i);
  87880. + gpiod_set_value(gds[i], 1);
  87881. + }
  87882. + }
  87883. +
  87884. + if (host->card_regulator) {
  87885. + dev_dbg(host->parent, "Enabling external regulator");
  87886. + if (regulator_enable(host->card_regulator))
  87887. + dev_err(host->parent, "Failed to enable external regulator");
  87888. + }
  87889. +
  87890. + if (host->card_clk) {
  87891. + dev_dbg(host->parent, "Enabling external clock");
  87892. + clk_prepare_enable(host->card_clk);
  87893. + }
  87894. +
  87895. + /* 2ms delay to let clocks and power settle */
  87896. + mmc_delay(20);
  87897. +
  87898. + for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
  87899. + if (gds[i]) {
  87900. + dev_dbg(host->parent, "Deasserting reset line %d", i);
  87901. + gpiod_set_value(gds[i], 0);
  87902. + }
  87903. + }
  87904. +
  87905. + /* 2ms delay to after reset release */
  87906. + mmc_delay(20);
  87907. +}
  87908. +
  87909. /*
  87910. * Apply power to the MMC stack. This is a two-stage process.
  87911. * First, we enable power to the card without the clock running.
  87912. @@ -1535,6 +1574,9 @@
  87913. if (host->ios.power_mode == MMC_POWER_ON)
  87914. return;
  87915. + /* Power up the card/module first, if needed */
  87916. + mmc_card_power_up(host);
  87917. +
  87918. mmc_host_clk_hold(host);
  87919. host->ios.vdd = fls(ocr) - 1;
  87920. diff -Nur linux-3.14.15/drivers/mmc/core/host.c linux-linaro-stable-mx6/drivers/mmc/core/host.c
  87921. --- linux-3.14.15/drivers/mmc/core/host.c 2014-07-31 23:51:43.000000000 +0200
  87922. +++ linux-linaro-stable-mx6/drivers/mmc/core/host.c 2014-08-20 19:31:45.948868233 +0200
  87923. @@ -12,14 +12,18 @@
  87924. * MMC host class device management
  87925. */
  87926. +#include <linux/kernel.h>
  87927. +#include <linux/clk.h>
  87928. #include <linux/device.h>
  87929. #include <linux/err.h>
  87930. +#include <linux/gpio/consumer.h>
  87931. #include <linux/idr.h>
  87932. #include <linux/of.h>
  87933. #include <linux/of_gpio.h>
  87934. #include <linux/pagemap.h>
  87935. #include <linux/export.h>
  87936. #include <linux/leds.h>
  87937. +#include <linux/regulator/consumer.h>
  87938. #include <linux/slab.h>
  87939. #include <linux/suspend.h>
  87940. @@ -439,6 +443,66 @@
  87941. EXPORT_SYMBOL(mmc_of_parse);
  87942. +static int mmc_of_parse_child(struct mmc_host *host)
  87943. +{
  87944. + struct device_node *np;
  87945. + struct clk *clk;
  87946. + int i;
  87947. +
  87948. + if (!host->parent || !host->parent->of_node)
  87949. + return 0;
  87950. +
  87951. + np = host->parent->of_node;
  87952. +
  87953. + host->card_regulator = regulator_get(host->parent, "card-external-vcc");
  87954. + if (IS_ERR(host->card_regulator)) {
  87955. + if (PTR_ERR(host->card_regulator) == -EPROBE_DEFER)
  87956. + return PTR_ERR(host->card_regulator);
  87957. + host->card_regulator = NULL;
  87958. + }
  87959. +
  87960. + /* Parse card power/reset/clock control */
  87961. + if (of_find_property(np, "card-reset-gpios", NULL)) {
  87962. + struct gpio_desc *gpd;
  87963. + int level = 0;
  87964. +
  87965. + /*
  87966. + * If the regulator is enabled, then we can hold the
  87967. + * card in reset with an active high resets. Otherwise,
  87968. + * hold the resets low.
  87969. + */
  87970. + if (host->card_regulator && regulator_is_enabled(host->card_regulator))
  87971. + level = 1;
  87972. +
  87973. + for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
  87974. + gpd = devm_gpiod_get_index(host->parent, "card-reset", i);
  87975. + if (IS_ERR(gpd)) {
  87976. + if (PTR_ERR(gpd) == -EPROBE_DEFER)
  87977. + return PTR_ERR(gpd);
  87978. + break;
  87979. + }
  87980. + gpiod_direction_output(gpd, gpiod_is_active_low(gpd) | level);
  87981. + host->card_reset_gpios[i] = gpd;
  87982. + }
  87983. +
  87984. + gpd = devm_gpiod_get_index(host->parent, "card-reset", ARRAY_SIZE(host->card_reset_gpios));
  87985. + if (!IS_ERR(gpd)) {
  87986. + dev_warn(host->parent, "More reset gpios than we can handle");
  87987. + gpiod_put(gpd);
  87988. + }
  87989. + }
  87990. +
  87991. + clk = of_clk_get_by_name(np, "card_ext_clock");
  87992. + if (IS_ERR(clk)) {
  87993. + if (PTR_ERR(clk) == -EPROBE_DEFER)
  87994. + return PTR_ERR(clk);
  87995. + clk = NULL;
  87996. + }
  87997. + host->card_clk = clk;
  87998. +
  87999. + return 0;
  88000. +}
  88001. +
  88002. /**
  88003. * mmc_alloc_host - initialise the per-host structure.
  88004. * @extra: sizeof private data structure
  88005. @@ -518,6 +582,10 @@
  88006. {
  88007. int err;
  88008. + err = mmc_of_parse_child(host);
  88009. + if (err)
  88010. + return err;
  88011. +
  88012. WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
  88013. !host->ops->enable_sdio_irq);
  88014. diff -Nur linux-3.14.15/drivers/mmc/core/mmc.c linux-linaro-stable-mx6/drivers/mmc/core/mmc.c
  88015. --- linux-3.14.15/drivers/mmc/core/mmc.c 2014-07-31 23:51:43.000000000 +0200
  88016. +++ linux-linaro-stable-mx6/drivers/mmc/core/mmc.c 2014-08-20 19:31:45.948868233 +0200
  88017. @@ -317,6 +317,11 @@
  88018. mmc_card_set_blockaddr(card);
  88019. }
  88020. + card->ext_csd.boot_info = ext_csd[EXT_CSD_BOOT_INFO];
  88021. + card->ext_csd.boot_config = ext_csd[EXT_CSD_PART_CONFIG];
  88022. + card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT];
  88023. + card->ext_csd.boot_bus_width = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
  88024. +
  88025. card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
  88026. mmc_select_card_type(card);
  88027. @@ -655,6 +660,372 @@
  88028. return err;
  88029. }
  88030. +static ssize_t mmc_boot_info_show(struct device *dev,
  88031. + struct device_attribute *attr, char *buf)
  88032. +{
  88033. + char *boot_partition[8] = {
  88034. + "Device not boot enabled",
  88035. + "Boot partition 1 enabled",
  88036. + "Boot partition 2 enabled",
  88037. + "Reserved",
  88038. + "Reserved",
  88039. + "Reserved",
  88040. + "Reserved",
  88041. + "User area enabled for boot"};
  88042. +
  88043. + char *bus_width[4] = {
  88044. + "x1 (sdr) or x4 (ddr) bus width in boot operation mode",
  88045. + "x4 (sdr/ddr) bus width in boot operation mode",
  88046. + "x8 (sdr/ddr) bus width in boot operation mode",
  88047. + "Reserved"};
  88048. +
  88049. + char *boot_mode[4] = {
  88050. + "Use single data rate + backward compatible timings in boot operation",
  88051. + "Use single data rate + high speed timings in boot operation mode",
  88052. + "Use dual data rate in boot operation",
  88053. + "Reserved"};
  88054. +
  88055. + int partition;
  88056. + int width;
  88057. + int mode;
  88058. + int err;
  88059. + u8 *ext_csd = NULL;
  88060. + struct mmc_card *card = container_of(dev, struct mmc_card, dev);
  88061. +
  88062. + /* read it again because user may change it */
  88063. + mmc_claim_host(card->host);
  88064. + err = mmc_get_ext_csd(card, &ext_csd);
  88065. + mmc_release_host(card->host);
  88066. + if (err || !ext_csd) {
  88067. + pr_err("%s: failed to get ext_csd, err=%d\n",
  88068. + mmc_hostname(card->host),
  88069. + err);
  88070. + return err;
  88071. + }
  88072. +
  88073. + mmc_read_ext_csd(card, ext_csd);
  88074. + mmc_free_ext_csd(ext_csd);
  88075. +
  88076. + partition = (card->ext_csd.boot_config >> 3) & 0x7;
  88077. + width = card->ext_csd.boot_bus_width & 0x3;
  88078. + mode = (card->ext_csd.boot_bus_width >> 3) & 0x3;
  88079. +
  88080. + return sprintf(buf,
  88081. + "boot_info:0x%02x;\n"
  88082. + " ALT_BOOT_MODE:%x - %s\n"
  88083. + " DDR_BOOT_MODE:%x - %s\n"
  88084. + " HS_BOOTMODE:%x - %s\n"
  88085. + "boot_size:%04dKB\n"
  88086. + "boot_partition:0x%02x;\n"
  88087. + " BOOT_ACK:%x - %s\n"
  88088. + " BOOT_PARTITION-ENABLE: %x - %s\n"
  88089. + "boot_bus:0x%02x\n"
  88090. + " BOOT_MODE:%x - %s\n"
  88091. + " RESET_BOOT_BUS_WIDTH:%x - %s\n"
  88092. + " BOOT_BUS_WIDTH:%x - %s\n",
  88093. +
  88094. + card->ext_csd.boot_info,
  88095. + !!(card->ext_csd.boot_info & 0x1),
  88096. + (card->ext_csd.boot_info & 0x1) ?
  88097. + "Supports alternate boot method" :
  88098. + "Does not support alternate boot method",
  88099. + !!(card->ext_csd.boot_info & 0x2),
  88100. + (card->ext_csd.boot_info & 0x2) ?
  88101. + "Supports alternate dual data rate during boot" :
  88102. + "Does not support dual data rate during boot",
  88103. + !!(card->ext_csd.boot_info & 0x4),
  88104. + (card->ext_csd.boot_info & 0x4) ?
  88105. + "Supports high speed timing during boot" :
  88106. + "Does not support high speed timing during boot",
  88107. +
  88108. + card->ext_csd.boot_size * 128,
  88109. +
  88110. + card->ext_csd.boot_config,
  88111. + !!(card->ext_csd.boot_config & 0x40),
  88112. + (card->ext_csd.boot_config & 0x40) ?
  88113. + "Boot acknowledge sent during boot operation" :
  88114. + "No boot acknowledge sent",
  88115. + partition,
  88116. + boot_partition[partition],
  88117. +
  88118. + card->ext_csd.boot_bus_width,
  88119. + mode,
  88120. + boot_mode[mode],
  88121. + !!(card->ext_csd.boot_bus_width & 0x4),
  88122. + (card->ext_csd.boot_bus_width & 0x4) ?
  88123. + "Retain boot bus width and boot mode after boot operation" :
  88124. + "Reset bus width to x1, single data rate and backward"
  88125. + "compatible timings after boot operation",
  88126. + width,
  88127. + bus_width[width]);
  88128. +}
  88129. +
  88130. +/* set up boot partitions */
  88131. +static ssize_t
  88132. +setup_boot_partitions(struct device *dev, struct device_attribute *attr,
  88133. + const char *buf, size_t count)
  88134. +{
  88135. + int err, busy = 0;
  88136. + u32 part;
  88137. + u8 *ext_csd, boot_config;
  88138. + struct mmc_command cmd;
  88139. + struct mmc_card *card = container_of(dev, struct mmc_card, dev);
  88140. +
  88141. + BUG_ON(!card);
  88142. +
  88143. + sscanf(buf, "%d\n", &part);
  88144. +
  88145. + if (card->csd.mmca_vsn < CSD_SPEC_VER_4) {
  88146. + pr_err("%s: invalid mmc version" \
  88147. + " mmc version is below version 4!)\n",
  88148. + mmc_hostname(card->host));
  88149. + return -EINVAL;
  88150. + }
  88151. +
  88152. + /* it's a normal SD/MMC but user request to configure boot partition */
  88153. + if (card->ext_csd.boot_size <= 0) {
  88154. + pr_err("%s: fail to send SWITCH command to card " \
  88155. + "to update boot_config of the EXT_CSD!\n",
  88156. + mmc_hostname(card->host));
  88157. + return -EINVAL;
  88158. + }
  88159. +
  88160. + /*
  88161. + * partition must be -
  88162. + * 0 - user area
  88163. + * 1 - boot partition 1
  88164. + * 2 - boot partition 2
  88165. + * DO NOT switch the partitions that used to be accessed
  88166. + * in OS layer HERE
  88167. + */
  88168. + if (part & EXT_CSD_BOOT_PARTITION_ACCESS_MASK) {
  88169. + pr_err("%s: DO NOT switch the partitions that used to be\n" \
  88170. + " accessed in OS layer HERE. please following the\n" \
  88171. + " guidance of Documentation/mmc/mmc-dev-parts.txt.\n",
  88172. + mmc_hostname(card->host));
  88173. + return -EINVAL;
  88174. + }
  88175. +
  88176. + ext_csd = kmalloc(512, GFP_KERNEL);
  88177. + if (!ext_csd) {
  88178. + pr_err("%s: could not allocate a buffer to " \
  88179. + "receive the ext_csd.\n", mmc_hostname(card->host));
  88180. + return -ENOMEM;
  88181. + }
  88182. +
  88183. + mmc_claim_host(card->host);
  88184. + err = mmc_send_ext_csd(card, ext_csd);
  88185. + if (err) {
  88186. + pr_err("%s: unable to read EXT_CSD.\n",
  88187. + mmc_hostname(card->host));
  88188. + goto err_rtn;
  88189. + }
  88190. +
  88191. + /* enable the boot partition in boot mode */
  88192. + /* boot enable be -
  88193. + * 0x00 - disable boot enable.
  88194. + * 0x08 - boot partition 1 is enabled for boot.
  88195. + * 0x10 - boot partition 2 is enabled for boot.
  88196. + * 0x38 - User area is enabled for boot.
  88197. + */
  88198. + switch (part & EXT_CSD_BOOT_PARTITION_ENABLE_MASK) {
  88199. + case 0:
  88200. + boot_config = (ext_csd[EXT_CSD_PART_CONFIG]
  88201. + & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK
  88202. + & ~EXT_CSD_BOOT_ACK_ENABLE);
  88203. + break;
  88204. + case EXT_CSD_BOOT_PARTITION_PART1:
  88205. + boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
  88206. + & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
  88207. + | EXT_CSD_BOOT_PARTITION_PART1
  88208. + | EXT_CSD_BOOT_ACK_ENABLE);
  88209. + break;
  88210. + case EXT_CSD_BOOT_PARTITION_PART2:
  88211. + boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
  88212. + & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
  88213. + | EXT_CSD_BOOT_PARTITION_PART2
  88214. + | EXT_CSD_BOOT_ACK_ENABLE);
  88215. + break;
  88216. + case EXT_CSD_BOOT_PARTITION_ENABLE_MASK:
  88217. + boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
  88218. + | EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
  88219. + & ~EXT_CSD_BOOT_ACK_ENABLE);
  88220. + break;
  88221. + default:
  88222. + pr_err("%s: wrong boot config parameter" \
  88223. + " 00 (disable boot), 08 (enable boot1)," \
  88224. + "16 (enable boot2), 56 (User area)\n",
  88225. + mmc_hostname(card->host));
  88226. + err = -EINVAL;
  88227. + goto err_rtn;
  88228. + }
  88229. +
  88230. + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
  88231. + EXT_CSD_PART_CONFIG, boot_config, card->ext_csd.part_time);
  88232. + if (err) {
  88233. + pr_err("%s: fail to send SWITCH command to card " \
  88234. + "to update boot_config of the EXT_CSD!\n",
  88235. + mmc_hostname(card->host));
  88236. + goto err_rtn;
  88237. + }
  88238. +
  88239. + /* waiting for the card to finish the busy state */
  88240. + do {
  88241. + memset(&cmd, 0, sizeof(struct mmc_command));
  88242. +
  88243. + cmd.opcode = MMC_SEND_STATUS;
  88244. + cmd.arg = card->rca << 16;
  88245. + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
  88246. +
  88247. + err = mmc_wait_for_cmd(card->host, &cmd, 0);
  88248. + if (err || busy > 100) {
  88249. + pr_err("%s: failed to wait for" \
  88250. + "the busy state to end.\n",
  88251. + mmc_hostname(card->host));
  88252. + break;
  88253. + }
  88254. +
  88255. + if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
  88256. + pr_info("%s: card is in busy state" \
  88257. + "pls wait for busy state to end.\n",
  88258. + mmc_hostname(card->host));
  88259. + }
  88260. + busy++;
  88261. + } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
  88262. +
  88263. + /* Now check whether it works */
  88264. + err = mmc_send_ext_csd(card, ext_csd);
  88265. + if (err) {
  88266. + pr_err("%s: %d unable to re-read EXT_CSD.\n",
  88267. + mmc_hostname(card->host), err);
  88268. + goto err_rtn;
  88269. + }
  88270. +
  88271. + card->ext_csd.boot_config = ext_csd[EXT_CSD_PART_CONFIG];
  88272. +
  88273. +err_rtn:
  88274. + mmc_release_host(card->host);
  88275. + kfree(ext_csd);
  88276. + if (err)
  88277. + return err;
  88278. + else
  88279. + return count;
  88280. +}
  88281. +
  88282. +/* configure the boot bus */
  88283. +static ssize_t
  88284. +setup_boot_bus(struct device *dev, struct device_attribute *attr,
  88285. + const char *buf, size_t count)
  88286. +{
  88287. + int err, busy = 0;
  88288. + u32 boot_bus, new_bus;
  88289. + u8 *ext_csd;
  88290. + struct mmc_command cmd;
  88291. + struct mmc_card *card = container_of(dev, struct mmc_card, dev);
  88292. +
  88293. + BUG_ON(!card);
  88294. +
  88295. + sscanf(buf, "%d\n", &boot_bus);
  88296. +
  88297. + if (card->csd.mmca_vsn < CSD_SPEC_VER_4) {
  88298. + pr_err("%s: invalid mmc version" \
  88299. + " mmc version is below version 4!)\n",
  88300. + mmc_hostname(card->host));
  88301. + return -EINVAL;
  88302. + }
  88303. +
  88304. + /* it's a normal SD/MMC but user request to configure boot bus */
  88305. + if (card->ext_csd.boot_size <= 0) {
  88306. + pr_err("%s: this is a normal SD/MMC card" \
  88307. + " but you request to configure boot bus !\n",
  88308. + mmc_hostname(card->host));
  88309. + return -EINVAL;
  88310. + }
  88311. +
  88312. + ext_csd = kmalloc(512, GFP_KERNEL);
  88313. + if (!ext_csd) {
  88314. + pr_err("%s: could not allocate a buffer to " \
  88315. + "receive the ext_csd.\n", mmc_hostname(card->host));
  88316. + return -ENOMEM;
  88317. + }
  88318. +
  88319. + mmc_claim_host(card->host);
  88320. + err = mmc_send_ext_csd(card, ext_csd);
  88321. + if (err) {
  88322. + pr_err("%s: unable to read EXT_CSD.\n",
  88323. + mmc_hostname(card->host));
  88324. + goto err_rtn;
  88325. + }
  88326. +
  88327. + /* Configure the boot bus width when boot partition is enabled */
  88328. + if (((boot_bus & EXT_CSD_BOOT_BUS_WIDTH_MODE_MASK) >> 3) > 2
  88329. + || (boot_bus & EXT_CSD_BOOT_BUS_WIDTH_WIDTH_MASK) > 2
  88330. + || (boot_bus & ~EXT_CSD_BOOT_BUS_WIDTH_MASK) > 0) {
  88331. + pr_err("%s: Invalid inputs!\n",
  88332. + mmc_hostname(card->host));
  88333. + err = -EINVAL;
  88334. + goto err_rtn;
  88335. + }
  88336. +
  88337. + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
  88338. + EXT_CSD_BOOT_BUS_WIDTH, boot_bus, card->ext_csd.part_time);
  88339. + if (err) {
  88340. + pr_err("%s: fail to send SWITCH command to card " \
  88341. + "to update boot_config of the EXT_CSD!\n",
  88342. + mmc_hostname(card->host));
  88343. + goto err_rtn;
  88344. + }
  88345. +
  88346. + /* waiting for the card to finish the busy state */
  88347. + do {
  88348. + memset(&cmd, 0, sizeof(struct mmc_command));
  88349. +
  88350. + cmd.opcode = MMC_SEND_STATUS;
  88351. + cmd.arg = card->rca << 16;
  88352. + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
  88353. +
  88354. + err = mmc_wait_for_cmd(card->host, &cmd, 0);
  88355. + if (err || busy > 100) {
  88356. + pr_err("%s: failed to wait for" \
  88357. + "the busy state to end.\n",
  88358. + mmc_hostname(card->host));
  88359. + break;
  88360. + }
  88361. +
  88362. + if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
  88363. + pr_info("%s: card is in busy state" \
  88364. + "pls wait for busy state to end.\n",
  88365. + mmc_hostname(card->host));
  88366. + }
  88367. + busy++;
  88368. + } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
  88369. +
  88370. + /* Now check whether it works */
  88371. + err = mmc_send_ext_csd(card, ext_csd);
  88372. + if (err) {
  88373. + pr_err("%s: %d unable to re-read EXT_CSD.\n",
  88374. + mmc_hostname(card->host), err);
  88375. + goto err_rtn;
  88376. + }
  88377. +
  88378. + new_bus = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
  88379. + if (boot_bus != new_bus) {
  88380. + pr_err("%s: after SWITCH, current boot bus mode %d" \
  88381. + " is not same as requested bus mode %d!\n",
  88382. + mmc_hostname(card->host), new_bus, boot_bus);
  88383. + goto err_rtn;
  88384. + }
  88385. + card->ext_csd.boot_bus_width = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
  88386. +
  88387. +err_rtn:
  88388. + mmc_release_host(card->host);
  88389. + mmc_free_ext_csd(ext_csd);
  88390. + if (err)
  88391. + return err;
  88392. + else
  88393. + return count;
  88394. +}
  88395. +
  88396. MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
  88397. card->raw_cid[2], card->raw_cid[3]);
  88398. MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
  88399. @@ -674,6 +1045,9 @@
  88400. MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
  88401. MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
  88402. MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
  88403. +DEVICE_ATTR(boot_info, S_IRUGO, mmc_boot_info_show, NULL);
  88404. +DEVICE_ATTR(boot_config, S_IWUGO, NULL, setup_boot_partitions);
  88405. +DEVICE_ATTR(boot_bus_config, S_IWUGO, NULL, setup_boot_bus);
  88406. static struct attribute *mmc_std_attrs[] = {
  88407. &dev_attr_cid.attr,
  88408. @@ -692,6 +1066,9 @@
  88409. &dev_attr_enhanced_area_size.attr,
  88410. &dev_attr_raw_rpmb_size_mult.attr,
  88411. &dev_attr_rel_sectors.attr,
  88412. + &dev_attr_boot_info.attr,
  88413. + &dev_attr_boot_config.attr,
  88414. + &dev_attr_boot_bus_config.attr,
  88415. NULL,
  88416. };
  88417. diff -Nur linux-3.14.15/drivers/mmc/core/sdio_irq.c linux-linaro-stable-mx6/drivers/mmc/core/sdio_irq.c
  88418. --- linux-3.14.15/drivers/mmc/core/sdio_irq.c 2014-07-31 23:51:43.000000000 +0200
  88419. +++ linux-linaro-stable-mx6/drivers/mmc/core/sdio_irq.c 2014-08-20 19:31:45.948868233 +0200
  88420. @@ -90,6 +90,15 @@
  88421. return ret;
  88422. }
  88423. +void sdio_run_irqs(struct mmc_host *host)
  88424. +{
  88425. + mmc_claim_host(host);
  88426. + host->sdio_irq_pending = true;
  88427. + process_sdio_pending_irqs(host);
  88428. + mmc_release_host(host);
  88429. +}
  88430. +EXPORT_SYMBOL_GPL(sdio_run_irqs);
  88431. +
  88432. static int sdio_irq_thread(void *_host)
  88433. {
  88434. struct mmc_host *host = _host;
  88435. @@ -189,14 +198,20 @@
  88436. WARN_ON(!host->claimed);
  88437. if (!host->sdio_irqs++) {
  88438. - atomic_set(&host->sdio_irq_thread_abort, 0);
  88439. - host->sdio_irq_thread =
  88440. - kthread_run(sdio_irq_thread, host, "ksdioirqd/%s",
  88441. - mmc_hostname(host));
  88442. - if (IS_ERR(host->sdio_irq_thread)) {
  88443. - int err = PTR_ERR(host->sdio_irq_thread);
  88444. - host->sdio_irqs--;
  88445. - return err;
  88446. + if (!(host->caps2 & MMC_CAP2_SDIO_NOTHREAD)) {
  88447. + atomic_set(&host->sdio_irq_thread_abort, 0);
  88448. + host->sdio_irq_thread =
  88449. + kthread_run(sdio_irq_thread, host,
  88450. + "ksdioirqd/%s", mmc_hostname(host));
  88451. + if (IS_ERR(host->sdio_irq_thread)) {
  88452. + int err = PTR_ERR(host->sdio_irq_thread);
  88453. + host->sdio_irqs--;
  88454. + return err;
  88455. + }
  88456. + } else {
  88457. + mmc_host_clk_hold(host);
  88458. + host->ops->enable_sdio_irq(host, 1);
  88459. + mmc_host_clk_release(host);
  88460. }
  88461. }
  88462. @@ -211,8 +226,14 @@
  88463. BUG_ON(host->sdio_irqs < 1);
  88464. if (!--host->sdio_irqs) {
  88465. - atomic_set(&host->sdio_irq_thread_abort, 1);
  88466. - kthread_stop(host->sdio_irq_thread);
  88467. + if (!(host->caps2 & MMC_CAP2_SDIO_NOTHREAD)) {
  88468. + atomic_set(&host->sdio_irq_thread_abort, 1);
  88469. + kthread_stop(host->sdio_irq_thread);
  88470. + } else {
  88471. + mmc_host_clk_hold(host);
  88472. + host->ops->enable_sdio_irq(host, 0);
  88473. + mmc_host_clk_release(host);
  88474. + }
  88475. }
  88476. return 0;
  88477. diff -Nur linux-3.14.15/drivers/mmc/host/dw_mmc.c linux-linaro-stable-mx6/drivers/mmc/host/dw_mmc.c
  88478. --- linux-3.14.15/drivers/mmc/host/dw_mmc.c 2014-07-31 23:51:43.000000000 +0200
  88479. +++ linux-linaro-stable-mx6/drivers/mmc/host/dw_mmc.c 2014-08-20 19:31:45.956868267 +0200
  88480. @@ -2140,6 +2140,8 @@
  88481. if (!mmc)
  88482. return -ENOMEM;
  88483. + mmc_of_parse(mmc);
  88484. +
  88485. slot = mmc_priv(mmc);
  88486. slot->id = id;
  88487. slot->mmc = mmc;
  88488. diff -Nur linux-3.14.15/drivers/mmc/host/Kconfig linux-linaro-stable-mx6/drivers/mmc/host/Kconfig
  88489. --- linux-3.14.15/drivers/mmc/host/Kconfig 2014-07-31 23:51:43.000000000 +0200
  88490. +++ linux-linaro-stable-mx6/drivers/mmc/host/Kconfig 2014-08-20 19:31:45.948868233 +0200
  88491. @@ -25,8 +25,7 @@
  88492. If unsure, say N.
  88493. config MMC_SDHCI
  88494. - tristate "Secure Digital Host Controller Interface support"
  88495. - depends on HAS_DMA
  88496. + tristate
  88497. help
  88498. This selects the generic Secure Digital Host Controller Interface.
  88499. It is used by manufacturers such as Texas Instruments(R), Ricoh(R)
  88500. @@ -59,7 +58,8 @@
  88501. config MMC_SDHCI_PCI
  88502. tristate "SDHCI support on PCI bus"
  88503. - depends on MMC_SDHCI && PCI
  88504. + depends on PCI && HAS_DMA
  88505. + select MMC_SDHCI
  88506. help
  88507. This selects the PCI Secure Digital Host Controller Interface.
  88508. Most controllers found today are PCI devices.
  88509. @@ -83,7 +83,8 @@
  88510. config MMC_SDHCI_ACPI
  88511. tristate "SDHCI support for ACPI enumerated SDHCI controllers"
  88512. - depends on MMC_SDHCI && ACPI
  88513. + depends on ACPI && HAS_DMA
  88514. + select MMC_SDHCI
  88515. help
  88516. This selects support for ACPI enumerated SDHCI controllers,
  88517. identified by ACPI Compatibility ID PNP0D40 or specific
  88518. @@ -94,8 +95,8 @@
  88519. If unsure, say N.
  88520. config MMC_SDHCI_PLTFM
  88521. - tristate "SDHCI platform and OF driver helper"
  88522. - depends on MMC_SDHCI
  88523. + tristate
  88524. + select MMC_SDHCI
  88525. help
  88526. This selects the common helper functions support for Secure Digital
  88527. Host Controller Interface based platform and OF drivers.
  88528. @@ -106,8 +107,8 @@
  88529. config MMC_SDHCI_OF_ARASAN
  88530. tristate "SDHCI OF support for the Arasan SDHCI controllers"
  88531. - depends on MMC_SDHCI_PLTFM
  88532. - depends on OF
  88533. + depends on OF && HAS_DMA
  88534. + select MMC_SDHCI_PLTFM
  88535. help
  88536. This selects the Arasan Secure Digital Host Controller Interface
  88537. (SDHCI). This hardware is found e.g. in Xilinx' Zynq SoC.
  88538. @@ -118,9 +119,9 @@
  88539. config MMC_SDHCI_OF_ESDHC
  88540. tristate "SDHCI OF support for the Freescale eSDHC controller"
  88541. - depends on MMC_SDHCI_PLTFM
  88542. - depends on PPC_OF
  88543. + depends on PPC_OF && HAS_DMA
  88544. select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
  88545. + select MMC_SDHCI_PLTFM
  88546. help
  88547. This selects the Freescale eSDHC controller support.
  88548. @@ -130,9 +131,9 @@
  88549. config MMC_SDHCI_OF_HLWD
  88550. tristate "SDHCI OF support for the Nintendo Wii SDHCI controllers"
  88551. - depends on MMC_SDHCI_PLTFM
  88552. - depends on PPC_OF
  88553. + depends on PPC_OF && HAS_DMA
  88554. select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
  88555. + select MMC_SDHCI_PLTFM
  88556. help
  88557. This selects the Secure Digital Host Controller Interface (SDHCI)
  88558. found in the "Hollywood" chipset of the Nintendo Wii video game
  88559. @@ -144,8 +145,8 @@
  88560. config MMC_SDHCI_CNS3XXX
  88561. tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
  88562. - depends on ARCH_CNS3XXX
  88563. - depends on MMC_SDHCI_PLTFM
  88564. + depends on ARCH_CNS3XXX && HAS_DMA
  88565. + select MMC_SDHCI_PLTFM
  88566. help
  88567. This selects the SDHCI support for CNS3xxx System-on-Chip devices.
  88568. @@ -155,9 +156,9 @@
  88569. config MMC_SDHCI_ESDHC_IMX
  88570. tristate "SDHCI support for the Freescale eSDHC/uSDHC i.MX controller"
  88571. - depends on ARCH_MXC
  88572. - depends on MMC_SDHCI_PLTFM
  88573. + depends on ARCH_MXC && HAS_DMA
  88574. select MMC_SDHCI_IO_ACCESSORS
  88575. + select MMC_SDHCI_PLTFM
  88576. help
  88577. This selects the Freescale eSDHC/uSDHC controller support
  88578. found on i.MX25, i.MX35 i.MX5x and i.MX6x.
  88579. @@ -168,9 +169,9 @@
  88580. config MMC_SDHCI_DOVE
  88581. tristate "SDHCI support on Marvell's Dove SoC"
  88582. - depends on ARCH_DOVE
  88583. - depends on MMC_SDHCI_PLTFM
  88584. + depends on ARCH_DOVE && HAS_DMA
  88585. select MMC_SDHCI_IO_ACCESSORS
  88586. + select MMC_SDHCI_PLTFM
  88587. help
  88588. This selects the Secure Digital Host Controller Interface in
  88589. Marvell's Dove SoC.
  88590. @@ -181,9 +182,9 @@
  88591. config MMC_SDHCI_TEGRA
  88592. tristate "SDHCI platform support for the Tegra SD/MMC Controller"
  88593. - depends on ARCH_TEGRA
  88594. - depends on MMC_SDHCI_PLTFM
  88595. + depends on ARCH_TEGRA && HAS_DMA
  88596. select MMC_SDHCI_IO_ACCESSORS
  88597. + select MMC_SDHCI_PLTFM
  88598. help
  88599. This selects the Tegra SD/MMC controller. If you have a Tegra
  88600. platform with SD or MMC devices, say Y or M here.
  88601. @@ -192,7 +193,8 @@
  88602. config MMC_SDHCI_S3C
  88603. tristate "SDHCI support on Samsung S3C SoC"
  88604. - depends on MMC_SDHCI && PLAT_SAMSUNG
  88605. + depends on PLAT_SAMSUNG && HAS_DMA
  88606. + select MMC_SDHCI
  88607. help
  88608. This selects the Secure Digital Host Controller Interface (SDHCI)
  88609. often referrered to as the HSMMC block in some of the Samsung S3C
  88610. @@ -204,8 +206,8 @@
  88611. config MMC_SDHCI_SIRF
  88612. tristate "SDHCI support on CSR SiRFprimaII and SiRFmarco SoCs"
  88613. - depends on ARCH_SIRF
  88614. - depends on MMC_SDHCI_PLTFM
  88615. + depends on ARCH_SIRF && HAS_DMA
  88616. + select MMC_SDHCI_PLTFM
  88617. help
  88618. This selects the SDHCI support for SiRF System-on-Chip devices.
  88619. @@ -215,8 +217,7 @@
  88620. config MMC_SDHCI_PXAV3
  88621. tristate "Marvell MMP2 SD Host Controller support (PXAV3)"
  88622. - depends on CLKDEV_LOOKUP
  88623. - select MMC_SDHCI
  88624. + depends on CLKDEV_LOOKUP && HAS_DMA
  88625. select MMC_SDHCI_PLTFM
  88626. default CPU_MMP2
  88627. help
  88628. @@ -228,8 +229,7 @@
  88629. config MMC_SDHCI_PXAV2
  88630. tristate "Marvell PXA9XX SD Host Controller support (PXAV2)"
  88631. - depends on CLKDEV_LOOKUP
  88632. - select MMC_SDHCI
  88633. + depends on CLKDEV_LOOKUP && HAS_DMA
  88634. select MMC_SDHCI_PLTFM
  88635. default CPU_PXA910
  88636. help
  88637. @@ -241,7 +241,8 @@
  88638. config MMC_SDHCI_SPEAR
  88639. tristate "SDHCI support on ST SPEAr platform"
  88640. - depends on MMC_SDHCI && PLAT_SPEAR
  88641. + depends on PLAT_SPEAR && HAS_DMA
  88642. + select MMC_SDHCI
  88643. help
  88644. This selects the Secure Digital Host Controller Interface (SDHCI)
  88645. often referrered to as the HSMMC block in some of the ST SPEAR range
  88646. @@ -263,7 +264,7 @@
  88647. config MMC_SDHCI_BCM_KONA
  88648. tristate "SDHCI support on Broadcom KONA platform"
  88649. - depends on ARCH_BCM
  88650. + depends on ARCH_BCM && HAS_DMA
  88651. select MMC_SDHCI_PLTFM
  88652. help
  88653. This selects the Broadcom Kona Secure Digital Host Controller
  88654. @@ -274,9 +275,9 @@
  88655. config MMC_SDHCI_BCM2835
  88656. tristate "SDHCI platform support for the BCM2835 SD/MMC Controller"
  88657. - depends on ARCH_BCM2835
  88658. - depends on MMC_SDHCI_PLTFM
  88659. + depends on ARCH_BCM2835 && HAS_DMA
  88660. select MMC_SDHCI_IO_ACCESSORS
  88661. + select MMC_SDHCI_PLTFM
  88662. help
  88663. This selects the BCM2835 SD/MMC controller. If you have a BCM2835
  88664. platform with SD or MMC devices, say Y or M here.
  88665. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-acpi.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-acpi.c
  88666. --- linux-3.14.15/drivers/mmc/host/sdhci-acpi.c 2014-07-31 23:51:43.000000000 +0200
  88667. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-acpi.c 2014-08-20 19:31:45.976868352 +0200
  88668. @@ -101,11 +101,19 @@
  88669. }
  88670. static const struct sdhci_ops sdhci_acpi_ops_dflt = {
  88671. + .set_clock = sdhci_set_clock,
  88672. .enable_dma = sdhci_acpi_enable_dma,
  88673. + .set_bus_width = sdhci_set_bus_width,
  88674. + .reset = sdhci_reset,
  88675. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  88676. };
  88677. static const struct sdhci_ops sdhci_acpi_ops_int = {
  88678. + .set_clock = sdhci_set_clock,
  88679. .enable_dma = sdhci_acpi_enable_dma,
  88680. + .set_bus_width = sdhci_set_bus_width,
  88681. + .reset = sdhci_reset,
  88682. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  88683. .hw_reset = sdhci_acpi_int_hw_reset,
  88684. };
  88685. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-bcm2835.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-bcm2835.c
  88686. --- linux-3.14.15/drivers/mmc/host/sdhci-bcm2835.c 2014-07-31 23:51:43.000000000 +0200
  88687. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-bcm2835.c 2014-08-20 19:31:45.976868352 +0200
  88688. @@ -131,8 +131,12 @@
  88689. .read_l = bcm2835_sdhci_readl,
  88690. .read_w = bcm2835_sdhci_readw,
  88691. .read_b = bcm2835_sdhci_readb,
  88692. + .set_clock = sdhci_set_clock,
  88693. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  88694. .get_min_clock = bcm2835_sdhci_get_min_clock,
  88695. + .set_bus_width = sdhci_set_bus_width,
  88696. + .reset = sdhci_reset,
  88697. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  88698. };
  88699. static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
  88700. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-bcm-kona.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-bcm-kona.c
  88701. --- linux-3.14.15/drivers/mmc/host/sdhci-bcm-kona.c 2014-07-31 23:51:43.000000000 +0200
  88702. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-bcm-kona.c 2014-08-20 19:31:45.976868352 +0200
  88703. @@ -205,9 +205,13 @@
  88704. }
  88705. static struct sdhci_ops sdhci_bcm_kona_ops = {
  88706. + .set_clock = sdhci_set_clock,
  88707. .get_max_clock = sdhci_bcm_kona_get_max_clk,
  88708. .get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
  88709. .platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
  88710. + .set_bus_width = sdhci_set_bus_width,
  88711. + .reset = sdhci_reset,
  88712. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  88713. .card_event = sdhci_bcm_kona_card_event,
  88714. };
  88715. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci.c
  88716. --- linux-3.14.15/drivers/mmc/host/sdhci.c 2014-07-31 23:51:43.000000000 +0200
  88717. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci.c 2014-08-20 19:31:45.996868438 +0200
  88718. @@ -44,6 +44,8 @@
  88719. #define MAX_TUNING_LOOP 40
  88720. +#define ADMA_SIZE ((128 * 2 + 1) * 4)
  88721. +
  88722. static unsigned int debug_quirks = 0;
  88723. static unsigned int debug_quirks2;
  88724. @@ -131,43 +133,28 @@
  88725. * *
  88726. \*****************************************************************************/
  88727. -static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
  88728. -{
  88729. - u32 ier;
  88730. -
  88731. - ier = sdhci_readl(host, SDHCI_INT_ENABLE);
  88732. - ier &= ~clear;
  88733. - ier |= set;
  88734. - sdhci_writel(host, ier, SDHCI_INT_ENABLE);
  88735. - sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
  88736. -}
  88737. -
  88738. -static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
  88739. -{
  88740. - sdhci_clear_set_irqs(host, 0, irqs);
  88741. -}
  88742. -
  88743. -static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
  88744. -{
  88745. - sdhci_clear_set_irqs(host, irqs, 0);
  88746. -}
  88747. -
  88748. static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
  88749. {
  88750. - u32 present, irqs;
  88751. + u32 present;
  88752. + int gpio_cd = mmc_gpio_get_cd(host->mmc);
  88753. if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
  88754. - (host->mmc->caps & MMC_CAP_NONREMOVABLE))
  88755. + (host->mmc->caps & MMC_CAP_NONREMOVABLE) ||
  88756. + !IS_ERR_VALUE(gpio_cd))
  88757. return;
  88758. - present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  88759. - SDHCI_CARD_PRESENT;
  88760. - irqs = present ? SDHCI_INT_CARD_REMOVE : SDHCI_INT_CARD_INSERT;
  88761. + if (enable) {
  88762. + present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  88763. + SDHCI_CARD_PRESENT;
  88764. - if (enable)
  88765. - sdhci_unmask_irqs(host, irqs);
  88766. - else
  88767. - sdhci_mask_irqs(host, irqs);
  88768. + host->ier |= present ? SDHCI_INT_CARD_REMOVE :
  88769. + SDHCI_INT_CARD_INSERT;
  88770. + } else {
  88771. + host->ier &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
  88772. + }
  88773. +
  88774. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  88775. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  88776. }
  88777. static void sdhci_enable_card_detection(struct sdhci_host *host)
  88778. @@ -180,22 +167,9 @@
  88779. sdhci_set_card_detection(host, false);
  88780. }
  88781. -static void sdhci_reset(struct sdhci_host *host, u8 mask)
  88782. +void sdhci_reset(struct sdhci_host *host, u8 mask)
  88783. {
  88784. unsigned long timeout;
  88785. - u32 uninitialized_var(ier);
  88786. -
  88787. - if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
  88788. - if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
  88789. - SDHCI_CARD_PRESENT))
  88790. - return;
  88791. - }
  88792. -
  88793. - if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
  88794. - ier = sdhci_readl(host, SDHCI_INT_ENABLE);
  88795. -
  88796. - if (host->ops->platform_reset_enter)
  88797. - host->ops->platform_reset_enter(host, mask);
  88798. sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
  88799. @@ -220,16 +194,27 @@
  88800. timeout--;
  88801. mdelay(1);
  88802. }
  88803. +}
  88804. +EXPORT_SYMBOL_GPL(sdhci_reset);
  88805. - if (host->ops->platform_reset_exit)
  88806. - host->ops->platform_reset_exit(host, mask);
  88807. +static void sdhci_do_reset(struct sdhci_host *host, u8 mask)
  88808. +{
  88809. + if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
  88810. + if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
  88811. + SDHCI_CARD_PRESENT))
  88812. + return;
  88813. + }
  88814. - if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
  88815. - sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
  88816. + host->ops->reset(host, mask);
  88817. - if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
  88818. - if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
  88819. - host->ops->enable_dma(host);
  88820. + if (mask & SDHCI_RESET_ALL) {
  88821. + if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
  88822. + if (host->ops->enable_dma)
  88823. + host->ops->enable_dma(host);
  88824. + }
  88825. +
  88826. + /* Resetting the controller clears many */
  88827. + host->preset_enabled = false;
  88828. }
  88829. }
  88830. @@ -238,15 +223,18 @@
  88831. static void sdhci_init(struct sdhci_host *host, int soft)
  88832. {
  88833. if (soft)
  88834. - sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
  88835. + sdhci_do_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
  88836. else
  88837. - sdhci_reset(host, SDHCI_RESET_ALL);
  88838. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  88839. - sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
  88840. - SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
  88841. - SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
  88842. - SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
  88843. - SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
  88844. + host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
  88845. + SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
  88846. + SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC |
  88847. + SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END |
  88848. + SDHCI_INT_RESPONSE;
  88849. +
  88850. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  88851. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  88852. if (soft) {
  88853. /* force clock reconfiguration */
  88854. @@ -502,11 +490,6 @@
  88855. else
  88856. direction = DMA_TO_DEVICE;
  88857. - /*
  88858. - * The ADMA descriptor table is mapped further down as we
  88859. - * need to fill it with data first.
  88860. - */
  88861. -
  88862. host->align_addr = dma_map_single(mmc_dev(host->mmc),
  88863. host->align_buffer, 128 * 4, direction);
  88864. if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
  88865. @@ -567,7 +550,7 @@
  88866. * If this triggers then we have a calculation bug
  88867. * somewhere. :/
  88868. */
  88869. - WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
  88870. + WARN_ON((desc - host->adma_desc) > ADMA_SIZE);
  88871. }
  88872. if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) {
  88873. @@ -595,17 +578,8 @@
  88874. host->align_addr, 128 * 4, direction);
  88875. }
  88876. - host->adma_addr = dma_map_single(mmc_dev(host->mmc),
  88877. - host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE);
  88878. - if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr))
  88879. - goto unmap_entries;
  88880. - BUG_ON(host->adma_addr & 0x3);
  88881. -
  88882. return 0;
  88883. -unmap_entries:
  88884. - dma_unmap_sg(mmc_dev(host->mmc), data->sg,
  88885. - data->sg_len, direction);
  88886. unmap_align:
  88887. dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
  88888. 128 * 4, direction);
  88889. @@ -623,19 +597,25 @@
  88890. u8 *align;
  88891. char *buffer;
  88892. unsigned long flags;
  88893. + bool has_unaligned;
  88894. if (data->flags & MMC_DATA_READ)
  88895. direction = DMA_FROM_DEVICE;
  88896. else
  88897. direction = DMA_TO_DEVICE;
  88898. - dma_unmap_single(mmc_dev(host->mmc), host->adma_addr,
  88899. - (128 * 2 + 1) * 4, DMA_TO_DEVICE);
  88900. -
  88901. dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
  88902. 128 * 4, direction);
  88903. - if (data->flags & MMC_DATA_READ) {
  88904. + /* Do a quick scan of the SG list for any unaligned mappings */
  88905. + has_unaligned = false;
  88906. + for_each_sg(data->sg, sg, host->sg_count, i)
  88907. + if (sg_dma_address(sg) & 3) {
  88908. + has_unaligned = true;
  88909. + break;
  88910. + }
  88911. +
  88912. + if (has_unaligned && data->flags & MMC_DATA_READ) {
  88913. dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
  88914. data->sg_len, direction);
  88915. @@ -721,9 +701,12 @@
  88916. u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
  88917. if (host->flags & SDHCI_REQ_USE_DMA)
  88918. - sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
  88919. + host->ier = (host->ier & ~pio_irqs) | dma_irqs;
  88920. else
  88921. - sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
  88922. + host->ier = (host->ier & ~dma_irqs) | pio_irqs;
  88923. +
  88924. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  88925. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  88926. }
  88927. static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
  88928. @@ -976,8 +959,8 @@
  88929. * upon error conditions.
  88930. */
  88931. if (data->error) {
  88932. - sdhci_reset(host, SDHCI_RESET_CMD);
  88933. - sdhci_reset(host, SDHCI_RESET_DATA);
  88934. + sdhci_do_reset(host, SDHCI_RESET_CMD);
  88935. + sdhci_do_reset(host, SDHCI_RESET_DATA);
  88936. }
  88937. sdhci_send_command(host, data->stop);
  88938. @@ -1107,24 +1090,23 @@
  88939. static u16 sdhci_get_preset_value(struct sdhci_host *host)
  88940. {
  88941. - u16 ctrl, preset = 0;
  88942. -
  88943. - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  88944. + u16 preset = 0;
  88945. - switch (ctrl & SDHCI_CTRL_UHS_MASK) {
  88946. - case SDHCI_CTRL_UHS_SDR12:
  88947. + switch (host->timing) {
  88948. + case MMC_TIMING_UHS_SDR12:
  88949. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
  88950. break;
  88951. - case SDHCI_CTRL_UHS_SDR25:
  88952. + case MMC_TIMING_UHS_SDR25:
  88953. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR25);
  88954. break;
  88955. - case SDHCI_CTRL_UHS_SDR50:
  88956. + case MMC_TIMING_UHS_SDR50:
  88957. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR50);
  88958. break;
  88959. - case SDHCI_CTRL_UHS_SDR104:
  88960. + case MMC_TIMING_UHS_SDR104:
  88961. + case MMC_TIMING_MMC_HS200:
  88962. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104);
  88963. break;
  88964. - case SDHCI_CTRL_UHS_DDR50:
  88965. + case MMC_TIMING_UHS_DDR50:
  88966. preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
  88967. break;
  88968. default:
  88969. @@ -1136,32 +1118,22 @@
  88970. return preset;
  88971. }
  88972. -static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
  88973. +void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
  88974. {
  88975. int div = 0; /* Initialized for compiler warning */
  88976. int real_div = div, clk_mul = 1;
  88977. u16 clk = 0;
  88978. unsigned long timeout;
  88979. - if (clock && clock == host->clock)
  88980. - return;
  88981. -
  88982. host->mmc->actual_clock = 0;
  88983. - if (host->ops->set_clock) {
  88984. - host->ops->set_clock(host, clock);
  88985. - if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
  88986. - return;
  88987. - }
  88988. -
  88989. sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
  88990. if (clock == 0)
  88991. - goto out;
  88992. + return;
  88993. if (host->version >= SDHCI_SPEC_300) {
  88994. - if (sdhci_readw(host, SDHCI_HOST_CONTROL2) &
  88995. - SDHCI_CTRL_PRESET_VAL_ENABLE) {
  88996. + if (host->preset_enabled) {
  88997. u16 pre_val;
  88998. clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
  88999. @@ -1247,26 +1219,16 @@
  89000. clk |= SDHCI_CLOCK_CARD_EN;
  89001. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  89002. -
  89003. -out:
  89004. - host->clock = clock;
  89005. -}
  89006. -
  89007. -static inline void sdhci_update_clock(struct sdhci_host *host)
  89008. -{
  89009. - unsigned int clock;
  89010. -
  89011. - clock = host->clock;
  89012. - host->clock = 0;
  89013. - sdhci_set_clock(host, clock);
  89014. }
  89015. +EXPORT_SYMBOL_GPL(sdhci_set_clock);
  89016. -static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
  89017. +static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
  89018. + unsigned short vdd)
  89019. {
  89020. u8 pwr = 0;
  89021. - if (power != (unsigned short)-1) {
  89022. - switch (1 << power) {
  89023. + if (mode != MMC_POWER_OFF) {
  89024. + switch (1 << vdd) {
  89025. case MMC_VDD_165_195:
  89026. pwr = SDHCI_POWER_180;
  89027. break;
  89028. @@ -1284,7 +1246,7 @@
  89029. }
  89030. if (host->pwr == pwr)
  89031. - return -1;
  89032. + return;
  89033. host->pwr = pwr;
  89034. @@ -1292,38 +1254,43 @@
  89035. sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
  89036. if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
  89037. sdhci_runtime_pm_bus_off(host);
  89038. - return 0;
  89039. - }
  89040. -
  89041. - /*
  89042. - * Spec says that we should clear the power reg before setting
  89043. - * a new value. Some controllers don't seem to like this though.
  89044. - */
  89045. - if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
  89046. - sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
  89047. + vdd = 0;
  89048. + } else {
  89049. + /*
  89050. + * Spec says that we should clear the power reg before setting
  89051. + * a new value. Some controllers don't seem to like this though.
  89052. + */
  89053. + if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
  89054. + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
  89055. - /*
  89056. - * At least the Marvell CaFe chip gets confused if we set the voltage
  89057. - * and set turn on power at the same time, so set the voltage first.
  89058. - */
  89059. - if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)
  89060. - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  89061. + /*
  89062. + * At least the Marvell CaFe chip gets confused if we set the
  89063. + * voltage and set turn on power at the same time, so set the
  89064. + * voltage first.
  89065. + */
  89066. + if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)
  89067. + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  89068. - pwr |= SDHCI_POWER_ON;
  89069. + pwr |= SDHCI_POWER_ON;
  89070. - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  89071. + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  89072. - if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
  89073. - sdhci_runtime_pm_bus_on(host);
  89074. + if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
  89075. + sdhci_runtime_pm_bus_on(host);
  89076. - /*
  89077. - * Some controllers need an extra 10ms delay of 10ms before they
  89078. - * can apply clock after applying power
  89079. - */
  89080. - if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
  89081. - mdelay(10);
  89082. + /*
  89083. + * Some controllers need an extra 10ms delay of 10ms before
  89084. + * they can apply clock after applying power
  89085. + */
  89086. + if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
  89087. + mdelay(10);
  89088. + }
  89089. - return power;
  89090. + if (host->vmmc) {
  89091. + spin_unlock_irq(&host->lock);
  89092. + mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd);
  89093. + spin_lock_irq(&host->lock);
  89094. + }
  89095. }
  89096. /*****************************************************************************\
  89097. @@ -1427,10 +1394,52 @@
  89098. spin_unlock_irqrestore(&host->lock, flags);
  89099. }
  89100. +void sdhci_set_bus_width(struct sdhci_host *host, int width)
  89101. +{
  89102. + u8 ctrl;
  89103. +
  89104. + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
  89105. + if (width == MMC_BUS_WIDTH_8) {
  89106. + ctrl &= ~SDHCI_CTRL_4BITBUS;
  89107. + if (host->version >= SDHCI_SPEC_300)
  89108. + ctrl |= SDHCI_CTRL_8BITBUS;
  89109. + } else {
  89110. + if (host->version >= SDHCI_SPEC_300)
  89111. + ctrl &= ~SDHCI_CTRL_8BITBUS;
  89112. + if (width == MMC_BUS_WIDTH_4)
  89113. + ctrl |= SDHCI_CTRL_4BITBUS;
  89114. + else
  89115. + ctrl &= ~SDHCI_CTRL_4BITBUS;
  89116. + }
  89117. + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  89118. +}
  89119. +EXPORT_SYMBOL_GPL(sdhci_set_bus_width);
  89120. +
  89121. +void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
  89122. +{
  89123. + u16 ctrl_2;
  89124. +
  89125. + ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89126. + /* Select Bus Speed Mode for host */
  89127. + ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
  89128. + if ((timing == MMC_TIMING_MMC_HS200) ||
  89129. + (timing == MMC_TIMING_UHS_SDR104))
  89130. + ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
  89131. + else if (timing == MMC_TIMING_UHS_SDR12)
  89132. + ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
  89133. + else if (timing == MMC_TIMING_UHS_SDR25)
  89134. + ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
  89135. + else if (timing == MMC_TIMING_UHS_SDR50)
  89136. + ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
  89137. + else if (timing == MMC_TIMING_UHS_DDR50)
  89138. + ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
  89139. + sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
  89140. +}
  89141. +EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
  89142. +
  89143. static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
  89144. {
  89145. unsigned long flags;
  89146. - int vdd_bit = -1;
  89147. u8 ctrl;
  89148. spin_lock_irqsave(&host->lock, flags);
  89149. @@ -1456,45 +1465,17 @@
  89150. !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
  89151. sdhci_enable_preset_value(host, false);
  89152. - sdhci_set_clock(host, ios->clock);
  89153. -
  89154. - if (ios->power_mode == MMC_POWER_OFF)
  89155. - vdd_bit = sdhci_set_power(host, -1);
  89156. - else
  89157. - vdd_bit = sdhci_set_power(host, ios->vdd);
  89158. -
  89159. - if (host->vmmc && vdd_bit != -1) {
  89160. - spin_unlock_irqrestore(&host->lock, flags);
  89161. - mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
  89162. - spin_lock_irqsave(&host->lock, flags);
  89163. + if (!ios->clock || ios->clock != host->clock) {
  89164. + host->ops->set_clock(host, ios->clock);
  89165. + host->clock = ios->clock;
  89166. }
  89167. + sdhci_set_power(host, ios->power_mode, ios->vdd);
  89168. +
  89169. if (host->ops->platform_send_init_74_clocks)
  89170. host->ops->platform_send_init_74_clocks(host, ios->power_mode);
  89171. - /*
  89172. - * If your platform has 8-bit width support but is not a v3 controller,
  89173. - * or if it requires special setup code, you should implement that in
  89174. - * platform_bus_width().
  89175. - */
  89176. - if (host->ops->platform_bus_width) {
  89177. - host->ops->platform_bus_width(host, ios->bus_width);
  89178. - } else {
  89179. - ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
  89180. - if (ios->bus_width == MMC_BUS_WIDTH_8) {
  89181. - ctrl &= ~SDHCI_CTRL_4BITBUS;
  89182. - if (host->version >= SDHCI_SPEC_300)
  89183. - ctrl |= SDHCI_CTRL_8BITBUS;
  89184. - } else {
  89185. - if (host->version >= SDHCI_SPEC_300)
  89186. - ctrl &= ~SDHCI_CTRL_8BITBUS;
  89187. - if (ios->bus_width == MMC_BUS_WIDTH_4)
  89188. - ctrl |= SDHCI_CTRL_4BITBUS;
  89189. - else
  89190. - ctrl &= ~SDHCI_CTRL_4BITBUS;
  89191. - }
  89192. - sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  89193. - }
  89194. + host->ops->set_bus_width(host, ios->bus_width);
  89195. ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
  89196. @@ -1516,13 +1497,13 @@
  89197. (ios->timing == MMC_TIMING_UHS_SDR25))
  89198. ctrl |= SDHCI_CTRL_HISPD;
  89199. - ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89200. - if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
  89201. + if (!host->preset_enabled) {
  89202. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  89203. /*
  89204. * We only need to set Driver Strength if the
  89205. * preset value enable is not set.
  89206. */
  89207. + ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89208. ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK;
  89209. if (ios->drv_type == MMC_SET_DRIVER_TYPE_A)
  89210. ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A;
  89211. @@ -1546,34 +1527,16 @@
  89212. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  89213. /* Re-enable SD Clock */
  89214. - sdhci_update_clock(host);
  89215. + host->ops->set_clock(host, host->clock);
  89216. }
  89217. -
  89218. /* Reset SD Clock Enable */
  89219. clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
  89220. clk &= ~SDHCI_CLOCK_CARD_EN;
  89221. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  89222. - if (host->ops->set_uhs_signaling)
  89223. - host->ops->set_uhs_signaling(host, ios->timing);
  89224. - else {
  89225. - ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89226. - /* Select Bus Speed Mode for host */
  89227. - ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
  89228. - if ((ios->timing == MMC_TIMING_MMC_HS200) ||
  89229. - (ios->timing == MMC_TIMING_UHS_SDR104))
  89230. - ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
  89231. - else if (ios->timing == MMC_TIMING_UHS_SDR12)
  89232. - ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
  89233. - else if (ios->timing == MMC_TIMING_UHS_SDR25)
  89234. - ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
  89235. - else if (ios->timing == MMC_TIMING_UHS_SDR50)
  89236. - ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
  89237. - else if (ios->timing == MMC_TIMING_UHS_DDR50)
  89238. - ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
  89239. - sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
  89240. - }
  89241. + host->ops->set_uhs_signaling(host, ios->timing);
  89242. + host->timing = ios->timing;
  89243. if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
  89244. ((ios->timing == MMC_TIMING_UHS_SDR12) ||
  89245. @@ -1589,8 +1552,7 @@
  89246. >> SDHCI_PRESET_DRV_SHIFT;
  89247. }
  89248. - /* Re-enable SD Clock */
  89249. - sdhci_update_clock(host);
  89250. + host->ops->set_clock(host, host->clock);
  89251. } else
  89252. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  89253. @@ -1600,7 +1562,7 @@
  89254. * it on each ios seems to solve the problem.
  89255. */
  89256. if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
  89257. - sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
  89258. + sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
  89259. mmiowb();
  89260. spin_unlock_irqrestore(&host->lock, flags);
  89261. @@ -1709,24 +1671,16 @@
  89262. static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
  89263. {
  89264. - if (host->flags & SDHCI_DEVICE_DEAD)
  89265. - goto out;
  89266. -
  89267. - if (enable)
  89268. - host->flags |= SDHCI_SDIO_IRQ_ENABLED;
  89269. - else
  89270. - host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
  89271. -
  89272. - /* SDIO IRQ will be enabled as appropriate in runtime resume */
  89273. - if (host->runtime_suspended)
  89274. - goto out;
  89275. + if (!(host->flags & SDHCI_DEVICE_DEAD)) {
  89276. + if (enable)
  89277. + host->ier |= SDHCI_INT_CARD_INT;
  89278. + else
  89279. + host->ier &= ~SDHCI_INT_CARD_INT;
  89280. - if (enable)
  89281. - sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
  89282. - else
  89283. - sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
  89284. -out:
  89285. - mmiowb();
  89286. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  89287. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  89288. + mmiowb();
  89289. + }
  89290. }
  89291. static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
  89292. @@ -1734,9 +1688,18 @@
  89293. struct sdhci_host *host = mmc_priv(mmc);
  89294. unsigned long flags;
  89295. + sdhci_runtime_pm_get(host);
  89296. +
  89297. spin_lock_irqsave(&host->lock, flags);
  89298. + if (enable)
  89299. + host->flags |= SDHCI_SDIO_IRQ_ENABLED;
  89300. + else
  89301. + host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
  89302. +
  89303. sdhci_enable_sdio_irq_nolock(host, enable);
  89304. spin_unlock_irqrestore(&host->lock, flags);
  89305. +
  89306. + sdhci_runtime_pm_put(host);
  89307. }
  89308. static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
  89309. @@ -1855,22 +1818,16 @@
  89310. static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
  89311. {
  89312. - struct sdhci_host *host;
  89313. + struct sdhci_host *host = mmc_priv(mmc);
  89314. u16 ctrl;
  89315. - u32 ier;
  89316. int tuning_loop_counter = MAX_TUNING_LOOP;
  89317. unsigned long timeout;
  89318. int err = 0;
  89319. - bool requires_tuning_nonuhs = false;
  89320. unsigned long flags;
  89321. - host = mmc_priv(mmc);
  89322. -
  89323. sdhci_runtime_pm_get(host);
  89324. spin_lock_irqsave(&host->lock, flags);
  89325. - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89326. -
  89327. /*
  89328. * The Host Controller needs tuning only in case of SDR104 mode
  89329. * and for SDR50 mode when Use Tuning for SDR50 is set in the
  89330. @@ -1878,15 +1835,18 @@
  89331. * If the Host Controller supports the HS200 mode then the
  89332. * tuning function has to be executed.
  89333. */
  89334. - if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
  89335. - (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
  89336. - host->flags & SDHCI_SDR104_NEEDS_TUNING))
  89337. - requires_tuning_nonuhs = true;
  89338. -
  89339. - if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
  89340. - requires_tuning_nonuhs)
  89341. - ctrl |= SDHCI_CTRL_EXEC_TUNING;
  89342. - else {
  89343. + switch (host->timing) {
  89344. + case MMC_TIMING_MMC_HS200:
  89345. + case MMC_TIMING_UHS_SDR104:
  89346. + break;
  89347. +
  89348. + case MMC_TIMING_UHS_SDR50:
  89349. + if (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
  89350. + host->flags & SDHCI_SDR104_NEEDS_TUNING)
  89351. + break;
  89352. + /* FALLTHROUGH */
  89353. +
  89354. + default:
  89355. spin_unlock_irqrestore(&host->lock, flags);
  89356. sdhci_runtime_pm_put(host);
  89357. return 0;
  89358. @@ -1899,6 +1859,8 @@
  89359. return err;
  89360. }
  89361. + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89362. + ctrl |= SDHCI_CTRL_EXEC_TUNING;
  89363. sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
  89364. /*
  89365. @@ -1911,8 +1873,8 @@
  89366. * to make sure we don't hit a controller bug, we _only_
  89367. * enable Buffer Read Ready interrupt here.
  89368. */
  89369. - ier = sdhci_readl(host, SDHCI_INT_ENABLE);
  89370. - sdhci_clear_set_irqs(host, ier, SDHCI_INT_DATA_AVAIL);
  89371. + sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
  89372. + sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
  89373. /*
  89374. * Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number
  89375. @@ -2045,7 +2007,8 @@
  89376. if (err && (host->flags & SDHCI_USING_RETUNING_TIMER))
  89377. err = 0;
  89378. - sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
  89379. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  89380. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  89381. spin_unlock_irqrestore(&host->lock, flags);
  89382. sdhci_runtime_pm_put(host);
  89383. @@ -2055,26 +2018,30 @@
  89384. static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
  89385. {
  89386. - u16 ctrl;
  89387. -
  89388. /* Host Controller v3.00 defines preset value registers */
  89389. if (host->version < SDHCI_SPEC_300)
  89390. return;
  89391. - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89392. -
  89393. /*
  89394. * We only enable or disable Preset Value if they are not already
  89395. * enabled or disabled respectively. Otherwise, we bail out.
  89396. */
  89397. - if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
  89398. - ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
  89399. - sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
  89400. - host->flags |= SDHCI_PV_ENABLED;
  89401. - } else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
  89402. - ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
  89403. + if (host->preset_enabled != enable) {
  89404. + u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89405. +
  89406. + if (enable)
  89407. + ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
  89408. + else
  89409. + ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
  89410. +
  89411. sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
  89412. - host->flags &= ~SDHCI_PV_ENABLED;
  89413. +
  89414. + if (enable)
  89415. + host->flags |= SDHCI_PV_ENABLED;
  89416. + else
  89417. + host->flags &= ~SDHCI_PV_ENABLED;
  89418. +
  89419. + host->preset_enabled = enable;
  89420. }
  89421. }
  89422. @@ -2096,8 +2063,8 @@
  89423. pr_err("%s: Resetting controller.\n",
  89424. mmc_hostname(host->mmc));
  89425. - sdhci_reset(host, SDHCI_RESET_CMD);
  89426. - sdhci_reset(host, SDHCI_RESET_DATA);
  89427. + sdhci_do_reset(host, SDHCI_RESET_CMD);
  89428. + sdhci_do_reset(host, SDHCI_RESET_DATA);
  89429. host->mrq->cmd->error = -ENOMEDIUM;
  89430. tasklet_schedule(&host->finish_tasklet);
  89431. @@ -2125,15 +2092,6 @@
  89432. * *
  89433. \*****************************************************************************/
  89434. -static void sdhci_tasklet_card(unsigned long param)
  89435. -{
  89436. - struct sdhci_host *host = (struct sdhci_host*)param;
  89437. -
  89438. - sdhci_card_event(host->mmc);
  89439. -
  89440. - mmc_detect_change(host->mmc, msecs_to_jiffies(200));
  89441. -}
  89442. -
  89443. static void sdhci_tasklet_finish(unsigned long param)
  89444. {
  89445. struct sdhci_host *host;
  89446. @@ -2170,12 +2128,12 @@
  89447. /* Some controllers need this kick or reset won't work here */
  89448. if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
  89449. /* This is to force an update */
  89450. - sdhci_update_clock(host);
  89451. + host->ops->set_clock(host, host->clock);
  89452. /* Spec says we should do both at the same time, but Ricoh
  89453. controllers do not like that. */
  89454. - sdhci_reset(host, SDHCI_RESET_CMD);
  89455. - sdhci_reset(host, SDHCI_RESET_DATA);
  89456. + sdhci_do_reset(host, SDHCI_RESET_CMD);
  89457. + sdhci_do_reset(host, SDHCI_RESET_DATA);
  89458. }
  89459. host->mrq = NULL;
  89460. @@ -2425,14 +2383,14 @@
  89461. static irqreturn_t sdhci_irq(int irq, void *dev_id)
  89462. {
  89463. - irqreturn_t result;
  89464. + irqreturn_t result = IRQ_NONE;
  89465. struct sdhci_host *host = dev_id;
  89466. - u32 intmask, unexpected = 0;
  89467. - int cardint = 0, max_loops = 16;
  89468. + u32 intmask, mask, unexpected = 0;
  89469. + int max_loops = 16;
  89470. spin_lock(&host->lock);
  89471. - if (host->runtime_suspended) {
  89472. + if (host->runtime_suspended && !sdhci_sdio_irq_enabled(host)) {
  89473. spin_unlock(&host->lock);
  89474. pr_warning("%s: got irq while runtime suspended\n",
  89475. mmc_hostname(host->mmc));
  89476. @@ -2440,88 +2398,81 @@
  89477. }
  89478. intmask = sdhci_readl(host, SDHCI_INT_STATUS);
  89479. -
  89480. if (!intmask || intmask == 0xffffffff) {
  89481. result = IRQ_NONE;
  89482. goto out;
  89483. }
  89484. -again:
  89485. - DBG("*** %s got interrupt: 0x%08x\n",
  89486. - mmc_hostname(host->mmc), intmask);
  89487. -
  89488. - if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
  89489. - u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  89490. - SDHCI_CARD_PRESENT;
  89491. -
  89492. - /*
  89493. - * There is a observation on i.mx esdhc. INSERT bit will be
  89494. - * immediately set again when it gets cleared, if a card is
  89495. - * inserted. We have to mask the irq to prevent interrupt
  89496. - * storm which will freeze the system. And the REMOVE gets
  89497. - * the same situation.
  89498. - *
  89499. - * More testing are needed here to ensure it works for other
  89500. - * platforms though.
  89501. - */
  89502. - sdhci_mask_irqs(host, present ? SDHCI_INT_CARD_INSERT :
  89503. - SDHCI_INT_CARD_REMOVE);
  89504. - sdhci_unmask_irqs(host, present ? SDHCI_INT_CARD_REMOVE :
  89505. - SDHCI_INT_CARD_INSERT);
  89506. -
  89507. - sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
  89508. - SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
  89509. - intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
  89510. - tasklet_schedule(&host->card_tasklet);
  89511. - }
  89512. -
  89513. - if (intmask & SDHCI_INT_CMD_MASK) {
  89514. - sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
  89515. - SDHCI_INT_STATUS);
  89516. - sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
  89517. - }
  89518. + do {
  89519. + /* Clear selected interrupts. */
  89520. + mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
  89521. + SDHCI_INT_BUS_POWER);
  89522. + sdhci_writel(host, mask, SDHCI_INT_STATUS);
  89523. +
  89524. + DBG("*** %s got interrupt: 0x%08x\n",
  89525. + mmc_hostname(host->mmc), intmask);
  89526. +
  89527. + if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
  89528. + u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  89529. + SDHCI_CARD_PRESENT;
  89530. - if (intmask & SDHCI_INT_DATA_MASK) {
  89531. - sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
  89532. - SDHCI_INT_STATUS);
  89533. - sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
  89534. - }
  89535. + /*
  89536. + * There is a observation on i.mx esdhc. INSERT
  89537. + * bit will be immediately set again when it gets
  89538. + * cleared, if a card is inserted. We have to mask
  89539. + * the irq to prevent interrupt storm which will
  89540. + * freeze the system. And the REMOVE gets the
  89541. + * same situation.
  89542. + *
  89543. + * More testing are needed here to ensure it works
  89544. + * for other platforms though.
  89545. + */
  89546. + host->ier &= ~(SDHCI_INT_CARD_INSERT |
  89547. + SDHCI_INT_CARD_REMOVE);
  89548. + host->ier |= present ? SDHCI_INT_CARD_REMOVE :
  89549. + SDHCI_INT_CARD_INSERT;
  89550. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  89551. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  89552. - intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
  89553. + sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
  89554. + SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
  89555. - intmask &= ~SDHCI_INT_ERROR;
  89556. + host->thread_isr |= intmask & (SDHCI_INT_CARD_INSERT |
  89557. + SDHCI_INT_CARD_REMOVE);
  89558. + result = IRQ_WAKE_THREAD;
  89559. + }
  89560. - if (intmask & SDHCI_INT_BUS_POWER) {
  89561. - pr_err("%s: Card is consuming too much power!\n",
  89562. - mmc_hostname(host->mmc));
  89563. - sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
  89564. - }
  89565. + if (intmask & SDHCI_INT_CMD_MASK)
  89566. + sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
  89567. - intmask &= ~SDHCI_INT_BUS_POWER;
  89568. + if (intmask & SDHCI_INT_DATA_MASK)
  89569. + sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
  89570. - if (intmask & SDHCI_INT_CARD_INT)
  89571. - cardint = 1;
  89572. + if (intmask & SDHCI_INT_BUS_POWER)
  89573. + pr_err("%s: Card is consuming too much power!\n",
  89574. + mmc_hostname(host->mmc));
  89575. - intmask &= ~SDHCI_INT_CARD_INT;
  89576. + if (intmask & SDHCI_INT_CARD_INT) {
  89577. + sdhci_enable_sdio_irq_nolock(host, false);
  89578. + host->thread_isr |= SDHCI_INT_CARD_INT;
  89579. + result = IRQ_WAKE_THREAD;
  89580. + }
  89581. - if (intmask) {
  89582. - unexpected |= intmask;
  89583. - sdhci_writel(host, intmask, SDHCI_INT_STATUS);
  89584. - }
  89585. + intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
  89586. + SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
  89587. + SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER |
  89588. + SDHCI_INT_CARD_INT);
  89589. - result = IRQ_HANDLED;
  89590. + if (intmask) {
  89591. + unexpected |= intmask;
  89592. + sdhci_writel(host, intmask, SDHCI_INT_STATUS);
  89593. + }
  89594. - intmask = sdhci_readl(host, SDHCI_INT_STATUS);
  89595. + if (result == IRQ_NONE)
  89596. + result = IRQ_HANDLED;
  89597. - /*
  89598. - * If we know we'll call the driver to signal SDIO IRQ, disregard
  89599. - * further indications of Card Interrupt in the status to avoid a
  89600. - * needless loop.
  89601. - */
  89602. - if (cardint)
  89603. - intmask &= ~SDHCI_INT_CARD_INT;
  89604. - if (intmask && --max_loops)
  89605. - goto again;
  89606. + intmask = sdhci_readl(host, SDHCI_INT_STATUS);
  89607. + } while (intmask && --max_loops);
  89608. out:
  89609. spin_unlock(&host->lock);
  89610. @@ -2530,15 +2481,38 @@
  89611. mmc_hostname(host->mmc), unexpected);
  89612. sdhci_dumpregs(host);
  89613. }
  89614. - /*
  89615. - * We have to delay this as it calls back into the driver.
  89616. - */
  89617. - if (cardint)
  89618. - mmc_signal_sdio_irq(host->mmc);
  89619. return result;
  89620. }
  89621. +static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
  89622. +{
  89623. + struct sdhci_host *host = dev_id;
  89624. + unsigned long flags;
  89625. + u32 isr;
  89626. +
  89627. + spin_lock_irqsave(&host->lock, flags);
  89628. + isr = host->thread_isr;
  89629. + host->thread_isr = 0;
  89630. + spin_unlock_irqrestore(&host->lock, flags);
  89631. +
  89632. + if (isr & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
  89633. + sdhci_card_event(host->mmc);
  89634. + mmc_detect_change(host->mmc, msecs_to_jiffies(200));
  89635. + }
  89636. +
  89637. + if (isr & SDHCI_INT_CARD_INT) {
  89638. + sdio_run_irqs(host->mmc);
  89639. +
  89640. + spin_lock_irqsave(&host->lock, flags);
  89641. + if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
  89642. + sdhci_enable_sdio_irq_nolock(host, true);
  89643. + spin_unlock_irqrestore(&host->lock, flags);
  89644. + }
  89645. +
  89646. + return isr ? IRQ_HANDLED : IRQ_NONE;
  89647. +}
  89648. +
  89649. /*****************************************************************************\
  89650. * *
  89651. * Suspend/resume *
  89652. @@ -2548,6 +2522,7 @@
  89653. #ifdef CONFIG_PM
  89654. void sdhci_enable_irq_wakeups(struct sdhci_host *host)
  89655. {
  89656. + int gpio_cd = mmc_gpio_get_cd(host->mmc);
  89657. u8 val;
  89658. u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE
  89659. | SDHCI_WAKE_ON_INT;
  89660. @@ -2555,7 +2530,8 @@
  89661. val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
  89662. val |= mask ;
  89663. /* Avoid fake wake up */
  89664. - if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
  89665. + if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION ||
  89666. + !IS_ERR_VALUE(gpio_cd))
  89667. val &= ~(SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE);
  89668. sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
  89669. }
  89670. @@ -2575,9 +2551,6 @@
  89671. int sdhci_suspend_host(struct sdhci_host *host)
  89672. {
  89673. - if (host->ops->platform_suspend)
  89674. - host->ops->platform_suspend(host);
  89675. -
  89676. sdhci_disable_card_detection(host);
  89677. /* Disable tuning since we are suspending */
  89678. @@ -2587,7 +2560,9 @@
  89679. }
  89680. if (!device_may_wakeup(mmc_dev(host->mmc))) {
  89681. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  89682. + host->ier = 0;
  89683. + sdhci_writel(host, 0, SDHCI_INT_ENABLE);
  89684. + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
  89685. free_irq(host->irq, host);
  89686. } else {
  89687. sdhci_enable_irq_wakeups(host);
  89688. @@ -2608,8 +2583,9 @@
  89689. }
  89690. if (!device_may_wakeup(mmc_dev(host->mmc))) {
  89691. - ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
  89692. - mmc_hostname(host->mmc), host);
  89693. + ret = request_threaded_irq(host->irq, sdhci_irq,
  89694. + sdhci_thread_irq, IRQF_SHARED,
  89695. + mmc_hostname(host->mmc), host);
  89696. if (ret)
  89697. return ret;
  89698. } else {
  89699. @@ -2631,9 +2607,6 @@
  89700. sdhci_enable_card_detection(host);
  89701. - if (host->ops->platform_resume)
  89702. - host->ops->platform_resume(host);
  89703. -
  89704. /* Set the re-tuning expiration flag */
  89705. if (host->flags & SDHCI_USING_RETUNING_TIMER)
  89706. host->flags |= SDHCI_NEEDS_RETUNING;
  89707. @@ -2685,10 +2658,12 @@
  89708. }
  89709. spin_lock_irqsave(&host->lock, flags);
  89710. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  89711. + host->ier &= SDHCI_INT_CARD_INT;
  89712. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  89713. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  89714. spin_unlock_irqrestore(&host->lock, flags);
  89715. - synchronize_irq(host->irq);
  89716. + synchronize_hardirq(host->irq);
  89717. spin_lock_irqsave(&host->lock, flags);
  89718. host->runtime_suspended = true;
  89719. @@ -2732,7 +2707,7 @@
  89720. host->runtime_suspended = false;
  89721. /* Enable SDIO IRQ */
  89722. - if ((host->flags & SDHCI_SDIO_IRQ_ENABLED))
  89723. + if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
  89724. sdhci_enable_sdio_irq_nolock(host, true);
  89725. /* Enable Card Detection */
  89726. @@ -2791,7 +2766,7 @@
  89727. if (debug_quirks2)
  89728. host->quirks2 = debug_quirks2;
  89729. - sdhci_reset(host, SDHCI_RESET_ALL);
  89730. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  89731. host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
  89732. host->version = (host->version & SDHCI_SPEC_VER_MASK)
  89733. @@ -2851,15 +2826,29 @@
  89734. * (128) and potentially one alignment transfer for
  89735. * each of those entries.
  89736. */
  89737. - host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL);
  89738. + host->adma_desc = dma_alloc_coherent(mmc_dev(host->mmc),
  89739. + ADMA_SIZE, &host->adma_addr,
  89740. + GFP_KERNEL);
  89741. host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
  89742. if (!host->adma_desc || !host->align_buffer) {
  89743. - kfree(host->adma_desc);
  89744. + dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
  89745. + host->adma_desc, host->adma_addr);
  89746. kfree(host->align_buffer);
  89747. pr_warning("%s: Unable to allocate ADMA "
  89748. "buffers. Falling back to standard DMA.\n",
  89749. mmc_hostname(mmc));
  89750. host->flags &= ~SDHCI_USE_ADMA;
  89751. + host->adma_desc = NULL;
  89752. + host->align_buffer = NULL;
  89753. + } else if (host->adma_addr & 3) {
  89754. + pr_warning("%s: unable to allocate aligned ADMA descriptor\n",
  89755. + mmc_hostname(mmc));
  89756. + host->flags &= ~SDHCI_USE_ADMA;
  89757. + dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
  89758. + host->adma_desc, host->adma_addr);
  89759. + kfree(host->align_buffer);
  89760. + host->adma_desc = NULL;
  89761. + host->align_buffer = NULL;
  89762. }
  89763. }
  89764. @@ -2941,9 +2930,22 @@
  89765. if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
  89766. host->timeout_clk = mmc->f_max / 1000;
  89767. - mmc->max_discard_to = (1 << 27) / host->timeout_clk;
  89768. + if (host->quirks2 & SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER) {
  89769. + if (host->ops->get_max_timeout_counter) {
  89770. + mmc->max_discard_to =
  89771. + host->ops->get_max_timeout_counter(host)
  89772. + / host->timeout_clk;
  89773. + } else {
  89774. + pr_err("%s: Hardware doesn't specify max timeout "
  89775. + "counter\n", mmc_hostname(mmc));
  89776. + return -ENODEV;
  89777. + }
  89778. + } else {
  89779. + mmc->max_discard_to = (1 << 27) / host->timeout_clk;
  89780. + }
  89781. mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
  89782. + mmc->caps2 |= MMC_CAP2_SDIO_NOTHREAD;
  89783. if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
  89784. host->flags |= SDHCI_AUTO_CMD12;
  89785. @@ -3214,8 +3216,6 @@
  89786. /*
  89787. * Init tasklets.
  89788. */
  89789. - tasklet_init(&host->card_tasklet,
  89790. - sdhci_tasklet_card, (unsigned long)host);
  89791. tasklet_init(&host->finish_tasklet,
  89792. sdhci_tasklet_finish, (unsigned long)host);
  89793. @@ -3232,8 +3232,8 @@
  89794. sdhci_init(host, 0);
  89795. - ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
  89796. - mmc_hostname(mmc), host);
  89797. + ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq,
  89798. + IRQF_SHARED, mmc_hostname(mmc), host);
  89799. if (ret) {
  89800. pr_err("%s: Failed to request IRQ %d: %d\n",
  89801. mmc_hostname(mmc), host->irq, ret);
  89802. @@ -3275,12 +3275,12 @@
  89803. #ifdef SDHCI_USE_LEDS_CLASS
  89804. reset:
  89805. - sdhci_reset(host, SDHCI_RESET_ALL);
  89806. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  89807. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  89808. + sdhci_writel(host, 0, SDHCI_INT_ENABLE);
  89809. + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
  89810. free_irq(host->irq, host);
  89811. #endif
  89812. untasklet:
  89813. - tasklet_kill(&host->card_tasklet);
  89814. tasklet_kill(&host->finish_tasklet);
  89815. return ret;
  89816. @@ -3317,14 +3317,14 @@
  89817. #endif
  89818. if (!dead)
  89819. - sdhci_reset(host, SDHCI_RESET_ALL);
  89820. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  89821. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  89822. + sdhci_writel(host, 0, SDHCI_INT_ENABLE);
  89823. + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
  89824. free_irq(host->irq, host);
  89825. del_timer_sync(&host->timer);
  89826. - tasklet_kill(&host->card_tasklet);
  89827. tasklet_kill(&host->finish_tasklet);
  89828. if (host->vmmc) {
  89829. @@ -3337,7 +3337,9 @@
  89830. regulator_put(host->vqmmc);
  89831. }
  89832. - kfree(host->adma_desc);
  89833. + if (host->adma_desc)
  89834. + dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
  89835. + host->adma_desc, host->adma_addr);
  89836. kfree(host->align_buffer);
  89837. host->adma_desc = NULL;
  89838. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-cns3xxx.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-cns3xxx.c
  89839. --- linux-3.14.15/drivers/mmc/host/sdhci-cns3xxx.c 2014-07-31 23:51:43.000000000 +0200
  89840. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-cns3xxx.c 2014-08-20 19:31:45.980868370 +0200
  89841. @@ -30,13 +30,12 @@
  89842. u16 clk;
  89843. unsigned long timeout;
  89844. - if (clock == host->clock)
  89845. - return;
  89846. + host->mmc->actual_clock = 0;
  89847. sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
  89848. if (clock == 0)
  89849. - goto out;
  89850. + return;
  89851. while (host->max_clk / div > clock) {
  89852. /*
  89853. @@ -75,13 +74,14 @@
  89854. clk |= SDHCI_CLOCK_CARD_EN;
  89855. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  89856. -out:
  89857. - host->clock = clock;
  89858. }
  89859. static const struct sdhci_ops sdhci_cns3xxx_ops = {
  89860. .get_max_clock = sdhci_cns3xxx_get_max_clk,
  89861. .set_clock = sdhci_cns3xxx_set_clock,
  89862. + .set_bus_width = sdhci_set_bus_width,
  89863. + .reset = sdhci_reset,
  89864. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  89865. };
  89866. static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
  89867. @@ -90,8 +90,7 @@
  89868. SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
  89869. SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
  89870. SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
  89871. - SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
  89872. - SDHCI_QUIRK_NONSTANDARD_CLOCK,
  89873. + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
  89874. };
  89875. static int sdhci_cns3xxx_probe(struct platform_device *pdev)
  89876. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-dove.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-dove.c
  89877. --- linux-3.14.15/drivers/mmc/host/sdhci-dove.c 2014-07-31 23:51:43.000000000 +0200
  89878. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-dove.c 2014-08-20 19:31:45.980868370 +0200
  89879. @@ -86,6 +86,10 @@
  89880. static const struct sdhci_ops sdhci_dove_ops = {
  89881. .read_w = sdhci_dove_readw,
  89882. .read_l = sdhci_dove_readl,
  89883. + .set_clock = sdhci_set_clock,
  89884. + .set_bus_width = sdhci_set_bus_width,
  89885. + .reset = sdhci_reset,
  89886. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  89887. };
  89888. static const struct sdhci_pltfm_data sdhci_dove_pdata = {
  89889. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-esdhc.h linux-linaro-stable-mx6/drivers/mmc/host/sdhci-esdhc.h
  89890. --- linux-3.14.15/drivers/mmc/host/sdhci-esdhc.h 2014-07-31 23:51:43.000000000 +0200
  89891. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-esdhc.h 2014-08-20 19:31:45.980868370 +0200
  89892. @@ -20,12 +20,11 @@
  89893. #define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
  89894. SDHCI_QUIRK_NO_BUSY_IRQ | \
  89895. - SDHCI_QUIRK_NONSTANDARD_CLOCK | \
  89896. SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
  89897. - SDHCI_QUIRK_PIO_NEEDS_DELAY | \
  89898. - SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
  89899. + SDHCI_QUIRK_PIO_NEEDS_DELAY)
  89900. #define ESDHC_SYSTEM_CONTROL 0x2c
  89901. +#define ESDHC_SYS_CTRL_RSTA (1 << 24)
  89902. #define ESDHC_CLOCK_MASK 0x0000fff0
  89903. #define ESDHC_PREDIV_SHIFT 8
  89904. #define ESDHC_DIVIDER_SHIFT 4
  89905. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-esdhc-imx.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-esdhc-imx.c
  89906. --- linux-3.14.15/drivers/mmc/host/sdhci-esdhc-imx.c 2014-07-31 23:51:43.000000000 +0200
  89907. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-esdhc-imx.c 2014-08-20 19:31:45.980868370 +0200
  89908. @@ -11,6 +11,7 @@
  89909. * the Free Software Foundation; either version 2 of the License.
  89910. */
  89911. +#include <linux/busfreq-imx6.h>
  89912. #include <linux/io.h>
  89913. #include <linux/delay.h>
  89914. #include <linux/err.h>
  89915. @@ -114,6 +115,10 @@
  89916. #define ESDHC_FLAG_STD_TUNING BIT(5)
  89917. /* The IP has SDHCI_CAPABILITIES_1 register */
  89918. #define ESDHC_FLAG_HAVE_CAP1 BIT(6)
  89919. +/* The IP has errata ERR004536 */
  89920. +#define ESDHC_FLAG_ERR004536 BIT(7)
  89921. +/* need request bus freq during low power */
  89922. +#define ESDHC_FLAG_BUSFREQ BIT(8)
  89923. struct esdhc_soc_data {
  89924. u32 flags;
  89925. @@ -141,7 +146,8 @@
  89926. static struct esdhc_soc_data usdhc_imx6sl_data = {
  89927. .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
  89928. - | ESDHC_FLAG_HAVE_CAP1,
  89929. + | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_ERR004536
  89930. + | ESDHC_FLAG_BUSFREQ,
  89931. };
  89932. struct pltfm_imx_data {
  89933. @@ -160,7 +166,6 @@
  89934. MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */
  89935. WAIT_FOR_INT, /* sent CMD12, waiting for response INT */
  89936. } multiblock_status;
  89937. - u32 uhs_mode;
  89938. u32 is_ddr;
  89939. };
  89940. @@ -382,7 +387,6 @@
  89941. if (val & ESDHC_MIX_CTRL_SMPCLK_SEL)
  89942. ret |= SDHCI_CTRL_TUNED_CLK;
  89943. - ret |= (imx_data->uhs_mode & SDHCI_CTRL_UHS_MASK);
  89944. ret &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
  89945. return ret;
  89946. @@ -429,7 +433,6 @@
  89947. else
  89948. new_val &= ~ESDHC_VENDOR_SPEC_VSELECT;
  89949. writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC);
  89950. - imx_data->uhs_mode = val & SDHCI_CTRL_UHS_MASK;
  89951. if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) {
  89952. new_val = readl(host->ioaddr + ESDHC_MIX_CTRL);
  89953. if (val & SDHCI_CTRL_TUNED_CLK)
  89954. @@ -600,12 +603,14 @@
  89955. u32 temp, val;
  89956. if (clock == 0) {
  89957. + host->mmc->actual_clock = 0;
  89958. +
  89959. if (esdhc_is_usdhc(imx_data)) {
  89960. val = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
  89961. writel(val & ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
  89962. host->ioaddr + ESDHC_VENDOR_SPEC);
  89963. }
  89964. - goto out;
  89965. + return;
  89966. }
  89967. if (esdhc_is_usdhc(imx_data) && !imx_data->is_ddr)
  89968. @@ -645,8 +650,6 @@
  89969. }
  89970. mdelay(1);
  89971. -out:
  89972. - host->clock = clock;
  89973. }
  89974. static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
  89975. @@ -668,7 +671,7 @@
  89976. return -ENOSYS;
  89977. }
  89978. -static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
  89979. +static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
  89980. {
  89981. u32 ctrl;
  89982. @@ -686,17 +689,56 @@
  89983. esdhc_clrset_le(host, ESDHC_CTRL_BUSWIDTH_MASK, ctrl,
  89984. SDHCI_HOST_CONTROL);
  89985. +}
  89986. - return 0;
  89987. +static void esdhc_tuning_reset(struct sdhci_host *host, u32 rst_bits)
  89988. +{
  89989. + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  89990. + struct pltfm_imx_data *imx_data = pltfm_host->priv;
  89991. + u32 timeout;
  89992. + u32 reg;
  89993. +
  89994. + reg = readl(host->ioaddr + ESDHC_SYSTEM_CONTROL);
  89995. + reg |= rst_bits;
  89996. + writel(reg, host->ioaddr + ESDHC_SYSTEM_CONTROL);
  89997. +
  89998. + /* Wait for max 100ms */
  89999. + timeout = 100;
  90000. +
  90001. + /* hw clears the bit when it's done */
  90002. + while (readl(host->ioaddr + ESDHC_SYSTEM_CONTROL) & rst_bits) {
  90003. + if (timeout == 0) {
  90004. + dev_err(mmc_dev(host->mmc),
  90005. + "Reset never completes!\n");
  90006. + return;
  90007. + }
  90008. + timeout--;
  90009. + mdelay(1);
  90010. + }
  90011. +
  90012. + /*
  90013. + * The RSTA, reset all, on usdhc will not clear following regs:
  90014. + * > SDHCI_MIX_CTRL
  90015. + * > SDHCI_TUNE_CTRL_STATUS
  90016. + *
  90017. + * Do it manually here.
  90018. + */
  90019. + if ((rst_bits & ESDHC_SYS_CTRL_RSTA) && is_imx6q_usdhc(imx_data)) {
  90020. + writel(0, host->ioaddr + ESDHC_MIX_CTRL);
  90021. + writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS);
  90022. + /* FIXME: delay for clear tuning status or some cards may not work */
  90023. + mdelay(1);
  90024. + }
  90025. }
  90026. static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
  90027. {
  90028. u32 reg;
  90029. - /* FIXME: delay a bit for card to be ready for next tuning due to errors */
  90030. - mdelay(1);
  90031. + /* reset controller before tuning or it may fail on some cards */
  90032. + esdhc_tuning_reset(host, ESDHC_SYS_CTRL_RSTA);
  90033. + /* This is balanced by the runtime put in sdhci_tasklet_finish */
  90034. pm_runtime_get_sync(host->mmc->parent);
  90035. reg = readl(host->ioaddr + ESDHC_MIX_CTRL);
  90036. reg |= ESDHC_MIX_CTRL_EXE_TUNE | ESDHC_MIX_CTRL_SMPCLK_SEL |
  90037. @@ -713,13 +755,12 @@
  90038. complete(&mrq->completion);
  90039. }
  90040. -static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode)
  90041. +static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode,
  90042. + struct scatterlist *sg)
  90043. {
  90044. struct mmc_command cmd = {0};
  90045. struct mmc_request mrq = {NULL};
  90046. struct mmc_data data = {0};
  90047. - struct scatterlist sg;
  90048. - char tuning_pattern[ESDHC_TUNING_BLOCK_PATTERN_LEN];
  90049. cmd.opcode = opcode;
  90050. cmd.arg = 0;
  90051. @@ -728,11 +769,9 @@
  90052. data.blksz = ESDHC_TUNING_BLOCK_PATTERN_LEN;
  90053. data.blocks = 1;
  90054. data.flags = MMC_DATA_READ;
  90055. - data.sg = &sg;
  90056. + data.sg = sg;
  90057. data.sg_len = 1;
  90058. - sg_init_one(&sg, tuning_pattern, sizeof(tuning_pattern));
  90059. -
  90060. mrq.cmd = &cmd;
  90061. mrq.cmd->mrq = &mrq;
  90062. mrq.data = &data;
  90063. @@ -742,14 +781,12 @@
  90064. mrq.done = esdhc_request_done;
  90065. init_completion(&(mrq.completion));
  90066. - disable_irq(host->irq);
  90067. - spin_lock(&host->lock);
  90068. + spin_lock_irq(&host->lock);
  90069. host->mrq = &mrq;
  90070. sdhci_send_command(host, mrq.cmd);
  90071. - spin_unlock(&host->lock);
  90072. - enable_irq(host->irq);
  90073. + spin_unlock_irq(&host->lock);
  90074. wait_for_completion(&mrq.completion);
  90075. @@ -772,13 +809,21 @@
  90076. static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
  90077. {
  90078. + struct scatterlist sg;
  90079. + char *tuning_pattern;
  90080. int min, max, avg, ret;
  90081. + tuning_pattern = kmalloc(ESDHC_TUNING_BLOCK_PATTERN_LEN, GFP_KERNEL);
  90082. + if (!tuning_pattern)
  90083. + return -ENOMEM;
  90084. +
  90085. + sg_init_one(&sg, tuning_pattern, ESDHC_TUNING_BLOCK_PATTERN_LEN);
  90086. +
  90087. /* find the mininum delay first which can pass tuning */
  90088. min = ESDHC_TUNE_CTRL_MIN;
  90089. while (min < ESDHC_TUNE_CTRL_MAX) {
  90090. esdhc_prepare_tuning(host, min);
  90091. - if (!esdhc_send_tuning_cmd(host, opcode))
  90092. + if (!esdhc_send_tuning_cmd(host, opcode, &sg))
  90093. break;
  90094. min += ESDHC_TUNE_CTRL_STEP;
  90095. }
  90096. @@ -787,7 +832,7 @@
  90097. max = min + ESDHC_TUNE_CTRL_STEP;
  90098. while (max < ESDHC_TUNE_CTRL_MAX) {
  90099. esdhc_prepare_tuning(host, max);
  90100. - if (esdhc_send_tuning_cmd(host, opcode)) {
  90101. + if (esdhc_send_tuning_cmd(host, opcode, &sg)) {
  90102. max -= ESDHC_TUNE_CTRL_STEP;
  90103. break;
  90104. }
  90105. @@ -797,9 +842,11 @@
  90106. /* use average delay to get the best timing */
  90107. avg = (min + max) / 2;
  90108. esdhc_prepare_tuning(host, avg);
  90109. - ret = esdhc_send_tuning_cmd(host, opcode);
  90110. + ret = esdhc_send_tuning_cmd(host, opcode, &sg);
  90111. esdhc_post_tuning(host);
  90112. + kfree(tuning_pattern);
  90113. +
  90114. dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n",
  90115. ret ? "failed" : "passed", avg, ret);
  90116. @@ -837,28 +884,20 @@
  90117. return pinctrl_select_state(imx_data->pinctrl, pinctrl);
  90118. }
  90119. -static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
  90120. +static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
  90121. {
  90122. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  90123. struct pltfm_imx_data *imx_data = pltfm_host->priv;
  90124. struct esdhc_platform_data *boarddata = &imx_data->boarddata;
  90125. - switch (uhs) {
  90126. + switch (timing) {
  90127. case MMC_TIMING_UHS_SDR12:
  90128. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR12;
  90129. - break;
  90130. case MMC_TIMING_UHS_SDR25:
  90131. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR25;
  90132. - break;
  90133. case MMC_TIMING_UHS_SDR50:
  90134. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR50;
  90135. - break;
  90136. case MMC_TIMING_UHS_SDR104:
  90137. case MMC_TIMING_MMC_HS200:
  90138. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR104;
  90139. break;
  90140. case MMC_TIMING_UHS_DDR50:
  90141. - imx_data->uhs_mode = SDHCI_CTRL_UHS_DDR50;
  90142. writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
  90143. ESDHC_MIX_CTRL_DDREN,
  90144. host->ioaddr + ESDHC_MIX_CTRL);
  90145. @@ -875,7 +914,20 @@
  90146. break;
  90147. }
  90148. - return esdhc_change_pinstate(host, uhs);
  90149. + esdhc_change_pinstate(host, timing);
  90150. +}
  90151. +
  90152. +static void esdhc_reset(struct sdhci_host *host, u8 mask)
  90153. +{
  90154. + sdhci_reset(host, mask);
  90155. +
  90156. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  90157. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  90158. +}
  90159. +
  90160. +static unsigned int esdhc_get_max_timeout_counter(struct sdhci_host *host)
  90161. +{
  90162. + return 1 << 28;
  90163. }
  90164. static struct sdhci_ops sdhci_esdhc_ops = {
  90165. @@ -888,8 +940,9 @@
  90166. .get_max_clock = esdhc_pltfm_get_max_clock,
  90167. .get_min_clock = esdhc_pltfm_get_min_clock,
  90168. .get_ro = esdhc_pltfm_get_ro,
  90169. - .platform_bus_width = esdhc_pltfm_bus_width,
  90170. + .set_bus_width = esdhc_pltfm_set_bus_width,
  90171. .set_uhs_signaling = esdhc_set_uhs_signaling,
  90172. + .reset = esdhc_reset,
  90173. };
  90174. static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
  90175. @@ -906,6 +959,7 @@
  90176. struct esdhc_platform_data *boarddata)
  90177. {
  90178. struct device_node *np = pdev->dev.of_node;
  90179. + struct sdhci_host *host = platform_get_drvdata(pdev);
  90180. if (!np)
  90181. return -ENODEV;
  90182. @@ -939,6 +993,12 @@
  90183. if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line))
  90184. boarddata->delay_line = 0;
  90185. + if (of_find_property(np, "keep-power-in-suspend", NULL))
  90186. + host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
  90187. +
  90188. + if (of_find_property(np, "enable-sdio-wakeup", NULL))
  90189. + host->mmc->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
  90190. +
  90191. return 0;
  90192. }
  90193. #else
  90194. @@ -994,6 +1054,9 @@
  90195. goto free_sdhci;
  90196. }
  90197. + if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
  90198. + request_bus_freq(BUS_FREQ_HIGH);
  90199. +
  90200. pltfm_host->clk = imx_data->clk_per;
  90201. pltfm_host->clock = clk_get_rate(pltfm_host->clk);
  90202. clk_prepare_enable(imx_data->clk_per);
  90203. @@ -1027,8 +1090,17 @@
  90204. */
  90205. if (esdhc_is_usdhc(imx_data)) {
  90206. writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
  90207. - host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
  90208. + host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
  90209. + SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER;
  90210. host->mmc->caps |= MMC_CAP_1_8V_DDR;
  90211. +
  90212. + /*
  90213. + * errata ESDHC_FLAG_ERR004536 fix for MX6Q TO1.2 and MX6DL
  90214. + * TO1.1, it's harmless for MX6SL
  90215. + */
  90216. + writel(readl(host->ioaddr + 0x6c) | BIT(7), host->ioaddr + 0x6c);
  90217. + sdhci_esdhc_ops.get_max_timeout_counter =
  90218. + esdhc_get_max_timeout_counter;
  90219. }
  90220. if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
  90221. @@ -1040,6 +1112,9 @@
  90222. ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP,
  90223. host->ioaddr + ESDHC_TUNING_CTRL);
  90224. + if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
  90225. + host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
  90226. +
  90227. boarddata = &imx_data->boarddata;
  90228. if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
  90229. if (!host->mmc->parent->platform_data) {
  90230. @@ -1116,6 +1191,10 @@
  90231. host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
  90232. }
  90233. + if (host->mmc->pm_caps & MMC_PM_KEEP_POWER &&
  90234. + host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ)
  90235. + device_init_wakeup(&pdev->dev, 1);
  90236. +
  90237. err = sdhci_add_host(host);
  90238. if (err)
  90239. goto disable_clk;
  90240. @@ -1132,6 +1211,8 @@
  90241. clk_disable_unprepare(imx_data->clk_per);
  90242. clk_disable_unprepare(imx_data->clk_ipg);
  90243. clk_disable_unprepare(imx_data->clk_ahb);
  90244. + if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
  90245. + release_bus_freq(BUS_FREQ_HIGH);
  90246. free_sdhci:
  90247. sdhci_pltfm_free(pdev);
  90248. return err;
  90249. @@ -1170,10 +1251,15 @@
  90250. ret = sdhci_runtime_suspend_host(host);
  90251. - clk_disable_unprepare(imx_data->clk_per);
  90252. - clk_disable_unprepare(imx_data->clk_ipg);
  90253. + if (!sdhci_sdio_irq_enabled(host)) {
  90254. + clk_disable_unprepare(imx_data->clk_per);
  90255. + clk_disable_unprepare(imx_data->clk_ipg);
  90256. + }
  90257. clk_disable_unprepare(imx_data->clk_ahb);
  90258. + if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
  90259. + release_bus_freq(BUS_FREQ_HIGH);
  90260. +
  90261. return ret;
  90262. }
  90263. @@ -1183,8 +1269,10 @@
  90264. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  90265. struct pltfm_imx_data *imx_data = pltfm_host->priv;
  90266. - clk_prepare_enable(imx_data->clk_per);
  90267. - clk_prepare_enable(imx_data->clk_ipg);
  90268. + if (!sdhci_sdio_irq_enabled(host)) {
  90269. + clk_prepare_enable(imx_data->clk_per);
  90270. + clk_prepare_enable(imx_data->clk_ipg);
  90271. + }
  90272. clk_prepare_enable(imx_data->clk_ahb);
  90273. return sdhci_runtime_resume_host(host);
  90274. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci.h linux-linaro-stable-mx6/drivers/mmc/host/sdhci.h
  90275. --- linux-3.14.15/drivers/mmc/host/sdhci.h 2014-07-31 23:51:43.000000000 +0200
  90276. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci.h 2014-08-20 19:31:45.996868438 +0200
  90277. @@ -281,18 +281,15 @@
  90278. unsigned int (*get_max_clock)(struct sdhci_host *host);
  90279. unsigned int (*get_min_clock)(struct sdhci_host *host);
  90280. unsigned int (*get_timeout_clock)(struct sdhci_host *host);
  90281. - int (*platform_bus_width)(struct sdhci_host *host,
  90282. - int width);
  90283. + unsigned int (*get_max_timeout_counter)(struct sdhci_host *host);
  90284. + void (*set_bus_width)(struct sdhci_host *host, int width);
  90285. void (*platform_send_init_74_clocks)(struct sdhci_host *host,
  90286. u8 power_mode);
  90287. unsigned int (*get_ro)(struct sdhci_host *host);
  90288. - void (*platform_reset_enter)(struct sdhci_host *host, u8 mask);
  90289. - void (*platform_reset_exit)(struct sdhci_host *host, u8 mask);
  90290. + void (*reset)(struct sdhci_host *host, u8 mask);
  90291. int (*platform_execute_tuning)(struct sdhci_host *host, u32 opcode);
  90292. - int (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
  90293. + void (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
  90294. void (*hw_reset)(struct sdhci_host *host);
  90295. - void (*platform_suspend)(struct sdhci_host *host);
  90296. - void (*platform_resume)(struct sdhci_host *host);
  90297. void (*adma_workaround)(struct sdhci_host *host, u32 intmask);
  90298. void (*platform_init)(struct sdhci_host *host);
  90299. void (*card_event)(struct sdhci_host *host);
  90300. @@ -397,6 +394,16 @@
  90301. extern void sdhci_send_command(struct sdhci_host *host,
  90302. struct mmc_command *cmd);
  90303. +static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
  90304. +{
  90305. + return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
  90306. +}
  90307. +
  90308. +void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
  90309. +void sdhci_set_bus_width(struct sdhci_host *host, int width);
  90310. +void sdhci_reset(struct sdhci_host *host, u8 mask);
  90311. +void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
  90312. +
  90313. #ifdef CONFIG_PM
  90314. extern int sdhci_suspend_host(struct sdhci_host *host);
  90315. extern int sdhci_resume_host(struct sdhci_host *host);
  90316. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-of-arasan.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-of-arasan.c
  90317. --- linux-3.14.15/drivers/mmc/host/sdhci-of-arasan.c 2014-07-31 23:51:43.000000000 +0200
  90318. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-of-arasan.c 2014-08-20 19:31:45.984868388 +0200
  90319. @@ -52,8 +52,12 @@
  90320. }
  90321. static struct sdhci_ops sdhci_arasan_ops = {
  90322. + .set_clock = sdhci_set_clock,
  90323. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  90324. .get_timeout_clock = sdhci_arasan_get_timeout_clock,
  90325. + .set_bus_width = sdhci_set_bus_width,
  90326. + .reset = sdhci_reset,
  90327. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90328. };
  90329. static struct sdhci_pltfm_data sdhci_arasan_pdata = {
  90330. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-of-esdhc.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-of-esdhc.c
  90331. --- linux-3.14.15/drivers/mmc/host/sdhci-of-esdhc.c 2014-07-31 23:51:43.000000000 +0200
  90332. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-of-esdhc.c 2014-08-20 19:31:45.984868388 +0200
  90333. @@ -199,13 +199,14 @@
  90334. static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
  90335. {
  90336. -
  90337. int pre_div = 2;
  90338. int div = 1;
  90339. u32 temp;
  90340. + host->mmc->actual_clock = 0;
  90341. +
  90342. if (clock == 0)
  90343. - goto out;
  90344. + return;
  90345. /* Workaround to reduce the clock frequency for p1010 esdhc */
  90346. if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
  90347. @@ -238,24 +239,8 @@
  90348. | (pre_div << ESDHC_PREDIV_SHIFT));
  90349. sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
  90350. mdelay(1);
  90351. -out:
  90352. - host->clock = clock;
  90353. }
  90354. -#ifdef CONFIG_PM
  90355. -static u32 esdhc_proctl;
  90356. -static void esdhc_of_suspend(struct sdhci_host *host)
  90357. -{
  90358. - esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
  90359. -}
  90360. -
  90361. -static void esdhc_of_resume(struct sdhci_host *host)
  90362. -{
  90363. - esdhc_of_enable_dma(host);
  90364. - sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
  90365. -}
  90366. -#endif
  90367. -
  90368. static void esdhc_of_platform_init(struct sdhci_host *host)
  90369. {
  90370. u32 vvn;
  90371. @@ -269,7 +254,7 @@
  90372. host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
  90373. }
  90374. -static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
  90375. +static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
  90376. {
  90377. u32 ctrl;
  90378. @@ -289,8 +274,6 @@
  90379. clrsetbits_be32(host->ioaddr + SDHCI_HOST_CONTROL,
  90380. ESDHC_CTRL_BUSWIDTH_MASK, ctrl);
  90381. -
  90382. - return 0;
  90383. }
  90384. static const struct sdhci_ops sdhci_esdhc_ops = {
  90385. @@ -305,13 +288,46 @@
  90386. .get_max_clock = esdhc_of_get_max_clock,
  90387. .get_min_clock = esdhc_of_get_min_clock,
  90388. .platform_init = esdhc_of_platform_init,
  90389. -#ifdef CONFIG_PM
  90390. - .platform_suspend = esdhc_of_suspend,
  90391. - .platform_resume = esdhc_of_resume,
  90392. -#endif
  90393. .adma_workaround = esdhci_of_adma_workaround,
  90394. - .platform_bus_width = esdhc_pltfm_bus_width,
  90395. + .set_bus_width = esdhc_pltfm_set_bus_width,
  90396. + .reset = sdhci_reset,
  90397. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90398. +};
  90399. +
  90400. +#ifdef CONFIG_PM
  90401. +
  90402. +static u32 esdhc_proctl;
  90403. +static int esdhc_of_suspend(struct device *dev)
  90404. +{
  90405. + struct sdhci_host *host = dev_get_drvdata(dev);
  90406. +
  90407. + esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
  90408. +
  90409. + return sdhci_suspend_host(host);
  90410. +}
  90411. +
  90412. +static void esdhc_of_resume(device *dev)
  90413. +{
  90414. + struct sdhci_host *host = dev_get_drvdata(dev);
  90415. + int ret = sdhci_resume_host(host);
  90416. +
  90417. + if (ret == 0) {
  90418. + /* Isn't this already done by sdhci_resume_host() ? --rmk */
  90419. + esdhc_of_enable_dma(host);
  90420. + sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
  90421. + }
  90422. +
  90423. + return ret;
  90424. +}
  90425. +
  90426. +static const struct dev_pm_ops esdhc_pmops = {
  90427. + .suspend = esdhci_of_suspend,
  90428. + .resume = esdhci_of_resume,
  90429. };
  90430. +#define ESDHC_PMOPS (&esdhc_pmops)
  90431. +#else
  90432. +#define ESDHC_PMOPS NULL
  90433. +#endif
  90434. static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
  90435. /*
  90436. @@ -374,7 +390,7 @@
  90437. .name = "sdhci-esdhc",
  90438. .owner = THIS_MODULE,
  90439. .of_match_table = sdhci_esdhc_of_match,
  90440. - .pm = SDHCI_PLTFM_PMOPS,
  90441. + .pm = ESDHC_PMOPS,
  90442. },
  90443. .probe = sdhci_esdhc_probe,
  90444. .remove = sdhci_esdhc_remove,
  90445. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-of-hlwd.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-of-hlwd.c
  90446. --- linux-3.14.15/drivers/mmc/host/sdhci-of-hlwd.c 2014-07-31 23:51:43.000000000 +0200
  90447. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-of-hlwd.c 2014-08-20 19:31:45.984868388 +0200
  90448. @@ -58,6 +58,10 @@
  90449. .write_l = sdhci_hlwd_writel,
  90450. .write_w = sdhci_hlwd_writew,
  90451. .write_b = sdhci_hlwd_writeb,
  90452. + .set_clock = sdhci_set_clock,
  90453. + .set_bus_width = sdhci_set_bus_width,
  90454. + .reset = sdhci_reset,
  90455. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90456. };
  90457. static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
  90458. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-pci.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-pci.c
  90459. --- linux-3.14.15/drivers/mmc/host/sdhci-pci.c 2014-07-31 23:51:43.000000000 +0200
  90460. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-pci.c 2014-08-20 19:31:45.988868406 +0200
  90461. @@ -1011,7 +1011,7 @@
  90462. return 0;
  90463. }
  90464. -static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
  90465. +static void sdhci_pci_set_bus_width(struct sdhci_host *host, int width)
  90466. {
  90467. u8 ctrl;
  90468. @@ -1032,8 +1032,6 @@
  90469. }
  90470. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  90471. -
  90472. - return 0;
  90473. }
  90474. static void sdhci_pci_gpio_hw_reset(struct sdhci_host *host)
  90475. @@ -1060,8 +1058,11 @@
  90476. }
  90477. static const struct sdhci_ops sdhci_pci_ops = {
  90478. + .set_clock = sdhci_set_clock,
  90479. .enable_dma = sdhci_pci_enable_dma,
  90480. - .platform_bus_width = sdhci_pci_bus_width,
  90481. + .set_bus_width = sdhci_pci_set_bus_width,
  90482. + .reset = sdhci_reset,
  90483. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90484. .hw_reset = sdhci_pci_hw_reset,
  90485. };
  90486. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-pltfm.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-pltfm.c
  90487. --- linux-3.14.15/drivers/mmc/host/sdhci-pltfm.c 2014-07-31 23:51:43.000000000 +0200
  90488. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-pltfm.c 2014-08-20 19:31:45.988868406 +0200
  90489. @@ -45,6 +45,10 @@
  90490. EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
  90491. static const struct sdhci_ops sdhci_pltfm_ops = {
  90492. + .set_clock = sdhci_set_clock,
  90493. + .set_bus_width = sdhci_set_bus_width,
  90494. + .reset = sdhci_reset,
  90495. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90496. };
  90497. #ifdef CONFIG_OF
  90498. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-pxav2.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-pxav2.c
  90499. --- linux-3.14.15/drivers/mmc/host/sdhci-pxav2.c 2014-07-31 23:51:43.000000000 +0200
  90500. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-pxav2.c 2014-08-20 19:31:45.992868421 +0200
  90501. @@ -51,11 +51,13 @@
  90502. #define MMC_CARD 0x1000
  90503. #define MMC_WIDTH 0x0100
  90504. -static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask)
  90505. +static void pxav2_reset(struct sdhci_host *host, u8 mask)
  90506. {
  90507. struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
  90508. struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
  90509. + sdhci_reset(host, mask);
  90510. +
  90511. if (mask == SDHCI_RESET_ALL) {
  90512. u16 tmp = 0;
  90513. @@ -88,7 +90,7 @@
  90514. }
  90515. }
  90516. -static int pxav2_mmc_set_width(struct sdhci_host *host, int width)
  90517. +static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
  90518. {
  90519. u8 ctrl;
  90520. u16 tmp;
  90521. @@ -107,14 +109,14 @@
  90522. }
  90523. writew(tmp, host->ioaddr + SD_CE_ATA_2);
  90524. writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
  90525. -
  90526. - return 0;
  90527. }
  90528. static const struct sdhci_ops pxav2_sdhci_ops = {
  90529. + .set_clock = sdhci_set_clock,
  90530. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  90531. - .platform_reset_exit = pxav2_set_private_registers,
  90532. - .platform_bus_width = pxav2_mmc_set_width,
  90533. + .set_bus_width = pxav2_mmc_set_bus_width,
  90534. + .reset = pxav2_reset,
  90535. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90536. };
  90537. #ifdef CONFIG_OF
  90538. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-pxav3.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-pxav3.c
  90539. --- linux-3.14.15/drivers/mmc/host/sdhci-pxav3.c 2014-07-31 23:51:43.000000000 +0200
  90540. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-pxav3.c 2014-08-20 19:31:45.992868421 +0200
  90541. @@ -57,11 +57,13 @@
  90542. #define SDCE_MISC_INT (1<<2)
  90543. #define SDCE_MISC_INT_EN (1<<1)
  90544. -static void pxav3_set_private_registers(struct sdhci_host *host, u8 mask)
  90545. +static void pxav3_reset(struct sdhci_host *host, u8 mask)
  90546. {
  90547. struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
  90548. struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
  90549. + sdhci_reset(host, mask);
  90550. +
  90551. if (mask == SDHCI_RESET_ALL) {
  90552. /*
  90553. * tune timing of read data/command when crc error happen
  90554. @@ -129,7 +131,7 @@
  90555. pxa->power_mode = power_mode;
  90556. }
  90557. -static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
  90558. +static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
  90559. {
  90560. u16 ctrl_2;
  90561. @@ -163,15 +165,16 @@
  90562. dev_dbg(mmc_dev(host->mmc),
  90563. "%s uhs = %d, ctrl_2 = %04X\n",
  90564. __func__, uhs, ctrl_2);
  90565. -
  90566. - return 0;
  90567. }
  90568. static const struct sdhci_ops pxav3_sdhci_ops = {
  90569. - .platform_reset_exit = pxav3_set_private_registers,
  90570. + .set_clock = sdhci_set_clock,
  90571. .set_uhs_signaling = pxav3_set_uhs_signaling,
  90572. .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
  90573. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  90574. + .set_bus_width = sdhci_set_bus_width,
  90575. + .reset = pxav3_reset,
  90576. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90577. };
  90578. static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
  90579. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-s3c.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-s3c.c
  90580. --- linux-3.14.15/drivers/mmc/host/sdhci-s3c.c 2014-07-31 23:51:43.000000000 +0200
  90581. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-s3c.c 2014-08-20 19:31:45.992868421 +0200
  90582. @@ -57,6 +57,8 @@
  90583. struct clk *clk_io;
  90584. struct clk *clk_bus[MAX_BUS_CLK];
  90585. +
  90586. + bool no_divider;
  90587. };
  90588. /**
  90589. @@ -69,6 +71,7 @@
  90590. */
  90591. struct sdhci_s3c_drv_data {
  90592. unsigned int sdhci_quirks;
  90593. + bool no_divider;
  90594. };
  90595. static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
  90596. @@ -153,7 +156,7 @@
  90597. * If controller uses a non-standard clock division, find the best clock
  90598. * speed possible with selected clock source and skip the division.
  90599. */
  90600. - if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
  90601. + if (ourhost->no_divider) {
  90602. rate = clk_round_rate(clksrc, wanted);
  90603. return wanted - rate;
  90604. }
  90605. @@ -188,9 +191,13 @@
  90606. int src;
  90607. u32 ctrl;
  90608. + host->mmc->actual_clock = 0;
  90609. +
  90610. /* don't bother if the clock is going off. */
  90611. - if (clock == 0)
  90612. + if (clock == 0) {
  90613. + sdhci_set_clock(host, clock);
  90614. return;
  90615. + }
  90616. for (src = 0; src < MAX_BUS_CLK; src++) {
  90617. delta = sdhci_s3c_consider_clock(ourhost, src, clock);
  90618. @@ -240,6 +247,8 @@
  90619. if (clock < 25 * 1000000)
  90620. ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2);
  90621. writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3);
  90622. +
  90623. + sdhci_set_clock(host, clock);
  90624. }
  90625. /**
  90626. @@ -296,10 +305,11 @@
  90627. unsigned long timeout;
  90628. u16 clk = 0;
  90629. + host->mmc->actual_clock = 0;
  90630. +
  90631. /* If the clock is going off, set to 0 at clock control register */
  90632. if (clock == 0) {
  90633. sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
  90634. - host->clock = clock;
  90635. return;
  90636. }
  90637. @@ -307,8 +317,6 @@
  90638. clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
  90639. - host->clock = clock;
  90640. -
  90641. clk = SDHCI_CLOCK_INT_EN;
  90642. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  90643. @@ -330,14 +338,14 @@
  90644. }
  90645. /**
  90646. - * sdhci_s3c_platform_bus_width - support 8bit buswidth
  90647. + * sdhci_s3c_set_bus_width - support 8bit buswidth
  90648. * @host: The SDHCI host being queried
  90649. * @width: MMC_BUS_WIDTH_ macro for the bus width being requested
  90650. *
  90651. * We have 8-bit width support but is not a v3 controller.
  90652. * So we add platform_bus_width() and support 8bit width.
  90653. */
  90654. -static int sdhci_s3c_platform_bus_width(struct sdhci_host *host, int width)
  90655. +static void sdhci_s3c_set_bus_width(struct sdhci_host *host, int width)
  90656. {
  90657. u8 ctrl;
  90658. @@ -359,15 +367,15 @@
  90659. }
  90660. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  90661. -
  90662. - return 0;
  90663. }
  90664. static struct sdhci_ops sdhci_s3c_ops = {
  90665. .get_max_clock = sdhci_s3c_get_max_clk,
  90666. .set_clock = sdhci_s3c_set_clock,
  90667. .get_min_clock = sdhci_s3c_get_min_clock,
  90668. - .platform_bus_width = sdhci_s3c_platform_bus_width,
  90669. + .set_bus_width = sdhci_s3c_set_bus_width,
  90670. + .reset = sdhci_reset,
  90671. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90672. };
  90673. static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
  90674. @@ -617,8 +625,10 @@
  90675. /* Setup quirks for the controller */
  90676. host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
  90677. host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
  90678. - if (drv_data)
  90679. + if (drv_data) {
  90680. host->quirks |= drv_data->sdhci_quirks;
  90681. + sc->no_divider = drv_data->no_divider;
  90682. + }
  90683. #ifndef CONFIG_MMC_SDHCI_S3C_DMA
  90684. @@ -667,7 +677,7 @@
  90685. * If controller does not have internal clock divider,
  90686. * we can use overriding functions instead of default.
  90687. */
  90688. - if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
  90689. + if (sc->no_divider) {
  90690. sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
  90691. sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
  90692. sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
  90693. @@ -813,7 +823,7 @@
  90694. #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
  90695. static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
  90696. - .sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK,
  90697. + .no_divider = true,
  90698. };
  90699. #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
  90700. #else
  90701. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-sirf.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-sirf.c
  90702. --- linux-3.14.15/drivers/mmc/host/sdhci-sirf.c 2014-07-31 23:51:43.000000000 +0200
  90703. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-sirf.c 2014-08-20 19:31:45.996868438 +0200
  90704. @@ -28,7 +28,11 @@
  90705. }
  90706. static struct sdhci_ops sdhci_sirf_ops = {
  90707. + .set_clock = sdhci_set_clock,
  90708. .get_max_clock = sdhci_sirf_get_max_clk,
  90709. + .set_bus_width = sdhci_set_bus_width,
  90710. + .reset = sdhci_reset,
  90711. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90712. };
  90713. static struct sdhci_pltfm_data sdhci_sirf_pdata = {
  90714. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-spear.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-spear.c
  90715. --- linux-3.14.15/drivers/mmc/host/sdhci-spear.c 2014-07-31 23:51:43.000000000 +0200
  90716. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-spear.c 2014-08-20 19:31:45.996868438 +0200
  90717. @@ -37,7 +37,10 @@
  90718. /* sdhci ops */
  90719. static const struct sdhci_ops sdhci_pltfm_ops = {
  90720. - /* Nothing to do for now. */
  90721. + .set_clock = sdhci_set_clock,
  90722. + .set_bus_width = sdhci_set_bus_width,
  90723. + .reset = sdhci_reset,
  90724. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90725. };
  90726. /* gpio card detection interrupt handler */
  90727. diff -Nur linux-3.14.15/drivers/mmc/host/sdhci-tegra.c linux-linaro-stable-mx6/drivers/mmc/host/sdhci-tegra.c
  90728. --- linux-3.14.15/drivers/mmc/host/sdhci-tegra.c 2014-07-31 23:51:43.000000000 +0200
  90729. +++ linux-linaro-stable-mx6/drivers/mmc/host/sdhci-tegra.c 2014-08-20 19:31:45.996868438 +0200
  90730. @@ -48,19 +48,6 @@
  90731. int power_gpio;
  90732. };
  90733. -static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg)
  90734. -{
  90735. - u32 val;
  90736. -
  90737. - if (unlikely(reg == SDHCI_PRESENT_STATE)) {
  90738. - /* Use wp_gpio here instead? */
  90739. - val = readl(host->ioaddr + reg);
  90740. - return val | SDHCI_WRITE_PROTECT;
  90741. - }
  90742. -
  90743. - return readl(host->ioaddr + reg);
  90744. -}
  90745. -
  90746. static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
  90747. {
  90748. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  90749. @@ -108,12 +95,14 @@
  90750. return mmc_gpio_get_ro(host->mmc);
  90751. }
  90752. -static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask)
  90753. +static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
  90754. {
  90755. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  90756. struct sdhci_tegra *tegra_host = pltfm_host->priv;
  90757. const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
  90758. + sdhci_reset(host, mask);
  90759. +
  90760. if (!(mask & SDHCI_RESET_ALL))
  90761. return;
  90762. @@ -127,7 +116,7 @@
  90763. }
  90764. }
  90765. -static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width)
  90766. +static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
  90767. {
  90768. u32 ctrl;
  90769. @@ -144,16 +133,16 @@
  90770. ctrl &= ~SDHCI_CTRL_4BITBUS;
  90771. }
  90772. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  90773. - return 0;
  90774. }
  90775. static const struct sdhci_ops tegra_sdhci_ops = {
  90776. .get_ro = tegra_sdhci_get_ro,
  90777. - .read_l = tegra_sdhci_readl,
  90778. .read_w = tegra_sdhci_readw,
  90779. .write_l = tegra_sdhci_writel,
  90780. - .platform_bus_width = tegra_sdhci_buswidth,
  90781. - .platform_reset_exit = tegra_sdhci_reset_exit,
  90782. + .set_clock = sdhci_set_clock,
  90783. + .set_bus_width = tegra_sdhci_set_bus_width,
  90784. + .reset = tegra_sdhci_reset,
  90785. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90786. };
  90787. static const struct sdhci_pltfm_data sdhci_tegra20_pdata = {
  90788. diff -Nur linux-3.14.15/drivers/mtd/chips/cfi_cmdset_0002.c linux-linaro-stable-mx6/drivers/mtd/chips/cfi_cmdset_0002.c
  90789. --- linux-3.14.15/drivers/mtd/chips/cfi_cmdset_0002.c 2014-07-31 23:51:43.000000000 +0200
  90790. +++ linux-linaro-stable-mx6/drivers/mtd/chips/cfi_cmdset_0002.c 2014-08-20 19:31:46.024868559 +0200
  90791. @@ -1058,17 +1058,13 @@
  90792. #define UDELAY(map, chip, adr, usec) \
  90793. do { \
  90794. - mutex_unlock(&chip->mutex); \
  90795. cfi_udelay(usec); \
  90796. - mutex_lock(&chip->mutex); \
  90797. } while (0)
  90798. #define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \
  90799. do { \
  90800. - mutex_unlock(&chip->mutex); \
  90801. INVALIDATE_CACHED_RANGE(map, adr, len); \
  90802. cfi_udelay(usec); \
  90803. - mutex_lock(&chip->mutex); \
  90804. } while (0)
  90805. #endif
  90806. diff -Nur linux-3.14.15/drivers/mtd/ubi/build.c linux-linaro-stable-mx6/drivers/mtd/ubi/build.c
  90807. --- linux-3.14.15/drivers/mtd/ubi/build.c 2014-07-31 23:51:43.000000000 +0200
  90808. +++ linux-linaro-stable-mx6/drivers/mtd/ubi/build.c 2014-08-20 19:31:46.068868748 +0200
  90809. @@ -640,7 +640,7 @@
  90810. dbg_gen("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb));
  90811. dbg_gen("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry));
  90812. - if (ubi->mtd->numeraseregions != 0) {
  90813. + if (ubi->mtd->numeraseregions > 1) {
  90814. /*
  90815. * Some flashes have several erase regions. Different regions
  90816. * may have different eraseblock size and other
  90817. diff -Nur linux-3.14.15/drivers/mxc/asrc/Kconfig linux-linaro-stable-mx6/drivers/mxc/asrc/Kconfig
  90818. --- linux-3.14.15/drivers/mxc/asrc/Kconfig 1970-01-01 01:00:00.000000000 +0100
  90819. +++ linux-linaro-stable-mx6/drivers/mxc/asrc/Kconfig 2014-08-20 19:23:53.554845822 +0200
  90820. @@ -0,0 +1,14 @@
  90821. +#
  90822. +# ASRC configuration
  90823. +#
  90824. +
  90825. +menu "MXC Asynchronous Sample Rate Converter support"
  90826. +
  90827. +config MXC_ASRC
  90828. + tristate "ASRC support"
  90829. + depends on SOC_IMX35 || SOC_IMX53 || SOC_IMX6Q
  90830. + select SND_SOC_FSL_ASRC
  90831. + ---help---
  90832. + Say Y to get the ASRC service.
  90833. +
  90834. +endmenu
  90835. diff -Nur linux-3.14.15/drivers/mxc/asrc/Makefile linux-linaro-stable-mx6/drivers/mxc/asrc/Makefile
  90836. --- linux-3.14.15/drivers/mxc/asrc/Makefile 1970-01-01 01:00:00.000000000 +0100
  90837. +++ linux-linaro-stable-mx6/drivers/mxc/asrc/Makefile 2014-08-20 19:23:53.554845822 +0200
  90838. @@ -0,0 +1,4 @@
  90839. +#
  90840. +# Makefile for the kernel Asynchronous Sample Rate Converter driver
  90841. +#
  90842. +obj-$(CONFIG_MXC_ASRC) += mxc_asrc.o
  90843. diff -Nur linux-3.14.15/drivers/mxc/asrc/mxc_asrc.c linux-linaro-stable-mx6/drivers/mxc/asrc/mxc_asrc.c
  90844. --- linux-3.14.15/drivers/mxc/asrc/mxc_asrc.c 1970-01-01 01:00:00.000000000 +0100
  90845. +++ linux-linaro-stable-mx6/drivers/mxc/asrc/mxc_asrc.c 2014-08-20 19:23:53.554845822 +0200
  90846. @@ -0,0 +1,1957 @@
  90847. +/*
  90848. + * Freescale Asynchronous Sample Rate Converter (ASRC) driver
  90849. + *
  90850. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  90851. + *
  90852. + * This file is licensed under the terms of the GNU General Public License
  90853. + * version 2. This program is licensed "as is" without any warranty of any
  90854. + * kind, whether express or implied.
  90855. + */
  90856. +
  90857. +#include <linux/clk.h>
  90858. +#include <linux/slab.h>
  90859. +#include <linux/delay.h>
  90860. +#include <linux/sched.h>
  90861. +#include <linux/regmap.h>
  90862. +#include <linux/module.h>
  90863. +#include <linux/proc_fs.h>
  90864. +#include <linux/pagemap.h>
  90865. +#include <linux/interrupt.h>
  90866. +#include <linux/miscdevice.h>
  90867. +#include <linux/dma-mapping.h>
  90868. +#include <linux/of_platform.h>
  90869. +#include <linux/platform_data/dma-imx.h>
  90870. +
  90871. +#include <linux/mxc_asrc.h>
  90872. +
  90873. +#define ASRC_PROC_PATH "driver/asrc"
  90874. +
  90875. +#define ASRC_RATIO_DECIMAL_DEPTH 26
  90876. +
  90877. +#define pair_err(fmt, ...) \
  90878. + dev_err(asrc->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
  90879. +
  90880. +#define pair_dbg(fmt, ...) \
  90881. + dev_dbg(asrc->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
  90882. +
  90883. +DEFINE_SPINLOCK(data_lock);
  90884. +DEFINE_SPINLOCK(pair_lock);
  90885. +
  90886. +/* Sample rates are aligned with that defined in pcm.h file */
  90887. +static const unsigned char asrc_process_table[][8][2] = {
  90888. + /* 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */
  90889. + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */
  90890. + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */
  90891. + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */
  90892. + {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */
  90893. + {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */
  90894. + {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */
  90895. + {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */
  90896. + {{0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */
  90897. + {{1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */
  90898. + {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */
  90899. + {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */
  90900. + {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */
  90901. + {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */
  90902. +};
  90903. +
  90904. +static struct asrc_data *asrc;
  90905. +
  90906. +/*
  90907. + * The following tables map the relationship between asrc_inclk/asrc_outclk in
  90908. + * mxc_asrc.h and the registers of ASRCSR
  90909. + */
  90910. +static unsigned char input_clk_map_v1[] = {
  90911. + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
  90912. +};
  90913. +
  90914. +static unsigned char output_clk_map_v1[] = {
  90915. + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
  90916. +};
  90917. +
  90918. +/* V2 uses the same map for input and output */
  90919. +static unsigned char input_clk_map_v2[] = {
  90920. +/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
  90921. + 0x0, 0x1, 0x2, 0x7, 0x4, 0x5, 0x6, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xe, 0xd,
  90922. +};
  90923. +
  90924. +static unsigned char output_clk_map_v2[] = {
  90925. +/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
  90926. + 0x8, 0x9, 0xa, 0x7, 0xc, 0x5, 0x6, 0xb, 0x0, 0x1, 0x2, 0x3, 0x4, 0xf, 0xe, 0xd,
  90927. +};
  90928. +
  90929. +static unsigned char *input_clk_map, *output_clk_map;
  90930. +
  90931. +enum mxc_asrc_type {
  90932. + IMX35_ASRC,
  90933. + IMX53_ASRC,
  90934. +};
  90935. +
  90936. +static const struct platform_device_id mxc_asrc_devtype[] = {
  90937. + {
  90938. + .name = "imx35-asrc",
  90939. + .driver_data = IMX35_ASRC,
  90940. + }, {
  90941. + .name = "imx53-asrc",
  90942. + .driver_data = IMX53_ASRC,
  90943. + }, {
  90944. + /* sentinel */
  90945. + }
  90946. +};
  90947. +MODULE_DEVICE_TABLE(platform, mxc_asrc_devtype);
  90948. +
  90949. +static const struct of_device_id fsl_asrc_ids[] = {
  90950. + {
  90951. + .compatible = "fsl,imx35-asrc",
  90952. + .data = &mxc_asrc_devtype[IMX35_ASRC],
  90953. + }, {
  90954. + .compatible = "fsl,imx53-asrc",
  90955. + .data = &mxc_asrc_devtype[IMX53_ASRC],
  90956. + }, {
  90957. + /* sentinel */
  90958. + }
  90959. +};
  90960. +MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
  90961. +
  90962. +
  90963. +#ifdef DEBUG
  90964. +u32 asrc_reg[] = {
  90965. + REG_ASRCTR,
  90966. + REG_ASRIER,
  90967. + REG_ASRCNCR,
  90968. + REG_ASRCFG,
  90969. + REG_ASRCSR,
  90970. + REG_ASRCDR1,
  90971. + REG_ASRCDR2,
  90972. + REG_ASRSTR,
  90973. + REG_ASRRA,
  90974. + REG_ASRRB,
  90975. + REG_ASRRC,
  90976. + REG_ASRPM1,
  90977. + REG_ASRPM2,
  90978. + REG_ASRPM3,
  90979. + REG_ASRPM4,
  90980. + REG_ASRPM5,
  90981. + REG_ASRTFR1,
  90982. + REG_ASRCCR,
  90983. + REG_ASRIDRHA,
  90984. + REG_ASRIDRLA,
  90985. + REG_ASRIDRHB,
  90986. + REG_ASRIDRLB,
  90987. + REG_ASRIDRHC,
  90988. + REG_ASRIDRLC,
  90989. + REG_ASR76K,
  90990. + REG_ASR56K,
  90991. + REG_ASRMCRA,
  90992. + REG_ASRFSTA,
  90993. + REG_ASRMCRB,
  90994. + REG_ASRFSTB,
  90995. + REG_ASRMCRC,
  90996. + REG_ASRFSTC,
  90997. + REG_ASRMCR1A,
  90998. + REG_ASRMCR1B,
  90999. + REG_ASRMCR1C,
  91000. +};
  91001. +
  91002. +static void dump_regs(void)
  91003. +{
  91004. + u32 reg, val;
  91005. + int i;
  91006. +
  91007. + for (i = 0; i < ARRAY_SIZE(asrc_reg); i++) {
  91008. + reg = asrc_reg[i];
  91009. + regmap_read(asrc->regmap, reg, &val);
  91010. + dev_dbg(asrc->dev, "REG addr=0x%x val=0x%x\n", reg, val);
  91011. + }
  91012. +}
  91013. +#else
  91014. +static void dump_regs(void) {}
  91015. +#endif
  91016. +
  91017. +/* Only used for Ideal Ratio mode */
  91018. +static int asrc_set_clock_ratio(enum asrc_pair_index index,
  91019. + int inrate, int outrate)
  91020. +{
  91021. + unsigned long val = 0;
  91022. + int integ, i;
  91023. +
  91024. + if (outrate == 0) {
  91025. + dev_err(asrc->dev, "wrong output sample rate: %d\n", outrate);
  91026. + return -EINVAL;
  91027. + }
  91028. +
  91029. + /* Formula: r = (1 << ASRC_RATIO_DECIMAL_DEPTH) / outrate * inrate; */
  91030. + for (integ = 0; inrate >= outrate; integ++)
  91031. + inrate -= outrate;
  91032. +
  91033. + val |= (integ << ASRC_RATIO_DECIMAL_DEPTH);
  91034. +
  91035. + for (i = 1; i <= ASRC_RATIO_DECIMAL_DEPTH; i++) {
  91036. + if ((inrate * 2) >= outrate) {
  91037. + val |= (1 << (ASRC_RATIO_DECIMAL_DEPTH - i));
  91038. + inrate = inrate * 2 - outrate;
  91039. + } else
  91040. + inrate = inrate << 1;
  91041. +
  91042. + if (inrate == 0)
  91043. + break;
  91044. + }
  91045. +
  91046. + regmap_write(asrc->regmap, REG_ASRIDRL(index), val);
  91047. + regmap_write(asrc->regmap, REG_ASRIDRH(index), (val >> 24));
  91048. +
  91049. + return 0;
  91050. +}
  91051. +
  91052. +/* Corresponding to asrc_process_table */
  91053. +static int supported_input_rate[] = {
  91054. + 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200,
  91055. + 96000, 176400, 192000,
  91056. +};
  91057. +
  91058. +static int supported_output_rate[] = {
  91059. + 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000,
  91060. +};
  91061. +
  91062. +static int asrc_set_process_configuration(enum asrc_pair_index index,
  91063. + int inrate, int outrate)
  91064. +{
  91065. + int in, out;
  91066. +
  91067. + for (in = 0; in < ARRAY_SIZE(supported_input_rate); in++) {
  91068. + if (inrate == supported_input_rate[in])
  91069. + break;
  91070. + }
  91071. +
  91072. + if (in == ARRAY_SIZE(supported_input_rate)) {
  91073. + dev_err(asrc->dev, "unsupported input sample rate: %d\n", in);
  91074. + return -EINVAL;
  91075. + }
  91076. +
  91077. + for (out = 0; out < ARRAY_SIZE(supported_output_rate); out++) {
  91078. + if (outrate == supported_output_rate[out])
  91079. + break;
  91080. + }
  91081. +
  91082. + if (out == ARRAY_SIZE(supported_output_rate)) {
  91083. + dev_err(asrc->dev, "unsupported output sample rate: %d\n", out);
  91084. + return -EINVAL;
  91085. + }
  91086. +
  91087. + regmap_update_bits(asrc->regmap, REG_ASRCFG,
  91088. + ASRCFG_PREMODx_MASK(index) | ASRCFG_POSTMODx_MASK(index),
  91089. + ASRCFG_PREMOD(index, asrc_process_table[in][out][0]) |
  91090. + ASRCFG_POSTMOD(index, asrc_process_table[in][out][1]));
  91091. +
  91092. + return 0;
  91093. +}
  91094. +
  91095. +static int asrc_get_asrck_clock_divider(int samplerate)
  91096. +{
  91097. + unsigned int prescaler, divider, ratio, ra, i;
  91098. + unsigned long bitclk;
  91099. +
  91100. + if (samplerate == 0) {
  91101. + dev_err(asrc->dev, "invalid sample rate: %d\n", samplerate);
  91102. + return -EINVAL;
  91103. + }
  91104. +
  91105. + bitclk = clk_get_rate(asrc->asrc_clk);
  91106. +
  91107. + ra = bitclk / samplerate;
  91108. + ratio = ra;
  91109. +
  91110. + /* Calculate the prescaler */
  91111. + for (i = 0; ratio > 8; i++)
  91112. + ratio >>= 1;
  91113. +
  91114. + prescaler = i;
  91115. +
  91116. + /* Calculate the divider */
  91117. + divider = i ? (((ra + (1 << (i - 1)) - 1) >> i) - 1) : (ra - 1);
  91118. +
  91119. + /* The totally divider is (2 ^ prescaler) * divider */
  91120. + return (divider << ASRCDRx_AxCPx_WIDTH) + prescaler;
  91121. +}
  91122. +
  91123. +int asrc_req_pair(int chn_num, enum asrc_pair_index *index)
  91124. +{
  91125. + int imax = 0, busy = 0, i, ret = 0;
  91126. + unsigned long lock_flags;
  91127. + struct asrc_pair *pair;
  91128. +
  91129. + spin_lock_irqsave(&data_lock, lock_flags);
  91130. +
  91131. + for (i = ASRC_PAIR_A; i < ASRC_PAIR_MAX_NUM; i++) {
  91132. + pair = &asrc->asrc_pair[i];
  91133. + if (chn_num > pair->chn_max) {
  91134. + imax++;
  91135. + continue;
  91136. + } else if (pair->active) {
  91137. + busy++;
  91138. + continue;
  91139. + }
  91140. + /* Save the current qualified pair */
  91141. + *index = i;
  91142. +
  91143. + /* Check if this pair is a perfect one */
  91144. + if (chn_num == pair->chn_max)
  91145. + break;
  91146. + }
  91147. +
  91148. + if (imax == ASRC_PAIR_MAX_NUM) {
  91149. + dev_err(asrc->dev, "no pair could afford required channel number\n");
  91150. + ret = -EINVAL;
  91151. + } else if (busy == ASRC_PAIR_MAX_NUM) {
  91152. + dev_err(asrc->dev, "all pairs are busy now\n");
  91153. + ret = -EBUSY;
  91154. + } else if (busy + imax >= ASRC_PAIR_MAX_NUM) {
  91155. + dev_err(asrc->dev, "all affordable pairs are busy now\n");
  91156. + ret = -EBUSY;
  91157. + } else {
  91158. + pair = &asrc->asrc_pair[*index];
  91159. + pair->chn_num = chn_num;
  91160. + pair->active = 1;
  91161. + }
  91162. +
  91163. + spin_unlock_irqrestore(&data_lock, lock_flags);
  91164. +
  91165. + if (!ret) {
  91166. + clk_enable(asrc->asrc_clk);
  91167. + clk_prepare_enable(asrc->dma_clk);
  91168. + }
  91169. +
  91170. + return ret;
  91171. +}
  91172. +EXPORT_SYMBOL(asrc_req_pair);
  91173. +
  91174. +void asrc_release_pair(enum asrc_pair_index index)
  91175. +{
  91176. + struct asrc_pair *pair = &asrc->asrc_pair[index];
  91177. + unsigned long lock_flags;
  91178. +
  91179. + spin_lock_irqsave(&data_lock, lock_flags);
  91180. +
  91181. + pair->active = 0;
  91182. + pair->overload_error = 0;
  91183. +
  91184. + spin_unlock_irqrestore(&data_lock, lock_flags);
  91185. +
  91186. + /* Disable PAIR */
  91187. + regmap_update_bits(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEx_MASK(index), 0);
  91188. +}
  91189. +EXPORT_SYMBOL(asrc_release_pair);
  91190. +
  91191. +int asrc_config_pair(struct asrc_config *config)
  91192. +{
  91193. + u32 inrate = config->input_sample_rate, indiv;
  91194. + u32 outrate = config->output_sample_rate, outdiv;
  91195. + int ret, channels, index = config->pair;
  91196. + unsigned long lock_flags;
  91197. +
  91198. + /* Set the channel number */
  91199. + spin_lock_irqsave(&data_lock, lock_flags);
  91200. + asrc->asrc_pair[index].chn_num = config->channel_num;
  91201. + spin_unlock_irqrestore(&data_lock, lock_flags);
  91202. +
  91203. + if (asrc->channel_bits > 3)
  91204. + channels = config->channel_num;
  91205. + else
  91206. + channels = (config->channel_num + 1) / 2;
  91207. +
  91208. + /* Update channel number of current pair */
  91209. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  91210. + ASRCNCR_ANCx_MASK(index, asrc->channel_bits),
  91211. + ASRCNCR_ANCx_set(index, channels, asrc->channel_bits));
  91212. +
  91213. + /* Set the clock source */
  91214. + regmap_update_bits(asrc->regmap, REG_ASRCSR,
  91215. + ASRCSR_AICSx_MASK(index) | ASRCSR_AOCSx_MASK(index),
  91216. + ASRCSR_AICS(index, input_clk_map[config->inclk]) |
  91217. + ASRCSR_AOCS(index, output_clk_map[config->outclk]));
  91218. +
  91219. + /* Default setting: Automatic selection for processing mode */
  91220. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  91221. + ASRCTR_ATSx_MASK(index), ASRCTR_ATS(index));
  91222. + regmap_update_bits(asrc->regmap, REG_ASRCTR, ASRCTR_USRx_MASK(index), 0);
  91223. +
  91224. + /* Default Input Clock Divider Setting */
  91225. + switch (config->inclk & ASRCSR_AxCSx_MASK) {
  91226. + case INCLK_SPDIF_RX:
  91227. + indiv = ASRC_PRESCALER_SPDIF_RX;
  91228. + break;
  91229. + case INCLK_SPDIF_TX:
  91230. + indiv = ASRC_PRESCALER_SPDIF_TX;
  91231. + break;
  91232. + case INCLK_ASRCK1_CLK:
  91233. + indiv = asrc_get_asrck_clock_divider(inrate);
  91234. + break;
  91235. + default:
  91236. + switch (config->input_word_width) {
  91237. + case ASRC_WIDTH_16_BIT:
  91238. + indiv = ASRC_PRESCALER_I2S_16BIT;
  91239. + break;
  91240. + case ASRC_WIDTH_24_BIT:
  91241. + indiv = ASRC_PRESCALER_I2S_24BIT;
  91242. + break;
  91243. + default:
  91244. + pair_err("unsupported input word width %d\n",
  91245. + config->input_word_width);
  91246. + return -EINVAL;
  91247. + }
  91248. + break;
  91249. + }
  91250. +
  91251. + /* Default Output Clock Divider Setting */
  91252. + switch (config->outclk & ASRCSR_AxCSx_MASK) {
  91253. + case OUTCLK_SPDIF_RX:
  91254. + outdiv = ASRC_PRESCALER_SPDIF_RX;
  91255. + break;
  91256. + case OUTCLK_SPDIF_TX:
  91257. + outdiv = ASRC_PRESCALER_SPDIF_TX;
  91258. + break;
  91259. + case OUTCLK_ASRCK1_CLK:
  91260. + if ((config->inclk & ASRCSR_AxCSx_MASK) == INCLK_NONE)
  91261. + outdiv = ASRC_PRESCALER_IDEAL_RATIO;
  91262. + else
  91263. + outdiv = asrc_get_asrck_clock_divider(outrate);
  91264. + break;
  91265. + default:
  91266. + switch (config->output_word_width) {
  91267. + case ASRC_WIDTH_16_BIT:
  91268. + outdiv = ASRC_PRESCALER_I2S_16BIT;
  91269. + break;
  91270. + case ASRC_WIDTH_24_BIT:
  91271. + outdiv = ASRC_PRESCALER_I2S_24BIT;
  91272. + break;
  91273. + default:
  91274. + pair_err("unsupported output word width %d\n",
  91275. + config->input_word_width);
  91276. + return -EINVAL;
  91277. + }
  91278. + break;
  91279. + }
  91280. +
  91281. + /* indiv and outdiv'd include prescaler's value, so add its MASK too */
  91282. + regmap_update_bits(asrc->regmap, REG_ASRCDR(index),
  91283. + ASRCDRx_AOCPx_MASK(index) | ASRCDRx_AICPx_MASK(index) |
  91284. + ASRCDRx_AOCDx_MASK(index) | ASRCDRx_AICDx_MASK(index),
  91285. + ASRCDRx_AOCP(index, outdiv) | ASRCDRx_AICP(index, indiv));
  91286. +
  91287. + /* Check whether ideal ratio is a must */
  91288. + switch (config->inclk & ASRCSR_AxCSx_MASK) {
  91289. + case INCLK_NONE:
  91290. + /* Clear ASTSx bit to use ideal ratio */
  91291. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  91292. + ASRCTR_ATSx_MASK(index), 0);
  91293. +
  91294. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  91295. + ASRCTR_IDRx_MASK(index) | ASRCTR_USRx_MASK(index),
  91296. + ASRCTR_IDR(index) | ASRCTR_USR(index));
  91297. +
  91298. + ret = asrc_set_clock_ratio(index, inrate, outrate);
  91299. + if (ret)
  91300. + return ret;
  91301. +
  91302. + ret = asrc_set_process_configuration(index, inrate, outrate);
  91303. + if (ret)
  91304. + return ret;
  91305. +
  91306. + break;
  91307. + case INCLK_ASRCK1_CLK:
  91308. + /* This case and default are both remained for v1 */
  91309. + if (inrate == 44100 || inrate == 88200) {
  91310. + pair_err("unsupported sample rate %d by selected clock\n",
  91311. + inrate);
  91312. + return -EINVAL;
  91313. + }
  91314. + break;
  91315. + default:
  91316. + if ((config->outclk & ASRCSR_AxCSx_MASK) != OUTCLK_ASRCK1_CLK)
  91317. + break;
  91318. +
  91319. + if (outrate == 44100 || outrate == 88200) {
  91320. + pair_err("unsupported sample rate %d by selected clock\n",
  91321. + outrate);
  91322. + return -EINVAL;
  91323. + }
  91324. + break;
  91325. + }
  91326. +
  91327. + /* Config input and output wordwidth */
  91328. + if (config->output_word_width == ASRC_WIDTH_8_BIT) {
  91329. + pair_err("unsupported wordwidth for output: 8bit\n");
  91330. + pair_err("output only support: 16bit or 24bit\n");
  91331. + return -EINVAL;
  91332. + }
  91333. +
  91334. + regmap_update_bits(asrc->regmap, REG_ASRMCR1(index),
  91335. + ASRMCR1x_OW16_MASK | ASRMCR1x_IWD_MASK,
  91336. + ASRMCR1x_OW16(config->output_word_width) |
  91337. + ASRMCR1x_IWD(config->input_word_width));
  91338. +
  91339. + /* Enable BUFFER STALL */
  91340. + regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
  91341. + ASRMCRx_BUFSTALLx_MASK, ASRMCRx_BUFSTALLx);
  91342. +
  91343. + /* Set Threshold for input and output FIFO */
  91344. + return asrc_set_watermark(index, ASRC_INPUTFIFO_THRESHOLD,
  91345. + ASRC_INPUTFIFO_THRESHOLD);
  91346. +}
  91347. +EXPORT_SYMBOL(asrc_config_pair);
  91348. +
  91349. +int asrc_set_watermark(enum asrc_pair_index index, u32 in_wm, u32 out_wm)
  91350. +{
  91351. + if (in_wm > ASRC_FIFO_THRESHOLD_MAX || out_wm > ASRC_FIFO_THRESHOLD_MAX) {
  91352. + pair_err("invalid watermark!\n");
  91353. + return -EINVAL;
  91354. + }
  91355. +
  91356. + return regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
  91357. + ASRMCRx_EXTTHRSHx_MASK | ASRMCRx_INFIFO_THRESHOLD_MASK |
  91358. + ASRMCRx_OUTFIFO_THRESHOLD_MASK,
  91359. + ASRMCRx_EXTTHRSHx | ASRMCRx_INFIFO_THRESHOLD(in_wm) |
  91360. + ASRMCRx_OUTFIFO_THRESHOLD(out_wm));
  91361. +}
  91362. +EXPORT_SYMBOL(asrc_set_watermark);
  91363. +
  91364. +void asrc_start_conv(enum asrc_pair_index index)
  91365. +{
  91366. + int reg, retry, channels, i;
  91367. +
  91368. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  91369. + ASRCTR_ASRCEx_MASK(index), ASRCTR_ASRCE(index));
  91370. +
  91371. + /* Wait for status of initialization */
  91372. + for (retry = 10, reg = 0; !reg && retry; --retry) {
  91373. + udelay(5);
  91374. + regmap_read(asrc->regmap, REG_ASRCFG, &reg);
  91375. + reg &= ASRCFG_INIRQx_MASK(index);
  91376. + }
  91377. +
  91378. + /* Set the input fifo to ASRC STALL level */
  91379. + regmap_read(asrc->regmap, REG_ASRCNCR, &reg);
  91380. + channels = ASRCNCR_ANCx_get(index, reg, asrc->channel_bits);
  91381. + for (i = 0; i < channels * 4; i++)
  91382. + regmap_write(asrc->regmap, REG_ASRDI(index), 0);
  91383. +
  91384. + /* Overload Interrupt Enable */
  91385. + regmap_write(asrc->regmap, REG_ASRIER, ASRIER_AOLIE);
  91386. +}
  91387. +EXPORT_SYMBOL(asrc_start_conv);
  91388. +
  91389. +void asrc_stop_conv(enum asrc_pair_index index)
  91390. +{
  91391. + regmap_update_bits(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEx_MASK(index), 0);
  91392. +}
  91393. +EXPORT_SYMBOL(asrc_stop_conv);
  91394. +
  91395. +void asrc_finish_conv(enum asrc_pair_index index)
  91396. +{
  91397. + clk_disable_unprepare(asrc->dma_clk);
  91398. + clk_disable(asrc->asrc_clk);
  91399. +}
  91400. +EXPORT_SYMBOL(asrc_finish_conv);
  91401. +
  91402. +#define SET_OVERLOAD_ERR(index, err, msg) \
  91403. + do { \
  91404. + asrc->asrc_pair[index].overload_error |= err; \
  91405. + pair_dbg(msg); \
  91406. + } while (0)
  91407. +
  91408. +static irqreturn_t asrc_isr(int irq, void *dev_id)
  91409. +{
  91410. + enum asrc_pair_index index;
  91411. + u32 status;
  91412. +
  91413. + regmap_read(asrc->regmap, REG_ASRSTR, &status);
  91414. +
  91415. + for (index = ASRC_PAIR_A; index < ASRC_PAIR_MAX_NUM; index++) {
  91416. + if (asrc->asrc_pair[index].active == 0)
  91417. + continue;
  91418. + if (status & ASRSTR_ATQOL)
  91419. + SET_OVERLOAD_ERR(index, ASRC_TASK_Q_OVERLOAD,
  91420. + "Task Queue FIFO overload");
  91421. + if (status & ASRSTR_AOOL(index))
  91422. + SET_OVERLOAD_ERR(index, ASRC_OUTPUT_TASK_OVERLOAD,
  91423. + "Output Task Overload");
  91424. + if (status & ASRSTR_AIOL(index))
  91425. + SET_OVERLOAD_ERR(index, ASRC_INPUT_TASK_OVERLOAD,
  91426. + "Input Task Overload");
  91427. + if (status & ASRSTR_AODO(index))
  91428. + SET_OVERLOAD_ERR(index, ASRC_OUTPUT_BUFFER_OVERFLOW,
  91429. + "Output Data Buffer has overflowed");
  91430. + if (status & ASRSTR_AIDU(index))
  91431. + SET_OVERLOAD_ERR(index, ASRC_INPUT_BUFFER_UNDERRUN,
  91432. + "Input Data Buffer has underflowed");
  91433. + }
  91434. +
  91435. + /* Clean overload error */
  91436. + regmap_write(asrc->regmap, REG_ASRSTR, ASRSTR_AOLE);
  91437. +
  91438. + return IRQ_HANDLED;
  91439. +}
  91440. +
  91441. +void asrc_get_status(struct asrc_status_flags *flags)
  91442. +{
  91443. + enum asrc_pair_index index = flags->index;
  91444. + unsigned long lock_flags;
  91445. +
  91446. + spin_lock_irqsave(&data_lock, lock_flags);
  91447. +
  91448. + flags->overload_error = asrc->asrc_pair[index].overload_error;
  91449. +
  91450. + spin_unlock_irqrestore(&data_lock, lock_flags);
  91451. +}
  91452. +EXPORT_SYMBOL(asrc_get_status);
  91453. +
  91454. +u32 asrc_get_per_addr(enum asrc_pair_index index, bool in)
  91455. +{
  91456. + return asrc->paddr + (in ? REG_ASRDI(index) : REG_ASRDO(index));
  91457. +}
  91458. +EXPORT_SYMBOL(asrc_get_per_addr);
  91459. +
  91460. +static int mxc_init_asrc(void)
  91461. +{
  91462. + /* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
  91463. + regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
  91464. +
  91465. + /* Disable interrupt by default */
  91466. + regmap_write(asrc->regmap, REG_ASRIER, 0x0);
  91467. +
  91468. + /* Default 2: 6: 2 channel assignment */
  91469. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  91470. + ASRCNCR_ANCx_MASK(ASRC_PAIR_A, asrc->channel_bits),
  91471. + ASRCNCR_ANCx_set(ASRC_PAIR_A, 2, asrc->channel_bits));
  91472. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  91473. + ASRCNCR_ANCx_MASK(ASRC_PAIR_B, asrc->channel_bits),
  91474. + ASRCNCR_ANCx_set(ASRC_PAIR_B, 6, asrc->channel_bits));
  91475. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  91476. + ASRCNCR_ANCx_MASK(ASRC_PAIR_C, asrc->channel_bits),
  91477. + ASRCNCR_ANCx_set(ASRC_PAIR_C, 2, asrc->channel_bits));
  91478. +
  91479. + /* Parameter Registers recommended settings */
  91480. + regmap_write(asrc->regmap, REG_ASRPM1, 0x7fffff);
  91481. + regmap_write(asrc->regmap, REG_ASRPM2, 0x255555);
  91482. + regmap_write(asrc->regmap, REG_ASRPM3, 0xff7280);
  91483. + regmap_write(asrc->regmap, REG_ASRPM4, 0xff7280);
  91484. + regmap_write(asrc->regmap, REG_ASRPM5, 0xff7280);
  91485. +
  91486. + /* Base address for task queue FIFO. Set to 0x7C */
  91487. + regmap_update_bits(asrc->regmap, REG_ASRTFR1,
  91488. + ASRTFR1_TF_BASE_MASK, ASRTFR1_TF_BASE(0xfc));
  91489. +
  91490. + /* Set the processing clock for 76KHz, 133M */
  91491. + regmap_write(asrc->regmap, REG_ASR76K, 0x06D6);
  91492. +
  91493. + /* Set the processing clock for 56KHz, 133M */
  91494. + return regmap_write(asrc->regmap, REG_ASR56K, 0x0947);
  91495. +}
  91496. +
  91497. +#define ASRC_xPUT_DMA_CALLBACK(in) \
  91498. + ((in) ? asrc_input_dma_callback : asrc_output_dma_callback)
  91499. +
  91500. +static void asrc_input_dma_callback(void *data)
  91501. +{
  91502. + struct asrc_pair_params *params = (struct asrc_pair_params *)data;
  91503. +
  91504. + dma_unmap_sg(NULL, params->input_sg, params->input_sg_nodes,
  91505. + DMA_MEM_TO_DEV);
  91506. +
  91507. + complete(&params->input_complete);
  91508. +
  91509. + schedule_work(&params->task_output_work);
  91510. +}
  91511. +
  91512. +static void asrc_output_dma_callback(void *data)
  91513. +{
  91514. + struct asrc_pair_params *params = (struct asrc_pair_params *)data;
  91515. +
  91516. + dma_unmap_sg(NULL, params->output_sg, params->output_sg_nodes,
  91517. + DMA_DEV_TO_MEM);
  91518. +
  91519. + complete(&params->output_complete);
  91520. +}
  91521. +
  91522. +static unsigned int asrc_get_output_FIFO_size(enum asrc_pair_index index)
  91523. +{
  91524. + u32 val;
  91525. +
  91526. + regmap_read(asrc->regmap, REG_ASRFST(index), &val);
  91527. +
  91528. + val &= ASRFSTx_OUTPUT_FIFO_MASK;
  91529. +
  91530. + return val >> ASRFSTx_OUTPUT_FIFO_SHIFT;
  91531. +}
  91532. +
  91533. +static u32 asrc_read_one_from_output_FIFO(enum asrc_pair_index index)
  91534. +{
  91535. + u32 val;
  91536. +
  91537. + regmap_read(asrc->regmap, REG_ASRDO(index), &val);
  91538. +
  91539. + return val;
  91540. +}
  91541. +
  91542. +static void asrc_read_output_FIFO(struct asrc_pair_params *params)
  91543. +{
  91544. + u32 *reg24 = params->output_last_period.dma_vaddr;
  91545. + u16 *reg16 = params->output_last_period.dma_vaddr;
  91546. + enum asrc_pair_index index = params->index;
  91547. + u32 i, j, reg, size, t_size;
  91548. + bool bit24 = false;
  91549. +
  91550. + if (params->output_word_width == ASRC_WIDTH_24_BIT)
  91551. + bit24 = true;
  91552. +
  91553. + t_size = 0;
  91554. + do {
  91555. + size = asrc_get_output_FIFO_size(index);
  91556. + for (i = 0; i < size; i++) {
  91557. + for (j = 0; j < params->channel_nums; j++) {
  91558. + reg = asrc_read_one_from_output_FIFO(index);
  91559. + if (bit24) {
  91560. + *(reg24) = reg;
  91561. + reg24++;
  91562. + } else {
  91563. + *(reg16) = (u16)reg;
  91564. + reg16++;
  91565. + }
  91566. + }
  91567. + }
  91568. + t_size += size;
  91569. + } while (size);
  91570. +
  91571. + if (t_size > params->last_period_sample)
  91572. + t_size = params->last_period_sample;
  91573. +
  91574. + params->output_last_period.length = t_size * params->channel_nums * 2;
  91575. + if (bit24)
  91576. + params->output_last_period.length *= 2;
  91577. +}
  91578. +
  91579. +static void asrc_output_task_worker(struct work_struct *w)
  91580. +{
  91581. + struct asrc_pair_params *params =
  91582. + container_of(w, struct asrc_pair_params, task_output_work);
  91583. + enum asrc_pair_index index = params->index;
  91584. + unsigned long lock_flags;
  91585. +
  91586. + if (!wait_for_completion_interruptible_timeout(&params->output_complete, HZ / 10)) {
  91587. + pair_err("output dma task timeout\n");
  91588. + return;
  91589. + }
  91590. +
  91591. + init_completion(&params->output_complete);
  91592. +
  91593. + spin_lock_irqsave(&pair_lock, lock_flags);
  91594. + if (!params->pair_hold) {
  91595. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  91596. + return;
  91597. + }
  91598. + asrc_read_output_FIFO(params);
  91599. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  91600. +
  91601. + complete(&params->lastperiod_complete);
  91602. +}
  91603. +
  91604. +static void mxc_free_dma_buf(struct asrc_pair_params *params)
  91605. +{
  91606. + if (params->input_dma_total.dma_vaddr != NULL) {
  91607. + kfree(params->input_dma_total.dma_vaddr);
  91608. + params->input_dma_total.dma_vaddr = NULL;
  91609. + }
  91610. +
  91611. + if (params->output_dma_total.dma_vaddr != NULL) {
  91612. + kfree(params->output_dma_total.dma_vaddr);
  91613. + params->output_dma_total.dma_vaddr = NULL;
  91614. + }
  91615. +
  91616. + if (params->output_last_period.dma_vaddr) {
  91617. + dma_free_coherent(asrc->dev, 1024 * params->last_period_sample,
  91618. + params->output_last_period.dma_vaddr,
  91619. + params->output_last_period.dma_paddr);
  91620. + params->output_last_period.dma_vaddr = NULL;
  91621. + }
  91622. +}
  91623. +
  91624. +static int mxc_allocate_dma_buf(struct asrc_pair_params *params)
  91625. +{
  91626. + struct dma_block *input_a, *output_a, *last_period;
  91627. + enum asrc_pair_index index = params->index;
  91628. +
  91629. + input_a = &params->input_dma_total;
  91630. + output_a = &params->output_dma_total;
  91631. + last_period = &params->output_last_period;
  91632. +
  91633. + input_a->dma_vaddr = kzalloc(input_a->length, GFP_KERNEL);
  91634. + if (!input_a->dma_vaddr) {
  91635. + pair_err("failed to allocate input dma buffer\n");
  91636. + goto exit;
  91637. + }
  91638. + input_a->dma_paddr = virt_to_dma(NULL, input_a->dma_vaddr);
  91639. +
  91640. + output_a->dma_vaddr = kzalloc(output_a->length, GFP_KERNEL);
  91641. + if (!output_a->dma_vaddr) {
  91642. + pair_err("failed to allocate output dma buffer\n");
  91643. + goto exit;
  91644. + }
  91645. + output_a->dma_paddr = virt_to_dma(NULL, output_a->dma_vaddr);
  91646. +
  91647. + last_period->dma_vaddr = dma_alloc_coherent(asrc->dev,
  91648. + 1024 * params->last_period_sample,
  91649. + &last_period->dma_paddr, GFP_KERNEL);
  91650. + if (!last_period->dma_vaddr) {
  91651. + pair_err("failed to allocate last period buffer\n");
  91652. + goto exit;
  91653. + }
  91654. +
  91655. + return 0;
  91656. +
  91657. +exit:
  91658. + mxc_free_dma_buf(params);
  91659. +
  91660. + return -ENOBUFS;
  91661. +}
  91662. +
  91663. +static struct dma_chan *imx_asrc_get_dma_channel(enum asrc_pair_index index, bool in)
  91664. +{
  91665. + char name[4];
  91666. +
  91667. + sprintf(name, "%cx%c", in ? 'r' : 't', index + 'a');
  91668. +
  91669. + return dma_request_slave_channel(asrc->dev, name);
  91670. +}
  91671. +
  91672. +static int imx_asrc_dma_config(struct asrc_pair_params *params,
  91673. + struct dma_chan *chan, u32 dma_addr,
  91674. + void *buf_addr, u32 buf_len, bool in,
  91675. + enum asrc_word_width word_width)
  91676. +{
  91677. + enum asrc_pair_index index = params->index;
  91678. + struct dma_async_tx_descriptor *desc;
  91679. + struct dma_slave_config slave_config;
  91680. + enum dma_slave_buswidth buswidth;
  91681. + struct scatterlist *sg;
  91682. + unsigned int sg_nent, i;
  91683. + int ret;
  91684. +
  91685. + if (in) {
  91686. + sg = params->input_sg;
  91687. + sg_nent = params->input_sg_nodes;
  91688. + desc = params->desc_in;
  91689. + } else {
  91690. + sg = params->output_sg;
  91691. + sg_nent = params->output_sg_nodes;
  91692. + desc = params->desc_out;
  91693. + }
  91694. +
  91695. + switch (word_width) {
  91696. + case ASRC_WIDTH_16_BIT:
  91697. + buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
  91698. + break;
  91699. + case ASRC_WIDTH_24_BIT:
  91700. + buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
  91701. + break;
  91702. + default:
  91703. + pair_err("invalid word width\n");
  91704. + return -EINVAL;
  91705. + }
  91706. +
  91707. + slave_config.dma_request0 = 0;
  91708. + slave_config.dma_request1 = 0;
  91709. +
  91710. + if (in) {
  91711. + slave_config.direction = DMA_MEM_TO_DEV;
  91712. + slave_config.dst_addr = dma_addr;
  91713. + slave_config.dst_addr_width = buswidth;
  91714. + slave_config.dst_maxburst =
  91715. + params->input_wm * params->channel_nums / buswidth;
  91716. + } else {
  91717. + slave_config.direction = DMA_DEV_TO_MEM;
  91718. + slave_config.src_addr = dma_addr;
  91719. + slave_config.src_addr_width = buswidth;
  91720. + slave_config.src_maxburst =
  91721. + params->output_wm * params->channel_nums / buswidth;
  91722. + }
  91723. + ret = dmaengine_slave_config(chan, &slave_config);
  91724. + if (ret) {
  91725. + pair_err("failed to config dmaengine for %sput task: %d\n",
  91726. + in ? "in" : "out", ret);
  91727. + return -EINVAL;
  91728. + }
  91729. +
  91730. + sg_init_table(sg, sg_nent);
  91731. + switch (sg_nent) {
  91732. + case 1:
  91733. + sg_init_one(sg, buf_addr, buf_len);
  91734. + break;
  91735. + case 2:
  91736. + case 3:
  91737. + case 4:
  91738. + for (i = 0; i < (sg_nent - 1); i++)
  91739. + sg_set_buf(&sg[i], buf_addr + i * ASRC_MAX_BUFFER_SIZE,
  91740. + ASRC_MAX_BUFFER_SIZE);
  91741. +
  91742. + sg_set_buf(&sg[i], buf_addr + i * ASRC_MAX_BUFFER_SIZE,
  91743. + buf_len - ASRC_MAX_BUFFER_SIZE * i);
  91744. + break;
  91745. + default:
  91746. + pair_err("invalid input DMA nodes number: %d\n", sg_nent);
  91747. + return -EINVAL;
  91748. + }
  91749. +
  91750. + ret = dma_map_sg(NULL, sg, sg_nent, slave_config.direction);
  91751. + if (ret != sg_nent) {
  91752. + pair_err("failed to map dma sg for %sput task\n",
  91753. + in ? "in" : "out");
  91754. + return -EINVAL;
  91755. + }
  91756. +
  91757. + desc = dmaengine_prep_slave_sg(chan, sg, sg_nent,
  91758. + slave_config.direction, DMA_PREP_INTERRUPT);
  91759. + if (!desc) {
  91760. + pair_err("failed to prepare slave sg for %sput task\n",
  91761. + in ? "in" : "out");
  91762. + return -EINVAL;
  91763. + }
  91764. +
  91765. + if (in) {
  91766. + params->desc_in = desc;
  91767. + params->desc_in->callback = asrc_input_dma_callback;
  91768. + } else {
  91769. + params->desc_out = desc;
  91770. + params->desc_out->callback = asrc_output_dma_callback;
  91771. + }
  91772. +
  91773. + desc->callback = ASRC_xPUT_DMA_CALLBACK(in);
  91774. + desc->callback_param = params;
  91775. +
  91776. + return 0;
  91777. +}
  91778. +
  91779. +static int mxc_asrc_prepare_io_buffer(struct asrc_pair_params *params,
  91780. + struct asrc_convert_buffer *pbuf, bool in)
  91781. +{
  91782. + enum asrc_pair_index index = params->index;
  91783. + struct dma_chan *dma_channel;
  91784. + enum asrc_word_width width;
  91785. + unsigned int *dma_len, *sg_nodes, buf_len, wm;
  91786. + void __user *buf_vaddr;
  91787. + void *dma_vaddr;
  91788. + u32 word_size, fifo_addr;
  91789. +
  91790. + if (in) {
  91791. + dma_channel = params->input_dma_channel;
  91792. + dma_vaddr = params->input_dma_total.dma_vaddr;
  91793. + dma_len = &params->input_dma_total.length;
  91794. + width = params->input_word_width;
  91795. + sg_nodes = &params->input_sg_nodes;
  91796. + wm = params->input_wm;
  91797. + buf_vaddr = (void __user *)pbuf->input_buffer_vaddr;
  91798. + buf_len = pbuf->input_buffer_length;
  91799. + } else {
  91800. + dma_channel = params->output_dma_channel;
  91801. + dma_vaddr = params->output_dma_total.dma_vaddr;
  91802. + dma_len = &params->output_dma_total.length;
  91803. + width = params->output_word_width;
  91804. + sg_nodes = &params->output_sg_nodes;
  91805. + wm = params->last_period_sample;
  91806. + buf_vaddr = (void __user *)pbuf->output_buffer_vaddr;
  91807. + buf_len = pbuf->output_buffer_length;
  91808. + }
  91809. +
  91810. + switch (width) {
  91811. + case ASRC_WIDTH_24_BIT:
  91812. + word_size = 4;
  91813. + break;
  91814. + case ASRC_WIDTH_16_BIT:
  91815. + case ASRC_WIDTH_8_BIT:
  91816. + word_size = 2;
  91817. + break;
  91818. + default:
  91819. + pair_err("invalid %sput word size!\n", in ? "in" : "out");
  91820. + return -EINVAL;
  91821. + }
  91822. +
  91823. + if (buf_len < word_size * params->channel_nums * wm) {
  91824. + pair_err("%sput buffer size[%d] is too small!\n",
  91825. + in ? "in" : "out", buf_len);
  91826. + return -EINVAL;
  91827. + }
  91828. +
  91829. + /* Copy origin data into input buffer */
  91830. + if (in && copy_from_user(dma_vaddr, buf_vaddr, buf_len))
  91831. + return -EFAULT;
  91832. +
  91833. + *dma_len = buf_len;
  91834. + if (!in)
  91835. + *dma_len -= wm * word_size * params->channel_nums;
  91836. +
  91837. + *sg_nodes = *dma_len / ASRC_MAX_BUFFER_SIZE + 1;
  91838. +
  91839. + fifo_addr = asrc_get_per_addr(params->index, in);
  91840. +
  91841. + return imx_asrc_dma_config(params, dma_channel, fifo_addr, dma_vaddr,
  91842. + *dma_len, in, width);
  91843. +}
  91844. +
  91845. +static int mxc_asrc_prepare_buffer(struct asrc_pair_params *params,
  91846. + struct asrc_convert_buffer *pbuf)
  91847. +{
  91848. + enum asrc_pair_index index = params->index;
  91849. + int ret;
  91850. +
  91851. + ret = mxc_asrc_prepare_io_buffer(params, pbuf, true);
  91852. + if (ret) {
  91853. + pair_err("failed to prepare input buffer: %d\n", ret);
  91854. + return ret;
  91855. + }
  91856. +
  91857. + ret = mxc_asrc_prepare_io_buffer(params, pbuf, false);
  91858. + if (ret) {
  91859. + pair_err("failed to prepare output buffer: %d\n", ret);
  91860. + return ret;
  91861. + }
  91862. +
  91863. + return 0;
  91864. +}
  91865. +
  91866. +int mxc_asrc_process_io_buffer(struct asrc_pair_params *params,
  91867. + struct asrc_convert_buffer *pbuf, bool in)
  91868. +{
  91869. + void *last_vaddr = params->output_last_period.dma_vaddr;
  91870. + unsigned int *last_len = &params->output_last_period.length;
  91871. + enum asrc_pair_index index = params->index;
  91872. + unsigned int dma_len, *buf_len;
  91873. + struct completion *complete;
  91874. + void __user *buf_vaddr;
  91875. + void *dma_vaddr;
  91876. +
  91877. + if (in) {
  91878. + dma_vaddr = params->input_dma_total.dma_vaddr;
  91879. + dma_len = params->input_dma_total.length;
  91880. + buf_len = &pbuf->input_buffer_length;
  91881. + complete = &params->input_complete;
  91882. + buf_vaddr = (void __user *)pbuf->input_buffer_vaddr;
  91883. + } else {
  91884. + dma_vaddr = params->output_dma_total.dma_vaddr;
  91885. + dma_len = params->output_dma_total.length;
  91886. + buf_len = &pbuf->output_buffer_length;
  91887. + complete = &params->lastperiod_complete;
  91888. + buf_vaddr = (void __user *)pbuf->output_buffer_vaddr;
  91889. + }
  91890. +
  91891. + if (!wait_for_completion_interruptible_timeout(complete, 10 * HZ)) {
  91892. + pair_err("%s task timeout\n", in ? "input dma" : "last period");
  91893. + return -ETIME;
  91894. + } else if (signal_pending(current)) {
  91895. + pair_err("%sput task forcibly aborted\n", in ? "in" : "out");
  91896. + return -ERESTARTSYS;
  91897. + }
  91898. +
  91899. + init_completion(complete);
  91900. +
  91901. + *buf_len = dma_len;
  91902. +
  91903. + /* Only output need return data to user space */
  91904. + if (!in) {
  91905. + if (copy_to_user(buf_vaddr, dma_vaddr, dma_len))
  91906. + return -EFAULT;
  91907. +
  91908. + *buf_len += *last_len;
  91909. +
  91910. + if (copy_to_user(buf_vaddr + dma_len, last_vaddr, *last_len))
  91911. + return -EFAULT;
  91912. + }
  91913. +
  91914. + return 0;
  91915. +}
  91916. +
  91917. +int mxc_asrc_process_buffer(struct asrc_pair_params *params,
  91918. + struct asrc_convert_buffer *pbuf)
  91919. +{
  91920. + enum asrc_pair_index index = params->index;
  91921. + int ret;
  91922. +
  91923. + ret = mxc_asrc_process_io_buffer(params, pbuf, true);
  91924. + if (ret) {
  91925. + pair_err("failed to process input buffer: %d\n", ret);
  91926. + return ret;
  91927. + }
  91928. +
  91929. + ret = mxc_asrc_process_io_buffer(params, pbuf, false);
  91930. + if (ret) {
  91931. + pair_err("failed to process output buffer: %d\n", ret);
  91932. + return ret;
  91933. + }
  91934. +
  91935. + return 0;
  91936. +}
  91937. +
  91938. +#ifdef ASRC_POLLING_WITHOUT_DMA
  91939. +static void asrc_write_one_to_input_FIFO(enum asrc_pair_index index, u32 val)
  91940. +{
  91941. + regmap_write(asrc->regmap, REG_ASRDI(index), val);
  91942. +}
  91943. +
  91944. +/* THIS FUNCTION ONLY EXISTS FOR DEBUGGING AND ONLY SUPPORTS TWO CHANNELS */
  91945. +static void asrc_polling_debug(struct asrc_pair_params *params)
  91946. +{
  91947. + enum asrc_pair_index index = params->index;
  91948. + u32 *in24 = params->input_dma_total.dma_vaddr;
  91949. + u32 dma_len = params->input_dma_total.length / (params->channel_nums * 4);
  91950. + u32 size, i, j, t_size, reg;
  91951. + u32 *reg24 = params->output_dma_total.dma_vaddr;
  91952. +
  91953. + t_size = 0;
  91954. +
  91955. + for (i = 0; i < dma_len; ) {
  91956. + for (j = 0; j < 2; j++) {
  91957. + asrc_write_one_to_input_FIFO(index, *in24);
  91958. + in24++;
  91959. + asrc_write_one_to_input_FIFO(index, *in24);
  91960. + in24++;
  91961. + i++;
  91962. + }
  91963. + udelay(50);
  91964. + udelay(50 * params->output_sample_rate / params->input_sample_rate);
  91965. +
  91966. + size = asrc_get_output_FIFO_size(index);
  91967. + for (j = 0; j < size; j++) {
  91968. + reg = asrc_read_one_from_output_FIFO(index);
  91969. + *(reg24) = reg;
  91970. + reg24++;
  91971. + reg = asrc_read_one_from_output_FIFO(index);
  91972. + *(reg24) = reg;
  91973. + reg24++;
  91974. + }
  91975. + t_size += size;
  91976. + }
  91977. +
  91978. + mdelay(1);
  91979. + size = asrc_get_output_FIFO_size(index);
  91980. + for (j = 0; j < size; j++) {
  91981. + reg = asrc_read_one_from_output_FIFO(index);
  91982. + *(reg24) = reg;
  91983. + reg24++;
  91984. + reg = asrc_read_one_from_output_FIFO(index);
  91985. + *(reg24) = reg;
  91986. + reg24++;
  91987. + }
  91988. + t_size += size;
  91989. +
  91990. + params->output_dma_total.length = t_size * params->channel_nums * 4;
  91991. + params->output_last_period.length = 0;
  91992. +
  91993. + dma_unmap_sg(NULL, params->input_sg, params->input_sg_nodes,
  91994. + DMA_MEM_TO_DEV);
  91995. + dma_unmap_sg(NULL, params->output_sg, params->output_sg_nodes,
  91996. + DMA_DEV_TO_MEM);
  91997. +
  91998. + complete(&params->input_complete);
  91999. + complete(&params->lastperiod_complete);
  92000. +}
  92001. +#else
  92002. +static void mxc_asrc_submit_dma(struct asrc_pair_params *params)
  92003. +{
  92004. + enum asrc_pair_index index = params->index;
  92005. + u32 size = asrc_get_output_FIFO_size(params->index);
  92006. + int i, j;
  92007. +
  92008. + /* Read all data in OUTPUT FIFO */
  92009. + while (size) {
  92010. + for (j = 0; j < size; j++)
  92011. + for (i = 0; i < params->channel_nums; i++)
  92012. + asrc_read_one_from_output_FIFO(index);
  92013. + /* Fetch the data every 100us */
  92014. + udelay(100);
  92015. +
  92016. + size = asrc_get_output_FIFO_size(index);
  92017. + }
  92018. +
  92019. + /* Submit dma request */
  92020. + dmaengine_submit(params->desc_in);
  92021. + dma_async_issue_pending(params->desc_in->chan);
  92022. +
  92023. + dmaengine_submit(params->desc_out);
  92024. + dma_async_issue_pending(params->desc_out->chan);
  92025. +
  92026. + /*
  92027. + * Clear dma request during the stall state of ASRC:
  92028. + * During STALL state, the remaining in input fifo would never be
  92029. + * smaller than the input threshold while the output fifo would not
  92030. + * be bigger than output one. Thus the dma request would be cleared.
  92031. + */
  92032. + asrc_set_watermark(index, ASRC_FIFO_THRESHOLD_MIN, ASRC_FIFO_THRESHOLD_MAX);
  92033. +
  92034. + /* Update the real input threshold to raise dma request */
  92035. + asrc_set_watermark(index, params->input_wm, params->output_wm);
  92036. +}
  92037. +#endif
  92038. +
  92039. +static long asrc_ioctl_req_pair(struct asrc_pair_params *params,
  92040. + void __user *user)
  92041. +{
  92042. + struct asrc_req req;
  92043. + long ret;
  92044. +
  92045. + ret = copy_from_user(&req, user, sizeof(req));
  92046. + if (ret) {
  92047. + dev_err(asrc->dev, "failed to get req from user space: %ld\n", ret);
  92048. + return ret;
  92049. + }
  92050. +
  92051. + ret = asrc_req_pair(req.chn_num, &req.index);
  92052. + if (ret) {
  92053. + dev_err(asrc->dev, "failed to request pair: %ld\n", ret);
  92054. + return ret;
  92055. + }
  92056. +
  92057. + params->pair_hold = 1;
  92058. + params->index = req.index;
  92059. + params->channel_nums = req.chn_num;
  92060. +
  92061. + ret = copy_to_user(user, &req, sizeof(req));
  92062. + if (ret) {
  92063. + dev_err(asrc->dev, "failed to send req to user space: %ld\n", ret);
  92064. + return ret;
  92065. + }
  92066. +
  92067. + return 0;
  92068. +}
  92069. +
  92070. +static long asrc_ioctl_config_pair(struct asrc_pair_params *params,
  92071. + void __user *user)
  92072. +{
  92073. + struct asrc_config config;
  92074. + enum asrc_pair_index index;
  92075. + long ret;
  92076. +
  92077. + ret = copy_from_user(&config, user, sizeof(config));
  92078. + if (ret) {
  92079. + dev_err(asrc->dev, "failed to get config from user space: %ld\n", ret);
  92080. + return ret;
  92081. + }
  92082. +
  92083. + index = config.pair;
  92084. +
  92085. + ret = asrc_config_pair(&config);
  92086. + if (ret) {
  92087. + pair_err("failed to config pair: %ld\n", ret);
  92088. + return ret;
  92089. + }
  92090. +
  92091. + params->input_wm = 4;
  92092. + params->output_wm = 2;
  92093. +
  92094. + ret = asrc_set_watermark(index, params->input_wm, params->output_wm);
  92095. + if (ret)
  92096. + return ret;
  92097. +
  92098. + params->output_buffer_size = config.dma_buffer_size;
  92099. + params->input_buffer_size = config.dma_buffer_size;
  92100. + if (config.buffer_num > ASRC_DMA_BUFFER_NUM)
  92101. + params->buffer_num = ASRC_DMA_BUFFER_NUM;
  92102. + else
  92103. + params->buffer_num = config.buffer_num;
  92104. +
  92105. + params->input_dma_total.length = ASRC_DMA_BUFFER_SIZE;
  92106. + params->output_dma_total.length = ASRC_DMA_BUFFER_SIZE;
  92107. +
  92108. + params->input_word_width = config.input_word_width;
  92109. + params->output_word_width = config.output_word_width;
  92110. +
  92111. + params->input_sample_rate = config.input_sample_rate;
  92112. + params->output_sample_rate = config.output_sample_rate;
  92113. +
  92114. + params->last_period_sample = ASRC_OUTPUT_LAST_SAMPLE_DEFAULT;
  92115. +
  92116. + ret = mxc_allocate_dma_buf(params);
  92117. + if (ret) {
  92118. + pair_err("failed to allocate dma buffer: %ld\n", ret);
  92119. + return ret;
  92120. + }
  92121. +
  92122. + /* Request DMA channel for both input and output */
  92123. + params->input_dma_channel = imx_asrc_get_dma_channel(index, true);
  92124. + if (params->input_dma_channel == NULL) {
  92125. + pair_err("failed to request input task dma channel\n");
  92126. + return -EBUSY;
  92127. + }
  92128. +
  92129. + params->output_dma_channel = imx_asrc_get_dma_channel(index, false);
  92130. + if (params->output_dma_channel == NULL) {
  92131. + pair_err("failed to request output task dma channel\n");
  92132. + return -EBUSY;
  92133. + }
  92134. +
  92135. + init_completion(&params->input_complete);
  92136. + init_completion(&params->output_complete);
  92137. + init_completion(&params->lastperiod_complete);
  92138. +
  92139. + /* Add work struct to receive last period of output data */
  92140. + INIT_WORK(&params->task_output_work, asrc_output_task_worker);
  92141. +
  92142. + ret = copy_to_user(user, &config, sizeof(config));
  92143. + if (ret) {
  92144. + pair_err("failed to send config to user space: %ld\n", ret);
  92145. + return ret;
  92146. + }
  92147. +
  92148. + return 0;
  92149. +}
  92150. +
  92151. +static long asrc_ioctl_release_pair(struct asrc_pair_params *params,
  92152. + void __user *user)
  92153. +{
  92154. + enum asrc_pair_index index;
  92155. + unsigned long lock_flags;
  92156. + long ret;
  92157. +
  92158. + ret = copy_from_user(&index, user, sizeof(index));
  92159. + if (ret) {
  92160. + dev_err(asrc->dev, "failed to get index from user space: %ld\n", ret);
  92161. + return ret;
  92162. + }
  92163. +
  92164. + /* index might be not valid due to some application failure. */
  92165. + if (index < 0)
  92166. + return -EINVAL;
  92167. +
  92168. + params->asrc_active = 0;
  92169. +
  92170. + spin_lock_irqsave(&pair_lock, lock_flags);
  92171. + params->pair_hold = 0;
  92172. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  92173. +
  92174. + if (params->input_dma_channel)
  92175. + dma_release_channel(params->input_dma_channel);
  92176. + if (params->output_dma_channel)
  92177. + dma_release_channel(params->output_dma_channel);
  92178. + mxc_free_dma_buf(params);
  92179. + asrc_release_pair(index);
  92180. + asrc_finish_conv(index);
  92181. +
  92182. + return 0;
  92183. +}
  92184. +
  92185. +static long asrc_ioctl_convert(struct asrc_pair_params *params,
  92186. + void __user *user)
  92187. +{
  92188. + enum asrc_pair_index index = params->index;
  92189. + struct asrc_convert_buffer buf;
  92190. + long ret;
  92191. +
  92192. + ret = copy_from_user(&buf, user, sizeof(buf));
  92193. + if (ret) {
  92194. + pair_err("failed to get buf from user space: %ld\n", ret);
  92195. + return ret;
  92196. + }
  92197. +
  92198. + ret = mxc_asrc_prepare_buffer(params, &buf);
  92199. + if (ret) {
  92200. + pair_err("failed to prepare buffer: %ld\n", ret);
  92201. + return ret;
  92202. + }
  92203. +
  92204. +#ifdef ASRC_POLLING_WITHOUT_DMA
  92205. + asrc_polling_debug(params);
  92206. +#else
  92207. + mxc_asrc_submit_dma(params);
  92208. +#endif
  92209. +
  92210. + ret = mxc_asrc_process_buffer(params, &buf);
  92211. + if (ret) {
  92212. + pair_err("failed to process buffer: %ld\n", ret);
  92213. + return ret;
  92214. + }
  92215. +
  92216. + ret = copy_to_user(user, &buf, sizeof(buf));
  92217. + if (ret) {
  92218. + pair_err("failed to send buf to user space: %ld\n", ret);
  92219. + return ret;
  92220. + }
  92221. +
  92222. + return 0;
  92223. +}
  92224. +
  92225. +static long asrc_ioctl_start_conv(struct asrc_pair_params *params,
  92226. + void __user *user)
  92227. +{
  92228. + enum asrc_pair_index index;
  92229. + long ret;
  92230. +
  92231. + ret = copy_from_user(&index, user, sizeof(index));
  92232. + if (ret) {
  92233. + dev_err(asrc->dev, "failed to get index from user space: %ld\n", ret);
  92234. + return ret;
  92235. + }
  92236. +
  92237. + params->asrc_active = 1;
  92238. + asrc_start_conv(index);
  92239. +
  92240. + return 0;
  92241. +}
  92242. +
  92243. +static long asrc_ioctl_stop_conv(struct asrc_pair_params *params,
  92244. + void __user *user)
  92245. +{
  92246. + enum asrc_pair_index index;
  92247. + long ret;
  92248. +
  92249. + ret = copy_from_user(&index, user, sizeof(index));
  92250. + if (ret) {
  92251. + dev_err(asrc->dev, "failed to get index from user space: %ld\n", ret);
  92252. + return ret;
  92253. + }
  92254. +
  92255. + dmaengine_terminate_all(params->input_dma_channel);
  92256. + dmaengine_terminate_all(params->output_dma_channel);
  92257. +
  92258. + asrc_stop_conv(index);
  92259. + params->asrc_active = 0;
  92260. +
  92261. + return 0;
  92262. +}
  92263. +
  92264. +static long asrc_ioctl_status(struct asrc_pair_params *params,
  92265. + void __user *user)
  92266. +{
  92267. + enum asrc_pair_index index = params->index;
  92268. + struct asrc_status_flags flags;
  92269. + long ret;
  92270. +
  92271. + ret = copy_from_user(&flags, user, sizeof(flags));
  92272. + if (ret) {
  92273. + pair_err("failed to get flags from user space: %ld\n", ret);
  92274. + return ret;
  92275. + }
  92276. +
  92277. + asrc_get_status(&flags);
  92278. +
  92279. + ret = copy_to_user(user, &flags, sizeof(flags));
  92280. + if (ret) {
  92281. + pair_err("failed to send flags to user space: %ld\n", ret);
  92282. + return ret;
  92283. + }
  92284. +
  92285. + return 0;
  92286. +}
  92287. +
  92288. +static long asrc_ioctl_flush(struct asrc_pair_params *params,
  92289. + void __user *user)
  92290. +{
  92291. + enum asrc_pair_index index = params->index;
  92292. + init_completion(&params->input_complete);
  92293. + init_completion(&params->output_complete);
  92294. + init_completion(&params->lastperiod_complete);
  92295. +
  92296. + /* Release DMA and request again */
  92297. + dma_release_channel(params->input_dma_channel);
  92298. + dma_release_channel(params->output_dma_channel);
  92299. +
  92300. + params->input_dma_channel = imx_asrc_get_dma_channel(index, true);
  92301. + if (params->input_dma_channel == NULL) {
  92302. + pair_err("failed to request input task dma channel\n");
  92303. + return -EBUSY;
  92304. + }
  92305. +
  92306. + params->output_dma_channel = imx_asrc_get_dma_channel(index, false);
  92307. + if (params->output_dma_channel == NULL) {
  92308. + pair_err("failed to request output task dma channel\n");
  92309. + return -EBUSY;
  92310. + }
  92311. +
  92312. + return 0;
  92313. +}
  92314. +
  92315. +static long asrc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  92316. +{
  92317. + struct asrc_pair_params *params = file->private_data;
  92318. + void __user *user = (void __user *)arg;
  92319. + long ret = 0;
  92320. +
  92321. + switch (cmd) {
  92322. + case ASRC_REQ_PAIR:
  92323. + ret = asrc_ioctl_req_pair(params, user);
  92324. + break;
  92325. + case ASRC_CONFIG_PAIR:
  92326. + ret = asrc_ioctl_config_pair(params, user);
  92327. + break;
  92328. + case ASRC_RELEASE_PAIR:
  92329. + ret = asrc_ioctl_release_pair(params, user);
  92330. + break;
  92331. + case ASRC_CONVERT:
  92332. + ret = asrc_ioctl_convert(params, user);
  92333. + break;
  92334. + case ASRC_START_CONV:
  92335. + ret = asrc_ioctl_start_conv(params, user);
  92336. + dump_regs();
  92337. + break;
  92338. + case ASRC_STOP_CONV:
  92339. + ret = asrc_ioctl_stop_conv(params, user);
  92340. + break;
  92341. + case ASRC_STATUS:
  92342. + ret = asrc_ioctl_status(params, user);
  92343. + break;
  92344. + case ASRC_FLUSH:
  92345. + ret = asrc_ioctl_flush(params, user);
  92346. + break;
  92347. + default:
  92348. + dev_err(asrc->dev, "invalid ioctl cmd!\n");
  92349. + break;
  92350. + }
  92351. +
  92352. + return ret;
  92353. +}
  92354. +
  92355. +static int mxc_asrc_open(struct inode *inode, struct file *file)
  92356. +{
  92357. + struct asrc_pair_params *params;
  92358. + int ret = 0;
  92359. +
  92360. + ret = signal_pending(current);
  92361. + if (ret) {
  92362. + dev_err(asrc->dev, "current process has a signal pending\n");
  92363. + return ret;
  92364. + }
  92365. +
  92366. + params = kzalloc(sizeof(struct asrc_pair_params), GFP_KERNEL);
  92367. + if (params == NULL) {
  92368. + dev_err(asrc->dev, "failed to allocate pair_params\n");
  92369. + return -ENOBUFS;
  92370. + }
  92371. +
  92372. + file->private_data = params;
  92373. +
  92374. + return ret;
  92375. +}
  92376. +
  92377. +static int mxc_asrc_close(struct inode *inode, struct file *file)
  92378. +{
  92379. + struct asrc_pair_params *params;
  92380. + unsigned long lock_flags;
  92381. +
  92382. + params = file->private_data;
  92383. +
  92384. + if (!params)
  92385. + return 0;
  92386. +
  92387. + if (params->asrc_active) {
  92388. + params->asrc_active = 0;
  92389. +
  92390. + dmaengine_terminate_all(params->input_dma_channel);
  92391. + dmaengine_terminate_all(params->output_dma_channel);
  92392. +
  92393. + asrc_stop_conv(params->index);
  92394. +
  92395. + complete(&params->input_complete);
  92396. + complete(&params->output_complete);
  92397. + complete(&params->lastperiod_complete);
  92398. + }
  92399. +
  92400. + if (params->pair_hold) {
  92401. + spin_lock_irqsave(&pair_lock, lock_flags);
  92402. + params->pair_hold = 0;
  92403. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  92404. +
  92405. + if (params->input_dma_channel)
  92406. + dma_release_channel(params->input_dma_channel);
  92407. + if (params->output_dma_channel)
  92408. + dma_release_channel(params->output_dma_channel);
  92409. +
  92410. + mxc_free_dma_buf(params);
  92411. +
  92412. + asrc_release_pair(params->index);
  92413. + asrc_finish_conv(params->index);
  92414. + }
  92415. +
  92416. + kfree(params);
  92417. + file->private_data = NULL;
  92418. +
  92419. + return 0;
  92420. +}
  92421. +
  92422. +static int mxc_asrc_mmap(struct file *file, struct vm_area_struct *vma)
  92423. +{
  92424. + unsigned long size = vma->vm_end - vma->vm_start;
  92425. + int ret;
  92426. +
  92427. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  92428. +
  92429. + ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  92430. + size, vma->vm_page_prot);
  92431. + if (ret) {
  92432. + dev_err(asrc->dev, "failed to memory map!\n");
  92433. + return ret;
  92434. + }
  92435. +
  92436. + vma->vm_flags &= ~VM_IO;
  92437. +
  92438. + return ret;
  92439. +}
  92440. +
  92441. +static const struct file_operations asrc_fops = {
  92442. + .owner = THIS_MODULE,
  92443. + .unlocked_ioctl = asrc_ioctl,
  92444. + .mmap = mxc_asrc_mmap,
  92445. + .open = mxc_asrc_open,
  92446. + .release = mxc_asrc_close,
  92447. +};
  92448. +
  92449. +static struct miscdevice asrc_miscdev = {
  92450. + .name = "mxc_asrc",
  92451. + .fops = &asrc_fops,
  92452. + .minor = MISC_DYNAMIC_MINOR,
  92453. +};
  92454. +
  92455. +static int asrc_read_proc_attr(struct file *file, char __user *buf,
  92456. + size_t count, loff_t *off)
  92457. +{
  92458. + char tmpbuf[80];
  92459. + int len = 0;
  92460. + u32 reg;
  92461. +
  92462. + if (*off)
  92463. + return 0;
  92464. +
  92465. + regmap_read(asrc->regmap, REG_ASRCNCR, &reg);
  92466. +
  92467. + len += sprintf(tmpbuf, "ANCA: %d\nANCB: %d\nANCC: %d\n",
  92468. + ASRCNCR_ANCx_get(ASRC_PAIR_A, reg, asrc->channel_bits),
  92469. + ASRCNCR_ANCx_get(ASRC_PAIR_B, reg, asrc->channel_bits),
  92470. + ASRCNCR_ANCx_get(ASRC_PAIR_C, reg, asrc->channel_bits));
  92471. +
  92472. + if (len > count)
  92473. + return 0;
  92474. +
  92475. + if (copy_to_user(buf, &tmpbuf, len))
  92476. + return -EFAULT;
  92477. +
  92478. + *off += len;
  92479. +
  92480. + return len;
  92481. +}
  92482. +
  92483. +#define ASRC_MAX_PROC_BUFFER_SIZE 63
  92484. +
  92485. +static int asrc_write_proc_attr(struct file *file, const char __user *buffer,
  92486. + size_t count, loff_t *data)
  92487. +{
  92488. + char buf[ASRC_MAX_PROC_BUFFER_SIZE];
  92489. + int na, nb, nc;
  92490. + int total;
  92491. +
  92492. + if (count > ASRC_MAX_PROC_BUFFER_SIZE) {
  92493. + dev_err(asrc->dev, "proc write: the input string was too long\n");
  92494. + return -EINVAL;
  92495. + }
  92496. +
  92497. + if (copy_from_user(buf, buffer, count)) {
  92498. + dev_err(asrc->dev, "proc write: failed to copy buffer from user\n");
  92499. + return -EFAULT;
  92500. + }
  92501. +
  92502. + sscanf(buf, "ANCA: %d\nANCB: %d\nANCC: %d", &na, &nb, &nc);
  92503. +
  92504. + total = asrc->channel_bits > 3 ? 10 : 5;
  92505. +
  92506. + if (na + nb + nc > total) {
  92507. + dev_err(asrc->dev, "don't surpass %d for total\n", total);
  92508. + return -EINVAL;
  92509. + } else if (na % 2 != 0 || nb % 2 != 0 || nc % 2 != 0) {
  92510. + dev_err(asrc->dev, "please set an even number for each pair\n");
  92511. + return -EINVAL;
  92512. + } else if (na < 0 || nb < 0 || nc < 0) {
  92513. + dev_err(asrc->dev, "please set an positive number for each pair\n");
  92514. + return -EINVAL;
  92515. + }
  92516. +
  92517. +
  92518. + asrc->asrc_pair[ASRC_PAIR_A].chn_max = na;
  92519. + asrc->asrc_pair[ASRC_PAIR_B].chn_max = nb;
  92520. + asrc->asrc_pair[ASRC_PAIR_C].chn_max = nc;
  92521. +
  92522. + /* Update channel number settings */
  92523. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  92524. + ASRCNCR_ANCx_MASK(ASRC_PAIR_A, asrc->channel_bits),
  92525. + ASRCNCR_ANCx_set(ASRC_PAIR_A, na, asrc->channel_bits));
  92526. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  92527. + ASRCNCR_ANCx_MASK(ASRC_PAIR_B, asrc->channel_bits),
  92528. + ASRCNCR_ANCx_set(ASRC_PAIR_B, nb, asrc->channel_bits));
  92529. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  92530. + ASRCNCR_ANCx_MASK(ASRC_PAIR_C, asrc->channel_bits),
  92531. + ASRCNCR_ANCx_set(ASRC_PAIR_C, nc, asrc->channel_bits));
  92532. +
  92533. + return count;
  92534. +}
  92535. +
  92536. +static const struct file_operations asrc_proc_fops = {
  92537. + .read = asrc_read_proc_attr,
  92538. + .write = asrc_write_proc_attr,
  92539. +};
  92540. +
  92541. +static void asrc_proc_create(void)
  92542. +{
  92543. + struct proc_dir_entry *proc_attr;
  92544. +
  92545. + asrc->proc_asrc = proc_mkdir(ASRC_PROC_PATH, NULL);
  92546. + if (!asrc->proc_asrc) {
  92547. + dev_err(asrc->dev, "failed to create proc entry %s\n", ASRC_PROC_PATH);
  92548. + return;
  92549. + }
  92550. +
  92551. + proc_attr = proc_create("ChSettings", S_IFREG | S_IRUGO | S_IWUSR,
  92552. + asrc->proc_asrc, &asrc_proc_fops);
  92553. + if (!proc_attr) {
  92554. + remove_proc_entry(ASRC_PROC_PATH, NULL);
  92555. + dev_err(asrc->dev, "failed to create proc attribute entry\n");
  92556. + }
  92557. +}
  92558. +
  92559. +static void asrc_proc_remove(void)
  92560. +{
  92561. + remove_proc_entry("ChSettings", asrc->proc_asrc);
  92562. + remove_proc_entry(ASRC_PROC_PATH, NULL);
  92563. +}
  92564. +
  92565. +
  92566. +static bool asrc_readable_reg(struct device *dev, unsigned int reg)
  92567. +{
  92568. + switch (reg) {
  92569. + case REG_ASRCTR:
  92570. + case REG_ASRIER:
  92571. + case REG_ASRCNCR:
  92572. + case REG_ASRCFG:
  92573. + case REG_ASRCSR:
  92574. + case REG_ASRCDR1:
  92575. + case REG_ASRCDR2:
  92576. + case REG_ASRSTR:
  92577. + case REG_ASRPM1:
  92578. + case REG_ASRPM2:
  92579. + case REG_ASRPM3:
  92580. + case REG_ASRPM4:
  92581. + case REG_ASRPM5:
  92582. + case REG_ASRTFR1:
  92583. + case REG_ASRCCR:
  92584. + case REG_ASRDOA:
  92585. + case REG_ASRDOB:
  92586. + case REG_ASRDOC:
  92587. + case REG_ASRIDRHA:
  92588. + case REG_ASRIDRLA:
  92589. + case REG_ASRIDRHB:
  92590. + case REG_ASRIDRLB:
  92591. + case REG_ASRIDRHC:
  92592. + case REG_ASRIDRLC:
  92593. + case REG_ASR76K:
  92594. + case REG_ASR56K:
  92595. + case REG_ASRMCRA:
  92596. + case REG_ASRFSTA:
  92597. + case REG_ASRMCRB:
  92598. + case REG_ASRFSTB:
  92599. + case REG_ASRMCRC:
  92600. + case REG_ASRFSTC:
  92601. + case REG_ASRMCR1A:
  92602. + case REG_ASRMCR1B:
  92603. + case REG_ASRMCR1C:
  92604. + return true;
  92605. + default:
  92606. + return false;
  92607. + }
  92608. +}
  92609. +
  92610. +static bool asrc_writeable_reg(struct device *dev, unsigned int reg)
  92611. +{
  92612. + switch (reg) {
  92613. + case REG_ASRCTR:
  92614. + case REG_ASRIER:
  92615. + case REG_ASRCNCR:
  92616. + case REG_ASRCFG:
  92617. + case REG_ASRCSR:
  92618. + case REG_ASRCDR1:
  92619. + case REG_ASRCDR2:
  92620. + case REG_ASRSTR:
  92621. + case REG_ASRPM1:
  92622. + case REG_ASRPM2:
  92623. + case REG_ASRPM3:
  92624. + case REG_ASRPM4:
  92625. + case REG_ASRPM5:
  92626. + case REG_ASRTFR1:
  92627. + case REG_ASRCCR:
  92628. + case REG_ASRDIA:
  92629. + case REG_ASRDIB:
  92630. + case REG_ASRDIC:
  92631. + case REG_ASRIDRHA:
  92632. + case REG_ASRIDRLA:
  92633. + case REG_ASRIDRHB:
  92634. + case REG_ASRIDRLB:
  92635. + case REG_ASRIDRHC:
  92636. + case REG_ASRIDRLC:
  92637. + case REG_ASR76K:
  92638. + case REG_ASR56K:
  92639. + case REG_ASRMCRA:
  92640. + case REG_ASRMCRB:
  92641. + case REG_ASRMCRC:
  92642. + case REG_ASRMCR1A:
  92643. + case REG_ASRMCR1B:
  92644. + case REG_ASRMCR1C:
  92645. + return true;
  92646. + default:
  92647. + return false;
  92648. + }
  92649. +}
  92650. +
  92651. +static struct regmap_config asrc_regmap_config = {
  92652. + .reg_bits = 32,
  92653. + .reg_stride = 4,
  92654. + .val_bits = 32,
  92655. +
  92656. + .max_register = REG_ASRMCR1C,
  92657. + .readable_reg = asrc_readable_reg,
  92658. + .writeable_reg = asrc_writeable_reg,
  92659. +};
  92660. +
  92661. +static int mxc_asrc_probe(struct platform_device *pdev)
  92662. +{
  92663. + const struct of_device_id *of_id = of_match_device(fsl_asrc_ids, &pdev->dev);
  92664. + struct device_node *np = pdev->dev.of_node;
  92665. + enum mxc_asrc_type devtype;
  92666. + struct resource *res;
  92667. + void __iomem *regs;
  92668. + int ret;
  92669. +
  92670. + /* Check if the device is existed */
  92671. + if (!np)
  92672. + return -ENODEV;
  92673. +
  92674. + asrc = devm_kzalloc(&pdev->dev, sizeof(struct asrc_data), GFP_KERNEL);
  92675. + if (!asrc)
  92676. + return -ENOMEM;
  92677. +
  92678. + if (of_id) {
  92679. + const struct platform_device_id *id_entry = of_id->data;
  92680. + devtype = id_entry->driver_data;
  92681. + } else {
  92682. + devtype = pdev->id_entry->driver_data;
  92683. + }
  92684. +
  92685. + asrc->dev = &pdev->dev;
  92686. + asrc->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  92687. +
  92688. + asrc->asrc_pair[ASRC_PAIR_A].chn_max = 2;
  92689. + asrc->asrc_pair[ASRC_PAIR_B].chn_max = 6;
  92690. + asrc->asrc_pair[ASRC_PAIR_C].chn_max = 2;
  92691. + asrc->asrc_pair[ASRC_PAIR_A].overload_error = 0;
  92692. + asrc->asrc_pair[ASRC_PAIR_B].overload_error = 0;
  92693. + asrc->asrc_pair[ASRC_PAIR_C].overload_error = 0;
  92694. +
  92695. + /* Map the address */
  92696. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  92697. + if (IS_ERR(res)) {
  92698. + dev_err(&pdev->dev, "could not determine device resources\n");
  92699. + return PTR_ERR(res);
  92700. + }
  92701. +
  92702. + regs = devm_ioremap_resource(&pdev->dev, res);
  92703. + if (IS_ERR(regs)) {
  92704. + dev_err(&pdev->dev, "could not map device resources\n");
  92705. + return PTR_ERR(regs);
  92706. + }
  92707. + asrc->paddr = res->start;
  92708. +
  92709. + /* Register regmap and let it prepare core clock */
  92710. + asrc->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
  92711. + "core", regs, &asrc_regmap_config);
  92712. + if (IS_ERR(asrc->regmap)) {
  92713. + dev_err(&pdev->dev, "regmap init failed\n");
  92714. + return PTR_ERR(asrc->regmap);
  92715. + }
  92716. +
  92717. + asrc->irq = platform_get_irq(pdev, 0);
  92718. + if (asrc->irq == NO_IRQ) {
  92719. + dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
  92720. + return asrc->irq;
  92721. + }
  92722. +
  92723. + ret = devm_request_irq(&pdev->dev, asrc->irq, asrc_isr, 0, np->name, NULL);
  92724. + if (ret) {
  92725. + dev_err(&pdev->dev, "could not claim irq %u: %d\n", asrc->irq, ret);
  92726. + return ret;
  92727. + }
  92728. +
  92729. + asrc->asrc_clk = devm_clk_get(&pdev->dev, "core");
  92730. + if (IS_ERR(asrc->asrc_clk)) {
  92731. + dev_err(&pdev->dev, "failed to get core clock\n");
  92732. + return PTR_ERR(asrc->asrc_clk);
  92733. + }
  92734. +
  92735. + asrc->dma_clk = devm_clk_get(&pdev->dev, "dma");
  92736. + if (IS_ERR(asrc->dma_clk)) {
  92737. + dev_err(&pdev->dev, "failed to get dma script clock\n");
  92738. + return PTR_ERR(asrc->dma_clk);
  92739. + }
  92740. +
  92741. + switch (devtype) {
  92742. + case IMX35_ASRC:
  92743. + asrc->channel_bits = 3;
  92744. + input_clk_map = input_clk_map_v1;
  92745. + output_clk_map = output_clk_map_v1;
  92746. + break;
  92747. + case IMX53_ASRC:
  92748. + asrc->channel_bits = 4;
  92749. + input_clk_map = input_clk_map_v2;
  92750. + output_clk_map = output_clk_map_v2;
  92751. + break;
  92752. + default:
  92753. + dev_err(&pdev->dev, "unsupported device type\n");
  92754. + return -EINVAL;
  92755. + }
  92756. +
  92757. + ret = misc_register(&asrc_miscdev);
  92758. + if (ret) {
  92759. + dev_err(&pdev->dev, "failed to register char device %d\n", ret);
  92760. + return ret;
  92761. + }
  92762. +
  92763. + asrc_proc_create();
  92764. +
  92765. + ret = mxc_init_asrc();
  92766. + if (ret) {
  92767. + dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
  92768. + goto err_misc;
  92769. + }
  92770. +
  92771. + dev_info(&pdev->dev, "mxc_asrc registered\n");
  92772. +
  92773. + return ret;
  92774. +
  92775. +err_misc:
  92776. + misc_deregister(&asrc_miscdev);
  92777. +
  92778. + return ret;
  92779. +}
  92780. +
  92781. +static int mxc_asrc_remove(struct platform_device *pdev)
  92782. +{
  92783. + asrc_proc_remove();
  92784. + misc_deregister(&asrc_miscdev);
  92785. +
  92786. + return 0;
  92787. +}
  92788. +
  92789. +static struct platform_driver mxc_asrc_driver = {
  92790. + .driver = {
  92791. + .name = "mxc_asrc",
  92792. + .of_match_table = fsl_asrc_ids,
  92793. + },
  92794. + .probe = mxc_asrc_probe,
  92795. + .remove = mxc_asrc_remove,
  92796. +};
  92797. +
  92798. +module_platform_driver(mxc_asrc_driver);
  92799. +
  92800. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  92801. +MODULE_DESCRIPTION("Asynchronous Sample Rate Converter");
  92802. +MODULE_LICENSE("GPL");
  92803. +MODULE_ALIAS("platform:mxc_asrc");
  92804. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c
  92805. --- linux-3.14.15/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c 1970-01-01 01:00:00.000000000 +0100
  92806. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c 2014-08-20 19:23:53.558845839 +0200
  92807. @@ -0,0 +1,932 @@
  92808. +/****************************************************************************
  92809. +*
  92810. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  92811. +*
  92812. +* This program is free software; you can redistribute it and/or modify
  92813. +* it under the terms of the GNU General Public License as published by
  92814. +* the Free Software Foundation; either version 2 of the license, or
  92815. +* (at your option) any later version.
  92816. +*
  92817. +* This program is distributed in the hope that it will be useful,
  92818. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  92819. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  92820. +* GNU General Public License for more details.
  92821. +*
  92822. +* You should have received a copy of the GNU General Public License
  92823. +* along with this program; if not write to the Free Software
  92824. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  92825. +*
  92826. +*****************************************************************************/
  92827. +
  92828. +
  92829. +#include "gc_hal.h"
  92830. +#include "gc_hal_kernel.h"
  92831. +
  92832. +#if gcdENABLE_VG
  92833. +
  92834. +#include "gc_hal_kernel_hardware_command_vg.h"
  92835. +
  92836. +#define _GC_OBJ_ZONE gcvZONE_COMMAND
  92837. +
  92838. +/******************************************************************************\
  92839. +****************************** gckVGCOMMAND API code *****************************
  92840. +\******************************************************************************/
  92841. +
  92842. +/*******************************************************************************
  92843. +**
  92844. +** gckVGCOMMAND_InitializeInfo
  92845. +**
  92846. +** Initialize architecture dependent command buffer information.
  92847. +**
  92848. +** INPUT:
  92849. +**
  92850. +** gckVGCOMMAND Command
  92851. +** Pointer to the Command object.
  92852. +**
  92853. +** OUTPUT:
  92854. +**
  92855. +** Nothing.
  92856. +*/
  92857. +gceSTATUS
  92858. +gckVGCOMMAND_InitializeInfo(
  92859. + IN gckVGCOMMAND Command
  92860. + )
  92861. +{
  92862. + gceSTATUS status;
  92863. + gcmkHEADER_ARG("Command=0x%x", Command);
  92864. +
  92865. + /* Verify the arguments. */
  92866. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  92867. +
  92868. + do
  92869. + {
  92870. + /* Reset interrupts. */
  92871. + Command->info.feBufferInt = -1;
  92872. + Command->info.tsOverflowInt = -1;
  92873. +
  92874. + /* Set command buffer attributes. */
  92875. + Command->info.addressAlignment = 64;
  92876. + Command->info.commandAlignment = 8;
  92877. +
  92878. + /* Determine command alignment address mask. */
  92879. + Command->info.addressMask = ((((gctUINT32) (Command->info.addressAlignment - 1)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) ((gctUINT32) (0 ) & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
  92880. +
  92881. + /* Query the number of bytes needed by the STATE command. */
  92882. + gcmkERR_BREAK(gckVGCOMMAND_StateCommand(
  92883. + Command, 0x0, gcvNULL, (gctUINT32)~0, 0,
  92884. + &Command->info.stateCommandSize
  92885. + ));
  92886. +
  92887. + /* Query the number of bytes needed by the RESTART command. */
  92888. + gcmkERR_BREAK(gckVGCOMMAND_RestartCommand(
  92889. + Command, gcvNULL, (gctUINT32)~0, 0,
  92890. + &Command->info.restartCommandSize
  92891. + ));
  92892. +
  92893. + /* Query the number of bytes needed by the FETCH command. */
  92894. + gcmkERR_BREAK(gckVGCOMMAND_FetchCommand(
  92895. + Command, gcvNULL, (gctUINT32)~0, 0,
  92896. + &Command->info.fetchCommandSize
  92897. + ));
  92898. +
  92899. + /* Query the number of bytes needed by the CALL command. */
  92900. + gcmkERR_BREAK(gckVGCOMMAND_CallCommand(
  92901. + Command, gcvNULL, (gctUINT32)~0, 0,
  92902. + &Command->info.callCommandSize
  92903. + ));
  92904. +
  92905. + /* Query the number of bytes needed by the RETURN command. */
  92906. + gcmkERR_BREAK(gckVGCOMMAND_ReturnCommand(
  92907. + Command, gcvNULL,
  92908. + &Command->info.returnCommandSize
  92909. + ));
  92910. +
  92911. + /* Query the number of bytes needed by the EVENT command. */
  92912. + gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
  92913. + Command, gcvNULL, gcvBLOCK_PIXEL, -1,
  92914. + &Command->info.eventCommandSize
  92915. + ));
  92916. +
  92917. + /* Query the number of bytes needed by the END command. */
  92918. + gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
  92919. + Command, gcvNULL, -1,
  92920. + &Command->info.endCommandSize
  92921. + ));
  92922. +
  92923. + /* Determine the tail reserve size. */
  92924. + Command->info.staticTailSize = gcmMAX(
  92925. + Command->info.fetchCommandSize,
  92926. + gcmMAX(
  92927. + Command->info.returnCommandSize,
  92928. + Command->info.endCommandSize
  92929. + )
  92930. + );
  92931. +
  92932. + /* Determine the maximum tail size. */
  92933. + Command->info.dynamicTailSize
  92934. + = Command->info.staticTailSize
  92935. + + Command->info.eventCommandSize * gcvBLOCK_COUNT;
  92936. + }
  92937. + while (gcvFALSE);
  92938. +
  92939. + gcmkFOOTER();
  92940. + /* Return status. */
  92941. + return status;
  92942. +}
  92943. +
  92944. +/*******************************************************************************
  92945. +**
  92946. +** gckVGCOMMAND_StateCommand
  92947. +**
  92948. +** Append a STATE command at the specified location in the command buffer.
  92949. +**
  92950. +** INPUT:
  92951. +**
  92952. +** gckVGCOMMAND Command
  92953. +** Pointer to an gckVGCOMMAND object.
  92954. +**
  92955. +** gctUINT32 Pipe
  92956. +** Harwdare destination pipe.
  92957. +**
  92958. +** gctPOINTER Logical
  92959. +** Pointer to the current location inside the command buffer to append
  92960. +** STATE command at or gcvNULL to query the size of the command.
  92961. +**
  92962. +** gctUINT32 Address
  92963. +** Starting register address of the state buffer.
  92964. +** If 'Logical' is gcvNULL, this argument is ignored.
  92965. +**
  92966. +** gctUINT32 Count
  92967. +** Number of states in state buffer.
  92968. +** If 'Logical' is gcvNULL, this argument is ignored.
  92969. +**
  92970. +** gctSIZE_T * Bytes
  92971. +** Pointer to the number of bytes available for the STATE command.
  92972. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  92973. +**
  92974. +** OUTPUT:
  92975. +**
  92976. +** gctSIZE_T * Bytes
  92977. +** Pointer to a variable that will receive the number of bytes required
  92978. +** for the STATE command. If 'Bytes' is gcvNULL, nothing is returned.
  92979. +*/
  92980. +gceSTATUS
  92981. +gckVGCOMMAND_StateCommand(
  92982. + IN gckVGCOMMAND Command,
  92983. + IN gctUINT32 Pipe,
  92984. + IN gctPOINTER Logical,
  92985. + IN gctUINT32 Address,
  92986. + IN gctSIZE_T Count,
  92987. + IN OUT gctSIZE_T * Bytes
  92988. + )
  92989. +{
  92990. + gcmkHEADER_ARG("Command=0x%x Pipe=0x%x Logical=0x%x Address=0x%x Count=0x%x Bytes = 0x%x",
  92991. + Command, Pipe, Logical, Address, Count, Bytes);
  92992. +
  92993. + /* Verify the arguments. */
  92994. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  92995. +
  92996. + if (Command->fe20)
  92997. + {
  92998. + if (Logical != gcvNULL)
  92999. + {
  93000. + gctUINT32_PTR buffer;
  93001. +
  93002. + /* Cast the buffer pointer. */
  93003. + buffer = (gctUINT32_PTR) Logical;
  93004. +
  93005. + /* Append STATE. */
  93006. + buffer[0]
  93007. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
  93008. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:0) - (0 ? 11:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:0) - (0 ? 11:0) + 1))))))) << (0 ? 11:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ? 11:0) - (0 ? 11:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:0) - (0 ? 11:0) + 1))))))) << (0 ? 11:0)))
  93009. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:16) - (0 ? 27:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:16) - (0 ? 27:16) + 1))))))) << (0 ? 27:16))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ? 27:16) - (0 ? 27:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:16) - (0 ? 27:16) + 1))))))) << (0 ? 27:16)))
  93010. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 13:12) - (0 ? 13:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12))) | (((gctUINT32) ((gctUINT32) (Pipe) & ((gctUINT32) ((((1 ? 13:12) - (0 ? 13:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12)));
  93011. + }
  93012. +
  93013. + if (Bytes != gcvNULL)
  93014. + {
  93015. + /* Return number of bytes required by the STATE command. */
  93016. + *Bytes = 4 * (Count + 1);
  93017. + }
  93018. + }
  93019. + else
  93020. + {
  93021. + if (Logical != gcvNULL)
  93022. + {
  93023. + gctUINT32_PTR buffer;
  93024. +
  93025. + /* Cast the buffer pointer. */
  93026. + buffer = (gctUINT32_PTR) Logical;
  93027. +
  93028. + /* Append LOAD_STATE. */
  93029. + buffer[0]
  93030. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  93031. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  93032. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  93033. + }
  93034. +
  93035. + if (Bytes != gcvNULL)
  93036. + {
  93037. + /* Return number of bytes required by the STATE command. */
  93038. + *Bytes = 4 * (Count + 1);
  93039. + }
  93040. + }
  93041. +
  93042. + gcmkFOOTER_NO();
  93043. + /* Success. */
  93044. + return gcvSTATUS_OK;
  93045. +}
  93046. +
  93047. +/*******************************************************************************
  93048. +**
  93049. +** gckVGCOMMAND_RestartCommand
  93050. +**
  93051. +** Form a RESTART command at the specified location in the command buffer.
  93052. +**
  93053. +** INPUT:
  93054. +**
  93055. +** gckVGCOMMAND Command
  93056. +** Pointer to an gckVGCOMMAND object.
  93057. +**
  93058. +** gctPOINTER Logical
  93059. +** Pointer to the current location inside the command buffer to append
  93060. +** RESTART command at or gcvNULL to query the size of the command.
  93061. +**
  93062. +** gctUINT32 FetchAddress
  93063. +** The address of another command buffer to be executed by this RESTART
  93064. +** command. If 'Logical' is gcvNULL, this argument is ignored.
  93065. +**
  93066. +** gctUINT FetchCount
  93067. +** The number of 64-bit data quantities in another command buffer to
  93068. +** be executed by this RESTART command. If 'Logical' is gcvNULL, this
  93069. +** argument is ignored.
  93070. +**
  93071. +** gctSIZE_T * Bytes
  93072. +** Pointer to the number of bytes available for the RESTART command.
  93073. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93074. +**
  93075. +** OUTPUT:
  93076. +**
  93077. +** gctSIZE_T * Bytes
  93078. +** Pointer to a variable that will receive the number of bytes required
  93079. +** for the RESTART command. If 'Bytes' is gcvNULL, nothing is returned.
  93080. +*/
  93081. +gceSTATUS
  93082. +gckVGCOMMAND_RestartCommand(
  93083. + IN gckVGCOMMAND Command,
  93084. + IN gctPOINTER Logical,
  93085. + IN gctUINT32 FetchAddress,
  93086. + IN gctUINT FetchCount,
  93087. + IN OUT gctSIZE_T * Bytes
  93088. + )
  93089. +{
  93090. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
  93091. + Command, Logical, FetchAddress, FetchCount, Bytes);
  93092. + /* Verify the arguments. */
  93093. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93094. +
  93095. + if (Command->fe20)
  93096. + {
  93097. + if (Logical != gcvNULL)
  93098. + {
  93099. + gctUINT32_PTR buffer;
  93100. + gctUINT32 beginEndMark;
  93101. +
  93102. + /* Cast the buffer pointer. */
  93103. + buffer = (gctUINT32_PTR) Logical;
  93104. +
  93105. + /* Determine Begin/End flag. */
  93106. + beginEndMark = (FetchCount > 0)
  93107. + ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24)))
  93108. + : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24)));
  93109. +
  93110. + /* Append RESTART. */
  93111. + buffer[0]
  93112. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x9 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
  93113. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0)))
  93114. + | beginEndMark;
  93115. +
  93116. + buffer[1]
  93117. + = FetchAddress;
  93118. + }
  93119. +
  93120. + if (Bytes != gcvNULL)
  93121. + {
  93122. + /* Return number of bytes required by the RESTART command. */
  93123. + *Bytes = 8;
  93124. + }
  93125. + }
  93126. + else
  93127. + {
  93128. + gcmkFOOTER_NO();
  93129. + return gcvSTATUS_NOT_SUPPORTED;
  93130. + }
  93131. +
  93132. +
  93133. + gcmkFOOTER_NO();
  93134. + /* Success. */
  93135. + return gcvSTATUS_OK;
  93136. +}
  93137. +
  93138. +/*******************************************************************************
  93139. +**
  93140. +** gckVGCOMMAND_FetchCommand
  93141. +**
  93142. +** Form a FETCH command at the specified location in the command buffer.
  93143. +**
  93144. +** INPUT:
  93145. +**
  93146. +** gckVGCOMMAND Command
  93147. +** Pointer to an gckVGCOMMAND object.
  93148. +**
  93149. +** gctPOINTER Logical
  93150. +** Pointer to the current location inside the command buffer to append
  93151. +** FETCH command at or gcvNULL to query the size of the command.
  93152. +**
  93153. +** gctUINT32 FetchAddress
  93154. +** The address of another command buffer to be executed by this FETCH
  93155. +** command. If 'Logical' is gcvNULL, this argument is ignored.
  93156. +**
  93157. +** gctUINT FetchCount
  93158. +** The number of 64-bit data quantities in another command buffer to
  93159. +** be executed by this FETCH command. If 'Logical' is gcvNULL, this
  93160. +** argument is ignored.
  93161. +**
  93162. +** gctSIZE_T * Bytes
  93163. +** Pointer to the number of bytes available for the FETCH command.
  93164. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93165. +**
  93166. +** OUTPUT:
  93167. +**
  93168. +** gctSIZE_T * Bytes
  93169. +** Pointer to a variable that will receive the number of bytes required
  93170. +** for the FETCH command. If 'Bytes' is gcvNULL, nothing is returned.
  93171. +*/
  93172. +gceSTATUS
  93173. +gckVGCOMMAND_FetchCommand(
  93174. + IN gckVGCOMMAND Command,
  93175. + IN gctPOINTER Logical,
  93176. + IN gctUINT32 FetchAddress,
  93177. + IN gctUINT FetchCount,
  93178. + IN OUT gctSIZE_T * Bytes
  93179. + )
  93180. +{
  93181. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
  93182. + Command, Logical, FetchAddress, FetchCount, Bytes);
  93183. + /* Verify the arguments. */
  93184. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93185. +
  93186. + if (Command->fe20)
  93187. + {
  93188. + if (Logical != gcvNULL)
  93189. + {
  93190. + gctUINT32_PTR buffer;
  93191. +
  93192. + /* Cast the buffer pointer. */
  93193. + buffer = (gctUINT32_PTR) Logical;
  93194. +
  93195. + /* Append FETCH. */
  93196. + buffer[0]
  93197. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x5 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
  93198. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0)));
  93199. +
  93200. + buffer[1]
  93201. + = gcmkFIXADDRESS(FetchAddress);
  93202. + }
  93203. +
  93204. + if (Bytes != gcvNULL)
  93205. + {
  93206. + /* Return number of bytes required by the FETCH command. */
  93207. + *Bytes = 8;
  93208. + }
  93209. + }
  93210. + else
  93211. + {
  93212. + if (Logical != gcvNULL)
  93213. + {
  93214. + gctUINT32_PTR buffer;
  93215. +
  93216. + /* Cast the buffer pointer. */
  93217. + buffer = (gctUINT32_PTR) Logical;
  93218. +
  93219. + /* Append LINK. */
  93220. + buffer[0]
  93221. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  93222. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  93223. +
  93224. + buffer[1]
  93225. + = gcmkFIXADDRESS(FetchAddress);
  93226. + }
  93227. +
  93228. + if (Bytes != gcvNULL)
  93229. + {
  93230. + /* Return number of bytes required by the LINK command. */
  93231. + *Bytes = 8;
  93232. + }
  93233. + }
  93234. +
  93235. + gcmkFOOTER_NO();
  93236. + /* Success. */
  93237. + return gcvSTATUS_OK;
  93238. +}
  93239. +
  93240. +/*******************************************************************************
  93241. +**
  93242. +** gckVGCOMMAND_CallCommand
  93243. +**
  93244. +** Append a CALL command at the specified location in the command buffer.
  93245. +**
  93246. +** INPUT:
  93247. +**
  93248. +** gckVGCOMMAND Command
  93249. +** Pointer to an gckVGCOMMAND object.
  93250. +**
  93251. +** gctPOINTER Logical
  93252. +** Pointer to the current location inside the command buffer to append
  93253. +** CALL command at or gcvNULL to query the size of the command.
  93254. +**
  93255. +** gctUINT32 FetchAddress
  93256. +** The address of another command buffer to be executed by this CALL
  93257. +** command. If 'Logical' is gcvNULL, this argument is ignored.
  93258. +**
  93259. +** gctUINT FetchCount
  93260. +** The number of 64-bit data quantities in another command buffer to
  93261. +** be executed by this CALL command. If 'Logical' is gcvNULL, this
  93262. +** argument is ignored.
  93263. +**
  93264. +** gctSIZE_T * Bytes
  93265. +** Pointer to the number of bytes available for the CALL command.
  93266. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93267. +**
  93268. +** OUTPUT:
  93269. +**
  93270. +** gctSIZE_T * Bytes
  93271. +** Pointer to a variable that will receive the number of bytes required
  93272. +** for the CALL command. If 'Bytes' is gcvNULL, nothing is returned.
  93273. +*/
  93274. +gceSTATUS
  93275. +gckVGCOMMAND_CallCommand(
  93276. + IN gckVGCOMMAND Command,
  93277. + IN gctPOINTER Logical,
  93278. + IN gctUINT32 FetchAddress,
  93279. + IN gctUINT FetchCount,
  93280. + IN OUT gctSIZE_T * Bytes
  93281. + )
  93282. +{
  93283. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
  93284. + Command, Logical, FetchAddress, FetchCount, Bytes);
  93285. + /* Verify the arguments. */
  93286. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93287. +
  93288. + if (Command->fe20)
  93289. + {
  93290. + if (Logical != gcvNULL)
  93291. + {
  93292. + gctUINT32_PTR buffer;
  93293. +
  93294. + /* Cast the buffer pointer. */
  93295. + buffer = (gctUINT32_PTR) Logical;
  93296. +
  93297. + /* Append CALL. */
  93298. + buffer[0]
  93299. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x6 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
  93300. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0))) | (((gctUINT32) ((gctUINT32) (FetchCount) & ((gctUINT32) ((((1 ? 20:0) - (0 ? 20:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0)));
  93301. +
  93302. + buffer[1]
  93303. + = gcmkFIXADDRESS(FetchAddress);
  93304. + }
  93305. +
  93306. + if (Bytes != gcvNULL)
  93307. + {
  93308. + /* Return number of bytes required by the CALL command. */
  93309. + *Bytes = 8;
  93310. + }
  93311. + }
  93312. + else
  93313. + {
  93314. + gcmkFOOTER_NO();
  93315. + return gcvSTATUS_NOT_SUPPORTED;
  93316. + }
  93317. +
  93318. + gcmkFOOTER_NO();
  93319. + /* Success. */
  93320. + return gcvSTATUS_OK;
  93321. +}
  93322. +
  93323. +/*******************************************************************************
  93324. +**
  93325. +** gckVGCOMMAND_ReturnCommand
  93326. +**
  93327. +** Append a RETURN command at the specified location in the command buffer.
  93328. +**
  93329. +** INPUT:
  93330. +**
  93331. +** gckVGCOMMAND Command
  93332. +** Pointer to an gckVGCOMMAND object.
  93333. +**
  93334. +** gctPOINTER Logical
  93335. +** Pointer to the current location inside the command buffer to append
  93336. +** RETURN command at or gcvNULL to query the size of the command.
  93337. +**
  93338. +** gctSIZE_T * Bytes
  93339. +** Pointer to the number of bytes available for the RETURN command.
  93340. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93341. +**
  93342. +** OUTPUT:
  93343. +**
  93344. +** gctSIZE_T * Bytes
  93345. +** Pointer to a variable that will receive the number of bytes required
  93346. +** for the RETURN command. If 'Bytes' is gcvNULL, nothing is returned.
  93347. +*/
  93348. +gceSTATUS
  93349. +gckVGCOMMAND_ReturnCommand(
  93350. + IN gckVGCOMMAND Command,
  93351. + IN gctPOINTER Logical,
  93352. + IN OUT gctSIZE_T * Bytes
  93353. + )
  93354. +{
  93355. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x Bytes = 0x%x",
  93356. + Command, Logical, Bytes);
  93357. + /* Verify the arguments. */
  93358. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93359. +
  93360. + if (Command->fe20)
  93361. + {
  93362. + if (Logical != gcvNULL)
  93363. + {
  93364. + gctUINT32_PTR buffer;
  93365. +
  93366. + /* Cast the buffer pointer. */
  93367. + buffer = (gctUINT32_PTR) Logical;
  93368. +
  93369. + /* Append RETURN. */
  93370. + buffer[0]
  93371. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x7 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)));
  93372. + }
  93373. +
  93374. + if (Bytes != gcvNULL)
  93375. + {
  93376. + /* Return number of bytes required by the RETURN command. */
  93377. + *Bytes = 8;
  93378. + }
  93379. + }
  93380. + else
  93381. + {
  93382. + gcmkFOOTER_NO();
  93383. + return gcvSTATUS_NOT_SUPPORTED;
  93384. + }
  93385. +
  93386. + gcmkFOOTER_NO();
  93387. + /* Success. */
  93388. + return gcvSTATUS_OK;
  93389. +}
  93390. +
  93391. +/*******************************************************************************
  93392. +**
  93393. +** gckVGCOMMAND_EventCommand
  93394. +**
  93395. +** Form an EVENT command at the specified location in the command buffer.
  93396. +**
  93397. +** INPUT:
  93398. +**
  93399. +** gckVGCOMMAND Command
  93400. +** Pointer to the Command object.
  93401. +**
  93402. +** gctPOINTER Logical
  93403. +** Pointer to the current location inside the command buffer to append
  93404. +** EVENT command at or gcvNULL to query the size of the command.
  93405. +**
  93406. +** gctINT32 InterruptId
  93407. +** The ID of the interrupt to generate.
  93408. +** If 'Logical' is gcvNULL, this argument is ignored.
  93409. +**
  93410. +** gceBLOCK Block
  93411. +** Block that will generate the interrupt.
  93412. +**
  93413. +** gctSIZE_T * Bytes
  93414. +** Pointer to the number of bytes available for the EVENT command.
  93415. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93416. +**
  93417. +** OUTPUT:
  93418. +**
  93419. +** gctSIZE_T * Bytes
  93420. +** Pointer to a variable that will receive the number of bytes required
  93421. +** for the END command. If 'Bytes' is gcvNULL, nothing is returned.
  93422. +*/
  93423. +gceSTATUS
  93424. +gckVGCOMMAND_EventCommand(
  93425. + IN gckVGCOMMAND Command,
  93426. + IN gctPOINTER Logical,
  93427. + IN gceBLOCK Block,
  93428. + IN gctINT32 InterruptId,
  93429. + IN OUT gctSIZE_T * Bytes
  93430. + )
  93431. +{
  93432. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x Block=0x%x InterruptId=0x%x Bytes = 0x%x",
  93433. + Command, Logical, Block, InterruptId, Bytes);
  93434. + /* Verify the arguments. */
  93435. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93436. +
  93437. + if (Command->fe20)
  93438. + {
  93439. + typedef struct _gcsEVENTSTATES
  93440. + {
  93441. + /* Chips before VG21 use these values. */
  93442. + gctUINT eventFromFE;
  93443. + gctUINT eventFromPE;
  93444. +
  93445. + /* VG21 chips and later use SOURCE field. */
  93446. + gctUINT eventSource;
  93447. + }
  93448. + gcsEVENTSTATES;
  93449. +
  93450. + static gcsEVENTSTATES states[] =
  93451. + {
  93452. + /* gcvBLOCK_COMMAND */
  93453. + {
  93454. + (gctUINT)~0,
  93455. + (gctUINT)~0,
  93456. + (gctUINT)~0
  93457. + },
  93458. +
  93459. + /* gcvBLOCK_TESSELLATOR */
  93460. + {
  93461. + 0x0,
  93462. + 0x1,
  93463. + 0x10
  93464. + },
  93465. +
  93466. + /* gcvBLOCK_TESSELLATOR2 */
  93467. + {
  93468. + 0x0,
  93469. + 0x1,
  93470. + 0x12
  93471. + },
  93472. +
  93473. + /* gcvBLOCK_TESSELLATOR3 */
  93474. + {
  93475. + 0x0,
  93476. + 0x1,
  93477. + 0x14
  93478. + },
  93479. +
  93480. + /* gcvBLOCK_RASTER */
  93481. + {
  93482. + 0x0,
  93483. + 0x1,
  93484. + 0x07,
  93485. + },
  93486. +
  93487. + /* gcvBLOCK_VG */
  93488. + {
  93489. + 0x0,
  93490. + 0x1,
  93491. + 0x0F
  93492. + },
  93493. +
  93494. + /* gcvBLOCK_VG2 */
  93495. + {
  93496. + 0x0,
  93497. + 0x1,
  93498. + 0x11
  93499. + },
  93500. +
  93501. + /* gcvBLOCK_VG3 */
  93502. + {
  93503. + 0x0,
  93504. + 0x1,
  93505. + 0x13
  93506. + },
  93507. +
  93508. + /* gcvBLOCK_PIXEL */
  93509. + {
  93510. + 0x0,
  93511. + 0x1,
  93512. + 0x07
  93513. + },
  93514. + };
  93515. +
  93516. + /* Verify block ID. */
  93517. + gcmkVERIFY_ARGUMENT(gcmIS_VALID_INDEX(Block, states));
  93518. +
  93519. + if (Logical != gcvNULL)
  93520. + {
  93521. + gctUINT32_PTR buffer;
  93522. +
  93523. + /* Verify the event ID. */
  93524. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  93525. + gcmkVERIFY_ARGUMENT(InterruptId <= ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))));
  93526. +
  93527. + /* Cast the buffer pointer. */
  93528. + buffer = (gctUINT32_PTR) Logical;
  93529. +
  93530. + /* Append EVENT. */
  93531. + buffer[0]
  93532. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
  93533. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:0) - (0 ? 11:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:0) - (0 ? 11:0) + 1))))))) << (0 ? 11:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ? 11:0) - (0 ? 11:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:0) - (0 ? 11:0) + 1))))))) << (0 ? 11:0)))
  93534. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:16) - (0 ? 27:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:16) - (0 ? 27:16) + 1))))))) << (0 ? 27:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:16) - (0 ? 27:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:16) - (0 ? 27:16) + 1))))))) << (0 ? 27:16)))
  93535. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 13:12) - (0 ? 13:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 13:12) - (0 ? 13:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:12) - (0 ? 13:12) + 1))))))) << (0 ? 13:12)));
  93536. +
  93537. + /* Determine chip version. */
  93538. + if (Command->vg21)
  93539. + {
  93540. + /* Get the event source for the block. */
  93541. + gctUINT eventSource = states[Block].eventSource;
  93542. +
  93543. + /* Supported? */
  93544. + if (eventSource == ~0)
  93545. + {
  93546. + gcmkFOOTER_NO();
  93547. + return gcvSTATUS_NOT_SUPPORTED;
  93548. + }
  93549. +
  93550. + buffer[1]
  93551. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  93552. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) ((gctUINT32) (eventSource) & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  93553. + }
  93554. + else
  93555. + {
  93556. + /* Get the event source for the block. */
  93557. + gctUINT eventFromFE = states[Block].eventFromFE;
  93558. + gctUINT eventFromPE = states[Block].eventFromPE;
  93559. +
  93560. + /* Supported? */
  93561. + if (eventFromFE == ~0)
  93562. + {
  93563. + gcmkFOOTER_NO();
  93564. + return gcvSTATUS_NOT_SUPPORTED;
  93565. + }
  93566. +
  93567. + buffer[1]
  93568. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  93569. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) ((gctUINT32) (eventFromFE) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
  93570. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) ((gctUINT32) (eventFromPE) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
  93571. + }
  93572. + }
  93573. +
  93574. + if (Bytes != gcvNULL)
  93575. + {
  93576. + /* Make sure the events are directly supported for the block. */
  93577. + if (states[Block].eventSource == ~0)
  93578. + {
  93579. + gcmkFOOTER_NO();
  93580. + return gcvSTATUS_NOT_SUPPORTED;
  93581. + }
  93582. +
  93583. + /* Return number of bytes required by the END command. */
  93584. + *Bytes = 8;
  93585. + }
  93586. + }
  93587. + else
  93588. + {
  93589. + if (Logical != gcvNULL)
  93590. + {
  93591. + gctUINT32_PTR buffer;
  93592. +
  93593. + /* Verify the event ID. */
  93594. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  93595. + gcmkVERIFY_ARGUMENT(InterruptId <= ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))));
  93596. +
  93597. + /* Cast the buffer pointer. */
  93598. + buffer = (gctUINT32_PTR) Logical;
  93599. +
  93600. + /* Append EVENT. */
  93601. + buffer[0]
  93602. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  93603. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  93604. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  93605. +
  93606. + /* Determine event source. */
  93607. + if (Block == gcvBLOCK_COMMAND)
  93608. + {
  93609. + buffer[1]
  93610. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  93611. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
  93612. + }
  93613. + else
  93614. + {
  93615. + buffer[1]
  93616. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  93617. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
  93618. + }
  93619. + }
  93620. +
  93621. + if (Bytes != gcvNULL)
  93622. + {
  93623. + /* Return number of bytes required by the EVENT and END commands. */
  93624. + *Bytes = 8;
  93625. + }
  93626. + }
  93627. +
  93628. + gcmkFOOTER_NO();
  93629. + /* Success. */
  93630. + return gcvSTATUS_OK;
  93631. +}
  93632. +
  93633. +/*******************************************************************************
  93634. +**
  93635. +** gckVGCOMMAND_EndCommand
  93636. +**
  93637. +** Form an END command at the specified location in the command buffer.
  93638. +**
  93639. +** INPUT:
  93640. +**
  93641. +** gckVGCOMMAND Command
  93642. +** Pointer to the Command object.
  93643. +**
  93644. +** gctPOINTER Logical
  93645. +** Pointer to the current location inside the command buffer to append
  93646. +** END command at or gcvNULL to query the size of the command.
  93647. +**
  93648. +** gctINT32 InterruptId
  93649. +** The ID of the interrupt to generate.
  93650. +** If 'Logical' is gcvNULL, this argument will be ignored.
  93651. +**
  93652. +** gctSIZE_T * Bytes
  93653. +** Pointer to the number of bytes available for the END command.
  93654. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93655. +**
  93656. +** OUTPUT:
  93657. +**
  93658. +** gctSIZE_T * Bytes
  93659. +** Pointer to a variable that will receive the number of bytes required
  93660. +** for the END command. If 'Bytes' is gcvNULL, nothing is returned.
  93661. +*/
  93662. +gceSTATUS
  93663. +gckVGCOMMAND_EndCommand(
  93664. + IN gckVGCOMMAND Command,
  93665. + IN gctPOINTER Logical,
  93666. + IN gctINT32 InterruptId,
  93667. + IN OUT gctSIZE_T * Bytes
  93668. + )
  93669. +{
  93670. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x InterruptId=0x%x Bytes = 0x%x",
  93671. + Command, Logical, InterruptId, Bytes);
  93672. + /* Verify the arguments. */
  93673. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93674. +
  93675. + if (Command->fe20)
  93676. + {
  93677. + if (Logical != gcvNULL)
  93678. + {
  93679. + gctUINT32_PTR buffer;
  93680. +
  93681. + /* Verify the event ID. */
  93682. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  93683. +
  93684. + /* Cast the buffer pointer. */
  93685. + buffer = (gctUINT32_PTR) Logical;
  93686. +
  93687. + /* Append END. */
  93688. + buffer[0]
  93689. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1))))))) << (0 ? 31:28)))
  93690. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
  93691. + }
  93692. +
  93693. + if (Bytes != gcvNULL)
  93694. + {
  93695. + /* Return number of bytes required by the END command. */
  93696. + *Bytes = 8;
  93697. + }
  93698. + }
  93699. + else
  93700. + {
  93701. + if (Logical != gcvNULL)
  93702. + {
  93703. + gctUINT32_PTR memory;
  93704. +
  93705. + /* Verify the event ID. */
  93706. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  93707. +
  93708. + /* Cast the buffer pointer. */
  93709. + memory = (gctUINT32_PTR) Logical;
  93710. +
  93711. + /* Append EVENT. */
  93712. + memory[0]
  93713. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  93714. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  93715. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  93716. +
  93717. + memory[1]
  93718. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (InterruptId) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  93719. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
  93720. +
  93721. + /* Append END. */
  93722. + memory[2]
  93723. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  93724. + }
  93725. +
  93726. + if (Bytes != gcvNULL)
  93727. + {
  93728. + /* Return number of bytes required by the EVENT and END commands. */
  93729. + *Bytes = 16;
  93730. + }
  93731. + }
  93732. +
  93733. + gcmkFOOTER_NO();
  93734. + /* Success. */
  93735. + return gcvSTATUS_OK;
  93736. +}
  93737. +
  93738. +#endif /* gcdENABLE_VG */
  93739. +
  93740. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h
  93741. --- linux-3.14.15/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h 1970-01-01 01:00:00.000000000 +0100
  93742. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h 2014-08-20 19:23:53.558845839 +0200
  93743. @@ -0,0 +1,319 @@
  93744. +/****************************************************************************
  93745. +*
  93746. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  93747. +*
  93748. +* This program is free software; you can redistribute it and/or modify
  93749. +* it under the terms of the GNU General Public License as published by
  93750. +* the Free Software Foundation; either version 2 of the license, or
  93751. +* (at your option) any later version.
  93752. +*
  93753. +* This program is distributed in the hope that it will be useful,
  93754. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  93755. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  93756. +* GNU General Public License for more details.
  93757. +*
  93758. +* You should have received a copy of the GNU General Public License
  93759. +* along with this program; if not write to the Free Software
  93760. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  93761. +*
  93762. +*****************************************************************************/
  93763. +
  93764. +
  93765. +#ifndef __gc_hal_kernel_hardware_command_vg_h_
  93766. +#define __gc_hal_kernel_hardware_command_vg_h_
  93767. +
  93768. +/******************************************************************************\
  93769. +******************* Task and Interrupt Management Structures. ******************
  93770. +\******************************************************************************/
  93771. +
  93772. +/* Task storage header. */
  93773. +typedef struct _gcsTASK_STORAGE * gcsTASK_STORAGE_PTR;
  93774. +typedef struct _gcsTASK_STORAGE
  93775. +{
  93776. + /* Next allocated storage buffer. */
  93777. + gcsTASK_STORAGE_PTR next;
  93778. +}
  93779. +gcsTASK_STORAGE;
  93780. +
  93781. +/* Task container header. */
  93782. +typedef struct _gcsTASK_CONTAINER * gcsTASK_CONTAINER_PTR;
  93783. +typedef struct _gcsTASK_CONTAINER
  93784. +{
  93785. + /* The number of tasks left to be processed in the container. */
  93786. + gctINT referenceCount;
  93787. +
  93788. + /* Size of the buffer. */
  93789. + gctUINT size;
  93790. +
  93791. + /* Link to the previous and the next allocated containers. */
  93792. + gcsTASK_CONTAINER_PTR allocPrev;
  93793. + gcsTASK_CONTAINER_PTR allocNext;
  93794. +
  93795. + /* Link to the previous and the next containers in the free list. */
  93796. + gcsTASK_CONTAINER_PTR freePrev;
  93797. + gcsTASK_CONTAINER_PTR freeNext;
  93798. +}
  93799. +gcsTASK_CONTAINER;
  93800. +
  93801. +/* Kernel space task master table entry. */
  93802. +typedef struct _gcsBLOCK_TASK_ENTRY * gcsBLOCK_TASK_ENTRY_PTR;
  93803. +typedef struct _gcsBLOCK_TASK_ENTRY
  93804. +{
  93805. + /* Pointer to the current task container for the block. */
  93806. + gcsTASK_CONTAINER_PTR container;
  93807. +
  93808. + /* Pointer to the current task data within the container. */
  93809. + gcsTASK_HEADER_PTR task;
  93810. +
  93811. + /* Pointer to the last link task within the container. */
  93812. + gcsTASK_LINK_PTR link;
  93813. +
  93814. + /* Number of interrupts allocated for this block. */
  93815. + gctUINT interruptCount;
  93816. +
  93817. + /* The index of the current interrupt. */
  93818. + gctUINT interruptIndex;
  93819. +
  93820. + /* Interrupt semaphore. */
  93821. + gctSEMAPHORE interruptSemaphore;
  93822. +
  93823. + /* Interrupt value array. */
  93824. + gctINT32 interruptArray[32];
  93825. +}
  93826. +gcsBLOCK_TASK_ENTRY;
  93827. +
  93828. +
  93829. +/******************************************************************************\
  93830. +********************* Command Queue Management Structures. *********************
  93831. +\******************************************************************************/
  93832. +
  93833. +/* Command queue kernel element pointer. */
  93834. +typedef struct _gcsKERNEL_CMDQUEUE * gcsKERNEL_CMDQUEUE_PTR;
  93835. +
  93836. +/* Command queue object handler function type. */
  93837. +typedef gceSTATUS (* gctOBJECT_HANDLER) (
  93838. + gckVGKERNEL Kernel,
  93839. + gcsKERNEL_CMDQUEUE_PTR Entry
  93840. + );
  93841. +
  93842. +/* Command queue kernel element. */
  93843. +typedef struct _gcsKERNEL_CMDQUEUE
  93844. +{
  93845. + /* The number of buffers in the queue. */
  93846. + gcsCMDBUFFER_PTR commandBuffer;
  93847. +
  93848. + /* Pointer to the object handler function. */
  93849. + gctOBJECT_HANDLER handler;
  93850. +}
  93851. +gcsKERNEL_CMDQUEUE;
  93852. +
  93853. +/* Command queue header. */
  93854. +typedef struct _gcsKERNEL_QUEUE_HEADER * gcsKERNEL_QUEUE_HEADER_PTR;
  93855. +typedef struct _gcsKERNEL_QUEUE_HEADER
  93856. +{
  93857. + /* The size of the buffer in bytes. */
  93858. + gctUINT size;
  93859. +
  93860. + /* The number of pending entries to be processed. */
  93861. + volatile gctUINT pending;
  93862. +
  93863. + /* The current command queue entry. */
  93864. + gcsKERNEL_CMDQUEUE_PTR currentEntry;
  93865. +
  93866. + /* Next buffer. */
  93867. + gcsKERNEL_QUEUE_HEADER_PTR next;
  93868. +}
  93869. +gcsKERNEL_QUEUE_HEADER;
  93870. +
  93871. +
  93872. +/******************************************************************************\
  93873. +******************************* gckVGCOMMAND Object *******************************
  93874. +\******************************************************************************/
  93875. +
  93876. +/* gckVGCOMMAND object. */
  93877. +struct _gckVGCOMMAND
  93878. +{
  93879. + /***************************************************************************
  93880. + ** Object data and pointers.
  93881. + */
  93882. +
  93883. + gcsOBJECT object;
  93884. + gckVGKERNEL kernel;
  93885. + gckOS os;
  93886. + gckVGHARDWARE hardware;
  93887. +
  93888. + /* Features. */
  93889. + gctBOOL fe20;
  93890. + gctBOOL vg20;
  93891. + gctBOOL vg21;
  93892. +
  93893. +
  93894. + /***************************************************************************
  93895. + ** Enable command queue dumping.
  93896. + */
  93897. +
  93898. + gctBOOL enableDumping;
  93899. +
  93900. +
  93901. + /***************************************************************************
  93902. + ** Bus Error interrupt.
  93903. + */
  93904. +
  93905. + gctINT32 busErrorInt;
  93906. +
  93907. +
  93908. + /***************************************************************************
  93909. + ** Command buffer information.
  93910. + */
  93911. +
  93912. + gcsCOMMAND_BUFFER_INFO info;
  93913. +
  93914. +
  93915. + /***************************************************************************
  93916. + ** Synchronization objects.
  93917. + */
  93918. +
  93919. + gctPOINTER queueMutex;
  93920. + gctPOINTER taskMutex;
  93921. + gctPOINTER commitMutex;
  93922. +
  93923. +
  93924. + /***************************************************************************
  93925. + ** Task management.
  93926. + */
  93927. +
  93928. + /* The head of the storage buffer linked list. */
  93929. + gcsTASK_STORAGE_PTR taskStorage;
  93930. +
  93931. + /* Allocation size. */
  93932. + gctUINT taskStorageGranularity;
  93933. + gctUINT taskStorageUsable;
  93934. +
  93935. + /* The free container list. */
  93936. + gcsTASK_CONTAINER_PTR taskFreeHead;
  93937. + gcsTASK_CONTAINER_PTR taskFreeTail;
  93938. +
  93939. + /* Task table */
  93940. + gcsBLOCK_TASK_ENTRY taskTable[gcvBLOCK_COUNT];
  93941. +
  93942. +
  93943. + /***************************************************************************
  93944. + ** Command queue.
  93945. + */
  93946. +
  93947. + /* Pointer to the allocated queue memory. */
  93948. + gcsKERNEL_QUEUE_HEADER_PTR queue;
  93949. +
  93950. + /* Pointer to the current available queue from which new queue entries
  93951. + will be allocated. */
  93952. + gcsKERNEL_QUEUE_HEADER_PTR queueHead;
  93953. +
  93954. + /* If different from queueHead, points to the command queue which is
  93955. + currently being executed by the hardware. */
  93956. + gcsKERNEL_QUEUE_HEADER_PTR queueTail;
  93957. +
  93958. + /* Points to the queue to merge the tail with when the tail is processed. */
  93959. + gcsKERNEL_QUEUE_HEADER_PTR mergeQueue;
  93960. +
  93961. + /* Queue overflow counter. */
  93962. + gctUINT queueOverflow;
  93963. +
  93964. +
  93965. + /***************************************************************************
  93966. + ** Context.
  93967. + */
  93968. +
  93969. + /* Context counter used for unique ID. */
  93970. + gctUINT64 contextCounter;
  93971. +
  93972. + /* Current context ID. */
  93973. + gctUINT64 currentContext;
  93974. +
  93975. + /* Command queue power semaphore. */
  93976. + gctPOINTER powerSemaphore;
  93977. + gctINT32 powerStallInt;
  93978. + gcsCMDBUFFER_PTR powerStallBuffer;
  93979. + gctSIGNAL powerStallSignal;
  93980. +
  93981. +};
  93982. +
  93983. +/******************************************************************************\
  93984. +************************ gckVGCOMMAND Object Internal API. ***********************
  93985. +\******************************************************************************/
  93986. +
  93987. +/* Initialize architecture dependent command buffer information. */
  93988. +gceSTATUS
  93989. +gckVGCOMMAND_InitializeInfo(
  93990. + IN gckVGCOMMAND Command
  93991. + );
  93992. +
  93993. +/* Form a STATE command at the specified location in the command buffer. */
  93994. +gceSTATUS
  93995. +gckVGCOMMAND_StateCommand(
  93996. + IN gckVGCOMMAND Command,
  93997. + IN gctUINT32 Pipe,
  93998. + IN gctPOINTER Logical,
  93999. + IN gctUINT32 Address,
  94000. + IN gctSIZE_T Count,
  94001. + IN OUT gctSIZE_T * Bytes
  94002. + );
  94003. +
  94004. +/* Form a RESTART command at the specified location in the command buffer. */
  94005. +gceSTATUS
  94006. +gckVGCOMMAND_RestartCommand(
  94007. + IN gckVGCOMMAND Command,
  94008. + IN gctPOINTER Logical,
  94009. + IN gctUINT32 FetchAddress,
  94010. + IN gctUINT FetchCount,
  94011. + IN OUT gctSIZE_T * Bytes
  94012. + );
  94013. +
  94014. +/* Form a FETCH command at the specified location in the command buffer. */
  94015. +gceSTATUS
  94016. +gckVGCOMMAND_FetchCommand(
  94017. + IN gckVGCOMMAND Command,
  94018. + IN gctPOINTER Logical,
  94019. + IN gctUINT32 FetchAddress,
  94020. + IN gctUINT FetchCount,
  94021. + IN OUT gctSIZE_T * Bytes
  94022. + );
  94023. +
  94024. +/* Form a CALL command at the specified location in the command buffer. */
  94025. +gceSTATUS
  94026. +gckVGCOMMAND_CallCommand(
  94027. + IN gckVGCOMMAND Command,
  94028. + IN gctPOINTER Logical,
  94029. + IN gctUINT32 FetchAddress,
  94030. + IN gctUINT FetchCount,
  94031. + IN OUT gctSIZE_T * Bytes
  94032. + );
  94033. +
  94034. +/* Form a RETURN command at the specified location in the command buffer. */
  94035. +gceSTATUS
  94036. +gckVGCOMMAND_ReturnCommand(
  94037. + IN gckVGCOMMAND Command,
  94038. + IN gctPOINTER Logical,
  94039. + IN OUT gctSIZE_T * Bytes
  94040. + );
  94041. +
  94042. +/* Form an EVENT command at the specified location in the command buffer. */
  94043. +gceSTATUS
  94044. +gckVGCOMMAND_EventCommand(
  94045. + IN gckVGCOMMAND Command,
  94046. + IN gctPOINTER Logical,
  94047. + IN gceBLOCK Block,
  94048. + IN gctINT32 InterruptId,
  94049. + IN OUT gctSIZE_T * Bytes
  94050. + );
  94051. +
  94052. +/* Form an END command at the specified location in the command buffer. */
  94053. +gceSTATUS
  94054. +gckVGCOMMAND_EndCommand(
  94055. + IN gckVGCOMMAND Command,
  94056. + IN gctPOINTER Logical,
  94057. + IN gctINT32 InterruptId,
  94058. + IN OUT gctSIZE_T * Bytes
  94059. + );
  94060. +
  94061. +#endif /* __gc_hal_kernel_hardware_command_h_ */
  94062. +
  94063. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
  94064. --- linux-3.14.15/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c 1970-01-01 01:00:00.000000000 +0100
  94065. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c 2014-08-20 19:31:46.124868988 +0200
  94066. @@ -0,0 +1,2114 @@
  94067. +/****************************************************************************
  94068. +*
  94069. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  94070. +*
  94071. +* This program is free software; you can redistribute it and/or modify
  94072. +* it under the terms of the GNU General Public License as published by
  94073. +* the Free Software Foundation; either version 2 of the license, or
  94074. +* (at your option) any later version.
  94075. +*
  94076. +* This program is distributed in the hope that it will be useful,
  94077. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  94078. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  94079. +* GNU General Public License for more details.
  94080. +*
  94081. +* You should have received a copy of the GNU General Public License
  94082. +* along with this program; if not write to the Free Software
  94083. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  94084. +*
  94085. +*****************************************************************************/
  94086. +
  94087. +
  94088. +#include "gc_hal.h"
  94089. +#include "gc_hal_kernel.h"
  94090. +#include "gc_hal_kernel_hardware_command_vg.h"
  94091. +
  94092. +#if gcdENABLE_VG
  94093. +
  94094. +#define _GC_OBJ_ZONE gcvZONE_HARDWARE
  94095. +
  94096. +typedef enum
  94097. +{
  94098. + gcvPOWER_FLAG_INITIALIZE = 1 << 0,
  94099. + gcvPOWER_FLAG_STALL = 1 << 1,
  94100. + gcvPOWER_FLAG_STOP = 1 << 2,
  94101. + gcvPOWER_FLAG_START = 1 << 3,
  94102. + gcvPOWER_FLAG_RELEASE = 1 << 4,
  94103. + gcvPOWER_FLAG_DELAY = 1 << 5,
  94104. + gcvPOWER_FLAG_SAVE = 1 << 6,
  94105. + gcvPOWER_FLAG_ACQUIRE = 1 << 7,
  94106. + gcvPOWER_FLAG_POWER_OFF = 1 << 8,
  94107. + gcvPOWER_FLAG_CLOCK_OFF = 1 << 9,
  94108. + gcvPOWER_FLAG_CLOCK_ON = 1 << 10,
  94109. + gcvPOWER_FLAG_NOP = 1 << 11,
  94110. +}
  94111. +gcePOWER_FLAGS;
  94112. +
  94113. +/******************************************************************************\
  94114. +********************************* Support Code *********************************
  94115. +\******************************************************************************/
  94116. +static gceSTATUS
  94117. +_ResetGPU(
  94118. + IN gckOS Os
  94119. + )
  94120. +{
  94121. + gctUINT32 control, idle;
  94122. + gceSTATUS status;
  94123. +
  94124. + /* Read register. */
  94125. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  94126. + gcvCORE_VG,
  94127. + 0x00000,
  94128. + &control));
  94129. +
  94130. + for (;;)
  94131. + {
  94132. + /* Disable clock gating. */
  94133. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  94134. + gcvCORE_VG,
  94135. + 0x00104,
  94136. + 0x00000000));
  94137. +
  94138. + /* Wait for clock being stable. */
  94139. + gcmkONERROR(gckOS_Delay(Os, 1));
  94140. +
  94141. + /* Isolate the GPU. */
  94142. + control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
  94143. +
  94144. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  94145. + gcvCORE_VG,
  94146. + 0x00000,
  94147. + control));
  94148. +
  94149. + /* Set soft reset. */
  94150. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  94151. + gcvCORE_VG,
  94152. + 0x00000,
  94153. + ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))));
  94154. +
  94155. + /* Wait for reset. */
  94156. + gcmkONERROR(gckOS_Delay(Os, 1));
  94157. +
  94158. + /* Reset soft reset bit. */
  94159. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  94160. + gcvCORE_VG,
  94161. + 0x00000,
  94162. + ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))));
  94163. +
  94164. + /* Reset GPU isolation. */
  94165. + control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
  94166. +
  94167. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  94168. + gcvCORE_VG,
  94169. + 0x00000,
  94170. + control));
  94171. +
  94172. + /* Read idle register. */
  94173. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  94174. + gcvCORE_VG,
  94175. + 0x00004,
  94176. + &idle));
  94177. +
  94178. + if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) == 0)
  94179. + {
  94180. + continue;
  94181. + }
  94182. +
  94183. + /* Read reset register. */
  94184. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  94185. + gcvCORE_VG,
  94186. + 0x00000,
  94187. + &control));
  94188. +
  94189. + if (((((((gctUINT32) (control)) >> (0 ? 16:16)) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) ) == 0)
  94190. + || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
  94191. + )
  94192. + {
  94193. + continue;
  94194. + }
  94195. +
  94196. + /* GPU is idle. */
  94197. + break;
  94198. + }
  94199. +
  94200. + /* Success. */
  94201. + return gcvSTATUS_OK;
  94202. +
  94203. +OnError:
  94204. +
  94205. + /* Return the error. */
  94206. + return status;
  94207. +}
  94208. +
  94209. +
  94210. +static gceSTATUS
  94211. +_IdentifyHardware(
  94212. + IN gckOS Os,
  94213. + OUT gceCHIPMODEL * ChipModel,
  94214. + OUT gctUINT32 * ChipRevision,
  94215. + OUT gctUINT32 * ChipFeatures,
  94216. + OUT gctUINT32 * ChipMinorFeatures,
  94217. + OUT gctUINT32 * ChipMinorFeatures2
  94218. + )
  94219. +{
  94220. + gceSTATUS status;
  94221. + gctUINT32 chipIdentity;
  94222. +
  94223. + do
  94224. + {
  94225. + /* Read chip identity register. */
  94226. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG, 0x00018, &chipIdentity));
  94227. +
  94228. + /* Special case for older graphic cores. */
  94229. + if (((((gctUINT32) (chipIdentity)) >> (0 ? 31:24) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))))
  94230. + {
  94231. + *ChipModel = gcv500;
  94232. + *ChipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) );
  94233. + }
  94234. +
  94235. + else
  94236. + {
  94237. + /* Read chip identity register. */
  94238. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG,
  94239. + 0x00020,
  94240. + (gctUINT32 *) ChipModel));
  94241. +
  94242. + /* Read CHIP_REV register. */
  94243. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG,
  94244. + 0x00024,
  94245. + ChipRevision));
  94246. + }
  94247. +
  94248. + /* Read chip feature register. */
  94249. + gcmkERR_BREAK(gckOS_ReadRegisterEx(
  94250. + Os, gcvCORE_VG, 0x0001C, ChipFeatures
  94251. + ));
  94252. +
  94253. + /* Read chip minor feature register. */
  94254. + gcmkERR_BREAK(gckOS_ReadRegisterEx(
  94255. + Os, gcvCORE_VG, 0x00034, ChipMinorFeatures
  94256. + ));
  94257. +
  94258. + /* Read chip minor feature register #2. */
  94259. + gcmkERR_BREAK(gckOS_ReadRegisterEx(
  94260. + Os, gcvCORE_VG, 0x00074, ChipMinorFeatures2
  94261. + ));
  94262. +
  94263. + gcmkTRACE(
  94264. + gcvLEVEL_VERBOSE,
  94265. + "ChipModel=0x%08X\n"
  94266. + "ChipRevision=0x%08X\n"
  94267. + "ChipFeatures=0x%08X\n"
  94268. + "ChipMinorFeatures=0x%08X\n"
  94269. + "ChipMinorFeatures2=0x%08X\n",
  94270. + *ChipModel,
  94271. + *ChipRevision,
  94272. + *ChipFeatures,
  94273. + *ChipMinorFeatures,
  94274. + *ChipMinorFeatures2
  94275. + );
  94276. +
  94277. + /* Success. */
  94278. + return gcvSTATUS_OK;
  94279. + }
  94280. + while (gcvFALSE);
  94281. +
  94282. + /* Return the status. */
  94283. + return status;
  94284. +}
  94285. +
  94286. +#if gcdPOWEROFF_TIMEOUT
  94287. +void
  94288. +_VGPowerTimerFunction(
  94289. + gctPOINTER Data
  94290. + )
  94291. +{
  94292. + gckVGHARDWARE hardware = (gckVGHARDWARE)Data;
  94293. + gcmkVERIFY_OK(
  94294. + gckVGHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
  94295. +}
  94296. +#endif
  94297. +
  94298. +/******************************************************************************\
  94299. +****************************** gckVGHARDWARE API code *****************************
  94300. +\******************************************************************************/
  94301. +
  94302. +/*******************************************************************************
  94303. +**
  94304. +** gckVGHARDWARE_Construct
  94305. +**
  94306. +** Construct a new gckVGHARDWARE object.
  94307. +**
  94308. +** INPUT:
  94309. +**
  94310. +** gckOS Os
  94311. +** Pointer to an initialized gckOS object.
  94312. +**
  94313. +** OUTPUT:
  94314. +**
  94315. +** gckVGHARDWARE * Hardware
  94316. +** Pointer to a variable that will hold the pointer to the gckVGHARDWARE
  94317. +** object.
  94318. +*/
  94319. +gceSTATUS
  94320. +gckVGHARDWARE_Construct(
  94321. + IN gckOS Os,
  94322. + OUT gckVGHARDWARE * Hardware
  94323. + )
  94324. +{
  94325. + gckVGHARDWARE hardware = gcvNULL;
  94326. + gceSTATUS status;
  94327. + gceCHIPMODEL chipModel;
  94328. + gctUINT32 chipRevision;
  94329. + gctUINT32 chipFeatures;
  94330. + gctUINT32 chipMinorFeatures;
  94331. + gctUINT32 chipMinorFeatures2;
  94332. +
  94333. + gcmkHEADER_ARG("Os=0x%x Hardware=0x%x ", Os, Hardware);
  94334. +
  94335. + /* Verify the arguments. */
  94336. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  94337. + gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
  94338. +
  94339. + do
  94340. + {
  94341. + gcmkERR_BREAK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvTRUE, gcvTRUE));
  94342. +
  94343. + status = _ResetGPU(Os);
  94344. +
  94345. + if (status != gcvSTATUS_OK)
  94346. + {
  94347. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  94348. + "_ResetGPU failed: status=%d\n", status);
  94349. + }
  94350. +
  94351. + /* Identify the hardware. */
  94352. + gcmkERR_BREAK(_IdentifyHardware(Os,
  94353. + &chipModel, &chipRevision,
  94354. + &chipFeatures, &chipMinorFeatures, &chipMinorFeatures2
  94355. + ));
  94356. +
  94357. + /* Allocate the gckVGHARDWARE object. */
  94358. + gcmkERR_BREAK(gckOS_Allocate(Os,
  94359. + gcmSIZEOF(struct _gckVGHARDWARE), (gctPOINTER *) &hardware
  94360. + ));
  94361. +
  94362. + /* Initialize the gckVGHARDWARE object. */
  94363. + hardware->object.type = gcvOBJ_HARDWARE;
  94364. + hardware->os = Os;
  94365. +
  94366. + /* Set chip identity. */
  94367. + hardware->chipModel = chipModel;
  94368. + hardware->chipRevision = chipRevision;
  94369. + hardware->chipFeatures = chipFeatures;
  94370. + hardware->chipMinorFeatures = chipMinorFeatures;
  94371. + hardware->chipMinorFeatures2 = chipMinorFeatures2;
  94372. +
  94373. + hardware->powerMutex = gcvNULL;
  94374. + hardware->chipPowerState = gcvPOWER_ON;
  94375. + hardware->chipPowerStateGlobal = gcvPOWER_ON;
  94376. + hardware->clockState = gcvTRUE;
  94377. + hardware->powerState = gcvTRUE;
  94378. +
  94379. +#if gcdPOWEROFF_TIMEOUT
  94380. + hardware->powerOffTime = 0;
  94381. + hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
  94382. +
  94383. + gcmkVERIFY_OK(gckOS_CreateTimer(Os,
  94384. + _VGPowerTimerFunction,
  94385. + (gctPOINTER)hardware,
  94386. + &hardware->powerOffTimer));
  94387. +#endif
  94388. +
  94389. + /* Determine whether FE 2.0 is present. */
  94390. + hardware->fe20 = ((((gctUINT32) (hardware->chipFeatures)) >> (0 ? 28:28) & ((gctUINT32) ((((1 ? 28:28) - (0 ? 28:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 28:28) - (0 ? 28:28) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 28:28) - (0 ? 28:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 28:28) - (0 ? 28:28) + 1)))))));
  94391. +
  94392. + /* Determine whether VG 2.0 is present. */
  94393. + hardware->vg20 = ((((gctUINT32) (hardware->chipMinorFeatures)) >> (0 ? 13:13) & ((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1)))))));
  94394. +
  94395. + /* Determine whether VG 2.1 is present. */
  94396. + hardware->vg21 = ((((gctUINT32) (hardware->chipMinorFeatures)) >> (0 ? 18:18) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1)))))));
  94397. +
  94398. + /* Set default event mask. */
  94399. + hardware->eventMask = 0xFFFFFFFF;
  94400. +
  94401. + gcmkERR_BREAK(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
  94402. +
  94403. + /* Set fast clear to auto. */
  94404. + gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(hardware, -1));
  94405. +
  94406. + gcmkERR_BREAK(gckOS_CreateMutex(Os, &hardware->powerMutex));
  94407. +
  94408. + /* Enable power management by default. */
  94409. + hardware->powerManagement = gcvTRUE;
  94410. +
  94411. + /* Return pointer to the gckVGHARDWARE object. */
  94412. + *Hardware = hardware;
  94413. +
  94414. + gcmkFOOTER_NO();
  94415. + /* Success. */
  94416. + return gcvSTATUS_OK;
  94417. + }
  94418. + while (gcvFALSE);
  94419. +
  94420. +#if gcdPOWEROFF_TIMEOUT
  94421. + if (hardware->powerOffTimer != gcvNULL)
  94422. + {
  94423. + gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
  94424. + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
  94425. + }
  94426. +#endif
  94427. +
  94428. + if (hardware->pageTableDirty != gcvNULL)
  94429. + {
  94430. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
  94431. + }
  94432. +
  94433. + if (hardware != gcvNULL)
  94434. + {
  94435. + gcmkVERIFY_OK(gckOS_Free(Os, hardware));
  94436. + }
  94437. +
  94438. + gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvFALSE, gcvFALSE));
  94439. +
  94440. + gcmkFOOTER();
  94441. + /* Return the status. */
  94442. + return status;
  94443. +}
  94444. +
  94445. +/*******************************************************************************
  94446. +**
  94447. +** gckVGHARDWARE_Destroy
  94448. +**
  94449. +** Destroy an gckVGHARDWARE object.
  94450. +**
  94451. +** INPUT:
  94452. +**
  94453. +** gckVGHARDWARE Hardware
  94454. +** Pointer to the gckVGHARDWARE object that needs to be destroyed.
  94455. +**
  94456. +** OUTPUT:
  94457. +**
  94458. +** Nothing.
  94459. +*/
  94460. +gceSTATUS
  94461. +gckVGHARDWARE_Destroy(
  94462. + IN gckVGHARDWARE Hardware
  94463. + )
  94464. +{
  94465. + gceSTATUS status;
  94466. + gcmkHEADER_ARG("Hardware=0x%x ", Hardware);
  94467. + /* Verify the arguments. */
  94468. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94469. +
  94470. + /* Mark the object as unknown. */
  94471. + Hardware->object.type = gcvOBJ_UNKNOWN;
  94472. +
  94473. + if (Hardware->powerMutex != gcvNULL)
  94474. + {
  94475. + gcmkVERIFY_OK(gckOS_DeleteMutex(
  94476. + Hardware->os, Hardware->powerMutex));
  94477. + }
  94478. +
  94479. +#if gcdPOWEROFF_TIMEOUT
  94480. + gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
  94481. + gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
  94482. +#endif
  94483. +
  94484. + if (Hardware->pageTableDirty != gcvNULL)
  94485. + {
  94486. + gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
  94487. + }
  94488. +
  94489. + /* Free the object. */
  94490. + status = gckOS_Free(Hardware->os, Hardware);
  94491. + gcmkFOOTER();
  94492. + return status;
  94493. +}
  94494. +
  94495. +/*******************************************************************************
  94496. +**
  94497. +** gckVGHARDWARE_QueryMemory
  94498. +**
  94499. +** Query the amount of memory available on the hardware.
  94500. +**
  94501. +** INPUT:
  94502. +**
  94503. +** gckVGHARDWARE Hardware
  94504. +** Pointer to the gckVGHARDWARE object.
  94505. +**
  94506. +** OUTPUT:
  94507. +**
  94508. +** gctSIZE_T * InternalSize
  94509. +** Pointer to a variable that will hold the size of the internal video
  94510. +** memory in bytes. If 'InternalSize' is gcvNULL, no information of the
  94511. +** internal memory will be returned.
  94512. +**
  94513. +** gctUINT32 * InternalBaseAddress
  94514. +** Pointer to a variable that will hold the hardware's base address for
  94515. +** the internal video memory. This pointer cannot be gcvNULL if
  94516. +** 'InternalSize' is also non-gcvNULL.
  94517. +**
  94518. +** gctUINT32 * InternalAlignment
  94519. +** Pointer to a variable that will hold the hardware's base address for
  94520. +** the internal video memory. This pointer cannot be gcvNULL if
  94521. +** 'InternalSize' is also non-gcvNULL.
  94522. +**
  94523. +** gctSIZE_T * ExternalSize
  94524. +** Pointer to a variable that will hold the size of the external video
  94525. +** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the
  94526. +** external memory will be returned.
  94527. +**
  94528. +** gctUINT32 * ExternalBaseAddress
  94529. +** Pointer to a variable that will hold the hardware's base address for
  94530. +** the external video memory. This pointer cannot be gcvNULL if
  94531. +** 'ExternalSize' is also non-gcvNULL.
  94532. +**
  94533. +** gctUINT32 * ExternalAlignment
  94534. +** Pointer to a variable that will hold the hardware's base address for
  94535. +** the external video memory. This pointer cannot be gcvNULL if
  94536. +** 'ExternalSize' is also non-gcvNULL.
  94537. +**
  94538. +** gctUINT32 * HorizontalTileSize
  94539. +** Number of horizontal pixels per tile. If 'HorizontalTileSize' is
  94540. +** gcvNULL, no horizontal pixel per tile will be returned.
  94541. +**
  94542. +** gctUINT32 * VerticalTileSize
  94543. +** Number of vertical pixels per tile. If 'VerticalTileSize' is
  94544. +** gcvNULL, no vertical pixel per tile will be returned.
  94545. +*/
  94546. +gceSTATUS
  94547. +gckVGHARDWARE_QueryMemory(
  94548. + IN gckVGHARDWARE Hardware,
  94549. + OUT gctSIZE_T * InternalSize,
  94550. + OUT gctUINT32 * InternalBaseAddress,
  94551. + OUT gctUINT32 * InternalAlignment,
  94552. + OUT gctSIZE_T * ExternalSize,
  94553. + OUT gctUINT32 * ExternalBaseAddress,
  94554. + OUT gctUINT32 * ExternalAlignment,
  94555. + OUT gctUINT32 * HorizontalTileSize,
  94556. + OUT gctUINT32 * VerticalTileSize
  94557. + )
  94558. +{
  94559. + gcmkHEADER_ARG("Hardware=0x%x InternalSize=0x%x InternalBaseAddress=0x%x InternalAlignment=0x%x"
  94560. + "ExternalSize=0x%x ExternalBaseAddress=0x%x ExternalAlignment=0x%x HorizontalTileSize=0x%x VerticalTileSize=0x%x",
  94561. + Hardware, InternalSize, InternalBaseAddress, InternalAlignment,
  94562. + ExternalSize, ExternalBaseAddress, ExternalAlignment, HorizontalTileSize, VerticalTileSize);
  94563. +
  94564. + /* Verify the arguments. */
  94565. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94566. +
  94567. + if (InternalSize != gcvNULL)
  94568. + {
  94569. + /* No internal memory. */
  94570. + *InternalSize = 0;
  94571. + }
  94572. +
  94573. + if (ExternalSize != gcvNULL)
  94574. + {
  94575. + /* No external memory. */
  94576. + *ExternalSize = 0;
  94577. + }
  94578. +
  94579. + if (HorizontalTileSize != gcvNULL)
  94580. + {
  94581. + /* 4x4 tiles. */
  94582. + *HorizontalTileSize = 4;
  94583. + }
  94584. +
  94585. + if (VerticalTileSize != gcvNULL)
  94586. + {
  94587. + /* 4x4 tiles. */
  94588. + *VerticalTileSize = 4;
  94589. + }
  94590. +
  94591. + gcmkFOOTER_NO();
  94592. + /* Success. */
  94593. + return gcvSTATUS_OK;
  94594. +}
  94595. +
  94596. +/*******************************************************************************
  94597. +**
  94598. +** gckVGHARDWARE_QueryChipIdentity
  94599. +**
  94600. +** Query the identity of the hardware.
  94601. +**
  94602. +** INPUT:
  94603. +**
  94604. +** gckVGHARDWARE Hardware
  94605. +** Pointer to the gckVGHARDWARE object.
  94606. +**
  94607. +** OUTPUT:
  94608. +**
  94609. +** gceCHIPMODEL * ChipModel
  94610. +** If 'ChipModel' is not gcvNULL, the variable it points to will
  94611. +** receive the model of the chip.
  94612. +**
  94613. +** gctUINT32 * ChipRevision
  94614. +** If 'ChipRevision' is not gcvNULL, the variable it points to will
  94615. +** receive the revision of the chip.
  94616. +**
  94617. +** gctUINT32 * ChipFeatures
  94618. +** If 'ChipFeatures' is not gcvNULL, the variable it points to will
  94619. +** receive the feature set of the chip.
  94620. +**
  94621. +** gctUINT32 * ChipMinorFeatures
  94622. +** If 'ChipMinorFeatures' is not gcvNULL, the variable it points to
  94623. +** will receive the minor feature set of the chip.
  94624. +**
  94625. +** gctUINT32 * ChipMinorFeatures2
  94626. +** If 'ChipMinorFeatures2' is not gcvNULL, the variable it points to
  94627. +** will receive the minor feature set of the chip.
  94628. +**
  94629. +*/
  94630. +gceSTATUS
  94631. +gckVGHARDWARE_QueryChipIdentity(
  94632. + IN gckVGHARDWARE Hardware,
  94633. + OUT gceCHIPMODEL * ChipModel,
  94634. + OUT gctUINT32 * ChipRevision,
  94635. + OUT gctUINT32* ChipFeatures,
  94636. + OUT gctUINT32* ChipMinorFeatures,
  94637. + OUT gctUINT32* ChipMinorFeatures2
  94638. + )
  94639. +{
  94640. + gcmkHEADER_ARG("Hardware=0x%x ChipModel=0x%x ChipRevision=0x%x ChipFeatures = 0x%x ChipMinorFeatures = 0x%x ChipMinorFeatures2 = 0x%x",
  94641. + Hardware, ChipModel, ChipRevision, ChipFeatures, ChipMinorFeatures, ChipMinorFeatures2);
  94642. +
  94643. + /* Verify the arguments. */
  94644. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94645. +
  94646. + /* Return chip model. */
  94647. + if (ChipModel != gcvNULL)
  94648. + {
  94649. + *ChipModel = Hardware->chipModel;
  94650. + }
  94651. +
  94652. + /* Return revision number. */
  94653. + if (ChipRevision != gcvNULL)
  94654. + {
  94655. + *ChipRevision = Hardware->chipRevision;
  94656. + }
  94657. +
  94658. + /* Return feature set. */
  94659. + if (ChipFeatures != gcvNULL)
  94660. + {
  94661. + gctUINT32 features = Hardware->chipFeatures;
  94662. +
  94663. + if ((((((gctUINT32) (features)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  94664. + {
  94665. + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (Hardware->allowFastClear) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
  94666. + }
  94667. +
  94668. + /* Mark 2D pipe as available for GC500.0 since it did not have this *\
  94669. + \* bit. */
  94670. + if ((Hardware->chipModel == gcv500)
  94671. + && (Hardware->chipRevision == 0)
  94672. + )
  94673. + {
  94674. + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
  94675. + }
  94676. +
  94677. + /* Mark 2D pipe as available for GC300 since it did not have this *\
  94678. + \* bit. */
  94679. + if (Hardware->chipModel == gcv300)
  94680. + {
  94681. + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
  94682. + }
  94683. +
  94684. + *ChipFeatures = features;
  94685. + }
  94686. +
  94687. + /* Return minor feature set. */
  94688. + if (ChipMinorFeatures != gcvNULL)
  94689. + {
  94690. + *ChipMinorFeatures = Hardware->chipMinorFeatures;
  94691. + }
  94692. +
  94693. + /* Return minor feature set #2. */
  94694. + if (ChipMinorFeatures2 != gcvNULL)
  94695. + {
  94696. + *ChipMinorFeatures2 = Hardware->chipMinorFeatures2;
  94697. + }
  94698. +
  94699. + gcmkFOOTER_NO();
  94700. + /* Success. */
  94701. + return gcvSTATUS_OK;
  94702. +}
  94703. +
  94704. +/*******************************************************************************
  94705. +**
  94706. +** gckVGHARDWARE_ConvertFormat
  94707. +**
  94708. +** Convert an API format to hardware parameters.
  94709. +**
  94710. +** INPUT:
  94711. +**
  94712. +** gckVGHARDWARE Hardware
  94713. +** Pointer to the gckVGHARDWARE object.
  94714. +**
  94715. +** gceSURF_FORMAT Format
  94716. +** API format to convert.
  94717. +**
  94718. +** OUTPUT:
  94719. +**
  94720. +** gctUINT32 * BitsPerPixel
  94721. +** Pointer to a variable that will hold the number of bits per pixel.
  94722. +**
  94723. +** gctUINT32 * BytesPerTile
  94724. +** Pointer to a variable that will hold the number of bytes per tile.
  94725. +*/
  94726. +gceSTATUS
  94727. +gckVGHARDWARE_ConvertFormat(
  94728. + IN gckVGHARDWARE Hardware,
  94729. + IN gceSURF_FORMAT Format,
  94730. + OUT gctUINT32 * BitsPerPixel,
  94731. + OUT gctUINT32 * BytesPerTile
  94732. + )
  94733. +{
  94734. + gctUINT32 bitsPerPixel;
  94735. + gctUINT32 bytesPerTile;
  94736. +
  94737. + gcmkHEADER_ARG("Hardware=0x%x Format=0x%x BitsPerPixel=0x%x BytesPerTile = 0x%x",
  94738. + Hardware, Format, BitsPerPixel, BytesPerTile);
  94739. +
  94740. + /* Verify the arguments. */
  94741. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94742. +
  94743. + /* Dispatch on format. */
  94744. + switch (Format)
  94745. + {
  94746. + case gcvSURF_A1:
  94747. + case gcvSURF_L1:
  94748. + /* 1-bpp format. */
  94749. + bitsPerPixel = 1;
  94750. + bytesPerTile = (1 * 4 * 4) / 8;
  94751. + break;
  94752. +
  94753. + case gcvSURF_A4:
  94754. + /* 4-bpp format. */
  94755. + bitsPerPixel = 4;
  94756. + bytesPerTile = (4 * 4 * 4) / 8;
  94757. + break;
  94758. +
  94759. + case gcvSURF_INDEX8:
  94760. + case gcvSURF_A8:
  94761. + case gcvSURF_L8:
  94762. + /* 8-bpp format. */
  94763. + bitsPerPixel = 8;
  94764. + bytesPerTile = (8 * 4 * 4) / 8;
  94765. + break;
  94766. +
  94767. + case gcvSURF_YV12:
  94768. + /* 12-bpp planar YUV formats. */
  94769. + bitsPerPixel = 12;
  94770. + bytesPerTile = (12 * 4 * 4) / 8;
  94771. + break;
  94772. +
  94773. + case gcvSURF_NV12:
  94774. + /* 12-bpp planar YUV formats. */
  94775. + bitsPerPixel = 12;
  94776. + bytesPerTile = (12 * 4 * 4) / 8;
  94777. + break;
  94778. +
  94779. + /* 4444 variations. */
  94780. + case gcvSURF_X4R4G4B4:
  94781. + case gcvSURF_A4R4G4B4:
  94782. + case gcvSURF_R4G4B4X4:
  94783. + case gcvSURF_R4G4B4A4:
  94784. + case gcvSURF_B4G4R4X4:
  94785. + case gcvSURF_B4G4R4A4:
  94786. + case gcvSURF_X4B4G4R4:
  94787. + case gcvSURF_A4B4G4R4:
  94788. +
  94789. + /* 1555 variations. */
  94790. + case gcvSURF_X1R5G5B5:
  94791. + case gcvSURF_A1R5G5B5:
  94792. + case gcvSURF_R5G5B5X1:
  94793. + case gcvSURF_R5G5B5A1:
  94794. + case gcvSURF_X1B5G5R5:
  94795. + case gcvSURF_A1B5G5R5:
  94796. + case gcvSURF_B5G5R5X1:
  94797. + case gcvSURF_B5G5R5A1:
  94798. +
  94799. + /* 565 variations. */
  94800. + case gcvSURF_R5G6B5:
  94801. + case gcvSURF_B5G6R5:
  94802. +
  94803. + case gcvSURF_A8L8:
  94804. + case gcvSURF_YUY2:
  94805. + case gcvSURF_UYVY:
  94806. + case gcvSURF_D16:
  94807. + /* 16-bpp format. */
  94808. + bitsPerPixel = 16;
  94809. + bytesPerTile = (16 * 4 * 4) / 8;
  94810. + break;
  94811. +
  94812. + case gcvSURF_X8R8G8B8:
  94813. + case gcvSURF_A8R8G8B8:
  94814. + case gcvSURF_X8B8G8R8:
  94815. + case gcvSURF_A8B8G8R8:
  94816. + case gcvSURF_R8G8B8X8:
  94817. + case gcvSURF_R8G8B8A8:
  94818. + case gcvSURF_B8G8R8X8:
  94819. + case gcvSURF_B8G8R8A8:
  94820. + case gcvSURF_D32:
  94821. + /* 32-bpp format. */
  94822. + bitsPerPixel = 32;
  94823. + bytesPerTile = (32 * 4 * 4) / 8;
  94824. + break;
  94825. +
  94826. + case gcvSURF_D24S8:
  94827. + /* 24-bpp format. */
  94828. + bitsPerPixel = 32;
  94829. + bytesPerTile = (32 * 4 * 4) / 8;
  94830. + break;
  94831. +
  94832. + case gcvSURF_DXT1:
  94833. + case gcvSURF_ETC1:
  94834. + bitsPerPixel = 4;
  94835. + bytesPerTile = (4 * 4 * 4) / 8;
  94836. + break;
  94837. +
  94838. + case gcvSURF_DXT2:
  94839. + case gcvSURF_DXT3:
  94840. + case gcvSURF_DXT4:
  94841. + case gcvSURF_DXT5:
  94842. + bitsPerPixel = 8;
  94843. + bytesPerTile = (8 * 4 * 4) / 8;
  94844. + break;
  94845. +
  94846. + default:
  94847. + /* Invalid format. */
  94848. + gcmkFOOTER_NO();
  94849. + return gcvSTATUS_INVALID_ARGUMENT;
  94850. + }
  94851. +
  94852. + /* Set the result. */
  94853. + if (BitsPerPixel != gcvNULL)
  94854. + {
  94855. + * BitsPerPixel = bitsPerPixel;
  94856. + }
  94857. +
  94858. + if (BytesPerTile != gcvNULL)
  94859. + {
  94860. + * BytesPerTile = bytesPerTile;
  94861. + }
  94862. +
  94863. + gcmkFOOTER_NO();
  94864. + /* Success. */
  94865. + return gcvSTATUS_OK;
  94866. +}
  94867. +
  94868. +/*******************************************************************************
  94869. +**
  94870. +** gckVGHARDWARE_SplitMemory
  94871. +**
  94872. +** Split a hardware specific memory address into a pool and offset.
  94873. +**
  94874. +** INPUT:
  94875. +**
  94876. +** gckVGHARDWARE Hardware
  94877. +** Pointer to the gckVGHARDWARE object.
  94878. +**
  94879. +** gctUINT32 Address
  94880. +** Address in hardware specific format.
  94881. +**
  94882. +** OUTPUT:
  94883. +**
  94884. +** gcePOOL * Pool
  94885. +** Pointer to a variable that will hold the pool type for the address.
  94886. +**
  94887. +** gctUINT32 * Offset
  94888. +** Pointer to a variable that will hold the offset for the address.
  94889. +*/
  94890. +gceSTATUS
  94891. +gckVGHARDWARE_SplitMemory(
  94892. + IN gckVGHARDWARE Hardware,
  94893. + IN gctUINT32 Address,
  94894. + OUT gcePOOL * Pool,
  94895. + OUT gctUINT32 * Offset
  94896. + )
  94897. +{
  94898. + gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Pool=0x%x Offset = 0x%x",
  94899. + Hardware, Address, Pool, Offset);
  94900. + /* Verify the arguments. */
  94901. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94902. + gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
  94903. + gcmkVERIFY_ARGUMENT(Offset != gcvNULL);
  94904. +
  94905. + /* Dispatch on memory type. */
  94906. + switch ((((((gctUINT32) (Address)) >> (0 ? 1:0)) & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1)))))) ))
  94907. + {
  94908. + case 0x0:
  94909. + /* System memory. */
  94910. + *Pool = gcvPOOL_SYSTEM;
  94911. + break;
  94912. +
  94913. + case 0x2:
  94914. + /* Virtual memory. */
  94915. + *Pool = gcvPOOL_VIRTUAL;
  94916. + break;
  94917. +
  94918. + default:
  94919. + /* Invalid memory type. */
  94920. + gcmkFOOTER_NO();
  94921. + return gcvSTATUS_INVALID_ARGUMENT;
  94922. + }
  94923. +
  94924. + /* Return offset of address. */
  94925. + *Offset = ((((gctUINT32) (Address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
  94926. +
  94927. + gcmkFOOTER_NO();
  94928. + /* Success. */
  94929. + return gcvSTATUS_OK;
  94930. +}
  94931. +
  94932. +/*******************************************************************************
  94933. +**
  94934. +** gckVGHARDWARE_Execute
  94935. +**
  94936. +** Kickstart the hardware's command processor with an initialized command
  94937. +** buffer.
  94938. +**
  94939. +** INPUT:
  94940. +**
  94941. +** gckVGHARDWARE Hardware
  94942. +** Pointer to the gckVGHARDWARE object.
  94943. +**
  94944. +** gctUINT32 Address
  94945. +** Address of the command buffer.
  94946. +**
  94947. +** gctSIZE_T Count
  94948. +** Number of command-sized data units to be executed.
  94949. +**
  94950. +** OUTPUT:
  94951. +**
  94952. +** Nothing.
  94953. +*/
  94954. +gceSTATUS
  94955. +gckVGHARDWARE_Execute(
  94956. + IN gckVGHARDWARE Hardware,
  94957. + IN gctUINT32 Address,
  94958. + IN gctSIZE_T Count
  94959. + )
  94960. +{
  94961. + gceSTATUS status;
  94962. +
  94963. + gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Count=0x%x",
  94964. + Hardware, Address, Count);
  94965. +
  94966. + /* Verify the arguments. */
  94967. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94968. +
  94969. + do
  94970. + {
  94971. + /* Enable all events. */
  94972. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  94973. + Hardware->os,
  94974. + gcvCORE_VG,
  94975. + 0x00014,
  94976. + Hardware->eventMask
  94977. + ));
  94978. +
  94979. + if (Hardware->fe20)
  94980. + {
  94981. + /* Write address register. */
  94982. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  94983. + Hardware->os,
  94984. + gcvCORE_VG,
  94985. + 0x00500,
  94986. + gcmkFIXADDRESS(Address)
  94987. + ));
  94988. +
  94989. + /* Write control register. */
  94990. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  94991. + Hardware->os,
  94992. + gcvCORE_VG,
  94993. + 0x00504,
  94994. + Count
  94995. + ));
  94996. + }
  94997. + else
  94998. + {
  94999. + /* Write address register. */
  95000. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  95001. + Hardware->os,
  95002. + gcvCORE_VG,
  95003. + 0x00654,
  95004. + gcmkFIXADDRESS(Address)
  95005. + ));
  95006. +
  95007. + /* Write control register. */
  95008. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  95009. + Hardware->os,
  95010. + gcvCORE_VG,
  95011. + 0x00658,
  95012. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) |
  95013. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  95014. + ));
  95015. + }
  95016. +
  95017. + /* Success. */
  95018. + gcmkFOOTER();
  95019. + return gcvSTATUS_OK;
  95020. + }
  95021. + while (gcvFALSE);
  95022. +
  95023. +
  95024. + gcmkFOOTER();
  95025. + /* Return the status. */
  95026. + return status;
  95027. +}
  95028. +
  95029. +/*******************************************************************************
  95030. +**
  95031. +** gckVGHARDWARE_AlignToTile
  95032. +**
  95033. +** Align the specified width and height to tile boundaries.
  95034. +**
  95035. +** INPUT:
  95036. +**
  95037. +** gckVGHARDWARE Hardware
  95038. +** Pointer to an gckVGHARDWARE object.
  95039. +**
  95040. +** gceSURF_TYPE Type
  95041. +** Type of alignment.
  95042. +**
  95043. +** gctUINT32 * Width
  95044. +** Pointer to the width to be aligned. If 'Width' is gcvNULL, no width
  95045. +** will be aligned.
  95046. +**
  95047. +** gctUINT32 * Height
  95048. +** Pointer to the height to be aligned. If 'Height' is gcvNULL, no height
  95049. +** will be aligned.
  95050. +**
  95051. +** OUTPUT:
  95052. +**
  95053. +** gctUINT32 * Width
  95054. +** Pointer to a variable that will receive the aligned width.
  95055. +**
  95056. +** gctUINT32 * Height
  95057. +** Pointer to a variable that will receive the aligned height.
  95058. +*/
  95059. +gceSTATUS
  95060. +gckVGHARDWARE_AlignToTile(
  95061. + IN gckVGHARDWARE Hardware,
  95062. + IN gceSURF_TYPE Type,
  95063. + IN OUT gctUINT32 * Width,
  95064. + IN OUT gctUINT32 * Height
  95065. + )
  95066. +{
  95067. + gcmkHEADER_ARG("Hardware=0x%x Type=0x%x Width=0x%x Height=0x%x",
  95068. + Hardware, Type, Width, Height);
  95069. + /* Verify the arguments. */
  95070. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95071. +
  95072. + if (Width != gcvNULL)
  95073. + {
  95074. + /* Align the width. */
  95075. + *Width = gcmALIGN(*Width, (Type == gcvSURF_TEXTURE) ? 4 : 16);
  95076. + }
  95077. +
  95078. + if (Height != gcvNULL)
  95079. + {
  95080. + /* Special case for VG images. */
  95081. + if ((*Height == 0) && (Type == gcvSURF_IMAGE))
  95082. + {
  95083. + *Height = 4;
  95084. + }
  95085. + else
  95086. + {
  95087. + /* Align the height. */
  95088. + *Height = gcmALIGN(*Height, 4);
  95089. + }
  95090. + }
  95091. +
  95092. + gcmkFOOTER_NO();
  95093. + /* Success. */
  95094. + return gcvSTATUS_OK;
  95095. +}
  95096. +
  95097. +/*******************************************************************************
  95098. +**
  95099. +** gckVGHARDWARE_ConvertLogical
  95100. +**
  95101. +** Convert a logical system address into a hardware specific address.
  95102. +**
  95103. +** INPUT:
  95104. +**
  95105. +** gckVGHARDWARE Hardware
  95106. +** Pointer to an gckVGHARDWARE object.
  95107. +**
  95108. +** gctPOINTER Logical
  95109. +** Logical address to convert.
  95110. +**
  95111. +** gctUINT32* Address
  95112. +** Return hardware specific address.
  95113. +**
  95114. +** OUTPUT:
  95115. +**
  95116. +** Nothing.
  95117. +*/
  95118. +gceSTATUS
  95119. +gckVGHARDWARE_ConvertLogical(
  95120. + IN gckVGHARDWARE Hardware,
  95121. + IN gctPOINTER Logical,
  95122. + OUT gctUINT32 * Address
  95123. + )
  95124. +{
  95125. + gctUINT32 address;
  95126. + gceSTATUS status;
  95127. +
  95128. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Address=0x%x",
  95129. + Hardware, Logical, Address);
  95130. +
  95131. + /* Verify the arguments. */
  95132. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95133. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  95134. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  95135. +
  95136. + do
  95137. + {
  95138. + /* Convert logical address into a physical address. */
  95139. + gcmkERR_BREAK(gckOS_GetPhysicalAddress(
  95140. + Hardware->os, Logical, &address
  95141. + ));
  95142. +
  95143. + /* Return hardware specific address. */
  95144. + *Address = ((((gctUINT32) (address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
  95145. +
  95146. + /* Success. */
  95147. + gcmkFOOTER();
  95148. + return gcvSTATUS_OK;
  95149. + }
  95150. + while (gcvFALSE);
  95151. +
  95152. + gcmkFOOTER();
  95153. + /* Return the status. */
  95154. + return status;
  95155. +}
  95156. +
  95157. +/*******************************************************************************
  95158. +**
  95159. +** gckVGHARDWARE_QuerySystemMemory
  95160. +**
  95161. +** Query the command buffer alignment and number of reserved bytes.
  95162. +**
  95163. +** INPUT:
  95164. +**
  95165. +** gckVGHARDWARE Harwdare
  95166. +** Pointer to an gckVGHARDWARE object.
  95167. +**
  95168. +** OUTPUT:
  95169. +**
  95170. +** gctSIZE_T * SystemSize
  95171. +** Pointer to a variable that receives the maximum size of the system
  95172. +** memory.
  95173. +**
  95174. +** gctUINT32 * SystemBaseAddress
  95175. +** Poinetr to a variable that receives the base address for system
  95176. +** memory.
  95177. +*/
  95178. +gceSTATUS gckVGHARDWARE_QuerySystemMemory(
  95179. + IN gckVGHARDWARE Hardware,
  95180. + OUT gctSIZE_T * SystemSize,
  95181. + OUT gctUINT32 * SystemBaseAddress
  95182. + )
  95183. +{
  95184. + gcmkHEADER_ARG("Hardware=0x%x SystemSize=0x%x SystemBaseAddress=0x%x",
  95185. + Hardware, SystemSize, SystemBaseAddress);
  95186. +
  95187. + /* Verify the arguments. */
  95188. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95189. +
  95190. + if (SystemSize != gcvNULL)
  95191. + {
  95192. + /* Maximum system memory can be 2GB. */
  95193. + *SystemSize = (gctSIZE_T)(1 << 31);
  95194. + }
  95195. +
  95196. + if (SystemBaseAddress != gcvNULL)
  95197. + {
  95198. + /* Set system memory base address. */
  95199. + *SystemBaseAddress = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
  95200. + }
  95201. +
  95202. + gcmkFOOTER_NO();
  95203. + /* Success. */
  95204. + return gcvSTATUS_OK;
  95205. +}
  95206. +
  95207. +/*******************************************************************************
  95208. +**
  95209. +** gckVGHARDWARE_SetMMU
  95210. +**
  95211. +** Set the page table base address.
  95212. +**
  95213. +** INPUT:
  95214. +**
  95215. +** gckVGHARDWARE Harwdare
  95216. +** Pointer to an gckVGHARDWARE object.
  95217. +**
  95218. +** gctPOINTER Logical
  95219. +** Logical address of the page table.
  95220. +**
  95221. +** OUTPUT:
  95222. +**
  95223. +** Nothing.
  95224. +*/
  95225. +gceSTATUS gckVGHARDWARE_SetMMU(
  95226. + IN gckVGHARDWARE Hardware,
  95227. + IN gctPOINTER Logical
  95228. + )
  95229. +{
  95230. + gceSTATUS status;
  95231. + gctUINT32 address = 0;
  95232. +
  95233. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x",
  95234. + Hardware, Logical);
  95235. +
  95236. + /* Verify the arguments. */
  95237. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95238. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  95239. +
  95240. + do
  95241. + {
  95242. + /* Convert the logical address into an hardware address. */
  95243. + gcmkERR_BREAK(gckVGHARDWARE_ConvertLogical(Hardware, Logical, &address) );
  95244. +
  95245. + /* Write the AQMemoryFePageTable register. */
  95246. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95247. + 0x00400,
  95248. + gcmkFIXADDRESS(address)) );
  95249. +
  95250. + /* Write the AQMemoryTxPageTable register. */
  95251. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95252. + 0x00404,
  95253. + gcmkFIXADDRESS(address)) );
  95254. +
  95255. + /* Write the AQMemoryPePageTable register. */
  95256. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95257. + 0x00408,
  95258. + gcmkFIXADDRESS(address)) );
  95259. +
  95260. + /* Write the AQMemoryPezPageTable register. */
  95261. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95262. + 0x0040C,
  95263. + gcmkFIXADDRESS(address)) );
  95264. +
  95265. + /* Write the AQMemoryRaPageTable register. */
  95266. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95267. + 0x00410,
  95268. + gcmkFIXADDRESS(address)) );
  95269. + }
  95270. + while (gcvFALSE);
  95271. +
  95272. + gcmkFOOTER();
  95273. + /* Return the status. */
  95274. + return status;
  95275. +}
  95276. +
  95277. +/*******************************************************************************
  95278. +**
  95279. +** gckVGHARDWARE_FlushMMU
  95280. +**
  95281. +** Flush the page table.
  95282. +**
  95283. +** INPUT:
  95284. +**
  95285. +** gckVGHARDWARE Harwdare
  95286. +** Pointer to an gckVGHARDWARE object.
  95287. +**
  95288. +** OUTPUT:
  95289. +**
  95290. +** Nothing.
  95291. +*/
  95292. +gceSTATUS gckVGHARDWARE_FlushMMU(
  95293. + IN gckVGHARDWARE Hardware
  95294. + )
  95295. +{
  95296. + gceSTATUS status;
  95297. + gckVGCOMMAND command;
  95298. +
  95299. + gcmkHEADER_ARG("Hardware=0x%x ", Hardware);
  95300. + /* Verify the arguments. */
  95301. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95302. +
  95303. + do
  95304. + {
  95305. + gcsCMDBUFFER_PTR commandBuffer;
  95306. + gctUINT32_PTR buffer;
  95307. +
  95308. + /* Create a shortcut to the command buffer object. */
  95309. + command = Hardware->kernel->command;
  95310. +
  95311. + /* Allocate command buffer space. */
  95312. + gcmkERR_BREAK(gckVGCOMMAND_Allocate(
  95313. + command, 8, &commandBuffer, (gctPOINTER *) &buffer
  95314. + ));
  95315. +
  95316. + buffer[0]
  95317. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  95318. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E04) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  95319. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  95320. +
  95321. + buffer[1]
  95322. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
  95323. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
  95324. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
  95325. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
  95326. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
  95327. + }
  95328. + while(gcvFALSE);
  95329. +
  95330. + gcmkFOOTER();
  95331. + /* Return the status. */
  95332. + return status;
  95333. +}
  95334. +
  95335. +/*******************************************************************************
  95336. +**
  95337. +** gckVGHARDWARE_BuildVirtualAddress
  95338. +**
  95339. +** Build a virtual address.
  95340. +**
  95341. +** INPUT:
  95342. +**
  95343. +** gckVGHARDWARE Harwdare
  95344. +** Pointer to an gckVGHARDWARE object.
  95345. +**
  95346. +** gctUINT32 Index
  95347. +** Index into page table.
  95348. +**
  95349. +** gctUINT32 Offset
  95350. +** Offset into page.
  95351. +**
  95352. +** OUTPUT:
  95353. +**
  95354. +** gctUINT32 * Address
  95355. +** Pointer to a variable receiving te hardware address.
  95356. +*/
  95357. +gceSTATUS gckVGHARDWARE_BuildVirtualAddress(
  95358. + IN gckVGHARDWARE Hardware,
  95359. + IN gctUINT32 Index,
  95360. + IN gctUINT32 Offset,
  95361. + OUT gctUINT32 * Address
  95362. + )
  95363. +{
  95364. + gctUINT32 address;
  95365. +
  95366. + gcmkHEADER_ARG("Hardware=0x%x Index=0x%x Offset=0x%x Address=0x%x",
  95367. + Hardware, Index, Offset, Address);
  95368. +
  95369. + /* Verify the arguments. */
  95370. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95371. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  95372. +
  95373. + /* Build virtual address. */
  95374. + address = (Index << 12) | Offset;
  95375. +
  95376. + /* Set virtual type. */
  95377. + address = ((((gctUINT32) (address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
  95378. +
  95379. + /* Set the result. */
  95380. + *Address = address;
  95381. +
  95382. + gcmkFOOTER_NO();
  95383. + /* Success. */
  95384. + return gcvSTATUS_OK;
  95385. +}
  95386. +
  95387. +gceSTATUS
  95388. +gckVGHARDWARE_GetIdle(
  95389. + IN gckVGHARDWARE Hardware,
  95390. + OUT gctUINT32 * Data
  95391. + )
  95392. +{
  95393. + gceSTATUS status;
  95394. + gcmkHEADER_ARG("Hardware=0x%x Data=0x%x", Hardware, Data);
  95395. + /* Verify the arguments. */
  95396. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95397. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  95398. +
  95399. + /* Read register and return. */
  95400. + status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, 0x00004, Data);
  95401. + gcmkFOOTER();
  95402. + return status;
  95403. +}
  95404. +
  95405. +gceSTATUS
  95406. +gckVGHARDWARE_SetFastClear(
  95407. + IN gckVGHARDWARE Hardware,
  95408. + IN gctINT Enable
  95409. + )
  95410. +{
  95411. + gctUINT32 debug;
  95412. + gceSTATUS status;
  95413. +
  95414. + if (!(((((gctUINT32) (Hardware->chipFeatures)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  95415. + {
  95416. + return gcvSTATUS_OK;
  95417. + }
  95418. +
  95419. + do
  95420. + {
  95421. + if (Enable == -1)
  95422. + {
  95423. + Enable = (Hardware->chipModel > gcv500) ||
  95424. + ((Hardware->chipModel == gcv500) && (Hardware->chipRevision >= 3));
  95425. + }
  95426. +
  95427. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG,
  95428. + 0x00414,
  95429. + &debug));
  95430. +
  95431. + debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20)));
  95432. +
  95433. +#ifdef AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION
  95434. + debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1) == 32) ? ~0 : (~(~0 << ((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1))))))) << (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1) == 32) ? ~0 : (~(~0 << ((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1))))))) << (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION)));
  95435. +#endif
  95436. +
  95437. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95438. + 0x00414,
  95439. + debug));
  95440. +
  95441. + Hardware->allowFastClear = Enable;
  95442. +
  95443. + status = gcvFALSE;
  95444. + }
  95445. + while (gcvFALSE);
  95446. +
  95447. + return status;
  95448. +}
  95449. +
  95450. +gceSTATUS
  95451. +gckVGHARDWARE_ReadInterrupt(
  95452. + IN gckVGHARDWARE Hardware,
  95453. + OUT gctUINT32_PTR IDs
  95454. + )
  95455. +{
  95456. + gceSTATUS status;
  95457. + gcmkHEADER_ARG("Hardware=0x%x IDs=0x%x", Hardware, IDs);
  95458. +
  95459. + /* Verify the arguments. */
  95460. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95461. + gcmkVERIFY_ARGUMENT(IDs != gcvNULL);
  95462. +
  95463. + /* Read AQIntrAcknowledge register. */
  95464. + status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG,
  95465. + 0x00010,
  95466. + IDs);
  95467. + gcmkFOOTER();
  95468. + return status;
  95469. +}
  95470. +
  95471. +static gceSTATUS _CommandStall(
  95472. + gckVGHARDWARE Hardware)
  95473. +{
  95474. + gceSTATUS status;
  95475. + gckVGCOMMAND command;
  95476. +
  95477. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  95478. + /* Verify the arguments. */
  95479. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95480. +
  95481. + do
  95482. + {
  95483. + gctUINT32_PTR buffer;
  95484. + command = Hardware->kernel->command;
  95485. +
  95486. + /* Allocate command buffer space. */
  95487. + gcmkERR_BREAK(gckVGCOMMAND_Allocate(
  95488. + command, 8, &command->powerStallBuffer,
  95489. + (gctPOINTER *) &buffer
  95490. + ));
  95491. +
  95492. + gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
  95493. + command, buffer, gcvBLOCK_PIXEL,
  95494. + command->powerStallInt, gcvNULL));
  95495. +
  95496. + gcmkERR_BREAK(gckVGCOMMAND_Execute(
  95497. + command,
  95498. + command->powerStallBuffer
  95499. + ));
  95500. +
  95501. + /* Wait the signal. */
  95502. + gcmkERR_BREAK(gckOS_WaitSignal(
  95503. + command->os,
  95504. + command->powerStallSignal,
  95505. + gcdGPU_TIMEOUT));
  95506. +
  95507. +
  95508. + }
  95509. + while(gcvFALSE);
  95510. +
  95511. + gcmkFOOTER();
  95512. + /* Return the status. */
  95513. + return status;
  95514. +}
  95515. +
  95516. +/*******************************************************************************
  95517. +**
  95518. +** gckHARDWARE_SetPowerManagementState
  95519. +**
  95520. +** Set GPU to a specified power state.
  95521. +**
  95522. +** INPUT:
  95523. +**
  95524. +** gckHARDWARE Harwdare
  95525. +** Pointer to an gckHARDWARE object.
  95526. +**
  95527. +** gceCHIPPOWERSTATE State
  95528. +** Power State.
  95529. +**
  95530. +*/
  95531. +gceSTATUS
  95532. +gckVGHARDWARE_SetPowerManagementState(
  95533. + IN gckVGHARDWARE Hardware,
  95534. + IN gceCHIPPOWERSTATE State
  95535. + )
  95536. +{
  95537. + gceSTATUS status;
  95538. + gckVGCOMMAND command = gcvNULL;
  95539. + gckOS os;
  95540. + gctUINT flag/*, clock*/;
  95541. +
  95542. + gctBOOL acquired = gcvFALSE;
  95543. + gctBOOL stall = gcvTRUE;
  95544. + gctBOOL commitMutex = gcvFALSE;
  95545. + gctBOOL mutexAcquired = gcvFALSE;
  95546. +
  95547. +#if gcdPOWEROFF_TIMEOUT
  95548. + gctBOOL timeout = gcvFALSE;
  95549. + gctBOOL isAfter = gcvFALSE;
  95550. + gctUINT32 currentTime;
  95551. +#endif
  95552. +
  95553. + gctBOOL broadcast = gcvFALSE;
  95554. + gctUINT32 process, thread;
  95555. + gctBOOL global = gcvFALSE;
  95556. +
  95557. +#if gcdENABLE_PROFILING
  95558. + gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
  95559. + initTime, offTime, startTime, totalTime;
  95560. +#endif
  95561. +
  95562. + /* State transition flags. */
  95563. + static const gctUINT flags[4][4] =
  95564. + {
  95565. + /* gcvPOWER_ON */
  95566. + { /* ON */ 0,
  95567. + /* OFF */ gcvPOWER_FLAG_ACQUIRE |
  95568. + gcvPOWER_FLAG_STALL |
  95569. + gcvPOWER_FLAG_STOP |
  95570. + gcvPOWER_FLAG_POWER_OFF |
  95571. + gcvPOWER_FLAG_CLOCK_OFF,
  95572. + /* IDLE */ gcvPOWER_FLAG_NOP,
  95573. + /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
  95574. + gcvPOWER_FLAG_STALL |
  95575. + gcvPOWER_FLAG_STOP |
  95576. + gcvPOWER_FLAG_CLOCK_OFF,
  95577. + },
  95578. +
  95579. + /* gcvPOWER_OFF */
  95580. + { /* ON */ gcvPOWER_FLAG_INITIALIZE |
  95581. + gcvPOWER_FLAG_START |
  95582. + gcvPOWER_FLAG_RELEASE |
  95583. + gcvPOWER_FLAG_DELAY,
  95584. + /* OFF */ 0,
  95585. + /* IDLE */ gcvPOWER_FLAG_INITIALIZE |
  95586. + gcvPOWER_FLAG_START |
  95587. + gcvPOWER_FLAG_RELEASE |
  95588. + gcvPOWER_FLAG_DELAY,
  95589. + /* SUSPEND */ gcvPOWER_FLAG_INITIALIZE |
  95590. + gcvPOWER_FLAG_CLOCK_OFF,
  95591. + },
  95592. +
  95593. + /* gcvPOWER_IDLE */
  95594. + { /* ON */ gcvPOWER_FLAG_NOP,
  95595. + /* OFF */ gcvPOWER_FLAG_ACQUIRE |
  95596. + gcvPOWER_FLAG_STOP |
  95597. + gcvPOWER_FLAG_POWER_OFF |
  95598. + gcvPOWER_FLAG_CLOCK_OFF,
  95599. + /* IDLE */ 0,
  95600. + /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
  95601. + gcvPOWER_FLAG_STOP |
  95602. + gcvPOWER_FLAG_CLOCK_OFF,
  95603. + },
  95604. +
  95605. + /* gcvPOWER_SUSPEND */
  95606. + { /* ON */ gcvPOWER_FLAG_START |
  95607. + gcvPOWER_FLAG_RELEASE |
  95608. + gcvPOWER_FLAG_DELAY |
  95609. + gcvPOWER_FLAG_CLOCK_ON,
  95610. + /* OFF */ gcvPOWER_FLAG_SAVE |
  95611. + gcvPOWER_FLAG_POWER_OFF |
  95612. + gcvPOWER_FLAG_CLOCK_OFF,
  95613. + /* IDLE */ gcvPOWER_FLAG_START |
  95614. + gcvPOWER_FLAG_DELAY |
  95615. + gcvPOWER_FLAG_RELEASE |
  95616. + gcvPOWER_FLAG_CLOCK_ON,
  95617. + /* SUSPEND */ 0,
  95618. + },
  95619. + };
  95620. +
  95621. + gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
  95622. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  95623. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  95624. + "Switching to power state %d",
  95625. + State);
  95626. +#endif
  95627. +
  95628. + /* Verify the arguments. */
  95629. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95630. +
  95631. + /* Get the gckOS object pointer. */
  95632. + os = Hardware->os;
  95633. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  95634. +
  95635. + /* Get the gckCOMMAND object pointer. */
  95636. + gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
  95637. + command = Hardware->kernel->command;
  95638. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  95639. +
  95640. + if (Hardware->powerManagement == gcvFALSE)
  95641. + {
  95642. + gcmkFOOTER_NO();
  95643. + return gcvSTATUS_OK;
  95644. + }
  95645. +
  95646. + /* Start profiler. */
  95647. + gcmkPROFILE_INIT(freq, time);
  95648. +
  95649. + /* Convert the broadcast power state. */
  95650. + switch (State)
  95651. + {
  95652. + case gcvPOWER_SUSPEND_ATPOWERON:
  95653. + /* Convert to SUSPEND and don't wait for STALL. */
  95654. + State = gcvPOWER_SUSPEND;
  95655. + stall = gcvFALSE;
  95656. + break;
  95657. +
  95658. + case gcvPOWER_OFF_ATPOWERON:
  95659. + /* Convert to OFF and don't wait for STALL. */
  95660. + State = gcvPOWER_OFF;
  95661. + stall = gcvFALSE;
  95662. + break;
  95663. +
  95664. + case gcvPOWER_IDLE_BROADCAST:
  95665. + /* Convert to IDLE and note we are inside broadcast. */
  95666. + State = gcvPOWER_IDLE;
  95667. + broadcast = gcvTRUE;
  95668. + break;
  95669. +
  95670. + case gcvPOWER_SUSPEND_BROADCAST:
  95671. + /* Convert to SUSPEND and note we are inside broadcast. */
  95672. + State = gcvPOWER_SUSPEND;
  95673. + broadcast = gcvTRUE;
  95674. + break;
  95675. +
  95676. + case gcvPOWER_OFF_BROADCAST:
  95677. + /* Convert to OFF and note we are inside broadcast. */
  95678. + State = gcvPOWER_OFF;
  95679. + broadcast = gcvTRUE;
  95680. + break;
  95681. +
  95682. + case gcvPOWER_OFF_RECOVERY:
  95683. + /* Convert to OFF and note we are inside recovery. */
  95684. + State = gcvPOWER_OFF;
  95685. + stall = gcvFALSE;
  95686. + broadcast = gcvTRUE;
  95687. + break;
  95688. +
  95689. + case gcvPOWER_ON_AUTO:
  95690. + /* Convert to ON and note we are inside recovery. */
  95691. + State = gcvPOWER_ON;
  95692. + break;
  95693. +
  95694. + case gcvPOWER_ON:
  95695. + case gcvPOWER_IDLE:
  95696. + case gcvPOWER_SUSPEND:
  95697. + case gcvPOWER_OFF:
  95698. + /* Mark as global power management. */
  95699. + global = gcvTRUE;
  95700. + break;
  95701. +
  95702. +#if gcdPOWEROFF_TIMEOUT
  95703. + case gcvPOWER_OFF_TIMEOUT:
  95704. + /* Convert to OFF and note we are inside broadcast. */
  95705. + State = gcvPOWER_OFF;
  95706. + broadcast = gcvTRUE;
  95707. + /* Check time out */
  95708. + timeout = gcvTRUE;
  95709. + break;
  95710. +#endif
  95711. +
  95712. + default:
  95713. + break;
  95714. + }
  95715. +
  95716. + /* Get current process and thread IDs. */
  95717. + gcmkONERROR(gckOS_GetProcessID(&process));
  95718. + gcmkONERROR(gckOS_GetThreadID(&thread));
  95719. +
  95720. + /* Acquire the power mutex. */
  95721. + if (broadcast)
  95722. + {
  95723. + /* Try to acquire the power mutex. */
  95724. + status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
  95725. +
  95726. + if (status == gcvSTATUS_TIMEOUT)
  95727. + {
  95728. + /* Check if we already own this mutex. */
  95729. + if ((Hardware->powerProcess == process)
  95730. + && (Hardware->powerThread == thread)
  95731. + )
  95732. + {
  95733. + /* Bail out on recursive power management. */
  95734. + gcmkFOOTER_NO();
  95735. + return gcvSTATUS_OK;
  95736. + }
  95737. + else if (State == gcvPOWER_IDLE)
  95738. + {
  95739. + /* gcvPOWER_IDLE_BROADCAST is from IST,
  95740. + ** so waiting here will cause deadlock,
  95741. + ** if lock holder call gckCOMMAND_Stall() */
  95742. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  95743. + }
  95744. + else
  95745. + {
  95746. + /* Acquire the power mutex. */
  95747. + gcmkONERROR(gckOS_AcquireMutex(os,
  95748. + Hardware->powerMutex,
  95749. + gcvINFINITE));
  95750. + }
  95751. + }
  95752. + }
  95753. + else
  95754. + {
  95755. + /* Acquire the power mutex. */
  95756. + gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
  95757. + }
  95758. +
  95759. + /* Get time until mtuex acquired. */
  95760. + gcmkPROFILE_QUERY(time, mutexTime);
  95761. +
  95762. + Hardware->powerProcess = process;
  95763. + Hardware->powerThread = thread;
  95764. + mutexAcquired = gcvTRUE;
  95765. +
  95766. + /* Grab control flags and clock. */
  95767. + flag = flags[Hardware->chipPowerState][State];
  95768. + /*clock = clocks[State];*/
  95769. +
  95770. +#if gcdPOWEROFF_TIMEOUT
  95771. + if (timeout)
  95772. + {
  95773. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  95774. +
  95775. + gcmkONERROR(
  95776. + gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
  95777. +
  95778. + /* powerOffTime is pushed forward, give up.*/
  95779. + if (isAfter
  95780. + /* Expect a transition start from IDLE. */
  95781. + || (Hardware->chipPowerState == gcvPOWER_ON)
  95782. + || (Hardware->chipPowerState == gcvPOWER_OFF)
  95783. + )
  95784. + {
  95785. + /* Release the power mutex. */
  95786. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  95787. +
  95788. + /* No need to do anything. */
  95789. + gcmkFOOTER_NO();
  95790. + return gcvSTATUS_OK;
  95791. + }
  95792. + }
  95793. +#endif
  95794. +
  95795. + if (flag == 0)
  95796. + {
  95797. + /* Release the power mutex. */
  95798. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  95799. +
  95800. + /* No need to do anything. */
  95801. + gcmkFOOTER_NO();
  95802. + return gcvSTATUS_OK;
  95803. + }
  95804. +
  95805. + /* internal power control */
  95806. + if (!global)
  95807. + {
  95808. + if (Hardware->chipPowerStateGlobal == gcvPOWER_OFF)
  95809. + {
  95810. + /* Release the power mutex. */
  95811. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  95812. +
  95813. + /* No need to do anything. */
  95814. + gcmkFOOTER_NO();
  95815. + return gcvSTATUS_OK;
  95816. + }
  95817. + }
  95818. + else
  95819. + {
  95820. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  95821. + {
  95822. + /* Acquire the power management semaphore. */
  95823. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  95824. + acquired = gcvTRUE;
  95825. +
  95826. + /* avoid acquiring again. */
  95827. + flag &= ~gcvPOWER_FLAG_ACQUIRE;
  95828. + }
  95829. + }
  95830. +
  95831. + if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
  95832. + {
  95833. + /* Turn on the power. */
  95834. + gcmkONERROR(gckOS_SetGPUPower(os, gcvCORE_VG, gcvTRUE, gcvTRUE));
  95835. +
  95836. + /* Mark clock and power as enabled. */
  95837. + Hardware->clockState = gcvTRUE;
  95838. + Hardware->powerState = gcvTRUE;
  95839. + }
  95840. +
  95841. + /* Get time until powered on. */
  95842. + gcmkPROFILE_QUERY(time, onTime);
  95843. +
  95844. + if ((flag & gcvPOWER_FLAG_STALL) && stall)
  95845. + {
  95846. + /* Acquire the mutex. */
  95847. + gcmkONERROR(gckOS_AcquireMutex(
  95848. + command->os,
  95849. + command->commitMutex,
  95850. + gcvINFINITE
  95851. + ));
  95852. +
  95853. + commitMutex = gcvTRUE;
  95854. +
  95855. + gcmkONERROR(_CommandStall(Hardware));
  95856. + }
  95857. +
  95858. + /* Get time until stalled. */
  95859. + gcmkPROFILE_QUERY(time, stallTime);
  95860. +
  95861. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  95862. + {
  95863. + /* Acquire the power management semaphore. */
  95864. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  95865. +
  95866. + acquired = gcvTRUE;
  95867. + }
  95868. +
  95869. + if (flag & gcvPOWER_FLAG_STOP)
  95870. + {
  95871. + }
  95872. +
  95873. + /* Get time until stopped. */
  95874. + gcmkPROFILE_QUERY(time, stopTime);
  95875. +
  95876. + /* Only process this when hardware is enabled. */
  95877. + if (Hardware->clockState && Hardware->powerState)
  95878. + {
  95879. + }
  95880. +
  95881. + if (flag & gcvPOWER_FLAG_DELAY)
  95882. + {
  95883. + /* Wait for the specified amount of time to settle coming back from
  95884. + ** power-off or suspend state. */
  95885. + gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
  95886. + }
  95887. +
  95888. + /* Get time until delayed. */
  95889. + gcmkPROFILE_QUERY(time, delayTime);
  95890. +
  95891. + if (flag & gcvPOWER_FLAG_INITIALIZE)
  95892. + {
  95893. + gcmkONERROR(gckVGHARDWARE_SetMMU(Hardware, Hardware->kernel->mmu->pageTableLogical));
  95894. +
  95895. + /* Force the command queue to reload the next context. */
  95896. + command->currentContext = 0;
  95897. + }
  95898. +
  95899. + /* Get time until initialized. */
  95900. + gcmkPROFILE_QUERY(time, initTime);
  95901. +
  95902. + if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
  95903. + {
  95904. + /* Turn off the GPU power. */
  95905. + gcmkONERROR(
  95906. + gckOS_SetGPUPower(os,
  95907. + gcvCORE_VG,
  95908. + (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  95909. + : gcvTRUE,
  95910. + (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  95911. + : gcvTRUE));
  95912. +
  95913. + /* Save current hardware power and clock states. */
  95914. + Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  95915. + : gcvTRUE;
  95916. + Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  95917. + : gcvTRUE;
  95918. + }
  95919. +
  95920. + /* Get time until off. */
  95921. + gcmkPROFILE_QUERY(time, offTime);
  95922. +
  95923. + if (flag & gcvPOWER_FLAG_START)
  95924. + {
  95925. + }
  95926. +
  95927. + /* Get time until started. */
  95928. + gcmkPROFILE_QUERY(time, startTime);
  95929. +
  95930. + if (flag & gcvPOWER_FLAG_RELEASE)
  95931. + {
  95932. + /* Release the power management semaphore. */
  95933. + gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
  95934. + acquired = gcvFALSE;
  95935. + }
  95936. +
  95937. + /* Save the new power state. */
  95938. + Hardware->chipPowerState = State;
  95939. +
  95940. + if (global)
  95941. + {
  95942. + /* Save the new power state. */
  95943. + Hardware->chipPowerStateGlobal = State;
  95944. + }
  95945. +
  95946. + if (commitMutex)
  95947. + {
  95948. + /* Acquire the mutex. */
  95949. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  95950. + command->os,
  95951. + command->commitMutex
  95952. + ));
  95953. + }
  95954. +
  95955. +#if gcdPOWEROFF_TIMEOUT
  95956. + /* Reset power off time */
  95957. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  95958. +
  95959. + Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
  95960. +
  95961. + if (State == gcvPOWER_IDLE)
  95962. + {
  95963. + /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
  95964. + gcmkVERIFY_OK(gckOS_StartTimer(os,
  95965. + Hardware->powerOffTimer,
  95966. + Hardware->powerOffTimeout));
  95967. + }
  95968. + else
  95969. + {
  95970. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
  95971. +
  95972. + /* Cancel running timer when GPU enters ON or OFF. */
  95973. + gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
  95974. + }
  95975. +#endif
  95976. +
  95977. + /* Release the power mutex. */
  95978. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  95979. +
  95980. + /* Get total time. */
  95981. + gcmkPROFILE_QUERY(time, totalTime);
  95982. +#if gcdENABLE_PROFILING
  95983. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  95984. + "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
  95985. + freq, mutexTime, onTime, stallTime, stopTime);
  95986. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  95987. + " delay:%llu init:%llu off:%llu start:%llu total:%llu",
  95988. + delayTime, initTime, offTime, startTime, totalTime);
  95989. +#endif
  95990. +
  95991. + /* Success. */
  95992. + gcmkFOOTER_NO();
  95993. + return gcvSTATUS_OK;
  95994. +
  95995. +OnError:
  95996. +
  95997. + if (acquired)
  95998. + {
  95999. + /* Release semaphore. */
  96000. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
  96001. + command->powerSemaphore));
  96002. + }
  96003. +
  96004. + if (mutexAcquired)
  96005. + {
  96006. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  96007. + }
  96008. +
  96009. + if (commitMutex)
  96010. + {
  96011. + /* Acquire the mutex. */
  96012. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  96013. + command->os,
  96014. + command->commitMutex
  96015. + ));
  96016. + }
  96017. +
  96018. + /* Return the status. */
  96019. + gcmkFOOTER();
  96020. + return status;
  96021. +}
  96022. +
  96023. +/*******************************************************************************
  96024. +**
  96025. +** gckHARDWARE_QueryPowerManagementState
  96026. +**
  96027. +** Get GPU power state.
  96028. +**
  96029. +** INPUT:
  96030. +**
  96031. +** gckHARDWARE Harwdare
  96032. +** Pointer to an gckHARDWARE object.
  96033. +**
  96034. +** gceCHIPPOWERSTATE* State
  96035. +** Power State.
  96036. +**
  96037. +*/
  96038. +gceSTATUS
  96039. +gckVGHARDWARE_QueryPowerManagementState(
  96040. + IN gckVGHARDWARE Hardware,
  96041. + OUT gceCHIPPOWERSTATE* State
  96042. + )
  96043. +{
  96044. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  96045. +
  96046. + /* Verify the arguments. */
  96047. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  96048. + gcmkVERIFY_ARGUMENT(State != gcvNULL);
  96049. +
  96050. + /* Return the statue. */
  96051. + *State = Hardware->chipPowerState;
  96052. +
  96053. + /* Success. */
  96054. + gcmkFOOTER_ARG("*State=%d", *State);
  96055. + return gcvSTATUS_OK;
  96056. +}
  96057. +
  96058. +/*******************************************************************************
  96059. +**
  96060. +** gckVGHARDWARE_SetPowerManagement
  96061. +**
  96062. +** Configure GPU power management function.
  96063. +** Only used in driver initialization stage.
  96064. +**
  96065. +** INPUT:
  96066. +**
  96067. +** gckVGHARDWARE Harwdare
  96068. +** Pointer to an gckHARDWARE object.
  96069. +**
  96070. +** gctBOOL PowerManagement
  96071. +** Power Mangement State.
  96072. +**
  96073. +*/
  96074. +gceSTATUS
  96075. +gckVGHARDWARE_SetPowerManagement(
  96076. + IN gckVGHARDWARE Hardware,
  96077. + IN gctBOOL PowerManagement
  96078. + )
  96079. +{
  96080. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  96081. +
  96082. + /* Verify the arguments. */
  96083. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  96084. +
  96085. + Hardware->powerManagement = PowerManagement;
  96086. +
  96087. + /* Success. */
  96088. + gcmkFOOTER_NO();
  96089. + return gcvSTATUS_OK;
  96090. +}
  96091. +
  96092. +gceSTATUS
  96093. +gckVGHARDWARE_SetPowerOffTimeout(
  96094. + IN gckVGHARDWARE Hardware,
  96095. + IN gctUINT32 Timeout
  96096. + )
  96097. +{
  96098. + gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
  96099. +
  96100. +#if gcdPOWEROFF_TIMEOUT
  96101. + Hardware->powerOffTimeout = Timeout;
  96102. +#endif
  96103. +
  96104. + gcmkFOOTER_NO();
  96105. + return gcvSTATUS_OK;
  96106. +}
  96107. +
  96108. +
  96109. +gceSTATUS
  96110. +gckVGHARDWARE_QueryPowerOffTimeout(
  96111. + IN gckVGHARDWARE Hardware,
  96112. + OUT gctUINT32* Timeout
  96113. + )
  96114. +{
  96115. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  96116. +
  96117. +#if gcdPOWEROFF_TIMEOUT
  96118. + *Timeout = Hardware->powerOffTimeout;
  96119. +#endif
  96120. +
  96121. + gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
  96122. + return gcvSTATUS_OK;
  96123. +}
  96124. +
  96125. +gceSTATUS
  96126. +gckVGHARDWARE_QueryIdle(
  96127. + IN gckVGHARDWARE Hardware,
  96128. + OUT gctBOOL_PTR IsIdle
  96129. + )
  96130. +{
  96131. + gceSTATUS status;
  96132. + gctUINT32 idle;
  96133. +
  96134. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  96135. +
  96136. + /* Verify the arguments. */
  96137. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  96138. + gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL);
  96139. +
  96140. + /* We are idle when the power is not ON. */
  96141. + if (Hardware->chipPowerState != gcvPOWER_ON)
  96142. + {
  96143. + *IsIdle = gcvTRUE;
  96144. + }
  96145. +
  96146. + else
  96147. + {
  96148. + /* Read idle register. */
  96149. + gcmkONERROR(
  96150. + gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, 0x00004, &idle));
  96151. +
  96152. + /* Pipe must be idle. */
  96153. + if (((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) != 1)
  96154. + || ((((((gctUINT32) (idle)) >> (0 ? 8:8)) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) ) != 1)
  96155. + || ((((((gctUINT32) (idle)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) ) != 1)
  96156. + || ((((((gctUINT32) (idle)) >> (0 ? 10:10)) & ((gctUINT32) ((((1 ? 10:10) - (0 ? 10:10) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 10:10) - (0 ? 10:10) + 1)))))) ) != 1)
  96157. + || ((((((gctUINT32) (idle)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) ) != 1)
  96158. + )
  96159. + {
  96160. + /* Something is busy. */
  96161. + *IsIdle = gcvFALSE;
  96162. + }
  96163. +
  96164. + else
  96165. + {
  96166. + *IsIdle = gcvTRUE;
  96167. + }
  96168. + }
  96169. +
  96170. + /* Success. */
  96171. + gcmkFOOTER_NO();
  96172. + return gcvSTATUS_OK;
  96173. +
  96174. +OnError:
  96175. + /* Return the status. */
  96176. + gcmkFOOTER();
  96177. + return status;
  96178. +}
  96179. +#endif /* gcdENABLE_VG */
  96180. +
  96181. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h
  96182. --- linux-3.14.15/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h 1970-01-01 01:00:00.000000000 +0100
  96183. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h 2014-08-20 19:23:53.558845839 +0200
  96184. @@ -0,0 +1,75 @@
  96185. +/****************************************************************************
  96186. +*
  96187. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  96188. +*
  96189. +* This program is free software; you can redistribute it and/or modify
  96190. +* it under the terms of the GNU General Public License as published by
  96191. +* the Free Software Foundation; either version 2 of the license, or
  96192. +* (at your option) any later version.
  96193. +*
  96194. +* This program is distributed in the hope that it will be useful,
  96195. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  96196. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  96197. +* GNU General Public License for more details.
  96198. +*
  96199. +* You should have received a copy of the GNU General Public License
  96200. +* along with this program; if not write to the Free Software
  96201. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  96202. +*
  96203. +*****************************************************************************/
  96204. +
  96205. +
  96206. +#ifndef __gc_hal_kernel_hardware_vg_h_
  96207. +#define __gc_hal_kernel_hardware_vg_h_
  96208. +
  96209. +/* gckHARDWARE object. */
  96210. +struct _gckVGHARDWARE
  96211. +{
  96212. + /* Object. */
  96213. + gcsOBJECT object;
  96214. +
  96215. + /* Pointer to gckKERNEL object. */
  96216. + gckVGKERNEL kernel;
  96217. +
  96218. + /* Pointer to gckOS object. */
  96219. + gckOS os;
  96220. +
  96221. + /* Chip characteristics. */
  96222. + gceCHIPMODEL chipModel;
  96223. + gctUINT32 chipRevision;
  96224. + gctUINT32 chipFeatures;
  96225. + gctUINT32 chipMinorFeatures;
  96226. + gctUINT32 chipMinorFeatures2;
  96227. + gctBOOL allowFastClear;
  96228. +
  96229. + /* Features. */
  96230. + gctBOOL fe20;
  96231. + gctBOOL vg20;
  96232. + gctBOOL vg21;
  96233. +
  96234. + /* Event mask. */
  96235. + gctUINT32 eventMask;
  96236. +
  96237. + gctBOOL clockState;
  96238. + gctBOOL powerState;
  96239. + gctPOINTER powerMutex;
  96240. + gctUINT32 powerProcess;
  96241. + gctUINT32 powerThread;
  96242. + gceCHIPPOWERSTATE chipPowerState;
  96243. + gceCHIPPOWERSTATE chipPowerStateGlobal;
  96244. + gctISRMANAGERFUNC startIsr;
  96245. + gctISRMANAGERFUNC stopIsr;
  96246. + gctPOINTER isrContext;
  96247. + gctPOINTER pageTableDirty;
  96248. +
  96249. +#if gcdPOWEROFF_TIMEOUT
  96250. + gctUINT32 powerOffTime;
  96251. + gctUINT32 powerOffTimeout;
  96252. + gctPOINTER powerOffTimer;
  96253. +#endif
  96254. +
  96255. + gctBOOL powerManagement;
  96256. +};
  96257. +
  96258. +#endif /* __gc_hal_kernel_hardware_h_ */
  96259. +
  96260. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
  96261. --- linux-3.14.15/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c 1970-01-01 01:00:00.000000000 +0100
  96262. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c 2014-08-20 19:23:53.558845839 +0200
  96263. @@ -0,0 +1,1735 @@
  96264. +/****************************************************************************
  96265. +*
  96266. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  96267. +*
  96268. +* This program is free software; you can redistribute it and/or modify
  96269. +* it under the terms of the GNU General Public License as published by
  96270. +* the Free Software Foundation; either version 2 of the license, or
  96271. +* (at your option) any later version.
  96272. +*
  96273. +* This program is distributed in the hope that it will be useful,
  96274. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  96275. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  96276. +* GNU General Public License for more details.
  96277. +*
  96278. +* You should have received a copy of the GNU General Public License
  96279. +* along with this program; if not write to the Free Software
  96280. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  96281. +*
  96282. +*****************************************************************************/
  96283. +
  96284. +
  96285. +#include "gc_hal.h"
  96286. +#include "gc_hal_kernel.h"
  96287. +#include "gc_hal_kernel_context.h"
  96288. +#include "gc_hal_kernel_buffer.h"
  96289. +
  96290. +/******************************************************************************\
  96291. +******************************** Debugging Macro *******************************
  96292. +\******************************************************************************/
  96293. +
  96294. +/* Zone used for header/footer. */
  96295. +#define _GC_OBJ_ZONE gcvZONE_HARDWARE
  96296. +
  96297. +
  96298. +/******************************************************************************\
  96299. +************************** Context State Buffer Helpers ************************
  96300. +\******************************************************************************/
  96301. +
  96302. +#define _STATE(reg) \
  96303. + _State(\
  96304. + Context, index, \
  96305. + reg ## _Address >> 2, \
  96306. + reg ## _ResetValue, \
  96307. + reg ## _Count, \
  96308. + gcvFALSE, gcvFALSE \
  96309. + )
  96310. +
  96311. +#define _STATE_COUNT(reg, count) \
  96312. + _State(\
  96313. + Context, index, \
  96314. + reg ## _Address >> 2, \
  96315. + reg ## _ResetValue, \
  96316. + count, \
  96317. + gcvFALSE, gcvFALSE \
  96318. + )
  96319. +
  96320. +#define _STATE_COUNT_OFFSET(reg, offset, count) \
  96321. + _State(\
  96322. + Context, index, \
  96323. + (reg ## _Address >> 2) + offset, \
  96324. + reg ## _ResetValue, \
  96325. + count, \
  96326. + gcvFALSE, gcvFALSE \
  96327. + )
  96328. +
  96329. +#define _STATE_MIRROR_COUNT(reg, mirror, count) \
  96330. + _StateMirror(\
  96331. + Context, \
  96332. + reg ## _Address >> 2, \
  96333. + count, \
  96334. + mirror ## _Address >> 2 \
  96335. + )
  96336. +
  96337. +#define _STATE_HINT(reg) \
  96338. + _State(\
  96339. + Context, index, \
  96340. + reg ## _Address >> 2, \
  96341. + reg ## _ResetValue, \
  96342. + reg ## _Count, \
  96343. + gcvFALSE, gcvTRUE \
  96344. + )
  96345. +
  96346. +#define _STATE_HINT_BLOCK(reg, block, count) \
  96347. + _State(\
  96348. + Context, index, \
  96349. + (reg ## _Address >> 2) + (block << reg ## _BLK), \
  96350. + reg ## _ResetValue, \
  96351. + count, \
  96352. + gcvFALSE, gcvTRUE \
  96353. + )
  96354. +
  96355. +#define _STATE_X(reg) \
  96356. + _State(\
  96357. + Context, index, \
  96358. + reg ## _Address >> 2, \
  96359. + reg ## _ResetValue, \
  96360. + reg ## _Count, \
  96361. + gcvTRUE, gcvFALSE \
  96362. + )
  96363. +
  96364. +#define _CLOSE_RANGE() \
  96365. + _TerminateStateBlock(Context, index)
  96366. +
  96367. +#define _ENABLE(reg, field) \
  96368. + do \
  96369. + { \
  96370. + if (gcmVERIFYFIELDVALUE(data, reg, MASK_ ## field, ENABLED)) \
  96371. + { \
  96372. + enable |= gcmFIELDMASK(reg, field); \
  96373. + } \
  96374. + } \
  96375. + while (gcvFALSE)
  96376. +
  96377. +#define _BLOCK_COUNT(reg) \
  96378. + ((reg ## _Count) >> (reg ## _BLK))
  96379. +
  96380. +
  96381. +/******************************************************************************\
  96382. +*********************** Support Functions and Definitions **********************
  96383. +\******************************************************************************/
  96384. +
  96385. +#define gcdSTATE_MASK \
  96386. + (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 | 0xC0FFEE & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))))
  96387. +
  96388. +#if !defined(VIVANTE_NO_3D)
  96389. +static gctSIZE_T
  96390. +_TerminateStateBlock(
  96391. + IN gckCONTEXT Context,
  96392. + IN gctSIZE_T Index
  96393. + )
  96394. +{
  96395. + gctUINT32_PTR buffer;
  96396. + gctSIZE_T align;
  96397. +
  96398. + /* Determine if we need alignment. */
  96399. + align = (Index & 1) ? 1 : 0;
  96400. +
  96401. + /* Address correct index. */
  96402. + buffer = (Context->buffer == gcvNULL)
  96403. + ? gcvNULL
  96404. + : Context->buffer->logical;
  96405. +
  96406. + /* Flush the current state block; make sure no pairing with the states
  96407. + to follow happens. */
  96408. + if (align && (buffer != gcvNULL))
  96409. + {
  96410. + buffer[Index] = 0xDEADDEAD;
  96411. + }
  96412. +
  96413. + /* Reset last address. */
  96414. + Context->lastAddress = ~0U;
  96415. +
  96416. + /* Return alignment requirement. */
  96417. + return align;
  96418. +}
  96419. +#endif
  96420. +
  96421. +
  96422. +static gctSIZE_T
  96423. +_FlushPipe(
  96424. + IN gckCONTEXT Context,
  96425. + IN gctSIZE_T Index,
  96426. + IN gcePIPE_SELECT Pipe
  96427. + )
  96428. +{
  96429. + if (Context->buffer != gcvNULL)
  96430. + {
  96431. + gctUINT32_PTR buffer;
  96432. +
  96433. + /* Address correct index. */
  96434. + buffer = Context->buffer->logical + Index;
  96435. +
  96436. + /* Flush the current pipe. */
  96437. + *buffer++
  96438. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  96439. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  96440. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  96441. +
  96442. + *buffer++
  96443. + = (Pipe == gcvPIPE_2D)
  96444. + ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
  96445. + : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
  96446. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
  96447. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
  96448. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
  96449. +
  96450. + /* Semaphore from FE to PE. */
  96451. + *buffer++
  96452. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  96453. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  96454. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  96455. +
  96456. + *buffer++
  96457. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  96458. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  96459. +
  96460. + /* Stall from FE to PE. */
  96461. + *buffer++
  96462. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  96463. +
  96464. + *buffer
  96465. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  96466. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  96467. + }
  96468. +
  96469. + /* Flushing 3D pipe takes 6 slots. */
  96470. + return 6;
  96471. +}
  96472. +
  96473. +#if !defined(VIVANTE_NO_3D)
  96474. +static gctSIZE_T
  96475. +_SemaphoreStall(
  96476. + IN gckCONTEXT Context,
  96477. + IN gctSIZE_T Index
  96478. + )
  96479. +{
  96480. + if (Context->buffer != gcvNULL)
  96481. + {
  96482. + gctUINT32_PTR buffer;
  96483. +
  96484. + /* Address correct index. */
  96485. + buffer = Context->buffer->logical + Index;
  96486. +
  96487. + /* Semaphore from FE to PE. */
  96488. + *buffer++
  96489. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  96490. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  96491. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  96492. +
  96493. + *buffer++
  96494. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  96495. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  96496. +
  96497. + /* Stall from FE to PE. */
  96498. + *buffer++
  96499. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  96500. +
  96501. + *buffer
  96502. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  96503. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  96504. + }
  96505. +
  96506. + /* Semaphore/stall takes 4 slots. */
  96507. + return 4;
  96508. +}
  96509. +#endif
  96510. +
  96511. +static gctSIZE_T
  96512. +_SwitchPipe(
  96513. + IN gckCONTEXT Context,
  96514. + IN gctSIZE_T Index,
  96515. + IN gcePIPE_SELECT Pipe
  96516. + )
  96517. +{
  96518. + if (Context->buffer != gcvNULL)
  96519. + {
  96520. + gctUINT32_PTR buffer;
  96521. +
  96522. + /* Address correct index. */
  96523. + buffer = Context->buffer->logical + Index;
  96524. +
  96525. + /* LoadState(AQPipeSelect, 1), pipe. */
  96526. + *buffer++
  96527. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  96528. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  96529. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  96530. +
  96531. + *buffer
  96532. + = (Pipe == gcvPIPE_2D)
  96533. + ? 0x1
  96534. + : 0x0;
  96535. + }
  96536. +
  96537. + return 2;
  96538. +}
  96539. +
  96540. +#if !defined(VIVANTE_NO_3D)
  96541. +static gctSIZE_T
  96542. +_State(
  96543. + IN gckCONTEXT Context,
  96544. + IN gctSIZE_T Index,
  96545. + IN gctUINT32 Address,
  96546. + IN gctUINT32 Value,
  96547. + IN gctSIZE_T Size,
  96548. + IN gctBOOL FixedPoint,
  96549. + IN gctBOOL Hinted
  96550. + )
  96551. +{
  96552. + gctUINT32_PTR buffer;
  96553. + gctSIZE_T align, i;
  96554. +
  96555. + /* Determine if we need alignment. */
  96556. + align = (Index & 1) ? 1 : 0;
  96557. +
  96558. + /* Address correct index. */
  96559. + buffer = (Context->buffer == gcvNULL)
  96560. + ? gcvNULL
  96561. + : Context->buffer->logical;
  96562. +
  96563. + if ((buffer == gcvNULL) && (Address + Size > Context->stateCount))
  96564. + {
  96565. + /* Determine maximum state. */
  96566. + Context->stateCount = Address + Size;
  96567. + }
  96568. +
  96569. + /* Do we need a new entry? */
  96570. + if ((Address != Context->lastAddress) || (FixedPoint != Context->lastFixed))
  96571. + {
  96572. + if (buffer != gcvNULL)
  96573. + {
  96574. + if (align)
  96575. + {
  96576. + /* Add filler. */
  96577. + buffer[Index++] = 0xDEADDEAD;
  96578. + }
  96579. +
  96580. + /* LoadState(Address, Count). */
  96581. + gcmkASSERT((Index & 1) == 0);
  96582. +
  96583. + if (FixedPoint)
  96584. + {
  96585. + buffer[Index]
  96586. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  96587. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
  96588. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  96589. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  96590. + }
  96591. + else
  96592. + {
  96593. + buffer[Index]
  96594. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  96595. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
  96596. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  96597. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  96598. + }
  96599. +
  96600. + /* Walk all the states. */
  96601. + for (i = 0; i < Size; i += 1)
  96602. + {
  96603. + /* Set state to uninitialized value. */
  96604. + buffer[Index + 1 + i] = Value;
  96605. +
  96606. + /* Set index in state mapping table. */
  96607. + Context->map[Address + i].index = Index + 1 + i;
  96608. +
  96609. +#if gcdSECURE_USER
  96610. + /* Save hint. */
  96611. + if (Context->hint != gcvNULL)
  96612. + {
  96613. + Context->hint[Address + i] = Hinted;
  96614. + }
  96615. +#endif
  96616. + }
  96617. + }
  96618. +
  96619. + /* Save information for this LoadState. */
  96620. + Context->lastIndex = Index;
  96621. + Context->lastAddress = Address + Size;
  96622. + Context->lastSize = Size;
  96623. + Context->lastFixed = FixedPoint;
  96624. +
  96625. + /* Return size for load state. */
  96626. + return align + 1 + Size;
  96627. + }
  96628. +
  96629. + /* Append this state to the previous one. */
  96630. + if (buffer != gcvNULL)
  96631. + {
  96632. + /* Update last load state. */
  96633. + buffer[Context->lastIndex] =
  96634. + ((((gctUINT32) (buffer[Context->lastIndex])) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (Context->lastSize + Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  96635. +
  96636. + /* Walk all the states. */
  96637. + for (i = 0; i < Size; i += 1)
  96638. + {
  96639. + /* Set state to uninitialized value. */
  96640. + buffer[Index + i] = Value;
  96641. +
  96642. + /* Set index in state mapping table. */
  96643. + Context->map[Address + i].index = Index + i;
  96644. +
  96645. +#if gcdSECURE_USER
  96646. + /* Save hint. */
  96647. + if (Context->hint != gcvNULL)
  96648. + {
  96649. + Context->hint[Address + i] = Hinted;
  96650. + }
  96651. +#endif
  96652. + }
  96653. + }
  96654. +
  96655. + /* Update last address and size. */
  96656. + Context->lastAddress += Size;
  96657. + Context->lastSize += Size;
  96658. +
  96659. + /* Return number of slots required. */
  96660. + return Size;
  96661. +}
  96662. +
  96663. +static gctSIZE_T
  96664. +_StateMirror(
  96665. + IN gckCONTEXT Context,
  96666. + IN gctUINT32 Address,
  96667. + IN gctSIZE_T Size,
  96668. + IN gctUINT32 AddressMirror
  96669. + )
  96670. +{
  96671. + gctSIZE_T i;
  96672. +
  96673. + /* Process when buffer is set. */
  96674. + if (Context->buffer != gcvNULL)
  96675. + {
  96676. + /* Walk all states. */
  96677. + for (i = 0; i < Size; i++)
  96678. + {
  96679. + /* Copy the mapping address. */
  96680. + Context->map[Address + i].index =
  96681. + Context->map[AddressMirror + i].index;
  96682. + }
  96683. + }
  96684. +
  96685. + /* Return the number of required maps. */
  96686. + return Size;
  96687. +}
  96688. +#endif
  96689. +
  96690. +static gceSTATUS
  96691. +_InitializeContextBuffer(
  96692. + IN gckCONTEXT Context
  96693. + )
  96694. +{
  96695. + gctUINT32_PTR buffer;
  96696. + gctSIZE_T index;
  96697. +
  96698. +#if !defined(VIVANTE_NO_3D)
  96699. + gctUINT i;
  96700. + gctUINT vertexUniforms, fragmentUniforms;
  96701. + gctUINT fe2vsCount;
  96702. + gctBOOL halti0;
  96703. +#endif
  96704. +
  96705. + /* Reset the buffer index. */
  96706. + index = 0;
  96707. +
  96708. + /* Reset the last state address. */
  96709. + Context->lastAddress = ~0U;
  96710. +
  96711. + /* Get the buffer pointer. */
  96712. + buffer = (Context->buffer == gcvNULL)
  96713. + ? gcvNULL
  96714. + : Context->buffer->logical;
  96715. +
  96716. +
  96717. + /**************************************************************************/
  96718. + /* Build 2D states. *******************************************************/
  96719. +
  96720. +
  96721. +#if !defined(VIVANTE_NO_3D)
  96722. + /**************************************************************************/
  96723. + /* Build 3D states. *******************************************************/
  96724. + halti0 = (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures1)) >> (0 ? 23:23)) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) );
  96725. +
  96726. + /* Query shader support. */
  96727. + gcmkVERIFY_OK(gckHARDWARE_QueryShaderCaps(
  96728. + Context->hardware, &vertexUniforms, &fragmentUniforms, gcvNULL));
  96729. +
  96730. + /* Store the 3D entry index. */
  96731. + Context->entryOffset3D = index * gcmSIZEOF(gctUINT32);
  96732. +
  96733. + /* Flush 2D pipe. */
  96734. + index += _FlushPipe(Context, index, gcvPIPE_2D);
  96735. +
  96736. + /* Switch to 3D pipe. */
  96737. + index += _SwitchPipe(Context, index, gcvPIPE_3D);
  96738. +
  96739. + /* Current context pointer. */
  96740. +#if gcdDEBUG
  96741. + index += _State(Context, index, 0x03850 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96742. +#endif
  96743. +
  96744. + index += _FlushPipe(Context, index, gcvPIPE_3D);
  96745. +
  96746. + /* Global states. */
  96747. + index += _State(Context, index, 0x03814 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
  96748. + index += _State(Context, index, 0x03818 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96749. + index += _State(Context, index, 0x0381C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96750. + index += _State(Context, index, 0x03820 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96751. + index += _State(Context, index, 0x03828 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96752. + index += _State(Context, index, 0x0382C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96753. + index += _State(Context, index, 0x03834 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96754. + index += _State(Context, index, 0x03838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96755. + index += _State(Context, index, 0x0384C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96756. +
  96757. + /* Front End states. */
  96758. + fe2vsCount = 12;
  96759. + if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures1)) >> (0 ? 23:23)) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) ))
  96760. + {
  96761. + fe2vsCount = 16;
  96762. + }
  96763. + index += _State(Context, index, 0x00600 >> 2, 0x00000000, fe2vsCount, gcvFALSE, gcvFALSE);
  96764. + index += _CLOSE_RANGE();
  96765. +
  96766. + index += _State(Context, index, 0x00644 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96767. + index += _State(Context, index, 0x00648 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96768. + index += _State(Context, index, 0x0064C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96769. + index += _State(Context, index, 0x00650 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96770. + index += _State(Context, index, 0x00680 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
  96771. + index += _State(Context, index, 0x006A0 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
  96772. + index += _State(Context, index, 0x00670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96773. + index += _State(Context, index, 0x00678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96774. + index += _State(Context, index, 0x0067C >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
  96775. + index += _State(Context, index, 0x006C0 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  96776. + index += _State(Context, index, 0x00700 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  96777. + index += _State(Context, index, 0x00740 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  96778. + index += _State(Context, index, 0x00780 >> 2, 0x3F800000, 16, gcvFALSE, gcvFALSE);
  96779. +
  96780. + /* Vertex Shader states. */
  96781. + index += _State(Context, index, 0x00800 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96782. + index += _State(Context, index, 0x00804 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96783. + index += _State(Context, index, 0x00808 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96784. + index += _State(Context, index, 0x0080C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96785. + index += _State(Context, index, 0x00810 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  96786. + index += _State(Context, index, 0x00820 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  96787. + index += _State(Context, index, 0x00830 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96788. + index += _State(Context, index, 0x00838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96789. + if (Context->hardware->identity.instructionCount <= 256)
  96790. + {
  96791. + index += _State(Context, index, 0x04000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
  96792. + }
  96793. +
  96794. + index += _CLOSE_RANGE();
  96795. + index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE);
  96796. +
  96797. + /* Primitive Assembly states. */
  96798. + index += _State(Context, index, 0x00A00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96799. + index += _State(Context, index, 0x00A04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96800. + index += _State(Context, index, 0x00A08 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96801. + index += _State(Context, index, 0x00A0C >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96802. + index += _State(Context, index, 0x00A10 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96803. + index += _State(Context, index, 0x00A14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96804. + index += _State(Context, index, 0x00A18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96805. + index += _State(Context, index, 0x00A1C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96806. + index += _State(Context, index, 0x00A28 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96807. + index += _State(Context, index, 0x00A2C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96808. + index += _State(Context, index, 0x00A30 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96809. + index += _State(Context, index, 0x00A40 >> 2, 0x00000000, 10, gcvFALSE, gcvFALSE);
  96810. + index += _State(Context, index, 0x00A34 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96811. + index += _State(Context, index, 0x00A38 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96812. + index += _State(Context, index, 0x00A3C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96813. + index += _State(Context, index, 0x00A80 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96814. + index += _State(Context, index, 0x00A84 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96815. + index += _State(Context, index, 0x00A8C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96816. +
  96817. + /* Setup states. */
  96818. + index += _State(Context, index, 0x00C00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96819. + index += _State(Context, index, 0x00C04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96820. + index += _State(Context, index, 0x00C08 >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
  96821. + index += _State(Context, index, 0x00C0C >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
  96822. + index += _State(Context, index, 0x00C10 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96823. + index += _State(Context, index, 0x00C14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96824. + index += _State(Context, index, 0x00C18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96825. + index += _State(Context, index, 0x00C1C >> 2, 0x42000000, 1, gcvFALSE, gcvFALSE);
  96826. + index += _State(Context, index, 0x00C20 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96827. + index += _State(Context, index, 0x00C24 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96828. +
  96829. + /* Raster states. */
  96830. + index += _State(Context, index, 0x00E00 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
  96831. + index += _State(Context, index, 0x00E10 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  96832. + index += _State(Context, index, 0x00E04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96833. + index += _State(Context, index, 0x00E40 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  96834. + index += _State(Context, index, 0x00E08 >> 2, 0x00000031, 1, gcvFALSE, gcvFALSE);
  96835. +
  96836. + /* Pixel Shader states. */
  96837. + index += _State(Context, index, 0x01000 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96838. + index += _State(Context, index, 0x01004 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96839. + index += _State(Context, index, 0x01008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96840. + index += _State(Context, index, 0x0100C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96841. + index += _State(Context, index, 0x01010 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96842. + index += _State(Context, index, 0x01018 >> 2, 0x01000000, 1, gcvFALSE, gcvFALSE);
  96843. + if (Context->hardware->identity.instructionCount <= 256)
  96844. + {
  96845. + index += _State(Context, index, 0x06000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
  96846. + }
  96847. +
  96848. + index += _CLOSE_RANGE();
  96849. + index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE);
  96850. +
  96851. + /* Texture states. */
  96852. + index += _State(Context, index, 0x02000 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96853. + index += _State(Context, index, 0x02040 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96854. + index += _State(Context, index, 0x02080 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96855. + index += _State(Context, index, 0x020C0 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96856. + index += _State(Context, index, 0x02100 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96857. + index += _State(Context, index, 0x02140 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96858. + index += _State(Context, index, 0x02180 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96859. + index += _State(Context, index, 0x021C0 >> 2, 0x00321000, 12, gcvFALSE, gcvFALSE);
  96860. + index += _State(Context, index, 0x02200 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96861. + index += _State(Context, index, 0x02240 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96862. + index += _State(Context, index, (0x02400 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96863. + index += _State(Context, index, (0x02440 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96864. + index += _State(Context, index, (0x02480 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96865. + index += _State(Context, index, (0x024C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96866. + index += _State(Context, index, (0x02500 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96867. + index += _State(Context, index, (0x02540 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96868. + index += _State(Context, index, (0x02580 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96869. + index += _State(Context, index, (0x025C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96870. + index += _State(Context, index, (0x02600 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96871. + index += _State(Context, index, (0x02640 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96872. + index += _State(Context, index, (0x02680 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96873. + index += _State(Context, index, (0x026C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96874. + index += _State(Context, index, (0x02700 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96875. + index += _State(Context, index, (0x02740 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96876. + index += _CLOSE_RANGE();
  96877. +
  96878. + if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures2)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) ))
  96879. + {
  96880. + gctUINT texBlockCount;
  96881. +
  96882. + /* New texture block. */
  96883. + index += _State(Context, index, 0x10000 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96884. + index += _State(Context, index, 0x10080 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96885. + index += _State(Context, index, 0x10100 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96886. + index += _State(Context, index, 0x10180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96887. + index += _State(Context, index, 0x10200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96888. + index += _State(Context, index, 0x10280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96889. + for (i = 0; i < 256 / 16; i += 1)
  96890. + {
  96891. + index += _State(Context, index, (0x02C00 >> 2) + i * 16, 0x00000000, 14, gcvFALSE, gcvFALSE);
  96892. + }
  96893. + index += _State(Context, index, 0x10300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96894. + index += _State(Context, index, 0x10380 >> 2, 0x00321000, 32, gcvFALSE, gcvFALSE);
  96895. + index += _State(Context, index, 0x10400 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96896. + index += _State(Context, index, 0x10480 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96897. +
  96898. + if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures2)) >> (0 ? 15:15)) & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1)))))) ))
  96899. + {
  96900. + index += _State(Context, index, 0x12000 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
  96901. + index += _State(Context, index, 0x12400 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
  96902. + }
  96903. +
  96904. + if ((Context->hardware->identity.chipModel == gcv2000)
  96905. + && (Context->hardware->identity.chipRevision == 0x5108))
  96906. + {
  96907. + texBlockCount = 12;
  96908. + }
  96909. + else
  96910. + {
  96911. + texBlockCount = ((512) >> (4));
  96912. + }
  96913. + for (i = 0; i < texBlockCount; i += 1)
  96914. + {
  96915. + index += _State(Context, index, (0x10800 >> 2) + (i << 4), 0x00000000, 14, gcvFALSE, gcvTRUE);
  96916. + }
  96917. + }
  96918. +
  96919. + /* YUV. */
  96920. + index += _State(Context, index, 0x01678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96921. + index += _State(Context, index, 0x0167C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96922. + index += _State(Context, index, 0x01680 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96923. + index += _State(Context, index, 0x01684 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96924. + index += _State(Context, index, 0x01688 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96925. + index += _State(Context, index, 0x0168C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96926. + index += _State(Context, index, 0x01690 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96927. + index += _State(Context, index, 0x01694 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96928. + index += _State(Context, index, 0x01698 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96929. + index += _State(Context, index, 0x0169C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96930. + index += _CLOSE_RANGE();
  96931. +
  96932. + /* Thread walker states. */
  96933. + index += _State(Context, index, 0x00900 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96934. + index += _State(Context, index, 0x00904 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96935. + index += _State(Context, index, 0x00908 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96936. + index += _State(Context, index, 0x0090C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96937. + index += _State(Context, index, 0x00910 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96938. + index += _State(Context, index, 0x00914 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96939. + index += _State(Context, index, 0x00918 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96940. + index += _State(Context, index, 0x0091C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96941. + index += _State(Context, index, 0x00924 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96942. + index += _CLOSE_RANGE();
  96943. +
  96944. + if (Context->hardware->identity.instructionCount > 1024)
  96945. + {
  96946. + /* New Shader instruction memory. */
  96947. + index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96948. + index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
  96949. + index += _State(Context, index, 0x00860 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96950. + index += _CLOSE_RANGE();
  96951. +
  96952. + for (i = 0;
  96953. + i < Context->hardware->identity.instructionCount << 2;
  96954. + i += 256 << 2
  96955. + )
  96956. + {
  96957. + index += _State(Context, index, (0x20000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
  96958. + index += _CLOSE_RANGE();
  96959. + }
  96960. + }
  96961. + else if (Context->hardware->identity.instructionCount > 256)
  96962. + {
  96963. + /* New Shader instruction memory. */
  96964. + index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96965. + index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
  96966. + index += _CLOSE_RANGE();
  96967. +
  96968. + /* VX instruction memory. */
  96969. + for (i = 0;
  96970. + i < Context->hardware->identity.instructionCount << 2;
  96971. + i += 256 << 2
  96972. + )
  96973. + {
  96974. + index += _State(Context, index, (0x0C000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
  96975. + index += _CLOSE_RANGE();
  96976. + }
  96977. +
  96978. + _StateMirror(Context, 0x08000 >> 2, Context->hardware->identity.instructionCount << 2 , 0x0C000 >> 2);
  96979. + }
  96980. +
  96981. + /* Store the index of the "XD" entry. */
  96982. + Context->entryOffsetXDFrom3D = index * gcmSIZEOF(gctUINT32);
  96983. +
  96984. +
  96985. + /* Pixel Engine states. */
  96986. + index += _State(Context, index, 0x01400 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96987. + index += _State(Context, index, 0x01404 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96988. + index += _State(Context, index, 0x01408 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96989. + index += _State(Context, index, 0x0140C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96990. + index += _State(Context, index, 0x01414 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96991. + index += _State(Context, index, 0x01418 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96992. + index += _State(Context, index, 0x0141C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96993. + index += _State(Context, index, 0x01420 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96994. + index += _State(Context, index, 0x01424 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96995. + index += _State(Context, index, 0x01428 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96996. + index += _State(Context, index, 0x0142C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96997. + index += _State(Context, index, 0x01434 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96998. + index += _State(Context, index, 0x01454 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96999. + index += _State(Context, index, 0x01458 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97000. + index += _State(Context, index, 0x0145C >> 2, 0x00000010, 1, gcvFALSE, gcvFALSE);
  97001. + index += _State(Context, index, 0x014A0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97002. + index += _State(Context, index, 0x014A8 >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
  97003. + index += _State(Context, index, 0x014AC >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
  97004. + index += _State(Context, index, 0x014B0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97005. + index += _State(Context, index, 0x014B4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97006. + index += _State(Context, index, 0x014A4 >> 2, 0x000E400C, 1, gcvFALSE, gcvFALSE);
  97007. + index += _State(Context, index, 0x01580 >> 2, 0x00000000, 3, gcvFALSE, gcvFALSE);
  97008. + index += _State(Context, index, 0x014B8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97009. +
  97010. + /* Composition states. */
  97011. + index += _State(Context, index, 0x03008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97012. +
  97013. + if (Context->hardware->identity.pixelPipes == 1)
  97014. + {
  97015. + index += _State(Context, index, 0x01460 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
  97016. +
  97017. + index += _State(Context, index, 0x01430 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97018. + index += _State(Context, index, 0x01410 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97019. + }
  97020. + else
  97021. + {
  97022. + index += _State(Context, index, (0x01460 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  97023. +
  97024. + for (i = 0; i < 2; i++)
  97025. + {
  97026. + index += _State(Context, index, (0x01500 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  97027. + }
  97028. + }
  97029. +
  97030. + if (Context->hardware->identity.pixelPipes > 1 || halti0)
  97031. + {
  97032. + index += _State(Context, index, (0x01480 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  97033. + }
  97034. +
  97035. + /* Resolve states. */
  97036. + index += _State(Context, index, 0x01604 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97037. + index += _State(Context, index, 0x01608 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97038. + index += _State(Context, index, 0x0160C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97039. + index += _State(Context, index, 0x01610 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97040. + index += _State(Context, index, 0x01614 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97041. + index += _State(Context, index, 0x01620 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97042. + index += _State(Context, index, 0x01630 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
  97043. + index += _State(Context, index, 0x01640 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  97044. + index += _State(Context, index, 0x0163C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97045. + index += _State(Context, index, 0x016A0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97046. + index += _State(Context, index, 0x016B4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97047. + index += _CLOSE_RANGE();
  97048. +
  97049. + if (Context->hardware->identity.pixelPipes > 1)
  97050. + {
  97051. + index += _State(Context, index, (0x016C0 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  97052. +
  97053. + index += _State(Context, index, (0x016E0 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  97054. +
  97055. + index += _State(Context, index, 0x01700 >> 2, 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvFALSE);
  97056. + }
  97057. +
  97058. + /* Tile status. */
  97059. + index += _State(Context, index, 0x01654 >> 2, 0x00200000, 1, gcvFALSE, gcvFALSE);
  97060. +
  97061. + index += _CLOSE_RANGE();
  97062. + index += _State(Context, index, 0x01658 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97063. + index += _State(Context, index, 0x0165C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97064. + index += _State(Context, index, 0x01660 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97065. + index += _State(Context, index, 0x01664 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97066. + index += _State(Context, index, 0x01668 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97067. + index += _State(Context, index, 0x0166C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97068. + index += _State(Context, index, 0x01670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97069. + index += _State(Context, index, 0x01674 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97070. + index += _State(Context, index, 0x016A4 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97071. + index += _State(Context, index, 0x016AC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97072. + index += _State(Context, index, 0x016A8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97073. + index += _State(Context, index, 0x01720 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
  97074. + index += _State(Context, index, 0x01740 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
  97075. + index += _State(Context, index, 0x01760 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
  97076. + index += _CLOSE_RANGE();
  97077. +
  97078. + /* Semaphore/stall. */
  97079. + index += _SemaphoreStall(Context, index);
  97080. +#endif
  97081. +
  97082. + /**************************************************************************/
  97083. + /* Link to another address. ***********************************************/
  97084. +
  97085. + Context->linkIndex3D = index;
  97086. +
  97087. + if (buffer != gcvNULL)
  97088. + {
  97089. + buffer[index + 0]
  97090. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  97091. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  97092. +
  97093. + buffer[index + 1]
  97094. + = 0;
  97095. + }
  97096. +
  97097. + index += 2;
  97098. +
  97099. + /* Store the end of the context buffer. */
  97100. + Context->bufferSize = index * gcmSIZEOF(gctUINT32);
  97101. +
  97102. +
  97103. + /**************************************************************************/
  97104. + /* Pipe switch for the case where neither 2D nor 3D are used. *************/
  97105. +
  97106. + /* Store the 3D entry index. */
  97107. + Context->entryOffsetXDFrom2D = index * gcmSIZEOF(gctUINT32);
  97108. +
  97109. + /* Flush 2D pipe. */
  97110. + index += _FlushPipe(Context, index, gcvPIPE_2D);
  97111. +
  97112. + /* Switch to 3D pipe. */
  97113. + index += _SwitchPipe(Context, index, gcvPIPE_3D);
  97114. +
  97115. + /* Store the location of the link. */
  97116. + Context->linkIndexXD = index;
  97117. +
  97118. + if (buffer != gcvNULL)
  97119. + {
  97120. + buffer[index + 0]
  97121. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  97122. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  97123. +
  97124. + buffer[index + 1]
  97125. + = 0;
  97126. + }
  97127. +
  97128. + index += 2;
  97129. +
  97130. +
  97131. + /**************************************************************************/
  97132. + /* Save size for buffer. **************************************************/
  97133. +
  97134. + Context->totalSize = index * gcmSIZEOF(gctUINT32);
  97135. +
  97136. +
  97137. + /* Success. */
  97138. + return gcvSTATUS_OK;
  97139. +}
  97140. +
  97141. +static gceSTATUS
  97142. +_DestroyContext(
  97143. + IN gckCONTEXT Context
  97144. + )
  97145. +{
  97146. + gceSTATUS status = gcvSTATUS_OK;
  97147. +
  97148. + if (Context != gcvNULL)
  97149. + {
  97150. + gcsCONTEXT_PTR bufferHead;
  97151. +
  97152. + /* Free context buffers. */
  97153. + for (bufferHead = Context->buffer; Context->buffer != gcvNULL;)
  97154. + {
  97155. + /* Get a shortcut to the current buffer. */
  97156. + gcsCONTEXT_PTR buffer = Context->buffer;
  97157. +
  97158. + /* Get the next buffer. */
  97159. + gcsCONTEXT_PTR next = buffer->next;
  97160. +
  97161. + /* Last item? */
  97162. + if (next == bufferHead)
  97163. + {
  97164. + next = gcvNULL;
  97165. + }
  97166. +
  97167. + /* Destroy the signal. */
  97168. + if (buffer->signal != gcvNULL)
  97169. + {
  97170. + gcmkONERROR(gckOS_DestroySignal(
  97171. + Context->os, buffer->signal
  97172. + ));
  97173. +
  97174. + buffer->signal = gcvNULL;
  97175. + }
  97176. +
  97177. + /* Free state delta map. */
  97178. + if (buffer->logical != gcvNULL)
  97179. + {
  97180. +#if gcdVIRTUAL_COMMAND_BUFFER
  97181. + gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer(
  97182. + Context->hardware->kernel->eventObj,
  97183. + Context->totalSize,
  97184. + buffer->physical,
  97185. + buffer->logical,
  97186. + gcvKERNEL_PIXEL
  97187. + ));
  97188. +
  97189. +#else
  97190. + gcmkONERROR(gckEVENT_FreeContiguousMemory(
  97191. + Context->hardware->kernel->eventObj,
  97192. + Context->totalSize,
  97193. + buffer->physical,
  97194. + buffer->logical,
  97195. + gcvKERNEL_PIXEL
  97196. + ));
  97197. +#endif
  97198. +
  97199. + buffer->logical = gcvNULL;
  97200. + }
  97201. +
  97202. + /* Free context buffer. */
  97203. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, buffer));
  97204. +
  97205. + /* Remove from the list. */
  97206. + Context->buffer = next;
  97207. + }
  97208. +
  97209. +#if gcdSECURE_USER
  97210. + /* Free the hint array. */
  97211. + if (Context->hint != gcvNULL)
  97212. + {
  97213. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->hint));
  97214. + }
  97215. +#endif
  97216. + /* Free record array copy. */
  97217. + if (Context->recordArray != gcvNULL)
  97218. + {
  97219. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->recordArray));
  97220. + }
  97221. +
  97222. + /* Free the state mapping. */
  97223. + if (Context->map != gcvNULL)
  97224. + {
  97225. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->map));
  97226. + }
  97227. +
  97228. + /* Mark the gckCONTEXT object as unknown. */
  97229. + Context->object.type = gcvOBJ_UNKNOWN;
  97230. +
  97231. + /* Free the gckCONTEXT object. */
  97232. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context));
  97233. + }
  97234. +
  97235. +OnError:
  97236. + return status;
  97237. +}
  97238. +
  97239. +
  97240. +/******************************************************************************\
  97241. +**************************** Context Management API ****************************
  97242. +\******************************************************************************/
  97243. +
  97244. +/******************************************************************************\
  97245. +**
  97246. +** gckCONTEXT_Construct
  97247. +**
  97248. +** Construct a new gckCONTEXT object.
  97249. +**
  97250. +** INPUT:
  97251. +**
  97252. +** gckOS Os
  97253. +** Pointer to gckOS object.
  97254. +**
  97255. +** gctUINT32 ProcessID
  97256. +** Current process ID.
  97257. +**
  97258. +** gckHARDWARE Hardware
  97259. +** Pointer to gckHARDWARE object.
  97260. +**
  97261. +** OUTPUT:
  97262. +**
  97263. +** gckCONTEXT * Context
  97264. +** Pointer to a variable thet will receive the gckCONTEXT object
  97265. +** pointer.
  97266. +*/
  97267. +gceSTATUS
  97268. +gckCONTEXT_Construct(
  97269. + IN gckOS Os,
  97270. + IN gckHARDWARE Hardware,
  97271. + IN gctUINT32 ProcessID,
  97272. + OUT gckCONTEXT * Context
  97273. + )
  97274. +{
  97275. + gceSTATUS status;
  97276. + gckCONTEXT context = gcvNULL;
  97277. + gctSIZE_T allocationSize;
  97278. + gctUINT i;
  97279. + gctPOINTER pointer = gcvNULL;
  97280. +
  97281. + gcmkHEADER_ARG("Os=0x%08X Hardware=0x%08X", Os, Hardware);
  97282. +
  97283. + /* Verify the arguments. */
  97284. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  97285. + gcmkVERIFY_ARGUMENT(Context != gcvNULL);
  97286. +
  97287. +
  97288. + /**************************************************************************/
  97289. + /* Allocate and initialize basic fields of gckCONTEXT. ********************/
  97290. +
  97291. + /* The context object size. */
  97292. + allocationSize = gcmSIZEOF(struct _gckCONTEXT);
  97293. +
  97294. + /* Allocate the object. */
  97295. + gcmkONERROR(gckOS_Allocate(
  97296. + Os, allocationSize, &pointer
  97297. + ));
  97298. +
  97299. + context = pointer;
  97300. +
  97301. + /* Reset the entire object. */
  97302. + gcmkONERROR(gckOS_ZeroMemory(context, allocationSize));
  97303. +
  97304. + /* Initialize the gckCONTEXT object. */
  97305. + context->object.type = gcvOBJ_CONTEXT;
  97306. + context->os = Os;
  97307. + context->hardware = Hardware;
  97308. +
  97309. +
  97310. +#if defined(VIVANTE_NO_3D)
  97311. + context->entryPipe = gcvPIPE_2D;
  97312. + context->exitPipe = gcvPIPE_2D;
  97313. +#elif gcdCMD_NO_2D_CONTEXT
  97314. + context->entryPipe = gcvPIPE_3D;
  97315. + context->exitPipe = gcvPIPE_3D;
  97316. +#else
  97317. + context->entryPipe
  97318. + = (((((gctUINT32) (context->hardware->identity.chipFeatures)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) )
  97319. + ? gcvPIPE_2D
  97320. + : gcvPIPE_3D;
  97321. + context->exitPipe = gcvPIPE_3D;
  97322. +#endif
  97323. +
  97324. + /* Get the command buffer requirements. */
  97325. + gcmkONERROR(gckHARDWARE_QueryCommandBuffer(
  97326. + Hardware,
  97327. + &context->alignment,
  97328. + &context->reservedHead,
  97329. + &context->reservedTail
  97330. + ));
  97331. +
  97332. + /* Mark the context as dirty to force loading of the entire state table
  97333. + the first time. */
  97334. + context->dirty = gcvTRUE;
  97335. +
  97336. +
  97337. + /**************************************************************************/
  97338. + /* Get the size of the context buffer. ************************************/
  97339. +
  97340. + gcmkONERROR(_InitializeContextBuffer(context));
  97341. +
  97342. +
  97343. + /**************************************************************************/
  97344. + /* Compute the size of the record array. **********************************/
  97345. +
  97346. + context->recordArraySize
  97347. + = gcmSIZEOF(gcsSTATE_DELTA_RECORD) * context->stateCount;
  97348. +
  97349. +
  97350. + if (context->stateCount > 0)
  97351. + {
  97352. + /**************************************************************************/
  97353. + /* Allocate and reset the state mapping table. ****************************/
  97354. +
  97355. + /* Allocate the state mapping table. */
  97356. + gcmkONERROR(gckOS_Allocate(
  97357. + Os,
  97358. + gcmSIZEOF(gcsSTATE_MAP) * context->stateCount,
  97359. + &pointer
  97360. + ));
  97361. +
  97362. + context->map = pointer;
  97363. +
  97364. + /* Zero the state mapping table. */
  97365. + gcmkONERROR(gckOS_ZeroMemory(
  97366. + context->map, gcmSIZEOF(gcsSTATE_MAP) * context->stateCount
  97367. + ));
  97368. +
  97369. +
  97370. + /**************************************************************************/
  97371. + /* Allocate the hint array. ***********************************************/
  97372. +
  97373. +#if gcdSECURE_USER
  97374. + /* Allocate hints. */
  97375. + gcmkONERROR(gckOS_Allocate(
  97376. + Os,
  97377. + gcmSIZEOF(gctBOOL) * context->stateCount,
  97378. + &pointer
  97379. + ));
  97380. +
  97381. + context->hint = pointer;
  97382. +#endif
  97383. + }
  97384. +
  97385. + /**************************************************************************/
  97386. + /* Allocate the context and state delta buffers. **************************/
  97387. +
  97388. + for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i += 1)
  97389. + {
  97390. + /* Allocate a context buffer. */
  97391. + gcsCONTEXT_PTR buffer;
  97392. +
  97393. + /* Allocate the context buffer structure. */
  97394. + gcmkONERROR(gckOS_Allocate(
  97395. + Os,
  97396. + gcmSIZEOF(gcsCONTEXT),
  97397. + &pointer
  97398. + ));
  97399. +
  97400. + buffer = pointer;
  97401. +
  97402. + /* Reset the context buffer structure. */
  97403. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  97404. + buffer, gcmSIZEOF(gcsCONTEXT)
  97405. + ));
  97406. +
  97407. + /* Append to the list. */
  97408. + if (context->buffer == gcvNULL)
  97409. + {
  97410. + buffer->next = buffer;
  97411. + context->buffer = buffer;
  97412. + }
  97413. + else
  97414. + {
  97415. + buffer->next = context->buffer->next;
  97416. + context->buffer->next = buffer;
  97417. + }
  97418. +
  97419. + /* Set the number of delta in the order of creation. */
  97420. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  97421. + buffer->num = i;
  97422. +#endif
  97423. +
  97424. + /* Create the busy signal. */
  97425. + gcmkONERROR(gckOS_CreateSignal(
  97426. + Os, gcvFALSE, &buffer->signal
  97427. + ));
  97428. +
  97429. + /* Set the signal, buffer is currently not busy. */
  97430. + gcmkONERROR(gckOS_Signal(
  97431. + Os, buffer->signal, gcvTRUE
  97432. + ));
  97433. +
  97434. + /* Create a new physical context buffer. */
  97435. +#if gcdVIRTUAL_COMMAND_BUFFER
  97436. + gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
  97437. + context->hardware->kernel,
  97438. + gcvFALSE,
  97439. + &context->totalSize,
  97440. + &buffer->physical,
  97441. + &pointer
  97442. + ));
  97443. +
  97444. +#else
  97445. + gcmkONERROR(gckOS_AllocateContiguous(
  97446. + Os,
  97447. + gcvFALSE,
  97448. + &context->totalSize,
  97449. + &buffer->physical,
  97450. + &pointer
  97451. + ));
  97452. +#endif
  97453. +
  97454. + buffer->logical = pointer;
  97455. +
  97456. + /* Set gckEVENT object pointer. */
  97457. + buffer->eventObj = Hardware->kernel->eventObj;
  97458. +
  97459. + /* Set the pointers to the LINK commands. */
  97460. + if (context->linkIndex2D != 0)
  97461. + {
  97462. + buffer->link2D = &buffer->logical[context->linkIndex2D];
  97463. + }
  97464. +
  97465. + if (context->linkIndex3D != 0)
  97466. + {
  97467. + buffer->link3D = &buffer->logical[context->linkIndex3D];
  97468. + }
  97469. +
  97470. + if (context->linkIndexXD != 0)
  97471. + {
  97472. + gctPOINTER xdLink;
  97473. + gctUINT8_PTR xdEntryLogical;
  97474. + gctSIZE_T xdEntrySize;
  97475. + gctSIZE_T linkBytes;
  97476. +
  97477. + /* Determine LINK parameters. */
  97478. + xdLink
  97479. + = &buffer->logical[context->linkIndexXD];
  97480. +
  97481. + xdEntryLogical
  97482. + = (gctUINT8_PTR) buffer->logical
  97483. + + context->entryOffsetXDFrom3D;
  97484. +
  97485. + xdEntrySize
  97486. + = context->bufferSize
  97487. + - context->entryOffsetXDFrom3D;
  97488. +
  97489. + /* Query LINK size. */
  97490. + gcmkONERROR(gckHARDWARE_Link(
  97491. + Hardware, gcvNULL, gcvNULL, 0, &linkBytes
  97492. + ));
  97493. +
  97494. + /* Generate a LINK. */
  97495. + gcmkONERROR(gckHARDWARE_Link(
  97496. + Hardware,
  97497. + xdLink,
  97498. + xdEntryLogical,
  97499. + xdEntrySize,
  97500. + &linkBytes
  97501. + ));
  97502. + }
  97503. + }
  97504. +
  97505. +
  97506. + /**************************************************************************/
  97507. + /* Initialize the context buffers. ****************************************/
  97508. +
  97509. + /* Initialize the current context buffer. */
  97510. + gcmkONERROR(_InitializeContextBuffer(context));
  97511. +
  97512. + /* Make all created contexts equal. */
  97513. + {
  97514. + gcsCONTEXT_PTR currContext, tempContext;
  97515. +
  97516. + /* Set the current context buffer. */
  97517. + currContext = context->buffer;
  97518. +
  97519. + /* Get the next context buffer. */
  97520. + tempContext = currContext->next;
  97521. +
  97522. + /* Loop through all buffers. */
  97523. + while (tempContext != currContext)
  97524. + {
  97525. + if (tempContext == gcvNULL)
  97526. + {
  97527. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  97528. + }
  97529. +
  97530. + /* Copy the current context. */
  97531. + gckOS_MemCopy(
  97532. + tempContext->logical,
  97533. + currContext->logical,
  97534. + context->totalSize
  97535. + );
  97536. +
  97537. + /* Get the next context buffer. */
  97538. + tempContext = tempContext->next;
  97539. + }
  97540. + }
  97541. +
  97542. + /* Return pointer to the gckCONTEXT object. */
  97543. + *Context = context;
  97544. +
  97545. + /* Success. */
  97546. + gcmkFOOTER_ARG("*Context=0x%08X", *Context);
  97547. + return gcvSTATUS_OK;
  97548. +
  97549. +OnError:
  97550. + /* Roll back on error. */
  97551. + gcmkVERIFY_OK(_DestroyContext(context));
  97552. +
  97553. + /* Return the status. */
  97554. + gcmkFOOTER();
  97555. + return status;
  97556. +}
  97557. +
  97558. +/******************************************************************************\
  97559. +**
  97560. +** gckCONTEXT_Destroy
  97561. +**
  97562. +** Destroy a gckCONTEXT object.
  97563. +**
  97564. +** INPUT:
  97565. +**
  97566. +** gckCONTEXT Context
  97567. +** Pointer to an gckCONTEXT object.
  97568. +**
  97569. +** OUTPUT:
  97570. +**
  97571. +** Nothing.
  97572. +*/
  97573. +gceSTATUS
  97574. +gckCONTEXT_Destroy(
  97575. + IN gckCONTEXT Context
  97576. + )
  97577. +{
  97578. + gceSTATUS status;
  97579. +
  97580. + gcmkHEADER_ARG("Context=0x%08X", Context);
  97581. +
  97582. + /* Verify the arguments. */
  97583. + gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
  97584. +
  97585. + /* Destroy the context and all related objects. */
  97586. + status = _DestroyContext(Context);
  97587. +
  97588. + /* Success. */
  97589. + gcmkFOOTER_NO();
  97590. + return status;
  97591. +}
  97592. +
  97593. +/******************************************************************************\
  97594. +**
  97595. +** gckCONTEXT_Update
  97596. +**
  97597. +** Merge all pending state delta buffers into the current context buffer.
  97598. +**
  97599. +** INPUT:
  97600. +**
  97601. +** gckCONTEXT Context
  97602. +** Pointer to an gckCONTEXT object.
  97603. +**
  97604. +** gctUINT32 ProcessID
  97605. +** Current process ID.
  97606. +**
  97607. +** gcsSTATE_DELTA_PTR StateDelta
  97608. +** Pointer to the state delta.
  97609. +**
  97610. +** OUTPUT:
  97611. +**
  97612. +** Nothing.
  97613. +*/
  97614. +gceSTATUS
  97615. +gckCONTEXT_Update(
  97616. + IN gckCONTEXT Context,
  97617. + IN gctUINT32 ProcessID,
  97618. + IN gcsSTATE_DELTA_PTR StateDelta
  97619. + )
  97620. +{
  97621. +#ifndef VIVANTE_NO_3D
  97622. + gceSTATUS status = gcvSTATUS_OK;
  97623. + gcsSTATE_DELTA _stateDelta;
  97624. + gckKERNEL kernel;
  97625. + gcsCONTEXT_PTR buffer;
  97626. + gcsSTATE_MAP_PTR map;
  97627. + gctBOOL needCopy = gcvFALSE;
  97628. + gcsSTATE_DELTA_PTR nDelta;
  97629. + gcsSTATE_DELTA_PTR uDelta = gcvNULL;
  97630. + gcsSTATE_DELTA_PTR kDelta = gcvNULL;
  97631. + gcsSTATE_DELTA_RECORD_PTR record;
  97632. + gcsSTATE_DELTA_RECORD_PTR recordArray = gcvNULL;
  97633. + gctUINT elementCount;
  97634. + gctUINT address;
  97635. + gctUINT32 mask;
  97636. + gctUINT32 data;
  97637. + gctUINT index;
  97638. + gctUINT i, j;
  97639. +
  97640. +#if gcdSECURE_USER
  97641. + gcskSECURE_CACHE_PTR cache;
  97642. +#endif
  97643. +
  97644. + gcmkHEADER_ARG(
  97645. + "Context=0x%08X ProcessID=%d StateDelta=0x%08X",
  97646. + Context, ProcessID, StateDelta
  97647. + );
  97648. +
  97649. + /* Verify the arguments. */
  97650. + gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
  97651. +
  97652. + /* Get a shortcut to the kernel object. */
  97653. + kernel = Context->hardware->kernel;
  97654. +
  97655. + /* Check wehther we need to copy the structures or not. */
  97656. + gcmkONERROR(gckOS_QueryNeedCopy(Context->os, ProcessID, &needCopy));
  97657. +
  97658. + /* Allocate the copy buffer for the user record array. */
  97659. + if (needCopy && (Context->recordArray == gcvNULL))
  97660. + {
  97661. + /* Allocate the buffer. */
  97662. + gcmkONERROR(gckOS_Allocate(
  97663. + Context->os,
  97664. + Context->recordArraySize,
  97665. + (gctPOINTER *) &Context->recordArray
  97666. + ));
  97667. + }
  97668. +
  97669. + /* Get the current context buffer. */
  97670. + buffer = Context->buffer;
  97671. +
  97672. + /* Wait until the context buffer becomes available; this will
  97673. + also reset the signal and mark the buffer as busy. */
  97674. + gcmkONERROR(gckOS_WaitSignal(
  97675. + Context->os, buffer->signal, gcvINFINITE
  97676. + ));
  97677. +
  97678. +#if gcdSECURE_USER
  97679. + /* Get the cache form the database. */
  97680. + gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
  97681. +#endif
  97682. +
  97683. +#if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && !defined(VIVANTE_NO_3D)
  97684. + /* Update current context token. */
  97685. + buffer->logical[Context->map[0x0E14].index]
  97686. + = gcmPTR2INT(Context);
  97687. +#endif
  97688. +
  97689. + /* Are there any pending deltas? */
  97690. + if (buffer->deltaCount != 0)
  97691. + {
  97692. + /* Get the state map. */
  97693. + map = Context->map;
  97694. +
  97695. + /* Get the first delta item. */
  97696. + uDelta = buffer->delta;
  97697. +
  97698. + /* Reset the vertex stream count. */
  97699. + elementCount = 0;
  97700. +
  97701. + /* Merge all pending deltas. */
  97702. + for (i = 0; i < buffer->deltaCount; i += 1)
  97703. + {
  97704. + /* Get access to the state delta. */
  97705. + gcmkONERROR(gckKERNEL_OpenUserData(
  97706. + kernel, needCopy,
  97707. + &_stateDelta,
  97708. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  97709. + (gctPOINTER *) &kDelta
  97710. + ));
  97711. +
  97712. + /* Get access to the state records. */
  97713. + gcmkONERROR(gckKERNEL_OpenUserData(
  97714. + kernel, needCopy,
  97715. + Context->recordArray,
  97716. + gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
  97717. + (gctPOINTER *) &recordArray
  97718. + ));
  97719. +
  97720. + /* Merge all pending states. */
  97721. + for (j = 0; j < kDelta->recordCount; j += 1)
  97722. + {
  97723. + if (j >= Context->stateCount)
  97724. + {
  97725. + break;
  97726. + }
  97727. +
  97728. + /* Get the current state record. */
  97729. + record = &recordArray[j];
  97730. +
  97731. + /* Get the state address. */
  97732. + address = record->address;
  97733. +
  97734. + /* Make sure the state is a part of the mapping table. */
  97735. + if (address >= Context->stateCount)
  97736. + {
  97737. + gcmkTRACE(
  97738. + gcvLEVEL_ERROR,
  97739. + "%s(%d): State 0x%04X is not mapped.\n",
  97740. + __FUNCTION__, __LINE__,
  97741. + address
  97742. + );
  97743. +
  97744. + continue;
  97745. + }
  97746. +
  97747. + /* Get the state index. */
  97748. + index = map[address].index;
  97749. +
  97750. + /* Skip the state if not mapped. */
  97751. + if (index == 0)
  97752. + {
  97753. +#if gcdDEBUG
  97754. + if ((address != 0x0594)
  97755. + && (address != 0x0E00)
  97756. + && (address != 0x0E03)
  97757. + )
  97758. + {
  97759. +#endif
  97760. + gcmkTRACE(
  97761. + gcvLEVEL_ERROR,
  97762. + "%s(%d): State 0x%04X is not mapped.\n",
  97763. + __FUNCTION__, __LINE__,
  97764. + address
  97765. + );
  97766. +#if gcdDEBUG
  97767. + }
  97768. +#endif
  97769. + continue;
  97770. + }
  97771. +
  97772. + /* Get the data mask. */
  97773. + mask = record->mask;
  97774. +
  97775. + /* Masked states that are being completly reset or regular states. */
  97776. + if ((mask == 0) || (mask == ~0U))
  97777. + {
  97778. + /* Get the new data value. */
  97779. + data = record->data;
  97780. +
  97781. + /* Process special states. */
  97782. + if (address == 0x0595)
  97783. + {
  97784. + /* Force auto-disable to be disabled. */
  97785. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
  97786. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
  97787. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1))))))) << (0 ? 13:13))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1))))))) << (0 ? 13:13)));
  97788. + }
  97789. +
  97790. +#if gcdSECURE_USER
  97791. + /* Do we need to convert the logical address? */
  97792. + if (Context->hint[address])
  97793. + {
  97794. + /* Map handle into physical address. */
  97795. + gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
  97796. + kernel, cache, (gctPOINTER) &data
  97797. + ));
  97798. + }
  97799. +#endif
  97800. +
  97801. + /* Set new data. */
  97802. + buffer->logical[index] = data;
  97803. + }
  97804. +
  97805. + /* Masked states that are being set partially. */
  97806. + else
  97807. + {
  97808. + buffer->logical[index]
  97809. + = (~mask & buffer->logical[index])
  97810. + | (mask & record->data);
  97811. + }
  97812. + }
  97813. +
  97814. + /* Get the element count. */
  97815. + if (kDelta->elementCount != 0)
  97816. + {
  97817. + elementCount = kDelta->elementCount;
  97818. + }
  97819. +
  97820. + /* Dereference delta. */
  97821. + kDelta->refCount -= 1;
  97822. + gcmkASSERT(kDelta->refCount >= 0);
  97823. +
  97824. + /* Get the next state delta. */
  97825. + nDelta = gcmUINT64_TO_PTR(kDelta->next);
  97826. +
  97827. + /* Get access to the state records. */
  97828. + gcmkONERROR(gckKERNEL_CloseUserData(
  97829. + kernel, needCopy,
  97830. + gcvFALSE,
  97831. + gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
  97832. + (gctPOINTER *) &recordArray
  97833. + ));
  97834. +
  97835. + /* Close access to the current state delta. */
  97836. + gcmkONERROR(gckKERNEL_CloseUserData(
  97837. + kernel, needCopy,
  97838. + gcvTRUE,
  97839. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  97840. + (gctPOINTER *) &kDelta
  97841. + ));
  97842. +
  97843. + /* Update the user delta pointer. */
  97844. + uDelta = nDelta;
  97845. + }
  97846. +
  97847. + /* Hardware disables all input streams when the stream 0 is programmed,
  97848. + it then reenables those streams that were explicitely programmed by
  97849. + the software. Because of this we cannot program the entire array of
  97850. + values, otherwise we'll get all streams reenabled, but rather program
  97851. + only those that are actully needed by the software. */
  97852. + if (elementCount != 0)
  97853. + {
  97854. + gctUINT base;
  97855. + gctUINT nopCount;
  97856. + gctUINT32_PTR nop;
  97857. + gctUINT fe2vsCount = 12;
  97858. +
  97859. + if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures1)) >> (0 ? 23:23)) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) ))
  97860. + {
  97861. + fe2vsCount = 16;
  97862. + }
  97863. +
  97864. + /* Determine the base index of the vertex stream array. */
  97865. + base = map[0x0180].index;
  97866. +
  97867. + /* Set the proper state count. */
  97868. + buffer->logical[base - 1]
  97869. + = ((((gctUINT32) (buffer->logical[base - 1])) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (elementCount ) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  97870. +
  97871. + /* Determine the number of NOP commands. */
  97872. + nopCount
  97873. + = (fe2vsCount / 2)
  97874. + - (elementCount / 2);
  97875. +
  97876. + /* Determine the location of the first NOP. */
  97877. + nop = &buffer->logical[base + (elementCount | 1)];
  97878. +
  97879. + /* Fill the unused space with NOPs. */
  97880. + for (i = 0; i < nopCount; i += 1)
  97881. + {
  97882. + if (nop >= buffer->logical + Context->totalSize)
  97883. + {
  97884. + break;
  97885. + }
  97886. +
  97887. + /* Generate a NOP command. */
  97888. + *nop = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  97889. +
  97890. + /* Advance. */
  97891. + nop += 2;
  97892. + }
  97893. + }
  97894. +
  97895. + /* Reset pending deltas. */
  97896. + buffer->deltaCount = 0;
  97897. + buffer->delta = gcvNULL;
  97898. + }
  97899. +
  97900. + /* Set state delta user pointer. */
  97901. + uDelta = StateDelta;
  97902. +
  97903. + /* Get access to the state delta. */
  97904. + gcmkONERROR(gckKERNEL_OpenUserData(
  97905. + kernel, needCopy,
  97906. + &_stateDelta,
  97907. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  97908. + (gctPOINTER *) &kDelta
  97909. + ));
  97910. +
  97911. + /* State delta cannot be attached to anything yet. */
  97912. + if (kDelta->refCount != 0)
  97913. + {
  97914. + gcmkTRACE(
  97915. + gcvLEVEL_ERROR,
  97916. + "%s(%d): kDelta->refCount = %d (has to be 0).\n",
  97917. + __FUNCTION__, __LINE__,
  97918. + kDelta->refCount
  97919. + );
  97920. + }
  97921. +
  97922. + /* Attach to all contexts. */
  97923. + buffer = Context->buffer;
  97924. +
  97925. + do
  97926. + {
  97927. + /* Attach to the context if nothing is attached yet. If a delta
  97928. + is allready attached, all we need to do is to increment
  97929. + the number of deltas in the context. */
  97930. + if (buffer->delta == gcvNULL)
  97931. + {
  97932. + buffer->delta = uDelta;
  97933. + }
  97934. +
  97935. + /* Update reference count. */
  97936. + kDelta->refCount += 1;
  97937. +
  97938. + /* Update counters. */
  97939. + buffer->deltaCount += 1;
  97940. +
  97941. + /* Get the next context buffer. */
  97942. + buffer = buffer->next;
  97943. +
  97944. + if (buffer == gcvNULL)
  97945. + {
  97946. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  97947. + }
  97948. + }
  97949. + while (Context->buffer != buffer);
  97950. +
  97951. + /* Close access to the current state delta. */
  97952. + gcmkONERROR(gckKERNEL_CloseUserData(
  97953. + kernel, needCopy,
  97954. + gcvTRUE,
  97955. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  97956. + (gctPOINTER *) &kDelta
  97957. + ));
  97958. +
  97959. + /* Schedule an event to mark the context buffer as available. */
  97960. + gcmkONERROR(gckEVENT_Signal(
  97961. + buffer->eventObj, buffer->signal, gcvKERNEL_PIXEL
  97962. + ));
  97963. +
  97964. + /* Advance to the next context buffer. */
  97965. + Context->buffer = buffer->next;
  97966. +
  97967. + /* Return the status. */
  97968. + gcmkFOOTER();
  97969. + return gcvSTATUS_OK;
  97970. +
  97971. +OnError:
  97972. + /* Get access to the state records. */
  97973. + if (kDelta != gcvNULL)
  97974. + {
  97975. + gcmkVERIFY_OK(gckKERNEL_CloseUserData(
  97976. + kernel, needCopy,
  97977. + gcvFALSE,
  97978. + gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
  97979. + (gctPOINTER *) &recordArray
  97980. + ));
  97981. + }
  97982. +
  97983. + /* Close access to the current state delta. */
  97984. + gcmkVERIFY_OK(gckKERNEL_CloseUserData(
  97985. + kernel, needCopy,
  97986. + gcvTRUE,
  97987. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  97988. + (gctPOINTER *) &kDelta
  97989. + ));
  97990. +
  97991. + /* Return the status. */
  97992. + gcmkFOOTER();
  97993. + return status;
  97994. +#else
  97995. + return gcvSTATUS_OK;
  97996. +#endif
  97997. +}
  97998. +
  97999. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h
  98000. --- linux-3.14.15/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h 1970-01-01 01:00:00.000000000 +0100
  98001. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h 2014-08-20 19:23:53.558845839 +0200
  98002. @@ -0,0 +1,157 @@
  98003. +/****************************************************************************
  98004. +*
  98005. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  98006. +*
  98007. +* This program is free software; you can redistribute it and/or modify
  98008. +* it under the terms of the GNU General Public License as published by
  98009. +* the Free Software Foundation; either version 2 of the license, or
  98010. +* (at your option) any later version.
  98011. +*
  98012. +* This program is distributed in the hope that it will be useful,
  98013. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  98014. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  98015. +* GNU General Public License for more details.
  98016. +*
  98017. +* You should have received a copy of the GNU General Public License
  98018. +* along with this program; if not write to the Free Software
  98019. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  98020. +*
  98021. +*****************************************************************************/
  98022. +
  98023. +
  98024. +#ifndef __gc_hal_kernel_context_h_
  98025. +#define __gc_hal_kernel_context_h_
  98026. +
  98027. +#include "gc_hal_kernel_buffer.h"
  98028. +
  98029. +#ifdef __cplusplus
  98030. +extern "C" {
  98031. +#endif
  98032. +
  98033. +/* Maps state locations within the context buffer. */
  98034. +typedef struct _gcsSTATE_MAP * gcsSTATE_MAP_PTR;
  98035. +typedef struct _gcsSTATE_MAP
  98036. +{
  98037. + /* Index of the state in the context buffer. */
  98038. + gctUINT index;
  98039. +
  98040. + /* State mask. */
  98041. + gctUINT32 mask;
  98042. +}
  98043. +gcsSTATE_MAP;
  98044. +
  98045. +/* Context buffer. */
  98046. +typedef struct _gcsCONTEXT * gcsCONTEXT_PTR;
  98047. +typedef struct _gcsCONTEXT
  98048. +{
  98049. + /* For debugging: the number of context buffer in the order of creation. */
  98050. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  98051. + gctUINT num;
  98052. +#endif
  98053. +
  98054. + /* Pointer to gckEVENT object. */
  98055. + gckEVENT eventObj;
  98056. +
  98057. + /* Context busy signal. */
  98058. + gctSIGNAL signal;
  98059. +
  98060. + /* Physical address of the context buffer. */
  98061. + gctPHYS_ADDR physical;
  98062. +
  98063. + /* Logical address of the context buffer. */
  98064. + gctUINT32_PTR logical;
  98065. +
  98066. + /* Pointer to the LINK commands. */
  98067. + gctPOINTER link2D;
  98068. + gctPOINTER link3D;
  98069. +
  98070. + /* The number of pending state deltas. */
  98071. + gctUINT deltaCount;
  98072. +
  98073. + /* Pointer to the first delta to be applied. */
  98074. + gcsSTATE_DELTA_PTR delta;
  98075. +
  98076. + /* Next context buffer. */
  98077. + gcsCONTEXT_PTR next;
  98078. +}
  98079. +gcsCONTEXT;
  98080. +
  98081. +/* gckCONTEXT structure that hold the current context. */
  98082. +struct _gckCONTEXT
  98083. +{
  98084. + /* Object. */
  98085. + gcsOBJECT object;
  98086. +
  98087. + /* Pointer to gckOS object. */
  98088. + gckOS os;
  98089. +
  98090. + /* Pointer to gckHARDWARE object. */
  98091. + gckHARDWARE hardware;
  98092. +
  98093. + /* Command buffer alignment. */
  98094. + gctSIZE_T alignment;
  98095. + gctSIZE_T reservedHead;
  98096. + gctSIZE_T reservedTail;
  98097. +
  98098. + /* Context buffer metrics. */
  98099. + gctSIZE_T stateCount;
  98100. + gctSIZE_T totalSize;
  98101. + gctSIZE_T bufferSize;
  98102. + gctUINT32 linkIndex2D;
  98103. + gctUINT32 linkIndex3D;
  98104. + gctUINT32 linkIndexXD;
  98105. + gctUINT32 entryOffset3D;
  98106. + gctUINT32 entryOffsetXDFrom2D;
  98107. + gctUINT32 entryOffsetXDFrom3D;
  98108. +
  98109. + /* Dirty flags. */
  98110. + gctBOOL dirty;
  98111. + gctBOOL dirty2D;
  98112. + gctBOOL dirty3D;
  98113. + gcsCONTEXT_PTR dirtyBuffer;
  98114. +
  98115. + /* State mapping. */
  98116. + gcsSTATE_MAP_PTR map;
  98117. +
  98118. + /* List of context buffers. */
  98119. + gcsCONTEXT_PTR buffer;
  98120. +
  98121. + /* A copy of the user record array. */
  98122. + gctUINT recordArraySize;
  98123. + gcsSTATE_DELTA_RECORD_PTR recordArray;
  98124. +
  98125. + /* Requested pipe select for context. */
  98126. + gcePIPE_SELECT entryPipe;
  98127. + gcePIPE_SELECT exitPipe;
  98128. +
  98129. + /* Variables used for building state buffer. */
  98130. + gctUINT32 lastAddress;
  98131. + gctSIZE_T lastSize;
  98132. + gctUINT32 lastIndex;
  98133. + gctBOOL lastFixed;
  98134. +
  98135. + /* Hint array. */
  98136. +#if gcdSECURE_USER
  98137. + gctBOOL_PTR hint;
  98138. +#endif
  98139. +
  98140. +#if VIVANTE_PROFILER_CONTEXT
  98141. + gcsPROFILER_COUNTERS latestProfiler;
  98142. + gcsPROFILER_COUNTERS histroyProfiler;
  98143. + gctUINT32 prevVSInstCount;
  98144. + gctUINT32 prevVSBranchInstCount;
  98145. + gctUINT32 prevVSTexInstCount;
  98146. + gctUINT32 prevVSVertexCount;
  98147. + gctUINT32 prevPSInstCount;
  98148. + gctUINT32 prevPSBranchInstCount;
  98149. + gctUINT32 prevPSTexInstCount;
  98150. + gctUINT32 prevPSPixelCount;
  98151. +#endif
  98152. +};
  98153. +
  98154. +#ifdef __cplusplus
  98155. +}
  98156. +#endif
  98157. +
  98158. +#endif /* __gc_hal_kernel_context_h_ */
  98159. +
  98160. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
  98161. --- linux-3.14.15/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c 1970-01-01 01:00:00.000000000 +0100
  98162. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c 2014-08-20 19:31:46.128869007 +0200
  98163. @@ -0,0 +1,7280 @@
  98164. +/****************************************************************************
  98165. +*
  98166. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  98167. +*
  98168. +* This program is free software; you can redistribute it and/or modify
  98169. +* it under the terms of the GNU General Public License as published by
  98170. +* the Free Software Foundation; either version 2 of the license, or
  98171. +* (at your option) any later version.
  98172. +*
  98173. +* This program is distributed in the hope that it will be useful,
  98174. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  98175. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  98176. +* GNU General Public License for more details.
  98177. +*
  98178. +* You should have received a copy of the GNU General Public License
  98179. +* along with this program; if not write to the Free Software
  98180. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  98181. +*
  98182. +*****************************************************************************/
  98183. +
  98184. +
  98185. +#include "gc_hal.h"
  98186. +#include "gc_hal_kernel.h"
  98187. +#if VIVANTE_PROFILER_CONTEXT
  98188. +#include "gc_hal_kernel_context.h"
  98189. +#endif
  98190. +
  98191. +#define _GC_OBJ_ZONE gcvZONE_HARDWARE
  98192. +
  98193. +typedef struct _gcsiDEBUG_REGISTERS * gcsiDEBUG_REGISTERS_PTR;
  98194. +typedef struct _gcsiDEBUG_REGISTERS
  98195. +{
  98196. + gctSTRING module;
  98197. + gctUINT index;
  98198. + gctUINT shift;
  98199. + gctUINT data;
  98200. + gctUINT count;
  98201. + gctUINT32 signature;
  98202. +}
  98203. +gcsiDEBUG_REGISTERS;
  98204. +
  98205. +extern int gpu3DMinClock;
  98206. +/******************************************************************************\
  98207. +********************************* Support Code *********************************
  98208. +\******************************************************************************/
  98209. +static gceSTATUS
  98210. +_ResetGPU(
  98211. + IN gckHARDWARE Hardware,
  98212. + IN gckOS Os,
  98213. + IN gceCORE Core
  98214. + );
  98215. +
  98216. +static gceSTATUS
  98217. +_IdentifyHardware(
  98218. + IN gckOS Os,
  98219. + IN gceCORE Core,
  98220. + OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  98221. + )
  98222. +{
  98223. + gceSTATUS status;
  98224. +
  98225. + gctUINT32 chipIdentity;
  98226. +
  98227. + gctUINT32 streamCount = 0;
  98228. + gctUINT32 registerMax = 0;
  98229. + gctUINT32 threadCount = 0;
  98230. + gctUINT32 shaderCoreCount = 0;
  98231. + gctUINT32 vertexCacheSize = 0;
  98232. + gctUINT32 vertexOutputBufferSize = 0;
  98233. + gctUINT32 pixelPipes = 0;
  98234. + gctUINT32 instructionCount = 0;
  98235. + gctUINT32 numConstants = 0;
  98236. + gctUINT32 bufferSize = 0;
  98237. + gctUINT32 varyingsCount = 0;
  98238. + gctBOOL useHZ;
  98239. +
  98240. + gcmkHEADER_ARG("Os=0x%x", Os);
  98241. +
  98242. + /***************************************************************************
  98243. + ** Get chip ID and revision.
  98244. + */
  98245. +
  98246. + /* Read chip identity register. */
  98247. + gcmkONERROR(
  98248. + gckOS_ReadRegisterEx(Os, Core,
  98249. + 0x00018,
  98250. + &chipIdentity));
  98251. +
  98252. + /* Special case for older graphic cores. */
  98253. + if (((((gctUINT32) (chipIdentity)) >> (0 ? 31:24) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))))
  98254. + {
  98255. + Identity->chipModel = gcv500;
  98256. + Identity->chipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) );
  98257. + }
  98258. +
  98259. + else
  98260. + {
  98261. + /* Read chip identity register. */
  98262. + gcmkONERROR(
  98263. + gckOS_ReadRegisterEx(Os, Core,
  98264. + 0x00020,
  98265. + (gctUINT32_PTR) &Identity->chipModel));
  98266. +
  98267. + /* !!!! HACK ALERT !!!! */
  98268. + /* Because people change device IDs without letting software know
  98269. + ** about it - here is the hack to make it all look the same. Only
  98270. + ** for GC400 family. Next time - TELL ME!!! */
  98271. + if (((Identity->chipModel & 0xFF00) == 0x0400)
  98272. + && (Identity->chipModel != 0x0420))
  98273. + {
  98274. + Identity->chipModel = (gceCHIPMODEL) (Identity->chipModel & 0x0400);
  98275. + }
  98276. +
  98277. + /* Read CHIP_REV register. */
  98278. + gcmkONERROR(
  98279. + gckOS_ReadRegisterEx(Os, Core,
  98280. + 0x00024,
  98281. + &Identity->chipRevision));
  98282. +
  98283. + if ((Identity->chipModel == gcv300)
  98284. + && (Identity->chipRevision == 0x2201)
  98285. + )
  98286. + {
  98287. + gctUINT32 chipDate;
  98288. + gctUINT32 chipTime;
  98289. +
  98290. + /* Read date and time registers. */
  98291. + gcmkONERROR(
  98292. + gckOS_ReadRegisterEx(Os, Core,
  98293. + 0x00028,
  98294. + &chipDate));
  98295. +
  98296. + gcmkONERROR(
  98297. + gckOS_ReadRegisterEx(Os, Core,
  98298. + 0x0002C,
  98299. + &chipTime));
  98300. +
  98301. + if ((chipDate == 0x20080814) && (chipTime == 0x12051100))
  98302. + {
  98303. + /* This IP has an ECO; put the correct revision in it. */
  98304. + Identity->chipRevision = 0x1051;
  98305. + }
  98306. + }
  98307. + }
  98308. +
  98309. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98310. + "Identity: chipModel=%X",
  98311. + Identity->chipModel);
  98312. +
  98313. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98314. + "Identity: chipRevision=%X",
  98315. + Identity->chipRevision);
  98316. +
  98317. +
  98318. + /***************************************************************************
  98319. + ** Get chip features.
  98320. + */
  98321. +
  98322. + /* Read chip feature register. */
  98323. + gcmkONERROR(
  98324. + gckOS_ReadRegisterEx(Os, Core,
  98325. + 0x0001C,
  98326. + &Identity->chipFeatures));
  98327. +
  98328. +#ifndef VIVANTE_NO_3D
  98329. + /* Disable fast clear on GC700. */
  98330. + if (Identity->chipModel == gcv700)
  98331. + {
  98332. + Identity->chipFeatures
  98333. + = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
  98334. + }
  98335. +#endif
  98336. +
  98337. + if (((Identity->chipModel == gcv500) && (Identity->chipRevision < 2))
  98338. + || ((Identity->chipModel == gcv300) && (Identity->chipRevision < 0x2000))
  98339. + )
  98340. + {
  98341. + /* GC500 rev 1.x and GC300 rev < 2.0 doesn't have these registers. */
  98342. + Identity->chipMinorFeatures = 0;
  98343. + Identity->chipMinorFeatures1 = 0;
  98344. + Identity->chipMinorFeatures2 = 0;
  98345. + Identity->chipMinorFeatures3 = 0;
  98346. + Identity->chipMinorFeatures4 = 0;
  98347. + }
  98348. + else
  98349. + {
  98350. + /* Read chip minor feature register #0. */
  98351. + gcmkONERROR(
  98352. + gckOS_ReadRegisterEx(Os, Core,
  98353. + 0x00034,
  98354. + &Identity->chipMinorFeatures));
  98355. +
  98356. + if (((((gctUINT32) (Identity->chipMinorFeatures)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))))
  98357. + )
  98358. + {
  98359. + /* Read chip minor featuress register #1. */
  98360. + gcmkONERROR(
  98361. + gckOS_ReadRegisterEx(Os, Core,
  98362. + 0x00074,
  98363. + &Identity->chipMinorFeatures1));
  98364. +
  98365. + /* Read chip minor featuress register #2. */
  98366. + gcmkONERROR(
  98367. + gckOS_ReadRegisterEx(Os, Core,
  98368. + 0x00084,
  98369. + &Identity->chipMinorFeatures2));
  98370. +
  98371. + /*Identity->chipMinorFeatures2 &= ~(0x1 << 3);*/
  98372. +
  98373. + /* Read chip minor featuress register #1. */
  98374. + gcmkONERROR(
  98375. + gckOS_ReadRegisterEx(Os, Core,
  98376. + 0x00088,
  98377. + &Identity->chipMinorFeatures3));
  98378. +
  98379. + /*The BG2 chip has no compression supertiled, and the bit of GCMinorFeature3BugFixes15 is n/a*/
  98380. + if(Identity->chipModel == gcv1000 && Identity->chipRevision == 0x5036)
  98381. + {
  98382. + Identity->chipMinorFeatures3
  98383. + = ((((gctUINT32) (Identity->chipMinorFeatures3)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
  98384. + Identity->chipMinorFeatures3
  98385. + = ((((gctUINT32) (Identity->chipMinorFeatures3)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27)));
  98386. + }
  98387. +
  98388. + /* Read chip minor featuress register #4. */
  98389. + gcmkONERROR(
  98390. + gckOS_ReadRegisterEx(Os, Core,
  98391. + 0x00094,
  98392. + &Identity->chipMinorFeatures4));
  98393. + }
  98394. + else
  98395. + {
  98396. + /* Chip doesn't has minor features register #1 or 2 or 3 or 4. */
  98397. + Identity->chipMinorFeatures1 = 0;
  98398. + Identity->chipMinorFeatures2 = 0;
  98399. + Identity->chipMinorFeatures3 = 0;
  98400. + Identity->chipMinorFeatures4 = 0;
  98401. + }
  98402. + }
  98403. +
  98404. + /* Get the Supertile layout in the hardware. */
  98405. + if (((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))))
  98406. + || ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))))
  98407. + {
  98408. + Identity->superTileMode = 2;
  98409. + }
  98410. + else if (((((gctUINT32) (Identity->chipMinorFeatures)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))))
  98411. + {
  98412. + Identity->superTileMode = 1;
  98413. + }
  98414. + else
  98415. + {
  98416. + Identity->superTileMode = 0;
  98417. + }
  98418. +
  98419. + /* Exception for GC1000, revision 5035 & GC800, revision 4612 */
  98420. + if (((Identity->chipModel == gcv1000) && ((Identity->chipRevision == 0x5035)
  98421. + || (Identity->chipRevision == 0x5036)
  98422. + || (Identity->chipRevision == 0x5037)))
  98423. + || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612))
  98424. + || ((Identity->chipModel == gcv860) && (Identity->chipRevision == 0x4647)))
  98425. + {
  98426. + Identity->superTileMode = 1;
  98427. + }
  98428. +
  98429. + if (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5245)
  98430. + {
  98431. + useHZ = ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))))
  98432. + || ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))));
  98433. + }
  98434. + else
  98435. + {
  98436. + useHZ = gcvFALSE;
  98437. + }
  98438. +
  98439. + if (useHZ)
  98440. + {
  98441. + /* Disable EZ. */
  98442. + Identity->chipFeatures
  98443. + = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
  98444. + }
  98445. +
  98446. + /* Disable HZ when EZ is present for older chips. */
  98447. + else if (!((((gctUINT32) (Identity->chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))))
  98448. + {
  98449. + /* Disable HIERARCHICAL_Z. */
  98450. + Identity->chipMinorFeatures
  98451. + = ((((gctUINT32) (Identity->chipMinorFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27)));
  98452. + }
  98453. +
  98454. + /* Disable rectangle primitive when chip is gc880_5_1_0_rc6*/
  98455. + if ((Identity->chipModel == gcv880) && (Identity->chipRevision == 0x5106))
  98456. + {
  98457. + /* Disable rectangle primitive. */
  98458. + Identity->chipMinorFeatures2
  98459. + = ((((gctUINT32) (Identity->chipMinorFeatures2)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
  98460. + }
  98461. +
  98462. + if ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4605))
  98463. + {
  98464. + /* Correct feature bit: RTL does not have such feature. */
  98465. + Identity->chipFeatures
  98466. + = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)));
  98467. + }
  98468. +
  98469. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98470. + "Identity: chipFeatures=0x%08X",
  98471. + Identity->chipFeatures);
  98472. +
  98473. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98474. + "Identity: chipMinorFeatures=0x%08X",
  98475. + Identity->chipMinorFeatures);
  98476. +
  98477. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98478. + "Identity: chipMinorFeatures1=0x%08X",
  98479. + Identity->chipMinorFeatures1);
  98480. +
  98481. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98482. + "Identity: chipMinorFeatures2=0x%08X",
  98483. + Identity->chipMinorFeatures2);
  98484. +
  98485. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98486. + "Identity: chipMinorFeatures3=0x%08X",
  98487. + Identity->chipMinorFeatures3);
  98488. +
  98489. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98490. + "Identity: chipMinorFeatures4=0x%08X",
  98491. + Identity->chipMinorFeatures4);
  98492. +
  98493. + /***************************************************************************
  98494. + ** Get chip specs.
  98495. + */
  98496. +
  98497. + if (((((gctUINT32) (Identity->chipMinorFeatures)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))))
  98498. + {
  98499. + gctUINT32 specs, specs2, specs3;
  98500. +
  98501. + /* Read gcChipSpecs register. */
  98502. + gcmkONERROR(
  98503. + gckOS_ReadRegisterEx(Os, Core,
  98504. + 0x00048,
  98505. + &specs));
  98506. +
  98507. + /* Extract the fields. */
  98508. + streamCount = (((((gctUINT32) (specs)) >> (0 ? 3:0)) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1)))))) );
  98509. + registerMax = (((((gctUINT32) (specs)) >> (0 ? 7:4)) & ((gctUINT32) ((((1 ? 7:4) - (0 ? 7:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:4) - (0 ? 7:4) + 1)))))) );
  98510. + threadCount = (((((gctUINT32) (specs)) >> (0 ? 11:8)) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1)))))) );
  98511. + shaderCoreCount = (((((gctUINT32) (specs)) >> (0 ? 24:20)) & ((gctUINT32) ((((1 ? 24:20) - (0 ? 24:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:20) - (0 ? 24:20) + 1)))))) );
  98512. + vertexCacheSize = (((((gctUINT32) (specs)) >> (0 ? 16:12)) & ((gctUINT32) ((((1 ? 16:12) - (0 ? 16:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:12) - (0 ? 16:12) + 1)))))) );
  98513. + vertexOutputBufferSize = (((((gctUINT32) (specs)) >> (0 ? 31:28)) & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1)))))) );
  98514. + pixelPipes = (((((gctUINT32) (specs)) >> (0 ? 27:25)) & ((gctUINT32) ((((1 ? 27:25) - (0 ? 27:25) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:25) - (0 ? 27:25) + 1)))))) );
  98515. +
  98516. + /* Read gcChipSpecs2 register. */
  98517. + gcmkONERROR(
  98518. + gckOS_ReadRegisterEx(Os, Core,
  98519. + 0x00080,
  98520. + &specs2));
  98521. +
  98522. + instructionCount = (((((gctUINT32) (specs2)) >> (0 ? 15:8)) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1)))))) );
  98523. + numConstants = (((((gctUINT32) (specs2)) >> (0 ? 31:16)) & ((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1)))))) );
  98524. + bufferSize = (((((gctUINT32) (specs2)) >> (0 ? 7:0)) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1)))))) );
  98525. +
  98526. + /* Read gcChipSpecs3 register. */
  98527. + gcmkONERROR(
  98528. + gckOS_ReadRegisterEx(Os, Core,
  98529. + 0x0008C,
  98530. + &specs3));
  98531. +
  98532. + varyingsCount = (((((gctUINT32) (specs3)) >> (0 ? 8:4)) & ((gctUINT32) ((((1 ? 8:4) - (0 ? 8:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:4) - (0 ? 8:4) + 1)))))) );
  98533. + }
  98534. +
  98535. + /* Get the number of pixel pipes. */
  98536. + Identity->pixelPipes = gcmMAX(pixelPipes, 1);
  98537. +
  98538. + /* Get the stream count. */
  98539. + Identity->streamCount = (streamCount != 0)
  98540. + ? streamCount
  98541. + : (Identity->chipModel >= gcv1000) ? 4 : 1;
  98542. +
  98543. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98544. + "Specs: streamCount=%u%s",
  98545. + Identity->streamCount,
  98546. + (streamCount == 0) ? " (default)" : "");
  98547. +
  98548. + /* Get the vertex output buffer size. */
  98549. + Identity->vertexOutputBufferSize = (vertexOutputBufferSize != 0)
  98550. + ? 1 << vertexOutputBufferSize
  98551. + : (Identity->chipModel == gcv400)
  98552. + ? (Identity->chipRevision < 0x4000) ? 512
  98553. + : (Identity->chipRevision < 0x4200) ? 256
  98554. + : 128
  98555. + : (Identity->chipModel == gcv530)
  98556. + ? (Identity->chipRevision < 0x4200) ? 512
  98557. + : 128
  98558. + : 512;
  98559. +
  98560. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98561. + "Specs: vertexOutputBufferSize=%u%s",
  98562. + Identity->vertexOutputBufferSize,
  98563. + (vertexOutputBufferSize == 0) ? " (default)" : "");
  98564. +
  98565. + /* Get the maximum number of threads. */
  98566. + Identity->threadCount = (threadCount != 0)
  98567. + ? 1 << threadCount
  98568. + : (Identity->chipModel == gcv400) ? 64
  98569. + : (Identity->chipModel == gcv500) ? 128
  98570. + : (Identity->chipModel == gcv530) ? 128
  98571. + : 256;
  98572. +
  98573. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98574. + "Specs: threadCount=%u%s",
  98575. + Identity->threadCount,
  98576. + (threadCount == 0) ? " (default)" : "");
  98577. +
  98578. + /* Get the number of shader cores. */
  98579. + Identity->shaderCoreCount = (shaderCoreCount != 0)
  98580. + ? shaderCoreCount
  98581. + : (Identity->chipModel >= gcv1000) ? 2
  98582. + : 1;
  98583. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98584. + "Specs: shaderCoreCount=%u%s",
  98585. + Identity->shaderCoreCount,
  98586. + (shaderCoreCount == 0) ? " (default)" : "");
  98587. +
  98588. + /* Get the vertex cache size. */
  98589. + Identity->vertexCacheSize = (vertexCacheSize != 0)
  98590. + ? vertexCacheSize
  98591. + : 8;
  98592. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98593. + "Specs: vertexCacheSize=%u%s",
  98594. + Identity->vertexCacheSize,
  98595. + (vertexCacheSize == 0) ? " (default)" : "");
  98596. +
  98597. + /* Get the maximum number of temporary registers. */
  98598. + Identity->registerMax = (registerMax != 0)
  98599. + /* Maximum of registerMax/4 registers are accessible to 1 shader */
  98600. + ? 1 << registerMax
  98601. + : (Identity->chipModel == gcv400) ? 32
  98602. + : 64;
  98603. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98604. + "Specs: registerMax=%u%s",
  98605. + Identity->registerMax,
  98606. + (registerMax == 0) ? " (default)" : "");
  98607. +
  98608. + /* Get the instruction count. */
  98609. + Identity->instructionCount = (instructionCount == 0) ? 256
  98610. + : (instructionCount == 1) ? 1024
  98611. + : (instructionCount == 2) ? 2048
  98612. + : (instructionCount == 0xFF) ? 512
  98613. + : 256;
  98614. +
  98615. + if (Identity->instructionCount == 256)
  98616. + {
  98617. + if ((Identity->chipModel == gcv2000 && Identity->chipRevision == 0x5108)
  98618. + || Identity->chipModel == gcv880)
  98619. + {
  98620. + Identity->instructionCount = 512;
  98621. + }
  98622. + }
  98623. +
  98624. + if (((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))))
  98625. + {
  98626. + Identity->instructionCount = 512;
  98627. + }
  98628. +
  98629. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98630. + "Specs: instructionCount=%u%s",
  98631. + Identity->instructionCount,
  98632. + (instructionCount == 0) ? " (default)" : "");
  98633. +
  98634. + /* Get the number of constants. */
  98635. + Identity->numConstants = (numConstants == 0) ? 168 : numConstants;
  98636. +
  98637. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98638. + "Specs: numConstants=%u%s",
  98639. + Identity->numConstants,
  98640. + (numConstants == 0) ? " (default)" : "");
  98641. +
  98642. + /* Get the buffer size. */
  98643. + Identity->bufferSize = bufferSize;
  98644. +
  98645. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98646. + "Specs: bufferSize=%u%s",
  98647. + Identity->bufferSize,
  98648. + (bufferSize == 0) ? " (default)" : "");
  98649. +
  98650. +
  98651. + if (varyingsCount != 0)
  98652. + {
  98653. + /* Bug 4480. */
  98654. + /*Identity->varyingsCount = varyingsCount;*/
  98655. + Identity->varyingsCount = 12;
  98656. + }
  98657. + else if (((((gctUINT32) (Identity->chipMinorFeatures1)) >> (0 ? 23:23) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))))
  98658. + {
  98659. + Identity->varyingsCount = 12;
  98660. + }
  98661. + else
  98662. + {
  98663. + Identity->varyingsCount = 8;
  98664. + }
  98665. +
  98666. + /* For some cores, it consumes two varying for position, so the max varying vectors should minus one. */
  98667. + if ((Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5222) ||
  98668. + (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5208) ||
  98669. + ((Identity->chipModel == gcv2100 || Identity->chipModel == gcv2000) && Identity->chipRevision == 0x5108) ||
  98670. + (Identity->chipModel == gcv880 && (Identity->chipRevision == 0x5107 || Identity->chipRevision == 0x5106)))
  98671. + {
  98672. + Identity->varyingsCount -= 1;
  98673. + }
  98674. +
  98675. + Identity->chip2DControl = 0;
  98676. + if (Identity->chipModel == gcv320)
  98677. + {
  98678. + gctUINT32 data;
  98679. +
  98680. + gcmkONERROR(
  98681. + gckOS_ReadRegisterEx(Os,
  98682. + Core,
  98683. + 0x0002C,
  98684. + &data));
  98685. +
  98686. + if ((data != 33956864) &&
  98687. + ((Identity->chipRevision == 0x5007) ||
  98688. + (Identity->chipRevision == 0x5220)))
  98689. + {
  98690. + Identity->chip2DControl |= 0xFF &
  98691. + (Identity->chipRevision == 0x5220 ? 8 :
  98692. + (Identity->chipRevision == 0x5007 ? 12 : 0));
  98693. + }
  98694. +
  98695. + if (Identity->chipRevision == 0x5007)
  98696. + {
  98697. + /* Disable splitting rectangle. */
  98698. + Identity->chip2DControl |= 0x100;
  98699. +
  98700. + /* Enable 2D Flush. */
  98701. + Identity->chip2DControl |= 0x200;
  98702. + }
  98703. + }
  98704. +
  98705. + /* Success. */
  98706. + gcmkFOOTER();
  98707. + return gcvSTATUS_OK;
  98708. +
  98709. +OnError:
  98710. + /* Return the status. */
  98711. + gcmkFOOTER();
  98712. + return status;
  98713. +}
  98714. +
  98715. +#if gcdPOWEROFF_TIMEOUT
  98716. +void
  98717. +_PowerTimerFunction(
  98718. + gctPOINTER Data
  98719. + )
  98720. +{
  98721. + gckHARDWARE hardware = (gckHARDWARE)Data;
  98722. + gcmkVERIFY_OK(
  98723. + gckHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
  98724. +}
  98725. +#endif
  98726. +
  98727. +static gceSTATUS
  98728. +_VerifyDMA(
  98729. + IN gckOS Os,
  98730. + IN gceCORE Core,
  98731. + gctUINT32_PTR Address1,
  98732. + gctUINT32_PTR Address2,
  98733. + gctUINT32_PTR State1,
  98734. + gctUINT32_PTR State2
  98735. + )
  98736. +{
  98737. + gceSTATUS status;
  98738. + gctUINT32 i;
  98739. +
  98740. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x660, State1));
  98741. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x664, Address1));
  98742. +
  98743. + for (i = 0; i < 500; i += 1)
  98744. + {
  98745. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x660, State2));
  98746. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x664, Address2));
  98747. +
  98748. + if (*Address1 != *Address2)
  98749. + {
  98750. + break;
  98751. + }
  98752. +
  98753. + if (*State1 != *State2)
  98754. + {
  98755. + break;
  98756. + }
  98757. + }
  98758. +
  98759. +OnError:
  98760. + return status;
  98761. +}
  98762. +
  98763. +static gceSTATUS
  98764. +_DumpDebugRegisters(
  98765. + IN gckOS Os,
  98766. + IN gceCORE Core,
  98767. + IN gcsiDEBUG_REGISTERS_PTR Descriptor
  98768. + )
  98769. +{
  98770. + gceSTATUS status = gcvSTATUS_OK;
  98771. + gctUINT32 select;
  98772. + gctUINT32 data = 0;
  98773. + gctUINT i;
  98774. +
  98775. + gcmkHEADER_ARG("Os=0x%X Descriptor=0x%X", Os, Descriptor);
  98776. +
  98777. + gcmkPRINT_N(4, " %s debug registers:\n", Descriptor->module);
  98778. +
  98779. + for (i = 0; i < Descriptor->count; i += 1)
  98780. + {
  98781. + select = i << Descriptor->shift;
  98782. +
  98783. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, select));
  98784. +#if gcdFPGA_BUILD
  98785. + gcmkONERROR(gckOS_Delay(Os, 1000));
  98786. +#endif
  98787. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &data));
  98788. +
  98789. + gcmkPRINT_N(12, " [0x%02X] 0x%08X\n", i, data);
  98790. + }
  98791. +
  98792. + select = 0xF << Descriptor->shift;
  98793. +
  98794. + for (i = 0; i < 500; i += 1)
  98795. + {
  98796. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, select));
  98797. +#if gcdFPGA_BUILD
  98798. + gcmkONERROR(gckOS_Delay(Os, 1000));
  98799. +#endif
  98800. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &data));
  98801. +
  98802. + if (data == Descriptor->signature)
  98803. + {
  98804. + break;
  98805. + }
  98806. + }
  98807. +
  98808. + if (i == 500)
  98809. + {
  98810. + gcmkPRINT_N(4, " failed to obtain the signature (read 0x%08X).\n", data);
  98811. + }
  98812. + else
  98813. + {
  98814. + gcmkPRINT_N(8, " signature = 0x%08X (%d read attempt(s))\n", data, i + 1);
  98815. + }
  98816. +
  98817. +OnError:
  98818. + /* Return the error. */
  98819. + gcmkFOOTER();
  98820. + return status;
  98821. +}
  98822. +
  98823. +static gceSTATUS
  98824. +_IsGPUPresent(
  98825. + IN gckHARDWARE Hardware
  98826. + )
  98827. +{
  98828. + gceSTATUS status;
  98829. + gcsHAL_QUERY_CHIP_IDENTITY identity;
  98830. + gctUINT32 control;
  98831. +
  98832. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  98833. +
  98834. + /* Verify the arguments. */
  98835. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  98836. +
  98837. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  98838. + Hardware->core,
  98839. + 0x00000,
  98840. + &control));
  98841. +
  98842. + control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)));
  98843. + control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
  98844. +
  98845. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  98846. + Hardware->core,
  98847. + 0x00000,
  98848. + control));
  98849. +
  98850. + /* Identify the hardware. */
  98851. + gcmkONERROR(_IdentifyHardware(Hardware->os,
  98852. + Hardware->core,
  98853. + &identity));
  98854. +
  98855. + /* Check if these are the same values as saved before. */
  98856. + if ((Hardware->identity.chipModel != identity.chipModel)
  98857. + || (Hardware->identity.chipRevision != identity.chipRevision)
  98858. + || (Hardware->identity.chipFeatures != identity.chipFeatures)
  98859. + || (Hardware->identity.chipMinorFeatures != identity.chipMinorFeatures)
  98860. + || (Hardware->identity.chipMinorFeatures1 != identity.chipMinorFeatures1)
  98861. + || (Hardware->identity.chipMinorFeatures2 != identity.chipMinorFeatures2)
  98862. + )
  98863. + {
  98864. + gcmkPRINT("[galcore]: GPU is not present.");
  98865. + gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
  98866. + }
  98867. +
  98868. + /* Success. */
  98869. + gcmkFOOTER_NO();
  98870. + return gcvSTATUS_OK;
  98871. +
  98872. +OnError:
  98873. + /* Return the error. */
  98874. + gcmkFOOTER();
  98875. + return status;
  98876. +}
  98877. +
  98878. +gceSTATUS
  98879. +_FlushCache(
  98880. + gckHARDWARE Hardware,
  98881. + gckCOMMAND Command
  98882. + )
  98883. +{
  98884. + gceSTATUS status;
  98885. + gctSIZE_T bytes, requested;
  98886. + gctPOINTER buffer;
  98887. +
  98888. + /* Get the size of the flush command. */
  98889. + gcmkONERROR(gckHARDWARE_Flush(Hardware,
  98890. + gcvFLUSH_ALL,
  98891. + gcvNULL,
  98892. + &requested));
  98893. +
  98894. + /* Reserve space in the command queue. */
  98895. + gcmkONERROR(gckCOMMAND_Reserve(Command,
  98896. + requested,
  98897. + &buffer,
  98898. + &bytes));
  98899. +
  98900. + /* Append a flush. */
  98901. + gcmkONERROR(gckHARDWARE_Flush(
  98902. + Hardware, gcvFLUSH_ALL, buffer, &bytes
  98903. + ));
  98904. +
  98905. + /* Execute the command queue. */
  98906. + gcmkONERROR(gckCOMMAND_Execute(Command, requested));
  98907. +
  98908. + return gcvSTATUS_OK;
  98909. +
  98910. +OnError:
  98911. + return status;
  98912. +}
  98913. +
  98914. +/******************************************************************************\
  98915. +****************************** gckHARDWARE API code *****************************
  98916. +\******************************************************************************/
  98917. +
  98918. +/*******************************************************************************
  98919. +**
  98920. +** gckHARDWARE_Construct
  98921. +**
  98922. +** Construct a new gckHARDWARE object.
  98923. +**
  98924. +** INPUT:
  98925. +**
  98926. +** gckOS Os
  98927. +** Pointer to an initialized gckOS object.
  98928. +**
  98929. +** gceCORE Core
  98930. +** Specified core.
  98931. +**
  98932. +** OUTPUT:
  98933. +**
  98934. +** gckHARDWARE * Hardware
  98935. +** Pointer to a variable that will hold the pointer to the gckHARDWARE
  98936. +** object.
  98937. +*/
  98938. +gceSTATUS
  98939. +gckHARDWARE_Construct(
  98940. + IN gckOS Os,
  98941. + IN gceCORE Core,
  98942. + OUT gckHARDWARE * Hardware
  98943. + )
  98944. +{
  98945. + gceSTATUS status;
  98946. + gckHARDWARE hardware = gcvNULL;
  98947. + gctUINT16 data = 0xff00;
  98948. + gctUINT32 axi_ot;
  98949. + gctPOINTER pointer = gcvNULL;
  98950. +
  98951. + gcmkHEADER_ARG("Os=0x%x", Os);
  98952. +
  98953. + /* Verify the arguments. */
  98954. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  98955. + gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
  98956. +
  98957. + /* Enable the GPU. */
  98958. + gcmkONERROR(gckOS_SetGPUPower(Os, Core, gcvTRUE, gcvTRUE));
  98959. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  98960. + Core,
  98961. + 0x00000,
  98962. + 0x00000900));
  98963. +
  98964. + /* Allocate the gckHARDWARE object. */
  98965. + gcmkONERROR(gckOS_Allocate(Os,
  98966. + gcmSIZEOF(struct _gckHARDWARE),
  98967. + &pointer));
  98968. +
  98969. + hardware = (gckHARDWARE) pointer;
  98970. +
  98971. + /* Initialize the gckHARDWARE object. */
  98972. + hardware->object.type = gcvOBJ_HARDWARE;
  98973. + hardware->os = Os;
  98974. + hardware->core = Core;
  98975. +
  98976. + /* Identify the hardware. */
  98977. + gcmkONERROR(_IdentifyHardware(Os, Core, &hardware->identity));
  98978. +
  98979. + /* Determine the hardware type */
  98980. + switch (hardware->identity.chipModel)
  98981. + {
  98982. + case gcv350:
  98983. + case gcv355:
  98984. + hardware->type = gcvHARDWARE_VG;
  98985. + break;
  98986. +
  98987. + case gcv300:
  98988. + case gcv320:
  98989. + case gcv420:
  98990. + hardware->type = gcvHARDWARE_2D;
  98991. + /*set outstanding limit*/
  98992. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
  98993. + axi_ot = (axi_ot & (~0xFF)) | 0x10;
  98994. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot));
  98995. + break;
  98996. +
  98997. + default:
  98998. + hardware->type = gcvHARDWARE_3D;
  98999. + if(hardware->identity.chipModel == gcv880)
  99000. + {
  99001. + /*set outstanding limit*/
  99002. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
  99003. + axi_ot = (axi_ot & (~0xFF)) | 0x10;
  99004. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot));
  99005. + }
  99006. +
  99007. + if ((((((gctUINT32) (hardware->identity.chipFeatures)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) ))
  99008. + {
  99009. + hardware->type = (gceHARDWARE_TYPE) (hardware->type | gcvHARDWARE_2D);
  99010. + }
  99011. + }
  99012. +
  99013. + hardware->powerBaseAddress
  99014. + = ((hardware->identity.chipModel == gcv300)
  99015. + && (hardware->identity.chipRevision < 0x2000))
  99016. + ? 0x0100
  99017. + : 0x0000;
  99018. +
  99019. + /* _ResetGPU need powerBaseAddress. */
  99020. + status = _ResetGPU(hardware, Os, Core);
  99021. +
  99022. + if (status != gcvSTATUS_OK)
  99023. + {
  99024. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  99025. + "_ResetGPU failed: status=%d\n", status);
  99026. + }
  99027. +
  99028. + hardware->powerMutex = gcvNULL;
  99029. +
  99030. + hardware->mmuVersion
  99031. + = (((((gctUINT32) (hardware->identity.chipMinorFeatures1)) >> (0 ? 28:28)) & ((gctUINT32) ((((1 ? 28:28) - (0 ? 28:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 28:28) - (0 ? 28:28) + 1)))))) );
  99032. +
  99033. + /* Determine whether bug fixes #1 are present. */
  99034. + hardware->extraEventStates = ((((gctUINT32) (hardware->identity.chipMinorFeatures1)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x0 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))));
  99035. +
  99036. + /* Check if big endian */
  99037. + hardware->bigEndian = (*(gctUINT8 *)&data == 0xff);
  99038. +
  99039. + /* Initialize the fast clear. */
  99040. + gcmkONERROR(gckHARDWARE_SetFastClear(hardware, -1, -1));
  99041. +
  99042. +#if !gcdENABLE_128B_MERGE
  99043. +
  99044. + if (((((gctUINT32) (hardware->identity.chipMinorFeatures2)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))))
  99045. + {
  99046. + /* 128B merge is turned on by default. Disable it. */
  99047. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00558, 0));
  99048. + }
  99049. +
  99050. +#endif
  99051. +
  99052. + /* Set power state to ON. */
  99053. + hardware->chipPowerState = gcvPOWER_ON;
  99054. + hardware->clockState = gcvTRUE;
  99055. + hardware->powerState = gcvTRUE;
  99056. + hardware->lastWaitLink = ~0U;
  99057. + hardware->globalSemaphore = gcvNULL;
  99058. +#if gcdENABLE_FSCALE_VAL_ADJUST
  99059. + hardware->powerOnFscaleVal = 64;
  99060. +#endif
  99061. +
  99062. + gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerMutex));
  99063. + gcmkONERROR(gckOS_CreateSemaphore(Os, &hardware->globalSemaphore));
  99064. + hardware->startIsr = gcvNULL;
  99065. + hardware->stopIsr = gcvNULL;
  99066. +
  99067. +#if gcdPOWEROFF_TIMEOUT
  99068. + hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
  99069. +
  99070. + gcmkVERIFY_OK(gckOS_CreateTimer(Os,
  99071. + _PowerTimerFunction,
  99072. + (gctPOINTER)hardware,
  99073. + &hardware->powerOffTimer));
  99074. +#endif
  99075. +
  99076. + gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
  99077. +
  99078. +#if gcdLINK_QUEUE_SIZE
  99079. + hardware->linkQueue.front = 0;
  99080. + hardware->linkQueue.rear = 0;
  99081. + hardware->linkQueue.count = 0;
  99082. +#endif
  99083. +
  99084. + /* Enable power management by default. */
  99085. + hardware->powerManagement = gcvTRUE;
  99086. +
  99087. + /* Disable profiler by default */
  99088. + hardware->gpuProfiler = gcvFALSE;
  99089. +
  99090. + /* Return pointer to the gckHARDWARE object. */
  99091. + *Hardware = hardware;
  99092. +
  99093. + /* Success. */
  99094. + gcmkFOOTER_ARG("*Hardware=0x%x", *Hardware);
  99095. + return gcvSTATUS_OK;
  99096. +
  99097. +OnError:
  99098. + /* Roll back. */
  99099. + if (hardware != gcvNULL)
  99100. + {
  99101. + /* Turn off the power. */
  99102. + gcmkVERIFY_OK(gckOS_SetGPUPower(Os, Core, gcvFALSE, gcvFALSE));
  99103. +
  99104. + if (hardware->globalSemaphore != gcvNULL)
  99105. + {
  99106. + /* Destroy the global semaphore. */
  99107. + gcmkVERIFY_OK(gckOS_DestroySemaphore(Os,
  99108. + hardware->globalSemaphore));
  99109. + }
  99110. +
  99111. + if (hardware->powerMutex != gcvNULL)
  99112. + {
  99113. + /* Destroy the power mutex. */
  99114. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, hardware->powerMutex));
  99115. + }
  99116. +
  99117. +#if gcdPOWEROFF_TIMEOUT
  99118. + if (hardware->powerOffTimer != gcvNULL)
  99119. + {
  99120. + gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
  99121. + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
  99122. + }
  99123. +#endif
  99124. +
  99125. + if (hardware->pageTableDirty != gcvNULL)
  99126. + {
  99127. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
  99128. + }
  99129. +
  99130. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, hardware));
  99131. + }
  99132. +
  99133. + /* Return the status. */
  99134. + gcmkFOOTER();
  99135. + return status;
  99136. +}
  99137. +
  99138. +/*******************************************************************************
  99139. +**
  99140. +** gckHARDWARE_Destroy
  99141. +**
  99142. +** Destroy an gckHARDWARE object.
  99143. +**
  99144. +** INPUT:
  99145. +**
  99146. +** gckHARDWARE Hardware
  99147. +** Pointer to the gckHARDWARE object that needs to be destroyed.
  99148. +**
  99149. +** OUTPUT:
  99150. +**
  99151. +** Nothing.
  99152. +*/
  99153. +gceSTATUS
  99154. +gckHARDWARE_Destroy(
  99155. + IN gckHARDWARE Hardware
  99156. + )
  99157. +{
  99158. + gceSTATUS status;
  99159. +
  99160. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  99161. +
  99162. + /* Verify the arguments. */
  99163. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99164. +
  99165. + /* Destroy the power semaphore. */
  99166. + gcmkVERIFY_OK(gckOS_DestroySemaphore(Hardware->os,
  99167. + Hardware->globalSemaphore));
  99168. +
  99169. + /* Destroy the power mutex. */
  99170. + gcmkVERIFY_OK(gckOS_DeleteMutex(Hardware->os, Hardware->powerMutex));
  99171. +
  99172. +#if gcdPOWEROFF_TIMEOUT
  99173. + gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
  99174. + gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
  99175. +#endif
  99176. +
  99177. + gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
  99178. +
  99179. + /* Mark the object as unknown. */
  99180. + Hardware->object.type = gcvOBJ_UNKNOWN;
  99181. +
  99182. + /* Free the object. */
  99183. + gcmkONERROR(gcmkOS_SAFE_FREE(Hardware->os, Hardware));
  99184. +
  99185. + /* Success. */
  99186. + gcmkFOOTER_NO();
  99187. + return gcvSTATUS_OK;
  99188. +
  99189. +OnError:
  99190. + gcmkFOOTER();
  99191. + return status;
  99192. +}
  99193. +
  99194. +/*******************************************************************************
  99195. +**
  99196. +** gckHARDWARE_GetType
  99197. +**
  99198. +** Get the hardware type.
  99199. +**
  99200. +** INPUT:
  99201. +**
  99202. +** gckHARDWARE Harwdare
  99203. +** Pointer to an gckHARDWARE object.
  99204. +**
  99205. +** OUTPUT:
  99206. +**
  99207. +** gceHARDWARE_TYPE * Type
  99208. +** Pointer to a variable that receives the type of hardware object.
  99209. +*/
  99210. +gceSTATUS
  99211. +gckHARDWARE_GetType(
  99212. + IN gckHARDWARE Hardware,
  99213. + OUT gceHARDWARE_TYPE * Type
  99214. + )
  99215. +{
  99216. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  99217. + gcmkVERIFY_ARGUMENT(Type != gcvNULL);
  99218. +
  99219. + *Type = Hardware->type;
  99220. +
  99221. + gcmkFOOTER_ARG("*Type=%d", *Type);
  99222. + return gcvSTATUS_OK;
  99223. +}
  99224. +
  99225. +/*******************************************************************************
  99226. +**
  99227. +** gckHARDWARE_InitializeHardware
  99228. +**
  99229. +** Initialize the hardware.
  99230. +**
  99231. +** INPUT:
  99232. +**
  99233. +** gckHARDWARE Hardware
  99234. +** Pointer to the gckHARDWARE object.
  99235. +**
  99236. +** OUTPUT:
  99237. +**
  99238. +** Nothing.
  99239. +*/
  99240. +gceSTATUS
  99241. +gckHARDWARE_InitializeHardware(
  99242. + IN gckHARDWARE Hardware
  99243. + )
  99244. +{
  99245. + gceSTATUS status;
  99246. + gctUINT32 baseAddress;
  99247. + gctUINT32 chipRev;
  99248. + gctUINT32 control;
  99249. +
  99250. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  99251. +
  99252. + /* Verify the arguments. */
  99253. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99254. +
  99255. + /* Read the chip revision register. */
  99256. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  99257. + Hardware->core,
  99258. + 0x00024,
  99259. + &chipRev));
  99260. +
  99261. + if (chipRev != Hardware->identity.chipRevision)
  99262. + {
  99263. + /* Chip is not there! */
  99264. + gcmkONERROR(gcvSTATUS_CONTEXT_LOSSED);
  99265. + }
  99266. +
  99267. + /* Disable isolate GPU bit. */
  99268. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99269. + Hardware->core,
  99270. + 0x00000,
  99271. + ((((gctUINT32) (0x00000900)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)))));
  99272. +
  99273. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  99274. + Hardware->core,
  99275. + 0x00000,
  99276. + &control));
  99277. +
  99278. + /* Enable debug register. */
  99279. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99280. + Hardware->core,
  99281. + 0x00000,
  99282. + ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)))));
  99283. +
  99284. + /* Reset memory counters. */
  99285. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99286. + Hardware->core,
  99287. + 0x0003C,
  99288. + ~0U));
  99289. +
  99290. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99291. + Hardware->core,
  99292. + 0x0003C,
  99293. + 0));
  99294. +
  99295. + /* Get the system's physical base address. */
  99296. + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  99297. +
  99298. + /* Program the base addesses. */
  99299. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99300. + Hardware->core,
  99301. + 0x0041C,
  99302. + baseAddress));
  99303. +
  99304. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99305. + Hardware->core,
  99306. + 0x00418,
  99307. + baseAddress));
  99308. +
  99309. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99310. + Hardware->core,
  99311. + 0x00428,
  99312. + baseAddress));
  99313. +
  99314. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99315. + Hardware->core,
  99316. + 0x00420,
  99317. + baseAddress));
  99318. +
  99319. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99320. + Hardware->core,
  99321. + 0x00424,
  99322. + baseAddress));
  99323. +
  99324. +#if !VIVANTE_PROFILER
  99325. + {
  99326. + gctUINT32 data;
  99327. +
  99328. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  99329. + Hardware->core,
  99330. + Hardware->powerBaseAddress +
  99331. + 0x00100,
  99332. + &data));
  99333. +
  99334. + /* Enable clock gating. */
  99335. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
  99336. +
  99337. + if ((Hardware->identity.chipRevision == 0x4301)
  99338. + || (Hardware->identity.chipRevision == 0x4302)
  99339. + )
  99340. + {
  99341. + /* Disable stall module level clock gating for 4.3.0.1 and 4.3.0.2
  99342. + ** revisions. */
  99343. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)));
  99344. + }
  99345. +
  99346. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99347. + Hardware->core,
  99348. + Hardware->powerBaseAddress
  99349. + + 0x00100,
  99350. + data));
  99351. +
  99352. +#ifndef VIVANTE_NO_3D
  99353. + /* Disable PE clock gating on revs < 5.0 when HZ is present without a
  99354. + ** bug fix. */
  99355. + if ((Hardware->identity.chipRevision < 0x5000)
  99356. + && ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 9:9) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) == (0x0 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))))
  99357. + && ((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))))
  99358. + )
  99359. + {
  99360. + gcmkONERROR(
  99361. + gckOS_ReadRegisterEx(Hardware->os,
  99362. + Hardware->core,
  99363. + Hardware->powerBaseAddress
  99364. + + 0x00104,
  99365. + &data));
  99366. +
  99367. + /* Disable PE clock gating. */
  99368. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
  99369. +
  99370. + gcmkONERROR(
  99371. + gckOS_WriteRegisterEx(Hardware->os,
  99372. + Hardware->core,
  99373. + Hardware->powerBaseAddress
  99374. + + 0x00104,
  99375. + data));
  99376. + }
  99377. +
  99378. +#endif
  99379. + }
  99380. +#endif
  99381. +
  99382. + /* Special workaround for this core
  99383. + ** Make sure pulse eater kicks in only when SH is idle */
  99384. + if (Hardware->identity.chipModel == gcv4000 &&
  99385. + Hardware->identity.chipRevision == 0x5208)
  99386. + {
  99387. + gcmkONERROR(
  99388. + gckOS_WriteRegisterEx(Hardware->os,
  99389. + Hardware->core,
  99390. + 0x0010C,
  99391. + ((((gctUINT32) (0x01590880)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23)))));
  99392. + }
  99393. +
  99394. + if ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) == gcvFALSE)
  99395. + || (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) && (Hardware->identity.chipRevision < 0x5422))
  99396. + )
  99397. + {
  99398. + gctUINT32 data;
  99399. +
  99400. + gcmkONERROR(
  99401. + gckOS_ReadRegisterEx(Hardware->os,
  99402. + Hardware->core,
  99403. + Hardware->powerBaseAddress
  99404. + + 0x00104,
  99405. + &data));
  99406. +
  99407. +
  99408. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15)));
  99409. +
  99410. +
  99411. + gcmkONERROR(
  99412. + gckOS_WriteRegisterEx(Hardware->os,
  99413. + Hardware->core,
  99414. + Hardware->powerBaseAddress
  99415. + + 0x00104,
  99416. + data));
  99417. + }
  99418. +
  99419. + /* Special workaround for this core
  99420. + ** Make sure FE and TX are on different buses */
  99421. + if ((Hardware->identity.chipModel == gcv2000)
  99422. + && (Hardware->identity.chipRevision == 0x5108))
  99423. + {
  99424. + gctUINT32 data;
  99425. +
  99426. + gcmkONERROR(
  99427. + gckOS_ReadRegisterEx(Hardware->os,
  99428. + Hardware->core,
  99429. + 0x00480,
  99430. + &data));
  99431. +
  99432. + /* Set FE bus to one, TX bus to zero */
  99433. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
  99434. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
  99435. +
  99436. + gcmkONERROR(
  99437. + gckOS_WriteRegisterEx(Hardware->os,
  99438. + Hardware->core,
  99439. + 0x00480,
  99440. + data));
  99441. + }
  99442. +
  99443. + /* Test if MMU is initialized. */
  99444. + if ((Hardware->kernel != gcvNULL)
  99445. + && (Hardware->kernel->mmu != gcvNULL)
  99446. + )
  99447. + {
  99448. + /* Reset MMU. */
  99449. + if (Hardware->mmuVersion == 0)
  99450. + {
  99451. + gcmkONERROR(
  99452. + gckHARDWARE_SetMMU(Hardware,
  99453. + Hardware->kernel->mmu->pageTableLogical));
  99454. + }
  99455. + }
  99456. +
  99457. + if (Hardware->identity.chipModel >= gcv400
  99458. + && Hardware->identity.chipModel != gcv420
  99459. + && (((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 15:15) & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) != gcvTRUE)
  99460. + )
  99461. + {
  99462. + gctUINT32 data;
  99463. +
  99464. + gcmkONERROR(
  99465. + gckOS_ReadRegisterEx(Hardware->os,
  99466. + Hardware->core,
  99467. + Hardware->powerBaseAddress
  99468. + + 0x00104,
  99469. + &data));
  99470. +
  99471. + /* Disable PA clock gating. */
  99472. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
  99473. +
  99474. + gcmkONERROR(
  99475. + gckOS_WriteRegisterEx(Hardware->os,
  99476. + Hardware->core,
  99477. + Hardware->powerBaseAddress
  99478. + + 0x00104,
  99479. + data));
  99480. + }
  99481. +
  99482. +#if gcdHZ_L2_DISALBE
  99483. + /* Disable HZ-L2. */
  99484. + if (((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) == gcvTRUE ||
  99485. + ((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) == gcvTRUE)
  99486. + {
  99487. + gctUINT32 data;
  99488. +
  99489. + gcmkONERROR(
  99490. + gckOS_ReadRegisterEx(Hardware->os,
  99491. + Hardware->core,
  99492. + 0x00414,
  99493. + &data));
  99494. +
  99495. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)));
  99496. +
  99497. + gcmkONERROR(
  99498. + gckOS_WriteRegisterEx(Hardware->os,
  99499. + Hardware->core,
  99500. + 0x00414,
  99501. + data));
  99502. + }
  99503. +#endif
  99504. +
  99505. + /* Limit 2D outstanding request. */
  99506. + if(Hardware->identity.chipModel == gcv880)
  99507. + {
  99508. + gctUINT32 axi_ot;
  99509. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &axi_ot));
  99510. + axi_ot = (axi_ot & (~0xFF)) | 0x10;
  99511. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00414, axi_ot));
  99512. + }
  99513. +
  99514. + if (Hardware->identity.chip2DControl & 0xFF)
  99515. + {
  99516. + gctUINT32 data;
  99517. +
  99518. + gcmkONERROR(
  99519. + gckOS_ReadRegisterEx(Hardware->os,
  99520. + Hardware->core,
  99521. + 0x00414,
  99522. + &data));
  99523. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (Hardware->identity.chip2DControl & 0xFF) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)));
  99524. +
  99525. + gcmkONERROR(
  99526. + gckOS_WriteRegisterEx(Hardware->os,
  99527. + Hardware->core,
  99528. + 0x00414,
  99529. + data));
  99530. + }
  99531. +
  99532. + /* Update GPU AXI cache atttribute. */
  99533. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99534. + Hardware->core,
  99535. + 0x00008,
  99536. + 0x00002200));
  99537. +
  99538. + /* Success. */
  99539. + gcmkFOOTER_NO();
  99540. + return gcvSTATUS_OK;
  99541. +
  99542. +OnError:
  99543. + /* Return the error. */
  99544. + gcmkFOOTER();
  99545. + return status;
  99546. +}
  99547. +
  99548. +/*******************************************************************************
  99549. +**
  99550. +** gckHARDWARE_QueryMemory
  99551. +**
  99552. +** Query the amount of memory available on the hardware.
  99553. +**
  99554. +** INPUT:
  99555. +**
  99556. +** gckHARDWARE Hardware
  99557. +** Pointer to the gckHARDWARE object.
  99558. +**
  99559. +** OUTPUT:
  99560. +**
  99561. +** gctSIZE_T * InternalSize
  99562. +** Pointer to a variable that will hold the size of the internal video
  99563. +** memory in bytes. If 'InternalSize' is gcvNULL, no information of the
  99564. +** internal memory will be returned.
  99565. +**
  99566. +** gctUINT32 * InternalBaseAddress
  99567. +** Pointer to a variable that will hold the hardware's base address for
  99568. +** the internal video memory. This pointer cannot be gcvNULL if
  99569. +** 'InternalSize' is also non-gcvNULL.
  99570. +**
  99571. +** gctUINT32 * InternalAlignment
  99572. +** Pointer to a variable that will hold the hardware's base address for
  99573. +** the internal video memory. This pointer cannot be gcvNULL if
  99574. +** 'InternalSize' is also non-gcvNULL.
  99575. +**
  99576. +** gctSIZE_T * ExternalSize
  99577. +** Pointer to a variable that will hold the size of the external video
  99578. +** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the
  99579. +** external memory will be returned.
  99580. +**
  99581. +** gctUINT32 * ExternalBaseAddress
  99582. +** Pointer to a variable that will hold the hardware's base address for
  99583. +** the external video memory. This pointer cannot be gcvNULL if
  99584. +** 'ExternalSize' is also non-gcvNULL.
  99585. +**
  99586. +** gctUINT32 * ExternalAlignment
  99587. +** Pointer to a variable that will hold the hardware's base address for
  99588. +** the external video memory. This pointer cannot be gcvNULL if
  99589. +** 'ExternalSize' is also non-gcvNULL.
  99590. +**
  99591. +** gctUINT32 * HorizontalTileSize
  99592. +** Number of horizontal pixels per tile. If 'HorizontalTileSize' is
  99593. +** gcvNULL, no horizontal pixel per tile will be returned.
  99594. +**
  99595. +** gctUINT32 * VerticalTileSize
  99596. +** Number of vertical pixels per tile. If 'VerticalTileSize' is
  99597. +** gcvNULL, no vertical pixel per tile will be returned.
  99598. +*/
  99599. +gceSTATUS
  99600. +gckHARDWARE_QueryMemory(
  99601. + IN gckHARDWARE Hardware,
  99602. + OUT gctSIZE_T * InternalSize,
  99603. + OUT gctUINT32 * InternalBaseAddress,
  99604. + OUT gctUINT32 * InternalAlignment,
  99605. + OUT gctSIZE_T * ExternalSize,
  99606. + OUT gctUINT32 * ExternalBaseAddress,
  99607. + OUT gctUINT32 * ExternalAlignment,
  99608. + OUT gctUINT32 * HorizontalTileSize,
  99609. + OUT gctUINT32 * VerticalTileSize
  99610. + )
  99611. +{
  99612. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  99613. +
  99614. + /* Verify the arguments. */
  99615. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99616. +
  99617. + if (InternalSize != gcvNULL)
  99618. + {
  99619. + /* No internal memory. */
  99620. + *InternalSize = 0;
  99621. + }
  99622. +
  99623. + if (ExternalSize != gcvNULL)
  99624. + {
  99625. + /* No external memory. */
  99626. + *ExternalSize = 0;
  99627. + }
  99628. +
  99629. + if (HorizontalTileSize != gcvNULL)
  99630. + {
  99631. + /* 4x4 tiles. */
  99632. + *HorizontalTileSize = 4;
  99633. + }
  99634. +
  99635. + if (VerticalTileSize != gcvNULL)
  99636. + {
  99637. + /* 4x4 tiles. */
  99638. + *VerticalTileSize = 4;
  99639. + }
  99640. +
  99641. + /* Success. */
  99642. + gcmkFOOTER_ARG("*InternalSize=%lu *InternalBaseAddress=0x%08x "
  99643. + "*InternalAlignment=0x%08x *ExternalSize=%lu "
  99644. + "*ExternalBaseAddress=0x%08x *ExtenalAlignment=0x%08x "
  99645. + "*HorizontalTileSize=%u *VerticalTileSize=%u",
  99646. + gcmOPT_VALUE(InternalSize),
  99647. + gcmOPT_VALUE(InternalBaseAddress),
  99648. + gcmOPT_VALUE(InternalAlignment),
  99649. + gcmOPT_VALUE(ExternalSize),
  99650. + gcmOPT_VALUE(ExternalBaseAddress),
  99651. + gcmOPT_VALUE(ExternalAlignment),
  99652. + gcmOPT_VALUE(HorizontalTileSize),
  99653. + gcmOPT_VALUE(VerticalTileSize));
  99654. + return gcvSTATUS_OK;
  99655. +}
  99656. +
  99657. +/*******************************************************************************
  99658. +**
  99659. +** gckHARDWARE_QueryChipIdentity
  99660. +**
  99661. +** Query the identity of the hardware.
  99662. +**
  99663. +** INPUT:
  99664. +**
  99665. +** gckHARDWARE Hardware
  99666. +** Pointer to the gckHARDWARE object.
  99667. +**
  99668. +** OUTPUT:
  99669. +**
  99670. +** gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  99671. +** Pointer to the identity structure.
  99672. +**
  99673. +*/
  99674. +gceSTATUS
  99675. +gckHARDWARE_QueryChipIdentity(
  99676. + IN gckHARDWARE Hardware,
  99677. + OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  99678. + )
  99679. +{
  99680. + gctUINT32 features;
  99681. +
  99682. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  99683. +
  99684. + /* Verify the arguments. */
  99685. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99686. + gcmkVERIFY_ARGUMENT(Identity != gcvNULL);
  99687. +
  99688. + /* Return chip model and revision. */
  99689. + Identity->chipModel = Hardware->identity.chipModel;
  99690. + Identity->chipRevision = Hardware->identity.chipRevision;
  99691. +
  99692. + /* Return feature set. */
  99693. + features = Hardware->identity.chipFeatures;
  99694. +
  99695. + if ((((((gctUINT32) (features)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  99696. + {
  99697. + /* Override fast clear by command line. */
  99698. + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (Hardware->allowFastClear) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
  99699. + }
  99700. +
  99701. + if ((((((gctUINT32) (features)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ))
  99702. + {
  99703. + /* Override compression by command line. */
  99704. + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) ((gctUINT32) (Hardware->allowCompression) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
  99705. + }
  99706. +
  99707. + /* Mark 2D pipe as available for GC500.0 through GC500.2 and GC300,
  99708. + ** since they did not have this bit. */
  99709. + if (((Hardware->identity.chipModel == gcv500) && (Hardware->identity.chipRevision <= 2))
  99710. + || (Hardware->identity.chipModel == gcv300)
  99711. + )
  99712. + {
  99713. + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
  99714. + }
  99715. +
  99716. + Identity->chipFeatures = features;
  99717. +
  99718. + /* Return minor features. */
  99719. + Identity->chipMinorFeatures = Hardware->identity.chipMinorFeatures;
  99720. + Identity->chipMinorFeatures1 = Hardware->identity.chipMinorFeatures1;
  99721. + Identity->chipMinorFeatures2 = Hardware->identity.chipMinorFeatures2;
  99722. + Identity->chipMinorFeatures3 = Hardware->identity.chipMinorFeatures3;
  99723. + Identity->chipMinorFeatures4 = Hardware->identity.chipMinorFeatures4;
  99724. +
  99725. + /* Return chip specs. */
  99726. + Identity->streamCount = Hardware->identity.streamCount;
  99727. + Identity->registerMax = Hardware->identity.registerMax;
  99728. + Identity->threadCount = Hardware->identity.threadCount;
  99729. + Identity->shaderCoreCount = Hardware->identity.shaderCoreCount;
  99730. + Identity->vertexCacheSize = Hardware->identity.vertexCacheSize;
  99731. + Identity->vertexOutputBufferSize = Hardware->identity.vertexOutputBufferSize;
  99732. + Identity->pixelPipes = Hardware->identity.pixelPipes;
  99733. + Identity->instructionCount = Hardware->identity.instructionCount;
  99734. + Identity->numConstants = Hardware->identity.numConstants;
  99735. + Identity->bufferSize = Hardware->identity.bufferSize;
  99736. + Identity->varyingsCount = Hardware->identity.varyingsCount;
  99737. + Identity->superTileMode = Hardware->identity.superTileMode;
  99738. + Identity->chip2DControl = Hardware->identity.chip2DControl;
  99739. +
  99740. + /* Success. */
  99741. + gcmkFOOTER_NO();
  99742. + return gcvSTATUS_OK;
  99743. +}
  99744. +
  99745. +/*******************************************************************************
  99746. +**
  99747. +** gckHARDWARE_SplitMemory
  99748. +**
  99749. +** Split a hardware specific memory address into a pool and offset.
  99750. +**
  99751. +** INPUT:
  99752. +**
  99753. +** gckHARDWARE Hardware
  99754. +** Pointer to the gckHARDWARE object.
  99755. +**
  99756. +** gctUINT32 Address
  99757. +** Address in hardware specific format.
  99758. +**
  99759. +** OUTPUT:
  99760. +**
  99761. +** gcePOOL * Pool
  99762. +** Pointer to a variable that will hold the pool type for the address.
  99763. +**
  99764. +** gctUINT32 * Offset
  99765. +** Pointer to a variable that will hold the offset for the address.
  99766. +*/
  99767. +gceSTATUS
  99768. +gckHARDWARE_SplitMemory(
  99769. + IN gckHARDWARE Hardware,
  99770. + IN gctUINT32 Address,
  99771. + OUT gcePOOL * Pool,
  99772. + OUT gctUINT32 * Offset
  99773. + )
  99774. +{
  99775. + gcmkHEADER_ARG("Hardware=0x%x Addres=0x%08x", Hardware, Address);
  99776. +
  99777. + /* Verify the arguments. */
  99778. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99779. + gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
  99780. + gcmkVERIFY_ARGUMENT(Offset != gcvNULL);
  99781. +
  99782. + if (Hardware->mmuVersion == 0)
  99783. + {
  99784. + /* Dispatch on memory type. */
  99785. + switch ((((((gctUINT32) (Address)) >> (0 ? 31:31)) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) ))
  99786. + {
  99787. + case 0x0:
  99788. + /* System memory. */
  99789. + *Pool = gcvPOOL_SYSTEM;
  99790. + break;
  99791. +
  99792. + case 0x1:
  99793. + /* Virtual memory. */
  99794. + *Pool = gcvPOOL_VIRTUAL;
  99795. + break;
  99796. +
  99797. + default:
  99798. + /* Invalid memory type. */
  99799. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  99800. + return gcvSTATUS_INVALID_ARGUMENT;
  99801. + }
  99802. +
  99803. + /* Return offset of address. */
  99804. + *Offset = (((((gctUINT32) (Address)) >> (0 ? 30:0)) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1)))))) );
  99805. + }
  99806. + else
  99807. + {
  99808. + *Pool = gcvPOOL_SYSTEM;
  99809. + *Offset = Address;
  99810. + }
  99811. +
  99812. + /* Success. */
  99813. + gcmkFOOTER_ARG("*Pool=%d *Offset=0x%08x", *Pool, *Offset);
  99814. + return gcvSTATUS_OK;
  99815. +}
  99816. +
  99817. +/*******************************************************************************
  99818. +**
  99819. +** gckHARDWARE_Execute
  99820. +**
  99821. +** Kickstart the hardware's command processor with an initialized command
  99822. +** buffer.
  99823. +**
  99824. +** INPUT:
  99825. +**
  99826. +** gckHARDWARE Hardware
  99827. +** Pointer to the gckHARDWARE object.
  99828. +**
  99829. +** gctPOINTER Logical
  99830. +** Logical address of command buffer.
  99831. +**
  99832. +** gctSIZE_T Bytes
  99833. +** Number of bytes for the prefetch unit (until after the first LINK).
  99834. +**
  99835. +** OUTPUT:
  99836. +**
  99837. +** Nothing.
  99838. +*/
  99839. +gceSTATUS
  99840. +gckHARDWARE_Execute(
  99841. + IN gckHARDWARE Hardware,
  99842. + IN gctPOINTER Logical,
  99843. +#ifdef __QNXNTO__
  99844. + IN gctPOINTER Physical,
  99845. + IN gctBOOL PhysicalAddresses,
  99846. +#endif
  99847. + IN gctSIZE_T Bytes
  99848. + )
  99849. +{
  99850. + gceSTATUS status;
  99851. + gctUINT32 address = 0, control;
  99852. +
  99853. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Bytes=%lu",
  99854. + Hardware, Logical, Bytes);
  99855. +
  99856. + /* Verify the arguments. */
  99857. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99858. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  99859. +
  99860. +#ifdef __QNXNTO__
  99861. + if (PhysicalAddresses && (Hardware->mmuVersion == 0))
  99862. + {
  99863. + /* Convert physical into hardware specific address. */
  99864. + gcmkONERROR(
  99865. + gckHARDWARE_ConvertPhysical(Hardware, Physical, &address));
  99866. + }
  99867. + else
  99868. + {
  99869. +#endif
  99870. + /* Convert logical into hardware specific address. */
  99871. + gcmkONERROR(
  99872. + gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
  99873. +#ifdef __QNXNTO__
  99874. + }
  99875. +#endif
  99876. +
  99877. + /* Enable all events. */
  99878. + gcmkONERROR(
  99879. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U));
  99880. +
  99881. + /* Write address register. */
  99882. + gcmkONERROR(
  99883. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, address));
  99884. +
  99885. + /* Build control register. */
  99886. + control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
  99887. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  99888. +
  99889. + /* Set big endian */
  99890. + if (Hardware->bigEndian)
  99891. + {
  99892. + control |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 21:20) - (0 ? 21:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ? 21:20) - (0 ? 21:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20)));
  99893. + }
  99894. +
  99895. + /* Write control register. */
  99896. + gcmkONERROR(
  99897. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
  99898. +
  99899. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  99900. + "Started command buffer @ 0x%08x",
  99901. + address);
  99902. +
  99903. + /* Success. */
  99904. + gcmkFOOTER_NO();
  99905. + return gcvSTATUS_OK;
  99906. +
  99907. +OnError:
  99908. + /* Return the status. */
  99909. + gcmkFOOTER();
  99910. + return status;
  99911. +}
  99912. +
  99913. +/*******************************************************************************
  99914. +**
  99915. +** gckHARDWARE_WaitLink
  99916. +**
  99917. +** Append a WAIT/LINK command sequence at the specified location in the command
  99918. +** queue.
  99919. +**
  99920. +** INPUT:
  99921. +**
  99922. +** gckHARDWARE Hardware
  99923. +** Pointer to an gckHARDWARE object.
  99924. +**
  99925. +** gctPOINTER Logical
  99926. +** Pointer to the current location inside the command queue to append
  99927. +** WAIT/LINK command sequence at or gcvNULL just to query the size of the
  99928. +** WAIT/LINK command sequence.
  99929. +**
  99930. +** gctUINT32 Offset
  99931. +** Offset into command buffer required for alignment.
  99932. +**
  99933. +** gctSIZE_T * Bytes
  99934. +** Pointer to the number of bytes available for the WAIT/LINK command
  99935. +** sequence. If 'Logical' is gcvNULL, this argument will be ignored.
  99936. +**
  99937. +** OUTPUT:
  99938. +**
  99939. +** gctSIZE_T * Bytes
  99940. +** Pointer to a variable that will receive the number of bytes required
  99941. +** by the WAIT/LINK command sequence. If 'Bytes' is gcvNULL, nothing will
  99942. +** be returned.
  99943. +**
  99944. +** gctUINT32 * WaitOffset
  99945. +** Pointer to a variable that will receive the offset of the WAIT command
  99946. +** from the specified logcial pointer.
  99947. +** If 'WaitOffset' is gcvNULL nothing will be returned.
  99948. +**
  99949. +** gctSIZE_T * WaitSize
  99950. +** Pointer to a variable that will receive the number of bytes used by
  99951. +** the WAIT command. If 'LinkSize' is gcvNULL nothing will be returned.
  99952. +*/
  99953. +gceSTATUS
  99954. +gckHARDWARE_WaitLink(
  99955. + IN gckHARDWARE Hardware,
  99956. + IN gctPOINTER Logical,
  99957. + IN gctUINT32 Offset,
  99958. + IN OUT gctSIZE_T * Bytes,
  99959. + OUT gctUINT32 * WaitOffset,
  99960. + OUT gctSIZE_T * WaitSize
  99961. + )
  99962. +{
  99963. + static const gctUINT waitCount = 200;
  99964. +
  99965. + gceSTATUS status;
  99966. + gctUINT32 address;
  99967. + gctUINT32_PTR logical;
  99968. + gctSIZE_T bytes;
  99969. +
  99970. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x *Bytes=%lu",
  99971. + Hardware, Logical, Offset, gcmOPT_VALUE(Bytes));
  99972. +
  99973. + /* Verify the arguments. */
  99974. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99975. + gcmkVERIFY_ARGUMENT((Logical != gcvNULL) || (Bytes != gcvNULL));
  99976. +
  99977. + /* Compute number of bytes required. */
  99978. +#if gcd6000_SUPPORT
  99979. + bytes = gcmALIGN(Offset + 96, 8) - Offset;
  99980. +#else
  99981. + bytes = gcmALIGN(Offset + 16, 8) - Offset;
  99982. +#endif
  99983. +
  99984. + /* Cast the input pointer. */
  99985. + logical = (gctUINT32_PTR) Logical;
  99986. +
  99987. + if (logical != gcvNULL)
  99988. + {
  99989. + /* Not enough space? */
  99990. + if (*Bytes < bytes)
  99991. + {
  99992. + /* Command queue too small. */
  99993. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  99994. + }
  99995. +
  99996. + /* Convert logical into hardware specific address. */
  99997. + gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, &address));
  99998. +
  99999. + /* Store the WAIT/LINK address. */
  100000. + Hardware->lastWaitLink = address;
  100001. +
  100002. + /* Append WAIT(count). */
  100003. + logical[0]
  100004. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100005. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (waitCount) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  100006. +
  100007. +#if gcd6000_SUPPORT
  100008. + /* Send FE-PE sempahore token. */
  100009. + logical[2]
  100010. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100011. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  100012. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  100013. +
  100014. + logical[3]
  100015. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  100016. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  100017. +
  100018. + /* Send FE-PE stall token. */
  100019. + logical[4]
  100020. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  100021. +
  100022. + logical[5]
  100023. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  100024. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  100025. +
  100026. + /*************************************************************/
  100027. + /* Enable chip ID 0. */
  100028. + logical[6] =
  100029. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100030. + | (1 << 0);
  100031. +
  100032. + /* Send semaphore from FE to ChipID 1. */
  100033. + logical[8] =
  100034. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100035. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  100036. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  100037. +
  100038. + logical[9] =
  100039. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  100040. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
  100041. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
  100042. +
  100043. + /* Send semaphore from FE to ChipID 1. */
  100044. + logical[10] =
  100045. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  100046. +
  100047. + logical[11] =
  100048. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  100049. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
  100050. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
  100051. +
  100052. + /*************************************************************/
  100053. + /* Enable chip ID 1. */
  100054. + logical[12] =
  100055. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100056. + | (1 << 1);
  100057. +
  100058. + /* Send semaphore from FE to ChipID 1. */
  100059. + logical[14] =
  100060. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100061. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  100062. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  100063. +
  100064. + logical[15] =
  100065. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  100066. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
  100067. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
  100068. +
  100069. + /* Wait for semaphore from ChipID 0. */
  100070. + logical[16] =
  100071. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  100072. +
  100073. + logical[17] =
  100074. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  100075. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
  100076. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
  100077. +
  100078. + /*************************************************************/
  100079. + /* Enable all chips. */
  100080. + logical[18] =
  100081. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100082. + | (0xFFFF);
  100083. +
  100084. + /* LoadState(AQFlush, 1), flush. */
  100085. + logical[20]
  100086. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100087. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  100088. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  100089. +
  100090. + logical[21]
  100091. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
  100092. +
  100093. + /* Append LINK(2, address). */
  100094. + logical[22]
  100095. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100096. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  100097. +
  100098. + logical[23] = address;
  100099. +#else
  100100. + /* Append LINK(2, address). */
  100101. + logical[2]
  100102. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100103. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  100104. +
  100105. + logical[3] = address;
  100106. +
  100107. + gcmkTRACE_ZONE(
  100108. + gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100109. + "0x%08x: WAIT %u", address, waitCount
  100110. + );
  100111. +
  100112. + gcmkTRACE_ZONE(
  100113. + gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100114. + "0x%08x: LINK 0x%08x, #%lu",
  100115. + address + 8, address, bytes
  100116. + );
  100117. +#endif
  100118. +
  100119. + if (WaitOffset != gcvNULL)
  100120. + {
  100121. + /* Return the offset pointer to WAIT command. */
  100122. + *WaitOffset = 0;
  100123. + }
  100124. +
  100125. + if (WaitSize != gcvNULL)
  100126. + {
  100127. + /* Return number of bytes used by the WAIT command. */
  100128. + *WaitSize = 8;
  100129. + }
  100130. + }
  100131. +
  100132. + if (Bytes != gcvNULL)
  100133. + {
  100134. + /* Return number of bytes required by the WAIT/LINK command
  100135. + ** sequence. */
  100136. + *Bytes = bytes;
  100137. + }
  100138. +
  100139. + /* Success. */
  100140. + gcmkFOOTER_ARG("*Bytes=%lu *WaitOffset=0x%x *WaitSize=%lu",
  100141. + gcmOPT_VALUE(Bytes), gcmOPT_VALUE(WaitOffset),
  100142. + gcmOPT_VALUE(WaitSize));
  100143. + return gcvSTATUS_OK;
  100144. +
  100145. +OnError:
  100146. + /* Return the status. */
  100147. + gcmkFOOTER();
  100148. + return status;
  100149. +}
  100150. +
  100151. +/*******************************************************************************
  100152. +**
  100153. +** gckHARDWARE_End
  100154. +**
  100155. +** Append an END command at the specified location in the command queue.
  100156. +**
  100157. +** INPUT:
  100158. +**
  100159. +** gckHARDWARE Hardware
  100160. +** Pointer to an gckHARDWARE object.
  100161. +**
  100162. +** gctPOINTER Logical
  100163. +** Pointer to the current location inside the command queue to append
  100164. +** END command at or gcvNULL just to query the size of the END command.
  100165. +**
  100166. +** gctSIZE_T * Bytes
  100167. +** Pointer to the number of bytes available for the END command. If
  100168. +** 'Logical' is gcvNULL, this argument will be ignored.
  100169. +**
  100170. +** OUTPUT:
  100171. +**
  100172. +** gctSIZE_T * Bytes
  100173. +** Pointer to a variable that will receive the number of bytes required
  100174. +** for the END command. If 'Bytes' is gcvNULL, nothing will be returned.
  100175. +*/
  100176. +gceSTATUS
  100177. +gckHARDWARE_End(
  100178. + IN gckHARDWARE Hardware,
  100179. + IN gctPOINTER Logical,
  100180. + IN OUT gctSIZE_T * Bytes
  100181. + )
  100182. +{
  100183. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  100184. + gceSTATUS status;
  100185. +
  100186. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
  100187. + Hardware, Logical, gcmOPT_VALUE(Bytes));
  100188. +
  100189. + /* Verify the arguments. */
  100190. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100191. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100192. +
  100193. + if (Logical != gcvNULL)
  100194. + {
  100195. + if (*Bytes < 8)
  100196. + {
  100197. + /* Command queue too small. */
  100198. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100199. + }
  100200. +
  100201. + /* Append END. */
  100202. + logical[0] =
  100203. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  100204. +
  100205. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: END", Logical);
  100206. +
  100207. + /* Make sure the CPU writes out the data to memory. */
  100208. + gcmkONERROR(
  100209. + gckOS_MemoryBarrier(Hardware->os, Logical));
  100210. + }
  100211. +
  100212. + if (Bytes != gcvNULL)
  100213. + {
  100214. + /* Return number of bytes required by the END command. */
  100215. + *Bytes = 8;
  100216. + }
  100217. +
  100218. + /* Success. */
  100219. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100220. + return gcvSTATUS_OK;
  100221. +
  100222. +OnError:
  100223. + /* Return the status. */
  100224. + gcmkFOOTER();
  100225. + return status;
  100226. +}
  100227. +
  100228. +/*******************************************************************************
  100229. +**
  100230. +** gckHARDWARE_Nop
  100231. +**
  100232. +** Append a NOP command at the specified location in the command queue.
  100233. +**
  100234. +** INPUT:
  100235. +**
  100236. +** gckHARDWARE Hardware
  100237. +** Pointer to an gckHARDWARE object.
  100238. +**
  100239. +** gctPOINTER Logical
  100240. +** Pointer to the current location inside the command queue to append
  100241. +** NOP command at or gcvNULL just to query the size of the NOP command.
  100242. +**
  100243. +** gctSIZE_T * Bytes
  100244. +** Pointer to the number of bytes available for the NOP command. If
  100245. +** 'Logical' is gcvNULL, this argument will be ignored.
  100246. +**
  100247. +** OUTPUT:
  100248. +**
  100249. +** gctSIZE_T * Bytes
  100250. +** Pointer to a variable that will receive the number of bytes required
  100251. +** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned.
  100252. +*/
  100253. +gceSTATUS
  100254. +gckHARDWARE_Nop(
  100255. + IN gckHARDWARE Hardware,
  100256. + IN gctPOINTER Logical,
  100257. + IN OUT gctSIZE_T * Bytes
  100258. + )
  100259. +{
  100260. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  100261. + gceSTATUS status;
  100262. +
  100263. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
  100264. + Hardware, Logical, gcmOPT_VALUE(Bytes));
  100265. +
  100266. + /* Verify the arguments. */
  100267. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100268. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100269. +
  100270. + if (Logical != gcvNULL)
  100271. + {
  100272. + if (*Bytes < 8)
  100273. + {
  100274. + /* Command queue too small. */
  100275. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100276. + }
  100277. +
  100278. + /* Append NOP. */
  100279. + logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  100280. +
  100281. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical);
  100282. + }
  100283. +
  100284. + if (Bytes != gcvNULL)
  100285. + {
  100286. + /* Return number of bytes required by the NOP command. */
  100287. + *Bytes = 8;
  100288. + }
  100289. +
  100290. + /* Success. */
  100291. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100292. + return gcvSTATUS_OK;
  100293. +
  100294. +OnError:
  100295. + /* Return the status. */
  100296. + gcmkFOOTER();
  100297. + return status;
  100298. +}
  100299. +
  100300. +/*******************************************************************************
  100301. +**
  100302. +** gckHARDWARE_Wait
  100303. +**
  100304. +** Append a WAIT command at the specified location in the command queue.
  100305. +**
  100306. +** INPUT:
  100307. +**
  100308. +** gckHARDWARE Hardware
  100309. +** Pointer to an gckHARDWARE object.
  100310. +**
  100311. +** gctPOINTER Logical
  100312. +** Pointer to the current location inside the command queue to append
  100313. +** WAIT command at or gcvNULL just to query the size of the WAIT command.
  100314. +**
  100315. +** gctUINT32 Count
  100316. +** Number of cycles to wait.
  100317. +**
  100318. +** gctSIZE_T * Bytes
  100319. +** Pointer to the number of bytes available for the WAIT command. If
  100320. +** 'Logical' is gcvNULL, this argument will be ignored.
  100321. +**
  100322. +** OUTPUT:
  100323. +**
  100324. +** gctSIZE_T * Bytes
  100325. +** Pointer to a variable that will receive the number of bytes required
  100326. +** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned.
  100327. +*/
  100328. +gceSTATUS
  100329. +gckHARDWARE_Wait(
  100330. + IN gckHARDWARE Hardware,
  100331. + IN gctPOINTER Logical,
  100332. + IN gctUINT32 Count,
  100333. + IN OUT gctSIZE_T * Bytes
  100334. + )
  100335. +{
  100336. + gceSTATUS status;
  100337. + gctUINT32_PTR logical;
  100338. +
  100339. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Count=%u *Bytes=%lu",
  100340. + Hardware, Logical, Count, gcmOPT_VALUE(Bytes));
  100341. +
  100342. + /* Verify the arguments. */
  100343. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100344. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100345. +
  100346. + /* Cast the input pointer. */
  100347. + logical = (gctUINT32_PTR) Logical;
  100348. +
  100349. + if (Logical != gcvNULL)
  100350. + {
  100351. + if (*Bytes < 8)
  100352. + {
  100353. + /* Command queue too small. */
  100354. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100355. + }
  100356. +
  100357. + /* Append WAIT. */
  100358. + logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100359. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  100360. +
  100361. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  100362. + {
  100363. + gctUINT32 address;
  100364. +
  100365. + /* Convert logical into hardware specific address. */
  100366. + gcmkONERROR(gckHARDWARE_ConvertLogical(
  100367. + Hardware, logical, &address
  100368. + ));
  100369. +
  100370. + gcmkTRACE_ZONE(
  100371. + gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100372. + "0x%08x: WAIT %u", address, Count
  100373. + );
  100374. + }
  100375. +#endif
  100376. + }
  100377. +
  100378. + if (Bytes != gcvNULL)
  100379. + {
  100380. + /* Return number of bytes required by the WAIT command. */
  100381. + *Bytes = 8;
  100382. + }
  100383. +
  100384. + /* Success. */
  100385. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100386. + return gcvSTATUS_OK;
  100387. +
  100388. +OnError:
  100389. + /* Return the status. */
  100390. + gcmkFOOTER();
  100391. + return status;
  100392. +}
  100393. +
  100394. +/*******************************************************************************
  100395. +**
  100396. +** gckHARDWARE_Event
  100397. +**
  100398. +** Append an EVENT command at the specified location in the command queue.
  100399. +**
  100400. +** INPUT:
  100401. +**
  100402. +** gckHARDWARE Hardware
  100403. +** Pointer to an gckHARDWARE object.
  100404. +**
  100405. +** gctPOINTER Logical
  100406. +** Pointer to the current location inside the command queue to append
  100407. +** the EVENT command at or gcvNULL just to query the size of the EVENT
  100408. +** command.
  100409. +**
  100410. +** gctUINT8 Event
  100411. +** Event ID to program.
  100412. +**
  100413. +** gceKERNEL_WHERE FromWhere
  100414. +** Location of the pipe to send the event.
  100415. +**
  100416. +** gctSIZE_T * Bytes
  100417. +** Pointer to the number of bytes available for the EVENT command. If
  100418. +** 'Logical' is gcvNULL, this argument will be ignored.
  100419. +**
  100420. +** OUTPUT:
  100421. +**
  100422. +** gctSIZE_T * Bytes
  100423. +** Pointer to a variable that will receive the number of bytes required
  100424. +** for the EVENT command. If 'Bytes' is gcvNULL, nothing will be
  100425. +** returned.
  100426. +*/
  100427. +gceSTATUS
  100428. +gckHARDWARE_Event(
  100429. + IN gckHARDWARE Hardware,
  100430. + IN gctPOINTER Logical,
  100431. + IN gctUINT8 Event,
  100432. + IN gceKERNEL_WHERE FromWhere,
  100433. + IN OUT gctSIZE_T * Bytes
  100434. + )
  100435. +{
  100436. + gctUINT size;
  100437. + gctUINT32 destination = 0;
  100438. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  100439. + gceSTATUS status;
  100440. +
  100441. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Event=%u FromWhere=%d *Bytes=%lu",
  100442. + Hardware, Logical, Event, FromWhere, gcmOPT_VALUE(Bytes));
  100443. +
  100444. + /* Verify the arguments. */
  100445. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100446. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100447. + gcmkVERIFY_ARGUMENT(Event < 32);
  100448. +
  100449. + /* Determine the size of the command. */
  100450. +
  100451. + size = (Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL))
  100452. + ? gcmALIGN(8 + (1 + 5) * 4, 8) /* EVENT + 5 STATES */
  100453. + : 8;
  100454. +
  100455. + if (Logical != gcvNULL)
  100456. + {
  100457. + if (*Bytes < size)
  100458. + {
  100459. + /* Command queue too small. */
  100460. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100461. + }
  100462. +
  100463. + switch (FromWhere)
  100464. + {
  100465. + case gcvKERNEL_COMMAND:
  100466. + /* From command processor. */
  100467. + destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
  100468. + break;
  100469. +
  100470. + case gcvKERNEL_PIXEL:
  100471. + /* From pixel engine. */
  100472. + destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
  100473. + break;
  100474. +
  100475. + default:
  100476. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  100477. + }
  100478. +
  100479. + /* Append EVENT(Event, destiantion). */
  100480. + logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100481. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  100482. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  100483. +
  100484. + logical[1] = ((((gctUINT32) (destination)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (Event) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
  100485. +
  100486. + /* Make sure the event ID gets written out before GPU can access it. */
  100487. + gcmkONERROR(
  100488. + gckOS_MemoryBarrier(Hardware->os, logical + 1));
  100489. +
  100490. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  100491. + {
  100492. + gctUINT32 phys;
  100493. + gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys);
  100494. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100495. + "0x%08x: EVENT %d", phys, Event);
  100496. + }
  100497. +#endif
  100498. +
  100499. + /* Append the extra states. These are needed for the chips that do not
  100500. + ** support back-to-back events due to the async interface. The extra
  100501. + ** states add the necessary delay to ensure that event IDs do not
  100502. + ** collide. */
  100503. + if (size > 8)
  100504. + {
  100505. + logical[2] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100506. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0100) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  100507. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  100508. + logical[3] = 0;
  100509. + logical[4] = 0;
  100510. + logical[5] = 0;
  100511. + logical[6] = 0;
  100512. + logical[7] = 0;
  100513. + }
  100514. + }
  100515. +
  100516. + if (Bytes != gcvNULL)
  100517. + {
  100518. + /* Return number of bytes required by the EVENT command. */
  100519. + *Bytes = size;
  100520. + }
  100521. +
  100522. + /* Success. */
  100523. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100524. + return gcvSTATUS_OK;
  100525. +
  100526. +OnError:
  100527. + /* Return the status. */
  100528. + gcmkFOOTER();
  100529. + return status;
  100530. +}
  100531. +
  100532. +/*******************************************************************************
  100533. +**
  100534. +** gckHARDWARE_PipeSelect
  100535. +**
  100536. +** Append a PIPESELECT command at the specified location in the command queue.
  100537. +**
  100538. +** INPUT:
  100539. +**
  100540. +** gckHARDWARE Hardware
  100541. +** Pointer to an gckHARDWARE object.
  100542. +**
  100543. +** gctPOINTER Logical
  100544. +** Pointer to the current location inside the command queue to append
  100545. +** the PIPESELECT command at or gcvNULL just to query the size of the
  100546. +** PIPESELECT command.
  100547. +**
  100548. +** gcePIPE_SELECT Pipe
  100549. +** Pipe value to select.
  100550. +**
  100551. +** gctSIZE_T * Bytes
  100552. +** Pointer to the number of bytes available for the PIPESELECT command.
  100553. +** If 'Logical' is gcvNULL, this argument will be ignored.
  100554. +**
  100555. +** OUTPUT:
  100556. +**
  100557. +** gctSIZE_T * Bytes
  100558. +** Pointer to a variable that will receive the number of bytes required
  100559. +** for the PIPESELECT command. If 'Bytes' is gcvNULL, nothing will be
  100560. +** returned.
  100561. +*/
  100562. +gceSTATUS
  100563. +gckHARDWARE_PipeSelect(
  100564. + IN gckHARDWARE Hardware,
  100565. + IN gctPOINTER Logical,
  100566. + IN gcePIPE_SELECT Pipe,
  100567. + IN OUT gctSIZE_T * Bytes
  100568. + )
  100569. +{
  100570. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  100571. + gceSTATUS status;
  100572. +
  100573. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Pipe=%d *Bytes=%lu",
  100574. + Hardware, Logical, Pipe, gcmOPT_VALUE(Bytes));
  100575. +
  100576. + /* Verify the arguments. */
  100577. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100578. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100579. +
  100580. + /* Append a PipeSelect. */
  100581. + if (Logical != gcvNULL)
  100582. + {
  100583. + gctUINT32 flush, stall;
  100584. +
  100585. + if (*Bytes < 32)
  100586. + {
  100587. + /* Command queue too small. */
  100588. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100589. + }
  100590. +
  100591. + flush = (Pipe == gcvPIPE_2D)
  100592. + ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
  100593. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
  100594. + : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
  100595. +
  100596. + stall = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  100597. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  100598. +
  100599. + /* LoadState(AQFlush, 1), flush. */
  100600. + logical[0]
  100601. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100602. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  100603. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  100604. +
  100605. + logical[1]
  100606. + = flush;
  100607. +
  100608. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100609. + "0x%x: FLUSH 0x%x", logical, flush);
  100610. +
  100611. + /* LoadState(AQSempahore, 1), stall. */
  100612. + logical[2]
  100613. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100614. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  100615. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  100616. +
  100617. + logical[3]
  100618. + = stall;
  100619. +
  100620. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100621. + "0x%x: SEMAPHORE 0x%x", logical + 2, stall);
  100622. +
  100623. + /* Stall, stall. */
  100624. + logical[4] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  100625. + logical[5] = stall;
  100626. +
  100627. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100628. + "0x%x: STALL 0x%x", logical + 4, stall);
  100629. +
  100630. + /* LoadState(AQPipeSelect, 1), pipe. */
  100631. + logical[6]
  100632. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100633. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  100634. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  100635. +
  100636. + logical[7] = (Pipe == gcvPIPE_2D)
  100637. + ? 0x1
  100638. + : 0x0;
  100639. +
  100640. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100641. + "0x%x: PIPE %d", logical + 6, Pipe);
  100642. + }
  100643. +
  100644. + if (Bytes != gcvNULL)
  100645. + {
  100646. + /* Return number of bytes required by the PIPESELECT command. */
  100647. + *Bytes = 32;
  100648. + }
  100649. +
  100650. + /* Success. */
  100651. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100652. + return gcvSTATUS_OK;
  100653. +
  100654. +OnError:
  100655. + /* Return the status. */
  100656. + gcmkFOOTER();
  100657. + return status;
  100658. +}
  100659. +
  100660. +/*******************************************************************************
  100661. +**
  100662. +** gckHARDWARE_Link
  100663. +**
  100664. +** Append a LINK command at the specified location in the command queue.
  100665. +**
  100666. +** INPUT:
  100667. +**
  100668. +** gckHARDWARE Hardware
  100669. +** Pointer to an gckHARDWARE object.
  100670. +**
  100671. +** gctPOINTER Logical
  100672. +** Pointer to the current location inside the command queue to append
  100673. +** the LINK command at or gcvNULL just to query the size of the LINK
  100674. +** command.
  100675. +**
  100676. +** gctPOINTER FetchAddress
  100677. +** Logical address of destination of LINK.
  100678. +**
  100679. +** gctSIZE_T FetchSize
  100680. +** Number of bytes in destination of LINK.
  100681. +**
  100682. +** gctSIZE_T * Bytes
  100683. +** Pointer to the number of bytes available for the LINK command. If
  100684. +** 'Logical' is gcvNULL, this argument will be ignored.
  100685. +**
  100686. +** OUTPUT:
  100687. +**
  100688. +** gctSIZE_T * Bytes
  100689. +** Pointer to a variable that will receive the number of bytes required
  100690. +** for the LINK command. If 'Bytes' is gcvNULL, nothing will be returned.
  100691. +*/
  100692. +gceSTATUS
  100693. +gckHARDWARE_Link(
  100694. + IN gckHARDWARE Hardware,
  100695. + IN gctPOINTER Logical,
  100696. + IN gctPOINTER FetchAddress,
  100697. + IN gctSIZE_T FetchSize,
  100698. + IN OUT gctSIZE_T * Bytes
  100699. + )
  100700. +{
  100701. + gceSTATUS status;
  100702. + gctSIZE_T bytes;
  100703. + gctUINT32 address;
  100704. + gctUINT32 link;
  100705. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  100706. +
  100707. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x FetchAddress=0x%x FetchSize=%lu "
  100708. + "*Bytes=%lu",
  100709. + Hardware, Logical, FetchAddress, FetchSize,
  100710. + gcmOPT_VALUE(Bytes));
  100711. +
  100712. + /* Verify the arguments. */
  100713. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100714. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100715. +
  100716. + if (Logical != gcvNULL)
  100717. + {
  100718. + if (*Bytes < 8)
  100719. + {
  100720. + /* Command queue too small. */
  100721. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100722. + }
  100723. +
  100724. + /* Convert logical address to hardware address. */
  100725. + gcmkONERROR(
  100726. + gckHARDWARE_ConvertLogical(Hardware, FetchAddress, &address));
  100727. +
  100728. + gcmkONERROR(
  100729. + gckOS_WriteMemory(Hardware->os, logical + 1, address));
  100730. +
  100731. + /* Make sure the address got written before the LINK command. */
  100732. + gcmkONERROR(
  100733. + gckOS_MemoryBarrier(Hardware->os, logical + 1));
  100734. +
  100735. + /* Compute number of 64-byte aligned bytes to fetch. */
  100736. + bytes = gcmALIGN(address + FetchSize, 8) - address;
  100737. +
  100738. + /* Append LINK(bytes / 8), FetchAddress. */
  100739. + link = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  100740. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  100741. +
  100742. + gcmkONERROR(
  100743. + gckOS_WriteMemory(Hardware->os, logical, link));
  100744. +
  100745. + /* Memory barrier. */
  100746. + gcmkONERROR(
  100747. + gckOS_MemoryBarrier(Hardware->os, logical));
  100748. +
  100749. +#if gcdLINK_QUEUE_SIZE && gcdVIRTUAL_COMMAND_BUFFER
  100750. + if (address >= 0x80000000)
  100751. + {
  100752. + gckLINKQUEUE_Enqueue(&Hardware->linkQueue, address, address + bytes);
  100753. + }
  100754. +#endif
  100755. + }
  100756. +
  100757. + if (Bytes != gcvNULL)
  100758. + {
  100759. + /* Return number of bytes required by the LINK command. */
  100760. + *Bytes = 8;
  100761. + }
  100762. +
  100763. + /* Success. */
  100764. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100765. + return gcvSTATUS_OK;
  100766. +
  100767. +OnError:
  100768. + /* Return the status. */
  100769. + gcmkFOOTER();
  100770. + return status;
  100771. +}
  100772. +
  100773. +/*******************************************************************************
  100774. +**
  100775. +** gckHARDWARE_UpdateQueueTail
  100776. +**
  100777. +** Update the tail of the command queue.
  100778. +**
  100779. +** INPUT:
  100780. +**
  100781. +** gckHARDWARE Hardware
  100782. +** Pointer to an gckHARDWARE object.
  100783. +**
  100784. +** gctPOINTER Logical
  100785. +** Logical address of the start of the command queue.
  100786. +**
  100787. +** gctUINT32 Offset
  100788. +** Offset into the command queue of the tail (last command).
  100789. +**
  100790. +** OUTPUT:
  100791. +**
  100792. +** Nothing.
  100793. +*/
  100794. +gceSTATUS
  100795. +gckHARDWARE_UpdateQueueTail(
  100796. + IN gckHARDWARE Hardware,
  100797. + IN gctPOINTER Logical,
  100798. + IN gctUINT32 Offset
  100799. + )
  100800. +{
  100801. + gceSTATUS status;
  100802. +
  100803. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x",
  100804. + Hardware, Logical, Offset);
  100805. +
  100806. + /* Verify the hardware. */
  100807. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100808. +
  100809. + /* Force a barrier. */
  100810. + gcmkONERROR(
  100811. + gckOS_MemoryBarrier(Hardware->os, Logical));
  100812. +
  100813. + /* Notify gckKERNEL object of change. */
  100814. + gcmkONERROR(
  100815. + gckKERNEL_Notify(Hardware->kernel,
  100816. + gcvNOTIFY_COMMAND_QUEUE,
  100817. + gcvFALSE));
  100818. +
  100819. + if (status == gcvSTATUS_CHIP_NOT_READY)
  100820. + {
  100821. + gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
  100822. + }
  100823. +
  100824. + /* Success. */
  100825. + gcmkFOOTER_NO();
  100826. + return gcvSTATUS_OK;
  100827. +
  100828. +OnError:
  100829. + /* Return the status. */
  100830. + gcmkFOOTER();
  100831. + return status;
  100832. +}
  100833. +
  100834. +/*******************************************************************************
  100835. +**
  100836. +** gckHARDWARE_ConvertLogical
  100837. +**
  100838. +** Convert a logical system address into a hardware specific address.
  100839. +**
  100840. +** INPUT:
  100841. +**
  100842. +** gckHARDWARE Hardware
  100843. +** Pointer to an gckHARDWARE object.
  100844. +**
  100845. +** gctPOINTER Logical
  100846. +** Logical address to convert.
  100847. +**
  100848. +** gctUINT32* Address
  100849. +** Return hardware specific address.
  100850. +**
  100851. +** OUTPUT:
  100852. +**
  100853. +** Nothing.
  100854. +*/
  100855. +gceSTATUS
  100856. +gckHARDWARE_ConvertLogical(
  100857. + IN gckHARDWARE Hardware,
  100858. + IN gctPOINTER Logical,
  100859. + OUT gctUINT32 * Address
  100860. + )
  100861. +{
  100862. + gctUINT32 address;
  100863. + gceSTATUS status;
  100864. + gctUINT32 baseAddress;
  100865. +
  100866. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
  100867. +
  100868. + /* Verify the arguments. */
  100869. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100870. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  100871. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  100872. +
  100873. +#if gcdVIRTUAL_COMMAND_BUFFER
  100874. + status = gckKERNEL_GetGPUAddress(Hardware->kernel, Logical, Address);
  100875. +
  100876. + if (status == gcvSTATUS_INVALID_ADDRESS)
  100877. +#endif
  100878. + {
  100879. + /* Convert logical address into a physical address. */
  100880. + gcmkONERROR(
  100881. + gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
  100882. +
  100883. + /* For old MMU, get GPU address according to baseAddress. */
  100884. + if (Hardware->mmuVersion == 0)
  100885. + {
  100886. + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  100887. +
  100888. + /* Subtract base address to get a GPU address. */
  100889. + gcmkASSERT(address >= baseAddress);
  100890. + address -= baseAddress;
  100891. + }
  100892. +
  100893. + /* Return hardware specific address. */
  100894. + *Address = (Hardware->mmuVersion == 0)
  100895. + ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
  100896. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)))
  100897. + : address;
  100898. + }
  100899. +
  100900. + /* Success. */
  100901. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  100902. + return gcvSTATUS_OK;
  100903. +
  100904. +OnError:
  100905. + /* Return the status. */
  100906. + gcmkFOOTER();
  100907. + return status;
  100908. +}
  100909. +
  100910. +/*******************************************************************************
  100911. +**
  100912. +** gckHARDWARE_ConvertPhysical
  100913. +**
  100914. +** Convert a physical address into a hardware specific address.
  100915. +**
  100916. +** INPUT:
  100917. +**
  100918. +** gckHARDWARE Hardware
  100919. +** Pointer to an gckHARDWARE object.
  100920. +**
  100921. +** gctPHYS_ADDR Physical
  100922. +** Physical address to convert.
  100923. +**
  100924. +** gctUINT32* Address
  100925. +** Return hardware specific address.
  100926. +**
  100927. +** OUTPUT:
  100928. +**
  100929. +** Nothing.
  100930. +*/
  100931. +gceSTATUS
  100932. +gckHARDWARE_ConvertPhysical(
  100933. + IN gckHARDWARE Hardware,
  100934. + IN gctPHYS_ADDR Physical,
  100935. + OUT gctUINT32 * Address
  100936. + )
  100937. +{
  100938. + gctUINT32 address;
  100939. + gctUINT32 baseAddress;
  100940. +
  100941. + gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x", Hardware, Physical);
  100942. +
  100943. + /* Verify the arguments. */
  100944. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100945. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  100946. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  100947. +
  100948. + address = gcmPTR2INT(Physical);
  100949. +
  100950. + /* For old MMU, get GPU address according to baseAddress. */
  100951. + if (Hardware->mmuVersion == 0)
  100952. + {
  100953. + gcmkVERIFY_OK(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  100954. +
  100955. + /* Subtract base address to get a GPU address. */
  100956. + gcmkASSERT(address >= baseAddress);
  100957. + address -= baseAddress;
  100958. + }
  100959. +
  100960. + /* Return hardware specific address. */
  100961. + *Address = (Hardware->mmuVersion == 0)
  100962. + ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
  100963. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)))
  100964. + : address;
  100965. +
  100966. + /* Return the status. */
  100967. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  100968. + return gcvSTATUS_OK;
  100969. +}
  100970. +
  100971. +/*******************************************************************************
  100972. +**
  100973. +** gckHARDWARE_Interrupt
  100974. +**
  100975. +** Process an interrupt.
  100976. +**
  100977. +** INPUT:
  100978. +**
  100979. +** gckHARDWARE Hardware
  100980. +** Pointer to an gckHARDWARE object.
  100981. +**
  100982. +** gctBOOL InterruptValid
  100983. +** If gcvTRUE, this function will read the interrupt acknowledge
  100984. +** register, stores the data, and return whether or not the interrupt
  100985. +** is ours or not. If gcvFALSE, this functions will read the interrupt
  100986. +** acknowledge register and combine it with any stored value to handle
  100987. +** the event notifications.
  100988. +**
  100989. +** OUTPUT:
  100990. +**
  100991. +** Nothing.
  100992. +*/
  100993. +gceSTATUS
  100994. +gckHARDWARE_Interrupt(
  100995. + IN gckHARDWARE Hardware,
  100996. + IN gctBOOL InterruptValid
  100997. + )
  100998. +{
  100999. + gckEVENT eventObj;
  101000. + gctUINT32 data;
  101001. + gceSTATUS status;
  101002. +
  101003. + gcmkHEADER_ARG("Hardware=0x%x InterruptValid=%d", Hardware, InterruptValid);
  101004. +
  101005. + /* Verify the arguments. */
  101006. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101007. +
  101008. + /* Extract gckEVENT object. */
  101009. + eventObj = Hardware->kernel->eventObj;
  101010. + gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
  101011. +
  101012. + if (InterruptValid)
  101013. + {
  101014. + /* Read AQIntrAcknowledge register. */
  101015. + gcmkONERROR(
  101016. + gckOS_ReadRegisterEx(Hardware->os,
  101017. + Hardware->core,
  101018. + 0x00010,
  101019. + &data));
  101020. +
  101021. + if (data == 0)
  101022. + {
  101023. + /* Not our interrupt. */
  101024. + status = gcvSTATUS_NOT_OUR_INTERRUPT;
  101025. + }
  101026. + else
  101027. + {
  101028. + /* Inform gckEVENT of the interrupt. */
  101029. + status = gckEVENT_Interrupt(eventObj, data);
  101030. + }
  101031. + }
  101032. + else
  101033. + {
  101034. + /* Handle events. */
  101035. + status = gckEVENT_Notify(eventObj, 0);
  101036. + }
  101037. +
  101038. +OnError:
  101039. + /* Return the status. */
  101040. + gcmkFOOTER();
  101041. + return status;
  101042. +}
  101043. +
  101044. +/*******************************************************************************
  101045. +**
  101046. +** gckHARDWARE_QueryCommandBuffer
  101047. +**
  101048. +** Query the command buffer alignment and number of reserved bytes.
  101049. +**
  101050. +** INPUT:
  101051. +**
  101052. +** gckHARDWARE Harwdare
  101053. +** Pointer to an gckHARDWARE object.
  101054. +**
  101055. +** OUTPUT:
  101056. +**
  101057. +** gctSIZE_T * Alignment
  101058. +** Pointer to a variable receiving the alignment for each command.
  101059. +**
  101060. +** gctSIZE_T * ReservedHead
  101061. +** Pointer to a variable receiving the number of reserved bytes at the
  101062. +** head of each command buffer.
  101063. +**
  101064. +** gctSIZE_T * ReservedTail
  101065. +** Pointer to a variable receiving the number of bytes reserved at the
  101066. +** tail of each command buffer.
  101067. +*/
  101068. +gceSTATUS
  101069. +gckHARDWARE_QueryCommandBuffer(
  101070. + IN gckHARDWARE Hardware,
  101071. + OUT gctSIZE_T * Alignment,
  101072. + OUT gctSIZE_T * ReservedHead,
  101073. + OUT gctSIZE_T * ReservedTail
  101074. + )
  101075. +{
  101076. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101077. +
  101078. + /* Verify the arguments. */
  101079. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101080. +
  101081. + if (Alignment != gcvNULL)
  101082. + {
  101083. + /* Align every 8 bytes. */
  101084. + *Alignment = 8;
  101085. + }
  101086. +
  101087. + if (ReservedHead != gcvNULL)
  101088. + {
  101089. + /* Reserve space for SelectPipe(). */
  101090. + *ReservedHead = 32;
  101091. + }
  101092. +
  101093. + if (ReservedTail != gcvNULL)
  101094. + {
  101095. + /* Reserve space for Link(). */
  101096. + *ReservedTail = 8;
  101097. + }
  101098. +
  101099. + /* Success. */
  101100. + gcmkFOOTER_ARG("*Alignment=%lu *ReservedHead=%lu *ReservedTail=%lu",
  101101. + gcmOPT_VALUE(Alignment), gcmOPT_VALUE(ReservedHead),
  101102. + gcmOPT_VALUE(ReservedTail));
  101103. + return gcvSTATUS_OK;
  101104. +}
  101105. +
  101106. +/*******************************************************************************
  101107. +**
  101108. +** gckHARDWARE_QuerySystemMemory
  101109. +**
  101110. +** Query the command buffer alignment and number of reserved bytes.
  101111. +**
  101112. +** INPUT:
  101113. +**
  101114. +** gckHARDWARE Harwdare
  101115. +** Pointer to an gckHARDWARE object.
  101116. +**
  101117. +** OUTPUT:
  101118. +**
  101119. +** gctSIZE_T * SystemSize
  101120. +** Pointer to a variable that receives the maximum size of the system
  101121. +** memory.
  101122. +**
  101123. +** gctUINT32 * SystemBaseAddress
  101124. +** Poinetr to a variable that receives the base address for system
  101125. +** memory.
  101126. +*/
  101127. +gceSTATUS
  101128. +gckHARDWARE_QuerySystemMemory(
  101129. + IN gckHARDWARE Hardware,
  101130. + OUT gctSIZE_T * SystemSize,
  101131. + OUT gctUINT32 * SystemBaseAddress
  101132. + )
  101133. +{
  101134. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101135. +
  101136. + /* Verify the arguments. */
  101137. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101138. +
  101139. + if (SystemSize != gcvNULL)
  101140. + {
  101141. + /* Maximum system memory can be 2GB. */
  101142. + *SystemSize = 1U << 31;
  101143. + }
  101144. +
  101145. + if (SystemBaseAddress != gcvNULL)
  101146. + {
  101147. + /* Set system memory base address. */
  101148. + *SystemBaseAddress = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)));
  101149. + }
  101150. +
  101151. + /* Success. */
  101152. + gcmkFOOTER_ARG("*SystemSize=%lu *SystemBaseAddress=%lu",
  101153. + gcmOPT_VALUE(SystemSize), gcmOPT_VALUE(SystemBaseAddress));
  101154. + return gcvSTATUS_OK;
  101155. +}
  101156. +
  101157. +#ifndef VIVANTE_NO_3D
  101158. +/*******************************************************************************
  101159. +**
  101160. +** gckHARDWARE_QueryShaderCaps
  101161. +**
  101162. +** Query the shader capabilities.
  101163. +**
  101164. +** INPUT:
  101165. +**
  101166. +** Nothing.
  101167. +**
  101168. +** OUTPUT:
  101169. +**
  101170. +** gctUINT * VertexUniforms
  101171. +** Pointer to a variable receiving the number of uniforms in the vertex
  101172. +** shader.
  101173. +**
  101174. +** gctUINT * FragmentUniforms
  101175. +** Pointer to a variable receiving the number of uniforms in the
  101176. +** fragment shader.
  101177. +**
  101178. +** gctUINT * Varyings
  101179. +** Pointer to a variable receiving the maimum number of varyings.
  101180. +*/
  101181. +gceSTATUS
  101182. +gckHARDWARE_QueryShaderCaps(
  101183. + IN gckHARDWARE Hardware,
  101184. + OUT gctUINT * VertexUniforms,
  101185. + OUT gctUINT * FragmentUniforms,
  101186. + OUT gctUINT * Varyings
  101187. + )
  101188. +{
  101189. + gctUINT32 vsConstMax;
  101190. + gctUINT32 psConstMax;
  101191. +
  101192. + gcmkHEADER_ARG("Hardware=0x%x VertexUniforms=0x%x "
  101193. + "FragmentUniforms=0x%x Varyings=0x%x",
  101194. + Hardware, VertexUniforms,
  101195. + FragmentUniforms, Varyings);
  101196. +
  101197. + if ((Hardware->identity.chipModel == gcv2000)
  101198. + && (Hardware->identity.chipRevision == 0x5118))
  101199. + {
  101200. + vsConstMax = 256;
  101201. + psConstMax = 64;
  101202. + }
  101203. + else if (Hardware->identity.numConstants > 256)
  101204. + {
  101205. + vsConstMax = 256;
  101206. + psConstMax = 256;
  101207. + }
  101208. + else if (Hardware->identity.numConstants == 256)
  101209. + {
  101210. + vsConstMax = 256;
  101211. + psConstMax = 256;
  101212. + }
  101213. + else
  101214. + {
  101215. + vsConstMax = 168;
  101216. + psConstMax = 64;
  101217. + }
  101218. +
  101219. + if (VertexUniforms != gcvNULL)
  101220. + {
  101221. + *VertexUniforms = vsConstMax;
  101222. + }
  101223. +
  101224. + if (FragmentUniforms != gcvNULL)
  101225. + {
  101226. + *FragmentUniforms = psConstMax;
  101227. + }
  101228. +
  101229. + if (Varyings != gcvNULL)
  101230. + {
  101231. + /* Return the shader varyings count. */
  101232. + *Varyings = Hardware->identity.varyingsCount;
  101233. + }
  101234. +
  101235. + /* Success. */
  101236. + gcmkFOOTER_NO();
  101237. + return gcvSTATUS_OK;
  101238. +}
  101239. +#endif
  101240. +
  101241. +/*******************************************************************************
  101242. +**
  101243. +** gckHARDWARE_SetMMU
  101244. +**
  101245. +** Set the page table base address.
  101246. +**
  101247. +** INPUT:
  101248. +**
  101249. +** gckHARDWARE Harwdare
  101250. +** Pointer to an gckHARDWARE object.
  101251. +**
  101252. +** gctPOINTER Logical
  101253. +** Logical address of the page table.
  101254. +**
  101255. +** OUTPUT:
  101256. +**
  101257. +** Nothing.
  101258. +*/
  101259. +gceSTATUS
  101260. +gckHARDWARE_SetMMU(
  101261. + IN gckHARDWARE Hardware,
  101262. + IN gctPOINTER Logical
  101263. + )
  101264. +{
  101265. + gceSTATUS status;
  101266. + gctUINT32 address = 0;
  101267. + gctUINT32 baseAddress;
  101268. +
  101269. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
  101270. +
  101271. + /* Verify the arguments. */
  101272. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101273. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  101274. +
  101275. + /* Convert the logical address into an hardware address. */
  101276. + gcmkONERROR(
  101277. + gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
  101278. +
  101279. + /* Also get the base address - we need a real physical address. */
  101280. + gcmkONERROR(
  101281. + gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  101282. +
  101283. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101284. + "Setting page table to 0x%08X",
  101285. + address + baseAddress);
  101286. +
  101287. + /* Write the AQMemoryFePageTable register. */
  101288. + gcmkONERROR(
  101289. + gckOS_WriteRegisterEx(Hardware->os,
  101290. + Hardware->core,
  101291. + 0x00400,
  101292. + address + baseAddress));
  101293. +
  101294. + /* Write the AQMemoryRaPageTable register. */
  101295. + gcmkONERROR(
  101296. + gckOS_WriteRegisterEx(Hardware->os,
  101297. + Hardware->core,
  101298. + 0x00410,
  101299. + address + baseAddress));
  101300. +
  101301. + /* Write the AQMemoryTxPageTable register. */
  101302. + gcmkONERROR(
  101303. + gckOS_WriteRegisterEx(Hardware->os,
  101304. + Hardware->core,
  101305. + 0x00404,
  101306. + address + baseAddress));
  101307. +
  101308. +
  101309. + /* Write the AQMemoryPePageTable register. */
  101310. + gcmkONERROR(
  101311. + gckOS_WriteRegisterEx(Hardware->os,
  101312. + Hardware->core,
  101313. + 0x00408,
  101314. + address + baseAddress));
  101315. +
  101316. + /* Write the AQMemoryPezPageTable register. */
  101317. + gcmkONERROR(
  101318. + gckOS_WriteRegisterEx(Hardware->os,
  101319. + Hardware->core,
  101320. + 0x0040C,
  101321. + address + baseAddress));
  101322. +
  101323. + /* Return the status. */
  101324. + gcmkFOOTER_NO();
  101325. + return status;
  101326. +
  101327. +OnError:
  101328. + /* Return the status. */
  101329. + gcmkFOOTER();
  101330. + return status;
  101331. +}
  101332. +
  101333. +/*******************************************************************************
  101334. +**
  101335. +** gckHARDWARE_FlushMMU
  101336. +**
  101337. +** Flush the page table.
  101338. +**
  101339. +** INPUT:
  101340. +**
  101341. +** gckHARDWARE Harwdare
  101342. +** Pointer to an gckHARDWARE object.
  101343. +**
  101344. +** OUTPUT:
  101345. +**
  101346. +** Nothing.
  101347. +*/
  101348. +gceSTATUS
  101349. +gckHARDWARE_FlushMMU(
  101350. + IN gckHARDWARE Hardware
  101351. + )
  101352. +{
  101353. + gceSTATUS status;
  101354. + gckCOMMAND command;
  101355. + gctUINT32_PTR buffer;
  101356. + gctSIZE_T bufferSize;
  101357. + gctBOOL commitEntered = gcvFALSE;
  101358. + gctPOINTER pointer = gcvNULL;
  101359. + gctUINT32 flushSize;
  101360. + gctUINT32 count;
  101361. + gctUINT32 physical;
  101362. +
  101363. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101364. +
  101365. + /* Verify the arguments. */
  101366. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101367. +
  101368. + /* Verify the gckCOMMAND object pointer. */
  101369. + command = Hardware->kernel->command;
  101370. +
  101371. + /* Acquire the command queue. */
  101372. + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
  101373. + commitEntered = gcvTRUE;
  101374. +
  101375. + /* Flush the memory controller. */
  101376. + if (Hardware->mmuVersion == 0)
  101377. + {
  101378. + gcmkONERROR(gckCOMMAND_Reserve(
  101379. + command, 8, &pointer, &bufferSize
  101380. + ));
  101381. +
  101382. + buffer = (gctUINT32_PTR) pointer;
  101383. +
  101384. + buffer[0]
  101385. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101386. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E04) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  101387. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  101388. +
  101389. + buffer[1]
  101390. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
  101391. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
  101392. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
  101393. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
  101394. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
  101395. +
  101396. + gcmkONERROR(gckCOMMAND_Execute(command, 8));
  101397. + }
  101398. + else
  101399. + {
  101400. + flushSize = 16 * 4;
  101401. +
  101402. + gcmkONERROR(gckCOMMAND_Reserve(
  101403. + command, flushSize, &pointer, &bufferSize
  101404. + ));
  101405. +
  101406. + buffer = (gctUINT32_PTR) pointer;
  101407. +
  101408. + count = (bufferSize - flushSize + 7) >> 3;
  101409. +
  101410. + gcmkONERROR(gckOS_GetPhysicalAddress(command->os, buffer, &physical));
  101411. +
  101412. + /* Flush cache. */
  101413. + buffer[0]
  101414. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101415. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  101416. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  101417. +
  101418. + buffer[1]
  101419. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
  101420. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
  101421. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
  101422. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)))
  101423. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
  101424. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
  101425. +
  101426. + /* Arm the PE-FE Semaphore. */
  101427. + buffer[2]
  101428. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101429. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  101430. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  101431. +
  101432. + buffer[3]
  101433. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  101434. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  101435. +
  101436. + /* STALL FE until PE is done flushing. */
  101437. + buffer[4]
  101438. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  101439. +
  101440. + buffer[5]
  101441. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  101442. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  101443. +
  101444. + /* LINK to next slot to flush FE FIFO. */
  101445. + buffer[6]
  101446. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101447. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  101448. +
  101449. + buffer[7]
  101450. + = physical + 8 * gcmSIZEOF(gctUINT32);
  101451. +
  101452. + /* Flush MMU cache. */
  101453. + buffer[8]
  101454. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101455. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  101456. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  101457. +
  101458. + buffer[9]
  101459. + = (((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) & ((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))));
  101460. +
  101461. + /* Arm the PE-FE Semaphore. */
  101462. + buffer[10]
  101463. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101464. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  101465. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  101466. +
  101467. + buffer[11]
  101468. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  101469. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  101470. +
  101471. + /* STALL FE until PE is done flushing. */
  101472. + buffer[12]
  101473. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  101474. +
  101475. + buffer[13]
  101476. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
  101477. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
  101478. +
  101479. + /* LINK to next slot to flush FE FIFO. */
  101480. + buffer[14]
  101481. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101482. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (count) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
  101483. +
  101484. + buffer[15]
  101485. + = physical + flushSize;
  101486. +
  101487. + gcmkONERROR(gckCOMMAND_Execute(command, flushSize));
  101488. + }
  101489. +
  101490. + /* Release the command queue. */
  101491. + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
  101492. + commitEntered = gcvFALSE;
  101493. +
  101494. + /* Success. */
  101495. + gcmkFOOTER_NO();
  101496. + return gcvSTATUS_OK;
  101497. +
  101498. +OnError:
  101499. + if (commitEntered)
  101500. + {
  101501. + /* Release the command queue mutex. */
  101502. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
  101503. + gcvFALSE));
  101504. + }
  101505. +
  101506. + /* Return the status. */
  101507. + gcmkFOOTER();
  101508. + return status;
  101509. +}
  101510. +
  101511. +/*******************************************************************************
  101512. +**
  101513. +** gckHARDWARE_SetMMUv2
  101514. +**
  101515. +** Set the page table base address.
  101516. +**
  101517. +** INPUT:
  101518. +**
  101519. +** gckHARDWARE Harwdare
  101520. +** Pointer to an gckHARDWARE object.
  101521. +**
  101522. +** OUTPUT:
  101523. +**
  101524. +** Nothing.
  101525. +*/
  101526. +gceSTATUS
  101527. +gckHARDWARE_SetMMUv2(
  101528. + IN gckHARDWARE Hardware,
  101529. + IN gctBOOL Enable,
  101530. + IN gctPOINTER MtlbAddress,
  101531. + IN gceMMU_MODE Mode,
  101532. + IN gctPOINTER SafeAddress,
  101533. + IN gctBOOL FromPower
  101534. + )
  101535. +{
  101536. + gceSTATUS status;
  101537. + gctUINT32 config, address;
  101538. + gckCOMMAND command;
  101539. + gctUINT32_PTR buffer;
  101540. + gctSIZE_T bufferSize;
  101541. + gctBOOL commitEntered = gcvFALSE;
  101542. + gctPOINTER pointer = gcvNULL;
  101543. + gctBOOL acquired = gcvFALSE;
  101544. + gctBOOL config2D;
  101545. + gctSIZE_T configSize;
  101546. +
  101547. + gcmkHEADER_ARG("Hardware=0x%x Enable=%d", Hardware, Enable);
  101548. +
  101549. + /* Verify the arguments. */
  101550. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101551. +
  101552. + config2D = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D)
  101553. + && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_2D);
  101554. +
  101555. + configSize = 4 * 4;
  101556. +
  101557. + if (config2D)
  101558. + {
  101559. + configSize +=
  101560. + /* Pipe Select. */
  101561. + 4 * 4
  101562. + /* Configure MMU States. */
  101563. + + 4 * 4;
  101564. + }
  101565. +
  101566. + /* Convert logical address into physical address. */
  101567. + gcmkONERROR(
  101568. + gckOS_GetPhysicalAddress(Hardware->os, MtlbAddress, &config));
  101569. +
  101570. + gcmkONERROR(
  101571. + gckOS_GetPhysicalAddress(Hardware->os, SafeAddress, &address));
  101572. +
  101573. + if (address & 0x3F)
  101574. + {
  101575. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  101576. + }
  101577. +
  101578. + switch (Mode)
  101579. + {
  101580. + case gcvMMU_MODE_1K:
  101581. + if (config & 0x3FF)
  101582. + {
  101583. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  101584. + }
  101585. +
  101586. + config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
  101587. +
  101588. + break;
  101589. +
  101590. + case gcvMMU_MODE_4K:
  101591. + if (config & 0xFFF)
  101592. + {
  101593. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  101594. + }
  101595. +
  101596. + config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
  101597. +
  101598. + break;
  101599. +
  101600. + default:
  101601. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  101602. + }
  101603. +
  101604. + /* Verify the gckCOMMAND object pointer. */
  101605. + command = Hardware->kernel->command;
  101606. +
  101607. + /* Acquire the command queue. */
  101608. + gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
  101609. + commitEntered = gcvTRUE;
  101610. +
  101611. + gcmkONERROR(gckCOMMAND_Reserve(
  101612. + command, configSize, &pointer, &bufferSize
  101613. + ));
  101614. +
  101615. + buffer = pointer;
  101616. +
  101617. + buffer[0]
  101618. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101619. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  101620. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  101621. +
  101622. + buffer[1] = config;
  101623. +
  101624. + buffer[2]
  101625. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101626. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  101627. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  101628. +
  101629. + buffer[3] = address;
  101630. +
  101631. + if (config2D)
  101632. + {
  101633. + /* LoadState(AQPipeSelect, 1), pipe. */
  101634. + buffer[4]
  101635. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101636. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  101637. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  101638. +
  101639. + buffer[5] = 0x1;
  101640. +
  101641. + buffer[6]
  101642. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101643. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  101644. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  101645. +
  101646. + buffer[7] = config;
  101647. +
  101648. + buffer[8]
  101649. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101650. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  101651. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  101652. +
  101653. + buffer[9] = address;
  101654. +
  101655. + /* LoadState(AQPipeSelect, 1), pipe. */
  101656. + buffer[10]
  101657. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101658. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  101659. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  101660. +
  101661. + buffer[11] = 0x0;
  101662. + }
  101663. +
  101664. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101665. + "Setup MMU: config=%08x, Safe Address=%08x\n.", config, address);
  101666. +
  101667. + gcmkONERROR(gckCOMMAND_Execute(command, configSize));
  101668. +
  101669. + if (FromPower == gcvFALSE)
  101670. + {
  101671. + /* Acquire global semaphore to suspend power management until MMU
  101672. + ** is enabled. And acquired it before gckCOMMAND_ExitCommit to
  101673. + ** make sure GPU keeps ON. */
  101674. + gcmkONERROR(
  101675. + gckOS_AcquireSemaphore(Hardware->os, Hardware->globalSemaphore));
  101676. +
  101677. + acquired = gcvTRUE;
  101678. + }
  101679. +
  101680. + /* Release the command queue. */
  101681. + gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
  101682. + commitEntered = gcvFALSE;
  101683. +
  101684. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101685. + "call gckCOMMAND_Stall to make sure the config is done.\n ");
  101686. +
  101687. + gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
  101688. +
  101689. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101690. + "Enable MMU through GCREG_MMU_CONTROL.");
  101691. +
  101692. + /* Enable MMU. */
  101693. + gcmkONERROR(
  101694. + gckOS_WriteRegisterEx(Hardware->os,
  101695. + Hardware->core,
  101696. + 0x0018C,
  101697. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (Enable) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))));
  101698. +
  101699. + if (FromPower == gcvFALSE)
  101700. + {
  101701. + /* Relase global semaphore. */
  101702. + gcmkVERIFY_OK(
  101703. + gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
  101704. +
  101705. + acquired = gcvFALSE;
  101706. + }
  101707. +
  101708. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101709. + "call gckCOMMAND_Stall to check MMU available.\n");
  101710. +
  101711. + gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
  101712. +
  101713. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101714. + "The MMU is available.\n");
  101715. +
  101716. + /* Return the status. */
  101717. + gcmkFOOTER_NO();
  101718. + return status;
  101719. +
  101720. +OnError:
  101721. + if (commitEntered)
  101722. + {
  101723. + /* Release the command queue mutex. */
  101724. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
  101725. + FromPower));
  101726. + }
  101727. +
  101728. + if (acquired)
  101729. + {
  101730. + gcmkVERIFY_OK(
  101731. + gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
  101732. + }
  101733. +
  101734. + /* Return the status. */
  101735. + gcmkFOOTER();
  101736. + return status;
  101737. +}
  101738. +
  101739. +/*******************************************************************************
  101740. +**
  101741. +** gckHARDWARE_BuildVirtualAddress
  101742. +**
  101743. +** Build a virtual address.
  101744. +**
  101745. +** INPUT:
  101746. +**
  101747. +** gckHARDWARE Harwdare
  101748. +** Pointer to an gckHARDWARE object.
  101749. +**
  101750. +** gctUINT32 Index
  101751. +** Index into page table.
  101752. +**
  101753. +** gctUINT32 Offset
  101754. +** Offset into page.
  101755. +**
  101756. +** OUTPUT:
  101757. +**
  101758. +** gctUINT32 * Address
  101759. +** Pointer to a variable receiving te hardware address.
  101760. +*/
  101761. +gceSTATUS
  101762. +gckHARDWARE_BuildVirtualAddress(
  101763. + IN gckHARDWARE Hardware,
  101764. + IN gctUINT32 Index,
  101765. + IN gctUINT32 Offset,
  101766. + OUT gctUINT32 * Address
  101767. + )
  101768. +{
  101769. + gcmkHEADER_ARG("Hardware=0x%x Index=%u Offset=%u", Hardware, Index, Offset);
  101770. +
  101771. + /* Verify the arguments. */
  101772. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101773. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  101774. +
  101775. + /* Build virtual address. */
  101776. + *Address = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
  101777. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (Offset | (Index << 12)) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)));
  101778. +
  101779. + /* Success. */
  101780. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  101781. + return gcvSTATUS_OK;
  101782. +}
  101783. +
  101784. +gceSTATUS
  101785. +gckHARDWARE_GetIdle(
  101786. + IN gckHARDWARE Hardware,
  101787. + IN gctBOOL Wait,
  101788. + OUT gctUINT32 * Data
  101789. + )
  101790. +{
  101791. + gceSTATUS status;
  101792. + gctUINT32 idle = 0;
  101793. + gctINT retry, poll, pollCount;
  101794. +
  101795. + gcmkHEADER_ARG("Hardware=0x%x Wait=%d", Hardware, Wait);
  101796. +
  101797. + /* Verify the arguments. */
  101798. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101799. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  101800. +
  101801. +
  101802. + /* If we have to wait, try 100 polls per millisecond. */
  101803. + pollCount = Wait ? 100 : 1;
  101804. +
  101805. + /* At most, try for 1 second. */
  101806. + for (retry = 0; retry < 1000; ++retry)
  101807. + {
  101808. + /* If we have to wait, try 100 polls per millisecond. */
  101809. + for (poll = pollCount; poll > 0; --poll)
  101810. + {
  101811. + /* Read register. */
  101812. + gcmkONERROR(
  101813. + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
  101814. +
  101815. + /* See if we have to wait for FE idle. */
  101816. + if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  101817. + {
  101818. + /* FE is idle. */
  101819. + break;
  101820. + }
  101821. + }
  101822. +
  101823. + /* Check if we need to wait for FE and FE is busy. */
  101824. + if (Wait && !(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  101825. + {
  101826. + /* Wait a little. */
  101827. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101828. + "%s: Waiting for idle: 0x%08X",
  101829. + __FUNCTION__, idle);
  101830. +
  101831. + gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
  101832. + }
  101833. + else
  101834. + {
  101835. + break;
  101836. + }
  101837. + }
  101838. +
  101839. + /* Return idle to caller. */
  101840. + *Data = idle;
  101841. +
  101842. + /* Success. */
  101843. + gcmkFOOTER_ARG("*Data=0x%08x", *Data);
  101844. + return gcvSTATUS_OK;
  101845. +
  101846. +OnError:
  101847. + /* Return the status. */
  101848. + gcmkFOOTER();
  101849. + return status;
  101850. +}
  101851. +
  101852. +/* Flush the caches. */
  101853. +gceSTATUS
  101854. +gckHARDWARE_Flush(
  101855. + IN gckHARDWARE Hardware,
  101856. + IN gceKERNEL_FLUSH Flush,
  101857. + IN gctPOINTER Logical,
  101858. + IN OUT gctSIZE_T * Bytes
  101859. + )
  101860. +{
  101861. + gctUINT32 pipe;
  101862. + gctUINT32 flush = 0;
  101863. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  101864. + gceSTATUS status;
  101865. + gctBOOL fcFlushStall;
  101866. + gctUINT32 reserveBytes = 8;
  101867. +
  101868. + gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu",
  101869. + Hardware, Flush, Logical, gcmOPT_VALUE(Bytes));
  101870. +
  101871. + /* Verify the arguments. */
  101872. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101873. +
  101874. + /* Get current pipe. */
  101875. + pipe = Hardware->kernel->command->pipeSelect;
  101876. +
  101877. + fcFlushStall
  101878. + = ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 31:31) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))))
  101879. + && (Flush == gcvFLUSH_ALL)
  101880. + ;
  101881. +
  101882. + if (fcFlushStall)
  101883. + {
  101884. + reserveBytes += 8;
  101885. + }
  101886. +
  101887. + /* Flush 3D color cache. */
  101888. + if ((Flush & gcvFLUSH_COLOR) && (pipe == 0x0))
  101889. + {
  101890. + flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)));
  101891. + }
  101892. +
  101893. + /* Flush 3D depth cache. */
  101894. + if ((Flush & gcvFLUSH_DEPTH) && (pipe == 0x0))
  101895. + {
  101896. + flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
  101897. + }
  101898. +
  101899. + /* Flush 3D texture cache. */
  101900. + if ((Flush & gcvFLUSH_TEXTURE) && (pipe == 0x0))
  101901. + {
  101902. + flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
  101903. + flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
  101904. + }
  101905. +
  101906. + /* Flush 2D cache. */
  101907. + if ((Flush & gcvFLUSH_2D) && (pipe == 0x1))
  101908. + {
  101909. + flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
  101910. + }
  101911. +
  101912. + /* See if there is a valid flush. */
  101913. + if (flush == 0)
  101914. + {
  101915. + if (Bytes != gcvNULL)
  101916. + {
  101917. + /* No bytes required. */
  101918. + *Bytes = 0;
  101919. + }
  101920. + }
  101921. +
  101922. + else
  101923. + {
  101924. + /* Copy to command queue. */
  101925. + if (Logical != gcvNULL)
  101926. + {
  101927. + if (*Bytes < reserveBytes)
  101928. + {
  101929. + /* Command queue too small. */
  101930. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  101931. + }
  101932. +
  101933. + /* Append LOAD_STATE to AQFlush. */
  101934. + logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101935. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  101936. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  101937. +
  101938. + logical[1] = flush;
  101939. +
  101940. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101941. + "0x%x: FLUSH 0x%x", logical, flush);
  101942. +
  101943. + if (fcFlushStall)
  101944. + {
  101945. + logical[2] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
  101946. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
  101947. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
  101948. +
  101949. + logical[3] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
  101950. +
  101951. +
  101952. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101953. + "0x%x: FLUSH 0x%x", logical + 3, logical[3]);
  101954. + }
  101955. +
  101956. + }
  101957. +
  101958. + if (Bytes != gcvNULL)
  101959. + {
  101960. + /* bytes required. */
  101961. + *Bytes = reserveBytes;
  101962. + }
  101963. + }
  101964. +
  101965. + /* Success. */
  101966. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  101967. + return gcvSTATUS_OK;
  101968. +
  101969. +OnError:
  101970. + /* Return the status. */
  101971. + gcmkFOOTER();
  101972. + return status;
  101973. +}
  101974. +
  101975. +gceSTATUS
  101976. +gckHARDWARE_SetFastClear(
  101977. + IN gckHARDWARE Hardware,
  101978. + IN gctINT Enable,
  101979. + IN gctINT Compression
  101980. + )
  101981. +{
  101982. +#ifndef VIVANTE_NO_3D
  101983. + gctUINT32 debug;
  101984. + gceSTATUS status;
  101985. +
  101986. + gcmkHEADER_ARG("Hardware=0x%x Enable=%d Compression=%d",
  101987. + Hardware, Enable, Compression);
  101988. +
  101989. + /* Only process if fast clear is available. */
  101990. + if ((((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  101991. + {
  101992. + if (Enable == -1)
  101993. + {
  101994. + /* Determine automatic value for fast clear. */
  101995. + Enable = ((Hardware->identity.chipModel != gcv500)
  101996. + || (Hardware->identity.chipRevision >= 3)
  101997. + ) ? 1 : 0;
  101998. + }
  101999. +
  102000. + if (Compression == -1)
  102001. + {
  102002. + /* Determine automatic value for compression. */
  102003. + Compression = Enable
  102004. + & (((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) );
  102005. + }
  102006. +
  102007. + /* Read AQMemoryDebug register. */
  102008. + gcmkONERROR(
  102009. + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &debug));
  102010. +
  102011. + /* Set fast clear bypass. */
  102012. + debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20)));
  102013. +
  102014. + if (
  102015. + ((((gctUINT32) (Hardware->identity.chipMinorFeatures2)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) ||
  102016. + (Hardware->identity.chipModel >= gcv4000))
  102017. + {
  102018. + /* Set compression bypass. */
  102019. + debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21))) | (((gctUINT32) ((gctUINT32) (Compression == 0) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21)));
  102020. + }
  102021. +
  102022. + /* Write back AQMemoryDebug register. */
  102023. + gcmkONERROR(
  102024. + gckOS_WriteRegisterEx(Hardware->os,
  102025. + Hardware->core,
  102026. + 0x00414,
  102027. + debug));
  102028. +
  102029. + /* Store fast clear and comprersison flags. */
  102030. + Hardware->allowFastClear = Enable;
  102031. + Hardware->allowCompression = Compression;
  102032. +
  102033. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102034. + "FastClear=%d Compression=%d", Enable, Compression);
  102035. + }
  102036. +
  102037. + /* Success. */
  102038. + gcmkFOOTER_NO();
  102039. + return gcvSTATUS_OK;
  102040. +
  102041. +OnError:
  102042. + /* Return the status. */
  102043. + gcmkFOOTER();
  102044. + return status;
  102045. +#else
  102046. + return gcvSTATUS_OK;
  102047. +#endif
  102048. +}
  102049. +
  102050. +typedef enum
  102051. +{
  102052. + gcvPOWER_FLAG_INITIALIZE = 1 << 0,
  102053. + gcvPOWER_FLAG_STALL = 1 << 1,
  102054. + gcvPOWER_FLAG_STOP = 1 << 2,
  102055. + gcvPOWER_FLAG_START = 1 << 3,
  102056. + gcvPOWER_FLAG_RELEASE = 1 << 4,
  102057. + gcvPOWER_FLAG_DELAY = 1 << 5,
  102058. + gcvPOWER_FLAG_SAVE = 1 << 6,
  102059. + gcvPOWER_FLAG_ACQUIRE = 1 << 7,
  102060. + gcvPOWER_FLAG_POWER_OFF = 1 << 8,
  102061. + gcvPOWER_FLAG_CLOCK_OFF = 1 << 9,
  102062. + gcvPOWER_FLAG_CLOCK_ON = 1 << 10,
  102063. +}
  102064. +gcePOWER_FLAGS;
  102065. +
  102066. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  102067. +static gctCONST_STRING
  102068. +_PowerEnum(gceCHIPPOWERSTATE State)
  102069. +{
  102070. + const gctCONST_STRING states[] =
  102071. + {
  102072. + gcmSTRING(gcvPOWER_ON),
  102073. + gcmSTRING(gcvPOWER_OFF),
  102074. + gcmSTRING(gcvPOWER_IDLE),
  102075. + gcmSTRING(gcvPOWER_SUSPEND),
  102076. + gcmSTRING(gcvPOWER_SUSPEND_ATPOWERON),
  102077. + gcmSTRING(gcvPOWER_OFF_ATPOWERON),
  102078. + gcmSTRING(gcvPOWER_IDLE_BROADCAST),
  102079. + gcmSTRING(gcvPOWER_SUSPEND_BROADCAST),
  102080. + gcmSTRING(gcvPOWER_OFF_BROADCAST),
  102081. + gcmSTRING(gcvPOWER_OFF_RECOVERY),
  102082. + gcmSTRING(gcvPOWER_ON_AUTO)
  102083. + };
  102084. +
  102085. + if ((State >= gcvPOWER_ON) && (State <= gcvPOWER_ON_AUTO))
  102086. + {
  102087. + return states[State - gcvPOWER_ON];
  102088. + }
  102089. +
  102090. + return "unknown";
  102091. +}
  102092. +#endif
  102093. +
  102094. +/*******************************************************************************
  102095. +**
  102096. +** gckHARDWARE_SetPowerManagementState
  102097. +**
  102098. +** Set GPU to a specified power state.
  102099. +**
  102100. +** INPUT:
  102101. +**
  102102. +** gckHARDWARE Harwdare
  102103. +** Pointer to an gckHARDWARE object.
  102104. +**
  102105. +** gceCHIPPOWERSTATE State
  102106. +** Power State.
  102107. +**
  102108. +*/
  102109. +gceSTATUS
  102110. +gckHARDWARE_SetPowerManagementState(
  102111. + IN gckHARDWARE Hardware,
  102112. + IN gceCHIPPOWERSTATE State
  102113. + )
  102114. +{
  102115. + gceSTATUS status;
  102116. + gckCOMMAND command = gcvNULL;
  102117. + gckOS os;
  102118. + gctUINT flag, clock;
  102119. + gctPOINTER buffer;
  102120. + gctSIZE_T bytes, requested;
  102121. + gctBOOL acquired = gcvFALSE;
  102122. + gctBOOL mutexAcquired = gcvFALSE;
  102123. + gctBOOL stall = gcvTRUE;
  102124. + gctBOOL broadcast = gcvFALSE;
  102125. +#if gcdPOWEROFF_TIMEOUT
  102126. + gctBOOL timeout = gcvFALSE;
  102127. + gctBOOL isAfter = gcvFALSE;
  102128. + gctUINT32 currentTime;
  102129. +#endif
  102130. + gctUINT32 process, thread;
  102131. + gctBOOL commitEntered = gcvFALSE;
  102132. + gctBOOL commandStarted = gcvFALSE;
  102133. + gctBOOL isrStarted = gcvFALSE;
  102134. +
  102135. +#if gcdENABLE_PROFILING
  102136. + gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
  102137. + initTime, offTime, startTime, totalTime;
  102138. +#endif
  102139. + gctBOOL global = gcvFALSE;
  102140. + gctBOOL globalAcquired = gcvFALSE;
  102141. + gctBOOL configMmu = gcvFALSE;
  102142. +
  102143. + /* State transition flags. */
  102144. + static const gctUINT flags[4][4] =
  102145. + {
  102146. + /* gcvPOWER_ON */
  102147. + { /* ON */ 0,
  102148. + /* OFF */ gcvPOWER_FLAG_ACQUIRE |
  102149. + gcvPOWER_FLAG_STALL |
  102150. + gcvPOWER_FLAG_STOP |
  102151. + gcvPOWER_FLAG_POWER_OFF |
  102152. + gcvPOWER_FLAG_CLOCK_OFF,
  102153. + /* IDLE */ gcvPOWER_FLAG_ACQUIRE |
  102154. + gcvPOWER_FLAG_STALL,
  102155. + /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
  102156. + gcvPOWER_FLAG_STALL |
  102157. + gcvPOWER_FLAG_STOP |
  102158. + gcvPOWER_FLAG_CLOCK_OFF,
  102159. + },
  102160. +
  102161. + /* gcvPOWER_OFF */
  102162. + { /* ON */ gcvPOWER_FLAG_INITIALIZE |
  102163. + gcvPOWER_FLAG_START |
  102164. + gcvPOWER_FLAG_RELEASE |
  102165. + gcvPOWER_FLAG_DELAY,
  102166. + /* OFF */ 0,
  102167. + /* IDLE */ gcvPOWER_FLAG_INITIALIZE |
  102168. + gcvPOWER_FLAG_START |
  102169. + gcvPOWER_FLAG_DELAY,
  102170. + /* SUSPEND */ gcvPOWER_FLAG_INITIALIZE |
  102171. + gcvPOWER_FLAG_CLOCK_OFF,
  102172. + },
  102173. +
  102174. + /* gcvPOWER_IDLE */
  102175. + { /* ON */ gcvPOWER_FLAG_RELEASE,
  102176. + /* OFF */ gcvPOWER_FLAG_STOP |
  102177. + gcvPOWER_FLAG_POWER_OFF |
  102178. + gcvPOWER_FLAG_CLOCK_OFF,
  102179. + /* IDLE */ 0,
  102180. + /* SUSPEND */ gcvPOWER_FLAG_STOP |
  102181. + gcvPOWER_FLAG_CLOCK_OFF,
  102182. + },
  102183. +
  102184. + /* gcvPOWER_SUSPEND */
  102185. + { /* ON */ gcvPOWER_FLAG_START |
  102186. + gcvPOWER_FLAG_RELEASE |
  102187. + gcvPOWER_FLAG_DELAY |
  102188. + gcvPOWER_FLAG_CLOCK_ON,
  102189. + /* OFF */ gcvPOWER_FLAG_SAVE |
  102190. + gcvPOWER_FLAG_POWER_OFF |
  102191. + gcvPOWER_FLAG_CLOCK_OFF,
  102192. + /* IDLE */ gcvPOWER_FLAG_START |
  102193. + gcvPOWER_FLAG_DELAY |
  102194. + gcvPOWER_FLAG_CLOCK_ON,
  102195. + /* SUSPEND */ 0,
  102196. + },
  102197. + };
  102198. +
  102199. + /* Clocks. */
  102200. + static const gctUINT clocks[4] =
  102201. + {
  102202. + /* gcvPOWER_ON */
  102203. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
  102204. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
  102205. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (64) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
  102206. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
  102207. +
  102208. + /* gcvPOWER_OFF */
  102209. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
  102210. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
  102211. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
  102212. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
  102213. +
  102214. + /* gcvPOWER_IDLE */
  102215. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
  102216. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
  102217. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
  102218. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
  102219. +
  102220. + /* gcvPOWER_SUSPEND */
  102221. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
  102222. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
  102223. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
  102224. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
  102225. + };
  102226. +
  102227. + gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
  102228. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  102229. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102230. + "Switching to power state %d(%s)",
  102231. + State, _PowerEnum(State));
  102232. +#endif
  102233. +
  102234. + /* Verify the arguments. */
  102235. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102236. +
  102237. + /* Get the gckOS object pointer. */
  102238. + os = Hardware->os;
  102239. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  102240. +
  102241. + /* Get the gckCOMMAND object pointer. */
  102242. + gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
  102243. + command = Hardware->kernel->command;
  102244. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  102245. +
  102246. + if (Hardware->powerManagement == gcvFALSE)
  102247. + {
  102248. + gcmkFOOTER_NO();
  102249. + return gcvSTATUS_OK;
  102250. + }
  102251. +
  102252. + /* Start profiler. */
  102253. + gcmkPROFILE_INIT(freq, time);
  102254. +
  102255. + /* Convert the broadcast power state. */
  102256. + switch (State)
  102257. + {
  102258. + case gcvPOWER_SUSPEND_ATPOWERON:
  102259. + /* Convert to SUSPEND and don't wait for STALL. */
  102260. + State = gcvPOWER_SUSPEND;
  102261. + stall = gcvFALSE;
  102262. + break;
  102263. +
  102264. + case gcvPOWER_OFF_ATPOWERON:
  102265. + /* Convert to OFF and don't wait for STALL. */
  102266. + State = gcvPOWER_OFF;
  102267. + stall = gcvFALSE;
  102268. + break;
  102269. +
  102270. + case gcvPOWER_IDLE_BROADCAST:
  102271. + /* Convert to IDLE and note we are inside broadcast. */
  102272. + State = gcvPOWER_IDLE;
  102273. + broadcast = gcvTRUE;
  102274. + break;
  102275. +
  102276. + case gcvPOWER_SUSPEND_BROADCAST:
  102277. + /* Convert to SUSPEND and note we are inside broadcast. */
  102278. + State = gcvPOWER_SUSPEND;
  102279. + broadcast = gcvTRUE;
  102280. + break;
  102281. +
  102282. + case gcvPOWER_OFF_BROADCAST:
  102283. + /* Convert to OFF and note we are inside broadcast. */
  102284. + State = gcvPOWER_OFF;
  102285. + broadcast = gcvTRUE;
  102286. + break;
  102287. +
  102288. + case gcvPOWER_OFF_RECOVERY:
  102289. + /* Convert to OFF and note we are inside recovery. */
  102290. + State = gcvPOWER_OFF;
  102291. + stall = gcvFALSE;
  102292. + broadcast = gcvTRUE;
  102293. + break;
  102294. +
  102295. + case gcvPOWER_ON_AUTO:
  102296. + /* Convert to ON and note we are inside recovery. */
  102297. + State = gcvPOWER_ON;
  102298. + break;
  102299. +
  102300. + case gcvPOWER_ON:
  102301. + case gcvPOWER_IDLE:
  102302. + case gcvPOWER_SUSPEND:
  102303. + case gcvPOWER_OFF:
  102304. + /* Mark as global power management. */
  102305. + global = gcvTRUE;
  102306. + break;
  102307. +
  102308. +#if gcdPOWEROFF_TIMEOUT
  102309. + case gcvPOWER_OFF_TIMEOUT:
  102310. + /* Convert to OFF and note we are inside broadcast. */
  102311. + State = gcvPOWER_OFF;
  102312. + broadcast = gcvTRUE;
  102313. + /* Check time out */
  102314. + timeout = gcvTRUE;
  102315. + break;
  102316. +#endif
  102317. +
  102318. + default:
  102319. + break;
  102320. + }
  102321. +
  102322. + /* Get current process and thread IDs. */
  102323. + gcmkONERROR(gckOS_GetProcessID(&process));
  102324. + gcmkONERROR(gckOS_GetThreadID(&thread));
  102325. +
  102326. + /* Before we grab locks see if this is actually a needed change */
  102327. + if (State == Hardware->chipPowerState)
  102328. + return gcvSTATUS_OK;
  102329. +
  102330. + if (broadcast)
  102331. + {
  102332. + /* Try to acquire the power mutex. */
  102333. + status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
  102334. +
  102335. + if (status == gcvSTATUS_TIMEOUT)
  102336. + {
  102337. + /* Check if we already own this mutex. */
  102338. + if ((Hardware->powerProcess == process)
  102339. + && (Hardware->powerThread == thread)
  102340. + )
  102341. + {
  102342. + /* Bail out on recursive power management. */
  102343. + gcmkFOOTER_NO();
  102344. + return gcvSTATUS_OK;
  102345. + }
  102346. + else if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
  102347. + {
  102348. + /* Called from IST,
  102349. + ** so waiting here will cause deadlock,
  102350. + ** if lock holder call gckCOMMAND_Stall() */
  102351. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  102352. + }
  102353. +#if gcdPOWEROFF_TIMEOUT
  102354. + else if(State == gcvPOWER_OFF && timeout == gcvTRUE)
  102355. + {
  102356. + /*
  102357. + ** try to aqcuire the mutex with more milliseconds,
  102358. + ** flush_delayed_work should be running with timeout,
  102359. + ** so waiting here will cause deadlock */
  102360. + status = gckOS_AcquireMutex(os, Hardware->powerMutex, gcdPOWEROFF_TIMEOUT);
  102361. +
  102362. + if (status == gcvSTATUS_TIMEOUT)
  102363. + {
  102364. + gckOS_Print("GPU Timer deadlock, exit by timeout!!!!\n");
  102365. +
  102366. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  102367. + }
  102368. + }
  102369. +#endif
  102370. + else
  102371. + {
  102372. + /* Acquire the power mutex. */
  102373. + gcmkONERROR(gckOS_AcquireMutex(os,
  102374. + Hardware->powerMutex,
  102375. + gcvINFINITE));
  102376. + }
  102377. + }
  102378. + }
  102379. + else
  102380. + {
  102381. + /* Acquire the power mutex. */
  102382. + gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
  102383. + }
  102384. +
  102385. + /* Get time until mtuex acquired. */
  102386. + gcmkPROFILE_QUERY(time, mutexTime);
  102387. +
  102388. + Hardware->powerProcess = process;
  102389. + Hardware->powerThread = thread;
  102390. + mutexAcquired = gcvTRUE;
  102391. +
  102392. + /* Grab control flags and clock. */
  102393. + flag = flags[Hardware->chipPowerState][State];
  102394. + clock = clocks[State];
  102395. +
  102396. +#if gcdENABLE_FSCALE_VAL_ADJUST
  102397. + if (State == gcvPOWER_ON)
  102398. + {
  102399. + clock = ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (Hardware->powerOnFscaleVal) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)));
  102400. + }
  102401. +#endif
  102402. +
  102403. + if (State == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF && broadcast)
  102404. + {
  102405. +#if gcdPOWER_SUSNPEND_WHEN_IDLE
  102406. + /* Do nothing */
  102407. +
  102408. + /* Release the power mutex. */
  102409. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102410. +
  102411. + gcmkFOOTER_NO();
  102412. + return gcvSTATUS_OK;
  102413. +#else
  102414. + /* Clock should be on when switch power from off to suspend */
  102415. + clock = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
  102416. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
  102417. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
  102418. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) ;
  102419. +#endif
  102420. + }
  102421. +
  102422. +#if gcdPOWEROFF_TIMEOUT
  102423. + if (timeout)
  102424. + {
  102425. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  102426. +
  102427. + gcmkONERROR(
  102428. + gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
  102429. +
  102430. + /* powerOffTime is pushed forward, give up.*/
  102431. + if (isAfter
  102432. + /* Expect a transition start from IDLE or SUSPEND. */
  102433. + || (Hardware->chipPowerState == gcvPOWER_ON)
  102434. + || (Hardware->chipPowerState == gcvPOWER_OFF)
  102435. + )
  102436. + {
  102437. + /* Release the power mutex. */
  102438. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102439. +
  102440. + /* No need to do anything. */
  102441. + gcmkFOOTER_NO();
  102442. + return gcvSTATUS_OK;
  102443. + }
  102444. +
  102445. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102446. + "Power Off GPU[%d] at %u [supposed to be at %u]",
  102447. + Hardware->core, currentTime, Hardware->powerOffTime);
  102448. + }
  102449. +
  102450. + if (State == gcvPOWER_ON || State == gcvPOWER_OFF)
  102451. + {
  102452. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
  102453. +
  102454. + /* Cancel running timer when GPU enters ON or OFF. */
  102455. + gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
  102456. + }
  102457. +#endif
  102458. +
  102459. + if (flag == 0)
  102460. + {
  102461. + /* Release the power mutex. */
  102462. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102463. +
  102464. + /* No need to do anything. */
  102465. + gcmkFOOTER_NO();
  102466. + return gcvSTATUS_OK;
  102467. + }
  102468. +
  102469. + /* If this is an internal power management, we have to check if we can grab
  102470. + ** the global power semaphore. If we cannot, we have to wait until the
  102471. + ** external world changes power management. */
  102472. + if (!global)
  102473. + {
  102474. + /* Try to acquire the global semaphore. */
  102475. + status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
  102476. + if (status == gcvSTATUS_TIMEOUT)
  102477. + {
  102478. + if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
  102479. + {
  102480. + /* Called from thread routine which should NEVER sleep.*/
  102481. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  102482. + }
  102483. +
  102484. + /* Release the power mutex. */
  102485. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102486. + "Releasing the power mutex.");
  102487. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102488. + mutexAcquired = gcvFALSE;
  102489. +
  102490. + /* Wait for the semaphore. */
  102491. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102492. + "Waiting for global semaphore.");
  102493. + gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore));
  102494. + globalAcquired = gcvTRUE;
  102495. +
  102496. + /* Acquire the power mutex. */
  102497. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102498. + "Reacquiring the power mutex.");
  102499. + gcmkONERROR(gckOS_AcquireMutex(os,
  102500. + Hardware->powerMutex,
  102501. + gcvINFINITE));
  102502. + mutexAcquired = gcvTRUE;
  102503. +
  102504. + /* chipPowerState may be changed by external world during the time
  102505. + ** we give up powerMutex, so updating flag now is necessary. */
  102506. + flag = flags[Hardware->chipPowerState][State];
  102507. +
  102508. + if (flag == 0)
  102509. + {
  102510. + gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
  102511. + globalAcquired = gcvFALSE;
  102512. +
  102513. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102514. + mutexAcquired = gcvFALSE;
  102515. +
  102516. + gcmkFOOTER_NO();
  102517. + return gcvSTATUS_OK;
  102518. + }
  102519. + }
  102520. + else
  102521. + {
  102522. + /* Error. */
  102523. + gcmkONERROR(status);
  102524. + }
  102525. +
  102526. + /* Release the global semaphore again. */
  102527. + gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
  102528. + globalAcquired = gcvFALSE;
  102529. + }
  102530. + else
  102531. + {
  102532. + if (State == gcvPOWER_OFF || State == gcvPOWER_SUSPEND || State == gcvPOWER_IDLE)
  102533. + {
  102534. + /* Acquire the global semaphore if it has not been acquired. */
  102535. + status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
  102536. + if (status == gcvSTATUS_OK)
  102537. + {
  102538. + globalAcquired = gcvTRUE;
  102539. + }
  102540. + else if (status != gcvSTATUS_TIMEOUT)
  102541. + {
  102542. + /* Other errors. */
  102543. + gcmkONERROR(status);
  102544. + }
  102545. + /* Ignore gcvSTATUS_TIMEOUT and leave globalAcquired as gcvFALSE.
  102546. + ** gcvSTATUS_TIMEOUT means global semaphore has already
  102547. + ** been acquired before this operation, so even if we fail,
  102548. + ** we should not release it in our error handling. It should be
  102549. + ** released by the next successful global gcvPOWER_ON. */
  102550. + }
  102551. +
  102552. + /* Global power management can't be aborted, so sync with
  102553. + ** proceeding last commit. */
  102554. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  102555. + {
  102556. + /* Acquire the power management semaphore. */
  102557. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  102558. + acquired = gcvTRUE;
  102559. +
  102560. + /* avoid acquiring again. */
  102561. + flag &= ~gcvPOWER_FLAG_ACQUIRE;
  102562. + }
  102563. + }
  102564. +
  102565. + if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
  102566. + {
  102567. + /* Turn on the power. */
  102568. + gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
  102569. +
  102570. + /* Mark clock and power as enabled. */
  102571. + Hardware->clockState = gcvTRUE;
  102572. + Hardware->powerState = gcvTRUE;
  102573. +
  102574. + for (;;)
  102575. + {
  102576. + /* Check if GPU is present and awake. */
  102577. + status = _IsGPUPresent(Hardware);
  102578. +
  102579. + /* Check if the GPU is not responding. */
  102580. + if (status == gcvSTATUS_GPU_NOT_RESPONDING)
  102581. + {
  102582. + /* Turn off the power and clock. */
  102583. + gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvFALSE, gcvFALSE));
  102584. +
  102585. + Hardware->clockState = gcvFALSE;
  102586. + Hardware->powerState = gcvFALSE;
  102587. +
  102588. + /* Wait a little. */
  102589. + gckOS_Delay(os, 1);
  102590. +
  102591. + /* Turn on the power and clock. */
  102592. + gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
  102593. +
  102594. + Hardware->clockState = gcvTRUE;
  102595. + Hardware->powerState = gcvTRUE;
  102596. +
  102597. + /* We need to initialize the hardware and start the command
  102598. + * processor. */
  102599. + flag |= gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_START;
  102600. + }
  102601. + else
  102602. + {
  102603. + /* Test for error. */
  102604. + gcmkONERROR(status);
  102605. +
  102606. + /* Break out of loop. */
  102607. + break;
  102608. + }
  102609. + }
  102610. + }
  102611. +
  102612. + /* Get time until powered on. */
  102613. + gcmkPROFILE_QUERY(time, onTime);
  102614. +
  102615. + if ((flag & gcvPOWER_FLAG_STALL) && stall)
  102616. + {
  102617. + gctBOOL idle;
  102618. + gctINT32 atomValue;
  102619. +
  102620. + /* For global operation, all pending commits have already been
  102621. + ** blocked by globalSemaphore or powerSemaphore.*/
  102622. + if (!global)
  102623. + {
  102624. + /* Check commit atom. */
  102625. + gcmkONERROR(gckOS_AtomGet(os, command->atomCommit, &atomValue));
  102626. +
  102627. + if (atomValue > 0)
  102628. + {
  102629. + /* Commits are pending - abort power management. */
  102630. + status = broadcast ? gcvSTATUS_CHIP_NOT_READY
  102631. + : gcvSTATUS_MORE_DATA;
  102632. + goto OnError;
  102633. + }
  102634. + }
  102635. +
  102636. + if (broadcast)
  102637. + {
  102638. + /* Check for idle. */
  102639. + gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
  102640. +
  102641. + if (!idle)
  102642. + {
  102643. + status = gcvSTATUS_CHIP_NOT_READY;
  102644. + goto OnError;
  102645. + }
  102646. + }
  102647. +
  102648. + else
  102649. + {
  102650. + /* Acquire the command queue. */
  102651. + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvTRUE));
  102652. + commitEntered = gcvTRUE;
  102653. +
  102654. + /* Get the size of the flush command. */
  102655. + gcmkONERROR(gckHARDWARE_Flush(Hardware,
  102656. + gcvFLUSH_ALL,
  102657. + gcvNULL,
  102658. + &requested));
  102659. +
  102660. + /* Reserve space in the command queue. */
  102661. + gcmkONERROR(gckCOMMAND_Reserve(command,
  102662. + requested,
  102663. + &buffer,
  102664. + &bytes));
  102665. +
  102666. + /* Append a flush. */
  102667. + gcmkONERROR(gckHARDWARE_Flush(
  102668. + Hardware, gcvFLUSH_ALL, buffer, &bytes
  102669. + ));
  102670. +
  102671. + /* Execute the command queue. */
  102672. + gcmkONERROR(gckCOMMAND_Execute(command, requested));
  102673. +
  102674. + /* Release the command queue. */
  102675. + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvTRUE));
  102676. + commitEntered = gcvFALSE;
  102677. +
  102678. + /* Wait to finish all commands. */
  102679. + gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE));
  102680. + }
  102681. + }
  102682. +
  102683. + /* Get time until stalled. */
  102684. + gcmkPROFILE_QUERY(time, stallTime);
  102685. +
  102686. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  102687. + {
  102688. + /* Acquire the power management semaphore. */
  102689. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  102690. + acquired = gcvTRUE;
  102691. + }
  102692. +
  102693. + if (flag & gcvPOWER_FLAG_STOP)
  102694. + {
  102695. + /* Stop the command parser. */
  102696. + gcmkONERROR(gckCOMMAND_Stop(command, gcvFALSE));
  102697. +
  102698. + /* Stop the Isr. */
  102699. + if (Hardware->stopIsr)
  102700. + {
  102701. + gcmkONERROR(Hardware->stopIsr(Hardware->isrContext, Hardware->core));
  102702. + }
  102703. + }
  102704. +
  102705. + /* Flush Cache before Power Off. */
  102706. + if (flag & gcvPOWER_FLAG_POWER_OFF)
  102707. + {
  102708. + if (Hardware->clockState == gcvFALSE)
  102709. + {
  102710. + /* Turn off the GPU power. */
  102711. + gcmkONERROR(
  102712. + gckOS_SetGPUPower(os,
  102713. + Hardware->core,
  102714. + gcvTRUE,
  102715. + gcvTRUE));
  102716. +
  102717. + Hardware->clockState = gcvTRUE;
  102718. +
  102719. + if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE)
  102720. + {
  102721. + /* Write the clock control register. */
  102722. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  102723. + Hardware->core,
  102724. + 0x00000,
  102725. + clocks[0]));
  102726. +
  102727. + /* Done loading the frequency scaler. */
  102728. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  102729. + Hardware->core,
  102730. + 0x00000,
  102731. + ((((gctUINT32) (clocks[0])) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
  102732. + }
  102733. + }
  102734. +
  102735. + gcmkONERROR(gckCOMMAND_Start(command));
  102736. +
  102737. + gcmkONERROR(_FlushCache(Hardware, command));
  102738. +
  102739. + gckOS_Delay(gcvNULL, 1);
  102740. +
  102741. + /* Stop the command parser. */
  102742. + gcmkONERROR(gckCOMMAND_Stop(command, gcvFALSE));
  102743. +
  102744. + flag |= gcvPOWER_FLAG_CLOCK_OFF;
  102745. + }
  102746. +
  102747. + /* Get time until stopped. */
  102748. + gcmkPROFILE_QUERY(time, stopTime);
  102749. +
  102750. + /* Only process this when hardware is enabled. */
  102751. + if (Hardware->clockState && Hardware->powerState
  102752. + /* Don't touch clock control if dynamic frequency scaling is available. */
  102753. + && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE
  102754. + )
  102755. + {
  102756. + if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
  102757. + {
  102758. + if (Hardware->identity.chipModel == gcv4000
  102759. + && Hardware->identity.chipRevision == 0x5208)
  102760. + {
  102761. + clock &= ~2U;
  102762. + }
  102763. + }
  102764. +
  102765. + /* Write the clock control register. */
  102766. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  102767. + Hardware->core,
  102768. + 0x00000,
  102769. + clock));
  102770. +
  102771. + /* Done loading the frequency scaler. */
  102772. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  102773. + Hardware->core,
  102774. + 0x00000,
  102775. + ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
  102776. + }
  102777. +
  102778. + if (flag & gcvPOWER_FLAG_DELAY)
  102779. + {
  102780. + /* Wait for the specified amount of time to settle coming back from
  102781. + ** power-off or suspend state. */
  102782. + gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
  102783. + }
  102784. +
  102785. + /* Get time until delayed. */
  102786. + gcmkPROFILE_QUERY(time, delayTime);
  102787. +
  102788. + if (flag & gcvPOWER_FLAG_INITIALIZE)
  102789. + {
  102790. + /* Initialize hardware. */
  102791. + gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
  102792. +
  102793. + gcmkONERROR(gckHARDWARE_SetFastClear(Hardware,
  102794. + Hardware->allowFastClear,
  102795. + Hardware->allowCompression));
  102796. +
  102797. + /* Force the command queue to reload the next context. */
  102798. + command->currContext = gcvNULL;
  102799. +
  102800. + /* Need to config mmu after command start. */
  102801. + configMmu = gcvTRUE;
  102802. + }
  102803. +
  102804. + /* Get time until initialized. */
  102805. + gcmkPROFILE_QUERY(time, initTime);
  102806. +
  102807. + if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
  102808. + {
  102809. + /* Turn off the GPU power. */
  102810. + gcmkONERROR(
  102811. + gckOS_SetGPUPower(os,
  102812. + Hardware->core,
  102813. + (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  102814. + : gcvTRUE,
  102815. + (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  102816. + : gcvTRUE));
  102817. +
  102818. + /* Save current hardware power and clock states. */
  102819. + Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  102820. + : gcvTRUE;
  102821. + Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  102822. + : gcvTRUE;
  102823. + }
  102824. +
  102825. + /* Get time until off. */
  102826. + gcmkPROFILE_QUERY(time, offTime);
  102827. +
  102828. + if (flag & gcvPOWER_FLAG_START)
  102829. + {
  102830. + /* Start the command processor. */
  102831. + gcmkONERROR(gckCOMMAND_Start(command));
  102832. + commandStarted = gcvTRUE;
  102833. +
  102834. + if (Hardware->startIsr)
  102835. + {
  102836. + /* Start the Isr. */
  102837. + gcmkONERROR(Hardware->startIsr(Hardware->isrContext, Hardware->core));
  102838. + isrStarted = gcvTRUE;
  102839. + }
  102840. +
  102841. + /* Set NEW MMU. */
  102842. + if (Hardware->mmuVersion != 0 && configMmu)
  102843. + {
  102844. + gcmkONERROR(
  102845. + gckHARDWARE_SetMMUv2(
  102846. + Hardware,
  102847. + gcvTRUE,
  102848. + Hardware->kernel->mmu->mtlbLogical,
  102849. + gcvMMU_MODE_4K,
  102850. + (gctUINT8_PTR)Hardware->kernel->mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
  102851. + gcvTRUE
  102852. + ));
  102853. + }
  102854. + }
  102855. +
  102856. + /* Get time until started. */
  102857. + gcmkPROFILE_QUERY(time, startTime);
  102858. +
  102859. + if (flag & gcvPOWER_FLAG_RELEASE)
  102860. + {
  102861. + /* Release the power management semaphore. */
  102862. + gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
  102863. + acquired = gcvFALSE;
  102864. +
  102865. + if (global)
  102866. + {
  102867. + /* Verify global semaphore has been acquired already before
  102868. + ** we release it.
  102869. + ** If it was acquired, gckOS_TryAcquireSemaphore will return
  102870. + ** gcvSTATUS_TIMEOUT and we release it. Otherwise, global
  102871. + ** semaphore will be acquried now, but it still is released
  102872. + ** immediately. */
  102873. + status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
  102874. + if (status != gcvSTATUS_TIMEOUT)
  102875. + {
  102876. + gcmkONERROR(status);
  102877. + }
  102878. +
  102879. + /* Release the global semaphore. */
  102880. + gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
  102881. + globalAcquired = gcvFALSE;
  102882. + }
  102883. + }
  102884. +
  102885. + /* Save the new power state. */
  102886. + Hardware->chipPowerState = State;
  102887. +
  102888. +#if gcdDVFS
  102889. + if (State == gcvPOWER_ON && Hardware->kernel->dvfs)
  102890. + {
  102891. + gckDVFS_Start(Hardware->kernel->dvfs);
  102892. + }
  102893. +#endif
  102894. +
  102895. +#if gcdPOWEROFF_TIMEOUT
  102896. + if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
  102897. + {
  102898. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  102899. +
  102900. + Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
  102901. + /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
  102902. + gcmkVERIFY_OK(gckOS_StartTimer(os,
  102903. + Hardware->powerOffTimer,
  102904. + Hardware->powerOffTimeout));
  102905. + }
  102906. +#endif
  102907. +
  102908. + /* Release the power mutex. */
  102909. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102910. +
  102911. + /* Get total time. */
  102912. + gcmkPROFILE_QUERY(time, totalTime);
  102913. +#if gcdENABLE_PROFILING
  102914. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102915. + "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
  102916. + freq, mutexTime, onTime, stallTime, stopTime);
  102917. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102918. + " delay:%llu init:%llu off:%llu start:%llu total:%llu",
  102919. + delayTime, initTime, offTime, startTime, totalTime);
  102920. +#endif
  102921. +
  102922. + /* Success. */
  102923. + gcmkFOOTER_NO();
  102924. + return gcvSTATUS_OK;
  102925. +
  102926. +OnError:
  102927. + if (commandStarted)
  102928. + {
  102929. + gcmkVERIFY_OK(gckCOMMAND_Stop(command, gcvFALSE));
  102930. + }
  102931. +
  102932. + if (isrStarted)
  102933. + {
  102934. + gcmkVERIFY_OK(Hardware->stopIsr(Hardware->isrContext, Hardware->core));
  102935. + }
  102936. +
  102937. + if (commitEntered)
  102938. + {
  102939. + /* Release the command queue mutex. */
  102940. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, gcvTRUE));
  102941. + }
  102942. +
  102943. + if (acquired)
  102944. + {
  102945. + /* Release semaphore. */
  102946. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
  102947. + command->powerSemaphore));
  102948. + }
  102949. +
  102950. + if (globalAcquired)
  102951. + {
  102952. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
  102953. + Hardware->globalSemaphore));
  102954. + }
  102955. +
  102956. + if (mutexAcquired)
  102957. + {
  102958. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  102959. + }
  102960. +
  102961. + /* Return the status. */
  102962. + gcmkFOOTER();
  102963. + return status;
  102964. +}
  102965. +
  102966. +/*******************************************************************************
  102967. +**
  102968. +** gckHARDWARE_QueryPowerManagementState
  102969. +**
  102970. +** Get GPU power state.
  102971. +**
  102972. +** INPUT:
  102973. +**
  102974. +** gckHARDWARE Harwdare
  102975. +** Pointer to an gckHARDWARE object.
  102976. +**
  102977. +** gceCHIPPOWERSTATE* State
  102978. +** Power State.
  102979. +**
  102980. +*/
  102981. +gceSTATUS
  102982. +gckHARDWARE_QueryPowerManagementState(
  102983. + IN gckHARDWARE Hardware,
  102984. + OUT gceCHIPPOWERSTATE* State
  102985. + )
  102986. +{
  102987. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  102988. +
  102989. + /* Verify the arguments. */
  102990. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102991. + gcmkVERIFY_ARGUMENT(State != gcvNULL);
  102992. +
  102993. + /* Return the statue. */
  102994. + *State = Hardware->chipPowerState;
  102995. +
  102996. + /* Success. */
  102997. + gcmkFOOTER_ARG("*State=%d", *State);
  102998. + return gcvSTATUS_OK;
  102999. +}
  103000. +
  103001. +/*******************************************************************************
  103002. +**
  103003. +** gckHARDWARE_SetPowerManagement
  103004. +**
  103005. +** Configure GPU power management function.
  103006. +** Only used in driver initialization stage.
  103007. +**
  103008. +** INPUT:
  103009. +**
  103010. +** gckHARDWARE Harwdare
  103011. +** Pointer to an gckHARDWARE object.
  103012. +**
  103013. +** gctBOOL PowerManagement
  103014. +** Power Mangement State.
  103015. +**
  103016. +*/
  103017. +gceSTATUS
  103018. +gckHARDWARE_SetPowerManagement(
  103019. + IN gckHARDWARE Hardware,
  103020. + IN gctBOOL PowerManagement
  103021. + )
  103022. +{
  103023. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  103024. +
  103025. + /* Verify the arguments. */
  103026. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103027. +
  103028. + Hardware->powerManagement = PowerManagement;
  103029. +
  103030. + /* Success. */
  103031. + gcmkFOOTER_NO();
  103032. + return gcvSTATUS_OK;
  103033. +}
  103034. +
  103035. +/*******************************************************************************
  103036. +**
  103037. +** gckHARDWARE_SetGpuProfiler
  103038. +**
  103039. +** Configure GPU profiler function.
  103040. +** Only used in driver initialization stage.
  103041. +**
  103042. +** INPUT:
  103043. +**
  103044. +** gckHARDWARE Harwdare
  103045. +** Pointer to an gckHARDWARE object.
  103046. +**
  103047. +** gctBOOL GpuProfiler
  103048. +** GOU Profiler State.
  103049. +**
  103050. +*/
  103051. +gceSTATUS
  103052. +gckHARDWARE_SetGpuProfiler(
  103053. + IN gckHARDWARE Hardware,
  103054. + IN gctBOOL GpuProfiler
  103055. + )
  103056. +{
  103057. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  103058. +
  103059. + /* Verify the arguments. */
  103060. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103061. +
  103062. + Hardware->gpuProfiler = GpuProfiler;
  103063. +
  103064. + /* Success. */
  103065. + gcmkFOOTER_NO();
  103066. + return gcvSTATUS_OK;
  103067. +}
  103068. +
  103069. +#if gcdENABLE_FSCALE_VAL_ADJUST
  103070. +gceSTATUS
  103071. +gckHARDWARE_SetFscaleValue(
  103072. + IN gckHARDWARE Hardware,
  103073. + IN gctUINT32 FscaleValue
  103074. + )
  103075. +{
  103076. + gceSTATUS status;
  103077. + gctUINT32 clock;
  103078. + gctBOOL acquired = gcvFALSE;
  103079. +
  103080. + gcmkHEADER_ARG("Hardware=0x%x FscaleValue=%d", Hardware, FscaleValue);
  103081. +
  103082. + gcmkVERIFY_ARGUMENT(FscaleValue > 0 && FscaleValue <= 64);
  103083. +
  103084. + gcmkONERROR(
  103085. + gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
  103086. + acquired = gcvTRUE;
  103087. +
  103088. + Hardware->powerOnFscaleVal = FscaleValue;
  103089. +
  103090. + if (Hardware->chipPowerState == gcvPOWER_ON)
  103091. + {
  103092. + gctUINT32 data;
  103093. +
  103094. + gcmkONERROR(
  103095. + gckOS_ReadRegisterEx(Hardware->os,
  103096. + Hardware->core,
  103097. + Hardware->powerBaseAddress
  103098. + + 0x00104,
  103099. + &data));
  103100. +
  103101. + /* Disable all clock gating. */
  103102. + gcmkONERROR(
  103103. + gckOS_WriteRegisterEx(Hardware->os,
  103104. + Hardware->core,
  103105. + Hardware->powerBaseAddress
  103106. + + 0x00104,
  103107. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
  103108. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
  103109. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
  103110. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
  103111. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)))
  103112. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
  103113. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)))
  103114. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)))
  103115. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8)))
  103116. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))
  103117. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)))));
  103118. +
  103119. + clock = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
  103120. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
  103121. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (FscaleValue) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)))
  103122. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
  103123. +
  103124. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103125. + Hardware->core,
  103126. + 0x00000,
  103127. + clock));
  103128. +
  103129. + /* Done loading the frequency scaler. */
  103130. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103131. + Hardware->core,
  103132. + 0x00000,
  103133. + ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
  103134. +
  103135. + /* Restore all clock gating. */
  103136. + gcmkONERROR(
  103137. + gckOS_WriteRegisterEx(Hardware->os,
  103138. + Hardware->core,
  103139. + Hardware->powerBaseAddress
  103140. + + 0x00104,
  103141. + data));
  103142. + }
  103143. +
  103144. + gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  103145. +
  103146. + gcmkFOOTER_NO();
  103147. + return gcvSTATUS_OK;
  103148. +
  103149. +OnError:
  103150. + if (acquired)
  103151. + {
  103152. + gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  103153. + }
  103154. +
  103155. + gcmkFOOTER();
  103156. + return status;
  103157. +}
  103158. +
  103159. +gceSTATUS
  103160. +gckHARDWARE_GetFscaleValue(
  103161. + IN gckHARDWARE Hardware,
  103162. + IN gctUINT * FscaleValue,
  103163. + IN gctUINT * MinFscaleValue,
  103164. + IN gctUINT * MaxFscaleValue
  103165. + )
  103166. +{
  103167. + *FscaleValue = Hardware->powerOnFscaleVal;
  103168. + if ((gpu3DMinClock > 0) && (gpu3DMinClock <= 64) && (Hardware->core == gcvCORE_MAJOR))
  103169. + *MinFscaleValue = gpu3DMinClock;
  103170. + else
  103171. + *MinFscaleValue = 1;
  103172. + *MaxFscaleValue = 64;
  103173. +
  103174. + return gcvSTATUS_OK;
  103175. +}
  103176. +
  103177. +#endif
  103178. +
  103179. +#if gcdPOWEROFF_TIMEOUT
  103180. +gceSTATUS
  103181. +gckHARDWARE_SetPowerOffTimeout(
  103182. + IN gckHARDWARE Hardware,
  103183. + IN gctUINT32 Timeout
  103184. +)
  103185. +{
  103186. + gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
  103187. +
  103188. + Hardware->powerOffTimeout = Timeout;
  103189. +
  103190. + gcmkFOOTER_NO();
  103191. + return gcvSTATUS_OK;
  103192. +}
  103193. +
  103194. +
  103195. +gceSTATUS
  103196. +gckHARDWARE_QueryPowerOffTimeout(
  103197. + IN gckHARDWARE Hardware,
  103198. + OUT gctUINT32* Timeout
  103199. +)
  103200. +{
  103201. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  103202. +
  103203. + *Timeout = Hardware->powerOffTimeout;
  103204. +
  103205. + gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
  103206. + return gcvSTATUS_OK;
  103207. +}
  103208. +#endif
  103209. +
  103210. +gceSTATUS
  103211. +gckHARDWARE_QueryIdle(
  103212. + IN gckHARDWARE Hardware,
  103213. + OUT gctBOOL_PTR IsIdle
  103214. + )
  103215. +{
  103216. + gceSTATUS status;
  103217. + gctUINT32 idle, address;
  103218. +
  103219. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  103220. +
  103221. + /* Verify the arguments. */
  103222. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103223. + gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL);
  103224. +
  103225. + /* We are idle when the power is not ON. */
  103226. + if (Hardware->chipPowerState != gcvPOWER_ON)
  103227. + {
  103228. + *IsIdle = gcvTRUE;
  103229. + }
  103230. +
  103231. + else
  103232. + {
  103233. + /* Read idle register. */
  103234. + gcmkONERROR(
  103235. + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
  103236. +
  103237. + /* Pipe must be idle. */
  103238. + if (((((((gctUINT32) (idle)) >> (0 ? 1:1)) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1)))))) ) != 1)
  103239. + || ((((((gctUINT32) (idle)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) ) != 1)
  103240. + || ((((((gctUINT32) (idle)) >> (0 ? 4:4)) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1)))))) ) != 1)
  103241. + || ((((((gctUINT32) (idle)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ) != 1)
  103242. + || ((((((gctUINT32) (idle)) >> (0 ? 6:6)) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1)))))) ) != 1)
  103243. + || ((((((gctUINT32) (idle)) >> (0 ? 7:7)) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1)))))) ) != 1)
  103244. + || ((((((gctUINT32) (idle)) >> (0 ? 2:2)) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) ) != 1)
  103245. + )
  103246. + {
  103247. + /* Something is busy. */
  103248. + *IsIdle = gcvFALSE;
  103249. + }
  103250. +
  103251. + else
  103252. + {
  103253. + /* Read the current FE address. */
  103254. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  103255. + Hardware->core,
  103256. + 0x00664,
  103257. + &address));
  103258. +
  103259. + /* Test if address is inside the last WAIT/LINK sequence. */
  103260. + if ((address >= Hardware->lastWaitLink)
  103261. + && (address <= Hardware->lastWaitLink + 16)
  103262. + )
  103263. + {
  103264. + /* FE is in last WAIT/LINK and the pipe is idle. */
  103265. + *IsIdle = gcvTRUE;
  103266. + }
  103267. + else
  103268. + {
  103269. + /* FE is not in WAIT/LINK yet. */
  103270. + *IsIdle = gcvFALSE;
  103271. + }
  103272. + }
  103273. + }
  103274. +
  103275. + /* Success. */
  103276. + gcmkFOOTER_NO();
  103277. + return gcvSTATUS_OK;
  103278. +
  103279. +OnError:
  103280. + /* Return the status. */
  103281. + gcmkFOOTER();
  103282. + return status;
  103283. +}
  103284. +
  103285. +/*******************************************************************************
  103286. +** Handy macros that will help in reading those debug registers.
  103287. +*/
  103288. +
  103289. +#define gcmkREAD_DEBUG_REGISTER(control, block, index, data) \
  103290. + gcmkONERROR(\
  103291. + gckOS_WriteRegisterEx(Hardware->os, \
  103292. + Hardware->core, \
  103293. + GC_DEBUG_CONTROL##control##_Address, \
  103294. + gcmSETFIELD(0, \
  103295. + GC_DEBUG_CONTROL##control, \
  103296. + block, \
  103297. + index))); \
  103298. + gcmkONERROR(\
  103299. + gckOS_ReadRegisterEx(Hardware->os, \
  103300. + Hardware->core, \
  103301. + GC_DEBUG_SIGNALS_##block##_Address, \
  103302. + &profiler->data))
  103303. +
  103304. +#define gcmkREAD_DEBUG_REGISTER_N(control, block, index, data) \
  103305. + gcmkONERROR(\
  103306. + gckOS_WriteRegisterEx(Hardware->os, \
  103307. + Hardware->core, \
  103308. + GC_DEBUG_CONTROL##control##_Address, \
  103309. + gcmSETFIELD(0, \
  103310. + GC_DEBUG_CONTROL##control, \
  103311. + block, \
  103312. + index))); \
  103313. + gcmkONERROR(\
  103314. + gckOS_ReadRegisterEx(Hardware->os, \
  103315. + Hardware->core, \
  103316. + GC_DEBUG_SIGNALS_##block##_Address, \
  103317. + &data))
  103318. +
  103319. +#define gcmkRESET_DEBUG_REGISTER(control, block) \
  103320. + gcmkONERROR(\
  103321. + gckOS_WriteRegisterEx(Hardware->os, \
  103322. + Hardware->core, \
  103323. + GC_DEBUG_CONTROL##control##_Address, \
  103324. + gcmSETFIELD(0, \
  103325. + GC_DEBUG_CONTROL##control, \
  103326. + block, \
  103327. + 15))); \
  103328. + gcmkONERROR(\
  103329. + gckOS_WriteRegisterEx(Hardware->os, \
  103330. + Hardware->core, \
  103331. + GC_DEBUG_CONTROL##control##_Address, \
  103332. + gcmSETFIELD(0, \
  103333. + GC_DEBUG_CONTROL##control, \
  103334. + block, \
  103335. + 0)))
  103336. +
  103337. +/*******************************************************************************
  103338. +**
  103339. +** gckHARDWARE_ProfileEngine2D
  103340. +**
  103341. +** Read the profile registers available in the 2D engine and sets them in the
  103342. +** profile. The function will also reset the pixelsRendered counter every time.
  103343. +**
  103344. +** INPUT:
  103345. +**
  103346. +** gckHARDWARE Hardware
  103347. +** Pointer to an gckHARDWARE object.
  103348. +**
  103349. +** OPTIONAL gcs2D_PROFILE_PTR Profile
  103350. +** Pointer to a gcs2D_Profile structure.
  103351. +**
  103352. +** OUTPUT:
  103353. +**
  103354. +** Nothing.
  103355. +*/
  103356. +gceSTATUS
  103357. +gckHARDWARE_ProfileEngine2D(
  103358. + IN gckHARDWARE Hardware,
  103359. + OPTIONAL gcs2D_PROFILE_PTR Profile
  103360. + )
  103361. +{
  103362. + gceSTATUS status;
  103363. + gcs2D_PROFILE_PTR profiler = Profile;
  103364. +
  103365. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  103366. +
  103367. + /* Verify the arguments. */
  103368. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103369. +
  103370. + if (Profile != gcvNULL)
  103371. + {
  103372. + /* Read the cycle count. */
  103373. + gcmkONERROR(
  103374. + gckOS_ReadRegisterEx(Hardware->os,
  103375. + Hardware->core,
  103376. + 0x00438,
  103377. + &Profile->cycleCount));
  103378. +
  103379. + /* Read pixels rendered by 2D engine. */
  103380. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103381. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pixelsRendered));
  103382. +
  103383. + /* Reset counter. */
  103384. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103385. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
  103386. +));
  103387. + }
  103388. +
  103389. + /* Success. */
  103390. + gcmkFOOTER_NO();
  103391. + return gcvSTATUS_OK;
  103392. +
  103393. +OnError:
  103394. + /* Return the status. */
  103395. + gcmkFOOTER();
  103396. + return status;
  103397. +}
  103398. +
  103399. +#if VIVANTE_PROFILER
  103400. +gceSTATUS
  103401. +gckHARDWARE_QueryProfileRegisters(
  103402. + IN gckHARDWARE Hardware,
  103403. + IN gctBOOL Reset,
  103404. + OUT gcsPROFILER_COUNTERS * Counters
  103405. + )
  103406. +{
  103407. + gceSTATUS status;
  103408. + gcsPROFILER_COUNTERS * profiler = Counters;
  103409. + gctUINT i, clock;
  103410. + gctUINT32 colorKilled, colorDrawn, depthKilled, depthDrawn;
  103411. + gctUINT32 totalRead, totalWrite;
  103412. +
  103413. + gcmkHEADER_ARG("Hardware=0x%x Counters=0x%x", Hardware, Counters);
  103414. +
  103415. + /* Verify the arguments. */
  103416. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103417. +
  103418. + /* Read the counters. */
  103419. + gcmkONERROR(
  103420. + gckOS_ReadRegisterEx(Hardware->os,
  103421. + Hardware->core,
  103422. + 0x00438,
  103423. + &profiler->gpuCyclesCounter));
  103424. +
  103425. + gcmkONERROR(
  103426. + gckOS_ReadRegisterEx(Hardware->os,
  103427. + Hardware->core,
  103428. + 0x00078,
  103429. + &profiler->gpuTotalCyclesCounter));
  103430. +
  103431. + gcmkONERROR(
  103432. + gckOS_ReadRegisterEx(Hardware->os,
  103433. + Hardware->core,
  103434. + 0x0007C,
  103435. + &profiler->gpuIdleCyclesCounter));
  103436. +
  103437. +
  103438. + /* Read clock control register. */
  103439. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  103440. + Hardware->core,
  103441. + 0x00000,
  103442. + &clock));
  103443. +
  103444. + profiler->gpuTotalRead64BytesPerFrame = 0;
  103445. + profiler->gpuTotalWrite64BytesPerFrame = 0;
  103446. + profiler->pe_pixel_count_killed_by_color_pipe = 0;
  103447. + profiler->pe_pixel_count_killed_by_depth_pipe = 0;
  103448. + profiler->pe_pixel_count_drawn_by_color_pipe = 0;
  103449. + profiler->pe_pixel_count_drawn_by_depth_pipe = 0;
  103450. +
  103451. + /* Walk through all avaiable pixel pipes. */
  103452. + for (i = 0; i < Hardware->identity.pixelPipes; ++i)
  103453. + {
  103454. + /* Select proper pipe. */
  103455. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103456. + Hardware->core,
  103457. + 0x00000,
  103458. + ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
  103459. +
  103460. + /* BW */
  103461. + gcmkONERROR(
  103462. + gckOS_ReadRegisterEx(Hardware->os,
  103463. + Hardware->core,
  103464. + 0x00040,
  103465. + &totalRead));
  103466. + gcmkONERROR(
  103467. + gckOS_ReadRegisterEx(Hardware->os,
  103468. + Hardware->core,
  103469. + 0x00044,
  103470. + &totalWrite));
  103471. +
  103472. + profiler->gpuTotalRead64BytesPerFrame += totalRead;
  103473. + profiler->gpuTotalWrite64BytesPerFrame += totalWrite;
  103474. +
  103475. + /* PE */
  103476. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorKilled));
  103477. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthKilled));
  103478. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorDrawn));
  103479. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthDrawn));
  103480. +
  103481. + profiler->pe_pixel_count_killed_by_color_pipe += colorKilled;
  103482. + profiler->pe_pixel_count_killed_by_depth_pipe += depthKilled;
  103483. + profiler->pe_pixel_count_drawn_by_color_pipe += colorDrawn;
  103484. + profiler->pe_pixel_count_drawn_by_depth_pipe += depthDrawn;
  103485. + }
  103486. +
  103487. + /* Reset clock control register. */
  103488. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103489. + Hardware->core,
  103490. + 0x00000,
  103491. + clock));
  103492. +
  103493. + if(Reset){
  103494. + /* Reset counters. */
  103495. + gcmkONERROR(
  103496. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
  103497. + gcmkONERROR(
  103498. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
  103499. + gcmkONERROR(
  103500. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
  103501. + gcmkONERROR(
  103502. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
  103503. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103504. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
  103505. +));
  103506. + }
  103507. +
  103508. + /* SH */
  103509. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103510. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->ps_inst_counter));
  103511. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103512. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_pixel_counter));
  103513. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103514. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vs_inst_counter));
  103515. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103516. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_vertice_counter));
  103517. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103518. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_branch_inst_counter));
  103519. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (12) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103520. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_texld_inst_counter));
  103521. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (13) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103522. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter));
  103523. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103524. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter));
  103525. + if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103526. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
  103527. +));}
  103528. +
  103529. + /* PA */
  103530. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103531. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_vtx_counter));
  103532. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103533. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_prim_counter));
  103534. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103535. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_output_prim_counter));
  103536. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103537. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_depth_clipped_counter));
  103538. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103539. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter));
  103540. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103541. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter));
  103542. + if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103543. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
  103544. +));}
  103545. +
  103546. + /* SE */
  103547. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  103548. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count));
  103549. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  103550. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count));
  103551. + if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  103552. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
  103553. +));}
  103554. +
  103555. + /* RA */
  103556. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103557. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_pixel_count));
  103558. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103559. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_quad_count));
  103560. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103561. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_quad_count_after_early_z));
  103562. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103563. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_primitive_count));
  103564. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103565. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter));
  103566. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103567. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter));
  103568. + if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103569. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
  103570. +));}
  103571. +
  103572. + /* TX */
  103573. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103574. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_bilinear_requests));
  103575. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103576. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_trilinear_requests));
  103577. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103578. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_discarded_texture_requests));
  103579. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103580. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_texture_requests));
  103581. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103582. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_count));
  103583. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103584. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_in_8B_count));
  103585. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103586. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_count));
  103587. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103588. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count));
  103589. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103590. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count));
  103591. + if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103592. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
  103593. +));}
  103594. +
  103595. + /* MC */
  103596. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103597. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_pipeline));
  103598. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103599. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP));
  103600. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103601. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline));
  103602. + if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103603. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
  103604. +));}
  103605. +
  103606. + /* HI */
  103607. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  103608. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_read_request_stalled));
  103609. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  103610. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled));
  103611. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  103612. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled));
  103613. + if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  103614. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
  103615. +));}
  103616. +
  103617. + /* Success. */
  103618. + gcmkFOOTER_NO();
  103619. + return gcvSTATUS_OK;
  103620. +
  103621. +OnError:
  103622. + /* Return the status. */
  103623. + gcmkFOOTER();
  103624. + return status;
  103625. +}
  103626. +#endif
  103627. +
  103628. +#if VIVANTE_PROFILER_CONTEXT
  103629. +#define gcmkUPDATE_PROFILE_DATA(data) \
  103630. + profilerHistroy->data += profiler->data
  103631. +
  103632. +gceSTATUS
  103633. +gckHARDWARE_QueryContextProfile(
  103634. + IN gckHARDWARE Hardware,
  103635. + IN gctBOOL Reset,
  103636. + IN gckCONTEXT Context,
  103637. + OUT gcsPROFILER_COUNTERS * Counters
  103638. + )
  103639. +{
  103640. + gceSTATUS status;
  103641. + gckCOMMAND command = Hardware->kernel->command;
  103642. + gcsPROFILER_COUNTERS * profiler = Counters;
  103643. +
  103644. + gcmkHEADER_ARG("Hardware=0x%x Counters=0x%x", Hardware, Counters);
  103645. +
  103646. + /* Verify the arguments. */
  103647. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103648. +
  103649. + /* Acquire the context sequnence mutex. */
  103650. + gcmkONERROR(gckOS_AcquireMutex(
  103651. + command->os, command->mutexContextSeq, gcvINFINITE
  103652. + ));
  103653. +
  103654. + /* Read the counters. */
  103655. + gcmkVERIFY_OK(gckOS_MemCopy(
  103656. + profiler, &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS)
  103657. + ));
  103658. +
  103659. + if (Reset)
  103660. + {
  103661. + /* Reset counters. */
  103662. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  103663. + &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS)
  103664. + ));
  103665. + }
  103666. +
  103667. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  103668. + command->os, command->mutexContextSeq
  103669. + ));
  103670. +
  103671. + /* Success. */
  103672. + gcmkFOOTER_NO();
  103673. + return gcvSTATUS_OK;
  103674. +
  103675. +OnError:
  103676. + /* Return the status. */
  103677. + gcmkFOOTER();
  103678. + return status;
  103679. +}
  103680. +
  103681. +
  103682. +gceSTATUS
  103683. +gckHARDWARE_UpdateContextProfile(
  103684. + IN gckHARDWARE Hardware,
  103685. + IN gckCONTEXT Context
  103686. + )
  103687. +{
  103688. + gceSTATUS status;
  103689. + gcsPROFILER_COUNTERS * profiler = &Context->latestProfiler;
  103690. + gcsPROFILER_COUNTERS * profilerHistroy = &Context->histroyProfiler;
  103691. + gctUINT i, clock;
  103692. + gctUINT32 colorKilled, colorDrawn, depthKilled, depthDrawn;
  103693. + gctUINT32 totalRead, totalWrite;
  103694. + gceCHIPMODEL chipModel;
  103695. + gctUINT32 chipRevision;
  103696. + gctUINT32 temp;
  103697. + gctBOOL needResetShader = gcvFALSE;
  103698. +
  103699. + gcmkHEADER_ARG("Hardware=0x%x Context=0x%x", Hardware, Context);
  103700. +
  103701. + /* Verify the arguments. */
  103702. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103703. + gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
  103704. +
  103705. + chipModel = Hardware->identity.chipModel;
  103706. + chipRevision = Hardware->identity.chipRevision;
  103707. + if (chipModel == gcv2000 || (chipModel == gcv2100 && chipRevision == 0x5118))
  103708. + {
  103709. + needResetShader = gcvTRUE;
  103710. + }
  103711. +
  103712. + /* Read the counters. */
  103713. + gcmkONERROR(
  103714. + gckOS_ReadRegisterEx(Hardware->os,
  103715. + Hardware->core,
  103716. + 0x00438,
  103717. + &profiler->gpuCyclesCounter));
  103718. + gcmkUPDATE_PROFILE_DATA(gpuCyclesCounter);
  103719. +
  103720. + gcmkONERROR(
  103721. + gckOS_ReadRegisterEx(Hardware->os,
  103722. + Hardware->core,
  103723. + 0x00078,
  103724. + &profiler->gpuTotalCyclesCounter));
  103725. + gcmkUPDATE_PROFILE_DATA(gpuTotalCyclesCounter);
  103726. +
  103727. + gcmkONERROR(
  103728. + gckOS_ReadRegisterEx(Hardware->os,
  103729. + Hardware->core,
  103730. + 0x0007C,
  103731. + &profiler->gpuIdleCyclesCounter));
  103732. + gcmkUPDATE_PROFILE_DATA(gpuIdleCyclesCounter);
  103733. +
  103734. + /* Read clock control register. */
  103735. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  103736. + Hardware->core,
  103737. + 0x00000,
  103738. + &clock));
  103739. +
  103740. + profiler->gpuTotalRead64BytesPerFrame = 0;
  103741. + profiler->gpuTotalWrite64BytesPerFrame = 0;
  103742. + profiler->pe_pixel_count_killed_by_color_pipe = 0;
  103743. + profiler->pe_pixel_count_killed_by_depth_pipe = 0;
  103744. + profiler->pe_pixel_count_drawn_by_color_pipe = 0;
  103745. + profiler->pe_pixel_count_drawn_by_depth_pipe = 0;
  103746. +
  103747. + /* Walk through all avaiable pixel pipes. */
  103748. + for (i = 0; i < Hardware->identity.pixelPipes; ++i)
  103749. + {
  103750. + /* Select proper pipe. */
  103751. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103752. + Hardware->core,
  103753. + 0x00000,
  103754. + ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
  103755. +
  103756. + /* BW */
  103757. + gcmkONERROR(
  103758. + gckOS_ReadRegisterEx(Hardware->os,
  103759. + Hardware->core,
  103760. + 0x00040,
  103761. + &totalRead));
  103762. + gcmkONERROR(
  103763. + gckOS_ReadRegisterEx(Hardware->os,
  103764. + Hardware->core,
  103765. + 0x00044,
  103766. + &totalWrite));
  103767. +
  103768. + profiler->gpuTotalRead64BytesPerFrame += totalRead;
  103769. + profiler->gpuTotalWrite64BytesPerFrame += totalWrite;
  103770. + gcmkUPDATE_PROFILE_DATA(gpuTotalRead64BytesPerFrame);
  103771. + gcmkUPDATE_PROFILE_DATA(gpuTotalWrite64BytesPerFrame);
  103772. +
  103773. + /* PE */
  103774. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorKilled));
  103775. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthKilled));
  103776. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorDrawn));
  103777. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthDrawn));
  103778. +
  103779. + profiler->pe_pixel_count_killed_by_color_pipe += colorKilled;
  103780. + profiler->pe_pixel_count_killed_by_depth_pipe += depthKilled;
  103781. + profiler->pe_pixel_count_drawn_by_color_pipe += colorDrawn;
  103782. + profiler->pe_pixel_count_drawn_by_depth_pipe += depthDrawn;
  103783. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_killed_by_color_pipe);
  103784. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_killed_by_depth_pipe);
  103785. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_drawn_by_color_pipe);
  103786. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_drawn_by_depth_pipe);
  103787. + }
  103788. +
  103789. + /* Reset clock control register. */
  103790. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103791. + Hardware->core,
  103792. + 0x00000,
  103793. + clock));
  103794. +
  103795. +
  103796. +
  103797. +
  103798. + /* Reset counters. */
  103799. + gcmkONERROR(
  103800. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
  103801. + gcmkONERROR(
  103802. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
  103803. + gcmkONERROR(
  103804. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
  103805. + gcmkONERROR(
  103806. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
  103807. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103808. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
  103809. +));
  103810. +
  103811. + /* SH */
  103812. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103813. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->ps_inst_counter));
  103814. + if (needResetShader)
  103815. + {
  103816. + temp = profiler->ps_inst_counter;
  103817. + profiler->ps_inst_counter -= Context->prevPSInstCount;
  103818. + Context->prevPSInstCount = temp;
  103819. + }
  103820. + gcmkUPDATE_PROFILE_DATA(ps_inst_counter);
  103821. +
  103822. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103823. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_pixel_counter));
  103824. + if (needResetShader)
  103825. + {
  103826. + temp = profiler->rendered_pixel_counter;
  103827. + profiler->rendered_pixel_counter -= Context->prevPSPixelCount;
  103828. + Context->prevPSPixelCount = temp;
  103829. + }
  103830. + gcmkUPDATE_PROFILE_DATA(rendered_pixel_counter);
  103831. +
  103832. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103833. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vs_inst_counter));
  103834. + if (needResetShader)
  103835. + {
  103836. + temp = profiler->vs_inst_counter;
  103837. + profiler->vs_inst_counter -= Context->prevVSInstCount;
  103838. + Context->prevVSInstCount = temp;
  103839. + }
  103840. + gcmkUPDATE_PROFILE_DATA(vs_inst_counter);
  103841. +
  103842. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103843. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_vertice_counter));
  103844. + if (needResetShader)
  103845. + {
  103846. + temp = profiler->rendered_vertice_counter;
  103847. + profiler->rendered_vertice_counter -= Context->prevVSVertexCount;
  103848. + Context->prevVSVertexCount = temp;
  103849. + }
  103850. + gcmkUPDATE_PROFILE_DATA(rendered_vertice_counter);
  103851. +
  103852. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103853. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_branch_inst_counter));
  103854. + if (needResetShader)
  103855. + {
  103856. + temp = profiler->vtx_branch_inst_counter;
  103857. + profiler->vtx_branch_inst_counter -= Context->prevVSBranchInstCount;
  103858. + Context->prevVSBranchInstCount = temp;
  103859. + }
  103860. + gcmkUPDATE_PROFILE_DATA(vtx_branch_inst_counter);
  103861. +
  103862. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (12) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103863. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_texld_inst_counter));
  103864. + if (needResetShader)
  103865. + {
  103866. + temp = profiler->vtx_texld_inst_counter;
  103867. + profiler->vtx_texld_inst_counter -= Context->prevVSTexInstCount;
  103868. + Context->prevVSTexInstCount = temp;
  103869. + }
  103870. + gcmkUPDATE_PROFILE_DATA(vtx_texld_inst_counter);
  103871. +
  103872. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (13) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103873. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter));
  103874. + if (needResetShader)
  103875. + {
  103876. + temp = profiler->pxl_branch_inst_counter;
  103877. + profiler->pxl_branch_inst_counter -= Context->prevPSBranchInstCount;
  103878. + Context->prevPSBranchInstCount = temp;
  103879. + }
  103880. + gcmkUPDATE_PROFILE_DATA(pxl_branch_inst_counter);
  103881. +
  103882. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103883. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter));
  103884. + if (needResetShader)
  103885. + {
  103886. + temp = profiler->pxl_texld_inst_counter;
  103887. + profiler->pxl_texld_inst_counter -= Context->prevPSTexInstCount;
  103888. + Context->prevPSTexInstCount = temp;
  103889. + }
  103890. + gcmkUPDATE_PROFILE_DATA(pxl_texld_inst_counter);
  103891. +
  103892. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103893. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
  103894. +));
  103895. +
  103896. + /* PA */
  103897. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103898. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_vtx_counter));
  103899. + gcmkUPDATE_PROFILE_DATA(pa_input_vtx_counter);
  103900. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103901. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_prim_counter));
  103902. + gcmkUPDATE_PROFILE_DATA(pa_input_prim_counter);
  103903. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103904. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_output_prim_counter));
  103905. + gcmkUPDATE_PROFILE_DATA(pa_output_prim_counter);
  103906. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103907. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_depth_clipped_counter));
  103908. + gcmkUPDATE_PROFILE_DATA(pa_depth_clipped_counter);
  103909. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103910. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter));
  103911. + gcmkUPDATE_PROFILE_DATA(pa_trivial_rejected_counter);
  103912. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103913. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter));
  103914. + gcmkUPDATE_PROFILE_DATA(pa_culled_counter);
  103915. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103916. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
  103917. +));
  103918. +
  103919. + /* SE */
  103920. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  103921. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count));
  103922. + gcmkUPDATE_PROFILE_DATA(se_culled_triangle_count);
  103923. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  103924. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count));
  103925. + gcmkUPDATE_PROFILE_DATA(se_culled_lines_count);
  103926. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  103927. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
  103928. +));
  103929. +
  103930. + /* RA */
  103931. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103932. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_pixel_count));
  103933. + gcmkUPDATE_PROFILE_DATA(ra_valid_pixel_count);
  103934. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103935. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_quad_count));
  103936. + gcmkUPDATE_PROFILE_DATA(ra_total_quad_count);
  103937. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103938. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_quad_count_after_early_z));
  103939. + gcmkUPDATE_PROFILE_DATA(ra_valid_quad_count_after_early_z);
  103940. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103941. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_primitive_count));
  103942. + gcmkUPDATE_PROFILE_DATA(ra_total_primitive_count);
  103943. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103944. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter));
  103945. + gcmkUPDATE_PROFILE_DATA(ra_pipe_cache_miss_counter);
  103946. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103947. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter));
  103948. + gcmkUPDATE_PROFILE_DATA(ra_prefetch_cache_miss_counter);
  103949. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
  103950. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
  103951. +));
  103952. +
  103953. + /* TX */
  103954. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103955. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_bilinear_requests));
  103956. + gcmkUPDATE_PROFILE_DATA(tx_total_bilinear_requests);
  103957. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103958. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_trilinear_requests));
  103959. + gcmkUPDATE_PROFILE_DATA(tx_total_trilinear_requests);
  103960. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103961. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_discarded_texture_requests));
  103962. + gcmkUPDATE_PROFILE_DATA(tx_total_discarded_texture_requests);
  103963. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103964. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_texture_requests));
  103965. + gcmkUPDATE_PROFILE_DATA(tx_total_texture_requests);
  103966. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103967. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_count));
  103968. + gcmkUPDATE_PROFILE_DATA(tx_mem_read_count);
  103969. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103970. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_in_8B_count));
  103971. + gcmkUPDATE_PROFILE_DATA(tx_mem_read_in_8B_count);
  103972. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103973. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_count));
  103974. + gcmkUPDATE_PROFILE_DATA(tx_cache_miss_count);
  103975. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103976. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count));
  103977. + gcmkUPDATE_PROFILE_DATA(tx_cache_hit_texel_count);
  103978. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103979. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count));
  103980. + gcmkUPDATE_PROFILE_DATA(tx_cache_miss_texel_count);
  103981. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
  103982. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
  103983. +));
  103984. +
  103985. + /* MC */
  103986. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103987. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_pipeline));
  103988. + gcmkUPDATE_PROFILE_DATA(mc_total_read_req_8B_from_pipeline);
  103989. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103990. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP));
  103991. + gcmkUPDATE_PROFILE_DATA(mc_total_read_req_8B_from_IP);
  103992. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103993. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline));
  103994. + gcmkUPDATE_PROFILE_DATA(mc_total_write_req_8B_from_pipeline);
  103995. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
  103996. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
  103997. +));
  103998. +
  103999. + /* HI */
  104000. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  104001. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_read_request_stalled));
  104002. + gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_read_request_stalled);
  104003. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  104004. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled));
  104005. + gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_write_request_stalled);
  104006. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  104007. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled));
  104008. + gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_write_data_stalled);
  104009. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
  104010. +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
  104011. +));
  104012. +
  104013. + /* Success. */
  104014. + gcmkFOOTER_NO();
  104015. + return gcvSTATUS_OK;
  104016. +
  104017. +OnError:
  104018. + /* Return the status. */
  104019. + gcmkFOOTER();
  104020. + return status;
  104021. +}
  104022. +#endif
  104023. +
  104024. +static gceSTATUS
  104025. +_ResetGPU(
  104026. + IN gckHARDWARE Hardware,
  104027. + IN gckOS Os,
  104028. + IN gceCORE Core
  104029. + )
  104030. +{
  104031. + gctUINT32 control, idle;
  104032. + gceSTATUS status;
  104033. +
  104034. + for (;;)
  104035. + {
  104036. + /* Disable clock gating. */
  104037. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104038. + Core,
  104039. + Hardware->powerBaseAddress +
  104040. + 0x00104,
  104041. + 0x00000000));
  104042. +
  104043. + control = ((((gctUINT32) (0x01590880)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17)));
  104044. +
  104045. + /* Disable pulse-eater. */
  104046. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104047. + Core,
  104048. + 0x0010C,
  104049. + control));
  104050. +
  104051. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104052. + Core,
  104053. + 0x0010C,
  104054. + ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))));
  104055. +
  104056. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104057. + Core,
  104058. + 0x0010C,
  104059. + control));
  104060. +
  104061. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104062. + Core,
  104063. + 0x00000,
  104064. + ((((gctUINT32) (0x00000900)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
  104065. +
  104066. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104067. + Core,
  104068. + 0x00000,
  104069. + 0x00000900));
  104070. +
  104071. + /* Wait for clock being stable. */
  104072. + gcmkONERROR(gckOS_Delay(Os, 1));
  104073. +
  104074. + /* Isolate the GPU. */
  104075. + control = ((((gctUINT32) (0x00000900)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
  104076. +
  104077. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104078. + Core,
  104079. + 0x00000,
  104080. + control));
  104081. +
  104082. + /* Set soft reset. */
  104083. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104084. + Core,
  104085. + 0x00000,
  104086. + ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))));
  104087. +
  104088. + /* Wait for reset. */
  104089. + gcmkONERROR(gckOS_Delay(Os, 1));
  104090. +
  104091. + /* Reset soft reset bit. */
  104092. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104093. + Core,
  104094. + 0x00000,
  104095. + ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))));
  104096. +
  104097. + /* Reset GPU isolation. */
  104098. + control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
  104099. +
  104100. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104101. + Core,
  104102. + 0x00000,
  104103. + control));
  104104. +
  104105. + /* Read idle register. */
  104106. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  104107. + Core,
  104108. + 0x00004,
  104109. + &idle));
  104110. +
  104111. + if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) == 0)
  104112. + {
  104113. + continue;
  104114. + }
  104115. +
  104116. + /* Read reset register. */
  104117. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  104118. + Core,
  104119. + 0x00000,
  104120. + &control));
  104121. +
  104122. + if (((((((gctUINT32) (control)) >> (0 ? 16:16)) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) ) == 0)
  104123. + || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
  104124. + )
  104125. + {
  104126. + continue;
  104127. + }
  104128. +
  104129. + /* GPU is idle. */
  104130. + break;
  104131. + }
  104132. +
  104133. + /* Success. */
  104134. + return gcvSTATUS_OK;
  104135. +
  104136. +OnError:
  104137. +
  104138. + /* Return the error. */
  104139. + return status;
  104140. +}
  104141. +
  104142. +gceSTATUS
  104143. +gckHARDWARE_Reset(
  104144. + IN gckHARDWARE Hardware
  104145. + )
  104146. +{
  104147. + gceSTATUS status;
  104148. + gckCOMMAND command;
  104149. + gctBOOL acquired = gcvFALSE;
  104150. + gctBOOL mutexAcquired = gcvFALSE;
  104151. + gctUINT32 process, thread;
  104152. +
  104153. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  104154. +
  104155. + /* Verify the arguments. */
  104156. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104157. + gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
  104158. + command = Hardware->kernel->command;
  104159. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  104160. +
  104161. + if (Hardware->identity.chipRevision < 0x4600)
  104162. + {
  104163. + /* Not supported - we need the isolation bit. */
  104164. + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
  104165. + }
  104166. +
  104167. + status = gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, 0);
  104168. + if (status == gcvSTATUS_TIMEOUT)
  104169. + {
  104170. + gcmkONERROR(gckOS_GetProcessID(&process));
  104171. + gcmkONERROR(gckOS_GetThreadID(&thread));
  104172. +
  104173. + if ((Hardware->powerProcess == process)
  104174. + && (Hardware->powerThread == thread))
  104175. + {
  104176. + /* No way to recovery from a error in power management. */
  104177. + gcmkFOOTER_NO();
  104178. + return gcvSTATUS_OK;
  104179. + }
  104180. + }
  104181. + else
  104182. + {
  104183. + mutexAcquired = gcvTRUE;
  104184. + }
  104185. +
  104186. + if (Hardware->chipPowerState == gcvPOWER_ON)
  104187. + {
  104188. + /* Acquire the power management semaphore. */
  104189. + gcmkONERROR(
  104190. + gckOS_AcquireSemaphore(Hardware->os, command->powerSemaphore));
  104191. + acquired = gcvTRUE;
  104192. + }
  104193. +
  104194. + if ((Hardware->chipPowerState == gcvPOWER_ON)
  104195. + || (Hardware->chipPowerState == gcvPOWER_IDLE)
  104196. + )
  104197. + {
  104198. + /* Stop the command processor. */
  104199. + gcmkONERROR(gckCOMMAND_Stop(command, gcvTRUE));
  104200. + }
  104201. +
  104202. + /* Stop isr, we will start it again when power on GPU. */
  104203. + if (Hardware->stopIsr)
  104204. + {
  104205. + gcmkONERROR(Hardware->stopIsr(Hardware->isrContext, Hardware->core));
  104206. + }
  104207. +
  104208. + /* Hardware reset. */
  104209. + status = gckOS_ResetGPU(Hardware->os, Hardware->core);
  104210. +
  104211. + if (gcmIS_ERROR(status))
  104212. + {
  104213. + /* Soft reset. */
  104214. + gcmkONERROR(_ResetGPU(Hardware, Hardware->os, Hardware->core));
  104215. + }
  104216. +
  104217. + /* Force an OFF to ON power switch. */
  104218. + Hardware->chipPowerState = gcvPOWER_OFF;
  104219. +
  104220. + gcmkONERROR(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  104221. + mutexAcquired = gcvFALSE;
  104222. +
  104223. + /* Success. */
  104224. + gcmkFOOTER_NO();
  104225. + return gcvSTATUS_OK;
  104226. +
  104227. +OnError:
  104228. + if (acquired)
  104229. + {
  104230. + /* Release the power management semaphore. */
  104231. + gcmkVERIFY_OK(
  104232. + gckOS_ReleaseSemaphore(Hardware->os, command->powerSemaphore));
  104233. + }
  104234. +
  104235. + if (mutexAcquired)
  104236. + {
  104237. + gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
  104238. + }
  104239. +
  104240. + /* Return the error. */
  104241. + gcmkFOOTER();
  104242. + return status;
  104243. +}
  104244. +
  104245. +gceSTATUS
  104246. +gckHARDWARE_GetBaseAddress(
  104247. + IN gckHARDWARE Hardware,
  104248. + OUT gctUINT32_PTR BaseAddress
  104249. + )
  104250. +{
  104251. + gceSTATUS status;
  104252. +
  104253. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  104254. +
  104255. + /* Verify the arguments. */
  104256. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104257. + gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL);
  104258. +
  104259. + /* Test if we have a new Memory Controller. */
  104260. + if (((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 22:22) & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1))))))))
  104261. + {
  104262. + /* No base address required. */
  104263. + *BaseAddress = 0;
  104264. + }
  104265. + else
  104266. + {
  104267. + /* Get the base address from the OS. */
  104268. + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, BaseAddress));
  104269. + }
  104270. +
  104271. + /* Success. */
  104272. + gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
  104273. + return gcvSTATUS_OK;
  104274. +
  104275. +OnError:
  104276. + /* Return the status. */
  104277. + gcmkFOOTER();
  104278. + return status;
  104279. +}
  104280. +
  104281. +gceSTATUS
  104282. +gckHARDWARE_NeedBaseAddress(
  104283. + IN gckHARDWARE Hardware,
  104284. + IN gctUINT32 State,
  104285. + OUT gctBOOL_PTR NeedBase
  104286. + )
  104287. +{
  104288. + gctBOOL need = gcvFALSE;
  104289. +
  104290. + gcmkHEADER_ARG("Hardware=0x%x State=0x%08x", Hardware, State);
  104291. +
  104292. + /* Verify the arguments. */
  104293. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104294. + gcmkVERIFY_ARGUMENT(NeedBase != gcvNULL);
  104295. +
  104296. + /* Make sure this is a load state. */
  104297. + if (((((gctUINT32) (State)) >> (0 ? 31:27) & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))))
  104298. + {
  104299. +#ifndef VIVANTE_NO_3D
  104300. + /* Get the state address. */
  104301. + switch ((((((gctUINT32) (State)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) ))
  104302. + {
  104303. + case 0x0596:
  104304. + case 0x0597:
  104305. + case 0x0599:
  104306. + case 0x059A:
  104307. + case 0x05A9:
  104308. + /* These states need a TRUE physical address. */
  104309. + need = gcvTRUE;
  104310. + break;
  104311. + }
  104312. +#else
  104313. + /* 2D addresses don't need a base address. */
  104314. +#endif
  104315. + }
  104316. +
  104317. + /* Return the flag. */
  104318. + *NeedBase = need;
  104319. +
  104320. + /* Success. */
  104321. + gcmkFOOTER_ARG("*NeedBase=%d", *NeedBase);
  104322. + return gcvSTATUS_OK;
  104323. +}
  104324. +
  104325. +gceSTATUS
  104326. +gckHARDWARE_SetIsrManager(
  104327. + IN gckHARDWARE Hardware,
  104328. + IN gctISRMANAGERFUNC StartIsr,
  104329. + IN gctISRMANAGERFUNC StopIsr,
  104330. + IN gctPOINTER Context
  104331. + )
  104332. +{
  104333. + gceSTATUS status = gcvSTATUS_OK;
  104334. +
  104335. + gcmkHEADER_ARG("Hardware=0x%x, StartIsr=0x%x, StopIsr=0x%x, Context=0x%x",
  104336. + Hardware, StartIsr, StopIsr, Context);
  104337. +
  104338. + /* Verify the arguments. */
  104339. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104340. +
  104341. + if (StartIsr == gcvNULL ||
  104342. + StopIsr == gcvNULL ||
  104343. + Context == gcvNULL)
  104344. + {
  104345. + status = gcvSTATUS_INVALID_ARGUMENT;
  104346. +
  104347. + gcmkFOOTER();
  104348. + return status;
  104349. + }
  104350. +
  104351. + Hardware->startIsr = StartIsr;
  104352. + Hardware->stopIsr = StopIsr;
  104353. + Hardware->isrContext = Context;
  104354. +
  104355. + /* Success. */
  104356. + gcmkFOOTER();
  104357. +
  104358. + return status;
  104359. +}
  104360. +
  104361. +/*******************************************************************************
  104362. +**
  104363. +** gckHARDWARE_Compose
  104364. +**
  104365. +** Start a composition.
  104366. +**
  104367. +** INPUT:
  104368. +**
  104369. +** gckHARDWARE Hardware
  104370. +** Pointer to the gckHARDWARE object.
  104371. +**
  104372. +** OUTPUT:
  104373. +**
  104374. +** Nothing.
  104375. +*/
  104376. +gceSTATUS
  104377. +gckHARDWARE_Compose(
  104378. + IN gckHARDWARE Hardware,
  104379. + IN gctUINT32 ProcessID,
  104380. + IN gctPHYS_ADDR Physical,
  104381. + IN gctPOINTER Logical,
  104382. + IN gctSIZE_T Offset,
  104383. + IN gctSIZE_T Size,
  104384. + IN gctUINT8 EventID
  104385. + )
  104386. +{
  104387. +#ifndef VIVANTE_NO_3D
  104388. + gceSTATUS status;
  104389. + gctUINT32_PTR triggerState;
  104390. +
  104391. + gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x Logical=0x%x"
  104392. + " Offset=%d Size=%d EventID=%d",
  104393. + Hardware, Physical, Logical, Offset, Size, EventID);
  104394. +
  104395. + /* Verify the arguments. */
  104396. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104397. + gcmkVERIFY_ARGUMENT(((Size + 8) & 63) == 0);
  104398. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  104399. +
  104400. + /* Program the trigger state. */
  104401. + triggerState = (gctUINT32_PTR) ((gctUINT8_PTR) Logical + Offset + Size);
  104402. + triggerState[0] = 0x0C03;
  104403. + triggerState[1]
  104404. + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)))
  104405. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:4) - (0 ? 5:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:4) - (0 ? 5:4) + 1))))))) << (0 ? 5:4))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ? 5:4) - (0 ? 5:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:4) - (0 ? 5:4) + 1))))))) << (0 ? 5:4)))
  104406. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8)))
  104407. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24)))
  104408. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))
  104409. + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:16) - (0 ? 20:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:16) - (0 ? 20:16) + 1))))))) << (0 ? 20:16))) | (((gctUINT32) ((gctUINT32) (EventID) & ((gctUINT32) ((((1 ? 20:16) - (0 ? 20:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:16) - (0 ? 20:16) + 1))))))) << (0 ? 20:16)))
  104410. + ;
  104411. +
  104412. +#if gcdNONPAGED_MEMORY_CACHEABLE
  104413. + /* Flush the cache for the wait/link. */
  104414. + gcmkONERROR(gckOS_CacheClean(
  104415. + Hardware->os, ProcessID, gcvNULL,
  104416. + Physical, Logical, Offset + Size
  104417. + ));
  104418. +#endif
  104419. +
  104420. + /* Start composition. */
  104421. + gcmkONERROR(gckOS_WriteRegisterEx(
  104422. + Hardware->os, Hardware->core, 0x00554,
  104423. + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)))
  104424. + ));
  104425. +
  104426. + /* Success. */
  104427. + gcmkFOOTER_NO();
  104428. + return gcvSTATUS_OK;
  104429. +
  104430. +OnError:
  104431. + /* Return the status. */
  104432. + gcmkFOOTER();
  104433. + return status;
  104434. +#else
  104435. + /* Return the status. */
  104436. + return gcvSTATUS_NOT_SUPPORTED;
  104437. +#endif
  104438. +}
  104439. +
  104440. +/*******************************************************************************
  104441. +**
  104442. +** gckHARDWARE_IsFeatureAvailable
  104443. +**
  104444. +** Verifies whether the specified feature is available in hardware.
  104445. +**
  104446. +** INPUT:
  104447. +**
  104448. +** gckHARDWARE Hardware
  104449. +** Pointer to an gckHARDWARE object.
  104450. +**
  104451. +** gceFEATURE Feature
  104452. +** Feature to be verified.
  104453. +*/
  104454. +gceSTATUS
  104455. +gckHARDWARE_IsFeatureAvailable(
  104456. + IN gckHARDWARE Hardware,
  104457. + IN gceFEATURE Feature
  104458. + )
  104459. +{
  104460. + gctBOOL available;
  104461. +
  104462. + gcmkHEADER_ARG("Hardware=0x%x Feature=%d", Hardware, Feature);
  104463. +
  104464. + /* Verify the arguments. */
  104465. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104466. +
  104467. + /* Only features needed by common kernel logic added here. */
  104468. + switch (Feature)
  104469. + {
  104470. + case gcvFEATURE_END_EVENT:
  104471. + /*available = gcmVERIFYFIELDVALUE(Hardware->identity.chipMinorFeatures2,
  104472. + GC_MINOR_FEATURES2, END_EVENT, AVAILABLE
  104473. + );*/
  104474. + available = gcvFALSE;
  104475. + break;
  104476. + case gcvFEATURE_MC20:
  104477. + available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 22:22) & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))));
  104478. + break;
  104479. + case gcvFEATURE_DYNAMIC_FREQUENCY_SCALING:
  104480. + /* This feature doesn't apply for 2D cores. */
  104481. + available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures2)) >> (0 ? 14:14) & ((gctUINT32) ((((1 ? 14:14) - (0 ? 14:14) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 14:14) - (0 ? 14:14) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 14:14) - (0 ? 14:14) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 14:14) - (0 ? 14:14) + 1)))))))
  104482. + && ((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 2:2) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))));
  104483. + break;
  104484. +
  104485. + case gcvFEATURE_PIPE_2D:
  104486. + available = ((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 9:9) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))));
  104487. + break;
  104488. +
  104489. + case gcvFEATURE_PIPE_3D:
  104490. +#ifndef VIVANTE_NO_3D
  104491. + available = ((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 2:2) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))));
  104492. +#else
  104493. + available = gcvFALSE;
  104494. +#endif
  104495. + break;
  104496. +
  104497. + case gcvFEATURE_HALTI2:
  104498. + available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures4)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))));
  104499. + break;
  104500. +
  104501. + default:
  104502. + gcmkFATAL("Invalid feature has been requested.");
  104503. + available = gcvFALSE;
  104504. + }
  104505. +
  104506. + /* Return result. */
  104507. + gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_OK);
  104508. + return available ? gcvSTATUS_TRUE : gcvSTATUS_OK;
  104509. +}
  104510. +
  104511. +/*******************************************************************************
  104512. +**
  104513. +** gckHARDWARE_DumpMMUException
  104514. +**
  104515. +** Dump the MMU debug info on an MMU exception.
  104516. +**
  104517. +** INPUT:
  104518. +**
  104519. +** gckHARDWARE Harwdare
  104520. +** Pointer to an gckHARDWARE object.
  104521. +**
  104522. +** OUTPUT:
  104523. +**
  104524. +** Nothing.
  104525. +*/
  104526. +gceSTATUS
  104527. +gckHARDWARE_DumpMMUException(
  104528. + IN gckHARDWARE Hardware
  104529. + )
  104530. +{
  104531. +#if !gcdPOWER_SUSNPEND_WHEN_IDLE && !gcdPOWEROFF_TIMEOUT
  104532. + gctUINT32 mmu, mmuStatus, address, i;
  104533. +#if gcdDEBUG
  104534. + gctUINT32 mtlb, stlb, offset;
  104535. +#endif
  104536. +
  104537. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  104538. +
  104539. + /* Verify the arguments. */
  104540. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104541. +
  104542. + gcmkPRINT("GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
  104543. + Hardware->core,
  104544. + Hardware->identity.chipModel,
  104545. + Hardware->identity.chipRevision);
  104546. +
  104547. + gcmkPRINT("**************************\n");
  104548. + gcmkPRINT("*** MMU ERROR DUMP ***\n");
  104549. + gcmkPRINT("**************************\n");
  104550. +
  104551. + gcmkVERIFY_OK(
  104552. + gckOS_ReadRegisterEx(Hardware->os,
  104553. + Hardware->core,
  104554. + 0x00188,
  104555. + &mmuStatus));
  104556. +
  104557. + gcmkPRINT(" MMU status = 0x%08X\n", mmuStatus);
  104558. +
  104559. + for (i = 0; i < 4; i += 1)
  104560. + {
  104561. + mmu = mmuStatus & 0xF;
  104562. + mmuStatus >>= 4;
  104563. +
  104564. + if (mmu == 0)
  104565. + {
  104566. + continue;
  104567. + }
  104568. +
  104569. + switch (mmu)
  104570. + {
  104571. + case 1:
  104572. + gcmkPRINT(" MMU%d: slave not present\n", i);
  104573. + break;
  104574. +
  104575. + case 2:
  104576. + gcmkPRINT(" MMU%d: page not present\n", i);
  104577. + break;
  104578. +
  104579. + case 3:
  104580. + gcmkPRINT(" MMU%d: write violation\n", i);
  104581. + break;
  104582. +
  104583. + default:
  104584. + gcmkPRINT(" MMU%d: unknown state\n", i);
  104585. + }
  104586. +
  104587. + gcmkVERIFY_OK(
  104588. + gckOS_ReadRegisterEx(Hardware->os,
  104589. + Hardware->core,
  104590. + 0x00190 + i * 4,
  104591. + &address));
  104592. +
  104593. + mtlb = (address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
  104594. + stlb = (address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
  104595. + offset = address & gcdMMU_OFFSET_4K_MASK;
  104596. +
  104597. + gcmkPRINT(" MMU%d: exception address = 0x%08X\n", i, address);
  104598. +
  104599. + gcmkPRINT(" MTLB entry = %d\n", mtlb);
  104600. +
  104601. + gcmkPRINT(" STLB entry = %d\n", stlb);
  104602. +
  104603. + gcmkPRINT(" Offset = 0x%08X (%d)\n", offset, offset);
  104604. +
  104605. + gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, address);
  104606. +
  104607. + }
  104608. +
  104609. + gcmkFOOTER_NO();
  104610. +#else
  104611. + /* If clock could be off automatically, we can't read mmu debug
  104612. + ** register here; build driver with gcdPOWER_SUSPEND_WHEN_IDLE = 0
  104613. + ** and gcdPOWEROFF_TIMEOUT = 0 to make it safe to read mmu register. */
  104614. + gcmkPRINT("[galcore] %s(%d): MMU Exception!", __FUNCTION__, __LINE__);
  104615. +#endif
  104616. +
  104617. + return gcvSTATUS_OK;
  104618. +}
  104619. +
  104620. +/*******************************************************************************
  104621. +**
  104622. +** gckHARDWARE_DumpGPUState
  104623. +**
  104624. +** Dump the GPU debug registers.
  104625. +**
  104626. +** INPUT:
  104627. +**
  104628. +** gckHARDWARE Harwdare
  104629. +** Pointer to an gckHARDWARE object.
  104630. +**
  104631. +** OUTPUT:
  104632. +**
  104633. +** Nothing.
  104634. +*/
  104635. +gceSTATUS
  104636. +gckHARDWARE_DumpGPUState(
  104637. + IN gckHARDWARE Hardware
  104638. + )
  104639. +{
  104640. + static gctCONST_STRING _cmdState[] =
  104641. + {
  104642. + "PAR_IDLE_ST", "PAR_DEC_ST", "PAR_ADR0_ST", "PAR_LOAD0_ST",
  104643. + "PAR_ADR1_ST", "PAR_LOAD1_ST", "PAR_3DADR_ST", "PAR_3DCMD_ST",
  104644. + "PAR_3DCNTL_ST", "PAR_3DIDXCNTL_ST", "PAR_INITREQDMA_ST",
  104645. + "PAR_DRAWIDX_ST", "PAR_DRAW_ST", "PAR_2DRECT0_ST", "PAR_2DRECT1_ST",
  104646. + "PAR_2DDATA0_ST", "PAR_2DDATA1_ST", "PAR_WAITFIFO_ST", "PAR_WAIT_ST",
  104647. + "PAR_LINK_ST", "PAR_END_ST", "PAR_STALL_ST"
  104648. + };
  104649. +
  104650. + static gctCONST_STRING _cmdDmaState[] =
  104651. + {
  104652. + "CMD_IDLE_ST", "CMD_START_ST", "CMD_REQ_ST", "CMD_END_ST"
  104653. + };
  104654. +
  104655. + static gctCONST_STRING _cmdFetState[] =
  104656. + {
  104657. + "FET_IDLE_ST", "FET_RAMVALID_ST", "FET_VALID_ST"
  104658. + };
  104659. +
  104660. + static gctCONST_STRING _reqDmaState[] =
  104661. + {
  104662. + "REQ_IDLE_ST", "REQ_WAITIDX_ST", "REQ_CAL_ST"
  104663. + };
  104664. +
  104665. + static gctCONST_STRING _calState[] =
  104666. + {
  104667. + "CAL_IDLE_ST", "CAL_LDADR_ST", "CAL_IDXCALC_ST"
  104668. + };
  104669. +
  104670. + static gctCONST_STRING _veReqState[] =
  104671. + {
  104672. + "VER_IDLE_ST", "VER_CKCACHE_ST", "VER_MISS_ST"
  104673. + };
  104674. +
  104675. + static gcsiDEBUG_REGISTERS _dbgRegs[] =
  104676. + {
  104677. + { "RA", 0x474, 16, 0x448, 16, 0x12344321 },
  104678. + { "TX", 0x474, 24, 0x44C, 16, 0x12211221 },
  104679. + { "FE", 0x470, 0, 0x450, 16, 0xBABEF00D },
  104680. + { "PE", 0x470, 16, 0x454, 16, 0xBABEF00D },
  104681. + { "DE", 0x470, 8, 0x458, 16, 0xBABEF00D },
  104682. + { "SH", 0x470, 24, 0x45C, 16, 0xDEADBEEF },
  104683. + { "PA", 0x474, 0, 0x460, 16, 0x0000AAAA },
  104684. + { "SE", 0x474, 8, 0x464, 16, 0x5E5E5E5E },
  104685. + { "MC", 0x478, 0, 0x468, 16, 0x12345678 },
  104686. + { "HI", 0x478, 8, 0x46C, 16, 0xAAAAAAAA }
  104687. + };
  104688. +
  104689. + static gctUINT32 _otherRegs[] =
  104690. + {
  104691. + 0x040, 0x044, 0x04C, 0x050, 0x054, 0x058, 0x05C, 0x060,
  104692. + 0x43c, 0x440, 0x444, 0x414,
  104693. + };
  104694. +
  104695. + gceSTATUS status;
  104696. + gckKERNEL kernel;
  104697. + gctUINT32 idle, axi;
  104698. + gctUINT32 dmaAddress1, dmaAddress2;
  104699. + gctUINT32 dmaState1, dmaState2;
  104700. + gctUINT32 dmaLow, dmaHigh;
  104701. + gctUINT32 cmdState, cmdDmaState, cmdFetState;
  104702. + gctUINT32 dmaReqState, calState, veReqState;
  104703. + gctUINT i;
  104704. + gctUINT pipe, pixelPipes;
  104705. + gctUINT32 control, oldControl;
  104706. + gckOS os = Hardware->os;
  104707. + gceCORE core = Hardware->core;
  104708. +
  104709. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  104710. +
  104711. + kernel = Hardware->kernel;
  104712. +
  104713. + gcmkPRINT_N(12, "GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
  104714. + core,
  104715. + Hardware->identity.chipModel,
  104716. + Hardware->identity.chipRevision);
  104717. +
  104718. + pixelPipes = Hardware->identity.pixelPipes
  104719. + ? Hardware->identity.pixelPipes
  104720. + : 1;
  104721. +
  104722. + /* Reset register values. */
  104723. + idle = axi =
  104724. + dmaState1 = dmaState2 =
  104725. + dmaAddress1 = dmaAddress2 =
  104726. + dmaLow = dmaHigh = 0;
  104727. +
  104728. + /* Verify whether DMA is running. */
  104729. + gcmkONERROR(_VerifyDMA(
  104730. + os, core, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
  104731. + ));
  104732. +
  104733. + cmdState = dmaState2 & 0x1F;
  104734. + cmdDmaState = (dmaState2 >> 8) & 0x03;
  104735. + cmdFetState = (dmaState2 >> 10) & 0x03;
  104736. + dmaReqState = (dmaState2 >> 12) & 0x03;
  104737. + calState = (dmaState2 >> 14) & 0x03;
  104738. + veReqState = (dmaState2 >> 16) & 0x03;
  104739. +
  104740. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x004, &idle));
  104741. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x00C, &axi));
  104742. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x668, &dmaLow));
  104743. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x66C, &dmaHigh));
  104744. +
  104745. + gcmkPRINT_N(0, "**************************\n");
  104746. + gcmkPRINT_N(0, "*** GPU STATE DUMP ***\n");
  104747. + gcmkPRINT_N(0, "**************************\n");
  104748. +
  104749. + gcmkPRINT_N(4, " axi = 0x%08X\n", axi);
  104750. +
  104751. + gcmkPRINT_N(4, " idle = 0x%08X\n", idle);
  104752. + if ((idle & 0x00000001) == 0) gcmkPRINT_N(0, " FE not idle\n");
  104753. + if ((idle & 0x00000002) == 0) gcmkPRINT_N(0, " DE not idle\n");
  104754. + if ((idle & 0x00000004) == 0) gcmkPRINT_N(0, " PE not idle\n");
  104755. + if ((idle & 0x00000008) == 0) gcmkPRINT_N(0, " SH not idle\n");
  104756. + if ((idle & 0x00000010) == 0) gcmkPRINT_N(0, " PA not idle\n");
  104757. + if ((idle & 0x00000020) == 0) gcmkPRINT_N(0, " SE not idle\n");
  104758. + if ((idle & 0x00000040) == 0) gcmkPRINT_N(0, " RA not idle\n");
  104759. + if ((idle & 0x00000080) == 0) gcmkPRINT_N(0, " TX not idle\n");
  104760. + if ((idle & 0x00000100) == 0) gcmkPRINT_N(0, " VG not idle\n");
  104761. + if ((idle & 0x00000200) == 0) gcmkPRINT_N(0, " IM not idle\n");
  104762. + if ((idle & 0x00000400) == 0) gcmkPRINT_N(0, " FP not idle\n");
  104763. + if ((idle & 0x00000800) == 0) gcmkPRINT_N(0, " TS not idle\n");
  104764. + if ((idle & 0x80000000) != 0) gcmkPRINT_N(0, " AXI low power mode\n");
  104765. +
  104766. + if (
  104767. + (dmaAddress1 == dmaAddress2)
  104768. + && (dmaState1 == dmaState2)
  104769. + )
  104770. + {
  104771. + gcmkPRINT_N(0, " DMA appears to be stuck at this address:\n");
  104772. + gcmkPRINT_N(4, " 0x%08X\n", dmaAddress1);
  104773. + }
  104774. + else
  104775. + {
  104776. + if (dmaAddress1 == dmaAddress2)
  104777. + {
  104778. + gcmkPRINT_N(0, " DMA address is constant, but state is changing:\n");
  104779. + gcmkPRINT_N(4, " 0x%08X\n", dmaState1);
  104780. + gcmkPRINT_N(4, " 0x%08X\n", dmaState2);
  104781. + }
  104782. + else
  104783. + {
  104784. + gcmkPRINT_N(0, " DMA is running; known addresses are:\n");
  104785. + gcmkPRINT_N(4, " 0x%08X\n", dmaAddress1);
  104786. + gcmkPRINT_N(4, " 0x%08X\n", dmaAddress2);
  104787. + }
  104788. + }
  104789. + gcmkPRINT_N(4, " dmaLow = 0x%08X\n", dmaLow);
  104790. + gcmkPRINT_N(4, " dmaHigh = 0x%08X\n", dmaHigh);
  104791. + gcmkPRINT_N(4, " dmaState = 0x%08X\n", dmaState2);
  104792. + gcmkPRINT_N(8, " command state = %d (%s)\n", cmdState, _cmdState [cmdState]);
  104793. + gcmkPRINT_N(8, " command DMA state = %d (%s)\n", cmdDmaState, _cmdDmaState[cmdDmaState]);
  104794. + gcmkPRINT_N(8, " command fetch state = %d (%s)\n", cmdFetState, _cmdFetState[cmdFetState]);
  104795. + gcmkPRINT_N(8, " DMA request state = %d (%s)\n", dmaReqState, _reqDmaState[dmaReqState]);
  104796. + gcmkPRINT_N(8, " cal state = %d (%s)\n", calState, _calState [calState]);
  104797. + gcmkPRINT_N(8, " VE request state = %d (%s)\n", veReqState, _veReqState [veReqState]);
  104798. +
  104799. + /* Record control. */
  104800. + gckOS_ReadRegisterEx(os, core, 0x0, &oldControl);
  104801. +
  104802. + for (pipe = 0; pipe < pixelPipes; pipe++)
  104803. + {
  104804. + gcmkPRINT_N(4, " Debug registers of pipe[%d]:\n", pipe);
  104805. +
  104806. + /* Switch pipe. */
  104807. + gckOS_ReadRegisterEx(os, core, 0x0, &control);
  104808. + control &= ~(0xF << 20);
  104809. + control |= (pipe << 20);
  104810. + gckOS_WriteRegisterEx(os, core, 0x0, control);
  104811. +
  104812. + for (i = 0; i < gcmCOUNTOF(_dbgRegs); i += 1)
  104813. + {
  104814. + gcmkONERROR(_DumpDebugRegisters(os, core, &_dbgRegs[i]));
  104815. + }
  104816. +
  104817. + gcmkPRINT_N(0, " Other Registers:\n");
  104818. + for (i = 0; i < gcmCOUNTOF(_otherRegs); i += 1)
  104819. + {
  104820. + gctUINT32 read;
  104821. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, _otherRegs[i], &read));
  104822. + gcmkPRINT_N(12, " [0x%04X] 0x%08X\n", _otherRegs[i], read);
  104823. + }
  104824. + }
  104825. +
  104826. + if (kernel->hardware->identity.chipFeatures & (1 << 4))
  104827. + {
  104828. + gctUINT32 read0, read1, write;
  104829. +
  104830. + read0 = read1 = write = 0;
  104831. +
  104832. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x43C, &read0));
  104833. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x440, &read1));
  104834. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x444, &write));
  104835. +
  104836. + gcmkPRINT_N(4, " read0 = 0x%08X\n", read0);
  104837. + gcmkPRINT_N(4, " read1 = 0x%08X\n", read1);
  104838. + gcmkPRINT_N(4, " write = 0x%08X\n", write);
  104839. + }
  104840. +
  104841. + /* Restore control. */
  104842. + gckOS_WriteRegisterEx(os, core, 0x0, oldControl);
  104843. +
  104844. + /* dump stack. */
  104845. + gckOS_DumpCallStack(os);
  104846. +
  104847. +OnError:
  104848. +
  104849. + /* Return the error. */
  104850. + gcmkFOOTER();
  104851. + return status;
  104852. +}
  104853. +
  104854. +
  104855. +#if gcdFRAME_DB
  104856. +static gceSTATUS
  104857. +gckHARDWARE_ReadPerformanceRegister(
  104858. + IN gckHARDWARE Hardware,
  104859. + IN gctUINT PerformanceAddress,
  104860. + IN gctUINT IndexAddress,
  104861. + IN gctUINT IndexShift,
  104862. + IN gctUINT Index,
  104863. + OUT gctUINT32_PTR Value
  104864. + )
  104865. +{
  104866. + gceSTATUS status;
  104867. +
  104868. + gcmkHEADER_ARG("Hardware=0x%x PerformanceAddress=0x%x IndexAddress=0x%x "
  104869. + "IndexShift=%u Index=%u",
  104870. + Hardware, PerformanceAddress, IndexAddress, IndexShift,
  104871. + Index);
  104872. +
  104873. + /* Write the index. */
  104874. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  104875. + Hardware->core,
  104876. + IndexAddress,
  104877. + Index << IndexShift));
  104878. +
  104879. + /* Read the register. */
  104880. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  104881. + Hardware->core,
  104882. + PerformanceAddress,
  104883. + Value));
  104884. +
  104885. + /* Test for reset. */
  104886. + if (Index == 15)
  104887. + {
  104888. + /* Index another register to get out of reset. */
  104889. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, IndexAddress, 0));
  104890. + }
  104891. +
  104892. + /* Success. */
  104893. + gcmkFOOTER_ARG("*Value=0x%x", *Value);
  104894. + return gcvSTATUS_OK;
  104895. +
  104896. +OnError:
  104897. + /* Return the status. */
  104898. + gcmkFOOTER();
  104899. + return status;
  104900. +}
  104901. +
  104902. +gceSTATUS
  104903. +gckHARDWARE_GetFrameInfo(
  104904. + IN gckHARDWARE Hardware,
  104905. + OUT gcsHAL_FRAME_INFO * FrameInfo
  104906. + )
  104907. +{
  104908. + gceSTATUS status;
  104909. + gctUINT i, clock;
  104910. + gcsHAL_FRAME_INFO info;
  104911. +#if gcdFRAME_DB_RESET
  104912. + gctUINT reset;
  104913. +#endif
  104914. +
  104915. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  104916. +
  104917. + /* Get profile tick. */
  104918. + gcmkONERROR(gckOS_GetProfileTick(&info.ticks));
  104919. +
  104920. + /* Read SH counters and reset them. */
  104921. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104922. + Hardware,
  104923. + 0x0045C,
  104924. + 0x00470,
  104925. + 24,
  104926. + 4,
  104927. + &info.shaderCycles));
  104928. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104929. + Hardware,
  104930. + 0x0045C,
  104931. + 0x00470,
  104932. + 24,
  104933. + 9,
  104934. + &info.vsInstructionCount));
  104935. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104936. + Hardware,
  104937. + 0x0045C,
  104938. + 0x00470,
  104939. + 24,
  104940. + 12,
  104941. + &info.vsTextureCount));
  104942. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104943. + Hardware,
  104944. + 0x0045C,
  104945. + 0x00470,
  104946. + 24,
  104947. + 7,
  104948. + &info.psInstructionCount));
  104949. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104950. + Hardware,
  104951. + 0x0045C,
  104952. + 0x00470,
  104953. + 24,
  104954. + 14,
  104955. + &info.psTextureCount));
  104956. +#if gcdFRAME_DB_RESET
  104957. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104958. + Hardware,
  104959. + 0x0045C,
  104960. + 0x00470,
  104961. + 24,
  104962. + 15,
  104963. + &reset));
  104964. +#endif
  104965. +
  104966. + /* Read PA counters and reset them. */
  104967. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104968. + Hardware,
  104969. + 0x00460,
  104970. + 0x00474,
  104971. + 0,
  104972. + 3,
  104973. + &info.vertexCount));
  104974. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104975. + Hardware,
  104976. + 0x00460,
  104977. + 0x00474,
  104978. + 0,
  104979. + 4,
  104980. + &info.primitiveCount));
  104981. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104982. + Hardware,
  104983. + 0x00460,
  104984. + 0x00474,
  104985. + 0,
  104986. + 7,
  104987. + &info.rejectedPrimitives));
  104988. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104989. + Hardware,
  104990. + 0x00460,
  104991. + 0x00474,
  104992. + 0,
  104993. + 8,
  104994. + &info.culledPrimitives));
  104995. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104996. + Hardware,
  104997. + 0x00460,
  104998. + 0x00474,
  104999. + 0,
  105000. + 6,
  105001. + &info.clippedPrimitives));
  105002. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105003. + Hardware,
  105004. + 0x00460,
  105005. + 0x00474,
  105006. + 0,
  105007. + 5,
  105008. + &info.outPrimitives));
  105009. +#if gcdFRAME_DB_RESET
  105010. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105011. + Hardware,
  105012. + 0x00460,
  105013. + 0x00474,
  105014. + 0,
  105015. + 15,
  105016. + &reset));
  105017. +#endif
  105018. +
  105019. + /* Read RA counters and reset them. */
  105020. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105021. + Hardware,
  105022. + 0x00448,
  105023. + 0x00474,
  105024. + 16,
  105025. + 3,
  105026. + &info.inPrimitives));
  105027. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105028. + Hardware,
  105029. + 0x00448,
  105030. + 0x00474,
  105031. + 16,
  105032. + 11,
  105033. + &info.culledQuadCount));
  105034. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105035. + Hardware,
  105036. + 0x00448,
  105037. + 0x00474,
  105038. + 16,
  105039. + 1,
  105040. + &info.totalQuadCount));
  105041. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105042. + Hardware,
  105043. + 0x00448,
  105044. + 0x00474,
  105045. + 16,
  105046. + 2,
  105047. + &info.quadCount));
  105048. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105049. + Hardware,
  105050. + 0x00448,
  105051. + 0x00474,
  105052. + 16,
  105053. + 0,
  105054. + &info.totalPixelCount));
  105055. +#if gcdFRAME_DB_RESET
  105056. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105057. + Hardware,
  105058. + 0x00448,
  105059. + 0x00474,
  105060. + 16,
  105061. + 15,
  105062. + &reset));
  105063. +#endif
  105064. +
  105065. + /* Read TX counters and reset them. */
  105066. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105067. + Hardware,
  105068. + 0x0044C,
  105069. + 0x00474,
  105070. + 24,
  105071. + 0,
  105072. + &info.bilinearRequests));
  105073. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105074. + Hardware,
  105075. + 0x0044C,
  105076. + 0x00474,
  105077. + 24,
  105078. + 1,
  105079. + &info.trilinearRequests));
  105080. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105081. + Hardware,
  105082. + 0x0044C,
  105083. + 0x00474,
  105084. + 24,
  105085. + 8,
  105086. + &info.txHitCount));
  105087. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105088. + Hardware,
  105089. + 0x0044C,
  105090. + 0x00474,
  105091. + 24,
  105092. + 9,
  105093. + &info.txMissCount));
  105094. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105095. + Hardware,
  105096. + 0x0044C,
  105097. + 0x00474,
  105098. + 24,
  105099. + 6,
  105100. + &info.txBytes8));
  105101. +#if gcdFRAME_DB_RESET
  105102. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105103. + Hardware,
  105104. + 0x0044C,
  105105. + 0x00474,
  105106. + 24,
  105107. + 15,
  105108. + &reset));
  105109. +#endif
  105110. +
  105111. + /* Read clock control register. */
  105112. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105113. + Hardware->core,
  105114. + 0x00000,
  105115. + &clock));
  105116. +
  105117. + /* Walk through all avaiable pixel pipes. */
  105118. + for (i = 0; i < Hardware->identity.pixelPipes; ++i)
  105119. + {
  105120. + /* Select proper pipe. */
  105121. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105122. + Hardware->core,
  105123. + 0x00000,
  105124. + ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
  105125. +
  105126. + /* Read cycle registers. */
  105127. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105128. + Hardware->core,
  105129. + 0x00078,
  105130. + &info.cycles[i]));
  105131. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105132. + Hardware->core,
  105133. + 0x0007C,
  105134. + &info.idleCycles[i]));
  105135. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105136. + Hardware->core,
  105137. + 0x00438,
  105138. + &info.mcCycles[i]));
  105139. +
  105140. + /* Read bandwidth registers. */
  105141. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105142. + Hardware->core,
  105143. + 0x0005C,
  105144. + &info.readRequests[i]));
  105145. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105146. + Hardware->core,
  105147. + 0x00040,
  105148. + &info.readBytes8[i]));
  105149. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105150. + Hardware->core,
  105151. + 0x00050,
  105152. + &info.writeRequests[i]));
  105153. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105154. + Hardware->core,
  105155. + 0x00044,
  105156. + &info.writeBytes8[i]));
  105157. +
  105158. + /* Read PE counters. */
  105159. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105160. + Hardware,
  105161. + 0x00454,
  105162. + 0x00470,
  105163. + 16,
  105164. + 0,
  105165. + &info.colorKilled[i]));
  105166. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105167. + Hardware,
  105168. + 0x00454,
  105169. + 0x00470,
  105170. + 16,
  105171. + 2,
  105172. + &info.colorDrawn[i]));
  105173. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105174. + Hardware,
  105175. + 0x00454,
  105176. + 0x00470,
  105177. + 16,
  105178. + 1,
  105179. + &info.depthKilled[i]));
  105180. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105181. + Hardware,
  105182. + 0x00454,
  105183. + 0x00470,
  105184. + 16,
  105185. + 3,
  105186. + &info.depthDrawn[i]));
  105187. + }
  105188. +
  105189. + /* Zero out remaning reserved counters. */
  105190. + for (; i < 8; ++i)
  105191. + {
  105192. + info.readBytes8[i] = 0;
  105193. + info.writeBytes8[i] = 0;
  105194. + info.cycles[i] = 0;
  105195. + info.idleCycles[i] = 0;
  105196. + info.mcCycles[i] = 0;
  105197. + info.readRequests[i] = 0;
  105198. + info.writeRequests[i] = 0;
  105199. + info.colorKilled[i] = 0;
  105200. + info.colorDrawn[i] = 0;
  105201. + info.depthKilled[i] = 0;
  105202. + info.depthDrawn[i] = 0;
  105203. + }
  105204. +
  105205. + /* Reset clock control register. */
  105206. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105207. + Hardware->core,
  105208. + 0x00000,
  105209. + clock));
  105210. +
  105211. + /* Reset cycle and bandwidth counters. */
  105212. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105213. + Hardware->core,
  105214. + 0x0003C,
  105215. + 1));
  105216. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105217. + Hardware->core,
  105218. + 0x0003C,
  105219. + 0));
  105220. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105221. + Hardware->core,
  105222. + 0x00078,
  105223. + 0));
  105224. +
  105225. +#if gcdFRAME_DB_RESET
  105226. + /* Reset PE counters. */
  105227. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105228. + Hardware,
  105229. + 0x00454,
  105230. + 0x00470,
  105231. + 16,
  105232. + 15,
  105233. + &reset));
  105234. +#endif
  105235. +
  105236. + /* Copy to user. */
  105237. + gcmkONERROR(gckOS_CopyToUserData(Hardware->os,
  105238. + &info,
  105239. + FrameInfo,
  105240. + gcmSIZEOF(info)));
  105241. +
  105242. + /* Success. */
  105243. + gcmkFOOTER_NO();
  105244. + return gcvSTATUS_OK;
  105245. +
  105246. +OnError:
  105247. + /* Return the status. */
  105248. + gcmkFOOTER();
  105249. + return status;
  105250. +}
  105251. +#endif
  105252. +
  105253. +#if gcdDVFS
  105254. +#define READ_FROM_EATER1 0
  105255. +
  105256. +gceSTATUS
  105257. +gckHARDWARE_QueryLoad(
  105258. + IN gckHARDWARE Hardware,
  105259. + OUT gctUINT32 * Load
  105260. + )
  105261. +{
  105262. + gctUINT32 debug1;
  105263. + gceSTATUS status;
  105264. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  105265. +
  105266. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105267. + gcmkVERIFY_ARGUMENT(Load != gcvNULL);
  105268. +
  105269. + gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
  105270. +
  105271. + if (Hardware->chipPowerState == gcvPOWER_ON)
  105272. + {
  105273. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105274. + Hardware->core,
  105275. + 0x00110,
  105276. + Load));
  105277. +#if READ_FROM_EATER1
  105278. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105279. + Hardware->core,
  105280. + 0x00134,
  105281. + Load));
  105282. +#endif
  105283. +
  105284. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105285. + Hardware->core,
  105286. + 0x00114,
  105287. + &debug1));
  105288. +
  105289. + /* Patch result of 0x110 with result of 0x114. */
  105290. + if ((debug1 & 0xFF) == 1)
  105291. + {
  105292. + *Load &= ~0xFF;
  105293. + *Load |= 1;
  105294. + }
  105295. +
  105296. + if (((debug1 & 0xFF00) >> 8) == 1)
  105297. + {
  105298. + *Load &= ~(0xFF << 8);
  105299. + *Load |= 1 << 8;
  105300. + }
  105301. +
  105302. + if (((debug1 & 0xFF0000) >> 16) == 1)
  105303. + {
  105304. + *Load &= ~(0xFF << 16);
  105305. + *Load |= 1 << 16;
  105306. + }
  105307. +
  105308. + if (((debug1 & 0xFF000000) >> 24) == 1)
  105309. + {
  105310. + *Load &= ~(0xFF << 24);
  105311. + *Load |= 1 << 24;
  105312. + }
  105313. + }
  105314. + else
  105315. + {
  105316. + status = gcvSTATUS_INVALID_REQUEST;
  105317. + }
  105318. +
  105319. +OnError:
  105320. +
  105321. + gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
  105322. +
  105323. + gcmkFOOTER();
  105324. + return status;
  105325. +}
  105326. +
  105327. +gceSTATUS
  105328. +gckHARDWARE_SetDVFSPeroid(
  105329. + IN gckHARDWARE Hardware,
  105330. + OUT gctUINT32 Frequency
  105331. + )
  105332. +{
  105333. + gceSTATUS status;
  105334. + gctUINT32 period;
  105335. + gctUINT32 eater;
  105336. +
  105337. +#if READ_FROM_EATER1
  105338. + gctUINT32 period1;
  105339. + gctUINT32 eater1;
  105340. +#endif
  105341. +
  105342. + gcmkHEADER_ARG("Hardware=0x%X Frequency=%d", Hardware, Frequency);
  105343. +
  105344. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105345. +
  105346. + period = 0;
  105347. +
  105348. + while((64 << period) < (gcdDVFS_ANAYLSE_WINDOW * Frequency * 1000) )
  105349. + {
  105350. + period++;
  105351. + }
  105352. +
  105353. +#if READ_FROM_EATER1
  105354. + /*
  105355. + * Peroid = F * 1000 * 1000 / (60 * 16 * 1024);
  105356. + */
  105357. + period1 = Frequency * 6250 / 6114;
  105358. +#endif
  105359. +
  105360. + gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
  105361. +
  105362. + if (Hardware->chipPowerState == gcvPOWER_ON)
  105363. + {
  105364. + /* Get current configure. */
  105365. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105366. + Hardware->core,
  105367. + 0x0010C,
  105368. + &eater));
  105369. +
  105370. + /* Change peroid. */
  105371. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105372. + Hardware->core,
  105373. + 0x0010C,
  105374. + ((((gctUINT32) (eater)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (period) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))));
  105375. +
  105376. +#if READ_FROM_EATER1
  105377. + /* Config eater1. */
  105378. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105379. + Hardware->core,
  105380. + 0x00130,
  105381. + &eater1));
  105382. +
  105383. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105384. + Hardware->core,
  105385. + 0x00130,
  105386. + ((((gctUINT32) (eater1)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1))))))) << (0 ? 31:16))) | (((gctUINT32) ((gctUINT32) (period1) & ((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1))))))) << (0 ? 31:16)))));
  105387. +#endif
  105388. + }
  105389. + else
  105390. + {
  105391. + status = gcvSTATUS_INVALID_REQUEST;
  105392. + }
  105393. +
  105394. +OnError:
  105395. + gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
  105396. +
  105397. + gcmkFOOTER();
  105398. + return status;
  105399. +}
  105400. +
  105401. +gceSTATUS
  105402. +gckHARDWARE_InitDVFS(
  105403. + IN gckHARDWARE Hardware
  105404. + )
  105405. +{
  105406. + gceSTATUS status;
  105407. + gctUINT32 data;
  105408. +
  105409. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  105410. +
  105411. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105412. +
  105413. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105414. + Hardware->core,
  105415. + 0x0010C,
  105416. + &data));
  105417. +
  105418. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
  105419. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18)));
  105420. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
  105421. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20)));
  105422. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23)));
  105423. + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1))))))) << (0 ? 22:22))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1))))))) << (0 ? 22:22)));
  105424. +
  105425. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  105426. + "DVFS Configure=0x%X",
  105427. + data);
  105428. +
  105429. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105430. + Hardware->core,
  105431. + 0x0010C,
  105432. + data));
  105433. +
  105434. + gcmkFOOTER_NO();
  105435. + return gcvSTATUS_OK;
  105436. +
  105437. +OnError:
  105438. + gcmkFOOTER();
  105439. + return status;
  105440. +}
  105441. +#endif
  105442. +
  105443. +
  105444. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h
  105445. --- linux-3.14.15/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h 1970-01-01 01:00:00.000000000 +0100
  105446. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h 2014-08-20 19:23:53.562845855 +0200
  105447. @@ -0,0 +1,136 @@
  105448. +/****************************************************************************
  105449. +*
  105450. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  105451. +*
  105452. +* This program is free software; you can redistribute it and/or modify
  105453. +* it under the terms of the GNU General Public License as published by
  105454. +* the Free Software Foundation; either version 2 of the license, or
  105455. +* (at your option) any later version.
  105456. +*
  105457. +* This program is distributed in the hope that it will be useful,
  105458. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  105459. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  105460. +* GNU General Public License for more details.
  105461. +*
  105462. +* You should have received a copy of the GNU General Public License
  105463. +* along with this program; if not write to the Free Software
  105464. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  105465. +*
  105466. +*****************************************************************************/
  105467. +
  105468. +
  105469. +#ifndef __gc_hal_kernel_hardware_h_
  105470. +#define __gc_hal_kernel_hardware_h_
  105471. +
  105472. +#if gcdENABLE_VG
  105473. +#include "gc_hal_kernel_hardware_vg.h"
  105474. +#endif
  105475. +
  105476. +#ifdef __cplusplus
  105477. +extern "C" {
  105478. +#endif
  105479. +
  105480. +/* gckHARDWARE object. */
  105481. +struct _gckHARDWARE
  105482. +{
  105483. + /* Object. */
  105484. + gcsOBJECT object;
  105485. +
  105486. + /* Pointer to gctKERNEL object. */
  105487. + gckKERNEL kernel;
  105488. +
  105489. + /* Pointer to gctOS object. */
  105490. + gckOS os;
  105491. +
  105492. + /* Core */
  105493. + gceCORE core;
  105494. +
  105495. + /* Chip characteristics. */
  105496. + gcsHAL_QUERY_CHIP_IDENTITY identity;
  105497. + gctBOOL allowFastClear;
  105498. + gctBOOL allowCompression;
  105499. + gctUINT32 powerBaseAddress;
  105500. + gctBOOL extraEventStates;
  105501. +
  105502. + /* Big endian */
  105503. + gctBOOL bigEndian;
  105504. +
  105505. + /* Chip status */
  105506. + gctPOINTER powerMutex;
  105507. + gctUINT32 powerProcess;
  105508. + gctUINT32 powerThread;
  105509. + gceCHIPPOWERSTATE chipPowerState;
  105510. + gctUINT32 lastWaitLink;
  105511. + gctBOOL clockState;
  105512. + gctBOOL powerState;
  105513. + gctPOINTER globalSemaphore;
  105514. +
  105515. + gctISRMANAGERFUNC startIsr;
  105516. + gctISRMANAGERFUNC stopIsr;
  105517. + gctPOINTER isrContext;
  105518. +
  105519. + gctUINT32 mmuVersion;
  105520. +
  105521. + /* Type */
  105522. + gceHARDWARE_TYPE type;
  105523. +
  105524. +#if gcdPOWEROFF_TIMEOUT
  105525. + gctUINT32 powerOffTime;
  105526. + gctUINT32 powerOffTimeout;
  105527. + gctPOINTER powerOffTimer;
  105528. +#endif
  105529. +
  105530. + gctPOINTER pageTableDirty;
  105531. +
  105532. +#if gcdENABLE_FSCALE_VAL_ADJUST
  105533. + /* FSCALE_VAL when gcvPOWER_ON. */
  105534. + gctUINT32 powerOnFscaleVal;
  105535. +#endif
  105536. +
  105537. +#if gcdLINK_QUEUE_SIZE
  105538. + struct _gckLINKQUEUE linkQueue;
  105539. +#endif
  105540. +
  105541. + gctBOOL powerManagement;
  105542. + gctBOOL gpuProfiler;
  105543. +};
  105544. +
  105545. +gceSTATUS
  105546. +gckHARDWARE_GetBaseAddress(
  105547. + IN gckHARDWARE Hardware,
  105548. + OUT gctUINT32_PTR BaseAddress
  105549. + );
  105550. +
  105551. +gceSTATUS
  105552. +gckHARDWARE_NeedBaseAddress(
  105553. + IN gckHARDWARE Hardware,
  105554. + IN gctUINT32 State,
  105555. + OUT gctBOOL_PTR NeedBase
  105556. + );
  105557. +
  105558. +gceSTATUS
  105559. +gckHARDWARE_GetFrameInfo(
  105560. + IN gckHARDWARE Hardware,
  105561. + OUT gcsHAL_FRAME_INFO * FrameInfo
  105562. + );
  105563. +
  105564. +gceSTATUS
  105565. +gckHARDWARE_SetFscaleValue(
  105566. + IN gckHARDWARE Hardware,
  105567. + IN gctUINT32 FscaleValue
  105568. + );
  105569. +
  105570. +gceSTATUS
  105571. +gckHARDWARE_GetFscaleValue(
  105572. + IN gckHARDWARE Hardware,
  105573. + IN gctUINT * FscaleValue,
  105574. + IN gctUINT * MinFscaleValue,
  105575. + IN gctUINT * MaxFscaleValue
  105576. + );
  105577. +
  105578. +#ifdef __cplusplus
  105579. +}
  105580. +#endif
  105581. +
  105582. +#endif /* __gc_hal_kernel_hardware_h_ */
  105583. +
  105584. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/config linux-linaro-stable-mx6/drivers/mxc/gpu-viv/config
  105585. --- linux-3.14.15/drivers/mxc/gpu-viv/config 1970-01-01 01:00:00.000000000 +0100
  105586. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/config 2014-08-20 19:31:46.128869007 +0200
  105587. @@ -0,0 +1,38 @@
  105588. +##############################################################################
  105589. +#
  105590. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  105591. +#
  105592. +# This program is free software; you can redistribute it and/or modify
  105593. +# it under the terms of the GNU General Public License as published by
  105594. +# the Free Software Foundation; either version 2 of the license, or
  105595. +# (at your option) any later version.
  105596. +#
  105597. +# This program is distributed in the hope that it will be useful,
  105598. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  105599. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  105600. +# GNU General Public License for more details.
  105601. +#
  105602. +# You should have received a copy of the GNU General Public License
  105603. +# along with this program; if not write to the Free Software
  105604. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  105605. +#
  105606. +##############################################################################
  105607. +
  105608. +
  105609. +ARCH_TYPE ?= arm
  105610. +SDK_DIR ?= $(AQROOT)/build/sdk
  105611. +USE_3D_VG ?= 1
  105612. +FORCE_ALL_VIDEO_MEMORY_CACHED ?= 0
  105613. +NONPAGED_MEMORY_CACHEABLE ?= 0
  105614. +NONPAGED_MEMORY_BUFFERABLE ?= 1
  105615. +CACHE_FUNCTION_UNIMPLEMENTED ?= 0
  105616. +VIVANTE_ENABLE_VG ?= 1
  105617. +NO_USER_DIRECT_ACCESS_FROM_KERNEL ?= 1
  105618. +VIVANTE_NO_3D ?= 0
  105619. +ENABLE_OUTER_CACHE_PATCH ?= 1
  105620. +USE_BANK_ALIGNMENT ?= 1
  105621. +BANK_BIT_START ?= 13
  105622. +BANK_BIT_END ?= 15
  105623. +BANK_CHANNEL_BIT ?= 12
  105624. +ENABLE_GPU_CLOCK_BY_DRIVER = 1
  105625. +
  105626. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
  105627. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c 1970-01-01 01:00:00.000000000 +0100
  105628. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c 2014-08-20 19:31:46.128869007 +0200
  105629. @@ -0,0 +1,3967 @@
  105630. +/****************************************************************************
  105631. +*
  105632. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  105633. +*
  105634. +* This program is free software; you can redistribute it and/or modify
  105635. +* it under the terms of the GNU General Public License as published by
  105636. +* the Free Software Foundation; either version 2 of the license, or
  105637. +* (at your option) any later version.
  105638. +*
  105639. +* This program is distributed in the hope that it will be useful,
  105640. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  105641. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  105642. +* GNU General Public License for more details.
  105643. +*
  105644. +* You should have received a copy of the GNU General Public License
  105645. +* along with this program; if not write to the Free Software
  105646. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  105647. +*
  105648. +*****************************************************************************/
  105649. +
  105650. +
  105651. +#include "gc_hal_kernel_precomp.h"
  105652. +
  105653. +#define _GC_OBJ_ZONE gcvZONE_KERNEL
  105654. +
  105655. +/*******************************************************************************
  105656. +***** Version Signature *******************************************************/
  105657. +
  105658. +#define _gcmTXT2STR(t) #t
  105659. +#define gcmTXT2STR(t) _gcmTXT2STR(t)
  105660. +const char * _VERSION = "\n\0$VERSION$"
  105661. + gcmTXT2STR(gcvVERSION_MAJOR) "."
  105662. + gcmTXT2STR(gcvVERSION_MINOR) "."
  105663. + gcmTXT2STR(gcvVERSION_PATCH) ":"
  105664. + gcmTXT2STR(gcvVERSION_BUILD) "$\n";
  105665. +
  105666. +/******************************************************************************\
  105667. +******************************* gckKERNEL API Code ******************************
  105668. +\******************************************************************************/
  105669. +
  105670. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  105671. +#define gcmDEFINE2TEXT(d) #d
  105672. +gctCONST_STRING _DispatchText[] =
  105673. +{
  105674. + gcmDEFINE2TEXT(gcvHAL_QUERY_VIDEO_MEMORY),
  105675. + gcmDEFINE2TEXT(gcvHAL_QUERY_CHIP_IDENTITY),
  105676. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_NON_PAGED_MEMORY),
  105677. + gcmDEFINE2TEXT(gcvHAL_FREE_NON_PAGED_MEMORY),
  105678. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY),
  105679. + gcmDEFINE2TEXT(gcvHAL_FREE_CONTIGUOUS_MEMORY),
  105680. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_VIDEO_MEMORY),
  105681. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY),
  105682. + gcmDEFINE2TEXT(gcvHAL_FREE_VIDEO_MEMORY),
  105683. + gcmDEFINE2TEXT(gcvHAL_MAP_MEMORY),
  105684. + gcmDEFINE2TEXT(gcvHAL_UNMAP_MEMORY),
  105685. + gcmDEFINE2TEXT(gcvHAL_MAP_USER_MEMORY),
  105686. + gcmDEFINE2TEXT(gcvHAL_UNMAP_USER_MEMORY),
  105687. + gcmDEFINE2TEXT(gcvHAL_LOCK_VIDEO_MEMORY),
  105688. + gcmDEFINE2TEXT(gcvHAL_UNLOCK_VIDEO_MEMORY),
  105689. + gcmDEFINE2TEXT(gcvHAL_EVENT_COMMIT),
  105690. + gcmDEFINE2TEXT(gcvHAL_USER_SIGNAL),
  105691. + gcmDEFINE2TEXT(gcvHAL_SIGNAL),
  105692. + gcmDEFINE2TEXT(gcvHAL_WRITE_DATA),
  105693. + gcmDEFINE2TEXT(gcvHAL_COMMIT),
  105694. + gcmDEFINE2TEXT(gcvHAL_STALL),
  105695. + gcmDEFINE2TEXT(gcvHAL_READ_REGISTER),
  105696. + gcmDEFINE2TEXT(gcvHAL_WRITE_REGISTER),
  105697. + gcmDEFINE2TEXT(gcvHAL_GET_PROFILE_SETTING),
  105698. + gcmDEFINE2TEXT(gcvHAL_SET_PROFILE_SETTING),
  105699. + gcmDEFINE2TEXT(gcvHAL_READ_ALL_PROFILE_REGISTERS),
  105700. +#if VIVANTE_PROFILER_PERDRAW
  105701. + gcmDEFINE2TEXT(gcvHAL_READ_PROFILER_REGISTER_SETTING),
  105702. +#endif
  105703. + gcmDEFINE2TEXT(gcvHAL_PROFILE_REGISTERS_2D),
  105704. + gcmDEFINE2TEXT(gcvHAL_SET_POWER_MANAGEMENT_STATE),
  105705. + gcmDEFINE2TEXT(gcvHAL_QUERY_POWER_MANAGEMENT_STATE),
  105706. + gcmDEFINE2TEXT(gcvHAL_GET_BASE_ADDRESS),
  105707. + gcmDEFINE2TEXT(gcvHAL_SET_IDLE),
  105708. + gcmDEFINE2TEXT(gcvHAL_QUERY_KERNEL_SETTINGS),
  105709. + gcmDEFINE2TEXT(gcvHAL_RESET),
  105710. + gcmDEFINE2TEXT(gcvHAL_MAP_PHYSICAL),
  105711. + gcmDEFINE2TEXT(gcvHAL_DEBUG),
  105712. + gcmDEFINE2TEXT(gcvHAL_CACHE),
  105713. + gcmDEFINE2TEXT(gcvHAL_TIMESTAMP),
  105714. + gcmDEFINE2TEXT(gcvHAL_DATABASE),
  105715. + gcmDEFINE2TEXT(gcvHAL_VERSION),
  105716. + gcmDEFINE2TEXT(gcvHAL_CHIP_INFO),
  105717. + gcmDEFINE2TEXT(gcvHAL_ATTACH),
  105718. + gcmDEFINE2TEXT(gcvHAL_DETACH)
  105719. +};
  105720. +#endif
  105721. +
  105722. +#if gcdENABLE_RECOVERY
  105723. +void
  105724. +_ResetFinishFunction(
  105725. + gctPOINTER Data
  105726. + )
  105727. +{
  105728. + gckKERNEL kernel = (gckKERNEL)Data;
  105729. +
  105730. + gckOS_AtomSet(kernel->os, kernel->resetAtom, 0);
  105731. +}
  105732. +#endif
  105733. +
  105734. +/*******************************************************************************
  105735. +**
  105736. +** gckKERNEL_Construct
  105737. +**
  105738. +** Construct a new gckKERNEL object.
  105739. +**
  105740. +** INPUT:
  105741. +**
  105742. +** gckOS Os
  105743. +** Pointer to an gckOS object.
  105744. +**
  105745. +** gceCORE Core
  105746. +** Specified core.
  105747. +**
  105748. +** IN gctPOINTER Context
  105749. +** Pointer to a driver defined context.
  105750. +**
  105751. +** IN gckDB SharedDB,
  105752. +** Pointer to a shared DB.
  105753. +**
  105754. +** OUTPUT:
  105755. +**
  105756. +** gckKERNEL * Kernel
  105757. +** Pointer to a variable that will hold the pointer to the gckKERNEL
  105758. +** object.
  105759. +*/
  105760. +
  105761. +gceSTATUS
  105762. +gckKERNEL_Construct(
  105763. + IN gckOS Os,
  105764. + IN gceCORE Core,
  105765. + IN gctPOINTER Context,
  105766. + IN gckDB SharedDB,
  105767. + OUT gckKERNEL * Kernel
  105768. + )
  105769. +{
  105770. + gckKERNEL kernel = gcvNULL;
  105771. + gceSTATUS status;
  105772. + gctSIZE_T i;
  105773. + gctPOINTER pointer = gcvNULL;
  105774. +
  105775. + gcmkHEADER_ARG("Os=0x%x Context=0x%x", Os, Context);
  105776. +
  105777. + /* Verify the arguments. */
  105778. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  105779. + gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
  105780. +
  105781. + /* Allocate the gckKERNEL object. */
  105782. + gcmkONERROR(gckOS_Allocate(Os,
  105783. + gcmSIZEOF(struct _gckKERNEL),
  105784. + &pointer));
  105785. +
  105786. + kernel = pointer;
  105787. +
  105788. + /* Zero the object pointers. */
  105789. + kernel->hardware = gcvNULL;
  105790. + kernel->command = gcvNULL;
  105791. + kernel->eventObj = gcvNULL;
  105792. + kernel->mmu = gcvNULL;
  105793. +#if gcdDVFS
  105794. + kernel->dvfs = gcvNULL;
  105795. +#endif
  105796. +
  105797. + /* Initialize the gckKERNEL object. */
  105798. + kernel->object.type = gcvOBJ_KERNEL;
  105799. + kernel->os = Os;
  105800. + kernel->core = Core;
  105801. +
  105802. +
  105803. + if (SharedDB == gcvNULL)
  105804. + {
  105805. + gcmkONERROR(gckOS_Allocate(Os,
  105806. + gcmSIZEOF(struct _gckDB),
  105807. + &pointer));
  105808. +
  105809. + kernel->db = pointer;
  105810. + kernel->dbCreated = gcvTRUE;
  105811. + kernel->db->freeDatabase = gcvNULL;
  105812. + kernel->db->freeRecord = gcvNULL;
  105813. + kernel->db->dbMutex = gcvNULL;
  105814. + kernel->db->lastDatabase = gcvNULL;
  105815. + kernel->db->idleTime = 0;
  105816. + kernel->db->lastIdle = 0;
  105817. + kernel->db->lastSlowdown = 0;
  105818. +
  105819. + for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
  105820. + {
  105821. + kernel->db->db[i] = gcvNULL;
  105822. + }
  105823. +
  105824. + /* Construct a database mutex. */
  105825. + gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->dbMutex));
  105826. +
  105827. + /* Construct a id-pointer database. */
  105828. + gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->pointerDatabase));
  105829. +
  105830. + /* Construct a id-pointer database mutex. */
  105831. + gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->pointerDatabaseMutex));
  105832. + }
  105833. + else
  105834. + {
  105835. + kernel->db = SharedDB;
  105836. + kernel->dbCreated = gcvFALSE;
  105837. + }
  105838. +
  105839. + for (i = 0; i < gcmCOUNTOF(kernel->timers); ++i)
  105840. + {
  105841. + kernel->timers[i].startTime = 0;
  105842. + kernel->timers[i].stopTime = 0;
  105843. + }
  105844. +
  105845. + kernel->timeOut = gcdGPU_TIMEOUT;
  105846. +
  105847. + /* Save context. */
  105848. + kernel->context = Context;
  105849. +
  105850. +#if gcdVIRTUAL_COMMAND_BUFFER
  105851. + kernel->virtualBufferHead =
  105852. + kernel->virtualBufferTail = gcvNULL;
  105853. +
  105854. + gcmkONERROR(
  105855. + gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock));
  105856. +#endif
  105857. +
  105858. + /* Construct atom holding number of clients. */
  105859. + kernel->atomClients = gcvNULL;
  105860. + gcmkONERROR(gckOS_AtomConstruct(Os, &kernel->atomClients));
  105861. +
  105862. +#if gcdENABLE_VG
  105863. + kernel->vg = gcvNULL;
  105864. +
  105865. + if (Core == gcvCORE_VG)
  105866. + {
  105867. + /* Construct the gckMMU object. */
  105868. + gcmkONERROR(
  105869. + gckVGKERNEL_Construct(Os, Context, kernel, &kernel->vg));
  105870. + }
  105871. + else
  105872. +#endif
  105873. + {
  105874. + /* Construct the gckHARDWARE object. */
  105875. + gcmkONERROR(
  105876. + gckHARDWARE_Construct(Os, kernel->core, &kernel->hardware));
  105877. +
  105878. + /* Set pointer to gckKERNEL object in gckHARDWARE object. */
  105879. + kernel->hardware->kernel = kernel;
  105880. +
  105881. + /* Initialize the hardware. */
  105882. + gcmkONERROR(
  105883. + gckHARDWARE_InitializeHardware(kernel->hardware));
  105884. +
  105885. + /* Construct the gckCOMMAND object. */
  105886. + gcmkONERROR(
  105887. + gckCOMMAND_Construct(kernel, &kernel->command));
  105888. +
  105889. + /* Construct the gckEVENT object. */
  105890. + gcmkONERROR(
  105891. + gckEVENT_Construct(kernel, &kernel->eventObj));
  105892. +
  105893. + /* Construct the gckMMU object. */
  105894. + gcmkONERROR(
  105895. + gckMMU_Construct(kernel, gcdMMU_SIZE, &kernel->mmu));
  105896. +
  105897. +#if gcdENABLE_RECOVERY
  105898. + gcmkONERROR(
  105899. + gckOS_AtomConstruct(Os, &kernel->resetAtom));
  105900. +
  105901. + gcmkVERIFY_OK(
  105902. + gckOS_CreateTimer(Os,
  105903. + (gctTIMERFUNCTION)_ResetFinishFunction,
  105904. + (gctPOINTER)kernel,
  105905. + &kernel->resetFlagClearTimer));
  105906. + kernel->resetTimeStamp = 0;
  105907. +#endif
  105908. +
  105909. +#if gcdDVFS
  105910. + if (gckHARDWARE_IsFeatureAvailable(kernel->hardware,
  105911. + gcvFEATURE_DYNAMIC_FREQUENCY_SCALING))
  105912. + {
  105913. + gcmkONERROR(gckDVFS_Construct(kernel->hardware, &kernel->dvfs));
  105914. + gcmkONERROR(gckDVFS_Start(kernel->dvfs));
  105915. + }
  105916. +#endif
  105917. + }
  105918. +
  105919. + spin_lock_init(&kernel->irq_lock);
  105920. +
  105921. +#if VIVANTE_PROFILER
  105922. + /* Initialize profile setting */
  105923. + kernel->profileEnable = gcvFALSE;
  105924. + kernel->profileCleanRegister = gcvTRUE;
  105925. +#endif
  105926. +
  105927. +#if gcdANDROID_NATIVE_FENCE_SYNC
  105928. + gcmkONERROR(gckOS_CreateSyncTimeline(Os, &kernel->timeline));
  105929. +#endif
  105930. +
  105931. + /* Return pointer to the gckKERNEL object. */
  105932. + *Kernel = kernel;
  105933. +
  105934. + /* Success. */
  105935. + gcmkFOOTER_ARG("*Kernel=0x%x", *Kernel);
  105936. + return gcvSTATUS_OK;
  105937. +
  105938. +OnError:
  105939. + if (kernel != gcvNULL)
  105940. + {
  105941. +#if gcdENABLE_VG
  105942. + if (Core != gcvCORE_VG)
  105943. +#endif
  105944. + {
  105945. + if (kernel->eventObj != gcvNULL)
  105946. + {
  105947. + gcmkVERIFY_OK(gckEVENT_Destroy(kernel->eventObj));
  105948. + }
  105949. +
  105950. + if (kernel->command != gcvNULL)
  105951. + {
  105952. + gcmkVERIFY_OK(gckCOMMAND_Destroy(kernel->command));
  105953. + }
  105954. +
  105955. + if (kernel->hardware != gcvNULL)
  105956. + {
  105957. + /* Turn off the power. */
  105958. + gcmkVERIFY_OK(gckOS_SetGPUPower(kernel->hardware->os,
  105959. + kernel->hardware->core,
  105960. + gcvFALSE,
  105961. + gcvFALSE));
  105962. + gcmkVERIFY_OK(gckHARDWARE_Destroy(kernel->hardware));
  105963. + }
  105964. + }
  105965. +
  105966. + if (kernel->atomClients != gcvNULL)
  105967. + {
  105968. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->atomClients));
  105969. + }
  105970. +
  105971. +#if gcdENABLE_RECOVERY
  105972. + if (kernel->resetAtom != gcvNULL)
  105973. + {
  105974. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->resetAtom));
  105975. + }
  105976. +
  105977. + if (kernel->resetFlagClearTimer)
  105978. + {
  105979. + gcmkVERIFY_OK(gckOS_StopTimer(Os, kernel->resetFlagClearTimer));
  105980. + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, kernel->resetFlagClearTimer));
  105981. + }
  105982. +#endif
  105983. +
  105984. + if (kernel->dbCreated && kernel->db != gcvNULL)
  105985. + {
  105986. + if (kernel->db->dbMutex != gcvNULL)
  105987. + {
  105988. + /* Destroy the database mutex. */
  105989. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, kernel->db->dbMutex));
  105990. + }
  105991. +
  105992. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel->db));
  105993. + }
  105994. +
  105995. +#if gcdVIRTUAL_COMMAND_BUFFER
  105996. + if (kernel->virtualBufferLock != gcvNULL)
  105997. + {
  105998. + /* Destroy the virtual command buffer mutex. */
  105999. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, kernel->virtualBufferLock));
  106000. + }
  106001. +#endif
  106002. +
  106003. +#if gcdDVFS
  106004. + if (kernel->dvfs)
  106005. + {
  106006. + gcmkVERIFY_OK(gckDVFS_Stop(kernel->dvfs));
  106007. + gcmkVERIFY_OK(gckDVFS_Destroy(kernel->dvfs));
  106008. + }
  106009. +#endif
  106010. +
  106011. +#if gcdANDROID_NATIVE_FENCE_SYNC
  106012. + if (kernel->timeline)
  106013. + {
  106014. + gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Os, kernel->timeline));
  106015. + }
  106016. +#endif
  106017. +
  106018. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel));
  106019. + }
  106020. +
  106021. + /* Return the error. */
  106022. + gcmkFOOTER();
  106023. + return status;
  106024. +}
  106025. +
  106026. +/*******************************************************************************
  106027. +**
  106028. +** gckKERNEL_Destroy
  106029. +**
  106030. +** Destroy an gckKERNEL object.
  106031. +**
  106032. +** INPUT:
  106033. +**
  106034. +** gckKERNEL Kernel
  106035. +** Pointer to an gckKERNEL object to destroy.
  106036. +**
  106037. +** OUTPUT:
  106038. +**
  106039. +** Nothing.
  106040. +*/
  106041. +gceSTATUS
  106042. +gckKERNEL_Destroy(
  106043. + IN gckKERNEL Kernel
  106044. + )
  106045. +{
  106046. + gctSIZE_T i;
  106047. + gcsDATABASE_PTR database, databaseNext;
  106048. + gcsDATABASE_RECORD_PTR record, recordNext;
  106049. +
  106050. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  106051. +
  106052. + /* Verify the arguments. */
  106053. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  106054. +#if QNX_SINGLE_THREADED_DEBUGGING
  106055. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->debugMutex));
  106056. +#endif
  106057. +
  106058. + /* Destroy the database. */
  106059. + if (Kernel->dbCreated)
  106060. + {
  106061. + for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
  106062. + {
  106063. + if (Kernel->db->db[i] != gcvNULL)
  106064. + {
  106065. + gcmkVERIFY_OK(
  106066. + gckKERNEL_DestroyProcessDB(Kernel, Kernel->db->db[i]->processID));
  106067. + }
  106068. + }
  106069. +
  106070. + /* Free all databases. */
  106071. + for (database = Kernel->db->freeDatabase;
  106072. + database != gcvNULL;
  106073. + database = databaseNext)
  106074. + {
  106075. + databaseNext = database->next;
  106076. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, database));
  106077. + }
  106078. +
  106079. + if (Kernel->db->lastDatabase != gcvNULL)
  106080. + {
  106081. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db->lastDatabase));
  106082. + }
  106083. +
  106084. + /* Free all database records. */
  106085. + for (record = Kernel->db->freeRecord; record != gcvNULL; record = recordNext)
  106086. + {
  106087. + recordNext = record->next;
  106088. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, record));
  106089. + }
  106090. +
  106091. + /* Destroy the database mutex. */
  106092. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->dbMutex));
  106093. +
  106094. +
  106095. + /* Destroy id-pointer database. */
  106096. + gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Kernel->db->pointerDatabase));
  106097. +
  106098. + /* Destroy id-pointer database mutex. */
  106099. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
  106100. + }
  106101. +
  106102. +#if gcdENABLE_VG
  106103. + if (Kernel->vg)
  106104. + {
  106105. + gcmkVERIFY_OK(gckVGKERNEL_Destroy(Kernel->vg));
  106106. + }
  106107. + else
  106108. +#endif
  106109. + {
  106110. + /* Destroy the gckMMU object. */
  106111. + gcmkVERIFY_OK(gckMMU_Destroy(Kernel->mmu));
  106112. +
  106113. + /* Destroy the gckCOMMNAND object. */
  106114. + gcmkVERIFY_OK(gckCOMMAND_Destroy(Kernel->command));
  106115. +
  106116. + /* Destroy the gckEVENT object. */
  106117. + gcmkVERIFY_OK(gckEVENT_Destroy(Kernel->eventObj));
  106118. +
  106119. + /* Destroy the gckHARDWARE object. */
  106120. + gcmkVERIFY_OK(gckHARDWARE_Destroy(Kernel->hardware));
  106121. +
  106122. +#if gcdENABLE_RECOVERY
  106123. + gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->resetAtom));
  106124. +
  106125. + if (Kernel->resetFlagClearTimer)
  106126. + {
  106127. + gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->resetFlagClearTimer));
  106128. + gcmkVERIFY_OK(gckOS_DestroyTimer(Kernel->os, Kernel->resetFlagClearTimer));
  106129. + }
  106130. +#endif
  106131. + }
  106132. +
  106133. + /* Detsroy the client atom. */
  106134. + gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->atomClients));
  106135. +
  106136. +#if gcdVIRTUAL_COMMAND_BUFFER
  106137. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->virtualBufferLock));
  106138. +#endif
  106139. +
  106140. +#if gcdDVFS
  106141. + if (Kernel->dvfs)
  106142. + {
  106143. + gcmkVERIFY_OK(gckDVFS_Stop(Kernel->dvfs));
  106144. + gcmkVERIFY_OK(gckDVFS_Destroy(Kernel->dvfs));
  106145. + }
  106146. +#endif
  106147. +
  106148. +#if gcdANDROID_NATIVE_FENCE_SYNC
  106149. + gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Kernel->os, Kernel->timeline));
  106150. +#endif
  106151. +
  106152. + /* Mark the gckKERNEL object as unknown. */
  106153. + Kernel->object.type = gcvOBJ_UNKNOWN;
  106154. +
  106155. + /* Free the gckKERNEL object. */
  106156. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel));
  106157. +
  106158. + /* Success. */
  106159. + gcmkFOOTER_NO();
  106160. + return gcvSTATUS_OK;
  106161. +}
  106162. +
  106163. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  106164. +#include <linux/kernel.h>
  106165. +#include <linux/mm.h>
  106166. +#include <linux/oom.h>
  106167. +#include <linux/sched.h>
  106168. +#include <linux/notifier.h>
  106169. +
  106170. +extern struct task_struct *lowmem_deathpending;
  106171. +static unsigned long lowmem_deathpending_timeout;
  106172. +
  106173. +static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel)
  106174. +{
  106175. + struct task_struct *p;
  106176. + struct task_struct *selected = NULL;
  106177. + int tasksize;
  106178. + int ret = -1;
  106179. + int min_adj = 0;
  106180. + int selected_tasksize = 0;
  106181. + int selected_oom_adj;
  106182. + /*
  106183. + * If we already have a death outstanding, then
  106184. + * bail out right away; indicating to vmscan
  106185. + * that we have nothing further to offer on
  106186. + * this pass.
  106187. + *
  106188. + */
  106189. + if (lowmem_deathpending &&
  106190. + time_before_eq(jiffies, lowmem_deathpending_timeout))
  106191. + return 0;
  106192. + selected_oom_adj = min_adj;
  106193. +
  106194. + read_lock(&tasklist_lock);
  106195. + for_each_process(p) {
  106196. + struct mm_struct *mm;
  106197. + struct signal_struct *sig;
  106198. + gcuDATABASE_INFO info;
  106199. + int oom_adj;
  106200. +
  106201. + task_lock(p);
  106202. + mm = p->mm;
  106203. + sig = p->signal;
  106204. + if (!mm || !sig) {
  106205. + task_unlock(p);
  106206. + continue;
  106207. + }
  106208. + oom_adj = sig->oom_adj;
  106209. + if (oom_adj < min_adj) {
  106210. + task_unlock(p);
  106211. + continue;
  106212. + }
  106213. +
  106214. + tasksize = 0;
  106215. + if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK){
  106216. + tasksize += info.counters.bytes / PAGE_SIZE;
  106217. + }
  106218. + if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_CONTIGUOUS, &info) == gcvSTATUS_OK){
  106219. + tasksize += info.counters.bytes / PAGE_SIZE;
  106220. + }
  106221. +
  106222. + task_unlock(p);
  106223. +
  106224. + if (tasksize <= 0)
  106225. + continue;
  106226. +
  106227. + gckOS_Print("<gpu> pid %d (%s), adj %d, size %d \n", p->pid, p->comm, oom_adj, tasksize);
  106228. +
  106229. + if (selected) {
  106230. + if (oom_adj < selected_oom_adj)
  106231. + continue;
  106232. + if (oom_adj == selected_oom_adj &&
  106233. + tasksize <= selected_tasksize)
  106234. + continue;
  106235. + }
  106236. + selected = p;
  106237. + selected_tasksize = tasksize;
  106238. + selected_oom_adj = oom_adj;
  106239. + }
  106240. + if (selected) {
  106241. + gckOS_Print("<gpu> send sigkill to %d (%s), adj %d, size %d\n",
  106242. + selected->pid, selected->comm,
  106243. + selected_oom_adj, selected_tasksize);
  106244. + lowmem_deathpending = selected;
  106245. + lowmem_deathpending_timeout = jiffies + HZ;
  106246. + force_sig(SIGKILL, selected);
  106247. + ret = 0;
  106248. + }
  106249. + read_unlock(&tasklist_lock);
  106250. + return ret;
  106251. +}
  106252. +
  106253. +#endif
  106254. +
  106255. +/*******************************************************************************
  106256. +**
  106257. +** _AllocateMemory
  106258. +**
  106259. +** Private function to walk all required memory pools to allocate the requested
  106260. +** amount of video memory.
  106261. +**
  106262. +** INPUT:
  106263. +**
  106264. +** gckKERNEL Kernel
  106265. +** Pointer to an gckKERNEL object.
  106266. +**
  106267. +** gcsHAL_INTERFACE * Interface
  106268. +** Pointer to a gcsHAL_INTERFACE structure that defines the command to
  106269. +** be dispatched.
  106270. +**
  106271. +** OUTPUT:
  106272. +**
  106273. +** gcsHAL_INTERFACE * Interface
  106274. +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
  106275. +** returned.
  106276. +*/
  106277. +static gceSTATUS
  106278. +_AllocateMemory(
  106279. + IN gckKERNEL Kernel,
  106280. + IN OUT gcePOOL * Pool,
  106281. + IN gctSIZE_T Bytes,
  106282. + IN gctSIZE_T Alignment,
  106283. + IN gceSURF_TYPE Type,
  106284. + OUT gcuVIDMEM_NODE_PTR * Node
  106285. + )
  106286. +{
  106287. + gcePOOL pool;
  106288. + gceSTATUS status;
  106289. + gckVIDMEM videoMemory;
  106290. + gctINT loopCount;
  106291. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  106292. + gctBOOL tileStatusInVirtual;
  106293. + gctBOOL forceContiguous = gcvFALSE;
  106294. +
  106295. + gcmkHEADER_ARG("Kernel=0x%x *Pool=%d Bytes=%lu Alignment=%lu Type=%d",
  106296. + Kernel, *Pool, Bytes, Alignment, Type);
  106297. +
  106298. + gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
  106299. + gcmkVERIFY_ARGUMENT(Bytes != 0);
  106300. +
  106301. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  106302. +_AllocateMemory_Retry:
  106303. +#endif
  106304. + /* Get initial pool. */
  106305. + switch (pool = *Pool)
  106306. + {
  106307. + case gcvPOOL_DEFAULT_FORCE_CONTIGUOUS:
  106308. + forceContiguous = gcvTRUE;
  106309. + case gcvPOOL_DEFAULT:
  106310. + case gcvPOOL_LOCAL:
  106311. + pool = gcvPOOL_LOCAL_INTERNAL;
  106312. + loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
  106313. + break;
  106314. +
  106315. + case gcvPOOL_UNIFIED:
  106316. + pool = gcvPOOL_SYSTEM;
  106317. + loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
  106318. + break;
  106319. +
  106320. + case gcvPOOL_CONTIGUOUS:
  106321. + loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
  106322. + break;
  106323. +
  106324. + case gcvPOOL_DEFAULT_FORCE_CONTIGUOUS_CACHEABLE:
  106325. + pool = gcvPOOL_CONTIGUOUS;
  106326. + loopCount = 1;
  106327. + forceContiguous = gcvTRUE;
  106328. + break;
  106329. +
  106330. + default:
  106331. + loopCount = 1;
  106332. + break;
  106333. + }
  106334. +
  106335. + while (loopCount-- > 0)
  106336. + {
  106337. + if (pool == gcvPOOL_VIRTUAL)
  106338. + {
  106339. + /* Create a gcuVIDMEM_NODE for virtual memory. */
  106340. + gcmkONERROR(
  106341. + gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, &node));
  106342. +
  106343. + /* Success. */
  106344. + break;
  106345. + }
  106346. +
  106347. + else
  106348. + if (pool == gcvPOOL_CONTIGUOUS)
  106349. + {
  106350. +#if gcdCONTIGUOUS_SIZE_LIMIT
  106351. + if (Bytes > gcdCONTIGUOUS_SIZE_LIMIT && forceContiguous == gcvFALSE)
  106352. + {
  106353. + status = gcvSTATUS_OUT_OF_MEMORY;
  106354. + }
  106355. + else
  106356. +#endif
  106357. + {
  106358. + /* Create a gcuVIDMEM_NODE from contiguous memory. */
  106359. + status = gckVIDMEM_ConstructVirtual(Kernel, gcvTRUE, Bytes, &node);
  106360. + }
  106361. +
  106362. + if (gcmIS_SUCCESS(status) || forceContiguous == gcvTRUE)
  106363. + {
  106364. + /* Memory allocated. */
  106365. + if(node && forceContiguous == gcvTRUE)
  106366. + {
  106367. + gctUINT32 physAddr=0;
  106368. + gctUINT32 baseAddress = 0;
  106369. +
  106370. + gcmkONERROR(
  106371. + gckOS_LockPages(Kernel->os,
  106372. + node->Virtual.physical,
  106373. + node->Virtual.bytes,
  106374. + gcvFALSE,
  106375. + &node->Virtual.logical,
  106376. + &node->Virtual.pageCount));
  106377. +
  106378. + /* Convert logical address into a physical address. */
  106379. + gcmkONERROR(
  106380. + gckOS_GetPhysicalAddress(Kernel->os,
  106381. + node->Virtual.logical,
  106382. + &physAddr));
  106383. +
  106384. + gcmkONERROR(
  106385. + gckOS_UnlockPages(Kernel->os,
  106386. + node->Virtual.physical,
  106387. + node->Virtual.bytes,
  106388. + node->Virtual.logical));
  106389. +
  106390. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  106391. +
  106392. + gcmkASSERT(physAddr >= baseAddress);
  106393. +
  106394. + /* Subtract baseAddress to get a GPU address used for programming. */
  106395. + physAddr -= baseAddress;
  106396. +
  106397. + if((physAddr & 0x80000000) || ((physAddr + Bytes) & 0x80000000))
  106398. + {
  106399. + gckOS_Print("gpu virtual memory 0x%x cannot be allocated in force contiguous request!\n", physAddr);
  106400. +
  106401. + gcmkONERROR(gckVIDMEM_Free(node));
  106402. +
  106403. + node = gcvNULL;
  106404. + }
  106405. + }
  106406. +
  106407. + break;
  106408. + }
  106409. + }
  106410. +
  106411. + else
  106412. + {
  106413. + /* Get pointer to gckVIDMEM object for pool. */
  106414. +#if gcdUSE_VIDMEM_PER_PID
  106415. + gctUINT32 pid;
  106416. + gckOS_GetProcessID(&pid);
  106417. +
  106418. + status = gckKERNEL_GetVideoMemoryPoolPid(Kernel, pool, pid, &videoMemory);
  106419. + if (status == gcvSTATUS_NOT_FOUND)
  106420. + {
  106421. + /* Create VidMem pool for this process. */
  106422. + status = gckKERNEL_CreateVideoMemoryPoolPid(Kernel, pool, pid, &videoMemory);
  106423. + }
  106424. +#else
  106425. + status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory);
  106426. +#endif
  106427. +
  106428. + if (gcmIS_SUCCESS(status))
  106429. + {
  106430. + /* Allocate memory. */
  106431. + status = gckVIDMEM_AllocateLinear(videoMemory,
  106432. + Bytes,
  106433. + Alignment,
  106434. + Type,
  106435. + &node);
  106436. +
  106437. + if (gcmIS_SUCCESS(status))
  106438. + {
  106439. + /* Memory allocated. */
  106440. + node->VidMem.pool = pool;
  106441. + break;
  106442. + }
  106443. + }
  106444. + }
  106445. +
  106446. + if (pool == gcvPOOL_LOCAL_INTERNAL)
  106447. + {
  106448. + /* Advance to external memory. */
  106449. + pool = gcvPOOL_LOCAL_EXTERNAL;
  106450. + }
  106451. +
  106452. + else
  106453. + if (pool == gcvPOOL_LOCAL_EXTERNAL)
  106454. + {
  106455. + /* Advance to contiguous system memory. */
  106456. + pool = gcvPOOL_SYSTEM;
  106457. + }
  106458. +
  106459. + else
  106460. + if (pool == gcvPOOL_SYSTEM)
  106461. + {
  106462. + /* Advance to contiguous memory. */
  106463. + pool = gcvPOOL_CONTIGUOUS;
  106464. + }
  106465. +
  106466. + else
  106467. + if (pool == gcvPOOL_CONTIGUOUS)
  106468. + {
  106469. + tileStatusInVirtual =
  106470. + gckHARDWARE_IsFeatureAvailable(Kernel->hardware,
  106471. + gcvFEATURE_MC20);
  106472. +
  106473. + if (Type == gcvSURF_TILE_STATUS && tileStatusInVirtual != gcvTRUE)
  106474. + {
  106475. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  106476. + }
  106477. +
  106478. + /* Advance to virtual memory. */
  106479. + pool = gcvPOOL_VIRTUAL;
  106480. + }
  106481. +
  106482. + else
  106483. + {
  106484. + /* Out of pools. */
  106485. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  106486. + }
  106487. + }
  106488. +
  106489. + if (node == gcvNULL)
  106490. + {
  106491. +
  106492. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  106493. + if(forceContiguous == gcvTRUE)
  106494. + {
  106495. + if(force_contiguous_lowmem_shrink(Kernel) == 0)
  106496. + {
  106497. + /* Sleep 1 millisecond. */
  106498. + gckOS_Delay(gcvNULL, 1);
  106499. + goto _AllocateMemory_Retry;
  106500. + }
  106501. + }
  106502. +#endif
  106503. + /* Nothing allocated. */
  106504. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  106505. + }
  106506. +
  106507. + /* Return node and pool used for allocation. */
  106508. + *Node = node;
  106509. + *Pool = pool;
  106510. +
  106511. + /* Return status. */
  106512. + gcmkFOOTER_ARG("*Pool=%d *Node=0x%x", *Pool, *Node);
  106513. + return gcvSTATUS_OK;
  106514. +
  106515. +OnError:
  106516. + /* Return the status. */
  106517. + gcmkFOOTER();
  106518. + return status;
  106519. +}
  106520. +
  106521. +/*******************************************************************************
  106522. +**
  106523. +** gckKERNEL_Dispatch
  106524. +**
  106525. +** Dispatch a command received from the user HAL layer.
  106526. +**
  106527. +** INPUT:
  106528. +**
  106529. +** gckKERNEL Kernel
  106530. +** Pointer to an gckKERNEL object.
  106531. +**
  106532. +** gctBOOL FromUser
  106533. +** whether the call is from the user space.
  106534. +**
  106535. +** gcsHAL_INTERFACE * Interface
  106536. +** Pointer to a gcsHAL_INTERFACE structure that defines the command to
  106537. +** be dispatched.
  106538. +**
  106539. +** OUTPUT:
  106540. +**
  106541. +** gcsHAL_INTERFACE * Interface
  106542. +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
  106543. +** returned.
  106544. +*/
  106545. +
  106546. +gceSTATUS
  106547. +gckKERNEL_Dispatch(
  106548. + IN gckKERNEL Kernel,
  106549. + IN gctBOOL FromUser,
  106550. + IN OUT gcsHAL_INTERFACE * Interface
  106551. + )
  106552. +{
  106553. + gceSTATUS status = gcvSTATUS_OK;
  106554. + gctSIZE_T bytes;
  106555. + gcuVIDMEM_NODE_PTR node;
  106556. + gctBOOL locked = gcvFALSE;
  106557. + gctPHYS_ADDR physical = gcvNULL;
  106558. + gctPOINTER logical = gcvNULL;
  106559. + gctPOINTER info = gcvNULL;
  106560. + gckCONTEXT context = gcvNULL;
  106561. + gctUINT32 address;
  106562. + gctUINT32 processID;
  106563. + gckKERNEL kernel = Kernel;
  106564. +#if gcdSECURE_USER
  106565. + gcskSECURE_CACHE_PTR cache;
  106566. +#endif
  106567. + gctBOOL asynchronous;
  106568. + gctPOINTER paddr = gcvNULL;
  106569. +#if !USE_NEW_LINUX_SIGNAL
  106570. + gctSIGNAL signal;
  106571. +#endif
  106572. + gceSURF_TYPE type;
  106573. +
  106574. + gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x",
  106575. + Kernel, FromUser, Interface);
  106576. +
  106577. + /* Verify the arguments. */
  106578. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  106579. + gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
  106580. +
  106581. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  106582. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  106583. + "Dispatching command %d (%s)",
  106584. + Interface->command, _DispatchText[Interface->command]);
  106585. +#endif
  106586. +#if QNX_SINGLE_THREADED_DEBUGGING
  106587. + gckOS_AcquireMutex(Kernel->os, Kernel->debugMutex, gcvINFINITE);
  106588. +#endif
  106589. +
  106590. + /* Get the current process ID. */
  106591. + gcmkONERROR(gckOS_GetProcessID(&processID));
  106592. +
  106593. +#if gcdSECURE_USER
  106594. + gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
  106595. +#endif
  106596. +
  106597. + /* Dispatch on command. */
  106598. + switch (Interface->command)
  106599. + {
  106600. + case gcvHAL_GET_BASE_ADDRESS:
  106601. + /* Get base address. */
  106602. + gcmkONERROR(
  106603. + gckOS_GetBaseAddress(Kernel->os,
  106604. + &Interface->u.GetBaseAddress.baseAddress));
  106605. + break;
  106606. +
  106607. + case gcvHAL_QUERY_VIDEO_MEMORY:
  106608. + /* Query video memory size. */
  106609. + gcmkONERROR(gckKERNEL_QueryVideoMemory(Kernel, Interface));
  106610. + break;
  106611. +
  106612. + case gcvHAL_QUERY_CHIP_IDENTITY:
  106613. + /* Query chip identity. */
  106614. + gcmkONERROR(
  106615. + gckHARDWARE_QueryChipIdentity(
  106616. + Kernel->hardware,
  106617. + &Interface->u.QueryChipIdentity));
  106618. + break;
  106619. +
  106620. + case gcvHAL_MAP_MEMORY:
  106621. + physical = gcmINT2PTR(Interface->u.MapMemory.physical);
  106622. +
  106623. + /* Map memory. */
  106624. + gcmkONERROR(
  106625. + gckKERNEL_MapMemory(Kernel,
  106626. + physical,
  106627. + (gctSIZE_T) Interface->u.MapMemory.bytes,
  106628. + &logical));
  106629. +
  106630. + Interface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
  106631. +
  106632. + gcmkVERIFY_OK(
  106633. + gckKERNEL_AddProcessDB(Kernel,
  106634. + processID, gcvDB_MAP_MEMORY,
  106635. + logical,
  106636. + physical,
  106637. + (gctSIZE_T) Interface->u.MapMemory.bytes));
  106638. + break;
  106639. +
  106640. + case gcvHAL_UNMAP_MEMORY:
  106641. + physical = gcmINT2PTR(Interface->u.UnmapMemory.physical);
  106642. +
  106643. + /* Unmap memory. */
  106644. + gcmkONERROR(
  106645. + gckKERNEL_UnmapMemory(Kernel,
  106646. + physical,
  106647. + (gctSIZE_T) Interface->u.UnmapMemory.bytes,
  106648. + gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical)));
  106649. + gcmkVERIFY_OK(
  106650. + gckKERNEL_RemoveProcessDB(Kernel,
  106651. + processID, gcvDB_MAP_MEMORY,
  106652. + gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical)));
  106653. + break;
  106654. +
  106655. + case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
  106656. + bytes = (gctSIZE_T) Interface->u.AllocateNonPagedMemory.bytes;
  106657. +
  106658. + /* Allocate non-paged memory. */
  106659. + gcmkONERROR(
  106660. + gckOS_AllocateNonPagedMemory(
  106661. + Kernel->os,
  106662. + FromUser,
  106663. + &bytes,
  106664. + &physical,
  106665. + &logical));
  106666. +
  106667. + Interface->u.AllocateNonPagedMemory.bytes = bytes;
  106668. + Interface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
  106669. + Interface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
  106670. +
  106671. + gcmkVERIFY_OK(
  106672. + gckKERNEL_AddProcessDB(Kernel,
  106673. + processID, gcvDB_NON_PAGED,
  106674. + logical,
  106675. + gcmINT2PTR(Interface->u.AllocateNonPagedMemory.physical),
  106676. + bytes));
  106677. +
  106678. + break;
  106679. +
  106680. + case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER:
  106681. +#if gcdVIRTUAL_COMMAND_BUFFER
  106682. + bytes = (gctSIZE_T) Interface->u.AllocateVirtualCommandBuffer.bytes;
  106683. +
  106684. + gcmkONERROR(
  106685. + gckKERNEL_AllocateVirtualCommandBuffer(
  106686. + Kernel,
  106687. + FromUser,
  106688. + &bytes,
  106689. + &physical,
  106690. + &logical));
  106691. +
  106692. + Interface->u.AllocateVirtualCommandBuffer.bytes = bytes;
  106693. + Interface->u.AllocateVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(logical);
  106694. + Interface->u.AllocateVirtualCommandBuffer.physical = gcmPTR_TO_NAME(physical);
  106695. +
  106696. + gcmkVERIFY_OK(
  106697. + gckKERNEL_AddProcessDB(Kernel,
  106698. + processID, gcvDB_COMMAND_BUFFER,
  106699. + logical,
  106700. + gcmINT2PTR(Interface->u.AllocateVirtualCommandBuffer.physical),
  106701. + bytes));
  106702. +#else
  106703. + status = gcvSTATUS_NOT_SUPPORTED;
  106704. +#endif
  106705. + break;
  106706. +
  106707. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  106708. + physical = gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical);
  106709. +
  106710. + /* Unmap user logical out of physical memory first. */
  106711. + gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
  106712. + physical,
  106713. + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
  106714. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  106715. +
  106716. + /* Free non-paged memory. */
  106717. + gcmkONERROR(
  106718. + gckOS_FreeNonPagedMemory(Kernel->os,
  106719. + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
  106720. + physical,
  106721. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  106722. +
  106723. + gcmkVERIFY_OK(
  106724. + gckKERNEL_RemoveProcessDB(Kernel,
  106725. + processID, gcvDB_NON_PAGED,
  106726. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  106727. +
  106728. +#if gcdSECURE_USER
  106729. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  106730. + Kernel,
  106731. + cache,
  106732. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical),
  106733. + Interface->u.FreeNonPagedMemory.bytes));
  106734. +#endif
  106735. +
  106736. + gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physical);
  106737. +
  106738. + break;
  106739. +
  106740. + case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
  106741. + bytes = (gctSIZE_T) Interface->u.AllocateContiguousMemory.bytes;
  106742. +
  106743. + /* Allocate contiguous memory. */
  106744. + gcmkONERROR(gckOS_AllocateContiguous(
  106745. + Kernel->os,
  106746. + FromUser,
  106747. + &bytes,
  106748. + &physical,
  106749. + &logical));
  106750. +
  106751. + Interface->u.AllocateContiguousMemory.bytes = bytes;
  106752. + Interface->u.AllocateContiguousMemory.logical = gcmPTR_TO_UINT64(logical);
  106753. + Interface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical);
  106754. +
  106755. + gcmkONERROR(gckHARDWARE_ConvertLogical(
  106756. + Kernel->hardware,
  106757. + gcmUINT64_TO_PTR(Interface->u.AllocateContiguousMemory.logical),
  106758. + &Interface->u.AllocateContiguousMemory.address));
  106759. +
  106760. + gcmkVERIFY_OK(gckKERNEL_AddProcessDB(
  106761. + Kernel,
  106762. + processID, gcvDB_CONTIGUOUS,
  106763. + logical,
  106764. + gcmINT2PTR(Interface->u.AllocateContiguousMemory.physical),
  106765. + bytes));
  106766. +
  106767. + break;
  106768. +
  106769. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  106770. + physical = gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical);
  106771. +
  106772. + /* Unmap user logical out of physical memory first. */
  106773. + gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
  106774. + physical,
  106775. + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
  106776. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
  106777. +
  106778. + /* Free contiguous memory. */
  106779. + gcmkONERROR(
  106780. + gckOS_FreeContiguous(Kernel->os,
  106781. + physical,
  106782. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
  106783. + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes));
  106784. +
  106785. + gcmkVERIFY_OK(
  106786. + gckKERNEL_RemoveProcessDB(Kernel,
  106787. + processID, gcvDB_CONTIGUOUS,
  106788. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  106789. +
  106790. +#if gcdSECURE_USER
  106791. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  106792. + Kernel,
  106793. + cache,
  106794. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
  106795. + Interface->u.FreeContiguousMemory.bytes));
  106796. +#endif
  106797. +
  106798. + gcmRELEASE_NAME(Interface->u.FreeContiguousMemory.physical);
  106799. +
  106800. + break;
  106801. +
  106802. + case gcvHAL_ALLOCATE_VIDEO_MEMORY:
  106803. +
  106804. + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
  106805. +
  106806. + break;
  106807. +
  106808. + case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
  106809. + type = Interface->u.AllocateLinearVideoMemory.type;
  106810. +
  106811. + /* Allocate memory. */
  106812. + gcmkONERROR(
  106813. + _AllocateMemory(Kernel,
  106814. + &Interface->u.AllocateLinearVideoMemory.pool,
  106815. + Interface->u.AllocateLinearVideoMemory.bytes,
  106816. + Interface->u.AllocateLinearVideoMemory.alignment,
  106817. + Interface->u.AllocateLinearVideoMemory.type,
  106818. + &node));
  106819. +
  106820. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  106821. + {
  106822. + bytes = node->VidMem.bytes;
  106823. + node->VidMem.type = type;
  106824. +
  106825. + gcmkONERROR(
  106826. + gckKERNEL_AddProcessDB(Kernel,
  106827. + processID, gcvDB_VIDEO_MEMORY_RESERVED,
  106828. + node,
  106829. + gcvNULL,
  106830. + bytes));
  106831. + }
  106832. + else
  106833. + {
  106834. + bytes = node->Virtual.bytes;
  106835. + node->Virtual.type = type;
  106836. +
  106837. + if(node->Virtual.contiguous)
  106838. + {
  106839. + gcmkONERROR(
  106840. + gckKERNEL_AddProcessDB(Kernel,
  106841. + processID, gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  106842. + node,
  106843. + gcvNULL,
  106844. + bytes));
  106845. + }
  106846. + else
  106847. + {
  106848. + gcmkONERROR(
  106849. + gckKERNEL_AddProcessDB(Kernel,
  106850. + processID, gcvDB_VIDEO_MEMORY_VIRTUAL,
  106851. + node,
  106852. + gcvNULL,
  106853. + bytes));
  106854. + }
  106855. +
  106856. + }
  106857. +
  106858. + gcmkONERROR(
  106859. + gckKERNEL_AddProcessDB(Kernel,
  106860. + processID, gcvDB_VIDEO_MEMORY,
  106861. + node,
  106862. + gcvNULL,
  106863. + bytes));
  106864. +
  106865. + /* Get the node. */
  106866. + Interface->u.AllocateLinearVideoMemory.node = gcmPTR_TO_UINT64(node);
  106867. + break;
  106868. +
  106869. + case gcvHAL_FREE_VIDEO_MEMORY:
  106870. + node = gcmUINT64_TO_PTR(Interface->u.FreeVideoMemory.node);
  106871. +#ifdef __QNXNTO__
  106872. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM
  106873. + && node->VidMem.logical != gcvNULL)
  106874. + {
  106875. + gcmkONERROR(
  106876. + gckKERNEL_UnmapVideoMemory(Kernel,
  106877. + node->VidMem.logical,
  106878. + processID,
  106879. + node->VidMem.bytes));
  106880. + node->VidMem.logical = gcvNULL;
  106881. + }
  106882. +#endif
  106883. + /* Free video memory. */
  106884. + gcmkONERROR(
  106885. + gckVIDMEM_Free(node));
  106886. +
  106887. + gcmkONERROR(
  106888. + gckKERNEL_RemoveProcessDB(Kernel,
  106889. + processID, gcvDB_VIDEO_MEMORY,
  106890. + node));
  106891. +
  106892. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  106893. + {
  106894. + gcmkONERROR(
  106895. + gckKERNEL_RemoveProcessDB(Kernel,
  106896. + processID, gcvDB_VIDEO_MEMORY_RESERVED,
  106897. + node));
  106898. + }
  106899. + else if(node->Virtual.contiguous)
  106900. + {
  106901. + gcmkONERROR(
  106902. + gckKERNEL_RemoveProcessDB(Kernel,
  106903. + processID, gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  106904. + node));
  106905. + }
  106906. + else
  106907. + {
  106908. + gcmkONERROR(
  106909. + gckKERNEL_RemoveProcessDB(Kernel,
  106910. + processID, gcvDB_VIDEO_MEMORY_VIRTUAL,
  106911. + node));
  106912. + }
  106913. +
  106914. + break;
  106915. +
  106916. + case gcvHAL_LOCK_VIDEO_MEMORY:
  106917. + node = gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node);
  106918. +
  106919. + /* Lock video memory. */
  106920. + gcmkONERROR(
  106921. + gckVIDMEM_Lock(Kernel,
  106922. + node,
  106923. + Interface->u.LockVideoMemory.cacheable,
  106924. + &Interface->u.LockVideoMemory.address));
  106925. +
  106926. + locked = gcvTRUE;
  106927. +
  106928. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  106929. + {
  106930. + /* Map video memory address into user space. */
  106931. +#ifdef __QNXNTO__
  106932. + if (node->VidMem.logical == gcvNULL)
  106933. + {
  106934. + gcmkONERROR(
  106935. + gckKERNEL_MapVideoMemory(Kernel,
  106936. + FromUser,
  106937. + Interface->u.LockVideoMemory.address,
  106938. + processID,
  106939. + node->VidMem.bytes,
  106940. + &node->VidMem.logical));
  106941. + }
  106942. + gcmkASSERT(node->VidMem.logical != gcvNULL);
  106943. +
  106944. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical);
  106945. +#else
  106946. + gcmkONERROR(
  106947. + gckKERNEL_MapVideoMemory(Kernel,
  106948. + FromUser,
  106949. + Interface->u.LockVideoMemory.address,
  106950. + &logical));
  106951. +
  106952. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical);
  106953. +#endif
  106954. + }
  106955. + else
  106956. + {
  106957. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical);
  106958. +
  106959. + /* Success. */
  106960. + status = gcvSTATUS_OK;
  106961. + }
  106962. +
  106963. +#if gcdSECURE_USER
  106964. + /* Return logical address as physical address. */
  106965. + Interface->u.LockVideoMemory.address =
  106966. + Interface->u.LockVideoMemory.memory;
  106967. +#endif
  106968. + gcmkONERROR(
  106969. + gckKERNEL_AddProcessDB(Kernel,
  106970. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  106971. + node,
  106972. + gcvNULL,
  106973. + 0));
  106974. +
  106975. + break;
  106976. +
  106977. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  106978. + /* Unlock video memory. */
  106979. + node = gcmUINT64_TO_PTR(Interface->u.UnlockVideoMemory.node);
  106980. +
  106981. +#if gcdSECURE_USER
  106982. + /* Save node information before it disappears. */
  106983. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  106984. + {
  106985. + logical = gcvNULL;
  106986. + bytes = 0;
  106987. + }
  106988. + else
  106989. + {
  106990. + logical = node->Virtual.logical;
  106991. + bytes = node->Virtual.bytes;
  106992. + }
  106993. +#endif
  106994. +
  106995. + /* Unlock video memory. */
  106996. + gcmkONERROR(
  106997. + gckVIDMEM_Unlock(Kernel,
  106998. + node,
  106999. + Interface->u.UnlockVideoMemory.type,
  107000. + &Interface->u.UnlockVideoMemory.asynchroneous));
  107001. +
  107002. +#if gcdSECURE_USER
  107003. + /* Flush the translation cache for virtual surfaces. */
  107004. + if (logical != gcvNULL)
  107005. + {
  107006. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel,
  107007. + cache,
  107008. + logical,
  107009. + bytes));
  107010. + }
  107011. +#endif
  107012. + if (Interface->u.UnlockVideoMemory.asynchroneous == gcvFALSE)
  107013. + {
  107014. + /* There isn't a event to unlock this node, remove record now */
  107015. + gcmkONERROR(
  107016. + gckKERNEL_RemoveProcessDB(Kernel,
  107017. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  107018. + node));
  107019. + }
  107020. + break;
  107021. +
  107022. + case gcvHAL_EVENT_COMMIT:
  107023. + /* Commit an event queue. */
  107024. + gcmkONERROR(
  107025. + gckEVENT_Commit(Kernel->eventObj,
  107026. + gcmUINT64_TO_PTR(Interface->u.Event.queue)));
  107027. + break;
  107028. +
  107029. + case gcvHAL_COMMIT:
  107030. + /* Commit a command and context buffer. */
  107031. + gcmkONERROR(
  107032. + gckCOMMAND_Commit(Kernel->command,
  107033. + Interface->u.Commit.context ?
  107034. + gcmNAME_TO_PTR(Interface->u.Commit.context) : gcvNULL,
  107035. + gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffer),
  107036. + gcmUINT64_TO_PTR(Interface->u.Commit.delta),
  107037. + gcmUINT64_TO_PTR(Interface->u.Commit.queue),
  107038. + processID));
  107039. + break;
  107040. +
  107041. + case gcvHAL_STALL:
  107042. + /* Stall the command queue. */
  107043. + gcmkONERROR(gckCOMMAND_Stall(Kernel->command, gcvFALSE));
  107044. + break;
  107045. +
  107046. + case gcvHAL_MAP_USER_MEMORY:
  107047. + /* Map user memory to DMA. */
  107048. + gcmkONERROR(
  107049. + gckOS_MapUserMemory(Kernel->os,
  107050. + Kernel->core,
  107051. + gcmUINT64_TO_PTR(Interface->u.MapUserMemory.memory),
  107052. + Interface->u.MapUserMemory.physical,
  107053. + (gctSIZE_T) Interface->u.MapUserMemory.size,
  107054. + &info,
  107055. + &Interface->u.MapUserMemory.address));
  107056. +
  107057. + Interface->u.MapUserMemory.info = gcmPTR_TO_NAME(info);
  107058. +
  107059. + gcmkVERIFY_OK(
  107060. + gckKERNEL_AddProcessDB(Kernel,
  107061. + processID, gcvDB_MAP_USER_MEMORY,
  107062. + gcmINT2PTR(Interface->u.MapUserMemory.info),
  107063. + gcmUINT64_TO_PTR(Interface->u.MapUserMemory.memory),
  107064. + (gctSIZE_T) Interface->u.MapUserMemory.size));
  107065. + break;
  107066. +
  107067. + case gcvHAL_UNMAP_USER_MEMORY:
  107068. + address = Interface->u.UnmapUserMemory.address;
  107069. + info = gcmNAME_TO_PTR(Interface->u.UnmapUserMemory.info);
  107070. +
  107071. + /* Unmap user memory. */
  107072. + gcmkONERROR(
  107073. + gckOS_UnmapUserMemory(Kernel->os,
  107074. + Kernel->core,
  107075. + gcmUINT64_TO_PTR(Interface->u.UnmapUserMemory.memory),
  107076. + (gctSIZE_T) Interface->u.UnmapUserMemory.size,
  107077. + info,
  107078. + address));
  107079. +
  107080. +#if gcdSECURE_USER
  107081. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  107082. + Kernel,
  107083. + cache,
  107084. + gcmUINT64_TO_PTR(Interface->u.UnmapUserMemory.memory),
  107085. + Interface->u.UnmapUserMemory.size));
  107086. +#endif
  107087. + gcmkVERIFY_OK(
  107088. + gckKERNEL_RemoveProcessDB(Kernel,
  107089. + processID, gcvDB_MAP_USER_MEMORY,
  107090. + gcmINT2PTR(Interface->u.UnmapUserMemory.info)));
  107091. +
  107092. + gcmRELEASE_NAME(Interface->u.UnmapUserMemory.info);
  107093. +
  107094. + break;
  107095. +
  107096. +#if !USE_NEW_LINUX_SIGNAL
  107097. + case gcvHAL_USER_SIGNAL:
  107098. + /* Dispatch depends on the user signal subcommands. */
  107099. + switch(Interface->u.UserSignal.command)
  107100. + {
  107101. + case gcvUSER_SIGNAL_CREATE:
  107102. + /* Create a signal used in the user space. */
  107103. + gcmkONERROR(
  107104. + gckOS_CreateUserSignal(Kernel->os,
  107105. + Interface->u.UserSignal.manualReset,
  107106. + &Interface->u.UserSignal.id));
  107107. +
  107108. + gcmkVERIFY_OK(
  107109. + gckKERNEL_AddProcessDB(Kernel,
  107110. + processID, gcvDB_SIGNAL,
  107111. + gcmINT2PTR(Interface->u.UserSignal.id),
  107112. + gcvNULL,
  107113. + 0));
  107114. + break;
  107115. +
  107116. + case gcvUSER_SIGNAL_DESTROY:
  107117. + /* Destroy the signal. */
  107118. + gcmkONERROR(
  107119. + gckOS_DestroyUserSignal(Kernel->os,
  107120. + Interface->u.UserSignal.id));
  107121. +
  107122. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  107123. + Kernel,
  107124. + processID, gcvDB_SIGNAL,
  107125. + gcmINT2PTR(Interface->u.UserSignal.id)));
  107126. + break;
  107127. +
  107128. + case gcvUSER_SIGNAL_SIGNAL:
  107129. + /* Signal the signal. */
  107130. + gcmkONERROR(
  107131. + gckOS_SignalUserSignal(Kernel->os,
  107132. + Interface->u.UserSignal.id,
  107133. + Interface->u.UserSignal.state));
  107134. + break;
  107135. +
  107136. + case gcvUSER_SIGNAL_WAIT:
  107137. +#if gcdGPU_TIMEOUT
  107138. + if (Interface->u.UserSignal.wait == gcvINFINITE)
  107139. + {
  107140. + gckHARDWARE hardware;
  107141. + gctUINT32 timer = 0;
  107142. +
  107143. + for(;;)
  107144. + {
  107145. + /* Wait on the signal. */
  107146. + status = gckOS_WaitUserSignal(Kernel->os,
  107147. + Interface->u.UserSignal.id,
  107148. + gcdGPU_ADVANCETIMER);
  107149. +
  107150. + if (status == gcvSTATUS_TIMEOUT)
  107151. + {
  107152. + gcmkONERROR(
  107153. + gckOS_SignalQueryHardware(Kernel->os,
  107154. + (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id,
  107155. + &hardware));
  107156. +
  107157. + if (hardware)
  107158. + {
  107159. + /* This signal is bound to a hardware,
  107160. + ** so the timeout is limited by Kernel->timeOut.
  107161. + */
  107162. + timer += gcdGPU_ADVANCETIMER;
  107163. + }
  107164. +
  107165. + if (timer >= Kernel->timeOut)
  107166. + {
  107167. + gcmkONERROR(
  107168. + gckOS_Broadcast(Kernel->os,
  107169. + hardware,
  107170. + gcvBROADCAST_GPU_STUCK));
  107171. +
  107172. + timer = 0;
  107173. +
  107174. + /* If a few process try to reset GPU, only one
  107175. + ** of them can do the real reset, other processes
  107176. + ** still need to wait for this signal is triggered,
  107177. + ** which menas reset is finished.
  107178. + */
  107179. + continue;
  107180. + }
  107181. + }
  107182. + else
  107183. + {
  107184. + /* Bail out on other error. */
  107185. + gcmkONERROR(status);
  107186. +
  107187. + /* Wait for signal successfully. */
  107188. + break;
  107189. + }
  107190. + }
  107191. + }
  107192. + else
  107193. +#endif
  107194. + {
  107195. + /* Wait on the signal. */
  107196. + status = gckOS_WaitUserSignal(Kernel->os,
  107197. + Interface->u.UserSignal.id,
  107198. + Interface->u.UserSignal.wait);
  107199. + }
  107200. +
  107201. + break;
  107202. +
  107203. + case gcvUSER_SIGNAL_MAP:
  107204. + gcmkONERROR(
  107205. + gckOS_MapSignal(Kernel->os,
  107206. + (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id,
  107207. + (gctHANDLE)(gctUINTPTR_T)processID,
  107208. + &signal));
  107209. +
  107210. + gcmkVERIFY_OK(
  107211. + gckKERNEL_AddProcessDB(Kernel,
  107212. + processID, gcvDB_SIGNAL,
  107213. + gcmINT2PTR(Interface->u.UserSignal.id),
  107214. + gcvNULL,
  107215. + 0));
  107216. + break;
  107217. +
  107218. + case gcvUSER_SIGNAL_UNMAP:
  107219. + /* Destroy the signal. */
  107220. + gcmkONERROR(
  107221. + gckOS_DestroyUserSignal(Kernel->os,
  107222. + Interface->u.UserSignal.id));
  107223. +
  107224. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  107225. + Kernel,
  107226. + processID, gcvDB_SIGNAL,
  107227. + gcmINT2PTR(Interface->u.UserSignal.id)));
  107228. + break;
  107229. +
  107230. + default:
  107231. + /* Invalid user signal command. */
  107232. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107233. + }
  107234. + break;
  107235. +#endif
  107236. +
  107237. + case gcvHAL_SET_POWER_MANAGEMENT_STATE:
  107238. + /* Set the power management state. */
  107239. + gcmkONERROR(
  107240. + gckHARDWARE_SetPowerManagementState(
  107241. + Kernel->hardware,
  107242. + Interface->u.SetPowerManagement.state));
  107243. + break;
  107244. +
  107245. + case gcvHAL_QUERY_POWER_MANAGEMENT_STATE:
  107246. + /* Chip is not idle. */
  107247. + Interface->u.QueryPowerManagement.isIdle = gcvFALSE;
  107248. +
  107249. + /* Query the power management state. */
  107250. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
  107251. + Kernel->hardware,
  107252. + &Interface->u.QueryPowerManagement.state));
  107253. +
  107254. + /* Query the idle state. */
  107255. + gcmkONERROR(
  107256. + gckHARDWARE_QueryIdle(Kernel->hardware,
  107257. + &Interface->u.QueryPowerManagement.isIdle));
  107258. + break;
  107259. +
  107260. + case gcvHAL_READ_REGISTER:
  107261. +#if gcdREGISTER_ACCESS_FROM_USER
  107262. + {
  107263. + gceCHIPPOWERSTATE power;
  107264. +
  107265. + gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE);
  107266. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
  107267. + &power));
  107268. + if (power == gcvPOWER_ON)
  107269. + {
  107270. + /* Read a register. */
  107271. + gcmkONERROR(gckOS_ReadRegisterEx(
  107272. + Kernel->os,
  107273. + Kernel->core,
  107274. + Interface->u.ReadRegisterData.address,
  107275. + &Interface->u.ReadRegisterData.data));
  107276. + }
  107277. + else
  107278. + {
  107279. + /* Chip is in power-state. */
  107280. + Interface->u.ReadRegisterData.data = 0;
  107281. + status = gcvSTATUS_CHIP_NOT_READY;
  107282. + }
  107283. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
  107284. + }
  107285. +#else
  107286. + /* No access from user land to read registers. */
  107287. + Interface->u.ReadRegisterData.data = 0;
  107288. + status = gcvSTATUS_NOT_SUPPORTED;
  107289. +#endif
  107290. + break;
  107291. +
  107292. + case gcvHAL_WRITE_REGISTER:
  107293. +#if gcdREGISTER_ACCESS_FROM_USER
  107294. + {
  107295. + gceCHIPPOWERSTATE power;
  107296. +
  107297. + gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE);
  107298. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
  107299. + &power));
  107300. + if (power == gcvPOWER_ON)
  107301. + {
  107302. + /* Write a register. */
  107303. + gcmkONERROR(
  107304. + gckOS_WriteRegisterEx(Kernel->os,
  107305. + Kernel->core,
  107306. + Interface->u.WriteRegisterData.address,
  107307. + Interface->u.WriteRegisterData.data));
  107308. + }
  107309. + else
  107310. + {
  107311. + /* Chip is in power-state. */
  107312. + Interface->u.WriteRegisterData.data = 0;
  107313. + status = gcvSTATUS_CHIP_NOT_READY;
  107314. + }
  107315. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
  107316. + }
  107317. +#else
  107318. + /* No access from user land to write registers. */
  107319. + status = gcvSTATUS_NOT_SUPPORTED;
  107320. +#endif
  107321. + break;
  107322. +
  107323. + case gcvHAL_READ_ALL_PROFILE_REGISTERS:
  107324. +#if VIVANTE_PROFILER && VIVANTE_PROFILER_CONTEXT
  107325. + /* Read profile data according to the context. */
  107326. + gcmkONERROR(
  107327. + gckHARDWARE_QueryContextProfile(
  107328. + Kernel->hardware,
  107329. + Kernel->profileCleanRegister,
  107330. + gcmNAME_TO_PTR(Interface->u.RegisterProfileData.context),
  107331. + &Interface->u.RegisterProfileData.counters));
  107332. +#elif VIVANTE_PROFILER
  107333. + /* Read all 3D profile registers. */
  107334. + gcmkONERROR(
  107335. + gckHARDWARE_QueryProfileRegisters(
  107336. + Kernel->hardware,
  107337. + Kernel->profileCleanRegister,
  107338. + &Interface->u.RegisterProfileData.counters));
  107339. +#else
  107340. + status = gcvSTATUS_OK;
  107341. +#endif
  107342. + break;
  107343. +
  107344. + case gcvHAL_PROFILE_REGISTERS_2D:
  107345. +#if VIVANTE_PROFILER
  107346. + /* Read all 2D profile registers. */
  107347. + gcmkONERROR(
  107348. + gckHARDWARE_ProfileEngine2D(
  107349. + Kernel->hardware,
  107350. + gcmUINT64_TO_PTR(Interface->u.RegisterProfileData2D.hwProfile2D)));
  107351. +#else
  107352. + status = gcvSTATUS_OK;
  107353. +#endif
  107354. + break;
  107355. +
  107356. + case gcvHAL_GET_PROFILE_SETTING:
  107357. +#if VIVANTE_PROFILER
  107358. + /* Get profile setting */
  107359. + Interface->u.GetProfileSetting.enable = Kernel->profileEnable;
  107360. +#endif
  107361. +
  107362. + status = gcvSTATUS_OK;
  107363. + break;
  107364. + case gcvHAL_SET_PROFILE_SETTING:
  107365. +#if VIVANTE_PROFILER
  107366. + /* Set profile setting */
  107367. + if(Kernel->hardware->gpuProfiler)
  107368. + Kernel->profileEnable = Interface->u.SetProfileSetting.enable;
  107369. + else
  107370. + {
  107371. + status = gcvSTATUS_NOT_SUPPORTED;
  107372. + break;
  107373. + }
  107374. +#endif
  107375. +
  107376. + status = gcvSTATUS_OK;
  107377. + break;
  107378. +
  107379. +#if VIVANTE_PROFILER_PERDRAW
  107380. + case gcvHAL_READ_PROFILER_REGISTER_SETTING:
  107381. + #if VIVANTE_PROFILER
  107382. + Kernel->profileCleanRegister = Interface->u.SetProfilerRegisterClear.bclear;
  107383. + #endif
  107384. + status = gcvSTATUS_OK;
  107385. + break;
  107386. +#endif
  107387. +
  107388. + case gcvHAL_QUERY_KERNEL_SETTINGS:
  107389. + /* Get kernel settings. */
  107390. + gcmkONERROR(
  107391. + gckKERNEL_QuerySettings(Kernel,
  107392. + &Interface->u.QueryKernelSettings.settings));
  107393. + break;
  107394. +
  107395. + case gcvHAL_RESET:
  107396. + /* Reset the hardware. */
  107397. + gckKERNEL_Recovery(Kernel);
  107398. + break;
  107399. +
  107400. + case gcvHAL_DEBUG:
  107401. + /* Set debug level and zones. */
  107402. + if (Interface->u.Debug.set)
  107403. + {
  107404. + gckOS_SetDebugLevel(Interface->u.Debug.level);
  107405. + gckOS_SetDebugZones(Interface->u.Debug.zones,
  107406. + Interface->u.Debug.enable);
  107407. + }
  107408. +
  107409. + if (Interface->u.Debug.message[0] != '\0')
  107410. + {
  107411. + /* Print a message to the debugger. */
  107412. + if (Interface->u.Debug.type == gcvMESSAGE_TEXT)
  107413. + {
  107414. + gckOS_CopyPrint(Interface->u.Debug.message);
  107415. + }
  107416. + else
  107417. + {
  107418. + gckOS_DumpBuffer(Kernel->os,
  107419. + Interface->u.Debug.message,
  107420. + Interface->u.Debug.messageSize,
  107421. + gceDUMP_BUFFER_FROM_USER,
  107422. + gcvTRUE);
  107423. + }
  107424. + }
  107425. + status = gcvSTATUS_OK;
  107426. + break;
  107427. +
  107428. + case gcvHAL_DUMP_GPU_STATE:
  107429. + /* Dump GPU state */
  107430. + {
  107431. + gceCHIPPOWERSTATE power;
  107432. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
  107433. + &power));
  107434. + if (power == gcvPOWER_ON)
  107435. + {
  107436. + Interface->u.ReadRegisterData.data = 1;
  107437. + gcmkVERIFY_OK(
  107438. + gckHARDWARE_DumpGPUState(Kernel->hardware));
  107439. +#if gcdVIRTUAL_COMMAND_BUFFER
  107440. + gcmkVERIFY_OK(
  107441. + gckCOMMAND_DumpExecutingBuffer(Kernel->command));
  107442. +#endif
  107443. + }
  107444. + else
  107445. + {
  107446. + Interface->u.ReadRegisterData.data = 0;
  107447. + status = gcvSTATUS_CHIP_NOT_READY;
  107448. + }
  107449. + }
  107450. + break;
  107451. +
  107452. + case gcvHAL_DUMP_EVENT:
  107453. + /* Dump GPU event */
  107454. + gcmkVERIFY_OK(gckEVENT_Dump(Kernel->eventObj));
  107455. +
  107456. + /* Dump Process DB. */
  107457. + gcmkVERIFY_OK(gckKERNEL_DumpProcessDB(Kernel));
  107458. + break;
  107459. +
  107460. + case gcvHAL_CACHE:
  107461. + node = gcmUINT64_TO_PTR(Interface->u.Cache.node);
  107462. + if (node == gcvNULL)
  107463. + {
  107464. + /* FIXME Surface wrap some memory which is not allocated by us,
  107465. + ** So we don't have physical address to handle outer cache, ignore it*/
  107466. + status = gcvSTATUS_OK;
  107467. + break;
  107468. + }
  107469. + else if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  107470. + {
  107471. + /* Video memory has no physical handles. */
  107472. + physical = gcvNULL;
  107473. + }
  107474. + else
  107475. + {
  107476. + /* Grab physical handle. */
  107477. + physical = node->Virtual.physical;
  107478. + }
  107479. +
  107480. + logical = gcmUINT64_TO_PTR(Interface->u.Cache.logical);
  107481. + bytes = (gctSIZE_T) Interface->u.Cache.bytes;
  107482. + switch(Interface->u.Cache.operation)
  107483. + {
  107484. + case gcvCACHE_FLUSH:
  107485. + /* Clean and invalidate the cache. */
  107486. + status = gckOS_CacheFlush(Kernel->os,
  107487. + processID,
  107488. + physical,
  107489. + paddr,
  107490. + logical,
  107491. + bytes);
  107492. + break;
  107493. + case gcvCACHE_CLEAN:
  107494. + /* Clean the cache. */
  107495. + status = gckOS_CacheClean(Kernel->os,
  107496. + processID,
  107497. + physical,
  107498. + paddr,
  107499. + logical,
  107500. + bytes);
  107501. + break;
  107502. + case gcvCACHE_INVALIDATE:
  107503. + /* Invalidate the cache. */
  107504. + status = gckOS_CacheInvalidate(Kernel->os,
  107505. + processID,
  107506. + physical,
  107507. + paddr,
  107508. + logical,
  107509. + bytes);
  107510. + break;
  107511. +
  107512. + case gcvCACHE_MEMORY_BARRIER:
  107513. + status = gckOS_MemoryBarrier(Kernel->os,
  107514. + logical);
  107515. + break;
  107516. + default:
  107517. + status = gcvSTATUS_INVALID_ARGUMENT;
  107518. + break;
  107519. + }
  107520. + break;
  107521. +
  107522. + case gcvHAL_TIMESTAMP:
  107523. + /* Check for invalid timer. */
  107524. + if ((Interface->u.TimeStamp.timer >= gcmCOUNTOF(Kernel->timers))
  107525. + || (Interface->u.TimeStamp.request != 2))
  107526. + {
  107527. + Interface->u.TimeStamp.timeDelta = 0;
  107528. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107529. + }
  107530. +
  107531. + /* Return timer results and reset timer. */
  107532. + {
  107533. + gcsTIMER_PTR timer = &(Kernel->timers[Interface->u.TimeStamp.timer]);
  107534. + gctUINT64 timeDelta = 0;
  107535. +
  107536. + if (timer->stopTime < timer->startTime )
  107537. + {
  107538. + Interface->u.TimeStamp.timeDelta = 0;
  107539. + gcmkONERROR(gcvSTATUS_TIMER_OVERFLOW);
  107540. + }
  107541. +
  107542. + timeDelta = timer->stopTime - timer->startTime;
  107543. +
  107544. + /* Check truncation overflow. */
  107545. + Interface->u.TimeStamp.timeDelta = (gctINT32) timeDelta;
  107546. + /*bit0~bit30 is available*/
  107547. + if (timeDelta>>31)
  107548. + {
  107549. + Interface->u.TimeStamp.timeDelta = 0;
  107550. + gcmkONERROR(gcvSTATUS_TIMER_OVERFLOW);
  107551. + }
  107552. +
  107553. + status = gcvSTATUS_OK;
  107554. + }
  107555. + break;
  107556. +
  107557. + case gcvHAL_DATABASE:
  107558. + /* Query video memory. */
  107559. + gcmkONERROR(
  107560. + gckKERNEL_QueryProcessDB(Kernel,
  107561. + Interface->u.Database.processID,
  107562. + !Interface->u.Database.validProcessID,
  107563. + gcvDB_VIDEO_MEMORY,
  107564. + &Interface->u.Database.vidMem));
  107565. +
  107566. + /* Query non-paged memory. */
  107567. + gcmkONERROR(
  107568. + gckKERNEL_QueryProcessDB(Kernel,
  107569. + Interface->u.Database.processID,
  107570. + !Interface->u.Database.validProcessID,
  107571. + gcvDB_NON_PAGED,
  107572. + &Interface->u.Database.nonPaged));
  107573. +
  107574. + /* Query contiguous memory. */
  107575. + gcmkONERROR(
  107576. + gckKERNEL_QueryProcessDB(Kernel,
  107577. + Interface->u.Database.processID,
  107578. + !Interface->u.Database.validProcessID,
  107579. + gcvDB_CONTIGUOUS,
  107580. + &Interface->u.Database.contiguous));
  107581. +
  107582. + /* Query GPU idle time. */
  107583. + gcmkONERROR(
  107584. + gckKERNEL_QueryProcessDB(Kernel,
  107585. + Interface->u.Database.processID,
  107586. + !Interface->u.Database.validProcessID,
  107587. + gcvDB_IDLE,
  107588. + &Interface->u.Database.gpuIdle));
  107589. + break;
  107590. +
  107591. + case gcvHAL_VIDMEM_DATABASE:
  107592. + /* Query reserved video memory. */
  107593. + gcmkONERROR(
  107594. + gckKERNEL_QueryProcessDB(Kernel,
  107595. + Interface->u.VidMemDatabase.processID,
  107596. + !Interface->u.VidMemDatabase.validProcessID,
  107597. + gcvDB_VIDEO_MEMORY_RESERVED,
  107598. + &Interface->u.VidMemDatabase.vidMemResv));
  107599. +
  107600. + /* Query contiguous video memory. */
  107601. + gcmkONERROR(
  107602. + gckKERNEL_QueryProcessDB(Kernel,
  107603. + Interface->u.VidMemDatabase.processID,
  107604. + !Interface->u.VidMemDatabase.validProcessID,
  107605. + gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  107606. + &Interface->u.VidMemDatabase.vidMemCont));
  107607. +
  107608. + /* Query virtual video memory. */
  107609. + gcmkONERROR(
  107610. + gckKERNEL_QueryProcessDB(Kernel,
  107611. + Interface->u.VidMemDatabase.processID,
  107612. + !Interface->u.VidMemDatabase.validProcessID,
  107613. + gcvDB_VIDEO_MEMORY_VIRTUAL,
  107614. + &Interface->u.VidMemDatabase.vidMemVirt));
  107615. +
  107616. + break;
  107617. +
  107618. + case gcvHAL_VERSION:
  107619. + Interface->u.Version.major = gcvVERSION_MAJOR;
  107620. + Interface->u.Version.minor = gcvVERSION_MINOR;
  107621. + Interface->u.Version.patch = gcvVERSION_PATCH;
  107622. + Interface->u.Version.build = gcvVERSION_BUILD;
  107623. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  107624. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  107625. + "KERNEL version %d.%d.%d build %u %s %s",
  107626. + gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH,
  107627. + gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME);
  107628. +#endif
  107629. + break;
  107630. +
  107631. + case gcvHAL_CHIP_INFO:
  107632. + /* Only if not support multi-core */
  107633. + Interface->u.ChipInfo.count = 1;
  107634. + Interface->u.ChipInfo.types[0] = Kernel->hardware->type;
  107635. + break;
  107636. +
  107637. + case gcvHAL_ATTACH:
  107638. + /* Attach user process. */
  107639. + gcmkONERROR(
  107640. + gckCOMMAND_Attach(Kernel->command,
  107641. + &context,
  107642. + &bytes,
  107643. + processID));
  107644. +
  107645. + Interface->u.Attach.stateCount = bytes;
  107646. + Interface->u.Attach.context = gcmPTR_TO_NAME(context);
  107647. +
  107648. + gcmkVERIFY_OK(
  107649. + gckKERNEL_AddProcessDB(Kernel,
  107650. + processID, gcvDB_CONTEXT,
  107651. + gcmINT2PTR(Interface->u.Attach.context),
  107652. + gcvNULL,
  107653. + 0));
  107654. + break;
  107655. +
  107656. + case gcvHAL_DETACH:
  107657. + /* Detach user process. */
  107658. + gcmkONERROR(
  107659. + gckCOMMAND_Detach(Kernel->command,
  107660. + gcmNAME_TO_PTR(Interface->u.Detach.context)));
  107661. +
  107662. + gcmkVERIFY_OK(
  107663. + gckKERNEL_RemoveProcessDB(Kernel,
  107664. + processID, gcvDB_CONTEXT,
  107665. + gcmINT2PTR(Interface->u.Detach.context)));
  107666. +
  107667. + gcmRELEASE_NAME(Interface->u.Detach.context);
  107668. + break;
  107669. +
  107670. + case gcvHAL_COMPOSE:
  107671. + Interface->u.Compose.physical = gcmPTR_TO_UINT64(gcmNAME_TO_PTR(Interface->u.Compose.physical));
  107672. + /* Start composition. */
  107673. + gcmkONERROR(
  107674. + gckEVENT_Compose(Kernel->eventObj,
  107675. + &Interface->u.Compose));
  107676. + break;
  107677. +
  107678. + case gcvHAL_SET_TIMEOUT:
  107679. + /* set timeOut value from user */
  107680. + gckKERNEL_SetTimeOut(Kernel, Interface->u.SetTimeOut.timeOut);
  107681. + break;
  107682. +
  107683. +#if gcdFRAME_DB
  107684. + case gcvHAL_GET_FRAME_INFO:
  107685. + gcmkONERROR(gckHARDWARE_GetFrameInfo(
  107686. + Kernel->hardware,
  107687. + gcmUINT64_TO_PTR(Interface->u.GetFrameInfo.frameInfo)));
  107688. + break;
  107689. +#endif
  107690. +
  107691. + case gcvHAL_GET_SHARED_INFO:
  107692. + if (Interface->u.GetSharedInfo.data == gcvNULL)
  107693. + {
  107694. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107695. + }
  107696. + else
  107697. + {
  107698. + gctUINT32 pid = Interface->u.GetSharedInfo.pid;
  107699. + gctUINT32 dataId = Interface->u.GetSharedInfo.dataId;
  107700. + gctSIZE_T bytes = Interface->u.GetSharedInfo.bytes;
  107701. + gctPOINTER data = Interface->u.GetSharedInfo.data;
  107702. + gcsDATABASE_RECORD record;
  107703. +
  107704. + /* Find record. */
  107705. + gcmkONERROR(
  107706. + gckKERNEL_FindProcessDB(Kernel,
  107707. + pid,
  107708. + 0,
  107709. + gcvDB_SHARED_INFO,
  107710. + gcmINT2PTR(dataId),
  107711. + &record));
  107712. +
  107713. + /* Check memory size. */
  107714. + if (bytes < record.bytes)
  107715. + {
  107716. + /* Insufficient memory to hold shared data. */
  107717. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107718. + }
  107719. +
  107720. + /* Copy to user. */
  107721. + status = gckOS_CopyToUserData(Kernel->os,
  107722. + record.physical,
  107723. + data,
  107724. + record.bytes);
  107725. +
  107726. + /*
  107727. + * Remove from process db.
  107728. + * Every time when shared info is taken, the record is erased in
  107729. + * kernel side.
  107730. + */
  107731. + gcmkVERIFY_OK(
  107732. + gckKERNEL_RemoveProcessDB(Kernel,
  107733. + pid,
  107734. + gcvDB_SHARED_INFO,
  107735. + gcmINT2PTR(dataId)));
  107736. + /* Free existed data. */
  107737. + gcmkVERIFY_OK(
  107738. + gckOS_FreeMemory(Kernel->os, record.physical));
  107739. + }
  107740. + break;
  107741. +
  107742. + case gcvHAL_SET_SHARED_INFO:
  107743. + {
  107744. + gctUINT32 dataId = Interface->u.SetSharedInfo.dataId;
  107745. + gctPOINTER data = Interface->u.SetSharedInfo.data;
  107746. + gctUINT32 bytes = Interface->u.SetSharedInfo.bytes;
  107747. + gctPOINTER memory = gcvNULL;
  107748. + gcsDATABASE_RECORD record;
  107749. +
  107750. + if (gcmIS_SUCCESS(gckKERNEL_FindProcessDB(Kernel,
  107751. + processID,
  107752. + 0,
  107753. + gcvDB_SHARED_INFO,
  107754. + gcmINT2PTR(dataId),
  107755. + &record)))
  107756. + {
  107757. + /* Find a record with the same id. */
  107758. + if (bytes != record.bytes)
  107759. + {
  107760. + /* Remove from process db. */
  107761. + gcmkVERIFY_OK(
  107762. + gckKERNEL_RemoveProcessDB(Kernel,
  107763. + processID,
  107764. + gcvDB_SHARED_INFO,
  107765. + gcmINT2PTR(dataId)));
  107766. +
  107767. + /* Free existed data. */
  107768. + gcmkVERIFY_OK(
  107769. + gckOS_FreeMemory(Kernel->os, record.physical));
  107770. + }
  107771. + else
  107772. + {
  107773. + /* Re-use allocated memory. */
  107774. + memory = record.physical;
  107775. + }
  107776. + }
  107777. +
  107778. + if ((data == gcvNULL) || (bytes == 0))
  107779. + {
  107780. + /* Nothing to record. */
  107781. + break;
  107782. + }
  107783. +
  107784. + if (bytes > 1024)
  107785. + {
  107786. + /* Limite data size. */
  107787. + gcmkONERROR(gcvSTATUS_TOO_COMPLEX);
  107788. + }
  107789. +
  107790. + if (memory == gcvNULL)
  107791. + {
  107792. + /* Allocate memory for holding shared data. */
  107793. + gcmkONERROR(
  107794. + gckOS_AllocateMemory(Kernel->os, bytes, &memory));
  107795. +
  107796. + /* Add to process db. */
  107797. + status = gckKERNEL_AddProcessDB(Kernel,
  107798. + processID,
  107799. + gcvDB_SHARED_INFO,
  107800. + gcmINT2PTR(dataId),
  107801. + memory,
  107802. + bytes);
  107803. +
  107804. + if (gcmIS_ERROR(status))
  107805. + {
  107806. + /* Failed to add process db. Free allocated memory. */
  107807. + gcmkVERIFY_OK(gckOS_FreeMemory(Kernel->os, memory));
  107808. + break;
  107809. + }
  107810. + }
  107811. +
  107812. + /* Copy shared data to kernel memory. */
  107813. + gcmkONERROR(
  107814. + gckOS_CopyFromUserData(Kernel->os,
  107815. + memory,
  107816. + data,
  107817. + bytes));
  107818. + }
  107819. + break;
  107820. +
  107821. + case gcvHAL_SET_FSCALE_VALUE:
  107822. +#if gcdENABLE_FSCALE_VAL_ADJUST
  107823. + status = gckHARDWARE_SetFscaleValue(Kernel->hardware,
  107824. + Interface->u.SetFscaleValue.value);
  107825. +#else
  107826. + status = gcvSTATUS_NOT_SUPPORTED;
  107827. +#endif
  107828. + break;
  107829. + case gcvHAL_GET_FSCALE_VALUE:
  107830. +#if gcdENABLE_FSCALE_VAL_ADJUST
  107831. + status = gckHARDWARE_GetFscaleValue(Kernel->hardware,
  107832. + &Interface->u.GetFscaleValue.value,
  107833. + &Interface->u.GetFscaleValue.minValue,
  107834. + &Interface->u.GetFscaleValue.maxValue);
  107835. +#else
  107836. + status = gcvSTATUS_NOT_SUPPORTED;
  107837. +#endif
  107838. + break;
  107839. +
  107840. + case gcvHAL_QUERY_RESET_TIME_STAMP:
  107841. +#if gcdENABLE_RECOVERY
  107842. + Interface->u.QueryResetTimeStamp.timeStamp = Kernel->resetTimeStamp;
  107843. +#else
  107844. + Interface->u.QueryResetTimeStamp.timeStamp = 0;
  107845. +#endif
  107846. + break;
  107847. +
  107848. +#if gcdANDROID_NATIVE_FENCE_SYNC
  107849. + case gcvHAL_SYNC_POINT:
  107850. + {
  107851. + gctSYNC_POINT syncPoint;
  107852. +
  107853. + switch (Interface->u.SyncPoint.command)
  107854. + {
  107855. + case gcvSYNC_POINT_CREATE:
  107856. + gcmkONERROR(gckOS_CreateSyncPoint(Kernel->os, &syncPoint));
  107857. +
  107858. + Interface->u.SyncPoint.syncPoint = gcmPTR_TO_UINT64(syncPoint);
  107859. +
  107860. + gcmkVERIFY_OK(
  107861. + gckKERNEL_AddProcessDB(Kernel,
  107862. + processID, gcvDB_SYNC_POINT,
  107863. + syncPoint,
  107864. + gcvNULL,
  107865. + 0));
  107866. + break;
  107867. +
  107868. + case gcvSYNC_POINT_DESTROY:
  107869. + syncPoint = gcmUINT64_TO_PTR(Interface->u.SyncPoint.syncPoint);
  107870. +
  107871. + gcmkONERROR(gckOS_DestroySyncPoint(Kernel->os, syncPoint));
  107872. +
  107873. + gcmkVERIFY_OK(
  107874. + gckKERNEL_RemoveProcessDB(Kernel,
  107875. + processID, gcvDB_SYNC_POINT,
  107876. + syncPoint));
  107877. + break;
  107878. +
  107879. + default:
  107880. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107881. + break;
  107882. + }
  107883. + }
  107884. + break;
  107885. +
  107886. + case gcvHAL_CREATE_NATIVE_FENCE:
  107887. + {
  107888. + gctINT fenceFD;
  107889. + gctSYNC_POINT syncPoint =
  107890. + gcmUINT64_TO_PTR(Interface->u.CreateNativeFence.syncPoint);
  107891. +
  107892. + gcmkONERROR(
  107893. + gckOS_CreateNativeFence(Kernel->os,
  107894. + Kernel->timeline,
  107895. + syncPoint,
  107896. + &fenceFD));
  107897. +
  107898. + Interface->u.CreateNativeFence.fenceFD = fenceFD;
  107899. + }
  107900. + break;
  107901. +#endif
  107902. +
  107903. + default:
  107904. + /* Invalid command. */
  107905. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107906. + }
  107907. +
  107908. +OnError:
  107909. + /* Save status. */
  107910. + Interface->status = status;
  107911. +
  107912. + if (gcmIS_ERROR(status))
  107913. + {
  107914. + if (locked)
  107915. + {
  107916. + /* Roll back the lock. */
  107917. + gcmkVERIFY_OK(
  107918. + gckVIDMEM_Unlock(Kernel,
  107919. + gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node),
  107920. + gcvSURF_TYPE_UNKNOWN,
  107921. + &asynchronous));
  107922. +
  107923. + if (gcvTRUE == asynchronous)
  107924. + {
  107925. + /* Bottom Half */
  107926. + gcmkVERIFY_OK(
  107927. + gckVIDMEM_Unlock(Kernel,
  107928. + gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node),
  107929. + gcvSURF_TYPE_UNKNOWN,
  107930. + gcvNULL));
  107931. + }
  107932. + }
  107933. + }
  107934. +
  107935. +#if QNX_SINGLE_THREADED_DEBUGGING
  107936. + gckOS_ReleaseMutex(Kernel->os, Kernel->debugMutex);
  107937. +#endif
  107938. +
  107939. + /* Return the status. */
  107940. + gcmkFOOTER();
  107941. + return status;
  107942. +}
  107943. +
  107944. +/*******************************************************************************
  107945. +** gckKERNEL_AttachProcess
  107946. +**
  107947. +** Attach or detach a process.
  107948. +**
  107949. +** INPUT:
  107950. +**
  107951. +** gckKERNEL Kernel
  107952. +** Pointer to an gckKERNEL object.
  107953. +**
  107954. +** gctBOOL Attach
  107955. +** gcvTRUE if a new process gets attached or gcFALSE when a process
  107956. +** gets detatched.
  107957. +**
  107958. +** OUTPUT:
  107959. +**
  107960. +** Nothing.
  107961. +*/
  107962. +gceSTATUS
  107963. +gckKERNEL_AttachProcess(
  107964. + IN gckKERNEL Kernel,
  107965. + IN gctBOOL Attach
  107966. + )
  107967. +{
  107968. + gceSTATUS status;
  107969. + gctUINT32 processID;
  107970. +
  107971. + gcmkHEADER_ARG("Kernel=0x%x Attach=%d", Kernel, Attach);
  107972. +
  107973. + /* Verify the arguments. */
  107974. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  107975. +
  107976. + /* Get current process ID. */
  107977. + gcmkONERROR(gckOS_GetProcessID(&processID));
  107978. +
  107979. + gcmkONERROR(gckKERNEL_AttachProcessEx(Kernel, Attach, processID));
  107980. +
  107981. + /* Success. */
  107982. + gcmkFOOTER_NO();
  107983. + return gcvSTATUS_OK;
  107984. +
  107985. +OnError:
  107986. + /* Return the status. */
  107987. + gcmkFOOTER();
  107988. + return status;
  107989. +}
  107990. +
  107991. +/*******************************************************************************
  107992. +** gckKERNEL_AttachProcessEx
  107993. +**
  107994. +** Attach or detach a process with the given PID. Can be paired with gckKERNEL_AttachProcess
  107995. +** provided the programmer is aware of the consequences.
  107996. +**
  107997. +** INPUT:
  107998. +**
  107999. +** gckKERNEL Kernel
  108000. +** Pointer to an gckKERNEL object.
  108001. +**
  108002. +** gctBOOL Attach
  108003. +** gcvTRUE if a new process gets attached or gcFALSE when a process
  108004. +** gets detatched.
  108005. +**
  108006. +** gctUINT32 PID
  108007. +** PID of the process to attach or detach.
  108008. +**
  108009. +** OUTPUT:
  108010. +**
  108011. +** Nothing.
  108012. +*/
  108013. +gceSTATUS
  108014. +gckKERNEL_AttachProcessEx(
  108015. + IN gckKERNEL Kernel,
  108016. + IN gctBOOL Attach,
  108017. + IN gctUINT32 PID
  108018. + )
  108019. +{
  108020. + gceSTATUS status;
  108021. + gctINT32 old;
  108022. +
  108023. + gcmkHEADER_ARG("Kernel=0x%x Attach=%d PID=%d", Kernel, Attach, PID);
  108024. +
  108025. + /* Verify the arguments. */
  108026. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  108027. +
  108028. + if (Attach)
  108029. + {
  108030. + /* Increment the number of clients attached. */
  108031. + gcmkONERROR(
  108032. + gckOS_AtomIncrement(Kernel->os, Kernel->atomClients, &old));
  108033. +
  108034. + if (old == 0)
  108035. + {
  108036. +#if gcdENABLE_VG
  108037. + if (Kernel->vg == gcvNULL)
  108038. +#endif
  108039. + {
  108040. + gcmkONERROR(gckOS_Broadcast(Kernel->os,
  108041. + Kernel->hardware,
  108042. + gcvBROADCAST_FIRST_PROCESS));
  108043. + }
  108044. + }
  108045. +
  108046. + if (Kernel->dbCreated)
  108047. + {
  108048. + /* Create the process database. */
  108049. + gcmkONERROR(gckKERNEL_CreateProcessDB(Kernel, PID));
  108050. + }
  108051. + }
  108052. + else
  108053. + {
  108054. + if (Kernel->dbCreated)
  108055. + {
  108056. + /* Clean up the process database. */
  108057. + gcmkONERROR(gckKERNEL_DestroyProcessDB(Kernel, PID));
  108058. +
  108059. + /* Save the last know process ID. */
  108060. + Kernel->db->lastProcessID = PID;
  108061. + }
  108062. +
  108063. +#if gcdENABLE_VG
  108064. + if (Kernel->vg == gcvNULL)
  108065. +#endif
  108066. + {
  108067. + status = gckEVENT_Submit(Kernel->eventObj, gcvTRUE, gcvFALSE);
  108068. +
  108069. + if (status == gcvSTATUS_INTERRUPTED && Kernel->eventObj->submitTimer)
  108070. + {
  108071. + gcmkONERROR(gckOS_StartTimer(Kernel->os,
  108072. + Kernel->eventObj->submitTimer,
  108073. + 1));
  108074. + }
  108075. + else
  108076. + {
  108077. + gcmkONERROR(status);
  108078. + }
  108079. + }
  108080. +
  108081. + /* Decrement the number of clients attached. */
  108082. + gcmkONERROR(
  108083. + gckOS_AtomDecrement(Kernel->os, Kernel->atomClients, &old));
  108084. +
  108085. + if (old == 1)
  108086. + {
  108087. +#if gcdENABLE_VG
  108088. + if (Kernel->vg == gcvNULL)
  108089. +#endif
  108090. + {
  108091. + /* Last client detached, switch to SUSPEND power state. */
  108092. + gcmkONERROR(gckOS_Broadcast(Kernel->os,
  108093. + Kernel->hardware,
  108094. + gcvBROADCAST_LAST_PROCESS));
  108095. + }
  108096. +
  108097. + /* Flush the debug cache. */
  108098. + gcmkDEBUGFLUSH(~0U);
  108099. + }
  108100. + }
  108101. +
  108102. + /* Success. */
  108103. + gcmkFOOTER_NO();
  108104. + return gcvSTATUS_OK;
  108105. +
  108106. +OnError:
  108107. + /* Return the status. */
  108108. + gcmkFOOTER();
  108109. + return status;
  108110. +}
  108111. +
  108112. +#if gcdSECURE_USER
  108113. +gceSTATUS
  108114. +gckKERNEL_MapLogicalToPhysical(
  108115. + IN gckKERNEL Kernel,
  108116. + IN gcskSECURE_CACHE_PTR Cache,
  108117. + IN OUT gctPOINTER * Data
  108118. + )
  108119. +{
  108120. + gceSTATUS status;
  108121. + static gctBOOL baseAddressValid = gcvFALSE;
  108122. + static gctUINT32 baseAddress;
  108123. + gctBOOL needBase;
  108124. + gcskLOGICAL_CACHE_PTR slot;
  108125. +
  108126. + gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x *Data=0x%x",
  108127. + Kernel, Cache, gcmOPT_POINTER(Data));
  108128. +
  108129. + /* Verify the arguments. */
  108130. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  108131. +
  108132. + if (!baseAddressValid)
  108133. + {
  108134. + /* Get base address. */
  108135. + gcmkONERROR(gckHARDWARE_GetBaseAddress(Kernel->hardware, &baseAddress));
  108136. +
  108137. + baseAddressValid = gcvTRUE;
  108138. + }
  108139. +
  108140. + /* Does this state load need a base address? */
  108141. + gcmkONERROR(gckHARDWARE_NeedBaseAddress(Kernel->hardware,
  108142. + ((gctUINT32_PTR) Data)[-1],
  108143. + &needBase));
  108144. +
  108145. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
  108146. + {
  108147. + gcskLOGICAL_CACHE_PTR next;
  108148. + gctINT i;
  108149. +
  108150. + /* Walk all used cache slots. */
  108151. + for (i = 1, slot = Cache->cache[0].next, next = gcvNULL;
  108152. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  108153. + ++i, slot = slot->next
  108154. + )
  108155. + {
  108156. + if (slot->logical == *Data)
  108157. + {
  108158. + /* Bail out. */
  108159. + next = slot;
  108160. + break;
  108161. + }
  108162. + }
  108163. +
  108164. + /* See if we had a miss. */
  108165. + if (next == gcvNULL)
  108166. + {
  108167. + /* Use the tail of the cache. */
  108168. + slot = Cache->cache[0].prev;
  108169. +
  108170. + /* Initialize the cache line. */
  108171. + slot->logical = *Data;
  108172. +
  108173. + /* Map the logical address to a DMA address. */
  108174. + gcmkONERROR(
  108175. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  108176. + }
  108177. +
  108178. + /* Move slot to head of list. */
  108179. + if (slot != Cache->cache[0].next)
  108180. + {
  108181. + /* Unlink. */
  108182. + slot->prev->next = slot->next;
  108183. + slot->next->prev = slot->prev;
  108184. +
  108185. + /* Move to head of chain. */
  108186. + slot->prev = &Cache->cache[0];
  108187. + slot->next = Cache->cache[0].next;
  108188. + slot->prev->next = slot;
  108189. + slot->next->prev = slot;
  108190. + }
  108191. + }
  108192. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
  108193. + {
  108194. + gctINT i;
  108195. + gcskLOGICAL_CACHE_PTR next = gcvNULL;
  108196. + gcskLOGICAL_CACHE_PTR oldestSlot = gcvNULL;
  108197. + slot = gcvNULL;
  108198. +
  108199. + if (Cache->cacheIndex != gcvNULL)
  108200. + {
  108201. + /* Walk the cache forwards. */
  108202. + for (i = 1, slot = Cache->cacheIndex;
  108203. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  108204. + ++i, slot = slot->next)
  108205. + {
  108206. + if (slot->logical == *Data)
  108207. + {
  108208. + /* Bail out. */
  108209. + next = slot;
  108210. + break;
  108211. + }
  108212. +
  108213. + /* Determine age of this slot. */
  108214. + if ((oldestSlot == gcvNULL)
  108215. + || (oldestSlot->stamp > slot->stamp)
  108216. + )
  108217. + {
  108218. + oldestSlot = slot;
  108219. + }
  108220. + }
  108221. +
  108222. + if (next == gcvNULL)
  108223. + {
  108224. + /* Walk the cache backwards. */
  108225. + for (slot = Cache->cacheIndex->prev;
  108226. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  108227. + ++i, slot = slot->prev)
  108228. + {
  108229. + if (slot->logical == *Data)
  108230. + {
  108231. + /* Bail out. */
  108232. + next = slot;
  108233. + break;
  108234. + }
  108235. +
  108236. + /* Determine age of this slot. */
  108237. + if ((oldestSlot == gcvNULL)
  108238. + || (oldestSlot->stamp > slot->stamp)
  108239. + )
  108240. + {
  108241. + oldestSlot = slot;
  108242. + }
  108243. + }
  108244. + }
  108245. + }
  108246. +
  108247. + /* See if we had a miss. */
  108248. + if (next == gcvNULL)
  108249. + {
  108250. + if (Cache->cacheFree != 0)
  108251. + {
  108252. + slot = &Cache->cache[Cache->cacheFree];
  108253. + gcmkASSERT(slot->logical == gcvNULL);
  108254. +
  108255. + ++ Cache->cacheFree;
  108256. + if (Cache->cacheFree >= gcmCOUNTOF(Cache->cache))
  108257. + {
  108258. + Cache->cacheFree = 0;
  108259. + }
  108260. + }
  108261. + else
  108262. + {
  108263. + /* Use the oldest cache slot. */
  108264. + gcmkASSERT(oldestSlot != gcvNULL);
  108265. + slot = oldestSlot;
  108266. +
  108267. + /* Unlink from the chain. */
  108268. + slot->prev->next = slot->next;
  108269. + slot->next->prev = slot->prev;
  108270. +
  108271. + /* Append to the end. */
  108272. + slot->prev = Cache->cache[0].prev;
  108273. + slot->next = &Cache->cache[0];
  108274. + slot->prev->next = slot;
  108275. + slot->next->prev = slot;
  108276. + }
  108277. +
  108278. + /* Initialize the cache line. */
  108279. + slot->logical = *Data;
  108280. +
  108281. + /* Map the logical address to a DMA address. */
  108282. + gcmkONERROR(
  108283. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  108284. + }
  108285. +
  108286. + /* Save time stamp. */
  108287. + slot->stamp = ++ Cache->cacheStamp;
  108288. +
  108289. + /* Save current slot for next lookup. */
  108290. + Cache->cacheIndex = slot;
  108291. + }
  108292. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  108293. + {
  108294. + gctINT i;
  108295. + gctUINT32 data = gcmPTR2INT(*Data);
  108296. + gctUINT32 key, index;
  108297. + gcskLOGICAL_CACHE_PTR hash;
  108298. +
  108299. + /* Generate a hash key. */
  108300. + key = (data >> 24) + (data >> 16) + (data >> 8) + data;
  108301. + index = key % gcmCOUNTOF(Cache->hash);
  108302. +
  108303. + /* Get the hash entry. */
  108304. + hash = &Cache->hash[index];
  108305. +
  108306. + for (slot = hash->nextHash, i = 0;
  108307. + (slot != gcvNULL) && (i < gcdSECURE_CACHE_SLOTS);
  108308. + slot = slot->nextHash, ++i
  108309. + )
  108310. + {
  108311. + if (slot->logical == (*Data))
  108312. + {
  108313. + break;
  108314. + }
  108315. + }
  108316. +
  108317. + if (slot == gcvNULL)
  108318. + {
  108319. + /* Grab from the tail of the cache. */
  108320. + slot = Cache->cache[0].prev;
  108321. +
  108322. + /* Unlink slot from any hash table it is part of. */
  108323. + if (slot->prevHash != gcvNULL)
  108324. + {
  108325. + slot->prevHash->nextHash = slot->nextHash;
  108326. + }
  108327. + if (slot->nextHash != gcvNULL)
  108328. + {
  108329. + slot->nextHash->prevHash = slot->prevHash;
  108330. + }
  108331. +
  108332. + /* Initialize the cache line. */
  108333. + slot->logical = *Data;
  108334. +
  108335. + /* Map the logical address to a DMA address. */
  108336. + gcmkONERROR(
  108337. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  108338. +
  108339. + if (hash->nextHash != gcvNULL)
  108340. + {
  108341. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  108342. + "Hash Collision: logical=0x%x key=0x%08x",
  108343. + *Data, key);
  108344. + }
  108345. +
  108346. + /* Insert the slot at the head of the hash list. */
  108347. + slot->nextHash = hash->nextHash;
  108348. + if (slot->nextHash != gcvNULL)
  108349. + {
  108350. + slot->nextHash->prevHash = slot;
  108351. + }
  108352. + slot->prevHash = hash;
  108353. + hash->nextHash = slot;
  108354. + }
  108355. +
  108356. + /* Move slot to head of list. */
  108357. + if (slot != Cache->cache[0].next)
  108358. + {
  108359. + /* Unlink. */
  108360. + slot->prev->next = slot->next;
  108361. + slot->next->prev = slot->prev;
  108362. +
  108363. + /* Move to head of chain. */
  108364. + slot->prev = &Cache->cache[0];
  108365. + slot->next = Cache->cache[0].next;
  108366. + slot->prev->next = slot;
  108367. + slot->next->prev = slot;
  108368. + }
  108369. + }
  108370. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
  108371. + {
  108372. + gctUINT32 index = (gcmPTR2INT(*Data) % gcdSECURE_CACHE_SLOTS) + 1;
  108373. +
  108374. + /* Get cache slot. */
  108375. + slot = &Cache->cache[index];
  108376. +
  108377. + /* Check for cache miss. */
  108378. + if (slot->logical != *Data)
  108379. + {
  108380. + /* Initialize the cache line. */
  108381. + slot->logical = *Data;
  108382. +
  108383. + /* Map the logical address to a DMA address. */
  108384. + gcmkONERROR(
  108385. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  108386. + }
  108387. + }
  108388. +#endif
  108389. +
  108390. + /* Return DMA address. */
  108391. + *Data = gcmINT2PTR(slot->dma + (needBase ? baseAddress : 0));
  108392. +
  108393. + /* Success. */
  108394. + gcmkFOOTER_ARG("*Data=0x%08x", *Data);
  108395. + return gcvSTATUS_OK;
  108396. +
  108397. +OnError:
  108398. + /* Return the status. */
  108399. + gcmkFOOTER();
  108400. + return status;
  108401. +}
  108402. +
  108403. +gceSTATUS
  108404. +gckKERNEL_FlushTranslationCache(
  108405. + IN gckKERNEL Kernel,
  108406. + IN gcskSECURE_CACHE_PTR Cache,
  108407. + IN gctPOINTER Logical,
  108408. + IN gctSIZE_T Bytes
  108409. + )
  108410. +{
  108411. + gctINT i;
  108412. + gcskLOGICAL_CACHE_PTR slot;
  108413. + gctUINT8_PTR ptr;
  108414. +
  108415. + gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x Logical=0x%x Bytes=%lu",
  108416. + Kernel, Cache, Logical, Bytes);
  108417. +
  108418. + /* Do we need to flush the entire cache? */
  108419. + if (Logical == gcvNULL)
  108420. + {
  108421. + /* Clear all cache slots. */
  108422. + for (i = 1; i <= gcdSECURE_CACHE_SLOTS; ++i)
  108423. + {
  108424. + Cache->cache[i].logical = gcvNULL;
  108425. +
  108426. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  108427. + Cache->cache[i].nextHash = gcvNULL;
  108428. + Cache->cache[i].prevHash = gcvNULL;
  108429. +#endif
  108430. +}
  108431. +
  108432. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  108433. + /* Zero the hash table. */
  108434. + for (i = 0; i < gcmCOUNTOF(Cache->hash); ++i)
  108435. + {
  108436. + Cache->hash[i].nextHash = gcvNULL;
  108437. + }
  108438. +#endif
  108439. +
  108440. + /* Reset the cache functionality. */
  108441. + Cache->cacheIndex = gcvNULL;
  108442. + Cache->cacheFree = 1;
  108443. + Cache->cacheStamp = 0;
  108444. + }
  108445. +
  108446. + else
  108447. + {
  108448. + gctUINT8_PTR low = (gctUINT8_PTR) Logical;
  108449. + gctUINT8_PTR high = low + Bytes;
  108450. +
  108451. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
  108452. + gcskLOGICAL_CACHE_PTR next;
  108453. +
  108454. + /* Walk all used cache slots. */
  108455. + for (i = 1, slot = Cache->cache[0].next;
  108456. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  108457. + ++i, slot = next
  108458. + )
  108459. + {
  108460. + /* Save pointer to next slot. */
  108461. + next = slot->next;
  108462. +
  108463. + /* Test if this slot falls within the range to flush. */
  108464. + ptr = (gctUINT8_PTR) slot->logical;
  108465. + if ((ptr >= low) && (ptr < high))
  108466. + {
  108467. + /* Unlink slot. */
  108468. + slot->prev->next = slot->next;
  108469. + slot->next->prev = slot->prev;
  108470. +
  108471. + /* Append slot to tail of cache. */
  108472. + slot->prev = Cache->cache[0].prev;
  108473. + slot->next = &Cache->cache[0];
  108474. + slot->prev->next = slot;
  108475. + slot->next->prev = slot;
  108476. +
  108477. + /* Mark slot as empty. */
  108478. + slot->logical = gcvNULL;
  108479. + }
  108480. + }
  108481. +
  108482. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
  108483. + gcskLOGICAL_CACHE_PTR next;
  108484. +
  108485. + for (i = 1, slot = Cache->cache[0].next;
  108486. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  108487. + ++i, slot = next)
  108488. + {
  108489. + /* Save pointer to next slot. */
  108490. + next = slot->next;
  108491. +
  108492. + /* Test if this slot falls within the range to flush. */
  108493. + ptr = (gctUINT8_PTR) slot->logical;
  108494. + if ((ptr >= low) && (ptr < high))
  108495. + {
  108496. + /* Test if this slot is the current slot. */
  108497. + if (slot == Cache->cacheIndex)
  108498. + {
  108499. + /* Move to next or previous slot. */
  108500. + Cache->cacheIndex = (slot->next->logical != gcvNULL)
  108501. + ? slot->next
  108502. + : (slot->prev->logical != gcvNULL)
  108503. + ? slot->prev
  108504. + : gcvNULL;
  108505. + }
  108506. +
  108507. + /* Unlink slot from cache. */
  108508. + slot->prev->next = slot->next;
  108509. + slot->next->prev = slot->prev;
  108510. +
  108511. + /* Insert slot to head of cache. */
  108512. + slot->prev = &Cache->cache[0];
  108513. + slot->next = Cache->cache[0].next;
  108514. + slot->prev->next = slot;
  108515. + slot->next->prev = slot;
  108516. +
  108517. + /* Mark slot as empty. */
  108518. + slot->logical = gcvNULL;
  108519. + slot->stamp = 0;
  108520. + }
  108521. + }
  108522. +
  108523. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  108524. + gctINT j;
  108525. + gcskLOGICAL_CACHE_PTR hash, next;
  108526. +
  108527. + /* Walk all hash tables. */
  108528. + for (i = 0, hash = Cache->hash;
  108529. + i < gcmCOUNTOF(Cache->hash);
  108530. + ++i, ++hash)
  108531. + {
  108532. + /* Walk all slots in the hash. */
  108533. + for (j = 0, slot = hash->nextHash;
  108534. + (j < gcdSECURE_CACHE_SLOTS) && (slot != gcvNULL);
  108535. + ++j, slot = next)
  108536. + {
  108537. + /* Save pointer to next slot. */
  108538. + next = slot->next;
  108539. +
  108540. + /* Test if this slot falls within the range to flush. */
  108541. + ptr = (gctUINT8_PTR) slot->logical;
  108542. + if ((ptr >= low) && (ptr < high))
  108543. + {
  108544. + /* Unlink slot from hash table. */
  108545. + if (slot->prevHash == hash)
  108546. + {
  108547. + hash->nextHash = slot->nextHash;
  108548. + }
  108549. + else
  108550. + {
  108551. + slot->prevHash->nextHash = slot->nextHash;
  108552. + }
  108553. +
  108554. + if (slot->nextHash != gcvNULL)
  108555. + {
  108556. + slot->nextHash->prevHash = slot->prevHash;
  108557. + }
  108558. +
  108559. + /* Unlink slot from cache. */
  108560. + slot->prev->next = slot->next;
  108561. + slot->next->prev = slot->prev;
  108562. +
  108563. + /* Append slot to tail of cache. */
  108564. + slot->prev = Cache->cache[0].prev;
  108565. + slot->next = &Cache->cache[0];
  108566. + slot->prev->next = slot;
  108567. + slot->next->prev = slot;
  108568. +
  108569. + /* Mark slot as empty. */
  108570. + slot->logical = gcvNULL;
  108571. + slot->prevHash = gcvNULL;
  108572. + slot->nextHash = gcvNULL;
  108573. + }
  108574. + }
  108575. + }
  108576. +
  108577. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
  108578. + gctUINT32 index;
  108579. +
  108580. + /* Loop while inside the range. */
  108581. + for (i = 1; (low < high) && (i <= gcdSECURE_CACHE_SLOTS); ++i)
  108582. + {
  108583. + /* Get index into cache for this range. */
  108584. + index = (gcmPTR2INT(low) % gcdSECURE_CACHE_SLOTS) + 1;
  108585. + slot = &Cache->cache[index];
  108586. +
  108587. + /* Test if this slot falls within the range to flush. */
  108588. + ptr = (gctUINT8_PTR) slot->logical;
  108589. + if ((ptr >= low) && (ptr < high))
  108590. + {
  108591. + /* Remove entry from cache. */
  108592. + slot->logical = gcvNULL;
  108593. + }
  108594. +
  108595. + /* Next block. */
  108596. + low += gcdSECURE_CACHE_SLOTS;
  108597. + }
  108598. +#endif
  108599. + }
  108600. +
  108601. + /* Success. */
  108602. + gcmkFOOTER_NO();
  108603. + return gcvSTATUS_OK;
  108604. +}
  108605. +#endif
  108606. +
  108607. +/*******************************************************************************
  108608. +**
  108609. +** gckKERNEL_Recovery
  108610. +**
  108611. +** Try to recover the GPU from a fatal error.
  108612. +**
  108613. +** INPUT:
  108614. +**
  108615. +** gckKERNEL Kernel
  108616. +** Pointer to an gckKERNEL object.
  108617. +**
  108618. +** OUTPUT:
  108619. +**
  108620. +** Nothing.
  108621. +*/
  108622. +gceSTATUS
  108623. +gckKERNEL_Recovery(
  108624. + IN gckKERNEL Kernel
  108625. + )
  108626. +{
  108627. +#if gcdENABLE_RECOVERY
  108628. +#define gcdEVENT_MASK 0x3FFFFFFF
  108629. + gceSTATUS status;
  108630. + gckEVENT eventObj;
  108631. + gckHARDWARE hardware;
  108632. +#if gcdSECURE_USER
  108633. + gctUINT32 processID;
  108634. + gcskSECURE_CACHE_PTR cache;
  108635. +#endif
  108636. + gctUINT32 oldValue;
  108637. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  108638. +
  108639. + /* Validate the arguemnts. */
  108640. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  108641. +
  108642. + /* Grab gckEVENT object. */
  108643. + eventObj = Kernel->eventObj;
  108644. + gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
  108645. +
  108646. + /* Grab gckHARDWARE object. */
  108647. + hardware = Kernel->hardware;
  108648. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  108649. +
  108650. +#if gcdSECURE_USER
  108651. + /* Flush the secure mapping cache. */
  108652. + gcmkONERROR(gckOS_GetProcessID(&processID));
  108653. + gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
  108654. + gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0));
  108655. +#endif
  108656. +
  108657. + gcmkONERROR(
  108658. + gckOS_AtomicExchange(Kernel->os, Kernel->resetAtom, 1, &oldValue));
  108659. +
  108660. + if (oldValue)
  108661. + {
  108662. + /* Some one else will recovery GPU. */
  108663. + return gcvSTATUS_OK;
  108664. + }
  108665. +
  108666. + gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core);
  108667. +
  108668. + /* Start a timer to clear reset flag, before timer is expired,
  108669. + ** other recovery request is ignored. */
  108670. + gcmkVERIFY_OK(
  108671. + gckOS_StartTimer(Kernel->os,
  108672. + Kernel->resetFlagClearTimer,
  108673. + gcdGPU_TIMEOUT - 500));
  108674. +
  108675. +
  108676. + /* Try issuing a soft reset for the GPU. */
  108677. + status = gckHARDWARE_Reset(hardware);
  108678. + if (status == gcvSTATUS_NOT_SUPPORTED)
  108679. + {
  108680. + /* Switch to OFF power. The next submit should return the GPU to ON
  108681. + ** state. */
  108682. + gcmkONERROR(
  108683. + gckHARDWARE_SetPowerManagementState(hardware,
  108684. + gcvPOWER_OFF_RECOVERY));
  108685. + }
  108686. + else
  108687. + {
  108688. + /* Bail out on reset error. */
  108689. + gcmkONERROR(status);
  108690. + }
  108691. +
  108692. + /* Handle all outstanding events now. */
  108693. +#if gcdSMP
  108694. + gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
  108695. +#else
  108696. + eventObj->pending = gcdEVENT_MASK;
  108697. +#endif
  108698. + gcmkONERROR(gckEVENT_Notify(eventObj, 1));
  108699. +
  108700. + /* Again in case more events got submitted. */
  108701. +#if gcdSMP
  108702. + gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
  108703. +#else
  108704. + eventObj->pending = gcdEVENT_MASK;
  108705. +#endif
  108706. + gcmkONERROR(gckEVENT_Notify(eventObj, 2));
  108707. +
  108708. + Kernel->resetTimeStamp++;
  108709. +
  108710. + /* Success. */
  108711. + gcmkFOOTER_NO();
  108712. + return gcvSTATUS_OK;
  108713. +
  108714. +OnError:
  108715. + /* Return the status. */
  108716. + gcmkFOOTER();
  108717. + return status;
  108718. +#else
  108719. + return gcvSTATUS_OK;
  108720. +#endif
  108721. +}
  108722. +
  108723. +/*******************************************************************************
  108724. +**
  108725. +** gckKERNEL_OpenUserData
  108726. +**
  108727. +** Get access to the user data.
  108728. +**
  108729. +** INPUT:
  108730. +**
  108731. +** gckKERNEL Kernel
  108732. +** Pointer to an gckKERNEL object.
  108733. +**
  108734. +** gctBOOL NeedCopy
  108735. +** The flag indicating whether or not the data should be copied.
  108736. +**
  108737. +** gctPOINTER StaticStorage
  108738. +** Pointer to the kernel storage where the data is to be copied if
  108739. +** NeedCopy is gcvTRUE.
  108740. +**
  108741. +** gctPOINTER UserPointer
  108742. +** User pointer to the data.
  108743. +**
  108744. +** gctSIZE_T Size
  108745. +** Size of the data.
  108746. +**
  108747. +** OUTPUT:
  108748. +**
  108749. +** gctPOINTER * KernelPointer
  108750. +** Pointer to the kernel pointer that will be pointing to the data.
  108751. +*/
  108752. +gceSTATUS
  108753. +gckKERNEL_OpenUserData(
  108754. + IN gckKERNEL Kernel,
  108755. + IN gctBOOL NeedCopy,
  108756. + IN gctPOINTER StaticStorage,
  108757. + IN gctPOINTER UserPointer,
  108758. + IN gctSIZE_T Size,
  108759. + OUT gctPOINTER * KernelPointer
  108760. + )
  108761. +{
  108762. + gceSTATUS status;
  108763. +
  108764. + gcmkHEADER_ARG(
  108765. + "Kernel=0x%08X NeedCopy=%d StaticStorage=0x%08X "
  108766. + "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
  108767. + Kernel, NeedCopy, StaticStorage, UserPointer, Size, KernelPointer
  108768. + );
  108769. +
  108770. + /* Validate the arguemnts. */
  108771. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  108772. + gcmkVERIFY_ARGUMENT(!NeedCopy || (StaticStorage != gcvNULL));
  108773. + gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
  108774. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  108775. + gcmkVERIFY_ARGUMENT(Size > 0);
  108776. +
  108777. + if (NeedCopy)
  108778. + {
  108779. + /* Copy the user data to the static storage. */
  108780. + gcmkONERROR(gckOS_CopyFromUserData(
  108781. + Kernel->os, StaticStorage, UserPointer, Size
  108782. + ));
  108783. +
  108784. + /* Set the kernel pointer. */
  108785. + * KernelPointer = StaticStorage;
  108786. + }
  108787. + else
  108788. + {
  108789. + gctPOINTER pointer = gcvNULL;
  108790. +
  108791. + /* Map the user pointer. */
  108792. + gcmkONERROR(gckOS_MapUserPointer(
  108793. + Kernel->os, UserPointer, Size, &pointer
  108794. + ));
  108795. +
  108796. + /* Set the kernel pointer. */
  108797. + * KernelPointer = pointer;
  108798. + }
  108799. +
  108800. +OnError:
  108801. + /* Return the status. */
  108802. + gcmkFOOTER();
  108803. + return status;
  108804. +}
  108805. +
  108806. +/*******************************************************************************
  108807. +**
  108808. +** gckKERNEL_CloseUserData
  108809. +**
  108810. +** Release resources associated with the user data connection opened by
  108811. +** gckKERNEL_OpenUserData.
  108812. +**
  108813. +** INPUT:
  108814. +**
  108815. +** gckKERNEL Kernel
  108816. +** Pointer to an gckKERNEL object.
  108817. +**
  108818. +** gctBOOL NeedCopy
  108819. +** The flag indicating whether or not the data should be copied.
  108820. +**
  108821. +** gctBOOL FlushData
  108822. +** If gcvTRUE, the data is written back to the user.
  108823. +**
  108824. +** gctPOINTER UserPointer
  108825. +** User pointer to the data.
  108826. +**
  108827. +** gctSIZE_T Size
  108828. +** Size of the data.
  108829. +**
  108830. +** OUTPUT:
  108831. +**
  108832. +** gctPOINTER * KernelPointer
  108833. +** Kernel pointer to the data.
  108834. +*/
  108835. +gceSTATUS
  108836. +gckKERNEL_CloseUserData(
  108837. + IN gckKERNEL Kernel,
  108838. + IN gctBOOL NeedCopy,
  108839. + IN gctBOOL FlushData,
  108840. + IN gctPOINTER UserPointer,
  108841. + IN gctSIZE_T Size,
  108842. + OUT gctPOINTER * KernelPointer
  108843. + )
  108844. +{
  108845. + gceSTATUS status = gcvSTATUS_OK;
  108846. + gctPOINTER pointer;
  108847. +
  108848. + gcmkHEADER_ARG(
  108849. + "Kernel=0x%08X NeedCopy=%d FlushData=%d "
  108850. + "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
  108851. + Kernel, NeedCopy, FlushData, UserPointer, Size, KernelPointer
  108852. + );
  108853. +
  108854. + /* Validate the arguemnts. */
  108855. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  108856. + gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
  108857. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  108858. + gcmkVERIFY_ARGUMENT(Size > 0);
  108859. +
  108860. + /* Get a shortcut to the kernel pointer. */
  108861. + pointer = * KernelPointer;
  108862. +
  108863. + if (pointer != gcvNULL)
  108864. + {
  108865. + if (NeedCopy)
  108866. + {
  108867. + if (FlushData)
  108868. + {
  108869. + gcmkONERROR(gckOS_CopyToUserData(
  108870. + Kernel->os, * KernelPointer, UserPointer, Size
  108871. + ));
  108872. + }
  108873. + }
  108874. + else
  108875. + {
  108876. + /* Unmap record from kernel memory. */
  108877. + gcmkONERROR(gckOS_UnmapUserPointer(
  108878. + Kernel->os,
  108879. + UserPointer,
  108880. + Size,
  108881. + * KernelPointer
  108882. + ));
  108883. + }
  108884. +
  108885. + /* Reset the kernel pointer. */
  108886. + * KernelPointer = gcvNULL;
  108887. + }
  108888. +
  108889. +OnError:
  108890. + /* Return the status. */
  108891. + gcmkFOOTER();
  108892. + return status;
  108893. +}
  108894. +
  108895. +void
  108896. +gckKERNEL_SetTimeOut(
  108897. + IN gckKERNEL Kernel,
  108898. + IN gctUINT32 timeOut
  108899. + )
  108900. +{
  108901. + gcmkHEADER_ARG("Kernel=0x%x timeOut=%d", Kernel, timeOut);
  108902. +#if gcdGPU_TIMEOUT
  108903. + Kernel->timeOut = timeOut;
  108904. +#endif
  108905. + gcmkFOOTER_NO();
  108906. +}
  108907. +
  108908. +#if gcdVIRTUAL_COMMAND_BUFFER
  108909. +gceSTATUS
  108910. +gckKERNEL_AllocateVirtualCommandBuffer(
  108911. + IN gckKERNEL Kernel,
  108912. + IN gctBOOL InUserSpace,
  108913. + IN OUT gctSIZE_T * Bytes,
  108914. + OUT gctPHYS_ADDR * Physical,
  108915. + OUT gctPOINTER * Logical
  108916. + )
  108917. +{
  108918. + gckOS os = Kernel->os;
  108919. + gceSTATUS status;
  108920. + gctPOINTER logical;
  108921. + gctSIZE_T pageCount;
  108922. + gctSIZE_T bytes = *Bytes;
  108923. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  108924. +
  108925. + gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
  108926. + os, InUserSpace, gcmOPT_VALUE(Bytes));
  108927. +
  108928. + /* Verify the arguments. */
  108929. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  108930. + gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
  108931. + gcmkVERIFY_ARGUMENT(*Bytes > 0);
  108932. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  108933. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  108934. +
  108935. + gcmkONERROR(gckOS_Allocate(os,
  108936. + sizeof(gckVIRTUAL_COMMAND_BUFFER),
  108937. + (gctPOINTER)&buffer));
  108938. +
  108939. + gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_COMMAND_BUFFER)));
  108940. +
  108941. + gcmkONERROR(gckOS_AllocatePagedMemoryEx(os,
  108942. + gcvFALSE,
  108943. + bytes,
  108944. + &buffer->physical));
  108945. +
  108946. + if (InUserSpace)
  108947. + {
  108948. + gcmkONERROR(gckOS_LockPages(os,
  108949. + buffer->physical,
  108950. + bytes,
  108951. + gcvFALSE,
  108952. + &logical,
  108953. + &pageCount));
  108954. +
  108955. + *Logical =
  108956. + buffer->userLogical = logical;
  108957. + }
  108958. + else
  108959. + {
  108960. + gcmkONERROR(
  108961. + gckOS_CreateKernelVirtualMapping(buffer->physical,
  108962. + &pageCount,
  108963. + &logical));
  108964. + *Logical =
  108965. + buffer->kernelLogical = logical;
  108966. + }
  108967. +
  108968. + buffer->pageCount = pageCount;
  108969. + buffer->kernel = Kernel;
  108970. +
  108971. + gcmkONERROR(gckOS_GetProcessID(&buffer->pid));
  108972. +
  108973. + gcmkONERROR(gckMMU_AllocatePages(Kernel->mmu,
  108974. + pageCount,
  108975. + &buffer->pageTable,
  108976. + &buffer->gpuAddress));
  108977. +
  108978. + gcmkONERROR(gckOS_MapPagesEx(os,
  108979. + Kernel->core,
  108980. + buffer->physical,
  108981. + pageCount,
  108982. + buffer->pageTable));
  108983. +
  108984. + gcmkONERROR(gckMMU_Flush(Kernel->mmu));
  108985. +
  108986. + *Physical = buffer;
  108987. +
  108988. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  108989. + "gpuAddress = %x pageCount = %d kernelLogical = %x userLogical=%x",
  108990. + buffer->gpuAddress, buffer->pageCount,
  108991. + buffer->kernelLogical, buffer->userLogical);
  108992. +
  108993. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, Kernel->virtualBufferLock, gcvINFINITE));
  108994. +
  108995. + if (Kernel->virtualBufferHead == gcvNULL)
  108996. + {
  108997. + Kernel->virtualBufferHead =
  108998. + Kernel->virtualBufferTail = buffer;
  108999. + }
  109000. + else
  109001. + {
  109002. + buffer->prev = Kernel->virtualBufferTail;
  109003. + Kernel->virtualBufferTail->next = buffer;
  109004. + Kernel->virtualBufferTail = buffer;
  109005. + }
  109006. +
  109007. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Kernel->virtualBufferLock));
  109008. +
  109009. + gcmkFOOTER_NO();
  109010. + return gcvSTATUS_OK;
  109011. +
  109012. +OnError:
  109013. + if (buffer->gpuAddress)
  109014. + {
  109015. + gcmkVERIFY_OK(
  109016. + gckMMU_FreePages(Kernel->mmu, buffer->pageTable, buffer->pageCount));
  109017. + }
  109018. +
  109019. + if (buffer->userLogical)
  109020. + {
  109021. + gcmkVERIFY_OK(
  109022. + gckOS_UnlockPages(os, buffer->physical, bytes, buffer->userLogical));
  109023. + }
  109024. +
  109025. + if (buffer->kernelLogical)
  109026. + {
  109027. + gcmkVERIFY_OK(
  109028. + gckOS_DestroyKernelVirtualMapping(buffer->kernelLogical));
  109029. + }
  109030. +
  109031. + if (buffer->physical)
  109032. + {
  109033. + gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, bytes));
  109034. + }
  109035. +
  109036. + gcmkVERIFY_OK(gckOS_Free(os, buffer));
  109037. +
  109038. + /* Return the status. */
  109039. + gcmkFOOTER();
  109040. + return status;
  109041. +}
  109042. +
  109043. +gceSTATUS
  109044. +gckKERNEL_DestroyVirtualCommandBuffer(
  109045. + IN gckKERNEL Kernel,
  109046. + IN gctSIZE_T Bytes,
  109047. + IN gctPHYS_ADDR Physical,
  109048. + IN gctPOINTER Logical
  109049. + )
  109050. +{
  109051. + gckOS os;
  109052. + gckKERNEL kernel;
  109053. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)Physical;
  109054. +
  109055. + gcmkHEADER();
  109056. + gcmkVERIFY_ARGUMENT(buffer != gcvNULL);
  109057. +
  109058. + kernel = buffer->kernel;
  109059. + os = kernel->os;
  109060. +
  109061. + if (buffer->userLogical)
  109062. + {
  109063. + gcmkVERIFY_OK(gckOS_UnlockPages(os, buffer->physical, Bytes, Logical));
  109064. + }
  109065. + else
  109066. + {
  109067. + gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(Logical));
  109068. + }
  109069. +
  109070. + gcmkVERIFY_OK(
  109071. + gckMMU_FreePages(kernel->mmu, buffer->pageTable, buffer->pageCount));
  109072. +
  109073. + gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, Bytes));
  109074. +
  109075. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE));
  109076. +
  109077. + if (buffer == kernel->virtualBufferHead)
  109078. + {
  109079. + if ((kernel->virtualBufferHead = buffer->next) == gcvNULL)
  109080. + {
  109081. + kernel->virtualBufferTail = gcvNULL;
  109082. + }
  109083. + }
  109084. + else
  109085. + {
  109086. + buffer->prev->next = buffer->next;
  109087. +
  109088. + if (buffer == kernel->virtualBufferTail)
  109089. + {
  109090. + kernel->virtualBufferTail = buffer->prev;
  109091. + }
  109092. + else
  109093. + {
  109094. + buffer->next->prev = buffer->prev;
  109095. + }
  109096. + }
  109097. +
  109098. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->virtualBufferLock));
  109099. +
  109100. + gcmkVERIFY_OK(gckOS_Free(os, buffer));
  109101. +
  109102. + gcmkFOOTER_NO();
  109103. + return gcvSTATUS_OK;
  109104. +}
  109105. +
  109106. +gceSTATUS
  109107. +gckKERNEL_GetGPUAddress(
  109108. + IN gckKERNEL Kernel,
  109109. + IN gctPOINTER Logical,
  109110. + OUT gctUINT32 * Address
  109111. + )
  109112. +{
  109113. + gceSTATUS status;
  109114. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  109115. + gctPOINTER start;
  109116. + gctINT pid;
  109117. +
  109118. + gcmkHEADER_ARG("Logical = %x", Logical);
  109119. +
  109120. + gckOS_GetProcessID(&pid);
  109121. +
  109122. + status = gcvSTATUS_INVALID_ADDRESS;
  109123. +
  109124. + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
  109125. +
  109126. + /* Walk all command buffer. */
  109127. + for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
  109128. + {
  109129. + if (buffer->userLogical)
  109130. + {
  109131. + start = buffer->userLogical;
  109132. + }
  109133. + else
  109134. + {
  109135. + start = buffer->kernelLogical;
  109136. + }
  109137. +
  109138. + if (Logical >= start
  109139. + && (Logical < (start + buffer->pageCount * 4096))
  109140. + && pid == buffer->pid
  109141. + )
  109142. + {
  109143. + * Address = buffer->gpuAddress + (Logical - start);
  109144. + status = gcvSTATUS_OK;
  109145. + break;
  109146. + }
  109147. + }
  109148. +
  109149. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
  109150. +
  109151. + gcmkFOOTER_NO();
  109152. + return status;
  109153. +}
  109154. +
  109155. +gceSTATUS
  109156. +gckKERNEL_QueryGPUAddress(
  109157. + IN gckKERNEL Kernel,
  109158. + IN gctUINT32 GpuAddress,
  109159. + OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
  109160. + )
  109161. +{
  109162. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  109163. + gctUINT32 start;
  109164. + gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
  109165. +
  109166. + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
  109167. +
  109168. + /* Walk all command buffers. */
  109169. + for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
  109170. + {
  109171. + start = (gctUINT32)buffer->gpuAddress;
  109172. +
  109173. + if (GpuAddress >= start && GpuAddress < (start + buffer->pageCount * 4096))
  109174. + {
  109175. + /* Find a range matched. */
  109176. + *Buffer = buffer;
  109177. + status = gcvSTATUS_OK;
  109178. + break;
  109179. + }
  109180. + }
  109181. +
  109182. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
  109183. +
  109184. + return status;
  109185. +}
  109186. +#endif
  109187. +
  109188. +#if gcdLINK_QUEUE_SIZE
  109189. +static void
  109190. +gckLINKQUEUE_Dequeue(
  109191. + IN gckLINKQUEUE LinkQueue
  109192. + )
  109193. +{
  109194. + gcmkASSERT(LinkQueue->count == gcdLINK_QUEUE_SIZE);
  109195. +
  109196. + LinkQueue->count--;
  109197. + LinkQueue->front = (LinkQueue->front + 1) % gcdLINK_QUEUE_SIZE;
  109198. +}
  109199. +
  109200. +void
  109201. +gckLINKQUEUE_Enqueue(
  109202. + IN gckLINKQUEUE LinkQueue,
  109203. + IN gctUINT32 start,
  109204. + IN gctUINT32 end
  109205. + )
  109206. +{
  109207. + if (LinkQueue->count == gcdLINK_QUEUE_SIZE)
  109208. + {
  109209. + gckLINKQUEUE_Dequeue(LinkQueue);
  109210. + }
  109211. +
  109212. + gcmkASSERT(LinkQueue->count < gcdLINK_QUEUE_SIZE);
  109213. +
  109214. + LinkQueue->count++;
  109215. +
  109216. + LinkQueue->data[LinkQueue->rear].start = start;
  109217. + LinkQueue->data[LinkQueue->rear].end = end;
  109218. +
  109219. + gcmkVERIFY_OK(
  109220. + gckOS_GetProcessID(&LinkQueue->data[LinkQueue->rear].pid));
  109221. +
  109222. + LinkQueue->rear = (LinkQueue->rear + 1) % gcdLINK_QUEUE_SIZE;
  109223. +}
  109224. +
  109225. +void
  109226. +gckLINKQUEUE_GetData(
  109227. + IN gckLINKQUEUE LinkQueue,
  109228. + IN gctUINT32 Index,
  109229. + OUT gckLINKDATA * Data
  109230. + )
  109231. +{
  109232. + gcmkASSERT(Index >= 0 && Index < gcdLINK_QUEUE_SIZE);
  109233. +
  109234. + *Data = &LinkQueue->data[(Index + LinkQueue->front) % gcdLINK_QUEUE_SIZE];
  109235. +}
  109236. +#endif
  109237. +
  109238. +/******************************************************************************\
  109239. +*************************** Pointer - ID translation ***************************
  109240. +\******************************************************************************/
  109241. +#define gcdID_TABLE_LENGTH 1024
  109242. +typedef struct _gcsINTEGERDB * gckINTEGERDB;
  109243. +typedef struct _gcsINTEGERDB
  109244. +{
  109245. + gckOS os;
  109246. + gctPOINTER* table;
  109247. + gctPOINTER mutex;
  109248. + gctUINT32 tableLen;
  109249. + gctUINT32 currentID;
  109250. + gctUINT32 unused;
  109251. +}
  109252. +gcsINTEGERDB;
  109253. +
  109254. +gceSTATUS
  109255. +gckKERNEL_CreateIntegerDatabase(
  109256. + IN gckKERNEL Kernel,
  109257. + OUT gctPOINTER * Database
  109258. + )
  109259. +{
  109260. + gceSTATUS status;
  109261. + gckINTEGERDB database = gcvNULL;
  109262. +
  109263. + gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
  109264. +
  109265. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  109266. + gcmkVERIFY_ARGUMENT(Database != gcvNULL);
  109267. +
  109268. + /* Allocate a database. */
  109269. + gcmkONERROR(gckOS_Allocate(
  109270. + Kernel->os, gcmSIZEOF(gcsINTEGERDB), (gctPOINTER *)&database));
  109271. +
  109272. + gckOS_ZeroMemory(database, gcmSIZEOF(gcsINTEGERDB));
  109273. +
  109274. + /* Allocate a pointer table. */
  109275. + gcmkONERROR(gckOS_Allocate(
  109276. + Kernel->os, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH, (gctPOINTER *)&database->table));
  109277. +
  109278. + gckOS_ZeroMemory(database->table, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH);
  109279. +
  109280. + /* Allocate a database mutex. */
  109281. + gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->mutex));
  109282. +
  109283. + /* Initialize. */
  109284. + database->currentID = 0;
  109285. + database->unused = gcdID_TABLE_LENGTH;
  109286. + database->os = Kernel->os;
  109287. + database->tableLen = gcdID_TABLE_LENGTH;
  109288. +
  109289. + *Database = database;
  109290. +
  109291. + gcmkFOOTER_ARG("*Database=0x%08X", *Database);
  109292. + return gcvSTATUS_OK;
  109293. +
  109294. +OnError:
  109295. + /* Rollback. */
  109296. + if (database)
  109297. + {
  109298. + if (database->table)
  109299. + {
  109300. + gcmkOS_SAFE_FREE(Kernel->os, database->table);
  109301. + }
  109302. +
  109303. + gcmkOS_SAFE_FREE(Kernel->os, database);
  109304. + }
  109305. +
  109306. + gcmkFOOTER();
  109307. + return status;
  109308. +}
  109309. +
  109310. +gceSTATUS
  109311. +gckKERNEL_DestroyIntegerDatabase(
  109312. + IN gckKERNEL Kernel,
  109313. + IN gctPOINTER Database
  109314. + )
  109315. +{
  109316. + gckINTEGERDB database = Database;
  109317. +
  109318. + gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
  109319. +
  109320. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  109321. + gcmkVERIFY_ARGUMENT(Database != gcvNULL);
  109322. +
  109323. + /* Destroy pointer table. */
  109324. + gcmkOS_SAFE_FREE(Kernel->os, database->table);
  109325. +
  109326. + /* Destroy database mutex. */
  109327. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->mutex));
  109328. +
  109329. + /* Destroy database. */
  109330. + gcmkOS_SAFE_FREE(Kernel->os, database);
  109331. +
  109332. + gcmkFOOTER_NO();
  109333. + return gcvSTATUS_OK;
  109334. +}
  109335. +
  109336. +gceSTATUS
  109337. +gckKERNEL_AllocateIntegerId(
  109338. + IN gctPOINTER Database,
  109339. + IN gctPOINTER Pointer,
  109340. + OUT gctUINT32 * Id
  109341. + )
  109342. +{
  109343. + gceSTATUS status;
  109344. + gckINTEGERDB database = Database;
  109345. + gctUINT32 i, unused, currentID, tableLen;
  109346. + gctPOINTER * table;
  109347. + gckOS os = database->os;
  109348. + gctBOOL acquired = gcvFALSE;
  109349. +
  109350. + gcmkHEADER_ARG("Database=0x%08X Pointer=0x%08X", Database, Pointer);
  109351. +
  109352. + gcmkVERIFY_ARGUMENT(Id != gcvNULL);
  109353. +
  109354. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
  109355. + acquired = gcvTRUE;
  109356. +
  109357. + if (database->unused < 1)
  109358. + {
  109359. + /* Extend table. */
  109360. + gcmkONERROR(
  109361. + gckOS_Allocate(os,
  109362. + gcmSIZEOF(gctPOINTER) * (database->tableLen + gcdID_TABLE_LENGTH),
  109363. + (gctPOINTER *)&table));
  109364. +
  109365. + gckOS_ZeroMemory(table + database->tableLen,
  109366. + gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH);
  109367. +
  109368. + /* Copy data from old table. */
  109369. + gckOS_MemCopy(table,
  109370. + database->table,
  109371. + database->tableLen * gcmSIZEOF(gctPOINTER));
  109372. +
  109373. + gcmkOS_SAFE_FREE(os, database->table);
  109374. +
  109375. + /* Update databse with new allocated table. */
  109376. + database->table = table;
  109377. + database->currentID = database->tableLen;
  109378. + database->tableLen += gcdID_TABLE_LENGTH;
  109379. + database->unused += gcdID_TABLE_LENGTH;
  109380. + }
  109381. +
  109382. + table = database->table;
  109383. + currentID = database->currentID;
  109384. + tableLen = database->tableLen;
  109385. + unused = database->unused;
  109386. +
  109387. + /* Connect id with pointer. */
  109388. + table[currentID] = Pointer;
  109389. +
  109390. + *Id = currentID + 1;
  109391. +
  109392. + /* Update the currentID. */
  109393. + if (--unused > 0)
  109394. + {
  109395. + for (i = 0; i < tableLen; i++)
  109396. + {
  109397. + if (++currentID >= tableLen)
  109398. + {
  109399. + /* Wrap to the begin. */
  109400. + currentID = 0;
  109401. + }
  109402. +
  109403. + if (table[currentID] == gcvNULL)
  109404. + {
  109405. + break;
  109406. + }
  109407. + }
  109408. + }
  109409. +
  109410. + database->table = table;
  109411. + database->currentID = currentID;
  109412. + database->tableLen = tableLen;
  109413. + database->unused = unused;
  109414. +
  109415. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109416. + acquired = gcvFALSE;
  109417. +
  109418. + gcmkFOOTER_ARG("*Id=%d", *Id);
  109419. + return gcvSTATUS_OK;
  109420. +
  109421. +OnError:
  109422. + if (acquired)
  109423. + {
  109424. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109425. + }
  109426. +
  109427. + gcmkFOOTER();
  109428. + return status;
  109429. +}
  109430. +
  109431. +gceSTATUS
  109432. +gckKERNEL_FreeIntegerId(
  109433. + IN gctPOINTER Database,
  109434. + IN gctUINT32 Id
  109435. + )
  109436. +{
  109437. + gceSTATUS status;
  109438. + gckINTEGERDB database = Database;
  109439. + gckOS os = database->os;
  109440. + gctBOOL acquired = gcvFALSE;
  109441. +
  109442. + gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
  109443. +
  109444. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
  109445. + acquired = gcvTRUE;
  109446. +
  109447. + if (!(Id > 0 && Id <= database->tableLen))
  109448. + {
  109449. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  109450. + }
  109451. +
  109452. + Id -= 1;
  109453. +
  109454. + database->table[Id] = gcvNULL;
  109455. +
  109456. + if (database->unused++ == 0)
  109457. + {
  109458. + database->currentID = Id;
  109459. + }
  109460. +
  109461. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109462. + acquired = gcvFALSE;
  109463. +
  109464. + gcmkFOOTER_NO();
  109465. + return gcvSTATUS_OK;
  109466. +
  109467. +OnError:
  109468. + if (acquired)
  109469. + {
  109470. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109471. + }
  109472. +
  109473. + gcmkFOOTER();
  109474. + return status;
  109475. +}
  109476. +
  109477. +gceSTATUS
  109478. +gckKERNEL_QueryIntegerId(
  109479. + IN gctPOINTER Database,
  109480. + IN gctUINT32 Id,
  109481. + OUT gctPOINTER * Pointer
  109482. + )
  109483. +{
  109484. + gceSTATUS status;
  109485. + gckINTEGERDB database = Database;
  109486. + gctPOINTER pointer;
  109487. + gckOS os = database->os;
  109488. + gctBOOL acquired = gcvFALSE;
  109489. +
  109490. + gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
  109491. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  109492. +
  109493. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
  109494. + acquired = gcvTRUE;
  109495. +
  109496. + if (!(Id > 0 && Id <= database->tableLen))
  109497. + {
  109498. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  109499. + }
  109500. +
  109501. + Id -= 1;
  109502. +
  109503. + pointer = database->table[Id];
  109504. +
  109505. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109506. + acquired = gcvFALSE;
  109507. +
  109508. + if (pointer)
  109509. + {
  109510. + *Pointer = pointer;
  109511. + }
  109512. + else
  109513. + {
  109514. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  109515. + }
  109516. +
  109517. + gcmkFOOTER_ARG("*Pointer=0x%08X", *Pointer);
  109518. + return gcvSTATUS_OK;
  109519. +
  109520. +OnError:
  109521. + if (acquired)
  109522. + {
  109523. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109524. + }
  109525. +
  109526. + gcmkFOOTER();
  109527. + return status;
  109528. +}
  109529. +
  109530. +
  109531. +gctUINT32
  109532. +gckKERNEL_AllocateNameFromPointer(
  109533. + IN gckKERNEL Kernel,
  109534. + IN gctPOINTER Pointer
  109535. + )
  109536. +{
  109537. + gceSTATUS status;
  109538. + gctUINT32 name;
  109539. + gctPOINTER database = Kernel->db->pointerDatabase;
  109540. +
  109541. + gcmkHEADER_ARG("Kernel=0x%X Pointer=0x%X", Kernel, Pointer);
  109542. +
  109543. + gcmkONERROR(
  109544. + gckKERNEL_AllocateIntegerId(database, Pointer, &name));
  109545. +
  109546. + gcmkFOOTER_ARG("name=%d", name);
  109547. + return name;
  109548. +
  109549. +OnError:
  109550. + gcmkFOOTER();
  109551. + return 0;
  109552. +}
  109553. +
  109554. +gctPOINTER
  109555. +gckKERNEL_QueryPointerFromName(
  109556. + IN gckKERNEL Kernel,
  109557. + IN gctUINT32 Name
  109558. + )
  109559. +{
  109560. + gceSTATUS status;
  109561. + gctPOINTER pointer = gcvNULL;
  109562. + gctPOINTER database = Kernel->db->pointerDatabase;
  109563. +
  109564. + gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name);
  109565. +
  109566. + /* Lookup in database to get pointer. */
  109567. + gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, &pointer));
  109568. +
  109569. + gcmkFOOTER_ARG("pointer=0x%X", pointer);
  109570. + return pointer;
  109571. +
  109572. +OnError:
  109573. + gcmkFOOTER();
  109574. + return gcvNULL;
  109575. +}
  109576. +
  109577. +gceSTATUS
  109578. +gckKERNEL_DeleteName(
  109579. + IN gckKERNEL Kernel,
  109580. + IN gctUINT32 Name
  109581. + )
  109582. +{
  109583. + gctPOINTER database = Kernel->db->pointerDatabase;
  109584. +
  109585. + gcmkHEADER_ARG("Kernel=0x%X Name=0x%X", Kernel, Name);
  109586. +
  109587. + /* Free name if exists. */
  109588. + gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Name));
  109589. +
  109590. + gcmkFOOTER_NO();
  109591. + return gcvSTATUS_OK;
  109592. +}
  109593. +/*******************************************************************************
  109594. +***** Test Code ****************************************************************
  109595. +*******************************************************************************/
  109596. +
  109597. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
  109598. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c 1970-01-01 01:00:00.000000000 +0100
  109599. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c 2014-08-20 19:23:53.562845855 +0200
  109600. @@ -0,0 +1,3042 @@
  109601. +/****************************************************************************
  109602. +*
  109603. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  109604. +*
  109605. +* This program is free software; you can redistribute it and/or modify
  109606. +* it under the terms of the GNU General Public License as published by
  109607. +* the Free Software Foundation; either version 2 of the license, or
  109608. +* (at your option) any later version.
  109609. +*
  109610. +* This program is distributed in the hope that it will be useful,
  109611. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  109612. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  109613. +* GNU General Public License for more details.
  109614. +*
  109615. +* You should have received a copy of the GNU General Public License
  109616. +* along with this program; if not write to the Free Software
  109617. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  109618. +*
  109619. +*****************************************************************************/
  109620. +
  109621. +
  109622. +#include "gc_hal_kernel_precomp.h"
  109623. +#include "gc_hal_kernel_context.h"
  109624. +
  109625. +#ifdef __QNXNTO__
  109626. +#include <sys/slog.h>
  109627. +#endif
  109628. +
  109629. +#define _GC_OBJ_ZONE gcvZONE_COMMAND
  109630. +
  109631. +/******************************************************************************\
  109632. +********************************* Support Code *********************************
  109633. +\******************************************************************************/
  109634. +
  109635. +/*******************************************************************************
  109636. +**
  109637. +** _NewQueue
  109638. +**
  109639. +** Allocate a new command queue.
  109640. +**
  109641. +** INPUT:
  109642. +**
  109643. +** gckCOMMAND Command
  109644. +** Pointer to an gckCOMMAND object.
  109645. +**
  109646. +** OUTPUT:
  109647. +**
  109648. +** gckCOMMAND Command
  109649. +** gckCOMMAND object has been updated with a new command queue.
  109650. +*/
  109651. +static gceSTATUS
  109652. +_NewQueue(
  109653. + IN OUT gckCOMMAND Command
  109654. + )
  109655. +{
  109656. + gceSTATUS status;
  109657. + gctINT currentIndex, newIndex;
  109658. +
  109659. + gcmkHEADER_ARG("Command=0x%x", Command);
  109660. +
  109661. + /* Switch to the next command buffer. */
  109662. + currentIndex = Command->index;
  109663. + newIndex = (currentIndex + 1) % gcdCOMMAND_QUEUES;
  109664. +
  109665. + /* Wait for availability. */
  109666. +#if gcdDUMP_COMMAND
  109667. + gcmkPRINT("@[kernel.waitsignal]");
  109668. +#endif
  109669. +
  109670. + gcmkONERROR(gckOS_WaitSignal(
  109671. + Command->os,
  109672. + Command->queues[newIndex].signal,
  109673. + gcvINFINITE
  109674. + ));
  109675. +
  109676. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  109677. + if (newIndex < currentIndex)
  109678. + {
  109679. + Command->wrapCount += 1;
  109680. +
  109681. + gcmkTRACE_ZONE_N(
  109682. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  109683. + 2 * 4,
  109684. + "%s(%d): queue array wrapped around.\n",
  109685. + __FUNCTION__, __LINE__
  109686. + );
  109687. + }
  109688. +
  109689. + gcmkTRACE_ZONE_N(
  109690. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  109691. + 3 * 4,
  109692. + "%s(%d): total queue wrap arounds %d.\n",
  109693. + __FUNCTION__, __LINE__, Command->wrapCount
  109694. + );
  109695. +
  109696. + gcmkTRACE_ZONE_N(
  109697. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  109698. + 3 * 4,
  109699. + "%s(%d): switched to queue %d.\n",
  109700. + __FUNCTION__, __LINE__, newIndex
  109701. + );
  109702. +#endif
  109703. +
  109704. + /* Update gckCOMMAND object with new command queue. */
  109705. + Command->index = newIndex;
  109706. + Command->newQueue = gcvTRUE;
  109707. + Command->logical = Command->queues[newIndex].logical;
  109708. + Command->offset = 0;
  109709. +
  109710. + gcmkONERROR(
  109711. + gckOS_GetPhysicalAddress(
  109712. + Command->os,
  109713. + Command->logical,
  109714. + (gctUINT32 *) &Command->physical
  109715. + ));
  109716. +
  109717. + if (currentIndex != -1)
  109718. + {
  109719. + /* Mark the command queue as available. */
  109720. + gcmkONERROR(gckEVENT_Signal(
  109721. + Command->kernel->eventObj,
  109722. + Command->queues[currentIndex].signal,
  109723. + gcvKERNEL_COMMAND
  109724. + ));
  109725. + }
  109726. +
  109727. + /* Success. */
  109728. + gcmkFOOTER_ARG("Command->index=%d", Command->index);
  109729. + return gcvSTATUS_OK;
  109730. +
  109731. +OnError:
  109732. + /* Return the status. */
  109733. + gcmkFOOTER();
  109734. + return status;
  109735. +}
  109736. +
  109737. +static gceSTATUS
  109738. +_IncrementCommitAtom(
  109739. + IN gckCOMMAND Command,
  109740. + IN gctBOOL Increment
  109741. + )
  109742. +{
  109743. + gceSTATUS status;
  109744. + gckHARDWARE hardware;
  109745. + gctINT32 atomValue;
  109746. + gctBOOL powerAcquired = gcvFALSE;
  109747. +
  109748. + gcmkHEADER_ARG("Command=0x%x", Command);
  109749. +
  109750. + /* Extract the gckHARDWARE and gckEVENT objects. */
  109751. + hardware = Command->kernel->hardware;
  109752. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  109753. +
  109754. + /* Grab the power mutex. */
  109755. + gcmkONERROR(gckOS_AcquireMutex(
  109756. + Command->os, hardware->powerMutex, gcvINFINITE
  109757. + ));
  109758. + powerAcquired = gcvTRUE;
  109759. +
  109760. + /* Increment the commit atom. */
  109761. + if (Increment)
  109762. + {
  109763. + gcmkONERROR(gckOS_AtomIncrement(
  109764. + Command->os, Command->atomCommit, &atomValue
  109765. + ));
  109766. + }
  109767. + else
  109768. + {
  109769. + gcmkONERROR(gckOS_AtomDecrement(
  109770. + Command->os, Command->atomCommit, &atomValue
  109771. + ));
  109772. + }
  109773. +
  109774. + /* Release the power mutex. */
  109775. + gcmkONERROR(gckOS_ReleaseMutex(
  109776. + Command->os, hardware->powerMutex
  109777. + ));
  109778. + powerAcquired = gcvFALSE;
  109779. +
  109780. + /* Success. */
  109781. + gcmkFOOTER();
  109782. + return gcvSTATUS_OK;
  109783. +
  109784. +OnError:
  109785. + if (powerAcquired)
  109786. + {
  109787. + /* Release the power mutex. */
  109788. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  109789. + Command->os, hardware->powerMutex
  109790. + ));
  109791. + }
  109792. +
  109793. + /* Return the status. */
  109794. + gcmkFOOTER();
  109795. + return status;
  109796. +}
  109797. +
  109798. +#if gcdSECURE_USER
  109799. +static gceSTATUS
  109800. +_ProcessHints(
  109801. + IN gckCOMMAND Command,
  109802. + IN gctUINT32 ProcessID,
  109803. + IN gcoCMDBUF CommandBuffer
  109804. + )
  109805. +{
  109806. + gceSTATUS status = gcvSTATUS_OK;
  109807. + gckKERNEL kernel;
  109808. + gctBOOL needCopy = gcvFALSE;
  109809. + gcskSECURE_CACHE_PTR cache;
  109810. + gctUINT8_PTR commandBufferLogical;
  109811. + gctUINT8_PTR hintedData;
  109812. + gctUINT32_PTR hintArray;
  109813. + gctUINT i, hintCount;
  109814. +
  109815. + gcmkHEADER_ARG(
  109816. + "Command=0x%08X ProcessID=%d CommandBuffer=0x%08X",
  109817. + Command, ProcessID, CommandBuffer
  109818. + );
  109819. +
  109820. + /* Verify the arguments. */
  109821. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  109822. +
  109823. + /* Reset state array pointer. */
  109824. + hintArray = gcvNULL;
  109825. +
  109826. + /* Get the kernel object. */
  109827. + kernel = Command->kernel;
  109828. +
  109829. + /* Get the cache form the database. */
  109830. + gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
  109831. +
  109832. + /* Determine the start of the command buffer. */
  109833. + commandBufferLogical
  109834. + = (gctUINT8_PTR) CommandBuffer->logical
  109835. + + CommandBuffer->startOffset;
  109836. +
  109837. + /* Determine the number of records in the state array. */
  109838. + hintCount = CommandBuffer->hintArrayTail - CommandBuffer->hintArray;
  109839. +
  109840. + /* Check wehther we need to copy the structures or not. */
  109841. + gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
  109842. +
  109843. + /* Get access to the state array. */
  109844. + if (needCopy)
  109845. + {
  109846. + gctUINT copySize;
  109847. +
  109848. + if (Command->hintArrayAllocated &&
  109849. + (Command->hintArraySize < CommandBuffer->hintArraySize))
  109850. + {
  109851. + gcmkONERROR(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
  109852. + Command->hintArraySize = gcvFALSE;
  109853. + }
  109854. +
  109855. + if (!Command->hintArrayAllocated)
  109856. + {
  109857. + gctPOINTER pointer = gcvNULL;
  109858. +
  109859. + gcmkONERROR(gckOS_Allocate(
  109860. + Command->os,
  109861. + CommandBuffer->hintArraySize,
  109862. + &pointer
  109863. + ));
  109864. +
  109865. + Command->hintArray = gcmPTR_TO_UINT64(pointer);
  109866. + Command->hintArrayAllocated = gcvTRUE;
  109867. + Command->hintArraySize = CommandBuffer->hintArraySize;
  109868. + }
  109869. +
  109870. + hintArray = gcmUINT64_TO_PTR(Command->hintArray);
  109871. + copySize = hintCount * gcmSIZEOF(gctUINT32);
  109872. +
  109873. + gcmkONERROR(gckOS_CopyFromUserData(
  109874. + Command->os,
  109875. + hintArray,
  109876. + gcmUINT64_TO_PTR(CommandBuffer->hintArray),
  109877. + copySize
  109878. + ));
  109879. + }
  109880. + else
  109881. + {
  109882. + gctPOINTER pointer = gcvNULL;
  109883. +
  109884. + gcmkONERROR(gckOS_MapUserPointer(
  109885. + Command->os,
  109886. + gcmUINT64_TO_PTR(CommandBuffer->hintArray),
  109887. + CommandBuffer->hintArraySize,
  109888. + &pointer
  109889. + ));
  109890. +
  109891. + hintArray = pointer;
  109892. + }
  109893. +
  109894. + /* Scan through the buffer. */
  109895. + for (i = 0; i < hintCount; i += 1)
  109896. + {
  109897. + /* Determine the location of the hinted data. */
  109898. + hintedData = commandBufferLogical + hintArray[i];
  109899. +
  109900. + /* Map handle into physical address. */
  109901. + gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
  109902. + kernel, cache, (gctPOINTER) hintedData
  109903. + ));
  109904. + }
  109905. +
  109906. +OnError:
  109907. + /* Get access to the state array. */
  109908. + if (!needCopy && (hintArray != gcvNULL))
  109909. + {
  109910. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(
  109911. + Command->os,
  109912. + gcmUINT64_TO_PTR(CommandBuffer->hintArray),
  109913. + CommandBuffer->hintArraySize,
  109914. + hintArray
  109915. + ));
  109916. + }
  109917. +
  109918. + /* Return the status. */
  109919. + gcmkFOOTER();
  109920. + return status;
  109921. +}
  109922. +#endif
  109923. +
  109924. +static gceSTATUS
  109925. +_FlushMMU(
  109926. + IN gckCOMMAND Command
  109927. + )
  109928. +{
  109929. + gceSTATUS status;
  109930. + gctUINT32 oldValue;
  109931. + gckHARDWARE hardware = Command->kernel->hardware;
  109932. +
  109933. + gcmkONERROR(gckOS_AtomicExchange(Command->os,
  109934. + hardware->pageTableDirty,
  109935. + 0,
  109936. + &oldValue));
  109937. +
  109938. + if (oldValue)
  109939. + {
  109940. + /* Page Table is upated, flush mmu before commit. */
  109941. + gcmkONERROR(gckHARDWARE_FlushMMU(hardware));
  109942. + }
  109943. +
  109944. + return gcvSTATUS_OK;
  109945. +OnError:
  109946. + return status;
  109947. +}
  109948. +
  109949. +#if gcdVIRTUAL_COMMAND_BUFFER
  109950. +static void
  109951. +_DumpBuffer(
  109952. + IN gctPOINTER Buffer,
  109953. + IN gctUINT32 GpuAddress,
  109954. + IN gctSIZE_T Size
  109955. + )
  109956. +{
  109957. + gctINT i, line, left;
  109958. + gctUINT32_PTR data = Buffer;
  109959. +
  109960. + line = Size / 32;
  109961. + left = Size % 32;
  109962. +
  109963. +
  109964. + for (i = 0; i < line; i++)
  109965. + {
  109966. + gcmkPRINT("%X : %08X %08X %08X %08X %08X %08X %08X %08X ",
  109967. + GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
  109968. + data += 8;
  109969. + GpuAddress += 8 * 4;
  109970. + }
  109971. +
  109972. + switch(left)
  109973. + {
  109974. + case 28:
  109975. + gcmkPRINT("%X : %08X %08X %08X %08X %08X %08X %08X ",
  109976. + GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
  109977. + break;
  109978. + case 24:
  109979. + gcmkPRINT("%X : %08X %08X %08X %08X %08X %08X ",
  109980. + GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5]);
  109981. + break;
  109982. + case 20:
  109983. + gcmkPRINT("%X : %08X %08X %08X %08X %08X ",
  109984. + GpuAddress, data[0], data[1], data[2], data[3], data[4]);
  109985. + break;
  109986. + case 16:
  109987. + gcmkPRINT("%X : %08X %08X %08X %08X ",
  109988. + GpuAddress, data[0], data[1], data[2], data[3]);
  109989. + break;
  109990. + case 12:
  109991. + gcmkPRINT("%X : %08X %08X %08X ",
  109992. + GpuAddress, data[0], data[1], data[2]);
  109993. + break;
  109994. + case 8:
  109995. + gcmkPRINT("%X : %08X %08X ",
  109996. + GpuAddress, data[0], data[1]);
  109997. + break;
  109998. + case 4:
  109999. + gcmkPRINT("%X : %08X ",
  110000. + GpuAddress, data[0]);
  110001. + break;
  110002. + default:
  110003. + break;
  110004. + }
  110005. +}
  110006. +
  110007. +static void
  110008. +_DumpKernelCommandBuffer(
  110009. + IN gckCOMMAND Command
  110010. +)
  110011. +{
  110012. + gctINT i;
  110013. + gctUINT32 physical;
  110014. + gctPOINTER entry;
  110015. +
  110016. + for (i = 0; i < gcdCOMMAND_QUEUES; i++)
  110017. + {
  110018. + entry = Command->queues[i].logical;
  110019. +
  110020. + gckOS_GetPhysicalAddress(Command->os, entry, &physical);
  110021. +
  110022. + gcmkPRINT("Kernel command buffer %d\n", i);
  110023. +
  110024. + _DumpBuffer(entry, physical, Command->pageSize);
  110025. + }
  110026. +}
  110027. +#endif
  110028. +
  110029. +/******************************************************************************\
  110030. +****************************** gckCOMMAND API Code ******************************
  110031. +\******************************************************************************/
  110032. +
  110033. +/*******************************************************************************
  110034. +**
  110035. +** gckCOMMAND_Construct
  110036. +**
  110037. +** Construct a new gckCOMMAND object.
  110038. +**
  110039. +** INPUT:
  110040. +**
  110041. +** gckKERNEL Kernel
  110042. +** Pointer to an gckKERNEL object.
  110043. +**
  110044. +** OUTPUT:
  110045. +**
  110046. +** gckCOMMAND * Command
  110047. +** Pointer to a variable that will hold the pointer to the gckCOMMAND
  110048. +** object.
  110049. +*/
  110050. +gceSTATUS
  110051. +gckCOMMAND_Construct(
  110052. + IN gckKERNEL Kernel,
  110053. + OUT gckCOMMAND * Command
  110054. + )
  110055. +{
  110056. + gckOS os;
  110057. + gckCOMMAND command = gcvNULL;
  110058. + gceSTATUS status;
  110059. + gctINT i;
  110060. + gctPOINTER pointer = gcvNULL;
  110061. +
  110062. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  110063. +
  110064. + /* Verify the arguments. */
  110065. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  110066. + gcmkVERIFY_ARGUMENT(Command != gcvNULL);
  110067. +
  110068. + /* Extract the gckOS object. */
  110069. + os = Kernel->os;
  110070. +
  110071. + /* Allocate the gckCOMMAND structure. */
  110072. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckCOMMAND), &pointer));
  110073. + command = pointer;
  110074. +
  110075. + /* Reset the entire object. */
  110076. + gcmkONERROR(gckOS_ZeroMemory(command, gcmSIZEOF(struct _gckCOMMAND)));
  110077. +
  110078. + /* Initialize the gckCOMMAND object.*/
  110079. + command->object.type = gcvOBJ_COMMAND;
  110080. + command->kernel = Kernel;
  110081. + command->os = os;
  110082. +
  110083. + /* Get the command buffer requirements. */
  110084. + gcmkONERROR(gckHARDWARE_QueryCommandBuffer(
  110085. + Kernel->hardware,
  110086. + &command->alignment,
  110087. + &command->reservedHead,
  110088. + &command->reservedTail
  110089. + ));
  110090. +
  110091. + /* Create the command queue mutex. */
  110092. + gcmkONERROR(gckOS_CreateMutex(os, &command->mutexQueue));
  110093. +
  110094. + /* Create the context switching mutex. */
  110095. + gcmkONERROR(gckOS_CreateMutex(os, &command->mutexContext));
  110096. +
  110097. +#if VIVANTE_PROFILER_CONTEXT
  110098. + /* Create the context switching mutex. */
  110099. + gcmkONERROR(gckOS_CreateMutex(os, &command->mutexContextSeq));
  110100. +#endif
  110101. +
  110102. + /* Create the power management semaphore. */
  110103. + gcmkONERROR(gckOS_CreateSemaphore(os, &command->powerSemaphore));
  110104. +
  110105. + /* Create the commit atom. */
  110106. + gcmkONERROR(gckOS_AtomConstruct(os, &command->atomCommit));
  110107. +
  110108. + /* Get the page size from teh OS. */
  110109. + gcmkONERROR(gckOS_GetPageSize(os, &command->pageSize));
  110110. +
  110111. + /* Get process ID. */
  110112. + gcmkONERROR(gckOS_GetProcessID(&command->kernelProcessID));
  110113. +
  110114. + /* Set hardware to pipe 0. */
  110115. + command->pipeSelect = gcvPIPE_INVALID;
  110116. +
  110117. + /* Pre-allocate the command queues. */
  110118. + for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
  110119. + {
  110120. + gcmkONERROR(gckOS_AllocateNonPagedMemory(
  110121. + os,
  110122. + gcvFALSE,
  110123. + &command->pageSize,
  110124. + &command->queues[i].physical,
  110125. + &command->queues[i].logical
  110126. + ));
  110127. +
  110128. + gcmkONERROR(gckOS_CreateSignal(
  110129. + os, gcvFALSE, &command->queues[i].signal
  110130. + ));
  110131. +
  110132. + gcmkONERROR(gckOS_Signal(
  110133. + os, command->queues[i].signal, gcvTRUE
  110134. + ));
  110135. + }
  110136. +
  110137. + /* No command queue in use yet. */
  110138. + command->index = -1;
  110139. + command->logical = gcvNULL;
  110140. + command->newQueue = gcvFALSE;
  110141. +
  110142. + /* Command is not yet running. */
  110143. + command->running = gcvFALSE;
  110144. +
  110145. + /* Command queue is idle. */
  110146. + command->idle = gcvTRUE;
  110147. +
  110148. + /* Commit stamp is zero. */
  110149. + command->commitStamp = 0;
  110150. +
  110151. + /* END event signal not created. */
  110152. + command->endEventSignal = gcvNULL;
  110153. +
  110154. + /* Return pointer to the gckCOMMAND object. */
  110155. + *Command = command;
  110156. +
  110157. + /* Success. */
  110158. + gcmkFOOTER_ARG("*Command=0x%x", *Command);
  110159. + return gcvSTATUS_OK;
  110160. +
  110161. +OnError:
  110162. + /* Roll back. */
  110163. + if (command != gcvNULL)
  110164. + {
  110165. + if (command->atomCommit != gcvNULL)
  110166. + {
  110167. + gcmkVERIFY_OK(gckOS_AtomDestroy(os, command->atomCommit));
  110168. + }
  110169. +
  110170. + if (command->powerSemaphore != gcvNULL)
  110171. + {
  110172. + gcmkVERIFY_OK(gckOS_DestroySemaphore(os, command->powerSemaphore));
  110173. + }
  110174. +
  110175. + if (command->mutexContext != gcvNULL)
  110176. + {
  110177. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, command->mutexContext));
  110178. + }
  110179. +
  110180. +#if VIVANTE_PROFILER_CONTEXT
  110181. + if (command->mutexContextSeq != gcvNULL)
  110182. + {
  110183. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, command->mutexContextSeq));
  110184. + }
  110185. +#endif
  110186. +
  110187. + if (command->mutexQueue != gcvNULL)
  110188. + {
  110189. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, command->mutexQueue));
  110190. + }
  110191. +
  110192. + for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
  110193. + {
  110194. + if (command->queues[i].signal != gcvNULL)
  110195. + {
  110196. + gcmkVERIFY_OK(gckOS_DestroySignal(
  110197. + os, command->queues[i].signal
  110198. + ));
  110199. + }
  110200. +
  110201. + if (command->queues[i].logical != gcvNULL)
  110202. + {
  110203. + gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
  110204. + os,
  110205. + command->pageSize,
  110206. + command->queues[i].physical,
  110207. + command->queues[i].logical
  110208. + ));
  110209. + }
  110210. + }
  110211. +
  110212. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, command));
  110213. + }
  110214. +
  110215. + /* Return the status. */
  110216. + gcmkFOOTER();
  110217. + return status;
  110218. +}
  110219. +
  110220. +/*******************************************************************************
  110221. +**
  110222. +** gckCOMMAND_Destroy
  110223. +**
  110224. +** Destroy an gckCOMMAND object.
  110225. +**
  110226. +** INPUT:
  110227. +**
  110228. +** gckCOMMAND Command
  110229. +** Pointer to an gckCOMMAND object to destroy.
  110230. +**
  110231. +** OUTPUT:
  110232. +**
  110233. +** Nothing.
  110234. +*/
  110235. +gceSTATUS
  110236. +gckCOMMAND_Destroy(
  110237. + IN gckCOMMAND Command
  110238. + )
  110239. +{
  110240. + gctINT i;
  110241. +
  110242. + gcmkHEADER_ARG("Command=0x%x", Command);
  110243. +
  110244. + /* Verify the arguments. */
  110245. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  110246. +
  110247. + /* Stop the command queue. */
  110248. + gcmkVERIFY_OK(gckCOMMAND_Stop(Command, gcvFALSE));
  110249. +
  110250. + for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
  110251. + {
  110252. + gcmkASSERT(Command->queues[i].signal != gcvNULL);
  110253. + gcmkVERIFY_OK(gckOS_DestroySignal(
  110254. + Command->os, Command->queues[i].signal
  110255. + ));
  110256. +
  110257. + gcmkASSERT(Command->queues[i].logical != gcvNULL);
  110258. + gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
  110259. + Command->os,
  110260. + Command->pageSize,
  110261. + Command->queues[i].physical,
  110262. + Command->queues[i].logical
  110263. + ));
  110264. + }
  110265. +
  110266. + /* END event signal. */
  110267. + if (Command->endEventSignal != gcvNULL)
  110268. + {
  110269. + gcmkVERIFY_OK(gckOS_DestroySignal(
  110270. + Command->os, Command->endEventSignal
  110271. + ));
  110272. + }
  110273. +
  110274. + /* Delete the context switching mutex. */
  110275. + gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexContext));
  110276. +
  110277. +#if VIVANTE_PROFILER_CONTEXT
  110278. + if (Command->mutexContextSeq != gcvNULL)
  110279. + gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexContextSeq));
  110280. +#endif
  110281. +
  110282. + /* Delete the command queue mutex. */
  110283. + gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexQueue));
  110284. +
  110285. + /* Destroy the power management semaphore. */
  110286. + gcmkVERIFY_OK(gckOS_DestroySemaphore(Command->os, Command->powerSemaphore));
  110287. +
  110288. + /* Destroy the commit atom. */
  110289. + gcmkVERIFY_OK(gckOS_AtomDestroy(Command->os, Command->atomCommit));
  110290. +
  110291. +#if gcdSECURE_USER
  110292. + /* Free state array. */
  110293. + if (Command->hintArrayAllocated)
  110294. + {
  110295. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
  110296. + Command->hintArrayAllocated = gcvFALSE;
  110297. + }
  110298. +#endif
  110299. +
  110300. + /* Mark object as unknown. */
  110301. + Command->object.type = gcvOBJ_UNKNOWN;
  110302. +
  110303. + /* Free the gckCOMMAND object. */
  110304. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Command->os, Command));
  110305. +
  110306. + /* Success. */
  110307. + gcmkFOOTER_NO();
  110308. + return gcvSTATUS_OK;
  110309. +}
  110310. +
  110311. +/*******************************************************************************
  110312. +**
  110313. +** gckCOMMAND_EnterCommit
  110314. +**
  110315. +** Acquire command queue synchronization objects.
  110316. +**
  110317. +** INPUT:
  110318. +**
  110319. +** gckCOMMAND Command
  110320. +** Pointer to an gckCOMMAND object to destroy.
  110321. +**
  110322. +** gctBOOL FromPower
  110323. +** Determines whether the call originates from inside the power
  110324. +** management or not.
  110325. +**
  110326. +** OUTPUT:
  110327. +**
  110328. +** Nothing.
  110329. +*/
  110330. +gceSTATUS
  110331. +gckCOMMAND_EnterCommit(
  110332. + IN gckCOMMAND Command,
  110333. + IN gctBOOL FromPower
  110334. + )
  110335. +{
  110336. + gceSTATUS status;
  110337. + gckHARDWARE hardware;
  110338. + gctBOOL atomIncremented = gcvFALSE;
  110339. + gctBOOL semaAcquired = gcvFALSE;
  110340. +
  110341. + gcmkHEADER_ARG("Command=0x%x", Command);
  110342. +
  110343. + /* Extract the gckHARDWARE and gckEVENT objects. */
  110344. + hardware = Command->kernel->hardware;
  110345. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  110346. +
  110347. + if (!FromPower)
  110348. + {
  110349. + /* Increment COMMIT atom to let power management know that a commit is
  110350. + ** in progress. */
  110351. + gcmkONERROR(_IncrementCommitAtom(Command, gcvTRUE));
  110352. + atomIncremented = gcvTRUE;
  110353. +
  110354. + /* Notify the system the GPU has a commit. */
  110355. + gcmkONERROR(gckOS_Broadcast(Command->os,
  110356. + hardware,
  110357. + gcvBROADCAST_GPU_COMMIT));
  110358. +
  110359. + /* Acquire the power management semaphore. */
  110360. + gcmkONERROR(gckOS_AcquireSemaphore(Command->os,
  110361. + Command->powerSemaphore));
  110362. + semaAcquired = gcvTRUE;
  110363. + }
  110364. +
  110365. + /* Grab the conmmand queue mutex. */
  110366. + gcmkONERROR(gckOS_AcquireMutex(Command->os,
  110367. + Command->mutexQueue,
  110368. + gcvINFINITE));
  110369. +
  110370. + /* Success. */
  110371. + gcmkFOOTER();
  110372. + return gcvSTATUS_OK;
  110373. +
  110374. +OnError:
  110375. + if (semaAcquired)
  110376. + {
  110377. + /* Release the power management semaphore. */
  110378. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
  110379. + Command->os, Command->powerSemaphore
  110380. + ));
  110381. + }
  110382. +
  110383. + if (atomIncremented)
  110384. + {
  110385. + /* Decrement the commit atom. */
  110386. + gcmkVERIFY_OK(_IncrementCommitAtom(
  110387. + Command, gcvFALSE
  110388. + ));
  110389. + }
  110390. +
  110391. + /* Return the status. */
  110392. + gcmkFOOTER();
  110393. + return status;
  110394. +}
  110395. +
  110396. +/*******************************************************************************
  110397. +**
  110398. +** gckCOMMAND_ExitCommit
  110399. +**
  110400. +** Release command queue synchronization objects.
  110401. +**
  110402. +** INPUT:
  110403. +**
  110404. +** gckCOMMAND Command
  110405. +** Pointer to an gckCOMMAND object to destroy.
  110406. +**
  110407. +** gctBOOL FromPower
  110408. +** Determines whether the call originates from inside the power
  110409. +** management or not.
  110410. +**
  110411. +** OUTPUT:
  110412. +**
  110413. +** Nothing.
  110414. +*/
  110415. +gceSTATUS
  110416. +gckCOMMAND_ExitCommit(
  110417. + IN gckCOMMAND Command,
  110418. + IN gctBOOL FromPower
  110419. + )
  110420. +{
  110421. + gceSTATUS status;
  110422. +
  110423. + gcmkHEADER_ARG("Command=0x%x", Command);
  110424. +
  110425. + /* Release the power mutex. */
  110426. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexQueue));
  110427. +
  110428. + if (!FromPower)
  110429. + {
  110430. + /* Release the power management semaphore. */
  110431. + gcmkONERROR(gckOS_ReleaseSemaphore(Command->os,
  110432. + Command->powerSemaphore));
  110433. +
  110434. + /* Decrement the commit atom. */
  110435. + gcmkONERROR(_IncrementCommitAtom(Command, gcvFALSE));
  110436. + }
  110437. +
  110438. + /* Success. */
  110439. + gcmkFOOTER();
  110440. + return gcvSTATUS_OK;
  110441. +
  110442. +OnError:
  110443. + /* Return the status. */
  110444. + gcmkFOOTER();
  110445. + return status;
  110446. +}
  110447. +
  110448. +/*******************************************************************************
  110449. +**
  110450. +** gckCOMMAND_Start
  110451. +**
  110452. +** Start up the command queue.
  110453. +**
  110454. +** INPUT:
  110455. +**
  110456. +** gckCOMMAND Command
  110457. +** Pointer to an gckCOMMAND object to start.
  110458. +**
  110459. +** OUTPUT:
  110460. +**
  110461. +** Nothing.
  110462. +*/
  110463. +gceSTATUS
  110464. +gckCOMMAND_Start(
  110465. + IN gckCOMMAND Command
  110466. + )
  110467. +{
  110468. + gceSTATUS status;
  110469. + gckHARDWARE hardware;
  110470. + gctUINT32 waitOffset;
  110471. + gctSIZE_T waitLinkBytes;
  110472. +
  110473. + gcmkHEADER_ARG("Command=0x%x", Command);
  110474. +
  110475. + /* Verify the arguments. */
  110476. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  110477. +
  110478. + if (Command->running)
  110479. + {
  110480. + /* Command queue already running. */
  110481. + gcmkFOOTER_NO();
  110482. + return gcvSTATUS_OK;
  110483. + }
  110484. +
  110485. + /* Extract the gckHARDWARE object. */
  110486. + hardware = Command->kernel->hardware;
  110487. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  110488. +
  110489. + if (Command->logical == gcvNULL)
  110490. + {
  110491. + /* Start at beginning of a new queue. */
  110492. + gcmkONERROR(_NewQueue(Command));
  110493. + }
  110494. +
  110495. + /* Start at beginning of page. */
  110496. + Command->offset = 0;
  110497. +
  110498. + /* Set abvailable number of bytes for WAIT/LINK command sequence. */
  110499. + waitLinkBytes = Command->pageSize;
  110500. +
  110501. + /* Append WAIT/LINK. */
  110502. + gcmkONERROR(gckHARDWARE_WaitLink(
  110503. + hardware,
  110504. + Command->logical,
  110505. + 0,
  110506. + &waitLinkBytes,
  110507. + &waitOffset,
  110508. + &Command->waitSize
  110509. + ));
  110510. +
  110511. + Command->waitLogical = (gctUINT8_PTR) Command->logical + waitOffset;
  110512. + Command->waitPhysical = (gctUINT8_PTR) Command->physical + waitOffset;
  110513. +
  110514. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110515. + /* Flush the cache for the wait/link. */
  110516. + gcmkONERROR(gckOS_CacheClean(
  110517. + Command->os,
  110518. + Command->kernelProcessID,
  110519. + gcvNULL,
  110520. + Command->physical,
  110521. + Command->logical,
  110522. + waitLinkBytes
  110523. + ));
  110524. +#endif
  110525. +
  110526. + /* Adjust offset. */
  110527. + Command->offset = waitLinkBytes;
  110528. + Command->newQueue = gcvFALSE;
  110529. +
  110530. + /* Enable command processor. */
  110531. +#ifdef __QNXNTO__
  110532. + gcmkONERROR(gckHARDWARE_Execute(
  110533. + hardware,
  110534. + Command->logical,
  110535. + Command->physical,
  110536. + gcvTRUE,
  110537. + waitLinkBytes
  110538. + ));
  110539. +#else
  110540. + gcmkONERROR(gckHARDWARE_Execute(
  110541. + hardware,
  110542. + Command->logical,
  110543. + waitLinkBytes
  110544. + ));
  110545. +#endif
  110546. +
  110547. + /* Command queue is running. */
  110548. + Command->running = gcvTRUE;
  110549. +
  110550. + /* Success. */
  110551. + gcmkFOOTER_NO();
  110552. + return gcvSTATUS_OK;
  110553. +
  110554. +OnError:
  110555. + /* Return the status. */
  110556. + gcmkFOOTER();
  110557. + return status;
  110558. +}
  110559. +
  110560. +/*******************************************************************************
  110561. +**
  110562. +** gckCOMMAND_Stop
  110563. +**
  110564. +** Stop the command queue.
  110565. +**
  110566. +** INPUT:
  110567. +**
  110568. +** gckCOMMAND Command
  110569. +** Pointer to an gckCOMMAND object to stop.
  110570. +**
  110571. +** OUTPUT:
  110572. +**
  110573. +** Nothing.
  110574. +*/
  110575. +gceSTATUS
  110576. +gckCOMMAND_Stop(
  110577. + IN gckCOMMAND Command,
  110578. + IN gctBOOL FromRecovery
  110579. + )
  110580. +{
  110581. + gckHARDWARE hardware;
  110582. + gceSTATUS status;
  110583. + gctUINT32 idle;
  110584. +
  110585. + gcmkHEADER_ARG("Command=0x%x", Command);
  110586. +
  110587. + /* Verify the arguments. */
  110588. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  110589. +
  110590. + if (!Command->running)
  110591. + {
  110592. + /* Command queue is not running. */
  110593. + gcmkFOOTER_NO();
  110594. + return gcvSTATUS_OK;
  110595. + }
  110596. +
  110597. + /* Extract the gckHARDWARE object. */
  110598. + hardware = Command->kernel->hardware;
  110599. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  110600. +
  110601. + if (gckHARDWARE_IsFeatureAvailable(hardware,
  110602. + gcvFEATURE_END_EVENT) == gcvSTATUS_TRUE)
  110603. + {
  110604. + /* Allocate the signal. */
  110605. + if (Command->endEventSignal == gcvNULL)
  110606. + {
  110607. + gcmkONERROR(gckOS_CreateSignal(Command->os,
  110608. + gcvTRUE,
  110609. + &Command->endEventSignal));
  110610. + }
  110611. +
  110612. + /* Append the END EVENT command to trigger the signal. */
  110613. + gcmkONERROR(gckEVENT_Stop(Command->kernel->eventObj,
  110614. + Command->kernelProcessID,
  110615. + Command->waitPhysical,
  110616. + Command->waitLogical,
  110617. + Command->endEventSignal,
  110618. + &Command->waitSize));
  110619. + }
  110620. + else
  110621. + {
  110622. + /* Replace last WAIT with END. */
  110623. + gcmkONERROR(gckHARDWARE_End(
  110624. + hardware, Command->waitLogical, &Command->waitSize
  110625. + ));
  110626. +
  110627. + /* Update queue tail pointer. */
  110628. + gcmkONERROR(gckHARDWARE_UpdateQueueTail(Command->kernel->hardware,
  110629. + Command->logical,
  110630. + Command->offset));
  110631. +
  110632. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110633. + /* Flush the cache for the END. */
  110634. + gcmkONERROR(gckOS_CacheClean(
  110635. + Command->os,
  110636. + Command->kernelProcessID,
  110637. + gcvNULL,
  110638. + Command->waitPhysical,
  110639. + Command->waitLogical,
  110640. + Command->waitSize
  110641. + ));
  110642. +#endif
  110643. +
  110644. + /* Wait for idle. */
  110645. + gcmkONERROR(gckHARDWARE_GetIdle(hardware, !FromRecovery, &idle));
  110646. + }
  110647. +
  110648. + /* Command queue is no longer running. */
  110649. + Command->running = gcvFALSE;
  110650. +
  110651. + /* Success. */
  110652. + gcmkFOOTER_NO();
  110653. + return gcvSTATUS_OK;
  110654. +
  110655. +OnError:
  110656. + /* Return the status. */
  110657. + gcmkFOOTER();
  110658. + return status;
  110659. +}
  110660. +
  110661. +/*******************************************************************************
  110662. +**
  110663. +** gckCOMMAND_Commit
  110664. +**
  110665. +** Commit a command buffer to the command queue.
  110666. +**
  110667. +** INPUT:
  110668. +**
  110669. +** gckCOMMAND Command
  110670. +** Pointer to a gckCOMMAND object.
  110671. +**
  110672. +** gckCONTEXT Context
  110673. +** Pointer to a gckCONTEXT object.
  110674. +**
  110675. +** gcoCMDBUF CommandBuffer
  110676. +** Pointer to a gcoCMDBUF object.
  110677. +**
  110678. +** gcsSTATE_DELTA_PTR StateDelta
  110679. +** Pointer to the state delta.
  110680. +**
  110681. +** gctUINT32 ProcessID
  110682. +** Current process ID.
  110683. +**
  110684. +** OUTPUT:
  110685. +**
  110686. +** Nothing.
  110687. +*/
  110688. +gceSTATUS
  110689. +gckCOMMAND_Commit(
  110690. + IN gckCOMMAND Command,
  110691. + IN gckCONTEXT Context,
  110692. + IN gcoCMDBUF CommandBuffer,
  110693. + IN gcsSTATE_DELTA_PTR StateDelta,
  110694. + IN gcsQUEUE_PTR EventQueue,
  110695. + IN gctUINT32 ProcessID
  110696. + )
  110697. +{
  110698. + gceSTATUS status;
  110699. + gctBOOL commitEntered = gcvFALSE;
  110700. + gctBOOL contextAcquired = gcvFALSE;
  110701. + gckHARDWARE hardware;
  110702. + gctBOOL needCopy = gcvFALSE;
  110703. + gcsQUEUE_PTR eventRecord = gcvNULL;
  110704. + gcsQUEUE _eventRecord;
  110705. + gcsQUEUE_PTR nextEventRecord;
  110706. + gctBOOL commandBufferMapped = gcvFALSE;
  110707. + gcoCMDBUF commandBufferObject = gcvNULL;
  110708. +
  110709. +#if !gcdNULL_DRIVER
  110710. + gcsCONTEXT_PTR contextBuffer;
  110711. + struct _gcoCMDBUF _commandBufferObject;
  110712. + gctPHYS_ADDR commandBufferPhysical;
  110713. + gctUINT8_PTR commandBufferLogical;
  110714. + gctUINT8_PTR commandBufferLink;
  110715. + gctUINT commandBufferSize;
  110716. + gctSIZE_T nopBytes;
  110717. + gctSIZE_T pipeBytes;
  110718. + gctSIZE_T linkBytes;
  110719. + gctSIZE_T bytes;
  110720. + gctUINT32 offset;
  110721. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110722. + gctPHYS_ADDR entryPhysical;
  110723. +#endif
  110724. + gctPOINTER entryLogical;
  110725. + gctSIZE_T entryBytes;
  110726. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110727. + gctPHYS_ADDR exitPhysical;
  110728. +#endif
  110729. + gctPOINTER exitLogical;
  110730. + gctSIZE_T exitBytes;
  110731. + gctPHYS_ADDR waitLinkPhysical;
  110732. + gctPOINTER waitLinkLogical;
  110733. + gctSIZE_T waitLinkBytes;
  110734. + gctPHYS_ADDR waitPhysical;
  110735. + gctPOINTER waitLogical;
  110736. + gctUINT32 waitOffset;
  110737. + gctSIZE_T waitSize;
  110738. +
  110739. +#if gcdDUMP_COMMAND
  110740. + gctPOINTER contextDumpLogical = gcvNULL;
  110741. + gctSIZE_T contextDumpBytes = 0;
  110742. + gctPOINTER bufferDumpLogical = gcvNULL;
  110743. + gctSIZE_T bufferDumpBytes = 0;
  110744. +# endif
  110745. +#endif
  110746. +
  110747. +#if VIVANTE_PROFILER_CONTEXT
  110748. + gctBOOL sequenceAcquired = gcvFALSE;
  110749. +#endif
  110750. +
  110751. + gctPOINTER pointer = gcvNULL;
  110752. +
  110753. + gcmkHEADER_ARG(
  110754. + "Command=0x%x CommandBuffer=0x%x ProcessID=%d",
  110755. + Command, CommandBuffer, ProcessID
  110756. + );
  110757. +
  110758. + /* Verify the arguments. */
  110759. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  110760. +
  110761. + if (Command->kernel->core == gcvCORE_2D)
  110762. + {
  110763. + /* There is no context for 2D. */
  110764. + Context = gcvNULL;
  110765. + }
  110766. +
  110767. + gcmkONERROR(_FlushMMU(Command));
  110768. +
  110769. +#if VIVANTE_PROFILER_CONTEXT
  110770. + if((Command->kernel->hardware->gpuProfiler) && (Command->kernel->profileEnable))
  110771. + {
  110772. + /* Acquire the context sequnence mutex. */
  110773. + gcmkONERROR(gckOS_AcquireMutex(
  110774. + Command->os, Command->mutexContextSeq, gcvINFINITE
  110775. + ));
  110776. + sequenceAcquired = gcvTRUE;
  110777. + }
  110778. +#endif
  110779. +
  110780. + /* Acquire the command queue. */
  110781. + gcmkONERROR(gckCOMMAND_EnterCommit(Command, gcvFALSE));
  110782. + commitEntered = gcvTRUE;
  110783. +
  110784. + /* Acquire the context switching mutex. */
  110785. + gcmkONERROR(gckOS_AcquireMutex(
  110786. + Command->os, Command->mutexContext, gcvINFINITE
  110787. + ));
  110788. + contextAcquired = gcvTRUE;
  110789. +
  110790. + /* Extract the gckHARDWARE and gckEVENT objects. */
  110791. + hardware = Command->kernel->hardware;
  110792. +
  110793. + /* Check wehther we need to copy the structures or not. */
  110794. + gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
  110795. +
  110796. +#if gcdNULL_DRIVER
  110797. + /* Context switch required? */
  110798. + if ((Context != gcvNULL) && (Command->currContext != Context))
  110799. + {
  110800. + /* Yes, merge in the deltas. */
  110801. + gckCONTEXT_Update(Context, ProcessID, StateDelta);
  110802. +
  110803. + /* Update the current context. */
  110804. + Command->currContext = Context;
  110805. + }
  110806. +#else
  110807. + if (needCopy)
  110808. + {
  110809. + commandBufferObject = &_commandBufferObject;
  110810. +
  110811. + gcmkONERROR(gckOS_CopyFromUserData(
  110812. + Command->os,
  110813. + commandBufferObject,
  110814. + CommandBuffer,
  110815. + gcmSIZEOF(struct _gcoCMDBUF)
  110816. + ));
  110817. +
  110818. + gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
  110819. + }
  110820. + else
  110821. + {
  110822. + gcmkONERROR(gckOS_MapUserPointer(
  110823. + Command->os,
  110824. + CommandBuffer,
  110825. + gcmSIZEOF(struct _gcoCMDBUF),
  110826. + &pointer
  110827. + ));
  110828. +
  110829. + commandBufferObject = pointer;
  110830. +
  110831. + gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
  110832. + commandBufferMapped = gcvTRUE;
  110833. + }
  110834. +
  110835. + /* Query the size of NOP command. */
  110836. + gcmkONERROR(gckHARDWARE_Nop(
  110837. + hardware, gcvNULL, &nopBytes
  110838. + ));
  110839. +
  110840. + /* Query the size of pipe select command sequence. */
  110841. + gcmkONERROR(gckHARDWARE_PipeSelect(
  110842. + hardware, gcvNULL, gcvPIPE_3D, &pipeBytes
  110843. + ));
  110844. +
  110845. + /* Query the size of LINK command. */
  110846. + gcmkONERROR(gckHARDWARE_Link(
  110847. + hardware, gcvNULL, gcvNULL, 0, &linkBytes
  110848. + ));
  110849. +
  110850. + /* Compute the command buffer entry and the size. */
  110851. + commandBufferLogical
  110852. + = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
  110853. + + commandBufferObject->startOffset;
  110854. +
  110855. + gcmkONERROR(gckOS_GetPhysicalAddress(
  110856. + Command->os,
  110857. + commandBufferLogical,
  110858. + (gctUINT32_PTR)&commandBufferPhysical
  110859. + ));
  110860. +
  110861. + commandBufferSize
  110862. + = commandBufferObject->offset
  110863. + + Command->reservedTail
  110864. + - commandBufferObject->startOffset;
  110865. +
  110866. + /* Get the current offset. */
  110867. + offset = Command->offset;
  110868. +
  110869. + /* Compute number of bytes left in current kernel command queue. */
  110870. + bytes = Command->pageSize - offset;
  110871. +
  110872. + /* Query the size of WAIT/LINK command sequence. */
  110873. + gcmkONERROR(gckHARDWARE_WaitLink(
  110874. + hardware,
  110875. + gcvNULL,
  110876. + offset,
  110877. + &waitLinkBytes,
  110878. + gcvNULL,
  110879. + gcvNULL
  110880. + ));
  110881. +
  110882. + /* Is there enough space in the current command queue? */
  110883. + if (bytes < waitLinkBytes)
  110884. + {
  110885. + /* No, create a new one. */
  110886. + gcmkONERROR(_NewQueue(Command));
  110887. +
  110888. + /* Get the new current offset. */
  110889. + offset = Command->offset;
  110890. +
  110891. + /* Recompute the number of bytes in the new kernel command queue. */
  110892. + bytes = Command->pageSize - offset;
  110893. + gcmkASSERT(bytes >= waitLinkBytes);
  110894. + }
  110895. +
  110896. + /* Compute the location if WAIT/LINK command sequence. */
  110897. + waitLinkPhysical = (gctUINT8_PTR) Command->physical + offset;
  110898. + waitLinkLogical = (gctUINT8_PTR) Command->logical + offset;
  110899. +
  110900. + /* Context switch required? */
  110901. + if (Context == gcvNULL)
  110902. + {
  110903. + /* See if we have to switch pipes for the command buffer. */
  110904. + if (commandBufferObject->entryPipe == Command->pipeSelect)
  110905. + {
  110906. + /* Skip pipe switching sequence. */
  110907. + offset = pipeBytes;
  110908. + }
  110909. + else
  110910. + {
  110911. + /* The current hardware and the entry command buffer pipes
  110912. + ** are different, switch to the correct pipe. */
  110913. + gcmkONERROR(gckHARDWARE_PipeSelect(
  110914. + Command->kernel->hardware,
  110915. + commandBufferLogical,
  110916. + commandBufferObject->entryPipe,
  110917. + &pipeBytes
  110918. + ));
  110919. +
  110920. + /* Do not skip pipe switching sequence. */
  110921. + offset = 0;
  110922. + }
  110923. +
  110924. + /* Compute the entry. */
  110925. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110926. + entryPhysical = (gctUINT8_PTR) commandBufferPhysical + offset;
  110927. +#endif
  110928. + entryLogical = commandBufferLogical + offset;
  110929. + entryBytes = commandBufferSize - offset;
  110930. + }
  110931. + else if (Command->currContext != Context)
  110932. + {
  110933. + /* Temporary disable context length oprimization. */
  110934. + Context->dirty = gcvTRUE;
  110935. +
  110936. + /* Get the current context buffer. */
  110937. + contextBuffer = Context->buffer;
  110938. +
  110939. + /* Yes, merge in the deltas. */
  110940. + gcmkONERROR(gckCONTEXT_Update(Context, ProcessID, StateDelta));
  110941. +
  110942. + /* Determine context entry and exit points. */
  110943. + if (0)
  110944. + {
  110945. + /* Reset 2D dirty flag. */
  110946. + Context->dirty2D = gcvFALSE;
  110947. +
  110948. + if (Context->dirty || commandBufferObject->using3D)
  110949. + {
  110950. + /***************************************************************
  110951. + ** SWITCHING CONTEXT: 2D and 3D are used.
  110952. + */
  110953. +
  110954. + /* Reset 3D dirty flag. */
  110955. + Context->dirty3D = gcvFALSE;
  110956. +
  110957. + /* Compute the entry. */
  110958. + if (Command->pipeSelect == gcvPIPE_2D)
  110959. + {
  110960. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110961. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  110962. +#endif
  110963. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  110964. + entryBytes = Context->bufferSize - pipeBytes;
  110965. + }
  110966. + else
  110967. + {
  110968. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110969. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  110970. +#endif
  110971. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  110972. + entryBytes = Context->bufferSize;
  110973. + }
  110974. +
  110975. + /* See if we have to switch pipes between the context
  110976. + and command buffers. */
  110977. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  110978. + {
  110979. + /* Skip pipe switching sequence. */
  110980. + offset = pipeBytes;
  110981. + }
  110982. + else
  110983. + {
  110984. + /* The current hardware and the initial context pipes are
  110985. + different, switch to the correct pipe. */
  110986. + gcmkONERROR(gckHARDWARE_PipeSelect(
  110987. + Command->kernel->hardware,
  110988. + commandBufferLogical,
  110989. + commandBufferObject->entryPipe,
  110990. + &pipeBytes
  110991. + ));
  110992. +
  110993. + /* Do not skip pipe switching sequence. */
  110994. + offset = 0;
  110995. + }
  110996. +
  110997. + /* Ensure the NOP between 2D and 3D is in place so that the
  110998. + execution falls through from 2D to 3D. */
  110999. + gcmkONERROR(gckHARDWARE_Nop(
  111000. + hardware,
  111001. + contextBuffer->link2D,
  111002. + &nopBytes
  111003. + ));
  111004. +
  111005. + /* Generate a LINK from the context buffer to
  111006. + the command buffer. */
  111007. + gcmkONERROR(gckHARDWARE_Link(
  111008. + hardware,
  111009. + contextBuffer->link3D,
  111010. + commandBufferLogical + offset,
  111011. + commandBufferSize - offset,
  111012. + &linkBytes
  111013. + ));
  111014. +
  111015. + /* Mark context as not dirty. */
  111016. + Context->dirty = gcvFALSE;
  111017. + }
  111018. + else
  111019. + {
  111020. + /***************************************************************
  111021. + ** SWITCHING CONTEXT: 2D only command buffer.
  111022. + */
  111023. +
  111024. + /* Mark 3D as dirty. */
  111025. + Context->dirty3D = gcvTRUE;
  111026. +
  111027. + /* Compute the entry. */
  111028. + if (Command->pipeSelect == gcvPIPE_2D)
  111029. + {
  111030. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111031. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  111032. +#endif
  111033. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  111034. + entryBytes = Context->entryOffset3D - pipeBytes;
  111035. + }
  111036. + else
  111037. + {
  111038. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111039. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  111040. +#endif
  111041. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  111042. + entryBytes = Context->entryOffset3D;
  111043. + }
  111044. +
  111045. + /* Store the current context buffer. */
  111046. + Context->dirtyBuffer = contextBuffer;
  111047. +
  111048. + /* See if we have to switch pipes between the context
  111049. + and command buffers. */
  111050. + if (commandBufferObject->entryPipe == gcvPIPE_2D)
  111051. + {
  111052. + /* Skip pipe switching sequence. */
  111053. + offset = pipeBytes;
  111054. + }
  111055. + else
  111056. + {
  111057. + /* The current hardware and the initial context pipes are
  111058. + different, switch to the correct pipe. */
  111059. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111060. + Command->kernel->hardware,
  111061. + commandBufferLogical,
  111062. + commandBufferObject->entryPipe,
  111063. + &pipeBytes
  111064. + ));
  111065. +
  111066. + /* Do not skip pipe switching sequence. */
  111067. + offset = 0;
  111068. + }
  111069. +
  111070. + /* 3D is not used, generate a LINK from the end of 2D part of
  111071. + the context buffer to the command buffer. */
  111072. + gcmkONERROR(gckHARDWARE_Link(
  111073. + hardware,
  111074. + contextBuffer->link2D,
  111075. + commandBufferLogical + offset,
  111076. + commandBufferSize - offset,
  111077. + &linkBytes
  111078. + ));
  111079. + }
  111080. + }
  111081. +
  111082. + /* Not using 2D. */
  111083. + else
  111084. + {
  111085. + /* Mark 2D as dirty. */
  111086. + Context->dirty2D = gcvTRUE;
  111087. +
  111088. + /* Store the current context buffer. */
  111089. + Context->dirtyBuffer = contextBuffer;
  111090. +
  111091. + if (Context->dirty || commandBufferObject->using3D)
  111092. + {
  111093. + /***************************************************************
  111094. + ** SWITCHING CONTEXT: 3D only command buffer.
  111095. + */
  111096. +
  111097. + /* Reset 3D dirty flag. */
  111098. + Context->dirty3D = gcvFALSE;
  111099. +
  111100. + /* Determine context buffer entry offset. */
  111101. + offset = (Command->pipeSelect == gcvPIPE_3D)
  111102. +
  111103. + /* Skip pipe switching sequence. */
  111104. + ? Context->entryOffset3D + pipeBytes
  111105. +
  111106. + /* Do not skip pipe switching sequence. */
  111107. + : Context->entryOffset3D;
  111108. +
  111109. + /* Compute the entry. */
  111110. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111111. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + offset;
  111112. +#endif
  111113. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + offset;
  111114. + entryBytes = Context->bufferSize - offset;
  111115. +
  111116. + /* See if we have to switch pipes between the context
  111117. + and command buffers. */
  111118. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  111119. + {
  111120. + /* Skip pipe switching sequence. */
  111121. + offset = pipeBytes;
  111122. + }
  111123. + else
  111124. + {
  111125. + /* The current hardware and the initial context pipes are
  111126. + different, switch to the correct pipe. */
  111127. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111128. + Command->kernel->hardware,
  111129. + commandBufferLogical,
  111130. + commandBufferObject->entryPipe,
  111131. + &pipeBytes
  111132. + ));
  111133. +
  111134. + /* Do not skip pipe switching sequence. */
  111135. + offset = 0;
  111136. + }
  111137. +
  111138. + /* Generate a LINK from the context buffer to
  111139. + the command buffer. */
  111140. + gcmkONERROR(gckHARDWARE_Link(
  111141. + hardware,
  111142. + contextBuffer->link3D,
  111143. + commandBufferLogical + offset,
  111144. + commandBufferSize - offset,
  111145. + &linkBytes
  111146. + ));
  111147. + }
  111148. + else
  111149. + {
  111150. + /***************************************************************
  111151. + ** SWITCHING CONTEXT: "XD" command buffer - neither 2D nor 3D.
  111152. + */
  111153. +
  111154. + /* Mark 3D as dirty. */
  111155. + Context->dirty3D = gcvTRUE;
  111156. +
  111157. + /* Compute the entry. */
  111158. + if (Command->pipeSelect == gcvPIPE_3D)
  111159. + {
  111160. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111161. + entryPhysical
  111162. + = (gctUINT8_PTR) contextBuffer->physical
  111163. + + Context->entryOffsetXDFrom3D;
  111164. +#endif
  111165. + entryLogical
  111166. + = (gctUINT8_PTR) contextBuffer->logical
  111167. + + Context->entryOffsetXDFrom3D;
  111168. +
  111169. + entryBytes
  111170. + = Context->bufferSize
  111171. + - Context->entryOffsetXDFrom3D;
  111172. + }
  111173. + else
  111174. + {
  111175. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111176. + entryPhysical
  111177. + = (gctUINT8_PTR) contextBuffer->physical
  111178. + + Context->entryOffsetXDFrom2D;
  111179. +#endif
  111180. + entryLogical
  111181. + = (gctUINT8_PTR) contextBuffer->logical
  111182. + + Context->entryOffsetXDFrom2D;
  111183. +
  111184. + entryBytes
  111185. + = Context->totalSize
  111186. + - Context->entryOffsetXDFrom2D;
  111187. + }
  111188. +
  111189. + /* See if we have to switch pipes between the context
  111190. + and command buffers. */
  111191. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  111192. + {
  111193. + /* Skip pipe switching sequence. */
  111194. + offset = pipeBytes;
  111195. + }
  111196. + else
  111197. + {
  111198. + /* The current hardware and the initial context pipes are
  111199. + different, switch to the correct pipe. */
  111200. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111201. + Command->kernel->hardware,
  111202. + commandBufferLogical,
  111203. + commandBufferObject->entryPipe,
  111204. + &pipeBytes
  111205. + ));
  111206. +
  111207. + /* Do not skip pipe switching sequence. */
  111208. + offset = 0;
  111209. + }
  111210. +
  111211. + /* Generate a LINK from the context buffer to
  111212. + the command buffer. */
  111213. + gcmkONERROR(gckHARDWARE_Link(
  111214. + hardware,
  111215. + contextBuffer->link3D,
  111216. + commandBufferLogical + offset,
  111217. + commandBufferSize - offset,
  111218. + &linkBytes
  111219. + ));
  111220. + }
  111221. + }
  111222. +
  111223. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111224. + /* Flush the context buffer cache. */
  111225. + gcmkONERROR(gckOS_CacheClean(
  111226. + Command->os,
  111227. + Command->kernelProcessID,
  111228. + gcvNULL,
  111229. + entryPhysical,
  111230. + entryLogical,
  111231. + entryBytes
  111232. + ));
  111233. +#endif
  111234. +
  111235. + /* Update the current context. */
  111236. + Command->currContext = Context;
  111237. +
  111238. +#if gcdDUMP_COMMAND
  111239. + contextDumpLogical = entryLogical;
  111240. + contextDumpBytes = entryBytes;
  111241. +#endif
  111242. + }
  111243. +
  111244. + /* Same context. */
  111245. + else
  111246. + {
  111247. + /* Determine context entry and exit points. */
  111248. + if (commandBufferObject->using2D && Context->dirty2D)
  111249. + {
  111250. + /* Reset 2D dirty flag. */
  111251. + Context->dirty2D = gcvFALSE;
  111252. +
  111253. + /* Get the "dirty" context buffer. */
  111254. + contextBuffer = Context->dirtyBuffer;
  111255. +
  111256. + if (commandBufferObject->using3D && Context->dirty3D)
  111257. + {
  111258. + /* Reset 3D dirty flag. */
  111259. + Context->dirty3D = gcvFALSE;
  111260. +
  111261. + /* Compute the entry. */
  111262. + if (Command->pipeSelect == gcvPIPE_2D)
  111263. + {
  111264. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111265. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  111266. +#endif
  111267. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  111268. + entryBytes = Context->bufferSize - pipeBytes;
  111269. + }
  111270. + else
  111271. + {
  111272. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111273. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  111274. +#endif
  111275. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  111276. + entryBytes = Context->bufferSize;
  111277. + }
  111278. +
  111279. + /* See if we have to switch pipes between the context
  111280. + and command buffers. */
  111281. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  111282. + {
  111283. + /* Skip pipe switching sequence. */
  111284. + offset = pipeBytes;
  111285. + }
  111286. + else
  111287. + {
  111288. + /* The current hardware and the initial context pipes are
  111289. + different, switch to the correct pipe. */
  111290. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111291. + Command->kernel->hardware,
  111292. + commandBufferLogical,
  111293. + commandBufferObject->entryPipe,
  111294. + &pipeBytes
  111295. + ));
  111296. +
  111297. + /* Do not skip pipe switching sequence. */
  111298. + offset = 0;
  111299. + }
  111300. +
  111301. + /* Ensure the NOP between 2D and 3D is in place so that the
  111302. + execution falls through from 2D to 3D. */
  111303. + gcmkONERROR(gckHARDWARE_Nop(
  111304. + hardware,
  111305. + contextBuffer->link2D,
  111306. + &nopBytes
  111307. + ));
  111308. +
  111309. + /* Generate a LINK from the context buffer to
  111310. + the command buffer. */
  111311. + gcmkONERROR(gckHARDWARE_Link(
  111312. + hardware,
  111313. + contextBuffer->link3D,
  111314. + commandBufferLogical + offset,
  111315. + commandBufferSize - offset,
  111316. + &linkBytes
  111317. + ));
  111318. + }
  111319. + else
  111320. + {
  111321. + /* Compute the entry. */
  111322. + if (Command->pipeSelect == gcvPIPE_2D)
  111323. + {
  111324. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111325. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  111326. +#endif
  111327. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  111328. + entryBytes = Context->entryOffset3D - pipeBytes;
  111329. + }
  111330. + else
  111331. + {
  111332. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111333. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  111334. +#endif
  111335. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  111336. + entryBytes = Context->entryOffset3D;
  111337. + }
  111338. +
  111339. + /* See if we have to switch pipes between the context
  111340. + and command buffers. */
  111341. + if (commandBufferObject->entryPipe == gcvPIPE_2D)
  111342. + {
  111343. + /* Skip pipe switching sequence. */
  111344. + offset = pipeBytes;
  111345. + }
  111346. + else
  111347. + {
  111348. + /* The current hardware and the initial context pipes are
  111349. + different, switch to the correct pipe. */
  111350. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111351. + Command->kernel->hardware,
  111352. + commandBufferLogical,
  111353. + commandBufferObject->entryPipe,
  111354. + &pipeBytes
  111355. + ));
  111356. +
  111357. + /* Do not skip pipe switching sequence. */
  111358. + offset = 0;
  111359. + }
  111360. +
  111361. + /* 3D is not used, generate a LINK from the end of 2D part of
  111362. + the context buffer to the command buffer. */
  111363. + gcmkONERROR(gckHARDWARE_Link(
  111364. + hardware,
  111365. + contextBuffer->link2D,
  111366. + commandBufferLogical + offset,
  111367. + commandBufferSize - offset,
  111368. + &linkBytes
  111369. + ));
  111370. + }
  111371. + }
  111372. + else
  111373. + {
  111374. + if (commandBufferObject->using3D && Context->dirty3D)
  111375. + {
  111376. + /* Reset 3D dirty flag. */
  111377. + Context->dirty3D = gcvFALSE;
  111378. +
  111379. + /* Get the "dirty" context buffer. */
  111380. + contextBuffer = Context->dirtyBuffer;
  111381. +
  111382. + /* Determine context buffer entry offset. */
  111383. + offset = (Command->pipeSelect == gcvPIPE_3D)
  111384. +
  111385. + /* Skip pipe switching sequence. */
  111386. + ? Context->entryOffset3D + pipeBytes
  111387. +
  111388. + /* Do not skip pipe switching sequence. */
  111389. + : Context->entryOffset3D;
  111390. +
  111391. + /* Compute the entry. */
  111392. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111393. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + offset;
  111394. +#endif
  111395. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + offset;
  111396. + entryBytes = Context->bufferSize - offset;
  111397. +
  111398. + /* See if we have to switch pipes between the context
  111399. + and command buffers. */
  111400. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  111401. + {
  111402. + /* Skip pipe switching sequence. */
  111403. + offset = pipeBytes;
  111404. + }
  111405. + else
  111406. + {
  111407. + /* The current hardware and the initial context pipes are
  111408. + different, switch to the correct pipe. */
  111409. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111410. + Command->kernel->hardware,
  111411. + commandBufferLogical,
  111412. + commandBufferObject->entryPipe,
  111413. + &pipeBytes
  111414. + ));
  111415. +
  111416. + /* Do not skip pipe switching sequence. */
  111417. + offset = 0;
  111418. + }
  111419. +
  111420. + /* Generate a LINK from the context buffer to
  111421. + the command buffer. */
  111422. + gcmkONERROR(gckHARDWARE_Link(
  111423. + hardware,
  111424. + contextBuffer->link3D,
  111425. + commandBufferLogical + offset,
  111426. + commandBufferSize - offset,
  111427. + &linkBytes
  111428. + ));
  111429. + }
  111430. + else
  111431. + {
  111432. + /* See if we have to switch pipes for the command buffer. */
  111433. + if (commandBufferObject->entryPipe == Command->pipeSelect)
  111434. + {
  111435. + /* Skip pipe switching sequence. */
  111436. + offset = pipeBytes;
  111437. + }
  111438. + else
  111439. + {
  111440. + /* The current hardware and the entry command buffer pipes
  111441. + ** are different, switch to the correct pipe. */
  111442. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111443. + Command->kernel->hardware,
  111444. + commandBufferLogical,
  111445. + commandBufferObject->entryPipe,
  111446. + &pipeBytes
  111447. + ));
  111448. +
  111449. + /* Do not skip pipe switching sequence. */
  111450. + offset = 0;
  111451. + }
  111452. +
  111453. + /* Compute the entry. */
  111454. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111455. + entryPhysical = (gctUINT8_PTR) commandBufferPhysical + offset;
  111456. +#endif
  111457. + entryLogical = commandBufferLogical + offset;
  111458. + entryBytes = commandBufferSize - offset;
  111459. + }
  111460. + }
  111461. + }
  111462. +
  111463. +#if gcdDUMP_COMMAND
  111464. + bufferDumpLogical = commandBufferLogical + offset;
  111465. + bufferDumpBytes = commandBufferSize - offset;
  111466. +#endif
  111467. +
  111468. +#if gcdSECURE_USER
  111469. + /* Process user hints. */
  111470. + gcmkONERROR(_ProcessHints(Command, ProcessID, commandBufferObject));
  111471. +#endif
  111472. +
  111473. + /* Determine the location to jump to for the command buffer being
  111474. + ** scheduled. */
  111475. + if (Command->newQueue)
  111476. + {
  111477. + /* New command queue, jump to the beginning of it. */
  111478. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111479. + exitPhysical = Command->physical;
  111480. +#endif
  111481. + exitLogical = Command->logical;
  111482. + exitBytes = Command->offset + waitLinkBytes;
  111483. + }
  111484. + else
  111485. + {
  111486. + /* Still within the preexisting command queue, jump to the new
  111487. + WAIT/LINK command sequence. */
  111488. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111489. + exitPhysical = waitLinkPhysical;
  111490. +#endif
  111491. + exitLogical = waitLinkLogical;
  111492. + exitBytes = waitLinkBytes;
  111493. + }
  111494. +
  111495. + /* Add a new WAIT/LINK command sequence. When the command buffer which is
  111496. + currently being scheduled is fully executed by the GPU, the FE will
  111497. + jump to this WAIT/LINK sequence. */
  111498. + gcmkONERROR(gckHARDWARE_WaitLink(
  111499. + hardware,
  111500. + waitLinkLogical,
  111501. + offset,
  111502. + &waitLinkBytes,
  111503. + &waitOffset,
  111504. + &waitSize
  111505. + ));
  111506. +
  111507. + /* Compute the location if WAIT command. */
  111508. + waitPhysical = (gctUINT8_PTR) waitLinkPhysical + waitOffset;
  111509. + waitLogical = (gctUINT8_PTR) waitLinkLogical + waitOffset;
  111510. +
  111511. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111512. + /* Flush the command queue cache. */
  111513. + gcmkONERROR(gckOS_CacheClean(
  111514. + Command->os,
  111515. + Command->kernelProcessID,
  111516. + gcvNULL,
  111517. + exitPhysical,
  111518. + exitLogical,
  111519. + exitBytes
  111520. + ));
  111521. +#endif
  111522. +
  111523. + /* Determine the location of the LINK command in the command buffer. */
  111524. + commandBufferLink
  111525. + = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
  111526. + + commandBufferObject->offset;
  111527. +
  111528. + /* Generate a LINK from the end of the command buffer being scheduled
  111529. + back to the kernel command queue. */
  111530. + gcmkONERROR(gckHARDWARE_Link(
  111531. + hardware,
  111532. + commandBufferLink,
  111533. + exitLogical,
  111534. + exitBytes,
  111535. + &linkBytes
  111536. + ));
  111537. +
  111538. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111539. + /* Flush the command buffer cache. */
  111540. + gcmkONERROR(gckOS_CacheClean(
  111541. + Command->os,
  111542. + ProcessID,
  111543. + gcvNULL,
  111544. + commandBufferPhysical,
  111545. + commandBufferLogical,
  111546. + commandBufferSize
  111547. + ));
  111548. +#endif
  111549. +
  111550. + /* Generate a LINK from the previous WAIT/LINK command sequence to the
  111551. + entry determined above (either the context or the command buffer).
  111552. + This LINK replaces the WAIT instruction from the previous WAIT/LINK
  111553. + pair, therefore we use WAIT metrics for generation of this LINK.
  111554. + This action will execute the entire sequence. */
  111555. + gcmkONERROR(gckHARDWARE_Link(
  111556. + hardware,
  111557. + Command->waitLogical,
  111558. + entryLogical,
  111559. + entryBytes,
  111560. + &Command->waitSize
  111561. + ));
  111562. +
  111563. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111564. + /* Flush the cache for the link. */
  111565. + gcmkONERROR(gckOS_CacheClean(
  111566. + Command->os,
  111567. + Command->kernelProcessID,
  111568. + gcvNULL,
  111569. + Command->waitPhysical,
  111570. + Command->waitLogical,
  111571. + Command->waitSize
  111572. + ));
  111573. +#endif
  111574. +
  111575. + gcmkDUMPCOMMAND(
  111576. + Command->os,
  111577. + Command->waitLogical,
  111578. + Command->waitSize,
  111579. + gceDUMP_BUFFER_LINK,
  111580. + gcvFALSE
  111581. + );
  111582. +
  111583. + gcmkDUMPCOMMAND(
  111584. + Command->os,
  111585. + contextDumpLogical,
  111586. + contextDumpBytes,
  111587. + gceDUMP_BUFFER_CONTEXT,
  111588. + gcvFALSE
  111589. + );
  111590. +
  111591. + gcmkDUMPCOMMAND(
  111592. + Command->os,
  111593. + bufferDumpLogical,
  111594. + bufferDumpBytes,
  111595. + gceDUMP_BUFFER_USER,
  111596. + gcvFALSE
  111597. + );
  111598. +
  111599. + gcmkDUMPCOMMAND(
  111600. + Command->os,
  111601. + waitLinkLogical,
  111602. + waitLinkBytes,
  111603. + gceDUMP_BUFFER_WAITLINK,
  111604. + gcvFALSE
  111605. + );
  111606. +
  111607. + /* Update the current pipe. */
  111608. + Command->pipeSelect = commandBufferObject->exitPipe;
  111609. +
  111610. + /* Update command queue offset. */
  111611. + Command->offset += waitLinkBytes;
  111612. + Command->newQueue = gcvFALSE;
  111613. +
  111614. + /* Update address of last WAIT. */
  111615. + Command->waitPhysical = waitPhysical;
  111616. + Command->waitLogical = waitLogical;
  111617. + Command->waitSize = waitSize;
  111618. +
  111619. + /* Update queue tail pointer. */
  111620. + gcmkONERROR(gckHARDWARE_UpdateQueueTail(
  111621. + hardware, Command->logical, Command->offset
  111622. + ));
  111623. +
  111624. +#if gcdDUMP_COMMAND
  111625. + gcmkPRINT("@[kernel.commit]");
  111626. +#endif
  111627. +#endif /* gcdNULL_DRIVER */
  111628. +
  111629. + /* Release the context switching mutex. */
  111630. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  111631. + contextAcquired = gcvFALSE;
  111632. +
  111633. + /* Release the command queue. */
  111634. + gcmkONERROR(gckCOMMAND_ExitCommit(Command, gcvFALSE));
  111635. + commitEntered = gcvFALSE;
  111636. +
  111637. +#if VIVANTE_PROFILER_CONTEXT
  111638. + if(sequenceAcquired)
  111639. + {
  111640. + gcmkONERROR(gckCOMMAND_Stall(Command, gcvTRUE));
  111641. + if (Command->currContext)
  111642. + {
  111643. + gcmkONERROR(gckHARDWARE_UpdateContextProfile(
  111644. + hardware,
  111645. + Command->currContext));
  111646. + }
  111647. +
  111648. + /* Release the context switching mutex. */
  111649. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContextSeq));
  111650. + sequenceAcquired = gcvFALSE;
  111651. + }
  111652. +#endif
  111653. +
  111654. + /* Loop while there are records in the queue. */
  111655. + while (EventQueue != gcvNULL)
  111656. + {
  111657. + if (needCopy)
  111658. + {
  111659. + /* Point to stack record. */
  111660. + eventRecord = &_eventRecord;
  111661. +
  111662. + /* Copy the data from the client. */
  111663. + gcmkONERROR(gckOS_CopyFromUserData(
  111664. + Command->os, eventRecord, EventQueue, gcmSIZEOF(gcsQUEUE)
  111665. + ));
  111666. + }
  111667. + else
  111668. + {
  111669. + /* Map record into kernel memory. */
  111670. + gcmkONERROR(gckOS_MapUserPointer(Command->os,
  111671. + EventQueue,
  111672. + gcmSIZEOF(gcsQUEUE),
  111673. + &pointer));
  111674. +
  111675. + eventRecord = pointer;
  111676. + }
  111677. +
  111678. + /* Append event record to event queue. */
  111679. + gcmkONERROR(gckEVENT_AddList(
  111680. + Command->kernel->eventObj, &eventRecord->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE
  111681. + ));
  111682. +
  111683. + /* Next record in the queue. */
  111684. + nextEventRecord = gcmUINT64_TO_PTR(eventRecord->next);
  111685. +
  111686. + if (!needCopy)
  111687. + {
  111688. + /* Unmap record from kernel memory. */
  111689. + gcmkONERROR(gckOS_UnmapUserPointer(
  111690. + Command->os, EventQueue, gcmSIZEOF(gcsQUEUE), (gctPOINTER *) eventRecord
  111691. + ));
  111692. +
  111693. + eventRecord = gcvNULL;
  111694. + }
  111695. +
  111696. + EventQueue = nextEventRecord;
  111697. + }
  111698. +
  111699. + if (Command->kernel->eventObj->queueHead == gcvNULL
  111700. + && Command->kernel->hardware->powerManagement == gcvTRUE
  111701. + )
  111702. + {
  111703. + /* Commit done event by which work thread knows all jobs done. */
  111704. + gcmkVERIFY_OK(
  111705. + gckEVENT_CommitDone(Command->kernel->eventObj, gcvKERNEL_PIXEL));
  111706. + }
  111707. +
  111708. + /* Submit events. */
  111709. + status = gckEVENT_Submit(Command->kernel->eventObj, gcvTRUE, gcvFALSE);
  111710. +
  111711. + if (status == gcvSTATUS_INTERRUPTED)
  111712. + {
  111713. + gcmkTRACE(
  111714. + gcvLEVEL_INFO,
  111715. + "%s(%d): Intterupted in gckEVENT_Submit",
  111716. + __FUNCTION__, __LINE__
  111717. + );
  111718. + status = gcvSTATUS_OK;
  111719. + }
  111720. + else
  111721. + {
  111722. + gcmkONERROR(status);
  111723. + }
  111724. +
  111725. + /* Unmap the command buffer pointer. */
  111726. + if (commandBufferMapped)
  111727. + {
  111728. + gcmkONERROR(gckOS_UnmapUserPointer(
  111729. + Command->os,
  111730. + CommandBuffer,
  111731. + gcmSIZEOF(struct _gcoCMDBUF),
  111732. + commandBufferObject
  111733. + ));
  111734. +
  111735. + commandBufferMapped = gcvFALSE;
  111736. + }
  111737. +
  111738. + /* Return status. */
  111739. + gcmkFOOTER();
  111740. + return gcvSTATUS_OK;
  111741. +
  111742. +OnError:
  111743. + if ((eventRecord != gcvNULL) && !needCopy)
  111744. + {
  111745. + /* Roll back. */
  111746. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(
  111747. + Command->os,
  111748. + EventQueue,
  111749. + gcmSIZEOF(gcsQUEUE),
  111750. + (gctPOINTER *) eventRecord
  111751. + ));
  111752. + }
  111753. +
  111754. + if (contextAcquired)
  111755. + {
  111756. + /* Release the context switching mutex. */
  111757. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  111758. + }
  111759. +
  111760. + if (commitEntered)
  111761. + {
  111762. + /* Release the command queue mutex. */
  111763. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Command, gcvFALSE));
  111764. + }
  111765. +
  111766. +#if VIVANTE_PROFILER_CONTEXT
  111767. + if (sequenceAcquired)
  111768. + {
  111769. + /* Release the context sequence mutex. */
  111770. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContextSeq));
  111771. + }
  111772. +#endif
  111773. +
  111774. + /* Unmap the command buffer pointer. */
  111775. + if (commandBufferMapped)
  111776. + {
  111777. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(
  111778. + Command->os,
  111779. + CommandBuffer,
  111780. + gcmSIZEOF(struct _gcoCMDBUF),
  111781. + commandBufferObject
  111782. + ));
  111783. + }
  111784. +
  111785. + /* Return status. */
  111786. + gcmkFOOTER();
  111787. + return status;
  111788. +}
  111789. +
  111790. +/*******************************************************************************
  111791. +**
  111792. +** gckCOMMAND_Reserve
  111793. +**
  111794. +** Reserve space in the command queue. Also acquire the command queue mutex.
  111795. +**
  111796. +** INPUT:
  111797. +**
  111798. +** gckCOMMAND Command
  111799. +** Pointer to an gckCOMMAND object.
  111800. +**
  111801. +** gctSIZE_T RequestedBytes
  111802. +** Number of bytes previously reserved.
  111803. +**
  111804. +** OUTPUT:
  111805. +**
  111806. +** gctPOINTER * Buffer
  111807. +** Pointer to a variable that will receive the address of the reserved
  111808. +** space.
  111809. +**
  111810. +** gctSIZE_T * BufferSize
  111811. +** Pointer to a variable that will receive the number of bytes
  111812. +** available in the command queue.
  111813. +*/
  111814. +gceSTATUS
  111815. +gckCOMMAND_Reserve(
  111816. + IN gckCOMMAND Command,
  111817. + IN gctSIZE_T RequestedBytes,
  111818. + OUT gctPOINTER * Buffer,
  111819. + OUT gctSIZE_T * BufferSize
  111820. + )
  111821. +{
  111822. + gceSTATUS status;
  111823. + gctSIZE_T bytes;
  111824. + gctSIZE_T requiredBytes;
  111825. + gctUINT32 requestedAligned;
  111826. +
  111827. + gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
  111828. +
  111829. + /* Verify the arguments. */
  111830. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  111831. +
  111832. + /* Compute aligned number of reuested bytes. */
  111833. + requestedAligned = gcmALIGN(RequestedBytes, Command->alignment);
  111834. +
  111835. + /* Another WAIT/LINK command sequence will have to be appended after
  111836. + the requested area being reserved. Compute the number of bytes
  111837. + required for WAIT/LINK at the location after the reserved area. */
  111838. + gcmkONERROR(gckHARDWARE_WaitLink(
  111839. + Command->kernel->hardware,
  111840. + gcvNULL,
  111841. + Command->offset + requestedAligned,
  111842. + &requiredBytes,
  111843. + gcvNULL,
  111844. + gcvNULL
  111845. + ));
  111846. +
  111847. + /* Compute total number of bytes required. */
  111848. + requiredBytes += requestedAligned;
  111849. +
  111850. + /* Compute number of bytes available in command queue. */
  111851. + bytes = Command->pageSize - Command->offset;
  111852. +
  111853. + /* Is there enough space in the current command queue? */
  111854. + if (bytes < requiredBytes)
  111855. + {
  111856. + /* Create a new command queue. */
  111857. + gcmkONERROR(_NewQueue(Command));
  111858. +
  111859. + /* Recompute the number of bytes in the new kernel command queue. */
  111860. + bytes = Command->pageSize - Command->offset;
  111861. +
  111862. + /* Still not enough space? */
  111863. + if (bytes < requiredBytes)
  111864. + {
  111865. + /* Rare case, not enough room in command queue. */
  111866. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  111867. + }
  111868. + }
  111869. +
  111870. + /* Return pointer to empty slot command queue. */
  111871. + *Buffer = (gctUINT8 *) Command->logical + Command->offset;
  111872. +
  111873. + /* Return number of bytes left in command queue. */
  111874. + *BufferSize = bytes;
  111875. +
  111876. + /* Success. */
  111877. + gcmkFOOTER_ARG("*Buffer=0x%x *BufferSize=%lu", *Buffer, *BufferSize);
  111878. + return gcvSTATUS_OK;
  111879. +
  111880. +OnError:
  111881. + /* Return status. */
  111882. + gcmkFOOTER();
  111883. + return status;
  111884. +}
  111885. +
  111886. +/*******************************************************************************
  111887. +**
  111888. +** gckCOMMAND_Execute
  111889. +**
  111890. +** Execute a previously reserved command queue by appending a WAIT/LINK command
  111891. +** sequence after it and modifying the last WAIT into a LINK command. The
  111892. +** command FIFO mutex will be released whether this function succeeds or not.
  111893. +**
  111894. +** INPUT:
  111895. +**
  111896. +** gckCOMMAND Command
  111897. +** Pointer to an gckCOMMAND object.
  111898. +**
  111899. +** gctSIZE_T RequestedBytes
  111900. +** Number of bytes previously reserved.
  111901. +**
  111902. +** OUTPUT:
  111903. +**
  111904. +** Nothing.
  111905. +*/
  111906. +gceSTATUS
  111907. +gckCOMMAND_Execute(
  111908. + IN gckCOMMAND Command,
  111909. + IN gctSIZE_T RequestedBytes
  111910. + )
  111911. +{
  111912. + gceSTATUS status;
  111913. +
  111914. + gctPHYS_ADDR waitLinkPhysical;
  111915. + gctUINT8_PTR waitLinkLogical;
  111916. + gctUINT32 waitLinkOffset;
  111917. + gctSIZE_T waitLinkBytes;
  111918. +
  111919. + gctPHYS_ADDR waitPhysical;
  111920. + gctPOINTER waitLogical;
  111921. + gctUINT32 waitOffset;
  111922. + gctSIZE_T waitBytes;
  111923. +
  111924. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111925. + gctPHYS_ADDR execPhysical;
  111926. +#endif
  111927. + gctPOINTER execLogical;
  111928. + gctSIZE_T execBytes;
  111929. +
  111930. + gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
  111931. +
  111932. + /* Verify the arguments. */
  111933. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  111934. +
  111935. + /* Compute offset for WAIT/LINK. */
  111936. + waitLinkOffset = Command->offset + RequestedBytes;
  111937. +
  111938. + /* Compute number of bytes left in command queue. */
  111939. + waitLinkBytes = Command->pageSize - waitLinkOffset;
  111940. +
  111941. + /* Compute the location if WAIT/LINK command sequence. */
  111942. + waitLinkPhysical = (gctUINT8_PTR) Command->physical + waitLinkOffset;
  111943. + waitLinkLogical = (gctUINT8_PTR) Command->logical + waitLinkOffset;
  111944. +
  111945. + /* Append WAIT/LINK in command queue. */
  111946. + gcmkONERROR(gckHARDWARE_WaitLink(
  111947. + Command->kernel->hardware,
  111948. + waitLinkLogical,
  111949. + waitLinkOffset,
  111950. + &waitLinkBytes,
  111951. + &waitOffset,
  111952. + &waitBytes
  111953. + ));
  111954. +
  111955. + /* Compute the location if WAIT command. */
  111956. + waitPhysical = (gctUINT8_PTR) waitLinkPhysical + waitOffset;
  111957. + waitLogical = waitLinkLogical + waitOffset;
  111958. +
  111959. + /* Determine the location to jump to for the command buffer being
  111960. + ** scheduled. */
  111961. + if (Command->newQueue)
  111962. + {
  111963. + /* New command queue, jump to the beginning of it. */
  111964. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111965. + execPhysical = Command->physical;
  111966. +#endif
  111967. + execLogical = Command->logical;
  111968. + execBytes = waitLinkOffset + waitLinkBytes;
  111969. + }
  111970. + else
  111971. + {
  111972. + /* Still within the preexisting command queue, jump directly to the
  111973. + reserved area. */
  111974. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111975. + execPhysical = (gctUINT8 *) Command->physical + Command->offset;
  111976. +#endif
  111977. + execLogical = (gctUINT8 *) Command->logical + Command->offset;
  111978. + execBytes = RequestedBytes + waitLinkBytes;
  111979. + }
  111980. +
  111981. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111982. + /* Flush the cache. */
  111983. + gcmkONERROR(gckOS_CacheClean(
  111984. + Command->os,
  111985. + Command->kernelProcessID,
  111986. + gcvNULL,
  111987. + execPhysical,
  111988. + execLogical,
  111989. + execBytes
  111990. + ));
  111991. +#endif
  111992. +
  111993. + /* Convert the last WAIT into a LINK. */
  111994. + gcmkONERROR(gckHARDWARE_Link(
  111995. + Command->kernel->hardware,
  111996. + Command->waitLogical,
  111997. + execLogical,
  111998. + execBytes,
  111999. + &Command->waitSize
  112000. + ));
  112001. +
  112002. +#if gcdNONPAGED_MEMORY_CACHEABLE
  112003. + /* Flush the cache. */
  112004. + gcmkONERROR(gckOS_CacheClean(
  112005. + Command->os,
  112006. + Command->kernelProcessID,
  112007. + gcvNULL,
  112008. + Command->waitPhysical,
  112009. + Command->waitLogical,
  112010. + Command->waitSize
  112011. + ));
  112012. +#endif
  112013. +
  112014. + gcmkDUMPCOMMAND(
  112015. + Command->os,
  112016. + Command->waitLogical,
  112017. + Command->waitSize,
  112018. + gceDUMP_BUFFER_LINK,
  112019. + gcvFALSE
  112020. + );
  112021. +
  112022. + gcmkDUMPCOMMAND(
  112023. + Command->os,
  112024. + execLogical,
  112025. + execBytes,
  112026. + gceDUMP_BUFFER_KERNEL,
  112027. + gcvFALSE
  112028. + );
  112029. +
  112030. + /* Update the pointer to the last WAIT. */
  112031. + Command->waitPhysical = waitPhysical;
  112032. + Command->waitLogical = waitLogical;
  112033. + Command->waitSize = waitBytes;
  112034. +
  112035. + /* Update the command queue. */
  112036. + Command->offset += RequestedBytes + waitLinkBytes;
  112037. + Command->newQueue = gcvFALSE;
  112038. +
  112039. + /* Update queue tail pointer. */
  112040. + gcmkONERROR(gckHARDWARE_UpdateQueueTail(
  112041. + Command->kernel->hardware, Command->logical, Command->offset
  112042. + ));
  112043. +
  112044. +#if gcdDUMP_COMMAND
  112045. + gcmkPRINT("@[kernel.execute]");
  112046. +#endif
  112047. +
  112048. + /* Success. */
  112049. + gcmkFOOTER_NO();
  112050. + return gcvSTATUS_OK;
  112051. +
  112052. +OnError:
  112053. + /* Return the status. */
  112054. + gcmkFOOTER();
  112055. + return status;
  112056. +}
  112057. +
  112058. +/*******************************************************************************
  112059. +**
  112060. +** gckCOMMAND_Stall
  112061. +**
  112062. +** The calling thread will be suspended until the command queue has been
  112063. +** completed.
  112064. +**
  112065. +** INPUT:
  112066. +**
  112067. +** gckCOMMAND Command
  112068. +** Pointer to an gckCOMMAND object.
  112069. +**
  112070. +** gctBOOL FromPower
  112071. +** Determines whether the call originates from inside the power
  112072. +** management or not.
  112073. +**
  112074. +** OUTPUT:
  112075. +**
  112076. +** Nothing.
  112077. +*/
  112078. +gceSTATUS
  112079. +gckCOMMAND_Stall(
  112080. + IN gckCOMMAND Command,
  112081. + IN gctBOOL FromPower
  112082. + )
  112083. +{
  112084. +#if gcdNULL_DRIVER
  112085. + /* Do nothing with infinite hardware. */
  112086. + return gcvSTATUS_OK;
  112087. +#else
  112088. + gckOS os;
  112089. + gckHARDWARE hardware;
  112090. + gckEVENT eventObject;
  112091. + gceSTATUS status;
  112092. + gctSIGNAL signal = gcvNULL;
  112093. + gctUINT timer = 0;
  112094. +
  112095. + gcmkHEADER_ARG("Command=0x%x", Command);
  112096. +
  112097. + /* Verify the arguments. */
  112098. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  112099. +
  112100. + /* Extract the gckOS object pointer. */
  112101. + os = Command->os;
  112102. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  112103. +
  112104. + /* Extract the gckHARDWARE object pointer. */
  112105. + hardware = Command->kernel->hardware;
  112106. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  112107. +
  112108. + /* Extract the gckEVENT object pointer. */
  112109. + eventObject = Command->kernel->eventObj;
  112110. + gcmkVERIFY_OBJECT(eventObject, gcvOBJ_EVENT);
  112111. +
  112112. + /* Allocate the signal. */
  112113. + gcmkONERROR(gckOS_CreateSignal(os, gcvTRUE, &signal));
  112114. +
  112115. + /* Append the EVENT command to trigger the signal. */
  112116. + gcmkONERROR(gckEVENT_Signal(eventObject, signal, gcvKERNEL_PIXEL));
  112117. +
  112118. + /* Submit the event queue. */
  112119. + gcmkONERROR(gckEVENT_Submit(eventObject, gcvTRUE, FromPower));
  112120. +
  112121. +#if gcdDUMP_COMMAND
  112122. + gcmkPRINT("@[kernel.stall]");
  112123. +#endif
  112124. +
  112125. + if (status == gcvSTATUS_CHIP_NOT_READY)
  112126. + {
  112127. + /* Error. */
  112128. + goto OnError;
  112129. + }
  112130. +
  112131. + do
  112132. + {
  112133. + /* Wait for the signal. */
  112134. + status = gckOS_WaitSignal(os, signal, gcdGPU_ADVANCETIMER);
  112135. +
  112136. + if (status == gcvSTATUS_TIMEOUT)
  112137. + {
  112138. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  112139. + gctUINT32 idle;
  112140. +
  112141. + /* Read idle register. */
  112142. + gcmkVERIFY_OK(gckHARDWARE_GetIdle(
  112143. + hardware, gcvFALSE, &idle
  112144. + ));
  112145. +
  112146. + gcmkTRACE(
  112147. + gcvLEVEL_ERROR,
  112148. + "%s(%d): idle=%08x",
  112149. + __FUNCTION__, __LINE__, idle
  112150. + );
  112151. +
  112152. + gcmkONERROR(gckOS_MemoryBarrier(os, gcvNULL));
  112153. +
  112154. +#ifdef __QNXNTO__
  112155. + gctUINT32 reg_cmdbuf_fetch;
  112156. + gctUINT32 reg_intr;
  112157. +
  112158. + gcmkVERIFY_OK(gckOS_ReadRegisterEx(
  112159. + Command->kernel->hardware->os, Command->kernel->core, 0x0664, &reg_cmdbuf_fetch
  112160. + ));
  112161. +
  112162. + if (idle == 0x7FFFFFFE)
  112163. + {
  112164. + /*
  112165. + * GPU is idle so there should not be pending interrupts.
  112166. + * Just double check.
  112167. + *
  112168. + * Note that reading interrupt register clears it.
  112169. + * That's why we don't read it in all cases.
  112170. + */
  112171. + gcmkVERIFY_OK(gckOS_ReadRegisterEx(
  112172. + Command->kernel->hardware->os, Command->kernel->core, 0x10, &reg_intr
  112173. + ));
  112174. +
  112175. + slogf(
  112176. + _SLOG_SETCODE(1, 0),
  112177. + _SLOG_CRITICAL,
  112178. + "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X, interrupt = 0x%X)",
  112179. + idle, reg_cmdbuf_fetch, reg_intr
  112180. + );
  112181. + }
  112182. + else
  112183. + {
  112184. + slogf(
  112185. + _SLOG_SETCODE(1, 0),
  112186. + _SLOG_CRITICAL,
  112187. + "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X)",
  112188. + idle, reg_cmdbuf_fetch
  112189. + );
  112190. + }
  112191. +#endif
  112192. +#endif
  112193. + /* Advance timer. */
  112194. + timer += gcdGPU_ADVANCETIMER;
  112195. + }
  112196. + else if (status == gcvSTATUS_INTERRUPTED)
  112197. + {
  112198. + gcmkONERROR(gcvSTATUS_INTERRUPTED);
  112199. + }
  112200. +
  112201. + }
  112202. + while (gcmIS_ERROR(status)
  112203. +#if gcdGPU_TIMEOUT
  112204. + && (timer < Command->kernel->timeOut)
  112205. +#endif
  112206. + );
  112207. +
  112208. + /* Bail out on timeout. */
  112209. + if (gcmIS_ERROR(status))
  112210. + {
  112211. + /* Broadcast the stuck GPU. */
  112212. + gcmkONERROR(gckOS_Broadcast(
  112213. + os, hardware, gcvBROADCAST_GPU_STUCK
  112214. + ));
  112215. + }
  112216. +
  112217. + /* Delete the signal. */
  112218. + gcmkVERIFY_OK(gckOS_DestroySignal(os, signal));
  112219. +
  112220. + /* Success. */
  112221. + gcmkFOOTER_NO();
  112222. + return gcvSTATUS_OK;
  112223. +
  112224. +OnError:
  112225. + if (signal != gcvNULL)
  112226. + {
  112227. + /* Free the signal. */
  112228. + gcmkVERIFY_OK(gckOS_DestroySignal(os, signal));
  112229. + }
  112230. +
  112231. + /* Return the status. */
  112232. + gcmkFOOTER();
  112233. + return status;
  112234. +#endif
  112235. +}
  112236. +
  112237. +/*******************************************************************************
  112238. +**
  112239. +** gckCOMMAND_Attach
  112240. +**
  112241. +** Attach user process.
  112242. +**
  112243. +** INPUT:
  112244. +**
  112245. +** gckCOMMAND Command
  112246. +** Pointer to a gckCOMMAND object.
  112247. +**
  112248. +** gctUINT32 ProcessID
  112249. +** Current process ID.
  112250. +**
  112251. +** OUTPUT:
  112252. +**
  112253. +** gckCONTEXT * Context
  112254. +** Pointer to a variable that will receive a pointer to a new
  112255. +** gckCONTEXT object.
  112256. +**
  112257. +** gctSIZE_T * StateCount
  112258. +** Pointer to a variable that will receive the number of states
  112259. +** in the context buffer.
  112260. +*/
  112261. +gceSTATUS
  112262. +gckCOMMAND_Attach(
  112263. + IN gckCOMMAND Command,
  112264. + OUT gckCONTEXT * Context,
  112265. + OUT gctSIZE_T * StateCount,
  112266. + IN gctUINT32 ProcessID
  112267. + )
  112268. +{
  112269. + gceSTATUS status;
  112270. + gctBOOL acquired = gcvFALSE;
  112271. +
  112272. + gcmkHEADER_ARG("Command=0x%x", Command);
  112273. +
  112274. + /* Verify the arguments. */
  112275. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  112276. +
  112277. + /* Acquire the context switching mutex. */
  112278. + gcmkONERROR(gckOS_AcquireMutex(
  112279. + Command->os, Command->mutexContext, gcvINFINITE
  112280. + ));
  112281. + acquired = gcvTRUE;
  112282. +
  112283. + /* Construct a gckCONTEXT object. */
  112284. + gcmkONERROR(gckCONTEXT_Construct(
  112285. + Command->os,
  112286. + Command->kernel->hardware,
  112287. + ProcessID,
  112288. + Context
  112289. + ));
  112290. +
  112291. + /* Return the number of states in the context. */
  112292. + * StateCount = (* Context)->stateCount;
  112293. +
  112294. + /* Release the context switching mutex. */
  112295. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  112296. + acquired = gcvFALSE;
  112297. +
  112298. + /* Success. */
  112299. + gcmkFOOTER_ARG("*Context=0x%x", *Context);
  112300. + return gcvSTATUS_OK;
  112301. +
  112302. +OnError:
  112303. + /* Release mutex. */
  112304. + if (acquired)
  112305. + {
  112306. + /* Release the context switching mutex. */
  112307. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  112308. + acquired = gcvFALSE;
  112309. + }
  112310. +
  112311. + /* Return the status. */
  112312. + gcmkFOOTER();
  112313. + return status;
  112314. +}
  112315. +
  112316. +/*******************************************************************************
  112317. +**
  112318. +** gckCOMMAND_Detach
  112319. +**
  112320. +** Detach user process.
  112321. +**
  112322. +** INPUT:
  112323. +**
  112324. +** gckCOMMAND Command
  112325. +** Pointer to a gckCOMMAND object.
  112326. +**
  112327. +** gckCONTEXT Context
  112328. +** Pointer to a gckCONTEXT object to be destroyed.
  112329. +**
  112330. +** OUTPUT:
  112331. +**
  112332. +** Nothing.
  112333. +*/
  112334. +gceSTATUS
  112335. +gckCOMMAND_Detach(
  112336. + IN gckCOMMAND Command,
  112337. + IN gckCONTEXT Context
  112338. + )
  112339. +{
  112340. + gceSTATUS status;
  112341. + gctBOOL acquired = gcvFALSE;
  112342. +
  112343. + gcmkHEADER_ARG("Command=0x%x Context=0x%x", Command, Context);
  112344. +
  112345. + /* Verify the arguments. */
  112346. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  112347. +
  112348. + /* Acquire the context switching mutex. */
  112349. + gcmkONERROR(gckOS_AcquireMutex(
  112350. + Command->os, Command->mutexContext, gcvINFINITE
  112351. + ));
  112352. + acquired = gcvTRUE;
  112353. +
  112354. + /* Construct a gckCONTEXT object. */
  112355. + gcmkONERROR(gckCONTEXT_Destroy(Context));
  112356. +
  112357. + if (Command->currContext == Context)
  112358. + {
  112359. + /* Detach from gckCOMMAND object if the destoryed context is current context. */
  112360. + Command->currContext = gcvNULL;
  112361. + }
  112362. +
  112363. + /* Release the context switching mutex. */
  112364. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  112365. + acquired = gcvFALSE;
  112366. +
  112367. + /* Return the status. */
  112368. + gcmkFOOTER();
  112369. + return gcvSTATUS_OK;
  112370. +
  112371. +OnError:
  112372. + /* Release mutex. */
  112373. + if (acquired)
  112374. + {
  112375. + /* Release the context switching mutex. */
  112376. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  112377. + acquired = gcvFALSE;
  112378. + }
  112379. +
  112380. + /* Return the status. */
  112381. + gcmkFOOTER();
  112382. + return status;
  112383. +}
  112384. +
  112385. +#if gcdVIRTUAL_COMMAND_BUFFER
  112386. +/*******************************************************************************
  112387. +**
  112388. +** gckCOMMAND_DumpExecutingBuffer
  112389. +**
  112390. +** Dump the command buffer which GPU is executing.
  112391. +**
  112392. +** INPUT:
  112393. +**
  112394. +** gckCOMMAND Command
  112395. +** Pointer to a gckCOMMAND object.
  112396. +**
  112397. +** OUTPUT:
  112398. +**
  112399. +** Nothing.
  112400. +*/
  112401. +gceSTATUS
  112402. +gckCOMMAND_DumpExecutingBuffer(
  112403. + IN gckCOMMAND Command
  112404. + )
  112405. +{
  112406. + gceSTATUS status;
  112407. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  112408. + gctUINT32 gpuAddress;
  112409. + gctSIZE_T pageCount;
  112410. + gctPOINTER entry;
  112411. + gckOS os = Command->os;
  112412. + gckKERNEL kernel = Command->kernel;
  112413. +#if gcdLINK_QUEUE_SIZE
  112414. + gctINT pid;
  112415. + gctINT i, rear;
  112416. + gctUINT32 start, end;
  112417. + gctUINT32 dumpFront, dumpRear;
  112418. + gckLINKQUEUE queue = &kernel->hardware->linkQueue;
  112419. + gckLINKQUEUE queueMirror;
  112420. + gctUINT32 bytes;
  112421. + gckLINKDATA linkData;
  112422. +#endif
  112423. +
  112424. + gcmkPRINT("**************************\n");
  112425. + gcmkPRINT("**** COMMAND BUF DUMP ****\n");
  112426. + gcmkPRINT("**************************\n");
  112427. +
  112428. + gcmkVERIFY_OK(gckOS_ReadRegisterEx(os, kernel->core, 0x664, &gpuAddress));
  112429. +
  112430. + gcmkPRINT("DMA Address 0x%08X", gpuAddress);
  112431. +
  112432. +#if gcdLINK_QUEUE_SIZE
  112433. + /* Duplicate queue because it will be changed.*/
  112434. + gcmkONERROR(gckOS_AllocateMemory(os,
  112435. + sizeof(struct _gckLINKQUEUE),
  112436. + (gctPOINTER *)&queueMirror));
  112437. +
  112438. + gcmkONERROR(gckOS_MemCopy(queueMirror,
  112439. + queue,
  112440. + sizeof(struct _gckLINKQUEUE)));
  112441. +
  112442. + /* If kernel command buffer link to a context buffer, then link to a user command
  112443. + ** buffer, the second link will be in queue first, so we must fix this.
  112444. + ** In Queue: C1 U1 U2 C2 U3 U4 U5 C3
  112445. + ** Real: C1 X1 U1 C2 U2 U3 U4 C3 U5
  112446. + ** Command buffer X1 which is after C1 is out of queue, so C1 is meaningless.
  112447. + */
  112448. + for (i = 0; i < gcdLINK_QUEUE_SIZE; i++)
  112449. + {
  112450. + gckLINKQUEUE_GetData(queueMirror, i, &linkData);
  112451. +
  112452. + status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer);
  112453. +
  112454. + if (gcmIS_ERROR(status))
  112455. + {
  112456. + /* Can't find it in virtual command buffer list, ignore it. */
  112457. + continue;
  112458. + }
  112459. +
  112460. + if (buffer->kernelLogical)
  112461. + {
  112462. + /* It is a context buffer. */
  112463. + if (i == 0)
  112464. + {
  112465. + /* The real command buffer is out, so clear this slot. */
  112466. + linkData->start = 0;
  112467. + linkData->end = 0;
  112468. + linkData->pid = 0;
  112469. + }
  112470. + else
  112471. + {
  112472. + /* switch context buffer and command buffer. */
  112473. + struct _gckLINKDATA tmp = *linkData;
  112474. + gckLINKDATA linkDataPrevious;
  112475. +
  112476. + gckLINKQUEUE_GetData(queueMirror, i - 1, &linkDataPrevious);
  112477. + *linkData = *linkDataPrevious;
  112478. + *linkDataPrevious = tmp;
  112479. + }
  112480. + }
  112481. + }
  112482. +
  112483. + /* Clear search result. */
  112484. + dumpFront = dumpRear = gcvINFINITE;
  112485. +
  112486. + gcmkPRINT("Link Stack:");
  112487. +
  112488. + /* Search stuck address in link queue from rear. */
  112489. + rear = gcdLINK_QUEUE_SIZE - 1;
  112490. + for (i = 0; i < gcdLINK_QUEUE_SIZE; i++)
  112491. + {
  112492. + gckLINKQUEUE_GetData(queueMirror, rear, &linkData);
  112493. +
  112494. + start = linkData->start;
  112495. + end = linkData->end;
  112496. + pid = linkData->pid;
  112497. +
  112498. + if (gpuAddress >= start && gpuAddress < end)
  112499. + {
  112500. + /* Find latest matched command buffer. */
  112501. + gcmkPRINT(" %d, [%08X - %08X]", pid, start, end);
  112502. +
  112503. + /* Initiliaze dump information. */
  112504. + dumpFront = dumpRear = rear;
  112505. + }
  112506. +
  112507. + /* Advance to previous one. */
  112508. + rear--;
  112509. +
  112510. + if (dumpFront != gcvINFINITE)
  112511. + {
  112512. + break;
  112513. + }
  112514. + }
  112515. +
  112516. + if (dumpFront == gcvINFINITE)
  112517. + {
  112518. + /* Can't find matched record in link queue, dump kernel command buffer. */
  112519. + _DumpKernelCommandBuffer(Command);
  112520. +
  112521. + /* Free local copy. */
  112522. + gcmkOS_SAFE_FREE(os, queueMirror);
  112523. + return gcvSTATUS_OK;
  112524. + }
  112525. +
  112526. + /* Search the last context buffer linked. */
  112527. + while (rear >= 0)
  112528. + {
  112529. + gckLINKQUEUE_GetData(queueMirror, rear, &linkData);
  112530. +
  112531. + gcmkPRINT(" %d, [%08X - %08X]",
  112532. + linkData->pid,
  112533. + linkData->start,
  112534. + linkData->end);
  112535. +
  112536. + status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer);
  112537. +
  112538. + if (gcmIS_SUCCESS(status) && buffer->kernelLogical)
  112539. + {
  112540. + /* Find a context buffer. */
  112541. + dumpFront = rear;
  112542. + break;
  112543. + }
  112544. +
  112545. + rear--;
  112546. + }
  112547. +
  112548. + /* Dump from last context buffer to last command buffer where hang happens. */
  112549. + for (i = dumpFront; i <= dumpRear; i++)
  112550. + {
  112551. + gckLINKQUEUE_GetData(queueMirror, i, &linkData);
  112552. +
  112553. + /* Get gpu address of this command buffer. */
  112554. + gpuAddress = linkData->start;
  112555. + bytes = linkData->end - gpuAddress;
  112556. +
  112557. + /* Get the whole buffer. */
  112558. + status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer);
  112559. +
  112560. + if (gcmIS_ERROR(status))
  112561. + {
  112562. + gcmkPRINT("Buffer [%08X - %08X] is lost",
  112563. + linkData->start,
  112564. + linkData->end);
  112565. + continue;
  112566. + }
  112567. +
  112568. + /* Get kernel logical for dump. */
  112569. + if (buffer->kernelLogical)
  112570. + {
  112571. + /* Get kernel logical directly if it is a context buffer. */
  112572. + entry = buffer->kernelLogical;
  112573. + gcmkPRINT("Context Buffer:");
  112574. + }
  112575. + else
  112576. + {
  112577. + /* Make it accessiable by kernel if it is a user command buffer. */
  112578. + gcmkVERIFY_OK(
  112579. + gckOS_CreateKernelVirtualMapping(buffer->physical,
  112580. + &pageCount,
  112581. + &entry));
  112582. + gcmkPRINT("User Command Buffer:");
  112583. + }
  112584. +
  112585. + /* Dump from the entry. */
  112586. + _DumpBuffer(entry + (gpuAddress - buffer->gpuAddress), gpuAddress, bytes);
  112587. +
  112588. + /* Release kernel logical address if neccessary. */
  112589. + if (!buffer->kernelLogical)
  112590. + {
  112591. + gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(entry));
  112592. + }
  112593. + }
  112594. +
  112595. + /* Free local copy. */
  112596. + gcmkOS_SAFE_FREE(os, queueMirror);
  112597. + return gcvSTATUS_OK;
  112598. +OnError:
  112599. + return status;
  112600. +#else
  112601. + /* Without link queue information, we don't know the entry of last command
  112602. + ** buffer, just dump the page where GPU stuck. */
  112603. + status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer);
  112604. +
  112605. + if (gcmIS_SUCCESS(status))
  112606. + {
  112607. + gcmkVERIFY_OK(
  112608. + gckOS_CreateKernelVirtualMapping(buffer->physical, &pageCount, &entry));
  112609. +
  112610. + if (entry)
  112611. + {
  112612. + gctUINT32 offset = gpuAddress - buffer->gpuAddress;
  112613. + gctPOINTER entryDump = entry;
  112614. +
  112615. + /* Dump one pages. */
  112616. + gctUINT32 bytes = 4096;
  112617. +
  112618. + /* Align to page. */
  112619. + offset &= 0xfffff000;
  112620. +
  112621. + /* Kernel address of page where stall point stay. */
  112622. + entryDump += offset;
  112623. +
  112624. + /* Align to page. */
  112625. + gpuAddress &= 0xfffff000;
  112626. +
  112627. + gcmkPRINT("User Command Buffer:\n");
  112628. + _DumpBuffer(entryDump, gpuAddress, bytes);
  112629. + }
  112630. +
  112631. + gcmkVERIFY_OK(
  112632. + gckOS_DestroyKernelVirtualMapping(entry));
  112633. + }
  112634. + else
  112635. + {
  112636. + _DumpKernelCommandBuffer(Command);
  112637. + }
  112638. +
  112639. + return gcvSTATUS_OK;
  112640. +#endif
  112641. +}
  112642. +#endif
  112643. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
  112644. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c 1970-01-01 01:00:00.000000000 +0100
  112645. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c 2014-08-20 19:31:46.128869007 +0200
  112646. @@ -0,0 +1,3677 @@
  112647. +/****************************************************************************
  112648. +*
  112649. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  112650. +*
  112651. +* This program is free software; you can redistribute it and/or modify
  112652. +* it under the terms of the GNU General Public License as published by
  112653. +* the Free Software Foundation; either version 2 of the license, or
  112654. +* (at your option) any later version.
  112655. +*
  112656. +* This program is distributed in the hope that it will be useful,
  112657. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  112658. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  112659. +* GNU General Public License for more details.
  112660. +*
  112661. +* You should have received a copy of the GNU General Public License
  112662. +* along with this program; if not write to the Free Software
  112663. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  112664. +*
  112665. +*****************************************************************************/
  112666. +
  112667. +
  112668. +#include "gc_hal_kernel_precomp.h"
  112669. +
  112670. +#if gcdENABLE_VG
  112671. +
  112672. +#include "gc_hal_kernel_hardware_command_vg.h"
  112673. +
  112674. +#define _GC_OBJ_ZONE gcvZONE_COMMAND
  112675. +
  112676. +/******************************************************************************\
  112677. +*********************************** Debugging **********************************
  112678. +\******************************************************************************/
  112679. +
  112680. +#define gcvDISABLE_TIMEOUT 1
  112681. +#define gcvDUMP_COMMAND_BUFFER 0
  112682. +#define gcvDUMP_COMMAND_LINES 0
  112683. +
  112684. +
  112685. +#if gcvDEBUG || defined(EMULATOR) || gcvDISABLE_TIMEOUT
  112686. +# define gcvQUEUE_TIMEOUT ~0
  112687. +#else
  112688. +# define gcvQUEUE_TIMEOUT 10
  112689. +#endif
  112690. +
  112691. +
  112692. +/******************************************************************************\
  112693. +********************************** Definitions *********************************
  112694. +\******************************************************************************/
  112695. +
  112696. +/* Minimum buffer size. */
  112697. +#define gcvMINUMUM_BUFFER \
  112698. + gcmSIZEOF(gcsKERNEL_QUEUE_HEADER) + \
  112699. + gcmSIZEOF(gcsKERNEL_CMDQUEUE) * 2
  112700. +
  112701. +#define gcmDECLARE_INTERRUPT_HANDLER(Block, Number) \
  112702. + static gceSTATUS \
  112703. + _EventHandler_##Block##_##Number( \
  112704. + IN gckVGKERNEL Kernel \
  112705. + )
  112706. +
  112707. +#define gcmDEFINE_INTERRUPT_HANDLER(Block, Number) \
  112708. + gcmDECLARE_INTERRUPT_HANDLER(Block, Number) \
  112709. + { \
  112710. + return _EventHandler_Block( \
  112711. + Kernel, \
  112712. + &Kernel->command->taskTable[gcvBLOCK_##Block], \
  112713. + gcvFALSE \
  112714. + ); \
  112715. + }
  112716. +
  112717. +#define gcmDEFINE_INTERRUPT_HANDLER_ENTRY(Block, Number) \
  112718. + { gcvBLOCK_##Block, _EventHandler_##Block##_##Number }
  112719. +
  112720. +/* Block interrupt handling table entry. */
  112721. +typedef struct _gcsBLOCK_INTERRUPT_HANDLER * gcsBLOCK_INTERRUPT_HANDLER_PTR;
  112722. +typedef struct _gcsBLOCK_INTERRUPT_HANDLER
  112723. +{
  112724. + gceBLOCK block;
  112725. + gctINTERRUPT_HANDLER handler;
  112726. +}
  112727. +gcsBLOCK_INTERRUPT_HANDLER;
  112728. +
  112729. +/* Queue control functions. */
  112730. +typedef struct _gcsQUEUE_UPDATE_CONTROL * gcsQUEUE_UPDATE_CONTROL_PTR;
  112731. +typedef struct _gcsQUEUE_UPDATE_CONTROL
  112732. +{
  112733. + gctOBJECT_HANDLER execute;
  112734. + gctOBJECT_HANDLER update;
  112735. + gctOBJECT_HANDLER lastExecute;
  112736. + gctOBJECT_HANDLER lastUpdate;
  112737. +}
  112738. +gcsQUEUE_UPDATE_CONTROL;
  112739. +
  112740. +
  112741. +/******************************************************************************\
  112742. +********************************* Support Code *********************************
  112743. +\******************************************************************************/
  112744. +static gceSTATUS
  112745. +_FlushMMU(
  112746. + IN gckVGCOMMAND Command
  112747. + )
  112748. +{
  112749. + gceSTATUS status;
  112750. + gctUINT32 oldValue;
  112751. + gckVGHARDWARE hardware = Command->hardware;
  112752. +
  112753. + gcmkONERROR(gckOS_AtomicExchange(Command->os,
  112754. + hardware->pageTableDirty,
  112755. + 0,
  112756. + &oldValue));
  112757. +
  112758. + if (oldValue)
  112759. + {
  112760. + /* Page Table is upated, flush mmu before commit. */
  112761. + gcmkONERROR(gckVGHARDWARE_FlushMMU(hardware));
  112762. + }
  112763. +
  112764. + return gcvSTATUS_OK;
  112765. +OnError:
  112766. + return status;
  112767. +}
  112768. +
  112769. +static gceSTATUS
  112770. +_WaitForIdle(
  112771. + IN gckVGCOMMAND Command,
  112772. + IN gcsKERNEL_QUEUE_HEADER_PTR Queue
  112773. + )
  112774. +{
  112775. + gceSTATUS status = gcvSTATUS_OK;
  112776. + gctUINT32 idle;
  112777. + gctUINT timeout = 0;
  112778. +
  112779. + /* Loop while not idle. */
  112780. + while (Queue->pending)
  112781. + {
  112782. + /* Did we reach the timeout limit? */
  112783. + if (timeout == gcvQUEUE_TIMEOUT)
  112784. + {
  112785. + /* Hardware is probably dead... */
  112786. + return gcvSTATUS_TIMEOUT;
  112787. + }
  112788. +
  112789. + /* Sleep for 100ms. */
  112790. + gcmkERR_BREAK(gckOS_Delay(Command->os, 100));
  112791. +
  112792. + /* Not the first loop? */
  112793. + if (timeout > 0)
  112794. + {
  112795. + /* Read IDLE register. */
  112796. + gcmkVERIFY_OK(gckVGHARDWARE_GetIdle(Command->hardware, &idle));
  112797. +
  112798. + gcmkTRACE_ZONE(
  112799. + gcvLEVEL_ERROR, gcvZONE_COMMAND,
  112800. + "%s: timeout, IDLE=%08X\n",
  112801. + __FUNCTION__, idle
  112802. + );
  112803. + }
  112804. +
  112805. + /* Increment the timeout counter. */
  112806. + timeout += 1;
  112807. + }
  112808. +
  112809. + /* Return status. */
  112810. + return status;
  112811. +}
  112812. +
  112813. +static gctINT32
  112814. +_GetNextInterrupt(
  112815. + IN gckVGCOMMAND Command,
  112816. + IN gceBLOCK Block
  112817. + )
  112818. +{
  112819. + gctUINT index;
  112820. + gcsBLOCK_TASK_ENTRY_PTR entry;
  112821. + gctINT32 interrupt;
  112822. +
  112823. + /* Get the block entry. */
  112824. + entry = &Command->taskTable[Block];
  112825. +
  112826. + /* Make sure we have initialized interrupts. */
  112827. + gcmkASSERT(entry->interruptCount > 0);
  112828. +
  112829. + /* Decrement the interrupt usage semaphore. */
  112830. + gcmkVERIFY_OK(gckOS_DecrementSemaphore(
  112831. + Command->os, entry->interruptSemaphore
  112832. + ));
  112833. +
  112834. + /* Get the value index. */
  112835. + index = entry->interruptIndex;
  112836. +
  112837. + /* Get the interrupt value. */
  112838. + interrupt = entry->interruptArray[index];
  112839. +
  112840. + /* Must be a valid value. */
  112841. + gcmkASSERT((interrupt >= 0) && (interrupt <= 31));
  112842. +
  112843. + /* Advance the index to the next value. */
  112844. + index += 1;
  112845. +
  112846. + /* Set the new index. */
  112847. + entry->interruptIndex = (index == entry->interruptCount)
  112848. + ? 0
  112849. + : index;
  112850. +
  112851. + /* Return interrupt value. */
  112852. + return interrupt;
  112853. +}
  112854. +
  112855. +
  112856. +/******************************************************************************\
  112857. +***************************** Task Storage Management **************************
  112858. +\******************************************************************************/
  112859. +
  112860. +/* Minimum task buffer size. */
  112861. +#define gcvMIN_TASK_BUFFER \
  112862. +( \
  112863. + gcmSIZEOF(gcsTASK_CONTAINER) + 128 \
  112864. +)
  112865. +
  112866. +/* Free list terminator. */
  112867. +#define gcvFREE_TASK_TERMINATOR \
  112868. +( \
  112869. + (gcsTASK_CONTAINER_PTR) gcmINT2PTR(~0) \
  112870. +)
  112871. +
  112872. +
  112873. +/*----------------------------------------------------------------------------*/
  112874. +/*------------------- Allocated Task Buffer List Management ------------------*/
  112875. +
  112876. +static void
  112877. +_InsertTaskBuffer(
  112878. + IN gcsTASK_CONTAINER_PTR AddAfter,
  112879. + IN gcsTASK_CONTAINER_PTR Buffer
  112880. + )
  112881. +{
  112882. + gcsTASK_CONTAINER_PTR addBefore;
  112883. +
  112884. + /* Cannot add before the first buffer. */
  112885. + gcmkASSERT(AddAfter != gcvNULL);
  112886. +
  112887. + /* Create a shortcut to the next buffer. */
  112888. + addBefore = AddAfter->allocNext;
  112889. +
  112890. + /* Initialize the links. */
  112891. + Buffer->allocPrev = AddAfter;
  112892. + Buffer->allocNext = addBefore;
  112893. +
  112894. + /* Link to the previous buffer. */
  112895. + AddAfter->allocNext = Buffer;
  112896. +
  112897. + /* Link to the next buffer. */
  112898. + if (addBefore != gcvNULL)
  112899. + {
  112900. + addBefore->allocPrev = Buffer;
  112901. + }
  112902. +}
  112903. +
  112904. +static void
  112905. +_RemoveTaskBuffer(
  112906. + IN gcsTASK_CONTAINER_PTR Buffer
  112907. + )
  112908. +{
  112909. + gcsTASK_CONTAINER_PTR prev;
  112910. + gcsTASK_CONTAINER_PTR next;
  112911. +
  112912. + /* Cannot remove the first buffer. */
  112913. + gcmkASSERT(Buffer->allocPrev != gcvNULL);
  112914. +
  112915. + /* Create shortcuts to the previous and next buffers. */
  112916. + prev = Buffer->allocPrev;
  112917. + next = Buffer->allocNext;
  112918. +
  112919. + /* Tail buffer? */
  112920. + if (next == gcvNULL)
  112921. + {
  112922. + /* Remove from the list. */
  112923. + prev->allocNext = gcvNULL;
  112924. + }
  112925. +
  112926. + /* Buffer from the middle. */
  112927. + else
  112928. + {
  112929. + prev->allocNext = next;
  112930. + next->allocPrev = prev;
  112931. + }
  112932. +}
  112933. +
  112934. +
  112935. +/*----------------------------------------------------------------------------*/
  112936. +/*--------------------- Free Task Buffer List Management ---------------------*/
  112937. +
  112938. +static void
  112939. +_AppendToFreeList(
  112940. + IN gckVGCOMMAND Command,
  112941. + IN gcsTASK_CONTAINER_PTR Buffer
  112942. + )
  112943. +{
  112944. + /* Cannot be a part of the free list already. */
  112945. + gcmkASSERT(Buffer->freePrev == gcvNULL);
  112946. + gcmkASSERT(Buffer->freeNext == gcvNULL);
  112947. +
  112948. + /* First buffer to add? */
  112949. + if (Command->taskFreeHead == gcvNULL)
  112950. + {
  112951. + /* Terminate the links. */
  112952. + Buffer->freePrev = gcvFREE_TASK_TERMINATOR;
  112953. + Buffer->freeNext = gcvFREE_TASK_TERMINATOR;
  112954. +
  112955. + /* Initialize the list pointer. */
  112956. + Command->taskFreeHead = Command->taskFreeTail = Buffer;
  112957. + }
  112958. +
  112959. + /* Not the first, add after the tail. */
  112960. + else
  112961. + {
  112962. + /* Initialize the new tail buffer. */
  112963. + Buffer->freePrev = Command->taskFreeTail;
  112964. + Buffer->freeNext = gcvFREE_TASK_TERMINATOR;
  112965. +
  112966. + /* Add after the tail. */
  112967. + Command->taskFreeTail->freeNext = Buffer;
  112968. + Command->taskFreeTail = Buffer;
  112969. + }
  112970. +}
  112971. +
  112972. +static void
  112973. +_RemoveFromFreeList(
  112974. + IN gckVGCOMMAND Command,
  112975. + IN gcsTASK_CONTAINER_PTR Buffer
  112976. + )
  112977. +{
  112978. + /* Has to be a part of the free list. */
  112979. + gcmkASSERT(Buffer->freePrev != gcvNULL);
  112980. + gcmkASSERT(Buffer->freeNext != gcvNULL);
  112981. +
  112982. + /* Head buffer? */
  112983. + if (Buffer->freePrev == gcvFREE_TASK_TERMINATOR)
  112984. + {
  112985. + /* Tail buffer as well? */
  112986. + if (Buffer->freeNext == gcvFREE_TASK_TERMINATOR)
  112987. + {
  112988. + /* Reset the list pointer. */
  112989. + Command->taskFreeHead = Command->taskFreeTail = gcvNULL;
  112990. + }
  112991. +
  112992. + /* No, just the head. */
  112993. + else
  112994. + {
  112995. + /* Update the head. */
  112996. + Command->taskFreeHead = Buffer->freeNext;
  112997. +
  112998. + /* Terminate the next buffer. */
  112999. + Command->taskFreeHead->freePrev = gcvFREE_TASK_TERMINATOR;
  113000. + }
  113001. + }
  113002. +
  113003. + /* Not the head. */
  113004. + else
  113005. + {
  113006. + /* Tail buffer? */
  113007. + if (Buffer->freeNext == gcvFREE_TASK_TERMINATOR)
  113008. + {
  113009. + /* Update the tail. */
  113010. + Command->taskFreeTail = Buffer->freePrev;
  113011. +
  113012. + /* Terminate the previous buffer. */
  113013. + Command->taskFreeTail->freeNext = gcvFREE_TASK_TERMINATOR;
  113014. + }
  113015. +
  113016. + /* A buffer in the middle. */
  113017. + else
  113018. + {
  113019. + /* Remove the buffer from the list. */
  113020. + Buffer->freePrev->freeNext = Buffer->freeNext;
  113021. + Buffer->freeNext->freePrev = Buffer->freePrev;
  113022. + }
  113023. + }
  113024. +
  113025. + /* Reset free list pointers. */
  113026. + Buffer->freePrev = gcvNULL;
  113027. + Buffer->freeNext = gcvNULL;
  113028. +}
  113029. +
  113030. +
  113031. +/*----------------------------------------------------------------------------*/
  113032. +/*-------------------------- Task Buffer Allocation --------------------------*/
  113033. +
  113034. +static void
  113035. +_SplitTaskBuffer(
  113036. + IN gckVGCOMMAND Command,
  113037. + IN gcsTASK_CONTAINER_PTR Buffer,
  113038. + IN gctUINT Size
  113039. + )
  113040. +{
  113041. + /* Determine the size of the new buffer. */
  113042. + gctINT splitBufferSize = Buffer->size - Size;
  113043. + gcmkASSERT(splitBufferSize >= 0);
  113044. +
  113045. + /* Is the split buffer big enough to become a separate buffer? */
  113046. + if (splitBufferSize >= gcvMIN_TASK_BUFFER)
  113047. + {
  113048. + /* Place the new path data. */
  113049. + gcsTASK_CONTAINER_PTR splitBuffer = (gcsTASK_CONTAINER_PTR)
  113050. + (
  113051. + (gctUINT8_PTR) Buffer + Size
  113052. + );
  113053. +
  113054. + /* Set the trimmed buffer size. */
  113055. + Buffer->size = Size;
  113056. +
  113057. + /* Initialize the split buffer. */
  113058. + splitBuffer->referenceCount = 0;
  113059. + splitBuffer->size = splitBufferSize;
  113060. + splitBuffer->freePrev = gcvNULL;
  113061. + splitBuffer->freeNext = gcvNULL;
  113062. +
  113063. + /* Link in. */
  113064. + _InsertTaskBuffer(Buffer, splitBuffer);
  113065. + _AppendToFreeList(Command, splitBuffer);
  113066. + }
  113067. +}
  113068. +
  113069. +static gceSTATUS
  113070. +_AllocateTaskContainer(
  113071. + IN gckVGCOMMAND Command,
  113072. + IN gctUINT Size,
  113073. + OUT gcsTASK_CONTAINER_PTR * Buffer
  113074. + )
  113075. +{
  113076. + gceSTATUS status;
  113077. +
  113078. + gcmkHEADER_ARG("Command=0x%x Size=0x%x, Buffer ==0x%x", Command, Size, Buffer);
  113079. +
  113080. + /* Verify arguments. */
  113081. + gcmkVERIFY_ARGUMENT(Buffer != gcvNULL);
  113082. +
  113083. + do
  113084. + {
  113085. + gcsTASK_STORAGE_PTR storage;
  113086. + gcsTASK_CONTAINER_PTR buffer;
  113087. +
  113088. + /* Adjust the size. */
  113089. + Size += gcmSIZEOF(gcsTASK_CONTAINER);
  113090. +
  113091. + /* Adjust the allocation size if not big enough. */
  113092. + if (Size > Command->taskStorageUsable)
  113093. + {
  113094. + Command->taskStorageGranularity
  113095. + = gcmALIGN(Size + gcmSIZEOF(gcsTASK_STORAGE), 1024);
  113096. +
  113097. + Command->taskStorageUsable
  113098. + = Command->taskStorageGranularity - gcmSIZEOF(gcsTASK_STORAGE);
  113099. + }
  113100. +
  113101. + /* Is there a free buffer available? */
  113102. + else if (Command->taskFreeHead != gcvNULL)
  113103. + {
  113104. + /* Set the initial free buffer. */
  113105. + gcsTASK_CONTAINER_PTR buffer = Command->taskFreeHead;
  113106. +
  113107. + do
  113108. + {
  113109. + /* Is the buffer big enough? */
  113110. + if (buffer->size >= Size)
  113111. + {
  113112. + /* Remove the buffer from the free list. */
  113113. + _RemoveFromFreeList(Command, buffer);
  113114. +
  113115. + /* Split the buffer. */
  113116. + _SplitTaskBuffer(Command, buffer, Size);
  113117. +
  113118. + /* Set the result. */
  113119. + * Buffer = buffer;
  113120. +
  113121. + gcmkFOOTER_ARG("*Buffer=0x%x",*Buffer);
  113122. + /* Success. */
  113123. + return gcvSTATUS_OK;
  113124. + }
  113125. +
  113126. + /* Get the next free buffer. */
  113127. + buffer = buffer->freeNext;
  113128. + }
  113129. + while (buffer != gcvFREE_TASK_TERMINATOR);
  113130. + }
  113131. +
  113132. + /* Allocate a container. */
  113133. + gcmkERR_BREAK(gckOS_Allocate(
  113134. + Command->os,
  113135. + Command->taskStorageGranularity,
  113136. + (gctPOINTER *) &storage
  113137. + ));
  113138. +
  113139. + /* Link in the storage buffer. */
  113140. + storage->next = Command->taskStorage;
  113141. + Command->taskStorage = storage;
  113142. +
  113143. + /* Place the task buffer. */
  113144. + buffer = (gcsTASK_CONTAINER_PTR) (storage + 1);
  113145. +
  113146. + /* Determine the size of the buffer. */
  113147. + buffer->size
  113148. + = Command->taskStorageGranularity
  113149. + - gcmSIZEOF(gcsTASK_STORAGE);
  113150. +
  113151. + /* Initialize the task buffer. */
  113152. + buffer->referenceCount = 0;
  113153. + buffer->allocPrev = gcvNULL;
  113154. + buffer->allocNext = gcvNULL;
  113155. + buffer->freePrev = gcvNULL;
  113156. + buffer->freeNext = gcvNULL;
  113157. +
  113158. + /* Split the buffer. */
  113159. + _SplitTaskBuffer(Command, buffer, Size);
  113160. +
  113161. + /* Set the result. */
  113162. + * Buffer = buffer;
  113163. +
  113164. + gcmkFOOTER_ARG("*Buffer=0x%x",*Buffer);
  113165. + /* Success. */
  113166. + return gcvSTATUS_OK;
  113167. + }
  113168. + while (gcvFALSE);
  113169. +
  113170. + gcmkFOOTER();
  113171. + /* Return status. */
  113172. + return status;
  113173. +}
  113174. +
  113175. +static void
  113176. +_FreeTaskContainer(
  113177. + IN gckVGCOMMAND Command,
  113178. + IN gcsTASK_CONTAINER_PTR Buffer
  113179. + )
  113180. +{
  113181. + gcsTASK_CONTAINER_PTR prev;
  113182. + gcsTASK_CONTAINER_PTR next;
  113183. + gcsTASK_CONTAINER_PTR merged;
  113184. +
  113185. + gctSIZE_T mergedSize;
  113186. +
  113187. + /* Verify arguments. */
  113188. + gcmkASSERT(Buffer != gcvNULL);
  113189. + gcmkASSERT(Buffer->freePrev == gcvNULL);
  113190. + gcmkASSERT(Buffer->freeNext == gcvNULL);
  113191. +
  113192. + /* Get shortcuts to the previous and next path data buffers. */
  113193. + prev = Buffer->allocPrev;
  113194. + next = Buffer->allocNext;
  113195. +
  113196. + /* Is the previous path data buffer already free? */
  113197. + if (prev && prev->freeNext)
  113198. + {
  113199. + /* The previous path data buffer is the one that remains. */
  113200. + merged = prev;
  113201. +
  113202. + /* Is the next path data buffer already free? */
  113203. + if (next && next->freeNext)
  113204. + {
  113205. + /* Merge all three path data buffers into the previous. */
  113206. + mergedSize = prev->size + Buffer->size + next->size;
  113207. +
  113208. + /* Remove the next path data buffer. */
  113209. + _RemoveFromFreeList(Command, next);
  113210. + _RemoveTaskBuffer(next);
  113211. + }
  113212. + else
  113213. + {
  113214. + /* Merge the current path data buffer into the previous. */
  113215. + mergedSize = prev->size + Buffer->size;
  113216. + }
  113217. +
  113218. + /* Delete the current path data buffer. */
  113219. + _RemoveTaskBuffer(Buffer);
  113220. +
  113221. + /* Set new size. */
  113222. + merged->size = mergedSize;
  113223. + }
  113224. + else
  113225. + {
  113226. + /* The current path data buffer is the one that remains. */
  113227. + merged = Buffer;
  113228. +
  113229. + /* Is the next buffer already free? */
  113230. + if (next && next->freeNext)
  113231. + {
  113232. + /* Merge the next into the current. */
  113233. + mergedSize = Buffer->size + next->size;
  113234. +
  113235. + /* Remove the next buffer. */
  113236. + _RemoveFromFreeList(Command, next);
  113237. + _RemoveTaskBuffer(next);
  113238. +
  113239. + /* Set new size. */
  113240. + merged->size = mergedSize;
  113241. + }
  113242. +
  113243. + /* Add the current buffer into the free list. */
  113244. + _AppendToFreeList(Command, merged);
  113245. + }
  113246. +}
  113247. +
  113248. +gceSTATUS
  113249. +_RemoveRecordFromProcesDB(
  113250. + IN gckVGCOMMAND Command,
  113251. + IN gcsTASK_HEADER_PTR Task
  113252. + )
  113253. +{
  113254. + gcsTASK_PTR task = (gcsTASK_PTR)((gctUINT8_PTR)Task - sizeof(gcsTASK));
  113255. + gcsTASK_FREE_VIDEO_MEMORY_PTR freeVideoMemory;
  113256. + gcsTASK_UNLOCK_VIDEO_MEMORY_PTR unlockVideoMemory;
  113257. + gctINT pid;
  113258. + gctUINT32 size;
  113259. +
  113260. + /* Get the total size of all tasks. */
  113261. + size = task->size;
  113262. +
  113263. + gcmkVERIFY_OK(gckOS_GetProcessID((gctUINT32_PTR)&pid));
  113264. +
  113265. + do
  113266. + {
  113267. + switch (Task->id)
  113268. + {
  113269. + case gcvTASK_FREE_VIDEO_MEMORY:
  113270. + freeVideoMemory = (gcsTASK_FREE_VIDEO_MEMORY_PTR)Task;
  113271. +
  113272. + /* Remove record from process db. */
  113273. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  113274. + Command->kernel->kernel,
  113275. + pid,
  113276. + gcvDB_VIDEO_MEMORY,
  113277. + gcmUINT64_TO_PTR(freeVideoMemory->node)));
  113278. +
  113279. + /* Advance to next task. */
  113280. + size -= sizeof(gcsTASK_FREE_VIDEO_MEMORY);
  113281. + Task = (gcsTASK_HEADER_PTR)(freeVideoMemory + 1);
  113282. +
  113283. + break;
  113284. + case gcvTASK_UNLOCK_VIDEO_MEMORY:
  113285. + unlockVideoMemory = (gcsTASK_UNLOCK_VIDEO_MEMORY_PTR)Task;
  113286. +
  113287. + /* Remove record from process db. */
  113288. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  113289. + Command->kernel->kernel,
  113290. + pid,
  113291. + gcvDB_VIDEO_MEMORY_LOCKED,
  113292. + gcmUINT64_TO_PTR(unlockVideoMemory->node)));
  113293. +
  113294. + /* Advance to next task. */
  113295. + size -= sizeof(gcsTASK_UNLOCK_VIDEO_MEMORY);
  113296. + Task = (gcsTASK_HEADER_PTR)(unlockVideoMemory + 1);
  113297. +
  113298. + break;
  113299. + default:
  113300. + /* Skip the whole task. */
  113301. + size = 0;
  113302. + break;
  113303. + }
  113304. + }
  113305. + while(size);
  113306. +
  113307. + return gcvSTATUS_OK;
  113308. +}
  113309. +
  113310. +/******************************************************************************\
  113311. +********************************* Task Scheduling ******************************
  113312. +\******************************************************************************/
  113313. +
  113314. +static gceSTATUS
  113315. +_ScheduleTasks(
  113316. + IN gckVGCOMMAND Command,
  113317. + IN gcsTASK_MASTER_TABLE_PTR TaskTable,
  113318. + IN gctUINT8_PTR PreviousEnd
  113319. + )
  113320. +{
  113321. + gceSTATUS status;
  113322. +
  113323. + do
  113324. + {
  113325. + gctINT block;
  113326. + gcsTASK_CONTAINER_PTR container;
  113327. + gcsTASK_MASTER_ENTRY_PTR userTaskEntry;
  113328. + gcsBLOCK_TASK_ENTRY_PTR kernelTaskEntry;
  113329. + gcsTASK_PTR userTask;
  113330. + gctUINT8_PTR kernelTask;
  113331. + gctINT32 interrupt;
  113332. + gctUINT8_PTR eventCommand;
  113333. +
  113334. + /* Nothing to schedule? */
  113335. + if (TaskTable->size == 0)
  113336. + {
  113337. + status = gcvSTATUS_OK;
  113338. + break;
  113339. + }
  113340. +
  113341. + /* Acquire the mutex. */
  113342. + gcmkERR_BREAK(gckOS_AcquireMutex(
  113343. + Command->os,
  113344. + Command->taskMutex,
  113345. + gcvINFINITE
  113346. + ));
  113347. +
  113348. + gcmkTRACE_ZONE(
  113349. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113350. + "%s(%d)\n",
  113351. + __FUNCTION__, __LINE__
  113352. + );
  113353. +
  113354. + do
  113355. + {
  113356. + gcmkTRACE_ZONE(
  113357. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113358. + " number of tasks scheduled = %d\n"
  113359. + " size of event data in bytes = %d\n",
  113360. + TaskTable->count,
  113361. + TaskTable->size
  113362. + );
  113363. +
  113364. + /* Allocate task buffer. */
  113365. + gcmkERR_BREAK(_AllocateTaskContainer(
  113366. + Command,
  113367. + TaskTable->size,
  113368. + &container
  113369. + ));
  113370. +
  113371. + /* Determine the task data pointer. */
  113372. + kernelTask = (gctUINT8_PTR) (container + 1);
  113373. +
  113374. + /* Initialize the reference count. */
  113375. + container->referenceCount = TaskTable->count;
  113376. +
  113377. + /* Process tasks. */
  113378. + for (block = gcvBLOCK_COUNT - 1; block >= 0; block -= 1)
  113379. + {
  113380. + /* Get the current user table entry. */
  113381. + userTaskEntry = &TaskTable->table[block];
  113382. +
  113383. + /* Are there tasks scheduled? */
  113384. + if (userTaskEntry->head == gcvNULL)
  113385. + {
  113386. + /* No, skip to the next block. */
  113387. + continue;
  113388. + }
  113389. +
  113390. + gcmkTRACE_ZONE(
  113391. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113392. + " processing tasks for block %d\n",
  113393. + block
  113394. + );
  113395. +
  113396. + /* Get the current kernel table entry. */
  113397. + kernelTaskEntry = &Command->taskTable[block];
  113398. +
  113399. + /* Are there tasks for the current block scheduled? */
  113400. + if (kernelTaskEntry->container == gcvNULL)
  113401. + {
  113402. + gcmkTRACE_ZONE(
  113403. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113404. + " first task container for the block added\n",
  113405. + block
  113406. + );
  113407. +
  113408. + /* Nothing yet, set the container buffer pointer. */
  113409. + kernelTaskEntry->container = container;
  113410. + kernelTaskEntry->task = (gcsTASK_HEADER_PTR) kernelTask;
  113411. + }
  113412. +
  113413. + /* Yes, append to the end. */
  113414. + else
  113415. + {
  113416. + kernelTaskEntry->link->cotainer = container;
  113417. + kernelTaskEntry->link->task = (gcsTASK_HEADER_PTR) kernelTask;
  113418. + }
  113419. +
  113420. + /* Set initial task. */
  113421. + userTask = userTaskEntry->head;
  113422. +
  113423. + gcmkTRACE_ZONE(
  113424. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113425. + " copying user tasks over to the kernel\n"
  113426. + );
  113427. +
  113428. + /* Copy tasks. */
  113429. + do
  113430. + {
  113431. + gcsTASK_HEADER_PTR taskHeader = (gcsTASK_HEADER_PTR) (userTask + 1);
  113432. +
  113433. + gcmkVERIFY_OK(_RemoveRecordFromProcesDB(Command, taskHeader));
  113434. +
  113435. + gcmkTRACE_ZONE(
  113436. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113437. + " task ID = %d, size = %d\n",
  113438. + ((gcsTASK_HEADER_PTR) (userTask + 1))->id,
  113439. + userTask->size
  113440. + );
  113441. +
  113442. +#ifdef __QNXNTO__
  113443. + if (taskHeader->id == gcvTASK_SIGNAL)
  113444. + {
  113445. + ((gcsTASK_SIGNAL_PTR)taskHeader)->coid = TaskTable->coid;
  113446. + ((gcsTASK_SIGNAL_PTR)taskHeader)->rcvid = TaskTable->rcvid;
  113447. + }
  113448. +#endif /* __QNXNTO__ */
  113449. + /* Copy the task data. */
  113450. + gcmkVERIFY_OK(gckOS_MemCopy(
  113451. + kernelTask, taskHeader, userTask->size
  113452. + ));
  113453. +
  113454. + /* Advance to the next task. */
  113455. + kernelTask += userTask->size;
  113456. + userTask = userTask->next;
  113457. + }
  113458. + while (userTask != gcvNULL);
  113459. +
  113460. + /* Update link pointer in the header. */
  113461. + kernelTaskEntry->link = (gcsTASK_LINK_PTR) kernelTask;
  113462. +
  113463. + /* Initialize link task. */
  113464. + kernelTaskEntry->link->id = gcvTASK_LINK;
  113465. + kernelTaskEntry->link->cotainer = gcvNULL;
  113466. + kernelTaskEntry->link->task = gcvNULL;
  113467. +
  113468. + /* Advance the task data pointer. */
  113469. + kernelTask += gcmSIZEOF(gcsTASK_LINK);
  113470. + }
  113471. + }
  113472. + while (gcvFALSE);
  113473. +
  113474. + /* Release the mutex. */
  113475. + gcmkERR_BREAK(gckOS_ReleaseMutex(
  113476. + Command->os,
  113477. + Command->taskMutex
  113478. + ));
  113479. +
  113480. + /* Assign interrupts to the blocks. */
  113481. + eventCommand = PreviousEnd;
  113482. +
  113483. + for (block = gcvBLOCK_COUNT - 1; block >= 0; block -= 1)
  113484. + {
  113485. + /* Get the current user table entry. */
  113486. + userTaskEntry = &TaskTable->table[block];
  113487. +
  113488. + /* Are there tasks scheduled? */
  113489. + if (userTaskEntry->head == gcvNULL)
  113490. + {
  113491. + /* No, skip to the next block. */
  113492. + continue;
  113493. + }
  113494. +
  113495. + /* Get the interrupt number. */
  113496. + interrupt = _GetNextInterrupt(Command, block);
  113497. +
  113498. + gcmkTRACE_ZONE(
  113499. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113500. + "%s(%d): block = %d interrupt = %d\n",
  113501. + __FUNCTION__, __LINE__,
  113502. + block, interrupt
  113503. + );
  113504. +
  113505. + /* Determine the command position. */
  113506. + eventCommand -= Command->info.eventCommandSize;
  113507. +
  113508. + /* Append an EVENT command. */
  113509. + gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
  113510. + Command, eventCommand, block, interrupt, gcvNULL
  113511. + ));
  113512. + }
  113513. + }
  113514. + while (gcvFALSE);
  113515. +
  113516. + /* Return status. */
  113517. + return status;
  113518. +}
  113519. +
  113520. +
  113521. +/******************************************************************************\
  113522. +******************************** Memory Management *****************************
  113523. +\******************************************************************************/
  113524. +
  113525. +static gceSTATUS
  113526. +_HardwareToKernel(
  113527. + IN gckOS Os,
  113528. + IN gcuVIDMEM_NODE_PTR Node,
  113529. + IN gctUINT32 Address,
  113530. + OUT gctPOINTER * KernelPointer
  113531. + )
  113532. +{
  113533. + gceSTATUS status;
  113534. + gckVIDMEM memory;
  113535. + gctUINT32 offset;
  113536. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY
  113537. + gctUINT32 nodePhysical;
  113538. +#endif
  113539. + status = gcvSTATUS_OK;
  113540. + /* Assume a non-virtual node and get the pool manager object. */
  113541. + memory = Node->VidMem.memory;
  113542. +
  113543. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY
  113544. + nodePhysical = memory->baseAddress
  113545. + + Node->VidMem.offset
  113546. + + Node->VidMem.alignment;
  113547. +
  113548. + if (Node->VidMem.kernelVirtual == gcvNULL)
  113549. + {
  113550. + status = gckOS_MapPhysical(Os,
  113551. + nodePhysical,
  113552. + Node->VidMem.bytes,
  113553. + (gctPOINTER *)&Node->VidMem.kernelVirtual);
  113554. +
  113555. + if (gcmkIS_ERROR(status))
  113556. + {
  113557. + return status;
  113558. + }
  113559. + }
  113560. +
  113561. + offset = Address - nodePhysical;
  113562. + *KernelPointer = (gctPOINTER)((gctUINT8_PTR)Node->VidMem.kernelVirtual + offset);
  113563. +#else
  113564. + /* Determine the header offset within the pool it is allocated in. */
  113565. + offset = Address - memory->baseAddress;
  113566. +
  113567. + /* Translate the offset into the kernel side pointer. */
  113568. + status = gckOS_GetKernelLogicalEx(
  113569. + Os,
  113570. + gcvCORE_VG,
  113571. + offset,
  113572. + KernelPointer
  113573. + );
  113574. +#endif
  113575. +
  113576. + /* Return status. */
  113577. + return status;
  113578. +}
  113579. +
  113580. +static gceSTATUS
  113581. +_ConvertUserCommandBufferPointer(
  113582. + IN gckVGCOMMAND Command,
  113583. + IN gcsCMDBUFFER_PTR UserCommandBuffer,
  113584. + OUT gcsCMDBUFFER_PTR * KernelCommandBuffer
  113585. + )
  113586. +{
  113587. + gceSTATUS status, last;
  113588. + gcsCMDBUFFER_PTR mappedUserCommandBuffer = gcvNULL;
  113589. +
  113590. + do
  113591. + {
  113592. + gctUINT32 headerAddress;
  113593. +
  113594. + /* Map the command buffer structure into the kernel space. */
  113595. + gcmkERR_BREAK(gckOS_MapUserPointer(
  113596. + Command->os,
  113597. + UserCommandBuffer,
  113598. + gcmSIZEOF(gcsCMDBUFFER),
  113599. + (gctPOINTER *) &mappedUserCommandBuffer
  113600. + ));
  113601. +
  113602. + /* Determine the address of the header. */
  113603. + headerAddress
  113604. + = mappedUserCommandBuffer->address
  113605. + - mappedUserCommandBuffer->bufferOffset;
  113606. +
  113607. + /* Translate the logical address to the kernel space. */
  113608. + gcmkERR_BREAK(_HardwareToKernel(
  113609. + Command->os,
  113610. + gcmUINT64_TO_PTR(mappedUserCommandBuffer->node),
  113611. + headerAddress,
  113612. + (gctPOINTER *) KernelCommandBuffer
  113613. + ));
  113614. + }
  113615. + while (gcvFALSE);
  113616. +
  113617. + /* Unmap the user command buffer. */
  113618. + if (mappedUserCommandBuffer != gcvNULL)
  113619. + {
  113620. + gcmkCHECK_STATUS(gckOS_UnmapUserPointer(
  113621. + Command->os,
  113622. + UserCommandBuffer,
  113623. + gcmSIZEOF(gcsCMDBUFFER),
  113624. + mappedUserCommandBuffer
  113625. + ));
  113626. + }
  113627. +
  113628. + /* Return status. */
  113629. + return status;
  113630. +}
  113631. +
  113632. +static gceSTATUS
  113633. +_AllocateLinear(
  113634. + IN gckVGCOMMAND Command,
  113635. + IN gctUINT Size,
  113636. + IN gctUINT Alignment,
  113637. + OUT gcuVIDMEM_NODE_PTR * Node,
  113638. + OUT gctUINT32 * Address,
  113639. + OUT gctPOINTER * Logical
  113640. + )
  113641. +{
  113642. + gceSTATUS status, last;
  113643. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  113644. + gctUINT32 address = (gctUINT32)~0;
  113645. +
  113646. + do
  113647. + {
  113648. + gcePOOL pool;
  113649. + gctPOINTER logical;
  113650. +
  113651. + /* Allocate from the system pool. */
  113652. + pool = gcvPOOL_SYSTEM;
  113653. +
  113654. + /* Allocate memory. */
  113655. + gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
  113656. + Command->kernel->kernel, &pool,
  113657. + Size, Alignment,
  113658. + gcvSURF_TYPE_UNKNOWN,
  113659. + &node
  113660. + ));
  113661. +
  113662. + /* Do not accept virtual pools for now because we don't handle the
  113663. + kernel pointer translation at the moment. */
  113664. + if (pool == gcvPOOL_VIRTUAL)
  113665. + {
  113666. + status = gcvSTATUS_OUT_OF_MEMORY;
  113667. + break;
  113668. + }
  113669. +
  113670. + /* Lock the command buffer. */
  113671. + gcmkERR_BREAK(gckVIDMEM_Lock(
  113672. + Command->kernel->kernel,
  113673. + node,
  113674. + gcvFALSE,
  113675. + &address
  113676. + ));
  113677. +
  113678. + /* Translate the logical address to the kernel space. */
  113679. + gcmkERR_BREAK(_HardwareToKernel(
  113680. + Command->os,
  113681. + node,
  113682. + address,
  113683. + &logical
  113684. + ));
  113685. +
  113686. + /* Set return values. */
  113687. + * Node = node;
  113688. + * Address = address;
  113689. + * Logical = logical;
  113690. +
  113691. + /* Success. */
  113692. + return gcvSTATUS_OK;
  113693. + }
  113694. + while (gcvFALSE);
  113695. +
  113696. + /* Roll back. */
  113697. + if (node != gcvNULL)
  113698. + {
  113699. + /* Unlock the command buffer. */
  113700. + if (address != ~0)
  113701. + {
  113702. + gcmkCHECK_STATUS(gckVIDMEM_Unlock(
  113703. + Command->kernel->kernel, node, gcvSURF_TYPE_UNKNOWN, gcvNULL
  113704. + ));
  113705. + }
  113706. +
  113707. + /* Free the command buffer. */
  113708. + gcmkCHECK_STATUS(gckVIDMEM_Free(
  113709. + node
  113710. + ));
  113711. + }
  113712. +
  113713. + /* Return status. */
  113714. + return status;
  113715. +}
  113716. +
  113717. +static gceSTATUS
  113718. +_FreeLinear(
  113719. + IN gckVGKERNEL Kernel,
  113720. + IN gcuVIDMEM_NODE_PTR Node
  113721. + )
  113722. +{
  113723. + gceSTATUS status;
  113724. +
  113725. + do
  113726. + {
  113727. + /* Unlock the linear buffer. */
  113728. + gcmkERR_BREAK(gckVIDMEM_Unlock(Kernel->kernel, Node, gcvSURF_TYPE_UNKNOWN, gcvNULL));
  113729. +
  113730. + /* Free the linear buffer. */
  113731. + gcmkERR_BREAK(gckVIDMEM_Free(Node));
  113732. + }
  113733. + while (gcvFALSE);
  113734. +
  113735. + /* Return status. */
  113736. + return status;
  113737. +}
  113738. +
  113739. +gceSTATUS
  113740. +_AllocateCommandBuffer(
  113741. + IN gckVGCOMMAND Command,
  113742. + IN gctSIZE_T Size,
  113743. + OUT gcsCMDBUFFER_PTR * CommandBuffer
  113744. + )
  113745. +{
  113746. + gceSTATUS status, last;
  113747. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  113748. +
  113749. + do
  113750. + {
  113751. + gctUINT alignedHeaderSize;
  113752. + gctUINT requestedSize;
  113753. + gctUINT allocationSize;
  113754. + gctUINT32 address = 0;
  113755. + gcsCMDBUFFER_PTR commandBuffer;
  113756. + gctUINT8_PTR endCommand;
  113757. +
  113758. + /* Determine the aligned header size. */
  113759. + alignedHeaderSize
  113760. + = gcmALIGN(gcmSIZEOF(gcsCMDBUFFER), Command->info.addressAlignment);
  113761. +
  113762. + /* Align the requested size. */
  113763. + requestedSize
  113764. + = gcmALIGN(Size, Command->info.commandAlignment);
  113765. +
  113766. + /* Determine the size of the buffer to allocate. */
  113767. + allocationSize
  113768. + = alignedHeaderSize
  113769. + + requestedSize
  113770. + + Command->info.staticTailSize;
  113771. +
  113772. + /* Allocate the command buffer. */
  113773. + gcmkERR_BREAK(_AllocateLinear(
  113774. + Command,
  113775. + allocationSize,
  113776. + Command->info.addressAlignment,
  113777. + &node,
  113778. + &address,
  113779. + (gctPOINTER *) &commandBuffer
  113780. + ));
  113781. +
  113782. + /* Initialize the structure. */
  113783. + commandBuffer->completion = gcvVACANT_BUFFER;
  113784. + commandBuffer->node = gcmPTR_TO_UINT64(node);
  113785. + commandBuffer->address = address + alignedHeaderSize;
  113786. + commandBuffer->bufferOffset = alignedHeaderSize;
  113787. + commandBuffer->size = requestedSize;
  113788. + commandBuffer->offset = requestedSize;
  113789. + commandBuffer->nextAllocated = gcvNULL;
  113790. + commandBuffer->nextSubBuffer = gcvNULL;
  113791. +
  113792. + /* Determine the data count. */
  113793. + commandBuffer->dataCount
  113794. + = (requestedSize + Command->info.staticTailSize)
  113795. + / Command->info.commandAlignment;
  113796. +
  113797. + /* Determine the location of the END command. */
  113798. + endCommand
  113799. + = (gctUINT8_PTR) commandBuffer
  113800. + + alignedHeaderSize
  113801. + + requestedSize;
  113802. +
  113803. + /* Append an END command. */
  113804. + gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
  113805. + Command,
  113806. + endCommand,
  113807. + Command->info.feBufferInt,
  113808. + gcvNULL
  113809. + ));
  113810. +
  113811. + /* Set the return pointer. */
  113812. + * CommandBuffer = commandBuffer;
  113813. +
  113814. + /* Success. */
  113815. + return gcvSTATUS_OK;
  113816. + }
  113817. + while (gcvFALSE);
  113818. +
  113819. + /* Roll back. */
  113820. + if (node != gcvNULL)
  113821. + {
  113822. + /* Free the command buffer. */
  113823. + gcmkCHECK_STATUS(_FreeLinear(Command->kernel, node));
  113824. + }
  113825. +
  113826. + /* Return status. */
  113827. + return status;
  113828. +}
  113829. +
  113830. +static gceSTATUS
  113831. +_FreeCommandBuffer(
  113832. + IN gckVGKERNEL Kernel,
  113833. + IN gcsCMDBUFFER_PTR CommandBuffer
  113834. + )
  113835. +{
  113836. + gceSTATUS status;
  113837. +
  113838. + /* Free the buffer. */
  113839. + status = _FreeLinear(Kernel, gcmUINT64_TO_PTR(CommandBuffer->node));
  113840. +
  113841. + /* Return status. */
  113842. + return status;
  113843. +}
  113844. +
  113845. +
  113846. +/******************************************************************************\
  113847. +****************************** TS Overflow Handler *****************************
  113848. +\******************************************************************************/
  113849. +
  113850. +static gceSTATUS
  113851. +_EventHandler_TSOverflow(
  113852. + IN gckVGKERNEL Kernel
  113853. + )
  113854. +{
  113855. + gcmkTRACE(
  113856. + gcvLEVEL_ERROR,
  113857. + "%s(%d): **** TS OVERFLOW ENCOUNTERED ****\n",
  113858. + __FUNCTION__, __LINE__
  113859. + );
  113860. +
  113861. + return gcvSTATUS_OK;
  113862. +}
  113863. +
  113864. +
  113865. +/******************************************************************************\
  113866. +****************************** Bus Error Handler *******************************
  113867. +\******************************************************************************/
  113868. +
  113869. +static gceSTATUS
  113870. +_EventHandler_BusError(
  113871. + IN gckVGKERNEL Kernel
  113872. + )
  113873. +{
  113874. + gcmkTRACE(
  113875. + gcvLEVEL_ERROR,
  113876. + "%s(%d): **** BUS ERROR ENCOUNTERED ****\n",
  113877. + __FUNCTION__, __LINE__
  113878. + );
  113879. +
  113880. + return gcvSTATUS_OK;
  113881. +}
  113882. +
  113883. +/******************************************************************************\
  113884. +****************************** Power Stall Handler *******************************
  113885. +\******************************************************************************/
  113886. +
  113887. +static gceSTATUS
  113888. +_EventHandler_PowerStall(
  113889. + IN gckVGKERNEL Kernel
  113890. + )
  113891. +{
  113892. + /* Signal. */
  113893. + return gckOS_Signal(
  113894. + Kernel->os,
  113895. + Kernel->command->powerStallSignal,
  113896. + gcvTRUE);
  113897. +}
  113898. +
  113899. +/******************************************************************************\
  113900. +******************************** Task Routines *********************************
  113901. +\******************************************************************************/
  113902. +
  113903. +typedef gceSTATUS (* gctTASKROUTINE) (
  113904. + gckVGCOMMAND Command,
  113905. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113906. + );
  113907. +
  113908. +static gceSTATUS
  113909. +_TaskLink(
  113910. + gckVGCOMMAND Command,
  113911. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113912. + );
  113913. +
  113914. +static gceSTATUS
  113915. +_TaskCluster(
  113916. + gckVGCOMMAND Command,
  113917. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113918. + );
  113919. +
  113920. +static gceSTATUS
  113921. +_TaskIncrement(
  113922. + gckVGCOMMAND Command,
  113923. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113924. + );
  113925. +
  113926. +static gceSTATUS
  113927. +_TaskDecrement(
  113928. + gckVGCOMMAND Command,
  113929. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113930. + );
  113931. +
  113932. +static gceSTATUS
  113933. +_TaskSignal(
  113934. + gckVGCOMMAND Command,
  113935. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113936. + );
  113937. +
  113938. +static gceSTATUS
  113939. +_TaskLockdown(
  113940. + gckVGCOMMAND Command,
  113941. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113942. + );
  113943. +
  113944. +static gceSTATUS
  113945. +_TaskUnlockVideoMemory(
  113946. + gckVGCOMMAND Command,
  113947. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113948. + );
  113949. +
  113950. +static gceSTATUS
  113951. +_TaskFreeVideoMemory(
  113952. + gckVGCOMMAND Command,
  113953. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113954. + );
  113955. +
  113956. +static gceSTATUS
  113957. +_TaskFreeContiguousMemory(
  113958. + gckVGCOMMAND Command,
  113959. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113960. + );
  113961. +
  113962. +static gceSTATUS
  113963. +_TaskUnmapUserMemory(
  113964. + gckVGCOMMAND Command,
  113965. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113966. + );
  113967. +
  113968. +static gctTASKROUTINE _taskRoutine[] =
  113969. +{
  113970. + _TaskLink, /* gcvTASK_LINK */
  113971. + _TaskCluster, /* gcvTASK_CLUSTER */
  113972. + _TaskIncrement, /* gcvTASK_INCREMENT */
  113973. + _TaskDecrement, /* gcvTASK_DECREMENT */
  113974. + _TaskSignal, /* gcvTASK_SIGNAL */
  113975. + _TaskLockdown, /* gcvTASK_LOCKDOWN */
  113976. + _TaskUnlockVideoMemory, /* gcvTASK_UNLOCK_VIDEO_MEMORY */
  113977. + _TaskFreeVideoMemory, /* gcvTASK_FREE_VIDEO_MEMORY */
  113978. + _TaskFreeContiguousMemory, /* gcvTASK_FREE_CONTIGUOUS_MEMORY */
  113979. + _TaskUnmapUserMemory, /* gcvTASK_UNMAP_USER_MEMORY */
  113980. +};
  113981. +
  113982. +static gceSTATUS
  113983. +_TaskLink(
  113984. + gckVGCOMMAND Command,
  113985. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113986. + )
  113987. +{
  113988. + /* Cast the task pointer. */
  113989. + gcsTASK_LINK_PTR task = (gcsTASK_LINK_PTR) TaskHeader->task;
  113990. +
  113991. + /* Save the pointer to the container. */
  113992. + gcsTASK_CONTAINER_PTR container = TaskHeader->container;
  113993. +
  113994. + /* No more tasks in the list? */
  113995. + if (task->task == gcvNULL)
  113996. + {
  113997. + /* Reset the entry. */
  113998. + TaskHeader->container = gcvNULL;
  113999. + TaskHeader->task = gcvNULL;
  114000. + TaskHeader->link = gcvNULL;
  114001. + }
  114002. + else
  114003. + {
  114004. + /* Update the entry. */
  114005. + TaskHeader->container = task->cotainer;
  114006. + TaskHeader->task = task->task;
  114007. + }
  114008. +
  114009. + /* Decrement the task buffer reference. */
  114010. + gcmkASSERT(container->referenceCount >= 0);
  114011. + if (container->referenceCount == 0)
  114012. + {
  114013. + /* Free the container. */
  114014. + _FreeTaskContainer(Command, container);
  114015. + }
  114016. +
  114017. + /* Success. */
  114018. + return gcvSTATUS_OK;
  114019. +}
  114020. +
  114021. +static gceSTATUS
  114022. +_TaskCluster(
  114023. + gckVGCOMMAND Command,
  114024. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114025. + )
  114026. +{
  114027. + gceSTATUS status = gcvSTATUS_OK;
  114028. +
  114029. + /* Cast the task pointer. */
  114030. + gcsTASK_CLUSTER_PTR cluster = (gcsTASK_CLUSTER_PTR) TaskHeader->task;
  114031. +
  114032. + /* Get the number of tasks. */
  114033. + gctUINT taskCount = cluster->taskCount;
  114034. +
  114035. + /* Advance to the next task. */
  114036. + TaskHeader->task = (gcsTASK_HEADER_PTR) (cluster + 1);
  114037. +
  114038. + /* Perform all tasks in the cluster. */
  114039. + while (taskCount)
  114040. + {
  114041. + /* Perform the current task. */
  114042. + gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
  114043. + Command,
  114044. + TaskHeader
  114045. + ));
  114046. +
  114047. + /* Update the task count. */
  114048. + taskCount -= 1;
  114049. + }
  114050. +
  114051. + /* Return status. */
  114052. + return status;
  114053. +}
  114054. +
  114055. +static gceSTATUS
  114056. +_TaskIncrement(
  114057. + gckVGCOMMAND Command,
  114058. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114059. + )
  114060. +{
  114061. + gceSTATUS status;
  114062. +
  114063. + do
  114064. + {
  114065. + /* Cast the task pointer. */
  114066. + gcsTASK_INCREMENT_PTR task = (gcsTASK_INCREMENT_PTR) TaskHeader->task;
  114067. +
  114068. + /* Convert physical into logical address. */
  114069. + gctUINT32_PTR logical;
  114070. + gcmkERR_BREAK(gckOS_MapPhysical(
  114071. + Command->os,
  114072. + task->address,
  114073. + gcmSIZEOF(gctUINT32),
  114074. + (gctPOINTER *) &logical
  114075. + ));
  114076. +
  114077. + /* Increment data. */
  114078. + (* logical) += 1;
  114079. +
  114080. + /* Unmap the physical memory. */
  114081. + gcmkERR_BREAK(gckOS_UnmapPhysical(
  114082. + Command->os,
  114083. + logical,
  114084. + gcmSIZEOF(gctUINT32)
  114085. + ));
  114086. +
  114087. + /* Update the reference counter. */
  114088. + TaskHeader->container->referenceCount -= 1;
  114089. +
  114090. + /* Update the task pointer. */
  114091. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114092. + }
  114093. + while (gcvFALSE);
  114094. +
  114095. + /* Return status. */
  114096. + return status;
  114097. +}
  114098. +
  114099. +static gceSTATUS
  114100. +_TaskDecrement(
  114101. + gckVGCOMMAND Command,
  114102. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114103. + )
  114104. +{
  114105. + gceSTATUS status;
  114106. +
  114107. + do
  114108. + {
  114109. + /* Cast the task pointer. */
  114110. + gcsTASK_DECREMENT_PTR task = (gcsTASK_DECREMENT_PTR) TaskHeader->task;
  114111. +
  114112. + /* Convert physical into logical address. */
  114113. + gctUINT32_PTR logical;
  114114. + gcmkERR_BREAK(gckOS_MapPhysical(
  114115. + Command->os,
  114116. + task->address,
  114117. + gcmSIZEOF(gctUINT32),
  114118. + (gctPOINTER *) &logical
  114119. + ));
  114120. +
  114121. + /* Decrement data. */
  114122. + (* logical) -= 1;
  114123. +
  114124. + /* Unmap the physical memory. */
  114125. + gcmkERR_BREAK(gckOS_UnmapPhysical(
  114126. + Command->os,
  114127. + logical,
  114128. + gcmSIZEOF(gctUINT32)
  114129. + ));
  114130. +
  114131. + /* Update the reference counter. */
  114132. + TaskHeader->container->referenceCount -= 1;
  114133. +
  114134. + /* Update the task pointer. */
  114135. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114136. + }
  114137. + while (gcvFALSE);
  114138. +
  114139. + /* Return status. */
  114140. + return status;
  114141. +}
  114142. +
  114143. +static gceSTATUS
  114144. +_TaskSignal(
  114145. + gckVGCOMMAND Command,
  114146. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114147. + )
  114148. +{
  114149. + gceSTATUS status;
  114150. +
  114151. + do
  114152. + {
  114153. + /* Cast the task pointer. */
  114154. + gcsTASK_SIGNAL_PTR task = (gcsTASK_SIGNAL_PTR) TaskHeader->task;
  114155. +
  114156. +
  114157. + /* Map the signal into kernel space. */
  114158. +#ifdef __QNXNTO__
  114159. + gcmkERR_BREAK(gckOS_UserSignal(
  114160. + Command->os, task->signal, task->rcvid, task->coid
  114161. + ));
  114162. +#else
  114163. + gcmkERR_BREAK(gckOS_UserSignal(
  114164. + Command->os, task->signal, task->process
  114165. + ));
  114166. +#endif /* __QNXNTO__ */
  114167. +
  114168. + /* Update the reference counter. */
  114169. + TaskHeader->container->referenceCount -= 1;
  114170. +
  114171. + /* Update the task pointer. */
  114172. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114173. + }
  114174. + while (gcvFALSE);
  114175. +
  114176. + /* Return status. */
  114177. + return status;
  114178. +}
  114179. +
  114180. +static gceSTATUS
  114181. +_TaskLockdown(
  114182. + gckVGCOMMAND Command,
  114183. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114184. + )
  114185. +{
  114186. + gceSTATUS status;
  114187. + gctUINT32_PTR userCounter = gcvNULL;
  114188. + gctUINT32_PTR kernelCounter = gcvNULL;
  114189. + gctSIGNAL signal = gcvNULL;
  114190. +
  114191. + do
  114192. + {
  114193. + /* Cast the task pointer. */
  114194. + gcsTASK_LOCKDOWN_PTR task = (gcsTASK_LOCKDOWN_PTR) TaskHeader->task;
  114195. +
  114196. + /* Convert physical addresses into logical. */
  114197. + gcmkERR_BREAK(gckOS_MapPhysical(
  114198. + Command->os,
  114199. + task->userCounter,
  114200. + gcmSIZEOF(gctUINT32),
  114201. + (gctPOINTER *) &userCounter
  114202. + ));
  114203. +
  114204. + gcmkERR_BREAK(gckOS_MapPhysical(
  114205. + Command->os,
  114206. + task->kernelCounter,
  114207. + gcmSIZEOF(gctUINT32),
  114208. + (gctPOINTER *) &kernelCounter
  114209. + ));
  114210. +
  114211. + /* Update the kernel counter. */
  114212. + (* kernelCounter) += 1;
  114213. +
  114214. + /* Are the counters equal? */
  114215. + if ((* userCounter) == (* kernelCounter))
  114216. + {
  114217. + /* Map the signal into kernel space. */
  114218. + gcmkERR_BREAK(gckOS_MapSignal(
  114219. + Command->os, task->signal, task->process, &signal
  114220. + ));
  114221. +
  114222. + if (signal == gcvNULL)
  114223. + {
  114224. + /* Signal. */
  114225. + gcmkERR_BREAK(gckOS_Signal(
  114226. + Command->os, task->signal, gcvTRUE
  114227. + ));
  114228. + }
  114229. + else
  114230. + {
  114231. + /* Signal. */
  114232. + gcmkERR_BREAK(gckOS_Signal(
  114233. + Command->os, signal, gcvTRUE
  114234. + ));
  114235. + }
  114236. + }
  114237. +
  114238. + /* Update the reference counter. */
  114239. + TaskHeader->container->referenceCount -= 1;
  114240. +
  114241. + /* Update the task pointer. */
  114242. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114243. + }
  114244. + while (gcvFALSE);
  114245. +
  114246. + /* Destroy the mapped signal. */
  114247. + if (signal != gcvNULL)
  114248. + {
  114249. + gcmkVERIFY_OK(gckOS_DestroySignal(
  114250. + Command->os, signal
  114251. + ));
  114252. + }
  114253. +
  114254. + /* Unmap the physical memory. */
  114255. + if (kernelCounter != gcvNULL)
  114256. + {
  114257. + gcmkVERIFY_OK(gckOS_UnmapPhysical(
  114258. + Command->os,
  114259. + kernelCounter,
  114260. + gcmSIZEOF(gctUINT32)
  114261. + ));
  114262. + }
  114263. +
  114264. + if (userCounter != gcvNULL)
  114265. + {
  114266. + gcmkVERIFY_OK(gckOS_UnmapPhysical(
  114267. + Command->os,
  114268. + userCounter,
  114269. + gcmSIZEOF(gctUINT32)
  114270. + ));
  114271. + }
  114272. +
  114273. + /* Return status. */
  114274. + return status;
  114275. +}
  114276. +
  114277. +static gceSTATUS
  114278. +_TaskUnlockVideoMemory(
  114279. + gckVGCOMMAND Command,
  114280. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114281. + )
  114282. +{
  114283. + gceSTATUS status;
  114284. +
  114285. + do
  114286. + {
  114287. + /* Cast the task pointer. */
  114288. + gcsTASK_UNLOCK_VIDEO_MEMORY_PTR task
  114289. + = (gcsTASK_UNLOCK_VIDEO_MEMORY_PTR) TaskHeader->task;
  114290. +
  114291. + /* Unlock video memory. */
  114292. + gcmkERR_BREAK(gckVIDMEM_Unlock(
  114293. + Command->kernel->kernel,
  114294. + gcmUINT64_TO_PTR(task->node),
  114295. + gcvSURF_TYPE_UNKNOWN,
  114296. + gcvNULL));
  114297. +
  114298. + /* Update the reference counter. */
  114299. + TaskHeader->container->referenceCount -= 1;
  114300. +
  114301. + /* Update the task pointer. */
  114302. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114303. + }
  114304. + while (gcvFALSE);
  114305. +
  114306. + /* Return status. */
  114307. + return status;
  114308. +}
  114309. +
  114310. +static gceSTATUS
  114311. +_TaskFreeVideoMemory(
  114312. + gckVGCOMMAND Command,
  114313. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114314. + )
  114315. +{
  114316. + gceSTATUS status;
  114317. +
  114318. + do
  114319. + {
  114320. + /* Cast the task pointer. */
  114321. + gcsTASK_FREE_VIDEO_MEMORY_PTR task
  114322. + = (gcsTASK_FREE_VIDEO_MEMORY_PTR) TaskHeader->task;
  114323. +
  114324. + /* Free video memory. */
  114325. + gcmkERR_BREAK(gckVIDMEM_Free(gcmUINT64_TO_PTR(task->node)));
  114326. +
  114327. + /* Update the reference counter. */
  114328. + TaskHeader->container->referenceCount -= 1;
  114329. +
  114330. + /* Update the task pointer. */
  114331. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114332. + }
  114333. + while (gcvFALSE);
  114334. +
  114335. + /* Return status. */
  114336. + return status;
  114337. +}
  114338. +
  114339. +static gceSTATUS
  114340. +_TaskFreeContiguousMemory(
  114341. + gckVGCOMMAND Command,
  114342. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114343. + )
  114344. +{
  114345. + gceSTATUS status;
  114346. +
  114347. + do
  114348. + {
  114349. + /* Cast the task pointer. */
  114350. + gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR task
  114351. + = (gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR) TaskHeader->task;
  114352. +
  114353. + /* Free contiguous memory. */
  114354. + gcmkERR_BREAK(gckOS_FreeContiguous(
  114355. + Command->os, task->physical, task->logical, task->bytes
  114356. + ));
  114357. +
  114358. + /* Update the reference counter. */
  114359. + TaskHeader->container->referenceCount -= 1;
  114360. +
  114361. + /* Update the task pointer. */
  114362. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114363. + }
  114364. + while (gcvFALSE);
  114365. +
  114366. + /* Return status. */
  114367. + return status;
  114368. +}
  114369. +
  114370. +static gceSTATUS
  114371. +_TaskUnmapUserMemory(
  114372. + gckVGCOMMAND Command,
  114373. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114374. + )
  114375. +{
  114376. + gceSTATUS status;
  114377. +
  114378. + do
  114379. + {
  114380. + /* Cast the task pointer. */
  114381. + gcsTASK_UNMAP_USER_MEMORY_PTR task
  114382. + = (gcsTASK_UNMAP_USER_MEMORY_PTR) TaskHeader->task;
  114383. +
  114384. + /* Unmap the user memory. */
  114385. + gcmkERR_BREAK(gckOS_UnmapUserMemory(
  114386. + Command->os, gcvCORE_VG, task->memory, task->size, task->info, task->address
  114387. + ));
  114388. +
  114389. + /* Update the reference counter. */
  114390. + TaskHeader->container->referenceCount -= 1;
  114391. +
  114392. + /* Update the task pointer. */
  114393. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114394. + }
  114395. + while (gcvFALSE);
  114396. +
  114397. + /* Return status. */
  114398. + return status;
  114399. +}
  114400. +
  114401. +/******************************************************************************\
  114402. +************ Hardware Block Interrupt Handlers For Scheduled Events ************
  114403. +\******************************************************************************/
  114404. +
  114405. +static gceSTATUS
  114406. +_EventHandler_Block(
  114407. + IN gckVGKERNEL Kernel,
  114408. + IN gcsBLOCK_TASK_ENTRY_PTR TaskHeader,
  114409. + IN gctBOOL ProcessAll
  114410. + )
  114411. +{
  114412. + gceSTATUS status, last;
  114413. +
  114414. + gcmkHEADER_ARG("Kernel=0x%x TaskHeader=0x%x ProcessAll=0x%x", Kernel, TaskHeader, ProcessAll);
  114415. + /* Verify the arguments. */
  114416. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  114417. +
  114418. + do
  114419. + {
  114420. + gckVGCOMMAND command;
  114421. +
  114422. + /* Get the command buffer object. */
  114423. + command = Kernel->command;
  114424. +
  114425. + /* Increment the interrupt usage semaphore. */
  114426. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  114427. + command->os, TaskHeader->interruptSemaphore
  114428. + ));
  114429. +
  114430. + /* Acquire the mutex. */
  114431. + gcmkERR_BREAK(gckOS_AcquireMutex(
  114432. + command->os,
  114433. + command->taskMutex,
  114434. + gcvINFINITE
  114435. + ));
  114436. +
  114437. + /* Verify inputs. */
  114438. + gcmkASSERT(TaskHeader != gcvNULL);
  114439. + gcmkASSERT(TaskHeader->container != gcvNULL);
  114440. + gcmkASSERT(TaskHeader->task != gcvNULL);
  114441. + gcmkASSERT(TaskHeader->link != gcvNULL);
  114442. +
  114443. + /* Process tasks. */
  114444. + do
  114445. + {
  114446. + /* Process the current task. */
  114447. + gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
  114448. + command,
  114449. + TaskHeader
  114450. + ));
  114451. +
  114452. + /* Is the next task is LINK? */
  114453. + if (TaskHeader->task->id == gcvTASK_LINK)
  114454. + {
  114455. + gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
  114456. + command,
  114457. + TaskHeader
  114458. + ));
  114459. +
  114460. + /* Done. */
  114461. + break;
  114462. + }
  114463. + }
  114464. + while (ProcessAll);
  114465. +
  114466. + /* Release the mutex. */
  114467. + gcmkCHECK_STATUS(gckOS_ReleaseMutex(
  114468. + command->os,
  114469. + command->taskMutex
  114470. + ));
  114471. + }
  114472. + while (gcvFALSE);
  114473. +
  114474. + gcmkFOOTER();
  114475. + /* Return status. */
  114476. + return status;
  114477. +}
  114478. +
  114479. +gcmDECLARE_INTERRUPT_HANDLER(COMMAND, 0)
  114480. +{
  114481. + gceSTATUS status, last;
  114482. +
  114483. + gcmkHEADER_ARG("Kernel=0x%x ", Kernel);
  114484. +
  114485. + /* Verify the arguments. */
  114486. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  114487. +
  114488. +
  114489. + do
  114490. + {
  114491. + gckVGCOMMAND command;
  114492. + gcsKERNEL_QUEUE_HEADER_PTR mergeQueue;
  114493. + gcsKERNEL_QUEUE_HEADER_PTR queueTail;
  114494. + gcsKERNEL_CMDQUEUE_PTR entry;
  114495. + gctUINT entryCount;
  114496. +
  114497. + /* Get the command buffer object. */
  114498. + command = Kernel->command;
  114499. +
  114500. + /* Acquire the mutex. */
  114501. + gcmkERR_BREAK(gckOS_AcquireMutex(
  114502. + command->os,
  114503. + command->queueMutex,
  114504. + gcvINFINITE
  114505. + ));
  114506. +
  114507. + /* Get the current queue. */
  114508. + queueTail = command->queueTail;
  114509. +
  114510. + /* Get the current queue entry. */
  114511. + entry = queueTail->currentEntry;
  114512. +
  114513. + /* Get the number of entries in the queue. */
  114514. + entryCount = queueTail->pending;
  114515. +
  114516. + /* Process all entries. */
  114517. + while (gcvTRUE)
  114518. + {
  114519. + /* Call post-execution function. */
  114520. + status = entry->handler(Kernel, entry);
  114521. +
  114522. + /* Failed? */
  114523. + if (gcmkIS_ERROR(status))
  114524. + {
  114525. + gcmkTRACE_ZONE(
  114526. + gcvLEVEL_ERROR,
  114527. + gcvZONE_COMMAND,
  114528. + "[%s] line %d: post action failed.\n",
  114529. + __FUNCTION__, __LINE__
  114530. + );
  114531. + }
  114532. +
  114533. + /* Executed the next buffer? */
  114534. + if (status == gcvSTATUS_EXECUTED)
  114535. + {
  114536. + /* Update the queue. */
  114537. + queueTail->pending = entryCount;
  114538. + queueTail->currentEntry = entry;
  114539. +
  114540. + /* Success. */
  114541. + status = gcvSTATUS_OK;
  114542. +
  114543. + /* Break out of the loop. */
  114544. + break;
  114545. + }
  114546. +
  114547. + /* Advance to the next entry. */
  114548. + entry += 1;
  114549. + entryCount -= 1;
  114550. +
  114551. + /* Last entry? */
  114552. + if (entryCount == 0)
  114553. + {
  114554. + /* Reset the queue to idle. */
  114555. + queueTail->pending = 0;
  114556. +
  114557. + /* Get a shortcut to the queue to merge with. */
  114558. + mergeQueue = command->mergeQueue;
  114559. +
  114560. + /* Merge the queues if necessary. */
  114561. + if (mergeQueue != queueTail)
  114562. + {
  114563. + gcmkASSERT(mergeQueue < queueTail);
  114564. + gcmkASSERT(mergeQueue->next == queueTail);
  114565. +
  114566. + mergeQueue->size
  114567. + += gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
  114568. + + queueTail->size;
  114569. +
  114570. + mergeQueue->next = queueTail->next;
  114571. + }
  114572. +
  114573. + /* Advance to the next queue. */
  114574. + queueTail = queueTail->next;
  114575. +
  114576. + /* Did it wrap around? */
  114577. + if (command->queue == queueTail)
  114578. + {
  114579. + /* Reset merge queue. */
  114580. + command->mergeQueue = queueTail;
  114581. + }
  114582. +
  114583. + /* Set new queue. */
  114584. + command->queueTail = queueTail;
  114585. +
  114586. + /* Is the next queue scheduled? */
  114587. + if (queueTail->pending > 0)
  114588. + {
  114589. + gcsCMDBUFFER_PTR commandBuffer;
  114590. +
  114591. + /* The first entry must be a command buffer. */
  114592. + commandBuffer = queueTail->currentEntry->commandBuffer;
  114593. +
  114594. + /* Start the command processor. */
  114595. + status = gckVGHARDWARE_Execute(
  114596. + command->hardware,
  114597. + commandBuffer->address,
  114598. + commandBuffer->dataCount
  114599. + );
  114600. +
  114601. + /* Failed? */
  114602. + if (gcmkIS_ERROR(status))
  114603. + {
  114604. + gcmkTRACE_ZONE(
  114605. + gcvLEVEL_ERROR,
  114606. + gcvZONE_COMMAND,
  114607. + "[%s] line %d: failed to start the next queue.\n",
  114608. + __FUNCTION__, __LINE__
  114609. + );
  114610. + }
  114611. + }
  114612. + else
  114613. + {
  114614. + status = gckVGHARDWARE_SetPowerManagementState(
  114615. + Kernel->command->hardware, gcvPOWER_IDLE_BROADCAST
  114616. + );
  114617. + }
  114618. +
  114619. + /* Break out of the loop. */
  114620. + break;
  114621. + }
  114622. + }
  114623. +
  114624. + /* Release the mutex. */
  114625. + gcmkCHECK_STATUS(gckOS_ReleaseMutex(
  114626. + command->os,
  114627. + command->queueMutex
  114628. + ));
  114629. + }
  114630. + while (gcvFALSE);
  114631. +
  114632. +
  114633. + gcmkFOOTER();
  114634. + /* Return status. */
  114635. + return status;
  114636. +}
  114637. +
  114638. +/* Define standard block interrupt handlers. */
  114639. +gcmDEFINE_INTERRUPT_HANDLER(TESSELLATOR, 0)
  114640. +gcmDEFINE_INTERRUPT_HANDLER(VG, 0)
  114641. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 0)
  114642. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 1)
  114643. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 2)
  114644. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 3)
  114645. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 4)
  114646. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 5)
  114647. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 6)
  114648. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 7)
  114649. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 8)
  114650. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 9)
  114651. +
  114652. +/* The entries in the array are arranged by event priority. */
  114653. +static gcsBLOCK_INTERRUPT_HANDLER _blockHandlers[] =
  114654. +{
  114655. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(TESSELLATOR, 0),
  114656. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(VG, 0),
  114657. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 0),
  114658. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 1),
  114659. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 2),
  114660. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 3),
  114661. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 4),
  114662. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 5),
  114663. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 6),
  114664. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 7),
  114665. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 8),
  114666. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 9),
  114667. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(COMMAND, 0),
  114668. +};
  114669. +
  114670. +
  114671. +/******************************************************************************\
  114672. +************************* Static Command Buffer Handlers ***********************
  114673. +\******************************************************************************/
  114674. +
  114675. +static gceSTATUS
  114676. +_UpdateStaticCommandBuffer(
  114677. + IN gckVGKERNEL Kernel,
  114678. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114679. + )
  114680. +{
  114681. + gcmkTRACE_ZONE(
  114682. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114683. + "%s(%d)\n",
  114684. + __FUNCTION__, __LINE__
  114685. + );
  114686. +
  114687. + /* Success. */
  114688. + return gcvSTATUS_OK;
  114689. +}
  114690. +
  114691. +static gceSTATUS
  114692. +_ExecuteStaticCommandBuffer(
  114693. + IN gckVGKERNEL Kernel,
  114694. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114695. + )
  114696. +{
  114697. + gceSTATUS status;
  114698. +
  114699. + do
  114700. + {
  114701. + gcsCMDBUFFER_PTR commandBuffer;
  114702. +
  114703. + /* Cast the command buffer header. */
  114704. + commandBuffer = Entry->commandBuffer;
  114705. +
  114706. + /* Set to update the command buffer next time. */
  114707. + Entry->handler = _UpdateStaticCommandBuffer;
  114708. +
  114709. + gcmkTRACE_ZONE(
  114710. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114711. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  114712. + __FUNCTION__, __LINE__,
  114713. + commandBuffer->address,
  114714. + commandBuffer->dataCount
  114715. + );
  114716. +
  114717. + /* Start the command processor. */
  114718. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  114719. + Kernel->hardware,
  114720. + commandBuffer->address,
  114721. + commandBuffer->dataCount
  114722. + ));
  114723. +
  114724. + /* Success. */
  114725. + return gcvSTATUS_EXECUTED;
  114726. + }
  114727. + while (gcvFALSE);
  114728. +
  114729. + /* Return status. */
  114730. + return status;
  114731. +}
  114732. +
  114733. +static gceSTATUS
  114734. +_UpdateLastStaticCommandBuffer(
  114735. + IN gckVGKERNEL Kernel,
  114736. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114737. + )
  114738. +{
  114739. +#if gcvDEBUG || gcdFORCE_MESSAGES
  114740. + /* Get the command buffer header. */
  114741. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  114742. +
  114743. + /* Validate the command buffer. */
  114744. + gcmkASSERT(commandBuffer->completion != gcvNULL);
  114745. + gcmkASSERT(commandBuffer->completion != gcvVACANT_BUFFER);
  114746. +
  114747. +#endif
  114748. +
  114749. + gcmkTRACE_ZONE(
  114750. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114751. + "%s(%d): processing all tasks scheduled for FE.\n",
  114752. + __FUNCTION__, __LINE__
  114753. + );
  114754. +
  114755. + /* Perform scheduled tasks. */
  114756. + return _EventHandler_Block(
  114757. + Kernel,
  114758. + &Kernel->command->taskTable[gcvBLOCK_COMMAND],
  114759. + gcvTRUE
  114760. + );
  114761. +}
  114762. +
  114763. +static gceSTATUS
  114764. +_ExecuteLastStaticCommandBuffer(
  114765. + IN gckVGKERNEL Kernel,
  114766. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114767. + )
  114768. +{
  114769. + gceSTATUS status;
  114770. +
  114771. + do
  114772. + {
  114773. + /* Cast the command buffer header. */
  114774. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  114775. +
  114776. + /* Set to update the command buffer next time. */
  114777. + Entry->handler = _UpdateLastStaticCommandBuffer;
  114778. +
  114779. + gcmkTRACE_ZONE(
  114780. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114781. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  114782. + __FUNCTION__, __LINE__,
  114783. + commandBuffer->address,
  114784. + commandBuffer->dataCount
  114785. + );
  114786. +
  114787. + /* Start the command processor. */
  114788. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  114789. + Kernel->hardware,
  114790. + commandBuffer->address,
  114791. + commandBuffer->dataCount
  114792. + ));
  114793. +
  114794. + /* Success. */
  114795. + return gcvSTATUS_EXECUTED;
  114796. + }
  114797. + while (gcvFALSE);
  114798. +
  114799. + /* Return status. */
  114800. + return status;
  114801. +}
  114802. +
  114803. +
  114804. +/******************************************************************************\
  114805. +************************* Dynamic Command Buffer Handlers **********************
  114806. +\******************************************************************************/
  114807. +
  114808. +static gceSTATUS
  114809. +_UpdateDynamicCommandBuffer(
  114810. + IN gckVGKERNEL Kernel,
  114811. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114812. + )
  114813. +{
  114814. + gcmkTRACE_ZONE(
  114815. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114816. + "%s(%d)\n",
  114817. + __FUNCTION__, __LINE__
  114818. + );
  114819. +
  114820. + /* Success. */
  114821. + return gcvSTATUS_OK;
  114822. +}
  114823. +
  114824. +static gceSTATUS
  114825. +_ExecuteDynamicCommandBuffer(
  114826. + IN gckVGKERNEL Kernel,
  114827. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114828. + )
  114829. +{
  114830. + gceSTATUS status;
  114831. +
  114832. + do
  114833. + {
  114834. + /* Cast the command buffer header. */
  114835. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  114836. +
  114837. + /* Set to update the command buffer next time. */
  114838. + Entry->handler = _UpdateDynamicCommandBuffer;
  114839. +
  114840. + gcmkTRACE_ZONE(
  114841. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114842. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  114843. + __FUNCTION__, __LINE__,
  114844. + commandBuffer->address,
  114845. + commandBuffer->dataCount
  114846. + );
  114847. +
  114848. + /* Start the command processor. */
  114849. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  114850. + Kernel->hardware,
  114851. + commandBuffer->address,
  114852. + commandBuffer->dataCount
  114853. + ));
  114854. +
  114855. + /* Success. */
  114856. + return gcvSTATUS_EXECUTED;
  114857. + }
  114858. + while (gcvFALSE);
  114859. +
  114860. + /* Return status. */
  114861. + return status;
  114862. +}
  114863. +
  114864. +static gceSTATUS
  114865. +_UpdateLastDynamicCommandBuffer(
  114866. + IN gckVGKERNEL Kernel,
  114867. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114868. + )
  114869. +{
  114870. +#if gcvDEBUG || gcdFORCE_MESSAGES
  114871. + /* Get the command buffer header. */
  114872. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  114873. +
  114874. + /* Validate the command buffer. */
  114875. + gcmkASSERT(commandBuffer->completion != gcvNULL);
  114876. + gcmkASSERT(commandBuffer->completion != gcvVACANT_BUFFER);
  114877. +
  114878. +#endif
  114879. +
  114880. + gcmkTRACE_ZONE(
  114881. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114882. + "%s(%d): processing all tasks scheduled for FE.\n",
  114883. + __FUNCTION__, __LINE__
  114884. + );
  114885. +
  114886. + /* Perform scheduled tasks. */
  114887. + return _EventHandler_Block(
  114888. + Kernel,
  114889. + &Kernel->command->taskTable[gcvBLOCK_COMMAND],
  114890. + gcvTRUE
  114891. + );
  114892. +}
  114893. +
  114894. +static gceSTATUS
  114895. +_ExecuteLastDynamicCommandBuffer(
  114896. + IN gckVGKERNEL Kernel,
  114897. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114898. + )
  114899. +{
  114900. + gceSTATUS status;
  114901. +
  114902. + do
  114903. + {
  114904. + /* Cast the command buffer header. */
  114905. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  114906. +
  114907. + /* Set to update the command buffer next time. */
  114908. + Entry->handler = _UpdateLastDynamicCommandBuffer;
  114909. +
  114910. + gcmkTRACE_ZONE(
  114911. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114912. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  114913. + __FUNCTION__, __LINE__,
  114914. + commandBuffer->address,
  114915. + commandBuffer->dataCount
  114916. + );
  114917. +
  114918. + /* Start the command processor. */
  114919. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  114920. + Kernel->hardware,
  114921. + commandBuffer->address,
  114922. + commandBuffer->dataCount
  114923. + ));
  114924. +
  114925. + /* Success. */
  114926. + return gcvSTATUS_EXECUTED;
  114927. + }
  114928. + while (gcvFALSE);
  114929. +
  114930. + /* Return status. */
  114931. + return status;
  114932. +}
  114933. +
  114934. +
  114935. +/******************************************************************************\
  114936. +********************************* Other Handlers *******************************
  114937. +\******************************************************************************/
  114938. +
  114939. +static gceSTATUS
  114940. +_FreeKernelCommandBuffer(
  114941. + IN gckVGKERNEL Kernel,
  114942. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114943. + )
  114944. +{
  114945. + gceSTATUS status;
  114946. +
  114947. + /* Free the command buffer. */
  114948. + status = _FreeCommandBuffer(Kernel, Entry->commandBuffer);
  114949. +
  114950. + /* Return status. */
  114951. + return status;
  114952. +}
  114953. +
  114954. +
  114955. +/******************************************************************************\
  114956. +******************************* Queue Management *******************************
  114957. +\******************************************************************************/
  114958. +
  114959. +#if gcvDUMP_COMMAND_BUFFER
  114960. +static void
  114961. +_DumpCommandQueue(
  114962. + IN gckVGCOMMAND Command,
  114963. + IN gcsKERNEL_QUEUE_HEADER_PTR QueueHeader,
  114964. + IN gctUINT EntryCount
  114965. + )
  114966. +{
  114967. + gcsKERNEL_CMDQUEUE_PTR entry;
  114968. + gctUINT queueIndex;
  114969. +
  114970. +#if defined(gcvCOMMAND_BUFFER_NAME)
  114971. + static gctUINT arrayCount = 0;
  114972. +#endif
  114973. +
  114974. + /* Is dumpinng enabled? */
  114975. + if (!Commad->enableDumping)
  114976. + {
  114977. + return;
  114978. + }
  114979. +
  114980. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  114981. + gcmkTRACE_ZONE(
  114982. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  114983. + "COMMAND QUEUE DUMP: %d entries\n", EntryCount
  114984. + );
  114985. +#endif
  114986. +
  114987. + /* Get the pointer to the first entry. */
  114988. + entry = QueueHeader->currentEntry;
  114989. +
  114990. + /* Iterate through the queue. */
  114991. + for (queueIndex = 0; queueIndex < EntryCount; queueIndex += 1)
  114992. + {
  114993. + gcsCMDBUFFER_PTR buffer;
  114994. + gctUINT bufferCount;
  114995. + gctUINT bufferIndex;
  114996. + gctUINT i, count;
  114997. + gctUINT size;
  114998. + gctUINT32_PTR data;
  114999. +
  115000. +#if gcvDUMP_COMMAND_LINES
  115001. + gctUINT lineNumber;
  115002. +#endif
  115003. +
  115004. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  115005. + gcmkTRACE_ZONE(
  115006. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  115007. + "ENTRY %d\n", queueIndex
  115008. + );
  115009. +#endif
  115010. +
  115011. + /* Reset the count. */
  115012. + bufferCount = 0;
  115013. +
  115014. + /* Set the initial buffer. */
  115015. + buffer = entry->commandBuffer;
  115016. +
  115017. + /* Loop through all subbuffers. */
  115018. + while (buffer)
  115019. + {
  115020. + /* Update the count. */
  115021. + bufferCount += 1;
  115022. +
  115023. + /* Advance to the next subbuffer. */
  115024. + buffer = buffer->nextSubBuffer;
  115025. + }
  115026. +
  115027. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  115028. + if (bufferCount > 1)
  115029. + {
  115030. + gcmkTRACE_ZONE(
  115031. + gcvLEVEL_INFO,
  115032. + gcvZONE_COMMAND,
  115033. + " COMMAND BUFFER SET: %d buffers.\n",
  115034. + bufferCount
  115035. + );
  115036. + }
  115037. +#endif
  115038. +
  115039. + /* Reset the buffer index. */
  115040. + bufferIndex = 0;
  115041. +
  115042. + /* Set the initial buffer. */
  115043. + buffer = entry->commandBuffer;
  115044. +
  115045. + /* Loop through all subbuffers. */
  115046. + while (buffer)
  115047. + {
  115048. + /* Determine the size of the buffer. */
  115049. + size = buffer->dataCount * Command->info.commandAlignment;
  115050. +
  115051. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  115052. + /* A single buffer? */
  115053. + if (bufferCount == 1)
  115054. + {
  115055. + gcmkTRACE_ZONE(
  115056. + gcvLEVEL_INFO,
  115057. + gcvZONE_COMMAND,
  115058. + " COMMAND BUFFER: count=%d (0x%X), size=%d bytes @ %08X.\n",
  115059. + buffer->dataCount,
  115060. + buffer->dataCount,
  115061. + size,
  115062. + buffer->address
  115063. + );
  115064. + }
  115065. + else
  115066. + {
  115067. + gcmkTRACE_ZONE(
  115068. + gcvLEVEL_INFO,
  115069. + gcvZONE_COMMAND,
  115070. + " COMMAND BUFFER %d: count=%d (0x%X), size=%d bytes @ %08X\n",
  115071. + bufferIndex,
  115072. + buffer->dataCount,
  115073. + buffer->dataCount,
  115074. + size,
  115075. + buffer->address
  115076. + );
  115077. + }
  115078. +#endif
  115079. +
  115080. + /* Determine the number of double words to print. */
  115081. + count = size / 4;
  115082. +
  115083. + /* Determine the buffer location. */
  115084. + data = (gctUINT32_PTR)
  115085. + (
  115086. + (gctUINT8_PTR) buffer + buffer->bufferOffset
  115087. + );
  115088. +
  115089. +#if defined(gcvCOMMAND_BUFFER_NAME)
  115090. + gcmkTRACE_ZONE(
  115091. + gcvLEVEL_INFO,
  115092. + gcvZONE_COMMAND,
  115093. + "unsigned int _" gcvCOMMAND_BUFFER_NAME "_%d[] =\n",
  115094. + arrayCount
  115095. + );
  115096. +
  115097. + gcmkTRACE_ZONE(
  115098. + gcvLEVEL_INFO,
  115099. + gcvZONE_COMMAND,
  115100. + "{\n"
  115101. + );
  115102. +
  115103. + arrayCount += 1;
  115104. +#endif
  115105. +
  115106. +#if gcvDUMP_COMMAND_LINES
  115107. + /* Reset the line number. */
  115108. + lineNumber = 0;
  115109. +#endif
  115110. +
  115111. +#if defined(gcvCOMMAND_BUFFER_NAME)
  115112. + count -= 2;
  115113. +#endif
  115114. +
  115115. + for (i = 0; i < count; i += 1)
  115116. + {
  115117. + if ((i % 8) == 0)
  115118. + {
  115119. +#if defined(gcvCOMMAND_BUFFER_NAME)
  115120. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "\t");
  115121. +#else
  115122. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, " ");
  115123. +#endif
  115124. + }
  115125. +
  115126. +#if gcvDUMP_COMMAND_LINES
  115127. + if (lineNumber == gcvDUMP_COMMAND_LINES)
  115128. + {
  115129. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, " . . . . . . . . .\n");
  115130. + break;
  115131. + }
  115132. +#endif
  115133. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "0x%08X", data[i]);
  115134. +
  115135. + if (i + 1 == count)
  115136. + {
  115137. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "\n");
  115138. +
  115139. +#if gcvDUMP_COMMAND_LINES
  115140. + lineNumber += 1;
  115141. +#endif
  115142. + }
  115143. + else
  115144. + {
  115145. + if (((i + 1) % 8) == 0)
  115146. + {
  115147. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, ",\n");
  115148. +
  115149. +#if gcvDUMP_COMMAND_LINES
  115150. + lineNumber += 1;
  115151. +#endif
  115152. + }
  115153. + else
  115154. + {
  115155. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, ", ");
  115156. + }
  115157. + }
  115158. + }
  115159. +
  115160. +#if defined(gcvCOMMAND_BUFFER_NAME)
  115161. + gcmkTRACE_ZONE(
  115162. + gcvLEVEL_INFO,
  115163. + gcvZONE_COMMAND,
  115164. + "};\n\n"
  115165. + );
  115166. +#endif
  115167. +
  115168. + /* Advance to the next subbuffer. */
  115169. + buffer = buffer->nextSubBuffer;
  115170. + bufferIndex += 1;
  115171. + }
  115172. +
  115173. + /* Advance to the next entry. */
  115174. + entry += 1;
  115175. + }
  115176. +}
  115177. +#endif
  115178. +
  115179. +static gceSTATUS
  115180. +_LockCurrentQueue(
  115181. + IN gckVGCOMMAND Command,
  115182. + OUT gcsKERNEL_CMDQUEUE_PTR * Entries,
  115183. + OUT gctUINT_PTR EntryCount
  115184. + )
  115185. +{
  115186. + gceSTATUS status;
  115187. +
  115188. + do
  115189. + {
  115190. + gcsKERNEL_QUEUE_HEADER_PTR queueHead;
  115191. +
  115192. + /* Get a shortcut to the head of the queue. */
  115193. + queueHead = Command->queueHead;
  115194. +
  115195. + /* Is the head buffer still being worked on? */
  115196. + if (queueHead->pending)
  115197. + {
  115198. + /* Increment overflow count. */
  115199. + Command->queueOverflow += 1;
  115200. +
  115201. + /* Wait until the head becomes idle. */
  115202. + gcmkERR_BREAK(_WaitForIdle(Command, queueHead));
  115203. + }
  115204. +
  115205. + /* Acquire the mutex. */
  115206. + gcmkERR_BREAK(gckOS_AcquireMutex(
  115207. + Command->os,
  115208. + Command->queueMutex,
  115209. + gcvINFINITE
  115210. + ));
  115211. +
  115212. + /* Determine the first queue entry. */
  115213. + queueHead->currentEntry = (gcsKERNEL_CMDQUEUE_PTR)
  115214. + (
  115215. + (gctUINT8_PTR) queueHead + gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
  115216. + );
  115217. +
  115218. + /* Set the pointer to the first entry. */
  115219. + * Entries = queueHead->currentEntry;
  115220. +
  115221. + /* Determine the number of available entries. */
  115222. + * EntryCount = queueHead->size / gcmSIZEOF(gcsKERNEL_CMDQUEUE);
  115223. +
  115224. + /* Success. */
  115225. + return gcvSTATUS_OK;
  115226. + }
  115227. + while (gcvFALSE);
  115228. +
  115229. + /* Return status. */
  115230. + return status;
  115231. +}
  115232. +
  115233. +static gceSTATUS
  115234. +_UnlockCurrentQueue(
  115235. + IN gckVGCOMMAND Command,
  115236. + IN gctUINT EntryCount
  115237. + )
  115238. +{
  115239. + gceSTATUS status;
  115240. +
  115241. + do
  115242. + {
  115243. +#if !gcdENABLE_INFINITE_SPEED_HW
  115244. + gcsKERNEL_QUEUE_HEADER_PTR queueTail;
  115245. + gcsKERNEL_QUEUE_HEADER_PTR queueHead;
  115246. + gcsKERNEL_QUEUE_HEADER_PTR queueNext;
  115247. + gctUINT queueSize;
  115248. + gctUINT newSize;
  115249. + gctUINT unusedSize;
  115250. +
  115251. + /* Get shortcut to the head and to the tail of the queue. */
  115252. + queueTail = Command->queueTail;
  115253. + queueHead = Command->queueHead;
  115254. +
  115255. + /* Dump the command buffer. */
  115256. +#if gcvDUMP_COMMAND_BUFFER
  115257. + _DumpCommandQueue(Command, queueHead, EntryCount);
  115258. +#endif
  115259. +
  115260. + /* Get a shortcut to the current queue size. */
  115261. + queueSize = queueHead->size;
  115262. +
  115263. + /* Determine the new queue size. */
  115264. + newSize = EntryCount * gcmSIZEOF(gcsKERNEL_CMDQUEUE);
  115265. + gcmkASSERT(newSize <= queueSize);
  115266. +
  115267. + /* Determine the size of the unused area. */
  115268. + unusedSize = queueSize - newSize;
  115269. +
  115270. + /* Is the unused area big enough to become a buffer? */
  115271. + if (unusedSize >= gcvMINUMUM_BUFFER)
  115272. + {
  115273. + gcsKERNEL_QUEUE_HEADER_PTR nextHead;
  115274. +
  115275. + /* Place the new header. */
  115276. + nextHead = (gcsKERNEL_QUEUE_HEADER_PTR)
  115277. + (
  115278. + (gctUINT8_PTR) queueHead
  115279. + + gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
  115280. + + newSize
  115281. + );
  115282. +
  115283. + /* Initialize the buffer. */
  115284. + nextHead->size = unusedSize - gcmSIZEOF(gcsKERNEL_QUEUE_HEADER);
  115285. + nextHead->pending = 0;
  115286. +
  115287. + /* Link the buffer in. */
  115288. + nextHead->next = queueHead->next;
  115289. + queueHead->next = nextHead;
  115290. + queueNext = nextHead;
  115291. +
  115292. + /* Update the size of the current buffer. */
  115293. + queueHead->size = newSize;
  115294. + }
  115295. +
  115296. + /* Not big enough. */
  115297. + else
  115298. + {
  115299. + /* Determine the next queue. */
  115300. + queueNext = queueHead->next;
  115301. + }
  115302. +
  115303. + /* Mark the buffer as busy. */
  115304. + queueHead->pending = EntryCount;
  115305. +
  115306. + /* Advance to the next buffer. */
  115307. + Command->queueHead = queueNext;
  115308. +
  115309. + /* Start the command processor if the queue was empty. */
  115310. + if (queueTail == queueHead)
  115311. + {
  115312. + gcsCMDBUFFER_PTR commandBuffer;
  115313. +
  115314. + /* The first entry must be a command buffer. */
  115315. + commandBuffer = queueTail->currentEntry->commandBuffer;
  115316. +
  115317. + /* Start the command processor. */
  115318. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  115319. + Command->hardware,
  115320. + commandBuffer->address,
  115321. + commandBuffer->dataCount
  115322. + ));
  115323. + }
  115324. +
  115325. + /* The queue was not empty. */
  115326. + else
  115327. + {
  115328. + /* Advance the merge buffer if needed. */
  115329. + if (queueHead == Command->mergeQueue)
  115330. + {
  115331. + Command->mergeQueue = queueNext;
  115332. + }
  115333. + }
  115334. +#endif
  115335. +
  115336. + /* Release the mutex. */
  115337. + gcmkERR_BREAK(gckOS_ReleaseMutex(
  115338. + Command->os,
  115339. + Command->queueMutex
  115340. + ));
  115341. +
  115342. + /* Success. */
  115343. + return gcvSTATUS_OK;
  115344. + }
  115345. + while (gcvFALSE);
  115346. +
  115347. + /* Return status. */
  115348. + return status;
  115349. +}
  115350. +
  115351. +
  115352. +
  115353. +/******************************************************************************\
  115354. +****************************** gckVGCOMMAND API Code *****************************
  115355. +\******************************************************************************/
  115356. +gceSTATUS
  115357. +gckVGCOMMAND_Construct(
  115358. + IN gckVGKERNEL Kernel,
  115359. + IN gctUINT TaskGranularity,
  115360. + IN gctUINT QueueSize,
  115361. + OUT gckVGCOMMAND * Command
  115362. + )
  115363. +{
  115364. + gceSTATUS status, last;
  115365. + gckVGCOMMAND command = gcvNULL;
  115366. + gcsKERNEL_QUEUE_HEADER_PTR queue;
  115367. + gctUINT i, j;
  115368. +
  115369. + gcmkHEADER_ARG("Kernel=0x%x TaskGranularity=0x%x QueueSize=0x%x Command=0x%x",
  115370. + Kernel, TaskGranularity, QueueSize, Command);
  115371. + /* Verify the arguments. */
  115372. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  115373. + gcmkVERIFY_ARGUMENT(QueueSize >= gcvMINUMUM_BUFFER);
  115374. + gcmkVERIFY_ARGUMENT(Command != gcvNULL);
  115375. +
  115376. + do
  115377. + {
  115378. + /***********************************************************************
  115379. + ** Generic object initialization.
  115380. + */
  115381. +
  115382. + /* Allocate the gckVGCOMMAND structure. */
  115383. + gcmkERR_BREAK(gckOS_Allocate(
  115384. + Kernel->os,
  115385. + gcmSIZEOF(struct _gckVGCOMMAND),
  115386. + (gctPOINTER *) &command
  115387. + ));
  115388. +
  115389. + /* Initialize the object. */
  115390. + command->object.type = gcvOBJ_COMMAND;
  115391. +
  115392. + /* Set the object pointers. */
  115393. + command->kernel = Kernel;
  115394. + command->os = Kernel->os;
  115395. + command->hardware = Kernel->hardware;
  115396. +
  115397. + /* Reset pointers. */
  115398. + command->queue = gcvNULL;
  115399. + command->queueMutex = gcvNULL;
  115400. + command->taskMutex = gcvNULL;
  115401. + command->commitMutex = gcvNULL;
  115402. +
  115403. + command->powerStallBuffer = gcvNULL;
  115404. + command->powerStallSignal = gcvNULL;
  115405. + command->powerSemaphore = gcvNULL;
  115406. +
  115407. + /* Reset context states. */
  115408. + command->contextCounter = 0;
  115409. + command->currentContext = 0;
  115410. +
  115411. + /* Enable command buffer dumping. */
  115412. + command->enableDumping = gcvTRUE;
  115413. +
  115414. + /* Set features. */
  115415. + command->fe20 = Kernel->hardware->fe20;
  115416. + command->vg20 = Kernel->hardware->vg20;
  115417. + command->vg21 = Kernel->hardware->vg21;
  115418. +
  115419. + /* Reset task table .*/
  115420. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  115421. + command->taskTable, gcmSIZEOF(command->taskTable)
  115422. + ));
  115423. +
  115424. + /* Query command buffer attributes. */
  115425. + gcmkERR_BREAK(gckVGCOMMAND_InitializeInfo(command));
  115426. +
  115427. + /* Create the control mutexes. */
  115428. + gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->queueMutex));
  115429. + gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->taskMutex));
  115430. + gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->commitMutex));
  115431. +
  115432. + /* Create the power management semaphore. */
  115433. + gcmkERR_BREAK(gckOS_CreateSemaphore(Kernel->os,
  115434. + &command->powerSemaphore));
  115435. +
  115436. + gcmkERR_BREAK(gckOS_CreateSignal(Kernel->os,
  115437. + gcvFALSE, &command->powerStallSignal));
  115438. +
  115439. + /***********************************************************************
  115440. + ** Command queue initialization.
  115441. + */
  115442. +
  115443. + /* Allocate the command queue. */
  115444. + gcmkERR_BREAK(gckOS_Allocate(
  115445. + Kernel->os,
  115446. + QueueSize,
  115447. + (gctPOINTER *) &command->queue
  115448. + ));
  115449. +
  115450. + /* Initialize the command queue. */
  115451. + queue = command->queue;
  115452. +
  115453. + queue->size = QueueSize - gcmSIZEOF(gcsKERNEL_QUEUE_HEADER);
  115454. + queue->pending = 0;
  115455. + queue->next = queue;
  115456. +
  115457. + command->queueHead =
  115458. + command->queueTail =
  115459. + command->mergeQueue = command->queue;
  115460. +
  115461. + command->queueOverflow = 0;
  115462. +
  115463. +
  115464. + /***********************************************************************
  115465. + ** Enable TS overflow interrupt.
  115466. + */
  115467. +
  115468. + command->info.tsOverflowInt = 0;
  115469. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  115470. + Kernel->interrupt,
  115471. + &command->info.tsOverflowInt,
  115472. + _EventHandler_TSOverflow
  115473. + ));
  115474. +
  115475. + /* Mask out the interrupt. */
  115476. + Kernel->hardware->eventMask &= ~(1 << command->info.tsOverflowInt);
  115477. +
  115478. +
  115479. + /***********************************************************************
  115480. + ** Enable Bus Error interrupt.
  115481. + */
  115482. +
  115483. + /* Hardwired to bit 31. */
  115484. + command->busErrorInt = 31;
  115485. +
  115486. + /* Enable the interrupt. */
  115487. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  115488. + Kernel->interrupt,
  115489. + &command->busErrorInt,
  115490. + _EventHandler_BusError
  115491. + ));
  115492. +
  115493. +
  115494. + command->powerStallInt = 30;
  115495. + /* Enable the interrupt. */
  115496. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  115497. + Kernel->interrupt,
  115498. + &command->powerStallInt,
  115499. + _EventHandler_PowerStall
  115500. + ));
  115501. +
  115502. + /***********************************************************************
  115503. + ** Task management initialization.
  115504. + */
  115505. +
  115506. + command->taskStorage = gcvNULL;
  115507. + command->taskStorageGranularity = TaskGranularity;
  115508. + command->taskStorageUsable = TaskGranularity - gcmSIZEOF(gcsTASK_STORAGE);
  115509. +
  115510. + command->taskFreeHead = gcvNULL;
  115511. + command->taskFreeTail = gcvNULL;
  115512. +
  115513. + /* Enable block handlers. */
  115514. + for (i = 0; i < gcmCOUNTOF(_blockHandlers); i += 1)
  115515. + {
  115516. + /* Get the target hardware block. */
  115517. + gceBLOCK block = _blockHandlers[i].block;
  115518. +
  115519. + /* Get the interrupt array entry. */
  115520. + gcsBLOCK_TASK_ENTRY_PTR entry = &command->taskTable[block];
  115521. +
  115522. + /* Determine the interrupt value index. */
  115523. + gctUINT index = entry->interruptCount;
  115524. +
  115525. + /* Create the block semaphore. */
  115526. + if (entry->interruptSemaphore == gcvNULL)
  115527. + {
  115528. + gcmkERR_BREAK(gckOS_CreateSemaphoreVG(
  115529. + command->os, &entry->interruptSemaphore
  115530. + ));
  115531. + }
  115532. +
  115533. + /* Enable auto-detection. */
  115534. + entry->interruptArray[index] = -1;
  115535. +
  115536. + /* Enable interrupt for the block. */
  115537. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  115538. + Kernel->interrupt,
  115539. + &entry->interruptArray[index],
  115540. + _blockHandlers[i].handler
  115541. + ));
  115542. +
  115543. + /* Update the number of registered interrupts. */
  115544. + entry->interruptCount += 1;
  115545. +
  115546. + /* Inrement the semaphore to allow the usage of the registered
  115547. + interrupt. */
  115548. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  115549. + command->os, entry->interruptSemaphore
  115550. + ));
  115551. +
  115552. + }
  115553. +
  115554. + /* Error? */
  115555. + if (gcmkIS_ERROR(status))
  115556. + {
  115557. + break;
  115558. + }
  115559. +
  115560. + /* Get the FE interrupt. */
  115561. + command->info.feBufferInt
  115562. + = command->taskTable[gcvBLOCK_COMMAND].interruptArray[0];
  115563. +
  115564. + /* Return gckVGCOMMAND object pointer. */
  115565. + *Command = command;
  115566. +
  115567. + gcmkFOOTER_ARG("*Command=0x%x",*Command);
  115568. + /* Success. */
  115569. + return gcvSTATUS_OK;
  115570. + }
  115571. + while (gcvFALSE);
  115572. +
  115573. + /* Roll back. */
  115574. + if (command != gcvNULL)
  115575. + {
  115576. + /* Disable block handlers. */
  115577. + for (i = 0; i < gcvBLOCK_COUNT; i += 1)
  115578. + {
  115579. + /* Get the task table entry. */
  115580. + gcsBLOCK_TASK_ENTRY_PTR entry = &command->taskTable[i];
  115581. +
  115582. + /* Destroy the semaphore. */
  115583. + if (entry->interruptSemaphore != gcvNULL)
  115584. + {
  115585. + gcmkCHECK_STATUS(gckOS_DestroySemaphore(
  115586. + command->os, entry->interruptSemaphore
  115587. + ));
  115588. + }
  115589. +
  115590. + /* Disable all enabled interrupts. */
  115591. + for (j = 0; j < entry->interruptCount; j += 1)
  115592. + {
  115593. + /* Must be a valid value. */
  115594. + gcmkASSERT(entry->interruptArray[j] >= 0);
  115595. + gcmkASSERT(entry->interruptArray[j] <= 31);
  115596. +
  115597. + /* Disable the interrupt. */
  115598. + gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
  115599. + Kernel->interrupt,
  115600. + entry->interruptArray[j]
  115601. + ));
  115602. + }
  115603. + }
  115604. +
  115605. + /* Disable the bus error interrupt. */
  115606. + gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
  115607. + Kernel->interrupt,
  115608. + command->busErrorInt
  115609. + ));
  115610. +
  115611. + /* Disable TS overflow interrupt. */
  115612. + if (command->info.tsOverflowInt != -1)
  115613. + {
  115614. + gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
  115615. + Kernel->interrupt,
  115616. + command->info.tsOverflowInt
  115617. + ));
  115618. + }
  115619. +
  115620. + /* Delete the commit mutex. */
  115621. + if (command->commitMutex != gcvNULL)
  115622. + {
  115623. + gcmkCHECK_STATUS(gckOS_DeleteMutex(
  115624. + Kernel->os, command->commitMutex
  115625. + ));
  115626. + }
  115627. +
  115628. + /* Delete the command queue mutex. */
  115629. + if (command->taskMutex != gcvNULL)
  115630. + {
  115631. + gcmkCHECK_STATUS(gckOS_DeleteMutex(
  115632. + Kernel->os, command->taskMutex
  115633. + ));
  115634. + }
  115635. +
  115636. + /* Delete the command queue mutex. */
  115637. + if (command->queueMutex != gcvNULL)
  115638. + {
  115639. + gcmkCHECK_STATUS(gckOS_DeleteMutex(
  115640. + Kernel->os, command->queueMutex
  115641. + ));
  115642. + }
  115643. +
  115644. + /* Delete the command queue. */
  115645. + if (command->queue != gcvNULL)
  115646. + {
  115647. + gcmkCHECK_STATUS(gckOS_Free(
  115648. + Kernel->os, command->queue
  115649. + ));
  115650. + }
  115651. +
  115652. + if (command->powerSemaphore != gcvNULL)
  115653. + {
  115654. + gcmkVERIFY_OK(gckOS_DestroySemaphore(
  115655. + Kernel->os, command->powerSemaphore));
  115656. + }
  115657. +
  115658. + if (command->powerStallSignal != gcvNULL)
  115659. + {
  115660. + /* Create the power management semaphore. */
  115661. + gcmkVERIFY_OK(gckOS_DestroySignal(
  115662. + Kernel->os,
  115663. + command->powerStallSignal));
  115664. + }
  115665. +
  115666. + /* Free the gckVGCOMMAND structure. */
  115667. + gcmkCHECK_STATUS(gckOS_Free(
  115668. + Kernel->os, command
  115669. + ));
  115670. + }
  115671. +
  115672. + gcmkFOOTER();
  115673. + /* Return the error. */
  115674. + return status;
  115675. +}
  115676. +
  115677. +gceSTATUS
  115678. +gckVGCOMMAND_Destroy(
  115679. + OUT gckVGCOMMAND Command
  115680. + )
  115681. +{
  115682. + gceSTATUS status = gcvSTATUS_OK;
  115683. +
  115684. + gcmkHEADER_ARG("Command=0x%x", Command);
  115685. +
  115686. + /* Verify the arguments. */
  115687. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  115688. +
  115689. + do
  115690. + {
  115691. + gctUINT i;
  115692. + gcsTASK_STORAGE_PTR nextStorage;
  115693. +
  115694. + if (Command->queueHead != gcvNULL)
  115695. + {
  115696. + /* Wait until the head becomes idle. */
  115697. + gcmkERR_BREAK(_WaitForIdle(Command, Command->queueHead));
  115698. + }
  115699. +
  115700. + /* Disable block handlers. */
  115701. + for (i = 0; i < gcvBLOCK_COUNT; i += 1)
  115702. + {
  115703. + /* Get the interrupt array entry. */
  115704. + gcsBLOCK_TASK_ENTRY_PTR entry = &Command->taskTable[i];
  115705. +
  115706. + /* Determine the index of the last interrupt in the array. */
  115707. + gctINT index = entry->interruptCount - 1;
  115708. +
  115709. + /* Destroy the semaphore. */
  115710. + if (entry->interruptSemaphore != gcvNULL)
  115711. + {
  115712. + gcmkERR_BREAK(gckOS_DestroySemaphore(
  115713. + Command->os, entry->interruptSemaphore
  115714. + ));
  115715. + }
  115716. +
  115717. + /* Disable all enabled interrupts. */
  115718. + while (index >= 0)
  115719. + {
  115720. + /* Must be a valid value. */
  115721. + gcmkASSERT(entry->interruptArray[index] >= 0);
  115722. + gcmkASSERT(entry->interruptArray[index] <= 31);
  115723. +
  115724. + /* Disable the interrupt. */
  115725. + gcmkERR_BREAK(gckVGINTERRUPT_Disable(
  115726. + Command->kernel->interrupt,
  115727. + entry->interruptArray[index]
  115728. + ));
  115729. +
  115730. + /* Update to the next interrupt. */
  115731. + index -= 1;
  115732. + entry->interruptCount -= 1;
  115733. + }
  115734. +
  115735. + /* Error? */
  115736. + if (gcmkIS_ERROR(status))
  115737. + {
  115738. + break;
  115739. + }
  115740. + }
  115741. +
  115742. + /* Error? */
  115743. + if (gcmkIS_ERROR(status))
  115744. + {
  115745. + break;
  115746. + }
  115747. +
  115748. + /* Disable the bus error interrupt. */
  115749. + gcmkERR_BREAK(gckVGINTERRUPT_Disable(
  115750. + Command->kernel->interrupt,
  115751. + Command->busErrorInt
  115752. + ));
  115753. +
  115754. + /* Disable TS overflow interrupt. */
  115755. + if (Command->info.tsOverflowInt != -1)
  115756. + {
  115757. + gcmkERR_BREAK(gckVGINTERRUPT_Disable(
  115758. + Command->kernel->interrupt,
  115759. + Command->info.tsOverflowInt
  115760. + ));
  115761. +
  115762. + Command->info.tsOverflowInt = -1;
  115763. + }
  115764. +
  115765. + /* Delete the commit mutex. */
  115766. + if (Command->commitMutex != gcvNULL)
  115767. + {
  115768. + gcmkERR_BREAK(gckOS_DeleteMutex(
  115769. + Command->os, Command->commitMutex
  115770. + ));
  115771. +
  115772. + Command->commitMutex = gcvNULL;
  115773. + }
  115774. +
  115775. + /* Delete the command queue mutex. */
  115776. + if (Command->taskMutex != gcvNULL)
  115777. + {
  115778. + gcmkERR_BREAK(gckOS_DeleteMutex(
  115779. + Command->os, Command->taskMutex
  115780. + ));
  115781. +
  115782. + Command->taskMutex = gcvNULL;
  115783. + }
  115784. +
  115785. + /* Delete the command queue mutex. */
  115786. + if (Command->queueMutex != gcvNULL)
  115787. + {
  115788. + gcmkERR_BREAK(gckOS_DeleteMutex(
  115789. + Command->os, Command->queueMutex
  115790. + ));
  115791. +
  115792. + Command->queueMutex = gcvNULL;
  115793. + }
  115794. +
  115795. + if (Command->powerSemaphore != gcvNULL)
  115796. + {
  115797. + /* Destroy the power management semaphore. */
  115798. + gcmkERR_BREAK(gckOS_DestroySemaphore(
  115799. + Command->os, Command->powerSemaphore));
  115800. + }
  115801. +
  115802. + if (Command->powerStallSignal != gcvNULL)
  115803. + {
  115804. + /* Create the power management semaphore. */
  115805. + gcmkERR_BREAK(gckOS_DestroySignal(
  115806. + Command->os,
  115807. + Command->powerStallSignal));
  115808. + }
  115809. +
  115810. + if (Command->queue != gcvNULL)
  115811. + {
  115812. + /* Delete the command queue. */
  115813. + gcmkERR_BREAK(gckOS_Free(
  115814. + Command->os, Command->queue
  115815. + ));
  115816. + }
  115817. +
  115818. + /* Destroy all allocated buffers. */
  115819. + while (Command->taskStorage)
  115820. + {
  115821. + /* Copy the buffer pointer. */
  115822. + nextStorage = Command->taskStorage->next;
  115823. +
  115824. + /* Free the current container. */
  115825. + gcmkERR_BREAK(gckOS_Free(
  115826. + Command->os, Command->taskStorage
  115827. + ));
  115828. +
  115829. + /* Advance to the next one. */
  115830. + Command->taskStorage = nextStorage;
  115831. + }
  115832. +
  115833. + /* Error? */
  115834. + if (gcmkIS_ERROR(status))
  115835. + {
  115836. + break;
  115837. + }
  115838. +
  115839. + /* Mark the object as unknown. */
  115840. + Command->object.type = gcvOBJ_UNKNOWN;
  115841. +
  115842. + /* Free the gckVGCOMMAND structure. */
  115843. + gcmkERR_BREAK(gckOS_Free(Command->os, Command));
  115844. +
  115845. + gcmkFOOTER_NO();
  115846. + /* Success. */
  115847. + return gcvSTATUS_OK;
  115848. + }
  115849. + while (gcvFALSE);
  115850. +
  115851. + /* Restore the object type if failed. */
  115852. + Command->object.type = gcvOBJ_COMMAND;
  115853. +
  115854. + gcmkFOOTER();
  115855. + /* Return the error. */
  115856. + return status;
  115857. +}
  115858. +
  115859. +gceSTATUS
  115860. +gckVGCOMMAND_QueryCommandBuffer(
  115861. + IN gckVGCOMMAND Command,
  115862. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  115863. + )
  115864. +{
  115865. + gcmkHEADER_ARG("Command=0x%x Information=0x%x", Command, Information);
  115866. + /* Verify the arguments. */
  115867. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  115868. + gcmkVERIFY_ARGUMENT(Information != gcvNULL);
  115869. +
  115870. + /* Copy the information. */
  115871. + gcmkVERIFY_OK(gckOS_MemCopy(
  115872. + Information, &Command->info, sizeof(gcsCOMMAND_BUFFER_INFO)
  115873. + ));
  115874. +
  115875. + gcmkFOOTER_NO();
  115876. + /* Success. */
  115877. + return gcvSTATUS_OK;
  115878. +}
  115879. +
  115880. +gceSTATUS
  115881. +gckVGCOMMAND_Allocate(
  115882. + IN gckVGCOMMAND Command,
  115883. + IN gctSIZE_T Size,
  115884. + OUT gcsCMDBUFFER_PTR * CommandBuffer,
  115885. + OUT gctPOINTER * Data
  115886. + )
  115887. +{
  115888. + gceSTATUS status;
  115889. +
  115890. + gcmkHEADER_ARG("Command=0x%x Size=0x%x CommandBuffer=0x%x Data=0x%x",
  115891. + Command, Size, CommandBuffer, Data);
  115892. +
  115893. + /* Verify the arguments. */
  115894. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  115895. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  115896. +
  115897. + do
  115898. + {
  115899. + /* Allocate the buffer. */
  115900. + gcmkERR_BREAK(_AllocateCommandBuffer(Command, Size, CommandBuffer));
  115901. +
  115902. + /* Determine the data pointer. */
  115903. + * Data = (gctUINT8_PTR) (*CommandBuffer) + (* CommandBuffer)->bufferOffset;
  115904. + }
  115905. + while (gcvFALSE);
  115906. +
  115907. + gcmkFOOTER();
  115908. + /* Return status. */
  115909. + return status;
  115910. +}
  115911. +
  115912. +gceSTATUS
  115913. +gckVGCOMMAND_Free(
  115914. + IN gckVGCOMMAND Command,
  115915. + IN gcsCMDBUFFER_PTR CommandBuffer
  115916. + )
  115917. +{
  115918. + gceSTATUS status;
  115919. +
  115920. + gcmkHEADER_ARG("Command=0x%x CommandBuffer=0x%x",
  115921. + Command, CommandBuffer);
  115922. +
  115923. + /* Verify the arguments. */
  115924. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  115925. + gcmkVERIFY_ARGUMENT(CommandBuffer != gcvNULL);
  115926. +
  115927. + /* Free command buffer. */
  115928. + status = _FreeCommandBuffer(Command->kernel, CommandBuffer);
  115929. +
  115930. + gcmkFOOTER();
  115931. + /* Return status. */
  115932. + return status;
  115933. +}
  115934. +
  115935. +gceSTATUS
  115936. +gckVGCOMMAND_Execute(
  115937. + IN gckVGCOMMAND Command,
  115938. + IN gcsCMDBUFFER_PTR CommandBuffer
  115939. + )
  115940. +{
  115941. + gceSTATUS status;
  115942. +
  115943. + gcmkHEADER_ARG("Command=0x%x CommandBuffer=0x%x",
  115944. + Command, CommandBuffer);
  115945. +
  115946. + /* Verify the arguments. */
  115947. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  115948. + gcmkVERIFY_ARGUMENT(CommandBuffer != gcvNULL);
  115949. +
  115950. + do
  115951. + {
  115952. + gctUINT queueLength;
  115953. + gcsKERNEL_CMDQUEUE_PTR kernelEntry;
  115954. +
  115955. + /* Lock the current queue. */
  115956. + gcmkERR_BREAK(_LockCurrentQueue(
  115957. + Command, &kernelEntry, &queueLength
  115958. + ));
  115959. +
  115960. + /* Set the buffer. */
  115961. + kernelEntry->commandBuffer = CommandBuffer;
  115962. + kernelEntry->handler = _FreeKernelCommandBuffer;
  115963. +
  115964. + /* Lock the current queue. */
  115965. + gcmkERR_BREAK(_UnlockCurrentQueue(
  115966. + Command, 1
  115967. + ));
  115968. + }
  115969. + while (gcvFALSE);
  115970. +
  115971. + gcmkFOOTER();
  115972. + /* Return status. */
  115973. + return status;
  115974. +}
  115975. +
  115976. +gceSTATUS
  115977. +gckVGCOMMAND_Commit(
  115978. + IN gckVGCOMMAND Command,
  115979. + IN gcsVGCONTEXT_PTR Context,
  115980. + IN gcsVGCMDQUEUE_PTR Queue,
  115981. + IN gctUINT EntryCount,
  115982. + IN gcsTASK_MASTER_TABLE_PTR TaskTable
  115983. + )
  115984. +{
  115985. + /*
  115986. + The first buffer is executed through a direct gckVGHARDWARE_Execute call,
  115987. + therefore only an update is needed after the execution is over. All
  115988. + consequent buffers need to be executed upon the first update call from
  115989. + the FE interrupt handler.
  115990. + */
  115991. +
  115992. + static gcsQUEUE_UPDATE_CONTROL _dynamicBuffer[] =
  115993. + {
  115994. + {
  115995. + _UpdateDynamicCommandBuffer,
  115996. + _UpdateDynamicCommandBuffer,
  115997. + _UpdateLastDynamicCommandBuffer,
  115998. + _UpdateLastDynamicCommandBuffer
  115999. + },
  116000. + {
  116001. + _ExecuteDynamicCommandBuffer,
  116002. + _UpdateDynamicCommandBuffer,
  116003. + _ExecuteLastDynamicCommandBuffer,
  116004. + _UpdateLastDynamicCommandBuffer
  116005. + }
  116006. + };
  116007. +
  116008. + static gcsQUEUE_UPDATE_CONTROL _staticBuffer[] =
  116009. + {
  116010. + {
  116011. + _UpdateStaticCommandBuffer,
  116012. + _UpdateStaticCommandBuffer,
  116013. + _UpdateLastStaticCommandBuffer,
  116014. + _UpdateLastStaticCommandBuffer
  116015. + },
  116016. + {
  116017. + _ExecuteStaticCommandBuffer,
  116018. + _UpdateStaticCommandBuffer,
  116019. + _ExecuteLastStaticCommandBuffer,
  116020. + _UpdateLastStaticCommandBuffer
  116021. + }
  116022. + };
  116023. +
  116024. + gceSTATUS status, last;
  116025. +
  116026. + gcmkHEADER_ARG("Command=0x%x Context=0x%x Queue=0x%x EntryCount=0x%x TaskTable=0x%x",
  116027. + Command, Context, Queue, EntryCount, TaskTable);
  116028. +
  116029. + /* Verify the arguments. */
  116030. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  116031. + gcmkVERIFY_ARGUMENT(Context != gcvNULL);
  116032. + gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
  116033. + gcmkVERIFY_ARGUMENT(EntryCount > 1);
  116034. +
  116035. +#ifdef __QNXNTO__
  116036. + TaskTable->coid = Context->coid;
  116037. + TaskTable->rcvid = Context->rcvid;
  116038. +#endif /* __QNXNTO__ */
  116039. +
  116040. + do
  116041. + {
  116042. + gctBOOL haveFETasks;
  116043. + gctUINT queueSize;
  116044. + gcsVGCMDQUEUE_PTR mappedQueue;
  116045. + gcsVGCMDQUEUE_PTR userEntry;
  116046. + gcsKERNEL_CMDQUEUE_PTR kernelEntry;
  116047. + gcsQUEUE_UPDATE_CONTROL_PTR queueControl;
  116048. + gctUINT currentLength;
  116049. + gctUINT queueLength;
  116050. + gctUINT entriesQueued;
  116051. + gctUINT8_PTR previousEnd;
  116052. + gctBOOL previousDynamic;
  116053. + gctBOOL previousExecuted;
  116054. + gctUINT controlIndex;
  116055. +
  116056. + gcmkERR_BREAK(gckVGHARDWARE_SetPowerManagementState(
  116057. + Command->hardware, gcvPOWER_ON_AUTO
  116058. + ));
  116059. +
  116060. + /* Acquire the power semaphore. */
  116061. + gcmkERR_BREAK(gckOS_AcquireSemaphore(
  116062. + Command->os, Command->powerSemaphore
  116063. + ));
  116064. +
  116065. + /* Acquire the mutex. */
  116066. + status = gckOS_AcquireMutex(
  116067. + Command->os,
  116068. + Command->commitMutex,
  116069. + gcvINFINITE
  116070. + );
  116071. +
  116072. + if (gcmIS_ERROR(status))
  116073. + {
  116074. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
  116075. + Command->os, Command->powerSemaphore));
  116076. + break;
  116077. + }
  116078. +
  116079. + do
  116080. + {
  116081. + gcmkERR_BREAK(_FlushMMU(Command));
  116082. +
  116083. + /* Assign a context ID if not yet assigned. */
  116084. + if (Context->id == 0)
  116085. + {
  116086. + /* Assign the next context number. */
  116087. + Context->id = ++ Command->contextCounter;
  116088. +
  116089. + /* See if we overflowed. */
  116090. + if (Command->contextCounter == 0)
  116091. + {
  116092. + /* We actually did overflow, wow... */
  116093. + status = gcvSTATUS_OUT_OF_RESOURCES;
  116094. + break;
  116095. + }
  116096. + }
  116097. +
  116098. + /* The first entry in the queue is always the context buffer.
  116099. + Verify whether the user context is the same as the current
  116100. + context and if that's the case, skip the first entry. */
  116101. + if (Context->id == Command->currentContext)
  116102. + {
  116103. + /* Same context as before, skip the first entry. */
  116104. + EntryCount -= 1;
  116105. + Queue += 1;
  116106. +
  116107. + /* Set the signal to avoid user waiting. */
  116108. +#ifdef __QNXNTO__
  116109. + gcmkERR_BREAK(gckOS_UserSignal(
  116110. + Command->os, Context->signal, Context->rcvid, Context->coid
  116111. + ));
  116112. +#else
  116113. + gcmkERR_BREAK(gckOS_UserSignal(
  116114. + Command->os, Context->signal, Context->process
  116115. + ));
  116116. +
  116117. +#endif /* __QNXNTO__ */
  116118. +
  116119. + }
  116120. + else
  116121. + {
  116122. + /* Different user context - keep the first entry.
  116123. + Set the user context as the current one. */
  116124. + Command->currentContext = Context->id;
  116125. + }
  116126. +
  116127. + /* Reset pointers. */
  116128. + queueControl = gcvNULL;
  116129. + previousEnd = gcvNULL;
  116130. +
  116131. + /* Determine whether there are FE tasks to be performed. */
  116132. + haveFETasks = (TaskTable->table[gcvBLOCK_COMMAND].head != gcvNULL);
  116133. +
  116134. + /* Determine the size of the queue. */
  116135. + queueSize = EntryCount * gcmSIZEOF(gcsVGCMDQUEUE);
  116136. +
  116137. + /* Map the command queue into the kernel space. */
  116138. + gcmkERR_BREAK(gckOS_MapUserPointer(
  116139. + Command->os,
  116140. + Queue,
  116141. + queueSize,
  116142. + (gctPOINTER *) &mappedQueue
  116143. + ));
  116144. +
  116145. + /* Set the first entry. */
  116146. + userEntry = mappedQueue;
  116147. +
  116148. + /* Process the command queue. */
  116149. + while (EntryCount)
  116150. + {
  116151. + /* Lock the current queue. */
  116152. + gcmkERR_BREAK(_LockCurrentQueue(
  116153. + Command, &kernelEntry, &queueLength
  116154. + ));
  116155. +
  116156. + /* Determine the number of entries to process. */
  116157. + currentLength = (queueLength < EntryCount)
  116158. + ? queueLength
  116159. + : EntryCount;
  116160. +
  116161. + /* Update the number of the entries left to process. */
  116162. + EntryCount -= currentLength;
  116163. +
  116164. + /* Reset previous flags. */
  116165. + previousDynamic = gcvFALSE;
  116166. + previousExecuted = gcvFALSE;
  116167. +
  116168. + /* Set the initial control index. */
  116169. + controlIndex = 0;
  116170. +
  116171. + /* Process entries. */
  116172. + for (entriesQueued = 0; entriesQueued < currentLength; entriesQueued += 1)
  116173. + {
  116174. + /* Get the kernel pointer to the command buffer header. */
  116175. + gcsCMDBUFFER_PTR commandBuffer = gcvNULL;
  116176. + gcmkERR_BREAK(_ConvertUserCommandBufferPointer(
  116177. + Command,
  116178. + userEntry->commandBuffer,
  116179. + &commandBuffer
  116180. + ));
  116181. +
  116182. + /* Is it a dynamic command buffer? */
  116183. + if (userEntry->dynamic)
  116184. + {
  116185. + /* Select dynamic buffer control functions. */
  116186. + queueControl = &_dynamicBuffer[controlIndex];
  116187. + }
  116188. +
  116189. + /* No, a static command buffer. */
  116190. + else
  116191. + {
  116192. + /* Select static buffer control functions. */
  116193. + queueControl = &_staticBuffer[controlIndex];
  116194. + }
  116195. +
  116196. + /* Set the command buffer pointer to the entry. */
  116197. + kernelEntry->commandBuffer = commandBuffer;
  116198. +
  116199. + /* If the previous entry was a dynamic command buffer,
  116200. + link it to the current. */
  116201. + if (previousDynamic)
  116202. + {
  116203. + gcmkERR_BREAK(gckVGCOMMAND_FetchCommand(
  116204. + Command,
  116205. + previousEnd,
  116206. + commandBuffer->address,
  116207. + commandBuffer->dataCount,
  116208. + gcvNULL
  116209. + ));
  116210. +
  116211. + /* The buffer will be auto-executed, only need to
  116212. + update it after it has been executed. */
  116213. + kernelEntry->handler = queueControl->update;
  116214. +
  116215. + /* The buffer is only being updated. */
  116216. + previousExecuted = gcvFALSE;
  116217. + }
  116218. + else
  116219. + {
  116220. + /* Set the buffer up for execution. */
  116221. + kernelEntry->handler = queueControl->execute;
  116222. +
  116223. + /* The buffer is being updated. */
  116224. + previousExecuted = gcvTRUE;
  116225. + }
  116226. +
  116227. + /* The current buffer's END command becomes the last END. */
  116228. + previousEnd
  116229. + = ((gctUINT8_PTR) commandBuffer)
  116230. + + commandBuffer->bufferOffset
  116231. + + commandBuffer->dataCount * Command->info.commandAlignment
  116232. + - Command->info.staticTailSize;
  116233. +
  116234. + /* Update the last entry info. */
  116235. + previousDynamic = userEntry->dynamic;
  116236. +
  116237. + /* Advance entries. */
  116238. + userEntry += 1;
  116239. + kernelEntry += 1;
  116240. +
  116241. + /* Update the control index. */
  116242. + controlIndex = 1;
  116243. + }
  116244. +
  116245. + /* If the previous entry was a dynamic command buffer,
  116246. + terminate it with an END. */
  116247. + if (previousDynamic)
  116248. + {
  116249. + gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
  116250. + Command,
  116251. + previousEnd,
  116252. + Command->info.feBufferInt,
  116253. + gcvNULL
  116254. + ));
  116255. + }
  116256. +
  116257. + /* Last buffer? */
  116258. + if (EntryCount == 0)
  116259. + {
  116260. + /* Modify the last command buffer's routines to handle
  116261. + tasks if any.*/
  116262. + if (haveFETasks)
  116263. + {
  116264. + if (previousExecuted)
  116265. + {
  116266. + kernelEntry[-1].handler = queueControl->lastExecute;
  116267. + }
  116268. + else
  116269. + {
  116270. + kernelEntry[-1].handler = queueControl->lastUpdate;
  116271. + }
  116272. + }
  116273. +
  116274. + /* Release the mutex. */
  116275. + gcmkERR_BREAK(gckOS_ReleaseMutex(
  116276. + Command->os,
  116277. + Command->queueMutex
  116278. + ));
  116279. + /* Schedule tasks. */
  116280. + gcmkERR_BREAK(_ScheduleTasks(Command, TaskTable, previousEnd));
  116281. +
  116282. + /* Acquire the mutex. */
  116283. + gcmkERR_BREAK(gckOS_AcquireMutex(
  116284. + Command->os,
  116285. + Command->queueMutex,
  116286. + gcvINFINITE
  116287. + ));
  116288. + }
  116289. +
  116290. + /* Unkock and schedule the current queue for execution. */
  116291. + gcmkERR_BREAK(_UnlockCurrentQueue(
  116292. + Command, currentLength
  116293. + ));
  116294. + }
  116295. +
  116296. +
  116297. + /* Unmap the user command buffer. */
  116298. + gcmkERR_BREAK(gckOS_UnmapUserPointer(
  116299. + Command->os,
  116300. + Queue,
  116301. + queueSize,
  116302. + mappedQueue
  116303. + ));
  116304. + }
  116305. + while (gcvFALSE);
  116306. +
  116307. + /* Release the mutex. */
  116308. + gcmkCHECK_STATUS(gckOS_ReleaseMutex(
  116309. + Command->os,
  116310. + Command->commitMutex
  116311. + ));
  116312. +
  116313. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
  116314. + Command->os, Command->powerSemaphore));
  116315. + }
  116316. + while (gcvFALSE);
  116317. +
  116318. + gcmkFOOTER();
  116319. + /* Return status. */
  116320. + return status;
  116321. +}
  116322. +
  116323. +#endif /* gcdENABLE_VG */
  116324. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
  116325. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c 1970-01-01 01:00:00.000000000 +0100
  116326. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c 2014-08-20 19:31:46.128869007 +0200
  116327. @@ -0,0 +1,1604 @@
  116328. +/****************************************************************************
  116329. +*
  116330. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  116331. +*
  116332. +* This program is free software; you can redistribute it and/or modify
  116333. +* it under the terms of the GNU General Public License as published by
  116334. +* the Free Software Foundation; either version 2 of the license, or
  116335. +* (at your option) any later version.
  116336. +*
  116337. +* This program is distributed in the hope that it will be useful,
  116338. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  116339. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  116340. +* GNU General Public License for more details.
  116341. +*
  116342. +* You should have received a copy of the GNU General Public License
  116343. +* along with this program; if not write to the Free Software
  116344. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  116345. +*
  116346. +*****************************************************************************/
  116347. +
  116348. +
  116349. +#include "gc_hal_kernel_precomp.h"
  116350. +
  116351. +#define _GC_OBJ_ZONE gcvZONE_DATABASE
  116352. +
  116353. +/*******************************************************************************
  116354. +***** Private fuctions ********************************************************/
  116355. +
  116356. +#define _GetSlot(database, x) \
  116357. + (gctUINT32)(((gcmPTR_TO_UINT64(x) >> 7) % gcmCOUNTOF(database->list)))
  116358. +
  116359. +/*******************************************************************************
  116360. +** gckKERNEL_NewDatabase
  116361. +**
  116362. +** Create a new database structure and insert it to the head of the hash list.
  116363. +**
  116364. +** INPUT:
  116365. +**
  116366. +** gckKERNEL Kernel
  116367. +** Pointer to a gckKERNEL object.
  116368. +**
  116369. +** gctUINT32 ProcessID
  116370. +** ProcessID that identifies the database.
  116371. +**
  116372. +** OUTPUT:
  116373. +**
  116374. +** gcsDATABASE_PTR * Database
  116375. +** Pointer to a variable receiving the database structure pointer on
  116376. +** success.
  116377. +*/
  116378. +static gceSTATUS
  116379. +gckKERNEL_NewDatabase(
  116380. + IN gckKERNEL Kernel,
  116381. + IN gctUINT32 ProcessID,
  116382. + OUT gcsDATABASE_PTR * Database
  116383. + )
  116384. +{
  116385. + gceSTATUS status;
  116386. + gcsDATABASE_PTR database;
  116387. + gctBOOL acquired = gcvFALSE;
  116388. + gctSIZE_T slot;
  116389. + gcsDATABASE_PTR existingDatabase;
  116390. +
  116391. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  116392. +
  116393. + /* Acquire the database mutex. */
  116394. + gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116395. + acquired = gcvTRUE;
  116396. +
  116397. + /* Compute the hash for the database. */
  116398. + slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
  116399. +
  116400. + /* Walk the hash list. */
  116401. + for (existingDatabase = Kernel->db->db[slot];
  116402. + existingDatabase != gcvNULL;
  116403. + existingDatabase = existingDatabase->next)
  116404. + {
  116405. + if (existingDatabase->processID == ProcessID)
  116406. + {
  116407. + /* One process can't be added twice. */
  116408. + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
  116409. + }
  116410. + }
  116411. +
  116412. + if (Kernel->db->freeDatabase != gcvNULL)
  116413. + {
  116414. + /* Allocate a database from the free list. */
  116415. + database = Kernel->db->freeDatabase;
  116416. + Kernel->db->freeDatabase = database->next;
  116417. + }
  116418. + else
  116419. + {
  116420. + gctPOINTER pointer = gcvNULL;
  116421. +
  116422. + /* Allocate a new database from the heap. */
  116423. + gcmkONERROR(gckOS_Allocate(Kernel->os,
  116424. + gcmSIZEOF(gcsDATABASE),
  116425. + &pointer));
  116426. +
  116427. + database = pointer;
  116428. + }
  116429. +
  116430. + /* Insert the database into the hash. */
  116431. + database->next = Kernel->db->db[slot];
  116432. + Kernel->db->db[slot] = database;
  116433. +
  116434. + /* Save the hash slot. */
  116435. + database->slot = slot;
  116436. +
  116437. + /* Release the database mutex. */
  116438. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116439. +
  116440. + /* Return the database. */
  116441. + *Database = database;
  116442. +
  116443. + /* Success. */
  116444. + gcmkFOOTER_ARG("*Database=0x%x", *Database);
  116445. + return gcvSTATUS_OK;
  116446. +
  116447. +OnError:
  116448. + if (acquired)
  116449. + {
  116450. + /* Release the database mutex. */
  116451. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116452. + }
  116453. +
  116454. + /* Return the status. */
  116455. + gcmkFOOTER();
  116456. + return status;
  116457. +}
  116458. +
  116459. +/*******************************************************************************
  116460. +** gckKERNEL_FindDatabase
  116461. +**
  116462. +** Find a database identified by a process ID and move it to the head of the
  116463. +** hash list.
  116464. +**
  116465. +** INPUT:
  116466. +**
  116467. +** gckKERNEL Kernel
  116468. +** Pointer to a gckKERNEL object.
  116469. +**
  116470. +** gctUINT32 ProcessID
  116471. +** ProcessID that identifies the database.
  116472. +**
  116473. +** gctBOOL LastProcessID
  116474. +** gcvTRUE if searching for the last known process ID. gcvFALSE if
  116475. +** we need to search for the process ID specified by the ProcessID
  116476. +** argument.
  116477. +**
  116478. +** OUTPUT:
  116479. +**
  116480. +** gcsDATABASE_PTR * Database
  116481. +** Pointer to a variable receiving the database structure pointer on
  116482. +** success.
  116483. +*/
  116484. +static gceSTATUS
  116485. +gckKERNEL_FindDatabase(
  116486. + IN gckKERNEL Kernel,
  116487. + IN gctUINT32 ProcessID,
  116488. + IN gctBOOL LastProcessID,
  116489. + OUT gcsDATABASE_PTR * Database
  116490. + )
  116491. +{
  116492. + gceSTATUS status;
  116493. + gcsDATABASE_PTR database, previous;
  116494. + gctSIZE_T slot;
  116495. + gctBOOL acquired = gcvFALSE;
  116496. +
  116497. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d LastProcessID=%d",
  116498. + Kernel, ProcessID, LastProcessID);
  116499. +
  116500. + /* Compute the hash for the database. */
  116501. + slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
  116502. +
  116503. + /* Acquire the database mutex. */
  116504. + gcmkONERROR(
  116505. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116506. + acquired = gcvTRUE;
  116507. +
  116508. + /* Check whether we are getting the last known database. */
  116509. + if (LastProcessID)
  116510. + {
  116511. + /* Use last database. */
  116512. + database = Kernel->db->lastDatabase;
  116513. +
  116514. + if (database == gcvNULL)
  116515. + {
  116516. + /* Database not found. */
  116517. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  116518. + }
  116519. + }
  116520. + else
  116521. + {
  116522. + /* Walk the hash list. */
  116523. + for (previous = gcvNULL, database = Kernel->db->db[slot];
  116524. + database != gcvNULL;
  116525. + database = database->next)
  116526. + {
  116527. + if (database->processID == ProcessID)
  116528. + {
  116529. + /* Found it! */
  116530. + break;
  116531. + }
  116532. +
  116533. + previous = database;
  116534. + }
  116535. +
  116536. + if (database == gcvNULL)
  116537. + {
  116538. + /* Database not found. */
  116539. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  116540. + }
  116541. +
  116542. + if (previous != gcvNULL)
  116543. + {
  116544. + /* Move database to the head of the hash list. */
  116545. + previous->next = database->next;
  116546. + database->next = Kernel->db->db[slot];
  116547. + Kernel->db->db[slot] = database;
  116548. + }
  116549. + }
  116550. +
  116551. + /* Release the database mutex. */
  116552. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116553. +
  116554. + /* Return the database. */
  116555. + *Database = database;
  116556. +
  116557. + /* Success. */
  116558. + gcmkFOOTER_ARG("*Database=0x%x", *Database);
  116559. + return gcvSTATUS_OK;
  116560. +
  116561. +OnError:
  116562. + if (acquired)
  116563. + {
  116564. + /* Release the database mutex. */
  116565. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116566. + }
  116567. +
  116568. + /* Return the status. */
  116569. + gcmkFOOTER();
  116570. + return status;
  116571. +}
  116572. +
  116573. +/*******************************************************************************
  116574. +** gckKERNEL_DeleteDatabase
  116575. +**
  116576. +** Remove a database from the hash list and delete its structure.
  116577. +**
  116578. +** INPUT:
  116579. +**
  116580. +** gckKERNEL Kernel
  116581. +** Pointer to a gckKERNEL object.
  116582. +**
  116583. +** gcsDATABASE_PTR Database
  116584. +** Pointer to the database structure to remove.
  116585. +**
  116586. +** OUTPUT:
  116587. +**
  116588. +** Nothing.
  116589. +*/
  116590. +static gceSTATUS
  116591. +gckKERNEL_DeleteDatabase(
  116592. + IN gckKERNEL Kernel,
  116593. + IN gcsDATABASE_PTR Database
  116594. + )
  116595. +{
  116596. + gceSTATUS status;
  116597. + gctBOOL acquired = gcvFALSE;
  116598. + gcsDATABASE_PTR database;
  116599. +
  116600. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
  116601. +
  116602. + /* Acquire the database mutex. */
  116603. + gcmkONERROR(
  116604. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116605. + acquired = gcvTRUE;
  116606. +
  116607. + /* Check slot value. */
  116608. + gcmkVERIFY_ARGUMENT(Database->slot < gcmCOUNTOF(Kernel->db->db));
  116609. +
  116610. + if (Database->slot < gcmCOUNTOF(Kernel->db->db))
  116611. + {
  116612. + /* Check if database if the head of the hash list. */
  116613. + if (Kernel->db->db[Database->slot] == Database)
  116614. + {
  116615. + /* Remove the database from the hash list. */
  116616. + Kernel->db->db[Database->slot] = Database->next;
  116617. + }
  116618. + else
  116619. + {
  116620. + /* Walk the has list to find the database. */
  116621. + for (database = Kernel->db->db[Database->slot];
  116622. + database != gcvNULL;
  116623. + database = database->next
  116624. + )
  116625. + {
  116626. + /* Check if the next list entry is this database. */
  116627. + if (database->next == Database)
  116628. + {
  116629. + /* Remove the database from the hash list. */
  116630. + database->next = Database->next;
  116631. + break;
  116632. + }
  116633. + }
  116634. +
  116635. + if (database == gcvNULL)
  116636. + {
  116637. + /* Ouch! Something got corrupted. */
  116638. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  116639. + }
  116640. + }
  116641. + }
  116642. +
  116643. + if (Kernel->db->lastDatabase != gcvNULL)
  116644. + {
  116645. + /* Insert database to the free list. */
  116646. + Kernel->db->lastDatabase->next = Kernel->db->freeDatabase;
  116647. + Kernel->db->freeDatabase = Kernel->db->lastDatabase;
  116648. + }
  116649. +
  116650. + /* Keep database as the last database. */
  116651. + Kernel->db->lastDatabase = Database;
  116652. +
  116653. + /* Release the database mutex. */
  116654. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116655. +
  116656. + /* Success. */
  116657. + gcmkFOOTER_NO();
  116658. + return gcvSTATUS_OK;
  116659. +
  116660. +OnError:
  116661. + if (acquired)
  116662. + {
  116663. + /* Release the database mutex. */
  116664. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116665. + }
  116666. +
  116667. + /* Return the status. */
  116668. + gcmkFOOTER();
  116669. + return status;
  116670. +}
  116671. +
  116672. +/*******************************************************************************
  116673. +** gckKERNEL_NewRecord
  116674. +**
  116675. +** Create a new database record structure and insert it to the head of the
  116676. +** database.
  116677. +**
  116678. +** INPUT:
  116679. +**
  116680. +** gckKERNEL Kernel
  116681. +** Pointer to a gckKERNEL object.
  116682. +**
  116683. +** gcsDATABASE_PTR Database
  116684. +** Pointer to a database structure.
  116685. +**
  116686. +** OUTPUT:
  116687. +**
  116688. +** gcsDATABASE_RECORD_PTR * Record
  116689. +** Pointer to a variable receiving the database record structure
  116690. +** pointer on success.
  116691. +*/
  116692. +static gceSTATUS
  116693. +gckKERNEL_NewRecord(
  116694. + IN gckKERNEL Kernel,
  116695. + IN gcsDATABASE_PTR Database,
  116696. + IN gctUINT32 Slot,
  116697. + OUT gcsDATABASE_RECORD_PTR * Record
  116698. + )
  116699. +{
  116700. + gceSTATUS status;
  116701. + gctBOOL acquired = gcvFALSE;
  116702. + gcsDATABASE_RECORD_PTR record = gcvNULL;
  116703. +
  116704. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
  116705. +
  116706. + /* Acquire the database mutex. */
  116707. + gcmkONERROR(
  116708. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116709. + acquired = gcvTRUE;
  116710. +
  116711. + if (Kernel->db->freeRecord != gcvNULL)
  116712. + {
  116713. + /* Allocate the record from the free list. */
  116714. + record = Kernel->db->freeRecord;
  116715. + Kernel->db->freeRecord = record->next;
  116716. + }
  116717. + else
  116718. + {
  116719. + gctPOINTER pointer = gcvNULL;
  116720. +
  116721. + /* Allocate the record from the heap. */
  116722. + gcmkONERROR(gckOS_Allocate(Kernel->os,
  116723. + gcmSIZEOF(gcsDATABASE_RECORD),
  116724. + &pointer));
  116725. +
  116726. + record = pointer;
  116727. + }
  116728. +
  116729. + /* Insert the record in the database. */
  116730. + record->next = Database->list[Slot];
  116731. + Database->list[Slot] = record;
  116732. +
  116733. + /* Release the database mutex. */
  116734. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116735. +
  116736. + /* Return the record. */
  116737. + *Record = record;
  116738. +
  116739. + /* Success. */
  116740. + gcmkFOOTER_ARG("*Record=0x%x", *Record);
  116741. + return gcvSTATUS_OK;
  116742. +
  116743. +OnError:
  116744. + if (acquired)
  116745. + {
  116746. + /* Release the database mutex. */
  116747. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116748. + }
  116749. + if (record != gcvNULL)
  116750. + {
  116751. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, record));
  116752. + }
  116753. +
  116754. + /* Return the status. */
  116755. + gcmkFOOTER();
  116756. + return status;
  116757. +}
  116758. +
  116759. +/*******************************************************************************
  116760. +** gckKERNEL_DeleteRecord
  116761. +**
  116762. +** Remove a database record from the database and delete its structure.
  116763. +**
  116764. +** INPUT:
  116765. +**
  116766. +** gckKERNEL Kernel
  116767. +** Pointer to a gckKERNEL object.
  116768. +**
  116769. +** gcsDATABASE_PTR Database
  116770. +** Pointer to a database structure.
  116771. +**
  116772. +** gceDATABASE_TYPE Type
  116773. +** Type of the record to remove.
  116774. +**
  116775. +** gctPOINTER Data
  116776. +** Data of the record to remove.
  116777. +**
  116778. +** OUTPUT:
  116779. +**
  116780. +** gctSIZE_T_PTR Bytes
  116781. +** Pointer to a variable that receives the size of the record deleted.
  116782. +** Can be gcvNULL if the size is not required.
  116783. +*/
  116784. +static gceSTATUS
  116785. +gckKERNEL_DeleteRecord(
  116786. + IN gckKERNEL Kernel,
  116787. + IN gcsDATABASE_PTR Database,
  116788. + IN gceDATABASE_TYPE Type,
  116789. + IN gctPOINTER Data,
  116790. + OUT gctSIZE_T_PTR Bytes OPTIONAL
  116791. + )
  116792. +{
  116793. + gceSTATUS status;
  116794. + gctBOOL acquired = gcvFALSE;
  116795. + gcsDATABASE_RECORD_PTR record, previous;
  116796. + gctUINT32 slot = _GetSlot(Database, Data);
  116797. +
  116798. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
  116799. + Kernel, Database, Type, Data);
  116800. +
  116801. + /* Acquire the database mutex. */
  116802. + gcmkONERROR(
  116803. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116804. + acquired = gcvTRUE;
  116805. +
  116806. +
  116807. + /* Scan the database for this record. */
  116808. + for (record = Database->list[slot], previous = gcvNULL;
  116809. + record != gcvNULL;
  116810. + record = record->next
  116811. + )
  116812. + {
  116813. + if ((record->type == Type)
  116814. + && (record->data == Data)
  116815. + )
  116816. + {
  116817. + /* Found it! */
  116818. + break;
  116819. + }
  116820. +
  116821. + previous = record;
  116822. + }
  116823. +
  116824. + if (record == gcvNULL)
  116825. + {
  116826. + /* Ouch! This record is not found? */
  116827. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  116828. + }
  116829. +
  116830. + if (Bytes != gcvNULL)
  116831. + {
  116832. + /* Return size of record. */
  116833. + *Bytes = record->bytes;
  116834. + }
  116835. +
  116836. + /* Remove record from database. */
  116837. + if (previous == gcvNULL)
  116838. + {
  116839. + Database->list[slot] = record->next;
  116840. + }
  116841. + else
  116842. + {
  116843. + previous->next = record->next;
  116844. + }
  116845. +
  116846. + /* Insert record in free list. */
  116847. + record->next = Kernel->db->freeRecord;
  116848. + Kernel->db->freeRecord = record;
  116849. +
  116850. + /* Release the database mutex. */
  116851. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116852. +
  116853. + /* Success. */
  116854. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  116855. + return gcvSTATUS_OK;
  116856. +
  116857. +OnError:
  116858. + if (acquired)
  116859. + {
  116860. + /* Release the database mutex. */
  116861. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116862. + }
  116863. +
  116864. + /* Return the status. */
  116865. + gcmkFOOTER();
  116866. + return status;
  116867. +}
  116868. +
  116869. +/*******************************************************************************
  116870. +** gckKERNEL_FindRecord
  116871. +**
  116872. +** Find a database record from the database.
  116873. +**
  116874. +** INPUT:
  116875. +**
  116876. +** gckKERNEL Kernel
  116877. +** Pointer to a gckKERNEL object.
  116878. +**
  116879. +** gcsDATABASE_PTR Database
  116880. +** Pointer to a database structure.
  116881. +**
  116882. +** gceDATABASE_TYPE Type
  116883. +** Type of the record to remove.
  116884. +**
  116885. +** gctPOINTER Data
  116886. +** Data of the record to remove.
  116887. +**
  116888. +** OUTPUT:
  116889. +**
  116890. +** gctSIZE_T_PTR Bytes
  116891. +** Pointer to a variable that receives the size of the record deleted.
  116892. +** Can be gcvNULL if the size is not required.
  116893. +*/
  116894. +static gceSTATUS
  116895. +gckKERNEL_FindRecord(
  116896. + IN gckKERNEL Kernel,
  116897. + IN gcsDATABASE_PTR Database,
  116898. + IN gceDATABASE_TYPE Type,
  116899. + IN gctPOINTER Data,
  116900. + OUT gcsDATABASE_RECORD_PTR Record
  116901. + )
  116902. +{
  116903. + gceSTATUS status;
  116904. + gctBOOL acquired = gcvFALSE;
  116905. + gcsDATABASE_RECORD_PTR record;
  116906. + gctUINT32 slot = _GetSlot(Database, Data);
  116907. +
  116908. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
  116909. + Kernel, Database, Type, Data);
  116910. +
  116911. + /* Acquire the database mutex. */
  116912. + gcmkONERROR(
  116913. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116914. + acquired = gcvTRUE;
  116915. +
  116916. + /* Scan the database for this record. */
  116917. + for (record = Database->list[slot];
  116918. + record != gcvNULL;
  116919. + record = record->next
  116920. + )
  116921. + {
  116922. + if ((record->type == Type)
  116923. + && (record->data == Data)
  116924. + )
  116925. + {
  116926. + /* Found it! */
  116927. + break;
  116928. + }
  116929. + }
  116930. +
  116931. + if (record == gcvNULL)
  116932. + {
  116933. + /* Ouch! This record is not found? */
  116934. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  116935. + }
  116936. +
  116937. + if (Record != gcvNULL)
  116938. + {
  116939. + /* Return information of record. */
  116940. + gcmkONERROR(
  116941. + gckOS_MemCopy(Record, record, sizeof(gcsDATABASE_RECORD)));
  116942. + }
  116943. +
  116944. + /* Release the database mutex. */
  116945. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116946. +
  116947. + /* Success. */
  116948. + gcmkFOOTER_ARG("Record=0x%x", Record);
  116949. + return gcvSTATUS_OK;
  116950. +
  116951. +OnError:
  116952. + if (acquired)
  116953. + {
  116954. + /* Release the database mutex. */
  116955. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116956. + }
  116957. +
  116958. + /* Return the status. */
  116959. + gcmkFOOTER();
  116960. + return status;
  116961. +}
  116962. +
  116963. +
  116964. +/*******************************************************************************
  116965. +***** Public API **************************************************************/
  116966. +
  116967. +/*******************************************************************************
  116968. +** gckKERNEL_CreateProcessDB
  116969. +**
  116970. +** Create a new process database.
  116971. +**
  116972. +** INPUT:
  116973. +**
  116974. +** gckKERNEL Kernel
  116975. +** Pointer to a gckKERNEL object.
  116976. +**
  116977. +** gctUINT32 ProcessID
  116978. +** Process ID used to identify the database.
  116979. +**
  116980. +** OUTPUT:
  116981. +**
  116982. +** Nothing.
  116983. +*/
  116984. +gceSTATUS
  116985. +gckKERNEL_CreateProcessDB(
  116986. + IN gckKERNEL Kernel,
  116987. + IN gctUINT32 ProcessID
  116988. + )
  116989. +{
  116990. + gceSTATUS status;
  116991. + gcsDATABASE_PTR database = gcvNULL;
  116992. + gctUINT32 i;
  116993. +
  116994. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  116995. +
  116996. + /* Verify the arguments. */
  116997. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  116998. +
  116999. + /* Create a new database. */
  117000. + gcmkONERROR(gckKERNEL_NewDatabase(Kernel, ProcessID, &database));
  117001. +
  117002. + /* Initialize the database. */
  117003. + database->processID = ProcessID;
  117004. + database->vidMem.bytes = 0;
  117005. + database->vidMem.maxBytes = 0;
  117006. + database->vidMem.totalBytes = 0;
  117007. + database->nonPaged.bytes = 0;
  117008. + database->nonPaged.maxBytes = 0;
  117009. + database->nonPaged.totalBytes = 0;
  117010. + database->contiguous.bytes = 0;
  117011. + database->contiguous.maxBytes = 0;
  117012. + database->contiguous.totalBytes = 0;
  117013. + database->mapMemory.bytes = 0;
  117014. + database->mapMemory.maxBytes = 0;
  117015. + database->mapMemory.totalBytes = 0;
  117016. + database->mapUserMemory.bytes = 0;
  117017. + database->mapUserMemory.maxBytes = 0;
  117018. + database->mapUserMemory.totalBytes = 0;
  117019. + database->vidMemResv.bytes = 0;
  117020. + database->vidMemResv.maxBytes = 0;
  117021. + database->vidMemResv.totalBytes = 0;
  117022. + database->vidMemCont.bytes = 0;
  117023. + database->vidMemCont.maxBytes = 0;
  117024. + database->vidMemCont.totalBytes = 0;
  117025. + database->vidMemVirt.bytes = 0;
  117026. + database->vidMemVirt.maxBytes = 0;
  117027. + database->vidMemVirt.totalBytes = 0;
  117028. +
  117029. + for (i = 0; i < gcmCOUNTOF(database->list); i++)
  117030. + {
  117031. + database->list[i] = gcvNULL;
  117032. + }
  117033. +
  117034. +#if gcdSECURE_USER
  117035. + {
  117036. + gctINT slot;
  117037. + gcskSECURE_CACHE * cache = &database->cache;
  117038. +
  117039. + /* Setup the linked list of cache nodes. */
  117040. + for (slot = 1; slot <= gcdSECURE_CACHE_SLOTS; ++slot)
  117041. + {
  117042. + cache->cache[slot].logical = gcvNULL;
  117043. +
  117044. +#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
  117045. + cache->cache[slot].prev = &cache->cache[slot - 1];
  117046. + cache->cache[slot].next = &cache->cache[slot + 1];
  117047. +# endif
  117048. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  117049. + cache->cache[slot].nextHash = gcvNULL;
  117050. + cache->cache[slot].prevHash = gcvNULL;
  117051. +# endif
  117052. + }
  117053. +
  117054. +#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
  117055. + /* Setup the head and tail of the cache. */
  117056. + cache->cache[0].next = &cache->cache[1];
  117057. + cache->cache[0].prev = &cache->cache[gcdSECURE_CACHE_SLOTS];
  117058. + cache->cache[0].logical = gcvNULL;
  117059. +
  117060. + /* Fix up the head and tail pointers. */
  117061. + cache->cache[0].next->prev = &cache->cache[0];
  117062. + cache->cache[0].prev->next = &cache->cache[0];
  117063. +# endif
  117064. +
  117065. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  117066. + /* Zero out the hash table. */
  117067. + for (slot = 0; slot < gcmCOUNTOF(cache->hash); ++slot)
  117068. + {
  117069. + cache->hash[slot].logical = gcvNULL;
  117070. + cache->hash[slot].nextHash = gcvNULL;
  117071. + }
  117072. +# endif
  117073. +
  117074. + /* Initialize cache index. */
  117075. + cache->cacheIndex = gcvNULL;
  117076. + cache->cacheFree = 1;
  117077. + cache->cacheStamp = 0;
  117078. + }
  117079. +#endif
  117080. +
  117081. + /* Reset idle timer. */
  117082. + Kernel->db->lastIdle = 0;
  117083. +
  117084. + /* Success. */
  117085. + gcmkFOOTER_NO();
  117086. + return gcvSTATUS_OK;
  117087. +
  117088. +OnError:
  117089. + /* Return the status. */
  117090. + gcmkFOOTER();
  117091. + return status;
  117092. +}
  117093. +
  117094. +/*******************************************************************************
  117095. +** gckKERNEL_AddProcessDB
  117096. +**
  117097. +** Add a record to a process database.
  117098. +**
  117099. +** INPUT:
  117100. +**
  117101. +** gckKERNEL Kernel
  117102. +** Pointer to a gckKERNEL object.
  117103. +**
  117104. +** gctUINT32 ProcessID
  117105. +** Process ID used to identify the database.
  117106. +**
  117107. +** gceDATABASE_TYPE TYPE
  117108. +** Type of the record to add.
  117109. +**
  117110. +** gctPOINTER Pointer
  117111. +** Data of the record to add.
  117112. +**
  117113. +** gctPHYS_ADDR Physical
  117114. +** Physical address of the record to add.
  117115. +**
  117116. +** gctSIZE_T Size
  117117. +** Size of the record to add.
  117118. +**
  117119. +** OUTPUT:
  117120. +**
  117121. +** Nothing.
  117122. +*/
  117123. +gceSTATUS
  117124. +gckKERNEL_AddProcessDB(
  117125. + IN gckKERNEL Kernel,
  117126. + IN gctUINT32 ProcessID,
  117127. + IN gceDATABASE_TYPE Type,
  117128. + IN gctPOINTER Pointer,
  117129. + IN gctPHYS_ADDR Physical,
  117130. + IN gctSIZE_T Size
  117131. + )
  117132. +{
  117133. + gceSTATUS status;
  117134. + gcsDATABASE_PTR database;
  117135. + gcsDATABASE_RECORD_PTR record = gcvNULL;
  117136. + gcsDATABASE_COUNTERS * count;
  117137. +
  117138. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x "
  117139. + "Physical=0x%x Size=%lu",
  117140. + Kernel, ProcessID, Type, Pointer, Physical, Size);
  117141. +
  117142. + /* Verify the arguments. */
  117143. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117144. +
  117145. + /* Special case the idle record. */
  117146. + if (Type == gcvDB_IDLE)
  117147. + {
  117148. + gctUINT64 time;
  117149. +
  117150. + /* Get the current profile time. */
  117151. + gcmkONERROR(gckOS_GetProfileTick(&time));
  117152. +
  117153. + if ((ProcessID == 0) && (Kernel->db->lastIdle != 0))
  117154. + {
  117155. + /* Out of idle, adjust time it was idle. */
  117156. + Kernel->db->idleTime += time - Kernel->db->lastIdle;
  117157. + Kernel->db->lastIdle = 0;
  117158. + }
  117159. + else if (ProcessID == 1)
  117160. + {
  117161. + /* Save current idle time. */
  117162. + Kernel->db->lastIdle = time;
  117163. + }
  117164. +
  117165. +#if gcdDYNAMIC_SPEED
  117166. + {
  117167. + /* Test for first call. */
  117168. + if (Kernel->db->lastSlowdown == 0)
  117169. + {
  117170. + /* Save milliseconds. */
  117171. + Kernel->db->lastSlowdown = time;
  117172. + Kernel->db->lastSlowdownIdle = Kernel->db->idleTime;
  117173. + }
  117174. + else
  117175. + {
  117176. + /* Compute ellapsed time in milliseconds. */
  117177. + gctUINT delta = gckOS_ProfileToMS(time - Kernel->db->lastSlowdown);
  117178. +
  117179. + /* Test for end of period. */
  117180. + if (delta >= gcdDYNAMIC_SPEED)
  117181. + {
  117182. + /* Compute number of idle milliseconds. */
  117183. + gctUINT idle = gckOS_ProfileToMS(
  117184. + Kernel->db->idleTime - Kernel->db->lastSlowdownIdle);
  117185. +
  117186. + /* Broadcast to slow down the GPU. */
  117187. + gcmkONERROR(gckOS_BroadcastCalibrateSpeed(Kernel->os,
  117188. + Kernel->hardware,
  117189. + idle,
  117190. + delta));
  117191. +
  117192. + /* Save current time. */
  117193. + Kernel->db->lastSlowdown = time;
  117194. + Kernel->db->lastSlowdownIdle = Kernel->db->idleTime;
  117195. + }
  117196. + }
  117197. + }
  117198. +#endif
  117199. +
  117200. + /* Success. */
  117201. + gcmkFOOTER_NO();
  117202. + return gcvSTATUS_OK;
  117203. + }
  117204. +
  117205. + /* Verify the arguments. */
  117206. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  117207. +
  117208. + /* Find the database. */
  117209. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  117210. +
  117211. + /* Create a new record in the database. */
  117212. + gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, _GetSlot(database, Pointer), &record));
  117213. +
  117214. + /* Initialize the record. */
  117215. + record->kernel = Kernel;
  117216. + record->type = Type;
  117217. + record->data = Pointer;
  117218. + record->physical = Physical;
  117219. + record->bytes = Size;
  117220. +
  117221. + /* Get pointer to counters. */
  117222. + switch (Type)
  117223. + {
  117224. + case gcvDB_VIDEO_MEMORY:
  117225. + count = &database->vidMem;
  117226. + break;
  117227. +
  117228. + case gcvDB_NON_PAGED:
  117229. + count = &database->nonPaged;
  117230. + break;
  117231. +
  117232. + case gcvDB_CONTIGUOUS:
  117233. + count = &database->contiguous;
  117234. + break;
  117235. +
  117236. + case gcvDB_MAP_MEMORY:
  117237. + count = &database->mapMemory;
  117238. + break;
  117239. +
  117240. + case gcvDB_MAP_USER_MEMORY:
  117241. + count = &database->mapUserMemory;
  117242. + break;
  117243. +
  117244. + case gcvDB_VIDEO_MEMORY_RESERVED:
  117245. + count = &database->vidMemResv;
  117246. + break;
  117247. +
  117248. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  117249. + count = &database->vidMemCont;
  117250. + break;
  117251. +
  117252. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  117253. + count = &database->vidMemVirt;
  117254. + break;
  117255. +
  117256. + default:
  117257. + count = gcvNULL;
  117258. + break;
  117259. + }
  117260. +
  117261. + if (count != gcvNULL)
  117262. + {
  117263. + /* Adjust counters. */
  117264. + count->totalBytes += Size;
  117265. + count->bytes += Size;
  117266. +
  117267. + if (count->bytes > count->maxBytes)
  117268. + {
  117269. + count->maxBytes = count->bytes;
  117270. + }
  117271. + }
  117272. +
  117273. + /* Success. */
  117274. + gcmkFOOTER_NO();
  117275. + return gcvSTATUS_OK;
  117276. +
  117277. +OnError:
  117278. + /* Return the status. */
  117279. + gcmkFOOTER();
  117280. + return status;
  117281. +}
  117282. +
  117283. +/*******************************************************************************
  117284. +** gckKERNEL_RemoveProcessDB
  117285. +**
  117286. +** Remove a record from a process database.
  117287. +**
  117288. +** INPUT:
  117289. +**
  117290. +** gckKERNEL Kernel
  117291. +** Pointer to a gckKERNEL object.
  117292. +**
  117293. +** gctUINT32 ProcessID
  117294. +** Process ID used to identify the database.
  117295. +**
  117296. +** gceDATABASE_TYPE TYPE
  117297. +** Type of the record to remove.
  117298. +**
  117299. +** gctPOINTER Pointer
  117300. +** Data of the record to remove.
  117301. +**
  117302. +** OUTPUT:
  117303. +**
  117304. +** Nothing.
  117305. +*/
  117306. +gceSTATUS
  117307. +gckKERNEL_RemoveProcessDB(
  117308. + IN gckKERNEL Kernel,
  117309. + IN gctUINT32 ProcessID,
  117310. + IN gceDATABASE_TYPE Type,
  117311. + IN gctPOINTER Pointer
  117312. + )
  117313. +{
  117314. + gceSTATUS status;
  117315. + gcsDATABASE_PTR database;
  117316. + gctSIZE_T bytes = 0;
  117317. +
  117318. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
  117319. + Kernel, ProcessID, Type, Pointer);
  117320. +
  117321. + /* Verify the arguments. */
  117322. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117323. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  117324. +
  117325. + /* Find the database. */
  117326. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  117327. +
  117328. + /* Delete the record. */
  117329. + gcmkONERROR(
  117330. + gckKERNEL_DeleteRecord(Kernel, database, Type, Pointer, &bytes));
  117331. +
  117332. + /* Update counters. */
  117333. + switch (Type)
  117334. + {
  117335. + case gcvDB_VIDEO_MEMORY:
  117336. + database->vidMem.bytes -= bytes;
  117337. + break;
  117338. +
  117339. + case gcvDB_NON_PAGED:
  117340. + database->nonPaged.bytes -= bytes;
  117341. + break;
  117342. +
  117343. + case gcvDB_CONTIGUOUS:
  117344. + database->contiguous.bytes -= bytes;
  117345. + break;
  117346. +
  117347. + case gcvDB_MAP_MEMORY:
  117348. + database->mapMemory.bytes -= bytes;
  117349. + break;
  117350. +
  117351. + case gcvDB_MAP_USER_MEMORY:
  117352. + database->mapUserMemory.bytes -= bytes;
  117353. + break;
  117354. +
  117355. + case gcvDB_VIDEO_MEMORY_RESERVED:
  117356. + database->vidMemResv.bytes -= bytes;
  117357. + break;
  117358. +
  117359. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  117360. + database->vidMemCont.bytes -= bytes;
  117361. + break;
  117362. +
  117363. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  117364. + database->vidMemVirt.bytes -= bytes;
  117365. + break;
  117366. +
  117367. + default:
  117368. + break;
  117369. + }
  117370. +
  117371. + /* Success. */
  117372. + gcmkFOOTER_NO();
  117373. + return gcvSTATUS_OK;
  117374. +
  117375. +OnError:
  117376. + /* Return the status. */
  117377. + gcmkFOOTER();
  117378. + return status;
  117379. +}
  117380. +
  117381. +/*******************************************************************************
  117382. +** gckKERNEL_FindProcessDB
  117383. +**
  117384. +** Find a record from a process database.
  117385. +**
  117386. +** INPUT:
  117387. +**
  117388. +** gckKERNEL Kernel
  117389. +** Pointer to a gckKERNEL object.
  117390. +**
  117391. +** gctUINT32 ProcessID
  117392. +** Process ID used to identify the database.
  117393. +**
  117394. +** gceDATABASE_TYPE TYPE
  117395. +** Type of the record to remove.
  117396. +**
  117397. +** gctPOINTER Pointer
  117398. +** Data of the record to remove.
  117399. +**
  117400. +** OUTPUT:
  117401. +**
  117402. +** gcsDATABASE_RECORD_PTR Record
  117403. +** Copy of record.
  117404. +*/
  117405. +gceSTATUS
  117406. +gckKERNEL_FindProcessDB(
  117407. + IN gckKERNEL Kernel,
  117408. + IN gctUINT32 ProcessID,
  117409. + IN gctUINT32 ThreadID,
  117410. + IN gceDATABASE_TYPE Type,
  117411. + IN gctPOINTER Pointer,
  117412. + OUT gcsDATABASE_RECORD_PTR Record
  117413. + )
  117414. +{
  117415. + gceSTATUS status;
  117416. + gcsDATABASE_PTR database;
  117417. +
  117418. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
  117419. + Kernel, ProcessID, ThreadID, Type, Pointer);
  117420. +
  117421. + /* Verify the arguments. */
  117422. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117423. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  117424. +
  117425. + /* Find the database. */
  117426. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  117427. +
  117428. + /* Find the record. */
  117429. + gcmkONERROR(
  117430. + gckKERNEL_FindRecord(Kernel, database, Type, Pointer, Record));
  117431. +
  117432. + /* Success. */
  117433. + gcmkFOOTER_NO();
  117434. + return gcvSTATUS_OK;
  117435. +
  117436. +OnError:
  117437. + /* Return the status. */
  117438. + gcmkFOOTER();
  117439. + return status;
  117440. +}
  117441. +
  117442. +/*******************************************************************************
  117443. +** gckKERNEL_DestroyProcessDB
  117444. +**
  117445. +** Destroy a process database. If the database contains any records, the data
  117446. +** inside those records will be deleted as well. This aids in the cleanup if
  117447. +** a process has died unexpectedly or has memory leaks.
  117448. +**
  117449. +** INPUT:
  117450. +**
  117451. +** gckKERNEL Kernel
  117452. +** Pointer to a gckKERNEL object.
  117453. +**
  117454. +** gctUINT32 ProcessID
  117455. +** Process ID used to identify the database.
  117456. +**
  117457. +** OUTPUT:
  117458. +**
  117459. +** Nothing.
  117460. +*/
  117461. +gceSTATUS
  117462. +gckKERNEL_DestroyProcessDB(
  117463. + IN gckKERNEL Kernel,
  117464. + IN gctUINT32 ProcessID
  117465. + )
  117466. +{
  117467. + gceSTATUS status;
  117468. + gcsDATABASE_PTR database;
  117469. + gcsDATABASE_RECORD_PTR record, next;
  117470. + gctBOOL asynchronous;
  117471. + gctPHYS_ADDR physical;
  117472. + gcuVIDMEM_NODE_PTR node;
  117473. + gckKERNEL kernel = Kernel;
  117474. + gctUINT32 i;
  117475. +
  117476. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  117477. +
  117478. + /* Verify the arguments. */
  117479. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117480. +
  117481. + /* Find the database. */
  117482. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  117483. +
  117484. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117485. + "DB(%d): VidMem: total=%lu max=%lu",
  117486. + ProcessID, database->vidMem.totalBytes,
  117487. + database->vidMem.maxBytes);
  117488. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117489. + "DB(%d): NonPaged: total=%lu max=%lu",
  117490. + ProcessID, database->nonPaged.totalBytes,
  117491. + database->nonPaged.maxBytes);
  117492. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117493. + "DB(%d): Contiguous: total=%lu max=%lu",
  117494. + ProcessID, database->contiguous.totalBytes,
  117495. + database->contiguous.maxBytes);
  117496. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117497. + "DB(%d): Idle time=%llu",
  117498. + ProcessID, Kernel->db->idleTime);
  117499. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117500. + "DB(%d): Map: total=%lu max=%lu",
  117501. + ProcessID, database->mapMemory.totalBytes,
  117502. + database->mapMemory.maxBytes);
  117503. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117504. + "DB(%d): Map: total=%lu max=%lu",
  117505. + ProcessID, database->mapUserMemory.totalBytes,
  117506. + database->mapUserMemory.maxBytes);
  117507. +
  117508. + if (database->list != gcvNULL)
  117509. + {
  117510. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117511. + "Process %d has entries in its database:",
  117512. + ProcessID);
  117513. + }
  117514. +
  117515. + for(i = 0; i < gcmCOUNTOF(database->list); i++)
  117516. + {
  117517. +
  117518. + /* Walk all records. */
  117519. + for (record = database->list[i]; record != gcvNULL; record = next)
  117520. + {
  117521. + /* Next next record. */
  117522. + next = record->next;
  117523. +
  117524. + /* Dispatch on record type. */
  117525. + switch (record->type)
  117526. + {
  117527. + case gcvDB_VIDEO_MEMORY:
  117528. + /* Free the video memory. */
  117529. + status = gckVIDMEM_Free(gcmUINT64_TO_PTR(record->data));
  117530. +
  117531. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117532. + "DB: VIDEO_MEMORY 0x%x (status=%d)",
  117533. + record->data, status);
  117534. + break;
  117535. +
  117536. + case gcvDB_NON_PAGED:
  117537. + physical = gcmNAME_TO_PTR(record->physical);
  117538. + /* Unmap user logical memory first. */
  117539. + status = gckOS_UnmapUserLogical(Kernel->os,
  117540. + physical,
  117541. + record->bytes,
  117542. + record->data);
  117543. +
  117544. + /* Free the non paged memory. */
  117545. + status = gckOS_FreeNonPagedMemory(Kernel->os,
  117546. + record->bytes,
  117547. + physical,
  117548. + record->data);
  117549. + gcmRELEASE_NAME(record->physical);
  117550. +
  117551. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117552. + "DB: NON_PAGED 0x%x, bytes=%lu (status=%d)",
  117553. + record->data, record->bytes, status);
  117554. + break;
  117555. +
  117556. +#if gcdVIRTUAL_COMMAND_BUFFER
  117557. + case gcvDB_COMMAND_BUFFER:
  117558. + /* Free the command buffer. */
  117559. + status = gckEVENT_DestroyVirtualCommandBuffer(record->kernel->eventObj,
  117560. + record->bytes,
  117561. + gcmNAME_TO_PTR(record->physical),
  117562. + record->data,
  117563. + gcvKERNEL_PIXEL);
  117564. + gcmRELEASE_NAME(record->physical);
  117565. +
  117566. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117567. + "DB: COMMAND_BUFFER 0x%x, bytes=%lu (status=%d)",
  117568. + record->data, record->bytes, status);
  117569. + break;
  117570. +#endif
  117571. +
  117572. + case gcvDB_CONTIGUOUS:
  117573. + physical = gcmNAME_TO_PTR(record->physical);
  117574. + /* Unmap user logical memory first. */
  117575. + status = gckOS_UnmapUserLogical(Kernel->os,
  117576. + physical,
  117577. + record->bytes,
  117578. + record->data);
  117579. +
  117580. + /* Free the contiguous memory. */
  117581. + status = gckEVENT_FreeContiguousMemory(Kernel->eventObj,
  117582. + record->bytes,
  117583. + physical,
  117584. + record->data,
  117585. + gcvKERNEL_PIXEL);
  117586. + gcmRELEASE_NAME(record->physical);
  117587. +
  117588. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117589. + "DB: CONTIGUOUS 0x%x bytes=%lu (status=%d)",
  117590. + record->data, record->bytes, status);
  117591. + break;
  117592. +
  117593. + case gcvDB_SIGNAL:
  117594. +#if USE_NEW_LINUX_SIGNAL
  117595. + status = gcvSTATUS_NOT_SUPPORTED;
  117596. +#else
  117597. + /* Free the user signal. */
  117598. + status = gckOS_DestroyUserSignal(Kernel->os,
  117599. + gcmPTR2INT(record->data));
  117600. +#endif /* USE_NEW_LINUX_SIGNAL */
  117601. +
  117602. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117603. + "DB: SIGNAL %d (status=%d)",
  117604. + (gctINT)(gctUINTPTR_T)record->data, status);
  117605. + break;
  117606. +
  117607. + case gcvDB_VIDEO_MEMORY_LOCKED:
  117608. + node = gcmUINT64_TO_PTR(record->data);
  117609. + /* Unlock what we still locked */
  117610. + status = gckVIDMEM_Unlock(record->kernel,
  117611. + node,
  117612. + gcvSURF_TYPE_UNKNOWN,
  117613. + &asynchronous);
  117614. +
  117615. + if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous))
  117616. + {
  117617. + /* TODO: we maybe need to schedule a event here */
  117618. + status = gckVIDMEM_Unlock(record->kernel,
  117619. + node,
  117620. + gcvSURF_TYPE_UNKNOWN,
  117621. + gcvNULL);
  117622. + }
  117623. +
  117624. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117625. + "DB: VIDEO_MEMORY_LOCKED 0x%x (status=%d)",
  117626. + node, status);
  117627. + break;
  117628. +
  117629. + case gcvDB_CONTEXT:
  117630. + /* TODO: Free the context */
  117631. + status = gckCOMMAND_Detach(Kernel->command, gcmNAME_TO_PTR(record->data));
  117632. + gcmRELEASE_NAME(record->data);
  117633. +
  117634. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117635. + "DB: CONTEXT 0x%x (status=%d)",
  117636. + record->data, status);
  117637. + break;
  117638. +
  117639. + case gcvDB_MAP_MEMORY:
  117640. + /* Unmap memory. */
  117641. + status = gckKERNEL_UnmapMemory(Kernel,
  117642. + record->physical,
  117643. + record->bytes,
  117644. + record->data);
  117645. +
  117646. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117647. + "DB: MAP MEMORY %d (status=%d)",
  117648. + gcmPTR2INT(record->data), status);
  117649. + break;
  117650. +
  117651. + case gcvDB_MAP_USER_MEMORY:
  117652. + /* TODO: Unmap user memory. */
  117653. + status = gckOS_UnmapUserMemory(Kernel->os,
  117654. + Kernel->core,
  117655. + record->physical,
  117656. + record->bytes,
  117657. + gcmNAME_TO_PTR(record->data),
  117658. + 0);
  117659. + gcmRELEASE_NAME(record->data);
  117660. +
  117661. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117662. + "DB: MAP USER MEMORY %d (status=%d)",
  117663. + gcmPTR2INT(record->data), status);
  117664. + break;
  117665. +
  117666. + case gcvDB_SHARED_INFO:
  117667. + status = gckOS_FreeMemory(Kernel->os, record->physical);
  117668. + break;
  117669. +
  117670. +#if gcdANDROID_NATIVE_FENCE_SYNC
  117671. + case gcvDB_SYNC_POINT:
  117672. + /* Free the user signal. */
  117673. + status = gckOS_DestroySyncPoint(Kernel->os,
  117674. + (gctSYNC_POINT) record->data);
  117675. +
  117676. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117677. + "DB: SYNC POINT %d (status=%d)",
  117678. + (gctINT)(gctUINTPTR_T)record->data, status);
  117679. + break;
  117680. +#endif
  117681. +
  117682. + case gcvDB_VIDEO_MEMORY_RESERVED:
  117683. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  117684. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  117685. + break;//Nothing to do
  117686. +
  117687. + default:
  117688. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DATABASE,
  117689. + "DB: Correcupted record=0x%08x type=%d",
  117690. + record, record->type);
  117691. + break;
  117692. + }
  117693. +
  117694. + /* Delete the record. */
  117695. + gcmkONERROR(gckKERNEL_DeleteRecord(Kernel,
  117696. + database,
  117697. + record->type,
  117698. + record->data,
  117699. + gcvNULL));
  117700. + }
  117701. +
  117702. + }
  117703. +
  117704. + /* Delete the database. */
  117705. + gcmkONERROR(gckKERNEL_DeleteDatabase(Kernel, database));
  117706. +
  117707. + /* Success. */
  117708. + gcmkFOOTER_NO();
  117709. + return gcvSTATUS_OK;
  117710. +
  117711. +OnError:
  117712. + /* Return the status. */
  117713. + gcmkFOOTER();
  117714. + return status;
  117715. +}
  117716. +
  117717. +/*******************************************************************************
  117718. +** gckKERNEL_QueryProcessDB
  117719. +**
  117720. +** Query a process database for the current usage of a particular record type.
  117721. +**
  117722. +** INPUT:
  117723. +**
  117724. +** gckKERNEL Kernel
  117725. +** Pointer to a gckKERNEL object.
  117726. +**
  117727. +** gctUINT32 ProcessID
  117728. +** Process ID used to identify the database.
  117729. +**
  117730. +** gctBOOL LastProcessID
  117731. +** gcvTRUE if searching for the last known process ID. gcvFALSE if
  117732. +** we need to search for the process ID specified by the ProcessID
  117733. +** argument.
  117734. +**
  117735. +** gceDATABASE_TYPE Type
  117736. +** Type of the record to query.
  117737. +**
  117738. +** OUTPUT:
  117739. +**
  117740. +** gcuDATABASE_INFO * Info
  117741. +** Pointer to a variable that receives the requested information.
  117742. +*/
  117743. +gceSTATUS
  117744. +gckKERNEL_QueryProcessDB(
  117745. + IN gckKERNEL Kernel,
  117746. + IN gctUINT32 ProcessID,
  117747. + IN gctBOOL LastProcessID,
  117748. + IN gceDATABASE_TYPE Type,
  117749. + OUT gcuDATABASE_INFO * Info
  117750. + )
  117751. +{
  117752. + gceSTATUS status;
  117753. + gcsDATABASE_PTR database;
  117754. +
  117755. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Info=0x%x",
  117756. + Kernel, ProcessID, Type, Info);
  117757. +
  117758. + /* Verify the arguments. */
  117759. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117760. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  117761. +
  117762. + /* Find the database. */
  117763. + gcmkONERROR(
  117764. + gckKERNEL_FindDatabase(Kernel, ProcessID, LastProcessID, &database));
  117765. +
  117766. + /* Get pointer to counters. */
  117767. + switch (Type)
  117768. + {
  117769. + case gcvDB_VIDEO_MEMORY:
  117770. + gckOS_MemCopy(&Info->counters,
  117771. + &database->vidMem,
  117772. + gcmSIZEOF(database->vidMem));
  117773. + break;
  117774. +
  117775. + case gcvDB_NON_PAGED:
  117776. + gckOS_MemCopy(&Info->counters,
  117777. + &database->nonPaged,
  117778. + gcmSIZEOF(database->vidMem));
  117779. + break;
  117780. +
  117781. + case gcvDB_CONTIGUOUS:
  117782. + gckOS_MemCopy(&Info->counters,
  117783. + &database->contiguous,
  117784. + gcmSIZEOF(database->vidMem));
  117785. + break;
  117786. +
  117787. + case gcvDB_IDLE:
  117788. + Info->time = Kernel->db->idleTime;
  117789. + Kernel->db->idleTime = 0;
  117790. + break;
  117791. +
  117792. + case gcvDB_MAP_MEMORY:
  117793. + gckOS_MemCopy(&Info->counters,
  117794. + &database->mapMemory,
  117795. + gcmSIZEOF(database->mapMemory));
  117796. + break;
  117797. +
  117798. + case gcvDB_MAP_USER_MEMORY:
  117799. + gckOS_MemCopy(&Info->counters,
  117800. + &database->mapUserMemory,
  117801. + gcmSIZEOF(database->mapUserMemory));
  117802. + break;
  117803. +
  117804. + case gcvDB_VIDEO_MEMORY_RESERVED:
  117805. + gckOS_MemCopy(&Info->counters,
  117806. + &database->vidMemResv,
  117807. + gcmSIZEOF(database->vidMemResv));
  117808. + break;
  117809. +
  117810. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  117811. + gckOS_MemCopy(&Info->counters,
  117812. + &database->vidMemCont,
  117813. + gcmSIZEOF(database->vidMemCont));
  117814. + break;
  117815. +
  117816. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  117817. + gckOS_MemCopy(&Info->counters,
  117818. + &database->vidMemVirt,
  117819. + gcmSIZEOF(database->vidMemVirt));
  117820. + break;
  117821. +
  117822. + default:
  117823. + break;
  117824. + }
  117825. +
  117826. + /* Success. */
  117827. + gcmkFOOTER_NO();
  117828. + return gcvSTATUS_OK;
  117829. +
  117830. +OnError:
  117831. + /* Return the status. */
  117832. + gcmkFOOTER();
  117833. + return status;
  117834. +}
  117835. +
  117836. +#if gcdSECURE_USER
  117837. +/*******************************************************************************
  117838. +** gckKERNEL_GetProcessDBCache
  117839. +**
  117840. +** Get teh secure cache from a process database.
  117841. +**
  117842. +** INPUT:
  117843. +**
  117844. +** gckKERNEL Kernel
  117845. +** Pointer to a gckKERNEL object.
  117846. +**
  117847. +** gctUINT32 ProcessID
  117848. +** Process ID used to identify the database.
  117849. +**
  117850. +** OUTPUT:
  117851. +**
  117852. +** gcskSECURE_CACHE_PTR * Cache
  117853. +** Pointer to a variable that receives the secure cache pointer.
  117854. +*/
  117855. +gceSTATUS
  117856. +gckKERNEL_GetProcessDBCache(
  117857. + IN gckKERNEL Kernel,
  117858. + IN gctUINT32 ProcessID,
  117859. + OUT gcskSECURE_CACHE_PTR * Cache
  117860. + )
  117861. +{
  117862. + gceSTATUS status;
  117863. + gcsDATABASE_PTR database;
  117864. +
  117865. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  117866. +
  117867. + /* Verify the arguments. */
  117868. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117869. + gcmkVERIFY_ARGUMENT(Cache != gcvNULL);
  117870. +
  117871. + /* Find the database. */
  117872. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  117873. +
  117874. + /* Return the pointer to the cache. */
  117875. + *Cache = &database->cache;
  117876. +
  117877. + /* Success. */
  117878. + gcmkFOOTER_ARG("*Cache=0x%x", *Cache);
  117879. + return gcvSTATUS_OK;
  117880. +
  117881. +OnError:
  117882. + /* Return the status. */
  117883. + gcmkFOOTER();
  117884. + return status;
  117885. +}
  117886. +#endif
  117887. +
  117888. +gceSTATUS
  117889. +gckKERNEL_DumpProcessDB(
  117890. + IN gckKERNEL Kernel
  117891. + )
  117892. +{
  117893. + gcsDATABASE_PTR database;
  117894. + gctINT i, pid;
  117895. + gctUINT8 name[24];
  117896. +
  117897. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  117898. +
  117899. + /* Acquire the database mutex. */
  117900. + gcmkVERIFY_OK(
  117901. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  117902. +
  117903. + gcmkPRINT("**************************\n");
  117904. + gcmkPRINT("*** PROCESS DB DUMP ***\n");
  117905. + gcmkPRINT("**************************\n");
  117906. +
  117907. + gcmkPRINT_N(8, "%-8s%s\n", "PID", "NAME");
  117908. + /* Walk the databases. */
  117909. + for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
  117910. + {
  117911. + for (database = Kernel->db->db[i];
  117912. + database != gcvNULL;
  117913. + database = database->next)
  117914. + {
  117915. + pid = database->processID;
  117916. +
  117917. + gcmkVERIFY_OK(gckOS_ZeroMemory(name, gcmSIZEOF(name)));
  117918. +
  117919. + gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));
  117920. +
  117921. + gcmkPRINT_N(8, "%-8d%s\n", pid, name);
  117922. + }
  117923. + }
  117924. +
  117925. + /* Release the database mutex. */
  117926. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  117927. +
  117928. + /* Success. */
  117929. + gcmkFOOTER_NO();
  117930. + return gcvSTATUS_OK;
  117931. +}
  117932. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c
  117933. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c 1970-01-01 01:00:00.000000000 +0100
  117934. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c 2014-08-20 19:31:46.128869007 +0200
  117935. @@ -0,0 +1,2559 @@
  117936. +/****************************************************************************
  117937. +*
  117938. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  117939. +*
  117940. +* This program is free software; you can redistribute it and/or modify
  117941. +* it under the terms of the GNU General Public License as published by
  117942. +* the Free Software Foundation; either version 2 of the license, or
  117943. +* (at your option) any later version.
  117944. +*
  117945. +* This program is distributed in the hope that it will be useful,
  117946. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  117947. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  117948. +* GNU General Public License for more details.
  117949. +*
  117950. +* You should have received a copy of the GNU General Public License
  117951. +* along with this program; if not write to the Free Software
  117952. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  117953. +*
  117954. +*****************************************************************************/
  117955. +
  117956. +
  117957. +#include "gc_hal_kernel_precomp.h"
  117958. +#include <gc_hal_kernel_debug.h>
  117959. +
  117960. +/******************************************************************************\
  117961. +******************************** Debug Variables *******************************
  117962. +\******************************************************************************/
  117963. +
  117964. +static gceSTATUS _lastError = gcvSTATUS_OK;
  117965. +static gctUINT32 _debugLevel = gcvLEVEL_ERROR;
  117966. +/*
  117967. +_debugZones config value
  117968. +Please Reference define in gc_hal_base.h
  117969. +*/
  117970. +static gctUINT32 _debugZones = gcvZONE_NONE;
  117971. +
  117972. +/******************************************************************************\
  117973. +********************************* Debug Switches *******************************
  117974. +\******************************************************************************/
  117975. +
  117976. +/*
  117977. + gcdBUFFERED_OUTPUT
  117978. +
  117979. + When set to non-zero, all output is collected into a buffer with the
  117980. + specified size. Once the buffer gets full, the debug buffer will be
  117981. + printed to the console. gcdBUFFERED_SIZE determines the size of the buffer.
  117982. +*/
  117983. +#define gcdBUFFERED_OUTPUT 0
  117984. +
  117985. +/*
  117986. + gcdBUFFERED_SIZE
  117987. +
  117988. + When set to non-zero, all output is collected into a buffer with the
  117989. + specified size. Once the buffer gets full, the debug buffer will be
  117990. + printed to the console.
  117991. +*/
  117992. +#define gcdBUFFERED_SIZE (1024 * 1024 * 2)
  117993. +
  117994. +/*
  117995. + gcdDMA_BUFFER_COUNT
  117996. +
  117997. + If greater then zero, the debugger will attempt to find the command buffer
  117998. + where DMA is currently executing and then print this buffer and
  117999. + (gcdDMA_BUFFER_COUNT - 1) buffers before the current one. If set to zero
  118000. + or the current buffer is not found, all buffers are printed.
  118001. +*/
  118002. +#define gcdDMA_BUFFER_COUNT 0
  118003. +
  118004. +/*
  118005. + gcdTHREAD_BUFFERS
  118006. +
  118007. + When greater then one, will accumulate messages from the specified number
  118008. + of threads in separate output buffers.
  118009. +*/
  118010. +#define gcdTHREAD_BUFFERS 1
  118011. +
  118012. +/*
  118013. + gcdENABLE_OVERFLOW
  118014. +
  118015. + When set to non-zero, and the output buffer gets full, instead of being
  118016. + printed, it will be allowed to overflow removing the oldest messages.
  118017. +*/
  118018. +#define gcdENABLE_OVERFLOW 1
  118019. +
  118020. +/*
  118021. + gcdSHOW_LINE_NUMBER
  118022. +
  118023. + When enabledm each print statement will be preceeded with the current
  118024. + line number.
  118025. +*/
  118026. +#define gcdSHOW_LINE_NUMBER 0
  118027. +
  118028. +/*
  118029. + gcdSHOW_PROCESS_ID
  118030. +
  118031. + When enabledm each print statement will be preceeded with the current
  118032. + process ID.
  118033. +*/
  118034. +#define gcdSHOW_PROCESS_ID 0
  118035. +
  118036. +/*
  118037. + gcdSHOW_THREAD_ID
  118038. +
  118039. + When enabledm each print statement will be preceeded with the current
  118040. + thread ID.
  118041. +*/
  118042. +#define gcdSHOW_THREAD_ID 0
  118043. +
  118044. +/*
  118045. + gcdSHOW_TIME
  118046. +
  118047. + When enabled each print statement will be preceeded with the current
  118048. + high-resolution time.
  118049. +*/
  118050. +#define gcdSHOW_TIME 0
  118051. +
  118052. +
  118053. +/******************************************************************************\
  118054. +****************************** Miscellaneous Macros ****************************
  118055. +\******************************************************************************/
  118056. +
  118057. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  118058. +# define gcmDBGASSERT(Expression, Format, Value) \
  118059. + if (!(Expression)) \
  118060. + { \
  118061. + _DirectPrint( \
  118062. + "*** gcmDBGASSERT ***************************\n" \
  118063. + " function : %s\n" \
  118064. + " line : %d\n" \
  118065. + " expression : " #Expression "\n" \
  118066. + " actual value : " Format "\n", \
  118067. + __FUNCTION__, __LINE__, Value \
  118068. + ); \
  118069. + }
  118070. +#else
  118071. +# define gcmDBGASSERT(Expression, Format, Value)
  118072. +#endif
  118073. +
  118074. +#define gcmPTRALIGNMENT(Pointer, Alignemnt) \
  118075. +( \
  118076. + gcmALIGN(gcmPTR2INT(Pointer), Alignemnt) - gcmPTR2INT(Pointer) \
  118077. +)
  118078. +
  118079. +#if gcdALIGNBYSIZE
  118080. +# define gcmISALIGNED(Offset, Alignment) \
  118081. + (((Offset) & ((Alignment) - 1)) == 0)
  118082. +
  118083. +# define gcmkALIGNPTR(Type, Pointer, Alignment) \
  118084. + Pointer = (Type) gcmINT2PTR(gcmALIGN(gcmPTR2INT(Pointer), Alignment))
  118085. +#else
  118086. +# define gcmISALIGNED(Offset, Alignment) \
  118087. + gcvTRUE
  118088. +
  118089. +# define gcmkALIGNPTR(Type, Pointer, Alignment)
  118090. +#endif
  118091. +
  118092. +#define gcmALIGNSIZE(Offset, Size) \
  118093. + ((Size - Offset) + Size)
  118094. +
  118095. +#define gcdHAVEPREFIX \
  118096. +( \
  118097. + gcdSHOW_TIME \
  118098. + || gcdSHOW_LINE_NUMBER \
  118099. + || gcdSHOW_PROCESS_ID \
  118100. + || gcdSHOW_THREAD_ID \
  118101. +)
  118102. +
  118103. +#if gcdHAVEPREFIX
  118104. +
  118105. +# define gcdOFFSET 0
  118106. +
  118107. +#if gcdSHOW_TIME
  118108. +#if gcmISALIGNED(gcdOFFSET, 8)
  118109. +# define gcdTIMESIZE gcmSIZEOF(gctUINT64)
  118110. +# elif gcdOFFSET == 4
  118111. +# define gcdTIMESIZE gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
  118112. +# else
  118113. +# error "Unexpected offset value."
  118114. +# endif
  118115. +# undef gcdOFFSET
  118116. +# define gcdOFFSET 8
  118117. +#if !defined(gcdPREFIX_LEADER)
  118118. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT64)
  118119. +# define gcdTIMEFORMAT "0x%016llX"
  118120. +# else
  118121. +# define gcdTIMEFORMAT ", 0x%016llX"
  118122. +# endif
  118123. +# else
  118124. +# define gcdTIMESIZE 0
  118125. +# define gcdTIMEFORMAT
  118126. +# endif
  118127. +
  118128. +#if gcdSHOW_LINE_NUMBER
  118129. +#if gcmISALIGNED(gcdOFFSET, 8)
  118130. +# define gcdNUMSIZE gcmSIZEOF(gctUINT64)
  118131. +# elif gcdOFFSET == 4
  118132. +# define gcdNUMSIZE gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
  118133. +# else
  118134. +# error "Unexpected offset value."
  118135. +# endif
  118136. +# undef gcdOFFSET
  118137. +# define gcdOFFSET 8
  118138. +#if !defined(gcdPREFIX_LEADER)
  118139. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT64)
  118140. +# define gcdNUMFORMAT "%8llu"
  118141. +# else
  118142. +# define gcdNUMFORMAT ", %8llu"
  118143. +# endif
  118144. +# else
  118145. +# define gcdNUMSIZE 0
  118146. +# define gcdNUMFORMAT
  118147. +# endif
  118148. +
  118149. +#if gcdSHOW_PROCESS_ID
  118150. +#if gcmISALIGNED(gcdOFFSET, 4)
  118151. +# define gcdPIDSIZE gcmSIZEOF(gctUINT32)
  118152. +# else
  118153. +# error "Unexpected offset value."
  118154. +# endif
  118155. +# undef gcdOFFSET
  118156. +# define gcdOFFSET 4
  118157. +#if !defined(gcdPREFIX_LEADER)
  118158. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
  118159. +# define gcdPIDFORMAT "pid=%5d"
  118160. +# else
  118161. +# define gcdPIDFORMAT ", pid=%5d"
  118162. +# endif
  118163. +# else
  118164. +# define gcdPIDSIZE 0
  118165. +# define gcdPIDFORMAT
  118166. +# endif
  118167. +
  118168. +#if gcdSHOW_THREAD_ID
  118169. +#if gcmISALIGNED(gcdOFFSET, 4)
  118170. +# define gcdTIDSIZE gcmSIZEOF(gctUINT32)
  118171. +# else
  118172. +# error "Unexpected offset value."
  118173. +# endif
  118174. +# undef gcdOFFSET
  118175. +# define gcdOFFSET 4
  118176. +#if !defined(gcdPREFIX_LEADER)
  118177. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
  118178. +# define gcdTIDFORMAT "tid=%5d"
  118179. +# else
  118180. +# define gcdTIDFORMAT ", tid=%5d"
  118181. +# endif
  118182. +# else
  118183. +# define gcdTIDSIZE 0
  118184. +# define gcdTIDFORMAT
  118185. +# endif
  118186. +
  118187. +# define gcdPREFIX_SIZE \
  118188. + ( \
  118189. + gcdTIMESIZE \
  118190. + + gcdNUMSIZE \
  118191. + + gcdPIDSIZE \
  118192. + + gcdTIDSIZE \
  118193. + )
  118194. +
  118195. + static const char * _prefixFormat =
  118196. + "["
  118197. + gcdTIMEFORMAT
  118198. + gcdNUMFORMAT
  118199. + gcdPIDFORMAT
  118200. + gcdTIDFORMAT
  118201. + "] ";
  118202. +
  118203. +#else
  118204. +
  118205. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
  118206. +# define gcdPREFIX_SIZE 0
  118207. +
  118208. +#endif
  118209. +
  118210. +/* Assumed largest variable argument leader size. */
  118211. +#define gcdVARARG_LEADER gcmSIZEOF(gctUINT64)
  118212. +
  118213. +/* Alignnments. */
  118214. +#if gcdALIGNBYSIZE
  118215. +# define gcdPREFIX_ALIGNMENT gcdPREFIX_LEADER
  118216. +# define gcdVARARG_ALIGNMENT gcdVARARG_LEADER
  118217. +#else
  118218. +# define gcdPREFIX_ALIGNMENT 0
  118219. +# define gcdVARARG_ALIGNMENT 0
  118220. +#endif
  118221. +
  118222. +#if gcdBUFFERED_OUTPUT
  118223. +# define gcdOUTPUTPREFIX _AppendPrefix
  118224. +# define gcdOUTPUTSTRING _AppendString
  118225. +# define gcdOUTPUTCOPY _AppendCopy
  118226. +# define gcdOUTPUTBUFFER _AppendBuffer
  118227. +#else
  118228. +# define gcdOUTPUTPREFIX _PrintPrefix
  118229. +# define gcdOUTPUTSTRING _PrintString
  118230. +# define gcdOUTPUTCOPY _PrintString
  118231. +# define gcdOUTPUTBUFFER _PrintBuffer
  118232. +#endif
  118233. +
  118234. +/******************************************************************************\
  118235. +****************************** Private Structures ******************************
  118236. +\******************************************************************************/
  118237. +
  118238. +typedef enum _gceBUFITEM
  118239. +{
  118240. + gceBUFITEM_NONE,
  118241. + gcvBUFITEM_PREFIX,
  118242. + gcvBUFITEM_STRING,
  118243. + gcvBUFITEM_COPY,
  118244. + gcvBUFITEM_BUFFER
  118245. +}
  118246. +gceBUFITEM;
  118247. +
  118248. +/* Common item head/buffer terminator. */
  118249. +typedef struct _gcsBUFITEM_HEAD * gcsBUFITEM_HEAD_PTR;
  118250. +typedef struct _gcsBUFITEM_HEAD
  118251. +{
  118252. + gceBUFITEM type;
  118253. +}
  118254. +gcsBUFITEM_HEAD;
  118255. +
  118256. +/* String prefix (for ex. [ 1,tid=0x019A]) */
  118257. +typedef struct _gcsBUFITEM_PREFIX * gcsBUFITEM_PREFIX_PTR;
  118258. +typedef struct _gcsBUFITEM_PREFIX
  118259. +{
  118260. + gceBUFITEM type;
  118261. +#if gcdHAVEPREFIX
  118262. + gctPOINTER prefixData;
  118263. +#endif
  118264. +}
  118265. +gcsBUFITEM_PREFIX;
  118266. +
  118267. +/* Buffered string. */
  118268. +typedef struct _gcsBUFITEM_STRING * gcsBUFITEM_STRING_PTR;
  118269. +typedef struct _gcsBUFITEM_STRING
  118270. +{
  118271. + gceBUFITEM type;
  118272. + gctINT indent;
  118273. + gctCONST_STRING message;
  118274. + gctPOINTER messageData;
  118275. + gctUINT messageDataSize;
  118276. +}
  118277. +gcsBUFITEM_STRING;
  118278. +
  118279. +/* Buffered string (copy of the string is included with the record). */
  118280. +typedef struct _gcsBUFITEM_COPY * gcsBUFITEM_COPY_PTR;
  118281. +typedef struct _gcsBUFITEM_COPY
  118282. +{
  118283. + gceBUFITEM type;
  118284. + gctINT indent;
  118285. + gctPOINTER messageData;
  118286. + gctUINT messageDataSize;
  118287. +}
  118288. +gcsBUFITEM_COPY;
  118289. +
  118290. +/* Memory buffer. */
  118291. +typedef struct _gcsBUFITEM_BUFFER * gcsBUFITEM_BUFFER_PTR;
  118292. +typedef struct _gcsBUFITEM_BUFFER
  118293. +{
  118294. + gceBUFITEM type;
  118295. + gctINT indent;
  118296. + gceDUMP_BUFFER bufferType;
  118297. +
  118298. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  118299. + gctUINT32 dmaAddress;
  118300. +#endif
  118301. +
  118302. + gctUINT dataSize;
  118303. + gctUINT32 address;
  118304. +#if gcdHAVEPREFIX
  118305. + gctPOINTER prefixData;
  118306. +#endif
  118307. +}
  118308. +gcsBUFITEM_BUFFER;
  118309. +
  118310. +typedef struct _gcsBUFFERED_OUTPUT * gcsBUFFERED_OUTPUT_PTR;
  118311. +typedef struct _gcsBUFFERED_OUTPUT
  118312. +{
  118313. +#if gcdTHREAD_BUFFERS > 1
  118314. + gctUINT32 threadID;
  118315. +#endif
  118316. +
  118317. +#if gcdSHOW_LINE_NUMBER
  118318. + gctUINT64 lineNumber;
  118319. +#endif
  118320. +
  118321. + gctINT indent;
  118322. +
  118323. +#if gcdBUFFERED_OUTPUT
  118324. + gctINT start;
  118325. + gctINT index;
  118326. + gctINT count;
  118327. + gctUINT8 buffer[gcdBUFFERED_SIZE];
  118328. +#endif
  118329. +
  118330. + gcsBUFFERED_OUTPUT_PTR prev;
  118331. + gcsBUFFERED_OUTPUT_PTR next;
  118332. +}
  118333. +gcsBUFFERED_OUTPUT;
  118334. +
  118335. +typedef gctUINT (* gcfPRINTSTRING) (
  118336. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118337. + IN gcsBUFITEM_HEAD_PTR Item
  118338. + );
  118339. +
  118340. +typedef gctINT (* gcfGETITEMSIZE) (
  118341. + IN gcsBUFITEM_HEAD_PTR Item
  118342. + );
  118343. +
  118344. +/******************************************************************************\
  118345. +******************************* Private Variables ******************************
  118346. +\******************************************************************************/
  118347. +
  118348. +static gcsBUFFERED_OUTPUT _outputBuffer[gcdTHREAD_BUFFERS];
  118349. +static gcsBUFFERED_OUTPUT_PTR _outputBufferHead = gcvNULL;
  118350. +static gcsBUFFERED_OUTPUT_PTR _outputBufferTail = gcvNULL;
  118351. +
  118352. +/******************************************************************************\
  118353. +****************************** Item Size Functions *****************************
  118354. +\******************************************************************************/
  118355. +
  118356. +#if gcdBUFFERED_OUTPUT
  118357. +static gctINT
  118358. +_GetTerminatorItemSize(
  118359. + IN gcsBUFITEM_HEAD_PTR Item
  118360. + )
  118361. +{
  118362. + return gcmSIZEOF(gcsBUFITEM_HEAD);
  118363. +}
  118364. +
  118365. +static gctINT
  118366. +_GetPrefixItemSize(
  118367. + IN gcsBUFITEM_HEAD_PTR Item
  118368. + )
  118369. +{
  118370. +#if gcdHAVEPREFIX
  118371. + gcsBUFITEM_PREFIX_PTR item = (gcsBUFITEM_PREFIX_PTR) Item;
  118372. + gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  118373. + return vlen + gcdPREFIX_SIZE;
  118374. +#else
  118375. + return gcmSIZEOF(gcsBUFITEM_PREFIX);
  118376. +#endif
  118377. +}
  118378. +
  118379. +static gctINT
  118380. +_GetStringItemSize(
  118381. + IN gcsBUFITEM_HEAD_PTR Item
  118382. + )
  118383. +{
  118384. + gcsBUFITEM_STRING_PTR item = (gcsBUFITEM_STRING_PTR) Item;
  118385. + gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  118386. + return vlen + item->messageDataSize;
  118387. +}
  118388. +
  118389. +static gctINT
  118390. +_GetCopyItemSize(
  118391. + IN gcsBUFITEM_HEAD_PTR Item
  118392. + )
  118393. +{
  118394. + gcsBUFITEM_COPY_PTR item = (gcsBUFITEM_COPY_PTR) Item;
  118395. + gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  118396. + return vlen + item->messageDataSize;
  118397. +}
  118398. +
  118399. +static gctINT
  118400. +_GetBufferItemSize(
  118401. + IN gcsBUFITEM_HEAD_PTR Item
  118402. + )
  118403. +{
  118404. +#if gcdHAVEPREFIX
  118405. + gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
  118406. + gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  118407. + return vlen + gcdPREFIX_SIZE + item->dataSize;
  118408. +#else
  118409. + gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
  118410. + return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
  118411. +#endif
  118412. +}
  118413. +
  118414. +static gcfGETITEMSIZE _itemSize[] =
  118415. +{
  118416. + _GetTerminatorItemSize,
  118417. + _GetPrefixItemSize,
  118418. + _GetStringItemSize,
  118419. + _GetCopyItemSize,
  118420. + _GetBufferItemSize
  118421. +};
  118422. +#endif
  118423. +
  118424. +/******************************************************************************\
  118425. +******************************* Printing Functions *****************************
  118426. +\******************************************************************************/
  118427. +
  118428. +#if gcdDEBUG || gcdBUFFERED_OUTPUT
  118429. +static void
  118430. +_DirectPrint(
  118431. + gctCONST_STRING Message,
  118432. + ...
  118433. + )
  118434. +{
  118435. + gctINT len;
  118436. + char buffer[768];
  118437. + gctARGUMENTS arguments;
  118438. +
  118439. + gcmkARGUMENTS_START(arguments, Message);
  118440. + len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), Message, arguments);
  118441. + gcmkARGUMENTS_END(arguments);
  118442. +
  118443. + buffer[len] = '\0';
  118444. + gcmkOUTPUT_STRING(buffer);
  118445. +}
  118446. +#endif
  118447. +
  118448. +static int
  118449. +_AppendIndent(
  118450. + IN gctINT Indent,
  118451. + IN char * Buffer,
  118452. + IN int BufferSize
  118453. + )
  118454. +{
  118455. + gctINT i;
  118456. +
  118457. + gctINT len = 0;
  118458. + gctINT indent = Indent % 40;
  118459. +
  118460. + for (i = 0; i < indent; i += 1)
  118461. + {
  118462. + Buffer[len++] = ' ';
  118463. + }
  118464. +
  118465. + if (indent != Indent)
  118466. + {
  118467. + len += gcmkSPRINTF(
  118468. + Buffer + len, BufferSize - len, " <%d> ", Indent
  118469. + );
  118470. +
  118471. + Buffer[len] = '\0';
  118472. + }
  118473. +
  118474. + return len;
  118475. +}
  118476. +
  118477. +#if gcdHAVEPREFIX
  118478. +static void
  118479. +_PrintPrefix(
  118480. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118481. + IN gctPOINTER Data
  118482. + )
  118483. +{
  118484. + char buffer[768];
  118485. + gctINT len;
  118486. +
  118487. + /* Format the string. */
  118488. + len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, Data);
  118489. + buffer[len] = '\0';
  118490. +
  118491. + /* Print the string. */
  118492. + gcmkOUTPUT_STRING(buffer);
  118493. +}
  118494. +#endif
  118495. +
  118496. +static void
  118497. +_PrintString(
  118498. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118499. + IN gctINT Indent,
  118500. + IN gctCONST_STRING Message,
  118501. + IN gctUINT ArgumentSize,
  118502. + IN gctPOINTER Data
  118503. + )
  118504. +{
  118505. + char buffer[768];
  118506. + gctINT len;
  118507. +
  118508. + /* Append the indent string. */
  118509. + len = _AppendIndent(Indent, buffer, gcmSIZEOF(buffer));
  118510. +
  118511. + /* Format the string. */
  118512. + len += gcmkVSPRINTF(buffer + len, gcmSIZEOF(buffer) - len, Message, Data);
  118513. + buffer[len] = '\0';
  118514. +
  118515. + /* Add end-of-line if missing. */
  118516. + if (buffer[len - 1] != '\n')
  118517. + {
  118518. + buffer[len++] = '\n';
  118519. + buffer[len] = '\0';
  118520. + }
  118521. +
  118522. + /* Print the string. */
  118523. + gcmkOUTPUT_STRING(buffer);
  118524. +}
  118525. +
  118526. +static void
  118527. +_PrintBuffer(
  118528. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118529. + IN gctINT Indent,
  118530. + IN gctPOINTER PrefixData,
  118531. + IN gctPOINTER Data,
  118532. + IN gctUINT Address,
  118533. + IN gctUINT DataSize,
  118534. + IN gceDUMP_BUFFER Type,
  118535. + IN gctUINT32 DmaAddress
  118536. + )
  118537. +{
  118538. + static gctCONST_STRING _titleString[] =
  118539. + {
  118540. + "CONTEXT BUFFER",
  118541. + "USER COMMAND BUFFER",
  118542. + "KERNEL COMMAND BUFFER",
  118543. + "LINK BUFFER",
  118544. + "WAIT LINK BUFFER",
  118545. + ""
  118546. + };
  118547. +
  118548. + static const gctINT COLUMN_COUNT = 8;
  118549. +
  118550. + gctUINT i, count, column, address;
  118551. + gctUINT32_PTR data;
  118552. + gctCHAR buffer[768];
  118553. + gctUINT indent, len;
  118554. + gctBOOL command;
  118555. +
  118556. + /* Append space for the prefix. */
  118557. +#if gcdHAVEPREFIX
  118558. + indent = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, PrefixData);
  118559. + buffer[indent] = '\0';
  118560. +#else
  118561. + indent = 0;
  118562. +#endif
  118563. +
  118564. + /* Append the indent string. */
  118565. + indent += _AppendIndent(
  118566. + Indent, buffer + indent, gcmSIZEOF(buffer) - indent
  118567. + );
  118568. +
  118569. + switch (Type)
  118570. + {
  118571. + case gceDUMP_BUFFER_CONTEXT:
  118572. + case gceDUMP_BUFFER_USER:
  118573. + case gceDUMP_BUFFER_KERNEL:
  118574. + case gceDUMP_BUFFER_LINK:
  118575. + case gceDUMP_BUFFER_WAITLINK:
  118576. + /* Form and print the title string. */
  118577. + gcmkSPRINTF2(
  118578. + buffer + indent, gcmSIZEOF(buffer) - indent,
  118579. + "%s%s\n", _titleString[Type],
  118580. + ((DmaAddress >= Address) && (DmaAddress < Address + DataSize))
  118581. + ? " (CURRENT)" : ""
  118582. + );
  118583. +
  118584. + gcmkOUTPUT_STRING(buffer);
  118585. +
  118586. + /* Terminate the string. */
  118587. + buffer[indent] = '\0';
  118588. +
  118589. + /* This is a command buffer. */
  118590. + command = gcvTRUE;
  118591. + break;
  118592. +
  118593. + case gceDUMP_BUFFER_FROM_USER:
  118594. + /* This is not a command buffer. */
  118595. + command = gcvFALSE;
  118596. +
  118597. + /* No title. */
  118598. + break;
  118599. +
  118600. + default:
  118601. + gcmDBGASSERT(gcvFALSE, "%s", "invalid buffer type");
  118602. +
  118603. + /* This is not a command buffer. */
  118604. + command = gcvFALSE;
  118605. + }
  118606. +
  118607. + /* Overwrite the prefix with spaces. */
  118608. + for (i = 0; i < indent; i += 1)
  118609. + {
  118610. + buffer[i] = ' ';
  118611. + }
  118612. +
  118613. + /* Form and print the opening string. */
  118614. + if (command)
  118615. + {
  118616. + gcmkSPRINTF2(
  118617. + buffer + indent, gcmSIZEOF(buffer) - indent,
  118618. + "@[kernel.command %08X %08X\n", Address, DataSize
  118619. + );
  118620. +
  118621. + gcmkOUTPUT_STRING(buffer);
  118622. +
  118623. + /* Terminate the string. */
  118624. + buffer[indent] = '\0';
  118625. + }
  118626. +
  118627. + /* Get initial address. */
  118628. + address = Address;
  118629. +
  118630. + /* Cast the data pointer. */
  118631. + data = (gctUINT32_PTR) Data;
  118632. +
  118633. + /* Compute the number of double words. */
  118634. + count = DataSize / gcmSIZEOF(gctUINT32);
  118635. +
  118636. + /* Print the buffer. */
  118637. + for (i = 0, len = indent, column = 0; i < count; i += 1)
  118638. + {
  118639. + /* Append the address. */
  118640. + if (column == 0)
  118641. + {
  118642. + len += gcmkSPRINTF(
  118643. + buffer + len, gcmSIZEOF(buffer) - len, "0x%08X:", address
  118644. + );
  118645. + }
  118646. +
  118647. + /* Append the data value. */
  118648. + len += gcmkSPRINTF2(
  118649. + buffer + len, gcmSIZEOF(buffer) - len, "%c%08X",
  118650. + (address == DmaAddress)? '>' : ' ', data[i]
  118651. + );
  118652. +
  118653. + buffer[len] = '\0';
  118654. +
  118655. + /* Update the address. */
  118656. + address += gcmSIZEOF(gctUINT32);
  118657. +
  118658. + /* Advance column count. */
  118659. + column += 1;
  118660. +
  118661. + /* End of line? */
  118662. + if ((column % COLUMN_COUNT) == 0)
  118663. + {
  118664. + /* Append EOL. */
  118665. + gcmkSTRCAT(buffer + len, gcmSIZEOF(buffer) - len, "\n");
  118666. +
  118667. + /* Print the string. */
  118668. + gcmkOUTPUT_STRING(buffer);
  118669. +
  118670. + /* Reset. */
  118671. + len = indent;
  118672. + column = 0;
  118673. + }
  118674. + }
  118675. +
  118676. + /* Print the last partial string. */
  118677. + if (column != 0)
  118678. + {
  118679. + /* Append EOL. */
  118680. + gcmkSTRCAT(buffer + len, gcmSIZEOF(buffer) - len, "\n");
  118681. +
  118682. + /* Print the string. */
  118683. + gcmkOUTPUT_STRING(buffer);
  118684. + }
  118685. +
  118686. + /* Form and print the opening string. */
  118687. + if (command)
  118688. + {
  118689. + buffer[indent] = '\0';
  118690. + gcmkSTRCAT(buffer, gcmSIZEOF(buffer), "] -- command\n");
  118691. + gcmkOUTPUT_STRING(buffer);
  118692. + }
  118693. +}
  118694. +
  118695. +#if gcdBUFFERED_OUTPUT
  118696. +static gctUINT
  118697. +_PrintNone(
  118698. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118699. + IN gcsBUFITEM_HEAD_PTR Item
  118700. + )
  118701. +{
  118702. + /* Return the size of the node. */
  118703. + return gcmSIZEOF(gcsBUFITEM_HEAD);
  118704. +}
  118705. +
  118706. +static gctUINT
  118707. +_PrintPrefixWrapper(
  118708. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118709. + IN gcsBUFITEM_HEAD_PTR Item
  118710. + )
  118711. +{
  118712. +#if gcdHAVEPREFIX
  118713. + gcsBUFITEM_PREFIX_PTR item;
  118714. + gctUINT vlen;
  118715. +
  118716. + /* Get access to the data. */
  118717. + item = (gcsBUFITEM_PREFIX_PTR) Item;
  118718. +
  118719. + /* Print the message. */
  118720. + _PrintPrefix(OutputBuffer, item->prefixData);
  118721. +
  118722. + /* Compute the size of the variable portion of the structure. */
  118723. + vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  118724. +
  118725. + /* Return the size of the node. */
  118726. + return vlen + gcdPREFIX_SIZE;
  118727. +#else
  118728. + return gcmSIZEOF(gcsBUFITEM_PREFIX);
  118729. +#endif
  118730. +}
  118731. +
  118732. +static gctUINT
  118733. +_PrintStringWrapper(
  118734. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118735. + IN gcsBUFITEM_HEAD_PTR Item
  118736. + )
  118737. +{
  118738. + gcsBUFITEM_STRING_PTR item;
  118739. + gctUINT vlen;
  118740. +
  118741. + /* Get access to the data. */
  118742. + item = (gcsBUFITEM_STRING_PTR) Item;
  118743. +
  118744. + /* Print the message. */
  118745. + _PrintString(
  118746. + OutputBuffer,
  118747. + item->indent, item->message, item->messageDataSize, item->messageData
  118748. + );
  118749. +
  118750. + /* Compute the size of the variable portion of the structure. */
  118751. + vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  118752. +
  118753. + /* Return the size of the node. */
  118754. + return vlen + item->messageDataSize;
  118755. +}
  118756. +
  118757. +static gctUINT
  118758. +_PrintCopyWrapper(
  118759. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118760. + IN gcsBUFITEM_HEAD_PTR Item
  118761. + )
  118762. +{
  118763. + gcsBUFITEM_COPY_PTR item;
  118764. + gctCONST_STRING message;
  118765. + gctUINT vlen;
  118766. +
  118767. + /* Get access to the data. */
  118768. + item = (gcsBUFITEM_COPY_PTR) Item;
  118769. +
  118770. + /* Determine the string pointer. */
  118771. + message = (gctCONST_STRING) (item + 1);
  118772. +
  118773. + /* Print the message. */
  118774. + _PrintString(
  118775. + OutputBuffer,
  118776. + item->indent, message, item->messageDataSize, item->messageData
  118777. + );
  118778. +
  118779. + /* Compute the size of the variable portion of the structure. */
  118780. + vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  118781. +
  118782. + /* Return the size of the node. */
  118783. + return vlen + item->messageDataSize;
  118784. +}
  118785. +
  118786. +static gctUINT
  118787. +_PrintBufferWrapper(
  118788. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118789. + IN gcsBUFITEM_HEAD_PTR Item
  118790. + )
  118791. +{
  118792. +#if gcdHAVEPREFIX
  118793. + gctUINT32 dmaAddress;
  118794. + gcsBUFITEM_BUFFER_PTR item;
  118795. + gctPOINTER data;
  118796. + gctUINT vlen;
  118797. +
  118798. + /* Get access to the data. */
  118799. + item = (gcsBUFITEM_BUFFER_PTR) Item;
  118800. +
  118801. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  118802. + dmaAddress = item->dmaAddress;
  118803. +#else
  118804. + dmaAddress = 0xFFFFFFFF;
  118805. +#endif
  118806. +
  118807. + if (dmaAddress != 0)
  118808. + {
  118809. + /* Compute the data address. */
  118810. + data = ((gctUINT8_PTR) item->prefixData) + gcdPREFIX_SIZE;
  118811. +
  118812. + /* Print buffer. */
  118813. + _PrintBuffer(
  118814. + OutputBuffer,
  118815. + item->indent, item->prefixData,
  118816. + data, item->address, item->dataSize,
  118817. + item->bufferType, dmaAddress
  118818. + );
  118819. + }
  118820. +
  118821. + /* Compute the size of the variable portion of the structure. */
  118822. + vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  118823. +
  118824. + /* Return the size of the node. */
  118825. + return vlen + gcdPREFIX_SIZE + item->dataSize;
  118826. +#else
  118827. + gctUINT32 dmaAddress;
  118828. + gcsBUFITEM_BUFFER_PTR item;
  118829. +
  118830. + /* Get access to the data. */
  118831. + item = (gcsBUFITEM_BUFFER_PTR) Item;
  118832. +
  118833. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  118834. + dmaAddress = item->dmaAddress;
  118835. +#else
  118836. + dmaAddress = 0xFFFFFFFF;
  118837. +#endif
  118838. +
  118839. + if (dmaAddress != 0)
  118840. + {
  118841. + /* Print buffer. */
  118842. + _PrintBuffer(
  118843. + OutputBuffer,
  118844. + item->indent, gcvNULL,
  118845. + item + 1, item->address, item->dataSize,
  118846. + item->bufferType, dmaAddress
  118847. + );
  118848. + }
  118849. +
  118850. + /* Return the size of the node. */
  118851. + return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
  118852. +#endif
  118853. +}
  118854. +
  118855. +static gcfPRINTSTRING _printArray[] =
  118856. +{
  118857. + _PrintNone,
  118858. + _PrintPrefixWrapper,
  118859. + _PrintStringWrapper,
  118860. + _PrintCopyWrapper,
  118861. + _PrintBufferWrapper
  118862. +};
  118863. +#endif
  118864. +
  118865. +/******************************************************************************\
  118866. +******************************* Private Functions ******************************
  118867. +\******************************************************************************/
  118868. +
  118869. +#if gcdBUFFERED_OUTPUT
  118870. +
  118871. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  118872. +static gcsBUFITEM_BUFFER_PTR
  118873. +_FindCurrentDMABuffer(
  118874. + gctUINT32 DmaAddress
  118875. + )
  118876. +{
  118877. + gctINT i, skip;
  118878. + gcsBUFITEM_HEAD_PTR item;
  118879. + gcsBUFITEM_BUFFER_PTR dmaCurrent;
  118880. +
  118881. + /* Reset the current buffer. */
  118882. + dmaCurrent = gcvNULL;
  118883. +
  118884. + /* Get the first stored item. */
  118885. + item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
  118886. +
  118887. + /* Run through all items. */
  118888. + for (i = 0; i < _outputBufferHead->count; i += 1)
  118889. + {
  118890. + /* Buffer item? */
  118891. + if (item->type == gcvBUFITEM_BUFFER)
  118892. + {
  118893. + gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
  118894. +
  118895. + if ((DmaAddress >= buffer->address) &&
  118896. + (DmaAddress < buffer->address + buffer->dataSize))
  118897. + {
  118898. + dmaCurrent = buffer;
  118899. + }
  118900. + }
  118901. +
  118902. + /* Get the item size and skip it. */
  118903. + skip = (* _itemSize[item->type]) (item);
  118904. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  118905. +
  118906. + /* End of the buffer? Wrap around. */
  118907. + if (item->type == gceBUFITEM_NONE)
  118908. + {
  118909. + item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
  118910. + }
  118911. + }
  118912. +
  118913. + /* Return result. */
  118914. + return dmaCurrent;
  118915. +}
  118916. +
  118917. +static void
  118918. +_EnableAllDMABuffers(
  118919. + void
  118920. + )
  118921. +{
  118922. + gctINT i, skip;
  118923. + gcsBUFITEM_HEAD_PTR item;
  118924. +
  118925. + /* Get the first stored item. */
  118926. + item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
  118927. +
  118928. + /* Run through all items. */
  118929. + for (i = 0; i < _outputBufferHead->count; i += 1)
  118930. + {
  118931. + /* Buffer item? */
  118932. + if (item->type == gcvBUFITEM_BUFFER)
  118933. + {
  118934. + gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
  118935. +
  118936. + /* Enable the buffer. */
  118937. + buffer->dmaAddress = ~0U;
  118938. + }
  118939. +
  118940. + /* Get the item size and skip it. */
  118941. + skip = (* _itemSize[item->type]) (item);
  118942. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  118943. +
  118944. + /* End of the buffer? Wrap around. */
  118945. + if (item->type == gceBUFITEM_NONE)
  118946. + {
  118947. + item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
  118948. + }
  118949. + }
  118950. +}
  118951. +
  118952. +static void
  118953. +_EnableDMABuffers(
  118954. + gctUINT32 DmaAddress,
  118955. + gcsBUFITEM_BUFFER_PTR CurrentDMABuffer
  118956. + )
  118957. +{
  118958. + gctINT i, skip, index;
  118959. + gcsBUFITEM_HEAD_PTR item;
  118960. + gcsBUFITEM_BUFFER_PTR buffers[gcdDMA_BUFFER_COUNT];
  118961. +
  118962. + /* Reset buffer pointers. */
  118963. + gckOS_ZeroMemory(buffers, gcmSIZEOF(buffers));
  118964. +
  118965. + /* Set the current buffer index. */
  118966. + index = -1;
  118967. +
  118968. + /* Get the first stored item. */
  118969. + item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
  118970. +
  118971. + /* Run through all items until the current DMA buffer is found. */
  118972. + for (i = 0; i < _outputBufferHead->count; i += 1)
  118973. + {
  118974. + /* Buffer item? */
  118975. + if (item->type == gcvBUFITEM_BUFFER)
  118976. + {
  118977. + /* Advance the index. */
  118978. + index = (index + 1) % gcdDMA_BUFFER_COUNT;
  118979. +
  118980. + /* Add to the buffer array. */
  118981. + buffers[index] = (gcsBUFITEM_BUFFER_PTR) item;
  118982. +
  118983. + /* Stop if this is the current DMA buffer. */
  118984. + if ((gcsBUFITEM_BUFFER_PTR) item == CurrentDMABuffer)
  118985. + {
  118986. + break;
  118987. + }
  118988. + }
  118989. +
  118990. + /* Get the item size and skip it. */
  118991. + skip = (* _itemSize[item->type]) (item);
  118992. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  118993. +
  118994. + /* End of the buffer? Wrap around. */
  118995. + if (item->type == gceBUFITEM_NONE)
  118996. + {
  118997. + item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
  118998. + }
  118999. + }
  119000. +
  119001. + /* Enable the found buffers. */
  119002. + gcmDBGASSERT(index != -1, "%d", index);
  119003. +
  119004. + for (i = 0; i < gcdDMA_BUFFER_COUNT; i += 1)
  119005. + {
  119006. + if (buffers[index] == gcvNULL)
  119007. + {
  119008. + break;
  119009. + }
  119010. +
  119011. + buffers[index]->dmaAddress = DmaAddress;
  119012. +
  119013. + index -= 1;
  119014. +
  119015. + if (index == -1)
  119016. + {
  119017. + index = gcdDMA_BUFFER_COUNT - 1;
  119018. + }
  119019. + }
  119020. +}
  119021. +#endif
  119022. +
  119023. +static void
  119024. +_Flush(
  119025. + gctUINT32 DmaAddress
  119026. + )
  119027. +{
  119028. + gctINT i, skip;
  119029. + gcsBUFITEM_HEAD_PTR item;
  119030. +
  119031. + gcsBUFFERED_OUTPUT_PTR outputBuffer = _outputBufferHead;
  119032. +
  119033. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  119034. + if ((outputBuffer != gcvNULL) && (outputBuffer->count != 0))
  119035. + {
  119036. + /* Find the current DMA buffer. */
  119037. + gcsBUFITEM_BUFFER_PTR dmaCurrent = _FindCurrentDMABuffer(DmaAddress);
  119038. +
  119039. + /* Was the current buffer found? */
  119040. + if (dmaCurrent == gcvNULL)
  119041. + {
  119042. + /* No, print all buffers. */
  119043. + _EnableAllDMABuffers();
  119044. + }
  119045. + else
  119046. + {
  119047. + /* Yes, enable only specified number of buffers. */
  119048. + _EnableDMABuffers(DmaAddress, dmaCurrent);
  119049. + }
  119050. + }
  119051. +#endif
  119052. +
  119053. + while (outputBuffer != gcvNULL)
  119054. + {
  119055. + if (outputBuffer->count != 0)
  119056. + {
  119057. + _DirectPrint("********************************************************************************\n");
  119058. + _DirectPrint("FLUSHING DEBUG OUTPUT BUFFER (%d elements).\n", outputBuffer->count);
  119059. + _DirectPrint("********************************************************************************\n");
  119060. +
  119061. + item = (gcsBUFITEM_HEAD_PTR) &outputBuffer->buffer[outputBuffer->start];
  119062. +
  119063. + for (i = 0; i < outputBuffer->count; i += 1)
  119064. + {
  119065. + skip = (* _printArray[item->type]) (outputBuffer, item);
  119066. +
  119067. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  119068. +
  119069. + if (item->type == gceBUFITEM_NONE)
  119070. + {
  119071. + item = (gcsBUFITEM_HEAD_PTR) outputBuffer->buffer;
  119072. + }
  119073. + }
  119074. +
  119075. + outputBuffer->start = 0;
  119076. + outputBuffer->index = 0;
  119077. + outputBuffer->count = 0;
  119078. + }
  119079. +
  119080. + outputBuffer = outputBuffer->next;
  119081. + }
  119082. +}
  119083. +
  119084. +static gcsBUFITEM_HEAD_PTR
  119085. +_AllocateItem(
  119086. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119087. + IN gctINT Size
  119088. + )
  119089. +{
  119090. + gctINT skip;
  119091. + gcsBUFITEM_HEAD_PTR item, next;
  119092. +
  119093. +#if gcdENABLE_OVERFLOW
  119094. + if (
  119095. + (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
  119096. + ||
  119097. + (
  119098. + (OutputBuffer->index < OutputBuffer->start) &&
  119099. + (OutputBuffer->index + Size >= OutputBuffer->start)
  119100. + )
  119101. + )
  119102. + {
  119103. + if (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
  119104. + {
  119105. + if (OutputBuffer->index < OutputBuffer->start)
  119106. + {
  119107. + item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
  119108. +
  119109. + while (item->type != gceBUFITEM_NONE)
  119110. + {
  119111. + skip = (* _itemSize[item->type]) (item);
  119112. +
  119113. + OutputBuffer->start += skip;
  119114. + OutputBuffer->count -= 1;
  119115. +
  119116. + item->type = gceBUFITEM_NONE;
  119117. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  119118. + }
  119119. +
  119120. + OutputBuffer->start = 0;
  119121. + }
  119122. +
  119123. + OutputBuffer->index = 0;
  119124. + }
  119125. +
  119126. + item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
  119127. +
  119128. + while (OutputBuffer->start - OutputBuffer->index <= Size)
  119129. + {
  119130. + skip = (* _itemSize[item->type]) (item);
  119131. +
  119132. + OutputBuffer->start += skip;
  119133. + OutputBuffer->count -= 1;
  119134. +
  119135. + item->type = gceBUFITEM_NONE;
  119136. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  119137. +
  119138. + if (item->type == gceBUFITEM_NONE)
  119139. + {
  119140. + OutputBuffer->start = 0;
  119141. + break;
  119142. + }
  119143. + }
  119144. + }
  119145. +#else
  119146. + if (OutputBuffer->index + Size > gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
  119147. + {
  119148. + _DirectPrint("\nMessage buffer full; forcing message flush.\n\n");
  119149. + _Flush(~0U);
  119150. + }
  119151. +#endif
  119152. +
  119153. + item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->index];
  119154. +
  119155. + OutputBuffer->index += Size;
  119156. + OutputBuffer->count += 1;
  119157. +
  119158. + next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + Size);
  119159. + next->type = gceBUFITEM_NONE;
  119160. +
  119161. + return item;
  119162. +}
  119163. +
  119164. +#if gcdALIGNBYSIZE
  119165. +static void
  119166. +_FreeExtraSpace(
  119167. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119168. + IN gctPOINTER Item,
  119169. + IN gctINT ItemSize,
  119170. + IN gctINT FreeSize
  119171. + )
  119172. +{
  119173. + gcsBUFITEM_HEAD_PTR next;
  119174. +
  119175. + OutputBuffer->index -= FreeSize;
  119176. +
  119177. + next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) Item + ItemSize);
  119178. + next->type = gceBUFITEM_NONE;
  119179. +}
  119180. +#endif
  119181. +
  119182. +#if gcdHAVEPREFIX
  119183. +static void
  119184. +_AppendPrefix(
  119185. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119186. + IN gctPOINTER Data
  119187. + )
  119188. +{
  119189. + gctUINT8_PTR prefixData;
  119190. + gcsBUFITEM_PREFIX_PTR item;
  119191. + gctINT allocSize;
  119192. +
  119193. +#if gcdALIGNBYSIZE
  119194. + gctUINT alignment;
  119195. + gctINT size, freeSize;
  119196. +#endif
  119197. +
  119198. + gcmDBGASSERT(Data != gcvNULL, "%p", Data);
  119199. +
  119200. + /* Determine the maximum item size. */
  119201. + allocSize
  119202. + = gcmSIZEOF(gcsBUFITEM_PREFIX)
  119203. + + gcdPREFIX_SIZE
  119204. + + gcdPREFIX_ALIGNMENT;
  119205. +
  119206. + /* Allocate prefix item. */
  119207. + item = (gcsBUFITEM_PREFIX_PTR) _AllocateItem(OutputBuffer, allocSize);
  119208. +
  119209. + /* Compute the initial prefix data pointer. */
  119210. + prefixData = (gctUINT8_PTR) (item + 1);
  119211. +
  119212. + /* Align the data pointer as necessary. */
  119213. +#if gcdALIGNBYSIZE
  119214. + alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
  119215. + prefixData += alignment;
  119216. +#endif
  119217. +
  119218. + /* Set item data. */
  119219. + item->type = gcvBUFITEM_PREFIX;
  119220. + item->prefixData = prefixData;
  119221. +
  119222. + /* Copy argument value. */
  119223. + memcpy(prefixData, Data, gcdPREFIX_SIZE);
  119224. +
  119225. +#if gcdALIGNBYSIZE
  119226. + /* Compute the actual node size. */
  119227. + size = gcmSIZEOF(gcsBUFITEM_PREFIX) + gcdPREFIX_SIZE + alignment;
  119228. +
  119229. + /* Free extra memory if any. */
  119230. + freeSize = allocSize - size;
  119231. + if (freeSize != 0)
  119232. + {
  119233. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  119234. + }
  119235. +#endif
  119236. +}
  119237. +#endif
  119238. +
  119239. +static void
  119240. +_AppendString(
  119241. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119242. + IN gctINT Indent,
  119243. + IN gctCONST_STRING Message,
  119244. + IN gctUINT ArgumentSize,
  119245. + IN gctPOINTER Data
  119246. + )
  119247. +{
  119248. + gctUINT8_PTR messageData;
  119249. + gcsBUFITEM_STRING_PTR item;
  119250. + gctINT allocSize;
  119251. +
  119252. +#if gcdALIGNBYSIZE
  119253. + gctUINT alignment;
  119254. + gctINT size, freeSize;
  119255. +#endif
  119256. +
  119257. + /* Determine the maximum item size. */
  119258. + allocSize
  119259. + = gcmSIZEOF(gcsBUFITEM_STRING)
  119260. + + ArgumentSize
  119261. + + gcdVARARG_ALIGNMENT;
  119262. +
  119263. + /* Allocate prefix item. */
  119264. + item = (gcsBUFITEM_STRING_PTR) _AllocateItem(OutputBuffer, allocSize);
  119265. +
  119266. + /* Compute the initial message data pointer. */
  119267. + messageData = (gctUINT8_PTR) (item + 1);
  119268. +
  119269. + /* Align the data pointer as necessary. */
  119270. +#if gcdALIGNBYSIZE
  119271. + alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
  119272. + messageData += alignment;
  119273. +#endif
  119274. +
  119275. + /* Set item data. */
  119276. + item->type = gcvBUFITEM_STRING;
  119277. + item->indent = Indent;
  119278. + item->message = Message;
  119279. + item->messageData = messageData;
  119280. + item->messageDataSize = ArgumentSize;
  119281. +
  119282. + /* Copy argument value. */
  119283. + if (ArgumentSize != 0)
  119284. + {
  119285. + memcpy(messageData, Data, ArgumentSize);
  119286. + }
  119287. +
  119288. +#if gcdALIGNBYSIZE
  119289. + /* Compute the actual node size. */
  119290. + size = gcmSIZEOF(gcsBUFITEM_STRING) + ArgumentSize + alignment;
  119291. +
  119292. + /* Free extra memory if any. */
  119293. + freeSize = allocSize - size;
  119294. + if (freeSize != 0)
  119295. + {
  119296. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  119297. + }
  119298. +#endif
  119299. +}
  119300. +
  119301. +static void
  119302. +_AppendCopy(
  119303. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119304. + IN gctINT Indent,
  119305. + IN gctCONST_STRING Message,
  119306. + IN gctUINT ArgumentSize,
  119307. + IN gctPOINTER Data
  119308. + )
  119309. +{
  119310. + gctUINT8_PTR messageData;
  119311. + gcsBUFITEM_COPY_PTR item;
  119312. + gctINT allocSize;
  119313. + gctINT messageLength;
  119314. + gctCONST_STRING message;
  119315. +
  119316. +#if gcdALIGNBYSIZE
  119317. + gctUINT alignment;
  119318. + gctINT size, freeSize;
  119319. +#endif
  119320. +
  119321. + /* Get the length of the string. */
  119322. + messageLength = strlen(Message) + 1;
  119323. +
  119324. + /* Determine the maximum item size. */
  119325. + allocSize
  119326. + = gcmSIZEOF(gcsBUFITEM_COPY)
  119327. + + messageLength
  119328. + + ArgumentSize
  119329. + + gcdVARARG_ALIGNMENT;
  119330. +
  119331. + /* Allocate prefix item. */
  119332. + item = (gcsBUFITEM_COPY_PTR) _AllocateItem(OutputBuffer, allocSize);
  119333. +
  119334. + /* Determine the message placement. */
  119335. + message = (gctCONST_STRING) (item + 1);
  119336. +
  119337. + /* Compute the initial message data pointer. */
  119338. + messageData = (gctUINT8_PTR) message + messageLength;
  119339. +
  119340. + /* Align the data pointer as necessary. */
  119341. +#if gcdALIGNBYSIZE
  119342. + if (ArgumentSize == 0)
  119343. + {
  119344. + alignment = 0;
  119345. + }
  119346. + else
  119347. + {
  119348. + alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
  119349. + messageData += alignment;
  119350. + }
  119351. +#endif
  119352. +
  119353. + /* Set item data. */
  119354. + item->type = gcvBUFITEM_COPY;
  119355. + item->indent = Indent;
  119356. + item->messageData = messageData;
  119357. + item->messageDataSize = ArgumentSize;
  119358. +
  119359. + /* Copy the message. */
  119360. + memcpy((gctPOINTER) message, Message, messageLength);
  119361. +
  119362. + /* Copy argument value. */
  119363. + if (ArgumentSize != 0)
  119364. + {
  119365. + memcpy(messageData, Data, ArgumentSize);
  119366. + }
  119367. +
  119368. +#if gcdALIGNBYSIZE
  119369. + /* Compute the actual node size. */
  119370. + size
  119371. + = gcmSIZEOF(gcsBUFITEM_COPY)
  119372. + + messageLength
  119373. + + ArgumentSize
  119374. + + alignment;
  119375. +
  119376. + /* Free extra memory if any. */
  119377. + freeSize = allocSize - size;
  119378. + if (freeSize != 0)
  119379. + {
  119380. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  119381. + }
  119382. +#endif
  119383. +}
  119384. +
  119385. +static void
  119386. +_AppendBuffer(
  119387. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119388. + IN gctINT Indent,
  119389. + IN gctPOINTER PrefixData,
  119390. + IN gctPOINTER Data,
  119391. + IN gctUINT Address,
  119392. + IN gctUINT DataSize,
  119393. + IN gceDUMP_BUFFER Type,
  119394. + IN gctUINT32 DmaAddress
  119395. + )
  119396. +{
  119397. +#if gcdHAVEPREFIX
  119398. + gctUINT8_PTR prefixData;
  119399. + gcsBUFITEM_BUFFER_PTR item;
  119400. + gctINT allocSize;
  119401. + gctPOINTER data;
  119402. +
  119403. +#if gcdALIGNBYSIZE
  119404. + gctUINT alignment;
  119405. + gctINT size, freeSize;
  119406. +#endif
  119407. +
  119408. + gcmDBGASSERT(DataSize != 0, "%d", DataSize);
  119409. + gcmDBGASSERT(Data != gcvNULL, "%p", Data);
  119410. +
  119411. + /* Determine the maximum item size. */
  119412. + allocSize
  119413. + = gcmSIZEOF(gcsBUFITEM_BUFFER)
  119414. + + gcdPREFIX_SIZE
  119415. + + gcdPREFIX_ALIGNMENT
  119416. + + DataSize;
  119417. +
  119418. + /* Allocate prefix item. */
  119419. + item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, allocSize);
  119420. +
  119421. + /* Compute the initial prefix data pointer. */
  119422. + prefixData = (gctUINT8_PTR) (item + 1);
  119423. +
  119424. +#if gcdALIGNBYSIZE
  119425. + /* Align the data pointer as necessary. */
  119426. + alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
  119427. + prefixData += alignment;
  119428. +#endif
  119429. +
  119430. + /* Set item data. */
  119431. + item->type = gcvBUFITEM_BUFFER;
  119432. + item->indent = Indent;
  119433. + item->bufferType = Type;
  119434. + item->dataSize = DataSize;
  119435. + item->address = Address;
  119436. + item->prefixData = prefixData;
  119437. +
  119438. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  119439. + item->dmaAddress = DmaAddress;
  119440. +#endif
  119441. +
  119442. + /* Copy prefix data. */
  119443. + memcpy(prefixData, PrefixData, gcdPREFIX_SIZE);
  119444. +
  119445. + /* Compute the data pointer. */
  119446. + data = prefixData + gcdPREFIX_SIZE;
  119447. +
  119448. + /* Copy argument value. */
  119449. + memcpy(data, Data, DataSize);
  119450. +
  119451. +#if gcdALIGNBYSIZE
  119452. + /* Compute the actual node size. */
  119453. + size
  119454. + = gcmSIZEOF(gcsBUFITEM_BUFFER)
  119455. + + gcdPREFIX_SIZE
  119456. + + alignment
  119457. + + DataSize;
  119458. +
  119459. + /* Free extra memory if any. */
  119460. + freeSize = allocSize - size;
  119461. + if (freeSize != 0)
  119462. + {
  119463. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  119464. + }
  119465. +#endif
  119466. +#else
  119467. + gcsBUFITEM_BUFFER_PTR item;
  119468. + gctINT size;
  119469. +
  119470. + gcmDBGASSERT(DataSize != 0, "%d", DataSize);
  119471. + gcmDBGASSERT(Data != gcvNULL, "%p", Data);
  119472. +
  119473. + /* Determine the maximum item size. */
  119474. + size = gcmSIZEOF(gcsBUFITEM_BUFFER) + DataSize;
  119475. +
  119476. + /* Allocate prefix item. */
  119477. + item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, size);
  119478. +
  119479. + /* Set item data. */
  119480. + item->type = gcvBUFITEM_BUFFER;
  119481. + item->indent = Indent;
  119482. + item->dataSize = DataSize;
  119483. + item->address = Address;
  119484. +
  119485. + /* Copy argument value. */
  119486. + memcpy(item + 1, Data, DataSize);
  119487. +#endif
  119488. +}
  119489. +#endif
  119490. +
  119491. +static gcmINLINE void
  119492. +_InitBuffers(
  119493. + void
  119494. + )
  119495. +{
  119496. + int i;
  119497. +
  119498. + if (_outputBufferHead == gcvNULL)
  119499. + {
  119500. + for (i = 0; i < gcdTHREAD_BUFFERS; i += 1)
  119501. + {
  119502. + if (_outputBufferTail == gcvNULL)
  119503. + {
  119504. + _outputBufferHead = &_outputBuffer[i];
  119505. + }
  119506. + else
  119507. + {
  119508. + _outputBufferTail->next = &_outputBuffer[i];
  119509. + }
  119510. +
  119511. +#if gcdTHREAD_BUFFERS > 1
  119512. + _outputBuffer[i].threadID = ~0U;
  119513. +#endif
  119514. +
  119515. + _outputBuffer[i].prev = _outputBufferTail;
  119516. + _outputBuffer[i].next = gcvNULL;
  119517. +
  119518. + _outputBufferTail = &_outputBuffer[i];
  119519. + }
  119520. + }
  119521. +}
  119522. +
  119523. +static gcmINLINE gcsBUFFERED_OUTPUT_PTR
  119524. +_GetOutputBuffer(
  119525. + void
  119526. + )
  119527. +{
  119528. + gcsBUFFERED_OUTPUT_PTR outputBuffer;
  119529. +
  119530. +#if gcdTHREAD_BUFFERS > 1
  119531. + /* Get the current thread ID. */
  119532. + gctUINT32 ThreadID = gcmkGETTHREADID();
  119533. +
  119534. + /* Locate the output buffer for the thread. */
  119535. + outputBuffer = _outputBufferHead;
  119536. +
  119537. + while (outputBuffer != gcvNULL)
  119538. + {
  119539. + if (outputBuffer->threadID == ThreadID)
  119540. + {
  119541. + break;
  119542. + }
  119543. +
  119544. + outputBuffer = outputBuffer->next;
  119545. + }
  119546. +
  119547. + /* No matching buffer found? */
  119548. + if (outputBuffer == gcvNULL)
  119549. + {
  119550. + /* Get the tail for the buffer. */
  119551. + outputBuffer = _outputBufferTail;
  119552. +
  119553. + /* Move it to the head. */
  119554. + _outputBufferTail = _outputBufferTail->prev;
  119555. + _outputBufferTail->next = gcvNULL;
  119556. +
  119557. + outputBuffer->prev = gcvNULL;
  119558. + outputBuffer->next = _outputBufferHead;
  119559. +
  119560. + _outputBufferHead->prev = outputBuffer;
  119561. + _outputBufferHead = outputBuffer;
  119562. +
  119563. + /* Reset the buffer. */
  119564. + outputBuffer->threadID = ThreadID;
  119565. +#if gcdBUFFERED_OUTPUT
  119566. + outputBuffer->start = 0;
  119567. + outputBuffer->index = 0;
  119568. + outputBuffer->count = 0;
  119569. +#endif
  119570. +#if gcdSHOW_LINE_NUMBER
  119571. + outputBuffer->lineNumber = 0;
  119572. +#endif
  119573. + }
  119574. +#else
  119575. + outputBuffer = _outputBufferHead;
  119576. +#endif
  119577. +
  119578. + return outputBuffer;
  119579. +}
  119580. +
  119581. +static gcmINLINE int _GetArgumentSize(
  119582. + IN gctCONST_STRING Message
  119583. + )
  119584. +{
  119585. + int i, count;
  119586. +
  119587. + gcmDBGASSERT(Message != gcvNULL, "%p", Message);
  119588. +
  119589. + for (i = 0, count = 0; Message[i]; i += 1)
  119590. + {
  119591. + if (Message[i] == '%')
  119592. + {
  119593. + count += 1;
  119594. + }
  119595. + }
  119596. +
  119597. + return count * gcmSIZEOF(gctUINT32);
  119598. +}
  119599. +
  119600. +#if gcdHAVEPREFIX
  119601. +static void
  119602. +_InitPrefixData(
  119603. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119604. + IN gctPOINTER Data
  119605. + )
  119606. +{
  119607. + gctUINT8_PTR data = (gctUINT8_PTR) Data;
  119608. +
  119609. +#if gcdSHOW_TIME
  119610. + {
  119611. + gctUINT64 time;
  119612. + gckOS_GetProfileTick(&time);
  119613. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
  119614. + * ((gctUINT64_PTR) data) = time;
  119615. + data += gcmSIZEOF(gctUINT64);
  119616. + }
  119617. +#endif
  119618. +
  119619. +#if gcdSHOW_LINE_NUMBER
  119620. + {
  119621. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
  119622. + * ((gctUINT64_PTR) data) = OutputBuffer->lineNumber;
  119623. + data += gcmSIZEOF(gctUINT64);
  119624. + }
  119625. +#endif
  119626. +
  119627. +#if gcdSHOW_PROCESS_ID
  119628. + {
  119629. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
  119630. + * ((gctUINT32_PTR) data) = gcmkGETPROCESSID();
  119631. + data += gcmSIZEOF(gctUINT32);
  119632. + }
  119633. +#endif
  119634. +
  119635. +#if gcdSHOW_THREAD_ID
  119636. + {
  119637. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
  119638. + * ((gctUINT32_PTR) data) = gcmkGETTHREADID();
  119639. + }
  119640. +#endif
  119641. +}
  119642. +#endif
  119643. +
  119644. +static void
  119645. +_Print(
  119646. + IN gctUINT ArgumentSize,
  119647. + IN gctBOOL CopyMessage,
  119648. + IN gctCONST_STRING Message,
  119649. + IN gctARGUMENTS Arguments
  119650. + )
  119651. +{
  119652. + gcsBUFFERED_OUTPUT_PTR outputBuffer;
  119653. + gcmkDECLARE_LOCK(lockHandle);
  119654. +
  119655. + gcmkLOCKSECTION(lockHandle);
  119656. +
  119657. + /* Initialize output buffer list. */
  119658. + _InitBuffers();
  119659. +
  119660. + /* Locate the proper output buffer. */
  119661. + outputBuffer = _GetOutputBuffer();
  119662. +
  119663. + /* Update the line number. */
  119664. +#if gcdSHOW_LINE_NUMBER
  119665. + outputBuffer->lineNumber += 1;
  119666. +#endif
  119667. +
  119668. + /* Print prefix. */
  119669. +#if gcdHAVEPREFIX
  119670. + {
  119671. + gctUINT8_PTR alignedPrefixData;
  119672. + gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
  119673. +
  119674. + /* Compute aligned pointer. */
  119675. + alignedPrefixData = prefixData;
  119676. + gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
  119677. +
  119678. + /* Initialize the prefix data. */
  119679. + _InitPrefixData(outputBuffer, alignedPrefixData);
  119680. +
  119681. + /* Print the prefix. */
  119682. + gcdOUTPUTPREFIX(outputBuffer, alignedPrefixData);
  119683. + }
  119684. +#endif
  119685. +
  119686. + /* Form the indent string. */
  119687. + if (strncmp(Message, "--", 2) == 0)
  119688. + {
  119689. + outputBuffer->indent -= 2;
  119690. + }
  119691. +
  119692. + /* Print the message. */
  119693. + if (CopyMessage)
  119694. + {
  119695. + gcdOUTPUTCOPY(
  119696. + outputBuffer, outputBuffer->indent,
  119697. + Message, ArgumentSize, * (gctPOINTER *) &Arguments
  119698. + );
  119699. + }
  119700. + else
  119701. + {
  119702. + gcdOUTPUTSTRING(
  119703. + outputBuffer, outputBuffer->indent,
  119704. + Message, ArgumentSize, * (gctPOINTER *) &Arguments
  119705. + );
  119706. + }
  119707. +
  119708. + /* Check increasing indent. */
  119709. + if (strncmp(Message, "++", 2) == 0)
  119710. + {
  119711. + outputBuffer->indent += 2;
  119712. + }
  119713. +
  119714. + gcmkUNLOCKSECTION(lockHandle);
  119715. +}
  119716. +
  119717. +
  119718. +/******************************************************************************\
  119719. +********************************* Debug Macros *********************************
  119720. +\******************************************************************************/
  119721. +
  119722. +#ifdef __QNXNTO__
  119723. +
  119724. +extern volatile unsigned g_nQnxInIsrs;
  119725. +
  119726. +#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
  119727. +{ \
  119728. + if (atomic_add_value(&g_nQnxInIsrs, 1) == 0) \
  119729. + { \
  119730. + gctARGUMENTS __arguments__; \
  119731. + gcmkARGUMENTS_START(__arguments__, Message); \
  119732. + _Print(ArgumentSize, CopyMessage, Message, __arguments__); \
  119733. + gcmkARGUMENTS_END(__arguments__); \
  119734. + } \
  119735. + atomic_sub(&g_nQnxInIsrs, 1); \
  119736. +}
  119737. +
  119738. +#else
  119739. +
  119740. +#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
  119741. +{ \
  119742. + gctARGUMENTS __arguments__; \
  119743. + gcmkARGUMENTS_START(__arguments__, Message); \
  119744. + _Print(ArgumentSize, CopyMessage, Message, __arguments__); \
  119745. + gcmkARGUMENTS_END(__arguments__); \
  119746. +}
  119747. +
  119748. +#endif
  119749. +
  119750. +/******************************************************************************\
  119751. +********************************** Debug Code **********************************
  119752. +\******************************************************************************/
  119753. +
  119754. +/*******************************************************************************
  119755. +**
  119756. +** gckOS_Print
  119757. +**
  119758. +** Send a message to the debugger.
  119759. +**
  119760. +** INPUT:
  119761. +**
  119762. +** gctCONST_STRING Message
  119763. +** Pointer to message.
  119764. +**
  119765. +** ...
  119766. +** Optional arguments.
  119767. +**
  119768. +** OUTPUT:
  119769. +**
  119770. +** Nothing.
  119771. +*/
  119772. +
  119773. +void
  119774. +gckOS_Print(
  119775. + IN gctCONST_STRING Message,
  119776. + ...
  119777. + )
  119778. +{
  119779. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  119780. +}
  119781. +
  119782. +/*******************************************************************************
  119783. +**
  119784. +** gckOS_PrintN
  119785. +**
  119786. +** Send a message to the debugger.
  119787. +**
  119788. +** INPUT:
  119789. +**
  119790. +** gctUINT ArgumentSize
  119791. +** The size of the optional arguments in bytes.
  119792. +**
  119793. +** gctCONST_STRING Message
  119794. +** Pointer to message.
  119795. +**
  119796. +** ...
  119797. +** Optional arguments.
  119798. +**
  119799. +** OUTPUT:
  119800. +**
  119801. +** Nothing.
  119802. +*/
  119803. +
  119804. +void
  119805. +gckOS_PrintN(
  119806. + IN gctUINT ArgumentSize,
  119807. + IN gctCONST_STRING Message,
  119808. + ...
  119809. + )
  119810. +{
  119811. + gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
  119812. +}
  119813. +
  119814. +/*******************************************************************************
  119815. +**
  119816. +** gckOS_CopyPrint
  119817. +**
  119818. +** Send a message to the debugger. If in buffered output mode, the entire
  119819. +** message will be copied into the buffer instead of using the pointer to
  119820. +** the string.
  119821. +**
  119822. +** INPUT:
  119823. +**
  119824. +** gctCONST_STRING Message
  119825. +** Pointer to message.
  119826. +**
  119827. +** ...
  119828. +** Optional arguments.
  119829. +**
  119830. +** OUTPUT:
  119831. +**
  119832. +** Nothing.
  119833. +*/
  119834. +
  119835. +void
  119836. +gckOS_CopyPrint(
  119837. + IN gctCONST_STRING Message,
  119838. + ...
  119839. + )
  119840. +{
  119841. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvTRUE, Message);
  119842. +}
  119843. +
  119844. +/*******************************************************************************
  119845. +**
  119846. +** gckOS_DumpBuffer
  119847. +**
  119848. +** Print the contents of the specified buffer.
  119849. +**
  119850. +** INPUT:
  119851. +**
  119852. +** gckOS Os
  119853. +** Pointer to gckOS object.
  119854. +**
  119855. +** gctPOINTER Buffer
  119856. +** Pointer to the buffer to print.
  119857. +**
  119858. +** gctUINT Size
  119859. +** Size of the buffer.
  119860. +**
  119861. +** gceDUMP_BUFFER Type
  119862. +** Buffer type.
  119863. +**
  119864. +** OUTPUT:
  119865. +**
  119866. +** Nothing.
  119867. +*/
  119868. +
  119869. +void
  119870. +gckOS_DumpBuffer(
  119871. + IN gckOS Os,
  119872. + IN gctPOINTER Buffer,
  119873. + IN gctUINT Size,
  119874. + IN gceDUMP_BUFFER Type,
  119875. + IN gctBOOL CopyMessage
  119876. + )
  119877. +{
  119878. + gctUINT32 address;
  119879. + gcsBUFFERED_OUTPUT_PTR outputBuffer;
  119880. + static gctBOOL userLocked;
  119881. + gctCHAR *buffer = (gctCHAR*)Buffer;
  119882. +
  119883. + gcmkDECLARE_LOCK(lockHandle);
  119884. +
  119885. + /* Request lock when not coming from user,
  119886. + or coming from user and not yet locked
  119887. + and message is starting with @[. */
  119888. + if (Type == gceDUMP_BUFFER_FROM_USER)
  119889. + {
  119890. + if ((Size > 2)
  119891. + && (buffer[0] == '@')
  119892. + && (buffer[1] == '['))
  119893. + {
  119894. + /* Beginning of a user dump. */
  119895. + gcmkLOCKSECTION(lockHandle);
  119896. + userLocked = gcvTRUE;
  119897. + }
  119898. + /* Else, let it pass through. */
  119899. + }
  119900. + else
  119901. + {
  119902. + gcmkLOCKSECTION(lockHandle);
  119903. + userLocked = gcvFALSE;
  119904. + }
  119905. +
  119906. + if (Buffer != gcvNULL)
  119907. + {
  119908. + /* Initialize output buffer list. */
  119909. + _InitBuffers();
  119910. +
  119911. + /* Locate the proper output buffer. */
  119912. + outputBuffer = _GetOutputBuffer();
  119913. +
  119914. + /* Update the line number. */
  119915. +#if gcdSHOW_LINE_NUMBER
  119916. + outputBuffer->lineNumber += 1;
  119917. +#endif
  119918. +
  119919. + /* Get the physical address of the buffer. */
  119920. + if (Type != gceDUMP_BUFFER_FROM_USER)
  119921. + {
  119922. + gcmkVERIFY_OK(gckOS_GetPhysicalAddress(Os, Buffer, &address));
  119923. + }
  119924. + else
  119925. + {
  119926. + address = 0;
  119927. + }
  119928. +
  119929. +#if gcdHAVEPREFIX
  119930. + {
  119931. + gctUINT8_PTR alignedPrefixData;
  119932. + gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
  119933. +
  119934. + /* Compute aligned pointer. */
  119935. + alignedPrefixData = prefixData;
  119936. + gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
  119937. +
  119938. + /* Initialize the prefix data. */
  119939. + _InitPrefixData(outputBuffer, alignedPrefixData);
  119940. +
  119941. + /* Print/schedule the buffer. */
  119942. + gcdOUTPUTBUFFER(
  119943. + outputBuffer, outputBuffer->indent,
  119944. + alignedPrefixData, Buffer, address, Size, Type, 0
  119945. + );
  119946. + }
  119947. +#else
  119948. + /* Print/schedule the buffer. */
  119949. + if (Type == gceDUMP_BUFFER_FROM_USER)
  119950. + {
  119951. + gcdOUTPUTSTRING(
  119952. + outputBuffer, outputBuffer->indent,
  119953. + Buffer, 0, gcvNULL
  119954. + );
  119955. + }
  119956. + else
  119957. + {
  119958. + gcdOUTPUTBUFFER(
  119959. + outputBuffer, outputBuffer->indent,
  119960. + gcvNULL, Buffer, address, Size, Type, 0
  119961. + );
  119962. + }
  119963. +#endif
  119964. + }
  119965. +
  119966. + /* Unlock when not coming from user,
  119967. + or coming from user and not yet locked. */
  119968. + if (userLocked)
  119969. + {
  119970. + if ((Size > 4)
  119971. + && (buffer[0] == ']')
  119972. + && (buffer[1] == ' ')
  119973. + && (buffer[2] == '-')
  119974. + && (buffer[3] == '-'))
  119975. + {
  119976. + /* End of a user dump. */
  119977. + gcmkUNLOCKSECTION(lockHandle);
  119978. + userLocked = gcvFALSE;
  119979. + }
  119980. + /* Else, let it pass through, don't unlock. */
  119981. + }
  119982. + else
  119983. + {
  119984. + gcmkUNLOCKSECTION(lockHandle);
  119985. + }
  119986. +}
  119987. +
  119988. +/*******************************************************************************
  119989. +**
  119990. +** gckOS_DebugTrace
  119991. +**
  119992. +** Send a leveled message to the debugger.
  119993. +**
  119994. +** INPUT:
  119995. +**
  119996. +** gctUINT32 Level
  119997. +** Debug level of message.
  119998. +**
  119999. +** gctCONST_STRING Message
  120000. +** Pointer to message.
  120001. +**
  120002. +** ...
  120003. +** Optional arguments.
  120004. +**
  120005. +** OUTPUT:
  120006. +**
  120007. +** Nothing.
  120008. +*/
  120009. +
  120010. +void
  120011. +gckOS_DebugTrace(
  120012. + IN gctUINT32 Level,
  120013. + IN gctCONST_STRING Message,
  120014. + ...
  120015. + )
  120016. +{
  120017. + if (Level > _debugLevel)
  120018. + {
  120019. + return;
  120020. + }
  120021. +
  120022. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  120023. +}
  120024. +
  120025. +/*******************************************************************************
  120026. +**
  120027. +** gckOS_DebugTraceN
  120028. +**
  120029. +** Send a leveled message to the debugger.
  120030. +**
  120031. +** INPUT:
  120032. +**
  120033. +** gctUINT32 Level
  120034. +** Debug level of message.
  120035. +**
  120036. +** gctUINT ArgumentSize
  120037. +** The size of the optional arguments in bytes.
  120038. +**
  120039. +** gctCONST_STRING Message
  120040. +** Pointer to message.
  120041. +**
  120042. +** ...
  120043. +** Optional arguments.
  120044. +**
  120045. +** OUTPUT:
  120046. +**
  120047. +** Nothing.
  120048. +*/
  120049. +
  120050. +void
  120051. +gckOS_DebugTraceN(
  120052. + IN gctUINT32 Level,
  120053. + IN gctUINT ArgumentSize,
  120054. + IN gctCONST_STRING Message,
  120055. + ...
  120056. + )
  120057. +{
  120058. + if (Level > _debugLevel)
  120059. + {
  120060. + return;
  120061. + }
  120062. +
  120063. + gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
  120064. +}
  120065. +
  120066. +/*******************************************************************************
  120067. +**
  120068. +** gckOS_DebugTraceZone
  120069. +**
  120070. +** Send a leveled and zoned message to the debugger.
  120071. +**
  120072. +** INPUT:
  120073. +**
  120074. +** gctUINT32 Level
  120075. +** Debug level for message.
  120076. +**
  120077. +** gctUINT32 Zone
  120078. +** Debug zone for message.
  120079. +**
  120080. +** gctCONST_STRING Message
  120081. +** Pointer to message.
  120082. +**
  120083. +** ...
  120084. +** Optional arguments.
  120085. +**
  120086. +** OUTPUT:
  120087. +**
  120088. +** Nothing.
  120089. +*/
  120090. +
  120091. +void
  120092. +gckOS_DebugTraceZone(
  120093. + IN gctUINT32 Level,
  120094. + IN gctUINT32 Zone,
  120095. + IN gctCONST_STRING Message,
  120096. + ...
  120097. + )
  120098. +{
  120099. + if ((Level > _debugLevel) || !(Zone & _debugZones))
  120100. + {
  120101. + return;
  120102. + }
  120103. +
  120104. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  120105. +}
  120106. +
  120107. +/*******************************************************************************
  120108. +**
  120109. +** gckOS_DebugTraceZoneN
  120110. +**
  120111. +** Send a leveled and zoned message to the debugger.
  120112. +**
  120113. +** INPUT:
  120114. +**
  120115. +** gctUINT32 Level
  120116. +** Debug level for message.
  120117. +**
  120118. +** gctUINT32 Zone
  120119. +** Debug zone for message.
  120120. +**
  120121. +** gctUINT ArgumentSize
  120122. +** The size of the optional arguments in bytes.
  120123. +**
  120124. +** gctCONST_STRING Message
  120125. +** Pointer to message.
  120126. +**
  120127. +** ...
  120128. +** Optional arguments.
  120129. +**
  120130. +** OUTPUT:
  120131. +**
  120132. +** Nothing.
  120133. +*/
  120134. +
  120135. +void
  120136. +gckOS_DebugTraceZoneN(
  120137. + IN gctUINT32 Level,
  120138. + IN gctUINT32 Zone,
  120139. + IN gctUINT ArgumentSize,
  120140. + IN gctCONST_STRING Message,
  120141. + ...
  120142. + )
  120143. +{
  120144. + if ((Level > _debugLevel) || !(Zone & _debugZones))
  120145. + {
  120146. + return;
  120147. + }
  120148. +
  120149. + gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
  120150. +}
  120151. +
  120152. +/*******************************************************************************
  120153. +**
  120154. +** gckOS_DebugBreak
  120155. +**
  120156. +** Break into the debugger.
  120157. +**
  120158. +** INPUT:
  120159. +**
  120160. +** Nothing.
  120161. +**
  120162. +** OUTPUT:
  120163. +**
  120164. +** Nothing.
  120165. +*/
  120166. +void
  120167. +gckOS_DebugBreak(
  120168. + void
  120169. + )
  120170. +{
  120171. + gckOS_DebugTrace(gcvLEVEL_ERROR, "%s(%d)", __FUNCTION__, __LINE__);
  120172. +}
  120173. +
  120174. +/*******************************************************************************
  120175. +**
  120176. +** gckOS_DebugFatal
  120177. +**
  120178. +** Send a message to the debugger and break into the debugger.
  120179. +**
  120180. +** INPUT:
  120181. +**
  120182. +** gctCONST_STRING Message
  120183. +** Pointer to message.
  120184. +**
  120185. +** ...
  120186. +** Optional arguments.
  120187. +**
  120188. +** OUTPUT:
  120189. +**
  120190. +** Nothing.
  120191. +*/
  120192. +void
  120193. +gckOS_DebugFatal(
  120194. + IN gctCONST_STRING Message,
  120195. + ...
  120196. + )
  120197. +{
  120198. + gcmkPRINT_VERSION();
  120199. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  120200. +
  120201. + /* Break into the debugger. */
  120202. + gckOS_DebugBreak();
  120203. +}
  120204. +
  120205. +/*******************************************************************************
  120206. +**
  120207. +** gckOS_SetDebugLevel
  120208. +**
  120209. +** Set the debug level.
  120210. +**
  120211. +** INPUT:
  120212. +**
  120213. +** gctUINT32 Level
  120214. +** New debug level.
  120215. +**
  120216. +** OUTPUT:
  120217. +**
  120218. +** Nothing.
  120219. +*/
  120220. +
  120221. +void
  120222. +gckOS_SetDebugLevel(
  120223. + IN gctUINT32 Level
  120224. + )
  120225. +{
  120226. + _debugLevel = Level;
  120227. +}
  120228. +
  120229. +/*******************************************************************************
  120230. +**
  120231. +** gckOS_SetDebugZone
  120232. +**
  120233. +** Set the debug zone.
  120234. +**
  120235. +** INPUT:
  120236. +**
  120237. +** gctUINT32 Zone
  120238. +** New debug zone.
  120239. +**
  120240. +** OUTPUT:
  120241. +**
  120242. +** Nothing.
  120243. +*/
  120244. +void
  120245. +gckOS_SetDebugZone(
  120246. + IN gctUINT32 Zone
  120247. + )
  120248. +{
  120249. + _debugZones = Zone;
  120250. +}
  120251. +
  120252. +/*******************************************************************************
  120253. +**
  120254. +** gckOS_SetDebugLevelZone
  120255. +**
  120256. +** Set the debug level and zone.
  120257. +**
  120258. +** INPUT:
  120259. +**
  120260. +** gctUINT32 Level
  120261. +** New debug level.
  120262. +**
  120263. +** gctUINT32 Zone
  120264. +** New debug zone.
  120265. +**
  120266. +** OUTPUT:
  120267. +**
  120268. +** Nothing.
  120269. +*/
  120270. +
  120271. +void
  120272. +gckOS_SetDebugLevelZone(
  120273. + IN gctUINT32 Level,
  120274. + IN gctUINT32 Zone
  120275. + )
  120276. +{
  120277. + _debugLevel = Level;
  120278. + _debugZones = Zone;
  120279. +}
  120280. +
  120281. +/*******************************************************************************
  120282. +**
  120283. +** gckOS_SetDebugZones
  120284. +**
  120285. +** Enable or disable debug zones.
  120286. +**
  120287. +** INPUT:
  120288. +**
  120289. +** gctUINT32 Zones
  120290. +** Debug zones to enable or disable.
  120291. +**
  120292. +** gctBOOL Enable
  120293. +** Set to gcvTRUE to enable the zones (or the Zones with the current
  120294. +** zones) or gcvFALSE to disable the specified Zones.
  120295. +**
  120296. +** OUTPUT:
  120297. +**
  120298. +** Nothing.
  120299. +*/
  120300. +
  120301. +void
  120302. +gckOS_SetDebugZones(
  120303. + IN gctUINT32 Zones,
  120304. + IN gctBOOL Enable
  120305. + )
  120306. +{
  120307. + if (Enable)
  120308. + {
  120309. + /* Enable the zones. */
  120310. + _debugZones |= Zones;
  120311. + }
  120312. + else
  120313. + {
  120314. + /* Disable the zones. */
  120315. + _debugZones &= ~Zones;
  120316. + }
  120317. +}
  120318. +
  120319. +/*******************************************************************************
  120320. +**
  120321. +** gckOS_Verify
  120322. +**
  120323. +** Called to verify the result of a function call.
  120324. +**
  120325. +** INPUT:
  120326. +**
  120327. +** gceSTATUS Status
  120328. +** Function call result.
  120329. +**
  120330. +** OUTPUT:
  120331. +**
  120332. +** Nothing.
  120333. +*/
  120334. +
  120335. +void
  120336. +gckOS_Verify(
  120337. + IN gceSTATUS status
  120338. + )
  120339. +{
  120340. + _lastError = status;
  120341. +}
  120342. +
  120343. +/*******************************************************************************
  120344. +**
  120345. +** gckOS_DebugFlush
  120346. +**
  120347. +** Force messages to be flushed out.
  120348. +**
  120349. +** INPUT:
  120350. +**
  120351. +** gctCONST_STRING CallerName
  120352. +** Name of the caller function.
  120353. +**
  120354. +** gctUINT LineNumber
  120355. +** Line number of the caller.
  120356. +**
  120357. +** gctUINT32 DmaAddress
  120358. +** The current DMA address or ~0U to ignore.
  120359. +**
  120360. +** OUTPUT:
  120361. +**
  120362. +** Nothing.
  120363. +*/
  120364. +
  120365. +void
  120366. +gckOS_DebugFlush(
  120367. + gctCONST_STRING CallerName,
  120368. + gctUINT LineNumber,
  120369. + gctUINT32 DmaAddress
  120370. + )
  120371. +{
  120372. +#if gcdBUFFERED_OUTPUT
  120373. + _DirectPrint("\nFlush requested by %s(%d).\n\n", CallerName, LineNumber);
  120374. + _Flush(DmaAddress);
  120375. +#endif
  120376. +}
  120377. +gctCONST_STRING
  120378. +gckOS_DebugStatus2Name(
  120379. + gceSTATUS status
  120380. + )
  120381. +{
  120382. + switch (status)
  120383. + {
  120384. + case gcvSTATUS_OK:
  120385. + return "gcvSTATUS_OK";
  120386. + case gcvSTATUS_TRUE:
  120387. + return "gcvSTATUS_TRUE";
  120388. + case gcvSTATUS_NO_MORE_DATA:
  120389. + return "gcvSTATUS_NO_MORE_DATA";
  120390. + case gcvSTATUS_CACHED:
  120391. + return "gcvSTATUS_CACHED";
  120392. + case gcvSTATUS_MIPMAP_TOO_LARGE:
  120393. + return "gcvSTATUS_MIPMAP_TOO_LARGE";
  120394. + case gcvSTATUS_NAME_NOT_FOUND:
  120395. + return "gcvSTATUS_NAME_NOT_FOUND";
  120396. + case gcvSTATUS_NOT_OUR_INTERRUPT:
  120397. + return "gcvSTATUS_NOT_OUR_INTERRUPT";
  120398. + case gcvSTATUS_MISMATCH:
  120399. + return "gcvSTATUS_MISMATCH";
  120400. + case gcvSTATUS_MIPMAP_TOO_SMALL:
  120401. + return "gcvSTATUS_MIPMAP_TOO_SMALL";
  120402. + case gcvSTATUS_LARGER:
  120403. + return "gcvSTATUS_LARGER";
  120404. + case gcvSTATUS_SMALLER:
  120405. + return "gcvSTATUS_SMALLER";
  120406. + case gcvSTATUS_CHIP_NOT_READY:
  120407. + return "gcvSTATUS_CHIP_NOT_READY";
  120408. + case gcvSTATUS_NEED_CONVERSION:
  120409. + return "gcvSTATUS_NEED_CONVERSION";
  120410. + case gcvSTATUS_SKIP:
  120411. + return "gcvSTATUS_SKIP";
  120412. + case gcvSTATUS_DATA_TOO_LARGE:
  120413. + return "gcvSTATUS_DATA_TOO_LARGE";
  120414. + case gcvSTATUS_INVALID_CONFIG:
  120415. + return "gcvSTATUS_INVALID_CONFIG";
  120416. + case gcvSTATUS_CHANGED:
  120417. + return "gcvSTATUS_CHANGED";
  120418. + case gcvSTATUS_NOT_SUPPORT_DITHER:
  120419. + return "gcvSTATUS_NOT_SUPPORT_DITHER";
  120420. +
  120421. + case gcvSTATUS_INVALID_ARGUMENT:
  120422. + return "gcvSTATUS_INVALID_ARGUMENT";
  120423. + case gcvSTATUS_INVALID_OBJECT:
  120424. + return "gcvSTATUS_INVALID_OBJECT";
  120425. + case gcvSTATUS_OUT_OF_MEMORY:
  120426. + return "gcvSTATUS_OUT_OF_MEMORY";
  120427. + case gcvSTATUS_MEMORY_LOCKED:
  120428. + return "gcvSTATUS_MEMORY_LOCKED";
  120429. + case gcvSTATUS_MEMORY_UNLOCKED:
  120430. + return "gcvSTATUS_MEMORY_UNLOCKED";
  120431. + case gcvSTATUS_HEAP_CORRUPTED:
  120432. + return "gcvSTATUS_HEAP_CORRUPTED";
  120433. + case gcvSTATUS_GENERIC_IO:
  120434. + return "gcvSTATUS_GENERIC_IO";
  120435. + case gcvSTATUS_INVALID_ADDRESS:
  120436. + return "gcvSTATUS_INVALID_ADDRESS";
  120437. + case gcvSTATUS_CONTEXT_LOSSED:
  120438. + return "gcvSTATUS_CONTEXT_LOSSED";
  120439. + case gcvSTATUS_TOO_COMPLEX:
  120440. + return "gcvSTATUS_TOO_COMPLEX";
  120441. + case gcvSTATUS_BUFFER_TOO_SMALL:
  120442. + return "gcvSTATUS_BUFFER_TOO_SMALL";
  120443. + case gcvSTATUS_INTERFACE_ERROR:
  120444. + return "gcvSTATUS_INTERFACE_ERROR";
  120445. + case gcvSTATUS_NOT_SUPPORTED:
  120446. + return "gcvSTATUS_NOT_SUPPORTED";
  120447. + case gcvSTATUS_MORE_DATA:
  120448. + return "gcvSTATUS_MORE_DATA";
  120449. + case gcvSTATUS_TIMEOUT:
  120450. + return "gcvSTATUS_TIMEOUT";
  120451. + case gcvSTATUS_OUT_OF_RESOURCES:
  120452. + return "gcvSTATUS_OUT_OF_RESOURCES";
  120453. + case gcvSTATUS_INVALID_DATA:
  120454. + return "gcvSTATUS_INVALID_DATA";
  120455. + case gcvSTATUS_INVALID_MIPMAP:
  120456. + return "gcvSTATUS_INVALID_MIPMAP";
  120457. + case gcvSTATUS_NOT_FOUND:
  120458. + return "gcvSTATUS_NOT_FOUND";
  120459. + case gcvSTATUS_NOT_ALIGNED:
  120460. + return "gcvSTATUS_NOT_ALIGNED";
  120461. + case gcvSTATUS_INVALID_REQUEST:
  120462. + return "gcvSTATUS_INVALID_REQUEST";
  120463. + case gcvSTATUS_GPU_NOT_RESPONDING:
  120464. + return "gcvSTATUS_GPU_NOT_RESPONDING";
  120465. + case gcvSTATUS_TIMER_OVERFLOW:
  120466. + return "gcvSTATUS_TIMER_OVERFLOW";
  120467. + case gcvSTATUS_VERSION_MISMATCH:
  120468. + return "gcvSTATUS_VERSION_MISMATCH";
  120469. + case gcvSTATUS_LOCKED:
  120470. + return "gcvSTATUS_LOCKED";
  120471. +
  120472. + /* Linker errors. */
  120473. + case gcvSTATUS_GLOBAL_TYPE_MISMATCH:
  120474. + return "gcvSTATUS_GLOBAL_TYPE_MISMATCH";
  120475. + case gcvSTATUS_TOO_MANY_ATTRIBUTES:
  120476. + return "gcvSTATUS_TOO_MANY_ATTRIBUTES";
  120477. + case gcvSTATUS_TOO_MANY_UNIFORMS:
  120478. + return "gcvSTATUS_TOO_MANY_UNIFORMS";
  120479. + case gcvSTATUS_TOO_MANY_VARYINGS:
  120480. + return "gcvSTATUS_TOO_MANY_VARYINGS";
  120481. + case gcvSTATUS_UNDECLARED_VARYING:
  120482. + return "gcvSTATUS_UNDECLARED_VARYING";
  120483. + case gcvSTATUS_VARYING_TYPE_MISMATCH:
  120484. + return "gcvSTATUS_VARYING_TYPE_MISMATCH";
  120485. + case gcvSTATUS_MISSING_MAIN:
  120486. + return "gcvSTATUS_MISSING_MAIN";
  120487. + case gcvSTATUS_NAME_MISMATCH:
  120488. + return "gcvSTATUS_NAME_MISMATCH";
  120489. + case gcvSTATUS_INVALID_INDEX:
  120490. + return "gcvSTATUS_INVALID_INDEX";
  120491. + default:
  120492. + return "nil";
  120493. + }
  120494. +}
  120495. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
  120496. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c 1970-01-01 01:00:00.000000000 +0100
  120497. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c 2014-08-20 19:31:46.132869024 +0200
  120498. @@ -0,0 +1,2898 @@
  120499. +/****************************************************************************
  120500. +*
  120501. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  120502. +*
  120503. +* This program is free software; you can redistribute it and/or modify
  120504. +* it under the terms of the GNU General Public License as published by
  120505. +* the Free Software Foundation; either version 2 of the license, or
  120506. +* (at your option) any later version.
  120507. +*
  120508. +* This program is distributed in the hope that it will be useful,
  120509. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  120510. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  120511. +* GNU General Public License for more details.
  120512. +*
  120513. +* You should have received a copy of the GNU General Public License
  120514. +* along with this program; if not write to the Free Software
  120515. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  120516. +*
  120517. +*****************************************************************************/
  120518. +
  120519. +
  120520. +#include "gc_hal_kernel_precomp.h"
  120521. +#include "gc_hal_kernel_buffer.h"
  120522. +
  120523. +#ifdef __QNXNTO__
  120524. +#include <atomic.h>
  120525. +#include "gc_hal_kernel_qnx.h"
  120526. +#endif
  120527. +
  120528. +#define _GC_OBJ_ZONE gcvZONE_EVENT
  120529. +
  120530. +#define gcdEVENT_ALLOCATION_COUNT (4096 / gcmSIZEOF(gcsHAL_INTERFACE))
  120531. +#define gcdEVENT_MIN_THRESHOLD 4
  120532. +
  120533. +/******************************************************************************\
  120534. +********************************* Support Code *********************************
  120535. +\******************************************************************************/
  120536. +
  120537. +static gceSTATUS
  120538. +gckEVENT_AllocateQueue(
  120539. + IN gckEVENT Event,
  120540. + OUT gcsEVENT_QUEUE_PTR * Queue
  120541. + )
  120542. +{
  120543. + gceSTATUS status;
  120544. +
  120545. + gcmkHEADER_ARG("Event=0x%x", Event);
  120546. +
  120547. + /* Verify the arguments. */
  120548. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  120549. + gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
  120550. +
  120551. + /* Do we have free queues? */
  120552. + if (Event->freeList == gcvNULL)
  120553. + {
  120554. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  120555. + }
  120556. +
  120557. + /* Move one free queue from the free list. */
  120558. + * Queue = Event->freeList;
  120559. + Event->freeList = Event->freeList->next;
  120560. +
  120561. + /* Success. */
  120562. + gcmkFOOTER_ARG("*Queue=0x%x", gcmOPT_POINTER(Queue));
  120563. + return gcvSTATUS_OK;
  120564. +
  120565. +OnError:
  120566. + /* Return the status. */
  120567. + gcmkFOOTER();
  120568. + return status;
  120569. +}
  120570. +
  120571. +static gceSTATUS
  120572. +gckEVENT_FreeQueue(
  120573. + IN gckEVENT Event,
  120574. + OUT gcsEVENT_QUEUE_PTR Queue
  120575. + )
  120576. +{
  120577. + gceSTATUS status = gcvSTATUS_OK;
  120578. +
  120579. + gcmkHEADER_ARG("Event=0x%x", Event);
  120580. +
  120581. + /* Verify the arguments. */
  120582. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  120583. + gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
  120584. +
  120585. + /* Move one free queue from the free list. */
  120586. + Queue->next = Event->freeList;
  120587. + Event->freeList = Queue;
  120588. +
  120589. + /* Success. */
  120590. + gcmkFOOTER();
  120591. + return status;
  120592. +}
  120593. +
  120594. +static gceSTATUS
  120595. +gckEVENT_FreeRecord(
  120596. + IN gckEVENT Event,
  120597. + IN gcsEVENT_PTR Record
  120598. + )
  120599. +{
  120600. + gceSTATUS status;
  120601. + gctBOOL acquired = gcvFALSE;
  120602. +
  120603. + gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
  120604. +
  120605. + /* Verify the arguments. */
  120606. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  120607. + gcmkVERIFY_ARGUMENT(Record != gcvNULL);
  120608. +
  120609. + /* Acquire the mutex. */
  120610. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  120611. + Event->freeEventMutex,
  120612. + gcvINFINITE));
  120613. + acquired = gcvTRUE;
  120614. +
  120615. + /* Push the record on the free list. */
  120616. + Record->next = Event->freeEventList;
  120617. + Event->freeEventList = Record;
  120618. + Event->freeEventCount += 1;
  120619. +
  120620. + /* Release the mutex. */
  120621. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  120622. +
  120623. + /* Success. */
  120624. + gcmkFOOTER_NO();
  120625. + return gcvSTATUS_OK;
  120626. +
  120627. +OnError:
  120628. + /* Roll back. */
  120629. + if (acquired)
  120630. + {
  120631. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  120632. + }
  120633. +
  120634. + /* Return the status. */
  120635. + gcmkFOOTER();
  120636. + return gcvSTATUS_OK;
  120637. +}
  120638. +
  120639. +static gceSTATUS
  120640. +gckEVENT_IsEmpty(
  120641. + IN gckEVENT Event,
  120642. + OUT gctBOOL_PTR IsEmpty
  120643. + )
  120644. +{
  120645. + gceSTATUS status;
  120646. + gctSIZE_T i;
  120647. +
  120648. + gcmkHEADER_ARG("Event=0x%x", Event);
  120649. +
  120650. + /* Verify the arguments. */
  120651. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  120652. + gcmkVERIFY_ARGUMENT(IsEmpty != gcvNULL);
  120653. +
  120654. + /* Assume the event queue is empty. */
  120655. + *IsEmpty = gcvTRUE;
  120656. +
  120657. + /* Try acquiring the mutex. */
  120658. + status = gckOS_AcquireMutex(Event->os, Event->eventQueueMutex, 0);
  120659. + if (status == gcvSTATUS_TIMEOUT)
  120660. + {
  120661. + /* Timeout - queue is no longer empty. */
  120662. + *IsEmpty = gcvFALSE;
  120663. + }
  120664. + else
  120665. + {
  120666. + /* Bail out on error. */
  120667. + gcmkONERROR(status);
  120668. +
  120669. + /* Walk the event queue. */
  120670. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  120671. + {
  120672. + /* Check whether this event is in use. */
  120673. + if (Event->queues[i].head != gcvNULL)
  120674. + {
  120675. + /* The event is in use, hence the queue is not empty. */
  120676. + *IsEmpty = gcvFALSE;
  120677. + break;
  120678. + }
  120679. + }
  120680. +
  120681. + /* Release the mutex. */
  120682. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  120683. + }
  120684. +
  120685. + /* Success. */
  120686. + gcmkFOOTER_ARG("*IsEmpty=%d", gcmOPT_VALUE(IsEmpty));
  120687. + return gcvSTATUS_OK;
  120688. +
  120689. +OnError:
  120690. + /* Return the status. */
  120691. + gcmkFOOTER();
  120692. + return status;
  120693. +}
  120694. +
  120695. +static gceSTATUS
  120696. +_TryToIdleGPU(
  120697. + IN gckEVENT Event
  120698. +)
  120699. +{
  120700. + gceSTATUS status;
  120701. + gctBOOL empty = gcvFALSE, idle = gcvFALSE;
  120702. + gctBOOL powerLocked = gcvFALSE;
  120703. + gckHARDWARE hardware;
  120704. +
  120705. + gcmkHEADER_ARG("Event=0x%x", Event);
  120706. +
  120707. + /* Verify the arguments. */
  120708. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  120709. +
  120710. + /* Grab gckHARDWARE object. */
  120711. + hardware = Event->kernel->hardware;
  120712. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  120713. +
  120714. + /* Check whether the event queue is empty. */
  120715. + gcmkONERROR(gckEVENT_IsEmpty(Event, &empty));
  120716. +
  120717. + if (empty)
  120718. + {
  120719. + status = gckOS_AcquireMutex(hardware->os, hardware->powerMutex, 0);
  120720. + if (status == gcvSTATUS_TIMEOUT)
  120721. + {
  120722. + gcmkFOOTER_NO();
  120723. + return gcvSTATUS_OK;
  120724. + }
  120725. +
  120726. + powerLocked = gcvTRUE;
  120727. +
  120728. + /* Query whether the hardware is idle. */
  120729. + gcmkONERROR(gckHARDWARE_QueryIdle(Event->kernel->hardware, &idle));
  120730. +
  120731. + gcmkONERROR(gckOS_ReleaseMutex(hardware->os, hardware->powerMutex));
  120732. + powerLocked = gcvFALSE;
  120733. +
  120734. + if (idle)
  120735. + {
  120736. + /* Inform the system of idle GPU. */
  120737. + gcmkONERROR(gckOS_Broadcast(Event->os,
  120738. + Event->kernel->hardware,
  120739. + gcvBROADCAST_GPU_IDLE));
  120740. + }
  120741. + }
  120742. +
  120743. + gcmkFOOTER_NO();
  120744. + return gcvSTATUS_OK;
  120745. +
  120746. +OnError:
  120747. + if (powerLocked)
  120748. + {
  120749. + gcmkONERROR(gckOS_ReleaseMutex(hardware->os, hardware->powerMutex));
  120750. + powerLocked = gcvFALSE;
  120751. + }
  120752. +
  120753. + gcmkFOOTER();
  120754. + return status;
  120755. +}
  120756. +
  120757. +static gceSTATUS
  120758. +__RemoveRecordFromProcessDB(
  120759. + IN gckEVENT Event,
  120760. + IN gcsEVENT_PTR Record
  120761. + )
  120762. +{
  120763. + gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
  120764. + gcmkVERIFY_ARGUMENT(Record != gcvNULL);
  120765. +
  120766. + while (Record != gcvNULL)
  120767. + {
  120768. + if (Record->info.command == gcvHAL_SIGNAL)
  120769. + {
  120770. + /* TODO: Find a better place to bind signal to hardware.*/
  120771. + gcmkVERIFY_OK(gckOS_SignalSetHardware(Event->os,
  120772. + gcmUINT64_TO_PTR(Record->info.u.Signal.signal),
  120773. + Event->kernel->hardware));
  120774. + }
  120775. +
  120776. + if (Record->fromKernel)
  120777. + {
  120778. + /* No need to check db if event is from kernel. */
  120779. + Record = Record->next;
  120780. + continue;
  120781. + }
  120782. +
  120783. + switch (Record->info.command)
  120784. + {
  120785. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  120786. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120787. + Event->kernel,
  120788. + Record->processID,
  120789. + gcvDB_NON_PAGED,
  120790. + gcmUINT64_TO_PTR(Record->info.u.FreeNonPagedMemory.logical)));
  120791. + break;
  120792. +
  120793. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  120794. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120795. + Event->kernel,
  120796. + Record->processID,
  120797. + gcvDB_CONTIGUOUS,
  120798. + gcmUINT64_TO_PTR(Record->info.u.FreeContiguousMemory.logical)));
  120799. + break;
  120800. +
  120801. + case gcvHAL_FREE_VIDEO_MEMORY:
  120802. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120803. + Event->kernel,
  120804. + Record->processID,
  120805. + gcvDB_VIDEO_MEMORY,
  120806. + gcmUINT64_TO_PTR(Record->info.u.FreeVideoMemory.node)));
  120807. +
  120808. + {
  120809. + gcuVIDMEM_NODE_PTR node = (gcuVIDMEM_NODE_PTR)(gcmUINT64_TO_PTR(Record->info.u.FreeVideoMemory.node));
  120810. +
  120811. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  120812. + {
  120813. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
  120814. + Record->processID,
  120815. + gcvDB_VIDEO_MEMORY_RESERVED,
  120816. + node));
  120817. + }
  120818. + else if(node->Virtual.contiguous)
  120819. + {
  120820. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
  120821. + Record->processID,
  120822. + gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  120823. + node));
  120824. + }
  120825. + else
  120826. + {
  120827. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
  120828. + Record->processID,
  120829. + gcvDB_VIDEO_MEMORY_VIRTUAL,
  120830. + node));
  120831. + }
  120832. + }
  120833. +
  120834. + break;
  120835. +
  120836. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  120837. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120838. + Event->kernel,
  120839. + Record->processID,
  120840. + gcvDB_VIDEO_MEMORY_LOCKED,
  120841. + gcmUINT64_TO_PTR(Record->info.u.UnlockVideoMemory.node)));
  120842. + break;
  120843. +
  120844. + case gcvHAL_UNMAP_USER_MEMORY:
  120845. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120846. + Event->kernel,
  120847. + Record->processID,
  120848. + gcvDB_MAP_USER_MEMORY,
  120849. + gcmINT2PTR(Record->info.u.UnmapUserMemory.info)));
  120850. + break;
  120851. +
  120852. + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
  120853. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120854. + Event->kernel,
  120855. + Record->processID,
  120856. + gcvDB_COMMAND_BUFFER,
  120857. + gcmUINT64_TO_PTR(Record->info.u.FreeVirtualCommandBuffer.logical)));
  120858. + break;
  120859. +
  120860. + default:
  120861. + break;
  120862. + }
  120863. +
  120864. + Record = Record->next;
  120865. + }
  120866. + gcmkFOOTER_NO();
  120867. + return gcvSTATUS_OK;
  120868. +}
  120869. +
  120870. +void
  120871. +_SubmitTimerFunction(
  120872. + gctPOINTER Data
  120873. + )
  120874. +{
  120875. + gckEVENT event = (gckEVENT)Data;
  120876. + gcmkVERIFY_OK(gckEVENT_Submit(event, gcvTRUE, gcvFALSE));
  120877. +}
  120878. +
  120879. +/******************************************************************************\
  120880. +******************************* gckEVENT API Code *******************************
  120881. +\******************************************************************************/
  120882. +
  120883. +/*******************************************************************************
  120884. +**
  120885. +** gckEVENT_Construct
  120886. +**
  120887. +** Construct a new gckEVENT object.
  120888. +**
  120889. +** INPUT:
  120890. +**
  120891. +** gckKERNEL Kernel
  120892. +** Pointer to an gckKERNEL object.
  120893. +**
  120894. +** OUTPUT:
  120895. +**
  120896. +** gckEVENT * Event
  120897. +** Pointer to a variable that receives the gckEVENT object pointer.
  120898. +*/
  120899. +gceSTATUS
  120900. +gckEVENT_Construct(
  120901. + IN gckKERNEL Kernel,
  120902. + OUT gckEVENT * Event
  120903. + )
  120904. +{
  120905. + gckOS os;
  120906. + gceSTATUS status;
  120907. + gckEVENT eventObj = gcvNULL;
  120908. + int i;
  120909. + gcsEVENT_PTR record;
  120910. + gctPOINTER pointer = gcvNULL;
  120911. +
  120912. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  120913. +
  120914. + /* Verify the arguments. */
  120915. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  120916. + gcmkVERIFY_ARGUMENT(Event != gcvNULL);
  120917. +
  120918. + /* Extract the pointer to the gckOS object. */
  120919. + os = Kernel->os;
  120920. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  120921. +
  120922. + /* Allocate the gckEVENT object. */
  120923. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckEVENT), &pointer));
  120924. +
  120925. + eventObj = pointer;
  120926. +
  120927. + /* Reset the object. */
  120928. + gcmkVERIFY_OK(gckOS_ZeroMemory(eventObj, gcmSIZEOF(struct _gckEVENT)));
  120929. +
  120930. + /* Initialize the gckEVENT object. */
  120931. + eventObj->object.type = gcvOBJ_EVENT;
  120932. + eventObj->kernel = Kernel;
  120933. + eventObj->os = os;
  120934. +
  120935. + /* Create the mutexes. */
  120936. + gcmkONERROR(gckOS_CreateMutex(os, &eventObj->eventQueueMutex));
  120937. + gcmkONERROR(gckOS_CreateMutex(os, &eventObj->freeEventMutex));
  120938. + gcmkONERROR(gckOS_CreateMutex(os, &eventObj->eventListMutex));
  120939. +
  120940. + /* Create a bunch of event reccords. */
  120941. + for (i = 0; i < gcdEVENT_ALLOCATION_COUNT; i += 1)
  120942. + {
  120943. + /* Allocate an event record. */
  120944. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsEVENT), &pointer));
  120945. +
  120946. + record = pointer;
  120947. +
  120948. + /* Push it on the free list. */
  120949. + record->next = eventObj->freeEventList;
  120950. + eventObj->freeEventList = record;
  120951. + eventObj->freeEventCount += 1;
  120952. + }
  120953. +
  120954. + /* Initialize the free list of event queues. */
  120955. + for (i = 0; i < gcdREPO_LIST_COUNT; i += 1)
  120956. + {
  120957. + eventObj->repoList[i].next = eventObj->freeList;
  120958. + eventObj->freeList = &eventObj->repoList[i];
  120959. + }
  120960. +
  120961. + /* Construct the atom. */
  120962. + gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->freeAtom));
  120963. + gcmkONERROR(gckOS_AtomSet(os,
  120964. + eventObj->freeAtom,
  120965. + gcmCOUNTOF(eventObj->queues)));
  120966. +
  120967. +#if gcdSMP
  120968. + gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pending));
  120969. +#endif
  120970. +
  120971. + gcmkVERIFY_OK(gckOS_CreateTimer(os,
  120972. + _SubmitTimerFunction,
  120973. + (gctPOINTER)eventObj,
  120974. + &eventObj->submitTimer));
  120975. +
  120976. + /* Return pointer to the gckEVENT object. */
  120977. + *Event = eventObj;
  120978. +
  120979. + /* Success. */
  120980. + gcmkFOOTER_ARG("*Event=0x%x", *Event);
  120981. + return gcvSTATUS_OK;
  120982. +
  120983. +OnError:
  120984. + /* Roll back. */
  120985. + if (eventObj != gcvNULL)
  120986. + {
  120987. + if (eventObj->eventQueueMutex != gcvNULL)
  120988. + {
  120989. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->eventQueueMutex));
  120990. + }
  120991. +
  120992. + if (eventObj->freeEventMutex != gcvNULL)
  120993. + {
  120994. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->freeEventMutex));
  120995. + }
  120996. +
  120997. + if (eventObj->eventListMutex != gcvNULL)
  120998. + {
  120999. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->eventListMutex));
  121000. + }
  121001. +
  121002. + while (eventObj->freeEventList != gcvNULL)
  121003. + {
  121004. + record = eventObj->freeEventList;
  121005. + eventObj->freeEventList = record->next;
  121006. +
  121007. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, record));
  121008. + }
  121009. +
  121010. + if (eventObj->freeAtom != gcvNULL)
  121011. + {
  121012. + gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->freeAtom));
  121013. + }
  121014. +
  121015. +#if gcdSMP
  121016. + if (eventObj->pending != gcvNULL)
  121017. + {
  121018. + gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->pending));
  121019. + }
  121020. +#endif
  121021. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, eventObj));
  121022. + }
  121023. +
  121024. + /* Return the status. */
  121025. + gcmkFOOTER();
  121026. + return status;
  121027. +}
  121028. +
  121029. +/*******************************************************************************
  121030. +**
  121031. +** gckEVENT_Destroy
  121032. +**
  121033. +** Destroy an gckEVENT object.
  121034. +**
  121035. +** INPUT:
  121036. +**
  121037. +** gckEVENT Event
  121038. +** Pointer to an gckEVENT object.
  121039. +**
  121040. +** OUTPUT:
  121041. +**
  121042. +** Nothing.
  121043. +*/
  121044. +gceSTATUS
  121045. +gckEVENT_Destroy(
  121046. + IN gckEVENT Event
  121047. + )
  121048. +{
  121049. + gcsEVENT_PTR record;
  121050. + gcsEVENT_QUEUE_PTR queue;
  121051. +
  121052. + gcmkHEADER_ARG("Event=0x%x", Event);
  121053. +
  121054. + /* Verify the arguments. */
  121055. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121056. +
  121057. + if (Event->submitTimer != gcvNULL)
  121058. + {
  121059. + gcmkVERIFY_OK(gckOS_StopTimer(Event->os, Event->submitTimer));
  121060. + gcmkVERIFY_OK(gckOS_DestroyTimer(Event->os, Event->submitTimer));
  121061. + }
  121062. +
  121063. + /* Delete the queue mutex. */
  121064. + gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->eventQueueMutex));
  121065. +
  121066. + /* Free all free events. */
  121067. + while (Event->freeEventList != gcvNULL)
  121068. + {
  121069. + record = Event->freeEventList;
  121070. + Event->freeEventList = record->next;
  121071. +
  121072. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, record));
  121073. + }
  121074. +
  121075. + /* Delete the free mutex. */
  121076. + gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->freeEventMutex));
  121077. +
  121078. + /* Free all pending queues. */
  121079. + while (Event->queueHead != gcvNULL)
  121080. + {
  121081. + /* Get the current queue. */
  121082. + queue = Event->queueHead;
  121083. +
  121084. + /* Free all pending events. */
  121085. + while (queue->head != gcvNULL)
  121086. + {
  121087. + record = queue->head;
  121088. + queue->head = record->next;
  121089. +
  121090. + gcmkTRACE_ZONE_N(
  121091. + gcvLEVEL_WARNING, gcvZONE_EVENT,
  121092. + gcmSIZEOF(record) + gcmSIZEOF(queue->source),
  121093. + "Event record 0x%x is still pending for %d.",
  121094. + record, queue->source
  121095. + );
  121096. +
  121097. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, record));
  121098. + }
  121099. +
  121100. + /* Remove the top queue from the list. */
  121101. + if (Event->queueHead == Event->queueTail)
  121102. + {
  121103. + Event->queueHead =
  121104. + Event->queueTail = gcvNULL;
  121105. + }
  121106. + else
  121107. + {
  121108. + Event->queueHead = Event->queueHead->next;
  121109. + }
  121110. +
  121111. + /* Free the queue. */
  121112. + gcmkVERIFY_OK(gckEVENT_FreeQueue(Event, queue));
  121113. + }
  121114. +
  121115. + /* Delete the list mutex. */
  121116. + gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->eventListMutex));
  121117. +
  121118. + /* Delete the atom. */
  121119. + gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->freeAtom));
  121120. +
  121121. +#if gcdSMP
  121122. + gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->pending));
  121123. +#endif
  121124. +
  121125. + /* Mark the gckEVENT object as unknown. */
  121126. + Event->object.type = gcvOBJ_UNKNOWN;
  121127. +
  121128. + /* Free the gckEVENT object. */
  121129. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, Event));
  121130. +
  121131. + /* Success. */
  121132. + gcmkFOOTER_NO();
  121133. + return gcvSTATUS_OK;
  121134. +}
  121135. +
  121136. +/*******************************************************************************
  121137. +**
  121138. +** gckEVENT_GetEvent
  121139. +**
  121140. +** Reserve the next available hardware event.
  121141. +**
  121142. +** INPUT:
  121143. +**
  121144. +** gckEVENT Event
  121145. +** Pointer to an gckEVENT object.
  121146. +**
  121147. +** gctBOOL Wait
  121148. +** Set to gcvTRUE to force the function to wait if no events are
  121149. +** immediately available.
  121150. +**
  121151. +** gceKERNEL_WHERE Source
  121152. +** Source of the event.
  121153. +**
  121154. +** OUTPUT:
  121155. +**
  121156. +** gctUINT8 * EventID
  121157. +** Reserved event ID.
  121158. +*/
  121159. +static gceSTATUS
  121160. +gckEVENT_GetEvent(
  121161. + IN gckEVENT Event,
  121162. + IN gctBOOL Wait,
  121163. + OUT gctUINT8 * EventID,
  121164. + IN gcsEVENT_PTR Head,
  121165. + IN gceKERNEL_WHERE Source
  121166. + )
  121167. +{
  121168. + gctINT i, id;
  121169. + gceSTATUS status;
  121170. + gctBOOL acquired = gcvFALSE;
  121171. + gctINT32 free;
  121172. +
  121173. +#if gcdGPU_TIMEOUT
  121174. + gctUINT32 timer = 0;
  121175. +#endif
  121176. +
  121177. + gcmkHEADER_ARG("Event=0x%x Head=%p Source=%d", Event, Head, Source);
  121178. +
  121179. + while (gcvTRUE)
  121180. + {
  121181. + /* Grab the queue mutex. */
  121182. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  121183. + Event->eventQueueMutex,
  121184. + gcvINFINITE));
  121185. + acquired = gcvTRUE;
  121186. +
  121187. + /* Walk through all events. */
  121188. + id = Event->lastID;
  121189. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  121190. + {
  121191. + gctINT nextID = gckMATH_ModuloInt((id + 1),
  121192. + gcmCOUNTOF(Event->queues));
  121193. +
  121194. + if (Event->queues[id].head == gcvNULL)
  121195. + {
  121196. + *EventID = (gctUINT8) id;
  121197. +
  121198. + Event->lastID = (gctUINT8) nextID;
  121199. +
  121200. + /* Save time stamp of event. */
  121201. + Event->queues[id].stamp = ++(Event->stamp);
  121202. + Event->queues[id].head = Head;
  121203. + Event->queues[id].source = Source;
  121204. +
  121205. + gcmkONERROR(gckOS_AtomDecrement(Event->os,
  121206. + Event->freeAtom,
  121207. + &free));
  121208. +#if gcdDYNAMIC_SPEED
  121209. + if (free <= gcdDYNAMIC_EVENT_THRESHOLD)
  121210. + {
  121211. + gcmkONERROR(gckOS_BroadcastHurry(
  121212. + Event->os,
  121213. + Event->kernel->hardware,
  121214. + gcdDYNAMIC_EVENT_THRESHOLD - free));
  121215. + }
  121216. +#endif
  121217. +
  121218. + /* Release the queue mutex. */
  121219. + gcmkONERROR(gckOS_ReleaseMutex(Event->os,
  121220. + Event->eventQueueMutex));
  121221. +
  121222. + /* Success. */
  121223. + gcmkTRACE_ZONE_N(
  121224. + gcvLEVEL_INFO, gcvZONE_EVENT,
  121225. + gcmSIZEOF(id),
  121226. + "Using id=%d",
  121227. + id
  121228. + );
  121229. +
  121230. + gcmkFOOTER_ARG("*EventID=%u", *EventID);
  121231. + return gcvSTATUS_OK;
  121232. + }
  121233. +
  121234. + id = nextID;
  121235. + }
  121236. +
  121237. +#if gcdDYNAMIC_SPEED
  121238. + /* No free events, speed up the GPU right now! */
  121239. + gcmkONERROR(gckOS_BroadcastHurry(Event->os,
  121240. + Event->kernel->hardware,
  121241. + gcdDYNAMIC_EVENT_THRESHOLD));
  121242. +#endif
  121243. +
  121244. + /* Release the queue mutex. */
  121245. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  121246. + acquired = gcvFALSE;
  121247. +
  121248. + /* Fail if wait is not requested. */
  121249. + if (!Wait)
  121250. + {
  121251. + /* Out of resources. */
  121252. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  121253. + }
  121254. +
  121255. + /* Delay a while. */
  121256. + gcmkONERROR(gckOS_Delay(Event->os, 1));
  121257. +
  121258. +#if gcdGPU_TIMEOUT
  121259. + /* Increment the wait timer. */
  121260. + timer += 1;
  121261. +
  121262. + if (timer == Event->kernel->timeOut)
  121263. + {
  121264. + /* Try to call any outstanding events. */
  121265. + gcmkONERROR(gckHARDWARE_Interrupt(Event->kernel->hardware,
  121266. + gcvTRUE));
  121267. + }
  121268. + else if (timer > Event->kernel->timeOut)
  121269. + {
  121270. + gcmkTRACE_N(
  121271. + gcvLEVEL_ERROR,
  121272. + gcmSIZEOF(gctCONST_STRING) + gcmSIZEOF(gctINT),
  121273. + "%s(%d): no available events\n",
  121274. + __FUNCTION__, __LINE__
  121275. + );
  121276. +
  121277. + /* Bail out. */
  121278. + gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
  121279. + }
  121280. +#endif
  121281. + }
  121282. +
  121283. +OnError:
  121284. + if (acquired)
  121285. + {
  121286. + /* Release the queue mutex. */
  121287. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  121288. + }
  121289. +
  121290. + /* Return the status. */
  121291. + gcmkFOOTER();
  121292. + return status;
  121293. +}
  121294. +
  121295. +/*******************************************************************************
  121296. +**
  121297. +** gckEVENT_AllocateRecord
  121298. +**
  121299. +** Allocate a record for the new event.
  121300. +**
  121301. +** INPUT:
  121302. +**
  121303. +** gckEVENT Event
  121304. +** Pointer to an gckEVENT object.
  121305. +**
  121306. +** gctBOOL AllocateAllowed
  121307. +** State for allocation if out of free events.
  121308. +**
  121309. +** OUTPUT:
  121310. +**
  121311. +** gcsEVENT_PTR * Record
  121312. +** Allocated event record.
  121313. +*/
  121314. +gceSTATUS
  121315. +gckEVENT_AllocateRecord(
  121316. + IN gckEVENT Event,
  121317. + IN gctBOOL AllocateAllowed,
  121318. + OUT gcsEVENT_PTR * Record
  121319. + )
  121320. +{
  121321. + gceSTATUS status;
  121322. + gctBOOL acquired = gcvFALSE;
  121323. + gctINT i;
  121324. + gcsEVENT_PTR record;
  121325. + gctPOINTER pointer = gcvNULL;
  121326. +
  121327. + gcmkHEADER_ARG("Event=0x%x AllocateAllowed=%d", Event, AllocateAllowed);
  121328. +
  121329. + /* Verify the arguments. */
  121330. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121331. + gcmkVERIFY_ARGUMENT(Record != gcvNULL);
  121332. +
  121333. + /* Acquire the mutex. */
  121334. + gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->freeEventMutex, gcvINFINITE));
  121335. + acquired = gcvTRUE;
  121336. +
  121337. + /* Test if we are below the allocation threshold. */
  121338. + if ( (AllocateAllowed && (Event->freeEventCount < gcdEVENT_MIN_THRESHOLD)) ||
  121339. + (Event->freeEventCount == 0) )
  121340. + {
  121341. + /* Allocate a bunch of records. */
  121342. + for (i = 0; i < gcdEVENT_ALLOCATION_COUNT; i += 1)
  121343. + {
  121344. + /* Allocate an event record. */
  121345. + gcmkONERROR(gckOS_Allocate(Event->os,
  121346. + gcmSIZEOF(gcsEVENT),
  121347. + &pointer));
  121348. +
  121349. + record = pointer;
  121350. +
  121351. + /* Push it on the free list. */
  121352. + record->next = Event->freeEventList;
  121353. + Event->freeEventList = record;
  121354. + Event->freeEventCount += 1;
  121355. + }
  121356. + }
  121357. +
  121358. + *Record = Event->freeEventList;
  121359. + Event->freeEventList = Event->freeEventList->next;
  121360. + Event->freeEventCount -= 1;
  121361. +
  121362. + /* Release the mutex. */
  121363. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  121364. + acquired = gcvFALSE;
  121365. +
  121366. + /* Success. */
  121367. + gcmkFOOTER_ARG("*Record=0x%x", gcmOPT_POINTER(Record));
  121368. + return gcvSTATUS_OK;
  121369. +
  121370. +OnError:
  121371. + /* Roll back. */
  121372. + if (acquired)
  121373. + {
  121374. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  121375. + }
  121376. +
  121377. + /* Return the status. */
  121378. + gcmkFOOTER();
  121379. + return status;
  121380. +}
  121381. +
  121382. +/*******************************************************************************
  121383. +**
  121384. +** gckEVENT_AddList
  121385. +**
  121386. +** Add a new event to the list of events.
  121387. +**
  121388. +** INPUT:
  121389. +**
  121390. +** gckEVENT Event
  121391. +** Pointer to an gckEVENT object.
  121392. +**
  121393. +** gcsHAL_INTERFACE_PTR Interface
  121394. +** Pointer to the interface for the event to be added.
  121395. +**
  121396. +** gceKERNEL_WHERE FromWhere
  121397. +** Place in the pipe where the event needs to be generated.
  121398. +**
  121399. +** gctBOOL AllocateAllowed
  121400. +** State for allocation if out of free events.
  121401. +**
  121402. +** OUTPUT:
  121403. +**
  121404. +** Nothing.
  121405. +*/
  121406. +gceSTATUS
  121407. +gckEVENT_AddList(
  121408. + IN gckEVENT Event,
  121409. + IN gcsHAL_INTERFACE_PTR Interface,
  121410. + IN gceKERNEL_WHERE FromWhere,
  121411. + IN gctBOOL AllocateAllowed,
  121412. + IN gctBOOL FromKernel
  121413. + )
  121414. +{
  121415. + gceSTATUS status;
  121416. + gctBOOL acquired = gcvFALSE;
  121417. + gcsEVENT_PTR record = gcvNULL;
  121418. + gcsEVENT_QUEUE_PTR queue;
  121419. + gckKERNEL kernel = Event->kernel;
  121420. +
  121421. + gcmkHEADER_ARG("Event=0x%x Interface=0x%x",
  121422. + Event, Interface);
  121423. +
  121424. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, _GC_OBJ_ZONE,
  121425. + "FromWhere=%d AllocateAllowed=%d",
  121426. + FromWhere, AllocateAllowed);
  121427. +
  121428. + /* Verify the arguments. */
  121429. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121430. + gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
  121431. +
  121432. + /* Verify the event command. */
  121433. + gcmkASSERT
  121434. + ( (Interface->command == gcvHAL_FREE_NON_PAGED_MEMORY)
  121435. + || (Interface->command == gcvHAL_FREE_CONTIGUOUS_MEMORY)
  121436. + || (Interface->command == gcvHAL_FREE_VIDEO_MEMORY)
  121437. + || (Interface->command == gcvHAL_WRITE_DATA)
  121438. + || (Interface->command == gcvHAL_UNLOCK_VIDEO_MEMORY)
  121439. + || (Interface->command == gcvHAL_SIGNAL)
  121440. + || (Interface->command == gcvHAL_UNMAP_USER_MEMORY)
  121441. + || (Interface->command == gcvHAL_TIMESTAMP)
  121442. + || (Interface->command == gcvHAL_COMMIT_DONE)
  121443. + || (Interface->command == gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER)
  121444. + || (Interface->command == gcvHAL_SYNC_POINT)
  121445. + );
  121446. +
  121447. + /* Validate the source. */
  121448. + if ((FromWhere != gcvKERNEL_COMMAND) && (FromWhere != gcvKERNEL_PIXEL))
  121449. + {
  121450. + /* Invalid argument. */
  121451. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  121452. + }
  121453. +
  121454. + /* Allocate a free record. */
  121455. + gcmkONERROR(gckEVENT_AllocateRecord(Event, AllocateAllowed, &record));
  121456. +
  121457. + /* Termninate the record. */
  121458. + record->next = gcvNULL;
  121459. +
  121460. + /* Record the committer. */
  121461. + record->fromKernel = FromKernel;
  121462. +
  121463. + /* Copy the event interface into the record. */
  121464. + gckOS_MemCopy(&record->info, Interface, gcmSIZEOF(record->info));
  121465. +
  121466. + /* Get process ID. */
  121467. + gcmkONERROR(gckOS_GetProcessID(&record->processID));
  121468. +
  121469. +#ifdef __QNXNTO__
  121470. + record->kernel = Event->kernel;
  121471. +#endif
  121472. +
  121473. + gcmkONERROR(__RemoveRecordFromProcessDB(Event, record));
  121474. +
  121475. + /* Acquire the mutex. */
  121476. + gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->eventListMutex, gcvINFINITE));
  121477. + acquired = gcvTRUE;
  121478. +
  121479. + /* Do we need to allocate a new queue? */
  121480. + if ((Event->queueTail == gcvNULL) || (Event->queueTail->source < FromWhere))
  121481. + {
  121482. + /* Allocate a new queue. */
  121483. + gcmkONERROR(gckEVENT_AllocateQueue(Event, &queue));
  121484. +
  121485. + /* Initialize the queue. */
  121486. + queue->source = FromWhere;
  121487. + queue->head = gcvNULL;
  121488. + queue->next = gcvNULL;
  121489. +
  121490. + /* Attach it to the list of allocated queues. */
  121491. + if (Event->queueTail == gcvNULL)
  121492. + {
  121493. + Event->queueHead =
  121494. + Event->queueTail = queue;
  121495. + }
  121496. + else
  121497. + {
  121498. + Event->queueTail->next = queue;
  121499. + Event->queueTail = queue;
  121500. + }
  121501. + }
  121502. + else
  121503. + {
  121504. + queue = Event->queueTail;
  121505. + }
  121506. +
  121507. + /* Attach the record to the queue. */
  121508. + if (queue->head == gcvNULL)
  121509. + {
  121510. + queue->head = record;
  121511. + queue->tail = record;
  121512. + }
  121513. + else
  121514. + {
  121515. + queue->tail->next = record;
  121516. + queue->tail = record;
  121517. + }
  121518. +
  121519. + /* Unmap user space logical address.
  121520. + * Linux kernel does not support unmap the memory of other process any more since 3.5.
  121521. + * Let's unmap memory of self process before submit the event to gpu.
  121522. + * */
  121523. + switch(Interface->command)
  121524. + {
  121525. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  121526. + gcmkONERROR(gckOS_UnmapUserLogical(
  121527. + Event->os,
  121528. + gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical),
  121529. + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
  121530. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  121531. + break;
  121532. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  121533. + gcmkONERROR(gckOS_UnmapUserLogical(
  121534. + Event->os,
  121535. + gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical),
  121536. + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
  121537. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
  121538. + break;
  121539. + default:
  121540. + break;
  121541. + }
  121542. +
  121543. +
  121544. + /* Release the mutex. */
  121545. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  121546. +
  121547. + /* Success. */
  121548. + gcmkFOOTER_NO();
  121549. + return gcvSTATUS_OK;
  121550. +
  121551. +OnError:
  121552. + /* Roll back. */
  121553. + if (acquired)
  121554. + {
  121555. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  121556. + }
  121557. +
  121558. + if (record != gcvNULL)
  121559. + {
  121560. + gcmkVERIFY_OK(gckEVENT_FreeRecord(Event, record));
  121561. + }
  121562. +
  121563. + /* Return the status. */
  121564. + gcmkFOOTER();
  121565. + return status;
  121566. +}
  121567. +
  121568. +/*******************************************************************************
  121569. +**
  121570. +** gckEVENT_Unlock
  121571. +**
  121572. +** Schedule an event to unlock virtual memory.
  121573. +**
  121574. +** INPUT:
  121575. +**
  121576. +** gckEVENT Event
  121577. +** Pointer to an gckEVENT object.
  121578. +**
  121579. +** gceKERNEL_WHERE FromWhere
  121580. +** Place in the pipe where the event needs to be generated.
  121581. +**
  121582. +** gcuVIDMEM_NODE_PTR Node
  121583. +** Pointer to a gcuVIDMEM_NODE union that specifies the virtual memory
  121584. +** to unlock.
  121585. +**
  121586. +** gceSURF_TYPE Type
  121587. +** Type of surface to unlock.
  121588. +**
  121589. +** OUTPUT:
  121590. +**
  121591. +** Nothing.
  121592. +*/
  121593. +gceSTATUS
  121594. +gckEVENT_Unlock(
  121595. + IN gckEVENT Event,
  121596. + IN gceKERNEL_WHERE FromWhere,
  121597. + IN gcuVIDMEM_NODE_PTR Node,
  121598. + IN gceSURF_TYPE Type
  121599. + )
  121600. +{
  121601. + gceSTATUS status;
  121602. + gcsHAL_INTERFACE iface;
  121603. +
  121604. + gcmkHEADER_ARG("Event=0x%x FromWhere=%d Node=0x%x Type=%d",
  121605. + Event, FromWhere, Node, Type);
  121606. +
  121607. + /* Verify the arguments. */
  121608. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121609. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  121610. +
  121611. + /* Mark the event as an unlock. */
  121612. + iface.command = gcvHAL_UNLOCK_VIDEO_MEMORY;
  121613. + iface.u.UnlockVideoMemory.node = gcmPTR_TO_UINT64(Node);
  121614. + iface.u.UnlockVideoMemory.type = Type;
  121615. + iface.u.UnlockVideoMemory.asynchroneous = 0;
  121616. +
  121617. + /* Append it to the queue. */
  121618. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121619. +
  121620. + /* Success. */
  121621. + gcmkFOOTER_NO();
  121622. + return gcvSTATUS_OK;
  121623. +
  121624. +OnError:
  121625. + /* Return the status. */
  121626. + gcmkFOOTER();
  121627. + return status;
  121628. +}
  121629. +
  121630. +/*******************************************************************************
  121631. +**
  121632. +** gckEVENT_FreeVideoMemory
  121633. +**
  121634. +** Schedule an event to free video memory.
  121635. +**
  121636. +** INPUT:
  121637. +**
  121638. +** gckEVENT Event
  121639. +** Pointer to an gckEVENT object.
  121640. +**
  121641. +** gcuVIDMEM_NODE_PTR VideoMemory
  121642. +** Pointer to a gcuVIDMEM_NODE object to free.
  121643. +**
  121644. +** gceKERNEL_WHERE FromWhere
  121645. +** Place in the pipe where the event needs to be generated.
  121646. +**
  121647. +** OUTPUT:
  121648. +**
  121649. +** Nothing.
  121650. +*/
  121651. +gceSTATUS
  121652. +gckEVENT_FreeVideoMemory(
  121653. + IN gckEVENT Event,
  121654. + IN gcuVIDMEM_NODE_PTR VideoMemory,
  121655. + IN gceKERNEL_WHERE FromWhere
  121656. + )
  121657. +{
  121658. + gceSTATUS status;
  121659. + gcsHAL_INTERFACE iface;
  121660. +
  121661. + gcmkHEADER_ARG("Event=0x%x VideoMemory=0x%x FromWhere=%d",
  121662. + Event, VideoMemory, FromWhere);
  121663. +
  121664. + /* Verify the arguments. */
  121665. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121666. + gcmkVERIFY_ARGUMENT(VideoMemory != gcvNULL);
  121667. +
  121668. + /* Create an event. */
  121669. + iface.command = gcvHAL_FREE_VIDEO_MEMORY;
  121670. + iface.u.FreeVideoMemory.node = gcmPTR_TO_UINT64(VideoMemory);
  121671. +
  121672. + /* Append it to the queue. */
  121673. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121674. +
  121675. + /* Success. */
  121676. + gcmkFOOTER_NO();
  121677. + return gcvSTATUS_OK;
  121678. +
  121679. +OnError:
  121680. + /* Return the status. */
  121681. + gcmkFOOTER();
  121682. + return status;
  121683. +}
  121684. +
  121685. +/*******************************************************************************
  121686. +**
  121687. +** gckEVENT_FreeNonPagedMemory
  121688. +**
  121689. +** Schedule an event to free non-paged memory.
  121690. +**
  121691. +** INPUT:
  121692. +**
  121693. +** gckEVENT Event
  121694. +** Pointer to an gckEVENT object.
  121695. +**
  121696. +** gctSIZE_T Bytes
  121697. +** Number of bytes of non-paged memory to free.
  121698. +**
  121699. +** gctPHYS_ADDR Physical
  121700. +** Physical address of non-paged memory to free.
  121701. +**
  121702. +** gctPOINTER Logical
  121703. +** Logical address of non-paged memory to free.
  121704. +**
  121705. +** gceKERNEL_WHERE FromWhere
  121706. +** Place in the pipe where the event needs to be generated.
  121707. +*/
  121708. +gceSTATUS
  121709. +gckEVENT_FreeNonPagedMemory(
  121710. + IN gckEVENT Event,
  121711. + IN gctSIZE_T Bytes,
  121712. + IN gctPHYS_ADDR Physical,
  121713. + IN gctPOINTER Logical,
  121714. + IN gceKERNEL_WHERE FromWhere
  121715. + )
  121716. +{
  121717. + gceSTATUS status;
  121718. + gcsHAL_INTERFACE iface;
  121719. + gckKERNEL kernel = Event->kernel;
  121720. +
  121721. + gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
  121722. + "FromWhere=%d",
  121723. + Event, Bytes, Physical, Logical, FromWhere);
  121724. +
  121725. + /* Verify the arguments. */
  121726. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121727. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  121728. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  121729. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  121730. +
  121731. + /* Create an event. */
  121732. + iface.command = gcvHAL_FREE_NON_PAGED_MEMORY;
  121733. + iface.u.FreeNonPagedMemory.bytes = Bytes;
  121734. + iface.u.FreeNonPagedMemory.physical = gcmPTR_TO_NAME(Physical);
  121735. + iface.u.FreeNonPagedMemory.logical = gcmPTR_TO_UINT64(Logical);
  121736. +
  121737. + /* Append it to the queue. */
  121738. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121739. +
  121740. + /* Success. */
  121741. + gcmkFOOTER_NO();
  121742. + return gcvSTATUS_OK;
  121743. +
  121744. +OnError:
  121745. + /* Return the status. */
  121746. + gcmkFOOTER();
  121747. + return status;
  121748. +}
  121749. +
  121750. +gceSTATUS
  121751. +gckEVENT_DestroyVirtualCommandBuffer(
  121752. + IN gckEVENT Event,
  121753. + IN gctSIZE_T Bytes,
  121754. + IN gctPHYS_ADDR Physical,
  121755. + IN gctPOINTER Logical,
  121756. + IN gceKERNEL_WHERE FromWhere
  121757. + )
  121758. +{
  121759. + gceSTATUS status;
  121760. + gcsHAL_INTERFACE iface;
  121761. + gckKERNEL kernel = Event->kernel;
  121762. +
  121763. + gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
  121764. + "FromWhere=%d",
  121765. + Event, Bytes, Physical, Logical, FromWhere);
  121766. +
  121767. + /* Verify the arguments. */
  121768. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121769. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  121770. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  121771. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  121772. +
  121773. + /* Create an event. */
  121774. + iface.command = gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER;
  121775. + iface.u.FreeVirtualCommandBuffer.bytes = Bytes;
  121776. + iface.u.FreeVirtualCommandBuffer.physical = gcmPTR_TO_NAME(Physical);
  121777. + iface.u.FreeVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(Logical);
  121778. +
  121779. + /* Append it to the queue. */
  121780. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121781. +
  121782. + /* Success. */
  121783. + gcmkFOOTER_NO();
  121784. + return gcvSTATUS_OK;
  121785. +
  121786. +OnError:
  121787. + /* Return the status. */
  121788. + gcmkFOOTER();
  121789. + return status;
  121790. +}
  121791. +
  121792. +/*******************************************************************************
  121793. +**
  121794. +** gckEVENT_FreeContigiuousMemory
  121795. +**
  121796. +** Schedule an event to free contiguous memory.
  121797. +**
  121798. +** INPUT:
  121799. +**
  121800. +** gckEVENT Event
  121801. +** Pointer to an gckEVENT object.
  121802. +**
  121803. +** gctSIZE_T Bytes
  121804. +** Number of bytes of contiguous memory to free.
  121805. +**
  121806. +** gctPHYS_ADDR Physical
  121807. +** Physical address of contiguous memory to free.
  121808. +**
  121809. +** gctPOINTER Logical
  121810. +** Logical address of contiguous memory to free.
  121811. +**
  121812. +** gceKERNEL_WHERE FromWhere
  121813. +** Place in the pipe where the event needs to be generated.
  121814. +*/
  121815. +gceSTATUS
  121816. +gckEVENT_FreeContiguousMemory(
  121817. + IN gckEVENT Event,
  121818. + IN gctSIZE_T Bytes,
  121819. + IN gctPHYS_ADDR Physical,
  121820. + IN gctPOINTER Logical,
  121821. + IN gceKERNEL_WHERE FromWhere
  121822. + )
  121823. +{
  121824. + gceSTATUS status;
  121825. + gcsHAL_INTERFACE iface;
  121826. + gckKERNEL kernel = Event->kernel;
  121827. +
  121828. + gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
  121829. + "FromWhere=%d",
  121830. + Event, Bytes, Physical, Logical, FromWhere);
  121831. +
  121832. + /* Verify the arguments. */
  121833. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121834. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  121835. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  121836. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  121837. +
  121838. + /* Create an event. */
  121839. + iface.command = gcvHAL_FREE_CONTIGUOUS_MEMORY;
  121840. + iface.u.FreeContiguousMemory.bytes = Bytes;
  121841. + iface.u.FreeContiguousMemory.physical = gcmPTR_TO_NAME(Physical);
  121842. + iface.u.FreeContiguousMemory.logical = gcmPTR_TO_UINT64(Logical);
  121843. +
  121844. + /* Append it to the queue. */
  121845. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121846. +
  121847. + /* Success. */
  121848. + gcmkFOOTER_NO();
  121849. + return gcvSTATUS_OK;
  121850. +
  121851. +OnError:
  121852. + /* Return the status. */
  121853. + gcmkFOOTER();
  121854. + return status;
  121855. +}
  121856. +
  121857. +/*******************************************************************************
  121858. +**
  121859. +** gckEVENT_Signal
  121860. +**
  121861. +** Schedule an event to trigger a signal.
  121862. +**
  121863. +** INPUT:
  121864. +**
  121865. +** gckEVENT Event
  121866. +** Pointer to an gckEVENT object.
  121867. +**
  121868. +** gctSIGNAL Signal
  121869. +** Pointer to the signal to trigger.
  121870. +**
  121871. +** gceKERNEL_WHERE FromWhere
  121872. +** Place in the pipe where the event needs to be generated.
  121873. +**
  121874. +** OUTPUT:
  121875. +**
  121876. +** Nothing.
  121877. +*/
  121878. +gceSTATUS
  121879. +gckEVENT_Signal(
  121880. + IN gckEVENT Event,
  121881. + IN gctSIGNAL Signal,
  121882. + IN gceKERNEL_WHERE FromWhere
  121883. + )
  121884. +{
  121885. + gceSTATUS status;
  121886. + gcsHAL_INTERFACE iface;
  121887. +
  121888. + gcmkHEADER_ARG("Event=0x%x Signal=0x%x FromWhere=%d",
  121889. + Event, Signal, FromWhere);
  121890. +
  121891. + /* Verify the arguments. */
  121892. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121893. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  121894. +
  121895. + /* Mark the event as a signal. */
  121896. + iface.command = gcvHAL_SIGNAL;
  121897. + iface.u.Signal.signal = gcmPTR_TO_UINT64(Signal);
  121898. +#ifdef __QNXNTO__
  121899. + iface.u.Signal.coid = 0;
  121900. + iface.u.Signal.rcvid = 0;
  121901. +#endif
  121902. + iface.u.Signal.auxSignal = 0;
  121903. + iface.u.Signal.process = 0;
  121904. +
  121905. + /* Append it to the queue. */
  121906. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121907. +
  121908. + /* Success. */
  121909. + gcmkFOOTER_NO();
  121910. + return gcvSTATUS_OK;
  121911. +
  121912. +OnError:
  121913. + /* Return the status. */
  121914. + gcmkFOOTER();
  121915. + return status;
  121916. +}
  121917. +
  121918. +/*******************************************************************************
  121919. +**
  121920. +** gckEVENT_CommitDone
  121921. +**
  121922. +** Schedule an event to wake up work thread when commit is done by GPU.
  121923. +**
  121924. +** INPUT:
  121925. +**
  121926. +** gckEVENT Event
  121927. +** Pointer to an gckEVENT object.
  121928. +**
  121929. +** gceKERNEL_WHERE FromWhere
  121930. +** Place in the pipe where the event needs to be generated.
  121931. +**
  121932. +** OUTPUT:
  121933. +**
  121934. +** Nothing.
  121935. +*/
  121936. +gceSTATUS
  121937. +gckEVENT_CommitDone(
  121938. + IN gckEVENT Event,
  121939. + IN gceKERNEL_WHERE FromWhere
  121940. + )
  121941. +{
  121942. + gceSTATUS status;
  121943. + gcsHAL_INTERFACE iface;
  121944. +
  121945. + gcmkHEADER_ARG("Event=0x%x FromWhere=%d", Event, FromWhere);
  121946. +
  121947. + /* Verify the arguments. */
  121948. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121949. +
  121950. + iface.command = gcvHAL_COMMIT_DONE;
  121951. +
  121952. + /* Append it to the queue. */
  121953. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121954. +
  121955. + /* Success. */
  121956. + gcmkFOOTER_NO();
  121957. + return gcvSTATUS_OK;
  121958. +
  121959. +OnError:
  121960. + /* Return the status. */
  121961. + gcmkFOOTER();
  121962. + return status;
  121963. +}
  121964. +/*******************************************************************************
  121965. +**
  121966. +** gckEVENT_Submit
  121967. +**
  121968. +** Submit the current event queue to the GPU.
  121969. +**
  121970. +** INPUT:
  121971. +**
  121972. +** gckEVENT Event
  121973. +** Pointer to an gckEVENT object.
  121974. +**
  121975. +** gctBOOL Wait
  121976. +** Submit requires one vacant event; if Wait is set to not zero,
  121977. +** and there are no vacant events at this time, the function will
  121978. +** wait until an event becomes vacant so that submission of the
  121979. +** queue is successful.
  121980. +**
  121981. +** gctBOOL FromPower
  121982. +** Determines whether the call originates from inside the power
  121983. +** management or not.
  121984. +**
  121985. +** OUTPUT:
  121986. +**
  121987. +** Nothing.
  121988. +*/
  121989. +gceSTATUS
  121990. +gckEVENT_Submit(
  121991. + IN gckEVENT Event,
  121992. + IN gctBOOL Wait,
  121993. + IN gctBOOL FromPower
  121994. + )
  121995. +{
  121996. + gceSTATUS status;
  121997. + gctUINT8 id = 0xFF;
  121998. + gcsEVENT_QUEUE_PTR queue;
  121999. + gctBOOL acquired = gcvFALSE;
  122000. + gckCOMMAND command = gcvNULL;
  122001. + gctBOOL commitEntered = gcvFALSE;
  122002. +#if !gcdNULL_DRIVER
  122003. + gctSIZE_T bytes;
  122004. + gctPOINTER buffer;
  122005. +#endif
  122006. +
  122007. + gcmkHEADER_ARG("Event=0x%x Wait=%d", Event, Wait);
  122008. +
  122009. + /* Get gckCOMMAND object. */
  122010. + command = Event->kernel->command;
  122011. +
  122012. + /* Are there event queues? */
  122013. + if (Event->queueHead != gcvNULL)
  122014. + {
  122015. + /* Acquire the command queue. */
  122016. + gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
  122017. + commitEntered = gcvTRUE;
  122018. +
  122019. + /* Process all queues. */
  122020. + while (Event->queueHead != gcvNULL)
  122021. + {
  122022. + /* Acquire the list mutex. */
  122023. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  122024. + Event->eventListMutex,
  122025. + gcvINFINITE));
  122026. + acquired = gcvTRUE;
  122027. +
  122028. + /* Get the current queue. */
  122029. + queue = Event->queueHead;
  122030. +
  122031. + /* Allocate an event ID. */
  122032. + gcmkONERROR(gckEVENT_GetEvent(Event, Wait, &id, queue->head, queue->source));
  122033. +
  122034. + /* Copy event list to event ID queue. */
  122035. + Event->queues[id].head = queue->head;
  122036. +
  122037. + /* Remove the top queue from the list. */
  122038. + if (Event->queueHead == Event->queueTail)
  122039. + {
  122040. + Event->queueHead = gcvNULL;
  122041. + Event->queueTail = gcvNULL;
  122042. + }
  122043. + else
  122044. + {
  122045. + Event->queueHead = Event->queueHead->next;
  122046. + }
  122047. +
  122048. + /* Free the queue. */
  122049. + gcmkONERROR(gckEVENT_FreeQueue(Event, queue));
  122050. +
  122051. + /* Release the list mutex. */
  122052. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  122053. + acquired = gcvFALSE;
  122054. +
  122055. +#if gcdNULL_DRIVER
  122056. + /* Notify immediately on infinite hardware. */
  122057. + gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id));
  122058. +
  122059. + gcmkONERROR(gckEVENT_Notify(Event, 0));
  122060. +#else
  122061. + /* Get the size of the hardware event. */
  122062. + gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware,
  122063. + gcvNULL,
  122064. + id,
  122065. + Event->queues[id].source,
  122066. + &bytes));
  122067. +
  122068. + /* Reserve space in the command queue. */
  122069. + gcmkONERROR(gckCOMMAND_Reserve(command,
  122070. + bytes,
  122071. + &buffer,
  122072. + &bytes));
  122073. +
  122074. + /* Set the hardware event in the command queue. */
  122075. + gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware,
  122076. + buffer,
  122077. + id,
  122078. + Event->queues[id].source,
  122079. + &bytes));
  122080. +
  122081. + /* Execute the hardware event. */
  122082. + gcmkONERROR(gckCOMMAND_Execute(command, bytes));
  122083. +#endif
  122084. + }
  122085. +
  122086. + /* Release the command queue. */
  122087. + gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
  122088. + commitEntered = gcvFALSE;
  122089. + }
  122090. +
  122091. + /* Success. */
  122092. + gcmkFOOTER_NO();
  122093. + return gcvSTATUS_OK;
  122094. +
  122095. +OnError:
  122096. + if (commitEntered)
  122097. + {
  122098. + /* Release the command queue mutex. */
  122099. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, FromPower));
  122100. + }
  122101. +
  122102. + if (acquired)
  122103. + {
  122104. + /* Need to unroll the mutex acquire. */
  122105. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  122106. + }
  122107. +
  122108. + if (id != 0xFF)
  122109. + {
  122110. + /* Need to unroll the event allocation. */
  122111. + Event->queues[id].head = gcvNULL;
  122112. + }
  122113. +
  122114. + if (status == gcvSTATUS_GPU_NOT_RESPONDING)
  122115. + {
  122116. + /* Broadcast GPU stuck. */
  122117. + status = gckOS_Broadcast(Event->os,
  122118. + Event->kernel->hardware,
  122119. + gcvBROADCAST_GPU_STUCK);
  122120. + }
  122121. +
  122122. + /* Return the status. */
  122123. + gcmkFOOTER();
  122124. + return status;
  122125. +}
  122126. +
  122127. +/*******************************************************************************
  122128. +**
  122129. +** gckEVENT_Commit
  122130. +**
  122131. +** Commit an event queue from the user.
  122132. +**
  122133. +** INPUT:
  122134. +**
  122135. +** gckEVENT Event
  122136. +** Pointer to an gckEVENT object.
  122137. +**
  122138. +** gcsQUEUE_PTR Queue
  122139. +** User event queue.
  122140. +**
  122141. +** OUTPUT:
  122142. +**
  122143. +** Nothing.
  122144. +*/
  122145. +gceSTATUS
  122146. +gckEVENT_Commit(
  122147. + IN gckEVENT Event,
  122148. + IN gcsQUEUE_PTR Queue
  122149. + )
  122150. +{
  122151. + gceSTATUS status;
  122152. + gcsQUEUE_PTR record = gcvNULL, next;
  122153. + gctUINT32 processID;
  122154. + gctBOOL needCopy = gcvFALSE;
  122155. +
  122156. + gcmkHEADER_ARG("Event=0x%x Queue=0x%x", Event, Queue);
  122157. +
  122158. + /* Verify the arguments. */
  122159. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122160. +
  122161. + /* Get the current process ID. */
  122162. + gcmkONERROR(gckOS_GetProcessID(&processID));
  122163. +
  122164. + /* Query if we need to copy the client data. */
  122165. + gcmkONERROR(gckOS_QueryNeedCopy(Event->os, processID, &needCopy));
  122166. +
  122167. + /* Loop while there are records in the queue. */
  122168. + while (Queue != gcvNULL)
  122169. + {
  122170. + gcsQUEUE queue;
  122171. +
  122172. + if (needCopy)
  122173. + {
  122174. + /* Point to stack record. */
  122175. + record = &queue;
  122176. +
  122177. + /* Copy the data from the client. */
  122178. + gcmkONERROR(gckOS_CopyFromUserData(Event->os,
  122179. + record,
  122180. + Queue,
  122181. + gcmSIZEOF(gcsQUEUE)));
  122182. + }
  122183. + else
  122184. + {
  122185. + gctPOINTER pointer = gcvNULL;
  122186. +
  122187. + /* Map record into kernel memory. */
  122188. + gcmkONERROR(gckOS_MapUserPointer(Event->os,
  122189. + Queue,
  122190. + gcmSIZEOF(gcsQUEUE),
  122191. + &pointer));
  122192. +
  122193. + record = pointer;
  122194. + }
  122195. +
  122196. + /* Append event record to event queue. */
  122197. + gcmkONERROR(
  122198. + gckEVENT_AddList(Event, &record->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE));
  122199. +
  122200. + /* Next record in the queue. */
  122201. + next = gcmUINT64_TO_PTR(record->next);
  122202. +
  122203. + if (!needCopy)
  122204. + {
  122205. + /* Unmap record from kernel memory. */
  122206. + gcmkONERROR(
  122207. + gckOS_UnmapUserPointer(Event->os,
  122208. + Queue,
  122209. + gcmSIZEOF(gcsQUEUE),
  122210. + (gctPOINTER *) record));
  122211. + record = gcvNULL;
  122212. + }
  122213. +
  122214. + Queue = next;
  122215. + }
  122216. +
  122217. + /* Submit the event list. */
  122218. + gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE));
  122219. +
  122220. + /* Success */
  122221. + gcmkFOOTER_NO();
  122222. + return gcvSTATUS_OK;
  122223. +
  122224. +OnError:
  122225. + if ((record != gcvNULL) && !needCopy)
  122226. + {
  122227. + /* Roll back. */
  122228. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(Event->os,
  122229. + Queue,
  122230. + gcmSIZEOF(gcsQUEUE),
  122231. + (gctPOINTER *) record));
  122232. + }
  122233. +
  122234. + /* Return the status. */
  122235. + gcmkFOOTER();
  122236. + return status;
  122237. +}
  122238. +
  122239. +/*******************************************************************************
  122240. +**
  122241. +** gckEVENT_Compose
  122242. +**
  122243. +** Schedule a composition event and start a composition.
  122244. +**
  122245. +** INPUT:
  122246. +**
  122247. +** gckEVENT Event
  122248. +** Pointer to an gckEVENT object.
  122249. +**
  122250. +** gcsHAL_COMPOSE_PTR Info
  122251. +** Pointer to the composition structure.
  122252. +**
  122253. +** OUTPUT:
  122254. +**
  122255. +** Nothing.
  122256. +*/
  122257. +gceSTATUS
  122258. +gckEVENT_Compose(
  122259. + IN gckEVENT Event,
  122260. + IN gcsHAL_COMPOSE_PTR Info
  122261. + )
  122262. +{
  122263. + gceSTATUS status;
  122264. + gcsEVENT_PTR headRecord;
  122265. + gcsEVENT_PTR tailRecord;
  122266. + gcsEVENT_PTR tempRecord;
  122267. + gctUINT8 id = 0xFF;
  122268. + gctUINT32 processID;
  122269. +
  122270. + gcmkHEADER_ARG("Event=0x%x Info=0x%x", Event, Info);
  122271. +
  122272. + /* Verify the arguments. */
  122273. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122274. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  122275. +
  122276. + /* Get process ID. */
  122277. + gcmkONERROR(gckOS_GetProcessID(&processID));
  122278. +
  122279. + /* Allocate a record. */
  122280. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &tempRecord));
  122281. + headRecord = tailRecord = tempRecord;
  122282. +
  122283. + /* Initialize the record. */
  122284. + tempRecord->info.command = gcvHAL_SIGNAL;
  122285. + tempRecord->info.u.Signal.process = Info->process;
  122286. +#ifdef __QNXNTO__
  122287. + tempRecord->info.u.Signal.coid = Info->coid;
  122288. + tempRecord->info.u.Signal.rcvid = Info->rcvid;
  122289. +#endif
  122290. + tempRecord->info.u.Signal.signal = Info->signal;
  122291. + tempRecord->info.u.Signal.auxSignal = 0;
  122292. + tempRecord->next = gcvNULL;
  122293. + tempRecord->processID = processID;
  122294. +
  122295. + /* Allocate another record for user signal #1. */
  122296. + if (gcmUINT64_TO_PTR(Info->userSignal1) != gcvNULL)
  122297. + {
  122298. + /* Allocate a record. */
  122299. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &tempRecord));
  122300. + tailRecord->next = tempRecord;
  122301. + tailRecord = tempRecord;
  122302. +
  122303. + /* Initialize the record. */
  122304. + tempRecord->info.command = gcvHAL_SIGNAL;
  122305. + tempRecord->info.u.Signal.process = Info->userProcess;
  122306. +#ifdef __QNXNTO__
  122307. + tempRecord->info.u.Signal.coid = Info->coid;
  122308. + tempRecord->info.u.Signal.rcvid = Info->rcvid;
  122309. +#endif
  122310. + tempRecord->info.u.Signal.signal = Info->userSignal1;
  122311. + tempRecord->info.u.Signal.auxSignal = 0;
  122312. + tempRecord->next = gcvNULL;
  122313. + tempRecord->processID = processID;
  122314. + }
  122315. +
  122316. + /* Allocate another record for user signal #2. */
  122317. + if (gcmUINT64_TO_PTR(Info->userSignal2) != gcvNULL)
  122318. + {
  122319. + /* Allocate a record. */
  122320. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &tempRecord));
  122321. + tailRecord->next = tempRecord;
  122322. + tailRecord = tempRecord;
  122323. +
  122324. + /* Initialize the record. */
  122325. + tempRecord->info.command = gcvHAL_SIGNAL;
  122326. + tempRecord->info.u.Signal.process = Info->userProcess;
  122327. +#ifdef __QNXNTO__
  122328. + tempRecord->info.u.Signal.coid = Info->coid;
  122329. + tempRecord->info.u.Signal.rcvid = Info->rcvid;
  122330. +#endif
  122331. + tempRecord->info.u.Signal.signal = Info->userSignal2;
  122332. + tempRecord->info.u.Signal.auxSignal = 0;
  122333. + tempRecord->next = gcvNULL;
  122334. + tempRecord->processID = processID;
  122335. + }
  122336. +
  122337. + /* Allocate an event ID. */
  122338. + gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, headRecord, gcvKERNEL_PIXEL));
  122339. +
  122340. + /* Start composition. */
  122341. + gcmkONERROR(gckHARDWARE_Compose(
  122342. + Event->kernel->hardware, processID,
  122343. + gcmUINT64_TO_PTR(Info->physical), gcmUINT64_TO_PTR(Info->logical), Info->offset, Info->size, id
  122344. + ));
  122345. +
  122346. + /* Success. */
  122347. + gcmkFOOTER_NO();
  122348. + return gcvSTATUS_OK;
  122349. +
  122350. +OnError:
  122351. + /* Return the status. */
  122352. + gcmkFOOTER();
  122353. + return status;
  122354. +}
  122355. +
  122356. +/*******************************************************************************
  122357. +**
  122358. +** gckEVENT_Interrupt
  122359. +**
  122360. +** Called by the interrupt service routine to store the triggered interrupt
  122361. +** mask to be later processed by gckEVENT_Notify.
  122362. +**
  122363. +** INPUT:
  122364. +**
  122365. +** gckEVENT Event
  122366. +** Pointer to an gckEVENT object.
  122367. +**
  122368. +** gctUINT32 Data
  122369. +** Mask for the 32 interrupts.
  122370. +**
  122371. +** OUTPUT:
  122372. +**
  122373. +** Nothing.
  122374. +*/
  122375. +gceSTATUS
  122376. +gckEVENT_Interrupt(
  122377. + IN gckEVENT Event,
  122378. + IN gctUINT32 Data
  122379. + )
  122380. +{
  122381. + unsigned long flags;
  122382. + gcmkHEADER_ARG("Event=0x%x Data=0x%x", Event, Data);
  122383. +
  122384. + /* Verify the arguments. */
  122385. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122386. +
  122387. + /* Combine current interrupt status with pending flags. */
  122388. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  122389. +#if gcdSMP
  122390. + gckOS_AtomSetMask(Event->pending, Data);
  122391. +#elif defined(__QNXNTO__)
  122392. + atomic_set(&Event->pending, Data);
  122393. +#else
  122394. + Event->pending |= Data;
  122395. +#endif
  122396. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  122397. +
  122398. + /* Success. */
  122399. + gcmkFOOTER_NO();
  122400. + return gcvSTATUS_OK;
  122401. +}
  122402. +
  122403. +/*******************************************************************************
  122404. +**
  122405. +** gckEVENT_Notify
  122406. +**
  122407. +** Process all triggered interrupts.
  122408. +**
  122409. +** INPUT:
  122410. +**
  122411. +** gckEVENT Event
  122412. +** Pointer to an gckEVENT object.
  122413. +**
  122414. +** OUTPUT:
  122415. +**
  122416. +** Nothing.
  122417. +*/
  122418. +gceSTATUS
  122419. +gckEVENT_Notify(
  122420. + IN gckEVENT Event,
  122421. + IN gctUINT32 IDs
  122422. + )
  122423. +{
  122424. + gceSTATUS status = gcvSTATUS_OK;
  122425. + gctINT i;
  122426. + gcsEVENT_QUEUE * queue;
  122427. + gctUINT mask = 0;
  122428. + gctBOOL acquired = gcvFALSE;
  122429. + gcuVIDMEM_NODE_PTR node;
  122430. + gctPOINTER info;
  122431. + gctSIGNAL signal;
  122432. + gctUINT pending;
  122433. + gckKERNEL kernel = Event->kernel;
  122434. +#if !gcdSMP
  122435. + gctBOOL suspended = gcvFALSE;
  122436. +#endif
  122437. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  122438. + gctINT eventNumber = 0;
  122439. +#endif
  122440. + gctINT32 free;
  122441. +#if gcdSECURE_USER
  122442. + gcskSECURE_CACHE_PTR cache;
  122443. +#endif
  122444. + unsigned long flags;
  122445. +
  122446. + gcmkHEADER_ARG("Event=0x%x IDs=0x%x", Event, IDs);
  122447. +
  122448. + /* Verify the arguments. */
  122449. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122450. +
  122451. + gcmDEBUG_ONLY(
  122452. + if (IDs != 0)
  122453. + {
  122454. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  122455. + {
  122456. + if (Event->queues[i].head != gcvNULL)
  122457. + {
  122458. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122459. + "Queue(%d): stamp=%llu source=%d",
  122460. + i,
  122461. + Event->queues[i].stamp,
  122462. + Event->queues[i].source);
  122463. + }
  122464. + }
  122465. + }
  122466. + );
  122467. +
  122468. + for (;;)
  122469. + {
  122470. + gcsEVENT_PTR record;
  122471. +
  122472. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  122473. +#if gcdSMP
  122474. + /* Get current interrupts. */
  122475. + gckOS_AtomGet(Event->os, Event->pending, (gctINT32_PTR)&pending);
  122476. +#else
  122477. + /* Get current interrupts. */
  122478. + pending = Event->pending;
  122479. +#endif
  122480. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  122481. +
  122482. + if (pending & 0x80000000)
  122483. + {
  122484. + //gckOS_Print("!!!!!!!!!!!!! AXI BUS ERROR !!!!!!!!!!!!!\n");
  122485. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_EVENT, "AXI BUS ERROR");
  122486. + pending &= 0x7FFFFFFF;
  122487. + }
  122488. +
  122489. + if (pending & 0x40000000)
  122490. + {
  122491. + gckHARDWARE_DumpMMUException(Event->kernel->hardware);
  122492. +
  122493. + pending &= 0x3FFFFFFF;
  122494. + }
  122495. +
  122496. + gcmkTRACE_ZONE_N(
  122497. + gcvLEVEL_INFO, gcvZONE_EVENT,
  122498. + gcmSIZEOF(pending),
  122499. + "Pending interrupts 0x%x",
  122500. + pending
  122501. + );
  122502. +
  122503. + if (pending == 0)
  122504. + {
  122505. + /* No more pending interrupts - done. */
  122506. + break;
  122507. + }
  122508. +
  122509. + queue = gcvNULL;
  122510. +
  122511. + /* Grab the mutex queue. */
  122512. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  122513. + Event->eventQueueMutex,
  122514. + gcvINFINITE));
  122515. + acquired = gcvTRUE;
  122516. +
  122517. + gcmDEBUG_ONLY(
  122518. + if (IDs == 0)
  122519. + {
  122520. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  122521. + {
  122522. + if (Event->queues[i].head != gcvNULL)
  122523. + {
  122524. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122525. + "Queue(%d): stamp=%llu source=%d",
  122526. + i,
  122527. + Event->queues[i].stamp,
  122528. + Event->queues[i].source);
  122529. + }
  122530. + }
  122531. + }
  122532. + );
  122533. +
  122534. + /* Find the oldest pending interrupt. */
  122535. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  122536. + {
  122537. + if ((Event->queues[i].head != gcvNULL)
  122538. + && (pending & (1 << i))
  122539. + )
  122540. + {
  122541. + if ((queue == gcvNULL)
  122542. + || (Event->queues[i].stamp < queue->stamp)
  122543. + )
  122544. + {
  122545. + queue = &Event->queues[i];
  122546. + mask = 1 << i;
  122547. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  122548. + eventNumber = i;
  122549. +#endif
  122550. + }
  122551. + }
  122552. + }
  122553. +
  122554. + if (queue == gcvNULL)
  122555. + {
  122556. + gcmkTRACE_ZONE_N(
  122557. + gcvLEVEL_ERROR, gcvZONE_EVENT,
  122558. + gcmSIZEOF(pending),
  122559. + "Interrupts 0x%x are not pending.",
  122560. + pending
  122561. + );
  122562. +
  122563. + /* Release the mutex queue. */
  122564. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  122565. + acquired = gcvFALSE;
  122566. +
  122567. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  122568. +#if gcdSMP
  122569. + /* Mark pending interrupts as handled. */
  122570. + gckOS_AtomClearMask(Event->pending, pending);
  122571. +#elif defined(__QNXNTO__)
  122572. + /* Mark pending interrupts as handled. */
  122573. + atomic_clr((gctUINT32_PTR)&Event->pending, pending);
  122574. +#else
  122575. + /* Mark pending interrupts as handled. */
  122576. + Event->pending &= ~pending;
  122577. +#endif
  122578. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  122579. + break;
  122580. + }
  122581. +
  122582. + /* Check whether there is a missed interrupt. */
  122583. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  122584. + {
  122585. + if ((Event->queues[i].head != gcvNULL)
  122586. + && (Event->queues[i].stamp < queue->stamp)
  122587. + && (Event->queues[i].source <= queue->source)
  122588. + )
  122589. + {
  122590. + gcmkTRACE_N(
  122591. + gcvLEVEL_ERROR,
  122592. + gcmSIZEOF(i) + gcmSIZEOF(Event->queues[i].stamp),
  122593. + "Event %d lost (stamp %llu)",
  122594. + i, Event->queues[i].stamp
  122595. + );
  122596. +
  122597. + /* Use this event instead. */
  122598. + queue = &Event->queues[i];
  122599. + mask = 0;
  122600. + }
  122601. + }
  122602. +
  122603. + if (mask != 0)
  122604. + {
  122605. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  122606. + gcmkTRACE_ZONE_N(
  122607. + gcvLEVEL_INFO, gcvZONE_EVENT,
  122608. + gcmSIZEOF(eventNumber),
  122609. + "Processing interrupt %d",
  122610. + eventNumber
  122611. + );
  122612. +#endif
  122613. + }
  122614. +
  122615. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  122616. +#if gcdSMP
  122617. + /* Mark pending interrupt as handled. */
  122618. + gckOS_AtomClearMask(Event->pending, mask);
  122619. +#elif defined(__QNXNTO__)
  122620. + /* Mark pending interrupt as handled. */
  122621. + atomic_clr(&Event->pending, mask);
  122622. +#else
  122623. + /* Mark pending interrupt as handled. */
  122624. + Event->pending &= ~mask;
  122625. +#endif
  122626. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  122627. +
  122628. + /* We are in the notify loop. */
  122629. + Event->inNotify = gcvTRUE;
  122630. +
  122631. + /* We are in the notify loop. */
  122632. + Event->inNotify = gcvTRUE;
  122633. +
  122634. + /* Grab the event head. */
  122635. + record = queue->head;
  122636. +
  122637. + /* Now quickly clear its event list. */
  122638. + queue->head = gcvNULL;
  122639. +
  122640. + /* Release the mutex queue. */
  122641. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  122642. + acquired = gcvFALSE;
  122643. +
  122644. + /* Increase the number of free events. */
  122645. + gcmkONERROR(gckOS_AtomIncrement(Event->os, Event->freeAtom, &free));
  122646. +
  122647. + /* Walk all events for this interrupt. */
  122648. + while (record != gcvNULL)
  122649. + {
  122650. + gcsEVENT_PTR recordNext;
  122651. +#ifndef __QNXNTO__
  122652. + gctPOINTER logical;
  122653. +#endif
  122654. +#if gcdSECURE_USER
  122655. + gctSIZE_T bytes;
  122656. +#endif
  122657. +
  122658. + /* Grab next record. */
  122659. + recordNext = record->next;
  122660. +
  122661. +#ifdef __QNXNTO__
  122662. + /* Assign record->processID as the pid for this galcore thread.
  122663. + * Used in OS calls like gckOS_UnlockMemory() which do not take a pid.
  122664. + */
  122665. + drv_thread_specific_key_assign(record->processID, 0, Event->kernel->core);
  122666. +#endif
  122667. +
  122668. +#if gcdSECURE_USER
  122669. + /* Get the cache that belongs to this process. */
  122670. + gcmkONERROR(gckKERNEL_GetProcessDBCache(Event->kernel,
  122671. + record->processID,
  122672. + &cache));
  122673. +#endif
  122674. +
  122675. + gcmkTRACE_ZONE_N(
  122676. + gcvLEVEL_INFO, gcvZONE_EVENT,
  122677. + gcmSIZEOF(record->info.command),
  122678. + "Processing event type: %d",
  122679. + record->info.command
  122680. + );
  122681. +
  122682. + switch (record->info.command)
  122683. + {
  122684. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  122685. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122686. + "gcvHAL_FREE_NON_PAGED_MEMORY: 0x%x",
  122687. + gcmNAME_TO_PTR(record->info.u.FreeNonPagedMemory.physical));
  122688. +
  122689. + /* Free non-paged memory. */
  122690. + status = gckOS_FreeNonPagedMemory(
  122691. + Event->os,
  122692. + (gctSIZE_T) record->info.u.FreeNonPagedMemory.bytes,
  122693. + gcmNAME_TO_PTR(record->info.u.FreeNonPagedMemory.physical),
  122694. + gcmUINT64_TO_PTR(record->info.u.FreeNonPagedMemory.logical));
  122695. +
  122696. + if (gcmIS_SUCCESS(status))
  122697. + {
  122698. +#if gcdSECURE_USER
  122699. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  122700. + Event->kernel,
  122701. + cache,
  122702. + gcmUINT64_TO_PTR(record->record.u.FreeNonPagedMemory.logical),
  122703. + (gctSIZE_T) record->record.u.FreeNonPagedMemory.bytes));
  122704. +#endif
  122705. + }
  122706. + gcmRELEASE_NAME(record->info.u.FreeNonPagedMemory.physical);
  122707. + break;
  122708. +
  122709. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  122710. + gcmkTRACE_ZONE(
  122711. + gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122712. + "gcvHAL_FREE_CONTIGUOUS_MEMORY: 0x%x",
  122713. + gcmNAME_TO_PTR(record->info.u.FreeContiguousMemory.physical));
  122714. +
  122715. + /* Unmap the user memory. */
  122716. + status = gckOS_FreeContiguous(
  122717. + Event->os,
  122718. + gcmNAME_TO_PTR(record->info.u.FreeContiguousMemory.physical),
  122719. + gcmUINT64_TO_PTR(record->info.u.FreeContiguousMemory.logical),
  122720. + (gctSIZE_T) record->info.u.FreeContiguousMemory.bytes);
  122721. +
  122722. + if (gcmIS_SUCCESS(status))
  122723. + {
  122724. +#if gcdSECURE_USER
  122725. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  122726. + Event->kernel,
  122727. + cache,
  122728. + gcmUINT64_TO_PTR(record->record.u.FreeContiguousMemory.logical),
  122729. + (gctSIZE_T) record->record.u.FreeContiguousMemory.bytes));
  122730. +#endif
  122731. + }
  122732. + gcmRELEASE_NAME(record->info.u.FreeContiguousMemory.physical);
  122733. + break;
  122734. +
  122735. + case gcvHAL_FREE_VIDEO_MEMORY:
  122736. + node = gcmUINT64_TO_PTR(record->info.u.FreeVideoMemory.node);
  122737. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122738. + "gcvHAL_FREE_VIDEO_MEMORY: 0x%x",
  122739. + node);
  122740. +#ifdef __QNXNTO__
  122741. +#if gcdUSE_VIDMEM_PER_PID
  122742. + /* Check if the VidMem object still exists. */
  122743. + if (gckKERNEL_GetVideoMemoryPoolPid(record->kernel,
  122744. + gcvPOOL_SYSTEM,
  122745. + record->processID,
  122746. + gcvNULL) == gcvSTATUS_NOT_FOUND)
  122747. + {
  122748. + /*printf("Vidmem not found for process:%d\n", queue->processID);*/
  122749. + status = gcvSTATUS_OK;
  122750. + break;
  122751. + }
  122752. +#else
  122753. + if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  122754. + && (node->VidMem.logical != gcvNULL)
  122755. + )
  122756. + {
  122757. + gcmkERR_BREAK(
  122758. + gckKERNEL_UnmapVideoMemory(record->kernel,
  122759. + node->VidMem.logical,
  122760. + record->processID,
  122761. + node->VidMem.bytes));
  122762. + node->VidMem.logical = gcvNULL;
  122763. + }
  122764. +#endif
  122765. +#endif
  122766. +
  122767. + /* Free video memory. */
  122768. + status =
  122769. + gckVIDMEM_Free(node);
  122770. +
  122771. + break;
  122772. +
  122773. + case gcvHAL_WRITE_DATA:
  122774. +#ifndef __QNXNTO__
  122775. + /* Convert physical into logical address. */
  122776. + gcmkERR_BREAK(
  122777. + gckOS_MapPhysical(Event->os,
  122778. + record->info.u.WriteData.address,
  122779. + gcmSIZEOF(gctUINT32),
  122780. + &logical));
  122781. +
  122782. + /* Write data. */
  122783. + gcmkERR_BREAK(
  122784. + gckOS_WriteMemory(Event->os,
  122785. + logical,
  122786. + record->info.u.WriteData.data));
  122787. +
  122788. + /* Unmap the physical memory. */
  122789. + gcmkERR_BREAK(
  122790. + gckOS_UnmapPhysical(Event->os,
  122791. + logical,
  122792. + gcmSIZEOF(gctUINT32)));
  122793. +#else
  122794. + /* Write data. */
  122795. + gcmkERR_BREAK(
  122796. + gckOS_WriteMemory(Event->os,
  122797. + (gctPOINTER)
  122798. + record->info.u.WriteData.address,
  122799. + record->info.u.WriteData.data));
  122800. +#endif
  122801. + break;
  122802. +
  122803. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  122804. + node = gcmUINT64_TO_PTR(record->info.u.UnlockVideoMemory.node);
  122805. +
  122806. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122807. + "gcvHAL_UNLOCK_VIDEO_MEMORY: 0x%x",
  122808. + node);
  122809. +
  122810. + /* Save node information before it disappears. */
  122811. +#if gcdSECURE_USER
  122812. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  122813. + {
  122814. + logical = gcvNULL;
  122815. + bytes = 0;
  122816. + }
  122817. + else
  122818. + {
  122819. + logical = node->Virtual.logical;
  122820. + bytes = node->Virtual.bytes;
  122821. + }
  122822. +#endif
  122823. +
  122824. + /* Unlock. */
  122825. + status = gckVIDMEM_Unlock(
  122826. + Event->kernel,
  122827. + node,
  122828. + record->info.u.UnlockVideoMemory.type,
  122829. + gcvNULL);
  122830. +
  122831. +#if gcdSECURE_USER
  122832. + if (gcmIS_SUCCESS(status) && (logical != gcvNULL))
  122833. + {
  122834. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  122835. + Event->kernel,
  122836. + cache,
  122837. + logical,
  122838. + bytes));
  122839. + }
  122840. +#endif
  122841. + break;
  122842. +
  122843. + case gcvHAL_SIGNAL:
  122844. + signal = gcmUINT64_TO_PTR(record->info.u.Signal.signal);
  122845. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122846. + "gcvHAL_SIGNAL: 0x%x",
  122847. + signal);
  122848. +
  122849. +#ifdef __QNXNTO__
  122850. + if ((record->info.u.Signal.coid == 0)
  122851. + && (record->info.u.Signal.rcvid == 0)
  122852. + )
  122853. + {
  122854. + /* Kernel signal. */
  122855. + gcmkERR_BREAK(
  122856. + gckOS_Signal(Event->os,
  122857. + signal,
  122858. + gcvTRUE));
  122859. + }
  122860. + else
  122861. + {
  122862. + /* User signal. */
  122863. + gcmkERR_BREAK(
  122864. + gckOS_UserSignal(Event->os,
  122865. + signal,
  122866. + record->info.u.Signal.rcvid,
  122867. + record->info.u.Signal.coid));
  122868. + }
  122869. +#else
  122870. + /* Set signal. */
  122871. + if (gcmUINT64_TO_PTR(record->info.u.Signal.process) == gcvNULL)
  122872. + {
  122873. + /* Kernel signal. */
  122874. + gcmkERR_BREAK(
  122875. + gckOS_Signal(Event->os,
  122876. + signal,
  122877. + gcvTRUE));
  122878. + }
  122879. + else
  122880. + {
  122881. + /* User signal. */
  122882. + gcmkERR_BREAK(
  122883. + gckOS_UserSignal(Event->os,
  122884. + signal,
  122885. + gcmUINT64_TO_PTR(record->info.u.Signal.process)));
  122886. + }
  122887. +
  122888. + gcmkASSERT(record->info.u.Signal.auxSignal == 0);
  122889. +#endif
  122890. + break;
  122891. +
  122892. + case gcvHAL_UNMAP_USER_MEMORY:
  122893. + info = gcmNAME_TO_PTR(record->info.u.UnmapUserMemory.info);
  122894. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122895. + "gcvHAL_UNMAP_USER_MEMORY: 0x%x",
  122896. + info);
  122897. +
  122898. + /* Unmap the user memory. */
  122899. + status = gckOS_UnmapUserMemory(
  122900. + Event->os,
  122901. + Event->kernel->core,
  122902. + gcmUINT64_TO_PTR(record->info.u.UnmapUserMemory.memory),
  122903. + (gctSIZE_T) record->info.u.UnmapUserMemory.size,
  122904. + info,
  122905. + record->info.u.UnmapUserMemory.address);
  122906. +
  122907. +#if gcdSECURE_USER
  122908. + if (gcmIS_SUCCESS(status))
  122909. + {
  122910. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  122911. + Event->kernel,
  122912. + cache,
  122913. + gcmUINT64_TO_PTR(record->info.u.UnmapUserMemory.memory),
  122914. + (gctSIZE_T) record->info.u.UnmapUserMemory.size));
  122915. + }
  122916. +#endif
  122917. + gcmRELEASE_NAME(record->info.u.UnmapUserMemory.info);
  122918. + break;
  122919. +
  122920. + case gcvHAL_TIMESTAMP:
  122921. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122922. + "gcvHAL_TIMESTAMP: %d %d",
  122923. + record->info.u.TimeStamp.timer,
  122924. + record->info.u.TimeStamp.request);
  122925. +
  122926. + /* Process the timestamp. */
  122927. + switch (record->info.u.TimeStamp.request)
  122928. + {
  122929. + case 0:
  122930. + status = gckOS_GetTime(&Event->kernel->timers[
  122931. + record->info.u.TimeStamp.timer].
  122932. + stopTime);
  122933. + break;
  122934. +
  122935. + case 1:
  122936. + status = gckOS_GetTime(&Event->kernel->timers[
  122937. + record->info.u.TimeStamp.timer].
  122938. + startTime);
  122939. + break;
  122940. +
  122941. + default:
  122942. + gcmkTRACE_ZONE_N(
  122943. + gcvLEVEL_ERROR, gcvZONE_EVENT,
  122944. + gcmSIZEOF(record->info.u.TimeStamp.request),
  122945. + "Invalid timestamp request: %d",
  122946. + record->info.u.TimeStamp.request
  122947. + );
  122948. +
  122949. + status = gcvSTATUS_INVALID_ARGUMENT;
  122950. + break;
  122951. + }
  122952. + break;
  122953. +
  122954. +#if gcdVIRTUAL_COMMAND_BUFFER
  122955. + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
  122956. + gcmkVERIFY_OK(
  122957. + gckKERNEL_DestroyVirtualCommandBuffer(Event->kernel,
  122958. + (gctSIZE_T) record->info.u.FreeVirtualCommandBuffer.bytes,
  122959. + gcmNAME_TO_PTR(record->info.u.FreeVirtualCommandBuffer.physical),
  122960. + gcmUINT64_TO_PTR(record->info.u.FreeVirtualCommandBuffer.logical)
  122961. + ));
  122962. + gcmRELEASE_NAME(record->info.u.FreeVirtualCommandBuffer.physical);
  122963. + break;
  122964. +#endif
  122965. +
  122966. +#if gcdANDROID_NATIVE_FENCE_SYNC
  122967. + case gcvHAL_SYNC_POINT:
  122968. + {
  122969. + gctSYNC_POINT syncPoint;
  122970. +
  122971. + syncPoint = gcmUINT64_TO_PTR(record->info.u.SyncPoint.syncPoint);
  122972. + status = gckOS_SignalSyncPoint(Event->os, syncPoint);
  122973. + }
  122974. + break;
  122975. +#endif
  122976. +
  122977. + case gcvHAL_COMMIT_DONE:
  122978. + break;
  122979. +
  122980. + default:
  122981. + /* Invalid argument. */
  122982. + gcmkTRACE_ZONE_N(
  122983. + gcvLEVEL_ERROR, gcvZONE_EVENT,
  122984. + gcmSIZEOF(record->info.command),
  122985. + "Unknown event type: %d",
  122986. + record->info.command
  122987. + );
  122988. +
  122989. + status = gcvSTATUS_INVALID_ARGUMENT;
  122990. + break;
  122991. + }
  122992. +
  122993. + /* Make sure there are no errors generated. */
  122994. + if (gcmIS_ERROR(status))
  122995. + {
  122996. + gcmkTRACE_ZONE_N(
  122997. + gcvLEVEL_WARNING, gcvZONE_EVENT,
  122998. + gcmSIZEOF(status),
  122999. + "Event produced status: %d(%s)",
  123000. + status, gckOS_DebugStatus2Name(status));
  123001. + }
  123002. +
  123003. + /* Free the event. */
  123004. + gcmkVERIFY_OK(gckEVENT_FreeRecord(Event, record));
  123005. +
  123006. + /* Advance to next record. */
  123007. + record = recordNext;
  123008. + }
  123009. +
  123010. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  123011. + "Handled interrupt 0x%x", mask);
  123012. + }
  123013. +
  123014. + if (IDs == 0)
  123015. + {
  123016. + gcmkONERROR(_TryToIdleGPU(Event));
  123017. + }
  123018. +
  123019. + /* We are out the notify loop. */
  123020. + Event->inNotify = gcvFALSE;
  123021. +
  123022. + /* Success. */
  123023. + gcmkFOOTER_NO();
  123024. + return gcvSTATUS_OK;
  123025. +
  123026. +OnError:
  123027. + if (acquired)
  123028. + {
  123029. + /* Release mutex. */
  123030. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  123031. + }
  123032. +
  123033. +#if !gcdSMP
  123034. + if (suspended)
  123035. + {
  123036. + /* Resume interrupts. */
  123037. + gcmkVERIFY_OK(gckOS_ResumeInterruptEx(Event->os, Event->kernel->core));
  123038. + }
  123039. +#endif
  123040. +
  123041. + /* We are out the notify loop. */
  123042. + Event->inNotify = gcvFALSE;
  123043. +
  123044. + /* Return the status. */
  123045. + gcmkFOOTER();
  123046. + return status;
  123047. +}
  123048. +
  123049. +/*******************************************************************************
  123050. +** gckEVENT_FreeProcess
  123051. +**
  123052. +** Free all events owned by a particular process ID.
  123053. +**
  123054. +** INPUT:
  123055. +**
  123056. +** gckEVENT Event
  123057. +** Pointer to an gckEVENT object.
  123058. +**
  123059. +** gctUINT32 ProcessID
  123060. +** Process ID of the process to be freed up.
  123061. +**
  123062. +** OUTPUT:
  123063. +**
  123064. +** Nothing.
  123065. +*/
  123066. +gceSTATUS
  123067. +gckEVENT_FreeProcess(
  123068. + IN gckEVENT Event,
  123069. + IN gctUINT32 ProcessID
  123070. + )
  123071. +{
  123072. + gctSIZE_T i;
  123073. + gctBOOL acquired = gcvFALSE;
  123074. + gcsEVENT_PTR record, next;
  123075. + gceSTATUS status;
  123076. + gcsEVENT_PTR deleteHead, deleteTail;
  123077. +
  123078. + gcmkHEADER_ARG("Event=0x%x ProcessID=%d", Event, ProcessID);
  123079. +
  123080. + /* Verify the arguments. */
  123081. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  123082. +
  123083. + /* Walk through all queues. */
  123084. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  123085. + {
  123086. + if (Event->queues[i].head != gcvNULL)
  123087. + {
  123088. + /* Grab the event queue mutex. */
  123089. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  123090. + Event->eventQueueMutex,
  123091. + gcvINFINITE));
  123092. + acquired = gcvTRUE;
  123093. +
  123094. + /* Grab the mutex head. */
  123095. + record = Event->queues[i].head;
  123096. + Event->queues[i].head = gcvNULL;
  123097. + Event->queues[i].tail = gcvNULL;
  123098. + deleteHead = gcvNULL;
  123099. + deleteTail = gcvNULL;
  123100. +
  123101. + while (record != gcvNULL)
  123102. + {
  123103. + next = record->next;
  123104. + if (record->processID == ProcessID)
  123105. + {
  123106. + if (deleteHead == gcvNULL)
  123107. + {
  123108. + deleteHead = record;
  123109. + }
  123110. + else
  123111. + {
  123112. + deleteTail->next = record;
  123113. + }
  123114. +
  123115. + deleteTail = record;
  123116. + }
  123117. + else
  123118. + {
  123119. + if (Event->queues[i].head == gcvNULL)
  123120. + {
  123121. + Event->queues[i].head = record;
  123122. + }
  123123. + else
  123124. + {
  123125. + Event->queues[i].tail->next = record;
  123126. + }
  123127. +
  123128. + Event->queues[i].tail = record;
  123129. + }
  123130. +
  123131. + record->next = gcvNULL;
  123132. + record = next;
  123133. + }
  123134. +
  123135. + /* Release the mutex queue. */
  123136. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  123137. + acquired = gcvFALSE;
  123138. +
  123139. + /* Loop through the entire list of events. */
  123140. + for (record = deleteHead; record != gcvNULL; record = next)
  123141. + {
  123142. + /* Get the next event record. */
  123143. + next = record->next;
  123144. +
  123145. + /* Free the event record. */
  123146. + gcmkONERROR(gckEVENT_FreeRecord(Event, record));
  123147. + }
  123148. + }
  123149. + }
  123150. +
  123151. + gcmkONERROR(_TryToIdleGPU(Event));
  123152. +
  123153. + /* Success. */
  123154. + gcmkFOOTER_NO();
  123155. + return gcvSTATUS_OK;
  123156. +
  123157. +OnError:
  123158. + /* Release the event queue mutex. */
  123159. + if (acquired)
  123160. + {
  123161. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  123162. + }
  123163. +
  123164. + /* Return the status. */
  123165. + gcmkFOOTER();
  123166. + return status;
  123167. +}
  123168. +
  123169. +/*******************************************************************************
  123170. +** gckEVENT_Stop
  123171. +**
  123172. +** Stop the hardware using the End event mechanism.
  123173. +**
  123174. +** INPUT:
  123175. +**
  123176. +** gckEVENT Event
  123177. +** Pointer to an gckEVENT object.
  123178. +**
  123179. +** gctUINT32 ProcessID
  123180. +** Process ID Logical belongs.
  123181. +**
  123182. +** gctPHYS_ADDR Handle
  123183. +** Physical address handle. If gcvNULL it is video memory.
  123184. +**
  123185. +** gctPOINTER Logical
  123186. +** Logical address to flush.
  123187. +**
  123188. +** gctSIGNAL Signal
  123189. +** Pointer to the signal to trigger.
  123190. +**
  123191. +** OUTPUT:
  123192. +**
  123193. +** Nothing.
  123194. +*/
  123195. +gceSTATUS
  123196. +gckEVENT_Stop(
  123197. + IN gckEVENT Event,
  123198. + IN gctUINT32 ProcessID,
  123199. + IN gctPHYS_ADDR Handle,
  123200. + IN gctPOINTER Logical,
  123201. + IN gctSIGNAL Signal,
  123202. + IN OUT gctSIZE_T * waitSize
  123203. + )
  123204. +{
  123205. + gceSTATUS status;
  123206. + /* gctSIZE_T waitSize;*/
  123207. + gcsEVENT_PTR record;
  123208. + gctUINT8 id = 0xFF;
  123209. +
  123210. + gcmkHEADER_ARG("Event=0x%x ProcessID=%u Handle=0x%x Logical=0x%x "
  123211. + "Signal=0x%x",
  123212. + Event, ProcessID, Handle, Logical, Signal);
  123213. +
  123214. + /* Verify the arguments. */
  123215. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  123216. +
  123217. + /* Submit the current event queue. */
  123218. + gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE));
  123219. +
  123220. + /* Allocate a record. */
  123221. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &record));
  123222. +
  123223. + /* Initialize the record. */
  123224. + record->next = gcvNULL;
  123225. + record->processID = ProcessID;
  123226. + record->info.command = gcvHAL_SIGNAL;
  123227. + record->info.u.Signal.signal = gcmPTR_TO_UINT64(Signal);
  123228. +#ifdef __QNXNTO__
  123229. + record->info.u.Signal.coid = 0;
  123230. + record->info.u.Signal.rcvid = 0;
  123231. +#endif
  123232. + record->info.u.Signal.auxSignal = 0;
  123233. + record->info.u.Signal.process = 0;
  123234. +
  123235. +
  123236. + gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, record, gcvKERNEL_PIXEL));
  123237. +
  123238. + /* Replace last WAIT with END. */
  123239. + gcmkONERROR(gckHARDWARE_End(
  123240. + Event->kernel->hardware, Logical, waitSize
  123241. + ));
  123242. +
  123243. +#if gcdNONPAGED_MEMORY_CACHEABLE
  123244. + /* Flush the cache for the END. */
  123245. + gcmkONERROR(gckOS_CacheClean(
  123246. + Event->os,
  123247. + ProcessID,
  123248. + gcvNULL,
  123249. + Handle,
  123250. + Logical,
  123251. + *waitSize
  123252. + ));
  123253. +#endif
  123254. +
  123255. + /* Wait for the signal. */
  123256. + gcmkONERROR(gckOS_WaitSignal(Event->os, Signal, gcvINFINITE));
  123257. +
  123258. + /* Success. */
  123259. + gcmkFOOTER_NO();
  123260. + return gcvSTATUS_OK;
  123261. +
  123262. +OnError:
  123263. +
  123264. + /* Return the status. */
  123265. + gcmkFOOTER();
  123266. + return status;
  123267. +}
  123268. +
  123269. +static void
  123270. +_PrintRecord(
  123271. + gcsEVENT_PTR record
  123272. + )
  123273. +{
  123274. + switch (record->info.command)
  123275. + {
  123276. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  123277. + gcmkPRINT(" gcvHAL_FREE_NON_PAGED_MEMORY");
  123278. + break;
  123279. +
  123280. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  123281. + gcmkPRINT(" gcvHAL_FREE_CONTIGUOUS_MEMORY");
  123282. + break;
  123283. +
  123284. + case gcvHAL_FREE_VIDEO_MEMORY:
  123285. + gcmkPRINT(" gcvHAL_FREE_VIDEO_MEMORY");
  123286. + break;
  123287. +
  123288. + case gcvHAL_WRITE_DATA:
  123289. + gcmkPRINT(" gcvHAL_WRITE_DATA");
  123290. + break;
  123291. +
  123292. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  123293. + gcmkPRINT(" gcvHAL_UNLOCK_VIDEO_MEMORY");
  123294. + break;
  123295. +
  123296. + case gcvHAL_SIGNAL:
  123297. + gcmkPRINT(" gcvHAL_SIGNAL process=%d signal=0x%x",
  123298. + record->info.u.Signal.process,
  123299. + record->info.u.Signal.signal);
  123300. + break;
  123301. +
  123302. + case gcvHAL_UNMAP_USER_MEMORY:
  123303. + gcmkPRINT(" gcvHAL_UNMAP_USER_MEMORY");
  123304. + break;
  123305. +
  123306. + case gcvHAL_TIMESTAMP:
  123307. + gcmkPRINT(" gcvHAL_TIMESTAMP");
  123308. + break;
  123309. +
  123310. + case gcvHAL_COMMIT_DONE:
  123311. + gcmkPRINT(" gcvHAL_COMMIT_DONE");
  123312. + break;
  123313. +
  123314. + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
  123315. + gcmkPRINT(" gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER logical=0x%08x",
  123316. + record->info.u.FreeVirtualCommandBuffer.logical);
  123317. + break;
  123318. +
  123319. + default:
  123320. + gcmkPRINT(" Illegal Event %d", record->info.command);
  123321. + break;
  123322. + }
  123323. +}
  123324. +
  123325. +/*******************************************************************************
  123326. +** gckEVENT_Dump
  123327. +**
  123328. +** Dump record in event queue when stuck happens.
  123329. +** No protection for the event queue.
  123330. +**/
  123331. +gceSTATUS
  123332. +gckEVENT_Dump(
  123333. + IN gckEVENT Event
  123334. + )
  123335. +{
  123336. + gcsEVENT_QUEUE_PTR queueHead = Event->queueHead;
  123337. + gcsEVENT_QUEUE_PTR queue;
  123338. + gcsEVENT_PTR record = gcvNULL;
  123339. + gctINT i;
  123340. +
  123341. + gcmkHEADER_ARG("Event=0x%x", Event);
  123342. +
  123343. + gcmkPRINT("**************************\n");
  123344. + gcmkPRINT("*** EVENT STATE DUMP ***\n");
  123345. + gcmkPRINT("**************************\n");
  123346. +
  123347. +
  123348. + gcmkPRINT(" Unsumbitted Event:");
  123349. + while(queueHead)
  123350. + {
  123351. + queue = queueHead;
  123352. + record = queueHead->head;
  123353. +
  123354. + gcmkPRINT(" [%x]:", queue);
  123355. + while(record)
  123356. + {
  123357. + _PrintRecord(record);
  123358. + record = record->next;
  123359. + }
  123360. +
  123361. + if (queueHead == Event->queueTail)
  123362. + {
  123363. + queueHead = gcvNULL;
  123364. + }
  123365. + else
  123366. + {
  123367. + queueHead = queueHead->next;
  123368. + }
  123369. + }
  123370. +
  123371. + gcmkPRINT(" Untriggered Event:");
  123372. + for (i = 0; i < 30; i++)
  123373. + {
  123374. + queue = &Event->queues[i];
  123375. + record = queue->head;
  123376. +
  123377. + gcmkPRINT(" [%d]:", i);
  123378. + while(record)
  123379. + {
  123380. + _PrintRecord(record);
  123381. + record = record->next;
  123382. + }
  123383. + }
  123384. +
  123385. + gcmkFOOTER_NO();
  123386. + return gcvSTATUS_OK;
  123387. +}
  123388. +
  123389. +gceSTATUS gckEVENT_WaitEmpty(gckEVENT Event)
  123390. +{
  123391. + gctBOOL isEmpty;
  123392. +
  123393. + while (Event->inNotify || (gcmIS_SUCCESS(gckEVENT_IsEmpty(Event, &isEmpty)) && !isEmpty)) ;
  123394. +
  123395. + return gcvSTATUS_OK;
  123396. +}
  123397. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
  123398. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h 1970-01-01 01:00:00.000000000 +0100
  123399. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h 2014-08-20 19:31:46.128869007 +0200
  123400. @@ -0,0 +1,1011 @@
  123401. +/****************************************************************************
  123402. +*
  123403. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  123404. +*
  123405. +* This program is free software; you can redistribute it and/or modify
  123406. +* it under the terms of the GNU General Public License as published by
  123407. +* the Free Software Foundation; either version 2 of the license, or
  123408. +* (at your option) any later version.
  123409. +*
  123410. +* This program is distributed in the hope that it will be useful,
  123411. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  123412. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  123413. +* GNU General Public License for more details.
  123414. +*
  123415. +* You should have received a copy of the GNU General Public License
  123416. +* along with this program; if not write to the Free Software
  123417. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  123418. +*
  123419. +*****************************************************************************/
  123420. +
  123421. +
  123422. +#ifndef __gc_hal_kernel_h_
  123423. +#define __gc_hal_kernel_h_
  123424. +
  123425. +#include <linux/spinlock.h>
  123426. +
  123427. +#include "gc_hal.h"
  123428. +#include "gc_hal_kernel_hardware.h"
  123429. +#include "gc_hal_driver.h"
  123430. +
  123431. +#if gcdENABLE_VG
  123432. +#include "gc_hal_kernel_vg.h"
  123433. +#endif
  123434. +
  123435. +#ifdef __cplusplus
  123436. +extern "C" {
  123437. +#endif
  123438. +
  123439. +
  123440. +/*******************************************************************************
  123441. +***** New MMU Defination *******************************************************/
  123442. +#define gcdMMU_MTLB_SHIFT 22
  123443. +#define gcdMMU_STLB_4K_SHIFT 12
  123444. +#define gcdMMU_STLB_64K_SHIFT 16
  123445. +
  123446. +#define gcdMMU_MTLB_BITS (32 - gcdMMU_MTLB_SHIFT)
  123447. +#define gcdMMU_PAGE_4K_BITS gcdMMU_STLB_4K_SHIFT
  123448. +#define gcdMMU_STLB_4K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_4K_BITS)
  123449. +#define gcdMMU_PAGE_64K_BITS gcdMMU_STLB_64K_SHIFT
  123450. +#define gcdMMU_STLB_64K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_64K_BITS)
  123451. +
  123452. +#define gcdMMU_MTLB_ENTRY_NUM (1 << gcdMMU_MTLB_BITS)
  123453. +#define gcdMMU_MTLB_SIZE (gcdMMU_MTLB_ENTRY_NUM << 2)
  123454. +#define gcdMMU_STLB_4K_ENTRY_NUM (1 << gcdMMU_STLB_4K_BITS)
  123455. +#define gcdMMU_STLB_4K_SIZE (gcdMMU_STLB_4K_ENTRY_NUM << 2)
  123456. +#define gcdMMU_PAGE_4K_SIZE (1 << gcdMMU_STLB_4K_SHIFT)
  123457. +#define gcdMMU_STLB_64K_ENTRY_NUM (1 << gcdMMU_STLB_64K_BITS)
  123458. +#define gcdMMU_STLB_64K_SIZE (gcdMMU_STLB_64K_ENTRY_NUM << 2)
  123459. +#define gcdMMU_PAGE_64K_SIZE (1 << gcdMMU_STLB_64K_SHIFT)
  123460. +
  123461. +#define gcdMMU_MTLB_MASK (~((1U << gcdMMU_MTLB_SHIFT)-1))
  123462. +#define gcdMMU_STLB_4K_MASK ((~0U << gcdMMU_STLB_4K_SHIFT) ^ gcdMMU_MTLB_MASK)
  123463. +#define gcdMMU_PAGE_4K_MASK (gcdMMU_PAGE_4K_SIZE - 1)
  123464. +#define gcdMMU_STLB_64K_MASK ((~((1U << gcdMMU_STLB_64K_SHIFT)-1)) ^ gcdMMU_MTLB_MASK)
  123465. +#define gcdMMU_PAGE_64K_MASK (gcdMMU_PAGE_64K_SIZE - 1)
  123466. +
  123467. +/* Page offset definitions. */
  123468. +#define gcdMMU_OFFSET_4K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_4K_BITS)
  123469. +#define gcdMMU_OFFSET_4K_MASK ((1U << gcdMMU_OFFSET_4K_BITS) - 1)
  123470. +#define gcdMMU_OFFSET_16K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_16K_BITS)
  123471. +#define gcdMMU_OFFSET_16K_MASK ((1U << gcdMMU_OFFSET_16K_BITS) - 1)
  123472. +
  123473. +/*******************************************************************************
  123474. +***** Process Secure Cache ****************************************************/
  123475. +
  123476. +#define gcdSECURE_CACHE_LRU 1
  123477. +#define gcdSECURE_CACHE_LINEAR 2
  123478. +#define gcdSECURE_CACHE_HASH 3
  123479. +#define gcdSECURE_CACHE_TABLE 4
  123480. +
  123481. +typedef struct _gcskLOGICAL_CACHE * gcskLOGICAL_CACHE_PTR;
  123482. +typedef struct _gcskLOGICAL_CACHE gcskLOGICAL_CACHE;
  123483. +struct _gcskLOGICAL_CACHE
  123484. +{
  123485. + /* Logical address. */
  123486. + gctPOINTER logical;
  123487. +
  123488. + /* DMAable address. */
  123489. + gctUINT32 dma;
  123490. +
  123491. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  123492. + /* Pointer to the previous and next hash tables. */
  123493. + gcskLOGICAL_CACHE_PTR nextHash;
  123494. + gcskLOGICAL_CACHE_PTR prevHash;
  123495. +#endif
  123496. +
  123497. +#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
  123498. + /* Pointer to the previous and next slot. */
  123499. + gcskLOGICAL_CACHE_PTR next;
  123500. + gcskLOGICAL_CACHE_PTR prev;
  123501. +#endif
  123502. +
  123503. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
  123504. + /* Time stamp. */
  123505. + gctUINT64 stamp;
  123506. +#endif
  123507. +};
  123508. +
  123509. +typedef struct _gcskSECURE_CACHE * gcskSECURE_CACHE_PTR;
  123510. +typedef struct _gcskSECURE_CACHE
  123511. +{
  123512. + /* Cache memory. */
  123513. + gcskLOGICAL_CACHE cache[1 + gcdSECURE_CACHE_SLOTS];
  123514. +
  123515. + /* Last known index for LINEAR mode. */
  123516. + gcskLOGICAL_CACHE_PTR cacheIndex;
  123517. +
  123518. + /* Current free slot for LINEAR mode. */
  123519. + gctUINT32 cacheFree;
  123520. +
  123521. + /* Time stamp for LINEAR mode. */
  123522. + gctUINT64 cacheStamp;
  123523. +
  123524. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  123525. + /* Hash table for HASH mode. */
  123526. + gcskLOGICAL_CACHE hash[256];
  123527. +#endif
  123528. +}
  123529. +gcskSECURE_CACHE;
  123530. +
  123531. +/*******************************************************************************
  123532. +***** Process Database Management *********************************************/
  123533. +
  123534. +typedef enum _gceDATABASE_TYPE
  123535. +{
  123536. + gcvDB_VIDEO_MEMORY = 1, /* Video memory created. */
  123537. + gcvDB_COMMAND_BUFFER, /* Command Buffer. */
  123538. + gcvDB_NON_PAGED, /* Non paged memory. */
  123539. + gcvDB_CONTIGUOUS, /* Contiguous memory. */
  123540. + gcvDB_SIGNAL, /* Signal. */
  123541. + gcvDB_VIDEO_MEMORY_LOCKED, /* Video memory locked. */
  123542. + gcvDB_CONTEXT, /* Context */
  123543. + gcvDB_IDLE, /* GPU idle. */
  123544. + gcvDB_MAP_MEMORY, /* Map memory */
  123545. + gcvDB_SHARED_INFO, /* Private data */
  123546. + gcvDB_MAP_USER_MEMORY, /* Map user memory */
  123547. + gcvDB_SYNC_POINT, /* Sync point. */
  123548. + gcvDB_VIDEO_MEMORY_RESERVED, /* Reserved video memory */
  123549. + gcvDB_VIDEO_MEMORY_CONTIGUOUS, /* Contiguous video memory */
  123550. + gcvDB_VIDEO_MEMORY_VIRTUAL, /* Virtual video memory */
  123551. +}
  123552. +gceDATABASE_TYPE;
  123553. +
  123554. +typedef struct _gcsDATABASE_RECORD * gcsDATABASE_RECORD_PTR;
  123555. +typedef struct _gcsDATABASE_RECORD
  123556. +{
  123557. + /* Pointer to kernel. */
  123558. + gckKERNEL kernel;
  123559. +
  123560. + /* Pointer to next database record. */
  123561. + gcsDATABASE_RECORD_PTR next;
  123562. +
  123563. + /* Type of record. */
  123564. + gceDATABASE_TYPE type;
  123565. +
  123566. + /* Data for record. */
  123567. + gctPOINTER data;
  123568. + gctPHYS_ADDR physical;
  123569. + gctSIZE_T bytes;
  123570. +}
  123571. +gcsDATABASE_RECORD;
  123572. +
  123573. +typedef struct _gcsDATABASE * gcsDATABASE_PTR;
  123574. +typedef struct _gcsDATABASE
  123575. +{
  123576. + /* Pointer to next entry is hash list. */
  123577. + gcsDATABASE_PTR next;
  123578. + gctSIZE_T slot;
  123579. +
  123580. + /* Process ID. */
  123581. + gctUINT32 processID;
  123582. +
  123583. + /* Sizes to query. */
  123584. + gcsDATABASE_COUNTERS vidMem;
  123585. + gcsDATABASE_COUNTERS nonPaged;
  123586. + gcsDATABASE_COUNTERS contiguous;
  123587. + gcsDATABASE_COUNTERS mapUserMemory;
  123588. + gcsDATABASE_COUNTERS mapMemory;
  123589. + gcsDATABASE_COUNTERS vidMemResv;
  123590. + gcsDATABASE_COUNTERS vidMemCont;
  123591. + gcsDATABASE_COUNTERS vidMemVirt;
  123592. +
  123593. + /* Idle time management. */
  123594. + gctUINT64 lastIdle;
  123595. + gctUINT64 idle;
  123596. +
  123597. + /* Pointer to database. */
  123598. + gcsDATABASE_RECORD_PTR list[48];
  123599. +
  123600. +#if gcdSECURE_USER
  123601. + /* Secure cache. */
  123602. + gcskSECURE_CACHE cache;
  123603. +#endif
  123604. +
  123605. + gctPOINTER handleDatabase;
  123606. + gctPOINTER handleDatabaseMutex;
  123607. +}
  123608. +gcsDATABASE;
  123609. +
  123610. +/* Create a process database that will contain all its allocations. */
  123611. +gceSTATUS
  123612. +gckKERNEL_CreateProcessDB(
  123613. + IN gckKERNEL Kernel,
  123614. + IN gctUINT32 ProcessID
  123615. + );
  123616. +
  123617. +/* Add a record to the process database. */
  123618. +gceSTATUS
  123619. +gckKERNEL_AddProcessDB(
  123620. + IN gckKERNEL Kernel,
  123621. + IN gctUINT32 ProcessID,
  123622. + IN gceDATABASE_TYPE Type,
  123623. + IN gctPOINTER Pointer,
  123624. + IN gctPHYS_ADDR Physical,
  123625. + IN gctSIZE_T Size
  123626. + );
  123627. +
  123628. +/* Remove a record to the process database. */
  123629. +gceSTATUS
  123630. +gckKERNEL_RemoveProcessDB(
  123631. + IN gckKERNEL Kernel,
  123632. + IN gctUINT32 ProcessID,
  123633. + IN gceDATABASE_TYPE Type,
  123634. + IN gctPOINTER Pointer
  123635. + );
  123636. +
  123637. +/* Destroy the process database. */
  123638. +gceSTATUS
  123639. +gckKERNEL_DestroyProcessDB(
  123640. + IN gckKERNEL Kernel,
  123641. + IN gctUINT32 ProcessID
  123642. + );
  123643. +
  123644. +/* Find a record to the process database. */
  123645. +gceSTATUS
  123646. +gckKERNEL_FindProcessDB(
  123647. + IN gckKERNEL Kernel,
  123648. + IN gctUINT32 ProcessID,
  123649. + IN gctUINT32 ThreadID,
  123650. + IN gceDATABASE_TYPE Type,
  123651. + IN gctPOINTER Pointer,
  123652. + OUT gcsDATABASE_RECORD_PTR Record
  123653. + );
  123654. +
  123655. +/* Query the process database. */
  123656. +gceSTATUS
  123657. +gckKERNEL_QueryProcessDB(
  123658. + IN gckKERNEL Kernel,
  123659. + IN gctUINT32 ProcessID,
  123660. + IN gctBOOL LastProcessID,
  123661. + IN gceDATABASE_TYPE Type,
  123662. + OUT gcuDATABASE_INFO * Info
  123663. + );
  123664. +
  123665. +/* Dump the process database. */
  123666. +gceSTATUS
  123667. +gckKERNEL_DumpProcessDB(
  123668. + IN gckKERNEL Kernel
  123669. + );
  123670. +
  123671. +/* ID database */
  123672. +gceSTATUS
  123673. +gckKERNEL_CreateIntegerDatabase(
  123674. + IN gckKERNEL Kernel,
  123675. + OUT gctPOINTER * Database
  123676. + );
  123677. +
  123678. +gceSTATUS
  123679. +gckKERNEL_DestroyIntegerDatabase(
  123680. + IN gckKERNEL Kernel,
  123681. + IN gctPOINTER Database
  123682. + );
  123683. +
  123684. +gceSTATUS
  123685. +gckKERNEL_AllocateIntegerId(
  123686. + IN gctPOINTER Database,
  123687. + IN gctPOINTER Pointer,
  123688. + OUT gctUINT32 * Id
  123689. + );
  123690. +
  123691. +gceSTATUS
  123692. +gckKERNEL_FreeIntegerId(
  123693. + IN gctPOINTER Database,
  123694. + IN gctUINT32 Id
  123695. + );
  123696. +
  123697. +gceSTATUS
  123698. +gckKERNEL_QueryIntegerId(
  123699. + IN gctPOINTER Database,
  123700. + IN gctUINT32 Id,
  123701. + OUT gctPOINTER * Pointer
  123702. + );
  123703. +
  123704. +gctUINT32
  123705. +gckKERNEL_AllocateNameFromPointer(
  123706. + IN gckKERNEL Kernel,
  123707. + IN gctPOINTER Pointer
  123708. + );
  123709. +
  123710. +gctPOINTER
  123711. +gckKERNEL_QueryPointerFromName(
  123712. + IN gckKERNEL Kernel,
  123713. + IN gctUINT32 Name
  123714. + );
  123715. +
  123716. +gceSTATUS
  123717. +gckKERNEL_DeleteName(
  123718. + IN gckKERNEL Kernel,
  123719. + IN gctUINT32 Name
  123720. + );
  123721. +
  123722. +#if gcdSECURE_USER
  123723. +/* Get secure cache from the process database. */
  123724. +gceSTATUS
  123725. +gckKERNEL_GetProcessDBCache(
  123726. + IN gckKERNEL Kernel,
  123727. + IN gctUINT32 ProcessID,
  123728. + OUT gcskSECURE_CACHE_PTR * Cache
  123729. + );
  123730. +#endif
  123731. +
  123732. +/*******************************************************************************
  123733. +********* Timer Management ****************************************************/
  123734. +typedef struct _gcsTIMER * gcsTIMER_PTR;
  123735. +typedef struct _gcsTIMER
  123736. +{
  123737. + /* Start and Stop time holders. */
  123738. + gctUINT64 startTime;
  123739. + gctUINT64 stopTime;
  123740. +}
  123741. +gcsTIMER;
  123742. +
  123743. +/******************************************************************************\
  123744. +********************************** Structures **********************************
  123745. +\******************************************************************************/
  123746. +
  123747. +/* gckDB object. */
  123748. +struct _gckDB
  123749. +{
  123750. + /* Database management. */
  123751. + gcsDATABASE_PTR db[16];
  123752. + gctPOINTER dbMutex;
  123753. + gcsDATABASE_PTR freeDatabase;
  123754. + gcsDATABASE_RECORD_PTR freeRecord;
  123755. + gcsDATABASE_PTR lastDatabase;
  123756. + gctUINT32 lastProcessID;
  123757. + gctUINT64 lastIdle;
  123758. + gctUINT64 idleTime;
  123759. + gctUINT64 lastSlowdown;
  123760. + gctUINT64 lastSlowdownIdle;
  123761. + /* ID - Pointer database*/
  123762. + gctPOINTER pointerDatabase;
  123763. + gctPOINTER pointerDatabaseMutex;
  123764. +};
  123765. +
  123766. +#if gcdVIRTUAL_COMMAND_BUFFER
  123767. +typedef struct _gckVIRTUAL_COMMAND_BUFFER * gckVIRTUAL_COMMAND_BUFFER_PTR;
  123768. +typedef struct _gckVIRTUAL_COMMAND_BUFFER
  123769. +{
  123770. + gctPHYS_ADDR physical;
  123771. + gctPOINTER userLogical;
  123772. + gctPOINTER kernelLogical;
  123773. + gctSIZE_T pageCount;
  123774. + gctPOINTER pageTable;
  123775. + gctUINT32 gpuAddress;
  123776. + gctUINT pid;
  123777. + gckVIRTUAL_COMMAND_BUFFER_PTR next;
  123778. + gckVIRTUAL_COMMAND_BUFFER_PTR prev;
  123779. + gckKERNEL kernel;
  123780. +}
  123781. +gckVIRTUAL_COMMAND_BUFFER;
  123782. +#endif
  123783. +
  123784. +/* gckKERNEL object. */
  123785. +struct _gckKERNEL
  123786. +{
  123787. + /* Object. */
  123788. + gcsOBJECT object;
  123789. +
  123790. + /* Pointer to gckOS object. */
  123791. + gckOS os;
  123792. +
  123793. + /* Core */
  123794. + gceCORE core;
  123795. +
  123796. + /* Pointer to gckHARDWARE object. */
  123797. + gckHARDWARE hardware;
  123798. +
  123799. + /* Pointer to gckCOMMAND object. */
  123800. + gckCOMMAND command;
  123801. +
  123802. + /* Pointer to gckEVENT object. */
  123803. + gckEVENT eventObj;
  123804. +
  123805. + /* Pointer to context. */
  123806. + gctPOINTER context;
  123807. +
  123808. + /* Pointer to gckMMU object. */
  123809. + gckMMU mmu;
  123810. +
  123811. + /* Arom holding number of clients. */
  123812. + gctPOINTER atomClients;
  123813. +
  123814. +#if VIVANTE_PROFILER
  123815. + /* Enable profiling */
  123816. + gctBOOL profileEnable;
  123817. +
  123818. + /* Clear profile register or not*/
  123819. + gctBOOL profileCleanRegister;
  123820. +
  123821. +#endif
  123822. +
  123823. +#ifdef QNX_SINGLE_THREADED_DEBUGGING
  123824. + gctPOINTER debugMutex;
  123825. +#endif
  123826. +
  123827. + /* Database management. */
  123828. + gckDB db;
  123829. + gctBOOL dbCreated;
  123830. +
  123831. +#if gcdENABLE_RECOVERY
  123832. + gctPOINTER resetFlagClearTimer;
  123833. + gctPOINTER resetAtom;
  123834. + gctUINT64 resetTimeStamp;
  123835. +#endif
  123836. +
  123837. + /* Pointer to gckEVENT object. */
  123838. + gcsTIMER timers[8];
  123839. + gctUINT32 timeOut;
  123840. +
  123841. +#if gcdENABLE_VG
  123842. + gckVGKERNEL vg;
  123843. +#endif
  123844. +
  123845. +#if gcdVIRTUAL_COMMAND_BUFFER
  123846. + gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferHead;
  123847. + gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferTail;
  123848. + gctPOINTER virtualBufferLock;
  123849. +#endif
  123850. +
  123851. +#if gcdDVFS
  123852. + gckDVFS dvfs;
  123853. +#endif
  123854. +
  123855. +#if gcdANDROID_NATIVE_FENCE_SYNC
  123856. + gctHANDLE timeline;
  123857. +#endif
  123858. +
  123859. + spinlock_t irq_lock;
  123860. +};
  123861. +
  123862. +struct _FrequencyHistory
  123863. +{
  123864. + gctUINT32 frequency;
  123865. + gctUINT32 count;
  123866. +};
  123867. +
  123868. +/* gckDVFS object. */
  123869. +struct _gckDVFS
  123870. +{
  123871. + gckOS os;
  123872. + gckHARDWARE hardware;
  123873. + gctPOINTER timer;
  123874. + gctUINT32 pollingTime;
  123875. + gctBOOL stop;
  123876. + gctUINT32 totalConfig;
  123877. + gctUINT32 loads[8];
  123878. + gctUINT8 currentScale;
  123879. + struct _FrequencyHistory frequencyHistory[16];
  123880. +};
  123881. +
  123882. +/* gckCOMMAND object. */
  123883. +struct _gckCOMMAND
  123884. +{
  123885. + /* Object. */
  123886. + gcsOBJECT object;
  123887. +
  123888. + /* Pointer to required object. */
  123889. + gckKERNEL kernel;
  123890. + gckOS os;
  123891. +
  123892. + /* Number of bytes per page. */
  123893. + gctSIZE_T pageSize;
  123894. +
  123895. + /* Current pipe select. */
  123896. + gcePIPE_SELECT pipeSelect;
  123897. +
  123898. + /* Command queue running flag. */
  123899. + gctBOOL running;
  123900. +
  123901. + /* Idle flag and commit stamp. */
  123902. + gctBOOL idle;
  123903. + gctUINT64 commitStamp;
  123904. +
  123905. + /* Command queue mutex. */
  123906. + gctPOINTER mutexQueue;
  123907. +
  123908. + /* Context switching mutex. */
  123909. + gctPOINTER mutexContext;
  123910. +
  123911. +#if VIVANTE_PROFILER_CONTEXT
  123912. + /* Context sequence mutex. */
  123913. + gctPOINTER mutexContextSeq;
  123914. +#endif
  123915. +
  123916. + /* Command queue power semaphore. */
  123917. + gctPOINTER powerSemaphore;
  123918. +
  123919. + /* Current command queue. */
  123920. + struct _gcskCOMMAND_QUEUE
  123921. + {
  123922. + gctSIGNAL signal;
  123923. + gctPHYS_ADDR physical;
  123924. + gctPOINTER logical;
  123925. + }
  123926. + queues[gcdCOMMAND_QUEUES];
  123927. +
  123928. + gctPHYS_ADDR physical;
  123929. + gctPOINTER logical;
  123930. + gctUINT32 offset;
  123931. + gctINT index;
  123932. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  123933. + gctUINT wrapCount;
  123934. +#endif
  123935. +
  123936. + /* The command queue is new. */
  123937. + gctBOOL newQueue;
  123938. +
  123939. + /* Context management. */
  123940. + gckCONTEXT currContext;
  123941. +
  123942. + /* Pointer to last WAIT command. */
  123943. + gctPHYS_ADDR waitPhysical;
  123944. + gctPOINTER waitLogical;
  123945. + gctSIZE_T waitSize;
  123946. +
  123947. + /* Command buffer alignment. */
  123948. + gctSIZE_T alignment;
  123949. + gctSIZE_T reservedHead;
  123950. + gctSIZE_T reservedTail;
  123951. +
  123952. + /* Commit counter. */
  123953. + gctPOINTER atomCommit;
  123954. +
  123955. + /* Kernel process ID. */
  123956. + gctUINT32 kernelProcessID;
  123957. +
  123958. + /* End Event signal. */
  123959. + gctSIGNAL endEventSignal;
  123960. +
  123961. +#if gcdSECURE_USER
  123962. + /* Hint array copy buffer. */
  123963. + gctBOOL hintArrayAllocated;
  123964. + gctUINT hintArraySize;
  123965. + gctUINT32_PTR hintArray;
  123966. +#endif
  123967. +};
  123968. +
  123969. +typedef struct _gcsEVENT * gcsEVENT_PTR;
  123970. +
  123971. +/* Structure holding one event to be processed. */
  123972. +typedef struct _gcsEVENT
  123973. +{
  123974. + /* Pointer to next event in queue. */
  123975. + gcsEVENT_PTR next;
  123976. +
  123977. + /* Event information. */
  123978. + gcsHAL_INTERFACE info;
  123979. +
  123980. + /* Process ID owning the event. */
  123981. + gctUINT32 processID;
  123982. +
  123983. +#ifdef __QNXNTO__
  123984. + /* Kernel. */
  123985. + gckKERNEL kernel;
  123986. +#endif
  123987. +
  123988. + gctBOOL fromKernel;
  123989. +}
  123990. +gcsEVENT;
  123991. +
  123992. +/* Structure holding a list of events to be processed by an interrupt. */
  123993. +typedef struct _gcsEVENT_QUEUE * gcsEVENT_QUEUE_PTR;
  123994. +typedef struct _gcsEVENT_QUEUE
  123995. +{
  123996. + /* Time stamp. */
  123997. + gctUINT64 stamp;
  123998. +
  123999. + /* Source of the event. */
  124000. + gceKERNEL_WHERE source;
  124001. +
  124002. + /* Pointer to head of event queue. */
  124003. + gcsEVENT_PTR head;
  124004. +
  124005. + /* Pointer to tail of event queue. */
  124006. + gcsEVENT_PTR tail;
  124007. +
  124008. + /* Next list of events. */
  124009. + gcsEVENT_QUEUE_PTR next;
  124010. +}
  124011. +gcsEVENT_QUEUE;
  124012. +
  124013. +/*
  124014. + gcdREPO_LIST_COUNT defines the maximum number of event queues with different
  124015. + hardware module sources that may coexist at the same time. Only two sources
  124016. + are supported - gcvKERNEL_COMMAND and gcvKERNEL_PIXEL. gcvKERNEL_COMMAND
  124017. + source is used only for managing the kernel command queue and is only issued
  124018. + when the current command queue gets full. Since we commit event queues every
  124019. + time we commit command buffers, in the worst case we can have up to three
  124020. + pending event queues:
  124021. + - gcvKERNEL_PIXEL
  124022. + - gcvKERNEL_COMMAND (queue overflow)
  124023. + - gcvKERNEL_PIXEL
  124024. +*/
  124025. +#define gcdREPO_LIST_COUNT 3
  124026. +
  124027. +/* gckEVENT object. */
  124028. +struct _gckEVENT
  124029. +{
  124030. + /* The object. */
  124031. + gcsOBJECT object;
  124032. +
  124033. + /* Pointer to required objects. */
  124034. + gckOS os;
  124035. + gckKERNEL kernel;
  124036. +
  124037. + /* Time stamp. */
  124038. + gctUINT64 stamp;
  124039. + gctUINT64 lastCommitStamp;
  124040. +
  124041. + /* Queue mutex. */
  124042. + gctPOINTER eventQueueMutex;
  124043. +
  124044. + /* Array of event queues. */
  124045. + gcsEVENT_QUEUE queues[30];
  124046. + gctUINT8 lastID;
  124047. + gctPOINTER freeAtom;
  124048. +
  124049. + /* Pending events. */
  124050. +#if gcdSMP
  124051. + gctPOINTER pending;
  124052. +#else
  124053. + volatile gctUINT pending;
  124054. +#endif
  124055. +
  124056. + /* List of free event structures and its mutex. */
  124057. + gcsEVENT_PTR freeEventList;
  124058. + gctSIZE_T freeEventCount;
  124059. + gctPOINTER freeEventMutex;
  124060. +
  124061. + /* Event queues. */
  124062. + gcsEVENT_QUEUE_PTR queueHead;
  124063. + gcsEVENT_QUEUE_PTR queueTail;
  124064. + gcsEVENT_QUEUE_PTR freeList;
  124065. + gcsEVENT_QUEUE repoList[gcdREPO_LIST_COUNT];
  124066. + gctPOINTER eventListMutex;
  124067. +
  124068. + gctPOINTER submitTimer;
  124069. +
  124070. + volatile gctBOOL inNotify;
  124071. +};
  124072. +
  124073. +/* Free all events belonging to a process. */
  124074. +gceSTATUS
  124075. +gckEVENT_FreeProcess(
  124076. + IN gckEVENT Event,
  124077. + IN gctUINT32 ProcessID
  124078. + );
  124079. +
  124080. +gceSTATUS
  124081. +gckEVENT_Stop(
  124082. + IN gckEVENT Event,
  124083. + IN gctUINT32 ProcessID,
  124084. + IN gctPHYS_ADDR Handle,
  124085. + IN gctPOINTER Logical,
  124086. + IN gctSIGNAL Signal,
  124087. + IN OUT gctSIZE_T * waitSize
  124088. + );
  124089. +
  124090. +gceSTATUS
  124091. +gckEVENT_WaitEmpty(
  124092. + IN gckEVENT Event
  124093. + );
  124094. +
  124095. +/* gcuVIDMEM_NODE structure. */
  124096. +typedef union _gcuVIDMEM_NODE
  124097. +{
  124098. + /* Allocated from gckVIDMEM. */
  124099. + struct _gcsVIDMEM_NODE_VIDMEM
  124100. + {
  124101. + /* Owner of this node. */
  124102. + gckVIDMEM memory;
  124103. +
  124104. + /* Dual-linked list of nodes. */
  124105. + gcuVIDMEM_NODE_PTR next;
  124106. + gcuVIDMEM_NODE_PTR prev;
  124107. +
  124108. + /* Dual linked list of free nodes. */
  124109. + gcuVIDMEM_NODE_PTR nextFree;
  124110. + gcuVIDMEM_NODE_PTR prevFree;
  124111. +
  124112. + /* Information for this node. */
  124113. + gctUINT32 offset;
  124114. + gctSIZE_T bytes;
  124115. + gctUINT32 alignment;
  124116. +
  124117. +#ifdef __QNXNTO__
  124118. + /* Client/server vaddr (mapped using mmap_join). */
  124119. + gctPOINTER logical;
  124120. +#endif
  124121. +
  124122. + /* Locked counter. */
  124123. + gctINT32 locked;
  124124. +
  124125. + /* Memory pool. */
  124126. + gcePOOL pool;
  124127. + gctUINT32 physical;
  124128. +
  124129. + /* Process ID owning this memory. */
  124130. + gctUINT32 processID;
  124131. +
  124132. + /* Prevent compositor from freeing until client unlocks. */
  124133. + gctBOOL freePending;
  124134. +
  124135. + /* */
  124136. + gcsVIDMEM_NODE_SHARED_INFO sharedInfo;
  124137. +
  124138. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  124139. + gctPOINTER kernelVirtual;
  124140. +#endif
  124141. +
  124142. + /* Surface type. */
  124143. + gceSURF_TYPE type;
  124144. + }
  124145. + VidMem;
  124146. +
  124147. + /* Allocated from gckOS. */
  124148. + struct _gcsVIDMEM_NODE_VIRTUAL
  124149. + {
  124150. + /* Pointer to gckKERNEL object. */
  124151. + gckKERNEL kernel;
  124152. +
  124153. + /* Information for this node. */
  124154. + /* Contiguously allocated? */
  124155. + gctBOOL contiguous;
  124156. + /* mdl record pointer... a kmalloc address. Process agnostic. */
  124157. + gctPHYS_ADDR physical;
  124158. + gctSIZE_T bytes;
  124159. + /* do_mmap_pgoff address... mapped per-process. */
  124160. + gctPOINTER logical;
  124161. +
  124162. + /* Page table information. */
  124163. + /* Used only when node is not contiguous */
  124164. + gctSIZE_T pageCount;
  124165. +
  124166. + /* Used only when node is not contiguous */
  124167. + gctPOINTER pageTables[gcdMAX_GPU_COUNT];
  124168. + /* Pointer to gckKERNEL object who lock this. */
  124169. + gckKERNEL lockKernels[gcdMAX_GPU_COUNT];
  124170. + /* Actual physical address */
  124171. + gctUINT32 addresses[gcdMAX_GPU_COUNT];
  124172. +
  124173. + /* Mutex. */
  124174. + gctPOINTER mutex;
  124175. +
  124176. + /* Locked counter. */
  124177. + gctINT32 lockeds[gcdMAX_GPU_COUNT];
  124178. +
  124179. +#ifdef __QNXNTO__
  124180. + /* Single linked list of nodes. */
  124181. + gcuVIDMEM_NODE_PTR next;
  124182. +
  124183. + /* Unlock pending flag. */
  124184. + gctBOOL unlockPendings[gcdMAX_GPU_COUNT];
  124185. +
  124186. + /* Free pending flag. */
  124187. + gctBOOL freePending;
  124188. +#endif
  124189. +
  124190. + /* Process ID owning this memory. */
  124191. + gctUINT32 processID;
  124192. +
  124193. + /* Owner process sets freed to true
  124194. + * when it trys to free a locked
  124195. + * node */
  124196. + gctBOOL freed;
  124197. +
  124198. + /* */
  124199. + gcsVIDMEM_NODE_SHARED_INFO sharedInfo;
  124200. +
  124201. + /* Surface type. */
  124202. + gceSURF_TYPE type;
  124203. + }
  124204. + Virtual;
  124205. +}
  124206. +gcuVIDMEM_NODE;
  124207. +
  124208. +/* gckVIDMEM object. */
  124209. +struct _gckVIDMEM
  124210. +{
  124211. + /* Object. */
  124212. + gcsOBJECT object;
  124213. +
  124214. + /* Pointer to gckOS object. */
  124215. + gckOS os;
  124216. +
  124217. + /* Information for this video memory heap. */
  124218. + gctUINT32 baseAddress;
  124219. + gctSIZE_T bytes;
  124220. + gctSIZE_T freeBytes;
  124221. +
  124222. + /* Mapping for each type of surface. */
  124223. + gctINT mapping[gcvSURF_NUM_TYPES];
  124224. +
  124225. + /* Sentinel nodes for up to 8 banks. */
  124226. + gcuVIDMEM_NODE sentinel[8];
  124227. +
  124228. + /* Allocation threshold. */
  124229. + gctSIZE_T threshold;
  124230. +
  124231. + /* The heap mutex. */
  124232. + gctPOINTER mutex;
  124233. +
  124234. +#if gcdUSE_VIDMEM_PER_PID
  124235. + /* The Pid this VidMem belongs to. */
  124236. + gctUINT32 pid;
  124237. +
  124238. + struct _gckVIDMEM* next;
  124239. +#endif
  124240. +};
  124241. +
  124242. +/* gckMMU object. */
  124243. +struct _gckMMU
  124244. +{
  124245. + /* The object. */
  124246. + gcsOBJECT object;
  124247. +
  124248. + /* Pointer to gckOS object. */
  124249. + gckOS os;
  124250. +
  124251. + /* Pointer to gckHARDWARE object. */
  124252. + gckHARDWARE hardware;
  124253. +
  124254. + /* The page table mutex. */
  124255. + gctPOINTER pageTableMutex;
  124256. +
  124257. + /* Page table information. */
  124258. + gctSIZE_T pageTableSize;
  124259. + gctPHYS_ADDR pageTablePhysical;
  124260. + gctUINT32_PTR pageTableLogical;
  124261. + gctUINT32 pageTableEntries;
  124262. +
  124263. + /* Master TLB information. */
  124264. + gctSIZE_T mtlbSize;
  124265. + gctPHYS_ADDR mtlbPhysical;
  124266. + gctUINT32_PTR mtlbLogical;
  124267. + gctUINT32 mtlbEntries;
  124268. +
  124269. + /* Free entries. */
  124270. + gctUINT32 heapList;
  124271. + gctBOOL freeNodes;
  124272. +
  124273. + gctPOINTER staticSTLB;
  124274. + gctBOOL enabled;
  124275. +
  124276. + gctUINT32 dynamicMappingStart;
  124277. +
  124278. +#ifdef __QNXNTO__
  124279. + /* Single linked list of all allocated nodes. */
  124280. + gctPOINTER nodeMutex;
  124281. + gcuVIDMEM_NODE_PTR nodeList;
  124282. +#endif
  124283. +};
  124284. +
  124285. +#if gcdVIRTUAL_COMMAND_BUFFER
  124286. +gceSTATUS
  124287. +gckOS_CreateKernelVirtualMapping(
  124288. + IN gctPHYS_ADDR Physical,
  124289. + OUT gctSIZE_T * PageCount,
  124290. + OUT gctPOINTER * Logical
  124291. + );
  124292. +
  124293. +gceSTATUS
  124294. +gckOS_DestroyKernelVirtualMapping(
  124295. + IN gctPOINTER Logical
  124296. + );
  124297. +
  124298. +gceSTATUS
  124299. +gckKERNEL_AllocateVirtualCommandBuffer(
  124300. + IN gckKERNEL Kernel,
  124301. + IN gctBOOL InUserSpace,
  124302. + IN OUT gctSIZE_T * Bytes,
  124303. + OUT gctPHYS_ADDR * Physical,
  124304. + OUT gctPOINTER * Logical
  124305. + );
  124306. +
  124307. +gceSTATUS
  124308. +gckKERNEL_DestroyVirtualCommandBuffer(
  124309. + IN gckKERNEL Kernel,
  124310. + IN gctSIZE_T Bytes,
  124311. + IN gctPHYS_ADDR Physical,
  124312. + IN gctPOINTER Logical
  124313. + );
  124314. +
  124315. +gceSTATUS
  124316. +gckKERNEL_GetGPUAddress(
  124317. + IN gckKERNEL Kernel,
  124318. + IN gctPOINTER Logical,
  124319. + OUT gctUINT32 * Address
  124320. + );
  124321. +
  124322. +gceSTATUS
  124323. +gckKERNEL_QueryGPUAddress(
  124324. + IN gckKERNEL Kernel,
  124325. + IN gctUINT32 GpuAddress,
  124326. + OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
  124327. + );
  124328. +#endif
  124329. +
  124330. +gceSTATUS
  124331. +gckKERNEL_AttachProcess(
  124332. + IN gckKERNEL Kernel,
  124333. + IN gctBOOL Attach
  124334. + );
  124335. +
  124336. +gceSTATUS
  124337. +gckKERNEL_AttachProcessEx(
  124338. + IN gckKERNEL Kernel,
  124339. + IN gctBOOL Attach,
  124340. + IN gctUINT32 PID
  124341. + );
  124342. +
  124343. +#if gcdSECURE_USER
  124344. +gceSTATUS
  124345. +gckKERNEL_MapLogicalToPhysical(
  124346. + IN gckKERNEL Kernel,
  124347. + IN gcskSECURE_CACHE_PTR Cache,
  124348. + IN OUT gctPOINTER * Data
  124349. + );
  124350. +
  124351. +gceSTATUS
  124352. +gckKERNEL_FlushTranslationCache(
  124353. + IN gckKERNEL Kernel,
  124354. + IN gcskSECURE_CACHE_PTR Cache,
  124355. + IN gctPOINTER Logical,
  124356. + IN gctSIZE_T Bytes
  124357. + );
  124358. +#endif
  124359. +
  124360. +gceSTATUS
  124361. +gckHARDWARE_QueryIdle(
  124362. + IN gckHARDWARE Hardware,
  124363. + OUT gctBOOL_PTR IsIdle
  124364. + );
  124365. +
  124366. +/******************************************************************************\
  124367. +******************************* gckCONTEXT Object *******************************
  124368. +\******************************************************************************/
  124369. +
  124370. +gceSTATUS
  124371. +gckCONTEXT_Construct(
  124372. + IN gckOS Os,
  124373. + IN gckHARDWARE Hardware,
  124374. + IN gctUINT32 ProcessID,
  124375. + OUT gckCONTEXT * Context
  124376. + );
  124377. +
  124378. +gceSTATUS
  124379. +gckCONTEXT_Destroy(
  124380. + IN gckCONTEXT Context
  124381. + );
  124382. +
  124383. +gceSTATUS
  124384. +gckCONTEXT_Update(
  124385. + IN gckCONTEXT Context,
  124386. + IN gctUINT32 ProcessID,
  124387. + IN gcsSTATE_DELTA_PTR StateDelta
  124388. + );
  124389. +
  124390. +#if gcdLINK_QUEUE_SIZE
  124391. +void
  124392. +gckLINKQUEUE_Enqueue(
  124393. + IN gckLINKQUEUE LinkQueue,
  124394. + IN gctUINT32 start,
  124395. + IN gctUINT32 end
  124396. + );
  124397. +
  124398. +void
  124399. +gckLINKQUEUE_GetData(
  124400. + IN gckLINKQUEUE LinkQueue,
  124401. + IN gctUINT32 Index,
  124402. + OUT gckLINKDATA * Data
  124403. + );
  124404. +#endif
  124405. +
  124406. +
  124407. +#ifdef __cplusplus
  124408. +}
  124409. +#endif
  124410. +
  124411. +#endif /* __gc_hal_kernel_h_ */
  124412. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c
  124413. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c 1970-01-01 01:00:00.000000000 +0100
  124414. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c 2014-08-20 19:23:53.562845855 +0200
  124415. @@ -0,0 +1,859 @@
  124416. +/****************************************************************************
  124417. +*
  124418. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  124419. +*
  124420. +* This program is free software; you can redistribute it and/or modify
  124421. +* it under the terms of the GNU General Public License as published by
  124422. +* the Free Software Foundation; either version 2 of the license, or
  124423. +* (at your option) any later version.
  124424. +*
  124425. +* This program is distributed in the hope that it will be useful,
  124426. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  124427. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  124428. +* GNU General Public License for more details.
  124429. +*
  124430. +* You should have received a copy of the GNU General Public License
  124431. +* along with this program; if not write to the Free Software
  124432. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  124433. +*
  124434. +*****************************************************************************/
  124435. +
  124436. +
  124437. +/**
  124438. +** @file
  124439. +** gckHEAP object for kernel HAL layer. The heap implemented here is an arena-
  124440. +** based memory allocation. An arena-based memory heap allocates data quickly
  124441. +** from specified arenas and reduces memory fragmentation.
  124442. +**
  124443. +*/
  124444. +#include "gc_hal_kernel_precomp.h"
  124445. +
  124446. +#define _GC_OBJ_ZONE gcvZONE_HEAP
  124447. +
  124448. +/*******************************************************************************
  124449. +***** Structures ***************************************************************
  124450. +*******************************************************************************/
  124451. +
  124452. +#define gcdIN_USE ((gcskNODE_PTR) ~0)
  124453. +
  124454. +typedef struct _gcskNODE * gcskNODE_PTR;
  124455. +typedef struct _gcskNODE
  124456. +{
  124457. + /* Number of byets in node. */
  124458. + gctSIZE_T bytes;
  124459. +
  124460. + /* Pointer to next free node, or gcvNULL to mark the node as freed, or
  124461. + ** gcdIN_USE to mark the node as used. */
  124462. + gcskNODE_PTR next;
  124463. +
  124464. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124465. + /* Time stamp of allocation. */
  124466. + gctUINT64 timeStamp;
  124467. +#endif
  124468. +}
  124469. +gcskNODE;
  124470. +
  124471. +typedef struct _gcskHEAP * gcskHEAP_PTR;
  124472. +typedef struct _gcskHEAP
  124473. +{
  124474. + /* Linked list. */
  124475. + gcskHEAP_PTR next;
  124476. + gcskHEAP_PTR prev;
  124477. +
  124478. + /* Heap size. */
  124479. + gctSIZE_T size;
  124480. +
  124481. + /* Free list. */
  124482. + gcskNODE_PTR freeList;
  124483. +}
  124484. +gcskHEAP;
  124485. +
  124486. +struct _gckHEAP
  124487. +{
  124488. + /* Object. */
  124489. + gcsOBJECT object;
  124490. +
  124491. + /* Pointer to a gckOS object. */
  124492. + gckOS os;
  124493. +
  124494. + /* Locking mutex. */
  124495. + gctPOINTER mutex;
  124496. +
  124497. + /* Allocation parameters. */
  124498. + gctSIZE_T allocationSize;
  124499. +
  124500. + /* Heap list. */
  124501. + gcskHEAP_PTR heap;
  124502. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124503. + gctUINT64 timeStamp;
  124504. +#endif
  124505. +
  124506. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  124507. + /* Profile information. */
  124508. + gctUINT32 allocCount;
  124509. + gctUINT64 allocBytes;
  124510. + gctUINT64 allocBytesMax;
  124511. + gctUINT64 allocBytesTotal;
  124512. + gctUINT32 heapCount;
  124513. + gctUINT32 heapCountMax;
  124514. + gctUINT64 heapMemory;
  124515. + gctUINT64 heapMemoryMax;
  124516. +#endif
  124517. +};
  124518. +
  124519. +/*******************************************************************************
  124520. +***** Static Support Functions *************************************************
  124521. +*******************************************************************************/
  124522. +
  124523. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124524. +static gctSIZE_T
  124525. +_DumpHeap(
  124526. + IN gcskHEAP_PTR Heap
  124527. + )
  124528. +{
  124529. + gctPOINTER p;
  124530. + gctSIZE_T leaked = 0;
  124531. +
  124532. + /* Start at first node. */
  124533. + for (p = Heap + 1;;)
  124534. + {
  124535. + /* Convert the pointer. */
  124536. + gcskNODE_PTR node = (gcskNODE_PTR) p;
  124537. +
  124538. + /* Check if this is a used node. */
  124539. + if (node->next == gcdIN_USE)
  124540. + {
  124541. + /* Print the leaking node. */
  124542. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_HEAP,
  124543. + "Detected leaking: node=0x%x bytes=%lu timeStamp=%llu "
  124544. + "(%08X %c%c%c%c)",
  124545. + node, node->bytes, node->timeStamp,
  124546. + ((gctUINT32_PTR) (node + 1))[0],
  124547. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[0]),
  124548. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[1]),
  124549. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[2]),
  124550. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[3]));
  124551. +
  124552. + /* Add leaking byte count. */
  124553. + leaked += node->bytes;
  124554. + }
  124555. +
  124556. + /* Test for end of heap. */
  124557. + if (node->bytes == 0)
  124558. + {
  124559. + break;
  124560. + }
  124561. +
  124562. + else
  124563. + {
  124564. + /* Move to next node. */
  124565. + p = (gctUINT8_PTR) node + node->bytes;
  124566. + }
  124567. + }
  124568. +
  124569. + /* Return the number of leaked bytes. */
  124570. + return leaked;
  124571. +}
  124572. +#endif
  124573. +
  124574. +static gceSTATUS
  124575. +_CompactKernelHeap(
  124576. + IN gckHEAP Heap
  124577. + )
  124578. +{
  124579. + gcskHEAP_PTR heap, next;
  124580. + gctPOINTER p;
  124581. + gcskHEAP_PTR freeList = gcvNULL;
  124582. +
  124583. + gcmkHEADER_ARG("Heap=0x%x", Heap);
  124584. +
  124585. + /* Walk all the heaps. */
  124586. + for (heap = Heap->heap; heap != gcvNULL; heap = next)
  124587. + {
  124588. + gcskNODE_PTR lastFree = gcvNULL;
  124589. +
  124590. + /* Zero out the free list. */
  124591. + heap->freeList = gcvNULL;
  124592. +
  124593. + /* Start at the first node. */
  124594. + for (p = (gctUINT8_PTR) (heap + 1);;)
  124595. + {
  124596. + /* Convert the pointer. */
  124597. + gcskNODE_PTR node = (gcskNODE_PTR) p;
  124598. +
  124599. + gcmkASSERT(p <= (gctPOINTER) ((gctUINT8_PTR) (heap + 1) + heap->size));
  124600. +
  124601. + /* Test if this node not used. */
  124602. + if (node->next != gcdIN_USE)
  124603. + {
  124604. + /* Test if this is the end of the heap. */
  124605. + if (node->bytes == 0)
  124606. + {
  124607. + break;
  124608. + }
  124609. +
  124610. + /* Test of this is the first free node. */
  124611. + else if (lastFree == gcvNULL)
  124612. + {
  124613. + /* Initialzie the free list. */
  124614. + heap->freeList = node;
  124615. + lastFree = node;
  124616. + }
  124617. +
  124618. + else
  124619. + {
  124620. + /* Test if this free node is contiguous with the previous
  124621. + ** free node. */
  124622. + if ((gctUINT8_PTR) lastFree + lastFree->bytes == p)
  124623. + {
  124624. + /* Just increase the size of the previous free node. */
  124625. + lastFree->bytes += node->bytes;
  124626. + }
  124627. + else
  124628. + {
  124629. + /* Add to linked list. */
  124630. + lastFree->next = node;
  124631. + lastFree = node;
  124632. + }
  124633. + }
  124634. + }
  124635. +
  124636. + /* Move to next node. */
  124637. + p = (gctUINT8_PTR) node + node->bytes;
  124638. + }
  124639. +
  124640. + /* Mark the end of the chain. */
  124641. + if (lastFree != gcvNULL)
  124642. + {
  124643. + lastFree->next = gcvNULL;
  124644. + }
  124645. +
  124646. + /* Get next heap. */
  124647. + next = heap->next;
  124648. +
  124649. + /* Check if the entire heap is free. */
  124650. + if ((heap->freeList != gcvNULL)
  124651. + && (heap->freeList->bytes == heap->size - gcmSIZEOF(gcskNODE))
  124652. + )
  124653. + {
  124654. + /* Remove the heap from the linked list. */
  124655. + if (heap->prev == gcvNULL)
  124656. + {
  124657. + Heap->heap = next;
  124658. + }
  124659. + else
  124660. + {
  124661. + heap->prev->next = next;
  124662. + }
  124663. +
  124664. + if (heap->next != gcvNULL)
  124665. + {
  124666. + heap->next->prev = heap->prev;
  124667. + }
  124668. +
  124669. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  124670. + /* Update profiling. */
  124671. + Heap->heapCount -= 1;
  124672. + Heap->heapMemory -= heap->size + gcmSIZEOF(gcskHEAP);
  124673. +#endif
  124674. +
  124675. + /* Add this heap to the list of heaps that need to be freed. */
  124676. + heap->next = freeList;
  124677. + freeList = heap;
  124678. + }
  124679. + }
  124680. +
  124681. + if (freeList != gcvNULL)
  124682. + {
  124683. + /* Release the mutex, remove any chance for a dead lock. */
  124684. + gcmkVERIFY_OK(
  124685. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  124686. +
  124687. + /* Free all heaps in the free list. */
  124688. + for (heap = freeList; heap != gcvNULL; heap = next)
  124689. + {
  124690. + /* Get pointer to the next heap. */
  124691. + next = heap->next;
  124692. +
  124693. + /* Free the heap. */
  124694. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HEAP,
  124695. + "Freeing heap 0x%x (%lu bytes)",
  124696. + heap, heap->size + gcmSIZEOF(gcskHEAP));
  124697. + gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, heap));
  124698. + }
  124699. +
  124700. + /* Acquire the mutex again. */
  124701. + gcmkVERIFY_OK(
  124702. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  124703. + }
  124704. +
  124705. + /* Success. */
  124706. + gcmkFOOTER_NO();
  124707. + return gcvSTATUS_OK;
  124708. +}
  124709. +
  124710. +/*******************************************************************************
  124711. +***** gckHEAP API Code *********************************************************
  124712. +*******************************************************************************/
  124713. +
  124714. +/*******************************************************************************
  124715. +**
  124716. +** gckHEAP_Construct
  124717. +**
  124718. +** Construct a new gckHEAP object.
  124719. +**
  124720. +** INPUT:
  124721. +**
  124722. +** gckOS Os
  124723. +** Pointer to a gckOS object.
  124724. +**
  124725. +** gctSIZE_T AllocationSize
  124726. +** Minimum size per arena.
  124727. +**
  124728. +** OUTPUT:
  124729. +**
  124730. +** gckHEAP * Heap
  124731. +** Pointer to a variable that will hold the pointer to the gckHEAP
  124732. +** object.
  124733. +*/
  124734. +gceSTATUS
  124735. +gckHEAP_Construct(
  124736. + IN gckOS Os,
  124737. + IN gctSIZE_T AllocationSize,
  124738. + OUT gckHEAP * Heap
  124739. + )
  124740. +{
  124741. + gceSTATUS status;
  124742. + gckHEAP heap = gcvNULL;
  124743. + gctPOINTER pointer = gcvNULL;
  124744. +
  124745. + gcmkHEADER_ARG("Os=0x%x AllocationSize=%lu", Os, AllocationSize);
  124746. +
  124747. + /* Verify the arguments. */
  124748. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  124749. + gcmkVERIFY_ARGUMENT(Heap != gcvNULL);
  124750. +
  124751. + /* Allocate the gckHEAP object. */
  124752. + gcmkONERROR(gckOS_AllocateMemory(Os,
  124753. + gcmSIZEOF(struct _gckHEAP),
  124754. + &pointer));
  124755. +
  124756. + heap = pointer;
  124757. +
  124758. + /* Initialize the gckHEAP object. */
  124759. + heap->object.type = gcvOBJ_HEAP;
  124760. + heap->os = Os;
  124761. + heap->allocationSize = AllocationSize;
  124762. + heap->heap = gcvNULL;
  124763. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124764. + heap->timeStamp = 0;
  124765. +#endif
  124766. +
  124767. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  124768. + /* Zero the counters. */
  124769. + heap->allocCount = 0;
  124770. + heap->allocBytes = 0;
  124771. + heap->allocBytesMax = 0;
  124772. + heap->allocBytesTotal = 0;
  124773. + heap->heapCount = 0;
  124774. + heap->heapCountMax = 0;
  124775. + heap->heapMemory = 0;
  124776. + heap->heapMemoryMax = 0;
  124777. +#endif
  124778. +
  124779. + /* Create the mutex. */
  124780. + gcmkONERROR(gckOS_CreateMutex(Os, &heap->mutex));
  124781. +
  124782. + /* Return the pointer to the gckHEAP object. */
  124783. + *Heap = heap;
  124784. +
  124785. + /* Success. */
  124786. + gcmkFOOTER_ARG("*Heap=0x%x", *Heap);
  124787. + return gcvSTATUS_OK;
  124788. +
  124789. +OnError:
  124790. + /* Roll back. */
  124791. + if (heap != gcvNULL)
  124792. + {
  124793. + /* Free the heap structure. */
  124794. + gcmkVERIFY_OK(gckOS_FreeMemory(Os, heap));
  124795. + }
  124796. +
  124797. + /* Return the status. */
  124798. + gcmkFOOTER();
  124799. + return status;
  124800. +}
  124801. +
  124802. +/*******************************************************************************
  124803. +**
  124804. +** gckHEAP_Destroy
  124805. +**
  124806. +** Destroy a gckHEAP object.
  124807. +**
  124808. +** INPUT:
  124809. +**
  124810. +** gckHEAP Heap
  124811. +** Pointer to a gckHEAP object to destroy.
  124812. +**
  124813. +** OUTPUT:
  124814. +**
  124815. +** Nothing.
  124816. +*/
  124817. +gceSTATUS
  124818. +gckHEAP_Destroy(
  124819. + IN gckHEAP Heap
  124820. + )
  124821. +{
  124822. + gcskHEAP_PTR heap;
  124823. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124824. + gctSIZE_T leaked = 0;
  124825. +#endif
  124826. +
  124827. + gcmkHEADER_ARG("Heap=0x%x", Heap);
  124828. +
  124829. + for (heap = Heap->heap; heap != gcvNULL; heap = Heap->heap)
  124830. + {
  124831. + /* Unlink heap from linked list. */
  124832. + Heap->heap = heap->next;
  124833. +
  124834. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124835. + /* Check for leaked memory. */
  124836. + leaked += _DumpHeap(heap);
  124837. +#endif
  124838. +
  124839. + /* Free the heap. */
  124840. + gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, heap));
  124841. + }
  124842. +
  124843. + /* Free the mutex. */
  124844. + gcmkVERIFY_OK(gckOS_DeleteMutex(Heap->os, Heap->mutex));
  124845. +
  124846. + /* Free the heap structure. */
  124847. + gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, Heap));
  124848. +
  124849. + /* Success. */
  124850. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124851. + gcmkFOOTER_ARG("leaked=%lu", leaked);
  124852. +#else
  124853. + gcmkFOOTER_NO();
  124854. +#endif
  124855. + return gcvSTATUS_OK;
  124856. +}
  124857. +
  124858. +/*******************************************************************************
  124859. +**
  124860. +** gckHEAP_Allocate
  124861. +**
  124862. +** Allocate data from the heap.
  124863. +**
  124864. +** INPUT:
  124865. +**
  124866. +** gckHEAP Heap
  124867. +** Pointer to a gckHEAP object.
  124868. +**
  124869. +** IN gctSIZE_T Bytes
  124870. +** Number of byte to allocate.
  124871. +**
  124872. +** OUTPUT:
  124873. +**
  124874. +** gctPOINTER * Memory
  124875. +** Pointer to a variable that will hold the address of the allocated
  124876. +** memory.
  124877. +*/
  124878. +gceSTATUS
  124879. +gckHEAP_Allocate(
  124880. + IN gckHEAP Heap,
  124881. + IN gctSIZE_T Bytes,
  124882. + OUT gctPOINTER * Memory
  124883. + )
  124884. +{
  124885. + gctBOOL acquired = gcvFALSE;
  124886. + gcskHEAP_PTR heap;
  124887. + gceSTATUS status;
  124888. + gctSIZE_T bytes;
  124889. + gcskNODE_PTR node, used, prevFree = gcvNULL;
  124890. + gctPOINTER memory = gcvNULL;
  124891. +
  124892. + gcmkHEADER_ARG("Heap=0x%x Bytes=%lu", Heap, Bytes);
  124893. +
  124894. + /* Verify the arguments. */
  124895. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  124896. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  124897. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  124898. +
  124899. + /* Determine number of bytes required for a node. */
  124900. + bytes = gcmALIGN(Bytes + gcmSIZEOF(gcskNODE), 8);
  124901. +
  124902. + /* Acquire the mutex. */
  124903. + gcmkONERROR(
  124904. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  124905. +
  124906. + acquired = gcvTRUE;
  124907. +
  124908. + /* Check if this allocation is bigger than the default allocation size. */
  124909. + if (bytes > Heap->allocationSize - gcmSIZEOF(gcskHEAP) - gcmSIZEOF(gcskNODE))
  124910. + {
  124911. + /* Adjust allocation size. */
  124912. + Heap->allocationSize = bytes * 2;
  124913. + }
  124914. +
  124915. + else if (Heap->heap != gcvNULL)
  124916. + {
  124917. + gctINT i;
  124918. +
  124919. + /* 2 retries, since we might need to compact. */
  124920. + for (i = 0; i < 2; ++i)
  124921. + {
  124922. + /* Walk all the heaps. */
  124923. + for (heap = Heap->heap; heap != gcvNULL; heap = heap->next)
  124924. + {
  124925. + /* Check if this heap has enough bytes to hold the request. */
  124926. + if (bytes <= heap->size - gcmSIZEOF(gcskNODE))
  124927. + {
  124928. + prevFree = gcvNULL;
  124929. +
  124930. + /* Walk the chain of free nodes. */
  124931. + for (node = heap->freeList;
  124932. + node != gcvNULL;
  124933. + node = node->next
  124934. + )
  124935. + {
  124936. + gcmkASSERT(node->next != gcdIN_USE);
  124937. +
  124938. + /* Check if this free node has enough bytes. */
  124939. + if (node->bytes >= bytes)
  124940. + {
  124941. + /* Use the node. */
  124942. + goto UseNode;
  124943. + }
  124944. +
  124945. + /* Save current free node for linked list management. */
  124946. + prevFree = node;
  124947. + }
  124948. + }
  124949. + }
  124950. +
  124951. + if (i == 0)
  124952. + {
  124953. + /* Compact the heap. */
  124954. + gcmkVERIFY_OK(_CompactKernelHeap(Heap));
  124955. +
  124956. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124957. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124958. + "===== KERNEL HEAP =====");
  124959. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124960. + "Number of allocations : %12u",
  124961. + Heap->allocCount);
  124962. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124963. + "Number of bytes allocated : %12llu",
  124964. + Heap->allocBytes);
  124965. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124966. + "Maximum allocation size : %12llu",
  124967. + Heap->allocBytesMax);
  124968. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124969. + "Total number of bytes allocated : %12llu",
  124970. + Heap->allocBytesTotal);
  124971. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124972. + "Number of heaps : %12u",
  124973. + Heap->heapCount);
  124974. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124975. + "Heap memory in bytes : %12llu",
  124976. + Heap->heapMemory);
  124977. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124978. + "Maximum number of heaps : %12u",
  124979. + Heap->heapCountMax);
  124980. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124981. + "Maximum heap memory in bytes : %12llu",
  124982. + Heap->heapMemoryMax);
  124983. +#endif
  124984. + }
  124985. + }
  124986. + }
  124987. +
  124988. + /* Release the mutex. */
  124989. + gcmkONERROR(
  124990. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  124991. +
  124992. + acquired = gcvFALSE;
  124993. +
  124994. + /* Allocate a new heap. */
  124995. + gcmkONERROR(
  124996. + gckOS_AllocateMemory(Heap->os,
  124997. + Heap->allocationSize,
  124998. + &memory));
  124999. +
  125000. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HEAP,
  125001. + "Allocated heap 0x%x (%lu bytes)",
  125002. + memory, Heap->allocationSize);
  125003. +
  125004. + /* Acquire the mutex. */
  125005. + gcmkONERROR(
  125006. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  125007. +
  125008. + acquired = gcvTRUE;
  125009. +
  125010. + /* Use the allocated memory as the heap. */
  125011. + heap = (gcskHEAP_PTR) memory;
  125012. +
  125013. + /* Insert this heap to the head of the chain. */
  125014. + heap->next = Heap->heap;
  125015. + heap->prev = gcvNULL;
  125016. + heap->size = Heap->allocationSize - gcmSIZEOF(gcskHEAP);
  125017. +
  125018. + if (heap->next != gcvNULL)
  125019. + {
  125020. + heap->next->prev = heap;
  125021. + }
  125022. + Heap->heap = heap;
  125023. +
  125024. + /* Mark the end of the heap. */
  125025. + node = (gcskNODE_PTR) ( (gctUINT8_PTR) heap
  125026. + + Heap->allocationSize
  125027. + - gcmSIZEOF(gcskNODE)
  125028. + );
  125029. + node->bytes = 0;
  125030. + node->next = gcvNULL;
  125031. +
  125032. + /* Create a free list. */
  125033. + node = (gcskNODE_PTR) (heap + 1);
  125034. + heap->freeList = node;
  125035. +
  125036. + /* Initialize the free list. */
  125037. + node->bytes = heap->size - gcmSIZEOF(gcskNODE);
  125038. + node->next = gcvNULL;
  125039. +
  125040. + /* No previous free. */
  125041. + prevFree = gcvNULL;
  125042. +
  125043. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  125044. + /* Update profiling. */
  125045. + Heap->heapCount += 1;
  125046. + Heap->heapMemory += Heap->allocationSize;
  125047. +
  125048. + if (Heap->heapCount > Heap->heapCountMax)
  125049. + {
  125050. + Heap->heapCountMax = Heap->heapCount;
  125051. + }
  125052. + if (Heap->heapMemory > Heap->heapMemoryMax)
  125053. + {
  125054. + Heap->heapMemoryMax = Heap->heapMemory;
  125055. + }
  125056. +#endif
  125057. +
  125058. +UseNode:
  125059. + /* Verify some stuff. */
  125060. + gcmkASSERT(heap != gcvNULL);
  125061. + gcmkASSERT(node != gcvNULL);
  125062. + gcmkASSERT(node->bytes >= bytes);
  125063. +
  125064. + if (heap->prev != gcvNULL)
  125065. + {
  125066. + /* Unlink the heap from the linked list. */
  125067. + heap->prev->next = heap->next;
  125068. + if (heap->next != gcvNULL)
  125069. + {
  125070. + heap->next->prev = heap->prev;
  125071. + }
  125072. +
  125073. + /* Move the heap to the front of the list. */
  125074. + heap->next = Heap->heap;
  125075. + heap->prev = gcvNULL;
  125076. + Heap->heap = heap;
  125077. + heap->next->prev = heap;
  125078. + }
  125079. +
  125080. + /* Check if there is enough free space left after usage for another free
  125081. + ** node. */
  125082. + if (node->bytes - bytes >= gcmSIZEOF(gcskNODE))
  125083. + {
  125084. + /* Allocated used space from the back of the free list. */
  125085. + used = (gcskNODE_PTR) ((gctUINT8_PTR) node + node->bytes - bytes);
  125086. +
  125087. + /* Adjust the number of free bytes. */
  125088. + node->bytes -= bytes;
  125089. + gcmkASSERT(node->bytes >= gcmSIZEOF(gcskNODE));
  125090. + }
  125091. + else
  125092. + {
  125093. + /* Remove this free list from the chain. */
  125094. + if (prevFree == gcvNULL)
  125095. + {
  125096. + heap->freeList = node->next;
  125097. + }
  125098. + else
  125099. + {
  125100. + prevFree->next = node->next;
  125101. + }
  125102. +
  125103. + /* Consume the entire free node. */
  125104. + used = (gcskNODE_PTR) node;
  125105. + bytes = node->bytes;
  125106. + }
  125107. +
  125108. + /* Mark node as used. */
  125109. + used->bytes = bytes;
  125110. + used->next = gcdIN_USE;
  125111. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  125112. + used->timeStamp = ++Heap->timeStamp;
  125113. +#endif
  125114. +
  125115. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  125116. + /* Update profile counters. */
  125117. + Heap->allocCount += 1;
  125118. + Heap->allocBytes += bytes;
  125119. + Heap->allocBytesMax = gcmMAX(Heap->allocBytes, Heap->allocBytesMax);
  125120. + Heap->allocBytesTotal += bytes;
  125121. +#endif
  125122. +
  125123. + /* Release the mutex. */
  125124. + gcmkVERIFY_OK(
  125125. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  125126. +
  125127. + /* Return pointer to memory. */
  125128. + *Memory = used + 1;
  125129. +
  125130. + /* Success. */
  125131. + gcmkFOOTER_ARG("*Memory=0x%x", *Memory);
  125132. + return gcvSTATUS_OK;
  125133. +
  125134. +OnError:
  125135. + if (acquired)
  125136. + {
  125137. + /* Release the mutex. */
  125138. + gcmkVERIFY_OK(
  125139. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  125140. + }
  125141. +
  125142. + if (memory != gcvNULL)
  125143. + {
  125144. + /* Free the heap memory. */
  125145. + gckOS_FreeMemory(Heap->os, memory);
  125146. + }
  125147. +
  125148. + /* Return the status. */
  125149. + gcmkFOOTER();
  125150. + return status;
  125151. +}
  125152. +
  125153. +/*******************************************************************************
  125154. +**
  125155. +** gckHEAP_Free
  125156. +**
  125157. +** Free allocated memory from the heap.
  125158. +**
  125159. +** INPUT:
  125160. +**
  125161. +** gckHEAP Heap
  125162. +** Pointer to a gckHEAP object.
  125163. +**
  125164. +** IN gctPOINTER Memory
  125165. +** Pointer to memory to free.
  125166. +**
  125167. +** OUTPUT:
  125168. +**
  125169. +** NOTHING.
  125170. +*/
  125171. +gceSTATUS
  125172. +gckHEAP_Free(
  125173. + IN gckHEAP Heap,
  125174. + IN gctPOINTER Memory
  125175. + )
  125176. +{
  125177. + gcskNODE_PTR node;
  125178. + gceSTATUS status;
  125179. +
  125180. + gcmkHEADER_ARG("Heap=0x%x Memory=0x%x", Heap, Memory);
  125181. +
  125182. + /* Verify the arguments. */
  125183. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  125184. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  125185. +
  125186. + /* Acquire the mutex. */
  125187. + gcmkONERROR(
  125188. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  125189. +
  125190. + /* Pointer to structure. */
  125191. + node = (gcskNODE_PTR) Memory - 1;
  125192. +
  125193. + /* Mark the node as freed. */
  125194. + node->next = gcvNULL;
  125195. +
  125196. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  125197. + /* Update profile counters. */
  125198. + Heap->allocBytes -= node->bytes;
  125199. +#endif
  125200. +
  125201. + /* Release the mutex. */
  125202. + gcmkVERIFY_OK(
  125203. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  125204. +
  125205. + /* Success. */
  125206. + gcmkFOOTER_NO();
  125207. + return gcvSTATUS_OK;
  125208. +
  125209. +OnError:
  125210. + /* Return the status. */
  125211. + gcmkFOOTER();
  125212. + return status;
  125213. +}
  125214. +
  125215. +#if VIVANTE_PROFILER
  125216. +gceSTATUS
  125217. +gckHEAP_ProfileStart(
  125218. + IN gckHEAP Heap
  125219. + )
  125220. +{
  125221. + gcmkHEADER_ARG("Heap=0x%x", Heap);
  125222. +
  125223. + /* Verify the arguments. */
  125224. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  125225. +
  125226. + /* Zero the counters. */
  125227. + Heap->allocCount = 0;
  125228. + Heap->allocBytes = 0;
  125229. + Heap->allocBytesMax = 0;
  125230. + Heap->allocBytesTotal = 0;
  125231. + Heap->heapCount = 0;
  125232. + Heap->heapCountMax = 0;
  125233. + Heap->heapMemory = 0;
  125234. + Heap->heapMemoryMax = 0;
  125235. +
  125236. + /* Success. */
  125237. + gcmkFOOTER_NO();
  125238. + return gcvSTATUS_OK;
  125239. +}
  125240. +
  125241. +gceSTATUS
  125242. +gckHEAP_ProfileEnd(
  125243. + IN gckHEAP Heap,
  125244. + IN gctCONST_STRING Title
  125245. + )
  125246. +{
  125247. + gcmkHEADER_ARG("Heap=0x%x Title=0x%x", Heap, Title);
  125248. +
  125249. + /* Verify the arguments. */
  125250. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  125251. + gcmkVERIFY_ARGUMENT(Title != gcvNULL);
  125252. +
  125253. + gcmkPRINT("");
  125254. + gcmkPRINT("=====[ HEAP - %s ]=====", Title);
  125255. + gcmkPRINT("Number of allocations : %12u", Heap->allocCount);
  125256. + gcmkPRINT("Number of bytes allocated : %12llu", Heap->allocBytes);
  125257. + gcmkPRINT("Maximum allocation size : %12llu", Heap->allocBytesMax);
  125258. + gcmkPRINT("Total number of bytes allocated : %12llu", Heap->allocBytesTotal);
  125259. + gcmkPRINT("Number of heaps : %12u", Heap->heapCount);
  125260. + gcmkPRINT("Heap memory in bytes : %12llu", Heap->heapMemory);
  125261. + gcmkPRINT("Maximum number of heaps : %12u", Heap->heapCountMax);
  125262. + gcmkPRINT("Maximum heap memory in bytes : %12llu", Heap->heapMemoryMax);
  125263. + gcmkPRINT("==============================================");
  125264. +
  125265. + /* Success. */
  125266. + gcmkFOOTER_NO();
  125267. + return gcvSTATUS_OK;
  125268. +}
  125269. +#endif /* VIVANTE_PROFILER */
  125270. +
  125271. +/*******************************************************************************
  125272. +***** Test Code ****************************************************************
  125273. +*******************************************************************************/
  125274. +
  125275. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c
  125276. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c 1970-01-01 01:00:00.000000000 +0100
  125277. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c 2014-08-20 19:23:53.562845855 +0200
  125278. @@ -0,0 +1,877 @@
  125279. +/****************************************************************************
  125280. +*
  125281. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  125282. +*
  125283. +* This program is free software; you can redistribute it and/or modify
  125284. +* it under the terms of the GNU General Public License as published by
  125285. +* the Free Software Foundation; either version 2 of the license, or
  125286. +* (at your option) any later version.
  125287. +*
  125288. +* This program is distributed in the hope that it will be useful,
  125289. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  125290. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  125291. +* GNU General Public License for more details.
  125292. +*
  125293. +* You should have received a copy of the GNU General Public License
  125294. +* along with this program; if not write to the Free Software
  125295. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  125296. +*
  125297. +*****************************************************************************/
  125298. +
  125299. +
  125300. +#include "gc_hal_kernel_precomp.h"
  125301. +
  125302. +#if gcdENABLE_VG
  125303. +
  125304. +/******************************************************************************\
  125305. +*********************** Support Functions and Definitions **********************
  125306. +\******************************************************************************/
  125307. +
  125308. +/* Interruot statistics will be accumulated if not zero. */
  125309. +#define gcmENABLE_INTERRUPT_STATISTICS 0
  125310. +
  125311. +#define _GC_OBJ_ZONE gcvZONE_INTERRUPT
  125312. +
  125313. +/* Object structure. */
  125314. +struct _gckVGINTERRUPT
  125315. +{
  125316. + /* Object. */
  125317. + gcsOBJECT object;
  125318. +
  125319. + /* gckVGKERNEL pointer. */
  125320. + gckVGKERNEL kernel;
  125321. +
  125322. + /* gckOS pointer. */
  125323. + gckOS os;
  125324. +
  125325. + /* Interrupt handlers. */
  125326. + gctINTERRUPT_HANDLER handlers[32];
  125327. +
  125328. + /* Main interrupt handler thread. */
  125329. + gctTHREAD handler;
  125330. + gctBOOL terminate;
  125331. +
  125332. + /* Interrupt FIFO. */
  125333. + gctSEMAPHORE fifoValid;
  125334. + gctUINT32 fifo[256];
  125335. + gctUINT fifoItems;
  125336. + gctUINT8 head;
  125337. + gctUINT8 tail;
  125338. +
  125339. + /* Interrupt statistics. */
  125340. +#if gcmENABLE_INTERRUPT_STATISTICS
  125341. + gctUINT maxFifoItems;
  125342. + gctUINT fifoOverflow;
  125343. + gctUINT maxSimultaneous;
  125344. + gctUINT multipleCount;
  125345. +#endif
  125346. +};
  125347. +
  125348. +
  125349. +/*******************************************************************************
  125350. +**
  125351. +** _ProcessInterrupt
  125352. +**
  125353. +** The interrupt processor.
  125354. +**
  125355. +** INPUT:
  125356. +**
  125357. +** ThreadParameter
  125358. +** Pointer to the gckVGINTERRUPT object.
  125359. +**
  125360. +** OUTPUT:
  125361. +**
  125362. +** Nothing.
  125363. +*/
  125364. +
  125365. +#if gcmENABLE_INTERRUPT_STATISTICS
  125366. +static void
  125367. +_ProcessInterrupt(
  125368. + gckVGINTERRUPT Interrupt,
  125369. + gctUINT_PTR TriggeredCount
  125370. + )
  125371. +#else
  125372. +static void
  125373. +_ProcessInterrupt(
  125374. + gckVGINTERRUPT Interrupt
  125375. + )
  125376. +#endif
  125377. +{
  125378. + gceSTATUS status;
  125379. + gctUINT32 triggered;
  125380. + gctUINT i;
  125381. +
  125382. + /* Advance to the next entry. */
  125383. + Interrupt->tail += 1;
  125384. + Interrupt->fifoItems -= 1;
  125385. +
  125386. + /* Get the interrupt value. */
  125387. + triggered = Interrupt->fifo[Interrupt->tail];
  125388. + gcmkASSERT(triggered != 0);
  125389. +
  125390. + gcmkTRACE_ZONE(
  125391. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125392. + "%s: triggered=0x%08X\n",
  125393. + __FUNCTION__,
  125394. + triggered
  125395. + );
  125396. +
  125397. + /* Walk through all possible interrupts. */
  125398. + for (i = 0; i < gcmSIZEOF(Interrupt->handlers); i += 1)
  125399. + {
  125400. + /* Test if interrupt happened. */
  125401. + if ((triggered & 1) == 1)
  125402. + {
  125403. +#if gcmENABLE_INTERRUPT_STATISTICS
  125404. + if (TriggeredCount != gcvNULL)
  125405. + {
  125406. + (* TriggeredCount) += 1;
  125407. + }
  125408. +#endif
  125409. +
  125410. + /* Make sure we have valid handler. */
  125411. + if (Interrupt->handlers[i] == gcvNULL)
  125412. + {
  125413. + gcmkTRACE(
  125414. + gcvLEVEL_ERROR,
  125415. + "%s: Interrupt %d isn't registered.\n",
  125416. + __FUNCTION__, i
  125417. + );
  125418. + }
  125419. + else
  125420. + {
  125421. + gcmkTRACE_ZONE(
  125422. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125423. + "%s: interrupt=%d\n",
  125424. + __FUNCTION__,
  125425. + i
  125426. + );
  125427. +
  125428. + /* Call the handler. */
  125429. + status = Interrupt->handlers[i] (Interrupt->kernel);
  125430. +
  125431. + if (gcmkIS_ERROR(status))
  125432. + {
  125433. + /* Failed to signal the semaphore. */
  125434. + gcmkTRACE(
  125435. + gcvLEVEL_ERROR,
  125436. + "%s: Error %d incrementing the semaphore #%d.\n",
  125437. + __FUNCTION__, status, i
  125438. + );
  125439. + }
  125440. + }
  125441. + }
  125442. +
  125443. + /* Next interrupt. */
  125444. + triggered >>= 1;
  125445. +
  125446. + /* No more interrupts to handle? */
  125447. + if (triggered == 0)
  125448. + {
  125449. + break;
  125450. + }
  125451. + }
  125452. +}
  125453. +
  125454. +
  125455. +/*******************************************************************************
  125456. +**
  125457. +** _MainInterruptHandler
  125458. +**
  125459. +** The main interrupt thread serves the interrupt FIFO and calls registered
  125460. +** handlers for the interrupts that occured. The handlers are called in the
  125461. +** sequence interrupts occured with the exception when multiple interrupts
  125462. +** occured at the same time. In that case the handler calls are "sorted" by
  125463. +** the interrupt number therefore giving the interrupts with lower numbers
  125464. +** higher priority.
  125465. +**
  125466. +** INPUT:
  125467. +**
  125468. +** ThreadParameter
  125469. +** Pointer to the gckVGINTERRUPT object.
  125470. +**
  125471. +** OUTPUT:
  125472. +**
  125473. +** Nothing.
  125474. +*/
  125475. +
  125476. +static gctTHREADFUNCRESULT gctTHREADFUNCTYPE
  125477. +_MainInterruptHandler(
  125478. + gctTHREADFUNCPARAMETER ThreadParameter
  125479. + )
  125480. +{
  125481. + gceSTATUS status;
  125482. + gckVGINTERRUPT interrupt;
  125483. +
  125484. +#if gcmENABLE_INTERRUPT_STATISTICS
  125485. + gctUINT count;
  125486. +#endif
  125487. +
  125488. + /* Cast the object. */
  125489. + interrupt = (gckVGINTERRUPT) ThreadParameter;
  125490. +
  125491. + /* Enter the loop. */
  125492. + while (gcvTRUE)
  125493. + {
  125494. + /* Wait for an interrupt. */
  125495. + status = gckOS_DecrementSemaphore(interrupt->os, interrupt->fifoValid);
  125496. +
  125497. + /* Error? */
  125498. + if (gcmkIS_ERROR(status))
  125499. + {
  125500. + break;
  125501. + }
  125502. +
  125503. + /* System termination request? */
  125504. + if (status == gcvSTATUS_TERMINATE)
  125505. + {
  125506. + break;
  125507. + }
  125508. +
  125509. + /* Driver is shutting down? */
  125510. + if (interrupt->terminate)
  125511. + {
  125512. + break;
  125513. + }
  125514. +
  125515. +#if gcmENABLE_INTERRUPT_STATISTICS
  125516. + /* Reset triggered count. */
  125517. + count = 0;
  125518. +
  125519. + /* Process the interrupt. */
  125520. + _ProcessInterrupt(interrupt, &count);
  125521. +
  125522. + /* Update conters. */
  125523. + if (count > interrupt->maxSimultaneous)
  125524. + {
  125525. + interrupt->maxSimultaneous = count;
  125526. + }
  125527. +
  125528. + if (count > 1)
  125529. + {
  125530. + interrupt->multipleCount += 1;
  125531. + }
  125532. +#else
  125533. + /* Process the interrupt. */
  125534. + _ProcessInterrupt(interrupt);
  125535. +#endif
  125536. + }
  125537. +
  125538. + return 0;
  125539. +}
  125540. +
  125541. +
  125542. +/*******************************************************************************
  125543. +**
  125544. +** _StartInterruptHandler / _StopInterruptHandler
  125545. +**
  125546. +** Main interrupt handler routine control.
  125547. +**
  125548. +** INPUT:
  125549. +**
  125550. +** ThreadParameter
  125551. +** Pointer to the gckVGINTERRUPT object.
  125552. +**
  125553. +** OUTPUT:
  125554. +**
  125555. +** Nothing.
  125556. +*/
  125557. +
  125558. +static gceSTATUS
  125559. +_StartInterruptHandler(
  125560. + gckVGINTERRUPT Interrupt
  125561. + )
  125562. +{
  125563. + gceSTATUS status, last;
  125564. +
  125565. + do
  125566. + {
  125567. + /* Objects must not be already created. */
  125568. + gcmkASSERT(Interrupt->fifoValid == gcvNULL);
  125569. + gcmkASSERT(Interrupt->handler == gcvNULL);
  125570. +
  125571. + /* Reset the termination request. */
  125572. + Interrupt->terminate = gcvFALSE;
  125573. +
  125574. +#if !gcdENABLE_INFINITE_SPEED_HW
  125575. + /* Construct the fifo semaphore. */
  125576. + gcmkERR_BREAK(gckOS_CreateSemaphoreVG(
  125577. + Interrupt->os, &Interrupt->fifoValid
  125578. + ));
  125579. +
  125580. + /* Start the interrupt handler thread. */
  125581. + gcmkERR_BREAK(gckOS_StartThread(
  125582. + Interrupt->os,
  125583. + _MainInterruptHandler,
  125584. + Interrupt,
  125585. + &Interrupt->handler
  125586. + ));
  125587. +#endif
  125588. +
  125589. + /* Success. */
  125590. + return gcvSTATUS_OK;
  125591. + }
  125592. + while (gcvFALSE);
  125593. +
  125594. + /* Roll back. */
  125595. + if (Interrupt->fifoValid != gcvNULL)
  125596. + {
  125597. + gcmkCHECK_STATUS(gckOS_DestroySemaphore(
  125598. + Interrupt->os, Interrupt->fifoValid
  125599. + ));
  125600. +
  125601. + Interrupt->fifoValid = gcvNULL;
  125602. + }
  125603. +
  125604. + /* Return the status. */
  125605. + return status;
  125606. +}
  125607. +
  125608. +static gceSTATUS
  125609. +_StopInterruptHandler(
  125610. + gckVGINTERRUPT Interrupt
  125611. + )
  125612. +{
  125613. + gceSTATUS status;
  125614. +
  125615. + do
  125616. + {
  125617. + /* Does the thread exist? */
  125618. + if (Interrupt->handler == gcvNULL)
  125619. + {
  125620. + /* The semaphore must be NULL as well. */
  125621. + gcmkASSERT(Interrupt->fifoValid == gcvNULL);
  125622. +
  125623. + /* Success. */
  125624. + status = gcvSTATUS_OK;
  125625. + break;
  125626. + }
  125627. +
  125628. + /* The semaphore must exist as well. */
  125629. + gcmkASSERT(Interrupt->fifoValid != gcvNULL);
  125630. +
  125631. + /* Set the termination request. */
  125632. + Interrupt->terminate = gcvTRUE;
  125633. +
  125634. + /* Unlock the thread. */
  125635. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  125636. + Interrupt->os, Interrupt->fifoValid
  125637. + ));
  125638. +
  125639. + /* Wait until the thread quits. */
  125640. + gcmkERR_BREAK(gckOS_StopThread(
  125641. + Interrupt->os,
  125642. + Interrupt->handler
  125643. + ));
  125644. +
  125645. + /* Destroy the semaphore. */
  125646. + gcmkERR_BREAK(gckOS_DestroySemaphore(
  125647. + Interrupt->os, Interrupt->fifoValid
  125648. + ));
  125649. +
  125650. + /* Reset handles. */
  125651. + Interrupt->handler = gcvNULL;
  125652. + Interrupt->fifoValid = gcvNULL;
  125653. + }
  125654. + while (gcvFALSE);
  125655. +
  125656. + /* Return the status. */
  125657. + return status;
  125658. +}
  125659. +
  125660. +
  125661. +/******************************************************************************\
  125662. +***************************** Interrupt Object API *****************************
  125663. +\******************************************************************************/
  125664. +
  125665. +/*******************************************************************************
  125666. +**
  125667. +** gckVGINTERRUPT_Construct
  125668. +**
  125669. +** Construct an interrupt object.
  125670. +**
  125671. +** INPUT:
  125672. +**
  125673. +** Kernel
  125674. +** Pointer to the gckVGKERNEL object.
  125675. +**
  125676. +** OUTPUT:
  125677. +**
  125678. +** Interrupt
  125679. +** Pointer to the new gckVGINTERRUPT object.
  125680. +*/
  125681. +
  125682. +gceSTATUS
  125683. +gckVGINTERRUPT_Construct(
  125684. + IN gckVGKERNEL Kernel,
  125685. + OUT gckVGINTERRUPT * Interrupt
  125686. + )
  125687. +{
  125688. + gceSTATUS status;
  125689. + gckVGINTERRUPT interrupt = gcvNULL;
  125690. +
  125691. + gcmkHEADER_ARG("Kernel=0x%x Interrupt=0x%x", Kernel, Interrupt);
  125692. +
  125693. + /* Verify argeuments. */
  125694. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  125695. + gcmkVERIFY_ARGUMENT(Interrupt != gcvNULL);
  125696. +
  125697. + do
  125698. + {
  125699. + /* Allocate the gckVGINTERRUPT structure. */
  125700. + gcmkERR_BREAK(gckOS_Allocate(
  125701. + Kernel->os,
  125702. + gcmSIZEOF(struct _gckVGINTERRUPT),
  125703. + (gctPOINTER *) &interrupt
  125704. + ));
  125705. +
  125706. + /* Reset the object data. */
  125707. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  125708. + interrupt, gcmSIZEOF(struct _gckVGINTERRUPT)
  125709. + ));
  125710. +
  125711. + /* Initialize the object. */
  125712. + interrupt->object.type = gcvOBJ_INTERRUPT;
  125713. +
  125714. + /* Initialize the object pointers. */
  125715. + interrupt->kernel = Kernel;
  125716. + interrupt->os = Kernel->os;
  125717. +
  125718. + /* Initialize the current FIFO position. */
  125719. + interrupt->head = (gctUINT8)~0;
  125720. + interrupt->tail = (gctUINT8)~0;
  125721. +
  125722. + /* Start the thread. */
  125723. + gcmkERR_BREAK(_StartInterruptHandler(interrupt));
  125724. +
  125725. + /* Return interrupt object. */
  125726. + *Interrupt = interrupt;
  125727. +
  125728. + gcmkFOOTER_ARG("*Interrup=0x%x", *Interrupt);
  125729. + /* Success. */
  125730. + return gcvSTATUS_OK;
  125731. + }
  125732. + while (gcvFALSE);
  125733. +
  125734. + /* Roll back. */
  125735. + if (interrupt != gcvNULL)
  125736. + {
  125737. + /* Free the gckVGINTERRUPT structure. */
  125738. + gcmkVERIFY_OK(gckOS_Free(interrupt->os, interrupt));
  125739. + }
  125740. +
  125741. + gcmkFOOTER();
  125742. +
  125743. + /* Return the status. */
  125744. + return status;
  125745. +}
  125746. +
  125747. +
  125748. +/*******************************************************************************
  125749. +**
  125750. +** gckVGINTERRUPT_Destroy
  125751. +**
  125752. +** Destroy an interrupt object.
  125753. +**
  125754. +** INPUT:
  125755. +**
  125756. +** Interrupt
  125757. +** Pointer to the gckVGINTERRUPT object to destroy.
  125758. +**
  125759. +** OUTPUT:
  125760. +**
  125761. +** Nothing.
  125762. +*/
  125763. +
  125764. +gceSTATUS
  125765. +gckVGINTERRUPT_Destroy(
  125766. + IN gckVGINTERRUPT Interrupt
  125767. + )
  125768. +{
  125769. + gceSTATUS status;
  125770. +
  125771. + gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
  125772. +
  125773. + /* Verify the arguments. */
  125774. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  125775. +
  125776. + do
  125777. + {
  125778. + /* Stop the interrupt thread. */
  125779. + gcmkERR_BREAK(_StopInterruptHandler(Interrupt));
  125780. +
  125781. + /* Mark the object as unknown. */
  125782. + Interrupt->object.type = gcvOBJ_UNKNOWN;
  125783. +
  125784. + /* Free the gckVGINTERRUPT structure. */
  125785. + gcmkERR_BREAK(gckOS_Free(Interrupt->os, Interrupt));
  125786. + }
  125787. + while (gcvFALSE);
  125788. +
  125789. + gcmkFOOTER();
  125790. +
  125791. + /* Return the status. */
  125792. + return status;
  125793. +}
  125794. +
  125795. +
  125796. +/*******************************************************************************
  125797. +**
  125798. +** gckVGINTERRUPT_DumpState
  125799. +**
  125800. +** Print the current state of the interrupt manager.
  125801. +**
  125802. +** INPUT:
  125803. +**
  125804. +** Interrupt
  125805. +** Pointer to a gckVGINTERRUPT object.
  125806. +**
  125807. +** OUTPUT:
  125808. +**
  125809. +** Nothing.
  125810. +*/
  125811. +
  125812. +#if gcvDEBUG
  125813. +gceSTATUS
  125814. +gckVGINTERRUPT_DumpState(
  125815. + IN gckVGINTERRUPT Interrupt
  125816. + )
  125817. +{
  125818. + gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
  125819. + /* Verify the arguments. */
  125820. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  125821. +
  125822. + /* Print the header. */
  125823. + gcmkTRACE_ZONE(
  125824. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125825. + "%s: INTERRUPT OBJECT STATUS\n",
  125826. + __FUNCTION__
  125827. + );
  125828. +
  125829. + /* Print statistics. */
  125830. +#if gcmENABLE_INTERRUPT_STATISTICS
  125831. + gcmkTRACE_ZONE(
  125832. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125833. + " Maximum number of FIFO items accumulated at a single time: %d\n",
  125834. + Interrupt->maxFifoItems
  125835. + );
  125836. +
  125837. + gcmkTRACE_ZONE(
  125838. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125839. + " Interrupt FIFO overflow happened times: %d\n",
  125840. + Interrupt->fifoOverflow
  125841. + );
  125842. +
  125843. + gcmkTRACE_ZONE(
  125844. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125845. + " Maximum number of interrupts simultaneously generated: %d\n",
  125846. + Interrupt->maxSimultaneous
  125847. + );
  125848. +
  125849. + gcmkTRACE_ZONE(
  125850. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125851. + " Number of times when there were multiple interrupts generated: %d\n",
  125852. + Interrupt->multipleCount
  125853. + );
  125854. +#endif
  125855. +
  125856. + gcmkTRACE_ZONE(
  125857. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125858. + " The current number of entries in the FIFO: %d\n",
  125859. + Interrupt->fifoItems
  125860. + );
  125861. +
  125862. + /* Print the FIFO contents. */
  125863. + if (Interrupt->fifoItems != 0)
  125864. + {
  125865. + gctUINT8 index;
  125866. + gctUINT8 last;
  125867. +
  125868. + gcmkTRACE_ZONE(
  125869. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125870. + " FIFO current contents:\n"
  125871. + );
  125872. +
  125873. + /* Get the current pointers. */
  125874. + index = Interrupt->tail;
  125875. + last = Interrupt->head;
  125876. +
  125877. + while (index != last)
  125878. + {
  125879. + /* Advance to the next entry. */
  125880. + index += 1;
  125881. +
  125882. + gcmkTRACE_ZONE(
  125883. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125884. + " %d: 0x%08X\n",
  125885. + index, Interrupt->fifo[index]
  125886. + );
  125887. + }
  125888. + }
  125889. +
  125890. + gcmkFOOTER_NO();
  125891. + /* Success. */
  125892. + return gcvSTATUS_OK;
  125893. +}
  125894. +#endif
  125895. +
  125896. +
  125897. +/*******************************************************************************
  125898. +**
  125899. +** gckVGINTERRUPT_Enable
  125900. +**
  125901. +** Enable the specified interrupt.
  125902. +**
  125903. +** INPUT:
  125904. +**
  125905. +** Interrupt
  125906. +** Pointer to a gckVGINTERRUPT object.
  125907. +**
  125908. +** Id
  125909. +** Pointer to the variable that holds the interrupt number to be
  125910. +** registered in range 0..31.
  125911. +** If the value is less then 0, gckVGINTERRUPT_Enable will attempt
  125912. +** to find an unused interrupt. If such interrupt is found, the number
  125913. +** will be assigned to the variable if the functuion call succeedes.
  125914. +**
  125915. +** Handler
  125916. +** Pointer to the handler to register for the interrupt.
  125917. +**
  125918. +** OUTPUT:
  125919. +**
  125920. +** Nothing.
  125921. +*/
  125922. +
  125923. +gceSTATUS
  125924. +gckVGINTERRUPT_Enable(
  125925. + IN gckVGINTERRUPT Interrupt,
  125926. + IN OUT gctINT32_PTR Id,
  125927. + IN gctINTERRUPT_HANDLER Handler
  125928. + )
  125929. +{
  125930. + gceSTATUS status;
  125931. + gctINT32 i;
  125932. +
  125933. + gcmkHEADER_ARG("Interrupt=0x%x Id=0x%x Handler=0x%x", Interrupt, Id, Handler);
  125934. +
  125935. + /* Verify the arguments. */
  125936. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  125937. + gcmkVERIFY_ARGUMENT(Id != gcvNULL);
  125938. + gcmkVERIFY_ARGUMENT(Handler != gcvNULL);
  125939. +
  125940. + do
  125941. + {
  125942. + /* See if we need to allocate an ID. */
  125943. + if (*Id < 0)
  125944. + {
  125945. + /* Find the first unused interrupt handler. */
  125946. + for (i = 0; i < gcmCOUNTOF(Interrupt->handlers); ++i)
  125947. + {
  125948. + if (Interrupt->handlers[i] == gcvNULL)
  125949. + {
  125950. + break;
  125951. + }
  125952. + }
  125953. +
  125954. + /* No unused innterrupts? */
  125955. + if (i == gcmCOUNTOF(Interrupt->handlers))
  125956. + {
  125957. + status = gcvSTATUS_OUT_OF_RESOURCES;
  125958. + break;
  125959. + }
  125960. +
  125961. + /* Update the interrupt ID. */
  125962. + *Id = i;
  125963. + }
  125964. +
  125965. + /* Make sure the ID is in range. */
  125966. + else if (*Id >= gcmCOUNTOF(Interrupt->handlers))
  125967. + {
  125968. + status = gcvSTATUS_INVALID_ARGUMENT;
  125969. + break;
  125970. + }
  125971. +
  125972. + /* Set interrupt handler. */
  125973. + Interrupt->handlers[*Id] = Handler;
  125974. +
  125975. + /* Success. */
  125976. + status = gcvSTATUS_OK;
  125977. + }
  125978. + while (gcvFALSE);
  125979. +
  125980. + gcmkFOOTER();
  125981. + /* Return the status. */
  125982. + return status;
  125983. +}
  125984. +
  125985. +
  125986. +/*******************************************************************************
  125987. +**
  125988. +** gckVGINTERRUPT_Disable
  125989. +**
  125990. +** Disable the specified interrupt.
  125991. +**
  125992. +** INPUT:
  125993. +**
  125994. +** Interrupt
  125995. +** Pointer to a gckVGINTERRUPT object.
  125996. +**
  125997. +** Id
  125998. +** Interrupt number to be disabled in range 0..31.
  125999. +**
  126000. +** OUTPUT:
  126001. +**
  126002. +** Nothing.
  126003. +*/
  126004. +
  126005. +gceSTATUS
  126006. +gckVGINTERRUPT_Disable(
  126007. + IN gckVGINTERRUPT Interrupt,
  126008. + IN gctINT32 Id
  126009. + )
  126010. +{
  126011. + gcmkHEADER_ARG("Interrupt=0x%x Id=0x%x", Interrupt, Id);
  126012. + /* Verify the arguments. */
  126013. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  126014. + gcmkVERIFY_ARGUMENT((Id >= 0) && (Id < gcmCOUNTOF(Interrupt->handlers)));
  126015. +
  126016. + /* Reset interrupt handler. */
  126017. + Interrupt->handlers[Id] = gcvNULL;
  126018. +
  126019. + gcmkFOOTER_NO();
  126020. + /* Success. */
  126021. + return gcvSTATUS_OK;
  126022. +}
  126023. +
  126024. +
  126025. +/*******************************************************************************
  126026. +**
  126027. +** gckVGINTERRUPT_Enque
  126028. +**
  126029. +** Read the interrupt status register and put the value in the interrupt FIFO.
  126030. +**
  126031. +** INPUT:
  126032. +**
  126033. +** Interrupt
  126034. +** Pointer to a gckVGINTERRUPT object.
  126035. +**
  126036. +** OUTPUT:
  126037. +**
  126038. +** Nothing.
  126039. +*/
  126040. +
  126041. +#ifndef __QNXNTO__
  126042. +gceSTATUS
  126043. +gckVGINTERRUPT_Enque(
  126044. + IN gckVGINTERRUPT Interrupt
  126045. + )
  126046. +#else
  126047. +gceSTATUS
  126048. +gckVGINTERRUPT_Enque(
  126049. + IN gckVGINTERRUPT Interrupt,
  126050. + OUT gckOS *Os,
  126051. + OUT gctSEMAPHORE *Semaphore
  126052. + )
  126053. +#endif
  126054. +{
  126055. + gceSTATUS status;
  126056. + gctUINT32 triggered;
  126057. +
  126058. + gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
  126059. +
  126060. + /* Verify the arguments. */
  126061. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  126062. +
  126063. +#ifdef __QNXNTO__
  126064. + *Os = gcvNULL;
  126065. + *Semaphore = gcvNULL;
  126066. +#endif
  126067. +
  126068. + do
  126069. + {
  126070. + /* Read interrupt status register. */
  126071. + gcmkERR_BREAK(gckVGHARDWARE_ReadInterrupt(
  126072. + Interrupt->kernel->hardware, &triggered
  126073. + ));
  126074. +
  126075. + /* Mask out TS overflow interrupt */
  126076. + triggered &= 0xfffffffe;
  126077. +
  126078. + /* No interrupts to process? */
  126079. + if (triggered == 0)
  126080. + {
  126081. + status = gcvSTATUS_NOT_OUR_INTERRUPT;
  126082. + break;
  126083. + }
  126084. +
  126085. + /* FIFO overflow? */
  126086. + if (Interrupt->fifoItems == gcmCOUNTOF(Interrupt->fifo))
  126087. + {
  126088. +#if gcmENABLE_INTERRUPT_STATISTICS
  126089. + Interrupt->fifoOverflow += 1;
  126090. +#endif
  126091. +
  126092. + /* OR the interrupt with the last value in the FIFO. */
  126093. + Interrupt->fifo[Interrupt->head] |= triggered;
  126094. +
  126095. + /* Success (kind of). */
  126096. + status = gcvSTATUS_OK;
  126097. + }
  126098. + else
  126099. + {
  126100. + /* Advance to the next entry. */
  126101. + Interrupt->head += 1;
  126102. + Interrupt->fifoItems += 1;
  126103. +
  126104. +#if gcmENABLE_INTERRUPT_STATISTICS
  126105. + if (Interrupt->fifoItems > Interrupt->maxFifoItems)
  126106. + {
  126107. + Interrupt->maxFifoItems = Interrupt->fifoItems;
  126108. + }
  126109. +#endif
  126110. +
  126111. + /* Set the new value. */
  126112. + Interrupt->fifo[Interrupt->head] = triggered;
  126113. +
  126114. +#ifndef __QNXNTO__
  126115. + /* Increment the FIFO semaphore. */
  126116. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  126117. + Interrupt->os, Interrupt->fifoValid
  126118. + ));
  126119. +#else
  126120. + *Os = Interrupt->os;
  126121. + *Semaphore = Interrupt->fifoValid;
  126122. +#endif
  126123. +
  126124. + /* Windows kills our threads prematurely when the application
  126125. + exists. Verify here that the thread is still alive. */
  126126. + status = gckOS_VerifyThread(Interrupt->os, Interrupt->handler);
  126127. +
  126128. + /* Has the thread been prematurely terminated? */
  126129. + if (status != gcvSTATUS_OK)
  126130. + {
  126131. + /* Process all accumulated interrupts. */
  126132. + while (Interrupt->head != Interrupt->tail)
  126133. + {
  126134. +#if gcmENABLE_INTERRUPT_STATISTICS
  126135. + /* Process the interrupt. */
  126136. + _ProcessInterrupt(Interrupt, gcvNULL);
  126137. +#else
  126138. + /* Process the interrupt. */
  126139. + _ProcessInterrupt(Interrupt);
  126140. +#endif
  126141. + }
  126142. +
  126143. + /* Set success. */
  126144. + status = gcvSTATUS_OK;
  126145. + }
  126146. + }
  126147. + }
  126148. + while (gcvFALSE);
  126149. +
  126150. + gcmkFOOTER();
  126151. + /* Return status. */
  126152. + return status;
  126153. +}
  126154. +
  126155. +#endif /* gcdENABLE_VG */
  126156. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
  126157. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c 1970-01-01 01:00:00.000000000 +0100
  126158. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c 2014-08-20 19:31:46.132869024 +0200
  126159. @@ -0,0 +1,1982 @@
  126160. +/****************************************************************************
  126161. +*
  126162. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  126163. +*
  126164. +* This program is free software; you can redistribute it and/or modify
  126165. +* it under the terms of the GNU General Public License as published by
  126166. +* the Free Software Foundation; either version 2 of the license, or
  126167. +* (at your option) any later version.
  126168. +*
  126169. +* This program is distributed in the hope that it will be useful,
  126170. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  126171. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  126172. +* GNU General Public License for more details.
  126173. +*
  126174. +* You should have received a copy of the GNU General Public License
  126175. +* along with this program; if not write to the Free Software
  126176. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  126177. +*
  126178. +*****************************************************************************/
  126179. +
  126180. +
  126181. +#include "gc_hal_kernel_precomp.h"
  126182. +
  126183. +#define _GC_OBJ_ZONE gcvZONE_MMU
  126184. +
  126185. +typedef enum _gceMMU_TYPE
  126186. +{
  126187. + gcvMMU_USED = (0 << 4),
  126188. + gcvMMU_SINGLE = (1 << 4),
  126189. + gcvMMU_FREE = (2 << 4),
  126190. +}
  126191. +gceMMU_TYPE;
  126192. +
  126193. +#define gcmENTRY_TYPE(x) (x & 0xF0)
  126194. +
  126195. +#define gcdMMU_TABLE_DUMP 0
  126196. +
  126197. +#define gcdUSE_MMU_EXCEPTION 0
  126198. +
  126199. +/*
  126200. + gcdMMU_CLEAR_VALUE
  126201. +
  126202. + The clear value for the entry of the old MMU.
  126203. +*/
  126204. +#ifndef gcdMMU_CLEAR_VALUE
  126205. +# define gcdMMU_CLEAR_VALUE 0x00000ABC
  126206. +#endif
  126207. +
  126208. +/* VIV: Start GPU address for gcvSURF_VERTEX. */
  126209. +#define gcdVERTEX_START (128 << 10)
  126210. +
  126211. +typedef struct _gcsMMU_STLB *gcsMMU_STLB_PTR;
  126212. +
  126213. +typedef struct _gcsMMU_STLB
  126214. +{
  126215. + gctPHYS_ADDR physical;
  126216. + gctUINT32_PTR logical;
  126217. + gctSIZE_T size;
  126218. + gctUINT32 physBase;
  126219. + gctSIZE_T pageCount;
  126220. + gctUINT32 mtlbIndex;
  126221. + gctUINT32 mtlbEntryNum;
  126222. + gcsMMU_STLB_PTR next;
  126223. +} gcsMMU_STLB;
  126224. +
  126225. +#if gcdSHARED_PAGETABLE
  126226. +typedef struct _gcsSharedPageTable * gcsSharedPageTable_PTR;
  126227. +typedef struct _gcsSharedPageTable
  126228. +{
  126229. + /* Shared gckMMU object. */
  126230. + gckMMU mmu;
  126231. +
  126232. + /* Hardwares which use this shared pagetable. */
  126233. + gckHARDWARE hardwares[gcdMAX_GPU_COUNT];
  126234. +
  126235. + /* Number of cores use this shared pagetable. */
  126236. + gctUINT32 reference;
  126237. +}
  126238. +gcsSharedPageTable;
  126239. +
  126240. +static gcsSharedPageTable_PTR sharedPageTable = gcvNULL;
  126241. +#endif
  126242. +
  126243. +#if gcdMIRROR_PAGETABLE
  126244. +typedef struct _gcsMirrorPageTable * gcsMirrorPageTable_PTR;
  126245. +typedef struct _gcsMirrorPageTable
  126246. +{
  126247. + /* gckMMU objects. */
  126248. + gckMMU mmus[gcdMAX_GPU_COUNT];
  126249. +
  126250. + /* Hardwares which use this shared pagetable. */
  126251. + gckHARDWARE hardwares[gcdMAX_GPU_COUNT];
  126252. +
  126253. + /* Number of cores use this shared pagetable. */
  126254. + gctUINT32 reference;
  126255. +}
  126256. +gcsMirrorPageTable;
  126257. +
  126258. +static gcsMirrorPageTable_PTR mirrorPageTable = gcvNULL;
  126259. +static gctPOINTER mirrorPageTableMutex = gcvNULL;
  126260. +#endif
  126261. +
  126262. +typedef struct _gcsDynamicSpaceNode * gcsDynamicSpaceNode_PTR;
  126263. +typedef struct _gcsDynamicSpaceNode
  126264. +{
  126265. + gctUINT32 start;
  126266. + gctINT32 entries;
  126267. +}
  126268. +gcsDynamicSpaceNode;
  126269. +
  126270. +static void
  126271. +_WritePageEntry(
  126272. + IN gctUINT32_PTR PageEntry,
  126273. + IN gctUINT32 EntryValue
  126274. + )
  126275. +{
  126276. + static gctUINT16 data = 0xff00;
  126277. +
  126278. + if (*(gctUINT8 *)&data == 0xff)
  126279. + {
  126280. + *PageEntry = gcmSWAB32(EntryValue);
  126281. + }
  126282. + else
  126283. + {
  126284. + *PageEntry = EntryValue;
  126285. + }
  126286. +}
  126287. +
  126288. +static gctUINT32
  126289. +_ReadPageEntry(
  126290. + IN gctUINT32_PTR PageEntry
  126291. + )
  126292. +{
  126293. + static gctUINT16 data = 0xff00;
  126294. + gctUINT32 entryValue;
  126295. +
  126296. + if (*(gctUINT8 *)&data == 0xff)
  126297. + {
  126298. + entryValue = *PageEntry;
  126299. + return gcmSWAB32(entryValue);
  126300. + }
  126301. + else
  126302. + {
  126303. + return *PageEntry;
  126304. + }
  126305. +}
  126306. +
  126307. +static gceSTATUS
  126308. +_FillPageTable(
  126309. + IN gctUINT32_PTR PageTable,
  126310. + IN gctUINT32 PageCount,
  126311. + IN gctUINT32 EntryValue
  126312. +)
  126313. +{
  126314. + gctUINT i;
  126315. +
  126316. + for (i = 0; i < PageCount; i++)
  126317. + {
  126318. + _WritePageEntry(PageTable + i, EntryValue);
  126319. + }
  126320. +
  126321. + return gcvSTATUS_OK;
  126322. +}
  126323. +
  126324. +static gceSTATUS
  126325. +_Link(
  126326. + IN gckMMU Mmu,
  126327. + IN gctUINT32 Index,
  126328. + IN gctUINT32 Next
  126329. + )
  126330. +{
  126331. + if (Index >= Mmu->pageTableEntries)
  126332. + {
  126333. + /* Just move heap pointer. */
  126334. + Mmu->heapList = Next;
  126335. + }
  126336. + else
  126337. + {
  126338. + /* Address page table. */
  126339. + gctUINT32_PTR pageTable = Mmu->pageTableLogical;
  126340. +
  126341. + /* Dispatch on node type. */
  126342. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[Index])))
  126343. + {
  126344. + case gcvMMU_SINGLE:
  126345. + /* Set single index. */
  126346. + _WritePageEntry(&pageTable[Index], (Next << 8) | gcvMMU_SINGLE);
  126347. + break;
  126348. +
  126349. + case gcvMMU_FREE:
  126350. + /* Set index. */
  126351. + _WritePageEntry(&pageTable[Index + 1], Next);
  126352. + break;
  126353. +
  126354. + default:
  126355. + gcmkFATAL("MMU table correcupted at index %u!", Index);
  126356. + return gcvSTATUS_HEAP_CORRUPTED;
  126357. + }
  126358. + }
  126359. +
  126360. + /* Success. */
  126361. + return gcvSTATUS_OK;
  126362. +}
  126363. +
  126364. +static gceSTATUS
  126365. +_AddFree(
  126366. + IN gckMMU Mmu,
  126367. + IN gctUINT32 Index,
  126368. + IN gctUINT32 Node,
  126369. + IN gctUINT32 Count
  126370. + )
  126371. +{
  126372. + gctUINT32_PTR pageTable = Mmu->pageTableLogical;
  126373. +
  126374. + if (Count == 1)
  126375. + {
  126376. + /* Initialize a single page node. */
  126377. + _WritePageEntry(pageTable + Node, (~((1U<<8)-1)) | gcvMMU_SINGLE);
  126378. + }
  126379. + else
  126380. + {
  126381. + /* Initialize the node. */
  126382. + _WritePageEntry(pageTable + Node + 0, (Count << 8) | gcvMMU_FREE);
  126383. + _WritePageEntry(pageTable + Node + 1, ~0U);
  126384. + }
  126385. +
  126386. + /* Append the node. */
  126387. + return _Link(Mmu, Index, Node);
  126388. +}
  126389. +
  126390. +static gceSTATUS
  126391. +_Collect(
  126392. + IN gckMMU Mmu
  126393. + )
  126394. +{
  126395. + gctUINT32_PTR pageTable = Mmu->pageTableLogical;
  126396. + gceSTATUS status;
  126397. + gctUINT32 i, previous, start = 0, count = 0;
  126398. +
  126399. + previous = Mmu->heapList = ~0U;
  126400. + Mmu->freeNodes = gcvFALSE;
  126401. +
  126402. + /* Walk the entire page table. */
  126403. + for (i = 0; i < Mmu->pageTableEntries; ++i)
  126404. + {
  126405. + /* Dispatch based on type of page. */
  126406. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[i])))
  126407. + {
  126408. + case gcvMMU_USED:
  126409. + /* Used page, so close any open node. */
  126410. + if (count > 0)
  126411. + {
  126412. + /* Add the node. */
  126413. + gcmkONERROR(_AddFree(Mmu, previous, start, count));
  126414. +
  126415. + /* Reset the node. */
  126416. + previous = start;
  126417. + count = 0;
  126418. + }
  126419. + break;
  126420. +
  126421. + case gcvMMU_SINGLE:
  126422. + /* Single free node. */
  126423. + if (count++ == 0)
  126424. + {
  126425. + /* Start a new node. */
  126426. + start = i;
  126427. + }
  126428. + break;
  126429. +
  126430. + case gcvMMU_FREE:
  126431. + /* A free node. */
  126432. + if (count == 0)
  126433. + {
  126434. + /* Start a new node. */
  126435. + start = i;
  126436. + }
  126437. +
  126438. + /* Advance the count. */
  126439. + count += _ReadPageEntry(&pageTable[i]) >> 8;
  126440. +
  126441. + /* Advance the index into the page table. */
  126442. + i += (_ReadPageEntry(&pageTable[i]) >> 8) - 1;
  126443. + break;
  126444. +
  126445. + default:
  126446. + gcmkFATAL("MMU page table correcupted at index %u!", i);
  126447. + return gcvSTATUS_HEAP_CORRUPTED;
  126448. + }
  126449. + }
  126450. +
  126451. + /* See if we have an open node left. */
  126452. + if (count > 0)
  126453. + {
  126454. + /* Add the node to the list. */
  126455. + gcmkONERROR(_AddFree(Mmu, previous, start, count));
  126456. + }
  126457. +
  126458. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_MMU,
  126459. + "Performed a garbage collection of the MMU heap.");
  126460. +
  126461. + /* Success. */
  126462. + return gcvSTATUS_OK;
  126463. +
  126464. +OnError:
  126465. + /* Return the staus. */
  126466. + return status;
  126467. +}
  126468. +
  126469. +static gctUINT32
  126470. +_SetPage(gctUINT32 PageAddress)
  126471. +{
  126472. + return PageAddress
  126473. + /* writable */
  126474. + | (1 << 2)
  126475. + /* Ignore exception */
  126476. + | (0 << 1)
  126477. + /* Present */
  126478. + | (1 << 0);
  126479. +}
  126480. +
  126481. +static gceSTATUS
  126482. +_FillFlatMapping(
  126483. + IN gckMMU Mmu,
  126484. + IN gctUINT32 PhysBase,
  126485. + OUT gctSIZE_T Size
  126486. + )
  126487. +{
  126488. + gceSTATUS status;
  126489. + gctBOOL mutex = gcvFALSE;
  126490. + gcsMMU_STLB_PTR head = gcvNULL, pre = gcvNULL;
  126491. + gctUINT32 start = PhysBase & (~gcdMMU_PAGE_64K_MASK);
  126492. + gctUINT32 end = (PhysBase + Size - 1) & (~gcdMMU_PAGE_64K_MASK);
  126493. + gctUINT32 mStart = start >> gcdMMU_MTLB_SHIFT;
  126494. + gctUINT32 mEnd = end >> gcdMMU_MTLB_SHIFT;
  126495. + gctUINT32 sStart = (start & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
  126496. + gctUINT32 sEnd = (end & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
  126497. +
  126498. + /* Grab the mutex. */
  126499. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  126500. + mutex = gcvTRUE;
  126501. +
  126502. + while (mStart <= mEnd)
  126503. + {
  126504. + gcmkASSERT(mStart < gcdMMU_MTLB_ENTRY_NUM);
  126505. + if (*(Mmu->mtlbLogical + mStart) == 0)
  126506. + {
  126507. + gcsMMU_STLB_PTR stlb;
  126508. + gctPOINTER pointer = gcvNULL;
  126509. + gctUINT32 last = (mStart == mEnd) ? sEnd : (gcdMMU_STLB_64K_ENTRY_NUM - 1);
  126510. +
  126511. + gcmkONERROR(gckOS_Allocate(Mmu->os, sizeof(struct _gcsMMU_STLB), &pointer));
  126512. + stlb = pointer;
  126513. +
  126514. + stlb->mtlbEntryNum = 0;
  126515. + stlb->next = gcvNULL;
  126516. + stlb->physical = gcvNULL;
  126517. + stlb->logical = gcvNULL;
  126518. + stlb->size = gcdMMU_STLB_64K_SIZE;
  126519. + stlb->pageCount = 0;
  126520. +
  126521. + if (pre == gcvNULL)
  126522. + {
  126523. + pre = head = stlb;
  126524. + }
  126525. + else
  126526. + {
  126527. + gcmkASSERT(pre->next == gcvNULL);
  126528. + pre->next = stlb;
  126529. + pre = stlb;
  126530. + }
  126531. +
  126532. + gcmkONERROR(
  126533. + gckOS_AllocateContiguous(Mmu->os,
  126534. + gcvFALSE,
  126535. + &stlb->size,
  126536. + &stlb->physical,
  126537. + (gctPOINTER)&stlb->logical));
  126538. +
  126539. + gcmkONERROR(gckOS_ZeroMemory(stlb->logical, stlb->size));
  126540. +
  126541. + gcmkONERROR(gckOS_GetPhysicalAddress(
  126542. + Mmu->os,
  126543. + stlb->logical,
  126544. + &stlb->physBase));
  126545. +
  126546. + if (stlb->physBase & (gcdMMU_STLB_64K_SIZE - 1))
  126547. + {
  126548. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  126549. + }
  126550. +
  126551. + _WritePageEntry(Mmu->mtlbLogical + mStart,
  126552. + stlb->physBase
  126553. + /* 64KB page size */
  126554. + | (1 << 2)
  126555. + /* Ignore exception */
  126556. + | (0 << 1)
  126557. + /* Present */
  126558. + | (1 << 0)
  126559. + );
  126560. +#if gcdMMU_TABLE_DUMP
  126561. + gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
  126562. + __FUNCTION__, __LINE__,
  126563. + mStart,
  126564. + _ReadPageEntry(Mmu->mtlbLogical + mStart));
  126565. +#endif
  126566. +
  126567. + stlb->mtlbIndex = mStart;
  126568. + stlb->mtlbEntryNum = 1;
  126569. +#if gcdMMU_TABLE_DUMP
  126570. + gckOS_Print("%s(%d): STLB: logical:%08x -> physical:%08x\n",
  126571. + __FUNCTION__, __LINE__,
  126572. + stlb->logical,
  126573. + stlb->physBase);
  126574. +#endif
  126575. +
  126576. + while (sStart <= last)
  126577. + {
  126578. + gcmkASSERT(!(start & gcdMMU_PAGE_64K_MASK));
  126579. + _WritePageEntry(stlb->logical + sStart, _SetPage(start));
  126580. +#if gcdMMU_TABLE_DUMP
  126581. + gckOS_Print("%s(%d): insert STLB[%d]: %08x\n",
  126582. + __FUNCTION__, __LINE__,
  126583. + sStart,
  126584. + _ReadPageEntry(stlb->logical + sStart));
  126585. +#endif
  126586. + /* next page. */
  126587. + start += gcdMMU_PAGE_64K_SIZE;
  126588. + sStart++;
  126589. + stlb->pageCount++;
  126590. + }
  126591. +
  126592. + sStart = 0;
  126593. + ++mStart;
  126594. + }
  126595. + else
  126596. + {
  126597. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  126598. + }
  126599. + }
  126600. +
  126601. + /* Insert the stlb into staticSTLB. */
  126602. + if (Mmu->staticSTLB == gcvNULL)
  126603. + {
  126604. + Mmu->staticSTLB = head;
  126605. + }
  126606. + else
  126607. + {
  126608. + gcmkASSERT(pre == gcvNULL);
  126609. + gcmkASSERT(pre->next == gcvNULL);
  126610. + pre->next = Mmu->staticSTLB;
  126611. + Mmu->staticSTLB = head;
  126612. + }
  126613. +
  126614. + /* Release the mutex. */
  126615. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  126616. +
  126617. + return gcvSTATUS_OK;
  126618. +
  126619. +OnError:
  126620. +
  126621. + /* Roll back. */
  126622. + while (head != gcvNULL)
  126623. + {
  126624. + pre = head;
  126625. + head = head->next;
  126626. +
  126627. + if (pre->physical != gcvNULL)
  126628. + {
  126629. + gcmkVERIFY_OK(
  126630. + gckOS_FreeContiguous(Mmu->os,
  126631. + pre->physical,
  126632. + pre->logical,
  126633. + pre->size));
  126634. + }
  126635. +
  126636. + if (pre->mtlbEntryNum != 0)
  126637. + {
  126638. + gcmkASSERT(pre->mtlbEntryNum == 1);
  126639. + _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex, 0);
  126640. + }
  126641. +
  126642. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
  126643. + }
  126644. +
  126645. + if (mutex)
  126646. + {
  126647. + /* Release the mutex. */
  126648. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  126649. + }
  126650. +
  126651. + return status;
  126652. +}
  126653. +
  126654. +static gceSTATUS
  126655. +_FindDynamicSpace(
  126656. + IN gckMMU Mmu,
  126657. + OUT gcsDynamicSpaceNode_PTR *Array,
  126658. + OUT gctINT * Size
  126659. + )
  126660. +{
  126661. + gceSTATUS status = gcvSTATUS_OK;
  126662. + gctPOINTER pointer = gcvNULL;
  126663. + gcsDynamicSpaceNode_PTR array = gcvNULL;
  126664. + gctINT size = 0;
  126665. + gctINT i = 0, nodeStart = -1, nodeEntries = 0;
  126666. +
  126667. + /* Allocate memory for the array. */
  126668. + gcmkONERROR(gckOS_Allocate(Mmu->os,
  126669. + gcmSIZEOF(*array) * (gcdMMU_MTLB_ENTRY_NUM / 2),
  126670. + &pointer));
  126671. +
  126672. + array = (gcsDynamicSpaceNode_PTR)pointer;
  126673. +
  126674. + /* Loop all the entries. */
  126675. + while (i < gcdMMU_MTLB_ENTRY_NUM)
  126676. + {
  126677. + if (!Mmu->mtlbLogical[i])
  126678. + {
  126679. + if (nodeStart < 0)
  126680. + {
  126681. + /* This is the first entry of the dynamic space. */
  126682. + nodeStart = i;
  126683. + nodeEntries = 1;
  126684. + }
  126685. + else
  126686. + {
  126687. + /* Other entries of the dynamic space. */
  126688. + nodeEntries++;
  126689. + }
  126690. + }
  126691. + else if (nodeStart >= 0)
  126692. + {
  126693. + /* Save the previous node. */
  126694. + array[size].start = nodeStart;
  126695. + array[size].entries = nodeEntries;
  126696. + size++;
  126697. +
  126698. + /* Reset the start. */
  126699. + nodeStart = -1;
  126700. + nodeEntries = 0;
  126701. + }
  126702. +
  126703. + i++;
  126704. + }
  126705. +
  126706. + /* Save the previous node. */
  126707. + if (nodeStart >= 0)
  126708. + {
  126709. + array[size].start = nodeStart;
  126710. + array[size].entries = nodeEntries;
  126711. + size++;
  126712. + }
  126713. +
  126714. +#if gcdMMU_TABLE_DUMP
  126715. + for (i = 0; i < size; i++)
  126716. + {
  126717. + gckOS_Print("%s(%d): [%d]: start=%d, entries=%d.\n",
  126718. + __FUNCTION__, __LINE__,
  126719. + i,
  126720. + array[i].start,
  126721. + array[i].entries);
  126722. + }
  126723. +#endif
  126724. +
  126725. + *Array = array;
  126726. + *Size = size;
  126727. +
  126728. + return gcvSTATUS_OK;
  126729. +
  126730. +OnError:
  126731. + if (pointer != gcvNULL)
  126732. + {
  126733. + gckOS_Free(Mmu->os, pointer);
  126734. + }
  126735. +
  126736. + return status;
  126737. +}
  126738. +
  126739. +static gceSTATUS
  126740. +_SetupDynamicSpace(
  126741. + IN gckMMU Mmu
  126742. + )
  126743. +{
  126744. + gceSTATUS status;
  126745. + gcsDynamicSpaceNode_PTR nodeArray = gcvNULL;
  126746. + gctINT i, nodeArraySize = 0;
  126747. + gctUINT32 physical;
  126748. + gctINT numEntries = 0;
  126749. + gctUINT32_PTR pageTable;
  126750. + gctBOOL acquired = gcvFALSE;
  126751. +
  126752. + /* Find all the dynamic address space. */
  126753. + gcmkONERROR(_FindDynamicSpace(Mmu, &nodeArray, &nodeArraySize));
  126754. +
  126755. + /* TODO: We only use the largest one for now. */
  126756. + for (i = 0; i < nodeArraySize; i++)
  126757. + {
  126758. + if (nodeArray[i].entries > numEntries)
  126759. + {
  126760. + Mmu->dynamicMappingStart = nodeArray[i].start;
  126761. + numEntries = nodeArray[i].entries;
  126762. + }
  126763. + }
  126764. +
  126765. + gckOS_Free(Mmu->os, (gctPOINTER)nodeArray);
  126766. +
  126767. + Mmu->pageTableSize = numEntries * 4096;
  126768. +
  126769. + Mmu->pageTableEntries = Mmu->pageTableSize / gcmSIZEOF(gctUINT32);
  126770. +
  126771. + /* Construct Slave TLB. */
  126772. + gcmkONERROR(gckOS_AllocateContiguous(Mmu->os,
  126773. + gcvFALSE,
  126774. + &Mmu->pageTableSize,
  126775. + &Mmu->pageTablePhysical,
  126776. + (gctPOINTER)&Mmu->pageTableLogical));
  126777. +
  126778. +#if gcdUSE_MMU_EXCEPTION
  126779. + gcmkONERROR(_FillPageTable(Mmu->pageTableLogical,
  126780. + Mmu->pageTableEntries,
  126781. + /* Enable exception */
  126782. + 1 << 1));
  126783. +#else
  126784. + /* Invalidate all entries. */
  126785. + gcmkONERROR(gckOS_ZeroMemory(Mmu->pageTableLogical,
  126786. + Mmu->pageTableSize));
  126787. +#endif
  126788. +
  126789. + /* Initilization. */
  126790. + pageTable = Mmu->pageTableLogical;
  126791. + _WritePageEntry(pageTable, (Mmu->pageTableEntries << 8) | gcvMMU_FREE);
  126792. + _WritePageEntry(pageTable + 1, ~0U);
  126793. + Mmu->heapList = 0;
  126794. + Mmu->freeNodes = gcvFALSE;
  126795. +
  126796. + gcmkONERROR(gckOS_GetPhysicalAddress(Mmu->os,
  126797. + Mmu->pageTableLogical,
  126798. + &physical));
  126799. +
  126800. + /* Grab the mutex. */
  126801. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  126802. + acquired = gcvTRUE;
  126803. +
  126804. + /* Map to Master TLB. */
  126805. + for (i = (gctINT)Mmu->dynamicMappingStart;
  126806. + i < (gctINT)Mmu->dynamicMappingStart + numEntries;
  126807. + i++)
  126808. + {
  126809. + _WritePageEntry(Mmu->mtlbLogical + i,
  126810. + physical
  126811. + /* 4KB page size */
  126812. + | (0 << 2)
  126813. + /* Ignore exception */
  126814. + | (0 << 1)
  126815. + /* Present */
  126816. + | (1 << 0)
  126817. + );
  126818. +#if gcdMMU_TABLE_DUMP
  126819. + gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
  126820. + __FUNCTION__, __LINE__,
  126821. + i,
  126822. + _ReadPageEntry(Mmu->mtlbLogical + i));
  126823. +#endif
  126824. + physical += gcdMMU_STLB_4K_SIZE;
  126825. + }
  126826. +
  126827. + /* Release the mutex. */
  126828. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  126829. +
  126830. + return gcvSTATUS_OK;
  126831. +
  126832. +OnError:
  126833. + if (Mmu->pageTableLogical)
  126834. + {
  126835. + /* Free the page table. */
  126836. + gcmkVERIFY_OK(
  126837. + gckOS_FreeContiguous(Mmu->os,
  126838. + Mmu->pageTablePhysical,
  126839. + (gctPOINTER) Mmu->pageTableLogical,
  126840. + Mmu->pageTableSize));
  126841. + }
  126842. +
  126843. + if (acquired)
  126844. + {
  126845. + /* Release the mutex. */
  126846. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  126847. + }
  126848. +
  126849. + return status;
  126850. +}
  126851. +
  126852. +/*******************************************************************************
  126853. +**
  126854. +** _Construct
  126855. +**
  126856. +** Construct a new gckMMU object.
  126857. +**
  126858. +** INPUT:
  126859. +**
  126860. +** gckKERNEL Kernel
  126861. +** Pointer to an gckKERNEL object.
  126862. +**
  126863. +** gctSIZE_T MmuSize
  126864. +** Number of bytes for the page table.
  126865. +**
  126866. +** OUTPUT:
  126867. +**
  126868. +** gckMMU * Mmu
  126869. +** Pointer to a variable that receives the gckMMU object pointer.
  126870. +*/
  126871. +gceSTATUS
  126872. +_Construct(
  126873. + IN gckKERNEL Kernel,
  126874. + IN gctSIZE_T MmuSize,
  126875. + OUT gckMMU * Mmu
  126876. + )
  126877. +{
  126878. + gckOS os;
  126879. + gckHARDWARE hardware;
  126880. + gceSTATUS status;
  126881. + gckMMU mmu = gcvNULL;
  126882. + gctUINT32_PTR pageTable;
  126883. + gctPOINTER pointer = gcvNULL;
  126884. +
  126885. + gcmkHEADER_ARG("Kernel=0x%x MmuSize=%lu", Kernel, MmuSize);
  126886. +
  126887. + /* Verify the arguments. */
  126888. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  126889. + gcmkVERIFY_ARGUMENT(MmuSize > 0);
  126890. + gcmkVERIFY_ARGUMENT(Mmu != gcvNULL);
  126891. +
  126892. + /* Extract the gckOS object pointer. */
  126893. + os = Kernel->os;
  126894. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  126895. +
  126896. + /* Extract the gckHARDWARE object pointer. */
  126897. + hardware = Kernel->hardware;
  126898. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  126899. +
  126900. + /* Allocate memory for the gckMMU object. */
  126901. + gcmkONERROR(gckOS_Allocate(os, sizeof(struct _gckMMU), &pointer));
  126902. +
  126903. + mmu = pointer;
  126904. +
  126905. + /* Initialize the gckMMU object. */
  126906. + mmu->object.type = gcvOBJ_MMU;
  126907. + mmu->os = os;
  126908. + mmu->hardware = hardware;
  126909. + mmu->pageTableMutex = gcvNULL;
  126910. + mmu->pageTableLogical = gcvNULL;
  126911. + mmu->mtlbLogical = gcvNULL;
  126912. + mmu->staticSTLB = gcvNULL;
  126913. + mmu->enabled = gcvFALSE;
  126914. +#ifdef __QNXNTO__
  126915. + mmu->nodeList = gcvNULL;
  126916. + mmu->nodeMutex = gcvNULL;
  126917. +#endif
  126918. +
  126919. + /* Create the page table mutex. */
  126920. + gcmkONERROR(gckOS_CreateMutex(os, &mmu->pageTableMutex));
  126921. +
  126922. +#ifdef __QNXNTO__
  126923. + /* Create the node list mutex. */
  126924. + gcmkONERROR(gckOS_CreateMutex(os, &mmu->nodeMutex));
  126925. +#endif
  126926. +
  126927. + if (hardware->mmuVersion == 0)
  126928. + {
  126929. + mmu->pageTableSize = MmuSize;
  126930. +
  126931. + gcmkONERROR(
  126932. + gckOS_AllocateContiguous(os,
  126933. + gcvFALSE,
  126934. + &mmu->pageTableSize,
  126935. + &mmu->pageTablePhysical,
  126936. + &pointer));
  126937. +
  126938. + mmu->pageTableLogical = pointer;
  126939. +
  126940. + /* Compute number of entries in page table. */
  126941. + mmu->pageTableEntries = mmu->pageTableSize / sizeof(gctUINT32);
  126942. +
  126943. + /* Mark all pages as free. */
  126944. + pageTable = mmu->pageTableLogical;
  126945. +
  126946. +#if gcdMMU_CLEAR_VALUE
  126947. + _FillPageTable(pageTable, mmu->pageTableEntries, gcdMMU_CLEAR_VALUE);
  126948. +#endif
  126949. +
  126950. + _WritePageEntry(pageTable, (mmu->pageTableEntries << 8) | gcvMMU_FREE);
  126951. + _WritePageEntry(pageTable + 1, ~0U);
  126952. + mmu->heapList = 0;
  126953. + mmu->freeNodes = gcvFALSE;
  126954. +
  126955. + /* Set page table address. */
  126956. + gcmkONERROR(
  126957. + gckHARDWARE_SetMMU(hardware, (gctPOINTER) mmu->pageTableLogical));
  126958. + }
  126959. + else
  126960. + {
  126961. + /* Allocate the 4K mode MTLB table. */
  126962. + mmu->mtlbSize = gcdMMU_MTLB_SIZE + 64;
  126963. +
  126964. + gcmkONERROR(
  126965. + gckOS_AllocateContiguous(os,
  126966. + gcvFALSE,
  126967. + &mmu->mtlbSize,
  126968. + &mmu->mtlbPhysical,
  126969. + &pointer));
  126970. +
  126971. + mmu->mtlbLogical = pointer;
  126972. +
  126973. + /* Invalid all the entries. */
  126974. + gcmkONERROR(
  126975. + gckOS_ZeroMemory(pointer, mmu->mtlbSize));
  126976. + }
  126977. +
  126978. + /* Return the gckMMU object pointer. */
  126979. + *Mmu = mmu;
  126980. +
  126981. + /* Success. */
  126982. + gcmkFOOTER_ARG("*Mmu=0x%x", *Mmu);
  126983. + return gcvSTATUS_OK;
  126984. +
  126985. +OnError:
  126986. + /* Roll back. */
  126987. + if (mmu != gcvNULL)
  126988. + {
  126989. + if (mmu->pageTableLogical != gcvNULL)
  126990. + {
  126991. + /* Free the page table. */
  126992. + gcmkVERIFY_OK(
  126993. + gckOS_FreeContiguous(os,
  126994. + mmu->pageTablePhysical,
  126995. + (gctPOINTER) mmu->pageTableLogical,
  126996. + mmu->pageTableSize));
  126997. +
  126998. + }
  126999. +
  127000. + if (mmu->mtlbLogical != gcvNULL)
  127001. + {
  127002. + gcmkVERIFY_OK(
  127003. + gckOS_FreeContiguous(os,
  127004. + mmu->mtlbPhysical,
  127005. + (gctPOINTER) mmu->mtlbLogical,
  127006. + mmu->mtlbSize));
  127007. + }
  127008. +
  127009. + if (mmu->pageTableMutex != gcvNULL)
  127010. + {
  127011. + /* Delete the mutex. */
  127012. + gcmkVERIFY_OK(
  127013. + gckOS_DeleteMutex(os, mmu->pageTableMutex));
  127014. + }
  127015. +
  127016. +#ifdef __QNXNTO__
  127017. + if (mmu->nodeMutex != gcvNULL)
  127018. + {
  127019. + /* Delete the mutex. */
  127020. + gcmkVERIFY_OK(
  127021. + gckOS_DeleteMutex(os, mmu->nodeMutex));
  127022. + }
  127023. +#endif
  127024. +
  127025. + /* Mark the gckMMU object as unknown. */
  127026. + mmu->object.type = gcvOBJ_UNKNOWN;
  127027. +
  127028. + /* Free the allocates memory. */
  127029. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, mmu));
  127030. + }
  127031. +
  127032. + /* Return the status. */
  127033. + gcmkFOOTER();
  127034. + return status;
  127035. +}
  127036. +
  127037. +/*******************************************************************************
  127038. +**
  127039. +** _Destroy
  127040. +**
  127041. +** Destroy a gckMMU object.
  127042. +**
  127043. +** INPUT:
  127044. +**
  127045. +** gckMMU Mmu
  127046. +** Pointer to an gckMMU object.
  127047. +**
  127048. +** OUTPUT:
  127049. +**
  127050. +** Nothing.
  127051. +*/
  127052. +gceSTATUS
  127053. +_Destroy(
  127054. + IN gckMMU Mmu
  127055. + )
  127056. +{
  127057. +#ifdef __QNXNTO__
  127058. + gcuVIDMEM_NODE_PTR node, next;
  127059. +#endif
  127060. +
  127061. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  127062. +
  127063. + /* Verify the arguments. */
  127064. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127065. +
  127066. +#ifdef __QNXNTO__
  127067. + /* Free all associated virtual memory. */
  127068. + for (node = Mmu->nodeList; node != gcvNULL; node = next)
  127069. + {
  127070. + next = node->Virtual.next;
  127071. + gcmkVERIFY_OK(gckVIDMEM_Free(node));
  127072. + }
  127073. +#endif
  127074. +
  127075. + while (Mmu->staticSTLB != gcvNULL)
  127076. + {
  127077. + gcsMMU_STLB_PTR pre = Mmu->staticSTLB;
  127078. + Mmu->staticSTLB = pre->next;
  127079. +
  127080. + if (pre->physical != gcvNULL)
  127081. + {
  127082. + gcmkVERIFY_OK(
  127083. + gckOS_FreeContiguous(Mmu->os,
  127084. + pre->physical,
  127085. + pre->logical,
  127086. + pre->size));
  127087. + }
  127088. +
  127089. + if (pre->mtlbEntryNum != 0)
  127090. + {
  127091. + gcmkASSERT(pre->mtlbEntryNum == 1);
  127092. + _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex, 0);
  127093. +#if gcdMMU_TABLE_DUMP
  127094. + gckOS_Print("%s(%d): clean MTLB[%d]\n",
  127095. + __FUNCTION__, __LINE__,
  127096. + pre->mtlbIndex);
  127097. +#endif
  127098. + }
  127099. +
  127100. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
  127101. + }
  127102. +
  127103. + if (Mmu->hardware->mmuVersion != 0)
  127104. + {
  127105. + gcmkVERIFY_OK(
  127106. + gckOS_FreeContiguous(Mmu->os,
  127107. + Mmu->mtlbPhysical,
  127108. + (gctPOINTER) Mmu->mtlbLogical,
  127109. + Mmu->mtlbSize));
  127110. + }
  127111. +
  127112. + /* Free the page table. */
  127113. + gcmkVERIFY_OK(
  127114. + gckOS_FreeContiguous(Mmu->os,
  127115. + Mmu->pageTablePhysical,
  127116. + (gctPOINTER) Mmu->pageTableLogical,
  127117. + Mmu->pageTableSize));
  127118. +
  127119. +#ifdef __QNXNTO__
  127120. + /* Delete the node list mutex. */
  127121. + gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->nodeMutex));
  127122. +#endif
  127123. +
  127124. + /* Delete the page table mutex. */
  127125. + gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->pageTableMutex));
  127126. +
  127127. + /* Mark the gckMMU object as unknown. */
  127128. + Mmu->object.type = gcvOBJ_UNKNOWN;
  127129. +
  127130. + /* Free the gckMMU object. */
  127131. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, Mmu));
  127132. +
  127133. + /* Success. */
  127134. + gcmkFOOTER_NO();
  127135. + return gcvSTATUS_OK;
  127136. +}
  127137. +
  127138. +/*******************************************************************************
  127139. +** _AdjstIndex
  127140. +**
  127141. +** Adjust the index from which we search for a usable node to make sure
  127142. +** index allocated is greater than Start.
  127143. +*/
  127144. +gceSTATUS
  127145. +_AdjustIndex(
  127146. + IN gckMMU Mmu,
  127147. + IN gctUINT32 Index,
  127148. + IN gctUINT32 PageCount,
  127149. + IN gctUINT32 Start,
  127150. + OUT gctUINT32 * IndexAdjusted
  127151. + )
  127152. +{
  127153. + gceSTATUS status;
  127154. + gctUINT32 index = Index;
  127155. + gctUINT32_PTR map = Mmu->pageTableLogical;
  127156. +
  127157. + gcmkHEADER();
  127158. +
  127159. + for (; index < Mmu->pageTableEntries;)
  127160. + {
  127161. + gctUINT32 result = 0;
  127162. + gctUINT32 nodeSize = 0;
  127163. +
  127164. + if (index >= Start)
  127165. + {
  127166. + break;
  127167. + }
  127168. +
  127169. + switch (gcmENTRY_TYPE(map[index]))
  127170. + {
  127171. + case gcvMMU_SINGLE:
  127172. + nodeSize = 1;
  127173. + break;
  127174. +
  127175. + case gcvMMU_FREE:
  127176. + nodeSize = map[index] >> 8;
  127177. + break;
  127178. +
  127179. + default:
  127180. + gcmkFATAL("MMU table correcupted at index %u!", index);
  127181. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  127182. + }
  127183. +
  127184. + if (nodeSize > PageCount)
  127185. + {
  127186. + result = index + (nodeSize - PageCount);
  127187. +
  127188. + if (result >= Start)
  127189. + {
  127190. + break;
  127191. + }
  127192. + }
  127193. +
  127194. + switch (gcmENTRY_TYPE(map[index]))
  127195. + {
  127196. + case gcvMMU_SINGLE:
  127197. + index = map[index] >> 8;
  127198. + break;
  127199. +
  127200. + case gcvMMU_FREE:
  127201. + index = map[index + 1];
  127202. + break;
  127203. +
  127204. + default:
  127205. + gcmkFATAL("MMU table correcupted at index %u!", index);
  127206. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  127207. + }
  127208. + }
  127209. +
  127210. + *IndexAdjusted = index;
  127211. +
  127212. + gcmkFOOTER_NO();
  127213. + return gcvSTATUS_OK;
  127214. +
  127215. +OnError:
  127216. + gcmkFOOTER();
  127217. + return status;
  127218. +}
  127219. +
  127220. +gceSTATUS
  127221. +gckMMU_Construct(
  127222. + IN gckKERNEL Kernel,
  127223. + IN gctSIZE_T MmuSize,
  127224. + OUT gckMMU * Mmu
  127225. + )
  127226. +{
  127227. +#if gcdSHARED_PAGETABLE
  127228. + gceSTATUS status;
  127229. + gctPOINTER pointer;
  127230. +
  127231. + gcmkHEADER_ARG("Kernel=0x%08x", Kernel);
  127232. +
  127233. + if (sharedPageTable == gcvNULL)
  127234. + {
  127235. + gcmkONERROR(
  127236. + gckOS_Allocate(Kernel->os,
  127237. + sizeof(struct _gcsSharedPageTable),
  127238. + &pointer));
  127239. + sharedPageTable = pointer;
  127240. +
  127241. + gcmkONERROR(
  127242. + gckOS_ZeroMemory(sharedPageTable,
  127243. + sizeof(struct _gcsSharedPageTable)));
  127244. +
  127245. + gcmkONERROR(_Construct(Kernel, MmuSize, &sharedPageTable->mmu));
  127246. + }
  127247. + else if (Kernel->hardware->mmuVersion == 0)
  127248. + {
  127249. + /* Set page table address. */
  127250. + gcmkONERROR(
  127251. + gckHARDWARE_SetMMU(Kernel->hardware, (gctPOINTER) sharedPageTable->mmu->pageTableLogical));
  127252. + }
  127253. +
  127254. + *Mmu = sharedPageTable->mmu;
  127255. +
  127256. + sharedPageTable->hardwares[sharedPageTable->reference] = Kernel->hardware;
  127257. +
  127258. + sharedPageTable->reference++;
  127259. +
  127260. + gcmkFOOTER_ARG("sharedPageTable->reference=%lu", sharedPageTable->reference);
  127261. + return gcvSTATUS_OK;
  127262. +
  127263. +OnError:
  127264. + if (sharedPageTable)
  127265. + {
  127266. + if (sharedPageTable->mmu)
  127267. + {
  127268. + gcmkVERIFY_OK(gckMMU_Destroy(sharedPageTable->mmu));
  127269. + }
  127270. +
  127271. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, sharedPageTable));
  127272. + }
  127273. +
  127274. + gcmkFOOTER();
  127275. + return status;
  127276. +#elif gcdMIRROR_PAGETABLE
  127277. + gceSTATUS status;
  127278. + gctPOINTER pointer;
  127279. +
  127280. + gcmkHEADER_ARG("Kernel=0x%08x", Kernel);
  127281. +
  127282. + if (mirrorPageTable == gcvNULL)
  127283. + {
  127284. + gcmkONERROR(
  127285. + gckOS_Allocate(Kernel->os,
  127286. + sizeof(struct _gcsMirrorPageTable),
  127287. + &pointer));
  127288. + mirrorPageTable = pointer;
  127289. +
  127290. + gcmkONERROR(
  127291. + gckOS_ZeroMemory(mirrorPageTable,
  127292. + sizeof(struct _gcsMirrorPageTable)));
  127293. +
  127294. + gcmkONERROR(
  127295. + gckOS_CreateMutex(Kernel->os, &mirrorPageTableMutex));
  127296. + }
  127297. +
  127298. + gcmkONERROR(_Construct(Kernel, MmuSize, Mmu));
  127299. +
  127300. + mirrorPageTable->mmus[mirrorPageTable->reference] = *Mmu;
  127301. +
  127302. + mirrorPageTable->hardwares[mirrorPageTable->reference] = Kernel->hardware;
  127303. +
  127304. + mirrorPageTable->reference++;
  127305. +
  127306. + gcmkFOOTER_ARG("mirrorPageTable->reference=%lu", mirrorPageTable->reference);
  127307. + return gcvSTATUS_OK;
  127308. +
  127309. +OnError:
  127310. + if (mirrorPageTable && mirrorPageTable->reference == 0)
  127311. + {
  127312. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, mirrorPageTable));
  127313. + }
  127314. +
  127315. + gcmkFOOTER();
  127316. + return status;
  127317. +#else
  127318. + return _Construct(Kernel, MmuSize, Mmu);
  127319. +#endif
  127320. +}
  127321. +
  127322. +gceSTATUS
  127323. +gckMMU_Destroy(
  127324. + IN gckMMU Mmu
  127325. + )
  127326. +{
  127327. +#if gcdSHARED_PAGETABLE
  127328. + sharedPageTable->reference--;
  127329. +
  127330. + if (sharedPageTable->reference == 0)
  127331. + {
  127332. + if (sharedPageTable->mmu)
  127333. + {
  127334. + gcmkVERIFY_OK(_Destroy(Mmu));
  127335. + }
  127336. +
  127337. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, sharedPageTable));
  127338. + }
  127339. +
  127340. + return gcvSTATUS_OK;
  127341. +#elif gcdMIRROR_PAGETABLE
  127342. + mirrorPageTable->reference--;
  127343. +
  127344. + if (mirrorPageTable->reference == 0)
  127345. + {
  127346. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTable));
  127347. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTableMutex));
  127348. + }
  127349. +
  127350. + return _Destroy(Mmu);
  127351. +#else
  127352. + return _Destroy(Mmu);
  127353. +#endif
  127354. +}
  127355. +
  127356. +/*******************************************************************************
  127357. +**
  127358. +** gckMMU_AllocatePages
  127359. +**
  127360. +** Allocate pages inside the page table.
  127361. +**
  127362. +** INPUT:
  127363. +**
  127364. +** gckMMU Mmu
  127365. +** Pointer to an gckMMU object.
  127366. +**
  127367. +** gctSIZE_T PageCount
  127368. +** Number of pages to allocate.
  127369. +**
  127370. +** OUTPUT:
  127371. +**
  127372. +** gctPOINTER * PageTable
  127373. +** Pointer to a variable that receives the base address of the page
  127374. +** table.
  127375. +**
  127376. +** gctUINT32 * Address
  127377. +** Pointer to a variable that receives the hardware specific address.
  127378. +*/
  127379. +gceSTATUS
  127380. +_AllocatePages(
  127381. + IN gckMMU Mmu,
  127382. + IN gctSIZE_T PageCount,
  127383. + IN gceSURF_TYPE Type,
  127384. + OUT gctPOINTER * PageTable,
  127385. + OUT gctUINT32 * Address
  127386. + )
  127387. +{
  127388. + gceSTATUS status;
  127389. + gctBOOL mutex = gcvFALSE;
  127390. + gctUINT32 index = 0, previous = ~0U, left;
  127391. + gctUINT32_PTR pageTable;
  127392. + gctBOOL gotIt;
  127393. + gctUINT32 address;
  127394. +
  127395. + gcmkHEADER_ARG("Mmu=0x%x PageCount=%lu", Mmu, PageCount);
  127396. +
  127397. + /* Verify the arguments. */
  127398. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127399. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  127400. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  127401. +
  127402. + if (PageCount > Mmu->pageTableEntries)
  127403. + {
  127404. + gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
  127405. + __FUNCTION__, __LINE__);
  127406. +
  127407. + /* Not enough pages avaiable. */
  127408. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  127409. + }
  127410. +
  127411. + /* Grab the mutex. */
  127412. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  127413. + mutex = gcvTRUE;
  127414. +
  127415. + /* Cast pointer to page table. */
  127416. + for (pageTable = Mmu->pageTableLogical, gotIt = gcvFALSE; !gotIt;)
  127417. + {
  127418. + index = Mmu->heapList;
  127419. +
  127420. + if ((Mmu->hardware->mmuVersion == 0) && (Type == gcvSURF_VERTEX))
  127421. + {
  127422. + gcmkONERROR(_AdjustIndex(
  127423. + Mmu,
  127424. + index,
  127425. + PageCount,
  127426. + gcdVERTEX_START / gcmSIZEOF(gctUINT32),
  127427. + &index
  127428. + ));
  127429. + }
  127430. +
  127431. + /* Walk the heap list. */
  127432. + for (; !gotIt && (index < Mmu->pageTableEntries);)
  127433. + {
  127434. + /* Check the node type. */
  127435. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
  127436. + {
  127437. + case gcvMMU_SINGLE:
  127438. + /* Single odes are valid if we only need 1 page. */
  127439. + if (PageCount == 1)
  127440. + {
  127441. + gotIt = gcvTRUE;
  127442. + }
  127443. + else
  127444. + {
  127445. + /* Move to next node. */
  127446. + previous = index;
  127447. + index = _ReadPageEntry(&pageTable[index]) >> 8;
  127448. + }
  127449. + break;
  127450. +
  127451. + case gcvMMU_FREE:
  127452. + /* Test if the node has enough space. */
  127453. + if (PageCount <= (_ReadPageEntry(&pageTable[index]) >> 8))
  127454. + {
  127455. + gotIt = gcvTRUE;
  127456. + }
  127457. + else
  127458. + {
  127459. + /* Move to next node. */
  127460. + previous = index;
  127461. + index = _ReadPageEntry(&pageTable[index + 1]);
  127462. + }
  127463. + break;
  127464. +
  127465. + default:
  127466. + gcmkFATAL("MMU table correcupted at index %u!", index);
  127467. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  127468. + }
  127469. + }
  127470. +
  127471. + /* Test if we are out of memory. */
  127472. + if (index >= Mmu->pageTableEntries)
  127473. + {
  127474. + if (Mmu->freeNodes)
  127475. + {
  127476. + /* Time to move out the trash! */
  127477. + gcmkONERROR(_Collect(Mmu));
  127478. + }
  127479. + else
  127480. + {
  127481. + gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
  127482. + __FUNCTION__, __LINE__);
  127483. +
  127484. + /* Out of resources. */
  127485. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  127486. + }
  127487. + }
  127488. + }
  127489. +
  127490. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
  127491. + {
  127492. + case gcvMMU_SINGLE:
  127493. + /* Unlink single node from free list. */
  127494. + gcmkONERROR(
  127495. + _Link(Mmu, previous, _ReadPageEntry(&pageTable[index]) >> 8));
  127496. + break;
  127497. +
  127498. + case gcvMMU_FREE:
  127499. + /* Check how many pages will be left. */
  127500. + left = (_ReadPageEntry(&pageTable[index]) >> 8) - PageCount;
  127501. + switch (left)
  127502. + {
  127503. + case 0:
  127504. + /* The entire node is consumed, just unlink it. */
  127505. + gcmkONERROR(
  127506. + _Link(Mmu, previous, _ReadPageEntry(&pageTable[index + 1])));
  127507. + break;
  127508. +
  127509. + case 1:
  127510. + /* One page will remain. Convert the node to a single node and
  127511. + ** advance the index. */
  127512. + _WritePageEntry(&pageTable[index], (_ReadPageEntry(&pageTable[index + 1]) << 8) | gcvMMU_SINGLE);
  127513. + index ++;
  127514. + break;
  127515. +
  127516. + default:
  127517. + /* Enough pages remain for a new node. However, we will just adjust
  127518. + ** the size of the current node and advance the index. */
  127519. + _WritePageEntry(&pageTable[index], (left << 8) | gcvMMU_FREE);
  127520. + index += left;
  127521. + break;
  127522. + }
  127523. + break;
  127524. + }
  127525. +
  127526. + /* Mark node as used. */
  127527. + gcmkONERROR(_FillPageTable(&pageTable[index], PageCount, gcvMMU_USED));
  127528. +
  127529. + /* Return pointer to page table. */
  127530. + *PageTable = &pageTable[index];
  127531. +
  127532. + /* Build virtual address. */
  127533. + if (Mmu->hardware->mmuVersion == 0)
  127534. + {
  127535. + gcmkONERROR(
  127536. + gckHARDWARE_BuildVirtualAddress(Mmu->hardware, index, 0, &address));
  127537. + }
  127538. + else
  127539. + {
  127540. + gctUINT32 masterOffset = index / gcdMMU_STLB_4K_ENTRY_NUM
  127541. + + Mmu->dynamicMappingStart;
  127542. + gctUINT32 slaveOffset = index % gcdMMU_STLB_4K_ENTRY_NUM;
  127543. +
  127544. + address = (masterOffset << gcdMMU_MTLB_SHIFT)
  127545. + | (slaveOffset << gcdMMU_STLB_4K_SHIFT);
  127546. + }
  127547. +
  127548. + if (Address != gcvNULL)
  127549. + {
  127550. + *Address = address;
  127551. + }
  127552. +
  127553. + /* Release the mutex. */
  127554. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  127555. +
  127556. + /* Success. */
  127557. + gcmkFOOTER_ARG("*PageTable=0x%x *Address=%08x",
  127558. + *PageTable, gcmOPT_VALUE(Address));
  127559. + return gcvSTATUS_OK;
  127560. +
  127561. +OnError:
  127562. +
  127563. + if (mutex)
  127564. + {
  127565. + /* Release the mutex. */
  127566. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  127567. + }
  127568. +
  127569. + /* Return the status. */
  127570. + gcmkFOOTER();
  127571. + return status;
  127572. +}
  127573. +
  127574. +/*******************************************************************************
  127575. +**
  127576. +** gckMMU_FreePages
  127577. +**
  127578. +** Free pages inside the page table.
  127579. +**
  127580. +** INPUT:
  127581. +**
  127582. +** gckMMU Mmu
  127583. +** Pointer to an gckMMU object.
  127584. +**
  127585. +** gctPOINTER PageTable
  127586. +** Base address of the page table to free.
  127587. +**
  127588. +** gctSIZE_T PageCount
  127589. +** Number of pages to free.
  127590. +**
  127591. +** OUTPUT:
  127592. +**
  127593. +** Nothing.
  127594. +*/
  127595. +gceSTATUS
  127596. +_FreePages(
  127597. + IN gckMMU Mmu,
  127598. + IN gctPOINTER PageTable,
  127599. + IN gctSIZE_T PageCount
  127600. + )
  127601. +{
  127602. + gctUINT32_PTR pageTable;
  127603. + gceSTATUS status;
  127604. + gctBOOL acquired = gcvFALSE;
  127605. +
  127606. + gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=%lu",
  127607. + Mmu, PageTable, PageCount);
  127608. +
  127609. + /* Verify the arguments. */
  127610. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127611. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  127612. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  127613. +
  127614. + /* Convert the pointer. */
  127615. + pageTable = (gctUINT32_PTR) PageTable;
  127616. +
  127617. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  127618. + acquired = gcvTRUE;
  127619. +
  127620. +#if gcdMMU_CLEAR_VALUE
  127621. + if (Mmu->hardware->mmuVersion == 0)
  127622. + {
  127623. + _FillPageTable(pageTable, PageCount, gcdMMU_CLEAR_VALUE);
  127624. + }
  127625. +#endif
  127626. +
  127627. + if (PageCount == 1)
  127628. + {
  127629. + /* Single page node. */
  127630. + _WritePageEntry(pageTable,
  127631. + (~((1U<<8)-1)) | gcvMMU_SINGLE
  127632. +#if gcdUSE_MMU_EXCEPTION
  127633. + /* Enable exception */
  127634. + | 1 << 1
  127635. +#endif
  127636. + );
  127637. + }
  127638. + else
  127639. + {
  127640. + /* Mark the node as free. */
  127641. + _WritePageEntry(pageTable,
  127642. + (PageCount << 8) | gcvMMU_FREE
  127643. +#if gcdUSE_MMU_EXCEPTION
  127644. + /* Enable exception */
  127645. + | 1 << 1
  127646. +#endif
  127647. + );
  127648. + _WritePageEntry(pageTable + 1, ~0U);
  127649. +
  127650. +#if gcdUSE_MMU_EXCEPTION
  127651. + /* Enable exception */
  127652. + gcmkVERIFY_OK(_FillPageTable(pageTable + 2, PageCount - 2, 1 << 1));
  127653. +#endif
  127654. + }
  127655. +
  127656. + /* We have free nodes. */
  127657. + Mmu->freeNodes = gcvTRUE;
  127658. +
  127659. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  127660. + acquired = gcvFALSE;
  127661. +
  127662. + /* Success. */
  127663. + gcmkFOOTER_NO();
  127664. + return gcvSTATUS_OK;
  127665. +
  127666. +OnError:
  127667. + if (acquired)
  127668. + {
  127669. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  127670. + }
  127671. +
  127672. + gcmkFOOTER();
  127673. + return status;
  127674. +}
  127675. +
  127676. +gceSTATUS
  127677. +gckMMU_AllocatePages(
  127678. + IN gckMMU Mmu,
  127679. + IN gctSIZE_T PageCount,
  127680. + OUT gctPOINTER * PageTable,
  127681. + OUT gctUINT32 * Address
  127682. + )
  127683. +{
  127684. + return gckMMU_AllocatePagesEx(
  127685. + Mmu, PageCount, gcvSURF_UNKNOWN, PageTable, Address);
  127686. +}
  127687. +
  127688. +gceSTATUS
  127689. +gckMMU_AllocatePagesEx(
  127690. + IN gckMMU Mmu,
  127691. + IN gctSIZE_T PageCount,
  127692. + IN gceSURF_TYPE Type,
  127693. + OUT gctPOINTER * PageTable,
  127694. + OUT gctUINT32 * Address
  127695. + )
  127696. +{
  127697. +#if gcdMIRROR_PAGETABLE
  127698. + gceSTATUS status;
  127699. + gctPOINTER pageTable;
  127700. + gctUINT32 address;
  127701. + gctINT i;
  127702. + gckMMU mmu;
  127703. + gctBOOL acquired = gcvFALSE;
  127704. + gctBOOL allocated = gcvFALSE;
  127705. +
  127706. + gckOS_AcquireMutex(Mmu->os, mirrorPageTableMutex, gcvINFINITE);
  127707. + acquired = gcvTRUE;
  127708. +
  127709. + /* Allocate page table for current MMU. */
  127710. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  127711. + {
  127712. + if (Mmu == mirrorPageTable->mmus[i])
  127713. + {
  127714. + gcmkONERROR(_AllocatePages(Mmu, PageCount, Type, PageTable, Address));
  127715. + allocated = gcvTRUE;
  127716. + }
  127717. + }
  127718. +
  127719. + /* Allocate page table for other MMUs. */
  127720. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  127721. + {
  127722. + mmu = mirrorPageTable->mmus[i];
  127723. +
  127724. + if (Mmu != mmu)
  127725. + {
  127726. + gcmkONERROR(_AllocatePages(mmu, PageCount, Type, &pageTable, &address));
  127727. + gcmkASSERT(address == *Address);
  127728. + }
  127729. + }
  127730. +
  127731. + gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex);
  127732. + acquired = gcvFALSE;
  127733. +
  127734. + return gcvSTATUS_OK;
  127735. +OnError:
  127736. +
  127737. + if (allocated)
  127738. + {
  127739. + /* Page tables for multiple GPU always keep the same. So it is impossible
  127740. + * the fist one allocates successfully but others fail.
  127741. + */
  127742. + gcmkASSERT(0);
  127743. + }
  127744. +
  127745. + if (acquired)
  127746. + {
  127747. + gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex);
  127748. + }
  127749. +
  127750. + return status;
  127751. +#else
  127752. + return _AllocatePages(Mmu, PageCount, Type, PageTable, Address);
  127753. +#endif
  127754. +}
  127755. +
  127756. +gceSTATUS
  127757. +gckMMU_FreePages(
  127758. + IN gckMMU Mmu,
  127759. + IN gctPOINTER PageTable,
  127760. + IN gctSIZE_T PageCount
  127761. + )
  127762. +{
  127763. +#if gcdMIRROR_PAGETABLE
  127764. + gctINT i;
  127765. + gctUINT32 offset;
  127766. + gckMMU mmu;
  127767. +
  127768. + gckOS_AcquireMutex(Mmu->os, mirrorPageTableMutex, gcvINFINITE);
  127769. +
  127770. + gcmkVERIFY_OK(_FreePages(Mmu, PageTable, PageCount));
  127771. +
  127772. + offset = (gctUINT32)PageTable - (gctUINT32)Mmu->pageTableLogical;
  127773. +
  127774. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  127775. + {
  127776. + mmu = mirrorPageTable->mmus[i];
  127777. +
  127778. + if (mmu != Mmu)
  127779. + {
  127780. + gcmkVERIFY_OK(_FreePages(mmu, mmu->pageTableLogical + offset/4, PageCount));
  127781. + }
  127782. + }
  127783. +
  127784. + gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex);
  127785. +
  127786. + return gcvSTATUS_OK;
  127787. +#else
  127788. + return _FreePages(Mmu, PageTable, PageCount);
  127789. +#endif
  127790. +}
  127791. +
  127792. +gceSTATUS
  127793. +gckMMU_Enable(
  127794. + IN gckMMU Mmu,
  127795. + IN gctUINT32 PhysBaseAddr,
  127796. + IN gctUINT32 PhysSize
  127797. + )
  127798. +{
  127799. + gceSTATUS status;
  127800. +#if gcdSHARED_PAGETABLE
  127801. + gckHARDWARE hardware;
  127802. + gctINT i;
  127803. +#endif
  127804. +
  127805. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  127806. +
  127807. + /* Verify the arguments. */
  127808. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127809. +
  127810. +#if gcdSHARED_PAGETABLE
  127811. + if (Mmu->enabled)
  127812. + {
  127813. + gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP);
  127814. + return gcvSTATUS_SKIP;
  127815. + }
  127816. +#endif
  127817. +
  127818. + if (Mmu->hardware->mmuVersion == 0)
  127819. + {
  127820. + /* Success. */
  127821. + gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP);
  127822. + return gcvSTATUS_SKIP;
  127823. + }
  127824. + else
  127825. + {
  127826. + if (PhysSize != 0)
  127827. + {
  127828. + gcmkONERROR(_FillFlatMapping(
  127829. + Mmu,
  127830. + PhysBaseAddr,
  127831. + PhysSize
  127832. + ));
  127833. + }
  127834. +
  127835. + gcmkONERROR(_SetupDynamicSpace(Mmu));
  127836. +
  127837. +#if gcdSHARED_PAGETABLE
  127838. + for(i = 0; i < gcdMAX_GPU_COUNT; i++)
  127839. + {
  127840. + hardware = sharedPageTable->hardwares[i];
  127841. + if (hardware != gcvNULL)
  127842. + {
  127843. + gcmkONERROR(
  127844. + gckHARDWARE_SetMMUv2(
  127845. + hardware,
  127846. + gcvTRUE,
  127847. + Mmu->mtlbLogical,
  127848. + gcvMMU_MODE_4K,
  127849. + (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
  127850. + gcvFALSE
  127851. + ));
  127852. + }
  127853. + }
  127854. +#else
  127855. + gcmkONERROR(
  127856. + gckHARDWARE_SetMMUv2(
  127857. + Mmu->hardware,
  127858. + gcvTRUE,
  127859. + Mmu->mtlbLogical,
  127860. + gcvMMU_MODE_4K,
  127861. + (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
  127862. + gcvFALSE
  127863. + ));
  127864. +#endif
  127865. +
  127866. + Mmu->enabled = gcvTRUE;
  127867. +
  127868. + /* Success. */
  127869. + gcmkFOOTER_NO();
  127870. + return gcvSTATUS_OK;
  127871. + }
  127872. +
  127873. +OnError:
  127874. + /* Return the status. */
  127875. + gcmkFOOTER();
  127876. + return status;
  127877. +}
  127878. +
  127879. +gceSTATUS
  127880. +gckMMU_SetPage(
  127881. + IN gckMMU Mmu,
  127882. + IN gctUINT32 PageAddress,
  127883. + IN gctUINT32 *PageEntry
  127884. + )
  127885. +{
  127886. +#if gcdMIRROR_PAGETABLE
  127887. + gctUINT32_PTR pageEntry;
  127888. + gctINT i;
  127889. + gckMMU mmu;
  127890. + gctUINT32 offset = (gctUINT32)PageEntry - (gctUINT32)Mmu->pageTableLogical;
  127891. +#endif
  127892. +
  127893. + gctUINT32 data;
  127894. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  127895. +
  127896. + /* Verify the arguments. */
  127897. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127898. + gcmkVERIFY_ARGUMENT(PageEntry != gcvNULL);
  127899. + gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
  127900. +
  127901. + if (Mmu->hardware->mmuVersion == 0)
  127902. + {
  127903. + data = PageAddress;
  127904. + }
  127905. + else
  127906. + {
  127907. + data = _SetPage(PageAddress);
  127908. + }
  127909. +
  127910. + _WritePageEntry(PageEntry, data);
  127911. +
  127912. +#if gcdMIRROR_PAGETABLE
  127913. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  127914. + {
  127915. + mmu = mirrorPageTable->mmus[i];
  127916. +
  127917. + if (mmu != Mmu)
  127918. + {
  127919. + pageEntry = mmu->pageTableLogical + offset / 4;
  127920. +
  127921. + if (mmu->hardware->mmuVersion == 0)
  127922. + {
  127923. + _WritePageEntry(pageEntry, PageAddress);
  127924. + }
  127925. + else
  127926. + {
  127927. + _WritePageEntry(pageEntry, _SetPage(PageAddress));
  127928. + }
  127929. + }
  127930. +
  127931. + }
  127932. +#endif
  127933. + /* Success. */
  127934. + gcmkFOOTER_NO();
  127935. + return gcvSTATUS_OK;
  127936. +}
  127937. +
  127938. +#ifdef __QNXNTO__
  127939. +gceSTATUS
  127940. +gckMMU_InsertNode(
  127941. + IN gckMMU Mmu,
  127942. + IN gcuVIDMEM_NODE_PTR Node)
  127943. +{
  127944. + gceSTATUS status;
  127945. + gctBOOL mutex = gcvFALSE;
  127946. +
  127947. + gcmkHEADER_ARG("Mmu=0x%x Node=0x%x", Mmu, Node);
  127948. +
  127949. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127950. +
  127951. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
  127952. + mutex = gcvTRUE;
  127953. +
  127954. + Node->Virtual.next = Mmu->nodeList;
  127955. + Mmu->nodeList = Node;
  127956. +
  127957. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  127958. +
  127959. + gcmkFOOTER();
  127960. + return gcvSTATUS_OK;
  127961. +
  127962. +OnError:
  127963. + if (mutex)
  127964. + {
  127965. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  127966. + }
  127967. +
  127968. + gcmkFOOTER();
  127969. + return status;
  127970. +}
  127971. +
  127972. +gceSTATUS
  127973. +gckMMU_RemoveNode(
  127974. + IN gckMMU Mmu,
  127975. + IN gcuVIDMEM_NODE_PTR Node)
  127976. +{
  127977. + gceSTATUS status;
  127978. + gctBOOL mutex = gcvFALSE;
  127979. + gcuVIDMEM_NODE_PTR *iter;
  127980. +
  127981. + gcmkHEADER_ARG("Mmu=0x%x Node=0x%x", Mmu, Node);
  127982. +
  127983. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127984. +
  127985. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
  127986. + mutex = gcvTRUE;
  127987. +
  127988. + for (iter = &Mmu->nodeList; *iter; iter = &(*iter)->Virtual.next)
  127989. + {
  127990. + if (*iter == Node)
  127991. + {
  127992. + *iter = Node->Virtual.next;
  127993. + break;
  127994. + }
  127995. + }
  127996. +
  127997. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  127998. +
  127999. + gcmkFOOTER();
  128000. + return gcvSTATUS_OK;
  128001. +
  128002. +OnError:
  128003. + if (mutex)
  128004. + {
  128005. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  128006. + }
  128007. +
  128008. + gcmkFOOTER();
  128009. + return status;
  128010. +}
  128011. +
  128012. +gceSTATUS
  128013. +gckMMU_FreeHandleMemory(
  128014. + IN gckKERNEL Kernel,
  128015. + IN gckMMU Mmu,
  128016. + IN gctUINT32 Pid
  128017. + )
  128018. +{
  128019. + gceSTATUS status;
  128020. + gctBOOL acquired = gcvFALSE;
  128021. + gcuVIDMEM_NODE_PTR curr, next;
  128022. +
  128023. + gcmkHEADER_ARG("Kernel=0x%x, Mmu=0x%x Pid=%u", Kernel, Mmu, Pid);
  128024. +
  128025. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  128026. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  128027. +
  128028. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
  128029. + acquired = gcvTRUE;
  128030. +
  128031. + for (curr = Mmu->nodeList; curr != gcvNULL; curr = next)
  128032. + {
  128033. + next = curr->Virtual.next;
  128034. +
  128035. + if (curr->Virtual.processID == Pid)
  128036. + {
  128037. + while (curr->Virtual.unlockPendings[Kernel->core] == 0 && curr->Virtual.lockeds[Kernel->core] > 0)
  128038. + {
  128039. + gcmkONERROR(gckVIDMEM_Unlock(Kernel, curr, gcvSURF_TYPE_UNKNOWN, gcvNULL));
  128040. + }
  128041. +
  128042. + gcmkVERIFY_OK(gckVIDMEM_Free(curr));
  128043. + }
  128044. + }
  128045. +
  128046. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  128047. +
  128048. + gcmkFOOTER();
  128049. + return gcvSTATUS_OK;
  128050. +
  128051. +OnError:
  128052. + if (acquired)
  128053. + {
  128054. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  128055. + }
  128056. +
  128057. + gcmkFOOTER();
  128058. + return status;
  128059. +}
  128060. +#endif
  128061. +
  128062. +gceSTATUS
  128063. +gckMMU_Flush(
  128064. + IN gckMMU Mmu
  128065. + )
  128066. +{
  128067. + gckHARDWARE hardware;
  128068. +#if gcdSHARED_PAGETABLE
  128069. + gctINT i;
  128070. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  128071. + {
  128072. +#if gcdENABLE_VG
  128073. + if (i == gcvCORE_VG)
  128074. + {
  128075. + continue;
  128076. + }
  128077. +#endif
  128078. + hardware = sharedPageTable->hardwares[i];
  128079. + if (hardware)
  128080. + {
  128081. + /* Notify cores who use this page table. */
  128082. + gcmkVERIFY_OK(
  128083. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  128084. + }
  128085. + }
  128086. +#elif gcdMIRROR_PAGETABLE
  128087. + gctINT i;
  128088. + for (i = 0; i < mirrorPageTable->reference; i++)
  128089. + {
  128090. + hardware = mirrorPageTable->hardwares[i];
  128091. +
  128092. + /* Notify cores who use this page table. */
  128093. + gcmkVERIFY_OK(
  128094. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  128095. + }
  128096. +#else
  128097. + hardware = Mmu->hardware;
  128098. + gcmkVERIFY_OK(
  128099. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  128100. +#endif
  128101. +
  128102. + return gcvSTATUS_OK;
  128103. +}
  128104. +
  128105. +gceSTATUS
  128106. +gckMMU_DumpPageTableEntry(
  128107. + IN gckMMU Mmu,
  128108. + IN gctUINT32 Address
  128109. + )
  128110. +{
  128111. + gctUINT32_PTR pageTable;
  128112. + gctUINT32 index;
  128113. + gctUINT32 mtlb, stlb;
  128114. +
  128115. + gcmkHEADER_ARG("Mmu=0x%08X Address=0x%08X", Mmu, Address);
  128116. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  128117. +
  128118. + gcmkASSERT(Mmu->hardware->mmuVersion > 0);
  128119. +
  128120. + mtlb = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
  128121. + stlb = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
  128122. +
  128123. + if (Address >= 0x80000000)
  128124. + {
  128125. + pageTable = Mmu->pageTableLogical;
  128126. +
  128127. + index = (mtlb - Mmu->dynamicMappingStart)
  128128. + * gcdMMU_STLB_4K_ENTRY_NUM
  128129. + + stlb;
  128130. +
  128131. + gcmkPRINT(" Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
  128132. + }
  128133. +
  128134. + gcmkFOOTER_NO();
  128135. + return gcvSTATUS_OK;
  128136. +}
  128137. +
  128138. +/******************************************************************************
  128139. +****************************** T E S T C O D E ******************************
  128140. +******************************************************************************/
  128141. +
  128142. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c
  128143. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c 1970-01-01 01:00:00.000000000 +0100
  128144. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c 2014-08-20 19:23:53.562845855 +0200
  128145. @@ -0,0 +1,522 @@
  128146. +/****************************************************************************
  128147. +*
  128148. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  128149. +*
  128150. +* This program is free software; you can redistribute it and/or modify
  128151. +* it under the terms of the GNU General Public License as published by
  128152. +* the Free Software Foundation; either version 2 of the license, or
  128153. +* (at your option) any later version.
  128154. +*
  128155. +* This program is distributed in the hope that it will be useful,
  128156. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  128157. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  128158. +* GNU General Public License for more details.
  128159. +*
  128160. +* You should have received a copy of the GNU General Public License
  128161. +* along with this program; if not write to the Free Software
  128162. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  128163. +*
  128164. +*****************************************************************************/
  128165. +
  128166. +
  128167. +#include "gc_hal_kernel_precomp.h"
  128168. +
  128169. +#if gcdENABLE_VG
  128170. +
  128171. +#define _GC_OBJ_ZONE gcvZONE_MMU
  128172. +
  128173. +/*******************************************************************************
  128174. +**
  128175. +** gckVGMMU_Construct
  128176. +**
  128177. +** Construct a new gckVGMMU object.
  128178. +**
  128179. +** INPUT:
  128180. +**
  128181. +** gckVGKERNEL Kernel
  128182. +** Pointer to an gckVGKERNEL object.
  128183. +**
  128184. +** gctSIZE_T MmuSize
  128185. +** Number of bytes for the page table.
  128186. +**
  128187. +** OUTPUT:
  128188. +**
  128189. +** gckVGMMU * Mmu
  128190. +** Pointer to a variable that receives the gckVGMMU object pointer.
  128191. +*/
  128192. +gceSTATUS gckVGMMU_Construct(
  128193. + IN gckVGKERNEL Kernel,
  128194. + IN gctSIZE_T MmuSize,
  128195. + OUT gckVGMMU * Mmu
  128196. + )
  128197. +{
  128198. + gckOS os;
  128199. + gckVGHARDWARE hardware;
  128200. + gceSTATUS status;
  128201. + gckVGMMU mmu;
  128202. + gctUINT32 * pageTable;
  128203. + gctUINT32 i;
  128204. +
  128205. + gcmkHEADER_ARG("Kernel=0x%x MmuSize=0x%x Mmu=0x%x", Kernel, MmuSize, Mmu);
  128206. +
  128207. + /* Verify the arguments. */
  128208. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  128209. + gcmkVERIFY_ARGUMENT(MmuSize > 0);
  128210. + gcmkVERIFY_ARGUMENT(Mmu != gcvNULL);
  128211. +
  128212. + /* Extract the gckOS object pointer. */
  128213. + os = Kernel->os;
  128214. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  128215. +
  128216. + /* Extract the gckVGHARDWARE object pointer. */
  128217. + hardware = Kernel->hardware;
  128218. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  128219. +
  128220. + /* Allocate memory for the gckVGMMU object. */
  128221. + status = gckOS_Allocate(os, sizeof(struct _gckVGMMU), (gctPOINTER *) &mmu);
  128222. +
  128223. + if (status < 0)
  128224. + {
  128225. + /* Error. */
  128226. + gcmkFATAL(
  128227. + "%s(%d): could not allocate gckVGMMU object.",
  128228. + __FUNCTION__, __LINE__
  128229. + );
  128230. +
  128231. + gcmkFOOTER();
  128232. + return status;
  128233. + }
  128234. +
  128235. + /* Initialize the gckVGMMU object. */
  128236. + mmu->object.type = gcvOBJ_MMU;
  128237. + mmu->os = os;
  128238. + mmu->hardware = hardware;
  128239. +
  128240. + /* Create the mutex. */
  128241. + status = gckOS_CreateMutex(os, &mmu->mutex);
  128242. +
  128243. + if (status < 0)
  128244. + {
  128245. + /* Roll back. */
  128246. + mmu->object.type = gcvOBJ_UNKNOWN;
  128247. + gcmkVERIFY_OK(gckOS_Free(os, mmu));
  128248. +
  128249. + gcmkFOOTER();
  128250. + /* Error. */
  128251. + return status;
  128252. + }
  128253. +
  128254. + /* Allocate the page table. */
  128255. + mmu->pageTableSize = MmuSize;
  128256. + status = gckOS_AllocateContiguous(os,
  128257. + gcvFALSE,
  128258. + &mmu->pageTableSize,
  128259. + &mmu->pageTablePhysical,
  128260. + &mmu->pageTableLogical);
  128261. +
  128262. + if (status < 0)
  128263. + {
  128264. + /* Roll back. */
  128265. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, mmu->mutex));
  128266. +
  128267. + mmu->object.type = gcvOBJ_UNKNOWN;
  128268. + gcmkVERIFY_OK(gckOS_Free(os, mmu));
  128269. +
  128270. + /* Error. */
  128271. + gcmkFATAL(
  128272. + "%s(%d): could not allocate page table.",
  128273. + __FUNCTION__, __LINE__
  128274. + );
  128275. +
  128276. + gcmkFOOTER();
  128277. + return status;
  128278. + }
  128279. +
  128280. + /* Compute number of entries in page table. */
  128281. + mmu->entryCount = mmu->pageTableSize / sizeof(gctUINT32);
  128282. + mmu->entry = 0;
  128283. +
  128284. + /* Mark the entire page table as available. */
  128285. + pageTable = (gctUINT32 *) mmu->pageTableLogical;
  128286. + for (i = 0; i < mmu->entryCount; i++)
  128287. + {
  128288. + pageTable[i] = (gctUINT32)~0;
  128289. + }
  128290. +
  128291. + /* Set page table address. */
  128292. + status = gckVGHARDWARE_SetMMU(hardware, mmu->pageTableLogical);
  128293. +
  128294. + if (status < 0)
  128295. + {
  128296. + /* Free the page table. */
  128297. + gcmkVERIFY_OK(gckOS_FreeContiguous(mmu->os,
  128298. + mmu->pageTablePhysical,
  128299. + mmu->pageTableLogical,
  128300. + mmu->pageTableSize));
  128301. +
  128302. + /* Roll back. */
  128303. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, mmu->mutex));
  128304. +
  128305. + mmu->object.type = gcvOBJ_UNKNOWN;
  128306. + gcmkVERIFY_OK(gckOS_Free(os, mmu));
  128307. +
  128308. + /* Error. */
  128309. + gcmkFATAL(
  128310. + "%s(%d): could not program page table.",
  128311. + __FUNCTION__, __LINE__
  128312. + );
  128313. +
  128314. + gcmkFOOTER();
  128315. + return status;
  128316. + }
  128317. +
  128318. + /* Return the gckVGMMU object pointer. */
  128319. + *Mmu = mmu;
  128320. +
  128321. + gcmkTRACE_ZONE(
  128322. + gcvLEVEL_INFO, gcvZONE_MMU,
  128323. + "%s(%d): %u entries at %p.(0x%08X)\n",
  128324. + __FUNCTION__, __LINE__,
  128325. + mmu->entryCount,
  128326. + mmu->pageTableLogical,
  128327. + mmu->pageTablePhysical
  128328. + );
  128329. +
  128330. + gcmkFOOTER_NO();
  128331. + /* Success. */
  128332. + return gcvSTATUS_OK;
  128333. +}
  128334. +
  128335. +/*******************************************************************************
  128336. +**
  128337. +** gckVGMMU_Destroy
  128338. +**
  128339. +** Destroy a nAQMMU object.
  128340. +**
  128341. +** INPUT:
  128342. +**
  128343. +** gckVGMMU Mmu
  128344. +** Pointer to an gckVGMMU object.
  128345. +**
  128346. +** OUTPUT:
  128347. +**
  128348. +** Nothing.
  128349. +*/
  128350. +gceSTATUS gckVGMMU_Destroy(
  128351. + IN gckVGMMU Mmu
  128352. + )
  128353. +{
  128354. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  128355. +
  128356. + /* Verify the arguments. */
  128357. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  128358. +
  128359. + /* Free the page table. */
  128360. + gcmkVERIFY_OK(gckOS_FreeContiguous(Mmu->os,
  128361. + Mmu->pageTablePhysical,
  128362. + Mmu->pageTableLogical,
  128363. + Mmu->pageTableSize));
  128364. +
  128365. + /* Roll back. */
  128366. + gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->mutex));
  128367. +
  128368. + /* Mark the gckVGMMU object as unknown. */
  128369. + Mmu->object.type = gcvOBJ_UNKNOWN;
  128370. +
  128371. + /* Free the gckVGMMU object. */
  128372. + gcmkVERIFY_OK(gckOS_Free(Mmu->os, Mmu));
  128373. +
  128374. + gcmkFOOTER_NO();
  128375. + /* Success. */
  128376. + return gcvSTATUS_OK;
  128377. +}
  128378. +
  128379. +/*******************************************************************************
  128380. +**
  128381. +** gckVGMMU_AllocatePages
  128382. +**
  128383. +** Allocate pages inside the page table.
  128384. +**
  128385. +** INPUT:
  128386. +**
  128387. +** gckVGMMU Mmu
  128388. +** Pointer to an gckVGMMU object.
  128389. +**
  128390. +** gctSIZE_T PageCount
  128391. +** Number of pages to allocate.
  128392. +**
  128393. +** OUTPUT:
  128394. +**
  128395. +** gctPOINTER * PageTable
  128396. +** Pointer to a variable that receives the base address of the page
  128397. +** table.
  128398. +**
  128399. +** gctUINT32 * Address
  128400. +** Pointer to a variable that receives the hardware specific address.
  128401. +*/
  128402. +gceSTATUS gckVGMMU_AllocatePages(
  128403. + IN gckVGMMU Mmu,
  128404. + IN gctSIZE_T PageCount,
  128405. + OUT gctPOINTER * PageTable,
  128406. + OUT gctUINT32 * Address
  128407. + )
  128408. +{
  128409. + gceSTATUS status;
  128410. + gctUINT32 tail, index, i;
  128411. + gctUINT32 * table;
  128412. + gctBOOL allocated = gcvFALSE;
  128413. +
  128414. + gcmkHEADER_ARG("Mmu=0x%x PageCount=0x%x PageTable=0x%x Address=0x%x",
  128415. + Mmu, PageCount, PageTable, Address);
  128416. +
  128417. + /* Verify the arguments. */
  128418. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  128419. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  128420. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  128421. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  128422. +
  128423. + gcmkTRACE_ZONE(
  128424. + gcvLEVEL_INFO, gcvZONE_MMU,
  128425. + "%s(%d): %u pages.\n",
  128426. + __FUNCTION__, __LINE__,
  128427. + PageCount
  128428. + );
  128429. +
  128430. + if (PageCount > Mmu->entryCount)
  128431. + {
  128432. + gcmkTRACE_ZONE(
  128433. + gcvLEVEL_ERROR, gcvZONE_MMU,
  128434. + "%s(%d): page table too small for %u pages.\n",
  128435. + __FUNCTION__, __LINE__,
  128436. + PageCount
  128437. + );
  128438. +
  128439. + gcmkFOOTER_NO();
  128440. + /* Not enough pages avaiable. */
  128441. + return gcvSTATUS_OUT_OF_RESOURCES;
  128442. + }
  128443. +
  128444. + /* Grab the mutex. */
  128445. + status = gckOS_AcquireMutex(Mmu->os, Mmu->mutex, gcvINFINITE);
  128446. +
  128447. + if (status < 0)
  128448. + {
  128449. + gcmkTRACE_ZONE(
  128450. + gcvLEVEL_ERROR, gcvZONE_MMU,
  128451. + "%s(%d): could not acquire mutex.\n"
  128452. + ,__FUNCTION__, __LINE__
  128453. + );
  128454. +
  128455. + gcmkFOOTER();
  128456. + /* Error. */
  128457. + return status;
  128458. + }
  128459. +
  128460. + /* Compute the tail for this allocation. */
  128461. + tail = Mmu->entryCount - PageCount;
  128462. +
  128463. + /* Walk all entries until we find enough slots. */
  128464. + for (index = Mmu->entry; index <= tail;)
  128465. + {
  128466. + /* Access page table. */
  128467. + table = (gctUINT32 *) Mmu->pageTableLogical + index;
  128468. +
  128469. + /* See if all slots are available. */
  128470. + for (i = 0; i < PageCount; i++, table++)
  128471. + {
  128472. + if (*table != ~0)
  128473. + {
  128474. + /* Start from next slot. */
  128475. + index += i + 1;
  128476. + break;
  128477. + }
  128478. + }
  128479. +
  128480. + if (i == PageCount)
  128481. + {
  128482. + /* Bail out if we have enough page entries. */
  128483. + allocated = gcvTRUE;
  128484. + break;
  128485. + }
  128486. + }
  128487. +
  128488. + if (!allocated)
  128489. + {
  128490. + if (status >= 0)
  128491. + {
  128492. + /* Walk all entries until we find enough slots. */
  128493. + for (index = 0; index <= tail;)
  128494. + {
  128495. + /* Access page table. */
  128496. + table = (gctUINT32 *) Mmu->pageTableLogical + index;
  128497. +
  128498. + /* See if all slots are available. */
  128499. + for (i = 0; i < PageCount; i++, table++)
  128500. + {
  128501. + if (*table != ~0)
  128502. + {
  128503. + /* Start from next slot. */
  128504. + index += i + 1;
  128505. + break;
  128506. + }
  128507. + }
  128508. +
  128509. + if (i == PageCount)
  128510. + {
  128511. + /* Bail out if we have enough page entries. */
  128512. + allocated = gcvTRUE;
  128513. + break;
  128514. + }
  128515. + }
  128516. + }
  128517. + }
  128518. +
  128519. + if (!allocated && (status >= 0))
  128520. + {
  128521. + gcmkTRACE_ZONE(
  128522. + gcvLEVEL_ERROR, gcvZONE_MMU,
  128523. + "%s(%d): not enough free pages for %u pages.\n",
  128524. + __FUNCTION__, __LINE__,
  128525. + PageCount
  128526. + );
  128527. +
  128528. + /* Not enough empty slots available. */
  128529. + status = gcvSTATUS_OUT_OF_RESOURCES;
  128530. + }
  128531. +
  128532. + if (status >= 0)
  128533. + {
  128534. + /* Build virtual address. */
  128535. + status = gckVGHARDWARE_BuildVirtualAddress(Mmu->hardware,
  128536. + index,
  128537. + 0,
  128538. + Address);
  128539. +
  128540. + if (status >= 0)
  128541. + {
  128542. + /* Update current entry into page table. */
  128543. + Mmu->entry = index + PageCount;
  128544. +
  128545. + /* Return pointer to page table. */
  128546. + *PageTable = (gctUINT32 *) Mmu->pageTableLogical + index;
  128547. +
  128548. + gcmkTRACE_ZONE(
  128549. + gcvLEVEL_INFO, gcvZONE_MMU,
  128550. + "%s(%d): allocated %u pages at index %u (0x%08X) @ %p.\n",
  128551. + __FUNCTION__, __LINE__,
  128552. + PageCount,
  128553. + index,
  128554. + *Address,
  128555. + *PageTable
  128556. + );
  128557. + }
  128558. + }
  128559. +
  128560. + /* Release the mutex. */
  128561. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->mutex));
  128562. + gcmkFOOTER();
  128563. +
  128564. + /* Return status. */
  128565. + return status;
  128566. +}
  128567. +
  128568. +/*******************************************************************************
  128569. +**
  128570. +** gckVGMMU_FreePages
  128571. +**
  128572. +** Free pages inside the page table.
  128573. +**
  128574. +** INPUT:
  128575. +**
  128576. +** gckVGMMU Mmu
  128577. +** Pointer to an gckVGMMU object.
  128578. +**
  128579. +** gctPOINTER PageTable
  128580. +** Base address of the page table to free.
  128581. +**
  128582. +** gctSIZE_T PageCount
  128583. +** Number of pages to free.
  128584. +**
  128585. +** OUTPUT:
  128586. +**
  128587. +** Nothing.
  128588. +*/
  128589. +gceSTATUS gckVGMMU_FreePages(
  128590. + IN gckVGMMU Mmu,
  128591. + IN gctPOINTER PageTable,
  128592. + IN gctSIZE_T PageCount
  128593. + )
  128594. +{
  128595. + gctUINT32 * table;
  128596. +
  128597. + gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=0x%x",
  128598. + Mmu, PageTable, PageCount);
  128599. +
  128600. + /* Verify the arguments. */
  128601. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  128602. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  128603. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  128604. +
  128605. + gcmkTRACE_ZONE(
  128606. + gcvLEVEL_INFO, gcvZONE_MMU,
  128607. + "%s(%d): freeing %u pages at index %u @ %p.\n",
  128608. + __FUNCTION__, __LINE__,
  128609. + PageCount,
  128610. + ((gctUINT32 *) PageTable - (gctUINT32 *) Mmu->pageTableLogical),
  128611. + PageTable
  128612. + );
  128613. +
  128614. + /* Convert pointer. */
  128615. + table = (gctUINT32 *) PageTable;
  128616. +
  128617. + /* Mark the page table entries as available. */
  128618. + while (PageCount-- > 0)
  128619. + {
  128620. + *table++ = (gctUINT32)~0;
  128621. + }
  128622. +
  128623. + gcmkFOOTER_NO();
  128624. + /* Success. */
  128625. + return gcvSTATUS_OK;
  128626. +}
  128627. +
  128628. +gceSTATUS
  128629. +gckVGMMU_SetPage(
  128630. + IN gckVGMMU Mmu,
  128631. + IN gctUINT32 PageAddress,
  128632. + IN gctUINT32 *PageEntry
  128633. + )
  128634. +{
  128635. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  128636. +
  128637. + /* Verify the arguments. */
  128638. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  128639. + gcmkVERIFY_ARGUMENT(PageEntry != gcvNULL);
  128640. + gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
  128641. +
  128642. + *PageEntry = PageAddress;
  128643. +
  128644. + /* Success. */
  128645. + gcmkFOOTER_NO();
  128646. + return gcvSTATUS_OK;
  128647. +}
  128648. +
  128649. +gceSTATUS
  128650. +gckVGMMU_Flush(
  128651. + IN gckVGMMU Mmu
  128652. + )
  128653. +{
  128654. + gckVGHARDWARE hardware;
  128655. +
  128656. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  128657. +
  128658. + hardware = Mmu->hardware;
  128659. + gcmkVERIFY_OK(
  128660. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  128661. +
  128662. + /* Success. */
  128663. + gcmkFOOTER_NO();
  128664. + return gcvSTATUS_OK;
  128665. +}
  128666. +
  128667. +#endif /* gcdENABLE_VG */
  128668. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c
  128669. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c 1970-01-01 01:00:00.000000000 +0100
  128670. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c 2014-08-20 19:23:53.562845855 +0200
  128671. @@ -0,0 +1,347 @@
  128672. +/****************************************************************************
  128673. +*
  128674. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  128675. +*
  128676. +* This program is free software; you can redistribute it and/or modify
  128677. +* it under the terms of the GNU General Public License as published by
  128678. +* the Free Software Foundation; either version 2 of the license, or
  128679. +* (at your option) any later version.
  128680. +*
  128681. +* This program is distributed in the hope that it will be useful,
  128682. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  128683. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  128684. +* GNU General Public License for more details.
  128685. +*
  128686. +* You should have received a copy of the GNU General Public License
  128687. +* along with this program; if not write to the Free Software
  128688. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  128689. +*
  128690. +*****************************************************************************/
  128691. +
  128692. +
  128693. +#include "gc_hal_kernel_precomp.h"
  128694. +
  128695. +#define _GC_OBJ_ZONE gcvZONE_POWER
  128696. +
  128697. +/******************************************************************************\
  128698. +************************ Dynamic Voltage Frequency Setting *********************
  128699. +\******************************************************************************/
  128700. +#if gcdDVFS
  128701. +static gctUINT32
  128702. +_GetLoadHistory(
  128703. + IN gckDVFS Dvfs,
  128704. + IN gctUINT32 Select,
  128705. + IN gctUINT32 Index
  128706. +)
  128707. +{
  128708. + return Dvfs->loads[Index];
  128709. +}
  128710. +
  128711. +static void
  128712. +_IncreaseScale(
  128713. + IN gckDVFS Dvfs,
  128714. + IN gctUINT32 Load,
  128715. + OUT gctUINT8 *Scale
  128716. + )
  128717. +{
  128718. + if (Dvfs->currentScale < 32)
  128719. + {
  128720. + *Scale = Dvfs->currentScale + 8;
  128721. + }
  128722. + else
  128723. + {
  128724. + *Scale = Dvfs->currentScale + 8;
  128725. + *Scale = gcmMIN(64, *Scale);
  128726. + }
  128727. +}
  128728. +
  128729. +static void
  128730. +_RecordFrequencyHistory(
  128731. + gckDVFS Dvfs,
  128732. + gctUINT32 Frequency
  128733. + )
  128734. +{
  128735. + gctUINT32 i = 0;
  128736. +
  128737. + struct _FrequencyHistory *history = Dvfs->frequencyHistory;
  128738. +
  128739. + for (i = 0; i < 16; i++)
  128740. + {
  128741. + if (history->frequency == Frequency)
  128742. + {
  128743. + break;
  128744. + }
  128745. +
  128746. + if (history->frequency == 0)
  128747. + {
  128748. + history->frequency = Frequency;
  128749. + break;
  128750. + }
  128751. +
  128752. + history++;
  128753. + }
  128754. +
  128755. + if (i < 16)
  128756. + {
  128757. + history->count++;
  128758. + }
  128759. +}
  128760. +
  128761. +static gctUINT32
  128762. +_GetFrequencyHistory(
  128763. + gckDVFS Dvfs,
  128764. + gctUINT32 Frequency
  128765. + )
  128766. +{
  128767. + gctUINT32 i = 0;
  128768. +
  128769. + struct _FrequencyHistory * history = Dvfs->frequencyHistory;
  128770. +
  128771. + for (i = 0; i < 16; i++)
  128772. + {
  128773. + if (history->frequency == Frequency)
  128774. + {
  128775. + break;
  128776. + }
  128777. +
  128778. + history++;
  128779. + }
  128780. +
  128781. + if (i < 16)
  128782. + {
  128783. + return history->count;
  128784. + }
  128785. +
  128786. + return 0;
  128787. +}
  128788. +
  128789. +static void
  128790. +_Policy(
  128791. + IN gckDVFS Dvfs,
  128792. + IN gctUINT32 Load,
  128793. + OUT gctUINT8 *Scale
  128794. + )
  128795. +{
  128796. + gctUINT8 load[4], nextLoad;
  128797. + gctUINT8 scale;
  128798. +
  128799. + /* Last 4 history. */
  128800. + load[0] = (Load & 0xFF);
  128801. + load[1] = (Load & 0xFF00) >> 8;
  128802. + load[2] = (Load & 0xFF0000) >> 16;
  128803. + load[3] = (Load & 0xFF000000) >> 24;
  128804. +
  128805. + /* Determine target scale. */
  128806. + if (load[0] > 54)
  128807. + {
  128808. + _IncreaseScale(Dvfs, Load, &scale);
  128809. + }
  128810. + else
  128811. + {
  128812. + nextLoad = (load[0] + load[1] + load[2] + load[3])/4;
  128813. +
  128814. + scale = Dvfs->currentScale * (nextLoad) / 54;
  128815. +
  128816. + scale = gcmMAX(1, scale);
  128817. + scale = gcmMIN(64, scale);
  128818. + }
  128819. +
  128820. + Dvfs->totalConfig++;
  128821. +
  128822. + Dvfs->loads[(load[0]-1)/8]++;
  128823. +
  128824. + *Scale = scale;
  128825. +
  128826. +
  128827. + if (Dvfs->totalConfig % 100 == 0)
  128828. + {
  128829. + gcmkPRINT("=======================================================");
  128830. + gcmkPRINT("GPU Load: %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
  128831. + 8, 16, 24, 32, 40, 48, 56, 64);
  128832. + gcmkPRINT(" %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
  128833. + _GetLoadHistory(Dvfs,2, 0),
  128834. + _GetLoadHistory(Dvfs,2, 1),
  128835. + _GetLoadHistory(Dvfs,2, 2),
  128836. + _GetLoadHistory(Dvfs,2, 3),
  128837. + _GetLoadHistory(Dvfs,2, 4),
  128838. + _GetLoadHistory(Dvfs,2, 5),
  128839. + _GetLoadHistory(Dvfs,2, 6),
  128840. + _GetLoadHistory(Dvfs,2, 7)
  128841. + );
  128842. +
  128843. + gcmkPRINT("Frequency(MHz) %-8d %-8d %-8d %-8d %-8d",
  128844. + 58, 120, 240, 360, 480);
  128845. + gcmkPRINT(" %-8d %-8d %-8d %-8d %-8d",
  128846. + _GetFrequencyHistory(Dvfs, 58),
  128847. + _GetFrequencyHistory(Dvfs,120),
  128848. + _GetFrequencyHistory(Dvfs,240),
  128849. + _GetFrequencyHistory(Dvfs,360),
  128850. + _GetFrequencyHistory(Dvfs,480)
  128851. + );
  128852. + }
  128853. +}
  128854. +
  128855. +static void
  128856. +_TimerFunction(
  128857. + gctPOINTER Data
  128858. + )
  128859. +{
  128860. + gceSTATUS status;
  128861. + gckDVFS dvfs = (gckDVFS) Data;
  128862. + gckHARDWARE hardware = dvfs->hardware;
  128863. + gctUINT32 value;
  128864. + gctUINT32 frequency;
  128865. + gctUINT8 scale;
  128866. + gctUINT32 t1, t2, consumed;
  128867. +
  128868. + gckOS_GetTicks(&t1);
  128869. +
  128870. + gcmkONERROR(gckHARDWARE_QueryLoad(hardware, &value));
  128871. +
  128872. + /* determine target sacle. */
  128873. + _Policy(dvfs, value, &scale);
  128874. +
  128875. + /* Set frequency and voltage. */
  128876. + gcmkONERROR(gckOS_SetGPUFrequency(hardware->os, hardware->core, scale));
  128877. +
  128878. + /* Query real frequency. */
  128879. + gcmkONERROR(
  128880. + gckOS_QueryGPUFrequency(hardware->os,
  128881. + hardware->core,
  128882. + &frequency,
  128883. + &dvfs->currentScale));
  128884. +
  128885. + _RecordFrequencyHistory(dvfs, frequency);
  128886. +
  128887. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_POWER,
  128888. + "Current frequency = %d",
  128889. + frequency);
  128890. +
  128891. + /* Set period. */
  128892. + gcmkONERROR(gckHARDWARE_SetDVFSPeroid(hardware, frequency));
  128893. +
  128894. +OnError:
  128895. + /* Determine next querying time. */
  128896. + gckOS_GetTicks(&t2);
  128897. +
  128898. + consumed = gcmMIN(((long)t2 - (long)t1), 5);
  128899. +
  128900. + if (dvfs->stop == gcvFALSE)
  128901. + {
  128902. + gcmkVERIFY_OK(gckOS_StartTimer(hardware->os,
  128903. + dvfs->timer,
  128904. + dvfs->pollingTime - consumed));
  128905. + }
  128906. +
  128907. + return;
  128908. +}
  128909. +
  128910. +gceSTATUS
  128911. +gckDVFS_Construct(
  128912. + IN gckHARDWARE Hardware,
  128913. + OUT gckDVFS * Dvfs
  128914. + )
  128915. +{
  128916. + gceSTATUS status;
  128917. + gctPOINTER pointer;
  128918. + gckDVFS dvfs = gcvNULL;
  128919. + gckOS os = Hardware->os;
  128920. +
  128921. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  128922. +
  128923. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  128924. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  128925. +
  128926. + /* Allocate a gckDVFS manager. */
  128927. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckDVFS), &pointer));
  128928. +
  128929. + gckOS_ZeroMemory(pointer, gcmSIZEOF(struct _gckDVFS));
  128930. +
  128931. + dvfs = pointer;
  128932. +
  128933. + /* Initialization. */
  128934. + dvfs->hardware = Hardware;
  128935. + dvfs->pollingTime = gcdDVFS_POLLING_TIME;
  128936. + dvfs->os = Hardware->os;
  128937. + dvfs->currentScale = 64;
  128938. +
  128939. + /* Create a polling timer. */
  128940. + gcmkONERROR(gckOS_CreateTimer(os, _TimerFunction, pointer, &dvfs->timer));
  128941. +
  128942. + /* Initialize frequency and voltage adjustment helper. */
  128943. + gcmkONERROR(gckOS_PrepareGPUFrequency(os, Hardware->core));
  128944. +
  128945. + /* Return result. */
  128946. + *Dvfs = dvfs;
  128947. +
  128948. + gcmkFOOTER_NO();
  128949. + return gcvSTATUS_OK;
  128950. +
  128951. +OnError:
  128952. + /* Roll back. */
  128953. + if (dvfs)
  128954. + {
  128955. + if (dvfs->timer)
  128956. + {
  128957. + gcmkVERIFY_OK(gckOS_DestroyTimer(os, dvfs->timer));
  128958. + }
  128959. +
  128960. + gcmkOS_SAFE_FREE(os, dvfs);
  128961. + }
  128962. +
  128963. + gcmkFOOTER();
  128964. + return status;
  128965. +}
  128966. +
  128967. +gceSTATUS
  128968. +gckDVFS_Destroy(
  128969. + IN gckDVFS Dvfs
  128970. + )
  128971. +{
  128972. + gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
  128973. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  128974. +
  128975. + /* Deinitialize helper fuunction. */
  128976. + gcmkVERIFY_OK(gckOS_FinishGPUFrequency(Dvfs->os, Dvfs->hardware->core));
  128977. +
  128978. + /* DestroyTimer. */
  128979. + gcmkVERIFY_OK(gckOS_DestroyTimer(Dvfs->os, Dvfs->timer));
  128980. +
  128981. + gcmkOS_SAFE_FREE(Dvfs->os, Dvfs);
  128982. +
  128983. + gcmkFOOTER_NO();
  128984. + return gcvSTATUS_OK;
  128985. +}
  128986. +
  128987. +gceSTATUS
  128988. +gckDVFS_Start(
  128989. + IN gckDVFS Dvfs
  128990. + )
  128991. +{
  128992. + gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
  128993. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  128994. +
  128995. + gckHARDWARE_InitDVFS(Dvfs->hardware);
  128996. +
  128997. + Dvfs->stop = gcvFALSE;
  128998. +
  128999. + gckOS_StartTimer(Dvfs->os, Dvfs->timer, Dvfs->pollingTime);
  129000. +
  129001. + gcmkFOOTER_NO();
  129002. + return gcvSTATUS_OK;
  129003. +}
  129004. +
  129005. +gceSTATUS
  129006. +gckDVFS_Stop(
  129007. + IN gckDVFS Dvfs
  129008. + )
  129009. +{
  129010. + gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
  129011. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  129012. +
  129013. + Dvfs->stop = gcvTRUE;
  129014. +
  129015. + gcmkFOOTER_NO();
  129016. + return gcvSTATUS_OK;
  129017. +}
  129018. +#endif
  129019. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h
  129020. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h 1970-01-01 01:00:00.000000000 +0100
  129021. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h 2014-08-20 19:23:53.562845855 +0200
  129022. @@ -0,0 +1,29 @@
  129023. +/****************************************************************************
  129024. +*
  129025. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  129026. +*
  129027. +* This program is free software; you can redistribute it and/or modify
  129028. +* it under the terms of the GNU General Public License as published by
  129029. +* the Free Software Foundation; either version 2 of the license, or
  129030. +* (at your option) any later version.
  129031. +*
  129032. +* This program is distributed in the hope that it will be useful,
  129033. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  129034. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  129035. +* GNU General Public License for more details.
  129036. +*
  129037. +* You should have received a copy of the GNU General Public License
  129038. +* along with this program; if not write to the Free Software
  129039. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  129040. +*
  129041. +*****************************************************************************/
  129042. +
  129043. +
  129044. +#ifndef __gc_hal_kernel_precomp_h_
  129045. +#define __gc_hal_kernel_precomp_h_
  129046. +
  129047. +#include "gc_hal.h"
  129048. +#include "gc_hal_driver.h"
  129049. +#include "gc_hal_kernel.h"
  129050. +
  129051. +#endif /* __gc_hal_kernel_precomp_h_ */
  129052. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
  129053. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c 1970-01-01 01:00:00.000000000 +0100
  129054. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c 2014-08-20 19:31:46.132869024 +0200
  129055. @@ -0,0 +1,895 @@
  129056. +/****************************************************************************
  129057. +*
  129058. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  129059. +*
  129060. +* This program is free software; you can redistribute it and/or modify
  129061. +* it under the terms of the GNU General Public License as published by
  129062. +* the Free Software Foundation; either version 2 of the license, or
  129063. +* (at your option) any later version.
  129064. +*
  129065. +* This program is distributed in the hope that it will be useful,
  129066. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  129067. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  129068. +* GNU General Public License for more details.
  129069. +*
  129070. +* You should have received a copy of the GNU General Public License
  129071. +* along with this program; if not write to the Free Software
  129072. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  129073. +*
  129074. +*****************************************************************************/
  129075. +
  129076. +
  129077. +#include "gc_hal_kernel_precomp.h"
  129078. +
  129079. +#if gcdENABLE_VG
  129080. +
  129081. +#define ENABLE_VG_TRY_VIRTUAL_MEMORY 0
  129082. +
  129083. +#define _GC_OBJ_ZONE gcvZONE_VG
  129084. +
  129085. +/******************************************************************************\
  129086. +******************************* gckKERNEL API Code ******************************
  129087. +\******************************************************************************/
  129088. +
  129089. +/*******************************************************************************
  129090. +**
  129091. +** gckKERNEL_Construct
  129092. +**
  129093. +** Construct a new gckKERNEL object.
  129094. +**
  129095. +** INPUT:
  129096. +**
  129097. +** gckOS Os
  129098. +** Pointer to an gckOS object.
  129099. +**
  129100. +** IN gctPOINTER Context
  129101. +** Pointer to a driver defined context.
  129102. +**
  129103. +** OUTPUT:
  129104. +**
  129105. +** gckKERNEL * Kernel
  129106. +** Pointer to a variable that will hold the pointer to the gckKERNEL
  129107. +** object.
  129108. +*/
  129109. +gceSTATUS gckVGKERNEL_Construct(
  129110. + IN gckOS Os,
  129111. + IN gctPOINTER Context,
  129112. + IN gckKERNEL inKernel,
  129113. + OUT gckVGKERNEL * Kernel
  129114. + )
  129115. +{
  129116. + gceSTATUS status;
  129117. + gckVGKERNEL kernel = gcvNULL;
  129118. +
  129119. + gcmkHEADER_ARG("Os=0x%x Context=0x%x", Os, Context);
  129120. + /* Verify the arguments. */
  129121. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  129122. + gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
  129123. +
  129124. + do
  129125. + {
  129126. + /* Allocate the gckKERNEL object. */
  129127. + gcmkERR_BREAK(gckOS_Allocate(
  129128. + Os,
  129129. + sizeof(struct _gckVGKERNEL),
  129130. + (gctPOINTER *) &kernel
  129131. + ));
  129132. +
  129133. + /* Initialize the gckKERNEL object. */
  129134. + kernel->object.type = gcvOBJ_KERNEL;
  129135. + kernel->os = Os;
  129136. + kernel->context = Context;
  129137. + kernel->hardware = gcvNULL;
  129138. + kernel->interrupt = gcvNULL;
  129139. + kernel->command = gcvNULL;
  129140. + kernel->mmu = gcvNULL;
  129141. + kernel->kernel = inKernel;
  129142. +
  129143. + /* Construct the gckVGHARDWARE object. */
  129144. + gcmkERR_BREAK(gckVGHARDWARE_Construct(
  129145. + Os, &kernel->hardware
  129146. + ));
  129147. +
  129148. + /* Set pointer to gckKERNEL object in gckVGHARDWARE object. */
  129149. + kernel->hardware->kernel = kernel;
  129150. +
  129151. + /* Construct the gckVGINTERRUPT object. */
  129152. + gcmkERR_BREAK(gckVGINTERRUPT_Construct(
  129153. + kernel, &kernel->interrupt
  129154. + ));
  129155. +
  129156. + /* Construct the gckVGCOMMAND object. */
  129157. + gcmkERR_BREAK(gckVGCOMMAND_Construct(
  129158. + kernel, gcmKB2BYTES(8), gcmKB2BYTES(2), &kernel->command
  129159. + ));
  129160. +
  129161. + /* Construct the gckVGMMU object. */
  129162. + gcmkERR_BREAK(gckVGMMU_Construct(
  129163. + kernel, gcmKB2BYTES(32), &kernel->mmu
  129164. + ));
  129165. +
  129166. + /* Return pointer to the gckKERNEL object. */
  129167. + *Kernel = kernel;
  129168. +
  129169. + gcmkFOOTER_ARG("*Kernel=0x%x", *Kernel);
  129170. + /* Success. */
  129171. + return gcvSTATUS_OK;
  129172. + }
  129173. + while (gcvFALSE);
  129174. +
  129175. + /* Roll back. */
  129176. + if (kernel != gcvNULL)
  129177. + {
  129178. + if (kernel->mmu != gcvNULL)
  129179. + {
  129180. + gcmkVERIFY_OK(gckVGMMU_Destroy(kernel->mmu));
  129181. + }
  129182. +
  129183. + if (kernel->command != gcvNULL)
  129184. + {
  129185. + gcmkVERIFY_OK(gckVGCOMMAND_Destroy(kernel->command));
  129186. + }
  129187. +
  129188. + if (kernel->interrupt != gcvNULL)
  129189. + {
  129190. + gcmkVERIFY_OK(gckVGINTERRUPT_Destroy(kernel->interrupt));
  129191. + }
  129192. +
  129193. + if (kernel->hardware != gcvNULL)
  129194. + {
  129195. + gcmkVERIFY_OK(gckVGHARDWARE_Destroy(kernel->hardware));
  129196. + }
  129197. +
  129198. + gcmkVERIFY_OK(gckOS_Free(Os, kernel));
  129199. + }
  129200. +
  129201. + gcmkFOOTER();
  129202. + /* Return status. */
  129203. + return status;
  129204. +}
  129205. +
  129206. +/*******************************************************************************
  129207. +**
  129208. +** gckKERNEL_Destroy
  129209. +**
  129210. +** Destroy an gckKERNEL object.
  129211. +**
  129212. +** INPUT:
  129213. +**
  129214. +** gckKERNEL Kernel
  129215. +** Pointer to an gckKERNEL object to destroy.
  129216. +**
  129217. +** OUTPUT:
  129218. +**
  129219. +** Nothing.
  129220. +*/
  129221. +gceSTATUS gckVGKERNEL_Destroy(
  129222. + IN gckVGKERNEL Kernel
  129223. + )
  129224. +{
  129225. + gceSTATUS status;
  129226. +
  129227. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  129228. +
  129229. + /* Verify the arguments. */
  129230. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  129231. +
  129232. + do
  129233. + {
  129234. + /* Destroy the gckVGMMU object. */
  129235. + if (Kernel->mmu != gcvNULL)
  129236. + {
  129237. + gcmkERR_BREAK(gckVGMMU_Destroy(Kernel->mmu));
  129238. + Kernel->mmu = gcvNULL;
  129239. + }
  129240. +
  129241. + /* Destroy the gckVGCOMMAND object. */
  129242. + if (Kernel->command != gcvNULL)
  129243. + {
  129244. + gcmkERR_BREAK(gckVGCOMMAND_Destroy(Kernel->command));
  129245. + Kernel->command = gcvNULL;
  129246. + }
  129247. +
  129248. + /* Destroy the gckVGINTERRUPT object. */
  129249. + if (Kernel->interrupt != gcvNULL)
  129250. + {
  129251. + gcmkERR_BREAK(gckVGINTERRUPT_Destroy(Kernel->interrupt));
  129252. + Kernel->interrupt = gcvNULL;
  129253. + }
  129254. +
  129255. + /* Destroy the gckVGHARDWARE object. */
  129256. + if (Kernel->hardware != gcvNULL)
  129257. + {
  129258. + gcmkERR_BREAK(gckVGHARDWARE_Destroy(Kernel->hardware));
  129259. + Kernel->hardware = gcvNULL;
  129260. + }
  129261. +
  129262. + /* Mark the gckKERNEL object as unknown. */
  129263. + Kernel->object.type = gcvOBJ_UNKNOWN;
  129264. +
  129265. + /* Free the gckKERNEL object. */
  129266. + gcmkERR_BREAK(gckOS_Free(Kernel->os, Kernel));
  129267. + }
  129268. + while (gcvFALSE);
  129269. +
  129270. + gcmkFOOTER();
  129271. +
  129272. + /* Return status. */
  129273. + return status;
  129274. +}
  129275. +
  129276. +/*******************************************************************************
  129277. +**
  129278. +** gckKERNEL_AllocateLinearMemory
  129279. +**
  129280. +** Function walks all required memory pools and allocates the requested
  129281. +** amount of video memory.
  129282. +**
  129283. +** INPUT:
  129284. +**
  129285. +** gckKERNEL Kernel
  129286. +** Pointer to an gckKERNEL object.
  129287. +**
  129288. +** gcePOOL * Pool
  129289. +** Pointer the desired memory pool.
  129290. +**
  129291. +** gctSIZE_T Bytes
  129292. +** Number of bytes to allocate.
  129293. +**
  129294. +** gctSIZE_T Alignment
  129295. +** Required buffer alignment.
  129296. +**
  129297. +** gceSURF_TYPE Type
  129298. +** Surface type.
  129299. +**
  129300. +** OUTPUT:
  129301. +**
  129302. +** gcePOOL * Pool
  129303. +** Pointer to the actual pool where the memory was allocated.
  129304. +**
  129305. +** gcuVIDMEM_NODE_PTR * Node
  129306. +** Allocated node.
  129307. +*/
  129308. +gceSTATUS
  129309. +gckKERNEL_AllocateLinearMemory(
  129310. + IN gckKERNEL Kernel,
  129311. + IN OUT gcePOOL * Pool,
  129312. + IN gctSIZE_T Bytes,
  129313. + IN gctSIZE_T Alignment,
  129314. + IN gceSURF_TYPE Type,
  129315. + OUT gcuVIDMEM_NODE_PTR * Node
  129316. + )
  129317. +{
  129318. + gcePOOL pool;
  129319. + gceSTATUS status;
  129320. + gckVIDMEM videoMemory;
  129321. +
  129322. + /* Get initial pool. */
  129323. + switch (pool = *Pool)
  129324. + {
  129325. + case gcvPOOL_DEFAULT:
  129326. + case gcvPOOL_LOCAL:
  129327. + pool = gcvPOOL_LOCAL_INTERNAL;
  129328. + break;
  129329. +
  129330. + case gcvPOOL_UNIFIED:
  129331. + pool = gcvPOOL_SYSTEM;
  129332. + break;
  129333. +
  129334. + default:
  129335. + break;
  129336. + }
  129337. +
  129338. + do
  129339. + {
  129340. + /* Verify the number of bytes to allocate. */
  129341. + if (Bytes == 0)
  129342. + {
  129343. + status = gcvSTATUS_INVALID_ARGUMENT;
  129344. + break;
  129345. + }
  129346. +
  129347. + if (pool == gcvPOOL_VIRTUAL)
  129348. + {
  129349. + /* Create a gcuVIDMEM_NODE for virtual memory. */
  129350. + gcmkERR_BREAK(gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, Node));
  129351. +
  129352. + /* Success. */
  129353. + break;
  129354. + }
  129355. +
  129356. + else
  129357. + {
  129358. + /* Get pointer to gckVIDMEM object for pool. */
  129359. + status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory);
  129360. +
  129361. + if (status == gcvSTATUS_OK)
  129362. + {
  129363. + if(*Pool == gcvPOOL_SYSTEM)
  129364. + Type |= gcvSURF_VG;
  129365. + /* Allocate memory. */
  129366. + status = gckVIDMEM_AllocateLinear(videoMemory,
  129367. + Bytes,
  129368. + Alignment,
  129369. + Type,
  129370. + Node);
  129371. +
  129372. + if (status == gcvSTATUS_OK)
  129373. + {
  129374. + /* Memory allocated. */
  129375. + break;
  129376. + }
  129377. + }
  129378. + }
  129379. +
  129380. + if (pool == gcvPOOL_LOCAL_INTERNAL)
  129381. + {
  129382. + /* Advance to external memory. */
  129383. + pool = gcvPOOL_LOCAL_EXTERNAL;
  129384. + }
  129385. + else if (pool == gcvPOOL_LOCAL_EXTERNAL)
  129386. + {
  129387. + /* Advance to contiguous system memory. */
  129388. + pool = gcvPOOL_SYSTEM;
  129389. + }
  129390. + else if (pool == gcvPOOL_SYSTEM)
  129391. + {
  129392. + /* Advance to virtual memory. */
  129393. +#if ENABLE_VG_TRY_VIRTUAL_MEMORY
  129394. + pool = gcvPOOL_VIRTUAL;
  129395. +#else
  129396. + /*VG non-contiguous memory support is not ready yet, disable it temporary*/
  129397. + status = gcvSTATUS_OUT_OF_MEMORY;
  129398. + break;
  129399. +#endif
  129400. + }
  129401. + else
  129402. + {
  129403. + /* Out of pools. */
  129404. + status = gcvSTATUS_OUT_OF_MEMORY;
  129405. + break;
  129406. + }
  129407. + }
  129408. + /* Loop only for multiple selection pools. */
  129409. + while ((*Pool == gcvPOOL_DEFAULT)
  129410. + || (*Pool == gcvPOOL_LOCAL)
  129411. + || (*Pool == gcvPOOL_UNIFIED)
  129412. + );
  129413. +
  129414. + if (gcmIS_SUCCESS(status))
  129415. + {
  129416. + /* Return pool used for allocation. */
  129417. + *Pool = pool;
  129418. + }
  129419. +
  129420. + /* Return status. */
  129421. + return status;
  129422. +}
  129423. +
  129424. +/*******************************************************************************
  129425. +**
  129426. +** gckKERNEL_Dispatch
  129427. +**
  129428. +** Dispatch a command received from the user HAL layer.
  129429. +**
  129430. +** INPUT:
  129431. +**
  129432. +** gckKERNEL Kernel
  129433. +** Pointer to an gckKERNEL object.
  129434. +**
  129435. +** gcsHAL_INTERFACE * Interface
  129436. +** Pointer to a gcsHAL_INTERFACE structure that defines the command to
  129437. +** be dispatched.
  129438. +**
  129439. +** OUTPUT:
  129440. +**
  129441. +** gcsHAL_INTERFACE * Interface
  129442. +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
  129443. +** returned.
  129444. +*/
  129445. +gceSTATUS gckVGKERNEL_Dispatch(
  129446. + IN gckKERNEL Kernel,
  129447. + IN gctBOOL FromUser,
  129448. + IN OUT gcsHAL_INTERFACE * Interface
  129449. + )
  129450. +{
  129451. + gceSTATUS status;
  129452. + gcsHAL_INTERFACE * kernelInterface = Interface;
  129453. + gcuVIDMEM_NODE_PTR node;
  129454. + gctUINT32 processID;
  129455. + gckKERNEL kernel = Kernel;
  129456. + gctPOINTER info = gcvNULL;
  129457. + gctPHYS_ADDR physical = gcvNULL;
  129458. + gctPOINTER logical = gcvNULL;
  129459. + gctSIZE_T bytes = 0;
  129460. +
  129461. + gcmkHEADER_ARG("Kernel=0x%x Interface=0x%x ", Kernel, Interface);
  129462. +
  129463. + /* Verify the arguments. */
  129464. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  129465. + gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
  129466. +
  129467. + gcmkONERROR(gckOS_GetProcessID(&processID));
  129468. +
  129469. + /* Dispatch on command. */
  129470. + switch (Interface->command)
  129471. + {
  129472. + case gcvHAL_QUERY_VIDEO_MEMORY:
  129473. + /* Query video memory size. */
  129474. + gcmkERR_BREAK(gckKERNEL_QueryVideoMemory(
  129475. + Kernel, kernelInterface
  129476. + ));
  129477. + break;
  129478. +
  129479. + case gcvHAL_QUERY_CHIP_IDENTITY:
  129480. + /* Query chip identity. */
  129481. + gcmkERR_BREAK(gckVGHARDWARE_QueryChipIdentity(
  129482. + Kernel->vg->hardware,
  129483. + &kernelInterface->u.QueryChipIdentity.chipModel,
  129484. + &kernelInterface->u.QueryChipIdentity.chipRevision,
  129485. + &kernelInterface->u.QueryChipIdentity.chipFeatures,
  129486. + &kernelInterface->u.QueryChipIdentity.chipMinorFeatures,
  129487. + &kernelInterface->u.QueryChipIdentity.chipMinorFeatures2
  129488. + ));
  129489. + break;
  129490. +
  129491. + case gcvHAL_QUERY_COMMAND_BUFFER:
  129492. + /* Query command buffer information. */
  129493. + gcmkERR_BREAK(gckKERNEL_QueryCommandBuffer(
  129494. + Kernel,
  129495. + &kernelInterface->u.QueryCommandBuffer.information
  129496. + ));
  129497. + break;
  129498. + case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
  129499. + bytes = (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes;
  129500. + /* Allocate non-paged memory. */
  129501. + gcmkERR_BREAK(gckOS_AllocateContiguous(
  129502. + Kernel->os,
  129503. + gcvTRUE,
  129504. + &bytes,
  129505. + &physical,
  129506. + &logical
  129507. + ));
  129508. +
  129509. + kernelInterface->u.AllocateNonPagedMemory.bytes = bytes;
  129510. + kernelInterface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
  129511. + kernelInterface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
  129512. + break;
  129513. +
  129514. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  129515. + physical = gcmNAME_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.physical);
  129516. +
  129517. + /* Unmap user logical out of physical memory first. */
  129518. + gcmkERR_BREAK(gckOS_UnmapUserLogical(
  129519. + Kernel->os,
  129520. + physical,
  129521. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes,
  129522. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical)
  129523. + ));
  129524. +
  129525. + /* Free non-paged memory. */
  129526. + gcmkERR_BREAK(gckOS_FreeNonPagedMemory(
  129527. + Kernel->os,
  129528. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes,
  129529. + physical,
  129530. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical)
  129531. + ));
  129532. +
  129533. + gcmRELEASE_NAME(kernelInterface->u.AllocateNonPagedMemory.physical);
  129534. + break;
  129535. +
  129536. + case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
  129537. + bytes = (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes;
  129538. + /* Allocate contiguous memory. */
  129539. + gcmkERR_BREAK(gckOS_AllocateContiguous(
  129540. + Kernel->os,
  129541. + gcvTRUE,
  129542. + &bytes,
  129543. + &physical,
  129544. + &logical
  129545. + ));
  129546. +
  129547. + kernelInterface->u.AllocateNonPagedMemory.bytes = bytes;
  129548. + kernelInterface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
  129549. + kernelInterface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
  129550. + break;
  129551. +
  129552. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  129553. + physical = gcmNAME_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.physical);
  129554. + /* Unmap user logical out of physical memory first. */
  129555. + gcmkERR_BREAK(gckOS_UnmapUserLogical(
  129556. + Kernel->os,
  129557. + physical,
  129558. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes,
  129559. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical)
  129560. + ));
  129561. +
  129562. + /* Free contiguous memory. */
  129563. + gcmkERR_BREAK(gckOS_FreeContiguous(
  129564. + Kernel->os,
  129565. + physical,
  129566. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical),
  129567. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes
  129568. + ));
  129569. +
  129570. + gcmRELEASE_NAME(kernelInterface->u.AllocateNonPagedMemory.physical);
  129571. + break;
  129572. +
  129573. + case gcvHAL_ALLOCATE_VIDEO_MEMORY:
  129574. + {
  129575. + gctSIZE_T bytes;
  129576. + gctUINT32 bitsPerPixel;
  129577. + gctUINT32 bits;
  129578. +
  129579. + /* Align width and height to tiles. */
  129580. + gcmkERR_BREAK(gckVGHARDWARE_AlignToTile(
  129581. + Kernel->vg->hardware,
  129582. + kernelInterface->u.AllocateVideoMemory.type,
  129583. + &kernelInterface->u.AllocateVideoMemory.width,
  129584. + &kernelInterface->u.AllocateVideoMemory.height
  129585. + ));
  129586. +
  129587. + /* Convert format into bytes per pixel and bytes per tile. */
  129588. + gcmkERR_BREAK(gckVGHARDWARE_ConvertFormat(
  129589. + Kernel->vg->hardware,
  129590. + kernelInterface->u.AllocateVideoMemory.format,
  129591. + &bitsPerPixel,
  129592. + gcvNULL
  129593. + ));
  129594. +
  129595. + /* Compute number of bits for the allocation. */
  129596. + bits
  129597. + = kernelInterface->u.AllocateVideoMemory.width
  129598. + * kernelInterface->u.AllocateVideoMemory.height
  129599. + * kernelInterface->u.AllocateVideoMemory.depth
  129600. + * bitsPerPixel;
  129601. +
  129602. + /* Compute number of bytes for the allocation. */
  129603. + bytes = gcmALIGN(bits, 8) / 8;
  129604. +
  129605. + /* Allocate memory. */
  129606. + gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
  129607. + Kernel,
  129608. + &kernelInterface->u.AllocateVideoMemory.pool,
  129609. + bytes,
  129610. + 64,
  129611. + kernelInterface->u.AllocateVideoMemory.type,
  129612. + &node
  129613. + ));
  129614. +
  129615. + kernelInterface->u.AllocateVideoMemory.node = gcmPTR_TO_UINT64(node);
  129616. + }
  129617. + break;
  129618. +
  129619. + case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
  129620. + /* Allocate memory. */
  129621. + gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
  129622. + Kernel,
  129623. + &kernelInterface->u.AllocateLinearVideoMemory.pool,
  129624. + kernelInterface->u.AllocateLinearVideoMemory.bytes,
  129625. + kernelInterface->u.AllocateLinearVideoMemory.alignment,
  129626. + kernelInterface->u.AllocateLinearVideoMemory.type,
  129627. + &node
  129628. + ));
  129629. +
  129630. + gcmkERR_BREAK(gckKERNEL_AddProcessDB(Kernel,
  129631. + processID, gcvDB_VIDEO_MEMORY,
  129632. + node,
  129633. + gcvNULL,
  129634. + kernelInterface->u.AllocateLinearVideoMemory.bytes
  129635. + ));
  129636. +
  129637. + kernelInterface->u.AllocateLinearVideoMemory.node = gcmPTR_TO_UINT64(node);
  129638. + break;
  129639. +
  129640. + case gcvHAL_FREE_VIDEO_MEMORY:
  129641. + node = gcmUINT64_TO_PTR(Interface->u.FreeVideoMemory.node);
  129642. +#ifdef __QNXNTO__
  129643. + /* Unmap the video memory */
  129644. +
  129645. + if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM) &&
  129646. + (node->VidMem.logical != gcvNULL))
  129647. + {
  129648. + gckKERNEL_UnmapVideoMemory(Kernel,
  129649. + node->VidMem.logical,
  129650. + processID,
  129651. + node->VidMem.bytes);
  129652. + node->VidMem.logical = gcvNULL;
  129653. + }
  129654. +#endif /* __QNXNTO__ */
  129655. +
  129656. + /* Free video memory. */
  129657. + gcmkERR_BREAK(gckVIDMEM_Free(
  129658. + node
  129659. + ));
  129660. +
  129661. + gcmkERR_BREAK(gckKERNEL_RemoveProcessDB(
  129662. + Kernel,
  129663. + processID, gcvDB_VIDEO_MEMORY,
  129664. + node
  129665. + ));
  129666. +
  129667. + break;
  129668. +
  129669. + case gcvHAL_MAP_MEMORY:
  129670. + /* Map memory. */
  129671. + gcmkERR_BREAK(gckKERNEL_MapMemory(
  129672. + Kernel,
  129673. + gcmINT2PTR(kernelInterface->u.MapMemory.physical),
  129674. + (gctSIZE_T) kernelInterface->u.MapMemory.bytes,
  129675. + &logical
  129676. + ));
  129677. + kernelInterface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
  129678. + break;
  129679. +
  129680. + case gcvHAL_UNMAP_MEMORY:
  129681. + /* Unmap memory. */
  129682. + gcmkERR_BREAK(gckKERNEL_UnmapMemory(
  129683. + Kernel,
  129684. + gcmINT2PTR(kernelInterface->u.MapMemory.physical),
  129685. + (gctSIZE_T) kernelInterface->u.MapMemory.bytes,
  129686. + gcmUINT64_TO_PTR(kernelInterface->u.MapMemory.logical)
  129687. + ));
  129688. + break;
  129689. +
  129690. + case gcvHAL_MAP_USER_MEMORY:
  129691. + /* Map user memory to DMA. */
  129692. + gcmkERR_BREAK(gckOS_MapUserMemory(
  129693. + Kernel->os,
  129694. + gcvCORE_VG,
  129695. + gcmUINT64_TO_PTR(kernelInterface->u.MapUserMemory.memory),
  129696. + kernelInterface->u.MapUserMemory.physical,
  129697. + (gctSIZE_T) kernelInterface->u.MapUserMemory.size,
  129698. + &info,
  129699. + &kernelInterface->u.MapUserMemory.address
  129700. + ));
  129701. +
  129702. + kernelInterface->u.MapUserMemory.info = gcmPTR_TO_NAME(info);
  129703. + break;
  129704. +
  129705. + case gcvHAL_UNMAP_USER_MEMORY:
  129706. + /* Unmap user memory. */
  129707. + gcmkERR_BREAK(gckOS_UnmapUserMemory(
  129708. + Kernel->os,
  129709. + gcvCORE_VG,
  129710. + gcmUINT64_TO_PTR(kernelInterface->u.UnmapUserMemory.memory),
  129711. + (gctSIZE_T) kernelInterface->u.UnmapUserMemory.size,
  129712. + gcmNAME_TO_PTR(kernelInterface->u.UnmapUserMemory.info),
  129713. + kernelInterface->u.UnmapUserMemory.address
  129714. + ));
  129715. + gcmRELEASE_NAME(kernelInterface->u.UnmapUserMemory.info);
  129716. + break;
  129717. + case gcvHAL_LOCK_VIDEO_MEMORY:
  129718. + node = gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node);
  129719. +
  129720. + /* Lock video memory. */
  129721. + gcmkERR_BREAK(
  129722. + gckVIDMEM_Lock(Kernel,
  129723. + node,
  129724. + gcvFALSE,
  129725. + &Interface->u.LockVideoMemory.address));
  129726. +
  129727. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  129728. + {
  129729. + /* Map video memory address into user space. */
  129730. +#ifdef __QNXNTO__
  129731. + if (node->VidMem.logical == gcvNULL)
  129732. + {
  129733. + gcmkONERROR(
  129734. + gckKERNEL_MapVideoMemory(Kernel,
  129735. + FromUser,
  129736. + Interface->u.LockVideoMemory.address,
  129737. + processID,
  129738. + node->VidMem.bytes,
  129739. + &node->VidMem.logical));
  129740. + }
  129741. +
  129742. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical);
  129743. +#else
  129744. + gcmkERR_BREAK(
  129745. + gckKERNEL_MapVideoMemoryEx(Kernel,
  129746. + gcvCORE_VG,
  129747. + FromUser,
  129748. + Interface->u.LockVideoMemory.address,
  129749. + &logical));
  129750. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical);
  129751. +#endif
  129752. + }
  129753. + else
  129754. + {
  129755. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical);
  129756. +
  129757. + /* Success. */
  129758. + status = gcvSTATUS_OK;
  129759. + }
  129760. +
  129761. +#if gcdSECURE_USER
  129762. + /* Return logical address as physical address. */
  129763. + Interface->u.LockVideoMemory.address =
  129764. + (gctUINT32)(Interface->u.LockVideoMemory.memory);
  129765. +#endif
  129766. + gcmkERR_BREAK(
  129767. + gckKERNEL_AddProcessDB(Kernel,
  129768. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  129769. + node,
  129770. + gcvNULL,
  129771. + 0));
  129772. + break;
  129773. +
  129774. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  129775. + /* Unlock video memory. */
  129776. + node = gcmUINT64_TO_PTR(Interface->u.UnlockVideoMemory.node);
  129777. +
  129778. +#if gcdSECURE_USER
  129779. + /* Save node information before it disappears. */
  129780. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  129781. + {
  129782. + logical = gcvNULL;
  129783. + bytes = 0;
  129784. + }
  129785. + else
  129786. + {
  129787. + logical = node->Virtual.logical;
  129788. + bytes = node->Virtual.bytes;
  129789. + }
  129790. +#endif
  129791. +
  129792. + /* Unlock video memory. */
  129793. + gcmkERR_BREAK(
  129794. + gckVIDMEM_Unlock(Kernel,
  129795. + node,
  129796. + Interface->u.UnlockVideoMemory.type,
  129797. + &Interface->u.UnlockVideoMemory.asynchroneous));
  129798. +
  129799. +#if gcdSECURE_USER
  129800. + /* Flush the translation cache for virtual surfaces. */
  129801. + if (logical != gcvNULL)
  129802. + {
  129803. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel,
  129804. + cache,
  129805. + logical,
  129806. + bytes));
  129807. + }
  129808. +#endif
  129809. +
  129810. + if (Interface->u.UnlockVideoMemory.asynchroneous == gcvFALSE)
  129811. + {
  129812. + /* There isn't a event to unlock this node, remove record now */
  129813. + gcmkERR_BREAK(
  129814. + gckKERNEL_RemoveProcessDB(Kernel,
  129815. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  129816. + node));
  129817. + }
  129818. +
  129819. + break;
  129820. + case gcvHAL_USER_SIGNAL:
  129821. +#if !USE_NEW_LINUX_SIGNAL
  129822. + /* Dispatch depends on the user signal subcommands. */
  129823. + switch(Interface->u.UserSignal.command)
  129824. + {
  129825. + case gcvUSER_SIGNAL_CREATE:
  129826. + /* Create a signal used in the user space. */
  129827. + gcmkERR_BREAK(
  129828. + gckOS_CreateUserSignal(Kernel->os,
  129829. + Interface->u.UserSignal.manualReset,
  129830. + &Interface->u.UserSignal.id));
  129831. +
  129832. + gcmkVERIFY_OK(
  129833. + gckKERNEL_AddProcessDB(Kernel,
  129834. + processID, gcvDB_SIGNAL,
  129835. + gcmINT2PTR(Interface->u.UserSignal.id),
  129836. + gcvNULL,
  129837. + 0));
  129838. + break;
  129839. +
  129840. + case gcvUSER_SIGNAL_DESTROY:
  129841. + /* Destroy the signal. */
  129842. + gcmkERR_BREAK(
  129843. + gckOS_DestroyUserSignal(Kernel->os,
  129844. + Interface->u.UserSignal.id));
  129845. +
  129846. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  129847. + Kernel,
  129848. + processID, gcvDB_SIGNAL,
  129849. + gcmINT2PTR(Interface->u.UserSignal.id)));
  129850. + break;
  129851. +
  129852. + case gcvUSER_SIGNAL_SIGNAL:
  129853. + /* Signal the signal. */
  129854. + gcmkERR_BREAK(
  129855. + gckOS_SignalUserSignal(Kernel->os,
  129856. + Interface->u.UserSignal.id,
  129857. + Interface->u.UserSignal.state));
  129858. + break;
  129859. +
  129860. + case gcvUSER_SIGNAL_WAIT:
  129861. + /* Wait on the signal. */
  129862. + status = gckOS_WaitUserSignal(Kernel->os,
  129863. + Interface->u.UserSignal.id,
  129864. + Interface->u.UserSignal.wait);
  129865. + break;
  129866. +
  129867. + default:
  129868. + /* Invalid user signal command. */
  129869. + gcmkERR_BREAK(gcvSTATUS_INVALID_ARGUMENT);
  129870. + }
  129871. +#endif
  129872. + break;
  129873. +
  129874. + case gcvHAL_COMMIT:
  129875. + /* Commit a command and context buffer. */
  129876. + gcmkERR_BREAK(gckVGCOMMAND_Commit(
  129877. + Kernel->vg->command,
  129878. + gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.context),
  129879. + gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.queue),
  129880. + kernelInterface->u.VGCommit.entryCount,
  129881. + gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.taskTable)
  129882. + ));
  129883. + break;
  129884. + case gcvHAL_VERSION:
  129885. + kernelInterface->u.Version.major = gcvVERSION_MAJOR;
  129886. + kernelInterface->u.Version.minor = gcvVERSION_MINOR;
  129887. + kernelInterface->u.Version.patch = gcvVERSION_PATCH;
  129888. + kernelInterface->u.Version.build = gcvVERSION_BUILD;
  129889. + status = gcvSTATUS_OK;
  129890. + break;
  129891. +
  129892. + case gcvHAL_GET_BASE_ADDRESS:
  129893. + /* Get base address. */
  129894. + gcmkERR_BREAK(
  129895. + gckOS_GetBaseAddress(Kernel->os,
  129896. + &kernelInterface->u.GetBaseAddress.baseAddress));
  129897. + break;
  129898. + default:
  129899. + /* Invalid command. */
  129900. + status = gcvSTATUS_INVALID_ARGUMENT;
  129901. + }
  129902. +
  129903. +OnError:
  129904. + /* Save status. */
  129905. + kernelInterface->status = status;
  129906. +
  129907. + gcmkFOOTER();
  129908. +
  129909. + /* Return the status. */
  129910. + return status;
  129911. +}
  129912. +
  129913. +/*******************************************************************************
  129914. +**
  129915. +** gckKERNEL_QueryCommandBuffer
  129916. +**
  129917. +** Query command buffer attributes.
  129918. +**
  129919. +** INPUT:
  129920. +**
  129921. +** gckKERNEL Kernel
  129922. +** Pointer to an gckVGHARDWARE object.
  129923. +**
  129924. +** OUTPUT:
  129925. +**
  129926. +** gcsCOMMAND_BUFFER_INFO_PTR Information
  129927. +** Pointer to the information structure to receive buffer attributes.
  129928. +*/
  129929. +gceSTATUS
  129930. +gckKERNEL_QueryCommandBuffer(
  129931. + IN gckKERNEL Kernel,
  129932. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  129933. + )
  129934. +{
  129935. + gceSTATUS status;
  129936. +
  129937. + gcmkHEADER_ARG("Kernel=0x%x *Pool=0x%x",
  129938. + Kernel, Information);
  129939. + /* Verify the arguments. */
  129940. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  129941. +
  129942. + /* Get the information. */
  129943. + status = gckVGCOMMAND_QueryCommandBuffer(Kernel->vg->command, Information);
  129944. +
  129945. + gcmkFOOTER();
  129946. + /* Return status. */
  129947. + return status;
  129948. +}
  129949. +
  129950. +#endif /* gcdENABLE_VG */
  129951. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h
  129952. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h 1970-01-01 01:00:00.000000000 +0100
  129953. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h 2014-08-20 19:23:53.566845873 +0200
  129954. @@ -0,0 +1,85 @@
  129955. +/****************************************************************************
  129956. +*
  129957. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  129958. +*
  129959. +* This program is free software; you can redistribute it and/or modify
  129960. +* it under the terms of the GNU General Public License as published by
  129961. +* the Free Software Foundation; either version 2 of the license, or
  129962. +* (at your option) any later version.
  129963. +*
  129964. +* This program is distributed in the hope that it will be useful,
  129965. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  129966. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  129967. +* GNU General Public License for more details.
  129968. +*
  129969. +* You should have received a copy of the GNU General Public License
  129970. +* along with this program; if not write to the Free Software
  129971. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  129972. +*
  129973. +*****************************************************************************/
  129974. +
  129975. +
  129976. +#ifndef __gc_hal_kernel_vg_h_
  129977. +#define __gc_hal_kernel_vg_h_
  129978. +
  129979. +#include "gc_hal.h"
  129980. +#include "gc_hal_driver.h"
  129981. +#include "gc_hal_kernel_hardware.h"
  129982. +
  129983. +/******************************************************************************\
  129984. +********************************** Structures **********************************
  129985. +\******************************************************************************/
  129986. +
  129987. +/* gckKERNEL object. */
  129988. +struct _gckVGKERNEL
  129989. +{
  129990. + /* Object. */
  129991. + gcsOBJECT object;
  129992. +
  129993. + /* Pointer to gckOS object. */
  129994. + gckOS os;
  129995. +
  129996. + /* Pointer to gckHARDWARE object. */
  129997. + gckVGHARDWARE hardware;
  129998. +
  129999. + /* Pointer to gckINTERRUPT object. */
  130000. + gckVGINTERRUPT interrupt;
  130001. +
  130002. + /* Pointer to gckCOMMAND object. */
  130003. + gckVGCOMMAND command;
  130004. +
  130005. + /* Pointer to context. */
  130006. + gctPOINTER context;
  130007. +
  130008. + /* Pointer to gckMMU object. */
  130009. + gckVGMMU mmu;
  130010. +
  130011. + gckKERNEL kernel;
  130012. +};
  130013. +
  130014. +/* gckMMU object. */
  130015. +struct _gckVGMMU
  130016. +{
  130017. + /* The object. */
  130018. + gcsOBJECT object;
  130019. +
  130020. + /* Pointer to gckOS object. */
  130021. + gckOS os;
  130022. +
  130023. + /* Pointer to gckHARDWARE object. */
  130024. + gckVGHARDWARE hardware;
  130025. +
  130026. + /* The page table mutex. */
  130027. + gctPOINTER mutex;
  130028. +
  130029. + /* Page table information. */
  130030. + gctSIZE_T pageTableSize;
  130031. + gctPHYS_ADDR pageTablePhysical;
  130032. + gctPOINTER pageTableLogical;
  130033. +
  130034. + /* Allocation index. */
  130035. + gctUINT32 entryCount;
  130036. + gctUINT32 entry;
  130037. +};
  130038. +
  130039. +#endif /* __gc_hal_kernel_h_ */
  130040. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
  130041. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c 1970-01-01 01:00:00.000000000 +0100
  130042. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c 2014-08-20 19:31:46.132869024 +0200
  130043. @@ -0,0 +1,2264 @@
  130044. +/****************************************************************************
  130045. +*
  130046. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  130047. +*
  130048. +* This program is free software; you can redistribute it and/or modify
  130049. +* it under the terms of the GNU General Public License as published by
  130050. +* the Free Software Foundation; either version 2 of the license, or
  130051. +* (at your option) any later version.
  130052. +*
  130053. +* This program is distributed in the hope that it will be useful,
  130054. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  130055. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  130056. +* GNU General Public License for more details.
  130057. +*
  130058. +* You should have received a copy of the GNU General Public License
  130059. +* along with this program; if not write to the Free Software
  130060. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  130061. +*
  130062. +*****************************************************************************/
  130063. +
  130064. +
  130065. +#include "gc_hal_kernel_precomp.h"
  130066. +
  130067. +#define _GC_OBJ_ZONE gcvZONE_VIDMEM
  130068. +
  130069. +/******************************************************************************\
  130070. +******************************* Private Functions ******************************
  130071. +\******************************************************************************/
  130072. +
  130073. +/*******************************************************************************
  130074. +**
  130075. +** _Split
  130076. +**
  130077. +** Split a node on the required byte boundary.
  130078. +**
  130079. +** INPUT:
  130080. +**
  130081. +** gckOS Os
  130082. +** Pointer to an gckOS object.
  130083. +**
  130084. +** gcuVIDMEM_NODE_PTR Node
  130085. +** Pointer to the node to split.
  130086. +**
  130087. +** gctSIZE_T Bytes
  130088. +** Number of bytes to keep in the node.
  130089. +**
  130090. +** OUTPUT:
  130091. +**
  130092. +** Nothing.
  130093. +**
  130094. +** RETURNS:
  130095. +**
  130096. +** gctBOOL
  130097. +** gcvTRUE if the node was split successfully, or gcvFALSE if there is an
  130098. +** error.
  130099. +**
  130100. +*/
  130101. +static gctBOOL
  130102. +_Split(
  130103. + IN gckOS Os,
  130104. + IN gcuVIDMEM_NODE_PTR Node,
  130105. + IN gctSIZE_T Bytes
  130106. + )
  130107. +{
  130108. + gcuVIDMEM_NODE_PTR node;
  130109. + gctPOINTER pointer = gcvNULL;
  130110. +
  130111. + /* Make sure the byte boundary makes sense. */
  130112. + if ((Bytes <= 0) || (Bytes > Node->VidMem.bytes))
  130113. + {
  130114. + return gcvFALSE;
  130115. + }
  130116. +
  130117. + /* Allocate a new gcuVIDMEM_NODE object. */
  130118. + if (gcmIS_ERROR(gckOS_Allocate(Os,
  130119. + gcmSIZEOF(gcuVIDMEM_NODE),
  130120. + &pointer)))
  130121. + {
  130122. + /* Error. */
  130123. + return gcvFALSE;
  130124. + }
  130125. +
  130126. + node = pointer;
  130127. +
  130128. + /* Initialize gcuVIDMEM_NODE structure. */
  130129. + node->VidMem.offset = Node->VidMem.offset + Bytes;
  130130. + node->VidMem.bytes = Node->VidMem.bytes - Bytes;
  130131. + node->VidMem.alignment = 0;
  130132. + node->VidMem.locked = 0;
  130133. + node->VidMem.memory = Node->VidMem.memory;
  130134. + node->VidMem.pool = Node->VidMem.pool;
  130135. + node->VidMem.physical = Node->VidMem.physical;
  130136. +#ifdef __QNXNTO__
  130137. +#if gcdUSE_VIDMEM_PER_PID
  130138. + gcmkASSERT(Node->VidMem.physical != 0);
  130139. + gcmkASSERT(Node->VidMem.logical != gcvNULL);
  130140. + node->VidMem.processID = Node->VidMem.processID;
  130141. + node->VidMem.physical = Node->VidMem.physical + Bytes;
  130142. + node->VidMem.logical = Node->VidMem.logical + Bytes;
  130143. +#else
  130144. + node->VidMem.processID = 0;
  130145. + node->VidMem.logical = gcvNULL;
  130146. +#endif
  130147. +#endif
  130148. +
  130149. + /* Insert node behind specified node. */
  130150. + node->VidMem.next = Node->VidMem.next;
  130151. + node->VidMem.prev = Node;
  130152. + Node->VidMem.next = node->VidMem.next->VidMem.prev = node;
  130153. +
  130154. + /* Insert free node behind specified node. */
  130155. + node->VidMem.nextFree = Node->VidMem.nextFree;
  130156. + node->VidMem.prevFree = Node;
  130157. + Node->VidMem.nextFree = node->VidMem.nextFree->VidMem.prevFree = node;
  130158. +
  130159. + /* Adjust size of specified node. */
  130160. + Node->VidMem.bytes = Bytes;
  130161. +
  130162. + /* Success. */
  130163. + return gcvTRUE;
  130164. +}
  130165. +
  130166. +/*******************************************************************************
  130167. +**
  130168. +** _Merge
  130169. +**
  130170. +** Merge two adjacent nodes together.
  130171. +**
  130172. +** INPUT:
  130173. +**
  130174. +** gckOS Os
  130175. +** Pointer to an gckOS object.
  130176. +**
  130177. +** gcuVIDMEM_NODE_PTR Node
  130178. +** Pointer to the first of the two nodes to merge.
  130179. +**
  130180. +** OUTPUT:
  130181. +**
  130182. +** Nothing.
  130183. +**
  130184. +*/
  130185. +static gceSTATUS
  130186. +_Merge(
  130187. + IN gckOS Os,
  130188. + IN gcuVIDMEM_NODE_PTR Node
  130189. + )
  130190. +{
  130191. + gcuVIDMEM_NODE_PTR node;
  130192. + gceSTATUS status;
  130193. +
  130194. + /* Save pointer to next node. */
  130195. + node = Node->VidMem.next;
  130196. +#if gcdUSE_VIDMEM_PER_PID
  130197. + /* Check if the nodes are adjacent physically. */
  130198. + if ( ((Node->VidMem.physical + Node->VidMem.bytes) != node->VidMem.physical) ||
  130199. + ((Node->VidMem.logical + Node->VidMem.bytes) != node->VidMem.logical) )
  130200. + {
  130201. + /* Can't merge. */
  130202. + return gcvSTATUS_OK;
  130203. + }
  130204. +#else
  130205. +
  130206. + /* This is a good time to make sure the heap is not corrupted. */
  130207. + if (Node->VidMem.offset + Node->VidMem.bytes != node->VidMem.offset)
  130208. + {
  130209. + /* Corrupted heap. */
  130210. + gcmkASSERT(
  130211. + Node->VidMem.offset + Node->VidMem.bytes == node->VidMem.offset);
  130212. + return gcvSTATUS_HEAP_CORRUPTED;
  130213. + }
  130214. +#endif
  130215. +
  130216. + /* Adjust byte count. */
  130217. + Node->VidMem.bytes += node->VidMem.bytes;
  130218. +
  130219. + /* Unlink next node from linked list. */
  130220. + Node->VidMem.next = node->VidMem.next;
  130221. + Node->VidMem.nextFree = node->VidMem.nextFree;
  130222. +
  130223. + Node->VidMem.next->VidMem.prev =
  130224. + Node->VidMem.nextFree->VidMem.prevFree = Node;
  130225. +
  130226. + /* Free next node. */
  130227. + status = gcmkOS_SAFE_FREE(Os, node);
  130228. + return status;
  130229. +}
  130230. +
  130231. +/******************************************************************************\
  130232. +******************************* gckVIDMEM API Code ******************************
  130233. +\******************************************************************************/
  130234. +
  130235. +/*******************************************************************************
  130236. +**
  130237. +** gckVIDMEM_ConstructVirtual
  130238. +**
  130239. +** Construct a new gcuVIDMEM_NODE union for virtual memory.
  130240. +**
  130241. +** INPUT:
  130242. +**
  130243. +** gckKERNEL Kernel
  130244. +** Pointer to an gckKERNEL object.
  130245. +**
  130246. +** gctSIZE_T Bytes
  130247. +** Number of byte to allocate.
  130248. +**
  130249. +** OUTPUT:
  130250. +**
  130251. +** gcuVIDMEM_NODE_PTR * Node
  130252. +** Pointer to a variable that receives the gcuVIDMEM_NODE union pointer.
  130253. +*/
  130254. +gceSTATUS
  130255. +gckVIDMEM_ConstructVirtual(
  130256. + IN gckKERNEL Kernel,
  130257. + IN gctBOOL Contiguous,
  130258. + IN gctSIZE_T Bytes,
  130259. + OUT gcuVIDMEM_NODE_PTR * Node
  130260. + )
  130261. +{
  130262. + gckOS os;
  130263. + gceSTATUS status;
  130264. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  130265. + gctPOINTER pointer = gcvNULL;
  130266. + gctINT i;
  130267. +
  130268. + gcmkHEADER_ARG("Kernel=0x%x Contiguous=%d Bytes=%lu", Kernel, Contiguous, Bytes);
  130269. +
  130270. + /* Verify the arguments. */
  130271. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  130272. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  130273. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  130274. +
  130275. + /* Extract the gckOS object pointer. */
  130276. + os = Kernel->os;
  130277. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  130278. +
  130279. + /* Allocate an gcuVIDMEM_NODE union. */
  130280. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
  130281. +
  130282. + node = pointer;
  130283. +
  130284. + /* Initialize gcuVIDMEM_NODE union for virtual memory. */
  130285. + node->Virtual.kernel = Kernel;
  130286. + node->Virtual.contiguous = Contiguous;
  130287. + node->Virtual.logical = gcvNULL;
  130288. +
  130289. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  130290. + {
  130291. + node->Virtual.lockeds[i] = 0;
  130292. + node->Virtual.pageTables[i] = gcvNULL;
  130293. + node->Virtual.lockKernels[i] = gcvNULL;
  130294. + }
  130295. +
  130296. + node->Virtual.mutex = gcvNULL;
  130297. +
  130298. + gcmkONERROR(gckOS_GetProcessID(&node->Virtual.processID));
  130299. +
  130300. +#ifdef __QNXNTO__
  130301. + node->Virtual.next = gcvNULL;
  130302. + node->Virtual.freePending = gcvFALSE;
  130303. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  130304. + {
  130305. + node->Virtual.unlockPendings[i] = gcvFALSE;
  130306. + }
  130307. +#endif
  130308. +
  130309. + node->Virtual.freed = gcvFALSE;
  130310. +
  130311. + gcmkONERROR(gckOS_ZeroMemory(&node->Virtual.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)));
  130312. +
  130313. + /* Create the mutex. */
  130314. + gcmkONERROR(
  130315. + gckOS_CreateMutex(os, &node->Virtual.mutex));
  130316. +
  130317. + /* Allocate the virtual memory. */
  130318. + gcmkONERROR(
  130319. + gckOS_AllocatePagedMemoryEx(os,
  130320. + node->Virtual.contiguous,
  130321. + node->Virtual.bytes = Bytes,
  130322. + &node->Virtual.physical));
  130323. +
  130324. +#ifdef __QNXNTO__
  130325. + /* Register. */
  130326. +#if gcdENABLE_VG
  130327. + if (Kernel->core != gcvCORE_VG)
  130328. +#endif
  130329. + {
  130330. + gckMMU_InsertNode(Kernel->mmu, node);
  130331. + }
  130332. +#endif
  130333. +
  130334. + /* Return pointer to the gcuVIDMEM_NODE union. */
  130335. + *Node = node;
  130336. +
  130337. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130338. + "Created virtual node 0x%x for %u bytes @ 0x%x",
  130339. + node, Bytes, node->Virtual.physical);
  130340. +
  130341. + /* Success. */
  130342. + gcmkFOOTER_ARG("*Node=0x%x", *Node);
  130343. + return gcvSTATUS_OK;
  130344. +
  130345. +OnError:
  130346. + /* Roll back. */
  130347. + if (node != gcvNULL)
  130348. + {
  130349. + if (node->Virtual.mutex != gcvNULL)
  130350. + {
  130351. + /* Destroy the mutex. */
  130352. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->Virtual.mutex));
  130353. + }
  130354. +
  130355. + /* Free the structure. */
  130356. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
  130357. + }
  130358. +
  130359. + /* Return the status. */
  130360. + gcmkFOOTER();
  130361. + return status;
  130362. +}
  130363. +
  130364. +/*******************************************************************************
  130365. +**
  130366. +** gckVIDMEM_DestroyVirtual
  130367. +**
  130368. +** Destroy an gcuVIDMEM_NODE union for virtual memory.
  130369. +**
  130370. +** INPUT:
  130371. +**
  130372. +** gcuVIDMEM_NODE_PTR Node
  130373. +** Pointer to a gcuVIDMEM_NODE union.
  130374. +**
  130375. +** OUTPUT:
  130376. +**
  130377. +** Nothing.
  130378. +*/
  130379. +gceSTATUS
  130380. +gckVIDMEM_DestroyVirtual(
  130381. + IN gcuVIDMEM_NODE_PTR Node
  130382. + )
  130383. +{
  130384. + gckOS os;
  130385. + gctINT i;
  130386. +
  130387. + gcmkHEADER_ARG("Node=0x%x", Node);
  130388. +
  130389. + /* Verify the arguments. */
  130390. + gcmkVERIFY_OBJECT(Node->Virtual.kernel, gcvOBJ_KERNEL);
  130391. +
  130392. + /* Extact the gckOS object pointer. */
  130393. + os = Node->Virtual.kernel->os;
  130394. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  130395. +
  130396. +#ifdef __QNXNTO__
  130397. + /* Unregister. */
  130398. +#if gcdENABLE_VG
  130399. + if (Node->Virtual.kernel->core != gcvCORE_VG)
  130400. +#endif
  130401. + {
  130402. + gcmkVERIFY_OK(
  130403. + gckMMU_RemoveNode(Node->Virtual.kernel->mmu, Node));
  130404. + }
  130405. +#endif
  130406. +
  130407. + /* Delete the mutex. */
  130408. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, Node->Virtual.mutex));
  130409. +
  130410. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  130411. + {
  130412. + if (Node->Virtual.pageTables[i] != gcvNULL)
  130413. + {
  130414. +#if gcdENABLE_VG
  130415. + if (i == gcvCORE_VG)
  130416. + {
  130417. + /* Free the pages. */
  130418. + gcmkVERIFY_OK(gckVGMMU_FreePages(Node->Virtual.lockKernels[i]->vg->mmu,
  130419. + Node->Virtual.pageTables[i],
  130420. + Node->Virtual.pageCount));
  130421. + }
  130422. + else
  130423. +#endif
  130424. + {
  130425. + /* Free the pages. */
  130426. + gcmkVERIFY_OK(gckMMU_FreePages(Node->Virtual.lockKernels[i]->mmu,
  130427. + Node->Virtual.pageTables[i],
  130428. + Node->Virtual.pageCount));
  130429. + }
  130430. + }
  130431. + }
  130432. +
  130433. + /* Delete the gcuVIDMEM_NODE union. */
  130434. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, Node));
  130435. +
  130436. + /* Success. */
  130437. + gcmkFOOTER_NO();
  130438. + return gcvSTATUS_OK;
  130439. +}
  130440. +
  130441. +/*******************************************************************************
  130442. +**
  130443. +** gckVIDMEM_Construct
  130444. +**
  130445. +** Construct a new gckVIDMEM object.
  130446. +**
  130447. +** INPUT:
  130448. +**
  130449. +** gckOS Os
  130450. +** Pointer to an gckOS object.
  130451. +**
  130452. +** gctUINT32 BaseAddress
  130453. +** Base address for the video memory heap.
  130454. +**
  130455. +** gctSIZE_T Bytes
  130456. +** Number of bytes in the video memory heap.
  130457. +**
  130458. +** gctSIZE_T Threshold
  130459. +** Minimum number of bytes beyond am allocation before the node is
  130460. +** split. Can be used as a minimum alignment requirement.
  130461. +**
  130462. +** gctSIZE_T BankSize
  130463. +** Number of bytes per physical memory bank. Used by bank
  130464. +** optimization.
  130465. +**
  130466. +** OUTPUT:
  130467. +**
  130468. +** gckVIDMEM * Memory
  130469. +** Pointer to a variable that will hold the pointer to the gckVIDMEM
  130470. +** object.
  130471. +*/
  130472. +gceSTATUS
  130473. +gckVIDMEM_Construct(
  130474. + IN gckOS Os,
  130475. + IN gctUINT32 BaseAddress,
  130476. + IN gctSIZE_T Bytes,
  130477. + IN gctSIZE_T Threshold,
  130478. + IN gctSIZE_T BankSize,
  130479. + OUT gckVIDMEM * Memory
  130480. + )
  130481. +{
  130482. + gckVIDMEM memory = gcvNULL;
  130483. + gceSTATUS status;
  130484. + gcuVIDMEM_NODE_PTR node;
  130485. + gctINT i, banks = 0;
  130486. + gctPOINTER pointer = gcvNULL;
  130487. +
  130488. + gcmkHEADER_ARG("Os=0x%x BaseAddress=%08x Bytes=%lu Threshold=%lu "
  130489. + "BankSize=%lu",
  130490. + Os, BaseAddress, Bytes, Threshold, BankSize);
  130491. +
  130492. + /* Verify the arguments. */
  130493. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  130494. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  130495. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  130496. +
  130497. + /* Allocate the gckVIDMEM object. */
  130498. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(struct _gckVIDMEM), &pointer));
  130499. +
  130500. + memory = pointer;
  130501. +
  130502. + /* Initialize the gckVIDMEM object. */
  130503. + memory->object.type = gcvOBJ_VIDMEM;
  130504. + memory->os = Os;
  130505. +
  130506. + /* Set video memory heap information. */
  130507. + memory->baseAddress = BaseAddress;
  130508. + memory->bytes = Bytes;
  130509. + memory->freeBytes = Bytes;
  130510. + memory->threshold = Threshold;
  130511. + memory->mutex = gcvNULL;
  130512. +#if gcdUSE_VIDMEM_PER_PID
  130513. + gcmkONERROR(gckOS_GetProcessID(&memory->pid));
  130514. +#endif
  130515. +
  130516. + BaseAddress = 0;
  130517. +
  130518. + /* Walk all possible banks. */
  130519. + for (i = 0; i < gcmCOUNTOF(memory->sentinel); ++i)
  130520. + {
  130521. + gctSIZE_T bytes;
  130522. +
  130523. + if (BankSize == 0)
  130524. + {
  130525. + /* Use all bytes for the first bank. */
  130526. + bytes = Bytes;
  130527. + }
  130528. + else
  130529. + {
  130530. + /* Compute number of bytes for this bank. */
  130531. + bytes = gcmALIGN(BaseAddress + 1, BankSize) - BaseAddress;
  130532. +
  130533. + if (bytes > Bytes)
  130534. + {
  130535. + /* Make sure we don't exceed the total number of bytes. */
  130536. + bytes = Bytes;
  130537. + }
  130538. + }
  130539. +
  130540. + if (bytes == 0)
  130541. + {
  130542. + /* Mark heap is not used. */
  130543. + memory->sentinel[i].VidMem.next =
  130544. + memory->sentinel[i].VidMem.prev =
  130545. + memory->sentinel[i].VidMem.nextFree =
  130546. + memory->sentinel[i].VidMem.prevFree = gcvNULL;
  130547. + continue;
  130548. + }
  130549. +
  130550. + /* Allocate one gcuVIDMEM_NODE union. */
  130551. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
  130552. +
  130553. + node = pointer;
  130554. +
  130555. + /* Initialize gcuVIDMEM_NODE union. */
  130556. + node->VidMem.memory = memory;
  130557. +
  130558. + node->VidMem.next =
  130559. + node->VidMem.prev =
  130560. + node->VidMem.nextFree =
  130561. + node->VidMem.prevFree = &memory->sentinel[i];
  130562. +
  130563. + node->VidMem.offset = BaseAddress;
  130564. + node->VidMem.bytes = bytes;
  130565. + node->VidMem.alignment = 0;
  130566. + node->VidMem.physical = 0;
  130567. + node->VidMem.pool = gcvPOOL_UNKNOWN;
  130568. +
  130569. + node->VidMem.locked = 0;
  130570. +
  130571. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  130572. + node->VidMem.kernelVirtual = gcvNULL;
  130573. +#endif
  130574. +
  130575. + gcmkONERROR(gckOS_ZeroMemory(&node->VidMem.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)));
  130576. +
  130577. +#ifdef __QNXNTO__
  130578. +#if gcdUSE_VIDMEM_PER_PID
  130579. + node->VidMem.processID = memory->pid;
  130580. + node->VidMem.physical = memory->baseAddress + BaseAddress;
  130581. + gcmkONERROR(gckOS_GetLogicalAddressProcess(Os,
  130582. + node->VidMem.processID,
  130583. + node->VidMem.physical,
  130584. + &node->VidMem.logical));
  130585. +#else
  130586. + node->VidMem.processID = 0;
  130587. + node->VidMem.logical = gcvNULL;
  130588. +#endif
  130589. +#endif
  130590. +
  130591. + /* Initialize the linked list of nodes. */
  130592. + memory->sentinel[i].VidMem.next =
  130593. + memory->sentinel[i].VidMem.prev =
  130594. + memory->sentinel[i].VidMem.nextFree =
  130595. + memory->sentinel[i].VidMem.prevFree = node;
  130596. +
  130597. + /* Mark sentinel. */
  130598. + memory->sentinel[i].VidMem.bytes = 0;
  130599. +
  130600. + /* Adjust address for next bank. */
  130601. + BaseAddress += bytes;
  130602. + Bytes -= bytes;
  130603. + banks ++;
  130604. + }
  130605. +
  130606. + /* Assign all the bank mappings. */
  130607. + memory->mapping[gcvSURF_RENDER_TARGET] = banks - 1;
  130608. + memory->mapping[gcvSURF_BITMAP] = banks - 1;
  130609. + if (banks > 1) --banks;
  130610. + memory->mapping[gcvSURF_DEPTH] = banks - 1;
  130611. + memory->mapping[gcvSURF_HIERARCHICAL_DEPTH] = banks - 1;
  130612. + if (banks > 1) --banks;
  130613. + memory->mapping[gcvSURF_TEXTURE] = banks - 1;
  130614. + if (banks > 1) --banks;
  130615. + memory->mapping[gcvSURF_VERTEX] = banks - 1;
  130616. + if (banks > 1) --banks;
  130617. + memory->mapping[gcvSURF_INDEX] = banks - 1;
  130618. + if (banks > 1) --banks;
  130619. + memory->mapping[gcvSURF_TILE_STATUS] = banks - 1;
  130620. + if (banks > 1) --banks;
  130621. + memory->mapping[gcvSURF_TYPE_UNKNOWN] = 0;
  130622. +
  130623. +#if gcdENABLE_VG
  130624. + memory->mapping[gcvSURF_IMAGE] = 0;
  130625. + memory->mapping[gcvSURF_MASK] = 0;
  130626. + memory->mapping[gcvSURF_SCISSOR] = 0;
  130627. +#endif
  130628. +
  130629. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130630. + "[GALCORE] INDEX: bank %d",
  130631. + memory->mapping[gcvSURF_INDEX]);
  130632. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130633. + "[GALCORE] VERTEX: bank %d",
  130634. + memory->mapping[gcvSURF_VERTEX]);
  130635. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130636. + "[GALCORE] TEXTURE: bank %d",
  130637. + memory->mapping[gcvSURF_TEXTURE]);
  130638. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130639. + "[GALCORE] RENDER_TARGET: bank %d",
  130640. + memory->mapping[gcvSURF_RENDER_TARGET]);
  130641. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130642. + "[GALCORE] DEPTH: bank %d",
  130643. + memory->mapping[gcvSURF_DEPTH]);
  130644. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130645. + "[GALCORE] TILE_STATUS: bank %d",
  130646. + memory->mapping[gcvSURF_TILE_STATUS]);
  130647. +
  130648. + /* Allocate the mutex. */
  130649. + gcmkONERROR(gckOS_CreateMutex(Os, &memory->mutex));
  130650. +
  130651. + /* Return pointer to the gckVIDMEM object. */
  130652. + *Memory = memory;
  130653. +
  130654. + /* Success. */
  130655. + gcmkFOOTER_ARG("*Memory=0x%x", *Memory);
  130656. + return gcvSTATUS_OK;
  130657. +
  130658. +OnError:
  130659. + /* Roll back. */
  130660. + if (memory != gcvNULL)
  130661. + {
  130662. + if (memory->mutex != gcvNULL)
  130663. + {
  130664. + /* Delete the mutex. */
  130665. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, memory->mutex));
  130666. + }
  130667. +
  130668. + for (i = 0; i < banks; ++i)
  130669. + {
  130670. + /* Free the heap. */
  130671. + gcmkASSERT(memory->sentinel[i].VidMem.next != gcvNULL);
  130672. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, memory->sentinel[i].VidMem.next));
  130673. + }
  130674. +
  130675. + /* Free the object. */
  130676. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, memory));
  130677. + }
  130678. +
  130679. + /* Return the status. */
  130680. + gcmkFOOTER();
  130681. + return status;
  130682. +}
  130683. +
  130684. +/*******************************************************************************
  130685. +**
  130686. +** gckVIDMEM_Destroy
  130687. +**
  130688. +** Destroy an gckVIDMEM object.
  130689. +**
  130690. +** INPUT:
  130691. +**
  130692. +** gckVIDMEM Memory
  130693. +** Pointer to an gckVIDMEM object to destroy.
  130694. +**
  130695. +** OUTPUT:
  130696. +**
  130697. +** Nothing.
  130698. +*/
  130699. +gceSTATUS
  130700. +gckVIDMEM_Destroy(
  130701. + IN gckVIDMEM Memory
  130702. + )
  130703. +{
  130704. + gcuVIDMEM_NODE_PTR node, next;
  130705. + gctINT i;
  130706. +
  130707. + gcmkHEADER_ARG("Memory=0x%x", Memory);
  130708. +
  130709. + /* Verify the arguments. */
  130710. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  130711. +
  130712. + /* Walk all sentinels. */
  130713. + for (i = 0; i < gcmCOUNTOF(Memory->sentinel); ++i)
  130714. + {
  130715. + /* Bail out of the heap is not used. */
  130716. + if (Memory->sentinel[i].VidMem.next == gcvNULL)
  130717. + {
  130718. + break;
  130719. + }
  130720. +
  130721. + /* Walk all the nodes until we reach the sentinel. */
  130722. + for (node = Memory->sentinel[i].VidMem.next;
  130723. + node->VidMem.bytes != 0;
  130724. + node = next)
  130725. + {
  130726. + /* Save pointer to the next node. */
  130727. + next = node->VidMem.next;
  130728. +
  130729. + /* Free the node. */
  130730. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Memory->os, node));
  130731. + }
  130732. + }
  130733. +
  130734. + /* Free the mutex. */
  130735. + gcmkVERIFY_OK(gckOS_DeleteMutex(Memory->os, Memory->mutex));
  130736. +
  130737. + /* Mark the object as unknown. */
  130738. + Memory->object.type = gcvOBJ_UNKNOWN;
  130739. +
  130740. + /* Free the gckVIDMEM object. */
  130741. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Memory->os, Memory));
  130742. +
  130743. + /* Success. */
  130744. + gcmkFOOTER_NO();
  130745. + return gcvSTATUS_OK;
  130746. +}
  130747. +
  130748. +/*******************************************************************************
  130749. +**
  130750. +** gckVIDMEM_Allocate
  130751. +**
  130752. +** Allocate rectangular memory from the gckVIDMEM object.
  130753. +**
  130754. +** INPUT:
  130755. +**
  130756. +** gckVIDMEM Memory
  130757. +** Pointer to an gckVIDMEM object.
  130758. +**
  130759. +** gctUINT Width
  130760. +** Width of rectangle to allocate. Make sure the width is properly
  130761. +** aligned.
  130762. +**
  130763. +** gctUINT Height
  130764. +** Height of rectangle to allocate. Make sure the height is properly
  130765. +** aligned.
  130766. +**
  130767. +** gctUINT Depth
  130768. +** Depth of rectangle to allocate. This equals to the number of
  130769. +** rectangles to allocate contiguously (i.e., for cubic maps and volume
  130770. +** textures).
  130771. +**
  130772. +** gctUINT BytesPerPixel
  130773. +** Number of bytes per pixel.
  130774. +**
  130775. +** gctUINT32 Alignment
  130776. +** Byte alignment for allocation.
  130777. +**
  130778. +** gceSURF_TYPE Type
  130779. +** Type of surface to allocate (use by bank optimization).
  130780. +**
  130781. +** OUTPUT:
  130782. +**
  130783. +** gcuVIDMEM_NODE_PTR * Node
  130784. +** Pointer to a variable that will hold the allocated memory node.
  130785. +*/
  130786. +gceSTATUS
  130787. +gckVIDMEM_Allocate(
  130788. + IN gckVIDMEM Memory,
  130789. + IN gctUINT Width,
  130790. + IN gctUINT Height,
  130791. + IN gctUINT Depth,
  130792. + IN gctUINT BytesPerPixel,
  130793. + IN gctUINT32 Alignment,
  130794. + IN gceSURF_TYPE Type,
  130795. + OUT gcuVIDMEM_NODE_PTR * Node
  130796. + )
  130797. +{
  130798. + gctSIZE_T bytes;
  130799. + gceSTATUS status;
  130800. +
  130801. + gcmkHEADER_ARG("Memory=0x%x Width=%u Height=%u Depth=%u BytesPerPixel=%u "
  130802. + "Alignment=%u Type=%d",
  130803. + Memory, Width, Height, Depth, BytesPerPixel, Alignment,
  130804. + Type);
  130805. +
  130806. + /* Verify the arguments. */
  130807. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  130808. + gcmkVERIFY_ARGUMENT(Width > 0);
  130809. + gcmkVERIFY_ARGUMENT(Height > 0);
  130810. + gcmkVERIFY_ARGUMENT(Depth > 0);
  130811. + gcmkVERIFY_ARGUMENT(BytesPerPixel > 0);
  130812. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  130813. +
  130814. + /* Compute linear size. */
  130815. + bytes = Width * Height * Depth * BytesPerPixel;
  130816. +
  130817. + /* Allocate through linear function. */
  130818. + gcmkONERROR(
  130819. + gckVIDMEM_AllocateLinear(Memory, bytes, Alignment, Type, Node));
  130820. +
  130821. + /* Success. */
  130822. + gcmkFOOTER_ARG("*Node=0x%x", *Node);
  130823. + return gcvSTATUS_OK;
  130824. +
  130825. +OnError:
  130826. + /* Return the status. */
  130827. + gcmkFOOTER();
  130828. + return status;
  130829. +}
  130830. +
  130831. +#if gcdENABLE_BANK_ALIGNMENT
  130832. +
  130833. +#if !gcdBANK_BIT_START
  130834. +#error gcdBANK_BIT_START not defined.
  130835. +#endif
  130836. +
  130837. +#if !gcdBANK_BIT_END
  130838. +#error gcdBANK_BIT_END not defined.
  130839. +#endif
  130840. +/*******************************************************************************
  130841. +** _GetSurfaceBankAlignment
  130842. +**
  130843. +** Return the required offset alignment required to the make BaseAddress
  130844. +** aligned properly.
  130845. +**
  130846. +** INPUT:
  130847. +**
  130848. +** gckOS Os
  130849. +** Pointer to gcoOS object.
  130850. +**
  130851. +** gceSURF_TYPE Type
  130852. +** Type of allocation.
  130853. +**
  130854. +** gctUINT32 BaseAddress
  130855. +** Base address of current video memory node.
  130856. +**
  130857. +** OUTPUT:
  130858. +**
  130859. +** gctUINT32_PTR AlignmentOffset
  130860. +** Pointer to a variable that will hold the number of bytes to skip in
  130861. +** the current video memory node in order to make the alignment bank
  130862. +** aligned.
  130863. +*/
  130864. +static gceSTATUS
  130865. +_GetSurfaceBankAlignment(
  130866. + IN gceSURF_TYPE Type,
  130867. + IN gctUINT32 BaseAddress,
  130868. + OUT gctUINT32_PTR AlignmentOffset
  130869. + )
  130870. +{
  130871. + gctUINT32 bank;
  130872. + /* To retrieve the bank. */
  130873. + static const gctUINT32 bankMask = (0xFFFFFFFF << gcdBANK_BIT_START)
  130874. + ^ (0xFFFFFFFF << (gcdBANK_BIT_END + 1));
  130875. +
  130876. + /* To retrieve the bank and all the lower bytes. */
  130877. + static const gctUINT32 byteMask = ~(0xFFFFFFFF << (gcdBANK_BIT_END + 1));
  130878. +
  130879. + gcmkHEADER_ARG("Type=%d BaseAddress=0x%x ", Type, BaseAddress);
  130880. +
  130881. + /* Verify the arguments. */
  130882. + gcmkVERIFY_ARGUMENT(AlignmentOffset != gcvNULL);
  130883. +
  130884. + switch (Type)
  130885. + {
  130886. + case gcvSURF_RENDER_TARGET:
  130887. + bank = (BaseAddress & bankMask) >> (gcdBANK_BIT_START);
  130888. +
  130889. + /* Align to the first bank. */
  130890. + *AlignmentOffset = (bank == 0) ?
  130891. + 0 :
  130892. + ((1 << (gcdBANK_BIT_END + 1)) + 0) - (BaseAddress & byteMask);
  130893. + break;
  130894. +
  130895. + case gcvSURF_DEPTH:
  130896. + bank = (BaseAddress & bankMask) >> (gcdBANK_BIT_START);
  130897. +
  130898. + /* Align to the third bank. */
  130899. + *AlignmentOffset = (bank == 2) ?
  130900. + 0 :
  130901. + ((1 << (gcdBANK_BIT_END + 1)) + (2 << gcdBANK_BIT_START)) - (BaseAddress & byteMask);
  130902. +
  130903. + /* Add a channel offset at the channel bit. */
  130904. + *AlignmentOffset += (1 << gcdBANK_CHANNEL_BIT);
  130905. + break;
  130906. +
  130907. + default:
  130908. + /* no alignment needed. */
  130909. + *AlignmentOffset = 0;
  130910. + }
  130911. +
  130912. + /* Return the status. */
  130913. + gcmkFOOTER_ARG("*AlignmentOffset=%u", *AlignmentOffset);
  130914. + return gcvSTATUS_OK;
  130915. +}
  130916. +#endif
  130917. +
  130918. +static gcuVIDMEM_NODE_PTR
  130919. +_FindNode(
  130920. + IN gckVIDMEM Memory,
  130921. + IN gctINT Bank,
  130922. + IN gctSIZE_T Bytes,
  130923. + IN gceSURF_TYPE Type,
  130924. + IN OUT gctUINT32_PTR Alignment
  130925. + )
  130926. +{
  130927. + gcuVIDMEM_NODE_PTR node;
  130928. + gctUINT32 alignment;
  130929. +
  130930. +#if gcdENABLE_BANK_ALIGNMENT
  130931. + gctUINT32 bankAlignment;
  130932. + gceSTATUS status;
  130933. +#endif
  130934. +
  130935. + if (Memory->sentinel[Bank].VidMem.nextFree == gcvNULL)
  130936. + {
  130937. + /* No free nodes left. */
  130938. + return gcvNULL;
  130939. + }
  130940. +
  130941. +#if gcdENABLE_BANK_ALIGNMENT
  130942. + /* Walk all free nodes until we have one that is big enough or we have
  130943. + ** reached the sentinel. */
  130944. + for (node = Memory->sentinel[Bank].VidMem.nextFree;
  130945. + node->VidMem.bytes != 0;
  130946. + node = node->VidMem.nextFree)
  130947. + {
  130948. + gcmkONERROR(_GetSurfaceBankAlignment(
  130949. + Type,
  130950. + node->VidMem.memory->baseAddress + node->VidMem.offset,
  130951. + &bankAlignment));
  130952. +
  130953. + bankAlignment = gcmALIGN(bankAlignment, *Alignment);
  130954. +
  130955. + /* Compute number of bytes to skip for alignment. */
  130956. + alignment = (*Alignment == 0)
  130957. + ? 0
  130958. + : (*Alignment - (node->VidMem.offset % *Alignment));
  130959. +
  130960. + if (alignment == *Alignment)
  130961. + {
  130962. + /* Node is already aligned. */
  130963. + alignment = 0;
  130964. + }
  130965. +
  130966. + if (node->VidMem.bytes >= Bytes + alignment + bankAlignment)
  130967. + {
  130968. + /* This node is big enough. */
  130969. + *Alignment = alignment + bankAlignment;
  130970. + return node;
  130971. + }
  130972. + }
  130973. +#endif
  130974. +
  130975. + /* Walk all free nodes until we have one that is big enough or we have
  130976. + reached the sentinel. */
  130977. + for (node = Memory->sentinel[Bank].VidMem.nextFree;
  130978. + node->VidMem.bytes != 0;
  130979. + node = node->VidMem.nextFree)
  130980. + {
  130981. +
  130982. + gctINT modulo = gckMATH_ModuloInt(node->VidMem.offset, *Alignment);
  130983. +
  130984. + /* Compute number of bytes to skip for alignment. */
  130985. + alignment = (*Alignment == 0) ? 0 : (*Alignment - modulo);
  130986. +
  130987. + if (alignment == *Alignment)
  130988. + {
  130989. + /* Node is already aligned. */
  130990. + alignment = 0;
  130991. + }
  130992. +
  130993. + if (node->VidMem.bytes >= Bytes + alignment)
  130994. + {
  130995. + /* This node is big enough. */
  130996. + *Alignment = alignment;
  130997. + return node;
  130998. + }
  130999. + }
  131000. +
  131001. +#if gcdENABLE_BANK_ALIGNMENT
  131002. +OnError:
  131003. +#endif
  131004. + /* Not enough memory. */
  131005. + return gcvNULL;
  131006. +}
  131007. +
  131008. +/*******************************************************************************
  131009. +**
  131010. +** gckVIDMEM_AllocateLinear
  131011. +**
  131012. +** Allocate linear memory from the gckVIDMEM object.
  131013. +**
  131014. +** INPUT:
  131015. +**
  131016. +** gckVIDMEM Memory
  131017. +** Pointer to an gckVIDMEM object.
  131018. +**
  131019. +** gctSIZE_T Bytes
  131020. +** Number of bytes to allocate.
  131021. +**
  131022. +** gctUINT32 Alignment
  131023. +** Byte alignment for allocation.
  131024. +**
  131025. +** gceSURF_TYPE Type
  131026. +** Type of surface to allocate (use by bank optimization).
  131027. +**
  131028. +** OUTPUT:
  131029. +**
  131030. +** gcuVIDMEM_NODE_PTR * Node
  131031. +** Pointer to a variable that will hold the allocated memory node.
  131032. +*/
  131033. +gceSTATUS
  131034. +gckVIDMEM_AllocateLinear(
  131035. + IN gckVIDMEM Memory,
  131036. + IN gctSIZE_T Bytes,
  131037. + IN gctUINT32 Alignment,
  131038. + IN gceSURF_TYPE Type,
  131039. + OUT gcuVIDMEM_NODE_PTR * Node
  131040. + )
  131041. +{
  131042. + gceSTATUS status;
  131043. + gcuVIDMEM_NODE_PTR node;
  131044. + gctUINT32 alignment;
  131045. + gctINT bank, i;
  131046. + gctBOOL acquired = gcvFALSE;
  131047. +#if gcdSMALL_BLOCK_SIZE
  131048. + gctBOOL force_allocate = (Type == gcvSURF_TILE_STATUS) || (Type & gcvSURF_VG);
  131049. +#endif
  131050. +
  131051. + gcmkHEADER_ARG("Memory=0x%x Bytes=%lu Alignment=%u Type=%d",
  131052. + Memory, Bytes, Alignment, Type);
  131053. +
  131054. + Type &= ~gcvSURF_VG;
  131055. + /* Verify the arguments. */
  131056. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  131057. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  131058. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  131059. + gcmkVERIFY_ARGUMENT(Type < gcvSURF_NUM_TYPES);
  131060. +
  131061. + /* Acquire the mutex. */
  131062. + gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
  131063. +
  131064. + acquired = gcvTRUE;
  131065. +#if !gcdUSE_VIDMEM_PER_PID
  131066. +
  131067. + if (Bytes > Memory->freeBytes)
  131068. + {
  131069. + /* Not enough memory. */
  131070. + status = gcvSTATUS_OUT_OF_MEMORY;
  131071. + goto OnError;
  131072. + }
  131073. +#endif
  131074. +
  131075. +#if gcdSMALL_BLOCK_SIZE
  131076. + if ((!force_allocate) && (Memory->freeBytes < (Memory->bytes/gcdRATIO_FOR_SMALL_MEMORY))
  131077. + && (Bytes >= gcdSMALL_BLOCK_SIZE)
  131078. + )
  131079. + {
  131080. + /* The left memory is for small memory.*/
  131081. + status = gcvSTATUS_OUT_OF_MEMORY;
  131082. + goto OnError;
  131083. + }
  131084. +#endif
  131085. +
  131086. + /* Find the default bank for this surface type. */
  131087. + gcmkASSERT((gctINT) Type < gcmCOUNTOF(Memory->mapping));
  131088. + bank = Memory->mapping[Type];
  131089. + alignment = Alignment;
  131090. +
  131091. +#if gcdUSE_VIDMEM_PER_PID
  131092. + if (Bytes <= Memory->freeBytes)
  131093. + {
  131094. +#endif
  131095. + /* Find a free node in the default bank. */
  131096. + node = _FindNode(Memory, bank, Bytes, Type, &alignment);
  131097. +
  131098. + /* Out of memory? */
  131099. + if (node == gcvNULL)
  131100. + {
  131101. + /* Walk all lower banks. */
  131102. + for (i = bank - 1; i >= 0; --i)
  131103. + {
  131104. + /* Find a free node inside the current bank. */
  131105. + node = _FindNode(Memory, i, Bytes, Type, &alignment);
  131106. + if (node != gcvNULL)
  131107. + {
  131108. + break;
  131109. + }
  131110. + }
  131111. + }
  131112. +
  131113. + if (node == gcvNULL)
  131114. + {
  131115. + /* Walk all upper banks. */
  131116. + for (i = bank + 1; i < gcmCOUNTOF(Memory->sentinel); ++i)
  131117. + {
  131118. + if (Memory->sentinel[i].VidMem.nextFree == gcvNULL)
  131119. + {
  131120. + /* Abort when we reach unused banks. */
  131121. + break;
  131122. + }
  131123. +
  131124. + /* Find a free node inside the current bank. */
  131125. + node = _FindNode(Memory, i, Bytes, Type, &alignment);
  131126. + if (node != gcvNULL)
  131127. + {
  131128. + break;
  131129. + }
  131130. + }
  131131. + }
  131132. +#if gcdUSE_VIDMEM_PER_PID
  131133. + }
  131134. +#endif
  131135. +
  131136. + if (node == gcvNULL)
  131137. + {
  131138. + /* Out of memory. */
  131139. +#if gcdUSE_VIDMEM_PER_PID
  131140. + /* Allocate more memory from shared pool. */
  131141. + gctSIZE_T bytes;
  131142. + gctPHYS_ADDR physical_temp;
  131143. + gctUINT32 physical;
  131144. + gctPOINTER logical;
  131145. +
  131146. + bytes = gcmALIGN(Bytes, gcdUSE_VIDMEM_PER_PID_SIZE);
  131147. +
  131148. + gcmkONERROR(gckOS_AllocateContiguous(Memory->os,
  131149. + gcvTRUE,
  131150. + &bytes,
  131151. + &physical_temp,
  131152. + &logical));
  131153. +
  131154. + /* physical address is returned as 0 for user space. workaround. */
  131155. + if (physical_temp == gcvNULL)
  131156. + {
  131157. + gcmkONERROR(gckOS_GetPhysicalAddress(Memory->os, logical, &physical));
  131158. + }
  131159. +
  131160. + /* Allocate one gcuVIDMEM_NODE union. */
  131161. + gcmkONERROR(
  131162. + gckOS_Allocate(Memory->os,
  131163. + gcmSIZEOF(gcuVIDMEM_NODE),
  131164. + (gctPOINTER *) &node));
  131165. +
  131166. + /* Initialize gcuVIDMEM_NODE union. */
  131167. + node->VidMem.memory = Memory;
  131168. +
  131169. + node->VidMem.offset = 0;
  131170. + node->VidMem.bytes = bytes;
  131171. + node->VidMem.alignment = 0;
  131172. + node->VidMem.physical = physical;
  131173. + node->VidMem.pool = gcvPOOL_UNKNOWN;
  131174. +
  131175. + node->VidMem.locked = 0;
  131176. +
  131177. +#ifdef __QNXNTO__
  131178. + gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID));
  131179. + node->VidMem.logical = logical;
  131180. + gcmkASSERT(logical != gcvNULL);
  131181. +#endif
  131182. +
  131183. + /* Insert node behind sentinel node. */
  131184. + node->VidMem.next = Memory->sentinel[bank].VidMem.next;
  131185. + node->VidMem.prev = &Memory->sentinel[bank];
  131186. + Memory->sentinel[bank].VidMem.next = node->VidMem.next->VidMem.prev = node;
  131187. +
  131188. + /* Insert free node behind sentinel node. */
  131189. + node->VidMem.nextFree = Memory->sentinel[bank].VidMem.nextFree;
  131190. + node->VidMem.prevFree = &Memory->sentinel[bank];
  131191. + Memory->sentinel[bank].VidMem.nextFree = node->VidMem.nextFree->VidMem.prevFree = node;
  131192. +
  131193. + Memory->freeBytes += bytes;
  131194. +#else
  131195. + status = gcvSTATUS_OUT_OF_MEMORY;
  131196. + goto OnError;
  131197. +#endif
  131198. + }
  131199. +
  131200. + /* Do we have an alignment? */
  131201. + if (alignment > 0)
  131202. + {
  131203. + /* Split the node so it is aligned. */
  131204. + if (_Split(Memory->os, node, alignment))
  131205. + {
  131206. + /* Successful split, move to aligned node. */
  131207. + node = node->VidMem.next;
  131208. +
  131209. + /* Remove alignment. */
  131210. + alignment = 0;
  131211. + }
  131212. + }
  131213. +
  131214. + /* Do we have enough memory after the allocation to split it? */
  131215. + if (node->VidMem.bytes - Bytes > Memory->threshold)
  131216. + {
  131217. + /* Adjust the node size. */
  131218. + _Split(Memory->os, node, Bytes);
  131219. + }
  131220. +
  131221. + /* Remove the node from the free list. */
  131222. + node->VidMem.prevFree->VidMem.nextFree = node->VidMem.nextFree;
  131223. + node->VidMem.nextFree->VidMem.prevFree = node->VidMem.prevFree;
  131224. + node->VidMem.nextFree =
  131225. + node->VidMem.prevFree = gcvNULL;
  131226. +
  131227. + /* Fill in the information. */
  131228. + node->VidMem.alignment = alignment;
  131229. + node->VidMem.memory = Memory;
  131230. +#ifdef __QNXNTO__
  131231. +#if !gcdUSE_VIDMEM_PER_PID
  131232. + node->VidMem.logical = gcvNULL;
  131233. + gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID));
  131234. +#else
  131235. + gcmkASSERT(node->VidMem.logical != gcvNULL);
  131236. +#endif
  131237. +#endif
  131238. +
  131239. + /* Adjust the number of free bytes. */
  131240. + Memory->freeBytes -= node->VidMem.bytes;
  131241. +
  131242. + node->VidMem.freePending = gcvFALSE;
  131243. +
  131244. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  131245. + node->VidMem.kernelVirtual = gcvNULL;
  131246. +#endif
  131247. +
  131248. + /* Release the mutex. */
  131249. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  131250. +
  131251. + /* Return the pointer to the node. */
  131252. + *Node = node;
  131253. +
  131254. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131255. + "Allocated %u bytes @ 0x%x [0x%08X]",
  131256. + node->VidMem.bytes, node, node->VidMem.offset);
  131257. +
  131258. + /* Success. */
  131259. + gcmkFOOTER_ARG("*Node=0x%x", *Node);
  131260. + return gcvSTATUS_OK;
  131261. +
  131262. +OnError:
  131263. + if (acquired)
  131264. + {
  131265. + /* Release the mutex. */
  131266. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  131267. + }
  131268. +
  131269. + /* Return the status. */
  131270. + gcmkFOOTER();
  131271. + return status;
  131272. +}
  131273. +
  131274. +/*******************************************************************************
  131275. +**
  131276. +** gckVIDMEM_Free
  131277. +**
  131278. +** Free an allocated video memory node.
  131279. +**
  131280. +** INPUT:
  131281. +**
  131282. +** gcuVIDMEM_NODE_PTR Node
  131283. +** Pointer to a gcuVIDMEM_NODE object.
  131284. +**
  131285. +** OUTPUT:
  131286. +**
  131287. +** Nothing.
  131288. +*/
  131289. +gceSTATUS
  131290. +gckVIDMEM_Free(
  131291. + IN gcuVIDMEM_NODE_PTR Node
  131292. + )
  131293. +{
  131294. + gceSTATUS status;
  131295. + gckKERNEL kernel = gcvNULL;
  131296. + gckVIDMEM memory = gcvNULL;
  131297. + gcuVIDMEM_NODE_PTR node;
  131298. + gctBOOL mutexAcquired = gcvFALSE;
  131299. + gckOS os = gcvNULL;
  131300. + gctBOOL acquired = gcvFALSE;
  131301. + gctINT32 i, totalLocked;
  131302. +
  131303. + gcmkHEADER_ARG("Node=0x%x", Node);
  131304. +
  131305. + /* Verify the arguments. */
  131306. + if ((Node == gcvNULL)
  131307. + || (Node->VidMem.memory == gcvNULL)
  131308. + )
  131309. + {
  131310. + /* Invalid object. */
  131311. + gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
  131312. + }
  131313. +
  131314. + /**************************** Video Memory ********************************/
  131315. +
  131316. + if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  131317. + {
  131318. + if (Node->VidMem.locked > 0)
  131319. + {
  131320. + /* Client still has a lock, defer free op 'till when lock reaches 0. */
  131321. + Node->VidMem.freePending = gcvTRUE;
  131322. +
  131323. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131324. + "Node 0x%x is locked (%d)... deferring free.",
  131325. + Node, Node->VidMem.locked);
  131326. +
  131327. + gcmkFOOTER_NO();
  131328. + return gcvSTATUS_OK;
  131329. + }
  131330. +
  131331. + /* Extract pointer to gckVIDMEM object owning the node. */
  131332. + memory = Node->VidMem.memory;
  131333. +
  131334. + /* Acquire the mutex. */
  131335. + gcmkONERROR(
  131336. + gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
  131337. +
  131338. + mutexAcquired = gcvTRUE;
  131339. +
  131340. +#ifdef __QNXNTO__
  131341. +#if !gcdUSE_VIDMEM_PER_PID
  131342. + /* Reset. */
  131343. + Node->VidMem.processID = 0;
  131344. + Node->VidMem.logical = gcvNULL;
  131345. +#endif
  131346. +
  131347. + /* Don't try to re-free an already freed node. */
  131348. + if ((Node->VidMem.nextFree == gcvNULL)
  131349. + && (Node->VidMem.prevFree == gcvNULL)
  131350. + )
  131351. +#endif
  131352. + {
  131353. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  131354. + if (Node->VidMem.kernelVirtual)
  131355. + {
  131356. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131357. + "%s(%d) Unmap %x from kernel space.",
  131358. + __FUNCTION__, __LINE__,
  131359. + Node->VidMem.kernelVirtual);
  131360. +
  131361. + gcmkVERIFY_OK(
  131362. + gckOS_UnmapPhysical(memory->os,
  131363. + Node->VidMem.kernelVirtual,
  131364. + Node->VidMem.bytes));
  131365. +
  131366. + Node->VidMem.kernelVirtual = gcvNULL;
  131367. + }
  131368. +#endif
  131369. +
  131370. + /* Check if Node is already freed. */
  131371. + if (Node->VidMem.nextFree)
  131372. + {
  131373. + /* Node is alread freed. */
  131374. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  131375. + }
  131376. +
  131377. + /* Update the number of free bytes. */
  131378. + memory->freeBytes += Node->VidMem.bytes;
  131379. +
  131380. + /* Find the next free node. */
  131381. + for (node = Node->VidMem.next;
  131382. + node != gcvNULL && node->VidMem.nextFree == gcvNULL;
  131383. + node = node->VidMem.next) ;
  131384. +
  131385. + /* Insert this node in the free list. */
  131386. + Node->VidMem.nextFree = node;
  131387. + Node->VidMem.prevFree = node->VidMem.prevFree;
  131388. +
  131389. + Node->VidMem.prevFree->VidMem.nextFree =
  131390. + node->VidMem.prevFree = Node;
  131391. +
  131392. + /* Is the next node a free node and not the sentinel? */
  131393. + if ((Node->VidMem.next == Node->VidMem.nextFree)
  131394. + && (Node->VidMem.next->VidMem.bytes != 0)
  131395. + )
  131396. + {
  131397. + /* Merge this node with the next node. */
  131398. + gcmkONERROR(_Merge(memory->os, node = Node));
  131399. + gcmkASSERT(node->VidMem.nextFree != node);
  131400. + gcmkASSERT(node->VidMem.prevFree != node);
  131401. + }
  131402. +
  131403. + /* Is the previous node a free node and not the sentinel? */
  131404. + if ((Node->VidMem.prev == Node->VidMem.prevFree)
  131405. + && (Node->VidMem.prev->VidMem.bytes != 0)
  131406. + )
  131407. + {
  131408. + /* Merge this node with the previous node. */
  131409. + gcmkONERROR(_Merge(memory->os, node = Node->VidMem.prev));
  131410. + gcmkASSERT(node->VidMem.nextFree != node);
  131411. + gcmkASSERT(node->VidMem.prevFree != node);
  131412. + }
  131413. + }
  131414. +
  131415. + /* Release the mutex. */
  131416. + gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
  131417. +
  131418. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131419. + "Node 0x%x is freed.",
  131420. + Node);
  131421. +
  131422. + /* Success. */
  131423. + gcmkFOOTER_NO();
  131424. + return gcvSTATUS_OK;
  131425. + }
  131426. +
  131427. + /*************************** Virtual Memory *******************************/
  131428. +
  131429. + /* Get gckKERNEL object. */
  131430. + kernel = Node->Virtual.kernel;
  131431. +
  131432. + /* Verify the gckKERNEL object pointer. */
  131433. + gcmkVERIFY_OBJECT(kernel, gcvOBJ_KERNEL);
  131434. +
  131435. + /* Get the gckOS object pointer. */
  131436. + os = kernel->os;
  131437. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  131438. +
  131439. + /* Grab the mutex. */
  131440. + gcmkONERROR(
  131441. + gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
  131442. +
  131443. + acquired = gcvTRUE;
  131444. +
  131445. + for (i = 0, totalLocked = 0; i < gcdMAX_GPU_COUNT; i++)
  131446. + {
  131447. + totalLocked += Node->Virtual.lockeds[i];
  131448. + }
  131449. +
  131450. + if (totalLocked > 0)
  131451. + {
  131452. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_VIDMEM,
  131453. + "gckVIDMEM_Free: Virtual node 0x%x is locked (%d)",
  131454. + Node, totalLocked);
  131455. +
  131456. + /* Set Flag */
  131457. + Node->Virtual.freed = gcvTRUE;
  131458. +
  131459. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  131460. + }
  131461. + else
  131462. + {
  131463. + /* Free the virtual memory. */
  131464. + gcmkVERIFY_OK(gckOS_FreePagedMemory(kernel->os,
  131465. + Node->Virtual.physical,
  131466. + Node->Virtual.bytes));
  131467. +
  131468. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  131469. +
  131470. + /* Destroy the gcuVIDMEM_NODE union. */
  131471. + gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
  131472. + }
  131473. +
  131474. + /* Success. */
  131475. + gcmkFOOTER_NO();
  131476. + return gcvSTATUS_OK;
  131477. +
  131478. +OnError:
  131479. + if (mutexAcquired)
  131480. + {
  131481. + /* Release the mutex. */
  131482. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  131483. + memory->os, memory->mutex
  131484. + ));
  131485. + }
  131486. +
  131487. + if (acquired)
  131488. + {
  131489. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  131490. + }
  131491. +
  131492. + /* Return the status. */
  131493. + gcmkFOOTER();
  131494. + return status;
  131495. +}
  131496. +
  131497. +
  131498. +#ifdef __QNXNTO__
  131499. +/*******************************************************************************
  131500. +**
  131501. +** gcoVIDMEM_FreeHandleMemory
  131502. +**
  131503. +** Free all allocated video memory nodes for a handle.
  131504. +**
  131505. +** INPUT:
  131506. +**
  131507. +** gcoVIDMEM Memory
  131508. +** Pointer to an gcoVIDMEM object..
  131509. +**
  131510. +** OUTPUT:
  131511. +**
  131512. +** Nothing.
  131513. +*/
  131514. +gceSTATUS
  131515. +gckVIDMEM_FreeHandleMemory(
  131516. + IN gckKERNEL Kernel,
  131517. + IN gckVIDMEM Memory,
  131518. + IN gctUINT32 Pid
  131519. + )
  131520. +{
  131521. + gceSTATUS status;
  131522. + gctBOOL mutex = gcvFALSE;
  131523. + gcuVIDMEM_NODE_PTR node;
  131524. + gctINT i;
  131525. + gctUINT32 nodeCount = 0, byteCount = 0;
  131526. + gctBOOL again;
  131527. +
  131528. + gcmkHEADER_ARG("Kernel=0x%x, Memory=0x%x Pid=0x%u", Kernel, Memory, Pid);
  131529. +
  131530. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  131531. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  131532. +
  131533. + gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
  131534. + mutex = gcvTRUE;
  131535. +
  131536. + /* Walk all sentinels. */
  131537. + for (i = 0; i < gcmCOUNTOF(Memory->sentinel); ++i)
  131538. + {
  131539. + /* Bail out of the heap if it is not used. */
  131540. + if (Memory->sentinel[i].VidMem.next == gcvNULL)
  131541. + {
  131542. + break;
  131543. + }
  131544. +
  131545. + do
  131546. + {
  131547. + again = gcvFALSE;
  131548. +
  131549. + /* Walk all the nodes until we reach the sentinel. */
  131550. + for (node = Memory->sentinel[i].VidMem.next;
  131551. + node->VidMem.bytes != 0;
  131552. + node = node->VidMem.next)
  131553. + {
  131554. + /* Free the node if it was allocated by Handle. */
  131555. + if (node->VidMem.processID == Pid)
  131556. + {
  131557. + /* Unlock video memory. */
  131558. + while (node->VidMem.locked > 0)
  131559. + {
  131560. + gckVIDMEM_Unlock(Kernel, node, gcvSURF_TYPE_UNKNOWN, gcvNULL);
  131561. + }
  131562. +
  131563. + nodeCount++;
  131564. + byteCount += node->VidMem.bytes;
  131565. +
  131566. + /* Free video memory. */
  131567. + gcmkVERIFY_OK(gckVIDMEM_Free(node));
  131568. +
  131569. + /*
  131570. + * Freeing may cause a merge which will invalidate our iteration.
  131571. + * Don't be clever, just restart.
  131572. + */
  131573. + again = gcvTRUE;
  131574. +
  131575. + break;
  131576. + }
  131577. +#if gcdUSE_VIDMEM_PER_PID
  131578. + else
  131579. + {
  131580. + gcmkASSERT(node->VidMem.processID == Pid);
  131581. + }
  131582. +#endif
  131583. + }
  131584. + }
  131585. + while (again);
  131586. + }
  131587. +
  131588. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  131589. + gcmkFOOTER();
  131590. + return gcvSTATUS_OK;
  131591. +
  131592. +OnError:
  131593. + if (mutex)
  131594. + {
  131595. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  131596. + }
  131597. +
  131598. + gcmkFOOTER();
  131599. + return status;
  131600. +}
  131601. +#endif
  131602. +
  131603. +/*******************************************************************************
  131604. +**
  131605. +** _NeedVirtualMapping
  131606. +**
  131607. +** Whether setup GPU page table for video node.
  131608. +**
  131609. +** INPUT:
  131610. +** gckKERNEL Kernel
  131611. +** Pointer to an gckKERNEL object.
  131612. +**
  131613. +** gcuVIDMEM_NODE_PTR Node
  131614. +** Pointer to a gcuVIDMEM_NODE union.
  131615. +**
  131616. +** gceCORE Core
  131617. +** Id of current GPU.
  131618. +**
  131619. +** OUTPUT:
  131620. +** gctBOOL * NeedMapping
  131621. +** A pointer hold the result whether Node should be mapping.
  131622. +*/
  131623. +static gceSTATUS
  131624. +_NeedVirtualMapping(
  131625. + IN gckKERNEL Kernel,
  131626. + IN gceCORE Core,
  131627. + IN gcuVIDMEM_NODE_PTR Node,
  131628. + OUT gctBOOL * NeedMapping
  131629. +)
  131630. +{
  131631. + gceSTATUS status;
  131632. + gctUINT32 phys;
  131633. + gctUINT32 end;
  131634. + gcePOOL pool;
  131635. + gctUINT32 offset;
  131636. + gctUINT32 baseAddress;
  131637. +
  131638. + gcmkHEADER_ARG("Node=0x%X", Node);
  131639. +
  131640. + /* Verify the arguments. */
  131641. + gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
  131642. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  131643. + gcmkVERIFY_ARGUMENT(NeedMapping != gcvNULL);
  131644. + gcmkVERIFY_ARGUMENT(Core < gcdMAX_GPU_COUNT);
  131645. +
  131646. + if (Node->Virtual.contiguous)
  131647. + {
  131648. +#if gcdENABLE_VG
  131649. + if (Core == gcvCORE_VG)
  131650. + {
  131651. + *NeedMapping = gcvFALSE;
  131652. + }
  131653. + else
  131654. +#endif
  131655. + {
  131656. + /* Convert logical address into a physical address. */
  131657. + gcmkONERROR(
  131658. + gckOS_GetPhysicalAddress(Kernel->os, Node->Virtual.logical, &phys));
  131659. +
  131660. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  131661. +
  131662. + gcmkASSERT(phys >= baseAddress);
  131663. +
  131664. + /* Subtract baseAddress to get a GPU address used for programming. */
  131665. + phys -= baseAddress;
  131666. +
  131667. + /* If part of region is belong to gcvPOOL_VIRTUAL,
  131668. + ** whole region has to be mapped. */
  131669. + end = phys + Node->Virtual.bytes - 1;
  131670. +
  131671. + gcmkONERROR(gckHARDWARE_SplitMemory(
  131672. + Kernel->hardware, end, &pool, &offset
  131673. + ));
  131674. +
  131675. + *NeedMapping = (pool == gcvPOOL_VIRTUAL);
  131676. + }
  131677. + }
  131678. + else
  131679. + {
  131680. + *NeedMapping = gcvTRUE;
  131681. + }
  131682. +
  131683. + gcmkFOOTER_ARG("*NeedMapping=%d", *NeedMapping);
  131684. + return gcvSTATUS_OK;
  131685. +
  131686. +OnError:
  131687. + gcmkFOOTER();
  131688. + return status;
  131689. +}
  131690. +
  131691. +/*******************************************************************************
  131692. +**
  131693. +** gckVIDMEM_Lock
  131694. +**
  131695. +** Lock a video memory node and return its hardware specific address.
  131696. +**
  131697. +** INPUT:
  131698. +**
  131699. +** gckKERNEL Kernel
  131700. +** Pointer to an gckKERNEL object.
  131701. +**
  131702. +** gcuVIDMEM_NODE_PTR Node
  131703. +** Pointer to a gcuVIDMEM_NODE union.
  131704. +**
  131705. +** OUTPUT:
  131706. +**
  131707. +** gctUINT32 * Address
  131708. +** Pointer to a variable that will hold the hardware specific address.
  131709. +*/
  131710. +gceSTATUS
  131711. +gckVIDMEM_Lock(
  131712. + IN gckKERNEL Kernel,
  131713. + IN gcuVIDMEM_NODE_PTR Node,
  131714. + IN gctBOOL Cacheable,
  131715. + OUT gctUINT32 * Address
  131716. + )
  131717. +{
  131718. + gceSTATUS status;
  131719. + gctBOOL acquired = gcvFALSE;
  131720. + gctBOOL locked = gcvFALSE;
  131721. + gckOS os = gcvNULL;
  131722. + gctBOOL needMapping;
  131723. + gctUINT32 baseAddress;
  131724. +
  131725. + gcmkHEADER_ARG("Node=0x%x", Node);
  131726. +
  131727. + /* Verify the arguments. */
  131728. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  131729. +
  131730. + if ((Node == gcvNULL)
  131731. + || (Node->VidMem.memory == gcvNULL)
  131732. + )
  131733. + {
  131734. + /* Invalid object. */
  131735. + gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
  131736. + }
  131737. +
  131738. + /**************************** Video Memory ********************************/
  131739. +
  131740. + if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  131741. + {
  131742. + if (Cacheable == gcvTRUE)
  131743. + {
  131744. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  131745. + }
  131746. +
  131747. + /* Increment the lock count. */
  131748. + Node->VidMem.locked ++;
  131749. +
  131750. + /* Return the physical address of the node. */
  131751. +#if !gcdUSE_VIDMEM_PER_PID
  131752. + *Address = Node->VidMem.memory->baseAddress
  131753. + + Node->VidMem.offset
  131754. + + Node->VidMem.alignment;
  131755. +#else
  131756. + *Address = Node->VidMem.physical;
  131757. +#endif
  131758. +
  131759. + /* Get hardware specific address. */
  131760. +#if gcdENABLE_VG
  131761. + if (Kernel->vg == gcvNULL)
  131762. +#endif
  131763. + {
  131764. + if (Kernel->hardware->mmuVersion == 0)
  131765. + {
  131766. + /* Convert physical to GPU address for old mmu. */
  131767. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  131768. + gcmkASSERT(*Address > baseAddress);
  131769. + *Address -= baseAddress;
  131770. + }
  131771. + }
  131772. +
  131773. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131774. + "Locked node 0x%x (%d) @ 0x%08X",
  131775. + Node,
  131776. + Node->VidMem.locked,
  131777. + *Address);
  131778. + }
  131779. +
  131780. + /*************************** Virtual Memory *******************************/
  131781. +
  131782. + else
  131783. + {
  131784. + /* Verify the gckKERNEL object pointer. */
  131785. + gcmkVERIFY_OBJECT(Node->Virtual.kernel, gcvOBJ_KERNEL);
  131786. +
  131787. + /* Extract the gckOS object pointer. */
  131788. + os = Node->Virtual.kernel->os;
  131789. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  131790. +
  131791. + /* Grab the mutex. */
  131792. + gcmkONERROR(gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
  131793. + acquired = gcvTRUE;
  131794. +
  131795. +#if gcdPAGED_MEMORY_CACHEABLE
  131796. + /* Force video memory cacheable. */
  131797. + Cacheable = gcvTRUE;
  131798. +#endif
  131799. +
  131800. + gcmkONERROR(
  131801. + gckOS_LockPages(os,
  131802. + Node->Virtual.physical,
  131803. + Node->Virtual.bytes,
  131804. + Cacheable,
  131805. + &Node->Virtual.logical,
  131806. + &Node->Virtual.pageCount));
  131807. +
  131808. + /* Increment the lock count. */
  131809. + if (Node->Virtual.lockeds[Kernel->core] ++ == 0)
  131810. + {
  131811. + /* Is this node pending for a final unlock? */
  131812. +#ifdef __QNXNTO__
  131813. + if (!Node->Virtual.contiguous && Node->Virtual.unlockPendings[Kernel->core])
  131814. + {
  131815. + /* Make sure we have a page table. */
  131816. + gcmkASSERT(Node->Virtual.pageTables[Kernel->core] != gcvNULL);
  131817. +
  131818. + /* Remove pending unlock. */
  131819. + Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
  131820. + }
  131821. +
  131822. + /* First lock - create a page table. */
  131823. + gcmkASSERT(Node->Virtual.pageTables[Kernel->core] == gcvNULL);
  131824. +
  131825. + /* Make sure we mark our node as not flushed. */
  131826. + Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
  131827. +#endif
  131828. +
  131829. + locked = gcvTRUE;
  131830. +
  131831. + gcmkONERROR(_NeedVirtualMapping(Kernel, Kernel->core, Node, &needMapping));
  131832. +
  131833. + if (needMapping == gcvFALSE)
  131834. + {
  131835. + /* Get hardware specific address. */
  131836. +#if gcdENABLE_VG
  131837. + if (Kernel->vg != gcvNULL)
  131838. + {
  131839. + gcmkONERROR(gckVGHARDWARE_ConvertLogical(Kernel->vg->hardware,
  131840. + Node->Virtual.logical,
  131841. + &Node->Virtual.addresses[Kernel->core]));
  131842. + }
  131843. + else
  131844. +#endif
  131845. + {
  131846. + gcmkONERROR(gckHARDWARE_ConvertLogical(Kernel->hardware,
  131847. + Node->Virtual.logical,
  131848. + &Node->Virtual.addresses[Kernel->core]));
  131849. + }
  131850. + }
  131851. + else
  131852. + {
  131853. +#if gcdENABLE_VG
  131854. + if (Kernel->vg != gcvNULL)
  131855. + {
  131856. + /* Allocate pages inside the MMU. */
  131857. + gcmkONERROR(
  131858. + gckVGMMU_AllocatePages(Kernel->vg->mmu,
  131859. + Node->Virtual.pageCount,
  131860. + &Node->Virtual.pageTables[Kernel->core],
  131861. + &Node->Virtual.addresses[Kernel->core]));
  131862. + }
  131863. + else
  131864. +#endif
  131865. + {
  131866. + /* Allocate pages inside the MMU. */
  131867. + gcmkONERROR(
  131868. + gckMMU_AllocatePagesEx(Kernel->mmu,
  131869. + Node->Virtual.pageCount,
  131870. + Node->Virtual.type,
  131871. + &Node->Virtual.pageTables[Kernel->core],
  131872. + &Node->Virtual.addresses[Kernel->core]));
  131873. + }
  131874. +
  131875. + Node->Virtual.lockKernels[Kernel->core] = Kernel;
  131876. +
  131877. + /* Map the pages. */
  131878. +#ifdef __QNXNTO__
  131879. + gcmkONERROR(
  131880. + gckOS_MapPagesEx(os,
  131881. + Kernel->core,
  131882. + Node->Virtual.physical,
  131883. + Node->Virtual.logical,
  131884. + Node->Virtual.pageCount,
  131885. + Node->Virtual.pageTables[Kernel->core]));
  131886. +#else
  131887. + gcmkONERROR(
  131888. + gckOS_MapPagesEx(os,
  131889. + Kernel->core,
  131890. + Node->Virtual.physical,
  131891. + Node->Virtual.pageCount,
  131892. + Node->Virtual.pageTables[Kernel->core]));
  131893. +#endif
  131894. +
  131895. +#if gcdENABLE_VG
  131896. + if (Kernel->core == gcvCORE_VG)
  131897. + {
  131898. + gcmkONERROR(gckVGMMU_Flush(Kernel->vg->mmu));
  131899. + }
  131900. + else
  131901. +#endif
  131902. + {
  131903. + gcmkONERROR(gckMMU_Flush(Kernel->mmu));
  131904. + }
  131905. + }
  131906. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131907. + "Mapped virtual node 0x%x to 0x%08X",
  131908. + Node,
  131909. + Node->Virtual.addresses[Kernel->core]);
  131910. + }
  131911. +
  131912. + /* Return hardware address. */
  131913. + *Address = Node->Virtual.addresses[Kernel->core];
  131914. +
  131915. + /* Release the mutex. */
  131916. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  131917. + }
  131918. +
  131919. + /* Success. */
  131920. + gcmkFOOTER_ARG("*Address=%08x", *Address);
  131921. + return gcvSTATUS_OK;
  131922. +
  131923. +OnError:
  131924. + if (locked)
  131925. + {
  131926. + if (Node->Virtual.pageTables[Kernel->core] != gcvNULL)
  131927. + {
  131928. +#if gcdENABLE_VG
  131929. + if (Kernel->vg != gcvNULL)
  131930. + {
  131931. + /* Free the pages from the MMU. */
  131932. + gcmkVERIFY_OK(
  131933. + gckVGMMU_FreePages(Kernel->vg->mmu,
  131934. + Node->Virtual.pageTables[Kernel->core],
  131935. + Node->Virtual.pageCount));
  131936. + }
  131937. + else
  131938. +#endif
  131939. + {
  131940. + /* Free the pages from the MMU. */
  131941. + gcmkVERIFY_OK(
  131942. + gckMMU_FreePages(Kernel->mmu,
  131943. + Node->Virtual.pageTables[Kernel->core],
  131944. + Node->Virtual.pageCount));
  131945. + }
  131946. + Node->Virtual.pageTables[Kernel->core] = gcvNULL;
  131947. + Node->Virtual.lockKernels[Kernel->core] = gcvNULL;
  131948. + }
  131949. +
  131950. + /* Unlock the pages. */
  131951. + gcmkVERIFY_OK(
  131952. + gckOS_UnlockPages(os,
  131953. + Node->Virtual.physical,
  131954. + Node->Virtual.bytes,
  131955. + Node->Virtual.logical
  131956. + ));
  131957. +
  131958. + Node->Virtual.lockeds[Kernel->core]--;
  131959. + }
  131960. +
  131961. + if (acquired)
  131962. + {
  131963. + /* Release the mutex. */
  131964. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  131965. + }
  131966. +
  131967. + /* Return the status. */
  131968. + gcmkFOOTER();
  131969. + return status;
  131970. +}
  131971. +
  131972. +/*******************************************************************************
  131973. +**
  131974. +** gckVIDMEM_Unlock
  131975. +**
  131976. +** Unlock a video memory node.
  131977. +**
  131978. +** INPUT:
  131979. +**
  131980. +** gckKERNEL Kernel
  131981. +** Pointer to an gckKERNEL object.
  131982. +**
  131983. +** gcuVIDMEM_NODE_PTR Node
  131984. +** Pointer to a locked gcuVIDMEM_NODE union.
  131985. +**
  131986. +** gceSURF_TYPE Type
  131987. +** Type of surface to unlock.
  131988. +**
  131989. +** gctBOOL * Asynchroneous
  131990. +** Pointer to a variable specifying whether the surface should be
  131991. +** unlocked asynchroneously or not.
  131992. +**
  131993. +** OUTPUT:
  131994. +**
  131995. +** gctBOOL * Asynchroneous
  131996. +** Pointer to a variable receiving the number of bytes used in the
  131997. +** command buffer specified by 'Commands'. If gcvNULL, there is no
  131998. +** command buffer.
  131999. +*/
  132000. +gceSTATUS
  132001. +gckVIDMEM_Unlock(
  132002. + IN gckKERNEL Kernel,
  132003. + IN gcuVIDMEM_NODE_PTR Node,
  132004. + IN gceSURF_TYPE Type,
  132005. + IN OUT gctBOOL * Asynchroneous
  132006. + )
  132007. +{
  132008. + gceSTATUS status;
  132009. + gckHARDWARE hardware;
  132010. + gctPOINTER buffer;
  132011. + gctSIZE_T requested, bufferSize;
  132012. + gckCOMMAND command = gcvNULL;
  132013. + gceKERNEL_FLUSH flush;
  132014. + gckOS os = gcvNULL;
  132015. + gctBOOL acquired = gcvFALSE;
  132016. + gctBOOL commitEntered = gcvFALSE;
  132017. + gctINT32 i, totalLocked;
  132018. +
  132019. + gcmkHEADER_ARG("Node=0x%x Type=%d *Asynchroneous=%d",
  132020. + Node, Type, gcmOPT_VALUE(Asynchroneous));
  132021. +
  132022. + /* Verify the arguments. */
  132023. + if ((Node == gcvNULL)
  132024. + || (Node->VidMem.memory == gcvNULL)
  132025. + )
  132026. + {
  132027. + /* Invalid object. */
  132028. + gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
  132029. + }
  132030. +
  132031. + /**************************** Video Memory ********************************/
  132032. +
  132033. + if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  132034. + {
  132035. + if (Node->VidMem.locked <= 0)
  132036. + {
  132037. + /* The surface was not locked. */
  132038. + status = gcvSTATUS_MEMORY_UNLOCKED;
  132039. + goto OnError;
  132040. + }
  132041. +
  132042. + /* Decrement the lock count. */
  132043. + Node->VidMem.locked --;
  132044. +
  132045. + if (Asynchroneous != gcvNULL)
  132046. + {
  132047. + /* No need for any events. */
  132048. + *Asynchroneous = gcvFALSE;
  132049. + }
  132050. +
  132051. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132052. + "Unlocked node 0x%x (%d)",
  132053. + Node,
  132054. + Node->VidMem.locked);
  132055. +
  132056. +#ifdef __QNXNTO__
  132057. + /* Unmap the video memory */
  132058. + if ((Node->VidMem.locked == 0) && (Node->VidMem.logical != gcvNULL))
  132059. + {
  132060. + if (Kernel->core == gcvCORE_VG)
  132061. + {
  132062. + gckKERNEL_UnmapVideoMemory(Kernel,
  132063. + Node->VidMem.logical,
  132064. + Node->VidMem.processID,
  132065. + Node->VidMem.bytes);
  132066. + Node->VidMem.logical = gcvNULL;
  132067. + }
  132068. + }
  132069. +#endif /* __QNXNTO__ */
  132070. +
  132071. + if (Node->VidMem.freePending && (Node->VidMem.locked == 0))
  132072. + {
  132073. + /* Client has unlocked node previously attempted to be freed by compositor. Free now. */
  132074. + Node->VidMem.freePending = gcvFALSE;
  132075. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132076. + "Deferred-freeing Node 0x%x.",
  132077. + Node);
  132078. + gcmkONERROR(gckVIDMEM_Free(Node));
  132079. + }
  132080. + }
  132081. +
  132082. + /*************************** Virtual Memory *******************************/
  132083. +
  132084. + else
  132085. + {
  132086. + /* Verify the gckHARDWARE object pointer. */
  132087. + hardware = Kernel->hardware;
  132088. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  132089. +
  132090. + /* Verify the gckCOMMAND object pointer. */
  132091. + command = Kernel->command;
  132092. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  132093. +
  132094. + /* Get the gckOS object pointer. */
  132095. + os = Kernel->os;
  132096. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  132097. +
  132098. + /* Grab the mutex. */
  132099. + gcmkONERROR(
  132100. + gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
  132101. +
  132102. + acquired = gcvTRUE;
  132103. +
  132104. + if (Asynchroneous == gcvNULL)
  132105. + {
  132106. + if (Node->Virtual.lockeds[Kernel->core] == 0)
  132107. + {
  132108. + status = gcvSTATUS_MEMORY_UNLOCKED;
  132109. + goto OnError;
  132110. + }
  132111. +
  132112. + /* Decrement lock count. */
  132113. + -- Node->Virtual.lockeds[Kernel->core];
  132114. +
  132115. + /* See if we can unlock the resources. */
  132116. + if (Node->Virtual.lockeds[Kernel->core] == 0)
  132117. + {
  132118. + /* Free the page table. */
  132119. + if (Node->Virtual.pageTables[Kernel->core] != gcvNULL)
  132120. + {
  132121. +#if gcdENABLE_VG
  132122. + if (Kernel->vg != gcvNULL)
  132123. + {
  132124. + gcmkONERROR(
  132125. + gckVGMMU_FreePages(Kernel->vg->mmu,
  132126. + Node->Virtual.pageTables[Kernel->core],
  132127. + Node->Virtual.pageCount));
  132128. + }
  132129. + else
  132130. +#endif
  132131. + {
  132132. + gcmkONERROR(
  132133. + gckMMU_FreePages(Kernel->mmu,
  132134. + Node->Virtual.pageTables[Kernel->core],
  132135. + Node->Virtual.pageCount));
  132136. + }
  132137. + /* Mark page table as freed. */
  132138. + Node->Virtual.pageTables[Kernel->core] = gcvNULL;
  132139. + Node->Virtual.lockKernels[Kernel->core] = gcvNULL;
  132140. + }
  132141. +
  132142. +#ifdef __QNXNTO__
  132143. + /* Mark node as unlocked. */
  132144. + Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
  132145. +#endif
  132146. + }
  132147. +
  132148. + for (i = 0, totalLocked = 0; i < gcdMAX_GPU_COUNT; i++)
  132149. + {
  132150. + totalLocked += Node->Virtual.lockeds[i];
  132151. + }
  132152. +
  132153. + if (totalLocked == 0)
  132154. + {
  132155. + /* Owner have already freed this node
  132156. + ** and we are the last one to unlock, do
  132157. + ** real free */
  132158. + if (Node->Virtual.freed)
  132159. + {
  132160. + /* Free the virtual memory. */
  132161. + gcmkVERIFY_OK(gckOS_FreePagedMemory(Kernel->os,
  132162. + Node->Virtual.physical,
  132163. + Node->Virtual.bytes));
  132164. +
  132165. + /* Release mutex before node is destroyed */
  132166. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  132167. +
  132168. + acquired = gcvFALSE;
  132169. +
  132170. + /* Destroy the gcuVIDMEM_NODE union. */
  132171. + gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
  132172. +
  132173. + /* Node has been destroyed, so we should not touch it any more */
  132174. + gcmkFOOTER();
  132175. + return gcvSTATUS_OK;
  132176. + }
  132177. + }
  132178. +
  132179. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132180. + "Unmapped virtual node 0x%x from 0x%08X",
  132181. + Node, Node->Virtual.addresses[Kernel->core]);
  132182. +
  132183. + }
  132184. +
  132185. + else
  132186. + {
  132187. + /* If we need to unlock a node from virtual memory we have to be
  132188. + ** very carefull. If the node is still inside the caches we
  132189. + ** might get a bus error later if the cache line needs to be
  132190. + ** replaced. So - we have to flush the caches before we do
  132191. + ** anything. */
  132192. +
  132193. + /* gckCommand_EnterCommit() can't be called in interrupt handler because
  132194. + ** of a dead lock situation:
  132195. + ** process call Command_Commit(), and acquire Command->mutexQueue in
  132196. + ** gckCOMMAND_EnterCommit(). Then it will wait for a signal which depends
  132197. + ** on interrupt handler to generate, if interrupt handler enter
  132198. + ** gckCommand_EnterCommit(), process will never get the signal. */
  132199. +
  132200. + /* So, flush cache when we still in process context, and then ask caller to
  132201. + ** schedule a event. */
  132202. +
  132203. + gcmkONERROR(
  132204. + gckOS_UnlockPages(os,
  132205. + Node->Virtual.physical,
  132206. + Node->Virtual.bytes,
  132207. + Node->Virtual.logical));
  132208. +
  132209. + if (!Node->Virtual.contiguous
  132210. + && (Node->Virtual.lockeds[Kernel->core] == 1)
  132211. +#if gcdENABLE_VG
  132212. + && (Kernel->vg == gcvNULL)
  132213. +#endif
  132214. + )
  132215. + {
  132216. + if (Type == gcvSURF_BITMAP)
  132217. + {
  132218. + /* Flush 2D cache. */
  132219. + flush = gcvFLUSH_2D;
  132220. + }
  132221. + else if (Type == gcvSURF_RENDER_TARGET)
  132222. + {
  132223. + /* Flush color cache. */
  132224. + flush = gcvFLUSH_COLOR;
  132225. + }
  132226. + else if (Type == gcvSURF_DEPTH)
  132227. + {
  132228. + /* Flush depth cache. */
  132229. + flush = gcvFLUSH_DEPTH;
  132230. + }
  132231. + else
  132232. + {
  132233. + /* No flush required. */
  132234. + flush = (gceKERNEL_FLUSH) 0;
  132235. + }
  132236. + if(hardware)
  132237. + {
  132238. + gcmkONERROR(
  132239. + gckHARDWARE_Flush(hardware, flush, gcvNULL, &requested));
  132240. +
  132241. + if (requested != 0)
  132242. + {
  132243. + /* Acquire the command queue. */
  132244. + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
  132245. + commitEntered = gcvTRUE;
  132246. +
  132247. + gcmkONERROR(gckCOMMAND_Reserve(
  132248. + command, requested, &buffer, &bufferSize
  132249. + ));
  132250. +
  132251. + gcmkONERROR(gckHARDWARE_Flush(
  132252. + hardware, flush, buffer, &bufferSize
  132253. + ));
  132254. +
  132255. + /* Mark node as pending. */
  132256. +#ifdef __QNXNTO__
  132257. + Node->Virtual.unlockPendings[Kernel->core] = gcvTRUE;
  132258. +#endif
  132259. +
  132260. + gcmkONERROR(gckCOMMAND_Execute(command, requested));
  132261. +
  132262. + /* Release the command queue. */
  132263. + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
  132264. + commitEntered = gcvFALSE;
  132265. + }
  132266. + }
  132267. + else
  132268. + {
  132269. + gckOS_Print("Hardware already is freed.\n");
  132270. + }
  132271. + }
  132272. +
  132273. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132274. + "Scheduled unlock for virtual node 0x%x",
  132275. + Node);
  132276. +
  132277. + /* Schedule the surface to be unlocked. */
  132278. + *Asynchroneous = gcvTRUE;
  132279. + }
  132280. +
  132281. + /* Release the mutex. */
  132282. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  132283. +
  132284. + acquired = gcvFALSE;
  132285. + }
  132286. +
  132287. + /* Success. */
  132288. + gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous));
  132289. + return gcvSTATUS_OK;
  132290. +
  132291. +OnError:
  132292. + if (commitEntered)
  132293. + {
  132294. + /* Release the command queue mutex. */
  132295. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, gcvFALSE));
  132296. + }
  132297. +
  132298. + if (acquired)
  132299. + {
  132300. + /* Release the mutex. */
  132301. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  132302. + }
  132303. +
  132304. + /* Return the status. */
  132305. + gcmkFOOTER();
  132306. + return status;
  132307. +}
  132308. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
  132309. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h 1970-01-01 01:00:00.000000000 +0100
  132310. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h 2014-08-20 19:31:46.132869024 +0200
  132311. @@ -0,0 +1,3896 @@
  132312. +/****************************************************************************
  132313. +*
  132314. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  132315. +*
  132316. +* This program is free software; you can redistribute it and/or modify
  132317. +* it under the terms of the GNU General Public License as published by
  132318. +* the Free Software Foundation; either version 2 of the license, or
  132319. +* (at your option) any later version.
  132320. +*
  132321. +* This program is distributed in the hope that it will be useful,
  132322. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  132323. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  132324. +* GNU General Public License for more details.
  132325. +*
  132326. +* You should have received a copy of the GNU General Public License
  132327. +* along with this program; if not write to the Free Software
  132328. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  132329. +*
  132330. +*****************************************************************************/
  132331. +
  132332. +
  132333. +#ifndef __gc_hal_base_h_
  132334. +#define __gc_hal_base_h_
  132335. +
  132336. +#include "gc_hal_enum.h"
  132337. +#include "gc_hal_types.h"
  132338. +
  132339. +#include "gc_hal_dump.h"
  132340. +
  132341. +#ifdef __cplusplus
  132342. +extern "C" {
  132343. +#endif
  132344. +
  132345. +/******************************************************************************\
  132346. +****************************** Object Declarations *****************************
  132347. +\******************************************************************************/
  132348. +
  132349. +typedef struct _gckOS * gckOS;
  132350. +typedef struct _gcoHAL * gcoHAL;
  132351. +typedef struct _gcoOS * gcoOS;
  132352. +typedef struct _gco2D * gco2D;
  132353. +
  132354. +#ifndef VIVANTE_NO_3D
  132355. +typedef struct _gco3D * gco3D;
  132356. +#endif
  132357. +
  132358. +typedef struct _gcoSURF * gcoSURF;
  132359. +typedef struct _gcsSURF_INFO * gcsSURF_INFO_PTR;
  132360. +typedef struct _gcsSURF_NODE * gcsSURF_NODE_PTR;
  132361. +typedef struct _gcsSURF_FORMAT_INFO * gcsSURF_FORMAT_INFO_PTR;
  132362. +typedef struct _gcsPOINT * gcsPOINT_PTR;
  132363. +typedef struct _gcsSIZE * gcsSIZE_PTR;
  132364. +typedef struct _gcsRECT * gcsRECT_PTR;
  132365. +typedef struct _gcsBOUNDARY * gcsBOUNDARY_PTR;
  132366. +typedef struct _gcoDUMP * gcoDUMP;
  132367. +typedef struct _gcoHARDWARE * gcoHARDWARE;
  132368. +typedef union _gcuVIDMEM_NODE * gcuVIDMEM_NODE_PTR;
  132369. +
  132370. +typedef struct gcsATOM * gcsATOM_PTR;
  132371. +
  132372. +#if gcdENABLE_VG
  132373. +typedef struct _gcoVG * gcoVG;
  132374. +typedef struct _gcsCOMPLETION_SIGNAL * gcsCOMPLETION_SIGNAL_PTR;
  132375. +typedef struct _gcsCONTEXT_MAP * gcsCONTEXT_MAP_PTR;
  132376. +#else
  132377. +typedef void * gcoVG;
  132378. +#endif
  132379. +
  132380. +#if gcdSYNC
  132381. +typedef struct _gcoFENCE * gcoFENCE;
  132382. +typedef struct _gcsSYNC_CONTEXT * gcsSYNC_CONTEXT_PTR;
  132383. +#endif
  132384. +
  132385. +typedef struct _gcoOS_SymbolsList gcoOS_SymbolsList;
  132386. +
  132387. +/******************************************************************************\
  132388. +******************************* Process local storage *************************
  132389. +\******************************************************************************/
  132390. +typedef struct _gcsPLS * gcsPLS_PTR;
  132391. +
  132392. +typedef void (* gctPLS_DESTRUCTOR) (
  132393. + gcsPLS_PTR
  132394. + );
  132395. +
  132396. +typedef struct _gcsPLS
  132397. +{
  132398. + /* Global objects. */
  132399. + gcoOS os;
  132400. + gcoHAL hal;
  132401. +
  132402. + /* Internal memory pool. */
  132403. + gctSIZE_T internalSize;
  132404. + gctPHYS_ADDR internalPhysical;
  132405. + gctPOINTER internalLogical;
  132406. +
  132407. + /* External memory pool. */
  132408. + gctSIZE_T externalSize;
  132409. + gctPHYS_ADDR externalPhysical;
  132410. + gctPOINTER externalLogical;
  132411. +
  132412. + /* Contiguous memory pool. */
  132413. + gctSIZE_T contiguousSize;
  132414. + gctPHYS_ADDR contiguousPhysical;
  132415. + gctPOINTER contiguousLogical;
  132416. +
  132417. + /* EGL-specific process-wide objects. */
  132418. + gctPOINTER eglDisplayInfo;
  132419. + gctPOINTER eglSurfaceInfo;
  132420. + gceSURF_FORMAT eglConfigFormat;
  132421. +
  132422. + /* PorcessID of the constrcutor process */
  132423. + gctUINT32 processID;
  132424. +#if gcdFORCE_GAL_LOAD_TWICE
  132425. + /* ThreadID of the constrcutor process. */
  132426. + gctSIZE_T threadID;
  132427. + /* Flag for calling module destructor. */
  132428. + gctBOOL exiting;
  132429. +#endif
  132430. +
  132431. + /* Reference count for destructor. */
  132432. + gcsATOM_PTR reference;
  132433. + gctBOOL bKFS;
  132434. +#if gcdUSE_NPOT_PATCH
  132435. + gctBOOL bNeedSupportNP2Texture;
  132436. +#endif
  132437. +
  132438. + /* Destructor for eglDisplayInfo. */
  132439. + gctPLS_DESTRUCTOR destructor;
  132440. +}
  132441. +gcsPLS;
  132442. +
  132443. +extern gcsPLS gcPLS;
  132444. +
  132445. +/******************************************************************************\
  132446. +******************************* Thread local storage *************************
  132447. +\******************************************************************************/
  132448. +
  132449. +typedef struct _gcsTLS * gcsTLS_PTR;
  132450. +
  132451. +typedef void (* gctTLS_DESTRUCTOR) (
  132452. + gcsTLS_PTR
  132453. + );
  132454. +
  132455. +typedef struct _gcsTLS
  132456. +{
  132457. + gceHARDWARE_TYPE currentType;
  132458. + gcoHARDWARE hardware;
  132459. + /* Only for separated 3D and 2D */
  132460. + gcoHARDWARE hardware2D;
  132461. +#if gcdENABLE_VG
  132462. + gcoVGHARDWARE vg;
  132463. + gcoVG engineVG;
  132464. +#endif /* gcdENABLE_VG */
  132465. + gctPOINTER context;
  132466. + gctTLS_DESTRUCTOR destructor;
  132467. + gctBOOL ProcessExiting;
  132468. +
  132469. +#ifndef VIVANTE_NO_3D
  132470. + gco3D engine3D;
  132471. +#endif
  132472. +#if gcdSYNC
  132473. + gctBOOL fenceEnable;
  132474. +#endif
  132475. + gco2D engine2D;
  132476. + gctBOOL copied;
  132477. +
  132478. +#if gcdFORCE_GAL_LOAD_TWICE
  132479. + /* libGAL.so handle */
  132480. + gctHANDLE handle;
  132481. +#endif
  132482. +}
  132483. +gcsTLS;
  132484. +
  132485. +/******************************************************************************\
  132486. +********************************* Enumerations *********************************
  132487. +\******************************************************************************/
  132488. +
  132489. +typedef enum _gcePLS_VALUE
  132490. +{
  132491. + gcePLS_VALUE_EGL_DISPLAY_INFO,
  132492. + gcePLS_VALUE_EGL_SURFACE_INFO,
  132493. + gcePLS_VALUE_EGL_CONFIG_FORMAT_INFO,
  132494. + gcePLS_VALUE_EGL_DESTRUCTOR_INFO,
  132495. +}
  132496. +gcePLS_VALUE;
  132497. +
  132498. +/* Video memory pool type. */
  132499. +typedef enum _gcePOOL
  132500. +{
  132501. + gcvPOOL_UNKNOWN = 0,
  132502. + gcvPOOL_DEFAULT,
  132503. + gcvPOOL_LOCAL,
  132504. + gcvPOOL_LOCAL_INTERNAL,
  132505. + gcvPOOL_LOCAL_EXTERNAL,
  132506. + gcvPOOL_UNIFIED,
  132507. + gcvPOOL_SYSTEM,
  132508. + gcvPOOL_VIRTUAL,
  132509. + gcvPOOL_USER,
  132510. + gcvPOOL_CONTIGUOUS,
  132511. + gcvPOOL_DEFAULT_FORCE_CONTIGUOUS,
  132512. + gcvPOOL_DEFAULT_FORCE_CONTIGUOUS_CACHEABLE,
  132513. +
  132514. + gcvPOOL_NUMBER_OF_POOLS
  132515. +}
  132516. +gcePOOL;
  132517. +
  132518. +#ifndef VIVANTE_NO_3D
  132519. +/* Blending functions. */
  132520. +typedef enum _gceBLEND_FUNCTION
  132521. +{
  132522. + gcvBLEND_ZERO,
  132523. + gcvBLEND_ONE,
  132524. + gcvBLEND_SOURCE_COLOR,
  132525. + gcvBLEND_INV_SOURCE_COLOR,
  132526. + gcvBLEND_SOURCE_ALPHA,
  132527. + gcvBLEND_INV_SOURCE_ALPHA,
  132528. + gcvBLEND_TARGET_COLOR,
  132529. + gcvBLEND_INV_TARGET_COLOR,
  132530. + gcvBLEND_TARGET_ALPHA,
  132531. + gcvBLEND_INV_TARGET_ALPHA,
  132532. + gcvBLEND_SOURCE_ALPHA_SATURATE,
  132533. + gcvBLEND_CONST_COLOR,
  132534. + gcvBLEND_INV_CONST_COLOR,
  132535. + gcvBLEND_CONST_ALPHA,
  132536. + gcvBLEND_INV_CONST_ALPHA,
  132537. +}
  132538. +gceBLEND_FUNCTION;
  132539. +
  132540. +/* Blending modes. */
  132541. +typedef enum _gceBLEND_MODE
  132542. +{
  132543. + gcvBLEND_ADD,
  132544. + gcvBLEND_SUBTRACT,
  132545. + gcvBLEND_REVERSE_SUBTRACT,
  132546. + gcvBLEND_MIN,
  132547. + gcvBLEND_MAX,
  132548. +}
  132549. +gceBLEND_MODE;
  132550. +
  132551. +/* API flags. */
  132552. +typedef enum _gceAPI
  132553. +{
  132554. + gcvAPI_D3D = 0x1,
  132555. + gcvAPI_OPENGL = 0x2,
  132556. + gcvAPI_OPENVG = 0x3,
  132557. + gcvAPI_OPENCL = 0x4,
  132558. +}
  132559. +gceAPI;
  132560. +
  132561. +/* Depth modes. */
  132562. +typedef enum _gceDEPTH_MODE
  132563. +{
  132564. + gcvDEPTH_NONE,
  132565. + gcvDEPTH_Z,
  132566. + gcvDEPTH_W,
  132567. +}
  132568. +gceDEPTH_MODE;
  132569. +#endif /* VIVANTE_NO_3D */
  132570. +
  132571. +typedef enum _gceWHERE
  132572. +{
  132573. + gcvWHERE_COMMAND,
  132574. + gcvWHERE_RASTER,
  132575. + gcvWHERE_PIXEL,
  132576. +}
  132577. +gceWHERE;
  132578. +
  132579. +typedef enum _gceHOW
  132580. +{
  132581. + gcvHOW_SEMAPHORE = 0x1,
  132582. + gcvHOW_STALL = 0x2,
  132583. + gcvHOW_SEMAPHORE_STALL = 0x3,
  132584. +}
  132585. +gceHOW;
  132586. +
  132587. +typedef enum _gceSignalHandlerType
  132588. +{
  132589. + gcvHANDLE_SIGFPE_WHEN_SIGNAL_CODE_IS_0 = 0x1,
  132590. +}
  132591. +gceSignalHandlerType;
  132592. +
  132593. +
  132594. +#if gcdENABLE_VG
  132595. +/* gcsHAL_Limits*/
  132596. +typedef struct _gcsHAL_LIMITS
  132597. +{
  132598. + /* chip info */
  132599. + gceCHIPMODEL chipModel;
  132600. + gctUINT32 chipRevision;
  132601. + gctUINT32 featureCount;
  132602. + gctUINT32 *chipFeatures;
  132603. +
  132604. + /* target caps */
  132605. + gctUINT32 maxWidth;
  132606. + gctUINT32 maxHeight;
  132607. + gctUINT32 multiTargetCount;
  132608. + gctUINT32 maxSamples;
  132609. +
  132610. +}gcsHAL_LIMITS;
  132611. +#endif
  132612. +
  132613. +/******************************************************************************\
  132614. +*********** Generic Memory Allocation Optimization Using Containers ************
  132615. +\******************************************************************************/
  132616. +
  132617. +/* Generic container definition. */
  132618. +typedef struct _gcsCONTAINER_LINK * gcsCONTAINER_LINK_PTR;
  132619. +typedef struct _gcsCONTAINER_LINK
  132620. +{
  132621. + /* Points to the next container. */
  132622. + gcsCONTAINER_LINK_PTR next;
  132623. +}
  132624. +gcsCONTAINER_LINK;
  132625. +
  132626. +typedef struct _gcsCONTAINER_RECORD * gcsCONTAINER_RECORD_PTR;
  132627. +typedef struct _gcsCONTAINER_RECORD
  132628. +{
  132629. + gcsCONTAINER_RECORD_PTR prev;
  132630. + gcsCONTAINER_RECORD_PTR next;
  132631. +}
  132632. +gcsCONTAINER_RECORD;
  132633. +
  132634. +typedef struct _gcsCONTAINER * gcsCONTAINER_PTR;
  132635. +typedef struct _gcsCONTAINER
  132636. +{
  132637. + gctUINT containerSize;
  132638. + gctUINT recordSize;
  132639. + gctUINT recordCount;
  132640. + gcsCONTAINER_LINK_PTR containers;
  132641. + gcsCONTAINER_RECORD freeList;
  132642. + gcsCONTAINER_RECORD allocList;
  132643. +}
  132644. +gcsCONTAINER;
  132645. +
  132646. +gceSTATUS
  132647. +gcsCONTAINER_Construct(
  132648. + IN gcsCONTAINER_PTR Container,
  132649. + gctUINT RecordsPerContainer,
  132650. + gctUINT RecordSize
  132651. + );
  132652. +
  132653. +gceSTATUS
  132654. +gcsCONTAINER_Destroy(
  132655. + IN gcsCONTAINER_PTR Container
  132656. + );
  132657. +
  132658. +gceSTATUS
  132659. +gcsCONTAINER_AllocateRecord(
  132660. + IN gcsCONTAINER_PTR Container,
  132661. + OUT gctPOINTER * Record
  132662. + );
  132663. +
  132664. +gceSTATUS
  132665. +gcsCONTAINER_FreeRecord(
  132666. + IN gcsCONTAINER_PTR Container,
  132667. + IN gctPOINTER Record
  132668. + );
  132669. +
  132670. +gceSTATUS
  132671. +gcsCONTAINER_FreeAll(
  132672. + IN gcsCONTAINER_PTR Container
  132673. + );
  132674. +
  132675. +/******************************************************************************\
  132676. +********************************* gcoHAL Object *********************************
  132677. +\******************************************************************************/
  132678. +
  132679. +/* Construct a new gcoHAL object. */
  132680. +gceSTATUS
  132681. +gcoHAL_Construct(
  132682. + IN gctPOINTER Context,
  132683. + IN gcoOS Os,
  132684. + OUT gcoHAL * Hal
  132685. + );
  132686. +
  132687. +/* Destroy an gcoHAL object. */
  132688. +gceSTATUS
  132689. +gcoHAL_Destroy(
  132690. + IN gcoHAL Hal
  132691. + );
  132692. +
  132693. +/* Get pointer to gco2D object. */
  132694. +gceSTATUS
  132695. +gcoHAL_Get2DEngine(
  132696. + IN gcoHAL Hal,
  132697. + OUT gco2D * Engine
  132698. + );
  132699. +
  132700. +gceSTATUS
  132701. +gcoHAL_SetFscaleValue(
  132702. + IN gctUINT FscaleValue
  132703. + );
  132704. +
  132705. +gceSTATUS
  132706. +gcoHAL_GetFscaleValue(
  132707. + OUT gctUINT * FscaleValue,
  132708. + OUT gctUINT * MinFscaleValue,
  132709. + OUT gctUINT * MaxFscaleValue
  132710. + );
  132711. +
  132712. +gceSTATUS
  132713. +gcoHAL_SetBltNP2Texture(
  132714. + gctBOOL enable
  132715. + );
  132716. +
  132717. +#ifndef VIVANTE_NO_3D
  132718. +/* Get pointer to gco3D object. */
  132719. +gceSTATUS
  132720. +gcoHAL_Get3DEngine(
  132721. + IN gcoHAL Hal,
  132722. + OUT gco3D * Engine
  132723. + );
  132724. +
  132725. +gceSTATUS
  132726. +gcoHAL_Query3DEngine(
  132727. + IN gcoHAL Hal,
  132728. + OUT gco3D * Engine
  132729. + );
  132730. +
  132731. +gceSTATUS
  132732. +gcoHAL_Set3DEngine(
  132733. + IN gcoHAL Hal,
  132734. + IN gco3D Engine
  132735. + );
  132736. +
  132737. +gceSTATUS
  132738. +gcoHAL_Get3DHardware(
  132739. + IN gcoHAL Hal,
  132740. + OUT gcoHARDWARE * Hardware
  132741. + );
  132742. +
  132743. +gceSTATUS
  132744. +gcoHAL_Set3DHardware(
  132745. + IN gcoHAL Hal,
  132746. + IN gcoHARDWARE Hardware
  132747. + );
  132748. +
  132749. +
  132750. +#endif /* VIVANTE_NO_3D */
  132751. +
  132752. +/* Verify whether the specified feature is available in hardware. */
  132753. +gceSTATUS
  132754. +gcoHAL_IsFeatureAvailable(
  132755. + IN gcoHAL Hal,
  132756. + IN gceFEATURE Feature
  132757. + );
  132758. +
  132759. +/* Query the identity of the hardware. */
  132760. +gceSTATUS
  132761. +gcoHAL_QueryChipIdentity(
  132762. + IN gcoHAL Hal,
  132763. + OUT gceCHIPMODEL* ChipModel,
  132764. + OUT gctUINT32* ChipRevision,
  132765. + OUT gctUINT32* ChipFeatures,
  132766. + OUT gctUINT32* ChipMinorFeatures
  132767. + );
  132768. +
  132769. +/* Query the minor features of the hardware. */
  132770. +gceSTATUS gcoHAL_QueryChipMinorFeatures(
  132771. + IN gcoHAL Hal,
  132772. + OUT gctUINT32* NumFeatures,
  132773. + OUT gctUINT32* ChipMinorFeatures
  132774. + );
  132775. +
  132776. +/* Query the amount of video memory. */
  132777. +gceSTATUS
  132778. +gcoHAL_QueryVideoMemory(
  132779. + IN gcoHAL Hal,
  132780. + OUT gctPHYS_ADDR * InternalAddress,
  132781. + OUT gctSIZE_T * InternalSize,
  132782. + OUT gctPHYS_ADDR * ExternalAddress,
  132783. + OUT gctSIZE_T * ExternalSize,
  132784. + OUT gctPHYS_ADDR * ContiguousAddress,
  132785. + OUT gctSIZE_T * ContiguousSize
  132786. + );
  132787. +
  132788. +/* Map video memory. */
  132789. +gceSTATUS
  132790. +gcoHAL_MapMemory(
  132791. + IN gcoHAL Hal,
  132792. + IN gctPHYS_ADDR Physical,
  132793. + IN gctSIZE_T NumberOfBytes,
  132794. + OUT gctPOINTER * Logical
  132795. + );
  132796. +
  132797. +/* Unmap video memory. */
  132798. +gceSTATUS
  132799. +gcoHAL_UnmapMemory(
  132800. + IN gcoHAL Hal,
  132801. + IN gctPHYS_ADDR Physical,
  132802. + IN gctSIZE_T NumberOfBytes,
  132803. + IN gctPOINTER Logical
  132804. + );
  132805. +
  132806. +/* Schedule an unmap of a buffer mapped through its physical address. */
  132807. +gceSTATUS
  132808. +gcoHAL_ScheduleUnmapMemory(
  132809. + IN gcoHAL Hal,
  132810. + IN gctPHYS_ADDR Physical,
  132811. + IN gctSIZE_T NumberOfBytes,
  132812. + IN gctPOINTER Logical
  132813. + );
  132814. +
  132815. +/* Map user memory. */
  132816. +gceSTATUS
  132817. +gcoHAL_MapUserMemory(
  132818. + IN gctPOINTER Logical,
  132819. + IN gctUINT32 Physical,
  132820. + IN gctSIZE_T Size,
  132821. + OUT gctPOINTER * Info,
  132822. + OUT gctUINT32_PTR GPUAddress
  132823. + );
  132824. +
  132825. +/* Unmap user memory. */
  132826. +gceSTATUS
  132827. +gcoHAL_UnmapUserMemory(
  132828. + IN gctPOINTER Logical,
  132829. + IN gctSIZE_T Size,
  132830. + IN gctPOINTER Info,
  132831. + IN gctUINT32 GPUAddress
  132832. + );
  132833. +
  132834. +/* Schedule an unmap of a user buffer using event mechanism. */
  132835. +gceSTATUS
  132836. +gcoHAL_ScheduleUnmapUserMemory(
  132837. + IN gcoHAL Hal,
  132838. + IN gctPOINTER Info,
  132839. + IN gctSIZE_T Size,
  132840. + IN gctUINT32 Address,
  132841. + IN gctPOINTER Memory
  132842. + );
  132843. +
  132844. +/* Commit the current command buffer. */
  132845. +gceSTATUS
  132846. +gcoHAL_Commit(
  132847. + IN gcoHAL Hal,
  132848. + IN gctBOOL Stall
  132849. + );
  132850. +
  132851. +/* Query the tile capabilities. */
  132852. +gceSTATUS
  132853. +gcoHAL_QueryTiled(
  132854. + IN gcoHAL Hal,
  132855. + OUT gctINT32 * TileWidth2D,
  132856. + OUT gctINT32 * TileHeight2D,
  132857. + OUT gctINT32 * TileWidth3D,
  132858. + OUT gctINT32 * TileHeight3D
  132859. + );
  132860. +
  132861. +gceSTATUS
  132862. +gcoHAL_Compact(
  132863. + IN gcoHAL Hal
  132864. + );
  132865. +
  132866. +#if VIVANTE_PROFILER
  132867. +gceSTATUS
  132868. +gcoHAL_ProfileStart(
  132869. + IN gcoHAL Hal
  132870. + );
  132871. +
  132872. +gceSTATUS
  132873. +gcoHAL_ProfileEnd(
  132874. + IN gcoHAL Hal,
  132875. + IN gctCONST_STRING Title
  132876. + );
  132877. +#endif
  132878. +
  132879. +/* Power Management */
  132880. +gceSTATUS
  132881. +gcoHAL_SetPowerManagementState(
  132882. + IN gcoHAL Hal,
  132883. + IN gceCHIPPOWERSTATE State
  132884. + );
  132885. +
  132886. +gceSTATUS
  132887. +gcoHAL_QueryPowerManagementState(
  132888. + IN gcoHAL Hal,
  132889. + OUT gceCHIPPOWERSTATE *State
  132890. + );
  132891. +
  132892. +/* Set the filter type for filter blit. */
  132893. +gceSTATUS
  132894. +gcoHAL_SetFilterType(
  132895. + IN gcoHAL Hal,
  132896. + IN gceFILTER_TYPE FilterType
  132897. + );
  132898. +
  132899. +gceSTATUS
  132900. +gcoHAL_GetDump(
  132901. + IN gcoHAL Hal,
  132902. + OUT gcoDUMP * Dump
  132903. + );
  132904. +
  132905. +/* Call the kernel HAL layer. */
  132906. +gceSTATUS
  132907. +gcoHAL_Call(
  132908. + IN gcoHAL Hal,
  132909. + IN OUT gcsHAL_INTERFACE_PTR Interface
  132910. + );
  132911. +
  132912. +gceSTATUS
  132913. +gcoHAL_GetPatchID(
  132914. + IN gcoHAL Hal,
  132915. + OUT gcePATCH_ID * PatchID
  132916. + );
  132917. +
  132918. +/* Schedule an event. */
  132919. +gceSTATUS
  132920. +gcoHAL_ScheduleEvent(
  132921. + IN gcoHAL Hal,
  132922. + IN OUT gcsHAL_INTERFACE_PTR Interface
  132923. + );
  132924. +
  132925. +/* Destroy a surface. */
  132926. +gceSTATUS
  132927. +gcoHAL_DestroySurface(
  132928. + IN gcoHAL Hal,
  132929. + IN gcoSURF Surface
  132930. + );
  132931. +
  132932. +/* Request a start/stop timestamp. */
  132933. +gceSTATUS
  132934. +gcoHAL_SetTimer(
  132935. + IN gcoHAL Hal,
  132936. + IN gctUINT32 Index,
  132937. + IN gctBOOL Start
  132938. + );
  132939. +
  132940. +/* Get Time delta from a Timer in microseconds. */
  132941. +gceSTATUS
  132942. +gcoHAL_GetTimerTime(
  132943. + IN gcoHAL Hal,
  132944. + IN gctUINT32 Timer,
  132945. + OUT gctINT32_PTR TimeDelta
  132946. + );
  132947. +
  132948. +/* set timeout value. */
  132949. +gceSTATUS
  132950. +gcoHAL_SetTimeOut(
  132951. + IN gcoHAL Hal,
  132952. + IN gctUINT32 timeOut
  132953. + );
  132954. +
  132955. +gceSTATUS
  132956. +gcoHAL_SetHardwareType(
  132957. + IN gcoHAL Hal,
  132958. + IN gceHARDWARE_TYPE HardwardType
  132959. + );
  132960. +
  132961. +gceSTATUS
  132962. +gcoHAL_GetHardwareType(
  132963. + IN gcoHAL Hal,
  132964. + OUT gceHARDWARE_TYPE * HardwardType
  132965. + );
  132966. +
  132967. +gceSTATUS
  132968. +gcoHAL_QueryChipCount(
  132969. + IN gcoHAL Hal,
  132970. + OUT gctINT32 * Count
  132971. + );
  132972. +
  132973. +gceSTATUS
  132974. +gcoHAL_QuerySeparated3D2D(
  132975. + IN gcoHAL Hal
  132976. + );
  132977. +
  132978. +gceSTATUS
  132979. +gcoHAL_QuerySpecialHint(
  132980. + IN gceSPECIAL_HINT Hint
  132981. + );
  132982. +
  132983. +gceSTATUS
  132984. +gcoHAL_SetSpecialHintData(
  132985. + IN gcoHARDWARE Hardware
  132986. + );
  132987. +
  132988. +/* Get pointer to gcoVG object. */
  132989. +gceSTATUS
  132990. +gcoHAL_GetVGEngine(
  132991. + IN gcoHAL Hal,
  132992. + OUT gcoVG * Engine
  132993. + );
  132994. +
  132995. +#if gcdENABLE_VG
  132996. +gceSTATUS
  132997. +gcoHAL_QueryChipLimits(
  132998. + IN gcoHAL Hal,
  132999. + IN gctINT32 Chip,
  133000. + OUT gcsHAL_LIMITS *Limits);
  133001. +
  133002. +gceSTATUS
  133003. +gcoHAL_QueryChipFeature(
  133004. + IN gcoHAL Hal,
  133005. + IN gctINT32 Chip,
  133006. + IN gceFEATURE Feature);
  133007. +
  133008. +#endif
  133009. +/******************************************************************************\
  133010. +********************************** gcoOS Object *********************************
  133011. +\******************************************************************************/
  133012. +
  133013. +/* Get PLS value for given key */
  133014. +gctPOINTER
  133015. +gcoOS_GetPLSValue(
  133016. + IN gcePLS_VALUE key
  133017. + );
  133018. +
  133019. +/* Set PLS value of a given key */
  133020. +void
  133021. +gcoOS_SetPLSValue(
  133022. + IN gcePLS_VALUE key,
  133023. + OUT gctPOINTER value
  133024. + );
  133025. +
  133026. +/* Get access to the thread local storage. */
  133027. +gceSTATUS
  133028. +gcoOS_GetTLS(
  133029. + OUT gcsTLS_PTR * TLS
  133030. + );
  133031. +
  133032. + /* Copy the TLS from a source thread. */
  133033. + gceSTATUS gcoOS_CopyTLS(IN gcsTLS_PTR Source);
  133034. +
  133035. +/* Destroy the objects associated with the current thread. */
  133036. +void
  133037. +gcoOS_FreeThreadData(
  133038. + IN gctBOOL ProcessExiting
  133039. + );
  133040. +
  133041. +/* Construct a new gcoOS object. */
  133042. +gceSTATUS
  133043. +gcoOS_Construct(
  133044. + IN gctPOINTER Context,
  133045. + OUT gcoOS * Os
  133046. + );
  133047. +
  133048. +/* Destroy an gcoOS object. */
  133049. +gceSTATUS
  133050. +gcoOS_Destroy(
  133051. + IN gcoOS Os
  133052. + );
  133053. +
  133054. +/* Get the base address for the physical memory. */
  133055. +gceSTATUS
  133056. +gcoOS_GetBaseAddress(
  133057. + IN gcoOS Os,
  133058. + OUT gctUINT32_PTR BaseAddress
  133059. + );
  133060. +
  133061. +/* Allocate memory from the heap. */
  133062. +gceSTATUS
  133063. +gcoOS_Allocate(
  133064. + IN gcoOS Os,
  133065. + IN gctSIZE_T Bytes,
  133066. + OUT gctPOINTER * Memory
  133067. + );
  133068. +
  133069. +/* Get allocated memory size. */
  133070. +gceSTATUS
  133071. +gcoOS_GetMemorySize(
  133072. + IN gcoOS Os,
  133073. + IN gctPOINTER Memory,
  133074. + OUT gctSIZE_T_PTR MemorySize
  133075. + );
  133076. +
  133077. +/* Free allocated memory. */
  133078. +gceSTATUS
  133079. +gcoOS_Free(
  133080. + IN gcoOS Os,
  133081. + IN gctPOINTER Memory
  133082. + );
  133083. +
  133084. +/* Allocate memory. */
  133085. +gceSTATUS
  133086. +gcoOS_AllocateMemory(
  133087. + IN gcoOS Os,
  133088. + IN gctSIZE_T Bytes,
  133089. + OUT gctPOINTER * Memory
  133090. + );
  133091. +
  133092. +/* Free memory. */
  133093. +gceSTATUS
  133094. +gcoOS_FreeMemory(
  133095. + IN gcoOS Os,
  133096. + IN gctPOINTER Memory
  133097. + );
  133098. +
  133099. +/* Allocate contiguous memory. */
  133100. +gceSTATUS
  133101. +gcoOS_AllocateContiguous(
  133102. + IN gcoOS Os,
  133103. + IN gctBOOL InUserSpace,
  133104. + IN OUT gctSIZE_T * Bytes,
  133105. + OUT gctPHYS_ADDR * Physical,
  133106. + OUT gctPOINTER * Logical
  133107. + );
  133108. +
  133109. +/* Free contiguous memory. */
  133110. +gceSTATUS
  133111. +gcoOS_FreeContiguous(
  133112. + IN gcoOS Os,
  133113. + IN gctPHYS_ADDR Physical,
  133114. + IN gctPOINTER Logical,
  133115. + IN gctSIZE_T Bytes
  133116. + );
  133117. +
  133118. +/* Allocate video memory. */
  133119. +gceSTATUS
  133120. +gcoOS_AllocateVideoMemory(
  133121. + IN gcoOS Os,
  133122. + IN gctBOOL InUserSpace,
  133123. + IN gctBOOL InCacheable,
  133124. + IN OUT gctSIZE_T * Bytes,
  133125. + OUT gctUINT32 * Physical,
  133126. + OUT gctPOINTER * Logical,
  133127. + OUT gctPOINTER * Handle
  133128. + );
  133129. +
  133130. +/* Free video memory. */
  133131. +gceSTATUS
  133132. +gcoOS_FreeVideoMemory(
  133133. + IN gcoOS Os,
  133134. + IN gctPOINTER Handle
  133135. + );
  133136. +
  133137. +gceSTATUS
  133138. +gcoSURF_GetBankOffsetBytes(
  133139. + IN gcoSURF Surfce,
  133140. + IN gceSURF_TYPE Type,
  133141. + IN gctUINT32 Stride,
  133142. + IN gctUINT32_PTR Bytes
  133143. + );
  133144. +
  133145. +/* Map user memory. */
  133146. +gceSTATUS
  133147. +gcoOS_MapUserMemory(
  133148. + IN gcoOS Os,
  133149. + IN gctPOINTER Memory,
  133150. + IN gctSIZE_T Size,
  133151. + OUT gctPOINTER * Info,
  133152. + OUT gctUINT32_PTR Address
  133153. + );
  133154. +
  133155. +/* Map user memory. */
  133156. +gceSTATUS
  133157. +gcoOS_MapUserMemoryEx(
  133158. + IN gcoOS Os,
  133159. + IN gctPOINTER Memory,
  133160. + IN gctUINT32 Physical,
  133161. + IN gctSIZE_T Size,
  133162. + OUT gctPOINTER * Info,
  133163. + OUT gctUINT32_PTR Address
  133164. + );
  133165. +
  133166. +/* Unmap user memory. */
  133167. +gceSTATUS
  133168. +gcoOS_UnmapUserMemory(
  133169. + IN gcoOS Os,
  133170. + IN gctPOINTER Memory,
  133171. + IN gctSIZE_T Size,
  133172. + IN gctPOINTER Info,
  133173. + IN gctUINT32 Address
  133174. + );
  133175. +
  133176. +/* Device I/O Control call to the kernel HAL layer. */
  133177. +gceSTATUS
  133178. +gcoOS_DeviceControl(
  133179. + IN gcoOS Os,
  133180. + IN gctUINT32 IoControlCode,
  133181. + IN gctPOINTER InputBuffer,
  133182. + IN gctSIZE_T InputBufferSize,
  133183. + IN gctPOINTER OutputBuffer,
  133184. + IN gctSIZE_T OutputBufferSize
  133185. + );
  133186. +
  133187. +/* Allocate non paged memory. */
  133188. +gceSTATUS
  133189. +gcoOS_AllocateNonPagedMemory(
  133190. + IN gcoOS Os,
  133191. + IN gctBOOL InUserSpace,
  133192. + IN OUT gctSIZE_T * Bytes,
  133193. + OUT gctPHYS_ADDR * Physical,
  133194. + OUT gctPOINTER * Logical
  133195. + );
  133196. +
  133197. +/* Free non paged memory. */
  133198. +gceSTATUS
  133199. +gcoOS_FreeNonPagedMemory(
  133200. + IN gcoOS Os,
  133201. + IN gctSIZE_T Bytes,
  133202. + IN gctPHYS_ADDR Physical,
  133203. + IN gctPOINTER Logical
  133204. + );
  133205. +
  133206. +#define gcmOS_SAFE_FREE(os, mem) \
  133207. + gcoOS_Free(os, mem); \
  133208. + mem = gcvNULL
  133209. +
  133210. +#define gcmkOS_SAFE_FREE(os, mem) \
  133211. + gckOS_Free(os, mem); \
  133212. + mem = gcvNULL
  133213. +
  133214. +typedef enum _gceFILE_MODE
  133215. +{
  133216. + gcvFILE_CREATE = 0,
  133217. + gcvFILE_APPEND,
  133218. + gcvFILE_READ,
  133219. + gcvFILE_CREATETEXT,
  133220. + gcvFILE_APPENDTEXT,
  133221. + gcvFILE_READTEXT,
  133222. +}
  133223. +gceFILE_MODE;
  133224. +
  133225. +/* Open a file. */
  133226. +gceSTATUS
  133227. +gcoOS_Open(
  133228. + IN gcoOS Os,
  133229. + IN gctCONST_STRING FileName,
  133230. + IN gceFILE_MODE Mode,
  133231. + OUT gctFILE * File
  133232. + );
  133233. +
  133234. +/* Close a file. */
  133235. +gceSTATUS
  133236. +gcoOS_Close(
  133237. + IN gcoOS Os,
  133238. + IN gctFILE File
  133239. + );
  133240. +
  133241. +/* Read data from a file. */
  133242. +gceSTATUS
  133243. +gcoOS_Read(
  133244. + IN gcoOS Os,
  133245. + IN gctFILE File,
  133246. + IN gctSIZE_T ByteCount,
  133247. + IN gctPOINTER Data,
  133248. + OUT gctSIZE_T * ByteRead
  133249. + );
  133250. +
  133251. +/* Write data to a file. */
  133252. +gceSTATUS
  133253. +gcoOS_Write(
  133254. + IN gcoOS Os,
  133255. + IN gctFILE File,
  133256. + IN gctSIZE_T ByteCount,
  133257. + IN gctCONST_POINTER Data
  133258. + );
  133259. +
  133260. +/* Flush data to a file. */
  133261. +gceSTATUS
  133262. +gcoOS_Flush(
  133263. + IN gcoOS Os,
  133264. + IN gctFILE File
  133265. + );
  133266. +
  133267. +/* Close a file descriptor. */
  133268. +gceSTATUS
  133269. +gcoOS_CloseFD(
  133270. + IN gcoOS Os,
  133271. + IN gctINT FD
  133272. + );
  133273. +
  133274. +/* Dup file descriptor to another. */
  133275. +gceSTATUS
  133276. +gcoOS_DupFD(
  133277. + IN gcoOS Os,
  133278. + IN gctINT FD,
  133279. + OUT gctINT * FD2
  133280. + );
  133281. +
  133282. +/* Create an endpoint for communication. */
  133283. +gceSTATUS
  133284. +gcoOS_Socket(
  133285. + IN gcoOS Os,
  133286. + IN gctINT Domain,
  133287. + IN gctINT Type,
  133288. + IN gctINT Protocol,
  133289. + OUT gctINT *SockFd
  133290. + );
  133291. +
  133292. +/* Close a socket. */
  133293. +gceSTATUS
  133294. +gcoOS_CloseSocket(
  133295. + IN gcoOS Os,
  133296. + IN gctINT SockFd
  133297. + );
  133298. +
  133299. +/* Initiate a connection on a socket. */
  133300. +gceSTATUS
  133301. +gcoOS_Connect(
  133302. + IN gcoOS Os,
  133303. + IN gctINT SockFd,
  133304. + IN gctCONST_POINTER HostName,
  133305. + IN gctUINT Port);
  133306. +
  133307. +/* Shut down part of connection on a socket. */
  133308. +gceSTATUS
  133309. +gcoOS_Shutdown(
  133310. + IN gcoOS Os,
  133311. + IN gctINT SockFd,
  133312. + IN gctINT How
  133313. + );
  133314. +
  133315. +/* Send a message on a socket. */
  133316. +gceSTATUS
  133317. +gcoOS_Send(
  133318. + IN gcoOS Os,
  133319. + IN gctINT SockFd,
  133320. + IN gctSIZE_T ByteCount,
  133321. + IN gctCONST_POINTER Data,
  133322. + IN gctINT Flags
  133323. + );
  133324. +
  133325. +/* Initiate a connection on a socket. */
  133326. +gceSTATUS
  133327. +gcoOS_WaitForSend(
  133328. + IN gcoOS Os,
  133329. + IN gctINT SockFd,
  133330. + IN gctINT Seconds,
  133331. + IN gctINT MicroSeconds);
  133332. +
  133333. +/* Get environment variable value. */
  133334. +gceSTATUS
  133335. +gcoOS_GetEnv(
  133336. + IN gcoOS Os,
  133337. + IN gctCONST_STRING VarName,
  133338. + OUT gctSTRING * Value
  133339. + );
  133340. +
  133341. +/* Set environment variable value. */
  133342. +gceSTATUS
  133343. +gcoOS_SetEnv(
  133344. + IN gcoOS Os,
  133345. + IN gctCONST_STRING VarName,
  133346. + IN gctSTRING Value
  133347. + );
  133348. +
  133349. +/* Get current working directory. */
  133350. +gceSTATUS
  133351. +gcoOS_GetCwd(
  133352. + IN gcoOS Os,
  133353. + IN gctINT SizeInBytes,
  133354. + OUT gctSTRING Buffer
  133355. + );
  133356. +
  133357. +/* Get file status info. */
  133358. +gceSTATUS
  133359. +gcoOS_Stat(
  133360. + IN gcoOS Os,
  133361. + IN gctCONST_STRING FileName,
  133362. + OUT gctPOINTER Buffer
  133363. + );
  133364. +
  133365. +typedef enum _gceFILE_WHENCE
  133366. +{
  133367. + gcvFILE_SEEK_SET,
  133368. + gcvFILE_SEEK_CUR,
  133369. + gcvFILE_SEEK_END
  133370. +}
  133371. +gceFILE_WHENCE;
  133372. +
  133373. +/* Set the current position of a file. */
  133374. +gceSTATUS
  133375. +gcoOS_Seek(
  133376. + IN gcoOS Os,
  133377. + IN gctFILE File,
  133378. + IN gctUINT32 Offset,
  133379. + IN gceFILE_WHENCE Whence
  133380. + );
  133381. +
  133382. +/* Set the current position of a file. */
  133383. +gceSTATUS
  133384. +gcoOS_SetPos(
  133385. + IN gcoOS Os,
  133386. + IN gctFILE File,
  133387. + IN gctUINT32 Position
  133388. + );
  133389. +
  133390. +/* Get the current position of a file. */
  133391. +gceSTATUS
  133392. +gcoOS_GetPos(
  133393. + IN gcoOS Os,
  133394. + IN gctFILE File,
  133395. + OUT gctUINT32 * Position
  133396. + );
  133397. +
  133398. +/* Same as strstr. */
  133399. +gceSTATUS
  133400. +gcoOS_StrStr(
  133401. + IN gctCONST_STRING String,
  133402. + IN gctCONST_STRING SubString,
  133403. + OUT gctSTRING * Output
  133404. + );
  133405. +
  133406. +/* Find the last occurance of a character inside a string. */
  133407. +gceSTATUS
  133408. +gcoOS_StrFindReverse(
  133409. + IN gctCONST_STRING String,
  133410. + IN gctINT8 Character,
  133411. + OUT gctSTRING * Output
  133412. + );
  133413. +
  133414. +gceSTATUS
  133415. +gcoOS_StrDup(
  133416. + IN gcoOS Os,
  133417. + IN gctCONST_STRING String,
  133418. + OUT gctSTRING * Target
  133419. + );
  133420. +
  133421. +/* Copy a string. */
  133422. +gceSTATUS
  133423. +gcoOS_StrCopySafe(
  133424. + IN gctSTRING Destination,
  133425. + IN gctSIZE_T DestinationSize,
  133426. + IN gctCONST_STRING Source
  133427. + );
  133428. +
  133429. +/* Append a string. */
  133430. +gceSTATUS
  133431. +gcoOS_StrCatSafe(
  133432. + IN gctSTRING Destination,
  133433. + IN gctSIZE_T DestinationSize,
  133434. + IN gctCONST_STRING Source
  133435. + );
  133436. +
  133437. +/* Compare two strings. */
  133438. +gceSTATUS
  133439. +gcoOS_StrCmp(
  133440. + IN gctCONST_STRING String1,
  133441. + IN gctCONST_STRING String2
  133442. + );
  133443. +
  133444. +/* Compare characters of two strings. */
  133445. +gceSTATUS
  133446. +gcoOS_StrNCmp(
  133447. + IN gctCONST_STRING String1,
  133448. + IN gctCONST_STRING String2,
  133449. + IN gctSIZE_T Count
  133450. + );
  133451. +
  133452. +/* Convert string to float. */
  133453. +gceSTATUS
  133454. +gcoOS_StrToFloat(
  133455. + IN gctCONST_STRING String,
  133456. + OUT gctFLOAT * Float
  133457. + );
  133458. +
  133459. +/* Convert hex string to integer. */
  133460. +gceSTATUS
  133461. +gcoOS_HexStrToInt(
  133462. + IN gctCONST_STRING String,
  133463. + OUT gctINT * Int
  133464. + );
  133465. +
  133466. +/* Convert hex string to float. */
  133467. +gceSTATUS
  133468. +gcoOS_HexStrToFloat(
  133469. + IN gctCONST_STRING String,
  133470. + OUT gctFLOAT * Float
  133471. + );
  133472. +
  133473. +/* Convert string to integer. */
  133474. +gceSTATUS
  133475. +gcoOS_StrToInt(
  133476. + IN gctCONST_STRING String,
  133477. + OUT gctINT * Int
  133478. + );
  133479. +
  133480. +gceSTATUS
  133481. +gcoOS_MemCmp(
  133482. + IN gctCONST_POINTER Memory1,
  133483. + IN gctCONST_POINTER Memory2,
  133484. + IN gctSIZE_T Bytes
  133485. + );
  133486. +
  133487. +gceSTATUS
  133488. +gcoOS_PrintStrSafe(
  133489. + OUT gctSTRING String,
  133490. + IN gctSIZE_T StringSize,
  133491. + IN OUT gctUINT * Offset,
  133492. + IN gctCONST_STRING Format,
  133493. + ...
  133494. + );
  133495. +
  133496. +gceSTATUS
  133497. +gcoOS_LoadLibrary(
  133498. + IN gcoOS Os,
  133499. + IN gctCONST_STRING Library,
  133500. + OUT gctHANDLE * Handle
  133501. + );
  133502. +
  133503. +gceSTATUS
  133504. +gcoOS_FreeLibrary(
  133505. + IN gcoOS Os,
  133506. + IN gctHANDLE Handle
  133507. + );
  133508. +
  133509. +gceSTATUS
  133510. +gcoOS_GetProcAddress(
  133511. + IN gcoOS Os,
  133512. + IN gctHANDLE Handle,
  133513. + IN gctCONST_STRING Name,
  133514. + OUT gctPOINTER * Function
  133515. + );
  133516. +
  133517. +gceSTATUS
  133518. +gcoOS_Compact(
  133519. + IN gcoOS Os
  133520. + );
  133521. +
  133522. +gceSTATUS
  133523. +gcoOS_AddSignalHandler (
  133524. + IN gceSignalHandlerType SignalHandlerType
  133525. + );
  133526. +
  133527. +#if VIVANTE_PROFILER
  133528. +gceSTATUS
  133529. +gcoOS_ProfileStart(
  133530. + IN gcoOS Os
  133531. + );
  133532. +
  133533. +gceSTATUS
  133534. +gcoOS_ProfileEnd(
  133535. + IN gcoOS Os,
  133536. + IN gctCONST_STRING Title
  133537. + );
  133538. +
  133539. +gceSTATUS
  133540. +gcoOS_SetProfileSetting(
  133541. + IN gcoOS Os,
  133542. + IN gctBOOL Enable,
  133543. + IN gctCONST_STRING FileName
  133544. + );
  133545. +#endif
  133546. +
  133547. +gctBOOL
  133548. +gcoOS_IsNeededSupportNP2Texture(
  133549. + IN gctCHAR* ProcName
  133550. + );
  133551. +
  133552. +/* Query the video memory. */
  133553. +gceSTATUS
  133554. +gcoOS_QueryVideoMemory(
  133555. + IN gcoOS Os,
  133556. + OUT gctPHYS_ADDR * InternalAddress,
  133557. + OUT gctSIZE_T * InternalSize,
  133558. + OUT gctPHYS_ADDR * ExternalAddress,
  133559. + OUT gctSIZE_T * ExternalSize,
  133560. + OUT gctPHYS_ADDR * ContiguousAddress,
  133561. + OUT gctSIZE_T * ContiguousSize
  133562. + );
  133563. +
  133564. +/* Detect if the process is the executable specified. */
  133565. +gceSTATUS
  133566. +gcoOS_DetectProcessByNamePid(
  133567. + IN gctCONST_STRING Name,
  133568. + IN gctHANDLE Pid
  133569. + );
  133570. +
  133571. +/* Detect if the current process is the executable specified. */
  133572. +gceSTATUS
  133573. +gcoOS_DetectProcessByName(
  133574. + IN gctCONST_STRING Name
  133575. + );
  133576. +
  133577. +gceSTATUS
  133578. +gcoOS_DetectProcessByEncryptedName(
  133579. + IN gctCONST_STRING Name
  133580. + );
  133581. +
  133582. +#if defined(ANDROID)
  133583. +gceSTATUS
  133584. +gcoOS_DetectProgrameByEncryptedSymbols(
  133585. + IN gcoOS_SymbolsList Symbols
  133586. + );
  133587. +#endif
  133588. +
  133589. +/*----------------------------------------------------------------------------*/
  133590. +/*----- Atoms ----------------------------------------------------------------*/
  133591. +
  133592. +/* Construct an atom. */
  133593. +gceSTATUS
  133594. +gcoOS_AtomConstruct(
  133595. + IN gcoOS Os,
  133596. + OUT gcsATOM_PTR * Atom
  133597. + );
  133598. +
  133599. +/* Destroy an atom. */
  133600. +gceSTATUS
  133601. +gcoOS_AtomDestroy(
  133602. + IN gcoOS Os,
  133603. + IN gcsATOM_PTR Atom
  133604. + );
  133605. +
  133606. +/* Increment an atom. */
  133607. +gceSTATUS
  133608. +gcoOS_AtomIncrement(
  133609. + IN gcoOS Os,
  133610. + IN gcsATOM_PTR Atom,
  133611. + OUT gctINT32_PTR OldValue
  133612. + );
  133613. +
  133614. +/* Decrement an atom. */
  133615. +gceSTATUS
  133616. +gcoOS_AtomDecrement(
  133617. + IN gcoOS Os,
  133618. + IN gcsATOM_PTR Atom,
  133619. + OUT gctINT32_PTR OldValue
  133620. + );
  133621. +
  133622. +gctHANDLE
  133623. +gcoOS_GetCurrentProcessID(
  133624. + void
  133625. + );
  133626. +
  133627. +gctHANDLE
  133628. +gcoOS_GetCurrentThreadID(
  133629. + void
  133630. + );
  133631. +
  133632. +/*----------------------------------------------------------------------------*/
  133633. +/*----- Time -----------------------------------------------------------------*/
  133634. +
  133635. +/* Get the number of milliseconds since the system started. */
  133636. +gctUINT32
  133637. +gcoOS_GetTicks(
  133638. + void
  133639. + );
  133640. +
  133641. +/* Get time in microseconds. */
  133642. +gceSTATUS
  133643. +gcoOS_GetTime(
  133644. + gctUINT64_PTR Time
  133645. + );
  133646. +
  133647. +/* Get CPU usage in microseconds. */
  133648. +gceSTATUS
  133649. +gcoOS_GetCPUTime(
  133650. + gctUINT64_PTR CPUTime
  133651. + );
  133652. +
  133653. +/* Get memory usage. */
  133654. +gceSTATUS
  133655. +gcoOS_GetMemoryUsage(
  133656. + gctUINT32_PTR MaxRSS,
  133657. + gctUINT32_PTR IxRSS,
  133658. + gctUINT32_PTR IdRSS,
  133659. + gctUINT32_PTR IsRSS
  133660. + );
  133661. +
  133662. +/* Delay a number of microseconds. */
  133663. +gceSTATUS
  133664. +gcoOS_Delay(
  133665. + IN gcoOS Os,
  133666. + IN gctUINT32 Delay
  133667. + );
  133668. +
  133669. +/*----------------------------------------------------------------------------*/
  133670. +/*----- Threads --------------------------------------------------------------*/
  133671. +
  133672. +#ifdef _WIN32
  133673. +/* Cannot include windows.h here becuase "near" and "far"
  133674. + * which are used in gcsDEPTH_INFO, are defined to nothing in WinDef.h.
  133675. + * So, use the real value of DWORD and WINAPI, instead.
  133676. + * DWORD is unsigned long, and WINAPI is __stdcall.
  133677. + * If these two are change in WinDef.h, the following two typdefs
  133678. + * need to be changed, too.
  133679. + */
  133680. +typedef unsigned long gctTHREAD_RETURN;
  133681. +typedef unsigned long (__stdcall * gcTHREAD_ROUTINE)(void * Argument);
  133682. +#else
  133683. +typedef void * gctTHREAD_RETURN;
  133684. +typedef void * (* gcTHREAD_ROUTINE)(void *);
  133685. +#endif
  133686. +
  133687. +/* Create a new thread. */
  133688. +gceSTATUS
  133689. +gcoOS_CreateThread(
  133690. + IN gcoOS Os,
  133691. + IN gcTHREAD_ROUTINE Worker,
  133692. + IN gctPOINTER Argument,
  133693. + OUT gctPOINTER * Thread
  133694. + );
  133695. +
  133696. +/* Close a thread. */
  133697. +gceSTATUS
  133698. +gcoOS_CloseThread(
  133699. + IN gcoOS Os,
  133700. + IN gctPOINTER Thread
  133701. + );
  133702. +
  133703. +/*----------------------------------------------------------------------------*/
  133704. +/*----- Mutexes --------------------------------------------------------------*/
  133705. +
  133706. +/* Create a new mutex. */
  133707. +gceSTATUS
  133708. +gcoOS_CreateMutex(
  133709. + IN gcoOS Os,
  133710. + OUT gctPOINTER * Mutex
  133711. + );
  133712. +
  133713. +/* Delete a mutex. */
  133714. +gceSTATUS
  133715. +gcoOS_DeleteMutex(
  133716. + IN gcoOS Os,
  133717. + IN gctPOINTER Mutex
  133718. + );
  133719. +
  133720. +/* Acquire a mutex. */
  133721. +gceSTATUS
  133722. +gcoOS_AcquireMutex(
  133723. + IN gcoOS Os,
  133724. + IN gctPOINTER Mutex,
  133725. + IN gctUINT32 Timeout
  133726. + );
  133727. +
  133728. +/* Release a mutex. */
  133729. +gceSTATUS
  133730. +gcoOS_ReleaseMutex(
  133731. + IN gcoOS Os,
  133732. + IN gctPOINTER Mutex
  133733. + );
  133734. +
  133735. +/*----------------------------------------------------------------------------*/
  133736. +/*----- Signals --------------------------------------------------------------*/
  133737. +
  133738. +/* Create a signal. */
  133739. +gceSTATUS
  133740. +gcoOS_CreateSignal(
  133741. + IN gcoOS Os,
  133742. + IN gctBOOL ManualReset,
  133743. + OUT gctSIGNAL * Signal
  133744. + );
  133745. +
  133746. +/* Destroy a signal. */
  133747. +gceSTATUS
  133748. +gcoOS_DestroySignal(
  133749. + IN gcoOS Os,
  133750. + IN gctSIGNAL Signal
  133751. + );
  133752. +
  133753. +/* Signal a signal. */
  133754. +gceSTATUS
  133755. +gcoOS_Signal(
  133756. + IN gcoOS Os,
  133757. + IN gctSIGNAL Signal,
  133758. + IN gctBOOL State
  133759. + );
  133760. +
  133761. +/* Wait for a signal. */
  133762. +gceSTATUS
  133763. +gcoOS_WaitSignal(
  133764. + IN gcoOS Os,
  133765. + IN gctSIGNAL Signal,
  133766. + IN gctUINT32 Wait
  133767. + );
  133768. +
  133769. +/* Map a signal from another process */
  133770. +gceSTATUS
  133771. +gcoOS_MapSignal(
  133772. + IN gctSIGNAL RemoteSignal,
  133773. + OUT gctSIGNAL * LocalSignal
  133774. + );
  133775. +
  133776. +/* Unmap a signal mapped from another process */
  133777. +gceSTATUS
  133778. +gcoOS_UnmapSignal(
  133779. + IN gctSIGNAL Signal
  133780. + );
  133781. +
  133782. +/*----------------------------------------------------------------------------*/
  133783. +/*----- Android Native Fence -------------------------------------------------*/
  133784. +
  133785. +/* Create sync point. */
  133786. +gceSTATUS
  133787. +gcoOS_CreateSyncPoint(
  133788. + IN gcoOS Os,
  133789. + OUT gctSYNC_POINT * SyncPoint
  133790. + );
  133791. +
  133792. +/* Destroy sync point. */
  133793. +gceSTATUS
  133794. +gcoOS_DestroySyncPoint(
  133795. + IN gcoOS Os,
  133796. + IN gctSYNC_POINT SyncPoint
  133797. + );
  133798. +
  133799. +/* Create native fence. */
  133800. +gceSTATUS
  133801. +gcoOS_CreateNativeFence(
  133802. + IN gcoOS Os,
  133803. + IN gctSYNC_POINT SyncPoint,
  133804. + OUT gctINT * FenceFD
  133805. + );
  133806. +
  133807. +/* Wait on native fence. */
  133808. +gceSTATUS
  133809. +gcoOS_WaitNativeFence(
  133810. + IN gcoOS Os,
  133811. + IN gctINT FenceFD,
  133812. + IN gctUINT32 Timeout
  133813. + );
  133814. +
  133815. +/*----------------------------------------------------------------------------*/
  133816. +/*----- Memory Access and Cache ----------------------------------------------*/
  133817. +
  133818. +/* Write a register. */
  133819. +gceSTATUS
  133820. +gcoOS_WriteRegister(
  133821. + IN gcoOS Os,
  133822. + IN gctUINT32 Address,
  133823. + IN gctUINT32 Data
  133824. + );
  133825. +
  133826. +/* Read a register. */
  133827. +gceSTATUS
  133828. +gcoOS_ReadRegister(
  133829. + IN gcoOS Os,
  133830. + IN gctUINT32 Address,
  133831. + OUT gctUINT32 * Data
  133832. + );
  133833. +
  133834. +gceSTATUS
  133835. +gcoOS_CacheClean(
  133836. + IN gcoOS Os,
  133837. + IN gctUINT64 Node,
  133838. + IN gctPOINTER Logical,
  133839. + IN gctSIZE_T Bytes
  133840. + );
  133841. +
  133842. +gceSTATUS
  133843. +gcoOS_CacheFlush(
  133844. + IN gcoOS Os,
  133845. + IN gctUINT64 Node,
  133846. + IN gctPOINTER Logical,
  133847. + IN gctSIZE_T Bytes
  133848. + );
  133849. +
  133850. +gceSTATUS
  133851. +gcoOS_CacheInvalidate(
  133852. + IN gcoOS Os,
  133853. + IN gctUINT64 Node,
  133854. + IN gctPOINTER Logical,
  133855. + IN gctSIZE_T Bytes
  133856. + );
  133857. +
  133858. +gceSTATUS
  133859. +gcoOS_MemoryBarrier(
  133860. + IN gcoOS Os,
  133861. + IN gctPOINTER Logical
  133862. + );
  133863. +
  133864. +
  133865. +/*----------------------------------------------------------------------------*/
  133866. +/*----- Profile --------------------------------------------------------------*/
  133867. +
  133868. +gceSTATUS
  133869. +gckOS_GetProfileTick(
  133870. + OUT gctUINT64_PTR Tick
  133871. + );
  133872. +
  133873. +gceSTATUS
  133874. +gckOS_QueryProfileTickRate(
  133875. + OUT gctUINT64_PTR TickRate
  133876. + );
  133877. +
  133878. +gctUINT32
  133879. +gckOS_ProfileToMS(
  133880. + IN gctUINT64 Ticks
  133881. + );
  133882. +
  133883. +gceSTATUS
  133884. +gcoOS_GetProfileTick(
  133885. + OUT gctUINT64_PTR Tick
  133886. + );
  133887. +
  133888. +gceSTATUS
  133889. +gcoOS_QueryProfileTickRate(
  133890. + OUT gctUINT64_PTR TickRate
  133891. + );
  133892. +
  133893. +#define _gcmPROFILE_INIT(prefix, freq, start) \
  133894. + do { \
  133895. + prefix ## OS_QueryProfileTickRate(&(freq)); \
  133896. + prefix ## OS_GetProfileTick(&(start)); \
  133897. + } while (gcvFALSE)
  133898. +
  133899. +#define _gcmPROFILE_QUERY(prefix, start, ticks) \
  133900. + do { \
  133901. + prefix ## OS_GetProfileTick(&(ticks)); \
  133902. + (ticks) = ((ticks) > (start)) ? ((ticks) - (start)) \
  133903. + : (~0ull - (start) + (ticks) + 1); \
  133904. + } while (gcvFALSE)
  133905. +
  133906. +#if gcdENABLE_PROFILING
  133907. +# define gcmkPROFILE_INIT(freq, start) _gcmPROFILE_INIT(gck, freq, start)
  133908. +# define gcmkPROFILE_QUERY(start, ticks) _gcmPROFILE_QUERY(gck, start, ticks)
  133909. +# define gcmPROFILE_INIT(freq, start) _gcmPROFILE_INIT(gco, freq, start)
  133910. +# define gcmPROFILE_QUERY(start, ticks) _gcmPROFILE_QUERY(gco, start, ticks)
  133911. +# define gcmPROFILE_ONLY(x) x
  133912. +# define gcmPROFILE_ELSE(x) do { } while (gcvFALSE)
  133913. +# define gcmPROFILE_DECLARE_ONLY(x) x
  133914. +# define gcmPROFILE_DECLARE_ELSE(x) typedef x
  133915. +#else
  133916. +# define gcmkPROFILE_INIT(start, freq) do { } while (gcvFALSE)
  133917. +# define gcmkPROFILE_QUERY(start, ticks) do { } while (gcvFALSE)
  133918. +# define gcmPROFILE_INIT(start, freq) do { } while (gcvFALSE)
  133919. +# define gcmPROFILE_QUERY(start, ticks) do { } while (gcvFALSE)
  133920. +# define gcmPROFILE_ONLY(x) do { } while (gcvFALSE)
  133921. +# define gcmPROFILE_ELSE(x) x
  133922. +# define gcmPROFILE_DECLARE_ONLY(x) do { } while (gcvFALSE)
  133923. +# define gcmPROFILE_DECLARE_ELSE(x) x
  133924. +#endif
  133925. +
  133926. +/*******************************************************************************
  133927. +** gcoMATH object
  133928. +*/
  133929. +
  133930. +#define gcdPI 3.14159265358979323846f
  133931. +
  133932. +/* Kernel. */
  133933. +gctINT
  133934. +gckMATH_ModuloInt(
  133935. + IN gctINT X,
  133936. + IN gctINT Y
  133937. + );
  133938. +
  133939. +/* User. */
  133940. +gctUINT32
  133941. +gcoMATH_Log2in5dot5(
  133942. + IN gctINT X
  133943. + );
  133944. +
  133945. +
  133946. +gctFLOAT
  133947. +gcoMATH_UIntAsFloat(
  133948. + IN gctUINT32 X
  133949. + );
  133950. +
  133951. +gctUINT32
  133952. +gcoMATH_FloatAsUInt(
  133953. + IN gctFLOAT X
  133954. + );
  133955. +
  133956. +gctBOOL
  133957. +gcoMATH_CompareEqualF(
  133958. + IN gctFLOAT X,
  133959. + IN gctFLOAT Y
  133960. + );
  133961. +
  133962. +gctUINT16
  133963. +gcoMATH_UInt8AsFloat16(
  133964. + IN gctUINT8 X
  133965. + );
  133966. +
  133967. +/******************************************************************************\
  133968. +**************************** Coordinate Structures *****************************
  133969. +\******************************************************************************/
  133970. +
  133971. +typedef struct _gcsPOINT
  133972. +{
  133973. + gctINT32 x;
  133974. + gctINT32 y;
  133975. +}
  133976. +gcsPOINT;
  133977. +
  133978. +typedef struct _gcsSIZE
  133979. +{
  133980. + gctINT32 width;
  133981. + gctINT32 height;
  133982. +}
  133983. +gcsSIZE;
  133984. +
  133985. +typedef struct _gcsRECT
  133986. +{
  133987. + gctINT32 left;
  133988. + gctINT32 top;
  133989. + gctINT32 right;
  133990. + gctINT32 bottom;
  133991. +}
  133992. +gcsRECT;
  133993. +
  133994. +typedef union _gcsPIXEL
  133995. +{
  133996. + struct
  133997. + {
  133998. + gctFLOAT r, g, b, a;
  133999. + gctFLOAT d, s;
  134000. + } pf;
  134001. +
  134002. + struct
  134003. + {
  134004. + gctINT32 r, g, b, a;
  134005. + gctINT32 d, s;
  134006. + } pi;
  134007. +
  134008. + struct
  134009. + {
  134010. + gctUINT32 r, g, b, a;
  134011. + gctUINT32 d, s;
  134012. + } pui;
  134013. +
  134014. +} gcsPIXEL;
  134015. +
  134016. +
  134017. +/******************************************************************************\
  134018. +********************************* gcoSURF Object ********************************
  134019. +\******************************************************************************/
  134020. +
  134021. +/*----------------------------------------------------------------------------*/
  134022. +/*------------------------------- gcoSURF Common ------------------------------*/
  134023. +
  134024. +/* Color format classes. */
  134025. +typedef enum _gceFORMAT_CLASS
  134026. +{
  134027. + gcvFORMAT_CLASS_RGBA = 4500,
  134028. + gcvFORMAT_CLASS_YUV,
  134029. + gcvFORMAT_CLASS_INDEX,
  134030. + gcvFORMAT_CLASS_LUMINANCE,
  134031. + gcvFORMAT_CLASS_BUMP,
  134032. + gcvFORMAT_CLASS_DEPTH,
  134033. +}
  134034. +gceFORMAT_CLASS;
  134035. +
  134036. +/* Special enums for width field in gcsFORMAT_COMPONENT. */
  134037. +typedef enum _gceCOMPONENT_CONTROL
  134038. +{
  134039. + gcvCOMPONENT_NOTPRESENT = 0x00,
  134040. + gcvCOMPONENT_DONTCARE = 0x80,
  134041. + gcvCOMPONENT_WIDTHMASK = 0x7F,
  134042. + gcvCOMPONENT_ODD = 0x80
  134043. +}
  134044. +gceCOMPONENT_CONTROL;
  134045. +
  134046. +/* Color format component parameters. */
  134047. +typedef struct _gcsFORMAT_COMPONENT
  134048. +{
  134049. + gctUINT8 start;
  134050. + gctUINT8 width;
  134051. +}
  134052. +gcsFORMAT_COMPONENT;
  134053. +
  134054. +/* RGBA color format class. */
  134055. +typedef struct _gcsFORMAT_CLASS_TYPE_RGBA
  134056. +{
  134057. + gcsFORMAT_COMPONENT alpha;
  134058. + gcsFORMAT_COMPONENT red;
  134059. + gcsFORMAT_COMPONENT green;
  134060. + gcsFORMAT_COMPONENT blue;
  134061. +}
  134062. +gcsFORMAT_CLASS_TYPE_RGBA;
  134063. +
  134064. +/* YUV color format class. */
  134065. +typedef struct _gcsFORMAT_CLASS_TYPE_YUV
  134066. +{
  134067. + gcsFORMAT_COMPONENT y;
  134068. + gcsFORMAT_COMPONENT u;
  134069. + gcsFORMAT_COMPONENT v;
  134070. +}
  134071. +gcsFORMAT_CLASS_TYPE_YUV;
  134072. +
  134073. +/* Index color format class. */
  134074. +typedef struct _gcsFORMAT_CLASS_TYPE_INDEX
  134075. +{
  134076. + gcsFORMAT_COMPONENT value;
  134077. +}
  134078. +gcsFORMAT_CLASS_TYPE_INDEX;
  134079. +
  134080. +/* Luminance color format class. */
  134081. +typedef struct _gcsFORMAT_CLASS_TYPE_LUMINANCE
  134082. +{
  134083. + gcsFORMAT_COMPONENT alpha;
  134084. + gcsFORMAT_COMPONENT value;
  134085. +}
  134086. +gcsFORMAT_CLASS_TYPE_LUMINANCE;
  134087. +
  134088. +/* Bump map color format class. */
  134089. +typedef struct _gcsFORMAT_CLASS_TYPE_BUMP
  134090. +{
  134091. + gcsFORMAT_COMPONENT alpha;
  134092. + gcsFORMAT_COMPONENT l;
  134093. + gcsFORMAT_COMPONENT v;
  134094. + gcsFORMAT_COMPONENT u;
  134095. + gcsFORMAT_COMPONENT q;
  134096. + gcsFORMAT_COMPONENT w;
  134097. +}
  134098. +gcsFORMAT_CLASS_TYPE_BUMP;
  134099. +
  134100. +/* Depth and stencil format class. */
  134101. +typedef struct _gcsFORMAT_CLASS_TYPE_DEPTH
  134102. +{
  134103. + gcsFORMAT_COMPONENT depth;
  134104. + gcsFORMAT_COMPONENT stencil;
  134105. +}
  134106. +gcsFORMAT_CLASS_TYPE_DEPTH;
  134107. +
  134108. +/* Format parameters. */
  134109. +typedef struct _gcsSURF_FORMAT_INFO
  134110. +{
  134111. + /* Format code and class. */
  134112. + gceSURF_FORMAT format;
  134113. + gceFORMAT_CLASS fmtClass;
  134114. +
  134115. + /* The size of one pixel in bits. */
  134116. + gctUINT8 bitsPerPixel;
  134117. +
  134118. + /* Component swizzle. */
  134119. + gceSURF_SWIZZLE swizzle;
  134120. +
  134121. + /* Some formats have two neighbour pixels interleaved together. */
  134122. + /* To describe such format, set the flag to 1 and add another */
  134123. + /* like this one describing the odd pixel format. */
  134124. + gctUINT8 interleaved;
  134125. +
  134126. + /* Format components. */
  134127. + union
  134128. + {
  134129. + gcsFORMAT_CLASS_TYPE_BUMP bump;
  134130. + gcsFORMAT_CLASS_TYPE_RGBA rgba;
  134131. + gcsFORMAT_CLASS_TYPE_YUV yuv;
  134132. + gcsFORMAT_CLASS_TYPE_LUMINANCE lum;
  134133. + gcsFORMAT_CLASS_TYPE_INDEX index;
  134134. + gcsFORMAT_CLASS_TYPE_DEPTH depth;
  134135. + } u;
  134136. +}
  134137. +gcsSURF_FORMAT_INFO;
  134138. +
  134139. +/* Frame buffer information. */
  134140. +typedef struct _gcsSURF_FRAMEBUFFER
  134141. +{
  134142. + gctPOINTER logical;
  134143. + gctUINT width, height;
  134144. + gctINT stride;
  134145. + gceSURF_FORMAT format;
  134146. +}
  134147. +gcsSURF_FRAMEBUFFER;
  134148. +
  134149. +typedef struct _gcsVIDMEM_NODE_SHARED_INFO
  134150. +{
  134151. + gctBOOL tileStatusDisabled;
  134152. + gcsPOINT SrcOrigin;
  134153. + gcsPOINT DestOrigin;
  134154. + gcsSIZE RectSize;
  134155. + gctUINT32 clearValue;
  134156. +}
  134157. +gcsVIDMEM_NODE_SHARED_INFO;
  134158. +
  134159. +/* Generic pixel component descriptors. */
  134160. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XXX8;
  134161. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XX8X;
  134162. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_X8XX;
  134163. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_8XXX;
  134164. +
  134165. +typedef enum _gceORIENTATION
  134166. +{
  134167. + gcvORIENTATION_TOP_BOTTOM,
  134168. + gcvORIENTATION_BOTTOM_TOP,
  134169. +}
  134170. +gceORIENTATION;
  134171. +
  134172. +
  134173. +/* Construct a new gcoSURF object. */
  134174. +gceSTATUS
  134175. +gcoSURF_Construct(
  134176. + IN gcoHAL Hal,
  134177. + IN gctUINT Width,
  134178. + IN gctUINT Height,
  134179. + IN gctUINT Depth,
  134180. + IN gceSURF_TYPE Type,
  134181. + IN gceSURF_FORMAT Format,
  134182. + IN gcePOOL Pool,
  134183. + OUT gcoSURF * Surface
  134184. + );
  134185. +
  134186. +/* Destroy an gcoSURF object. */
  134187. +gceSTATUS
  134188. +gcoSURF_Destroy(
  134189. + IN gcoSURF Surface
  134190. + );
  134191. +
  134192. +/* Map user-allocated surface. */
  134193. +gceSTATUS
  134194. +gcoSURF_MapUserSurface(
  134195. + IN gcoSURF Surface,
  134196. + IN gctUINT Alignment,
  134197. + IN gctPOINTER Logical,
  134198. + IN gctUINT32 Physical
  134199. + );
  134200. +
  134201. +/* Query vid mem node info. */
  134202. +gceSTATUS
  134203. +gcoSURF_QueryVidMemNode(
  134204. + IN gcoSURF Surface,
  134205. + OUT gctUINT64 * Node,
  134206. + OUT gcePOOL * Pool,
  134207. + OUT gctUINT_PTR Bytes
  134208. + );
  134209. +
  134210. +/* Set the color type of the surface. */
  134211. +gceSTATUS
  134212. +gcoSURF_SetColorType(
  134213. + IN gcoSURF Surface,
  134214. + IN gceSURF_COLOR_TYPE ColorType
  134215. + );
  134216. +
  134217. +/* Get the color type of the surface. */
  134218. +gceSTATUS
  134219. +gcoSURF_GetColorType(
  134220. + IN gcoSURF Surface,
  134221. + OUT gceSURF_COLOR_TYPE *ColorType
  134222. + );
  134223. +
  134224. +/* Set the surface ration angle. */
  134225. +gceSTATUS
  134226. +gcoSURF_SetRotation(
  134227. + IN gcoSURF Surface,
  134228. + IN gceSURF_ROTATION Rotation
  134229. + );
  134230. +
  134231. +gceSTATUS
  134232. +gcoSURF_SetPreRotation(
  134233. + IN gcoSURF Surface,
  134234. + IN gceSURF_ROTATION Rotation
  134235. + );
  134236. +
  134237. +gceSTATUS
  134238. +gcoSURF_GetPreRotation(
  134239. + IN gcoSURF Surface,
  134240. + IN gceSURF_ROTATION *Rotation
  134241. + );
  134242. +
  134243. +gceSTATUS
  134244. +gcoSURF_IsValid(
  134245. + IN gcoSURF Surface
  134246. + );
  134247. +
  134248. +#ifndef VIVANTE_NO_3D
  134249. +/* Verify and return the state of the tile status mechanism. */
  134250. +gceSTATUS
  134251. +gcoSURF_IsTileStatusSupported(
  134252. + IN gcoSURF Surface
  134253. + );
  134254. +
  134255. +/* Process tile status for the specified surface. */
  134256. +gceSTATUS
  134257. +gcoSURF_SetTileStatus(
  134258. + IN gcoSURF Surface
  134259. + );
  134260. +
  134261. +/* Enable tile status for the specified surface. */
  134262. +gceSTATUS
  134263. +gcoSURF_EnableTileStatus(
  134264. + IN gcoSURF Surface
  134265. + );
  134266. +
  134267. +/* Disable tile status for the specified surface. */
  134268. +gceSTATUS
  134269. +gcoSURF_DisableTileStatus(
  134270. + IN gcoSURF Surface,
  134271. + IN gctBOOL Decompress
  134272. + );
  134273. +
  134274. +gceSTATUS
  134275. +gcoSURF_AlignResolveRect(
  134276. + IN gcoSURF Surf,
  134277. + IN gcsPOINT_PTR RectOrigin,
  134278. + IN gcsPOINT_PTR RectSize,
  134279. + OUT gcsPOINT_PTR AlignedOrigin,
  134280. + OUT gcsPOINT_PTR AlignedSize
  134281. + );
  134282. +#endif /* VIVANTE_NO_3D */
  134283. +
  134284. +/* Get surface size. */
  134285. +gceSTATUS
  134286. +gcoSURF_GetSize(
  134287. + IN gcoSURF Surface,
  134288. + OUT gctUINT * Width,
  134289. + OUT gctUINT * Height,
  134290. + OUT gctUINT * Depth
  134291. + );
  134292. +
  134293. +/* Get surface aligned sizes. */
  134294. +gceSTATUS
  134295. +gcoSURF_GetAlignedSize(
  134296. + IN gcoSURF Surface,
  134297. + OUT gctUINT * Width,
  134298. + OUT gctUINT * Height,
  134299. + OUT gctINT * Stride
  134300. + );
  134301. +
  134302. +/* Get alignments. */
  134303. +gceSTATUS
  134304. +gcoSURF_GetAlignment(
  134305. + IN gceSURF_TYPE Type,
  134306. + IN gceSURF_FORMAT Format,
  134307. + OUT gctUINT * AddressAlignment,
  134308. + OUT gctUINT * XAlignment,
  134309. + OUT gctUINT * YAlignment
  134310. + );
  134311. +
  134312. +/* Get surface type and format. */
  134313. +gceSTATUS
  134314. +gcoSURF_GetFormat(
  134315. + IN gcoSURF Surface,
  134316. + OUT gceSURF_TYPE * Type,
  134317. + OUT gceSURF_FORMAT * Format
  134318. + );
  134319. +
  134320. +/* Get surface tiling. */
  134321. +gceSTATUS
  134322. +gcoSURF_GetTiling(
  134323. + IN gcoSURF Surface,
  134324. + OUT gceTILING * Tiling
  134325. + );
  134326. +
  134327. +/* Lock the surface. */
  134328. +gceSTATUS
  134329. +gcoSURF_Lock(
  134330. + IN gcoSURF Surface,
  134331. + IN OUT gctUINT32 * Address,
  134332. + IN OUT gctPOINTER * Memory
  134333. + );
  134334. +
  134335. +/* Unlock the surface. */
  134336. +gceSTATUS
  134337. +gcoSURF_Unlock(
  134338. + IN gcoSURF Surface,
  134339. + IN gctPOINTER Memory
  134340. + );
  134341. +
  134342. +/* Return pixel format parameters. */
  134343. +gceSTATUS
  134344. +gcoSURF_QueryFormat(
  134345. + IN gceSURF_FORMAT Format,
  134346. + OUT gcsSURF_FORMAT_INFO_PTR * Info
  134347. + );
  134348. +
  134349. +/* Compute the color pixel mask. */
  134350. +gceSTATUS
  134351. +gcoSURF_ComputeColorMask(
  134352. + IN gcsSURF_FORMAT_INFO_PTR Format,
  134353. + OUT gctUINT32_PTR ColorMask
  134354. + );
  134355. +
  134356. +/* Flush the surface. */
  134357. +gceSTATUS
  134358. +gcoSURF_Flush(
  134359. + IN gcoSURF Surface
  134360. + );
  134361. +
  134362. +/* Fill surface from it's tile status buffer. */
  134363. +gceSTATUS
  134364. +gcoSURF_FillFromTile(
  134365. + IN gcoSURF Surface
  134366. + );
  134367. +
  134368. +/* Check if surface needs a filler. */
  134369. +gceSTATUS gcoSURF_NeedFiller(IN gcoSURF Surface);
  134370. +
  134371. +/* Fill surface with a value. */
  134372. +gceSTATUS
  134373. +gcoSURF_Fill(
  134374. + IN gcoSURF Surface,
  134375. + IN gcsPOINT_PTR Origin,
  134376. + IN gcsSIZE_PTR Size,
  134377. + IN gctUINT32 Value,
  134378. + IN gctUINT32 Mask
  134379. + );
  134380. +
  134381. +/* Alpha blend two surfaces together. */
  134382. +gceSTATUS
  134383. +gcoSURF_Blend(
  134384. + IN gcoSURF SrcSurface,
  134385. + IN gcoSURF DestSurface,
  134386. + IN gcsPOINT_PTR SrcOrig,
  134387. + IN gcsPOINT_PTR DestOrigin,
  134388. + IN gcsSIZE_PTR Size,
  134389. + IN gceSURF_BLEND_MODE Mode
  134390. + );
  134391. +
  134392. +/* Create a new gcoSURF wrapper object. */
  134393. +gceSTATUS
  134394. +gcoSURF_ConstructWrapper(
  134395. + IN gcoHAL Hal,
  134396. + OUT gcoSURF * Surface
  134397. + );
  134398. +
  134399. +/* Set the underlying buffer for the surface wrapper. */
  134400. +gceSTATUS
  134401. +gcoSURF_SetBuffer(
  134402. + IN gcoSURF Surface,
  134403. + IN gceSURF_TYPE Type,
  134404. + IN gceSURF_FORMAT Format,
  134405. + IN gctUINT Stride,
  134406. + IN gctPOINTER Logical,
  134407. + IN gctUINT32 Physical
  134408. + );
  134409. +
  134410. +/* Set the underlying video buffer for the surface wrapper. */
  134411. +gceSTATUS
  134412. +gcoSURF_SetVideoBuffer(
  134413. + IN gcoSURF Surface,
  134414. + IN gceSURF_TYPE Type,
  134415. + IN gceSURF_FORMAT Format,
  134416. + IN gctUINT Width,
  134417. + IN gctUINT Height,
  134418. + IN gctUINT Stride,
  134419. + IN gctPOINTER *LogicalPlane1,
  134420. + IN gctUINT32 *PhysicalPlane1
  134421. + );
  134422. +
  134423. +/* Set the size of the surface in pixels and map the underlying buffer. */
  134424. +gceSTATUS
  134425. +gcoSURF_SetWindow(
  134426. + IN gcoSURF Surface,
  134427. + IN gctUINT X,
  134428. + IN gctUINT Y,
  134429. + IN gctUINT Width,
  134430. + IN gctUINT Height
  134431. + );
  134432. +
  134433. +/* Set width/height alignment of the surface directly and calculate stride/size. This is only for dri backend now. Please be careful before use. */
  134434. +gceSTATUS
  134435. +gcoSURF_SetAlignment(
  134436. + IN gcoSURF Surface,
  134437. + IN gctUINT Width,
  134438. + IN gctUINT Height
  134439. + );
  134440. +
  134441. +/* Increase reference count of the surface. */
  134442. +gceSTATUS
  134443. +gcoSURF_ReferenceSurface(
  134444. + IN gcoSURF Surface
  134445. + );
  134446. +
  134447. +/* Get surface reference count. */
  134448. +gceSTATUS
  134449. +gcoSURF_QueryReferenceCount(
  134450. + IN gcoSURF Surface,
  134451. + OUT gctINT32 * ReferenceCount
  134452. + );
  134453. +
  134454. +/* Set surface orientation. */
  134455. +gceSTATUS
  134456. +gcoSURF_SetOrientation(
  134457. + IN gcoSURF Surface,
  134458. + IN gceORIENTATION Orientation
  134459. + );
  134460. +
  134461. +/* Query surface orientation. */
  134462. +gceSTATUS
  134463. +gcoSURF_QueryOrientation(
  134464. + IN gcoSURF Surface,
  134465. + OUT gceORIENTATION * Orientation
  134466. + );
  134467. +
  134468. +gceSTATUS
  134469. +gcoSURF_SetOffset(
  134470. + IN gcoSURF Surface,
  134471. + IN gctUINT Offset
  134472. + );
  134473. +
  134474. +gceSTATUS
  134475. +gcoSURF_GetOffset(
  134476. + IN gcoSURF Surface,
  134477. + OUT gctUINT *Offset
  134478. + );
  134479. +
  134480. +gceSTATUS
  134481. +gcoSURF_NODE_Cache(
  134482. + IN gcsSURF_NODE_PTR Node,
  134483. + IN gctPOINTER Logical,
  134484. + IN gctSIZE_T Bytes,
  134485. + IN gceCACHEOPERATION Operation
  134486. + );
  134487. +
  134488. +/* Perform CPU cache operation on surface */
  134489. +gceSTATUS
  134490. +gcoSURF_CPUCacheOperation(
  134491. + IN gcoSURF Surface,
  134492. + IN gceCACHEOPERATION Operation
  134493. + );
  134494. +
  134495. +
  134496. +gceSTATUS
  134497. +gcoSURF_SetLinearResolveAddress(
  134498. + IN gcoSURF Surface,
  134499. + IN gctUINT32 Address,
  134500. + IN gctPOINTER Memory
  134501. + );
  134502. +
  134503. + gceSTATUS
  134504. + gcoSURF_Swap(IN gcoSURF Surface1, IN gcoSURF Surface2);
  134505. +
  134506. +/******************************************************************************\
  134507. +********************************* gcoDUMP Object ********************************
  134508. +\******************************************************************************/
  134509. +
  134510. +/* Construct a new gcoDUMP object. */
  134511. +gceSTATUS
  134512. +gcoDUMP_Construct(
  134513. + IN gcoOS Os,
  134514. + IN gcoHAL Hal,
  134515. + OUT gcoDUMP * Dump
  134516. + );
  134517. +
  134518. +/* Destroy a gcoDUMP object. */
  134519. +gceSTATUS
  134520. +gcoDUMP_Destroy(
  134521. + IN gcoDUMP Dump
  134522. + );
  134523. +
  134524. +/* Enable/disable dumping. */
  134525. +gceSTATUS
  134526. +gcoDUMP_Control(
  134527. + IN gcoDUMP Dump,
  134528. + IN gctSTRING FileName
  134529. + );
  134530. +
  134531. +gceSTATUS
  134532. +gcoDUMP_IsEnabled(
  134533. + IN gcoDUMP Dump,
  134534. + OUT gctBOOL * Enabled
  134535. + );
  134536. +
  134537. +/* Add surface. */
  134538. +gceSTATUS
  134539. +gcoDUMP_AddSurface(
  134540. + IN gcoDUMP Dump,
  134541. + IN gctINT32 Width,
  134542. + IN gctINT32 Height,
  134543. + IN gceSURF_FORMAT PixelFormat,
  134544. + IN gctUINT32 Address,
  134545. + IN gctSIZE_T ByteCount
  134546. + );
  134547. +
  134548. +/* Mark the beginning of a frame. */
  134549. +gceSTATUS
  134550. +gcoDUMP_FrameBegin(
  134551. + IN gcoDUMP Dump
  134552. + );
  134553. +
  134554. +/* Mark the end of a frame. */
  134555. +gceSTATUS
  134556. +gcoDUMP_FrameEnd(
  134557. + IN gcoDUMP Dump
  134558. + );
  134559. +
  134560. +/* Dump data. */
  134561. +gceSTATUS
  134562. +gcoDUMP_DumpData(
  134563. + IN gcoDUMP Dump,
  134564. + IN gceDUMP_TAG Type,
  134565. + IN gctUINT32 Address,
  134566. + IN gctSIZE_T ByteCount,
  134567. + IN gctCONST_POINTER Data
  134568. + );
  134569. +
  134570. +/* Delete an address. */
  134571. +gceSTATUS
  134572. +gcoDUMP_Delete(
  134573. + IN gcoDUMP Dump,
  134574. + IN gctUINT32 Address
  134575. + );
  134576. +
  134577. +/* Enable dump or not. */
  134578. +gceSTATUS
  134579. +gcoDUMP_SetDumpFlag(
  134580. + IN gctBOOL DumpState
  134581. + );
  134582. +
  134583. +/******************************************************************************\
  134584. +******************************* gcsRECT Structure ******************************
  134585. +\******************************************************************************/
  134586. +
  134587. +/* Initialize rectangle structure. */
  134588. +gceSTATUS
  134589. +gcsRECT_Set(
  134590. + OUT gcsRECT_PTR Rect,
  134591. + IN gctINT32 Left,
  134592. + IN gctINT32 Top,
  134593. + IN gctINT32 Right,
  134594. + IN gctINT32 Bottom
  134595. + );
  134596. +
  134597. +/* Return the width of the rectangle. */
  134598. +gceSTATUS
  134599. +gcsRECT_Width(
  134600. + IN gcsRECT_PTR Rect,
  134601. + OUT gctINT32 * Width
  134602. + );
  134603. +
  134604. +/* Return the height of the rectangle. */
  134605. +gceSTATUS
  134606. +gcsRECT_Height(
  134607. + IN gcsRECT_PTR Rect,
  134608. + OUT gctINT32 * Height
  134609. + );
  134610. +
  134611. +/* Ensure that top left corner is to the left and above the right bottom. */
  134612. +gceSTATUS
  134613. +gcsRECT_Normalize(
  134614. + IN OUT gcsRECT_PTR Rect
  134615. + );
  134616. +
  134617. +/* Compare two rectangles. */
  134618. +gceSTATUS
  134619. +gcsRECT_IsEqual(
  134620. + IN gcsRECT_PTR Rect1,
  134621. + IN gcsRECT_PTR Rect2,
  134622. + OUT gctBOOL * Equal
  134623. + );
  134624. +
  134625. +/* Compare the sizes of two rectangles. */
  134626. +gceSTATUS
  134627. +gcsRECT_IsOfEqualSize(
  134628. + IN gcsRECT_PTR Rect1,
  134629. + IN gcsRECT_PTR Rect2,
  134630. + OUT gctBOOL * EqualSize
  134631. + );
  134632. +
  134633. +gceSTATUS
  134634. +gcsRECT_RelativeRotation(
  134635. + IN gceSURF_ROTATION Orientation,
  134636. + IN OUT gceSURF_ROTATION *Relation);
  134637. +
  134638. +gceSTATUS
  134639. +
  134640. +gcsRECT_Rotate(
  134641. +
  134642. + IN OUT gcsRECT_PTR Rect,
  134643. +
  134644. + IN gceSURF_ROTATION Rotation,
  134645. +
  134646. + IN gceSURF_ROTATION toRotation,
  134647. +
  134648. + IN gctINT32 SurfaceWidth,
  134649. +
  134650. + IN gctINT32 SurfaceHeight
  134651. +
  134652. + );
  134653. +
  134654. +/******************************************************************************\
  134655. +**************************** gcsBOUNDARY Structure *****************************
  134656. +\******************************************************************************/
  134657. +
  134658. +typedef struct _gcsBOUNDARY
  134659. +{
  134660. + gctINT x;
  134661. + gctINT y;
  134662. + gctINT width;
  134663. + gctINT height;
  134664. +}
  134665. +gcsBOUNDARY;
  134666. +
  134667. +/******************************************************************************\
  134668. +********************************* gcoHEAP Object ********************************
  134669. +\******************************************************************************/
  134670. +
  134671. +typedef struct _gcoHEAP * gcoHEAP;
  134672. +
  134673. +/* Construct a new gcoHEAP object. */
  134674. +gceSTATUS
  134675. +gcoHEAP_Construct(
  134676. + IN gcoOS Os,
  134677. + IN gctSIZE_T AllocationSize,
  134678. + OUT gcoHEAP * Heap
  134679. + );
  134680. +
  134681. +/* Destroy an gcoHEAP object. */
  134682. +gceSTATUS
  134683. +gcoHEAP_Destroy(
  134684. + IN gcoHEAP Heap
  134685. + );
  134686. +
  134687. +/* Allocate memory. */
  134688. +gceSTATUS
  134689. +gcoHEAP_Allocate(
  134690. + IN gcoHEAP Heap,
  134691. + IN gctSIZE_T Bytes,
  134692. + OUT gctPOINTER * Node
  134693. + );
  134694. +
  134695. +gceSTATUS
  134696. +gcoHEAP_GetMemorySize(
  134697. + IN gcoHEAP Heap,
  134698. + IN gctPOINTER Memory,
  134699. + OUT gctSIZE_T_PTR MemorySize
  134700. + );
  134701. +
  134702. +/* Free memory. */
  134703. +gceSTATUS
  134704. +gcoHEAP_Free(
  134705. + IN gcoHEAP Heap,
  134706. + IN gctPOINTER Node
  134707. + );
  134708. +
  134709. +#if (VIVANTE_PROFILER || gcdDEBUG)
  134710. +/* Profile the heap. */
  134711. +gceSTATUS
  134712. +gcoHEAP_ProfileStart(
  134713. + IN gcoHEAP Heap
  134714. + );
  134715. +
  134716. +gceSTATUS
  134717. +gcoHEAP_ProfileEnd(
  134718. + IN gcoHEAP Heap,
  134719. + IN gctCONST_STRING Title
  134720. + );
  134721. +#endif
  134722. +
  134723. +
  134724. +/******************************************************************************\
  134725. +******************************* Debugging Macros *******************************
  134726. +\******************************************************************************/
  134727. +
  134728. +void
  134729. +gcoOS_SetDebugLevel(
  134730. + IN gctUINT32 Level
  134731. + );
  134732. +
  134733. +void
  134734. +gcoOS_GetDebugLevel(
  134735. + OUT gctUINT32_PTR DebugLevel
  134736. + );
  134737. +
  134738. +void
  134739. +gcoOS_SetDebugZone(
  134740. + IN gctUINT32 Zone
  134741. + );
  134742. +
  134743. +void
  134744. +gcoOS_GetDebugZone(
  134745. + IN gctUINT32 Zone,
  134746. + OUT gctUINT32_PTR DebugZone
  134747. + );
  134748. +
  134749. +void
  134750. +gcoOS_SetDebugLevelZone(
  134751. + IN gctUINT32 Level,
  134752. + IN gctUINT32 Zone
  134753. + );
  134754. +
  134755. +void
  134756. +gcoOS_SetDebugZones(
  134757. + IN gctUINT32 Zones,
  134758. + IN gctBOOL Enable
  134759. + );
  134760. +
  134761. +void
  134762. +gcoOS_SetDebugFile(
  134763. + IN gctCONST_STRING FileName
  134764. + );
  134765. +
  134766. +gctFILE
  134767. +gcoOS_ReplaceDebugFile(
  134768. + IN gctFILE fp
  134769. + );
  134770. +
  134771. +/*******************************************************************************
  134772. +**
  134773. +** gcmFATAL
  134774. +**
  134775. +** Print a message to the debugger and execute a break point.
  134776. +**
  134777. +** ARGUMENTS:
  134778. +**
  134779. +** message Message.
  134780. +** ... Optional arguments.
  134781. +*/
  134782. +
  134783. +void
  134784. +gckOS_DebugFatal(
  134785. + IN gctCONST_STRING Message,
  134786. + ...
  134787. + );
  134788. +
  134789. +void
  134790. +gcoOS_DebugFatal(
  134791. + IN gctCONST_STRING Message,
  134792. + ...
  134793. + );
  134794. +
  134795. +#if gcmIS_DEBUG(gcdDEBUG_FATAL)
  134796. +# define gcmFATAL gcoOS_DebugFatal
  134797. +# define gcmkFATAL gckOS_DebugFatal
  134798. +#elif gcdHAS_ELLIPSES
  134799. +# define gcmFATAL(...)
  134800. +# define gcmkFATAL(...)
  134801. +#else
  134802. + gcmINLINE static void
  134803. + __dummy_fatal(
  134804. + IN gctCONST_STRING Message,
  134805. + ...
  134806. + )
  134807. + {
  134808. + }
  134809. +# define gcmFATAL __dummy_fatal
  134810. +# define gcmkFATAL __dummy_fatal
  134811. +#endif
  134812. +
  134813. +#define gcmENUM2TEXT(e) case e: return #e
  134814. +
  134815. +/*******************************************************************************
  134816. +**
  134817. +** gcmTRACE
  134818. +**
  134819. +** Print a message to the debugfer if the correct level has been set. In
  134820. +** retail mode this macro does nothing.
  134821. +**
  134822. +** ARGUMENTS:
  134823. +**
  134824. +** level Level of message.
  134825. +** message Message.
  134826. +** ... Optional arguments.
  134827. +*/
  134828. +#define gcvLEVEL_NONE -1
  134829. +#define gcvLEVEL_ERROR 0
  134830. +#define gcvLEVEL_WARNING 1
  134831. +#define gcvLEVEL_INFO 2
  134832. +#define gcvLEVEL_VERBOSE 3
  134833. +
  134834. +void
  134835. +gckOS_DebugTrace(
  134836. + IN gctUINT32 Level,
  134837. + IN gctCONST_STRING Message,
  134838. + ...
  134839. + );
  134840. +
  134841. +void
  134842. +gckOS_DebugTraceN(
  134843. + IN gctUINT32 Level,
  134844. + IN gctUINT ArgumentSize,
  134845. + IN gctCONST_STRING Message,
  134846. + ...
  134847. + );
  134848. +
  134849. +void
  134850. +gcoOS_DebugTrace(
  134851. + IN gctUINT32 Level,
  134852. + IN gctCONST_STRING Message,
  134853. + ...
  134854. + );
  134855. +
  134856. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  134857. +# define gcmTRACE gcoOS_DebugTrace
  134858. +# define gcmkTRACE gckOS_DebugTrace
  134859. +# define gcmkTRACE_N gckOS_DebugTraceN
  134860. +#elif gcdHAS_ELLIPSES
  134861. +# define gcmTRACE(...)
  134862. +# define gcmkTRACE(...)
  134863. +# define gcmkTRACE_N(...)
  134864. +#else
  134865. + gcmINLINE static void
  134866. + __dummy_trace(
  134867. + IN gctUINT32 Level,
  134868. + IN gctCONST_STRING Message,
  134869. + ...
  134870. + )
  134871. + {
  134872. + }
  134873. +
  134874. + gcmINLINE static void
  134875. + __dummy_trace_n(
  134876. + IN gctUINT32 Level,
  134877. + IN gctUINT ArgumentSize,
  134878. + IN gctCONST_STRING Message,
  134879. + ...
  134880. + )
  134881. + {
  134882. + }
  134883. +
  134884. +# define gcmTRACE __dummy_trace
  134885. +# define gcmkTRACE __dummy_trace
  134886. +# define gcmkTRACE_N __dummy_trace_n
  134887. +#endif
  134888. +
  134889. +/* Zones common for kernel and user. */
  134890. +#define gcvZONE_OS (1 << 0)
  134891. +#define gcvZONE_HARDWARE (1 << 1)
  134892. +#define gcvZONE_HEAP (1 << 2)
  134893. +#define gcvZONE_SIGNAL (1 << 27)
  134894. +
  134895. +/* Kernel zones. */
  134896. +#define gcvZONE_KERNEL (1 << 3)
  134897. +#define gcvZONE_VIDMEM (1 << 4)
  134898. +#define gcvZONE_COMMAND (1 << 5)
  134899. +#define gcvZONE_DRIVER (1 << 6)
  134900. +#define gcvZONE_CMODEL (1 << 7)
  134901. +#define gcvZONE_MMU (1 << 8)
  134902. +#define gcvZONE_EVENT (1 << 9)
  134903. +#define gcvZONE_DEVICE (1 << 10)
  134904. +#define gcvZONE_DATABASE (1 << 11)
  134905. +#define gcvZONE_INTERRUPT (1 << 12)
  134906. +#define gcvZONE_POWER (1 << 13)
  134907. +
  134908. +/* User zones. */
  134909. +#define gcvZONE_HAL (1 << 3)
  134910. +#define gcvZONE_BUFFER (1 << 4)
  134911. +#define gcvZONE_CONTEXT (1 << 5)
  134912. +#define gcvZONE_SURFACE (1 << 6)
  134913. +#define gcvZONE_INDEX (1 << 7)
  134914. +#define gcvZONE_STREAM (1 << 8)
  134915. +#define gcvZONE_TEXTURE (1 << 9)
  134916. +#define gcvZONE_2D (1 << 10)
  134917. +#define gcvZONE_3D (1 << 11)
  134918. +#define gcvZONE_COMPILER (1 << 12)
  134919. +#define gcvZONE_MEMORY (1 << 13)
  134920. +#define gcvZONE_STATE (1 << 14)
  134921. +#define gcvZONE_AUX (1 << 15)
  134922. +#define gcvZONE_VERTEX (1 << 16)
  134923. +#define gcvZONE_CL (1 << 17)
  134924. +#define gcvZONE_COMPOSITION (1 << 17)
  134925. +#define gcvZONE_VG (1 << 18)
  134926. +#define gcvZONE_IMAGE (1 << 19)
  134927. +#define gcvZONE_UTILITY (1 << 20)
  134928. +#define gcvZONE_PARAMETERS (1 << 21)
  134929. +
  134930. +/* API definitions. */
  134931. +#define gcvZONE_API_HAL (1 << 28)
  134932. +#define gcvZONE_API_EGL (2 << 28)
  134933. +#define gcvZONE_API_ES11 (3 << 28)
  134934. +#define gcvZONE_API_ES20 (4 << 28)
  134935. +#define gcvZONE_API_VG11 (5 << 28)
  134936. +#define gcvZONE_API_GL (6 << 28)
  134937. +#define gcvZONE_API_DFB (7 << 28)
  134938. +#define gcvZONE_API_GDI (8 << 28)
  134939. +#define gcvZONE_API_D3D (9 << 28)
  134940. +#define gcvZONE_API_ES30 (10 << 28)
  134941. +
  134942. +
  134943. +#define gcmZONE_GET_API(zone) ((zone) >> 28)
  134944. +/*Set gcdZONE_MASE like 0x0 | gcvZONE_API_EGL
  134945. +will enable print EGL module debug info*/
  134946. +#define gcdZONE_MASK 0x0FFFFFFF
  134947. +
  134948. +/* Handy zones. */
  134949. +#define gcvZONE_NONE 0
  134950. +#define gcvZONE_ALL 0x0FFFFFFF
  134951. +
  134952. +/*Dump API depth set 1 for API, 2 for API and API behavior*/
  134953. +#define gcvDUMP_API_DEPTH 1
  134954. +
  134955. +/*******************************************************************************
  134956. +**
  134957. +** gcmTRACE_ZONE
  134958. +**
  134959. +** Print a message to the debugger if the correct level and zone has been
  134960. +** set. In retail mode this macro does nothing.
  134961. +**
  134962. +** ARGUMENTS:
  134963. +**
  134964. +** Level Level of message.
  134965. +** Zone Zone of message.
  134966. +** Message Message.
  134967. +** ... Optional arguments.
  134968. +*/
  134969. +
  134970. +void
  134971. +gckOS_DebugTraceZone(
  134972. + IN gctUINT32 Level,
  134973. + IN gctUINT32 Zone,
  134974. + IN gctCONST_STRING Message,
  134975. + ...
  134976. + );
  134977. +
  134978. +void
  134979. +gckOS_DebugTraceZoneN(
  134980. + IN gctUINT32 Level,
  134981. + IN gctUINT32 Zone,
  134982. + IN gctUINT ArgumentSize,
  134983. + IN gctCONST_STRING Message,
  134984. + ...
  134985. + );
  134986. +
  134987. +void
  134988. +gcoOS_DebugTraceZone(
  134989. + IN gctUINT32 Level,
  134990. + IN gctUINT32 Zone,
  134991. + IN gctCONST_STRING Message,
  134992. + ...
  134993. + );
  134994. +
  134995. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  134996. +# define gcmTRACE_ZONE gcoOS_DebugTraceZone
  134997. +# define gcmkTRACE_ZONE gckOS_DebugTraceZone
  134998. +# define gcmkTRACE_ZONE_N gckOS_DebugTraceZoneN
  134999. +#elif gcdHAS_ELLIPSES
  135000. +# define gcmTRACE_ZONE(...)
  135001. +# define gcmkTRACE_ZONE(...)
  135002. +# define gcmkTRACE_ZONE_N(...)
  135003. +#else
  135004. + gcmINLINE static void
  135005. + __dummy_trace_zone(
  135006. + IN gctUINT32 Level,
  135007. + IN gctUINT32 Zone,
  135008. + IN gctCONST_STRING Message,
  135009. + ...
  135010. + )
  135011. + {
  135012. + }
  135013. +
  135014. + gcmINLINE static void
  135015. + __dummy_trace_zone_n(
  135016. + IN gctUINT32 Level,
  135017. + IN gctUINT32 Zone,
  135018. + IN gctUINT ArgumentSize,
  135019. + IN gctCONST_STRING Message,
  135020. + ...
  135021. + )
  135022. + {
  135023. + }
  135024. +
  135025. +# define gcmTRACE_ZONE __dummy_trace_zone
  135026. +# define gcmkTRACE_ZONE __dummy_trace_zone
  135027. +# define gcmkTRACE_ZONE_N __dummy_trace_zone_n
  135028. +#endif
  135029. +
  135030. +/*******************************************************************************
  135031. +**
  135032. +** gcmDEBUG_ONLY
  135033. +**
  135034. +** Execute a statement or function only in DEBUG mode.
  135035. +**
  135036. +** ARGUMENTS:
  135037. +**
  135038. +** f Statement or function to execute.
  135039. +*/
  135040. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  135041. +# define gcmDEBUG_ONLY(f) f
  135042. +#else
  135043. +# define gcmDEBUG_ONLY(f)
  135044. +#endif
  135045. +
  135046. +/*******************************************************************************
  135047. +**
  135048. +** gcmSTACK_PUSH
  135049. +** gcmSTACK_POP
  135050. +** gcmSTACK_DUMP
  135051. +**
  135052. +** Push or pop a function with entry arguments on the trace stack.
  135053. +**
  135054. +** ARGUMENTS:
  135055. +**
  135056. +** Function Name of function.
  135057. +** Line Line number.
  135058. +** Text Optional text.
  135059. +** ... Optional arguments for text.
  135060. +*/
  135061. +#if gcmIS_DEBUG(gcdDEBUG_STACK)
  135062. + void
  135063. + gcoOS_StackPush(
  135064. + IN gctCONST_STRING Function,
  135065. + IN gctINT Line,
  135066. + IN gctCONST_STRING Text,
  135067. + ...
  135068. + );
  135069. + void
  135070. + gcoOS_StackPop(
  135071. + IN gctCONST_STRING Function
  135072. + );
  135073. + void
  135074. + gcoOS_StackDump(
  135075. + void
  135076. + );
  135077. +# define gcmSTACK_PUSH gcoOS_StackPush
  135078. +# define gcmSTACK_POP gcoOS_StackPop
  135079. +# define gcmSTACK_DUMP gcoOS_StackDump
  135080. +#elif gcdHAS_ELLIPSES
  135081. +# define gcmSTACK_PUSH(...) do { } while (0)
  135082. +# define gcmSTACK_POP(Function) do { } while (0)
  135083. +# define gcmSTACK_DUMP() do { } while (0)
  135084. +#else
  135085. + gcmINLINE static void
  135086. + __dummy_stack_push(
  135087. + IN gctCONST_STRING Function,
  135088. + IN gctINT Line,
  135089. + IN gctCONST_STRING Text, ...
  135090. + )
  135091. + {
  135092. + }
  135093. +# define gcmSTACK_PUSH __dummy_stack_push
  135094. +# define gcmSTACK_POP(Function) do { } while (0)
  135095. +# define gcmSTACK_DUMP() do { } while (0)
  135096. +#endif
  135097. +
  135098. +/******************************************************************************\
  135099. +******************************** Logging Macros ********************************
  135100. +\******************************************************************************/
  135101. +
  135102. +#define gcdHEADER_LEVEL gcvLEVEL_VERBOSE
  135103. +
  135104. +
  135105. +#if gcdENABLE_PROFILING
  135106. +void
  135107. +gcoOS_ProfileDB(
  135108. + IN gctCONST_STRING Function,
  135109. + IN OUT gctBOOL_PTR Initialized
  135110. + );
  135111. +
  135112. +#define gcmHEADER() \
  135113. + static gctBOOL __profile__initialized__ = gcvFALSE; \
  135114. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
  135115. + gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__)
  135116. +#define gcmHEADER_ARG(...) \
  135117. + static gctBOOL __profile__initialized__ = gcvFALSE; \
  135118. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
  135119. + gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__)
  135120. +#define gcmFOOTER() \
  135121. + gcmSTACK_POP(__FUNCTION__); \
  135122. + gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
  135123. +#define gcmFOOTER_NO() \
  135124. + gcmSTACK_POP(__FUNCTION__); \
  135125. + gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
  135126. +#define gcmFOOTER_ARG(...) \
  135127. + gcmSTACK_POP(__FUNCTION__); \
  135128. + gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
  135129. +#define gcmFOOTER_KILL() \
  135130. + gcmSTACK_POP(__FUNCTION__); \
  135131. + gcoOS_ProfileDB(gcvNULL, gcvNULL)
  135132. +
  135133. +#else /* gcdENABLE_PROFILING */
  135134. +
  135135. +#if gcdHAS_ELLIPSES
  135136. +#define gcmHEADER() \
  135137. + gctINT8 __user__ = 1; \
  135138. + gctINT8_PTR __user_ptr__ = &__user__; \
  135139. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
  135140. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135141. + "++%s(%d)", __FUNCTION__, __LINE__)
  135142. +#else
  135143. + gcmINLINE static void
  135144. + __dummy_header(void)
  135145. + {
  135146. + }
  135147. +# define gcmHEADER __dummy_header
  135148. +#endif
  135149. +
  135150. +#if gcdHAS_ELLIPSES
  135151. +# define gcmHEADER_ARG(Text, ...) \
  135152. + gctINT8 __user__ = 1; \
  135153. + gctINT8_PTR __user_ptr__ = &__user__; \
  135154. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
  135155. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135156. + "++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__)
  135157. +#else
  135158. + gcmINLINE static void
  135159. + __dummy_header_arg(
  135160. + IN gctCONST_STRING Text,
  135161. + ...
  135162. + )
  135163. + {
  135164. + }
  135165. +# define gcmHEADER_ARG __dummy_header_arg
  135166. +#endif
  135167. +
  135168. +#if gcdHAS_ELLIPSES
  135169. +# define gcmFOOTER() \
  135170. + gcmSTACK_POP(__FUNCTION__); \
  135171. + gcmPROFILE_ONLY(gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135172. + "--%s(%d) [%llu,%llu]: status=%d(%s)", \
  135173. + __FUNCTION__, __LINE__, \
  135174. + __ticks__, __total__, \
  135175. + status, gcoOS_DebugStatus2Name(status))); \
  135176. + gcmPROFILE_ELSE(gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135177. + "--%s(%d): status=%d(%s)", \
  135178. + __FUNCTION__, __LINE__, \
  135179. + status, gcoOS_DebugStatus2Name(status))); \
  135180. + *__user_ptr__ -= 1
  135181. +#else
  135182. + gcmINLINE static void
  135183. + __dummy_footer(void)
  135184. + {
  135185. + }
  135186. +# define gcmFOOTER __dummy_footer
  135187. +#endif
  135188. +
  135189. +#if gcdHAS_ELLIPSES
  135190. +#define gcmFOOTER_NO() \
  135191. + gcmSTACK_POP(__FUNCTION__); \
  135192. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135193. + "--%s(%d)", __FUNCTION__, __LINE__); \
  135194. + *__user_ptr__ -= 1
  135195. +#else
  135196. + gcmINLINE static void
  135197. + __dummy_footer_no(void)
  135198. + {
  135199. + }
  135200. +# define gcmFOOTER_NO __dummy_footer_no
  135201. +#endif
  135202. +
  135203. +#if gcdHAS_ELLIPSES
  135204. +#define gcmFOOTER_KILL() \
  135205. + gcmSTACK_POP(__FUNCTION__); \
  135206. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135207. + "--%s(%d)", __FUNCTION__, __LINE__); \
  135208. + *__user_ptr__ -= 1
  135209. +#else
  135210. + gcmINLINE static void
  135211. + __dummy_footer_kill(void)
  135212. + {
  135213. + }
  135214. +# define gcmFOOTER_KILL __dummy_footer_kill
  135215. +#endif
  135216. +
  135217. +#if gcdHAS_ELLIPSES
  135218. +# define gcmFOOTER_ARG(Text, ...) \
  135219. + gcmSTACK_POP(__FUNCTION__); \
  135220. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135221. + "--%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__); \
  135222. + *__user_ptr__ -= 1
  135223. +#else
  135224. + gcmINLINE static void
  135225. + __dummy_footer_arg(
  135226. + IN gctCONST_STRING Text,
  135227. + ...
  135228. + )
  135229. + {
  135230. + }
  135231. +# define gcmFOOTER_ARG __dummy_footer_arg
  135232. +#endif
  135233. +
  135234. +#endif /* gcdENABLE_PROFILING */
  135235. +
  135236. +#if gcdHAS_ELLIPSES
  135237. +#define gcmkHEADER() \
  135238. + gctINT8 __kernel__ = 1; \
  135239. + gctINT8_PTR __kernel_ptr__ = &__kernel__; \
  135240. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135241. + "++%s(%d)", __FUNCTION__, __LINE__)
  135242. +#else
  135243. + gcmINLINE static void
  135244. + __dummy_kheader(void)
  135245. + {
  135246. + }
  135247. +# define gcmkHEADER __dummy_kheader
  135248. +#endif
  135249. +
  135250. +#if gcdHAS_ELLIPSES
  135251. +# define gcmkHEADER_ARG(Text, ...) \
  135252. + gctINT8 __kernel__ = 1; \
  135253. + gctINT8_PTR __kernel_ptr__ = &__kernel__; \
  135254. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135255. + "++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__)
  135256. +#else
  135257. + gcmINLINE static void
  135258. + __dummy_kheader_arg(
  135259. + IN gctCONST_STRING Text,
  135260. + ...
  135261. + )
  135262. + {
  135263. + }
  135264. +# define gcmkHEADER_ARG __dummy_kheader_arg
  135265. +#endif
  135266. +
  135267. +#if gcdHAS_ELLIPSES
  135268. +#define gcmkFOOTER() \
  135269. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135270. + "--%s(%d): status=%d(%s)", \
  135271. + __FUNCTION__, __LINE__, status, gckOS_DebugStatus2Name(status)); \
  135272. + *__kernel_ptr__ -= 1
  135273. +#else
  135274. + gcmINLINE static void
  135275. + __dummy_kfooter(void)
  135276. + {
  135277. + }
  135278. +# define gcmkFOOTER __dummy_kfooter
  135279. +#endif
  135280. +
  135281. +#if gcdHAS_ELLIPSES
  135282. +#define gcmkFOOTER_NO() \
  135283. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135284. + "--%s(%d)", __FUNCTION__, __LINE__); \
  135285. + *__kernel_ptr__ -= 1
  135286. +#else
  135287. + gcmINLINE static void
  135288. + __dummy_kfooter_no(void)
  135289. + {
  135290. + }
  135291. +# define gcmkFOOTER_NO __dummy_kfooter_no
  135292. +#endif
  135293. +
  135294. +#if gcdHAS_ELLIPSES
  135295. +# define gcmkFOOTER_ARG(Text, ...) \
  135296. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135297. + "--%s(%d): " Text, \
  135298. + __FUNCTION__, __LINE__, __VA_ARGS__); \
  135299. + *__kernel_ptr__ -= 1
  135300. +#else
  135301. + gcmINLINE static void
  135302. + __dummy_kfooter_arg(
  135303. + IN gctCONST_STRING Text,
  135304. + ...
  135305. + )
  135306. + {
  135307. + }
  135308. +# define gcmkFOOTER_ARG __dummy_kfooter_arg
  135309. +#endif
  135310. +
  135311. +#define gcmOPT_VALUE(ptr) (((ptr) == gcvNULL) ? 0 : *(ptr))
  135312. +#define gcmOPT_VALUE_INDEX(ptr, index) (((ptr) == gcvNULL) ? 0 : ptr[index])
  135313. +#define gcmOPT_POINTER(ptr) (((ptr) == gcvNULL) ? gcvNULL : *(ptr))
  135314. +#define gcmOPT_STRING(ptr) (((ptr) == gcvNULL) ? "(nil)" : (ptr))
  135315. +
  135316. +void
  135317. +gckOS_Print(
  135318. + IN gctCONST_STRING Message,
  135319. + ...
  135320. + );
  135321. +
  135322. +void
  135323. +gckOS_PrintN(
  135324. + IN gctUINT ArgumentSize,
  135325. + IN gctCONST_STRING Message,
  135326. + ...
  135327. + );
  135328. +
  135329. +void
  135330. +gckOS_CopyPrint(
  135331. + IN gctCONST_STRING Message,
  135332. + ...
  135333. + );
  135334. +
  135335. +void
  135336. +gcoOS_Print(
  135337. + IN gctCONST_STRING Message,
  135338. + ...
  135339. + );
  135340. +
  135341. +#define gcmPRINT gcoOS_Print
  135342. +#define gcmkPRINT gckOS_Print
  135343. +#define gcmkPRINT_N gckOS_PrintN
  135344. +
  135345. +#if gcdPRINT_VERSION
  135346. +# define gcmPRINT_VERSION() do { \
  135347. + _gcmPRINT_VERSION(gcm); \
  135348. + gcmSTACK_DUMP(); \
  135349. + } while (0)
  135350. +# define gcmkPRINT_VERSION() _gcmPRINT_VERSION(gcmk)
  135351. +# define _gcmPRINT_VERSION(prefix) \
  135352. + prefix##TRACE(gcvLEVEL_ERROR, \
  135353. + "Vivante HAL version %d.%d.%d build %d %s %s", \
  135354. + gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, \
  135355. + gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME )
  135356. +#else
  135357. +# define gcmPRINT_VERSION() do { gcmSTACK_DUMP(); } while (gcvFALSE)
  135358. +# define gcmkPRINT_VERSION() do { } while (gcvFALSE)
  135359. +#endif
  135360. +
  135361. +typedef enum _gceDUMP_BUFFER
  135362. +{
  135363. + gceDUMP_BUFFER_CONTEXT,
  135364. + gceDUMP_BUFFER_USER,
  135365. + gceDUMP_BUFFER_KERNEL,
  135366. + gceDUMP_BUFFER_LINK,
  135367. + gceDUMP_BUFFER_WAITLINK,
  135368. + gceDUMP_BUFFER_FROM_USER,
  135369. +}
  135370. +gceDUMP_BUFFER;
  135371. +
  135372. +void
  135373. +gckOS_DumpBuffer(
  135374. + IN gckOS Os,
  135375. + IN gctPOINTER Buffer,
  135376. + IN gctUINT Size,
  135377. + IN gceDUMP_BUFFER Type,
  135378. + IN gctBOOL CopyMessage
  135379. + );
  135380. +
  135381. +#define gcmkDUMPBUFFER gckOS_DumpBuffer
  135382. +
  135383. +#if gcdDUMP_COMMAND
  135384. +# define gcmkDUMPCOMMAND(Os, Buffer, Size, Type, CopyMessage) \
  135385. + gcmkDUMPBUFFER(Os, Buffer, Size, Type, CopyMessage)
  135386. +#else
  135387. +# define gcmkDUMPCOMMAND(Os, Buffer, Size, Type, CopyMessage)
  135388. +#endif
  135389. +
  135390. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  135391. +
  135392. +void
  135393. +gckOS_DebugFlush(
  135394. + gctCONST_STRING CallerName,
  135395. + gctUINT LineNumber,
  135396. + gctUINT32 DmaAddress
  135397. + );
  135398. +
  135399. +# define gcmkDEBUGFLUSH(DmaAddress) \
  135400. + gckOS_DebugFlush(__FUNCTION__, __LINE__, DmaAddress)
  135401. +#else
  135402. +# define gcmkDEBUGFLUSH(DmaAddress)
  135403. +#endif
  135404. +
  135405. +/*******************************************************************************
  135406. +**
  135407. +** gcmDUMP_FRAMERATE
  135408. +**
  135409. +** Print average frame rate
  135410. +**
  135411. +*/
  135412. +#if gcdDUMP_FRAMERATE
  135413. + gceSTATUS
  135414. + gcfDumpFrameRate(
  135415. + void
  135416. + );
  135417. +# define gcmDUMP_FRAMERATE gcfDumpFrameRate
  135418. +#elif gcdHAS_ELLIPSES
  135419. +# define gcmDUMP_FRAMERATE(...)
  135420. +#else
  135421. + gcmINLINE static void
  135422. + __dummy_dump_frame_rate(
  135423. + void
  135424. + )
  135425. + {
  135426. + }
  135427. +# define gcmDUMP_FRAMERATE __dummy_dump_frame_rate
  135428. +#endif
  135429. +
  135430. +
  135431. +/*******************************************************************************
  135432. +**
  135433. +** gcmDUMP
  135434. +**
  135435. +** Print a dump message.
  135436. +**
  135437. +** ARGUMENTS:
  135438. +**
  135439. +** gctSTRING Message.
  135440. +**
  135441. +** ... Optional arguments.
  135442. +*/
  135443. +#if gcdDUMP
  135444. + gceSTATUS
  135445. + gcfDump(
  135446. + IN gcoOS Os,
  135447. + IN gctCONST_STRING String,
  135448. + ...
  135449. + );
  135450. +# define gcmDUMP gcfDump
  135451. +#elif gcdHAS_ELLIPSES
  135452. +# define gcmDUMP(...)
  135453. +#else
  135454. + gcmINLINE static void
  135455. + __dummy_dump(
  135456. + IN gcoOS Os,
  135457. + IN gctCONST_STRING Message,
  135458. + ...
  135459. + )
  135460. + {
  135461. + }
  135462. +# define gcmDUMP __dummy_dump
  135463. +#endif
  135464. +
  135465. +/*******************************************************************************
  135466. +**
  135467. +** gcmDUMP_DATA
  135468. +**
  135469. +** Add data to the dump.
  135470. +**
  135471. +** ARGUMENTS:
  135472. +**
  135473. +** gctSTRING Tag
  135474. +** Tag for dump.
  135475. +**
  135476. +** gctPOINTER Logical
  135477. +** Logical address of buffer.
  135478. +**
  135479. +** gctSIZE_T Bytes
  135480. +** Number of bytes.
  135481. +*/
  135482. +
  135483. +#if gcdDUMP || gcdDUMP_COMMAND
  135484. + gceSTATUS
  135485. + gcfDumpData(
  135486. + IN gcoOS Os,
  135487. + IN gctSTRING Tag,
  135488. + IN gctPOINTER Logical,
  135489. + IN gctSIZE_T Bytes
  135490. + );
  135491. +# define gcmDUMP_DATA gcfDumpData
  135492. +#elif gcdHAS_ELLIPSES
  135493. +# define gcmDUMP_DATA(...)
  135494. +#else
  135495. + gcmINLINE static void
  135496. + __dummy_dump_data(
  135497. + IN gcoOS Os,
  135498. + IN gctSTRING Tag,
  135499. + IN gctPOINTER Logical,
  135500. + IN gctSIZE_T Bytes
  135501. + )
  135502. + {
  135503. + }
  135504. +# define gcmDUMP_DATA __dummy_dump_data
  135505. +#endif
  135506. +
  135507. +/*******************************************************************************
  135508. +**
  135509. +** gcmDUMP_BUFFER
  135510. +**
  135511. +** Print a buffer to the dump.
  135512. +**
  135513. +** ARGUMENTS:
  135514. +**
  135515. +** gctSTRING Tag
  135516. +** Tag for dump.
  135517. +**
  135518. +** gctUINT32 Physical
  135519. +** Physical address of buffer.
  135520. +**
  135521. +** gctPOINTER Logical
  135522. +** Logical address of buffer.
  135523. +**
  135524. +** gctUINT32 Offset
  135525. +** Offset into buffer.
  135526. +**
  135527. +** gctSIZE_T Bytes
  135528. +** Number of bytes.
  135529. +*/
  135530. +
  135531. +#if gcdDUMP || gcdDUMP_COMMAND
  135532. +gceSTATUS
  135533. +gcfDumpBuffer(
  135534. + IN gcoOS Os,
  135535. + IN gctSTRING Tag,
  135536. + IN gctUINT32 Physical,
  135537. + IN gctPOINTER Logical,
  135538. + IN gctUINT32 Offset,
  135539. + IN gctSIZE_T Bytes
  135540. + );
  135541. +# define gcmDUMP_BUFFER gcfDumpBuffer
  135542. +#elif gcdHAS_ELLIPSES
  135543. +# define gcmDUMP_BUFFER(...)
  135544. +#else
  135545. + gcmINLINE static void
  135546. + __dummy_dump_buffer(
  135547. + IN gcoOS Os,
  135548. + IN gctSTRING Tag,
  135549. + IN gctUINT32 Physical,
  135550. + IN gctPOINTER Logical,
  135551. + IN gctUINT32 Offset,
  135552. + IN gctSIZE_T Bytes
  135553. + )
  135554. + {
  135555. + }
  135556. +# define gcmDUMP_BUFFER __dummy_dump_buffer
  135557. +#endif
  135558. +
  135559. +/*******************************************************************************
  135560. +**
  135561. +** gcmDUMP_API
  135562. +**
  135563. +** Print a dump message for a high level API prefixed by the function name.
  135564. +**
  135565. +** ARGUMENTS:
  135566. +**
  135567. +** gctSTRING Message.
  135568. +**
  135569. +** ... Optional arguments.
  135570. +*/
  135571. +gceSTATUS gcfDumpApi(IN gctCONST_STRING String, ...);
  135572. +#if gcdDUMP_API
  135573. +# define gcmDUMP_API gcfDumpApi
  135574. +#elif gcdHAS_ELLIPSES
  135575. +# define gcmDUMP_API(...)
  135576. +#else
  135577. + gcmINLINE static void
  135578. + __dummy_dump_api(
  135579. + IN gctCONST_STRING Message,
  135580. + ...
  135581. + )
  135582. + {
  135583. + }
  135584. +# define gcmDUMP_API __dummy_dump_api
  135585. +#endif
  135586. +
  135587. +/*******************************************************************************
  135588. +**
  135589. +** gcmDUMP_API_ARRAY
  135590. +**
  135591. +** Print an array of data.
  135592. +**
  135593. +** ARGUMENTS:
  135594. +**
  135595. +** gctUINT32_PTR Pointer to array.
  135596. +** gctUINT32 Size.
  135597. +*/
  135598. +gceSTATUS gcfDumpArray(IN gctCONST_POINTER Data, IN gctUINT32 Size);
  135599. +#if gcdDUMP_API
  135600. +# define gcmDUMP_API_ARRAY gcfDumpArray
  135601. +#elif gcdHAS_ELLIPSES
  135602. +# define gcmDUMP_API_ARRAY(...)
  135603. +#else
  135604. + gcmINLINE static void
  135605. + __dummy_dump_api_array(
  135606. + IN gctCONST_POINTER Data,
  135607. + IN gctUINT32 Size
  135608. + )
  135609. + {
  135610. + }
  135611. +# define gcmDUMP_API_ARRAY __dummy_dump_api_array
  135612. +#endif
  135613. +
  135614. +/*******************************************************************************
  135615. +**
  135616. +** gcmDUMP_API_ARRAY_TOKEN
  135617. +**
  135618. +** Print an array of data terminated by a token.
  135619. +**
  135620. +** ARGUMENTS:
  135621. +**
  135622. +** gctUINT32_PTR Pointer to array.
  135623. +** gctUINT32 Termination.
  135624. +*/
  135625. +gceSTATUS gcfDumpArrayToken(IN gctCONST_POINTER Data, IN gctUINT32 Termination);
  135626. +#if gcdDUMP_API
  135627. +# define gcmDUMP_API_ARRAY_TOKEN gcfDumpArrayToken
  135628. +#elif gcdHAS_ELLIPSES
  135629. +# define gcmDUMP_API_ARRAY_TOKEN(...)
  135630. +#else
  135631. + gcmINLINE static void
  135632. + __dummy_dump_api_array_token(
  135633. + IN gctCONST_POINTER Data,
  135634. + IN gctUINT32 Termination
  135635. + )
  135636. + {
  135637. + }
  135638. +# define gcmDUMP_API_ARRAY_TOKEN __dummy_dump_api_array_token
  135639. +#endif
  135640. +
  135641. +/*******************************************************************************
  135642. +**
  135643. +** gcmDUMP_API_DATA
  135644. +**
  135645. +** Print an array of bytes.
  135646. +**
  135647. +** ARGUMENTS:
  135648. +**
  135649. +** gctCONST_POINTER Pointer to array.
  135650. +** gctSIZE_T Size.
  135651. +*/
  135652. +gceSTATUS gcfDumpApiData(IN gctCONST_POINTER Data, IN gctSIZE_T Size);
  135653. +#if gcdDUMP_API
  135654. +# define gcmDUMP_API_DATA gcfDumpApiData
  135655. +#elif gcdHAS_ELLIPSES
  135656. +# define gcmDUMP_API_DATA(...)
  135657. +#else
  135658. + gcmINLINE static void
  135659. + __dummy_dump_api_data(
  135660. + IN gctCONST_POINTER Data,
  135661. + IN gctSIZE_T Size
  135662. + )
  135663. + {
  135664. + }
  135665. +# define gcmDUMP_API_DATA __dummy_dump_api_data
  135666. +#endif
  135667. +
  135668. +/*******************************************************************************
  135669. +**
  135670. +** gcmTRACE_RELEASE
  135671. +**
  135672. +** Print a message to the shader debugger.
  135673. +**
  135674. +** ARGUMENTS:
  135675. +**
  135676. +** message Message.
  135677. +** ... Optional arguments.
  135678. +*/
  135679. +
  135680. +#define gcmTRACE_RELEASE gcoOS_DebugShaderTrace
  135681. +
  135682. +void
  135683. +gcoOS_DebugShaderTrace(
  135684. + IN gctCONST_STRING Message,
  135685. + ...
  135686. + );
  135687. +
  135688. +void
  135689. +gcoOS_SetDebugShaderFiles(
  135690. + IN gctCONST_STRING VSFileName,
  135691. + IN gctCONST_STRING FSFileName
  135692. + );
  135693. +
  135694. +void
  135695. +gcoOS_SetDebugShaderFileType(
  135696. + IN gctUINT32 ShaderType
  135697. + );
  135698. +
  135699. +void
  135700. +gcoOS_EnableDebugBuffer(
  135701. + IN gctBOOL Enable
  135702. + );
  135703. +
  135704. +/*******************************************************************************
  135705. +**
  135706. +** gcmBREAK
  135707. +**
  135708. +** Break into the debugger. In retail mode this macro does nothing.
  135709. +**
  135710. +** ARGUMENTS:
  135711. +**
  135712. +** None.
  135713. +*/
  135714. +
  135715. +void
  135716. +gcoOS_DebugBreak(
  135717. + void
  135718. + );
  135719. +
  135720. +void
  135721. +gckOS_DebugBreak(
  135722. + void
  135723. + );
  135724. +
  135725. +#if gcmIS_DEBUG(gcdDEBUG_BREAK)
  135726. +# define gcmBREAK gcoOS_DebugBreak
  135727. +# define gcmkBREAK gckOS_DebugBreak
  135728. +#else
  135729. +# define gcmBREAK()
  135730. +# define gcmkBREAK()
  135731. +#endif
  135732. +
  135733. +/*******************************************************************************
  135734. +**
  135735. +** gcmASSERT
  135736. +**
  135737. +** Evaluate an expression and break into the debugger if the expression
  135738. +** evaluates to false. In retail mode this macro does nothing.
  135739. +**
  135740. +** ARGUMENTS:
  135741. +**
  135742. +** exp Expression to evaluate.
  135743. +*/
  135744. +#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
  135745. +# define _gcmASSERT(prefix, exp) \
  135746. + do \
  135747. + { \
  135748. + if (!(exp)) \
  135749. + { \
  135750. + prefix##TRACE(gcvLEVEL_ERROR, \
  135751. + #prefix "ASSERT at %s(%d)", \
  135752. + __FUNCTION__, __LINE__); \
  135753. + prefix##TRACE(gcvLEVEL_ERROR, \
  135754. + "(%s)", #exp); \
  135755. + prefix##BREAK(); \
  135756. + } \
  135757. + } \
  135758. + while (gcvFALSE)
  135759. +# define gcmASSERT(exp) _gcmASSERT(gcm, exp)
  135760. +# define gcmkASSERT(exp) _gcmASSERT(gcmk, exp)
  135761. +#else
  135762. +# define gcmASSERT(exp)
  135763. +# define gcmkASSERT(exp)
  135764. +#endif
  135765. +
  135766. +/*******************************************************************************
  135767. +**
  135768. +** gcmVERIFY
  135769. +**
  135770. +** Verify if an expression returns true. If the expression does not
  135771. +** evaluates to true, an assertion will happen in debug mode.
  135772. +**
  135773. +** ARGUMENTS:
  135774. +**
  135775. +** exp Expression to evaluate.
  135776. +*/
  135777. +#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
  135778. +# define gcmVERIFY(exp) gcmASSERT(exp)
  135779. +# define gcmkVERIFY(exp) gcmkASSERT(exp)
  135780. +#else
  135781. +# define gcmVERIFY(exp) exp
  135782. +# define gcmkVERIFY(exp) exp
  135783. +#endif
  135784. +
  135785. +/*******************************************************************************
  135786. +**
  135787. +** gcmVERIFY_OK
  135788. +**
  135789. +** Verify a fucntion returns gcvSTATUS_OK. If the function does not return
  135790. +** gcvSTATUS_OK, an assertion will happen in debug mode.
  135791. +**
  135792. +** ARGUMENTS:
  135793. +**
  135794. +** func Function to evaluate.
  135795. +*/
  135796. +
  135797. +void
  135798. +gcoOS_Verify(
  135799. + IN gceSTATUS status
  135800. + );
  135801. +
  135802. +void
  135803. +gckOS_Verify(
  135804. + IN gceSTATUS status
  135805. + );
  135806. +
  135807. +#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
  135808. +# define gcmVERIFY_OK(func) \
  135809. + do \
  135810. + { \
  135811. + gceSTATUS verifyStatus = func; \
  135812. + gcoOS_Verify(verifyStatus); \
  135813. + if (verifyStatus != gcvSTATUS_OK) \
  135814. + { \
  135815. + gcmTRACE( \
  135816. + gcvLEVEL_ERROR, \
  135817. + "gcmVERIFY_OK(%d): function returned %d", \
  135818. + __LINE__, verifyStatus \
  135819. + ); \
  135820. + } \
  135821. + gcmASSERT(verifyStatus == gcvSTATUS_OK); \
  135822. + } \
  135823. + while (gcvFALSE)
  135824. +# define gcmkVERIFY_OK(func) \
  135825. + do \
  135826. + { \
  135827. + gceSTATUS verifyStatus = func; \
  135828. + if (verifyStatus != gcvSTATUS_OK) \
  135829. + { \
  135830. + gcmkTRACE( \
  135831. + gcvLEVEL_ERROR, \
  135832. + "gcmkVERIFY_OK(%d): function returned %d", \
  135833. + __LINE__, verifyStatus \
  135834. + ); \
  135835. + } \
  135836. + gckOS_Verify(verifyStatus); \
  135837. + gcmkASSERT(verifyStatus == gcvSTATUS_OK); \
  135838. + } \
  135839. + while (gcvFALSE)
  135840. +#else
  135841. +# define gcmVERIFY_OK(func) func
  135842. +# define gcmkVERIFY_OK(func) func
  135843. +#endif
  135844. +
  135845. +gctCONST_STRING
  135846. +gcoOS_DebugStatus2Name(
  135847. + gceSTATUS status
  135848. + );
  135849. +
  135850. +gctCONST_STRING
  135851. +gckOS_DebugStatus2Name(
  135852. + gceSTATUS status
  135853. + );
  135854. +
  135855. +/*******************************************************************************
  135856. +**
  135857. +** gcmERR_BREAK
  135858. +**
  135859. +** Executes a break statement on error.
  135860. +**
  135861. +** ASSUMPTIONS:
  135862. +**
  135863. +** 'status' variable of gceSTATUS type must be defined.
  135864. +**
  135865. +** ARGUMENTS:
  135866. +**
  135867. +** func Function to evaluate.
  135868. +*/
  135869. +#define _gcmERR_BREAK(prefix, func) \
  135870. + status = func; \
  135871. + if (gcmIS_ERROR(status)) \
  135872. + { \
  135873. + prefix##PRINT_VERSION(); \
  135874. + prefix##TRACE(gcvLEVEL_ERROR, \
  135875. + #prefix "ERR_BREAK: status=%d(%s) @ %s(%d)", \
  135876. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135877. + break; \
  135878. + } \
  135879. + do { } while (gcvFALSE)
  135880. +#define _gcmkERR_BREAK(prefix, func) \
  135881. + status = func; \
  135882. + if (gcmIS_ERROR(status)) \
  135883. + { \
  135884. + prefix##PRINT_VERSION(); \
  135885. + prefix##TRACE(gcvLEVEL_ERROR, \
  135886. + #prefix "ERR_BREAK: status=%d(%s) @ %s(%d)", \
  135887. + status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135888. + break; \
  135889. + } \
  135890. + do { } while (gcvFALSE)
  135891. +#define gcmERR_BREAK(func) _gcmERR_BREAK(gcm, func)
  135892. +#define gcmkERR_BREAK(func) _gcmkERR_BREAK(gcmk, func)
  135893. +
  135894. +/*******************************************************************************
  135895. +**
  135896. +** gcmERR_RETURN
  135897. +**
  135898. +** Executes a return on error.
  135899. +**
  135900. +** ASSUMPTIONS:
  135901. +**
  135902. +** 'status' variable of gceSTATUS type must be defined.
  135903. +**
  135904. +** ARGUMENTS:
  135905. +**
  135906. +** func Function to evaluate.
  135907. +*/
  135908. +#define _gcmERR_RETURN(prefix, func) \
  135909. + status = func; \
  135910. + if (gcmIS_ERROR(status)) \
  135911. + { \
  135912. + prefix##PRINT_VERSION(); \
  135913. + prefix##TRACE(gcvLEVEL_ERROR, \
  135914. + #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
  135915. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135916. + prefix##FOOTER(); \
  135917. + return status; \
  135918. + } \
  135919. + do { } while (gcvFALSE)
  135920. +#define _gcmkERR_RETURN(prefix, func) \
  135921. + status = func; \
  135922. + if (gcmIS_ERROR(status)) \
  135923. + { \
  135924. + prefix##PRINT_VERSION(); \
  135925. + prefix##TRACE(gcvLEVEL_ERROR, \
  135926. + #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
  135927. + status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135928. + prefix##FOOTER(); \
  135929. + return status; \
  135930. + } \
  135931. + do { } while (gcvFALSE)
  135932. +#define gcmERR_RETURN(func) _gcmERR_RETURN(gcm, func)
  135933. +#define gcmkERR_RETURN(func) _gcmkERR_RETURN(gcmk, func)
  135934. +
  135935. +
  135936. +/*******************************************************************************
  135937. +**
  135938. +** gcmONERROR
  135939. +**
  135940. +** Jump to the error handler in case there is an error.
  135941. +**
  135942. +** ASSUMPTIONS:
  135943. +**
  135944. +** 'status' variable of gceSTATUS type must be defined.
  135945. +**
  135946. +** ARGUMENTS:
  135947. +**
  135948. +** func Function to evaluate.
  135949. +*/
  135950. +#define _gcmONERROR(prefix, func) \
  135951. + do \
  135952. + { \
  135953. + status = func; \
  135954. + if (gcmIS_ERROR(status)) \
  135955. + { \
  135956. + prefix##PRINT_VERSION(); \
  135957. + prefix##TRACE(gcvLEVEL_ERROR, \
  135958. + #prefix "ONERROR: status=%d(%s) @ %s(%d)", \
  135959. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135960. + goto OnError; \
  135961. + } \
  135962. + } \
  135963. + while (gcvFALSE)
  135964. +#define _gcmkONERROR(prefix, func) \
  135965. + do \
  135966. + { \
  135967. + status = func; \
  135968. + if (gcmIS_ERROR(status)) \
  135969. + { \
  135970. + prefix##PRINT_VERSION(); \
  135971. + prefix##TRACE(gcvLEVEL_ERROR, \
  135972. + #prefix "ONERROR: status=%d(%s) @ %s(%d)", \
  135973. + status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135974. + goto OnError; \
  135975. + } \
  135976. + } \
  135977. + while (gcvFALSE)
  135978. +#define gcmONERROR(func) _gcmONERROR(gcm, func)
  135979. +#define gcmkONERROR(func) _gcmkONERROR(gcmk, func)
  135980. +
  135981. +/*******************************************************************************
  135982. +**
  135983. +** gcmVERIFY_LOCK
  135984. +**
  135985. +** Verifies whether the surface is locked.
  135986. +**
  135987. +** ARGUMENTS:
  135988. +**
  135989. +** surfaceInfo Pointer to the surface iniformational structure.
  135990. +*/
  135991. +#define gcmVERIFY_LOCK(surfaceInfo) \
  135992. + if (!surfaceInfo->node.valid) \
  135993. + { \
  135994. + gcmONERROR(gcvSTATUS_MEMORY_UNLOCKED); \
  135995. + } \
  135996. +
  135997. +/*******************************************************************************
  135998. +**
  135999. +** gcmVERIFY_NODE_LOCK
  136000. +**
  136001. +** Verifies whether the surface node is locked.
  136002. +**
  136003. +** ARGUMENTS:
  136004. +**
  136005. +** surfaceInfo Pointer to the surface iniformational structure.
  136006. +*/
  136007. +#define gcmVERIFY_NODE_LOCK(surfaceNode) \
  136008. + if (!(surfaceNode)->valid) \
  136009. + { \
  136010. + status = gcvSTATUS_MEMORY_UNLOCKED; \
  136011. + break; \
  136012. + } \
  136013. + do { } while (gcvFALSE)
  136014. +
  136015. +/*******************************************************************************
  136016. +**
  136017. +** gcmBADOBJECT_BREAK
  136018. +**
  136019. +** Executes a break statement on bad object.
  136020. +**
  136021. +** ARGUMENTS:
  136022. +**
  136023. +** obj Object to test.
  136024. +** t Expected type of the object.
  136025. +*/
  136026. +#define gcmBADOBJECT_BREAK(obj, t) \
  136027. + if ((obj == gcvNULL) \
  136028. + || (((gcsOBJECT *)(obj))->type != t) \
  136029. + ) \
  136030. + { \
  136031. + status = gcvSTATUS_INVALID_OBJECT; \
  136032. + break; \
  136033. + } \
  136034. + do { } while (gcvFALSE)
  136035. +
  136036. +/*******************************************************************************
  136037. +**
  136038. +** gcmCHECK_STATUS
  136039. +**
  136040. +** Executes a break statement on error.
  136041. +**
  136042. +** ASSUMPTIONS:
  136043. +**
  136044. +** 'status' variable of gceSTATUS type must be defined.
  136045. +**
  136046. +** ARGUMENTS:
  136047. +**
  136048. +** func Function to evaluate.
  136049. +*/
  136050. +#define _gcmCHECK_STATUS(prefix, func) \
  136051. + do \
  136052. + { \
  136053. + last = func; \
  136054. + if (gcmIS_ERROR(last)) \
  136055. + { \
  136056. + prefix##TRACE(gcvLEVEL_ERROR, \
  136057. + #prefix "CHECK_STATUS: status=%d(%s) @ %s(%d)", \
  136058. + last, gcoOS_DebugStatus2Name(last), __FUNCTION__, __LINE__); \
  136059. + status = last; \
  136060. + } \
  136061. + } \
  136062. + while (gcvFALSE)
  136063. +#define _gcmkCHECK_STATUS(prefix, func) \
  136064. + do \
  136065. + { \
  136066. + last = func; \
  136067. + if (gcmIS_ERROR(last)) \
  136068. + { \
  136069. + prefix##TRACE(gcvLEVEL_ERROR, \
  136070. + #prefix "CHECK_STATUS: status=%d(%s) @ %s(%d)", \
  136071. + last, gckOS_DebugStatus2Name(last), __FUNCTION__, __LINE__); \
  136072. + status = last; \
  136073. + } \
  136074. + } \
  136075. + while (gcvFALSE)
  136076. +#define gcmCHECK_STATUS(func) _gcmCHECK_STATUS(gcm, func)
  136077. +#define gcmkCHECK_STATUS(func) _gcmkCHECK_STATUS(gcmk, func)
  136078. +
  136079. +/*******************************************************************************
  136080. +**
  136081. +** gcmVERIFY_ARGUMENT
  136082. +**
  136083. +** Assert if an argument does not apply to the specified expression. If
  136084. +** the argument evaluates to false, gcvSTATUS_INVALID_ARGUMENT will be
  136085. +** returned from the current function. In retail mode this macro does
  136086. +** nothing.
  136087. +**
  136088. +** ARGUMENTS:
  136089. +**
  136090. +** arg Argument to evaluate.
  136091. +*/
  136092. +# define _gcmVERIFY_ARGUMENT(prefix, arg) \
  136093. + do \
  136094. + { \
  136095. + if (!(arg)) \
  136096. + { \
  136097. + prefix##TRACE(gcvLEVEL_ERROR, #prefix "VERIFY_ARGUMENT failed:"); \
  136098. + prefix##ASSERT(arg); \
  136099. + prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT); \
  136100. + return gcvSTATUS_INVALID_ARGUMENT; \
  136101. + } \
  136102. + } \
  136103. + while (gcvFALSE)
  136104. +# define gcmVERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcm, arg)
  136105. +# define gcmkVERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcmk, arg)
  136106. +
  136107. +/*******************************************************************************
  136108. +**
  136109. +** gcmDEBUG_VERIFY_ARGUMENT
  136110. +**
  136111. +** Works just like gcmVERIFY_ARGUMENT, but is only valid in debug mode.
  136112. +** Use this to verify arguments inside non-public API functions.
  136113. +*/
  136114. +#if gcdDEBUG
  136115. +# define gcmDEBUG_VERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcm, arg)
  136116. +# define gcmkDEBUG_VERIFY_ARGUMENT(arg) _gcmkVERIFY_ARGUMENT(gcm, arg)
  136117. +#else
  136118. +# define gcmDEBUG_VERIFY_ARGUMENT(arg)
  136119. +# define gcmkDEBUG_VERIFY_ARGUMENT(arg)
  136120. +#endif
  136121. +
  136122. +/*******************************************************************************
  136123. +**
  136124. +** gcmVERIFY_ARGUMENT_RETURN
  136125. +**
  136126. +** Assert if an argument does not apply to the specified expression. If
  136127. +** the argument evaluates to false, gcvSTATUS_INVALID_ARGUMENT will be
  136128. +** returned from the current function. In retail mode this macro does
  136129. +** nothing.
  136130. +**
  136131. +** ARGUMENTS:
  136132. +**
  136133. +** arg Argument to evaluate.
  136134. +*/
  136135. +# define _gcmVERIFY_ARGUMENT_RETURN(prefix, arg, value) \
  136136. + do \
  136137. + { \
  136138. + if (!(arg)) \
  136139. + { \
  136140. + prefix##TRACE(gcvLEVEL_ERROR, \
  136141. + #prefix "gcmVERIFY_ARGUMENT_RETURN failed:"); \
  136142. + prefix##ASSERT(arg); \
  136143. + prefix##FOOTER_ARG("value=%d", value); \
  136144. + return value; \
  136145. + } \
  136146. + } \
  136147. + while (gcvFALSE)
  136148. +# define gcmVERIFY_ARGUMENT_RETURN(arg, value) \
  136149. + _gcmVERIFY_ARGUMENT_RETURN(gcm, arg, value)
  136150. +# define gcmkVERIFY_ARGUMENT_RETURN(arg, value) \
  136151. + _gcmVERIFY_ARGUMENT_RETURN(gcmk, arg, value)
  136152. +
  136153. +#define MAX_LOOP_COUNT 0x7FFFFFFF
  136154. +
  136155. +/******************************************************************************\
  136156. +****************************** User Debug Option ******************************
  136157. +\******************************************************************************/
  136158. +
  136159. +/* User option. */
  136160. +typedef enum _gceDEBUG_MSG
  136161. +{
  136162. + gcvDEBUG_MSG_NONE,
  136163. + gcvDEBUG_MSG_ERROR,
  136164. + gcvDEBUG_MSG_WARNING
  136165. +}
  136166. +gceDEBUG_MSG;
  136167. +
  136168. +typedef struct _gcsUSER_DEBUG_OPTION
  136169. +{
  136170. + gceDEBUG_MSG debugMsg;
  136171. +}
  136172. +gcsUSER_DEBUG_OPTION;
  136173. +
  136174. +gcsUSER_DEBUG_OPTION *
  136175. +gcGetUserDebugOption(
  136176. + void
  136177. + );
  136178. +
  136179. +struct _gcoOS_SymbolsList
  136180. +{
  136181. + gcePATCH_ID patchId;
  136182. + const char * symList[10];
  136183. +};
  136184. +
  136185. +#if gcdHAS_ELLIPSES
  136186. +#define gcmUSER_DEBUG_MSG(level, ...) \
  136187. + do \
  136188. + { \
  136189. + if (level <= gcGetUserDebugOption()->debugMsg) \
  136190. + { \
  136191. + gcoOS_Print(__VA_ARGS__); \
  136192. + } \
  136193. + } while (gcvFALSE)
  136194. +
  136195. +#define gcmUSER_DEBUG_ERROR_MSG(...) gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_ERROR, "Error: " __VA_ARGS__)
  136196. +#define gcmUSER_DEBUG_WARNING_MSG(...) gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_WARNING, "Warring: " __VA_ARGS__)
  136197. +#else
  136198. +#define gcmUSER_DEBUG_MSG
  136199. +#define gcmUSER_DEBUG_ERROR_MSG
  136200. +#define gcmUSER_DEBUG_WARNING_MSG
  136201. +#endif
  136202. +
  136203. +#ifdef __cplusplus
  136204. +}
  136205. +#endif
  136206. +
  136207. +#endif /* __gc_hal_base_h_ */
  136208. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
  136209. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h 1970-01-01 01:00:00.000000000 +0100
  136210. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h 2014-08-20 19:31:46.132869024 +0200
  136211. @@ -0,0 +1,4298 @@
  136212. +/****************************************************************************
  136213. +*
  136214. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  136215. +*
  136216. +* This program is free software; you can redistribute it and/or modify
  136217. +* it under the terms of the GNU General Public License as published by
  136218. +* the Free Software Foundation; either version 2 of the license, or
  136219. +* (at your option) any later version.
  136220. +*
  136221. +* This program is distributed in the hope that it will be useful,
  136222. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  136223. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  136224. +* GNU General Public License for more details.
  136225. +*
  136226. +* You should have received a copy of the GNU General Public License
  136227. +* along with this program; if not write to the Free Software
  136228. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  136229. +*
  136230. +*****************************************************************************/
  136231. +
  136232. +/*
  136233. +** Include file the defines the front- and back-end compilers, as well as the
  136234. +** objects they use.
  136235. +*/
  136236. +
  136237. +#ifndef __gc_hal_compiler_h_
  136238. +#define __gc_hal_compiler_h_
  136239. +
  136240. +#ifndef VIVANTE_NO_3D
  136241. +#include "gc_hal_types.h"
  136242. +#include "gc_hal_engine.h"
  136243. +
  136244. +#ifdef __cplusplus
  136245. +extern "C" {
  136246. +#endif
  136247. +
  136248. +#ifndef GC_ENABLE_LOADTIME_OPT
  136249. +#define GC_ENABLE_LOADTIME_OPT 1
  136250. +#endif
  136251. +
  136252. +#define TEMP_OPT_CONSTANT_TEXLD_COORD 0
  136253. +
  136254. +#define TEMP_SHADER_PATCH 1
  136255. +
  136256. +#define TEMP_INLINE_ALL_EXPANSION 1
  136257. +/******************************* IR VERSION ******************/
  136258. +#define gcdSL_IR_VERSION gcmCC('\0','\0','\0','\1')
  136259. +
  136260. +/******************************************************************************\
  136261. +|******************************* SHADER LANGUAGE ******************************|
  136262. +\******************************************************************************/
  136263. +
  136264. + /* allocator/deallocator function pointer */
  136265. +typedef gceSTATUS (*gctAllocatorFunc)(
  136266. + IN gctSIZE_T Bytes,
  136267. + OUT gctPOINTER * Memory
  136268. + );
  136269. +
  136270. +typedef gceSTATUS (*gctDeallocatorFunc)(
  136271. + IN gctPOINTER Memory
  136272. + );
  136273. +
  136274. +typedef gctBOOL (*compareFunc) (
  136275. + IN void * data,
  136276. + IN void * key
  136277. + );
  136278. +
  136279. +typedef struct _gcsListNode gcsListNode;
  136280. +struct _gcsListNode
  136281. +{
  136282. + gcsListNode * next;
  136283. + void * data;
  136284. +};
  136285. +
  136286. +typedef struct _gcsAllocator
  136287. +{
  136288. + gctAllocatorFunc allocate;
  136289. + gctDeallocatorFunc deallocate;
  136290. +} gcsAllocator;
  136291. +
  136292. +/* simple map structure */
  136293. +typedef struct _SimpleMap SimpleMap;
  136294. +struct _SimpleMap
  136295. +{
  136296. + gctUINT32 key;
  136297. + gctUINT32 val;
  136298. + SimpleMap *next;
  136299. + gcsAllocator *allocator;
  136300. +
  136301. +};
  136302. +
  136303. +/* SimpleMap Operations */
  136304. +/* return -1 if not found, otherwise return the mapped value */
  136305. +gctUINT32
  136306. +gcSimpleMap_Find(
  136307. + IN SimpleMap *Map,
  136308. + IN gctUINT32 Key
  136309. + );
  136310. +
  136311. +gceSTATUS
  136312. +gcSimpleMap_Destory(
  136313. + IN SimpleMap * Map,
  136314. + IN gcsAllocator * Allocator
  136315. + );
  136316. +
  136317. +/* Add a pair <Key, Val> to the Map head, the user should be aware that the
  136318. + * map pointer is always changed when adding a new node :
  136319. + *
  136320. + * gcSimpleMap_AddNode(&theMap, key, val, allocator);
  136321. + *
  136322. + */
  136323. +gceSTATUS
  136324. +gcSimpleMap_AddNode(
  136325. + IN SimpleMap ** Map,
  136326. + IN gctUINT32 Key,
  136327. + IN gctUINT32 Val,
  136328. + IN gcsAllocator * Allocator
  136329. + );
  136330. +
  136331. +/* gcsList data structure and related operations */
  136332. +typedef struct _gcsList
  136333. +{
  136334. + gcsListNode *head;
  136335. + gcsListNode *tail;
  136336. + gctINT count;
  136337. + gcsAllocator *allocator;
  136338. +} gcsList;
  136339. +
  136340. +/* List operations */
  136341. +void
  136342. +gcList_Init(
  136343. + IN gcsList *list,
  136344. + IN gcsAllocator *allocator
  136345. + );
  136346. +
  136347. +gceSTATUS
  136348. +gcList_CreateNode(
  136349. + IN void * Data,
  136350. + IN gctAllocatorFunc Allocator,
  136351. + OUT gcsListNode ** ListNode
  136352. + );
  136353. +
  136354. +gceSTATUS
  136355. +gcList_Clean(
  136356. + IN gcsList * List,
  136357. + IN gctBOOL FreeData
  136358. + );
  136359. +
  136360. +gcsListNode *
  136361. +gcList_FindNode(
  136362. + IN gcsList * List,
  136363. + IN void * Key,
  136364. + IN compareFunc compare
  136365. + );
  136366. +
  136367. +gceSTATUS
  136368. +gcList_AddNode(
  136369. + IN gcsList * List,
  136370. + IN void * Data
  136371. + );
  136372. +
  136373. +gceSTATUS
  136374. +gcList_RemoveNode(
  136375. + IN gcsList * List,
  136376. + IN gcsListNode * Node
  136377. + );
  136378. +
  136379. +/* link list structure for code list */
  136380. +typedef gcsList gcsCodeList;
  136381. +typedef gcsCodeList * gctCodeList;
  136382. +typedef gcsListNode gcsCodeListNode;
  136383. +
  136384. +/* Possible shader language opcodes. */
  136385. +typedef enum _gcSL_OPCODE
  136386. +{
  136387. + gcSL_NOP, /* 0x00 */
  136388. + gcSL_MOV, /* 0x01 */
  136389. + gcSL_SAT, /* 0x02 */
  136390. + gcSL_DP3, /* 0x03 */
  136391. + gcSL_DP4, /* 0x04 */
  136392. + gcSL_ABS, /* 0x05 */
  136393. + gcSL_JMP, /* 0x06 */
  136394. + gcSL_ADD, /* 0x07 */
  136395. + gcSL_MUL, /* 0x08 */
  136396. + gcSL_RCP, /* 0x09 */
  136397. + gcSL_SUB, /* 0x0A */
  136398. + gcSL_KILL, /* 0x0B */
  136399. + gcSL_TEXLD, /* 0x0C */
  136400. + gcSL_CALL, /* 0x0D */
  136401. + gcSL_RET, /* 0x0E */
  136402. + gcSL_NORM, /* 0x0F */
  136403. + gcSL_MAX, /* 0x10 */
  136404. + gcSL_MIN, /* 0x11 */
  136405. + gcSL_POW, /* 0x12 */
  136406. + gcSL_RSQ, /* 0x13 */
  136407. + gcSL_LOG, /* 0x14 */
  136408. + gcSL_FRAC, /* 0x15 */
  136409. + gcSL_FLOOR, /* 0x16 */
  136410. + gcSL_CEIL, /* 0x17 */
  136411. + gcSL_CROSS, /* 0x18 */
  136412. + gcSL_TEXLDP, /* 0x19 */
  136413. + gcSL_TEXBIAS, /* 0x1A */
  136414. + gcSL_TEXGRAD, /* 0x1B */
  136415. + gcSL_TEXLOD, /* 0x1C */
  136416. + gcSL_SIN, /* 0x1D */
  136417. + gcSL_COS, /* 0x1E */
  136418. + gcSL_TAN, /* 0x1F */
  136419. + gcSL_EXP, /* 0x20 */
  136420. + gcSL_SIGN, /* 0x21 */
  136421. + gcSL_STEP, /* 0x22 */
  136422. + gcSL_SQRT, /* 0x23 */
  136423. + gcSL_ACOS, /* 0x24 */
  136424. + gcSL_ASIN, /* 0x25 */
  136425. + gcSL_ATAN, /* 0x26 */
  136426. + gcSL_SET, /* 0x27 */
  136427. + gcSL_DSX, /* 0x28 */
  136428. + gcSL_DSY, /* 0x29 */
  136429. + gcSL_FWIDTH, /* 0x2A */
  136430. + gcSL_DIV, /* 0x2B */
  136431. + gcSL_MOD, /* 0x2C */
  136432. + gcSL_AND_BITWISE, /* 0x2D */
  136433. + gcSL_OR_BITWISE, /* 0x2E */
  136434. + gcSL_XOR_BITWISE, /* 0x2F */
  136435. + gcSL_NOT_BITWISE, /* 0x30 */
  136436. + gcSL_LSHIFT, /* 0x31 */
  136437. + gcSL_RSHIFT, /* 0x32 */
  136438. + gcSL_ROTATE, /* 0x33 */
  136439. + gcSL_BITSEL, /* 0x34 */
  136440. + gcSL_LEADZERO, /* 0x35 */
  136441. + gcSL_LOAD, /* 0x36 */
  136442. + gcSL_STORE, /* 0x37 */
  136443. + gcSL_BARRIER, /* 0x38 */
  136444. + gcSL_STORE1, /* 0x39 */
  136445. + gcSL_ATOMADD, /* 0x3A */
  136446. + gcSL_ATOMSUB, /* 0x3B */
  136447. + gcSL_ATOMXCHG, /* 0x3C */
  136448. + gcSL_ATOMCMPXCHG, /* 0x3D */
  136449. + gcSL_ATOMMIN, /* 0x3E */
  136450. + gcSL_ATOMMAX, /* 0x3F */
  136451. + gcSL_ATOMOR, /* 0x40 */
  136452. + gcSL_ATOMAND, /* 0x41 */
  136453. + gcSL_ATOMXOR, /* 0x42 */
  136454. + /*gcSL_UNUSED, 0x43 */
  136455. + /*gcSL_UNUSED, 0x44 */
  136456. + /*gcSL_UNUSED, 0x45 */
  136457. + /*gcSL_UNUSED, 0x46 */
  136458. + /*gcSL_UNUSED, 0x47 */
  136459. + /*gcSL_UNUSED, 0x48 */
  136460. + /*gcSL_UNUSED, 0x49 */
  136461. + /*gcSL_UNUSED, 0x4A */
  136462. + /*gcSL_UNUSED, 0x4B */
  136463. + /*gcSL_UNUSED, 0x4C */
  136464. + /*gcSL_UNUSED, 0x4D */
  136465. + /*gcSL_UNUSED, 0x4E */
  136466. + /*gcSL_UNUSED, 0x4F */
  136467. + /*gcSL_UNUSED, 0x50 */
  136468. + /*gcSL_UNUSED, 0x51 */
  136469. + /*gcSL_UNUSED, 0x52 */
  136470. + gcSL_ADDLO = 0x53, /* 0x53 */ /* Float only. */
  136471. + gcSL_MULLO, /* 0x54 */ /* Float only. */
  136472. + gcSL_CONV, /* 0x55 */
  136473. + gcSL_GETEXP, /* 0x56 */
  136474. + gcSL_GETMANT, /* 0x57 */
  136475. + gcSL_MULHI, /* 0x58 */ /* Integer only. */
  136476. + gcSL_CMP, /* 0x59 */
  136477. + gcSL_I2F, /* 0x5A */
  136478. + gcSL_F2I, /* 0x5B */
  136479. + gcSL_ADDSAT, /* 0x5C */ /* Integer only. */
  136480. + gcSL_SUBSAT, /* 0x5D */ /* Integer only. */
  136481. + gcSL_MULSAT, /* 0x5E */ /* Integer only. */
  136482. + gcSL_DP2, /* 0x5F */
  136483. + gcSL_MAXOPCODE
  136484. +}
  136485. +gcSL_OPCODE;
  136486. +
  136487. +typedef enum _gcSL_FORMAT
  136488. +{
  136489. + gcSL_FLOAT = 0, /* 0 */
  136490. + gcSL_INTEGER = 1, /* 1 */
  136491. + gcSL_INT32 = 1, /* 1 */
  136492. + gcSL_BOOLEAN = 2, /* 2 */
  136493. + gcSL_UINT32 = 3, /* 3 */
  136494. + gcSL_INT8, /* 4 */
  136495. + gcSL_UINT8, /* 5 */
  136496. + gcSL_INT16, /* 6 */
  136497. + gcSL_UINT16, /* 7 */
  136498. + gcSL_INT64, /* 8 */ /* Reserved for future enhancement. */
  136499. + gcSL_UINT64, /* 9 */ /* Reserved for future enhancement. */
  136500. + gcSL_INT128, /* 10 */ /* Reserved for future enhancement. */
  136501. + gcSL_UINT128, /* 11 */ /* Reserved for future enhancement. */
  136502. + gcSL_FLOAT16, /* 12 */
  136503. + gcSL_FLOAT64, /* 13 */ /* Reserved for future enhancement. */
  136504. + gcSL_FLOAT128, /* 14 */ /* Reserved for future enhancement. */
  136505. +}
  136506. +gcSL_FORMAT;
  136507. +
  136508. +/* Destination write enable bits. */
  136509. +typedef enum _gcSL_ENABLE
  136510. +{
  136511. + gcSL_ENABLE_NONE = 0x0, /* none is enabled, error/uninitialized state */
  136512. + gcSL_ENABLE_X = 0x1,
  136513. + gcSL_ENABLE_Y = 0x2,
  136514. + gcSL_ENABLE_Z = 0x4,
  136515. + gcSL_ENABLE_W = 0x8,
  136516. + /* Combinations. */
  136517. + gcSL_ENABLE_XY = gcSL_ENABLE_X | gcSL_ENABLE_Y,
  136518. + gcSL_ENABLE_XYZ = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z,
  136519. + gcSL_ENABLE_XYZW = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W,
  136520. + gcSL_ENABLE_XYW = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_W,
  136521. + gcSL_ENABLE_XZ = gcSL_ENABLE_X | gcSL_ENABLE_Z,
  136522. + gcSL_ENABLE_XZW = gcSL_ENABLE_X | gcSL_ENABLE_Z | gcSL_ENABLE_W,
  136523. + gcSL_ENABLE_XW = gcSL_ENABLE_X | gcSL_ENABLE_W,
  136524. + gcSL_ENABLE_YZ = gcSL_ENABLE_Y | gcSL_ENABLE_Z,
  136525. + gcSL_ENABLE_YZW = gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W,
  136526. + gcSL_ENABLE_YW = gcSL_ENABLE_Y | gcSL_ENABLE_W,
  136527. + gcSL_ENABLE_ZW = gcSL_ENABLE_Z | gcSL_ENABLE_W,
  136528. +}
  136529. +gcSL_ENABLE;
  136530. +
  136531. +/* Possible indices. */
  136532. +typedef enum _gcSL_INDEXED
  136533. +{
  136534. + gcSL_NOT_INDEXED, /* 0 */
  136535. + gcSL_INDEXED_X, /* 1 */
  136536. + gcSL_INDEXED_Y, /* 2 */
  136537. + gcSL_INDEXED_Z, /* 3 */
  136538. + gcSL_INDEXED_W, /* 4 */
  136539. +}
  136540. +gcSL_INDEXED;
  136541. +
  136542. +/* Opcode conditions. */
  136543. +typedef enum _gcSL_CONDITION
  136544. +{
  136545. + gcSL_ALWAYS, /* 0x0 */
  136546. + gcSL_NOT_EQUAL, /* 0x1 */
  136547. + gcSL_LESS_OR_EQUAL, /* 0x2 */
  136548. + gcSL_LESS, /* 0x3 */
  136549. + gcSL_EQUAL, /* 0x4 */
  136550. + gcSL_GREATER, /* 0x5 */
  136551. + gcSL_GREATER_OR_EQUAL, /* 0x6 */
  136552. + gcSL_AND, /* 0x7 */
  136553. + gcSL_OR, /* 0x8 */
  136554. + gcSL_XOR, /* 0x9 */
  136555. + gcSL_NOT_ZERO, /* 0xA */
  136556. +}
  136557. +gcSL_CONDITION;
  136558. +
  136559. +/* Possible source operand types. */
  136560. +typedef enum _gcSL_TYPE
  136561. +{
  136562. + gcSL_NONE, /* 0x0 */
  136563. + gcSL_TEMP, /* 0x1 */
  136564. + gcSL_ATTRIBUTE, /* 0x2 */
  136565. + gcSL_UNIFORM, /* 0x3 */
  136566. + gcSL_SAMPLER, /* 0x4 */
  136567. + gcSL_CONSTANT, /* 0x5 */
  136568. + gcSL_OUTPUT, /* 0x6 */
  136569. + gcSL_PHYSICAL, /* 0x7 */
  136570. +}
  136571. +gcSL_TYPE;
  136572. +
  136573. +/* Swizzle generator macro. */
  136574. +#define gcmSWIZZLE(Component1, Component2, Component3, Component4) \
  136575. +( \
  136576. + (gcSL_SWIZZLE_ ## Component1 << 0) | \
  136577. + (gcSL_SWIZZLE_ ## Component2 << 2) | \
  136578. + (gcSL_SWIZZLE_ ## Component3 << 4) | \
  136579. + (gcSL_SWIZZLE_ ## Component4 << 6) \
  136580. +)
  136581. +
  136582. +#define gcmExtractSwizzle(Swizzle, Index) \
  136583. + ((gcSL_SWIZZLE) ((((Swizzle) >> (Index * 2)) & 0x3)))
  136584. +
  136585. +#define gcmComposeSwizzle(SwizzleX, SwizzleY, SwizzleZ, SwizzleW) \
  136586. +( \
  136587. + ((SwizzleX) << 0) | \
  136588. + ((SwizzleY) << 2) | \
  136589. + ((SwizzleZ) << 4) | \
  136590. + ((SwizzleW) << 6) \
  136591. +)
  136592. +
  136593. +/* Possible swizzle values. */
  136594. +typedef enum _gcSL_SWIZZLE
  136595. +{
  136596. + gcSL_SWIZZLE_X, /* 0x0 */
  136597. + gcSL_SWIZZLE_Y, /* 0x1 */
  136598. + gcSL_SWIZZLE_Z, /* 0x2 */
  136599. + gcSL_SWIZZLE_W, /* 0x3 */
  136600. + /* Combinations. */
  136601. + gcSL_SWIZZLE_XXXX = gcmSWIZZLE(X, X, X, X),
  136602. + gcSL_SWIZZLE_YYYY = gcmSWIZZLE(Y, Y, Y, Y),
  136603. + gcSL_SWIZZLE_ZZZZ = gcmSWIZZLE(Z, Z, Z, Z),
  136604. + gcSL_SWIZZLE_WWWW = gcmSWIZZLE(W, W, W, W),
  136605. + gcSL_SWIZZLE_XYYY = gcmSWIZZLE(X, Y, Y, Y),
  136606. + gcSL_SWIZZLE_XZZZ = gcmSWIZZLE(X, Z, Z, Z),
  136607. + gcSL_SWIZZLE_XWWW = gcmSWIZZLE(X, W, W, W),
  136608. + gcSL_SWIZZLE_YZZZ = gcmSWIZZLE(Y, Z, Z, Z),
  136609. + gcSL_SWIZZLE_YWWW = gcmSWIZZLE(Y, W, W, W),
  136610. + gcSL_SWIZZLE_ZWWW = gcmSWIZZLE(Z, W, W, W),
  136611. + gcSL_SWIZZLE_XYZZ = gcmSWIZZLE(X, Y, Z, Z),
  136612. + gcSL_SWIZZLE_XYWW = gcmSWIZZLE(X, Y, W, W),
  136613. + gcSL_SWIZZLE_XZWW = gcmSWIZZLE(X, Z, W, W),
  136614. + gcSL_SWIZZLE_YZWW = gcmSWIZZLE(Y, Z, W, W),
  136615. + gcSL_SWIZZLE_XXYZ = gcmSWIZZLE(X, X, Y, Z),
  136616. + gcSL_SWIZZLE_XYZW = gcmSWIZZLE(X, Y, Z, W),
  136617. + gcSL_SWIZZLE_XYXY = gcmSWIZZLE(X, Y, X, Y),
  136618. + gcSL_SWIZZLE_YYZZ = gcmSWIZZLE(Y, Y, Z, Z),
  136619. + gcSL_SWIZZLE_YYWW = gcmSWIZZLE(Y, Y, W, W),
  136620. + gcSL_SWIZZLE_ZZZW = gcmSWIZZLE(Z, Z, Z, W),
  136621. + gcSL_SWIZZLE_XZZW = gcmSWIZZLE(X, Z, Z, W),
  136622. + gcSL_SWIZZLE_YYZW = gcmSWIZZLE(Y, Y, Z, W),
  136623. +
  136624. + gcSL_SWIZZLE_INVALID = 0x7FFFFFFF
  136625. +}
  136626. +gcSL_SWIZZLE;
  136627. +
  136628. +typedef enum _gcSL_COMPONENT
  136629. +{
  136630. + gcSL_COMPONENT_X, /* 0x0 */
  136631. + gcSL_COMPONENT_Y, /* 0x1 */
  136632. + gcSL_COMPONENT_Z, /* 0x2 */
  136633. + gcSL_COMPONENT_W, /* 0x3 */
  136634. + gcSL_COMPONENT_COUNT /* 0x4 */
  136635. +} gcSL_COMPONENT;
  136636. +
  136637. +#define gcmIsComponentEnabled(Enable, Component) (((Enable) & (1 << (Component))) != 0)
  136638. +
  136639. +/******************************************************************************\
  136640. +|*********************************** SHADERS **********************************|
  136641. +\******************************************************************************/
  136642. +
  136643. +/* Shader types. */
  136644. +typedef enum _gcSHADER_KIND {
  136645. + gcSHADER_TYPE_UNKNOWN = 0,
  136646. + gcSHADER_TYPE_VERTEX,
  136647. + gcSHADER_TYPE_FRAGMENT,
  136648. + gcSHADER_TYPE_CL,
  136649. + gcSHADER_TYPE_PRECOMPILED,
  136650. + gcSHADER_KIND_COUNT
  136651. +} gcSHADER_KIND;
  136652. +
  136653. +typedef enum _gcGL_DRIVER_VERSION {
  136654. + gcGL_DRIVER_ES11, /* OpenGL ES 1.1 */
  136655. + gcGL_DRIVER_ES20, /* OpenGL ES 2.0 */
  136656. + gcGL_DRIVER_ES30 /* OpenGL ES 3.0 */
  136657. +} gcGL_DRIVER_VERSION;
  136658. +
  136659. +/* gcSHADER objects. */
  136660. +typedef struct _gcSHADER * gcSHADER;
  136661. +typedef struct _gcATTRIBUTE * gcATTRIBUTE;
  136662. +typedef struct _gcUNIFORM * gcUNIFORM;
  136663. +typedef struct _gcOUTPUT * gcOUTPUT;
  136664. +typedef struct _gcsFUNCTION * gcFUNCTION;
  136665. +typedef struct _gcsKERNEL_FUNCTION * gcKERNEL_FUNCTION;
  136666. +typedef struct _gcsHINT * gcsHINT_PTR;
  136667. +typedef struct _gcSHADER_PROFILER * gcSHADER_PROFILER;
  136668. +typedef struct _gcVARIABLE * gcVARIABLE;
  136669. +
  136670. +struct _gcsHINT
  136671. +{
  136672. + /* Numbr of data transfers for Vertex Shader output. */
  136673. + gctUINT32 vsOutputCount;
  136674. +
  136675. + /* Flag whether the VS has point size or not. */
  136676. + gctBOOL vsHasPointSize;
  136677. +
  136678. +#if gcdUSE_WCLIP_PATCH
  136679. + /* Flag whether the VS gl_position.z depends on gl_position.w
  136680. + it's a hint for wclipping */
  136681. + gctBOOL vsPositionZDependsOnW;
  136682. +#endif
  136683. +
  136684. + gctBOOL clipW;
  136685. +
  136686. + /* Flag whether or not the shader has a KILL instruction. */
  136687. + gctBOOL hasKill;
  136688. +
  136689. + /* Element count. */
  136690. + gctUINT32 elementCount;
  136691. +
  136692. + /* Component count. */
  136693. + gctUINT32 componentCount;
  136694. +
  136695. + /* Number of data transfers for Fragment Shader input. */
  136696. + gctUINT32 fsInputCount;
  136697. +
  136698. + /* Maximum number of temporary registers used in FS. */
  136699. + gctUINT32 fsMaxTemp;
  136700. +
  136701. + /* Maximum number of temporary registers used in VS. */
  136702. + gctUINT32 vsMaxTemp;
  136703. +
  136704. + /* Balance minimum. */
  136705. + gctUINT32 balanceMin;
  136706. +
  136707. + /* Balance maximum. */
  136708. + gctUINT32 balanceMax;
  136709. +
  136710. + /* Auto-shift balancing. */
  136711. + gctBOOL autoShift;
  136712. +
  136713. + /* Flag whether the PS outputs the depth value or not. */
  136714. + gctBOOL psHasFragDepthOut;
  136715. +
  136716. + /* Flag whether the ThreadWalker is in PS. */
  136717. + gctBOOL threadWalkerInPS;
  136718. +
  136719. + /* HW reg number for position of VS */
  136720. + gctUINT32 hwRegNoOfSIVPos;
  136721. +
  136722. +#if gcdALPHA_KILL_IN_SHADER
  136723. + /* States to set when alpha kill is enabled. */
  136724. + gctUINT32 killStateAddress;
  136725. + gctUINT32 alphaKillStateValue;
  136726. + gctUINT32 colorKillStateValue;
  136727. +
  136728. + /* Shader instructiuon. */
  136729. + gctUINT32 killInstructionAddress;
  136730. + gctUINT32 alphaKillInstruction[3];
  136731. + gctUINT32 colorKillInstruction[3];
  136732. +#endif
  136733. +
  136734. +#if TEMP_SHADER_PATCH
  136735. + gctUINT32 pachedShaderIdentifier;
  136736. +#endif
  136737. +};
  136738. +
  136739. +#if TEMP_SHADER_PATCH
  136740. +#define INVALID_SHADER_IDENTIFIER 0xFFFFFFFF
  136741. +#endif
  136742. +
  136743. +/* gcSHADER_TYPE enumeration. */
  136744. +typedef enum _gcSHADER_TYPE
  136745. +{
  136746. + gcSHADER_FLOAT_X1 = 0, /* 0x00 */
  136747. + gcSHADER_FLOAT_X2, /* 0x01 */
  136748. + gcSHADER_FLOAT_X3, /* 0x02 */
  136749. + gcSHADER_FLOAT_X4, /* 0x03 */
  136750. + gcSHADER_FLOAT_2X2, /* 0x04 */
  136751. + gcSHADER_FLOAT_3X3, /* 0x05 */
  136752. + gcSHADER_FLOAT_4X4, /* 0x06 */
  136753. + gcSHADER_BOOLEAN_X1, /* 0x07 */
  136754. + gcSHADER_BOOLEAN_X2, /* 0x08 */
  136755. + gcSHADER_BOOLEAN_X3, /* 0x09 */
  136756. + gcSHADER_BOOLEAN_X4, /* 0x0A */
  136757. + gcSHADER_INTEGER_X1, /* 0x0B */
  136758. + gcSHADER_INTEGER_X2, /* 0x0C */
  136759. + gcSHADER_INTEGER_X3, /* 0x0D */
  136760. + gcSHADER_INTEGER_X4, /* 0x0E */
  136761. + gcSHADER_SAMPLER_1D, /* 0x0F */
  136762. + gcSHADER_SAMPLER_2D, /* 0x10 */
  136763. + gcSHADER_SAMPLER_3D, /* 0x11 */
  136764. + gcSHADER_SAMPLER_CUBIC, /* 0x12 */
  136765. + gcSHADER_FIXED_X1, /* 0x13 */
  136766. + gcSHADER_FIXED_X2, /* 0x14 */
  136767. + gcSHADER_FIXED_X3, /* 0x15 */
  136768. + gcSHADER_FIXED_X4, /* 0x16 */
  136769. + gcSHADER_IMAGE_2D, /* 0x17 */ /* For OCL. */
  136770. + gcSHADER_IMAGE_3D, /* 0x18 */ /* For OCL. */
  136771. + gcSHADER_SAMPLER, /* 0x19 */ /* For OCL. */
  136772. + gcSHADER_FLOAT_2X3, /* 0x1A */
  136773. + gcSHADER_FLOAT_2X4, /* 0x1B */
  136774. + gcSHADER_FLOAT_3X2, /* 0x1C */
  136775. + gcSHADER_FLOAT_3X4, /* 0x1D */
  136776. + gcSHADER_FLOAT_4X2, /* 0x1E */
  136777. + gcSHADER_FLOAT_4X3, /* 0x1F */
  136778. + gcSHADER_ISAMPLER_2D, /* 0x20 */
  136779. + gcSHADER_ISAMPLER_3D, /* 0x21 */
  136780. + gcSHADER_ISAMPLER_CUBIC, /* 0x22 */
  136781. + gcSHADER_USAMPLER_2D, /* 0x23 */
  136782. + gcSHADER_USAMPLER_3D, /* 0x24 */
  136783. + gcSHADER_USAMPLER_CUBIC, /* 0x25 */
  136784. + gcSHADER_SAMPLER_EXTERNAL_OES, /* 0x26 */
  136785. +
  136786. + gcSHADER_UINT_X1, /* 0x27 */
  136787. + gcSHADER_UINT_X2, /* 0x28 */
  136788. + gcSHADER_UINT_X3, /* 0x29 */
  136789. + gcSHADER_UINT_X4, /* 0x2A */
  136790. +
  136791. + gcSHADER_UNKONWN_TYPE, /* do not add type after this */
  136792. + gcSHADER_TYPE_COUNT /* must to change gcvShaderTypeInfo at the
  136793. + * same time if you add any new type! */}
  136794. +gcSHADER_TYPE;
  136795. +
  136796. +typedef enum _gcSHADER_TYPE_KIND
  136797. +{
  136798. + gceTK_UNKOWN,
  136799. + gceTK_FLOAT,
  136800. + gceTK_INT,
  136801. + gceTK_UINT,
  136802. + gceTK_BOOL,
  136803. + gceTK_FIXED,
  136804. + gceTK_SAMPLER,
  136805. + gceTK_IMAGE,
  136806. + gceTK_OTHER
  136807. +} gcSHADER_TYPE_KIND;
  136808. +
  136809. +typedef struct _gcSHADER_TYPEINFO
  136810. +{
  136811. + gcSHADER_TYPE type; /* e.g. gcSHADER_FLOAT_2X4 */
  136812. + gctINT components; /* e.g. 4 components */
  136813. + gctINT rows; /* e.g. 2 rows */
  136814. + gcSHADER_TYPE componentType; /* e.g. gcSHADER_FLOAT_X4 */
  136815. + gcSHADER_TYPE_KIND kind; /* e.g. gceTK_FLOAT */
  136816. + gctCONST_STRING name; /* e.g. "FLOAT_2X4" */
  136817. +} gcSHADER_TYPEINFO;
  136818. +
  136819. +extern gcSHADER_TYPEINFO gcvShaderTypeInfo[];
  136820. +
  136821. +#define gcmType_Comonents(Type) (gcvShaderTypeInfo[Type].components)
  136822. +#define gcmType_Rows(Type) (gcvShaderTypeInfo[Type].rows)
  136823. +#define gcmType_ComonentType(Type) (gcvShaderTypeInfo[Type].componentType)
  136824. +#define gcmType_Kind(Type) (gcvShaderTypeInfo[Type].kind)
  136825. +#define gcmType_Name(Type) (gcvShaderTypeInfo[Type].name)
  136826. +
  136827. +#define gcmType_isMatrix(type) (gcmType_Rows(type) > 1)
  136828. +
  136829. +typedef enum _gcSHADER_VAR_CATEGORY
  136830. +{
  136831. + gcSHADER_VAR_CATEGORY_NORMAL = 0, /* primitive type and its array */
  136832. + gcSHADER_VAR_CATEGORY_STRUCT = 1 /* structure */
  136833. +}
  136834. +gcSHADER_VAR_CATEGORY;
  136835. +
  136836. +typedef enum _gceTYPE_QUALIFIER
  136837. +{
  136838. + gcvTYPE_QUALIFIER_NONE = 0x0, /* unqualified */
  136839. + gcvTYPE_QUALIFIER_VOLATILE = 0x1, /* volatile */
  136840. +}gceTYPE_QUALIFIER;
  136841. +
  136842. +typedef gctUINT16 gctTYPE_QUALIFIER;
  136843. +
  136844. +#if GC_ENABLE_LOADTIME_OPT
  136845. +typedef struct _gcSHADER_TYPE_INFO
  136846. +{
  136847. + gcSHADER_TYPE type; /* eg. gcSHADER_FLOAT_2X3 is the type */
  136848. + gctCONST_STRING name; /* the name of the type: "gcSHADER_FLOAT_2X3" */
  136849. + gcSHADER_TYPE baseType; /* its base type is gcSHADER_FLOAT_2 */
  136850. + gctINT components; /* it has 2 components */
  136851. + gctINT rows; /* and 3 rows */
  136852. + gctINT size; /* the size in byte */
  136853. +} gcSHADER_TYPE_INFO;
  136854. +
  136855. +extern gcSHADER_TYPE_INFO shader_type_info[];
  136856. +
  136857. +enum gceLTCDumpOption {
  136858. + gceLTC_DUMP_UNIFORM = 0x0001,
  136859. + gceLTC_DUMP_EVALUATION = 0x0002,
  136860. + gceLTC_DUMP_EXPESSION = 0x0004,
  136861. + gceLTC_DUMP_COLLECTING = 0x0008,
  136862. +};
  136863. +
  136864. +gctBOOL gcDumpOption(gctINT Opt);
  136865. +
  136866. +#endif /* GC_ENABLE_LOADTIME_OPT */
  136867. +
  136868. +#define IS_MATRIX_TYPE(type) \
  136869. + (((type >= gcSHADER_FLOAT_2X2) && (type <= gcSHADER_FLOAT_4X4)) || \
  136870. + ((type >= gcSHADER_FLOAT_2X3) && (type <= gcSHADER_FLOAT_4X3)))
  136871. +
  136872. +/* gcSHADER_PRECISION enumeration. */
  136873. +typedef enum _gcSHADER_PRECISION
  136874. +{
  136875. + gcSHADER_PRECISION_DEFAULT, /* 0x00 */
  136876. + gcSHADER_PRECISION_HIGH, /* 0x01 */
  136877. + gcSHADER_PRECISION_MEDIUM, /* 0x02 */
  136878. + gcSHADER_PRECISION_LOW, /* 0x03 */
  136879. +}
  136880. +gcSHADER_PRECISION;
  136881. +
  136882. +/* Shader flags. */
  136883. +typedef enum _gceSHADER_FLAGS
  136884. +{
  136885. + gcvSHADER_NO_OPTIMIZATION = 0x00,
  136886. + gcvSHADER_DEAD_CODE = 0x01,
  136887. + gcvSHADER_RESOURCE_USAGE = 0x02,
  136888. + gcvSHADER_OPTIMIZER = 0x04,
  136889. + gcvSHADER_USE_GL_Z = 0x08,
  136890. + /*
  136891. + The GC family of GPU cores model GC860 and under require the Z
  136892. + to be from 0 <= z <= w.
  136893. + However, OpenGL specifies the Z to be from -w <= z <= w. So we
  136894. + have to a conversion here:
  136895. +
  136896. + z = (z + w) / 2.
  136897. +
  136898. + So here we append two instructions to the vertex shader.
  136899. + */
  136900. + gcvSHADER_USE_GL_POSITION = 0x10,
  136901. + gcvSHADER_USE_GL_FACE = 0x20,
  136902. + gcvSHADER_USE_GL_POINT_COORD = 0x40,
  136903. + gcvSHADER_LOADTIME_OPTIMIZER = 0x80,
  136904. +#if gcdALPHA_KILL_IN_SHADER
  136905. + gcvSHADER_USE_ALPHA_KILL = 0x100,
  136906. +#endif
  136907. +
  136908. +#if gcdPRE_ROTATION && (ANDROID_SDK_VERSION >= 14)
  136909. + gcvSHADER_VS_PRE_ROTATION = 0x200,
  136910. +#endif
  136911. +
  136912. +#if TEMP_INLINE_ALL_EXPANSION
  136913. + gcvSHADER_INLINE_ALL_EXPANSION = 0x400,
  136914. +#endif
  136915. +}
  136916. +gceSHADER_FLAGS;
  136917. +
  136918. +gceSTATUS
  136919. +gcSHADER_CheckClipW(
  136920. + IN gctCONST_STRING VertexSource,
  136921. + IN gctCONST_STRING FragmentSource,
  136922. + OUT gctBOOL * clipW);
  136923. +
  136924. +/*******************************************************************************
  136925. +** gcSHADER_GetUniformVectorCount
  136926. +**
  136927. +** Get the number of vectors used by uniforms for this shader.
  136928. +**
  136929. +** INPUT:
  136930. +**
  136931. +** gcSHADER Shader
  136932. +** Pointer to a gcSHADER object.
  136933. +**
  136934. +** OUTPUT:
  136935. +**
  136936. +** gctSIZE_T * Count
  136937. +** Pointer to a variable receiving the number of vectors.
  136938. +*/
  136939. +gceSTATUS
  136940. +gcSHADER_GetUniformVectorCount(
  136941. + IN gcSHADER Shader,
  136942. + OUT gctSIZE_T * Count
  136943. + );
  136944. +
  136945. +/*******************************************************************************
  136946. +** gcOptimizer Data Structures
  136947. +*******************************************************************************/
  136948. +typedef enum _gceSHADER_OPTIMIZATION
  136949. +{
  136950. + /* No optimization. */
  136951. + gcvOPTIMIZATION_NONE,
  136952. +
  136953. + /* Flow graph construction. */
  136954. + gcvOPTIMIZATION_CONSTRUCTION = 1 << 0,
  136955. +
  136956. + /* Dead code elimination. */
  136957. + gcvOPTIMIZATION_DEAD_CODE = 1 << 1,
  136958. +
  136959. + /* Redundant move instruction elimination. */
  136960. + gcvOPTIMIZATION_REDUNDANT_MOVE = 1 << 2,
  136961. +
  136962. + /* Inline expansion. */
  136963. + gcvOPTIMIZATION_INLINE_EXPANSION = 1 << 3,
  136964. +
  136965. + /* Constant propagation. */
  136966. + gcvOPTIMIZATION_CONSTANT_PROPAGATION = 1 << 4,
  136967. +
  136968. + /* Redundant bounds/checking elimination. */
  136969. + gcvOPTIMIZATION_REDUNDANT_CHECKING = 1 << 5,
  136970. +
  136971. + /* Loop invariant movement. */
  136972. + gcvOPTIMIZATION_LOOP_INVARIANT = 1 << 6,
  136973. +
  136974. + /* Induction variable removal. */
  136975. + gcvOPTIMIZATION_INDUCTION_VARIABLE = 1 << 7,
  136976. +
  136977. + /* Common subexpression elimination. */
  136978. + gcvOPTIMIZATION_COMMON_SUBEXPRESSION = 1 << 8,
  136979. +
  136980. + /* Control flow/banch optimization. */
  136981. + gcvOPTIMIZATION_CONTROL_FLOW = 1 << 9,
  136982. +
  136983. + /* Vector component operation merge. */
  136984. + gcvOPTIMIZATION_VECTOR_INSTRUCTION_MERGE = 1 << 10,
  136985. +
  136986. + /* Algebra simplificaton. */
  136987. + gcvOPTIMIZATION_ALGEBRAIC_SIMPLIFICATION = 1 << 11,
  136988. +
  136989. + /* Pattern matching and replacing. */
  136990. + gcvOPTIMIZATION_PATTERN_MATCHING = 1 << 12,
  136991. +
  136992. + /* Interprocedural constant propagation. */
  136993. + gcvOPTIMIZATION_IP_CONSTANT_PROPAGATION = 1 << 13,
  136994. +
  136995. + /* Interprecedural register optimization. */
  136996. + gcvOPTIMIZATION_IP_REGISTRATION = 1 << 14,
  136997. +
  136998. + /* Optimization option number. */
  136999. + gcvOPTIMIZATION_OPTION_NUMBER = 1 << 15,
  137000. +
  137001. + /* Loadtime constant. */
  137002. + gcvOPTIMIZATION_LOADTIME_CONSTANT = 1 << 16,
  137003. +
  137004. + /* MAD instruction optimization. */
  137005. + gcvOPTIMIZATION_MAD_INSTRUCTION = 1 << 17,
  137006. +
  137007. + /* Special optimization for LOAD SW workaround. */
  137008. + gcvOPTIMIZATION_LOAD_SW_WORKAROUND = 1 << 18,
  137009. +
  137010. + /* move code into conditional block if possile */
  137011. + gcvOPTIMIZATION_CONDITIONALIZE = 1 << 19,
  137012. +
  137013. + /* expriemental: power optimization mode
  137014. + 1. add extra dummy texld to tune performance
  137015. + 2. insert NOP after high power instrucitons
  137016. + 3. split high power vec3/vec4 instruciton to vec2/vec1 operation
  137017. + 4. ...
  137018. + */
  137019. + gcvOPTIMIZATION_POWER_OPTIMIZATION = 1 << 20,
  137020. +
  137021. + /* optimize varying packing */
  137022. + gcvOPTIMIZATION_VARYINGPACKING = 1 << 22,
  137023. +
  137024. +#if TEMP_INLINE_ALL_EXPANSION
  137025. + gcvOPTIMIZATION_INLINE_ALL_EXPANSION = 1 << 23,
  137026. +#endif
  137027. +
  137028. + /* Full optimization. */
  137029. + /* Note that gcvOPTIMIZATION_LOAD_SW_WORKAROUND is off. */
  137030. + gcvOPTIMIZATION_FULL = 0x7FFFFFFF &
  137031. + ~gcvOPTIMIZATION_LOAD_SW_WORKAROUND &
  137032. + ~gcvOPTIMIZATION_INLINE_ALL_EXPANSION &
  137033. + ~gcvOPTIMIZATION_POWER_OPTIMIZATION,
  137034. +
  137035. + /* Optimization Unit Test flag. */
  137036. + gcvOPTIMIZATION_UNIT_TEST = 1 << 31
  137037. +}
  137038. +gceSHADER_OPTIMIZATION;
  137039. +
  137040. +typedef enum _gceOPTIMIZATION_VaryingPaking
  137041. +{
  137042. + gcvOPTIMIZATION_VARYINGPACKING_NONE = 0,
  137043. + gcvOPTIMIZATION_VARYINGPACKING_NOSPLIT,
  137044. + gcvOPTIMIZATION_VARYINGPACKING_SPLIT
  137045. +} gceOPTIMIZATION_VaryingPaking;
  137046. +
  137047. +typedef struct _gcOPTIMIZER_OPTION
  137048. +{
  137049. + gceSHADER_OPTIMIZATION optFlags;
  137050. +
  137051. + /* debug & dump options:
  137052. +
  137053. + VC_OPTION=-DUMP:SRC:OPT|:OPTV|:CG|:CGV:|ALL|ALLV
  137054. +
  137055. + SRC: dump shader source code
  137056. + OPT: dump incoming and final IR
  137057. + OPTV: dump result IR in each optimization phase
  137058. + CG: dump generated machine code
  137059. + CGV: dump BE tree and optimization detail
  137060. +
  137061. + ALL = SRC|OPT|CG
  137062. + ALLV = SRC|OPT|OPTV|CG|CGV
  137063. + */
  137064. + gctBOOL dumpShaderSource; /* dump shader source code */
  137065. + gctBOOL dumpOptimizer; /* dump incoming and final IR */
  137066. + gctBOOL dumpOptimizerVerbose; /* dump result IR in each optimization phase */
  137067. + gctBOOL dumpBEGenertedCode; /* dump generated machine code */
  137068. + gctBOOL dumpBEVerbose; /* dump BE tree and optimization detail */
  137069. + gctBOOL dumpBEFinalIR; /* dump BE final IR */
  137070. +
  137071. + /* Code generation */
  137072. +
  137073. + /* Varying Packing:
  137074. +
  137075. + VC_OPTION=-PACKVARYING:[0-2]|:T[-]m[,n]|:LshaderIdx,min,max
  137076. +
  137077. + 0: turn off varying packing
  137078. + 1: pack varyings, donot split any varying
  137079. + 2: pack varyings, may split to make fully packed output
  137080. +
  137081. + Tm: only packing shader pair which vertex shader id is m
  137082. + Tm,n: only packing shader pair which vertex shader id
  137083. + is in range of [m, n]
  137084. + T-m: do not packing shader pair which vertex shader id is m
  137085. + T-m,n: do not packing shader pair which vertex shader id
  137086. + is in range of [m, n]
  137087. +
  137088. + LshaderIdx,min,max : set load balance (min, max) for shaderIdx
  137089. + if shaderIdx is -1, all shaders are impacted
  137090. + newMin = origMin * (min/100.);
  137091. + newMax = origMax * (max/100.);
  137092. + */
  137093. + gceOPTIMIZATION_VaryingPaking packVarying;
  137094. + gctINT _triageStart;
  137095. + gctINT _triageEnd;
  137096. + gctINT _loadBalanceShaderIdx;
  137097. + gctINT _loadBalanceMin;
  137098. + gctINT _loadBalanceMax;
  137099. +
  137100. + /* Do not generate immdeiate
  137101. +
  137102. + VC_OPTION=-NOIMM
  137103. +
  137104. + Force generate immediate even the machine model don't support it,
  137105. + for testing purpose only
  137106. +
  137107. + VC_OPTION=-FORCEIMM
  137108. + */
  137109. + gctBOOL noImmediate;
  137110. + gctBOOL forceImmediate;
  137111. +
  137112. + /* Power reduction mode options */
  137113. + gctBOOL needPowerOptimization;
  137114. +
  137115. + /* Patch TEXLD instruction by adding dummy texld
  137116. + (can be used to tune GPU power usage):
  137117. + for every TEXLD we seen, add n dummy TEXLD
  137118. +
  137119. + it can be enabled by environment variable:
  137120. +
  137121. + VC_OPTION=-PATCH_TEXLD:M:N
  137122. +
  137123. + (for each M texld, add N dummy texld)
  137124. + */
  137125. + gctINT patchEveryTEXLDs;
  137126. + gctINT patchDummyTEXLDs;
  137127. +
  137128. + /* Insert NOP after high power consumption instructions
  137129. +
  137130. + VC_OPTION="-INSERTNOP:MUL:MULLO:DP3:DP4:SEENTEXLD"
  137131. + */
  137132. + gctBOOL insertNOP;
  137133. + gctBOOL insertNOPAfterMUL;
  137134. + gctBOOL insertNOPAfterMULLO;
  137135. + gctBOOL insertNOPAfterDP3;
  137136. + gctBOOL insertNOPAfterDP4;
  137137. + gctBOOL insertNOPOnlyWhenTexldSeen;
  137138. +
  137139. + /* split MAD to MUL and ADD:
  137140. +
  137141. + VC_OPTION=-SPLITMAD
  137142. + */
  137143. + gctBOOL splitMAD;
  137144. +
  137145. + /* Convert vect3/vec4 operations to multiple vec2/vec1 operations
  137146. +
  137147. + VC_OPTION=-SPLITVEC:MUL:MULLO:DP3:DP4
  137148. + */
  137149. + gctBOOL splitVec;
  137150. + gctBOOL splitVec4MUL;
  137151. + gctBOOL splitVec4MULLO;
  137152. + gctBOOL splitVec4DP3;
  137153. + gctBOOL splitVec4DP4;
  137154. +
  137155. + /* turn/off features:
  137156. +
  137157. + VC_OPTION=-F:n,[0|1]
  137158. + Note: n must be decimal number
  137159. + */
  137160. + gctUINT featureBits;
  137161. +
  137162. + /* inline level (default 2 at O1):
  137163. +
  137164. + VC_OPTION=-INLINELEVEL:[0-3]
  137165. + 0: no inline
  137166. + 1: only inline the function only called once or small function
  137167. + 2: inline functions be called less than 5 times or medium size function
  137168. + 3: inline everything possible
  137169. + */
  137170. + gctUINT inlineLevel;
  137171. +} gcOPTIMIZER_OPTION;
  137172. +
  137173. +extern gcOPTIMIZER_OPTION theOptimizerOption;
  137174. +#define gcmGetOptimizerOption() gcGetOptimizerOption()
  137175. +
  137176. +#define gcmOPT_DUMP_SHADER_SRC() \
  137177. + (gcmGetOptimizerOption()->dumpShaderSource != 0)
  137178. +#define gcmOPT_DUMP_OPTIMIZER() \
  137179. + (gcmGetOptimizerOption()->dumpOptimizer != 0 || \
  137180. + gcmOPT_DUMP_OPTIMIZER_VERBOSE() )
  137181. +#define gcmOPT_DUMP_OPTIMIZER_VERBOSE() \
  137182. + (gcmGetOptimizerOption()->dumpOptimizerVerbose != 0)
  137183. +#define gcmOPT_DUMP_CODEGEN() \
  137184. + (gcmGetOptimizerOption()->dumpBEGenertedCode != 0 || \
  137185. + gcmOPT_DUMP_CODEGEN_VERBOSE() )
  137186. +#define gcmOPT_DUMP_CODEGEN_VERBOSE() \
  137187. + (gcmGetOptimizerOption()->dumpBEVerbose != 0)
  137188. +#define gcmOPT_DUMP_FINAL_IR() \
  137189. + (gcmGetOptimizerOption()->dumpBEFinalIR != 0)
  137190. +
  137191. +#define gcmOPT_SET_DUMP_SHADER_SRC(v) \
  137192. + gcmGetOptimizerOption()->dumpShaderSource = (v)
  137193. +
  137194. +#define gcmOPT_PATCH_TEXLD() (gcmGetOptimizerOption()->patchDummyTEXLDs != 0)
  137195. +#define gcmOPT_INSERT_NOP() (gcmGetOptimizerOption()->insertNOP == gcvTRUE)
  137196. +#define gcmOPT_SPLITMAD() (gcmGetOptimizerOption()->splitMAD == gcvTRUE)
  137197. +#define gcmOPT_SPLITVEC() (gcmGetOptimizerOption()->splitVec == gcvTRUE)
  137198. +
  137199. +#define gcmOPT_NOIMMEDIATE() (gcmGetOptimizerOption()->noImmediate == gcvTRUE)
  137200. +#define gcmOPT_FORCEIMMEDIATE() (gcmGetOptimizerOption()->forceImmediate == gcvTRUE)
  137201. +
  137202. +#define gcmOPT_PACKVARYING() (gcmGetOptimizerOption()->packVarying)
  137203. +#define gcmOPT_PACKVARYING_triageStart() (gcmGetOptimizerOption()->_triageStart)
  137204. +#define gcmOPT_PACKVARYING_triageEnd() (gcmGetOptimizerOption()->_triageEnd)
  137205. +
  137206. +#define gcmOPT_INLINELEVEL() (gcmGetOptimizerOption()->inlineLevel)
  137207. +
  137208. +/* Setters */
  137209. +#define gcmOPT_SetPatchTexld(m,n) (gcmGetOptimizerOption()->patchEveryTEXLDs = (m),\
  137210. + gcmGetOptimizerOption()->patchDummyTEXLDs = (n))
  137211. +#define gcmOPT_SetSplitVecMUL() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  137212. + gcmGetOptimizerOption()->splitVec4MUL = gcvTRUE)
  137213. +#define gcmOPT_SetSplitVecMULLO() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  137214. + gcmGetOptimizerOption()->splitVec4MULLO = gcvTRUE)
  137215. +#define gcmOPT_SetSplitVecDP3() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  137216. + gcmGetOptimizerOption()->splitVec4DP3 = gcvTRUE)
  137217. +#define gcmOPT_SetSplitVecDP4() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  137218. + gcmGetOptimizerOption()->splitVec4DP4 = gcvTRUE)
  137219. +
  137220. +#define gcmOPT_SetPackVarying(v) (gcmGetOptimizerOption()->packVarying = v)
  137221. +
  137222. +#define FB_LIVERANGE_FIX1 0x0001
  137223. +
  137224. +
  137225. +#define PredefinedDummySamplerId 8
  137226. +
  137227. +/* Function argument qualifier */
  137228. +typedef enum _gceINPUT_OUTPUT
  137229. +{
  137230. + gcvFUNCTION_INPUT,
  137231. + gcvFUNCTION_OUTPUT,
  137232. + gcvFUNCTION_INOUT
  137233. +}
  137234. +gceINPUT_OUTPUT;
  137235. +
  137236. +/* Kernel function property flags. */
  137237. +typedef enum _gcePROPERTY_FLAGS
  137238. +{
  137239. + gcvPROPERTY_REQD_WORK_GRP_SIZE = 0x01
  137240. +}
  137241. +gceKERNEL_FUNCTION_PROPERTY_FLAGS;
  137242. +
  137243. +/* Uniform flags. */
  137244. +typedef enum _gceUNIFORM_FLAGS
  137245. +{
  137246. + gcvUNIFORM_KERNEL_ARG = 0x01,
  137247. + gcvUNIFORM_KERNEL_ARG_LOCAL = 0x02,
  137248. + gcvUNIFORM_KERNEL_ARG_SAMPLER = 0x04,
  137249. + gcvUNIFORM_LOCAL_ADDRESS_SPACE = 0x08,
  137250. + gcvUNIFORM_PRIVATE_ADDRESS_SPACE = 0x10,
  137251. + gcvUNIFORM_CONSTANT_ADDRESS_SPACE = 0x20,
  137252. + gcvUNIFORM_GLOBAL_SIZE = 0x40,
  137253. + gcvUNIFORM_LOCAL_SIZE = 0x80,
  137254. + gcvUNIFORM_NUM_GROUPS = 0x100,
  137255. + gcvUNIFORM_GLOBAL_OFFSET = 0x200,
  137256. + gcvUNIFORM_WORK_DIM = 0x400,
  137257. + gcvUNIFORM_KERNEL_ARG_CONSTANT = 0x800,
  137258. + gcvUNIFORM_KERNEL_ARG_LOCAL_MEM_SIZE = 0x1000,
  137259. + gcvUNIFORM_KERNEL_ARG_PRIVATE = 0x2000,
  137260. + gcvUNIFORM_LOADTIME_CONSTANT = 0x4000,
  137261. + gcvUNIFORM_IS_ARRAY = 0x8000,
  137262. +}
  137263. +gceUNIFORM_FLAGS;
  137264. +
  137265. +#define gcdUNIFORM_KERNEL_ARG_MASK (gcvUNIFORM_KERNEL_ARG | \
  137266. + gcvUNIFORM_KERNEL_ARG_LOCAL | \
  137267. + gcvUNIFORM_KERNEL_ARG_SAMPLER | \
  137268. + gcvUNIFORM_KERNEL_ARG_PRIVATE | \
  137269. + gcvUNIFORM_KERNEL_ARG_CONSTANT)
  137270. +
  137271. +typedef enum _gceVARIABLE_UPDATE_FLAGS
  137272. +{
  137273. + gcvVARIABLE_UPDATE_NOUPDATE = 0,
  137274. + gcvVARIABLE_UPDATE_TEMPREG,
  137275. + gcvVARIABLE_UPDATE_TYPE_QUALIFIER,
  137276. +}gceVARIABLE_UPDATE_FLAGS;
  137277. +
  137278. +typedef struct _gcMACHINE_INST
  137279. +{
  137280. + gctUINT state0;
  137281. + gctUINT state1;
  137282. + gctUINT state2;
  137283. + gctUINT state3;
  137284. +}gcMACHINE_INST, *gcMACHINE_INST_PTR;
  137285. +
  137286. +typedef struct _gcMACHINECODE
  137287. +{
  137288. + gcMACHINE_INST_PTR pCode; /* machine code */
  137289. + gctUINT instCount; /* 128-bit count */
  137290. + gctUINT maxConstRegNo;
  137291. + gctUINT maxTempRegNo;
  137292. + gctUINT endPCOfMainRoutine;
  137293. +}gcMACHINECODE, *gcMACHINECODE_PTR;
  137294. +
  137295. +typedef enum NP2_ADDRESS_MODE
  137296. +{
  137297. + NP2_ADDRESS_MODE_CLAMP = 0,
  137298. + NP2_ADDRESS_MODE_REPEAT = 1,
  137299. + NP2_ADDRESS_MODE_MIRROR = 2
  137300. +}NP2_ADDRESS_MODE;
  137301. +
  137302. +typedef struct _gcNPOT_PATCH_PARAM
  137303. +{
  137304. + gctINT samplerSlot;
  137305. + NP2_ADDRESS_MODE addressMode[3];
  137306. + gctINT texDimension; /* 2 or 3 */
  137307. +}gcNPOT_PATCH_PARAM, *gcNPOT_PATCH_PARAM_PTR;
  137308. +
  137309. +typedef struct _gcZBIAS_PATCH_PARAM
  137310. +{
  137311. + /* Driver uses this to program uniform that designating zbias */
  137312. + gctINT uniformAddr;
  137313. + gctINT channel;
  137314. +}gcZBIAS_PATCH_PARAM, *gcZBIAS_PATCH_PARAM_PTR;
  137315. +
  137316. +void
  137317. +gcGetOptionFromEnv(
  137318. + IN OUT gcOPTIMIZER_OPTION * Option
  137319. + );
  137320. +
  137321. +void
  137322. +gcSetOptimizerOption(
  137323. + IN gceSHADER_FLAGS Flags
  137324. + );
  137325. +
  137326. +gcOPTIMIZER_OPTION *
  137327. +gcGetOptimizerOption();
  137328. +
  137329. +/*******************************************************************************
  137330. +** gcSHADER_SetCompilerVersion
  137331. +**
  137332. +** Set the compiler version of a gcSHADER object.
  137333. +**
  137334. +** INPUT:
  137335. +**
  137336. +** gcSHADER Shader
  137337. +** Pointer to gcSHADER object
  137338. +**
  137339. +** gctINT *Version
  137340. +** Pointer to a two word version
  137341. +*/
  137342. +gceSTATUS
  137343. +gcSHADER_SetCompilerVersion(
  137344. + IN gcSHADER Shader,
  137345. + IN gctUINT32 *Version
  137346. + );
  137347. +
  137348. +/*******************************************************************************
  137349. +** gcSHADER_GetCompilerVersion
  137350. +**
  137351. +** Get the compiler version of a gcSHADER object.
  137352. +**
  137353. +** INPUT:
  137354. +**
  137355. +** gcSHADER Shader
  137356. +** Pointer to a gcSHADER object.
  137357. +**
  137358. +** OUTPUT:
  137359. +**
  137360. +** gctUINT32_PTR *CompilerVersion.
  137361. +** Pointer to holder of returned compilerVersion pointer
  137362. +*/
  137363. +gceSTATUS
  137364. +gcSHADER_GetCompilerVersion(
  137365. + IN gcSHADER Shader,
  137366. + OUT gctUINT32_PTR *CompilerVersion
  137367. + );
  137368. +
  137369. +/*******************************************************************************
  137370. +** gcSHADER_GetType
  137371. +**
  137372. +** Get the gcSHADER object's type.
  137373. +**
  137374. +** INPUT:
  137375. +**
  137376. +** gcSHADER Shader
  137377. +** Pointer to a gcSHADER object.
  137378. +**
  137379. +** OUTPUT:
  137380. +**
  137381. +** gctINT *Type.
  137382. +** Pointer to return shader type.
  137383. +*/
  137384. +gceSTATUS
  137385. +gcSHADER_GetType(
  137386. + IN gcSHADER Shader,
  137387. + OUT gctINT *Type
  137388. + );
  137389. +
  137390. +gctUINT
  137391. +gcSHADER_NextId();
  137392. +/*******************************************************************************
  137393. +** gcSHADER_Construct
  137394. +********************************************************************************
  137395. +**
  137396. +** Construct a new gcSHADER object.
  137397. +**
  137398. +** INPUT:
  137399. +**
  137400. +** gcoOS Hal
  137401. +** Pointer to an gcoHAL object.
  137402. +**
  137403. +** gctINT ShaderType
  137404. +** Type of gcSHADER object to cerate. 'ShaderType' can be one of the
  137405. +** following:
  137406. +**
  137407. +** gcSHADER_TYPE_VERTEX Vertex shader.
  137408. +** gcSHADER_TYPE_FRAGMENT Fragment shader.
  137409. +**
  137410. +** OUTPUT:
  137411. +**
  137412. +** gcSHADER * Shader
  137413. +** Pointer to a variable receiving the gcSHADER object pointer.
  137414. +*/
  137415. +gceSTATUS
  137416. +gcSHADER_Construct(
  137417. + IN gcoHAL Hal,
  137418. + IN gctINT ShaderType,
  137419. + OUT gcSHADER * Shader
  137420. + );
  137421. +
  137422. +/*******************************************************************************
  137423. +** gcSHADER_Destroy
  137424. +********************************************************************************
  137425. +**
  137426. +** Destroy a gcSHADER object.
  137427. +**
  137428. +** INPUT:
  137429. +**
  137430. +** gcSHADER Shader
  137431. +** Pointer to a gcSHADER object.
  137432. +**
  137433. +** OUTPUT:
  137434. +**
  137435. +** Nothing.
  137436. +*/
  137437. +gceSTATUS
  137438. +gcSHADER_Destroy(
  137439. + IN gcSHADER Shader
  137440. + );
  137441. +
  137442. +/*******************************************************************************
  137443. +** gcSHADER_Copy
  137444. +********************************************************************************
  137445. +**
  137446. +** Copy a gcSHADER object.
  137447. +**
  137448. +** INPUT:
  137449. +**
  137450. +** gcSHADER Shader
  137451. +** Pointer to a gcSHADER object.
  137452. +**
  137453. +** gcSHADER Source
  137454. +** Pointer to a gcSHADER object that will be copied.
  137455. +**
  137456. +** OUTPUT:
  137457. +**
  137458. +** Nothing.
  137459. +*/
  137460. +gceSTATUS
  137461. +gcSHADER_Copy(
  137462. + IN gcSHADER Shader,
  137463. + IN gcSHADER Source
  137464. + );
  137465. +
  137466. +/*******************************************************************************
  137467. +** gcSHADER_LoadHeader
  137468. +**
  137469. +** Load a gcSHADER object from a binary buffer. The binary buffer is layed out
  137470. +** as follows:
  137471. +** // Six word header
  137472. +** // Signature, must be 'S','H','D','R'.
  137473. +** gctINT8 signature[4];
  137474. +** gctUINT32 binFileVersion;
  137475. +** gctUINT32 compilerVersion[2];
  137476. +** gctUINT32 gcSLVersion;
  137477. +** gctUINT32 binarySize;
  137478. +**
  137479. +** INPUT:
  137480. +**
  137481. +** gcSHADER Shader
  137482. +** Pointer to a gcSHADER object.
  137483. +** Shader type will be returned if type in shader object is not gcSHADER_TYPE_PRECOMPILED
  137484. +**
  137485. +** gctPOINTER Buffer
  137486. +** Pointer to a binary buffer containing the shader data to load.
  137487. +**
  137488. +** gctSIZE_T BufferSize
  137489. +** Number of bytes inside the binary buffer pointed to by 'Buffer'.
  137490. +**
  137491. +** OUTPUT:
  137492. +** nothing
  137493. +**
  137494. +*/
  137495. +gceSTATUS
  137496. +gcSHADER_LoadHeader(
  137497. + IN gcSHADER Shader,
  137498. + IN gctPOINTER Buffer,
  137499. + IN gctSIZE_T BufferSize,
  137500. + OUT gctUINT32 * ShaderVersion
  137501. + );
  137502. +
  137503. +/*******************************************************************************
  137504. +** gcSHADER_LoadKernel
  137505. +**
  137506. +** Load a kernel function given by name into gcSHADER object
  137507. +**
  137508. +** INPUT:
  137509. +**
  137510. +** gcSHADER Shader
  137511. +** Pointer to a gcSHADER object.
  137512. +**
  137513. +** gctSTRING KernelName
  137514. +** Pointer to a kernel function name
  137515. +**
  137516. +** OUTPUT:
  137517. +** nothing
  137518. +**
  137519. +*/
  137520. +gceSTATUS
  137521. +gcSHADER_LoadKernel(
  137522. + IN gcSHADER Shader,
  137523. + IN gctSTRING KernelName
  137524. + );
  137525. +
  137526. +/*******************************************************************************
  137527. +** gcSHADER_Load
  137528. +********************************************************************************
  137529. +**
  137530. +** Load a gcSHADER object from a binary buffer.
  137531. +**
  137532. +** INPUT:
  137533. +**
  137534. +** gcSHADER Shader
  137535. +** Pointer to a gcSHADER object.
  137536. +**
  137537. +** gctPOINTER Buffer
  137538. +** Pointer to a binary buffer containg the shader data to load.
  137539. +**
  137540. +** gctSIZE_T BufferSize
  137541. +** Number of bytes inside the binary buffer pointed to by 'Buffer'.
  137542. +**
  137543. +** OUTPUT:
  137544. +**
  137545. +** Nothing.
  137546. +*/
  137547. +gceSTATUS
  137548. +gcSHADER_Load(
  137549. + IN gcSHADER Shader,
  137550. + IN gctPOINTER Buffer,
  137551. + IN gctSIZE_T BufferSize
  137552. + );
  137553. +
  137554. +/*******************************************************************************
  137555. +** gcSHADER_Save
  137556. +********************************************************************************
  137557. +**
  137558. +** Save a gcSHADER object to a binary buffer.
  137559. +**
  137560. +** INPUT:
  137561. +**
  137562. +** gcSHADER Shader
  137563. +** Pointer to a gcSHADER object.
  137564. +**
  137565. +** gctPOINTER Buffer
  137566. +** Pointer to a binary buffer to be used as storage for the gcSHADER
  137567. +** object. If 'Buffer' is gcvNULL, the gcSHADER object will not be saved,
  137568. +** but the number of bytes required to hold the binary output for the
  137569. +** gcSHADER object will be returned.
  137570. +**
  137571. +** gctSIZE_T * BufferSize
  137572. +** Pointer to a variable holding the number of bytes allocated in
  137573. +** 'Buffer'. Only valid if 'Buffer' is not gcvNULL.
  137574. +**
  137575. +** OUTPUT:
  137576. +**
  137577. +** gctSIZE_T * BufferSize
  137578. +** Pointer to a variable receiving the number of bytes required to hold
  137579. +** the binary form of the gcSHADER object.
  137580. +*/
  137581. +gceSTATUS
  137582. +gcSHADER_Save(
  137583. + IN gcSHADER Shader,
  137584. + IN gctPOINTER Buffer,
  137585. + IN OUT gctSIZE_T * BufferSize
  137586. + );
  137587. +
  137588. +/*******************************************************************************
  137589. +** gcSHADER_LoadEx
  137590. +********************************************************************************
  137591. +**
  137592. +** Load a gcSHADER object from a binary buffer.
  137593. +**
  137594. +** INPUT:
  137595. +**
  137596. +** gcSHADER Shader
  137597. +** Pointer to a gcSHADER object.
  137598. +**
  137599. +** gctPOINTER Buffer
  137600. +** Pointer to a binary buffer containg the shader data to load.
  137601. +**
  137602. +** gctSIZE_T BufferSize
  137603. +** Number of bytes inside the binary buffer pointed to by 'Buffer'.
  137604. +**
  137605. +** OUTPUT:
  137606. +**
  137607. +** Nothing.
  137608. +*/
  137609. +gceSTATUS
  137610. +gcSHADER_LoadEx(
  137611. + IN gcSHADER Shader,
  137612. + IN gctPOINTER Buffer,
  137613. + IN gctSIZE_T BufferSize
  137614. + );
  137615. +
  137616. +/*******************************************************************************
  137617. +** gcSHADER_SaveEx
  137618. +********************************************************************************
  137619. +**
  137620. +** Save a gcSHADER object to a binary buffer.
  137621. +**
  137622. +** INPUT:
  137623. +**
  137624. +** gcSHADER Shader
  137625. +** Pointer to a gcSHADER object.
  137626. +**
  137627. +** gctPOINTER Buffer
  137628. +** Pointer to a binary buffer to be used as storage for the gcSHADER
  137629. +** object. If 'Buffer' is gcvNULL, the gcSHADER object will not be saved,
  137630. +** but the number of bytes required to hold the binary output for the
  137631. +** gcSHADER object will be returned.
  137632. +**
  137633. +** gctSIZE_T * BufferSize
  137634. +** Pointer to a variable holding the number of bytes allocated in
  137635. +** 'Buffer'. Only valid if 'Buffer' is not gcvNULL.
  137636. +**
  137637. +** OUTPUT:
  137638. +**
  137639. +** gctSIZE_T * BufferSize
  137640. +** Pointer to a variable receiving the number of bytes required to hold
  137641. +** the binary form of the gcSHADER object.
  137642. +*/
  137643. +gceSTATUS
  137644. +gcSHADER_SaveEx(
  137645. + IN gcSHADER Shader,
  137646. + IN gctPOINTER Buffer,
  137647. + IN OUT gctSIZE_T * BufferSize
  137648. + );
  137649. +
  137650. +/*******************************************************************************
  137651. +** gcSHADER_ReallocateAttributes
  137652. +**
  137653. +** Reallocate an array of pointers to gcATTRIBUTE objects.
  137654. +**
  137655. +** INPUT:
  137656. +**
  137657. +** gcSHADER Shader
  137658. +** Pointer to a gcSHADER object.
  137659. +**
  137660. +** gctSIZE_T Count
  137661. +** Array count to reallocate. 'Count' must be at least 1.
  137662. +*/
  137663. +gceSTATUS
  137664. +gcSHADER_ReallocateAttributes(
  137665. + IN gcSHADER Shader,
  137666. + IN gctSIZE_T Count
  137667. + );
  137668. +
  137669. +/*******************************************************************************
  137670. +** gcSHADER_AddAttribute
  137671. +********************************************************************************
  137672. +**
  137673. +** Add an attribute to a gcSHADER object.
  137674. +**
  137675. +** INPUT:
  137676. +**
  137677. +** gcSHADER Shader
  137678. +** Pointer to a gcSHADER object.
  137679. +**
  137680. +** gctCONST_STRING Name
  137681. +** Name of the attribute to add.
  137682. +**
  137683. +** gcSHADER_TYPE Type
  137684. +** Type of the attribute to add.
  137685. +**
  137686. +** gctSIZE_T Length
  137687. +** Array length of the attribute to add. 'Length' must be at least 1.
  137688. +**
  137689. +** gctBOOL IsTexture
  137690. +** gcvTRUE if the attribute is used as a texture coordinate, gcvFALSE if not.
  137691. +**
  137692. +** OUTPUT:
  137693. +**
  137694. +** gcATTRIBUTE * Attribute
  137695. +** Pointer to a variable receiving the gcATTRIBUTE object pointer.
  137696. +*/
  137697. +gceSTATUS
  137698. +gcSHADER_AddAttribute(
  137699. + IN gcSHADER Shader,
  137700. + IN gctCONST_STRING Name,
  137701. + IN gcSHADER_TYPE Type,
  137702. + IN gctSIZE_T Length,
  137703. + IN gctBOOL IsTexture,
  137704. + OUT gcATTRIBUTE * Attribute
  137705. + );
  137706. +
  137707. +/*******************************************************************************
  137708. +** gcSHADER_GetAttributeCount
  137709. +********************************************************************************
  137710. +**
  137711. +** Get the number of attributes for this shader.
  137712. +**
  137713. +** INPUT:
  137714. +**
  137715. +** gcSHADER Shader
  137716. +** Pointer to a gcSHADER object.
  137717. +**
  137718. +** OUTPUT:
  137719. +**
  137720. +** gctSIZE_T * Count
  137721. +** Pointer to a variable receiving the number of attributes.
  137722. +*/
  137723. +gceSTATUS
  137724. +gcSHADER_GetAttributeCount(
  137725. + IN gcSHADER Shader,
  137726. + OUT gctSIZE_T * Count
  137727. + );
  137728. +
  137729. +/*******************************************************************************
  137730. +** gcSHADER_GetAttribute
  137731. +********************************************************************************
  137732. +**
  137733. +** Get the gcATTRIBUTE object poniter for an indexed attribute for this shader.
  137734. +**
  137735. +** INPUT:
  137736. +**
  137737. +** gcSHADER Shader
  137738. +** Pointer to a gcSHADER object.
  137739. +**
  137740. +** gctUINT Index
  137741. +** Index of the attribute to retrieve.
  137742. +**
  137743. +** OUTPUT:
  137744. +**
  137745. +** gcATTRIBUTE * Attribute
  137746. +** Pointer to a variable receiving the gcATTRIBUTE object pointer.
  137747. +*/
  137748. +gceSTATUS
  137749. +gcSHADER_GetAttribute(
  137750. + IN gcSHADER Shader,
  137751. + IN gctUINT Index,
  137752. + OUT gcATTRIBUTE * Attribute
  137753. + );
  137754. +
  137755. +/*******************************************************************************
  137756. +** gcSHADER_ReallocateUniforms
  137757. +**
  137758. +** Reallocate an array of pointers to gcUNIFORM objects.
  137759. +**
  137760. +** INPUT:
  137761. +**
  137762. +** gcSHADER Shader
  137763. +** Pointer to a gcSHADER object.
  137764. +**
  137765. +** gctSIZE_T Count
  137766. +** Array count to reallocate. 'Count' must be at least 1.
  137767. +*/
  137768. +gceSTATUS
  137769. +gcSHADER_ReallocateUniforms(
  137770. + IN gcSHADER Shader,
  137771. + IN gctSIZE_T Count
  137772. + );
  137773. +
  137774. +/*******************************************************************************
  137775. +** gcSHADER_AddUniform
  137776. +********************************************************************************
  137777. +**
  137778. +** Add an uniform to a gcSHADER object.
  137779. +**
  137780. +** INPUT:
  137781. +**
  137782. +** gcSHADER Shader
  137783. +** Pointer to a gcSHADER object.
  137784. +**
  137785. +** gctCONST_STRING Name
  137786. +** Name of the uniform to add.
  137787. +**
  137788. +** gcSHADER_TYPE Type
  137789. +** Type of the uniform to add.
  137790. +**
  137791. +** gctSIZE_T Length
  137792. +** Array length of the uniform to add. 'Length' must be at least 1.
  137793. +**
  137794. +** OUTPUT:
  137795. +**
  137796. +** gcUNIFORM * Uniform
  137797. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  137798. +*/
  137799. +gceSTATUS
  137800. +gcSHADER_AddUniform(
  137801. + IN gcSHADER Shader,
  137802. + IN gctCONST_STRING Name,
  137803. + IN gcSHADER_TYPE Type,
  137804. + IN gctSIZE_T Length,
  137805. + OUT gcUNIFORM * Uniform
  137806. + );
  137807. +
  137808. +/*******************************************************************************
  137809. +** gcSHADER_AddPreRotationUniform
  137810. +********************************************************************************
  137811. +**
  137812. +** Add an uniform to a gcSHADER object.
  137813. +**
  137814. +** INPUT:
  137815. +**
  137816. +** gcSHADER Shader
  137817. +** Pointer to a gcSHADER object.
  137818. +**
  137819. +** gctCONST_STRING Name
  137820. +** Name of the uniform to add.
  137821. +**
  137822. +** gcSHADER_TYPE Type
  137823. +** Type of the uniform to add.
  137824. +**
  137825. +** gctSIZE_T Length
  137826. +** Array length of the uniform to add. 'Length' must be at least 1.
  137827. +**
  137828. +** gctINT col
  137829. +** Which uniform.
  137830. +**
  137831. +** OUTPUT:
  137832. +**
  137833. +** gcUNIFORM * Uniform
  137834. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  137835. +*/
  137836. +gceSTATUS
  137837. +gcSHADER_AddPreRotationUniform(
  137838. + IN gcSHADER Shader,
  137839. + IN gctCONST_STRING Name,
  137840. + IN gcSHADER_TYPE Type,
  137841. + IN gctSIZE_T Length,
  137842. + IN gctINT col,
  137843. + OUT gcUNIFORM * Uniform
  137844. + );
  137845. +
  137846. +/*******************************************************************************
  137847. +** gcSHADER_AddUniformEx
  137848. +********************************************************************************
  137849. +**
  137850. +** Add an uniform to a gcSHADER object.
  137851. +**
  137852. +** INPUT:
  137853. +**
  137854. +** gcSHADER Shader
  137855. +** Pointer to a gcSHADER object.
  137856. +**
  137857. +** gctCONST_STRING Name
  137858. +** Name of the uniform to add.
  137859. +**
  137860. +** gcSHADER_TYPE Type
  137861. +** Type of the uniform to add.
  137862. +**
  137863. +** gcSHADER_PRECISION precision
  137864. +** Precision of the uniform to add.
  137865. +**
  137866. +** gctSIZE_T Length
  137867. +** Array length of the uniform to add. 'Length' must be at least 1.
  137868. +**
  137869. +** OUTPUT:
  137870. +**
  137871. +** gcUNIFORM * Uniform
  137872. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  137873. +*/
  137874. +gceSTATUS
  137875. +gcSHADER_AddUniformEx(
  137876. + IN gcSHADER Shader,
  137877. + IN gctCONST_STRING Name,
  137878. + IN gcSHADER_TYPE Type,
  137879. + IN gcSHADER_PRECISION precision,
  137880. + IN gctSIZE_T Length,
  137881. + OUT gcUNIFORM * Uniform
  137882. + );
  137883. +
  137884. +/*******************************************************************************
  137885. +** gcSHADER_AddUniformEx1
  137886. +********************************************************************************
  137887. +**
  137888. +** Add an uniform to a gcSHADER object.
  137889. +**
  137890. +** INPUT:
  137891. +**
  137892. +** gcSHADER Shader
  137893. +** Pointer to a gcSHADER object.
  137894. +**
  137895. +** gctCONST_STRING Name
  137896. +** Name of the uniform to add.
  137897. +**
  137898. +** gcSHADER_TYPE Type
  137899. +** Type of the uniform to add.
  137900. +**
  137901. +** gcSHADER_PRECISION precision
  137902. +** Precision of the uniform to add.
  137903. +**
  137904. +** gctSIZE_T Length
  137905. +** Array length of the uniform to add. 'Length' must be at least 1.
  137906. +**
  137907. +** gcSHADER_VAR_CATEGORY varCategory
  137908. +** Variable category, normal or struct.
  137909. +**
  137910. +** gctUINT16 numStructureElement
  137911. +** If struct, its element number.
  137912. +**
  137913. +** gctINT16 parent
  137914. +** If struct, parent index in gcSHADER.variables.
  137915. +**
  137916. +** gctINT16 prevSibling
  137917. +** If struct, previous sibling index in gcSHADER.variables.
  137918. +**
  137919. +** OUTPUT:
  137920. +**
  137921. +** gcUNIFORM * Uniform
  137922. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  137923. +**
  137924. +** gctINT16* ThisUniformIndex
  137925. +** Returned value about uniform index in gcSHADER.
  137926. +*/
  137927. +gceSTATUS
  137928. +gcSHADER_AddUniformEx1(
  137929. + IN gcSHADER Shader,
  137930. + IN gctCONST_STRING Name,
  137931. + IN gcSHADER_TYPE Type,
  137932. + IN gcSHADER_PRECISION precision,
  137933. + IN gctSIZE_T Length,
  137934. + IN gctINT IsArray,
  137935. + IN gcSHADER_VAR_CATEGORY varCategory,
  137936. + IN gctUINT16 numStructureElement,
  137937. + IN gctINT16 parent,
  137938. + IN gctINT16 prevSibling,
  137939. + OUT gctINT16* ThisUniformIndex,
  137940. + OUT gcUNIFORM * Uniform
  137941. + );
  137942. +
  137943. +/*******************************************************************************
  137944. +** gcSHADER_GetUniformCount
  137945. +********************************************************************************
  137946. +**
  137947. +** Get the number of uniforms for this shader.
  137948. +**
  137949. +** INPUT:
  137950. +**
  137951. +** gcSHADER Shader
  137952. +** Pointer to a gcSHADER object.
  137953. +**
  137954. +** OUTPUT:
  137955. +**
  137956. +** gctSIZE_T * Count
  137957. +** Pointer to a variable receiving the number of uniforms.
  137958. +*/
  137959. +gceSTATUS
  137960. +gcSHADER_GetUniformCount(
  137961. + IN gcSHADER Shader,
  137962. + OUT gctSIZE_T * Count
  137963. + );
  137964. +
  137965. +/*******************************************************************************
  137966. +** gcSHADER_GetPreRotationUniform
  137967. +********************************************************************************
  137968. +**
  137969. +** Get the preRotate Uniform.
  137970. +**
  137971. +** INPUT:
  137972. +**
  137973. +** gcSHADER Shader
  137974. +** Pointer to a gcSHADER object.
  137975. +**
  137976. +** OUTPUT:
  137977. +**
  137978. +** gcUNIFORM ** pUniform
  137979. +** Pointer to a preRotation uniforms array.
  137980. +*/
  137981. +gceSTATUS
  137982. +gcSHADER_GetPreRotationUniform(
  137983. + IN gcSHADER Shader,
  137984. + OUT gcUNIFORM ** pUniform
  137985. + );
  137986. +
  137987. +/*******************************************************************************
  137988. +** gcSHADER_GetUniform
  137989. +********************************************************************************
  137990. +**
  137991. +** Get the gcUNIFORM object pointer for an indexed uniform for this shader.
  137992. +**
  137993. +** INPUT:
  137994. +**
  137995. +** gcSHADER Shader
  137996. +** Pointer to a gcSHADER object.
  137997. +**
  137998. +** gctUINT Index
  137999. +** Index of the uniform to retrieve.
  138000. +**
  138001. +** OUTPUT:
  138002. +**
  138003. +** gcUNIFORM * Uniform
  138004. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  138005. +*/
  138006. +gceSTATUS
  138007. +gcSHADER_GetUniform(
  138008. + IN gcSHADER Shader,
  138009. + IN gctUINT Index,
  138010. + OUT gcUNIFORM * Uniform
  138011. + );
  138012. +
  138013. +
  138014. +/*******************************************************************************
  138015. +** gcSHADER_GetUniformIndexingRange
  138016. +********************************************************************************
  138017. +**
  138018. +** Get the gcUNIFORM object pointer for an indexed uniform for this shader.
  138019. +**
  138020. +** INPUT:
  138021. +**
  138022. +** gcSHADER Shader
  138023. +** Pointer to a gcSHADER object.
  138024. +**
  138025. +** gctINT uniformIndex
  138026. +** Index of the start uniform.
  138027. +**
  138028. +** gctINT offset
  138029. +** Offset to indexing.
  138030. +**
  138031. +** OUTPUT:
  138032. +**
  138033. +** gctINT * LastUniformIndex
  138034. +** Pointer to index of last uniform in indexing range.
  138035. +**
  138036. +** gctINT * OffsetUniformIndex
  138037. +** Pointer to index of uniform that indexing at offset.
  138038. +**
  138039. +** gctINT * DeviationInOffsetUniform
  138040. +** Pointer to offset in uniform picked up.
  138041. +*/
  138042. +gceSTATUS
  138043. +gcSHADER_GetUniformIndexingRange(
  138044. + IN gcSHADER Shader,
  138045. + IN gctINT uniformIndex,
  138046. + IN gctINT offset,
  138047. + OUT gctINT * LastUniformIndex,
  138048. + OUT gctINT * OffsetUniformIndex,
  138049. + OUT gctINT * DeviationInOffsetUniform
  138050. + );
  138051. +
  138052. +/*******************************************************************************
  138053. +** gcSHADER_GetKernelFucntion
  138054. +**
  138055. +** Get the gcKERNEL_FUNCTION object pointer for an indexed kernel function for this shader.
  138056. +**
  138057. +** INPUT:
  138058. +**
  138059. +** gcSHADER Shader
  138060. +** Pointer to a gcSHADER object.
  138061. +**
  138062. +** gctUINT Index
  138063. +** Index of kernel function to retreive the name for.
  138064. +**
  138065. +** OUTPUT:
  138066. +**
  138067. +** gcKERNEL_FUNCTION * KernelFunction
  138068. +** Pointer to a variable receiving the gcKERNEL_FUNCTION object pointer.
  138069. +*/
  138070. +gceSTATUS
  138071. +gcSHADER_GetKernelFunction(
  138072. + IN gcSHADER Shader,
  138073. + IN gctUINT Index,
  138074. + OUT gcKERNEL_FUNCTION * KernelFunction
  138075. + );
  138076. +
  138077. +gceSTATUS
  138078. +gcSHADER_GetKernelFunctionByName(
  138079. + IN gcSHADER Shader,
  138080. + IN gctSTRING KernelName,
  138081. + OUT gcKERNEL_FUNCTION * KernelFunction
  138082. + );
  138083. +/*******************************************************************************
  138084. +** gcSHADER_GetKernelFunctionCount
  138085. +**
  138086. +** Get the number of kernel functions for this shader.
  138087. +**
  138088. +** INPUT:
  138089. +**
  138090. +** gcSHADER Shader
  138091. +** Pointer to a gcSHADER object.
  138092. +**
  138093. +** OUTPUT:
  138094. +**
  138095. +** gctSIZE_T * Count
  138096. +** Pointer to a variable receiving the number of kernel functions.
  138097. +*/
  138098. +gceSTATUS
  138099. +gcSHADER_GetKernelFunctionCount(
  138100. + IN gcSHADER Shader,
  138101. + OUT gctSIZE_T * Count
  138102. + );
  138103. +
  138104. +/*******************************************************************************
  138105. +** gcSHADER_ReallocateOutputs
  138106. +**
  138107. +** Reallocate an array of pointers to gcOUTPUT objects.
  138108. +**
  138109. +** INPUT:
  138110. +**
  138111. +** gcSHADER Shader
  138112. +** Pointer to a gcSHADER object.
  138113. +**
  138114. +** gctSIZE_T Count
  138115. +** Array count to reallocate. 'Count' must be at least 1.
  138116. +*/
  138117. +gceSTATUS
  138118. +gcSHADER_ReallocateOutputs(
  138119. + IN gcSHADER Shader,
  138120. + IN gctSIZE_T Count
  138121. + );
  138122. +
  138123. +/*******************************************************************************
  138124. +** gcSHADER_AddOutput
  138125. +********************************************************************************
  138126. +**
  138127. +** Add an output to a gcSHADER object.
  138128. +**
  138129. +** INPUT:
  138130. +**
  138131. +** gcSHADER Shader
  138132. +** Pointer to a gcSHADER object.
  138133. +**
  138134. +** gctCONST_STRING Name
  138135. +** Name of the output to add.
  138136. +**
  138137. +** gcSHADER_TYPE Type
  138138. +** Type of the output to add.
  138139. +**
  138140. +** gctSIZE_T Length
  138141. +** Array length of the output to add. 'Length' must be at least 1.
  138142. +**
  138143. +** gctUINT16 TempRegister
  138144. +** Temporary register index that holds the output value.
  138145. +**
  138146. +** OUTPUT:
  138147. +**
  138148. +** Nothing.
  138149. +*/
  138150. +gceSTATUS
  138151. +gcSHADER_AddOutput(
  138152. + IN gcSHADER Shader,
  138153. + IN gctCONST_STRING Name,
  138154. + IN gcSHADER_TYPE Type,
  138155. + IN gctSIZE_T Length,
  138156. + IN gctUINT16 TempRegister
  138157. + );
  138158. +
  138159. +gceSTATUS
  138160. +gcSHADER_AddOutputIndexed(
  138161. + IN gcSHADER Shader,
  138162. + IN gctCONST_STRING Name,
  138163. + IN gctSIZE_T Index,
  138164. + IN gctUINT16 TempIndex
  138165. + );
  138166. +
  138167. +/*******************************************************************************
  138168. +** gcSHADER_GetOutputCount
  138169. +********************************************************************************
  138170. +**
  138171. +** Get the number of outputs for this shader.
  138172. +**
  138173. +** INPUT:
  138174. +**
  138175. +** gcSHADER Shader
  138176. +** Pointer to a gcSHADER object.
  138177. +**
  138178. +** OUTPUT:
  138179. +**
  138180. +** gctSIZE_T * Count
  138181. +** Pointer to a variable receiving the number of outputs.
  138182. +*/
  138183. +gceSTATUS
  138184. +gcSHADER_GetOutputCount(
  138185. + IN gcSHADER Shader,
  138186. + OUT gctSIZE_T * Count
  138187. + );
  138188. +
  138189. +/*******************************************************************************
  138190. +** gcSHADER_GetOutput
  138191. +********************************************************************************
  138192. +**
  138193. +** Get the gcOUTPUT object pointer for an indexed output for this shader.
  138194. +**
  138195. +** INPUT:
  138196. +**
  138197. +** gcSHADER Shader
  138198. +** Pointer to a gcSHADER object.
  138199. +**
  138200. +** gctUINT Index
  138201. +** Index of output to retrieve.
  138202. +**
  138203. +** OUTPUT:
  138204. +**
  138205. +** gcOUTPUT * Output
  138206. +** Pointer to a variable receiving the gcOUTPUT object pointer.
  138207. +*/
  138208. +gceSTATUS
  138209. +gcSHADER_GetOutput(
  138210. + IN gcSHADER Shader,
  138211. + IN gctUINT Index,
  138212. + OUT gcOUTPUT * Output
  138213. + );
  138214. +
  138215. +
  138216. +/*******************************************************************************
  138217. +** gcSHADER_GetOutputByName
  138218. +********************************************************************************
  138219. +**
  138220. +** Get the gcOUTPUT object pointer for this shader by output name.
  138221. +**
  138222. +** INPUT:
  138223. +**
  138224. +** gcSHADER Shader
  138225. +** Pointer to a gcSHADER object.
  138226. +**
  138227. +** gctSTRING name
  138228. +** Name of output to retrieve.
  138229. +**
  138230. +** gctSIZE_T nameLength
  138231. +** Length of name to retrieve
  138232. +**
  138233. +** OUTPUT:
  138234. +**
  138235. +** gcOUTPUT * Output
  138236. +** Pointer to a variable receiving the gcOUTPUT object pointer.
  138237. +*/
  138238. +gceSTATUS
  138239. +gcSHADER_GetOutputByName(
  138240. + IN gcSHADER Shader,
  138241. + IN gctSTRING name,
  138242. + IN gctSIZE_T nameLength,
  138243. + OUT gcOUTPUT * Output
  138244. + );
  138245. +
  138246. +/*******************************************************************************
  138247. +** gcSHADER_ReallocateVariables
  138248. +**
  138249. +** Reallocate an array of pointers to gcVARIABLE objects.
  138250. +**
  138251. +** INPUT:
  138252. +**
  138253. +** gcSHADER Shader
  138254. +** Pointer to a gcSHADER object.
  138255. +**
  138256. +** gctSIZE_T Count
  138257. +** Array count to reallocate. 'Count' must be at least 1.
  138258. +*/
  138259. +gceSTATUS
  138260. +gcSHADER_ReallocateVariables(
  138261. + IN gcSHADER Shader,
  138262. + IN gctSIZE_T Count
  138263. + );
  138264. +
  138265. +/*******************************************************************************
  138266. +** gcSHADER_AddVariable
  138267. +********************************************************************************
  138268. +**
  138269. +** Add a variable to a gcSHADER object.
  138270. +**
  138271. +** INPUT:
  138272. +**
  138273. +** gcSHADER Shader
  138274. +** Pointer to a gcSHADER object.
  138275. +**
  138276. +** gctCONST_STRING Name
  138277. +** Name of the variable to add.
  138278. +**
  138279. +** gcSHADER_TYPE Type
  138280. +** Type of the variable to add.
  138281. +**
  138282. +** gctSIZE_T Length
  138283. +** Array length of the variable to add. 'Length' must be at least 1.
  138284. +**
  138285. +** gctUINT16 TempRegister
  138286. +** Temporary register index that holds the variable value.
  138287. +**
  138288. +** OUTPUT:
  138289. +**
  138290. +** Nothing.
  138291. +*/
  138292. +gceSTATUS
  138293. +gcSHADER_AddVariable(
  138294. + IN gcSHADER Shader,
  138295. + IN gctCONST_STRING Name,
  138296. + IN gcSHADER_TYPE Type,
  138297. + IN gctSIZE_T Length,
  138298. + IN gctUINT16 TempRegister
  138299. + );
  138300. +
  138301. +
  138302. +/*******************************************************************************
  138303. +** gcSHADER_AddVariableEx
  138304. +********************************************************************************
  138305. +**
  138306. +** Add a variable to a gcSHADER object.
  138307. +**
  138308. +** INPUT:
  138309. +**
  138310. +** gcSHADER Shader
  138311. +** Pointer to a gcSHADER object.
  138312. +**
  138313. +** gctCONST_STRING Name
  138314. +** Name of the variable to add.
  138315. +**
  138316. +** gcSHADER_TYPE Type
  138317. +** Type of the variable to add.
  138318. +**
  138319. +** gctSIZE_T Length
  138320. +** Array length of the variable to add. 'Length' must be at least 1.
  138321. +**
  138322. +** gctUINT16 TempRegister
  138323. +** Temporary register index that holds the variable value.
  138324. +**
  138325. +** gcSHADER_VAR_CATEGORY varCategory
  138326. +** Variable category, normal or struct.
  138327. +**
  138328. +** gctUINT16 numStructureElement
  138329. +** If struct, its element number.
  138330. +**
  138331. +** gctINT16 parent
  138332. +** If struct, parent index in gcSHADER.variables.
  138333. +**
  138334. +** gctINT16 prevSibling
  138335. +** If struct, previous sibling index in gcSHADER.variables.
  138336. +**
  138337. +** OUTPUT:
  138338. +**
  138339. +** gctINT16* ThisVarIndex
  138340. +** Returned value about variable index in gcSHADER.
  138341. +*/
  138342. +gceSTATUS
  138343. +gcSHADER_AddVariableEx(
  138344. + IN gcSHADER Shader,
  138345. + IN gctCONST_STRING Name,
  138346. + IN gcSHADER_TYPE Type,
  138347. + IN gctSIZE_T Length,
  138348. + IN gctUINT16 TempRegister,
  138349. + IN gcSHADER_VAR_CATEGORY varCategory,
  138350. + IN gctUINT16 numStructureElement,
  138351. + IN gctINT16 parent,
  138352. + IN gctINT16 prevSibling,
  138353. + OUT gctINT16* ThisVarIndex
  138354. + );
  138355. +
  138356. +/*******************************************************************************
  138357. +** gcSHADER_UpdateVariable
  138358. +********************************************************************************
  138359. +**
  138360. +** Update a variable to a gcSHADER object.
  138361. +**
  138362. +** INPUT:
  138363. +**
  138364. +** gcSHADER Shader
  138365. +** Pointer to a gcSHADER object.
  138366. +**
  138367. +** gctUINT Index
  138368. +** Index of variable to retrieve.
  138369. +**
  138370. +** gceVARIABLE_UPDATE_FLAGS flag
  138371. +** Flag which property of variable will be updated.
  138372. +**
  138373. +** gctUINT newValue
  138374. +** New value to update.
  138375. +**
  138376. +** OUTPUT:
  138377. +**
  138378. +** Nothing.
  138379. +*/
  138380. +gceSTATUS
  138381. +gcSHADER_UpdateVariable(
  138382. + IN gcSHADER Shader,
  138383. + IN gctUINT Index,
  138384. + IN gceVARIABLE_UPDATE_FLAGS flag,
  138385. + IN gctUINT newValue
  138386. + );
  138387. +
  138388. +/*******************************************************************************
  138389. +** gcSHADER_GetVariableCount
  138390. +********************************************************************************
  138391. +**
  138392. +** Get the number of variables for this shader.
  138393. +**
  138394. +** INPUT:
  138395. +**
  138396. +** gcSHADER Shader
  138397. +** Pointer to a gcSHADER object.
  138398. +**
  138399. +** OUTPUT:
  138400. +**
  138401. +** gctSIZE_T * Count
  138402. +** Pointer to a variable receiving the number of variables.
  138403. +*/
  138404. +gceSTATUS
  138405. +gcSHADER_GetVariableCount(
  138406. + IN gcSHADER Shader,
  138407. + OUT gctSIZE_T * Count
  138408. + );
  138409. +
  138410. +/*******************************************************************************
  138411. +** gcSHADER_GetVariable
  138412. +********************************************************************************
  138413. +**
  138414. +** Get the gcVARIABLE object pointer for an indexed variable for this shader.
  138415. +**
  138416. +** INPUT:
  138417. +**
  138418. +** gcSHADER Shader
  138419. +** Pointer to a gcSHADER object.
  138420. +**
  138421. +** gctUINT Index
  138422. +** Index of variable to retrieve.
  138423. +**
  138424. +** OUTPUT:
  138425. +**
  138426. +** gcVARIABLE * Variable
  138427. +** Pointer to a variable receiving the gcVARIABLE object pointer.
  138428. +*/
  138429. +gceSTATUS
  138430. +gcSHADER_GetVariable(
  138431. + IN gcSHADER Shader,
  138432. + IN gctUINT Index,
  138433. + OUT gcVARIABLE * Variable
  138434. + );
  138435. +
  138436. +/*******************************************************************************
  138437. +** gcSHADER_GetVariableIndexingRange
  138438. +********************************************************************************
  138439. +**
  138440. +** Get the gcVARIABLE indexing range.
  138441. +**
  138442. +** INPUT:
  138443. +**
  138444. +** gcSHADER Shader
  138445. +** Pointer to a gcSHADER object.
  138446. +**
  138447. +** gcVARIABLE variable
  138448. +** Start variable.
  138449. +**
  138450. +** gctBOOL whole
  138451. +** Indicate whether maximum indexing range is queried
  138452. +**
  138453. +** OUTPUT:
  138454. +**
  138455. +** gctUINT *Start
  138456. +** Pointer to range start (temp register index).
  138457. +**
  138458. +** gctUINT *End
  138459. +** Pointer to range end (temp register index).
  138460. +*/
  138461. +gceSTATUS
  138462. +gcSHADER_GetVariableIndexingRange(
  138463. + IN gcSHADER Shader,
  138464. + IN gcVARIABLE variable,
  138465. + IN gctBOOL whole,
  138466. + OUT gctUINT *Start,
  138467. + OUT gctUINT *End
  138468. + );
  138469. +
  138470. +/*******************************************************************************
  138471. +** gcSHADER_AddOpcode
  138472. +********************************************************************************
  138473. +**
  138474. +** Add an opcode to a gcSHADER object.
  138475. +**
  138476. +** INPUT:
  138477. +**
  138478. +** gcSHADER Shader
  138479. +** Pointer to a gcSHADER object.
  138480. +**
  138481. +** gcSL_OPCODE Opcode
  138482. +** Opcode to add.
  138483. +**
  138484. +** gctUINT16 TempRegister
  138485. +** Temporary register index that acts as the target of the opcode.
  138486. +**
  138487. +** gctUINT8 Enable
  138488. +** Write enable bits for the temporary register that acts as the target
  138489. +** of the opcode.
  138490. +**
  138491. +** gcSL_FORMAT Format
  138492. +** Format of the temporary register.
  138493. +**
  138494. +** OUTPUT:
  138495. +**
  138496. +** Nothing.
  138497. +*/
  138498. +gceSTATUS
  138499. +gcSHADER_AddOpcode(
  138500. + IN gcSHADER Shader,
  138501. + IN gcSL_OPCODE Opcode,
  138502. + IN gctUINT16 TempRegister,
  138503. + IN gctUINT8 Enable,
  138504. + IN gcSL_FORMAT Format
  138505. + );
  138506. +
  138507. +gceSTATUS
  138508. +gcSHADER_AddOpcode2(
  138509. + IN gcSHADER Shader,
  138510. + IN gcSL_OPCODE Opcode,
  138511. + IN gcSL_CONDITION Condition,
  138512. + IN gctUINT16 TempRegister,
  138513. + IN gctUINT8 Enable,
  138514. + IN gcSL_FORMAT Format
  138515. + );
  138516. +
  138517. +/*******************************************************************************
  138518. +** gcSHADER_AddOpcodeIndexed
  138519. +********************************************************************************
  138520. +**
  138521. +** Add an opcode to a gcSHADER object that writes to an dynamically indexed
  138522. +** target.
  138523. +**
  138524. +** INPUT:
  138525. +**
  138526. +** gcSHADER Shader
  138527. +** Pointer to a gcSHADER object.
  138528. +**
  138529. +** gcSL_OPCODE Opcode
  138530. +** Opcode to add.
  138531. +**
  138532. +** gctUINT16 TempRegister
  138533. +** Temporary register index that acts as the target of the opcode.
  138534. +**
  138535. +** gctUINT8 Enable
  138536. +** Write enable bits for the temporary register that acts as the
  138537. +** target of the opcode.
  138538. +**
  138539. +** gcSL_INDEXED Mode
  138540. +** Location of the dynamic index inside the temporary register. Valid
  138541. +** values can be:
  138542. +**
  138543. +** gcSL_INDEXED_X - Use x component of the temporary register.
  138544. +** gcSL_INDEXED_Y - Use y component of the temporary register.
  138545. +** gcSL_INDEXED_Z - Use z component of the temporary register.
  138546. +** gcSL_INDEXED_W - Use w component of the temporary register.
  138547. +**
  138548. +** gctUINT16 IndexRegister
  138549. +** Temporary register index that holds the dynamic index.
  138550. +**
  138551. +** gcSL_FORMAT Format
  138552. +** Format of the temporary register.
  138553. +**
  138554. +** OUTPUT:
  138555. +**
  138556. +** Nothing.
  138557. +*/
  138558. +gceSTATUS
  138559. +gcSHADER_AddOpcodeIndexed(
  138560. + IN gcSHADER Shader,
  138561. + IN gcSL_OPCODE Opcode,
  138562. + IN gctUINT16 TempRegister,
  138563. + IN gctUINT8 Enable,
  138564. + IN gcSL_INDEXED Mode,
  138565. + IN gctUINT16 IndexRegister,
  138566. + IN gcSL_FORMAT Format
  138567. + );
  138568. +
  138569. +/*******************************************************************************
  138570. +** gcSHADER_AddOpcodeConditionIndexed
  138571. +**
  138572. +** Add an opcode to a gcSHADER object that writes to an dynamically indexed
  138573. +** target.
  138574. +**
  138575. +** INPUT:
  138576. +**
  138577. +** gcSHADER Shader
  138578. +** Pointer to a gcSHADER object.
  138579. +**
  138580. +** gcSL_OPCODE Opcode
  138581. +** Opcode to add.
  138582. +**
  138583. +** gcSL_CONDITION Condition
  138584. +** Condition to check.
  138585. +**
  138586. +** gctUINT16 TempRegister
  138587. +** Temporary register index that acts as the target of the opcode.
  138588. +**
  138589. +** gctUINT8 Enable
  138590. +** Write enable bits for the temporary register that acts as the
  138591. +** target of the opcode.
  138592. +**
  138593. +** gcSL_INDEXED Indexed
  138594. +** Location of the dynamic index inside the temporary register. Valid
  138595. +** values can be:
  138596. +**
  138597. +** gcSL_INDEXED_X - Use x component of the temporary register.
  138598. +** gcSL_INDEXED_Y - Use y component of the temporary register.
  138599. +** gcSL_INDEXED_Z - Use z component of the temporary register.
  138600. +** gcSL_INDEXED_W - Use w component of the temporary register.
  138601. +**
  138602. +** gctUINT16 IndexRegister
  138603. +** Temporary register index that holds the dynamic index.
  138604. +**
  138605. +** OUTPUT:
  138606. +**
  138607. +** Nothing.
  138608. +*/
  138609. +gceSTATUS
  138610. +gcSHADER_AddOpcodeConditionIndexed(
  138611. + IN gcSHADER Shader,
  138612. + IN gcSL_OPCODE Opcode,
  138613. + IN gcSL_CONDITION Condition,
  138614. + IN gctUINT16 TempRegister,
  138615. + IN gctUINT8 Enable,
  138616. + IN gcSL_INDEXED Indexed,
  138617. + IN gctUINT16 IndexRegister,
  138618. + IN gcSL_FORMAT Format
  138619. + );
  138620. +
  138621. +/*******************************************************************************
  138622. +** gcSHADER_AddOpcodeConditional
  138623. +********************************************************************************
  138624. +**
  138625. +** Add an conditional opcode to a gcSHADER object.
  138626. +**
  138627. +** INPUT:
  138628. +**
  138629. +** gcSHADER Shader
  138630. +** Pointer to a gcSHADER object.
  138631. +**
  138632. +** gcSL_OPCODE Opcode
  138633. +** Opcode to add.
  138634. +**
  138635. +** gcSL_CONDITION Condition
  138636. +** Condition that needs to evaluate to gcvTRUE in order for the opcode to
  138637. +** execute.
  138638. +**
  138639. +** gctUINT Label
  138640. +** Target label if 'Condition' evaluates to gcvTRUE.
  138641. +**
  138642. +** OUTPUT:
  138643. +**
  138644. +** Nothing.
  138645. +*/
  138646. +gceSTATUS
  138647. +gcSHADER_AddOpcodeConditional(
  138648. + IN gcSHADER Shader,
  138649. + IN gcSL_OPCODE Opcode,
  138650. + IN gcSL_CONDITION Condition,
  138651. + IN gctUINT Label
  138652. + );
  138653. +
  138654. +/*******************************************************************************
  138655. +** gcSHADER_AddOpcodeConditionalFormatted
  138656. +**
  138657. +** Add an conditional jump or call opcode to a gcSHADER object.
  138658. +**
  138659. +** INPUT:
  138660. +**
  138661. +** gcSHADER Shader
  138662. +** Pointer to a gcSHADER object.
  138663. +**
  138664. +** gcSL_OPCODE Opcode
  138665. +** Opcode to add.
  138666. +**
  138667. +** gcSL_CONDITION Condition
  138668. +** Condition that needs to evaluate to gcvTRUE in order for the opcode to
  138669. +** execute.
  138670. +**
  138671. +** gcSL_FORMAT Format
  138672. +** Format of conditional operands
  138673. +**
  138674. +** gctUINT Label
  138675. +** Target label if 'Condition' evaluates to gcvTRUE.
  138676. +**
  138677. +** OUTPUT:
  138678. +**
  138679. +** Nothing.
  138680. +*/
  138681. +gceSTATUS
  138682. +gcSHADER_AddOpcodeConditionalFormatted(
  138683. + IN gcSHADER Shader,
  138684. + IN gcSL_OPCODE Opcode,
  138685. + IN gcSL_CONDITION Condition,
  138686. + IN gcSL_FORMAT Format,
  138687. + IN gctUINT Label
  138688. + );
  138689. +
  138690. +/*******************************************************************************
  138691. +** gcSHADER_AddOpcodeConditionalFormattedEnable
  138692. +**
  138693. +** Add an conditional jump or call opcode to a gcSHADER object.
  138694. +**
  138695. +** INPUT:
  138696. +**
  138697. +** gcSHADER Shader
  138698. +** Pointer to a gcSHADER object.
  138699. +**
  138700. +** gcSL_OPCODE Opcode
  138701. +** Opcode to add.
  138702. +**
  138703. +** gcSL_CONDITION Condition
  138704. +** Condition that needs to evaluate to gcvTRUE in order for the opcode to
  138705. +** execute.
  138706. +**
  138707. +** gcSL_FORMAT Format
  138708. +** Format of conditional operands
  138709. +**
  138710. +** gctUINT8 Enable
  138711. +** Write enable value for the target of the opcode.
  138712. +**
  138713. +** gctUINT Label
  138714. +** Target label if 'Condition' evaluates to gcvTRUE.
  138715. +**
  138716. +** OUTPUT:
  138717. +**
  138718. +** Nothing.
  138719. +*/
  138720. +gceSTATUS
  138721. +gcSHADER_AddOpcodeConditionalFormattedEnable(
  138722. + IN gcSHADER Shader,
  138723. + IN gcSL_OPCODE Opcode,
  138724. + IN gcSL_CONDITION Condition,
  138725. + IN gcSL_FORMAT Format,
  138726. + IN gctUINT8 Enable,
  138727. + IN gctUINT Label
  138728. + );
  138729. +
  138730. +/*******************************************************************************
  138731. +** gcSHADER_AddLabel
  138732. +********************************************************************************
  138733. +**
  138734. +** Define a label at the current instruction of a gcSHADER object.
  138735. +**
  138736. +** INPUT:
  138737. +**
  138738. +** gcSHADER Shader
  138739. +** Pointer to a gcSHADER object.
  138740. +**
  138741. +** gctUINT Label
  138742. +** Label to define.
  138743. +**
  138744. +** OUTPUT:
  138745. +**
  138746. +** Nothing.
  138747. +*/
  138748. +gceSTATUS
  138749. +gcSHADER_AddLabel(
  138750. + IN gcSHADER Shader,
  138751. + IN gctUINT Label
  138752. + );
  138753. +
  138754. +/*******************************************************************************
  138755. +** gcSHADER_AddSource
  138756. +********************************************************************************
  138757. +**
  138758. +** Add a source operand to a gcSHADER object.
  138759. +**
  138760. +** INPUT:
  138761. +**
  138762. +** gcSHADER Shader
  138763. +** Pointer to a gcSHADER object.
  138764. +**
  138765. +** gcSL_TYPE Type
  138766. +** Type of the source operand.
  138767. +**
  138768. +** gctUINT16 SourceIndex
  138769. +** Index of the source operand.
  138770. +**
  138771. +** gctUINT8 Swizzle
  138772. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138773. +**
  138774. +** gcSL_FORMAT Format
  138775. +** Format of the source operand.
  138776. +**
  138777. +** OUTPUT:
  138778. +**
  138779. +** Nothing.
  138780. +*/
  138781. +gceSTATUS
  138782. +gcSHADER_AddSource(
  138783. + IN gcSHADER Shader,
  138784. + IN gcSL_TYPE Type,
  138785. + IN gctUINT16 SourceIndex,
  138786. + IN gctUINT8 Swizzle,
  138787. + IN gcSL_FORMAT Format
  138788. + );
  138789. +
  138790. +/*******************************************************************************
  138791. +** gcSHADER_AddSourceIndexed
  138792. +********************************************************************************
  138793. +**
  138794. +** Add a dynamically indexed source operand to a gcSHADER object.
  138795. +**
  138796. +** INPUT:
  138797. +**
  138798. +** gcSHADER Shader
  138799. +** Pointer to a gcSHADER object.
  138800. +**
  138801. +** gcSL_TYPE Type
  138802. +** Type of the source operand.
  138803. +**
  138804. +** gctUINT16 SourceIndex
  138805. +** Index of the source operand.
  138806. +**
  138807. +** gctUINT8 Swizzle
  138808. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138809. +**
  138810. +** gcSL_INDEXED Mode
  138811. +** Addressing mode for the index.
  138812. +**
  138813. +** gctUINT16 IndexRegister
  138814. +** Temporary register index that holds the dynamic index.
  138815. +**
  138816. +** gcSL_FORMAT Format
  138817. +** Format of the source operand.
  138818. +**
  138819. +** OUTPUT:
  138820. +**
  138821. +** Nothing.
  138822. +*/
  138823. +gceSTATUS
  138824. +gcSHADER_AddSourceIndexed(
  138825. + IN gcSHADER Shader,
  138826. + IN gcSL_TYPE Type,
  138827. + IN gctUINT16 SourceIndex,
  138828. + IN gctUINT8 Swizzle,
  138829. + IN gcSL_INDEXED Mode,
  138830. + IN gctUINT16 IndexRegister,
  138831. + IN gcSL_FORMAT Format
  138832. + );
  138833. +
  138834. +/*******************************************************************************
  138835. +** gcSHADER_AddSourceAttribute
  138836. +********************************************************************************
  138837. +**
  138838. +** Add an attribute as a source operand to a gcSHADER object.
  138839. +**
  138840. +** INPUT:
  138841. +**
  138842. +** gcSHADER Shader
  138843. +** Pointer to a gcSHADER object.
  138844. +**
  138845. +** gcATTRIBUTE Attribute
  138846. +** Pointer to a gcATTRIBUTE object.
  138847. +**
  138848. +** gctUINT8 Swizzle
  138849. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138850. +**
  138851. +** gctINT Index
  138852. +** Static index into the attribute in case the attribute is a matrix
  138853. +** or array.
  138854. +**
  138855. +** OUTPUT:
  138856. +**
  138857. +** Nothing.
  138858. +*/
  138859. +gceSTATUS
  138860. +gcSHADER_AddSourceAttribute(
  138861. + IN gcSHADER Shader,
  138862. + IN gcATTRIBUTE Attribute,
  138863. + IN gctUINT8 Swizzle,
  138864. + IN gctINT Index
  138865. + );
  138866. +
  138867. +/*******************************************************************************
  138868. +** gcSHADER_AddSourceAttributeIndexed
  138869. +********************************************************************************
  138870. +**
  138871. +** Add an indexed attribute as a source operand to a gcSHADER object.
  138872. +**
  138873. +** INPUT:
  138874. +**
  138875. +** gcSHADER Shader
  138876. +** Pointer to a gcSHADER object.
  138877. +**
  138878. +** gcATTRIBUTE Attribute
  138879. +** Pointer to a gcATTRIBUTE object.
  138880. +**
  138881. +** gctUINT8 Swizzle
  138882. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138883. +**
  138884. +** gctINT Index
  138885. +** Static index into the attribute in case the attribute is a matrix
  138886. +** or array.
  138887. +**
  138888. +** gcSL_INDEXED Mode
  138889. +** Addressing mode of the dynamic index.
  138890. +**
  138891. +** gctUINT16 IndexRegister
  138892. +** Temporary register index that holds the dynamic index.
  138893. +**
  138894. +** OUTPUT:
  138895. +**
  138896. +** Nothing.
  138897. +*/
  138898. +gceSTATUS
  138899. +gcSHADER_AddSourceAttributeIndexed(
  138900. + IN gcSHADER Shader,
  138901. + IN gcATTRIBUTE Attribute,
  138902. + IN gctUINT8 Swizzle,
  138903. + IN gctINT Index,
  138904. + IN gcSL_INDEXED Mode,
  138905. + IN gctUINT16 IndexRegister
  138906. + );
  138907. +
  138908. +/*******************************************************************************
  138909. +** gcSHADER_AddSourceUniform
  138910. +********************************************************************************
  138911. +**
  138912. +** Add a uniform as a source operand to a gcSHADER object.
  138913. +**
  138914. +** INPUT:
  138915. +**
  138916. +** gcSHADER Shader
  138917. +** Pointer to a gcSHADER object.
  138918. +**
  138919. +** gcUNIFORM Uniform
  138920. +** Pointer to a gcUNIFORM object.
  138921. +**
  138922. +** gctUINT8 Swizzle
  138923. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138924. +**
  138925. +** gctINT Index
  138926. +** Static index into the uniform in case the uniform is a matrix or
  138927. +** array.
  138928. +**
  138929. +** OUTPUT:
  138930. +**
  138931. +** Nothing.
  138932. +*/
  138933. +gceSTATUS
  138934. +gcSHADER_AddSourceUniform(
  138935. + IN gcSHADER Shader,
  138936. + IN gcUNIFORM Uniform,
  138937. + IN gctUINT8 Swizzle,
  138938. + IN gctINT Index
  138939. + );
  138940. +
  138941. +/*******************************************************************************
  138942. +** gcSHADER_AddSourceUniformIndexed
  138943. +********************************************************************************
  138944. +**
  138945. +** Add an indexed uniform as a source operand to a gcSHADER object.
  138946. +**
  138947. +** INPUT:
  138948. +**
  138949. +** gcSHADER Shader
  138950. +** Pointer to a gcSHADER object.
  138951. +**
  138952. +** gcUNIFORM Uniform
  138953. +** Pointer to a gcUNIFORM object.
  138954. +**
  138955. +** gctUINT8 Swizzle
  138956. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138957. +**
  138958. +** gctINT Index
  138959. +** Static index into the uniform in case the uniform is a matrix or
  138960. +** array.
  138961. +**
  138962. +** gcSL_INDEXED Mode
  138963. +** Addressing mode of the dynamic index.
  138964. +**
  138965. +** gctUINT16 IndexRegister
  138966. +** Temporary register index that holds the dynamic index.
  138967. +**
  138968. +** OUTPUT:
  138969. +**
  138970. +** Nothing.
  138971. +*/
  138972. +gceSTATUS
  138973. +gcSHADER_AddSourceUniformIndexed(
  138974. + IN gcSHADER Shader,
  138975. + IN gcUNIFORM Uniform,
  138976. + IN gctUINT8 Swizzle,
  138977. + IN gctINT Index,
  138978. + IN gcSL_INDEXED Mode,
  138979. + IN gctUINT16 IndexRegister
  138980. + );
  138981. +
  138982. +gceSTATUS
  138983. +gcSHADER_AddSourceSamplerIndexed(
  138984. + IN gcSHADER Shader,
  138985. + IN gctUINT8 Swizzle,
  138986. + IN gcSL_INDEXED Mode,
  138987. + IN gctUINT16 IndexRegister
  138988. + );
  138989. +
  138990. +gceSTATUS
  138991. +gcSHADER_AddSourceAttributeFormatted(
  138992. + IN gcSHADER Shader,
  138993. + IN gcATTRIBUTE Attribute,
  138994. + IN gctUINT8 Swizzle,
  138995. + IN gctINT Index,
  138996. + IN gcSL_FORMAT Format
  138997. + );
  138998. +
  138999. +gceSTATUS
  139000. +gcSHADER_AddSourceAttributeIndexedFormatted(
  139001. + IN gcSHADER Shader,
  139002. + IN gcATTRIBUTE Attribute,
  139003. + IN gctUINT8 Swizzle,
  139004. + IN gctINT Index,
  139005. + IN gcSL_INDEXED Mode,
  139006. + IN gctUINT16 IndexRegister,
  139007. + IN gcSL_FORMAT Format
  139008. + );
  139009. +
  139010. +gceSTATUS
  139011. +gcSHADER_AddSourceUniformFormatted(
  139012. + IN gcSHADER Shader,
  139013. + IN gcUNIFORM Uniform,
  139014. + IN gctUINT8 Swizzle,
  139015. + IN gctINT Index,
  139016. + IN gcSL_FORMAT Format
  139017. + );
  139018. +
  139019. +gceSTATUS
  139020. +gcSHADER_AddSourceUniformIndexedFormatted(
  139021. + IN gcSHADER Shader,
  139022. + IN gcUNIFORM Uniform,
  139023. + IN gctUINT8 Swizzle,
  139024. + IN gctINT Index,
  139025. + IN gcSL_INDEXED Mode,
  139026. + IN gctUINT16 IndexRegister,
  139027. + IN gcSL_FORMAT Format
  139028. + );
  139029. +
  139030. +gceSTATUS
  139031. +gcSHADER_AddSourceSamplerIndexedFormatted(
  139032. + IN gcSHADER Shader,
  139033. + IN gctUINT8 Swizzle,
  139034. + IN gcSL_INDEXED Mode,
  139035. + IN gctUINT16 IndexRegister,
  139036. + IN gcSL_FORMAT Format
  139037. + );
  139038. +
  139039. +/*******************************************************************************
  139040. +** gcSHADER_AddSourceConstant
  139041. +********************************************************************************
  139042. +**
  139043. +** Add a constant floating point value as a source operand to a gcSHADER
  139044. +** object.
  139045. +**
  139046. +** INPUT:
  139047. +**
  139048. +** gcSHADER Shader
  139049. +** Pointer to a gcSHADER object.
  139050. +**
  139051. +** gctFLOAT Constant
  139052. +** Floating point constant.
  139053. +**
  139054. +** OUTPUT:
  139055. +**
  139056. +** Nothing.
  139057. +*/
  139058. +gceSTATUS
  139059. +gcSHADER_AddSourceConstant(
  139060. + IN gcSHADER Shader,
  139061. + IN gctFLOAT Constant
  139062. + );
  139063. +
  139064. +/*******************************************************************************
  139065. +** gcSHADER_AddSourceConstantFormatted
  139066. +********************************************************************************
  139067. +**
  139068. +** Add a constant value as a source operand to a gcSHADER
  139069. +** object.
  139070. +**
  139071. +** INPUT:
  139072. +**
  139073. +** gcSHADER Shader
  139074. +** Pointer to a gcSHADER object.
  139075. +**
  139076. +** void * Constant
  139077. +** Pointer to constant.
  139078. +**
  139079. +** gcSL_FORMAT Format
  139080. +**
  139081. +** OUTPUT:
  139082. +**
  139083. +** Nothing.
  139084. +*/
  139085. +gceSTATUS
  139086. +gcSHADER_AddSourceConstantFormatted(
  139087. + IN gcSHADER Shader,
  139088. + IN void *Constant,
  139089. + IN gcSL_FORMAT Format
  139090. + );
  139091. +
  139092. +/*******************************************************************************
  139093. +** gcSHADER_Pack
  139094. +********************************************************************************
  139095. +**
  139096. +** Pack a dynamically created gcSHADER object by trimming the allocated arrays
  139097. +** and resolving all the labeling.
  139098. +**
  139099. +** INPUT:
  139100. +**
  139101. +** gcSHADER Shader
  139102. +** Pointer to a gcSHADER object.
  139103. +**
  139104. +** OUTPUT:
  139105. +**
  139106. +** Nothing.
  139107. +*/
  139108. +gceSTATUS
  139109. +gcSHADER_Pack(
  139110. + IN gcSHADER Shader
  139111. + );
  139112. +
  139113. +/*******************************************************************************
  139114. +** gcSHADER_SetOptimizationOption
  139115. +********************************************************************************
  139116. +**
  139117. +** Set optimization option of a gcSHADER object.
  139118. +**
  139119. +** INPUT:
  139120. +**
  139121. +** gcSHADER Shader
  139122. +** Pointer to a gcSHADER object.
  139123. +**
  139124. +** gctUINT OptimizationOption
  139125. +** Optimization option. Can be one of the following:
  139126. +**
  139127. +** 0 - No optimization.
  139128. +** 1 - Full optimization.
  139129. +** Other value - For optimizer testing.
  139130. +**
  139131. +** OUTPUT:
  139132. +**
  139133. +** Nothing.
  139134. +*/
  139135. +gceSTATUS
  139136. +gcSHADER_SetOptimizationOption(
  139137. + IN gcSHADER Shader,
  139138. + IN gctUINT OptimizationOption
  139139. + );
  139140. +
  139141. +/*******************************************************************************
  139142. +** gcSHADER_ReallocateFunctions
  139143. +**
  139144. +** Reallocate an array of pointers to gcFUNCTION objects.
  139145. +**
  139146. +** INPUT:
  139147. +**
  139148. +** gcSHADER Shader
  139149. +** Pointer to a gcSHADER object.
  139150. +**
  139151. +** gctSIZE_T Count
  139152. +** Array count to reallocate. 'Count' must be at least 1.
  139153. +*/
  139154. +gceSTATUS
  139155. +gcSHADER_ReallocateFunctions(
  139156. + IN gcSHADER Shader,
  139157. + IN gctSIZE_T Count
  139158. + );
  139159. +
  139160. +gceSTATUS
  139161. +gcSHADER_AddFunction(
  139162. + IN gcSHADER Shader,
  139163. + IN gctCONST_STRING Name,
  139164. + OUT gcFUNCTION * Function
  139165. + );
  139166. +
  139167. +gceSTATUS
  139168. +gcSHADER_ReallocateKernelFunctions(
  139169. + IN gcSHADER Shader,
  139170. + IN gctSIZE_T Count
  139171. + );
  139172. +
  139173. +gceSTATUS
  139174. +gcSHADER_AddKernelFunction(
  139175. + IN gcSHADER Shader,
  139176. + IN gctCONST_STRING Name,
  139177. + OUT gcKERNEL_FUNCTION * KernelFunction
  139178. + );
  139179. +
  139180. +gceSTATUS
  139181. +gcSHADER_BeginFunction(
  139182. + IN gcSHADER Shader,
  139183. + IN gcFUNCTION Function
  139184. + );
  139185. +
  139186. +gceSTATUS
  139187. +gcSHADER_EndFunction(
  139188. + IN gcSHADER Shader,
  139189. + IN gcFUNCTION Function
  139190. + );
  139191. +
  139192. +gceSTATUS
  139193. +gcSHADER_BeginKernelFunction(
  139194. + IN gcSHADER Shader,
  139195. + IN gcKERNEL_FUNCTION KernelFunction
  139196. + );
  139197. +
  139198. +gceSTATUS
  139199. +gcSHADER_EndKernelFunction(
  139200. + IN gcSHADER Shader,
  139201. + IN gcKERNEL_FUNCTION KernelFunction,
  139202. + IN gctSIZE_T LocalMemorySize
  139203. + );
  139204. +
  139205. +gceSTATUS
  139206. +gcSHADER_SetMaxKernelFunctionArgs(
  139207. + IN gcSHADER Shader,
  139208. + IN gctUINT32 MaxKernelFunctionArgs
  139209. + );
  139210. +
  139211. +/*******************************************************************************
  139212. +** gcSHADER_SetConstantMemorySize
  139213. +**
  139214. +** Set the constant memory address space size of a gcSHADER object.
  139215. +**
  139216. +** INPUT:
  139217. +**
  139218. +** gcSHADER Shader
  139219. +** Pointer to a gcSHADER object.
  139220. +**
  139221. +** gctSIZE_T ConstantMemorySize
  139222. +** Constant memory size in bytes
  139223. +**
  139224. +** gctCHAR *ConstantMemoryBuffer
  139225. +** Constant memory buffer
  139226. +*/
  139227. +gceSTATUS
  139228. +gcSHADER_SetConstantMemorySize(
  139229. + IN gcSHADER Shader,
  139230. + IN gctSIZE_T ConstantMemorySize,
  139231. + IN gctCHAR * ConstantMemoryBuffer
  139232. + );
  139233. +
  139234. +/*******************************************************************************
  139235. +** gcSHADER_GetConstantMemorySize
  139236. +**
  139237. +** Set the constant memory address space size of a gcSHADER object.
  139238. +**
  139239. +** INPUT:
  139240. +**
  139241. +** gcSHADER Shader
  139242. +** Pointer to a gcSHADER object.
  139243. +**
  139244. +** OUTPUT:
  139245. +**
  139246. +** gctSIZE_T * ConstantMemorySize
  139247. +** Pointer to a variable receiving constant memory size in bytes
  139248. +**
  139249. +** gctCHAR **ConstantMemoryBuffer.
  139250. +** Pointer to a variable for returned shader constant memory buffer.
  139251. +*/
  139252. +gceSTATUS
  139253. +gcSHADER_GetConstantMemorySize(
  139254. + IN gcSHADER Shader,
  139255. + OUT gctSIZE_T * ConstantMemorySize,
  139256. + OUT gctCHAR ** ConstantMemoryBuffer
  139257. + );
  139258. +
  139259. +/*******************************************************************************
  139260. +** gcSHADER_SetPrivateMemorySize
  139261. +**
  139262. +** Set the private memory address space size of a gcSHADER object.
  139263. +**
  139264. +** INPUT:
  139265. +**
  139266. +** gcSHADER Shader
  139267. +** Pointer to a gcSHADER object.
  139268. +**
  139269. +** gctSIZE_T PrivateMemorySize
  139270. +** Private memory size in bytes
  139271. +*/
  139272. +gceSTATUS
  139273. +gcSHADER_SetPrivateMemorySize(
  139274. + IN gcSHADER Shader,
  139275. + IN gctSIZE_T PrivateMemorySize
  139276. + );
  139277. +
  139278. +/*******************************************************************************
  139279. +** gcSHADER_GetPrivateMemorySize
  139280. +**
  139281. +** Set the private memory address space size of a gcSHADER object.
  139282. +**
  139283. +** INPUT:
  139284. +**
  139285. +** gcSHADER Shader
  139286. +** Pointer to a gcSHADER object.
  139287. +**
  139288. +** OUTPUT:
  139289. +**
  139290. +** gctSIZE_T * PrivateMemorySize
  139291. +** Pointer to a variable receiving private memory size in bytes
  139292. +*/
  139293. +gceSTATUS
  139294. +gcSHADER_GetPrivateMemorySize(
  139295. + IN gcSHADER Shader,
  139296. + OUT gctSIZE_T * PrivateMemorySize
  139297. + );
  139298. +
  139299. +/*******************************************************************************
  139300. +** gcSHADER_SetLocalMemorySize
  139301. +**
  139302. +** Set the local memory address space size of a gcSHADER object.
  139303. +**
  139304. +** INPUT:
  139305. +**
  139306. +** gcSHADER Shader
  139307. +** Pointer to a gcSHADER object.
  139308. +**
  139309. +** gctSIZE_T LocalMemorySize
  139310. +** Local memory size in bytes
  139311. +*/
  139312. +gceSTATUS
  139313. +gcSHADER_SetLocalMemorySize(
  139314. + IN gcSHADER Shader,
  139315. + IN gctSIZE_T LocalMemorySize
  139316. + );
  139317. +
  139318. +/*******************************************************************************
  139319. +** gcSHADER_GetLocalMemorySize
  139320. +**
  139321. +** Set the local memory address space size of a gcSHADER object.
  139322. +**
  139323. +** INPUT:
  139324. +**
  139325. +** gcSHADER Shader
  139326. +** Pointer to a gcSHADER object.
  139327. +**
  139328. +** OUTPUT:
  139329. +**
  139330. +** gctSIZE_T * LocalMemorySize
  139331. +** Pointer to a variable receiving lcoal memory size in bytes
  139332. +*/
  139333. +gceSTATUS
  139334. +gcSHADER_GetLocalMemorySize(
  139335. + IN gcSHADER Shader,
  139336. + OUT gctSIZE_T * LocalMemorySize
  139337. + );
  139338. +
  139339. +
  139340. +/*******************************************************************************
  139341. +** gcSHADER_CheckValidity
  139342. +**
  139343. +** Check validity for a gcSHADER object.
  139344. +**
  139345. +** INPUT:
  139346. +**
  139347. +** gcSHADER Shader
  139348. +** Pointer to a gcSHADER object.
  139349. +**
  139350. +*/
  139351. +gceSTATUS
  139352. +gcSHADER_CheckValidity(
  139353. + IN gcSHADER Shader
  139354. + );
  139355. +
  139356. +#if gcdUSE_WCLIP_PATCH
  139357. +gceSTATUS
  139358. +gcATTRIBUTE_IsPosition(
  139359. + IN gcATTRIBUTE Attribute,
  139360. + OUT gctBOOL * IsPosition
  139361. + );
  139362. +#endif
  139363. +
  139364. +/*******************************************************************************
  139365. +** gcATTRIBUTE_GetType
  139366. +********************************************************************************
  139367. +**
  139368. +** Get the type and array length of a gcATTRIBUTE object.
  139369. +**
  139370. +** INPUT:
  139371. +**
  139372. +** gcATTRIBUTE Attribute
  139373. +** Pointer to a gcATTRIBUTE object.
  139374. +**
  139375. +** OUTPUT:
  139376. +**
  139377. +** gcSHADER_TYPE * Type
  139378. +** Pointer to a variable receiving the type of the attribute. 'Type'
  139379. +** can be gcvNULL, in which case no type will be returned.
  139380. +**
  139381. +** gctSIZE_T * ArrayLength
  139382. +** Pointer to a variable receiving the length of the array if the
  139383. +** attribute was declared as an array. If the attribute was not
  139384. +** declared as an array, the array length will be 1. 'ArrayLength' can
  139385. +** be gcvNULL, in which case no array length will be returned.
  139386. +*/
  139387. +gceSTATUS
  139388. +gcATTRIBUTE_GetType(
  139389. + IN gcATTRIBUTE Attribute,
  139390. + OUT gcSHADER_TYPE * Type,
  139391. + OUT gctSIZE_T * ArrayLength
  139392. + );
  139393. +
  139394. +/*******************************************************************************
  139395. +** gcATTRIBUTE_GetName
  139396. +********************************************************************************
  139397. +**
  139398. +** Get the name of a gcATTRIBUTE object.
  139399. +**
  139400. +** INPUT:
  139401. +**
  139402. +** gcATTRIBUTE Attribute
  139403. +** Pointer to a gcATTRIBUTE object.
  139404. +**
  139405. +** OUTPUT:
  139406. +**
  139407. +** gctSIZE_T * Length
  139408. +** Pointer to a variable receiving the length of the attribute name.
  139409. +** 'Length' can be gcvNULL, in which case no length will be returned.
  139410. +**
  139411. +** gctCONST_STRING * Name
  139412. +** Pointer to a variable receiving the pointer to the attribute name.
  139413. +** 'Name' can be gcvNULL, in which case no name will be returned.
  139414. +*/
  139415. +gceSTATUS
  139416. +gcATTRIBUTE_GetName(
  139417. + IN gcATTRIBUTE Attribute,
  139418. + OUT gctSIZE_T * Length,
  139419. + OUT gctCONST_STRING * Name
  139420. + );
  139421. +
  139422. +/*******************************************************************************
  139423. +** gcATTRIBUTE_IsEnabled
  139424. +********************************************************************************
  139425. +**
  139426. +** Query the enabled state of a gcATTRIBUTE object.
  139427. +**
  139428. +** INPUT:
  139429. +**
  139430. +** gcATTRIBUTE Attribute
  139431. +** Pointer to a gcATTRIBUTE object.
  139432. +**
  139433. +** OUTPUT:
  139434. +**
  139435. +** gctBOOL * Enabled
  139436. +** Pointer to a variable receiving the enabled state of the attribute.
  139437. +*/
  139438. +gceSTATUS
  139439. +gcATTRIBUTE_IsEnabled(
  139440. + IN gcATTRIBUTE Attribute,
  139441. + OUT gctBOOL * Enabled
  139442. + );
  139443. +
  139444. +/*******************************************************************************
  139445. +** gcUNIFORM_GetType
  139446. +********************************************************************************
  139447. +**
  139448. +** Get the type and array length of a gcUNIFORM object.
  139449. +**
  139450. +** INPUT:
  139451. +**
  139452. +** gcUNIFORM Uniform
  139453. +** Pointer to a gcUNIFORM object.
  139454. +**
  139455. +** OUTPUT:
  139456. +**
  139457. +** gcSHADER_TYPE * Type
  139458. +** Pointer to a variable receiving the type of the uniform. 'Type' can
  139459. +** be gcvNULL, in which case no type will be returned.
  139460. +**
  139461. +** gctSIZE_T * ArrayLength
  139462. +** Pointer to a variable receiving the length of the array if the
  139463. +** uniform was declared as an array. If the uniform was not declared
  139464. +** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
  139465. +** in which case no array length will be returned.
  139466. +*/
  139467. +gceSTATUS
  139468. +gcUNIFORM_GetType(
  139469. + IN gcUNIFORM Uniform,
  139470. + OUT gcSHADER_TYPE * Type,
  139471. + OUT gctSIZE_T * ArrayLength
  139472. + );
  139473. +
  139474. +/*******************************************************************************
  139475. +** gcUNIFORM_GetTypeEx
  139476. +********************************************************************************
  139477. +**
  139478. +** Get the type and array length of a gcUNIFORM object.
  139479. +**
  139480. +** INPUT:
  139481. +**
  139482. +** gcUNIFORM Uniform
  139483. +** Pointer to a gcUNIFORM object.
  139484. +**
  139485. +** OUTPUT:
  139486. +**
  139487. +** gcSHADER_TYPE * Type
  139488. +** Pointer to a variable receiving the type of the uniform. 'Type' can
  139489. +** be gcvNULL, in which case no type will be returned.
  139490. +**
  139491. +** gcSHADER_PRECISION * Precision
  139492. +** Pointer to a variable receiving the precision of the uniform. 'Precision' can
  139493. +** be gcvNULL, in which case no type will be returned.
  139494. +**
  139495. +** gctSIZE_T * ArrayLength
  139496. +** Pointer to a variable receiving the length of the array if the
  139497. +** uniform was declared as an array. If the uniform was not declared
  139498. +** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
  139499. +** in which case no array length will be returned.
  139500. +*/
  139501. +gceSTATUS
  139502. +gcUNIFORM_GetTypeEx(
  139503. + IN gcUNIFORM Uniform,
  139504. + OUT gcSHADER_TYPE * Type,
  139505. + OUT gcSHADER_PRECISION * Precision,
  139506. + OUT gctSIZE_T * ArrayLength
  139507. + );
  139508. +
  139509. +/*******************************************************************************
  139510. +** gcUNIFORM_GetFlags
  139511. +********************************************************************************
  139512. +**
  139513. +** Get the flags of a gcUNIFORM object.
  139514. +**
  139515. +** INPUT:
  139516. +**
  139517. +** gcUNIFORM Uniform
  139518. +** Pointer to a gcUNIFORM object.
  139519. +**
  139520. +** OUTPUT:
  139521. +**
  139522. +** gceUNIFORM_FLAGS * Flags
  139523. +** Pointer to a variable receiving the flags of the uniform.
  139524. +**
  139525. +*/
  139526. +gceSTATUS
  139527. +gcUNIFORM_GetFlags(
  139528. + IN gcUNIFORM Uniform,
  139529. + OUT gceUNIFORM_FLAGS * Flags
  139530. + );
  139531. +
  139532. +/*******************************************************************************
  139533. +** gcUNIFORM_SetFlags
  139534. +********************************************************************************
  139535. +**
  139536. +** Set the flags of a gcUNIFORM object.
  139537. +**
  139538. +** INPUT:
  139539. +**
  139540. +** gcUNIFORM Uniform
  139541. +** Pointer to a gcUNIFORM object.
  139542. +**
  139543. +** gceUNIFORM_FLAGS Flags
  139544. +** Flags of the uniform to be set.
  139545. +**
  139546. +** OUTPUT:
  139547. +** Nothing.
  139548. +**
  139549. +*/
  139550. +gceSTATUS
  139551. +gcUNIFORM_SetFlags(
  139552. + IN gcUNIFORM Uniform,
  139553. + IN gceUNIFORM_FLAGS Flags
  139554. + );
  139555. +
  139556. +/*******************************************************************************
  139557. +** gcUNIFORM_GetName
  139558. +********************************************************************************
  139559. +**
  139560. +** Get the name of a gcUNIFORM object.
  139561. +**
  139562. +** INPUT:
  139563. +**
  139564. +** gcUNIFORM Uniform
  139565. +** Pointer to a gcUNIFORM object.
  139566. +**
  139567. +** OUTPUT:
  139568. +**
  139569. +** gctSIZE_T * Length
  139570. +** Pointer to a variable receiving the length of the uniform name.
  139571. +** 'Length' can be gcvNULL, in which case no length will be returned.
  139572. +**
  139573. +** gctCONST_STRING * Name
  139574. +** Pointer to a variable receiving the pointer to the uniform name.
  139575. +** 'Name' can be gcvNULL, in which case no name will be returned.
  139576. +*/
  139577. +gceSTATUS
  139578. +gcUNIFORM_GetName(
  139579. + IN gcUNIFORM Uniform,
  139580. + OUT gctSIZE_T * Length,
  139581. + OUT gctCONST_STRING * Name
  139582. + );
  139583. +
  139584. +/*******************************************************************************
  139585. +** gcUNIFORM_GetSampler
  139586. +********************************************************************************
  139587. +**
  139588. +** Get the physical sampler number for a sampler gcUNIFORM object.
  139589. +**
  139590. +** INPUT:
  139591. +**
  139592. +** gcUNIFORM Uniform
  139593. +** Pointer to a gcUNIFORM object.
  139594. +**
  139595. +** OUTPUT:
  139596. +**
  139597. +** gctUINT32 * Sampler
  139598. +** Pointer to a variable receiving the physical sampler.
  139599. +*/
  139600. +gceSTATUS
  139601. +gcUNIFORM_GetSampler(
  139602. + IN gcUNIFORM Uniform,
  139603. + OUT gctUINT32 * Sampler
  139604. + );
  139605. +
  139606. +/*******************************************************************************
  139607. +** gcUNIFORM_GetFormat
  139608. +**
  139609. +** Get the type and array length of a gcUNIFORM object.
  139610. +**
  139611. +** INPUT:
  139612. +**
  139613. +** gcUNIFORM Uniform
  139614. +** Pointer to a gcUNIFORM object.
  139615. +**
  139616. +** OUTPUT:
  139617. +**
  139618. +** gcSL_FORMAT * Format
  139619. +** Pointer to a variable receiving the format of element of the uniform.
  139620. +** 'Type' can be gcvNULL, in which case no type will be returned.
  139621. +**
  139622. +** gctBOOL * IsPointer
  139623. +** Pointer to a variable receiving the state wheter the uniform is a pointer.
  139624. +** 'IsPointer' can be gcvNULL, in which case no array length will be returned.
  139625. +*/
  139626. +gceSTATUS
  139627. +gcUNIFORM_GetFormat(
  139628. + IN gcUNIFORM Uniform,
  139629. + OUT gcSL_FORMAT * Format,
  139630. + OUT gctBOOL * IsPointer
  139631. + );
  139632. +
  139633. +/*******************************************************************************
  139634. +** gcUNIFORM_SetFormat
  139635. +**
  139636. +** Set the format and isPointer of a uniform.
  139637. +**
  139638. +** INPUT:
  139639. +**
  139640. +** gcUNIFORM Uniform
  139641. +** Pointer to a gcUNIFORM object.
  139642. +**
  139643. +** gcSL_FORMAT Format
  139644. +** Format of element of the uniform shaderType.
  139645. +**
  139646. +** gctBOOL IsPointer
  139647. +** Wheter the uniform is a pointer.
  139648. +**
  139649. +** OUTPUT:
  139650. +**
  139651. +** Nothing.
  139652. +*/
  139653. +gceSTATUS
  139654. +gcUNIFORM_SetFormat(
  139655. + IN gcUNIFORM Uniform,
  139656. + IN gcSL_FORMAT Format,
  139657. + IN gctBOOL IsPointer
  139658. + );
  139659. +
  139660. +/*******************************************************************************
  139661. +** gcUNIFORM_SetValue
  139662. +********************************************************************************
  139663. +**
  139664. +** Set the value of a uniform in integer.
  139665. +**
  139666. +** INPUT:
  139667. +**
  139668. +** gcUNIFORM Uniform
  139669. +** Pointer to a gcUNIFORM object.
  139670. +**
  139671. +** gctSIZE_T Count
  139672. +** Number of entries to program if the uniform has been declared as an
  139673. +** array.
  139674. +**
  139675. +** const gctINT * Value
  139676. +** Pointer to a buffer holding the integer values for the uniform.
  139677. +**
  139678. +** OUTPUT:
  139679. +**
  139680. +** Nothing.
  139681. +*/
  139682. +gceSTATUS
  139683. +gcUNIFORM_SetValue(
  139684. + IN gcUNIFORM Uniform,
  139685. + IN gctSIZE_T Count,
  139686. + IN const gctINT * Value
  139687. + );
  139688. +
  139689. +/*******************************************************************************
  139690. +** gcUNIFORM_SetValueX
  139691. +********************************************************************************
  139692. +**
  139693. +** Set the value of a uniform in fixed point.
  139694. +**
  139695. +** INPUT:
  139696. +**
  139697. +** gcUNIFORM Uniform
  139698. +** Pointer to a gcUNIFORM object.
  139699. +**
  139700. +** gctSIZE_T Count
  139701. +** Number of entries to program if the uniform has been declared as an
  139702. +** array.
  139703. +**
  139704. +** const gctFIXED_POINT * Value
  139705. +** Pointer to a buffer holding the fixed point values for the uniform.
  139706. +**
  139707. +** OUTPUT:
  139708. +**
  139709. +** Nothing.
  139710. +*/
  139711. +gceSTATUS
  139712. +gcUNIFORM_SetValueX(
  139713. + IN gcUNIFORM Uniform,
  139714. + IN gctSIZE_T Count,
  139715. + IN gctFIXED_POINT * Value
  139716. + );
  139717. +
  139718. +/*******************************************************************************
  139719. +** gcUNIFORM_SetValueF
  139720. +********************************************************************************
  139721. +**
  139722. +** Set the value of a uniform in floating point.
  139723. +**
  139724. +** INPUT:
  139725. +**
  139726. +** gcUNIFORM Uniform
  139727. +** Pointer to a gcUNIFORM object.
  139728. +**
  139729. +** gctSIZE_T Count
  139730. +** Number of entries to program if the uniform has been declared as an
  139731. +** array.
  139732. +**
  139733. +** const gctFLOAT * Value
  139734. +** Pointer to a buffer holding the floating point values for the
  139735. +** uniform.
  139736. +**
  139737. +** OUTPUT:
  139738. +**
  139739. +** Nothing.
  139740. +*/
  139741. +gceSTATUS
  139742. +gcUNIFORM_SetValueF(
  139743. + IN gcUNIFORM Uniform,
  139744. + IN gctSIZE_T Count,
  139745. + IN const gctFLOAT * Value
  139746. + );
  139747. +
  139748. +/*******************************************************************************
  139749. +** gcUNIFORM_ProgramF
  139750. +**
  139751. +** Set the value of a uniform in floating point.
  139752. +**
  139753. +** INPUT:
  139754. +**
  139755. +** gctUINT32 Address
  139756. +** Address of Uniform.
  139757. +**
  139758. +** gctSIZE_T Row/Col
  139759. +**
  139760. +** const gctFLOAT * Value
  139761. +** Pointer to a buffer holding the floating point values for the
  139762. +** uniform.
  139763. +**
  139764. +** OUTPUT:
  139765. +**
  139766. +** Nothing.
  139767. +*/
  139768. +gceSTATUS
  139769. +gcUNIFORM_ProgramF(
  139770. + IN gctUINT32 Address,
  139771. + IN gctSIZE_T Row,
  139772. + IN gctSIZE_T Col,
  139773. + IN const gctFLOAT * Value
  139774. + );
  139775. +
  139776. +/*******************************************************************************
  139777. +** gcUNIFORM_GetModelViewProjMatrix
  139778. +********************************************************************************
  139779. +**
  139780. +** Get the value of uniform modelViewProjMatrix ID if present.
  139781. +**
  139782. +** INPUT:
  139783. +**
  139784. +** gcUNIFORM Uniform
  139785. +** Pointer to a gcUNIFORM object.
  139786. +**
  139787. +** OUTPUT:
  139788. +**
  139789. +** Nothing.
  139790. +*/
  139791. +gctUINT
  139792. +gcUNIFORM_GetModelViewProjMatrix(
  139793. + IN gcUNIFORM Uniform
  139794. + );
  139795. +
  139796. +/*******************************************************************************
  139797. +** gcOUTPUT_GetType
  139798. +********************************************************************************
  139799. +**
  139800. +** Get the type and array length of a gcOUTPUT object.
  139801. +**
  139802. +** INPUT:
  139803. +**
  139804. +** gcOUTPUT Output
  139805. +** Pointer to a gcOUTPUT object.
  139806. +**
  139807. +** OUTPUT:
  139808. +**
  139809. +** gcSHADER_TYPE * Type
  139810. +** Pointer to a variable receiving the type of the output. 'Type' can
  139811. +** be gcvNULL, in which case no type will be returned.
  139812. +**
  139813. +** gctSIZE_T * ArrayLength
  139814. +** Pointer to a variable receiving the length of the array if the
  139815. +** output was declared as an array. If the output was not declared
  139816. +** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
  139817. +** in which case no array length will be returned.
  139818. +*/
  139819. +gceSTATUS
  139820. +gcOUTPUT_GetType(
  139821. + IN gcOUTPUT Output,
  139822. + OUT gcSHADER_TYPE * Type,
  139823. + OUT gctSIZE_T * ArrayLength
  139824. + );
  139825. +
  139826. +/*******************************************************************************
  139827. +** gcOUTPUT_GetIndex
  139828. +********************************************************************************
  139829. +**
  139830. +** Get the index of a gcOUTPUT object.
  139831. +**
  139832. +** INPUT:
  139833. +**
  139834. +** gcOUTPUT Output
  139835. +** Pointer to a gcOUTPUT object.
  139836. +**
  139837. +** OUTPUT:
  139838. +**
  139839. +** gctUINT * Index
  139840. +** Pointer to a variable receiving the temporary register index of the
  139841. +** output. 'Index' can be gcvNULL,. in which case no index will be
  139842. +** returned.
  139843. +*/
  139844. +gceSTATUS
  139845. +gcOUTPUT_GetIndex(
  139846. + IN gcOUTPUT Output,
  139847. + OUT gctUINT * Index
  139848. + );
  139849. +
  139850. +/*******************************************************************************
  139851. +** gcOUTPUT_GetName
  139852. +********************************************************************************
  139853. +**
  139854. +** Get the name of a gcOUTPUT object.
  139855. +**
  139856. +** INPUT:
  139857. +**
  139858. +** gcOUTPUT Output
  139859. +** Pointer to a gcOUTPUT object.
  139860. +**
  139861. +** OUTPUT:
  139862. +**
  139863. +** gctSIZE_T * Length
  139864. +** Pointer to a variable receiving the length of the output name.
  139865. +** 'Length' can be gcvNULL, in which case no length will be returned.
  139866. +**
  139867. +** gctCONST_STRING * Name
  139868. +** Pointer to a variable receiving the pointer to the output name.
  139869. +** 'Name' can be gcvNULL, in which case no name will be returned.
  139870. +*/
  139871. +gceSTATUS
  139872. +gcOUTPUT_GetName(
  139873. + IN gcOUTPUT Output,
  139874. + OUT gctSIZE_T * Length,
  139875. + OUT gctCONST_STRING * Name
  139876. + );
  139877. +
  139878. +/*******************************************************************************
  139879. +*********************************************************** F U N C T I O N S **
  139880. +*******************************************************************************/
  139881. +
  139882. +/*******************************************************************************
  139883. +** gcFUNCTION_ReallocateArguments
  139884. +**
  139885. +** Reallocate an array of gcsFUNCTION_ARGUMENT objects.
  139886. +**
  139887. +** INPUT:
  139888. +**
  139889. +** gcFUNCTION Function
  139890. +** Pointer to a gcFUNCTION object.
  139891. +**
  139892. +** gctSIZE_T Count
  139893. +** Array count to reallocate. 'Count' must be at least 1.
  139894. +*/
  139895. +gceSTATUS
  139896. +gcFUNCTION_ReallocateArguments(
  139897. + IN gcFUNCTION Function,
  139898. + IN gctSIZE_T Count
  139899. + );
  139900. +
  139901. +gceSTATUS
  139902. +gcFUNCTION_AddArgument(
  139903. + IN gcFUNCTION Function,
  139904. + IN gctUINT16 TempIndex,
  139905. + IN gctUINT8 Enable,
  139906. + IN gctUINT8 Qualifier
  139907. + );
  139908. +
  139909. +gceSTATUS
  139910. +gcFUNCTION_GetArgument(
  139911. + IN gcFUNCTION Function,
  139912. + IN gctUINT16 Index,
  139913. + OUT gctUINT16_PTR Temp,
  139914. + OUT gctUINT8_PTR Enable,
  139915. + OUT gctUINT8_PTR Swizzle
  139916. + );
  139917. +
  139918. +gceSTATUS
  139919. +gcFUNCTION_GetLabel(
  139920. + IN gcFUNCTION Function,
  139921. + OUT gctUINT_PTR Label
  139922. + );
  139923. +
  139924. +/*******************************************************************************
  139925. +************************* K E R N E L P R O P E R T Y F U N C T I O N S **
  139926. +*******************************************************************************/
  139927. +/*******************************************************************************/
  139928. +gceSTATUS
  139929. +gcKERNEL_FUNCTION_AddKernelFunctionProperties(
  139930. + IN gcKERNEL_FUNCTION KernelFunction,
  139931. + IN gctINT propertyType,
  139932. + IN gctSIZE_T propertySize,
  139933. + IN gctINT * values
  139934. + );
  139935. +
  139936. +gceSTATUS
  139937. +gcKERNEL_FUNCTION_GetPropertyCount(
  139938. + IN gcKERNEL_FUNCTION KernelFunction,
  139939. + OUT gctSIZE_T * Count
  139940. + );
  139941. +
  139942. +gceSTATUS
  139943. +gcKERNEL_FUNCTION_GetProperty(
  139944. + IN gcKERNEL_FUNCTION KernelFunction,
  139945. + IN gctUINT Index,
  139946. + OUT gctSIZE_T * propertySize,
  139947. + OUT gctINT * propertyType,
  139948. + OUT gctINT * propertyValues
  139949. + );
  139950. +
  139951. +
  139952. +/*******************************************************************************
  139953. +*******************************I M A G E S A M P L E R F U N C T I O N S **
  139954. +*******************************************************************************/
  139955. +/*******************************************************************************
  139956. +** gcKERNEL_FUNCTION_ReallocateImageSamplers
  139957. +**
  139958. +** Reallocate an array of pointers to image sampler pair.
  139959. +**
  139960. +** INPUT:
  139961. +**
  139962. +** gcKERNEL_FUNCTION KernelFunction
  139963. +** Pointer to a gcKERNEL_FUNCTION object.
  139964. +**
  139965. +** gctSIZE_T Count
  139966. +** Array count to reallocate. 'Count' must be at least 1.
  139967. +*/
  139968. +gceSTATUS
  139969. +gcKERNEL_FUNCTION_ReallocateImageSamplers(
  139970. + IN gcKERNEL_FUNCTION KernelFunction,
  139971. + IN gctSIZE_T Count
  139972. + );
  139973. +
  139974. +gceSTATUS
  139975. +gcKERNEL_FUNCTION_AddImageSampler(
  139976. + IN gcKERNEL_FUNCTION KernelFunction,
  139977. + IN gctUINT8 ImageNum,
  139978. + IN gctBOOL IsConstantSamplerType,
  139979. + IN gctUINT32 SamplerType
  139980. + );
  139981. +
  139982. +gceSTATUS
  139983. +gcKERNEL_FUNCTION_GetImageSamplerCount(
  139984. + IN gcKERNEL_FUNCTION KernelFunction,
  139985. + OUT gctSIZE_T * Count
  139986. + );
  139987. +
  139988. +gceSTATUS
  139989. +gcKERNEL_FUNCTION_GetImageSampler(
  139990. + IN gcKERNEL_FUNCTION KernelFunction,
  139991. + IN gctUINT Index,
  139992. + OUT gctUINT8 *ImageNum,
  139993. + OUT gctBOOL *IsConstantSamplerType,
  139994. + OUT gctUINT32 *SamplerType
  139995. + );
  139996. +
  139997. +/*******************************************************************************
  139998. +*********************************************K E R N E L F U N C T I O N S **
  139999. +*******************************************************************************/
  140000. +
  140001. +/*******************************************************************************
  140002. +** gcKERNEL_FUNCTION_ReallocateArguments
  140003. +**
  140004. +** Reallocate an array of gcsFUNCTION_ARGUMENT objects.
  140005. +**
  140006. +** INPUT:
  140007. +**
  140008. +** gcKERNEL_FUNCTION Function
  140009. +** Pointer to a gcKERNEL_FUNCTION object.
  140010. +**
  140011. +** gctSIZE_T Count
  140012. +** Array count to reallocate. 'Count' must be at least 1.
  140013. +*/
  140014. +gceSTATUS
  140015. +gcKERNEL_FUNCTION_ReallocateArguments(
  140016. + IN gcKERNEL_FUNCTION Function,
  140017. + IN gctSIZE_T Count
  140018. + );
  140019. +
  140020. +gceSTATUS
  140021. +gcKERNEL_FUNCTION_AddArgument(
  140022. + IN gcKERNEL_FUNCTION Function,
  140023. + IN gctUINT16 TempIndex,
  140024. + IN gctUINT8 Enable,
  140025. + IN gctUINT8 Qualifier
  140026. + );
  140027. +
  140028. +gceSTATUS
  140029. +gcKERNEL_FUNCTION_GetArgument(
  140030. + IN gcKERNEL_FUNCTION Function,
  140031. + IN gctUINT16 Index,
  140032. + OUT gctUINT16_PTR Temp,
  140033. + OUT gctUINT8_PTR Enable,
  140034. + OUT gctUINT8_PTR Swizzle
  140035. + );
  140036. +
  140037. +gceSTATUS
  140038. +gcKERNEL_FUNCTION_GetLabel(
  140039. + IN gcKERNEL_FUNCTION Function,
  140040. + OUT gctUINT_PTR Label
  140041. + );
  140042. +
  140043. +gceSTATUS
  140044. +gcKERNEL_FUNCTION_GetName(
  140045. + IN gcKERNEL_FUNCTION KernelFunction,
  140046. + OUT gctSIZE_T * Length,
  140047. + OUT gctCONST_STRING * Name
  140048. + );
  140049. +
  140050. +gceSTATUS
  140051. +gcKERNEL_FUNCTION_ReallocateUniformArguments(
  140052. + IN gcKERNEL_FUNCTION KernelFunction,
  140053. + IN gctSIZE_T Count
  140054. + );
  140055. +
  140056. +gceSTATUS
  140057. +gcKERNEL_FUNCTION_AddUniformArgument(
  140058. + IN gcKERNEL_FUNCTION KernelFunction,
  140059. + IN gctCONST_STRING Name,
  140060. + IN gcSHADER_TYPE Type,
  140061. + IN gctSIZE_T Length,
  140062. + OUT gcUNIFORM * UniformArgument
  140063. + );
  140064. +
  140065. +gceSTATUS
  140066. +gcKERNEL_FUNCTION_GetUniformArgumentCount(
  140067. + IN gcKERNEL_FUNCTION KernelFunction,
  140068. + OUT gctSIZE_T * Count
  140069. + );
  140070. +
  140071. +gceSTATUS
  140072. +gcKERNEL_FUNCTION_GetUniformArgument(
  140073. + IN gcKERNEL_FUNCTION KernelFunction,
  140074. + IN gctUINT Index,
  140075. + OUT gcUNIFORM * UniformArgument
  140076. + );
  140077. +
  140078. +gceSTATUS
  140079. +gcKERNEL_FUNCTION_SetCodeEnd(
  140080. + IN gcKERNEL_FUNCTION KernelFunction
  140081. + );
  140082. +
  140083. +/*******************************************************************************
  140084. +** gcCompileShader
  140085. +********************************************************************************
  140086. +**
  140087. +** Compile a shader.
  140088. +**
  140089. +** INPUT:
  140090. +**
  140091. +** gcoOS Hal
  140092. +** Pointer to an gcoHAL object.
  140093. +**
  140094. +** gctINT ShaderType
  140095. +** Shader type to compile. Can be one of the following values:
  140096. +**
  140097. +** gcSHADER_TYPE_VERTEX
  140098. +** Compile a vertex shader.
  140099. +**
  140100. +** gcSHADER_TYPE_FRAGMENT
  140101. +** Compile a fragment shader.
  140102. +**
  140103. +** gctSIZE_T SourceSize
  140104. +** Size of the source buffer in bytes.
  140105. +**
  140106. +** gctCONST_STRING Source
  140107. +** Pointer to the buffer containing the shader source code.
  140108. +**
  140109. +** OUTPUT:
  140110. +**
  140111. +** gcSHADER * Binary
  140112. +** Pointer to a variable receiving the pointer to a gcSHADER object
  140113. +** containg the compiled shader code.
  140114. +**
  140115. +** gctSTRING * Log
  140116. +** Pointer to a variable receiving a string pointer containging the
  140117. +** compile log.
  140118. +*/
  140119. +gceSTATUS
  140120. +gcCompileShader(
  140121. + IN gcoHAL Hal,
  140122. + IN gctINT ShaderType,
  140123. + IN gctSIZE_T SourceSize,
  140124. + IN gctCONST_STRING Source,
  140125. + OUT gcSHADER * Binary,
  140126. + OUT gctSTRING * Log
  140127. + );
  140128. +
  140129. +/*******************************************************************************
  140130. +** gcOptimizeShader
  140131. +********************************************************************************
  140132. +**
  140133. +** Optimize a shader.
  140134. +**
  140135. +** INPUT:
  140136. +**
  140137. +** gcSHADER Shader
  140138. +** Pointer to a gcSHADER object holding information about the compiled
  140139. +** shader.
  140140. +**
  140141. +** gctFILE LogFile
  140142. +** Pointer to an open FILE object.
  140143. +*/
  140144. +gceSTATUS
  140145. +gcOptimizeShader(
  140146. + IN gcSHADER Shader,
  140147. + IN gctFILE LogFile
  140148. + );
  140149. +
  140150. +/*******************************************************************************
  140151. +** gcLinkShaders
  140152. +********************************************************************************
  140153. +**
  140154. +** Link two shaders and generate a harwdare specific state buffer by compiling
  140155. +** the compiler generated code through the resource allocator and code
  140156. +** generator.
  140157. +**
  140158. +** INPUT:
  140159. +**
  140160. +** gcSHADER VertexShader
  140161. +** Pointer to a gcSHADER object holding information about the compiled
  140162. +** vertex shader.
  140163. +**
  140164. +** gcSHADER FragmentShader
  140165. +** Pointer to a gcSHADER object holding information about the compiled
  140166. +** fragment shader.
  140167. +**
  140168. +** gceSHADER_FLAGS Flags
  140169. +** Compiler flags. Can be any of the following:
  140170. +**
  140171. +** gcvSHADER_DEAD_CODE - Dead code elimination.
  140172. +** gcvSHADER_RESOURCE_USAGE - Resource usage optimizaion.
  140173. +** gcvSHADER_OPTIMIZER - Full optimization.
  140174. +** gcvSHADER_USE_GL_Z - Use OpenGL ES Z coordinate.
  140175. +** gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position.
  140176. +** gcvSHADER_USE_GL_FACE - Use OpenGL ES gl_FaceForward.
  140177. +**
  140178. +** OUTPUT:
  140179. +**
  140180. +** gctSIZE_T * StateBufferSize
  140181. +** Pointer to a variable receicing the number of bytes in the buffer
  140182. +** returned in 'StateBuffer'.
  140183. +**
  140184. +** gctPOINTER * StateBuffer
  140185. +** Pointer to a variable receiving a buffer pointer that contains the
  140186. +** states required to download the shaders into the hardware.
  140187. +**
  140188. +** gcsHINT_PTR * Hints
  140189. +** Pointer to a variable receiving a gcsHINT structure pointer that
  140190. +** contains information required when loading the shader states.
  140191. +*/
  140192. +gceSTATUS
  140193. +gcLinkShaders(
  140194. + IN gcSHADER VertexShader,
  140195. + IN gcSHADER FragmentShader,
  140196. + IN gceSHADER_FLAGS Flags,
  140197. + OUT gctSIZE_T * StateBufferSize,
  140198. + OUT gctPOINTER * StateBuffer,
  140199. + OUT gcsHINT_PTR * Hints,
  140200. + OUT gcMACHINECODE_PTR *ppVsMachineCode,
  140201. + OUT gcMACHINECODE_PTR *ppFsMachineCode
  140202. + );
  140203. +
  140204. +/*******************************************************************************
  140205. +** gcLoadShaders
  140206. +********************************************************************************
  140207. +**
  140208. +** Load a pre-compiled and pre-linked shader program into the hardware.
  140209. +**
  140210. +** INPUT:
  140211. +**
  140212. +** gcoHAL Hal
  140213. +** Pointer to a gcoHAL object.
  140214. +**
  140215. +** gctSIZE_T StateBufferSize
  140216. +** The number of bytes in the 'StateBuffer'.
  140217. +**
  140218. +** gctPOINTER StateBuffer
  140219. +** Pointer to the states that make up the shader program.
  140220. +**
  140221. +** gcsHINT_PTR Hints
  140222. +** Pointer to a gcsHINT structure that contains information required
  140223. +** when loading the shader states.
  140224. +*/
  140225. +gceSTATUS
  140226. +gcLoadShaders(
  140227. + IN gcoHAL Hal,
  140228. + IN gctSIZE_T StateBufferSize,
  140229. + IN gctPOINTER StateBuffer,
  140230. + IN gcsHINT_PTR Hints
  140231. + );
  140232. +
  140233. +gceSTATUS
  140234. +gcRecompileShaders(
  140235. + IN gcoHAL Hal,
  140236. + IN gcMACHINECODE_PTR pVsMachineCode,
  140237. + IN gcMACHINECODE_PTR pPsMachineCode,
  140238. + /*Recompile variables*/
  140239. + IN OUT gctPOINTER *ppRecompileStateBuffer,
  140240. + IN OUT gctSIZE_T *pRecompileStateBufferSize,
  140241. + IN OUT gcsHINT_PTR *ppRecompileHints,
  140242. + /* natvie state*/
  140243. + IN gctPOINTER pNativeStateBuffer,
  140244. + IN gctSIZE_T nativeStateBufferSize,
  140245. + IN gcsHINT_PTR pNativeHints,
  140246. + /* npt info */
  140247. + IN gctUINT32 Samplers,
  140248. + IN gctUINT32 *SamplerWrapS,
  140249. + IN gctUINT32 *SamplerWrapT
  140250. + );
  140251. +
  140252. +gceSTATUS
  140253. +gcRecompileDepthBias(
  140254. + IN gcoHAL Hal,
  140255. + IN gcMACHINECODE_PTR pVsMachineCode,
  140256. + /*Recompile variables*/
  140257. + IN OUT gctPOINTER *ppRecompileStateBuffer,
  140258. + IN OUT gctSIZE_T *pRecompileStateBufferSize,
  140259. + IN OUT gcsHINT_PTR *ppRecompileHints,
  140260. + /* natvie state*/
  140261. + IN gctPOINTER pNativeStateBuffer,
  140262. + IN gctSIZE_T nativeStateBufferSize,
  140263. + IN gcsHINT_PTR pNativeHints,
  140264. + OUT gctINT * uniformAddr,
  140265. + OUT gctINT * uniformChannel
  140266. + );
  140267. +
  140268. +/*******************************************************************************
  140269. +** gcSaveProgram
  140270. +********************************************************************************
  140271. +**
  140272. +** Save pre-compiled shaders and pre-linked programs to a binary file.
  140273. +**
  140274. +** INPUT:
  140275. +**
  140276. +** gcSHADER VertexShader
  140277. +** Pointer to vertex shader object.
  140278. +**
  140279. +** gcSHADER FragmentShader
  140280. +** Pointer to fragment shader object.
  140281. +**
  140282. +** gctSIZE_T ProgramBufferSize
  140283. +** Number of bytes in 'ProgramBuffer'.
  140284. +**
  140285. +** gctPOINTER ProgramBuffer
  140286. +** Pointer to buffer containing the program states.
  140287. +**
  140288. +** gcsHINT_PTR Hints
  140289. +** Pointer to HINTS structure for program states.
  140290. +**
  140291. +** OUTPUT:
  140292. +**
  140293. +** gctPOINTER * Binary
  140294. +** Pointer to a variable receiving the binary data to be saved.
  140295. +**
  140296. +** gctSIZE_T * BinarySize
  140297. +** Pointer to a variable receiving the number of bytes inside 'Binary'.
  140298. +*/
  140299. +gceSTATUS
  140300. +gcSaveProgram(
  140301. + IN gcSHADER VertexShader,
  140302. + IN gcSHADER FragmentShader,
  140303. + IN gctSIZE_T ProgramBufferSize,
  140304. + IN gctPOINTER ProgramBuffer,
  140305. + IN gcsHINT_PTR Hints,
  140306. + OUT gctPOINTER * Binary,
  140307. + OUT gctSIZE_T * BinarySize
  140308. + );
  140309. +
  140310. +/*******************************************************************************
  140311. +** gcLoadProgram
  140312. +********************************************************************************
  140313. +**
  140314. +** Load pre-compiled shaders and pre-linked programs from a binary file.
  140315. +**
  140316. +** INPUT:
  140317. +**
  140318. +** gctPOINTER Binary
  140319. +** Pointer to the binary data loaded.
  140320. +**
  140321. +** gctSIZE_T BinarySize
  140322. +** Number of bytes in 'Binary'.
  140323. +**
  140324. +** OUTPUT:
  140325. +**
  140326. +** gcSHADER VertexShader
  140327. +** Pointer to a vertex shader object.
  140328. +**
  140329. +** gcSHADER FragmentShader
  140330. +** Pointer to a fragment shader object.
  140331. +**
  140332. +** gctSIZE_T * ProgramBufferSize
  140333. +** Pointer to a variable receicing the number of bytes in the buffer
  140334. +** returned in 'ProgramBuffer'.
  140335. +**
  140336. +** gctPOINTER * ProgramBuffer
  140337. +** Pointer to a variable receiving a buffer pointer that contains the
  140338. +** states required to download the shaders into the hardware.
  140339. +**
  140340. +** gcsHINT_PTR * Hints
  140341. +** Pointer to a variable receiving a gcsHINT structure pointer that
  140342. +** contains information required when loading the shader states.
  140343. +*/
  140344. +gceSTATUS
  140345. +gcLoadProgram(
  140346. + IN gctPOINTER Binary,
  140347. + IN gctSIZE_T BinarySize,
  140348. + OUT gcSHADER VertexShader,
  140349. + OUT gcSHADER FragmentShader,
  140350. + OUT gctSIZE_T * ProgramBufferSize,
  140351. + OUT gctPOINTER * ProgramBuffer,
  140352. + OUT gcsHINT_PTR * Hints
  140353. + );
  140354. +
  140355. +/*******************************************************************************
  140356. +** gcCompileKernel
  140357. +********************************************************************************
  140358. +**
  140359. +** Compile a OpenCL kernel shader.
  140360. +**
  140361. +** INPUT:
  140362. +**
  140363. +** gcoOS Hal
  140364. +** Pointer to an gcoHAL object.
  140365. +**
  140366. +** gctSIZE_T SourceSize
  140367. +** Size of the source buffer in bytes.
  140368. +**
  140369. +** gctCONST_STRING Source
  140370. +** Pointer to the buffer containing the shader source code.
  140371. +**
  140372. +** OUTPUT:
  140373. +**
  140374. +** gcSHADER * Binary
  140375. +** Pointer to a variable receiving the pointer to a gcSHADER object
  140376. +** containg the compiled shader code.
  140377. +**
  140378. +** gctSTRING * Log
  140379. +** Pointer to a variable receiving a string pointer containging the
  140380. +** compile log.
  140381. +*/
  140382. +gceSTATUS
  140383. +gcCompileKernel(
  140384. + IN gcoHAL Hal,
  140385. + IN gctSIZE_T SourceSize,
  140386. + IN gctCONST_STRING Source,
  140387. + IN gctCONST_STRING Options,
  140388. + OUT gcSHADER * Binary,
  140389. + OUT gctSTRING * Log
  140390. + );
  140391. +
  140392. +/*******************************************************************************
  140393. +** gcLinkKernel
  140394. +********************************************************************************
  140395. +**
  140396. +** Link OpenCL kernel and generate a harwdare specific state buffer by compiling
  140397. +** the compiler generated code through the resource allocator and code
  140398. +** generator.
  140399. +**
  140400. +** INPUT:
  140401. +**
  140402. +** gcSHADER Kernel
  140403. +** Pointer to a gcSHADER object holding information about the compiled
  140404. +** OpenCL kernel.
  140405. +**
  140406. +** gceSHADER_FLAGS Flags
  140407. +** Compiler flags. Can be any of the following:
  140408. +**
  140409. +** gcvSHADER_DEAD_CODE - Dead code elimination.
  140410. +** gcvSHADER_RESOURCE_USAGE - Resource usage optimizaion.
  140411. +** gcvSHADER_OPTIMIZER - Full optimization.
  140412. +** gcvSHADER_USE_GL_Z - Use OpenGL ES Z coordinate.
  140413. +** gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position.
  140414. +** gcvSHADER_USE_GL_FACE - Use OpenGL ES gl_FaceForward.
  140415. +**
  140416. +** OUTPUT:
  140417. +**
  140418. +** gctSIZE_T * StateBufferSize
  140419. +** Pointer to a variable receiving the number of bytes in the buffer
  140420. +** returned in 'StateBuffer'.
  140421. +**
  140422. +** gctPOINTER * StateBuffer
  140423. +** Pointer to a variable receiving a buffer pointer that contains the
  140424. +** states required to download the shaders into the hardware.
  140425. +**
  140426. +** gcsHINT_PTR * Hints
  140427. +** Pointer to a variable receiving a gcsHINT structure pointer that
  140428. +** contains information required when loading the shader states.
  140429. +*/
  140430. +gceSTATUS
  140431. +gcLinkKernel(
  140432. + IN gcSHADER Kernel,
  140433. + IN gceSHADER_FLAGS Flags,
  140434. + OUT gctSIZE_T * StateBufferSize,
  140435. + OUT gctPOINTER * StateBuffer,
  140436. + OUT gcsHINT_PTR * Hints
  140437. + );
  140438. +
  140439. +/*******************************************************************************
  140440. +** gcLoadKernel
  140441. +********************************************************************************
  140442. +**
  140443. +** Load a pre-compiled and pre-linked kernel program into the hardware.
  140444. +**
  140445. +** INPUT:
  140446. +**
  140447. +** gctSIZE_T StateBufferSize
  140448. +** The number of bytes in the 'StateBuffer'.
  140449. +**
  140450. +** gctPOINTER StateBuffer
  140451. +** Pointer to the states that make up the shader program.
  140452. +**
  140453. +** gcsHINT_PTR Hints
  140454. +** Pointer to a gcsHINT structure that contains information required
  140455. +** when loading the shader states.
  140456. +*/
  140457. +gceSTATUS
  140458. +gcLoadKernel(
  140459. + IN gctSIZE_T StateBufferSize,
  140460. + IN gctPOINTER StateBuffer,
  140461. + IN gcsHINT_PTR Hints
  140462. + );
  140463. +
  140464. +gceSTATUS
  140465. +gcInvokeThreadWalker(
  140466. + IN gcsTHREAD_WALKER_INFO_PTR Info
  140467. + );
  140468. +
  140469. +void
  140470. +gcTYPE_GetTypeInfo(
  140471. + IN gcSHADER_TYPE Type,
  140472. + OUT gctINT * Components,
  140473. + OUT gctINT * Rows,
  140474. + OUT gctCONST_STRING * Name
  140475. + );
  140476. +
  140477. +gctBOOL
  140478. +gcOPT_doVaryingPackingForShader(
  140479. + IN gcSHADER Shader
  140480. + );
  140481. +
  140482. +gceSTATUS
  140483. +gcSHADER_PatchNPOTForMachineCode(
  140484. + IN gcSHADER_KIND shaderType,
  140485. + IN gcMACHINECODE_PTR pMachineCode,
  140486. + IN gcNPOT_PATCH_PARAM_PTR pPatchParam,
  140487. + IN gctUINT countOfPatchParam,
  140488. + IN gctUINT hwSupportedInstCount,
  140489. + OUT gctPOINTER* ppCmdBuffer,
  140490. + OUT gctUINT32* pByteSizeOfCmdBuffer,
  140491. + IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */
  140492. + );
  140493. +
  140494. +gceSTATUS
  140495. +gcSHADER_PatchZBiasForMachineCodeVS(
  140496. + IN gcMACHINECODE_PTR pMachineCode,
  140497. + IN OUT gcZBIAS_PATCH_PARAM_PTR pPatchParam,
  140498. + IN gctUINT hwSupportedInstCount,
  140499. + OUT gctPOINTER* ppCmdBuffer,
  140500. + OUT gctUINT32* pByteSizeOfCmdBuffer,
  140501. + IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */
  140502. + );
  140503. +
  140504. +#ifdef __cplusplus
  140505. +}
  140506. +#endif
  140507. +
  140508. +#endif /* VIVANTE_NO_3D */
  140509. +#endif /* __gc_hal_compiler_h_ */
  140510. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
  140511. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h 1970-01-01 01:00:00.000000000 +0100
  140512. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h 2014-08-20 19:31:46.132869024 +0200
  140513. @@ -0,0 +1,1051 @@
  140514. +/****************************************************************************
  140515. +*
  140516. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  140517. +*
  140518. +* This program is free software; you can redistribute it and/or modify
  140519. +* it under the terms of the GNU General Public License as published by
  140520. +* the Free Software Foundation; either version 2 of the license, or
  140521. +* (at your option) any later version.
  140522. +*
  140523. +* This program is distributed in the hope that it will be useful,
  140524. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  140525. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  140526. +* GNU General Public License for more details.
  140527. +*
  140528. +* You should have received a copy of the GNU General Public License
  140529. +* along with this program; if not write to the Free Software
  140530. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  140531. +*
  140532. +*****************************************************************************/
  140533. +
  140534. +
  140535. +#ifndef __gc_hal_driver_h_
  140536. +#define __gc_hal_driver_h_
  140537. +
  140538. +#include "gc_hal_enum.h"
  140539. +#include "gc_hal_types.h"
  140540. +
  140541. +#if gcdENABLE_VG
  140542. +#include "gc_hal_driver_vg.h"
  140543. +#endif
  140544. +
  140545. +#ifdef __cplusplus
  140546. +extern "C" {
  140547. +#endif
  140548. +
  140549. +/******************************************************************************\
  140550. +******************************* I/O Control Codes ******************************
  140551. +\******************************************************************************/
  140552. +
  140553. +#define gcvHAL_CLASS "galcore"
  140554. +#define IOCTL_GCHAL_INTERFACE 30000
  140555. +#define IOCTL_GCHAL_KERNEL_INTERFACE 30001
  140556. +#define IOCTL_GCHAL_TERMINATE 30002
  140557. +
  140558. +/******************************************************************************\
  140559. +********************************* Command Codes ********************************
  140560. +\******************************************************************************/
  140561. +
  140562. +typedef enum _gceHAL_COMMAND_CODES
  140563. +{
  140564. + /* Generic query. */
  140565. + gcvHAL_QUERY_VIDEO_MEMORY,
  140566. + gcvHAL_QUERY_CHIP_IDENTITY,
  140567. +
  140568. + /* Contiguous memory. */
  140569. + gcvHAL_ALLOCATE_NON_PAGED_MEMORY,
  140570. + gcvHAL_FREE_NON_PAGED_MEMORY,
  140571. + gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY,
  140572. + gcvHAL_FREE_CONTIGUOUS_MEMORY,
  140573. +
  140574. + /* Video memory allocation. */
  140575. + gcvHAL_ALLOCATE_VIDEO_MEMORY, /* Enforced alignment. */
  140576. + gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY, /* No alignment. */
  140577. + gcvHAL_FREE_VIDEO_MEMORY,
  140578. +
  140579. + /* Physical-to-logical mapping. */
  140580. + gcvHAL_MAP_MEMORY,
  140581. + gcvHAL_UNMAP_MEMORY,
  140582. +
  140583. + /* Logical-to-physical mapping. */
  140584. + gcvHAL_MAP_USER_MEMORY,
  140585. + gcvHAL_UNMAP_USER_MEMORY,
  140586. +
  140587. + /* Surface lock/unlock. */
  140588. + gcvHAL_LOCK_VIDEO_MEMORY,
  140589. + gcvHAL_UNLOCK_VIDEO_MEMORY,
  140590. +
  140591. + /* Event queue. */
  140592. + gcvHAL_EVENT_COMMIT,
  140593. +
  140594. + gcvHAL_USER_SIGNAL,
  140595. + gcvHAL_SIGNAL,
  140596. + gcvHAL_WRITE_DATA,
  140597. +
  140598. + gcvHAL_COMMIT,
  140599. + gcvHAL_STALL,
  140600. +
  140601. + gcvHAL_READ_REGISTER,
  140602. + gcvHAL_WRITE_REGISTER,
  140603. +
  140604. + gcvHAL_GET_PROFILE_SETTING,
  140605. + gcvHAL_SET_PROFILE_SETTING,
  140606. +
  140607. + gcvHAL_READ_ALL_PROFILE_REGISTERS,
  140608. + gcvHAL_PROFILE_REGISTERS_2D,
  140609. +#if VIVANTE_PROFILER_PERDRAW
  140610. + gcvHAL_READ_PROFILER_REGISTER_SETTING,
  140611. +#endif
  140612. +
  140613. + /* Power management. */
  140614. + gcvHAL_SET_POWER_MANAGEMENT_STATE,
  140615. + gcvHAL_QUERY_POWER_MANAGEMENT_STATE,
  140616. +
  140617. + gcvHAL_GET_BASE_ADDRESS,
  140618. +
  140619. + gcvHAL_SET_IDLE, /* reserved */
  140620. +
  140621. + /* Queries. */
  140622. + gcvHAL_QUERY_KERNEL_SETTINGS,
  140623. +
  140624. + /* Reset. */
  140625. + gcvHAL_RESET,
  140626. +
  140627. + /* Map physical address into handle. */
  140628. + gcvHAL_MAP_PHYSICAL,
  140629. +
  140630. + /* Debugger stuff. */
  140631. + gcvHAL_DEBUG,
  140632. +
  140633. + /* Cache stuff. */
  140634. + gcvHAL_CACHE,
  140635. +
  140636. + /* TimeStamp */
  140637. + gcvHAL_TIMESTAMP,
  140638. +
  140639. + /* Database. */
  140640. + gcvHAL_DATABASE,
  140641. +
  140642. + /* Version. */
  140643. + gcvHAL_VERSION,
  140644. +
  140645. + /* Chip info */
  140646. + gcvHAL_CHIP_INFO,
  140647. +
  140648. + /* Process attaching/detaching. */
  140649. + gcvHAL_ATTACH,
  140650. + gcvHAL_DETACH,
  140651. +
  140652. + /* Composition. */
  140653. + gcvHAL_COMPOSE,
  140654. +
  140655. + /* Set timeOut value */
  140656. + gcvHAL_SET_TIMEOUT,
  140657. +
  140658. + /* Frame database. */
  140659. + gcvHAL_GET_FRAME_INFO,
  140660. +
  140661. + /* Shared info for each process */
  140662. + gcvHAL_GET_SHARED_INFO,
  140663. + gcvHAL_SET_SHARED_INFO,
  140664. + gcvHAL_QUERY_COMMAND_BUFFER,
  140665. +
  140666. + gcvHAL_COMMIT_DONE,
  140667. +
  140668. + /* GPU and event dump */
  140669. + gcvHAL_DUMP_GPU_STATE,
  140670. + gcvHAL_DUMP_EVENT,
  140671. +
  140672. + /* Virtual command buffer. */
  140673. + gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER,
  140674. + gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER,
  140675. +
  140676. + /* FSCALE_VAL. */
  140677. + gcvHAL_SET_FSCALE_VALUE,
  140678. + gcvHAL_GET_FSCALE_VALUE,
  140679. +
  140680. + /* Reset time stamp. */
  140681. + gcvHAL_QUERY_RESET_TIME_STAMP,
  140682. +
  140683. + /* Sync point operations. */
  140684. + gcvHAL_SYNC_POINT,
  140685. +
  140686. + /* Create native fence and return its fd. */
  140687. + gcvHAL_CREATE_NATIVE_FENCE,
  140688. +
  140689. + /* Video memory database */
  140690. + gcvHAL_VIDMEM_DATABASE,
  140691. +}
  140692. +gceHAL_COMMAND_CODES;
  140693. +
  140694. +/******************************************************************************\
  140695. +****************************** Interface Structure *****************************
  140696. +\******************************************************************************/
  140697. +
  140698. +#define gcdMAX_PROFILE_FILE_NAME 128
  140699. +
  140700. +/* Kernel settings. */
  140701. +typedef struct _gcsKERNEL_SETTINGS
  140702. +{
  140703. + /* Used RealTime signal between kernel and user. */
  140704. + gctINT signal;
  140705. +}
  140706. +gcsKERNEL_SETTINGS;
  140707. +
  140708. +
  140709. +/* gcvHAL_QUERY_CHIP_IDENTITY */
  140710. +typedef struct _gcsHAL_QUERY_CHIP_IDENTITY * gcsHAL_QUERY_CHIP_IDENTITY_PTR;
  140711. +typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
  140712. +{
  140713. +
  140714. + /* Chip model. */
  140715. + gceCHIPMODEL chipModel;
  140716. +
  140717. + /* Revision value.*/
  140718. + gctUINT32 chipRevision;
  140719. +
  140720. + /* Supported feature fields. */
  140721. + gctUINT32 chipFeatures;
  140722. +
  140723. + /* Supported minor feature fields. */
  140724. + gctUINT32 chipMinorFeatures;
  140725. +
  140726. + /* Supported minor feature 1 fields. */
  140727. + gctUINT32 chipMinorFeatures1;
  140728. +
  140729. + /* Supported minor feature 2 fields. */
  140730. + gctUINT32 chipMinorFeatures2;
  140731. +
  140732. + /* Supported minor feature 3 fields. */
  140733. + gctUINT32 chipMinorFeatures3;
  140734. +
  140735. + /* Supported minor feature 4 fields. */
  140736. + gctUINT32 chipMinorFeatures4;
  140737. +
  140738. + /* Number of streams supported. */
  140739. + gctUINT32 streamCount;
  140740. +
  140741. + /* Total number of temporary registers per thread. */
  140742. + gctUINT32 registerMax;
  140743. +
  140744. + /* Maximum number of threads. */
  140745. + gctUINT32 threadCount;
  140746. +
  140747. + /* Number of shader cores. */
  140748. + gctUINT32 shaderCoreCount;
  140749. +
  140750. + /* Size of the vertex cache. */
  140751. + gctUINT32 vertexCacheSize;
  140752. +
  140753. + /* Number of entries in the vertex output buffer. */
  140754. + gctUINT32 vertexOutputBufferSize;
  140755. +
  140756. + /* Number of pixel pipes. */
  140757. + gctUINT32 pixelPipes;
  140758. +
  140759. + /* Number of instructions. */
  140760. + gctUINT32 instructionCount;
  140761. +
  140762. + /* Number of constants. */
  140763. + gctUINT32 numConstants;
  140764. +
  140765. + /* Buffer size */
  140766. + gctUINT32 bufferSize;
  140767. +
  140768. + /* Number of varyings */
  140769. + gctUINT32 varyingsCount;
  140770. +
  140771. + /* Supertile layout style in hardware */
  140772. + gctUINT32 superTileMode;
  140773. +
  140774. + /* Special control bits for 2D chip. */
  140775. + gctUINT32 chip2DControl;
  140776. +}
  140777. +gcsHAL_QUERY_CHIP_IDENTITY;
  140778. +
  140779. +/* gcvHAL_COMPOSE. */
  140780. +typedef struct _gcsHAL_COMPOSE * gcsHAL_COMPOSE_PTR;
  140781. +typedef struct _gcsHAL_COMPOSE
  140782. +{
  140783. + /* Composition state buffer. */
  140784. + gctUINT64 physical;
  140785. + gctUINT64 logical;
  140786. + gctUINT offset;
  140787. + gctUINT size;
  140788. +
  140789. + /* Composition end signal. */
  140790. + gctUINT64 process;
  140791. + gctUINT64 signal;
  140792. +
  140793. + /* User signals. */
  140794. + gctUINT64 userProcess;
  140795. + gctUINT64 userSignal1;
  140796. + gctUINT64 userSignal2;
  140797. +
  140798. +#if defined(__QNXNTO__)
  140799. + /* Client pulse side-channel connection ID. */
  140800. + gctINT32 coid;
  140801. +
  140802. + /* Set by server. */
  140803. + gctINT32 rcvid;
  140804. +#endif
  140805. +}
  140806. +gcsHAL_COMPOSE;
  140807. +
  140808. +
  140809. +typedef struct _gcsHAL_INTERFACE
  140810. +{
  140811. + /* Command code. */
  140812. + gceHAL_COMMAND_CODES command;
  140813. +
  140814. + /* Hardware type. */
  140815. + gceHARDWARE_TYPE hardwareType;
  140816. +
  140817. + /* Status value. */
  140818. + gceSTATUS status;
  140819. +
  140820. + /* Handle to this interface channel. */
  140821. + gctUINT64 handle;
  140822. +
  140823. + /* Pid of the client. */
  140824. + gctUINT32 pid;
  140825. +
  140826. + /* Union of command structures. */
  140827. + union _u
  140828. + {
  140829. + /* gcvHAL_GET_BASE_ADDRESS */
  140830. + struct _gcsHAL_GET_BASE_ADDRESS
  140831. + {
  140832. + /* Physical memory address of internal memory. */
  140833. + OUT gctUINT32 baseAddress;
  140834. + }
  140835. + GetBaseAddress;
  140836. +
  140837. + /* gcvHAL_QUERY_VIDEO_MEMORY */
  140838. + struct _gcsHAL_QUERY_VIDEO_MEMORY
  140839. + {
  140840. + /* Physical memory address of internal memory. Just a name. */
  140841. + OUT gctUINT32 internalPhysical;
  140842. +
  140843. + /* Size in bytes of internal memory. */
  140844. + OUT gctUINT64 internalSize;
  140845. +
  140846. + /* Physical memory address of external memory. Just a name. */
  140847. + OUT gctUINT32 externalPhysical;
  140848. +
  140849. + /* Size in bytes of external memory.*/
  140850. + OUT gctUINT64 externalSize;
  140851. +
  140852. + /* Physical memory address of contiguous memory. Just a name. */
  140853. + OUT gctUINT32 contiguousPhysical;
  140854. +
  140855. + /* Size in bytes of contiguous memory.*/
  140856. + OUT gctUINT64 contiguousSize;
  140857. + }
  140858. + QueryVideoMemory;
  140859. +
  140860. + /* gcvHAL_QUERY_CHIP_IDENTITY */
  140861. + gcsHAL_QUERY_CHIP_IDENTITY QueryChipIdentity;
  140862. +
  140863. + /* gcvHAL_MAP_MEMORY */
  140864. + struct _gcsHAL_MAP_MEMORY
  140865. + {
  140866. + /* Physical memory address to map. Just a name on Linux/Qnx. */
  140867. + IN gctUINT32 physical;
  140868. +
  140869. + /* Number of bytes in physical memory to map. */
  140870. + IN gctUINT64 bytes;
  140871. +
  140872. + /* Address of mapped memory. */
  140873. + OUT gctUINT64 logical;
  140874. + }
  140875. + MapMemory;
  140876. +
  140877. + /* gcvHAL_UNMAP_MEMORY */
  140878. + struct _gcsHAL_UNMAP_MEMORY
  140879. + {
  140880. + /* Physical memory address to unmap. Just a name on Linux/Qnx. */
  140881. + IN gctUINT32 physical;
  140882. +
  140883. + /* Number of bytes in physical memory to unmap. */
  140884. + IN gctUINT64 bytes;
  140885. +
  140886. + /* Address of mapped memory to unmap. */
  140887. + IN gctUINT64 logical;
  140888. + }
  140889. + UnmapMemory;
  140890. +
  140891. + /* gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY */
  140892. + struct _gcsHAL_ALLOCATE_LINEAR_VIDEO_MEMORY
  140893. + {
  140894. + /* Number of bytes to allocate. */
  140895. + IN OUT gctUINT bytes;
  140896. +
  140897. + /* Buffer alignment. */
  140898. + IN gctUINT alignment;
  140899. +
  140900. + /* Type of allocation. */
  140901. + IN gceSURF_TYPE type;
  140902. +
  140903. + /* Memory pool to allocate from. */
  140904. + IN OUT gcePOOL pool;
  140905. +
  140906. + /* Allocated video memory in gcuVIDMEM_NODE. */
  140907. + OUT gctUINT64 node;
  140908. + }
  140909. + AllocateLinearVideoMemory;
  140910. +
  140911. + /* gcvHAL_ALLOCATE_VIDEO_MEMORY */
  140912. + struct _gcsHAL_ALLOCATE_VIDEO_MEMORY
  140913. + {
  140914. + /* Width of rectangle to allocate. */
  140915. + IN OUT gctUINT width;
  140916. +
  140917. + /* Height of rectangle to allocate. */
  140918. + IN OUT gctUINT height;
  140919. +
  140920. + /* Depth of rectangle to allocate. */
  140921. + IN gctUINT depth;
  140922. +
  140923. + /* Format rectangle to allocate in gceSURF_FORMAT. */
  140924. + IN gceSURF_FORMAT format;
  140925. +
  140926. + /* Type of allocation. */
  140927. + IN gceSURF_TYPE type;
  140928. +
  140929. + /* Memory pool to allocate from. */
  140930. + IN OUT gcePOOL pool;
  140931. +
  140932. + /* Allocated video memory in gcuVIDMEM_NODE. */
  140933. + OUT gctUINT64 node;
  140934. + }
  140935. + AllocateVideoMemory;
  140936. +
  140937. + /* gcvHAL_FREE_VIDEO_MEMORY */
  140938. + struct _gcsHAL_FREE_VIDEO_MEMORY
  140939. + {
  140940. + /* Allocated video memory in gcuVIDMEM_NODE. */
  140941. + IN gctUINT64 node;
  140942. +
  140943. +#ifdef __QNXNTO__
  140944. +/* TODO: This is part of the unlock - why is it here? */
  140945. + /* Mapped logical address to unmap in user space. */
  140946. + OUT gctUINT64 memory;
  140947. +
  140948. + /* Number of bytes to allocated. */
  140949. + OUT gctUINT64 bytes;
  140950. +#endif
  140951. + }
  140952. + FreeVideoMemory;
  140953. +
  140954. + /* gcvHAL_LOCK_VIDEO_MEMORY */
  140955. + struct _gcsHAL_LOCK_VIDEO_MEMORY
  140956. + {
  140957. + /* Allocated video memory gcuVIDMEM_NODE gcuVIDMEM_NODE. */
  140958. + IN gctUINT64 node;
  140959. +
  140960. + /* Cache configuration. */
  140961. + /* Only gcvPOOL_CONTIGUOUS and gcvPOOL_VIRUTAL
  140962. + ** can be configured */
  140963. + IN gctBOOL cacheable;
  140964. +
  140965. + /* Hardware specific address. */
  140966. + OUT gctUINT32 address;
  140967. +
  140968. + /* Mapped logical address. */
  140969. + OUT gctUINT64 memory;
  140970. + }
  140971. + LockVideoMemory;
  140972. +
  140973. + /* gcvHAL_UNLOCK_VIDEO_MEMORY */
  140974. + struct _gcsHAL_UNLOCK_VIDEO_MEMORY
  140975. + {
  140976. + /* Allocated video memory in gcuVIDMEM_NODE. */
  140977. + IN gctUINT64 node;
  140978. +
  140979. + /* Type of surface. */
  140980. + IN gceSURF_TYPE type;
  140981. +
  140982. + /* Flag to unlock surface asynchroneously. */
  140983. + IN OUT gctBOOL asynchroneous;
  140984. + }
  140985. + UnlockVideoMemory;
  140986. +
  140987. + /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
  140988. + struct _gcsHAL_ALLOCATE_NON_PAGED_MEMORY
  140989. + {
  140990. + /* Number of bytes to allocate. */
  140991. + IN OUT gctUINT64 bytes;
  140992. +
  140993. + /* Physical address of allocation. Just a name. */
  140994. + OUT gctUINT32 physical;
  140995. +
  140996. + /* Logical address of allocation. */
  140997. + OUT gctUINT64 logical;
  140998. + }
  140999. + AllocateNonPagedMemory;
  141000. +
  141001. + /* gcvHAL_FREE_NON_PAGED_MEMORY */
  141002. + struct _gcsHAL_FREE_NON_PAGED_MEMORY
  141003. + {
  141004. + /* Number of bytes allocated. */
  141005. + IN gctUINT64 bytes;
  141006. +
  141007. + /* Physical address of allocation. Just a name. */
  141008. + IN gctUINT32 physical;
  141009. +
  141010. + /* Logical address of allocation. */
  141011. + IN gctUINT64 logical;
  141012. + }
  141013. + FreeNonPagedMemory;
  141014. +
  141015. + /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
  141016. + struct _gcsHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER
  141017. + {
  141018. + /* Number of bytes to allocate. */
  141019. + IN OUT gctUINT64 bytes;
  141020. +
  141021. + /* Physical address of allocation. Just a name. */
  141022. + OUT gctUINT32 physical;
  141023. +
  141024. + /* Logical address of allocation. */
  141025. + OUT gctUINT64 logical;
  141026. + }
  141027. + AllocateVirtualCommandBuffer;
  141028. +
  141029. + /* gcvHAL_FREE_NON_PAGED_MEMORY */
  141030. + struct _gcsHAL_FREE_VIRTUAL_COMMAND_BUFFER
  141031. + {
  141032. + /* Number of bytes allocated. */
  141033. + IN gctUINT64 bytes;
  141034. +
  141035. + /* Physical address of allocation. Just a name. */
  141036. + IN gctUINT32 physical;
  141037. +
  141038. + /* Logical address of allocation. */
  141039. + IN gctUINT64 logical;
  141040. + }
  141041. + FreeVirtualCommandBuffer;
  141042. +
  141043. + /* gcvHAL_EVENT_COMMIT. */
  141044. + struct _gcsHAL_EVENT_COMMIT
  141045. + {
  141046. + /* Event queue in gcsQUEUE. */
  141047. + IN gctUINT64 queue;
  141048. + }
  141049. + Event;
  141050. +
  141051. + /* gcvHAL_COMMIT */
  141052. + struct _gcsHAL_COMMIT
  141053. + {
  141054. + /* Context buffer object gckCONTEXT. */
  141055. + IN gctUINT64 context;
  141056. +
  141057. + /* Command buffer gcoCMDBUF. */
  141058. + IN gctUINT64 commandBuffer;
  141059. +
  141060. + /* State delta buffer in gcsSTATE_DELTA. */
  141061. + gctUINT64 delta;
  141062. +
  141063. + /* Event queue in gcsQUEUE. */
  141064. + IN gctUINT64 queue;
  141065. + }
  141066. + Commit;
  141067. +
  141068. + /* gcvHAL_MAP_USER_MEMORY */
  141069. + struct _gcsHAL_MAP_USER_MEMORY
  141070. + {
  141071. + /* Base address of user memory to map. */
  141072. + IN gctUINT64 memory;
  141073. +
  141074. + /* Physical address of user memory to map. */
  141075. + IN gctUINT32 physical;
  141076. +
  141077. + /* Size of user memory in bytes to map. */
  141078. + IN gctUINT64 size;
  141079. +
  141080. + /* Info record required by gcvHAL_UNMAP_USER_MEMORY. Just a name. */
  141081. + OUT gctUINT32 info;
  141082. +
  141083. + /* Physical address of mapped memory. */
  141084. + OUT gctUINT32 address;
  141085. + }
  141086. + MapUserMemory;
  141087. +
  141088. + /* gcvHAL_UNMAP_USER_MEMORY */
  141089. + struct _gcsHAL_UNMAP_USER_MEMORY
  141090. + {
  141091. + /* Base address of user memory to unmap. */
  141092. + IN gctUINT64 memory;
  141093. +
  141094. + /* Size of user memory in bytes to unmap. */
  141095. + IN gctUINT64 size;
  141096. +
  141097. + /* Info record returned by gcvHAL_MAP_USER_MEMORY. Just a name. */
  141098. + IN gctUINT32 info;
  141099. +
  141100. + /* Physical address of mapped memory as returned by
  141101. + gcvHAL_MAP_USER_MEMORY. */
  141102. + IN gctUINT32 address;
  141103. + }
  141104. + UnmapUserMemory;
  141105. +#if !USE_NEW_LINUX_SIGNAL
  141106. + /* gcsHAL_USER_SIGNAL */
  141107. + struct _gcsHAL_USER_SIGNAL
  141108. + {
  141109. + /* Command. */
  141110. + gceUSER_SIGNAL_COMMAND_CODES command;
  141111. +
  141112. + /* Signal ID. */
  141113. + IN OUT gctINT id;
  141114. +
  141115. + /* Reset mode. */
  141116. + IN gctBOOL manualReset;
  141117. +
  141118. + /* Wait timedout. */
  141119. + IN gctUINT32 wait;
  141120. +
  141121. + /* State. */
  141122. + IN gctBOOL state;
  141123. + }
  141124. + UserSignal;
  141125. +#endif
  141126. +
  141127. + /* gcvHAL_SIGNAL. */
  141128. + struct _gcsHAL_SIGNAL
  141129. + {
  141130. + /* Signal handle to signal gctSIGNAL. */
  141131. + IN gctUINT64 signal;
  141132. +
  141133. + /* Reserved gctSIGNAL. */
  141134. + IN gctUINT64 auxSignal;
  141135. +
  141136. + /* Process owning the signal gctHANDLE. */
  141137. + IN gctUINT64 process;
  141138. +
  141139. +#if defined(__QNXNTO__)
  141140. + /* Client pulse side-channel connection ID. Set by client in gcoOS_CreateSignal. */
  141141. + IN gctINT32 coid;
  141142. +
  141143. + /* Set by server. */
  141144. + IN gctINT32 rcvid;
  141145. +#endif
  141146. + /* Event generated from where of pipeline */
  141147. + IN gceKERNEL_WHERE fromWhere;
  141148. + }
  141149. + Signal;
  141150. +
  141151. + /* gcvHAL_WRITE_DATA. */
  141152. + struct _gcsHAL_WRITE_DATA
  141153. + {
  141154. + /* Address to write data to. */
  141155. + IN gctUINT32 address;
  141156. +
  141157. + /* Data to write. */
  141158. + IN gctUINT32 data;
  141159. + }
  141160. + WriteData;
  141161. +
  141162. + /* gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY */
  141163. + struct _gcsHAL_ALLOCATE_CONTIGUOUS_MEMORY
  141164. + {
  141165. + /* Number of bytes to allocate. */
  141166. + IN OUT gctUINT64 bytes;
  141167. +
  141168. + /* Hardware address of allocation. */
  141169. + OUT gctUINT32 address;
  141170. +
  141171. + /* Physical address of allocation. Just a name. */
  141172. + OUT gctUINT32 physical;
  141173. +
  141174. + /* Logical address of allocation. */
  141175. + OUT gctUINT64 logical;
  141176. + }
  141177. + AllocateContiguousMemory;
  141178. +
  141179. + /* gcvHAL_FREE_CONTIGUOUS_MEMORY */
  141180. + struct _gcsHAL_FREE_CONTIGUOUS_MEMORY
  141181. + {
  141182. + /* Number of bytes allocated. */
  141183. + IN gctUINT64 bytes;
  141184. +
  141185. + /* Physical address of allocation. Just a name. */
  141186. + IN gctUINT32 physical;
  141187. +
  141188. + /* Logical address of allocation. */
  141189. + IN gctUINT64 logical;
  141190. + }
  141191. + FreeContiguousMemory;
  141192. +
  141193. + /* gcvHAL_READ_REGISTER */
  141194. + struct _gcsHAL_READ_REGISTER
  141195. + {
  141196. + /* Logical address of memory to write data to. */
  141197. + IN gctUINT32 address;
  141198. +
  141199. + /* Data read. */
  141200. + OUT gctUINT32 data;
  141201. + }
  141202. + ReadRegisterData;
  141203. +
  141204. + /* gcvHAL_WRITE_REGISTER */
  141205. + struct _gcsHAL_WRITE_REGISTER
  141206. + {
  141207. + /* Logical address of memory to write data to. */
  141208. + IN gctUINT32 address;
  141209. +
  141210. + /* Data read. */
  141211. + IN gctUINT32 data;
  141212. + }
  141213. + WriteRegisterData;
  141214. +
  141215. +#if VIVANTE_PROFILER
  141216. + /* gcvHAL_GET_PROFILE_SETTING */
  141217. + struct _gcsHAL_GET_PROFILE_SETTING
  141218. + {
  141219. + /* Enable profiling */
  141220. + OUT gctBOOL enable;
  141221. +
  141222. + /* The profile file name */
  141223. + OUT gctCHAR fileName[gcdMAX_PROFILE_FILE_NAME];
  141224. + }
  141225. + GetProfileSetting;
  141226. +
  141227. + /* gcvHAL_SET_PROFILE_SETTING */
  141228. + struct _gcsHAL_SET_PROFILE_SETTING
  141229. + {
  141230. + /* Enable profiling */
  141231. + IN gctBOOL enable;
  141232. +
  141233. + /* The profile file name */
  141234. + IN gctCHAR fileName[gcdMAX_PROFILE_FILE_NAME];
  141235. + }
  141236. + SetProfileSetting;
  141237. +
  141238. +#if VIVANTE_PROFILER_PERDRAW
  141239. + /* gcvHAL_READ_PROFILER_REGISTER_SETTING */
  141240. + struct _gcsHAL_READ_PROFILER_REGISTER_SETTING
  141241. + {
  141242. + /*Should Clear Register*/
  141243. + IN gctBOOL bclear;
  141244. + }
  141245. + SetProfilerRegisterClear;
  141246. +#endif
  141247. +
  141248. + /* gcvHAL_READ_ALL_PROFILE_REGISTERS */
  141249. + struct _gcsHAL_READ_ALL_PROFILE_REGISTERS
  141250. + {
  141251. +#if VIVANTE_PROFILER_CONTEXT
  141252. + /* Context buffer object gckCONTEXT. Just a name. */
  141253. + IN gctUINT32 context;
  141254. +#endif
  141255. + /* Data read. */
  141256. + OUT gcsPROFILER_COUNTERS counters;
  141257. + }
  141258. + RegisterProfileData;
  141259. +
  141260. + /* gcvHAL_PROFILE_REGISTERS_2D */
  141261. + struct _gcsHAL_PROFILE_REGISTERS_2D
  141262. + {
  141263. + /* Data read in gcs2D_PROFILE. */
  141264. + OUT gctUINT64 hwProfile2D;
  141265. + }
  141266. + RegisterProfileData2D;
  141267. +#endif
  141268. + /* Power management. */
  141269. + /* gcvHAL_SET_POWER_MANAGEMENT_STATE */
  141270. + struct _gcsHAL_SET_POWER_MANAGEMENT
  141271. + {
  141272. + /* Data read. */
  141273. + IN gceCHIPPOWERSTATE state;
  141274. + }
  141275. + SetPowerManagement;
  141276. +
  141277. + /* gcvHAL_QUERY_POWER_MANAGEMENT_STATE */
  141278. + struct _gcsHAL_QUERY_POWER_MANAGEMENT
  141279. + {
  141280. + /* Data read. */
  141281. + OUT gceCHIPPOWERSTATE state;
  141282. +
  141283. + /* Idle query. */
  141284. + OUT gctBOOL isIdle;
  141285. + }
  141286. + QueryPowerManagement;
  141287. +
  141288. + /* gcvHAL_QUERY_KERNEL_SETTINGS */
  141289. + struct _gcsHAL_QUERY_KERNEL_SETTINGS
  141290. + {
  141291. + /* Settings.*/
  141292. + OUT gcsKERNEL_SETTINGS settings;
  141293. + }
  141294. + QueryKernelSettings;
  141295. +
  141296. + /* gcvHAL_MAP_PHYSICAL */
  141297. + struct _gcsHAL_MAP_PHYSICAL
  141298. + {
  141299. + /* gcvTRUE to map, gcvFALSE to unmap. */
  141300. + IN gctBOOL map;
  141301. +
  141302. + /* Physical address. */
  141303. + IN OUT gctUINT64 physical;
  141304. + }
  141305. + MapPhysical;
  141306. +
  141307. + /* gcvHAL_DEBUG */
  141308. + struct _gcsHAL_DEBUG
  141309. + {
  141310. + /* If gcvTRUE, set the debug information. */
  141311. + IN gctBOOL set;
  141312. + IN gctUINT32 level;
  141313. + IN gctUINT32 zones;
  141314. + IN gctBOOL enable;
  141315. +
  141316. + IN gceDEBUG_MESSAGE_TYPE type;
  141317. + IN gctUINT32 messageSize;
  141318. +
  141319. + /* Message to print if not empty. */
  141320. + IN gctCHAR message[80];
  141321. + }
  141322. + Debug;
  141323. +
  141324. + /* gcvHAL_CACHE */
  141325. + struct _gcsHAL_CACHE
  141326. + {
  141327. + IN gceCACHEOPERATION operation;
  141328. + /* gctHANDLE */
  141329. + IN gctUINT64 process;
  141330. + IN gctUINT64 logical;
  141331. + IN gctUINT64 bytes;
  141332. + /* gcuVIDMEM_NODE_PTR */
  141333. + IN gctUINT64 node;
  141334. + }
  141335. + Cache;
  141336. +
  141337. + /* gcvHAL_TIMESTAMP */
  141338. + struct _gcsHAL_TIMESTAMP
  141339. + {
  141340. + /* Timer select. */
  141341. + IN gctUINT32 timer;
  141342. +
  141343. + /* Timer request type (0-stop, 1-start, 2-send delta). */
  141344. + IN gctUINT32 request;
  141345. +
  141346. + /* Result of delta time in microseconds. */
  141347. + OUT gctINT32 timeDelta;
  141348. + }
  141349. + TimeStamp;
  141350. +
  141351. + /* gcvHAL_DATABASE */
  141352. + struct _gcsHAL_DATABASE
  141353. + {
  141354. + /* Set to gcvTRUE if you want to query a particular process ID.
  141355. + ** Set to gcvFALSE to query the last detached process. */
  141356. + IN gctBOOL validProcessID;
  141357. +
  141358. + /* Process ID to query. */
  141359. + IN gctUINT32 processID;
  141360. +
  141361. + /* Information. */
  141362. + OUT gcuDATABASE_INFO vidMem;
  141363. + OUT gcuDATABASE_INFO nonPaged;
  141364. + OUT gcuDATABASE_INFO contiguous;
  141365. + OUT gcuDATABASE_INFO gpuIdle;
  141366. + }
  141367. + Database;
  141368. +
  141369. + /* gcvHAL_VIDMEM_DATABASE */
  141370. + struct _gcsHAL_VIDMEM_DATABASE
  141371. + {
  141372. + /* Set to gcvTRUE if you want to query a particular process ID.
  141373. + ** Set to gcvFALSE to query the last detached process. */
  141374. + IN gctBOOL validProcessID;
  141375. +
  141376. + /* Process ID to query. */
  141377. + IN gctUINT32 processID;
  141378. +
  141379. + /* Information. */
  141380. + OUT gcuDATABASE_INFO vidMemResv;
  141381. + OUT gcuDATABASE_INFO vidMemCont;
  141382. + OUT gcuDATABASE_INFO vidMemVirt;
  141383. + }
  141384. + VidMemDatabase;
  141385. +
  141386. + /* gcvHAL_VERSION */
  141387. + struct _gcsHAL_VERSION
  141388. + {
  141389. + /* Major version: N.n.n. */
  141390. + OUT gctINT32 major;
  141391. +
  141392. + /* Minor version: n.N.n. */
  141393. + OUT gctINT32 minor;
  141394. +
  141395. + /* Patch version: n.n.N. */
  141396. + OUT gctINT32 patch;
  141397. +
  141398. + /* Build version. */
  141399. + OUT gctUINT32 build;
  141400. + }
  141401. + Version;
  141402. +
  141403. + /* gcvHAL_CHIP_INFO */
  141404. + struct _gcsHAL_CHIP_INFO
  141405. + {
  141406. + /* Chip count. */
  141407. + OUT gctINT32 count;
  141408. +
  141409. + /* Chip types. */
  141410. + OUT gceHARDWARE_TYPE types[gcdCHIP_COUNT];
  141411. + }
  141412. + ChipInfo;
  141413. +
  141414. + /* gcvHAL_ATTACH */
  141415. + struct _gcsHAL_ATTACH
  141416. + {
  141417. + /* Context buffer object gckCONTEXT. Just a name. */
  141418. + OUT gctUINT32 context;
  141419. +
  141420. + /* Number of states in the buffer. */
  141421. + OUT gctUINT64 stateCount;
  141422. + }
  141423. + Attach;
  141424. +
  141425. + /* gcvHAL_DETACH */
  141426. + struct _gcsHAL_DETACH
  141427. + {
  141428. + /* Context buffer object gckCONTEXT. Just a name. */
  141429. + IN gctUINT32 context;
  141430. + }
  141431. + Detach;
  141432. +
  141433. + /* gcvHAL_COMPOSE. */
  141434. + gcsHAL_COMPOSE Compose;
  141435. +
  141436. + /* gcvHAL_GET_FRAME_INFO. */
  141437. + struct _gcsHAL_GET_FRAME_INFO
  141438. + {
  141439. + /* gcsHAL_FRAME_INFO* */
  141440. + OUT gctUINT64 frameInfo;
  141441. + }
  141442. + GetFrameInfo;
  141443. +
  141444. + /* gcvHAL_SET_TIME_OUT. */
  141445. + struct _gcsHAL_SET_TIMEOUT
  141446. + {
  141447. + gctUINT32 timeOut;
  141448. + }
  141449. + SetTimeOut;
  141450. +
  141451. +#if gcdENABLE_VG
  141452. + /* gcvHAL_COMMIT */
  141453. + struct _gcsHAL_VGCOMMIT
  141454. + {
  141455. + /* Context buffer in gcsVGCONTEXT. */
  141456. + IN gctUINT64 context;
  141457. +
  141458. + /* Command queue in gcsVGCMDQUEUE. */
  141459. + IN gctUINT64 queue;
  141460. +
  141461. + /* Number of entries in the queue. */
  141462. + IN gctUINT entryCount;
  141463. +
  141464. + /* Task table in gcsTASK_MASTER_TABLE. */
  141465. + IN gctUINT64 taskTable;
  141466. + }
  141467. + VGCommit;
  141468. +
  141469. + /* gcvHAL_QUERY_COMMAND_BUFFER */
  141470. + struct _gcsHAL_QUERY_COMMAND_BUFFER
  141471. + {
  141472. + /* Command buffer attributes. */
  141473. + OUT gcsCOMMAND_BUFFER_INFO information;
  141474. + }
  141475. + QueryCommandBuffer;
  141476. +
  141477. +#endif
  141478. +
  141479. + struct _gcsHAL_GET_SHARED_INFO
  141480. + {
  141481. + /* Process id. */
  141482. + IN gctUINT32 pid;
  141483. +
  141484. + /* Data id. */
  141485. + IN gctUINT32 dataId;
  141486. +
  141487. + /* Data size. */
  141488. + IN gctSIZE_T bytes;
  141489. +
  141490. + /* Pointer to save the shared data. */
  141491. + OUT gctPOINTER data;
  141492. + }
  141493. + GetSharedInfo;
  141494. +
  141495. + struct _gcsHAL_SET_SHARED_INFO
  141496. + {
  141497. + /* Data id. */
  141498. + IN gctUINT32 dataId;
  141499. +
  141500. + /* Data to be shared. */
  141501. + IN gctPOINTER data;
  141502. +
  141503. + /* Data size. */
  141504. + IN gctSIZE_T bytes;
  141505. + }
  141506. + SetSharedInfo;
  141507. +
  141508. + struct _gcsHAL_SET_FSCALE_VALUE
  141509. + {
  141510. + IN gctUINT value;
  141511. + }
  141512. + SetFscaleValue;
  141513. +
  141514. + struct _gcsHAL_GET_FSCALE_VALUE
  141515. + {
  141516. + OUT gctUINT value;
  141517. + OUT gctUINT minValue;
  141518. + OUT gctUINT maxValue;
  141519. + }
  141520. + GetFscaleValue;
  141521. +
  141522. + struct _gcsHAL_QUERY_RESET_TIME_STAMP
  141523. + {
  141524. + OUT gctUINT64 timeStamp;
  141525. + }
  141526. + QueryResetTimeStamp;
  141527. +
  141528. + struct _gcsHAL_SYNC_POINT
  141529. + {
  141530. + /* Command. */
  141531. + gceSYNC_POINT_COMMAND_CODES command;
  141532. +
  141533. + /* Sync point. */
  141534. + IN OUT gctUINT64 syncPoint;
  141535. +
  141536. + /* From where. */
  141537. + IN gceKERNEL_WHERE fromWhere;
  141538. +
  141539. + /* Signaled state. */
  141540. + OUT gctBOOL state;
  141541. + }
  141542. + SyncPoint;
  141543. +
  141544. + struct _gcsHAL_CREATE_NATIVE_FENCE
  141545. + {
  141546. + /* Signal id to dup. */
  141547. + IN gctUINT64 syncPoint;
  141548. +
  141549. + /* Native fence file descriptor. */
  141550. + OUT gctINT fenceFD;
  141551. +
  141552. + }
  141553. + CreateNativeFence;
  141554. + }
  141555. + u;
  141556. +}
  141557. +gcsHAL_INTERFACE;
  141558. +
  141559. +
  141560. +#ifdef __cplusplus
  141561. +}
  141562. +#endif
  141563. +
  141564. +#endif /* __gc_hal_driver_h_ */
  141565. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h
  141566. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h 1970-01-01 01:00:00.000000000 +0100
  141567. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h 2014-08-20 19:23:53.566845873 +0200
  141568. @@ -0,0 +1,270 @@
  141569. +/****************************************************************************
  141570. +*
  141571. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  141572. +*
  141573. +* This program is free software; you can redistribute it and/or modify
  141574. +* it under the terms of the GNU General Public License as published by
  141575. +* the Free Software Foundation; either version 2 of the license, or
  141576. +* (at your option) any later version.
  141577. +*
  141578. +* This program is distributed in the hope that it will be useful,
  141579. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  141580. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  141581. +* GNU General Public License for more details.
  141582. +*
  141583. +* You should have received a copy of the GNU General Public License
  141584. +* along with this program; if not write to the Free Software
  141585. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  141586. +*
  141587. +*****************************************************************************/
  141588. +
  141589. +
  141590. +#ifndef __gc_hal_driver_vg_h_
  141591. +#define __gc_hal_driver_vg_h_
  141592. +
  141593. +
  141594. +
  141595. +#include "gc_hal_types.h"
  141596. +
  141597. +#ifdef __cplusplus
  141598. +extern "C" {
  141599. +#endif
  141600. +
  141601. +/******************************************************************************\
  141602. +******************************* I/O Control Codes ******************************
  141603. +\******************************************************************************/
  141604. +
  141605. +#define gcvHAL_CLASS "galcore"
  141606. +#define IOCTL_GCHAL_INTERFACE 30000
  141607. +
  141608. +/******************************************************************************\
  141609. +********************************* Command Codes ********************************
  141610. +\******************************************************************************/
  141611. +
  141612. +/******************************************************************************\
  141613. +********************* Command buffer information structure. ********************
  141614. +\******************************************************************************/
  141615. +
  141616. +typedef struct _gcsCOMMAND_BUFFER_INFO * gcsCOMMAND_BUFFER_INFO_PTR;
  141617. +typedef struct _gcsCOMMAND_BUFFER_INFO
  141618. +{
  141619. + /* FE command buffer interrupt ID. */
  141620. + gctINT32 feBufferInt;
  141621. +
  141622. + /* TS overflow interrupt ID. */
  141623. + gctINT32 tsOverflowInt;
  141624. +
  141625. + /* Alignment and mask for the buffer address. */
  141626. + gctUINT addressMask;
  141627. + gctSIZE_T addressAlignment;
  141628. +
  141629. + /* Alignment for each command. */
  141630. + gctSIZE_T commandAlignment;
  141631. +
  141632. + /* Number of bytes required by the STATE command. */
  141633. + gctSIZE_T stateCommandSize;
  141634. +
  141635. + /* Number of bytes required by the RESTART command. */
  141636. + gctSIZE_T restartCommandSize;
  141637. +
  141638. + /* Number of bytes required by the FETCH command. */
  141639. + gctSIZE_T fetchCommandSize;
  141640. +
  141641. + /* Number of bytes required by the CALL command. */
  141642. + gctSIZE_T callCommandSize;
  141643. +
  141644. + /* Number of bytes required by the RETURN command. */
  141645. + gctSIZE_T returnCommandSize;
  141646. +
  141647. + /* Number of bytes required by the EVENT command. */
  141648. + gctSIZE_T eventCommandSize;
  141649. +
  141650. + /* Number of bytes required by the END command. */
  141651. + gctSIZE_T endCommandSize;
  141652. +
  141653. + /* Number of bytes reserved at the tail of a static command buffer. */
  141654. + gctSIZE_T staticTailSize;
  141655. +
  141656. + /* Number of bytes reserved at the tail of a dynamic command buffer. */
  141657. + gctSIZE_T dynamicTailSize;
  141658. +}
  141659. +gcsCOMMAND_BUFFER_INFO;
  141660. +
  141661. +/******************************************************************************\
  141662. +******************************** Task Structures *******************************
  141663. +\******************************************************************************/
  141664. +
  141665. +typedef enum _gceTASK
  141666. +{
  141667. + gcvTASK_LINK,
  141668. + gcvTASK_CLUSTER,
  141669. + gcvTASK_INCREMENT,
  141670. + gcvTASK_DECREMENT,
  141671. + gcvTASK_SIGNAL,
  141672. + gcvTASK_LOCKDOWN,
  141673. + gcvTASK_UNLOCK_VIDEO_MEMORY,
  141674. + gcvTASK_FREE_VIDEO_MEMORY,
  141675. + gcvTASK_FREE_CONTIGUOUS_MEMORY,
  141676. + gcvTASK_UNMAP_USER_MEMORY
  141677. +}
  141678. +gceTASK;
  141679. +
  141680. +typedef struct _gcsTASK_HEADER * gcsTASK_HEADER_PTR;
  141681. +typedef struct _gcsTASK_HEADER
  141682. +{
  141683. + /* Task ID. */
  141684. + IN gceTASK id;
  141685. +}
  141686. +gcsTASK_HEADER;
  141687. +
  141688. +typedef struct _gcsTASK_LINK * gcsTASK_LINK_PTR;
  141689. +typedef struct _gcsTASK_LINK
  141690. +{
  141691. + /* Task ID (gcvTASK_LINK). */
  141692. + IN gceTASK id;
  141693. +
  141694. + /* Pointer to the next task container. */
  141695. + IN gctPOINTER cotainer;
  141696. +
  141697. + /* Pointer to the next task from the next task container. */
  141698. + IN gcsTASK_HEADER_PTR task;
  141699. +}
  141700. +gcsTASK_LINK;
  141701. +
  141702. +typedef struct _gcsTASK_CLUSTER * gcsTASK_CLUSTER_PTR;
  141703. +typedef struct _gcsTASK_CLUSTER
  141704. +{
  141705. + /* Task ID (gcvTASK_CLUSTER). */
  141706. + IN gceTASK id;
  141707. +
  141708. + /* Number of tasks in the cluster. */
  141709. + IN gctUINT taskCount;
  141710. +}
  141711. +gcsTASK_CLUSTER;
  141712. +
  141713. +typedef struct _gcsTASK_INCREMENT * gcsTASK_INCREMENT_PTR;
  141714. +typedef struct _gcsTASK_INCREMENT
  141715. +{
  141716. + /* Task ID (gcvTASK_INCREMENT). */
  141717. + IN gceTASK id;
  141718. +
  141719. + /* Address of the variable to increment. */
  141720. + IN gctUINT32 address;
  141721. +}
  141722. +gcsTASK_INCREMENT;
  141723. +
  141724. +typedef struct _gcsTASK_DECREMENT * gcsTASK_DECREMENT_PTR;
  141725. +typedef struct _gcsTASK_DECREMENT
  141726. +{
  141727. + /* Task ID (gcvTASK_DECREMENT). */
  141728. + IN gceTASK id;
  141729. +
  141730. + /* Address of the variable to decrement. */
  141731. + IN gctUINT32 address;
  141732. +}
  141733. +gcsTASK_DECREMENT;
  141734. +
  141735. +typedef struct _gcsTASK_SIGNAL * gcsTASK_SIGNAL_PTR;
  141736. +typedef struct _gcsTASK_SIGNAL
  141737. +{
  141738. + /* Task ID (gcvTASK_SIGNAL). */
  141739. + IN gceTASK id;
  141740. +
  141741. + /* Process owning the signal. */
  141742. + IN gctHANDLE process;
  141743. +
  141744. + /* Signal handle to signal. */
  141745. + IN gctSIGNAL signal;
  141746. +
  141747. +#if defined(__QNXNTO__)
  141748. + IN gctINT32 coid;
  141749. + IN gctINT32 rcvid;
  141750. +#endif
  141751. +}
  141752. +gcsTASK_SIGNAL;
  141753. +
  141754. +typedef struct _gcsTASK_LOCKDOWN * gcsTASK_LOCKDOWN_PTR;
  141755. +typedef struct _gcsTASK_LOCKDOWN
  141756. +{
  141757. + /* Task ID (gcvTASK_LOCKDOWN). */
  141758. + IN gceTASK id;
  141759. +
  141760. + /* Address of the user space counter. */
  141761. + IN gctUINT32 userCounter;
  141762. +
  141763. + /* Address of the kernel space counter. */
  141764. + IN gctUINT32 kernelCounter;
  141765. +
  141766. + /* Process owning the signal. */
  141767. + IN gctHANDLE process;
  141768. +
  141769. + /* Signal handle to signal. */
  141770. + IN gctSIGNAL signal;
  141771. +}
  141772. +gcsTASK_LOCKDOWN;
  141773. +
  141774. +typedef struct _gcsTASK_UNLOCK_VIDEO_MEMORY * gcsTASK_UNLOCK_VIDEO_MEMORY_PTR;
  141775. +typedef struct _gcsTASK_UNLOCK_VIDEO_MEMORY
  141776. +{
  141777. + /* Task ID (gcvTASK_UNLOCK_VIDEO_MEMORY). */
  141778. + IN gceTASK id;
  141779. +
  141780. + /* Allocated video memory. */
  141781. + IN gctUINT64 node;
  141782. +}
  141783. +gcsTASK_UNLOCK_VIDEO_MEMORY;
  141784. +
  141785. +typedef struct _gcsTASK_FREE_VIDEO_MEMORY * gcsTASK_FREE_VIDEO_MEMORY_PTR;
  141786. +typedef struct _gcsTASK_FREE_VIDEO_MEMORY
  141787. +{
  141788. + /* Task ID (gcvTASK_FREE_VIDEO_MEMORY). */
  141789. + IN gceTASK id;
  141790. +
  141791. + /* Allocated video memory. */
  141792. + IN gctUINT64 node;
  141793. +}
  141794. +gcsTASK_FREE_VIDEO_MEMORY;
  141795. +
  141796. +typedef struct _gcsTASK_FREE_CONTIGUOUS_MEMORY * gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR;
  141797. +typedef struct _gcsTASK_FREE_CONTIGUOUS_MEMORY
  141798. +{
  141799. + /* Task ID (gcvTASK_FREE_CONTIGUOUS_MEMORY). */
  141800. + IN gceTASK id;
  141801. +
  141802. + /* Number of bytes allocated. */
  141803. + IN gctSIZE_T bytes;
  141804. +
  141805. + /* Physical address of allocation. */
  141806. + IN gctPHYS_ADDR physical;
  141807. +
  141808. + /* Logical address of allocation. */
  141809. + IN gctPOINTER logical;
  141810. +}
  141811. +gcsTASK_FREE_CONTIGUOUS_MEMORY;
  141812. +
  141813. +typedef struct _gcsTASK_UNMAP_USER_MEMORY * gcsTASK_UNMAP_USER_MEMORY_PTR;
  141814. +typedef struct _gcsTASK_UNMAP_USER_MEMORY
  141815. +{
  141816. + /* Task ID (gcvTASK_UNMAP_USER_MEMORY). */
  141817. + IN gceTASK id;
  141818. +
  141819. + /* Base address of user memory to unmap. */
  141820. + IN gctPOINTER memory;
  141821. +
  141822. + /* Size of user memory in bytes to unmap. */
  141823. + IN gctSIZE_T size;
  141824. +
  141825. + /* Info record returned by gcvHAL_MAP_USER_MEMORY. */
  141826. + IN gctPOINTER info;
  141827. +
  141828. + /* Physical address of mapped memory as returned by
  141829. + gcvHAL_MAP_USER_MEMORY. */
  141830. + IN gctUINT32 address;
  141831. +}
  141832. +gcsTASK_UNMAP_USER_MEMORY;
  141833. +
  141834. +#ifdef __cplusplus
  141835. +}
  141836. +#endif
  141837. +
  141838. +#endif /* __gc_hal_driver_h_ */
  141839. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h
  141840. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h 1970-01-01 01:00:00.000000000 +0100
  141841. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h 2014-08-20 19:23:53.566845873 +0200
  141842. @@ -0,0 +1,88 @@
  141843. +/****************************************************************************
  141844. +*
  141845. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  141846. +*
  141847. +* This program is free software; you can redistribute it and/or modify
  141848. +* it under the terms of the GNU General Public License as published by
  141849. +* the Free Software Foundation; either version 2 of the license, or
  141850. +* (at your option) any later version.
  141851. +*
  141852. +* This program is distributed in the hope that it will be useful,
  141853. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  141854. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  141855. +* GNU General Public License for more details.
  141856. +*
  141857. +* You should have received a copy of the GNU General Public License
  141858. +* along with this program; if not write to the Free Software
  141859. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  141860. +*
  141861. +*****************************************************************************/
  141862. +
  141863. +
  141864. +#ifndef __gc_hal_dump_h_
  141865. +#define __gc_hal_dump_h_
  141866. +
  141867. +#ifdef __cplusplus
  141868. +extern "C" {
  141869. +#endif
  141870. +
  141871. +/*
  141872. +** FILE LAYOUT:
  141873. +**
  141874. +** gcsDUMP_FILE structure
  141875. +**
  141876. +** gcsDUMP_DATA frame
  141877. +** gcsDUMP_DATA or gcDUMP_DATA_SIZE records rendingring the frame
  141878. +** gctUINT8 data[length]
  141879. +*/
  141880. +
  141881. +#define gcvDUMP_FILE_SIGNATURE gcmCC('g','c','D','B')
  141882. +
  141883. +typedef struct _gcsDUMP_FILE
  141884. +{
  141885. + gctUINT32 signature; /* File signature */
  141886. + gctSIZE_T length; /* Length of file */
  141887. + gctUINT32 frames; /* Number of frames in file */
  141888. +}
  141889. +gcsDUMP_FILE;
  141890. +
  141891. +typedef enum _gceDUMP_TAG
  141892. +{
  141893. + gcvTAG_SURFACE = gcmCC('s','u','r','f'),
  141894. + gcvTAG_FRAME = gcmCC('f','r','m',' '),
  141895. + gcvTAG_COMMAND = gcmCC('c','m','d',' '),
  141896. + gcvTAG_INDEX = gcmCC('i','n','d','x'),
  141897. + gcvTAG_STREAM = gcmCC('s','t','r','m'),
  141898. + gcvTAG_TEXTURE = gcmCC('t','e','x','t'),
  141899. + gcvTAG_RENDER_TARGET = gcmCC('r','n','d','r'),
  141900. + gcvTAG_DEPTH = gcmCC('z','b','u','f'),
  141901. + gcvTAG_RESOLVE = gcmCC('r','s','l','v'),
  141902. + gcvTAG_DELETE = gcmCC('d','e','l',' '),
  141903. +}
  141904. +gceDUMP_TAG;
  141905. +
  141906. +typedef struct _gcsDUMP_SURFACE
  141907. +{
  141908. + gceDUMP_TAG type; /* Type of record. */
  141909. + gctUINT32 address; /* Address of the surface. */
  141910. + gctINT16 width; /* Width of surface. */
  141911. + gctINT16 height; /* Height of surface. */
  141912. + gceSURF_FORMAT format; /* Surface pixel format. */
  141913. + gctSIZE_T length; /* Number of bytes inside the surface. */
  141914. +}
  141915. +gcsDUMP_SURFACE;
  141916. +
  141917. +typedef struct _gcsDUMP_DATA
  141918. +{
  141919. + gceDUMP_TAG type; /* Type of record. */
  141920. + gctSIZE_T length; /* Number of bytes of data. */
  141921. + gctUINT32 address; /* Address for the data. */
  141922. +}
  141923. +gcsDUMP_DATA;
  141924. +
  141925. +#ifdef __cplusplus
  141926. +}
  141927. +#endif
  141928. +
  141929. +#endif /* __gc_hal_dump_h_ */
  141930. +
  141931. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
  141932. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h 1970-01-01 01:00:00.000000000 +0100
  141933. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h 2014-08-20 19:31:46.132869024 +0200
  141934. @@ -0,0 +1,627 @@
  141935. +/****************************************************************************
  141936. +*
  141937. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  141938. +*
  141939. +* This program is free software; you can redistribute it and/or modify
  141940. +* it under the terms of the GNU General Public License as published by
  141941. +* the Free Software Foundation; either version 2 of the license, or
  141942. +* (at your option) any later version.
  141943. +*
  141944. +* This program is distributed in the hope that it will be useful,
  141945. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  141946. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  141947. +* GNU General Public License for more details.
  141948. +*
  141949. +* You should have received a copy of the GNU General Public License
  141950. +* along with this program; if not write to the Free Software
  141951. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  141952. +*
  141953. +*****************************************************************************/
  141954. +
  141955. +#ifndef __gc_hal_eglplatform_h_
  141956. +#define __gc_hal_eglplatform_h_
  141957. +
  141958. +/* Include VDK types. */
  141959. +#include "gc_hal_types.h"
  141960. +#include "gc_hal_base.h"
  141961. +#include "gc_hal_eglplatform_type.h"
  141962. +#ifdef __cplusplus
  141963. +extern "C" {
  141964. +#endif
  141965. +
  141966. +
  141967. +#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
  141968. +/* Win32 and Windows CE platforms. */
  141969. +#include <windows.h>
  141970. +typedef HDC HALNativeDisplayType;
  141971. +typedef HWND HALNativeWindowType;
  141972. +typedef HBITMAP HALNativePixmapType;
  141973. +
  141974. +typedef struct __BITFIELDINFO{
  141975. + BITMAPINFO bmi;
  141976. + RGBQUAD bmiColors[2];
  141977. +} BITFIELDINFO;
  141978. +
  141979. +#elif defined(LINUX) && defined(EGL_API_DFB) && !defined(__APPLE__)
  141980. +#include <directfb.h>
  141981. +typedef struct _DFBDisplay * HALNativeDisplayType;
  141982. +typedef struct _DFBWindow * HALNativeWindowType;
  141983. +typedef struct _DFBPixmap * HALNativePixmapType;
  141984. +
  141985. +#elif defined(LINUX) && defined(EGL_API_FB) && !defined(__APPLE__)
  141986. +
  141987. +#if defined(EGL_API_WL)
  141988. +/* Wayland platform. */
  141989. +#include "wayland-server.h"
  141990. +#include <wayland-egl.h>
  141991. +
  141992. +#define WL_EGL_NUM_BACKBUFFERS 3
  141993. +
  141994. +typedef struct _gcsWL_VIV_BUFFER
  141995. +{
  141996. + struct wl_resource *wl_buffer;
  141997. + gcoSURF surface;
  141998. + gctINT32 width, height;
  141999. +} gcsWL_VIV_BUFFER;
  142000. +
  142001. +typedef struct _gcsWL_EGL_DISPLAY
  142002. +{
  142003. + struct wl_display* wl_display;
  142004. + struct wl_viv* wl_viv;
  142005. + struct wl_registry *registry;
  142006. + struct wl_event_queue *wl_queue;
  142007. +} gcsWL_EGL_DISPLAY;
  142008. +
  142009. +typedef struct _gcsWL_EGL_BUFFER_INFO
  142010. +{
  142011. + gctINT32 width;
  142012. + gctINT32 height;
  142013. + gctINT32 stride;
  142014. + gceSURF_FORMAT format;
  142015. + gcuVIDMEM_NODE_PTR node;
  142016. + gcePOOL pool;
  142017. + gctUINT bytes;
  142018. + gcoSURF surface;
  142019. + gcoSURF attached_surface;
  142020. + gctINT32 invalidate;
  142021. + gctBOOL locked;
  142022. +} gcsWL_EGL_BUFFER_INFO;
  142023. +
  142024. +typedef struct _gcsWL_EGL_BUFFER
  142025. +{
  142026. + struct wl_buffer* wl_buffer;
  142027. + gcsWL_EGL_BUFFER_INFO info;
  142028. +} gcsWL_EGL_BUFFER;
  142029. +
  142030. +typedef struct _gcsWL_EGL_WINDOW_INFO
  142031. +{
  142032. + gctINT32 dx;
  142033. + gctINT32 dy;
  142034. + gctUINT width;
  142035. + gctUINT height;
  142036. + gctINT32 attached_width;
  142037. + gctINT32 attached_height;
  142038. + gceSURF_FORMAT format;
  142039. + gctUINT bpp;
  142040. +} gcsWL_EGL_WINDOW_INFO;
  142041. +
  142042. +struct wl_egl_window
  142043. +{
  142044. + gcsWL_EGL_DISPLAY* display;
  142045. + gcsWL_EGL_BUFFER backbuffers[WL_EGL_NUM_BACKBUFFERS];
  142046. + gcsWL_EGL_WINDOW_INFO info;
  142047. + gctUINT current;
  142048. + struct wl_surface* surface;
  142049. + struct wl_callback* frame_callback;
  142050. +};
  142051. +
  142052. +typedef void* HALNativeDisplayType;
  142053. +typedef void* HALNativeWindowType;
  142054. +typedef void* HALNativePixmapType;
  142055. +#else
  142056. +/* Linux platform for FBDEV. */
  142057. +typedef struct _FBDisplay * HALNativeDisplayType;
  142058. +typedef struct _FBWindow * HALNativeWindowType;
  142059. +typedef struct _FBPixmap * HALNativePixmapType;
  142060. +#endif
  142061. +#elif defined(__ANDROID__) || defined(ANDROID)
  142062. +
  142063. +struct egl_native_pixmap_t;
  142064. +
  142065. +#if ANDROID_SDK_VERSION >= 9
  142066. + #include <android/native_window.h>
  142067. +
  142068. + typedef struct ANativeWindow* HALNativeWindowType;
  142069. + typedef struct egl_native_pixmap_t* HALNativePixmapType;
  142070. + typedef void* HALNativeDisplayType;
  142071. +#else
  142072. + struct android_native_window_t;
  142073. + typedef struct android_native_window_t* HALNativeWindowType;
  142074. + typedef struct egl_native_pixmap_t * HALNativePixmapType;
  142075. + typedef void* HALNativeDisplayType;
  142076. +#endif
  142077. +
  142078. +#elif defined(LINUX) || defined(__APPLE__)
  142079. +/* X11 platform. */
  142080. +#include <X11/Xlib.h>
  142081. +#include <X11/Xutil.h>
  142082. +
  142083. +typedef Display * HALNativeDisplayType;
  142084. +typedef Window HALNativeWindowType;
  142085. +
  142086. +#ifdef CUSTOM_PIXMAP
  142087. +typedef void * HALNativePixmapType;
  142088. +#else
  142089. +typedef Pixmap HALNativePixmapType;
  142090. +#endif /* CUSTOM_PIXMAP */
  142091. +
  142092. +/* Rename some badly named X defines. */
  142093. +#ifdef Status
  142094. +# define XStatus int
  142095. +# undef Status
  142096. +#endif
  142097. +#ifdef Always
  142098. +# define XAlways 2
  142099. +# undef Always
  142100. +#endif
  142101. +#ifdef CurrentTime
  142102. +# undef CurrentTime
  142103. +# define XCurrentTime 0
  142104. +#endif
  142105. +
  142106. +#elif defined(__QNXNTO__)
  142107. +#include <screen/screen.h>
  142108. +
  142109. +/* VOID */
  142110. +typedef int HALNativeDisplayType;
  142111. +typedef screen_window_t HALNativeWindowType;
  142112. +typedef screen_pixmap_t HALNativePixmapType;
  142113. +
  142114. +#else
  142115. +
  142116. +#error "Platform not recognized"
  142117. +
  142118. +/* VOID */
  142119. +typedef void * HALNativeDisplayType;
  142120. +typedef void * HALNativeWindowType;
  142121. +typedef void * HALNativePixmapType;
  142122. +
  142123. +#endif
  142124. +
  142125. +/* define DUMMY according to the system */
  142126. +#if defined(EGL_API_WL)
  142127. +# define WL_DUMMY (31415926)
  142128. +# define EGL_DUMMY WL_DUMMY
  142129. +#elif defined(__ANDROID__) || defined(ANDROID)
  142130. +# define ANDROID_DUMMY (31415926)
  142131. +# define EGL_DUMMY ANDROID_DUMMY
  142132. +#else
  142133. +# define EGL_DUMMY (31415926)
  142134. +#endif
  142135. +
  142136. +/*******************************************************************************
  142137. +** Display. ********************************************************************
  142138. +*/
  142139. +
  142140. +gceSTATUS
  142141. +gcoOS_GetDisplay(
  142142. + OUT HALNativeDisplayType * Display,
  142143. + IN gctPOINTER Context
  142144. + );
  142145. +
  142146. +gceSTATUS
  142147. +gcoOS_GetDisplayByIndex(
  142148. + IN gctINT DisplayIndex,
  142149. + OUT HALNativeDisplayType * Display,
  142150. + IN gctPOINTER Context
  142151. + );
  142152. +
  142153. +gceSTATUS
  142154. +gcoOS_GetDisplayInfo(
  142155. + IN HALNativeDisplayType Display,
  142156. + OUT gctINT * Width,
  142157. + OUT gctINT * Height,
  142158. + OUT gctSIZE_T * Physical,
  142159. + OUT gctINT * Stride,
  142160. + OUT gctINT * BitsPerPixel
  142161. + );
  142162. +
  142163. +
  142164. +
  142165. +gceSTATUS
  142166. +gcoOS_GetDisplayInfoEx(
  142167. + IN HALNativeDisplayType Display,
  142168. + IN HALNativeWindowType Window,
  142169. + IN gctUINT DisplayInfoSize,
  142170. + OUT halDISPLAY_INFO * DisplayInfo
  142171. + );
  142172. +
  142173. +gceSTATUS
  142174. +gcoOS_GetNextDisplayInfoExByIndex(
  142175. + IN gctINT Index,
  142176. + IN HALNativeDisplayType Display,
  142177. + IN HALNativeWindowType Window,
  142178. + IN gctUINT DisplayInfoSize,
  142179. + OUT halDISPLAY_INFO * DisplayInfo
  142180. + );
  142181. +
  142182. +gceSTATUS
  142183. +gcoOS_GetDisplayVirtual(
  142184. + IN HALNativeDisplayType Display,
  142185. + OUT gctINT * Width,
  142186. + OUT gctINT * Height
  142187. + );
  142188. +
  142189. +gceSTATUS
  142190. +gcoOS_GetDisplayBackbuffer(
  142191. + IN HALNativeDisplayType Display,
  142192. + IN HALNativeWindowType Window,
  142193. + OUT gctPOINTER * context,
  142194. + OUT gcoSURF * surface,
  142195. + OUT gctUINT * Offset,
  142196. + OUT gctINT * X,
  142197. + OUT gctINT * Y
  142198. + );
  142199. +
  142200. +gceSTATUS
  142201. +gcoOS_SetDisplayVirtual(
  142202. + IN HALNativeDisplayType Display,
  142203. + IN HALNativeWindowType Window,
  142204. + IN gctUINT Offset,
  142205. + IN gctINT X,
  142206. + IN gctINT Y
  142207. + );
  142208. +
  142209. +gceSTATUS
  142210. +gcoOS_SetDisplayVirtualEx(
  142211. + IN HALNativeDisplayType Display,
  142212. + IN HALNativeWindowType Window,
  142213. + IN gctPOINTER Context,
  142214. + IN gcoSURF Surface,
  142215. + IN gctUINT Offset,
  142216. + IN gctINT X,
  142217. + IN gctINT Y
  142218. + );
  142219. +
  142220. +gceSTATUS
  142221. +gcoOS_SetSwapInterval(
  142222. + IN HALNativeDisplayType Display,
  142223. + IN gctINT Interval
  142224. +);
  142225. +
  142226. +gceSTATUS
  142227. +gcoOS_GetSwapInterval(
  142228. + IN HALNativeDisplayType Display,
  142229. + IN gctINT_PTR Min,
  142230. + IN gctINT_PTR Max
  142231. +);
  142232. +
  142233. +gceSTATUS
  142234. +gcoOS_DisplayBufferRegions(
  142235. + IN HALNativeDisplayType Display,
  142236. + IN HALNativeWindowType Window,
  142237. + IN gctINT NumRects,
  142238. + IN gctINT_PTR Rects
  142239. + );
  142240. +
  142241. +gceSTATUS
  142242. +gcoOS_DestroyDisplay(
  142243. + IN HALNativeDisplayType Display
  142244. + );
  142245. +
  142246. +gceSTATUS
  142247. +gcoOS_InitLocalDisplayInfo(
  142248. + IN HALNativeDisplayType Display,
  142249. + IN OUT gctPOINTER * localDisplay
  142250. + );
  142251. +
  142252. +gceSTATUS
  142253. +gcoOS_DeinitLocalDisplayInfo(
  142254. + IN HALNativeDisplayType Display,
  142255. + IN OUT gctPOINTER * localDisplay
  142256. + );
  142257. +
  142258. +gceSTATUS
  142259. +gcoOS_GetDisplayInfoEx2(
  142260. + IN HALNativeDisplayType Display,
  142261. + IN HALNativeWindowType Window,
  142262. + IN gctPOINTER localDisplay,
  142263. + IN gctUINT DisplayInfoSize,
  142264. + OUT halDISPLAY_INFO * DisplayInfo
  142265. + );
  142266. +
  142267. +gceSTATUS
  142268. +gcoOS_GetDisplayBackbufferEx(
  142269. + IN HALNativeDisplayType Display,
  142270. + IN HALNativeWindowType Window,
  142271. + IN gctPOINTER localDisplay,
  142272. + OUT gctPOINTER * context,
  142273. + OUT gcoSURF * surface,
  142274. + OUT gctUINT * Offset,
  142275. + OUT gctINT * X,
  142276. + OUT gctINT * Y
  142277. + );
  142278. +
  142279. +gceSTATUS
  142280. +gcoOS_IsValidDisplay(
  142281. + IN HALNativeDisplayType Display
  142282. + );
  142283. +
  142284. +gceSTATUS
  142285. +gcoOS_GetNativeVisualId(
  142286. + IN HALNativeDisplayType Display,
  142287. + OUT gctINT* nativeVisualId
  142288. + );
  142289. +
  142290. +gctBOOL
  142291. +gcoOS_SynchronousFlip(
  142292. + IN HALNativeDisplayType Display
  142293. + );
  142294. +
  142295. +/*******************************************************************************
  142296. +** Windows. ********************************************************************
  142297. +*/
  142298. +
  142299. +gceSTATUS
  142300. +gcoOS_CreateWindow(
  142301. + IN HALNativeDisplayType Display,
  142302. + IN gctINT X,
  142303. + IN gctINT Y,
  142304. + IN gctINT Width,
  142305. + IN gctINT Height,
  142306. + OUT HALNativeWindowType * Window
  142307. + );
  142308. +
  142309. +gceSTATUS
  142310. +gcoOS_GetWindowInfo(
  142311. + IN HALNativeDisplayType Display,
  142312. + IN HALNativeWindowType Window,
  142313. + OUT gctINT * X,
  142314. + OUT gctINT * Y,
  142315. + OUT gctINT * Width,
  142316. + OUT gctINT * Height,
  142317. + OUT gctINT * BitsPerPixel,
  142318. + OUT gctUINT * Offset
  142319. + );
  142320. +
  142321. +gceSTATUS
  142322. +gcoOS_DestroyWindow(
  142323. + IN HALNativeDisplayType Display,
  142324. + IN HALNativeWindowType Window
  142325. + );
  142326. +
  142327. +gceSTATUS
  142328. +gcoOS_DrawImage(
  142329. + IN HALNativeDisplayType Display,
  142330. + IN HALNativeWindowType Window,
  142331. + IN gctINT Left,
  142332. + IN gctINT Top,
  142333. + IN gctINT Right,
  142334. + IN gctINT Bottom,
  142335. + IN gctINT Width,
  142336. + IN gctINT Height,
  142337. + IN gctINT BitsPerPixel,
  142338. + IN gctPOINTER Bits
  142339. + );
  142340. +
  142341. +gceSTATUS
  142342. +gcoOS_GetImage(
  142343. + IN HALNativeWindowType Window,
  142344. + IN gctINT Left,
  142345. + IN gctINT Top,
  142346. + IN gctINT Right,
  142347. + IN gctINT Bottom,
  142348. + OUT gctINT * BitsPerPixel,
  142349. + OUT gctPOINTER * Bits
  142350. + );
  142351. +
  142352. +gceSTATUS
  142353. +gcoOS_GetWindowInfoEx(
  142354. + IN HALNativeDisplayType Display,
  142355. + IN HALNativeWindowType Window,
  142356. + OUT gctINT * X,
  142357. + OUT gctINT * Y,
  142358. + OUT gctINT * Width,
  142359. + OUT gctINT * Height,
  142360. + OUT gctINT * BitsPerPixel,
  142361. + OUT gctUINT * Offset,
  142362. + OUT gceSURF_FORMAT * Format
  142363. + );
  142364. +
  142365. +gceSTATUS
  142366. +gcoOS_DrawImageEx(
  142367. + IN HALNativeDisplayType Display,
  142368. + IN HALNativeWindowType Window,
  142369. + IN gctINT Left,
  142370. + IN gctINT Top,
  142371. + IN gctINT Right,
  142372. + IN gctINT Bottom,
  142373. + IN gctINT Width,
  142374. + IN gctINT Height,
  142375. + IN gctINT BitsPerPixel,
  142376. + IN gctPOINTER Bits,
  142377. + IN gceSURF_FORMAT Format
  142378. + );
  142379. +
  142380. +/*******************************************************************************
  142381. +** Pixmaps. ********************************************************************
  142382. +*/
  142383. +
  142384. +gceSTATUS
  142385. +gcoOS_CreatePixmap(
  142386. + IN HALNativeDisplayType Display,
  142387. + IN gctINT Width,
  142388. + IN gctINT Height,
  142389. + IN gctINT BitsPerPixel,
  142390. + OUT HALNativePixmapType * Pixmap
  142391. + );
  142392. +
  142393. +gceSTATUS
  142394. +gcoOS_GetPixmapInfo(
  142395. + IN HALNativeDisplayType Display,
  142396. + IN HALNativePixmapType Pixmap,
  142397. + OUT gctINT * Width,
  142398. + OUT gctINT * Height,
  142399. + OUT gctINT * BitsPerPixel,
  142400. + OUT gctINT * Stride,
  142401. + OUT gctPOINTER * Bits
  142402. + );
  142403. +
  142404. +gceSTATUS
  142405. +gcoOS_DrawPixmap(
  142406. + IN HALNativeDisplayType Display,
  142407. + IN HALNativePixmapType Pixmap,
  142408. + IN gctINT Left,
  142409. + IN gctINT Top,
  142410. + IN gctINT Right,
  142411. + IN gctINT Bottom,
  142412. + IN gctINT Width,
  142413. + IN gctINT Height,
  142414. + IN gctINT BitsPerPixel,
  142415. + IN gctPOINTER Bits
  142416. + );
  142417. +
  142418. +gceSTATUS
  142419. +gcoOS_DestroyPixmap(
  142420. + IN HALNativeDisplayType Display,
  142421. + IN HALNativePixmapType Pixmap
  142422. + );
  142423. +
  142424. +gceSTATUS
  142425. +gcoOS_GetPixmapInfoEx(
  142426. + IN HALNativeDisplayType Display,
  142427. + IN HALNativePixmapType Pixmap,
  142428. + OUT gctINT * Width,
  142429. + OUT gctINT * Height,
  142430. + OUT gctINT * BitsPerPixel,
  142431. + OUT gctINT * Stride,
  142432. + OUT gctPOINTER * Bits,
  142433. + OUT gceSURF_FORMAT * Format
  142434. + );
  142435. +
  142436. +gceSTATUS
  142437. +gcoOS_CopyPixmapBits(
  142438. + IN HALNativeDisplayType Display,
  142439. + IN HALNativePixmapType Pixmap,
  142440. + IN gctUINT DstWidth,
  142441. + IN gctUINT DstHeight,
  142442. + IN gctINT DstStride,
  142443. + IN gceSURF_FORMAT DstFormat,
  142444. + OUT gctPOINTER DstBits
  142445. + );
  142446. +
  142447. +/*******************************************************************************
  142448. +** OS relative. ****************************************************************
  142449. +*/
  142450. +gceSTATUS
  142451. +gcoOS_LoadEGLLibrary(
  142452. + OUT gctHANDLE * Handle
  142453. + );
  142454. +
  142455. +gceSTATUS
  142456. +gcoOS_FreeEGLLibrary(
  142457. + IN gctHANDLE Handle
  142458. + );
  142459. +
  142460. +gceSTATUS
  142461. +gcoOS_ShowWindow(
  142462. + IN HALNativeDisplayType Display,
  142463. + IN HALNativeWindowType Window
  142464. + );
  142465. +
  142466. +gceSTATUS
  142467. +gcoOS_HideWindow(
  142468. + IN HALNativeDisplayType Display,
  142469. + IN HALNativeWindowType Window
  142470. + );
  142471. +
  142472. +gceSTATUS
  142473. +gcoOS_SetWindowTitle(
  142474. + IN HALNativeDisplayType Display,
  142475. + IN HALNativeWindowType Window,
  142476. + IN gctCONST_STRING Title
  142477. + );
  142478. +
  142479. +gceSTATUS
  142480. +gcoOS_CapturePointer(
  142481. + IN HALNativeDisplayType Display,
  142482. + IN HALNativeWindowType Window
  142483. + );
  142484. +
  142485. +gceSTATUS
  142486. +gcoOS_GetEvent(
  142487. + IN HALNativeDisplayType Display,
  142488. + IN HALNativeWindowType Window,
  142489. + OUT halEvent * Event
  142490. + );
  142491. +
  142492. +gceSTATUS
  142493. +gcoOS_CreateClientBuffer(
  142494. + IN gctINT Width,
  142495. + IN gctINT Height,
  142496. + IN gctINT Format,
  142497. + IN gctINT Type,
  142498. + OUT gctPOINTER * ClientBuffer
  142499. + );
  142500. +
  142501. +gceSTATUS
  142502. +gcoOS_GetClientBufferInfo(
  142503. + IN gctPOINTER ClientBuffer,
  142504. + OUT gctINT * Width,
  142505. + OUT gctINT * Height,
  142506. + OUT gctINT * Stride,
  142507. + OUT gctPOINTER * Bits
  142508. + );
  142509. +
  142510. +gceSTATUS
  142511. +gcoOS_DestroyClientBuffer(
  142512. + IN gctPOINTER ClientBuffer
  142513. + );
  142514. +
  142515. +gceSTATUS
  142516. +gcoOS_DestroyContext(
  142517. + IN gctPOINTER Display,
  142518. + IN gctPOINTER Context
  142519. + );
  142520. +
  142521. +gceSTATUS
  142522. +gcoOS_CreateContext(
  142523. + IN gctPOINTER LocalDisplay,
  142524. + IN gctPOINTER Context
  142525. + );
  142526. +
  142527. +gceSTATUS
  142528. +gcoOS_MakeCurrent(
  142529. + IN gctPOINTER LocalDisplay,
  142530. + IN HALNativeWindowType DrawDrawable,
  142531. + IN HALNativeWindowType ReadDrawable,
  142532. + IN gctPOINTER Context,
  142533. + IN gcoSURF ResolveTarget
  142534. + );
  142535. +
  142536. +gceSTATUS
  142537. +gcoOS_CreateDrawable(
  142538. + IN gctPOINTER LocalDisplay,
  142539. + IN HALNativeWindowType Drawable
  142540. + );
  142541. +
  142542. +gceSTATUS
  142543. +gcoOS_DestroyDrawable(
  142544. + IN gctPOINTER LocalDisplay,
  142545. + IN HALNativeWindowType Drawable
  142546. + );
  142547. +gceSTATUS
  142548. +gcoOS_SwapBuffers(
  142549. + IN gctPOINTER LocalDisplay,
  142550. + IN HALNativeWindowType Drawable,
  142551. + IN gcoSURF RenderTarget,
  142552. + IN gcoSURF ResolveTarget,
  142553. + IN gctPOINTER ResolveBits,
  142554. + OUT gctUINT *Width,
  142555. + OUT gctUINT *Height
  142556. + );
  142557. +#ifdef __cplusplus
  142558. +}
  142559. +#endif
  142560. +
  142561. +#endif /* __gc_hal_eglplatform_h_ */
  142562. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h
  142563. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h 1970-01-01 01:00:00.000000000 +0100
  142564. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h 2014-08-20 19:23:53.566845873 +0200
  142565. @@ -0,0 +1,286 @@
  142566. +/****************************************************************************
  142567. +*
  142568. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  142569. +*
  142570. +* This program is free software; you can redistribute it and/or modify
  142571. +* it under the terms of the GNU General Public License as published by
  142572. +* the Free Software Foundation; either version 2 of the license, or
  142573. +* (at your option) any later version.
  142574. +*
  142575. +* This program is distributed in the hope that it will be useful,
  142576. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  142577. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  142578. +* GNU General Public License for more details.
  142579. +*
  142580. +* You should have received a copy of the GNU General Public License
  142581. +* along with this program; if not write to the Free Software
  142582. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  142583. +*
  142584. +*****************************************************************************/
  142585. +
  142586. +
  142587. +#ifndef __gc_hal_eglplatform_type_h_
  142588. +#define __gc_hal_eglplatform_type_h_
  142589. +
  142590. +#ifdef __cplusplus
  142591. +extern "C" {
  142592. +#endif
  142593. +
  142594. +/*******************************************************************************
  142595. +** Events. *********************************************************************
  142596. +*/
  142597. +
  142598. +typedef enum _halEventType
  142599. +{
  142600. + /* Keyboard event. */
  142601. + HAL_KEYBOARD,
  142602. +
  142603. + /* Mouse move event. */
  142604. + HAL_POINTER,
  142605. +
  142606. + /* Mouse button event. */
  142607. + HAL_BUTTON,
  142608. +
  142609. + /* Application close event. */
  142610. + HAL_CLOSE,
  142611. +
  142612. + /* Application window has been updated. */
  142613. + HAL_WINDOW_UPDATE
  142614. +}
  142615. +halEventType;
  142616. +
  142617. +/* Scancodes for keyboard. */
  142618. +typedef enum _halKeys
  142619. +{
  142620. + HAL_UNKNOWN = -1,
  142621. +
  142622. + HAL_BACKSPACE = 0x08,
  142623. + HAL_TAB,
  142624. + HAL_ENTER = 0x0D,
  142625. + HAL_ESCAPE = 0x1B,
  142626. +
  142627. + HAL_SPACE = 0x20,
  142628. + HAL_SINGLEQUOTE = 0x27,
  142629. + HAL_PAD_ASTERISK = 0x2A,
  142630. + HAL_COMMA = 0x2C,
  142631. + HAL_HYPHEN,
  142632. + HAL_PERIOD,
  142633. + HAL_SLASH,
  142634. + HAL_0,
  142635. + HAL_1,
  142636. + HAL_2,
  142637. + HAL_3,
  142638. + HAL_4,
  142639. + HAL_5,
  142640. + HAL_6,
  142641. + HAL_7,
  142642. + HAL_8,
  142643. + HAL_9,
  142644. + HAL_SEMICOLON = 0x3B,
  142645. + HAL_EQUAL = 0x3D,
  142646. + HAL_A = 0x41,
  142647. + HAL_B,
  142648. + HAL_C,
  142649. + HAL_D,
  142650. + HAL_E,
  142651. + HAL_F,
  142652. + HAL_G,
  142653. + HAL_H,
  142654. + HAL_I,
  142655. + HAL_J,
  142656. + HAL_K,
  142657. + HAL_L,
  142658. + HAL_M,
  142659. + HAL_N,
  142660. + HAL_O,
  142661. + HAL_P,
  142662. + HAL_Q,
  142663. + HAL_R,
  142664. + HAL_S,
  142665. + HAL_T,
  142666. + HAL_U,
  142667. + HAL_V,
  142668. + HAL_W,
  142669. + HAL_X,
  142670. + HAL_Y,
  142671. + HAL_Z,
  142672. + HAL_LBRACKET,
  142673. + HAL_BACKSLASH,
  142674. + HAL_RBRACKET,
  142675. + HAL_BACKQUOTE = 0x60,
  142676. +
  142677. + HAL_F1 = 0x80,
  142678. + HAL_F2,
  142679. + HAL_F3,
  142680. + HAL_F4,
  142681. + HAL_F5,
  142682. + HAL_F6,
  142683. + HAL_F7,
  142684. + HAL_F8,
  142685. + HAL_F9,
  142686. + HAL_F10,
  142687. + HAL_F11,
  142688. + HAL_F12,
  142689. +
  142690. + HAL_LCTRL,
  142691. + HAL_RCTRL,
  142692. + HAL_LSHIFT,
  142693. + HAL_RSHIFT,
  142694. + HAL_LALT,
  142695. + HAL_RALT,
  142696. + HAL_CAPSLOCK,
  142697. + HAL_NUMLOCK,
  142698. + HAL_SCROLLLOCK,
  142699. + HAL_PAD_0,
  142700. + HAL_PAD_1,
  142701. + HAL_PAD_2,
  142702. + HAL_PAD_3,
  142703. + HAL_PAD_4,
  142704. + HAL_PAD_5,
  142705. + HAL_PAD_6,
  142706. + HAL_PAD_7,
  142707. + HAL_PAD_8,
  142708. + HAL_PAD_9,
  142709. + HAL_PAD_HYPHEN,
  142710. + HAL_PAD_PLUS,
  142711. + HAL_PAD_SLASH,
  142712. + HAL_PAD_PERIOD,
  142713. + HAL_PAD_ENTER,
  142714. + HAL_SYSRQ,
  142715. + HAL_PRNTSCRN,
  142716. + HAL_BREAK,
  142717. + HAL_UP,
  142718. + HAL_LEFT,
  142719. + HAL_RIGHT,
  142720. + HAL_DOWN,
  142721. + HAL_HOME,
  142722. + HAL_END,
  142723. + HAL_PGUP,
  142724. + HAL_PGDN,
  142725. + HAL_INSERT,
  142726. + HAL_DELETE,
  142727. + HAL_LWINDOW,
  142728. + HAL_RWINDOW,
  142729. + HAL_MENU,
  142730. + HAL_POWER,
  142731. + HAL_SLEEP,
  142732. + HAL_WAKE
  142733. +}
  142734. +halKeys;
  142735. +
  142736. +/* Structure that defined keyboard mapping. */
  142737. +typedef struct _halKeyMap
  142738. +{
  142739. + /* Normal key. */
  142740. + halKeys normal;
  142741. +
  142742. + /* Extended key. */
  142743. + halKeys extended;
  142744. +}
  142745. +halKeyMap;
  142746. +
  142747. +/* Event structure. */
  142748. +typedef struct _halEvent
  142749. +{
  142750. + /* Event type. */
  142751. + halEventType type;
  142752. +
  142753. + /* Event data union. */
  142754. + union _halEventData
  142755. + {
  142756. + /* Event data for keyboard. */
  142757. + struct _halKeyboard
  142758. + {
  142759. + /* Scancode. */
  142760. + halKeys scancode;
  142761. +
  142762. + /* ASCII characte of the key pressed. */
  142763. + char key;
  142764. +
  142765. + /* Flag whether the key was pressed (1) or released (0). */
  142766. + char pressed;
  142767. + }
  142768. + keyboard;
  142769. +
  142770. + /* Event data for pointer. */
  142771. + struct _halPointer
  142772. + {
  142773. + /* Current pointer coordinate. */
  142774. + int x;
  142775. + int y;
  142776. + }
  142777. + pointer;
  142778. +
  142779. + /* Event data for mouse buttons. */
  142780. + struct _halButton
  142781. + {
  142782. + /* Left button state. */
  142783. + int left;
  142784. +
  142785. + /* Middle button state. */
  142786. + int middle;
  142787. +
  142788. + /* Right button state. */
  142789. + int right;
  142790. +
  142791. + /* Current pointer coordinate. */
  142792. + int x;
  142793. + int y;
  142794. + }
  142795. + button;
  142796. + }
  142797. + data;
  142798. +}
  142799. +halEvent;
  142800. +
  142801. +/* VFK_DISPLAY_INFO structure defining information returned by
  142802. + vdkGetDisplayInfoEx. */
  142803. +typedef struct _halDISPLAY_INFO
  142804. +{
  142805. + /* The size of the display in pixels. */
  142806. + int width;
  142807. + int height;
  142808. +
  142809. + /* The stride of the dispay. -1 is returned if the stride is not known
  142810. + ** for the specified display.*/
  142811. + int stride;
  142812. +
  142813. + /* The color depth of the display in bits per pixel. */
  142814. + int bitsPerPixel;
  142815. +
  142816. + /* The logical pointer to the display memory buffer. NULL is returned
  142817. + ** if the pointer is not known for the specified display. */
  142818. + void * logical;
  142819. +
  142820. + /* The physical address of the display memory buffer. ~0 is returned
  142821. + ** if the address is not known for the specified display. */
  142822. + unsigned long physical;
  142823. +
  142824. + int wrapFB; /* true if compositor, false otherwise. */
  142825. +
  142826. +#ifndef __QNXNTO__
  142827. + /* 355_FB_MULTI_BUFFER */
  142828. + int multiBuffer;
  142829. + int backBufferY;
  142830. +#endif
  142831. +
  142832. + /* The color info of the display. */
  142833. + unsigned int alphaLength;
  142834. + unsigned int alphaOffset;
  142835. + unsigned int redLength;
  142836. + unsigned int redOffset;
  142837. + unsigned int greenLength;
  142838. + unsigned int greenOffset;
  142839. + unsigned int blueLength;
  142840. + unsigned int blueOffset;
  142841. +
  142842. + /* Display flip support. */
  142843. + int flip;
  142844. +}
  142845. +halDISPLAY_INFO;
  142846. +
  142847. +#ifdef __cplusplus
  142848. +}
  142849. +#endif
  142850. +
  142851. +#endif /* __gc_hal_eglplatform_type_h_ */
  142852. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
  142853. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h 1970-01-01 01:00:00.000000000 +0100
  142854. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h 2014-08-20 19:23:53.566845873 +0200
  142855. @@ -0,0 +1,2053 @@
  142856. +/****************************************************************************
  142857. +*
  142858. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  142859. +*
  142860. +* This program is free software; you can redistribute it and/or modify
  142861. +* it under the terms of the GNU General Public License as published by
  142862. +* the Free Software Foundation; either version 2 of the license, or
  142863. +* (at your option) any later version.
  142864. +*
  142865. +* This program is distributed in the hope that it will be useful,
  142866. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  142867. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  142868. +* GNU General Public License for more details.
  142869. +*
  142870. +* You should have received a copy of the GNU General Public License
  142871. +* along with this program; if not write to the Free Software
  142872. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  142873. +*
  142874. +*****************************************************************************/
  142875. +
  142876. +
  142877. +#ifndef __gc_hal_engine_h_
  142878. +#define __gc_hal_engine_h_
  142879. +
  142880. +#ifndef VIVANTE_NO_3D
  142881. +#include "gc_hal_types.h"
  142882. +#include "gc_hal_enum.h"
  142883. +
  142884. +#if gcdENABLE_VG
  142885. +#include "gc_hal_engine_vg.h"
  142886. +#endif
  142887. +
  142888. +#ifdef __cplusplus
  142889. +extern "C" {
  142890. +#endif
  142891. +
  142892. +/******************************************************************************\
  142893. +****************************** Object Declarations *****************************
  142894. +\******************************************************************************/
  142895. +
  142896. +typedef struct _gcoSTREAM * gcoSTREAM;
  142897. +typedef struct _gcoVERTEX * gcoVERTEX;
  142898. +typedef struct _gcoTEXTURE * gcoTEXTURE;
  142899. +typedef struct _gcoINDEX * gcoINDEX;
  142900. +typedef struct _gcsVERTEX_ATTRIBUTES * gcsVERTEX_ATTRIBUTES_PTR;
  142901. +typedef struct _gcoVERTEXARRAY * gcoVERTEXARRAY;
  142902. +
  142903. +#define gcdATTRIBUTE_COUNT 16
  142904. +
  142905. +/******************************************************************************\
  142906. +********************************* Enumerations *********************************
  142907. +\******************************************************************************/
  142908. +
  142909. +/* Shading format. */
  142910. +typedef enum _gceSHADING
  142911. +{
  142912. + gcvSHADING_SMOOTH,
  142913. + gcvSHADING_FLAT_D3D,
  142914. + gcvSHADING_FLAT_OPENGL,
  142915. +}
  142916. +gceSHADING;
  142917. +
  142918. +/* Culling modes. */
  142919. +typedef enum _gceCULL
  142920. +{
  142921. + gcvCULL_NONE,
  142922. + gcvCULL_CCW,
  142923. + gcvCULL_CW,
  142924. +}
  142925. +gceCULL;
  142926. +
  142927. +/* Fill modes. */
  142928. +typedef enum _gceFILL
  142929. +{
  142930. + gcvFILL_POINT,
  142931. + gcvFILL_WIRE_FRAME,
  142932. + gcvFILL_SOLID,
  142933. +}
  142934. +gceFILL;
  142935. +
  142936. +/* Compare modes. */
  142937. +typedef enum _gceCOMPARE
  142938. +{
  142939. + gcvCOMPARE_NEVER,
  142940. + gcvCOMPARE_NOT_EQUAL,
  142941. + gcvCOMPARE_LESS,
  142942. + gcvCOMPARE_LESS_OR_EQUAL,
  142943. + gcvCOMPARE_EQUAL,
  142944. + gcvCOMPARE_GREATER,
  142945. + gcvCOMPARE_GREATER_OR_EQUAL,
  142946. + gcvCOMPARE_ALWAYS,
  142947. + gcvCOMPARE_INVALID = -1
  142948. +}
  142949. +gceCOMPARE;
  142950. +
  142951. +/* Stencil modes. */
  142952. +typedef enum _gceSTENCIL_MODE
  142953. +{
  142954. + gcvSTENCIL_NONE,
  142955. + gcvSTENCIL_SINGLE_SIDED,
  142956. + gcvSTENCIL_DOUBLE_SIDED,
  142957. +}
  142958. +gceSTENCIL_MODE;
  142959. +
  142960. +/* Stencil operations. */
  142961. +typedef enum _gceSTENCIL_OPERATION
  142962. +{
  142963. + gcvSTENCIL_KEEP,
  142964. + gcvSTENCIL_REPLACE,
  142965. + gcvSTENCIL_ZERO,
  142966. + gcvSTENCIL_INVERT,
  142967. + gcvSTENCIL_INCREMENT,
  142968. + gcvSTENCIL_DECREMENT,
  142969. + gcvSTENCIL_INCREMENT_SATURATE,
  142970. + gcvSTENCIL_DECREMENT_SATURATE,
  142971. + gcvSTENCIL_OPERATION_INVALID = -1
  142972. +}
  142973. +gceSTENCIL_OPERATION;
  142974. +
  142975. +/* Stencil selection. */
  142976. +typedef enum _gceSTENCIL_WHERE
  142977. +{
  142978. + gcvSTENCIL_FRONT,
  142979. + gcvSTENCIL_BACK,
  142980. +}
  142981. +gceSTENCIL_WHERE;
  142982. +
  142983. +/* Texture addressing selection. */
  142984. +typedef enum _gceTEXTURE_WHICH
  142985. +{
  142986. + gcvTEXTURE_S,
  142987. + gcvTEXTURE_T,
  142988. + gcvTEXTURE_R,
  142989. +}
  142990. +gceTEXTURE_WHICH;
  142991. +
  142992. +/* Texture addressing modes. */
  142993. +typedef enum _gceTEXTURE_ADDRESSING
  142994. +{
  142995. + gcvTEXTURE_WRAP,
  142996. + gcvTEXTURE_CLAMP,
  142997. + gcvTEXTURE_BORDER,
  142998. + gcvTEXTURE_MIRROR,
  142999. + gcvTEXTURE_MIRROR_ONCE,
  143000. +}
  143001. +gceTEXTURE_ADDRESSING;
  143002. +
  143003. +/* Texture filters. */
  143004. +typedef enum _gceTEXTURE_FILTER
  143005. +{
  143006. + gcvTEXTURE_NONE,
  143007. + gcvTEXTURE_POINT,
  143008. + gcvTEXTURE_LINEAR,
  143009. + gcvTEXTURE_ANISOTROPIC,
  143010. +}
  143011. +gceTEXTURE_FILTER;
  143012. +
  143013. +/* Primitive types. */
  143014. +typedef enum _gcePRIMITIVE
  143015. +{
  143016. + gcvPRIMITIVE_POINT_LIST,
  143017. + gcvPRIMITIVE_LINE_LIST,
  143018. + gcvPRIMITIVE_LINE_STRIP,
  143019. + gcvPRIMITIVE_LINE_LOOP,
  143020. + gcvPRIMITIVE_TRIANGLE_LIST,
  143021. + gcvPRIMITIVE_TRIANGLE_STRIP,
  143022. + gcvPRIMITIVE_TRIANGLE_FAN,
  143023. + gcvPRIMITIVE_RECTANGLE,
  143024. +}
  143025. +gcePRIMITIVE;
  143026. +
  143027. +/* Index types. */
  143028. +typedef enum _gceINDEX_TYPE
  143029. +{
  143030. + gcvINDEX_8,
  143031. + gcvINDEX_16,
  143032. + gcvINDEX_32,
  143033. +}
  143034. +gceINDEX_TYPE;
  143035. +
  143036. +/******************************************************************************\
  143037. +********************************* gcoHAL Object *********************************
  143038. +\******************************************************************************/
  143039. +
  143040. +/* Query the target capabilities. */
  143041. +gceSTATUS
  143042. +gcoHAL_QueryTargetCaps(
  143043. + IN gcoHAL Hal,
  143044. + OUT gctUINT * MaxWidth,
  143045. + OUT gctUINT * MaxHeight,
  143046. + OUT gctUINT * MultiTargetCount,
  143047. + OUT gctUINT * MaxSamples
  143048. + );
  143049. +
  143050. +gceSTATUS
  143051. +gcoHAL_SetDepthOnly(
  143052. + IN gcoHAL Hal,
  143053. + IN gctBOOL Enable
  143054. + );
  143055. +
  143056. +gceSTATUS
  143057. +gcoHAL_QueryShaderCaps(
  143058. + IN gcoHAL Hal,
  143059. + OUT gctUINT * VertexUniforms,
  143060. + OUT gctUINT * FragmentUniforms,
  143061. + OUT gctUINT * Varyings
  143062. + );
  143063. +
  143064. +gceSTATUS
  143065. +gcoHAL_QueryTextureCaps(
  143066. + IN gcoHAL Hal,
  143067. + OUT gctUINT * MaxWidth,
  143068. + OUT gctUINT * MaxHeight,
  143069. + OUT gctUINT * MaxDepth,
  143070. + OUT gctBOOL * Cubic,
  143071. + OUT gctBOOL * NonPowerOfTwo,
  143072. + OUT gctUINT * VertexSamplers,
  143073. + OUT gctUINT * PixelSamplers
  143074. + );
  143075. +
  143076. +gceSTATUS
  143077. +gcoHAL_QueryTextureMaxAniso(
  143078. + IN gcoHAL Hal,
  143079. + OUT gctUINT * MaxAnisoValue
  143080. + );
  143081. +
  143082. +gceSTATUS
  143083. +gcoHAL_QueryStreamCaps(
  143084. + IN gcoHAL Hal,
  143085. + OUT gctUINT32 * MaxAttributes,
  143086. + OUT gctUINT32 * MaxStreamSize,
  143087. + OUT gctUINT32 * NumberOfStreams,
  143088. + OUT gctUINT32 * Alignment
  143089. + );
  143090. +
  143091. +/******************************************************************************\
  143092. +********************************* gcoSURF Object ********************************
  143093. +\******************************************************************************/
  143094. +
  143095. +/*----------------------------------------------------------------------------*/
  143096. +/*--------------------------------- gcoSURF 3D --------------------------------*/
  143097. +
  143098. +/* Copy surface. */
  143099. +gceSTATUS
  143100. +gcoSURF_Copy(
  143101. + IN gcoSURF Surface,
  143102. + IN gcoSURF Source
  143103. + );
  143104. +
  143105. +/* Clear surface. */
  143106. +gceSTATUS
  143107. +gcoSURF_Clear(
  143108. + IN gcoSURF Surface,
  143109. + IN gctUINT Flags
  143110. + );
  143111. +
  143112. +/* Set number of samples for a gcoSURF object. */
  143113. +gceSTATUS
  143114. +gcoSURF_SetSamples(
  143115. + IN gcoSURF Surface,
  143116. + IN gctUINT Samples
  143117. + );
  143118. +
  143119. +/* Get the number of samples per pixel. */
  143120. +gceSTATUS
  143121. +gcoSURF_GetSamples(
  143122. + IN gcoSURF Surface,
  143123. + OUT gctUINT_PTR Samples
  143124. + );
  143125. +
  143126. +/* Clear rectangular surface. */
  143127. +gceSTATUS
  143128. +gcoSURF_ClearRect(
  143129. + IN gcoSURF Surface,
  143130. + IN gctINT Left,
  143131. + IN gctINT Top,
  143132. + IN gctINT Right,
  143133. + IN gctINT Bottom,
  143134. + IN gctUINT Flags
  143135. + );
  143136. +
  143137. +/* TO BE REMOVED */
  143138. + gceSTATUS
  143139. + depr_gcoSURF_Resolve(
  143140. + IN gcoSURF SrcSurface,
  143141. + IN gcoSURF DestSurface,
  143142. + IN gctUINT32 DestAddress,
  143143. + IN gctPOINTER DestBits,
  143144. + IN gctINT DestStride,
  143145. + IN gceSURF_TYPE DestType,
  143146. + IN gceSURF_FORMAT DestFormat,
  143147. + IN gctUINT DestWidth,
  143148. + IN gctUINT DestHeight
  143149. + );
  143150. +
  143151. + gceSTATUS
  143152. + depr_gcoSURF_ResolveRect(
  143153. + IN gcoSURF SrcSurface,
  143154. + IN gcoSURF DestSurface,
  143155. + IN gctUINT32 DestAddress,
  143156. + IN gctPOINTER DestBits,
  143157. + IN gctINT DestStride,
  143158. + IN gceSURF_TYPE DestType,
  143159. + IN gceSURF_FORMAT DestFormat,
  143160. + IN gctUINT DestWidth,
  143161. + IN gctUINT DestHeight,
  143162. + IN gcsPOINT_PTR SrcOrigin,
  143163. + IN gcsPOINT_PTR DestOrigin,
  143164. + IN gcsPOINT_PTR RectSize
  143165. + );
  143166. +
  143167. +/* Resample surface. */
  143168. +gceSTATUS
  143169. +gcoSURF_Resample(
  143170. + IN gcoSURF SrcSurface,
  143171. + IN gcoSURF DestSurface
  143172. + );
  143173. +
  143174. +/* Resolve surface. */
  143175. +gceSTATUS
  143176. +gcoSURF_Resolve(
  143177. + IN gcoSURF SrcSurface,
  143178. + IN gcoSURF DestSurface
  143179. + );
  143180. +
  143181. +gceSTATUS
  143182. +gcoSURF_IsHWResolveable(
  143183. + IN gcoSURF SrcSurface,
  143184. + IN gcoSURF DestSurface,
  143185. + IN gcsPOINT_PTR SrcOrigin,
  143186. + IN gcsPOINT_PTR DestOrigin,
  143187. + IN gcsPOINT_PTR RectSize
  143188. + );
  143189. +
  143190. +/* Resolve rectangular area of a surface. */
  143191. +gceSTATUS
  143192. +gcoSURF_ResolveRect(
  143193. + IN gcoSURF SrcSurface,
  143194. + IN gcoSURF DestSurface,
  143195. + IN gcsPOINT_PTR SrcOrigin,
  143196. + IN gcsPOINT_PTR DestOrigin,
  143197. + IN gcsPOINT_PTR RectSize
  143198. + );
  143199. +
  143200. +/* Set surface resolvability. */
  143201. +gceSTATUS
  143202. +gcoSURF_SetResolvability(
  143203. + IN gcoSURF Surface,
  143204. + IN gctBOOL Resolvable
  143205. + );
  143206. +
  143207. +gceSTATUS
  143208. +gcoSURF_IsRenderable(
  143209. + IN gcoSURF Surface
  143210. + );
  143211. +
  143212. +gceSTATUS
  143213. +gcoSURF_IsFormatRenderableAsRT(
  143214. + IN gcoSURF Surface
  143215. + );
  143216. +
  143217. +#if gcdSYNC
  143218. +gceSTATUS
  143219. +gcoSURF_GetFence(
  143220. + IN gcoSURF Surface
  143221. + );
  143222. +gceSTATUS
  143223. +gcoSURF_WaitFence(
  143224. + IN gcoSURF Surface
  143225. + );
  143226. +
  143227. +gceSTATUS
  143228. +gcoSTREAM_GetFence(
  143229. + IN gcoSTREAM stream
  143230. + );
  143231. +
  143232. +gceSTATUS
  143233. +gcoSTREAM_WaitFence(
  143234. + IN gcoSTREAM stream
  143235. + );
  143236. +
  143237. +gceSTATUS
  143238. +gcoINDEX_GetFence(
  143239. + IN gcoINDEX index
  143240. + );
  143241. +
  143242. +gceSTATUS
  143243. +gcoINDEX_WaitFence(
  143244. + IN gcoINDEX index
  143245. + );
  143246. +#endif
  143247. +
  143248. +/******************************************************************************\
  143249. +******************************** gcoINDEX Object *******************************
  143250. +\******************************************************************************/
  143251. +
  143252. +/* Construct a new gcoINDEX object. */
  143253. +gceSTATUS
  143254. +gcoINDEX_Construct(
  143255. + IN gcoHAL Hal,
  143256. + OUT gcoINDEX * Index
  143257. + );
  143258. +
  143259. +/* Destroy a gcoINDEX object. */
  143260. +gceSTATUS
  143261. +gcoINDEX_Destroy(
  143262. + IN gcoINDEX Index
  143263. + );
  143264. +
  143265. +/* Lock index in memory. */
  143266. +gceSTATUS
  143267. +gcoINDEX_Lock(
  143268. + IN gcoINDEX Index,
  143269. + OUT gctUINT32 * Address,
  143270. + OUT gctPOINTER * Memory
  143271. + );
  143272. +
  143273. +/* Unlock index that was previously locked with gcoINDEX_Lock. */
  143274. +gceSTATUS
  143275. +gcoINDEX_Unlock(
  143276. + IN gcoINDEX Index
  143277. + );
  143278. +
  143279. +/* Upload index data into the memory. */
  143280. +gceSTATUS
  143281. +gcoINDEX_Load(
  143282. + IN gcoINDEX Index,
  143283. + IN gceINDEX_TYPE IndexType,
  143284. + IN gctUINT32 IndexCount,
  143285. + IN gctPOINTER IndexBuffer
  143286. + );
  143287. +
  143288. +/* Bind an index object to the hardware. */
  143289. +gceSTATUS
  143290. +gcoINDEX_Bind(
  143291. + IN gcoINDEX Index,
  143292. + IN gceINDEX_TYPE Type
  143293. + );
  143294. +
  143295. +/* Bind an index object to the hardware. */
  143296. +gceSTATUS
  143297. +gcoINDEX_BindOffset(
  143298. + IN gcoINDEX Index,
  143299. + IN gceINDEX_TYPE Type,
  143300. + IN gctUINT32 Offset
  143301. + );
  143302. +
  143303. +/* Free existing index buffer. */
  143304. +gceSTATUS
  143305. +gcoINDEX_Free(
  143306. + IN gcoINDEX Index
  143307. + );
  143308. +
  143309. +/* Upload data into an index buffer. */
  143310. +gceSTATUS
  143311. +gcoINDEX_Upload(
  143312. + IN gcoINDEX Index,
  143313. + IN gctCONST_POINTER Buffer,
  143314. + IN gctSIZE_T Bytes
  143315. + );
  143316. +
  143317. +/* Upload data into an index buffer starting at an offset. */
  143318. +gceSTATUS
  143319. +gcoINDEX_UploadOffset(
  143320. + IN gcoINDEX Index,
  143321. + IN gctUINT32 Offset,
  143322. + IN gctCONST_POINTER Buffer,
  143323. + IN gctSIZE_T Bytes
  143324. + );
  143325. +
  143326. +/*Merge index2 to index1 from 0, index2 must subset of inex1*/
  143327. +gceSTATUS
  143328. +gcoINDEX_Merge(
  143329. + IN gcoINDEX Index1,
  143330. + IN gcoINDEX Index2
  143331. + );
  143332. +
  143333. +/*check if index buffer is enough for this draw*/
  143334. +gctBOOL
  143335. +gcoINDEX_CheckRange(
  143336. + IN gcoINDEX Index,
  143337. + IN gceINDEX_TYPE Type,
  143338. + IN gctINT Count,
  143339. + IN gctUINT32 Indices
  143340. + );
  143341. +
  143342. +/* Query the index capabilities. */
  143343. +gceSTATUS
  143344. +gcoINDEX_QueryCaps(
  143345. + OUT gctBOOL * Index8,
  143346. + OUT gctBOOL * Index16,
  143347. + OUT gctBOOL * Index32,
  143348. + OUT gctUINT * MaxIndex
  143349. + );
  143350. +
  143351. +/* Determine the index range in the current index buffer. */
  143352. +gceSTATUS
  143353. +gcoINDEX_GetIndexRange(
  143354. + IN gcoINDEX Index,
  143355. + IN gceINDEX_TYPE Type,
  143356. + IN gctUINT32 Offset,
  143357. + IN gctUINT32 Count,
  143358. + OUT gctUINT32 * MinimumIndex,
  143359. + OUT gctUINT32 * MaximumIndex
  143360. + );
  143361. +
  143362. +/* Dynamic buffer management. */
  143363. +gceSTATUS
  143364. +gcoINDEX_SetDynamic(
  143365. + IN gcoINDEX Index,
  143366. + IN gctSIZE_T Bytes,
  143367. + IN gctUINT Buffers
  143368. + );
  143369. +
  143370. +gceSTATUS
  143371. +gcoINDEX_UploadDynamic(
  143372. + IN gcoINDEX Index,
  143373. + IN gctCONST_POINTER Data,
  143374. + IN gctSIZE_T Bytes
  143375. + );
  143376. +
  143377. +/******************************************************************************\
  143378. +********************************** gco3D Object *********************************
  143379. +\******************************************************************************/
  143380. +
  143381. +/* Clear flags. */
  143382. +typedef enum _gceCLEAR
  143383. +{
  143384. + gcvCLEAR_COLOR = 0x1,
  143385. + gcvCLEAR_DEPTH = 0x2,
  143386. + gcvCLEAR_STENCIL = 0x4,
  143387. + gcvCLEAR_HZ = 0x8,
  143388. + gcvCLEAR_HAS_VAA = 0x10,
  143389. +}
  143390. +gceCLEAR;
  143391. +
  143392. +/* Blending targets. */
  143393. +typedef enum _gceBLEND_UNIT
  143394. +{
  143395. + gcvBLEND_SOURCE,
  143396. + gcvBLEND_TARGET,
  143397. +}
  143398. +gceBLEND_UNIT;
  143399. +
  143400. +/* Construct a new gco3D object. */
  143401. +gceSTATUS
  143402. +gco3D_Construct(
  143403. + IN gcoHAL Hal,
  143404. + OUT gco3D * Engine
  143405. + );
  143406. +
  143407. +/* Destroy an gco3D object. */
  143408. +gceSTATUS
  143409. +gco3D_Destroy(
  143410. + IN gco3D Engine
  143411. + );
  143412. +
  143413. +/* Set 3D API type. */
  143414. +gceSTATUS
  143415. +gco3D_SetAPI(
  143416. + IN gco3D Engine,
  143417. + IN gceAPI ApiType
  143418. + );
  143419. +
  143420. +/* Set render target. */
  143421. +gceSTATUS
  143422. +gco3D_SetTarget(
  143423. + IN gco3D Engine,
  143424. + IN gcoSURF Surface
  143425. + );
  143426. +
  143427. +/* Unset render target. */
  143428. +gceSTATUS
  143429. +gco3D_UnsetTarget(
  143430. + IN gco3D Engine,
  143431. + IN gcoSURF Surface
  143432. + );
  143433. +
  143434. +/* Set depth buffer. */
  143435. +gceSTATUS
  143436. +gco3D_SetDepth(
  143437. + IN gco3D Engine,
  143438. + IN gcoSURF Surface
  143439. + );
  143440. +
  143441. +/* Unset depth buffer. */
  143442. +gceSTATUS
  143443. +gco3D_UnsetDepth(
  143444. + IN gco3D Engine,
  143445. + IN gcoSURF Surface
  143446. + );
  143447. +
  143448. +/* Set viewport. */
  143449. +gceSTATUS
  143450. +gco3D_SetViewport(
  143451. + IN gco3D Engine,
  143452. + IN gctINT32 Left,
  143453. + IN gctINT32 Top,
  143454. + IN gctINT32 Right,
  143455. + IN gctINT32 Bottom
  143456. + );
  143457. +
  143458. +/* Set scissors. */
  143459. +gceSTATUS
  143460. +gco3D_SetScissors(
  143461. + IN gco3D Engine,
  143462. + IN gctINT32 Left,
  143463. + IN gctINT32 Top,
  143464. + IN gctINT32 Right,
  143465. + IN gctINT32 Bottom
  143466. + );
  143467. +
  143468. +/* Set clear color. */
  143469. +gceSTATUS
  143470. +gco3D_SetClearColor(
  143471. + IN gco3D Engine,
  143472. + IN gctUINT8 Red,
  143473. + IN gctUINT8 Green,
  143474. + IN gctUINT8 Blue,
  143475. + IN gctUINT8 Alpha
  143476. + );
  143477. +
  143478. +/* Set fixed point clear color. */
  143479. +gceSTATUS
  143480. +gco3D_SetClearColorX(
  143481. + IN gco3D Engine,
  143482. + IN gctFIXED_POINT Red,
  143483. + IN gctFIXED_POINT Green,
  143484. + IN gctFIXED_POINT Blue,
  143485. + IN gctFIXED_POINT Alpha
  143486. + );
  143487. +
  143488. +/* Set floating point clear color. */
  143489. +gceSTATUS
  143490. +gco3D_SetClearColorF(
  143491. + IN gco3D Engine,
  143492. + IN gctFLOAT Red,
  143493. + IN gctFLOAT Green,
  143494. + IN gctFLOAT Blue,
  143495. + IN gctFLOAT Alpha
  143496. + );
  143497. +
  143498. +/* Set fixed point clear depth. */
  143499. +gceSTATUS
  143500. +gco3D_SetClearDepthX(
  143501. + IN gco3D Engine,
  143502. + IN gctFIXED_POINT Depth
  143503. + );
  143504. +
  143505. +/* Set floating point clear depth. */
  143506. +gceSTATUS
  143507. +gco3D_SetClearDepthF(
  143508. + IN gco3D Engine,
  143509. + IN gctFLOAT Depth
  143510. + );
  143511. +
  143512. +/* Set clear stencil. */
  143513. +gceSTATUS
  143514. +gco3D_SetClearStencil(
  143515. + IN gco3D Engine,
  143516. + IN gctUINT32 Stencil
  143517. + );
  143518. +
  143519. +/* Clear a Rect sub-surface. */
  143520. +gceSTATUS
  143521. +gco3D_ClearRect(
  143522. + IN gco3D Engine,
  143523. + IN gctUINT32 Address,
  143524. + IN gctPOINTER Memory,
  143525. + IN gctUINT32 Stride,
  143526. + IN gceSURF_FORMAT Format,
  143527. + IN gctINT32 Left,
  143528. + IN gctINT32 Top,
  143529. + IN gctINT32 Right,
  143530. + IN gctINT32 Bottom,
  143531. + IN gctUINT32 Width,
  143532. + IN gctUINT32 Height,
  143533. + IN gctUINT32 Flags
  143534. + );
  143535. +
  143536. +/* Clear surface. */
  143537. +gceSTATUS
  143538. +gco3D_Clear(
  143539. + IN gco3D Engine,
  143540. + IN gctUINT32 Address,
  143541. + IN gctUINT32 Stride,
  143542. + IN gceSURF_FORMAT Format,
  143543. + IN gctUINT32 Width,
  143544. + IN gctUINT32 Height,
  143545. + IN gctUINT32 Flags
  143546. + );
  143547. +
  143548. +
  143549. +/* Clear tile status. */
  143550. +gceSTATUS
  143551. +gco3D_ClearTileStatus(
  143552. + IN gco3D Engine,
  143553. + IN gcsSURF_INFO_PTR Surface,
  143554. + IN gctUINT32 TileStatusAddress,
  143555. + IN gctUINT32 Flags
  143556. + );
  143557. +
  143558. +/* Set shading mode. */
  143559. +gceSTATUS
  143560. +gco3D_SetShading(
  143561. + IN gco3D Engine,
  143562. + IN gceSHADING Shading
  143563. + );
  143564. +
  143565. +/* Set blending mode. */
  143566. +gceSTATUS
  143567. +gco3D_EnableBlending(
  143568. + IN gco3D Engine,
  143569. + IN gctBOOL Enable
  143570. + );
  143571. +
  143572. +/* Set blending function. */
  143573. +gceSTATUS
  143574. +gco3D_SetBlendFunction(
  143575. + IN gco3D Engine,
  143576. + IN gceBLEND_UNIT Unit,
  143577. + IN gceBLEND_FUNCTION FunctionRGB,
  143578. + IN gceBLEND_FUNCTION FunctionAlpha
  143579. + );
  143580. +
  143581. +/* Set blending mode. */
  143582. +gceSTATUS
  143583. +gco3D_SetBlendMode(
  143584. + IN gco3D Engine,
  143585. + IN gceBLEND_MODE ModeRGB,
  143586. + IN gceBLEND_MODE ModeAlpha
  143587. + );
  143588. +
  143589. +/* Set blending color. */
  143590. +gceSTATUS
  143591. +gco3D_SetBlendColor(
  143592. + IN gco3D Engine,
  143593. + IN gctUINT Red,
  143594. + IN gctUINT Green,
  143595. + IN gctUINT Blue,
  143596. + IN gctUINT Alpha
  143597. + );
  143598. +
  143599. +/* Set fixed point blending color. */
  143600. +gceSTATUS
  143601. +gco3D_SetBlendColorX(
  143602. + IN gco3D Engine,
  143603. + IN gctFIXED_POINT Red,
  143604. + IN gctFIXED_POINT Green,
  143605. + IN gctFIXED_POINT Blue,
  143606. + IN gctFIXED_POINT Alpha
  143607. + );
  143608. +
  143609. +/* Set floating point blending color. */
  143610. +gceSTATUS
  143611. +gco3D_SetBlendColorF(
  143612. + IN gco3D Engine,
  143613. + IN gctFLOAT Red,
  143614. + IN gctFLOAT Green,
  143615. + IN gctFLOAT Blue,
  143616. + IN gctFLOAT Alpha
  143617. + );
  143618. +
  143619. +/* Set culling mode. */
  143620. +gceSTATUS
  143621. +gco3D_SetCulling(
  143622. + IN gco3D Engine,
  143623. + IN gceCULL Mode
  143624. + );
  143625. +
  143626. +/* Enable point size */
  143627. +gceSTATUS
  143628. +gco3D_SetPointSizeEnable(
  143629. + IN gco3D Engine,
  143630. + IN gctBOOL Enable
  143631. + );
  143632. +
  143633. +/* Set point sprite */
  143634. +gceSTATUS
  143635. +gco3D_SetPointSprite(
  143636. + IN gco3D Engine,
  143637. + IN gctBOOL Enable
  143638. + );
  143639. +
  143640. +/* Set fill mode. */
  143641. +gceSTATUS
  143642. +gco3D_SetFill(
  143643. + IN gco3D Engine,
  143644. + IN gceFILL Mode
  143645. + );
  143646. +
  143647. +/* Set depth compare mode. */
  143648. +gceSTATUS
  143649. +gco3D_SetDepthCompare(
  143650. + IN gco3D Engine,
  143651. + IN gceCOMPARE Compare
  143652. + );
  143653. +
  143654. +/* Enable depth writing. */
  143655. +gceSTATUS
  143656. +gco3D_EnableDepthWrite(
  143657. + IN gco3D Engine,
  143658. + IN gctBOOL Enable
  143659. + );
  143660. +
  143661. +/* Set depth mode. */
  143662. +gceSTATUS
  143663. +gco3D_SetDepthMode(
  143664. + IN gco3D Engine,
  143665. + IN gceDEPTH_MODE Mode
  143666. + );
  143667. +
  143668. +/* Set depth range. */
  143669. +gceSTATUS
  143670. +gco3D_SetDepthRangeX(
  143671. + IN gco3D Engine,
  143672. + IN gceDEPTH_MODE Mode,
  143673. + IN gctFIXED_POINT Near,
  143674. + IN gctFIXED_POINT Far
  143675. + );
  143676. +
  143677. +/* Set depth range. */
  143678. +gceSTATUS
  143679. +gco3D_SetDepthRangeF(
  143680. + IN gco3D Engine,
  143681. + IN gceDEPTH_MODE Mode,
  143682. + IN gctFLOAT Near,
  143683. + IN gctFLOAT Far
  143684. + );
  143685. +
  143686. +/* Set last pixel enable */
  143687. +gceSTATUS
  143688. +gco3D_SetLastPixelEnable(
  143689. + IN gco3D Engine,
  143690. + IN gctBOOL Enable
  143691. + );
  143692. +
  143693. +/* Set depth Bias and Scale */
  143694. +gceSTATUS
  143695. +gco3D_SetDepthScaleBiasX(
  143696. + IN gco3D Engine,
  143697. + IN gctFIXED_POINT DepthScale,
  143698. + IN gctFIXED_POINT DepthBias
  143699. + );
  143700. +
  143701. +gceSTATUS
  143702. +gco3D_SetDepthScaleBiasF(
  143703. + IN gco3D Engine,
  143704. + IN gctFLOAT DepthScale,
  143705. + IN gctFLOAT DepthBias
  143706. + );
  143707. +
  143708. +/* Set depth near and far clipping plane. */
  143709. +gceSTATUS
  143710. +gco3D_SetDepthPlaneF(
  143711. + IN gco3D Engine,
  143712. + IN gctFLOAT Near,
  143713. + IN gctFLOAT Far
  143714. + );
  143715. +
  143716. +/* Enable or disable dithering. */
  143717. +gceSTATUS
  143718. +gco3D_EnableDither(
  143719. + IN gco3D Engine,
  143720. + IN gctBOOL Enable
  143721. + );
  143722. +
  143723. +/* Set color write enable bits. */
  143724. +gceSTATUS
  143725. +gco3D_SetColorWrite(
  143726. + IN gco3D Engine,
  143727. + IN gctUINT8 Enable
  143728. + );
  143729. +
  143730. +/* Enable or disable early depth. */
  143731. +gceSTATUS
  143732. +gco3D_SetEarlyDepth(
  143733. + IN gco3D Engine,
  143734. + IN gctBOOL Enable
  143735. + );
  143736. +
  143737. +/* Enable or disable all early depth operations. */
  143738. +gceSTATUS
  143739. +gco3D_SetAllEarlyDepthModes(
  143740. + IN gco3D Engine,
  143741. + IN gctBOOL Disable
  143742. + );
  143743. +
  143744. +/* Switch dynamic early mode */
  143745. +gceSTATUS
  143746. +gco3D_SwitchDynamicEarlyDepthMode(
  143747. + IN gco3D Engine
  143748. + );
  143749. +
  143750. +/* Set dynamic early mode */
  143751. +gceSTATUS
  143752. +gco3D_DisableDynamicEarlyDepthMode(
  143753. + IN gco3D Engine,
  143754. + IN gctBOOL Disable
  143755. + );
  143756. +
  143757. +/* Enable or disable depth-only mode. */
  143758. +gceSTATUS
  143759. +gco3D_SetDepthOnly(
  143760. + IN gco3D Engine,
  143761. + IN gctBOOL Enable
  143762. + );
  143763. +
  143764. +typedef struct _gcsSTENCIL_INFO * gcsSTENCIL_INFO_PTR;
  143765. +typedef struct _gcsSTENCIL_INFO
  143766. +{
  143767. + gceSTENCIL_MODE mode;
  143768. +
  143769. + gctUINT8 maskFront;
  143770. + gctUINT8 maskBack;
  143771. + gctUINT8 writeMaskFront;
  143772. + gctUINT8 writeMaskBack;
  143773. +
  143774. + gctUINT8 referenceFront;
  143775. +
  143776. + gceCOMPARE compareFront;
  143777. + gceSTENCIL_OPERATION passFront;
  143778. + gceSTENCIL_OPERATION failFront;
  143779. + gceSTENCIL_OPERATION depthFailFront;
  143780. +
  143781. + gctUINT8 referenceBack;
  143782. + gceCOMPARE compareBack;
  143783. + gceSTENCIL_OPERATION passBack;
  143784. + gceSTENCIL_OPERATION failBack;
  143785. + gceSTENCIL_OPERATION depthFailBack;
  143786. +}
  143787. +gcsSTENCIL_INFO;
  143788. +
  143789. +/* Set stencil mode. */
  143790. +gceSTATUS
  143791. +gco3D_SetStencilMode(
  143792. + IN gco3D Engine,
  143793. + IN gceSTENCIL_MODE Mode
  143794. + );
  143795. +
  143796. +/* Set stencil mask. */
  143797. +gceSTATUS
  143798. +gco3D_SetStencilMask(
  143799. + IN gco3D Engine,
  143800. + IN gctUINT8 Mask
  143801. + );
  143802. +
  143803. +/* Set stencil back mask. */
  143804. +gceSTATUS
  143805. +gco3D_SetStencilMaskBack(
  143806. + IN gco3D Engine,
  143807. + IN gctUINT8 Mask
  143808. + );
  143809. +
  143810. +/* Set stencil write mask. */
  143811. +gceSTATUS
  143812. +gco3D_SetStencilWriteMask(
  143813. + IN gco3D Engine,
  143814. + IN gctUINT8 Mask
  143815. + );
  143816. +
  143817. +/* Set stencil back write mask. */
  143818. +gceSTATUS
  143819. +gco3D_SetStencilWriteMaskBack(
  143820. + IN gco3D Engine,
  143821. + IN gctUINT8 Mask
  143822. + );
  143823. +
  143824. +/* Set stencil reference. */
  143825. +gceSTATUS
  143826. +gco3D_SetStencilReference(
  143827. + IN gco3D Engine,
  143828. + IN gctUINT8 Reference,
  143829. + IN gctBOOL Front
  143830. + );
  143831. +
  143832. +/* Set stencil compare. */
  143833. +gceSTATUS
  143834. +gco3D_SetStencilCompare(
  143835. + IN gco3D Engine,
  143836. + IN gceSTENCIL_WHERE Where,
  143837. + IN gceCOMPARE Compare
  143838. + );
  143839. +
  143840. +/* Set stencil operation on pass. */
  143841. +gceSTATUS
  143842. +gco3D_SetStencilPass(
  143843. + IN gco3D Engine,
  143844. + IN gceSTENCIL_WHERE Where,
  143845. + IN gceSTENCIL_OPERATION Operation
  143846. + );
  143847. +
  143848. +/* Set stencil operation on fail. */
  143849. +gceSTATUS
  143850. +gco3D_SetStencilFail(
  143851. + IN gco3D Engine,
  143852. + IN gceSTENCIL_WHERE Where,
  143853. + IN gceSTENCIL_OPERATION Operation
  143854. + );
  143855. +
  143856. +/* Set stencil operation on depth fail. */
  143857. +gceSTATUS
  143858. +gco3D_SetStencilDepthFail(
  143859. + IN gco3D Engine,
  143860. + IN gceSTENCIL_WHERE Where,
  143861. + IN gceSTENCIL_OPERATION Operation
  143862. + );
  143863. +
  143864. +/* Set all stencil states in one blow. */
  143865. +gceSTATUS
  143866. +gco3D_SetStencilAll(
  143867. + IN gco3D Engine,
  143868. + IN gcsSTENCIL_INFO_PTR Info
  143869. + );
  143870. +
  143871. +typedef struct _gcsALPHA_INFO * gcsALPHA_INFO_PTR;
  143872. +typedef struct _gcsALPHA_INFO
  143873. +{
  143874. + /* Alpha test states. */
  143875. + gctBOOL test;
  143876. + gceCOMPARE compare;
  143877. + gctUINT8 reference;
  143878. + gctFLOAT floatReference;
  143879. +
  143880. + /* Alpha blending states. */
  143881. + gctBOOL blend;
  143882. +
  143883. + gceBLEND_FUNCTION srcFuncColor;
  143884. + gceBLEND_FUNCTION srcFuncAlpha;
  143885. + gceBLEND_FUNCTION trgFuncColor;
  143886. + gceBLEND_FUNCTION trgFuncAlpha;
  143887. +
  143888. + gceBLEND_MODE modeColor;
  143889. + gceBLEND_MODE modeAlpha;
  143890. +
  143891. + gctUINT32 color;
  143892. +}
  143893. +gcsALPHA_INFO;
  143894. +
  143895. +/* Enable or disable alpha test. */
  143896. +gceSTATUS
  143897. +gco3D_SetAlphaTest(
  143898. + IN gco3D Engine,
  143899. + IN gctBOOL Enable
  143900. + );
  143901. +
  143902. +/* Set alpha test compare. */
  143903. +gceSTATUS
  143904. +gco3D_SetAlphaCompare(
  143905. + IN gco3D Engine,
  143906. + IN gceCOMPARE Compare
  143907. + );
  143908. +
  143909. +/* Set alpha test reference in unsigned integer. */
  143910. +gceSTATUS
  143911. +gco3D_SetAlphaReference(
  143912. + IN gco3D Engine,
  143913. + IN gctUINT8 Reference,
  143914. + IN gctFLOAT FloatReference
  143915. + );
  143916. +
  143917. +/* Set alpha test reference in fixed point. */
  143918. +gceSTATUS
  143919. +gco3D_SetAlphaReferenceX(
  143920. + IN gco3D Engine,
  143921. + IN gctFIXED_POINT Reference
  143922. + );
  143923. +
  143924. +/* Set alpha test reference in floating point. */
  143925. +gceSTATUS
  143926. +gco3D_SetAlphaReferenceF(
  143927. + IN gco3D Engine,
  143928. + IN gctFLOAT Reference
  143929. + );
  143930. +
  143931. +/* Enable/Disable anti-alias line. */
  143932. +gceSTATUS
  143933. +gco3D_SetAntiAliasLine(
  143934. + IN gco3D Engine,
  143935. + IN gctBOOL Enable
  143936. + );
  143937. +
  143938. +/* Set texture slot for anti-alias line. */
  143939. +gceSTATUS
  143940. +gco3D_SetAALineTexSlot(
  143941. + IN gco3D Engine,
  143942. + IN gctUINT TexSlot
  143943. + );
  143944. +
  143945. +/* Set anti-alias line width scale. */
  143946. +gceSTATUS
  143947. +gco3D_SetAALineWidth(
  143948. + IN gco3D Engine,
  143949. + IN gctFLOAT Width
  143950. + );
  143951. +
  143952. +/* Draw a number of primitives. */
  143953. +gceSTATUS
  143954. +gco3D_DrawPrimitives(
  143955. + IN gco3D Engine,
  143956. + IN gcePRIMITIVE Type,
  143957. + IN gctINT StartVertex,
  143958. + IN gctSIZE_T PrimitiveCount
  143959. + );
  143960. +
  143961. +gceSTATUS
  143962. +gco3D_DrawPrimitivesCount(
  143963. + IN gco3D Engine,
  143964. + IN gcePRIMITIVE Type,
  143965. + IN gctINT* StartVertex,
  143966. + IN gctSIZE_T* VertexCount,
  143967. + IN gctSIZE_T PrimitiveCount
  143968. + );
  143969. +
  143970. +
  143971. +/* Draw a number of primitives using offsets. */
  143972. +gceSTATUS
  143973. +gco3D_DrawPrimitivesOffset(
  143974. + IN gco3D Engine,
  143975. + IN gcePRIMITIVE Type,
  143976. + IN gctINT32 StartOffset,
  143977. + IN gctSIZE_T PrimitiveCount
  143978. + );
  143979. +
  143980. +/* Draw a number of indexed primitives. */
  143981. +gceSTATUS
  143982. +gco3D_DrawIndexedPrimitives(
  143983. + IN gco3D Engine,
  143984. + IN gcePRIMITIVE Type,
  143985. + IN gctINT BaseVertex,
  143986. + IN gctINT StartIndex,
  143987. + IN gctSIZE_T PrimitiveCount
  143988. + );
  143989. +
  143990. +/* Draw a number of indexed primitives using offsets. */
  143991. +gceSTATUS
  143992. +gco3D_DrawIndexedPrimitivesOffset(
  143993. + IN gco3D Engine,
  143994. + IN gcePRIMITIVE Type,
  143995. + IN gctINT32 BaseOffset,
  143996. + IN gctINT32 StartOffset,
  143997. + IN gctSIZE_T PrimitiveCount
  143998. + );
  143999. +
  144000. +/* Enable or disable anti-aliasing. */
  144001. +gceSTATUS
  144002. +gco3D_SetAntiAlias(
  144003. + IN gco3D Engine,
  144004. + IN gctBOOL Enable
  144005. + );
  144006. +
  144007. +/* Write data into the command buffer. */
  144008. +gceSTATUS
  144009. +gco3D_WriteBuffer(
  144010. + IN gco3D Engine,
  144011. + IN gctCONST_POINTER Data,
  144012. + IN gctSIZE_T Bytes,
  144013. + IN gctBOOL Aligned
  144014. + );
  144015. +
  144016. +/* Send sempahore and stall until sempahore is signalled. */
  144017. +gceSTATUS
  144018. +gco3D_Semaphore(
  144019. + IN gco3D Engine,
  144020. + IN gceWHERE From,
  144021. + IN gceWHERE To,
  144022. + IN gceHOW How);
  144023. +
  144024. +/* Set the subpixels center. */
  144025. +gceSTATUS
  144026. +gco3D_SetCentroids(
  144027. + IN gco3D Engine,
  144028. + IN gctUINT32 Index,
  144029. + IN gctPOINTER Centroids
  144030. + );
  144031. +
  144032. +gceSTATUS
  144033. +gco3D_SetLogicOp(
  144034. + IN gco3D Engine,
  144035. + IN gctUINT8 Rop
  144036. + );
  144037. +
  144038. +/* OCL thread walker information. */
  144039. +typedef struct _gcsTHREAD_WALKER_INFO * gcsTHREAD_WALKER_INFO_PTR;
  144040. +typedef struct _gcsTHREAD_WALKER_INFO
  144041. +{
  144042. + gctUINT32 dimensions;
  144043. + gctUINT32 traverseOrder;
  144044. + gctUINT32 enableSwathX;
  144045. + gctUINT32 enableSwathY;
  144046. + gctUINT32 enableSwathZ;
  144047. + gctUINT32 swathSizeX;
  144048. + gctUINT32 swathSizeY;
  144049. + gctUINT32 swathSizeZ;
  144050. + gctUINT32 valueOrder;
  144051. +
  144052. + gctUINT32 globalSizeX;
  144053. + gctUINT32 globalOffsetX;
  144054. + gctUINT32 globalSizeY;
  144055. + gctUINT32 globalOffsetY;
  144056. + gctUINT32 globalSizeZ;
  144057. + gctUINT32 globalOffsetZ;
  144058. +
  144059. + gctUINT32 workGroupSizeX;
  144060. + gctUINT32 workGroupCountX;
  144061. + gctUINT32 workGroupSizeY;
  144062. + gctUINT32 workGroupCountY;
  144063. + gctUINT32 workGroupSizeZ;
  144064. + gctUINT32 workGroupCountZ;
  144065. +
  144066. + gctUINT32 threadAllocation;
  144067. +}
  144068. +gcsTHREAD_WALKER_INFO;
  144069. +
  144070. +/* Start OCL thread walker. */
  144071. +gceSTATUS
  144072. +gco3D_InvokeThreadWalker(
  144073. + IN gco3D Engine,
  144074. + IN gcsTHREAD_WALKER_INFO_PTR Info
  144075. + );
  144076. +
  144077. +/* Set w clip and w plane limit value. */
  144078. +gceSTATUS
  144079. +gco3D_SetWClipEnable(
  144080. + IN gco3D Engine,
  144081. + IN gctBOOL Enable
  144082. + );
  144083. +
  144084. +gceSTATUS
  144085. +gco3D_GetWClipEnable(
  144086. + IN gco3D Engine,
  144087. + OUT gctBOOL * Enable
  144088. + );
  144089. +
  144090. +gceSTATUS
  144091. +gco3D_SetWPlaneLimitF(
  144092. + IN gco3D Engine,
  144093. + IN gctFLOAT Value
  144094. + );
  144095. +
  144096. +gceSTATUS
  144097. +gco3D_SetWPlaneLimitX(
  144098. + IN gco3D Engine,
  144099. + IN gctFIXED_POINT Value
  144100. + );
  144101. +
  144102. +
  144103. +gceSTATUS
  144104. +gco3D_SetWPlaneLimit(
  144105. + IN gco3D Engine,
  144106. + IN gctFLOAT Value
  144107. + );
  144108. +
  144109. +/*----------------------------------------------------------------------------*/
  144110. +/*-------------------------- gco3D Fragment Processor ------------------------*/
  144111. +
  144112. +/* Set the fragment processor configuration. */
  144113. +gceSTATUS
  144114. +gco3D_SetFragmentConfiguration(
  144115. + IN gco3D Engine,
  144116. + IN gctBOOL ColorFromStream,
  144117. + IN gctBOOL EnableFog,
  144118. + IN gctBOOL EnableSmoothPoint,
  144119. + IN gctUINT32 ClipPlanes
  144120. + );
  144121. +
  144122. +/* Enable/disable texture stage operation. */
  144123. +gceSTATUS
  144124. +gco3D_EnableTextureStage(
  144125. + IN gco3D Engine,
  144126. + IN gctINT Stage,
  144127. + IN gctBOOL Enable
  144128. + );
  144129. +
  144130. +/* Program the channel enable masks for the color texture function. */
  144131. +gceSTATUS
  144132. +gco3D_SetTextureColorMask(
  144133. + IN gco3D Engine,
  144134. + IN gctINT Stage,
  144135. + IN gctBOOL ColorEnabled,
  144136. + IN gctBOOL AlphaEnabled
  144137. + );
  144138. +
  144139. +/* Program the channel enable masks for the alpha texture function. */
  144140. +gceSTATUS
  144141. +gco3D_SetTextureAlphaMask(
  144142. + IN gco3D Engine,
  144143. + IN gctINT Stage,
  144144. + IN gctBOOL ColorEnabled,
  144145. + IN gctBOOL AlphaEnabled
  144146. + );
  144147. +
  144148. +/* Program the constant fragment color. */
  144149. +gceSTATUS
  144150. +gco3D_SetFragmentColorX(
  144151. + IN gco3D Engine,
  144152. + IN gctFIXED_POINT Red,
  144153. + IN gctFIXED_POINT Green,
  144154. + IN gctFIXED_POINT Blue,
  144155. + IN gctFIXED_POINT Alpha
  144156. + );
  144157. +
  144158. +gceSTATUS
  144159. +gco3D_SetFragmentColorF(
  144160. + IN gco3D Engine,
  144161. + IN gctFLOAT Red,
  144162. + IN gctFLOAT Green,
  144163. + IN gctFLOAT Blue,
  144164. + IN gctFLOAT Alpha
  144165. + );
  144166. +
  144167. +/* Program the constant fog color. */
  144168. +gceSTATUS
  144169. +gco3D_SetFogColorX(
  144170. + IN gco3D Engine,
  144171. + IN gctFIXED_POINT Red,
  144172. + IN gctFIXED_POINT Green,
  144173. + IN gctFIXED_POINT Blue,
  144174. + IN gctFIXED_POINT Alpha
  144175. + );
  144176. +
  144177. +gceSTATUS
  144178. +gco3D_SetFogColorF(
  144179. + IN gco3D Engine,
  144180. + IN gctFLOAT Red,
  144181. + IN gctFLOAT Green,
  144182. + IN gctFLOAT Blue,
  144183. + IN gctFLOAT Alpha
  144184. + );
  144185. +
  144186. +/* Program the constant texture color. */
  144187. +gceSTATUS
  144188. +gco3D_SetTetxureColorX(
  144189. + IN gco3D Engine,
  144190. + IN gctINT Stage,
  144191. + IN gctFIXED_POINT Red,
  144192. + IN gctFIXED_POINT Green,
  144193. + IN gctFIXED_POINT Blue,
  144194. + IN gctFIXED_POINT Alpha
  144195. + );
  144196. +
  144197. +gceSTATUS
  144198. +gco3D_SetTetxureColorF(
  144199. + IN gco3D Engine,
  144200. + IN gctINT Stage,
  144201. + IN gctFLOAT Red,
  144202. + IN gctFLOAT Green,
  144203. + IN gctFLOAT Blue,
  144204. + IN gctFLOAT Alpha
  144205. + );
  144206. +
  144207. +/* Configure color texture function. */
  144208. +gceSTATUS
  144209. +gco3D_SetColorTextureFunction(
  144210. + IN gco3D Engine,
  144211. + IN gctINT Stage,
  144212. + IN gceTEXTURE_FUNCTION Function,
  144213. + IN gceTEXTURE_SOURCE Source0,
  144214. + IN gceTEXTURE_CHANNEL Channel0,
  144215. + IN gceTEXTURE_SOURCE Source1,
  144216. + IN gceTEXTURE_CHANNEL Channel1,
  144217. + IN gceTEXTURE_SOURCE Source2,
  144218. + IN gceTEXTURE_CHANNEL Channel2,
  144219. + IN gctINT Scale
  144220. + );
  144221. +
  144222. +/* Configure alpha texture function. */
  144223. +gceSTATUS
  144224. +gco3D_SetAlphaTextureFunction(
  144225. + IN gco3D Engine,
  144226. + IN gctINT Stage,
  144227. + IN gceTEXTURE_FUNCTION Function,
  144228. + IN gceTEXTURE_SOURCE Source0,
  144229. + IN gceTEXTURE_CHANNEL Channel0,
  144230. + IN gceTEXTURE_SOURCE Source1,
  144231. + IN gceTEXTURE_CHANNEL Channel1,
  144232. + IN gceTEXTURE_SOURCE Source2,
  144233. + IN gceTEXTURE_CHANNEL Channel2,
  144234. + IN gctINT Scale
  144235. + );
  144236. +
  144237. +/* Invoke OCL thread walker. */
  144238. +gceSTATUS
  144239. +gcoHARDWARE_InvokeThreadWalker(
  144240. + IN gcsTHREAD_WALKER_INFO_PTR Info
  144241. + );
  144242. +
  144243. +/******************************************************************************\
  144244. +******************************* gcoTEXTURE Object *******************************
  144245. +\******************************************************************************/
  144246. +
  144247. +/* Cube faces. */
  144248. +typedef enum _gceTEXTURE_FACE
  144249. +{
  144250. + gcvFACE_NONE,
  144251. + gcvFACE_POSITIVE_X,
  144252. + gcvFACE_NEGATIVE_X,
  144253. + gcvFACE_POSITIVE_Y,
  144254. + gcvFACE_NEGATIVE_Y,
  144255. + gcvFACE_POSITIVE_Z,
  144256. + gcvFACE_NEGATIVE_Z,
  144257. +}
  144258. +gceTEXTURE_FACE;
  144259. +
  144260. +#if gcdFORCE_MIPMAP
  144261. +typedef enum
  144262. +{
  144263. + gcvForceMipDisabled = 0,
  144264. + gcvForceMipEnable = 1,
  144265. + gcvForceMipGenerated = 2,
  144266. + gcvForceMipNever = 3,
  144267. +}gceFORCE_MIPMAP;
  144268. +#endif
  144269. +
  144270. +typedef struct _gcsTEXTURE
  144271. +{
  144272. + /* Addressing modes. */
  144273. + gceTEXTURE_ADDRESSING s;
  144274. + gceTEXTURE_ADDRESSING t;
  144275. + gceTEXTURE_ADDRESSING r;
  144276. +
  144277. + /* Border color. */
  144278. + gctUINT8 border[4];
  144279. +
  144280. + /* Filters. */
  144281. + gceTEXTURE_FILTER minFilter;
  144282. + gceTEXTURE_FILTER magFilter;
  144283. + gceTEXTURE_FILTER mipFilter;
  144284. + gctUINT anisoFilter;
  144285. + gctBOOL forceTopLevel;
  144286. + gctBOOL autoMipmap;
  144287. +#if gcdFORCE_MIPMAP
  144288. + gceFORCE_MIPMAP forceMipmap;
  144289. +#endif
  144290. + /* Level of detail. */
  144291. + gctFIXED_POINT lodBias;
  144292. + gctFIXED_POINT lodMin;
  144293. + gctFIXED_POINT lodMax;
  144294. +}
  144295. +gcsTEXTURE, * gcsTEXTURE_PTR;
  144296. +
  144297. +/* Construct a new gcoTEXTURE object. */
  144298. +gceSTATUS
  144299. +gcoTEXTURE_Construct(
  144300. + IN gcoHAL Hal,
  144301. + OUT gcoTEXTURE * Texture
  144302. + );
  144303. +
  144304. +/* Construct a new sized gcoTEXTURE object. */
  144305. +gceSTATUS
  144306. +gcoTEXTURE_ConstructSized(
  144307. + IN gcoHAL Hal,
  144308. + IN gceSURF_FORMAT Format,
  144309. + IN gctUINT Width,
  144310. + IN gctUINT Height,
  144311. + IN gctUINT Depth,
  144312. + IN gctUINT Faces,
  144313. + IN gctUINT MipMapCount,
  144314. + IN gcePOOL Pool,
  144315. + OUT gcoTEXTURE * Texture
  144316. + );
  144317. +
  144318. +/* Destroy an gcoTEXTURE object. */
  144319. +gceSTATUS
  144320. +gcoTEXTURE_Destroy(
  144321. + IN gcoTEXTURE Texture
  144322. + );
  144323. +#if gcdFORCE_MIPMAP
  144324. +gceSTATUS
  144325. +gcoTEXTURE_DestroyForceMipmap(
  144326. + IN gcoTEXTURE Texture
  144327. + );
  144328. +
  144329. +gceSTATUS
  144330. +gcoTEXTURE_GetMipLevels(
  144331. + IN gcoTEXTURE Texture,
  144332. + OUT gctINT * levels
  144333. + );
  144334. +#endif
  144335. +/* Replace a mipmap in gcoTEXTURE object. */
  144336. +gceSTATUS
  144337. +gcoTEXTURE_ReplaceMipMap(
  144338. + IN gcoTEXTURE Texture,
  144339. + IN gctUINT Level,
  144340. + IN gctUINT Width,
  144341. + IN gctUINT Height,
  144342. + IN gctINT imageFormat,
  144343. + IN gceSURF_FORMAT Format,
  144344. + IN gctUINT Depth,
  144345. + IN gctUINT Faces,
  144346. + IN gcePOOL Pool
  144347. + );
  144348. +
  144349. +/* Upload data to an gcoTEXTURE object. */
  144350. +gceSTATUS
  144351. +gcoTEXTURE_Upload(
  144352. + IN gcoTEXTURE Texture,
  144353. + IN gceTEXTURE_FACE Face,
  144354. + IN gctUINT Width,
  144355. + IN gctUINT Height,
  144356. + IN gctUINT Slice,
  144357. + IN gctCONST_POINTER Memory,
  144358. + IN gctINT Stride,
  144359. + IN gceSURF_FORMAT Format
  144360. + );
  144361. +
  144362. +/* Upload data to an gcoTEXTURE object. */
  144363. +gceSTATUS
  144364. +gcoTEXTURE_UploadSub(
  144365. + IN gcoTEXTURE Texture,
  144366. + IN gctUINT MipMap,
  144367. + IN gceTEXTURE_FACE Face,
  144368. + IN gctUINT X,
  144369. + IN gctUINT Y,
  144370. + IN gctUINT Width,
  144371. + IN gctUINT Height,
  144372. + IN gctUINT Slice,
  144373. + IN gctCONST_POINTER Memory,
  144374. + IN gctINT Stride,
  144375. + IN gceSURF_FORMAT Format
  144376. + );
  144377. +
  144378. +/* Upload YUV data to an gcoTEXTURE object. */
  144379. +gceSTATUS
  144380. +gcoTEXTURE_UploadYUV(
  144381. + IN gcoTEXTURE Texture,
  144382. + IN gceTEXTURE_FACE Face,
  144383. + IN gctUINT Width,
  144384. + IN gctUINT Height,
  144385. + IN gctUINT Slice,
  144386. + IN gctPOINTER Memory[3],
  144387. + IN gctINT Stride[3],
  144388. + IN gceSURF_FORMAT Format
  144389. + );
  144390. +
  144391. +/* Upload compressed data to an gcoTEXTURE object. */
  144392. +gceSTATUS
  144393. +gcoTEXTURE_UploadCompressed(
  144394. + IN gcoTEXTURE Texture,
  144395. + IN gceTEXTURE_FACE Face,
  144396. + IN gctUINT Width,
  144397. + IN gctUINT Height,
  144398. + IN gctUINT Slice,
  144399. + IN gctCONST_POINTER Memory,
  144400. + IN gctSIZE_T Bytes
  144401. + );
  144402. +
  144403. +/* Upload compressed sub data to an gcoTEXTURE object. */
  144404. +gceSTATUS
  144405. +gcoTEXTURE_UploadCompressedSub(
  144406. + IN gcoTEXTURE Texture,
  144407. + IN gctUINT MipMap,
  144408. + IN gceTEXTURE_FACE Face,
  144409. + IN gctUINT XOffset,
  144410. + IN gctUINT YOffset,
  144411. + IN gctUINT Width,
  144412. + IN gctUINT Height,
  144413. + IN gctUINT Slice,
  144414. + IN gctCONST_POINTER Memory,
  144415. + IN gctSIZE_T Size
  144416. + );
  144417. +
  144418. +/* GetImageFormat of texture. */
  144419. +gceSTATUS
  144420. +gcoTEXTURE_GetImageFormat(
  144421. + IN gcoTEXTURE Texture,
  144422. + IN gctUINT MipMap,
  144423. + OUT gctINT * ImageFormat
  144424. + );
  144425. +
  144426. +/* Get gcoSURF object for a mipmap level. */
  144427. +gceSTATUS
  144428. +gcoTEXTURE_GetMipMap(
  144429. + IN gcoTEXTURE Texture,
  144430. + IN gctUINT MipMap,
  144431. + OUT gcoSURF * Surface
  144432. + );
  144433. +
  144434. +/* Get gcoSURF object for a mipmap level and face offset. */
  144435. +gceSTATUS
  144436. +gcoTEXTURE_GetMipMapFace(
  144437. + IN gcoTEXTURE Texture,
  144438. + IN gctUINT MipMap,
  144439. + IN gceTEXTURE_FACE Face,
  144440. + OUT gcoSURF * Surface,
  144441. + OUT gctUINT32_PTR Offset
  144442. + );
  144443. +
  144444. +gceSTATUS
  144445. +gcoTEXTURE_AddMipMap(
  144446. + IN gcoTEXTURE Texture,
  144447. + IN gctINT Level,
  144448. + IN gctINT imageFormat,
  144449. + IN gceSURF_FORMAT Format,
  144450. + IN gctUINT Width,
  144451. + IN gctUINT Height,
  144452. + IN gctUINT Depth,
  144453. + IN gctUINT Faces,
  144454. + IN gcePOOL Pool,
  144455. + OUT gcoSURF * Surface
  144456. + );
  144457. +
  144458. +gceSTATUS
  144459. +gcoTEXTURE_AddMipMapFromClient(
  144460. + IN gcoTEXTURE Texture,
  144461. + IN gctINT Level,
  144462. + IN gcoSURF Surface
  144463. + );
  144464. +
  144465. +gceSTATUS
  144466. +gcoTEXTURE_AddMipMapFromSurface(
  144467. + IN gcoTEXTURE Texture,
  144468. + IN gctINT Level,
  144469. + IN gcoSURF Surface
  144470. + );
  144471. +
  144472. +gceSTATUS
  144473. +gcoTEXTURE_SetMaxLevel(
  144474. + IN gcoTEXTURE Texture,
  144475. + IN gctUINT Levels
  144476. + );
  144477. +
  144478. +gceSTATUS
  144479. +gcoTEXTURE_SetEndianHint(
  144480. + IN gcoTEXTURE Texture,
  144481. + IN gceENDIAN_HINT EndianHint
  144482. + );
  144483. +
  144484. +gceSTATUS
  144485. +gcoTEXTURE_Disable(
  144486. + IN gcoHAL Hal,
  144487. + IN gctINT Sampler
  144488. + );
  144489. +
  144490. +gceSTATUS
  144491. +gcoTEXTURE_Flush(
  144492. + IN gcoTEXTURE Texture
  144493. + );
  144494. +
  144495. +gceSTATUS
  144496. +gcoTEXTURE_QueryCaps(
  144497. + IN gcoHAL Hal,
  144498. + OUT gctUINT * MaxWidth,
  144499. + OUT gctUINT * MaxHeight,
  144500. + OUT gctUINT * MaxDepth,
  144501. + OUT gctBOOL * Cubic,
  144502. + OUT gctBOOL * NonPowerOfTwo,
  144503. + OUT gctUINT * VertexSamplers,
  144504. + OUT gctUINT * PixelSamplers
  144505. + );
  144506. +
  144507. +gceSTATUS
  144508. +gcoTEXTURE_GetTiling(
  144509. + IN gcoTEXTURE Texture,
  144510. + IN gctINT preferLevel,
  144511. + OUT gceTILING * Tiling
  144512. + );
  144513. +
  144514. +gceSTATUS
  144515. +gcoTEXTURE_GetClosestFormat(
  144516. + IN gcoHAL Hal,
  144517. + IN gceSURF_FORMAT InFormat,
  144518. + OUT gceSURF_FORMAT* OutFormat
  144519. + );
  144520. +
  144521. +gceSTATUS
  144522. +gcoTEXTURE_RenderIntoMipMap(
  144523. + IN gcoTEXTURE Texture,
  144524. + IN gctINT Level
  144525. + );
  144526. +
  144527. +gceSTATUS
  144528. +gcoTEXTURE_IsRenderable(
  144529. + IN gcoTEXTURE Texture,
  144530. + IN gctUINT Level
  144531. + );
  144532. +
  144533. +gceSTATUS
  144534. +gcoTEXTURE_IsRenderableEx(
  144535. + IN gcoTEXTURE Texture,
  144536. + IN gctUINT Level
  144537. + );
  144538. +
  144539. +gceSTATUS
  144540. +gcoTEXTURE_IsComplete(
  144541. + IN gcoTEXTURE Texture,
  144542. + IN gctINT MaxLevel
  144543. + );
  144544. +
  144545. +gceSTATUS
  144546. +gcoTEXTURE_BindTexture(
  144547. + IN gcoTEXTURE Texture,
  144548. + IN gctINT Target,
  144549. + IN gctINT Sampler,
  144550. + IN gcsTEXTURE_PTR Info
  144551. + );
  144552. +
  144553. +/******************************************************************************\
  144554. +******************************* gcoSTREAM Object ******************************
  144555. +\******************************************************************************/
  144556. +
  144557. +typedef enum _gceVERTEX_FORMAT
  144558. +{
  144559. + gcvVERTEX_BYTE,
  144560. + gcvVERTEX_UNSIGNED_BYTE,
  144561. + gcvVERTEX_SHORT,
  144562. + gcvVERTEX_UNSIGNED_SHORT,
  144563. + gcvVERTEX_INT,
  144564. + gcvVERTEX_UNSIGNED_INT,
  144565. + gcvVERTEX_FIXED,
  144566. + gcvVERTEX_HALF,
  144567. + gcvVERTEX_FLOAT,
  144568. + gcvVERTEX_UNSIGNED_INT_10_10_10_2,
  144569. + gcvVERTEX_INT_10_10_10_2,
  144570. +}
  144571. +gceVERTEX_FORMAT;
  144572. +
  144573. +gceSTATUS
  144574. +gcoSTREAM_Construct(
  144575. + IN gcoHAL Hal,
  144576. + OUT gcoSTREAM * Stream
  144577. + );
  144578. +
  144579. +gceSTATUS
  144580. +gcoSTREAM_Destroy(
  144581. + IN gcoSTREAM Stream
  144582. + );
  144583. +
  144584. +gceSTATUS
  144585. +gcoSTREAM_Upload(
  144586. + IN gcoSTREAM Stream,
  144587. + IN gctCONST_POINTER Buffer,
  144588. + IN gctUINT32 Offset,
  144589. + IN gctSIZE_T Bytes,
  144590. + IN gctBOOL Dynamic
  144591. + );
  144592. +
  144593. +gceSTATUS
  144594. +gcoSTREAM_SetStride(
  144595. + IN gcoSTREAM Stream,
  144596. + IN gctUINT32 Stride
  144597. + );
  144598. +
  144599. +gceSTATUS
  144600. +gcoSTREAM_Lock(
  144601. + IN gcoSTREAM Stream,
  144602. + OUT gctPOINTER * Logical,
  144603. + OUT gctUINT32 * Physical
  144604. + );
  144605. +
  144606. +gceSTATUS
  144607. +gcoSTREAM_Unlock(
  144608. + IN gcoSTREAM Stream
  144609. + );
  144610. +
  144611. +gceSTATUS
  144612. +gcoSTREAM_Reserve(
  144613. + IN gcoSTREAM Stream,
  144614. + IN gctSIZE_T Bytes
  144615. + );
  144616. +
  144617. +gceSTATUS
  144618. +gcoSTREAM_Flush(
  144619. + IN gcoSTREAM Stream
  144620. + );
  144621. +
  144622. +/* Dynamic buffer API. */
  144623. +gceSTATUS
  144624. +gcoSTREAM_SetDynamic(
  144625. + IN gcoSTREAM Stream,
  144626. + IN gctSIZE_T Bytes,
  144627. + IN gctUINT Buffers
  144628. + );
  144629. +
  144630. +typedef struct _gcsSTREAM_INFO
  144631. +{
  144632. + gctUINT index;
  144633. + gceVERTEX_FORMAT format;
  144634. + gctBOOL normalized;
  144635. + gctUINT components;
  144636. + gctSIZE_T size;
  144637. + gctCONST_POINTER data;
  144638. + gctUINT stride;
  144639. +}
  144640. +gcsSTREAM_INFO, * gcsSTREAM_INFO_PTR;
  144641. +
  144642. +gceSTATUS
  144643. +gcoSTREAM_UploadDynamic(
  144644. + IN gcoSTREAM Stream,
  144645. + IN gctUINT VertexCount,
  144646. + IN gctUINT InfoCount,
  144647. + IN gcsSTREAM_INFO_PTR Info,
  144648. + IN gcoVERTEX Vertex
  144649. + );
  144650. +
  144651. +gceSTATUS
  144652. +gcoSTREAM_CPUCacheOperation(
  144653. + IN gcoSTREAM Stream,
  144654. + IN gceCACHEOPERATION Operation
  144655. + );
  144656. +
  144657. +/******************************************************************************\
  144658. +******************************** gcoVERTEX Object ******************************
  144659. +\******************************************************************************/
  144660. +
  144661. +typedef struct _gcsVERTEX_ATTRIBUTES
  144662. +{
  144663. + gceVERTEX_FORMAT format;
  144664. + gctBOOL normalized;
  144665. + gctUINT32 components;
  144666. + gctSIZE_T size;
  144667. + gctUINT32 stream;
  144668. + gctUINT32 offset;
  144669. + gctUINT32 stride;
  144670. +}
  144671. +gcsVERTEX_ATTRIBUTES;
  144672. +
  144673. +gceSTATUS
  144674. +gcoVERTEX_Construct(
  144675. + IN gcoHAL Hal,
  144676. + OUT gcoVERTEX * Vertex
  144677. + );
  144678. +
  144679. +gceSTATUS
  144680. +gcoVERTEX_Destroy(
  144681. + IN gcoVERTEX Vertex
  144682. + );
  144683. +
  144684. +gceSTATUS
  144685. +gcoVERTEX_Reset(
  144686. + IN gcoVERTEX Vertex
  144687. + );
  144688. +
  144689. +gceSTATUS
  144690. +gcoVERTEX_EnableAttribute(
  144691. + IN gcoVERTEX Vertex,
  144692. + IN gctUINT32 Index,
  144693. + IN gceVERTEX_FORMAT Format,
  144694. + IN gctBOOL Normalized,
  144695. + IN gctUINT32 Components,
  144696. + IN gcoSTREAM Stream,
  144697. + IN gctUINT32 Offset,
  144698. + IN gctUINT32 Stride
  144699. + );
  144700. +
  144701. +gceSTATUS
  144702. +gcoVERTEX_DisableAttribute(
  144703. + IN gcoVERTEX Vertex,
  144704. + IN gctUINT32 Index
  144705. + );
  144706. +
  144707. +gceSTATUS
  144708. +gcoVERTEX_Bind(
  144709. + IN gcoVERTEX Vertex
  144710. + );
  144711. +
  144712. +/*******************************************************************************
  144713. +***** gcoVERTEXARRAY Object ***************************************************/
  144714. +
  144715. +typedef struct _gcsVERTEXARRAY
  144716. +{
  144717. + /* Enabled. */
  144718. + gctBOOL enable;
  144719. +
  144720. + /* Number of components. */
  144721. + gctINT size;
  144722. +
  144723. + /* Attribute format. */
  144724. + gceVERTEX_FORMAT format;
  144725. +
  144726. + /* Flag whether the attribute is normalized or not. */
  144727. + gctBOOL normalized;
  144728. +
  144729. + /* Stride of the component. */
  144730. + gctUINT stride;
  144731. +
  144732. + /* Pointer to the attribute data. */
  144733. + gctCONST_POINTER pointer;
  144734. +
  144735. + /* Stream object owning the attribute data. */
  144736. + gcoSTREAM stream;
  144737. +
  144738. + /* Generic values for attribute. */
  144739. + gctFLOAT genericValue[4];
  144740. +
  144741. + /* Generic size for attribute. */
  144742. + gctINT genericSize;
  144743. +
  144744. + /* Vertex shader linkage. */
  144745. + gctUINT linkage;
  144746. +
  144747. +#if gcdUSE_WCLIP_PATCH
  144748. + gctBOOL isPosition;
  144749. +#endif
  144750. +}
  144751. +gcsVERTEXARRAY,
  144752. +* gcsVERTEXARRAY_PTR;
  144753. +
  144754. +gceSTATUS
  144755. +gcoVERTEXARRAY_Construct(
  144756. + IN gcoHAL Hal,
  144757. + OUT gcoVERTEXARRAY * Vertex
  144758. + );
  144759. +
  144760. +gceSTATUS
  144761. +gcoVERTEXARRAY_Destroy(
  144762. + IN gcoVERTEXARRAY Vertex
  144763. + );
  144764. +
  144765. +gceSTATUS
  144766. +gcoVERTEXARRAY_Bind(
  144767. + IN gcoVERTEXARRAY Vertex,
  144768. + IN gctUINT32 EnableBits,
  144769. + IN gcsVERTEXARRAY_PTR VertexArray,
  144770. + IN gctUINT First,
  144771. + IN gctSIZE_T Count,
  144772. + IN gceINDEX_TYPE IndexType,
  144773. + IN gcoINDEX IndexObject,
  144774. + IN gctPOINTER IndexMemory,
  144775. + IN OUT gcePRIMITIVE * PrimitiveType,
  144776. +#if gcdUSE_WCLIP_PATCH
  144777. + IN OUT gctUINT * PrimitiveCount,
  144778. + IN OUT gctFLOAT * wLimitRms,
  144779. + IN OUT gctBOOL * wLimitDirty
  144780. +#else
  144781. + IN OUT gctUINT * PrimitiveCount
  144782. +#endif
  144783. + );
  144784. +
  144785. +gctUINT
  144786. +gcoVERTEXARRAY_GetMaxStream(
  144787. + IN gcoVERTEXARRAY Vertex
  144788. +);
  144789. +
  144790. +gceSTATUS
  144791. +gcoVERTEXARRAY_SetMaxStream(
  144792. + IN gcoVERTEXARRAY Vertex,
  144793. + gctUINT maxStreams
  144794. +);
  144795. +/*******************************************************************************
  144796. +***** Composition *************************************************************/
  144797. +
  144798. +typedef enum _gceCOMPOSITION
  144799. +{
  144800. + gcvCOMPOSE_CLEAR = 1,
  144801. + gcvCOMPOSE_BLUR,
  144802. + gcvCOMPOSE_DIM,
  144803. + gcvCOMPOSE_LAYER
  144804. +}
  144805. +gceCOMPOSITION;
  144806. +
  144807. +typedef struct _gcsCOMPOSITION * gcsCOMPOSITION_PTR;
  144808. +typedef struct _gcsCOMPOSITION
  144809. +{
  144810. + /* Structure size. */
  144811. + gctUINT structSize;
  144812. +
  144813. + /* Composition operation. */
  144814. + gceCOMPOSITION operation;
  144815. +
  144816. + /* Layer to be composed. */
  144817. + gcoSURF layer;
  144818. +
  144819. + /* Source and target coordinates. */
  144820. + gcsRECT srcRect;
  144821. + gcsRECT trgRect;
  144822. +
  144823. + /* Target rectangle */
  144824. + gcsPOINT v0;
  144825. + gcsPOINT v1;
  144826. + gcsPOINT v2;
  144827. +
  144828. + /* Blending parameters. */
  144829. + gctBOOL enableBlending;
  144830. + gctBOOL premultiplied;
  144831. + gctUINT8 alphaValue;
  144832. +
  144833. + /* Clear color. */
  144834. + gctFLOAT r;
  144835. + gctFLOAT g;
  144836. + gctFLOAT b;
  144837. + gctFLOAT a;
  144838. +}
  144839. +gcsCOMPOSITION;
  144840. +
  144841. +gceSTATUS
  144842. +gco3D_ProbeComposition(
  144843. + gctBOOL ResetIfEmpty
  144844. + );
  144845. +
  144846. +gceSTATUS
  144847. +gco3D_CompositionBegin(
  144848. + void
  144849. + );
  144850. +
  144851. +gceSTATUS
  144852. +gco3D_ComposeLayer(
  144853. + IN gcsCOMPOSITION_PTR Layer
  144854. + );
  144855. +
  144856. +gceSTATUS
  144857. +gco3D_CompositionSignals(
  144858. + IN gctHANDLE Process,
  144859. + IN gctSIGNAL Signal1,
  144860. + IN gctSIGNAL Signal2
  144861. + );
  144862. +
  144863. +gceSTATUS
  144864. +gco3D_CompositionEnd(
  144865. + IN gcoSURF Target,
  144866. + IN gctBOOL Synchronous
  144867. + );
  144868. +
  144869. +/* Frame Database */
  144870. +gceSTATUS
  144871. +gcoHAL_AddFrameDB(
  144872. + void
  144873. + );
  144874. +
  144875. +gceSTATUS
  144876. +gcoHAL_DumpFrameDB(
  144877. + gctCONST_STRING Filename OPTIONAL
  144878. + );
  144879. +
  144880. +gceSTATUS
  144881. +gcoHAL_GetSharedInfo(
  144882. + IN gctUINT32 Pid,
  144883. + IN gctUINT32 DataId,
  144884. + IN gctSIZE_T Bytes,
  144885. + OUT gctPOINTER Data
  144886. + );
  144887. +
  144888. +gceSTATUS
  144889. +gcoHAL_SetSharedInfo(
  144890. + IN gctUINT32 DataId,
  144891. + IN gctPOINTER Data,
  144892. + IN gctSIZE_T Bytes
  144893. + );
  144894. +
  144895. +#if VIVANTE_PROFILER_CONTEXT
  144896. +gceSTATUS
  144897. +gcoHARDWARE_GetContext(
  144898. + IN gcoHARDWARE Hardware,
  144899. + OUT gctUINT32 * Context
  144900. + );
  144901. +#endif
  144902. +
  144903. +#ifdef __cplusplus
  144904. +}
  144905. +#endif
  144906. +
  144907. +#endif /* VIVANTE_NO_3D */
  144908. +#endif /* __gc_hal_engine_h_ */
  144909. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h
  144910. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h 1970-01-01 01:00:00.000000000 +0100
  144911. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h 2014-08-20 19:23:53.566845873 +0200
  144912. @@ -0,0 +1,904 @@
  144913. +/****************************************************************************
  144914. +*
  144915. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  144916. +*
  144917. +* This program is free software; you can redistribute it and/or modify
  144918. +* it under the terms of the GNU General Public License as published by
  144919. +* the Free Software Foundation; either version 2 of the license, or
  144920. +* (at your option) any later version.
  144921. +*
  144922. +* This program is distributed in the hope that it will be useful,
  144923. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  144924. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  144925. +* GNU General Public License for more details.
  144926. +*
  144927. +* You should have received a copy of the GNU General Public License
  144928. +* along with this program; if not write to the Free Software
  144929. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  144930. +*
  144931. +*****************************************************************************/
  144932. +
  144933. +
  144934. +#ifndef __gc_hal_engine_vg_h_
  144935. +#define __gc_hal_engine_vg_h_
  144936. +
  144937. +#ifdef __cplusplus
  144938. +extern "C" {
  144939. +#endif
  144940. +
  144941. +#include "gc_hal_types.h"
  144942. +
  144943. +/******************************************************************************\
  144944. +******************************** VG Enumerations *******************************
  144945. +\******************************************************************************/
  144946. +
  144947. +/**
  144948. +** @ingroup gcoVG
  144949. +**
  144950. +** @brief Tiling mode for painting and imagig.
  144951. +**
  144952. +** This enumeration defines the tiling modes supported by the HAL. This is
  144953. +** in fact a one-to-one mapping of the OpenVG 1.1 tile modes.
  144954. +*/
  144955. +typedef enum _gceTILE_MODE
  144956. +{
  144957. + gcvTILE_FILL,
  144958. + gcvTILE_PAD,
  144959. + gcvTILE_REPEAT,
  144960. + gcvTILE_REFLECT
  144961. +}
  144962. +gceTILE_MODE;
  144963. +
  144964. +/******************************************************************************/
  144965. +/** @ingroup gcoVG
  144966. +**
  144967. +** @brief The different paint modes.
  144968. +**
  144969. +** This enumeration lists the available paint modes.
  144970. +*/
  144971. +typedef enum _gcePAINT_TYPE
  144972. +{
  144973. + /** Solid color. */
  144974. + gcvPAINT_MODE_SOLID,
  144975. +
  144976. + /** Linear gradient. */
  144977. + gcvPAINT_MODE_LINEAR,
  144978. +
  144979. + /** Radial gradient. */
  144980. + gcvPAINT_MODE_RADIAL,
  144981. +
  144982. + /** Pattern. */
  144983. + gcvPAINT_MODE_PATTERN,
  144984. +
  144985. + /** Mode count. */
  144986. + gcvPAINT_MODE_COUNT
  144987. +}
  144988. +gcePAINT_TYPE;
  144989. +
  144990. +/**
  144991. +** @ingroup gcoVG
  144992. +**
  144993. +** @brief Types of path data supported by HAL.
  144994. +**
  144995. +** This enumeration defines the types of path data supported by the HAL.
  144996. +** This is in fact a one-to-one mapping of the OpenVG 1.1 path types.
  144997. +*/
  144998. +typedef enum _gcePATHTYPE
  144999. +{
  145000. + gcePATHTYPE_UNKNOWN = -1,
  145001. + gcePATHTYPE_INT8,
  145002. + gcePATHTYPE_INT16,
  145003. + gcePATHTYPE_INT32,
  145004. + gcePATHTYPE_FLOAT
  145005. +}
  145006. +gcePATHTYPE;
  145007. +
  145008. +/**
  145009. +** @ingroup gcoVG
  145010. +**
  145011. +** @brief Supported path segment commands.
  145012. +**
  145013. +** This enumeration defines the path segment commands supported by the HAL.
  145014. +*/
  145015. +typedef enum _gceVGCMD
  145016. +{
  145017. + gcvVGCMD_END, /* 0: GCCMD_TS_OPCODE_END */
  145018. + gcvVGCMD_CLOSE, /* 1: GCCMD_TS_OPCODE_CLOSE */
  145019. + gcvVGCMD_MOVE, /* 2: GCCMD_TS_OPCODE_MOVE */
  145020. + gcvVGCMD_MOVE_REL, /* 3: GCCMD_TS_OPCODE_MOVE_REL */
  145021. + gcvVGCMD_LINE, /* 4: GCCMD_TS_OPCODE_LINE */
  145022. + gcvVGCMD_LINE_REL, /* 5: GCCMD_TS_OPCODE_LINE_REL */
  145023. + gcvVGCMD_QUAD, /* 6: GCCMD_TS_OPCODE_QUADRATIC */
  145024. + gcvVGCMD_QUAD_REL, /* 7: GCCMD_TS_OPCODE_QUADRATIC_REL */
  145025. + gcvVGCMD_CUBIC, /* 8: GCCMD_TS_OPCODE_CUBIC */
  145026. + gcvVGCMD_CUBIC_REL, /* 9: GCCMD_TS_OPCODE_CUBIC_REL */
  145027. + gcvVGCMD_BREAK, /* 10: GCCMD_TS_OPCODE_BREAK */
  145028. + gcvVGCMD_HLINE, /* 11: ******* R E S E R V E D *******/
  145029. + gcvVGCMD_HLINE_REL, /* 12: ******* R E S E R V E D *******/
  145030. + gcvVGCMD_VLINE, /* 13: ******* R E S E R V E D *******/
  145031. + gcvVGCMD_VLINE_REL, /* 14: ******* R E S E R V E D *******/
  145032. + gcvVGCMD_SQUAD, /* 15: ******* R E S E R V E D *******/
  145033. + gcvVGCMD_SQUAD_REL, /* 16: ******* R E S E R V E D *******/
  145034. + gcvVGCMD_SCUBIC, /* 17: ******* R E S E R V E D *******/
  145035. + gcvVGCMD_SCUBIC_REL, /* 18: ******* R E S E R V E D *******/
  145036. + gcvVGCMD_SCCWARC, /* 19: ******* R E S E R V E D *******/
  145037. + gcvVGCMD_SCCWARC_REL, /* 20: ******* R E S E R V E D *******/
  145038. + gcvVGCMD_SCWARC, /* 21: ******* R E S E R V E D *******/
  145039. + gcvVGCMD_SCWARC_REL, /* 22: ******* R E S E R V E D *******/
  145040. + gcvVGCMD_LCCWARC, /* 23: ******* R E S E R V E D *******/
  145041. + gcvVGCMD_LCCWARC_REL, /* 24: ******* R E S E R V E D *******/
  145042. + gcvVGCMD_LCWARC, /* 25: ******* R E S E R V E D *******/
  145043. + gcvVGCMD_LCWARC_REL, /* 26: ******* R E S E R V E D *******/
  145044. +
  145045. + /* The width of the command recognized by the hardware on bits. */
  145046. + gcvVGCMD_WIDTH = 5,
  145047. +
  145048. + /* Hardware command mask. */
  145049. + gcvVGCMD_MASK = (1 << gcvVGCMD_WIDTH) - 1,
  145050. +
  145051. + /* Command modifiers. */
  145052. + gcvVGCMD_H_MOD = 1 << gcvVGCMD_WIDTH, /* = 32 */
  145053. + gcvVGCMD_V_MOD = 2 << gcvVGCMD_WIDTH, /* = 64 */
  145054. + gcvVGCMD_S_MOD = 3 << gcvVGCMD_WIDTH, /* = 96 */
  145055. + gcvVGCMD_ARC_MOD = 4 << gcvVGCMD_WIDTH, /* = 128 */
  145056. +
  145057. + /* Emulated LINE commands. */
  145058. + gcvVGCMD_HLINE_EMUL = gcvVGCMD_H_MOD | gcvVGCMD_LINE, /* = 36 */
  145059. + gcvVGCMD_HLINE_EMUL_REL = gcvVGCMD_H_MOD | gcvVGCMD_LINE_REL, /* = 37 */
  145060. + gcvVGCMD_VLINE_EMUL = gcvVGCMD_V_MOD | gcvVGCMD_LINE, /* = 68 */
  145061. + gcvVGCMD_VLINE_EMUL_REL = gcvVGCMD_V_MOD | gcvVGCMD_LINE_REL, /* = 69 */
  145062. +
  145063. + /* Emulated SMOOTH commands. */
  145064. + gcvVGCMD_SQUAD_EMUL = gcvVGCMD_S_MOD | gcvVGCMD_QUAD, /* = 102 */
  145065. + gcvVGCMD_SQUAD_EMUL_REL = gcvVGCMD_S_MOD | gcvVGCMD_QUAD_REL, /* = 103 */
  145066. + gcvVGCMD_SCUBIC_EMUL = gcvVGCMD_S_MOD | gcvVGCMD_CUBIC, /* = 104 */
  145067. + gcvVGCMD_SCUBIC_EMUL_REL = gcvVGCMD_S_MOD | gcvVGCMD_CUBIC_REL, /* = 105 */
  145068. +
  145069. + /* Emulation ARC commands. */
  145070. + gcvVGCMD_ARC_LINE = gcvVGCMD_ARC_MOD | gcvVGCMD_LINE, /* = 132 */
  145071. + gcvVGCMD_ARC_LINE_REL = gcvVGCMD_ARC_MOD | gcvVGCMD_LINE_REL, /* = 133 */
  145072. + gcvVGCMD_ARC_QUAD = gcvVGCMD_ARC_MOD | gcvVGCMD_QUAD, /* = 134 */
  145073. + gcvVGCMD_ARC_QUAD_REL = gcvVGCMD_ARC_MOD | gcvVGCMD_QUAD_REL /* = 135 */
  145074. +}
  145075. +gceVGCMD;
  145076. +typedef enum _gceVGCMD * gceVGCMD_PTR;
  145077. +
  145078. +/**
  145079. +** @ingroup gcoVG
  145080. +**
  145081. +** @brief Blending modes supported by the HAL.
  145082. +**
  145083. +** This enumeration defines the blending modes supported by the HAL. This is
  145084. +** in fact a one-to-one mapping of the OpenVG 1.1 blending modes.
  145085. +*/
  145086. +typedef enum _gceVG_BLEND
  145087. +{
  145088. + gcvVG_BLEND_SRC,
  145089. + gcvVG_BLEND_SRC_OVER,
  145090. + gcvVG_BLEND_DST_OVER,
  145091. + gcvVG_BLEND_SRC_IN,
  145092. + gcvVG_BLEND_DST_IN,
  145093. + gcvVG_BLEND_MULTIPLY,
  145094. + gcvVG_BLEND_SCREEN,
  145095. + gcvVG_BLEND_DARKEN,
  145096. + gcvVG_BLEND_LIGHTEN,
  145097. + gcvVG_BLEND_ADDITIVE,
  145098. + gcvVG_BLEND_SUBTRACT,
  145099. + gcvVG_BLEND_FILTER
  145100. +}
  145101. +gceVG_BLEND;
  145102. +
  145103. +/**
  145104. +** @ingroup gcoVG
  145105. +**
  145106. +** @brief Image modes supported by the HAL.
  145107. +**
  145108. +** This enumeration defines the image modes supported by the HAL. This is
  145109. +** in fact a one-to-one mapping of the OpenVG 1.1 image modes with the addition
  145110. +** of NO IMAGE.
  145111. +*/
  145112. +typedef enum _gceVG_IMAGE
  145113. +{
  145114. + gcvVG_IMAGE_NONE,
  145115. + gcvVG_IMAGE_NORMAL,
  145116. + gcvVG_IMAGE_MULTIPLY,
  145117. + gcvVG_IMAGE_STENCIL,
  145118. + gcvVG_IMAGE_FILTER
  145119. +}
  145120. +gceVG_IMAGE;
  145121. +
  145122. +/**
  145123. +** @ingroup gcoVG
  145124. +**
  145125. +** @brief Filter mode patterns and imaging.
  145126. +**
  145127. +** This enumeration defines the filter modes supported by the HAL.
  145128. +*/
  145129. +typedef enum _gceIMAGE_FILTER
  145130. +{
  145131. + gcvFILTER_POINT,
  145132. + gcvFILTER_LINEAR,
  145133. + gcvFILTER_BI_LINEAR
  145134. +}
  145135. +gceIMAGE_FILTER;
  145136. +
  145137. +/**
  145138. +** @ingroup gcoVG
  145139. +**
  145140. +** @brief Primitive modes supported by the HAL.
  145141. +**
  145142. +** This enumeration defines the primitive modes supported by the HAL.
  145143. +*/
  145144. +typedef enum _gceVG_PRIMITIVE
  145145. +{
  145146. + gcvVG_SCANLINE,
  145147. + gcvVG_RECTANGLE,
  145148. + gcvVG_TESSELLATED,
  145149. + gcvVG_TESSELLATED_TILED
  145150. +}
  145151. +gceVG_PRIMITIVE;
  145152. +
  145153. +/**
  145154. +** @ingroup gcoVG
  145155. +**
  145156. +** @brief Rendering quality modes supported by the HAL.
  145157. +**
  145158. +** This enumeration defines the rendering quality modes supported by the HAL.
  145159. +*/
  145160. +typedef enum _gceRENDER_QUALITY
  145161. +{
  145162. + gcvVG_NONANTIALIASED,
  145163. + gcvVG_2X2_MSAA,
  145164. + gcvVG_2X4_MSAA,
  145165. + gcvVG_4X4_MSAA
  145166. +}
  145167. +gceRENDER_QUALITY;
  145168. +
  145169. +/**
  145170. +** @ingroup gcoVG
  145171. +**
  145172. +** @brief Fill rules supported by the HAL.
  145173. +**
  145174. +** This enumeration defines the fill rules supported by the HAL.
  145175. +*/
  145176. +typedef enum _gceFILL_RULE
  145177. +{
  145178. + gcvVG_EVEN_ODD,
  145179. + gcvVG_NON_ZERO
  145180. +}
  145181. +gceFILL_RULE;
  145182. +
  145183. +/**
  145184. +** @ingroup gcoVG
  145185. +**
  145186. +** @brief Cap styles supported by the HAL.
  145187. +**
  145188. +** This enumeration defines the cap styles supported by the HAL.
  145189. +*/
  145190. +typedef enum _gceCAP_STYLE
  145191. +{
  145192. + gcvCAP_BUTT,
  145193. + gcvCAP_ROUND,
  145194. + gcvCAP_SQUARE
  145195. +}
  145196. +gceCAP_STYLE;
  145197. +
  145198. +/**
  145199. +** @ingroup gcoVG
  145200. +**
  145201. +** @brief Join styles supported by the HAL.
  145202. +**
  145203. +** This enumeration defines the join styles supported by the HAL.
  145204. +*/
  145205. +typedef enum _gceJOIN_STYLE
  145206. +{
  145207. + gcvJOIN_MITER,
  145208. + gcvJOIN_ROUND,
  145209. + gcvJOIN_BEVEL
  145210. +}
  145211. +gceJOIN_STYLE;
  145212. +
  145213. +/**
  145214. +** @ingroup gcoVG
  145215. +**
  145216. +** @brief Channel mask values.
  145217. +**
  145218. +** This enumeration defines the values for channel mask used in image
  145219. +** filtering.
  145220. +*/
  145221. +
  145222. +/* Base values for channel mask definitions. */
  145223. +#define gcvCHANNEL_X (0)
  145224. +#define gcvCHANNEL_R (1 << 0)
  145225. +#define gcvCHANNEL_G (1 << 1)
  145226. +#define gcvCHANNEL_B (1 << 2)
  145227. +#define gcvCHANNEL_A (1 << 3)
  145228. +
  145229. +typedef enum _gceCHANNEL
  145230. +{
  145231. + gcvCHANNEL_XXXX = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X),
  145232. + gcvCHANNEL_XXXA = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_A),
  145233. + gcvCHANNEL_XXBX = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_X),
  145234. + gcvCHANNEL_XXBA = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_A),
  145235. +
  145236. + gcvCHANNEL_XGXX = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_X),
  145237. + gcvCHANNEL_XGXA = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_A),
  145238. + gcvCHANNEL_XGBX = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_X),
  145239. + gcvCHANNEL_XGBA = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_A),
  145240. +
  145241. + gcvCHANNEL_RXXX = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X),
  145242. + gcvCHANNEL_RXXA = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_A),
  145243. + gcvCHANNEL_RXBX = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_X),
  145244. + gcvCHANNEL_RXBA = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_A),
  145245. +
  145246. + gcvCHANNEL_RGXX = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_X),
  145247. + gcvCHANNEL_RGXA = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_A),
  145248. + gcvCHANNEL_RGBX = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_X),
  145249. + gcvCHANNEL_RGBA = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_A),
  145250. +}
  145251. +gceCHANNEL;
  145252. +
  145253. +/******************************************************************************\
  145254. +******************************** VG Structures *******************************
  145255. +\******************************************************************************/
  145256. +
  145257. +/**
  145258. +** @ingroup gcoVG
  145259. +**
  145260. +** @brief Definition of the color ramp used by the gradient paints.
  145261. +**
  145262. +** The gcsCOLOR_RAMP structure defines the layout of one single color inside
  145263. +** a color ramp which is used by gradient paints.
  145264. +*/
  145265. +typedef struct _gcsCOLOR_RAMP
  145266. +{
  145267. + /** Value for the color stop. */
  145268. + gctFLOAT stop;
  145269. +
  145270. + /** Red color channel value for the color stop. */
  145271. + gctFLOAT red;
  145272. +
  145273. + /** Green color channel value for the color stop. */
  145274. + gctFLOAT green;
  145275. +
  145276. + /** Blue color channel value for the color stop. */
  145277. + gctFLOAT blue;
  145278. +
  145279. + /** Alpha color channel value for the color stop. */
  145280. + gctFLOAT alpha;
  145281. +}
  145282. +gcsCOLOR_RAMP, * gcsCOLOR_RAMP_PTR;
  145283. +
  145284. +/**
  145285. +** @ingroup gcoVG
  145286. +**
  145287. +** @brief Definition of the color ramp used by the gradient paints in fixed form.
  145288. +**
  145289. +** The gcsCOLOR_RAMP structure defines the layout of one single color inside
  145290. +** a color ramp which is used by gradient paints.
  145291. +*/
  145292. +typedef struct _gcsFIXED_COLOR_RAMP
  145293. +{
  145294. + /** Value for the color stop. */
  145295. + gctFIXED_POINT stop;
  145296. +
  145297. + /** Red color channel value for the color stop. */
  145298. + gctFIXED_POINT red;
  145299. +
  145300. + /** Green color channel value for the color stop. */
  145301. + gctFIXED_POINT green;
  145302. +
  145303. + /** Blue color channel value for the color stop. */
  145304. + gctFIXED_POINT blue;
  145305. +
  145306. + /** Alpha color channel value for the color stop. */
  145307. + gctFIXED_POINT alpha;
  145308. +}
  145309. +gcsFIXED_COLOR_RAMP, * gcsFIXED_COLOR_RAMP_PTR;
  145310. +
  145311. +
  145312. +/**
  145313. +** @ingroup gcoVG
  145314. +**
  145315. +** @brief Rectangle structure used by the gcoVG object.
  145316. +**
  145317. +** This structure defines the layout of a rectangle. Make sure width and
  145318. +** height are larger than 0.
  145319. +*/
  145320. +typedef struct _gcsVG_RECT * gcsVG_RECT_PTR;
  145321. +typedef struct _gcsVG_RECT
  145322. +{
  145323. + /** Left location of the rectangle. */
  145324. + gctINT x;
  145325. +
  145326. + /** Top location of the rectangle. */
  145327. + gctINT y;
  145328. +
  145329. + /** Width of the rectangle. */
  145330. + gctINT width;
  145331. +
  145332. + /** Height of the rectangle. */
  145333. + gctINT height;
  145334. +}
  145335. +gcsVG_RECT;
  145336. +
  145337. +/**
  145338. +** @ingroup gcoVG
  145339. +**
  145340. +** @brief Path command buffer attribute structure.
  145341. +**
  145342. +** The gcsPATH_BUFFER_INFO structure contains the specifics about
  145343. +** the layout of the path data command buffer.
  145344. +*/
  145345. +typedef struct _gcsPATH_BUFFER_INFO * gcsPATH_BUFFER_INFO_PTR;
  145346. +typedef struct _gcsPATH_BUFFER_INFO
  145347. +{
  145348. + gctUINT reservedForHead;
  145349. + gctUINT reservedForTail;
  145350. +}
  145351. +gcsPATH_BUFFER_INFO;
  145352. +
  145353. +/**
  145354. +** @ingroup gcoVG
  145355. +**
  145356. +** @brief Definition of the path data container structure.
  145357. +**
  145358. +** The gcsPATH structure defines the layout of the path data container.
  145359. +*/
  145360. +typedef struct _gcsPATH_DATA * gcsPATH_DATA_PTR;
  145361. +typedef struct _gcsPATH_DATA
  145362. +{
  145363. + /* Data container in command buffer format. */
  145364. + gcsCMDBUFFER data;
  145365. +
  145366. + /* Path data type. */
  145367. + gcePATHTYPE dataType;
  145368. +}
  145369. +gcsPATH_DATA;
  145370. +
  145371. +
  145372. +/******************************************************************************\
  145373. +********************************* gcoHAL Object ********************************
  145374. +\******************************************************************************/
  145375. +
  145376. +/* Query path data storage attributes. */
  145377. +gceSTATUS
  145378. +gcoHAL_QueryPathStorage(
  145379. + IN gcoHAL Hal,
  145380. + OUT gcsPATH_BUFFER_INFO_PTR Information
  145381. + );
  145382. +
  145383. +/* Associate a completion signal with the command buffer. */
  145384. +gceSTATUS
  145385. +gcoHAL_AssociateCompletion(
  145386. + IN gcoHAL Hal,
  145387. + IN gcsPATH_DATA_PTR PathData
  145388. + );
  145389. +
  145390. +/* Release the current command buffer completion signal. */
  145391. +gceSTATUS
  145392. +gcoHAL_DeassociateCompletion(
  145393. + IN gcoHAL Hal,
  145394. + IN gcsPATH_DATA_PTR PathData
  145395. + );
  145396. +
  145397. +/* Verify whether the command buffer is still in use. */
  145398. +gceSTATUS
  145399. +gcoHAL_CheckCompletion(
  145400. + IN gcoHAL Hal,
  145401. + IN gcsPATH_DATA_PTR PathData
  145402. + );
  145403. +
  145404. +/* Wait until the command buffer is no longer in use. */
  145405. +gceSTATUS
  145406. +gcoHAL_WaitCompletion(
  145407. + IN gcoHAL Hal,
  145408. + IN gcsPATH_DATA_PTR PathData
  145409. + );
  145410. +
  145411. +/* Flush the pixel cache. */
  145412. +gceSTATUS
  145413. +gcoHAL_Flush(
  145414. + IN gcoHAL Hal
  145415. + );
  145416. +
  145417. +/* Split a harwdare address into pool and offset. */
  145418. +gceSTATUS
  145419. +gcoHAL_SplitAddress(
  145420. + IN gcoHAL Hal,
  145421. + IN gctUINT32 Address,
  145422. + OUT gcePOOL * Pool,
  145423. + OUT gctUINT32 * Offset
  145424. + );
  145425. +
  145426. +/* Combine pool and offset into a harwdare address. */
  145427. +gceSTATUS
  145428. +gcoHAL_CombineAddress(
  145429. + IN gcoHAL Hal,
  145430. + IN gcePOOL Pool,
  145431. + IN gctUINT32 Offset,
  145432. + OUT gctUINT32 * Address
  145433. + );
  145434. +
  145435. +/* Schedule to free linear video memory allocated. */
  145436. +gceSTATUS
  145437. +gcoHAL_ScheduleVideoMemory(
  145438. + IN gcoHAL Hal,
  145439. + IN gctUINT64 Node
  145440. + );
  145441. +
  145442. +/* Free linear video memory allocated with gcoHAL_AllocateLinearVideoMemory. */
  145443. +gceSTATUS
  145444. +gcoHAL_FreeVideoMemory(
  145445. + IN gcoHAL Hal,
  145446. + IN gctUINT64 Node
  145447. + );
  145448. +
  145449. +/* Query command buffer attributes. */
  145450. +gceSTATUS
  145451. +gcoHAL_QueryCommandBuffer(
  145452. + IN gcoHAL Hal,
  145453. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  145454. + );
  145455. +/* Allocate and lock linear video memory. */
  145456. +gceSTATUS
  145457. +gcoHAL_AllocateLinearVideoMemory(
  145458. + IN gcoHAL Hal,
  145459. + IN gctUINT Size,
  145460. + IN gctUINT Alignment,
  145461. + IN gcePOOL Pool,
  145462. + OUT gctUINT64 * Node,
  145463. + OUT gctUINT32 * Address,
  145464. + OUT gctPOINTER * Memory
  145465. + );
  145466. +
  145467. +/* Align the specified size accordingly to the hardware requirements. */
  145468. +gceSTATUS
  145469. +gcoHAL_GetAlignedSurfaceSize(
  145470. + IN gcoHAL Hal,
  145471. + IN gceSURF_TYPE Type,
  145472. + IN OUT gctUINT32_PTR Width,
  145473. + IN OUT gctUINT32_PTR Height
  145474. + );
  145475. +
  145476. +gceSTATUS
  145477. +gcoHAL_ReserveTask(
  145478. + IN gcoHAL Hal,
  145479. + IN gceBLOCK Block,
  145480. + IN gctUINT TaskCount,
  145481. + IN gctSIZE_T Bytes,
  145482. + OUT gctPOINTER * Memory
  145483. + );
  145484. +/******************************************************************************\
  145485. +********************************** gcoVG Object ********************************
  145486. +\******************************************************************************/
  145487. +
  145488. +/** @defgroup gcoVG gcoVG
  145489. +**
  145490. +** The gcoVG object abstracts the VG hardware pipe.
  145491. +*/
  145492. +
  145493. +gctBOOL
  145494. +gcoVG_IsMaskSupported(
  145495. + IN gceSURF_FORMAT Format
  145496. + );
  145497. +
  145498. +gctBOOL
  145499. +gcoVG_IsTargetSupported(
  145500. + IN gceSURF_FORMAT Format
  145501. + );
  145502. +
  145503. +gctBOOL
  145504. +gcoVG_IsImageSupported(
  145505. + IN gceSURF_FORMAT Format
  145506. + );
  145507. +
  145508. +gctUINT8 gcoVG_PackColorComponent(
  145509. + gctFLOAT Value
  145510. + );
  145511. +
  145512. +gceSTATUS
  145513. +gcoVG_Construct(
  145514. + IN gcoHAL Hal,
  145515. + OUT gcoVG * Vg
  145516. + );
  145517. +
  145518. +gceSTATUS
  145519. +gcoVG_Destroy(
  145520. + IN gcoVG Vg
  145521. + );
  145522. +
  145523. +gceSTATUS
  145524. +gcoVG_SetTarget(
  145525. + IN gcoVG Vg,
  145526. + IN gcoSURF Target
  145527. + );
  145528. +
  145529. +gceSTATUS
  145530. +gcoVG_UnsetTarget(
  145531. + IN gcoVG Vg,
  145532. + IN gcoSURF Surface
  145533. + );
  145534. +
  145535. +gceSTATUS
  145536. +gcoVG_SetUserToSurface(
  145537. + IN gcoVG Vg,
  145538. + IN gctFLOAT UserToSurface[9]
  145539. + );
  145540. +
  145541. +gceSTATUS
  145542. +gcoVG_SetSurfaceToImage(
  145543. + IN gcoVG Vg,
  145544. + IN gctFLOAT SurfaceToImage[9]
  145545. + );
  145546. +
  145547. +gceSTATUS
  145548. +gcoVG_EnableMask(
  145549. + IN gcoVG Vg,
  145550. + IN gctBOOL Enable
  145551. + );
  145552. +
  145553. +gceSTATUS
  145554. +gcoVG_SetMask(
  145555. + IN gcoVG Vg,
  145556. + IN gcoSURF Mask
  145557. + );
  145558. +
  145559. +gceSTATUS
  145560. +gcoVG_UnsetMask(
  145561. + IN gcoVG Vg,
  145562. + IN gcoSURF Surface
  145563. + );
  145564. +
  145565. +gceSTATUS
  145566. +gcoVG_FlushMask(
  145567. + IN gcoVG Vg
  145568. + );
  145569. +
  145570. +gceSTATUS
  145571. +gcoVG_EnableScissor(
  145572. + IN gcoVG Vg,
  145573. + IN gctBOOL Enable
  145574. + );
  145575. +
  145576. +gceSTATUS
  145577. +gcoVG_SetScissor(
  145578. + IN gcoVG Vg,
  145579. + IN gctSIZE_T RectangleCount,
  145580. + IN gcsVG_RECT_PTR Rectangles
  145581. + );
  145582. +
  145583. +gceSTATUS
  145584. +gcoVG_EnableColorTransform(
  145585. + IN gcoVG Vg,
  145586. + IN gctBOOL Enable
  145587. + );
  145588. +
  145589. +gceSTATUS
  145590. +gcoVG_SetColorTransform(
  145591. + IN gcoVG Vg,
  145592. + IN gctFLOAT ColorTransform[8]
  145593. + );
  145594. +
  145595. +gceSTATUS
  145596. +gcoVG_SetTileFillColor(
  145597. + IN gcoVG Vg,
  145598. + IN gctFLOAT Red,
  145599. + IN gctFLOAT Green,
  145600. + IN gctFLOAT Blue,
  145601. + IN gctFLOAT Alpha
  145602. + );
  145603. +
  145604. +gceSTATUS
  145605. +gcoVG_SetSolidPaint(
  145606. + IN gcoVG Vg,
  145607. + IN gctUINT8 Red,
  145608. + IN gctUINT8 Green,
  145609. + IN gctUINT8 Blue,
  145610. + IN gctUINT8 Alpha
  145611. + );
  145612. +
  145613. +gceSTATUS
  145614. +gcoVG_SetLinearPaint(
  145615. + IN gcoVG Vg,
  145616. + IN gctFLOAT Constant,
  145617. + IN gctFLOAT StepX,
  145618. + IN gctFLOAT StepY
  145619. + );
  145620. +
  145621. +gceSTATUS
  145622. +gcoVG_SetRadialPaint(
  145623. + IN gcoVG Vg,
  145624. + IN gctFLOAT LinConstant,
  145625. + IN gctFLOAT LinStepX,
  145626. + IN gctFLOAT LinStepY,
  145627. + IN gctFLOAT RadConstant,
  145628. + IN gctFLOAT RadStepX,
  145629. + IN gctFLOAT RadStepY,
  145630. + IN gctFLOAT RadStepXX,
  145631. + IN gctFLOAT RadStepYY,
  145632. + IN gctFLOAT RadStepXY
  145633. + );
  145634. +
  145635. +gceSTATUS
  145636. +gcoVG_SetPatternPaint(
  145637. + IN gcoVG Vg,
  145638. + IN gctFLOAT UConstant,
  145639. + IN gctFLOAT UStepX,
  145640. + IN gctFLOAT UStepY,
  145641. + IN gctFLOAT VConstant,
  145642. + IN gctFLOAT VStepX,
  145643. + IN gctFLOAT VStepY,
  145644. + IN gctBOOL Linear
  145645. + );
  145646. +
  145647. +gceSTATUS
  145648. +gcoVG_SetColorRamp(
  145649. + IN gcoVG Vg,
  145650. + IN gcoSURF ColorRamp,
  145651. + IN gceTILE_MODE ColorRampSpreadMode
  145652. + );
  145653. +
  145654. +gceSTATUS
  145655. +gcoVG_SetPattern(
  145656. + IN gcoVG Vg,
  145657. + IN gcoSURF Pattern,
  145658. + IN gceTILE_MODE TileMode,
  145659. + IN gceIMAGE_FILTER Filter
  145660. + );
  145661. +
  145662. +gceSTATUS
  145663. +gcoVG_SetImageMode(
  145664. + IN gcoVG Vg,
  145665. + IN gceVG_IMAGE Mode
  145666. + );
  145667. +
  145668. +gceSTATUS
  145669. +gcoVG_SetBlendMode(
  145670. + IN gcoVG Vg,
  145671. + IN gceVG_BLEND Mode
  145672. + );
  145673. +
  145674. +gceSTATUS
  145675. +gcoVG_SetRenderingQuality(
  145676. + IN gcoVG Vg,
  145677. + IN gceRENDER_QUALITY Quality
  145678. + );
  145679. +
  145680. +gceSTATUS
  145681. +gcoVG_SetFillRule(
  145682. + IN gcoVG Vg,
  145683. + IN gceFILL_RULE FillRule
  145684. + );
  145685. +
  145686. +gceSTATUS
  145687. +gcoVG_FinalizePath(
  145688. + IN gcoVG Vg,
  145689. + IN gcsPATH_DATA_PTR PathData
  145690. + );
  145691. +
  145692. +gceSTATUS
  145693. +gcoVG_Clear(
  145694. + IN gcoVG Vg,
  145695. + IN gctINT X,
  145696. + IN gctINT Y,
  145697. + IN gctINT Width,
  145698. + IN gctINT Height
  145699. + );
  145700. +
  145701. +gceSTATUS
  145702. +gcoVG_DrawPath(
  145703. + IN gcoVG Vg,
  145704. + IN gcsPATH_DATA_PTR PathData,
  145705. + IN gctFLOAT Scale,
  145706. + IN gctFLOAT Bias,
  145707. + IN gctBOOL SoftwareTesselation
  145708. + );
  145709. +
  145710. +gceSTATUS
  145711. +gcoVG_DrawImage(
  145712. + IN gcoVG Vg,
  145713. + IN gcoSURF Source,
  145714. + IN gcsPOINT_PTR SourceOrigin,
  145715. + IN gcsPOINT_PTR TargetOrigin,
  145716. + IN gcsSIZE_PTR SourceSize,
  145717. + IN gctINT SourceX,
  145718. + IN gctINT SourceY,
  145719. + IN gctINT TargetX,
  145720. + IN gctINT TargetY,
  145721. + IN gctINT Width,
  145722. + IN gctINT Height,
  145723. + IN gctBOOL Mask
  145724. + );
  145725. +
  145726. +gceSTATUS
  145727. +gcoVG_TesselateImage(
  145728. + IN gcoVG Vg,
  145729. + IN gcoSURF Image,
  145730. + IN gcsVG_RECT_PTR Rectangle,
  145731. + IN gceIMAGE_FILTER Filter,
  145732. + IN gctBOOL Mask,
  145733. + IN gctBOOL SoftwareTesselation
  145734. + );
  145735. +
  145736. +gceSTATUS
  145737. +gcoVG_Blit(
  145738. + IN gcoVG Vg,
  145739. + IN gcoSURF Source,
  145740. + IN gcoSURF Target,
  145741. + IN gcsVG_RECT_PTR SrcRect,
  145742. + IN gcsVG_RECT_PTR TrgRect,
  145743. + IN gceIMAGE_FILTER Filter,
  145744. + IN gceVG_BLEND Mode
  145745. + );
  145746. +
  145747. +gceSTATUS
  145748. +gcoVG_ColorMatrix(
  145749. + IN gcoVG Vg,
  145750. + IN gcoSURF Source,
  145751. + IN gcoSURF Target,
  145752. + IN const gctFLOAT * Matrix,
  145753. + IN gceCHANNEL ColorChannels,
  145754. + IN gctBOOL FilterLinear,
  145755. + IN gctBOOL FilterPremultiplied,
  145756. + IN gcsPOINT_PTR SourceOrigin,
  145757. + IN gcsPOINT_PTR TargetOrigin,
  145758. + IN gctINT Width,
  145759. + IN gctINT Height
  145760. + );
  145761. +
  145762. +gceSTATUS
  145763. +gcoVG_SeparableConvolve(
  145764. + IN gcoVG Vg,
  145765. + IN gcoSURF Source,
  145766. + IN gcoSURF Target,
  145767. + IN gctINT KernelWidth,
  145768. + IN gctINT KernelHeight,
  145769. + IN gctINT ShiftX,
  145770. + IN gctINT ShiftY,
  145771. + IN const gctINT16 * KernelX,
  145772. + IN const gctINT16 * KernelY,
  145773. + IN gctFLOAT Scale,
  145774. + IN gctFLOAT Bias,
  145775. + IN gceTILE_MODE TilingMode,
  145776. + IN gctFLOAT_PTR FillColor,
  145777. + IN gceCHANNEL ColorChannels,
  145778. + IN gctBOOL FilterLinear,
  145779. + IN gctBOOL FilterPremultiplied,
  145780. + IN gcsPOINT_PTR SourceOrigin,
  145781. + IN gcsPOINT_PTR TargetOrigin,
  145782. + IN gcsSIZE_PTR SourceSize,
  145783. + IN gctINT Width,
  145784. + IN gctINT Height
  145785. + );
  145786. +
  145787. +gceSTATUS
  145788. +gcoVG_GaussianBlur(
  145789. + IN gcoVG Vg,
  145790. + IN gcoSURF Source,
  145791. + IN gcoSURF Target,
  145792. + IN gctFLOAT StdDeviationX,
  145793. + IN gctFLOAT StdDeviationY,
  145794. + IN gceTILE_MODE TilingMode,
  145795. + IN gctFLOAT_PTR FillColor,
  145796. + IN gceCHANNEL ColorChannels,
  145797. + IN gctBOOL FilterLinear,
  145798. + IN gctBOOL FilterPremultiplied,
  145799. + IN gcsPOINT_PTR SourceOrigin,
  145800. + IN gcsPOINT_PTR TargetOrigin,
  145801. + IN gcsSIZE_PTR SourceSize,
  145802. + IN gctINT Width,
  145803. + IN gctINT Height
  145804. + );
  145805. +
  145806. +gceSTATUS
  145807. +gcoVG_EnableDither(
  145808. + IN gcoVG Vg,
  145809. + IN gctBOOL Enable
  145810. + );
  145811. +
  145812. +#ifdef __cplusplus
  145813. +}
  145814. +#endif
  145815. +
  145816. +#endif /* __gc_hal_vg_h_ */
  145817. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
  145818. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h 1970-01-01 01:00:00.000000000 +0100
  145819. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h 2014-08-20 19:31:46.136869040 +0200
  145820. @@ -0,0 +1,965 @@
  145821. +/****************************************************************************
  145822. +*
  145823. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  145824. +*
  145825. +* This program is free software; you can redistribute it and/or modify
  145826. +* it under the terms of the GNU General Public License as published by
  145827. +* the Free Software Foundation; either version 2 of the license, or
  145828. +* (at your option) any later version.
  145829. +*
  145830. +* This program is distributed in the hope that it will be useful,
  145831. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  145832. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  145833. +* GNU General Public License for more details.
  145834. +*
  145835. +* You should have received a copy of the GNU General Public License
  145836. +* along with this program; if not write to the Free Software
  145837. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  145838. +*
  145839. +*****************************************************************************/
  145840. +
  145841. +
  145842. +#ifndef __gc_hal_enum_h_
  145843. +#define __gc_hal_enum_h_
  145844. +
  145845. +#ifdef __cplusplus
  145846. +extern "C" {
  145847. +#endif
  145848. +
  145849. +/* Chip models. */
  145850. +typedef enum _gceCHIPMODEL
  145851. +{
  145852. + gcv300 = 0x0300,
  145853. + gcv320 = 0x0320,
  145854. + gcv350 = 0x0350,
  145855. + gcv355 = 0x0355,
  145856. + gcv400 = 0x0400,
  145857. + gcv410 = 0x0410,
  145858. + gcv420 = 0x0420,
  145859. + gcv450 = 0x0450,
  145860. + gcv500 = 0x0500,
  145861. + gcv530 = 0x0530,
  145862. + gcv600 = 0x0600,
  145863. + gcv700 = 0x0700,
  145864. + gcv800 = 0x0800,
  145865. + gcv860 = 0x0860,
  145866. + gcv880 = 0x0880,
  145867. + gcv1000 = 0x1000,
  145868. + gcv2000 = 0x2000,
  145869. + gcv2100 = 0x2100,
  145870. + gcv4000 = 0x4000,
  145871. +}
  145872. +gceCHIPMODEL;
  145873. +
  145874. +/* Chip features. */
  145875. +typedef enum _gceFEATURE
  145876. +{
  145877. + gcvFEATURE_PIPE_2D = 0,
  145878. + gcvFEATURE_PIPE_3D,
  145879. + gcvFEATURE_PIPE_VG,
  145880. + gcvFEATURE_DC,
  145881. + gcvFEATURE_HIGH_DYNAMIC_RANGE,
  145882. + gcvFEATURE_MODULE_CG,
  145883. + gcvFEATURE_MIN_AREA,
  145884. + gcvFEATURE_BUFFER_INTERLEAVING,
  145885. + gcvFEATURE_BYTE_WRITE_2D,
  145886. + gcvFEATURE_ENDIANNESS_CONFIG,
  145887. + gcvFEATURE_DUAL_RETURN_BUS,
  145888. + gcvFEATURE_DEBUG_MODE,
  145889. + gcvFEATURE_YUY2_RENDER_TARGET,
  145890. + gcvFEATURE_FRAGMENT_PROCESSOR,
  145891. + gcvFEATURE_2DPE20,
  145892. + gcvFEATURE_FAST_CLEAR,
  145893. + gcvFEATURE_YUV420_TILER,
  145894. + gcvFEATURE_YUY2_AVERAGING,
  145895. + gcvFEATURE_FLIP_Y,
  145896. + gcvFEATURE_EARLY_Z,
  145897. + gcvFEATURE_Z_COMPRESSION,
  145898. + gcvFEATURE_MSAA,
  145899. + gcvFEATURE_SPECIAL_ANTI_ALIASING,
  145900. + gcvFEATURE_SPECIAL_MSAA_LOD,
  145901. + gcvFEATURE_422_TEXTURE_COMPRESSION,
  145902. + gcvFEATURE_DXT_TEXTURE_COMPRESSION,
  145903. + gcvFEATURE_ETC1_TEXTURE_COMPRESSION,
  145904. + gcvFEATURE_CORRECT_TEXTURE_CONVERTER,
  145905. + gcvFEATURE_TEXTURE_8K,
  145906. + gcvFEATURE_SCALER,
  145907. + gcvFEATURE_YUV420_SCALER,
  145908. + gcvFEATURE_SHADER_HAS_W,
  145909. + gcvFEATURE_SHADER_HAS_SIGN,
  145910. + gcvFEATURE_SHADER_HAS_FLOOR,
  145911. + gcvFEATURE_SHADER_HAS_CEIL,
  145912. + gcvFEATURE_SHADER_HAS_SQRT,
  145913. + gcvFEATURE_SHADER_HAS_TRIG,
  145914. + gcvFEATURE_VAA,
  145915. + gcvFEATURE_HZ,
  145916. + gcvFEATURE_CORRECT_STENCIL,
  145917. + gcvFEATURE_VG20,
  145918. + gcvFEATURE_VG_FILTER,
  145919. + gcvFEATURE_VG21,
  145920. + gcvFEATURE_VG_DOUBLE_BUFFER,
  145921. + gcvFEATURE_MC20,
  145922. + gcvFEATURE_SUPER_TILED,
  145923. + gcvFEATURE_2D_FILTERBLIT_PLUS_ALPHABLEND,
  145924. + gcvFEATURE_2D_DITHER,
  145925. + gcvFEATURE_2D_A8_TARGET,
  145926. + gcvFEATURE_2D_FILTERBLIT_FULLROTATION,
  145927. + gcvFEATURE_2D_BITBLIT_FULLROTATION,
  145928. + gcvFEATURE_WIDE_LINE,
  145929. + gcvFEATURE_FC_FLUSH_STALL,
  145930. + gcvFEATURE_FULL_DIRECTFB,
  145931. + gcvFEATURE_HALF_FLOAT_PIPE,
  145932. + gcvFEATURE_LINE_LOOP,
  145933. + gcvFEATURE_2D_YUV_BLIT,
  145934. + gcvFEATURE_2D_TILING,
  145935. + gcvFEATURE_NON_POWER_OF_TWO,
  145936. + gcvFEATURE_3D_TEXTURE,
  145937. + gcvFEATURE_TEXTURE_ARRAY,
  145938. + gcvFEATURE_TILE_FILLER,
  145939. + gcvFEATURE_LOGIC_OP,
  145940. + gcvFEATURE_COMPOSITION,
  145941. + gcvFEATURE_MIXED_STREAMS,
  145942. + gcvFEATURE_2D_MULTI_SOURCE_BLT,
  145943. + gcvFEATURE_END_EVENT,
  145944. + gcvFEATURE_VERTEX_10_10_10_2,
  145945. + gcvFEATURE_TEXTURE_10_10_10_2,
  145946. + gcvFEATURE_TEXTURE_ANISOTROPIC_FILTERING,
  145947. + gcvFEATURE_TEXTURE_FLOAT_HALF_FLOAT,
  145948. + gcvFEATURE_2D_ROTATION_STALL_FIX,
  145949. + gcvFEATURE_2D_MULTI_SOURCE_BLT_EX,
  145950. + gcvFEATURE_BUG_FIXES10,
  145951. + gcvFEATURE_2D_MINOR_TILING,
  145952. + /* Supertiled compressed textures are supported. */
  145953. + gcvFEATURE_TEX_COMPRRESSION_SUPERTILED,
  145954. + gcvFEATURE_FAST_MSAA,
  145955. + gcvFEATURE_BUG_FIXED_INDEXED_TRIANGLE_STRIP,
  145956. + gcvFEATURE_TEXTURE_TILED_READ,
  145957. + gcvFEATURE_DEPTH_BIAS_FIX,
  145958. + gcvFEATURE_RECT_PRIMITIVE,
  145959. + gcvFEATURE_BUG_FIXES11,
  145960. + gcvFEATURE_SUPERTILED_TEXTURE,
  145961. + gcvFEATURE_2D_NO_COLORBRUSH_INDEX8,
  145962. + gcvFEATURE_RS_YUV_TARGET,
  145963. + gcvFEATURE_2D_FC_SOURCE,
  145964. + gcvFEATURE_PE_DITHER_FIX,
  145965. + gcvFEATURE_2D_YUV_SEPARATE_STRIDE,
  145966. + gcvFEATURE_FRUSTUM_CLIP_FIX,
  145967. + gcvFEATURE_TEXTURE_LINEAR,
  145968. + gcvFEATURE_TEXTURE_YUV_ASSEMBLER,
  145969. + gcvFEATURE_SHADER_HAS_INSTRUCTION_CACHE,
  145970. + gcvFEATURE_DYNAMIC_FREQUENCY_SCALING,
  145971. + gcvFEATURE_BUGFIX15,
  145972. + gcvFEATURE_2D_GAMMA,
  145973. + gcvFEATURE_2D_COLOR_SPACE_CONVERSION,
  145974. + gcvFEATURE_2D_SUPER_TILE_VERSION,
  145975. + gcvFEATURE_2D_MIRROR_EXTENSION,
  145976. + gcvFEATURE_2D_SUPER_TILE_V1,
  145977. + gcvFEATURE_2D_SUPER_TILE_V2,
  145978. + gcvFEATURE_2D_SUPER_TILE_V3,
  145979. + gcvFEATURE_2D_MULTI_SOURCE_BLT_EX2,
  145980. + gcvFEATURE_ELEMENT_INDEX_UINT,
  145981. + gcvFEATURE_2D_COMPRESSION,
  145982. + gcvFEATURE_2D_OPF_YUV_OUTPUT,
  145983. + gcvFEATURE_2D_MULTI_SRC_BLT_TO_UNIFIED_DST_RECT,
  145984. + gcvFEATURE_2D_YUV_MODE,
  145985. + gcvFEATURE_DECOMPRESS_Z16,
  145986. + gcvFEATURE_LINEAR_RENDER_TARGET,
  145987. + gcvFEATURE_BUG_FIXES8,
  145988. + gcvFEATURE_HALTI2,
  145989. + gcvFEATURE_MMU,
  145990. +}
  145991. +gceFEATURE;
  145992. +
  145993. +/* Chip Power Status. */
  145994. +typedef enum _gceCHIPPOWERSTATE
  145995. +{
  145996. + gcvPOWER_ON = 0,
  145997. + gcvPOWER_OFF,
  145998. + gcvPOWER_IDLE,
  145999. + gcvPOWER_SUSPEND,
  146000. + gcvPOWER_SUSPEND_ATPOWERON,
  146001. + gcvPOWER_OFF_ATPOWERON,
  146002. + gcvPOWER_IDLE_BROADCAST,
  146003. + gcvPOWER_SUSPEND_BROADCAST,
  146004. + gcvPOWER_OFF_BROADCAST,
  146005. + gcvPOWER_OFF_RECOVERY,
  146006. + gcvPOWER_OFF_TIMEOUT,
  146007. + gcvPOWER_ON_AUTO
  146008. +}
  146009. +gceCHIPPOWERSTATE;
  146010. +
  146011. +/* CPU cache operations */
  146012. +typedef enum _gceCACHEOPERATION
  146013. +{
  146014. + gcvCACHE_CLEAN = 0x01,
  146015. + gcvCACHE_INVALIDATE = 0x02,
  146016. + gcvCACHE_FLUSH = gcvCACHE_CLEAN | gcvCACHE_INVALIDATE,
  146017. + gcvCACHE_MEMORY_BARRIER = 0x04
  146018. +}
  146019. +gceCACHEOPERATION;
  146020. +
  146021. +/* Surface types. */
  146022. +typedef enum _gceSURF_TYPE
  146023. +{
  146024. + gcvSURF_TYPE_UNKNOWN = 0,
  146025. + gcvSURF_INDEX,
  146026. + gcvSURF_VERTEX,
  146027. + gcvSURF_TEXTURE,
  146028. + gcvSURF_RENDER_TARGET,
  146029. + gcvSURF_DEPTH,
  146030. + gcvSURF_BITMAP,
  146031. + gcvSURF_TILE_STATUS,
  146032. + gcvSURF_IMAGE,
  146033. + gcvSURF_MASK,
  146034. + gcvSURF_SCISSOR,
  146035. + gcvSURF_HIERARCHICAL_DEPTH,
  146036. + gcvSURF_NUM_TYPES, /* Make sure this is the last one! */
  146037. +
  146038. + /* Combinations. */
  146039. + gcvSURF_NO_TILE_STATUS = 0x100,
  146040. + gcvSURF_NO_VIDMEM = 0x200, /* Used to allocate surfaces with no underlying vidmem node.
  146041. + In Android, vidmem node is allocated by another process. */
  146042. + gcvSURF_CACHEABLE = 0x400, /* Used to allocate a cacheable surface */
  146043. + gcvSURF_FLIP = 0x800, /* The Resolve Target the will been flip resolve from RT */
  146044. + gcvSURF_TILE_STATUS_DIRTY = 0x1000, /* Init tile status to all dirty */
  146045. +
  146046. + gcvSURF_LINEAR = 0x2000,
  146047. + gcvSURF_VG = 0x4000,
  146048. +
  146049. + gcvSURF_TEXTURE_LINEAR = gcvSURF_TEXTURE
  146050. + | gcvSURF_LINEAR,
  146051. +
  146052. + gcvSURF_RENDER_TARGET_NO_TILE_STATUS = gcvSURF_RENDER_TARGET
  146053. + | gcvSURF_NO_TILE_STATUS,
  146054. +
  146055. + gcvSURF_RENDER_TARGET_TS_DIRTY = gcvSURF_RENDER_TARGET
  146056. + | gcvSURF_TILE_STATUS_DIRTY,
  146057. +
  146058. + gcvSURF_DEPTH_NO_TILE_STATUS = gcvSURF_DEPTH
  146059. + | gcvSURF_NO_TILE_STATUS,
  146060. +
  146061. + gcvSURF_DEPTH_TS_DIRTY = gcvSURF_DEPTH
  146062. + | gcvSURF_TILE_STATUS_DIRTY,
  146063. +
  146064. + /* Supported surface types with no vidmem node. */
  146065. + gcvSURF_BITMAP_NO_VIDMEM = gcvSURF_BITMAP
  146066. + | gcvSURF_NO_VIDMEM,
  146067. +
  146068. + gcvSURF_TEXTURE_NO_VIDMEM = gcvSURF_TEXTURE
  146069. + | gcvSURF_NO_VIDMEM,
  146070. +
  146071. + /* Cacheable surface types with no vidmem node. */
  146072. + gcvSURF_CACHEABLE_BITMAP_NO_VIDMEM = gcvSURF_BITMAP_NO_VIDMEM
  146073. + | gcvSURF_CACHEABLE,
  146074. +
  146075. + gcvSURF_CACHEABLE_BITMAP = gcvSURF_BITMAP
  146076. + | gcvSURF_CACHEABLE,
  146077. +
  146078. + gcvSURF_FLIP_BITMAP = gcvSURF_BITMAP
  146079. + | gcvSURF_FLIP,
  146080. +}
  146081. +gceSURF_TYPE;
  146082. +
  146083. +typedef enum _gceSURF_USAGE
  146084. +{
  146085. + gcvSURF_USAGE_UNKNOWN,
  146086. + gcvSURF_USAGE_RESOLVE_AFTER_CPU,
  146087. + gcvSURF_USAGE_RESOLVE_AFTER_3D
  146088. +}
  146089. +gceSURF_USAGE;
  146090. +
  146091. +typedef enum _gceSURF_COLOR_TYPE
  146092. +{
  146093. + gcvSURF_COLOR_UNKNOWN = 0,
  146094. + gcvSURF_COLOR_LINEAR = 0x01,
  146095. + gcvSURF_COLOR_ALPHA_PRE = 0x02,
  146096. +}
  146097. +gceSURF_COLOR_TYPE;
  146098. +
  146099. +/* Rotation. */
  146100. +typedef enum _gceSURF_ROTATION
  146101. +{
  146102. + gcvSURF_0_DEGREE = 0,
  146103. + gcvSURF_90_DEGREE,
  146104. + gcvSURF_180_DEGREE,
  146105. + gcvSURF_270_DEGREE,
  146106. + gcvSURF_FLIP_X,
  146107. + gcvSURF_FLIP_Y,
  146108. +
  146109. + gcvSURF_POST_FLIP_X = 0x40000000,
  146110. + gcvSURF_POST_FLIP_Y = 0x80000000,
  146111. +}
  146112. +gceSURF_ROTATION;
  146113. +
  146114. +typedef enum _gceMIPMAP_IMAGE_FORMAT
  146115. +{
  146116. + gcvUNKNOWN_MIPMAP_IMAGE_FORMAT = -2
  146117. +}
  146118. +gceMIPMAP_IMAGE_FORMAT;
  146119. +
  146120. +
  146121. +/* Surface formats. */
  146122. +typedef enum _gceSURF_FORMAT
  146123. +{
  146124. + /* Unknown format. */
  146125. + gcvSURF_UNKNOWN = 0,
  146126. +
  146127. + /* Palettized formats. */
  146128. + gcvSURF_INDEX1 = 100,
  146129. + gcvSURF_INDEX4,
  146130. + gcvSURF_INDEX8,
  146131. +
  146132. + /* RGB formats. */
  146133. + gcvSURF_A2R2G2B2 = 200,
  146134. + gcvSURF_R3G3B2,
  146135. + gcvSURF_A8R3G3B2,
  146136. + gcvSURF_X4R4G4B4,
  146137. + gcvSURF_A4R4G4B4,
  146138. + gcvSURF_R4G4B4A4,
  146139. + gcvSURF_X1R5G5B5,
  146140. + gcvSURF_A1R5G5B5,
  146141. + gcvSURF_R5G5B5A1,
  146142. + gcvSURF_R5G6B5,
  146143. + gcvSURF_R8G8B8,
  146144. + gcvSURF_X8R8G8B8,
  146145. + gcvSURF_A8R8G8B8,
  146146. + gcvSURF_R8G8B8A8,
  146147. + gcvSURF_G8R8G8B8,
  146148. + gcvSURF_R8G8B8G8,
  146149. + gcvSURF_X2R10G10B10,
  146150. + gcvSURF_A2R10G10B10,
  146151. + gcvSURF_X12R12G12B12,
  146152. + gcvSURF_A12R12G12B12,
  146153. + gcvSURF_X16R16G16B16,
  146154. + gcvSURF_A16R16G16B16,
  146155. + gcvSURF_A32R32G32B32,
  146156. + gcvSURF_R8G8B8X8,
  146157. + gcvSURF_R5G5B5X1,
  146158. + gcvSURF_R4G4B4X4,
  146159. +
  146160. + /* BGR formats. */
  146161. + gcvSURF_A4B4G4R4 = 300,
  146162. + gcvSURF_A1B5G5R5,
  146163. + gcvSURF_B5G6R5,
  146164. + gcvSURF_B8G8R8,
  146165. + gcvSURF_B16G16R16,
  146166. + gcvSURF_X8B8G8R8,
  146167. + gcvSURF_A8B8G8R8,
  146168. + gcvSURF_A2B10G10R10,
  146169. + gcvSURF_X16B16G16R16,
  146170. + gcvSURF_A16B16G16R16,
  146171. + gcvSURF_B32G32R32,
  146172. + gcvSURF_X32B32G32R32,
  146173. + gcvSURF_A32B32G32R32,
  146174. + gcvSURF_B4G4R4A4,
  146175. + gcvSURF_B5G5R5A1,
  146176. + gcvSURF_B8G8R8X8,
  146177. + gcvSURF_B8G8R8A8,
  146178. + gcvSURF_X4B4G4R4,
  146179. + gcvSURF_X1B5G5R5,
  146180. + gcvSURF_B4G4R4X4,
  146181. + gcvSURF_B5G5R5X1,
  146182. + gcvSURF_X2B10G10R10,
  146183. +
  146184. + /* Compressed formats. */
  146185. + gcvSURF_DXT1 = 400,
  146186. + gcvSURF_DXT2,
  146187. + gcvSURF_DXT3,
  146188. + gcvSURF_DXT4,
  146189. + gcvSURF_DXT5,
  146190. + gcvSURF_CXV8U8,
  146191. + gcvSURF_ETC1,
  146192. + gcvSURF_R11_EAC,
  146193. + gcvSURF_SIGNED_R11_EAC,
  146194. + gcvSURF_RG11_EAC,
  146195. + gcvSURF_SIGNED_RG11_EAC,
  146196. + gcvSURF_RGB8_ETC2,
  146197. + gcvSURF_SRGB8_ETC2,
  146198. + gcvSURF_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
  146199. + gcvSURF_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
  146200. + gcvSURF_RGBA8_ETC2_EAC,
  146201. + gcvSURF_SRGB8_ALPHA8_ETC2_EAC,
  146202. +
  146203. + /* YUV formats. */
  146204. + gcvSURF_YUY2 = 500,
  146205. + gcvSURF_UYVY,
  146206. + gcvSURF_YV12,
  146207. + gcvSURF_I420,
  146208. + gcvSURF_NV12,
  146209. + gcvSURF_NV21,
  146210. + gcvSURF_NV16,
  146211. + gcvSURF_NV61,
  146212. + gcvSURF_YVYU,
  146213. + gcvSURF_VYUY,
  146214. +
  146215. + /* Depth formats. */
  146216. + gcvSURF_D16 = 600,
  146217. + gcvSURF_D24S8,
  146218. + gcvSURF_D32,
  146219. + gcvSURF_D24X8,
  146220. +
  146221. + /* Alpha formats. */
  146222. + gcvSURF_A4 = 700,
  146223. + gcvSURF_A8,
  146224. + gcvSURF_A12,
  146225. + gcvSURF_A16,
  146226. + gcvSURF_A32,
  146227. + gcvSURF_A1,
  146228. +
  146229. + /* Luminance formats. */
  146230. + gcvSURF_L4 = 800,
  146231. + gcvSURF_L8,
  146232. + gcvSURF_L12,
  146233. + gcvSURF_L16,
  146234. + gcvSURF_L32,
  146235. + gcvSURF_L1,
  146236. +
  146237. + /* Alpha/Luminance formats. */
  146238. + gcvSURF_A4L4 = 900,
  146239. + gcvSURF_A2L6,
  146240. + gcvSURF_A8L8,
  146241. + gcvSURF_A4L12,
  146242. + gcvSURF_A12L12,
  146243. + gcvSURF_A16L16,
  146244. +
  146245. + /* Bump formats. */
  146246. + gcvSURF_L6V5U5 = 1000,
  146247. + gcvSURF_V8U8,
  146248. + gcvSURF_X8L8V8U8,
  146249. + gcvSURF_Q8W8V8U8,
  146250. + gcvSURF_A2W10V10U10,
  146251. + gcvSURF_V16U16,
  146252. + gcvSURF_Q16W16V16U16,
  146253. +
  146254. + /* R/RG/RA formats. */
  146255. + gcvSURF_R8 = 1100,
  146256. + gcvSURF_X8R8,
  146257. + gcvSURF_G8R8,
  146258. + gcvSURF_X8G8R8,
  146259. + gcvSURF_A8R8,
  146260. + gcvSURF_R16,
  146261. + gcvSURF_X16R16,
  146262. + gcvSURF_G16R16,
  146263. + gcvSURF_X16G16R16,
  146264. + gcvSURF_A16R16,
  146265. + gcvSURF_R32,
  146266. + gcvSURF_X32R32,
  146267. + gcvSURF_G32R32,
  146268. + gcvSURF_X32G32R32,
  146269. + gcvSURF_A32R32,
  146270. + gcvSURF_RG16,
  146271. +
  146272. + /* Floating point formats. */
  146273. + gcvSURF_R16F = 1200,
  146274. + gcvSURF_X16R16F,
  146275. + gcvSURF_G16R16F,
  146276. + gcvSURF_X16G16R16F,
  146277. + gcvSURF_B16G16R16F,
  146278. + gcvSURF_X16B16G16R16F,
  146279. + gcvSURF_A16B16G16R16F,
  146280. + gcvSURF_R32F,
  146281. + gcvSURF_X32R32F,
  146282. + gcvSURF_G32R32F,
  146283. + gcvSURF_X32G32R32F,
  146284. + gcvSURF_B32G32R32F,
  146285. + gcvSURF_X32B32G32R32F,
  146286. + gcvSURF_A32B32G32R32F,
  146287. + gcvSURF_A16F,
  146288. + gcvSURF_L16F,
  146289. + gcvSURF_A16L16F,
  146290. + gcvSURF_A16R16F,
  146291. + gcvSURF_A32F,
  146292. + gcvSURF_L32F,
  146293. + gcvSURF_A32L32F,
  146294. + gcvSURF_A32R32F,
  146295. +
  146296. +}
  146297. +gceSURF_FORMAT;
  146298. +
  146299. +/* Pixel swizzle modes. */
  146300. +typedef enum _gceSURF_SWIZZLE
  146301. +{
  146302. + gcvSURF_NOSWIZZLE = 0,
  146303. + gcvSURF_ARGB,
  146304. + gcvSURF_ABGR,
  146305. + gcvSURF_RGBA,
  146306. + gcvSURF_BGRA
  146307. +}
  146308. +gceSURF_SWIZZLE;
  146309. +
  146310. +/* Transparency modes. */
  146311. +typedef enum _gceSURF_TRANSPARENCY
  146312. +{
  146313. + /* Valid only for PE 1.0 */
  146314. + gcvSURF_OPAQUE = 0,
  146315. + gcvSURF_SOURCE_MATCH,
  146316. + gcvSURF_SOURCE_MASK,
  146317. + gcvSURF_PATTERN_MASK,
  146318. +}
  146319. +gceSURF_TRANSPARENCY;
  146320. +
  146321. +/* Surface Alignment. */
  146322. +typedef enum _gceSURF_ALIGNMENT
  146323. +{
  146324. + gcvSURF_FOUR = 0,
  146325. + gcvSURF_SIXTEEN,
  146326. + gcvSURF_SUPER_TILED,
  146327. + gcvSURF_SPLIT_TILED,
  146328. + gcvSURF_SPLIT_SUPER_TILED,
  146329. +}
  146330. +gceSURF_ALIGNMENT;
  146331. +
  146332. +
  146333. +/* Surface Addressing. */
  146334. +typedef enum _gceSURF_ADDRESSING
  146335. +{
  146336. + gcvSURF_NO_STRIDE_TILED = 0,
  146337. + gcvSURF_NO_STRIDE_LINEAR,
  146338. + gcvSURF_STRIDE_TILED,
  146339. + gcvSURF_STRIDE_LINEAR
  146340. +}
  146341. +gceSURF_ADDRESSING;
  146342. +
  146343. +/* Transparency modes. */
  146344. +typedef enum _gce2D_TRANSPARENCY
  146345. +{
  146346. + /* Valid only for PE 2.0 */
  146347. + gcv2D_OPAQUE = 0,
  146348. + gcv2D_KEYED,
  146349. + gcv2D_MASKED
  146350. +}
  146351. +gce2D_TRANSPARENCY;
  146352. +
  146353. +/* Mono packing modes. */
  146354. +typedef enum _gceSURF_MONOPACK
  146355. +{
  146356. + gcvSURF_PACKED8 = 0,
  146357. + gcvSURF_PACKED16,
  146358. + gcvSURF_PACKED32,
  146359. + gcvSURF_UNPACKED,
  146360. +}
  146361. +gceSURF_MONOPACK;
  146362. +
  146363. +/* Blending modes. */
  146364. +typedef enum _gceSURF_BLEND_MODE
  146365. +{
  146366. + /* Porter-Duff blending modes. */
  146367. + /* Fsrc Fdst */
  146368. + gcvBLEND_CLEAR = 0, /* 0 0 */
  146369. + gcvBLEND_SRC, /* 1 0 */
  146370. + gcvBLEND_DST, /* 0 1 */
  146371. + gcvBLEND_SRC_OVER_DST, /* 1 1 - Asrc */
  146372. + gcvBLEND_DST_OVER_SRC, /* 1 - Adst 1 */
  146373. + gcvBLEND_SRC_IN_DST, /* Adst 0 */
  146374. + gcvBLEND_DST_IN_SRC, /* 0 Asrc */
  146375. + gcvBLEND_SRC_OUT_DST, /* 1 - Adst 0 */
  146376. + gcvBLEND_DST_OUT_SRC, /* 0 1 - Asrc */
  146377. + gcvBLEND_SRC_ATOP_DST, /* Adst 1 - Asrc */
  146378. + gcvBLEND_DST_ATOP_SRC, /* 1 - Adst Asrc */
  146379. + gcvBLEND_SRC_XOR_DST, /* 1 - Adst 1 - Asrc */
  146380. +
  146381. + /* Special blending modes. */
  146382. + gcvBLEND_SET, /* DST = 1 */
  146383. + gcvBLEND_SUB /* DST = DST * (1 - SRC) */
  146384. +}
  146385. +gceSURF_BLEND_MODE;
  146386. +
  146387. +/* Per-pixel alpha modes. */
  146388. +typedef enum _gceSURF_PIXEL_ALPHA_MODE
  146389. +{
  146390. + gcvSURF_PIXEL_ALPHA_STRAIGHT = 0,
  146391. + gcvSURF_PIXEL_ALPHA_INVERSED
  146392. +}
  146393. +gceSURF_PIXEL_ALPHA_MODE;
  146394. +
  146395. +/* Global alpha modes. */
  146396. +typedef enum _gceSURF_GLOBAL_ALPHA_MODE
  146397. +{
  146398. + gcvSURF_GLOBAL_ALPHA_OFF = 0,
  146399. + gcvSURF_GLOBAL_ALPHA_ON,
  146400. + gcvSURF_GLOBAL_ALPHA_SCALE
  146401. +}
  146402. +gceSURF_GLOBAL_ALPHA_MODE;
  146403. +
  146404. +/* Color component modes for alpha blending. */
  146405. +typedef enum _gceSURF_PIXEL_COLOR_MODE
  146406. +{
  146407. + gcvSURF_COLOR_STRAIGHT = 0,
  146408. + gcvSURF_COLOR_MULTIPLY
  146409. +}
  146410. +gceSURF_PIXEL_COLOR_MODE;
  146411. +
  146412. +/* Color component modes for alpha blending. */
  146413. +typedef enum _gce2D_PIXEL_COLOR_MULTIPLY_MODE
  146414. +{
  146415. + gcv2D_COLOR_MULTIPLY_DISABLE = 0,
  146416. + gcv2D_COLOR_MULTIPLY_ENABLE
  146417. +}
  146418. +gce2D_PIXEL_COLOR_MULTIPLY_MODE;
  146419. +
  146420. +/* Color component modes for alpha blending. */
  146421. +typedef enum _gce2D_GLOBAL_COLOR_MULTIPLY_MODE
  146422. +{
  146423. + gcv2D_GLOBAL_COLOR_MULTIPLY_DISABLE = 0,
  146424. + gcv2D_GLOBAL_COLOR_MULTIPLY_ALPHA,
  146425. + gcv2D_GLOBAL_COLOR_MULTIPLY_COLOR
  146426. +}
  146427. +gce2D_GLOBAL_COLOR_MULTIPLY_MODE;
  146428. +
  146429. +/* Alpha blending factor modes. */
  146430. +typedef enum _gceSURF_BLEND_FACTOR_MODE
  146431. +{
  146432. + gcvSURF_BLEND_ZERO = 0,
  146433. + gcvSURF_BLEND_ONE,
  146434. + gcvSURF_BLEND_STRAIGHT,
  146435. + gcvSURF_BLEND_INVERSED,
  146436. + gcvSURF_BLEND_COLOR,
  146437. + gcvSURF_BLEND_COLOR_INVERSED,
  146438. + gcvSURF_BLEND_SRC_ALPHA_SATURATED,
  146439. + gcvSURF_BLEND_STRAIGHT_NO_CROSS,
  146440. + gcvSURF_BLEND_INVERSED_NO_CROSS,
  146441. + gcvSURF_BLEND_COLOR_NO_CROSS,
  146442. + gcvSURF_BLEND_COLOR_INVERSED_NO_CROSS,
  146443. + gcvSURF_BLEND_SRC_ALPHA_SATURATED_CROSS
  146444. +}
  146445. +gceSURF_BLEND_FACTOR_MODE;
  146446. +
  146447. +/* Alpha blending porter duff rules. */
  146448. +typedef enum _gce2D_PORTER_DUFF_RULE
  146449. +{
  146450. + gcvPD_CLEAR = 0,
  146451. + gcvPD_SRC,
  146452. + gcvPD_SRC_OVER,
  146453. + gcvPD_DST_OVER,
  146454. + gcvPD_SRC_IN,
  146455. + gcvPD_DST_IN,
  146456. + gcvPD_SRC_OUT,
  146457. + gcvPD_DST_OUT,
  146458. + gcvPD_SRC_ATOP,
  146459. + gcvPD_DST_ATOP,
  146460. + gcvPD_ADD,
  146461. + gcvPD_XOR,
  146462. + gcvPD_DST
  146463. +}
  146464. +gce2D_PORTER_DUFF_RULE;
  146465. +
  146466. +/* Alpha blending factor modes. */
  146467. +typedef enum _gce2D_YUV_COLOR_MODE
  146468. +{
  146469. + gcv2D_YUV_601= 0,
  146470. + gcv2D_YUV_709,
  146471. + gcv2D_YUV_USER_DEFINED,
  146472. + gcv2D_YUV_USER_DEFINED_CLAMP,
  146473. +
  146474. + /* Default setting is for src. gcv2D_YUV_DST
  146475. + can be ORed to set dst.
  146476. + */
  146477. + gcv2D_YUV_DST = 0x80000000,
  146478. +}
  146479. +gce2D_YUV_COLOR_MODE;
  146480. +
  146481. +typedef enum _gce2D_COMMAND
  146482. +{
  146483. + gcv2D_CLEAR = 0,
  146484. + gcv2D_LINE,
  146485. + gcv2D_BLT,
  146486. + gcv2D_STRETCH,
  146487. + gcv2D_HOR_FILTER,
  146488. + gcv2D_VER_FILTER,
  146489. + gcv2D_MULTI_SOURCE_BLT,
  146490. +}
  146491. +gce2D_COMMAND;
  146492. +
  146493. +typedef enum _gce2D_TILE_STATUS_CONFIG
  146494. +{
  146495. + gcv2D_TSC_DISABLE = 0,
  146496. + gcv2D_TSC_ENABLE = 0x00000001,
  146497. + gcv2D_TSC_COMPRESSED = 0x00000002,
  146498. + gcv2D_TSC_DOWN_SAMPLER = 0x00000004,
  146499. + gcv2D_TSC_2D_COMPRESSED = 0x00000008,
  146500. +}
  146501. +gce2D_TILE_STATUS_CONFIG;
  146502. +
  146503. +typedef enum _gce2D_QUERY
  146504. +{
  146505. + gcv2D_QUERY_RGB_ADDRESS_MIN_ALIGN = 0,
  146506. + gcv2D_QUERY_RGB_STRIDE_MIN_ALIGN,
  146507. + gcv2D_QUERY_YUV_ADDRESS_MIN_ALIGN,
  146508. + gcv2D_QUERY_YUV_STRIDE_MIN_ALIGN,
  146509. +}
  146510. +gce2D_QUERY;
  146511. +
  146512. +typedef enum _gce2D_SUPER_TILE_VERSION
  146513. +{
  146514. + gcv2D_SUPER_TILE_VERSION_V1 = 1,
  146515. + gcv2D_SUPER_TILE_VERSION_V2 = 2,
  146516. + gcv2D_SUPER_TILE_VERSION_V3 = 3,
  146517. +}
  146518. +gce2D_SUPER_TILE_VERSION;
  146519. +
  146520. +typedef enum _gce2D_STATE
  146521. +{
  146522. + gcv2D_STATE_SPECIAL_FILTER_MIRROR_MODE = 1,
  146523. + gcv2D_STATE_SUPER_TILE_VERSION,
  146524. + gcv2D_STATE_EN_GAMMA,
  146525. + gcv2D_STATE_DE_GAMMA,
  146526. + gcv2D_STATE_MULTI_SRC_BLIT_UNIFIED_DST_RECT,
  146527. + gcv2D_STATE_XRGB_ENABLE,
  146528. +
  146529. + gcv2D_STATE_ARRAY_EN_GAMMA = 0x10001,
  146530. + gcv2D_STATE_ARRAY_DE_GAMMA,
  146531. + gcv2D_STATE_ARRAY_CSC_YUV_TO_RGB,
  146532. + gcv2D_STATE_ARRAY_CSC_RGB_TO_YUV,
  146533. +}
  146534. +gce2D_STATE;
  146535. +
  146536. +#ifndef VIVANTE_NO_3D
  146537. +/* Texture functions. */
  146538. +typedef enum _gceTEXTURE_FUNCTION
  146539. +{
  146540. + gcvTEXTURE_DUMMY = 0,
  146541. + gcvTEXTURE_REPLACE = 0,
  146542. + gcvTEXTURE_MODULATE,
  146543. + gcvTEXTURE_ADD,
  146544. + gcvTEXTURE_ADD_SIGNED,
  146545. + gcvTEXTURE_INTERPOLATE,
  146546. + gcvTEXTURE_SUBTRACT,
  146547. + gcvTEXTURE_DOT3
  146548. +}
  146549. +gceTEXTURE_FUNCTION;
  146550. +
  146551. +/* Texture sources. */
  146552. +typedef enum _gceTEXTURE_SOURCE
  146553. +{
  146554. + gcvCOLOR_FROM_TEXTURE = 0,
  146555. + gcvCOLOR_FROM_CONSTANT_COLOR,
  146556. + gcvCOLOR_FROM_PRIMARY_COLOR,
  146557. + gcvCOLOR_FROM_PREVIOUS_COLOR
  146558. +}
  146559. +gceTEXTURE_SOURCE;
  146560. +
  146561. +/* Texture source channels. */
  146562. +typedef enum _gceTEXTURE_CHANNEL
  146563. +{
  146564. + gcvFROM_COLOR = 0,
  146565. + gcvFROM_ONE_MINUS_COLOR,
  146566. + gcvFROM_ALPHA,
  146567. + gcvFROM_ONE_MINUS_ALPHA
  146568. +}
  146569. +gceTEXTURE_CHANNEL;
  146570. +#endif /* VIVANTE_NO_3D */
  146571. +
  146572. +/* Filter types. */
  146573. +typedef enum _gceFILTER_TYPE
  146574. +{
  146575. + gcvFILTER_SYNC = 0,
  146576. + gcvFILTER_BLUR,
  146577. + gcvFILTER_USER
  146578. +}
  146579. +gceFILTER_TYPE;
  146580. +
  146581. +/* Filter pass types. */
  146582. +typedef enum _gceFILTER_PASS_TYPE
  146583. +{
  146584. + gcvFILTER_HOR_PASS = 0,
  146585. + gcvFILTER_VER_PASS
  146586. +}
  146587. +gceFILTER_PASS_TYPE;
  146588. +
  146589. +/* Endian hints. */
  146590. +typedef enum _gceENDIAN_HINT
  146591. +{
  146592. + gcvENDIAN_NO_SWAP = 0,
  146593. + gcvENDIAN_SWAP_WORD,
  146594. + gcvENDIAN_SWAP_DWORD
  146595. +}
  146596. +gceENDIAN_HINT;
  146597. +
  146598. +/* Tiling modes. */
  146599. +typedef enum _gceTILING
  146600. +{
  146601. + gcvLINEAR = 0,
  146602. + gcvTILED,
  146603. + gcvSUPERTILED,
  146604. + gcvMULTI_TILED,
  146605. + gcvMULTI_SUPERTILED,
  146606. + gcvMINORTILED,
  146607. +}
  146608. +gceTILING;
  146609. +
  146610. +/* 2D pattern type. */
  146611. +typedef enum _gce2D_PATTERN
  146612. +{
  146613. + gcv2D_PATTERN_SOLID = 0,
  146614. + gcv2D_PATTERN_MONO,
  146615. + gcv2D_PATTERN_COLOR,
  146616. + gcv2D_PATTERN_INVALID
  146617. +}
  146618. +gce2D_PATTERN;
  146619. +
  146620. +/* 2D source type. */
  146621. +typedef enum _gce2D_SOURCE
  146622. +{
  146623. + gcv2D_SOURCE_MASKED = 0,
  146624. + gcv2D_SOURCE_MONO,
  146625. + gcv2D_SOURCE_COLOR,
  146626. + gcv2D_SOURCE_INVALID
  146627. +}
  146628. +gce2D_SOURCE;
  146629. +
  146630. +/* Pipes. */
  146631. +typedef enum _gcePIPE_SELECT
  146632. +{
  146633. + gcvPIPE_INVALID = ~0,
  146634. + gcvPIPE_3D = 0,
  146635. + gcvPIPE_2D
  146636. +}
  146637. +gcePIPE_SELECT;
  146638. +
  146639. +/* Hardware type. */
  146640. +typedef enum _gceHARDWARE_TYPE
  146641. +{
  146642. + gcvHARDWARE_INVALID = 0x00,
  146643. + gcvHARDWARE_3D = 0x01,
  146644. + gcvHARDWARE_2D = 0x02,
  146645. + gcvHARDWARE_VG = 0x04,
  146646. +
  146647. + gcvHARDWARE_3D2D = gcvHARDWARE_3D | gcvHARDWARE_2D
  146648. +}
  146649. +gceHARDWARE_TYPE;
  146650. +
  146651. +#define gcdCHIP_COUNT 3
  146652. +
  146653. +typedef enum _gceMMU_MODE
  146654. +{
  146655. + gcvMMU_MODE_1K,
  146656. + gcvMMU_MODE_4K,
  146657. +} gceMMU_MODE;
  146658. +
  146659. +/* User signal command codes. */
  146660. +typedef enum _gceUSER_SIGNAL_COMMAND_CODES
  146661. +{
  146662. + gcvUSER_SIGNAL_CREATE,
  146663. + gcvUSER_SIGNAL_DESTROY,
  146664. + gcvUSER_SIGNAL_SIGNAL,
  146665. + gcvUSER_SIGNAL_WAIT,
  146666. + gcvUSER_SIGNAL_MAP,
  146667. + gcvUSER_SIGNAL_UNMAP,
  146668. +}
  146669. +gceUSER_SIGNAL_COMMAND_CODES;
  146670. +
  146671. +/* Sync point command codes. */
  146672. +typedef enum _gceSYNC_POINT_COMMAND_CODES
  146673. +{
  146674. + gcvSYNC_POINT_CREATE,
  146675. + gcvSYNC_POINT_DESTROY,
  146676. + gcvSYNC_POINT_SIGNAL,
  146677. +}
  146678. +gceSYNC_POINT_COMMAND_CODES;
  146679. +
  146680. +/* Event locations. */
  146681. +typedef enum _gceKERNEL_WHERE
  146682. +{
  146683. + gcvKERNEL_COMMAND,
  146684. + gcvKERNEL_VERTEX,
  146685. + gcvKERNEL_TRIANGLE,
  146686. + gcvKERNEL_TEXTURE,
  146687. + gcvKERNEL_PIXEL,
  146688. +}
  146689. +gceKERNEL_WHERE;
  146690. +
  146691. +#if gcdENABLE_VG
  146692. +/* Hardware blocks. */
  146693. +typedef enum _gceBLOCK
  146694. +{
  146695. + gcvBLOCK_COMMAND,
  146696. + gcvBLOCK_TESSELLATOR,
  146697. + gcvBLOCK_TESSELLATOR2,
  146698. + gcvBLOCK_TESSELLATOR3,
  146699. + gcvBLOCK_RASTER,
  146700. + gcvBLOCK_VG,
  146701. + gcvBLOCK_VG2,
  146702. + gcvBLOCK_VG3,
  146703. + gcvBLOCK_PIXEL,
  146704. +
  146705. + /* Number of defined blocks. */
  146706. + gcvBLOCK_COUNT
  146707. +}
  146708. +gceBLOCK;
  146709. +#endif
  146710. +
  146711. +/* gcdDUMP message type. */
  146712. +typedef enum _gceDEBUG_MESSAGE_TYPE
  146713. +{
  146714. + gcvMESSAGE_TEXT,
  146715. + gcvMESSAGE_DUMP
  146716. +}
  146717. +gceDEBUG_MESSAGE_TYPE;
  146718. +
  146719. +typedef enum _gceSPECIAL_HINT
  146720. +{
  146721. + gceSPECIAL_HINT0,
  146722. + gceSPECIAL_HINT1,
  146723. + gceSPECIAL_HINT2,
  146724. + gceSPECIAL_HINT3,
  146725. + /* For disable dynamic stream/index */
  146726. + gceSPECIAL_HINT4
  146727. +}
  146728. +gceSPECIAL_HINT;
  146729. +
  146730. +typedef enum _gceMACHINECODE
  146731. +{
  146732. + gcvMACHINECODE_HOVERJET0 = 0x0,
  146733. + gcvMACHINECODE_HOVERJET1 ,
  146734. +
  146735. + gcvMACHINECODE_TAIJI0 ,
  146736. + gcvMACHINECODE_TAIJI1 ,
  146737. + gcvMACHINECODE_TAIJI2 ,
  146738. +
  146739. + gcvMACHINECODE_ANTUTU0 ,
  146740. +
  146741. + gcvMACHINECODE_GLB27_RELEASE_0,
  146742. + gcvMACHINECODE_GLB27_RELEASE_1,
  146743. +
  146744. + gcvMACHINECODE_WAVESCAPE0 ,
  146745. + gcvMACHINECODE_WAVESCAPE1 ,
  146746. +
  146747. + gcvMACHINECODE_NENAMARKV2_4_0 ,
  146748. + gcvMACHINECODE_NENAMARKV2_4_1 ,
  146749. +
  146750. + gcvMACHINECODE_GLB25_RELEASE_0,
  146751. + gcvMACHINECODE_GLB25_RELEASE_1,
  146752. + gcvMACHINECODE_GLB25_RELEASE_2,
  146753. +}
  146754. +gceMACHINECODE;
  146755. +
  146756. +
  146757. +/******************************************************************************\
  146758. +****************************** Object Declarations *****************************
  146759. +\******************************************************************************/
  146760. +
  146761. +typedef struct _gckCONTEXT * gckCONTEXT;
  146762. +typedef struct _gcoCMDBUF * gcoCMDBUF;
  146763. +typedef struct _gcsSTATE_DELTA * gcsSTATE_DELTA_PTR;
  146764. +typedef struct _gcsQUEUE * gcsQUEUE_PTR;
  146765. +typedef struct _gcoQUEUE * gcoQUEUE;
  146766. +typedef struct _gcsHAL_INTERFACE * gcsHAL_INTERFACE_PTR;
  146767. +typedef struct _gcs2D_PROFILE * gcs2D_PROFILE_PTR;
  146768. +
  146769. +#if gcdENABLE_VG
  146770. +typedef struct _gcoVGHARDWARE * gcoVGHARDWARE;
  146771. +typedef struct _gcoVGBUFFER * gcoVGBUFFER;
  146772. +typedef struct _gckVGHARDWARE * gckVGHARDWARE;
  146773. +typedef struct _gcsVGCONTEXT * gcsVGCONTEXT_PTR;
  146774. +typedef struct _gcsVGCONTEXT_MAP * gcsVGCONTEXT_MAP_PTR;
  146775. +typedef struct _gcsVGCMDQUEUE * gcsVGCMDQUEUE_PTR;
  146776. +typedef struct _gcsTASK_MASTER_TABLE * gcsTASK_MASTER_TABLE_PTR;
  146777. +typedef struct _gckVGKERNEL * gckVGKERNEL;
  146778. +typedef void * gctTHREAD;
  146779. +#endif
  146780. +
  146781. +#ifdef __cplusplus
  146782. +}
  146783. +#endif
  146784. +
  146785. +#endif /* __gc_hal_enum_h_ */
  146786. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
  146787. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h 1970-01-01 01:00:00.000000000 +0100
  146788. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h 2014-08-20 19:31:46.132869024 +0200
  146789. @@ -0,0 +1,2661 @@
  146790. +/****************************************************************************
  146791. +*
  146792. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  146793. +*
  146794. +* This program is free software; you can redistribute it and/or modify
  146795. +* it under the terms of the GNU General Public License as published by
  146796. +* the Free Software Foundation; either version 2 of the license, or
  146797. +* (at your option) any later version.
  146798. +*
  146799. +* This program is distributed in the hope that it will be useful,
  146800. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  146801. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  146802. +* GNU General Public License for more details.
  146803. +*
  146804. +* You should have received a copy of the GNU General Public License
  146805. +* along with this program; if not write to the Free Software
  146806. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  146807. +*
  146808. +*****************************************************************************/
  146809. +
  146810. +
  146811. +#ifndef __gc_hal_h_
  146812. +#define __gc_hal_h_
  146813. +
  146814. +#include "gc_hal_rename.h"
  146815. +#include "gc_hal_types.h"
  146816. +#include "gc_hal_enum.h"
  146817. +#include "gc_hal_base.h"
  146818. +#include "gc_hal_profiler.h"
  146819. +#include "gc_hal_driver.h"
  146820. +#ifndef VIVANTE_NO_3D
  146821. +#include "gc_hal_statistics.h"
  146822. +#endif
  146823. +
  146824. +#ifdef __cplusplus
  146825. +extern "C" {
  146826. +#endif
  146827. +
  146828. +/******************************************************************************\
  146829. +******************************* Alignment Macros *******************************
  146830. +\******************************************************************************/
  146831. +
  146832. +#define gcmALIGN(n, align) \
  146833. +( \
  146834. + ((n) + ((align) - 1)) & ~((align) - 1) \
  146835. +)
  146836. +
  146837. +#define gcmALIGN_BASE(n, align) \
  146838. +( \
  146839. + ((n) & ~((align) - 1)) \
  146840. +)
  146841. +
  146842. +/******************************************************************************\
  146843. +***************************** Element Count Macro *****************************
  146844. +\******************************************************************************/
  146845. +
  146846. +#define gcmSIZEOF(a) \
  146847. +( \
  146848. + (gctSIZE_T) (sizeof(a)) \
  146849. +)
  146850. +
  146851. +#define gcmCOUNTOF(a) \
  146852. +( \
  146853. + sizeof(a) / sizeof(a[0]) \
  146854. +)
  146855. +
  146856. +/******************************************************************************\
  146857. +********************************* Cast Macro **********************************
  146858. +\******************************************************************************/
  146859. +#define gcmNAME_TO_PTR(na) \
  146860. + gckKERNEL_QueryPointerFromName(kernel, gcmALL_TO_UINT32(na))
  146861. +
  146862. +#define gcmPTR_TO_NAME(ptr) \
  146863. + gckKERNEL_AllocateNameFromPointer(kernel, ptr)
  146864. +
  146865. +#define gcmRELEASE_NAME(na) \
  146866. + gckKERNEL_DeleteName(kernel, gcmALL_TO_UINT32(na))
  146867. +
  146868. +#ifdef __LP64__
  146869. +
  146870. +#define gcmALL_TO_UINT32(t) \
  146871. +( \
  146872. + (gctUINT32) (gctUINTPTR_T) (t)\
  146873. +)
  146874. +
  146875. +#define gcmPTR_TO_UINT64(p) \
  146876. +( \
  146877. + (gctUINT64) (p)\
  146878. +)
  146879. +
  146880. +#define gcmUINT64_TO_PTR(u) \
  146881. +( \
  146882. + (gctPOINTER) (u)\
  146883. +)
  146884. +
  146885. +#else /* 32 bit */
  146886. +
  146887. +#define gcmALL_TO_UINT32(t) \
  146888. +( \
  146889. + (gctUINT32) (t)\
  146890. +)
  146891. +
  146892. +#define gcmPTR_TO_UINT64(p) \
  146893. +( \
  146894. + (gctUINT64) (gctUINTPTR_T) (p)\
  146895. +)
  146896. +
  146897. +#define gcmUINT64_TO_PTR(u) \
  146898. +( \
  146899. + (gctPOINTER) (gctUINTPTR_T) (u)\
  146900. +)
  146901. +
  146902. +#endif
  146903. +
  146904. +#define gcmUINT64_TO_TYPE(u, t) \
  146905. +( \
  146906. + (t) (gctUINTPTR_T) (u)\
  146907. +)
  146908. +
  146909. +/******************************************************************************\
  146910. +******************************** Useful Macro *********************************
  146911. +\******************************************************************************/
  146912. +
  146913. +#define gcvINVALID_ADDRESS ~0U
  146914. +
  146915. +#define gcmGET_PRE_ROTATION(rotate) \
  146916. + ((rotate) & (~(gcvSURF_POST_FLIP_X | gcvSURF_POST_FLIP_Y)))
  146917. +
  146918. +#define gcmGET_POST_ROTATION(rotate) \
  146919. + ((rotate) & (gcvSURF_POST_FLIP_X | gcvSURF_POST_FLIP_Y))
  146920. +
  146921. +/******************************************************************************\
  146922. +******************************** gcsOBJECT Object *******************************
  146923. +\******************************************************************************/
  146924. +
  146925. +/* Type of objects. */
  146926. +typedef enum _gceOBJECT_TYPE
  146927. +{
  146928. + gcvOBJ_UNKNOWN = 0,
  146929. + gcvOBJ_2D = gcmCC('2','D',' ',' '),
  146930. + gcvOBJ_3D = gcmCC('3','D',' ',' '),
  146931. + gcvOBJ_ATTRIBUTE = gcmCC('A','T','T','R'),
  146932. + gcvOBJ_BRUSHCACHE = gcmCC('B','R','U','$'),
  146933. + gcvOBJ_BRUSHNODE = gcmCC('B','R','U','n'),
  146934. + gcvOBJ_BRUSH = gcmCC('B','R','U','o'),
  146935. + gcvOBJ_BUFFER = gcmCC('B','U','F','R'),
  146936. + gcvOBJ_COMMAND = gcmCC('C','M','D',' '),
  146937. + gcvOBJ_COMMANDBUFFER = gcmCC('C','M','D','B'),
  146938. + gcvOBJ_CONTEXT = gcmCC('C','T','X','T'),
  146939. + gcvOBJ_DEVICE = gcmCC('D','E','V',' '),
  146940. + gcvOBJ_DUMP = gcmCC('D','U','M','P'),
  146941. + gcvOBJ_EVENT = gcmCC('E','V','N','T'),
  146942. + gcvOBJ_FUNCTION = gcmCC('F','U','N','C'),
  146943. + gcvOBJ_HAL = gcmCC('H','A','L',' '),
  146944. + gcvOBJ_HARDWARE = gcmCC('H','A','R','D'),
  146945. + gcvOBJ_HEAP = gcmCC('H','E','A','P'),
  146946. + gcvOBJ_INDEX = gcmCC('I','N','D','X'),
  146947. + gcvOBJ_INTERRUPT = gcmCC('I','N','T','R'),
  146948. + gcvOBJ_KERNEL = gcmCC('K','E','R','N'),
  146949. + gcvOBJ_KERNEL_FUNCTION = gcmCC('K','F','C','N'),
  146950. + gcvOBJ_MEMORYBUFFER = gcmCC('M','E','M','B'),
  146951. + gcvOBJ_MMU = gcmCC('M','M','U',' '),
  146952. + gcvOBJ_OS = gcmCC('O','S',' ',' '),
  146953. + gcvOBJ_OUTPUT = gcmCC('O','U','T','P'),
  146954. + gcvOBJ_PAINT = gcmCC('P','N','T',' '),
  146955. + gcvOBJ_PATH = gcmCC('P','A','T','H'),
  146956. + gcvOBJ_QUEUE = gcmCC('Q','U','E',' '),
  146957. + gcvOBJ_SAMPLER = gcmCC('S','A','M','P'),
  146958. + gcvOBJ_SHADER = gcmCC('S','H','D','R'),
  146959. + gcvOBJ_STREAM = gcmCC('S','T','R','M'),
  146960. + gcvOBJ_SURF = gcmCC('S','U','R','F'),
  146961. + gcvOBJ_TEXTURE = gcmCC('T','X','T','R'),
  146962. + gcvOBJ_UNIFORM = gcmCC('U','N','I','F'),
  146963. + gcvOBJ_VARIABLE = gcmCC('V','A','R','I'),
  146964. + gcvOBJ_VERTEX = gcmCC('V','R','T','X'),
  146965. + gcvOBJ_VIDMEM = gcmCC('V','M','E','M'),
  146966. + gcvOBJ_VG = gcmCC('V','G',' ',' '),
  146967. +}
  146968. +gceOBJECT_TYPE;
  146969. +
  146970. +/* gcsOBJECT object defintinon. */
  146971. +typedef struct _gcsOBJECT
  146972. +{
  146973. + /* Type of an object. */
  146974. + gceOBJECT_TYPE type;
  146975. +}
  146976. +gcsOBJECT;
  146977. +
  146978. +typedef struct _gckHARDWARE * gckHARDWARE;
  146979. +
  146980. +/* CORE flags. */
  146981. +typedef enum _gceCORE
  146982. +{
  146983. + gcvCORE_MAJOR = 0x0,
  146984. + gcvCORE_2D = 0x1,
  146985. + gcvCORE_VG = 0x2
  146986. +}
  146987. +gceCORE;
  146988. +
  146989. +#define gcdMAX_GPU_COUNT 3
  146990. +
  146991. +/*******************************************************************************
  146992. +**
  146993. +** gcmVERIFY_OBJECT
  146994. +**
  146995. +** Assert if an object is invalid or is not of the specified type. If the
  146996. +** object is invalid or not of the specified type, gcvSTATUS_INVALID_OBJECT
  146997. +** will be returned from the current function. In retail mode this macro
  146998. +** does nothing.
  146999. +**
  147000. +** ARGUMENTS:
  147001. +**
  147002. +** obj Object to test.
  147003. +** t Expected type of the object.
  147004. +*/
  147005. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  147006. +#define _gcmVERIFY_OBJECT(prefix, obj, t) \
  147007. + if ((obj) == gcvNULL) \
  147008. + { \
  147009. + prefix##TRACE(gcvLEVEL_ERROR, \
  147010. + #prefix "VERIFY_OBJECT failed: NULL"); \
  147011. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  147012. + gcmCC_PRINT(t)); \
  147013. + prefix##ASSERT((obj) != gcvNULL); \
  147014. + prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_OBJECT); \
  147015. + return gcvSTATUS_INVALID_OBJECT; \
  147016. + } \
  147017. + else if (((gcsOBJECT*) (obj))->type != t) \
  147018. + { \
  147019. + prefix##TRACE(gcvLEVEL_ERROR, \
  147020. + #prefix "VERIFY_OBJECT failed: %c%c%c%c", \
  147021. + gcmCC_PRINT(((gcsOBJECT*) (obj))->type)); \
  147022. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  147023. + gcmCC_PRINT(t)); \
  147024. + prefix##ASSERT(((gcsOBJECT*)(obj))->type == t); \
  147025. + prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_OBJECT); \
  147026. + return gcvSTATUS_INVALID_OBJECT; \
  147027. + }
  147028. +
  147029. +# define gcmVERIFY_OBJECT(obj, t) _gcmVERIFY_OBJECT(gcm, obj, t)
  147030. +# define gcmkVERIFY_OBJECT(obj, t) _gcmVERIFY_OBJECT(gcmk, obj, t)
  147031. +#else
  147032. +# define gcmVERIFY_OBJECT(obj, t) do {} while (gcvFALSE)
  147033. +# define gcmkVERIFY_OBJECT(obj, t) do {} while (gcvFALSE)
  147034. +#endif
  147035. +
  147036. +/******************************************************************************/
  147037. +/*VERIFY_OBJECT if special return expected*/
  147038. +/******************************************************************************/
  147039. +#ifndef EGL_API_ANDROID
  147040. +# define _gcmVERIFY_OBJECT_RETURN(prefix, obj, t, retVal) \
  147041. + do \
  147042. + { \
  147043. + if ((obj) == gcvNULL) \
  147044. + { \
  147045. + prefix##PRINT_VERSION(); \
  147046. + prefix##TRACE(gcvLEVEL_ERROR, \
  147047. + #prefix "VERIFY_OBJECT_RETURN failed: NULL"); \
  147048. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  147049. + gcmCC_PRINT(t)); \
  147050. + prefix##ASSERT((obj) != gcvNULL); \
  147051. + prefix##FOOTER_ARG("retVal=%d", retVal); \
  147052. + return retVal; \
  147053. + } \
  147054. + else if (((gcsOBJECT*) (obj))->type != t) \
  147055. + { \
  147056. + prefix##PRINT_VERSION(); \
  147057. + prefix##TRACE(gcvLEVEL_ERROR, \
  147058. + #prefix "VERIFY_OBJECT_RETURN failed: %c%c%c%c", \
  147059. + gcmCC_PRINT(((gcsOBJECT*) (obj))->type)); \
  147060. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  147061. + gcmCC_PRINT(t)); \
  147062. + prefix##ASSERT(((gcsOBJECT*)(obj))->type == t); \
  147063. + prefix##FOOTER_ARG("retVal=%d", retVal); \
  147064. + return retVal; \
  147065. + } \
  147066. + } \
  147067. + while (gcvFALSE)
  147068. +# define gcmVERIFY_OBJECT_RETURN(obj, t, retVal) \
  147069. + _gcmVERIFY_OBJECT_RETURN(gcm, obj, t, retVal)
  147070. +# define gcmkVERIFY_OBJECT_RETURN(obj, t, retVal) \
  147071. + _gcmVERIFY_OBJECT_RETURN(gcmk, obj, t, retVal)
  147072. +#else
  147073. +# define gcmVERIFY_OBJECT_RETURN(obj, t) do {} while (gcvFALSE)
  147074. +# define gcmVERIFY_OBJECT_RETURN(obj, t) do {} while (gcvFALSE)
  147075. +#endif
  147076. +
  147077. +/******************************************************************************\
  147078. +********************************** gckOS Object *********************************
  147079. +\******************************************************************************/
  147080. +
  147081. +/* Construct a new gckOS object. */
  147082. +gceSTATUS
  147083. +gckOS_Construct(
  147084. + IN gctPOINTER Context,
  147085. + OUT gckOS * Os
  147086. + );
  147087. +
  147088. +/* Destroy an gckOS object. */
  147089. +gceSTATUS
  147090. +gckOS_Destroy(
  147091. + IN gckOS Os
  147092. + );
  147093. +
  147094. +/* Query the video memory. */
  147095. +gceSTATUS
  147096. +gckOS_QueryVideoMemory(
  147097. + IN gckOS Os,
  147098. + OUT gctPHYS_ADDR * InternalAddress,
  147099. + OUT gctSIZE_T * InternalSize,
  147100. + OUT gctPHYS_ADDR * ExternalAddress,
  147101. + OUT gctSIZE_T * ExternalSize,
  147102. + OUT gctPHYS_ADDR * ContiguousAddress,
  147103. + OUT gctSIZE_T * ContiguousSize
  147104. + );
  147105. +
  147106. +/* Allocate memory from the heap. */
  147107. +gceSTATUS
  147108. +gckOS_Allocate(
  147109. + IN gckOS Os,
  147110. + IN gctSIZE_T Bytes,
  147111. + OUT gctPOINTER * Memory
  147112. + );
  147113. +
  147114. +/* Free allocated memory. */
  147115. +gceSTATUS
  147116. +gckOS_Free(
  147117. + IN gckOS Os,
  147118. + IN gctPOINTER Memory
  147119. + );
  147120. +
  147121. +/* Wrapper for allocation memory.. */
  147122. +gceSTATUS
  147123. +gckOS_AllocateMemory(
  147124. + IN gckOS Os,
  147125. + IN gctSIZE_T Bytes,
  147126. + OUT gctPOINTER * Memory
  147127. + );
  147128. +
  147129. +/* Wrapper for freeing memory. */
  147130. +gceSTATUS
  147131. +gckOS_FreeMemory(
  147132. + IN gckOS Os,
  147133. + IN gctPOINTER Memory
  147134. + );
  147135. +
  147136. +/* Allocate paged memory. */
  147137. +gceSTATUS
  147138. +gckOS_AllocatePagedMemory(
  147139. + IN gckOS Os,
  147140. + IN gctSIZE_T Bytes,
  147141. + OUT gctPHYS_ADDR * Physical
  147142. + );
  147143. +
  147144. +/* Allocate paged memory. */
  147145. +gceSTATUS
  147146. +gckOS_AllocatePagedMemoryEx(
  147147. + IN gckOS Os,
  147148. + IN gctBOOL Contiguous,
  147149. + IN gctSIZE_T Bytes,
  147150. + OUT gctPHYS_ADDR * Physical
  147151. + );
  147152. +
  147153. +/* Lock pages. */
  147154. +gceSTATUS
  147155. +gckOS_LockPages(
  147156. + IN gckOS Os,
  147157. + IN gctPHYS_ADDR Physical,
  147158. + IN gctSIZE_T Bytes,
  147159. + IN gctBOOL Cacheable,
  147160. + OUT gctPOINTER * Logical,
  147161. + OUT gctSIZE_T * PageCount
  147162. + );
  147163. +
  147164. +/* Map pages. */
  147165. +gceSTATUS
  147166. +gckOS_MapPages(
  147167. + IN gckOS Os,
  147168. + IN gctPHYS_ADDR Physical,
  147169. +#ifdef __QNXNTO__
  147170. + IN gctPOINTER Logical,
  147171. +#endif
  147172. + IN gctSIZE_T PageCount,
  147173. + IN gctPOINTER PageTable
  147174. + );
  147175. +
  147176. +/* Map pages. */
  147177. +gceSTATUS
  147178. +gckOS_MapPagesEx(
  147179. + IN gckOS Os,
  147180. + IN gceCORE Core,
  147181. + IN gctPHYS_ADDR Physical,
  147182. +#ifdef __QNXNTO__
  147183. + IN gctPOINTER Logical,
  147184. +#endif
  147185. + IN gctSIZE_T PageCount,
  147186. + IN gctPOINTER PageTable
  147187. + );
  147188. +
  147189. +/* Unlock pages. */
  147190. +gceSTATUS
  147191. +gckOS_UnlockPages(
  147192. + IN gckOS Os,
  147193. + IN gctPHYS_ADDR Physical,
  147194. + IN gctSIZE_T Bytes,
  147195. + IN gctPOINTER Logical
  147196. + );
  147197. +
  147198. +/* Free paged memory. */
  147199. +gceSTATUS
  147200. +gckOS_FreePagedMemory(
  147201. + IN gckOS Os,
  147202. + IN gctPHYS_ADDR Physical,
  147203. + IN gctSIZE_T Bytes
  147204. + );
  147205. +
  147206. +/* Allocate non-paged memory. */
  147207. +gceSTATUS
  147208. +gckOS_AllocateNonPagedMemory(
  147209. + IN gckOS Os,
  147210. + IN gctBOOL InUserSpace,
  147211. + IN OUT gctSIZE_T * Bytes,
  147212. + OUT gctPHYS_ADDR * Physical,
  147213. + OUT gctPOINTER * Logical
  147214. + );
  147215. +
  147216. +/* Free non-paged memory. */
  147217. +gceSTATUS
  147218. +gckOS_FreeNonPagedMemory(
  147219. + IN gckOS Os,
  147220. + IN gctSIZE_T Bytes,
  147221. + IN gctPHYS_ADDR Physical,
  147222. + IN gctPOINTER Logical
  147223. + );
  147224. +
  147225. +/* Allocate contiguous memory. */
  147226. +gceSTATUS
  147227. +gckOS_AllocateContiguous(
  147228. + IN gckOS Os,
  147229. + IN gctBOOL InUserSpace,
  147230. + IN OUT gctSIZE_T * Bytes,
  147231. + OUT gctPHYS_ADDR * Physical,
  147232. + OUT gctPOINTER * Logical
  147233. + );
  147234. +
  147235. +/* Free contiguous memory. */
  147236. +gceSTATUS
  147237. +gckOS_FreeContiguous(
  147238. + IN gckOS Os,
  147239. + IN gctPHYS_ADDR Physical,
  147240. + IN gctPOINTER Logical,
  147241. + IN gctSIZE_T Bytes
  147242. + );
  147243. +
  147244. +/* Get the number fo bytes per page. */
  147245. +gceSTATUS
  147246. +gckOS_GetPageSize(
  147247. + IN gckOS Os,
  147248. + OUT gctSIZE_T * PageSize
  147249. + );
  147250. +
  147251. +/* Get the physical address of a corresponding logical address. */
  147252. +gceSTATUS
  147253. +gckOS_GetPhysicalAddress(
  147254. + IN gckOS Os,
  147255. + IN gctPOINTER Logical,
  147256. + OUT gctUINT32 * Address
  147257. + );
  147258. +
  147259. +/* Get the physical address of a corresponding logical address. */
  147260. +gceSTATUS
  147261. +gckOS_GetPhysicalAddressProcess(
  147262. + IN gckOS Os,
  147263. + IN gctPOINTER Logical,
  147264. + IN gctUINT32 ProcessID,
  147265. + OUT gctUINT32 * Address
  147266. + );
  147267. +
  147268. +/* Map physical memory. */
  147269. +gceSTATUS
  147270. +gckOS_MapPhysical(
  147271. + IN gckOS Os,
  147272. + IN gctUINT32 Physical,
  147273. + IN gctSIZE_T Bytes,
  147274. + OUT gctPOINTER * Logical
  147275. + );
  147276. +
  147277. +/* Unmap previously mapped physical memory. */
  147278. +gceSTATUS
  147279. +gckOS_UnmapPhysical(
  147280. + IN gckOS Os,
  147281. + IN gctPOINTER Logical,
  147282. + IN gctSIZE_T Bytes
  147283. + );
  147284. +
  147285. +/* Read data from a hardware register. */
  147286. +gceSTATUS
  147287. +gckOS_ReadRegister(
  147288. + IN gckOS Os,
  147289. + IN gctUINT32 Address,
  147290. + OUT gctUINT32 * Data
  147291. + );
  147292. +
  147293. +/* Read data from a hardware register. */
  147294. +gceSTATUS
  147295. +gckOS_ReadRegisterEx(
  147296. + IN gckOS Os,
  147297. + IN gceCORE Core,
  147298. + IN gctUINT32 Address,
  147299. + OUT gctUINT32 * Data
  147300. + );
  147301. +
  147302. +/* Write data to a hardware register. */
  147303. +gceSTATUS
  147304. +gckOS_WriteRegister(
  147305. + IN gckOS Os,
  147306. + IN gctUINT32 Address,
  147307. + IN gctUINT32 Data
  147308. + );
  147309. +
  147310. +/* Write data to a hardware register. */
  147311. +gceSTATUS
  147312. +gckOS_WriteRegisterEx(
  147313. + IN gckOS Os,
  147314. + IN gceCORE Core,
  147315. + IN gctUINT32 Address,
  147316. + IN gctUINT32 Data
  147317. + );
  147318. +
  147319. +/* Write data to a 32-bit memory location. */
  147320. +gceSTATUS
  147321. +gckOS_WriteMemory(
  147322. + IN gckOS Os,
  147323. + IN gctPOINTER Address,
  147324. + IN gctUINT32 Data
  147325. + );
  147326. +
  147327. +/* Map physical memory into the process space. */
  147328. +gceSTATUS
  147329. +gckOS_MapMemory(
  147330. + IN gckOS Os,
  147331. + IN gctPHYS_ADDR Physical,
  147332. + IN gctSIZE_T Bytes,
  147333. + OUT gctPOINTER * Logical
  147334. + );
  147335. +
  147336. +/* Unmap physical memory from the specified process space. */
  147337. +gceSTATUS
  147338. +gckOS_UnmapMemoryEx(
  147339. + IN gckOS Os,
  147340. + IN gctPHYS_ADDR Physical,
  147341. + IN gctSIZE_T Bytes,
  147342. + IN gctPOINTER Logical,
  147343. + IN gctUINT32 PID
  147344. + );
  147345. +
  147346. +/* Unmap physical memory from the process space. */
  147347. +gceSTATUS
  147348. +gckOS_UnmapMemory(
  147349. + IN gckOS Os,
  147350. + IN gctPHYS_ADDR Physical,
  147351. + IN gctSIZE_T Bytes,
  147352. + IN gctPOINTER Logical
  147353. + );
  147354. +
  147355. +/* Unmap user logical memory out of physical memory.
  147356. + * This function is only supported in Linux currently.
  147357. + */
  147358. +gceSTATUS
  147359. +gckOS_UnmapUserLogical(
  147360. + IN gckOS Os,
  147361. + IN gctPHYS_ADDR Physical,
  147362. + IN gctSIZE_T Bytes,
  147363. + IN gctPOINTER Logical
  147364. + );
  147365. +
  147366. +/* Create a new mutex. */
  147367. +gceSTATUS
  147368. +gckOS_CreateMutex(
  147369. + IN gckOS Os,
  147370. + OUT gctPOINTER * Mutex
  147371. + );
  147372. +
  147373. +/* Delete a mutex. */
  147374. +gceSTATUS
  147375. +gckOS_DeleteMutex(
  147376. + IN gckOS Os,
  147377. + IN gctPOINTER Mutex
  147378. + );
  147379. +
  147380. +/* Acquire a mutex. */
  147381. +gceSTATUS
  147382. +gckOS_AcquireMutex(
  147383. + IN gckOS Os,
  147384. + IN gctPOINTER Mutex,
  147385. + IN gctUINT32 Timeout
  147386. + );
  147387. +
  147388. +/* Release a mutex. */
  147389. +gceSTATUS
  147390. +gckOS_ReleaseMutex(
  147391. + IN gckOS Os,
  147392. + IN gctPOINTER Mutex
  147393. + );
  147394. +
  147395. +/* Atomically exchange a pair of 32-bit values. */
  147396. +gceSTATUS
  147397. +gckOS_AtomicExchange(
  147398. + IN gckOS Os,
  147399. + IN OUT gctUINT32_PTR Target,
  147400. + IN gctUINT32 NewValue,
  147401. + OUT gctUINT32_PTR OldValue
  147402. + );
  147403. +
  147404. +/* Atomically exchange a pair of pointers. */
  147405. +gceSTATUS
  147406. +gckOS_AtomicExchangePtr(
  147407. + IN gckOS Os,
  147408. + IN OUT gctPOINTER * Target,
  147409. + IN gctPOINTER NewValue,
  147410. + OUT gctPOINTER * OldValue
  147411. + );
  147412. +
  147413. +#if gcdSMP
  147414. +gceSTATUS
  147415. +gckOS_AtomSetMask(
  147416. + IN gctPOINTER Atom,
  147417. + IN gctUINT32 Mask
  147418. + );
  147419. +
  147420. +gceSTATUS
  147421. +gckOS_AtomClearMask(
  147422. + IN gctPOINTER Atom,
  147423. + IN gctUINT32 Mask
  147424. + );
  147425. +#endif
  147426. +
  147427. +gceSTATUS
  147428. +gckOS_DumpCallStack(
  147429. + IN gckOS Os
  147430. + );
  147431. +
  147432. +gceSTATUS
  147433. +gckOS_GetProcessNameByPid(
  147434. + IN gctINT Pid,
  147435. + IN gctSIZE_T Length,
  147436. + OUT gctUINT8_PTR String
  147437. + );
  147438. +
  147439. +
  147440. +
  147441. +/*******************************************************************************
  147442. +**
  147443. +** gckOS_AtomConstruct
  147444. +**
  147445. +** Create an atom.
  147446. +**
  147447. +** INPUT:
  147448. +**
  147449. +** gckOS Os
  147450. +** Pointer to a gckOS object.
  147451. +**
  147452. +** OUTPUT:
  147453. +**
  147454. +** gctPOINTER * Atom
  147455. +** Pointer to a variable receiving the constructed atom.
  147456. +*/
  147457. +gceSTATUS
  147458. +gckOS_AtomConstruct(
  147459. + IN gckOS Os,
  147460. + OUT gctPOINTER * Atom
  147461. + );
  147462. +
  147463. +/*******************************************************************************
  147464. +**
  147465. +** gckOS_AtomDestroy
  147466. +**
  147467. +** Destroy an atom.
  147468. +**
  147469. +** INPUT:
  147470. +**
  147471. +** gckOS Os
  147472. +** Pointer to a gckOS object.
  147473. +**
  147474. +** gctPOINTER Atom
  147475. +** Pointer to the atom to destroy.
  147476. +**
  147477. +** OUTPUT:
  147478. +**
  147479. +** Nothing.
  147480. +*/
  147481. +gceSTATUS
  147482. +gckOS_AtomDestroy(
  147483. + IN gckOS Os,
  147484. + OUT gctPOINTER Atom
  147485. + );
  147486. +
  147487. +/*******************************************************************************
  147488. +**
  147489. +** gckOS_AtomGet
  147490. +**
  147491. +** Get the 32-bit value protected by an atom.
  147492. +**
  147493. +** INPUT:
  147494. +**
  147495. +** gckOS Os
  147496. +** Pointer to a gckOS object.
  147497. +**
  147498. +** gctPOINTER Atom
  147499. +** Pointer to the atom.
  147500. +**
  147501. +** OUTPUT:
  147502. +**
  147503. +** gctINT32_PTR Value
  147504. +** Pointer to a variable the receives the value of the atom.
  147505. +*/
  147506. +gceSTATUS
  147507. +gckOS_AtomGet(
  147508. + IN gckOS Os,
  147509. + IN gctPOINTER Atom,
  147510. + OUT gctINT32_PTR Value
  147511. + );
  147512. +
  147513. +/*******************************************************************************
  147514. +**
  147515. +** gckOS_AtomSet
  147516. +**
  147517. +** Set the 32-bit value protected by an atom.
  147518. +**
  147519. +** INPUT:
  147520. +**
  147521. +** gckOS Os
  147522. +** Pointer to a gckOS object.
  147523. +**
  147524. +** gctPOINTER Atom
  147525. +** Pointer to the atom.
  147526. +**
  147527. +** gctINT32 Value
  147528. +** The value of the atom.
  147529. +**
  147530. +** OUTPUT:
  147531. +**
  147532. +** Nothing.
  147533. +*/
  147534. +gceSTATUS
  147535. +gckOS_AtomSet(
  147536. + IN gckOS Os,
  147537. + IN gctPOINTER Atom,
  147538. + IN gctINT32 Value
  147539. + );
  147540. +
  147541. +/*******************************************************************************
  147542. +**
  147543. +** gckOS_AtomIncrement
  147544. +**
  147545. +** Atomically increment the 32-bit integer value inside an atom.
  147546. +**
  147547. +** INPUT:
  147548. +**
  147549. +** gckOS Os
  147550. +** Pointer to a gckOS object.
  147551. +**
  147552. +** gctPOINTER Atom
  147553. +** Pointer to the atom.
  147554. +**
  147555. +** OUTPUT:
  147556. +**
  147557. +** gctINT32_PTR Value
  147558. +** Pointer to a variable the receives the original value of the atom.
  147559. +*/
  147560. +gceSTATUS
  147561. +gckOS_AtomIncrement(
  147562. + IN gckOS Os,
  147563. + IN gctPOINTER Atom,
  147564. + OUT gctINT32_PTR Value
  147565. + );
  147566. +
  147567. +/*******************************************************************************
  147568. +**
  147569. +** gckOS_AtomDecrement
  147570. +**
  147571. +** Atomically decrement the 32-bit integer value inside an atom.
  147572. +**
  147573. +** INPUT:
  147574. +**
  147575. +** gckOS Os
  147576. +** Pointer to a gckOS object.
  147577. +**
  147578. +** gctPOINTER Atom
  147579. +** Pointer to the atom.
  147580. +**
  147581. +** OUTPUT:
  147582. +**
  147583. +** gctINT32_PTR Value
  147584. +** Pointer to a variable the receives the original value of the atom.
  147585. +*/
  147586. +gceSTATUS
  147587. +gckOS_AtomDecrement(
  147588. + IN gckOS Os,
  147589. + IN gctPOINTER Atom,
  147590. + OUT gctINT32_PTR Value
  147591. + );
  147592. +
  147593. +/* Delay a number of microseconds. */
  147594. +gceSTATUS
  147595. +gckOS_Delay(
  147596. + IN gckOS Os,
  147597. + IN gctUINT32 Delay
  147598. + );
  147599. +
  147600. +/* Get time in milliseconds. */
  147601. +gceSTATUS
  147602. +gckOS_GetTicks(
  147603. + OUT gctUINT32_PTR Time
  147604. + );
  147605. +
  147606. +/* Compare time value. */
  147607. +gceSTATUS
  147608. +gckOS_TicksAfter(
  147609. + IN gctUINT32 Time1,
  147610. + IN gctUINT32 Time2,
  147611. + OUT gctBOOL_PTR IsAfter
  147612. + );
  147613. +
  147614. +/* Get time in microseconds. */
  147615. +gceSTATUS
  147616. +gckOS_GetTime(
  147617. + OUT gctUINT64_PTR Time
  147618. + );
  147619. +
  147620. +/* Memory barrier. */
  147621. +gceSTATUS
  147622. +gckOS_MemoryBarrier(
  147623. + IN gckOS Os,
  147624. + IN gctPOINTER Address
  147625. + );
  147626. +
  147627. +/* Map user pointer. */
  147628. +gceSTATUS
  147629. +gckOS_MapUserPointer(
  147630. + IN gckOS Os,
  147631. + IN gctPOINTER Pointer,
  147632. + IN gctSIZE_T Size,
  147633. + OUT gctPOINTER * KernelPointer
  147634. + );
  147635. +
  147636. +/* Unmap user pointer. */
  147637. +gceSTATUS
  147638. +gckOS_UnmapUserPointer(
  147639. + IN gckOS Os,
  147640. + IN gctPOINTER Pointer,
  147641. + IN gctSIZE_T Size,
  147642. + IN gctPOINTER KernelPointer
  147643. + );
  147644. +
  147645. +/*******************************************************************************
  147646. +**
  147647. +** gckOS_QueryNeedCopy
  147648. +**
  147649. +** Query whether the memory can be accessed or mapped directly or it has to be
  147650. +** copied.
  147651. +**
  147652. +** INPUT:
  147653. +**
  147654. +** gckOS Os
  147655. +** Pointer to an gckOS object.
  147656. +**
  147657. +** gctUINT32 ProcessID
  147658. +** Process ID of the current process.
  147659. +**
  147660. +** OUTPUT:
  147661. +**
  147662. +** gctBOOL_PTR NeedCopy
  147663. +** Pointer to a boolean receiving gcvTRUE if the memory needs a copy or
  147664. +** gcvFALSE if the memory can be accessed or mapped dircetly.
  147665. +*/
  147666. +gceSTATUS
  147667. +gckOS_QueryNeedCopy(
  147668. + IN gckOS Os,
  147669. + IN gctUINT32 ProcessID,
  147670. + OUT gctBOOL_PTR NeedCopy
  147671. + );
  147672. +
  147673. +/*******************************************************************************
  147674. +**
  147675. +** gckOS_CopyFromUserData
  147676. +**
  147677. +** Copy data from user to kernel memory.
  147678. +**
  147679. +** INPUT:
  147680. +**
  147681. +** gckOS Os
  147682. +** Pointer to an gckOS object.
  147683. +**
  147684. +** gctPOINTER KernelPointer
  147685. +** Pointer to kernel memory.
  147686. +**
  147687. +** gctPOINTER Pointer
  147688. +** Pointer to user memory.
  147689. +**
  147690. +** gctSIZE_T Size
  147691. +** Number of bytes to copy.
  147692. +**
  147693. +** OUTPUT:
  147694. +**
  147695. +** Nothing.
  147696. +*/
  147697. +gceSTATUS
  147698. +gckOS_CopyFromUserData(
  147699. + IN gckOS Os,
  147700. + IN gctPOINTER KernelPointer,
  147701. + IN gctPOINTER Pointer,
  147702. + IN gctSIZE_T Size
  147703. + );
  147704. +
  147705. +/*******************************************************************************
  147706. +**
  147707. +** gckOS_CopyToUserData
  147708. +**
  147709. +** Copy data from kernel to user memory.
  147710. +**
  147711. +** INPUT:
  147712. +**
  147713. +** gckOS Os
  147714. +** Pointer to an gckOS object.
  147715. +**
  147716. +** gctPOINTER KernelPointer
  147717. +** Pointer to kernel memory.
  147718. +**
  147719. +** gctPOINTER Pointer
  147720. +** Pointer to user memory.
  147721. +**
  147722. +** gctSIZE_T Size
  147723. +** Number of bytes to copy.
  147724. +**
  147725. +** OUTPUT:
  147726. +**
  147727. +** Nothing.
  147728. +*/
  147729. +gceSTATUS
  147730. +gckOS_CopyToUserData(
  147731. + IN gckOS Os,
  147732. + IN gctPOINTER KernelPointer,
  147733. + IN gctPOINTER Pointer,
  147734. + IN gctSIZE_T Size
  147735. + );
  147736. +
  147737. +#ifdef __QNXNTO__
  147738. +/* Map user physical address. */
  147739. +gceSTATUS
  147740. +gckOS_MapUserPhysical(
  147741. + IN gckOS Os,
  147742. + IN gctPHYS_ADDR Phys,
  147743. + OUT gctPOINTER * KernelPointer
  147744. + );
  147745. +#endif
  147746. +
  147747. +gceSTATUS
  147748. +gckOS_SuspendInterrupt(
  147749. + IN gckOS Os
  147750. + );
  147751. +
  147752. +gceSTATUS
  147753. +gckOS_SuspendInterruptEx(
  147754. + IN gckOS Os,
  147755. + IN gceCORE Core
  147756. + );
  147757. +
  147758. +gceSTATUS
  147759. +gckOS_ResumeInterrupt(
  147760. + IN gckOS Os
  147761. + );
  147762. +
  147763. +gceSTATUS
  147764. +gckOS_ResumeInterruptEx(
  147765. + IN gckOS Os,
  147766. + IN gceCORE Core
  147767. + );
  147768. +
  147769. +/* Get the base address for the physical memory. */
  147770. +gceSTATUS
  147771. +gckOS_GetBaseAddress(
  147772. + IN gckOS Os,
  147773. + OUT gctUINT32_PTR BaseAddress
  147774. + );
  147775. +
  147776. +/* Perform a memory copy. */
  147777. +gceSTATUS
  147778. +gckOS_MemCopy(
  147779. + IN gctPOINTER Destination,
  147780. + IN gctCONST_POINTER Source,
  147781. + IN gctSIZE_T Bytes
  147782. + );
  147783. +
  147784. +/* Zero memory. */
  147785. +gceSTATUS
  147786. +gckOS_ZeroMemory(
  147787. + IN gctPOINTER Memory,
  147788. + IN gctSIZE_T Bytes
  147789. + );
  147790. +
  147791. +/* Device I/O control to the kernel HAL layer. */
  147792. +gceSTATUS
  147793. +gckOS_DeviceControl(
  147794. + IN gckOS Os,
  147795. + IN gctBOOL FromUser,
  147796. + IN gctUINT32 IoControlCode,
  147797. + IN gctPOINTER InputBuffer,
  147798. + IN gctSIZE_T InputBufferSize,
  147799. + OUT gctPOINTER OutputBuffer,
  147800. + IN gctSIZE_T OutputBufferSize
  147801. + );
  147802. +
  147803. +/*******************************************************************************
  147804. +**
  147805. +** gckOS_GetProcessID
  147806. +**
  147807. +** Get current process ID.
  147808. +**
  147809. +** INPUT:
  147810. +**
  147811. +** Nothing.
  147812. +**
  147813. +** OUTPUT:
  147814. +**
  147815. +** gctUINT32_PTR ProcessID
  147816. +** Pointer to the variable that receives the process ID.
  147817. +*/
  147818. +gceSTATUS
  147819. +gckOS_GetProcessID(
  147820. + OUT gctUINT32_PTR ProcessID
  147821. + );
  147822. +
  147823. +gceSTATUS
  147824. +gckOS_GetCurrentProcessID(
  147825. + OUT gctUINT32_PTR ProcessID
  147826. + );
  147827. +
  147828. +/*******************************************************************************
  147829. +**
  147830. +** gckOS_GetThreadID
  147831. +**
  147832. +** Get current thread ID.
  147833. +**
  147834. +** INPUT:
  147835. +**
  147836. +** Nothing.
  147837. +**
  147838. +** OUTPUT:
  147839. +**
  147840. +** gctUINT32_PTR ThreadID
  147841. +** Pointer to the variable that receives the thread ID.
  147842. +*/
  147843. +gceSTATUS
  147844. +gckOS_GetThreadID(
  147845. + OUT gctUINT32_PTR ThreadID
  147846. + );
  147847. +
  147848. +/******************************************************************************\
  147849. +********************************** Signal Object *********************************
  147850. +\******************************************************************************/
  147851. +
  147852. +/* Create a signal. */
  147853. +gceSTATUS
  147854. +gckOS_CreateSignal(
  147855. + IN gckOS Os,
  147856. + IN gctBOOL ManualReset,
  147857. + OUT gctSIGNAL * Signal
  147858. + );
  147859. +
  147860. +/* Destroy a signal. */
  147861. +gceSTATUS
  147862. +gckOS_DestroySignal(
  147863. + IN gckOS Os,
  147864. + IN gctSIGNAL Signal
  147865. + );
  147866. +
  147867. +/* Signal a signal. */
  147868. +gceSTATUS
  147869. +gckOS_Signal(
  147870. + IN gckOS Os,
  147871. + IN gctSIGNAL Signal,
  147872. + IN gctBOOL State
  147873. + );
  147874. +
  147875. +/* Wait for a signal. */
  147876. +gceSTATUS
  147877. +gckOS_WaitSignal(
  147878. + IN gckOS Os,
  147879. + IN gctSIGNAL Signal,
  147880. + IN gctUINT32 Wait
  147881. + );
  147882. +
  147883. +/* Map a user signal to the kernel space. */
  147884. +gceSTATUS
  147885. +gckOS_MapSignal(
  147886. + IN gckOS Os,
  147887. + IN gctSIGNAL Signal,
  147888. + IN gctHANDLE Process,
  147889. + OUT gctSIGNAL * MappedSignal
  147890. + );
  147891. +
  147892. +/* Unmap a user signal */
  147893. +gceSTATUS
  147894. +gckOS_UnmapSignal(
  147895. + IN gckOS Os,
  147896. + IN gctSIGNAL Signal
  147897. + );
  147898. +
  147899. +/* Map user memory. */
  147900. +gceSTATUS
  147901. +gckOS_MapUserMemory(
  147902. + IN gckOS Os,
  147903. + IN gceCORE Core,
  147904. + IN gctPOINTER Memory,
  147905. + IN gctUINT32 Physical,
  147906. + IN gctSIZE_T Size,
  147907. + OUT gctPOINTER * Info,
  147908. + OUT gctUINT32_PTR Address
  147909. + );
  147910. +
  147911. +/* Unmap user memory. */
  147912. +gceSTATUS
  147913. +gckOS_UnmapUserMemory(
  147914. + IN gckOS Os,
  147915. + IN gceCORE Core,
  147916. + IN gctPOINTER Memory,
  147917. + IN gctSIZE_T Size,
  147918. + IN gctPOINTER Info,
  147919. + IN gctUINT32 Address
  147920. + );
  147921. +
  147922. +/******************************************************************************\
  147923. +************************** Android Native Fence Sync ***************************
  147924. +\******************************************************************************/
  147925. +gceSTATUS
  147926. +gckOS_CreateSyncTimeline(
  147927. + IN gckOS Os,
  147928. + OUT gctHANDLE * Timeline
  147929. + );
  147930. +
  147931. +gceSTATUS
  147932. +gckOS_DestroySyncTimeline(
  147933. + IN gckOS Os,
  147934. + IN gctHANDLE Timeline
  147935. + );
  147936. +
  147937. +gceSTATUS
  147938. +gckOS_CreateSyncPoint(
  147939. + IN gckOS Os,
  147940. + OUT gctSYNC_POINT * SyncPoint
  147941. + );
  147942. +
  147943. +gceSTATUS
  147944. +gckOS_ReferenceSyncPoint(
  147945. + IN gckOS Os,
  147946. + IN gctSYNC_POINT SyncPoint
  147947. + );
  147948. +
  147949. +gceSTATUS
  147950. +gckOS_DestroySyncPoint(
  147951. + IN gckOS Os,
  147952. + IN gctSYNC_POINT SyncPoint
  147953. + );
  147954. +
  147955. +gceSTATUS
  147956. +gckOS_SignalSyncPoint(
  147957. + IN gckOS Os,
  147958. + IN gctSYNC_POINT SyncPoint
  147959. + );
  147960. +
  147961. +gceSTATUS
  147962. +gckOS_QuerySyncPoint(
  147963. + IN gckOS Os,
  147964. + IN gctSYNC_POINT SyncPoint,
  147965. + OUT gctBOOL_PTR State
  147966. + );
  147967. +
  147968. +gceSTATUS
  147969. +gckOS_CreateNativeFence(
  147970. + IN gckOS Os,
  147971. + IN gctHANDLE Timeline,
  147972. + IN gctSYNC_POINT SyncPoint,
  147973. + OUT gctINT * FenceFD
  147974. + );
  147975. +
  147976. +#if !USE_NEW_LINUX_SIGNAL
  147977. +/* Create signal to be used in the user space. */
  147978. +gceSTATUS
  147979. +gckOS_CreateUserSignal(
  147980. + IN gckOS Os,
  147981. + IN gctBOOL ManualReset,
  147982. + OUT gctINT * SignalID
  147983. + );
  147984. +
  147985. +/* Destroy signal used in the user space. */
  147986. +gceSTATUS
  147987. +gckOS_DestroyUserSignal(
  147988. + IN gckOS Os,
  147989. + IN gctINT SignalID
  147990. + );
  147991. +
  147992. +/* Wait for signal used in the user space. */
  147993. +gceSTATUS
  147994. +gckOS_WaitUserSignal(
  147995. + IN gckOS Os,
  147996. + IN gctINT SignalID,
  147997. + IN gctUINT32 Wait
  147998. + );
  147999. +
  148000. +/* Signal a signal used in the user space. */
  148001. +gceSTATUS
  148002. +gckOS_SignalUserSignal(
  148003. + IN gckOS Os,
  148004. + IN gctINT SignalID,
  148005. + IN gctBOOL State
  148006. + );
  148007. +#endif /* USE_NEW_LINUX_SIGNAL */
  148008. +
  148009. +/* Set a signal owned by a process. */
  148010. +#if defined(__QNXNTO__)
  148011. +gceSTATUS
  148012. +gckOS_UserSignal(
  148013. + IN gckOS Os,
  148014. + IN gctSIGNAL Signal,
  148015. + IN gctINT Recvid,
  148016. + IN gctINT Coid
  148017. + );
  148018. +#else
  148019. +gceSTATUS
  148020. +gckOS_UserSignal(
  148021. + IN gckOS Os,
  148022. + IN gctSIGNAL Signal,
  148023. + IN gctHANDLE Process
  148024. + );
  148025. +#endif
  148026. +
  148027. +/******************************************************************************\
  148028. +** Cache Support
  148029. +*/
  148030. +
  148031. +gceSTATUS
  148032. +gckOS_CacheClean(
  148033. + gckOS Os,
  148034. + gctUINT32 ProcessID,
  148035. + gctPHYS_ADDR Handle,
  148036. + gctPOINTER Physical,
  148037. + gctPOINTER Logical,
  148038. + gctSIZE_T Bytes
  148039. + );
  148040. +
  148041. +gceSTATUS
  148042. +gckOS_CacheFlush(
  148043. + gckOS Os,
  148044. + gctUINT32 ProcessID,
  148045. + gctPHYS_ADDR Handle,
  148046. + gctPOINTER Physical,
  148047. + gctPOINTER Logical,
  148048. + gctSIZE_T Bytes
  148049. + );
  148050. +
  148051. +gceSTATUS
  148052. +gckOS_CacheInvalidate(
  148053. + gckOS Os,
  148054. + gctUINT32 ProcessID,
  148055. + gctPHYS_ADDR Handle,
  148056. + gctPOINTER Physical,
  148057. + gctPOINTER Logical,
  148058. + gctSIZE_T Bytes
  148059. + );
  148060. +
  148061. +/******************************************************************************\
  148062. +** Debug Support
  148063. +*/
  148064. +
  148065. +void
  148066. +gckOS_SetDebugLevel(
  148067. + IN gctUINT32 Level
  148068. + );
  148069. +
  148070. +void
  148071. +gckOS_SetDebugZone(
  148072. + IN gctUINT32 Zone
  148073. + );
  148074. +
  148075. +void
  148076. +gckOS_SetDebugLevelZone(
  148077. + IN gctUINT32 Level,
  148078. + IN gctUINT32 Zone
  148079. + );
  148080. +
  148081. +void
  148082. +gckOS_SetDebugZones(
  148083. + IN gctUINT32 Zones,
  148084. + IN gctBOOL Enable
  148085. + );
  148086. +
  148087. +void
  148088. +gckOS_SetDebugFile(
  148089. + IN gctCONST_STRING FileName
  148090. + );
  148091. +
  148092. +/*******************************************************************************
  148093. +** Broadcast interface.
  148094. +*/
  148095. +
  148096. +typedef enum _gceBROADCAST
  148097. +{
  148098. + /* GPU might be idle. */
  148099. + gcvBROADCAST_GPU_IDLE,
  148100. +
  148101. + /* A commit is going to happen. */
  148102. + gcvBROADCAST_GPU_COMMIT,
  148103. +
  148104. + /* GPU seems to be stuck. */
  148105. + gcvBROADCAST_GPU_STUCK,
  148106. +
  148107. + /* First process gets attached. */
  148108. + gcvBROADCAST_FIRST_PROCESS,
  148109. +
  148110. + /* Last process gets detached. */
  148111. + gcvBROADCAST_LAST_PROCESS,
  148112. +
  148113. + /* AXI bus error. */
  148114. + gcvBROADCAST_AXI_BUS_ERROR,
  148115. +}
  148116. +gceBROADCAST;
  148117. +
  148118. +gceSTATUS
  148119. +gckOS_Broadcast(
  148120. + IN gckOS Os,
  148121. + IN gckHARDWARE Hardware,
  148122. + IN gceBROADCAST Reason
  148123. + );
  148124. +
  148125. +gceSTATUS
  148126. +gckOS_BroadcastHurry(
  148127. + IN gckOS Os,
  148128. + IN gckHARDWARE Hardware,
  148129. + IN gctUINT Urgency
  148130. + );
  148131. +
  148132. +gceSTATUS
  148133. +gckOS_BroadcastCalibrateSpeed(
  148134. + IN gckOS Os,
  148135. + IN gckHARDWARE Hardware,
  148136. + IN gctUINT Idle,
  148137. + IN gctUINT Time
  148138. + );
  148139. +
  148140. +/*******************************************************************************
  148141. +**
  148142. +** gckOS_SetGPUPower
  148143. +**
  148144. +** Set the power of the GPU on or off.
  148145. +**
  148146. +** INPUT:
  148147. +**
  148148. +** gckOS Os
  148149. +** Pointer to a gckOS object.ß
  148150. +**
  148151. +** gckCORE Core
  148152. +** GPU whose power is set.
  148153. +**
  148154. +** gctBOOL Clock
  148155. +** gcvTRUE to turn on the clock, or gcvFALSE to turn off the clock.
  148156. +**
  148157. +** gctBOOL Power
  148158. +** gcvTRUE to turn on the power, or gcvFALSE to turn off the power.
  148159. +**
  148160. +** OUTPUT:
  148161. +**
  148162. +** Nothing.
  148163. +*/
  148164. +gceSTATUS
  148165. +gckOS_SetGPUPower(
  148166. + IN gckOS Os,
  148167. + IN gceCORE Core,
  148168. + IN gctBOOL Clock,
  148169. + IN gctBOOL Power
  148170. + );
  148171. +
  148172. +gceSTATUS
  148173. +gckOS_ResetGPU(
  148174. + IN gckOS Os,
  148175. + IN gceCORE Core
  148176. + );
  148177. +
  148178. +gceSTATUS
  148179. +gckOS_PrepareGPUFrequency(
  148180. + IN gckOS Os,
  148181. + IN gceCORE Core
  148182. + );
  148183. +
  148184. +gceSTATUS
  148185. +gckOS_FinishGPUFrequency(
  148186. + IN gckOS Os,
  148187. + IN gceCORE Core
  148188. + );
  148189. +
  148190. +gceSTATUS
  148191. +gckOS_QueryGPUFrequency(
  148192. + IN gckOS Os,
  148193. + IN gceCORE Core,
  148194. + OUT gctUINT32 * Frequency,
  148195. + OUT gctUINT8 * Scale
  148196. + );
  148197. +
  148198. +gceSTATUS
  148199. +gckOS_SetGPUFrequency(
  148200. + IN gckOS Os,
  148201. + IN gceCORE Core,
  148202. + IN gctUINT8 Scale
  148203. + );
  148204. +
  148205. +/*******************************************************************************
  148206. +** Semaphores.
  148207. +*/
  148208. +
  148209. +/* Create a new semaphore. */
  148210. +gceSTATUS
  148211. +gckOS_CreateSemaphore(
  148212. + IN gckOS Os,
  148213. + OUT gctPOINTER * Semaphore
  148214. + );
  148215. +
  148216. +#if gcdENABLE_VG
  148217. +gceSTATUS
  148218. +gckOS_CreateSemaphoreVG(
  148219. + IN gckOS Os,
  148220. + OUT gctPOINTER * Semaphore
  148221. + );
  148222. +#endif
  148223. +
  148224. +/* Delete a semahore. */
  148225. +gceSTATUS
  148226. +gckOS_DestroySemaphore(
  148227. + IN gckOS Os,
  148228. + IN gctPOINTER Semaphore
  148229. + );
  148230. +
  148231. +/* Acquire a semahore. */
  148232. +gceSTATUS
  148233. +gckOS_AcquireSemaphore(
  148234. + IN gckOS Os,
  148235. + IN gctPOINTER Semaphore
  148236. + );
  148237. +
  148238. +/* Try to acquire a semahore. */
  148239. +gceSTATUS
  148240. +gckOS_TryAcquireSemaphore(
  148241. + IN gckOS Os,
  148242. + IN gctPOINTER Semaphore
  148243. + );
  148244. +
  148245. +/* Release a semahore. */
  148246. +gceSTATUS
  148247. +gckOS_ReleaseSemaphore(
  148248. + IN gckOS Os,
  148249. + IN gctPOINTER Semaphore
  148250. + );
  148251. +
  148252. +/*******************************************************************************
  148253. +** Timer API.
  148254. +*/
  148255. +
  148256. +typedef void (*gctTIMERFUNCTION)(gctPOINTER);
  148257. +
  148258. +/* Create a timer. */
  148259. +gceSTATUS
  148260. +gckOS_CreateTimer(
  148261. + IN gckOS Os,
  148262. + IN gctTIMERFUNCTION Function,
  148263. + IN gctPOINTER Data,
  148264. + OUT gctPOINTER * Timer
  148265. + );
  148266. +
  148267. +/* Destory a timer. */
  148268. +gceSTATUS
  148269. +gckOS_DestroyTimer(
  148270. + IN gckOS Os,
  148271. + IN gctPOINTER Timer
  148272. + );
  148273. +
  148274. +/* Start a timer. */
  148275. +gceSTATUS
  148276. +gckOS_StartTimer(
  148277. + IN gckOS Os,
  148278. + IN gctPOINTER Timer,
  148279. + IN gctUINT32 Delay
  148280. + );
  148281. +
  148282. +/* Stop a timer. */
  148283. +gceSTATUS
  148284. +gckOS_StopTimer(
  148285. + IN gckOS Os,
  148286. + IN gctPOINTER Timer
  148287. + );
  148288. +
  148289. +/******************************************************************************\
  148290. +********************************* gckHEAP Object ********************************
  148291. +\******************************************************************************/
  148292. +
  148293. +typedef struct _gckHEAP * gckHEAP;
  148294. +
  148295. +/* Construct a new gckHEAP object. */
  148296. +gceSTATUS
  148297. +gckHEAP_Construct(
  148298. + IN gckOS Os,
  148299. + IN gctSIZE_T AllocationSize,
  148300. + OUT gckHEAP * Heap
  148301. + );
  148302. +
  148303. +/* Destroy an gckHEAP object. */
  148304. +gceSTATUS
  148305. +gckHEAP_Destroy(
  148306. + IN gckHEAP Heap
  148307. + );
  148308. +
  148309. +/* Allocate memory. */
  148310. +gceSTATUS
  148311. +gckHEAP_Allocate(
  148312. + IN gckHEAP Heap,
  148313. + IN gctSIZE_T Bytes,
  148314. + OUT gctPOINTER * Node
  148315. + );
  148316. +
  148317. +/* Free memory. */
  148318. +gceSTATUS
  148319. +gckHEAP_Free(
  148320. + IN gckHEAP Heap,
  148321. + IN gctPOINTER Node
  148322. + );
  148323. +
  148324. +/* Profile the heap. */
  148325. +gceSTATUS
  148326. +gckHEAP_ProfileStart(
  148327. + IN gckHEAP Heap
  148328. + );
  148329. +
  148330. +gceSTATUS
  148331. +gckHEAP_ProfileEnd(
  148332. + IN gckHEAP Heap,
  148333. + IN gctCONST_STRING Title
  148334. + );
  148335. +
  148336. +
  148337. +/******************************************************************************\
  148338. +******************************** gckVIDMEM Object ******************************
  148339. +\******************************************************************************/
  148340. +
  148341. +typedef struct _gckVIDMEM * gckVIDMEM;
  148342. +typedef struct _gckKERNEL * gckKERNEL;
  148343. +typedef struct _gckDB * gckDB;
  148344. +typedef struct _gckDVFS * gckDVFS;
  148345. +
  148346. +/* Construct a new gckVIDMEM object. */
  148347. +gceSTATUS
  148348. +gckVIDMEM_Construct(
  148349. + IN gckOS Os,
  148350. + IN gctUINT32 BaseAddress,
  148351. + IN gctSIZE_T Bytes,
  148352. + IN gctSIZE_T Threshold,
  148353. + IN gctSIZE_T Banking,
  148354. + OUT gckVIDMEM * Memory
  148355. + );
  148356. +
  148357. +/* Destroy an gckVDIMEM object. */
  148358. +gceSTATUS
  148359. +gckVIDMEM_Destroy(
  148360. + IN gckVIDMEM Memory
  148361. + );
  148362. +
  148363. +/* Allocate rectangular memory. */
  148364. +gceSTATUS
  148365. +gckVIDMEM_Allocate(
  148366. + IN gckVIDMEM Memory,
  148367. + IN gctUINT Width,
  148368. + IN gctUINT Height,
  148369. + IN gctUINT Depth,
  148370. + IN gctUINT BytesPerPixel,
  148371. + IN gctUINT32 Alignment,
  148372. + IN gceSURF_TYPE Type,
  148373. + OUT gcuVIDMEM_NODE_PTR * Node
  148374. + );
  148375. +
  148376. +/* Allocate linear memory. */
  148377. +gceSTATUS
  148378. +gckVIDMEM_AllocateLinear(
  148379. + IN gckVIDMEM Memory,
  148380. + IN gctSIZE_T Bytes,
  148381. + IN gctUINT32 Alignment,
  148382. + IN gceSURF_TYPE Type,
  148383. + OUT gcuVIDMEM_NODE_PTR * Node
  148384. + );
  148385. +
  148386. +/* Free memory. */
  148387. +gceSTATUS
  148388. +gckVIDMEM_Free(
  148389. + IN gcuVIDMEM_NODE_PTR Node
  148390. + );
  148391. +
  148392. +/* Lock memory. */
  148393. +gceSTATUS
  148394. +gckVIDMEM_Lock(
  148395. + IN gckKERNEL Kernel,
  148396. + IN gcuVIDMEM_NODE_PTR Node,
  148397. + IN gctBOOL Cacheable,
  148398. + OUT gctUINT32 * Address
  148399. + );
  148400. +
  148401. +/* Unlock memory. */
  148402. +gceSTATUS
  148403. +gckVIDMEM_Unlock(
  148404. + IN gckKERNEL Kernel,
  148405. + IN gcuVIDMEM_NODE_PTR Node,
  148406. + IN gceSURF_TYPE Type,
  148407. + IN OUT gctBOOL * Asynchroneous
  148408. + );
  148409. +
  148410. +/* Construct a gcuVIDMEM_NODE union for virtual memory. */
  148411. +gceSTATUS
  148412. +gckVIDMEM_ConstructVirtual(
  148413. + IN gckKERNEL Kernel,
  148414. + IN gctBOOL Contiguous,
  148415. + IN gctSIZE_T Bytes,
  148416. + OUT gcuVIDMEM_NODE_PTR * Node
  148417. + );
  148418. +
  148419. +/* Destroy a gcuVIDMEM_NODE union for virtual memory. */
  148420. +gceSTATUS
  148421. +gckVIDMEM_DestroyVirtual(
  148422. + IN gcuVIDMEM_NODE_PTR Node
  148423. + );
  148424. +
  148425. +/******************************************************************************\
  148426. +******************************** gckKERNEL Object ******************************
  148427. +\******************************************************************************/
  148428. +
  148429. +struct _gcsHAL_INTERFACE;
  148430. +
  148431. +/* Notifications. */
  148432. +typedef enum _gceNOTIFY
  148433. +{
  148434. + gcvNOTIFY_INTERRUPT,
  148435. + gcvNOTIFY_COMMAND_QUEUE,
  148436. +}
  148437. +gceNOTIFY;
  148438. +
  148439. +/* Flush flags. */
  148440. +typedef enum _gceKERNEL_FLUSH
  148441. +{
  148442. + gcvFLUSH_COLOR = 0x01,
  148443. + gcvFLUSH_DEPTH = 0x02,
  148444. + gcvFLUSH_TEXTURE = 0x04,
  148445. + gcvFLUSH_2D = 0x08,
  148446. + gcvFLUSH_ALL = gcvFLUSH_COLOR
  148447. + | gcvFLUSH_DEPTH
  148448. + | gcvFLUSH_TEXTURE
  148449. + | gcvFLUSH_2D,
  148450. +}
  148451. +gceKERNEL_FLUSH;
  148452. +
  148453. +/* Construct a new gckKERNEL object. */
  148454. +gceSTATUS
  148455. +gckKERNEL_Construct(
  148456. + IN gckOS Os,
  148457. + IN gceCORE Core,
  148458. + IN gctPOINTER Context,
  148459. + IN gckDB SharedDB,
  148460. + OUT gckKERNEL * Kernel
  148461. + );
  148462. +
  148463. +/* Destroy an gckKERNEL object. */
  148464. +gceSTATUS
  148465. +gckKERNEL_Destroy(
  148466. + IN gckKERNEL Kernel
  148467. + );
  148468. +
  148469. +/* Dispatch a user-level command. */
  148470. +gceSTATUS
  148471. +gckKERNEL_Dispatch(
  148472. + IN gckKERNEL Kernel,
  148473. + IN gctBOOL FromUser,
  148474. + IN OUT struct _gcsHAL_INTERFACE * Interface
  148475. + );
  148476. +
  148477. +/* Query the video memory. */
  148478. +gceSTATUS
  148479. +gckKERNEL_QueryVideoMemory(
  148480. + IN gckKERNEL Kernel,
  148481. + OUT struct _gcsHAL_INTERFACE * Interface
  148482. + );
  148483. +
  148484. +/* Lookup the gckVIDMEM object for a pool. */
  148485. +gceSTATUS
  148486. +gckKERNEL_GetVideoMemoryPool(
  148487. + IN gckKERNEL Kernel,
  148488. + IN gcePOOL Pool,
  148489. + OUT gckVIDMEM * VideoMemory
  148490. + );
  148491. +
  148492. +#if gcdUSE_VIDMEM_PER_PID
  148493. +gceSTATUS
  148494. +gckKERNEL_GetVideoMemoryPoolPid(
  148495. + IN gckKERNEL Kernel,
  148496. + IN gcePOOL Pool,
  148497. + IN gctUINT32 Pid,
  148498. + OUT gckVIDMEM * VideoMemory
  148499. + );
  148500. +
  148501. +gceSTATUS
  148502. +gckKERNEL_CreateVideoMemoryPoolPid(
  148503. + IN gckKERNEL Kernel,
  148504. + IN gcePOOL Pool,
  148505. + IN gctUINT32 Pid,
  148506. + OUT gckVIDMEM * VideoMemory
  148507. + );
  148508. +
  148509. +gceSTATUS
  148510. +gckKERNEL_RemoveVideoMemoryPoolPid(
  148511. + IN gckKERNEL Kernel,
  148512. + IN gckVIDMEM VideoMemory
  148513. + );
  148514. +#endif
  148515. +
  148516. +/* Map video memory. */
  148517. +gceSTATUS
  148518. +gckKERNEL_MapVideoMemory(
  148519. + IN gckKERNEL Kernel,
  148520. + IN gctBOOL InUserSpace,
  148521. + IN gctUINT32 Address,
  148522. +#ifdef __QNXNTO__
  148523. + IN gctUINT32 Pid,
  148524. + IN gctUINT32 Bytes,
  148525. +#endif
  148526. + OUT gctPOINTER * Logical
  148527. + );
  148528. +
  148529. +/* Map video memory. */
  148530. +gceSTATUS
  148531. +gckKERNEL_MapVideoMemoryEx(
  148532. + IN gckKERNEL Kernel,
  148533. + IN gceCORE Core,
  148534. + IN gctBOOL InUserSpace,
  148535. + IN gctUINT32 Address,
  148536. +#ifdef __QNXNTO__
  148537. + IN gctUINT32 Pid,
  148538. + IN gctUINT32 Bytes,
  148539. +#endif
  148540. + OUT gctPOINTER * Logical
  148541. + );
  148542. +
  148543. +#ifdef __QNXNTO__
  148544. +/* Unmap video memory. */
  148545. +gceSTATUS
  148546. +gckKERNEL_UnmapVideoMemory(
  148547. + IN gckKERNEL Kernel,
  148548. + IN gctPOINTER Logical,
  148549. + IN gctUINT32 Pid,
  148550. + IN gctUINT32 Bytes
  148551. + );
  148552. +#endif
  148553. +
  148554. +/* Map memory. */
  148555. +gceSTATUS
  148556. +gckKERNEL_MapMemory(
  148557. + IN gckKERNEL Kernel,
  148558. + IN gctPHYS_ADDR Physical,
  148559. + IN gctSIZE_T Bytes,
  148560. + OUT gctPOINTER * Logical
  148561. + );
  148562. +
  148563. +/* Unmap memory. */
  148564. +gceSTATUS
  148565. +gckKERNEL_UnmapMemory(
  148566. + IN gckKERNEL Kernel,
  148567. + IN gctPHYS_ADDR Physical,
  148568. + IN gctSIZE_T Bytes,
  148569. + IN gctPOINTER Logical
  148570. + );
  148571. +
  148572. +/* Notification of events. */
  148573. +gceSTATUS
  148574. +gckKERNEL_Notify(
  148575. + IN gckKERNEL Kernel,
  148576. + IN gceNOTIFY Notifcation,
  148577. + IN gctBOOL Data
  148578. + );
  148579. +
  148580. +gceSTATUS
  148581. +gckKERNEL_QuerySettings(
  148582. + IN gckKERNEL Kernel,
  148583. + OUT gcsKERNEL_SETTINGS * Settings
  148584. + );
  148585. +
  148586. +/*******************************************************************************
  148587. +**
  148588. +** gckKERNEL_Recovery
  148589. +**
  148590. +** Try to recover the GPU from a fatal error.
  148591. +**
  148592. +** INPUT:
  148593. +**
  148594. +** gckKERNEL Kernel
  148595. +** Pointer to an gckKERNEL object.
  148596. +**
  148597. +** OUTPUT:
  148598. +**
  148599. +** Nothing.
  148600. +*/
  148601. +gceSTATUS
  148602. +gckKERNEL_Recovery(
  148603. + IN gckKERNEL Kernel
  148604. + );
  148605. +
  148606. +/* Set the value of timeout on HW operation. */
  148607. +void
  148608. +gckKERNEL_SetTimeOut(
  148609. + IN gckKERNEL Kernel,
  148610. + IN gctUINT32 timeOut
  148611. + );
  148612. +
  148613. +/* Get access to the user data. */
  148614. +gceSTATUS
  148615. +gckKERNEL_OpenUserData(
  148616. + IN gckKERNEL Kernel,
  148617. + IN gctBOOL NeedCopy,
  148618. + IN gctPOINTER StaticStorage,
  148619. + IN gctPOINTER UserPointer,
  148620. + IN gctSIZE_T Size,
  148621. + OUT gctPOINTER * KernelPointer
  148622. + );
  148623. +
  148624. +/* Release resources associated with the user data connection. */
  148625. +gceSTATUS
  148626. +gckKERNEL_CloseUserData(
  148627. + IN gckKERNEL Kernel,
  148628. + IN gctBOOL NeedCopy,
  148629. + IN gctBOOL FlushData,
  148630. + IN gctPOINTER UserPointer,
  148631. + IN gctSIZE_T Size,
  148632. + OUT gctPOINTER * KernelPointer
  148633. + );
  148634. +
  148635. +gceSTATUS
  148636. +gckDVFS_Construct(
  148637. + IN gckHARDWARE Hardware,
  148638. + OUT gckDVFS * Frequency
  148639. + );
  148640. +
  148641. +gceSTATUS
  148642. +gckDVFS_Destroy(
  148643. + IN gckDVFS Dvfs
  148644. + );
  148645. +
  148646. +gceSTATUS
  148647. +gckDVFS_Start(
  148648. + IN gckDVFS Dvfs
  148649. + );
  148650. +
  148651. +gceSTATUS
  148652. +gckDVFS_Stop(
  148653. + IN gckDVFS Dvfs
  148654. + );
  148655. +
  148656. +/******************************************************************************\
  148657. +******************************* gckHARDWARE Object *****************************
  148658. +\******************************************************************************/
  148659. +
  148660. +/* Construct a new gckHARDWARE object. */
  148661. +gceSTATUS
  148662. +gckHARDWARE_Construct(
  148663. + IN gckOS Os,
  148664. + IN gceCORE Core,
  148665. + OUT gckHARDWARE * Hardware
  148666. + );
  148667. +
  148668. +/* Destroy an gckHARDWARE object. */
  148669. +gceSTATUS
  148670. +gckHARDWARE_Destroy(
  148671. + IN gckHARDWARE Hardware
  148672. + );
  148673. +
  148674. +/* Get hardware type. */
  148675. +gceSTATUS
  148676. +gckHARDWARE_GetType(
  148677. + IN gckHARDWARE Hardware,
  148678. + OUT gceHARDWARE_TYPE * Type
  148679. + );
  148680. +
  148681. +/* Query system memory requirements. */
  148682. +gceSTATUS
  148683. +gckHARDWARE_QuerySystemMemory(
  148684. + IN gckHARDWARE Hardware,
  148685. + OUT gctSIZE_T * SystemSize,
  148686. + OUT gctUINT32 * SystemBaseAddress
  148687. + );
  148688. +
  148689. +/* Build virtual address. */
  148690. +gceSTATUS
  148691. +gckHARDWARE_BuildVirtualAddress(
  148692. + IN gckHARDWARE Hardware,
  148693. + IN gctUINT32 Index,
  148694. + IN gctUINT32 Offset,
  148695. + OUT gctUINT32 * Address
  148696. + );
  148697. +
  148698. +/* Query command buffer requirements. */
  148699. +gceSTATUS
  148700. +gckHARDWARE_QueryCommandBuffer(
  148701. + IN gckHARDWARE Hardware,
  148702. + OUT gctSIZE_T * Alignment,
  148703. + OUT gctSIZE_T * ReservedHead,
  148704. + OUT gctSIZE_T * ReservedTail
  148705. + );
  148706. +
  148707. +/* Add a WAIT/LINK pair in the command queue. */
  148708. +gceSTATUS
  148709. +gckHARDWARE_WaitLink(
  148710. + IN gckHARDWARE Hardware,
  148711. + IN gctPOINTER Logical,
  148712. + IN gctUINT32 Offset,
  148713. + IN OUT gctSIZE_T * Bytes,
  148714. + OUT gctUINT32 * WaitOffset,
  148715. + OUT gctSIZE_T * WaitBytes
  148716. + );
  148717. +
  148718. +/* Kickstart the command processor. */
  148719. +gceSTATUS
  148720. +gckHARDWARE_Execute(
  148721. + IN gckHARDWARE Hardware,
  148722. + IN gctPOINTER Logical,
  148723. +#ifdef __QNXNTO__
  148724. + IN gctPOINTER Physical,
  148725. + IN gctBOOL PhysicalAddresses,
  148726. +#endif
  148727. + IN gctSIZE_T Bytes
  148728. + );
  148729. +
  148730. +/* Add an END command in the command queue. */
  148731. +gceSTATUS
  148732. +gckHARDWARE_End(
  148733. + IN gckHARDWARE Hardware,
  148734. + IN gctPOINTER Logical,
  148735. + IN OUT gctSIZE_T * Bytes
  148736. + );
  148737. +
  148738. +/* Add a NOP command in the command queue. */
  148739. +gceSTATUS
  148740. +gckHARDWARE_Nop(
  148741. + IN gckHARDWARE Hardware,
  148742. + IN gctPOINTER Logical,
  148743. + IN OUT gctSIZE_T * Bytes
  148744. + );
  148745. +
  148746. +/* Add a WAIT command in the command queue. */
  148747. +gceSTATUS
  148748. +gckHARDWARE_Wait(
  148749. + IN gckHARDWARE Hardware,
  148750. + IN gctPOINTER Logical,
  148751. + IN gctUINT32 Count,
  148752. + IN OUT gctSIZE_T * Bytes
  148753. + );
  148754. +
  148755. +/* Add a PIPESELECT command in the command queue. */
  148756. +gceSTATUS
  148757. +gckHARDWARE_PipeSelect(
  148758. + IN gckHARDWARE Hardware,
  148759. + IN gctPOINTER Logical,
  148760. + IN gcePIPE_SELECT Pipe,
  148761. + IN OUT gctSIZE_T * Bytes
  148762. + );
  148763. +
  148764. +/* Add a LINK command in the command queue. */
  148765. +gceSTATUS
  148766. +gckHARDWARE_Link(
  148767. + IN gckHARDWARE Hardware,
  148768. + IN gctPOINTER Logical,
  148769. + IN gctPOINTER FetchAddress,
  148770. + IN gctSIZE_T FetchSize,
  148771. + IN OUT gctSIZE_T * Bytes
  148772. + );
  148773. +
  148774. +/* Add an EVENT command in the command queue. */
  148775. +gceSTATUS
  148776. +gckHARDWARE_Event(
  148777. + IN gckHARDWARE Hardware,
  148778. + IN gctPOINTER Logical,
  148779. + IN gctUINT8 Event,
  148780. + IN gceKERNEL_WHERE FromWhere,
  148781. + IN OUT gctSIZE_T * Bytes
  148782. + );
  148783. +
  148784. +/* Query the available memory. */
  148785. +gceSTATUS
  148786. +gckHARDWARE_QueryMemory(
  148787. + IN gckHARDWARE Hardware,
  148788. + OUT gctSIZE_T * InternalSize,
  148789. + OUT gctUINT32 * InternalBaseAddress,
  148790. + OUT gctUINT32 * InternalAlignment,
  148791. + OUT gctSIZE_T * ExternalSize,
  148792. + OUT gctUINT32 * ExternalBaseAddress,
  148793. + OUT gctUINT32 * ExternalAlignment,
  148794. + OUT gctUINT32 * HorizontalTileSize,
  148795. + OUT gctUINT32 * VerticalTileSize
  148796. + );
  148797. +
  148798. +/* Query the identity of the hardware. */
  148799. +gceSTATUS
  148800. +gckHARDWARE_QueryChipIdentity(
  148801. + IN gckHARDWARE Hardware,
  148802. + OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  148803. + );
  148804. +
  148805. +/* Query the shader support. */
  148806. +gceSTATUS
  148807. +gckHARDWARE_QueryShaderCaps(
  148808. + IN gckHARDWARE Hardware,
  148809. + OUT gctUINT * VertexUniforms,
  148810. + OUT gctUINT * FragmentUniforms,
  148811. + OUT gctUINT * Varyings
  148812. + );
  148813. +
  148814. +/* Split a harwdare specific address into API stuff. */
  148815. +gceSTATUS
  148816. +gckHARDWARE_SplitMemory(
  148817. + IN gckHARDWARE Hardware,
  148818. + IN gctUINT32 Address,
  148819. + OUT gcePOOL * Pool,
  148820. + OUT gctUINT32 * Offset
  148821. + );
  148822. +
  148823. +/* Update command queue tail pointer. */
  148824. +gceSTATUS
  148825. +gckHARDWARE_UpdateQueueTail(
  148826. + IN gckHARDWARE Hardware,
  148827. + IN gctPOINTER Logical,
  148828. + IN gctUINT32 Offset
  148829. + );
  148830. +
  148831. +/* Convert logical address to hardware specific address. */
  148832. +gceSTATUS
  148833. +gckHARDWARE_ConvertLogical(
  148834. + IN gckHARDWARE Hardware,
  148835. + IN gctPOINTER Logical,
  148836. + OUT gctUINT32 * Address
  148837. + );
  148838. +
  148839. +#ifdef __QNXNTO__
  148840. +/* Convert physical address to hardware specific address. */
  148841. +gceSTATUS
  148842. +gckHARDWARE_ConvertPhysical(
  148843. + IN gckHARDWARE Hardware,
  148844. + IN gctPHYS_ADDR Physical,
  148845. + OUT gctUINT32 * Address
  148846. + );
  148847. +#endif
  148848. +
  148849. +/* Interrupt manager. */
  148850. +gceSTATUS
  148851. +gckHARDWARE_Interrupt(
  148852. + IN gckHARDWARE Hardware,
  148853. + IN gctBOOL InterruptValid
  148854. + );
  148855. +
  148856. +/* Program MMU. */
  148857. +gceSTATUS
  148858. +gckHARDWARE_SetMMU(
  148859. + IN gckHARDWARE Hardware,
  148860. + IN gctPOINTER Logical
  148861. + );
  148862. +
  148863. +/* Flush the MMU. */
  148864. +gceSTATUS
  148865. +gckHARDWARE_FlushMMU(
  148866. + IN gckHARDWARE Hardware
  148867. + );
  148868. +
  148869. +/* Set the page table base address. */
  148870. +gceSTATUS
  148871. +gckHARDWARE_SetMMUv2(
  148872. + IN gckHARDWARE Hardware,
  148873. + IN gctBOOL Enable,
  148874. + IN gctPOINTER MtlbAddress,
  148875. + IN gceMMU_MODE Mode,
  148876. + IN gctPOINTER SafeAddress,
  148877. + IN gctBOOL FromPower
  148878. + );
  148879. +
  148880. +/* Get idle register. */
  148881. +gceSTATUS
  148882. +gckHARDWARE_GetIdle(
  148883. + IN gckHARDWARE Hardware,
  148884. + IN gctBOOL Wait,
  148885. + OUT gctUINT32 * Data
  148886. + );
  148887. +
  148888. +/* Flush the caches. */
  148889. +gceSTATUS
  148890. +gckHARDWARE_Flush(
  148891. + IN gckHARDWARE Hardware,
  148892. + IN gceKERNEL_FLUSH Flush,
  148893. + IN gctPOINTER Logical,
  148894. + IN OUT gctSIZE_T * Bytes
  148895. + );
  148896. +
  148897. +/* Enable/disable fast clear. */
  148898. +gceSTATUS
  148899. +gckHARDWARE_SetFastClear(
  148900. + IN gckHARDWARE Hardware,
  148901. + IN gctINT Enable,
  148902. + IN gctINT Compression
  148903. + );
  148904. +
  148905. +gceSTATUS
  148906. +gckHARDWARE_ReadInterrupt(
  148907. + IN gckHARDWARE Hardware,
  148908. + OUT gctUINT32_PTR IDs
  148909. + );
  148910. +
  148911. +/* Power management. */
  148912. +gceSTATUS
  148913. +gckHARDWARE_SetPowerManagementState(
  148914. + IN gckHARDWARE Hardware,
  148915. + IN gceCHIPPOWERSTATE State
  148916. + );
  148917. +
  148918. +gceSTATUS
  148919. +gckHARDWARE_QueryPowerManagementState(
  148920. + IN gckHARDWARE Hardware,
  148921. + OUT gceCHIPPOWERSTATE* State
  148922. + );
  148923. +
  148924. +gceSTATUS
  148925. +gckHARDWARE_SetPowerManagement(
  148926. + IN gckHARDWARE Hardware,
  148927. + IN gctBOOL PowerManagement
  148928. + );
  148929. +
  148930. +gceSTATUS
  148931. +gckHARDWARE_SetGpuProfiler(
  148932. + IN gckHARDWARE Hardware,
  148933. + IN gctBOOL GpuProfiler
  148934. + );
  148935. +
  148936. +#if gcdENABLE_FSCALE_VAL_ADJUST
  148937. +gceSTATUS
  148938. +gckHARDWARE_SetFscaleValue(
  148939. + IN gckHARDWARE Hardware,
  148940. + IN gctUINT32 FscaleValue
  148941. + );
  148942. +
  148943. +gceSTATUS
  148944. +gckHARDWARE_GetFscaleValue(
  148945. + IN gckHARDWARE Hardware,
  148946. + IN gctUINT * FscaleValue,
  148947. + IN gctUINT * MinFscaleValue,
  148948. + IN gctUINT * MaxFscaleValue
  148949. + );
  148950. +#endif
  148951. +
  148952. +#if gcdPOWEROFF_TIMEOUT
  148953. +gceSTATUS
  148954. +gckHARDWARE_SetPowerOffTimeout(
  148955. + IN gckHARDWARE Hardware,
  148956. + IN gctUINT32 Timeout
  148957. +);
  148958. +
  148959. +gceSTATUS
  148960. +gckHARDWARE_QueryPowerOffTimeout(
  148961. + IN gckHARDWARE Hardware,
  148962. + OUT gctUINT32* Timeout
  148963. +);
  148964. +#endif
  148965. +
  148966. +/* Profile 2D Engine. */
  148967. +gceSTATUS
  148968. +gckHARDWARE_ProfileEngine2D(
  148969. + IN gckHARDWARE Hardware,
  148970. + OUT gcs2D_PROFILE_PTR Profile
  148971. + );
  148972. +
  148973. +gceSTATUS
  148974. +gckHARDWARE_InitializeHardware(
  148975. + IN gckHARDWARE Hardware
  148976. + );
  148977. +
  148978. +gceSTATUS
  148979. +gckHARDWARE_Reset(
  148980. + IN gckHARDWARE Hardware
  148981. + );
  148982. +
  148983. +typedef gceSTATUS (*gctISRMANAGERFUNC)(gctPOINTER Context, gceCORE Core);
  148984. +
  148985. +gceSTATUS
  148986. +gckHARDWARE_SetIsrManager(
  148987. + IN gckHARDWARE Hardware,
  148988. + IN gctISRMANAGERFUNC StartIsr,
  148989. + IN gctISRMANAGERFUNC StopIsr,
  148990. + IN gctPOINTER Context
  148991. + );
  148992. +
  148993. +/* Start a composition. */
  148994. +gceSTATUS
  148995. +gckHARDWARE_Compose(
  148996. + IN gckHARDWARE Hardware,
  148997. + IN gctUINT32 ProcessID,
  148998. + IN gctPHYS_ADDR Physical,
  148999. + IN gctPOINTER Logical,
  149000. + IN gctSIZE_T Offset,
  149001. + IN gctSIZE_T Size,
  149002. + IN gctUINT8 EventID
  149003. + );
  149004. +
  149005. +/* Check for Hardware features. */
  149006. +gceSTATUS
  149007. +gckHARDWARE_IsFeatureAvailable(
  149008. + IN gckHARDWARE Hardware,
  149009. + IN gceFEATURE Feature
  149010. + );
  149011. +
  149012. +gceSTATUS
  149013. +gckHARDWARE_DumpMMUException(
  149014. + IN gckHARDWARE Hardware
  149015. + );
  149016. +
  149017. +gceSTATUS
  149018. +gckHARDWARE_DumpGPUState(
  149019. + IN gckHARDWARE Hardware
  149020. + );
  149021. +
  149022. +gceSTATUS
  149023. +gckHARDWARE_InitDVFS(
  149024. + IN gckHARDWARE Hardware
  149025. + );
  149026. +
  149027. +gceSTATUS
  149028. +gckHARDWARE_QueryLoad(
  149029. + IN gckHARDWARE Hardware,
  149030. + OUT gctUINT32 * Load
  149031. + );
  149032. +
  149033. +gceSTATUS
  149034. +gckHARDWARE_SetDVFSPeroid(
  149035. + IN gckHARDWARE Hardware,
  149036. + IN gctUINT32 Frequency
  149037. + );
  149038. +
  149039. +#if !gcdENABLE_VG
  149040. +/******************************************************************************\
  149041. +***************************** gckINTERRUPT Object ******************************
  149042. +\******************************************************************************/
  149043. +
  149044. +typedef struct _gckINTERRUPT * gckINTERRUPT;
  149045. +
  149046. +typedef gceSTATUS (* gctINTERRUPT_HANDLER)(
  149047. + IN gckKERNEL Kernel
  149048. + );
  149049. +
  149050. +gceSTATUS
  149051. +gckINTERRUPT_Construct(
  149052. + IN gckKERNEL Kernel,
  149053. + OUT gckINTERRUPT * Interrupt
  149054. + );
  149055. +
  149056. +gceSTATUS
  149057. +gckINTERRUPT_Destroy(
  149058. + IN gckINTERRUPT Interrupt
  149059. + );
  149060. +
  149061. +gceSTATUS
  149062. +gckINTERRUPT_SetHandler(
  149063. + IN gckINTERRUPT Interrupt,
  149064. + IN OUT gctINT32_PTR Id,
  149065. + IN gctINTERRUPT_HANDLER Handler
  149066. + );
  149067. +
  149068. +gceSTATUS
  149069. +gckINTERRUPT_Notify(
  149070. + IN gckINTERRUPT Interrupt,
  149071. + IN gctBOOL Valid
  149072. + );
  149073. +#endif
  149074. +/******************************************************************************\
  149075. +******************************** gckEVENT Object *******************************
  149076. +\******************************************************************************/
  149077. +
  149078. +typedef struct _gckEVENT * gckEVENT;
  149079. +
  149080. +/* Construct a new gckEVENT object. */
  149081. +gceSTATUS
  149082. +gckEVENT_Construct(
  149083. + IN gckKERNEL Kernel,
  149084. + OUT gckEVENT * Event
  149085. + );
  149086. +
  149087. +/* Destroy an gckEVENT object. */
  149088. +gceSTATUS
  149089. +gckEVENT_Destroy(
  149090. + IN gckEVENT Event
  149091. + );
  149092. +
  149093. +/* Add a new event to the list of events. */
  149094. +gceSTATUS
  149095. +gckEVENT_AddList(
  149096. + IN gckEVENT Event,
  149097. + IN gcsHAL_INTERFACE_PTR Interface,
  149098. + IN gceKERNEL_WHERE FromWhere,
  149099. + IN gctBOOL AllocateAllowed,
  149100. + IN gctBOOL FromKernel
  149101. + );
  149102. +
  149103. +/* Schedule a FreeNonPagedMemory event. */
  149104. +gceSTATUS
  149105. +gckEVENT_FreeNonPagedMemory(
  149106. + IN gckEVENT Event,
  149107. + IN gctSIZE_T Bytes,
  149108. + IN gctPHYS_ADDR Physical,
  149109. + IN gctPOINTER Logical,
  149110. + IN gceKERNEL_WHERE FromWhere
  149111. + );
  149112. +
  149113. +/* Schedule a FreeContiguousMemory event. */
  149114. +gceSTATUS
  149115. +gckEVENT_FreeContiguousMemory(
  149116. + IN gckEVENT Event,
  149117. + IN gctSIZE_T Bytes,
  149118. + IN gctPHYS_ADDR Physical,
  149119. + IN gctPOINTER Logical,
  149120. + IN gceKERNEL_WHERE FromWhere
  149121. + );
  149122. +
  149123. +/* Schedule a FreeVideoMemory event. */
  149124. +gceSTATUS
  149125. +gckEVENT_FreeVideoMemory(
  149126. + IN gckEVENT Event,
  149127. + IN gcuVIDMEM_NODE_PTR VideoMemory,
  149128. + IN gceKERNEL_WHERE FromWhere
  149129. + );
  149130. +
  149131. +/* Schedule a signal event. */
  149132. +gceSTATUS
  149133. +gckEVENT_Signal(
  149134. + IN gckEVENT Event,
  149135. + IN gctSIGNAL Signal,
  149136. + IN gceKERNEL_WHERE FromWhere
  149137. + );
  149138. +
  149139. +/* Schedule an Unlock event. */
  149140. +gceSTATUS
  149141. +gckEVENT_Unlock(
  149142. + IN gckEVENT Event,
  149143. + IN gceKERNEL_WHERE FromWhere,
  149144. + IN gcuVIDMEM_NODE_PTR Node,
  149145. + IN gceSURF_TYPE Type
  149146. + );
  149147. +
  149148. +gceSTATUS
  149149. +gckEVENT_CommitDone(
  149150. + IN gckEVENT Event,
  149151. + IN gceKERNEL_WHERE FromWhere
  149152. + );
  149153. +
  149154. +#if gcdVIRTUAL_COMMAND_BUFFER
  149155. +/* Schedule a FreeVirtualCommandBuffer event. */
  149156. +gceSTATUS
  149157. +gckEVENT_DestroyVirtualCommandBuffer(
  149158. + IN gckEVENT Event,
  149159. + IN gctSIZE_T Bytes,
  149160. + IN gctPHYS_ADDR Physical,
  149161. + IN gctPOINTER Logical,
  149162. + IN gceKERNEL_WHERE FromWhere
  149163. + );
  149164. +#endif
  149165. +
  149166. +gceSTATUS
  149167. +gckEVENT_Submit(
  149168. + IN gckEVENT Event,
  149169. + IN gctBOOL Wait,
  149170. + IN gctBOOL FromPower
  149171. + );
  149172. +
  149173. +/* Commit an event queue. */
  149174. +gceSTATUS
  149175. +gckEVENT_Commit(
  149176. + IN gckEVENT Event,
  149177. + IN gcsQUEUE_PTR Queue
  149178. + );
  149179. +
  149180. +/* Schedule a composition event. */
  149181. +gceSTATUS
  149182. +gckEVENT_Compose(
  149183. + IN gckEVENT Event,
  149184. + IN gcsHAL_COMPOSE_PTR Info
  149185. + );
  149186. +
  149187. +/* Event callback routine. */
  149188. +gceSTATUS
  149189. +gckEVENT_Notify(
  149190. + IN gckEVENT Event,
  149191. + IN gctUINT32 IDs
  149192. + );
  149193. +
  149194. +/* Event callback routine. */
  149195. +gceSTATUS
  149196. +gckEVENT_Interrupt(
  149197. + IN gckEVENT Event,
  149198. + IN gctUINT32 IDs
  149199. + );
  149200. +
  149201. +gceSTATUS
  149202. +gckEVENT_Dump(
  149203. + IN gckEVENT Event
  149204. + );
  149205. +/******************************************************************************\
  149206. +******************************* gckCOMMAND Object ******************************
  149207. +\******************************************************************************/
  149208. +
  149209. +typedef struct _gckCOMMAND * gckCOMMAND;
  149210. +
  149211. +/* Construct a new gckCOMMAND object. */
  149212. +gceSTATUS
  149213. +gckCOMMAND_Construct(
  149214. + IN gckKERNEL Kernel,
  149215. + OUT gckCOMMAND * Command
  149216. + );
  149217. +
  149218. +/* Destroy an gckCOMMAND object. */
  149219. +gceSTATUS
  149220. +gckCOMMAND_Destroy(
  149221. + IN gckCOMMAND Command
  149222. + );
  149223. +
  149224. +/* Acquire command queue synchronization objects. */
  149225. +gceSTATUS
  149226. +gckCOMMAND_EnterCommit(
  149227. + IN gckCOMMAND Command,
  149228. + IN gctBOOL FromPower
  149229. + );
  149230. +
  149231. +/* Release command queue synchronization objects. */
  149232. +gceSTATUS
  149233. +gckCOMMAND_ExitCommit(
  149234. + IN gckCOMMAND Command,
  149235. + IN gctBOOL FromPower
  149236. + );
  149237. +
  149238. +/* Start the command queue. */
  149239. +gceSTATUS
  149240. +gckCOMMAND_Start(
  149241. + IN gckCOMMAND Command
  149242. + );
  149243. +
  149244. +/* Stop the command queue. */
  149245. +gceSTATUS
  149246. +gckCOMMAND_Stop(
  149247. + IN gckCOMMAND Command,
  149248. + IN gctBOOL FromRecovery
  149249. + );
  149250. +
  149251. +/* Commit a buffer to the command queue. */
  149252. +gceSTATUS
  149253. +gckCOMMAND_Commit(
  149254. + IN gckCOMMAND Command,
  149255. + IN gckCONTEXT Context,
  149256. + IN gcoCMDBUF CommandBuffer,
  149257. + IN gcsSTATE_DELTA_PTR StateDelta,
  149258. + IN gcsQUEUE_PTR EventQueue,
  149259. + IN gctUINT32 ProcessID
  149260. + );
  149261. +
  149262. +/* Reserve space in the command buffer. */
  149263. +gceSTATUS
  149264. +gckCOMMAND_Reserve(
  149265. + IN gckCOMMAND Command,
  149266. + IN gctSIZE_T RequestedBytes,
  149267. + OUT gctPOINTER * Buffer,
  149268. + OUT gctSIZE_T * BufferSize
  149269. + );
  149270. +
  149271. +/* Execute reserved space in the command buffer. */
  149272. +gceSTATUS
  149273. +gckCOMMAND_Execute(
  149274. + IN gckCOMMAND Command,
  149275. + IN gctSIZE_T RequstedBytes
  149276. + );
  149277. +
  149278. +/* Stall the command queue. */
  149279. +gceSTATUS
  149280. +gckCOMMAND_Stall(
  149281. + IN gckCOMMAND Command,
  149282. + IN gctBOOL FromPower
  149283. + );
  149284. +
  149285. +/* Attach user process. */
  149286. +gceSTATUS
  149287. +gckCOMMAND_Attach(
  149288. + IN gckCOMMAND Command,
  149289. + OUT gckCONTEXT * Context,
  149290. + OUT gctSIZE_T * StateCount,
  149291. + IN gctUINT32 ProcessID
  149292. + );
  149293. +
  149294. +/* Detach user process. */
  149295. +gceSTATUS
  149296. +gckCOMMAND_Detach(
  149297. + IN gckCOMMAND Command,
  149298. + IN gckCONTEXT Context
  149299. + );
  149300. +
  149301. +#if gcdVIRTUAL_COMMAND_BUFFER
  149302. +gceSTATUS
  149303. +gckCOMMAND_DumpExecutingBuffer(
  149304. + IN gckCOMMAND Command
  149305. + );
  149306. +#endif
  149307. +
  149308. +/******************************************************************************\
  149309. +********************************* gckMMU Object ********************************
  149310. +\******************************************************************************/
  149311. +
  149312. +typedef struct _gckMMU * gckMMU;
  149313. +
  149314. +/* Construct a new gckMMU object. */
  149315. +gceSTATUS
  149316. +gckMMU_Construct(
  149317. + IN gckKERNEL Kernel,
  149318. + IN gctSIZE_T MmuSize,
  149319. + OUT gckMMU * Mmu
  149320. + );
  149321. +
  149322. +/* Destroy an gckMMU object. */
  149323. +gceSTATUS
  149324. +gckMMU_Destroy(
  149325. + IN gckMMU Mmu
  149326. + );
  149327. +
  149328. +/* Enable the MMU. */
  149329. +gceSTATUS
  149330. +gckMMU_Enable(
  149331. + IN gckMMU Mmu,
  149332. + IN gctUINT32 PhysBaseAddr,
  149333. + IN gctUINT32 PhysSize
  149334. + );
  149335. +
  149336. +/* Allocate pages inside the MMU. */
  149337. +gceSTATUS
  149338. +gckMMU_AllocatePages(
  149339. + IN gckMMU Mmu,
  149340. + IN gctSIZE_T PageCount,
  149341. + OUT gctPOINTER * PageTable,
  149342. + OUT gctUINT32 * Address
  149343. + );
  149344. +
  149345. +gceSTATUS
  149346. +gckMMU_AllocatePagesEx(
  149347. + IN gckMMU Mmu,
  149348. + IN gctSIZE_T PageCount,
  149349. + IN gceSURF_TYPE Type,
  149350. + OUT gctPOINTER * PageTable,
  149351. + OUT gctUINT32 * Address
  149352. + );
  149353. +
  149354. +/* Remove a page table from the MMU. */
  149355. +gceSTATUS
  149356. +gckMMU_FreePages(
  149357. + IN gckMMU Mmu,
  149358. + IN gctPOINTER PageTable,
  149359. + IN gctSIZE_T PageCount
  149360. + );
  149361. +
  149362. +/* Set the MMU page with info. */
  149363. +gceSTATUS
  149364. +gckMMU_SetPage(
  149365. + IN gckMMU Mmu,
  149366. + IN gctUINT32 PageAddress,
  149367. + IN gctUINT32 *PageEntry
  149368. + );
  149369. +
  149370. +#ifdef __QNXNTO__
  149371. +gceSTATUS
  149372. +gckMMU_InsertNode(
  149373. + IN gckMMU Mmu,
  149374. + IN gcuVIDMEM_NODE_PTR Node);
  149375. +
  149376. +gceSTATUS
  149377. +gckMMU_RemoveNode(
  149378. + IN gckMMU Mmu,
  149379. + IN gcuVIDMEM_NODE_PTR Node);
  149380. +#endif
  149381. +
  149382. +#ifdef __QNXNTO__
  149383. +gceSTATUS
  149384. +gckMMU_FreeHandleMemory(
  149385. + IN gckKERNEL Kernel,
  149386. + IN gckMMU Mmu,
  149387. + IN gctUINT32 Pid
  149388. + );
  149389. +#endif
  149390. +
  149391. +gceSTATUS
  149392. +gckMMU_Flush(
  149393. + IN gckMMU Mmu
  149394. + );
  149395. +
  149396. +gceSTATUS
  149397. +gckMMU_DumpPageTableEntry(
  149398. + IN gckMMU Mmu,
  149399. + IN gctUINT32 Address
  149400. + );
  149401. +
  149402. +
  149403. +#if VIVANTE_PROFILER
  149404. +gceSTATUS
  149405. +gckHARDWARE_QueryProfileRegisters(
  149406. + IN gckHARDWARE Hardware,
  149407. + IN gctBOOL Clear,
  149408. + OUT gcsPROFILER_COUNTERS * Counters
  149409. + );
  149410. +#endif
  149411. +
  149412. +#if VIVANTE_PROFILER_CONTEXT
  149413. +gceSTATUS
  149414. +gckHARDWARE_QueryContextProfile(
  149415. + IN gckHARDWARE Hardware,
  149416. + IN gctBOOL Clear,
  149417. + IN gckCONTEXT Context,
  149418. + OUT gcsPROFILER_COUNTERS * Counters
  149419. + );
  149420. +
  149421. +gceSTATUS
  149422. +gckHARDWARE_UpdateContextProfile(
  149423. + IN gckHARDWARE Hardware,
  149424. + IN gckCONTEXT Context
  149425. + );
  149426. +#endif
  149427. +
  149428. +gceSTATUS
  149429. +gckOS_SignalQueryHardware(
  149430. + IN gckOS Os,
  149431. + IN gctSIGNAL Signal,
  149432. + OUT gckHARDWARE * Hardware
  149433. + );
  149434. +
  149435. +gceSTATUS
  149436. +gckOS_SignalSetHardware(
  149437. + IN gckOS Os,
  149438. + IN gctSIGNAL Signal,
  149439. + gckHARDWARE Hardware
  149440. + );
  149441. +
  149442. +#ifdef __cplusplus
  149443. +}
  149444. +#endif
  149445. +
  149446. +#if gcdENABLE_VG
  149447. +#include "gc_hal_vg.h"
  149448. +#endif
  149449. +
  149450. +#endif /* __gc_hal_h_ */
  149451. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h
  149452. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h 1970-01-01 01:00:00.000000000 +0100
  149453. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h 2014-08-20 19:23:53.566845873 +0200
  149454. @@ -0,0 +1,185 @@
  149455. +/****************************************************************************
  149456. +*
  149457. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  149458. +*
  149459. +* This program is free software; you can redistribute it and/or modify
  149460. +* it under the terms of the GNU General Public License as published by
  149461. +* the Free Software Foundation; either version 2 of the license, or
  149462. +* (at your option) any later version.
  149463. +*
  149464. +* This program is distributed in the hope that it will be useful,
  149465. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  149466. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  149467. +* GNU General Public License for more details.
  149468. +*
  149469. +* You should have received a copy of the GNU General Public License
  149470. +* along with this program; if not write to the Free Software
  149471. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  149472. +*
  149473. +*****************************************************************************/
  149474. +
  149475. +
  149476. +#ifndef __gc_hal_kernel_buffer_h_
  149477. +#define __gc_hal_kernel_buffer_h_
  149478. +
  149479. +
  149480. +#ifdef __cplusplus
  149481. +extern "C" {
  149482. +#endif
  149483. +
  149484. +/******************************************************************************\
  149485. +************************ Command Buffer and Event Objects **********************
  149486. +\******************************************************************************/
  149487. +
  149488. +/* The number of context buffers per user. */
  149489. +#define gcdCONTEXT_BUFFER_COUNT 2
  149490. +
  149491. +/* State delta record. */
  149492. +typedef struct _gcsSTATE_DELTA_RECORD * gcsSTATE_DELTA_RECORD_PTR;
  149493. +typedef struct _gcsSTATE_DELTA_RECORD
  149494. +{
  149495. + /* State address. */
  149496. + gctUINT address;
  149497. +
  149498. + /* State mask. */
  149499. + gctUINT32 mask;
  149500. +
  149501. + /* State data. */
  149502. + gctUINT32 data;
  149503. +}
  149504. +gcsSTATE_DELTA_RECORD;
  149505. +
  149506. +/* State delta. */
  149507. +typedef struct _gcsSTATE_DELTA
  149508. +{
  149509. + /* For debugging: the number of delta in the order of creation. */
  149510. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  149511. + gctUINT num;
  149512. +#endif
  149513. +
  149514. + /* Main state delta ID. Every time state delta structure gets reinitialized,
  149515. + main ID is incremented. If main state ID overflows, all map entry IDs get
  149516. + reinitialized to make sure there is no potential erroneous match after
  149517. + the overflow.*/
  149518. + gctUINT id;
  149519. +
  149520. + /* The number of contexts pending modification by the delta. */
  149521. + gctINT refCount;
  149522. +
  149523. + /* Vertex element count for the delta buffer. */
  149524. + gctUINT elementCount;
  149525. +
  149526. + /* Number of states currently stored in the record array. */
  149527. + gctUINT recordCount;
  149528. +
  149529. + /* Record array; holds all modified states in gcsSTATE_DELTA_RECORD. */
  149530. + gctUINT64 recordArray;
  149531. +
  149532. + /* Map entry ID is used for map entry validation. If map entry ID does not
  149533. + match the main state delta ID, the entry and the corresponding state are
  149534. + considered not in use. */
  149535. + gctUINT64 mapEntryID;
  149536. + gctUINT mapEntryIDSize;
  149537. +
  149538. + /* If the map entry ID matches the main state delta ID, index points to
  149539. + the state record in the record array. */
  149540. + gctUINT64 mapEntryIndex;
  149541. +
  149542. + /* Previous and next state deltas in gcsSTATE_DELTA. */
  149543. + gctUINT64 prev;
  149544. + gctUINT64 next;
  149545. +}
  149546. +gcsSTATE_DELTA;
  149547. +
  149548. +/* Command buffer object. */
  149549. +struct _gcoCMDBUF
  149550. +{
  149551. + /* The object. */
  149552. + gcsOBJECT object;
  149553. +
  149554. + /* Command buffer entry and exit pipes. */
  149555. + gcePIPE_SELECT entryPipe;
  149556. + gcePIPE_SELECT exitPipe;
  149557. +
  149558. + /* Feature usage flags. */
  149559. + gctBOOL using2D;
  149560. + gctBOOL using3D;
  149561. + gctBOOL usingFilterBlit;
  149562. + gctBOOL usingPalette;
  149563. +
  149564. + /* Physical address of command buffer. Just a name. */
  149565. + gctUINT32 physical;
  149566. +
  149567. + /* Logical address of command buffer. */
  149568. + gctUINT64 logical;
  149569. +
  149570. + /* Number of bytes in command buffer. */
  149571. + gctUINT bytes;
  149572. +
  149573. + /* Start offset into the command buffer. */
  149574. + gctUINT startOffset;
  149575. +
  149576. + /* Current offset into the command buffer. */
  149577. + gctUINT offset;
  149578. +
  149579. + /* Number of free bytes in command buffer. */
  149580. + gctUINT free;
  149581. +
  149582. + /* Location of the last reserved area. */
  149583. + gctUINT64 lastReserve;
  149584. + gctUINT lastOffset;
  149585. +
  149586. +#if gcdSECURE_USER
  149587. + /* Hint array for the current command buffer. */
  149588. + gctUINT hintArraySize;
  149589. + gctUINT64 hintArray;
  149590. + gctUINT64 hintArrayTail;
  149591. +#endif
  149592. +
  149593. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  149594. + /* Last load state command location and hardware address. */
  149595. + gctUINT64 lastLoadStatePtr;
  149596. + gctUINT32 lastLoadStateAddress;
  149597. + gctUINT32 lastLoadStateCount;
  149598. +#endif
  149599. +};
  149600. +
  149601. +typedef struct _gcsQUEUE
  149602. +{
  149603. + /* Pointer to next gcsQUEUE structure in gcsQUEUE. */
  149604. + gctUINT64 next;
  149605. +
  149606. + /* Event information. */
  149607. + gcsHAL_INTERFACE iface;
  149608. +}
  149609. +gcsQUEUE;
  149610. +
  149611. +/* Event queue. */
  149612. +struct _gcoQUEUE
  149613. +{
  149614. + /* The object. */
  149615. + gcsOBJECT object;
  149616. +
  149617. + /* Pointer to current event queue. */
  149618. + gcsQUEUE_PTR head;
  149619. + gcsQUEUE_PTR tail;
  149620. +
  149621. +#ifdef __QNXNTO__
  149622. + /* Buffer for records. */
  149623. + gcsQUEUE_PTR records;
  149624. + gctUINT32 freeBytes;
  149625. + gctUINT32 offset;
  149626. +#else
  149627. + /* List of free records. */
  149628. + gcsQUEUE_PTR freeList;
  149629. +#endif
  149630. + #define gcdIN_QUEUE_RECORD_LIMIT 16
  149631. + /* Number of records currently in queue */
  149632. + gctUINT32 recordCount;
  149633. +};
  149634. +
  149635. +#ifdef __cplusplus
  149636. +}
  149637. +#endif
  149638. +
  149639. +#endif /* __gc_hal_kernel_buffer_h_ */
  149640. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h
  149641. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h 1970-01-01 01:00:00.000000000 +0100
  149642. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h 2014-08-20 19:23:53.566845873 +0200
  149643. @@ -0,0 +1,530 @@
  149644. +/****************************************************************************
  149645. +*
  149646. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  149647. +*
  149648. +* This program is free software; you can redistribute it and/or modify
  149649. +* it under the terms of the GNU General Public License as published by
  149650. +* the Free Software Foundation; either version 2 of the license, or
  149651. +* (at your option) any later version.
  149652. +*
  149653. +* This program is distributed in the hope that it will be useful,
  149654. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  149655. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  149656. +* GNU General Public License for more details.
  149657. +*
  149658. +* You should have received a copy of the GNU General Public License
  149659. +* along with this program; if not write to the Free Software
  149660. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  149661. +*
  149662. +*****************************************************************************/
  149663. +
  149664. +
  149665. +/*
  149666. +** Include file for the local memory management.
  149667. +*/
  149668. +
  149669. +#ifndef __gc_hal_mem_h_
  149670. +#define __gc_hal_mem_h_
  149671. +#ifndef VIVANTE_NO_3D
  149672. +
  149673. +#ifdef __cplusplus
  149674. +extern "C" {
  149675. +#endif
  149676. +
  149677. +/*******************************************************************************
  149678. +** Usage:
  149679. +
  149680. + The macros to declare MemPool type and functions are
  149681. + gcmMEM_DeclareFSMemPool (Type, TypeName, Prefix)
  149682. + gcmMEM_DeclareVSMemPool (Type, TypeName, Prefix)
  149683. + gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix)
  149684. +
  149685. + The data structures for MemPool are
  149686. + typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
  149687. + typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
  149688. + typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
  149689. +
  149690. + The MemPool constructor and destructor functions are
  149691. + gcfMEM_InitFSMemPool(gcsMEM_FS_MEM_POOL *, gcoOS, gctUINT, gctUINT);
  149692. + gcfMEM_FreeFSMemPool(gcsMEM_FS_MEM_POOL *);
  149693. + gcfMEM_InitVSMemPool(gcsMEM_VS_MEM_POOL *, gcoOS, gctUINT, gctBOOL);
  149694. + gcfMEM_FreeVSMemPool(gcsMEM_VS_MEM_POOL *);
  149695. + gcfMEM_InitAFSMemPool(gcsMEM_AFS_MEM_POOL *, gcoOS, gctUINT);
  149696. + gcfMEM_FreeAFSMemPool(gcsMEM_AFS_MEM_POOL *);
  149697. +
  149698. + FS: for Fixed-Size data structures
  149699. + VS: for Variable-size data structures
  149700. + AFS: for Array of Fixed-Size data structures
  149701. +
  149702. +
  149703. + // Example 1: For a fixed-size data structure, struct gcsNode.
  149704. + // It is used locally in a file, so the functions are static without prefix.
  149705. + // At top level, declear allocate and free functions.
  149706. + // The first argument is the data type.
  149707. + // The second armument is the short name used in the fuctions.
  149708. + gcmMEM_DeclareFSMemPool(struct gcsNode, Node, );
  149709. +
  149710. + // The previous macro creates two inline functions,
  149711. + // _AllocateNode and _FreeNode.
  149712. +
  149713. + // In function or struct
  149714. + gcsMEM_FS_MEM_POOL nodeMemPool;
  149715. +
  149716. + // In function,
  149717. + struct gcsNode * node;
  149718. + gceSTATUS status;
  149719. +
  149720. + // Before using the memory pool, initialize it.
  149721. + // The second argument is the gcoOS object.
  149722. + // The third argument is the number of data structures to allocate for each chunk.
  149723. + status = gcfMEM_InitFSMemPool(&nodeMemPool, os, 100, sizeof(struct gcsNode));
  149724. + ...
  149725. +
  149726. + // Allocate a node.
  149727. + status = _AllocateNode(nodeMemPool, &node);
  149728. + ...
  149729. + // Free a node.
  149730. + _FreeNode(nodeMemPool, node);
  149731. +
  149732. + // After using the memory pool, free it.
  149733. + gcfMEM_FreeFSMemPool(&nodeMemPool);
  149734. +
  149735. +
  149736. + // Example 2: For array of fixed-size data structures, struct gcsNode.
  149737. + // It is used in several files, so the functions are extern with prefix.
  149738. + // At top level, declear allocate and free functions.
  149739. + // The first argument is the data type, and the second one is the short name
  149740. + // used in the fuctions.
  149741. + gcmMEM_DeclareAFSMemPool(struct gcsNode, NodeArray, gcfOpt);
  149742. +
  149743. + // The previous macro creates two inline functions,
  149744. + // gcfOpt_AllocateNodeArray and gcfOpt_FreeNodeArray.
  149745. +
  149746. + // In function or struct
  149747. + gcsMEM_AFS_MEM_POOL nodeArrayMemPool;
  149748. +
  149749. + // In function,
  149750. + struct gcsNode * nodeArray;
  149751. + gceSTATUS status;
  149752. +
  149753. + // Before using the array memory pool, initialize it.
  149754. + // The second argument is the gcoOS object, the third is the number of data
  149755. + // structures to allocate for each chunk.
  149756. + status = gcfMEM_InitAFSMemPool(&nodeArrayMemPool, os, sizeof(struct gcsNode));
  149757. + ...
  149758. +
  149759. + // Allocate a node array of size 100.
  149760. + status = gcfOpt_AllocateNodeArray(nodeArrayMemPool, &nodeArray, 100);
  149761. + ...
  149762. + // Free a node array.
  149763. + gcfOpt_FreeNodeArray(&nodeArrayMemPool, nodeArray);
  149764. +
  149765. + // After using the array memory pool, free it.
  149766. + gcfMEM_FreeAFSMemPool(&nodeArrayMemPool);
  149767. +
  149768. +*******************************************************************************/
  149769. +
  149770. +/*******************************************************************************
  149771. +** To switch back to use gcoOS_Allocate and gcoOS_Free, add
  149772. +** #define USE_LOCAL_MEMORY_POOL 0
  149773. +** before including this file.
  149774. +*******************************************************************************/
  149775. +#ifndef USE_LOCAL_MEMORY_POOL
  149776. +/*
  149777. + USE_LOCAL_MEMORY_POOL
  149778. +
  149779. + This define enables the local memory management to improve performance.
  149780. +*/
  149781. +#define USE_LOCAL_MEMORY_POOL 1
  149782. +#endif
  149783. +
  149784. +/*******************************************************************************
  149785. +** Memory Pool Data Structures
  149786. +*******************************************************************************/
  149787. +#if USE_LOCAL_MEMORY_POOL
  149788. + typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
  149789. + typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
  149790. + typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
  149791. +#else
  149792. + typedef gcoOS gcsMEM_FS_MEM_POOL;
  149793. + typedef gcoOS gcsMEM_VS_MEM_POOL;
  149794. + typedef gcoOS gcsMEM_AFS_MEM_POOL;
  149795. +#endif
  149796. +
  149797. +/*******************************************************************************
  149798. +** Memory Pool Macros
  149799. +*******************************************************************************/
  149800. +#if USE_LOCAL_MEMORY_POOL
  149801. +#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
  149802. +gceSTATUS \
  149803. +Prefix##_Allocate##TypeName( \
  149804. + gcsMEM_FS_MEM_POOL MemPool, \
  149805. + Type ** Pointer \
  149806. + ) \
  149807. +{ \
  149808. + return(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
  149809. +} \
  149810. + \
  149811. +gceSTATUS \
  149812. +Prefix##_CAllocate##TypeName( \
  149813. + gcsMEM_FS_MEM_POOL MemPool, \
  149814. + Type ** Pointer \
  149815. + ) \
  149816. +{ \
  149817. + gceSTATUS status; \
  149818. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149819. + gcmERR_RETURN(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
  149820. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
  149821. + gcmFOOTER(); \
  149822. + return gcvSTATUS_OK; \
  149823. +} \
  149824. + \
  149825. +gceSTATUS \
  149826. +Prefix##_Free##TypeName( \
  149827. + gcsMEM_FS_MEM_POOL MemPool, \
  149828. + Type * Pointer \
  149829. + ) \
  149830. +{ \
  149831. + gceSTATUS status; \
  149832. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149833. + status = gcfMEM_FSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
  149834. + gcmFOOTER(); \
  149835. + return status; \
  149836. +} \
  149837. + \
  149838. +gceSTATUS \
  149839. +Prefix##_Free##TypeName##List( \
  149840. + gcsMEM_FS_MEM_POOL MemPool, \
  149841. + Type * FirstPointer, \
  149842. + Type * LastPointer \
  149843. + ) \
  149844. +{ \
  149845. + gceSTATUS status; \
  149846. + gcmHEADER_ARG("MemPool=0x%x FirstPointer=0x%x LastPointer=0x%x", MemPool, FirstPointer, LastPointer); \
  149847. + status = gcfMEM_FSMemPoolFreeAList(MemPool, (gctPOINTER) FirstPointer, (gctPOINTER) LastPointer); \
  149848. + gcmFOOTER(); \
  149849. + return status; \
  149850. +}
  149851. +
  149852. +#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
  149853. +gceSTATUS \
  149854. +Prefix##_Allocate##TypeName( \
  149855. + gcsMEM_FS_MEM_POOL MemPool, \
  149856. + Type ** Pointer, \
  149857. + gctUINT Size \
  149858. + ) \
  149859. +{ \
  149860. + gceSTATUS status;\
  149861. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  149862. + status = gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer); \
  149863. + gcmFOOTER(); \
  149864. + return status; \
  149865. +} \
  149866. + \
  149867. +gceSTATUS \
  149868. + Prefix##_CAllocate##TypeName( \
  149869. + gcsMEM_FS_MEM_POOL MemPool, \
  149870. + Type ** Pointer, \
  149871. + gctUINT Size \
  149872. + ) \
  149873. +{ \
  149874. + gceSTATUS status; \
  149875. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  149876. + gcmERR_RETURN(gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer)); \
  149877. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, size); \
  149878. + gcmFOOTER(); \
  149879. + return gcvSTATUS_OK; \
  149880. +} \
  149881. + \
  149882. +gceSTATUS \
  149883. +Prefix##_Free##TypeName( \
  149884. + gcsMEM_FS_MEM_POOL MemPool, \
  149885. + Type * Pointer \
  149886. + ) \
  149887. +{ \
  149888. + gceSTATUS status; \
  149889. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pinter); \
  149890. + status = gcfMEM_VSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
  149891. + gcmFOOTER(); \
  149892. + return status; \
  149893. +}
  149894. +
  149895. +#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
  149896. +gceSTATUS \
  149897. +Prefix##_Allocate##TypeName( \
  149898. + gcsMEM_AFS_MEM_POOL MemPool, \
  149899. + Type ** Pointer, \
  149900. + gctUINT Count \
  149901. + ) \
  149902. +{ \
  149903. + gceSTATUS status; \
  149904. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  149905. + status = gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer); \
  149906. + gcmFOOTER(); \
  149907. + return status; \
  149908. +} \
  149909. + \
  149910. +gceSTATUS \
  149911. +Prefix##_CAllocate##TypeName( \
  149912. + gcsMEM_AFS_MEM_POOL MemPool, \
  149913. + Type ** Pointer, \
  149914. + gctUINT Count \
  149915. + ) \
  149916. +{ \
  149917. + gceSTATUS status; \
  149918. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  149919. + gcmERR_RETURN(gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer)); \
  149920. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
  149921. + gcmFOOTER(); \
  149922. + return gcvSTATUS_OK; \
  149923. +} \
  149924. + \
  149925. +gceSTATUS \
  149926. +Prefix##_Free##TypeName( \
  149927. + gcsMEM_AFS_MEM_POOL MemPool, \
  149928. + Type * Pointer \
  149929. + ) \
  149930. +{ \
  149931. + gceSTATUS status; \
  149932. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149933. + status = gcfMEM_AFSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
  149934. + gcmFOOTER(); \
  149935. + return status; \
  149936. +}
  149937. +
  149938. +#else
  149939. +
  149940. +#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
  149941. +gceSTATUS \
  149942. +Prefix##_Allocate##TypeName( \
  149943. + gcsMEM_FS_MEM_POOL MemPool, \
  149944. + Type ** Pointer \
  149945. + ) \
  149946. +{ \
  149947. + gceSTATUS status; \
  149948. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149949. + status = gcoOS_Allocate(MemPool, \
  149950. + gcmSIZEOF(Type), \
  149951. + (gctPOINTER *) Pointer); \
  149952. + gcmFOOTER(); \
  149953. + return status; \
  149954. +} \
  149955. + \
  149956. +gceSTATUS \
  149957. +Prefix##_CAllocate##TypeName( \
  149958. + gcsMEM_FS_MEM_POOL MemPool, \
  149959. + Type ** Pointer \
  149960. + ) \
  149961. +{ \
  149962. + gceSTATUS status; \
  149963. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149964. + gcmERR_RETURN(gcoOS_Allocate(MemPool, \
  149965. + gcmSIZEOF(Type), \
  149966. + (gctPOINTER *) Pointer)); \
  149967. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
  149968. + gcmFOOTER(); \
  149969. + return gcvSTATUS_OK; \
  149970. +} \
  149971. + \
  149972. +gceSTATUS \
  149973. +Prefix##_Free##TypeName( \
  149974. + gcsMEM_FS_MEM_POOL MemPool, \
  149975. + Type * Pointer \
  149976. + ) \
  149977. +{ \
  149978. + gceSTATUS status; \
  149979. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149980. + status = gcmOS_SAFE_FREE(MemPool, Pointer); \
  149981. + gcmFOOTER(); \
  149982. + return status; \
  149983. +}
  149984. +
  149985. +#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
  149986. +gceSTATUS \
  149987. +Prefix##_Allocate##TypeName( \
  149988. + gcsMEM_VS_MEM_POOL MemPool, \
  149989. + Type ** Pointer, \
  149990. + gctUINT Size \
  149991. + ) \
  149992. +{ \
  149993. + gceSTATUS status; \
  149994. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  149995. + status = gcoOS_Allocate(MemPool, \
  149996. + Size, \
  149997. + (gctPOINTER *) Pointer); \
  149998. + gcmFOOTER(); \
  149999. + return status; \
  150000. +} \
  150001. + \
  150002. +gceSTATUS \
  150003. +Prefix##_CAllocate##TypeName( \
  150004. + gcsMEM_VS_MEM_POOL MemPool, \
  150005. + Type ** Pointer, \
  150006. + gctUINT Size \
  150007. + ) \
  150008. +{ \
  150009. + gceSTATUS status; \
  150010. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  150011. + gcmERR_RETURN(gcoOS_Allocate(MemPool, \
  150012. + Size, \
  150013. + (gctPOINTER *) Pointer)); \
  150014. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Size); \
  150015. + gcmFOOTER(); \
  150016. + return gcvSTATUS_OK; \
  150017. +} \
  150018. + \
  150019. +gceSTATUS \
  150020. +Prefix##_Free##TypeName( \
  150021. + gcsMEM_VS_MEM_POOL MemPool, \
  150022. + Type * Pointer \
  150023. + ) \
  150024. +{ \
  150025. + gceSTATUS status; \
  150026. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  150027. + status = gcmOS_SAFE_FREE(MemPool, Pointer); \
  150028. + gcmFOOTER(); \
  150029. + return status; \
  150030. +}
  150031. +
  150032. +#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
  150033. +gceSTATUS \
  150034. +Prefix##_Allocate##TypeName( \
  150035. + gcsMEM_AFS_MEM_POOL MemPool, \
  150036. + Type ** Pointer, \
  150037. + gctUINT Count \
  150038. + ) \
  150039. +{ \
  150040. + gceSTATUS status; \
  150041. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  150042. + status = gcoOS_Allocate(MemPool, \
  150043. + Count * gcmSIZEOF(Type), \
  150044. + (gctPOINTER *) Pointer); \
  150045. + gcmFOOTER(); \
  150046. + return status; \
  150047. +} \
  150048. + \
  150049. +gceSTATUS \
  150050. +Prefix##_CAllocate##TypeName( \
  150051. + gcsMEM_AFS_MEM_POOL MemPool, \
  150052. + Type ** Pointer, \
  150053. + gctUINT Count \
  150054. + ) \
  150055. +{ \
  150056. + gceSTATUS status; \
  150057. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  150058. + gcmERR_RETURN(gcoOS_Allocate(MemPool, \
  150059. + Count * gcmSIZEOF(Type), \
  150060. + (gctPOINTER *) Pointer)); \
  150061. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
  150062. + gcmFOOTER(); \
  150063. + return gcvSTATUS_OK; \
  150064. +} \
  150065. + \
  150066. +gceSTATUS \
  150067. +Prefix##_Free##TypeName( \
  150068. + gcsMEM_AFS_MEM_POOL MemPool, \
  150069. + Type * Pointer \
  150070. + ) \
  150071. +{ \
  150072. + gceSTATUS status; \
  150073. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  150074. + status = gcmOS_SAFE_FREE(MemPool, Pointer); \
  150075. + gcmFOOTER(); \
  150076. + return status; \
  150077. +}
  150078. +#endif
  150079. +
  150080. +/*******************************************************************************
  150081. +** Memory Pool Data Functions
  150082. +*******************************************************************************/
  150083. +gceSTATUS
  150084. +gcfMEM_InitFSMemPool(
  150085. + IN gcsMEM_FS_MEM_POOL * MemPool,
  150086. + IN gcoOS OS,
  150087. + IN gctUINT NodeCount,
  150088. + IN gctUINT NodeSize
  150089. + );
  150090. +
  150091. +gceSTATUS
  150092. +gcfMEM_FreeFSMemPool(
  150093. + IN gcsMEM_FS_MEM_POOL * MemPool
  150094. + );
  150095. +
  150096. +gceSTATUS
  150097. +gcfMEM_FSMemPoolGetANode(
  150098. + IN gcsMEM_FS_MEM_POOL MemPool,
  150099. + OUT gctPOINTER * Node
  150100. + );
  150101. +
  150102. +gceSTATUS
  150103. +gcfMEM_FSMemPoolFreeANode(
  150104. + IN gcsMEM_FS_MEM_POOL MemPool,
  150105. + IN gctPOINTER Node
  150106. + );
  150107. +
  150108. +gceSTATUS
  150109. +gcfMEM_FSMemPoolFreeAList(
  150110. + IN gcsMEM_FS_MEM_POOL MemPool,
  150111. + IN gctPOINTER FirstNode,
  150112. + IN gctPOINTER LastNode
  150113. + );
  150114. +
  150115. +gceSTATUS
  150116. +gcfMEM_InitVSMemPool(
  150117. + IN gcsMEM_VS_MEM_POOL * MemPool,
  150118. + IN gcoOS OS,
  150119. + IN gctUINT BlockSize,
  150120. + IN gctBOOL RecycleFreeNode
  150121. + );
  150122. +
  150123. +gceSTATUS
  150124. +gcfMEM_FreeVSMemPool(
  150125. + IN gcsMEM_VS_MEM_POOL * MemPool
  150126. + );
  150127. +
  150128. +gceSTATUS
  150129. +gcfMEM_VSMemPoolGetANode(
  150130. + IN gcsMEM_VS_MEM_POOL MemPool,
  150131. + IN gctUINT Size,
  150132. + IN gctUINT Alignment,
  150133. + OUT gctPOINTER * Node
  150134. + );
  150135. +
  150136. +gceSTATUS
  150137. +gcfMEM_VSMemPoolFreeANode(
  150138. + IN gcsMEM_VS_MEM_POOL MemPool,
  150139. + IN gctPOINTER Node
  150140. + );
  150141. +
  150142. +gceSTATUS
  150143. +gcfMEM_InitAFSMemPool(
  150144. + IN gcsMEM_AFS_MEM_POOL *MemPool,
  150145. + IN gcoOS OS,
  150146. + IN gctUINT NodeCount,
  150147. + IN gctUINT NodeSize
  150148. + );
  150149. +
  150150. +gceSTATUS
  150151. +gcfMEM_FreeAFSMemPool(
  150152. + IN gcsMEM_AFS_MEM_POOL *MemPool
  150153. + );
  150154. +
  150155. +gceSTATUS
  150156. +gcfMEM_AFSMemPoolGetANode(
  150157. + IN gcsMEM_AFS_MEM_POOL MemPool,
  150158. + IN gctUINT Count,
  150159. + OUT gctPOINTER * Node
  150160. + );
  150161. +
  150162. +gceSTATUS
  150163. +gcfMEM_AFSMemPoolFreeANode(
  150164. + IN gcsMEM_AFS_MEM_POOL MemPool,
  150165. + IN gctPOINTER Node
  150166. + );
  150167. +
  150168. +#ifdef __cplusplus
  150169. +}
  150170. +#endif
  150171. +
  150172. +#endif /* VIVANTE_NO_3D */
  150173. +#endif /* __gc_hal_mem_h_ */
  150174. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
  150175. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h 1970-01-01 01:00:00.000000000 +0100
  150176. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h 2014-08-20 19:31:46.136869040 +0200
  150177. @@ -0,0 +1,947 @@
  150178. +/****************************************************************************
  150179. +*
  150180. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  150181. +*
  150182. +* This program is free software; you can redistribute it and/or modify
  150183. +* it under the terms of the GNU General Public License as published by
  150184. +* the Free Software Foundation; either version 2 of the license, or
  150185. +* (at your option) any later version.
  150186. +*
  150187. +* This program is distributed in the hope that it will be useful,
  150188. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  150189. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  150190. +* GNU General Public License for more details.
  150191. +*
  150192. +* You should have received a copy of the GNU General Public License
  150193. +* along with this program; if not write to the Free Software
  150194. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  150195. +*
  150196. +*****************************************************************************/
  150197. +
  150198. +
  150199. +#ifndef __gc_hal_options_h_
  150200. +#define __gc_hal_options_h_
  150201. +
  150202. +/*
  150203. + gcdPRINT_VERSION
  150204. +
  150205. + Print HAL version.
  150206. +*/
  150207. +#ifndef gcdPRINT_VERSION
  150208. +# define gcdPRINT_VERSION 0
  150209. +#endif
  150210. +
  150211. +/*
  150212. + USE_NEW_LINUX_SIGNAL
  150213. +
  150214. + This define enables the Linux kernel signaling between kernel and user.
  150215. +*/
  150216. +#ifndef USE_NEW_LINUX_SIGNAL
  150217. +# define USE_NEW_LINUX_SIGNAL 0
  150218. +#endif
  150219. +
  150220. +/*
  150221. + VIVANTE_PROFILER
  150222. +
  150223. + This define enables the profiler.
  150224. +*/
  150225. +#ifndef VIVANTE_PROFILER
  150226. +# define VIVANTE_PROFILER 1
  150227. +#endif
  150228. +
  150229. +#ifndef VIVANTE_PROFILER_PERDRAW
  150230. +# define VIVANTE_PROFILER_PERDRAW 0
  150231. +#endif
  150232. +
  150233. +/*
  150234. + VIVANTE_PROFILER_CONTEXT
  150235. +
  150236. + This define enables the profiler according to each hw context.
  150237. +*/
  150238. +#ifndef VIVANTE_PROFILER_CONTEXT
  150239. +# define VIVANTE_PROFILER_CONTEXT 1
  150240. +#endif
  150241. +
  150242. +/*
  150243. + gcdUSE_VG
  150244. +
  150245. + Enable VG HAL layer (only for GC350).
  150246. +*/
  150247. +#ifndef gcdUSE_VG
  150248. +# define gcdUSE_VG 0
  150249. +#endif
  150250. +
  150251. +/*
  150252. + USE_SW_FB
  150253. +
  150254. + Set to 1 if the frame buffer memory cannot be accessed by the GPU.
  150255. +*/
  150256. +#ifndef USE_SW_FB
  150257. +# define USE_SW_FB 0
  150258. +#endif
  150259. +
  150260. +/*
  150261. + USE_SUPER_SAMPLING
  150262. +
  150263. + This define enables super-sampling support.
  150264. +*/
  150265. +#define USE_SUPER_SAMPLING 0
  150266. +
  150267. +/*
  150268. + PROFILE_HAL_COUNTERS
  150269. +
  150270. + This define enables HAL counter profiling support. HW and SHADER
  150271. + counter profiling depends on this.
  150272. +*/
  150273. +#ifndef PROFILE_HAL_COUNTERS
  150274. +# define PROFILE_HAL_COUNTERS 1
  150275. +#endif
  150276. +
  150277. +/*
  150278. + PROFILE_HW_COUNTERS
  150279. +
  150280. + This define enables HW counter profiling support.
  150281. +*/
  150282. +#ifndef PROFILE_HW_COUNTERS
  150283. +# define PROFILE_HW_COUNTERS 1
  150284. +#endif
  150285. +
  150286. +/*
  150287. + PROFILE_SHADER_COUNTERS
  150288. +
  150289. + This define enables SHADER counter profiling support.
  150290. +*/
  150291. +#ifndef PROFILE_SHADER_COUNTERS
  150292. +# define PROFILE_SHADER_COUNTERS 1
  150293. +#endif
  150294. +
  150295. +/*
  150296. + COMMAND_PROCESSOR_VERSION
  150297. +
  150298. + The version of the command buffer and task manager.
  150299. +*/
  150300. +#define COMMAND_PROCESSOR_VERSION 1
  150301. +
  150302. +/*
  150303. + gcdDUMP_KEY
  150304. +
  150305. + Set this to a string that appears in 'cat /proc/<pid>/cmdline'. E.g. 'camera'.
  150306. + HAL will create dumps for the processes matching this key.
  150307. +*/
  150308. +#ifndef gcdDUMP_KEY
  150309. +# define gcdDUMP_KEY "process"
  150310. +#endif
  150311. +
  150312. +/*
  150313. + gcdDUMP_PATH
  150314. +
  150315. + The dump file location. Some processes cannot write to the sdcard.
  150316. + Try apps' data dir, e.g. /data/data/com.android.launcher
  150317. +*/
  150318. +#ifndef gcdDUMP_PATH
  150319. +#if defined(ANDROID)
  150320. +# define gcdDUMP_PATH "/mnt/sdcard/"
  150321. +#else
  150322. +# define gcdDUMP_PATH "./"
  150323. +#endif
  150324. +#endif
  150325. +
  150326. +/*
  150327. + gcdDUMP
  150328. +
  150329. + When set to 1, a dump of all states and memory uploads, as well as other
  150330. + hardware related execution will be printed to the debug console. This
  150331. + data can be used for playing back applications.
  150332. +*/
  150333. +#ifndef gcdDUMP
  150334. +# define gcdDUMP 0
  150335. +#endif
  150336. +
  150337. +/*
  150338. + gcdDUMP_API
  150339. +
  150340. + When set to 1, a high level dump of the EGL and GL/VG APs's are
  150341. + captured.
  150342. +*/
  150343. +#ifndef gcdDUMP_API
  150344. +# define gcdDUMP_API 0
  150345. +#endif
  150346. +
  150347. +/*
  150348. + gcdDUMP_FRAMERATE
  150349. + When set to a value other than zero, averaqe frame rate will be dumped.
  150350. + The value set is the starting frame that the average will be calculated.
  150351. + This is needed because sometimes first few frames are too slow to be included
  150352. + in the average. Frame count starts from 1.
  150353. +*/
  150354. +#ifndef gcdDUMP_FRAMERATE
  150355. +# define gcdDUMP_FRAMERATE 0
  150356. +#endif
  150357. +
  150358. +/*
  150359. + gcdVIRTUAL_COMMAND_BUFFER
  150360. + When set to 1, user command buffer and context buffer will be allocated
  150361. + from gcvPOOL_VIRTUAL.
  150362. +*/
  150363. +#ifndef gcdVIRTUAL_COMMAND_BUFFER
  150364. +# define gcdVIRTUAL_COMMAND_BUFFER 0
  150365. +#endif
  150366. +
  150367. +/*
  150368. + gcdENABLE_FSCALE_VAL_ADJUST
  150369. + When non-zero, FSCALE_VAL when gcvPOWER_ON can be adjusted externally.
  150370. + */
  150371. +#ifndef gcdENABLE_FSCALE_VAL_ADJUST
  150372. +# define gcdENABLE_FSCALE_VAL_ADJUST 1
  150373. +#endif
  150374. +
  150375. +/*
  150376. + gcdDUMP_IN_KERNEL
  150377. +
  150378. + When set to 1, all dumps will happen in the kernel. This is handy if
  150379. + you want the kernel to dump its command buffers as well and the data
  150380. + needs to be in sync.
  150381. +*/
  150382. +#ifndef gcdDUMP_IN_KERNEL
  150383. +# define gcdDUMP_IN_KERNEL 0
  150384. +#endif
  150385. +
  150386. +/*
  150387. + gcdDUMP_COMMAND
  150388. +
  150389. + When set to non-zero, the command queue will dump all incoming command
  150390. + and context buffers as well as all other modifications to the command
  150391. + queue.
  150392. +*/
  150393. +#ifndef gcdDUMP_COMMAND
  150394. +# define gcdDUMP_COMMAND 0
  150395. +#endif
  150396. +
  150397. +/*
  150398. + gcdDUMP_FRAME_TGA
  150399. +
  150400. + When set to a value other than 0, a dump of the frame specified by the value,
  150401. + will be done into frame.tga. Frame count starts from 1.
  150402. + */
  150403. +#ifndef gcdDUMP_FRAME_TGA
  150404. +#define gcdDUMP_FRAME_TGA 0
  150405. +#endif
  150406. +/*
  150407. + gcdNULL_DRIVER
  150408. +
  150409. + Set to 1 for infinite speed hardware.
  150410. + Set to 2 for bypassing the HAL.
  150411. + Set to 3 for bypassing the drivers.
  150412. +*/
  150413. +#ifndef gcdNULL_DRIVER
  150414. +# define gcdNULL_DRIVER 0
  150415. +#endif
  150416. +
  150417. +/*
  150418. + gcdENABLE_TIMEOUT_DETECTION
  150419. +
  150420. + Enable timeout detection.
  150421. +*/
  150422. +#ifndef gcdENABLE_TIMEOUT_DETECTION
  150423. +# define gcdENABLE_TIMEOUT_DETECTION 0
  150424. +#endif
  150425. +
  150426. +/*
  150427. + gcdCMD_BUFFER_SIZE
  150428. +
  150429. + Number of bytes in a command buffer.
  150430. +*/
  150431. +#ifndef gcdCMD_BUFFER_SIZE
  150432. +# define gcdCMD_BUFFER_SIZE (128 << 10)
  150433. +#endif
  150434. +
  150435. +/*
  150436. + gcdCMD_BUFFERS
  150437. +
  150438. + Number of command buffers to use per client.
  150439. +*/
  150440. +#ifndef gcdCMD_BUFFERS
  150441. +# define gcdCMD_BUFFERS 2
  150442. +#endif
  150443. +
  150444. +/*
  150445. + gcdMAX_CMD_BUFFERS
  150446. +
  150447. + Maximum number of command buffers to use per client.
  150448. +*/
  150449. +#ifndef gcdMAX_CMD_BUFFERS
  150450. +# define gcdMAX_CMD_BUFFERS 8
  150451. +#endif
  150452. +
  150453. +/*
  150454. + gcdCOMMAND_QUEUES
  150455. +
  150456. + Number of command queues in the kernel.
  150457. +*/
  150458. +#ifndef gcdCOMMAND_QUEUES
  150459. +# define gcdCOMMAND_QUEUES 2
  150460. +#endif
  150461. +
  150462. +/*
  150463. + gcdPOWER_CONTROL_DELAY
  150464. +
  150465. + The delay in milliseconds required to wait until the GPU has woke up
  150466. + from a suspend or power-down state. This is system dependent because
  150467. + the bus clock also needs to stabalize.
  150468. +*/
  150469. +#ifndef gcdPOWER_CONTROL_DELAY
  150470. +# define gcdPOWER_CONTROL_DELAY 0
  150471. +#endif
  150472. +
  150473. +/*
  150474. + gcdMIRROR_PAGETABLE
  150475. +
  150476. + Enable it when GPUs with old MMU and new MMU exist at same SoC. It makes
  150477. + each GPU use same virtual address to access same physical memory.
  150478. +*/
  150479. +#ifndef gcdMIRROR_PAGETABLE
  150480. +# define gcdMIRROR_PAGETABLE 0
  150481. +#endif
  150482. +
  150483. +/*
  150484. + gcdMMU_SIZE
  150485. +
  150486. + Size of the MMU page table in bytes. Each 4 bytes can hold 4kB worth of
  150487. + virtual data.
  150488. +*/
  150489. +#ifndef gcdMMU_SIZE
  150490. +#if gcdMIRROR_PAGETABLE
  150491. +# define gcdMMU_SIZE 0x200000
  150492. +#else
  150493. +# define gcdMMU_SIZE (2048 << 10)
  150494. +#endif
  150495. +#endif
  150496. +
  150497. +/*
  150498. + gcdSECURE_USER
  150499. +
  150500. + Use logical addresses instead of physical addresses in user land. In
  150501. + this case a hint table is created for both command buffers and context
  150502. + buffers, and that hint table will be used to patch up those buffers in
  150503. + the kernel when they are ready to submit.
  150504. +*/
  150505. +#ifndef gcdSECURE_USER
  150506. +# define gcdSECURE_USER 0
  150507. +#endif
  150508. +
  150509. +/*
  150510. + gcdSECURE_CACHE_SLOTS
  150511. +
  150512. + Number of slots in the logical to DMA address cache table. Each time a
  150513. + logical address needs to be translated into a DMA address for the GPU,
  150514. + this cache will be walked. The replacement scheme is LRU.
  150515. +*/
  150516. +#ifndef gcdSECURE_CACHE_SLOTS
  150517. +# define gcdSECURE_CACHE_SLOTS 1024
  150518. +#endif
  150519. +
  150520. +/*
  150521. + gcdSECURE_CACHE_METHOD
  150522. +
  150523. + Replacement scheme used for Secure Cache. The following options are
  150524. + available:
  150525. +
  150526. + gcdSECURE_CACHE_LRU
  150527. + A standard LRU cache.
  150528. +
  150529. + gcdSECURE_CACHE_LINEAR
  150530. + A linear walker with the idea that an application will always
  150531. + render the scene in a similar way, so the next entry in the
  150532. + cache should be a hit most of the time.
  150533. +
  150534. + gcdSECURE_CACHE_HASH
  150535. + A 256-entry hash table.
  150536. +
  150537. + gcdSECURE_CACHE_TABLE
  150538. + A simple cache but with potential of a lot of cache replacement.
  150539. +*/
  150540. +#ifndef gcdSECURE_CACHE_METHOD
  150541. +# define gcdSECURE_CACHE_METHOD gcdSECURE_CACHE_HASH
  150542. +#endif
  150543. +
  150544. +/*
  150545. + gcdREGISTER_ACCESS_FROM_USER
  150546. +
  150547. + Set to 1 to allow IOCTL calls to get through from user land. This
  150548. + should only be in debug or development drops.
  150549. +*/
  150550. +#ifndef gcdREGISTER_ACCESS_FROM_USER
  150551. +# define gcdREGISTER_ACCESS_FROM_USER 1
  150552. +#endif
  150553. +
  150554. +/*
  150555. + gcdUSER_HEAP_ALLOCATOR
  150556. +
  150557. + Set to 1 to enable user mode heap allocator for fast memory allocation
  150558. + and destroying. Otherwise, memory allocation/destroying in user mode
  150559. + will be directly managed by system. Only for linux for now.
  150560. +*/
  150561. +#ifndef gcdUSER_HEAP_ALLOCATOR
  150562. +# define gcdUSER_HEAP_ALLOCATOR 1
  150563. +#endif
  150564. +
  150565. +/*
  150566. + gcdHEAP_SIZE
  150567. +
  150568. + Set the allocation size for the internal heaps. Each time a heap is
  150569. + full, a new heap will be allocated with this minmimum amount of bytes.
  150570. + The bigger this size, the fewer heaps there are to allocate, the better
  150571. + the performance. However, heaps won't be freed until they are
  150572. + completely free, so there might be some more memory waste if the size is
  150573. + too big.
  150574. +*/
  150575. +#ifndef gcdHEAP_SIZE
  150576. +# define gcdHEAP_SIZE (64 << 10)
  150577. +#endif
  150578. +
  150579. +/*
  150580. + gcdPOWER_SUSNPEND_WHEN_IDLE
  150581. +
  150582. + Set to 1 to make GPU enter gcvPOWER_SUSPEND when idle detected,
  150583. + otherwise GPU will enter gcvPOWER_IDLE.
  150584. +*/
  150585. +#ifndef gcdPOWER_SUSNPEND_WHEN_IDLE
  150586. +# define gcdPOWER_SUSNPEND_WHEN_IDLE 1
  150587. +#endif
  150588. +
  150589. +/*
  150590. + gcdFPGA_BUILD
  150591. +
  150592. + This define enables work arounds for FPGA images.
  150593. +*/
  150594. +#ifndef gcdFPGA_BUILD
  150595. +# define gcdFPGA_BUILD 0
  150596. +#endif
  150597. +
  150598. +/*
  150599. + gcdGPU_TIMEOUT
  150600. +
  150601. + This define specified the number of milliseconds the system will wait
  150602. + before it broadcasts the GPU is stuck. In other words, it will define
  150603. + the timeout of any operation that needs to wait for the GPU.
  150604. +
  150605. + If the value is 0, no timeout will be checked for.
  150606. +*/
  150607. +#ifndef gcdGPU_TIMEOUT
  150608. +#if gcdFPGA_BUILD
  150609. +# define gcdGPU_TIMEOUT 0
  150610. +# else
  150611. +# define gcdGPU_TIMEOUT 20000
  150612. +# endif
  150613. +#endif
  150614. +
  150615. +/*
  150616. + gcdGPU_ADVANCETIMER
  150617. +
  150618. + it is advance timer.
  150619. +*/
  150620. +#ifndef gcdGPU_ADVANCETIMER
  150621. +# define gcdGPU_ADVANCETIMER 250
  150622. +#endif
  150623. +
  150624. +/*
  150625. + gcdSTATIC_LINK
  150626. +
  150627. + This define disalbes static linking;
  150628. +*/
  150629. +#ifndef gcdSTATIC_LINK
  150630. +# define gcdSTATIC_LINK 0
  150631. +#endif
  150632. +
  150633. +/*
  150634. + gcdUSE_NEW_HEAP
  150635. +
  150636. + Setting this define to 1 enables new heap.
  150637. +*/
  150638. +#ifndef gcdUSE_NEW_HEAP
  150639. +# define gcdUSE_NEW_HEAP 0
  150640. +#endif
  150641. +
  150642. +/*
  150643. + gcdCMD_NO_2D_CONTEXT
  150644. +
  150645. + This define enables no-context 2D command buffer.
  150646. +*/
  150647. +#ifndef gcdCMD_NO_2D_CONTEXT
  150648. +# define gcdCMD_NO_2D_CONTEXT 1
  150649. +#endif
  150650. +
  150651. +/*
  150652. + gcdENABLE_BANK_ALIGNMENT
  150653. +
  150654. + When enabled, video memory is allocated bank aligned. The vendor can modify
  150655. + _GetSurfaceBankAlignment() and gcoSURF_GetBankOffsetBytes() to define how
  150656. + different types of allocations are bank and channel aligned.
  150657. + When disabled (default), no bank alignment is done.
  150658. +*/
  150659. +#ifndef gcdENABLE_BANK_ALIGNMENT
  150660. +# define gcdENABLE_BANK_ALIGNMENT 0
  150661. +#endif
  150662. +
  150663. +/*
  150664. + gcdBANK_BIT_START
  150665. +
  150666. + Specifies the start bit of the bank (inclusive).
  150667. +*/
  150668. +#ifndef gcdBANK_BIT_START
  150669. +# define gcdBANK_BIT_START 12
  150670. +#endif
  150671. +
  150672. +/*
  150673. + gcdBANK_BIT_END
  150674. +
  150675. + Specifies the end bit of the bank (inclusive).
  150676. +*/
  150677. +#ifndef gcdBANK_BIT_END
  150678. +# define gcdBANK_BIT_END 14
  150679. +#endif
  150680. +
  150681. +/*
  150682. + gcdBANK_CHANNEL_BIT
  150683. +
  150684. + When set, video memory when allocated bank aligned is allocated such that
  150685. + render and depth buffer addresses alternate on the channel bit specified.
  150686. + This option has an effect only when gcdENABLE_BANK_ALIGNMENT is enabled.
  150687. + When disabled (default), no alteration is done.
  150688. +*/
  150689. +#ifndef gcdBANK_CHANNEL_BIT
  150690. +# define gcdBANK_CHANNEL_BIT 7
  150691. +#endif
  150692. +
  150693. +/*
  150694. + gcdDYNAMIC_SPEED
  150695. +
  150696. + When non-zero, it informs the kernel driver to use the speed throttling
  150697. + broadcasting functions to inform the system the GPU should be spet up or
  150698. + slowed down. It will send a broadcast for slowdown each "interval"
  150699. + specified by this define in milliseconds
  150700. + (gckOS_BroadcastCalibrateSpeed).
  150701. +*/
  150702. +#ifndef gcdDYNAMIC_SPEED
  150703. +# define gcdDYNAMIC_SPEED 2000
  150704. +#endif
  150705. +
  150706. +/*
  150707. + gcdDYNAMIC_EVENT_THRESHOLD
  150708. +
  150709. + When non-zero, it specifies the maximum number of available events at
  150710. + which the kernel driver will issue a broadcast to speed up the GPU
  150711. + (gckOS_BroadcastHurry).
  150712. +*/
  150713. +#ifndef gcdDYNAMIC_EVENT_THRESHOLD
  150714. +# define gcdDYNAMIC_EVENT_THRESHOLD 5
  150715. +#endif
  150716. +
  150717. +/*
  150718. + gcdENABLE_PROFILING
  150719. +
  150720. + Enable profiling macros.
  150721. +*/
  150722. +#ifndef gcdENABLE_PROFILING
  150723. +# define gcdENABLE_PROFILING 0
  150724. +#endif
  150725. +
  150726. +/*
  150727. + gcdENABLE_128B_MERGE
  150728. +
  150729. + Enable 128B merge for the BUS control.
  150730. +*/
  150731. +#ifndef gcdENABLE_128B_MERGE
  150732. +# define gcdENABLE_128B_MERGE 0
  150733. +#endif
  150734. +
  150735. +/*
  150736. + gcdFRAME_DB
  150737. +
  150738. + When non-zero, it specified the number of frames inside the frame
  150739. + database. The frame DB will collect per-frame timestamps and hardware
  150740. + counters.
  150741. +*/
  150742. +#ifndef gcdFRAME_DB
  150743. +# define gcdFRAME_DB 0
  150744. +# define gcdFRAME_DB_RESET 0
  150745. +# define gcdFRAME_DB_NAME "/var/log/frameDB.log"
  150746. +#endif
  150747. +
  150748. +/*
  150749. + gcdENABLE_VG
  150750. + enable the 2D openVG
  150751. +*/
  150752. +
  150753. +#ifndef gcdENABLE_VG
  150754. +# define gcdENABLE_VG 0
  150755. +#endif
  150756. +
  150757. +/*
  150758. + gcdDYNAMIC_MAP_RESERVED_MEMORY
  150759. +
  150760. + When gcvPOOL_SYSTEM is constructed from RESERVED memory,
  150761. + driver can map the whole reserved memory to kernel space
  150762. + at the beginning, or just map a piece of memory when need
  150763. + to access.
  150764. +
  150765. + Notice:
  150766. + - It's only for the 2D openVG. For other cores, there is
  150767. + _NO_ need to map reserved memory to kernel.
  150768. + - It's meaningless when memory is allocated by
  150769. + gckOS_AllocateContiguous, in that case, memory is always
  150770. + mapped by system when allocated.
  150771. +*/
  150772. +#ifndef gcdDYNAMIC_MAP_RESERVED_MEMORY
  150773. +# define gcdDYNAMIC_MAP_RESERVED_MEMORY 1
  150774. +#endif
  150775. +
  150776. +/*
  150777. + gcdPAGED_MEMORY_CACHEABLE
  150778. +
  150779. + When non-zero, paged memory will be cacheable.
  150780. +
  150781. + Normally, driver will detemines whether a video memory
  150782. + is cacheable or not. When cacheable is not neccessary,
  150783. + it will be writecombine.
  150784. +
  150785. + This option is only for those SOC which can't enable
  150786. + writecombine without enabling cacheable.
  150787. +*/
  150788. +
  150789. +#ifndef gcdPAGED_MEMORY_CACHEABLE
  150790. +# define gcdPAGED_MEMORY_CACHEABLE 0
  150791. +#endif
  150792. +
  150793. +/*
  150794. + gcdNONPAGED_MEMORY_CACHEABLE
  150795. +
  150796. + When non-zero, non paged memory will be cacheable.
  150797. +*/
  150798. +
  150799. +#ifndef gcdNONPAGED_MEMORY_CACHEABLE
  150800. +# define gcdNONPAGED_MEMORY_CACHEABLE 0
  150801. +#endif
  150802. +
  150803. +/*
  150804. + gcdNONPAGED_MEMORY_BUFFERABLE
  150805. +
  150806. + When non-zero, non paged memory will be bufferable.
  150807. + gcdNONPAGED_MEMORY_BUFFERABLE and gcdNONPAGED_MEMORY_CACHEABLE
  150808. + can't be set 1 at same time
  150809. +*/
  150810. +
  150811. +#ifndef gcdNONPAGED_MEMORY_BUFFERABLE
  150812. +# define gcdNONPAGED_MEMORY_BUFFERABLE 1
  150813. +#endif
  150814. +
  150815. +/*
  150816. + gcdENABLE_INFINITE_SPEED_HW
  150817. + enable the Infinte HW , this is for 2D openVG
  150818. +*/
  150819. +
  150820. +#ifndef gcdENABLE_INFINITE_SPEED_HW
  150821. +# define gcdENABLE_INFINITE_SPEED_HW 0
  150822. +#endif
  150823. +
  150824. +/*
  150825. + gcdENABLE_TS_DOUBLE_BUFFER
  150826. + enable the TS double buffer, this is for 2D openVG
  150827. +*/
  150828. +
  150829. +#ifndef gcdENABLE_TS_DOUBLE_BUFFER
  150830. +# define gcdENABLE_TS_DOUBLE_BUFFER 1
  150831. +#endif
  150832. +
  150833. +/*
  150834. + gcd6000_SUPPORT
  150835. +
  150836. + Temporary define to enable/disable 6000 support.
  150837. + */
  150838. +#ifndef gcd6000_SUPPORT
  150839. +# define gcd6000_SUPPORT 0
  150840. +#endif
  150841. +
  150842. +/*
  150843. + gcdPOWEROFF_TIMEOUT
  150844. +
  150845. + When non-zero, GPU will power off automatically from
  150846. + idle state, and gcdPOWEROFF_TIMEOUT is also the default
  150847. + timeout in milliseconds.
  150848. + */
  150849. +
  150850. +#ifndef gcdPOWEROFF_TIMEOUT
  150851. +# define gcdPOWEROFF_TIMEOUT 300
  150852. +#endif
  150853. +
  150854. +/*
  150855. + gcdUSE_VIDMEM_PER_PID
  150856. +*/
  150857. +#ifndef gcdUSE_VIDMEM_PER_PID
  150858. +# define gcdUSE_VIDMEM_PER_PID 0
  150859. +#endif
  150860. +
  150861. +/*
  150862. + QNX_SINGLE_THREADED_DEBUGGING
  150863. +*/
  150864. +#ifndef QNX_SINGLE_THREADED_DEBUGGING
  150865. +# define QNX_SINGLE_THREADED_DEBUGGING 0
  150866. +#endif
  150867. +
  150868. +/*
  150869. + gcdENABLE_RECOVERY
  150870. +
  150871. + This define enables the recovery code.
  150872. +*/
  150873. +#ifndef gcdENABLE_RECOVERY
  150874. +# define gcdENABLE_RECOVERY 1
  150875. +#endif
  150876. +
  150877. +/*
  150878. + gcdRENDER_THREADS
  150879. +
  150880. + Number of render threads. Make it zero, and there will be no render
  150881. + threads.
  150882. +*/
  150883. +#ifndef gcdRENDER_THREADS
  150884. +# define gcdRENDER_THREADS 0
  150885. +#endif
  150886. +
  150887. +/*
  150888. + gcdSMP
  150889. +
  150890. + This define enables SMP support.
  150891. +
  150892. + Currently, it only works on Linux/Android,
  150893. + Kbuild will config it according to whether
  150894. + CONFIG_SMP is set.
  150895. +
  150896. +*/
  150897. +#ifndef gcdSMP
  150898. +# define gcdSMP 0
  150899. +#endif
  150900. +
  150901. +/*
  150902. + gcdSUPPORT_SWAP_RECTANGLE
  150903. +
  150904. + Support swap with a specific rectangle.
  150905. +
  150906. + Set the rectangle with eglSetSwapRectangleANDROID api.
  150907. +*/
  150908. +#ifndef gcdSUPPORT_SWAP_RECTANGLE
  150909. +# define gcdSUPPORT_SWAP_RECTANGLE 0
  150910. +#endif
  150911. +
  150912. +/*
  150913. + gcdGPU_LINEAR_BUFFER_ENABLED
  150914. +
  150915. + Use linear buffer for GPU apps so HWC can do 2D composition.
  150916. +*/
  150917. +#ifndef gcdGPU_LINEAR_BUFFER_ENABLED
  150918. +# define gcdGPU_LINEAR_BUFFER_ENABLED 1
  150919. +#endif
  150920. +
  150921. +/*
  150922. + gcdENABLE_RENDER_INTO_WINDOW
  150923. +
  150924. + Enable Render-Into-Window (ie, No-Resolve) feature on android.
  150925. + NOTE that even if enabled, it still depends on hardware feature and
  150926. + android application behavior. When hardware feature or application
  150927. + behavior can not support render into window mode, it will fail back
  150928. + to normal mode.
  150929. + When Render-Into-Window is finally used, window back buffer of android
  150930. + applications will be allocated matching render target tiling format.
  150931. + Otherwise buffer tiling is decided by the above option
  150932. + 'gcdGPU_LINEAR_BUFFER_ENABLED'.
  150933. +*/
  150934. +#ifndef gcdENABLE_RENDER_INTO_WINDOW
  150935. +# define gcdENABLE_RENDER_INTO_WINDOW 1
  150936. +#endif
  150937. +
  150938. +/*
  150939. + gcdSHARED_RESOLVE_BUFFER_ENABLED
  150940. +
  150941. + Use shared resolve buffer for all app buffers.
  150942. +*/
  150943. +#ifndef gcdSHARED_RESOLVE_BUFFER_ENABLED
  150944. +# define gcdSHARED_RESOLVE_BUFFER_ENABLED 0
  150945. +#endif
  150946. +
  150947. +/*
  150948. + gcdUSE_TRIANGLE_STRIP_PATCH
  150949. + */
  150950. +#ifndef gcdUSE_TRIANGLE_STRIP_PATCH
  150951. +# define gcdUSE_TRIANGLE_STRIP_PATCH 1
  150952. +#endif
  150953. +
  150954. +/*
  150955. + gcdENABLE_OUTER_CACHE_PATCH
  150956. +
  150957. + Enable the outer cache patch.
  150958. +*/
  150959. +#ifndef gcdENABLE_OUTER_CACHE_PATCH
  150960. +# define gcdENABLE_OUTER_CACHE_PATCH 0
  150961. +#endif
  150962. +
  150963. +#ifndef gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST
  150964. +# ifdef ANDROID
  150965. +# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 1
  150966. +# else
  150967. +# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 0
  150968. +# endif
  150969. +#endif
  150970. +
  150971. +#ifndef gcdENABLE_PE_DITHER_FIX
  150972. +# define gcdENABLE_PE_DITHER_FIX 1
  150973. +#endif
  150974. +
  150975. +#ifndef gcdSHARED_PAGETABLE
  150976. +# define gcdSHARED_PAGETABLE 1
  150977. +#endif
  150978. +#ifndef gcdUSE_PVR
  150979. +# define gcdUSE_PVR 1
  150980. +#endif
  150981. +
  150982. +/*
  150983. + gcdSMALL_BLOCK_SIZE
  150984. +
  150985. + When non-zero, a part of VIDMEM will be reserved for requests
  150986. + whose requesting size is less than gcdSMALL_BLOCK_SIZE.
  150987. +
  150988. + For Linux, it's the size of a page. If this requeset fallbacks
  150989. + to gcvPOOL_CONTIGUOUS or gcvPOOL_VIRTUAL, memory will be wasted
  150990. + because they allocate a page at least.
  150991. + */
  150992. +#ifndef gcdSMALL_BLOCK_SIZE
  150993. +# define gcdSMALL_BLOCK_SIZE 4096
  150994. +# define gcdRATIO_FOR_SMALL_MEMORY 32
  150995. +#endif
  150996. +
  150997. +/*
  150998. + gcdCONTIGUOUS_SIZE_LIMIT
  150999. + When non-zero, size of video node from gcvPOOL_CONTIGUOUS is
  151000. + limited by gcdCONTIGUOUS_SIZE_LIMIT.
  151001. + */
  151002. +#ifndef gcdCONTIGUOUS_SIZE_LIMIT
  151003. +# define gcdCONTIGUOUS_SIZE_LIMIT 0
  151004. +#endif
  151005. +
  151006. +#ifndef gcdDISALBE_EARLY_EARLY_Z
  151007. +# define gcdDISALBE_EARLY_EARLY_Z 1
  151008. +#endif
  151009. +
  151010. +#ifndef gcdSHADER_SRC_BY_MACHINECODE
  151011. +# define gcdSHADER_SRC_BY_MACHINECODE 1
  151012. +#endif
  151013. +
  151014. +/*
  151015. + gcdLINK_QUEUE_SIZE
  151016. +
  151017. + When non-zero, driver maintains a queue to record information of
  151018. + latest lined context buffer and command buffer. Data in this queue
  151019. + is be used to debug.
  151020. +*/
  151021. +#ifndef gcdLINK_QUEUE_SIZE
  151022. +# define gcdLINK_QUEUE_SIZE 0
  151023. +#endif
  151024. +
  151025. +/* gcdALPHA_KILL_IN_SHADER
  151026. + *
  151027. + * Enable alpha kill inside the shader. This will be set automatically by the
  151028. + * HAL if certain states match a criteria.
  151029. + */
  151030. +#ifndef gcdALPHA_KILL_IN_SHADER
  151031. +# define gcdALPHA_KILL_IN_SHADER 1
  151032. +#endif
  151033. +
  151034. +/* gcdHIGH_PRECISION_DELAY_ENABLE
  151035. + *
  151036. + * Enable high precision schedule delay with 1ms unit. otherwise schedule delay up to 10ms.
  151037. + * Browser app performance will have obvious drop without this enablement
  151038. + */
  151039. +#ifndef gcdHIGH_PRECISION_DELAY_ENABLE
  151040. +# define gcdHIGH_PRECISION_DELAY_ENABLE 1
  151041. +#endif
  151042. +
  151043. +#ifndef gcdUSE_WCLIP_PATCH
  151044. +# define gcdUSE_WCLIP_PATCH 1
  151045. +#endif
  151046. +
  151047. +#ifndef gcdHZ_L2_DISALBE
  151048. +# define gcdHZ_L2_DISALBE 1
  151049. +#endif
  151050. +
  151051. +#ifndef gcdBUGFIX15_DISABLE
  151052. +# define gcdBUGFIX15_DISABLE 1
  151053. +#endif
  151054. +
  151055. +#ifndef gcdDISABLE_HZ_FAST_CLEAR
  151056. +# define gcdDISABLE_HZ_FAST_CLEAR 1
  151057. +#endif
  151058. +
  151059. +#ifndef gcdUSE_NPOT_PATCH
  151060. +#define gcdUSE_NPOT_PATCH 1
  151061. +#endif
  151062. +
  151063. +#ifndef gcdSYNC
  151064. +# define gcdSYNC 1
  151065. +#endif
  151066. +
  151067. +#ifndef gcdENABLE_SPECIAL_HINT3
  151068. +# define gcdENABLE_SPECIAL_HINT3 1
  151069. +#endif
  151070. +
  151071. +#if defined(ANDROID)
  151072. +#ifndef gcdPRE_ROTATION
  151073. +# define gcdPRE_ROTATION 1
  151074. +#endif
  151075. +#endif
  151076. +
  151077. +/*
  151078. + gcdDVFS
  151079. +
  151080. + When non-zero, software will make use of dynamic voltage and
  151081. + frequency feature.
  151082. + */
  151083. +#ifndef gcdDVFS
  151084. +# define gcdDVFS 0
  151085. +# define gcdDVFS_ANAYLSE_WINDOW 4
  151086. +# define gcdDVFS_POLLING_TIME (gcdDVFS_ANAYLSE_WINDOW * 4)
  151087. +#endif
  151088. +
  151089. +/*
  151090. + gcdANDROID_NATIVE_FENCE_SYNC
  151091. +
  151092. + Enable android native fence sync. It is introduced since jellybean-4.2.
  151093. + Depends on linux kernel option: CONFIG_SYNC.
  151094. +
  151095. + 0: Disabled
  151096. + 1: Build framework for native fence sync feature, and EGL extension
  151097. + 2: Enable async swap buffers for client
  151098. + * Native fence sync for client 'queueBuffer' in EGL, which is
  151099. + 'acquireFenceFd' for layer in compositor side.
  151100. + 3. Enable async hwcomposer composition.
  151101. + * 'releaseFenceFd' for layer in compositor side, which is native
  151102. + fence sync when client 'dequeueBuffer'
  151103. + * Native fence sync for compositor 'queueBuffer' in EGL, which is
  151104. + 'acquireFenceFd' for framebuffer target for DC
  151105. + */
  151106. +#ifndef gcdANDROID_NATIVE_FENCE_SYNC
  151107. +# define gcdANDROID_NATIVE_FENCE_SYNC 0
  151108. +#endif
  151109. +
  151110. +#ifndef gcdFORCE_MIPMAP
  151111. +# define gcdFORCE_MIPMAP 0
  151112. +#endif
  151113. +
  151114. +/*
  151115. + gcdFORCE_GAL_LOAD_TWICE
  151116. +
  151117. + When non-zero, each thread except the main one will load libGAL.so twice to avoid potential segmetantion fault when app using dlopen/dlclose.
  151118. + If threads exit arbitrarily, libGAL.so may not unload until the process quit.
  151119. + */
  151120. +#ifndef gcdFORCE_GAL_LOAD_TWICE
  151121. +# define gcdFORCE_GAL_LOAD_TWICE 0
  151122. +#endif
  151123. +
  151124. +#endif /* __gc_hal_options_h_ */
  151125. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h
  151126. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h 1970-01-01 01:00:00.000000000 +0100
  151127. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h 2014-08-20 19:23:53.566845873 +0200
  151128. @@ -0,0 +1,584 @@
  151129. +/****************************************************************************
  151130. +*
  151131. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  151132. +*
  151133. +* This program is free software; you can redistribute it and/or modify
  151134. +* it under the terms of the GNU General Public License as published by
  151135. +* the Free Software Foundation; either version 2 of the license, or
  151136. +* (at your option) any later version.
  151137. +*
  151138. +* This program is distributed in the hope that it will be useful,
  151139. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  151140. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  151141. +* GNU General Public License for more details.
  151142. +*
  151143. +* You should have received a copy of the GNU General Public License
  151144. +* along with this program; if not write to the Free Software
  151145. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  151146. +*
  151147. +*****************************************************************************/
  151148. +
  151149. +
  151150. +#ifndef __gc_hal_profiler_h_
  151151. +#define __gc_hal_profiler_h_
  151152. +
  151153. +#ifdef __cplusplus
  151154. +extern "C" {
  151155. +#endif
  151156. +
  151157. +#define GLVERTEX_OBJECT 10
  151158. +#define GLVERTEX_OBJECT_BYTES 11
  151159. +
  151160. +#define GLINDEX_OBJECT 20
  151161. +#define GLINDEX_OBJECT_BYTES 21
  151162. +
  151163. +#define GLTEXTURE_OBJECT 30
  151164. +#define GLTEXTURE_OBJECT_BYTES 31
  151165. +
  151166. +#if VIVANTE_PROFILER
  151167. +#define gcmPROFILE_GC(Enum, Value) gcoPROFILER_Count(gcvNULL, Enum, Value)
  151168. +#else
  151169. +#define gcmPROFILE_GC(Enum, Value) do { } while (gcvFALSE)
  151170. +#endif
  151171. +
  151172. +#ifndef gcdNEW_PROFILER_FILE
  151173. +#define gcdNEW_PROFILER_FILE 1
  151174. +#endif
  151175. +
  151176. +#define ES11_CALLS 151
  151177. +#define ES11_DRAWCALLS (ES11_CALLS + 1)
  151178. +#define ES11_STATECHANGECALLS (ES11_DRAWCALLS + 1)
  151179. +#define ES11_POINTCOUNT (ES11_STATECHANGECALLS + 1)
  151180. +#define ES11_LINECOUNT (ES11_POINTCOUNT + 1)
  151181. +#define ES11_TRIANGLECOUNT (ES11_LINECOUNT + 1)
  151182. +
  151183. +#define ES20_CALLS 159
  151184. +#define ES20_DRAWCALLS (ES20_CALLS + 1)
  151185. +#define ES20_STATECHANGECALLS (ES20_DRAWCALLS + 1)
  151186. +#define ES20_POINTCOUNT (ES20_STATECHANGECALLS + 1)
  151187. +#define ES20_LINECOUNT (ES20_POINTCOUNT + 1)
  151188. +#define ES20_TRIANGLECOUNT (ES20_LINECOUNT + 1)
  151189. +
  151190. +#define VG11_CALLS 88
  151191. +#define VG11_DRAWCALLS (VG11_CALLS + 1)
  151192. +#define VG11_STATECHANGECALLS (VG11_DRAWCALLS + 1)
  151193. +#define VG11_FILLCOUNT (VG11_STATECHANGECALLS + 1)
  151194. +#define VG11_STROKECOUNT (VG11_FILLCOUNT + 1)
  151195. +/* End of Driver API ID Definitions. */
  151196. +
  151197. +/* HAL & MISC IDs. */
  151198. +#define HAL_VERTBUFNEWBYTEALLOC 1
  151199. +#define HAL_VERTBUFTOTALBYTEALLOC (HAL_VERTBUFNEWBYTEALLOC + 1)
  151200. +#define HAL_VERTBUFNEWOBJALLOC (HAL_VERTBUFTOTALBYTEALLOC + 1)
  151201. +#define HAL_VERTBUFTOTALOBJALLOC (HAL_VERTBUFNEWOBJALLOC + 1)
  151202. +#define HAL_INDBUFNEWBYTEALLOC (HAL_VERTBUFTOTALOBJALLOC + 1)
  151203. +#define HAL_INDBUFTOTALBYTEALLOC (HAL_INDBUFNEWBYTEALLOC + 1)
  151204. +#define HAL_INDBUFNEWOBJALLOC (HAL_INDBUFTOTALBYTEALLOC + 1)
  151205. +#define HAL_INDBUFTOTALOBJALLOC (HAL_INDBUFNEWOBJALLOC + 1)
  151206. +#define HAL_TEXBUFNEWBYTEALLOC (HAL_INDBUFTOTALOBJALLOC + 1)
  151207. +#define HAL_TEXBUFTOTALBYTEALLOC (HAL_TEXBUFNEWBYTEALLOC + 1)
  151208. +#define HAL_TEXBUFNEWOBJALLOC (HAL_TEXBUFTOTALBYTEALLOC + 1)
  151209. +#define HAL_TEXBUFTOTALOBJALLOC (HAL_TEXBUFNEWOBJALLOC + 1)
  151210. +
  151211. +#define GPU_CYCLES 1
  151212. +#define GPU_READ64BYTE (GPU_CYCLES + 1)
  151213. +#define GPU_WRITE64BYTE (GPU_READ64BYTE + 1)
  151214. +#define GPU_TOTALCYCLES (GPU_WRITE64BYTE + 1)
  151215. +#define GPU_IDLECYCLES (GPU_TOTALCYCLES + 1)
  151216. +
  151217. +#define VS_INSTCOUNT 1
  151218. +#define VS_BRANCHINSTCOUNT (VS_INSTCOUNT + 1)
  151219. +#define VS_TEXLDINSTCOUNT (VS_BRANCHINSTCOUNT + 1)
  151220. +#define VS_RENDEREDVERTCOUNT (VS_TEXLDINSTCOUNT + 1)
  151221. +#define VS_SOURCE (VS_RENDEREDVERTCOUNT + 1)
  151222. +
  151223. +#define PS_INSTCOUNT 1
  151224. +#define PS_BRANCHINSTCOUNT (PS_INSTCOUNT + 1)
  151225. +#define PS_TEXLDINSTCOUNT (PS_BRANCHINSTCOUNT + 1)
  151226. +#define PS_RENDEREDPIXCOUNT (PS_TEXLDINSTCOUNT + 1)
  151227. +#define PS_SOURCE (PS_RENDEREDPIXCOUNT + 1)
  151228. +
  151229. +#define PA_INVERTCOUNT 1
  151230. +#define PA_INPRIMCOUNT (PA_INVERTCOUNT + 1)
  151231. +#define PA_OUTPRIMCOUNT (PA_INPRIMCOUNT + 1)
  151232. +#define PA_DEPTHCLIPCOUNT (PA_OUTPRIMCOUNT + 1)
  151233. +#define PA_TRIVIALREJCOUNT (PA_DEPTHCLIPCOUNT + 1)
  151234. +#define PA_CULLCOUNT (PA_TRIVIALREJCOUNT + 1)
  151235. +
  151236. +#define SE_TRIANGLECOUNT 1
  151237. +#define SE_LINECOUNT (SE_TRIANGLECOUNT + 1)
  151238. +
  151239. +#define RA_VALIDPIXCOUNT 1
  151240. +#define RA_TOTALQUADCOUNT (RA_VALIDPIXCOUNT + 1)
  151241. +#define RA_VALIDQUADCOUNTEZ (RA_TOTALQUADCOUNT + 1)
  151242. +#define RA_TOTALPRIMCOUNT (RA_VALIDQUADCOUNTEZ + 1)
  151243. +#define RA_PIPECACHEMISSCOUNT (RA_TOTALPRIMCOUNT + 1)
  151244. +#define RA_PREFCACHEMISSCOUNT (RA_PIPECACHEMISSCOUNT + 1)
  151245. +#define RA_EEZCULLCOUNT (RA_PREFCACHEMISSCOUNT + 1)
  151246. +
  151247. +#define TX_TOTBILINEARREQ 1
  151248. +#define TX_TOTTRILINEARREQ (TX_TOTBILINEARREQ + 1)
  151249. +#define TX_TOTDISCARDTEXREQ (TX_TOTTRILINEARREQ + 1)
  151250. +#define TX_TOTTEXREQ (TX_TOTDISCARDTEXREQ + 1)
  151251. +#define TX_MEMREADCOUNT (TX_TOTTEXREQ + 1)
  151252. +#define TX_MEMREADIN8BCOUNT (TX_MEMREADCOUNT + 1)
  151253. +#define TX_CACHEMISSCOUNT (TX_MEMREADIN8BCOUNT + 1)
  151254. +#define TX_CACHEHITTEXELCOUNT (TX_CACHEMISSCOUNT + 1)
  151255. +#define TX_CACHEMISSTEXELCOUNT (TX_CACHEHITTEXELCOUNT + 1)
  151256. +
  151257. +#define PE_KILLEDBYCOLOR 1
  151258. +#define PE_KILLEDBYDEPTH (PE_KILLEDBYCOLOR + 1)
  151259. +#define PE_DRAWNBYCOLOR (PE_KILLEDBYDEPTH + 1)
  151260. +#define PE_DRAWNBYDEPTH (PE_DRAWNBYCOLOR + 1)
  151261. +
  151262. +#define MC_READREQ8BPIPE 1
  151263. +#define MC_READREQ8BIP (MC_READREQ8BPIPE + 1)
  151264. +#define MC_WRITEREQ8BPIPE (MC_READREQ8BIP + 1)
  151265. +
  151266. +#define AXI_READREQSTALLED 1
  151267. +#define AXI_WRITEREQSTALLED (AXI_READREQSTALLED + 1)
  151268. +#define AXI_WRITEDATASTALLED (AXI_WRITEREQSTALLED + 1)
  151269. +
  151270. +#define PVS_INSTRCOUNT 1
  151271. +#define PVS_ALUINSTRCOUNT (PVS_INSTRCOUNT + 1)
  151272. +#define PVS_TEXINSTRCOUNT (PVS_ALUINSTRCOUNT + 1)
  151273. +#define PVS_ATTRIBCOUNT (PVS_TEXINSTRCOUNT + 1)
  151274. +#define PVS_UNIFORMCOUNT (PVS_ATTRIBCOUNT + 1)
  151275. +#define PVS_FUNCTIONCOUNT (PVS_UNIFORMCOUNT + 1)
  151276. +#define PVS_SOURCE (PVS_FUNCTIONCOUNT + 1)
  151277. +
  151278. +#define PPS_INSTRCOUNT 1
  151279. +#define PPS_ALUINSTRCOUNT (PPS_INSTRCOUNT + 1)
  151280. +#define PPS_TEXINSTRCOUNT (PPS_ALUINSTRCOUNT + 1)
  151281. +#define PPS_ATTRIBCOUNT (PPS_TEXINSTRCOUNT + 1)
  151282. +#define PPS_UNIFORMCOUNT (PPS_ATTRIBCOUNT + 1)
  151283. +#define PPS_FUNCTIONCOUNT (PPS_UNIFORMCOUNT + 1)
  151284. +#define PPS_SOURCE (PPS_FUNCTIONCOUNT + 1)
  151285. +/* End of MISC Counter IDs. */
  151286. +
  151287. +#ifdef gcdNEW_PROFILER_FILE
  151288. +
  151289. +/* Category Constants. */
  151290. +#define VPHEADER 0x010000
  151291. +#define VPG_INFO 0x020000
  151292. +#define VPG_TIME 0x030000
  151293. +#define VPG_MEM 0x040000
  151294. +#define VPG_ES11 0x050000
  151295. +#define VPG_ES20 0x060000
  151296. +#define VPG_VG11 0x070000
  151297. +#define VPG_HAL 0x080000
  151298. +#define VPG_HW 0x090000
  151299. +#define VPG_GPU 0x0a0000
  151300. +#define VPG_VS 0x0b0000
  151301. +#define VPG_PS 0x0c0000
  151302. +#define VPG_PA 0x0d0000
  151303. +#define VPG_SETUP 0x0e0000
  151304. +#define VPG_RA 0x0f0000
  151305. +#define VPG_TX 0x100000
  151306. +#define VPG_PE 0x110000
  151307. +#define VPG_MC 0x120000
  151308. +#define VPG_AXI 0x130000
  151309. +#define VPG_PROG 0x140000
  151310. +#define VPG_PVS 0x150000
  151311. +#define VPG_PPS 0x160000
  151312. +#define VPG_ES11_TIME 0x170000
  151313. +#define VPG_ES20_TIME 0x180000
  151314. +#define VPG_FRAME 0x190000
  151315. +#define VPG_ES11_DRAW 0x200000
  151316. +#define VPG_ES20_DRAW 0x210000
  151317. +#define VPG_END 0xff0000
  151318. +
  151319. +/* Info. */
  151320. +#define VPC_INFOCOMPANY (VPG_INFO + 1)
  151321. +#define VPC_INFOVERSION (VPC_INFOCOMPANY + 1)
  151322. +#define VPC_INFORENDERER (VPC_INFOVERSION + 1)
  151323. +#define VPC_INFOREVISION (VPC_INFORENDERER + 1)
  151324. +#define VPC_INFODRIVER (VPC_INFOREVISION + 1)
  151325. +#define VPC_INFODRIVERMODE (VPC_INFODRIVER + 1)
  151326. +#define VPC_INFOSCREENSIZE (VPC_INFODRIVERMODE + 1)
  151327. +
  151328. +/* Counter Constants. */
  151329. +#define VPC_ELAPSETIME (VPG_TIME + 1)
  151330. +#define VPC_CPUTIME (VPC_ELAPSETIME + 1)
  151331. +
  151332. +#define VPC_MEMMAXRES (VPG_MEM + 1)
  151333. +#define VPC_MEMSHARED (VPC_MEMMAXRES + 1)
  151334. +#define VPC_MEMUNSHAREDDATA (VPC_MEMSHARED + 1)
  151335. +#define VPC_MEMUNSHAREDSTACK (VPC_MEMUNSHAREDDATA + 1)
  151336. +
  151337. +/* OpenGL ES11 Statics Counter IDs. */
  151338. +#define VPC_ES11CALLS (VPG_ES11 + ES11_CALLS)
  151339. +#define VPC_ES11DRAWCALLS (VPG_ES11 + ES11_DRAWCALLS)
  151340. +#define VPC_ES11STATECHANGECALLS (VPG_ES11 + ES11_STATECHANGECALLS)
  151341. +#define VPC_ES11POINTCOUNT (VPG_ES11 + ES11_POINTCOUNT)
  151342. +#define VPC_ES11LINECOUNT (VPG_ES11 + ES11_LINECOUNT)
  151343. +#define VPC_ES11TRIANGLECOUNT (VPG_ES11 + ES11_TRIANGLECOUNT)
  151344. +
  151345. +/* OpenGL ES20 Statistics Counter IDs. */
  151346. +#define VPC_ES20CALLS (VPG_ES20 + ES20_CALLS)
  151347. +#define VPC_ES20DRAWCALLS (VPG_ES20 + ES20_DRAWCALLS)
  151348. +#define VPC_ES20STATECHANGECALLS (VPG_ES20 + ES20_STATECHANGECALLS)
  151349. +#define VPC_ES20POINTCOUNT (VPG_ES20 + ES20_POINTCOUNT)
  151350. +#define VPC_ES20LINECOUNT (VPG_ES20 + ES20_LINECOUNT)
  151351. +#define VPC_ES20TRIANGLECOUNT (VPG_ES20 + ES20_TRIANGLECOUNT)
  151352. +
  151353. +/* OpenVG Statistics Counter IDs. */
  151354. +#define VPC_VG11CALLS (VPG_VG11 + VG11_CALLS)
  151355. +#define VPC_VG11DRAWCALLS (VPG_VG11 + VG11_DRAWCALLS)
  151356. +#define VPC_VG11STATECHANGECALLS (VPG_VG11 + VG11_STATECHANGECALLS)
  151357. +#define VPC_VG11FILLCOUNT (VPG_VG11 + VG11_FILLCOUNT)
  151358. +#define VPC_VG11STROKECOUNT (VPG_VG11 + VG11_STROKECOUNT)
  151359. +
  151360. +/* HAL Counters. */
  151361. +#define VPC_HALVERTBUFNEWBYTEALLOC (VPG_HAL + HAL_VERTBUFNEWBYTEALLOC)
  151362. +#define VPC_HALVERTBUFTOTALBYTEALLOC (VPG_HAL + HAL_VERTBUFTOTALBYTEALLOC)
  151363. +#define VPC_HALVERTBUFNEWOBJALLOC (VPG_HAL + HAL_VERTBUFNEWOBJALLOC)
  151364. +#define VPC_HALVERTBUFTOTALOBJALLOC (VPG_HAL + HAL_VERTBUFTOTALOBJALLOC)
  151365. +#define VPC_HALINDBUFNEWBYTEALLOC (VPG_HAL + HAL_INDBUFNEWBYTEALLOC)
  151366. +#define VPC_HALINDBUFTOTALBYTEALLOC (VPG_HAL + HAL_INDBUFTOTALBYTEALLOC)
  151367. +#define VPC_HALINDBUFNEWOBJALLOC (VPG_HAL + HAL_INDBUFNEWOBJALLOC)
  151368. +#define VPC_HALINDBUFTOTALOBJALLOC (VPG_HAL + HAL_INDBUFTOTALOBJALLOC)
  151369. +#define VPC_HALTEXBUFNEWBYTEALLOC (VPG_HAL + HAL_TEXBUFNEWBYTEALLOC)
  151370. +#define VPC_HALTEXBUFTOTALBYTEALLOC (VPG_HAL + HAL_TEXBUFTOTALBYTEALLOC)
  151371. +#define VPC_HALTEXBUFNEWOBJALLOC (VPG_HAL + HAL_TEXBUFNEWOBJALLOC)
  151372. +#define VPC_HALTEXBUFTOTALOBJALLOC (VPG_HAL + HAL_TEXBUFTOTALOBJALLOC)
  151373. +
  151374. +/* HW: GPU Counters. */
  151375. +#define VPC_GPUCYCLES (VPG_GPU + GPU_CYCLES)
  151376. +#define VPC_GPUREAD64BYTE (VPG_GPU + GPU_READ64BYTE)
  151377. +#define VPC_GPUWRITE64BYTE (VPG_GPU + GPU_WRITE64BYTE)
  151378. +#define VPC_GPUTOTALCYCLES (VPG_GPU + GPU_TOTALCYCLES)
  151379. +#define VPC_GPUIDLECYCLES (VPG_GPU + GPU_IDLECYCLES)
  151380. +
  151381. +/* HW: Shader Counters. */
  151382. +#define VPC_VSINSTCOUNT (VPG_VS + VS_INSTCOUNT)
  151383. +#define VPC_VSBRANCHINSTCOUNT (VPG_VS + VS_BRANCHINSTCOUNT)
  151384. +#define VPC_VSTEXLDINSTCOUNT (VPG_VS + VS_TEXLDINSTCOUNT)
  151385. +#define VPC_VSRENDEREDVERTCOUNT (VPG_VS + VS_RENDEREDVERTCOUNT)
  151386. +/* HW: PS Count. */
  151387. +#define VPC_PSINSTCOUNT (VPG_PS + PS_INSTCOUNT)
  151388. +#define VPC_PSBRANCHINSTCOUNT (VPG_PS + PS_BRANCHINSTCOUNT)
  151389. +#define VPC_PSTEXLDINSTCOUNT (VPG_PS + PS_TEXLDINSTCOUNT)
  151390. +#define VPC_PSRENDEREDPIXCOUNT (VPG_PS + PS_RENDEREDPIXCOUNT)
  151391. +
  151392. +
  151393. +/* HW: PA Counters. */
  151394. +#define VPC_PAINVERTCOUNT (VPG_PA + PA_INVERTCOUNT)
  151395. +#define VPC_PAINPRIMCOUNT (VPG_PA + PA_INPRIMCOUNT)
  151396. +#define VPC_PAOUTPRIMCOUNT (VPG_PA + PA_OUTPRIMCOUNT)
  151397. +#define VPC_PADEPTHCLIPCOUNT (VPG_PA + PA_DEPTHCLIPCOUNT)
  151398. +#define VPC_PATRIVIALREJCOUNT (VPG_PA + PA_TRIVIALREJCOUNT)
  151399. +#define VPC_PACULLCOUNT (VPG_PA + PA_CULLCOUNT)
  151400. +
  151401. +/* HW: Setup Counters. */
  151402. +#define VPC_SETRIANGLECOUNT (VPG_SETUP + SE_TRIANGLECOUNT)
  151403. +#define VPC_SELINECOUNT (VPG_SETUP + SE_LINECOUNT)
  151404. +
  151405. +/* HW: RA Counters. */
  151406. +#define VPC_RAVALIDPIXCOUNT (VPG_RA + RA_VALIDPIXCOUNT)
  151407. +#define VPC_RATOTALQUADCOUNT (VPG_RA + RA_TOTALQUADCOUNT)
  151408. +#define VPC_RAVALIDQUADCOUNTEZ (VPG_RA + RA_VALIDQUADCOUNTEZ)
  151409. +#define VPC_RATOTALPRIMCOUNT (VPG_RA + RA_TOTALPRIMCOUNT)
  151410. +#define VPC_RAPIPECACHEMISSCOUNT (VPG_RA + RA_PIPECACHEMISSCOUNT)
  151411. +#define VPC_RAPREFCACHEMISSCOUNT (VPG_RA + RA_PREFCACHEMISSCOUNT)
  151412. +#define VPC_RAEEZCULLCOUNT (VPG_RA + RA_EEZCULLCOUNT)
  151413. +
  151414. +/* HW: TEX Counters. */
  151415. +#define VPC_TXTOTBILINEARREQ (VPG_TX + TX_TOTBILINEARREQ)
  151416. +#define VPC_TXTOTTRILINEARREQ (VPG_TX + TX_TOTTRILINEARREQ)
  151417. +#define VPC_TXTOTDISCARDTEXREQ (VPG_TX + TX_TOTDISCARDTEXREQ)
  151418. +#define VPC_TXTOTTEXREQ (VPG_TX + TX_TOTTEXREQ)
  151419. +#define VPC_TXMEMREADCOUNT (VPG_TX + TX_MEMREADCOUNT)
  151420. +#define VPC_TXMEMREADIN8BCOUNT (VPG_TX + TX_MEMREADIN8BCOUNT)
  151421. +#define VPC_TXCACHEMISSCOUNT (VPG_TX + TX_CACHEMISSCOUNT)
  151422. +#define VPC_TXCACHEHITTEXELCOUNT (VPG_TX + TX_CACHEHITTEXELCOUNT)
  151423. +#define VPC_TXCACHEMISSTEXELCOUNT (VPG_TX + TX_CACHEMISSTEXELCOUNT)
  151424. +
  151425. +/* HW: PE Counters. */
  151426. +#define VPC_PEKILLEDBYCOLOR (VPG_PE + PE_KILLEDBYCOLOR)
  151427. +#define VPC_PEKILLEDBYDEPTH (VPG_PE + PE_KILLEDBYDEPTH)
  151428. +#define VPC_PEDRAWNBYCOLOR (VPG_PE + PE_DRAWNBYCOLOR)
  151429. +#define VPC_PEDRAWNBYDEPTH (VPG_PE + PE_DRAWNBYDEPTH)
  151430. +
  151431. +/* HW: MC Counters. */
  151432. +#define VPC_MCREADREQ8BPIPE (VPG_MC + MC_READREQ8BPIPE)
  151433. +#define VPC_MCREADREQ8BIP (VPG_MC + MC_READREQ8BIP)
  151434. +#define VPC_MCWRITEREQ8BPIPE (VPG_MC + MC_WRITEREQ8BPIPE)
  151435. +
  151436. +/* HW: AXI Counters. */
  151437. +#define VPC_AXIREADREQSTALLED (VPG_AXI + AXI_READREQSTALLED)
  151438. +#define VPC_AXIWRITEREQSTALLED (VPG_AXI + AXI_WRITEREQSTALLED)
  151439. +#define VPC_AXIWRITEDATASTALLED (VPG_AXI + AXI_WRITEDATASTALLED)
  151440. +
  151441. +/* PROGRAM: Shader program counters. */
  151442. +#define VPC_PVSINSTRCOUNT (VPG_PVS + PVS_INSTRCOUNT)
  151443. +#define VPC_PVSALUINSTRCOUNT (VPG_PVS + PVS_ALUINSTRCOUNT)
  151444. +#define VPC_PVSTEXINSTRCOUNT (VPG_PVS + PVS_TEXINSTRCOUNT)
  151445. +#define VPC_PVSATTRIBCOUNT (VPG_PVS + PVS_ATTRIBCOUNT)
  151446. +#define VPC_PVSUNIFORMCOUNT (VPG_PVS + PVS_UNIFORMCOUNT)
  151447. +#define VPC_PVSFUNCTIONCOUNT (VPG_PVS + PVS_FUNCTIONCOUNT)
  151448. +#define VPC_PVSSOURCE (VPG_PVS + PVS_SOURCE)
  151449. +
  151450. +#define VPC_PPSINSTRCOUNT (VPG_PPS + PPS_INSTRCOUNT)
  151451. +#define VPC_PPSALUINSTRCOUNT (VPG_PPS + PPS_ALUINSTRCOUNT)
  151452. +#define VPC_PPSTEXINSTRCOUNT (VPG_PPS + PPS_TEXINSTRCOUNT)
  151453. +#define VPC_PPSATTRIBCOUNT (VPG_PPS + PPS_ATTRIBCOUNT)
  151454. +#define VPC_PPSUNIFORMCOUNT (VPG_PPS + PPS_UNIFORMCOUNT)
  151455. +#define VPC_PPSFUNCTIONCOUNT (VPG_PPS + PPS_FUNCTIONCOUNT)
  151456. +#define VPC_PPSSOURCE (VPG_PPS + PPS_SOURCE)
  151457. +
  151458. +#define VPC_PROGRAMHANDLE (VPG_PROG + 1)
  151459. +
  151460. +#define VPG_ES20_DRAW_NO (VPG_ES20_DRAW + 1)
  151461. +#define VPG_ES11_DRAW_NO (VPG_ES11_DRAW + 1)
  151462. +
  151463. +#define VPG_FRAME_USEVBO (VPG_FRAME + 1)
  151464. +
  151465. +#endif
  151466. +
  151467. +
  151468. +/* HW profile information. */
  151469. +typedef struct _gcsPROFILER_COUNTERS
  151470. +{
  151471. + /* HW static counters. */
  151472. + gctUINT32 gpuClock;
  151473. + gctUINT32 axiClock;
  151474. + gctUINT32 shaderClock;
  151475. +
  151476. + /* HW vairable counters. */
  151477. + gctUINT32 gpuClockStart;
  151478. + gctUINT32 gpuClockEnd;
  151479. +
  151480. + /* HW vairable counters. */
  151481. + gctUINT32 gpuCyclesCounter;
  151482. + gctUINT32 gpuTotalCyclesCounter;
  151483. + gctUINT32 gpuIdleCyclesCounter;
  151484. + gctUINT32 gpuTotalRead64BytesPerFrame;
  151485. + gctUINT32 gpuTotalWrite64BytesPerFrame;
  151486. +
  151487. + /* PE */
  151488. + gctUINT32 pe_pixel_count_killed_by_color_pipe;
  151489. + gctUINT32 pe_pixel_count_killed_by_depth_pipe;
  151490. + gctUINT32 pe_pixel_count_drawn_by_color_pipe;
  151491. + gctUINT32 pe_pixel_count_drawn_by_depth_pipe;
  151492. +
  151493. + /* SH */
  151494. + gctUINT32 ps_inst_counter;
  151495. + gctUINT32 rendered_pixel_counter;
  151496. + gctUINT32 vs_inst_counter;
  151497. + gctUINT32 rendered_vertice_counter;
  151498. + gctUINT32 vtx_branch_inst_counter;
  151499. + gctUINT32 vtx_texld_inst_counter;
  151500. + gctUINT32 pxl_branch_inst_counter;
  151501. + gctUINT32 pxl_texld_inst_counter;
  151502. +
  151503. + /* PA */
  151504. + gctUINT32 pa_input_vtx_counter;
  151505. + gctUINT32 pa_input_prim_counter;
  151506. + gctUINT32 pa_output_prim_counter;
  151507. + gctUINT32 pa_depth_clipped_counter;
  151508. + gctUINT32 pa_trivial_rejected_counter;
  151509. + gctUINT32 pa_culled_counter;
  151510. +
  151511. + /* SE */
  151512. + gctUINT32 se_culled_triangle_count;
  151513. + gctUINT32 se_culled_lines_count;
  151514. +
  151515. + /* RA */
  151516. + gctUINT32 ra_valid_pixel_count;
  151517. + gctUINT32 ra_total_quad_count;
  151518. + gctUINT32 ra_valid_quad_count_after_early_z;
  151519. + gctUINT32 ra_total_primitive_count;
  151520. + gctUINT32 ra_pipe_cache_miss_counter;
  151521. + gctUINT32 ra_prefetch_cache_miss_counter;
  151522. + gctUINT32 ra_eez_culled_counter;
  151523. +
  151524. + /* TX */
  151525. + gctUINT32 tx_total_bilinear_requests;
  151526. + gctUINT32 tx_total_trilinear_requests;
  151527. + gctUINT32 tx_total_discarded_texture_requests;
  151528. + gctUINT32 tx_total_texture_requests;
  151529. + gctUINT32 tx_mem_read_count;
  151530. + gctUINT32 tx_mem_read_in_8B_count;
  151531. + gctUINT32 tx_cache_miss_count;
  151532. + gctUINT32 tx_cache_hit_texel_count;
  151533. + gctUINT32 tx_cache_miss_texel_count;
  151534. +
  151535. + /* MC */
  151536. + gctUINT32 mc_total_read_req_8B_from_pipeline;
  151537. + gctUINT32 mc_total_read_req_8B_from_IP;
  151538. + gctUINT32 mc_total_write_req_8B_from_pipeline;
  151539. +
  151540. + /* HI */
  151541. + gctUINT32 hi_axi_cycles_read_request_stalled;
  151542. + gctUINT32 hi_axi_cycles_write_request_stalled;
  151543. + gctUINT32 hi_axi_cycles_write_data_stalled;
  151544. +}
  151545. +gcsPROFILER_COUNTERS;
  151546. +
  151547. +/* HAL profile information. */
  151548. +typedef struct _gcsPROFILER
  151549. +{
  151550. + gctUINT32 enable;
  151551. + gctBOOL enableHal;
  151552. + gctBOOL enableHW;
  151553. + gctBOOL enableSH;
  151554. + gctBOOL isSyncMode;
  151555. +
  151556. + gctBOOL useSocket;
  151557. + gctINT sockFd;
  151558. +
  151559. + gctFILE file;
  151560. +
  151561. + /* Aggregate Information */
  151562. +
  151563. + /* Clock Info */
  151564. + gctUINT64 frameStart;
  151565. + gctUINT64 frameEnd;
  151566. +
  151567. + /* Current frame information */
  151568. + gctUINT32 frameNumber;
  151569. + gctUINT64 frameStartTimeusec;
  151570. + gctUINT64 frameEndTimeusec;
  151571. + gctUINT64 frameStartCPUTimeusec;
  151572. + gctUINT64 frameEndCPUTimeusec;
  151573. +
  151574. +#if PROFILE_HAL_COUNTERS
  151575. + gctUINT32 vertexBufferTotalBytesAlloc;
  151576. + gctUINT32 vertexBufferNewBytesAlloc;
  151577. + int vertexBufferTotalObjectsAlloc;
  151578. + int vertexBufferNewObjectsAlloc;
  151579. +
  151580. + gctUINT32 indexBufferTotalBytesAlloc;
  151581. + gctUINT32 indexBufferNewBytesAlloc;
  151582. + int indexBufferTotalObjectsAlloc;
  151583. + int indexBufferNewObjectsAlloc;
  151584. +
  151585. + gctUINT32 textureBufferTotalBytesAlloc;
  151586. + gctUINT32 textureBufferNewBytesAlloc;
  151587. + int textureBufferTotalObjectsAlloc;
  151588. + int textureBufferNewObjectsAlloc;
  151589. +
  151590. + gctUINT32 numCommits;
  151591. + gctUINT32 drawPointCount;
  151592. + gctUINT32 drawLineCount;
  151593. + gctUINT32 drawTriangleCount;
  151594. + gctUINT32 drawVertexCount;
  151595. + gctUINT32 redundantStateChangeCalls;
  151596. +#endif
  151597. +
  151598. + gctUINT32 prevVSInstCount;
  151599. + gctUINT32 prevVSBranchInstCount;
  151600. + gctUINT32 prevVSTexInstCount;
  151601. + gctUINT32 prevVSVertexCount;
  151602. + gctUINT32 prevPSInstCount;
  151603. + gctUINT32 prevPSBranchInstCount;
  151604. + gctUINT32 prevPSTexInstCount;
  151605. + gctUINT32 prevPSPixelCount;
  151606. +
  151607. + char* psSource;
  151608. + char* vsSource;
  151609. +
  151610. +}
  151611. +gcsPROFILER;
  151612. +
  151613. +/* Memory profile information. */
  151614. +struct _gcsMemProfile
  151615. +{
  151616. + /* Memory Usage */
  151617. + gctUINT32 videoMemUsed;
  151618. + gctUINT32 systemMemUsed;
  151619. + gctUINT32 commitBufferSize;
  151620. + gctUINT32 contextBufferCopyBytes;
  151621. +};
  151622. +
  151623. +/* Shader profile information. */
  151624. +struct _gcsSHADER_PROFILER
  151625. +{
  151626. + gctUINT32 shaderLength;
  151627. + gctUINT32 shaderALUCycles;
  151628. + gctUINT32 shaderTexLoadCycles;
  151629. + gctUINT32 shaderTempRegCount;
  151630. + gctUINT32 shaderSamplerRegCount;
  151631. + gctUINT32 shaderInputRegCount;
  151632. + gctUINT32 shaderOutputRegCount;
  151633. +};
  151634. +
  151635. +/* Initialize the gcsProfiler. */
  151636. +gceSTATUS
  151637. +gcoPROFILER_Initialize(
  151638. + IN gcoHAL Hal
  151639. + );
  151640. +
  151641. +/* Destroy the gcProfiler. */
  151642. +gceSTATUS
  151643. +gcoPROFILER_Destroy(
  151644. + IN gcoHAL Hal
  151645. + );
  151646. +
  151647. +/* Write data to profiler. */
  151648. +gceSTATUS
  151649. +gcoPROFILER_Write(
  151650. + IN gcoHAL Hal,
  151651. + IN gctSIZE_T ByteCount,
  151652. + IN gctCONST_POINTER Data
  151653. + );
  151654. +
  151655. +/* Flush data out. */
  151656. +gceSTATUS
  151657. +gcoPROFILER_Flush(
  151658. + IN gcoHAL Hal
  151659. + );
  151660. +
  151661. +/* Call to signal end of frame. */
  151662. +gceSTATUS
  151663. +gcoPROFILER_EndFrame(
  151664. + IN gcoHAL Hal
  151665. + );
  151666. +
  151667. +/* Call to signal end of draw. */
  151668. +gceSTATUS
  151669. +gcoPROFILER_EndDraw(
  151670. + IN gcoHAL Hal,
  151671. + IN gctBOOL FirstDraw
  151672. + );
  151673. +
  151674. +/* Increase profile counter Enum by Value. */
  151675. +gceSTATUS
  151676. +gcoPROFILER_Count(
  151677. + IN gcoHAL Hal,
  151678. + IN gctUINT32 Enum,
  151679. + IN gctINT Value
  151680. + );
  151681. +
  151682. +gceSTATUS
  151683. +gcoPROFILER_ShaderSourceFS(
  151684. + IN gcoHAL Hal,
  151685. + IN char* source
  151686. + );
  151687. +
  151688. +gceSTATUS
  151689. +gcoPROFILER_ShaderSourceVS(
  151690. + IN gcoHAL Hal,
  151691. + IN char* source
  151692. + );
  151693. +
  151694. +/* Profile input vertex shader. */
  151695. +gceSTATUS
  151696. +gcoPROFILER_ShaderVS(
  151697. + IN gcoHAL Hal,
  151698. + IN gctPOINTER Vs
  151699. + );
  151700. +
  151701. +/* Profile input fragment shader. */
  151702. +gceSTATUS
  151703. +gcoPROFILER_ShaderFS(
  151704. + IN gcoHAL Hal,
  151705. + IN gctPOINTER Fs
  151706. + );
  151707. +
  151708. +#ifdef __cplusplus
  151709. +}
  151710. +#endif
  151711. +
  151712. +#endif /* __gc_hal_profiler_h_ */
  151713. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
  151714. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h 1970-01-01 01:00:00.000000000 +0100
  151715. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h 2014-08-20 19:23:53.570845890 +0200
  151716. @@ -0,0 +1,1010 @@
  151717. +/****************************************************************************
  151718. +*
  151719. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  151720. +*
  151721. +* This program is free software; you can redistribute it and/or modify
  151722. +* it under the terms of the GNU General Public License as published by
  151723. +* the Free Software Foundation; either version 2 of the license, or
  151724. +* (at your option) any later version.
  151725. +*
  151726. +* This program is distributed in the hope that it will be useful,
  151727. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  151728. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  151729. +* GNU General Public License for more details.
  151730. +*
  151731. +* You should have received a copy of the GNU General Public License
  151732. +* along with this program; if not write to the Free Software
  151733. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  151734. +*
  151735. +*****************************************************************************/
  151736. +
  151737. +
  151738. +#ifndef __gc_hal_raster_h_
  151739. +#define __gc_hal_raster_h_
  151740. +
  151741. +#include "gc_hal_enum.h"
  151742. +#include "gc_hal_types.h"
  151743. +
  151744. +#ifdef __cplusplus
  151745. +extern "C" {
  151746. +#endif
  151747. +
  151748. +/******************************************************************************\
  151749. +****************************** Object Declarations *****************************
  151750. +\******************************************************************************/
  151751. +
  151752. +typedef struct _gcoBRUSH * gcoBRUSH;
  151753. +typedef struct _gcoBRUSH_CACHE * gcoBRUSH_CACHE;
  151754. +
  151755. +/******************************************************************************\
  151756. +******************************** gcoBRUSH Object *******************************
  151757. +\******************************************************************************/
  151758. +
  151759. +/* Create a new solid color gcoBRUSH object. */
  151760. +gceSTATUS
  151761. +gcoBRUSH_ConstructSingleColor(
  151762. + IN gcoHAL Hal,
  151763. + IN gctUINT32 ColorConvert,
  151764. + IN gctUINT32 Color,
  151765. + IN gctUINT64 Mask,
  151766. + gcoBRUSH * Brush
  151767. + );
  151768. +
  151769. +/* Create a new monochrome gcoBRUSH object. */
  151770. +gceSTATUS
  151771. +gcoBRUSH_ConstructMonochrome(
  151772. + IN gcoHAL Hal,
  151773. + IN gctUINT32 OriginX,
  151774. + IN gctUINT32 OriginY,
  151775. + IN gctUINT32 ColorConvert,
  151776. + IN gctUINT32 FgColor,
  151777. + IN gctUINT32 BgColor,
  151778. + IN gctUINT64 Bits,
  151779. + IN gctUINT64 Mask,
  151780. + gcoBRUSH * Brush
  151781. + );
  151782. +
  151783. +/* Create a color gcoBRUSH object. */
  151784. +gceSTATUS
  151785. +gcoBRUSH_ConstructColor(
  151786. + IN gcoHAL Hal,
  151787. + IN gctUINT32 OriginX,
  151788. + IN gctUINT32 OriginY,
  151789. + IN gctPOINTER Address,
  151790. + IN gceSURF_FORMAT Format,
  151791. + IN gctUINT64 Mask,
  151792. + gcoBRUSH * Brush
  151793. + );
  151794. +
  151795. +/* Destroy an gcoBRUSH object. */
  151796. +gceSTATUS
  151797. +gcoBRUSH_Destroy(
  151798. + IN gcoBRUSH Brush
  151799. + );
  151800. +
  151801. +/******************************************************************************\
  151802. +******************************** gcoSURF Object *******************************
  151803. +\******************************************************************************/
  151804. +
  151805. +/* Set cipping rectangle. */
  151806. +gceSTATUS
  151807. +gcoSURF_SetClipping(
  151808. + IN gcoSURF Surface
  151809. + );
  151810. +
  151811. +/* Clear one or more rectangular areas. */
  151812. +gceSTATUS
  151813. +gcoSURF_Clear2D(
  151814. + IN gcoSURF DestSurface,
  151815. + IN gctUINT32 RectCount,
  151816. + IN gcsRECT_PTR DestRect,
  151817. + IN gctUINT32 LoColor,
  151818. + IN gctUINT32 HiColor
  151819. + );
  151820. +
  151821. +/* Draw one or more Bresenham lines. */
  151822. +gceSTATUS
  151823. +gcoSURF_Line(
  151824. + IN gcoSURF Surface,
  151825. + IN gctUINT32 LineCount,
  151826. + IN gcsRECT_PTR Position,
  151827. + IN gcoBRUSH Brush,
  151828. + IN gctUINT8 FgRop,
  151829. + IN gctUINT8 BgRop
  151830. + );
  151831. +
  151832. +/* Generic rectangular blit. */
  151833. +gceSTATUS
  151834. +gcoSURF_Blit(
  151835. + IN OPTIONAL gcoSURF SrcSurface,
  151836. + IN gcoSURF DestSurface,
  151837. + IN gctUINT32 RectCount,
  151838. + IN OPTIONAL gcsRECT_PTR SrcRect,
  151839. + IN gcsRECT_PTR DestRect,
  151840. + IN OPTIONAL gcoBRUSH Brush,
  151841. + IN gctUINT8 FgRop,
  151842. + IN gctUINT8 BgRop,
  151843. + IN OPTIONAL gceSURF_TRANSPARENCY Transparency,
  151844. + IN OPTIONAL gctUINT32 TransparencyColor,
  151845. + IN OPTIONAL gctPOINTER Mask,
  151846. + IN OPTIONAL gceSURF_MONOPACK MaskPack
  151847. + );
  151848. +
  151849. +/* Monochrome blit. */
  151850. +gceSTATUS
  151851. +gcoSURF_MonoBlit(
  151852. + IN gcoSURF DestSurface,
  151853. + IN gctPOINTER Source,
  151854. + IN gceSURF_MONOPACK SourcePack,
  151855. + IN gcsPOINT_PTR SourceSize,
  151856. + IN gcsPOINT_PTR SourceOrigin,
  151857. + IN gcsRECT_PTR DestRect,
  151858. + IN OPTIONAL gcoBRUSH Brush,
  151859. + IN gctUINT8 FgRop,
  151860. + IN gctUINT8 BgRop,
  151861. + IN gctBOOL ColorConvert,
  151862. + IN gctUINT8 MonoTransparency,
  151863. + IN gceSURF_TRANSPARENCY Transparency,
  151864. + IN gctUINT32 FgColor,
  151865. + IN gctUINT32 BgColor
  151866. + );
  151867. +
  151868. +/* Filter blit. */
  151869. +gceSTATUS
  151870. +gcoSURF_FilterBlit(
  151871. + IN gcoSURF SrcSurface,
  151872. + IN gcoSURF DestSurface,
  151873. + IN gcsRECT_PTR SrcRect,
  151874. + IN gcsRECT_PTR DestRect,
  151875. + IN gcsRECT_PTR DestSubRect
  151876. + );
  151877. +
  151878. +/* Enable alpha blending engine in the hardware and disengage the ROP engine. */
  151879. +gceSTATUS
  151880. +gcoSURF_EnableAlphaBlend(
  151881. + IN gcoSURF Surface,
  151882. + IN gctUINT8 SrcGlobalAlphaValue,
  151883. + IN gctUINT8 DstGlobalAlphaValue,
  151884. + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
  151885. + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
  151886. + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
  151887. + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
  151888. + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
  151889. + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
  151890. + IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
  151891. + IN gceSURF_PIXEL_COLOR_MODE DstColorMode
  151892. + );
  151893. +
  151894. +/* Disable alpha blending engine in the hardware and engage the ROP engine. */
  151895. +gceSTATUS
  151896. +gcoSURF_DisableAlphaBlend(
  151897. + IN gcoSURF Surface
  151898. + );
  151899. +
  151900. +/* Copy a rectangular area with format conversion. */
  151901. +gceSTATUS
  151902. +gcoSURF_CopyPixels(
  151903. + IN gcoSURF Source,
  151904. + IN gcoSURF Target,
  151905. + IN gctINT SourceX,
  151906. + IN gctINT SourceY,
  151907. + IN gctINT TargetX,
  151908. + IN gctINT TargetY,
  151909. + IN gctINT Width,
  151910. + IN gctINT Height
  151911. + );
  151912. +
  151913. +/* Read surface pixel. */
  151914. +gceSTATUS
  151915. +gcoSURF_ReadPixel(
  151916. + IN gcoSURF Surface,
  151917. + IN gctPOINTER Memory,
  151918. + IN gctINT X,
  151919. + IN gctINT Y,
  151920. + IN gceSURF_FORMAT Format,
  151921. + OUT gctPOINTER PixelValue
  151922. + );
  151923. +
  151924. +/* Write surface pixel. */
  151925. +gceSTATUS
  151926. +gcoSURF_WritePixel(
  151927. + IN gcoSURF Surface,
  151928. + IN gctPOINTER Memory,
  151929. + IN gctINT X,
  151930. + IN gctINT Y,
  151931. + IN gceSURF_FORMAT Format,
  151932. + IN gctPOINTER PixelValue
  151933. + );
  151934. +
  151935. +gceSTATUS
  151936. +gcoSURF_SetDither(
  151937. + IN gcoSURF Surface,
  151938. + IN gctBOOL Dither
  151939. + );
  151940. +/******************************************************************************\
  151941. +********************************** gco2D Object *********************************
  151942. +\******************************************************************************/
  151943. +
  151944. +/* Construct a new gco2D object. */
  151945. +gceSTATUS
  151946. +gco2D_Construct(
  151947. + IN gcoHAL Hal,
  151948. + OUT gco2D * Hardware
  151949. + );
  151950. +
  151951. +/* Destroy an gco2D object. */
  151952. +gceSTATUS
  151953. +gco2D_Destroy(
  151954. + IN gco2D Hardware
  151955. + );
  151956. +
  151957. +/* Sets the maximum number of brushes in the brush cache. */
  151958. +gceSTATUS
  151959. +gco2D_SetBrushLimit(
  151960. + IN gco2D Hardware,
  151961. + IN gctUINT MaxCount
  151962. + );
  151963. +
  151964. +/* Flush the brush. */
  151965. +gceSTATUS
  151966. +gco2D_FlushBrush(
  151967. + IN gco2D Engine,
  151968. + IN gcoBRUSH Brush,
  151969. + IN gceSURF_FORMAT Format
  151970. + );
  151971. +
  151972. +/* Program the specified solid color brush. */
  151973. +gceSTATUS
  151974. +gco2D_LoadSolidBrush(
  151975. + IN gco2D Engine,
  151976. + IN gceSURF_FORMAT Format,
  151977. + IN gctUINT32 ColorConvert,
  151978. + IN gctUINT32 Color,
  151979. + IN gctUINT64 Mask
  151980. + );
  151981. +
  151982. +gceSTATUS
  151983. +gco2D_LoadMonochromeBrush(
  151984. + IN gco2D Engine,
  151985. + IN gctUINT32 OriginX,
  151986. + IN gctUINT32 OriginY,
  151987. + IN gctUINT32 ColorConvert,
  151988. + IN gctUINT32 FgColor,
  151989. + IN gctUINT32 BgColor,
  151990. + IN gctUINT64 Bits,
  151991. + IN gctUINT64 Mask
  151992. + );
  151993. +
  151994. +gceSTATUS
  151995. +gco2D_LoadColorBrush(
  151996. + IN gco2D Engine,
  151997. + IN gctUINT32 OriginX,
  151998. + IN gctUINT32 OriginY,
  151999. + IN gctUINT32 Address,
  152000. + IN gceSURF_FORMAT Format,
  152001. + IN gctUINT64 Mask
  152002. + );
  152003. +
  152004. +/* Configure monochrome source. */
  152005. +gceSTATUS
  152006. +gco2D_SetMonochromeSource(
  152007. + IN gco2D Engine,
  152008. + IN gctBOOL ColorConvert,
  152009. + IN gctUINT8 MonoTransparency,
  152010. + IN gceSURF_MONOPACK DataPack,
  152011. + IN gctBOOL CoordRelative,
  152012. + IN gceSURF_TRANSPARENCY Transparency,
  152013. + IN gctUINT32 FgColor,
  152014. + IN gctUINT32 BgColor
  152015. + );
  152016. +
  152017. +/* Configure color source. */
  152018. +gceSTATUS
  152019. +gco2D_SetColorSource(
  152020. + IN gco2D Engine,
  152021. + IN gctUINT32 Address,
  152022. + IN gctUINT32 Stride,
  152023. + IN gceSURF_FORMAT Format,
  152024. + IN gceSURF_ROTATION Rotation,
  152025. + IN gctUINT32 SurfaceWidth,
  152026. + IN gctBOOL CoordRelative,
  152027. + IN gceSURF_TRANSPARENCY Transparency,
  152028. + IN gctUINT32 TransparencyColor
  152029. + );
  152030. +
  152031. +/* Configure color source extension for full rotation. */
  152032. +gceSTATUS
  152033. +gco2D_SetColorSourceEx(
  152034. + IN gco2D Engine,
  152035. + IN gctUINT32 Address,
  152036. + IN gctUINT32 Stride,
  152037. + IN gceSURF_FORMAT Format,
  152038. + IN gceSURF_ROTATION Rotation,
  152039. + IN gctUINT32 SurfaceWidth,
  152040. + IN gctUINT32 SurfaceHeight,
  152041. + IN gctBOOL CoordRelative,
  152042. + IN gceSURF_TRANSPARENCY Transparency,
  152043. + IN gctUINT32 TransparencyColor
  152044. + );
  152045. +
  152046. +/* Configure color source. */
  152047. +gceSTATUS
  152048. +gco2D_SetColorSourceAdvanced(
  152049. + IN gco2D Engine,
  152050. + IN gctUINT32 Address,
  152051. + IN gctUINT32 Stride,
  152052. + IN gceSURF_FORMAT Format,
  152053. + IN gceSURF_ROTATION Rotation,
  152054. + IN gctUINT32 SurfaceWidth,
  152055. + IN gctUINT32 SurfaceHeight,
  152056. + IN gctBOOL CoordRelative
  152057. + );
  152058. +
  152059. +gceSTATUS
  152060. +gco2D_SetColorSourceN(
  152061. + IN gco2D Engine,
  152062. + IN gctUINT32 Address,
  152063. + IN gctUINT32 Stride,
  152064. + IN gceSURF_FORMAT Format,
  152065. + IN gceSURF_ROTATION Rotation,
  152066. + IN gctUINT32 SurfaceWidth,
  152067. + IN gctUINT32 SurfaceHeight,
  152068. + IN gctUINT32 SurfaceNumber
  152069. + );
  152070. +
  152071. +/* Configure masked color source. */
  152072. +gceSTATUS
  152073. +gco2D_SetMaskedSource(
  152074. + IN gco2D Engine,
  152075. + IN gctUINT32 Address,
  152076. + IN gctUINT32 Stride,
  152077. + IN gceSURF_FORMAT Format,
  152078. + IN gctBOOL CoordRelative,
  152079. + IN gceSURF_MONOPACK MaskPack
  152080. + );
  152081. +
  152082. +/* Configure masked color source extension for full rotation. */
  152083. +gceSTATUS
  152084. +gco2D_SetMaskedSourceEx(
  152085. + IN gco2D Engine,
  152086. + IN gctUINT32 Address,
  152087. + IN gctUINT32 Stride,
  152088. + IN gceSURF_FORMAT Format,
  152089. + IN gctBOOL CoordRelative,
  152090. + IN gceSURF_MONOPACK MaskPack,
  152091. + IN gceSURF_ROTATION Rotation,
  152092. + IN gctUINT32 SurfaceWidth,
  152093. + IN gctUINT32 SurfaceHeight
  152094. + );
  152095. +
  152096. +/* Setup the source rectangle. */
  152097. +gceSTATUS
  152098. +gco2D_SetSource(
  152099. + IN gco2D Engine,
  152100. + IN gcsRECT_PTR SrcRect
  152101. + );
  152102. +
  152103. +/* Set clipping rectangle. */
  152104. +gceSTATUS
  152105. +gco2D_SetClipping(
  152106. + IN gco2D Engine,
  152107. + IN gcsRECT_PTR Rect
  152108. + );
  152109. +
  152110. +/* Configure destination. */
  152111. +gceSTATUS
  152112. +gco2D_SetTarget(
  152113. + IN gco2D Engine,
  152114. + IN gctUINT32 Address,
  152115. + IN gctUINT32 Stride,
  152116. + IN gceSURF_ROTATION Rotation,
  152117. + IN gctUINT32 SurfaceWidth
  152118. + );
  152119. +
  152120. +/* Configure destination extension for full rotation. */
  152121. +gceSTATUS
  152122. +gco2D_SetTargetEx(
  152123. + IN gco2D Engine,
  152124. + IN gctUINT32 Address,
  152125. + IN gctUINT32 Stride,
  152126. + IN gceSURF_ROTATION Rotation,
  152127. + IN gctUINT32 SurfaceWidth,
  152128. + IN gctUINT32 SurfaceHeight
  152129. + );
  152130. +
  152131. +/* Calculate and program the stretch factors. */
  152132. +gceSTATUS
  152133. +gco2D_CalcStretchFactor(
  152134. + IN gco2D Engine,
  152135. + IN gctINT32 SrcSize,
  152136. + IN gctINT32 DestSize,
  152137. + OUT gctUINT32_PTR Factor
  152138. + );
  152139. +
  152140. +gceSTATUS
  152141. +gco2D_SetStretchFactors(
  152142. + IN gco2D Engine,
  152143. + IN gctUINT32 HorFactor,
  152144. + IN gctUINT32 VerFactor
  152145. + );
  152146. +
  152147. +/* Calculate and program the stretch factors based on the rectangles. */
  152148. +gceSTATUS
  152149. +gco2D_SetStretchRectFactors(
  152150. + IN gco2D Engine,
  152151. + IN gcsRECT_PTR SrcRect,
  152152. + IN gcsRECT_PTR DestRect
  152153. + );
  152154. +
  152155. +/* Create a new solid color gcoBRUSH object. */
  152156. +gceSTATUS
  152157. +gco2D_ConstructSingleColorBrush(
  152158. + IN gco2D Engine,
  152159. + IN gctUINT32 ColorConvert,
  152160. + IN gctUINT32 Color,
  152161. + IN gctUINT64 Mask,
  152162. + gcoBRUSH * Brush
  152163. + );
  152164. +
  152165. +/* Create a new monochrome gcoBRUSH object. */
  152166. +gceSTATUS
  152167. +gco2D_ConstructMonochromeBrush(
  152168. + IN gco2D Engine,
  152169. + IN gctUINT32 OriginX,
  152170. + IN gctUINT32 OriginY,
  152171. + IN gctUINT32 ColorConvert,
  152172. + IN gctUINT32 FgColor,
  152173. + IN gctUINT32 BgColor,
  152174. + IN gctUINT64 Bits,
  152175. + IN gctUINT64 Mask,
  152176. + gcoBRUSH * Brush
  152177. + );
  152178. +
  152179. +/* Create a color gcoBRUSH object. */
  152180. +gceSTATUS
  152181. +gco2D_ConstructColorBrush(
  152182. + IN gco2D Engine,
  152183. + IN gctUINT32 OriginX,
  152184. + IN gctUINT32 OriginY,
  152185. + IN gctPOINTER Address,
  152186. + IN gceSURF_FORMAT Format,
  152187. + IN gctUINT64 Mask,
  152188. + gcoBRUSH * Brush
  152189. + );
  152190. +
  152191. +/* Clear one or more rectangular areas. */
  152192. +gceSTATUS
  152193. +gco2D_Clear(
  152194. + IN gco2D Engine,
  152195. + IN gctUINT32 RectCount,
  152196. + IN gcsRECT_PTR Rect,
  152197. + IN gctUINT32 Color32,
  152198. + IN gctUINT8 FgRop,
  152199. + IN gctUINT8 BgRop,
  152200. + IN gceSURF_FORMAT DestFormat
  152201. + );
  152202. +
  152203. +/* Draw one or more Bresenham lines. */
  152204. +gceSTATUS
  152205. +gco2D_Line(
  152206. + IN gco2D Engine,
  152207. + IN gctUINT32 LineCount,
  152208. + IN gcsRECT_PTR Position,
  152209. + IN gcoBRUSH Brush,
  152210. + IN gctUINT8 FgRop,
  152211. + IN gctUINT8 BgRop,
  152212. + IN gceSURF_FORMAT DestFormat
  152213. + );
  152214. +
  152215. +/* Draw one or more Bresenham lines based on the 32-bit color. */
  152216. +gceSTATUS
  152217. +gco2D_ColorLine(
  152218. + IN gco2D Engine,
  152219. + IN gctUINT32 LineCount,
  152220. + IN gcsRECT_PTR Position,
  152221. + IN gctUINT32 Color32,
  152222. + IN gctUINT8 FgRop,
  152223. + IN gctUINT8 BgRop,
  152224. + IN gceSURF_FORMAT DestFormat
  152225. + );
  152226. +
  152227. +/* Generic blit. */
  152228. +gceSTATUS
  152229. +gco2D_Blit(
  152230. + IN gco2D Engine,
  152231. + IN gctUINT32 RectCount,
  152232. + IN gcsRECT_PTR Rect,
  152233. + IN gctUINT8 FgRop,
  152234. + IN gctUINT8 BgRop,
  152235. + IN gceSURF_FORMAT DestFormat
  152236. + );
  152237. +
  152238. +gceSTATUS
  152239. +gco2D_Blend(
  152240. + IN gco2D Engine,
  152241. + IN gctUINT32 SrcCount,
  152242. + IN gctUINT32 RectCount,
  152243. + IN gcsRECT_PTR Rect,
  152244. + IN gctUINT8 FgRop,
  152245. + IN gctUINT8 BgRop,
  152246. + IN gceSURF_FORMAT DestFormat
  152247. + );
  152248. +
  152249. +/* Batch blit. */
  152250. +gceSTATUS
  152251. +gco2D_BatchBlit(
  152252. + IN gco2D Engine,
  152253. + IN gctUINT32 RectCount,
  152254. + IN gcsRECT_PTR SrcRect,
  152255. + IN gcsRECT_PTR DestRect,
  152256. + IN gctUINT8 FgRop,
  152257. + IN gctUINT8 BgRop,
  152258. + IN gceSURF_FORMAT DestFormat
  152259. + );
  152260. +
  152261. +/* Stretch blit. */
  152262. +gceSTATUS
  152263. +gco2D_StretchBlit(
  152264. + IN gco2D Engine,
  152265. + IN gctUINT32 RectCount,
  152266. + IN gcsRECT_PTR Rect,
  152267. + IN gctUINT8 FgRop,
  152268. + IN gctUINT8 BgRop,
  152269. + IN gceSURF_FORMAT DestFormat
  152270. + );
  152271. +
  152272. +/* Monochrome blit. */
  152273. +gceSTATUS
  152274. +gco2D_MonoBlit(
  152275. + IN gco2D Engine,
  152276. + IN gctPOINTER StreamBits,
  152277. + IN gcsPOINT_PTR StreamSize,
  152278. + IN gcsRECT_PTR StreamRect,
  152279. + IN gceSURF_MONOPACK SrcStreamPack,
  152280. + IN gceSURF_MONOPACK DestStreamPack,
  152281. + IN gcsRECT_PTR DestRect,
  152282. + IN gctUINT32 FgRop,
  152283. + IN gctUINT32 BgRop,
  152284. + IN gceSURF_FORMAT DestFormat
  152285. + );
  152286. +
  152287. +gceSTATUS
  152288. +gco2D_MonoBlitEx(
  152289. + IN gco2D Engine,
  152290. + IN gctPOINTER StreamBits,
  152291. + IN gctINT32 StreamStride,
  152292. + IN gctINT32 StreamWidth,
  152293. + IN gctINT32 StreamHeight,
  152294. + IN gctINT32 StreamX,
  152295. + IN gctINT32 StreamY,
  152296. + IN gctUINT32 FgColor,
  152297. + IN gctUINT32 BgColor,
  152298. + IN gcsRECT_PTR SrcRect,
  152299. + IN gcsRECT_PTR DstRect,
  152300. + IN gctUINT8 FgRop,
  152301. + IN gctUINT8 BgRop
  152302. + );
  152303. +
  152304. +/* Set kernel size. */
  152305. +gceSTATUS
  152306. +gco2D_SetKernelSize(
  152307. + IN gco2D Engine,
  152308. + IN gctUINT8 HorKernelSize,
  152309. + IN gctUINT8 VerKernelSize
  152310. + );
  152311. +
  152312. +/* Set filter type. */
  152313. +gceSTATUS
  152314. +gco2D_SetFilterType(
  152315. + IN gco2D Engine,
  152316. + IN gceFILTER_TYPE FilterType
  152317. + );
  152318. +
  152319. +/* Set the filter kernel by user. */
  152320. +gceSTATUS
  152321. +gco2D_SetUserFilterKernel(
  152322. + IN gco2D Engine,
  152323. + IN gceFILTER_PASS_TYPE PassType,
  152324. + IN gctUINT16_PTR KernelArray
  152325. + );
  152326. +
  152327. +/* Select the pass(es) to be done for user defined filter. */
  152328. +gceSTATUS
  152329. +gco2D_EnableUserFilterPasses(
  152330. + IN gco2D Engine,
  152331. + IN gctBOOL HorPass,
  152332. + IN gctBOOL VerPass
  152333. + );
  152334. +
  152335. +/* Frees the temporary buffer allocated by filter blit operation. */
  152336. +gceSTATUS
  152337. +gco2D_FreeFilterBuffer(
  152338. + IN gco2D Engine
  152339. + );
  152340. +
  152341. +/* Filter blit. */
  152342. +gceSTATUS
  152343. +gco2D_FilterBlit(
  152344. + IN gco2D Engine,
  152345. + IN gctUINT32 SrcAddress,
  152346. + IN gctUINT SrcStride,
  152347. + IN gctUINT32 SrcUAddress,
  152348. + IN gctUINT SrcUStride,
  152349. + IN gctUINT32 SrcVAddress,
  152350. + IN gctUINT SrcVStride,
  152351. + IN gceSURF_FORMAT SrcFormat,
  152352. + IN gceSURF_ROTATION SrcRotation,
  152353. + IN gctUINT32 SrcSurfaceWidth,
  152354. + IN gcsRECT_PTR SrcRect,
  152355. + IN gctUINT32 DestAddress,
  152356. + IN gctUINT DestStride,
  152357. + IN gceSURF_FORMAT DestFormat,
  152358. + IN gceSURF_ROTATION DestRotation,
  152359. + IN gctUINT32 DestSurfaceWidth,
  152360. + IN gcsRECT_PTR DestRect,
  152361. + IN gcsRECT_PTR DestSubRect
  152362. + );
  152363. +
  152364. +/* Filter blit extension for full rotation. */
  152365. +gceSTATUS
  152366. +gco2D_FilterBlitEx(
  152367. + IN gco2D Engine,
  152368. + IN gctUINT32 SrcAddress,
  152369. + IN gctUINT SrcStride,
  152370. + IN gctUINT32 SrcUAddress,
  152371. + IN gctUINT SrcUStride,
  152372. + IN gctUINT32 SrcVAddress,
  152373. + IN gctUINT SrcVStride,
  152374. + IN gceSURF_FORMAT SrcFormat,
  152375. + IN gceSURF_ROTATION SrcRotation,
  152376. + IN gctUINT32 SrcSurfaceWidth,
  152377. + IN gctUINT32 SrcSurfaceHeight,
  152378. + IN gcsRECT_PTR SrcRect,
  152379. + IN gctUINT32 DestAddress,
  152380. + IN gctUINT DestStride,
  152381. + IN gceSURF_FORMAT DestFormat,
  152382. + IN gceSURF_ROTATION DestRotation,
  152383. + IN gctUINT32 DestSurfaceWidth,
  152384. + IN gctUINT32 DestSurfaceHeight,
  152385. + IN gcsRECT_PTR DestRect,
  152386. + IN gcsRECT_PTR DestSubRect
  152387. + );
  152388. +
  152389. +gceSTATUS
  152390. +gco2D_FilterBlitEx2(
  152391. + IN gco2D Engine,
  152392. + IN gctUINT32_PTR SrcAddresses,
  152393. + IN gctUINT32 SrcAddressNum,
  152394. + IN gctUINT32_PTR SrcStrides,
  152395. + IN gctUINT32 SrcStrideNum,
  152396. + IN gceTILING SrcTiling,
  152397. + IN gceSURF_FORMAT SrcFormat,
  152398. + IN gceSURF_ROTATION SrcRotation,
  152399. + IN gctUINT32 SrcSurfaceWidth,
  152400. + IN gctUINT32 SrcSurfaceHeight,
  152401. + IN gcsRECT_PTR SrcRect,
  152402. + IN gctUINT32_PTR DestAddresses,
  152403. + IN gctUINT32 DestAddressNum,
  152404. + IN gctUINT32_PTR DestStrides,
  152405. + IN gctUINT32 DestStrideNum,
  152406. + IN gceTILING DestTiling,
  152407. + IN gceSURF_FORMAT DestFormat,
  152408. + IN gceSURF_ROTATION DestRotation,
  152409. + IN gctUINT32 DestSurfaceWidth,
  152410. + IN gctUINT32 DestSurfaceHeight,
  152411. + IN gcsRECT_PTR DestRect,
  152412. + IN gcsRECT_PTR DestSubRect
  152413. + );
  152414. +
  152415. +/* Enable alpha blending engine in the hardware and disengage the ROP engine. */
  152416. +gceSTATUS
  152417. +gco2D_EnableAlphaBlend(
  152418. + IN gco2D Engine,
  152419. + IN gctUINT8 SrcGlobalAlphaValue,
  152420. + IN gctUINT8 DstGlobalAlphaValue,
  152421. + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
  152422. + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
  152423. + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
  152424. + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
  152425. + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
  152426. + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
  152427. + IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
  152428. + IN gceSURF_PIXEL_COLOR_MODE DstColorMode
  152429. + );
  152430. +
  152431. +/* Enable alpha blending engine in the hardware. */
  152432. +gceSTATUS
  152433. +gco2D_EnableAlphaBlendAdvanced(
  152434. + IN gco2D Engine,
  152435. + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
  152436. + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
  152437. + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
  152438. + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
  152439. + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
  152440. + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode
  152441. + );
  152442. +
  152443. +/* Enable alpha blending engine with Porter Duff rule. */
  152444. +gceSTATUS
  152445. +gco2D_SetPorterDuffBlending(
  152446. + IN gco2D Engine,
  152447. + IN gce2D_PORTER_DUFF_RULE Rule
  152448. + );
  152449. +
  152450. +/* Disable alpha blending engine in the hardware and engage the ROP engine. */
  152451. +gceSTATUS
  152452. +gco2D_DisableAlphaBlend(
  152453. + IN gco2D Engine
  152454. + );
  152455. +
  152456. +/* Retrieve the maximum number of 32-bit data chunks for a single DE command. */
  152457. +gctUINT32
  152458. +gco2D_GetMaximumDataCount(
  152459. + void
  152460. + );
  152461. +
  152462. +/* Retrieve the maximum number of rectangles, that can be passed in a single DE command. */
  152463. +gctUINT32
  152464. +gco2D_GetMaximumRectCount(
  152465. + void
  152466. + );
  152467. +
  152468. +/* Returns the pixel alignment of the surface. */
  152469. +gceSTATUS
  152470. +gco2D_GetPixelAlignment(
  152471. + gceSURF_FORMAT Format,
  152472. + gcsPOINT_PTR Alignment
  152473. + );
  152474. +
  152475. +/* Retrieve monochrome stream pack size. */
  152476. +gceSTATUS
  152477. +gco2D_GetPackSize(
  152478. + IN gceSURF_MONOPACK StreamPack,
  152479. + OUT gctUINT32 * PackWidth,
  152480. + OUT gctUINT32 * PackHeight
  152481. + );
  152482. +
  152483. +/* Flush the 2D pipeline. */
  152484. +gceSTATUS
  152485. +gco2D_Flush(
  152486. + IN gco2D Engine
  152487. + );
  152488. +
  152489. +/* Load 256-entry color table for INDEX8 source surfaces. */
  152490. +gceSTATUS
  152491. +gco2D_LoadPalette(
  152492. + IN gco2D Engine,
  152493. + IN gctUINT FirstIndex,
  152494. + IN gctUINT IndexCount,
  152495. + IN gctPOINTER ColorTable,
  152496. + IN gctBOOL ColorConvert
  152497. + );
  152498. +
  152499. +/* Enable/disable 2D BitBlt mirrorring. */
  152500. +gceSTATUS
  152501. +gco2D_SetBitBlitMirror(
  152502. + IN gco2D Engine,
  152503. + IN gctBOOL HorizontalMirror,
  152504. + IN gctBOOL VerticalMirror
  152505. + );
  152506. +
  152507. +/*
  152508. + * Set the transparency for source, destination and pattern.
  152509. + * It also enable or disable the DFB color key mode.
  152510. + */
  152511. +gceSTATUS
  152512. +gco2D_SetTransparencyAdvancedEx(
  152513. + IN gco2D Engine,
  152514. + IN gce2D_TRANSPARENCY SrcTransparency,
  152515. + IN gce2D_TRANSPARENCY DstTransparency,
  152516. + IN gce2D_TRANSPARENCY PatTransparency,
  152517. + IN gctBOOL EnableDFBColorKeyMode
  152518. + );
  152519. +
  152520. +/* Set the transparency for source, destination and pattern. */
  152521. +gceSTATUS
  152522. +gco2D_SetTransparencyAdvanced(
  152523. + IN gco2D Engine,
  152524. + IN gce2D_TRANSPARENCY SrcTransparency,
  152525. + IN gce2D_TRANSPARENCY DstTransparency,
  152526. + IN gce2D_TRANSPARENCY PatTransparency
  152527. + );
  152528. +
  152529. +/* Set the source color key. */
  152530. +gceSTATUS
  152531. +gco2D_SetSourceColorKeyAdvanced(
  152532. + IN gco2D Engine,
  152533. + IN gctUINT32 ColorKey
  152534. + );
  152535. +
  152536. +/* Set the source color key range. */
  152537. +gceSTATUS
  152538. +gco2D_SetSourceColorKeyRangeAdvanced(
  152539. + IN gco2D Engine,
  152540. + IN gctUINT32 ColorKeyLow,
  152541. + IN gctUINT32 ColorKeyHigh
  152542. + );
  152543. +
  152544. +/* Set the target color key. */
  152545. +gceSTATUS
  152546. +gco2D_SetTargetColorKeyAdvanced(
  152547. + IN gco2D Engine,
  152548. + IN gctUINT32 ColorKey
  152549. + );
  152550. +
  152551. +/* Set the target color key range. */
  152552. +gceSTATUS
  152553. +gco2D_SetTargetColorKeyRangeAdvanced(
  152554. + IN gco2D Engine,
  152555. + IN gctUINT32 ColorKeyLow,
  152556. + IN gctUINT32 ColorKeyHigh
  152557. + );
  152558. +
  152559. +/* Set the YUV color space mode. */
  152560. +gceSTATUS
  152561. +gco2D_SetYUVColorMode(
  152562. + IN gco2D Engine,
  152563. + IN gce2D_YUV_COLOR_MODE Mode
  152564. + );
  152565. +
  152566. +/* Setup the source global color value in ARGB8 format. */
  152567. +gceSTATUS gco2D_SetSourceGlobalColorAdvanced(
  152568. + IN gco2D Engine,
  152569. + IN gctUINT32 Color32
  152570. + );
  152571. +
  152572. +/* Setup the target global color value in ARGB8 format. */
  152573. +gceSTATUS gco2D_SetTargetGlobalColorAdvanced(
  152574. + IN gco2D Engine,
  152575. + IN gctUINT32 Color32
  152576. + );
  152577. +
  152578. +/* Setup the source and target pixel multiply modes. */
  152579. +gceSTATUS
  152580. +gco2D_SetPixelMultiplyModeAdvanced(
  152581. + IN gco2D Engine,
  152582. + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE SrcPremultiplySrcAlpha,
  152583. + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstPremultiplyDstAlpha,
  152584. + IN gce2D_GLOBAL_COLOR_MULTIPLY_MODE SrcPremultiplyGlobalMode,
  152585. + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstDemultiplyDstAlpha
  152586. + );
  152587. +
  152588. +/* Set the GPU clock cycles after which the idle engine will keep auto-flushing. */
  152589. +gceSTATUS
  152590. +gco2D_SetAutoFlushCycles(
  152591. + IN gco2D Engine,
  152592. + IN gctUINT32 Cycles
  152593. + );
  152594. +
  152595. +#if VIVANTE_PROFILER
  152596. +/* Read the profile registers available in the 2D engine and sets them in the profile.
  152597. + The function will also reset the pixelsRendered counter every time.
  152598. +*/
  152599. +gceSTATUS
  152600. +gco2D_ProfileEngine(
  152601. + IN gco2D Engine,
  152602. + OPTIONAL gcs2D_PROFILE_PTR Profile
  152603. + );
  152604. +#endif
  152605. +
  152606. +/* Enable or disable 2D dithering. */
  152607. +gceSTATUS
  152608. +gco2D_EnableDither(
  152609. + IN gco2D Engine,
  152610. + IN gctBOOL Enable
  152611. + );
  152612. +
  152613. +gceSTATUS
  152614. +gco2D_SetGenericSource(
  152615. + IN gco2D Engine,
  152616. + IN gctUINT32_PTR Addresses,
  152617. + IN gctUINT32 AddressNum,
  152618. + IN gctUINT32_PTR Strides,
  152619. + IN gctUINT32 StrideNum,
  152620. + IN gceTILING Tiling,
  152621. + IN gceSURF_FORMAT Format,
  152622. + IN gceSURF_ROTATION Rotation,
  152623. + IN gctUINT32 SurfaceWidth,
  152624. + IN gctUINT32 SurfaceHeight
  152625. +);
  152626. +
  152627. +gceSTATUS
  152628. +gco2D_SetGenericTarget(
  152629. + IN gco2D Engine,
  152630. + IN gctUINT32_PTR Addresses,
  152631. + IN gctUINT32 AddressNum,
  152632. + IN gctUINT32_PTR Strides,
  152633. + IN gctUINT32 StrideNum,
  152634. + IN gceTILING Tiling,
  152635. + IN gceSURF_FORMAT Format,
  152636. + IN gceSURF_ROTATION Rotation,
  152637. + IN gctUINT32 SurfaceWidth,
  152638. + IN gctUINT32 SurfaceHeight
  152639. +);
  152640. +
  152641. +gceSTATUS
  152642. +gco2D_SetCurrentSourceIndex(
  152643. + IN gco2D Engine,
  152644. + IN gctUINT32 SrcIndex
  152645. + );
  152646. +
  152647. +gceSTATUS
  152648. +gco2D_MultiSourceBlit(
  152649. + IN gco2D Engine,
  152650. + IN gctUINT32 SourceMask,
  152651. + IN gcsRECT_PTR DestRect,
  152652. + IN gctUINT32 RectCount
  152653. + );
  152654. +
  152655. +gceSTATUS
  152656. +gco2D_SetROP(
  152657. + IN gco2D Engine,
  152658. + IN gctUINT8 FgRop,
  152659. + IN gctUINT8 BgRop
  152660. + );
  152661. +
  152662. +gceSTATUS
  152663. +gco2D_SetGdiStretchMode(
  152664. + IN gco2D Engine,
  152665. + IN gctBOOL Enable
  152666. + );
  152667. +
  152668. +gceSTATUS
  152669. +gco2D_SetSourceTileStatus(
  152670. + IN gco2D Engine,
  152671. + IN gce2D_TILE_STATUS_CONFIG TSControl,
  152672. + IN gceSURF_FORMAT CompressedFormat,
  152673. + IN gctUINT32 ClearValue,
  152674. + IN gctUINT32 GpuAddress
  152675. + );
  152676. +
  152677. +gceSTATUS
  152678. +gco2D_SetTargetTileStatus(
  152679. + IN gco2D Engine,
  152680. + IN gce2D_TILE_STATUS_CONFIG TileStatusConfig,
  152681. + IN gceSURF_FORMAT CompressedFormat,
  152682. + IN gctUINT32 ClearValue,
  152683. + IN gctUINT32 GpuAddress
  152684. + );
  152685. +
  152686. +gceSTATUS
  152687. +gco2D_QueryU32(
  152688. + IN gco2D Engine,
  152689. + IN gce2D_QUERY Item,
  152690. + OUT gctUINT32_PTR Value
  152691. + );
  152692. +
  152693. +gceSTATUS
  152694. +gco2D_SetStateU32(
  152695. + IN gco2D Engine,
  152696. + IN gce2D_STATE State,
  152697. + IN gctUINT32 Value
  152698. + );
  152699. +
  152700. +gceSTATUS
  152701. +gco2D_SetStateArrayI32(
  152702. + IN gco2D Engine,
  152703. + IN gce2D_STATE State,
  152704. + IN gctINT32_PTR Array,
  152705. + IN gctINT32 ArraySize
  152706. + );
  152707. +
  152708. +gceSTATUS
  152709. +gco2D_SetStateArrayU32(
  152710. + IN gco2D Engine,
  152711. + IN gce2D_STATE State,
  152712. + IN gctUINT32_PTR Array,
  152713. + IN gctINT32 ArraySize
  152714. + );
  152715. +
  152716. +gceSTATUS
  152717. +gco2D_SetTargetRect(
  152718. + IN gco2D Engine,
  152719. + IN gcsRECT_PTR Rect
  152720. + );
  152721. +
  152722. +#ifdef __cplusplus
  152723. +}
  152724. +#endif
  152725. +
  152726. +#endif /* __gc_hal_raster_h_ */
  152727. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h
  152728. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h 1970-01-01 01:00:00.000000000 +0100
  152729. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h 2014-08-20 19:23:53.570845890 +0200
  152730. @@ -0,0 +1,248 @@
  152731. +/****************************************************************************
  152732. +*
  152733. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  152734. +*
  152735. +* This program is free software; you can redistribute it and/or modify
  152736. +* it under the terms of the GNU General Public License as published by
  152737. +* the Free Software Foundation; either version 2 of the license, or
  152738. +* (at your option) any later version.
  152739. +*
  152740. +* This program is distributed in the hope that it will be useful,
  152741. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  152742. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  152743. +* GNU General Public License for more details.
  152744. +*
  152745. +* You should have received a copy of the GNU General Public License
  152746. +* along with this program; if not write to the Free Software
  152747. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  152748. +*
  152749. +*****************************************************************************/
  152750. +
  152751. +
  152752. +#ifndef __gc_hal_rename_h_
  152753. +#define __gc_hal_rename_h_
  152754. +
  152755. +
  152756. +#if defined(_HAL2D_APPENDIX)
  152757. +
  152758. +#define _HAL2D_RENAME_2(api, appendix) api ## appendix
  152759. +#define _HAL2D_RENAME_1(api, appendix) _HAL2D_RENAME_2(api, appendix)
  152760. +#define gcmHAL2D(api) _HAL2D_RENAME_1(api, _HAL2D_APPENDIX)
  152761. +
  152762. +
  152763. +#define gckOS_Construct gcmHAL2D(gckOS_Construct)
  152764. +#define gckOS_Destroy gcmHAL2D(gckOS_Destroy)
  152765. +#define gckOS_QueryVideoMemory gcmHAL2D(gckOS_QueryVideoMemory)
  152766. +#define gckOS_Allocate gcmHAL2D(gckOS_Allocate)
  152767. +#define gckOS_Free gcmHAL2D(gckOS_Free)
  152768. +#define gckOS_AllocateMemory gcmHAL2D(gckOS_AllocateMemory)
  152769. +#define gckOS_FreeMemory gcmHAL2D(gckOS_FreeMemory)
  152770. +#define gckOS_AllocatePagedMemory gcmHAL2D(gckOS_AllocatePagedMemory)
  152771. +#define gckOS_AllocatePagedMemoryEx gcmHAL2D(gckOS_AllocatePagedMemoryEx)
  152772. +#define gckOS_LockPages gcmHAL2D(gckOS_LockPages)
  152773. +#define gckOS_MapPages gcmHAL2D(gckOS_MapPages)
  152774. +#define gckOS_UnlockPages gcmHAL2D(gckOS_UnlockPages)
  152775. +#define gckOS_FreePagedMemory gcmHAL2D(gckOS_FreePagedMemory)
  152776. +#define gckOS_AllocateNonPagedMemory gcmHAL2D(gckOS_AllocateNonPagedMemory)
  152777. +#define gckOS_FreeNonPagedMemory gcmHAL2D(gckOS_FreeNonPagedMemory)
  152778. +#define gckOS_AllocateContiguous gcmHAL2D(gckOS_AllocateContiguous)
  152779. +#define gckOS_FreeContiguous gcmHAL2D(gckOS_FreeContiguous)
  152780. +#define gckOS_GetPageSize gcmHAL2D(gckOS_GetPageSize)
  152781. +#define gckOS_GetPhysicalAddress gcmHAL2D(gckOS_GetPhysicalAddress)
  152782. +#define gckOS_GetPhysicalAddressProcess gcmHAL2D(gckOS_GetPhysicalAddressProcess)
  152783. +#define gckOS_MapPhysical gcmHAL2D(gckOS_MapPhysical)
  152784. +#define gckOS_UnmapPhysical gcmHAL2D(gckOS_UnmapPhysical)
  152785. +#define gckOS_ReadRegister gcmHAL2D(gckOS_ReadRegister)
  152786. +#define gckOS_WriteRegister gcmHAL2D(gckOS_WriteRegister)
  152787. +#define gckOS_WriteMemory gcmHAL2D(gckOS_WriteMemory)
  152788. +#define gckOS_MapMemory gcmHAL2D(gckOS_MapMemory)
  152789. +#define gckOS_UnmapMemory gcmHAL2D(gckOS_UnmapMemory)
  152790. +#define gckOS_UnmapMemoryEx gcmHAL2D(gckOS_UnmapMemoryEx)
  152791. +#define gckOS_CreateMutex gcmHAL2D(gckOS_CreateMutex)
  152792. +#define gckOS_DeleteMutex gcmHAL2D(gckOS_DeleteMutex)
  152793. +#define gckOS_AcquireMutex gcmHAL2D(gckOS_AcquireMutex)
  152794. +#define gckOS_ReleaseMutex gcmHAL2D(gckOS_ReleaseMutex)
  152795. +#define gckOS_AtomicExchange gcmHAL2D(gckOS_AtomicExchange)
  152796. +#define gckOS_AtomicExchangePtr gcmHAL2D(gckOS_AtomicExchangePtr)
  152797. +#define gckOS_AtomConstruct gcmHAL2D(gckOS_AtomConstruct)
  152798. +#define gckOS_AtomDestroy gcmHAL2D(gckOS_AtomDestroy)
  152799. +#define gckOS_AtomGet gcmHAL2D(gckOS_AtomGet)
  152800. +#define gckOS_AtomIncrement gcmHAL2D(gckOS_AtomIncrement)
  152801. +#define gckOS_AtomDecrement gcmHAL2D(gckOS_AtomDecrement)
  152802. +#define gckOS_Delay gcmHAL2D(gckOS_Delay)
  152803. +#define gckOS_GetTime gcmHAL2D(gckOS_GetTime)
  152804. +#define gckOS_MemoryBarrier gcmHAL2D(gckOS_MemoryBarrier)
  152805. +#define gckOS_MapUserPointer gcmHAL2D(gckOS_MapUserPointer)
  152806. +#define gckOS_UnmapUserPointer gcmHAL2D(gckOS_UnmapUserPointer)
  152807. +#define gckOS_QueryNeedCopy gcmHAL2D(gckOS_QueryNeedCopy)
  152808. +#define gckOS_CopyFromUserData gcmHAL2D(gckOS_CopyFromUserData)
  152809. +#define gckOS_CopyToUserData gcmHAL2D(gckOS_CopyToUserData)
  152810. +#define gckOS_MapUserPhysical gcmHAL2D(gckOS_MapUserPhysical)
  152811. +#define gckOS_SuspendInterrupt gcmHAL2D(gckOS_SuspendInterrupt)
  152812. +#define gckOS_ResumeInterrupt gcmHAL2D(gckOS_ResumeInterrupt)
  152813. +#define gckOS_GetBaseAddress gcmHAL2D(gckOS_GetBaseAddress)
  152814. +#define gckOS_MemCopy gcmHAL2D(gckOS_MemCopy)
  152815. +#define gckOS_ZeroMemory gcmHAL2D(gckOS_ZeroMemory)
  152816. +#define gckOS_DeviceControl gcmHAL2D(gckOS_DeviceControl)
  152817. +#define gckOS_GetProcessID gcmHAL2D(gckOS_GetProcessID)
  152818. +#define gckOS_GetThreadID gcmHAL2D(gckOS_GetThreadID)
  152819. +#define gckOS_CreateSignal gcmHAL2D(gckOS_CreateSignal)
  152820. +#define gckOS_DestroySignal gcmHAL2D(gckOS_DestroySignal)
  152821. +#define gckOS_Signal gcmHAL2D(gckOS_Signal)
  152822. +#define gckOS_WaitSignal gcmHAL2D(gckOS_WaitSignal)
  152823. +#define gckOS_MapSignal gcmHAL2D(gckOS_MapSignal)
  152824. +#define gckOS_MapUserMemory gcmHAL2D(gckOS_MapUserMemory)
  152825. +#define gckOS_UnmapUserMemory gcmHAL2D(gckOS_UnmapUserMemory)
  152826. +#define gckOS_CreateUserSignal gcmHAL2D(gckOS_CreateUserSignal)
  152827. +#define gckOS_DestroyUserSignal gcmHAL2D(gckOS_DestroyUserSignal)
  152828. +#define gckOS_WaitUserSignal gcmHAL2D(gckOS_WaitUserSignal)
  152829. +#define gckOS_SignalUserSignal gcmHAL2D(gckOS_SignalUserSignal)
  152830. +#define gckOS_UserSignal gcmHAL2D(gckOS_UserSignal)
  152831. +#define gckOS_UserSignal gcmHAL2D(gckOS_UserSignal)
  152832. +#define gckOS_CacheClean gcmHAL2D(gckOS_CacheClean)
  152833. +#define gckOS_CacheFlush gcmHAL2D(gckOS_CacheFlush)
  152834. +#define gckOS_SetDebugLevel gcmHAL2D(gckOS_SetDebugLevel)
  152835. +#define gckOS_SetDebugZone gcmHAL2D(gckOS_SetDebugZone)
  152836. +#define gckOS_SetDebugLevelZone gcmHAL2D(gckOS_SetDebugLevelZone)
  152837. +#define gckOS_SetDebugZones gcmHAL2D(gckOS_SetDebugZones)
  152838. +#define gckOS_SetDebugFile gcmHAL2D(gckOS_SetDebugFile)
  152839. +#define gckOS_Broadcast gcmHAL2D(gckOS_Broadcast)
  152840. +#define gckOS_SetGPUPower gcmHAL2D(gckOS_SetGPUPower)
  152841. +#define gckOS_CreateSemaphore gcmHAL2D(gckOS_CreateSemaphore)
  152842. +#define gckOS_DestroySemaphore gcmHAL2D(gckOS_DestroySemaphore)
  152843. +#define gckOS_AcquireSemaphore gcmHAL2D(gckOS_AcquireSemaphore)
  152844. +#define gckOS_ReleaseSemaphore gcmHAL2D(gckOS_ReleaseSemaphore)
  152845. +#define gckHEAP_Construct gcmHAL2D(gckHEAP_Construct)
  152846. +#define gckHEAP_Destroy gcmHAL2D(gckHEAP_Destroy)
  152847. +#define gckHEAP_Allocate gcmHAL2D(gckHEAP_Allocate)
  152848. +#define gckHEAP_Free gcmHAL2D(gckHEAP_Free)
  152849. +#define gckHEAP_ProfileStart gcmHAL2D(gckHEAP_ProfileStart)
  152850. +#define gckHEAP_ProfileEnd gcmHAL2D(gckHEAP_ProfileEnd)
  152851. +#define gckHEAP_Test gcmHAL2D(gckHEAP_Test)
  152852. +#define gckVIDMEM_Construct gcmHAL2D(gckVIDMEM_Construct)
  152853. +#define gckVIDMEM_Destroy gcmHAL2D(gckVIDMEM_Destroy)
  152854. +#define gckVIDMEM_Allocate gcmHAL2D(gckVIDMEM_Allocate)
  152855. +#define gckVIDMEM_AllocateLinear gcmHAL2D(gckVIDMEM_AllocateLinear)
  152856. +#define gckVIDMEM_Free gcmHAL2D(gckVIDMEM_Free)
  152857. +#define gckVIDMEM_Lock gcmHAL2D(gckVIDMEM_Lock)
  152858. +#define gckVIDMEM_Unlock gcmHAL2D(gckVIDMEM_Unlock)
  152859. +#define gckVIDMEM_ConstructVirtual gcmHAL2D(gckVIDMEM_ConstructVirtual)
  152860. +#define gckVIDMEM_DestroyVirtual gcmHAL2D(gckVIDMEM_DestroyVirtual)
  152861. +#define gckKERNEL_Construct gcmHAL2D(gckKERNEL_Construct)
  152862. +#define gckKERNEL_Destroy gcmHAL2D(gckKERNEL_Destroy)
  152863. +#define gckKERNEL_Dispatch gcmHAL2D(gckKERNEL_Dispatch)
  152864. +#define gckKERNEL_QueryVideoMemory gcmHAL2D(gckKERNEL_QueryVideoMemory)
  152865. +#define gckKERNEL_GetVideoMemoryPool gcmHAL2D(gckKERNEL_GetVideoMemoryPool)
  152866. +#define gckKERNEL_MapVideoMemory gcmHAL2D(gckKERNEL_MapVideoMemory)
  152867. +#define gckKERNEL_UnmapVideoMemory gcmHAL2D(gckKERNEL_UnmapVideoMemory)
  152868. +#define gckKERNEL_MapMemory gcmHAL2D(gckKERNEL_MapMemory)
  152869. +#define gckKERNEL_UnmapMemory gcmHAL2D(gckKERNEL_UnmapMemory)
  152870. +#define gckKERNEL_Notify gcmHAL2D(gckKERNEL_Notify)
  152871. +#define gckKERNEL_QuerySettings gcmHAL2D(gckKERNEL_QuerySettings)
  152872. +#define gckKERNEL_Recovery gcmHAL2D(gckKERNEL_Recovery)
  152873. +#define gckKERNEL_OpenUserData gcmHAL2D(gckKERNEL_OpenUserData)
  152874. +#define gckKERNEL_CloseUserData gcmHAL2D(gckKERNEL_CloseUserData)
  152875. +#define gckHARDWARE_Construct gcmHAL2D(gckHARDWARE_Construct)
  152876. +#define gckHARDWARE_Destroy gcmHAL2D(gckHARDWARE_Destroy)
  152877. +#define gckHARDWARE_QuerySystemMemory gcmHAL2D(gckHARDWARE_QuerySystemMemory)
  152878. +#define gckHARDWARE_BuildVirtualAddress gcmHAL2D(gckHARDWARE_BuildVirtualAddress)
  152879. +#define gckHARDWARE_QueryCommandBuffer gcmHAL2D(gckHARDWARE_QueryCommandBuffer)
  152880. +#define gckHARDWARE_WaitLink gcmHAL2D(gckHARDWARE_WaitLink)
  152881. +#define gckHARDWARE_Execute gcmHAL2D(gckHARDWARE_Execute)
  152882. +#define gckHARDWARE_End gcmHAL2D(gckHARDWARE_End)
  152883. +#define gckHARDWARE_Nop gcmHAL2D(gckHARDWARE_Nop)
  152884. +#define gckHARDWARE_Wait gcmHAL2D(gckHARDWARE_Wait)
  152885. +#define gckHARDWARE_PipeSelect gcmHAL2D(gckHARDWARE_PipeSelect)
  152886. +#define gckHARDWARE_Link gcmHAL2D(gckHARDWARE_Link)
  152887. +#define gckHARDWARE_Event gcmHAL2D(gckHARDWARE_Event)
  152888. +#define gckHARDWARE_QueryMemory gcmHAL2D(gckHARDWARE_QueryMemory)
  152889. +#define gckHARDWARE_QueryChipIdentity gcmHAL2D(gckHARDWARE_QueryChipIdentity)
  152890. +#define gckHARDWARE_QueryChipSpecs gcmHAL2D(gckHARDWARE_QueryChipSpecs)
  152891. +#define gckHARDWARE_QueryShaderCaps gcmHAL2D(gckHARDWARE_QueryShaderCaps)
  152892. +#define gckHARDWARE_ConvertFormat gcmHAL2D(gckHARDWARE_ConvertFormat)
  152893. +#define gckHARDWARE_SplitMemory gcmHAL2D(gckHARDWARE_SplitMemory)
  152894. +#define gckHARDWARE_AlignToTile gcmHAL2D(gckHARDWARE_AlignToTile)
  152895. +#define gckHARDWARE_UpdateQueueTail gcmHAL2D(gckHARDWARE_UpdateQueueTail)
  152896. +#define gckHARDWARE_ConvertLogical gcmHAL2D(gckHARDWARE_ConvertLogical)
  152897. +#define gckHARDWARE_ConvertPhysical gcmHAL2D(gckHARDWARE_ConvertPhysical)
  152898. +#define gckHARDWARE_Interrupt gcmHAL2D(gckHARDWARE_Interrupt)
  152899. +#define gckHARDWARE_SetMMU gcmHAL2D(gckHARDWARE_SetMMU)
  152900. +#define gckHARDWARE_FlushMMU gcmHAL2D(gckHARDWARE_FlushMMU)
  152901. +#define gckHARDWARE_GetIdle gcmHAL2D(gckHARDWARE_GetIdle)
  152902. +#define gckHARDWARE_Flush gcmHAL2D(gckHARDWARE_Flush)
  152903. +#define gckHARDWARE_SetFastClear gcmHAL2D(gckHARDWARE_SetFastClear)
  152904. +#define gckHARDWARE_ReadInterrupt gcmHAL2D(gckHARDWARE_ReadInterrupt)
  152905. +#define gckHARDWARE_SetPowerManagementState gcmHAL2D(gckHARDWARE_SetPowerManagementState)
  152906. +#define gckHARDWARE_QueryPowerManagementState gcmHAL2D(gckHARDWARE_QueryPowerManagementState)
  152907. +#define gckHARDWARE_ProfileEngine2D gcmHAL2D(gckHARDWARE_ProfileEngine2D)
  152908. +#define gckHARDWARE_InitializeHardware gcmHAL2D(gckHARDWARE_InitializeHardware)
  152909. +#define gckHARDWARE_Reset gcmHAL2D(gckHARDWARE_Reset)
  152910. +#define gckINTERRUPT_Construct gcmHAL2D(gckINTERRUPT_Construct)
  152911. +#define gckINTERRUPT_Destroy gcmHAL2D(gckINTERRUPT_Destroy)
  152912. +#define gckINTERRUPT_SetHandler gcmHAL2D(gckINTERRUPT_SetHandler)
  152913. +#define gckINTERRUPT_Notify gcmHAL2D(gckINTERRUPT_Notify)
  152914. +#define gckEVENT_Construct gcmHAL2D(gckEVENT_Construct)
  152915. +#define gckEVENT_Destroy gcmHAL2D(gckEVENT_Destroy)
  152916. +#define gckEVENT_AddList gcmHAL2D(gckEVENT_AddList)
  152917. +#define gckEVENT_FreeNonPagedMemory gcmHAL2D(gckEVENT_FreeNonPagedMemory)
  152918. +#define gckEVENT_FreeContiguousMemory gcmHAL2D(gckEVENT_FreeContiguousMemory)
  152919. +#define gckEVENT_FreeVideoMemory gcmHAL2D(gckEVENT_FreeVideoMemory)
  152920. +#define gckEVENT_Signal gcmHAL2D(gckEVENT_Signal)
  152921. +#define gckEVENT_Unlock gcmHAL2D(gckEVENT_Unlock)
  152922. +#define gckEVENT_Submit gcmHAL2D(gckEVENT_Submit)
  152923. +#define gckEVENT_Commit gcmHAL2D(gckEVENT_Commit)
  152924. +#define gckEVENT_Notify gcmHAL2D(gckEVENT_Notify)
  152925. +#define gckEVENT_Interrupt gcmHAL2D(gckEVENT_Interrupt)
  152926. +#define gckCOMMAND_Construct gcmHAL2D(gckCOMMAND_Construct)
  152927. +#define gckCOMMAND_Destroy gcmHAL2D(gckCOMMAND_Destroy)
  152928. +#define gckCOMMAND_EnterCommit gcmHAL2D(gckCOMMAND_EnterCommit)
  152929. +#define gckCOMMAND_ExitCommit gcmHAL2D(gckCOMMAND_ExitCommit)
  152930. +#define gckCOMMAND_Start gcmHAL2D(gckCOMMAND_Start)
  152931. +#define gckCOMMAND_Stop gcmHAL2D(gckCOMMAND_Stop)
  152932. +#define gckCOMMAND_Commit gcmHAL2D(gckCOMMAND_Commit)
  152933. +#define gckCOMMAND_Reserve gcmHAL2D(gckCOMMAND_Reserve)
  152934. +#define gckCOMMAND_Execute gcmHAL2D(gckCOMMAND_Execute)
  152935. +#define gckCOMMAND_Stall gcmHAL2D(gckCOMMAND_Stall)
  152936. +#define gckCOMMAND_Attach gcmHAL2D(gckCOMMAND_Attach)
  152937. +#define gckCOMMAND_Detach gcmHAL2D(gckCOMMAND_Detach)
  152938. +#define gckMMU_Construct gcmHAL2D(gckMMU_Construct)
  152939. +#define gckMMU_Destroy gcmHAL2D(gckMMU_Destroy)
  152940. +#define gckMMU_AllocatePages gcmHAL2D(gckMMU_AllocatePages)
  152941. +#define gckMMU_FreePages gcmHAL2D(gckMMU_FreePages)
  152942. +#define gckMMU_InsertNode gcmHAL2D(gckMMU_InsertNode)
  152943. +#define gckMMU_RemoveNode gcmHAL2D(gckMMU_RemoveNode)
  152944. +#define gckMMU_FreeHandleMemory gcmHAL2D(gckMMU_FreeHandleMemory)
  152945. +#define gckMMU_Test gcmHAL2D(gckMMU_Test)
  152946. +#define gckHARDWARE_QueryProfileRegisters gcmHAL2D(gckHARDWARE_QueryProfileRegisters)
  152947. +
  152948. +
  152949. +#define FindMdlMap gcmHAL2D(FindMdlMap)
  152950. +#define OnProcessExit gcmHAL2D(OnProcessExit)
  152951. +
  152952. +#define gckGALDEVICE_Destroy gcmHAL2D(gckGALDEVICE_Destroy)
  152953. +#define gckOS_Print gcmHAL2D(gckOS_Print)
  152954. +#define gckGALDEVICE_FreeMemory gcmHAL2D(gckGALDEVICE_FreeMemory)
  152955. +#define gckGALDEVICE_AllocateMemory gcmHAL2D(gckGALDEVICE_AllocateMemory)
  152956. +#define gckOS_DebugBreak gcmHAL2D(gckOS_DebugBreak)
  152957. +#define gckGALDEVICE_Release_ISR gcmHAL2D(gckGALDEVICE_Release_ISR)
  152958. +#define gckOS_Verify gcmHAL2D(gckOS_Verify)
  152959. +#define gckCOMMAND_Release gcmHAL2D(gckCOMMAND_Release)
  152960. +#define gckGALDEVICE_Stop gcmHAL2D(gckGALDEVICE_Stop)
  152961. +#define gckGALDEVICE_Construct gcmHAL2D(gckGALDEVICE_Construct)
  152962. +#define gckOS_DebugFatal gcmHAL2D(gckOS_DebugFatal)
  152963. +#define gckOS_DebugTrace gcmHAL2D(gckOS_DebugTrace)
  152964. +#define gckHARDWARE_GetBaseAddress gcmHAL2D(gckHARDWARE_GetBaseAddress)
  152965. +#define gckGALDEVICE_Setup_ISR gcmHAL2D(gckGALDEVICE_Setup_ISR)
  152966. +#define gckKERNEL_AttachProcess gcmHAL2D(gckKERNEL_AttachProcess)
  152967. +#define gckKERNEL_AttachProcessEx gcmHAL2D(gckKERNEL_AttachProcessEx)
  152968. +#define gckGALDEVICE_Start_Thread gcmHAL2D(gckGALDEVICE_Start_Thread)
  152969. +#define gckHARDWARE_QueryIdle gcmHAL2D(gckHARDWARE_QueryIdle)
  152970. +#define gckGALDEVICE_Start gcmHAL2D(gckGALDEVICE_Start)
  152971. +#define gckOS_GetKernelLogical gcmHAL2D(gckOS_GetKernelLogical)
  152972. +#define gckOS_DebugTraceZone gcmHAL2D(gckOS_DebugTraceZone)
  152973. +#define gckGALDEVICE_Stop_Thread gcmHAL2D(gckGALDEVICE_Stop_Thread)
  152974. +#define gckHARDWARE_NeedBaseAddress gcmHAL2D(gckHARDWARE_NeedBaseAddress)
  152975. +
  152976. +#endif
  152977. +
  152978. +#endif /* __gc_hal_rename_h_ */
  152979. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h
  152980. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h 1970-01-01 01:00:00.000000000 +0100
  152981. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h 2014-08-20 19:23:53.570845890 +0200
  152982. @@ -0,0 +1,115 @@
  152983. +/****************************************************************************
  152984. +*
  152985. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  152986. +*
  152987. +* This program is free software; you can redistribute it and/or modify
  152988. +* it under the terms of the GNU General Public License as published by
  152989. +* the Free Software Foundation; either version 2 of the license, or
  152990. +* (at your option) any later version.
  152991. +*
  152992. +* This program is distributed in the hope that it will be useful,
  152993. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  152994. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  152995. +* GNU General Public License for more details.
  152996. +*
  152997. +* You should have received a copy of the GNU General Public License
  152998. +* along with this program; if not write to the Free Software
  152999. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  153000. +*
  153001. +*****************************************************************************/
  153002. +
  153003. +
  153004. +#ifndef __gc_hal_statistics_h_
  153005. +#define __gc_hal_statistics_h_
  153006. +
  153007. +
  153008. +#define VIV_STAT_ENABLE_STATISTICS 0
  153009. +
  153010. +/* Toal number of frames for which the frame time is accounted. We have storage
  153011. + to keep frame times for last this many frames.
  153012. +*/
  153013. +#define VIV_STAT_FRAME_BUFFER_SIZE 30
  153014. +
  153015. +/*
  153016. + Total number of frames sampled for a mode. This means
  153017. +
  153018. + # of frames for HZ Current : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
  153019. + # of frames for HZ Switched : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
  153020. + +
  153021. + --------------------------------------------------------
  153022. + : (2 * VIV_STAT_EARLY_Z_SAMPLE_FRAMES) frames needed
  153023. +
  153024. + IMPORTANT: This total must be smaller than VIV_STAT_FRAME_BUFFER_SIZE
  153025. +*/
  153026. +#define VIV_STAT_EARLY_Z_SAMPLE_FRAMES 7
  153027. +#define VIV_STAT_EARLY_Z_LATENCY_FRAMES 2
  153028. +
  153029. +/* Multiplication factor for previous Hz off mode. Make it more than 1.0 to advertise HZ on.*/
  153030. +#define VIV_STAT_EARLY_Z_FACTOR (1.05f)
  153031. +
  153032. +/* Defines the statistical data keys monitored by the statistics module */
  153033. +typedef enum _gceSTATISTICS
  153034. +{
  153035. + gcvFRAME_FPS = 1,
  153036. +}
  153037. +gceSTATISTICS;
  153038. +
  153039. +/* HAL statistics information. */
  153040. +typedef struct _gcsSTATISTICS_EARLYZ
  153041. +{
  153042. + gctUINT switchBackCount;
  153043. + gctUINT nextCheckPoint;
  153044. + gctBOOL disabled;
  153045. +}
  153046. +gcsSTATISTICS_EARLYZ;
  153047. +
  153048. +
  153049. +/* Defines the statistical data keys monitored by the statistics module */
  153050. +typedef enum _gceSTATISTICS_Call
  153051. +{
  153052. + gcvSTAT_ES11_GLDRAWELEMENTS = 1,
  153053. +}
  153054. +gceSTATISTICS_Call;
  153055. +
  153056. +
  153057. +/* HAL statistics information. */
  153058. +typedef struct _gcsSTATISTICS
  153059. +{
  153060. + gctUINT64 frameTime[VIV_STAT_FRAME_BUFFER_SIZE];
  153061. + gctUINT64 previousFrameTime;
  153062. + gctUINT frame;
  153063. + gcsSTATISTICS_EARLYZ earlyZ;
  153064. + gctUINT ES11_drawElementsCount;
  153065. + gctBOOL applyRTestVAFix;
  153066. +}
  153067. +gcsSTATISTICS;
  153068. +
  153069. +
  153070. +/* Add a frame based data into current statistics. */
  153071. +void
  153072. +gcfSTATISTICS_AddData(
  153073. + IN gceSTATISTICS Key,
  153074. + IN gctUINT Value
  153075. + );
  153076. +
  153077. +/* Marks the frame end and triggers statistical calculations and decisions.*/
  153078. +void
  153079. +gcfSTATISTICS_MarkFrameEnd (
  153080. + void
  153081. + );
  153082. +
  153083. +/* Sets whether the dynmaic HZ is disabled or not .*/
  153084. +void
  153085. +gcfSTATISTICS_DisableDynamicEarlyZ (
  153086. + IN gctBOOL Disabled
  153087. + );
  153088. +
  153089. +/* Checks whether or not glDrawArray function call will be discarded */
  153090. +gctBOOL
  153091. +gcfSTATISTICS_DiscardCall(
  153092. + gceSTATISTICS_Call Function
  153093. + );
  153094. +
  153095. +
  153096. +#endif /*__gc_hal_statistics_h_ */
  153097. +
  153098. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
  153099. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h 1970-01-01 01:00:00.000000000 +0100
  153100. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h 2014-08-20 19:31:46.136869040 +0200
  153101. @@ -0,0 +1,1080 @@
  153102. +/****************************************************************************
  153103. +*
  153104. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  153105. +*
  153106. +* This program is free software; you can redistribute it and/or modify
  153107. +* it under the terms of the GNU General Public License as published by
  153108. +* the Free Software Foundation; either version 2 of the license, or
  153109. +* (at your option) any later version.
  153110. +*
  153111. +* This program is distributed in the hope that it will be useful,
  153112. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  153113. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  153114. +* GNU General Public License for more details.
  153115. +*
  153116. +* You should have received a copy of the GNU General Public License
  153117. +* along with this program; if not write to the Free Software
  153118. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  153119. +*
  153120. +*****************************************************************************/
  153121. +
  153122. +
  153123. +#ifndef __gc_hal_types_h_
  153124. +#define __gc_hal_types_h_
  153125. +
  153126. +#include "gc_hal_version.h"
  153127. +#include "gc_hal_options.h"
  153128. +
  153129. +#ifdef _WIN32
  153130. +#pragma warning(disable:4127) /* Conditional expression is constant (do { }
  153131. + ** while(0)). */
  153132. +#pragma warning(disable:4100) /* Unreferenced formal parameter. */
  153133. +#pragma warning(disable:4204) /* Non-constant aggregate initializer (C99). */
  153134. +#pragma warning(disable:4131) /* Uses old-style declarator (for Bison and
  153135. + ** Flex generated files). */
  153136. +#pragma warning(disable:4206) /* Translation unit is empty. */
  153137. +#endif
  153138. +
  153139. +#ifdef __cplusplus
  153140. +extern "C" {
  153141. +#endif
  153142. +
  153143. +/******************************************************************************\
  153144. +** Platform macros.
  153145. +*/
  153146. +
  153147. +#if defined(__GNUC__)
  153148. +# define gcdHAS_ELLIPSES 1 /* GCC always has it. */
  153149. +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
  153150. +# define gcdHAS_ELLIPSES 1 /* C99 has it. */
  153151. +#elif defined(_MSC_VER) && (_MSC_VER >= 1500)
  153152. +# define gcdHAS_ELLIPSES 1 /* MSVC 2007+ has it. */
  153153. +#elif defined(UNDER_CE)
  153154. +#if UNDER_CE >= 600
  153155. +# define gcdHAS_ELLIPSES 1
  153156. +# else
  153157. +# define gcdHAS_ELLIPSES 0
  153158. +# endif
  153159. +#else
  153160. +# error "gcdHAS_ELLIPSES: Platform could not be determined"
  153161. +#endif
  153162. +
  153163. +/******************************************************************************\
  153164. +************************************ Keyword ***********************************
  153165. +\******************************************************************************/
  153166. +
  153167. +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
  153168. +# define gcmINLINE inline /* C99 keyword. */
  153169. +#elif defined(__GNUC__)
  153170. +# define gcmINLINE __inline__ /* GNU keyword. */
  153171. +#elif defined(_MSC_VER) || defined(UNDER_CE)
  153172. +# define gcmINLINE __inline /* Internal keyword. */
  153173. +#else
  153174. +# error "gcmINLINE: Platform could not be determined"
  153175. +#endif
  153176. +
  153177. +/* Possible debug flags. */
  153178. +#define gcdDEBUG_NONE 0
  153179. +#define gcdDEBUG_ALL (1 << 0)
  153180. +#define gcdDEBUG_FATAL (1 << 1)
  153181. +#define gcdDEBUG_TRACE (1 << 2)
  153182. +#define gcdDEBUG_BREAK (1 << 3)
  153183. +#define gcdDEBUG_ASSERT (1 << 4)
  153184. +#define gcdDEBUG_CODE (1 << 5)
  153185. +#define gcdDEBUG_STACK (1 << 6)
  153186. +
  153187. +#define gcmIS_DEBUG(flag) ( gcdDEBUG & (flag | gcdDEBUG_ALL) )
  153188. +
  153189. +#ifndef gcdDEBUG
  153190. +#if (defined(DBG) && DBG) || defined(DEBUG) || defined(_DEBUG)
  153191. +# define gcdDEBUG gcdDEBUG_ALL
  153192. +# else
  153193. +# define gcdDEBUG gcdDEBUG_NONE
  153194. +# endif
  153195. +#endif
  153196. +
  153197. +#ifdef _USRDLL
  153198. +#ifdef _MSC_VER
  153199. +#ifdef HAL_EXPORTS
  153200. +# define HALAPI __declspec(dllexport)
  153201. +# else
  153202. +# define HALAPI __declspec(dllimport)
  153203. +# endif
  153204. +# define HALDECL __cdecl
  153205. +# else
  153206. +#ifdef HAL_EXPORTS
  153207. +# define HALAPI
  153208. +# else
  153209. +# define HALAPI extern
  153210. +# endif
  153211. +# endif
  153212. +#else
  153213. +# define HALAPI
  153214. +# define HALDECL
  153215. +#endif
  153216. +
  153217. +/******************************************************************************\
  153218. +********************************** Common Types ********************************
  153219. +\******************************************************************************/
  153220. +
  153221. +#define gcvFALSE 0
  153222. +#define gcvTRUE 1
  153223. +
  153224. +#define gcvINFINITE ((gctUINT32) ~0U)
  153225. +
  153226. +#define gcvINVALID_HANDLE ((gctHANDLE) ~0U)
  153227. +
  153228. +typedef int gctBOOL;
  153229. +typedef gctBOOL * gctBOOL_PTR;
  153230. +
  153231. +typedef int gctINT;
  153232. +typedef long gctLONG;
  153233. +typedef signed char gctINT8;
  153234. +typedef signed short gctINT16;
  153235. +typedef signed int gctINT32;
  153236. +typedef signed long long gctINT64;
  153237. +
  153238. +typedef gctINT * gctINT_PTR;
  153239. +typedef gctINT8 * gctINT8_PTR;
  153240. +typedef gctINT16 * gctINT16_PTR;
  153241. +typedef gctINT32 * gctINT32_PTR;
  153242. +typedef gctINT64 * gctINT64_PTR;
  153243. +
  153244. +typedef unsigned int gctUINT;
  153245. +typedef unsigned char gctUINT8;
  153246. +typedef unsigned short gctUINT16;
  153247. +typedef unsigned int gctUINT32;
  153248. +typedef unsigned long long gctUINT64;
  153249. +typedef unsigned long gctUINTPTR_T;
  153250. +
  153251. +typedef gctUINT * gctUINT_PTR;
  153252. +typedef gctUINT8 * gctUINT8_PTR;
  153253. +typedef gctUINT16 * gctUINT16_PTR;
  153254. +typedef gctUINT32 * gctUINT32_PTR;
  153255. +typedef gctUINT64 * gctUINT64_PTR;
  153256. +
  153257. +typedef unsigned long gctSIZE_T;
  153258. +typedef gctSIZE_T * gctSIZE_T_PTR;
  153259. +
  153260. +#ifdef __cplusplus
  153261. +# define gcvNULL 0
  153262. +#else
  153263. +# define gcvNULL ((void *) 0)
  153264. +#endif
  153265. +
  153266. +typedef float gctFLOAT;
  153267. +typedef signed int gctFIXED_POINT;
  153268. +typedef float * gctFLOAT_PTR;
  153269. +
  153270. +typedef void * gctPHYS_ADDR;
  153271. +typedef void * gctHANDLE;
  153272. +typedef void * gctFILE;
  153273. +typedef void * gctSIGNAL;
  153274. +typedef void * gctWINDOW;
  153275. +typedef void * gctIMAGE;
  153276. +typedef void * gctSYNC_POINT;
  153277. +
  153278. +typedef void * gctSEMAPHORE;
  153279. +
  153280. +typedef void * gctPOINTER;
  153281. +typedef const void * gctCONST_POINTER;
  153282. +
  153283. +typedef char gctCHAR;
  153284. +typedef char * gctSTRING;
  153285. +typedef const char * gctCONST_STRING;
  153286. +
  153287. +typedef struct _gcsCOUNT_STRING
  153288. +{
  153289. + gctSIZE_T Length;
  153290. + gctCONST_STRING String;
  153291. +}
  153292. +gcsCOUNT_STRING;
  153293. +
  153294. +typedef union _gcuFLOAT_UINT32
  153295. +{
  153296. + gctFLOAT f;
  153297. + gctUINT32 u;
  153298. +}
  153299. +gcuFLOAT_UINT32;
  153300. +
  153301. +/* Fixed point constants. */
  153302. +#define gcvZERO_X ((gctFIXED_POINT) 0x00000000)
  153303. +#define gcvHALF_X ((gctFIXED_POINT) 0x00008000)
  153304. +#define gcvONE_X ((gctFIXED_POINT) 0x00010000)
  153305. +#define gcvNEGONE_X ((gctFIXED_POINT) 0xFFFF0000)
  153306. +#define gcvTWO_X ((gctFIXED_POINT) 0x00020000)
  153307. +
  153308. +/* Stringizing macro. */
  153309. +#define gcmSTRING(Value) #Value
  153310. +
  153311. +/******************************************************************************\
  153312. +******************************* Fixed Point Math *******************************
  153313. +\******************************************************************************/
  153314. +
  153315. +#define gcmXMultiply(x1, x2) gcoMATH_MultiplyFixed(x1, x2)
  153316. +#define gcmXDivide(x1, x2) gcoMATH_DivideFixed(x1, x2)
  153317. +#define gcmXMultiplyDivide(x1, x2, x3) gcoMATH_MultiplyDivideFixed(x1, x2, x3)
  153318. +
  153319. +/* 2D Engine profile. */
  153320. +typedef struct _gcs2D_PROFILE
  153321. +{
  153322. + /* Cycle count.
  153323. + 32bit counter incremented every 2D clock cycle.
  153324. + Wraps back to 0 when the counter overflows.
  153325. + */
  153326. + gctUINT32 cycleCount;
  153327. +
  153328. + /* Pixels rendered by the 2D engine.
  153329. + Resets to 0 every time it is read. */
  153330. + gctUINT32 pixelsRendered;
  153331. +}
  153332. +gcs2D_PROFILE;
  153333. +
  153334. +/* Macro to combine four characters into a Charcater Code. */
  153335. +#define gcmCC(c1, c2, c3, c4) \
  153336. +( \
  153337. + (char) (c1) \
  153338. + | \
  153339. + ((char) (c2) << 8) \
  153340. + | \
  153341. + ((char) (c3) << 16) \
  153342. + | \
  153343. + ((char) (c4) << 24) \
  153344. +)
  153345. +
  153346. +#define gcmPRINTABLE(c) ((((c) >= ' ') && ((c) <= '}')) ? ((c) != '%' ? (c) : ' ') : ' ')
  153347. +
  153348. +#define gcmCC_PRINT(cc) \
  153349. + gcmPRINTABLE((char) ( (cc) & 0xFF)), \
  153350. + gcmPRINTABLE((char) (((cc) >> 8) & 0xFF)), \
  153351. + gcmPRINTABLE((char) (((cc) >> 16) & 0xFF)), \
  153352. + gcmPRINTABLE((char) (((cc) >> 24) & 0xFF))
  153353. +
  153354. +/******************************************************************************\
  153355. +****************************** Function Parameters *****************************
  153356. +\******************************************************************************/
  153357. +
  153358. +#define IN
  153359. +#define OUT
  153360. +#define OPTIONAL
  153361. +
  153362. +/******************************************************************************\
  153363. +********************************* Status Codes *********************************
  153364. +\******************************************************************************/
  153365. +
  153366. +typedef enum _gceSTATUS
  153367. +{
  153368. + gcvSTATUS_OK = 0,
  153369. + gcvSTATUS_FALSE = 0,
  153370. + gcvSTATUS_TRUE = 1,
  153371. + gcvSTATUS_NO_MORE_DATA = 2,
  153372. + gcvSTATUS_CACHED = 3,
  153373. + gcvSTATUS_MIPMAP_TOO_LARGE = 4,
  153374. + gcvSTATUS_NAME_NOT_FOUND = 5,
  153375. + gcvSTATUS_NOT_OUR_INTERRUPT = 6,
  153376. + gcvSTATUS_MISMATCH = 7,
  153377. + gcvSTATUS_MIPMAP_TOO_SMALL = 8,
  153378. + gcvSTATUS_LARGER = 9,
  153379. + gcvSTATUS_SMALLER = 10,
  153380. + gcvSTATUS_CHIP_NOT_READY = 11,
  153381. + gcvSTATUS_NEED_CONVERSION = 12,
  153382. + gcvSTATUS_SKIP = 13,
  153383. + gcvSTATUS_DATA_TOO_LARGE = 14,
  153384. + gcvSTATUS_INVALID_CONFIG = 15,
  153385. + gcvSTATUS_CHANGED = 16,
  153386. + gcvSTATUS_NOT_SUPPORT_DITHER = 17,
  153387. + gcvSTATUS_EXECUTED = 18,
  153388. + gcvSTATUS_TERMINATE = 19,
  153389. +
  153390. + gcvSTATUS_CONVERT_TO_SINGLE_STREAM = 20,
  153391. +
  153392. + gcvSTATUS_INVALID_ARGUMENT = -1,
  153393. + gcvSTATUS_INVALID_OBJECT = -2,
  153394. + gcvSTATUS_OUT_OF_MEMORY = -3,
  153395. + gcvSTATUS_MEMORY_LOCKED = -4,
  153396. + gcvSTATUS_MEMORY_UNLOCKED = -5,
  153397. + gcvSTATUS_HEAP_CORRUPTED = -6,
  153398. + gcvSTATUS_GENERIC_IO = -7,
  153399. + gcvSTATUS_INVALID_ADDRESS = -8,
  153400. + gcvSTATUS_CONTEXT_LOSSED = -9,
  153401. + gcvSTATUS_TOO_COMPLEX = -10,
  153402. + gcvSTATUS_BUFFER_TOO_SMALL = -11,
  153403. + gcvSTATUS_INTERFACE_ERROR = -12,
  153404. + gcvSTATUS_NOT_SUPPORTED = -13,
  153405. + gcvSTATUS_MORE_DATA = -14,
  153406. + gcvSTATUS_TIMEOUT = -15,
  153407. + gcvSTATUS_OUT_OF_RESOURCES = -16,
  153408. + gcvSTATUS_INVALID_DATA = -17,
  153409. + gcvSTATUS_INVALID_MIPMAP = -18,
  153410. + gcvSTATUS_NOT_FOUND = -19,
  153411. + gcvSTATUS_NOT_ALIGNED = -20,
  153412. + gcvSTATUS_INVALID_REQUEST = -21,
  153413. + gcvSTATUS_GPU_NOT_RESPONDING = -22,
  153414. + gcvSTATUS_TIMER_OVERFLOW = -23,
  153415. + gcvSTATUS_VERSION_MISMATCH = -24,
  153416. + gcvSTATUS_LOCKED = -25,
  153417. + gcvSTATUS_INTERRUPTED = -26,
  153418. + gcvSTATUS_DEVICE = -27,
  153419. + gcvSTATUS_NOT_MULTI_PIPE_ALIGNED = -28,
  153420. +
  153421. + /* Linker errors. */
  153422. + gcvSTATUS_GLOBAL_TYPE_MISMATCH = -1000,
  153423. + gcvSTATUS_TOO_MANY_ATTRIBUTES = -1001,
  153424. + gcvSTATUS_TOO_MANY_UNIFORMS = -1002,
  153425. + gcvSTATUS_TOO_MANY_VARYINGS = -1003,
  153426. + gcvSTATUS_UNDECLARED_VARYING = -1004,
  153427. + gcvSTATUS_VARYING_TYPE_MISMATCH = -1005,
  153428. + gcvSTATUS_MISSING_MAIN = -1006,
  153429. + gcvSTATUS_NAME_MISMATCH = -1007,
  153430. + gcvSTATUS_INVALID_INDEX = -1008,
  153431. + gcvSTATUS_UNIFORM_TYPE_MISMATCH = -1009,
  153432. +
  153433. + /* Compiler errors. */
  153434. + gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR = -2000,
  153435. + gcvSTATUS_COMPILER_FE_PARSER_ERROR = -2001,
  153436. +}
  153437. +gceSTATUS;
  153438. +
  153439. +/******************************************************************************\
  153440. +********************************* Status Macros ********************************
  153441. +\******************************************************************************/
  153442. +
  153443. +#define gcmIS_ERROR(status) (status < 0)
  153444. +#define gcmNO_ERROR(status) (status >= 0)
  153445. +#define gcmIS_SUCCESS(status) (status == gcvSTATUS_OK)
  153446. +
  153447. +/******************************************************************************\
  153448. +********************************* Field Macros *********************************
  153449. +\******************************************************************************/
  153450. +
  153451. +#define __gcmSTART(reg_field) \
  153452. + (0 ? reg_field)
  153453. +
  153454. +#define __gcmEND(reg_field) \
  153455. + (1 ? reg_field)
  153456. +
  153457. +#define __gcmGETSIZE(reg_field) \
  153458. + (__gcmEND(reg_field) - __gcmSTART(reg_field) + 1)
  153459. +
  153460. +#define __gcmALIGN(data, reg_field) \
  153461. + (((gctUINT32) (data)) << __gcmSTART(reg_field))
  153462. +
  153463. +#define __gcmMASK(reg_field) \
  153464. + ((gctUINT32) ((__gcmGETSIZE(reg_field) == 32) \
  153465. + ? ~0 \
  153466. + : (~(~0 << __gcmGETSIZE(reg_field)))))
  153467. +
  153468. +/*******************************************************************************
  153469. +**
  153470. +** gcmFIELDMASK
  153471. +**
  153472. +** Get aligned field mask.
  153473. +**
  153474. +** ARGUMENTS:
  153475. +**
  153476. +** reg Name of register.
  153477. +** field Name of field within register.
  153478. +*/
  153479. +#define gcmFIELDMASK(reg, field) \
  153480. +( \
  153481. + __gcmALIGN(__gcmMASK(reg##_##field), reg##_##field) \
  153482. +)
  153483. +
  153484. +/*******************************************************************************
  153485. +**
  153486. +** gcmGETFIELD
  153487. +**
  153488. +** Extract the value of a field from specified data.
  153489. +**
  153490. +** ARGUMENTS:
  153491. +**
  153492. +** data Data value.
  153493. +** reg Name of register.
  153494. +** field Name of field within register.
  153495. +*/
  153496. +#define gcmGETFIELD(data, reg, field) \
  153497. +( \
  153498. + ((((gctUINT32) (data)) >> __gcmSTART(reg##_##field)) \
  153499. + & __gcmMASK(reg##_##field)) \
  153500. +)
  153501. +
  153502. +/*******************************************************************************
  153503. +**
  153504. +** gcmSETFIELD
  153505. +**
  153506. +** Set the value of a field within specified data.
  153507. +**
  153508. +** ARGUMENTS:
  153509. +**
  153510. +** data Data value.
  153511. +** reg Name of register.
  153512. +** field Name of field within register.
  153513. +** value Value for field.
  153514. +*/
  153515. +#define gcmSETFIELD(data, reg, field, value) \
  153516. +( \
  153517. + (((gctUINT32) (data)) \
  153518. + & ~__gcmALIGN(__gcmMASK(reg##_##field), reg##_##field)) \
  153519. + | __gcmALIGN((gctUINT32) (value) \
  153520. + & __gcmMASK(reg##_##field), reg##_##field) \
  153521. +)
  153522. +
  153523. +/*******************************************************************************
  153524. +**
  153525. +** gcmSETFIELDVALUE
  153526. +**
  153527. +** Set the value of a field within specified data with a
  153528. +** predefined value.
  153529. +**
  153530. +** ARGUMENTS:
  153531. +**
  153532. +** data Data value.
  153533. +** reg Name of register.
  153534. +** field Name of field within register.
  153535. +** value Name of the value within the field.
  153536. +*/
  153537. +#define gcmSETFIELDVALUE(data, reg, field, value) \
  153538. +( \
  153539. + (((gctUINT32) (data)) \
  153540. + & ~__gcmALIGN(__gcmMASK(reg##_##field), reg##_##field)) \
  153541. + | __gcmALIGN(reg##_##field##_##value \
  153542. + & __gcmMASK(reg##_##field), reg##_##field) \
  153543. +)
  153544. +
  153545. +/*******************************************************************************
  153546. +**
  153547. +** gcmGETMASKEDFIELDMASK
  153548. +**
  153549. +** Determine field mask of a masked field.
  153550. +**
  153551. +** ARGUMENTS:
  153552. +**
  153553. +** reg Name of register.
  153554. +** field Name of field within register.
  153555. +*/
  153556. +#define gcmGETMASKEDFIELDMASK(reg, field) \
  153557. +( \
  153558. + gcmSETFIELD(0, reg, field, ~0) | \
  153559. + gcmSETFIELD(0, reg, MASK_ ## field, ~0) \
  153560. +)
  153561. +
  153562. +/*******************************************************************************
  153563. +**
  153564. +** gcmSETMASKEDFIELD
  153565. +**
  153566. +** Set the value of a masked field with specified data.
  153567. +**
  153568. +** ARGUMENTS:
  153569. +**
  153570. +** reg Name of register.
  153571. +** field Name of field within register.
  153572. +** value Value for field.
  153573. +*/
  153574. +#define gcmSETMASKEDFIELD(reg, field, value) \
  153575. +( \
  153576. + gcmSETFIELD (~0, reg, field, value) & \
  153577. + gcmSETFIELDVALUE(~0, reg, MASK_ ## field, ENABLED) \
  153578. +)
  153579. +
  153580. +/*******************************************************************************
  153581. +**
  153582. +** gcmSETMASKEDFIELDVALUE
  153583. +**
  153584. +** Set the value of a masked field with specified data.
  153585. +**
  153586. +** ARGUMENTS:
  153587. +**
  153588. +** reg Name of register.
  153589. +** field Name of field within register.
  153590. +** value Value for field.
  153591. +*/
  153592. +#define gcmSETMASKEDFIELDVALUE(reg, field, value) \
  153593. +( \
  153594. + gcmSETFIELDVALUE(~0, reg, field, value) & \
  153595. + gcmSETFIELDVALUE(~0, reg, MASK_ ## field, ENABLED) \
  153596. +)
  153597. +
  153598. +/*******************************************************************************
  153599. +**
  153600. +** gcmVERIFYFIELDVALUE
  153601. +**
  153602. +** Verify if the value of a field within specified data equals a
  153603. +** predefined value.
  153604. +**
  153605. +** ARGUMENTS:
  153606. +**
  153607. +** data Data value.
  153608. +** reg Name of register.
  153609. +** field Name of field within register.
  153610. +** value Name of the value within the field.
  153611. +*/
  153612. +#define gcmVERIFYFIELDVALUE(data, reg, field, value) \
  153613. +( \
  153614. + (((gctUINT32) (data)) >> __gcmSTART(reg##_##field) & \
  153615. + __gcmMASK(reg##_##field)) \
  153616. + == \
  153617. + (reg##_##field##_##value & __gcmMASK(reg##_##field)) \
  153618. +)
  153619. +
  153620. +/*******************************************************************************
  153621. +** Bit field macros.
  153622. +*/
  153623. +
  153624. +#define __gcmSTARTBIT(Field) \
  153625. + ( 1 ? Field )
  153626. +
  153627. +#define __gcmBITSIZE(Field) \
  153628. + ( 0 ? Field )
  153629. +
  153630. +#define __gcmBITMASK(Field) \
  153631. +( \
  153632. + (1 << __gcmBITSIZE(Field)) - 1 \
  153633. +)
  153634. +
  153635. +#define gcmGETBITS(Value, Type, Field) \
  153636. +( \
  153637. + ( ((Type) (Value)) >> __gcmSTARTBIT(Field) ) \
  153638. + & \
  153639. + __gcmBITMASK(Field) \
  153640. +)
  153641. +
  153642. +#define gcmSETBITS(Value, Type, Field, NewValue) \
  153643. +( \
  153644. + ( ((Type) (Value)) \
  153645. + & ~(__gcmBITMASK(Field) << __gcmSTARTBIT(Field)) \
  153646. + ) \
  153647. + | \
  153648. + ( ( ((Type) (NewValue)) \
  153649. + & __gcmBITMASK(Field) \
  153650. + ) << __gcmSTARTBIT(Field) \
  153651. + ) \
  153652. +)
  153653. +
  153654. +/*******************************************************************************
  153655. +**
  153656. +** gcmISINREGRANGE
  153657. +**
  153658. +** Verify whether the specified address is in the register range.
  153659. +**
  153660. +** ARGUMENTS:
  153661. +**
  153662. +** Address Address to be verified.
  153663. +** Name Name of a register.
  153664. +*/
  153665. +
  153666. +#define gcmISINREGRANGE(Address, Name) \
  153667. +( \
  153668. + ((Address & (~0U << Name ## _LSB)) == (Name ## _Address >> 2)) \
  153669. +)
  153670. +
  153671. +/*******************************************************************************
  153672. +**
  153673. +** A set of macros to aid state loading.
  153674. +**
  153675. +** ARGUMENTS:
  153676. +**
  153677. +** CommandBuffer Pointer to a gcoCMDBUF object.
  153678. +** StateDelta Pointer to a gcsSTATE_DELTA state delta structure.
  153679. +** Memory Destination memory pointer of gctUINT32_PTR type.
  153680. +** PartOfContext Whether or not the state is a part of the context.
  153681. +** FixedPoint Whether or not the state is of the fixed point format.
  153682. +** Count Number of consecutive states to be loaded.
  153683. +** Address State address.
  153684. +** Data Data to be set to the state.
  153685. +*/
  153686. +
  153687. +/*----------------------------------------------------------------------------*/
  153688. +
  153689. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  153690. +
  153691. +# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count) \
  153692. + CommandBuffer->lastLoadStatePtr = gcmPTR_TO_UINT64(Memory); \
  153693. + CommandBuffer->lastLoadStateAddress = Address; \
  153694. + CommandBuffer->lastLoadStateCount = Count
  153695. +
  153696. +# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address) \
  153697. + gcmASSERT( \
  153698. + (gctUINT) (Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastLoadStatePtr, gctUINT32_PTR) - 1) \
  153699. + == \
  153700. + (gctUINT) (Address - CommandBuffer->lastLoadStateAddress) \
  153701. + ); \
  153702. + \
  153703. + gcmASSERT(CommandBuffer->lastLoadStateCount > 0); \
  153704. + \
  153705. + CommandBuffer->lastLoadStateCount -= 1
  153706. +
  153707. +# define gcmVERIFYLOADSTATEDONE(CommandBuffer) \
  153708. + gcmASSERT(CommandBuffer->lastLoadStateCount == 0)
  153709. +
  153710. +#else
  153711. +
  153712. +# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count)
  153713. +# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address)
  153714. +# define gcmVERIFYLOADSTATEDONE(CommandBuffer)
  153715. +
  153716. +#endif
  153717. +
  153718. +#if gcdSECURE_USER
  153719. +
  153720. +# define gcmDEFINESECUREUSER() \
  153721. + gctUINT __secure_user_offset__; \
  153722. + gctUINT32_PTR __secure_user_hintArray__;
  153723. +
  153724. +# define gcmBEGINSECUREUSER() \
  153725. + __secure_user_offset__ = reserve->lastOffset; \
  153726. + \
  153727. + __secure_user_hintArray__ = gcmUINT64_TO_PTR(reserve->hintArrayTail)
  153728. +
  153729. +# define gcmENDSECUREUSER() \
  153730. + reserve->hintArrayTail = gcmPTR_TO_UINT64(__secure_user_hintArray__)
  153731. +
  153732. +# define gcmSKIPSECUREUSER() \
  153733. + __secure_user_offset__ += gcmSIZEOF(gctUINT32)
  153734. +
  153735. +# define gcmUPDATESECUREUSER() \
  153736. + *__secure_user_hintArray__ = __secure_user_offset__; \
  153737. + \
  153738. + __secure_user_offset__ += gcmSIZEOF(gctUINT32); \
  153739. + __secure_user_hintArray__ += 1
  153740. +
  153741. +#else
  153742. +
  153743. +# define gcmDEFINESECUREUSER()
  153744. +# define gcmBEGINSECUREUSER()
  153745. +# define gcmENDSECUREUSER()
  153746. +# define gcmSKIPSECUREUSER()
  153747. +# define gcmUPDATESECUREUSER()
  153748. +
  153749. +#endif
  153750. +
  153751. +/*----------------------------------------------------------------------------*/
  153752. +
  153753. +#if gcdDUMP
  153754. +# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data) \
  153755. + if (FixedPoint) \
  153756. + { \
  153757. + gcmDUMP(gcvNULL, "@[state.x 0x%04X 0x%08X]", \
  153758. + Address, Data \
  153759. + ); \
  153760. + } \
  153761. + else \
  153762. + { \
  153763. + gcmDUMP(gcvNULL, "@[state 0x%04X 0x%08X]", \
  153764. + Address, Data \
  153765. + ); \
  153766. + }
  153767. +#else
  153768. +# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data)
  153769. +#endif
  153770. +
  153771. +/*----------------------------------------------------------------------------*/
  153772. +
  153773. +#define gcmDEFINESTATEBUFFER(CommandBuffer, StateDelta, Memory, ReserveSize) \
  153774. + gcmDEFINESECUREUSER() \
  153775. + gctSIZE_T ReserveSize; \
  153776. + gcoCMDBUF CommandBuffer; \
  153777. + gctUINT32_PTR Memory; \
  153778. + gcsSTATE_DELTA_PTR StateDelta
  153779. +
  153780. +#define gcmBEGINSTATEBUFFER(Hardware, CommandBuffer, StateDelta, Memory, ReserveSize) \
  153781. +{ \
  153782. + gcmONERROR(gcoBUFFER_Reserve( \
  153783. + Hardware->buffer, ReserveSize, gcvTRUE, &CommandBuffer \
  153784. + )); \
  153785. + \
  153786. + Memory = gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \
  153787. + \
  153788. + StateDelta = Hardware->delta; \
  153789. + \
  153790. + gcmBEGINSECUREUSER(); \
  153791. +}
  153792. +
  153793. +#define gcmENDSTATEBUFFER(CommandBuffer, Memory, ReserveSize) \
  153794. +{ \
  153795. + gcmENDSECUREUSER(); \
  153796. + \
  153797. + gcmASSERT( \
  153798. + gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT8_PTR) + ReserveSize \
  153799. + == \
  153800. + (gctUINT8_PTR) Memory \
  153801. + ); \
  153802. +}
  153803. +
  153804. +/*----------------------------------------------------------------------------*/
  153805. +
  153806. +#define gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, Count) \
  153807. +{ \
  153808. + gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
  153809. + gcmASSERT((gctUINT32)Count <= 1024); \
  153810. + \
  153811. + gcmVERIFYLOADSTATEDONE(CommandBuffer); \
  153812. + \
  153813. + gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count); \
  153814. + \
  153815. + *Memory++ \
  153816. + = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \
  153817. + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
  153818. + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
  153819. + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
  153820. + \
  153821. + gcmSKIPSECUREUSER(); \
  153822. +}
  153823. +
  153824. +#define gcmENDSTATEBATCH(CommandBuffer, Memory) \
  153825. +{ \
  153826. + gcmVERIFYLOADSTATEDONE(CommandBuffer); \
  153827. + \
  153828. + gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
  153829. +}
  153830. +
  153831. +/*----------------------------------------------------------------------------*/
  153832. +
  153833. +#define gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
  153834. + Address, Data) \
  153835. +{ \
  153836. + gctUINT32 __temp_data32__; \
  153837. + \
  153838. + gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
  153839. + \
  153840. + __temp_data32__ = Data; \
  153841. + \
  153842. + *Memory++ = __temp_data32__; \
  153843. + \
  153844. + gcoHARDWARE_UpdateDelta( \
  153845. + StateDelta, FixedPoint, Address, 0, __temp_data32__ \
  153846. + ); \
  153847. + \
  153848. + gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
  153849. + \
  153850. + gcmUPDATESECUREUSER(); \
  153851. +}
  153852. +
  153853. +#define gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data) \
  153854. +{ \
  153855. + gctUINT32 __temp_data32__; \
  153856. + \
  153857. + gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
  153858. + \
  153859. + __temp_data32__ = Data; \
  153860. + \
  153861. + *Memory++ = __temp_data32__; \
  153862. + \
  153863. + gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
  153864. + \
  153865. + gcmSKIPSECUREUSER(); \
  153866. +}
  153867. +
  153868. +#define gcmSETFILLER(CommandBuffer, Memory) \
  153869. +{ \
  153870. + gcmVERIFYLOADSTATEDONE(CommandBuffer); \
  153871. + \
  153872. + Memory += 1; \
  153873. + \
  153874. + gcmSKIPSECUREUSER(); \
  153875. +}
  153876. +
  153877. +/*----------------------------------------------------------------------------*/
  153878. +
  153879. +#define gcmSETSINGLESTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
  153880. + Address, Data) \
  153881. +{ \
  153882. + gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
  153883. + gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
  153884. + Address, Data); \
  153885. + gcmENDSTATEBATCH(CommandBuffer, Memory); \
  153886. +}
  153887. +
  153888. +#define gcmSETSINGLECTRLSTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
  153889. + Address, Data) \
  153890. +{ \
  153891. + gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
  153892. + gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data); \
  153893. + gcmENDSTATEBATCH(CommandBuffer, Memory); \
  153894. +}
  153895. +
  153896. +
  153897. +/*******************************************************************************
  153898. +**
  153899. +** gcmSETSTARTDECOMMAND
  153900. +**
  153901. +** Form a START_DE command.
  153902. +**
  153903. +** ARGUMENTS:
  153904. +**
  153905. +** Memory Destination memory pointer of gctUINT32_PTR type.
  153906. +** Count Number of the rectangles.
  153907. +*/
  153908. +
  153909. +#define gcmSETSTARTDECOMMAND(Memory, Count) \
  153910. +{ \
  153911. + *Memory++ \
  153912. + = gcmSETFIELDVALUE(0, AQ_COMMAND_START_DE_COMMAND, OPCODE, START_DE) \
  153913. + | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, COUNT, Count) \
  153914. + | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, DATA_COUNT, 0); \
  153915. + \
  153916. + *Memory++ = 0xDEADDEED; \
  153917. +}
  153918. +
  153919. +/******************************************************************************\
  153920. +******************************** Ceiling Macro ********************************
  153921. +\******************************************************************************/
  153922. +#define gcmCEIL(x) ((x - (gctUINT32)x) == 0 ? (gctUINT32)x : (gctUINT32)x + 1)
  153923. +
  153924. +/******************************************************************************\
  153925. +******************************** Min/Max Macros ********************************
  153926. +\******************************************************************************/
  153927. +
  153928. +#define gcmMIN(x, y) (((x) <= (y)) ? (x) : (y))
  153929. +#define gcmMAX(x, y) (((x) >= (y)) ? (x) : (y))
  153930. +#define gcmCLAMP(x, min, max) (((x) < (min)) ? (min) : \
  153931. + ((x) > (max)) ? (max) : (x))
  153932. +#define gcmABS(x) (((x) < 0) ? -(x) : (x))
  153933. +#define gcmNEG(x) (((x) < 0) ? (x) : -(x))
  153934. +
  153935. +/*******************************************************************************
  153936. +**
  153937. +** gcmPTR2INT
  153938. +**
  153939. +** Convert a pointer to an integer value.
  153940. +**
  153941. +** ARGUMENTS:
  153942. +**
  153943. +** p Pointer value.
  153944. +*/
  153945. +#if defined(_WIN32) || (defined(__LP64__) && __LP64__)
  153946. +# define gcmPTR2INT(p) \
  153947. + ( \
  153948. + (gctUINT32) (gctUINT64) (p) \
  153949. + )
  153950. +#else
  153951. +# define gcmPTR2INT(p) \
  153952. + ( \
  153953. + (gctUINT32) (p) \
  153954. + )
  153955. +#endif
  153956. +
  153957. +/*******************************************************************************
  153958. +**
  153959. +** gcmINT2PTR
  153960. +**
  153961. +** Convert an integer value into a pointer.
  153962. +**
  153963. +** ARGUMENTS:
  153964. +**
  153965. +** v Integer value.
  153966. +*/
  153967. +#ifdef __LP64__
  153968. +# define gcmINT2PTR(i) \
  153969. + ( \
  153970. + (gctPOINTER) (gctINT64) (i) \
  153971. + )
  153972. +#else
  153973. +# define gcmINT2PTR(i) \
  153974. + ( \
  153975. + (gctPOINTER) (i) \
  153976. + )
  153977. +#endif
  153978. +
  153979. +/*******************************************************************************
  153980. +**
  153981. +** gcmOFFSETOF
  153982. +**
  153983. +** Compute the byte offset of a field inside a structure.
  153984. +**
  153985. +** ARGUMENTS:
  153986. +**
  153987. +** s Structure name.
  153988. +** field Field name.
  153989. +*/
  153990. +#define gcmOFFSETOF(s, field) \
  153991. +( \
  153992. + gcmPTR2INT(& (((struct s *) 0)->field)) \
  153993. +)
  153994. +
  153995. +#define gcmSWAB32(x) ((gctUINT32)( \
  153996. + (((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \
  153997. + (((gctUINT32)(x) & (gctUINT32)0x0000FF00UL) << 8) | \
  153998. + (((gctUINT32)(x) & (gctUINT32)0x00FF0000UL) >> 8) | \
  153999. + (((gctUINT32)(x) & (gctUINT32)0xFF000000UL) >> 24)))
  154000. +
  154001. +/*******************************************************************************
  154002. +***** Database ****************************************************************/
  154003. +
  154004. +typedef struct _gcsDATABASE_COUNTERS
  154005. +{
  154006. + /* Number of currently allocated bytes. */
  154007. + gctUINT64 bytes;
  154008. +
  154009. + /* Maximum number of bytes allocated (memory footprint). */
  154010. + gctUINT64 maxBytes;
  154011. +
  154012. + /* Total number of bytes allocated. */
  154013. + gctUINT64 totalBytes;
  154014. +}
  154015. +gcsDATABASE_COUNTERS;
  154016. +
  154017. +typedef struct _gcuDATABASE_INFO
  154018. +{
  154019. + /* Counters. */
  154020. + gcsDATABASE_COUNTERS counters;
  154021. +
  154022. + /* Time value. */
  154023. + gctUINT64 time;
  154024. +}
  154025. +gcuDATABASE_INFO;
  154026. +
  154027. +/*******************************************************************************
  154028. +***** Frame database **********************************************************/
  154029. +
  154030. +/* gcsHAL_FRAME_INFO */
  154031. +typedef struct _gcsHAL_FRAME_INFO
  154032. +{
  154033. + /* Current timer tick. */
  154034. + OUT gctUINT64 ticks;
  154035. +
  154036. + /* Bandwidth counters. */
  154037. + OUT gctUINT readBytes8[8];
  154038. + OUT gctUINT writeBytes8[8];
  154039. +
  154040. + /* Counters. */
  154041. + OUT gctUINT cycles[8];
  154042. + OUT gctUINT idleCycles[8];
  154043. + OUT gctUINT mcCycles[8];
  154044. + OUT gctUINT readRequests[8];
  154045. + OUT gctUINT writeRequests[8];
  154046. +
  154047. + /* FE counters. */
  154048. + OUT gctUINT drawCount;
  154049. + OUT gctUINT vertexOutCount;
  154050. + OUT gctUINT vertexMissCount;
  154051. +
  154052. + /* 3D counters. */
  154053. + OUT gctUINT vertexCount;
  154054. + OUT gctUINT primitiveCount;
  154055. + OUT gctUINT rejectedPrimitives;
  154056. + OUT gctUINT culledPrimitives;
  154057. + OUT gctUINT clippedPrimitives;
  154058. + OUT gctUINT droppedPrimitives;
  154059. + OUT gctUINT frustumClippedPrimitives;
  154060. + OUT gctUINT outPrimitives;
  154061. + OUT gctUINT inPrimitives;
  154062. + OUT gctUINT culledQuadCount;
  154063. + OUT gctUINT totalQuadCount;
  154064. + OUT gctUINT quadCount;
  154065. + OUT gctUINT totalPixelCount;
  154066. +
  154067. + /* PE counters. */
  154068. + OUT gctUINT colorKilled[8];
  154069. + OUT gctUINT colorDrawn[8];
  154070. + OUT gctUINT depthKilled[8];
  154071. + OUT gctUINT depthDrawn[8];
  154072. +
  154073. + /* Shader counters. */
  154074. + OUT gctUINT shaderCycles;
  154075. + OUT gctUINT vsInstructionCount;
  154076. + OUT gctUINT vsTextureCount;
  154077. + OUT gctUINT vsBranchCount;
  154078. + OUT gctUINT vsVertices;
  154079. + OUT gctUINT psInstructionCount;
  154080. + OUT gctUINT psTextureCount;
  154081. + OUT gctUINT psBranchCount;
  154082. + OUT gctUINT psPixels;
  154083. +
  154084. + /* Texture counters. */
  154085. + OUT gctUINT bilinearRequests;
  154086. + OUT gctUINT trilinearRequests;
  154087. + OUT gctUINT txBytes8[2];
  154088. + OUT gctUINT txHitCount;
  154089. + OUT gctUINT txMissCount;
  154090. +}
  154091. +gcsHAL_FRAME_INFO;
  154092. +
  154093. +typedef enum _gcePATCH_ID
  154094. +{
  154095. + gcePATCH_UNKNOWN = 0xFFFFFFFF,
  154096. +
  154097. + /* Benchmark list*/
  154098. + gcePATCH_GLB11 = 0x0,
  154099. + gcePATCH_GLB21,
  154100. + gcePATCH_GLB25,
  154101. + gcePATCH_GLB27,
  154102. +
  154103. + gcePATCH_BM21,
  154104. + gcePATCH_MM,
  154105. + gcePATCH_MM06,
  154106. + gcePATCH_MM07,
  154107. + gcePATCH_QUADRANT,
  154108. + gcePATCH_ANTUTU,
  154109. + gcePATCH_SMARTBENCH,
  154110. + gcePATCH_JPCT,
  154111. + gcePATCH_NENAMARK,
  154112. + gcePATCH_NENAMARK2,
  154113. + gcePATCH_NEOCORE,
  154114. + gcePATCH_GLB,
  154115. + gcePATCH_GB,
  154116. + gcePATCH_RTESTVA,
  154117. + gcePATCH_BMX,
  154118. + gcePATCH_BMGUI,
  154119. +
  154120. + /* Game list */
  154121. + gcePATCH_NBA2013,
  154122. + gcePATCH_BARDTALE,
  154123. + gcePATCH_BUSPARKING3D,
  154124. + gcePATCH_FISHBOODLE,
  154125. + gcePATCH_SUBWAYSURFER,
  154126. + gcePATCH_HIGHWAYDRIVER,
  154127. + gcePATCH_PREMIUM,
  154128. + gcePATCH_RACEILLEGAL,
  154129. + gcePATCH_BLABLA,
  154130. + gcePATCH_MEGARUN,
  154131. + gcePATCH_GALAXYONFIRE2,
  154132. + gcePATCH_GLOFTR3HM,
  154133. + gcePATCH_GLOFTSXHM,
  154134. + gcePATCH_GLOFTF3HM,
  154135. + gcePATCH_GLOFTGANG,
  154136. + gcePATCH_XRUNNER,
  154137. + gcePATCH_WP,
  154138. + gcePATCH_DEVIL,
  154139. + gcePATCH_HOLYARCH,
  154140. + gcePATCH_MUSE,
  154141. + gcePATCH_SG,
  154142. + gcePATCH_SIEGECRAFT,
  154143. + gcePATCH_CARCHALLENGE,
  154144. + gcePATCH_HEROESCALL,
  154145. + gcePATCH_MONOPOLY,
  154146. + gcePATCH_CTGL20,
  154147. + gcePATCH_FIREFOX,
  154148. + gcePATCH_CHORME,
  154149. + gcePATCH_DUOKANTV,
  154150. + gcePATCH_TESTAPP,
  154151. + gcePATCH_GOOGLEEARTH,
  154152. +
  154153. + /* Count enum*/
  154154. + gcePATCH_COUNT,
  154155. +}
  154156. +gcePATCH_ID;
  154157. +
  154158. +#if gcdLINK_QUEUE_SIZE
  154159. +typedef struct _gckLINKDATA * gckLINKDATA;
  154160. +struct _gckLINKDATA
  154161. +{
  154162. + gctUINT32 start;
  154163. + gctUINT32 end;
  154164. + gctINT pid;
  154165. +};
  154166. +
  154167. +typedef struct _gckLINKQUEUE * gckLINKQUEUE;
  154168. +struct _gckLINKQUEUE
  154169. +{
  154170. + struct _gckLINKDATA data[gcdLINK_QUEUE_SIZE];
  154171. + gctUINT32 rear;
  154172. + gctUINT32 front;
  154173. + gctUINT32 count;
  154174. +};
  154175. +#endif
  154176. +
  154177. +#ifdef __cplusplus
  154178. +}
  154179. +#endif
  154180. +
  154181. +#endif /* __gc_hal_types_h_ */
  154182. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
  154183. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h 1970-01-01 01:00:00.000000000 +0100
  154184. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h 2014-08-20 19:23:53.570845890 +0200
  154185. @@ -0,0 +1,37 @@
  154186. +/****************************************************************************
  154187. +*
  154188. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  154189. +*
  154190. +* This program is free software; you can redistribute it and/or modify
  154191. +* it under the terms of the GNU General Public License as published by
  154192. +* the Free Software Foundation; either version 2 of the license, or
  154193. +* (at your option) any later version.
  154194. +*
  154195. +* This program is distributed in the hope that it will be useful,
  154196. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  154197. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  154198. +* GNU General Public License for more details.
  154199. +*
  154200. +* You should have received a copy of the GNU General Public License
  154201. +* along with this program; if not write to the Free Software
  154202. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  154203. +*
  154204. +*****************************************************************************/
  154205. +
  154206. +
  154207. +#ifndef __gc_hal_version_h_
  154208. +#define __gc_hal_version_h_
  154209. +
  154210. +#define gcvVERSION_MAJOR 4
  154211. +
  154212. +#define gcvVERSION_MINOR 6
  154213. +
  154214. +#define gcvVERSION_PATCH 9
  154215. +
  154216. +#define gcvVERSION_BUILD 9754
  154217. +
  154218. +#define gcvVERSION_DATE __DATE__
  154219. +
  154220. +#define gcvVERSION_TIME __TIME__
  154221. +
  154222. +#endif /* __gc_hal_version_h_ */
  154223. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
  154224. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h 1970-01-01 01:00:00.000000000 +0100
  154225. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h 2014-08-20 19:23:53.570845890 +0200
  154226. @@ -0,0 +1,913 @@
  154227. +/****************************************************************************
  154228. +*
  154229. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  154230. +*
  154231. +* This program is free software; you can redistribute it and/or modify
  154232. +* it under the terms of the GNU General Public License as published by
  154233. +* the Free Software Foundation; either version 2 of the license, or
  154234. +* (at your option) any later version.
  154235. +*
  154236. +* This program is distributed in the hope that it will be useful,
  154237. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  154238. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  154239. +* GNU General Public License for more details.
  154240. +*
  154241. +* You should have received a copy of the GNU General Public License
  154242. +* along with this program; if not write to the Free Software
  154243. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  154244. +*
  154245. +*****************************************************************************/
  154246. +
  154247. +
  154248. +#ifndef __gc_hal_vg_h_
  154249. +#define __gc_hal_vg_h_
  154250. +
  154251. +#ifdef __cplusplus
  154252. +extern "C" {
  154253. +#endif
  154254. +
  154255. +
  154256. +#include "gc_hal_rename.h"
  154257. +#include "gc_hal_types.h"
  154258. +#include "gc_hal_enum.h"
  154259. +#include "gc_hal_base.h"
  154260. +
  154261. +#if gcdENABLE_VG
  154262. +
  154263. +/* Thread routine type. */
  154264. +#if defined(LINUX)
  154265. + typedef gctINT gctTHREADFUNCRESULT;
  154266. + typedef gctPOINTER gctTHREADFUNCPARAMETER;
  154267. +# define gctTHREADFUNCTYPE
  154268. +#elif defined(WIN32)
  154269. + typedef gctUINT gctTHREADFUNCRESULT;
  154270. + typedef gctPOINTER gctTHREADFUNCPARAMETER;
  154271. +# define gctTHREADFUNCTYPE __stdcall
  154272. +#elif defined(__QNXNTO__)
  154273. + typedef void * gctTHREADFUNCRESULT;
  154274. + typedef gctPOINTER gctTHREADFUNCPARAMETER;
  154275. +# define gctTHREADFUNCTYPE
  154276. +#endif
  154277. +
  154278. +typedef gctTHREADFUNCRESULT (gctTHREADFUNCTYPE * gctTHREADFUNC) (
  154279. + gctTHREADFUNCPARAMETER ThreadParameter
  154280. + );
  154281. +
  154282. +
  154283. +#if defined(gcvDEBUG)
  154284. +# undef gcvDEBUG
  154285. +#endif
  154286. +
  154287. +#define gcdFORCE_DEBUG 0
  154288. +#define gcdFORCE_MESSAGES 0
  154289. +
  154290. +
  154291. +#if DBG || defined(DEBUG) || defined(_DEBUG) || gcdFORCE_DEBUG
  154292. +# define gcvDEBUG 1
  154293. +#else
  154294. +# define gcvDEBUG 0
  154295. +#endif
  154296. +
  154297. +#define _gcmERROR_RETURN(prefix, func) \
  154298. + status = func; \
  154299. + if (gcmIS_ERROR(status)) \
  154300. + { \
  154301. + prefix##PRINT_VERSION(); \
  154302. + prefix##TRACE(gcvLEVEL_ERROR, \
  154303. + #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
  154304. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  154305. + return status; \
  154306. + } \
  154307. + do { } while (gcvFALSE)
  154308. +
  154309. +#define gcmERROR_RETURN(func) _gcmERROR_RETURN(gcm, func)
  154310. +
  154311. +#define gcmLOG_LOCATION()
  154312. +
  154313. +#define gcmkIS_ERROR(status) (status < 0)
  154314. +
  154315. +#define gcmALIGNDOWN(n, align) \
  154316. +( \
  154317. + (n) & ~((align) - 1) \
  154318. +)
  154319. +
  154320. +#define gcmIS_VALID_INDEX(Index, Array) \
  154321. + (((gctUINT) (Index)) < gcmCOUNTOF(Array))
  154322. +
  154323. +
  154324. +#define gcmIS_NAN(x) \
  154325. +( \
  154326. + ((* (gctUINT32_PTR) &(x)) & 0x7FFFFFFF) == 0x7FFFFFFF \
  154327. +)
  154328. +
  154329. +#define gcmLERP(v1, v2, w) \
  154330. + ((v1) * (w) + (v2) * (1.0f - (w)))
  154331. +
  154332. +#define gcmINTERSECT(Start1, Start2, Length) \
  154333. + (gcmABS((Start1) - (Start2)) < (Length))
  154334. +
  154335. +/*******************************************************************************
  154336. +**
  154337. +** gcmERR_GOTO
  154338. +**
  154339. +** Prints a message and terminates the current loop on error.
  154340. +**
  154341. +** ASSUMPTIONS:
  154342. +**
  154343. +** 'status' variable of gceSTATUS type must be defined.
  154344. +**
  154345. +** ARGUMENTS:
  154346. +**
  154347. +** Function
  154348. +** Function to evaluate.
  154349. +*/
  154350. +
  154351. +#define gcmERR_GOTO(Function) \
  154352. + status = Function; \
  154353. + if (gcmIS_ERROR(status)) \
  154354. + { \
  154355. + gcmTRACE( \
  154356. + gcvLEVEL_ERROR, \
  154357. + "gcmERR_GOTO: status=%d @ line=%d in function %s.\n", \
  154358. + status, __LINE__, __FUNCTION__ \
  154359. + ); \
  154360. + goto ErrorHandler; \
  154361. + }
  154362. +
  154363. +#if gcvDEBUG || gcdFORCE_MESSAGES
  154364. +# define gcmVERIFY_BOOLEAN(Expression) \
  154365. + gcmASSERT( \
  154366. + ( (Expression) == gcvFALSE ) || \
  154367. + ( (Expression) == gcvTRUE ) \
  154368. + )
  154369. +#else
  154370. +# define gcmVERIFY_BOOLEAN(Expression)
  154371. +#endif
  154372. +
  154373. +/*******************************************************************************
  154374. +**
  154375. +** gcmVERIFYFIELDFIT
  154376. +**
  154377. +** Verify whether the value fits in the field.
  154378. +**
  154379. +** ARGUMENTS:
  154380. +**
  154381. +** data Data value.
  154382. +** reg Name of register.
  154383. +** field Name of field within register.
  154384. +** value Value for field.
  154385. +*/
  154386. +#define gcmVERIFYFIELDFIT(reg, field, value) \
  154387. + gcmASSERT( \
  154388. + (value) <= gcmFIELDMAX(reg, field) \
  154389. + )
  154390. +/*******************************************************************************
  154391. +**
  154392. +** gcmFIELDMAX
  154393. +**
  154394. +** Get field maximum value.
  154395. +**
  154396. +** ARGUMENTS:
  154397. +**
  154398. +** reg Name of register.
  154399. +** field Name of field within register.
  154400. +*/
  154401. +#define gcmFIELDMAX(reg, field) \
  154402. +( \
  154403. + (gctUINT32) \
  154404. + ( \
  154405. + (__gcmGETSIZE(reg##_##field) == 32) \
  154406. + ? ~0 \
  154407. + : (~(~0 << __gcmGETSIZE(reg##_##field))) \
  154408. + ) \
  154409. +)
  154410. +
  154411. +
  154412. +/* ANSI C does not have the 'f' functions, define replacements here. */
  154413. +#define gcmSINF(x) ((gctFLOAT) sin(x))
  154414. +#define gcmCOSF(x) ((gctFLOAT) cos(x))
  154415. +#define gcmASINF(x) ((gctFLOAT) asin(x))
  154416. +#define gcmACOSF(x) ((gctFLOAT) acos(x))
  154417. +#define gcmSQRTF(x) ((gctFLOAT) sqrt(x))
  154418. +#define gcmFABSF(x) ((gctFLOAT) fabs(x))
  154419. +#define gcmFMODF(x, y) ((gctFLOAT) fmod((x), (y)))
  154420. +#define gcmCEILF(x) ((gctFLOAT) ceil(x))
  154421. +#define gcmFLOORF(x) ((gctFLOAT) floor(x))
  154422. +
  154423. +
  154424. +
  154425. +/* Fixed point constants. */
  154426. +#define gcvZERO_X ((gctFIXED_POINT) 0x00000000)
  154427. +#define gcvHALF_X ((gctFIXED_POINT) 0x00008000)
  154428. +#define gcvONE_X ((gctFIXED_POINT) 0x00010000)
  154429. +#define gcvNEGONE_X ((gctFIXED_POINT) 0xFFFF0000)
  154430. +#define gcvTWO_X ((gctFIXED_POINT) 0x00020000)
  154431. +
  154432. +/* Integer constants. */
  154433. +#define gcvMAX_POS_INT ((gctINT) 0x7FFFFFFF)
  154434. +#define gcvMAX_NEG_INT ((gctINT) 0x80000000)
  154435. +
  154436. +/* Float constants. */
  154437. +#define gcvMAX_POS_FLOAT ((gctFLOAT) 3.4028235e+038)
  154438. +#define gcvMAX_NEG_FLOAT ((gctFLOAT) -3.4028235e+038)
  154439. +
  154440. +/******************************************************************************\
  154441. +***************************** Miscellaneous Macro ******************************
  154442. +\******************************************************************************/
  154443. +
  154444. +#define gcmKB2BYTES(Kilobyte) \
  154445. +( \
  154446. + (Kilobyte) << 10 \
  154447. +)
  154448. +
  154449. +#define gcmMB2BYTES(Megabyte) \
  154450. +( \
  154451. + (Megabyte) << 20 \
  154452. +)
  154453. +
  154454. +#define gcmMAT(Matrix, Row, Column) \
  154455. +( \
  154456. + (Matrix) [(Row) * 3 + (Column)] \
  154457. +)
  154458. +
  154459. +#define gcmMAKE2CHAR(Char1, Char2) \
  154460. +( \
  154461. + ((gctUINT16) (gctUINT8) (Char1) << 0) | \
  154462. + ((gctUINT16) (gctUINT8) (Char2) << 8) \
  154463. +)
  154464. +
  154465. +#define gcmMAKE4CHAR(Char1, Char2, Char3, Char4) \
  154466. +( \
  154467. + ((gctUINT32)(gctUINT8) (Char1) << 0) | \
  154468. + ((gctUINT32)(gctUINT8) (Char2) << 8) | \
  154469. + ((gctUINT32)(gctUINT8) (Char3) << 16) | \
  154470. + ((gctUINT32)(gctUINT8) (Char4) << 24) \
  154471. +)
  154472. +
  154473. +/* some platforms need to fix the physical address for HW to access*/
  154474. +#define gcmFIXADDRESS(address) \
  154475. +(\
  154476. + (address)\
  154477. +)
  154478. +
  154479. +#define gcmkFIXADDRESS(address) \
  154480. +(\
  154481. + (address)\
  154482. +)
  154483. +
  154484. +/******************************************************************************\
  154485. +****************************** Kernel Debug Macro ******************************
  154486. +\******************************************************************************/
  154487. +
  154488. +/* Set signal to signaled state for specified process. */
  154489. +gceSTATUS
  154490. +gckOS_SetSignal(
  154491. + IN gckOS Os,
  154492. + IN gctHANDLE Process,
  154493. + IN gctSIGNAL Signal
  154494. + );
  154495. +
  154496. +/* Return the kernel logical pointer for the given physical one. */
  154497. +gceSTATUS
  154498. +gckOS_GetKernelLogical(
  154499. + IN gckOS Os,
  154500. + IN gctUINT32 Address,
  154501. + OUT gctPOINTER * KernelPointer
  154502. + );
  154503. +
  154504. +/* Return the kernel logical pointer for the given physical one. */
  154505. +gceSTATUS
  154506. +gckOS_GetKernelLogicalEx(
  154507. + IN gckOS Os,
  154508. + IN gceCORE Core,
  154509. + IN gctUINT32 Address,
  154510. + OUT gctPOINTER * KernelPointer
  154511. + );
  154512. +
  154513. +/*----------------------------------------------------------------------------*/
  154514. +/*----------------------------- Semaphore Object -----------------------------*/
  154515. +
  154516. +/* Increment the value of a semaphore. */
  154517. +gceSTATUS
  154518. +gckOS_IncrementSemaphore(
  154519. + IN gckOS Os,
  154520. + IN gctSEMAPHORE Semaphore
  154521. + );
  154522. +
  154523. +/* Decrement the value of a semaphore (waiting might occur). */
  154524. +gceSTATUS
  154525. +gckOS_DecrementSemaphore(
  154526. + IN gckOS Os,
  154527. + IN gctSEMAPHORE Semaphore
  154528. + );
  154529. +
  154530. +
  154531. +/*----------------------------------------------------------------------------*/
  154532. +/*------------------------------- Thread Object ------------------------------*/
  154533. +
  154534. +/* Start a thread. */
  154535. +gceSTATUS
  154536. +gckOS_StartThread(
  154537. + IN gckOS Os,
  154538. + IN gctTHREADFUNC ThreadFunction,
  154539. + IN gctPOINTER ThreadParameter,
  154540. + OUT gctTHREAD * Thread
  154541. + );
  154542. +
  154543. +/* Stop a thread. */
  154544. +gceSTATUS
  154545. +gckOS_StopThread(
  154546. + IN gckOS Os,
  154547. + IN gctTHREAD Thread
  154548. + );
  154549. +
  154550. +/* Verify whether the thread is still running. */
  154551. +gceSTATUS
  154552. +gckOS_VerifyThread(
  154553. + IN gckOS Os,
  154554. + IN gctTHREAD Thread
  154555. + );
  154556. +
  154557. +
  154558. +/* Construct a new gckVGKERNEL object. */
  154559. +gceSTATUS
  154560. +gckVGKERNEL_Construct(
  154561. + IN gckOS Os,
  154562. + IN gctPOINTER Context,
  154563. + IN gckKERNEL inKernel,
  154564. + OUT gckVGKERNEL * Kernel
  154565. + );
  154566. +
  154567. +/* Destroy an gckVGKERNEL object. */
  154568. +gceSTATUS
  154569. +gckVGKERNEL_Destroy(
  154570. + IN gckVGKERNEL Kernel
  154571. + );
  154572. +
  154573. +/* Allocate linear video memory. */
  154574. +gceSTATUS
  154575. +gckKERNEL_AllocateLinearMemory(
  154576. + IN gckKERNEL Kernel,
  154577. + IN OUT gcePOOL * Pool,
  154578. + IN gctSIZE_T Bytes,
  154579. + IN gctSIZE_T Alignment,
  154580. + IN gceSURF_TYPE Type,
  154581. + OUT gcuVIDMEM_NODE_PTR * Node
  154582. + );
  154583. +
  154584. +/* Unmap memory. */
  154585. +gceSTATUS
  154586. +gckKERNEL_UnmapMemory(
  154587. + IN gckKERNEL Kernel,
  154588. + IN gctPHYS_ADDR Physical,
  154589. + IN gctSIZE_T Bytes,
  154590. + IN gctPOINTER Logical
  154591. + );
  154592. +
  154593. +/* Dispatch a user-level command. */
  154594. +gceSTATUS
  154595. +gckVGKERNEL_Dispatch(
  154596. + IN gckKERNEL Kernel,
  154597. + IN gctBOOL FromUser,
  154598. + IN OUT struct _gcsHAL_INTERFACE * Interface
  154599. + );
  154600. +
  154601. +/* Query command buffer requirements. */
  154602. +gceSTATUS
  154603. +gckKERNEL_QueryCommandBuffer(
  154604. + IN gckKERNEL Kernel,
  154605. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  154606. + );
  154607. +
  154608. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY
  154609. +gceSTATUS
  154610. +gckOS_MapReservedMemoryToKernel(
  154611. + IN gckOS Os,
  154612. + IN gctUINT32 Physical,
  154613. + IN gctINT Bytes,
  154614. + IN OUT gctPOINTER *Virtual
  154615. + );
  154616. +
  154617. +gceSTATUS
  154618. +gckOS_UnmapReservedMemoryFromKernel(
  154619. + IN gctPOINTER Virtual
  154620. + );
  154621. +#endif
  154622. +
  154623. +/******************************************************************************\
  154624. +******************************* gckVGHARDWARE Object ******************************
  154625. +\******************************************************************************/
  154626. +
  154627. +/* Construct a new gckVGHARDWARE object. */
  154628. +gceSTATUS
  154629. +gckVGHARDWARE_Construct(
  154630. + IN gckOS Os,
  154631. + OUT gckVGHARDWARE * Hardware
  154632. + );
  154633. +
  154634. +/* Destroy an gckVGHARDWARE object. */
  154635. +gceSTATUS
  154636. +gckVGHARDWARE_Destroy(
  154637. + IN gckVGHARDWARE Hardware
  154638. + );
  154639. +
  154640. +/* Query system memory requirements. */
  154641. +gceSTATUS
  154642. +gckVGHARDWARE_QuerySystemMemory(
  154643. + IN gckVGHARDWARE Hardware,
  154644. + OUT gctSIZE_T * SystemSize,
  154645. + OUT gctUINT32 * SystemBaseAddress
  154646. + );
  154647. +
  154648. +/* Build virtual address. */
  154649. +gceSTATUS
  154650. +gckVGHARDWARE_BuildVirtualAddress(
  154651. + IN gckVGHARDWARE Hardware,
  154652. + IN gctUINT32 Index,
  154653. + IN gctUINT32 Offset,
  154654. + OUT gctUINT32 * Address
  154655. + );
  154656. +
  154657. +/* Kickstart the command processor. */
  154658. +gceSTATUS
  154659. +gckVGHARDWARE_Execute(
  154660. + IN gckVGHARDWARE Hardware,
  154661. + IN gctUINT32 Address,
  154662. + IN gctSIZE_T Count
  154663. + );
  154664. +
  154665. +/* Query the available memory. */
  154666. +gceSTATUS
  154667. +gckVGHARDWARE_QueryMemory(
  154668. + IN gckVGHARDWARE Hardware,
  154669. + OUT gctSIZE_T * InternalSize,
  154670. + OUT gctUINT32 * InternalBaseAddress,
  154671. + OUT gctUINT32 * InternalAlignment,
  154672. + OUT gctSIZE_T * ExternalSize,
  154673. + OUT gctUINT32 * ExternalBaseAddress,
  154674. + OUT gctUINT32 * ExternalAlignment,
  154675. + OUT gctUINT32 * HorizontalTileSize,
  154676. + OUT gctUINT32 * VerticalTileSize
  154677. + );
  154678. +
  154679. +/* Query the identity of the hardware. */
  154680. +gceSTATUS
  154681. +gckVGHARDWARE_QueryChipIdentity(
  154682. + IN gckVGHARDWARE Hardware,
  154683. + OUT gceCHIPMODEL* ChipModel,
  154684. + OUT gctUINT32* ChipRevision,
  154685. + OUT gctUINT32* ChipFeatures,
  154686. + OUT gctUINT32* ChipMinorFeatures,
  154687. + OUT gctUINT32* ChipMinorFeatures1
  154688. + );
  154689. +
  154690. +/* Convert an API format. */
  154691. +gceSTATUS
  154692. +gckVGHARDWARE_ConvertFormat(
  154693. + IN gckVGHARDWARE Hardware,
  154694. + IN gceSURF_FORMAT Format,
  154695. + OUT gctUINT32 * BitsPerPixel,
  154696. + OUT gctUINT32 * BytesPerTile
  154697. + );
  154698. +
  154699. +/* Split a harwdare specific address into API stuff. */
  154700. +gceSTATUS
  154701. +gckVGHARDWARE_SplitMemory(
  154702. + IN gckVGHARDWARE Hardware,
  154703. + IN gctUINT32 Address,
  154704. + OUT gcePOOL * Pool,
  154705. + OUT gctUINT32 * Offset
  154706. + );
  154707. +
  154708. +/* Align size to tile boundary. */
  154709. +gceSTATUS
  154710. +gckVGHARDWARE_AlignToTile(
  154711. + IN gckVGHARDWARE Hardware,
  154712. + IN gceSURF_TYPE Type,
  154713. + IN OUT gctUINT32_PTR Width,
  154714. + IN OUT gctUINT32_PTR Height
  154715. + );
  154716. +
  154717. +/* Convert logical address to hardware specific address. */
  154718. +gceSTATUS
  154719. +gckVGHARDWARE_ConvertLogical(
  154720. + IN gckVGHARDWARE Hardware,
  154721. + IN gctPOINTER Logical,
  154722. + OUT gctUINT32 * Address
  154723. + );
  154724. +
  154725. +/* Program MMU. */
  154726. +gceSTATUS
  154727. +gckVGHARDWARE_SetMMU(
  154728. + IN gckVGHARDWARE Hardware,
  154729. + IN gctPOINTER Logical
  154730. + );
  154731. +
  154732. +/* Flush the MMU. */
  154733. +gceSTATUS
  154734. +gckVGHARDWARE_FlushMMU(
  154735. + IN gckVGHARDWARE Hardware
  154736. + );
  154737. +
  154738. +/* Get idle register. */
  154739. +gceSTATUS
  154740. +gckVGHARDWARE_GetIdle(
  154741. + IN gckVGHARDWARE Hardware,
  154742. + OUT gctUINT32 * Data
  154743. + );
  154744. +
  154745. +/* Flush the caches. */
  154746. +gceSTATUS
  154747. +gckVGHARDWARE_Flush(
  154748. + IN gckVGHARDWARE Hardware,
  154749. + IN gceKERNEL_FLUSH Flush,
  154750. + IN gctPOINTER Logical,
  154751. + IN OUT gctSIZE_T * Bytes
  154752. + );
  154753. +
  154754. +/* Enable/disable fast clear. */
  154755. +gceSTATUS
  154756. +gckVGHARDWARE_SetFastClear(
  154757. + IN gckVGHARDWARE Hardware,
  154758. + IN gctINT Enable
  154759. + );
  154760. +
  154761. +gceSTATUS
  154762. +gckVGHARDWARE_ReadInterrupt(
  154763. + IN gckVGHARDWARE Hardware,
  154764. + OUT gctUINT32_PTR IDs
  154765. + );
  154766. +
  154767. +/* Power management. */
  154768. +gceSTATUS
  154769. +gckVGHARDWARE_SetPowerManagementState(
  154770. + IN gckVGHARDWARE Hardware,
  154771. + IN gceCHIPPOWERSTATE State
  154772. + );
  154773. +
  154774. +gceSTATUS
  154775. +gckVGHARDWARE_QueryPowerManagementState(
  154776. + IN gckVGHARDWARE Hardware,
  154777. + OUT gceCHIPPOWERSTATE* State
  154778. + );
  154779. +
  154780. +gceSTATUS
  154781. +gckVGHARDWARE_SetPowerManagement(
  154782. + IN gckVGHARDWARE Hardware,
  154783. + IN gctBOOL PowerManagement
  154784. + );
  154785. +
  154786. +gceSTATUS
  154787. +gckVGHARDWARE_SetPowerOffTimeout(
  154788. + IN gckVGHARDWARE Hardware,
  154789. + IN gctUINT32 Timeout
  154790. + );
  154791. +
  154792. +gceSTATUS
  154793. +gckVGHARDWARE_QueryPowerOffTimeout(
  154794. + IN gckVGHARDWARE Hardware,
  154795. + OUT gctUINT32* Timeout
  154796. + );
  154797. +
  154798. +gceSTATUS
  154799. +gckVGHARDWARE_QueryIdle(
  154800. + IN gckVGHARDWARE Hardware,
  154801. + OUT gctBOOL_PTR IsIdle
  154802. + );
  154803. +/******************************************************************************\
  154804. +*************************** Command Buffer Structures **************************
  154805. +\******************************************************************************/
  154806. +
  154807. +/* Vacant command buffer marker. */
  154808. +#define gcvVACANT_BUFFER ((gcsCOMPLETION_SIGNAL_PTR) (1))
  154809. +
  154810. +/* Command buffer header. */
  154811. +typedef struct _gcsCMDBUFFER * gcsCMDBUFFER_PTR;
  154812. +typedef struct _gcsCMDBUFFER
  154813. +{
  154814. + /* Pointer to the completion signal. */
  154815. + gcsCOMPLETION_SIGNAL_PTR completion;
  154816. +
  154817. + /* The user sets this to the node of the container buffer whitin which
  154818. + this particular command buffer resides. The kernel sets this to the
  154819. + node of the internally allocated buffer. */
  154820. + gctUINT64 node;
  154821. +
  154822. + /* Command buffer hardware address. */
  154823. + gctUINT32 address;
  154824. +
  154825. + /* The offset of the buffer from the beginning of the header. */
  154826. + gctUINT32 bufferOffset;
  154827. +
  154828. + /* Size of the area allocated for the data portion of this particular
  154829. + command buffer (headers and tail reserves are excluded). */
  154830. + gctSIZE_T size;
  154831. +
  154832. + /* Offset into the buffer [0..size]; reflects exactly how much data has
  154833. + been put into the command buffer. */
  154834. + gctUINT offset;
  154835. +
  154836. + /* The number of command units in the buffer for the hardware to
  154837. + execute. */
  154838. + gctSIZE_T dataCount;
  154839. +
  154840. + /* MANAGED BY : user HAL (gcoBUFFER object).
  154841. + USED BY : user HAL (gcoBUFFER object).
  154842. + Points to the immediate next allocated command buffer. */
  154843. + gcsCMDBUFFER_PTR nextAllocated;
  154844. +
  154845. + /* MANAGED BY : user layers (HAL and drivers).
  154846. + USED BY : kernel HAL (gcoBUFFER object).
  154847. + Points to the next subbuffer if any. A family of subbuffers are chained
  154848. + together and are meant to be executed inseparably as a unit. Meaning
  154849. + that context switching cannot occur while a chain of subbuffers is being
  154850. + executed. */
  154851. + gcsCMDBUFFER_PTR nextSubBuffer;
  154852. +}
  154853. +gcsCMDBUFFER;
  154854. +
  154855. +/* Command queue element. */
  154856. +typedef struct _gcsVGCMDQUEUE
  154857. +{
  154858. + /* Pointer to the command buffer header. */
  154859. + gcsCMDBUFFER_PTR commandBuffer;
  154860. +
  154861. + /* Dynamic vs. static command buffer state. */
  154862. + gctBOOL dynamic;
  154863. +}
  154864. +gcsVGCMDQUEUE;
  154865. +
  154866. +/* Context map entry. */
  154867. +typedef struct _gcsVGCONTEXT_MAP
  154868. +{
  154869. + /* State index. */
  154870. + gctUINT32 index;
  154871. +
  154872. + /* New state value. */
  154873. + gctUINT32 data;
  154874. +
  154875. + /* Points to the next entry in the mod list. */
  154876. + gcsVGCONTEXT_MAP_PTR next;
  154877. +}
  154878. +gcsVGCONTEXT_MAP;
  154879. +
  154880. +/* gcsVGCONTEXT structure that holds the current context. */
  154881. +typedef struct _gcsVGCONTEXT
  154882. +{
  154883. + /* Context ID. */
  154884. + gctUINT64 id;
  154885. +
  154886. + /* State caching ebable flag. */
  154887. + gctBOOL stateCachingEnabled;
  154888. +
  154889. + /* Current pipe. */
  154890. + gctUINT32 currentPipe;
  154891. +
  154892. + /* State map/mod buffer. */
  154893. + gctSIZE_T mapFirst;
  154894. + gctSIZE_T mapLast;
  154895. +#ifdef __QNXNTO__
  154896. + gctSIZE_T mapContainerSize;
  154897. +#endif
  154898. + gcsVGCONTEXT_MAP_PTR mapContainer;
  154899. + gcsVGCONTEXT_MAP_PTR mapPrev;
  154900. + gcsVGCONTEXT_MAP_PTR mapCurr;
  154901. + gcsVGCONTEXT_MAP_PTR firstPrevMap;
  154902. + gcsVGCONTEXT_MAP_PTR firstCurrMap;
  154903. +
  154904. + /* Main context buffer. */
  154905. + gcsCMDBUFFER_PTR header;
  154906. + gctUINT32_PTR buffer;
  154907. +
  154908. + /* Completion signal. */
  154909. + gctHANDLE process;
  154910. + gctSIGNAL signal;
  154911. +
  154912. +#if defined(__QNXNTO__)
  154913. + gctINT32 coid;
  154914. + gctINT32 rcvid;
  154915. +#endif
  154916. +}
  154917. +gcsVGCONTEXT;
  154918. +
  154919. +/* User space task header. */
  154920. +typedef struct _gcsTASK * gcsTASK_PTR;
  154921. +typedef struct _gcsTASK
  154922. +{
  154923. + /* Pointer to the next task for the same interrupt in user space. */
  154924. + gcsTASK_PTR next;
  154925. +
  154926. + /* Size of the task data that immediately follows the structure. */
  154927. + gctUINT size;
  154928. +
  154929. + /* Task data starts here. */
  154930. + /* ... */
  154931. +}
  154932. +gcsTASK;
  154933. +
  154934. +/* User space task master table entry. */
  154935. +typedef struct _gcsTASK_MASTER_ENTRY * gcsTASK_MASTER_ENTRY_PTR;
  154936. +typedef struct _gcsTASK_MASTER_ENTRY
  154937. +{
  154938. + /* Pointers to the head and to the tail of the task chain. */
  154939. + gcsTASK_PTR head;
  154940. + gcsTASK_PTR tail;
  154941. +}
  154942. +gcsTASK_MASTER_ENTRY;
  154943. +
  154944. +/* User space task master table entry. */
  154945. +typedef struct _gcsTASK_MASTER_TABLE
  154946. +{
  154947. + /* Table with one entry per block. */
  154948. + gcsTASK_MASTER_ENTRY table[gcvBLOCK_COUNT];
  154949. +
  154950. + /* The total number of tasks sckeduled. */
  154951. + gctUINT count;
  154952. +
  154953. + /* The total size of event data in bytes. */
  154954. + gctUINT size;
  154955. +
  154956. +#if defined(__QNXNTO__)
  154957. + gctINT32 coid;
  154958. + gctINT32 rcvid;
  154959. +#endif
  154960. +}
  154961. +gcsTASK_MASTER_TABLE;
  154962. +
  154963. +/******************************************************************************\
  154964. +***************************** gckVGINTERRUPT Object ******************************
  154965. +\******************************************************************************/
  154966. +
  154967. +typedef struct _gckVGINTERRUPT * gckVGINTERRUPT;
  154968. +
  154969. +typedef gceSTATUS (* gctINTERRUPT_HANDLER)(
  154970. + IN gckVGKERNEL Kernel
  154971. + );
  154972. +
  154973. +gceSTATUS
  154974. +gckVGINTERRUPT_Construct(
  154975. + IN gckVGKERNEL Kernel,
  154976. + OUT gckVGINTERRUPT * Interrupt
  154977. + );
  154978. +
  154979. +gceSTATUS
  154980. +gckVGINTERRUPT_Destroy(
  154981. + IN gckVGINTERRUPT Interrupt
  154982. + );
  154983. +
  154984. +gceSTATUS
  154985. +gckVGINTERRUPT_Enable(
  154986. + IN gckVGINTERRUPT Interrupt,
  154987. + IN OUT gctINT32_PTR Id,
  154988. + IN gctINTERRUPT_HANDLER Handler
  154989. + );
  154990. +
  154991. +gceSTATUS
  154992. +gckVGINTERRUPT_Disable(
  154993. + IN gckVGINTERRUPT Interrupt,
  154994. + IN gctINT32 Id
  154995. + );
  154996. +
  154997. +#ifndef __QNXNTO__
  154998. +
  154999. +gceSTATUS
  155000. +gckVGINTERRUPT_Enque(
  155001. + IN gckVGINTERRUPT Interrupt
  155002. + );
  155003. +
  155004. +#else
  155005. +
  155006. +gceSTATUS
  155007. +gckVGINTERRUPT_Enque(
  155008. + IN gckVGINTERRUPT Interrupt,
  155009. + OUT gckOS *Os,
  155010. + OUT gctSEMAPHORE *Semaphore
  155011. + );
  155012. +
  155013. +#endif
  155014. +
  155015. +gceSTATUS
  155016. +gckVGINTERRUPT_DumpState(
  155017. + IN gckVGINTERRUPT Interrupt
  155018. + );
  155019. +
  155020. +
  155021. +/******************************************************************************\
  155022. +******************************* gckVGCOMMAND Object *******************************
  155023. +\******************************************************************************/
  155024. +
  155025. +typedef struct _gckVGCOMMAND * gckVGCOMMAND;
  155026. +
  155027. +/* Construct a new gckVGCOMMAND object. */
  155028. +gceSTATUS
  155029. +gckVGCOMMAND_Construct(
  155030. + IN gckVGKERNEL Kernel,
  155031. + IN gctUINT TaskGranularity,
  155032. + IN gctUINT QueueSize,
  155033. + OUT gckVGCOMMAND * Command
  155034. + );
  155035. +
  155036. +/* Destroy an gckVGCOMMAND object. */
  155037. +gceSTATUS
  155038. +gckVGCOMMAND_Destroy(
  155039. + IN gckVGCOMMAND Command
  155040. + );
  155041. +
  155042. +/* Query command buffer attributes. */
  155043. +gceSTATUS
  155044. +gckVGCOMMAND_QueryCommandBuffer(
  155045. + IN gckVGCOMMAND Command,
  155046. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  155047. + );
  155048. +
  155049. +/* Allocate a command queue. */
  155050. +gceSTATUS
  155051. +gckVGCOMMAND_Allocate(
  155052. + IN gckVGCOMMAND Command,
  155053. + IN gctSIZE_T Size,
  155054. + OUT gcsCMDBUFFER_PTR * CommandBuffer,
  155055. + OUT gctPOINTER * Data
  155056. + );
  155057. +
  155058. +/* Release memory held by the command queue. */
  155059. +gceSTATUS
  155060. +gckVGCOMMAND_Free(
  155061. + IN gckVGCOMMAND Command,
  155062. + IN gcsCMDBUFFER_PTR CommandBuffer
  155063. + );
  155064. +
  155065. +/* Schedule the command queue for execution. */
  155066. +gceSTATUS
  155067. +gckVGCOMMAND_Execute(
  155068. + IN gckVGCOMMAND Command,
  155069. + IN gcsCMDBUFFER_PTR CommandBuffer
  155070. + );
  155071. +
  155072. +/* Commit a buffer to the command queue. */
  155073. +gceSTATUS
  155074. +gckVGCOMMAND_Commit(
  155075. + IN gckVGCOMMAND Command,
  155076. + IN gcsVGCONTEXT_PTR Context,
  155077. + IN gcsVGCMDQUEUE_PTR Queue,
  155078. + IN gctUINT EntryCount,
  155079. + IN gcsTASK_MASTER_TABLE_PTR TaskTable
  155080. + );
  155081. +
  155082. +/******************************************************************************\
  155083. +********************************* gckVGMMU Object ********************************
  155084. +\******************************************************************************/
  155085. +
  155086. +typedef struct _gckVGMMU * gckVGMMU;
  155087. +
  155088. +/* Construct a new gckVGMMU object. */
  155089. +gceSTATUS
  155090. +gckVGMMU_Construct(
  155091. + IN gckVGKERNEL Kernel,
  155092. + IN gctSIZE_T MmuSize,
  155093. + OUT gckVGMMU * Mmu
  155094. + );
  155095. +
  155096. +/* Destroy an gckVGMMU object. */
  155097. +gceSTATUS
  155098. +gckVGMMU_Destroy(
  155099. + IN gckVGMMU Mmu
  155100. + );
  155101. +
  155102. +/* Allocate pages inside the MMU. */
  155103. +gceSTATUS
  155104. +gckVGMMU_AllocatePages(
  155105. + IN gckVGMMU Mmu,
  155106. + IN gctSIZE_T PageCount,
  155107. + OUT gctPOINTER * PageTable,
  155108. + OUT gctUINT32 * Address
  155109. + );
  155110. +
  155111. +/* Remove a page table from the MMU. */
  155112. +gceSTATUS
  155113. +gckVGMMU_FreePages(
  155114. + IN gckVGMMU Mmu,
  155115. + IN gctPOINTER PageTable,
  155116. + IN gctSIZE_T PageCount
  155117. + );
  155118. +
  155119. +/* Set the MMU page with info. */
  155120. +gceSTATUS
  155121. +gckVGMMU_SetPage(
  155122. + IN gckVGMMU Mmu,
  155123. + IN gctUINT32 PageAddress,
  155124. + IN gctUINT32 *PageEntry
  155125. + );
  155126. +
  155127. +/* Flush MMU */
  155128. +gceSTATUS
  155129. +gckVGMMU_Flush(
  155130. + IN gckVGMMU Mmu
  155131. + );
  155132. +
  155133. +#endif /* gcdENABLE_VG */
  155134. +
  155135. +#ifdef __cplusplus
  155136. +} /* extern "C" */
  155137. +#endif
  155138. +
  155139. +#endif /* __gc_hal_h_ */
  155140. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
  155141. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c 1970-01-01 01:00:00.000000000 +0100
  155142. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c 2014-08-20 19:23:53.570845890 +0200
  155143. @@ -0,0 +1,795 @@
  155144. +/****************************************************************************
  155145. +*
  155146. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  155147. +*
  155148. +* This program is free software; you can redistribute it and/or modify
  155149. +* it under the terms of the GNU General Public License as published by
  155150. +* the Free Software Foundation; either version 2 of the license, or
  155151. +* (at your option) any later version.
  155152. +*
  155153. +* This program is distributed in the hope that it will be useful,
  155154. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  155155. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  155156. +* GNU General Public License for more details.
  155157. +*
  155158. +* You should have received a copy of the GNU General Public License
  155159. +* along with this program; if not write to the Free Software
  155160. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  155161. +*
  155162. +*****************************************************************************/
  155163. +
  155164. +
  155165. +#ifdef MODULE
  155166. +#include <linux/module.h>
  155167. +#endif
  155168. +#include <linux/init.h>
  155169. +#include <linux/debugfs.h>
  155170. +#include <linux/slab.h>
  155171. +#ifdef MODVERSIONS
  155172. +#include <linux/modversions.h>
  155173. +#endif
  155174. +#include <linux/stddef.h>
  155175. +#include <linux/sched.h>
  155176. +#include <linux/kernel.h>
  155177. +#include <linux/timer.h>
  155178. +#include <linux/delay.h>
  155179. +#include <linux/errno.h>
  155180. +#include <linux/mutex.h>
  155181. +#include <linux/vmalloc.h>
  155182. +#include <linux/types.h>
  155183. +#include <linux/fs.h>
  155184. +#include <linux/poll.h>
  155185. +#include <asm/uaccess.h>
  155186. +#include <linux/completion.h>
  155187. +#include "gc_hal_kernel_linux.h"
  155188. +
  155189. +/*
  155190. + Prequsite:
  155191. +
  155192. + 1) Debugfs feature must be enabled in the kernel.
  155193. + 1.a) You can enable this, in the compilation of the uImage, all you have to do is, In the "make menuconfig" part,
  155194. + you have to enable the debugfs in the kernel hacking part of the menu.
  155195. +
  155196. + HOW TO USE:
  155197. + 1) insert the driver with the following option logFileSize, Ex: insmod galcore.ko ...... logFileSize=10240
  155198. + This gives a circular buffer of 10 MB
  155199. +
  155200. + 2)Usually after inserting the driver, the debug file system is mounted under /sys/kernel/debug/
  155201. +
  155202. + 2.a)If the debugfs is not mounted, you must do "mount -t debugfs none /sys/kernel/debug"
  155203. +
  155204. + 3) To read what is being printed in the debugfs file system:
  155205. + Ex : cat /sys/kernel/debug/gpu/galcore_trace
  155206. +
  155207. + 4)To write into the debug file system from user side :
  155208. + Ex: echo "hello" > cat /sys/kernel/debug/gpu/galcore_trace
  155209. +
  155210. + 5)To write into debugfs from kernel side, Use the function called gckDebugFileSystemPrint
  155211. +
  155212. +
  155213. + USECASE Kernel Dump:
  155214. +
  155215. + 1) Go to /hal/inc/gc_hal_options.h, and enable the following flags:
  155216. + - # define gcdDUMP 1
  155217. + - # define gcdDUMP_IN_KERNEL 1
  155218. + - # define gcdDUMP_COMMAND 1
  155219. +
  155220. + 2) Go to /hal/kernel/gc_hal_kernel_command.c and disable the following flag
  155221. + -#define gcdSIMPLE_COMMAND_DUMP 0
  155222. +
  155223. + 3) Compile the driver
  155224. + 4) insmod it with the logFileSize option
  155225. + 5) Run an application
  155226. + 6) You can get the dump by cat /sys/kernel/debug/gpu/galcore_trace
  155227. +
  155228. + */
  155229. +
  155230. +/**/
  155231. +typedef va_list gctDBGARGS ;
  155232. +#define gcmkARGS_START(argument, pointer) va_start(argument, pointer)
  155233. +#define gcmkARGS_END(argument) va_end(argument)
  155234. +
  155235. +#define gcmkDBGFSPRINT(ArgumentSize, Message) \
  155236. + { \
  155237. + gctDBGARGS __arguments__; \
  155238. + gcmkARGS_START(__arguments__, Message); \
  155239. + _DebugFSPrint(ArgumentSize, Message, __arguments__);\
  155240. + gcmkARGS_END(__arguments__); \
  155241. + }
  155242. +
  155243. +/*Debug File System Node Struct*/
  155244. +struct _gcsDebugFileSystemNode
  155245. +{
  155246. + /*wait queues for read and write operations*/
  155247. +#if defined(DECLARE_WAIT_QUEUE_HEAD)
  155248. + wait_queue_head_t read_q , write_q ;
  155249. +#else
  155250. + struct wait_queue *read_q , *write_q ;
  155251. +#endif
  155252. + struct dentry *parent ; /*parent directory*/
  155253. + struct dentry *filen ; /*filename*/
  155254. + struct semaphore sem ; /* mutual exclusion semaphore */
  155255. + char *data ; /* The circular buffer data */
  155256. + int size ; /* Size of the buffer pointed to by 'data' */
  155257. + int refcount ; /* Files that have this buffer open */
  155258. + int read_point ; /* Offset in circ. buffer of oldest data */
  155259. + int write_point ; /* Offset in circ. buffer of newest data */
  155260. + int offset ; /* Byte number of read_point in the stream */
  155261. + struct _gcsDebugFileSystemNode *next ;
  155262. +} ;
  155263. +
  155264. +/* amount of data in the queue */
  155265. +#define gcmkNODE_QLEN(node) ( (node)->write_point >= (node)->read_point ? \
  155266. + (node)->write_point - (node)->read_point : \
  155267. + (node)->size - (node)->read_point + (node)->write_point)
  155268. +
  155269. +/* byte number of the last byte in the queue */
  155270. +#define gcmkNODE_FIRST_EMPTY_BYTE(node) ((node)->offset + gcmkNODE_QLEN(node))
  155271. +
  155272. +/*Synchronization primitives*/
  155273. +#define gcmkNODE_READQ(node) (&((node)->read_q))
  155274. +#define gcmkNODE_WRITEQ(node) (&((node)->write_q))
  155275. +#define gcmkNODE_SEM(node) (&((node)->sem))
  155276. +
  155277. +/*Utilities*/
  155278. +#define gcmkMIN(x, y) ((x) < (y) ? (x) : y)
  155279. +
  155280. +/*Debug File System Struct*/
  155281. +typedef struct _gcsDebugFileSystem
  155282. +{
  155283. + gcsDebugFileSystemNode* linkedlist ;
  155284. + gcsDebugFileSystemNode* currentNode ;
  155285. + int isInited ;
  155286. +} gcsDebugFileSystem ;
  155287. +
  155288. +
  155289. +/*debug file system*/
  155290. +static gcsDebugFileSystem gc_dbgfs ;
  155291. +
  155292. +
  155293. +
  155294. +/*******************************************************************************
  155295. + **
  155296. + ** READ & WRITE FUNCTIONS (START)
  155297. + **
  155298. + *******************************************************************************/
  155299. +
  155300. +/*******************************************************************************
  155301. + **
  155302. + ** _ReadFromNode
  155303. + **
  155304. + ** 1) reading bytes out of a circular buffer with wraparound.
  155305. + ** 2)returns caddr_t, pointer to data read, which the caller must free.
  155306. + ** 3) length is (a pointer to) the number of bytes to be read, which will be set by this function to
  155307. + ** be the number of bytes actually returned
  155308. + **
  155309. + *******************************************************************************/
  155310. +static caddr_t
  155311. +_ReadFromNode (
  155312. + gcsDebugFileSystemNode* Node ,
  155313. + size_t *Length ,
  155314. + loff_t *Offset
  155315. + )
  155316. +{
  155317. + caddr_t retval ;
  155318. + int bytes_copied = 0 , n , start_point , remaining ;
  155319. +
  155320. + /* is the user trying to read data that has already scrolled off? */
  155321. + if ( *Offset < Node->offset )
  155322. + {
  155323. + *Offset = Node->offset ;
  155324. + }
  155325. +
  155326. + /* is the user trying to read past EOF? */
  155327. + if ( *Offset >= gcmkNODE_FIRST_EMPTY_BYTE ( Node ) )
  155328. + {
  155329. + return NULL ;
  155330. + }
  155331. +
  155332. + /* find the smaller of the total bytes we have available and what
  155333. + * the user is asking for */
  155334. +
  155335. + *Length = gcmkMIN ( *Length , gcmkNODE_FIRST_EMPTY_BYTE ( Node ) - *Offset ) ;
  155336. +
  155337. + remaining = * Length ;
  155338. +
  155339. + /* figure out where to start based on user's Offset */
  155340. + start_point = Node->read_point + ( *Offset - Node->offset ) ;
  155341. +
  155342. + start_point = start_point % Node->size ;
  155343. +
  155344. + /* allocate memory to return */
  155345. + if ( ( retval = kmalloc ( sizeof (char ) * remaining , GFP_KERNEL ) ) == NULL )
  155346. + return NULL ;
  155347. +
  155348. + /* copy the (possibly noncontiguous) data to our buffer */
  155349. + while ( remaining )
  155350. + {
  155351. + n = gcmkMIN ( remaining , Node->size - start_point ) ;
  155352. + memcpy ( retval + bytes_copied , Node->data + start_point , n ) ;
  155353. + bytes_copied += n ;
  155354. + remaining -= n ;
  155355. + start_point = ( start_point + n ) % Node->size ;
  155356. + }
  155357. +
  155358. + /* advance user's file pointer */
  155359. + *Offset += * Length ;
  155360. +
  155361. + return retval ;
  155362. +}
  155363. +
  155364. +/*******************************************************************************
  155365. + **
  155366. + ** _WriteToNode
  155367. + **
  155368. + ** 1) writes to a circular buffer with wraparound.
  155369. + ** 2)in case of an overflow, it overwrites the oldest unread data.
  155370. + **
  155371. + *********************************************************************************/
  155372. +static void
  155373. +_WriteToNode (
  155374. + gcsDebugFileSystemNode* Node ,
  155375. + caddr_t Buf ,
  155376. + int Length
  155377. + )
  155378. +{
  155379. + int bytes_copied = 0 ;
  155380. + int overflow = 0 ;
  155381. + int n ;
  155382. +
  155383. + if ( Length + gcmkNODE_QLEN ( Node ) >= ( Node->size - 1 ) )
  155384. + {
  155385. + overflow = 1 ;
  155386. +
  155387. + /* in case of overflow, figure out where the new buffer will
  155388. + * begin. we start by figuring out where the current buffer ENDS:
  155389. + * node->parent->offset + gcmkNODE_QLEN. we then advance the end-offset
  155390. + * by the Length of the current write, and work backwards to
  155391. + * figure out what the oldest unoverwritten data will be (i.e.,
  155392. + * size of the buffer). */
  155393. + Node->offset = Node->offset + gcmkNODE_QLEN ( Node ) + Length
  155394. + - Node->size + 1 ;
  155395. + }
  155396. +
  155397. + while ( Length )
  155398. + {
  155399. + /* how many contiguous bytes are available from the write point to
  155400. + * the end of the circular buffer? */
  155401. + n = gcmkMIN ( Length , Node->size - Node->write_point ) ;
  155402. + memcpy ( Node->data + Node->write_point , Buf + bytes_copied , n ) ;
  155403. + bytes_copied += n ;
  155404. + Length -= n ;
  155405. + Node->write_point = ( Node->write_point + n ) % Node->size ;
  155406. + }
  155407. +
  155408. + /* if there is an overflow, reset the read point to read whatever is
  155409. + * the oldest data that we have, that has not yet been
  155410. + * overwritten. */
  155411. + if ( overflow )
  155412. + {
  155413. + Node->read_point = ( Node->write_point + 1 ) % Node->size ;
  155414. + }
  155415. +}
  155416. +
  155417. +
  155418. +/*******************************************************************************
  155419. + **
  155420. + ** PRINTING UTILITY (START)
  155421. + **
  155422. + *******************************************************************************/
  155423. +
  155424. +/*******************************************************************************
  155425. + **
  155426. + ** _GetArgumentSize
  155427. + **
  155428. + **
  155429. + *******************************************************************************/
  155430. +static gctINT
  155431. +_GetArgumentSize (
  155432. + IN gctCONST_STRING Message
  155433. + )
  155434. +{
  155435. + gctINT i , count ;
  155436. +
  155437. + for ( i = 0 , count = 0 ; Message[i] ; i += 1 )
  155438. + {
  155439. + if ( Message[i] == '%' )
  155440. + {
  155441. + count += 1 ;
  155442. + }
  155443. + }
  155444. + return count * sizeof (unsigned int ) ;
  155445. +}
  155446. +
  155447. +/*******************************************************************************
  155448. + **
  155449. + ** _AppendString
  155450. + **
  155451. + **
  155452. + *******************************************************************************/
  155453. +static ssize_t
  155454. +_AppendString (
  155455. + IN gcsDebugFileSystemNode* Node ,
  155456. + IN gctCONST_STRING String ,
  155457. + IN int Length
  155458. + )
  155459. +{
  155460. + caddr_t message = NULL ;
  155461. + int n ;
  155462. +
  155463. + /* if the message is longer than the buffer, just take the beginning
  155464. + * of it, in hopes that the reader (if any) will have time to read
  155465. + * before we wrap around and obliterate it */
  155466. + n = gcmkMIN ( Length , Node->size - 1 ) ;
  155467. +
  155468. + /* make sure we have the memory for it */
  155469. + if ( ( message = kmalloc ( n , GFP_KERNEL ) ) == NULL )
  155470. + return - ENOMEM ;
  155471. +
  155472. + /* copy into our temp buffer */
  155473. + memcpy ( message , String , n ) ;
  155474. +
  155475. + /* now copy it into the circular buffer and free our temp copy */
  155476. + _WriteToNode ( Node , message , n ) ;
  155477. + kfree ( message ) ;
  155478. + return n ;
  155479. +}
  155480. +
  155481. +/*******************************************************************************
  155482. + **
  155483. + ** _DebugFSPrint
  155484. + **
  155485. + **
  155486. + *******************************************************************************/
  155487. +static void
  155488. +_DebugFSPrint (
  155489. + IN unsigned int ArgumentSize ,
  155490. + IN const char* Message ,
  155491. + IN gctDBGARGS Arguments
  155492. +
  155493. + )
  155494. +{
  155495. + char buffer[MAX_LINE_SIZE] ;
  155496. + int len ;
  155497. + down ( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ;
  155498. + len = vsnprintf ( buffer , sizeof (buffer ) , Message , *( va_list * ) & Arguments ) ;
  155499. + buffer[len] = '\0' ;
  155500. +
  155501. + /* Add end-of-line if missing. */
  155502. + if ( buffer[len - 1] != '\n' )
  155503. + {
  155504. + buffer[len ++] = '\n' ;
  155505. + buffer[len] = '\0' ;
  155506. + }
  155507. + _AppendString ( gc_dbgfs.currentNode , buffer , len ) ;
  155508. + up ( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ;
  155509. + wake_up_interruptible ( gcmkNODE_READQ ( gc_dbgfs.currentNode ) ) ; /* blocked in read*/
  155510. +}
  155511. +
  155512. +/*******************************************************************************
  155513. + **
  155514. + ** LINUX SYSTEM FUNCTIONS (START)
  155515. + **
  155516. + *******************************************************************************/
  155517. +
  155518. +/*******************************************************************************
  155519. + **
  155520. + ** find the vivlog structure associated with an inode.
  155521. + ** returns a pointer to the structure if found, NULL if not found
  155522. + **
  155523. + *******************************************************************************/
  155524. +static gcsDebugFileSystemNode*
  155525. +_GetNodeInfo (
  155526. + IN struct inode *Inode
  155527. + )
  155528. +{
  155529. + gcsDebugFileSystemNode* node ;
  155530. +
  155531. + if ( Inode == NULL )
  155532. + return NULL ;
  155533. +
  155534. + for ( node = gc_dbgfs.linkedlist ; node != NULL ; node = node->next )
  155535. + if ( node->filen->d_inode->i_ino == Inode->i_ino )
  155536. + return node ;
  155537. +
  155538. + return NULL ;
  155539. +}
  155540. +
  155541. +/*******************************************************************************
  155542. + **
  155543. + ** _DebugFSRead
  155544. + **
  155545. + *******************************************************************************/
  155546. +static ssize_t
  155547. +_DebugFSRead (
  155548. + struct file *file ,
  155549. + char __user * buffer ,
  155550. + size_t length ,
  155551. + loff_t * offset
  155552. + )
  155553. +{
  155554. + int retval ;
  155555. + caddr_t data_to_return ;
  155556. + gcsDebugFileSystemNode* node ;
  155557. + /* get the metadata about this emlog */
  155558. + if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL )
  155559. + {
  155560. + printk ( "debugfs_read: record not found\n" ) ;
  155561. + return - EIO ;
  155562. + }
  155563. +
  155564. + if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
  155565. + {
  155566. + return - ERESTARTSYS ;
  155567. + }
  155568. +
  155569. + /* wait until there's data available (unless we do nonblocking reads) */
  155570. + while ( *offset >= gcmkNODE_FIRST_EMPTY_BYTE ( node ) )
  155571. + {
  155572. + up ( gcmkNODE_SEM ( node ) ) ;
  155573. + if ( file->f_flags & O_NONBLOCK )
  155574. + {
  155575. + return - EAGAIN ;
  155576. + }
  155577. + if ( wait_event_interruptible ( ( *( gcmkNODE_READQ ( node ) ) ) , ( *offset < gcmkNODE_FIRST_EMPTY_BYTE ( node ) ) ) )
  155578. + {
  155579. + return - ERESTARTSYS ; /* signal: tell the fs layer to handle it */
  155580. + }
  155581. + /* otherwise loop, but first reacquire the lock */
  155582. + if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
  155583. + {
  155584. + return - ERESTARTSYS ;
  155585. + }
  155586. + }
  155587. + data_to_return = _ReadFromNode ( node , &length , offset ) ;
  155588. + if ( data_to_return == NULL )
  155589. + {
  155590. + retval = 0 ;
  155591. + goto unlock ;
  155592. + }
  155593. + if ( copy_to_user ( buffer , data_to_return , length ) > 0 )
  155594. + {
  155595. + retval = - EFAULT ;
  155596. + }
  155597. + else
  155598. + {
  155599. + retval = length ;
  155600. + }
  155601. + kfree ( data_to_return ) ;
  155602. +unlock:
  155603. + up ( gcmkNODE_SEM ( node ) ) ;
  155604. + wake_up_interruptible ( gcmkNODE_WRITEQ ( node ) ) ;
  155605. + return retval ;
  155606. +}
  155607. +
  155608. +/*******************************************************************************
  155609. + **
  155610. + **_DebugFSWrite
  155611. + **
  155612. + *******************************************************************************/
  155613. +static ssize_t
  155614. +_DebugFSWrite (
  155615. + struct file *file ,
  155616. + const char __user * buffer ,
  155617. + size_t length ,
  155618. + loff_t * offset
  155619. + )
  155620. +{
  155621. + caddr_t message = NULL ;
  155622. + int n ;
  155623. + gcsDebugFileSystemNode*node ;
  155624. +
  155625. + /* get the metadata about this log */
  155626. + if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL )
  155627. + {
  155628. + return - EIO ;
  155629. + }
  155630. +
  155631. + if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
  155632. + {
  155633. + return - ERESTARTSYS ;
  155634. + }
  155635. +
  155636. + /* if the message is longer than the buffer, just take the beginning
  155637. + * of it, in hopes that the reader (if any) will have time to read
  155638. + * before we wrap around and obliterate it */
  155639. + n = gcmkMIN ( length , node->size - 1 ) ;
  155640. +
  155641. + /* make sure we have the memory for it */
  155642. + if ( ( message = kmalloc ( n , GFP_KERNEL ) ) == NULL )
  155643. + {
  155644. + up ( gcmkNODE_SEM ( node ) ) ;
  155645. + return - ENOMEM ;
  155646. + }
  155647. +
  155648. + /* copy into our temp buffer */
  155649. + if ( copy_from_user ( message , buffer , n ) > 0 )
  155650. + {
  155651. + up ( gcmkNODE_SEM ( node ) ) ;
  155652. + kfree ( message ) ;
  155653. + return - EFAULT ;
  155654. + }
  155655. +
  155656. + /* now copy it into the circular buffer and free our temp copy */
  155657. + _WriteToNode ( node , message , n ) ;
  155658. +
  155659. + kfree ( message ) ;
  155660. + up ( gcmkNODE_SEM ( node ) ) ;
  155661. +
  155662. + /* wake up any readers that might be waiting for the data. we call
  155663. + * schedule in the vague hope that a reader will run before the
  155664. + * writer's next write, to avoid losing data. */
  155665. + wake_up_interruptible ( gcmkNODE_READQ ( node ) ) ;
  155666. +
  155667. + return n ;
  155668. +}
  155669. +
  155670. +/*******************************************************************************
  155671. + **
  155672. + ** File Operations Table
  155673. + **
  155674. + *******************************************************************************/
  155675. +static const struct file_operations debugfs_operations = {
  155676. + .owner = THIS_MODULE ,
  155677. + .read = _DebugFSRead ,
  155678. + .write = _DebugFSWrite ,
  155679. +} ;
  155680. +
  155681. +/*******************************************************************************
  155682. + **
  155683. + ** INTERFACE FUNCTIONS (START)
  155684. + **
  155685. + *******************************************************************************/
  155686. +
  155687. +/*******************************************************************************
  155688. + **
  155689. + ** gckDebugFileSystemIsEnabled
  155690. + **
  155691. + **
  155692. + ** INPUT:
  155693. + **
  155694. + ** OUTPUT:
  155695. + **
  155696. + *******************************************************************************/
  155697. +
  155698. +
  155699. +gctINT
  155700. +gckDebugFileSystemIsEnabled ( void )
  155701. +{
  155702. + return gc_dbgfs.isInited ;
  155703. +}
  155704. +/*******************************************************************************
  155705. + **
  155706. + ** gckDebugFileSystemInitialize
  155707. + **
  155708. + **
  155709. + ** INPUT:
  155710. + **
  155711. + ** OUTPUT:
  155712. + **
  155713. + *******************************************************************************/
  155714. +
  155715. +gctINT
  155716. +gckDebugFileSystemInitialize ( void )
  155717. +{
  155718. + if ( ! gc_dbgfs.isInited )
  155719. + {
  155720. + gc_dbgfs.linkedlist = gcvNULL ;
  155721. + gc_dbgfs.currentNode = gcvNULL ;
  155722. + gc_dbgfs.isInited = 1 ;
  155723. + }
  155724. + return gc_dbgfs.isInited ;
  155725. +}
  155726. +/*******************************************************************************
  155727. + **
  155728. + ** gckDebugFileSystemTerminate
  155729. + **
  155730. + **
  155731. + ** INPUT:
  155732. + **
  155733. + ** OUTPUT:
  155734. + **
  155735. + *******************************************************************************/
  155736. +
  155737. +gctINT
  155738. +gckDebugFileSystemTerminate ( void )
  155739. +{
  155740. + gcsDebugFileSystemNode * next = gcvNULL ;
  155741. + gcsDebugFileSystemNode * temp = gcvNULL ;
  155742. + if ( gc_dbgfs.isInited )
  155743. + {
  155744. + temp = gc_dbgfs.linkedlist ;
  155745. + while ( temp != gcvNULL )
  155746. + {
  155747. + next = temp->next ;
  155748. + gckDebugFileSystemFreeNode ( temp ) ;
  155749. + kfree ( temp ) ;
  155750. + temp = next ;
  155751. + }
  155752. + gc_dbgfs.isInited = 0 ;
  155753. + }
  155754. + return 0 ;
  155755. +}
  155756. +
  155757. +
  155758. +/*******************************************************************************
  155759. + **
  155760. + ** gckDebugFileSystemCreateNode
  155761. + **
  155762. + **
  155763. + ** INPUT:
  155764. + **
  155765. + ** OUTPUT:
  155766. + **
  155767. + ** gckDebugFileSystemFreeNode * Device
  155768. + ** Pointer to a variable receiving the gcsDebugFileSystemNode object pointer on
  155769. + ** success.
  155770. + *********************************************************************************/
  155771. +
  155772. +gctINT
  155773. +gckDebugFileSystemCreateNode (
  155774. + IN gctINT SizeInKB ,
  155775. + IN gctCONST_STRING ParentName ,
  155776. + IN gctCONST_STRING NodeName ,
  155777. + OUT gcsDebugFileSystemNode **Node
  155778. + )
  155779. +{
  155780. + gcsDebugFileSystemNode*node ;
  155781. + /* allocate space for our metadata and initialize it */
  155782. + if ( ( node = kmalloc ( sizeof (gcsDebugFileSystemNode ) , GFP_KERNEL ) ) == NULL )
  155783. + goto struct_malloc_failed ;
  155784. +
  155785. + /*Zero it out*/
  155786. + memset ( node , 0 , sizeof (gcsDebugFileSystemNode ) ) ;
  155787. +
  155788. + /*Init the sync primitives*/
  155789. +#if defined(DECLARE_WAIT_QUEUE_HEAD)
  155790. + init_waitqueue_head ( gcmkNODE_READQ ( node ) ) ;
  155791. +#else
  155792. + init_waitqueue ( gcmkNODE_READQ ( node ) ) ;
  155793. +#endif
  155794. +
  155795. +#if defined(DECLARE_WAIT_QUEUE_HEAD)
  155796. + init_waitqueue_head ( gcmkNODE_WRITEQ ( node ) ) ;
  155797. +#else
  155798. + init_waitqueue ( gcmkNODE_WRITEQ ( node ) ) ;
  155799. +#endif
  155800. + sema_init ( gcmkNODE_SEM ( node ) , 1 ) ;
  155801. + /*End the sync primitives*/
  155802. +
  155803. +
  155804. + /* figure out how much of a buffer this should be and allocate the buffer */
  155805. + node->size = 1024 * SizeInKB ;
  155806. + if ( ( node->data = ( char * ) vmalloc ( sizeof (char ) * node->size ) ) == NULL )
  155807. + goto data_malloc_failed ;
  155808. +
  155809. + /*creating the debug file system*/
  155810. + node->parent = debugfs_create_dir ( ParentName , NULL ) ;
  155811. +
  155812. + /*creating the file*/
  155813. + node->filen = debugfs_create_file ( NodeName , S_IRUGO | S_IWUSR , node->parent , NULL ,
  155814. + &debugfs_operations ) ;
  155815. +
  155816. + /* add it to our linked list */
  155817. + node->next = gc_dbgfs.linkedlist ;
  155818. + gc_dbgfs.linkedlist = node ;
  155819. +
  155820. + /* pass the struct back */
  155821. + *Node = node ;
  155822. + return 0 ;
  155823. +
  155824. + vfree ( node->data ) ;
  155825. +data_malloc_failed:
  155826. + kfree ( node ) ;
  155827. +struct_malloc_failed:
  155828. + return - ENOMEM ;
  155829. +}
  155830. +
  155831. +/*******************************************************************************
  155832. + **
  155833. + ** gckDebugFileSystemFreeNode
  155834. + **
  155835. + **
  155836. + ** INPUT:
  155837. + **
  155838. + ** OUTPUT:
  155839. + **
  155840. + *******************************************************************************/
  155841. +void
  155842. +gckDebugFileSystemFreeNode (
  155843. + IN gcsDebugFileSystemNode * Node
  155844. + )
  155845. +{
  155846. +
  155847. + gcsDebugFileSystemNode **ptr ;
  155848. +
  155849. + if ( Node == NULL )
  155850. + {
  155851. + printk ( "null passed to free_vinfo\n" ) ;
  155852. + return ;
  155853. + }
  155854. +
  155855. + down ( gcmkNODE_SEM ( Node ) ) ;
  155856. + /*free data*/
  155857. + vfree ( Node->data ) ;
  155858. +
  155859. + /*Close Debug fs*/
  155860. + if ( Node->filen )
  155861. + {
  155862. + debugfs_remove ( Node->filen ) ;
  155863. + }
  155864. + if ( Node->parent )
  155865. + {
  155866. + debugfs_remove ( Node->parent ) ;
  155867. + }
  155868. +
  155869. + /* now delete the node from the linked list */
  155870. + ptr = & ( gc_dbgfs.linkedlist ) ;
  155871. + while ( *ptr != Node )
  155872. + {
  155873. + if ( ! *ptr )
  155874. + {
  155875. + printk ( "corrupt info list!\n" ) ;
  155876. + break ;
  155877. + }
  155878. + else
  155879. + ptr = & ( ( **ptr ).next ) ;
  155880. + }
  155881. + *ptr = Node->next ;
  155882. + up ( gcmkNODE_SEM ( Node ) ) ;
  155883. +}
  155884. +
  155885. +/*******************************************************************************
  155886. + **
  155887. + ** gckDebugFileSystemSetCurrentNode
  155888. + **
  155889. + **
  155890. + ** INPUT:
  155891. + **
  155892. + ** OUTPUT:
  155893. + **
  155894. + *******************************************************************************/
  155895. +void
  155896. +gckDebugFileSystemSetCurrentNode (
  155897. + IN gcsDebugFileSystemNode * Node
  155898. + )
  155899. +{
  155900. + gc_dbgfs.currentNode = Node ;
  155901. +}
  155902. +
  155903. +/*******************************************************************************
  155904. + **
  155905. + ** gckDebugFileSystemGetCurrentNode
  155906. + **
  155907. + **
  155908. + ** INPUT:
  155909. + **
  155910. + ** OUTPUT:
  155911. + **
  155912. + *******************************************************************************/
  155913. +void
  155914. +gckDebugFileSystemGetCurrentNode (
  155915. + OUT gcsDebugFileSystemNode ** Node
  155916. + )
  155917. +{
  155918. + *Node = gc_dbgfs.currentNode ;
  155919. +}
  155920. +
  155921. +/*******************************************************************************
  155922. + **
  155923. + ** gckDebugFileSystemPrint
  155924. + **
  155925. + **
  155926. + ** INPUT:
  155927. + **
  155928. + ** OUTPUT:
  155929. + **
  155930. + *******************************************************************************/
  155931. +void
  155932. +gckDebugFileSystemPrint (
  155933. + IN gctCONST_STRING Message ,
  155934. + ...
  155935. + )
  155936. +{
  155937. + gcmkDBGFSPRINT ( _GetArgumentSize ( Message ) , Message ) ;
  155938. +}
  155939. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h
  155940. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h 1970-01-01 01:00:00.000000000 +0100
  155941. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h 2014-08-20 19:23:53.570845890 +0200
  155942. @@ -0,0 +1,84 @@
  155943. +/****************************************************************************
  155944. +*
  155945. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  155946. +*
  155947. +* This program is free software; you can redistribute it and/or modify
  155948. +* it under the terms of the GNU General Public License as published by
  155949. +* the Free Software Foundation; either version 2 of the license, or
  155950. +* (at your option) any later version.
  155951. +*
  155952. +* This program is distributed in the hope that it will be useful,
  155953. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  155954. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  155955. +* GNU General Public License for more details.
  155956. +*
  155957. +* You should have received a copy of the GNU General Public License
  155958. +* along with this program; if not write to the Free Software
  155959. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  155960. +*
  155961. +*****************************************************************************/
  155962. +
  155963. +
  155964. +#include <stdarg.h>
  155965. +
  155966. +#ifndef __gc_hal_kernel_debugfs_h_
  155967. +#define __gc_hal_kernel_debugfs_h_
  155968. +
  155969. + #define MAX_LINE_SIZE 768 /* Max bytes for a line of debug info */
  155970. +
  155971. +
  155972. + typedef struct _gcsDebugFileSystemNode gcsDebugFileSystemNode ;
  155973. +
  155974. +
  155975. +/*******************************************************************************
  155976. + **
  155977. + ** System Related
  155978. + **
  155979. + *******************************************************************************/
  155980. +
  155981. +gctINT gckDebugFileSystemIsEnabled(void);
  155982. +
  155983. +gctINT gckDebugFileSystemInitialize(void);
  155984. +
  155985. +gctINT gckDebugFileSystemTerminate(void);
  155986. +
  155987. +
  155988. +/*******************************************************************************
  155989. + **
  155990. + ** Node Related
  155991. + **
  155992. + *******************************************************************************/
  155993. +
  155994. +gctINT gckDebugFileSystemCreateNode(
  155995. + IN gctINT SizeInKB,
  155996. + IN gctCONST_STRING ParentName ,
  155997. + IN gctCONST_STRING NodeName,
  155998. + OUT gcsDebugFileSystemNode **Node
  155999. + );
  156000. +
  156001. +
  156002. +void gckDebugFileSystemFreeNode(
  156003. + IN gcsDebugFileSystemNode * Node
  156004. + );
  156005. +
  156006. +
  156007. +
  156008. +void gckDebugFileSystemSetCurrentNode(
  156009. + IN gcsDebugFileSystemNode * Node
  156010. + );
  156011. +
  156012. +
  156013. +
  156014. +void gckDebugFileSystemGetCurrentNode(
  156015. + OUT gcsDebugFileSystemNode ** Node
  156016. + );
  156017. +
  156018. +
  156019. +void gckDebugFileSystemPrint(
  156020. + IN gctCONST_STRING Message,
  156021. + ...
  156022. + );
  156023. +
  156024. +#endif
  156025. +
  156026. +
  156027. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
  156028. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h 1970-01-01 01:00:00.000000000 +0100
  156029. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h 2014-08-20 19:23:53.570845890 +0200
  156030. @@ -0,0 +1,102 @@
  156031. +/****************************************************************************
  156032. +*
  156033. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  156034. +*
  156035. +* This program is free software; you can redistribute it and/or modify
  156036. +* it under the terms of the GNU General Public License as published by
  156037. +* the Free Software Foundation; either version 2 of the license, or
  156038. +* (at your option) any later version.
  156039. +*
  156040. +* This program is distributed in the hope that it will be useful,
  156041. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  156042. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  156043. +* GNU General Public License for more details.
  156044. +*
  156045. +* You should have received a copy of the GNU General Public License
  156046. +* along with this program; if not write to the Free Software
  156047. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  156048. +*
  156049. +*****************************************************************************/
  156050. +
  156051. +
  156052. +#ifndef __gc_hal_kernel_debug_h_
  156053. +#define __gc_hal_kernel_debug_h_
  156054. +
  156055. +#include <gc_hal_kernel_linux.h>
  156056. +#include <linux/spinlock.h>
  156057. +#include <linux/time.h>
  156058. +#include <stdarg.h>
  156059. +
  156060. +#ifdef __cplusplus
  156061. +extern "C" {
  156062. +#endif
  156063. +
  156064. +/******************************************************************************\
  156065. +****************************** OS-dependent Macros *****************************
  156066. +\******************************************************************************/
  156067. +
  156068. +typedef va_list gctARGUMENTS;
  156069. +
  156070. +#define gcmkARGUMENTS_START(Arguments, Pointer) \
  156071. + va_start(Arguments, Pointer)
  156072. +
  156073. +#define gcmkARGUMENTS_END(Arguments) \
  156074. + va_end(Arguments)
  156075. +
  156076. +#define gcmkDECLARE_LOCK(__spinLock__) \
  156077. + static DEFINE_SPINLOCK(__spinLock__);
  156078. +
  156079. +#define gcmkLOCKSECTION(__spinLock__) \
  156080. + spin_lock(&__spinLock__)
  156081. +
  156082. +#define gcmkUNLOCKSECTION(__spinLock__) \
  156083. + spin_unlock(&__spinLock__)
  156084. +
  156085. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  156086. +# define gcmkGETPROCESSID() \
  156087. + task_tgid_vnr(current)
  156088. +#else
  156089. +# define gcmkGETPROCESSID() \
  156090. + current->tgid
  156091. +#endif
  156092. +
  156093. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  156094. +# define gcmkGETTHREADID() \
  156095. + task_pid_vnr(current)
  156096. +#else
  156097. +# define gcmkGETTHREADID() \
  156098. + current->pid
  156099. +#endif
  156100. +
  156101. +#define gcmkOUTPUT_STRING(String) \
  156102. + if(gckDebugFileSystemIsEnabled()) \
  156103. + gckDebugFileSystemPrint(String);\
  156104. + else\
  156105. + printk(String); \
  156106. + touch_softlockup_watchdog()
  156107. +
  156108. +
  156109. +#define gcmkSPRINTF(Destination, Size, Message, Value) \
  156110. + snprintf(Destination, Size, Message, Value)
  156111. +
  156112. +#define gcmkSPRINTF2(Destination, Size, Message, Value1, Value2) \
  156113. + snprintf(Destination, Size, Message, Value1, Value2)
  156114. +
  156115. +#define gcmkSPRINTF3(Destination, Size, Message, Value1, Value2, Value3) \
  156116. + snprintf(Destination, Size, Message, Value1, Value2, Value3)
  156117. +
  156118. +#define gcmkVSPRINTF(Destination, Size, Message, Arguments) \
  156119. + vsnprintf(Destination, Size, Message, *(va_list *) &Arguments)
  156120. +
  156121. +#define gcmkSTRCAT(Destination, Size, String) \
  156122. + strncat(Destination, String, Size)
  156123. +
  156124. +/* If not zero, forces data alignment in the variable argument list
  156125. + by its individual size. */
  156126. +#define gcdALIGNBYSIZE 1
  156127. +
  156128. +#ifdef __cplusplus
  156129. +}
  156130. +#endif
  156131. +
  156132. +#endif /* __gc_hal_kernel_debug_h_ */
  156133. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
  156134. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c 1970-01-01 01:00:00.000000000 +0100
  156135. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c 2014-08-20 19:31:46.136869040 +0200
  156136. @@ -0,0 +1,1676 @@
  156137. +/****************************************************************************
  156138. +*
  156139. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  156140. +*
  156141. +* This program is free software; you can redistribute it and/or modify
  156142. +* it under the terms of the GNU General Public License as published by
  156143. +* the Free Software Foundation; either version 2 of the license, or
  156144. +* (at your option) any later version.
  156145. +*
  156146. +* This program is distributed in the hope that it will be useful,
  156147. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  156148. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  156149. +* GNU General Public License for more details.
  156150. +*
  156151. +* You should have received a copy of the GNU General Public License
  156152. +* along with this program; if not write to the Free Software
  156153. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  156154. +*
  156155. +*****************************************************************************/
  156156. +
  156157. +
  156158. +#include "gc_hal_kernel_linux.h"
  156159. +#include <linux/pagemap.h>
  156160. +#include <linux/seq_file.h>
  156161. +#include <linux/mm.h>
  156162. +#include <linux/mman.h>
  156163. +#include <linux/slab.h>
  156164. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
  156165. +#include <mach/hardware.h>
  156166. +#endif
  156167. +#include <linux/pm_runtime.h>
  156168. +
  156169. +#define _GC_OBJ_ZONE gcvZONE_DEVICE
  156170. +
  156171. +#define DEBUG_FILE "galcore_trace"
  156172. +#define PARENT_FILE "gpu"
  156173. +
  156174. +
  156175. +#ifdef FLAREON
  156176. + static struct dove_gpio_irq_handler gc500_handle;
  156177. +#endif
  156178. +
  156179. +#define gcmIS_CORE_PRESENT(Device, Core) (Device->irqLines[Core] > 0)
  156180. +
  156181. +/******************************************************************************\
  156182. +*************************** Memory Allocation Wrappers *************************
  156183. +\******************************************************************************/
  156184. +
  156185. +static gceSTATUS
  156186. +_AllocateMemory(
  156187. + IN gckGALDEVICE Device,
  156188. + IN gctSIZE_T Bytes,
  156189. + OUT gctPOINTER *Logical,
  156190. + OUT gctPHYS_ADDR *Physical,
  156191. + OUT gctUINT32 *PhysAddr
  156192. + )
  156193. +{
  156194. + gceSTATUS status;
  156195. +
  156196. + gcmkHEADER_ARG("Device=0x%x Bytes=%lu", Device, Bytes);
  156197. +
  156198. + gcmkVERIFY_ARGUMENT(Device != NULL);
  156199. + gcmkVERIFY_ARGUMENT(Logical != NULL);
  156200. + gcmkVERIFY_ARGUMENT(Physical != NULL);
  156201. + gcmkVERIFY_ARGUMENT(PhysAddr != NULL);
  156202. +
  156203. + gcmkONERROR(gckOS_AllocateContiguous(
  156204. + Device->os, gcvFALSE, &Bytes, Physical, Logical
  156205. + ));
  156206. +
  156207. + *PhysAddr = ((PLINUX_MDL)*Physical)->dmaHandle - Device->baseAddress;
  156208. +
  156209. + /* Success. */
  156210. + gcmkFOOTER_ARG(
  156211. + "*Logical=0x%x *Physical=0x%x *PhysAddr=0x%08x",
  156212. + *Logical, *Physical, *PhysAddr
  156213. + );
  156214. +
  156215. + return gcvSTATUS_OK;
  156216. +
  156217. +OnError:
  156218. + gcmkFOOTER();
  156219. + return status;
  156220. +}
  156221. +
  156222. +static gceSTATUS
  156223. +_FreeMemory(
  156224. + IN gckGALDEVICE Device,
  156225. + IN gctPOINTER Logical,
  156226. + IN gctPHYS_ADDR Physical)
  156227. +{
  156228. + gceSTATUS status;
  156229. +
  156230. + gcmkHEADER_ARG("Device=0x%x Logical=0x%x Physical=0x%x",
  156231. + Device, Logical, Physical);
  156232. +
  156233. + gcmkVERIFY_ARGUMENT(Device != NULL);
  156234. +
  156235. + status = gckOS_FreeContiguous(
  156236. + Device->os, Physical, Logical,
  156237. + ((PLINUX_MDL) Physical)->numPages * PAGE_SIZE
  156238. + );
  156239. +
  156240. + gcmkFOOTER();
  156241. + return status;
  156242. +}
  156243. +
  156244. +
  156245. +
  156246. +/******************************************************************************\
  156247. +******************************* Interrupt Handler ******************************
  156248. +\******************************************************************************/
  156249. +static irqreturn_t isrRoutine(int irq, void *ctxt)
  156250. +{
  156251. + gceSTATUS status;
  156252. + gckGALDEVICE device;
  156253. +
  156254. + device = (gckGALDEVICE) ctxt;
  156255. +
  156256. + /* Call kernel interrupt notification. */
  156257. + status = gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], gcvNOTIFY_INTERRUPT, gcvTRUE);
  156258. +
  156259. + if (gcmIS_SUCCESS(status))
  156260. + {
  156261. + device->dataReadys[gcvCORE_MAJOR] = gcvTRUE;
  156262. +
  156263. + up(&device->semas[gcvCORE_MAJOR]);
  156264. +
  156265. + return IRQ_HANDLED;
  156266. + }
  156267. +
  156268. + return IRQ_NONE;
  156269. +}
  156270. +
  156271. +static int threadRoutine(void *ctxt)
  156272. +{
  156273. + gckGALDEVICE device = (gckGALDEVICE) ctxt;
  156274. +
  156275. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  156276. + "Starting isr Thread with extension=%p",
  156277. + device);
  156278. +
  156279. + for (;;)
  156280. + {
  156281. + static int down;
  156282. +
  156283. + down = down_interruptible(&device->semas[gcvCORE_MAJOR]);
  156284. + if (down); /*To make gcc 4.6 happye*/
  156285. + device->dataReadys[gcvCORE_MAJOR] = gcvFALSE;
  156286. +
  156287. + if (device->killThread == gcvTRUE)
  156288. + {
  156289. + /* The daemon exits. */
  156290. + while (!kthread_should_stop())
  156291. + {
  156292. + gckOS_Delay(device->os, 1);
  156293. + }
  156294. +
  156295. + return 0;
  156296. + }
  156297. +
  156298. + gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], gcvNOTIFY_INTERRUPT, gcvFALSE);
  156299. + }
  156300. +}
  156301. +
  156302. +static irqreturn_t isrRoutine2D(int irq, void *ctxt)
  156303. +{
  156304. + gceSTATUS status;
  156305. + gckGALDEVICE device;
  156306. +
  156307. + device = (gckGALDEVICE) ctxt;
  156308. +
  156309. + /* Call kernel interrupt notification. */
  156310. + status = gckKERNEL_Notify(device->kernels[gcvCORE_2D], gcvNOTIFY_INTERRUPT, gcvTRUE);
  156311. +
  156312. + if (gcmIS_SUCCESS(status))
  156313. + {
  156314. + device->dataReadys[gcvCORE_2D] = gcvTRUE;
  156315. +
  156316. + up(&device->semas[gcvCORE_2D]);
  156317. +
  156318. + return IRQ_HANDLED;
  156319. + }
  156320. +
  156321. + return IRQ_NONE;
  156322. +}
  156323. +
  156324. +static int threadRoutine2D(void *ctxt)
  156325. +{
  156326. + gckGALDEVICE device = (gckGALDEVICE) ctxt;
  156327. +
  156328. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  156329. + "Starting isr Thread with extension=%p",
  156330. + device);
  156331. +
  156332. + for (;;)
  156333. + {
  156334. + static int down;
  156335. +
  156336. + down = down_interruptible(&device->semas[gcvCORE_2D]);
  156337. + if (down); /*To make gcc 4.6 happye*/
  156338. + device->dataReadys[gcvCORE_2D] = gcvFALSE;
  156339. +
  156340. + if (device->killThread == gcvTRUE)
  156341. + {
  156342. + /* The daemon exits. */
  156343. + while (!kthread_should_stop())
  156344. + {
  156345. + gckOS_Delay(device->os, 1);
  156346. + }
  156347. +
  156348. + return 0;
  156349. + }
  156350. +
  156351. + gckKERNEL_Notify(device->kernels[gcvCORE_2D], gcvNOTIFY_INTERRUPT, gcvFALSE);
  156352. + }
  156353. +}
  156354. +
  156355. +static irqreturn_t isrRoutineVG(int irq, void *ctxt)
  156356. +{
  156357. +#if gcdENABLE_VG
  156358. + gceSTATUS status;
  156359. + gckGALDEVICE device;
  156360. +
  156361. + device = (gckGALDEVICE) ctxt;
  156362. +
  156363. + /* Serve the interrupt. */
  156364. + status = gckVGINTERRUPT_Enque(device->kernels[gcvCORE_VG]->vg->interrupt);
  156365. +
  156366. + /* Determine the return value. */
  156367. + return (status == gcvSTATUS_NOT_OUR_INTERRUPT)
  156368. + ? IRQ_RETVAL(0)
  156369. + : IRQ_RETVAL(1);
  156370. +#else
  156371. + return IRQ_NONE;
  156372. +#endif
  156373. +}
  156374. +
  156375. +static int threadRoutineVG(void *ctxt)
  156376. +{
  156377. + gckGALDEVICE device = (gckGALDEVICE) ctxt;
  156378. +
  156379. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  156380. + "Starting isr Thread with extension=%p",
  156381. + device);
  156382. +
  156383. + for (;;)
  156384. + {
  156385. + static int down;
  156386. +
  156387. + down = down_interruptible(&device->semas[gcvCORE_VG]);
  156388. + if (down); /*To make gcc 4.6 happye*/
  156389. + device->dataReadys[gcvCORE_VG] = gcvFALSE;
  156390. +
  156391. + if (device->killThread == gcvTRUE)
  156392. + {
  156393. + /* The daemon exits. */
  156394. + while (!kthread_should_stop())
  156395. + {
  156396. + gckOS_Delay(device->os, 1);
  156397. + }
  156398. +
  156399. + return 0;
  156400. + }
  156401. +
  156402. + gckKERNEL_Notify(device->kernels[gcvCORE_VG], gcvNOTIFY_INTERRUPT, gcvFALSE);
  156403. + }
  156404. +}
  156405. +
  156406. +/******************************************************************************\
  156407. +******************************* gckGALDEVICE Code ******************************
  156408. +\******************************************************************************/
  156409. +
  156410. +/*******************************************************************************
  156411. +**
  156412. +** gckGALDEVICE_Construct
  156413. +**
  156414. +** Constructor.
  156415. +**
  156416. +** INPUT:
  156417. +**
  156418. +** OUTPUT:
  156419. +**
  156420. +** gckGALDEVICE * Device
  156421. +** Pointer to a variable receiving the gckGALDEVICE object pointer on
  156422. +** success.
  156423. +*/
  156424. +gceSTATUS
  156425. +gckGALDEVICE_Construct(
  156426. + IN gctINT IrqLine,
  156427. + IN gctUINT32 RegisterMemBase,
  156428. + IN gctSIZE_T RegisterMemSize,
  156429. + IN gctINT IrqLine2D,
  156430. + IN gctUINT32 RegisterMemBase2D,
  156431. + IN gctSIZE_T RegisterMemSize2D,
  156432. + IN gctINT IrqLineVG,
  156433. + IN gctUINT32 RegisterMemBaseVG,
  156434. + IN gctSIZE_T RegisterMemSizeVG,
  156435. + IN gctUINT32 ContiguousBase,
  156436. + IN gctSIZE_T ContiguousSize,
  156437. + IN gctSIZE_T BankSize,
  156438. + IN gctINT FastClear,
  156439. + IN gctINT Compression,
  156440. + IN gctUINT32 PhysBaseAddr,
  156441. + IN gctUINT32 PhysSize,
  156442. + IN gctINT Signal,
  156443. + IN gctUINT LogFileSize,
  156444. + IN struct device *pdev,
  156445. + IN gctINT PowerManagement,
  156446. + IN gctINT GpuProfiler,
  156447. + OUT gckGALDEVICE *Device
  156448. + )
  156449. +{
  156450. + gctUINT32 internalBaseAddress = 0, internalAlignment = 0;
  156451. + gctUINT32 externalBaseAddress = 0, externalAlignment = 0;
  156452. + gctUINT32 horizontalTileSize, verticalTileSize;
  156453. + struct resource* mem_region;
  156454. + gctUINT32 physAddr;
  156455. + gctUINT32 physical;
  156456. + gckGALDEVICE device;
  156457. + gceSTATUS status;
  156458. + gctINT32 i;
  156459. + gceHARDWARE_TYPE type;
  156460. + gckDB sharedDB = gcvNULL;
  156461. + gckKERNEL kernel = gcvNULL;
  156462. +
  156463. + gcmkHEADER_ARG("IrqLine=%d RegisterMemBase=0x%08x RegisterMemSize=%u "
  156464. + "IrqLine2D=%d RegisterMemBase2D=0x%08x RegisterMemSize2D=%u "
  156465. + "IrqLineVG=%d RegisterMemBaseVG=0x%08x RegisterMemSizeVG=%u "
  156466. + "ContiguousBase=0x%08x ContiguousSize=%lu BankSize=%lu "
  156467. + "FastClear=%d Compression=%d PhysBaseAddr=0x%x PhysSize=%d Signal=%d",
  156468. + IrqLine, RegisterMemBase, RegisterMemSize,
  156469. + IrqLine2D, RegisterMemBase2D, RegisterMemSize2D,
  156470. + IrqLineVG, RegisterMemBaseVG, RegisterMemSizeVG,
  156471. + ContiguousBase, ContiguousSize, BankSize, FastClear, Compression,
  156472. + PhysBaseAddr, PhysSize, Signal);
  156473. +
  156474. + /* Allocate device structure. */
  156475. + device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL);
  156476. +
  156477. + if (!device)
  156478. + {
  156479. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  156480. + }
  156481. +
  156482. + memset(device, 0, sizeof(struct _gckGALDEVICE));
  156483. +
  156484. + device->dbgnode = gcvNULL;
  156485. + if(LogFileSize != 0)
  156486. + {
  156487. + if(gckDebugFileSystemCreateNode(LogFileSize,PARENT_FILE,DEBUG_FILE,&(device->dbgnode)) != 0)
  156488. + {
  156489. + gcmkTRACE_ZONE(
  156490. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  156491. + "%s(%d): Failed to create the debug file system %s/%s \n",
  156492. + __FUNCTION__, __LINE__,
  156493. + PARENT_FILE, DEBUG_FILE
  156494. + );
  156495. + }
  156496. + else
  156497. + {
  156498. + /*Everything is OK*/
  156499. + gckDebugFileSystemSetCurrentNode(device->dbgnode);
  156500. + }
  156501. + }
  156502. +#ifdef CONFIG_PM
  156503. + /*Init runtime pm for gpu*/
  156504. + pm_runtime_enable(pdev);
  156505. + device->pmdev = pdev;
  156506. +#endif
  156507. +
  156508. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  156509. + /*get gpu regulator*/
  156510. + device->gpu_regulator = regulator_get(pdev, "cpu_vddgpu");
  156511. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  156512. + device->gpu_regulator = devm_regulator_get(pdev, "pu");
  156513. +#endif
  156514. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  156515. + if (IS_ERR(device->gpu_regulator)) {
  156516. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER,
  156517. + "%s(%d): Failed to get gpu regulator %s/%s \n",
  156518. + __FUNCTION__, __LINE__,
  156519. + PARENT_FILE, DEBUG_FILE);
  156520. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  156521. + }
  156522. +#endif
  156523. + /*Initialize the clock structure*/
  156524. + if (IrqLine != -1) {
  156525. + device->clk_3d_core = clk_get(pdev, "gpu3d_clk");
  156526. + if (!IS_ERR(device->clk_3d_core)) {
  156527. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  156528. + if (cpu_is_mx6q()) {
  156529. + device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk");
  156530. + if (IS_ERR(device->clk_3d_shader)) {
  156531. + IrqLine = -1;
  156532. + clk_put(device->clk_3d_core);
  156533. + device->clk_3d_core = NULL;
  156534. + device->clk_3d_shader = NULL;
  156535. + gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
  156536. + }
  156537. + }
  156538. +#else
  156539. + device->clk_3d_axi = clk_get(pdev, "gpu3d_axi_clk");
  156540. + device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk");
  156541. + if (IS_ERR(device->clk_3d_shader)) {
  156542. + IrqLine = -1;
  156543. + clk_put(device->clk_3d_core);
  156544. + device->clk_3d_core = NULL;
  156545. + device->clk_3d_shader = NULL;
  156546. + gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
  156547. + }
  156548. +#endif
  156549. + } else {
  156550. + IrqLine = -1;
  156551. + device->clk_3d_core = NULL;
  156552. + gckOS_Print("galcore: clk_get gpu3d_clk failed, disable 3d!\n");
  156553. + }
  156554. + }
  156555. + if ((IrqLine2D != -1) || (IrqLineVG != -1)) {
  156556. + device->clk_2d_core = clk_get(pdev, "gpu2d_clk");
  156557. + if (IS_ERR(device->clk_2d_core)) {
  156558. + IrqLine2D = -1;
  156559. + IrqLineVG = -1;
  156560. + device->clk_2d_core = NULL;
  156561. + gckOS_Print("galcore: clk_get 2d core clock failed, disable 2d/vg!\n");
  156562. + } else {
  156563. + if (IrqLine2D != -1) {
  156564. + device->clk_2d_axi = clk_get(pdev, "gpu2d_axi_clk");
  156565. + if (IS_ERR(device->clk_2d_axi)) {
  156566. + device->clk_2d_axi = NULL;
  156567. + IrqLine2D = -1;
  156568. + gckOS_Print("galcore: clk_get 2d axi clock failed, disable 2d\n");
  156569. + }
  156570. + }
  156571. + if (IrqLineVG != -1) {
  156572. + device->clk_vg_axi = clk_get(pdev, "openvg_axi_clk");
  156573. + if (IS_ERR(device->clk_vg_axi)) {
  156574. + IrqLineVG = -1;
  156575. + device->clk_vg_axi = NULL;
  156576. + gckOS_Print("galcore: clk_get vg clock failed, disable vg!\n");
  156577. + }
  156578. + }
  156579. + }
  156580. + }
  156581. +
  156582. + if (IrqLine != -1)
  156583. + {
  156584. + device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase;
  156585. + device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize;
  156586. + }
  156587. +
  156588. + if (IrqLine2D != -1)
  156589. + {
  156590. + device->requestedRegisterMemBases[gcvCORE_2D] = RegisterMemBase2D;
  156591. + device->requestedRegisterMemSizes[gcvCORE_2D] = RegisterMemSize2D;
  156592. + }
  156593. +
  156594. + if (IrqLineVG != -1)
  156595. + {
  156596. + device->requestedRegisterMemBases[gcvCORE_VG] = RegisterMemBaseVG;
  156597. + device->requestedRegisterMemSizes[gcvCORE_VG] = RegisterMemSizeVG;
  156598. + }
  156599. +
  156600. + device->requestedContiguousBase = 0;
  156601. + device->requestedContiguousSize = 0;
  156602. +
  156603. +
  156604. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  156605. + {
  156606. + physical = device->requestedRegisterMemBases[i];
  156607. +
  156608. + /* Set up register memory region. */
  156609. + if (physical != 0)
  156610. + {
  156611. + mem_region = request_mem_region(
  156612. + physical, device->requestedRegisterMemSizes[i], "galcore register region"
  156613. + );
  156614. +
  156615. + if (mem_region == gcvNULL)
  156616. + {
  156617. + gcmkTRACE_ZONE(
  156618. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  156619. + "%s(%d): Failed to claim %lu bytes @ 0x%08X\n",
  156620. + __FUNCTION__, __LINE__,
  156621. + physical, device->requestedRegisterMemSizes[i]
  156622. + );
  156623. +
  156624. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  156625. + }
  156626. +
  156627. + device->registerBases[i] = (gctPOINTER) ioremap_nocache(
  156628. + physical, device->requestedRegisterMemSizes[i]);
  156629. +
  156630. + if (device->registerBases[i] == gcvNULL)
  156631. + {
  156632. + gcmkTRACE_ZONE(
  156633. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  156634. + "%s(%d): Unable to map %ld bytes @ 0x%08X\n",
  156635. + __FUNCTION__, __LINE__,
  156636. + physical, device->requestedRegisterMemSizes[i]
  156637. + );
  156638. +
  156639. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  156640. + }
  156641. +
  156642. + physical += device->requestedRegisterMemSizes[i];
  156643. + }
  156644. + else
  156645. + {
  156646. + device->registerBases[i] = gcvNULL;
  156647. + }
  156648. + }
  156649. +
  156650. + /* Set the base address */
  156651. + device->baseAddress = PhysBaseAddr;
  156652. +
  156653. + /* Construct the gckOS object. */
  156654. + gcmkONERROR(gckOS_Construct(device, &device->os));
  156655. +
  156656. + if (IrqLine != -1)
  156657. + {
  156658. + /* Construct the gckKERNEL object. */
  156659. + gcmkONERROR(gckKERNEL_Construct(
  156660. + device->os, gcvCORE_MAJOR, device,
  156661. + gcvNULL, &device->kernels[gcvCORE_MAJOR]));
  156662. +
  156663. + sharedDB = device->kernels[gcvCORE_MAJOR]->db;
  156664. +
  156665. + /* Initialize core mapping */
  156666. + for (i = 0; i < 8; i++)
  156667. + {
  156668. + device->coreMapping[i] = gcvCORE_MAJOR;
  156669. + }
  156670. +
  156671. + /* Setup the ISR manager. */
  156672. + gcmkONERROR(gckHARDWARE_SetIsrManager(
  156673. + device->kernels[gcvCORE_MAJOR]->hardware,
  156674. + (gctISRMANAGERFUNC) gckGALDEVICE_Enable_ISR,
  156675. + (gctISRMANAGERFUNC) gckGALDEVICE_Disable_ISR,
  156676. + device
  156677. + ));
  156678. +
  156679. + gcmkONERROR(gckHARDWARE_SetFastClear(
  156680. + device->kernels[gcvCORE_MAJOR]->hardware, FastClear, Compression
  156681. + ));
  156682. +
  156683. + gcmkONERROR(gckHARDWARE_SetPowerManagement(
  156684. + device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement
  156685. + ));
  156686. +
  156687. + gcmkONERROR(gckHARDWARE_SetGpuProfiler(
  156688. + device->kernels[gcvCORE_MAJOR]->hardware, GpuProfiler
  156689. + ));
  156690. +
  156691. +#if COMMAND_PROCESSOR_VERSION == 1
  156692. + /* Start the command queue. */
  156693. + gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_MAJOR]->command));
  156694. +#endif
  156695. + }
  156696. + else
  156697. + {
  156698. + device->kernels[gcvCORE_MAJOR] = gcvNULL;
  156699. + }
  156700. +
  156701. + if (IrqLine2D != -1)
  156702. + {
  156703. + gcmkONERROR(gckKERNEL_Construct(
  156704. + device->os, gcvCORE_2D, device,
  156705. + sharedDB, &device->kernels[gcvCORE_2D]));
  156706. +
  156707. + if (sharedDB == gcvNULL) sharedDB = device->kernels[gcvCORE_2D]->db;
  156708. +
  156709. + /* Verify the hardware type */
  156710. + gcmkONERROR(gckHARDWARE_GetType(device->kernels[gcvCORE_2D]->hardware, &type));
  156711. +
  156712. + if (type != gcvHARDWARE_2D)
  156713. + {
  156714. + gcmkTRACE_ZONE(
  156715. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  156716. + "%s(%d): Unexpected hardware type: %d\n",
  156717. + __FUNCTION__, __LINE__,
  156718. + type
  156719. + );
  156720. +
  156721. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  156722. + }
  156723. +
  156724. + /* Initialize core mapping */
  156725. + if (device->kernels[gcvCORE_MAJOR] == gcvNULL)
  156726. + {
  156727. + for (i = 0; i < 8; i++)
  156728. + {
  156729. + device->coreMapping[i] = gcvCORE_2D;
  156730. + }
  156731. + }
  156732. + else
  156733. + {
  156734. + device->coreMapping[gcvHARDWARE_2D] = gcvCORE_2D;
  156735. + }
  156736. +
  156737. + /* Setup the ISR manager. */
  156738. + gcmkONERROR(gckHARDWARE_SetIsrManager(
  156739. + device->kernels[gcvCORE_2D]->hardware,
  156740. + (gctISRMANAGERFUNC) gckGALDEVICE_Enable_ISR,
  156741. + (gctISRMANAGERFUNC) gckGALDEVICE_Disable_ISR,
  156742. + device
  156743. + ));
  156744. +
  156745. + gcmkONERROR(gckHARDWARE_SetPowerManagement(
  156746. + device->kernels[gcvCORE_2D]->hardware, PowerManagement
  156747. + ));
  156748. +
  156749. +
  156750. +#if COMMAND_PROCESSOR_VERSION == 1
  156751. + /* Start the command queue. */
  156752. + gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_2D]->command));
  156753. +#endif
  156754. + }
  156755. + else
  156756. + {
  156757. + device->kernels[gcvCORE_2D] = gcvNULL;
  156758. + }
  156759. +
  156760. + if (IrqLineVG != -1)
  156761. + {
  156762. +#if gcdENABLE_VG
  156763. + gcmkONERROR(gckKERNEL_Construct(
  156764. + device->os, gcvCORE_VG, device,
  156765. + sharedDB, &device->kernels[gcvCORE_VG]));
  156766. + /* Initialize core mapping */
  156767. + if (device->kernels[gcvCORE_MAJOR] == gcvNULL
  156768. + && device->kernels[gcvCORE_2D] == gcvNULL
  156769. + )
  156770. + {
  156771. + for (i = 0; i < 8; i++)
  156772. + {
  156773. + device->coreMapping[i] = gcvCORE_VG;
  156774. + }
  156775. + }
  156776. + else
  156777. + {
  156778. + device->coreMapping[gcvHARDWARE_VG] = gcvCORE_VG;
  156779. + }
  156780. +
  156781. +
  156782. + gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
  156783. + device->kernels[gcvCORE_VG]->vg->hardware,
  156784. + PowerManagement
  156785. + ));
  156786. +
  156787. +#endif
  156788. + }
  156789. + else
  156790. + {
  156791. + device->kernels[gcvCORE_VG] = gcvNULL;
  156792. + }
  156793. +
  156794. + /* Initialize the ISR. */
  156795. + device->irqLines[gcvCORE_MAJOR] = IrqLine;
  156796. + device->irqLines[gcvCORE_2D] = IrqLine2D;
  156797. + device->irqLines[gcvCORE_VG] = IrqLineVG;
  156798. +
  156799. + /* Initialize the kernel thread semaphores. */
  156800. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  156801. + {
  156802. + if (device->irqLines[i] != -1) sema_init(&device->semas[i], 0);
  156803. + }
  156804. +
  156805. + device->signal = Signal;
  156806. +
  156807. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  156808. + {
  156809. + if (device->kernels[i] != gcvNULL) break;
  156810. + }
  156811. +
  156812. + if (i == gcdMAX_GPU_COUNT)
  156813. + {
  156814. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  156815. + }
  156816. +
  156817. +#if gcdENABLE_VG
  156818. + if (i == gcvCORE_VG)
  156819. + {
  156820. + /* Query the ceiling of the system memory. */
  156821. + gcmkONERROR(gckVGHARDWARE_QuerySystemMemory(
  156822. + device->kernels[i]->vg->hardware,
  156823. + &device->systemMemorySize,
  156824. + &device->systemMemoryBaseAddress
  156825. + ));
  156826. + /* query the amount of video memory */
  156827. + gcmkONERROR(gckVGHARDWARE_QueryMemory(
  156828. + device->kernels[i]->vg->hardware,
  156829. + &device->internalSize, &internalBaseAddress, &internalAlignment,
  156830. + &device->externalSize, &externalBaseAddress, &externalAlignment,
  156831. + &horizontalTileSize, &verticalTileSize
  156832. + ));
  156833. + }
  156834. + else
  156835. +#endif
  156836. + {
  156837. + /* Query the ceiling of the system memory. */
  156838. + gcmkONERROR(gckHARDWARE_QuerySystemMemory(
  156839. + device->kernels[i]->hardware,
  156840. + &device->systemMemorySize,
  156841. + &device->systemMemoryBaseAddress
  156842. + ));
  156843. +
  156844. + /* query the amount of video memory */
  156845. + gcmkONERROR(gckHARDWARE_QueryMemory(
  156846. + device->kernels[i]->hardware,
  156847. + &device->internalSize, &internalBaseAddress, &internalAlignment,
  156848. + &device->externalSize, &externalBaseAddress, &externalAlignment,
  156849. + &horizontalTileSize, &verticalTileSize
  156850. + ));
  156851. + }
  156852. +
  156853. +
  156854. + /* Grab the first availiable kernel */
  156855. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  156856. + {
  156857. + if (device->irqLines[i] != -1)
  156858. + {
  156859. + kernel = device->kernels[i];
  156860. + break;
  156861. + }
  156862. + }
  156863. +
  156864. + /* Set up the internal memory region. */
  156865. + if (device->internalSize > 0)
  156866. + {
  156867. + status = gckVIDMEM_Construct(
  156868. + device->os,
  156869. + internalBaseAddress, device->internalSize, internalAlignment,
  156870. + 0, &device->internalVidMem
  156871. + );
  156872. +
  156873. + if (gcmIS_ERROR(status))
  156874. + {
  156875. + /* Error, disable internal heap. */
  156876. + device->internalSize = 0;
  156877. + }
  156878. + else
  156879. + {
  156880. + /* Map internal memory. */
  156881. + device->internalLogical
  156882. + = (gctPOINTER) ioremap_nocache(physical, device->internalSize);
  156883. +
  156884. + if (device->internalLogical == gcvNULL)
  156885. + {
  156886. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  156887. + }
  156888. +
  156889. + device->internalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical;
  156890. + device->internalPhysicalName = gcmPTR_TO_NAME(device->internalPhysical);
  156891. + physical += device->internalSize;
  156892. + }
  156893. + }
  156894. +
  156895. + if (device->externalSize > 0)
  156896. + {
  156897. + /* create the external memory heap */
  156898. + status = gckVIDMEM_Construct(
  156899. + device->os,
  156900. + externalBaseAddress, device->externalSize, externalAlignment,
  156901. + 0, &device->externalVidMem
  156902. + );
  156903. +
  156904. + if (gcmIS_ERROR(status))
  156905. + {
  156906. + /* Error, disable internal heap. */
  156907. + device->externalSize = 0;
  156908. + }
  156909. + else
  156910. + {
  156911. + /* Map external memory. */
  156912. + device->externalLogical
  156913. + = (gctPOINTER) ioremap_nocache(physical, device->externalSize);
  156914. +
  156915. + if (device->externalLogical == gcvNULL)
  156916. + {
  156917. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  156918. + }
  156919. +
  156920. + device->externalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical;
  156921. + device->externalPhysicalName = gcmPTR_TO_NAME(device->externalPhysical);
  156922. + physical += device->externalSize;
  156923. + }
  156924. + }
  156925. +
  156926. + /* set up the contiguous memory */
  156927. + device->contiguousSize = ContiguousSize;
  156928. +
  156929. + if (ContiguousSize > 0)
  156930. + {
  156931. + if (ContiguousBase == 0)
  156932. + {
  156933. + while (device->contiguousSize > 0)
  156934. + {
  156935. + /* Allocate contiguous memory. */
  156936. + status = _AllocateMemory(
  156937. + device,
  156938. + device->contiguousSize,
  156939. + &device->contiguousBase,
  156940. + &device->contiguousPhysical,
  156941. + &physAddr
  156942. + );
  156943. +
  156944. + if (gcmIS_SUCCESS(status))
  156945. + {
  156946. + device->contiguousPhysicalName = gcmPTR_TO_NAME(device->contiguousPhysical);
  156947. + status = gckVIDMEM_Construct(
  156948. + device->os,
  156949. + physAddr | device->systemMemoryBaseAddress,
  156950. + device->contiguousSize,
  156951. + 64,
  156952. + BankSize,
  156953. + &device->contiguousVidMem
  156954. + );
  156955. +
  156956. + if (gcmIS_SUCCESS(status))
  156957. + {
  156958. + break;
  156959. + }
  156960. +
  156961. + gcmkONERROR(_FreeMemory(
  156962. + device,
  156963. + device->contiguousBase,
  156964. + device->contiguousPhysical
  156965. + ));
  156966. +
  156967. + gcmRELEASE_NAME(device->contiguousPhysicalName);
  156968. + device->contiguousBase = gcvNULL;
  156969. + device->contiguousPhysical = gcvNULL;
  156970. + }
  156971. +
  156972. + if (device->contiguousSize <= (4 << 20))
  156973. + {
  156974. + device->contiguousSize = 0;
  156975. + }
  156976. + else
  156977. + {
  156978. + device->contiguousSize -= (4 << 20);
  156979. + }
  156980. + }
  156981. + }
  156982. + else
  156983. + {
  156984. + /* Create the contiguous memory heap. */
  156985. + status = gckVIDMEM_Construct(
  156986. + device->os,
  156987. + ContiguousBase | device->systemMemoryBaseAddress,
  156988. + ContiguousSize,
  156989. + 64, BankSize,
  156990. + &device->contiguousVidMem
  156991. + );
  156992. +
  156993. + if (gcmIS_ERROR(status))
  156994. + {
  156995. + /* Error, disable contiguous memory pool. */
  156996. + device->contiguousVidMem = gcvNULL;
  156997. + device->contiguousSize = 0;
  156998. + }
  156999. + else
  157000. + {
  157001. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
  157002. + mem_region = request_mem_region(
  157003. + ContiguousBase, ContiguousSize, "galcore managed memory"
  157004. + );
  157005. +
  157006. + if (mem_region == gcvNULL)
  157007. + {
  157008. + gcmkTRACE_ZONE(
  157009. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  157010. + "%s(%d): Failed to claim %ld bytes @ 0x%08X\n",
  157011. + __FUNCTION__, __LINE__,
  157012. + ContiguousSize, ContiguousBase
  157013. + );
  157014. +
  157015. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  157016. + }
  157017. +#endif
  157018. +
  157019. + device->requestedContiguousBase = ContiguousBase;
  157020. + device->requestedContiguousSize = ContiguousSize;
  157021. +
  157022. +#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  157023. + if (gcmIS_CORE_PRESENT(device, gcvCORE_VG))
  157024. + {
  157025. + device->contiguousBase
  157026. +#if gcdPAGED_MEMORY_CACHEABLE
  157027. + = (gctPOINTER) ioremap_cached(ContiguousBase, ContiguousSize);
  157028. +#else
  157029. + = (gctPOINTER) ioremap_nocache(ContiguousBase, ContiguousSize);
  157030. +#endif
  157031. + if (device->contiguousBase == gcvNULL)
  157032. + {
  157033. + device->contiguousVidMem = gcvNULL;
  157034. + device->contiguousSize = 0;
  157035. +
  157036. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  157037. + }
  157038. + }
  157039. +#endif
  157040. +
  157041. + device->contiguousPhysical = gcvNULL;
  157042. + device->contiguousPhysicalName = 0;
  157043. + device->contiguousSize = ContiguousSize;
  157044. + device->contiguousMapped = gcvTRUE;
  157045. + }
  157046. + }
  157047. + }
  157048. +
  157049. + /* Return pointer to the device. */
  157050. + * Device = device;
  157051. +
  157052. + gcmkFOOTER_ARG("*Device=0x%x", * Device);
  157053. + return gcvSTATUS_OK;
  157054. +
  157055. +OnError:
  157056. + /* Roll back. */
  157057. + gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
  157058. +
  157059. + gcmkFOOTER();
  157060. + return status;
  157061. +}
  157062. +
  157063. +/*******************************************************************************
  157064. +**
  157065. +** gckGALDEVICE_Destroy
  157066. +**
  157067. +** Class destructor.
  157068. +**
  157069. +** INPUT:
  157070. +**
  157071. +** Nothing.
  157072. +**
  157073. +** OUTPUT:
  157074. +**
  157075. +** Nothing.
  157076. +**
  157077. +** RETURNS:
  157078. +**
  157079. +** Nothing.
  157080. +*/
  157081. +gceSTATUS
  157082. +gckGALDEVICE_Destroy(
  157083. + gckGALDEVICE Device)
  157084. +{
  157085. + gctINT i;
  157086. + gceSTATUS status = gcvSTATUS_OK;
  157087. + gckKERNEL kernel = gcvNULL;
  157088. +
  157089. + gcmkHEADER_ARG("Device=0x%x", Device);
  157090. +
  157091. + if (Device != gcvNULL)
  157092. + {
  157093. + /* Grab the first availiable kernel */
  157094. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  157095. + {
  157096. + if (Device->irqLines[i] != -1)
  157097. + {
  157098. + kernel = Device->kernels[i];
  157099. + break;
  157100. + }
  157101. + }
  157102. + if (Device->internalPhysicalName != 0)
  157103. + {
  157104. + gcmRELEASE_NAME(Device->internalPhysicalName);
  157105. + Device->internalPhysicalName = 0;
  157106. + }
  157107. + if (Device->externalPhysicalName != 0)
  157108. + {
  157109. + gcmRELEASE_NAME(Device->externalPhysicalName);
  157110. + Device->externalPhysicalName = 0;
  157111. + }
  157112. + if (Device->contiguousPhysicalName != 0)
  157113. + {
  157114. + gcmRELEASE_NAME(Device->contiguousPhysicalName);
  157115. + Device->contiguousPhysicalName = 0;
  157116. + }
  157117. +
  157118. +
  157119. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  157120. + {
  157121. + if (Device->kernels[i] != gcvNULL)
  157122. + {
  157123. + /* Destroy the gckKERNEL object. */
  157124. + gcmkVERIFY_OK(gckKERNEL_Destroy(Device->kernels[i]));
  157125. + Device->kernels[i] = gcvNULL;
  157126. + }
  157127. + }
  157128. +
  157129. + {
  157130. + if (Device->internalLogical != gcvNULL)
  157131. + {
  157132. + /* Unmap the internal memory. */
  157133. + iounmap(Device->internalLogical);
  157134. + Device->internalLogical = gcvNULL;
  157135. + }
  157136. +
  157137. + if (Device->internalVidMem != gcvNULL)
  157138. + {
  157139. + /* Destroy the internal heap. */
  157140. + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->internalVidMem));
  157141. + Device->internalVidMem = gcvNULL;
  157142. + }
  157143. + }
  157144. +
  157145. + {
  157146. + if (Device->externalLogical != gcvNULL)
  157147. + {
  157148. + /* Unmap the external memory. */
  157149. + iounmap(Device->externalLogical);
  157150. + Device->externalLogical = gcvNULL;
  157151. + }
  157152. +
  157153. + if (Device->externalVidMem != gcvNULL)
  157154. + {
  157155. + /* destroy the external heap */
  157156. + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->externalVidMem));
  157157. + Device->externalVidMem = gcvNULL;
  157158. + }
  157159. + }
  157160. +
  157161. + {
  157162. + if (Device->contiguousBase != gcvNULL)
  157163. + {
  157164. + if (Device->contiguousMapped)
  157165. + {
  157166. +#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  157167. + if (Device->contiguousBase)
  157168. + {
  157169. + /* Unmap the contiguous memory. */
  157170. + iounmap(Device->contiguousBase);
  157171. + }
  157172. +#endif
  157173. + }
  157174. + else
  157175. + {
  157176. + gcmkONERROR(_FreeMemory(
  157177. + Device,
  157178. + Device->contiguousBase,
  157179. + Device->contiguousPhysical
  157180. + ));
  157181. + }
  157182. +
  157183. + Device->contiguousBase = gcvNULL;
  157184. + Device->contiguousPhysical = gcvNULL;
  157185. + }
  157186. +
  157187. + if (Device->requestedContiguousBase != 0)
  157188. + {
  157189. + release_mem_region(Device->requestedContiguousBase, Device->requestedContiguousSize);
  157190. + Device->requestedContiguousBase = 0;
  157191. + Device->requestedContiguousSize = 0;
  157192. + }
  157193. +
  157194. + if (Device->contiguousVidMem != gcvNULL)
  157195. + {
  157196. + /* Destroy the contiguous heap. */
  157197. + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->contiguousVidMem));
  157198. + Device->contiguousVidMem = gcvNULL;
  157199. + }
  157200. + }
  157201. +
  157202. + {
  157203. + if(gckDebugFileSystemIsEnabled())
  157204. + {
  157205. + gckDebugFileSystemFreeNode(Device->dbgnode);
  157206. + kfree(Device->dbgnode);
  157207. + Device->dbgnode = gcvNULL;
  157208. + }
  157209. + }
  157210. +
  157211. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  157212. + {
  157213. + if (Device->registerBases[i] != gcvNULL)
  157214. + {
  157215. + /* Unmap register memory. */
  157216. + iounmap(Device->registerBases[i]);
  157217. + if (Device->requestedRegisterMemBases[i] != 0)
  157218. + {
  157219. + release_mem_region(Device->requestedRegisterMemBases[i], Device->requestedRegisterMemSizes[i]);
  157220. + }
  157221. +
  157222. + Device->registerBases[i] = gcvNULL;
  157223. + Device->requestedRegisterMemBases[i] = 0;
  157224. + Device->requestedRegisterMemSizes[i] = 0;
  157225. + }
  157226. + }
  157227. +
  157228. + /*Disable clock*/
  157229. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  157230. + if (Device->clk_3d_axi) {
  157231. + clk_put(Device->clk_3d_axi);
  157232. + Device->clk_3d_axi = NULL;
  157233. + }
  157234. +#endif
  157235. + if (Device->clk_3d_core) {
  157236. + clk_put(Device->clk_3d_core);
  157237. + Device->clk_3d_core = NULL;
  157238. + }
  157239. + if (Device->clk_3d_shader) {
  157240. + clk_put(Device->clk_3d_shader);
  157241. + Device->clk_3d_shader = NULL;
  157242. + }
  157243. + if (Device->clk_2d_core) {
  157244. + clk_put(Device->clk_2d_core);
  157245. + Device->clk_2d_core = NULL;
  157246. + }
  157247. + if (Device->clk_2d_axi) {
  157248. + clk_put(Device->clk_2d_axi);
  157249. + Device->clk_2d_axi = NULL;
  157250. + }
  157251. + if (Device->clk_vg_axi) {
  157252. + clk_put(Device->clk_vg_axi);
  157253. + Device->clk_vg_axi = NULL;
  157254. + }
  157255. +
  157256. +#ifdef CONFIG_PM
  157257. + if(Device->pmdev)
  157258. + pm_runtime_disable(Device->pmdev);
  157259. +#endif
  157260. +
  157261. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  157262. + if (Device->gpu_regulator) {
  157263. + regulator_put(Device->gpu_regulator);
  157264. + Device->gpu_regulator = NULL;
  157265. + }
  157266. +#endif
  157267. +
  157268. + /* Destroy the gckOS object. */
  157269. + if (Device->os != gcvNULL)
  157270. + {
  157271. + gcmkVERIFY_OK(gckOS_Destroy(Device->os));
  157272. + Device->os = gcvNULL;
  157273. + }
  157274. +
  157275. + /* Free the device. */
  157276. + kfree(Device);
  157277. + }
  157278. +
  157279. + gcmkFOOTER_NO();
  157280. + return gcvSTATUS_OK;
  157281. +
  157282. +OnError:
  157283. + gcmkFOOTER();
  157284. + return status;
  157285. +}
  157286. +
  157287. +/*******************************************************************************
  157288. +**
  157289. +** gckGALDEVICE_Setup_ISR
  157290. +**
  157291. +** Start the ISR routine.
  157292. +**
  157293. +** INPUT:
  157294. +**
  157295. +** gckGALDEVICE Device
  157296. +** Pointer to an gckGALDEVICE object.
  157297. +**
  157298. +** OUTPUT:
  157299. +**
  157300. +** Nothing.
  157301. +**
  157302. +** RETURNS:
  157303. +**
  157304. +** gcvSTATUS_OK
  157305. +** Setup successfully.
  157306. +** gcvSTATUS_GENERIC_IO
  157307. +** Setup failed.
  157308. +*/
  157309. +gceSTATUS
  157310. +gckGALDEVICE_Setup_ISR(
  157311. + IN gckGALDEVICE Device,
  157312. + IN gceCORE Core
  157313. + )
  157314. +{
  157315. + gceSTATUS status;
  157316. + gctINT ret = -1;
  157317. +
  157318. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  157319. +
  157320. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157321. +
  157322. + if (Device->irqLines[Core] < 0)
  157323. + {
  157324. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157325. + }
  157326. +
  157327. + /* Hook up the isr based on the irq line. */
  157328. +#ifdef FLAREON
  157329. + gc500_handle.dev_name = "galcore interrupt service";
  157330. + gc500_handle.dev_id = Device;
  157331. + switch (Core) {
  157332. + case gcvCORE_MAJOR:
  157333. + gc500_handle.handler = isrRoutine;
  157334. + break;
  157335. + case gcvCORE_2D:
  157336. + gc500_handle.handler = isrRoutine2D;
  157337. + break;
  157338. + case gcvCORE_VG:
  157339. + gc500_handle.handler = isrRoutineVG;
  157340. + break;
  157341. + default:
  157342. + break;
  157343. + }
  157344. + gc500_handle.intr_gen = GPIO_INTR_LEVEL_TRIGGER;
  157345. + gc500_handle.intr_trig = GPIO_TRIG_HIGH_LEVEL;
  157346. +
  157347. + ret = dove_gpio_request(
  157348. + DOVE_GPIO0_7, &gc500_handle
  157349. + );
  157350. +#else
  157351. + switch (Core) {
  157352. + case gcvCORE_MAJOR:
  157353. + ret = request_irq(
  157354. + Device->irqLines[Core], isrRoutine, IRQF_DISABLED,
  157355. + "galcore interrupt service", Device
  157356. + );
  157357. + break;
  157358. + case gcvCORE_2D:
  157359. + ret = request_irq(
  157360. + Device->irqLines[Core], isrRoutine2D, IRQF_DISABLED,
  157361. + "galcore 2D interrupt service", Device
  157362. + );
  157363. + break;
  157364. + case gcvCORE_VG:
  157365. + ret = request_irq(
  157366. + Device->irqLines[Core], isrRoutineVG, IRQF_DISABLED,
  157367. + "galcore VG interrupt service", Device
  157368. + );
  157369. + break;
  157370. + default:
  157371. + break;
  157372. + }
  157373. +#endif
  157374. +
  157375. + if (ret != 0)
  157376. + {
  157377. + gcmkTRACE_ZONE(
  157378. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  157379. + "%s(%d): Could not register irq line %d (error=%d)\n",
  157380. + __FUNCTION__, __LINE__,
  157381. + Device->irqLines[Core], ret
  157382. + );
  157383. +
  157384. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157385. + }
  157386. +
  157387. + Device->isrEnabled[Core] = 1;
  157388. +
  157389. + /* Mark ISR as initialized. */
  157390. + Device->isrInitializeds[Core] = gcvTRUE;
  157391. +
  157392. + gcmkFOOTER_NO();
  157393. + return gcvSTATUS_OK;
  157394. +
  157395. +OnError:
  157396. + gcmkFOOTER();
  157397. + return status;
  157398. +}
  157399. +
  157400. +gceSTATUS
  157401. +gckGALDEVICE_Enable_ISR(
  157402. + IN gckGALDEVICE Device,
  157403. + IN gceCORE Core
  157404. + )
  157405. +{
  157406. + gceSTATUS status;
  157407. +
  157408. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  157409. +
  157410. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157411. +
  157412. + if (Device->irqLines[Core] < 0)
  157413. + {
  157414. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157415. + }
  157416. +
  157417. + spin_lock(&Device->kernels[Core]->irq_lock);
  157418. + if (Device->isrEnabled[Core] == 0)
  157419. + {
  157420. + enable_irq(Device->irqLines[Core]);
  157421. + /* Mark ISR as initialized. */
  157422. + Device->isrEnabled[Core] = gcvTRUE;
  157423. + }
  157424. + Device->isrEnabled[Core]++;
  157425. + spin_unlock(&Device->kernels[Core]->irq_lock);
  157426. +
  157427. + gcmkFOOTER_NO();
  157428. + return gcvSTATUS_OK;
  157429. +
  157430. +OnError:
  157431. + gcmkFOOTER();
  157432. + return status;
  157433. +}
  157434. +
  157435. +/*******************************************************************************
  157436. +**
  157437. +** gckGALDEVICE_Release_ISR
  157438. +**
  157439. +** Release the irq line.
  157440. +**
  157441. +** INPUT:
  157442. +**
  157443. +** gckGALDEVICE Device
  157444. +** Pointer to an gckGALDEVICE object.
  157445. +**
  157446. +** OUTPUT:
  157447. +**
  157448. +** Nothing.
  157449. +**
  157450. +** RETURNS:
  157451. +**
  157452. +** Nothing.
  157453. +*/
  157454. +gceSTATUS
  157455. +gckGALDEVICE_Release_ISR(
  157456. + IN gckGALDEVICE Device,
  157457. + IN gceCORE Core
  157458. + )
  157459. +{
  157460. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  157461. +
  157462. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157463. +
  157464. + /* release the irq */
  157465. + if (Device->isrInitializeds[Core])
  157466. + {
  157467. +#ifdef FLAREON
  157468. + dove_gpio_free(DOVE_GPIO0_7, "galcore interrupt service");
  157469. +#else
  157470. + free_irq(Device->irqLines[Core], Device);
  157471. +#endif
  157472. +
  157473. + Device->isrInitializeds[Core] = gcvFALSE;
  157474. + }
  157475. +
  157476. + gcmkFOOTER_NO();
  157477. + return gcvSTATUS_OK;
  157478. +}
  157479. +
  157480. +gceSTATUS
  157481. +gckGALDEVICE_Disable_ISR(
  157482. + IN gckGALDEVICE Device,
  157483. + IN gceCORE Core
  157484. + )
  157485. +{
  157486. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  157487. +
  157488. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157489. +
  157490. + /* disable the irq */
  157491. + spin_lock(&Device->kernels[Core]->irq_lock);
  157492. + if (Device->isrEnabled[Core] > 0)
  157493. + {
  157494. + Device->isrEnabled[Core]--;
  157495. + if (Device->isrEnabled[Core] == 0)
  157496. + disable_irq(Device->irqLines[Core]);
  157497. + }
  157498. + spin_unlock(&Device->kernels[Core]->irq_lock);
  157499. +
  157500. + gcmkFOOTER_NO();
  157501. + return gcvSTATUS_OK;
  157502. +}
  157503. +
  157504. +/*******************************************************************************
  157505. +**
  157506. +** gckGALDEVICE_Start_Threads
  157507. +**
  157508. +** Start the daemon threads.
  157509. +**
  157510. +** INPUT:
  157511. +**
  157512. +** gckGALDEVICE Device
  157513. +** Pointer to an gckGALDEVICE object.
  157514. +**
  157515. +** OUTPUT:
  157516. +**
  157517. +** Nothing.
  157518. +**
  157519. +** RETURNS:
  157520. +**
  157521. +** gcvSTATUS_OK
  157522. +** Start successfully.
  157523. +** gcvSTATUS_GENERIC_IO
  157524. +** Start failed.
  157525. +*/
  157526. +gceSTATUS
  157527. +gckGALDEVICE_Start_Threads(
  157528. + IN gckGALDEVICE Device
  157529. + )
  157530. +{
  157531. + gceSTATUS status;
  157532. + struct task_struct * task;
  157533. +
  157534. + gcmkHEADER_ARG("Device=0x%x", Device);
  157535. +
  157536. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157537. +
  157538. + if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
  157539. + {
  157540. + /* Start the kernel thread. */
  157541. + task = kthread_run(threadRoutine, Device, "galcore daemon thread");
  157542. +
  157543. + if (IS_ERR(task))
  157544. + {
  157545. + gcmkTRACE_ZONE(
  157546. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  157547. + "%s(%d): Could not start the kernel thread.\n",
  157548. + __FUNCTION__, __LINE__
  157549. + );
  157550. +
  157551. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157552. + }
  157553. +
  157554. + Device->threadCtxts[gcvCORE_MAJOR] = task;
  157555. + Device->threadInitializeds[gcvCORE_MAJOR] = gcvTRUE;
  157556. + }
  157557. +
  157558. + if (Device->kernels[gcvCORE_2D] != gcvNULL)
  157559. + {
  157560. + /* Start the kernel thread. */
  157561. + task = kthread_run(threadRoutine2D, Device, "galcore daemon thread for 2D");
  157562. +
  157563. + if (IS_ERR(task))
  157564. + {
  157565. + gcmkTRACE_ZONE(
  157566. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  157567. + "%s(%d): Could not start the kernel thread.\n",
  157568. + __FUNCTION__, __LINE__
  157569. + );
  157570. +
  157571. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157572. + }
  157573. +
  157574. + Device->threadCtxts[gcvCORE_2D] = task;
  157575. + Device->threadInitializeds[gcvCORE_2D] = gcvTRUE;
  157576. + }
  157577. + else
  157578. + {
  157579. + Device->threadInitializeds[gcvCORE_2D] = gcvFALSE;
  157580. + }
  157581. +
  157582. + if (Device->kernels[gcvCORE_VG] != gcvNULL)
  157583. + {
  157584. + /* Start the kernel thread. */
  157585. + task = kthread_run(threadRoutineVG, Device, "galcore daemon thread for VG");
  157586. +
  157587. + if (IS_ERR(task))
  157588. + {
  157589. + gcmkTRACE_ZONE(
  157590. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  157591. + "%s(%d): Could not start the kernel thread.\n",
  157592. + __FUNCTION__, __LINE__
  157593. + );
  157594. +
  157595. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157596. + }
  157597. +
  157598. + Device->threadCtxts[gcvCORE_VG] = task;
  157599. + Device->threadInitializeds[gcvCORE_VG] = gcvTRUE;
  157600. + }
  157601. + else
  157602. + {
  157603. + Device->threadInitializeds[gcvCORE_VG] = gcvFALSE;
  157604. + }
  157605. +
  157606. + gcmkFOOTER_NO();
  157607. + return gcvSTATUS_OK;
  157608. +
  157609. +OnError:
  157610. + gcmkFOOTER();
  157611. + return status;
  157612. +}
  157613. +
  157614. +/*******************************************************************************
  157615. +**
  157616. +** gckGALDEVICE_Stop_Threads
  157617. +**
  157618. +** Stop the gal device, including the following actions: stop the daemon
  157619. +** thread, release the irq.
  157620. +**
  157621. +** INPUT:
  157622. +**
  157623. +** gckGALDEVICE Device
  157624. +** Pointer to an gckGALDEVICE object.
  157625. +**
  157626. +** OUTPUT:
  157627. +**
  157628. +** Nothing.
  157629. +**
  157630. +** RETURNS:
  157631. +**
  157632. +** Nothing.
  157633. +*/
  157634. +gceSTATUS
  157635. +gckGALDEVICE_Stop_Threads(
  157636. + gckGALDEVICE Device
  157637. + )
  157638. +{
  157639. + gctINT i;
  157640. +
  157641. + gcmkHEADER_ARG("Device=0x%x", Device);
  157642. +
  157643. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157644. +
  157645. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  157646. + {
  157647. + /* Stop the kernel threads. */
  157648. + if (Device->threadInitializeds[i])
  157649. + {
  157650. + Device->killThread = gcvTRUE;
  157651. + up(&Device->semas[i]);
  157652. +
  157653. + kthread_stop(Device->threadCtxts[i]);
  157654. + Device->threadCtxts[i] = gcvNULL;
  157655. + Device->threadInitializeds[i] = gcvFALSE;
  157656. + }
  157657. + }
  157658. +
  157659. + gcmkFOOTER_NO();
  157660. + return gcvSTATUS_OK;
  157661. +}
  157662. +
  157663. +/*******************************************************************************
  157664. +**
  157665. +** gckGALDEVICE_Start
  157666. +**
  157667. +** Start the gal device, including the following actions: setup the isr routine
  157668. +** and start the daemoni thread.
  157669. +**
  157670. +** INPUT:
  157671. +**
  157672. +** gckGALDEVICE Device
  157673. +** Pointer to an gckGALDEVICE object.
  157674. +**
  157675. +** OUTPUT:
  157676. +**
  157677. +** Nothing.
  157678. +**
  157679. +** RETURNS:
  157680. +**
  157681. +** gcvSTATUS_OK
  157682. +** Start successfully.
  157683. +*/
  157684. +gceSTATUS
  157685. +gckGALDEVICE_Start(
  157686. + IN gckGALDEVICE Device
  157687. + )
  157688. +{
  157689. + gceSTATUS status;
  157690. +
  157691. + gcmkHEADER_ARG("Device=0x%x", Device);
  157692. +
  157693. + /* Start the kernel thread. */
  157694. + gcmkONERROR(gckGALDEVICE_Start_Threads(Device));
  157695. +
  157696. + if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
  157697. + {
  157698. + /* Setup the ISR routine. */
  157699. + gcmkONERROR(gckGALDEVICE_Setup_ISR(Device, gcvCORE_MAJOR));
  157700. +
  157701. + /* Switch to SUSPEND power state. */
  157702. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  157703. + Device->kernels[gcvCORE_MAJOR]->hardware, gcvPOWER_OFF_BROADCAST
  157704. + ));
  157705. + }
  157706. +
  157707. + if (Device->kernels[gcvCORE_2D] != gcvNULL)
  157708. + {
  157709. + /* Setup the ISR routine. */
  157710. + gcmkONERROR(gckGALDEVICE_Setup_ISR(Device, gcvCORE_2D));
  157711. +
  157712. + /* Switch to SUSPEND power state. */
  157713. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  157714. + Device->kernels[gcvCORE_2D]->hardware, gcvPOWER_OFF_BROADCAST
  157715. + ));
  157716. + }
  157717. +
  157718. + if (Device->kernels[gcvCORE_VG] != gcvNULL)
  157719. + {
  157720. + /* Setup the ISR routine. */
  157721. + gcmkONERROR(gckGALDEVICE_Setup_ISR(Device, gcvCORE_VG));
  157722. +
  157723. + /* Switch to SUSPEND power state. */
  157724. + gcmkONERROR(gckVGHARDWARE_SetPowerManagementState(
  157725. + Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF_BROADCAST
  157726. + ));
  157727. + }
  157728. +
  157729. + gcmkFOOTER_NO();
  157730. + return gcvSTATUS_OK;
  157731. +
  157732. +OnError:
  157733. + gcmkFOOTER();
  157734. + return status;
  157735. +}
  157736. +
  157737. +/*******************************************************************************
  157738. +**
  157739. +** gckGALDEVICE_Stop
  157740. +**
  157741. +** Stop the gal device, including the following actions: stop the daemon
  157742. +** thread, release the irq.
  157743. +**
  157744. +** INPUT:
  157745. +**
  157746. +** gckGALDEVICE Device
  157747. +** Pointer to an gckGALDEVICE object.
  157748. +**
  157749. +** OUTPUT:
  157750. +**
  157751. +** Nothing.
  157752. +**
  157753. +** RETURNS:
  157754. +**
  157755. +** Nothing.
  157756. +*/
  157757. +gceSTATUS
  157758. +gckGALDEVICE_Stop(
  157759. + gckGALDEVICE Device
  157760. + )
  157761. +{
  157762. + gceSTATUS status;
  157763. +
  157764. + gcmkHEADER_ARG("Device=0x%x", Device);
  157765. +
  157766. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157767. +
  157768. + if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
  157769. + {
  157770. + /* Switch to OFF power state. */
  157771. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  157772. + Device->kernels[gcvCORE_MAJOR]->hardware, gcvPOWER_OFF
  157773. + ));
  157774. +
  157775. + /* Remove the ISR routine. */
  157776. + gcmkONERROR(gckGALDEVICE_Release_ISR(Device, gcvCORE_MAJOR));
  157777. + }
  157778. +
  157779. + if (Device->kernels[gcvCORE_2D] != gcvNULL)
  157780. + {
  157781. + /* Setup the ISR routine. */
  157782. + gcmkONERROR(gckGALDEVICE_Release_ISR(Device, gcvCORE_2D));
  157783. +
  157784. + /* Switch to OFF power state. */
  157785. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  157786. + Device->kernels[gcvCORE_2D]->hardware, gcvPOWER_OFF
  157787. + ));
  157788. + }
  157789. +
  157790. + if (Device->kernels[gcvCORE_VG] != gcvNULL)
  157791. + {
  157792. + /* Setup the ISR routine. */
  157793. + gcmkONERROR(gckGALDEVICE_Release_ISR(Device, gcvCORE_VG));
  157794. +
  157795. +#if gcdENABLE_VG
  157796. + /* Switch to OFF power state. */
  157797. + gcmkONERROR(gckVGHARDWARE_SetPowerManagementState(
  157798. + Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF
  157799. + ));
  157800. +#endif
  157801. + }
  157802. +
  157803. + /* Stop the kernel thread. */
  157804. + gcmkONERROR(gckGALDEVICE_Stop_Threads(Device));
  157805. +
  157806. + gcmkFOOTER_NO();
  157807. + return gcvSTATUS_OK;
  157808. +
  157809. +OnError:
  157810. + gcmkFOOTER();
  157811. + return status;
  157812. +}
  157813. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
  157814. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h 1970-01-01 01:00:00.000000000 +0100
  157815. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h 2014-08-20 19:31:46.136869040 +0200
  157816. @@ -0,0 +1,192 @@
  157817. +/****************************************************************************
  157818. +*
  157819. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  157820. +*
  157821. +* This program is free software; you can redistribute it and/or modify
  157822. +* it under the terms of the GNU General Public License as published by
  157823. +* the Free Software Foundation; either version 2 of the license, or
  157824. +* (at your option) any later version.
  157825. +*
  157826. +* This program is distributed in the hope that it will be useful,
  157827. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  157828. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  157829. +* GNU General Public License for more details.
  157830. +*
  157831. +* You should have received a copy of the GNU General Public License
  157832. +* along with this program; if not write to the Free Software
  157833. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  157834. +*
  157835. +*****************************************************************************/
  157836. +
  157837. +
  157838. +#ifndef __gc_hal_kernel_device_h_
  157839. +#define __gc_hal_kernel_device_h_
  157840. +
  157841. +/******************************************************************************\
  157842. +******************************* gckGALDEVICE Structure *******************************
  157843. +\******************************************************************************/
  157844. +
  157845. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  157846. +struct contiguous_mem_pool {
  157847. + struct dma_attrs attrs;
  157848. + dma_addr_t phys;
  157849. + void *virt;
  157850. + size_t size;
  157851. +};
  157852. +#endif
  157853. +
  157854. +typedef struct _gckGALDEVICE
  157855. +{
  157856. + /* Objects. */
  157857. + gckOS os;
  157858. + gckKERNEL kernels[gcdMAX_GPU_COUNT];
  157859. +
  157860. + /* Attributes. */
  157861. + gctSIZE_T internalSize;
  157862. + gctPHYS_ADDR internalPhysical;
  157863. + gctUINT32 internalPhysicalName;
  157864. + gctPOINTER internalLogical;
  157865. + gckVIDMEM internalVidMem;
  157866. + gctSIZE_T externalSize;
  157867. + gctPHYS_ADDR externalPhysical;
  157868. + gctUINT32 externalPhysicalName;
  157869. + gctPOINTER externalLogical;
  157870. + gckVIDMEM externalVidMem;
  157871. + gckVIDMEM contiguousVidMem;
  157872. + gctPOINTER contiguousBase;
  157873. + gctPHYS_ADDR contiguousPhysical;
  157874. + gctUINT32 contiguousPhysicalName;
  157875. + gctSIZE_T contiguousSize;
  157876. + gctBOOL contiguousMapped;
  157877. + gctPOINTER contiguousMappedUser;
  157878. + gctSIZE_T systemMemorySize;
  157879. + gctUINT32 systemMemoryBaseAddress;
  157880. + gctPOINTER registerBases[gcdMAX_GPU_COUNT];
  157881. + gctSIZE_T registerSizes[gcdMAX_GPU_COUNT];
  157882. + gctUINT32 baseAddress;
  157883. + gctUINT32 requestedRegisterMemBases[gcdMAX_GPU_COUNT];
  157884. + gctSIZE_T requestedRegisterMemSizes[gcdMAX_GPU_COUNT];
  157885. + gctUINT32 requestedContiguousBase;
  157886. + gctSIZE_T requestedContiguousSize;
  157887. +
  157888. + /* IRQ management. */
  157889. + gctINT irqLines[gcdMAX_GPU_COUNT];
  157890. + gctBOOL isrInitializeds[gcdMAX_GPU_COUNT];
  157891. + gctINT isrEnabled[gcdMAX_GPU_COUNT];
  157892. + gctBOOL dataReadys[gcdMAX_GPU_COUNT];
  157893. +
  157894. + /* Thread management. */
  157895. + struct task_struct *threadCtxts[gcdMAX_GPU_COUNT];
  157896. + struct semaphore semas[gcdMAX_GPU_COUNT];
  157897. + gctBOOL threadInitializeds[gcdMAX_GPU_COUNT];
  157898. + gctBOOL killThread;
  157899. +
  157900. + /* Signal management. */
  157901. + gctINT signal;
  157902. +
  157903. + /* Core mapping */
  157904. + gceCORE coreMapping[8];
  157905. +
  157906. + /* States before suspend. */
  157907. + gceCHIPPOWERSTATE statesStored[gcdMAX_GPU_COUNT];
  157908. +
  157909. + /*Device Debug File System Entry in Kernel*/
  157910. + struct _gcsDebugFileSystemNode * dbgnode;
  157911. +
  157912. + /* Clock management.*/
  157913. + struct clk *clk_3d_core;
  157914. + struct clk *clk_3d_shader;
  157915. + struct clk *clk_3d_axi;
  157916. + struct clk *clk_2d_core;
  157917. + struct clk *clk_2d_axi;
  157918. + struct clk *clk_vg_axi;
  157919. +
  157920. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  157921. + /*Power management.*/
  157922. + struct regulator *gpu_regulator;
  157923. +#endif
  157924. + /*Run time pm*/
  157925. + struct device *pmdev;
  157926. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  157927. + struct contiguous_mem_pool *pool;
  157928. + struct reset_control *rstc[gcdMAX_GPU_COUNT];
  157929. +#endif
  157930. +}
  157931. +* gckGALDEVICE;
  157932. +
  157933. +typedef struct _gcsHAL_PRIVATE_DATA
  157934. +{
  157935. + gckGALDEVICE device;
  157936. + gctPOINTER mappedMemory;
  157937. + gctPOINTER contiguousLogical;
  157938. + /* The process opening the device may not be the same as the one that closes it. */
  157939. + gctUINT32 pidOpen;
  157940. +}
  157941. +gcsHAL_PRIVATE_DATA, * gcsHAL_PRIVATE_DATA_PTR;
  157942. +
  157943. +gceSTATUS gckGALDEVICE_Enable_ISR(
  157944. + IN gckGALDEVICE Device,
  157945. + IN gceCORE Core
  157946. + );
  157947. +
  157948. +gceSTATUS gckGALDEVICE_Disable_ISR(
  157949. + IN gckGALDEVICE Device,
  157950. + IN gceCORE Core
  157951. + );
  157952. +
  157953. +gceSTATUS gckGALDEVICE_Setup_ISR(
  157954. + IN gckGALDEVICE Device,
  157955. + IN gceCORE Core
  157956. + );
  157957. +
  157958. +gceSTATUS gckGALDEVICE_Release_ISR(
  157959. + IN gckGALDEVICE Device,
  157960. + IN gceCORE Core
  157961. + );
  157962. +
  157963. +gceSTATUS gckGALDEVICE_Start_Threads(
  157964. + IN gckGALDEVICE Device
  157965. + );
  157966. +
  157967. +gceSTATUS gckGALDEVICE_Stop_Threads(
  157968. + gckGALDEVICE Device
  157969. + );
  157970. +
  157971. +gceSTATUS gckGALDEVICE_Start(
  157972. + IN gckGALDEVICE Device
  157973. + );
  157974. +
  157975. +gceSTATUS gckGALDEVICE_Stop(
  157976. + gckGALDEVICE Device
  157977. + );
  157978. +
  157979. +gceSTATUS gckGALDEVICE_Construct(
  157980. + IN gctINT IrqLine,
  157981. + IN gctUINT32 RegisterMemBase,
  157982. + IN gctSIZE_T RegisterMemSize,
  157983. + IN gctINT IrqLine2D,
  157984. + IN gctUINT32 RegisterMemBase2D,
  157985. + IN gctSIZE_T RegisterMemSize2D,
  157986. + IN gctINT IrqLineVG,
  157987. + IN gctUINT32 RegisterMemBaseVG,
  157988. + IN gctSIZE_T RegisterMemSizeVG,
  157989. + IN gctUINT32 ContiguousBase,
  157990. + IN gctSIZE_T ContiguousSize,
  157991. + IN gctSIZE_T BankSize,
  157992. + IN gctINT FastClear,
  157993. + IN gctINT Compression,
  157994. + IN gctUINT32 PhysBaseAddr,
  157995. + IN gctUINT32 PhysSize,
  157996. + IN gctINT Signal,
  157997. + IN gctUINT LogFileSize,
  157998. + IN struct device *pdev,
  157999. + IN gctINT PowerManagement,
  158000. + IN gctINT GpuProfiler,
  158001. + OUT gckGALDEVICE *Device
  158002. + );
  158003. +
  158004. +gceSTATUS gckGALDEVICE_Destroy(
  158005. + IN gckGALDEVICE Device
  158006. + );
  158007. +
  158008. +#endif /* __gc_hal_kernel_device_h_ */
  158009. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
  158010. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c 1970-01-01 01:00:00.000000000 +0100
  158011. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c 2014-08-20 19:31:46.136869040 +0200
  158012. @@ -0,0 +1,1471 @@
  158013. +/****************************************************************************
  158014. +*
  158015. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  158016. +* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  158017. +*
  158018. +* This program is free software; you can redistribute it and/or modify
  158019. +* it under the terms of the GNU General Public License as published by
  158020. +* the Free Software Foundation; either version 2 of the license, or
  158021. +* (at your option) any later version.
  158022. +*
  158023. +* This program is distributed in the hope that it will be useful,
  158024. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  158025. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  158026. +* GNU General Public License for more details.
  158027. +*
  158028. +* You should have received a copy of the GNU General Public License
  158029. +* along with this program; if not write to the Free Software
  158030. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  158031. +*
  158032. +*****************************************************************************/
  158033. +
  158034. +#include <linux/device.h>
  158035. +#include <linux/slab.h>
  158036. +#include <linux/notifier.h>
  158037. +#include "gc_hal_kernel_linux.h"
  158038. +#include "gc_hal_driver.h"
  158039. +
  158040. +#if USE_PLATFORM_DRIVER
  158041. +# include <linux/platform_device.h>
  158042. +#endif
  158043. +
  158044. +#ifdef CONFIG_PXA_DVFM
  158045. +# include <mach/dvfm.h>
  158046. +# include <mach/pxa3xx_dvfm.h>
  158047. +#endif
  158048. +
  158049. +
  158050. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  158051. +# include <linux/resmem_account.h>
  158052. +# include <linux/kernel.h>
  158053. +# include <linux/mm.h>
  158054. +# include <linux/oom.h>
  158055. +# include <linux/sched.h>
  158056. +# include <linux/notifier.h>
  158057. +
  158058. +struct task_struct *lowmem_deathpending;
  158059. +
  158060. +static int
  158061. +task_notify_func(struct notifier_block *self, unsigned long val, void *data);
  158062. +
  158063. +static struct notifier_block task_nb = {
  158064. + .notifier_call = task_notify_func,
  158065. +};
  158066. +
  158067. +static int
  158068. +task_notify_func(struct notifier_block *self, unsigned long val, void *data)
  158069. +{
  158070. + struct task_struct *task = data;
  158071. +
  158072. + if (task == lowmem_deathpending)
  158073. + lowmem_deathpending = NULL;
  158074. +
  158075. + return NOTIFY_OK;
  158076. +}
  158077. +#endif
  158078. +
  158079. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  158080. +#include <mach/viv_gpu.h>
  158081. +#else
  158082. +#include <linux/pm_runtime.h>
  158083. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
  158084. +#include <mach/busfreq.h>
  158085. +#else
  158086. +#include <linux/busfreq-imx6.h>
  158087. +#include <linux/reset.h>
  158088. +#endif
  158089. +#endif
  158090. +/* Zone used for header/footer. */
  158091. +#define _GC_OBJ_ZONE gcvZONE_DRIVER
  158092. +
  158093. +#if gcdENABLE_FSCALE_VAL_ADJUST
  158094. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  158095. +#include <linux/device_cooling.h>
  158096. +#define REG_THERMAL_NOTIFIER(a) register_devfreq_cooling_notifier(a);
  158097. +#define UNREG_THERMAL_NOTIFIER(a) unregister_devfreq_cooling_notifier(a);
  158098. +#else
  158099. +extern int register_thermal_notifier(struct notifier_block *nb);
  158100. +extern int unregister_thermal_notifier(struct notifier_block *nb);
  158101. +#define REG_THERMAL_NOTIFIER(a) register_thermal_notifier(a);
  158102. +#define UNREG_THERMAL_NOTIFIER(a) unregister_thermal_notifier(a);
  158103. +#endif
  158104. +#endif
  158105. +
  158106. +MODULE_DESCRIPTION("Vivante Graphics Driver");
  158107. +MODULE_LICENSE("GPL");
  158108. +
  158109. +static struct class* gpuClass;
  158110. +
  158111. +static gckGALDEVICE galDevice;
  158112. +
  158113. +static uint major = 199;
  158114. +module_param(major, uint, 0644);
  158115. +
  158116. +static int irqLine = -1;
  158117. +module_param(irqLine, int, 0644);
  158118. +
  158119. +static ulong registerMemBase = 0x80000000;
  158120. +module_param(registerMemBase, ulong, 0644);
  158121. +
  158122. +static ulong registerMemSize = 2 << 10;
  158123. +module_param(registerMemSize, ulong, 0644);
  158124. +
  158125. +static int irqLine2D = -1;
  158126. +module_param(irqLine2D, int, 0644);
  158127. +
  158128. +static ulong registerMemBase2D = 0x00000000;
  158129. +module_param(registerMemBase2D, ulong, 0644);
  158130. +
  158131. +static ulong registerMemSize2D = 2 << 10;
  158132. +module_param(registerMemSize2D, ulong, 0644);
  158133. +
  158134. +static int irqLineVG = -1;
  158135. +module_param(irqLineVG, int, 0644);
  158136. +
  158137. +static ulong registerMemBaseVG = 0x00000000;
  158138. +module_param(registerMemBaseVG, ulong, 0644);
  158139. +
  158140. +static ulong registerMemSizeVG = 2 << 10;
  158141. +module_param(registerMemSizeVG, ulong, 0644);
  158142. +
  158143. +#if gcdENABLE_FSCALE_VAL_ADJUST
  158144. +static ulong contiguousSize = 128 << 20;
  158145. +#else
  158146. +static ulong contiguousSize = 4 << 20;
  158147. +#endif
  158148. +module_param(contiguousSize, ulong, 0644);
  158149. +
  158150. +static ulong contiguousBase = 0;
  158151. +module_param(contiguousBase, ulong, 0644);
  158152. +
  158153. +static ulong bankSize = 0;
  158154. +module_param(bankSize, ulong, 0644);
  158155. +
  158156. +static int fastClear = -1;
  158157. +module_param(fastClear, int, 0644);
  158158. +
  158159. +static int compression = -1;
  158160. +module_param(compression, int, 0644);
  158161. +
  158162. +static int powerManagement = 1;
  158163. +module_param(powerManagement, int, 0644);
  158164. +
  158165. +static int gpuProfiler = 0;
  158166. +module_param(gpuProfiler, int, 0644);
  158167. +
  158168. +static int signal = 48;
  158169. +module_param(signal, int, 0644);
  158170. +
  158171. +static ulong baseAddress = 0;
  158172. +module_param(baseAddress, ulong, 0644);
  158173. +
  158174. +static ulong physSize = 0;
  158175. +module_param(physSize, ulong, 0644);
  158176. +
  158177. +static uint logFileSize=0;
  158178. +module_param(logFileSize,uint, 0644);
  158179. +
  158180. +static int showArgs = 0;
  158181. +module_param(showArgs, int, 0644);
  158182. +
  158183. +int gpu3DMinClock = 0;
  158184. +module_param(gpu3DMinClock, int, 0644);
  158185. +
  158186. +#if ENABLE_GPU_CLOCK_BY_DRIVER
  158187. + unsigned long coreClock = 156000000;
  158188. + module_param(coreClock, ulong, 0644);
  158189. +#endif
  158190. +
  158191. +static int drv_open(
  158192. + struct inode* inode,
  158193. + struct file* filp
  158194. + );
  158195. +
  158196. +static int drv_release(
  158197. + struct inode* inode,
  158198. + struct file* filp
  158199. + );
  158200. +
  158201. +static long drv_ioctl(
  158202. + struct file* filp,
  158203. + unsigned int ioctlCode,
  158204. + unsigned long arg
  158205. + );
  158206. +
  158207. +static int drv_mmap(
  158208. + struct file* filp,
  158209. + struct vm_area_struct* vma
  158210. + );
  158211. +
  158212. +static struct file_operations driver_fops =
  158213. +{
  158214. + .owner = THIS_MODULE,
  158215. + .open = drv_open,
  158216. + .release = drv_release,
  158217. + .unlocked_ioctl = drv_ioctl,
  158218. +#ifdef HAVE_COMPAT_IOCTL
  158219. + .compat_ioctl = drv_ioctl,
  158220. +#endif
  158221. + .mmap = drv_mmap,
  158222. +};
  158223. +
  158224. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  158225. +static size_t viv_gpu_resmem_query(struct task_struct *p, struct reserved_memory_account *m);
  158226. +static struct reserved_memory_account viv_gpu_resmem_handler = {
  158227. + .name = "viv_gpu",
  158228. + .get_page_used_by_process = viv_gpu_resmem_query,
  158229. +};
  158230. +
  158231. +size_t viv_gpu_resmem_query(struct task_struct *p, struct reserved_memory_account *m)
  158232. +{
  158233. + gcuDATABASE_INFO info;
  158234. + unsigned int processid = p->pid;
  158235. + gckKERNEL gpukernel = m->data;
  158236. +
  158237. + /* ignore error happens in this api. */
  158238. + if (gckKERNEL_QueryProcessDB(gpukernel, processid, false, gcvDB_VIDEO_MEMORY, &info) != gcvSTATUS_OK)
  158239. + return 0;
  158240. +
  158241. + /* we return pages. */
  158242. + if (info.counters.bytes > 0)
  158243. + return info.counters.bytes / PAGE_SIZE;
  158244. + return 0;
  158245. +}
  158246. +#endif
  158247. +
  158248. +int drv_open(
  158249. + struct inode* inode,
  158250. + struct file* filp
  158251. + )
  158252. +{
  158253. + gceSTATUS status;
  158254. + gctBOOL attached = gcvFALSE;
  158255. + gcsHAL_PRIVATE_DATA_PTR data = gcvNULL;
  158256. + gctINT i;
  158257. +
  158258. + gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp);
  158259. +
  158260. + if (filp == gcvNULL)
  158261. + {
  158262. + gcmkTRACE_ZONE(
  158263. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158264. + "%s(%d): filp is NULL\n",
  158265. + __FUNCTION__, __LINE__
  158266. + );
  158267. +
  158268. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158269. + }
  158270. +
  158271. + data = kmalloc(sizeof(gcsHAL_PRIVATE_DATA), GFP_KERNEL);
  158272. +
  158273. + if (data == gcvNULL)
  158274. + {
  158275. + gcmkTRACE_ZONE(
  158276. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158277. + "%s(%d): private_data is NULL\n",
  158278. + __FUNCTION__, __LINE__
  158279. + );
  158280. +
  158281. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  158282. + }
  158283. +
  158284. + data->device = galDevice;
  158285. + data->mappedMemory = gcvNULL;
  158286. + data->contiguousLogical = gcvNULL;
  158287. + gcmkONERROR(gckOS_GetProcessID(&data->pidOpen));
  158288. +
  158289. + /* Attached the process. */
  158290. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  158291. + {
  158292. + if (galDevice->kernels[i] != gcvNULL)
  158293. + {
  158294. + gcmkONERROR(gckKERNEL_AttachProcess(galDevice->kernels[i], gcvTRUE));
  158295. + }
  158296. + }
  158297. + attached = gcvTRUE;
  158298. +
  158299. + if (!galDevice->contiguousMapped)
  158300. + {
  158301. + gcmkONERROR(gckOS_MapMemory(
  158302. + galDevice->os,
  158303. + galDevice->contiguousPhysical,
  158304. + galDevice->contiguousSize,
  158305. + &data->contiguousLogical
  158306. + ));
  158307. + }
  158308. +
  158309. + filp->private_data = data;
  158310. +
  158311. + /* Success. */
  158312. + gcmkFOOTER_NO();
  158313. + return 0;
  158314. +
  158315. +OnError:
  158316. + if (data != gcvNULL)
  158317. + {
  158318. + if (data->contiguousLogical != gcvNULL)
  158319. + {
  158320. + gcmkVERIFY_OK(gckOS_UnmapMemory(
  158321. + galDevice->os,
  158322. + galDevice->contiguousPhysical,
  158323. + galDevice->contiguousSize,
  158324. + data->contiguousLogical
  158325. + ));
  158326. + }
  158327. +
  158328. + kfree(data);
  158329. + }
  158330. +
  158331. + if (attached)
  158332. + {
  158333. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  158334. + {
  158335. + if (galDevice->kernels[i] != gcvNULL)
  158336. + {
  158337. + gcmkVERIFY_OK(gckKERNEL_AttachProcess(galDevice->kernels[i], gcvFALSE));
  158338. + }
  158339. + }
  158340. + }
  158341. +
  158342. + gcmkFOOTER();
  158343. + return -ENOTTY;
  158344. +}
  158345. +
  158346. +int drv_release(
  158347. + struct inode* inode,
  158348. + struct file* filp
  158349. + )
  158350. +{
  158351. + gceSTATUS status;
  158352. + gcsHAL_PRIVATE_DATA_PTR data;
  158353. + gckGALDEVICE device;
  158354. + gctINT i;
  158355. +
  158356. + gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp);
  158357. +
  158358. + if (filp == gcvNULL)
  158359. + {
  158360. + gcmkTRACE_ZONE(
  158361. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158362. + "%s(%d): filp is NULL\n",
  158363. + __FUNCTION__, __LINE__
  158364. + );
  158365. +
  158366. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158367. + }
  158368. +
  158369. + data = filp->private_data;
  158370. +
  158371. + if (data == gcvNULL)
  158372. + {
  158373. + gcmkTRACE_ZONE(
  158374. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158375. + "%s(%d): private_data is NULL\n",
  158376. + __FUNCTION__, __LINE__
  158377. + );
  158378. +
  158379. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158380. + }
  158381. +
  158382. + device = data->device;
  158383. +
  158384. + if (device == gcvNULL)
  158385. + {
  158386. + gcmkTRACE_ZONE(
  158387. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158388. + "%s(%d): device is NULL\n",
  158389. + __FUNCTION__, __LINE__
  158390. + );
  158391. +
  158392. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158393. + }
  158394. +
  158395. + if (!device->contiguousMapped)
  158396. + {
  158397. + if (data->contiguousLogical != gcvNULL)
  158398. + {
  158399. + gcmkONERROR(gckOS_UnmapMemoryEx(
  158400. + galDevice->os,
  158401. + galDevice->contiguousPhysical,
  158402. + galDevice->contiguousSize,
  158403. + data->contiguousLogical,
  158404. + data->pidOpen
  158405. + ));
  158406. +
  158407. + data->contiguousLogical = gcvNULL;
  158408. + }
  158409. + }
  158410. +
  158411. + /* A process gets detached. */
  158412. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  158413. + {
  158414. + if (galDevice->kernels[i] != gcvNULL)
  158415. + {
  158416. + gcmkONERROR(gckKERNEL_AttachProcessEx(galDevice->kernels[i], gcvFALSE, data->pidOpen));
  158417. + }
  158418. + }
  158419. +
  158420. + kfree(data);
  158421. + filp->private_data = NULL;
  158422. +
  158423. + /* Success. */
  158424. + gcmkFOOTER_NO();
  158425. + return 0;
  158426. +
  158427. +OnError:
  158428. + gcmkFOOTER();
  158429. + return -ENOTTY;
  158430. +}
  158431. +
  158432. +long drv_ioctl(
  158433. + struct file* filp,
  158434. + unsigned int ioctlCode,
  158435. + unsigned long arg
  158436. + )
  158437. +{
  158438. + gceSTATUS status;
  158439. + gcsHAL_INTERFACE iface;
  158440. + gctUINT32 copyLen;
  158441. + DRIVER_ARGS drvArgs;
  158442. + gckGALDEVICE device;
  158443. + gcsHAL_PRIVATE_DATA_PTR data;
  158444. + gctINT32 i, count;
  158445. +
  158446. + gcmkHEADER_ARG(
  158447. + "filp=0x%08X ioctlCode=0x%08X arg=0x%08X",
  158448. + filp, ioctlCode, arg
  158449. + );
  158450. +
  158451. + if (filp == gcvNULL)
  158452. + {
  158453. + gcmkTRACE_ZONE(
  158454. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158455. + "%s(%d): filp is NULL\n",
  158456. + __FUNCTION__, __LINE__
  158457. + );
  158458. +
  158459. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158460. + }
  158461. +
  158462. + data = filp->private_data;
  158463. +
  158464. + if (data == gcvNULL)
  158465. + {
  158466. + gcmkTRACE_ZONE(
  158467. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158468. + "%s(%d): private_data is NULL\n",
  158469. + __FUNCTION__, __LINE__
  158470. + );
  158471. +
  158472. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158473. + }
  158474. +
  158475. + device = data->device;
  158476. +
  158477. + if (device == gcvNULL)
  158478. + {
  158479. + gcmkTRACE_ZONE(
  158480. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158481. + "%s(%d): device is NULL\n",
  158482. + __FUNCTION__, __LINE__
  158483. + );
  158484. +
  158485. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158486. + }
  158487. +
  158488. + if ((ioctlCode != IOCTL_GCHAL_INTERFACE)
  158489. + && (ioctlCode != IOCTL_GCHAL_KERNEL_INTERFACE)
  158490. + )
  158491. + {
  158492. + gcmkTRACE_ZONE(
  158493. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158494. + "%s(%d): unknown command %d\n",
  158495. + __FUNCTION__, __LINE__,
  158496. + ioctlCode
  158497. + );
  158498. +
  158499. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158500. + }
  158501. +
  158502. + /* Get the drvArgs. */
  158503. + copyLen = copy_from_user(
  158504. + &drvArgs, (void *) arg, sizeof(DRIVER_ARGS)
  158505. + );
  158506. +
  158507. + if (copyLen != 0)
  158508. + {
  158509. + gcmkTRACE_ZONE(
  158510. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158511. + "%s(%d): error copying of the input arguments.\n",
  158512. + __FUNCTION__, __LINE__
  158513. + );
  158514. +
  158515. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158516. + }
  158517. +
  158518. + /* Now bring in the gcsHAL_INTERFACE structure. */
  158519. + if ((drvArgs.InputBufferSize != sizeof(gcsHAL_INTERFACE))
  158520. + || (drvArgs.OutputBufferSize != sizeof(gcsHAL_INTERFACE))
  158521. + )
  158522. + {
  158523. + gcmkTRACE_ZONE(
  158524. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158525. + "%s(%d): input or/and output structures are invalid.\n",
  158526. + __FUNCTION__, __LINE__
  158527. + );
  158528. +
  158529. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158530. + }
  158531. +
  158532. + copyLen = copy_from_user(
  158533. + &iface, gcmUINT64_TO_PTR(drvArgs.InputBuffer), sizeof(gcsHAL_INTERFACE)
  158534. + );
  158535. +
  158536. + if (copyLen != 0)
  158537. + {
  158538. + gcmkTRACE_ZONE(
  158539. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158540. + "%s(%d): error copying of input HAL interface.\n",
  158541. + __FUNCTION__, __LINE__
  158542. + );
  158543. +
  158544. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158545. + }
  158546. +
  158547. + if (iface.command == gcvHAL_CHIP_INFO)
  158548. + {
  158549. + count = 0;
  158550. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  158551. + {
  158552. + if (device->kernels[i] != gcvNULL)
  158553. + {
  158554. +#if gcdENABLE_VG
  158555. + if (i == gcvCORE_VG)
  158556. + {
  158557. + iface.u.ChipInfo.types[count] = gcvHARDWARE_VG;
  158558. + }
  158559. + else
  158560. +#endif
  158561. + {
  158562. + gcmkVERIFY_OK(gckHARDWARE_GetType(device->kernels[i]->hardware,
  158563. + &iface.u.ChipInfo.types[count]));
  158564. + }
  158565. + count++;
  158566. + }
  158567. + }
  158568. +
  158569. + iface.u.ChipInfo.count = count;
  158570. + iface.status = status = gcvSTATUS_OK;
  158571. + }
  158572. + else
  158573. + {
  158574. + if (iface.hardwareType < 0 || iface.hardwareType > 7)
  158575. + {
  158576. + gcmkTRACE_ZONE(
  158577. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158578. + "%s(%d): unknown hardwareType %d\n",
  158579. + __FUNCTION__, __LINE__,
  158580. + iface.hardwareType
  158581. + );
  158582. +
  158583. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158584. + }
  158585. +
  158586. +#if gcdENABLE_VG
  158587. + if (device->coreMapping[iface.hardwareType] == gcvCORE_VG)
  158588. + {
  158589. + status = gckVGKERNEL_Dispatch(device->kernels[gcvCORE_VG],
  158590. + (ioctlCode == IOCTL_GCHAL_INTERFACE),
  158591. + &iface);
  158592. + }
  158593. + else
  158594. +#endif
  158595. + {
  158596. + status = gckKERNEL_Dispatch(device->kernels[device->coreMapping[iface.hardwareType]],
  158597. + (ioctlCode == IOCTL_GCHAL_INTERFACE),
  158598. + &iface);
  158599. + }
  158600. + }
  158601. +
  158602. + /* Redo system call after pending signal is handled. */
  158603. + if (status == gcvSTATUS_INTERRUPTED)
  158604. + {
  158605. + gcmkFOOTER();
  158606. + return -ERESTARTSYS;
  158607. + }
  158608. +
  158609. + if (gcmIS_SUCCESS(status) && (iface.command == gcvHAL_LOCK_VIDEO_MEMORY))
  158610. + {
  158611. + gcuVIDMEM_NODE_PTR node = gcmUINT64_TO_PTR(iface.u.LockVideoMemory.node);
  158612. + /* Special case for mapped memory. */
  158613. + if ((data->mappedMemory != gcvNULL)
  158614. + && (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  158615. + )
  158616. + {
  158617. + /* Compute offset into mapped memory. */
  158618. + gctUINT32 offset
  158619. + = (gctUINT8 *) gcmUINT64_TO_PTR(iface.u.LockVideoMemory.memory)
  158620. + - (gctUINT8 *) device->contiguousBase;
  158621. +
  158622. + /* Compute offset into user-mapped region. */
  158623. + iface.u.LockVideoMemory.memory =
  158624. + gcmPTR_TO_UINT64((gctUINT8 *) data->mappedMemory + offset);
  158625. + }
  158626. + }
  158627. +
  158628. + /* Copy data back to the user. */
  158629. + copyLen = copy_to_user(
  158630. + gcmUINT64_TO_PTR(drvArgs.OutputBuffer), &iface, sizeof(gcsHAL_INTERFACE)
  158631. + );
  158632. +
  158633. + if (copyLen != 0)
  158634. + {
  158635. + gcmkTRACE_ZONE(
  158636. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158637. + "%s(%d): error copying of output HAL interface.\n",
  158638. + __FUNCTION__, __LINE__
  158639. + );
  158640. +
  158641. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158642. + }
  158643. +
  158644. + /* Success. */
  158645. + gcmkFOOTER_NO();
  158646. + return 0;
  158647. +
  158648. +OnError:
  158649. + gcmkFOOTER();
  158650. + return -ENOTTY;
  158651. +}
  158652. +
  158653. +static int drv_mmap(
  158654. + struct file* filp,
  158655. + struct vm_area_struct* vma
  158656. + )
  158657. +{
  158658. + gceSTATUS status = gcvSTATUS_OK;
  158659. + gcsHAL_PRIVATE_DATA_PTR data;
  158660. + gckGALDEVICE device;
  158661. +
  158662. + gcmkHEADER_ARG("filp=0x%08X vma=0x%08X", filp, vma);
  158663. +
  158664. + if (filp == gcvNULL)
  158665. + {
  158666. + gcmkTRACE_ZONE(
  158667. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158668. + "%s(%d): filp is NULL\n",
  158669. + __FUNCTION__, __LINE__
  158670. + );
  158671. +
  158672. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158673. + }
  158674. +
  158675. + data = filp->private_data;
  158676. +
  158677. + if (data == gcvNULL)
  158678. + {
  158679. + gcmkTRACE_ZONE(
  158680. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158681. + "%s(%d): private_data is NULL\n",
  158682. + __FUNCTION__, __LINE__
  158683. + );
  158684. +
  158685. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158686. + }
  158687. +
  158688. + device = data->device;
  158689. +
  158690. + if (device == gcvNULL)
  158691. + {
  158692. + gcmkTRACE_ZONE(
  158693. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158694. + "%s(%d): device is NULL\n",
  158695. + __FUNCTION__, __LINE__
  158696. + );
  158697. +
  158698. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158699. + }
  158700. +
  158701. +#if !gcdPAGED_MEMORY_CACHEABLE
  158702. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  158703. + vma->vm_flags |= gcdVM_FLAGS;
  158704. +#endif
  158705. + vma->vm_pgoff = 0;
  158706. +
  158707. + if (device->contiguousMapped)
  158708. + {
  158709. + unsigned long size = vma->vm_end - vma->vm_start;
  158710. + int ret = 0;
  158711. +
  158712. + if (size > device->contiguousSize)
  158713. + {
  158714. + gcmkTRACE_ZONE(
  158715. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158716. + "%s(%d): Invalid mapping size.\n",
  158717. + __FUNCTION__, __LINE__
  158718. + );
  158719. +
  158720. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158721. + }
  158722. +
  158723. + ret = io_remap_pfn_range(
  158724. + vma,
  158725. + vma->vm_start,
  158726. + device->requestedContiguousBase >> PAGE_SHIFT,
  158727. + size,
  158728. + vma->vm_page_prot
  158729. + );
  158730. +
  158731. + if (ret != 0)
  158732. + {
  158733. + gcmkTRACE_ZONE(
  158734. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158735. + "%s(%d): io_remap_pfn_range failed %d\n",
  158736. + __FUNCTION__, __LINE__,
  158737. + ret
  158738. + );
  158739. +
  158740. + data->mappedMemory = gcvNULL;
  158741. +
  158742. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  158743. + }
  158744. +
  158745. + data->mappedMemory = (gctPOINTER) vma->vm_start;
  158746. +
  158747. + /* Success. */
  158748. + gcmkFOOTER_NO();
  158749. + return 0;
  158750. + }
  158751. +
  158752. +
  158753. +OnError:
  158754. + gcmkFOOTER();
  158755. + return -ENOTTY;
  158756. +}
  158757. +
  158758. +
  158759. +#if !USE_PLATFORM_DRIVER
  158760. +static int __init drv_init(void)
  158761. +#else
  158762. +static int drv_init(struct device *pdev)
  158763. +#endif
  158764. +{
  158765. + int ret;
  158766. + int result = -EINVAL;
  158767. + gceSTATUS status;
  158768. + gckGALDEVICE device = gcvNULL;
  158769. + struct class* device_class = gcvNULL;
  158770. +
  158771. + gcmkHEADER();
  158772. +
  158773. +#if ENABLE_GPU_CLOCK_BY_DRIVER && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
  158774. + {
  158775. +# if 0
  158776. + struct clk * clk;
  158777. +
  158778. + clk = clk_get(NULL, "GCCLK");
  158779. +
  158780. + if (IS_ERR(clk))
  158781. + {
  158782. + gcmkTRACE_ZONE(
  158783. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158784. + "%s(%d): clk get error: %d\n",
  158785. + __FUNCTION__, __LINE__,
  158786. + PTR_ERR(clk)
  158787. + );
  158788. +
  158789. + result = -ENODEV;
  158790. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  158791. + }
  158792. +
  158793. + /*
  158794. + * APMU_GC_156M, APMU_GC_312M, APMU_GC_PLL2, APMU_GC_PLL2_DIV2 currently.
  158795. + * Use the 2X clock.
  158796. + */
  158797. + if (clk_set_rate(clk, coreClock * 2))
  158798. + {
  158799. + gcmkTRACE_ZONE(
  158800. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158801. + "%s(%d): Failed to set core clock.\n",
  158802. + __FUNCTION__, __LINE__
  158803. + );
  158804. +
  158805. + result = -EAGAIN;
  158806. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  158807. + }
  158808. +
  158809. + clk_enable(clk);
  158810. +
  158811. +#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
  158812. + gc_pwr(1);
  158813. +# endif
  158814. +# endif
  158815. + }
  158816. +#endif
  158817. +
  158818. + printk(KERN_INFO "Galcore version %d.%d.%d.%d\n",
  158819. + gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD);
  158820. + /* when enable gpu profiler, we need to turn off gpu powerMangement */
  158821. + if(gpuProfiler)
  158822. + powerManagement = 0;
  158823. + if (showArgs)
  158824. + {
  158825. + printk("galcore options:\n");
  158826. + printk(" irqLine = %d\n", irqLine);
  158827. + printk(" registerMemBase = 0x%08lX\n", registerMemBase);
  158828. + printk(" registerMemSize = 0x%08lX\n", registerMemSize);
  158829. +
  158830. + if (irqLine2D != -1)
  158831. + {
  158832. + printk(" irqLine2D = %d\n", irqLine2D);
  158833. + printk(" registerMemBase2D = 0x%08lX\n", registerMemBase2D);
  158834. + printk(" registerMemSize2D = 0x%08lX\n", registerMemSize2D);
  158835. + }
  158836. +
  158837. + if (irqLineVG != -1)
  158838. + {
  158839. + printk(" irqLineVG = %d\n", irqLineVG);
  158840. + printk(" registerMemBaseVG = 0x%08lX\n", registerMemBaseVG);
  158841. + printk(" registerMemSizeVG = 0x%08lX\n", registerMemSizeVG);
  158842. + }
  158843. +
  158844. + printk(" contiguousSize = %ld\n", contiguousSize);
  158845. + printk(" contiguousBase = 0x%08lX\n", contiguousBase);
  158846. + printk(" bankSize = 0x%08lX\n", bankSize);
  158847. + printk(" fastClear = %d\n", fastClear);
  158848. + printk(" compression = %d\n", compression);
  158849. + printk(" signal = %d\n", signal);
  158850. + printk(" baseAddress = 0x%08lX\n", baseAddress);
  158851. + printk(" physSize = 0x%08lX\n", physSize);
  158852. + printk(" logFileSize = %d KB \n", logFileSize);
  158853. + printk(" powerManagement = %d\n", powerManagement);
  158854. + printk(" gpuProfiler = %d\n", gpuProfiler);
  158855. +#if ENABLE_GPU_CLOCK_BY_DRIVER
  158856. + printk(" coreClock = %lu\n", coreClock);
  158857. +#endif
  158858. + }
  158859. +
  158860. + if(logFileSize != 0)
  158861. + {
  158862. + gckDebugFileSystemInitialize();
  158863. + }
  158864. +
  158865. + /* Create the GAL device. */
  158866. + gcmkONERROR(gckGALDEVICE_Construct(
  158867. + irqLine,
  158868. + registerMemBase, registerMemSize,
  158869. + irqLine2D,
  158870. + registerMemBase2D, registerMemSize2D,
  158871. + irqLineVG,
  158872. + registerMemBaseVG, registerMemSizeVG,
  158873. + contiguousBase, contiguousSize,
  158874. + bankSize, fastClear, compression, baseAddress, physSize, signal,
  158875. + logFileSize,
  158876. + pdev,
  158877. + powerManagement,
  158878. + gpuProfiler,
  158879. + &device
  158880. + ));
  158881. +
  158882. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  158883. + device->pool = dev_get_drvdata(pdev);
  158884. +#endif
  158885. +
  158886. + /* Start the GAL device. */
  158887. + gcmkONERROR(gckGALDEVICE_Start(device));
  158888. +
  158889. + if ((physSize != 0)
  158890. + && (device->kernels[gcvCORE_MAJOR] != gcvNULL)
  158891. + && (device->kernels[gcvCORE_MAJOR]->hardware->mmuVersion != 0))
  158892. + {
  158893. + status = gckMMU_Enable(device->kernels[gcvCORE_MAJOR]->mmu, baseAddress, physSize);
  158894. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  158895. + "Enable new MMU: status=%d\n", status);
  158896. +
  158897. + if ((device->kernels[gcvCORE_2D] != gcvNULL)
  158898. + && (device->kernels[gcvCORE_2D]->hardware->mmuVersion != 0))
  158899. + {
  158900. + status = gckMMU_Enable(device->kernels[gcvCORE_2D]->mmu, baseAddress, physSize);
  158901. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  158902. + "Enable new MMU for 2D: status=%d\n", status);
  158903. + }
  158904. +
  158905. + /* Reset the base address */
  158906. + device->baseAddress = 0;
  158907. + }
  158908. +
  158909. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  158910. + task_free_register(&task_nb);
  158911. + viv_gpu_resmem_handler.data = device->kernels[gcvCORE_MAJOR];
  158912. + register_reserved_memory_account(&viv_gpu_resmem_handler);
  158913. +#endif
  158914. +
  158915. +
  158916. + /* Register the character device. */
  158917. + ret = register_chrdev(major, DRV_NAME, &driver_fops);
  158918. +
  158919. + if (ret < 0)
  158920. + {
  158921. + gcmkTRACE_ZONE(
  158922. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158923. + "%s(%d): Could not allocate major number for mmap.\n",
  158924. + __FUNCTION__, __LINE__
  158925. + );
  158926. +
  158927. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  158928. + }
  158929. +
  158930. + if (major == 0)
  158931. + {
  158932. + major = ret;
  158933. + }
  158934. +
  158935. + /* Create the device class. */
  158936. + device_class = class_create(THIS_MODULE, "graphics_class");
  158937. +
  158938. + if (IS_ERR(device_class))
  158939. + {
  158940. + gcmkTRACE_ZONE(
  158941. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158942. + "%s(%d): Failed to create the class.\n",
  158943. + __FUNCTION__, __LINE__
  158944. + );
  158945. +
  158946. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  158947. + }
  158948. +
  158949. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  158950. + device_create(device_class, NULL, MKDEV(major, 0), NULL, "galcore");
  158951. +#else
  158952. + device_create(device_class, NULL, MKDEV(major, 0), "galcore");
  158953. +#endif
  158954. +
  158955. + galDevice = device;
  158956. + gpuClass = device_class;
  158957. +
  158958. + gcmkTRACE_ZONE(
  158959. + gcvLEVEL_INFO, gcvZONE_DRIVER,
  158960. + "%s(%d): irqLine=%d, contiguousSize=%lu, memBase=0x%lX\n",
  158961. + __FUNCTION__, __LINE__,
  158962. + irqLine, contiguousSize, registerMemBase
  158963. + );
  158964. +
  158965. + /* Success. */
  158966. + gcmkFOOTER_NO();
  158967. + return 0;
  158968. +
  158969. +OnError:
  158970. + /* Roll back. */
  158971. + if (device_class != gcvNULL)
  158972. + {
  158973. + device_destroy(device_class, MKDEV(major, 0));
  158974. + class_destroy(device_class);
  158975. + }
  158976. +
  158977. + if (device != gcvNULL)
  158978. + {
  158979. + gcmkVERIFY_OK(gckGALDEVICE_Stop(device));
  158980. + gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
  158981. + }
  158982. +
  158983. + gcmkFOOTER();
  158984. + return result;
  158985. +}
  158986. +
  158987. +#if !USE_PLATFORM_DRIVER
  158988. +static void __exit drv_exit(void)
  158989. +#else
  158990. +static void drv_exit(void)
  158991. +#endif
  158992. +{
  158993. + gcmkHEADER();
  158994. +
  158995. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  158996. + task_free_unregister(&task_nb);
  158997. + unregister_reserved_memory_account(&viv_gpu_resmem_handler);
  158998. +#endif
  158999. +
  159000. + gcmkASSERT(gpuClass != gcvNULL);
  159001. + device_destroy(gpuClass, MKDEV(major, 0));
  159002. + class_destroy(gpuClass);
  159003. +
  159004. + unregister_chrdev(major, DRV_NAME);
  159005. +
  159006. + gcmkVERIFY_OK(gckGALDEVICE_Stop(galDevice));
  159007. + gcmkVERIFY_OK(gckGALDEVICE_Destroy(galDevice));
  159008. +
  159009. + if(gckDebugFileSystemIsEnabled())
  159010. + {
  159011. + gckDebugFileSystemTerminate();
  159012. + }
  159013. +
  159014. +#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
  159015. + {
  159016. +# if 0
  159017. + struct clk * clk = NULL;
  159018. +
  159019. +#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
  159020. + gc_pwr(0);
  159021. +#endif
  159022. + clk = clk_get(NULL, "GCCLK");
  159023. + clk_disable(clk);
  159024. +# endif
  159025. + }
  159026. +#endif
  159027. +
  159028. + gcmkFOOTER_NO();
  159029. +}
  159030. +
  159031. +#if !USE_PLATFORM_DRIVER
  159032. + module_init(drv_init);
  159033. + module_exit(drv_exit);
  159034. +#else
  159035. +
  159036. +#ifdef CONFIG_DOVE_GPU
  159037. +# define DEVICE_NAME "dove_gpu"
  159038. +#else
  159039. +# define DEVICE_NAME "galcore"
  159040. +#endif
  159041. +
  159042. +#if gcdENABLE_FSCALE_VAL_ADJUST
  159043. +static int thermal_hot_pm_notify(struct notifier_block *nb, unsigned long event,
  159044. + void *dummy)
  159045. +{
  159046. + static gctUINT orgFscale, minFscale, maxFscale;
  159047. + static gctBOOL bAlreadyTooHot = gcvFALSE;
  159048. + gckHARDWARE hardware = galDevice->kernels[gcvCORE_MAJOR]->hardware;
  159049. +
  159050. + if (event && !bAlreadyTooHot) {
  159051. + gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
  159052. + gckHARDWARE_SetFscaleValue(hardware, minFscale);
  159053. + bAlreadyTooHot = gcvTRUE;
  159054. + gckOS_Print("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale);
  159055. + } else if (!event && bAlreadyTooHot) {
  159056. + gckHARDWARE_SetFscaleValue(hardware, orgFscale);
  159057. + gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale);
  159058. + bAlreadyTooHot = gcvFALSE;
  159059. + }
  159060. + return NOTIFY_OK;
  159061. +}
  159062. +
  159063. +static struct notifier_block thermal_hot_pm_notifier = {
  159064. + .notifier_call = thermal_hot_pm_notify,
  159065. + };
  159066. +#endif
  159067. +
  159068. +
  159069. +
  159070. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
  159071. +static int gpu_probe(struct platform_device *pdev)
  159072. +#else
  159073. +static int __devinit gpu_probe(struct platform_device *pdev)
  159074. +#endif
  159075. +{
  159076. + int ret = -ENODEV;
  159077. + struct resource* res;
  159078. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159079. + struct contiguous_mem_pool *pool;
  159080. + struct reset_control *rstc;
  159081. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  159082. + struct device_node *dn =pdev->dev.of_node;
  159083. + const u32 *prop;
  159084. +#else
  159085. + struct viv_gpu_platform_data *pdata;
  159086. +#endif
  159087. + gcmkHEADER();
  159088. +
  159089. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phys_baseaddr");
  159090. + if (res)
  159091. + baseAddress = res->start;
  159092. +
  159093. + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_3d");
  159094. + if (res)
  159095. + irqLine = res->start;
  159096. +
  159097. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_3d");
  159098. + if (res)
  159099. + {
  159100. + registerMemBase = res->start;
  159101. + registerMemSize = res->end - res->start + 1;
  159102. + }
  159103. +
  159104. + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_2d");
  159105. + if (res)
  159106. + irqLine2D = res->start;
  159107. +
  159108. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_2d");
  159109. + if (res)
  159110. + {
  159111. + registerMemBase2D = res->start;
  159112. + registerMemSize2D = res->end - res->start + 1;
  159113. + }
  159114. +
  159115. + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_vg");
  159116. + if (res)
  159117. + irqLineVG = res->start;
  159118. +
  159119. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_vg");
  159120. + if (res)
  159121. + {
  159122. + registerMemBaseVG = res->start;
  159123. + registerMemSizeVG = res->end - res->start + 1;
  159124. + }
  159125. +
  159126. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159127. + pool = devm_kzalloc(&pdev->dev, sizeof(*pool), GFP_KERNEL);
  159128. + if (!pool)
  159129. + return -ENOMEM;
  159130. + pool->size = contiguousSize;
  159131. + init_dma_attrs(&pool->attrs);
  159132. + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &pool->attrs);
  159133. + pool->virt = dma_alloc_attrs(&pdev->dev, pool->size, &pool->phys,
  159134. + GFP_KERNEL, &pool->attrs);
  159135. + if (!pool->virt) {
  159136. + dev_err(&pdev->dev, "Failed to allocate contiguous memory\n");
  159137. + return -ENOMEM;
  159138. + }
  159139. + contiguousBase = pool->phys;
  159140. + dev_set_drvdata(&pdev->dev, pool);
  159141. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  159142. + prop = of_get_property(dn, "contiguousbase", NULL);
  159143. + if(prop)
  159144. + contiguousBase = *prop;
  159145. + of_property_read_u32(dn,"contiguoussize", (u32 *)&contiguousSize);
  159146. +#else
  159147. + pdata = pdev->dev.platform_data;
  159148. + if (pdata) {
  159149. + contiguousBase = pdata->reserved_mem_base;
  159150. + contiguousSize = pdata->reserved_mem_size;
  159151. + }
  159152. +#endif
  159153. + if (contiguousSize == 0)
  159154. + gckOS_Print("Warning: No contiguous memory is reserverd for gpu.!\n ");
  159155. + ret = drv_init(&pdev->dev);
  159156. +
  159157. + if (!ret)
  159158. + {
  159159. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159160. + rstc = devm_reset_control_get(&pdev->dev, "gpu3d");
  159161. + galDevice->rstc[gcvCORE_MAJOR] = IS_ERR(rstc) ? NULL : rstc;
  159162. +
  159163. + rstc = devm_reset_control_get(&pdev->dev, "gpu2d");
  159164. + galDevice->rstc[gcvCORE_2D] = IS_ERR(rstc) ? NULL : rstc;
  159165. +
  159166. + rstc = devm_reset_control_get(&pdev->dev, "gpuvg");
  159167. + galDevice->rstc[gcvCORE_VG] = IS_ERR(rstc) ? NULL : rstc;
  159168. +#endif
  159169. + platform_set_drvdata(pdev, galDevice);
  159170. +
  159171. +#if gcdENABLE_FSCALE_VAL_ADJUST
  159172. + if (galDevice->kernels[gcvCORE_MAJOR])
  159173. + REG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
  159174. +#endif
  159175. + gcmkFOOTER_NO();
  159176. + return ret;
  159177. + }
  159178. +#if gcdENABLE_FSCALE_VAL_ADJUST
  159179. + UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
  159180. +#endif
  159181. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159182. + dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
  159183. + &pool->attrs);
  159184. +#endif
  159185. + gcmkFOOTER_ARG(KERN_INFO "Failed to register gpu driver: %d\n", ret);
  159186. + return ret;
  159187. +}
  159188. +
  159189. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
  159190. +static int gpu_remove(struct platform_device *pdev)
  159191. +#else
  159192. +static int __devexit gpu_remove(struct platform_device *pdev)
  159193. +#endif
  159194. +{
  159195. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159196. + gckGALDEVICE device = platform_get_drvdata(pdev);
  159197. + struct contiguous_mem_pool *pool = device->pool;
  159198. +#endif
  159199. + gcmkHEADER();
  159200. +#if gcdENABLE_FSCALE_VAL_ADJUST
  159201. + if(galDevice->kernels[gcvCORE_MAJOR])
  159202. + UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
  159203. +#endif
  159204. + drv_exit();
  159205. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159206. + dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
  159207. + &pool->attrs);
  159208. +#endif
  159209. + gcmkFOOTER_NO();
  159210. + return 0;
  159211. +}
  159212. +
  159213. +static int gpu_suspend(struct platform_device *dev, pm_message_t state)
  159214. +{
  159215. + gceSTATUS status;
  159216. + gckGALDEVICE device;
  159217. + gctINT i;
  159218. +
  159219. + device = platform_get_drvdata(dev);
  159220. +
  159221. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  159222. + {
  159223. + if (device->kernels[i] != gcvNULL)
  159224. + {
  159225. + /* Store states. */
  159226. +#if gcdENABLE_VG
  159227. + if (i == gcvCORE_VG)
  159228. + {
  159229. + status = gckVGHARDWARE_QueryPowerManagementState(device->kernels[i]->vg->hardware, &device->statesStored[i]);
  159230. + }
  159231. + else
  159232. +#endif
  159233. + {
  159234. + status = gckHARDWARE_QueryPowerManagementState(device->kernels[i]->hardware, &device->statesStored[i]);
  159235. + }
  159236. +
  159237. + if (gcmIS_ERROR(status))
  159238. + {
  159239. + return -1;
  159240. + }
  159241. +
  159242. +#if gcdENABLE_VG
  159243. + if (i == gcvCORE_VG)
  159244. + {
  159245. + status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_OFF);
  159246. + }
  159247. + else
  159248. +#endif
  159249. + {
  159250. + status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_OFF);
  159251. + }
  159252. + if (gcmIS_ERROR(status))
  159253. + {
  159254. + return -1;
  159255. + }
  159256. +
  159257. + }
  159258. + }
  159259. +
  159260. + return 0;
  159261. +}
  159262. +
  159263. +static int gpu_resume(struct platform_device *dev)
  159264. +{
  159265. + gceSTATUS status;
  159266. + gckGALDEVICE device;
  159267. + gctINT i;
  159268. + gceCHIPPOWERSTATE statesStored;
  159269. +
  159270. + device = platform_get_drvdata(dev);
  159271. +
  159272. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  159273. + {
  159274. + if (device->kernels[i] != gcvNULL)
  159275. + {
  159276. +#if gcdENABLE_VG
  159277. + if (i == gcvCORE_VG)
  159278. + {
  159279. + status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_ON);
  159280. + }
  159281. + else
  159282. +#endif
  159283. + {
  159284. + status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_ON);
  159285. + }
  159286. +
  159287. + if (gcmIS_ERROR(status))
  159288. + {
  159289. + return -1;
  159290. + }
  159291. +
  159292. + /* Convert global state to crossponding internal state. */
  159293. + switch(device->statesStored[i])
  159294. + {
  159295. + case gcvPOWER_OFF:
  159296. + statesStored = gcvPOWER_OFF_BROADCAST;
  159297. + break;
  159298. + case gcvPOWER_IDLE:
  159299. + statesStored = gcvPOWER_IDLE_BROADCAST;
  159300. + break;
  159301. + case gcvPOWER_SUSPEND:
  159302. + statesStored = gcvPOWER_SUSPEND_BROADCAST;
  159303. + break;
  159304. + case gcvPOWER_ON:
  159305. + statesStored = gcvPOWER_ON_AUTO;
  159306. + break;
  159307. + default:
  159308. + statesStored = device->statesStored[i];
  159309. + break;
  159310. + }
  159311. +
  159312. + /* Restore states. */
  159313. +#if gcdENABLE_VG
  159314. + if (i == gcvCORE_VG)
  159315. + {
  159316. + status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, statesStored);
  159317. + }
  159318. + else
  159319. +#endif
  159320. + {
  159321. + status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, statesStored);
  159322. + }
  159323. +
  159324. + if (gcmIS_ERROR(status))
  159325. + {
  159326. + return -1;
  159327. + }
  159328. + }
  159329. + }
  159330. +
  159331. + return 0;
  159332. +}
  159333. +
  159334. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  159335. +static const struct of_device_id mxs_gpu_dt_ids[] = {
  159336. + { .compatible = "fsl,imx6q-gpu", },
  159337. + {/* sentinel */}
  159338. +};
  159339. +MODULE_DEVICE_TABLE(of, mxs_gpu_dt_ids);
  159340. +
  159341. +#ifdef CONFIG_PM
  159342. +static int gpu_runtime_suspend(struct device *dev)
  159343. +{
  159344. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 7)
  159345. + release_bus_freq(BUS_FREQ_HIGH);
  159346. +#endif
  159347. + return 0;
  159348. +}
  159349. +
  159350. +static int gpu_runtime_resume(struct device *dev)
  159351. +{
  159352. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 7)
  159353. + request_bus_freq(BUS_FREQ_HIGH);
  159354. +#endif
  159355. + return 0;
  159356. +}
  159357. +
  159358. +static int gpu_system_suspend(struct device *dev)
  159359. +{
  159360. + pm_message_t state={0};
  159361. + return gpu_suspend(to_platform_device(dev), state);
  159362. +}
  159363. +
  159364. +static int gpu_system_resume(struct device *dev)
  159365. +{
  159366. + return gpu_resume(to_platform_device(dev));
  159367. +}
  159368. +
  159369. +static const struct dev_pm_ops gpu_pm_ops = {
  159370. + SET_RUNTIME_PM_OPS(gpu_runtime_suspend, gpu_runtime_resume, NULL)
  159371. + SET_SYSTEM_SLEEP_PM_OPS(gpu_system_suspend, gpu_system_resume)
  159372. +};
  159373. +#endif
  159374. +#endif
  159375. +
  159376. +static struct platform_driver gpu_driver = {
  159377. + .probe = gpu_probe,
  159378. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
  159379. + .remove = gpu_remove,
  159380. +#else
  159381. + .remove = __devexit_p(gpu_remove),
  159382. +#endif
  159383. +
  159384. + .suspend = gpu_suspend,
  159385. + .resume = gpu_resume,
  159386. +
  159387. + .driver = {
  159388. + .name = DEVICE_NAME,
  159389. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  159390. + .of_match_table = mxs_gpu_dt_ids,
  159391. +#if CONFIG_PM
  159392. + .pm = &gpu_pm_ops,
  159393. +#endif
  159394. +#endif
  159395. + }
  159396. +};
  159397. +
  159398. +#if 0 /*CONFIG_DOVE_GPU*/
  159399. +static struct resource gpu_resources[] = {
  159400. + {
  159401. + .name = "gpu_irq",
  159402. + .flags = IORESOURCE_IRQ,
  159403. + },
  159404. + {
  159405. + .name = "gpu_base",
  159406. + .flags = IORESOURCE_MEM,
  159407. + },
  159408. + {
  159409. + .name = "gpu_mem",
  159410. + .flags = IORESOURCE_MEM,
  159411. + },
  159412. +};
  159413. +
  159414. +static struct platform_device * gpu_device;
  159415. +#endif
  159416. +
  159417. +static int __init gpu_init(void)
  159418. +{
  159419. + int ret = 0;
  159420. +
  159421. +#if 0 /*ndef CONFIG_DOVE_GPU*/
  159422. + gpu_resources[0].start = gpu_resources[0].end = irqLine;
  159423. +
  159424. + gpu_resources[1].start = registerMemBase;
  159425. + gpu_resources[1].end = registerMemBase + registerMemSize - 1;
  159426. +
  159427. + gpu_resources[2].start = contiguousBase;
  159428. + gpu_resources[2].end = contiguousBase + contiguousSize - 1;
  159429. +
  159430. + /* Allocate device */
  159431. + gpu_device = platform_device_alloc(DEVICE_NAME, -1);
  159432. + if (!gpu_device)
  159433. + {
  159434. + printk(KERN_ERR "galcore: platform_device_alloc failed.\n");
  159435. + ret = -ENOMEM;
  159436. + goto out;
  159437. + }
  159438. +
  159439. + /* Insert resource */
  159440. + ret = platform_device_add_resources(gpu_device, gpu_resources, 3);
  159441. + if (ret)
  159442. + {
  159443. + printk(KERN_ERR "galcore: platform_device_add_resources failed.\n");
  159444. + goto put_dev;
  159445. + }
  159446. +
  159447. + /* Add device */
  159448. + ret = platform_device_add(gpu_device);
  159449. + if (ret)
  159450. + {
  159451. + printk(KERN_ERR "galcore: platform_device_add failed.\n");
  159452. + goto put_dev;
  159453. + }
  159454. +#endif
  159455. +
  159456. + ret = platform_driver_register(&gpu_driver);
  159457. + if (!ret)
  159458. + {
  159459. + goto out;
  159460. + }
  159461. +
  159462. +#if 0 /*ndef CONFIG_DOVE_GPU*/
  159463. + platform_device_del(gpu_device);
  159464. +put_dev:
  159465. + platform_device_put(gpu_device);
  159466. +#endif
  159467. +
  159468. +out:
  159469. + return ret;
  159470. +}
  159471. +
  159472. +static void __exit gpu_exit(void)
  159473. +{
  159474. + platform_driver_unregister(&gpu_driver);
  159475. +#if 0 /*ndef CONFIG_DOVE_GPU*/
  159476. + platform_device_unregister(gpu_device);
  159477. +#endif
  159478. +}
  159479. +
  159480. +module_init(gpu_init);
  159481. +module_exit(gpu_exit);
  159482. +
  159483. +#endif
  159484. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c
  159485. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c 1970-01-01 01:00:00.000000000 +0100
  159486. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c 2014-08-20 19:23:53.570845890 +0200
  159487. @@ -0,0 +1,481 @@
  159488. +/****************************************************************************
  159489. +*
  159490. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  159491. +*
  159492. +* This program is free software; you can redistribute it and/or modify
  159493. +* it under the terms of the GNU General Public License as published by
  159494. +* the Free Software Foundation; either version 2 of the license, or
  159495. +* (at your option) any later version.
  159496. +*
  159497. +* This program is distributed in the hope that it will be useful,
  159498. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  159499. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  159500. +* GNU General Public License for more details.
  159501. +*
  159502. +* You should have received a copy of the GNU General Public License
  159503. +* along with this program; if not write to the Free Software
  159504. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  159505. +*
  159506. +*****************************************************************************/
  159507. +
  159508. +
  159509. +#include "gc_hal_kernel_linux.h"
  159510. +
  159511. +#define _GC_OBJ_ZONE gcvZONE_KERNEL
  159512. +
  159513. +/******************************************************************************\
  159514. +******************************* gckKERNEL API Code ******************************
  159515. +\******************************************************************************/
  159516. +
  159517. +/*******************************************************************************
  159518. +**
  159519. +** gckKERNEL_QueryVideoMemory
  159520. +**
  159521. +** Query the amount of video memory.
  159522. +**
  159523. +** INPUT:
  159524. +**
  159525. +** gckKERNEL Kernel
  159526. +** Pointer to an gckKERNEL object.
  159527. +**
  159528. +** OUTPUT:
  159529. +**
  159530. +** gcsHAL_INTERFACE * Interface
  159531. +** Pointer to an gcsHAL_INTERFACE structure that will be filled in with
  159532. +** the memory information.
  159533. +*/
  159534. +gceSTATUS
  159535. +gckKERNEL_QueryVideoMemory(
  159536. + IN gckKERNEL Kernel,
  159537. + OUT gcsHAL_INTERFACE * Interface
  159538. + )
  159539. +{
  159540. + gckGALDEVICE device;
  159541. +
  159542. + gcmkHEADER_ARG("Kernel=%p", Kernel);
  159543. +
  159544. + /* Verify the arguments. */
  159545. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  159546. + gcmkVERIFY_ARGUMENT(Interface != NULL);
  159547. +
  159548. + /* Extract the pointer to the gckGALDEVICE class. */
  159549. + device = (gckGALDEVICE) Kernel->context;
  159550. +
  159551. + /* Get internal memory size and physical address. */
  159552. + Interface->u.QueryVideoMemory.internalSize = device->internalSize;
  159553. + Interface->u.QueryVideoMemory.internalPhysical = device->internalPhysicalName;
  159554. +
  159555. + /* Get external memory size and physical address. */
  159556. + Interface->u.QueryVideoMemory.externalSize = device->externalSize;
  159557. + Interface->u.QueryVideoMemory.externalPhysical = device->externalPhysicalName;
  159558. +
  159559. + /* Get contiguous memory size and physical address. */
  159560. + Interface->u.QueryVideoMemory.contiguousSize = device->contiguousSize;
  159561. + Interface->u.QueryVideoMemory.contiguousPhysical = device->contiguousPhysicalName;
  159562. +
  159563. + /* Success. */
  159564. + gcmkFOOTER_NO();
  159565. + return gcvSTATUS_OK;
  159566. +}
  159567. +
  159568. +/*******************************************************************************
  159569. +**
  159570. +** gckKERNEL_GetVideoMemoryPool
  159571. +**
  159572. +** Get the gckVIDMEM object belonging to the specified pool.
  159573. +**
  159574. +** INPUT:
  159575. +**
  159576. +** gckKERNEL Kernel
  159577. +** Pointer to an gckKERNEL object.
  159578. +**
  159579. +** gcePOOL Pool
  159580. +** Pool to query gckVIDMEM object for.
  159581. +**
  159582. +** OUTPUT:
  159583. +**
  159584. +** gckVIDMEM * VideoMemory
  159585. +** Pointer to a variable that will hold the pointer to the gckVIDMEM
  159586. +** object belonging to the requested pool.
  159587. +*/
  159588. +gceSTATUS
  159589. +gckKERNEL_GetVideoMemoryPool(
  159590. + IN gckKERNEL Kernel,
  159591. + IN gcePOOL Pool,
  159592. + OUT gckVIDMEM * VideoMemory
  159593. + )
  159594. +{
  159595. + gckGALDEVICE device;
  159596. + gckVIDMEM videoMemory;
  159597. +
  159598. + gcmkHEADER_ARG("Kernel=%p Pool=%d", Kernel, Pool);
  159599. +
  159600. + /* Verify the arguments. */
  159601. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  159602. + gcmkVERIFY_ARGUMENT(VideoMemory != NULL);
  159603. +
  159604. + /* Extract the pointer to the gckGALDEVICE class. */
  159605. + device = (gckGALDEVICE) Kernel->context;
  159606. +
  159607. + /* Dispatch on pool. */
  159608. + switch (Pool)
  159609. + {
  159610. + case gcvPOOL_LOCAL_INTERNAL:
  159611. + /* Internal memory. */
  159612. + videoMemory = device->internalVidMem;
  159613. + break;
  159614. +
  159615. + case gcvPOOL_LOCAL_EXTERNAL:
  159616. + /* External memory. */
  159617. + videoMemory = device->externalVidMem;
  159618. + break;
  159619. +
  159620. + case gcvPOOL_SYSTEM:
  159621. + /* System memory. */
  159622. + videoMemory = device->contiguousVidMem;
  159623. + break;
  159624. +
  159625. + default:
  159626. + /* Unknown pool. */
  159627. + videoMemory = NULL;
  159628. + }
  159629. +
  159630. + /* Return pointer to the gckVIDMEM object. */
  159631. + *VideoMemory = videoMemory;
  159632. +
  159633. + /* Return status. */
  159634. + gcmkFOOTER_ARG("*VideoMemory=%p", *VideoMemory);
  159635. + return (videoMemory == NULL) ? gcvSTATUS_OUT_OF_MEMORY : gcvSTATUS_OK;
  159636. +}
  159637. +
  159638. +/*******************************************************************************
  159639. +**
  159640. +** gckKERNEL_MapMemory
  159641. +**
  159642. +** Map video memory into the current process space.
  159643. +**
  159644. +** INPUT:
  159645. +**
  159646. +** gckKERNEL Kernel
  159647. +** Pointer to an gckKERNEL object.
  159648. +**
  159649. +** gctPHYS_ADDR Physical
  159650. +** Physical address of video memory to map.
  159651. +**
  159652. +** gctSIZE_T Bytes
  159653. +** Number of bytes to map.
  159654. +**
  159655. +** OUTPUT:
  159656. +**
  159657. +** gctPOINTER * Logical
  159658. +** Pointer to a variable that will hold the base address of the mapped
  159659. +** memory region.
  159660. +*/
  159661. +gceSTATUS
  159662. +gckKERNEL_MapMemory(
  159663. + IN gckKERNEL Kernel,
  159664. + IN gctPHYS_ADDR Physical,
  159665. + IN gctSIZE_T Bytes,
  159666. + OUT gctPOINTER * Logical
  159667. + )
  159668. +{
  159669. + gckKERNEL kernel = Kernel;
  159670. + gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
  159671. +
  159672. + return gckOS_MapMemory(Kernel->os, physical, Bytes, Logical);
  159673. +}
  159674. +
  159675. +/*******************************************************************************
  159676. +**
  159677. +** gckKERNEL_UnmapMemory
  159678. +**
  159679. +** Unmap video memory from the current process space.
  159680. +**
  159681. +** INPUT:
  159682. +**
  159683. +** gckKERNEL Kernel
  159684. +** Pointer to an gckKERNEL object.
  159685. +**
  159686. +** gctPHYS_ADDR Physical
  159687. +** Physical address of video memory to map.
  159688. +**
  159689. +** gctSIZE_T Bytes
  159690. +** Number of bytes to map.
  159691. +**
  159692. +** gctPOINTER Logical
  159693. +** Base address of the mapped memory region.
  159694. +**
  159695. +** OUTPUT:
  159696. +**
  159697. +** Nothing.
  159698. +*/
  159699. +gceSTATUS
  159700. +gckKERNEL_UnmapMemory(
  159701. + IN gckKERNEL Kernel,
  159702. + IN gctPHYS_ADDR Physical,
  159703. + IN gctSIZE_T Bytes,
  159704. + IN gctPOINTER Logical
  159705. + )
  159706. +{
  159707. + gckKERNEL kernel = Kernel;
  159708. + gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
  159709. +
  159710. + return gckOS_UnmapMemory(Kernel->os, physical, Bytes, Logical);
  159711. +}
  159712. +
  159713. +/*******************************************************************************
  159714. +**
  159715. +** gckKERNEL_MapVideoMemory
  159716. +**
  159717. +** Get the logical address for a hardware specific memory address for the
  159718. +** current process.
  159719. +**
  159720. +** INPUT:
  159721. +**
  159722. +** gckKERNEL Kernel
  159723. +** Pointer to an gckKERNEL object.
  159724. +**
  159725. +** gctBOOL InUserSpace
  159726. +** gcvTRUE to map the memory into the user space.
  159727. +**
  159728. +** gctUINT32 Address
  159729. +** Hardware specific memory address.
  159730. +**
  159731. +** OUTPUT:
  159732. +**
  159733. +** gctPOINTER * Logical
  159734. +** Pointer to a variable that will hold the logical address of the
  159735. +** specified memory address.
  159736. +*/
  159737. +gceSTATUS
  159738. +gckKERNEL_MapVideoMemoryEx(
  159739. + IN gckKERNEL Kernel,
  159740. + IN gceCORE Core,
  159741. + IN gctBOOL InUserSpace,
  159742. + IN gctUINT32 Address,
  159743. + OUT gctPOINTER * Logical
  159744. + )
  159745. +{
  159746. + gckGALDEVICE device;
  159747. + PLINUX_MDL mdl;
  159748. + PLINUX_MDL_MAP mdlMap;
  159749. + gcePOOL pool;
  159750. + gctUINT32 offset, base;
  159751. + gceSTATUS status;
  159752. + gctPOINTER logical;
  159753. +
  159754. + gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x",
  159755. + Kernel, InUserSpace, Address);
  159756. +
  159757. + /* Verify the arguments. */
  159758. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  159759. + gcmkVERIFY_ARGUMENT(Logical != NULL);
  159760. +
  159761. + /* Extract the pointer to the gckGALDEVICE class. */
  159762. + device = (gckGALDEVICE) Kernel->context;
  159763. +
  159764. +#if gcdENABLE_VG
  159765. + if (Core == gcvCORE_VG)
  159766. + {
  159767. + /* Split the memory address into a pool type and offset. */
  159768. + gcmkONERROR(
  159769. + gckVGHARDWARE_SplitMemory(Kernel->vg->hardware, Address, &pool, &offset));
  159770. + }
  159771. + else
  159772. +#endif
  159773. + {
  159774. + /* Split the memory address into a pool type and offset. */
  159775. + gcmkONERROR(
  159776. + gckHARDWARE_SplitMemory(Kernel->hardware, Address, &pool, &offset));
  159777. + }
  159778. +
  159779. + /* Dispatch on pool. */
  159780. + switch (pool)
  159781. + {
  159782. + case gcvPOOL_LOCAL_INTERNAL:
  159783. + /* Internal memory. */
  159784. + logical = device->internalLogical;
  159785. + break;
  159786. +
  159787. + case gcvPOOL_LOCAL_EXTERNAL:
  159788. + /* External memory. */
  159789. + logical = device->externalLogical;
  159790. + break;
  159791. +
  159792. + case gcvPOOL_SYSTEM:
  159793. + /* System memory. */
  159794. + if (device->contiguousMapped)
  159795. + {
  159796. + logical = device->contiguousBase;
  159797. + }
  159798. + else
  159799. + {
  159800. + gctINT processID;
  159801. + gckOS_GetProcessID(&processID);
  159802. +
  159803. + mdl = (PLINUX_MDL) device->contiguousPhysical;
  159804. +
  159805. + mdlMap = FindMdlMap(mdl, processID);
  159806. + gcmkASSERT(mdlMap);
  159807. +
  159808. + logical = (gctPOINTER) mdlMap->vmaAddr;
  159809. + }
  159810. +#if gcdENABLE_VG
  159811. + if (Core == gcvCORE_VG)
  159812. + {
  159813. + gcmkVERIFY_OK(
  159814. + gckVGHARDWARE_SplitMemory(Kernel->vg->hardware,
  159815. + device->contiguousVidMem->baseAddress,
  159816. + &pool,
  159817. + &base));
  159818. + }
  159819. + else
  159820. +#endif
  159821. + {
  159822. + gctUINT32 baseAddress = 0;
  159823. +
  159824. + if (Kernel->hardware->mmuVersion == 0)
  159825. + {
  159826. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  159827. + }
  159828. +
  159829. + gcmkVERIFY_OK(
  159830. + gckHARDWARE_SplitMemory(Kernel->hardware,
  159831. + device->contiguousVidMem->baseAddress - baseAddress,
  159832. + &pool,
  159833. + &base));
  159834. + }
  159835. + offset -= base;
  159836. + break;
  159837. +
  159838. + default:
  159839. + /* Invalid memory pool. */
  159840. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  159841. + }
  159842. +
  159843. + /* Build logical address of specified address. */
  159844. + *Logical = (gctPOINTER) ((gctUINT8_PTR) logical + offset);
  159845. +
  159846. + /* Success. */
  159847. + gcmkFOOTER_ARG("*Logical=%p", *Logical);
  159848. + return gcvSTATUS_OK;
  159849. +
  159850. +OnError:
  159851. + /* Retunn the status. */
  159852. + gcmkFOOTER();
  159853. + return status;
  159854. +}
  159855. +
  159856. +/*******************************************************************************
  159857. +**
  159858. +** gckKERNEL_MapVideoMemory
  159859. +**
  159860. +** Get the logical address for a hardware specific memory address for the
  159861. +** current process.
  159862. +**
  159863. +** INPUT:
  159864. +**
  159865. +** gckKERNEL Kernel
  159866. +** Pointer to an gckKERNEL object.
  159867. +**
  159868. +** gctBOOL InUserSpace
  159869. +** gcvTRUE to map the memory into the user space.
  159870. +**
  159871. +** gctUINT32 Address
  159872. +** Hardware specific memory address.
  159873. +**
  159874. +** OUTPUT:
  159875. +**
  159876. +** gctPOINTER * Logical
  159877. +** Pointer to a variable that will hold the logical address of the
  159878. +** specified memory address.
  159879. +*/
  159880. +gceSTATUS
  159881. +gckKERNEL_MapVideoMemory(
  159882. + IN gckKERNEL Kernel,
  159883. + IN gctBOOL InUserSpace,
  159884. + IN gctUINT32 Address,
  159885. + OUT gctPOINTER * Logical
  159886. + )
  159887. +{
  159888. + return gckKERNEL_MapVideoMemoryEx(Kernel, gcvCORE_MAJOR, InUserSpace, Address, Logical);
  159889. +}
  159890. +/*******************************************************************************
  159891. +**
  159892. +** gckKERNEL_Notify
  159893. +**
  159894. +** This function iscalled by clients to notify the gckKERNRL object of an event.
  159895. +**
  159896. +** INPUT:
  159897. +**
  159898. +** gckKERNEL Kernel
  159899. +** Pointer to an gckKERNEL object.
  159900. +**
  159901. +** gceNOTIFY Notification
  159902. +** Notification event.
  159903. +**
  159904. +** OUTPUT:
  159905. +**
  159906. +** Nothing.
  159907. +*/
  159908. +gceSTATUS
  159909. +gckKERNEL_Notify(
  159910. + IN gckKERNEL Kernel,
  159911. + IN gceNOTIFY Notification,
  159912. + IN gctBOOL Data
  159913. + )
  159914. +{
  159915. + gceSTATUS status;
  159916. +
  159917. + gcmkHEADER_ARG("Kernel=%p Notification=%d Data=%d",
  159918. + Kernel, Notification, Data);
  159919. +
  159920. + /* Verify the arguments. */
  159921. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  159922. +
  159923. + /* Dispatch on notifcation. */
  159924. + switch (Notification)
  159925. + {
  159926. + case gcvNOTIFY_INTERRUPT:
  159927. + /* Process the interrupt. */
  159928. +#if COMMAND_PROCESSOR_VERSION > 1
  159929. + status = gckINTERRUPT_Notify(Kernel->interrupt, Data);
  159930. +#else
  159931. + status = gckHARDWARE_Interrupt(Kernel->hardware, Data);
  159932. +#endif
  159933. + break;
  159934. +
  159935. + default:
  159936. + status = gcvSTATUS_OK;
  159937. + break;
  159938. + }
  159939. +
  159940. + /* Success. */
  159941. + gcmkFOOTER();
  159942. + return status;
  159943. +}
  159944. +
  159945. +gceSTATUS
  159946. +gckKERNEL_QuerySettings(
  159947. + IN gckKERNEL Kernel,
  159948. + OUT gcsKERNEL_SETTINGS * Settings
  159949. + )
  159950. +{
  159951. + gckGALDEVICE device;
  159952. +
  159953. + gcmkHEADER_ARG("Kernel=%p", Kernel);
  159954. +
  159955. + /* Verify the arguments. */
  159956. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  159957. + gcmkVERIFY_ARGUMENT(Settings != gcvNULL);
  159958. +
  159959. + /* Extract the pointer to the gckGALDEVICE class. */
  159960. + device = (gckGALDEVICE) Kernel->context;
  159961. +
  159962. + /* Fill in signal. */
  159963. + Settings->signal = device->signal;
  159964. +
  159965. + /* Success. */
  159966. + gcmkFOOTER_ARG("Settings->signal=%d", Settings->signal);
  159967. + return gcvSTATUS_OK;
  159968. +}
  159969. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
  159970. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h 1970-01-01 01:00:00.000000000 +0100
  159971. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h 2014-08-20 19:23:53.570845890 +0200
  159972. @@ -0,0 +1,94 @@
  159973. +/****************************************************************************
  159974. +*
  159975. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  159976. +*
  159977. +* This program is free software; you can redistribute it and/or modify
  159978. +* it under the terms of the GNU General Public License as published by
  159979. +* the Free Software Foundation; either version 2 of the license, or
  159980. +* (at your option) any later version.
  159981. +*
  159982. +* This program is distributed in the hope that it will be useful,
  159983. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  159984. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  159985. +* GNU General Public License for more details.
  159986. +*
  159987. +* You should have received a copy of the GNU General Public License
  159988. +* along with this program; if not write to the Free Software
  159989. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  159990. +*
  159991. +*****************************************************************************/
  159992. +
  159993. +
  159994. +#ifndef __gc_hal_kernel_linux_h_
  159995. +#define __gc_hal_kernel_linux_h_
  159996. +
  159997. +#include <linux/version.h>
  159998. +#include <linux/init.h>
  159999. +#include <linux/module.h>
  160000. +#include <linux/fs.h>
  160001. +#include <linux/mm.h>
  160002. +#include <linux/sched.h>
  160003. +#include <linux/signal.h>
  160004. +#ifdef FLAREON
  160005. +# include <asm/arch-realview/dove_gpio_irq.h>
  160006. +#endif
  160007. +#include <linux/interrupt.h>
  160008. +#include <linux/vmalloc.h>
  160009. +#include <linux/dma-mapping.h>
  160010. +#include <linux/kthread.h>
  160011. +
  160012. +#ifdef MODVERSIONS
  160013. +# include <linux/modversions.h>
  160014. +#endif
  160015. +#include <asm/io.h>
  160016. +#include <asm/uaccess.h>
  160017. +
  160018. +#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
  160019. +#include <linux/clk.h>
  160020. +#include <linux/regulator/consumer.h>
  160021. +#endif
  160022. +
  160023. +#define NTSTRSAFE_NO_CCH_FUNCTIONS
  160024. +#include "gc_hal.h"
  160025. +#include "gc_hal_driver.h"
  160026. +#include "gc_hal_kernel.h"
  160027. +#include "gc_hal_kernel_device.h"
  160028. +#include "gc_hal_kernel_os.h"
  160029. +#include "gc_hal_kernel_debugfs.h"
  160030. +
  160031. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
  160032. +#define FIND_TASK_BY_PID(x) pid_task(find_vpid(x), PIDTYPE_PID)
  160033. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  160034. +#define FIND_TASK_BY_PID(x) find_task_by_vpid(x)
  160035. +#else
  160036. +#define FIND_TASK_BY_PID(x) find_task_by_pid(x)
  160037. +#endif
  160038. +
  160039. +#define _WIDE(string) L##string
  160040. +#define WIDE(string) _WIDE(string)
  160041. +
  160042. +#define countof(a) (sizeof(a) / sizeof(a[0]))
  160043. +
  160044. +#define DRV_NAME "galcore"
  160045. +
  160046. +#define GetPageCount(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
  160047. +
  160048. +#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,7,0)
  160049. +#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP)
  160050. +#else
  160051. +#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED)
  160052. +#endif
  160053. +
  160054. +static inline gctINT
  160055. +GetOrder(
  160056. + IN gctINT numPages
  160057. + )
  160058. +{
  160059. + gctINT order = 0;
  160060. +
  160061. + while ((1 << order) < numPages) order++;
  160062. +
  160063. + return order;
  160064. +}
  160065. +
  160066. +#endif /* __gc_hal_kernel_linux_h_ */
  160067. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c
  160068. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c 1970-01-01 01:00:00.000000000 +0100
  160069. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c 2014-08-20 19:23:53.570845890 +0200
  160070. @@ -0,0 +1,32 @@
  160071. +/****************************************************************************
  160072. +*
  160073. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  160074. +*
  160075. +* This program is free software; you can redistribute it and/or modify
  160076. +* it under the terms of the GNU General Public License as published by
  160077. +* the Free Software Foundation; either version 2 of the license, or
  160078. +* (at your option) any later version.
  160079. +*
  160080. +* This program is distributed in the hope that it will be useful,
  160081. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  160082. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  160083. +* GNU General Public License for more details.
  160084. +*
  160085. +* You should have received a copy of the GNU General Public License
  160086. +* along with this program; if not write to the Free Software
  160087. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  160088. +*
  160089. +*****************************************************************************/
  160090. +
  160091. +
  160092. +#include "gc_hal_kernel_linux.h"
  160093. +
  160094. +gctINT
  160095. +gckMATH_ModuloInt(
  160096. + IN gctINT X,
  160097. + IN gctINT Y
  160098. + )
  160099. +{
  160100. + if(Y ==0) {return 0;}
  160101. + else {return X % Y;}
  160102. +}
  160103. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
  160104. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c 1970-01-01 01:00:00.000000000 +0100
  160105. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c 2014-08-20 19:31:46.136869040 +0200
  160106. @@ -0,0 +1,9019 @@
  160107. +/****************************************************************************
  160108. +*
  160109. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  160110. +*
  160111. +* This program is free software; you can redistribute it and/or modify
  160112. +* it under the terms of the GNU General Public License as published by
  160113. +* the Free Software Foundation; either version 2 of the license, or
  160114. +* (at your option) any later version.
  160115. +*
  160116. +* This program is distributed in the hope that it will be useful,
  160117. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  160118. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  160119. +* GNU General Public License for more details.
  160120. +*
  160121. +* You should have received a copy of the GNU General Public License
  160122. +* along with this program; if not write to the Free Software
  160123. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  160124. +*
  160125. +*****************************************************************************/
  160126. +
  160127. +
  160128. +#include "gc_hal_kernel_linux.h"
  160129. +
  160130. +#include <linux/pagemap.h>
  160131. +#include <linux/seq_file.h>
  160132. +#include <linux/mm.h>
  160133. +#include <linux/mman.h>
  160134. +#include <linux/sched.h>
  160135. +#include <asm/atomic.h>
  160136. +#include <linux/dma-mapping.h>
  160137. +#include <linux/slab.h>
  160138. +#include <linux/idr.h>
  160139. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
  160140. +#include <mach/hardware.h>
  160141. +#endif
  160142. +#include <linux/workqueue.h>
  160143. +#include <linux/idr.h>
  160144. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
  160145. +#include <linux/math64.h>
  160146. +#endif
  160147. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  160148. +#include <linux/reset.h>
  160149. +static inline void imx_gpc_power_up_pu(bool flag) {}
  160150. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  160151. +#include <mach/common.h>
  160152. +#endif
  160153. +#include <linux/delay.h>
  160154. +#include <linux/pm_runtime.h>
  160155. +
  160156. +
  160157. +#if gcdANDROID_NATIVE_FENCE_SYNC
  160158. +#include <linux/file.h>
  160159. +#include "gc_hal_kernel_sync.h"
  160160. +#endif
  160161. +
  160162. +
  160163. +#define _GC_OBJ_ZONE gcvZONE_OS
  160164. +
  160165. +/*******************************************************************************
  160166. +***** Version Signature *******************************************************/
  160167. +
  160168. +#ifdef ANDROID
  160169. +const char * _PLATFORM = "\n\0$PLATFORM$Android$\n";
  160170. +#else
  160171. +const char * _PLATFORM = "\n\0$PLATFORM$Linux$\n";
  160172. +#endif
  160173. +
  160174. +#define USER_SIGNAL_TABLE_LEN_INIT 64
  160175. +#define gcdSUPPRESS_OOM_MESSAGE 1
  160176. +
  160177. +#define MEMORY_LOCK(os) \
  160178. + gcmkVERIFY_OK(gckOS_AcquireMutex( \
  160179. + (os), \
  160180. + (os)->memoryLock, \
  160181. + gcvINFINITE))
  160182. +
  160183. +#define MEMORY_UNLOCK(os) \
  160184. + gcmkVERIFY_OK(gckOS_ReleaseMutex((os), (os)->memoryLock))
  160185. +
  160186. +#define MEMORY_MAP_LOCK(os) \
  160187. + gcmkVERIFY_OK(gckOS_AcquireMutex( \
  160188. + (os), \
  160189. + (os)->memoryMapLock, \
  160190. + gcvINFINITE))
  160191. +
  160192. +#define MEMORY_MAP_UNLOCK(os) \
  160193. + gcmkVERIFY_OK(gckOS_ReleaseMutex((os), (os)->memoryMapLock))
  160194. +
  160195. +/* Protection bit when mapping memroy to user sapce */
  160196. +#define gcmkPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
  160197. +
  160198. +#if gcdNONPAGED_MEMORY_BUFFERABLE
  160199. +#define gcmkIOREMAP ioremap_wc
  160200. +#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
  160201. +#elif !gcdNONPAGED_MEMORY_CACHEABLE
  160202. +#define gcmkIOREMAP ioremap_nocache
  160203. +#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_noncached(x)
  160204. +#endif
  160205. +
  160206. +#if gcdSUPPRESS_OOM_MESSAGE
  160207. +#define gcdNOWARN __GFP_NOWARN
  160208. +#else
  160209. +#define gcdNOWARN 0
  160210. +#endif
  160211. +
  160212. +#define gcdINFINITE_TIMEOUT (60 * 1000)
  160213. +#define gcdDETECT_TIMEOUT 0
  160214. +#define gcdDETECT_DMA_ADDRESS 1
  160215. +#define gcdDETECT_DMA_STATE 1
  160216. +
  160217. +#define gcdUSE_NON_PAGED_MEMORY_CACHE 10
  160218. +
  160219. +/******************************************************************************\
  160220. +********************************** Structures **********************************
  160221. +\******************************************************************************/
  160222. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  160223. +typedef struct _gcsNonPagedMemoryCache
  160224. +{
  160225. +#ifndef NO_DMA_COHERENT
  160226. + gctINT size;
  160227. + gctSTRING addr;
  160228. + dma_addr_t dmaHandle;
  160229. +#else
  160230. + long order;
  160231. + struct page * page;
  160232. +#endif
  160233. +
  160234. + struct _gcsNonPagedMemoryCache * prev;
  160235. + struct _gcsNonPagedMemoryCache * next;
  160236. +}
  160237. +gcsNonPagedMemoryCache;
  160238. +#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */
  160239. +
  160240. +typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR;
  160241. +typedef struct _gcsUSER_MAPPING
  160242. +{
  160243. + /* Pointer to next mapping structure. */
  160244. + gcsUSER_MAPPING_PTR next;
  160245. +
  160246. + /* Physical address of this mapping. */
  160247. + gctUINT32 physical;
  160248. +
  160249. + /* Logical address of this mapping. */
  160250. + gctPOINTER logical;
  160251. +
  160252. + /* Number of bytes of this mapping. */
  160253. + gctSIZE_T bytes;
  160254. +
  160255. + /* Starting address of this mapping. */
  160256. + gctINT8_PTR start;
  160257. +
  160258. + /* Ending address of this mapping. */
  160259. + gctINT8_PTR end;
  160260. +}
  160261. +gcsUSER_MAPPING;
  160262. +
  160263. +typedef struct _gcsINTEGER_DB * gcsINTEGER_DB_PTR;
  160264. +typedef struct _gcsINTEGER_DB
  160265. +{
  160266. + struct idr idr;
  160267. + spinlock_t lock;
  160268. + gctINT curr;
  160269. +}
  160270. +gcsINTEGER_DB;
  160271. +
  160272. +struct _gckOS
  160273. +{
  160274. + /* Object. */
  160275. + gcsOBJECT object;
  160276. +
  160277. + /* Heap. */
  160278. + gckHEAP heap;
  160279. +
  160280. + /* Pointer to device */
  160281. + gckGALDEVICE device;
  160282. +
  160283. + /* Memory management */
  160284. + gctPOINTER memoryLock;
  160285. + gctPOINTER memoryMapLock;
  160286. +
  160287. + struct _LINUX_MDL *mdlHead;
  160288. + struct _LINUX_MDL *mdlTail;
  160289. +
  160290. + /* Kernel process ID. */
  160291. + gctUINT32 kernelProcessID;
  160292. +
  160293. + /* Signal management. */
  160294. +
  160295. + /* Lock. */
  160296. + gctPOINTER signalMutex;
  160297. +
  160298. + /* signal id database. */
  160299. + gcsINTEGER_DB signalDB;
  160300. +
  160301. +#if gcdANDROID_NATIVE_FENCE_SYNC
  160302. + /* Lock. */
  160303. + gctPOINTER syncPointMutex;
  160304. +
  160305. + /* sync point id database. */
  160306. + gcsINTEGER_DB syncPointDB;
  160307. +#endif
  160308. +
  160309. + gcsUSER_MAPPING_PTR userMap;
  160310. + gctPOINTER debugLock;
  160311. +
  160312. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  160313. + gctUINT cacheSize;
  160314. + gcsNonPagedMemoryCache * cacheHead;
  160315. + gcsNonPagedMemoryCache * cacheTail;
  160316. +#endif
  160317. +
  160318. + /* workqueue for os timer. */
  160319. + struct workqueue_struct * workqueue;
  160320. +};
  160321. +
  160322. +typedef struct _gcsSIGNAL * gcsSIGNAL_PTR;
  160323. +typedef struct _gcsSIGNAL
  160324. +{
  160325. + /* Kernel sync primitive. */
  160326. + struct completion obj;
  160327. +
  160328. + /* Manual reset flag. */
  160329. + gctBOOL manualReset;
  160330. +
  160331. + /* The reference counter. */
  160332. + atomic_t ref;
  160333. +
  160334. + /* The owner of the signal. */
  160335. + gctHANDLE process;
  160336. +
  160337. + gckHARDWARE hardware;
  160338. +
  160339. + /* ID. */
  160340. + gctUINT32 id;
  160341. +}
  160342. +gcsSIGNAL;
  160343. +
  160344. +#if gcdANDROID_NATIVE_FENCE_SYNC
  160345. +typedef struct _gcsSYNC_POINT * gcsSYNC_POINT_PTR;
  160346. +typedef struct _gcsSYNC_POINT
  160347. +{
  160348. + /* The reference counter. */
  160349. + atomic_t ref;
  160350. +
  160351. + /* State. */
  160352. + atomic_t state;
  160353. +
  160354. + /* timeline. */
  160355. + struct sync_timeline * timeline;
  160356. +
  160357. + /* ID. */
  160358. + gctUINT32 id;
  160359. +}
  160360. +gcsSYNC_POINT;
  160361. +#endif
  160362. +
  160363. +typedef struct _gcsPageInfo * gcsPageInfo_PTR;
  160364. +typedef struct _gcsPageInfo
  160365. +{
  160366. + struct page **pages;
  160367. + gctUINT32_PTR pageTable;
  160368. +}
  160369. +gcsPageInfo;
  160370. +
  160371. +typedef struct _gcsOSTIMER * gcsOSTIMER_PTR;
  160372. +typedef struct _gcsOSTIMER
  160373. +{
  160374. + struct delayed_work work;
  160375. + gctTIMERFUNCTION function;
  160376. + gctPOINTER data;
  160377. +} gcsOSTIMER;
  160378. +
  160379. +/******************************************************************************\
  160380. +******************************* Private Functions ******************************
  160381. +\******************************************************************************/
  160382. +
  160383. +static gctINT
  160384. +_GetProcessID(
  160385. + void
  160386. + )
  160387. +{
  160388. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  160389. + return task_tgid_vnr(current);
  160390. +#else
  160391. + return current->tgid;
  160392. +#endif
  160393. +}
  160394. +
  160395. +static gctINT
  160396. +_GetThreadID(
  160397. + void
  160398. + )
  160399. +{
  160400. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  160401. + return task_pid_vnr(current);
  160402. +#else
  160403. + return current->pid;
  160404. +#endif
  160405. +}
  160406. +
  160407. +static PLINUX_MDL
  160408. +_CreateMdl(
  160409. + IN gctINT ProcessID
  160410. + )
  160411. +{
  160412. + PLINUX_MDL mdl;
  160413. +
  160414. + gcmkHEADER_ARG("ProcessID=%d", ProcessID);
  160415. +
  160416. + mdl = (PLINUX_MDL)kzalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | gcdNOWARN);
  160417. + if (mdl == gcvNULL)
  160418. + {
  160419. + gcmkFOOTER_NO();
  160420. + return gcvNULL;
  160421. + }
  160422. +
  160423. + mdl->pid = ProcessID;
  160424. + mdl->maps = gcvNULL;
  160425. + mdl->prev = gcvNULL;
  160426. + mdl->next = gcvNULL;
  160427. +
  160428. + gcmkFOOTER_ARG("0x%X", mdl);
  160429. + return mdl;
  160430. +}
  160431. +
  160432. +static gceSTATUS
  160433. +_DestroyMdlMap(
  160434. + IN PLINUX_MDL Mdl,
  160435. + IN PLINUX_MDL_MAP MdlMap
  160436. + );
  160437. +
  160438. +static gceSTATUS
  160439. +_DestroyMdl(
  160440. + IN PLINUX_MDL Mdl
  160441. + )
  160442. +{
  160443. + PLINUX_MDL_MAP mdlMap, next;
  160444. +
  160445. + gcmkHEADER_ARG("Mdl=0x%X", Mdl);
  160446. +
  160447. + /* Verify the arguments. */
  160448. + gcmkVERIFY_ARGUMENT(Mdl != gcvNULL);
  160449. +
  160450. + mdlMap = Mdl->maps;
  160451. +
  160452. + while (mdlMap != gcvNULL)
  160453. + {
  160454. + next = mdlMap->next;
  160455. +
  160456. + gcmkVERIFY_OK(_DestroyMdlMap(Mdl, mdlMap));
  160457. +
  160458. + mdlMap = next;
  160459. + }
  160460. +
  160461. + kfree(Mdl);
  160462. +
  160463. + gcmkFOOTER_NO();
  160464. + return gcvSTATUS_OK;
  160465. +}
  160466. +
  160467. +static PLINUX_MDL_MAP
  160468. +_CreateMdlMap(
  160469. + IN PLINUX_MDL Mdl,
  160470. + IN gctINT ProcessID
  160471. + )
  160472. +{
  160473. + PLINUX_MDL_MAP mdlMap;
  160474. +
  160475. + gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
  160476. +
  160477. + mdlMap = (PLINUX_MDL_MAP)kmalloc(sizeof(struct _LINUX_MDL_MAP), GFP_KERNEL | gcdNOWARN);
  160478. + if (mdlMap == gcvNULL)
  160479. + {
  160480. + gcmkFOOTER_NO();
  160481. + return gcvNULL;
  160482. + }
  160483. +
  160484. + mdlMap->pid = ProcessID;
  160485. + mdlMap->vmaAddr = gcvNULL;
  160486. + mdlMap->vma = gcvNULL;
  160487. + mdlMap->count = 0;
  160488. +
  160489. + mdlMap->next = Mdl->maps;
  160490. + Mdl->maps = mdlMap;
  160491. +
  160492. + gcmkFOOTER_ARG("0x%X", mdlMap);
  160493. + return mdlMap;
  160494. +}
  160495. +
  160496. +static gceSTATUS
  160497. +_DestroyMdlMap(
  160498. + IN PLINUX_MDL Mdl,
  160499. + IN PLINUX_MDL_MAP MdlMap
  160500. + )
  160501. +{
  160502. + PLINUX_MDL_MAP prevMdlMap;
  160503. +
  160504. + gcmkHEADER_ARG("Mdl=0x%X MdlMap=0x%X", Mdl, MdlMap);
  160505. +
  160506. + /* Verify the arguments. */
  160507. + gcmkVERIFY_ARGUMENT(MdlMap != gcvNULL);
  160508. + gcmkASSERT(Mdl->maps != gcvNULL);
  160509. +
  160510. + if (Mdl->maps == MdlMap)
  160511. + {
  160512. + Mdl->maps = MdlMap->next;
  160513. + }
  160514. + else
  160515. + {
  160516. + prevMdlMap = Mdl->maps;
  160517. +
  160518. + while (prevMdlMap->next != MdlMap)
  160519. + {
  160520. + prevMdlMap = prevMdlMap->next;
  160521. +
  160522. + gcmkASSERT(prevMdlMap != gcvNULL);
  160523. + }
  160524. +
  160525. + prevMdlMap->next = MdlMap->next;
  160526. + }
  160527. +
  160528. + kfree(MdlMap);
  160529. +
  160530. + gcmkFOOTER_NO();
  160531. + return gcvSTATUS_OK;
  160532. +}
  160533. +
  160534. +extern PLINUX_MDL_MAP
  160535. +FindMdlMap(
  160536. + IN PLINUX_MDL Mdl,
  160537. + IN gctINT ProcessID
  160538. + )
  160539. +{
  160540. + PLINUX_MDL_MAP mdlMap;
  160541. +
  160542. + gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
  160543. + if(Mdl == gcvNULL)
  160544. + {
  160545. + gcmkFOOTER_NO();
  160546. + return gcvNULL;
  160547. + }
  160548. + mdlMap = Mdl->maps;
  160549. +
  160550. + while (mdlMap != gcvNULL)
  160551. + {
  160552. + if (mdlMap->pid == ProcessID)
  160553. + {
  160554. + gcmkFOOTER_ARG("0x%X", mdlMap);
  160555. + return mdlMap;
  160556. + }
  160557. +
  160558. + mdlMap = mdlMap->next;
  160559. + }
  160560. +
  160561. + gcmkFOOTER_NO();
  160562. + return gcvNULL;
  160563. +}
  160564. +
  160565. +void
  160566. +OnProcessExit(
  160567. + IN gckOS Os,
  160568. + IN gckKERNEL Kernel
  160569. + )
  160570. +{
  160571. +}
  160572. +
  160573. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
  160574. +static inline int
  160575. +is_vmalloc_addr(
  160576. + void *Addr
  160577. + )
  160578. +{
  160579. + unsigned long addr = (unsigned long)Addr;
  160580. +
  160581. + return addr >= VMALLOC_START && addr < VMALLOC_END;
  160582. +}
  160583. +#endif
  160584. +
  160585. +static void
  160586. +_NonContiguousFree(
  160587. + IN struct page ** Pages,
  160588. + IN gctUINT32 NumPages
  160589. + )
  160590. +{
  160591. + gctINT i;
  160592. +
  160593. + gcmkHEADER_ARG("Pages=0x%X, NumPages=%d", Pages, NumPages);
  160594. +
  160595. + gcmkASSERT(Pages != gcvNULL);
  160596. +
  160597. + for (i = 0; i < NumPages; i++)
  160598. + {
  160599. + __free_page(Pages[i]);
  160600. + }
  160601. +
  160602. + if (is_vmalloc_addr(Pages))
  160603. + {
  160604. + vfree(Pages);
  160605. + }
  160606. + else
  160607. + {
  160608. + kfree(Pages);
  160609. + }
  160610. +
  160611. + gcmkFOOTER_NO();
  160612. +}
  160613. +
  160614. +static struct page **
  160615. +_NonContiguousAlloc(
  160616. + IN gctUINT32 NumPages
  160617. + )
  160618. +{
  160619. + struct page ** pages;
  160620. + struct page *p;
  160621. + gctINT i, size;
  160622. +
  160623. + gcmkHEADER_ARG("NumPages=%lu", NumPages);
  160624. +
  160625. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
  160626. + if (NumPages > totalram_pages)
  160627. +#else
  160628. + if (NumPages > num_physpages)
  160629. +#endif
  160630. + {
  160631. + gcmkFOOTER_NO();
  160632. + return gcvNULL;
  160633. + }
  160634. +
  160635. + size = NumPages * sizeof(struct page *);
  160636. +
  160637. + pages = kmalloc(size, GFP_KERNEL | gcdNOWARN);
  160638. +
  160639. + if (!pages)
  160640. + {
  160641. + pages = vmalloc(size);
  160642. +
  160643. + if (!pages)
  160644. + {
  160645. + gcmkFOOTER_NO();
  160646. + return gcvNULL;
  160647. + }
  160648. + }
  160649. +
  160650. + for (i = 0; i < NumPages; i++)
  160651. + {
  160652. + p = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN);
  160653. +
  160654. + if (!p)
  160655. + {
  160656. + _NonContiguousFree(pages, i);
  160657. + gcmkFOOTER_NO();
  160658. + return gcvNULL;
  160659. + }
  160660. +
  160661. + pages[i] = p;
  160662. + }
  160663. +
  160664. + gcmkFOOTER_ARG("pages=0x%X", pages);
  160665. + return pages;
  160666. +}
  160667. +
  160668. +static inline struct page *
  160669. +_NonContiguousToPage(
  160670. + IN struct page ** Pages,
  160671. + IN gctUINT32 Index
  160672. + )
  160673. +{
  160674. + gcmkASSERT(Pages != gcvNULL);
  160675. + return Pages[Index];
  160676. +}
  160677. +
  160678. +static inline unsigned long
  160679. +_NonContiguousToPfn(
  160680. + IN struct page ** Pages,
  160681. + IN gctUINT32 Index
  160682. + )
  160683. +{
  160684. + gcmkASSERT(Pages != gcvNULL);
  160685. + return page_to_pfn(_NonContiguousToPage(Pages, Index));
  160686. +}
  160687. +
  160688. +static inline unsigned long
  160689. +_NonContiguousToPhys(
  160690. + IN struct page ** Pages,
  160691. + IN gctUINT32 Index
  160692. + )
  160693. +{
  160694. + gcmkASSERT(Pages != gcvNULL);
  160695. + return page_to_phys(_NonContiguousToPage(Pages, Index));
  160696. +}
  160697. +
  160698. +
  160699. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  160700. +
  160701. +static gctBOOL
  160702. +_AddNonPagedMemoryCache(
  160703. + gckOS Os,
  160704. +#ifndef NO_DMA_COHERENT
  160705. + gctINT Size,
  160706. + gctSTRING Addr,
  160707. + dma_addr_t DmaHandle
  160708. +#else
  160709. + long Order,
  160710. + struct page * Page
  160711. +#endif
  160712. + )
  160713. +{
  160714. + gcsNonPagedMemoryCache *cache;
  160715. +
  160716. + if (Os->cacheSize >= gcdUSE_NON_PAGED_MEMORY_CACHE)
  160717. + {
  160718. + return gcvFALSE;
  160719. + }
  160720. +
  160721. + /* Allocate the cache record */
  160722. + cache = (gcsNonPagedMemoryCache *)kmalloc(sizeof(gcsNonPagedMemoryCache), GFP_ATOMIC);
  160723. +
  160724. + if (cache == gcvNULL) return gcvFALSE;
  160725. +
  160726. +#ifndef NO_DMA_COHERENT
  160727. + cache->size = Size;
  160728. + cache->addr = Addr;
  160729. + cache->dmaHandle = DmaHandle;
  160730. +#else
  160731. + cache->order = Order;
  160732. + cache->page = Page;
  160733. +#endif
  160734. +
  160735. + /* Add to list */
  160736. + if (Os->cacheHead == gcvNULL)
  160737. + {
  160738. + cache->prev = gcvNULL;
  160739. + cache->next = gcvNULL;
  160740. + Os->cacheHead =
  160741. + Os->cacheTail = cache;
  160742. + }
  160743. + else
  160744. + {
  160745. + /* Add to the tail. */
  160746. + cache->prev = Os->cacheTail;
  160747. + cache->next = gcvNULL;
  160748. + Os->cacheTail->next = cache;
  160749. + Os->cacheTail = cache;
  160750. + }
  160751. +
  160752. + Os->cacheSize++;
  160753. +
  160754. + return gcvTRUE;
  160755. +}
  160756. +
  160757. +#ifndef NO_DMA_COHERENT
  160758. +static gctSTRING
  160759. +_GetNonPagedMemoryCache(
  160760. + gckOS Os,
  160761. + gctINT Size,
  160762. + dma_addr_t * DmaHandle
  160763. + )
  160764. +#else
  160765. +static struct page *
  160766. +_GetNonPagedMemoryCache(
  160767. + gckOS Os,
  160768. + long Order
  160769. + )
  160770. +#endif
  160771. +{
  160772. + gcsNonPagedMemoryCache *cache;
  160773. +#ifndef NO_DMA_COHERENT
  160774. + gctSTRING addr;
  160775. +#else
  160776. + struct page * page;
  160777. +#endif
  160778. +
  160779. + if (Os->cacheHead == gcvNULL) return gcvNULL;
  160780. +
  160781. + /* Find the right cache */
  160782. + cache = Os->cacheHead;
  160783. +
  160784. + while (cache != gcvNULL)
  160785. + {
  160786. +#ifndef NO_DMA_COHERENT
  160787. + if (cache->size == Size) break;
  160788. +#else
  160789. + if (cache->order == Order) break;
  160790. +#endif
  160791. +
  160792. + cache = cache->next;
  160793. + }
  160794. +
  160795. + if (cache == gcvNULL) return gcvNULL;
  160796. +
  160797. + /* Remove the cache from list */
  160798. + if (cache == Os->cacheHead)
  160799. + {
  160800. + Os->cacheHead = cache->next;
  160801. +
  160802. + if (Os->cacheHead == gcvNULL)
  160803. + {
  160804. + Os->cacheTail = gcvNULL;
  160805. + }
  160806. + }
  160807. + else
  160808. + {
  160809. + cache->prev->next = cache->next;
  160810. +
  160811. + if (cache == Os->cacheTail)
  160812. + {
  160813. + Os->cacheTail = cache->prev;
  160814. + }
  160815. + else
  160816. + {
  160817. + cache->next->prev = cache->prev;
  160818. + }
  160819. + }
  160820. +
  160821. + /* Destroy cache */
  160822. +#ifndef NO_DMA_COHERENT
  160823. + addr = cache->addr;
  160824. + *DmaHandle = cache->dmaHandle;
  160825. +#else
  160826. + page = cache->page;
  160827. +#endif
  160828. +
  160829. + kfree(cache);
  160830. +
  160831. + Os->cacheSize--;
  160832. +
  160833. +#ifndef NO_DMA_COHERENT
  160834. + return addr;
  160835. +#else
  160836. + return page;
  160837. +#endif
  160838. +}
  160839. +
  160840. +static void
  160841. +_FreeAllNonPagedMemoryCache(
  160842. + gckOS Os
  160843. + )
  160844. +{
  160845. + gcsNonPagedMemoryCache *cache, *nextCache;
  160846. +
  160847. + MEMORY_LOCK(Os);
  160848. +
  160849. + cache = Os->cacheHead;
  160850. +
  160851. + while (cache != gcvNULL)
  160852. + {
  160853. + if (cache != Os->cacheTail)
  160854. + {
  160855. + nextCache = cache->next;
  160856. + }
  160857. + else
  160858. + {
  160859. + nextCache = gcvNULL;
  160860. + }
  160861. +
  160862. + /* Remove the cache from list */
  160863. + if (cache == Os->cacheHead)
  160864. + {
  160865. + Os->cacheHead = cache->next;
  160866. +
  160867. + if (Os->cacheHead == gcvNULL)
  160868. + {
  160869. + Os->cacheTail = gcvNULL;
  160870. + }
  160871. + }
  160872. + else
  160873. + {
  160874. + cache->prev->next = cache->next;
  160875. +
  160876. + if (cache == Os->cacheTail)
  160877. + {
  160878. + Os->cacheTail = cache->prev;
  160879. + }
  160880. + else
  160881. + {
  160882. + cache->next->prev = cache->prev;
  160883. + }
  160884. + }
  160885. +
  160886. +#ifndef NO_DMA_COHERENT
  160887. + dma_free_coherent(gcvNULL,
  160888. + cache->size,
  160889. + cache->addr,
  160890. + cache->dmaHandle);
  160891. +#else
  160892. + free_pages((unsigned long)page_address(cache->page), cache->order);
  160893. +#endif
  160894. +
  160895. + kfree(cache);
  160896. +
  160897. + cache = nextCache;
  160898. + }
  160899. +
  160900. + MEMORY_UNLOCK(Os);
  160901. +}
  160902. +
  160903. +#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */
  160904. +
  160905. +/*******************************************************************************
  160906. +** Integer Id Management.
  160907. +*/
  160908. +gceSTATUS
  160909. +_AllocateIntegerId(
  160910. + IN gcsINTEGER_DB_PTR Database,
  160911. + IN gctPOINTER KernelPointer,
  160912. + OUT gctUINT32 *Id
  160913. + )
  160914. +{
  160915. + int result;
  160916. + gctINT next;
  160917. +
  160918. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
  160919. + idr_preload(GFP_KERNEL | gcdNOWARN);
  160920. +
  160921. + spin_lock(&Database->lock);
  160922. +
  160923. + next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
  160924. + result = idr_alloc(&Database->idr, KernelPointer, next, 0, GFP_ATOMIC);
  160925. +
  160926. + if (!result)
  160927. + {
  160928. + Database->curr = *Id;
  160929. + }
  160930. +
  160931. + spin_unlock(&Database->lock);
  160932. +
  160933. + idr_preload_end();
  160934. +
  160935. + if (result < 0)
  160936. + {
  160937. + return gcvSTATUS_OUT_OF_RESOURCES;
  160938. + }
  160939. +
  160940. + *Id = result;
  160941. +#else
  160942. +again:
  160943. + if (idr_pre_get(&Database->idr, GFP_KERNEL | gcdNOWARN) == 0)
  160944. + {
  160945. + return gcvSTATUS_OUT_OF_MEMORY;
  160946. + }
  160947. +
  160948. + spin_lock(&Database->lock);
  160949. +
  160950. + next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
  160951. +
  160952. + /* Try to get a id greater than current id. */
  160953. + result = idr_get_new_above(&Database->idr, KernelPointer, next, Id);
  160954. +
  160955. + if (!result)
  160956. + {
  160957. + Database->curr = *Id;
  160958. + }
  160959. +
  160960. + spin_unlock(&Database->lock);
  160961. +
  160962. + if (result == -EAGAIN)
  160963. + {
  160964. + goto again;
  160965. + }
  160966. +
  160967. + if (result != 0)
  160968. + {
  160969. + return gcvSTATUS_OUT_OF_RESOURCES;
  160970. + }
  160971. +#endif
  160972. +
  160973. + return gcvSTATUS_OK;
  160974. +}
  160975. +
  160976. +gceSTATUS
  160977. +_QueryIntegerId(
  160978. + IN gcsINTEGER_DB_PTR Database,
  160979. + IN gctUINT32 Id,
  160980. + OUT gctPOINTER * KernelPointer
  160981. + )
  160982. +{
  160983. + gctPOINTER pointer;
  160984. +
  160985. + spin_lock(&Database->lock);
  160986. +
  160987. + pointer = idr_find(&Database->idr, Id);
  160988. +
  160989. + spin_unlock(&Database->lock);
  160990. +
  160991. + if(pointer)
  160992. + {
  160993. + *KernelPointer = pointer;
  160994. + return gcvSTATUS_OK;
  160995. + }
  160996. + else
  160997. + {
  160998. + gcmkTRACE_ZONE(
  160999. + gcvLEVEL_ERROR, gcvZONE_OS,
  161000. + "%s(%d) Id = %d is not found",
  161001. + __FUNCTION__, __LINE__, Id);
  161002. +
  161003. + return gcvSTATUS_NOT_FOUND;
  161004. + }
  161005. +}
  161006. +
  161007. +gceSTATUS
  161008. +_DestroyIntegerId(
  161009. + IN gcsINTEGER_DB_PTR Database,
  161010. + IN gctUINT32 Id
  161011. + )
  161012. +{
  161013. + spin_lock(&Database->lock);
  161014. +
  161015. + idr_remove(&Database->idr, Id);
  161016. +
  161017. + spin_unlock(&Database->lock);
  161018. +
  161019. + return gcvSTATUS_OK;
  161020. +}
  161021. +
  161022. +static void
  161023. +_UnmapUserLogical(
  161024. + IN gctINT Pid,
  161025. + IN gctPOINTER Logical,
  161026. + IN gctUINT32 Size
  161027. +)
  161028. +{
  161029. + if (unlikely(current->mm == gcvNULL))
  161030. + {
  161031. + /* Do nothing if process is exiting. */
  161032. + return;
  161033. + }
  161034. +
  161035. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  161036. + if (vm_munmap((unsigned long)Logical, Size) < 0)
  161037. + {
  161038. + gcmkTRACE_ZONE(
  161039. + gcvLEVEL_WARNING, gcvZONE_OS,
  161040. + "%s(%d): vm_munmap failed",
  161041. + __FUNCTION__, __LINE__
  161042. + );
  161043. + }
  161044. +#else
  161045. + down_write(&current->mm->mmap_sem);
  161046. + if (do_munmap(current->mm, (unsigned long)Logical, Size) < 0)
  161047. + {
  161048. + gcmkTRACE_ZONE(
  161049. + gcvLEVEL_WARNING, gcvZONE_OS,
  161050. + "%s(%d): do_munmap failed",
  161051. + __FUNCTION__, __LINE__
  161052. + );
  161053. + }
  161054. + up_write(&current->mm->mmap_sem);
  161055. +#endif
  161056. +}
  161057. +
  161058. +gceSTATUS
  161059. +_QueryProcessPageTable(
  161060. + IN gctPOINTER Logical,
  161061. + OUT gctUINT32 * Address
  161062. + )
  161063. +{
  161064. + spinlock_t *lock;
  161065. + gctUINTPTR_T logical = (gctUINTPTR_T)Logical;
  161066. + pgd_t *pgd;
  161067. + pud_t *pud;
  161068. + pmd_t *pmd;
  161069. + pte_t *pte;
  161070. +
  161071. + if (!current->mm)
  161072. + {
  161073. + return gcvSTATUS_NOT_FOUND;
  161074. + }
  161075. +
  161076. + pgd = pgd_offset(current->mm, logical);
  161077. + if (pgd_none(*pgd) || pgd_bad(*pgd))
  161078. + {
  161079. + return gcvSTATUS_NOT_FOUND;
  161080. + }
  161081. +
  161082. + pud = pud_offset(pgd, logical);
  161083. + if (pud_none(*pud) || pud_bad(*pud))
  161084. + {
  161085. + return gcvSTATUS_NOT_FOUND;
  161086. + }
  161087. +
  161088. + pmd = pmd_offset(pud, logical);
  161089. + if (pmd_none(*pmd) || pmd_bad(*pmd))
  161090. + {
  161091. + return gcvSTATUS_NOT_FOUND;
  161092. + }
  161093. +
  161094. + pte = pte_offset_map_lock(current->mm, pmd, logical, &lock);
  161095. + if (!pte)
  161096. + {
  161097. + return gcvSTATUS_NOT_FOUND;
  161098. + }
  161099. +
  161100. + if (!pte_present(*pte))
  161101. + {
  161102. + pte_unmap_unlock(pte, lock);
  161103. + return gcvSTATUS_NOT_FOUND;
  161104. + }
  161105. +
  161106. + *Address = (pte_pfn(*pte) << PAGE_SHIFT) | (logical & ~PAGE_MASK);
  161107. + pte_unmap_unlock(pte, lock);
  161108. +
  161109. + return gcvSTATUS_OK;
  161110. +}
  161111. +
  161112. +/*******************************************************************************
  161113. +**
  161114. +** gckOS_Construct
  161115. +**
  161116. +** Construct a new gckOS object.
  161117. +**
  161118. +** INPUT:
  161119. +**
  161120. +** gctPOINTER Context
  161121. +** Pointer to the gckGALDEVICE class.
  161122. +**
  161123. +** OUTPUT:
  161124. +**
  161125. +** gckOS * Os
  161126. +** Pointer to a variable that will hold the pointer to the gckOS object.
  161127. +*/
  161128. +gceSTATUS
  161129. +gckOS_Construct(
  161130. + IN gctPOINTER Context,
  161131. + OUT gckOS * Os
  161132. + )
  161133. +{
  161134. + gckOS os;
  161135. + gceSTATUS status;
  161136. +
  161137. + gcmkHEADER_ARG("Context=0x%X", Context);
  161138. +
  161139. + /* Verify the arguments. */
  161140. + gcmkVERIFY_ARGUMENT(Os != gcvNULL);
  161141. +
  161142. + /* Allocate the gckOS object. */
  161143. + os = (gckOS) kmalloc(gcmSIZEOF(struct _gckOS), GFP_KERNEL | gcdNOWARN);
  161144. +
  161145. + if (os == gcvNULL)
  161146. + {
  161147. + /* Out of memory. */
  161148. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
  161149. + return gcvSTATUS_OUT_OF_MEMORY;
  161150. + }
  161151. +
  161152. + /* Zero the memory. */
  161153. + gckOS_ZeroMemory(os, gcmSIZEOF(struct _gckOS));
  161154. +
  161155. + /* Initialize the gckOS object. */
  161156. + os->object.type = gcvOBJ_OS;
  161157. +
  161158. + /* Set device device. */
  161159. + os->device = Context;
  161160. +
  161161. + /* IMPORTANT! No heap yet. */
  161162. + os->heap = gcvNULL;
  161163. +
  161164. + /* Initialize the memory lock. */
  161165. + gcmkONERROR(gckOS_CreateMutex(os, &os->memoryLock));
  161166. + gcmkONERROR(gckOS_CreateMutex(os, &os->memoryMapLock));
  161167. +
  161168. + /* Create debug lock mutex. */
  161169. + gcmkONERROR(gckOS_CreateMutex(os, &os->debugLock));
  161170. +
  161171. +
  161172. + os->mdlHead = os->mdlTail = gcvNULL;
  161173. +
  161174. + /* Get the kernel process ID. */
  161175. + gcmkONERROR(gckOS_GetProcessID(&os->kernelProcessID));
  161176. +
  161177. + /*
  161178. + * Initialize the signal manager.
  161179. + */
  161180. +
  161181. + /* Initialize mutex. */
  161182. + gcmkONERROR(gckOS_CreateMutex(os, &os->signalMutex));
  161183. +
  161184. + /* Initialize signal id database lock. */
  161185. + spin_lock_init(&os->signalDB.lock);
  161186. +
  161187. + /* Initialize signal id database. */
  161188. + idr_init(&os->signalDB.idr);
  161189. +
  161190. +#if gcdANDROID_NATIVE_FENCE_SYNC
  161191. + /*
  161192. + * Initialize the sync point manager.
  161193. + */
  161194. +
  161195. + /* Initialize mutex. */
  161196. + gcmkONERROR(gckOS_CreateMutex(os, &os->syncPointMutex));
  161197. +
  161198. + /* Initialize sync point id database lock. */
  161199. + spin_lock_init(&os->syncPointDB.lock);
  161200. +
  161201. + /* Initialize sync point id database. */
  161202. + idr_init(&os->syncPointDB.idr);
  161203. +#endif
  161204. +
  161205. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  161206. + os->cacheSize = 0;
  161207. + os->cacheHead = gcvNULL;
  161208. + os->cacheTail = gcvNULL;
  161209. +#endif
  161210. +
  161211. + /* Create a workqueue for os timer. */
  161212. + os->workqueue = create_singlethread_workqueue("galcore workqueue");
  161213. +
  161214. + if (os->workqueue == gcvNULL)
  161215. + {
  161216. + /* Out of memory. */
  161217. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  161218. + }
  161219. +
  161220. + /* Return pointer to the gckOS object. */
  161221. + *Os = os;
  161222. +
  161223. + /* Success. */
  161224. + gcmkFOOTER_ARG("*Os=0x%X", *Os);
  161225. + return gcvSTATUS_OK;
  161226. +
  161227. +OnError:
  161228. +
  161229. +#if gcdANDROID_NATIVE_FENCE_SYNC
  161230. + if (os->syncPointMutex != gcvNULL)
  161231. + {
  161232. + gcmkVERIFY_OK(
  161233. + gckOS_DeleteMutex(os, os->syncPointMutex));
  161234. + }
  161235. +#endif
  161236. +
  161237. + if (os->signalMutex != gcvNULL)
  161238. + {
  161239. + gcmkVERIFY_OK(
  161240. + gckOS_DeleteMutex(os, os->signalMutex));
  161241. + }
  161242. +
  161243. + if (os->heap != gcvNULL)
  161244. + {
  161245. + gcmkVERIFY_OK(
  161246. + gckHEAP_Destroy(os->heap));
  161247. + }
  161248. +
  161249. + if (os->memoryMapLock != gcvNULL)
  161250. + {
  161251. + gcmkVERIFY_OK(
  161252. + gckOS_DeleteMutex(os, os->memoryMapLock));
  161253. + }
  161254. +
  161255. + if (os->memoryLock != gcvNULL)
  161256. + {
  161257. + gcmkVERIFY_OK(
  161258. + gckOS_DeleteMutex(os, os->memoryLock));
  161259. + }
  161260. +
  161261. + if (os->debugLock != gcvNULL)
  161262. + {
  161263. + gcmkVERIFY_OK(
  161264. + gckOS_DeleteMutex(os, os->debugLock));
  161265. + }
  161266. +
  161267. + if (os->workqueue != gcvNULL)
  161268. + {
  161269. + destroy_workqueue(os->workqueue);
  161270. + }
  161271. +
  161272. + kfree(os);
  161273. +
  161274. + /* Return the error. */
  161275. + gcmkFOOTER();
  161276. + return status;
  161277. +}
  161278. +
  161279. +/*******************************************************************************
  161280. +**
  161281. +** gckOS_Destroy
  161282. +**
  161283. +** Destroy an gckOS object.
  161284. +**
  161285. +** INPUT:
  161286. +**
  161287. +** gckOS Os
  161288. +** Pointer to an gckOS object that needs to be destroyed.
  161289. +**
  161290. +** OUTPUT:
  161291. +**
  161292. +** Nothing.
  161293. +*/
  161294. +gceSTATUS
  161295. +gckOS_Destroy(
  161296. + IN gckOS Os
  161297. + )
  161298. +{
  161299. + gckHEAP heap;
  161300. +
  161301. + gcmkHEADER_ARG("Os=0x%X", Os);
  161302. +
  161303. + /* Verify the arguments. */
  161304. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161305. +
  161306. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  161307. + _FreeAllNonPagedMemoryCache(Os);
  161308. +#endif
  161309. +
  161310. +#if gcdANDROID_NATIVE_FENCE_SYNC
  161311. + /*
  161312. + * Destroy the sync point manager.
  161313. + */
  161314. +
  161315. + /* Destroy the mutex. */
  161316. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->syncPointMutex));
  161317. +#endif
  161318. +
  161319. + /*
  161320. + * Destroy the signal manager.
  161321. + */
  161322. +
  161323. + /* Destroy the mutex. */
  161324. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->signalMutex));
  161325. +
  161326. + if (Os->heap != gcvNULL)
  161327. + {
  161328. + /* Mark gckHEAP as gone. */
  161329. + heap = Os->heap;
  161330. + Os->heap = gcvNULL;
  161331. +
  161332. + /* Destroy the gckHEAP object. */
  161333. + gcmkVERIFY_OK(gckHEAP_Destroy(heap));
  161334. + }
  161335. +
  161336. + /* Destroy the memory lock. */
  161337. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->memoryMapLock));
  161338. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->memoryLock));
  161339. +
  161340. + /* Destroy debug lock mutex. */
  161341. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->debugLock));
  161342. +
  161343. + /* Wait for all works done. */
  161344. + flush_workqueue(Os->workqueue);
  161345. +
  161346. + /* Destory work queue. */
  161347. + destroy_workqueue(Os->workqueue);
  161348. +
  161349. + /* Flush the debug cache. */
  161350. + gcmkDEBUGFLUSH(~0U);
  161351. +
  161352. + /* Mark the gckOS object as unknown. */
  161353. + Os->object.type = gcvOBJ_UNKNOWN;
  161354. +
  161355. + /* Free the gckOS object. */
  161356. + kfree(Os);
  161357. +
  161358. + /* Success. */
  161359. + gcmkFOOTER_NO();
  161360. + return gcvSTATUS_OK;
  161361. +}
  161362. +
  161363. +static gctSTRING
  161364. +_CreateKernelVirtualMapping(
  161365. + IN PLINUX_MDL Mdl
  161366. + )
  161367. +{
  161368. + gctSTRING addr = 0;
  161369. + gctINT numPages = Mdl->numPages;
  161370. +
  161371. +#if gcdNONPAGED_MEMORY_CACHEABLE
  161372. + if (Mdl->contiguous)
  161373. + {
  161374. + addr = page_address(Mdl->u.contiguousPages);
  161375. + }
  161376. + else
  161377. + {
  161378. + addr = vmap(Mdl->u.nonContiguousPages,
  161379. + numPages,
  161380. + 0,
  161381. + PAGE_KERNEL);
  161382. +
  161383. + /* Trigger a page fault. */
  161384. + memset(addr, 0, numPages * PAGE_SIZE);
  161385. + }
  161386. +#else
  161387. + struct page ** pages;
  161388. + gctBOOL free = gcvFALSE;
  161389. + gctINT i;
  161390. +
  161391. + if (Mdl->contiguous)
  161392. + {
  161393. + pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN);
  161394. +
  161395. + if (!pages)
  161396. + {
  161397. + return gcvNULL;
  161398. + }
  161399. +
  161400. + for (i = 0; i < numPages; i++)
  161401. + {
  161402. + pages[i] = nth_page(Mdl->u.contiguousPages, i);
  161403. + }
  161404. +
  161405. + free = gcvTRUE;
  161406. + }
  161407. + else
  161408. + {
  161409. + pages = Mdl->u.nonContiguousPages;
  161410. + }
  161411. +
  161412. + /* ioremap() can't work on system memory since 2.6.38. */
  161413. + addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
  161414. +
  161415. + /* Trigger a page fault. */
  161416. + memset(addr, 0, numPages * PAGE_SIZE);
  161417. +
  161418. + if (free)
  161419. + {
  161420. + kfree(pages);
  161421. + }
  161422. +
  161423. +#endif
  161424. +
  161425. + return addr;
  161426. +}
  161427. +
  161428. +static void
  161429. +_DestoryKernelVirtualMapping(
  161430. + IN gctSTRING Addr
  161431. + )
  161432. +{
  161433. +#if !gcdNONPAGED_MEMORY_CACHEABLE
  161434. + vunmap(Addr);
  161435. +#endif
  161436. +}
  161437. +
  161438. +gceSTATUS
  161439. +gckOS_CreateKernelVirtualMapping(
  161440. + IN gctPHYS_ADDR Physical,
  161441. + OUT gctSIZE_T * PageCount,
  161442. + OUT gctPOINTER * Logical
  161443. + )
  161444. +{
  161445. + *PageCount = ((PLINUX_MDL)Physical)->numPages;
  161446. + *Logical = _CreateKernelVirtualMapping((PLINUX_MDL)Physical);
  161447. +
  161448. + return gcvSTATUS_OK;
  161449. +}
  161450. +
  161451. +gceSTATUS
  161452. +gckOS_DestroyKernelVirtualMapping(
  161453. + IN gctPOINTER Logical
  161454. + )
  161455. +{
  161456. + _DestoryKernelVirtualMapping((gctSTRING)Logical);
  161457. + return gcvSTATUS_OK;
  161458. +}
  161459. +
  161460. +/*******************************************************************************
  161461. +**
  161462. +** gckOS_Allocate
  161463. +**
  161464. +** Allocate memory.
  161465. +**
  161466. +** INPUT:
  161467. +**
  161468. +** gckOS Os
  161469. +** Pointer to an gckOS object.
  161470. +**
  161471. +** gctSIZE_T Bytes
  161472. +** Number of bytes to allocate.
  161473. +**
  161474. +** OUTPUT:
  161475. +**
  161476. +** gctPOINTER * Memory
  161477. +** Pointer to a variable that will hold the allocated memory location.
  161478. +*/
  161479. +gceSTATUS
  161480. +gckOS_Allocate(
  161481. + IN gckOS Os,
  161482. + IN gctSIZE_T Bytes,
  161483. + OUT gctPOINTER * Memory
  161484. + )
  161485. +{
  161486. + gceSTATUS status;
  161487. +
  161488. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
  161489. +
  161490. + /* Verify the arguments. */
  161491. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161492. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  161493. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  161494. +
  161495. + /* Do we have a heap? */
  161496. + if (Os->heap != gcvNULL)
  161497. + {
  161498. + /* Allocate from the heap. */
  161499. + gcmkONERROR(gckHEAP_Allocate(Os->heap, Bytes, Memory));
  161500. + }
  161501. + else
  161502. + {
  161503. + gcmkONERROR(gckOS_AllocateMemory(Os, Bytes, Memory));
  161504. + }
  161505. +
  161506. + /* Success. */
  161507. + gcmkFOOTER_ARG("*Memory=0x%X", *Memory);
  161508. + return gcvSTATUS_OK;
  161509. +
  161510. +OnError:
  161511. + /* Return the status. */
  161512. + gcmkFOOTER();
  161513. + return status;
  161514. +}
  161515. +
  161516. +/*******************************************************************************
  161517. +**
  161518. +** gckOS_Free
  161519. +**
  161520. +** Free allocated memory.
  161521. +**
  161522. +** INPUT:
  161523. +**
  161524. +** gckOS Os
  161525. +** Pointer to an gckOS object.
  161526. +**
  161527. +** gctPOINTER Memory
  161528. +** Pointer to memory allocation to free.
  161529. +**
  161530. +** OUTPUT:
  161531. +**
  161532. +** Nothing.
  161533. +*/
  161534. +gceSTATUS
  161535. +gckOS_Free(
  161536. + IN gckOS Os,
  161537. + IN gctPOINTER Memory
  161538. + )
  161539. +{
  161540. + gceSTATUS status;
  161541. +
  161542. + gcmkHEADER_ARG("Os=0x%X Memory=0x%X", Os, Memory);
  161543. +
  161544. + /* Verify the arguments. */
  161545. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161546. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  161547. +
  161548. + /* Do we have a heap? */
  161549. + if (Os->heap != gcvNULL)
  161550. + {
  161551. + /* Free from the heap. */
  161552. + gcmkONERROR(gckHEAP_Free(Os->heap, Memory));
  161553. + }
  161554. + else
  161555. + {
  161556. + gcmkONERROR(gckOS_FreeMemory(Os, Memory));
  161557. + }
  161558. +
  161559. + /* Success. */
  161560. + gcmkFOOTER_NO();
  161561. + return gcvSTATUS_OK;
  161562. +
  161563. +OnError:
  161564. + /* Return the status. */
  161565. + gcmkFOOTER();
  161566. + return status;
  161567. +}
  161568. +
  161569. +/*******************************************************************************
  161570. +**
  161571. +** gckOS_AllocateMemory
  161572. +**
  161573. +** Allocate memory wrapper.
  161574. +**
  161575. +** INPUT:
  161576. +**
  161577. +** gctSIZE_T Bytes
  161578. +** Number of bytes to allocate.
  161579. +**
  161580. +** OUTPUT:
  161581. +**
  161582. +** gctPOINTER * Memory
  161583. +** Pointer to a variable that will hold the allocated memory location.
  161584. +*/
  161585. +gceSTATUS
  161586. +gckOS_AllocateMemory(
  161587. + IN gckOS Os,
  161588. + IN gctSIZE_T Bytes,
  161589. + OUT gctPOINTER * Memory
  161590. + )
  161591. +{
  161592. + gctPOINTER memory;
  161593. + gceSTATUS status;
  161594. +
  161595. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
  161596. +
  161597. + /* Verify the arguments. */
  161598. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  161599. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  161600. +
  161601. + if (Bytes > PAGE_SIZE)
  161602. + {
  161603. + memory = (gctPOINTER) vmalloc(Bytes);
  161604. + }
  161605. + else
  161606. + {
  161607. + memory = (gctPOINTER) kmalloc(Bytes, GFP_KERNEL | gcdNOWARN);
  161608. + }
  161609. +
  161610. + if (memory == gcvNULL)
  161611. + {
  161612. + /* Out of memory. */
  161613. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  161614. + }
  161615. +
  161616. + /* Return pointer to the memory allocation. */
  161617. + *Memory = memory;
  161618. +
  161619. + /* Success. */
  161620. + gcmkFOOTER_ARG("*Memory=0x%X", *Memory);
  161621. + return gcvSTATUS_OK;
  161622. +
  161623. +OnError:
  161624. + /* Return the status. */
  161625. + gcmkFOOTER();
  161626. + return status;
  161627. +}
  161628. +
  161629. +/*******************************************************************************
  161630. +**
  161631. +** gckOS_FreeMemory
  161632. +**
  161633. +** Free allocated memory wrapper.
  161634. +**
  161635. +** INPUT:
  161636. +**
  161637. +** gctPOINTER Memory
  161638. +** Pointer to memory allocation to free.
  161639. +**
  161640. +** OUTPUT:
  161641. +**
  161642. +** Nothing.
  161643. +*/
  161644. +gceSTATUS
  161645. +gckOS_FreeMemory(
  161646. + IN gckOS Os,
  161647. + IN gctPOINTER Memory
  161648. + )
  161649. +{
  161650. + gcmkHEADER_ARG("Memory=0x%X", Memory);
  161651. +
  161652. + /* Verify the arguments. */
  161653. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  161654. +
  161655. + /* Free the memory from the OS pool. */
  161656. + if (is_vmalloc_addr(Memory))
  161657. + {
  161658. + vfree(Memory);
  161659. + }
  161660. + else
  161661. + {
  161662. + kfree(Memory);
  161663. + }
  161664. +
  161665. + /* Success. */
  161666. + gcmkFOOTER_NO();
  161667. + return gcvSTATUS_OK;
  161668. +}
  161669. +
  161670. +/*******************************************************************************
  161671. +**
  161672. +** gckOS_MapMemory
  161673. +**
  161674. +** Map physical memory into the current process.
  161675. +**
  161676. +** INPUT:
  161677. +**
  161678. +** gckOS Os
  161679. +** Pointer to an gckOS object.
  161680. +**
  161681. +** gctPHYS_ADDR Physical
  161682. +** Start of physical address memory.
  161683. +**
  161684. +** gctSIZE_T Bytes
  161685. +** Number of bytes to map.
  161686. +**
  161687. +** OUTPUT:
  161688. +**
  161689. +** gctPOINTER * Memory
  161690. +** Pointer to a variable that will hold the logical address of the
  161691. +** mapped memory.
  161692. +*/
  161693. +gceSTATUS
  161694. +gckOS_MapMemory(
  161695. + IN gckOS Os,
  161696. + IN gctPHYS_ADDR Physical,
  161697. + IN gctSIZE_T Bytes,
  161698. + OUT gctPOINTER * Logical
  161699. + )
  161700. +{
  161701. + PLINUX_MDL_MAP mdlMap;
  161702. + PLINUX_MDL mdl = (PLINUX_MDL)Physical;
  161703. +
  161704. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
  161705. +
  161706. + /* Verify the arguments. */
  161707. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161708. + gcmkVERIFY_ARGUMENT(Physical != 0);
  161709. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  161710. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  161711. +
  161712. + MEMORY_LOCK(Os);
  161713. +
  161714. + mdlMap = FindMdlMap(mdl, _GetProcessID());
  161715. +
  161716. + if (mdlMap == gcvNULL)
  161717. + {
  161718. + mdlMap = _CreateMdlMap(mdl, _GetProcessID());
  161719. +
  161720. + if (mdlMap == gcvNULL)
  161721. + {
  161722. + MEMORY_UNLOCK(Os);
  161723. +
  161724. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
  161725. + return gcvSTATUS_OUT_OF_MEMORY;
  161726. + }
  161727. + }
  161728. +
  161729. + if (mdlMap->vmaAddr == gcvNULL)
  161730. + {
  161731. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
  161732. + mdlMap->vmaAddr = (char *)vm_mmap(gcvNULL,
  161733. + 0L,
  161734. + mdl->numPages * PAGE_SIZE,
  161735. + PROT_READ | PROT_WRITE,
  161736. + MAP_SHARED,
  161737. + 0);
  161738. +#else
  161739. + down_write(&current->mm->mmap_sem);
  161740. +
  161741. + mdlMap->vmaAddr = (char *)do_mmap_pgoff(gcvNULL,
  161742. + 0L,
  161743. + mdl->numPages * PAGE_SIZE,
  161744. + PROT_READ | PROT_WRITE,
  161745. + MAP_SHARED,
  161746. + 0);
  161747. +
  161748. + up_write(&current->mm->mmap_sem);
  161749. +#endif
  161750. +
  161751. + if (IS_ERR(mdlMap->vmaAddr))
  161752. + {
  161753. + gcmkTRACE(
  161754. + gcvLEVEL_ERROR,
  161755. + "%s(%d): do_mmap_pgoff error",
  161756. + __FUNCTION__, __LINE__
  161757. + );
  161758. +
  161759. + gcmkTRACE(
  161760. + gcvLEVEL_ERROR,
  161761. + "%s(%d): mdl->numPages: %d mdl->vmaAddr: 0x%X",
  161762. + __FUNCTION__, __LINE__,
  161763. + mdl->numPages,
  161764. + mdlMap->vmaAddr
  161765. + );
  161766. +
  161767. + mdlMap->vmaAddr = gcvNULL;
  161768. +
  161769. + MEMORY_UNLOCK(Os);
  161770. +
  161771. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
  161772. + return gcvSTATUS_OUT_OF_MEMORY;
  161773. + }
  161774. +
  161775. + down_write(&current->mm->mmap_sem);
  161776. +
  161777. + mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
  161778. +
  161779. + if (!mdlMap->vma)
  161780. + {
  161781. + gcmkTRACE(
  161782. + gcvLEVEL_ERROR,
  161783. + "%s(%d): find_vma error.",
  161784. + __FUNCTION__, __LINE__
  161785. + );
  161786. +
  161787. + mdlMap->vmaAddr = gcvNULL;
  161788. +
  161789. + up_write(&current->mm->mmap_sem);
  161790. +
  161791. + MEMORY_UNLOCK(Os);
  161792. +
  161793. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  161794. + return gcvSTATUS_OUT_OF_RESOURCES;
  161795. + }
  161796. +
  161797. +#ifndef NO_DMA_COHERENT
  161798. + if (dma_mmap_coherent(gcvNULL,
  161799. + mdlMap->vma,
  161800. + mdl->addr,
  161801. + mdl->dmaHandle,
  161802. + mdl->numPages * PAGE_SIZE) < 0)
  161803. + {
  161804. + up_write(&current->mm->mmap_sem);
  161805. +
  161806. + gcmkTRACE(
  161807. + gcvLEVEL_ERROR,
  161808. + "%s(%d): dma_mmap_coherent error.",
  161809. + __FUNCTION__, __LINE__
  161810. + );
  161811. +
  161812. + mdlMap->vmaAddr = gcvNULL;
  161813. +
  161814. + MEMORY_UNLOCK(Os);
  161815. +
  161816. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  161817. + return gcvSTATUS_OUT_OF_RESOURCES;
  161818. + }
  161819. +#else
  161820. +#if !gcdPAGED_MEMORY_CACHEABLE
  161821. + mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
  161822. + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
  161823. +# endif
  161824. + mdlMap->vma->vm_pgoff = 0;
  161825. +
  161826. + if (remap_pfn_range(mdlMap->vma,
  161827. + mdlMap->vma->vm_start,
  161828. + mdl->dmaHandle >> PAGE_SHIFT,
  161829. + mdl->numPages*PAGE_SIZE,
  161830. + mdlMap->vma->vm_page_prot) < 0)
  161831. + {
  161832. + up_write(&current->mm->mmap_sem);
  161833. +
  161834. + gcmkTRACE(
  161835. + gcvLEVEL_ERROR,
  161836. + "%s(%d): remap_pfn_range error.",
  161837. + __FUNCTION__, __LINE__
  161838. + );
  161839. +
  161840. + mdlMap->vmaAddr = gcvNULL;
  161841. +
  161842. + MEMORY_UNLOCK(Os);
  161843. +
  161844. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  161845. + return gcvSTATUS_OUT_OF_RESOURCES;
  161846. + }
  161847. +#endif
  161848. +
  161849. + up_write(&current->mm->mmap_sem);
  161850. + }
  161851. +
  161852. + MEMORY_UNLOCK(Os);
  161853. +
  161854. + *Logical = mdlMap->vmaAddr;
  161855. +
  161856. + gcmkFOOTER_ARG("*Logical=0x%X", *Logical);
  161857. + return gcvSTATUS_OK;
  161858. +}
  161859. +
  161860. +/*******************************************************************************
  161861. +**
  161862. +** gckOS_UnmapMemory
  161863. +**
  161864. +** Unmap physical memory out of the current process.
  161865. +**
  161866. +** INPUT:
  161867. +**
  161868. +** gckOS Os
  161869. +** Pointer to an gckOS object.
  161870. +**
  161871. +** gctPHYS_ADDR Physical
  161872. +** Start of physical address memory.
  161873. +**
  161874. +** gctSIZE_T Bytes
  161875. +** Number of bytes to unmap.
  161876. +**
  161877. +** gctPOINTER Memory
  161878. +** Pointer to a previously mapped memory region.
  161879. +**
  161880. +** OUTPUT:
  161881. +**
  161882. +** Nothing.
  161883. +*/
  161884. +gceSTATUS
  161885. +gckOS_UnmapMemory(
  161886. + IN gckOS Os,
  161887. + IN gctPHYS_ADDR Physical,
  161888. + IN gctSIZE_T Bytes,
  161889. + IN gctPOINTER Logical
  161890. + )
  161891. +{
  161892. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X",
  161893. + Os, Physical, Bytes, Logical);
  161894. +
  161895. + /* Verify the arguments. */
  161896. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161897. + gcmkVERIFY_ARGUMENT(Physical != 0);
  161898. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  161899. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  161900. +
  161901. + gckOS_UnmapMemoryEx(Os, Physical, Bytes, Logical, _GetProcessID());
  161902. +
  161903. + /* Success. */
  161904. + gcmkFOOTER_NO();
  161905. + return gcvSTATUS_OK;
  161906. +}
  161907. +
  161908. +
  161909. +/*******************************************************************************
  161910. +**
  161911. +** gckOS_UnmapMemoryEx
  161912. +**
  161913. +** Unmap physical memory in the specified process.
  161914. +**
  161915. +** INPUT:
  161916. +**
  161917. +** gckOS Os
  161918. +** Pointer to an gckOS object.
  161919. +**
  161920. +** gctPHYS_ADDR Physical
  161921. +** Start of physical address memory.
  161922. +**
  161923. +** gctSIZE_T Bytes
  161924. +** Number of bytes to unmap.
  161925. +**
  161926. +** gctPOINTER Memory
  161927. +** Pointer to a previously mapped memory region.
  161928. +**
  161929. +** gctUINT32 PID
  161930. +** Pid of the process that opened the device and mapped this memory.
  161931. +**
  161932. +** OUTPUT:
  161933. +**
  161934. +** Nothing.
  161935. +*/
  161936. +gceSTATUS
  161937. +gckOS_UnmapMemoryEx(
  161938. + IN gckOS Os,
  161939. + IN gctPHYS_ADDR Physical,
  161940. + IN gctSIZE_T Bytes,
  161941. + IN gctPOINTER Logical,
  161942. + IN gctUINT32 PID
  161943. + )
  161944. +{
  161945. + PLINUX_MDL_MAP mdlMap;
  161946. + PLINUX_MDL mdl = (PLINUX_MDL)Physical;
  161947. +
  161948. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X PID=%d",
  161949. + Os, Physical, Bytes, Logical, PID);
  161950. +
  161951. + /* Verify the arguments. */
  161952. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161953. + gcmkVERIFY_ARGUMENT(Physical != 0);
  161954. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  161955. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  161956. + gcmkVERIFY_ARGUMENT(PID != 0);
  161957. +
  161958. + MEMORY_LOCK(Os);
  161959. +
  161960. + if (Logical)
  161961. + {
  161962. + mdlMap = FindMdlMap(mdl, PID);
  161963. +
  161964. + if (mdlMap == gcvNULL || mdlMap->vmaAddr == gcvNULL)
  161965. + {
  161966. + MEMORY_UNLOCK(Os);
  161967. +
  161968. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  161969. + return gcvSTATUS_INVALID_ARGUMENT;
  161970. + }
  161971. +
  161972. + _UnmapUserLogical(PID, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
  161973. +
  161974. + gcmkVERIFY_OK(_DestroyMdlMap(mdl, mdlMap));
  161975. + }
  161976. +
  161977. + MEMORY_UNLOCK(Os);
  161978. +
  161979. + /* Success. */
  161980. + gcmkFOOTER_NO();
  161981. + return gcvSTATUS_OK;
  161982. +}
  161983. +
  161984. +/*******************************************************************************
  161985. +**
  161986. +** gckOS_UnmapUserLogical
  161987. +**
  161988. +** Unmap user logical memory out of physical memory.
  161989. +**
  161990. +** INPUT:
  161991. +**
  161992. +** gckOS Os
  161993. +** Pointer to an gckOS object.
  161994. +**
  161995. +** gctPHYS_ADDR Physical
  161996. +** Start of physical address memory.
  161997. +**
  161998. +** gctSIZE_T Bytes
  161999. +** Number of bytes to unmap.
  162000. +**
  162001. +** gctPOINTER Memory
  162002. +** Pointer to a previously mapped memory region.
  162003. +**
  162004. +** OUTPUT:
  162005. +**
  162006. +** Nothing.
  162007. +*/
  162008. +gceSTATUS
  162009. +gckOS_UnmapUserLogical(
  162010. + IN gckOS Os,
  162011. + IN gctPHYS_ADDR Physical,
  162012. + IN gctSIZE_T Bytes,
  162013. + IN gctPOINTER Logical
  162014. + )
  162015. +{
  162016. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X",
  162017. + Os, Physical, Bytes, Logical);
  162018. +
  162019. + /* Verify the arguments. */
  162020. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162021. + gcmkVERIFY_ARGUMENT(Physical != 0);
  162022. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  162023. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  162024. +
  162025. + gckOS_UnmapMemory(Os, Physical, Bytes, Logical);
  162026. +
  162027. + /* Success. */
  162028. + gcmkFOOTER_NO();
  162029. + return gcvSTATUS_OK;
  162030. +
  162031. +}
  162032. +
  162033. +/*******************************************************************************
  162034. +**
  162035. +** gckOS_AllocateNonPagedMemory
  162036. +**
  162037. +** Allocate a number of pages from non-paged memory.
  162038. +**
  162039. +** INPUT:
  162040. +**
  162041. +** gckOS Os
  162042. +** Pointer to an gckOS object.
  162043. +**
  162044. +** gctBOOL InUserSpace
  162045. +** gcvTRUE if the pages need to be mapped into user space.
  162046. +**
  162047. +** gctSIZE_T * Bytes
  162048. +** Pointer to a variable that holds the number of bytes to allocate.
  162049. +**
  162050. +** OUTPUT:
  162051. +**
  162052. +** gctSIZE_T * Bytes
  162053. +** Pointer to a variable that hold the number of bytes allocated.
  162054. +**
  162055. +** gctPHYS_ADDR * Physical
  162056. +** Pointer to a variable that will hold the physical address of the
  162057. +** allocation.
  162058. +**
  162059. +** gctPOINTER * Logical
  162060. +** Pointer to a variable that will hold the logical address of the
  162061. +** allocation.
  162062. +*/
  162063. +gceSTATUS
  162064. +gckOS_AllocateNonPagedMemory(
  162065. + IN gckOS Os,
  162066. + IN gctBOOL InUserSpace,
  162067. + IN OUT gctSIZE_T * Bytes,
  162068. + OUT gctPHYS_ADDR * Physical,
  162069. + OUT gctPOINTER * Logical
  162070. + )
  162071. +{
  162072. + gctSIZE_T bytes;
  162073. + gctINT numPages;
  162074. + PLINUX_MDL mdl = gcvNULL;
  162075. + PLINUX_MDL_MAP mdlMap = gcvNULL;
  162076. + gctSTRING addr;
  162077. +#ifdef NO_DMA_COHERENT
  162078. + struct page * page;
  162079. + long size, order;
  162080. + gctPOINTER vaddr;
  162081. +#endif
  162082. + gctBOOL locked = gcvFALSE;
  162083. + gceSTATUS status;
  162084. +
  162085. + gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
  162086. + Os, InUserSpace, gcmOPT_VALUE(Bytes));
  162087. +
  162088. + /* Verify the arguments. */
  162089. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162090. + gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
  162091. + gcmkVERIFY_ARGUMENT(*Bytes > 0);
  162092. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  162093. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  162094. +
  162095. + /* Align number of bytes to page size. */
  162096. + bytes = gcmALIGN(*Bytes, PAGE_SIZE);
  162097. +
  162098. + /* Get total number of pages.. */
  162099. + numPages = GetPageCount(bytes, 0);
  162100. +
  162101. + /* Allocate mdl+vector structure */
  162102. + mdl = _CreateMdl(_GetProcessID());
  162103. + if (mdl == gcvNULL)
  162104. + {
  162105. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  162106. + }
  162107. +
  162108. + mdl->pagedMem = 0;
  162109. + mdl->numPages = numPages;
  162110. +
  162111. + MEMORY_LOCK(Os);
  162112. + locked = gcvTRUE;
  162113. +
  162114. +#ifndef NO_DMA_COHERENT
  162115. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162116. + addr = _GetNonPagedMemoryCache(Os,
  162117. + mdl->numPages * PAGE_SIZE,
  162118. + &mdl->dmaHandle);
  162119. +
  162120. + if (addr == gcvNULL)
  162121. +#endif
  162122. + {
  162123. + addr = dma_alloc_coherent(gcvNULL,
  162124. + mdl->numPages * PAGE_SIZE,
  162125. + &mdl->dmaHandle,
  162126. + GFP_KERNEL | gcdNOWARN);
  162127. + }
  162128. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162129. + if(addr == gcvNULL)
  162130. + {
  162131. + MEMORY_UNLOCK(Os);
  162132. + locked = gcvFALSE;
  162133. + /*Free all cache and try again*/
  162134. + _FreeAllNonPagedMemoryCache(Os);
  162135. + MEMORY_LOCK(Os);
  162136. + locked = gcvTRUE;
  162137. + addr = dma_alloc_coherent(gcvNULL,
  162138. + mdl->numPages * PAGE_SIZE,
  162139. + &mdl->dmaHandle,
  162140. + GFP_KERNEL | gcdNOWARN);
  162141. + }
  162142. +#endif
  162143. +#else
  162144. + size = mdl->numPages * PAGE_SIZE;
  162145. + order = get_order(size);
  162146. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162147. + page = _GetNonPagedMemoryCache(Os, order);
  162148. +
  162149. + if (page == gcvNULL)
  162150. +#endif
  162151. + {
  162152. + page = alloc_pages(GFP_KERNEL | gcdNOWARN, order);
  162153. + }
  162154. +
  162155. + if (page == gcvNULL)
  162156. + {
  162157. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  162158. + }
  162159. +
  162160. + vaddr = (gctPOINTER)page_address(page);
  162161. + mdl->contiguous = gcvTRUE;
  162162. + mdl->u.contiguousPages = page;
  162163. + addr = _CreateKernelVirtualMapping(mdl);
  162164. + mdl->dmaHandle = virt_to_phys(vaddr);
  162165. + mdl->kaddr = vaddr;
  162166. + mdl->u.contiguousPages = page;
  162167. +
  162168. +#if !defined(CONFIG_PPC)
  162169. + /* Cache invalidate. */
  162170. + dma_sync_single_for_device(
  162171. + gcvNULL,
  162172. + page_to_phys(page),
  162173. + bytes,
  162174. + DMA_FROM_DEVICE);
  162175. +#endif
  162176. +
  162177. + while (size > 0)
  162178. + {
  162179. + SetPageReserved(virt_to_page(vaddr));
  162180. +
  162181. + vaddr += PAGE_SIZE;
  162182. + size -= PAGE_SIZE;
  162183. + }
  162184. +#endif
  162185. +
  162186. + if (addr == gcvNULL)
  162187. + {
  162188. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  162189. + }
  162190. +
  162191. + mdl->addr = addr;
  162192. +
  162193. + /* Return allocated memory. */
  162194. + *Bytes = bytes;
  162195. + *Physical = (gctPHYS_ADDR) mdl;
  162196. +
  162197. + if (InUserSpace)
  162198. + {
  162199. + mdlMap = _CreateMdlMap(mdl, _GetProcessID());
  162200. +
  162201. + if (mdlMap == gcvNULL)
  162202. + {
  162203. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  162204. + }
  162205. +
  162206. + /* Only after mmap this will be valid. */
  162207. +
  162208. + /* We need to map this to user space. */
  162209. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
  162210. + mdlMap->vmaAddr = (gctSTRING) vm_mmap(gcvNULL,
  162211. + 0L,
  162212. + mdl->numPages * PAGE_SIZE,
  162213. + PROT_READ | PROT_WRITE,
  162214. + MAP_SHARED,
  162215. + 0);
  162216. +#else
  162217. + down_write(&current->mm->mmap_sem);
  162218. +
  162219. + mdlMap->vmaAddr = (gctSTRING) do_mmap_pgoff(gcvNULL,
  162220. + 0L,
  162221. + mdl->numPages * PAGE_SIZE,
  162222. + PROT_READ | PROT_WRITE,
  162223. + MAP_SHARED,
  162224. + 0);
  162225. +
  162226. + up_write(&current->mm->mmap_sem);
  162227. +#endif
  162228. +
  162229. + if (IS_ERR(mdlMap->vmaAddr))
  162230. + {
  162231. + gcmkTRACE_ZONE(
  162232. + gcvLEVEL_WARNING, gcvZONE_OS,
  162233. + "%s(%d): do_mmap_pgoff error",
  162234. + __FUNCTION__, __LINE__
  162235. + );
  162236. +
  162237. + mdlMap->vmaAddr = gcvNULL;
  162238. +
  162239. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  162240. + }
  162241. +
  162242. + down_write(&current->mm->mmap_sem);
  162243. +
  162244. + mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
  162245. +
  162246. + if (mdlMap->vma == gcvNULL)
  162247. + {
  162248. + gcmkTRACE_ZONE(
  162249. + gcvLEVEL_WARNING, gcvZONE_OS,
  162250. + "%s(%d): find_vma error",
  162251. + __FUNCTION__, __LINE__
  162252. + );
  162253. +
  162254. + up_write(&current->mm->mmap_sem);
  162255. +
  162256. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  162257. + }
  162258. +
  162259. +#ifndef NO_DMA_COHERENT
  162260. + if (dma_mmap_coherent(gcvNULL,
  162261. + mdlMap->vma,
  162262. + mdl->addr,
  162263. + mdl->dmaHandle,
  162264. + mdl->numPages * PAGE_SIZE) < 0)
  162265. + {
  162266. + gcmkTRACE_ZONE(
  162267. + gcvLEVEL_WARNING, gcvZONE_OS,
  162268. + "%s(%d): dma_mmap_coherent error",
  162269. + __FUNCTION__, __LINE__
  162270. + );
  162271. +
  162272. + up_write(&current->mm->mmap_sem);
  162273. +
  162274. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  162275. + }
  162276. +#else
  162277. + mdlMap->vma->vm_page_prot = gcmkNONPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
  162278. + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
  162279. + mdlMap->vma->vm_pgoff = 0;
  162280. +
  162281. + if (remap_pfn_range(mdlMap->vma,
  162282. + mdlMap->vma->vm_start,
  162283. + mdl->dmaHandle >> PAGE_SHIFT,
  162284. + mdl->numPages * PAGE_SIZE,
  162285. + mdlMap->vma->vm_page_prot))
  162286. + {
  162287. + gcmkTRACE_ZONE(
  162288. + gcvLEVEL_WARNING, gcvZONE_OS,
  162289. + "%s(%d): remap_pfn_range error",
  162290. + __FUNCTION__, __LINE__
  162291. + );
  162292. +
  162293. + up_write(&current->mm->mmap_sem);
  162294. +
  162295. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  162296. + }
  162297. +#endif /* NO_DMA_COHERENT */
  162298. +
  162299. + up_write(&current->mm->mmap_sem);
  162300. +
  162301. + *Logical = mdlMap->vmaAddr;
  162302. + }
  162303. + else
  162304. + {
  162305. + *Logical = (gctPOINTER)mdl->addr;
  162306. + }
  162307. +
  162308. + /*
  162309. + * Add this to a global list.
  162310. + * Will be used by get physical address
  162311. + * and mapuser pointer functions.
  162312. + */
  162313. +
  162314. + if (!Os->mdlHead)
  162315. + {
  162316. + /* Initialize the queue. */
  162317. + Os->mdlHead = Os->mdlTail = mdl;
  162318. + }
  162319. + else
  162320. + {
  162321. + /* Add to the tail. */
  162322. + mdl->prev = Os->mdlTail;
  162323. + Os->mdlTail->next = mdl;
  162324. + Os->mdlTail = mdl;
  162325. + }
  162326. +
  162327. + MEMORY_UNLOCK(Os);
  162328. +
  162329. + /* Success. */
  162330. + gcmkFOOTER_ARG("*Bytes=%lu *Physical=0x%X *Logical=0x%X",
  162331. + *Bytes, *Physical, *Logical);
  162332. + return gcvSTATUS_OK;
  162333. +
  162334. +OnError:
  162335. + if (mdlMap != gcvNULL)
  162336. + {
  162337. + /* Free LINUX_MDL_MAP. */
  162338. + gcmkVERIFY_OK(_DestroyMdlMap(mdl, mdlMap));
  162339. + }
  162340. +
  162341. + if (mdl != gcvNULL)
  162342. + {
  162343. + /* Free LINUX_MDL. */
  162344. + gcmkVERIFY_OK(_DestroyMdl(mdl));
  162345. + }
  162346. +
  162347. + if (locked)
  162348. + {
  162349. + /* Unlock memory. */
  162350. + MEMORY_UNLOCK(Os);
  162351. + }
  162352. +
  162353. + /* Return the status. */
  162354. + gcmkFOOTER();
  162355. + return status;
  162356. +}
  162357. +
  162358. +/*******************************************************************************
  162359. +**
  162360. +** gckOS_FreeNonPagedMemory
  162361. +**
  162362. +** Free previously allocated and mapped pages from non-paged memory.
  162363. +**
  162364. +** INPUT:
  162365. +**
  162366. +** gckOS Os
  162367. +** Pointer to an gckOS object.
  162368. +**
  162369. +** gctSIZE_T Bytes
  162370. +** Number of bytes allocated.
  162371. +**
  162372. +** gctPHYS_ADDR Physical
  162373. +** Physical address of the allocated memory.
  162374. +**
  162375. +** gctPOINTER Logical
  162376. +** Logical address of the allocated memory.
  162377. +**
  162378. +** OUTPUT:
  162379. +**
  162380. +** Nothing.
  162381. +*/
  162382. +gceSTATUS gckOS_FreeNonPagedMemory(
  162383. + IN gckOS Os,
  162384. + IN gctSIZE_T Bytes,
  162385. + IN gctPHYS_ADDR Physical,
  162386. + IN gctPOINTER Logical
  162387. + )
  162388. +{
  162389. + PLINUX_MDL mdl;
  162390. + PLINUX_MDL_MAP mdlMap;
  162391. +#ifdef NO_DMA_COHERENT
  162392. + unsigned size;
  162393. + gctPOINTER vaddr;
  162394. +#endif /* NO_DMA_COHERENT */
  162395. +
  162396. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu Physical=0x%X Logical=0x%X",
  162397. + Os, Bytes, Physical, Logical);
  162398. +
  162399. + /* Verify the arguments. */
  162400. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162401. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  162402. + gcmkVERIFY_ARGUMENT(Physical != 0);
  162403. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  162404. +
  162405. + /* Convert physical address into a pointer to a MDL. */
  162406. + mdl = (PLINUX_MDL) Physical;
  162407. +
  162408. + MEMORY_LOCK(Os);
  162409. +
  162410. +#ifndef NO_DMA_COHERENT
  162411. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162412. + if (!_AddNonPagedMemoryCache(Os,
  162413. + mdl->numPages * PAGE_SIZE,
  162414. + mdl->addr,
  162415. + mdl->dmaHandle))
  162416. +#endif
  162417. + {
  162418. + dma_free_coherent(gcvNULL,
  162419. + mdl->numPages * PAGE_SIZE,
  162420. + mdl->addr,
  162421. + mdl->dmaHandle);
  162422. + }
  162423. +#else
  162424. + size = mdl->numPages * PAGE_SIZE;
  162425. + vaddr = mdl->kaddr;
  162426. +
  162427. + while (size > 0)
  162428. + {
  162429. + ClearPageReserved(virt_to_page(vaddr));
  162430. +
  162431. + vaddr += PAGE_SIZE;
  162432. + size -= PAGE_SIZE;
  162433. + }
  162434. +
  162435. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162436. + if (!_AddNonPagedMemoryCache(Os,
  162437. + get_order(mdl->numPages * PAGE_SIZE),
  162438. + virt_to_page(mdl->kaddr)))
  162439. +#endif
  162440. + {
  162441. + free_pages((unsigned long)mdl->kaddr, get_order(mdl->numPages * PAGE_SIZE));
  162442. + }
  162443. +
  162444. + _DestoryKernelVirtualMapping(mdl->addr);
  162445. +#endif /* NO_DMA_COHERENT */
  162446. +
  162447. + mdlMap = mdl->maps;
  162448. +
  162449. + while (mdlMap != gcvNULL)
  162450. + {
  162451. + if (mdlMap->vmaAddr != gcvNULL)
  162452. + {
  162453. + /* No mapped memory exists when free nonpaged memory */
  162454. + gcmkASSERT(0);
  162455. + }
  162456. +
  162457. + mdlMap = mdlMap->next;
  162458. + }
  162459. +
  162460. + /* Remove the node from global list.. */
  162461. + if (mdl == Os->mdlHead)
  162462. + {
  162463. + if ((Os->mdlHead = mdl->next) == gcvNULL)
  162464. + {
  162465. + Os->mdlTail = gcvNULL;
  162466. + }
  162467. + }
  162468. + else
  162469. + {
  162470. + mdl->prev->next = mdl->next;
  162471. + if (mdl == Os->mdlTail)
  162472. + {
  162473. + Os->mdlTail = mdl->prev;
  162474. + }
  162475. + else
  162476. + {
  162477. + mdl->next->prev = mdl->prev;
  162478. + }
  162479. + }
  162480. +
  162481. + MEMORY_UNLOCK(Os);
  162482. +
  162483. + gcmkVERIFY_OK(_DestroyMdl(mdl));
  162484. +
  162485. + /* Success. */
  162486. + gcmkFOOTER_NO();
  162487. + return gcvSTATUS_OK;
  162488. +}
  162489. +
  162490. +/*******************************************************************************
  162491. +**
  162492. +** gckOS_ReadRegister
  162493. +**
  162494. +** Read data from a register.
  162495. +**
  162496. +** INPUT:
  162497. +**
  162498. +** gckOS Os
  162499. +** Pointer to an gckOS object.
  162500. +**
  162501. +** gctUINT32 Address
  162502. +** Address of register.
  162503. +**
  162504. +** OUTPUT:
  162505. +**
  162506. +** gctUINT32 * Data
  162507. +** Pointer to a variable that receives the data read from the register.
  162508. +*/
  162509. +gceSTATUS
  162510. +gckOS_ReadRegister(
  162511. + IN gckOS Os,
  162512. + IN gctUINT32 Address,
  162513. + OUT gctUINT32 * Data
  162514. + )
  162515. +{
  162516. + return gckOS_ReadRegisterEx(Os, gcvCORE_MAJOR, Address, Data);
  162517. +}
  162518. +
  162519. +gceSTATUS
  162520. +gckOS_ReadRegisterEx(
  162521. + IN gckOS Os,
  162522. + IN gceCORE Core,
  162523. + IN gctUINT32 Address,
  162524. + OUT gctUINT32 * Data
  162525. + )
  162526. +{
  162527. + gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%X", Os, Core, Address);
  162528. +
  162529. + /* Verify the arguments. */
  162530. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162531. + gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
  162532. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  162533. +
  162534. + *Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address);
  162535. +
  162536. + /* Success. */
  162537. + gcmkFOOTER_ARG("*Data=0x%08x", *Data);
  162538. + return gcvSTATUS_OK;
  162539. +}
  162540. +
  162541. +/*******************************************************************************
  162542. +**
  162543. +** gckOS_WriteRegister
  162544. +**
  162545. +** Write data to a register.
  162546. +**
  162547. +** INPUT:
  162548. +**
  162549. +** gckOS Os
  162550. +** Pointer to an gckOS object.
  162551. +**
  162552. +** gctUINT32 Address
  162553. +** Address of register.
  162554. +**
  162555. +** gctUINT32 Data
  162556. +** Data for register.
  162557. +**
  162558. +** OUTPUT:
  162559. +**
  162560. +** Nothing.
  162561. +*/
  162562. +gceSTATUS
  162563. +gckOS_WriteRegister(
  162564. + IN gckOS Os,
  162565. + IN gctUINT32 Address,
  162566. + IN gctUINT32 Data
  162567. + )
  162568. +{
  162569. + return gckOS_WriteRegisterEx(Os, gcvCORE_MAJOR, Address, Data);
  162570. +}
  162571. +
  162572. +gceSTATUS
  162573. +gckOS_WriteRegisterEx(
  162574. + IN gckOS Os,
  162575. + IN gceCORE Core,
  162576. + IN gctUINT32 Address,
  162577. + IN gctUINT32 Data
  162578. + )
  162579. +{
  162580. + gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%X Data=0x%08x", Os, Core, Address, Data);
  162581. +
  162582. + gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
  162583. +
  162584. + writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address);
  162585. +
  162586. + /* Success. */
  162587. + gcmkFOOTER_NO();
  162588. + return gcvSTATUS_OK;
  162589. +}
  162590. +
  162591. +/*******************************************************************************
  162592. +**
  162593. +** gckOS_GetPageSize
  162594. +**
  162595. +** Get the system's page size.
  162596. +**
  162597. +** INPUT:
  162598. +**
  162599. +** gckOS Os
  162600. +** Pointer to an gckOS object.
  162601. +**
  162602. +** OUTPUT:
  162603. +**
  162604. +** gctSIZE_T * PageSize
  162605. +** Pointer to a variable that will receive the system's page size.
  162606. +*/
  162607. +gceSTATUS gckOS_GetPageSize(
  162608. + IN gckOS Os,
  162609. + OUT gctSIZE_T * PageSize
  162610. + )
  162611. +{
  162612. + gcmkHEADER_ARG("Os=0x%X", Os);
  162613. +
  162614. + /* Verify the arguments. */
  162615. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162616. + gcmkVERIFY_ARGUMENT(PageSize != gcvNULL);
  162617. +
  162618. + /* Return the page size. */
  162619. + *PageSize = (gctSIZE_T) PAGE_SIZE;
  162620. +
  162621. + /* Success. */
  162622. + gcmkFOOTER_ARG("*PageSize", *PageSize);
  162623. + return gcvSTATUS_OK;
  162624. +}
  162625. +
  162626. +/*******************************************************************************
  162627. +**
  162628. +** gckOS_GetPhysicalAddress
  162629. +**
  162630. +** Get the physical system address of a corresponding virtual address.
  162631. +**
  162632. +** INPUT:
  162633. +**
  162634. +** gckOS Os
  162635. +** Pointer to an gckOS object.
  162636. +**
  162637. +** gctPOINTER Logical
  162638. +** Logical address.
  162639. +**
  162640. +** OUTPUT:
  162641. +**
  162642. +** gctUINT32 * Address
  162643. +** Poinetr to a variable that receives the 32-bit physical adress.
  162644. +*/
  162645. +gceSTATUS
  162646. +gckOS_GetPhysicalAddress(
  162647. + IN gckOS Os,
  162648. + IN gctPOINTER Logical,
  162649. + OUT gctUINT32 * Address
  162650. + )
  162651. +{
  162652. + gceSTATUS status;
  162653. + gctUINT32 processID;
  162654. +
  162655. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X", Os, Logical);
  162656. +
  162657. + /* Verify the arguments. */
  162658. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162659. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  162660. +
  162661. + /* Query page table of current process first. */
  162662. + status = _QueryProcessPageTable(Logical, Address);
  162663. +
  162664. + if (gcmIS_ERROR(status))
  162665. + {
  162666. + /* Get current process ID. */
  162667. + processID = _GetProcessID();
  162668. +
  162669. + /* Route through other function. */
  162670. + gcmkONERROR(
  162671. + gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
  162672. + }
  162673. +
  162674. + /* Success. */
  162675. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  162676. + return gcvSTATUS_OK;
  162677. +
  162678. +OnError:
  162679. + /* Return the status. */
  162680. + gcmkFOOTER();
  162681. + return status;
  162682. +}
  162683. +
  162684. +#if gcdSECURE_USER
  162685. +static gceSTATUS
  162686. +gckOS_AddMapping(
  162687. + IN gckOS Os,
  162688. + IN gctUINT32 Physical,
  162689. + IN gctPOINTER Logical,
  162690. + IN gctSIZE_T Bytes
  162691. + )
  162692. +{
  162693. + gceSTATUS status;
  162694. + gcsUSER_MAPPING_PTR map;
  162695. +
  162696. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Logical=0x%X Bytes=%lu",
  162697. + Os, Physical, Logical, Bytes);
  162698. +
  162699. + gcmkONERROR(gckOS_Allocate(Os,
  162700. + gcmSIZEOF(gcsUSER_MAPPING),
  162701. + (gctPOINTER *) &map));
  162702. +
  162703. + map->next = Os->userMap;
  162704. + map->physical = Physical - Os->device->baseAddress;
  162705. + map->logical = Logical;
  162706. + map->bytes = Bytes;
  162707. + map->start = (gctINT8_PTR) Logical;
  162708. + map->end = map->start + Bytes;
  162709. +
  162710. + Os->userMap = map;
  162711. +
  162712. + gcmkFOOTER_NO();
  162713. + return gcvSTATUS_OK;
  162714. +
  162715. +OnError:
  162716. + gcmkFOOTER();
  162717. + return status;
  162718. +}
  162719. +
  162720. +static gceSTATUS
  162721. +gckOS_RemoveMapping(
  162722. + IN gckOS Os,
  162723. + IN gctPOINTER Logical,
  162724. + IN gctSIZE_T Bytes
  162725. + )
  162726. +{
  162727. + gceSTATUS status;
  162728. + gcsUSER_MAPPING_PTR map, prev;
  162729. +
  162730. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu", Os, Logical, Bytes);
  162731. +
  162732. + for (map = Os->userMap, prev = gcvNULL; map != gcvNULL; map = map->next)
  162733. + {
  162734. + if ((map->logical == Logical)
  162735. + && (map->bytes == Bytes)
  162736. + )
  162737. + {
  162738. + break;
  162739. + }
  162740. +
  162741. + prev = map;
  162742. + }
  162743. +
  162744. + if (map == gcvNULL)
  162745. + {
  162746. + gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
  162747. + }
  162748. +
  162749. + if (prev == gcvNULL)
  162750. + {
  162751. + Os->userMap = map->next;
  162752. + }
  162753. + else
  162754. + {
  162755. + prev->next = map->next;
  162756. + }
  162757. +
  162758. + gcmkONERROR(gcmkOS_SAFE_FREE(Os, map));
  162759. +
  162760. + gcmkFOOTER_NO();
  162761. + return gcvSTATUS_OK;
  162762. +
  162763. +OnError:
  162764. + gcmkFOOTER();
  162765. + return status;
  162766. +}
  162767. +#endif
  162768. +
  162769. +static gceSTATUS
  162770. +_ConvertLogical2Physical(
  162771. + IN gckOS Os,
  162772. + IN gctPOINTER Logical,
  162773. + IN gctUINT32 ProcessID,
  162774. + IN PLINUX_MDL Mdl,
  162775. + OUT gctUINT32_PTR Physical
  162776. + )
  162777. +{
  162778. + gctINT8_PTR base, vBase;
  162779. + gctUINT32 offset;
  162780. + PLINUX_MDL_MAP map;
  162781. + gcsUSER_MAPPING_PTR userMap;
  162782. +
  162783. + base = (Mdl == gcvNULL) ? gcvNULL : (gctINT8_PTR) Mdl->addr;
  162784. +
  162785. + /* Check for the logical address match. */
  162786. + if ((base != gcvNULL)
  162787. + && ((gctINT8_PTR) Logical >= base)
  162788. + && ((gctINT8_PTR) Logical < base + Mdl->numPages * PAGE_SIZE)
  162789. + )
  162790. + {
  162791. + offset = (gctINT8_PTR) Logical - base;
  162792. +
  162793. + if (Mdl->dmaHandle != 0)
  162794. + {
  162795. + /* The memory was from coherent area. */
  162796. + *Physical = (gctUINT32) Mdl->dmaHandle + offset;
  162797. + }
  162798. + else if (Mdl->pagedMem && !Mdl->contiguous)
  162799. + {
  162800. + /* paged memory is not mapped to kernel space. */
  162801. + return gcvSTATUS_INVALID_ADDRESS;
  162802. + }
  162803. + else
  162804. + {
  162805. + *Physical = gcmPTR2INT(virt_to_phys(base)) + offset;
  162806. + }
  162807. +
  162808. + return gcvSTATUS_OK;
  162809. + }
  162810. +
  162811. + /* Walk user maps. */
  162812. + for (userMap = Os->userMap; userMap != gcvNULL; userMap = userMap->next)
  162813. + {
  162814. + if (((gctINT8_PTR) Logical >= userMap->start)
  162815. + && ((gctINT8_PTR) Logical < userMap->end)
  162816. + )
  162817. + {
  162818. + *Physical = userMap->physical
  162819. + + (gctUINT32) ((gctINT8_PTR) Logical - userMap->start);
  162820. +
  162821. + return gcvSTATUS_OK;
  162822. + }
  162823. + }
  162824. +
  162825. + if (ProcessID != Os->kernelProcessID)
  162826. + {
  162827. + map = FindMdlMap(Mdl, (gctINT) ProcessID);
  162828. + vBase = (map == gcvNULL) ? gcvNULL : (gctINT8_PTR) map->vmaAddr;
  162829. +
  162830. + /* Is the given address within that range. */
  162831. + if ((vBase != gcvNULL)
  162832. + && ((gctINT8_PTR) Logical >= vBase)
  162833. + && ((gctINT8_PTR) Logical < vBase + Mdl->numPages * PAGE_SIZE)
  162834. + )
  162835. + {
  162836. + offset = (gctINT8_PTR) Logical - vBase;
  162837. +
  162838. + if (Mdl->dmaHandle != 0)
  162839. + {
  162840. + /* The memory was from coherent area. */
  162841. + *Physical = (gctUINT32) Mdl->dmaHandle + offset;
  162842. + }
  162843. + else if (Mdl->pagedMem && !Mdl->contiguous)
  162844. + {
  162845. + *Physical = _NonContiguousToPhys(Mdl->u.nonContiguousPages, offset/PAGE_SIZE);
  162846. + }
  162847. + else
  162848. + {
  162849. + *Physical = page_to_phys(Mdl->u.contiguousPages) + offset;
  162850. + }
  162851. +
  162852. + return gcvSTATUS_OK;
  162853. + }
  162854. + }
  162855. +
  162856. + /* Address not yet found. */
  162857. + return gcvSTATUS_INVALID_ADDRESS;
  162858. +}
  162859. +
  162860. +/*******************************************************************************
  162861. +**
  162862. +** gckOS_GetPhysicalAddressProcess
  162863. +**
  162864. +** Get the physical system address of a corresponding virtual address for a
  162865. +** given process.
  162866. +**
  162867. +** INPUT:
  162868. +**
  162869. +** gckOS Os
  162870. +** Pointer to gckOS object.
  162871. +**
  162872. +** gctPOINTER Logical
  162873. +** Logical address.
  162874. +**
  162875. +** gctUINT32 ProcessID
  162876. +** Process ID.
  162877. +**
  162878. +** OUTPUT:
  162879. +**
  162880. +** gctUINT32 * Address
  162881. +** Poinetr to a variable that receives the 32-bit physical adress.
  162882. +*/
  162883. +gceSTATUS
  162884. +gckOS_GetPhysicalAddressProcess(
  162885. + IN gckOS Os,
  162886. + IN gctPOINTER Logical,
  162887. + IN gctUINT32 ProcessID,
  162888. + OUT gctUINT32 * Address
  162889. + )
  162890. +{
  162891. + PLINUX_MDL mdl;
  162892. + gctINT8_PTR base;
  162893. + gceSTATUS status = gcvSTATUS_INVALID_ADDRESS;
  162894. +
  162895. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X ProcessID=%d", Os, Logical, ProcessID);
  162896. +
  162897. + /* Verify the arguments. */
  162898. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162899. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  162900. +
  162901. + MEMORY_LOCK(Os);
  162902. +
  162903. + /* First try the contiguous memory pool. */
  162904. + if (Os->device->contiguousMapped)
  162905. + {
  162906. + base = (gctINT8_PTR) Os->device->contiguousBase;
  162907. +
  162908. + if (((gctINT8_PTR) Logical >= base)
  162909. + && ((gctINT8_PTR) Logical < base + Os->device->contiguousSize)
  162910. + )
  162911. + {
  162912. + /* Convert logical address into physical. */
  162913. + *Address = Os->device->contiguousVidMem->baseAddress
  162914. + + (gctINT8_PTR) Logical - base;
  162915. + status = gcvSTATUS_OK;
  162916. + }
  162917. + }
  162918. + else
  162919. + {
  162920. + /* Try the contiguous memory pool. */
  162921. + mdl = (PLINUX_MDL) Os->device->contiguousPhysical;
  162922. + status = _ConvertLogical2Physical(Os,
  162923. + Logical,
  162924. + ProcessID,
  162925. + mdl,
  162926. + Address);
  162927. + }
  162928. +
  162929. + if (gcmIS_ERROR(status))
  162930. + {
  162931. + /* Walk all MDLs. */
  162932. + for (mdl = Os->mdlHead; mdl != gcvNULL; mdl = mdl->next)
  162933. + {
  162934. + /* Try this MDL. */
  162935. + status = _ConvertLogical2Physical(Os,
  162936. + Logical,
  162937. + ProcessID,
  162938. + mdl,
  162939. + Address);
  162940. + if (gcmIS_SUCCESS(status))
  162941. + {
  162942. + break;
  162943. + }
  162944. + }
  162945. + }
  162946. +
  162947. + MEMORY_UNLOCK(Os);
  162948. +
  162949. + gcmkONERROR(status);
  162950. +
  162951. + /* Success. */
  162952. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  162953. + return gcvSTATUS_OK;
  162954. +
  162955. +OnError:
  162956. + /* Return the status. */
  162957. + gcmkFOOTER();
  162958. + return status;
  162959. +}
  162960. +
  162961. +/*******************************************************************************
  162962. +**
  162963. +** gckOS_MapPhysical
  162964. +**
  162965. +** Map a physical address into kernel space.
  162966. +**
  162967. +** INPUT:
  162968. +**
  162969. +** gckOS Os
  162970. +** Pointer to an gckOS object.
  162971. +**
  162972. +** gctUINT32 Physical
  162973. +** Physical address of the memory to map.
  162974. +**
  162975. +** gctSIZE_T Bytes
  162976. +** Number of bytes to map.
  162977. +**
  162978. +** OUTPUT:
  162979. +**
  162980. +** gctPOINTER * Logical
  162981. +** Pointer to a variable that receives the base address of the mapped
  162982. +** memory.
  162983. +*/
  162984. +gceSTATUS
  162985. +gckOS_MapPhysical(
  162986. + IN gckOS Os,
  162987. + IN gctUINT32 Physical,
  162988. + IN gctSIZE_T Bytes,
  162989. + OUT gctPOINTER * Logical
  162990. + )
  162991. +{
  162992. + gctPOINTER logical;
  162993. + PLINUX_MDL mdl;
  162994. + gctUINT32 physical = Physical;
  162995. +
  162996. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
  162997. +
  162998. + /* Verify the arguments. */
  162999. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163000. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  163001. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  163002. +
  163003. + MEMORY_LOCK(Os);
  163004. +
  163005. + /* Go through our mapping to see if we know this physical address already. */
  163006. + mdl = Os->mdlHead;
  163007. +
  163008. + while (mdl != gcvNULL)
  163009. + {
  163010. + if (mdl->dmaHandle != 0)
  163011. + {
  163012. + if ((physical >= mdl->dmaHandle)
  163013. + && (physical < mdl->dmaHandle + mdl->numPages * PAGE_SIZE)
  163014. + )
  163015. + {
  163016. + *Logical = mdl->addr + (physical - mdl->dmaHandle);
  163017. + break;
  163018. + }
  163019. + }
  163020. +
  163021. + mdl = mdl->next;
  163022. + }
  163023. +
  163024. + if (mdl == gcvNULL)
  163025. + {
  163026. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  163027. + struct contiguous_mem_pool *pool = Os->device->pool;
  163028. +
  163029. + if (Physical >= pool->phys && Physical < pool->phys + pool->size)
  163030. + logical = (gctPOINTER)(Physical - pool->phys + pool->virt);
  163031. + else
  163032. + logical = gcvNULL;
  163033. +#else
  163034. + /* Map memory as cached memory. */
  163035. + request_mem_region(physical, Bytes, "MapRegion");
  163036. + logical = (gctPOINTER) ioremap_nocache(physical, Bytes);
  163037. +#endif
  163038. +
  163039. + if (logical == gcvNULL)
  163040. + {
  163041. + gcmkTRACE_ZONE(
  163042. + gcvLEVEL_INFO, gcvZONE_OS,
  163043. + "%s(%d): Failed to map physical address 0x%08x",
  163044. + __FUNCTION__, __LINE__, Physical
  163045. + );
  163046. +
  163047. + MEMORY_UNLOCK(Os);
  163048. +
  163049. + /* Out of resources. */
  163050. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  163051. + return gcvSTATUS_OUT_OF_RESOURCES;
  163052. + }
  163053. +
  163054. + /* Return pointer to mapped memory. */
  163055. + *Logical = logical;
  163056. + }
  163057. +
  163058. + MEMORY_UNLOCK(Os);
  163059. +
  163060. + /* Success. */
  163061. + gcmkFOOTER_ARG("*Logical=0x%X", *Logical);
  163062. + return gcvSTATUS_OK;
  163063. +}
  163064. +
  163065. +/*******************************************************************************
  163066. +**
  163067. +** gckOS_UnmapPhysical
  163068. +**
  163069. +** Unmap a previously mapped memory region from kernel memory.
  163070. +**
  163071. +** INPUT:
  163072. +**
  163073. +** gckOS Os
  163074. +** Pointer to an gckOS object.
  163075. +**
  163076. +** gctPOINTER Logical
  163077. +** Pointer to the base address of the memory to unmap.
  163078. +**
  163079. +** gctSIZE_T Bytes
  163080. +** Number of bytes to unmap.
  163081. +**
  163082. +** OUTPUT:
  163083. +**
  163084. +** Nothing.
  163085. +*/
  163086. +gceSTATUS
  163087. +gckOS_UnmapPhysical(
  163088. + IN gckOS Os,
  163089. + IN gctPOINTER Logical,
  163090. + IN gctSIZE_T Bytes
  163091. + )
  163092. +{
  163093. + PLINUX_MDL mdl;
  163094. +
  163095. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu", Os, Logical, Bytes);
  163096. +
  163097. + /* Verify the arguments. */
  163098. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163099. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  163100. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  163101. +
  163102. + MEMORY_LOCK(Os);
  163103. +
  163104. + mdl = Os->mdlHead;
  163105. +
  163106. + while (mdl != gcvNULL)
  163107. + {
  163108. + if (mdl->addr != gcvNULL)
  163109. + {
  163110. + if (Logical >= (gctPOINTER)mdl->addr
  163111. + && Logical < (gctPOINTER)((gctSTRING)mdl->addr + mdl->numPages * PAGE_SIZE))
  163112. + {
  163113. + break;
  163114. + }
  163115. + }
  163116. +
  163117. + mdl = mdl->next;
  163118. + }
  163119. +
  163120. + if (mdl == gcvNULL)
  163121. + {
  163122. + /* Unmap the memory. */
  163123. + iounmap(Logical);
  163124. + }
  163125. +
  163126. + MEMORY_UNLOCK(Os);
  163127. +
  163128. + /* Success. */
  163129. + gcmkFOOTER_NO();
  163130. + return gcvSTATUS_OK;
  163131. +}
  163132. +
  163133. +/*******************************************************************************
  163134. +**
  163135. +** gckOS_CreateMutex
  163136. +**
  163137. +** Create a new mutex.
  163138. +**
  163139. +** INPUT:
  163140. +**
  163141. +** gckOS Os
  163142. +** Pointer to an gckOS object.
  163143. +**
  163144. +** OUTPUT:
  163145. +**
  163146. +** gctPOINTER * Mutex
  163147. +** Pointer to a variable that will hold a pointer to the mutex.
  163148. +*/
  163149. +gceSTATUS
  163150. +gckOS_CreateMutex(
  163151. + IN gckOS Os,
  163152. + OUT gctPOINTER * Mutex
  163153. + )
  163154. +{
  163155. + gceSTATUS status;
  163156. +
  163157. + gcmkHEADER_ARG("Os=0x%X", Os);
  163158. +
  163159. + /* Validate the arguments. */
  163160. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163161. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  163162. +
  163163. + /* Allocate the mutex structure. */
  163164. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(struct mutex), Mutex));
  163165. +
  163166. + /* Initialize the mutex. */
  163167. + mutex_init(*Mutex);
  163168. +
  163169. + /* Return status. */
  163170. + gcmkFOOTER_ARG("*Mutex=0x%X", *Mutex);
  163171. + return gcvSTATUS_OK;
  163172. +
  163173. +OnError:
  163174. + /* Return status. */
  163175. + gcmkFOOTER();
  163176. + return status;
  163177. +}
  163178. +
  163179. +/*******************************************************************************
  163180. +**
  163181. +** gckOS_DeleteMutex
  163182. +**
  163183. +** Delete a mutex.
  163184. +**
  163185. +** INPUT:
  163186. +**
  163187. +** gckOS Os
  163188. +** Pointer to an gckOS object.
  163189. +**
  163190. +** gctPOINTER Mutex
  163191. +** Pointer to the mute to be deleted.
  163192. +**
  163193. +** OUTPUT:
  163194. +**
  163195. +** Nothing.
  163196. +*/
  163197. +gceSTATUS
  163198. +gckOS_DeleteMutex(
  163199. + IN gckOS Os,
  163200. + IN gctPOINTER Mutex
  163201. + )
  163202. +{
  163203. + gceSTATUS status;
  163204. +
  163205. + gcmkHEADER_ARG("Os=0x%X Mutex=0x%X", Os, Mutex);
  163206. +
  163207. + /* Validate the arguments. */
  163208. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163209. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  163210. +
  163211. + /* Destroy the mutex. */
  163212. + mutex_destroy(Mutex);
  163213. +
  163214. + /* Free the mutex structure. */
  163215. + gcmkONERROR(gckOS_Free(Os, Mutex));
  163216. +
  163217. + gcmkFOOTER_NO();
  163218. + return gcvSTATUS_OK;
  163219. +
  163220. +OnError:
  163221. + /* Return status. */
  163222. + gcmkFOOTER();
  163223. + return status;
  163224. +}
  163225. +
  163226. +/*******************************************************************************
  163227. +**
  163228. +** gckOS_AcquireMutex
  163229. +**
  163230. +** Acquire a mutex.
  163231. +**
  163232. +** INPUT:
  163233. +**
  163234. +** gckOS Os
  163235. +** Pointer to an gckOS object.
  163236. +**
  163237. +** gctPOINTER Mutex
  163238. +** Pointer to the mutex to be acquired.
  163239. +**
  163240. +** gctUINT32 Timeout
  163241. +** Timeout value specified in milliseconds.
  163242. +** Specify the value of gcvINFINITE to keep the thread suspended
  163243. +** until the mutex has been acquired.
  163244. +**
  163245. +** OUTPUT:
  163246. +**
  163247. +** Nothing.
  163248. +*/
  163249. +gceSTATUS
  163250. +gckOS_AcquireMutex(
  163251. + IN gckOS Os,
  163252. + IN gctPOINTER Mutex,
  163253. + IN gctUINT32 Timeout
  163254. + )
  163255. +{
  163256. +#if gcdDETECT_TIMEOUT
  163257. + gctUINT32 timeout;
  163258. +#endif
  163259. +
  163260. + gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x Timeout=%u", Os, Mutex, Timeout);
  163261. +
  163262. + /* Validate the arguments. */
  163263. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163264. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  163265. +
  163266. +#if gcdDETECT_TIMEOUT
  163267. + timeout = 0;
  163268. +
  163269. + for (;;)
  163270. + {
  163271. + /* Try to acquire the mutex. */
  163272. + if (mutex_trylock(Mutex))
  163273. + {
  163274. + /* Success. */
  163275. + gcmkFOOTER_NO();
  163276. + return gcvSTATUS_OK;
  163277. + }
  163278. +
  163279. + /* Advance the timeout. */
  163280. + timeout += 1;
  163281. +
  163282. + if (Timeout == gcvINFINITE)
  163283. + {
  163284. + if (timeout == gcdINFINITE_TIMEOUT)
  163285. + {
  163286. + gctUINT32 dmaAddress1, dmaAddress2;
  163287. + gctUINT32 dmaState1, dmaState2;
  163288. +
  163289. + dmaState1 = dmaState2 =
  163290. + dmaAddress1 = dmaAddress2 = 0;
  163291. +
  163292. + /* Verify whether DMA is running. */
  163293. + gcmkVERIFY_OK(_VerifyDMA(
  163294. + Os, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
  163295. + ));
  163296. +
  163297. +#if gcdDETECT_DMA_ADDRESS
  163298. + /* Dump only if DMA appears stuck. */
  163299. + if (
  163300. + (dmaAddress1 == dmaAddress2)
  163301. +#if gcdDETECT_DMA_STATE
  163302. + && (dmaState1 == dmaState2)
  163303. +# endif
  163304. + )
  163305. +# endif
  163306. + {
  163307. + gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR));
  163308. +
  163309. + gcmkPRINT(
  163310. + "%s(%d): mutex 0x%X; forced message flush.",
  163311. + __FUNCTION__, __LINE__, Mutex
  163312. + );
  163313. +
  163314. + /* Flush the debug cache. */
  163315. + gcmkDEBUGFLUSH(dmaAddress2);
  163316. + }
  163317. +
  163318. + timeout = 0;
  163319. + }
  163320. + }
  163321. + else
  163322. + {
  163323. + /* Timedout? */
  163324. + if (timeout >= Timeout)
  163325. + {
  163326. + break;
  163327. + }
  163328. + }
  163329. +
  163330. + /* Wait for 1 millisecond. */
  163331. + gcmkVERIFY_OK(gckOS_Delay(Os, 1));
  163332. + }
  163333. +#else
  163334. + if (Timeout == gcvINFINITE)
  163335. + {
  163336. + /* Lock the mutex. */
  163337. + mutex_lock(Mutex);
  163338. +
  163339. + /* Success. */
  163340. + gcmkFOOTER_NO();
  163341. + return gcvSTATUS_OK;
  163342. + }
  163343. +
  163344. + for (;;)
  163345. + {
  163346. + /* Try to acquire the mutex. */
  163347. + if (mutex_trylock(Mutex))
  163348. + {
  163349. + /* Success. */
  163350. + gcmkFOOTER_NO();
  163351. + return gcvSTATUS_OK;
  163352. + }
  163353. +
  163354. + if (Timeout-- == 0)
  163355. + {
  163356. + break;
  163357. + }
  163358. +
  163359. + /* Wait for 1 millisecond. */
  163360. + gcmkVERIFY_OK(gckOS_Delay(Os, 1));
  163361. + }
  163362. +#endif
  163363. +
  163364. + /* Timeout. */
  163365. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_TIMEOUT);
  163366. + return gcvSTATUS_TIMEOUT;
  163367. +}
  163368. +
  163369. +/*******************************************************************************
  163370. +**
  163371. +** gckOS_ReleaseMutex
  163372. +**
  163373. +** Release an acquired mutex.
  163374. +**
  163375. +** INPUT:
  163376. +**
  163377. +** gckOS Os
  163378. +** Pointer to an gckOS object.
  163379. +**
  163380. +** gctPOINTER Mutex
  163381. +** Pointer to the mutex to be released.
  163382. +**
  163383. +** OUTPUT:
  163384. +**
  163385. +** Nothing.
  163386. +*/
  163387. +gceSTATUS
  163388. +gckOS_ReleaseMutex(
  163389. + IN gckOS Os,
  163390. + IN gctPOINTER Mutex
  163391. + )
  163392. +{
  163393. + gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x", Os, Mutex);
  163394. +
  163395. + /* Validate the arguments. */
  163396. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163397. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  163398. +
  163399. + /* Release the mutex. */
  163400. + mutex_unlock(Mutex);
  163401. +
  163402. + /* Success. */
  163403. + gcmkFOOTER_NO();
  163404. + return gcvSTATUS_OK;
  163405. +}
  163406. +
  163407. +/*******************************************************************************
  163408. +**
  163409. +** gckOS_AtomicExchange
  163410. +**
  163411. +** Atomically exchange a pair of 32-bit values.
  163412. +**
  163413. +** INPUT:
  163414. +**
  163415. +** gckOS Os
  163416. +** Pointer to an gckOS object.
  163417. +**
  163418. +** IN OUT gctINT32_PTR Target
  163419. +** Pointer to the 32-bit value to exchange.
  163420. +**
  163421. +** IN gctINT32 NewValue
  163422. +** Specifies a new value for the 32-bit value pointed to by Target.
  163423. +**
  163424. +** OUT gctINT32_PTR OldValue
  163425. +** The old value of the 32-bit value pointed to by Target.
  163426. +**
  163427. +** OUTPUT:
  163428. +**
  163429. +** Nothing.
  163430. +*/
  163431. +gceSTATUS
  163432. +gckOS_AtomicExchange(
  163433. + IN gckOS Os,
  163434. + IN OUT gctUINT32_PTR Target,
  163435. + IN gctUINT32 NewValue,
  163436. + OUT gctUINT32_PTR OldValue
  163437. + )
  163438. +{
  163439. + gcmkHEADER_ARG("Os=0x%X Target=0x%X NewValue=%u", Os, Target, NewValue);
  163440. +
  163441. + /* Verify the arguments. */
  163442. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163443. +
  163444. + /* Exchange the pair of 32-bit values. */
  163445. + *OldValue = (gctUINT32) atomic_xchg((atomic_t *) Target, (int) NewValue);
  163446. +
  163447. + /* Success. */
  163448. + gcmkFOOTER_ARG("*OldValue=%u", *OldValue);
  163449. + return gcvSTATUS_OK;
  163450. +}
  163451. +
  163452. +/*******************************************************************************
  163453. +**
  163454. +** gckOS_AtomicExchangePtr
  163455. +**
  163456. +** Atomically exchange a pair of pointers.
  163457. +**
  163458. +** INPUT:
  163459. +**
  163460. +** gckOS Os
  163461. +** Pointer to an gckOS object.
  163462. +**
  163463. +** IN OUT gctPOINTER * Target
  163464. +** Pointer to the 32-bit value to exchange.
  163465. +**
  163466. +** IN gctPOINTER NewValue
  163467. +** Specifies a new value for the pointer pointed to by Target.
  163468. +**
  163469. +** OUT gctPOINTER * OldValue
  163470. +** The old value of the pointer pointed to by Target.
  163471. +**
  163472. +** OUTPUT:
  163473. +**
  163474. +** Nothing.
  163475. +*/
  163476. +gceSTATUS
  163477. +gckOS_AtomicExchangePtr(
  163478. + IN gckOS Os,
  163479. + IN OUT gctPOINTER * Target,
  163480. + IN gctPOINTER NewValue,
  163481. + OUT gctPOINTER * OldValue
  163482. + )
  163483. +{
  163484. + gcmkHEADER_ARG("Os=0x%X Target=0x%X NewValue=0x%X", Os, Target, NewValue);
  163485. +
  163486. + /* Verify the arguments. */
  163487. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163488. +
  163489. + /* Exchange the pair of pointers. */
  163490. + *OldValue = (gctPOINTER)(gctUINTPTR_T) atomic_xchg((atomic_t *) Target, (int)(gctUINTPTR_T) NewValue);
  163491. +
  163492. + /* Success. */
  163493. + gcmkFOOTER_ARG("*OldValue=0x%X", *OldValue);
  163494. + return gcvSTATUS_OK;
  163495. +}
  163496. +
  163497. +#if gcdSMP
  163498. +/*******************************************************************************
  163499. +**
  163500. +** gckOS_AtomicSetMask
  163501. +**
  163502. +** Atomically set mask to Atom
  163503. +**
  163504. +** INPUT:
  163505. +** IN OUT gctPOINTER Atom
  163506. +** Pointer to the atom to set.
  163507. +**
  163508. +** IN gctUINT32 Mask
  163509. +** Mask to set.
  163510. +**
  163511. +** OUTPUT:
  163512. +**
  163513. +** Nothing.
  163514. +*/
  163515. +gceSTATUS
  163516. +gckOS_AtomSetMask(
  163517. + IN gctPOINTER Atom,
  163518. + IN gctUINT32 Mask
  163519. + )
  163520. +{
  163521. + gctUINT32 oval, nval;
  163522. +
  163523. + gcmkHEADER_ARG("Atom=0x%0x", Atom);
  163524. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163525. +
  163526. + do
  163527. + {
  163528. + oval = atomic_read((atomic_t *) Atom);
  163529. + nval = oval | Mask;
  163530. + } while (atomic_cmpxchg((atomic_t *) Atom, oval, nval) != oval);
  163531. +
  163532. + gcmkFOOTER_NO();
  163533. + return gcvSTATUS_OK;
  163534. +}
  163535. +
  163536. +/*******************************************************************************
  163537. +**
  163538. +** gckOS_AtomClearMask
  163539. +**
  163540. +** Atomically clear mask from Atom
  163541. +**
  163542. +** INPUT:
  163543. +** IN OUT gctPOINTER Atom
  163544. +** Pointer to the atom to clear.
  163545. +**
  163546. +** IN gctUINT32 Mask
  163547. +** Mask to clear.
  163548. +**
  163549. +** OUTPUT:
  163550. +**
  163551. +** Nothing.
  163552. +*/
  163553. +gceSTATUS
  163554. +gckOS_AtomClearMask(
  163555. + IN gctPOINTER Atom,
  163556. + IN gctUINT32 Mask
  163557. + )
  163558. +{
  163559. + gctUINT32 oval, nval;
  163560. +
  163561. + gcmkHEADER_ARG("Atom=0x%0x", Atom);
  163562. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163563. +
  163564. + do
  163565. + {
  163566. + oval = atomic_read((atomic_t *) Atom);
  163567. + nval = oval & ~Mask;
  163568. + } while (atomic_cmpxchg((atomic_t *) Atom, oval, nval) != oval);
  163569. +
  163570. + gcmkFOOTER_NO();
  163571. + return gcvSTATUS_OK;
  163572. +}
  163573. +#endif
  163574. +
  163575. +/*******************************************************************************
  163576. +**
  163577. +** gckOS_AtomConstruct
  163578. +**
  163579. +** Create an atom.
  163580. +**
  163581. +** INPUT:
  163582. +**
  163583. +** gckOS Os
  163584. +** Pointer to a gckOS object.
  163585. +**
  163586. +** OUTPUT:
  163587. +**
  163588. +** gctPOINTER * Atom
  163589. +** Pointer to a variable receiving the constructed atom.
  163590. +*/
  163591. +gceSTATUS
  163592. +gckOS_AtomConstruct(
  163593. + IN gckOS Os,
  163594. + OUT gctPOINTER * Atom
  163595. + )
  163596. +{
  163597. + gceSTATUS status;
  163598. +
  163599. + gcmkHEADER_ARG("Os=0x%X", Os);
  163600. +
  163601. + /* Verify the arguments. */
  163602. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163603. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163604. +
  163605. + /* Allocate the atom. */
  163606. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(atomic_t), Atom));
  163607. +
  163608. + /* Initialize the atom. */
  163609. + atomic_set((atomic_t *) *Atom, 0);
  163610. +
  163611. + /* Success. */
  163612. + gcmkFOOTER_ARG("*Atom=0x%X", *Atom);
  163613. + return gcvSTATUS_OK;
  163614. +
  163615. +OnError:
  163616. + /* Return the status. */
  163617. + gcmkFOOTER();
  163618. + return status;
  163619. +}
  163620. +
  163621. +/*******************************************************************************
  163622. +**
  163623. +** gckOS_AtomDestroy
  163624. +**
  163625. +** Destroy an atom.
  163626. +**
  163627. +** INPUT:
  163628. +**
  163629. +** gckOS Os
  163630. +** Pointer to a gckOS object.
  163631. +**
  163632. +** gctPOINTER Atom
  163633. +** Pointer to the atom to destroy.
  163634. +**
  163635. +** OUTPUT:
  163636. +**
  163637. +** Nothing.
  163638. +*/
  163639. +gceSTATUS
  163640. +gckOS_AtomDestroy(
  163641. + IN gckOS Os,
  163642. + OUT gctPOINTER Atom
  163643. + )
  163644. +{
  163645. + gceSTATUS status;
  163646. +
  163647. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  163648. +
  163649. + /* Verify the arguments. */
  163650. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163651. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163652. +
  163653. + /* Free the atom. */
  163654. + gcmkONERROR(gcmkOS_SAFE_FREE(Os, Atom));
  163655. +
  163656. + /* Success. */
  163657. + gcmkFOOTER_NO();
  163658. + return gcvSTATUS_OK;
  163659. +
  163660. +OnError:
  163661. + /* Return the status. */
  163662. + gcmkFOOTER();
  163663. + return status;
  163664. +}
  163665. +
  163666. +/*******************************************************************************
  163667. +**
  163668. +** gckOS_AtomGet
  163669. +**
  163670. +** Get the 32-bit value protected by an atom.
  163671. +**
  163672. +** INPUT:
  163673. +**
  163674. +** gckOS Os
  163675. +** Pointer to a gckOS object.
  163676. +**
  163677. +** gctPOINTER Atom
  163678. +** Pointer to the atom.
  163679. +**
  163680. +** OUTPUT:
  163681. +**
  163682. +** gctINT32_PTR Value
  163683. +** Pointer to a variable the receives the value of the atom.
  163684. +*/
  163685. +gceSTATUS
  163686. +gckOS_AtomGet(
  163687. + IN gckOS Os,
  163688. + IN gctPOINTER Atom,
  163689. + OUT gctINT32_PTR Value
  163690. + )
  163691. +{
  163692. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  163693. +
  163694. + /* Verify the arguments. */
  163695. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163696. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163697. +
  163698. + /* Return the current value of atom. */
  163699. + *Value = atomic_read((atomic_t *) Atom);
  163700. +
  163701. + /* Success. */
  163702. + gcmkFOOTER_ARG("*Value=%d", *Value);
  163703. + return gcvSTATUS_OK;
  163704. +}
  163705. +
  163706. +/*******************************************************************************
  163707. +**
  163708. +** gckOS_AtomSet
  163709. +**
  163710. +** Set the 32-bit value protected by an atom.
  163711. +**
  163712. +** INPUT:
  163713. +**
  163714. +** gckOS Os
  163715. +** Pointer to a gckOS object.
  163716. +**
  163717. +** gctPOINTER Atom
  163718. +** Pointer to the atom.
  163719. +**
  163720. +** gctINT32 Value
  163721. +** The value of the atom.
  163722. +**
  163723. +** OUTPUT:
  163724. +**
  163725. +** Nothing.
  163726. +*/
  163727. +gceSTATUS
  163728. +gckOS_AtomSet(
  163729. + IN gckOS Os,
  163730. + IN gctPOINTER Atom,
  163731. + IN gctINT32 Value
  163732. + )
  163733. +{
  163734. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x Value=%d", Os, Atom);
  163735. +
  163736. + /* Verify the arguments. */
  163737. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163738. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163739. +
  163740. + /* Set the current value of atom. */
  163741. + atomic_set((atomic_t *) Atom, Value);
  163742. +
  163743. + /* Success. */
  163744. + gcmkFOOTER_NO();
  163745. + return gcvSTATUS_OK;
  163746. +}
  163747. +
  163748. +/*******************************************************************************
  163749. +**
  163750. +** gckOS_AtomIncrement
  163751. +**
  163752. +** Atomically increment the 32-bit integer value inside an atom.
  163753. +**
  163754. +** INPUT:
  163755. +**
  163756. +** gckOS Os
  163757. +** Pointer to a gckOS object.
  163758. +**
  163759. +** gctPOINTER Atom
  163760. +** Pointer to the atom.
  163761. +**
  163762. +** OUTPUT:
  163763. +**
  163764. +** gctINT32_PTR Value
  163765. +** Pointer to a variable that receives the original value of the atom.
  163766. +*/
  163767. +gceSTATUS
  163768. +gckOS_AtomIncrement(
  163769. + IN gckOS Os,
  163770. + IN gctPOINTER Atom,
  163771. + OUT gctINT32_PTR Value
  163772. + )
  163773. +{
  163774. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  163775. +
  163776. + /* Verify the arguments. */
  163777. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163778. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163779. +
  163780. + /* Increment the atom. */
  163781. + *Value = atomic_inc_return((atomic_t *) Atom) - 1;
  163782. +
  163783. + /* Success. */
  163784. + gcmkFOOTER_ARG("*Value=%d", *Value);
  163785. + return gcvSTATUS_OK;
  163786. +}
  163787. +
  163788. +/*******************************************************************************
  163789. +**
  163790. +** gckOS_AtomDecrement
  163791. +**
  163792. +** Atomically decrement the 32-bit integer value inside an atom.
  163793. +**
  163794. +** INPUT:
  163795. +**
  163796. +** gckOS Os
  163797. +** Pointer to a gckOS object.
  163798. +**
  163799. +** gctPOINTER Atom
  163800. +** Pointer to the atom.
  163801. +**
  163802. +** OUTPUT:
  163803. +**
  163804. +** gctINT32_PTR Value
  163805. +** Pointer to a variable that receives the original value of the atom.
  163806. +*/
  163807. +gceSTATUS
  163808. +gckOS_AtomDecrement(
  163809. + IN gckOS Os,
  163810. + IN gctPOINTER Atom,
  163811. + OUT gctINT32_PTR Value
  163812. + )
  163813. +{
  163814. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  163815. +
  163816. + /* Verify the arguments. */
  163817. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163818. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163819. +
  163820. + /* Decrement the atom. */
  163821. + *Value = atomic_dec_return((atomic_t *) Atom) + 1;
  163822. +
  163823. + /* Success. */
  163824. + gcmkFOOTER_ARG("*Value=%d", *Value);
  163825. + return gcvSTATUS_OK;
  163826. +}
  163827. +
  163828. +/*******************************************************************************
  163829. +**
  163830. +** gckOS_Delay
  163831. +**
  163832. +** Delay execution of the current thread for a number of milliseconds.
  163833. +**
  163834. +** INPUT:
  163835. +**
  163836. +** gckOS Os
  163837. +** Pointer to an gckOS object.
  163838. +**
  163839. +** gctUINT32 Delay
  163840. +** Delay to sleep, specified in milliseconds.
  163841. +**
  163842. +** OUTPUT:
  163843. +**
  163844. +** Nothing.
  163845. +*/
  163846. +gceSTATUS
  163847. +gckOS_Delay(
  163848. + IN gckOS Os,
  163849. + IN gctUINT32 Delay
  163850. + )
  163851. +{
  163852. + gcmkHEADER_ARG("Os=0x%X Delay=%u", Os, Delay);
  163853. +
  163854. + if (Delay > 0)
  163855. + {
  163856. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
  163857. + ktime_t delay = ktime_set(Delay/1000, (Delay%1000) * NSEC_PER_MSEC);
  163858. + __set_current_state(TASK_UNINTERRUPTIBLE);
  163859. + schedule_hrtimeout(&delay, HRTIMER_MODE_REL);
  163860. +#else
  163861. + msleep(Delay);
  163862. +#endif
  163863. +
  163864. + }
  163865. +
  163866. + /* Success. */
  163867. + gcmkFOOTER_NO();
  163868. + return gcvSTATUS_OK;
  163869. +}
  163870. +
  163871. +/*******************************************************************************
  163872. +**
  163873. +** gckOS_GetTicks
  163874. +**
  163875. +** Get the number of milliseconds since the system started.
  163876. +**
  163877. +** INPUT:
  163878. +**
  163879. +** OUTPUT:
  163880. +**
  163881. +** gctUINT32_PTR Time
  163882. +** Pointer to a variable to get time.
  163883. +**
  163884. +*/
  163885. +gceSTATUS
  163886. +gckOS_GetTicks(
  163887. + OUT gctUINT32_PTR Time
  163888. + )
  163889. +{
  163890. + gcmkHEADER();
  163891. +
  163892. + *Time = jiffies_to_msecs(jiffies);
  163893. +
  163894. + gcmkFOOTER_NO();
  163895. + return gcvSTATUS_OK;
  163896. +}
  163897. +
  163898. +/*******************************************************************************
  163899. +**
  163900. +** gckOS_TicksAfter
  163901. +**
  163902. +** Compare time values got from gckOS_GetTicks.
  163903. +**
  163904. +** INPUT:
  163905. +** gctUINT32 Time1
  163906. +** First time value to be compared.
  163907. +**
  163908. +** gctUINT32 Time2
  163909. +** Second time value to be compared.
  163910. +**
  163911. +** OUTPUT:
  163912. +**
  163913. +** gctBOOL_PTR IsAfter
  163914. +** Pointer to a variable to result.
  163915. +**
  163916. +*/
  163917. +gceSTATUS
  163918. +gckOS_TicksAfter(
  163919. + IN gctUINT32 Time1,
  163920. + IN gctUINT32 Time2,
  163921. + OUT gctBOOL_PTR IsAfter
  163922. + )
  163923. +{
  163924. + gcmkHEADER();
  163925. +
  163926. + *IsAfter = time_after((unsigned long)Time1, (unsigned long)Time2);
  163927. +
  163928. + gcmkFOOTER_NO();
  163929. + return gcvSTATUS_OK;
  163930. +}
  163931. +
  163932. +/*******************************************************************************
  163933. +**
  163934. +** gckOS_GetTime
  163935. +**
  163936. +** Get the number of microseconds since the system started.
  163937. +**
  163938. +** INPUT:
  163939. +**
  163940. +** OUTPUT:
  163941. +**
  163942. +** gctUINT64_PTR Time
  163943. +** Pointer to a variable to get time.
  163944. +**
  163945. +*/
  163946. +gceSTATUS
  163947. +gckOS_GetTime(
  163948. + OUT gctUINT64_PTR Time
  163949. + )
  163950. +{
  163951. + gcmkHEADER();
  163952. +
  163953. + *Time = 0;
  163954. +
  163955. + gcmkFOOTER_NO();
  163956. + return gcvSTATUS_OK;
  163957. +}
  163958. +
  163959. +/*******************************************************************************
  163960. +**
  163961. +** gckOS_MemoryBarrier
  163962. +**
  163963. +** Make sure the CPU has executed everything up to this point and the data got
  163964. +** written to the specified pointer.
  163965. +**
  163966. +** INPUT:
  163967. +**
  163968. +** gckOS Os
  163969. +** Pointer to an gckOS object.
  163970. +**
  163971. +** gctPOINTER Address
  163972. +** Address of memory that needs to be barriered.
  163973. +**
  163974. +** OUTPUT:
  163975. +**
  163976. +** Nothing.
  163977. +*/
  163978. +gceSTATUS
  163979. +gckOS_MemoryBarrier(
  163980. + IN gckOS Os,
  163981. + IN gctPOINTER Address
  163982. + )
  163983. +{
  163984. + gcmkHEADER_ARG("Os=0x%X Address=0x%X", Os, Address);
  163985. +
  163986. + /* Verify the arguments. */
  163987. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163988. +
  163989. +#if gcdNONPAGED_MEMORY_BUFFERABLE \
  163990. + && defined (CONFIG_ARM) \
  163991. + && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
  163992. + /* drain write buffer */
  163993. + dsb();
  163994. +
  163995. + /* drain outer cache's write buffer? */
  163996. +#else
  163997. + mb();
  163998. +#endif
  163999. +
  164000. + /* Success. */
  164001. + gcmkFOOTER_NO();
  164002. + return gcvSTATUS_OK;
  164003. +}
  164004. +
  164005. +/*******************************************************************************
  164006. +**
  164007. +** gckOS_AllocatePagedMemory
  164008. +**
  164009. +** Allocate memory from the paged pool.
  164010. +**
  164011. +** INPUT:
  164012. +**
  164013. +** gckOS Os
  164014. +** Pointer to an gckOS object.
  164015. +**
  164016. +** gctSIZE_T Bytes
  164017. +** Number of bytes to allocate.
  164018. +**
  164019. +** OUTPUT:
  164020. +**
  164021. +** gctPHYS_ADDR * Physical
  164022. +** Pointer to a variable that receives the physical address of the
  164023. +** memory allocation.
  164024. +*/
  164025. +gceSTATUS
  164026. +gckOS_AllocatePagedMemory(
  164027. + IN gckOS Os,
  164028. + IN gctSIZE_T Bytes,
  164029. + OUT gctPHYS_ADDR * Physical
  164030. + )
  164031. +{
  164032. + gceSTATUS status;
  164033. +
  164034. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
  164035. +
  164036. + /* Verify the arguments. */
  164037. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164038. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  164039. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164040. +
  164041. + /* Allocate the memory. */
  164042. + gcmkONERROR(gckOS_AllocatePagedMemoryEx(Os, gcvFALSE, Bytes, Physical));
  164043. +
  164044. + /* Success. */
  164045. + gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
  164046. + return gcvSTATUS_OK;
  164047. +
  164048. +OnError:
  164049. + /* Return the status. */
  164050. + gcmkFOOTER();
  164051. + return status;
  164052. +}
  164053. +
  164054. +/*******************************************************************************
  164055. +**
  164056. +** gckOS_AllocatePagedMemoryEx
  164057. +**
  164058. +** Allocate memory from the paged pool.
  164059. +**
  164060. +** INPUT:
  164061. +**
  164062. +** gckOS Os
  164063. +** Pointer to an gckOS object.
  164064. +**
  164065. +** gctBOOL Contiguous
  164066. +** Need contiguous memory or not.
  164067. +**
  164068. +** gctSIZE_T Bytes
  164069. +** Number of bytes to allocate.
  164070. +**
  164071. +** OUTPUT:
  164072. +**
  164073. +** gctPHYS_ADDR * Physical
  164074. +** Pointer to a variable that receives the physical address of the
  164075. +** memory allocation.
  164076. +*/
  164077. +gceSTATUS
  164078. +gckOS_AllocatePagedMemoryEx(
  164079. + IN gckOS Os,
  164080. + IN gctBOOL Contiguous,
  164081. + IN gctSIZE_T Bytes,
  164082. + OUT gctPHYS_ADDR * Physical
  164083. + )
  164084. +{
  164085. + gctINT numPages;
  164086. + gctINT i;
  164087. + PLINUX_MDL mdl = gcvNULL;
  164088. + gctSIZE_T bytes;
  164089. + gctBOOL locked = gcvFALSE;
  164090. + gceSTATUS status;
  164091. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  164092. + gctPOINTER addr = gcvNULL;
  164093. +#endif
  164094. +
  164095. + gcmkHEADER_ARG("Os=0x%X Contiguous=%d Bytes=%lu", Os, Contiguous, Bytes);
  164096. +
  164097. + /* Verify the arguments. */
  164098. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164099. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  164100. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164101. +
  164102. + bytes = gcmALIGN(Bytes, PAGE_SIZE);
  164103. +
  164104. + numPages = GetPageCount(bytes, 0);
  164105. +
  164106. + MEMORY_LOCK(Os);
  164107. + locked = gcvTRUE;
  164108. +
  164109. + mdl = _CreateMdl(_GetProcessID());
  164110. + if (mdl == gcvNULL)
  164111. + {
  164112. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  164113. + }
  164114. +
  164115. + if (Contiguous)
  164116. + {
  164117. + gctUINT32 order = get_order(bytes);
  164118. +
  164119. + if (order >= MAX_ORDER)
  164120. + {
  164121. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  164122. + }
  164123. +
  164124. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  164125. + addr =
  164126. + alloc_pages_exact(numPages * PAGE_SIZE, GFP_KERNEL | gcdNOWARN | __GFP_NORETRY);
  164127. +
  164128. + mdl->u.contiguousPages = addr
  164129. + ? virt_to_page(addr)
  164130. + : gcvNULL;
  164131. +
  164132. + mdl->exact = gcvTRUE;
  164133. +#else
  164134. + mdl->u.contiguousPages =
  164135. + alloc_pages(GFP_KERNEL | gcdNOWARN | __GFP_NORETRY, order);
  164136. +#endif
  164137. + if (mdl->u.contiguousPages == gcvNULL)
  164138. + {
  164139. + mdl->u.contiguousPages =
  164140. + alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN, order);
  164141. +
  164142. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  164143. + mdl->exact = gcvFALSE;
  164144. +#endif
  164145. + }
  164146. + }
  164147. + else
  164148. + {
  164149. + mdl->u.nonContiguousPages = _NonContiguousAlloc(numPages);
  164150. + }
  164151. +
  164152. + if (mdl->u.contiguousPages == gcvNULL && mdl->u.nonContiguousPages == gcvNULL)
  164153. + {
  164154. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  164155. + }
  164156. +
  164157. + mdl->dmaHandle = 0;
  164158. + mdl->addr = 0;
  164159. + mdl->numPages = numPages;
  164160. + mdl->pagedMem = 1;
  164161. + mdl->contiguous = Contiguous;
  164162. +
  164163. + for (i = 0; i < mdl->numPages; i++)
  164164. + {
  164165. + struct page *page;
  164166. +
  164167. + if (mdl->contiguous)
  164168. + {
  164169. + page = nth_page(mdl->u.contiguousPages, i);
  164170. + }
  164171. + else
  164172. + {
  164173. + page = _NonContiguousToPage(mdl->u.nonContiguousPages, i);
  164174. + }
  164175. +
  164176. + SetPageReserved(page);
  164177. +
  164178. + if (!PageHighMem(page) && page_to_phys(page))
  164179. + {
  164180. + gcmkVERIFY_OK(
  164181. + gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
  164182. + (gctPOINTER)(gctUINTPTR_T)page_to_phys(page),
  164183. + page_address(page),
  164184. + PAGE_SIZE));
  164185. + }
  164186. + }
  164187. +
  164188. + /* Return physical address. */
  164189. + *Physical = (gctPHYS_ADDR) mdl;
  164190. +
  164191. + /*
  164192. + * Add this to a global list.
  164193. + * Will be used by get physical address
  164194. + * and mapuser pointer functions.
  164195. + */
  164196. + if (!Os->mdlHead)
  164197. + {
  164198. + /* Initialize the queue. */
  164199. + Os->mdlHead = Os->mdlTail = mdl;
  164200. + }
  164201. + else
  164202. + {
  164203. + /* Add to tail. */
  164204. + mdl->prev = Os->mdlTail;
  164205. + Os->mdlTail->next = mdl;
  164206. + Os->mdlTail = mdl;
  164207. + }
  164208. +
  164209. + MEMORY_UNLOCK(Os);
  164210. +
  164211. + /* Success. */
  164212. + gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
  164213. + return gcvSTATUS_OK;
  164214. +
  164215. +OnError:
  164216. + if (mdl != gcvNULL)
  164217. + {
  164218. + /* Free the memory. */
  164219. + _DestroyMdl(mdl);
  164220. + }
  164221. +
  164222. + if (locked)
  164223. + {
  164224. + /* Unlock the memory. */
  164225. + MEMORY_UNLOCK(Os);
  164226. + }
  164227. +
  164228. + /* Return the status. */
  164229. + gcmkFOOTER();
  164230. + return status;
  164231. +}
  164232. +
  164233. +/*******************************************************************************
  164234. +**
  164235. +** gckOS_FreePagedMemory
  164236. +**
  164237. +** Free memory allocated from the paged pool.
  164238. +**
  164239. +** INPUT:
  164240. +**
  164241. +** gckOS Os
  164242. +** Pointer to an gckOS object.
  164243. +**
  164244. +** gctPHYS_ADDR Physical
  164245. +** Physical address of the allocation.
  164246. +**
  164247. +** gctSIZE_T Bytes
  164248. +** Number of bytes of the allocation.
  164249. +**
  164250. +** OUTPUT:
  164251. +**
  164252. +** Nothing.
  164253. +*/
  164254. +gceSTATUS
  164255. +gckOS_FreePagedMemory(
  164256. + IN gckOS Os,
  164257. + IN gctPHYS_ADDR Physical,
  164258. + IN gctSIZE_T Bytes
  164259. + )
  164260. +{
  164261. + PLINUX_MDL mdl = (PLINUX_MDL) Physical;
  164262. + gctINT i;
  164263. +
  164264. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
  164265. +
  164266. + /* Verify the arguments. */
  164267. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164268. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164269. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  164270. +
  164271. + /*addr = mdl->addr;*/
  164272. +
  164273. + MEMORY_LOCK(Os);
  164274. +
  164275. + for (i = 0; i < mdl->numPages; i++)
  164276. + {
  164277. + if (mdl->contiguous)
  164278. + {
  164279. + ClearPageReserved(nth_page(mdl->u.contiguousPages, i));
  164280. + }
  164281. + else
  164282. + {
  164283. + ClearPageReserved(_NonContiguousToPage(mdl->u.nonContiguousPages, i));
  164284. + }
  164285. + }
  164286. +
  164287. + if (mdl->contiguous)
  164288. + {
  164289. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  164290. + if (mdl->exact == gcvTRUE)
  164291. + {
  164292. + free_pages_exact(page_address(mdl->u.contiguousPages), mdl->numPages * PAGE_SIZE);
  164293. + }
  164294. + else
  164295. +#endif
  164296. + {
  164297. + __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages));
  164298. + }
  164299. + }
  164300. + else
  164301. + {
  164302. + _NonContiguousFree(mdl->u.nonContiguousPages, mdl->numPages);
  164303. + }
  164304. +
  164305. + /* Remove the node from global list. */
  164306. + if (mdl == Os->mdlHead)
  164307. + {
  164308. + if ((Os->mdlHead = mdl->next) == gcvNULL)
  164309. + {
  164310. + Os->mdlTail = gcvNULL;
  164311. + }
  164312. + }
  164313. + else
  164314. + {
  164315. + mdl->prev->next = mdl->next;
  164316. +
  164317. + if (mdl == Os->mdlTail)
  164318. + {
  164319. + Os->mdlTail = mdl->prev;
  164320. + }
  164321. + else
  164322. + {
  164323. + mdl->next->prev = mdl->prev;
  164324. + }
  164325. + }
  164326. +
  164327. + MEMORY_UNLOCK(Os);
  164328. +
  164329. + /* Free the structure... */
  164330. + gcmkVERIFY_OK(_DestroyMdl(mdl));
  164331. +
  164332. + /* Success. */
  164333. + gcmkFOOTER_NO();
  164334. + return gcvSTATUS_OK;
  164335. +}
  164336. +
  164337. +/*******************************************************************************
  164338. +**
  164339. +** gckOS_LockPages
  164340. +**
  164341. +** Lock memory allocated from the paged pool.
  164342. +**
  164343. +** INPUT:
  164344. +**
  164345. +** gckOS Os
  164346. +** Pointer to an gckOS object.
  164347. +**
  164348. +** gctPHYS_ADDR Physical
  164349. +** Physical address of the allocation.
  164350. +**
  164351. +** gctSIZE_T Bytes
  164352. +** Number of bytes of the allocation.
  164353. +**
  164354. +** gctBOOL Cacheable
  164355. +** Cache mode of mapping.
  164356. +**
  164357. +** OUTPUT:
  164358. +**
  164359. +** gctPOINTER * Logical
  164360. +** Pointer to a variable that receives the address of the mapped
  164361. +** memory.
  164362. +**
  164363. +** gctSIZE_T * PageCount
  164364. +** Pointer to a variable that receives the number of pages required for
  164365. +** the page table according to the GPU page size.
  164366. +*/
  164367. +gceSTATUS
  164368. +gckOS_LockPages(
  164369. + IN gckOS Os,
  164370. + IN gctPHYS_ADDR Physical,
  164371. + IN gctSIZE_T Bytes,
  164372. + IN gctBOOL Cacheable,
  164373. + OUT gctPOINTER * Logical,
  164374. + OUT gctSIZE_T * PageCount
  164375. + )
  164376. +{
  164377. + PLINUX_MDL mdl;
  164378. + PLINUX_MDL_MAP mdlMap;
  164379. + gctSTRING addr;
  164380. + unsigned long start;
  164381. + unsigned long pfn;
  164382. + gctINT i;
  164383. +
  164384. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Logical);
  164385. +
  164386. + /* Verify the arguments. */
  164387. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164388. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164389. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164390. + gcmkVERIFY_ARGUMENT(PageCount != gcvNULL);
  164391. +
  164392. + mdl = (PLINUX_MDL) Physical;
  164393. +
  164394. + MEMORY_LOCK(Os);
  164395. +
  164396. + mdlMap = FindMdlMap(mdl, _GetProcessID());
  164397. +
  164398. + if (mdlMap == gcvNULL)
  164399. + {
  164400. + mdlMap = _CreateMdlMap(mdl, _GetProcessID());
  164401. +
  164402. + if (mdlMap == gcvNULL)
  164403. + {
  164404. + MEMORY_UNLOCK(Os);
  164405. +
  164406. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  164407. + return gcvSTATUS_OUT_OF_MEMORY;
  164408. + }
  164409. + }
  164410. +
  164411. + if (mdlMap->vmaAddr == gcvNULL)
  164412. + {
  164413. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
  164414. + mdlMap->vmaAddr = (gctSTRING)vm_mmap(gcvNULL,
  164415. + 0L,
  164416. + mdl->numPages * PAGE_SIZE,
  164417. + PROT_READ | PROT_WRITE,
  164418. + MAP_SHARED,
  164419. + 0);
  164420. +#else
  164421. + down_write(&current->mm->mmap_sem);
  164422. +
  164423. + mdlMap->vmaAddr = (gctSTRING)do_mmap_pgoff(gcvNULL,
  164424. + 0L,
  164425. + mdl->numPages * PAGE_SIZE,
  164426. + PROT_READ | PROT_WRITE,
  164427. + MAP_SHARED,
  164428. + 0);
  164429. +
  164430. + up_write(&current->mm->mmap_sem);
  164431. +#endif
  164432. +
  164433. + gcmkTRACE_ZONE(
  164434. + gcvLEVEL_INFO, gcvZONE_OS,
  164435. + "%s(%d): vmaAddr->0x%X for phys_addr->0x%X",
  164436. + __FUNCTION__, __LINE__,
  164437. + (gctUINT32)(gctUINTPTR_T)mdlMap->vmaAddr,
  164438. + (gctUINT32)(gctUINTPTR_T)mdl
  164439. + );
  164440. +
  164441. + if (IS_ERR(mdlMap->vmaAddr))
  164442. + {
  164443. + gcmkTRACE_ZONE(
  164444. + gcvLEVEL_INFO, gcvZONE_OS,
  164445. + "%s(%d): do_mmap_pgoff error",
  164446. + __FUNCTION__, __LINE__
  164447. + );
  164448. +
  164449. + mdlMap->vmaAddr = gcvNULL;
  164450. +
  164451. + MEMORY_UNLOCK(Os);
  164452. +
  164453. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  164454. + return gcvSTATUS_OUT_OF_MEMORY;
  164455. + }
  164456. +
  164457. + down_write(&current->mm->mmap_sem);
  164458. +
  164459. + mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
  164460. +
  164461. + if (mdlMap->vma == gcvNULL)
  164462. + {
  164463. + up_write(&current->mm->mmap_sem);
  164464. +
  164465. + gcmkTRACE_ZONE(
  164466. + gcvLEVEL_INFO, gcvZONE_OS,
  164467. + "%s(%d): find_vma error",
  164468. + __FUNCTION__, __LINE__
  164469. + );
  164470. +
  164471. + mdlMap->vmaAddr = gcvNULL;
  164472. +
  164473. + MEMORY_UNLOCK(Os);
  164474. +
  164475. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  164476. + return gcvSTATUS_OUT_OF_RESOURCES;
  164477. + }
  164478. +
  164479. + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
  164480. +
  164481. + if (Cacheable == gcvFALSE)
  164482. + {
  164483. + /* Make this mapping non-cached. */
  164484. + mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
  164485. + }
  164486. +
  164487. + addr = mdl->addr;
  164488. +
  164489. + /* Now map all the vmalloc pages to this user address. */
  164490. + if (mdl->contiguous)
  164491. + {
  164492. + /* map kernel memory to user space.. */
  164493. + if (remap_pfn_range(mdlMap->vma,
  164494. + mdlMap->vma->vm_start,
  164495. + page_to_pfn(mdl->u.contiguousPages),
  164496. + mdlMap->vma->vm_end - mdlMap->vma->vm_start,
  164497. + mdlMap->vma->vm_page_prot) < 0)
  164498. + {
  164499. + up_write(&current->mm->mmap_sem);
  164500. +
  164501. + gcmkTRACE_ZONE(
  164502. + gcvLEVEL_INFO, gcvZONE_OS,
  164503. + "%s(%d): unable to mmap ret",
  164504. + __FUNCTION__, __LINE__
  164505. + );
  164506. +
  164507. + mdlMap->vmaAddr = gcvNULL;
  164508. +
  164509. + MEMORY_UNLOCK(Os);
  164510. +
  164511. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  164512. + return gcvSTATUS_OUT_OF_MEMORY;
  164513. + }
  164514. + }
  164515. + else
  164516. + {
  164517. + start = mdlMap->vma->vm_start;
  164518. +
  164519. + for (i = 0; i < mdl->numPages; i++)
  164520. + {
  164521. + pfn = _NonContiguousToPfn(mdl->u.nonContiguousPages, i);
  164522. +
  164523. + if (remap_pfn_range(mdlMap->vma,
  164524. + start,
  164525. + pfn,
  164526. + PAGE_SIZE,
  164527. + mdlMap->vma->vm_page_prot) < 0)
  164528. + {
  164529. + up_write(&current->mm->mmap_sem);
  164530. +
  164531. + gcmkTRACE_ZONE(
  164532. + gcvLEVEL_INFO, gcvZONE_OS,
  164533. + "%s(%d): gctPHYS_ADDR->0x%X Logical->0x%X Unable to map addr->0x%X to start->0x%X",
  164534. + __FUNCTION__, __LINE__,
  164535. + (gctUINT32)(gctUINTPTR_T)Physical,
  164536. + (gctUINT32)(gctUINTPTR_T)*Logical,
  164537. + (gctUINT32)(gctUINTPTR_T)addr,
  164538. + (gctUINT32)(gctUINTPTR_T)start
  164539. + );
  164540. +
  164541. + mdlMap->vmaAddr = gcvNULL;
  164542. +
  164543. + MEMORY_UNLOCK(Os);
  164544. +
  164545. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  164546. + return gcvSTATUS_OUT_OF_MEMORY;
  164547. + }
  164548. +
  164549. + start += PAGE_SIZE;
  164550. + addr += PAGE_SIZE;
  164551. + }
  164552. + }
  164553. +
  164554. + up_write(&current->mm->mmap_sem);
  164555. + }
  164556. +
  164557. + mdlMap->count++;
  164558. +
  164559. + /* Convert pointer to MDL. */
  164560. + *Logical = mdlMap->vmaAddr;
  164561. +
  164562. + /* Return the page number according to the GPU page size. */
  164563. + gcmkASSERT((PAGE_SIZE % 4096) == 0);
  164564. + gcmkASSERT((PAGE_SIZE / 4096) >= 1);
  164565. +
  164566. + *PageCount = mdl->numPages * (PAGE_SIZE / 4096);
  164567. +
  164568. + MEMORY_UNLOCK(Os);
  164569. +
  164570. + gcmkVERIFY_OK(gckOS_CacheFlush(
  164571. + Os,
  164572. + _GetProcessID(),
  164573. + Physical,
  164574. + gcvNULL,
  164575. + (gctPOINTER)mdlMap->vmaAddr,
  164576. + mdl->numPages * PAGE_SIZE
  164577. + ));
  164578. +
  164579. + /* Success. */
  164580. + gcmkFOOTER_ARG("*Logical=0x%X *PageCount=%lu", *Logical, *PageCount);
  164581. + return gcvSTATUS_OK;
  164582. +}
  164583. +
  164584. +/*******************************************************************************
  164585. +**
  164586. +** gckOS_MapPages
  164587. +**
  164588. +** Map paged memory into a page table.
  164589. +**
  164590. +** INPUT:
  164591. +**
  164592. +** gckOS Os
  164593. +** Pointer to an gckOS object.
  164594. +**
  164595. +** gctPHYS_ADDR Physical
  164596. +** Physical address of the allocation.
  164597. +**
  164598. +** gctSIZE_T PageCount
  164599. +** Number of pages required for the physical address.
  164600. +**
  164601. +** gctPOINTER PageTable
  164602. +** Pointer to the page table to fill in.
  164603. +**
  164604. +** OUTPUT:
  164605. +**
  164606. +** Nothing.
  164607. +*/
  164608. +gceSTATUS
  164609. +gckOS_MapPages(
  164610. + IN gckOS Os,
  164611. + IN gctPHYS_ADDR Physical,
  164612. + IN gctSIZE_T PageCount,
  164613. + IN gctPOINTER PageTable
  164614. + )
  164615. +{
  164616. + return gckOS_MapPagesEx(Os,
  164617. + gcvCORE_MAJOR,
  164618. + Physical,
  164619. + PageCount,
  164620. + PageTable);
  164621. +}
  164622. +
  164623. +gceSTATUS
  164624. +gckOS_MapPagesEx(
  164625. + IN gckOS Os,
  164626. + IN gceCORE Core,
  164627. + IN gctPHYS_ADDR Physical,
  164628. + IN gctSIZE_T PageCount,
  164629. + IN gctPOINTER PageTable
  164630. + )
  164631. +{
  164632. + gceSTATUS status = gcvSTATUS_OK;
  164633. + PLINUX_MDL mdl;
  164634. + gctUINT32* table;
  164635. + gctUINT32 offset;
  164636. +#if gcdNONPAGED_MEMORY_CACHEABLE
  164637. + gckMMU mmu;
  164638. + PLINUX_MDL mmuMdl;
  164639. + gctUINT32 bytes;
  164640. + gctPHYS_ADDR pageTablePhysical;
  164641. +#endif
  164642. +
  164643. + gcmkHEADER_ARG("Os=0x%X Core=%d Physical=0x%X PageCount=%u PageTable=0x%X",
  164644. + Os, Core, Physical, PageCount, PageTable);
  164645. +
  164646. + /* Verify the arguments. */
  164647. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164648. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164649. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  164650. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  164651. +
  164652. + /* Convert pointer to MDL. */
  164653. + mdl = (PLINUX_MDL)Physical;
  164654. +
  164655. + gcmkTRACE_ZONE(
  164656. + gcvLEVEL_INFO, gcvZONE_OS,
  164657. + "%s(%d): Physical->0x%X PageCount->0x%X PagedMemory->?%d",
  164658. + __FUNCTION__, __LINE__,
  164659. + (gctUINT32)(gctUINTPTR_T)Physical,
  164660. + (gctUINT32)(gctUINTPTR_T)PageCount,
  164661. + mdl->pagedMem
  164662. + );
  164663. +
  164664. + MEMORY_LOCK(Os);
  164665. +
  164666. + table = (gctUINT32 *)PageTable;
  164667. +#if gcdNONPAGED_MEMORY_CACHEABLE
  164668. + mmu = Os->device->kernels[Core]->mmu;
  164669. + bytes = PageCount * sizeof(*table);
  164670. + mmuMdl = (PLINUX_MDL)mmu->pageTablePhysical;
  164671. +#endif
  164672. +
  164673. + /* Get all the physical addresses and store them in the page table. */
  164674. +
  164675. + offset = 0;
  164676. +
  164677. + if (mdl->pagedMem)
  164678. + {
  164679. + /* Try to get the user pages so DMA can happen. */
  164680. + while (PageCount-- > 0)
  164681. + {
  164682. +#if gcdENABLE_VG
  164683. + if (Core == gcvCORE_VG)
  164684. + {
  164685. + if (mdl->contiguous)
  164686. + {
  164687. + gcmkONERROR(
  164688. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  164689. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  164690. + table));
  164691. + }
  164692. + else
  164693. + {
  164694. + gcmkONERROR(
  164695. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  164696. + _NonContiguousToPhys(mdl->u.nonContiguousPages, offset),
  164697. + table));
  164698. + }
  164699. + }
  164700. + else
  164701. +#endif
  164702. + {
  164703. + if (mdl->contiguous)
  164704. + {
  164705. + gcmkONERROR(
  164706. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  164707. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  164708. + table));
  164709. + }
  164710. + else
  164711. + {
  164712. + gcmkONERROR(
  164713. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  164714. + _NonContiguousToPhys(mdl->u.nonContiguousPages, offset),
  164715. + table));
  164716. + }
  164717. + }
  164718. +
  164719. + table++;
  164720. + offset += 1;
  164721. + }
  164722. + }
  164723. + else
  164724. + {
  164725. + gcmkTRACE_ZONE(
  164726. + gcvLEVEL_INFO, gcvZONE_OS,
  164727. + "%s(%d): we should not get this call for Non Paged Memory!",
  164728. + __FUNCTION__, __LINE__
  164729. + );
  164730. +
  164731. + while (PageCount-- > 0)
  164732. + {
  164733. +#if gcdENABLE_VG
  164734. + if (Core == gcvCORE_VG)
  164735. + {
  164736. + gcmkONERROR(
  164737. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  164738. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  164739. + table));
  164740. + }
  164741. + else
  164742. +#endif
  164743. + {
  164744. + gcmkONERROR(
  164745. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  164746. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  164747. + table));
  164748. + }
  164749. + table++;
  164750. + offset += 1;
  164751. + }
  164752. + }
  164753. +
  164754. +#if gcdNONPAGED_MEMORY_CACHEABLE
  164755. + /* Get physical address of pageTable */
  164756. + pageTablePhysical = (gctPHYS_ADDR)(mmuMdl->dmaHandle +
  164757. + ((gctUINT32 *)PageTable - mmu->pageTableLogical));
  164758. +
  164759. + /* Flush the mmu page table cache. */
  164760. + gcmkONERROR(gckOS_CacheClean(
  164761. + Os,
  164762. + _GetProcessID(),
  164763. + gcvNULL,
  164764. + pageTablePhysical,
  164765. + PageTable,
  164766. + bytes
  164767. + ));
  164768. +#endif
  164769. +
  164770. +OnError:
  164771. +
  164772. + MEMORY_UNLOCK(Os);
  164773. +
  164774. + /* Return the status. */
  164775. + gcmkFOOTER();
  164776. + return status;
  164777. +}
  164778. +
  164779. +/*******************************************************************************
  164780. +**
  164781. +** gckOS_UnlockPages
  164782. +**
  164783. +** Unlock memory allocated from the paged pool.
  164784. +**
  164785. +** INPUT:
  164786. +**
  164787. +** gckOS Os
  164788. +** Pointer to an gckOS object.
  164789. +**
  164790. +** gctPHYS_ADDR Physical
  164791. +** Physical address of the allocation.
  164792. +**
  164793. +** gctSIZE_T Bytes
  164794. +** Number of bytes of the allocation.
  164795. +**
  164796. +** gctPOINTER Logical
  164797. +** Address of the mapped memory.
  164798. +**
  164799. +** OUTPUT:
  164800. +**
  164801. +** Nothing.
  164802. +*/
  164803. +gceSTATUS
  164804. +gckOS_UnlockPages(
  164805. + IN gckOS Os,
  164806. + IN gctPHYS_ADDR Physical,
  164807. + IN gctSIZE_T Bytes,
  164808. + IN gctPOINTER Logical
  164809. + )
  164810. +{
  164811. + PLINUX_MDL_MAP mdlMap;
  164812. + PLINUX_MDL mdl = (PLINUX_MDL)Physical;
  164813. +
  164814. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%u Logical=0x%X",
  164815. + Os, Physical, Bytes, Logical);
  164816. +
  164817. + /* Verify the arguments. */
  164818. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164819. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164820. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164821. +
  164822. + /* Make sure there is already a mapping...*/
  164823. + gcmkVERIFY_ARGUMENT(mdl->u.nonContiguousPages != gcvNULL
  164824. + || mdl->u.contiguousPages != gcvNULL);
  164825. +
  164826. + MEMORY_LOCK(Os);
  164827. +
  164828. + mdlMap = mdl->maps;
  164829. +
  164830. + while (mdlMap != gcvNULL)
  164831. + {
  164832. + if ((mdlMap->vmaAddr != gcvNULL) && (_GetProcessID() == mdlMap->pid))
  164833. + {
  164834. + if (--mdlMap->count == 0)
  164835. + {
  164836. + _UnmapUserLogical(mdlMap->pid, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
  164837. + mdlMap->vmaAddr = gcvNULL;
  164838. + }
  164839. + }
  164840. +
  164841. + mdlMap = mdlMap->next;
  164842. + }
  164843. +
  164844. + MEMORY_UNLOCK(Os);
  164845. +
  164846. + /* Success. */
  164847. + gcmkFOOTER_NO();
  164848. + return gcvSTATUS_OK;
  164849. +}
  164850. +
  164851. +
  164852. +/*******************************************************************************
  164853. +**
  164854. +** gckOS_AllocateContiguous
  164855. +**
  164856. +** Allocate memory from the contiguous pool.
  164857. +**
  164858. +** INPUT:
  164859. +**
  164860. +** gckOS Os
  164861. +** Pointer to an gckOS object.
  164862. +**
  164863. +** gctBOOL InUserSpace
  164864. +** gcvTRUE if the pages need to be mapped into user space.
  164865. +**
  164866. +** gctSIZE_T * Bytes
  164867. +** Pointer to the number of bytes to allocate.
  164868. +**
  164869. +** OUTPUT:
  164870. +**
  164871. +** gctSIZE_T * Bytes
  164872. +** Pointer to a variable that receives the number of bytes allocated.
  164873. +**
  164874. +** gctPHYS_ADDR * Physical
  164875. +** Pointer to a variable that receives the physical address of the
  164876. +** memory allocation.
  164877. +**
  164878. +** gctPOINTER * Logical
  164879. +** Pointer to a variable that receives the logical address of the
  164880. +** memory allocation.
  164881. +*/
  164882. +gceSTATUS
  164883. +gckOS_AllocateContiguous(
  164884. + IN gckOS Os,
  164885. + IN gctBOOL InUserSpace,
  164886. + IN OUT gctSIZE_T * Bytes,
  164887. + OUT gctPHYS_ADDR * Physical,
  164888. + OUT gctPOINTER * Logical
  164889. + )
  164890. +{
  164891. + gceSTATUS status;
  164892. +
  164893. + gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
  164894. + Os, InUserSpace, gcmOPT_VALUE(Bytes));
  164895. +
  164896. + /* Verify the arguments. */
  164897. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164898. + gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
  164899. + gcmkVERIFY_ARGUMENT(*Bytes > 0);
  164900. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164901. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164902. +
  164903. + /* Same as non-paged memory for now. */
  164904. + gcmkONERROR(gckOS_AllocateNonPagedMemory(Os,
  164905. + InUserSpace,
  164906. + Bytes,
  164907. + Physical,
  164908. + Logical));
  164909. +
  164910. + /* Success. */
  164911. + gcmkFOOTER_ARG("*Bytes=%lu *Physical=0x%X *Logical=0x%X",
  164912. + *Bytes, *Physical, *Logical);
  164913. + return gcvSTATUS_OK;
  164914. +
  164915. +OnError:
  164916. + /* Return the status. */
  164917. + gcmkFOOTER();
  164918. + return status;
  164919. +}
  164920. +
  164921. +/*******************************************************************************
  164922. +**
  164923. +** gckOS_FreeContiguous
  164924. +**
  164925. +** Free memory allocated from the contiguous pool.
  164926. +**
  164927. +** INPUT:
  164928. +**
  164929. +** gckOS Os
  164930. +** Pointer to an gckOS object.
  164931. +**
  164932. +** gctPHYS_ADDR Physical
  164933. +** Physical address of the allocation.
  164934. +**
  164935. +** gctPOINTER Logical
  164936. +** Logicval address of the allocation.
  164937. +**
  164938. +** gctSIZE_T Bytes
  164939. +** Number of bytes of the allocation.
  164940. +**
  164941. +** OUTPUT:
  164942. +**
  164943. +** Nothing.
  164944. +*/
  164945. +gceSTATUS
  164946. +gckOS_FreeContiguous(
  164947. + IN gckOS Os,
  164948. + IN gctPHYS_ADDR Physical,
  164949. + IN gctPOINTER Logical,
  164950. + IN gctSIZE_T Bytes
  164951. + )
  164952. +{
  164953. + gceSTATUS status;
  164954. +
  164955. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Logical=0x%X Bytes=%lu",
  164956. + Os, Physical, Logical, Bytes);
  164957. +
  164958. + /* Verify the arguments. */
  164959. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164960. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164961. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164962. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  164963. +
  164964. + /* Same of non-paged memory for now. */
  164965. + gcmkONERROR(gckOS_FreeNonPagedMemory(Os, Bytes, Physical, Logical));
  164966. +
  164967. + /* Success. */
  164968. + gcmkFOOTER_NO();
  164969. + return gcvSTATUS_OK;
  164970. +
  164971. +OnError:
  164972. + /* Return the status. */
  164973. + gcmkFOOTER();
  164974. + return status;
  164975. +}
  164976. +
  164977. +#if gcdENABLE_VG
  164978. +/******************************************************************************
  164979. +**
  164980. +** gckOS_GetKernelLogical
  164981. +**
  164982. +** Return the kernel logical pointer that corresponods to the specified
  164983. +** hardware address.
  164984. +**
  164985. +** INPUT:
  164986. +**
  164987. +** gckOS Os
  164988. +** Pointer to an gckOS object.
  164989. +**
  164990. +** gctUINT32 Address
  164991. +** Hardware physical address.
  164992. +**
  164993. +** OUTPUT:
  164994. +**
  164995. +** gctPOINTER * KernelPointer
  164996. +** Pointer to a variable receiving the pointer in kernel address space.
  164997. +*/
  164998. +gceSTATUS
  164999. +gckOS_GetKernelLogical(
  165000. + IN gckOS Os,
  165001. + IN gctUINT32 Address,
  165002. + OUT gctPOINTER * KernelPointer
  165003. + )
  165004. +{
  165005. + return gckOS_GetKernelLogicalEx(Os, gcvCORE_MAJOR, Address, KernelPointer);
  165006. +}
  165007. +
  165008. +gceSTATUS
  165009. +gckOS_GetKernelLogicalEx(
  165010. + IN gckOS Os,
  165011. + IN gceCORE Core,
  165012. + IN gctUINT32 Address,
  165013. + OUT gctPOINTER * KernelPointer
  165014. + )
  165015. +{
  165016. + gceSTATUS status;
  165017. +
  165018. + gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%08x", Os, Core, Address);
  165019. +
  165020. + do
  165021. + {
  165022. + gckGALDEVICE device;
  165023. + gckKERNEL kernel;
  165024. + gcePOOL pool;
  165025. + gctUINT32 offset;
  165026. + gctPOINTER logical;
  165027. +
  165028. + /* Extract the pointer to the gckGALDEVICE class. */
  165029. + device = (gckGALDEVICE) Os->device;
  165030. +
  165031. + /* Kernel shortcut. */
  165032. + kernel = device->kernels[Core];
  165033. +#if gcdENABLE_VG
  165034. + if (Core == gcvCORE_VG)
  165035. + {
  165036. + gcmkERR_BREAK(gckVGHARDWARE_SplitMemory(
  165037. + kernel->vg->hardware, Address, &pool, &offset
  165038. + ));
  165039. + }
  165040. + else
  165041. +#endif
  165042. + {
  165043. + /* Split the memory address into a pool type and offset. */
  165044. + gcmkERR_BREAK(gckHARDWARE_SplitMemory(
  165045. + kernel->hardware, Address, &pool, &offset
  165046. + ));
  165047. + }
  165048. +
  165049. + /* Dispatch on pool. */
  165050. + switch (pool)
  165051. + {
  165052. + case gcvPOOL_LOCAL_INTERNAL:
  165053. + /* Internal memory. */
  165054. + logical = device->internalLogical;
  165055. + break;
  165056. +
  165057. + case gcvPOOL_LOCAL_EXTERNAL:
  165058. + /* External memory. */
  165059. + logical = device->externalLogical;
  165060. + break;
  165061. +
  165062. + case gcvPOOL_SYSTEM:
  165063. + /* System memory. */
  165064. + logical = device->contiguousBase;
  165065. + break;
  165066. +
  165067. + default:
  165068. + /* Invalid memory pool. */
  165069. + gcmkFOOTER();
  165070. + return gcvSTATUS_INVALID_ARGUMENT;
  165071. + }
  165072. +
  165073. + /* Build logical address of specified address. */
  165074. + * KernelPointer = ((gctUINT8_PTR) logical) + offset;
  165075. +
  165076. + /* Success. */
  165077. + gcmkFOOTER_ARG("*KernelPointer=0x%X", *KernelPointer);
  165078. + return gcvSTATUS_OK;
  165079. + }
  165080. + while (gcvFALSE);
  165081. +
  165082. + /* Return status. */
  165083. + gcmkFOOTER();
  165084. + return status;
  165085. +}
  165086. +#endif
  165087. +
  165088. +/*******************************************************************************
  165089. +**
  165090. +** gckOS_MapUserPointer
  165091. +**
  165092. +** Map a pointer from the user process into the kernel address space.
  165093. +**
  165094. +** INPUT:
  165095. +**
  165096. +** gckOS Os
  165097. +** Pointer to an gckOS object.
  165098. +**
  165099. +** gctPOINTER Pointer
  165100. +** Pointer in user process space that needs to be mapped.
  165101. +**
  165102. +** gctSIZE_T Size
  165103. +** Number of bytes that need to be mapped.
  165104. +**
  165105. +** OUTPUT:
  165106. +**
  165107. +** gctPOINTER * KernelPointer
  165108. +** Pointer to a variable receiving the mapped pointer in kernel address
  165109. +** space.
  165110. +*/
  165111. +gceSTATUS
  165112. +gckOS_MapUserPointer(
  165113. + IN gckOS Os,
  165114. + IN gctPOINTER Pointer,
  165115. + IN gctSIZE_T Size,
  165116. + OUT gctPOINTER * KernelPointer
  165117. + )
  165118. +{
  165119. + gctPOINTER buf = gcvNULL;
  165120. + gctUINT32 len;
  165121. +
  165122. + gcmkHEADER_ARG("Os=0x%X Pointer=0x%X Size=%lu", Os, Pointer, Size);
  165123. +
  165124. + /* Verify the arguments. */
  165125. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165126. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  165127. + gcmkVERIFY_ARGUMENT(Size > 0);
  165128. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  165129. +
  165130. + buf = kmalloc(Size, GFP_KERNEL | gcdNOWARN);
  165131. + if (buf == gcvNULL)
  165132. + {
  165133. + gcmkTRACE(
  165134. + gcvLEVEL_ERROR,
  165135. + "%s(%d): Failed to allocate memory.",
  165136. + __FUNCTION__, __LINE__
  165137. + );
  165138. +
  165139. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  165140. + return gcvSTATUS_OUT_OF_MEMORY;
  165141. + }
  165142. +
  165143. + len = copy_from_user(buf, Pointer, Size);
  165144. + if (len != 0)
  165145. + {
  165146. + gcmkTRACE(
  165147. + gcvLEVEL_ERROR,
  165148. + "%s(%d): Failed to copy data from user.",
  165149. + __FUNCTION__, __LINE__
  165150. + );
  165151. +
  165152. + if (buf != gcvNULL)
  165153. + {
  165154. + kfree(buf);
  165155. + }
  165156. +
  165157. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_GENERIC_IO);
  165158. + return gcvSTATUS_GENERIC_IO;
  165159. + }
  165160. +
  165161. + *KernelPointer = buf;
  165162. +
  165163. + gcmkFOOTER_ARG("*KernelPointer=0x%X", *KernelPointer);
  165164. + return gcvSTATUS_OK;
  165165. +}
  165166. +
  165167. +/*******************************************************************************
  165168. +**
  165169. +** gckOS_UnmapUserPointer
  165170. +**
  165171. +** Unmap a user process pointer from the kernel address space.
  165172. +**
  165173. +** INPUT:
  165174. +**
  165175. +** gckOS Os
  165176. +** Pointer to an gckOS object.
  165177. +**
  165178. +** gctPOINTER Pointer
  165179. +** Pointer in user process space that needs to be unmapped.
  165180. +**
  165181. +** gctSIZE_T Size
  165182. +** Number of bytes that need to be unmapped.
  165183. +**
  165184. +** gctPOINTER KernelPointer
  165185. +** Pointer in kernel address space that needs to be unmapped.
  165186. +**
  165187. +** OUTPUT:
  165188. +**
  165189. +** Nothing.
  165190. +*/
  165191. +gceSTATUS
  165192. +gckOS_UnmapUserPointer(
  165193. + IN gckOS Os,
  165194. + IN gctPOINTER Pointer,
  165195. + IN gctSIZE_T Size,
  165196. + IN gctPOINTER KernelPointer
  165197. + )
  165198. +{
  165199. + gctUINT32 len;
  165200. +
  165201. + gcmkHEADER_ARG("Os=0x%X Pointer=0x%X Size=%lu KernelPointer=0x%X",
  165202. + Os, Pointer, Size, KernelPointer);
  165203. +
  165204. +
  165205. + /* Verify the arguments. */
  165206. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165207. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  165208. + gcmkVERIFY_ARGUMENT(Size > 0);
  165209. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  165210. +
  165211. + len = copy_to_user(Pointer, KernelPointer, Size);
  165212. +
  165213. + kfree(KernelPointer);
  165214. +
  165215. + if (len != 0)
  165216. + {
  165217. + gcmkTRACE(
  165218. + gcvLEVEL_ERROR,
  165219. + "%s(%d): Failed to copy data to user.",
  165220. + __FUNCTION__, __LINE__
  165221. + );
  165222. +
  165223. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
  165224. + return gcvSTATUS_GENERIC_IO;
  165225. + }
  165226. +
  165227. + gcmkFOOTER_NO();
  165228. + return gcvSTATUS_OK;
  165229. +}
  165230. +
  165231. +/*******************************************************************************
  165232. +**
  165233. +** gckOS_QueryNeedCopy
  165234. +**
  165235. +** Query whether the memory can be accessed or mapped directly or it has to be
  165236. +** copied.
  165237. +**
  165238. +** INPUT:
  165239. +**
  165240. +** gckOS Os
  165241. +** Pointer to an gckOS object.
  165242. +**
  165243. +** gctUINT32 ProcessID
  165244. +** Process ID of the current process.
  165245. +**
  165246. +** OUTPUT:
  165247. +**
  165248. +** gctBOOL_PTR NeedCopy
  165249. +** Pointer to a boolean receiving gcvTRUE if the memory needs a copy or
  165250. +** gcvFALSE if the memory can be accessed or mapped dircetly.
  165251. +*/
  165252. +gceSTATUS
  165253. +gckOS_QueryNeedCopy(
  165254. + IN gckOS Os,
  165255. + IN gctUINT32 ProcessID,
  165256. + OUT gctBOOL_PTR NeedCopy
  165257. + )
  165258. +{
  165259. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d", Os, ProcessID);
  165260. +
  165261. + /* Verify the arguments. */
  165262. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165263. + gcmkVERIFY_ARGUMENT(NeedCopy != gcvNULL);
  165264. +
  165265. + /* We need to copy data. */
  165266. + *NeedCopy = gcvTRUE;
  165267. +
  165268. + /* Success. */
  165269. + gcmkFOOTER_ARG("*NeedCopy=%d", *NeedCopy);
  165270. + return gcvSTATUS_OK;
  165271. +}
  165272. +
  165273. +/*******************************************************************************
  165274. +**
  165275. +** gckOS_CopyFromUserData
  165276. +**
  165277. +** Copy data from user to kernel memory.
  165278. +**
  165279. +** INPUT:
  165280. +**
  165281. +** gckOS Os
  165282. +** Pointer to an gckOS object.
  165283. +**
  165284. +** gctPOINTER KernelPointer
  165285. +** Pointer to kernel memory.
  165286. +**
  165287. +** gctPOINTER Pointer
  165288. +** Pointer to user memory.
  165289. +**
  165290. +** gctSIZE_T Size
  165291. +** Number of bytes to copy.
  165292. +**
  165293. +** OUTPUT:
  165294. +**
  165295. +** Nothing.
  165296. +*/
  165297. +gceSTATUS
  165298. +gckOS_CopyFromUserData(
  165299. + IN gckOS Os,
  165300. + IN gctPOINTER KernelPointer,
  165301. + IN gctPOINTER Pointer,
  165302. + IN gctSIZE_T Size
  165303. + )
  165304. +{
  165305. + gceSTATUS status;
  165306. +
  165307. + gcmkHEADER_ARG("Os=0x%X KernelPointer=0x%X Pointer=0x%X Size=%lu",
  165308. + Os, KernelPointer, Pointer, Size);
  165309. +
  165310. + /* Verify the arguments. */
  165311. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165312. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  165313. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  165314. + gcmkVERIFY_ARGUMENT(Size > 0);
  165315. +
  165316. + /* Copy data from user. */
  165317. + if (copy_from_user(KernelPointer, Pointer, Size) != 0)
  165318. + {
  165319. + /* Could not copy all the bytes. */
  165320. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  165321. + }
  165322. +
  165323. + /* Success. */
  165324. + gcmkFOOTER_NO();
  165325. + return gcvSTATUS_OK;
  165326. +
  165327. +OnError:
  165328. + /* Return the status. */
  165329. + gcmkFOOTER();
  165330. + return status;
  165331. +}
  165332. +
  165333. +/*******************************************************************************
  165334. +**
  165335. +** gckOS_CopyToUserData
  165336. +**
  165337. +** Copy data from kernel to user memory.
  165338. +**
  165339. +** INPUT:
  165340. +**
  165341. +** gckOS Os
  165342. +** Pointer to an gckOS object.
  165343. +**
  165344. +** gctPOINTER KernelPointer
  165345. +** Pointer to kernel memory.
  165346. +**
  165347. +** gctPOINTER Pointer
  165348. +** Pointer to user memory.
  165349. +**
  165350. +** gctSIZE_T Size
  165351. +** Number of bytes to copy.
  165352. +**
  165353. +** OUTPUT:
  165354. +**
  165355. +** Nothing.
  165356. +*/
  165357. +gceSTATUS
  165358. +gckOS_CopyToUserData(
  165359. + IN gckOS Os,
  165360. + IN gctPOINTER KernelPointer,
  165361. + IN gctPOINTER Pointer,
  165362. + IN gctSIZE_T Size
  165363. + )
  165364. +{
  165365. + gceSTATUS status;
  165366. +
  165367. + gcmkHEADER_ARG("Os=0x%X KernelPointer=0x%X Pointer=0x%X Size=%lu",
  165368. + Os, KernelPointer, Pointer, Size);
  165369. +
  165370. + /* Verify the arguments. */
  165371. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165372. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  165373. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  165374. + gcmkVERIFY_ARGUMENT(Size > 0);
  165375. +
  165376. + /* Copy data to user. */
  165377. + if (copy_to_user(Pointer, KernelPointer, Size) != 0)
  165378. + {
  165379. + /* Could not copy all the bytes. */
  165380. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  165381. + }
  165382. +
  165383. + /* Success. */
  165384. + gcmkFOOTER_NO();
  165385. + return gcvSTATUS_OK;
  165386. +
  165387. +OnError:
  165388. + /* Return the status. */
  165389. + gcmkFOOTER();
  165390. + return status;
  165391. +}
  165392. +
  165393. +/*******************************************************************************
  165394. +**
  165395. +** gckOS_WriteMemory
  165396. +**
  165397. +** Write data to a memory.
  165398. +**
  165399. +** INPUT:
  165400. +**
  165401. +** gckOS Os
  165402. +** Pointer to an gckOS object.
  165403. +**
  165404. +** gctPOINTER Address
  165405. +** Address of the memory to write to.
  165406. +**
  165407. +** gctUINT32 Data
  165408. +** Data for register.
  165409. +**
  165410. +** OUTPUT:
  165411. +**
  165412. +** Nothing.
  165413. +*/
  165414. +gceSTATUS
  165415. +gckOS_WriteMemory(
  165416. + IN gckOS Os,
  165417. + IN gctPOINTER Address,
  165418. + IN gctUINT32 Data
  165419. + )
  165420. +{
  165421. + gceSTATUS status;
  165422. + gcmkHEADER_ARG("Os=0x%X Address=0x%X Data=%u", Os, Address, Data);
  165423. +
  165424. + /* Verify the arguments. */
  165425. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  165426. +
  165427. + /* Write memory. */
  165428. + if (access_ok(VERIFY_WRITE, Address, 4))
  165429. + {
  165430. + /* User address. */
  165431. + if(put_user(Data, (gctUINT32*)Address))
  165432. + {
  165433. + gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
  165434. + }
  165435. + }
  165436. + else
  165437. + {
  165438. + /* Kernel address. */
  165439. + *(gctUINT32 *)Address = Data;
  165440. + }
  165441. +
  165442. + /* Success. */
  165443. + gcmkFOOTER_NO();
  165444. + return gcvSTATUS_OK;
  165445. +
  165446. +OnError:
  165447. + gcmkFOOTER();
  165448. + return status;
  165449. +}
  165450. +
  165451. +/*******************************************************************************
  165452. +**
  165453. +** gckOS_MapUserMemory
  165454. +**
  165455. +** Lock down a user buffer and return an DMA'able address to be used by the
  165456. +** hardware to access it.
  165457. +**
  165458. +** INPUT:
  165459. +**
  165460. +** gctPOINTER Memory
  165461. +** Pointer to memory to lock down.
  165462. +**
  165463. +** gctSIZE_T Size
  165464. +** Size in bytes of the memory to lock down.
  165465. +**
  165466. +** OUTPUT:
  165467. +**
  165468. +** gctPOINTER * Info
  165469. +** Pointer to variable receiving the information record required by
  165470. +** gckOS_UnmapUserMemory.
  165471. +**
  165472. +** gctUINT32_PTR Address
  165473. +** Pointer to a variable that will receive the address DMA'able by the
  165474. +** hardware.
  165475. +*/
  165476. +gceSTATUS
  165477. +gckOS_MapUserMemory(
  165478. + IN gckOS Os,
  165479. + IN gceCORE Core,
  165480. + IN gctPOINTER Memory,
  165481. + IN gctUINT32 Physical,
  165482. + IN gctSIZE_T Size,
  165483. + OUT gctPOINTER * Info,
  165484. + OUT gctUINT32_PTR Address
  165485. + )
  165486. +{
  165487. + gceSTATUS status;
  165488. +
  165489. + gcmkHEADER_ARG("Os=0x%x Core=%d Memory=0x%x Size=%lu", Os, Core, Memory, Size);
  165490. +
  165491. +#if gcdSECURE_USER
  165492. + gcmkONERROR(gckOS_AddMapping(Os, *Address, Memory, Size));
  165493. +
  165494. + gcmkFOOTER_NO();
  165495. + return gcvSTATUS_OK;
  165496. +
  165497. +OnError:
  165498. + gcmkFOOTER();
  165499. + return status;
  165500. +#else
  165501. +{
  165502. + gctSIZE_T pageCount, i, j;
  165503. + gctUINT32_PTR pageTable;
  165504. + gctUINT32 address = 0, physical = ~0U;
  165505. + gctUINTPTR_T start, end, memory;
  165506. + gctUINT32 offset;
  165507. + gctINT result = 0;
  165508. +
  165509. + gcsPageInfo_PTR info = gcvNULL;
  165510. + struct page **pages = gcvNULL;
  165511. +
  165512. + /* Verify the arguments. */
  165513. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165514. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL || Physical != ~0U);
  165515. + gcmkVERIFY_ARGUMENT(Size > 0);
  165516. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  165517. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  165518. +
  165519. + do
  165520. + {
  165521. + memory = (gctUINTPTR_T) Memory;
  165522. +
  165523. + /* Get the number of required pages. */
  165524. + end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  165525. + start = memory >> PAGE_SHIFT;
  165526. + pageCount = end - start;
  165527. +
  165528. + gcmkTRACE_ZONE(
  165529. + gcvLEVEL_INFO, gcvZONE_OS,
  165530. + "%s(%d): pageCount: %d.",
  165531. + __FUNCTION__, __LINE__,
  165532. + pageCount
  165533. + );
  165534. +
  165535. + /* Overflow. */
  165536. + if ((memory + Size) < memory)
  165537. + {
  165538. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  165539. + return gcvSTATUS_INVALID_ARGUMENT;
  165540. + }
  165541. +
  165542. + MEMORY_MAP_LOCK(Os);
  165543. +
  165544. + /* Allocate the Info struct. */
  165545. + info = (gcsPageInfo_PTR)kmalloc(sizeof(gcsPageInfo), GFP_KERNEL | gcdNOWARN);
  165546. +
  165547. + if (info == gcvNULL)
  165548. + {
  165549. + status = gcvSTATUS_OUT_OF_MEMORY;
  165550. + break;
  165551. + }
  165552. +
  165553. + /* Allocate the array of page addresses. */
  165554. + pages = (struct page **)kmalloc(pageCount * sizeof(struct page *), GFP_KERNEL | gcdNOWARN);
  165555. +
  165556. + if (pages == gcvNULL)
  165557. + {
  165558. + status = gcvSTATUS_OUT_OF_MEMORY;
  165559. + break;
  165560. + }
  165561. +
  165562. + if (Physical != ~0U)
  165563. + {
  165564. + for (i = 0; i < pageCount; i++)
  165565. + {
  165566. + pages[i] = pfn_to_page((Physical >> PAGE_SHIFT) + i);
  165567. + get_page(pages[i]);
  165568. + }
  165569. + }
  165570. + else
  165571. + {
  165572. + /* Get the user pages. */
  165573. + down_read(&current->mm->mmap_sem);
  165574. +
  165575. + result = get_user_pages(current,
  165576. + current->mm,
  165577. + memory & PAGE_MASK,
  165578. + pageCount,
  165579. + 1,
  165580. + 0,
  165581. + pages,
  165582. + gcvNULL
  165583. + );
  165584. +
  165585. + up_read(&current->mm->mmap_sem);
  165586. +
  165587. + if (result <=0 || result < pageCount)
  165588. + {
  165589. + struct vm_area_struct *vma;
  165590. +
  165591. + /* Release the pages if any. */
  165592. + if (result > 0)
  165593. + {
  165594. + for (i = 0; i < result; i++)
  165595. + {
  165596. + if (pages[i] == gcvNULL)
  165597. + {
  165598. + break;
  165599. + }
  165600. +
  165601. + page_cache_release(pages[i]);
  165602. + pages[i] = gcvNULL;
  165603. + }
  165604. +
  165605. + result = 0;
  165606. + }
  165607. +
  165608. + vma = find_vma(current->mm, memory);
  165609. +
  165610. + if (vma && (vma->vm_flags & VM_PFNMAP))
  165611. + {
  165612. + pte_t * pte;
  165613. + spinlock_t * ptl;
  165614. + gctUINTPTR_T logical = memory;
  165615. +
  165616. + for (i = 0; i < pageCount; i++)
  165617. + {
  165618. + pgd_t * pgd = pgd_offset(current->mm, logical);
  165619. + pud_t * pud = pud_offset(pgd, logical);
  165620. +
  165621. + if (pud)
  165622. + {
  165623. + pmd_t * pmd = pmd_offset(pud, logical);
  165624. + pte = pte_offset_map_lock(current->mm, pmd, logical, &ptl);
  165625. + if (!pte)
  165626. + {
  165627. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  165628. + }
  165629. + }
  165630. + else
  165631. + {
  165632. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  165633. + }
  165634. +
  165635. + pages[i] = pte_page(*pte);
  165636. + pte_unmap_unlock(pte, ptl);
  165637. +
  165638. + /* Advance to next. */
  165639. + logical += PAGE_SIZE;
  165640. + }
  165641. + }
  165642. + else
  165643. + {
  165644. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  165645. + }
  165646. +
  165647. + /* Check if this memory is contiguous for old mmu. */
  165648. + if (Os->device->kernels[Core]->hardware->mmuVersion == 0)
  165649. + {
  165650. + for (i = 1; i < pageCount; i++)
  165651. + {
  165652. + if (pages[i] != nth_page(pages[0], i))
  165653. + {
  165654. + /* Non-contiguous. */
  165655. + break;
  165656. + }
  165657. + }
  165658. +
  165659. + if (i == pageCount)
  165660. + {
  165661. + /* Contiguous memory. */
  165662. + physical = page_to_phys(pages[0]) | (memory & ~PAGE_MASK);
  165663. +
  165664. + if (!((physical - Os->device->baseAddress) & 0x80000000))
  165665. + {
  165666. + kfree(pages);
  165667. + pages = gcvNULL;
  165668. +
  165669. + info->pages = gcvNULL;
  165670. + info->pageTable = gcvNULL;
  165671. +
  165672. + MEMORY_MAP_UNLOCK(Os);
  165673. +
  165674. + *Address = physical - Os->device->baseAddress;
  165675. + *Info = info;
  165676. +
  165677. + gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x",
  165678. + *Info, *Address);
  165679. +
  165680. + return gcvSTATUS_OK;
  165681. + }
  165682. + }
  165683. + }
  165684. +
  165685. + /* Reference pages. */
  165686. + for (i = 0; i < pageCount; i++)
  165687. + {
  165688. + get_page(pages[i]);
  165689. + }
  165690. + }
  165691. + }
  165692. +
  165693. + for (i = 0; i < pageCount; i++)
  165694. + {
  165695. +#ifdef CONFIG_ARM
  165696. + gctUINT32 data;
  165697. + get_user(data, (gctUINT32*)((memory & PAGE_MASK) + i * PAGE_SIZE));
  165698. +#endif
  165699. +
  165700. + /* Flush(clean) the data cache. */
  165701. + gcmkONERROR(gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
  165702. + (gctPOINTER)(gctUINTPTR_T)page_to_phys(pages[i]),
  165703. + (gctPOINTER)(memory & PAGE_MASK) + i*PAGE_SIZE,
  165704. + PAGE_SIZE));
  165705. + }
  165706. +
  165707. +#if gcdENABLE_VG
  165708. + if (Core == gcvCORE_VG)
  165709. + {
  165710. + /* Allocate pages inside the page table. */
  165711. + gcmkERR_BREAK(gckVGMMU_AllocatePages(Os->device->kernels[Core]->vg->mmu,
  165712. + pageCount * (PAGE_SIZE/4096),
  165713. + (gctPOINTER *) &pageTable,
  165714. + &address));
  165715. + }
  165716. + else
  165717. +#endif
  165718. + {
  165719. + /* Allocate pages inside the page table. */
  165720. + gcmkERR_BREAK(gckMMU_AllocatePages(Os->device->kernels[Core]->mmu,
  165721. + pageCount * (PAGE_SIZE/4096),
  165722. + (gctPOINTER *) &pageTable,
  165723. + &address));
  165724. + }
  165725. +
  165726. + /* Fill the page table. */
  165727. + for (i = 0; i < pageCount; i++)
  165728. + {
  165729. + gctUINT32 phys;
  165730. + gctUINT32_PTR tab = pageTable + i * (PAGE_SIZE/4096);
  165731. +
  165732. + phys = page_to_phys(pages[i]);
  165733. +
  165734. +#if gcdENABLE_VG
  165735. + if (Core == gcvCORE_VG)
  165736. + {
  165737. + /* Get the physical address from page struct. */
  165738. + gcmkONERROR(
  165739. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  165740. + phys,
  165741. + tab));
  165742. + }
  165743. + else
  165744. +#endif
  165745. + {
  165746. + /* Get the physical address from page struct. */
  165747. + gcmkONERROR(
  165748. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  165749. + phys,
  165750. + tab));
  165751. + }
  165752. +
  165753. + for (j = 1; j < (PAGE_SIZE/4096); j++)
  165754. + {
  165755. + pageTable[i * (PAGE_SIZE/4096) + j] = pageTable[i * (PAGE_SIZE/4096)] + 4096 * j;
  165756. + }
  165757. +
  165758. + gcmkTRACE_ZONE(
  165759. + gcvLEVEL_INFO, gcvZONE_OS,
  165760. + "%s(%d): pageTable[%d]: 0x%X 0x%X.",
  165761. + __FUNCTION__, __LINE__,
  165762. + i, phys, pageTable[i]);
  165763. + }
  165764. +
  165765. +#if gcdENABLE_VG
  165766. + if (Core == gcvCORE_VG)
  165767. + {
  165768. + gcmkONERROR(gckVGMMU_Flush(Os->device->kernels[Core]->vg->mmu));
  165769. + }
  165770. + else
  165771. +#endif
  165772. + {
  165773. + gcmkONERROR(gckMMU_Flush(Os->device->kernels[Core]->mmu));
  165774. + }
  165775. +
  165776. + /* Save pointer to page table. */
  165777. + info->pageTable = pageTable;
  165778. + info->pages = pages;
  165779. +
  165780. + *Info = (gctPOINTER) info;
  165781. +
  165782. + gcmkTRACE_ZONE(
  165783. + gcvLEVEL_INFO, gcvZONE_OS,
  165784. + "%s(%d): info->pages: 0x%X, info->pageTable: 0x%X, info: 0x%X.",
  165785. + __FUNCTION__, __LINE__,
  165786. + info->pages,
  165787. + info->pageTable,
  165788. + info
  165789. + );
  165790. +
  165791. + offset = (Physical != ~0U)
  165792. + ? (Physical & ~PAGE_MASK)
  165793. + : (memory & ~PAGE_MASK);
  165794. +
  165795. + /* Return address. */
  165796. + *Address = address + offset;
  165797. +
  165798. + gcmkTRACE_ZONE(
  165799. + gcvLEVEL_INFO, gcvZONE_OS,
  165800. + "%s(%d): Address: 0x%X.",
  165801. + __FUNCTION__, __LINE__,
  165802. + *Address
  165803. + );
  165804. +
  165805. + /* Success. */
  165806. + status = gcvSTATUS_OK;
  165807. + }
  165808. + while (gcvFALSE);
  165809. +
  165810. +OnError:
  165811. +
  165812. + if (gcmIS_ERROR(status))
  165813. + {
  165814. + gcmkTRACE(
  165815. + gcvLEVEL_ERROR,
  165816. + "%s(%d): error occured: %d.",
  165817. + __FUNCTION__, __LINE__,
  165818. + status
  165819. + );
  165820. +
  165821. + /* Release page array. */
  165822. + if (result > 0 && pages != gcvNULL)
  165823. + {
  165824. + gcmkTRACE(
  165825. + gcvLEVEL_ERROR,
  165826. + "%s(%d): error: page table is freed.",
  165827. + __FUNCTION__, __LINE__
  165828. + );
  165829. +
  165830. + for (i = 0; i < result; i++)
  165831. + {
  165832. + if (pages[i] == gcvNULL)
  165833. + {
  165834. + break;
  165835. + }
  165836. + page_cache_release(pages[i]);
  165837. + }
  165838. + }
  165839. +
  165840. + if (info!= gcvNULL && pages != gcvNULL)
  165841. + {
  165842. + gcmkTRACE(
  165843. + gcvLEVEL_ERROR,
  165844. + "%s(%d): error: pages is freed.",
  165845. + __FUNCTION__, __LINE__
  165846. + );
  165847. +
  165848. + /* Free the page table. */
  165849. + kfree(pages);
  165850. + info->pages = gcvNULL;
  165851. + }
  165852. +
  165853. + /* Release page info struct. */
  165854. + if (info != gcvNULL)
  165855. + {
  165856. + gcmkTRACE(
  165857. + gcvLEVEL_ERROR,
  165858. + "%s(%d): error: info is freed.",
  165859. + __FUNCTION__, __LINE__
  165860. + );
  165861. +
  165862. + /* Free the page info struct. */
  165863. + kfree(info);
  165864. + *Info = gcvNULL;
  165865. + }
  165866. + }
  165867. +
  165868. + MEMORY_MAP_UNLOCK(Os);
  165869. +
  165870. + /* Return the status. */
  165871. + if (gcmIS_SUCCESS(status))
  165872. + {
  165873. + gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x", *Info, *Address);
  165874. + }
  165875. + else
  165876. + {
  165877. + gcmkFOOTER();
  165878. + }
  165879. +
  165880. + return status;
  165881. +}
  165882. +#endif
  165883. +}
  165884. +
  165885. +/*******************************************************************************
  165886. +**
  165887. +** gckOS_UnmapUserMemory
  165888. +**
  165889. +** Unlock a user buffer and that was previously locked down by
  165890. +** gckOS_MapUserMemory.
  165891. +**
  165892. +** INPUT:
  165893. +**
  165894. +** gctPOINTER Memory
  165895. +** Pointer to memory to unlock.
  165896. +**
  165897. +** gctSIZE_T Size
  165898. +** Size in bytes of the memory to unlock.
  165899. +**
  165900. +** gctPOINTER Info
  165901. +** Information record returned by gckOS_MapUserMemory.
  165902. +**
  165903. +** gctUINT32_PTR Address
  165904. +** The address returned by gckOS_MapUserMemory.
  165905. +**
  165906. +** OUTPUT:
  165907. +**
  165908. +** Nothing.
  165909. +*/
  165910. +gceSTATUS
  165911. +gckOS_UnmapUserMemory(
  165912. + IN gckOS Os,
  165913. + IN gceCORE Core,
  165914. + IN gctPOINTER Memory,
  165915. + IN gctSIZE_T Size,
  165916. + IN gctPOINTER Info,
  165917. + IN gctUINT32 Address
  165918. + )
  165919. +{
  165920. + gceSTATUS status;
  165921. +
  165922. + gcmkHEADER_ARG("Os=0x%X Core=%d Memory=0x%X Size=%lu Info=0x%X Address0x%08x",
  165923. + Os, Core, Memory, Size, Info, Address);
  165924. +
  165925. +#if gcdSECURE_USER
  165926. + gcmkONERROR(gckOS_RemoveMapping(Os, Memory, Size));
  165927. +
  165928. + gcmkFOOTER_NO();
  165929. + return gcvSTATUS_OK;
  165930. +
  165931. +OnError:
  165932. + gcmkFOOTER();
  165933. + return status;
  165934. +#else
  165935. +{
  165936. + gctUINTPTR_T memory, start, end;
  165937. + gcsPageInfo_PTR info;
  165938. + gctSIZE_T pageCount, i;
  165939. + struct page **pages;
  165940. +
  165941. + /* Verify the arguments. */
  165942. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165943. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  165944. + gcmkVERIFY_ARGUMENT(Size > 0);
  165945. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  165946. +
  165947. + do
  165948. + {
  165949. + info = (gcsPageInfo_PTR) Info;
  165950. +
  165951. + pages = info->pages;
  165952. +
  165953. + gcmkTRACE_ZONE(
  165954. + gcvLEVEL_INFO, gcvZONE_OS,
  165955. + "%s(%d): info=0x%X, pages=0x%X.",
  165956. + __FUNCTION__, __LINE__,
  165957. + info, pages
  165958. + );
  165959. +
  165960. + /* Invalid page array. */
  165961. + if (pages == gcvNULL && info->pageTable == gcvNULL)
  165962. + {
  165963. + kfree(info);
  165964. +
  165965. + gcmkFOOTER_NO();
  165966. + return gcvSTATUS_OK;
  165967. + }
  165968. +
  165969. + memory = (gctUINTPTR_T)Memory;
  165970. + end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  165971. + start = memory >> PAGE_SHIFT;
  165972. + pageCount = end - start;
  165973. +
  165974. + /* Overflow. */
  165975. + if ((memory + Size) < memory)
  165976. + {
  165977. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  165978. + return gcvSTATUS_INVALID_ARGUMENT;
  165979. + }
  165980. +
  165981. + gcmkTRACE_ZONE(
  165982. + gcvLEVEL_INFO, gcvZONE_OS,
  165983. + "%s(%d): memory: 0x%X, pageCount: %d, pageTable: 0x%X.",
  165984. + __FUNCTION__, __LINE__,
  165985. + memory, pageCount, info->pageTable
  165986. + );
  165987. +
  165988. + MEMORY_MAP_LOCK(Os);
  165989. +
  165990. + gcmkASSERT(info->pageTable != gcvNULL);
  165991. +
  165992. +#if gcdENABLE_VG
  165993. + if (Core == gcvCORE_VG)
  165994. + {
  165995. + /* Free the pages from the MMU. */
  165996. + gcmkERR_BREAK(gckVGMMU_FreePages(Os->device->kernels[Core]->vg->mmu,
  165997. + info->pageTable,
  165998. + pageCount * (PAGE_SIZE/4096)
  165999. + ));
  166000. + }
  166001. + else
  166002. +#endif
  166003. + {
  166004. + /* Free the pages from the MMU. */
  166005. + gcmkERR_BREAK(gckMMU_FreePages(Os->device->kernels[Core]->mmu,
  166006. + info->pageTable,
  166007. + pageCount * (PAGE_SIZE/4096)
  166008. + ));
  166009. + }
  166010. +
  166011. + /* Release the page cache. */
  166012. + if (pages)
  166013. + {
  166014. + for (i = 0; i < pageCount; i++)
  166015. + {
  166016. + gcmkTRACE_ZONE(
  166017. + gcvLEVEL_INFO, gcvZONE_OS,
  166018. + "%s(%d): pages[%d]: 0x%X.",
  166019. + __FUNCTION__, __LINE__,
  166020. + i, pages[i]
  166021. + );
  166022. +
  166023. + if (!PageReserved(pages[i]))
  166024. + {
  166025. + SetPageDirty(pages[i]);
  166026. + }
  166027. +
  166028. + page_cache_release(pages[i]);
  166029. + }
  166030. + }
  166031. +
  166032. + /* Success. */
  166033. + status = gcvSTATUS_OK;
  166034. + }
  166035. + while (gcvFALSE);
  166036. +
  166037. + if (info != gcvNULL)
  166038. + {
  166039. + /* Free the page array. */
  166040. + if (info->pages != gcvNULL)
  166041. + {
  166042. + kfree(info->pages);
  166043. + }
  166044. +
  166045. + kfree(info);
  166046. + }
  166047. +
  166048. + MEMORY_MAP_UNLOCK(Os);
  166049. +
  166050. + /* Return the status. */
  166051. + gcmkFOOTER();
  166052. + return status;
  166053. +}
  166054. +#endif
  166055. +}
  166056. +
  166057. +/*******************************************************************************
  166058. +**
  166059. +** gckOS_GetBaseAddress
  166060. +**
  166061. +** Get the base address for the physical memory.
  166062. +**
  166063. +** INPUT:
  166064. +**
  166065. +** gckOS Os
  166066. +** Pointer to the gckOS object.
  166067. +**
  166068. +** OUTPUT:
  166069. +**
  166070. +** gctUINT32_PTR BaseAddress
  166071. +** Pointer to a variable that will receive the base address.
  166072. +*/
  166073. +gceSTATUS
  166074. +gckOS_GetBaseAddress(
  166075. + IN gckOS Os,
  166076. + OUT gctUINT32_PTR BaseAddress
  166077. + )
  166078. +{
  166079. + gcmkHEADER_ARG("Os=0x%X", Os);
  166080. +
  166081. + /* Verify the arguments. */
  166082. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166083. + gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL);
  166084. +
  166085. + /* Return base address. */
  166086. + *BaseAddress = Os->device->baseAddress;
  166087. +
  166088. + /* Success. */
  166089. + gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
  166090. + return gcvSTATUS_OK;
  166091. +}
  166092. +
  166093. +gceSTATUS
  166094. +gckOS_SuspendInterrupt(
  166095. + IN gckOS Os
  166096. + )
  166097. +{
  166098. + return gckOS_SuspendInterruptEx(Os, gcvCORE_MAJOR);
  166099. +}
  166100. +
  166101. +gceSTATUS
  166102. +gckOS_SuspendInterruptEx(
  166103. + IN gckOS Os,
  166104. + IN gceCORE Core
  166105. + )
  166106. +{
  166107. + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
  166108. +
  166109. + /* Verify the arguments. */
  166110. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166111. +
  166112. + disable_irq(Os->device->irqLines[Core]);
  166113. +
  166114. + gcmkFOOTER_NO();
  166115. + return gcvSTATUS_OK;
  166116. +}
  166117. +
  166118. +gceSTATUS
  166119. +gckOS_ResumeInterrupt(
  166120. + IN gckOS Os
  166121. + )
  166122. +{
  166123. + return gckOS_ResumeInterruptEx(Os, gcvCORE_MAJOR);
  166124. +}
  166125. +
  166126. +gceSTATUS
  166127. +gckOS_ResumeInterruptEx(
  166128. + IN gckOS Os,
  166129. + IN gceCORE Core
  166130. + )
  166131. +{
  166132. + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
  166133. +
  166134. + /* Verify the arguments. */
  166135. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166136. +
  166137. + enable_irq(Os->device->irqLines[Core]);
  166138. +
  166139. + gcmkFOOTER_NO();
  166140. + return gcvSTATUS_OK;
  166141. +}
  166142. +
  166143. +gceSTATUS
  166144. +gckOS_MemCopy(
  166145. + IN gctPOINTER Destination,
  166146. + IN gctCONST_POINTER Source,
  166147. + IN gctSIZE_T Bytes
  166148. + )
  166149. +{
  166150. + gcmkHEADER_ARG("Destination=0x%X Source=0x%X Bytes=%lu",
  166151. + Destination, Source, Bytes);
  166152. +
  166153. + gcmkVERIFY_ARGUMENT(Destination != gcvNULL);
  166154. + gcmkVERIFY_ARGUMENT(Source != gcvNULL);
  166155. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166156. +
  166157. + memcpy(Destination, Source, Bytes);
  166158. +
  166159. + gcmkFOOTER_NO();
  166160. + return gcvSTATUS_OK;
  166161. +}
  166162. +
  166163. +gceSTATUS
  166164. +gckOS_ZeroMemory(
  166165. + IN gctPOINTER Memory,
  166166. + IN gctSIZE_T Bytes
  166167. + )
  166168. +{
  166169. + gcmkHEADER_ARG("Memory=0x%X Bytes=%lu", Memory, Bytes);
  166170. +
  166171. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  166172. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166173. +
  166174. + memset(Memory, 0, Bytes);
  166175. +
  166176. + gcmkFOOTER_NO();
  166177. + return gcvSTATUS_OK;
  166178. +}
  166179. +
  166180. +/*******************************************************************************
  166181. +********************************* Cache Control ********************************
  166182. +*******************************************************************************/
  166183. +
  166184. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED && defined(CONFIG_OUTER_CACHE)
  166185. +static inline gceSTATUS
  166186. +outer_func(
  166187. + gceCACHEOPERATION Type,
  166188. + unsigned long Start,
  166189. + unsigned long End
  166190. + )
  166191. +{
  166192. + switch (Type)
  166193. + {
  166194. + case gcvCACHE_CLEAN:
  166195. + outer_clean_range(Start, End);
  166196. + break;
  166197. + case gcvCACHE_INVALIDATE:
  166198. + outer_inv_range(Start, End);
  166199. + break;
  166200. + case gcvCACHE_FLUSH:
  166201. + outer_flush_range(Start, End);
  166202. + break;
  166203. + default:
  166204. + return gcvSTATUS_INVALID_ARGUMENT;
  166205. + break;
  166206. + }
  166207. + return gcvSTATUS_OK;
  166208. +}
  166209. +
  166210. +#if gcdENABLE_OUTER_CACHE_PATCH
  166211. +/*******************************************************************************
  166212. +** _HandleOuterCache
  166213. +**
  166214. +** Handle the outer cache for the specified addresses.
  166215. +**
  166216. +** ARGUMENTS:
  166217. +**
  166218. +** gckOS Os
  166219. +** Pointer to gckOS object.
  166220. +**
  166221. +** gctUINT32 ProcessID
  166222. +** Process ID Logical belongs.
  166223. +**
  166224. +** gctPHYS_ADDR Handle
  166225. +** Physical address handle. If gcvNULL it is video memory.
  166226. +**
  166227. +** gctPOINTER Physical
  166228. +** Physical address to flush.
  166229. +**
  166230. +** gctPOINTER Logical
  166231. +** Logical address to flush.
  166232. +**
  166233. +** gctSIZE_T Bytes
  166234. +** Size of the address range in bytes to flush.
  166235. +**
  166236. +** gceOUTERCACHE_OPERATION Type
  166237. +** Operation need to be execute.
  166238. +*/
  166239. +static gceSTATUS
  166240. +_HandleOuterCache(
  166241. + IN gckOS Os,
  166242. + IN gctUINT32 ProcessID,
  166243. + IN gctPHYS_ADDR Handle,
  166244. + IN gctPOINTER Physical,
  166245. + IN gctPOINTER Logical,
  166246. + IN gctSIZE_T Bytes,
  166247. + IN gceCACHEOPERATION Type
  166248. + )
  166249. +{
  166250. + gceSTATUS status;
  166251. + gctUINT32 i, pageNum;
  166252. + unsigned long paddr;
  166253. + gctPOINTER vaddr;
  166254. +
  166255. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  166256. + Os, ProcessID, Handle, Logical, Bytes);
  166257. +
  166258. + if (Physical != gcvNULL)
  166259. + {
  166260. + /* Non paged memory or gcvPOOL_USER surface */
  166261. + paddr = (unsigned long) Physical;
  166262. + gcmkONERROR(outer_func(Type, paddr, paddr + Bytes));
  166263. + }
  166264. + else if ((Handle == gcvNULL)
  166265. + || (Handle != gcvNULL && ((PLINUX_MDL)Handle)->contiguous)
  166266. + )
  166267. + {
  166268. + /* Video Memory or contiguous virtual memory */
  166269. + gcmkONERROR(gckOS_GetPhysicalAddress(Os, Logical, (gctUINT32*)&paddr));
  166270. + gcmkONERROR(outer_func(Type, paddr, paddr + Bytes));
  166271. + }
  166272. + else
  166273. + {
  166274. + /* Non contiguous virtual memory */
  166275. + vaddr = (gctPOINTER)gcmALIGN_BASE((gctUINTPTR_T)Logical, PAGE_SIZE);
  166276. + pageNum = GetPageCount(Bytes, 0);
  166277. +
  166278. + for (i = 0; i < pageNum; i += 1)
  166279. + {
  166280. + gcmkONERROR(_ConvertLogical2Physical(
  166281. + Os,
  166282. + vaddr + PAGE_SIZE * i,
  166283. + ProcessID,
  166284. + (PLINUX_MDL)Handle,
  166285. + (gctUINT32*)&paddr
  166286. + ));
  166287. +
  166288. + gcmkONERROR(outer_func(Type, paddr, paddr + PAGE_SIZE));
  166289. + }
  166290. + }
  166291. +
  166292. + mb();
  166293. +
  166294. + /* Success. */
  166295. + gcmkFOOTER_NO();
  166296. + return gcvSTATUS_OK;
  166297. +
  166298. +OnError:
  166299. + /* Return the status. */
  166300. + gcmkFOOTER();
  166301. + return status;
  166302. +}
  166303. +#endif
  166304. +#endif
  166305. +
  166306. +/*******************************************************************************
  166307. +** gckOS_CacheClean
  166308. +**
  166309. +** Clean the cache for the specified addresses. The GPU is going to need the
  166310. +** data. If the system is allocating memory as non-cachable, this function can
  166311. +** be ignored.
  166312. +**
  166313. +** ARGUMENTS:
  166314. +**
  166315. +** gckOS Os
  166316. +** Pointer to gckOS object.
  166317. +**
  166318. +** gctUINT32 ProcessID
  166319. +** Process ID Logical belongs.
  166320. +**
  166321. +** gctPHYS_ADDR Handle
  166322. +** Physical address handle. If gcvNULL it is video memory.
  166323. +**
  166324. +** gctPOINTER Physical
  166325. +** Physical address to flush.
  166326. +**
  166327. +** gctPOINTER Logical
  166328. +** Logical address to flush.
  166329. +**
  166330. +** gctSIZE_T Bytes
  166331. +** Size of the address range in bytes to flush.
  166332. +*/
  166333. +gceSTATUS
  166334. +gckOS_CacheClean(
  166335. + IN gckOS Os,
  166336. + IN gctUINT32 ProcessID,
  166337. + IN gctPHYS_ADDR Handle,
  166338. + IN gctPOINTER Physical,
  166339. + IN gctPOINTER Logical,
  166340. + IN gctSIZE_T Bytes
  166341. + )
  166342. +{
  166343. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  166344. + Os, ProcessID, Handle, Logical, Bytes);
  166345. +
  166346. + /* Verify the arguments. */
  166347. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166348. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  166349. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166350. +
  166351. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
  166352. +#ifdef CONFIG_ARM
  166353. +
  166354. + /* Inner cache. */
  166355. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
  166356. + dmac_map_area(Logical, Bytes, DMA_TO_DEVICE);
  166357. +# else
  166358. + dmac_clean_range(Logical, Logical + Bytes);
  166359. +# endif
  166360. +
  166361. +#if defined(CONFIG_OUTER_CACHE)
  166362. + /* Outer cache. */
  166363. +#if gcdENABLE_OUTER_CACHE_PATCH
  166364. + _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_CLEAN);
  166365. +#else
  166366. + outer_clean_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
  166367. +#endif
  166368. +#endif
  166369. +
  166370. +#elif defined(CONFIG_MIPS)
  166371. +
  166372. + dma_cache_wback((unsigned long) Logical, Bytes);
  166373. +
  166374. +#elif defined(CONFIG_PPC)
  166375. +
  166376. + /* TODO */
  166377. +
  166378. +#else
  166379. + dma_sync_single_for_device(
  166380. + gcvNULL,
  166381. + (dma_addr_t)Physical,
  166382. + Bytes,
  166383. + DMA_TO_DEVICE);
  166384. +#endif
  166385. +#endif
  166386. +
  166387. + /* Success. */
  166388. + gcmkFOOTER_NO();
  166389. + return gcvSTATUS_OK;
  166390. +}
  166391. +
  166392. +/*******************************************************************************
  166393. +** gckOS_CacheInvalidate
  166394. +**
  166395. +** Invalidate the cache for the specified addresses. The GPU is going to need
  166396. +** data. If the system is allocating memory as non-cachable, this function can
  166397. +** be ignored.
  166398. +**
  166399. +** ARGUMENTS:
  166400. +**
  166401. +** gckOS Os
  166402. +** Pointer to gckOS object.
  166403. +**
  166404. +** gctUINT32 ProcessID
  166405. +** Process ID Logical belongs.
  166406. +**
  166407. +** gctPHYS_ADDR Handle
  166408. +** Physical address handle. If gcvNULL it is video memory.
  166409. +**
  166410. +** gctPOINTER Logical
  166411. +** Logical address to flush.
  166412. +**
  166413. +** gctSIZE_T Bytes
  166414. +** Size of the address range in bytes to flush.
  166415. +*/
  166416. +gceSTATUS
  166417. +gckOS_CacheInvalidate(
  166418. + IN gckOS Os,
  166419. + IN gctUINT32 ProcessID,
  166420. + IN gctPHYS_ADDR Handle,
  166421. + IN gctPOINTER Physical,
  166422. + IN gctPOINTER Logical,
  166423. + IN gctSIZE_T Bytes
  166424. + )
  166425. +{
  166426. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  166427. + Os, ProcessID, Handle, Logical, Bytes);
  166428. +
  166429. + /* Verify the arguments. */
  166430. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166431. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  166432. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166433. +
  166434. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
  166435. +#ifdef CONFIG_ARM
  166436. +
  166437. + /* Inner cache. */
  166438. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
  166439. + dmac_map_area(Logical, Bytes, DMA_FROM_DEVICE);
  166440. +# else
  166441. + dmac_inv_range(Logical, Logical + Bytes);
  166442. +# endif
  166443. +
  166444. +#if defined(CONFIG_OUTER_CACHE)
  166445. + /* Outer cache. */
  166446. +#if gcdENABLE_OUTER_CACHE_PATCH
  166447. + _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_INVALIDATE);
  166448. +#else
  166449. + outer_inv_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
  166450. +#endif
  166451. +#endif
  166452. +
  166453. +#elif defined(CONFIG_MIPS)
  166454. + dma_cache_inv((unsigned long) Logical, Bytes);
  166455. +#elif defined(CONFIG_PPC)
  166456. + /* TODO */
  166457. +#else
  166458. + dma_sync_single_for_device(
  166459. + gcvNULL,
  166460. + (dma_addr_t)Physical,
  166461. + Bytes,
  166462. + DMA_FROM_DEVICE);
  166463. +#endif
  166464. +#endif
  166465. +
  166466. + /* Success. */
  166467. + gcmkFOOTER_NO();
  166468. + return gcvSTATUS_OK;
  166469. +}
  166470. +
  166471. +/*******************************************************************************
  166472. +** gckOS_CacheFlush
  166473. +**
  166474. +** Clean the cache for the specified addresses and invalidate the lines as
  166475. +** well. The GPU is going to need and modify the data. If the system is
  166476. +** allocating memory as non-cachable, this function can be ignored.
  166477. +**
  166478. +** ARGUMENTS:
  166479. +**
  166480. +** gckOS Os
  166481. +** Pointer to gckOS object.
  166482. +**
  166483. +** gctUINT32 ProcessID
  166484. +** Process ID Logical belongs.
  166485. +**
  166486. +** gctPHYS_ADDR Handle
  166487. +** Physical address handle. If gcvNULL it is video memory.
  166488. +**
  166489. +** gctPOINTER Logical
  166490. +** Logical address to flush.
  166491. +**
  166492. +** gctSIZE_T Bytes
  166493. +** Size of the address range in bytes to flush.
  166494. +*/
  166495. +gceSTATUS
  166496. +gckOS_CacheFlush(
  166497. + IN gckOS Os,
  166498. + IN gctUINT32 ProcessID,
  166499. + IN gctPHYS_ADDR Handle,
  166500. + IN gctPOINTER Physical,
  166501. + IN gctPOINTER Logical,
  166502. + IN gctSIZE_T Bytes
  166503. + )
  166504. +{
  166505. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  166506. + Os, ProcessID, Handle, Logical, Bytes);
  166507. +
  166508. + /* Verify the arguments. */
  166509. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166510. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  166511. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166512. +
  166513. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
  166514. +#ifdef CONFIG_ARM
  166515. + /* Inner cache. */
  166516. + dmac_flush_range(Logical, Logical + Bytes);
  166517. +
  166518. +#if defined(CONFIG_OUTER_CACHE)
  166519. + /* Outer cache. */
  166520. +#if gcdENABLE_OUTER_CACHE_PATCH
  166521. + _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_FLUSH);
  166522. +#else
  166523. + outer_flush_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
  166524. +#endif
  166525. +#endif
  166526. +
  166527. +#elif defined(CONFIG_MIPS)
  166528. + dma_cache_wback_inv((unsigned long) Logical, Bytes);
  166529. +#elif defined(CONFIG_PPC)
  166530. + /* TODO */
  166531. +#else
  166532. + dma_sync_single_for_device(
  166533. + gcvNULL,
  166534. + (dma_addr_t)Physical,
  166535. + Bytes,
  166536. + DMA_BIDIRECTIONAL);
  166537. +#endif
  166538. +#endif
  166539. +
  166540. + /* Success. */
  166541. + gcmkFOOTER_NO();
  166542. + return gcvSTATUS_OK;
  166543. +}
  166544. +
  166545. +/*******************************************************************************
  166546. +********************************* Broadcasting *********************************
  166547. +*******************************************************************************/
  166548. +
  166549. +/*******************************************************************************
  166550. +**
  166551. +** gckOS_Broadcast
  166552. +**
  166553. +** System hook for broadcast events from the kernel driver.
  166554. +**
  166555. +** INPUT:
  166556. +**
  166557. +** gckOS Os
  166558. +** Pointer to the gckOS object.
  166559. +**
  166560. +** gckHARDWARE Hardware
  166561. +** Pointer to the gckHARDWARE object.
  166562. +**
  166563. +** gceBROADCAST Reason
  166564. +** Reason for the broadcast. Can be one of the following values:
  166565. +**
  166566. +** gcvBROADCAST_GPU_IDLE
  166567. +** Broadcasted when the kernel driver thinks the GPU might be
  166568. +** idle. This can be used to handle power management.
  166569. +**
  166570. +** gcvBROADCAST_GPU_COMMIT
  166571. +** Broadcasted when any client process commits a command
  166572. +** buffer. This can be used to handle power management.
  166573. +**
  166574. +** gcvBROADCAST_GPU_STUCK
  166575. +** Broadcasted when the kernel driver hits the timeout waiting
  166576. +** for the GPU.
  166577. +**
  166578. +** gcvBROADCAST_FIRST_PROCESS
  166579. +** First process is trying to connect to the kernel.
  166580. +**
  166581. +** gcvBROADCAST_LAST_PROCESS
  166582. +** Last process has detached from the kernel.
  166583. +**
  166584. +** OUTPUT:
  166585. +**
  166586. +** Nothing.
  166587. +*/
  166588. +gceSTATUS
  166589. +gckOS_Broadcast(
  166590. + IN gckOS Os,
  166591. + IN gckHARDWARE Hardware,
  166592. + IN gceBROADCAST Reason
  166593. + )
  166594. +{
  166595. + gceSTATUS status;
  166596. +
  166597. + gcmkHEADER_ARG("Os=0x%X Hardware=0x%X Reason=%d", Os, Hardware, Reason);
  166598. +
  166599. + /* Verify the arguments. */
  166600. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166601. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  166602. +
  166603. + switch (Reason)
  166604. + {
  166605. + case gcvBROADCAST_FIRST_PROCESS:
  166606. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "First process has attached");
  166607. + break;
  166608. +
  166609. + case gcvBROADCAST_LAST_PROCESS:
  166610. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "Last process has detached");
  166611. +
  166612. + /* Put GPU OFF. */
  166613. + gcmkONERROR(
  166614. + gckHARDWARE_SetPowerManagementState(Hardware,
  166615. + gcvPOWER_OFF_BROADCAST));
  166616. + break;
  166617. +
  166618. + case gcvBROADCAST_GPU_IDLE:
  166619. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "GPU idle.");
  166620. +
  166621. + /* Put GPU IDLE. */
  166622. + gcmkONERROR(
  166623. + gckHARDWARE_SetPowerManagementState(Hardware,
  166624. +#if gcdPOWER_SUSNPEND_WHEN_IDLE
  166625. + gcvPOWER_SUSPEND_BROADCAST));
  166626. +#else
  166627. + gcvPOWER_IDLE_BROADCAST));
  166628. +#endif
  166629. +
  166630. + /* Add idle process DB. */
  166631. + gcmkONERROR(gckKERNEL_AddProcessDB(Hardware->kernel,
  166632. + 1,
  166633. + gcvDB_IDLE,
  166634. + gcvNULL, gcvNULL, 0));
  166635. + break;
  166636. +
  166637. + case gcvBROADCAST_GPU_COMMIT:
  166638. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "COMMIT has arrived.");
  166639. +
  166640. + /* Add busy process DB. */
  166641. + gcmkONERROR(gckKERNEL_AddProcessDB(Hardware->kernel,
  166642. + 0,
  166643. + gcvDB_IDLE,
  166644. + gcvNULL, gcvNULL, 0));
  166645. +
  166646. + /* Put GPU ON. */
  166647. + gcmkONERROR(
  166648. + gckHARDWARE_SetPowerManagementState(Hardware, gcvPOWER_ON_AUTO));
  166649. + break;
  166650. +
  166651. + case gcvBROADCAST_GPU_STUCK:
  166652. + gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_GPU_STUCK\n");
  166653. +#if !gcdENABLE_RECOVERY
  166654. + gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware));
  166655. +#endif
  166656. + gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
  166657. + break;
  166658. +
  166659. + case gcvBROADCAST_AXI_BUS_ERROR:
  166660. + gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_AXI_BUS_ERROR\n");
  166661. + gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware));
  166662. + gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
  166663. + break;
  166664. + }
  166665. +
  166666. + /* Success. */
  166667. + gcmkFOOTER_NO();
  166668. + return gcvSTATUS_OK;
  166669. +
  166670. +OnError:
  166671. + /* Return the status. */
  166672. + gcmkFOOTER();
  166673. + return status;
  166674. +}
  166675. +
  166676. +/*******************************************************************************
  166677. +**
  166678. +** gckOS_BroadcastHurry
  166679. +**
  166680. +** The GPU is running too slow.
  166681. +**
  166682. +** INPUT:
  166683. +**
  166684. +** gckOS Os
  166685. +** Pointer to the gckOS object.
  166686. +**
  166687. +** gckHARDWARE Hardware
  166688. +** Pointer to the gckHARDWARE object.
  166689. +**
  166690. +** gctUINT Urgency
  166691. +** The higher the number, the higher the urgency to speed up the GPU.
  166692. +** The maximum value is defined by the gcdDYNAMIC_EVENT_THRESHOLD.
  166693. +**
  166694. +** OUTPUT:
  166695. +**
  166696. +** Nothing.
  166697. +*/
  166698. +gceSTATUS
  166699. +gckOS_BroadcastHurry(
  166700. + IN gckOS Os,
  166701. + IN gckHARDWARE Hardware,
  166702. + IN gctUINT Urgency
  166703. + )
  166704. +{
  166705. + gcmkHEADER_ARG("Os=0x%x Hardware=0x%x Urgency=%u", Os, Hardware, Urgency);
  166706. +
  166707. + /* Do whatever you need to do to speed up the GPU now. */
  166708. +
  166709. + /* Success. */
  166710. + gcmkFOOTER_NO();
  166711. + return gcvSTATUS_OK;
  166712. +}
  166713. +
  166714. +/*******************************************************************************
  166715. +**
  166716. +** gckOS_BroadcastCalibrateSpeed
  166717. +**
  166718. +** Calibrate the speed of the GPU.
  166719. +**
  166720. +** INPUT:
  166721. +**
  166722. +** gckOS Os
  166723. +** Pointer to the gckOS object.
  166724. +**
  166725. +** gckHARDWARE Hardware
  166726. +** Pointer to the gckHARDWARE object.
  166727. +**
  166728. +** gctUINT Idle, Time
  166729. +** Idle/Time will give the percentage the GPU is idle, so you can use
  166730. +** this to calibrate the working point of the GPU.
  166731. +**
  166732. +** OUTPUT:
  166733. +**
  166734. +** Nothing.
  166735. +*/
  166736. +gceSTATUS
  166737. +gckOS_BroadcastCalibrateSpeed(
  166738. + IN gckOS Os,
  166739. + IN gckHARDWARE Hardware,
  166740. + IN gctUINT Idle,
  166741. + IN gctUINT Time
  166742. + )
  166743. +{
  166744. + gcmkHEADER_ARG("Os=0x%x Hardware=0x%x Idle=%u Time=%u",
  166745. + Os, Hardware, Idle, Time);
  166746. +
  166747. + /* Do whatever you need to do to callibrate the GPU speed. */
  166748. +
  166749. + /* Success. */
  166750. + gcmkFOOTER_NO();
  166751. + return gcvSTATUS_OK;
  166752. +}
  166753. +
  166754. +/*******************************************************************************
  166755. +********************************** Semaphores **********************************
  166756. +*******************************************************************************/
  166757. +
  166758. +/*******************************************************************************
  166759. +**
  166760. +** gckOS_CreateSemaphore
  166761. +**
  166762. +** Create a semaphore.
  166763. +**
  166764. +** INPUT:
  166765. +**
  166766. +** gckOS Os
  166767. +** Pointer to the gckOS object.
  166768. +**
  166769. +** OUTPUT:
  166770. +**
  166771. +** gctPOINTER * Semaphore
  166772. +** Pointer to the variable that will receive the created semaphore.
  166773. +*/
  166774. +gceSTATUS
  166775. +gckOS_CreateSemaphore(
  166776. + IN gckOS Os,
  166777. + OUT gctPOINTER * Semaphore
  166778. + )
  166779. +{
  166780. + gceSTATUS status;
  166781. + struct semaphore *sem = gcvNULL;
  166782. +
  166783. + gcmkHEADER_ARG("Os=0x%X", Os);
  166784. +
  166785. + /* Verify the arguments. */
  166786. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166787. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  166788. +
  166789. + /* Allocate the semaphore structure. */
  166790. + sem = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
  166791. + if (sem == gcvNULL)
  166792. + {
  166793. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  166794. + }
  166795. +
  166796. + /* Initialize the semaphore. */
  166797. + sema_init(sem, 1);
  166798. +
  166799. + /* Return to caller. */
  166800. + *Semaphore = (gctPOINTER) sem;
  166801. +
  166802. + /* Success. */
  166803. + gcmkFOOTER_NO();
  166804. + return gcvSTATUS_OK;
  166805. +
  166806. +OnError:
  166807. + /* Return the status. */
  166808. + gcmkFOOTER();
  166809. + return status;
  166810. +}
  166811. +
  166812. +/*******************************************************************************
  166813. +**
  166814. +** gckOS_AcquireSemaphore
  166815. +**
  166816. +** Acquire a semaphore.
  166817. +**
  166818. +** INPUT:
  166819. +**
  166820. +** gckOS Os
  166821. +** Pointer to the gckOS object.
  166822. +**
  166823. +** gctPOINTER Semaphore
  166824. +** Pointer to the semaphore thet needs to be acquired.
  166825. +**
  166826. +** OUTPUT:
  166827. +**
  166828. +** Nothing.
  166829. +*/
  166830. +gceSTATUS
  166831. +gckOS_AcquireSemaphore(
  166832. + IN gckOS Os,
  166833. + IN gctPOINTER Semaphore
  166834. + )
  166835. +{
  166836. + gceSTATUS status;
  166837. +
  166838. + gcmkHEADER_ARG("Os=0x%08X Semaphore=0x%08X", Os, Semaphore);
  166839. +
  166840. + /* Verify the arguments. */
  166841. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166842. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  166843. +
  166844. + /* Acquire the semaphore. */
  166845. + if (down_interruptible((struct semaphore *) Semaphore))
  166846. + {
  166847. + gcmkONERROR(gcvSTATUS_INTERRUPTED);
  166848. + }
  166849. +
  166850. + /* Success. */
  166851. + gcmkFOOTER_NO();
  166852. + return gcvSTATUS_OK;
  166853. +
  166854. +OnError:
  166855. + /* Return the status. */
  166856. + gcmkFOOTER();
  166857. + return status;
  166858. +}
  166859. +
  166860. +/*******************************************************************************
  166861. +**
  166862. +** gckOS_TryAcquireSemaphore
  166863. +**
  166864. +** Try to acquire a semaphore.
  166865. +**
  166866. +** INPUT:
  166867. +**
  166868. +** gckOS Os
  166869. +** Pointer to the gckOS object.
  166870. +**
  166871. +** gctPOINTER Semaphore
  166872. +** Pointer to the semaphore thet needs to be acquired.
  166873. +**
  166874. +** OUTPUT:
  166875. +**
  166876. +** Nothing.
  166877. +*/
  166878. +gceSTATUS
  166879. +gckOS_TryAcquireSemaphore(
  166880. + IN gckOS Os,
  166881. + IN gctPOINTER Semaphore
  166882. + )
  166883. +{
  166884. + gceSTATUS status;
  166885. +
  166886. + gcmkHEADER_ARG("Os=0x%x", Os);
  166887. +
  166888. + /* Verify the arguments. */
  166889. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166890. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  166891. +
  166892. + /* Acquire the semaphore. */
  166893. + if (down_trylock((struct semaphore *) Semaphore))
  166894. + {
  166895. + /* Timeout. */
  166896. + status = gcvSTATUS_TIMEOUT;
  166897. + gcmkFOOTER();
  166898. + return status;
  166899. + }
  166900. +
  166901. + /* Success. */
  166902. + gcmkFOOTER_NO();
  166903. + return gcvSTATUS_OK;
  166904. +}
  166905. +
  166906. +/*******************************************************************************
  166907. +**
  166908. +** gckOS_ReleaseSemaphore
  166909. +**
  166910. +** Release a previously acquired semaphore.
  166911. +**
  166912. +** INPUT:
  166913. +**
  166914. +** gckOS Os
  166915. +** Pointer to the gckOS object.
  166916. +**
  166917. +** gctPOINTER Semaphore
  166918. +** Pointer to the semaphore thet needs to be released.
  166919. +**
  166920. +** OUTPUT:
  166921. +**
  166922. +** Nothing.
  166923. +*/
  166924. +gceSTATUS
  166925. +gckOS_ReleaseSemaphore(
  166926. + IN gckOS Os,
  166927. + IN gctPOINTER Semaphore
  166928. + )
  166929. +{
  166930. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%X", Os, Semaphore);
  166931. +
  166932. + /* Verify the arguments. */
  166933. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166934. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  166935. +
  166936. + /* Release the semaphore. */
  166937. + up((struct semaphore *) Semaphore);
  166938. +
  166939. + /* Success. */
  166940. + gcmkFOOTER_NO();
  166941. + return gcvSTATUS_OK;
  166942. +}
  166943. +
  166944. +/*******************************************************************************
  166945. +**
  166946. +** gckOS_DestroySemaphore
  166947. +**
  166948. +** Destroy a semaphore.
  166949. +**
  166950. +** INPUT:
  166951. +**
  166952. +** gckOS Os
  166953. +** Pointer to the gckOS object.
  166954. +**
  166955. +** gctPOINTER Semaphore
  166956. +** Pointer to the semaphore thet needs to be destroyed.
  166957. +**
  166958. +** OUTPUT:
  166959. +**
  166960. +** Nothing.
  166961. +*/
  166962. +gceSTATUS
  166963. +gckOS_DestroySemaphore(
  166964. + IN gckOS Os,
  166965. + IN gctPOINTER Semaphore
  166966. + )
  166967. +{
  166968. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%X", Os, Semaphore);
  166969. +
  166970. + /* Verify the arguments. */
  166971. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166972. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  166973. +
  166974. + /* Free the sempahore structure. */
  166975. + kfree(Semaphore);
  166976. +
  166977. + /* Success. */
  166978. + gcmkFOOTER_NO();
  166979. + return gcvSTATUS_OK;
  166980. +}
  166981. +
  166982. +/*******************************************************************************
  166983. +**
  166984. +** gckOS_GetProcessID
  166985. +**
  166986. +** Get current process ID.
  166987. +**
  166988. +** INPUT:
  166989. +**
  166990. +** Nothing.
  166991. +**
  166992. +** OUTPUT:
  166993. +**
  166994. +** gctUINT32_PTR ProcessID
  166995. +** Pointer to the variable that receives the process ID.
  166996. +*/
  166997. +gceSTATUS
  166998. +gckOS_GetProcessID(
  166999. + OUT gctUINT32_PTR ProcessID
  167000. + )
  167001. +{
  167002. + /* Get process ID. */
  167003. + if (ProcessID != gcvNULL)
  167004. + {
  167005. + *ProcessID = _GetProcessID();
  167006. + }
  167007. +
  167008. + /* Success. */
  167009. + return gcvSTATUS_OK;
  167010. +}
  167011. +
  167012. +/*******************************************************************************
  167013. +**
  167014. +** gckOS_GetThreadID
  167015. +**
  167016. +** Get current thread ID.
  167017. +**
  167018. +** INPUT:
  167019. +**
  167020. +** Nothing.
  167021. +**
  167022. +** OUTPUT:
  167023. +**
  167024. +** gctUINT32_PTR ThreadID
  167025. +** Pointer to the variable that receives the thread ID.
  167026. +*/
  167027. +gceSTATUS
  167028. +gckOS_GetThreadID(
  167029. + OUT gctUINT32_PTR ThreadID
  167030. + )
  167031. +{
  167032. + /* Get thread ID. */
  167033. + if (ThreadID != gcvNULL)
  167034. + {
  167035. + *ThreadID = _GetThreadID();
  167036. + }
  167037. +
  167038. + /* Success. */
  167039. + return gcvSTATUS_OK;
  167040. +}
  167041. +
  167042. +/*******************************************************************************
  167043. +**
  167044. +** gckOS_SetGPUPower
  167045. +**
  167046. +** Set the power of the GPU on or off.
  167047. +**
  167048. +** INPUT:
  167049. +**
  167050. +** gckOS Os
  167051. +** Pointer to a gckOS object.
  167052. +**
  167053. +** gckCORE Core
  167054. +** GPU whose power is set.
  167055. +**
  167056. +** gctBOOL Clock
  167057. +** gcvTRUE to turn on the clock, or gcvFALSE to turn off the clock.
  167058. +**
  167059. +** gctBOOL Power
  167060. +** gcvTRUE to turn on the power, or gcvFALSE to turn off the power.
  167061. +**
  167062. +** OUTPUT:
  167063. +**
  167064. +** Nothing.
  167065. +*/
  167066. +gceSTATUS
  167067. +gckOS_SetGPUPower(
  167068. + IN gckOS Os,
  167069. + IN gceCORE Core,
  167070. + IN gctBOOL Clock,
  167071. + IN gctBOOL Power
  167072. + )
  167073. +{
  167074. + struct clk *clk_3dcore = Os->device->clk_3d_core;
  167075. + struct clk *clk_3dshader = Os->device->clk_3d_shader;
  167076. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  167077. + struct clk *clk_3d_axi = Os->device->clk_3d_axi;
  167078. +#endif
  167079. + struct clk *clk_2dcore = Os->device->clk_2d_core;
  167080. + struct clk *clk_2d_axi = Os->device->clk_2d_axi;
  167081. + struct clk *clk_vg_axi = Os->device->clk_vg_axi;
  167082. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  167083. + int ret;
  167084. +#endif
  167085. +
  167086. + gctBOOL oldClockState = gcvFALSE;
  167087. + gctBOOL oldPowerState = gcvFALSE;
  167088. +
  167089. + gcmkHEADER_ARG("Os=0x%X Core=%d Clock=%d Power=%d", Os, Core, Clock, Power);
  167090. +
  167091. + if (Os->device->kernels[Core] != NULL)
  167092. + {
  167093. +#if gcdENABLE_VG
  167094. + if (Core == gcvCORE_VG)
  167095. + {
  167096. + oldClockState = Os->device->kernels[Core]->vg->hardware->clockState;
  167097. + oldPowerState = Os->device->kernels[Core]->vg->hardware->powerState;
  167098. + }
  167099. + else
  167100. + {
  167101. +#endif
  167102. + oldClockState = Os->device->kernels[Core]->hardware->clockState;
  167103. + oldPowerState = Os->device->kernels[Core]->hardware->powerState;
  167104. +#if gcdENABLE_VG
  167105. + }
  167106. +#endif
  167107. + }
  167108. + if((Power == gcvTRUE) && (oldPowerState == gcvFALSE))
  167109. + {
  167110. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  167111. + if(!IS_ERR(Os->device->gpu_regulator)) {
  167112. + ret = regulator_enable(Os->device->gpu_regulator);
  167113. + if (ret != 0)
  167114. + gckOS_Print("%s(%d): fail to enable pu regulator %d!\n",
  167115. + __FUNCTION__, __LINE__, ret);
  167116. + }
  167117. +#else
  167118. + imx_gpc_power_up_pu(true);
  167119. +#endif
  167120. +
  167121. +#ifdef CONFIG_PM
  167122. + pm_runtime_get_sync(Os->device->pmdev);
  167123. +#endif
  167124. + }
  167125. +
  167126. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  167127. + if (Clock == gcvTRUE) {
  167128. + if (oldClockState == gcvFALSE) {
  167129. + switch (Core) {
  167130. + case gcvCORE_MAJOR:
  167131. + clk_enable(clk_3dcore);
  167132. + if (cpu_is_mx6q())
  167133. + clk_enable(clk_3dshader);
  167134. + break;
  167135. + case gcvCORE_2D:
  167136. + clk_enable(clk_2dcore);
  167137. + clk_enable(clk_2d_axi);
  167138. + break;
  167139. + case gcvCORE_VG:
  167140. + clk_enable(clk_2dcore);
  167141. + clk_enable(clk_vg_axi);
  167142. + break;
  167143. + default:
  167144. + break;
  167145. + }
  167146. + }
  167147. + } else {
  167148. + if (oldClockState == gcvTRUE) {
  167149. + switch (Core) {
  167150. + case gcvCORE_MAJOR:
  167151. + if (cpu_is_mx6q())
  167152. + clk_disable(clk_3dshader);
  167153. + clk_disable(clk_3dcore);
  167154. + break;
  167155. + case gcvCORE_2D:
  167156. + clk_disable(clk_2dcore);
  167157. + clk_disable(clk_2d_axi);
  167158. + break;
  167159. + case gcvCORE_VG:
  167160. + clk_disable(clk_2dcore);
  167161. + clk_disable(clk_vg_axi);
  167162. + break;
  167163. + default:
  167164. + break;
  167165. + }
  167166. + }
  167167. + }
  167168. +#else
  167169. + if (Clock == gcvTRUE) {
  167170. + if (oldClockState == gcvFALSE) {
  167171. + switch (Core) {
  167172. + case gcvCORE_MAJOR:
  167173. + clk_prepare_enable(clk_3dcore);
  167174. + clk_prepare_enable(clk_3dshader);
  167175. + clk_prepare_enable(clk_3d_axi);
  167176. + break;
  167177. + case gcvCORE_2D:
  167178. + clk_prepare_enable(clk_2dcore);
  167179. + clk_prepare_enable(clk_2d_axi);
  167180. + break;
  167181. + case gcvCORE_VG:
  167182. + clk_prepare_enable(clk_2dcore);
  167183. + clk_prepare_enable(clk_vg_axi);
  167184. + break;
  167185. + default:
  167186. + break;
  167187. + }
  167188. + }
  167189. + } else {
  167190. + if (oldClockState == gcvTRUE) {
  167191. + switch (Core) {
  167192. + case gcvCORE_MAJOR:
  167193. + clk_disable_unprepare(clk_3d_axi);
  167194. + clk_disable_unprepare(clk_3dshader);
  167195. + clk_disable_unprepare(clk_3dcore);
  167196. + break;
  167197. + case gcvCORE_2D:
  167198. + clk_disable_unprepare(clk_2d_axi);
  167199. + clk_disable_unprepare(clk_2dcore);
  167200. + break;
  167201. + case gcvCORE_VG:
  167202. + clk_disable_unprepare(clk_vg_axi);
  167203. + clk_disable_unprepare(clk_2dcore);
  167204. + break;
  167205. + default:
  167206. + break;
  167207. + }
  167208. + }
  167209. + }
  167210. +#endif
  167211. + if((Power == gcvFALSE) && (oldPowerState == gcvTRUE))
  167212. + {
  167213. +#ifdef CONFIG_PM
  167214. + pm_runtime_put_sync(Os->device->pmdev);
  167215. +#endif
  167216. +
  167217. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  167218. + if(!IS_ERR(Os->device->gpu_regulator))
  167219. + regulator_disable(Os->device->gpu_regulator);
  167220. +#else
  167221. + imx_gpc_power_up_pu(false);
  167222. +#endif
  167223. +
  167224. + }
  167225. + /* TODO: Put your code here. */
  167226. + gcmkFOOTER_NO();
  167227. + return gcvSTATUS_OK;
  167228. +}
  167229. +
  167230. +/*******************************************************************************
  167231. +**
  167232. +** gckOS_ResetGPU
  167233. +**
  167234. +** Reset the GPU.
  167235. +**
  167236. +** INPUT:
  167237. +**
  167238. +** gckOS Os
  167239. +** Pointer to a gckOS object.
  167240. +**
  167241. +** gckCORE Core
  167242. +** GPU whose power is set.
  167243. +**
  167244. +** OUTPUT:
  167245. +**
  167246. +** Nothing.
  167247. +*/
  167248. +gceSTATUS
  167249. +gckOS_ResetGPU(
  167250. + IN gckOS Os,
  167251. + IN gceCORE Core
  167252. + )
  167253. +{
  167254. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  167255. +#define SRC_SCR_OFFSET 0
  167256. +#define BP_SRC_SCR_GPU3D_RST 1
  167257. +#define BP_SRC_SCR_GPU2D_RST 4
  167258. + void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR);
  167259. + gctUINT32 bit_offset,val;
  167260. +
  167261. + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
  167262. +
  167263. + if(Core == gcvCORE_MAJOR) {
  167264. + bit_offset = BP_SRC_SCR_GPU3D_RST;
  167265. + } else if((Core == gcvCORE_VG)
  167266. + ||(Core == gcvCORE_2D)) {
  167267. + bit_offset = BP_SRC_SCR_GPU2D_RST;
  167268. + } else {
  167269. + return gcvSTATUS_INVALID_CONFIG;
  167270. + }
  167271. + val = __raw_readl(src_base + SRC_SCR_OFFSET);
  167272. + val &= ~(1 << (bit_offset));
  167273. + val |= (1 << (bit_offset));
  167274. + __raw_writel(val, src_base + SRC_SCR_OFFSET);
  167275. +
  167276. + while ((__raw_readl(src_base + SRC_SCR_OFFSET) &
  167277. + (1 << (bit_offset))) != 0) {
  167278. + }
  167279. +
  167280. + gcmkFOOTER_NO();
  167281. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  167282. + struct reset_control *rstc = Os->device->rstc[Core];
  167283. + if (rstc)
  167284. + reset_control_reset(rstc);
  167285. +#else
  167286. + imx_src_reset_gpu((int)Core);
  167287. +#endif
  167288. + return gcvSTATUS_OK;
  167289. +}
  167290. +
  167291. +/*******************************************************************************
  167292. +**
  167293. +** gckOS_PrepareGPUFrequency
  167294. +**
  167295. +** Prepare to set GPU frequency and voltage.
  167296. +**
  167297. +** INPUT:
  167298. +**
  167299. +** gckOS Os
  167300. +** Pointer to a gckOS object.
  167301. +**
  167302. +** gckCORE Core
  167303. +** GPU whose frequency and voltage will be set.
  167304. +**
  167305. +** OUTPUT:
  167306. +**
  167307. +** Nothing.
  167308. +*/
  167309. +gceSTATUS
  167310. +gckOS_PrepareGPUFrequency(
  167311. + IN gckOS Os,
  167312. + IN gceCORE Core
  167313. + )
  167314. +{
  167315. + return gcvSTATUS_OK;
  167316. +}
  167317. +
  167318. +/*******************************************************************************
  167319. +**
  167320. +** gckOS_FinishGPUFrequency
  167321. +**
  167322. +** Finish GPU frequency setting.
  167323. +**
  167324. +** INPUT:
  167325. +**
  167326. +** gckOS Os
  167327. +** Pointer to a gckOS object.
  167328. +**
  167329. +** gckCORE Core
  167330. +** GPU whose frequency and voltage is set.
  167331. +**
  167332. +** OUTPUT:
  167333. +**
  167334. +** Nothing.
  167335. +*/
  167336. +gceSTATUS
  167337. +gckOS_FinishGPUFrequency(
  167338. + IN gckOS Os,
  167339. + IN gceCORE Core
  167340. + )
  167341. +{
  167342. + return gcvSTATUS_OK;
  167343. +}
  167344. +
  167345. +/*******************************************************************************
  167346. +**
  167347. +** gckOS_QueryGPUFrequency
  167348. +**
  167349. +** Query the current frequency of the GPU.
  167350. +**
  167351. +** INPUT:
  167352. +**
  167353. +** gckOS Os
  167354. +** Pointer to a gckOS object.
  167355. +**
  167356. +** gckCORE Core
  167357. +** GPU whose power is set.
  167358. +**
  167359. +** gctUINT32 * Frequency
  167360. +** Pointer to a gctUINT32 to obtain current frequency, in MHz.
  167361. +**
  167362. +** gctUINT8 * Scale
  167363. +** Pointer to a gctUINT8 to obtain current scale(1 - 64).
  167364. +**
  167365. +** OUTPUT:
  167366. +**
  167367. +** Nothing.
  167368. +*/
  167369. +gceSTATUS
  167370. +gckOS_QueryGPUFrequency(
  167371. + IN gckOS Os,
  167372. + IN gceCORE Core,
  167373. + OUT gctUINT32 * Frequency,
  167374. + OUT gctUINT8 * Scale
  167375. + )
  167376. +{
  167377. + return gcvSTATUS_OK;
  167378. +}
  167379. +
  167380. +/*******************************************************************************
  167381. +**
  167382. +** gckOS_SetGPUFrequency
  167383. +**
  167384. +** Set frequency and voltage of the GPU.
  167385. +**
  167386. +** 1. DVFS manager gives the target scale of full frequency, BSP must find
  167387. +** a real frequency according to this scale and board's configure.
  167388. +**
  167389. +** 2. BSP should find a suitable voltage for this frequency.
  167390. +**
  167391. +** 3. BSP must make sure setting take effect before this function returns.
  167392. +**
  167393. +** INPUT:
  167394. +**
  167395. +** gckOS Os
  167396. +** Pointer to a gckOS object.
  167397. +**
  167398. +** gckCORE Core
  167399. +** GPU whose power is set.
  167400. +**
  167401. +** gctUINT8 Scale
  167402. +** Target scale of full frequency, range is [1, 64]. 1 means 1/64 of
  167403. +** full frequency and 64 means 64/64 of full frequency.
  167404. +**
  167405. +** OUTPUT:
  167406. +**
  167407. +** Nothing.
  167408. +*/
  167409. +gceSTATUS
  167410. +gckOS_SetGPUFrequency(
  167411. + IN gckOS Os,
  167412. + IN gceCORE Core,
  167413. + IN gctUINT8 Scale
  167414. + )
  167415. +{
  167416. + return gcvSTATUS_OK;
  167417. +}
  167418. +
  167419. +/*----------------------------------------------------------------------------*/
  167420. +/*----- Profile --------------------------------------------------------------*/
  167421. +
  167422. +gceSTATUS
  167423. +gckOS_GetProfileTick(
  167424. + OUT gctUINT64_PTR Tick
  167425. + )
  167426. +{
  167427. + struct timespec time;
  167428. +
  167429. + ktime_get_ts(&time);
  167430. +
  167431. + *Tick = time.tv_nsec + time.tv_sec * 1000000000ULL;
  167432. +
  167433. + return gcvSTATUS_OK;
  167434. +}
  167435. +
  167436. +gceSTATUS
  167437. +gckOS_QueryProfileTickRate(
  167438. + OUT gctUINT64_PTR TickRate
  167439. + )
  167440. +{
  167441. + struct timespec res;
  167442. +
  167443. + hrtimer_get_res(CLOCK_MONOTONIC, &res);
  167444. +
  167445. + *TickRate = res.tv_nsec + res.tv_sec * 1000000000ULL;
  167446. +
  167447. + return gcvSTATUS_OK;
  167448. +}
  167449. +
  167450. +gctUINT32
  167451. +gckOS_ProfileToMS(
  167452. + IN gctUINT64 Ticks
  167453. + )
  167454. +{
  167455. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
  167456. + return div_u64(Ticks, 1000000);
  167457. +#else
  167458. + gctUINT64 rem = Ticks;
  167459. + gctUINT64 b = 1000000;
  167460. + gctUINT64 res, d = 1;
  167461. + gctUINT32 high = rem >> 32;
  167462. +
  167463. + /* Reduce the thing a bit first */
  167464. + res = 0;
  167465. + if (high >= 1000000)
  167466. + {
  167467. + high /= 1000000;
  167468. + res = (gctUINT64) high << 32;
  167469. + rem -= (gctUINT64) (high * 1000000) << 32;
  167470. + }
  167471. +
  167472. + while (((gctINT64) b > 0) && (b < rem))
  167473. + {
  167474. + b <<= 1;
  167475. + d <<= 1;
  167476. + }
  167477. +
  167478. + do
  167479. + {
  167480. + if (rem >= b)
  167481. + {
  167482. + rem -= b;
  167483. + res += d;
  167484. + }
  167485. +
  167486. + b >>= 1;
  167487. + d >>= 1;
  167488. + }
  167489. + while (d);
  167490. +
  167491. + return (gctUINT32) res;
  167492. +#endif
  167493. +}
  167494. +
  167495. +/******************************************************************************\
  167496. +******************************* Signal Management ******************************
  167497. +\******************************************************************************/
  167498. +
  167499. +#undef _GC_OBJ_ZONE
  167500. +#define _GC_OBJ_ZONE gcvZONE_SIGNAL
  167501. +
  167502. +/*******************************************************************************
  167503. +**
  167504. +** gckOS_CreateSignal
  167505. +**
  167506. +** Create a new signal.
  167507. +**
  167508. +** INPUT:
  167509. +**
  167510. +** gckOS Os
  167511. +** Pointer to an gckOS object.
  167512. +**
  167513. +** gctBOOL ManualReset
  167514. +** If set to gcvTRUE, gckOS_Signal with gcvFALSE must be called in
  167515. +** order to set the signal to nonsignaled state.
  167516. +** If set to gcvFALSE, the signal will automatically be set to
  167517. +** nonsignaled state by gckOS_WaitSignal function.
  167518. +**
  167519. +** OUTPUT:
  167520. +**
  167521. +** gctSIGNAL * Signal
  167522. +** Pointer to a variable receiving the created gctSIGNAL.
  167523. +*/
  167524. +gceSTATUS
  167525. +gckOS_CreateSignal(
  167526. + IN gckOS Os,
  167527. + IN gctBOOL ManualReset,
  167528. + OUT gctSIGNAL * Signal
  167529. + )
  167530. +{
  167531. + gceSTATUS status;
  167532. + gcsSIGNAL_PTR signal;
  167533. +
  167534. + gcmkHEADER_ARG("Os=0x%X ManualReset=%d", Os, ManualReset);
  167535. +
  167536. + /* Verify the arguments. */
  167537. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167538. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167539. +
  167540. + /* Create an event structure. */
  167541. + signal = (gcsSIGNAL_PTR) kmalloc(sizeof(gcsSIGNAL), GFP_KERNEL | gcdNOWARN);
  167542. +
  167543. + if (signal == gcvNULL)
  167544. + {
  167545. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  167546. + }
  167547. +
  167548. + /* Save the process ID. */
  167549. + signal->process = (gctHANDLE)(gctUINTPTR_T) _GetProcessID();
  167550. + signal->manualReset = ManualReset;
  167551. + signal->hardware = gcvNULL;
  167552. + init_completion(&signal->obj);
  167553. + atomic_set(&signal->ref, 1);
  167554. +
  167555. + gcmkONERROR(_AllocateIntegerId(&Os->signalDB, signal, &signal->id));
  167556. +
  167557. + *Signal = (gctSIGNAL)(gctUINTPTR_T)signal->id;
  167558. +
  167559. + gcmkFOOTER_ARG("*Signal=0x%X", *Signal);
  167560. + return gcvSTATUS_OK;
  167561. +
  167562. +OnError:
  167563. + if (signal != gcvNULL)
  167564. + {
  167565. + kfree(signal);
  167566. + }
  167567. +
  167568. + gcmkFOOTER_NO();
  167569. + return status;
  167570. +}
  167571. +
  167572. +gceSTATUS
  167573. +gckOS_SignalQueryHardware(
  167574. + IN gckOS Os,
  167575. + IN gctSIGNAL Signal,
  167576. + OUT gckHARDWARE * Hardware
  167577. + )
  167578. +{
  167579. + gceSTATUS status;
  167580. + gcsSIGNAL_PTR signal;
  167581. +
  167582. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Hardware=0x%X", Os, Signal, Hardware);
  167583. +
  167584. + /* Verify the arguments. */
  167585. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167586. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167587. + gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
  167588. +
  167589. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  167590. +
  167591. + *Hardware = signal->hardware;
  167592. +
  167593. + gcmkFOOTER_NO();
  167594. + return gcvSTATUS_OK;
  167595. +OnError:
  167596. + gcmkFOOTER();
  167597. + return status;
  167598. +}
  167599. +
  167600. +gceSTATUS
  167601. +gckOS_SignalSetHardware(
  167602. + IN gckOS Os,
  167603. + IN gctSIGNAL Signal,
  167604. + IN gckHARDWARE Hardware
  167605. + )
  167606. +{
  167607. + gceSTATUS status;
  167608. + gcsSIGNAL_PTR signal;
  167609. +
  167610. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Hardware=0x%X", Os, Signal, Hardware);
  167611. +
  167612. + /* Verify the arguments. */
  167613. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167614. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167615. +
  167616. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  167617. +
  167618. + signal->hardware = Hardware;
  167619. +
  167620. + gcmkFOOTER_NO();
  167621. + return gcvSTATUS_OK;
  167622. +OnError:
  167623. + gcmkFOOTER();
  167624. + return status;
  167625. +}
  167626. +
  167627. +/*******************************************************************************
  167628. +**
  167629. +** gckOS_DestroySignal
  167630. +**
  167631. +** Destroy a signal.
  167632. +**
  167633. +** INPUT:
  167634. +**
  167635. +** gckOS Os
  167636. +** Pointer to an gckOS object.
  167637. +**
  167638. +** gctSIGNAL Signal
  167639. +** Pointer to the gctSIGNAL.
  167640. +**
  167641. +** OUTPUT:
  167642. +**
  167643. +** Nothing.
  167644. +*/
  167645. +gceSTATUS
  167646. +gckOS_DestroySignal(
  167647. + IN gckOS Os,
  167648. + IN gctSIGNAL Signal
  167649. + )
  167650. +{
  167651. + gceSTATUS status;
  167652. + gcsSIGNAL_PTR signal;
  167653. + gctBOOL acquired = gcvFALSE;
  167654. +
  167655. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X", Os, Signal);
  167656. +
  167657. + /* Verify the arguments. */
  167658. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167659. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167660. +
  167661. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->signalMutex, gcvINFINITE));
  167662. + acquired = gcvTRUE;
  167663. +
  167664. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  167665. +
  167666. + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
  167667. +
  167668. + if (atomic_dec_and_test(&signal->ref))
  167669. + {
  167670. + gcmkVERIFY_OK(_DestroyIntegerId(&Os->signalDB, signal->id));
  167671. +
  167672. + /* Free the sgianl. */
  167673. + kfree(signal);
  167674. + }
  167675. +
  167676. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  167677. + acquired = gcvFALSE;
  167678. +
  167679. + /* Success. */
  167680. + gcmkFOOTER_NO();
  167681. + return gcvSTATUS_OK;
  167682. +
  167683. +OnError:
  167684. + if (acquired)
  167685. + {
  167686. + /* Release the mutex. */
  167687. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  167688. + }
  167689. +
  167690. + gcmkFOOTER();
  167691. + return status;
  167692. +}
  167693. +
  167694. +/*******************************************************************************
  167695. +**
  167696. +** gckOS_Signal
  167697. +**
  167698. +** Set a state of the specified signal.
  167699. +**
  167700. +** INPUT:
  167701. +**
  167702. +** gckOS Os
  167703. +** Pointer to an gckOS object.
  167704. +**
  167705. +** gctSIGNAL Signal
  167706. +** Pointer to the gctSIGNAL.
  167707. +**
  167708. +** gctBOOL State
  167709. +** If gcvTRUE, the signal will be set to signaled state.
  167710. +** If gcvFALSE, the signal will be set to nonsignaled state.
  167711. +**
  167712. +** OUTPUT:
  167713. +**
  167714. +** Nothing.
  167715. +*/
  167716. +gceSTATUS
  167717. +gckOS_Signal(
  167718. + IN gckOS Os,
  167719. + IN gctSIGNAL Signal,
  167720. + IN gctBOOL State
  167721. + )
  167722. +{
  167723. + gceSTATUS status;
  167724. + gcsSIGNAL_PTR signal;
  167725. + gctBOOL acquired = gcvFALSE;
  167726. +
  167727. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X State=%d", Os, Signal, State);
  167728. +
  167729. + /* Verify the arguments. */
  167730. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167731. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167732. +
  167733. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->signalMutex, gcvINFINITE));
  167734. + acquired = gcvTRUE;
  167735. +
  167736. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  167737. +
  167738. + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
  167739. +
  167740. + if (State)
  167741. + {
  167742. + /* unbind the signal from hardware. */
  167743. + signal->hardware = gcvNULL;
  167744. +
  167745. + /* Set the event to a signaled state. */
  167746. + complete(&signal->obj);
  167747. + }
  167748. + else
  167749. + {
  167750. + /* Set the event to an unsignaled state. */
  167751. + reinit_completion(&signal->obj);
  167752. + }
  167753. +
  167754. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  167755. + acquired = gcvFALSE;
  167756. +
  167757. + /* Success. */
  167758. + gcmkFOOTER_NO();
  167759. + return gcvSTATUS_OK;
  167760. +
  167761. +OnError:
  167762. + if (acquired)
  167763. + {
  167764. + /* Release the mutex. */
  167765. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  167766. + }
  167767. +
  167768. + gcmkFOOTER();
  167769. + return status;
  167770. +}
  167771. +
  167772. +#if gcdENABLE_VG
  167773. +gceSTATUS
  167774. +gckOS_SetSignalVG(
  167775. + IN gckOS Os,
  167776. + IN gctHANDLE Process,
  167777. + IN gctSIGNAL Signal
  167778. + )
  167779. +{
  167780. + gceSTATUS status;
  167781. + gctINT result;
  167782. + struct task_struct * userTask;
  167783. + struct siginfo info;
  167784. +
  167785. + userTask = FIND_TASK_BY_PID((pid_t)(gctUINTPTR_T) Process);
  167786. +
  167787. + if (userTask != gcvNULL)
  167788. + {
  167789. + info.si_signo = 48;
  167790. + info.si_code = __SI_CODE(__SI_RT, SI_KERNEL);
  167791. + info.si_pid = 0;
  167792. + info.si_uid = 0;
  167793. + info.si_ptr = (gctPOINTER) Signal;
  167794. +
  167795. + /* Signals with numbers between 32 and 63 are real-time,
  167796. + send a real-time signal to the user process. */
  167797. + result = send_sig_info(48, &info, userTask);
  167798. +
  167799. + printk("gckOS_SetSignalVG:0x%x\n", result);
  167800. + /* Error? */
  167801. + if (result < 0)
  167802. + {
  167803. + status = gcvSTATUS_GENERIC_IO;
  167804. +
  167805. + gcmkTRACE(
  167806. + gcvLEVEL_ERROR,
  167807. + "%s(%d): an error has occurred.\n",
  167808. + __FUNCTION__, __LINE__
  167809. + );
  167810. + }
  167811. + else
  167812. + {
  167813. + status = gcvSTATUS_OK;
  167814. + }
  167815. + }
  167816. + else
  167817. + {
  167818. + status = gcvSTATUS_GENERIC_IO;
  167819. +
  167820. + gcmkTRACE(
  167821. + gcvLEVEL_ERROR,
  167822. + "%s(%d): an error has occurred.\n",
  167823. + __FUNCTION__, __LINE__
  167824. + );
  167825. + }
  167826. +
  167827. + /* Return status. */
  167828. + return status;
  167829. +}
  167830. +#endif
  167831. +
  167832. +/*******************************************************************************
  167833. +**
  167834. +** gckOS_UserSignal
  167835. +**
  167836. +** Set the specified signal which is owned by a process to signaled state.
  167837. +**
  167838. +** INPUT:
  167839. +**
  167840. +** gckOS Os
  167841. +** Pointer to an gckOS object.
  167842. +**
  167843. +** gctSIGNAL Signal
  167844. +** Pointer to the gctSIGNAL.
  167845. +**
  167846. +** gctHANDLE Process
  167847. +** Handle of process owning the signal.
  167848. +**
  167849. +** OUTPUT:
  167850. +**
  167851. +** Nothing.
  167852. +*/
  167853. +gceSTATUS
  167854. +gckOS_UserSignal(
  167855. + IN gckOS Os,
  167856. + IN gctSIGNAL Signal,
  167857. + IN gctHANDLE Process
  167858. + )
  167859. +{
  167860. + gceSTATUS status;
  167861. + gctSIGNAL signal;
  167862. +
  167863. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=%d",
  167864. + Os, Signal, (gctINT32)(gctUINTPTR_T)Process);
  167865. +
  167866. + /* Map the signal into kernel space. */
  167867. + gcmkONERROR(gckOS_MapSignal(Os, Signal, Process, &signal));
  167868. +
  167869. + /* Signal. */
  167870. + status = gckOS_Signal(Os, signal, gcvTRUE);
  167871. +
  167872. + /* Unmap the signal */
  167873. + gcmkVERIFY_OK(gckOS_UnmapSignal(Os, Signal));
  167874. +
  167875. + gcmkFOOTER();
  167876. + return status;
  167877. +
  167878. +OnError:
  167879. + /* Return the status. */
  167880. + gcmkFOOTER();
  167881. + return status;
  167882. +}
  167883. +
  167884. +/*******************************************************************************
  167885. +**
  167886. +** gckOS_WaitSignal
  167887. +**
  167888. +** Wait for a signal to become signaled.
  167889. +**
  167890. +** INPUT:
  167891. +**
  167892. +** gckOS Os
  167893. +** Pointer to an gckOS object.
  167894. +**
  167895. +** gctSIGNAL Signal
  167896. +** Pointer to the gctSIGNAL.
  167897. +**
  167898. +** gctUINT32 Wait
  167899. +** Number of milliseconds to wait.
  167900. +** Pass the value of gcvINFINITE for an infinite wait.
  167901. +**
  167902. +** OUTPUT:
  167903. +**
  167904. +** Nothing.
  167905. +*/
  167906. +gceSTATUS
  167907. +gckOS_WaitSignal(
  167908. + IN gckOS Os,
  167909. + IN gctSIGNAL Signal,
  167910. + IN gctUINT32 Wait
  167911. + )
  167912. +{
  167913. + gceSTATUS status = gcvSTATUS_OK;
  167914. + gcsSIGNAL_PTR signal;
  167915. +
  167916. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Wait=0x%08X", Os, Signal, Wait);
  167917. +
  167918. + /* Verify the arguments. */
  167919. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167920. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167921. +
  167922. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  167923. +
  167924. + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
  167925. +
  167926. + might_sleep();
  167927. +
  167928. + spin_lock_irq(&signal->obj.wait.lock);
  167929. +
  167930. + if (signal->obj.done)
  167931. + {
  167932. + if (!signal->manualReset)
  167933. + {
  167934. + signal->obj.done = 0;
  167935. + }
  167936. +
  167937. + status = gcvSTATUS_OK;
  167938. + }
  167939. + else if (Wait == 0)
  167940. + {
  167941. + status = gcvSTATUS_TIMEOUT;
  167942. + }
  167943. + else
  167944. + {
  167945. + /* Convert wait to milliseconds. */
  167946. +#if gcdDETECT_TIMEOUT
  167947. + gctINT timeout = (Wait == gcvINFINITE)
  167948. + ? gcdINFINITE_TIMEOUT * HZ / 1000
  167949. + : Wait * HZ / 1000;
  167950. +
  167951. + gctUINT complained = 0;
  167952. +#else
  167953. + gctINT timeout = (Wait == gcvINFINITE)
  167954. + ? MAX_SCHEDULE_TIMEOUT
  167955. + : Wait * HZ / 1000;
  167956. +#endif
  167957. +
  167958. + DECLARE_WAITQUEUE(wait, current);
  167959. + wait.flags |= WQ_FLAG_EXCLUSIVE;
  167960. + __add_wait_queue_tail(&signal->obj.wait, &wait);
  167961. +
  167962. + while (gcvTRUE)
  167963. + {
  167964. + if (signal_pending(current))
  167965. + {
  167966. + /* Interrupt received. */
  167967. + status = gcvSTATUS_INTERRUPTED;
  167968. + break;
  167969. + }
  167970. +
  167971. + __set_current_state(TASK_INTERRUPTIBLE);
  167972. + spin_unlock_irq(&signal->obj.wait.lock);
  167973. + timeout = schedule_timeout(timeout);
  167974. + spin_lock_irq(&signal->obj.wait.lock);
  167975. +
  167976. + if (signal->obj.done)
  167977. + {
  167978. + if (!signal->manualReset)
  167979. + {
  167980. + signal->obj.done = 0;
  167981. + }
  167982. +
  167983. + status = gcvSTATUS_OK;
  167984. + break;
  167985. + }
  167986. +
  167987. +#if gcdDETECT_TIMEOUT
  167988. + if ((Wait == gcvINFINITE) && (timeout == 0))
  167989. + {
  167990. + gctUINT32 dmaAddress1, dmaAddress2;
  167991. + gctUINT32 dmaState1, dmaState2;
  167992. +
  167993. + dmaState1 = dmaState2 =
  167994. + dmaAddress1 = dmaAddress2 = 0;
  167995. +
  167996. + /* Verify whether DMA is running. */
  167997. + gcmkVERIFY_OK(_VerifyDMA(
  167998. + Os, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
  167999. + ));
  168000. +
  168001. +#if gcdDETECT_DMA_ADDRESS
  168002. + /* Dump only if DMA appears stuck. */
  168003. + if (
  168004. + (dmaAddress1 == dmaAddress2)
  168005. +#if gcdDETECT_DMA_STATE
  168006. + && (dmaState1 == dmaState2)
  168007. +#endif
  168008. + )
  168009. +#endif
  168010. + {
  168011. + /* Increment complain count. */
  168012. + complained += 1;
  168013. +
  168014. + gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR));
  168015. +
  168016. + gcmkPRINT(
  168017. + "%s(%d): signal 0x%X; forced message flush (%d).",
  168018. + __FUNCTION__, __LINE__, Signal, complained
  168019. + );
  168020. +
  168021. + /* Flush the debug cache. */
  168022. + gcmkDEBUGFLUSH(dmaAddress2);
  168023. + }
  168024. +
  168025. + /* Reset timeout. */
  168026. + timeout = gcdINFINITE_TIMEOUT * HZ / 1000;
  168027. + }
  168028. +#endif
  168029. +
  168030. + if (timeout == 0)
  168031. + {
  168032. +
  168033. + status = gcvSTATUS_TIMEOUT;
  168034. + break;
  168035. + }
  168036. + }
  168037. +
  168038. + __remove_wait_queue(&signal->obj.wait, &wait);
  168039. +
  168040. +#if gcdDETECT_TIMEOUT
  168041. + if (complained)
  168042. + {
  168043. + gcmkPRINT(
  168044. + "%s(%d): signal=0x%X; waiting done; status=%d",
  168045. + __FUNCTION__, __LINE__, Signal, status
  168046. + );
  168047. + }
  168048. +#endif
  168049. + }
  168050. +
  168051. + spin_unlock_irq(&signal->obj.wait.lock);
  168052. +
  168053. +OnError:
  168054. + /* Return status. */
  168055. + gcmkFOOTER_ARG("Signal=0x%X status=%d", Signal, status);
  168056. + return status;
  168057. +}
  168058. +
  168059. +/*******************************************************************************
  168060. +**
  168061. +** gckOS_MapSignal
  168062. +**
  168063. +** Map a signal in to the current process space.
  168064. +**
  168065. +** INPUT:
  168066. +**
  168067. +** gckOS Os
  168068. +** Pointer to an gckOS object.
  168069. +**
  168070. +** gctSIGNAL Signal
  168071. +** Pointer to tha gctSIGNAL to map.
  168072. +**
  168073. +** gctHANDLE Process
  168074. +** Handle of process owning the signal.
  168075. +**
  168076. +** OUTPUT:
  168077. +**
  168078. +** gctSIGNAL * MappedSignal
  168079. +** Pointer to a variable receiving the mapped gctSIGNAL.
  168080. +*/
  168081. +gceSTATUS
  168082. +gckOS_MapSignal(
  168083. + IN gckOS Os,
  168084. + IN gctSIGNAL Signal,
  168085. + IN gctHANDLE Process,
  168086. + OUT gctSIGNAL * MappedSignal
  168087. + )
  168088. +{
  168089. + gceSTATUS status;
  168090. + gcsSIGNAL_PTR signal;
  168091. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=0x%X", Os, Signal, Process);
  168092. +
  168093. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  168094. + gcmkVERIFY_ARGUMENT(MappedSignal != gcvNULL);
  168095. +
  168096. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  168097. +
  168098. + if(atomic_inc_return(&signal->ref) <= 1)
  168099. + {
  168100. + /* The previous value is 0, it has been deleted. */
  168101. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  168102. + }
  168103. +
  168104. + *MappedSignal = (gctSIGNAL) Signal;
  168105. +
  168106. + /* Success. */
  168107. + gcmkFOOTER_ARG("*MappedSignal=0x%X", *MappedSignal);
  168108. + return gcvSTATUS_OK;
  168109. +
  168110. +OnError:
  168111. + gcmkFOOTER_NO();
  168112. + return status;
  168113. +}
  168114. +
  168115. +/*******************************************************************************
  168116. +**
  168117. +** gckOS_UnmapSignal
  168118. +**
  168119. +** Unmap a signal .
  168120. +**
  168121. +** INPUT:
  168122. +**
  168123. +** gckOS Os
  168124. +** Pointer to an gckOS object.
  168125. +**
  168126. +** gctSIGNAL Signal
  168127. +** Pointer to that gctSIGNAL mapped.
  168128. +*/
  168129. +gceSTATUS
  168130. +gckOS_UnmapSignal(
  168131. + IN gckOS Os,
  168132. + IN gctSIGNAL Signal
  168133. + )
  168134. +{
  168135. + return gckOS_DestroySignal(Os, Signal);
  168136. +}
  168137. +
  168138. +/*******************************************************************************
  168139. +**
  168140. +** gckOS_CreateUserSignal
  168141. +**
  168142. +** Create a new signal to be used in the user space.
  168143. +**
  168144. +** INPUT:
  168145. +**
  168146. +** gckOS Os
  168147. +** Pointer to an gckOS object.
  168148. +**
  168149. +** gctBOOL ManualReset
  168150. +** If set to gcvTRUE, gckOS_Signal with gcvFALSE must be called in
  168151. +** order to set the signal to nonsignaled state.
  168152. +** If set to gcvFALSE, the signal will automatically be set to
  168153. +** nonsignaled state by gckOS_WaitSignal function.
  168154. +**
  168155. +** OUTPUT:
  168156. +**
  168157. +** gctINT * SignalID
  168158. +** Pointer to a variable receiving the created signal's ID.
  168159. +*/
  168160. +gceSTATUS
  168161. +gckOS_CreateUserSignal(
  168162. + IN gckOS Os,
  168163. + IN gctBOOL ManualReset,
  168164. + OUT gctINT * SignalID
  168165. + )
  168166. +{
  168167. + gceSTATUS status;
  168168. + gctSIZE_T signal;
  168169. +
  168170. + /* Create a new signal. */
  168171. + status = gckOS_CreateSignal(Os, ManualReset, (gctSIGNAL *) &signal);
  168172. + *SignalID = (gctINT) signal;
  168173. +
  168174. + return status;
  168175. +}
  168176. +
  168177. +/*******************************************************************************
  168178. +**
  168179. +** gckOS_DestroyUserSignal
  168180. +**
  168181. +** Destroy a signal to be used in the user space.
  168182. +**
  168183. +** INPUT:
  168184. +**
  168185. +** gckOS Os
  168186. +** Pointer to an gckOS object.
  168187. +**
  168188. +** gctINT SignalID
  168189. +** The signal's ID.
  168190. +**
  168191. +** OUTPUT:
  168192. +**
  168193. +** Nothing.
  168194. +*/
  168195. +gceSTATUS
  168196. +gckOS_DestroyUserSignal(
  168197. + IN gckOS Os,
  168198. + IN gctINT SignalID
  168199. + )
  168200. +{
  168201. + return gckOS_DestroySignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID);
  168202. +}
  168203. +
  168204. +/*******************************************************************************
  168205. +**
  168206. +** gckOS_WaitUserSignal
  168207. +**
  168208. +** Wait for a signal used in the user mode to become signaled.
  168209. +**
  168210. +** INPUT:
  168211. +**
  168212. +** gckOS Os
  168213. +** Pointer to an gckOS object.
  168214. +**
  168215. +** gctINT SignalID
  168216. +** Signal ID.
  168217. +**
  168218. +** gctUINT32 Wait
  168219. +** Number of milliseconds to wait.
  168220. +** Pass the value of gcvINFINITE for an infinite wait.
  168221. +**
  168222. +** OUTPUT:
  168223. +**
  168224. +** Nothing.
  168225. +*/
  168226. +gceSTATUS
  168227. +gckOS_WaitUserSignal(
  168228. + IN gckOS Os,
  168229. + IN gctINT SignalID,
  168230. + IN gctUINT32 Wait
  168231. + )
  168232. +{
  168233. + return gckOS_WaitSignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, Wait);
  168234. +}
  168235. +
  168236. +/*******************************************************************************
  168237. +**
  168238. +** gckOS_SignalUserSignal
  168239. +**
  168240. +** Set a state of the specified signal to be used in the user space.
  168241. +**
  168242. +** INPUT:
  168243. +**
  168244. +** gckOS Os
  168245. +** Pointer to an gckOS object.
  168246. +**
  168247. +** gctINT SignalID
  168248. +** SignalID.
  168249. +**
  168250. +** gctBOOL State
  168251. +** If gcvTRUE, the signal will be set to signaled state.
  168252. +** If gcvFALSE, the signal will be set to nonsignaled state.
  168253. +**
  168254. +** OUTPUT:
  168255. +**
  168256. +** Nothing.
  168257. +*/
  168258. +gceSTATUS
  168259. +gckOS_SignalUserSignal(
  168260. + IN gckOS Os,
  168261. + IN gctINT SignalID,
  168262. + IN gctBOOL State
  168263. + )
  168264. +{
  168265. + return gckOS_Signal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, State);
  168266. +}
  168267. +
  168268. +#if gcdENABLE_VG
  168269. +gceSTATUS
  168270. +gckOS_CreateSemaphoreVG(
  168271. + IN gckOS Os,
  168272. + OUT gctSEMAPHORE * Semaphore
  168273. + )
  168274. +{
  168275. + gceSTATUS status;
  168276. + struct semaphore * newSemaphore;
  168277. +
  168278. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
  168279. + /* Verify the arguments. */
  168280. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168281. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  168282. +
  168283. + do
  168284. + {
  168285. + /* Allocate the semaphore structure. */
  168286. + newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
  168287. + if (newSemaphore == gcvNULL)
  168288. + {
  168289. + gcmkERR_BREAK(gcvSTATUS_OUT_OF_MEMORY);
  168290. + }
  168291. +
  168292. + /* Initialize the semaphore. */
  168293. + sema_init(newSemaphore, 0);
  168294. +
  168295. + /* Set the handle. */
  168296. + * Semaphore = (gctSEMAPHORE) newSemaphore;
  168297. +
  168298. + /* Success. */
  168299. + status = gcvSTATUS_OK;
  168300. + }
  168301. + while (gcvFALSE);
  168302. +
  168303. + gcmkFOOTER();
  168304. + /* Return the status. */
  168305. + return status;
  168306. +}
  168307. +
  168308. +
  168309. +gceSTATUS
  168310. +gckOS_IncrementSemaphore(
  168311. + IN gckOS Os,
  168312. + IN gctSEMAPHORE Semaphore
  168313. + )
  168314. +{
  168315. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
  168316. + /* Verify the arguments. */
  168317. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168318. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  168319. +
  168320. + /* Increment the semaphore's count. */
  168321. + up((struct semaphore *) Semaphore);
  168322. +
  168323. + gcmkFOOTER_NO();
  168324. + /* Success. */
  168325. + return gcvSTATUS_OK;
  168326. +}
  168327. +
  168328. +gceSTATUS
  168329. +gckOS_DecrementSemaphore(
  168330. + IN gckOS Os,
  168331. + IN gctSEMAPHORE Semaphore
  168332. + )
  168333. +{
  168334. + gceSTATUS status;
  168335. + gctINT result;
  168336. +
  168337. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
  168338. + /* Verify the arguments. */
  168339. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168340. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  168341. +
  168342. + do
  168343. + {
  168344. + /* Decrement the semaphore's count. If the count is zero, wait
  168345. + until it gets incremented. */
  168346. + result = down_interruptible((struct semaphore *) Semaphore);
  168347. +
  168348. + /* Signal received? */
  168349. + if (result != 0)
  168350. + {
  168351. + status = gcvSTATUS_TERMINATE;
  168352. + break;
  168353. + }
  168354. +
  168355. + /* Success. */
  168356. + status = gcvSTATUS_OK;
  168357. + }
  168358. + while (gcvFALSE);
  168359. +
  168360. + gcmkFOOTER();
  168361. + /* Return the status. */
  168362. + return status;
  168363. +}
  168364. +
  168365. +/*******************************************************************************
  168366. +**
  168367. +** gckOS_SetSignal
  168368. +**
  168369. +** Set the specified signal to signaled state.
  168370. +**
  168371. +** INPUT:
  168372. +**
  168373. +** gckOS Os
  168374. +** Pointer to the gckOS object.
  168375. +**
  168376. +** gctHANDLE Process
  168377. +** Handle of process owning the signal.
  168378. +**
  168379. +** gctSIGNAL Signal
  168380. +** Pointer to the gctSIGNAL.
  168381. +**
  168382. +** OUTPUT:
  168383. +**
  168384. +** Nothing.
  168385. +*/
  168386. +gceSTATUS
  168387. +gckOS_SetSignal(
  168388. + IN gckOS Os,
  168389. + IN gctHANDLE Process,
  168390. + IN gctSIGNAL Signal
  168391. + )
  168392. +{
  168393. + gceSTATUS status;
  168394. + gctINT result;
  168395. + struct task_struct * userTask;
  168396. + struct siginfo info;
  168397. +
  168398. + userTask = FIND_TASK_BY_PID((pid_t)(gctUINTPTR_T) Process);
  168399. +
  168400. + if (userTask != gcvNULL)
  168401. + {
  168402. + info.si_signo = 48;
  168403. + info.si_code = __SI_CODE(__SI_RT, SI_KERNEL);
  168404. + info.si_pid = 0;
  168405. + info.si_uid = 0;
  168406. + info.si_ptr = (gctPOINTER) Signal;
  168407. +
  168408. + /* Signals with numbers between 32 and 63 are real-time,
  168409. + send a real-time signal to the user process. */
  168410. + result = send_sig_info(48, &info, userTask);
  168411. +
  168412. + /* Error? */
  168413. + if (result < 0)
  168414. + {
  168415. + status = gcvSTATUS_GENERIC_IO;
  168416. +
  168417. + gcmkTRACE(
  168418. + gcvLEVEL_ERROR,
  168419. + "%s(%d): an error has occurred.\n",
  168420. + __FUNCTION__, __LINE__
  168421. + );
  168422. + }
  168423. + else
  168424. + {
  168425. + status = gcvSTATUS_OK;
  168426. + }
  168427. + }
  168428. + else
  168429. + {
  168430. + status = gcvSTATUS_GENERIC_IO;
  168431. +
  168432. + gcmkTRACE(
  168433. + gcvLEVEL_ERROR,
  168434. + "%s(%d): an error has occurred.\n",
  168435. + __FUNCTION__, __LINE__
  168436. + );
  168437. + }
  168438. +
  168439. + /* Return status. */
  168440. + return status;
  168441. +}
  168442. +
  168443. +/******************************************************************************\
  168444. +******************************** Thread Object *********************************
  168445. +\******************************************************************************/
  168446. +
  168447. +gceSTATUS
  168448. +gckOS_StartThread(
  168449. + IN gckOS Os,
  168450. + IN gctTHREADFUNC ThreadFunction,
  168451. + IN gctPOINTER ThreadParameter,
  168452. + OUT gctTHREAD * Thread
  168453. + )
  168454. +{
  168455. + gceSTATUS status;
  168456. + struct task_struct * thread;
  168457. +
  168458. + gcmkHEADER_ARG("Os=0x%X ", Os);
  168459. + /* Verify the arguments. */
  168460. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168461. + gcmkVERIFY_ARGUMENT(ThreadFunction != gcvNULL);
  168462. + gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
  168463. +
  168464. + do
  168465. + {
  168466. + /* Create the thread. */
  168467. + thread = kthread_create(
  168468. + ThreadFunction,
  168469. + ThreadParameter,
  168470. + "Vivante Kernel Thread"
  168471. + );
  168472. +
  168473. + /* Failed? */
  168474. + if (IS_ERR(thread))
  168475. + {
  168476. + status = gcvSTATUS_GENERIC_IO;
  168477. + break;
  168478. + }
  168479. +
  168480. + /* Start the thread. */
  168481. + wake_up_process(thread);
  168482. +
  168483. + /* Set the thread handle. */
  168484. + * Thread = (gctTHREAD) thread;
  168485. +
  168486. + /* Success. */
  168487. + status = gcvSTATUS_OK;
  168488. + }
  168489. + while (gcvFALSE);
  168490. +
  168491. + gcmkFOOTER();
  168492. + /* Return the status. */
  168493. + return status;
  168494. +}
  168495. +
  168496. +gceSTATUS
  168497. +gckOS_StopThread(
  168498. + IN gckOS Os,
  168499. + IN gctTHREAD Thread
  168500. + )
  168501. +{
  168502. + gcmkHEADER_ARG("Os=0x%X Thread=0x%x", Os, Thread);
  168503. + /* Verify the arguments. */
  168504. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168505. + gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
  168506. +
  168507. + /* Thread should have already been enabled to terminate. */
  168508. + kthread_stop((struct task_struct *) Thread);
  168509. +
  168510. + gcmkFOOTER_NO();
  168511. + /* Success. */
  168512. + return gcvSTATUS_OK;
  168513. +}
  168514. +
  168515. +gceSTATUS
  168516. +gckOS_VerifyThread(
  168517. + IN gckOS Os,
  168518. + IN gctTHREAD Thread
  168519. + )
  168520. +{
  168521. + gcmkHEADER_ARG("Os=0x%X Thread=0x%x", Os, Thread);
  168522. + /* Verify the arguments. */
  168523. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168524. + gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
  168525. +
  168526. + gcmkFOOTER_NO();
  168527. + /* Success. */
  168528. + return gcvSTATUS_OK;
  168529. +}
  168530. +#endif
  168531. +
  168532. +/******************************************************************************\
  168533. +******************************** Software Timer ********************************
  168534. +\******************************************************************************/
  168535. +
  168536. +void
  168537. +_TimerFunction(
  168538. + struct work_struct * work
  168539. + )
  168540. +{
  168541. + gcsOSTIMER_PTR timer = (gcsOSTIMER_PTR)work;
  168542. +
  168543. + gctTIMERFUNCTION function = timer->function;
  168544. +
  168545. + function(timer->data);
  168546. +}
  168547. +
  168548. +/*******************************************************************************
  168549. +**
  168550. +** gckOS_CreateTimer
  168551. +**
  168552. +** Create a software timer.
  168553. +**
  168554. +** INPUT:
  168555. +**
  168556. +** gckOS Os
  168557. +** Pointer to the gckOS object.
  168558. +**
  168559. +** gctTIMERFUNCTION Function.
  168560. +** Pointer to a call back function which will be called when timer is
  168561. +** expired.
  168562. +**
  168563. +** gctPOINTER Data.
  168564. +** Private data which will be passed to call back function.
  168565. +**
  168566. +** OUTPUT:
  168567. +**
  168568. +** gctPOINTER * Timer
  168569. +** Pointer to a variable receiving the created timer.
  168570. +*/
  168571. +gceSTATUS
  168572. +gckOS_CreateTimer(
  168573. + IN gckOS Os,
  168574. + IN gctTIMERFUNCTION Function,
  168575. + IN gctPOINTER Data,
  168576. + OUT gctPOINTER * Timer
  168577. + )
  168578. +{
  168579. + gceSTATUS status;
  168580. + gcsOSTIMER_PTR pointer;
  168581. + gcmkHEADER_ARG("Os=0x%X Function=0x%X Data=0x%X", Os, Function, Data);
  168582. +
  168583. + /* Verify the arguments. */
  168584. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168585. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  168586. +
  168587. + gcmkONERROR(gckOS_Allocate(Os, sizeof(gcsOSTIMER), (gctPOINTER)&pointer));
  168588. +
  168589. + pointer->function = Function;
  168590. + pointer->data = Data;
  168591. +
  168592. + INIT_DELAYED_WORK(&pointer->work, _TimerFunction);
  168593. +
  168594. + *Timer = pointer;
  168595. +
  168596. + gcmkFOOTER_NO();
  168597. + return gcvSTATUS_OK;
  168598. +
  168599. +OnError:
  168600. + gcmkFOOTER();
  168601. + return status;
  168602. +}
  168603. +
  168604. +/*******************************************************************************
  168605. +**
  168606. +** gckOS_DestroyTimer
  168607. +**
  168608. +** Destory a software timer.
  168609. +**
  168610. +** INPUT:
  168611. +**
  168612. +** gckOS Os
  168613. +** Pointer to the gckOS object.
  168614. +**
  168615. +** gctPOINTER Timer
  168616. +** Pointer to the timer to be destoryed.
  168617. +**
  168618. +** OUTPUT:
  168619. +**
  168620. +** Nothing.
  168621. +*/
  168622. +gceSTATUS
  168623. +gckOS_DestroyTimer(
  168624. + IN gckOS Os,
  168625. + IN gctPOINTER Timer
  168626. + )
  168627. +{
  168628. + gcsOSTIMER_PTR timer;
  168629. + gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
  168630. +
  168631. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168632. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  168633. +
  168634. + timer = (gcsOSTIMER_PTR)Timer;
  168635. +
  168636. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
  168637. + cancel_delayed_work_sync(&timer->work);
  168638. +#else
  168639. + cancel_delayed_work(&timer->work);
  168640. + flush_workqueue(Os->workqueue);
  168641. +#endif
  168642. +
  168643. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, Timer));
  168644. +
  168645. + gcmkFOOTER_NO();
  168646. + return gcvSTATUS_OK;
  168647. +}
  168648. +
  168649. +/*******************************************************************************
  168650. +**
  168651. +** gckOS_StartTimer
  168652. +**
  168653. +** Schedule a software timer.
  168654. +**
  168655. +** INPUT:
  168656. +**
  168657. +** gckOS Os
  168658. +** Pointer to the gckOS object.
  168659. +**
  168660. +** gctPOINTER Timer
  168661. +** Pointer to the timer to be scheduled.
  168662. +**
  168663. +** gctUINT32 Delay
  168664. +** Delay in milliseconds.
  168665. +**
  168666. +** OUTPUT:
  168667. +**
  168668. +** Nothing.
  168669. +*/
  168670. +gceSTATUS
  168671. +gckOS_StartTimer(
  168672. + IN gckOS Os,
  168673. + IN gctPOINTER Timer,
  168674. + IN gctUINT32 Delay
  168675. + )
  168676. +{
  168677. + gcsOSTIMER_PTR timer;
  168678. +
  168679. + gcmkHEADER_ARG("Os=0x%X Timer=0x%X Delay=%u", Os, Timer, Delay);
  168680. +
  168681. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168682. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  168683. + gcmkVERIFY_ARGUMENT(Delay != 0);
  168684. +
  168685. + timer = (gcsOSTIMER_PTR)Timer;
  168686. +
  168687. + if (unlikely(delayed_work_pending(&timer->work)))
  168688. + {
  168689. + if (unlikely(!cancel_delayed_work(&timer->work)))
  168690. + {
  168691. + cancel_work_sync(&timer->work.work);
  168692. +
  168693. + if (unlikely(delayed_work_pending(&timer->work)))
  168694. + {
  168695. + gckOS_Print("gckOS_StartTimer error, the pending worker cannot complete!!!! \n");
  168696. +
  168697. + return gcvSTATUS_INVALID_REQUEST;
  168698. + }
  168699. + }
  168700. + }
  168701. +
  168702. + queue_delayed_work(Os->workqueue, &timer->work, msecs_to_jiffies(Delay));
  168703. +
  168704. + gcmkFOOTER_NO();
  168705. + return gcvSTATUS_OK;
  168706. +}
  168707. +
  168708. +/*******************************************************************************
  168709. +**
  168710. +** gckOS_StopTimer
  168711. +**
  168712. +** Cancel a unscheduled timer.
  168713. +**
  168714. +** INPUT:
  168715. +**
  168716. +** gckOS Os
  168717. +** Pointer to the gckOS object.
  168718. +**
  168719. +** gctPOINTER Timer
  168720. +** Pointer to the timer to be cancel.
  168721. +**
  168722. +** OUTPUT:
  168723. +**
  168724. +** Nothing.
  168725. +*/
  168726. +gceSTATUS
  168727. +gckOS_StopTimer(
  168728. + IN gckOS Os,
  168729. + IN gctPOINTER Timer
  168730. + )
  168731. +{
  168732. + gcsOSTIMER_PTR timer;
  168733. + gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
  168734. +
  168735. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168736. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  168737. +
  168738. + timer = (gcsOSTIMER_PTR)Timer;
  168739. +
  168740. + cancel_delayed_work(&timer->work);
  168741. +
  168742. + gcmkFOOTER_NO();
  168743. + return gcvSTATUS_OK;
  168744. +}
  168745. +
  168746. +
  168747. +gceSTATUS
  168748. +gckOS_DumpCallStack(
  168749. + IN gckOS Os
  168750. + )
  168751. +{
  168752. + gcmkHEADER_ARG("Os=0x%X", Os);
  168753. +
  168754. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168755. +
  168756. + dump_stack();
  168757. +
  168758. + gcmkFOOTER_NO();
  168759. + return gcvSTATUS_OK;
  168760. +}
  168761. +
  168762. +
  168763. +gceSTATUS
  168764. +gckOS_GetProcessNameByPid(
  168765. + IN gctINT Pid,
  168766. + IN gctSIZE_T Length,
  168767. + OUT gctUINT8_PTR String
  168768. + )
  168769. +{
  168770. + struct task_struct *task;
  168771. +
  168772. + /* Get the task_struct of the task with pid. */
  168773. + rcu_read_lock();
  168774. +
  168775. + task = FIND_TASK_BY_PID(Pid);
  168776. +
  168777. + if (task == gcvNULL)
  168778. + {
  168779. + rcu_read_unlock();
  168780. + return gcvSTATUS_NOT_FOUND;
  168781. + }
  168782. +
  168783. + /* Get name of process. */
  168784. + strncpy(String, task->comm, Length);
  168785. +
  168786. + rcu_read_unlock();
  168787. +
  168788. + return gcvSTATUS_OK;
  168789. +}
  168790. +
  168791. +#if gcdANDROID_NATIVE_FENCE_SYNC
  168792. +
  168793. +gceSTATUS
  168794. +gckOS_CreateSyncPoint(
  168795. + IN gckOS Os,
  168796. + OUT gctSYNC_POINT * SyncPoint
  168797. + )
  168798. +{
  168799. + gceSTATUS status;
  168800. + gcsSYNC_POINT_PTR syncPoint;
  168801. +
  168802. + gcmkHEADER_ARG("Os=0x%X", Os);
  168803. +
  168804. + /* Verify the arguments. */
  168805. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168806. +
  168807. + /* Create an sync point structure. */
  168808. + syncPoint = (gcsSYNC_POINT_PTR) kmalloc(
  168809. + sizeof(gcsSYNC_POINT), GFP_KERNEL | gcdNOWARN);
  168810. +
  168811. + if (syncPoint == gcvNULL)
  168812. + {
  168813. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  168814. + }
  168815. +
  168816. + /* Initialize the sync point. */
  168817. + atomic_set(&syncPoint->ref, 1);
  168818. + atomic_set(&syncPoint->state, 0);
  168819. +
  168820. + gcmkONERROR(_AllocateIntegerId(&Os->syncPointDB, syncPoint, &syncPoint->id));
  168821. +
  168822. + *SyncPoint = (gctSYNC_POINT)(gctUINTPTR_T)syncPoint->id;
  168823. +
  168824. + gcmkFOOTER_ARG("*SyncPonint=%d", syncPoint->id);
  168825. + return gcvSTATUS_OK;
  168826. +
  168827. +OnError:
  168828. + if (syncPoint != gcvNULL)
  168829. + {
  168830. + kfree(syncPoint);
  168831. + }
  168832. +
  168833. + gcmkFOOTER();
  168834. + return status;
  168835. +}
  168836. +
  168837. +gceSTATUS
  168838. +gckOS_ReferenceSyncPoint(
  168839. + IN gckOS Os,
  168840. + IN gctSYNC_POINT SyncPoint
  168841. + )
  168842. +{
  168843. + gceSTATUS status;
  168844. + gcsSYNC_POINT_PTR syncPoint;
  168845. +
  168846. + gcmkHEADER_ARG("Os=0x%X", Os);
  168847. +
  168848. + /* Verify the arguments. */
  168849. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168850. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  168851. +
  168852. + gcmkONERROR(
  168853. + _QueryIntegerId(&Os->syncPointDB,
  168854. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  168855. + (gctPOINTER)&syncPoint));
  168856. +
  168857. + /* Initialize the sync point. */
  168858. + atomic_inc(&syncPoint->ref);
  168859. +
  168860. + gcmkFOOTER_NO();
  168861. + return gcvSTATUS_OK;
  168862. +
  168863. +OnError:
  168864. + gcmkFOOTER();
  168865. + return status;
  168866. +}
  168867. +
  168868. +gceSTATUS
  168869. +gckOS_DestroySyncPoint(
  168870. + IN gckOS Os,
  168871. + IN gctSYNC_POINT SyncPoint
  168872. + )
  168873. +{
  168874. + gceSTATUS status;
  168875. + gcsSYNC_POINT_PTR syncPoint;
  168876. + gctBOOL acquired = gcvFALSE;
  168877. +
  168878. + gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168879. +
  168880. + /* Verify the arguments. */
  168881. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168882. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  168883. +
  168884. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->syncPointMutex, gcvINFINITE));
  168885. + acquired = gcvTRUE;
  168886. +
  168887. + gcmkONERROR(
  168888. + _QueryIntegerId(&Os->syncPointDB,
  168889. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  168890. + (gctPOINTER)&syncPoint));
  168891. +
  168892. + gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168893. +
  168894. + if (atomic_dec_and_test(&syncPoint->ref))
  168895. + {
  168896. + gcmkVERIFY_OK(_DestroyIntegerId(&Os->syncPointDB, syncPoint->id));
  168897. +
  168898. + /* Free the sgianl. */
  168899. + syncPoint->timeline = gcvNULL;
  168900. + kfree(syncPoint);
  168901. + }
  168902. +
  168903. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  168904. + acquired = gcvFALSE;
  168905. +
  168906. + /* Success. */
  168907. + gcmkFOOTER_NO();
  168908. + return gcvSTATUS_OK;
  168909. +
  168910. +OnError:
  168911. + if (acquired)
  168912. + {
  168913. + /* Release the mutex. */
  168914. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  168915. + }
  168916. +
  168917. + gcmkFOOTER();
  168918. + return status;
  168919. +}
  168920. +
  168921. +gceSTATUS
  168922. +gckOS_SignalSyncPoint(
  168923. + IN gckOS Os,
  168924. + IN gctSYNC_POINT SyncPoint
  168925. + )
  168926. +{
  168927. + gceSTATUS status;
  168928. + gcsSYNC_POINT_PTR syncPoint;
  168929. + gctBOOL acquired = gcvFALSE;
  168930. +
  168931. + gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168932. +
  168933. + /* Verify the arguments. */
  168934. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168935. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  168936. +
  168937. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->syncPointMutex, gcvINFINITE));
  168938. + acquired = gcvTRUE;
  168939. +
  168940. + gcmkONERROR(
  168941. + _QueryIntegerId(&Os->syncPointDB,
  168942. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  168943. + (gctPOINTER)&syncPoint));
  168944. +
  168945. + gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168946. +
  168947. + /* Get state. */
  168948. + atomic_set(&syncPoint->state, gcvTRUE);
  168949. +
  168950. + /* Signal timeline. */
  168951. + if (syncPoint->timeline)
  168952. + {
  168953. + sync_timeline_signal(syncPoint->timeline);
  168954. + }
  168955. +
  168956. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  168957. + acquired = gcvFALSE;
  168958. +
  168959. + /* Success. */
  168960. + gcmkFOOTER_NO();
  168961. + return gcvSTATUS_OK;
  168962. +
  168963. +OnError:
  168964. + if (acquired)
  168965. + {
  168966. + /* Release the mutex. */
  168967. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  168968. + }
  168969. +
  168970. + gcmkFOOTER();
  168971. + return status;
  168972. +}
  168973. +
  168974. +gceSTATUS
  168975. +gckOS_QuerySyncPoint(
  168976. + IN gckOS Os,
  168977. + IN gctSYNC_POINT SyncPoint,
  168978. + OUT gctBOOL_PTR State
  168979. + )
  168980. +{
  168981. + gceSTATUS status;
  168982. + gcsSYNC_POINT_PTR syncPoint;
  168983. +
  168984. + gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168985. +
  168986. + /* Verify the arguments. */
  168987. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168988. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  168989. +
  168990. + gcmkONERROR(
  168991. + _QueryIntegerId(&Os->syncPointDB,
  168992. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  168993. + (gctPOINTER)&syncPoint));
  168994. +
  168995. + gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168996. +
  168997. + /* Get state. */
  168998. + *State = atomic_read(&syncPoint->state);
  168999. +
  169000. + /* Success. */
  169001. + gcmkFOOTER_ARG("*State=%d", *State);
  169002. + return gcvSTATUS_OK;
  169003. +
  169004. +OnError:
  169005. + gcmkFOOTER();
  169006. + return status;
  169007. +}
  169008. +
  169009. +gceSTATUS
  169010. +gckOS_CreateSyncTimeline(
  169011. + IN gckOS Os,
  169012. + OUT gctHANDLE * Timeline
  169013. + )
  169014. +{
  169015. + struct viv_sync_timeline * timeline;
  169016. +
  169017. + /* Create viv sync timeline. */
  169018. + timeline = viv_sync_timeline_create("viv timeline", Os);
  169019. +
  169020. + if (timeline == gcvNULL)
  169021. + {
  169022. + /* Out of memory. */
  169023. + return gcvSTATUS_OUT_OF_MEMORY;
  169024. + }
  169025. +
  169026. + *Timeline = (gctHANDLE) timeline;
  169027. + return gcvSTATUS_OK;
  169028. +}
  169029. +
  169030. +gceSTATUS
  169031. +gckOS_DestroySyncTimeline(
  169032. + IN gckOS Os,
  169033. + IN gctHANDLE Timeline
  169034. + )
  169035. +{
  169036. + struct viv_sync_timeline * timeline;
  169037. + gcmkASSERT(Timeline != gcvNULL);
  169038. +
  169039. + /* Destroy timeline. */
  169040. + timeline = (struct viv_sync_timeline *) Timeline;
  169041. + sync_timeline_destroy(&timeline->obj);
  169042. +
  169043. + return gcvSTATUS_OK;
  169044. +}
  169045. +
  169046. +gceSTATUS
  169047. +gckOS_CreateNativeFence(
  169048. + IN gckOS Os,
  169049. + IN gctHANDLE Timeline,
  169050. + IN gctSYNC_POINT SyncPoint,
  169051. + OUT gctINT * FenceFD
  169052. + )
  169053. +{
  169054. + int fd = -1;
  169055. + struct viv_sync_timeline *timeline;
  169056. + struct sync_pt * pt = gcvNULL;
  169057. + struct sync_fence * fence;
  169058. + char name[32];
  169059. + gcsSYNC_POINT_PTR syncPoint;
  169060. + gceSTATUS status;
  169061. +
  169062. + gcmkHEADER_ARG("Os=0x%X Timeline=0x%X SyncPoint=%d",
  169063. + Os, Timeline, (gctUINT)(gctUINTPTR_T)SyncPoint);
  169064. +
  169065. + gcmkONERROR(
  169066. + _QueryIntegerId(&Os->syncPointDB,
  169067. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  169068. + (gctPOINTER)&syncPoint));
  169069. +
  169070. + /* Cast timeline. */
  169071. + timeline = (struct viv_sync_timeline *) Timeline;
  169072. +
  169073. + fd = get_unused_fd();
  169074. +
  169075. + if (fd < 0)
  169076. + {
  169077. + /* Out of resources. */
  169078. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  169079. + }
  169080. +
  169081. + /* Create viv_sync_pt. */
  169082. + pt = viv_sync_pt_create(timeline, SyncPoint);
  169083. +
  169084. + if (pt == gcvNULL)
  169085. + {
  169086. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  169087. + }
  169088. +
  169089. + /* Reference sync_timeline. */
  169090. + syncPoint->timeline = &timeline->obj;
  169091. +
  169092. + /* Build fence name. */
  169093. + snprintf(name, 32, "viv sync_fence-%u", (gctUINT)(gctUINTPTR_T)SyncPoint);
  169094. +
  169095. + /* Create sync_fence. */
  169096. + fence = sync_fence_create(name, pt);
  169097. +
  169098. + if (fence == NULL)
  169099. + {
  169100. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  169101. + }
  169102. +
  169103. + /* Install fence to fd. */
  169104. + sync_fence_install(fence, fd);
  169105. +
  169106. + *FenceFD = fd;
  169107. + gcmkFOOTER_ARG("*FenceFD=%d", fd);
  169108. + return gcvSTATUS_OK;
  169109. +
  169110. +OnError:
  169111. + /* Error roll back. */
  169112. + if (pt)
  169113. + {
  169114. + sync_pt_free(pt);
  169115. + }
  169116. +
  169117. + if (fd > 0)
  169118. + {
  169119. + put_unused_fd(fd);
  169120. + }
  169121. +
  169122. + gcmkFOOTER();
  169123. + return status;
  169124. +}
  169125. +#endif
  169126. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
  169127. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h 1970-01-01 01:00:00.000000000 +0100
  169128. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h 2014-08-20 19:31:46.136869040 +0200
  169129. @@ -0,0 +1,83 @@
  169130. +/****************************************************************************
  169131. +*
  169132. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  169133. +*
  169134. +* This program is free software; you can redistribute it and/or modify
  169135. +* it under the terms of the GNU General Public License as published by
  169136. +* the Free Software Foundation; either version 2 of the license, or
  169137. +* (at your option) any later version.
  169138. +*
  169139. +* This program is distributed in the hope that it will be useful,
  169140. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  169141. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  169142. +* GNU General Public License for more details.
  169143. +*
  169144. +* You should have received a copy of the GNU General Public License
  169145. +* along with this program; if not write to the Free Software
  169146. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  169147. +*
  169148. +*****************************************************************************/
  169149. +
  169150. +
  169151. +#ifndef __gc_hal_kernel_os_h_
  169152. +#define __gc_hal_kernel_os_h_
  169153. +
  169154. +typedef struct _LINUX_MDL_MAP
  169155. +{
  169156. + gctINT pid;
  169157. + gctPOINTER vmaAddr;
  169158. + gctUINT32 count;
  169159. + struct vm_area_struct * vma;
  169160. + struct _LINUX_MDL_MAP * next;
  169161. +}
  169162. +LINUX_MDL_MAP;
  169163. +
  169164. +typedef struct _LINUX_MDL_MAP * PLINUX_MDL_MAP;
  169165. +
  169166. +typedef struct _LINUX_MDL
  169167. +{
  169168. + gctINT pid;
  169169. + char * addr;
  169170. +
  169171. + union _pages
  169172. + {
  169173. + /* Pointer to a array of pages. */
  169174. + struct page * contiguousPages;
  169175. + /* Pointer to a array of pointers to page. */
  169176. + struct page ** nonContiguousPages;
  169177. + }
  169178. + u;
  169179. +
  169180. +#ifdef NO_DMA_COHERENT
  169181. + gctPOINTER kaddr;
  169182. +#endif /* NO_DMA_COHERENT */
  169183. +
  169184. + gctINT numPages;
  169185. + gctINT pagedMem;
  169186. + gctBOOL contiguous;
  169187. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  169188. + gctBOOL exact;
  169189. +#endif
  169190. + dma_addr_t dmaHandle;
  169191. + PLINUX_MDL_MAP maps;
  169192. + struct _LINUX_MDL * prev;
  169193. + struct _LINUX_MDL * next;
  169194. +}
  169195. +LINUX_MDL, *PLINUX_MDL;
  169196. +
  169197. +extern PLINUX_MDL_MAP
  169198. +FindMdlMap(
  169199. + IN PLINUX_MDL Mdl,
  169200. + IN gctINT PID
  169201. + );
  169202. +
  169203. +typedef struct _DRIVER_ARGS
  169204. +{
  169205. + gctUINT64 InputBuffer;
  169206. + gctUINT64 InputBufferSize;
  169207. + gctUINT64 OutputBuffer;
  169208. + gctUINT64 OutputBufferSize;
  169209. +}
  169210. +DRIVER_ARGS;
  169211. +
  169212. +#endif /* __gc_hal_kernel_os_h_ */
  169213. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
  169214. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c 1970-01-01 01:00:00.000000000 +0100
  169215. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c 2014-08-20 19:23:53.574845907 +0200
  169216. @@ -0,0 +1,174 @@
  169217. +/****************************************************************************
  169218. +*
  169219. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  169220. +*
  169221. +* This program is free software; you can redistribute it and/or modify
  169222. +* it under the terms of the GNU General Public License as published by
  169223. +* the Free Software Foundation; either version 2 of the license, or
  169224. +* (at your option) any later version.
  169225. +*
  169226. +* This program is distributed in the hope that it will be useful,
  169227. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  169228. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  169229. +* GNU General Public License for more details.
  169230. +*
  169231. +* You should have received a copy of the GNU General Public License
  169232. +* along with this program; if not write to the Free Software
  169233. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  169234. +*
  169235. +*****************************************************************************/
  169236. +
  169237. +
  169238. +#include <linux/kernel.h>
  169239. +#include <linux/file.h>
  169240. +#include <linux/fs.h>
  169241. +#include <linux/miscdevice.h>
  169242. +#include <linux/module.h>
  169243. +#include <linux/syscalls.h>
  169244. +#include <linux/uaccess.h>
  169245. +
  169246. +#include "gc_hal_kernel_sync.h"
  169247. +
  169248. +#if gcdANDROID_NATIVE_FENCE_SYNC
  169249. +
  169250. +static struct sync_pt *
  169251. +viv_sync_pt_dup(
  169252. + struct sync_pt * sync_pt
  169253. + )
  169254. +{
  169255. + gceSTATUS status;
  169256. + struct viv_sync_pt *pt;
  169257. + struct viv_sync_pt *src;
  169258. + struct viv_sync_timeline *obj;
  169259. +
  169260. + src = (struct viv_sync_pt *) sync_pt;
  169261. + obj = (struct viv_sync_timeline *) sync_pt->parent;
  169262. +
  169263. + /* Create the new sync_pt. */
  169264. + pt = (struct viv_sync_pt *)
  169265. + sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt));
  169266. +
  169267. + pt->stamp = src->stamp;
  169268. + pt->sync = src->sync;
  169269. +
  169270. + /* Reference sync point. */
  169271. + status = gckOS_ReferenceSyncPoint(obj->os, pt->sync);
  169272. +
  169273. + if (gcmIS_ERROR(status))
  169274. + {
  169275. + sync_pt_free((struct sync_pt *)pt);
  169276. + return NULL;
  169277. + }
  169278. +
  169279. + return (struct sync_pt *)pt;
  169280. +}
  169281. +
  169282. +static int
  169283. +viv_sync_pt_has_signaled(
  169284. + struct sync_pt * sync_pt
  169285. + )
  169286. +{
  169287. + gceSTATUS status;
  169288. + gctBOOL state;
  169289. + struct viv_sync_pt * pt;
  169290. + struct viv_sync_timeline * obj;
  169291. +
  169292. + pt = (struct viv_sync_pt *)sync_pt;
  169293. + obj = (struct viv_sync_timeline *)sync_pt->parent;
  169294. +
  169295. + status = gckOS_QuerySyncPoint(obj->os, pt->sync, &state);
  169296. +
  169297. + if (gcmIS_ERROR(status))
  169298. + {
  169299. + /* Error. */
  169300. + return -1;
  169301. + }
  169302. +
  169303. + return state;
  169304. +}
  169305. +
  169306. +static int
  169307. +viv_sync_pt_compare(
  169308. + struct sync_pt * a,
  169309. + struct sync_pt * b
  169310. + )
  169311. +{
  169312. + int ret;
  169313. + struct viv_sync_pt * pt1 = (struct viv_sync_pt *) a;
  169314. + struct viv_sync_pt * pt2 = (struct viv_sync_pt *) b;
  169315. +
  169316. + ret = (pt1->stamp < pt2->stamp) ? -1
  169317. + : (pt1->stamp == pt2->stamp) ? 0
  169318. + : 1;
  169319. +
  169320. + return ret;
  169321. +}
  169322. +
  169323. +static void
  169324. +viv_sync_pt_free(
  169325. + struct sync_pt * sync_pt
  169326. + )
  169327. +{
  169328. + struct viv_sync_pt * pt;
  169329. + struct viv_sync_timeline * obj;
  169330. +
  169331. + pt = (struct viv_sync_pt *) sync_pt;
  169332. + obj = (struct viv_sync_timeline *) sync_pt->parent;
  169333. +
  169334. + gckOS_DestroySyncPoint(obj->os, pt->sync);
  169335. +}
  169336. +
  169337. +static struct sync_timeline_ops viv_timeline_ops =
  169338. +{
  169339. + .driver_name = "viv_sync",
  169340. + .dup = viv_sync_pt_dup,
  169341. + .has_signaled = viv_sync_pt_has_signaled,
  169342. + .compare = viv_sync_pt_compare,
  169343. + .free_pt = viv_sync_pt_free,
  169344. +};
  169345. +
  169346. +struct viv_sync_timeline *
  169347. +viv_sync_timeline_create(
  169348. + const char * name,
  169349. + gckOS os
  169350. + )
  169351. +{
  169352. + struct viv_sync_timeline * obj;
  169353. +
  169354. + obj = (struct viv_sync_timeline *)
  169355. + sync_timeline_create(&viv_timeline_ops, sizeof(struct viv_sync_timeline), name);
  169356. +
  169357. + obj->os = os;
  169358. + obj->stamp = 0;
  169359. +
  169360. + return obj;
  169361. +}
  169362. +
  169363. +struct sync_pt *
  169364. +viv_sync_pt_create(
  169365. + struct viv_sync_timeline * obj,
  169366. + gctSYNC_POINT SyncPoint
  169367. + )
  169368. +{
  169369. + gceSTATUS status;
  169370. + struct viv_sync_pt * pt;
  169371. +
  169372. + pt = (struct viv_sync_pt *)
  169373. + sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt));
  169374. +
  169375. + pt->stamp = obj->stamp++;
  169376. + pt->sync = SyncPoint;
  169377. +
  169378. + /* Dup signal. */
  169379. + status = gckOS_ReferenceSyncPoint(obj->os, SyncPoint);
  169380. +
  169381. + if (gcmIS_ERROR(status))
  169382. + {
  169383. + sync_pt_free((struct sync_pt *)pt);
  169384. + return NULL;
  169385. + }
  169386. +
  169387. + return (struct sync_pt *) pt;
  169388. +}
  169389. +
  169390. +#endif
  169391. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h
  169392. --- linux-3.14.15/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h 1970-01-01 01:00:00.000000000 +0100
  169393. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h 2014-08-20 19:23:53.574845907 +0200
  169394. @@ -0,0 +1,71 @@
  169395. +/****************************************************************************
  169396. +*
  169397. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  169398. +*
  169399. +* This program is free software; you can redistribute it and/or modify
  169400. +* it under the terms of the GNU General Public License as published by
  169401. +* the Free Software Foundation; either version 2 of the license, or
  169402. +* (at your option) any later version.
  169403. +*
  169404. +* This program is distributed in the hope that it will be useful,
  169405. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  169406. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  169407. +* GNU General Public License for more details.
  169408. +*
  169409. +* You should have received a copy of the GNU General Public License
  169410. +* along with this program; if not write to the Free Software
  169411. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  169412. +*
  169413. +*****************************************************************************/
  169414. +
  169415. +
  169416. +#ifndef __gc_hal_kernel_sync_h_
  169417. +#define __gc_hal_kernel_sync_h_
  169418. +
  169419. +#include <linux/types.h>
  169420. +
  169421. +#include <linux/sync.h>
  169422. +
  169423. +#include <gc_hal.h>
  169424. +#include <gc_hal_base.h>
  169425. +
  169426. +struct viv_sync_timeline
  169427. +{
  169428. + /* Parent object. */
  169429. + struct sync_timeline obj;
  169430. +
  169431. + /* Timestamp when sync_pt is created. */
  169432. + gctUINT stamp;
  169433. +
  169434. + /* Pointer to os struct. */
  169435. + gckOS os;
  169436. +};
  169437. +
  169438. +
  169439. +struct viv_sync_pt
  169440. +{
  169441. + /* Parent object. */
  169442. + struct sync_pt pt;
  169443. +
  169444. + /* Reference sync point*/
  169445. + gctSYNC_POINT sync;
  169446. +
  169447. + /* Timestamp when sync_pt is created. */
  169448. + gctUINT stamp;
  169449. +};
  169450. +
  169451. +/* Create viv_sync_timeline object. */
  169452. +struct viv_sync_timeline *
  169453. +viv_sync_timeline_create(
  169454. + const char * Name,
  169455. + gckOS Os
  169456. + );
  169457. +
  169458. +/* Create viv_sync_pt object. */
  169459. +struct sync_pt *
  169460. +viv_sync_pt_create(
  169461. + struct viv_sync_timeline * Obj,
  169462. + gctSYNC_POINT SyncPoint
  169463. + );
  169464. +
  169465. +#endif /* __gc_hal_kernel_sync_h_ */
  169466. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/Kbuild linux-linaro-stable-mx6/drivers/mxc/gpu-viv/Kbuild
  169467. --- linux-3.14.15/drivers/mxc/gpu-viv/Kbuild 1970-01-01 01:00:00.000000000 +0100
  169468. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/Kbuild 2014-08-20 19:31:46.068868748 +0200
  169469. @@ -0,0 +1,236 @@
  169470. +##############################################################################
  169471. +#
  169472. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  169473. +#
  169474. +# This program is free software; you can redistribute it and/or modify
  169475. +# it under the terms of the GNU General Public License as published by
  169476. +# the Free Software Foundation; either version 2 of the license, or
  169477. +# (at your option) any later version.
  169478. +#
  169479. +# This program is distributed in the hope that it will be useful,
  169480. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  169481. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  169482. +# GNU General Public License for more details.
  169483. +#
  169484. +# You should have received a copy of the GNU General Public License
  169485. +# along with this program; if not write to the Free Software
  169486. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  169487. +#
  169488. +##############################################################################
  169489. +
  169490. +
  169491. +#
  169492. +# Linux build file for kernel HAL driver.
  169493. +#
  169494. +
  169495. +AQROOT := $(srctree)/drivers/mxc/gpu-viv
  169496. +AQARCH := $(AQROOT)/arch/XAQ2
  169497. +AQVGARCH := $(AQROOT)/arch/GC350
  169498. +
  169499. +include $(AQROOT)/config
  169500. +
  169501. +KERNEL_DIR ?= $(TOOL_DIR)/kernel
  169502. +
  169503. +OS_KERNEL_DIR := hal/os/linux/kernel
  169504. +ARCH_KERNEL_DIR := arch/$(notdir $(AQARCH))/hal/kernel
  169505. +ARCH_VG_KERNEL_DIR := arch/$(notdir $(AQVGARCH))/hal/kernel
  169506. +HAL_KERNEL_DIR := hal/kernel
  169507. +
  169508. +# EXTRA_CFLAGS += -Werror
  169509. +
  169510. +OBJS := $(OS_KERNEL_DIR)/gc_hal_kernel_device.o \
  169511. + $(OS_KERNEL_DIR)/gc_hal_kernel_driver.o \
  169512. + $(OS_KERNEL_DIR)/gc_hal_kernel_linux.o \
  169513. + $(OS_KERNEL_DIR)/gc_hal_kernel_math.o \
  169514. + $(OS_KERNEL_DIR)/gc_hal_kernel_os.o \
  169515. + $(OS_KERNEL_DIR)/gc_hal_kernel_debugfs.o
  169516. +
  169517. +OBJS += $(HAL_KERNEL_DIR)/gc_hal_kernel.o \
  169518. + $(HAL_KERNEL_DIR)/gc_hal_kernel_command.o \
  169519. + $(HAL_KERNEL_DIR)/gc_hal_kernel_db.o \
  169520. + $(HAL_KERNEL_DIR)/gc_hal_kernel_debug.o \
  169521. + $(HAL_KERNEL_DIR)/gc_hal_kernel_event.o \
  169522. + $(HAL_KERNEL_DIR)/gc_hal_kernel_heap.o \
  169523. + $(HAL_KERNEL_DIR)/gc_hal_kernel_mmu.o \
  169524. + $(HAL_KERNEL_DIR)/gc_hal_kernel_video_memory.o \
  169525. + $(HAL_KERNEL_DIR)/gc_hal_kernel_power.o
  169526. +
  169527. +OBJS += $(ARCH_KERNEL_DIR)/gc_hal_kernel_context.o \
  169528. + $(ARCH_KERNEL_DIR)/gc_hal_kernel_hardware.o
  169529. +
  169530. +ifeq ($(VIVANTE_ENABLE_VG), 1)
  169531. +OBJS +=\
  169532. + $(HAL_KERNEL_DIR)/gc_hal_kernel_vg.o\
  169533. + $(HAL_KERNEL_DIR)/gc_hal_kernel_command_vg.o\
  169534. + $(HAL_KERNEL_DIR)/gc_hal_kernel_interrupt_vg.o\
  169535. + $(HAL_KERNEL_DIR)/gc_hal_kernel_mmu_vg.o\
  169536. + $(ARCH_VG_KERNEL_DIR)/gc_hal_kernel_hardware_command_vg.o\
  169537. + $(ARCH_VG_KERNEL_DIR)/gc_hal_kernel_hardware_vg.o
  169538. +endif
  169539. +
  169540. +ifneq ($(CONFIG_SYNC),)
  169541. +OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_sync.o
  169542. +endif
  169543. +
  169544. +ifeq ($(KERNELRELEASE), )
  169545. +
  169546. +.PHONY: all clean install
  169547. +
  169548. +# Define targets.
  169549. +all:
  169550. + @make V=$(V) ARCH=$(ARCH_TYPE) -C $(KERNEL_DIR) SUBDIRS=`pwd` modules
  169551. +
  169552. +clean:
  169553. + @rm -rf $(OBJS)
  169554. + @rm -rf modules.order Module.symvers
  169555. + @find $(AQROOT) -name ".gc_*.cmd" | xargs rm -f
  169556. +
  169557. +install: all
  169558. + @mkdir -p $(SDK_DIR)/drivers
  169559. +
  169560. +else
  169561. +
  169562. +
  169563. +EXTRA_CFLAGS += -DLINUX -DDRIVER
  169564. +
  169565. +ifeq ($(ENUM_WORKAROUND), 1)
  169566. +EXTRA_CFLAGS += -DENUM_WORKAROUND=1
  169567. +else
  169568. +EXTRA_CFLAGS += -DENUM_WORKAROUND=0
  169569. +endif
  169570. +
  169571. +ifeq ($(FLAREON),1)
  169572. +EXTRA_CFLAGS += -DFLAREON
  169573. +endif
  169574. +
  169575. +ifeq ($(DEBUG), 1)
  169576. +EXTRA_CFLAGS += -DDBG=1 -DDEBUG -D_DEBUG
  169577. +else
  169578. +EXTRA_CFLAGS += -DDBG=0
  169579. +endif
  169580. +
  169581. +ifeq ($(NO_DMA_COHERENT), 1)
  169582. +EXTRA_CFLAGS += -DNO_DMA_COHERENT
  169583. +endif
  169584. +
  169585. +ifeq ($(CONFIG_DOVE_GPU), 1)
  169586. +EXTRA_CFLAGS += -DCONFIG_DOVE_GPU=1
  169587. +endif
  169588. +
  169589. +ifneq ($(USE_PLATFORM_DRIVER), 0)
  169590. +EXTRA_CFLAGS += -DUSE_PLATFORM_DRIVER=1
  169591. +else
  169592. +EXTRA_CFLAGS += -DUSE_PLATFORM_DRIVER=0
  169593. +endif
  169594. +
  169595. +
  169596. +EXTRA_CFLAGS += -DVIVANTE_PROFILER=1
  169597. +EXTRA_CFLAGS += -DVIVANTE_PROFILER_CONTEXT=1
  169598. +
  169599. +
  169600. +ifeq ($(ANDROID), 1)
  169601. +EXTRA_CFLAGS += -DANDROID=1
  169602. +endif
  169603. +
  169604. +ifeq ($(ENABLE_GPU_CLOCK_BY_DRIVER), 1)
  169605. +EXTRA_CFLAGS += -DENABLE_GPU_CLOCK_BY_DRIVER=1
  169606. +else
  169607. +EXTRA_CFLAGS += -DENABLE_GPU_CLOCK_BY_DRIVER=0
  169608. +endif
  169609. +
  169610. +ifeq ($(USE_NEW_LINUX_SIGNAL), 1)
  169611. +EXTRA_CFLAGS += -DUSE_NEW_LINUX_SIGNAL=1
  169612. +else
  169613. +EXTRA_CFLAGS += -DUSE_NEW_LINUX_SIGNAL=0
  169614. +endif
  169615. +
  169616. +ifeq ($(NO_USER_DIRECT_ACCESS_FROM_KERNEL), 1)
  169617. +EXTRA_CFLAGS += -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=1
  169618. +else
  169619. +EXTRA_CFLAGS += -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=0
  169620. +endif
  169621. +
  169622. +ifeq ($(FORCE_ALL_VIDEO_MEMORY_CACHED), 1)
  169623. +EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=1
  169624. +else
  169625. +EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=0
  169626. +endif
  169627. +
  169628. +ifeq ($(NONPAGED_MEMORY_CACHEABLE), 1)
  169629. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_CACHEABLE=1
  169630. +else
  169631. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_CACHEABLE=0
  169632. +endif
  169633. +
  169634. +ifeq ($(NONPAGED_MEMORY_BUFFERABLE), 1)
  169635. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_BUFFERABLE=1
  169636. +else
  169637. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_BUFFERABLE=0
  169638. +endif
  169639. +
  169640. +ifeq ($(CACHE_FUNCTION_UNIMPLEMENTED), 1)
  169641. +EXTRA_CFLAGS += -DgcdCACHE_FUNCTION_UNIMPLEMENTED=1
  169642. +else
  169643. +EXTRA_CFLAGS += -DgcdCACHE_FUNCTION_UNIMPLEMENTED=0
  169644. +endif
  169645. +
  169646. +ifeq ($(SUPPORT_SWAP_RECTANGLE), 1)
  169647. +EXTRA_CFLAGS += -DgcdSUPPORT_SWAP_RECTANGLE=1
  169648. +else
  169649. +EXTRA_CFLAGS += -DgcdSUPPORT_SWAP_RECTANGLE=0
  169650. +endif
  169651. +
  169652. +ifeq ($(VIVANTE_ENABLE_VG), 1)
  169653. +EXTRA_CFLAGS += -DgcdENABLE_VG=1
  169654. +else
  169655. +EXTRA_CFLAGS += -DgcdENABLE_VG=0
  169656. +endif
  169657. +
  169658. +ifeq ($(CONFIG_SMP), y)
  169659. +EXTRA_CFLAGS += -DgcdSMP=1
  169660. +else
  169661. +EXTRA_CFLAGS += -DgcdSMP=0
  169662. +endif
  169663. +
  169664. +ifeq ($(VIVANTE_NO_3D),1)
  169665. +EXTRA_CFLAGS += -DVIVANTE_NO_3D
  169666. +endif
  169667. +
  169668. +ifeq ($(ENABLE_OUTER_CACHE_PATCH), 1)
  169669. +EXTRA_CFLAGS += -DgcdENABLE_OUTER_CACHE_PATCH=1
  169670. +else
  169671. +EXTRA_CFLAGS += -DgcdENABLE_OUTER_CACHE_PATCH=0
  169672. +endif
  169673. +
  169674. +ifeq ($(USE_BANK_ALIGNMENT), 1)
  169675. + EXTRA_CFLAGS += -DgcdENABLE_BANK_ALIGNMENT=1
  169676. + ifneq ($(BANK_BIT_START), 0)
  169677. + ifneq ($(BANK_BIT_END), 0)
  169678. + EXTRA_CFLAGS += -DgcdBANK_BIT_START=$(BANK_BIT_START)
  169679. + EXTRA_CFLAGS += -DgcdBANK_BIT_END=$(BANK_BIT_END)
  169680. + endif
  169681. + endif
  169682. +
  169683. + ifneq ($(BANK_CHANNEL_BIT), 0)
  169684. + EXTRA_CFLAGS += -DgcdBANK_CHANNEL_BIT=$(BANK_CHANNEL_BIT)
  169685. + endif
  169686. +endif
  169687. +
  169688. +ifneq ($(CONFIG_SYNC),)
  169689. +EXTRA_CFLAGS += -DgcdANDROID_NATIVE_FENCE_SYNC=1
  169690. +endif
  169691. +
  169692. +EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/inc
  169693. +EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel
  169694. +EXTRA_CFLAGS += -I$(AQARCH)/hal/kernel
  169695. +EXTRA_CFLAGS += -I$(AQROOT)/hal/os/linux/kernel
  169696. +
  169697. +ifeq ($(VIVANTE_ENABLE_VG), 1)
  169698. +EXTRA_CFLAGS += -I$(AQVGARCH)/hal/kernel
  169699. +endif
  169700. +
  169701. +obj-$(CONFIG_MXC_GPU_VIV) += galcore.o
  169702. +
  169703. +galcore-objs := $(OBJS)
  169704. +
  169705. +endif
  169706. diff -Nur linux-3.14.15/drivers/mxc/gpu-viv/Kconfig linux-linaro-stable-mx6/drivers/mxc/gpu-viv/Kconfig
  169707. --- linux-3.14.15/drivers/mxc/gpu-viv/Kconfig 1970-01-01 01:00:00.000000000 +0100
  169708. +++ linux-linaro-stable-mx6/drivers/mxc/gpu-viv/Kconfig 2014-08-20 19:23:53.554845822 +0200
  169709. @@ -0,0 +1,9 @@
  169710. +menu "MXC Vivante GPU support"
  169711. + depends on SOC_IMX6Q
  169712. +
  169713. +config MXC_GPU_VIV
  169714. + tristate "MXC Vivante GPU support"
  169715. + ---help---
  169716. + Say Y to get the GPU driver support.
  169717. +
  169718. +endmenu
  169719. diff -Nur linux-3.14.15/drivers/mxc/hdmi-cec/Kconfig linux-linaro-stable-mx6/drivers/mxc/hdmi-cec/Kconfig
  169720. --- linux-3.14.15/drivers/mxc/hdmi-cec/Kconfig 1970-01-01 01:00:00.000000000 +0100
  169721. +++ linux-linaro-stable-mx6/drivers/mxc/hdmi-cec/Kconfig 2014-08-20 19:23:53.574845907 +0200
  169722. @@ -0,0 +1,11 @@
  169723. +
  169724. +menu "MXC HDMI CEC (Consumer Electronics Control) support"
  169725. +
  169726. +config MXC_HDMI_CEC
  169727. + tristate "Support for MXC HDMI CEC (Consumer Electronics Control)"
  169728. + depends on MFD_MXC_HDMI
  169729. + depends on FB_MXC_HDMI
  169730. + help
  169731. + The HDMI CEC device implement low level protocol on i.MX6x platforms.
  169732. +
  169733. +endmenu
  169734. diff -Nur linux-3.14.15/drivers/mxc/hdmi-cec/Makefile linux-linaro-stable-mx6/drivers/mxc/hdmi-cec/Makefile
  169735. --- linux-3.14.15/drivers/mxc/hdmi-cec/Makefile 1970-01-01 01:00:00.000000000 +0100
  169736. +++ linux-linaro-stable-mx6/drivers/mxc/hdmi-cec/Makefile 2014-08-20 19:23:53.574845907 +0200
  169737. @@ -0,0 +1 @@
  169738. +obj-$(CONFIG_MXC_HDMI_CEC) += mxc_hdmi-cec.o
  169739. diff -Nur linux-3.14.15/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c linux-linaro-stable-mx6/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
  169740. --- linux-3.14.15/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c 1970-01-01 01:00:00.000000000 +0100
  169741. +++ linux-linaro-stable-mx6/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c 2014-08-20 19:23:53.574845907 +0200
  169742. @@ -0,0 +1,608 @@
  169743. +/*
  169744. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  169745. + */
  169746. +
  169747. +/*
  169748. + * The code contained herein is licensed under the GNU General Public
  169749. + * License. You may obtain a copy of the GNU General Public License
  169750. + * Version 2 or later at the following locations:
  169751. + *
  169752. + * http://www.opensource.org/licenses/gpl-license.html
  169753. + * http://www.gnu.org/copyleft/gpl.html
  169754. + */
  169755. +
  169756. +/*!
  169757. + * @file mxc_hdmi-cec.c
  169758. + *
  169759. + * @brief HDMI CEC system initialization and file operation implementation
  169760. + *
  169761. + * @ingroup HDMI
  169762. + */
  169763. +
  169764. +#include <linux/module.h>
  169765. +#include <linux/kernel.h>
  169766. +#include <linux/mm.h>
  169767. +#include <linux/fs.h>
  169768. +#include <linux/stat.h>
  169769. +#include <linux/platform_device.h>
  169770. +#include <linux/poll.h>
  169771. +#include <linux/wait.h>
  169772. +#include <linux/list.h>
  169773. +#include <linux/delay.h>
  169774. +#include <linux/fsl_devices.h>
  169775. +#include <linux/uaccess.h>
  169776. +#include <linux/io.h>
  169777. +#include <linux/slab.h>
  169778. +#include <linux/vmalloc.h>
  169779. +#include <linux/workqueue.h>
  169780. +#include <linux/sizes.h>
  169781. +
  169782. +#include <linux/console.h>
  169783. +#include <linux/types.h>
  169784. +#include <linux/mfd/mxc-hdmi-core.h>
  169785. +#include <linux/pinctrl/consumer.h>
  169786. +
  169787. +#include <video/mxc_hdmi.h>
  169788. +
  169789. +#include "mxc_hdmi-cec.h"
  169790. +
  169791. +
  169792. +#define MAX_MESSAGE_LEN 17
  169793. +
  169794. +#define MESSAGE_TYPE_RECEIVE_SUCCESS 1
  169795. +#define MESSAGE_TYPE_NOACK 2
  169796. +#define MESSAGE_TYPE_DISCONNECTED 3
  169797. +#define MESSAGE_TYPE_CONNECTED 4
  169798. +#define MESSAGE_TYPE_SEND_SUCCESS 5
  169799. +
  169800. +#define CEC_TX_INPROGRESS -1
  169801. +#define CEC_TX_AVAIL 0
  169802. +
  169803. +struct hdmi_cec_priv {
  169804. + int receive_error;
  169805. + int send_error;
  169806. + u8 Logical_address;
  169807. + bool cec_state;
  169808. + u8 last_msg[MAX_MESSAGE_LEN];
  169809. + u8 msg_len;
  169810. + int tx_answer;
  169811. + u16 latest_cec_stat;
  169812. + u8 link_status;
  169813. + spinlock_t irq_lock;
  169814. + struct delayed_work hdmi_cec_work;
  169815. + struct mutex lock;
  169816. +};
  169817. +
  169818. +struct hdmi_cec_event {
  169819. + int event_type;
  169820. + int msg_len;
  169821. + u8 msg[MAX_MESSAGE_LEN];
  169822. + struct list_head list;
  169823. +};
  169824. +
  169825. +
  169826. +static LIST_HEAD(head);
  169827. +
  169828. +static int hdmi_cec_major;
  169829. +static struct class *hdmi_cec_class;
  169830. +static struct hdmi_cec_priv hdmi_cec_data;
  169831. +static u8 open_count;
  169832. +
  169833. +static wait_queue_head_t hdmi_cec_queue;
  169834. +static wait_queue_head_t tx_cec_queue;
  169835. +
  169836. +static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
  169837. +{
  169838. + struct hdmi_cec_priv *hdmi_cec = data;
  169839. + u16 cec_stat = 0;
  169840. + unsigned long flags;
  169841. + u8 phy_stat0;
  169842. + irqreturn_t ret = IRQ_HANDLED;
  169843. +
  169844. + spin_lock_irqsave(&hdmi_cec->irq_lock, flags);
  169845. +
  169846. + hdmi_writeb(0x7f, HDMI_IH_MUTE_CEC_STAT0);
  169847. +
  169848. + cec_stat = hdmi_readb(HDMI_IH_CEC_STAT0);
  169849. + hdmi_writeb(cec_stat, HDMI_IH_CEC_STAT0);
  169850. + phy_stat0 = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
  169851. +
  169852. + if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \
  169853. + HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \
  169854. + HDMI_IH_CEC_STAT0_DONE)) == 0) {
  169855. + ret = IRQ_NONE;
  169856. + cec_stat = 0;
  169857. + }
  169858. + if (hdmi_cec->link_status ^ phy_stat0) {
  169859. + /* HPD value changed */
  169860. + hdmi_cec->link_status = phy_stat0;
  169861. + if (hdmi_cec->link_status)
  169862. + cec_stat |= 0x80; /* Connected */
  169863. + else
  169864. + cec_stat |= 0x100; /* Disconnected */
  169865. + }
  169866. + pr_debug("HDMI CEC interrupt received\n");
  169867. + hdmi_cec->latest_cec_stat = cec_stat ;
  169868. +
  169869. + schedule_delayed_work(&(hdmi_cec->hdmi_cec_work), msecs_to_jiffies(20));
  169870. +
  169871. + spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags);
  169872. +
  169873. + return ret;
  169874. +}
  169875. +
  169876. +void mxc_hdmi_cec_handle(u16 cec_stat)
  169877. +{
  169878. + u8 val = 0, i = 0;
  169879. + struct hdmi_cec_event *event = NULL;
  169880. + /*The current transmission is successful (for initiator only).*/
  169881. + if (!open_count)
  169882. + return;
  169883. +
  169884. + if (cec_stat & HDMI_IH_CEC_STAT0_DONE) {
  169885. + hdmi_cec_data.tx_answer = cec_stat;
  169886. + wake_up(&tx_cec_queue);
  169887. + }
  169888. + /*EOM is detected so that the received data is ready in the receiver data buffer*/
  169889. + if (cec_stat & HDMI_IH_CEC_STAT0_EOM) {
  169890. + hdmi_writeb(0x02, HDMI_IH_CEC_STAT0);
  169891. + event = vmalloc(sizeof(struct hdmi_cec_event));
  169892. + if (NULL == event) {
  169893. + pr_err("%s: Not enough memory!\n", __func__);
  169894. + return;
  169895. + }
  169896. + memset(event, 0, sizeof(struct hdmi_cec_event));
  169897. + event->msg_len = hdmi_readb(HDMI_CEC_RX_CNT);
  169898. + if (!event->msg_len) {
  169899. + pr_err("%s: Invalid CEC message length!\n", __func__);
  169900. + return;
  169901. + }
  169902. + event->event_type = MESSAGE_TYPE_RECEIVE_SUCCESS;
  169903. + for (i = 0; i < event->msg_len; i++)
  169904. + event->msg[i] = hdmi_readb(HDMI_CEC_RX_DATA0+i);
  169905. + hdmi_writeb(0x0, HDMI_CEC_LOCK);
  169906. + mutex_lock(&hdmi_cec_data.lock);
  169907. + list_add_tail(&event->list, &head);
  169908. + mutex_unlock(&hdmi_cec_data.lock);
  169909. + wake_up(&hdmi_cec_queue);
  169910. + }
  169911. + /*An error is detected on cec line (for initiator only). */
  169912. + if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_INIT) {
  169913. + mutex_lock(&hdmi_cec_data.lock);
  169914. + hdmi_cec_data.send_error++;
  169915. + if (hdmi_cec_data.send_error > 2) {
  169916. + pr_err("%s:Re-transmission is attempted more than 2 times!\n", __func__);
  169917. + hdmi_cec_data.send_error = 0;
  169918. + mutex_unlock(&hdmi_cec_data.lock);
  169919. + hdmi_cec_data.tx_answer = cec_stat;
  169920. + wake_up(&tx_cec_queue);
  169921. + return;
  169922. + }
  169923. + for (i = 0; i < hdmi_cec_data.msg_len; i++)
  169924. + hdmi_writeb(hdmi_cec_data.last_msg[i], HDMI_CEC_TX_DATA0+i);
  169925. + hdmi_writeb(hdmi_cec_data.msg_len, HDMI_CEC_TX_CNT);
  169926. + val = hdmi_readb(HDMI_CEC_CTRL);
  169927. + val |= 0x01;
  169928. + hdmi_writeb(val, HDMI_CEC_CTRL);
  169929. + mutex_unlock(&hdmi_cec_data.lock);
  169930. + }
  169931. + /*A frame is not acknowledged in a directly addressed message. Or a frame is negatively acknowledged in
  169932. + a broadcast message (for initiator only).*/
  169933. + if (cec_stat & HDMI_IH_CEC_STAT0_NACK) {
  169934. + hdmi_cec_data.tx_answer = cec_stat;
  169935. + wake_up(&tx_cec_queue);
  169936. + }
  169937. + /*An error is notified by a follower. Abnormal logic data bit error (for follower).*/
  169938. + if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_FOLL) {
  169939. + hdmi_cec_data.receive_error++;
  169940. + }
  169941. + /*HDMI cable connected*/
  169942. + if (cec_stat & 0x80) {
  169943. + pr_info("HDMI link connected\n");
  169944. + event = vmalloc(sizeof(struct hdmi_cec_event));
  169945. + if (NULL == event) {
  169946. + pr_err("%s: Not enough memory\n", __func__);
  169947. + return;
  169948. + }
  169949. + memset(event, 0, sizeof(struct hdmi_cec_event));
  169950. + event->event_type = MESSAGE_TYPE_CONNECTED;
  169951. + mutex_lock(&hdmi_cec_data.lock);
  169952. + list_add_tail(&event->list, &head);
  169953. + mutex_unlock(&hdmi_cec_data.lock);
  169954. + wake_up(&hdmi_cec_queue);
  169955. + }
  169956. + /*HDMI cable disconnected*/
  169957. + if (cec_stat & 0x100) {
  169958. + pr_info("HDMI link disconnected\n");
  169959. + event = vmalloc(sizeof(struct hdmi_cec_event));
  169960. + if (NULL == event) {
  169961. + pr_err("%s: Not enough memory!\n", __func__);
  169962. + return;
  169963. + }
  169964. + memset(event, 0, sizeof(struct hdmi_cec_event));
  169965. + event->event_type = MESSAGE_TYPE_DISCONNECTED;
  169966. + mutex_lock(&hdmi_cec_data.lock);
  169967. + list_add_tail(&event->list, &head);
  169968. + mutex_unlock(&hdmi_cec_data.lock);
  169969. + wake_up(&hdmi_cec_queue);
  169970. + }
  169971. + return;
  169972. +}
  169973. +EXPORT_SYMBOL(mxc_hdmi_cec_handle);
  169974. +static void mxc_hdmi_cec_worker(struct work_struct *work)
  169975. +{
  169976. + u8 val;
  169977. + mxc_hdmi_cec_handle(hdmi_cec_data.latest_cec_stat);
  169978. + val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST;
  169979. + hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
  169980. +}
  169981. +
  169982. +/*!
  169983. + * @brief open function for cec file operation
  169984. + *
  169985. + * @return 0 on success or negative error code on error
  169986. + */
  169987. +static int hdmi_cec_open(struct inode *inode, struct file *filp)
  169988. +{
  169989. + mutex_lock(&hdmi_cec_data.lock);
  169990. + if (open_count) {
  169991. + mutex_unlock(&hdmi_cec_data.lock);
  169992. + return -EBUSY;
  169993. + }
  169994. + open_count = 1;
  169995. + filp->private_data = (void *)(&hdmi_cec_data);
  169996. + hdmi_cec_data.Logical_address = 15;
  169997. + hdmi_cec_data.cec_state = false;
  169998. + mutex_unlock(&hdmi_cec_data.lock);
  169999. + return 0;
  170000. +}
  170001. +
  170002. +static ssize_t hdmi_cec_read(struct file *file, char __user *buf, size_t count,
  170003. + loff_t *ppos)
  170004. +{
  170005. + struct hdmi_cec_event *event = NULL;
  170006. + pr_debug("function : %s\n", __func__);
  170007. +
  170008. + if (!open_count)
  170009. + return -ENODEV;
  170010. + mutex_lock(&hdmi_cec_data.lock);
  170011. + if (false == hdmi_cec_data.cec_state) {
  170012. + mutex_unlock(&hdmi_cec_data.lock);
  170013. + return -EACCES;
  170014. + }
  170015. +
  170016. + if (list_empty(&head)) {
  170017. + if (file->f_flags & O_NONBLOCK) {
  170018. + mutex_unlock(&hdmi_cec_data.lock);
  170019. + return -EAGAIN;
  170020. + } else {
  170021. + do {
  170022. + mutex_unlock(&hdmi_cec_data.lock);
  170023. + if (wait_event_interruptible(hdmi_cec_queue, (!list_empty(&head))))
  170024. + return -ERESTARTSYS;
  170025. + mutex_lock(&hdmi_cec_data.lock);
  170026. + } while (list_empty(&head));
  170027. + }
  170028. + }
  170029. +
  170030. + event = list_first_entry(&head, struct hdmi_cec_event, list);
  170031. + list_del(&event->list);
  170032. + mutex_unlock(&hdmi_cec_data.lock);
  170033. + if (copy_to_user(buf, event,
  170034. + sizeof(struct hdmi_cec_event) - sizeof(struct list_head))) {
  170035. + vfree(event);
  170036. + return -EFAULT;
  170037. + }
  170038. + vfree(event);
  170039. + return (sizeof(struct hdmi_cec_event) - sizeof(struct list_head));
  170040. +}
  170041. +
  170042. +static ssize_t hdmi_cec_write(struct file *file, const char __user *buf,
  170043. + size_t count, loff_t *ppos)
  170044. +{
  170045. + int ret = 0 , i = 0;
  170046. + u8 msg[MAX_MESSAGE_LEN];
  170047. + u8 msg_len = 0, val = 0;
  170048. +
  170049. + pr_debug("function : %s\n", __func__);
  170050. +
  170051. + if (!open_count)
  170052. + return -ENODEV;
  170053. + mutex_lock(&hdmi_cec_data.lock);
  170054. + if (false == hdmi_cec_data.cec_state) {
  170055. + mutex_unlock(&hdmi_cec_data.lock);
  170056. + return -EACCES;
  170057. + }
  170058. + /* Ensure that there is only one writer who is the only listener of tx_cec_queue */
  170059. + if (hdmi_cec_data.tx_answer != CEC_TX_AVAIL) {
  170060. + mutex_unlock(&hdmi_cec_data.lock);
  170061. + return -EBUSY;
  170062. + }
  170063. + mutex_unlock(&hdmi_cec_data.lock);
  170064. + if (count > MAX_MESSAGE_LEN)
  170065. + return -EINVAL;
  170066. + memset(&msg, 0, MAX_MESSAGE_LEN);
  170067. + ret = copy_from_user(&msg, buf, count);
  170068. + if (ret)
  170069. + return -EACCES;
  170070. + mutex_lock(&hdmi_cec_data.lock);
  170071. + hdmi_cec_data.send_error = 0;
  170072. + hdmi_cec_data.tx_answer = CEC_TX_INPROGRESS;
  170073. + msg_len = count;
  170074. + hdmi_writeb(msg_len, HDMI_CEC_TX_CNT);
  170075. + for (i = 0; i < msg_len; i++)
  170076. + hdmi_writeb(msg[i], HDMI_CEC_TX_DATA0+i);
  170077. + val = hdmi_readb(HDMI_CEC_CTRL);
  170078. + val |= 0x01;
  170079. + hdmi_writeb(val, HDMI_CEC_CTRL);
  170080. + memcpy(hdmi_cec_data.last_msg, msg, msg_len);
  170081. + hdmi_cec_data.msg_len = msg_len;
  170082. + mutex_unlock(&hdmi_cec_data.lock);
  170083. +
  170084. + ret = wait_event_interruptible_timeout(tx_cec_queue, hdmi_cec_data.tx_answer != CEC_TX_INPROGRESS, HZ);
  170085. +
  170086. + if (ret < 0) {
  170087. + ret = -ERESTARTSYS;
  170088. + goto tx_out;
  170089. + }
  170090. +
  170091. + if (hdmi_cec_data.tx_answer & HDMI_IH_CEC_STAT0_DONE)
  170092. + /* msg correctly sent */
  170093. + ret = msg_len;
  170094. + else
  170095. + ret = -EIO;
  170096. +
  170097. + tx_out:
  170098. + hdmi_cec_data.tx_answer = CEC_TX_AVAIL;
  170099. + return ret;
  170100. +}
  170101. +
  170102. +
  170103. +static void hdmi_stop_device(void)
  170104. +{
  170105. + u8 val;
  170106. +
  170107. + hdmi_writeb(0x10, HDMI_CEC_CTRL);
  170108. + val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_ARB_LOST | \
  170109. + HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
  170110. + hdmi_writeb(val, HDMI_CEC_MASK);
  170111. + hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
  170112. + hdmi_writeb(0x0, HDMI_CEC_POLARITY);
  170113. + val = hdmi_readb(HDMI_MC_CLKDIS);
  170114. + val |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
  170115. + hdmi_writeb(val, HDMI_MC_CLKDIS);
  170116. + mutex_lock(&hdmi_cec_data.lock);
  170117. + hdmi_cec_data.cec_state = false;
  170118. + mutex_unlock(&hdmi_cec_data.lock);
  170119. +}
  170120. +
  170121. +/*!
  170122. + * @brief IO ctrl function for vpu file operation
  170123. + * @param cmd IO ctrl command
  170124. + * @return 0 on success or negative error code on error
  170125. + */
  170126. +static long hdmi_cec_ioctl(struct file *filp, u_int cmd,
  170127. + u_long arg)
  170128. +{
  170129. + int ret = 0, status = 0;
  170130. + u8 val = 0, msg = 0;
  170131. + struct mxc_edid_cfg hdmi_edid_cfg;
  170132. + pr_debug("function : %s\n", __func__);
  170133. + if (!open_count)
  170134. + return -ENODEV;
  170135. + switch (cmd) {
  170136. + case HDMICEC_IOC_SETLOGICALADDRESS:
  170137. + mutex_lock(&hdmi_cec_data.lock);
  170138. + if (false == hdmi_cec_data.cec_state) {
  170139. + mutex_unlock(&hdmi_cec_data.lock);
  170140. + pr_err("Trying to set logical address while not started\n");
  170141. + return -EACCES;
  170142. + }
  170143. + hdmi_cec_data.Logical_address = (u8)arg;
  170144. + if (hdmi_cec_data.Logical_address <= 7) {
  170145. + val = 1 << hdmi_cec_data.Logical_address;
  170146. + hdmi_writeb(val, HDMI_CEC_ADDR_L);
  170147. + hdmi_writeb(0, HDMI_CEC_ADDR_H);
  170148. + } else if (hdmi_cec_data.Logical_address > 7 && hdmi_cec_data.Logical_address <= 15) {
  170149. + val = 1 << (hdmi_cec_data.Logical_address - 8);
  170150. + hdmi_writeb(val, HDMI_CEC_ADDR_H);
  170151. + hdmi_writeb(0, HDMI_CEC_ADDR_L);
  170152. + } else
  170153. + ret = -EINVAL;
  170154. + /*Send Polling message with same source and destination address*/
  170155. + if (0 == ret && 15 != hdmi_cec_data.Logical_address) {
  170156. + msg = (hdmi_cec_data.Logical_address << 4)|hdmi_cec_data.Logical_address;
  170157. + hdmi_writeb(1, HDMI_CEC_TX_CNT);
  170158. + hdmi_writeb(msg, HDMI_CEC_TX_DATA0);
  170159. + val = hdmi_readb(HDMI_CEC_CTRL);
  170160. + val |= 0x01;
  170161. + hdmi_writeb(val, HDMI_CEC_CTRL);
  170162. + }
  170163. + mutex_unlock(&hdmi_cec_data.lock);
  170164. + break;
  170165. + case HDMICEC_IOC_STARTDEVICE:
  170166. + val = hdmi_readb(HDMI_MC_CLKDIS);
  170167. + val &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
  170168. + hdmi_writeb(val, HDMI_MC_CLKDIS);
  170169. + hdmi_writeb(0x02, HDMI_CEC_CTRL);
  170170. + /* Force read unlock */
  170171. + hdmi_writeb(0x0, HDMI_CEC_LOCK);
  170172. + val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
  170173. + hdmi_writeb(val, HDMI_CEC_POLARITY);
  170174. + val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST;
  170175. + hdmi_writeb(val, HDMI_CEC_MASK);
  170176. + hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
  170177. + hdmi_cec_data.link_status = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
  170178. + mutex_lock(&hdmi_cec_data.lock);
  170179. + hdmi_cec_data.cec_state = true;
  170180. + mutex_unlock(&hdmi_cec_data.lock);
  170181. + break;
  170182. + case HDMICEC_IOC_STOPDEVICE:
  170183. + hdmi_stop_device();
  170184. + break;
  170185. + case HDMICEC_IOC_GETPHYADDRESS:
  170186. + hdmi_get_edid_cfg(&hdmi_edid_cfg);
  170187. + status = copy_to_user((void __user *)arg,
  170188. + &hdmi_edid_cfg.physical_address,
  170189. + 4*sizeof(u8));
  170190. + if (status)
  170191. + ret = -EFAULT;
  170192. + break;
  170193. + default:
  170194. + ret = -EINVAL;
  170195. + break;
  170196. + }
  170197. + return ret;
  170198. +}
  170199. +
  170200. +/*!
  170201. + * @brief Release function for vpu file operation
  170202. + * @return 0 on success or negative error code on error
  170203. + */
  170204. +static int hdmi_cec_release(struct inode *inode, struct file *filp)
  170205. +{
  170206. + mutex_lock(&hdmi_cec_data.lock);
  170207. + if (open_count) {
  170208. + open_count = 0;
  170209. + hdmi_cec_data.cec_state = false;
  170210. + hdmi_cec_data.Logical_address = 15;
  170211. + }
  170212. + mutex_unlock(&hdmi_cec_data.lock);
  170213. +
  170214. + return 0;
  170215. +}
  170216. +
  170217. +static unsigned int hdmi_cec_poll(struct file *file, poll_table *wait)
  170218. +{
  170219. + unsigned int mask = 0;
  170220. +
  170221. + pr_debug("function : %s\n", __func__);
  170222. +
  170223. + poll_wait(file, &hdmi_cec_queue, wait);
  170224. +
  170225. + mutex_lock(&hdmi_cec_data.lock);
  170226. + if (hdmi_cec_data.tx_answer == CEC_TX_AVAIL)
  170227. + mask = (POLLOUT | POLLWRNORM);
  170228. + if (!list_empty(&head))
  170229. + mask |= (POLLIN | POLLRDNORM);
  170230. + mutex_unlock(&hdmi_cec_data.lock);
  170231. + return mask;
  170232. +}
  170233. +
  170234. +
  170235. +const struct file_operations hdmi_cec_fops = {
  170236. + .owner = THIS_MODULE,
  170237. + .read = hdmi_cec_read,
  170238. + .write = hdmi_cec_write,
  170239. + .open = hdmi_cec_open,
  170240. + .unlocked_ioctl = hdmi_cec_ioctl,
  170241. + .release = hdmi_cec_release,
  170242. + .poll = hdmi_cec_poll,
  170243. +};
  170244. +
  170245. +static int hdmi_cec_dev_probe(struct platform_device *pdev)
  170246. +{
  170247. + int err = 0;
  170248. + struct device *temp_class;
  170249. + struct resource *res;
  170250. + struct pinctrl *pinctrl;
  170251. + int irq = platform_get_irq(pdev, 0);
  170252. +
  170253. + hdmi_cec_major = register_chrdev(hdmi_cec_major, "mxc_hdmi_cec", &hdmi_cec_fops);
  170254. + if (hdmi_cec_major < 0) {
  170255. + dev_err(&pdev->dev, "hdmi_cec: unable to get a major for HDMI CEC\n");
  170256. + err = -EBUSY;
  170257. + goto out;
  170258. + }
  170259. +
  170260. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  170261. + if (unlikely(res == NULL)) {
  170262. + dev_err(&pdev->dev, "hdmi_cec:No HDMI irq line provided\n");
  170263. + goto err_out_chrdev;
  170264. + }
  170265. + spin_lock_init(&hdmi_cec_data.irq_lock);
  170266. +
  170267. + err = devm_request_irq(&pdev->dev, irq, mxc_hdmi_cec_isr, IRQF_SHARED,
  170268. + dev_name(&pdev->dev), &hdmi_cec_data);
  170269. + if (err < 0) {
  170270. + dev_err(&pdev->dev, "hdmi_cec:Unable to request irq: %d\n", err);
  170271. + goto err_out_chrdev;
  170272. + }
  170273. +
  170274. + hdmi_cec_class = class_create(THIS_MODULE, "mxc_hdmi_cec");
  170275. + if (IS_ERR(hdmi_cec_class)) {
  170276. + err = PTR_ERR(hdmi_cec_class);
  170277. + goto err_out_chrdev;
  170278. + }
  170279. +
  170280. + temp_class = device_create(hdmi_cec_class, NULL, MKDEV(hdmi_cec_major, 0),
  170281. + NULL, "mxc_hdmi_cec");
  170282. + if (IS_ERR(temp_class)) {
  170283. + err = PTR_ERR(temp_class);
  170284. + goto err_out_class;
  170285. + }
  170286. +
  170287. + pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
  170288. + if (IS_ERR(pinctrl)) {
  170289. + dev_err(&pdev->dev, "can't get/select CEC pinctrl\n");
  170290. + goto err_out_class;
  170291. + }
  170292. +
  170293. + init_waitqueue_head(&hdmi_cec_queue);
  170294. + init_waitqueue_head(&tx_cec_queue);
  170295. +
  170296. + INIT_LIST_HEAD(&head);
  170297. +
  170298. + mutex_init(&hdmi_cec_data.lock);
  170299. + hdmi_cec_data.Logical_address = 15;
  170300. + hdmi_cec_data.tx_answer = CEC_TX_AVAIL;
  170301. + platform_set_drvdata(pdev, &hdmi_cec_data);
  170302. + INIT_DELAYED_WORK(&hdmi_cec_data.hdmi_cec_work, mxc_hdmi_cec_worker);
  170303. +
  170304. + dev_info(&pdev->dev, "HDMI CEC initialized\n");
  170305. + goto out;
  170306. +
  170307. +err_out_class:
  170308. + device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0));
  170309. + class_destroy(hdmi_cec_class);
  170310. +err_out_chrdev:
  170311. + unregister_chrdev(hdmi_cec_major, "mxc_hdmi_cec");
  170312. +out:
  170313. + return err;
  170314. +}
  170315. +
  170316. +static int hdmi_cec_dev_remove(struct platform_device *pdev)
  170317. +{
  170318. + if (hdmi_cec_data.cec_state)
  170319. + hdmi_stop_device();
  170320. + if (hdmi_cec_major > 0) {
  170321. + device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0));
  170322. + class_destroy(hdmi_cec_class);
  170323. + unregister_chrdev(hdmi_cec_major, "mxc_hdmi_cec");
  170324. + hdmi_cec_major = 0;
  170325. +}
  170326. + return 0;
  170327. +}
  170328. +
  170329. +static const struct of_device_id imx_hdmi_cec_match[] = {
  170330. + { .compatible = "fsl,imx6q-hdmi-cec", },
  170331. + { .compatible = "fsl,imx6dl-hdmi-cec", },
  170332. + { /* sentinel */ }
  170333. +};
  170334. +
  170335. +static struct platform_driver mxc_hdmi_cec_driver = {
  170336. + .probe = hdmi_cec_dev_probe,
  170337. + .remove = hdmi_cec_dev_remove,
  170338. + .driver = {
  170339. + .name = "mxc_hdmi_cec",
  170340. + .of_match_table = imx_hdmi_cec_match,
  170341. + },
  170342. +};
  170343. +
  170344. +module_platform_driver(mxc_hdmi_cec_driver);
  170345. +
  170346. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  170347. +MODULE_DESCRIPTION("Linux HDMI CEC driver for Freescale i.MX/MXC");
  170348. +MODULE_LICENSE("GPL");
  170349. +MODULE_ALIAS("platform:mxc_hdmi_cec");
  170350. +
  170351. diff -Nur linux-3.14.15/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h linux-linaro-stable-mx6/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h
  170352. --- linux-3.14.15/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h 1970-01-01 01:00:00.000000000 +0100
  170353. +++ linux-linaro-stable-mx6/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h 2014-08-20 19:23:53.574845907 +0200
  170354. @@ -0,0 +1,38 @@
  170355. +/*
  170356. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  170357. + */
  170358. +
  170359. +/*
  170360. + * The code contained herein is licensed under the GNU General Public
  170361. + * License. You may obtain a copy of the GNU General Public License
  170362. + * Version 2 or later at the following locations:
  170363. + *
  170364. + * http://www.opensource.org/licenses/gpl-license.html
  170365. + * http://www.gnu.org/copyleft/gpl.html
  170366. + */
  170367. +#ifndef _HDMICEC_H_
  170368. +#define _HDMICEC_H_
  170369. +#include <linux/ioctl.h>
  170370. +
  170371. +/*
  170372. + * Ioctl definitions
  170373. + */
  170374. +
  170375. +/* Use 'k' as magic number */
  170376. +#define HDMICEC_IOC_MAGIC 'H'
  170377. +/*
  170378. + * S means "Set" through a ptr,
  170379. + * T means "Tell" directly with the argument value
  170380. + * G means "Get": reply by setting through a pointer
  170381. + * Q means "Query": response is on the return value
  170382. + * X means "eXchange": G and S atomically
  170383. + * H means "sHift": T and Q atomically
  170384. + */
  170385. +#define HDMICEC_IOC_SETLOGICALADDRESS \
  170386. + _IOW(HDMICEC_IOC_MAGIC, 1, unsigned char)
  170387. +#define HDMICEC_IOC_STARTDEVICE _IO(HDMICEC_IOC_MAGIC, 2)
  170388. +#define HDMICEC_IOC_STOPDEVICE _IO(HDMICEC_IOC_MAGIC, 3)
  170389. +#define HDMICEC_IOC_GETPHYADDRESS \
  170390. + _IOR(HDMICEC_IOC_MAGIC, 4, unsigned char[4])
  170391. +
  170392. +#endif /* !_HDMICEC_H_ */
  170393. diff -Nur linux-3.14.15/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
  170394. --- linux-3.14.15/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c 1970-01-01 01:00:00.000000000 +0100
  170395. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c 2014-08-20 19:31:46.136869040 +0200
  170396. @@ -0,0 +1,495 @@
  170397. +/*
  170398. + * Copyright 2009-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  170399. + */
  170400. +
  170401. +/*
  170402. + * The code contained herein is licensed under the GNU General Public
  170403. + * License. You may obtain a copy of the GNU General Public License
  170404. + * Version 2 or later at the following locations:
  170405. + *
  170406. + * http://www.opensource.org/licenses/gpl-license.html
  170407. + * http://www.gnu.org/copyleft/gpl.html
  170408. + */
  170409. +
  170410. +/*
  170411. + * @file ipu_calc_stripes_sizes.c
  170412. + *
  170413. + * @brief IPU IC functions
  170414. + *
  170415. + * @ingroup IPU
  170416. + */
  170417. +
  170418. +#include <linux/ipu-v3.h>
  170419. +#include <linux/module.h>
  170420. +#include <linux/math64.h>
  170421. +
  170422. +#define BPP_32 0
  170423. +#define BPP_16 3
  170424. +#define BPP_8 5
  170425. +#define BPP_24 1
  170426. +#define BPP_12 4
  170427. +#define BPP_18 2
  170428. +
  170429. +static u32 truncate(u32 up, /* 0: down; else: up */
  170430. + u64 a, /* must be non-negative */
  170431. + u32 b)
  170432. +{
  170433. + u32 d;
  170434. + u64 div;
  170435. + div = div_u64(a, b);
  170436. + d = b * (div >> 32);
  170437. + if (up && (a > (((u64)d) << 32)))
  170438. + return d+b;
  170439. + else
  170440. + return d;
  170441. +}
  170442. +
  170443. +static unsigned int f_calc(unsigned int pfs, unsigned int bpp, unsigned int *write)
  170444. +{/* return input_f */
  170445. + unsigned int f_calculated = 0;
  170446. + switch (pfs) {
  170447. + case IPU_PIX_FMT_YVU422P:
  170448. + case IPU_PIX_FMT_YUV422P:
  170449. + case IPU_PIX_FMT_YUV420P2:
  170450. + case IPU_PIX_FMT_YUV420P:
  170451. + case IPU_PIX_FMT_YVU420P:
  170452. + case IPU_PIX_FMT_YUV444P:
  170453. + f_calculated = 16;
  170454. + break;
  170455. +
  170456. + case IPU_PIX_FMT_RGB565:
  170457. + case IPU_PIX_FMT_YUYV:
  170458. + case IPU_PIX_FMT_UYVY:
  170459. + f_calculated = 8;
  170460. + break;
  170461. +
  170462. + case IPU_PIX_FMT_NV12:
  170463. + f_calculated = 8;
  170464. + break;
  170465. +
  170466. + default:
  170467. + f_calculated = 0;
  170468. + break;
  170469. +
  170470. + }
  170471. + if (!f_calculated) {
  170472. + switch (bpp) {
  170473. + case BPP_32:
  170474. + f_calculated = 2;
  170475. + break;
  170476. +
  170477. + case BPP_16:
  170478. + f_calculated = 4;
  170479. + break;
  170480. +
  170481. + case BPP_8:
  170482. + case BPP_24:
  170483. + f_calculated = 8;
  170484. + break;
  170485. +
  170486. + case BPP_12:
  170487. + f_calculated = 16;
  170488. + break;
  170489. +
  170490. + case BPP_18:
  170491. + f_calculated = 32;
  170492. + break;
  170493. +
  170494. + default:
  170495. + f_calculated = 0;
  170496. + break;
  170497. + }
  170498. + }
  170499. + return f_calculated;
  170500. +}
  170501. +
  170502. +
  170503. +static unsigned int m_calc(unsigned int pfs)
  170504. +{
  170505. + unsigned int m_calculated = 0;
  170506. + switch (pfs) {
  170507. + case IPU_PIX_FMT_YUV420P2:
  170508. + case IPU_PIX_FMT_YUV420P:
  170509. + case IPU_PIX_FMT_YVU422P:
  170510. + case IPU_PIX_FMT_YUV422P:
  170511. + case IPU_PIX_FMT_YVU420P:
  170512. + case IPU_PIX_FMT_YUV444P:
  170513. + m_calculated = 16;
  170514. + break;
  170515. +
  170516. + case IPU_PIX_FMT_NV12:
  170517. + case IPU_PIX_FMT_YUYV:
  170518. + case IPU_PIX_FMT_UYVY:
  170519. + m_calculated = 8;
  170520. + break;
  170521. +
  170522. + default:
  170523. + m_calculated = 8;
  170524. + break;
  170525. +
  170526. + }
  170527. + return m_calculated;
  170528. +}
  170529. +
  170530. +static int calc_split_resize_coeffs(unsigned int inSize, unsigned int outSize,
  170531. + unsigned int *resizeCoeff,
  170532. + unsigned int *downsizeCoeff)
  170533. +{
  170534. + uint32_t tempSize;
  170535. + uint32_t tempDownsize;
  170536. +
  170537. + if (inSize > 4096) {
  170538. + pr_debug("IC input size(%d) cannot exceed 4096\n",
  170539. + inSize);
  170540. + return -EINVAL;
  170541. + }
  170542. +
  170543. + if (outSize > 1024) {
  170544. + pr_debug("IC output size(%d) cannot exceed 1024\n",
  170545. + outSize);
  170546. + return -EINVAL;
  170547. + }
  170548. +
  170549. + if ((outSize << 3) < inSize) {
  170550. + pr_debug("IC cannot downsize more than 8:1\n");
  170551. + return -EINVAL;
  170552. + }
  170553. +
  170554. + /* Compute downsizing coefficient */
  170555. + /* Output of downsizing unit cannot be more than 1024 */
  170556. + tempDownsize = 0;
  170557. + tempSize = inSize;
  170558. + while (((tempSize > 1024) || (tempSize >= outSize * 2)) &&
  170559. + (tempDownsize < 2)) {
  170560. + tempSize >>= 1;
  170561. + tempDownsize++;
  170562. + }
  170563. + *downsizeCoeff = tempDownsize;
  170564. +
  170565. + /* compute resizing coefficient using the following equation:
  170566. + resizeCoeff = M*(SI -1)/(SO - 1)
  170567. + where M = 2^13, SI - input size, SO - output size */
  170568. + *resizeCoeff = (8192L * (tempSize - 1)) / (outSize - 1);
  170569. + if (*resizeCoeff >= 16384L) {
  170570. + pr_debug("Overflow on IC resize coefficient.\n");
  170571. + return -EINVAL;
  170572. + }
  170573. +
  170574. + pr_debug("resizing from %u -> %u pixels, "
  170575. + "downsize=%u, resize=%u.%lu (reg=%u)\n", inSize, outSize,
  170576. + *downsizeCoeff, (*resizeCoeff >= 8192L) ? 1 : 0,
  170577. + ((*resizeCoeff & 0x1FFF) * 10000L) / 8192L, *resizeCoeff);
  170578. +
  170579. + return 0;
  170580. +}
  170581. +
  170582. +/* Stripe parameters calculator */
  170583. +/**************************************************************************
  170584. +Notes:
  170585. +MSW = the maximal width allowed for a stripe
  170586. + i.MX31: 720, i.MX35: 800, i.MX37/51/53: 1024
  170587. +cirr = the maximal inverse resizing ratio for which overlap in the input
  170588. + is requested; typically cirr~2
  170589. +flags
  170590. + bit 0 - equal_stripes
  170591. + 0 each stripe is allowed to have independent parameters
  170592. + for maximal image quality
  170593. + 1 the stripes are requested to have identical parameters
  170594. + (except the base address), for maximal performance
  170595. + bit 1 - vertical/horizontal
  170596. + 0 horizontal
  170597. + 1 vertical
  170598. +
  170599. +If performance is the top priority (above image quality)
  170600. + Avoid overlap, by setting CIRR = 0
  170601. + This will also force effectively identical_stripes = 1
  170602. + Choose IF & OF that corresponds to the same IOX/SX for both stripes
  170603. + Choose IFW & OFW such that
  170604. + IFW/IM, IFW/IF, OFW/OM, OFW/OF are even integers
  170605. + The function returns an error status:
  170606. + 0: no error
  170607. + 1: invalid input parameters -> aborted without result
  170608. + Valid parameters should satisfy the following conditions
  170609. + IFW <= OFW, otherwise downsizing is required
  170610. + - which is not supported yet
  170611. + 4 <= IFW,OFW, so some interpolation may be needed even without overlap
  170612. + IM, OM, IF, OF should not vanish
  170613. + 2*IF <= IFW
  170614. + so the frame can be split to two equal stripes, even without overlap
  170615. + 2*(OF+IF/irr_opt) <= OFW
  170616. + so a valid positive INW exists even for equal stripes
  170617. + OF <= MSW, otherwise, the left stripe cannot be sufficiently large
  170618. + MSW < OFW, so splitting to stripes is required
  170619. + OFW <= 2*MSW, so two stripes are sufficient
  170620. + (this also implies that 2<=MSW)
  170621. + 2: OF is not a multiple of OM - not fully-supported yet
  170622. + Output is produced but OW is not guaranited to be a multiple of OM
  170623. + 4: OFW reduced to be a multiple of OM
  170624. + 8: CIRR > 1: truncated to 1
  170625. + Overlap is not supported (and not needed) y for upsizing)
  170626. +**************************************************************************/
  170627. +int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
  170628. + /* input frame width;>1 */
  170629. + unsigned int output_frame_width, /* output frame width; >1 */
  170630. + const unsigned int maximal_stripe_width,
  170631. + /* the maximal width allowed for a stripe */
  170632. + const unsigned long long cirr, /* see above */
  170633. + const unsigned int flags, /* see above */
  170634. + u32 input_pixelformat,/* pixel format after of read channel*/
  170635. + u32 output_pixelformat,/* pixel format after of write channel*/
  170636. + struct stripe_param *left,
  170637. + struct stripe_param *right)
  170638. +{
  170639. + const unsigned int irr_frac_bits = 13;
  170640. + const unsigned long irr_steps = 1 << irr_frac_bits;
  170641. + const u64 dirr = ((u64)1) << (32 - 2);
  170642. + /* The maximum relative difference allowed between the irrs */
  170643. + const u64 cr = ((u64)4) << 32;
  170644. + /* The importance ratio between the two terms in the cost function below */
  170645. +
  170646. + unsigned int status;
  170647. + unsigned int temp;
  170648. + unsigned int onw_min;
  170649. + unsigned int inw = 0, onw = 0, inw_best = 0;
  170650. + /* number of pixels in the left stripe NOT hidden by the right stripe */
  170651. + u64 irr_opt; /* the optimal inverse resizing ratio */
  170652. + u64 rr_opt; /* the optimal resizing ratio = 1/irr_opt*/
  170653. + u64 dinw; /* the misalignment between the stripes */
  170654. + /* (measured in units of input columns) */
  170655. + u64 difwl, difwr = 0;
  170656. + /* The number of input columns not reflected in the output */
  170657. + /* the resizing ratio used for the right stripe is */
  170658. + /* left->irr and right->irr respectively */
  170659. + u64 cost, cost_min;
  170660. + u64 div; /* result of division */
  170661. + bool equal_stripes = (flags & 0x1) != 0;
  170662. + bool vertical = (flags & 0x2) != 0;
  170663. +
  170664. + unsigned int input_m, input_f, output_m, output_f; /* parameters for upsizing by stripes */
  170665. + unsigned int resize_coeff;
  170666. + unsigned int downsize_coeff;
  170667. +
  170668. + status = 0;
  170669. +
  170670. + if (vertical) {
  170671. + input_f = 2;
  170672. + input_m = 8;
  170673. + output_f = 8;
  170674. + output_m = 2;
  170675. + } else {
  170676. + input_f = f_calc(input_pixelformat, 0, NULL);
  170677. + input_m = m_calc(input_pixelformat);
  170678. + output_f = input_m;
  170679. + output_m = m_calc(output_pixelformat);
  170680. + }
  170681. + if ((input_frame_width < 4) || (output_frame_width < 4))
  170682. + return 1;
  170683. +
  170684. + irr_opt = div_u64((((u64)(input_frame_width - 1)) << 32),
  170685. + (output_frame_width - 1));
  170686. + rr_opt = div_u64((((u64)(output_frame_width - 1)) << 32),
  170687. + (input_frame_width - 1));
  170688. +
  170689. + if ((input_m == 0) || (output_m == 0) || (input_f == 0) || (output_f == 0)
  170690. + || (input_frame_width < (2 * input_f))
  170691. + || ((((u64)output_frame_width) << 32) <
  170692. + (2 * ((((u64)output_f) << 32) + (input_f * rr_opt))))
  170693. + || (maximal_stripe_width < output_f)
  170694. + || ((output_frame_width <= maximal_stripe_width)
  170695. + && (equal_stripes == 0))
  170696. + || ((2 * maximal_stripe_width) < output_frame_width))
  170697. + return 1;
  170698. +
  170699. + if (output_f % output_m)
  170700. + status += 2;
  170701. +
  170702. + temp = truncate(0, (((u64)output_frame_width) << 32), output_m);
  170703. + if (temp < output_frame_width) {
  170704. + output_frame_width = temp;
  170705. + status += 4;
  170706. + }
  170707. +
  170708. + pr_debug("---------------->\n"
  170709. + "if = %d\n"
  170710. + "im = %d\n"
  170711. + "of = %d\n"
  170712. + "om = %d\n"
  170713. + "irr_opt = %llu\n"
  170714. + "rr_opt = %llu\n"
  170715. + "cirr = %llu\n"
  170716. + "pixel in = %08x\n"
  170717. + "pixel out = %08x\n"
  170718. + "ifw = %d\n"
  170719. + "ofwidth = %d\n",
  170720. + input_f,
  170721. + input_m,
  170722. + output_f,
  170723. + output_m,
  170724. + irr_opt,
  170725. + rr_opt,
  170726. + cirr,
  170727. + input_pixelformat,
  170728. + output_pixelformat,
  170729. + input_frame_width,
  170730. + output_frame_width
  170731. + );
  170732. +
  170733. + if (equal_stripes) {
  170734. + if ((irr_opt > cirr) /* overlap in the input is not requested */
  170735. + && ((input_frame_width % (input_m << 1)) == 0)
  170736. + && ((input_frame_width % (input_f << 1)) == 0)
  170737. + && ((output_frame_width % (output_m << 1)) == 0)
  170738. + && ((output_frame_width % (output_f << 1)) == 0)) {
  170739. + /* without overlap */
  170740. + left->input_width = right->input_width = right->input_column =
  170741. + input_frame_width >> 1;
  170742. + left->output_width = right->output_width = right->output_column =
  170743. + output_frame_width >> 1;
  170744. + left->input_column = 0;
  170745. + left->output_column = 0;
  170746. + div = div_u64(((((u64)irr_steps) << 32) *
  170747. + (right->input_width - 1)), (right->output_width - 1));
  170748. + left->irr = right->irr = truncate(0, div, 1);
  170749. + } else { /* with overlap */
  170750. + onw = truncate(0, (((u64)output_frame_width - 1) << 32) >> 1,
  170751. + output_f);
  170752. + inw = truncate(0, onw * irr_opt, input_f);
  170753. + /* this is the maximal inw which allows the same resizing ratio */
  170754. + /* in both stripes */
  170755. + onw = truncate(1, (inw * rr_opt), output_f);
  170756. + div = div_u64((((u64)(irr_steps * inw)) <<
  170757. + 32), onw);
  170758. + left->irr = right->irr = truncate(0, div, 1);
  170759. + left->output_width = right->output_width =
  170760. + output_frame_width - onw;
  170761. + /* These are valid assignments for output_width, */
  170762. + /* assuming output_f is a multiple of output_m */
  170763. + div = (((u64)(left->output_width-1) * (left->irr)) << 32);
  170764. + div = (((u64)1) << 32) + div_u64(div, irr_steps);
  170765. +
  170766. + left->input_width = right->input_width = truncate(1, div, input_m);
  170767. +
  170768. + div = div_u64((((u64)((right->output_width - 1) * right->irr)) <<
  170769. + 32), irr_steps);
  170770. + difwr = (((u64)(input_frame_width - 1 - inw)) << 32) - div;
  170771. + div = div_u64((difwr + (((u64)input_f) << 32)), 2);
  170772. + left->input_column = truncate(0, div, input_f);
  170773. +
  170774. +
  170775. + /* This splits the truncated input columns evenly */
  170776. + /* between the left and right margins */
  170777. + right->input_column = left->input_column + inw;
  170778. + left->output_column = 0;
  170779. + right->output_column = onw;
  170780. + }
  170781. + if (left->input_width > left->output_width) {
  170782. + if (calc_split_resize_coeffs(left->input_width,
  170783. + left->output_width,
  170784. + &resize_coeff,
  170785. + &downsize_coeff) < 0)
  170786. + return -EINVAL;
  170787. +
  170788. + if (downsize_coeff > 0) {
  170789. + left->irr = right->irr =
  170790. + (downsize_coeff << 14) | resize_coeff;
  170791. + }
  170792. + }
  170793. + pr_debug("inw %d, onw %d, ilw %d, ilc %d, olw %d,"
  170794. + " irw %d, irc %d, orw %d, orc %d, "
  170795. + "difwr %llu, lirr %u\n",
  170796. + inw, onw, left->input_width,
  170797. + left->input_column, left->output_width,
  170798. + right->input_width, right->input_column,
  170799. + right->output_width,
  170800. + right->output_column, difwr, left->irr);
  170801. + } else { /* independent stripes */
  170802. + onw_min = output_frame_width - maximal_stripe_width;
  170803. + /* onw is a multiple of output_f, in the range */
  170804. + /* [max(output_f,output_frame_width-maximal_stripe_width),*/
  170805. + /*min(output_frame_width-2,maximal_stripe_width)] */
  170806. + /* definitely beyond the cost of any valid setting */
  170807. + cost_min = (((u64)input_frame_width) << 32) + cr;
  170808. + onw = truncate(0, ((u64)maximal_stripe_width), output_f);
  170809. + if (output_frame_width - onw == 1)
  170810. + onw -= output_f; /* => onw and output_frame_width-1-onw are positive */
  170811. + inw = truncate(0, onw * irr_opt, input_f);
  170812. + /* this is the maximal inw which allows the same resizing ratio */
  170813. + /* in both stripes */
  170814. + onw = truncate(1, inw * rr_opt, output_f);
  170815. + do {
  170816. + div = div_u64((((u64)(irr_steps * inw)) << 32), onw);
  170817. + left->irr = truncate(0, div, 1);
  170818. + div = div_u64((((u64)(onw * left->irr)) << 32),
  170819. + irr_steps);
  170820. + dinw = (((u64)inw) << 32) - div;
  170821. +
  170822. + div = div_u64((((u64)((output_frame_width - 1 - onw) * left->irr)) <<
  170823. + 32), irr_steps);
  170824. +
  170825. + difwl = (((u64)(input_frame_width - 1 - inw)) << 32) - div;
  170826. +
  170827. + cost = difwl + (((u64)(cr * dinw)) >> 32);
  170828. +
  170829. + if (cost < cost_min) {
  170830. + inw_best = inw;
  170831. + cost_min = cost;
  170832. + }
  170833. +
  170834. + inw -= input_f;
  170835. + onw = truncate(1, inw * rr_opt, output_f);
  170836. + /* This is the minimal onw which allows the same resizing ratio */
  170837. + /* in both stripes */
  170838. + } while (onw >= onw_min);
  170839. +
  170840. + inw = inw_best;
  170841. + onw = truncate(1, inw * rr_opt, output_f);
  170842. + div = div_u64((((u64)(irr_steps * inw)) << 32), onw);
  170843. + left->irr = truncate(0, div, 1);
  170844. +
  170845. + left->output_width = onw;
  170846. + right->output_width = output_frame_width - onw;
  170847. + /* These are valid assignments for output_width, */
  170848. + /* assuming output_f is a multiple of output_m */
  170849. + left->input_width = truncate(1, ((u64)(inw + 1)) << 32, input_m);
  170850. + right->input_width = truncate(1, ((u64)(input_frame_width - inw)) <<
  170851. + 32, input_m);
  170852. +
  170853. + div = div_u64((((u64)(irr_steps * (input_frame_width - 1 - inw))) <<
  170854. + 32), (right->output_width - 1));
  170855. + right->irr = truncate(0, div, 1);
  170856. + temp = truncate(0, ((u64)left->irr) * ((((u64)1) << 32) + dirr), 1);
  170857. + if (temp < right->irr)
  170858. + right->irr = temp;
  170859. + div = div_u64(((u64)((right->output_width - 1) * right->irr) <<
  170860. + 32), irr_steps);
  170861. + difwr = (u64)(input_frame_width - 1 - inw) - div;
  170862. +
  170863. +
  170864. + div = div_u64((difwr + (((u64)input_f) << 32)), 2);
  170865. + left->input_column = truncate(0, div, input_f);
  170866. +
  170867. + /* This splits the truncated input columns evenly */
  170868. + /* between the left and right margins */
  170869. + right->input_column = left->input_column + inw;
  170870. + left->output_column = 0;
  170871. + right->output_column = onw;
  170872. + if (left->input_width > left->output_width) {
  170873. + if (calc_split_resize_coeffs(left->input_width,
  170874. + left->output_width,
  170875. + &resize_coeff,
  170876. + &downsize_coeff) < 0)
  170877. + return -EINVAL;
  170878. + left->irr = (downsize_coeff << 14) | resize_coeff;
  170879. + }
  170880. + if (right->input_width > right->output_width) {
  170881. + if (calc_split_resize_coeffs(right->input_width,
  170882. + right->output_width,
  170883. + &resize_coeff,
  170884. + &downsize_coeff) < 0)
  170885. + return -EINVAL;
  170886. + right->irr = (downsize_coeff << 14) | resize_coeff;
  170887. + }
  170888. + }
  170889. + return status;
  170890. +}
  170891. +EXPORT_SYMBOL(ipu_calc_stripes_sizes);
  170892. diff -Nur linux-3.14.15/drivers/mxc/ipu3/ipu_capture.c linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_capture.c
  170893. --- linux-3.14.15/drivers/mxc/ipu3/ipu_capture.c 1970-01-01 01:00:00.000000000 +0100
  170894. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_capture.c 2014-08-20 19:31:46.136869040 +0200
  170895. @@ -0,0 +1,816 @@
  170896. +/*
  170897. + * Copyright 2008-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  170898. + */
  170899. +
  170900. +/*
  170901. + * The code contained herein is licensed under the GNU General Public
  170902. + * License. You may obtain a copy of the GNU General Public License
  170903. + * Version 2 or later at the following locations:
  170904. + *
  170905. + * http://www.opensource.org/licenses/gpl-license.html
  170906. + * http://www.gnu.org/copyleft/gpl.html
  170907. + */
  170908. +
  170909. +/*!
  170910. + * @file ipu_capture.c
  170911. + *
  170912. + * @brief IPU capture dase functions
  170913. + *
  170914. + * @ingroup IPU
  170915. + */
  170916. +#include <linux/clk.h>
  170917. +#include <linux/delay.h>
  170918. +#include <linux/errno.h>
  170919. +#include <linux/init.h>
  170920. +#include <linux/io.h>
  170921. +#include <linux/ipu-v3.h>
  170922. +#include <linux/module.h>
  170923. +#include <linux/spinlock.h>
  170924. +#include <linux/types.h>
  170925. +
  170926. +#include "ipu_prv.h"
  170927. +#include "ipu_regs.h"
  170928. +
  170929. +/*!
  170930. + * _ipu_csi_mclk_set
  170931. + *
  170932. + * @param ipu ipu handler
  170933. + * @param pixel_clk desired pixel clock frequency in Hz
  170934. + * @param csi csi 0 or csi 1
  170935. + *
  170936. + * @return Returns 0 on success or negative error code on fail
  170937. + */
  170938. +int _ipu_csi_mclk_set(struct ipu_soc *ipu, uint32_t pixel_clk, uint32_t csi)
  170939. +{
  170940. + uint32_t temp;
  170941. + uint32_t div_ratio;
  170942. +
  170943. + div_ratio = (clk_get_rate(ipu->ipu_clk) / pixel_clk) - 1;
  170944. +
  170945. + if (div_ratio > 0xFF || div_ratio < 0) {
  170946. + dev_dbg(ipu->dev, "value of pixel_clk extends normal range\n");
  170947. + return -EINVAL;
  170948. + }
  170949. +
  170950. + temp = ipu_csi_read(ipu, csi, CSI_SENS_CONF);
  170951. + temp &= ~CSI_SENS_CONF_DIVRATIO_MASK;
  170952. + ipu_csi_write(ipu, csi, temp |
  170953. + (div_ratio << CSI_SENS_CONF_DIVRATIO_SHIFT),
  170954. + CSI_SENS_CONF);
  170955. +
  170956. + return 0;
  170957. +}
  170958. +
  170959. +/*!
  170960. + * ipu_csi_init_interface
  170961. + * Sets initial values for the CSI registers.
  170962. + * The width and height of the sensor and the actual frame size will be
  170963. + * set to the same values.
  170964. + * @param ipu ipu handler
  170965. + * @param width Sensor width
  170966. + * @param height Sensor height
  170967. + * @param pixel_fmt pixel format
  170968. + * @param cfg_param ipu_csi_signal_cfg_t structure
  170969. + * @param csi csi 0 or csi 1
  170970. + *
  170971. + * @return 0 for success, -EINVAL for error
  170972. + */
  170973. +int32_t
  170974. +ipu_csi_init_interface(struct ipu_soc *ipu, uint16_t width, uint16_t height,
  170975. + uint32_t pixel_fmt, ipu_csi_signal_cfg_t cfg_param)
  170976. +{
  170977. + uint32_t data = 0;
  170978. + uint32_t csi = cfg_param.csi;
  170979. +
  170980. + /* Set SENS_DATA_FORMAT bits (8, 9 and 10)
  170981. + RGB or YUV444 is 0 which is current value in data so not set
  170982. + explicitly
  170983. + This is also the default value if attempts are made to set it to
  170984. + something invalid. */
  170985. + switch (pixel_fmt) {
  170986. + case IPU_PIX_FMT_YUYV:
  170987. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV;
  170988. + break;
  170989. + case IPU_PIX_FMT_UYVY:
  170990. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY;
  170991. + break;
  170992. + case IPU_PIX_FMT_RGB24:
  170993. + case IPU_PIX_FMT_BGR24:
  170994. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB_YUV444;
  170995. + break;
  170996. + case IPU_PIX_FMT_GENERIC:
  170997. + case IPU_PIX_FMT_GENERIC_16:
  170998. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
  170999. + break;
  171000. + case IPU_PIX_FMT_RGB565:
  171001. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565;
  171002. + break;
  171003. + case IPU_PIX_FMT_RGB555:
  171004. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB555;
  171005. + break;
  171006. + default:
  171007. + return -EINVAL;
  171008. + }
  171009. +
  171010. + /* Set the CSI_SENS_CONF register remaining fields */
  171011. + data |= cfg_param.data_width << CSI_SENS_CONF_DATA_WIDTH_SHIFT |
  171012. + cfg_param.data_fmt << CSI_SENS_CONF_DATA_FMT_SHIFT |
  171013. + cfg_param.data_pol << CSI_SENS_CONF_DATA_POL_SHIFT |
  171014. + cfg_param.Vsync_pol << CSI_SENS_CONF_VSYNC_POL_SHIFT |
  171015. + cfg_param.Hsync_pol << CSI_SENS_CONF_HSYNC_POL_SHIFT |
  171016. + cfg_param.pixclk_pol << CSI_SENS_CONF_PIX_CLK_POL_SHIFT |
  171017. + cfg_param.ext_vsync << CSI_SENS_CONF_EXT_VSYNC_SHIFT |
  171018. + cfg_param.clk_mode << CSI_SENS_CONF_SENS_PRTCL_SHIFT |
  171019. + cfg_param.pack_tight << CSI_SENS_CONF_PACK_TIGHT_SHIFT |
  171020. + cfg_param.force_eof << CSI_SENS_CONF_FORCE_EOF_SHIFT |
  171021. + cfg_param.data_en_pol << CSI_SENS_CONF_DATA_EN_POL_SHIFT;
  171022. +
  171023. + _ipu_get(ipu);
  171024. +
  171025. + mutex_lock(&ipu->mutex_lock);
  171026. +
  171027. + ipu_csi_write(ipu, csi, data, CSI_SENS_CONF);
  171028. +
  171029. + /* Setup sensor frame size */
  171030. + ipu_csi_write(ipu, csi, (width - 1) | (height - 1) << 16, CSI_SENS_FRM_SIZE);
  171031. +
  171032. + /* Set CCIR registers */
  171033. + if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) {
  171034. + ipu_csi_write(ipu, csi, 0x40030, CSI_CCIR_CODE_1);
  171035. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  171036. + } else if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED) {
  171037. + if (width == 720 && height == 625) {
  171038. + /* PAL case */
  171039. + /*
  171040. + * Field0BlankEnd = 0x6, Field0BlankStart = 0x2,
  171041. + * Field0ActiveEnd = 0x4, Field0ActiveStart = 0
  171042. + */
  171043. + ipu_csi_write(ipu, csi, 0x40596, CSI_CCIR_CODE_1);
  171044. + /*
  171045. + * Field1BlankEnd = 0x7, Field1BlankStart = 0x3,
  171046. + * Field1ActiveEnd = 0x5, Field1ActiveStart = 0x1
  171047. + */
  171048. + ipu_csi_write(ipu, csi, 0xD07DF, CSI_CCIR_CODE_2);
  171049. +
  171050. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  171051. +
  171052. + } else if (width == 720 && height == 525) {
  171053. + /* NTSC case */
  171054. + /*
  171055. + * Field0BlankEnd = 0x7, Field0BlankStart = 0x3,
  171056. + * Field0ActiveEnd = 0x5, Field0ActiveStart = 0x1
  171057. + */
  171058. + ipu_csi_write(ipu, csi, 0xD07DF, CSI_CCIR_CODE_1);
  171059. + /*
  171060. + * Field1BlankEnd = 0x6, Field1BlankStart = 0x2,
  171061. + * Field1ActiveEnd = 0x4, Field1ActiveStart = 0
  171062. + */
  171063. + ipu_csi_write(ipu, csi, 0x40596, CSI_CCIR_CODE_2);
  171064. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  171065. + } else {
  171066. + dev_err(ipu->dev, "Unsupported CCIR656 interlaced "
  171067. + "video mode\n");
  171068. + mutex_unlock(&ipu->mutex_lock);
  171069. + _ipu_put(ipu);
  171070. + return -EINVAL;
  171071. + }
  171072. + _ipu_csi_ccir_err_detection_enable(ipu, csi);
  171073. + } else if ((cfg_param.clk_mode ==
  171074. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR) ||
  171075. + (cfg_param.clk_mode ==
  171076. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR) ||
  171077. + (cfg_param.clk_mode ==
  171078. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR) ||
  171079. + (cfg_param.clk_mode ==
  171080. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR)) {
  171081. + ipu_csi_write(ipu, csi, 0x40030, CSI_CCIR_CODE_1);
  171082. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  171083. + _ipu_csi_ccir_err_detection_enable(ipu, csi);
  171084. + } else if ((cfg_param.clk_mode == IPU_CSI_CLK_MODE_GATED_CLK) ||
  171085. + (cfg_param.clk_mode == IPU_CSI_CLK_MODE_NONGATED_CLK)) {
  171086. + _ipu_csi_ccir_err_detection_disable(ipu, csi);
  171087. + }
  171088. +
  171089. + dev_dbg(ipu->dev, "CSI_SENS_CONF = 0x%08X\n",
  171090. + ipu_csi_read(ipu, csi, CSI_SENS_CONF));
  171091. + dev_dbg(ipu->dev, "CSI_ACT_FRM_SIZE = 0x%08X\n",
  171092. + ipu_csi_read(ipu, csi, CSI_ACT_FRM_SIZE));
  171093. +
  171094. + mutex_unlock(&ipu->mutex_lock);
  171095. +
  171096. + _ipu_put(ipu);
  171097. +
  171098. + return 0;
  171099. +}
  171100. +EXPORT_SYMBOL(ipu_csi_init_interface);
  171101. +
  171102. +/*!
  171103. + * ipu_csi_get_sensor_protocol
  171104. + *
  171105. + * @param ipu ipu handler
  171106. + * @param csi csi 0 or csi 1
  171107. + *
  171108. + * @return Returns sensor protocol
  171109. + */
  171110. +int32_t ipu_csi_get_sensor_protocol(struct ipu_soc *ipu, uint32_t csi)
  171111. +{
  171112. + int ret;
  171113. + _ipu_get(ipu);
  171114. + ret = (ipu_csi_read(ipu, csi, CSI_SENS_CONF) &
  171115. + CSI_SENS_CONF_SENS_PRTCL_MASK) >>
  171116. + CSI_SENS_CONF_SENS_PRTCL_SHIFT;
  171117. + _ipu_put(ipu);
  171118. + return ret;
  171119. +}
  171120. +EXPORT_SYMBOL(ipu_csi_get_sensor_protocol);
  171121. +
  171122. +/*!
  171123. + * ipu_csi_enable_mclk
  171124. + *
  171125. + * @param ipu ipu handler
  171126. + * @param csi csi 0 or csi 1
  171127. + * @param flag true to enable mclk, false to disable mclk
  171128. + * @param wait true to wait 100ms make clock stable, false not wait
  171129. + *
  171130. + * @return Returns 0 on success
  171131. + */
  171132. +int ipu_csi_enable_mclk(struct ipu_soc *ipu, int csi, bool flag, bool wait)
  171133. +{
  171134. + /* Return immediately if there is no csi_clk to manage */
  171135. + if (ipu->csi_clk[csi] == NULL)
  171136. + return 0;
  171137. +
  171138. + if (flag) {
  171139. + clk_enable(ipu->csi_clk[csi]);
  171140. + if (wait == true)
  171141. + msleep(10);
  171142. + } else {
  171143. + clk_disable(ipu->csi_clk[csi]);
  171144. + }
  171145. +
  171146. + return 0;
  171147. +}
  171148. +EXPORT_SYMBOL(ipu_csi_enable_mclk);
  171149. +
  171150. +/*!
  171151. + * ipu_csi_get_window_size
  171152. + *
  171153. + * @param ipu ipu handler
  171154. + * @param width pointer to window width
  171155. + * @param height pointer to window height
  171156. + * @param csi csi 0 or csi 1
  171157. + */
  171158. +void ipu_csi_get_window_size(struct ipu_soc *ipu, uint32_t *width, uint32_t *height, uint32_t csi)
  171159. +{
  171160. + uint32_t reg;
  171161. +
  171162. + _ipu_get(ipu);
  171163. +
  171164. + mutex_lock(&ipu->mutex_lock);
  171165. +
  171166. + reg = ipu_csi_read(ipu, csi, CSI_ACT_FRM_SIZE);
  171167. + *width = (reg & 0xFFFF) + 1;
  171168. + *height = (reg >> 16 & 0xFFFF) + 1;
  171169. +
  171170. + mutex_unlock(&ipu->mutex_lock);
  171171. +
  171172. + _ipu_put(ipu);
  171173. +}
  171174. +EXPORT_SYMBOL(ipu_csi_get_window_size);
  171175. +
  171176. +/*!
  171177. + * ipu_csi_set_window_size
  171178. + *
  171179. + * @param ipu ipu handler
  171180. + * @param width window width
  171181. + * @param height window height
  171182. + * @param csi csi 0 or csi 1
  171183. + */
  171184. +void ipu_csi_set_window_size(struct ipu_soc *ipu, uint32_t width, uint32_t height, uint32_t csi)
  171185. +{
  171186. + _ipu_get(ipu);
  171187. +
  171188. + mutex_lock(&ipu->mutex_lock);
  171189. +
  171190. + ipu_csi_write(ipu, csi, (width - 1) | (height - 1) << 16, CSI_ACT_FRM_SIZE);
  171191. +
  171192. + mutex_unlock(&ipu->mutex_lock);
  171193. +
  171194. + _ipu_put(ipu);
  171195. +}
  171196. +EXPORT_SYMBOL(ipu_csi_set_window_size);
  171197. +
  171198. +/*!
  171199. + * ipu_csi_set_window_pos
  171200. + *
  171201. + * @param ipu ipu handler
  171202. + * @param left uint32 window x start
  171203. + * @param top uint32 window y start
  171204. + * @param csi csi 0 or csi 1
  171205. + */
  171206. +void ipu_csi_set_window_pos(struct ipu_soc *ipu, uint32_t left, uint32_t top, uint32_t csi)
  171207. +{
  171208. + uint32_t temp;
  171209. +
  171210. + _ipu_get(ipu);
  171211. +
  171212. + mutex_lock(&ipu->mutex_lock);
  171213. +
  171214. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  171215. + temp &= ~(CSI_HSC_MASK | CSI_VSC_MASK);
  171216. + temp |= ((top << CSI_VSC_SHIFT) | (left << CSI_HSC_SHIFT));
  171217. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  171218. +
  171219. + mutex_unlock(&ipu->mutex_lock);
  171220. +
  171221. + _ipu_put(ipu);
  171222. +}
  171223. +EXPORT_SYMBOL(ipu_csi_set_window_pos);
  171224. +
  171225. +/*!
  171226. + * _ipu_csi_horizontal_downsize_enable
  171227. + * Enable horizontal downsizing(decimation) by 2.
  171228. + *
  171229. + * @param ipu ipu handler
  171230. + * @param csi csi 0 or csi 1
  171231. + */
  171232. +void _ipu_csi_horizontal_downsize_enable(struct ipu_soc *ipu, uint32_t csi)
  171233. +{
  171234. + uint32_t temp;
  171235. +
  171236. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  171237. + temp |= CSI_HORI_DOWNSIZE_EN;
  171238. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  171239. +}
  171240. +
  171241. +/*!
  171242. + * _ipu_csi_horizontal_downsize_disable
  171243. + * Disable horizontal downsizing(decimation) by 2.
  171244. + *
  171245. + * @param ipu ipu handler
  171246. + * @param csi csi 0 or csi 1
  171247. + */
  171248. +void _ipu_csi_horizontal_downsize_disable(struct ipu_soc *ipu, uint32_t csi)
  171249. +{
  171250. + uint32_t temp;
  171251. +
  171252. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  171253. + temp &= ~CSI_HORI_DOWNSIZE_EN;
  171254. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  171255. +}
  171256. +
  171257. +/*!
  171258. + * _ipu_csi_vertical_downsize_enable
  171259. + * Enable vertical downsizing(decimation) by 2.
  171260. + *
  171261. + * @param ipu ipu handler
  171262. + * @param csi csi 0 or csi 1
  171263. + */
  171264. +void _ipu_csi_vertical_downsize_enable(struct ipu_soc *ipu, uint32_t csi)
  171265. +{
  171266. + uint32_t temp;
  171267. +
  171268. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  171269. + temp |= CSI_VERT_DOWNSIZE_EN;
  171270. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  171271. +}
  171272. +
  171273. +/*!
  171274. + * _ipu_csi_vertical_downsize_disable
  171275. + * Disable vertical downsizing(decimation) by 2.
  171276. + *
  171277. + * @param ipu ipu handler
  171278. + * @param csi csi 0 or csi 1
  171279. + */
  171280. +void _ipu_csi_vertical_downsize_disable(struct ipu_soc *ipu, uint32_t csi)
  171281. +{
  171282. + uint32_t temp;
  171283. +
  171284. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  171285. + temp &= ~CSI_VERT_DOWNSIZE_EN;
  171286. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  171287. +}
  171288. +
  171289. +/*!
  171290. + * _ipu_csi_set_test_generator
  171291. + *
  171292. + * @param ipu ipu handler
  171293. + * @param active 1 for active and 0 for inactive
  171294. + * @param r_value red value for the generated pattern of even pixel
  171295. + * @param g_value green value for the generated pattern of even
  171296. + * pixel
  171297. + * @param b_value blue value for the generated pattern of even pixel
  171298. + * @param pixel_clk desired pixel clock frequency in Hz
  171299. + * @param csi csi 0 or csi 1
  171300. + */
  171301. +void _ipu_csi_set_test_generator(struct ipu_soc *ipu, bool active, uint32_t r_value,
  171302. + uint32_t g_value, uint32_t b_value, uint32_t pix_clk, uint32_t csi)
  171303. +{
  171304. + uint32_t temp;
  171305. +
  171306. + temp = ipu_csi_read(ipu, csi, CSI_TST_CTRL);
  171307. +
  171308. + if (active == false) {
  171309. + temp &= ~CSI_TEST_GEN_MODE_EN;
  171310. + ipu_csi_write(ipu, csi, temp, CSI_TST_CTRL);
  171311. + } else {
  171312. + /* Set sensb_mclk div_ratio*/
  171313. + _ipu_csi_mclk_set(ipu, pix_clk, csi);
  171314. +
  171315. + temp &= ~(CSI_TEST_GEN_R_MASK | CSI_TEST_GEN_G_MASK |
  171316. + CSI_TEST_GEN_B_MASK);
  171317. + temp |= CSI_TEST_GEN_MODE_EN;
  171318. + temp |= (r_value << CSI_TEST_GEN_R_SHIFT) |
  171319. + (g_value << CSI_TEST_GEN_G_SHIFT) |
  171320. + (b_value << CSI_TEST_GEN_B_SHIFT);
  171321. + ipu_csi_write(ipu, csi, temp, CSI_TST_CTRL);
  171322. + }
  171323. +}
  171324. +
  171325. +/*!
  171326. + * _ipu_csi_ccir_err_detection_en
  171327. + * Enable error detection and correction for
  171328. + * CCIR interlaced mode with protection bit.
  171329. + *
  171330. + * @param ipu ipu handler
  171331. + * @param csi csi 0 or csi 1
  171332. + */
  171333. +void _ipu_csi_ccir_err_detection_enable(struct ipu_soc *ipu, uint32_t csi)
  171334. +{
  171335. + uint32_t temp;
  171336. +
  171337. + temp = ipu_csi_read(ipu, csi, CSI_CCIR_CODE_1);
  171338. + temp |= CSI_CCIR_ERR_DET_EN;
  171339. + ipu_csi_write(ipu, csi, temp, CSI_CCIR_CODE_1);
  171340. +
  171341. +}
  171342. +
  171343. +/*!
  171344. + * _ipu_csi_ccir_err_detection_disable
  171345. + * Disable error detection and correction for
  171346. + * CCIR interlaced mode with protection bit.
  171347. + *
  171348. + * @param ipu ipu handler
  171349. + * @param csi csi 0 or csi 1
  171350. + */
  171351. +void _ipu_csi_ccir_err_detection_disable(struct ipu_soc *ipu, uint32_t csi)
  171352. +{
  171353. + uint32_t temp;
  171354. +
  171355. + temp = ipu_csi_read(ipu, csi, CSI_CCIR_CODE_1);
  171356. + temp &= ~CSI_CCIR_ERR_DET_EN;
  171357. + ipu_csi_write(ipu, csi, temp, CSI_CCIR_CODE_1);
  171358. +
  171359. +}
  171360. +
  171361. +/*!
  171362. + * _ipu_csi_set_mipi_di
  171363. + *
  171364. + * @param ipu ipu handler
  171365. + * @param num MIPI data identifier 0-3 handled by CSI
  171366. + * @param di_val data identifier value
  171367. + * @param csi csi 0 or csi 1
  171368. + *
  171369. + * @return Returns 0 on success or negative error code on fail
  171370. + */
  171371. +int _ipu_csi_set_mipi_di(struct ipu_soc *ipu, uint32_t num, uint32_t di_val, uint32_t csi)
  171372. +{
  171373. + uint32_t temp;
  171374. + int retval = 0;
  171375. +
  171376. + if (di_val > 0xFFL) {
  171377. + retval = -EINVAL;
  171378. + goto err;
  171379. + }
  171380. +
  171381. + temp = ipu_csi_read(ipu, csi, CSI_MIPI_DI);
  171382. +
  171383. + switch (num) {
  171384. + case IPU_CSI_MIPI_DI0:
  171385. + temp &= ~CSI_MIPI_DI0_MASK;
  171386. + temp |= (di_val << CSI_MIPI_DI0_SHIFT);
  171387. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  171388. + break;
  171389. + case IPU_CSI_MIPI_DI1:
  171390. + temp &= ~CSI_MIPI_DI1_MASK;
  171391. + temp |= (di_val << CSI_MIPI_DI1_SHIFT);
  171392. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  171393. + break;
  171394. + case IPU_CSI_MIPI_DI2:
  171395. + temp &= ~CSI_MIPI_DI2_MASK;
  171396. + temp |= (di_val << CSI_MIPI_DI2_SHIFT);
  171397. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  171398. + break;
  171399. + case IPU_CSI_MIPI_DI3:
  171400. + temp &= ~CSI_MIPI_DI3_MASK;
  171401. + temp |= (di_val << CSI_MIPI_DI3_SHIFT);
  171402. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  171403. + break;
  171404. + default:
  171405. + retval = -EINVAL;
  171406. + }
  171407. +
  171408. +err:
  171409. + return retval;
  171410. +}
  171411. +
  171412. +/*!
  171413. + * _ipu_csi_set_skip_isp
  171414. + *
  171415. + * @param ipu ipu handler
  171416. + * @param skip select frames to be skipped and set the
  171417. + * correspond bits to 1
  171418. + * @param max_ratio number of frames in a skipping set and the
  171419. + * maximum value of max_ratio is 5
  171420. + * @param csi csi 0 or csi 1
  171421. + *
  171422. + * @return Returns 0 on success or negative error code on fail
  171423. + */
  171424. +int _ipu_csi_set_skip_isp(struct ipu_soc *ipu, uint32_t skip, uint32_t max_ratio, uint32_t csi)
  171425. +{
  171426. + uint32_t temp;
  171427. + int retval = 0;
  171428. +
  171429. + if (max_ratio > 5) {
  171430. + retval = -EINVAL;
  171431. + goto err;
  171432. + }
  171433. +
  171434. + temp = ipu_csi_read(ipu, csi, CSI_SKIP);
  171435. + temp &= ~(CSI_MAX_RATIO_SKIP_ISP_MASK | CSI_SKIP_ISP_MASK);
  171436. + temp |= (max_ratio << CSI_MAX_RATIO_SKIP_ISP_SHIFT) |
  171437. + (skip << CSI_SKIP_ISP_SHIFT);
  171438. + ipu_csi_write(ipu, csi, temp, CSI_SKIP);
  171439. +
  171440. +err:
  171441. + return retval;
  171442. +}
  171443. +
  171444. +/*!
  171445. + * _ipu_csi_set_skip_smfc
  171446. + *
  171447. + * @param ipu ipu handler
  171448. + * @param skip select frames to be skipped and set the
  171449. + * correspond bits to 1
  171450. + * @param max_ratio number of frames in a skipping set and the
  171451. + * maximum value of max_ratio is 5
  171452. + * @param id csi to smfc skipping id
  171453. + * @param csi csi 0 or csi 1
  171454. + *
  171455. + * @return Returns 0 on success or negative error code on fail
  171456. + */
  171457. +int _ipu_csi_set_skip_smfc(struct ipu_soc *ipu, uint32_t skip,
  171458. + uint32_t max_ratio, uint32_t id, uint32_t csi)
  171459. +{
  171460. + uint32_t temp;
  171461. + int retval = 0;
  171462. +
  171463. + if (max_ratio > 5 || id > 3) {
  171464. + retval = -EINVAL;
  171465. + goto err;
  171466. + }
  171467. +
  171468. + temp = ipu_csi_read(ipu, csi, CSI_SKIP);
  171469. + temp &= ~(CSI_MAX_RATIO_SKIP_SMFC_MASK | CSI_ID_2_SKIP_MASK |
  171470. + CSI_SKIP_SMFC_MASK);
  171471. + temp |= (max_ratio << CSI_MAX_RATIO_SKIP_SMFC_SHIFT) |
  171472. + (id << CSI_ID_2_SKIP_SHIFT) |
  171473. + (skip << CSI_SKIP_SMFC_SHIFT);
  171474. + ipu_csi_write(ipu, csi, temp, CSI_SKIP);
  171475. +
  171476. +err:
  171477. + return retval;
  171478. +}
  171479. +
  171480. +/*!
  171481. + * _ipu_smfc_init
  171482. + * Map CSI frames to IDMAC channels.
  171483. + *
  171484. + * @param ipu ipu handler
  171485. + * @param channel IDMAC channel 0-3
  171486. + * @param mipi_id mipi id number 0-3
  171487. + * @param csi csi0 or csi1
  171488. + */
  171489. +void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi)
  171490. +{
  171491. + uint32_t temp;
  171492. +
  171493. + temp = ipu_smfc_read(ipu, SMFC_MAP);
  171494. +
  171495. + switch (channel) {
  171496. + case CSI_MEM0:
  171497. + temp &= ~SMFC_MAP_CH0_MASK;
  171498. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH0_SHIFT;
  171499. + break;
  171500. + case CSI_MEM1:
  171501. + temp &= ~SMFC_MAP_CH1_MASK;
  171502. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH1_SHIFT;
  171503. + break;
  171504. + case CSI_MEM2:
  171505. + temp &= ~SMFC_MAP_CH2_MASK;
  171506. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH2_SHIFT;
  171507. + break;
  171508. + case CSI_MEM3:
  171509. + temp &= ~SMFC_MAP_CH3_MASK;
  171510. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH3_SHIFT;
  171511. + break;
  171512. + default:
  171513. + return;
  171514. + }
  171515. +
  171516. + ipu_smfc_write(ipu, temp, SMFC_MAP);
  171517. +}
  171518. +
  171519. +/*!
  171520. + * _ipu_smfc_set_wmc
  171521. + * Caution: The number of required channels, the enabled channels
  171522. + * and the FIFO size per channel are configured restrictedly.
  171523. + *
  171524. + * @param ipu ipu handler
  171525. + * @param channel IDMAC channel 0-3
  171526. + * @param set set 1 or clear 0
  171527. + * @param level water mark level when FIFO is on the
  171528. + * relative size
  171529. + */
  171530. +void _ipu_smfc_set_wmc(struct ipu_soc *ipu, ipu_channel_t channel, bool set, uint32_t level)
  171531. +{
  171532. + uint32_t temp;
  171533. +
  171534. + temp = ipu_smfc_read(ipu, SMFC_WMC);
  171535. +
  171536. + switch (channel) {
  171537. + case CSI_MEM0:
  171538. + if (set == true) {
  171539. + temp &= ~SMFC_WM0_SET_MASK;
  171540. + temp |= level << SMFC_WM0_SET_SHIFT;
  171541. + } else {
  171542. + temp &= ~SMFC_WM0_CLR_MASK;
  171543. + temp |= level << SMFC_WM0_CLR_SHIFT;
  171544. + }
  171545. + break;
  171546. + case CSI_MEM1:
  171547. + if (set == true) {
  171548. + temp &= ~SMFC_WM1_SET_MASK;
  171549. + temp |= level << SMFC_WM1_SET_SHIFT;
  171550. + } else {
  171551. + temp &= ~SMFC_WM1_CLR_MASK;
  171552. + temp |= level << SMFC_WM1_CLR_SHIFT;
  171553. + }
  171554. + break;
  171555. + case CSI_MEM2:
  171556. + if (set == true) {
  171557. + temp &= ~SMFC_WM2_SET_MASK;
  171558. + temp |= level << SMFC_WM2_SET_SHIFT;
  171559. + } else {
  171560. + temp &= ~SMFC_WM2_CLR_MASK;
  171561. + temp |= level << SMFC_WM2_CLR_SHIFT;
  171562. + }
  171563. + break;
  171564. + case CSI_MEM3:
  171565. + if (set == true) {
  171566. + temp &= ~SMFC_WM3_SET_MASK;
  171567. + temp |= level << SMFC_WM3_SET_SHIFT;
  171568. + } else {
  171569. + temp &= ~SMFC_WM3_CLR_MASK;
  171570. + temp |= level << SMFC_WM3_CLR_SHIFT;
  171571. + }
  171572. + break;
  171573. + default:
  171574. + return;
  171575. + }
  171576. +
  171577. + ipu_smfc_write(ipu, temp, SMFC_WMC);
  171578. +}
  171579. +
  171580. +/*!
  171581. + * _ipu_smfc_set_burst_size
  171582. + *
  171583. + * @param ipu ipu handler
  171584. + * @param channel IDMAC channel 0-3
  171585. + * @param bs burst size of IDMAC channel,
  171586. + * the value programmed here shoud be BURST_SIZE-1
  171587. + */
  171588. +void _ipu_smfc_set_burst_size(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t bs)
  171589. +{
  171590. + uint32_t temp;
  171591. +
  171592. + temp = ipu_smfc_read(ipu, SMFC_BS);
  171593. +
  171594. + switch (channel) {
  171595. + case CSI_MEM0:
  171596. + temp &= ~SMFC_BS0_MASK;
  171597. + temp |= bs << SMFC_BS0_SHIFT;
  171598. + break;
  171599. + case CSI_MEM1:
  171600. + temp &= ~SMFC_BS1_MASK;
  171601. + temp |= bs << SMFC_BS1_SHIFT;
  171602. + break;
  171603. + case CSI_MEM2:
  171604. + temp &= ~SMFC_BS2_MASK;
  171605. + temp |= bs << SMFC_BS2_SHIFT;
  171606. + break;
  171607. + case CSI_MEM3:
  171608. + temp &= ~SMFC_BS3_MASK;
  171609. + temp |= bs << SMFC_BS3_SHIFT;
  171610. + break;
  171611. + default:
  171612. + return;
  171613. + }
  171614. +
  171615. + ipu_smfc_write(ipu, temp, SMFC_BS);
  171616. +}
  171617. +
  171618. +/*!
  171619. + * _ipu_csi_init
  171620. + *
  171621. + * @param ipu ipu handler
  171622. + * @param channel IDMAC channel
  171623. + * @param csi csi 0 or csi 1
  171624. + *
  171625. + * @return Returns 0 on success or negative error code on fail
  171626. + */
  171627. +int _ipu_csi_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t csi)
  171628. +{
  171629. + uint32_t csi_sens_conf, csi_dest;
  171630. + int retval = 0;
  171631. +
  171632. + switch (channel) {
  171633. + case CSI_MEM0:
  171634. + case CSI_MEM1:
  171635. + case CSI_MEM2:
  171636. + case CSI_MEM3:
  171637. + csi_dest = CSI_DATA_DEST_IDMAC;
  171638. + break;
  171639. + case CSI_PRP_ENC_MEM:
  171640. + case CSI_PRP_VF_MEM:
  171641. + csi_dest = CSI_DATA_DEST_IC;
  171642. + break;
  171643. + default:
  171644. + retval = -EINVAL;
  171645. + goto err;
  171646. + }
  171647. +
  171648. + csi_sens_conf = ipu_csi_read(ipu, csi, CSI_SENS_CONF);
  171649. + csi_sens_conf &= ~CSI_SENS_CONF_DATA_DEST_MASK;
  171650. + ipu_csi_write(ipu, csi, csi_sens_conf | (csi_dest <<
  171651. + CSI_SENS_CONF_DATA_DEST_SHIFT), CSI_SENS_CONF);
  171652. +err:
  171653. + return retval;
  171654. +}
  171655. +
  171656. +/*!
  171657. + * csi_irq_handler
  171658. + *
  171659. + * @param irq interrupt id
  171660. + * @param dev_id pointer to ipu handler
  171661. + *
  171662. + * @return Returns if irq is handled
  171663. + */
  171664. +static irqreturn_t csi_irq_handler(int irq, void *dev_id)
  171665. +{
  171666. + struct ipu_soc *ipu = dev_id;
  171667. + struct completion *comp = &ipu->csi_comp;
  171668. +
  171669. + complete(comp);
  171670. + return IRQ_HANDLED;
  171671. +}
  171672. +
  171673. +/*!
  171674. + * _ipu_csi_wait4eof
  171675. + *
  171676. + * @param ipu ipu handler
  171677. + * @param channel IDMAC channel
  171678. + *
  171679. + */
  171680. +void _ipu_csi_wait4eof(struct ipu_soc *ipu, ipu_channel_t channel)
  171681. +{
  171682. + int ret;
  171683. + int irq = 0;
  171684. +
  171685. + if (channel == CSI_MEM0)
  171686. + irq = IPU_IRQ_CSI0_OUT_EOF;
  171687. + else if (channel == CSI_MEM1)
  171688. + irq = IPU_IRQ_CSI1_OUT_EOF;
  171689. + else if (channel == CSI_MEM2)
  171690. + irq = IPU_IRQ_CSI2_OUT_EOF;
  171691. + else if (channel == CSI_MEM3)
  171692. + irq = IPU_IRQ_CSI3_OUT_EOF;
  171693. + else if (channel == CSI_PRP_ENC_MEM)
  171694. + irq = IPU_IRQ_PRP_ENC_OUT_EOF;
  171695. + else if (channel == CSI_PRP_VF_MEM)
  171696. + irq = IPU_IRQ_PRP_VF_OUT_EOF;
  171697. + else{
  171698. + dev_err(ipu->dev, "Not a CSI channel\n");
  171699. + return;
  171700. + }
  171701. +
  171702. + init_completion(&ipu->csi_comp);
  171703. + ret = ipu_request_irq(ipu, irq, csi_irq_handler, 0, NULL, ipu);
  171704. + if (ret < 0) {
  171705. + dev_err(ipu->dev, "CSI irq %d in use\n", irq);
  171706. + return;
  171707. + }
  171708. + ret = wait_for_completion_timeout(&ipu->csi_comp, msecs_to_jiffies(500));
  171709. + ipu_free_irq(ipu, irq, ipu);
  171710. + dev_dbg(ipu->dev, "CSI stop timeout - %d * 10ms\n", 5 - ret);
  171711. +}
  171712. diff -Nur linux-3.14.15/drivers/mxc/ipu3/ipu_common.c linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_common.c
  171713. --- linux-3.14.15/drivers/mxc/ipu3/ipu_common.c 1970-01-01 01:00:00.000000000 +0100
  171714. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_common.c 2014-08-20 19:31:46.140869056 +0200
  171715. @@ -0,0 +1,3134 @@
  171716. +/*
  171717. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  171718. + */
  171719. +
  171720. +/*
  171721. + * The code contained herein is licensed under the GNU General Public
  171722. + * License. You may obtain a copy of the GNU General Public License
  171723. + * Version 2 or later at the following locations:
  171724. + *
  171725. + * http://www.opensource.org/licenses/gpl-license.html
  171726. + * http://www.gnu.org/copyleft/gpl.html
  171727. + */
  171728. +
  171729. +/*!
  171730. + * @file ipu_common.c
  171731. + *
  171732. + * @brief This file contains the IPU driver common API functions.
  171733. + *
  171734. + * @ingroup IPU
  171735. + */
  171736. +#include <linux/busfreq-imx6.h>
  171737. +#include <linux/clk.h>
  171738. +#include <linux/clk-provider.h>
  171739. +#include <linux/delay.h>
  171740. +#include <linux/err.h>
  171741. +#include <linux/init.h>
  171742. +#include <linux/interrupt.h>
  171743. +#include <linux/io.h>
  171744. +#include <linux/ipu-v3.h>
  171745. +#include <linux/irq.h>
  171746. +#include <linux/irqdesc.h>
  171747. +#include <linux/module.h>
  171748. +#include <linux/mod_devicetable.h>
  171749. +#include <linux/of_device.h>
  171750. +#include <linux/platform_device.h>
  171751. +#include <linux/pm_runtime.h>
  171752. +#include <linux/reset.h>
  171753. +#include <linux/spinlock.h>
  171754. +#include <linux/types.h>
  171755. +
  171756. +#include <asm/cacheflush.h>
  171757. +
  171758. +#include "ipu_param_mem.h"
  171759. +#include "ipu_regs.h"
  171760. +
  171761. +static struct ipu_soc ipu_array[MXC_IPU_MAX_NUM];
  171762. +int g_ipu_hw_rev;
  171763. +
  171764. +/* Static functions */
  171765. +static irqreturn_t ipu_sync_irq_handler(int irq, void *desc);
  171766. +static irqreturn_t ipu_err_irq_handler(int irq, void *desc);
  171767. +
  171768. +static inline uint32_t channel_2_dma(ipu_channel_t ch, ipu_buffer_t type)
  171769. +{
  171770. + return ((uint32_t) ch >> (6 * type)) & 0x3F;
  171771. +};
  171772. +
  171773. +static inline int _ipu_is_ic_chan(uint32_t dma_chan)
  171774. +{
  171775. + return (((dma_chan >= 11) && (dma_chan <= 22) && (dma_chan != 17) &&
  171776. + (dma_chan != 18)));
  171777. +}
  171778. +
  171779. +static inline int _ipu_is_vdi_out_chan(uint32_t dma_chan)
  171780. +{
  171781. + return (dma_chan == 5);
  171782. +}
  171783. +
  171784. +static inline int _ipu_is_ic_graphic_chan(uint32_t dma_chan)
  171785. +{
  171786. + return (dma_chan == 14 || dma_chan == 15);
  171787. +}
  171788. +
  171789. +/* Either DP BG or DP FG can be graphic window */
  171790. +static inline int _ipu_is_dp_graphic_chan(uint32_t dma_chan)
  171791. +{
  171792. + return (dma_chan == 23 || dma_chan == 27);
  171793. +}
  171794. +
  171795. +static inline int _ipu_is_irt_chan(uint32_t dma_chan)
  171796. +{
  171797. + return ((dma_chan >= 45) && (dma_chan <= 50));
  171798. +}
  171799. +
  171800. +static inline int _ipu_is_dmfc_chan(uint32_t dma_chan)
  171801. +{
  171802. + return ((dma_chan >= 23) && (dma_chan <= 29));
  171803. +}
  171804. +
  171805. +static inline int _ipu_is_smfc_chan(uint32_t dma_chan)
  171806. +{
  171807. + return ((dma_chan >= 0) && (dma_chan <= 3));
  171808. +}
  171809. +
  171810. +static inline int _ipu_is_trb_chan(uint32_t dma_chan)
  171811. +{
  171812. + return (((dma_chan == 8) || (dma_chan == 9) ||
  171813. + (dma_chan == 10) || (dma_chan == 13) ||
  171814. + (dma_chan == 21) || (dma_chan == 23) ||
  171815. + (dma_chan == 27) || (dma_chan == 28)) &&
  171816. + (g_ipu_hw_rev >= IPU_V3DEX));
  171817. +}
  171818. +
  171819. +/*
  171820. + * We usually use IDMAC 23 as full plane and IDMAC 27 as partial
  171821. + * plane.
  171822. + * IDMAC 23/24/28/41 can drive a display respectively - primary
  171823. + * IDMAC 27 depends on IDMAC 23 - nonprimary
  171824. + */
  171825. +static inline int _ipu_is_primary_disp_chan(uint32_t dma_chan)
  171826. +{
  171827. + return ((dma_chan == 23) || (dma_chan == 24) ||
  171828. + (dma_chan == 28) || (dma_chan == 41));
  171829. +}
  171830. +
  171831. +static inline int _ipu_is_sync_irq(uint32_t irq)
  171832. +{
  171833. + /* sync interrupt register number */
  171834. + int reg_num = irq / 32 + 1;
  171835. +
  171836. + return ((reg_num == 1) || (reg_num == 2) || (reg_num == 3) ||
  171837. + (reg_num == 4) || (reg_num == 7) || (reg_num == 8) ||
  171838. + (reg_num == 11) || (reg_num == 12) || (reg_num == 13) ||
  171839. + (reg_num == 14) || (reg_num == 15));
  171840. +}
  171841. +
  171842. +#define idma_is_valid(ch) (ch != NO_DMA)
  171843. +#define idma_mask(ch) (idma_is_valid(ch) ? (1UL << (ch & 0x1F)) : 0)
  171844. +#define idma_is_set(ipu, reg, dma) (ipu_idmac_read(ipu, reg(dma)) & idma_mask(dma))
  171845. +#define tri_cur_buf_mask(ch) (idma_mask(ch*2) * 3)
  171846. +#define tri_cur_buf_shift(ch) (ffs(idma_mask(ch*2)) - 1)
  171847. +
  171848. +static int ipu_clk_setup_enable(struct ipu_soc *ipu,
  171849. + struct ipu_pltfm_data *pdata)
  171850. +{
  171851. + char pixel_clk_0[] = "ipu1_pclk_0";
  171852. + char pixel_clk_1[] = "ipu1_pclk_1";
  171853. + char pixel_clk_0_sel[] = "ipu1_pclk0_sel";
  171854. + char pixel_clk_1_sel[] = "ipu1_pclk1_sel";
  171855. + char pixel_clk_0_div[] = "ipu1_pclk0_div";
  171856. + char pixel_clk_1_div[] = "ipu1_pclk1_div";
  171857. + char *ipu_pixel_clk_sel[] = { "ipu1", "ipu1_di0", "ipu1_di1", };
  171858. + char *pclk_sel;
  171859. + struct clk *clk;
  171860. + int ret;
  171861. + int i;
  171862. +
  171863. + pixel_clk_0[3] += pdata->id;
  171864. + pixel_clk_1[3] += pdata->id;
  171865. + pixel_clk_0_sel[3] += pdata->id;
  171866. + pixel_clk_1_sel[3] += pdata->id;
  171867. + pixel_clk_0_div[3] += pdata->id;
  171868. + pixel_clk_1_div[3] += pdata->id;
  171869. + for (i = 0; i < ARRAY_SIZE(ipu_pixel_clk_sel); i++) {
  171870. + pclk_sel = ipu_pixel_clk_sel[i];
  171871. + pclk_sel[3] += pdata->id;
  171872. + }
  171873. + dev_dbg(ipu->dev, "ipu_clk = %lu\n", clk_get_rate(ipu->ipu_clk));
  171874. +
  171875. + clk = clk_register_mux_pix_clk(ipu->dev, pixel_clk_0_sel,
  171876. + (const char **)ipu_pixel_clk_sel,
  171877. + ARRAY_SIZE(ipu_pixel_clk_sel),
  171878. + 0, pdata->id, 0, 0);
  171879. + if (IS_ERR(clk)) {
  171880. + dev_err(ipu->dev, "clk_register mux di0 failed");
  171881. + return PTR_ERR(clk);
  171882. + }
  171883. + ipu->pixel_clk_sel[0] = clk;
  171884. + clk = clk_register_mux_pix_clk(ipu->dev, pixel_clk_1_sel,
  171885. + (const char **)ipu_pixel_clk_sel,
  171886. + ARRAY_SIZE(ipu_pixel_clk_sel),
  171887. + 0, pdata->id, 1, 0);
  171888. + if (IS_ERR(clk)) {
  171889. + dev_err(ipu->dev, "clk_register mux di1 failed");
  171890. + return PTR_ERR(clk);
  171891. + }
  171892. + ipu->pixel_clk_sel[1] = clk;
  171893. +
  171894. + clk = clk_register_div_pix_clk(ipu->dev, pixel_clk_0_div,
  171895. + pixel_clk_0_sel, 0, pdata->id, 0, 0);
  171896. + if (IS_ERR(clk)) {
  171897. + dev_err(ipu->dev, "clk register di0 div failed");
  171898. + return PTR_ERR(clk);
  171899. + }
  171900. + clk = clk_register_div_pix_clk(ipu->dev, pixel_clk_1_div,
  171901. + pixel_clk_1_sel, CLK_SET_RATE_PARENT, pdata->id, 1, 0);
  171902. + if (IS_ERR(clk)) {
  171903. + dev_err(ipu->dev, "clk register di1 div failed");
  171904. + return PTR_ERR(clk);
  171905. + }
  171906. +
  171907. + ipu->pixel_clk[0] = clk_register_gate_pix_clk(ipu->dev, pixel_clk_0,
  171908. + pixel_clk_0_div, CLK_SET_RATE_PARENT,
  171909. + pdata->id, 0, 0);
  171910. + if (IS_ERR(ipu->pixel_clk[0])) {
  171911. + dev_err(ipu->dev, "clk register di0 gate failed");
  171912. + return PTR_ERR(ipu->pixel_clk[0]);
  171913. + }
  171914. + ipu->pixel_clk[1] = clk_register_gate_pix_clk(ipu->dev, pixel_clk_1,
  171915. + pixel_clk_1_div, CLK_SET_RATE_PARENT,
  171916. + pdata->id, 1, 0);
  171917. + if (IS_ERR(ipu->pixel_clk[1])) {
  171918. + dev_err(ipu->dev, "clk register di1 gate failed");
  171919. + return PTR_ERR(ipu->pixel_clk[1]);
  171920. + }
  171921. +
  171922. + ret = clk_set_parent(ipu->pixel_clk_sel[0], ipu->ipu_clk);
  171923. + if (ret) {
  171924. + dev_err(ipu->dev, "clk set parent failed");
  171925. + return ret;
  171926. + }
  171927. +
  171928. + ret = clk_set_parent(ipu->pixel_clk_sel[1], ipu->ipu_clk);
  171929. + if (ret) {
  171930. + dev_err(ipu->dev, "clk set parent failed");
  171931. + return ret;
  171932. + }
  171933. +
  171934. + ipu->di_clk[0] = devm_clk_get(ipu->dev, "di0");
  171935. + if (IS_ERR(ipu->di_clk[0])) {
  171936. + dev_err(ipu->dev, "clk_get di0 failed");
  171937. + return PTR_ERR(ipu->di_clk[0]);
  171938. + }
  171939. + ipu->di_clk[1] = devm_clk_get(ipu->dev, "di1");
  171940. + if (IS_ERR(ipu->di_clk[1])) {
  171941. + dev_err(ipu->dev, "clk_get di1 failed");
  171942. + return PTR_ERR(ipu->di_clk[1]);
  171943. + }
  171944. +
  171945. + ipu->di_clk_sel[0] = devm_clk_get(ipu->dev, "di0_sel");
  171946. + if (IS_ERR(ipu->di_clk_sel[0])) {
  171947. + dev_err(ipu->dev, "clk_get di0_sel failed");
  171948. + return PTR_ERR(ipu->di_clk_sel[0]);
  171949. + }
  171950. + ipu->di_clk_sel[1] = devm_clk_get(ipu->dev, "di1_sel");
  171951. + if (IS_ERR(ipu->di_clk_sel[1])) {
  171952. + dev_err(ipu->dev, "clk_get di1_sel failed");
  171953. + return PTR_ERR(ipu->di_clk_sel[1]);
  171954. + }
  171955. +
  171956. + return 0;
  171957. +}
  171958. +
  171959. +static int ipu_mem_reset(struct ipu_soc *ipu)
  171960. +{
  171961. + int timeout = 1000;
  171962. +
  171963. + ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST);
  171964. +
  171965. + while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) {
  171966. + if (!timeout--)
  171967. + return -ETIME;
  171968. + msleep(1);
  171969. + }
  171970. +
  171971. + return 0;
  171972. +}
  171973. +
  171974. +struct ipu_soc *ipu_get_soc(int id)
  171975. +{
  171976. + if (id >= MXC_IPU_MAX_NUM)
  171977. + return ERR_PTR(-ENODEV);
  171978. + else if (!ipu_array[id].online)
  171979. + return ERR_PTR(-ENODEV);
  171980. + else
  171981. + return &(ipu_array[id]);
  171982. +}
  171983. +EXPORT_SYMBOL_GPL(ipu_get_soc);
  171984. +
  171985. +void _ipu_get(struct ipu_soc *ipu)
  171986. +{
  171987. + int ret;
  171988. +
  171989. + ret = clk_enable(ipu->ipu_clk);
  171990. + if (ret < 0)
  171991. + BUG();
  171992. +}
  171993. +
  171994. +void _ipu_put(struct ipu_soc *ipu)
  171995. +{
  171996. + clk_disable(ipu->ipu_clk);
  171997. +}
  171998. +
  171999. +void ipu_disable_hsp_clk(struct ipu_soc *ipu)
  172000. +{
  172001. + _ipu_put(ipu);
  172002. +}
  172003. +EXPORT_SYMBOL(ipu_disable_hsp_clk);
  172004. +
  172005. +static struct platform_device_id imx_ipu_type[] = {
  172006. + {
  172007. + .name = "ipu-imx6q",
  172008. + .driver_data = IPU_V3H,
  172009. + }, {
  172010. + /* sentinel */
  172011. + }
  172012. +};
  172013. +MODULE_DEVICE_TABLE(platform, imx_ipu_type);
  172014. +
  172015. +static const struct of_device_id imx_ipuv3_dt_ids[] = {
  172016. + { .compatible = "fsl,imx6q-ipu", .data = &imx_ipu_type[IMX6Q_IPU], },
  172017. + { /* sentinel */ }
  172018. +};
  172019. +MODULE_DEVICE_TABLE(of, imx_ipuv3_dt_ids);
  172020. +
  172021. +/*!
  172022. + * This function is called by the driver framework to initialize the IPU
  172023. + * hardware.
  172024. + *
  172025. + * @param dev The device structure for the IPU passed in by the
  172026. + * driver framework.
  172027. + *
  172028. + * @return Returns 0 on success or negative error code on error
  172029. + */
  172030. +static int ipu_probe(struct platform_device *pdev)
  172031. +{
  172032. + struct ipu_soc *ipu;
  172033. + struct resource *res;
  172034. + unsigned long ipu_base;
  172035. + const struct of_device_id *of_id =
  172036. + of_match_device(imx_ipuv3_dt_ids, &pdev->dev);
  172037. + struct ipu_pltfm_data *pltfm_data;
  172038. + int ret = 0;
  172039. + u32 bypass_reset;
  172040. +
  172041. + dev_dbg(&pdev->dev, "<%s>\n", __func__);
  172042. +
  172043. + pltfm_data = devm_kzalloc(&pdev->dev, sizeof(struct ipu_pltfm_data),
  172044. + GFP_KERNEL);
  172045. + if (!pltfm_data)
  172046. + return -ENOMEM;
  172047. +
  172048. + ret = of_property_read_u32(pdev->dev.of_node,
  172049. + "bypass_reset", &bypass_reset);
  172050. + if (ret < 0) {
  172051. + dev_dbg(&pdev->dev, "can not get bypass_reset\n");
  172052. + return ret;
  172053. + }
  172054. + pltfm_data->bypass_reset = (bool)bypass_reset;
  172055. +
  172056. + pltfm_data->id = of_alias_get_id(pdev->dev.of_node, "ipu");
  172057. + if (pltfm_data->id < 0) {
  172058. + dev_dbg(&pdev->dev, "can not get alias id\n");
  172059. + return pltfm_data->id;
  172060. + }
  172061. +
  172062. + if (of_id)
  172063. + pdev->id_entry = of_id->data;
  172064. + pltfm_data->devtype = pdev->id_entry->driver_data;
  172065. + g_ipu_hw_rev = pltfm_data->devtype;
  172066. +
  172067. + ipu = &ipu_array[pltfm_data->id];
  172068. + memset(ipu, 0, sizeof(struct ipu_soc));
  172069. + ipu->dev = &pdev->dev;
  172070. + ipu->pdata = pltfm_data;
  172071. + dev_dbg(ipu->dev, "IPU rev:%d\n", g_ipu_hw_rev);
  172072. + spin_lock_init(&ipu->int_reg_spin_lock);
  172073. + spin_lock_init(&ipu->rdy_reg_spin_lock);
  172074. + mutex_init(&ipu->mutex_lock);
  172075. +
  172076. + ipu->irq_sync = platform_get_irq(pdev, 0);
  172077. + ipu->irq_err = platform_get_irq(pdev, 1);
  172078. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  172079. +
  172080. + if (!res || ipu->irq_sync < 0 || ipu->irq_err < 0) {
  172081. + dev_err(&pdev->dev, "can't get device resources\n");
  172082. + return -ENODEV;
  172083. + }
  172084. +
  172085. + if (!devm_request_mem_region(&pdev->dev, res->start,
  172086. + resource_size(res), pdev->name))
  172087. + return -EBUSY;
  172088. +
  172089. + ret = devm_request_irq(&pdev->dev, ipu->irq_sync,
  172090. + ipu_sync_irq_handler, 0, pdev->name, ipu);
  172091. + if (ret) {
  172092. + dev_err(ipu->dev, "request SYNC interrupt failed\n");
  172093. + return ret;
  172094. + }
  172095. + ret = devm_request_irq(&pdev->dev, ipu->irq_err,
  172096. + ipu_err_irq_handler, 0, pdev->name, ipu);
  172097. + if (ret) {
  172098. + dev_err(ipu->dev, "request ERR interrupt failed\n");
  172099. + return ret;
  172100. + }
  172101. +
  172102. + ipu_base = res->start;
  172103. + /* base fixup */
  172104. + if (g_ipu_hw_rev == IPU_V3H) /* IPUv3H */
  172105. + ipu_base += IPUV3H_REG_BASE;
  172106. + else if (g_ipu_hw_rev == IPU_V3M) /* IPUv3M */
  172107. + ipu_base += IPUV3M_REG_BASE;
  172108. + else /* IPUv3D, v3E, v3EX */
  172109. + ipu_base += IPUV3DEX_REG_BASE;
  172110. +
  172111. + ipu->cm_reg = devm_ioremap(&pdev->dev,
  172112. + ipu_base + IPU_CM_REG_BASE, PAGE_SIZE);
  172113. + ipu->ic_reg = devm_ioremap(&pdev->dev,
  172114. + ipu_base + IPU_IC_REG_BASE, PAGE_SIZE);
  172115. + ipu->idmac_reg = devm_ioremap(&pdev->dev,
  172116. + ipu_base + IPU_IDMAC_REG_BASE, PAGE_SIZE);
  172117. + /* DP Registers are accessed thru the SRM */
  172118. + ipu->dp_reg = devm_ioremap(&pdev->dev,
  172119. + ipu_base + IPU_SRM_REG_BASE, PAGE_SIZE);
  172120. + ipu->dc_reg = devm_ioremap(&pdev->dev,
  172121. + ipu_base + IPU_DC_REG_BASE, PAGE_SIZE);
  172122. + ipu->dmfc_reg = devm_ioremap(&pdev->dev,
  172123. + ipu_base + IPU_DMFC_REG_BASE, PAGE_SIZE);
  172124. + ipu->di_reg[0] = devm_ioremap(&pdev->dev,
  172125. + ipu_base + IPU_DI0_REG_BASE, PAGE_SIZE);
  172126. + ipu->di_reg[1] = devm_ioremap(&pdev->dev,
  172127. + ipu_base + IPU_DI1_REG_BASE, PAGE_SIZE);
  172128. + ipu->smfc_reg = devm_ioremap(&pdev->dev,
  172129. + ipu_base + IPU_SMFC_REG_BASE, PAGE_SIZE);
  172130. + ipu->csi_reg[0] = devm_ioremap(&pdev->dev,
  172131. + ipu_base + IPU_CSI0_REG_BASE, PAGE_SIZE);
  172132. + ipu->csi_reg[1] = devm_ioremap(&pdev->dev,
  172133. + ipu_base + IPU_CSI1_REG_BASE, PAGE_SIZE);
  172134. + ipu->cpmem_base = devm_ioremap(&pdev->dev,
  172135. + ipu_base + IPU_CPMEM_REG_BASE, SZ_128K);
  172136. + ipu->tpmem_base = devm_ioremap(&pdev->dev,
  172137. + ipu_base + IPU_TPM_REG_BASE, SZ_64K);
  172138. + ipu->dc_tmpl_reg = devm_ioremap(&pdev->dev,
  172139. + ipu_base + IPU_DC_TMPL_REG_BASE, SZ_128K);
  172140. + ipu->vdi_reg = devm_ioremap(&pdev->dev,
  172141. + ipu_base + IPU_VDI_REG_BASE, PAGE_SIZE);
  172142. + ipu->disp_base[1] = devm_ioremap(&pdev->dev,
  172143. + ipu_base + IPU_DISP1_BASE, SZ_4K);
  172144. + if (!ipu->cm_reg || !ipu->ic_reg || !ipu->idmac_reg ||
  172145. + !ipu->dp_reg || !ipu->dc_reg || !ipu->dmfc_reg ||
  172146. + !ipu->di_reg[0] || !ipu->di_reg[1] || !ipu->smfc_reg ||
  172147. + !ipu->csi_reg[0] || !ipu->csi_reg[1] || !ipu->cpmem_base ||
  172148. + !ipu->tpmem_base || !ipu->dc_tmpl_reg || !ipu->disp_base[1]
  172149. + || !ipu->vdi_reg)
  172150. + return -ENOMEM;
  172151. +
  172152. + dev_dbg(ipu->dev, "IPU CM Regs = %p\n", ipu->cm_reg);
  172153. + dev_dbg(ipu->dev, "IPU IC Regs = %p\n", ipu->ic_reg);
  172154. + dev_dbg(ipu->dev, "IPU IDMAC Regs = %p\n", ipu->idmac_reg);
  172155. + dev_dbg(ipu->dev, "IPU DP Regs = %p\n", ipu->dp_reg);
  172156. + dev_dbg(ipu->dev, "IPU DC Regs = %p\n", ipu->dc_reg);
  172157. + dev_dbg(ipu->dev, "IPU DMFC Regs = %p\n", ipu->dmfc_reg);
  172158. + dev_dbg(ipu->dev, "IPU DI0 Regs = %p\n", ipu->di_reg[0]);
  172159. + dev_dbg(ipu->dev, "IPU DI1 Regs = %p\n", ipu->di_reg[1]);
  172160. + dev_dbg(ipu->dev, "IPU SMFC Regs = %p\n", ipu->smfc_reg);
  172161. + dev_dbg(ipu->dev, "IPU CSI0 Regs = %p\n", ipu->csi_reg[0]);
  172162. + dev_dbg(ipu->dev, "IPU CSI1 Regs = %p\n", ipu->csi_reg[1]);
  172163. + dev_dbg(ipu->dev, "IPU CPMem = %p\n", ipu->cpmem_base);
  172164. + dev_dbg(ipu->dev, "IPU TPMem = %p\n", ipu->tpmem_base);
  172165. + dev_dbg(ipu->dev, "IPU DC Template Mem = %p\n", ipu->dc_tmpl_reg);
  172166. + dev_dbg(ipu->dev, "IPU Display Region 1 Mem = %p\n", ipu->disp_base[1]);
  172167. + dev_dbg(ipu->dev, "IPU VDI Regs = %p\n", ipu->vdi_reg);
  172168. +
  172169. + ipu->ipu_clk = devm_clk_get(ipu->dev, "bus");
  172170. + if (IS_ERR(ipu->ipu_clk)) {
  172171. + dev_err(ipu->dev, "clk_get ipu failed");
  172172. + return PTR_ERR(ipu->ipu_clk);
  172173. + }
  172174. +
  172175. + /* ipu_clk is always prepared */
  172176. + ret = clk_prepare_enable(ipu->ipu_clk);
  172177. + if (ret < 0) {
  172178. + dev_err(ipu->dev, "ipu clk enable failed\n");
  172179. + return ret;
  172180. + }
  172181. +
  172182. + ipu->online = true;
  172183. +
  172184. + platform_set_drvdata(pdev, ipu);
  172185. +
  172186. + if (!pltfm_data->bypass_reset) {
  172187. + ret = device_reset(&pdev->dev);
  172188. + if (ret) {
  172189. + dev_err(&pdev->dev, "failed to reset: %d\n", ret);
  172190. + return ret;
  172191. + }
  172192. +
  172193. + ipu_mem_reset(ipu);
  172194. +
  172195. + ipu_disp_init(ipu);
  172196. +
  172197. + /* Set MCU_T to divide MCU access window into 2 */
  172198. + ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18),
  172199. + IPU_DISP_GEN);
  172200. + }
  172201. +
  172202. + /* setup ipu clk tree after ipu reset */
  172203. + ret = ipu_clk_setup_enable(ipu, pltfm_data);
  172204. + if (ret < 0) {
  172205. + dev_err(ipu->dev, "ipu clk setup failed\n");
  172206. + ipu->online = false;
  172207. + return ret;
  172208. + }
  172209. +
  172210. + /* Set sync refresh channels and CSI->mem channel as high priority */
  172211. + ipu_idmac_write(ipu, 0x18800001L, IDMAC_CHA_PRI(0));
  172212. +
  172213. + /* Enable error interrupts by default */
  172214. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(5));
  172215. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(6));
  172216. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(9));
  172217. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(10));
  172218. +
  172219. + if (!pltfm_data->bypass_reset)
  172220. + clk_disable(ipu->ipu_clk);
  172221. +
  172222. + register_ipu_device(ipu, ipu->pdata->id);
  172223. +
  172224. + pm_runtime_enable(&pdev->dev);
  172225. +
  172226. + return ret;
  172227. +}
  172228. +
  172229. +int ipu_remove(struct platform_device *pdev)
  172230. +{
  172231. + struct ipu_soc *ipu = platform_get_drvdata(pdev);
  172232. +
  172233. + unregister_ipu_device(ipu, ipu->pdata->id);
  172234. +
  172235. + clk_put(ipu->ipu_clk);
  172236. +
  172237. + return 0;
  172238. +}
  172239. +
  172240. +void ipu_dump_registers(struct ipu_soc *ipu)
  172241. +{
  172242. + dev_dbg(ipu->dev, "IPU_CONF = \t0x%08X\n", ipu_cm_read(ipu, IPU_CONF));
  172243. + dev_dbg(ipu->dev, "IDMAC_CONF = \t0x%08X\n", ipu_idmac_read(ipu, IDMAC_CONF));
  172244. + dev_dbg(ipu->dev, "IDMAC_CHA_EN1 = \t0x%08X\n",
  172245. + ipu_idmac_read(ipu, IDMAC_CHA_EN(0)));
  172246. + dev_dbg(ipu->dev, "IDMAC_CHA_EN2 = \t0x%08X\n",
  172247. + ipu_idmac_read(ipu, IDMAC_CHA_EN(32)));
  172248. + dev_dbg(ipu->dev, "IDMAC_CHA_PRI1 = \t0x%08X\n",
  172249. + ipu_idmac_read(ipu, IDMAC_CHA_PRI(0)));
  172250. + dev_dbg(ipu->dev, "IDMAC_CHA_PRI2 = \t0x%08X\n",
  172251. + ipu_idmac_read(ipu, IDMAC_CHA_PRI(32)));
  172252. + dev_dbg(ipu->dev, "IDMAC_BAND_EN1 = \t0x%08X\n",
  172253. + ipu_idmac_read(ipu, IDMAC_BAND_EN(0)));
  172254. + dev_dbg(ipu->dev, "IDMAC_BAND_EN2 = \t0x%08X\n",
  172255. + ipu_idmac_read(ipu, IDMAC_BAND_EN(32)));
  172256. + dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n",
  172257. + ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(0)));
  172258. + dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n",
  172259. + ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(32)));
  172260. + if (g_ipu_hw_rev >= IPU_V3DEX) {
  172261. + dev_dbg(ipu->dev, "IPU_CHA_TRB_MODE_SEL0 = \t0x%08X\n",
  172262. + ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(0)));
  172263. + dev_dbg(ipu->dev, "IPU_CHA_TRB_MODE_SEL1 = \t0x%08X\n",
  172264. + ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(32)));
  172265. + }
  172266. + dev_dbg(ipu->dev, "DMFC_WR_CHAN = \t0x%08X\n",
  172267. + ipu_dmfc_read(ipu, DMFC_WR_CHAN));
  172268. + dev_dbg(ipu->dev, "DMFC_WR_CHAN_DEF = \t0x%08X\n",
  172269. + ipu_dmfc_read(ipu, DMFC_WR_CHAN_DEF));
  172270. + dev_dbg(ipu->dev, "DMFC_DP_CHAN = \t0x%08X\n",
  172271. + ipu_dmfc_read(ipu, DMFC_DP_CHAN));
  172272. + dev_dbg(ipu->dev, "DMFC_DP_CHAN_DEF = \t0x%08X\n",
  172273. + ipu_dmfc_read(ipu, DMFC_DP_CHAN_DEF));
  172274. + dev_dbg(ipu->dev, "DMFC_IC_CTRL = \t0x%08X\n",
  172275. + ipu_dmfc_read(ipu, DMFC_IC_CTRL));
  172276. + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW1 = \t0x%08X\n",
  172277. + ipu_cm_read(ipu, IPU_FS_PROC_FLOW1));
  172278. + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW2 = \t0x%08X\n",
  172279. + ipu_cm_read(ipu, IPU_FS_PROC_FLOW2));
  172280. + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW3 = \t0x%08X\n",
  172281. + ipu_cm_read(ipu, IPU_FS_PROC_FLOW3));
  172282. + dev_dbg(ipu->dev, "IPU_FS_DISP_FLOW1 = \t0x%08X\n",
  172283. + ipu_cm_read(ipu, IPU_FS_DISP_FLOW1));
  172284. + dev_dbg(ipu->dev, "IPU_VDIC_VDI_FSIZE = \t0x%08X\n",
  172285. + ipu_vdi_read(ipu, VDI_FSIZE));
  172286. + dev_dbg(ipu->dev, "IPU_VDIC_VDI_C = \t0x%08X\n",
  172287. + ipu_vdi_read(ipu, VDI_C));
  172288. + dev_dbg(ipu->dev, "IPU_IC_CONF = \t0x%08X\n",
  172289. + ipu_ic_read(ipu, IC_CONF));
  172290. +}
  172291. +
  172292. +/*!
  172293. + * This function is called to initialize a logical IPU channel.
  172294. + *
  172295. + * @param ipu ipu handler
  172296. + * @param channel Input parameter for the logical channel ID to init.
  172297. + *
  172298. + * @param params Input parameter containing union of channel
  172299. + * initialization parameters.
  172300. + *
  172301. + * @return Returns 0 on success or negative error code on fail
  172302. + */
  172303. +int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params)
  172304. +{
  172305. + int ret = 0;
  172306. + bool bad_pixfmt;
  172307. + uint32_t ipu_conf, reg, in_g_pixel_fmt, sec_dma;
  172308. +
  172309. + dev_dbg(ipu->dev, "init channel = %d\n", IPU_CHAN_ID(channel));
  172310. +
  172311. + ret = pm_runtime_get_sync(ipu->dev);
  172312. + if (ret < 0) {
  172313. + dev_err(ipu->dev, "ch = %d, pm_runtime_get failed:%d!\n",
  172314. + IPU_CHAN_ID(channel), ret);
  172315. + dump_stack();
  172316. + return ret;
  172317. + }
  172318. + /*
  172319. + * Here, ret could be 1 if the device's runtime PM status was
  172320. + * already 'active', so clear it to be 0.
  172321. + */
  172322. + ret = 0;
  172323. +
  172324. + _ipu_get(ipu);
  172325. +
  172326. + mutex_lock(&ipu->mutex_lock);
  172327. +
  172328. + /* Re-enable error interrupts every time a channel is initialized */
  172329. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(5));
  172330. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(6));
  172331. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(9));
  172332. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(10));
  172333. +
  172334. + if (ipu->channel_init_mask & (1L << IPU_CHAN_ID(channel))) {
  172335. + dev_warn(ipu->dev, "Warning: channel already initialized %d\n",
  172336. + IPU_CHAN_ID(channel));
  172337. + }
  172338. +
  172339. + ipu_conf = ipu_cm_read(ipu, IPU_CONF);
  172340. +
  172341. + switch (channel) {
  172342. + case CSI_MEM0:
  172343. + case CSI_MEM1:
  172344. + case CSI_MEM2:
  172345. + case CSI_MEM3:
  172346. + if (params->csi_mem.csi > 1) {
  172347. + ret = -EINVAL;
  172348. + goto err;
  172349. + }
  172350. +
  172351. + if (params->csi_mem.interlaced)
  172352. + ipu->chan_is_interlaced[channel_2_dma(channel,
  172353. + IPU_OUTPUT_BUFFER)] = true;
  172354. + else
  172355. + ipu->chan_is_interlaced[channel_2_dma(channel,
  172356. + IPU_OUTPUT_BUFFER)] = false;
  172357. +
  172358. + ipu->smfc_use_count++;
  172359. + ipu->csi_channel[params->csi_mem.csi] = channel;
  172360. +
  172361. + /*SMFC setting*/
  172362. + if (params->csi_mem.mipi_en) {
  172363. + ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172364. + params->csi_mem.csi));
  172365. + _ipu_smfc_init(ipu, channel, params->csi_mem.mipi_vc,
  172366. + params->csi_mem.csi);
  172367. + _ipu_csi_set_mipi_di(ipu, params->csi_mem.mipi_vc,
  172368. + params->csi_mem.mipi_id, params->csi_mem.csi);
  172369. + } else {
  172370. + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172371. + params->csi_mem.csi));
  172372. + _ipu_smfc_init(ipu, channel, 0, params->csi_mem.csi);
  172373. + }
  172374. +
  172375. + /*CSI data (include compander) dest*/
  172376. + _ipu_csi_init(ipu, channel, params->csi_mem.csi);
  172377. + break;
  172378. + case CSI_PRP_ENC_MEM:
  172379. + if (params->csi_prp_enc_mem.csi > 1) {
  172380. + ret = -EINVAL;
  172381. + goto err;
  172382. + }
  172383. + if ((ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
  172384. + (ipu->using_ic_dirct_ch == MEM_VDI_MEM)) {
  172385. + ret = -EINVAL;
  172386. + goto err;
  172387. + }
  172388. + ipu->using_ic_dirct_ch = CSI_PRP_ENC_MEM;
  172389. +
  172390. + ipu->ic_use_count++;
  172391. + ipu->csi_channel[params->csi_prp_enc_mem.csi] = channel;
  172392. +
  172393. + if (params->csi_prp_enc_mem.mipi_en) {
  172394. + ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172395. + params->csi_prp_enc_mem.csi));
  172396. + _ipu_csi_set_mipi_di(ipu,
  172397. + params->csi_prp_enc_mem.mipi_vc,
  172398. + params->csi_prp_enc_mem.mipi_id,
  172399. + params->csi_prp_enc_mem.csi);
  172400. + } else
  172401. + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172402. + params->csi_prp_enc_mem.csi));
  172403. +
  172404. + /*CSI0/1 feed into IC*/
  172405. + ipu_conf &= ~IPU_CONF_IC_INPUT;
  172406. + if (params->csi_prp_enc_mem.csi)
  172407. + ipu_conf |= IPU_CONF_CSI_SEL;
  172408. + else
  172409. + ipu_conf &= ~IPU_CONF_CSI_SEL;
  172410. +
  172411. + /*PRP skip buffer in memory, only valid when RWS_EN is true*/
  172412. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172413. + ipu_cm_write(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
  172414. +
  172415. + /*CSI data (include compander) dest*/
  172416. + _ipu_csi_init(ipu, channel, params->csi_prp_enc_mem.csi);
  172417. + _ipu_ic_init_prpenc(ipu, params, true);
  172418. + break;
  172419. + case CSI_PRP_VF_MEM:
  172420. + if (params->csi_prp_vf_mem.csi > 1) {
  172421. + ret = -EINVAL;
  172422. + goto err;
  172423. + }
  172424. + if ((ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
  172425. + (ipu->using_ic_dirct_ch == MEM_VDI_MEM)) {
  172426. + ret = -EINVAL;
  172427. + goto err;
  172428. + }
  172429. + ipu->using_ic_dirct_ch = CSI_PRP_VF_MEM;
  172430. +
  172431. + ipu->ic_use_count++;
  172432. + ipu->csi_channel[params->csi_prp_vf_mem.csi] = channel;
  172433. +
  172434. + if (params->csi_prp_vf_mem.mipi_en) {
  172435. + ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172436. + params->csi_prp_vf_mem.csi));
  172437. + _ipu_csi_set_mipi_di(ipu,
  172438. + params->csi_prp_vf_mem.mipi_vc,
  172439. + params->csi_prp_vf_mem.mipi_id,
  172440. + params->csi_prp_vf_mem.csi);
  172441. + } else
  172442. + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172443. + params->csi_prp_vf_mem.csi));
  172444. +
  172445. + /*CSI0/1 feed into IC*/
  172446. + ipu_conf &= ~IPU_CONF_IC_INPUT;
  172447. + if (params->csi_prp_vf_mem.csi)
  172448. + ipu_conf |= IPU_CONF_CSI_SEL;
  172449. + else
  172450. + ipu_conf &= ~IPU_CONF_CSI_SEL;
  172451. +
  172452. + /*PRP skip buffer in memory, only valid when RWS_EN is true*/
  172453. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172454. + ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  172455. +
  172456. + /*CSI data (include compander) dest*/
  172457. + _ipu_csi_init(ipu, channel, params->csi_prp_vf_mem.csi);
  172458. + _ipu_ic_init_prpvf(ipu, params, true);
  172459. + break;
  172460. + case MEM_PRP_VF_MEM:
  172461. + if (params->mem_prp_vf_mem.graphics_combine_en) {
  172462. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  172463. + in_g_pixel_fmt = params->mem_prp_vf_mem.in_g_pixel_fmt;
  172464. + bad_pixfmt =
  172465. + _ipu_ch_param_bad_alpha_pos(in_g_pixel_fmt);
  172466. +
  172467. + if (params->mem_prp_vf_mem.alpha_chan_en) {
  172468. + if (bad_pixfmt) {
  172469. + dev_err(ipu->dev, "bad pixel format "
  172470. + "for graphics plane from "
  172471. + "ch%d\n", sec_dma);
  172472. + ret = -EINVAL;
  172473. + goto err;
  172474. + }
  172475. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  172476. + }
  172477. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
  172478. + }
  172479. +
  172480. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172481. + ipu_cm_write(ipu, reg | FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  172482. +
  172483. + _ipu_ic_init_prpvf(ipu, params, false);
  172484. + ipu->ic_use_count++;
  172485. + break;
  172486. + case MEM_VDI_PRP_VF_MEM:
  172487. + if ((ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM) ||
  172488. + (ipu->using_ic_dirct_ch == MEM_VDI_MEM) ||
  172489. + (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)) {
  172490. + ret = -EINVAL;
  172491. + goto err;
  172492. + }
  172493. + ipu->using_ic_dirct_ch = MEM_VDI_PRP_VF_MEM;
  172494. + ipu->ic_use_count++;
  172495. + ipu->vdi_use_count++;
  172496. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172497. + reg &= ~FS_VDI_SRC_SEL_MASK;
  172498. + ipu_cm_write(ipu, reg , IPU_FS_PROC_FLOW1);
  172499. +
  172500. + if (params->mem_prp_vf_mem.graphics_combine_en)
  172501. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
  172502. + _ipu_ic_init_prpvf(ipu, params, false);
  172503. + _ipu_vdi_init(ipu, channel, params);
  172504. + break;
  172505. + case MEM_VDI_PRP_VF_MEM_P:
  172506. + case MEM_VDI_PRP_VF_MEM_N:
  172507. + case MEM_VDI_MEM_P:
  172508. + case MEM_VDI_MEM_N:
  172509. + _ipu_vdi_init(ipu, channel, params);
  172510. + break;
  172511. + case MEM_VDI_MEM:
  172512. + if ((ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM) ||
  172513. + (ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
  172514. + (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)) {
  172515. + ret = -EINVAL;
  172516. + goto err;
  172517. + }
  172518. + ipu->using_ic_dirct_ch = MEM_VDI_MEM;
  172519. + ipu->ic_use_count++;
  172520. + ipu->vdi_use_count++;
  172521. + _ipu_vdi_init(ipu, channel, params);
  172522. + break;
  172523. + case MEM_ROT_VF_MEM:
  172524. + ipu->ic_use_count++;
  172525. + ipu->rot_use_count++;
  172526. + _ipu_ic_init_rotate_vf(ipu, params);
  172527. + break;
  172528. + case MEM_PRP_ENC_MEM:
  172529. + ipu->ic_use_count++;
  172530. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172531. + ipu_cm_write(ipu, reg | FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
  172532. + _ipu_ic_init_prpenc(ipu, params, false);
  172533. + break;
  172534. + case MEM_ROT_ENC_MEM:
  172535. + ipu->ic_use_count++;
  172536. + ipu->rot_use_count++;
  172537. + _ipu_ic_init_rotate_enc(ipu, params);
  172538. + break;
  172539. + case MEM_PP_MEM:
  172540. + if (params->mem_pp_mem.graphics_combine_en) {
  172541. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  172542. + in_g_pixel_fmt = params->mem_pp_mem.in_g_pixel_fmt;
  172543. + bad_pixfmt =
  172544. + _ipu_ch_param_bad_alpha_pos(in_g_pixel_fmt);
  172545. +
  172546. + if (params->mem_pp_mem.alpha_chan_en) {
  172547. + if (bad_pixfmt) {
  172548. + dev_err(ipu->dev, "bad pixel format "
  172549. + "for graphics plane from "
  172550. + "ch%d\n", sec_dma);
  172551. + ret = -EINVAL;
  172552. + goto err;
  172553. + }
  172554. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  172555. + }
  172556. +
  172557. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
  172558. + }
  172559. +
  172560. + _ipu_ic_init_pp(ipu, params);
  172561. + ipu->ic_use_count++;
  172562. + break;
  172563. + case MEM_ROT_PP_MEM:
  172564. + _ipu_ic_init_rotate_pp(ipu, params);
  172565. + ipu->ic_use_count++;
  172566. + ipu->rot_use_count++;
  172567. + break;
  172568. + case MEM_DC_SYNC:
  172569. + if (params->mem_dc_sync.di > 1) {
  172570. + ret = -EINVAL;
  172571. + goto err;
  172572. + }
  172573. +
  172574. + ipu->dc_di_assignment[1] = params->mem_dc_sync.di;
  172575. + _ipu_dc_init(ipu, 1, params->mem_dc_sync.di,
  172576. + params->mem_dc_sync.interlaced,
  172577. + params->mem_dc_sync.out_pixel_fmt);
  172578. + ipu->di_use_count[params->mem_dc_sync.di]++;
  172579. + ipu->dc_use_count++;
  172580. + ipu->dmfc_use_count++;
  172581. + break;
  172582. + case MEM_BG_SYNC:
  172583. + if (params->mem_dp_bg_sync.di > 1) {
  172584. + ret = -EINVAL;
  172585. + goto err;
  172586. + }
  172587. +
  172588. + if (params->mem_dp_bg_sync.alpha_chan_en)
  172589. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  172590. +
  172591. + ipu->dc_di_assignment[5] = params->mem_dp_bg_sync.di;
  172592. + _ipu_dp_init(ipu, channel, params->mem_dp_bg_sync.in_pixel_fmt,
  172593. + params->mem_dp_bg_sync.out_pixel_fmt);
  172594. + _ipu_dc_init(ipu, 5, params->mem_dp_bg_sync.di,
  172595. + params->mem_dp_bg_sync.interlaced,
  172596. + params->mem_dp_bg_sync.out_pixel_fmt);
  172597. + ipu->di_use_count[params->mem_dp_bg_sync.di]++;
  172598. + ipu->dc_use_count++;
  172599. + ipu->dp_use_count++;
  172600. + ipu->dmfc_use_count++;
  172601. + break;
  172602. + case MEM_FG_SYNC:
  172603. + _ipu_dp_init(ipu, channel, params->mem_dp_fg_sync.in_pixel_fmt,
  172604. + params->mem_dp_fg_sync.out_pixel_fmt);
  172605. +
  172606. + if (params->mem_dp_fg_sync.alpha_chan_en)
  172607. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  172608. +
  172609. + ipu->dc_use_count++;
  172610. + ipu->dp_use_count++;
  172611. + ipu->dmfc_use_count++;
  172612. + break;
  172613. + case DIRECT_ASYNC0:
  172614. + if (params->direct_async.di > 1) {
  172615. + ret = -EINVAL;
  172616. + goto err;
  172617. + }
  172618. +
  172619. + ipu->dc_di_assignment[8] = params->direct_async.di;
  172620. + _ipu_dc_init(ipu, 8, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
  172621. + ipu->di_use_count[params->direct_async.di]++;
  172622. + ipu->dc_use_count++;
  172623. + break;
  172624. + case DIRECT_ASYNC1:
  172625. + if (params->direct_async.di > 1) {
  172626. + ret = -EINVAL;
  172627. + goto err;
  172628. + }
  172629. +
  172630. + ipu->dc_di_assignment[9] = params->direct_async.di;
  172631. + _ipu_dc_init(ipu, 9, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
  172632. + ipu->di_use_count[params->direct_async.di]++;
  172633. + ipu->dc_use_count++;
  172634. + break;
  172635. + default:
  172636. + dev_err(ipu->dev, "Missing channel initialization\n");
  172637. + break;
  172638. + }
  172639. +
  172640. + ipu->channel_init_mask |= 1L << IPU_CHAN_ID(channel);
  172641. +
  172642. + ipu_cm_write(ipu, ipu_conf, IPU_CONF);
  172643. +
  172644. +err:
  172645. + mutex_unlock(&ipu->mutex_lock);
  172646. + return ret;
  172647. +}
  172648. +EXPORT_SYMBOL(ipu_init_channel);
  172649. +
  172650. +/*!
  172651. + * This function is called to uninitialize a logical IPU channel.
  172652. + *
  172653. + * @param ipu ipu handler
  172654. + * @param channel Input parameter for the logical channel ID to uninit.
  172655. + */
  172656. +void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel)
  172657. +{
  172658. + uint32_t reg;
  172659. + uint32_t in_dma, out_dma = 0;
  172660. + uint32_t ipu_conf;
  172661. + uint32_t dc_chan = 0;
  172662. + int ret;
  172663. +
  172664. + mutex_lock(&ipu->mutex_lock);
  172665. +
  172666. + if ((ipu->channel_init_mask & (1L << IPU_CHAN_ID(channel))) == 0) {
  172667. + dev_dbg(ipu->dev, "Channel already uninitialized %d\n",
  172668. + IPU_CHAN_ID(channel));
  172669. + mutex_unlock(&ipu->mutex_lock);
  172670. + return;
  172671. + }
  172672. +
  172673. + /* Make sure channel is disabled */
  172674. + /* Get input and output dma channels */
  172675. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  172676. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  172677. +
  172678. + if (idma_is_set(ipu, IDMAC_CHA_EN, in_dma) ||
  172679. + idma_is_set(ipu, IDMAC_CHA_EN, out_dma)) {
  172680. + dev_err(ipu->dev,
  172681. + "Channel %d is not disabled, disable first\n",
  172682. + IPU_CHAN_ID(channel));
  172683. + mutex_unlock(&ipu->mutex_lock);
  172684. + return;
  172685. + }
  172686. +
  172687. + ipu_conf = ipu_cm_read(ipu, IPU_CONF);
  172688. +
  172689. + /* Reset the double buffer */
  172690. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(in_dma));
  172691. + ipu_cm_write(ipu, reg & ~idma_mask(in_dma), IPU_CHA_DB_MODE_SEL(in_dma));
  172692. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(out_dma));
  172693. + ipu_cm_write(ipu, reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma));
  172694. +
  172695. + /* Reset the triple buffer */
  172696. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(in_dma));
  172697. + ipu_cm_write(ipu, reg & ~idma_mask(in_dma), IPU_CHA_TRB_MODE_SEL(in_dma));
  172698. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(out_dma));
  172699. + ipu_cm_write(ipu, reg & ~idma_mask(out_dma), IPU_CHA_TRB_MODE_SEL(out_dma));
  172700. +
  172701. + if (_ipu_is_ic_chan(in_dma) || _ipu_is_dp_graphic_chan(in_dma)) {
  172702. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = false;
  172703. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = false;
  172704. + }
  172705. +
  172706. + switch (channel) {
  172707. + case CSI_MEM0:
  172708. + case CSI_MEM1:
  172709. + case CSI_MEM2:
  172710. + case CSI_MEM3:
  172711. + ipu->smfc_use_count--;
  172712. + if (ipu->csi_channel[0] == channel) {
  172713. + ipu->csi_channel[0] = CHAN_NONE;
  172714. + } else if (ipu->csi_channel[1] == channel) {
  172715. + ipu->csi_channel[1] = CHAN_NONE;
  172716. + }
  172717. + break;
  172718. + case CSI_PRP_ENC_MEM:
  172719. + ipu->ic_use_count--;
  172720. + if (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)
  172721. + ipu->using_ic_dirct_ch = 0;
  172722. + _ipu_ic_uninit_prpenc(ipu);
  172723. + if (ipu->csi_channel[0] == channel) {
  172724. + ipu->csi_channel[0] = CHAN_NONE;
  172725. + } else if (ipu->csi_channel[1] == channel) {
  172726. + ipu->csi_channel[1] = CHAN_NONE;
  172727. + }
  172728. + break;
  172729. + case CSI_PRP_VF_MEM:
  172730. + ipu->ic_use_count--;
  172731. + if (ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM)
  172732. + ipu->using_ic_dirct_ch = 0;
  172733. + _ipu_ic_uninit_prpvf(ipu);
  172734. + if (ipu->csi_channel[0] == channel) {
  172735. + ipu->csi_channel[0] = CHAN_NONE;
  172736. + } else if (ipu->csi_channel[1] == channel) {
  172737. + ipu->csi_channel[1] = CHAN_NONE;
  172738. + }
  172739. + break;
  172740. + case MEM_PRP_VF_MEM:
  172741. + ipu->ic_use_count--;
  172742. + _ipu_ic_uninit_prpvf(ipu);
  172743. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172744. + ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  172745. + break;
  172746. + case MEM_VDI_PRP_VF_MEM:
  172747. + ipu->ic_use_count--;
  172748. + ipu->vdi_use_count--;
  172749. + if (ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM)
  172750. + ipu->using_ic_dirct_ch = 0;
  172751. + _ipu_ic_uninit_prpvf(ipu);
  172752. + _ipu_vdi_uninit(ipu);
  172753. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172754. + ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  172755. + break;
  172756. + case MEM_VDI_MEM:
  172757. + ipu->ic_use_count--;
  172758. + ipu->vdi_use_count--;
  172759. + if (ipu->using_ic_dirct_ch == MEM_VDI_MEM)
  172760. + ipu->using_ic_dirct_ch = 0;
  172761. + _ipu_vdi_uninit(ipu);
  172762. + break;
  172763. + case MEM_VDI_PRP_VF_MEM_P:
  172764. + case MEM_VDI_PRP_VF_MEM_N:
  172765. + case MEM_VDI_MEM_P:
  172766. + case MEM_VDI_MEM_N:
  172767. + break;
  172768. + case MEM_ROT_VF_MEM:
  172769. + ipu->rot_use_count--;
  172770. + ipu->ic_use_count--;
  172771. + _ipu_ic_uninit_rotate_vf(ipu);
  172772. + break;
  172773. + case MEM_PRP_ENC_MEM:
  172774. + ipu->ic_use_count--;
  172775. + _ipu_ic_uninit_prpenc(ipu);
  172776. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172777. + ipu_cm_write(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
  172778. + break;
  172779. + case MEM_ROT_ENC_MEM:
  172780. + ipu->rot_use_count--;
  172781. + ipu->ic_use_count--;
  172782. + _ipu_ic_uninit_rotate_enc(ipu);
  172783. + break;
  172784. + case MEM_PP_MEM:
  172785. + ipu->ic_use_count--;
  172786. + _ipu_ic_uninit_pp(ipu);
  172787. + break;
  172788. + case MEM_ROT_PP_MEM:
  172789. + ipu->rot_use_count--;
  172790. + ipu->ic_use_count--;
  172791. + _ipu_ic_uninit_rotate_pp(ipu);
  172792. + break;
  172793. + case MEM_DC_SYNC:
  172794. + dc_chan = 1;
  172795. + _ipu_dc_uninit(ipu, 1);
  172796. + ipu->di_use_count[ipu->dc_di_assignment[1]]--;
  172797. + ipu->dc_use_count--;
  172798. + ipu->dmfc_use_count--;
  172799. + break;
  172800. + case MEM_BG_SYNC:
  172801. + dc_chan = 5;
  172802. + _ipu_dp_uninit(ipu, channel);
  172803. + _ipu_dc_uninit(ipu, 5);
  172804. + ipu->di_use_count[ipu->dc_di_assignment[5]]--;
  172805. + ipu->dc_use_count--;
  172806. + ipu->dp_use_count--;
  172807. + ipu->dmfc_use_count--;
  172808. + break;
  172809. + case MEM_FG_SYNC:
  172810. + _ipu_dp_uninit(ipu, channel);
  172811. + ipu->dc_use_count--;
  172812. + ipu->dp_use_count--;
  172813. + ipu->dmfc_use_count--;
  172814. + break;
  172815. + case DIRECT_ASYNC0:
  172816. + dc_chan = 8;
  172817. + _ipu_dc_uninit(ipu, 8);
  172818. + ipu->di_use_count[ipu->dc_di_assignment[8]]--;
  172819. + ipu->dc_use_count--;
  172820. + break;
  172821. + case DIRECT_ASYNC1:
  172822. + dc_chan = 9;
  172823. + _ipu_dc_uninit(ipu, 9);
  172824. + ipu->di_use_count[ipu->dc_di_assignment[9]]--;
  172825. + ipu->dc_use_count--;
  172826. + break;
  172827. + default:
  172828. + break;
  172829. + }
  172830. +
  172831. + if (ipu->ic_use_count == 0)
  172832. + ipu_conf &= ~IPU_CONF_IC_EN;
  172833. + if (ipu->vdi_use_count == 0) {
  172834. + ipu_conf &= ~IPU_CONF_ISP_EN;
  172835. + ipu_conf &= ~IPU_CONF_VDI_EN;
  172836. + ipu_conf &= ~IPU_CONF_IC_INPUT;
  172837. + }
  172838. + if (ipu->rot_use_count == 0)
  172839. + ipu_conf &= ~IPU_CONF_ROT_EN;
  172840. + if (ipu->dc_use_count == 0)
  172841. + ipu_conf &= ~IPU_CONF_DC_EN;
  172842. + if (ipu->dp_use_count == 0)
  172843. + ipu_conf &= ~IPU_CONF_DP_EN;
  172844. + if (ipu->dmfc_use_count == 0)
  172845. + ipu_conf &= ~IPU_CONF_DMFC_EN;
  172846. + if (ipu->di_use_count[0] == 0) {
  172847. + ipu_conf &= ~IPU_CONF_DI0_EN;
  172848. + }
  172849. + if (ipu->di_use_count[1] == 0) {
  172850. + ipu_conf &= ~IPU_CONF_DI1_EN;
  172851. + }
  172852. + if (ipu->smfc_use_count == 0)
  172853. + ipu_conf &= ~IPU_CONF_SMFC_EN;
  172854. +
  172855. + ipu_cm_write(ipu, ipu_conf, IPU_CONF);
  172856. +
  172857. + ipu->channel_init_mask &= ~(1L << IPU_CHAN_ID(channel));
  172858. +
  172859. + /*
  172860. + * Disable pixel clk and its parent clock(if the parent clock
  172861. + * usecount is 1) after clearing DC/DP/DI bits in IPU_CONF
  172862. + * register to prevent LVDS display channel starvation.
  172863. + */
  172864. + if (_ipu_is_primary_disp_chan(in_dma))
  172865. + clk_disable_unprepare(ipu->pixel_clk[ipu->dc_di_assignment[dc_chan]]);
  172866. +
  172867. + mutex_unlock(&ipu->mutex_lock);
  172868. +
  172869. + _ipu_put(ipu);
  172870. +
  172871. + ret = pm_runtime_put_sync_suspend(ipu->dev);
  172872. + if (ret < 0) {
  172873. + dev_err(ipu->dev, "ch = %d, pm_runtime_put failed:%d!\n",
  172874. + IPU_CHAN_ID(channel), ret);
  172875. + dump_stack();
  172876. + }
  172877. +
  172878. + WARN_ON(ipu->ic_use_count < 0);
  172879. + WARN_ON(ipu->vdi_use_count < 0);
  172880. + WARN_ON(ipu->rot_use_count < 0);
  172881. + WARN_ON(ipu->dc_use_count < 0);
  172882. + WARN_ON(ipu->dp_use_count < 0);
  172883. + WARN_ON(ipu->dmfc_use_count < 0);
  172884. + WARN_ON(ipu->smfc_use_count < 0);
  172885. +}
  172886. +EXPORT_SYMBOL(ipu_uninit_channel);
  172887. +
  172888. +/*!
  172889. + * This function is called to initialize buffer(s) for logical IPU channel.
  172890. + *
  172891. + * @param ipu ipu handler
  172892. + *
  172893. + * @param channel Input parameter for the logical channel ID.
  172894. + *
  172895. + * @param type Input parameter which buffer to initialize.
  172896. + *
  172897. + * @param pixel_fmt Input parameter for pixel format of buffer.
  172898. + * Pixel format is a FOURCC ASCII code.
  172899. + *
  172900. + * @param width Input parameter for width of buffer in pixels.
  172901. + *
  172902. + * @param height Input parameter for height of buffer in pixels.
  172903. + *
  172904. + * @param stride Input parameter for stride length of buffer
  172905. + * in pixels.
  172906. + *
  172907. + * @param rot_mode Input parameter for rotation setting of buffer.
  172908. + * A rotation setting other than
  172909. + * IPU_ROTATE_VERT_FLIP
  172910. + * should only be used for input buffers of
  172911. + * rotation channels.
  172912. + *
  172913. + * @param phyaddr_0 Input parameter buffer 0 physical address.
  172914. + *
  172915. + * @param phyaddr_1 Input parameter buffer 1 physical address.
  172916. + * Setting this to a value other than NULL enables
  172917. + * double buffering mode.
  172918. + *
  172919. + * @param phyaddr_2 Input parameter buffer 2 physical address.
  172920. + * Setting this to a value other than NULL enables
  172921. + * triple buffering mode, phyaddr_1 should not be
  172922. + * NULL then.
  172923. + *
  172924. + * @param u private u offset for additional cropping,
  172925. + * zero if not used.
  172926. + *
  172927. + * @param v private v offset for additional cropping,
  172928. + * zero if not used.
  172929. + *
  172930. + * @return Returns 0 on success or negative error code on fail
  172931. + */
  172932. +int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  172933. + ipu_buffer_t type,
  172934. + uint32_t pixel_fmt,
  172935. + uint16_t width, uint16_t height,
  172936. + uint32_t stride,
  172937. + ipu_rotate_mode_t rot_mode,
  172938. + dma_addr_t phyaddr_0, dma_addr_t phyaddr_1,
  172939. + dma_addr_t phyaddr_2,
  172940. + uint32_t u, uint32_t v)
  172941. +{
  172942. + uint32_t reg;
  172943. + uint32_t dma_chan;
  172944. + uint32_t burst_size;
  172945. +
  172946. + dma_chan = channel_2_dma(channel, type);
  172947. + if (!idma_is_valid(dma_chan))
  172948. + return -EINVAL;
  172949. +
  172950. + if (stride < width * bytes_per_pixel(pixel_fmt))
  172951. + stride = width * bytes_per_pixel(pixel_fmt);
  172952. +
  172953. + if (stride % 4) {
  172954. + dev_err(ipu->dev,
  172955. + "Stride not 32-bit aligned, stride = %d\n", stride);
  172956. + return -EINVAL;
  172957. + }
  172958. + /* IC & IRT channels' width must be multiple of 8 pixels */
  172959. + if ((_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan))
  172960. + && (width % 8)) {
  172961. + dev_err(ipu->dev, "Width must be 8 pixel multiple\n");
  172962. + return -EINVAL;
  172963. + }
  172964. +
  172965. + if (_ipu_is_vdi_out_chan(dma_chan) &&
  172966. + ((width < 16) || (height < 16) || (width % 2) || (height % 4))) {
  172967. + dev_err(ipu->dev, "vdi width/height limited err\n");
  172968. + return -EINVAL;
  172969. + }
  172970. +
  172971. + /* IPUv3EX and IPUv3M support triple buffer */
  172972. + if ((!_ipu_is_trb_chan(dma_chan)) && phyaddr_2) {
  172973. + dev_err(ipu->dev, "Chan%d doesn't support triple buffer "
  172974. + "mode\n", dma_chan);
  172975. + return -EINVAL;
  172976. + }
  172977. + if (!phyaddr_1 && phyaddr_2) {
  172978. + dev_err(ipu->dev, "Chan%d's buf1 physical addr is NULL for "
  172979. + "triple buffer mode\n", dma_chan);
  172980. + return -EINVAL;
  172981. + }
  172982. +
  172983. + mutex_lock(&ipu->mutex_lock);
  172984. +
  172985. + /* Build parameter memory data for DMA channel */
  172986. + _ipu_ch_param_init(ipu, dma_chan, pixel_fmt, width, height, stride, u, v, 0,
  172987. + phyaddr_0, phyaddr_1, phyaddr_2);
  172988. +
  172989. + /* Set correlative channel parameter of local alpha channel */
  172990. + if ((_ipu_is_ic_graphic_chan(dma_chan) ||
  172991. + _ipu_is_dp_graphic_chan(dma_chan)) &&
  172992. + (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] == true)) {
  172993. + _ipu_ch_param_set_alpha_use_separate_channel(ipu, dma_chan, true);
  172994. + _ipu_ch_param_set_alpha_buffer_memory(ipu, dma_chan);
  172995. + _ipu_ch_param_set_alpha_condition_read(ipu, dma_chan);
  172996. + /* fix alpha width as 8 and burst size as 16*/
  172997. + _ipu_ch_params_set_alpha_width(ipu, dma_chan, 8);
  172998. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 16);
  172999. + } else if (_ipu_is_ic_graphic_chan(dma_chan) &&
  173000. + ipu_pixel_format_has_alpha(pixel_fmt))
  173001. + _ipu_ch_param_set_alpha_use_separate_channel(ipu, dma_chan, false);
  173002. +
  173003. + if (rot_mode)
  173004. + _ipu_ch_param_set_rotation(ipu, dma_chan, rot_mode);
  173005. +
  173006. + /* IC and ROT channels have restriction of 8 or 16 pix burst length */
  173007. + if (_ipu_is_ic_chan(dma_chan) || _ipu_is_vdi_out_chan(dma_chan)) {
  173008. + if ((width % 16) == 0)
  173009. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 16);
  173010. + else
  173011. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 8);
  173012. + } else if (_ipu_is_irt_chan(dma_chan)) {
  173013. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 8);
  173014. + _ipu_ch_param_set_block_mode(ipu, dma_chan);
  173015. + } else if (_ipu_is_dmfc_chan(dma_chan)) {
  173016. + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
  173017. + _ipu_dmfc_set_wait4eot(ipu, dma_chan, width);
  173018. + _ipu_dmfc_set_burst_size(ipu, dma_chan, burst_size);
  173019. + }
  173020. +
  173021. + if (_ipu_disp_chan_is_interlaced(ipu, channel) ||
  173022. + ipu->chan_is_interlaced[dma_chan])
  173023. + _ipu_ch_param_set_interlaced_scan(ipu, dma_chan);
  173024. +
  173025. + if (_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan) ||
  173026. + _ipu_is_vdi_out_chan(dma_chan)) {
  173027. + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
  173028. + _ipu_ic_idma_init(ipu, dma_chan, width, height, burst_size,
  173029. + rot_mode);
  173030. + } else if (_ipu_is_smfc_chan(dma_chan)) {
  173031. + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
  173032. + /*
  173033. + * This is different from IPUv3 spec, but it is confirmed
  173034. + * in IPUforum that SMFC burst size should be NPB[6:3]
  173035. + * when IDMAC works in 16-bit generic data mode.
  173036. + */
  173037. + if (pixel_fmt == IPU_PIX_FMT_GENERIC)
  173038. + /* 8 bits per pixel */
  173039. + burst_size = burst_size >> 4;
  173040. + else if (pixel_fmt == IPU_PIX_FMT_GENERIC_16)
  173041. + /* 16 bits per pixel */
  173042. + burst_size = burst_size >> 3;
  173043. + else
  173044. + burst_size = burst_size >> 2;
  173045. + _ipu_smfc_set_burst_size(ipu, channel, burst_size-1);
  173046. + }
  173047. +
  173048. + /* AXI-id */
  173049. + if (idma_is_set(ipu, IDMAC_CHA_PRI, dma_chan)) {
  173050. + unsigned reg = IDMAC_CH_LOCK_EN_1;
  173051. + uint32_t value = 0;
  173052. + if (ipu->pdata->devtype == IPU_V3H) {
  173053. + _ipu_ch_param_set_axi_id(ipu, dma_chan, 0);
  173054. + switch (dma_chan) {
  173055. + case 5:
  173056. + value = 0x3;
  173057. + break;
  173058. + case 11:
  173059. + value = 0x3 << 2;
  173060. + break;
  173061. + case 12:
  173062. + value = 0x3 << 4;
  173063. + break;
  173064. + case 14:
  173065. + value = 0x3 << 6;
  173066. + break;
  173067. + case 15:
  173068. + value = 0x3 << 8;
  173069. + break;
  173070. + case 20:
  173071. + value = 0x3 << 10;
  173072. + break;
  173073. + case 21:
  173074. + value = 0x3 << 12;
  173075. + break;
  173076. + case 22:
  173077. + value = 0x3 << 14;
  173078. + break;
  173079. + case 23:
  173080. + value = 0x3 << 16;
  173081. + break;
  173082. + case 27:
  173083. + value = 0x3 << 18;
  173084. + break;
  173085. + case 28:
  173086. + value = 0x3 << 20;
  173087. + break;
  173088. + case 45:
  173089. + reg = IDMAC_CH_LOCK_EN_2;
  173090. + value = 0x3 << 0;
  173091. + break;
  173092. + case 46:
  173093. + reg = IDMAC_CH_LOCK_EN_2;
  173094. + value = 0x3 << 2;
  173095. + break;
  173096. + case 47:
  173097. + reg = IDMAC_CH_LOCK_EN_2;
  173098. + value = 0x3 << 4;
  173099. + break;
  173100. + case 48:
  173101. + reg = IDMAC_CH_LOCK_EN_2;
  173102. + value = 0x3 << 6;
  173103. + break;
  173104. + case 49:
  173105. + reg = IDMAC_CH_LOCK_EN_2;
  173106. + value = 0x3 << 8;
  173107. + break;
  173108. + case 50:
  173109. + reg = IDMAC_CH_LOCK_EN_2;
  173110. + value = 0x3 << 10;
  173111. + break;
  173112. + default:
  173113. + break;
  173114. + }
  173115. + value |= ipu_idmac_read(ipu, reg);
  173116. + ipu_idmac_write(ipu, value, reg);
  173117. + } else
  173118. + _ipu_ch_param_set_axi_id(ipu, dma_chan, 1);
  173119. + } else {
  173120. + if (ipu->pdata->devtype == IPU_V3H)
  173121. + _ipu_ch_param_set_axi_id(ipu, dma_chan, 1);
  173122. + }
  173123. +
  173124. + _ipu_ch_param_dump(ipu, dma_chan);
  173125. +
  173126. + if (phyaddr_2 && g_ipu_hw_rev >= IPU_V3DEX) {
  173127. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(dma_chan));
  173128. + reg &= ~idma_mask(dma_chan);
  173129. + ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(dma_chan));
  173130. +
  173131. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan));
  173132. + reg |= idma_mask(dma_chan);
  173133. + ipu_cm_write(ipu, reg, IPU_CHA_TRB_MODE_SEL(dma_chan));
  173134. +
  173135. + /* Set IDMAC third buffer's cpmem number */
  173136. + /* See __ipu_ch_get_third_buf_cpmem_num() for mapping */
  173137. + ipu_idmac_write(ipu, 0x00444047L, IDMAC_SUB_ADDR_4);
  173138. + ipu_idmac_write(ipu, 0x46004241L, IDMAC_SUB_ADDR_3);
  173139. + ipu_idmac_write(ipu, 0x00000045L, IDMAC_SUB_ADDR_1);
  173140. +
  173141. + /* Reset to buffer 0 */
  173142. + ipu_cm_write(ipu, tri_cur_buf_mask(dma_chan),
  173143. + IPU_CHA_TRIPLE_CUR_BUF(dma_chan));
  173144. + } else {
  173145. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan));
  173146. + reg &= ~idma_mask(dma_chan);
  173147. + ipu_cm_write(ipu, reg, IPU_CHA_TRB_MODE_SEL(dma_chan));
  173148. +
  173149. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(dma_chan));
  173150. + if (phyaddr_1)
  173151. + reg |= idma_mask(dma_chan);
  173152. + else
  173153. + reg &= ~idma_mask(dma_chan);
  173154. + ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(dma_chan));
  173155. +
  173156. + /* Reset to buffer 0 */
  173157. + ipu_cm_write(ipu, idma_mask(dma_chan),
  173158. + IPU_CHA_CUR_BUF(dma_chan));
  173159. +
  173160. + }
  173161. +
  173162. + mutex_unlock(&ipu->mutex_lock);
  173163. +
  173164. + return 0;
  173165. +}
  173166. +EXPORT_SYMBOL(ipu_init_channel_buffer);
  173167. +
  173168. +/*!
  173169. + * This function is called to update the physical address of a buffer for
  173170. + * a logical IPU channel.
  173171. + *
  173172. + * @param ipu ipu handler
  173173. + * @param channel Input parameter for the logical channel ID.
  173174. + *
  173175. + * @param type Input parameter which buffer to initialize.
  173176. + *
  173177. + * @param bufNum Input parameter for buffer number to update.
  173178. + * 0 or 1 are the only valid values.
  173179. + *
  173180. + * @param phyaddr Input parameter buffer physical address.
  173181. + *
  173182. + * @return This function returns 0 on success or negative error code on
  173183. + * fail. This function will fail if the buffer is set to ready.
  173184. + */
  173185. +int32_t ipu_update_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  173186. + ipu_buffer_t type, uint32_t bufNum, dma_addr_t phyaddr)
  173187. +{
  173188. + uint32_t reg;
  173189. + int ret = 0;
  173190. + uint32_t dma_chan = channel_2_dma(channel, type);
  173191. + unsigned long lock_flags;
  173192. +
  173193. + if (dma_chan == IDMA_CHAN_INVALID)
  173194. + return -EINVAL;
  173195. +
  173196. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173197. + if (bufNum == 0)
  173198. + reg = ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan));
  173199. + else if (bufNum == 1)
  173200. + reg = ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan));
  173201. + else
  173202. + reg = ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan));
  173203. +
  173204. + if ((reg & idma_mask(dma_chan)) == 0)
  173205. + _ipu_ch_param_set_buffer(ipu, dma_chan, bufNum, phyaddr);
  173206. + else
  173207. + ret = -EACCES;
  173208. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173209. +
  173210. + return ret;
  173211. +}
  173212. +EXPORT_SYMBOL(ipu_update_channel_buffer);
  173213. +
  173214. +/*!
  173215. + * This function is called to update the band mode setting for
  173216. + * a logical IPU channel.
  173217. + *
  173218. + * @param ipu ipu handler
  173219. + *
  173220. + * @param channel Input parameter for the logical channel ID.
  173221. + *
  173222. + * @param type Input parameter which buffer to initialize.
  173223. + *
  173224. + * @param band_height Input parameter for band lines:
  173225. + * shoule be log2(4/8/16/32/64/128/256).
  173226. + *
  173227. + * @return This function returns 0 on success or negative error code on
  173228. + * fail.
  173229. + */
  173230. +int32_t ipu_set_channel_bandmode(struct ipu_soc *ipu, ipu_channel_t channel,
  173231. + ipu_buffer_t type, uint32_t band_height)
  173232. +{
  173233. + uint32_t reg;
  173234. + int ret = 0;
  173235. + uint32_t dma_chan = channel_2_dma(channel, type);
  173236. +
  173237. + if ((2 > band_height) || (8 < band_height))
  173238. + return -EINVAL;
  173239. +
  173240. + mutex_lock(&ipu->mutex_lock);
  173241. +
  173242. + reg = ipu_idmac_read(ipu, IDMAC_BAND_EN(dma_chan));
  173243. + reg |= 1 << (dma_chan % 32);
  173244. + ipu_idmac_write(ipu, reg, IDMAC_BAND_EN(dma_chan));
  173245. +
  173246. + _ipu_ch_param_set_bandmode(ipu, dma_chan, band_height);
  173247. + dev_dbg(ipu->dev, "dma_chan:%d, band_height:%d.\n\n",
  173248. + dma_chan, 1 << band_height);
  173249. + mutex_unlock(&ipu->mutex_lock);
  173250. +
  173251. + return ret;
  173252. +}
  173253. +EXPORT_SYMBOL(ipu_set_channel_bandmode);
  173254. +
  173255. +/*!
  173256. + * This function is called to initialize a buffer for logical IPU channel.
  173257. + *
  173258. + * @param ipu ipu handler
  173259. + * @param channel Input parameter for the logical channel ID.
  173260. + *
  173261. + * @param type Input parameter which buffer to initialize.
  173262. + *
  173263. + * @param pixel_fmt Input parameter for pixel format of buffer.
  173264. + * Pixel format is a FOURCC ASCII code.
  173265. + *
  173266. + * @param width Input parameter for width of buffer in pixels.
  173267. + *
  173268. + * @param height Input parameter for height of buffer in pixels.
  173269. + *
  173270. + * @param stride Input parameter for stride length of buffer
  173271. + * in pixels.
  173272. + *
  173273. + * @param u predefined private u offset for additional cropping,
  173274. + * zero if not used.
  173275. + *
  173276. + * @param v predefined private v offset for additional cropping,
  173277. + * zero if not used.
  173278. + *
  173279. + * @param vertical_offset vertical offset for Y coordinate
  173280. + * in the existed frame
  173281. + *
  173282. + *
  173283. + * @param horizontal_offset horizontal offset for X coordinate
  173284. + * in the existed frame
  173285. + *
  173286. + *
  173287. + * @return Returns 0 on success or negative error code on fail
  173288. + * This function will fail if any buffer is set to ready.
  173289. + */
  173290. +
  173291. +int32_t ipu_update_channel_offset(struct ipu_soc *ipu,
  173292. + ipu_channel_t channel, ipu_buffer_t type,
  173293. + uint32_t pixel_fmt,
  173294. + uint16_t width, uint16_t height,
  173295. + uint32_t stride,
  173296. + uint32_t u, uint32_t v,
  173297. + uint32_t vertical_offset, uint32_t horizontal_offset)
  173298. +{
  173299. + int ret = 0;
  173300. + uint32_t dma_chan = channel_2_dma(channel, type);
  173301. + unsigned long lock_flags;
  173302. +
  173303. + if (dma_chan == IDMA_CHAN_INVALID)
  173304. + return -EINVAL;
  173305. +
  173306. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173307. + if ((ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan)) & idma_mask(dma_chan)) ||
  173308. + (ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan)) & idma_mask(dma_chan)) ||
  173309. + ((ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan)) & idma_mask(dma_chan)) &&
  173310. + (ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan)) & idma_mask(dma_chan)) &&
  173311. + _ipu_is_trb_chan(dma_chan)))
  173312. + ret = -EACCES;
  173313. + else
  173314. + _ipu_ch_offset_update(ipu, dma_chan, pixel_fmt, width, height, stride,
  173315. + u, v, 0, vertical_offset, horizontal_offset);
  173316. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173317. +
  173318. + return ret;
  173319. +}
  173320. +EXPORT_SYMBOL(ipu_update_channel_offset);
  173321. +
  173322. +
  173323. +/*!
  173324. + * This function is called to set a channel's buffer as ready.
  173325. + *
  173326. + * @param ipu ipu handler
  173327. + * @param channel Input parameter for the logical channel ID.
  173328. + *
  173329. + * @param type Input parameter which buffer to initialize.
  173330. + *
  173331. + * @param bufNum Input parameter for which buffer number set to
  173332. + * ready state.
  173333. + *
  173334. + * @return Returns 0 on success or negative error code on fail
  173335. + */
  173336. +int32_t ipu_select_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  173337. + ipu_buffer_t type, uint32_t bufNum)
  173338. +{
  173339. + uint32_t dma_chan = channel_2_dma(channel, type);
  173340. + unsigned long lock_flags;
  173341. +
  173342. + if (dma_chan == IDMA_CHAN_INVALID)
  173343. + return -EINVAL;
  173344. +
  173345. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173346. + /* Mark buffer to be ready. */
  173347. + if (bufNum == 0)
  173348. + ipu_cm_write(ipu, idma_mask(dma_chan),
  173349. + IPU_CHA_BUF0_RDY(dma_chan));
  173350. + else if (bufNum == 1)
  173351. + ipu_cm_write(ipu, idma_mask(dma_chan),
  173352. + IPU_CHA_BUF1_RDY(dma_chan));
  173353. + else
  173354. + ipu_cm_write(ipu, idma_mask(dma_chan),
  173355. + IPU_CHA_BUF2_RDY(dma_chan));
  173356. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173357. +
  173358. + return 0;
  173359. +}
  173360. +EXPORT_SYMBOL(ipu_select_buffer);
  173361. +
  173362. +/*!
  173363. + * This function is called to set a channel's buffer as ready.
  173364. + *
  173365. + * @param ipu ipu handler
  173366. + * @param bufNum Input parameter for which buffer number set to
  173367. + * ready state.
  173368. + *
  173369. + * @return Returns 0 on success or negative error code on fail
  173370. + */
  173371. +int32_t ipu_select_multi_vdi_buffer(struct ipu_soc *ipu, uint32_t bufNum)
  173372. +{
  173373. +
  173374. + uint32_t dma_chan = channel_2_dma(MEM_VDI_PRP_VF_MEM, IPU_INPUT_BUFFER);
  173375. + uint32_t mask_bit =
  173376. + idma_mask(channel_2_dma(MEM_VDI_PRP_VF_MEM_P, IPU_INPUT_BUFFER))|
  173377. + idma_mask(dma_chan)|
  173378. + idma_mask(channel_2_dma(MEM_VDI_PRP_VF_MEM_N, IPU_INPUT_BUFFER));
  173379. + unsigned long lock_flags;
  173380. +
  173381. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173382. + /* Mark buffers to be ready. */
  173383. + if (bufNum == 0)
  173384. + ipu_cm_write(ipu, mask_bit, IPU_CHA_BUF0_RDY(dma_chan));
  173385. + else
  173386. + ipu_cm_write(ipu, mask_bit, IPU_CHA_BUF1_RDY(dma_chan));
  173387. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173388. +
  173389. + return 0;
  173390. +}
  173391. +EXPORT_SYMBOL(ipu_select_multi_vdi_buffer);
  173392. +
  173393. +#define NA -1
  173394. +static int proc_dest_sel[] = {
  173395. + 0, 1, 1, 3, 5, 5, 4, 7, 8, 9, 10, 11, 12, 14, 15, 16,
  173396. + 0, 1, 1, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 14, 31 };
  173397. +static int proc_src_sel[] = { 0, 6, 7, 6, 7, 8, 5, NA, NA, NA,
  173398. + NA, NA, NA, NA, NA, 1, 2, 3, 4, 7, 8, NA, 8, NA };
  173399. +static int disp_src_sel[] = { 0, 6, 7, 8, 3, 4, 5, NA, NA, NA,
  173400. + NA, NA, NA, NA, NA, 1, NA, 2, NA, 3, 4, 4, 4, 4 };
  173401. +
  173402. +
  173403. +/*!
  173404. + * This function links 2 channels together for automatic frame
  173405. + * synchronization. The output of the source channel is linked to the input of
  173406. + * the destination channel.
  173407. + *
  173408. + * @param ipu ipu handler
  173409. + * @param src_ch Input parameter for the logical channel ID of
  173410. + * the source channel.
  173411. + *
  173412. + * @param dest_ch Input parameter for the logical channel ID of
  173413. + * the destination channel.
  173414. + *
  173415. + * @return This function returns 0 on success or negative error code on
  173416. + * fail.
  173417. + */
  173418. +int32_t ipu_link_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch)
  173419. +{
  173420. + int retval = 0;
  173421. + uint32_t fs_proc_flow1;
  173422. + uint32_t fs_proc_flow2;
  173423. + uint32_t fs_proc_flow3;
  173424. + uint32_t fs_disp_flow1;
  173425. +
  173426. + mutex_lock(&ipu->mutex_lock);
  173427. +
  173428. + fs_proc_flow1 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  173429. + fs_proc_flow2 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW2);
  173430. + fs_proc_flow3 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW3);
  173431. + fs_disp_flow1 = ipu_cm_read(ipu, IPU_FS_DISP_FLOW1);
  173432. +
  173433. + switch (src_ch) {
  173434. + case CSI_MEM0:
  173435. + fs_proc_flow3 &= ~FS_SMFC0_DEST_SEL_MASK;
  173436. + fs_proc_flow3 |=
  173437. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173438. + FS_SMFC0_DEST_SEL_OFFSET;
  173439. + break;
  173440. + case CSI_MEM1:
  173441. + fs_proc_flow3 &= ~FS_SMFC1_DEST_SEL_MASK;
  173442. + fs_proc_flow3 |=
  173443. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173444. + FS_SMFC1_DEST_SEL_OFFSET;
  173445. + break;
  173446. + case CSI_MEM2:
  173447. + fs_proc_flow3 &= ~FS_SMFC2_DEST_SEL_MASK;
  173448. + fs_proc_flow3 |=
  173449. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173450. + FS_SMFC2_DEST_SEL_OFFSET;
  173451. + break;
  173452. + case CSI_MEM3:
  173453. + fs_proc_flow3 &= ~FS_SMFC3_DEST_SEL_MASK;
  173454. + fs_proc_flow3 |=
  173455. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173456. + FS_SMFC3_DEST_SEL_OFFSET;
  173457. + break;
  173458. + case CSI_PRP_ENC_MEM:
  173459. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  173460. + fs_proc_flow2 |=
  173461. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173462. + FS_PRPENC_DEST_SEL_OFFSET;
  173463. + break;
  173464. + case CSI_PRP_VF_MEM:
  173465. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173466. + fs_proc_flow2 |=
  173467. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173468. + FS_PRPVF_DEST_SEL_OFFSET;
  173469. + break;
  173470. + case MEM_PP_MEM:
  173471. + fs_proc_flow2 &= ~FS_PP_DEST_SEL_MASK;
  173472. + fs_proc_flow2 |=
  173473. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173474. + FS_PP_DEST_SEL_OFFSET;
  173475. + break;
  173476. + case MEM_ROT_PP_MEM:
  173477. + fs_proc_flow2 &= ~FS_PP_ROT_DEST_SEL_MASK;
  173478. + fs_proc_flow2 |=
  173479. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173480. + FS_PP_ROT_DEST_SEL_OFFSET;
  173481. + break;
  173482. + case MEM_PRP_ENC_MEM:
  173483. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  173484. + fs_proc_flow2 |=
  173485. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173486. + FS_PRPENC_DEST_SEL_OFFSET;
  173487. + break;
  173488. + case MEM_ROT_ENC_MEM:
  173489. + fs_proc_flow2 &= ~FS_PRPENC_ROT_DEST_SEL_MASK;
  173490. + fs_proc_flow2 |=
  173491. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173492. + FS_PRPENC_ROT_DEST_SEL_OFFSET;
  173493. + break;
  173494. + case MEM_PRP_VF_MEM:
  173495. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173496. + fs_proc_flow2 |=
  173497. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173498. + FS_PRPVF_DEST_SEL_OFFSET;
  173499. + break;
  173500. + case MEM_VDI_PRP_VF_MEM:
  173501. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173502. + fs_proc_flow2 |=
  173503. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173504. + FS_PRPVF_DEST_SEL_OFFSET;
  173505. + break;
  173506. + case MEM_ROT_VF_MEM:
  173507. + fs_proc_flow2 &= ~FS_PRPVF_ROT_DEST_SEL_MASK;
  173508. + fs_proc_flow2 |=
  173509. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173510. + FS_PRPVF_ROT_DEST_SEL_OFFSET;
  173511. + break;
  173512. + case MEM_VDOA_MEM:
  173513. + fs_proc_flow3 &= ~FS_VDOA_DEST_SEL_MASK;
  173514. + if (MEM_VDI_MEM == dest_ch)
  173515. + fs_proc_flow3 |= FS_VDOA_DEST_SEL_VDI;
  173516. + else if (MEM_PP_MEM == dest_ch)
  173517. + fs_proc_flow3 |= FS_VDOA_DEST_SEL_IC;
  173518. + else {
  173519. + retval = -EINVAL;
  173520. + goto err;
  173521. + }
  173522. + break;
  173523. + default:
  173524. + retval = -EINVAL;
  173525. + goto err;
  173526. + }
  173527. +
  173528. + switch (dest_ch) {
  173529. + case MEM_PP_MEM:
  173530. + fs_proc_flow1 &= ~FS_PP_SRC_SEL_MASK;
  173531. + if (MEM_VDOA_MEM == src_ch)
  173532. + fs_proc_flow1 |= FS_PP_SRC_SEL_VDOA;
  173533. + else
  173534. + fs_proc_flow1 |= proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  173535. + FS_PP_SRC_SEL_OFFSET;
  173536. + break;
  173537. + case MEM_ROT_PP_MEM:
  173538. + fs_proc_flow1 &= ~FS_PP_ROT_SRC_SEL_MASK;
  173539. + fs_proc_flow1 |=
  173540. + proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  173541. + FS_PP_ROT_SRC_SEL_OFFSET;
  173542. + break;
  173543. + case MEM_PRP_ENC_MEM:
  173544. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173545. + fs_proc_flow1 |=
  173546. + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
  173547. + break;
  173548. + case MEM_ROT_ENC_MEM:
  173549. + fs_proc_flow1 &= ~FS_PRPENC_ROT_SRC_SEL_MASK;
  173550. + fs_proc_flow1 |=
  173551. + proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  173552. + FS_PRPENC_ROT_SRC_SEL_OFFSET;
  173553. + break;
  173554. + case MEM_PRP_VF_MEM:
  173555. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173556. + fs_proc_flow1 |=
  173557. + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
  173558. + break;
  173559. + case MEM_VDI_PRP_VF_MEM:
  173560. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173561. + fs_proc_flow1 |=
  173562. + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
  173563. + break;
  173564. + case MEM_ROT_VF_MEM:
  173565. + fs_proc_flow1 &= ~FS_PRPVF_ROT_SRC_SEL_MASK;
  173566. + fs_proc_flow1 |=
  173567. + proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  173568. + FS_PRPVF_ROT_SRC_SEL_OFFSET;
  173569. + break;
  173570. + case MEM_DC_SYNC:
  173571. + fs_disp_flow1 &= ~FS_DC1_SRC_SEL_MASK;
  173572. + fs_disp_flow1 |=
  173573. + disp_src_sel[IPU_CHAN_ID(src_ch)] << FS_DC1_SRC_SEL_OFFSET;
  173574. + break;
  173575. + case MEM_BG_SYNC:
  173576. + fs_disp_flow1 &= ~FS_DP_SYNC0_SRC_SEL_MASK;
  173577. + fs_disp_flow1 |=
  173578. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  173579. + FS_DP_SYNC0_SRC_SEL_OFFSET;
  173580. + break;
  173581. + case MEM_FG_SYNC:
  173582. + fs_disp_flow1 &= ~FS_DP_SYNC1_SRC_SEL_MASK;
  173583. + fs_disp_flow1 |=
  173584. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  173585. + FS_DP_SYNC1_SRC_SEL_OFFSET;
  173586. + break;
  173587. + case MEM_DC_ASYNC:
  173588. + fs_disp_flow1 &= ~FS_DC2_SRC_SEL_MASK;
  173589. + fs_disp_flow1 |=
  173590. + disp_src_sel[IPU_CHAN_ID(src_ch)] << FS_DC2_SRC_SEL_OFFSET;
  173591. + break;
  173592. + case MEM_BG_ASYNC0:
  173593. + fs_disp_flow1 &= ~FS_DP_ASYNC0_SRC_SEL_MASK;
  173594. + fs_disp_flow1 |=
  173595. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  173596. + FS_DP_ASYNC0_SRC_SEL_OFFSET;
  173597. + break;
  173598. + case MEM_FG_ASYNC0:
  173599. + fs_disp_flow1 &= ~FS_DP_ASYNC1_SRC_SEL_MASK;
  173600. + fs_disp_flow1 |=
  173601. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  173602. + FS_DP_ASYNC1_SRC_SEL_OFFSET;
  173603. + break;
  173604. + case MEM_VDI_MEM:
  173605. + fs_proc_flow1 &= ~FS_VDI_SRC_SEL_MASK;
  173606. + if (MEM_VDOA_MEM == src_ch)
  173607. + fs_proc_flow1 |= FS_VDI_SRC_SEL_VDOA;
  173608. + else {
  173609. + retval = -EINVAL;
  173610. + goto err;
  173611. + }
  173612. + break;
  173613. + default:
  173614. + retval = -EINVAL;
  173615. + goto err;
  173616. + }
  173617. +
  173618. + ipu_cm_write(ipu, fs_proc_flow1, IPU_FS_PROC_FLOW1);
  173619. + ipu_cm_write(ipu, fs_proc_flow2, IPU_FS_PROC_FLOW2);
  173620. + ipu_cm_write(ipu, fs_proc_flow3, IPU_FS_PROC_FLOW3);
  173621. + ipu_cm_write(ipu, fs_disp_flow1, IPU_FS_DISP_FLOW1);
  173622. +
  173623. +err:
  173624. + mutex_unlock(&ipu->mutex_lock);
  173625. + return retval;
  173626. +}
  173627. +EXPORT_SYMBOL(ipu_link_channels);
  173628. +
  173629. +/*!
  173630. + * This function unlinks 2 channels and disables automatic frame
  173631. + * synchronization.
  173632. + *
  173633. + * @param ipu ipu handler
  173634. + * @param src_ch Input parameter for the logical channel ID of
  173635. + * the source channel.
  173636. + *
  173637. + * @param dest_ch Input parameter for the logical channel ID of
  173638. + * the destination channel.
  173639. + *
  173640. + * @return This function returns 0 on success or negative error code on
  173641. + * fail.
  173642. + */
  173643. +int32_t ipu_unlink_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch)
  173644. +{
  173645. + int retval = 0;
  173646. + uint32_t fs_proc_flow1;
  173647. + uint32_t fs_proc_flow2;
  173648. + uint32_t fs_proc_flow3;
  173649. + uint32_t fs_disp_flow1;
  173650. +
  173651. + mutex_lock(&ipu->mutex_lock);
  173652. +
  173653. + fs_proc_flow1 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  173654. + fs_proc_flow2 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW2);
  173655. + fs_proc_flow3 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW3);
  173656. + fs_disp_flow1 = ipu_cm_read(ipu, IPU_FS_DISP_FLOW1);
  173657. +
  173658. + switch (src_ch) {
  173659. + case CSI_MEM0:
  173660. + fs_proc_flow3 &= ~FS_SMFC0_DEST_SEL_MASK;
  173661. + break;
  173662. + case CSI_MEM1:
  173663. + fs_proc_flow3 &= ~FS_SMFC1_DEST_SEL_MASK;
  173664. + break;
  173665. + case CSI_MEM2:
  173666. + fs_proc_flow3 &= ~FS_SMFC2_DEST_SEL_MASK;
  173667. + break;
  173668. + case CSI_MEM3:
  173669. + fs_proc_flow3 &= ~FS_SMFC3_DEST_SEL_MASK;
  173670. + break;
  173671. + case CSI_PRP_ENC_MEM:
  173672. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  173673. + break;
  173674. + case CSI_PRP_VF_MEM:
  173675. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173676. + break;
  173677. + case MEM_PP_MEM:
  173678. + fs_proc_flow2 &= ~FS_PP_DEST_SEL_MASK;
  173679. + break;
  173680. + case MEM_ROT_PP_MEM:
  173681. + fs_proc_flow2 &= ~FS_PP_ROT_DEST_SEL_MASK;
  173682. + break;
  173683. + case MEM_PRP_ENC_MEM:
  173684. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  173685. + break;
  173686. + case MEM_ROT_ENC_MEM:
  173687. + fs_proc_flow2 &= ~FS_PRPENC_ROT_DEST_SEL_MASK;
  173688. + break;
  173689. + case MEM_PRP_VF_MEM:
  173690. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173691. + break;
  173692. + case MEM_VDI_PRP_VF_MEM:
  173693. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173694. + break;
  173695. + case MEM_ROT_VF_MEM:
  173696. + fs_proc_flow2 &= ~FS_PRPVF_ROT_DEST_SEL_MASK;
  173697. + break;
  173698. + case MEM_VDOA_MEM:
  173699. + fs_proc_flow3 &= ~FS_VDOA_DEST_SEL_MASK;
  173700. + break;
  173701. + default:
  173702. + retval = -EINVAL;
  173703. + goto err;
  173704. + }
  173705. +
  173706. + switch (dest_ch) {
  173707. + case MEM_PP_MEM:
  173708. + fs_proc_flow1 &= ~FS_PP_SRC_SEL_MASK;
  173709. + break;
  173710. + case MEM_ROT_PP_MEM:
  173711. + fs_proc_flow1 &= ~FS_PP_ROT_SRC_SEL_MASK;
  173712. + break;
  173713. + case MEM_PRP_ENC_MEM:
  173714. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173715. + break;
  173716. + case MEM_ROT_ENC_MEM:
  173717. + fs_proc_flow1 &= ~FS_PRPENC_ROT_SRC_SEL_MASK;
  173718. + break;
  173719. + case MEM_PRP_VF_MEM:
  173720. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173721. + break;
  173722. + case MEM_VDI_PRP_VF_MEM:
  173723. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173724. + break;
  173725. + case MEM_ROT_VF_MEM:
  173726. + fs_proc_flow1 &= ~FS_PRPVF_ROT_SRC_SEL_MASK;
  173727. + break;
  173728. + case MEM_DC_SYNC:
  173729. + fs_disp_flow1 &= ~FS_DC1_SRC_SEL_MASK;
  173730. + break;
  173731. + case MEM_BG_SYNC:
  173732. + fs_disp_flow1 &= ~FS_DP_SYNC0_SRC_SEL_MASK;
  173733. + break;
  173734. + case MEM_FG_SYNC:
  173735. + fs_disp_flow1 &= ~FS_DP_SYNC1_SRC_SEL_MASK;
  173736. + break;
  173737. + case MEM_DC_ASYNC:
  173738. + fs_disp_flow1 &= ~FS_DC2_SRC_SEL_MASK;
  173739. + break;
  173740. + case MEM_BG_ASYNC0:
  173741. + fs_disp_flow1 &= ~FS_DP_ASYNC0_SRC_SEL_MASK;
  173742. + break;
  173743. + case MEM_FG_ASYNC0:
  173744. + fs_disp_flow1 &= ~FS_DP_ASYNC1_SRC_SEL_MASK;
  173745. + break;
  173746. + case MEM_VDI_MEM:
  173747. + fs_proc_flow1 &= ~FS_VDI_SRC_SEL_MASK;
  173748. + break;
  173749. + default:
  173750. + retval = -EINVAL;
  173751. + goto err;
  173752. + }
  173753. +
  173754. + ipu_cm_write(ipu, fs_proc_flow1, IPU_FS_PROC_FLOW1);
  173755. + ipu_cm_write(ipu, fs_proc_flow2, IPU_FS_PROC_FLOW2);
  173756. + ipu_cm_write(ipu, fs_proc_flow3, IPU_FS_PROC_FLOW3);
  173757. + ipu_cm_write(ipu, fs_disp_flow1, IPU_FS_DISP_FLOW1);
  173758. +
  173759. +err:
  173760. + mutex_unlock(&ipu->mutex_lock);
  173761. + return retval;
  173762. +}
  173763. +EXPORT_SYMBOL(ipu_unlink_channels);
  173764. +
  173765. +/*!
  173766. + * This function check whether a logical channel was enabled.
  173767. + *
  173768. + * @param ipu ipu handler
  173769. + * @param channel Input parameter for the logical channel ID.
  173770. + *
  173771. + * @return This function returns 1 while request channel is enabled or
  173772. + * 0 for not enabled.
  173773. + */
  173774. +int32_t ipu_is_channel_busy(struct ipu_soc *ipu, ipu_channel_t channel)
  173775. +{
  173776. + uint32_t reg;
  173777. + uint32_t in_dma;
  173778. + uint32_t out_dma;
  173779. +
  173780. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  173781. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  173782. +
  173783. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
  173784. + if (reg & idma_mask(in_dma))
  173785. + return 1;
  173786. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
  173787. + if (reg & idma_mask(out_dma))
  173788. + return 1;
  173789. + return 0;
  173790. +}
  173791. +EXPORT_SYMBOL(ipu_is_channel_busy);
  173792. +
  173793. +/*!
  173794. + * This function enables a logical channel.
  173795. + *
  173796. + * @param ipu ipu handler
  173797. + * @param channel Input parameter for the logical channel ID.
  173798. + *
  173799. + * @return This function returns 0 on success or negative error code on
  173800. + * fail.
  173801. + */
  173802. +int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel)
  173803. +{
  173804. + uint32_t reg;
  173805. + uint32_t ipu_conf;
  173806. + uint32_t in_dma;
  173807. + uint32_t out_dma;
  173808. + uint32_t sec_dma;
  173809. + uint32_t thrd_dma;
  173810. +
  173811. + mutex_lock(&ipu->mutex_lock);
  173812. +
  173813. + if (ipu->channel_enable_mask & (1L << IPU_CHAN_ID(channel))) {
  173814. + dev_err(ipu->dev, "Warning: channel already enabled %d\n",
  173815. + IPU_CHAN_ID(channel));
  173816. + mutex_unlock(&ipu->mutex_lock);
  173817. + return -EACCES;
  173818. + }
  173819. +
  173820. + /* Get input and output dma channels */
  173821. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  173822. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  173823. +
  173824. + ipu_conf = ipu_cm_read(ipu, IPU_CONF);
  173825. + if (ipu->di_use_count[0] > 0) {
  173826. + ipu_conf |= IPU_CONF_DI0_EN;
  173827. + }
  173828. + if (ipu->di_use_count[1] > 0) {
  173829. + ipu_conf |= IPU_CONF_DI1_EN;
  173830. + }
  173831. + if (ipu->dp_use_count > 0)
  173832. + ipu_conf |= IPU_CONF_DP_EN;
  173833. + if (ipu->dc_use_count > 0)
  173834. + ipu_conf |= IPU_CONF_DC_EN;
  173835. + if (ipu->dmfc_use_count > 0)
  173836. + ipu_conf |= IPU_CONF_DMFC_EN;
  173837. + if (ipu->ic_use_count > 0)
  173838. + ipu_conf |= IPU_CONF_IC_EN;
  173839. + if (ipu->vdi_use_count > 0) {
  173840. + ipu_conf |= IPU_CONF_ISP_EN;
  173841. + ipu_conf |= IPU_CONF_VDI_EN;
  173842. + ipu_conf |= IPU_CONF_IC_INPUT;
  173843. + }
  173844. + if (ipu->rot_use_count > 0)
  173845. + ipu_conf |= IPU_CONF_ROT_EN;
  173846. + if (ipu->smfc_use_count > 0)
  173847. + ipu_conf |= IPU_CONF_SMFC_EN;
  173848. + ipu_cm_write(ipu, ipu_conf, IPU_CONF);
  173849. +
  173850. + if (idma_is_valid(in_dma)) {
  173851. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
  173852. + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
  173853. + }
  173854. + if (idma_is_valid(out_dma)) {
  173855. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
  173856. + ipu_idmac_write(ipu, reg | idma_mask(out_dma), IDMAC_CHA_EN(out_dma));
  173857. + }
  173858. +
  173859. + if ((ipu->sec_chan_en[IPU_CHAN_ID(channel)]) &&
  173860. + ((channel == MEM_PP_MEM) || (channel == MEM_PRP_VF_MEM) ||
  173861. + (channel == MEM_VDI_PRP_VF_MEM))) {
  173862. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  173863. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(sec_dma));
  173864. + ipu_idmac_write(ipu, reg | idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma));
  173865. + }
  173866. + if ((ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) &&
  173867. + ((channel == MEM_PP_MEM) || (channel == MEM_PRP_VF_MEM))) {
  173868. + thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
  173869. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
  173870. + ipu_idmac_write(ipu, reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
  173871. +
  173872. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  173873. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  173874. + ipu_idmac_write(ipu, reg | idma_mask(sec_dma), IDMAC_SEP_ALPHA);
  173875. + } else if ((ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) &&
  173876. + ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC))) {
  173877. + thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
  173878. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
  173879. + ipu_idmac_write(ipu, reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
  173880. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  173881. + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_SEP_ALPHA);
  173882. + }
  173883. +
  173884. + if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_SYNC) ||
  173885. + (channel == MEM_FG_SYNC)) {
  173886. + reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma));
  173887. + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_WM_EN(in_dma));
  173888. +
  173889. + _ipu_dp_dc_enable(ipu, channel);
  173890. + }
  173891. +
  173892. + if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
  173893. + _ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma) ||
  173894. + _ipu_is_vdi_out_chan(out_dma))
  173895. + _ipu_ic_enable_task(ipu, channel);
  173896. +
  173897. + ipu->channel_enable_mask |= 1L << IPU_CHAN_ID(channel);
  173898. +
  173899. + mutex_unlock(&ipu->mutex_lock);
  173900. +
  173901. + return 0;
  173902. +}
  173903. +EXPORT_SYMBOL(ipu_enable_channel);
  173904. +
  173905. +/*!
  173906. + * This function check buffer ready for a logical channel.
  173907. + *
  173908. + * @param ipu ipu handler
  173909. + * @param channel Input parameter for the logical channel ID.
  173910. + *
  173911. + * @param type Input parameter which buffer to clear.
  173912. + *
  173913. + * @param bufNum Input parameter for which buffer number clear
  173914. + * ready state.
  173915. + *
  173916. + */
  173917. +int32_t ipu_check_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  173918. + uint32_t bufNum)
  173919. +{
  173920. + uint32_t dma_chan = channel_2_dma(channel, type);
  173921. + uint32_t reg;
  173922. + unsigned long lock_flags;
  173923. +
  173924. + if (dma_chan == IDMA_CHAN_INVALID)
  173925. + return -EINVAL;
  173926. +
  173927. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173928. + if (bufNum == 0)
  173929. + reg = ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan));
  173930. + else if (bufNum == 1)
  173931. + reg = ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan));
  173932. + else
  173933. + reg = ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan));
  173934. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173935. +
  173936. + if (reg & idma_mask(dma_chan))
  173937. + return 1;
  173938. + else
  173939. + return 0;
  173940. +}
  173941. +EXPORT_SYMBOL(ipu_check_buffer_ready);
  173942. +
  173943. +/*!
  173944. + * This function clear buffer ready for a logical channel.
  173945. + *
  173946. + * @param ipu ipu handler
  173947. + * @param channel Input parameter for the logical channel ID.
  173948. + *
  173949. + * @param type Input parameter which buffer to clear.
  173950. + *
  173951. + * @param bufNum Input parameter for which buffer number clear
  173952. + * ready state.
  173953. + *
  173954. + */
  173955. +void _ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  173956. + uint32_t bufNum)
  173957. +{
  173958. + uint32_t dma_ch = channel_2_dma(channel, type);
  173959. +
  173960. + if (!idma_is_valid(dma_ch))
  173961. + return;
  173962. +
  173963. + ipu_cm_write(ipu, 0xF0300000, IPU_GPR); /* write one to clear */
  173964. + if (bufNum == 0)
  173965. + ipu_cm_write(ipu, idma_mask(dma_ch),
  173966. + IPU_CHA_BUF0_RDY(dma_ch));
  173967. + else if (bufNum == 1)
  173968. + ipu_cm_write(ipu, idma_mask(dma_ch),
  173969. + IPU_CHA_BUF1_RDY(dma_ch));
  173970. + else
  173971. + ipu_cm_write(ipu, idma_mask(dma_ch),
  173972. + IPU_CHA_BUF2_RDY(dma_ch));
  173973. + ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
  173974. +}
  173975. +
  173976. +void ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  173977. + uint32_t bufNum)
  173978. +{
  173979. + unsigned long lock_flags;
  173980. +
  173981. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173982. + _ipu_clear_buffer_ready(ipu, channel, type, bufNum);
  173983. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173984. +}
  173985. +EXPORT_SYMBOL(ipu_clear_buffer_ready);
  173986. +
  173987. +/*!
  173988. + * This function disables a logical channel.
  173989. + *
  173990. + * @param ipu ipu handler
  173991. + * @param channel Input parameter for the logical channel ID.
  173992. + *
  173993. + * @param wait_for_stop Flag to set whether to wait for channel end
  173994. + * of frame or return immediately.
  173995. + *
  173996. + * @return This function returns 0 on success or negative error code on
  173997. + * fail.
  173998. + */
  173999. +int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wait_for_stop)
  174000. +{
  174001. + uint32_t reg;
  174002. + uint32_t in_dma;
  174003. + uint32_t out_dma;
  174004. + uint32_t sec_dma = NO_DMA;
  174005. + uint32_t thrd_dma = NO_DMA;
  174006. + uint16_t fg_pos_x, fg_pos_y;
  174007. + unsigned long lock_flags;
  174008. +
  174009. + mutex_lock(&ipu->mutex_lock);
  174010. +
  174011. + if ((ipu->channel_enable_mask & (1L << IPU_CHAN_ID(channel))) == 0) {
  174012. + dev_dbg(ipu->dev, "Channel already disabled %d\n",
  174013. + IPU_CHAN_ID(channel));
  174014. + mutex_unlock(&ipu->mutex_lock);
  174015. + return -EACCES;
  174016. + }
  174017. +
  174018. + /* Get input and output dma channels */
  174019. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  174020. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  174021. +
  174022. + if ((idma_is_valid(in_dma) &&
  174023. + !idma_is_set(ipu, IDMAC_CHA_EN, in_dma))
  174024. + && (idma_is_valid(out_dma) &&
  174025. + !idma_is_set(ipu, IDMAC_CHA_EN, out_dma))) {
  174026. + mutex_unlock(&ipu->mutex_lock);
  174027. + return -EINVAL;
  174028. + }
  174029. +
  174030. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)])
  174031. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  174032. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) {
  174033. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  174034. + thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
  174035. + }
  174036. +
  174037. + if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
  174038. + (channel == MEM_DC_SYNC)) {
  174039. + if (channel == MEM_FG_SYNC) {
  174040. + _ipu_disp_get_window_pos(ipu, channel, &fg_pos_x, &fg_pos_y);
  174041. + _ipu_disp_set_window_pos(ipu, channel, 0, 0);
  174042. + }
  174043. +
  174044. + _ipu_dp_dc_disable(ipu, channel, false);
  174045. +
  174046. + /*
  174047. + * wait for BG channel EOF then disable FG-IDMAC,
  174048. + * it avoid FG NFB4EOF error.
  174049. + */
  174050. + if ((channel == MEM_FG_SYNC) && (ipu_is_channel_busy(ipu, MEM_BG_SYNC))) {
  174051. + int timeout = 50;
  174052. +
  174053. + ipu_cm_write(ipu, IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF),
  174054. + IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF));
  174055. + while ((ipu_cm_read(ipu, IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF)) &
  174056. + IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF)) == 0) {
  174057. + msleep(10);
  174058. + timeout -= 10;
  174059. + if (timeout <= 0) {
  174060. + dev_err(ipu->dev, "warning: wait for bg sync eof timeout\n");
  174061. + break;
  174062. + }
  174063. + }
  174064. + }
  174065. + } else if (wait_for_stop && !_ipu_is_smfc_chan(out_dma) &&
  174066. + channel != CSI_PRP_VF_MEM && channel != CSI_PRP_ENC_MEM) {
  174067. + while (idma_is_set(ipu, IDMAC_CHA_BUSY, in_dma) ||
  174068. + idma_is_set(ipu, IDMAC_CHA_BUSY, out_dma) ||
  174069. + (ipu->sec_chan_en[IPU_CHAN_ID(channel)] &&
  174070. + idma_is_set(ipu, IDMAC_CHA_BUSY, sec_dma)) ||
  174071. + (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] &&
  174072. + idma_is_set(ipu, IDMAC_CHA_BUSY, thrd_dma))) {
  174073. + uint32_t irq = 0xffffffff;
  174074. + int timeout = 50000;
  174075. +
  174076. + if (idma_is_set(ipu, IDMAC_CHA_BUSY, out_dma))
  174077. + irq = out_dma;
  174078. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] &&
  174079. + idma_is_set(ipu, IDMAC_CHA_BUSY, sec_dma))
  174080. + irq = sec_dma;
  174081. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] &&
  174082. + idma_is_set(ipu, IDMAC_CHA_BUSY, thrd_dma))
  174083. + irq = thrd_dma;
  174084. + if (idma_is_set(ipu, IDMAC_CHA_BUSY, in_dma))
  174085. + irq = in_dma;
  174086. +
  174087. + if (irq == 0xffffffff) {
  174088. + dev_dbg(ipu->dev, "warning: no channel busy, break\n");
  174089. + break;
  174090. + }
  174091. +
  174092. + ipu_cm_write(ipu, IPUIRQ_2_MASK(irq),
  174093. + IPUIRQ_2_STATREG(irq));
  174094. +
  174095. + dev_dbg(ipu->dev, "warning: channel %d busy, need wait\n", irq);
  174096. +
  174097. + while (((ipu_cm_read(ipu, IPUIRQ_2_STATREG(irq))
  174098. + & IPUIRQ_2_MASK(irq)) == 0) &&
  174099. + (idma_is_set(ipu, IDMAC_CHA_BUSY, irq))) {
  174100. + udelay(10);
  174101. + timeout -= 10;
  174102. + if (timeout <= 0) {
  174103. + ipu_dump_registers(ipu);
  174104. + dev_err(ipu->dev, "warning: disable ipu dma channel %d during its busy state\n", irq);
  174105. + break;
  174106. + }
  174107. + }
  174108. + dev_dbg(ipu->dev, "wait_time:%d\n", 50000 - timeout);
  174109. +
  174110. + }
  174111. + }
  174112. +
  174113. + if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
  174114. + (channel == MEM_DC_SYNC)) {
  174115. + reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma));
  174116. + ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_WM_EN(in_dma));
  174117. + }
  174118. +
  174119. + /* Disable IC task */
  174120. + if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
  174121. + _ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma) ||
  174122. + _ipu_is_vdi_out_chan(out_dma))
  174123. + _ipu_ic_disable_task(ipu, channel);
  174124. +
  174125. + /* Disable DMA channel(s) */
  174126. + if (idma_is_valid(in_dma)) {
  174127. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
  174128. + ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
  174129. + ipu_cm_write(ipu, idma_mask(in_dma), IPU_CHA_CUR_BUF(in_dma));
  174130. + ipu_cm_write(ipu, tri_cur_buf_mask(in_dma),
  174131. + IPU_CHA_TRIPLE_CUR_BUF(in_dma));
  174132. + }
  174133. + if (idma_is_valid(out_dma)) {
  174134. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
  174135. + ipu_idmac_write(ipu, reg & ~idma_mask(out_dma), IDMAC_CHA_EN(out_dma));
  174136. + ipu_cm_write(ipu, idma_mask(out_dma), IPU_CHA_CUR_BUF(out_dma));
  174137. + ipu_cm_write(ipu, tri_cur_buf_mask(out_dma),
  174138. + IPU_CHA_TRIPLE_CUR_BUF(out_dma));
  174139. + }
  174140. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) {
  174141. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(sec_dma));
  174142. + ipu_idmac_write(ipu, reg & ~idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma));
  174143. + ipu_cm_write(ipu, idma_mask(sec_dma), IPU_CHA_CUR_BUF(sec_dma));
  174144. + }
  174145. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) {
  174146. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
  174147. + ipu_idmac_write(ipu, reg & ~idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
  174148. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC) {
  174149. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  174150. + ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_SEP_ALPHA);
  174151. + } else {
  174152. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  174153. + ipu_idmac_write(ipu, reg & ~idma_mask(sec_dma), IDMAC_SEP_ALPHA);
  174154. + }
  174155. + ipu_cm_write(ipu, idma_mask(thrd_dma), IPU_CHA_CUR_BUF(thrd_dma));
  174156. + }
  174157. +
  174158. + if (channel == MEM_FG_SYNC)
  174159. + _ipu_disp_set_window_pos(ipu, channel, fg_pos_x, fg_pos_y);
  174160. +
  174161. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  174162. + /* Set channel buffers NOT to be ready */
  174163. + if (idma_is_valid(in_dma)) {
  174164. + _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 0);
  174165. + _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 1);
  174166. + _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 2);
  174167. + }
  174168. + if (idma_is_valid(out_dma)) {
  174169. + _ipu_clear_buffer_ready(ipu, channel, IPU_OUTPUT_BUFFER, 0);
  174170. + _ipu_clear_buffer_ready(ipu, channel, IPU_OUTPUT_BUFFER, 1);
  174171. + }
  174172. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) {
  174173. + _ipu_clear_buffer_ready(ipu, channel, IPU_GRAPH_IN_BUFFER, 0);
  174174. + _ipu_clear_buffer_ready(ipu, channel, IPU_GRAPH_IN_BUFFER, 1);
  174175. + }
  174176. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) {
  174177. + _ipu_clear_buffer_ready(ipu, channel, IPU_ALPHA_IN_BUFFER, 0);
  174178. + _ipu_clear_buffer_ready(ipu, channel, IPU_ALPHA_IN_BUFFER, 1);
  174179. + }
  174180. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  174181. +
  174182. + ipu->channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel));
  174183. +
  174184. + mutex_unlock(&ipu->mutex_lock);
  174185. +
  174186. + return 0;
  174187. +}
  174188. +EXPORT_SYMBOL(ipu_disable_channel);
  174189. +
  174190. +/*!
  174191. + * This function enables CSI.
  174192. + *
  174193. + * @param ipu ipu handler
  174194. + * @param csi csi num 0 or 1
  174195. + *
  174196. + * @return This function returns 0 on success or negative error code on
  174197. + * fail.
  174198. + */
  174199. +int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi)
  174200. +{
  174201. + uint32_t reg;
  174202. +
  174203. + if (csi > 1) {
  174204. + dev_err(ipu->dev, "Wrong csi num_%d\n", csi);
  174205. + return -EINVAL;
  174206. + }
  174207. +
  174208. + _ipu_get(ipu);
  174209. + mutex_lock(&ipu->mutex_lock);
  174210. + ipu->csi_use_count[csi]++;
  174211. +
  174212. + if (ipu->csi_use_count[csi] == 1) {
  174213. + reg = ipu_cm_read(ipu, IPU_CONF);
  174214. + if (csi == 0)
  174215. + ipu_cm_write(ipu, reg | IPU_CONF_CSI0_EN, IPU_CONF);
  174216. + else
  174217. + ipu_cm_write(ipu, reg | IPU_CONF_CSI1_EN, IPU_CONF);
  174218. + }
  174219. + mutex_unlock(&ipu->mutex_lock);
  174220. + _ipu_put(ipu);
  174221. + return 0;
  174222. +}
  174223. +EXPORT_SYMBOL(ipu_enable_csi);
  174224. +
  174225. +/*!
  174226. + * This function disables CSI.
  174227. + *
  174228. + * @param ipu ipu handler
  174229. + * @param csi csi num 0 or 1
  174230. + *
  174231. + * @return This function returns 0 on success or negative error code on
  174232. + * fail.
  174233. + */
  174234. +int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi)
  174235. +{
  174236. + uint32_t reg;
  174237. +
  174238. + if (csi > 1) {
  174239. + dev_err(ipu->dev, "Wrong csi num_%d\n", csi);
  174240. + return -EINVAL;
  174241. + }
  174242. + _ipu_get(ipu);
  174243. + mutex_lock(&ipu->mutex_lock);
  174244. + ipu->csi_use_count[csi]--;
  174245. + if (ipu->csi_use_count[csi] == 0) {
  174246. + _ipu_csi_wait4eof(ipu, ipu->csi_channel[csi]);
  174247. + reg = ipu_cm_read(ipu, IPU_CONF);
  174248. + if (csi == 0)
  174249. + ipu_cm_write(ipu, reg & ~IPU_CONF_CSI0_EN, IPU_CONF);
  174250. + else
  174251. + ipu_cm_write(ipu, reg & ~IPU_CONF_CSI1_EN, IPU_CONF);
  174252. + }
  174253. + mutex_unlock(&ipu->mutex_lock);
  174254. + _ipu_put(ipu);
  174255. + return 0;
  174256. +}
  174257. +EXPORT_SYMBOL(ipu_disable_csi);
  174258. +
  174259. +static irqreturn_t ipu_sync_irq_handler(int irq, void *desc)
  174260. +{
  174261. + struct ipu_soc *ipu = desc;
  174262. + int i;
  174263. + uint32_t line, bit, int_stat, int_ctrl;
  174264. + irqreturn_t result = IRQ_NONE;
  174265. + const int int_reg[] = { 1, 2, 3, 4, 11, 12, 13, 14, 15, 0 };
  174266. +
  174267. + spin_lock(&ipu->int_reg_spin_lock);
  174268. +
  174269. + for (i = 0; int_reg[i] != 0; i++) {
  174270. + int_stat = ipu_cm_read(ipu, IPU_INT_STAT(int_reg[i]));
  174271. + int_ctrl = ipu_cm_read(ipu, IPU_INT_CTRL(int_reg[i]));
  174272. + int_stat &= int_ctrl;
  174273. + ipu_cm_write(ipu, int_stat, IPU_INT_STAT(int_reg[i]));
  174274. + while ((line = ffs(int_stat)) != 0) {
  174275. + bit = --line;
  174276. + int_stat &= ~(1UL << line);
  174277. + line += (int_reg[i] - 1) * 32;
  174278. + result |=
  174279. + ipu->irq_list[line].handler(line,
  174280. + ipu->irq_list[line].
  174281. + dev_id);
  174282. + if (ipu->irq_list[line].flags & IPU_IRQF_ONESHOT) {
  174283. + int_ctrl &= ~(1UL << bit);
  174284. + ipu_cm_write(ipu, int_ctrl,
  174285. + IPU_INT_CTRL(int_reg[i]));
  174286. + }
  174287. + }
  174288. + }
  174289. +
  174290. + spin_unlock(&ipu->int_reg_spin_lock);
  174291. +
  174292. + return result;
  174293. +}
  174294. +
  174295. +static irqreturn_t ipu_err_irq_handler(int irq, void *desc)
  174296. +{
  174297. + struct ipu_soc *ipu = desc;
  174298. + int i;
  174299. + uint32_t int_stat;
  174300. + const int err_reg[] = { 5, 6, 9, 10, 0 };
  174301. +
  174302. + spin_lock(&ipu->int_reg_spin_lock);
  174303. +
  174304. + for (i = 0; err_reg[i] != 0; i++) {
  174305. + int_stat = ipu_cm_read(ipu, IPU_INT_STAT(err_reg[i]));
  174306. + int_stat &= ipu_cm_read(ipu, IPU_INT_CTRL(err_reg[i]));
  174307. + if (int_stat) {
  174308. + ipu_cm_write(ipu, int_stat, IPU_INT_STAT(err_reg[i]));
  174309. + dev_warn(ipu->dev,
  174310. + "IPU Warning - IPU_INT_STAT_%d = 0x%08X\n",
  174311. + err_reg[i], int_stat);
  174312. + /* Disable interrupts so we only get error once */
  174313. + int_stat = ipu_cm_read(ipu, IPU_INT_CTRL(err_reg[i])) &
  174314. + ~int_stat;
  174315. + ipu_cm_write(ipu, int_stat, IPU_INT_CTRL(err_reg[i]));
  174316. + }
  174317. + }
  174318. +
  174319. + spin_unlock(&ipu->int_reg_spin_lock);
  174320. +
  174321. + return IRQ_HANDLED;
  174322. +}
  174323. +
  174324. +/*!
  174325. + * This function enables the interrupt for the specified interrupt line.
  174326. + * The interrupt lines are defined in \b ipu_irq_line enum.
  174327. + *
  174328. + * @param ipu ipu handler
  174329. + * @param irq Interrupt line to enable interrupt for.
  174330. + *
  174331. + * @return This function returns 0 on success or negative error code on
  174332. + * fail.
  174333. + */
  174334. +int ipu_enable_irq(struct ipu_soc *ipu, uint32_t irq)
  174335. +{
  174336. + uint32_t reg;
  174337. + unsigned long lock_flags;
  174338. + int ret = 0;
  174339. +
  174340. + _ipu_get(ipu);
  174341. +
  174342. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174343. +
  174344. + /*
  174345. + * Check sync interrupt handler only, since we do nothing for
  174346. + * error interrupts but than print out register values in the
  174347. + * error interrupt source handler.
  174348. + */
  174349. + if (_ipu_is_sync_irq(irq) && (ipu->irq_list[irq].handler == NULL)) {
  174350. + dev_err(ipu->dev, "handler hasn't been registered on sync "
  174351. + "irq %d\n", irq);
  174352. + ret = -EACCES;
  174353. + goto out;
  174354. + }
  174355. +
  174356. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  174357. + reg |= IPUIRQ_2_MASK(irq);
  174358. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  174359. +out:
  174360. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174361. +
  174362. + _ipu_put(ipu);
  174363. +
  174364. + return ret;
  174365. +}
  174366. +EXPORT_SYMBOL(ipu_enable_irq);
  174367. +
  174368. +/*!
  174369. + * This function disables the interrupt for the specified interrupt line.
  174370. + * The interrupt lines are defined in \b ipu_irq_line enum.
  174371. + *
  174372. + * @param ipu ipu handler
  174373. + * @param irq Interrupt line to disable interrupt for.
  174374. + *
  174375. + */
  174376. +void ipu_disable_irq(struct ipu_soc *ipu, uint32_t irq)
  174377. +{
  174378. + uint32_t reg;
  174379. + unsigned long lock_flags;
  174380. +
  174381. + _ipu_get(ipu);
  174382. +
  174383. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174384. +
  174385. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  174386. + reg &= ~IPUIRQ_2_MASK(irq);
  174387. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  174388. +
  174389. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174390. +
  174391. + _ipu_put(ipu);
  174392. +}
  174393. +EXPORT_SYMBOL(ipu_disable_irq);
  174394. +
  174395. +/*!
  174396. + * This function clears the interrupt for the specified interrupt line.
  174397. + * The interrupt lines are defined in \b ipu_irq_line enum.
  174398. + *
  174399. + * @param ipu ipu handler
  174400. + * @param irq Interrupt line to clear interrupt for.
  174401. + *
  174402. + */
  174403. +void ipu_clear_irq(struct ipu_soc *ipu, uint32_t irq)
  174404. +{
  174405. + unsigned long lock_flags;
  174406. +
  174407. + _ipu_get(ipu);
  174408. +
  174409. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174410. +
  174411. + ipu_cm_write(ipu, IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq));
  174412. +
  174413. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174414. +
  174415. + _ipu_put(ipu);
  174416. +}
  174417. +EXPORT_SYMBOL(ipu_clear_irq);
  174418. +
  174419. +/*!
  174420. + * This function returns the current interrupt status for the specified
  174421. + * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum.
  174422. + *
  174423. + * @param ipu ipu handler
  174424. + * @param irq Interrupt line to get status for.
  174425. + *
  174426. + * @return Returns true if the interrupt is pending/asserted or false if
  174427. + * the interrupt is not pending.
  174428. + */
  174429. +bool ipu_get_irq_status(struct ipu_soc *ipu, uint32_t irq)
  174430. +{
  174431. + uint32_t reg;
  174432. + unsigned long lock_flags;
  174433. +
  174434. + _ipu_get(ipu);
  174435. +
  174436. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174437. + reg = ipu_cm_read(ipu, IPUIRQ_2_STATREG(irq));
  174438. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174439. +
  174440. + _ipu_put(ipu);
  174441. +
  174442. + if (reg & IPUIRQ_2_MASK(irq))
  174443. + return true;
  174444. + else
  174445. + return false;
  174446. +}
  174447. +EXPORT_SYMBOL(ipu_get_irq_status);
  174448. +
  174449. +/*!
  174450. + * This function registers an interrupt handler function for the specified
  174451. + * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum.
  174452. + *
  174453. + * @param ipu ipu handler
  174454. + * @param irq Interrupt line to get status for.
  174455. + *
  174456. + * @param handler Input parameter for address of the handler
  174457. + * function.
  174458. + *
  174459. + * @param irq_flags Flags for interrupt mode. Currently not used.
  174460. + *
  174461. + * @param devname Input parameter for string name of driver
  174462. + * registering the handler.
  174463. + *
  174464. + * @param dev_id Input parameter for pointer of data to be
  174465. + * passed to the handler.
  174466. + *
  174467. + * @return This function returns 0 on success or negative error code on
  174468. + * fail.
  174469. + */
  174470. +int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
  174471. + irqreturn_t(*handler) (int, void *),
  174472. + uint32_t irq_flags, const char *devname, void *dev_id)
  174473. +{
  174474. + uint32_t reg;
  174475. + unsigned long lock_flags;
  174476. + int ret = 0;
  174477. +
  174478. + BUG_ON(irq >= IPU_IRQ_COUNT);
  174479. +
  174480. + _ipu_get(ipu);
  174481. +
  174482. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174483. +
  174484. + if (ipu->irq_list[irq].handler != NULL) {
  174485. + dev_err(ipu->dev,
  174486. + "handler already installed on irq %d\n", irq);
  174487. + ret = -EINVAL;
  174488. + goto out;
  174489. + }
  174490. +
  174491. + /*
  174492. + * Check sync interrupt handler only, since we do nothing for
  174493. + * error interrupts but than print out register values in the
  174494. + * error interrupt source handler.
  174495. + */
  174496. + if (_ipu_is_sync_irq(irq) && (handler == NULL)) {
  174497. + dev_err(ipu->dev, "handler is NULL for sync irq %d\n", irq);
  174498. + ret = -EINVAL;
  174499. + goto out;
  174500. + }
  174501. +
  174502. + ipu->irq_list[irq].handler = handler;
  174503. + ipu->irq_list[irq].flags = irq_flags;
  174504. + ipu->irq_list[irq].dev_id = dev_id;
  174505. + ipu->irq_list[irq].name = devname;
  174506. +
  174507. + /* clear irq stat for previous use */
  174508. + ipu_cm_write(ipu, IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq));
  174509. + /* enable the interrupt */
  174510. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  174511. + reg |= IPUIRQ_2_MASK(irq);
  174512. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  174513. +out:
  174514. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174515. +
  174516. + _ipu_put(ipu);
  174517. +
  174518. + return ret;
  174519. +}
  174520. +EXPORT_SYMBOL(ipu_request_irq);
  174521. +
  174522. +/*!
  174523. + * This function unregisters an interrupt handler for the specified interrupt
  174524. + * line. The interrupt lines are defined in \b ipu_irq_line enum.
  174525. + *
  174526. + * @param ipu ipu handler
  174527. + * @param irq Interrupt line to get status for.
  174528. + *
  174529. + * @param dev_id Input parameter for pointer of data to be passed
  174530. + * to the handler. This must match value passed to
  174531. + * ipu_request_irq().
  174532. + *
  174533. + */
  174534. +void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id)
  174535. +{
  174536. + uint32_t reg;
  174537. + unsigned long lock_flags;
  174538. +
  174539. + _ipu_get(ipu);
  174540. +
  174541. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174542. +
  174543. + /* disable the interrupt */
  174544. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  174545. + reg &= ~IPUIRQ_2_MASK(irq);
  174546. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  174547. + if (ipu->irq_list[irq].dev_id == dev_id)
  174548. + memset(&ipu->irq_list[irq], 0, sizeof(ipu->irq_list[irq]));
  174549. +
  174550. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174551. +
  174552. + _ipu_put(ipu);
  174553. +}
  174554. +EXPORT_SYMBOL(ipu_free_irq);
  174555. +
  174556. +uint32_t ipu_get_cur_buffer_idx(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type)
  174557. +{
  174558. + uint32_t reg, dma_chan;
  174559. +
  174560. + dma_chan = channel_2_dma(channel, type);
  174561. + if (!idma_is_valid(dma_chan))
  174562. + return -EINVAL;
  174563. +
  174564. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan));
  174565. + if ((reg & idma_mask(dma_chan)) && _ipu_is_trb_chan(dma_chan)) {
  174566. + reg = ipu_cm_read(ipu, IPU_CHA_TRIPLE_CUR_BUF(dma_chan));
  174567. + return (reg & tri_cur_buf_mask(dma_chan)) >>
  174568. + tri_cur_buf_shift(dma_chan);
  174569. + } else {
  174570. + reg = ipu_cm_read(ipu, IPU_CHA_CUR_BUF(dma_chan));
  174571. + if (reg & idma_mask(dma_chan))
  174572. + return 1;
  174573. + else
  174574. + return 0;
  174575. + }
  174576. +}
  174577. +EXPORT_SYMBOL(ipu_get_cur_buffer_idx);
  174578. +
  174579. +uint32_t _ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel)
  174580. +{
  174581. + uint32_t stat = 0;
  174582. + uint32_t task_stat_reg = ipu_cm_read(ipu, IPU_PROC_TASK_STAT);
  174583. +
  174584. + switch (channel) {
  174585. + case MEM_PRP_VF_MEM:
  174586. + stat = (task_stat_reg & TSTAT_VF_MASK) >> TSTAT_VF_OFFSET;
  174587. + break;
  174588. + case MEM_VDI_PRP_VF_MEM:
  174589. + stat = (task_stat_reg & TSTAT_VF_MASK) >> TSTAT_VF_OFFSET;
  174590. + break;
  174591. + case MEM_ROT_VF_MEM:
  174592. + stat =
  174593. + (task_stat_reg & TSTAT_VF_ROT_MASK) >> TSTAT_VF_ROT_OFFSET;
  174594. + break;
  174595. + case MEM_PRP_ENC_MEM:
  174596. + stat = (task_stat_reg & TSTAT_ENC_MASK) >> TSTAT_ENC_OFFSET;
  174597. + break;
  174598. + case MEM_ROT_ENC_MEM:
  174599. + stat =
  174600. + (task_stat_reg & TSTAT_ENC_ROT_MASK) >>
  174601. + TSTAT_ENC_ROT_OFFSET;
  174602. + break;
  174603. + case MEM_PP_MEM:
  174604. + stat = (task_stat_reg & TSTAT_PP_MASK) >> TSTAT_PP_OFFSET;
  174605. + break;
  174606. + case MEM_ROT_PP_MEM:
  174607. + stat =
  174608. + (task_stat_reg & TSTAT_PP_ROT_MASK) >> TSTAT_PP_ROT_OFFSET;
  174609. + break;
  174610. +
  174611. + default:
  174612. + stat = TASK_STAT_IDLE;
  174613. + break;
  174614. + }
  174615. + return stat;
  174616. +}
  174617. +
  174618. +/*!
  174619. + * This function check for a logical channel status
  174620. + *
  174621. + * @param ipu ipu handler
  174622. + * @param channel Input parameter for the logical channel ID.
  174623. + *
  174624. + * @return This function returns 0 on idle and 1 on busy.
  174625. + *
  174626. + */
  174627. +uint32_t ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel)
  174628. +{
  174629. + uint32_t dma_status;
  174630. +
  174631. + _ipu_get(ipu);
  174632. + mutex_lock(&ipu->mutex_lock);
  174633. + dma_status = ipu_is_channel_busy(ipu, channel);
  174634. + mutex_unlock(&ipu->mutex_lock);
  174635. + _ipu_put(ipu);
  174636. +
  174637. + dev_dbg(ipu->dev, "%s, dma_status:%d.\n", __func__, dma_status);
  174638. +
  174639. + return dma_status;
  174640. +}
  174641. +EXPORT_SYMBOL(ipu_channel_status);
  174642. +
  174643. +int32_t ipu_swap_channel(struct ipu_soc *ipu, ipu_channel_t from_ch, ipu_channel_t to_ch)
  174644. +{
  174645. + uint32_t reg;
  174646. + unsigned long lock_flags;
  174647. + int from_dma = channel_2_dma(from_ch, IPU_INPUT_BUFFER);
  174648. + int to_dma = channel_2_dma(to_ch, IPU_INPUT_BUFFER);
  174649. +
  174650. + mutex_lock(&ipu->mutex_lock);
  174651. +
  174652. + /* enable target channel */
  174653. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(to_dma));
  174654. + ipu_idmac_write(ipu, reg | idma_mask(to_dma), IDMAC_CHA_EN(to_dma));
  174655. +
  174656. + ipu->channel_enable_mask |= 1L << IPU_CHAN_ID(to_ch);
  174657. +
  174658. + /* switch dp dc */
  174659. + _ipu_dp_dc_disable(ipu, from_ch, true);
  174660. +
  174661. + /* disable source channel */
  174662. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(from_dma));
  174663. + ipu_idmac_write(ipu, reg & ~idma_mask(from_dma), IDMAC_CHA_EN(from_dma));
  174664. + ipu_cm_write(ipu, idma_mask(from_dma), IPU_CHA_CUR_BUF(from_dma));
  174665. + ipu_cm_write(ipu, tri_cur_buf_mask(from_dma),
  174666. + IPU_CHA_TRIPLE_CUR_BUF(from_dma));
  174667. +
  174668. + ipu->channel_enable_mask &= ~(1L << IPU_CHAN_ID(from_ch));
  174669. +
  174670. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  174671. + _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 0);
  174672. + _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 1);
  174673. + _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 2);
  174674. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  174675. +
  174676. + mutex_unlock(&ipu->mutex_lock);
  174677. +
  174678. + return 0;
  174679. +}
  174680. +EXPORT_SYMBOL(ipu_swap_channel);
  174681. +
  174682. +uint32_t bytes_per_pixel(uint32_t fmt)
  174683. +{
  174684. + switch (fmt) {
  174685. + case IPU_PIX_FMT_GENERIC: /*generic data */
  174686. + case IPU_PIX_FMT_RGB332:
  174687. + case IPU_PIX_FMT_YUV420P:
  174688. + case IPU_PIX_FMT_YVU420P:
  174689. + case IPU_PIX_FMT_YUV422P:
  174690. + case IPU_PIX_FMT_YUV444P:
  174691. + return 1;
  174692. + break;
  174693. + case IPU_PIX_FMT_GENERIC_16: /* generic data */
  174694. + case IPU_PIX_FMT_RGB565:
  174695. + case IPU_PIX_FMT_YUYV:
  174696. + case IPU_PIX_FMT_UYVY:
  174697. + return 2;
  174698. + break;
  174699. + case IPU_PIX_FMT_BGR24:
  174700. + case IPU_PIX_FMT_RGB24:
  174701. + case IPU_PIX_FMT_YUV444:
  174702. + return 3;
  174703. + break;
  174704. + case IPU_PIX_FMT_GENERIC_32: /*generic data */
  174705. + case IPU_PIX_FMT_BGR32:
  174706. + case IPU_PIX_FMT_BGRA32:
  174707. + case IPU_PIX_FMT_RGB32:
  174708. + case IPU_PIX_FMT_RGBA32:
  174709. + case IPU_PIX_FMT_ABGR32:
  174710. + return 4;
  174711. + break;
  174712. + default:
  174713. + return 1;
  174714. + break;
  174715. + }
  174716. + return 0;
  174717. +}
  174718. +EXPORT_SYMBOL(bytes_per_pixel);
  174719. +
  174720. +ipu_color_space_t format_to_colorspace(uint32_t fmt)
  174721. +{
  174722. + switch (fmt) {
  174723. + case IPU_PIX_FMT_RGB666:
  174724. + case IPU_PIX_FMT_RGB565:
  174725. + case IPU_PIX_FMT_BGR24:
  174726. + case IPU_PIX_FMT_RGB24:
  174727. + case IPU_PIX_FMT_GBR24:
  174728. + case IPU_PIX_FMT_BGR32:
  174729. + case IPU_PIX_FMT_BGRA32:
  174730. + case IPU_PIX_FMT_RGB32:
  174731. + case IPU_PIX_FMT_RGBA32:
  174732. + case IPU_PIX_FMT_ABGR32:
  174733. + case IPU_PIX_FMT_LVDS666:
  174734. + case IPU_PIX_FMT_LVDS888:
  174735. + return RGB;
  174736. + break;
  174737. +
  174738. + default:
  174739. + return YCbCr;
  174740. + break;
  174741. + }
  174742. + return RGB;
  174743. +}
  174744. +
  174745. +bool ipu_pixel_format_has_alpha(uint32_t fmt)
  174746. +{
  174747. + switch (fmt) {
  174748. + case IPU_PIX_FMT_RGBA32:
  174749. + case IPU_PIX_FMT_BGRA32:
  174750. + case IPU_PIX_FMT_ABGR32:
  174751. + return true;
  174752. + break;
  174753. + default:
  174754. + return false;
  174755. + break;
  174756. + }
  174757. + return false;
  174758. +}
  174759. +
  174760. +bool ipu_ch_param_bad_alpha_pos(uint32_t pixel_fmt)
  174761. +{
  174762. + return _ipu_ch_param_bad_alpha_pos(pixel_fmt);
  174763. +}
  174764. +EXPORT_SYMBOL(ipu_ch_param_bad_alpha_pos);
  174765. +
  174766. +#ifdef CONFIG_PM
  174767. +static int ipu_suspend(struct device *dev)
  174768. +{
  174769. + struct ipu_soc *ipu = dev_get_drvdata(dev);
  174770. +
  174771. + /* All IDMAC channel and IPU clock should be disabled.*/
  174772. + if (ipu->pdata->pg)
  174773. + ipu->pdata->pg(1);
  174774. +
  174775. + dev_dbg(dev, "ipu suspend.\n");
  174776. + return 0;
  174777. +}
  174778. +
  174779. +static int ipu_resume(struct device *dev)
  174780. +{
  174781. + struct ipu_soc *ipu = dev_get_drvdata(dev);
  174782. +
  174783. + if (ipu->pdata->pg) {
  174784. + ipu->pdata->pg(0);
  174785. +
  174786. + _ipu_get(ipu);
  174787. + _ipu_dmfc_init(ipu, dmfc_type_setup, 1);
  174788. + /* Set sync refresh channels as high priority */
  174789. + ipu_idmac_write(ipu, 0x18800001L, IDMAC_CHA_PRI(0));
  174790. + _ipu_put(ipu);
  174791. + }
  174792. + dev_dbg(dev, "ipu resume.\n");
  174793. + return 0;
  174794. +}
  174795. +
  174796. +int ipu_runtime_suspend(struct device *dev)
  174797. +{
  174798. + release_bus_freq(BUS_FREQ_HIGH);
  174799. + dev_dbg(dev, "ipu busfreq high release.\n");
  174800. +
  174801. + return 0;
  174802. +}
  174803. +
  174804. +int ipu_runtime_resume(struct device *dev)
  174805. +{
  174806. + request_bus_freq(BUS_FREQ_HIGH);
  174807. + dev_dbg(dev, "ipu busfreq high requst.\n");
  174808. +
  174809. + return 0;
  174810. +}
  174811. +
  174812. +static const struct dev_pm_ops ipu_pm_ops = {
  174813. + SET_RUNTIME_PM_OPS(ipu_runtime_suspend, ipu_runtime_resume, NULL)
  174814. + SET_SYSTEM_SLEEP_PM_OPS(ipu_suspend, ipu_resume)
  174815. +};
  174816. +#endif
  174817. +
  174818. +/*!
  174819. + * This structure contains pointers to the power management callback functions.
  174820. + */
  174821. +static struct platform_driver mxcipu_driver = {
  174822. + .driver = {
  174823. + .name = "imx-ipuv3",
  174824. + .of_match_table = imx_ipuv3_dt_ids,
  174825. + #ifdef CONFIG_PM
  174826. + .pm = &ipu_pm_ops,
  174827. + #endif
  174828. + },
  174829. + .probe = ipu_probe,
  174830. + .id_table = imx_ipu_type,
  174831. + .remove = ipu_remove,
  174832. +};
  174833. +
  174834. +int32_t __init ipu_gen_init(void)
  174835. +{
  174836. + int32_t ret;
  174837. +
  174838. + ret = platform_driver_register(&mxcipu_driver);
  174839. + return 0;
  174840. +}
  174841. +
  174842. +subsys_initcall(ipu_gen_init);
  174843. +
  174844. +static void __exit ipu_gen_uninit(void)
  174845. +{
  174846. + platform_driver_unregister(&mxcipu_driver);
  174847. +}
  174848. +
  174849. +module_exit(ipu_gen_uninit);
  174850. diff -Nur linux-3.14.15/drivers/mxc/ipu3/ipu_device.c linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_device.c
  174851. --- linux-3.14.15/drivers/mxc/ipu3/ipu_device.c 1970-01-01 01:00:00.000000000 +0100
  174852. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_device.c 2014-08-20 19:31:46.140869056 +0200
  174853. @@ -0,0 +1,3717 @@
  174854. +/*
  174855. + * Copyright 2005-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  174856. + */
  174857. +
  174858. +/*
  174859. + * The code contained herein is licensed under the GNU General Public
  174860. + * License. You may obtain a copy of the GNU General Public License
  174861. + * Version 2 or later at the following locations:
  174862. + *
  174863. + * http://www.opensource.org/licenses/gpl-license.html
  174864. + * http://www.gnu.org/copyleft/gpl.html
  174865. + */
  174866. +
  174867. +/*!
  174868. + * @file ipu_device.c
  174869. + *
  174870. + * @brief This file contains the IPUv3 driver device interface and fops functions.
  174871. + *
  174872. + * @ingroup IPU
  174873. + */
  174874. +#include <linux/clk.h>
  174875. +#include <linux/cpumask.h>
  174876. +#include <linux/delay.h>
  174877. +#include <linux/dma-mapping.h>
  174878. +#include <linux/err.h>
  174879. +#include <linux/init.h>
  174880. +#include <linux/io.h>
  174881. +#include <linux/ipu-v3.h>
  174882. +#include <linux/kernel.h>
  174883. +#include <linux/kthread.h>
  174884. +#include <linux/module.h>
  174885. +#include <linux/platform_device.h>
  174886. +#include <linux/poll.h>
  174887. +#include <linux/sched.h>
  174888. +#include <linux/sched/rt.h>
  174889. +#include <linux/slab.h>
  174890. +#include <linux/spinlock.h>
  174891. +#include <linux/time.h>
  174892. +#include <linux/types.h>
  174893. +#include <linux/vmalloc.h>
  174894. +#include <linux/wait.h>
  174895. +
  174896. +#include <asm/cacheflush.h>
  174897. +#include <asm/outercache.h>
  174898. +
  174899. +#include "ipu_param_mem.h"
  174900. +#include "ipu_regs.h"
  174901. +#include "vdoa.h"
  174902. +
  174903. +#define CHECK_RETCODE(cont, str, err, label, ret) \
  174904. +do { \
  174905. + if (cont) { \
  174906. + dev_err(t->dev, "ERR:[0x%p]-no:0x%x "#str" ret:%d," \
  174907. + "line:%d\n", t, t->task_no, ret, __LINE__);\
  174908. + if (ret != -EACCES) { \
  174909. + t->state = err; \
  174910. + goto label; \
  174911. + } \
  174912. + } \
  174913. +} while (0)
  174914. +
  174915. +#define CHECK_RETCODE_CONT(cont, str, err, ret) \
  174916. +do { \
  174917. + if (cont) { \
  174918. + dev_err(t->dev, "ERR:[0x%p]-no:0x%x"#str" ret:%d," \
  174919. + "line:%d\n", t, t->task_no, ret, __LINE__);\
  174920. + if (ret != -EACCES) { \
  174921. + if (t->state == STATE_OK) \
  174922. + t->state = err; \
  174923. + } \
  174924. + } \
  174925. +} while (0)
  174926. +
  174927. +#undef DBG_IPU_PERF
  174928. +#ifdef DBG_IPU_PERF
  174929. +#define CHECK_PERF(ts) \
  174930. +do { \
  174931. + getnstimeofday(ts); \
  174932. +} while (0)
  174933. +
  174934. +#define DECLARE_PERF_VAR \
  174935. + struct timespec ts_queue; \
  174936. + struct timespec ts_dotask; \
  174937. + struct timespec ts_waitirq; \
  174938. + struct timespec ts_sche; \
  174939. + struct timespec ts_rel; \
  174940. + struct timespec ts_frame
  174941. +
  174942. +#define PRINT_TASK_STATISTICS \
  174943. +do { \
  174944. + ts_queue = timespec_sub(tsk->ts_dotask, tsk->ts_queue); \
  174945. + ts_dotask = timespec_sub(tsk->ts_waitirq, tsk->ts_dotask); \
  174946. + ts_waitirq = timespec_sub(tsk->ts_inirq, tsk->ts_waitirq); \
  174947. + ts_sche = timespec_sub(tsk->ts_wakeup, tsk->ts_inirq); \
  174948. + ts_rel = timespec_sub(tsk->ts_rel, tsk->ts_wakeup); \
  174949. + ts_frame = timespec_sub(tsk->ts_rel, tsk->ts_queue); \
  174950. + dev_dbg(tsk->dev, "[0x%p] no-0x%x, ts_q:%ldus, ts_do:%ldus," \
  174951. + "ts_waitirq:%ldus,ts_sche:%ldus, ts_rel:%ldus," \
  174952. + "ts_frame: %ldus\n", tsk, tsk->task_no, \
  174953. + ts_queue.tv_nsec / NSEC_PER_USEC + ts_queue.tv_sec * USEC_PER_SEC,\
  174954. + ts_dotask.tv_nsec / NSEC_PER_USEC + ts_dotask.tv_sec * USEC_PER_SEC,\
  174955. + ts_waitirq.tv_nsec / NSEC_PER_USEC + ts_waitirq.tv_sec * USEC_PER_SEC,\
  174956. + ts_sche.tv_nsec / NSEC_PER_USEC + ts_sche.tv_sec * USEC_PER_SEC,\
  174957. + ts_rel.tv_nsec / NSEC_PER_USEC + ts_rel.tv_sec * USEC_PER_SEC,\
  174958. + ts_frame.tv_nsec / NSEC_PER_USEC + ts_frame.tv_sec * USEC_PER_SEC); \
  174959. + if ((ts_frame.tv_nsec/NSEC_PER_USEC + ts_frame.tv_sec*USEC_PER_SEC) > \
  174960. + 80000) \
  174961. + dev_dbg(tsk->dev, "ts_frame larger than 80ms [0x%p] no-0x%x.\n"\
  174962. + , tsk, tsk->task_no); \
  174963. +} while (0)
  174964. +#else
  174965. +#define CHECK_PERF(ts)
  174966. +#define DECLARE_PERF_VAR
  174967. +#define PRINT_TASK_STATISTICS
  174968. +#endif
  174969. +
  174970. +#define IPU_PP_CH_VF (IPU_TASK_ID_VF - 1)
  174971. +#define IPU_PP_CH_PP (IPU_TASK_ID_PP - 1)
  174972. +#define MAX_PP_CH (IPU_TASK_ID_MAX - 1)
  174973. +#define VDOA_DEF_TIMEOUT_MS (HZ/2)
  174974. +
  174975. +/* Strucutures and variables for exporting MXC IPU as device*/
  174976. +typedef enum {
  174977. + STATE_OK = 0,
  174978. + STATE_QUEUE,
  174979. + STATE_IN_PROGRESS,
  174980. + STATE_ERR,
  174981. + STATE_TIMEOUT,
  174982. + STATE_RES_TIMEOUT,
  174983. + STATE_NO_IPU,
  174984. + STATE_NO_IRQ,
  174985. + STATE_IPU_BUSY,
  174986. + STATE_IRQ_FAIL,
  174987. + STATE_IRQ_TIMEOUT,
  174988. + STATE_ENABLE_CHAN_FAIL,
  174989. + STATE_DISABLE_CHAN_FAIL,
  174990. + STATE_SEL_BUF_FAIL,
  174991. + STATE_INIT_CHAN_FAIL,
  174992. + STATE_LINK_CHAN_FAIL,
  174993. + STATE_UNLINK_CHAN_FAIL,
  174994. + STATE_INIT_CHAN_BUF_FAIL,
  174995. + STATE_INIT_CHAN_BAND_FAIL,
  174996. + STATE_SYS_NO_MEM,
  174997. + STATE_VDOA_IRQ_TIMEOUT,
  174998. + STATE_VDOA_IRQ_FAIL,
  174999. + STATE_VDOA_TASK_FAIL,
  175000. +} ipu_state_t;
  175001. +
  175002. +enum {
  175003. + INPUT_CHAN_VDI_P = 1,
  175004. + INPUT_CHAN,
  175005. + INPUT_CHAN_VDI_N,
  175006. +};
  175007. +
  175008. +struct ipu_state_msg {
  175009. + int state;
  175010. + char *msg;
  175011. +} state_msg[] = {
  175012. + {STATE_OK, "ok"},
  175013. + {STATE_QUEUE, "split queue"},
  175014. + {STATE_IN_PROGRESS, "split in progress"},
  175015. + {STATE_ERR, "error"},
  175016. + {STATE_TIMEOUT, "split task timeout"},
  175017. + {STATE_RES_TIMEOUT, "wait resource timeout"},
  175018. + {STATE_NO_IPU, "no ipu found"},
  175019. + {STATE_NO_IRQ, "no irq found for task"},
  175020. + {STATE_IPU_BUSY, "ipu busy"},
  175021. + {STATE_IRQ_FAIL, "request irq failed"},
  175022. + {STATE_IRQ_TIMEOUT, "wait for irq timeout"},
  175023. + {STATE_ENABLE_CHAN_FAIL, "ipu enable channel fail"},
  175024. + {STATE_DISABLE_CHAN_FAIL, "ipu disable channel fail"},
  175025. + {STATE_SEL_BUF_FAIL, "ipu select buf fail"},
  175026. + {STATE_INIT_CHAN_FAIL, "ipu init channel fail"},
  175027. + {STATE_LINK_CHAN_FAIL, "ipu link channel fail"},
  175028. + {STATE_UNLINK_CHAN_FAIL, "ipu unlink channel fail"},
  175029. + {STATE_INIT_CHAN_BUF_FAIL, "ipu init channel buffer fail"},
  175030. + {STATE_INIT_CHAN_BAND_FAIL, "ipu init channel band mode fail"},
  175031. + {STATE_SYS_NO_MEM, "sys no mem: -ENOMEM"},
  175032. + {STATE_VDOA_IRQ_TIMEOUT, "wait for vdoa irq timeout"},
  175033. + {STATE_VDOA_IRQ_FAIL, "vdoa irq fail"},
  175034. + {STATE_VDOA_TASK_FAIL, "vdoa task fail"},
  175035. +};
  175036. +
  175037. +struct stripe_setting {
  175038. + u32 iw;
  175039. + u32 ih;
  175040. + u32 ow;
  175041. + u32 oh;
  175042. + u32 outh_resize_ratio;
  175043. + u32 outv_resize_ratio;
  175044. + u32 i_left_pos;
  175045. + u32 i_right_pos;
  175046. + u32 i_top_pos;
  175047. + u32 i_bottom_pos;
  175048. + u32 o_left_pos;
  175049. + u32 o_right_pos;
  175050. + u32 o_top_pos;
  175051. + u32 o_bottom_pos;
  175052. + u32 rl_split_line;
  175053. + u32 ud_split_line;
  175054. +};
  175055. +
  175056. +struct task_set {
  175057. +#define NULL_MODE 0x0
  175058. +#define IC_MODE 0x1
  175059. +#define ROT_MODE 0x2
  175060. +#define VDI_MODE 0x4
  175061. +#define IPU_PREPROCESS_MODE_MASK (IC_MODE | ROT_MODE | VDI_MODE)
  175062. +/* VDOA_MODE means this task use vdoa, and VDOA has two modes:
  175063. + * BAND MODE and non-BAND MODE. Non-band mode will do transfer data
  175064. + * to memory. BAND mode needs hareware sync with IPU, it is used default
  175065. + * if connected to VDIC.
  175066. + */
  175067. +#define VDOA_MODE 0x8
  175068. +#define VDOA_BAND_MODE 0x10
  175069. + u8 mode;
  175070. +#define IC_VF 0x1
  175071. +#define IC_PP 0x2
  175072. +#define ROT_VF 0x4
  175073. +#define ROT_PP 0x8
  175074. +#define VDI_VF 0x10
  175075. +#define VDOA_ONLY 0x20
  175076. + u8 task;
  175077. +#define NO_SPLIT 0x0
  175078. +#define RL_SPLIT 0x1
  175079. +#define UD_SPLIT 0x2
  175080. +#define LEFT_STRIPE 0x1
  175081. +#define RIGHT_STRIPE 0x2
  175082. +#define UP_STRIPE 0x4
  175083. +#define DOWN_STRIPE 0x8
  175084. +#define SPLIT_MASK 0xF
  175085. + u8 split_mode;
  175086. + u8 band_lines;
  175087. + ipu_channel_t ic_chan;
  175088. + ipu_channel_t rot_chan;
  175089. + ipu_channel_t vdi_ic_p_chan;
  175090. + ipu_channel_t vdi_ic_n_chan;
  175091. +
  175092. + u32 i_off;
  175093. + u32 i_uoff;
  175094. + u32 i_voff;
  175095. + u32 istride;
  175096. +
  175097. + u32 ov_off;
  175098. + u32 ov_uoff;
  175099. + u32 ov_voff;
  175100. + u32 ovstride;
  175101. +
  175102. + u32 ov_alpha_off;
  175103. + u32 ov_alpha_stride;
  175104. +
  175105. + u32 o_off;
  175106. + u32 o_uoff;
  175107. + u32 o_voff;
  175108. + u32 ostride;
  175109. +
  175110. + u32 r_fmt;
  175111. + u32 r_width;
  175112. + u32 r_height;
  175113. + u32 r_stride;
  175114. + dma_addr_t r_paddr;
  175115. +
  175116. + struct stripe_setting sp_setting;
  175117. +};
  175118. +
  175119. +struct ipu_split_task {
  175120. + struct ipu_task task;
  175121. + struct ipu_task_entry *parent_task;
  175122. + struct ipu_task_entry *child_task;
  175123. + u32 task_no;
  175124. +};
  175125. +
  175126. +struct ipu_task_entry {
  175127. + struct ipu_input input;
  175128. + struct ipu_output output;
  175129. +
  175130. + bool overlay_en;
  175131. + struct ipu_overlay overlay;
  175132. +#define DEF_TIMEOUT_MS 1000
  175133. +#define DEF_DELAY_MS 20
  175134. + int timeout;
  175135. + int irq;
  175136. +
  175137. + u8 task_id;
  175138. + u8 ipu_id;
  175139. + u8 task_in_list;
  175140. + u8 split_done;
  175141. + struct mutex split_lock;
  175142. + struct mutex vdic_lock;
  175143. + wait_queue_head_t split_waitq;
  175144. +
  175145. + struct list_head node;
  175146. + struct list_head split_list;
  175147. + struct ipu_soc *ipu;
  175148. + struct device *dev;
  175149. + struct task_set set;
  175150. + wait_queue_head_t task_waitq;
  175151. + struct completion irq_comp;
  175152. + struct kref refcount;
  175153. + ipu_state_t state;
  175154. + u32 task_no;
  175155. + atomic_t done;
  175156. + atomic_t res_free;
  175157. + atomic_t res_get;
  175158. +
  175159. + struct ipu_task_entry *parent;
  175160. + char *vditmpbuf[2];
  175161. + u32 old_save_lines;
  175162. + u32 old_size;
  175163. + bool buf1filled;
  175164. + bool buf0filled;
  175165. +
  175166. + vdoa_handle_t vdoa_handle;
  175167. + struct vdoa_output_mem {
  175168. + void *vaddr;
  175169. + dma_addr_t paddr;
  175170. + int size;
  175171. + } vdoa_dma;
  175172. +
  175173. +#ifdef DBG_IPU_PERF
  175174. + struct timespec ts_queue;
  175175. + struct timespec ts_dotask;
  175176. + struct timespec ts_waitirq;
  175177. + struct timespec ts_inirq;
  175178. + struct timespec ts_wakeup;
  175179. + struct timespec ts_rel;
  175180. +#endif
  175181. +};
  175182. +
  175183. +struct ipu_channel_tabel {
  175184. + struct mutex lock;
  175185. + u8 used[MXC_IPU_MAX_NUM][MAX_PP_CH];
  175186. + u8 vdoa_used;
  175187. +};
  175188. +
  175189. +struct ipu_thread_data {
  175190. + struct ipu_soc *ipu;
  175191. + u32 id;
  175192. + u32 is_vdoa;
  175193. +};
  175194. +
  175195. +struct ipu_alloc_list {
  175196. + struct list_head list;
  175197. + dma_addr_t phy_addr;
  175198. + void *cpu_addr;
  175199. + u32 size;
  175200. + void *file_index;
  175201. +};
  175202. +
  175203. +static LIST_HEAD(ipu_alloc_list);
  175204. +static DEFINE_MUTEX(ipu_alloc_lock);
  175205. +static struct ipu_channel_tabel ipu_ch_tbl;
  175206. +static LIST_HEAD(ipu_task_list);
  175207. +static DEFINE_SPINLOCK(ipu_task_list_lock);
  175208. +static DECLARE_WAIT_QUEUE_HEAD(thread_waitq);
  175209. +static DECLARE_WAIT_QUEUE_HEAD(res_waitq);
  175210. +static atomic_t req_cnt;
  175211. +static atomic_t file_index = ATOMIC_INIT(1);
  175212. +static int major;
  175213. +static int max_ipu_no;
  175214. +static int thread_id;
  175215. +static atomic_t frame_no;
  175216. +static struct class *ipu_class;
  175217. +static struct device *ipu_dev;
  175218. +static int debug;
  175219. +module_param(debug, int, 0600);
  175220. +#ifdef DBG_IPU_PERF
  175221. +static struct timespec ts_frame_max;
  175222. +static u32 ts_frame_avg;
  175223. +static atomic_t frame_cnt;
  175224. +#endif
  175225. +
  175226. +static bool deinterlace_3_field(struct ipu_task_entry *t)
  175227. +{
  175228. + return ((t->set.mode & VDI_MODE) &&
  175229. + (t->input.deinterlace.motion != HIGH_MOTION));
  175230. +}
  175231. +
  175232. +static u32 tiled_filed_size(struct ipu_task_entry *t)
  175233. +{
  175234. + u32 field_size;
  175235. +
  175236. + /* note: page_align is required by VPU hw ouput buffer */
  175237. + field_size = TILED_NV12_FRAME_SIZE(t->input.width, t->input.height/2);
  175238. + return field_size;
  175239. +}
  175240. +
  175241. +static bool only_ic(u8 mode)
  175242. +{
  175243. + mode = mode & IPU_PREPROCESS_MODE_MASK;
  175244. + return ((mode == IC_MODE) || (mode == VDI_MODE));
  175245. +}
  175246. +
  175247. +static bool only_rot(u8 mode)
  175248. +{
  175249. + mode = mode & IPU_PREPROCESS_MODE_MASK;
  175250. + return (mode == ROT_MODE);
  175251. +}
  175252. +
  175253. +static bool ic_and_rot(u8 mode)
  175254. +{
  175255. + mode = mode & IPU_PREPROCESS_MODE_MASK;
  175256. + return ((mode == (IC_MODE | ROT_MODE)) ||
  175257. + (mode == (VDI_MODE | ROT_MODE)));
  175258. +}
  175259. +
  175260. +static bool need_split(struct ipu_task_entry *t)
  175261. +{
  175262. + return ((t->set.split_mode != NO_SPLIT) || (t->task_no & SPLIT_MASK));
  175263. +}
  175264. +
  175265. +unsigned int fmt_to_bpp(unsigned int pixelformat)
  175266. +{
  175267. + u32 bpp;
  175268. +
  175269. + switch (pixelformat) {
  175270. + case IPU_PIX_FMT_RGB565:
  175271. + /*interleaved 422*/
  175272. + case IPU_PIX_FMT_YUYV:
  175273. + case IPU_PIX_FMT_UYVY:
  175274. + /*non-interleaved 422*/
  175275. + case IPU_PIX_FMT_YUV422P:
  175276. + case IPU_PIX_FMT_YVU422P:
  175277. + bpp = 16;
  175278. + break;
  175279. + case IPU_PIX_FMT_BGR24:
  175280. + case IPU_PIX_FMT_RGB24:
  175281. + case IPU_PIX_FMT_YUV444:
  175282. + case IPU_PIX_FMT_YUV444P:
  175283. + bpp = 24;
  175284. + break;
  175285. + case IPU_PIX_FMT_BGR32:
  175286. + case IPU_PIX_FMT_BGRA32:
  175287. + case IPU_PIX_FMT_RGB32:
  175288. + case IPU_PIX_FMT_RGBA32:
  175289. + case IPU_PIX_FMT_ABGR32:
  175290. + bpp = 32;
  175291. + break;
  175292. + /*non-interleaved 420*/
  175293. + case IPU_PIX_FMT_YUV420P:
  175294. + case IPU_PIX_FMT_YVU420P:
  175295. + case IPU_PIX_FMT_YUV420P2:
  175296. + case IPU_PIX_FMT_NV12:
  175297. + bpp = 12;
  175298. + break;
  175299. + default:
  175300. + bpp = 8;
  175301. + break;
  175302. + }
  175303. + return bpp;
  175304. +}
  175305. +EXPORT_SYMBOL_GPL(fmt_to_bpp);
  175306. +
  175307. +cs_t colorspaceofpixel(int fmt)
  175308. +{
  175309. + switch (fmt) {
  175310. + case IPU_PIX_FMT_RGB565:
  175311. + case IPU_PIX_FMT_BGR24:
  175312. + case IPU_PIX_FMT_RGB24:
  175313. + case IPU_PIX_FMT_BGRA32:
  175314. + case IPU_PIX_FMT_BGR32:
  175315. + case IPU_PIX_FMT_RGBA32:
  175316. + case IPU_PIX_FMT_RGB32:
  175317. + case IPU_PIX_FMT_ABGR32:
  175318. + return RGB_CS;
  175319. + break;
  175320. + case IPU_PIX_FMT_UYVY:
  175321. + case IPU_PIX_FMT_YUYV:
  175322. + case IPU_PIX_FMT_YUV420P2:
  175323. + case IPU_PIX_FMT_YUV420P:
  175324. + case IPU_PIX_FMT_YVU420P:
  175325. + case IPU_PIX_FMT_YVU422P:
  175326. + case IPU_PIX_FMT_YUV422P:
  175327. + case IPU_PIX_FMT_YUV444:
  175328. + case IPU_PIX_FMT_YUV444P:
  175329. + case IPU_PIX_FMT_NV12:
  175330. + case IPU_PIX_FMT_TILED_NV12:
  175331. + case IPU_PIX_FMT_TILED_NV12F:
  175332. + return YUV_CS;
  175333. + break;
  175334. + default:
  175335. + return NULL_CS;
  175336. + }
  175337. +}
  175338. +EXPORT_SYMBOL_GPL(colorspaceofpixel);
  175339. +
  175340. +int need_csc(int ifmt, int ofmt)
  175341. +{
  175342. + cs_t ics, ocs;
  175343. +
  175344. + ics = colorspaceofpixel(ifmt);
  175345. + ocs = colorspaceofpixel(ofmt);
  175346. +
  175347. + if ((ics == NULL_CS) || (ocs == NULL_CS))
  175348. + return -1;
  175349. + else if (ics != ocs)
  175350. + return 1;
  175351. +
  175352. + return 0;
  175353. +}
  175354. +EXPORT_SYMBOL_GPL(need_csc);
  175355. +
  175356. +static int soc_max_in_width(u32 is_vdoa)
  175357. +{
  175358. + return is_vdoa ? 8192 : 4096;
  175359. +}
  175360. +
  175361. +static int soc_max_vdi_in_width(void)
  175362. +{
  175363. + return IPU_MAX_VDI_IN_WIDTH;
  175364. +}
  175365. +static int soc_max_in_height(void)
  175366. +{
  175367. + return 4096;
  175368. +}
  175369. +
  175370. +static int soc_max_out_width(void)
  175371. +{
  175372. + /* mx51/mx53/mx6q is 1024*/
  175373. + return 1024;
  175374. +}
  175375. +
  175376. +static int soc_max_out_height(void)
  175377. +{
  175378. + /* mx51/mx53/mx6q is 1024*/
  175379. + return 1024;
  175380. +}
  175381. +
  175382. +static void dump_task_info(struct ipu_task_entry *t)
  175383. +{
  175384. + if (!debug)
  175385. + return;
  175386. + dev_dbg(t->dev, "[0x%p]input:\n", (void *)t);
  175387. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->input.format);
  175388. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->input.width);
  175389. + dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->input.height);
  175390. + dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n", (void *)t, t->input.crop.w);
  175391. + dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n", (void *)t, t->input.crop.h);
  175392. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
  175393. + (void *)t, t->input.crop.pos.x);
  175394. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
  175395. + (void *)t, t->input.crop.pos.y);
  175396. + dev_dbg(t->dev, "[0x%p]input buffer:\n", (void *)t);
  175397. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->input.paddr);
  175398. + dev_dbg(t->dev, "[0x%p]\ti_off = 0x%x\n", (void *)t, t->set.i_off);
  175399. + dev_dbg(t->dev, "[0x%p]\ti_uoff = 0x%x\n", (void *)t, t->set.i_uoff);
  175400. + dev_dbg(t->dev, "[0x%p]\ti_voff = 0x%x\n", (void *)t, t->set.i_voff);
  175401. + dev_dbg(t->dev, "[0x%p]\tistride = %d\n", (void *)t, t->set.istride);
  175402. + if (t->input.deinterlace.enable) {
  175403. + dev_dbg(t->dev, "[0x%p]deinterlace enabled with:\n", (void *)t);
  175404. + if (t->input.deinterlace.motion != HIGH_MOTION) {
  175405. + dev_dbg(t->dev, "[0x%p]\tlow/medium motion\n", (void *)t);
  175406. + dev_dbg(t->dev, "[0x%p]\tpaddr_n = 0x%x\n",
  175407. + (void *)t, t->input.paddr_n);
  175408. + } else
  175409. + dev_dbg(t->dev, "[0x%p]\thigh motion\n", (void *)t);
  175410. + }
  175411. +
  175412. + dev_dbg(t->dev, "[0x%p]output:\n", (void *)t);
  175413. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->output.format);
  175414. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->output.width);
  175415. + dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->output.height);
  175416. + dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n", (void *)t, t->output.crop.w);
  175417. + dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n", (void *)t, t->output.crop.h);
  175418. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
  175419. + (void *)t, t->output.crop.pos.x);
  175420. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
  175421. + (void *)t, t->output.crop.pos.y);
  175422. + dev_dbg(t->dev, "[0x%p]\trotate = %d\n", (void *)t, t->output.rotate);
  175423. + dev_dbg(t->dev, "[0x%p]output buffer:\n", (void *)t);
  175424. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->output.paddr);
  175425. + dev_dbg(t->dev, "[0x%p]\to_off = 0x%x\n", (void *)t, t->set.o_off);
  175426. + dev_dbg(t->dev, "[0x%p]\to_uoff = 0x%x\n", (void *)t, t->set.o_uoff);
  175427. + dev_dbg(t->dev, "[0x%p]\to_voff = 0x%x\n", (void *)t, t->set.o_voff);
  175428. + dev_dbg(t->dev, "[0x%p]\tostride = %d\n", (void *)t, t->set.ostride);
  175429. +
  175430. + if (t->overlay_en) {
  175431. + dev_dbg(t->dev, "[0x%p]overlay:\n", (void *)t);
  175432. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n",
  175433. + (void *)t, t->overlay.format);
  175434. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n",
  175435. + (void *)t, t->overlay.width);
  175436. + dev_dbg(t->dev, "[0x%p]\theight = %d\n",
  175437. + (void *)t, t->overlay.height);
  175438. + dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n",
  175439. + (void *)t, t->overlay.crop.w);
  175440. + dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n",
  175441. + (void *)t, t->overlay.crop.h);
  175442. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
  175443. + (void *)t, t->overlay.crop.pos.x);
  175444. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
  175445. + (void *)t, t->overlay.crop.pos.y);
  175446. + dev_dbg(t->dev, "[0x%p]overlay buffer:\n", (void *)t);
  175447. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n",
  175448. + (void *)t, t->overlay.paddr);
  175449. + dev_dbg(t->dev, "[0x%p]\tov_off = 0x%x\n",
  175450. + (void *)t, t->set.ov_off);
  175451. + dev_dbg(t->dev, "[0x%p]\tov_uoff = 0x%x\n",
  175452. + (void *)t, t->set.ov_uoff);
  175453. + dev_dbg(t->dev, "[0x%p]\tov_voff = 0x%x\n",
  175454. + (void *)t, t->set.ov_voff);
  175455. + dev_dbg(t->dev, "[0x%p]\tovstride = %d\n",
  175456. + (void *)t, t->set.ovstride);
  175457. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  175458. + dev_dbg(t->dev, "[0x%p]local alpha enabled with:\n",
  175459. + (void *)t);
  175460. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n",
  175461. + (void *)t, t->overlay.alpha.loc_alp_paddr);
  175462. + dev_dbg(t->dev, "[0x%p]\tov_alpha_off = 0x%x\n",
  175463. + (void *)t, t->set.ov_alpha_off);
  175464. + dev_dbg(t->dev, "[0x%p]\tov_alpha_stride = %d\n",
  175465. + (void *)t, t->set.ov_alpha_stride);
  175466. + } else
  175467. + dev_dbg(t->dev, "[0x%p]globle alpha enabled with value 0x%x\n",
  175468. + (void *)t, t->overlay.alpha.gvalue);
  175469. + if (t->overlay.colorkey.enable)
  175470. + dev_dbg(t->dev, "[0x%p]colorkey enabled with value 0x%x\n",
  175471. + (void *)t, t->overlay.colorkey.value);
  175472. + }
  175473. +
  175474. + dev_dbg(t->dev, "[0x%p]want task_id = %d\n", (void *)t, t->task_id);
  175475. + dev_dbg(t->dev, "[0x%p]want task mode is 0x%x\n",
  175476. + (void *)t, t->set.mode);
  175477. + dev_dbg(t->dev, "[0x%p]\tIC_MODE = 0x%x\n", (void *)t, IC_MODE);
  175478. + dev_dbg(t->dev, "[0x%p]\tROT_MODE = 0x%x\n", (void *)t, ROT_MODE);
  175479. + dev_dbg(t->dev, "[0x%p]\tVDI_MODE = 0x%x\n", (void *)t, VDI_MODE);
  175480. + dev_dbg(t->dev, "[0x%p]\tTask_no = 0x%x\n\n\n", (void *)t, t->task_no);
  175481. +}
  175482. +
  175483. +static void dump_check_err(struct device *dev, int err)
  175484. +{
  175485. + switch (err) {
  175486. + case IPU_CHECK_ERR_INPUT_CROP:
  175487. + dev_err(dev, "input crop setting error\n");
  175488. + break;
  175489. + case IPU_CHECK_ERR_OUTPUT_CROP:
  175490. + dev_err(dev, "output crop setting error\n");
  175491. + break;
  175492. + case IPU_CHECK_ERR_OVERLAY_CROP:
  175493. + dev_err(dev, "overlay crop setting error\n");
  175494. + break;
  175495. + case IPU_CHECK_ERR_INPUT_OVER_LIMIT:
  175496. + dev_err(dev, "input over limitation\n");
  175497. + break;
  175498. + case IPU_CHECK_ERR_OVERLAY_WITH_VDI:
  175499. + dev_err(dev, "do not support overlay with deinterlace\n");
  175500. + break;
  175501. + case IPU_CHECK_ERR_OV_OUT_NO_FIT:
  175502. + dev_err(dev,
  175503. + "width/height of overlay and ic output should be same\n");
  175504. + break;
  175505. + case IPU_CHECK_ERR_PROC_NO_NEED:
  175506. + dev_err(dev, "no ipu processing need\n");
  175507. + break;
  175508. + case IPU_CHECK_ERR_SPLIT_INPUTW_OVER:
  175509. + dev_err(dev, "split mode input width overflow\n");
  175510. + break;
  175511. + case IPU_CHECK_ERR_SPLIT_INPUTH_OVER:
  175512. + dev_err(dev, "split mode input height overflow\n");
  175513. + break;
  175514. + case IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER:
  175515. + dev_err(dev, "split mode output width overflow\n");
  175516. + break;
  175517. + case IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER:
  175518. + dev_err(dev, "split mode output height overflow\n");
  175519. + break;
  175520. + case IPU_CHECK_ERR_SPLIT_WITH_ROT:
  175521. + dev_err(dev, "not support split mode with rotation\n");
  175522. + break;
  175523. + case IPU_CHECK_ERR_W_DOWNSIZE_OVER:
  175524. + dev_err(dev, "horizontal downsizing ratio overflow\n");
  175525. + break;
  175526. + case IPU_CHECK_ERR_H_DOWNSIZE_OVER:
  175527. + dev_err(dev, "vertical downsizing ratio overflow\n");
  175528. + break;
  175529. + default:
  175530. + break;
  175531. + }
  175532. +}
  175533. +
  175534. +static void dump_check_warn(struct device *dev, int warn)
  175535. +{
  175536. + if (warn & IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN)
  175537. + dev_warn(dev, "input u/v offset not 8 align\n");
  175538. + if (warn & IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN)
  175539. + dev_warn(dev, "output u/v offset not 8 align\n");
  175540. + if (warn & IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN)
  175541. + dev_warn(dev, "overlay u/v offset not 8 align\n");
  175542. +}
  175543. +
  175544. +static int set_crop(struct ipu_crop *crop, int width, int height, int fmt)
  175545. +{
  175546. + if ((width == 0) || (height == 0)) {
  175547. + pr_err("Invalid param: width=%d, height=%d\n", width, height);
  175548. + return -EINVAL;
  175549. + }
  175550. +
  175551. + if ((IPU_PIX_FMT_TILED_NV12 == fmt) ||
  175552. + (IPU_PIX_FMT_TILED_NV12F == fmt)) {
  175553. + if (crop->w || crop->h) {
  175554. + if (((crop->w + crop->pos.x) > width)
  175555. + || ((crop->h + crop->pos.y) > height)
  175556. + || (0 != (crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  175557. + || (0 != (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  175558. + || (0 != (crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  175559. + || (0 != (crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  175560. + ) {
  175561. + pr_err("set_crop error MB align.\n");
  175562. + return -EINVAL;
  175563. + }
  175564. + } else {
  175565. + crop->pos.x = 0;
  175566. + crop->pos.y = 0;
  175567. + crop->w = width;
  175568. + crop->h = height;
  175569. + if ((0 != (crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  175570. + || (0 != (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))) {
  175571. + pr_err("set_crop error w/h MB align.\n");
  175572. + return -EINVAL;
  175573. + }
  175574. + }
  175575. + } else {
  175576. + if (crop->w || crop->h) {
  175577. + if (((crop->w + crop->pos.x) > (width + 16))
  175578. + || ((crop->h + crop->pos.y) > height + 16)) {
  175579. + pr_err("set_crop error exceeds width/height.\n");
  175580. + return -EINVAL;
  175581. + }
  175582. + } else {
  175583. + crop->pos.x = 0;
  175584. + crop->pos.y = 0;
  175585. + crop->w = width;
  175586. + crop->h = height;
  175587. + }
  175588. + crop->w -= crop->w%8;
  175589. + crop->h -= crop->h%8;
  175590. + }
  175591. +
  175592. + if ((crop->w == 0) || (crop->h == 0)) {
  175593. + pr_err("Invalid crop param: crop.w=%d, crop.h=%d\n",
  175594. + crop->w, crop->h);
  175595. + return -EINVAL;
  175596. + }
  175597. +
  175598. + return 0;
  175599. +}
  175600. +
  175601. +static void update_offset(unsigned int fmt,
  175602. + unsigned int width, unsigned int height,
  175603. + unsigned int pos_x, unsigned int pos_y,
  175604. + int *off, int *uoff, int *voff, int *stride)
  175605. +{
  175606. + /* NOTE: u v offset should based on start point of off*/
  175607. + switch (fmt) {
  175608. + case IPU_PIX_FMT_YUV420P2:
  175609. + case IPU_PIX_FMT_YUV420P:
  175610. + *off = pos_y * width + pos_x;
  175611. + *uoff = (width * (height - pos_y) - pos_x)
  175612. + + (width/2) * (pos_y/2) + pos_x/2;
  175613. + /* In case height is odd, round up to even */
  175614. + *voff = *uoff + (width/2) * ((height+1)/2);
  175615. + break;
  175616. + case IPU_PIX_FMT_YVU420P:
  175617. + *off = pos_y * width + pos_x;
  175618. + *voff = (width * (height - pos_y) - pos_x)
  175619. + + (width/2) * (pos_y/2) + pos_x/2;
  175620. + /* In case height is odd, round up to even */
  175621. + *uoff = *voff + (width/2) * ((height+1)/2);
  175622. + break;
  175623. + case IPU_PIX_FMT_YVU422P:
  175624. + *off = pos_y * width + pos_x;
  175625. + *voff = (width * (height - pos_y) - pos_x)
  175626. + + (width/2) * pos_y + pos_x/2;
  175627. + *uoff = *voff + (width/2) * height;
  175628. + break;
  175629. + case IPU_PIX_FMT_YUV422P:
  175630. + *off = pos_y * width + pos_x;
  175631. + *uoff = (width * (height - pos_y) - pos_x)
  175632. + + (width/2) * pos_y + pos_x/2;
  175633. + *voff = *uoff + (width/2) * height;
  175634. + break;
  175635. + case IPU_PIX_FMT_YUV444P:
  175636. + *off = pos_y * width + pos_x;
  175637. + *uoff = width * height;
  175638. + *voff = width * height * 2;
  175639. + break;
  175640. + case IPU_PIX_FMT_NV12:
  175641. + *off = pos_y * width + pos_x;
  175642. + *uoff = (width * (height - pos_y) - pos_x)
  175643. + + width * (pos_y/2) + pos_x;
  175644. + break;
  175645. + case IPU_PIX_FMT_TILED_NV12:
  175646. + /*
  175647. + * tiled format, progressive:
  175648. + * assuming that line is aligned with MB height (aligned to 16)
  175649. + * offset = line * stride + (pixel / MB_width) * pixels_in_MB
  175650. + * = line * stride + (pixel / 16) * 256
  175651. + * = line * stride + pixel * 16
  175652. + */
  175653. + *off = pos_y * width + (pos_x << 4);
  175654. + *uoff = ALIGN(width * height, SZ_4K) + (*off >> 1) - *off;
  175655. + break;
  175656. + case IPU_PIX_FMT_TILED_NV12F:
  175657. + /*
  175658. + * tiled format, interlaced:
  175659. + * same as above, only number of pixels in MB is 128,
  175660. + * instead of 256
  175661. + */
  175662. + *off = (pos_y >> 1) * width + (pos_x << 3);
  175663. + *uoff = ALIGN(width * height/2, SZ_4K) + (*off >> 1) - *off;
  175664. + break;
  175665. + default:
  175666. + *off = (pos_y * width + pos_x) * fmt_to_bpp(fmt)/8;
  175667. + break;
  175668. + }
  175669. + *stride = width * bytes_per_pixel(fmt);
  175670. +}
  175671. +
  175672. +static int update_split_setting(struct ipu_task_entry *t, bool vdi_split)
  175673. +{
  175674. + struct stripe_param left_stripe;
  175675. + struct stripe_param right_stripe;
  175676. + struct stripe_param up_stripe;
  175677. + struct stripe_param down_stripe;
  175678. + u32 iw, ih, ow, oh;
  175679. + u32 max_width;
  175680. + int ret;
  175681. +
  175682. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT)
  175683. + return IPU_CHECK_ERR_SPLIT_WITH_ROT;
  175684. +
  175685. + iw = t->input.crop.w;
  175686. + ih = t->input.crop.h;
  175687. +
  175688. + ow = t->output.crop.w;
  175689. + oh = t->output.crop.h;
  175690. +
  175691. + memset(&left_stripe, 0, sizeof(left_stripe));
  175692. + memset(&right_stripe, 0, sizeof(right_stripe));
  175693. + memset(&up_stripe, 0, sizeof(up_stripe));
  175694. + memset(&down_stripe, 0, sizeof(down_stripe));
  175695. +
  175696. + if (t->set.split_mode & RL_SPLIT) {
  175697. + /*
  175698. + * We do want equal strips: initialize stripes in case
  175699. + * calc_stripes returns before actually doing the calculation
  175700. + */
  175701. + left_stripe.input_width = iw / 2;
  175702. + left_stripe.output_width = ow / 2;
  175703. + right_stripe.input_column = iw / 2;
  175704. + right_stripe.output_column = ow / 2;
  175705. +
  175706. + if (vdi_split)
  175707. + max_width = soc_max_vdi_in_width();
  175708. + else
  175709. + max_width = soc_max_out_width();
  175710. + ret = ipu_calc_stripes_sizes(iw,
  175711. + ow,
  175712. + max_width,
  175713. + (((unsigned long long)1) << 32), /* 32bit for fractional*/
  175714. + 1, /* equal stripes */
  175715. + t->input.format,
  175716. + t->output.format,
  175717. + &left_stripe,
  175718. + &right_stripe);
  175719. + if (ret < 0)
  175720. + return IPU_CHECK_ERR_W_DOWNSIZE_OVER;
  175721. + else if (ret)
  175722. + dev_dbg(t->dev, "Warn: no:0x%x,calc_stripes ret:%d\n",
  175723. + t->task_no, ret);
  175724. + t->set.sp_setting.iw = left_stripe.input_width;
  175725. + t->set.sp_setting.ow = left_stripe.output_width;
  175726. + t->set.sp_setting.outh_resize_ratio = left_stripe.irr;
  175727. + t->set.sp_setting.i_left_pos = left_stripe.input_column;
  175728. + t->set.sp_setting.o_left_pos = left_stripe.output_column;
  175729. + t->set.sp_setting.i_right_pos = right_stripe.input_column;
  175730. + t->set.sp_setting.o_right_pos = right_stripe.output_column;
  175731. + } else {
  175732. + t->set.sp_setting.iw = iw;
  175733. + t->set.sp_setting.ow = ow;
  175734. + t->set.sp_setting.outh_resize_ratio = 0;
  175735. + t->set.sp_setting.i_left_pos = 0;
  175736. + t->set.sp_setting.o_left_pos = 0;
  175737. + t->set.sp_setting.i_right_pos = 0;
  175738. + t->set.sp_setting.o_right_pos = 0;
  175739. + }
  175740. + if ((t->set.sp_setting.iw + t->set.sp_setting.i_right_pos) > (iw+16))
  175741. + return IPU_CHECK_ERR_SPLIT_INPUTW_OVER;
  175742. + if (((t->set.sp_setting.ow + t->set.sp_setting.o_right_pos) > ow)
  175743. + || (t->set.sp_setting.ow > soc_max_out_width()))
  175744. + return IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER;
  175745. + if (rounddown(t->set.sp_setting.ow, 8) * 8 <=
  175746. + rounddown(t->set.sp_setting.iw, 8))
  175747. + return IPU_CHECK_ERR_W_DOWNSIZE_OVER;
  175748. +
  175749. + if (t->set.split_mode & UD_SPLIT) {
  175750. + /*
  175751. + * We do want equal strips: initialize stripes in case
  175752. + * calc_stripes returns before actually doing the calculation
  175753. + */
  175754. + up_stripe.input_width = ih / 2;
  175755. + up_stripe.output_width = oh / 2;
  175756. + down_stripe.input_column = ih / 2;
  175757. + down_stripe.output_column = oh / 2;
  175758. + ret = ipu_calc_stripes_sizes(ih,
  175759. + oh,
  175760. + soc_max_out_height(),
  175761. + (((unsigned long long)1) << 32), /* 32bit for fractional*/
  175762. + 0x1 | 0x2, /* equal stripes and vertical */
  175763. + t->input.format,
  175764. + t->output.format,
  175765. + &up_stripe,
  175766. + &down_stripe);
  175767. + if (ret < 0)
  175768. + return IPU_CHECK_ERR_H_DOWNSIZE_OVER;
  175769. + else if (ret)
  175770. + dev_err(t->dev, "Warn: no:0x%x,calc_stripes ret:%d\n",
  175771. + t->task_no, ret);
  175772. + t->set.sp_setting.ih = up_stripe.input_width;
  175773. + t->set.sp_setting.oh = up_stripe.output_width;
  175774. + t->set.sp_setting.outv_resize_ratio = up_stripe.irr;
  175775. + t->set.sp_setting.i_top_pos = up_stripe.input_column;
  175776. + t->set.sp_setting.o_top_pos = up_stripe.output_column;
  175777. + t->set.sp_setting.i_bottom_pos = down_stripe.input_column;
  175778. + t->set.sp_setting.o_bottom_pos = down_stripe.output_column;
  175779. + } else {
  175780. + t->set.sp_setting.ih = ih;
  175781. + t->set.sp_setting.oh = oh;
  175782. + t->set.sp_setting.outv_resize_ratio = 0;
  175783. + t->set.sp_setting.i_top_pos = 0;
  175784. + t->set.sp_setting.o_top_pos = 0;
  175785. + t->set.sp_setting.i_bottom_pos = 0;
  175786. + t->set.sp_setting.o_bottom_pos = 0;
  175787. + }
  175788. +
  175789. + /* downscale case: enforce limits */
  175790. + if (((t->set.sp_setting.ih + t->set.sp_setting.i_bottom_pos) > (ih))
  175791. + && (t->set.sp_setting.ih >= t->set.sp_setting.oh))
  175792. + return IPU_CHECK_ERR_SPLIT_INPUTH_OVER;
  175793. + /* upscale case: relax limits because ipu_calc_stripes_sizes() may
  175794. + create input stripe that falls just outside of the input window */
  175795. + else if ((t->set.sp_setting.ih + t->set.sp_setting.i_bottom_pos)
  175796. + > (ih+16))
  175797. + return IPU_CHECK_ERR_SPLIT_INPUTH_OVER;
  175798. + if (((t->set.sp_setting.oh + t->set.sp_setting.o_bottom_pos) > oh)
  175799. + || (t->set.sp_setting.oh > soc_max_out_height()))
  175800. + return IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER;
  175801. + if (rounddown(t->set.sp_setting.oh, 8) * 8 <=
  175802. + rounddown(t->set.sp_setting.ih, 8))
  175803. + return IPU_CHECK_ERR_H_DOWNSIZE_OVER;
  175804. +
  175805. + return IPU_CHECK_OK;
  175806. +}
  175807. +
  175808. +static int check_task(struct ipu_task_entry *t)
  175809. +{
  175810. + int tmp;
  175811. + int ret = IPU_CHECK_OK;
  175812. + int timeout;
  175813. + bool vdi_split = false;
  175814. + int ocw, och;
  175815. +
  175816. + if ((IPU_PIX_FMT_TILED_NV12 == t->overlay.format) ||
  175817. + (IPU_PIX_FMT_TILED_NV12F == t->overlay.format) ||
  175818. + (IPU_PIX_FMT_TILED_NV12 == t->output.format) ||
  175819. + (IPU_PIX_FMT_TILED_NV12F == t->output.format) ||
  175820. + ((IPU_PIX_FMT_TILED_NV12F == t->input.format) &&
  175821. + !t->input.deinterlace.enable)) {
  175822. + ret = IPU_CHECK_ERR_NOT_SUPPORT;
  175823. + goto done;
  175824. + }
  175825. +
  175826. + /* check input */
  175827. + ret = set_crop(&t->input.crop, t->input.width, t->input.height,
  175828. + t->input.format);
  175829. + if (ret < 0) {
  175830. + ret = IPU_CHECK_ERR_INPUT_CROP;
  175831. + goto done;
  175832. + } else
  175833. + update_offset(t->input.format, t->input.width, t->input.height,
  175834. + t->input.crop.pos.x, t->input.crop.pos.y,
  175835. + &t->set.i_off, &t->set.i_uoff,
  175836. + &t->set.i_voff, &t->set.istride);
  175837. +
  175838. + /* check output */
  175839. + ret = set_crop(&t->output.crop, t->output.width, t->output.height,
  175840. + t->output.format);
  175841. + if (ret < 0) {
  175842. + ret = IPU_CHECK_ERR_OUTPUT_CROP;
  175843. + goto done;
  175844. + } else
  175845. + update_offset(t->output.format,
  175846. + t->output.width, t->output.height,
  175847. + t->output.crop.pos.x, t->output.crop.pos.y,
  175848. + &t->set.o_off, &t->set.o_uoff,
  175849. + &t->set.o_voff, &t->set.ostride);
  175850. +
  175851. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  175852. + /*
  175853. + * Cache output width and height and
  175854. + * swap them so that we may check
  175855. + * downsize overflow correctly.
  175856. + */
  175857. + ocw = t->output.crop.h;
  175858. + och = t->output.crop.w;
  175859. + } else {
  175860. + ocw = t->output.crop.w;
  175861. + och = t->output.crop.h;
  175862. + }
  175863. +
  175864. + if (ocw * 8 <= t->input.crop.w) {
  175865. + ret = IPU_CHECK_ERR_W_DOWNSIZE_OVER;
  175866. + goto done;
  175867. + }
  175868. +
  175869. + if (och * 8 <= t->input.crop.h) {
  175870. + ret = IPU_CHECK_ERR_H_DOWNSIZE_OVER;
  175871. + goto done;
  175872. + }
  175873. +
  175874. + if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  175875. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  175876. + if ((t->input.crop.w > soc_max_in_width(1)) ||
  175877. + (t->input.crop.h > soc_max_in_height())) {
  175878. + ret = IPU_CHECK_ERR_INPUT_OVER_LIMIT;
  175879. + goto done;
  175880. + }
  175881. + /* output fmt: NV12 and YUYV, now don't support resize */
  175882. + if (((IPU_PIX_FMT_NV12 != t->output.format) &&
  175883. + (IPU_PIX_FMT_YUYV != t->output.format)) ||
  175884. + (t->input.crop.w != t->output.crop.w) ||
  175885. + (t->input.crop.h != t->output.crop.h)) {
  175886. + ret = IPU_CHECK_ERR_NOT_SUPPORT;
  175887. + goto done;
  175888. + }
  175889. + }
  175890. +
  175891. + /* check overlay if there is */
  175892. + if (t->overlay_en) {
  175893. + if (t->input.deinterlace.enable) {
  175894. + ret = IPU_CHECK_ERR_OVERLAY_WITH_VDI;
  175895. + goto done;
  175896. + }
  175897. +
  175898. + ret = set_crop(&t->overlay.crop, t->overlay.width,
  175899. + t->overlay.height, t->overlay.format);
  175900. + if (ret < 0) {
  175901. + ret = IPU_CHECK_ERR_OVERLAY_CROP;
  175902. + goto done;
  175903. + } else {
  175904. + ocw = t->output.crop.w;
  175905. + och = t->output.crop.h;
  175906. +
  175907. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  175908. + ocw = t->output.crop.h;
  175909. + och = t->output.crop.w;
  175910. + }
  175911. + if ((t->overlay.crop.w != ocw) ||
  175912. + (t->overlay.crop.h != och)) {
  175913. + ret = IPU_CHECK_ERR_OV_OUT_NO_FIT;
  175914. + goto done;
  175915. + }
  175916. +
  175917. + update_offset(t->overlay.format,
  175918. + t->overlay.width, t->overlay.height,
  175919. + t->overlay.crop.pos.x, t->overlay.crop.pos.y,
  175920. + &t->set.ov_off, &t->set.ov_uoff,
  175921. + &t->set.ov_voff, &t->set.ovstride);
  175922. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  175923. + t->set.ov_alpha_stride = t->overlay.width;
  175924. + t->set.ov_alpha_off = t->overlay.crop.pos.y *
  175925. + t->overlay.width + t->overlay.crop.pos.x;
  175926. + }
  175927. + }
  175928. + }
  175929. +
  175930. + /* input overflow? */
  175931. + if (!((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  175932. + (IPU_PIX_FMT_TILED_NV12F == t->input.format))) {
  175933. + if ((t->input.crop.w > soc_max_in_width(0)) ||
  175934. + (t->input.crop.h > soc_max_in_height())) {
  175935. + ret = IPU_CHECK_ERR_INPUT_OVER_LIMIT;
  175936. + goto done;
  175937. + }
  175938. + }
  175939. +
  175940. + /* check task mode */
  175941. + t->set.mode = NULL_MODE;
  175942. + t->set.split_mode = NO_SPLIT;
  175943. +
  175944. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  175945. + /*output swap*/
  175946. + tmp = t->output.crop.w;
  175947. + t->output.crop.w = t->output.crop.h;
  175948. + t->output.crop.h = tmp;
  175949. + }
  175950. +
  175951. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT)
  175952. + t->set.mode |= ROT_MODE;
  175953. +
  175954. + /*need resize or CSC?*/
  175955. + if ((t->input.crop.w != t->output.crop.w) ||
  175956. + (t->input.crop.h != t->output.crop.h) ||
  175957. + need_csc(t->input.format, t->output.format))
  175958. + t->set.mode |= IC_MODE;
  175959. +
  175960. + /*need flip?*/
  175961. + if ((t->set.mode == NULL_MODE) && (t->output.rotate > IPU_ROTATE_NONE))
  175962. + t->set.mode |= IC_MODE;
  175963. +
  175964. + /*need IDMAC do format(same color space)?*/
  175965. + if ((t->set.mode == NULL_MODE) && (t->input.format != t->output.format))
  175966. + t->set.mode |= IC_MODE;
  175967. +
  175968. + /*overlay support*/
  175969. + if (t->overlay_en)
  175970. + t->set.mode |= IC_MODE;
  175971. +
  175972. + /*deinterlace*/
  175973. + if (t->input.deinterlace.enable) {
  175974. + t->set.mode &= ~IC_MODE;
  175975. + t->set.mode |= VDI_MODE;
  175976. + }
  175977. + if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  175978. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  175979. + if (t->set.mode & ROT_MODE) {
  175980. + ret = IPU_CHECK_ERR_NOT_SUPPORT;
  175981. + goto done;
  175982. + }
  175983. + t->set.mode |= VDOA_MODE;
  175984. + if (IPU_PIX_FMT_TILED_NV12F == t->input.format)
  175985. + t->set.mode |= VDOA_BAND_MODE;
  175986. + t->set.mode &= ~IC_MODE;
  175987. + }
  175988. +
  175989. + if ((t->set.mode & (IC_MODE | VDI_MODE)) &&
  175990. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  175991. + if (t->output.crop.w > soc_max_out_width())
  175992. + t->set.split_mode |= RL_SPLIT;
  175993. + if (t->output.crop.h > soc_max_out_height())
  175994. + t->set.split_mode |= UD_SPLIT;
  175995. + if (!t->set.split_mode && (t->set.mode & VDI_MODE) &&
  175996. + (t->input.crop.w > soc_max_vdi_in_width())) {
  175997. + t->set.split_mode |= RL_SPLIT;
  175998. + vdi_split = true;
  175999. + }
  176000. + if (t->set.split_mode) {
  176001. + if ((t->set.split_mode == RL_SPLIT) ||
  176002. + (t->set.split_mode == UD_SPLIT))
  176003. + timeout = DEF_TIMEOUT_MS * 2 + DEF_DELAY_MS;
  176004. + else
  176005. + timeout = DEF_TIMEOUT_MS * 4 + DEF_DELAY_MS;
  176006. + if (t->timeout < timeout)
  176007. + t->timeout = timeout;
  176008. +
  176009. + ret = update_split_setting(t, vdi_split);
  176010. + if (ret > IPU_CHECK_ERR_MIN)
  176011. + goto done;
  176012. + }
  176013. + }
  176014. +
  176015. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  176016. + /*output swap*/
  176017. + tmp = t->output.crop.w;
  176018. + t->output.crop.w = t->output.crop.h;
  176019. + t->output.crop.h = tmp;
  176020. + }
  176021. +
  176022. + if (t->set.mode == NULL_MODE) {
  176023. + ret = IPU_CHECK_ERR_PROC_NO_NEED;
  176024. + goto done;
  176025. + }
  176026. +
  176027. + if ((t->set.i_uoff % 8) || (t->set.i_voff % 8))
  176028. + ret |= IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN;
  176029. + if ((t->set.o_uoff % 8) || (t->set.o_voff % 8))
  176030. + ret |= IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN;
  176031. + if (t->overlay_en && ((t->set.ov_uoff % 8) || (t->set.ov_voff % 8)))
  176032. + ret |= IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN;
  176033. +
  176034. +done:
  176035. + /* dump msg */
  176036. + if (debug) {
  176037. + if (ret > IPU_CHECK_ERR_MIN)
  176038. + dump_check_err(t->dev, ret);
  176039. + else if (ret != IPU_CHECK_OK)
  176040. + dump_check_warn(t->dev, ret);
  176041. + }
  176042. +
  176043. + return ret;
  176044. +}
  176045. +
  176046. +static int prepare_task(struct ipu_task_entry *t)
  176047. +{
  176048. + int ret = 0;
  176049. +
  176050. + ret = check_task(t);
  176051. + if (ret > IPU_CHECK_ERR_MIN)
  176052. + return -EINVAL;
  176053. +
  176054. + if (t->set.mode & VDI_MODE) {
  176055. + t->task_id = IPU_TASK_ID_VF;
  176056. + t->set.task = VDI_VF;
  176057. + if (t->set.mode & ROT_MODE)
  176058. + t->set.task |= ROT_VF;
  176059. + }
  176060. +
  176061. + if (VDOA_MODE == t->set.mode) {
  176062. + if (t->set.task != 0) {
  176063. + dev_err(t->dev, "ERR: vdoa only task:0x%x, [0x%p].\n",
  176064. + t->set.task, t);
  176065. + return -EINVAL;
  176066. + }
  176067. + t->set.task |= VDOA_ONLY;
  176068. + }
  176069. +
  176070. + if (VDOA_BAND_MODE & t->set.mode) {
  176071. + /* to save band size: 1<<3 = 8 lines */
  176072. + t->set.band_lines = 3;
  176073. + }
  176074. +
  176075. + dump_task_info(t);
  176076. +
  176077. + return ret;
  176078. +}
  176079. +
  176080. +static uint32_t ic_vf_pp_is_busy(struct ipu_soc *ipu, bool is_vf)
  176081. +{
  176082. + uint32_t status;
  176083. + uint32_t status_vf;
  176084. + uint32_t status_rot;
  176085. +
  176086. + if (is_vf) {
  176087. + status = ipu_channel_status(ipu, MEM_VDI_PRP_VF_MEM);
  176088. + status_vf = ipu_channel_status(ipu, MEM_PRP_VF_MEM);
  176089. + status_rot = ipu_channel_status(ipu, MEM_ROT_VF_MEM);
  176090. + return status || status_vf || status_rot;
  176091. + } else {
  176092. + status = ipu_channel_status(ipu, MEM_PP_MEM);
  176093. + status_rot = ipu_channel_status(ipu, MEM_ROT_PP_MEM);
  176094. + return status || status_rot;
  176095. + }
  176096. +}
  176097. +
  176098. +static int _get_vdoa_ipu_res(struct ipu_task_entry *t)
  176099. +{
  176100. + int i;
  176101. + struct ipu_soc *ipu;
  176102. + u8 *used;
  176103. + uint32_t found_ipu = 0;
  176104. + uint32_t found_vdoa = 0;
  176105. + struct ipu_channel_tabel *tbl = &ipu_ch_tbl;
  176106. +
  176107. + mutex_lock(&tbl->lock);
  176108. + if (t->set.mode & VDOA_MODE) {
  176109. + if (NULL != t->vdoa_handle)
  176110. + found_vdoa = 1;
  176111. + else {
  176112. + found_vdoa = tbl->vdoa_used ? 0 : 1;
  176113. + if (found_vdoa) {
  176114. + tbl->vdoa_used = 1;
  176115. + vdoa_get_handle(&t->vdoa_handle);
  176116. + } else
  176117. + /* first get vdoa->ipu resource sequence */
  176118. + goto out;
  176119. + if (t->set.task & VDOA_ONLY)
  176120. + goto out;
  176121. + }
  176122. + }
  176123. +
  176124. + for (i = 0; i < max_ipu_no; i++) {
  176125. + ipu = ipu_get_soc(i);
  176126. + if (IS_ERR(ipu))
  176127. + dev_err(t->dev, "no:0x%x,found_vdoa:%d, ipu:%d\n",
  176128. + t->task_no, found_vdoa, i);
  176129. +
  176130. + used = &tbl->used[i][IPU_PP_CH_VF];
  176131. + if (t->set.mode & VDI_MODE) {
  176132. + if (0 == *used) {
  176133. + *used = 1;
  176134. + found_ipu = 1;
  176135. + break;
  176136. + }
  176137. + } else if ((t->set.mode & IC_MODE) || only_rot(t->set.mode)) {
  176138. + if (0 == *used) {
  176139. + t->task_id = IPU_TASK_ID_VF;
  176140. + if (t->set.mode & IC_MODE)
  176141. + t->set.task |= IC_VF;
  176142. + if (t->set.mode & ROT_MODE)
  176143. + t->set.task |= ROT_VF;
  176144. + *used = 1;
  176145. + found_ipu = 1;
  176146. + break;
  176147. + }
  176148. + } else
  176149. + dev_err(t->dev, "no:0x%x,found_vdoa:%d, mode:0x%x\n",
  176150. + t->task_no, found_vdoa, t->set.mode);
  176151. + }
  176152. + if (found_ipu)
  176153. + goto next;
  176154. +
  176155. + for (i = 0; i < max_ipu_no; i++) {
  176156. + ipu = ipu_get_soc(i);
  176157. + if (IS_ERR(ipu))
  176158. + dev_err(t->dev, "no:0x%x,found_vdoa:%d, ipu:%d\n",
  176159. + t->task_no, found_vdoa, i);
  176160. +
  176161. + if ((t->set.mode & IC_MODE) || only_rot(t->set.mode)) {
  176162. + used = &tbl->used[i][IPU_PP_CH_PP];
  176163. + if (0 == *used) {
  176164. + t->task_id = IPU_TASK_ID_PP;
  176165. + if (t->set.mode & IC_MODE)
  176166. + t->set.task |= IC_PP;
  176167. + if (t->set.mode & ROT_MODE)
  176168. + t->set.task |= ROT_PP;
  176169. + *used = 1;
  176170. + found_ipu = 1;
  176171. + break;
  176172. + }
  176173. + }
  176174. + }
  176175. +
  176176. +next:
  176177. + if (found_ipu) {
  176178. + t->ipu = ipu;
  176179. + t->ipu_id = i;
  176180. + t->dev = ipu->dev;
  176181. + if (atomic_inc_return(&t->res_get) == 2)
  176182. + dev_err(t->dev,
  176183. + "ERR no:0x%x,found_vdoa:%d,get ipu twice\n",
  176184. + t->task_no, found_vdoa);
  176185. + }
  176186. +out:
  176187. + dev_dbg(t->dev,
  176188. + "%s:no:0x%x,found_vdoa:%d, found_ipu:%d\n",
  176189. + __func__, t->task_no, found_vdoa, found_ipu);
  176190. + mutex_unlock(&tbl->lock);
  176191. + if (t->set.task & VDOA_ONLY)
  176192. + return found_vdoa;
  176193. + else if (t->set.mode & VDOA_MODE)
  176194. + return found_vdoa && found_ipu;
  176195. + else
  176196. + return found_ipu;
  176197. +}
  176198. +
  176199. +static void put_vdoa_ipu_res(struct ipu_task_entry *tsk, int vdoa_only)
  176200. +{
  176201. + int ret;
  176202. + int rel_vdoa = 0, rel_ipu = 0;
  176203. + struct ipu_channel_tabel *tbl = &ipu_ch_tbl;
  176204. +
  176205. + mutex_lock(&tbl->lock);
  176206. + if (tsk->set.mode & VDOA_MODE) {
  176207. + if (!tbl->vdoa_used && tsk->vdoa_handle)
  176208. + dev_err(tsk->dev,
  176209. + "ERR no:0x%x,vdoa not used,mode:0x%x\n",
  176210. + tsk->task_no, tsk->set.mode);
  176211. + if (tbl->vdoa_used && tsk->vdoa_handle) {
  176212. + tbl->vdoa_used = 0;
  176213. + vdoa_put_handle(&tsk->vdoa_handle);
  176214. + if (tsk->ipu)
  176215. + tsk->ipu->vdoa_en = 0;
  176216. + rel_vdoa = 1;
  176217. + if (vdoa_only || (tsk->set.task & VDOA_ONLY))
  176218. + goto out;
  176219. + }
  176220. + }
  176221. +
  176222. + tbl->used[tsk->ipu_id][tsk->task_id - 1] = 0;
  176223. + rel_ipu = 1;
  176224. + ret = atomic_inc_return(&tsk->res_free);
  176225. + if (ret == 2)
  176226. + dev_err(tsk->dev,
  176227. + "ERR no:0x%x,rel_vdoa:%d,put ipu twice\n",
  176228. + tsk->task_no, rel_vdoa);
  176229. +out:
  176230. + dev_dbg(tsk->dev,
  176231. + "%s:no:0x%x,rel_vdoa:%d, rel_ipu:%d\n",
  176232. + __func__, tsk->task_no, rel_vdoa, rel_ipu);
  176233. + mutex_unlock(&tbl->lock);
  176234. +}
  176235. +
  176236. +static int get_vdoa_ipu_res(struct ipu_task_entry *t)
  176237. +{
  176238. + int ret;
  176239. + uint32_t found = 0;
  176240. +
  176241. + found = _get_vdoa_ipu_res(t);
  176242. + if (!found) {
  176243. + t->ipu_id = -1;
  176244. + t->ipu = NULL;
  176245. + /* blocking to get resource */
  176246. + ret = atomic_inc_return(&req_cnt);
  176247. + dev_dbg(t->dev,
  176248. + "wait_res:no:0x%x,req_cnt:%d\n", t->task_no, ret);
  176249. + ret = wait_event_timeout(res_waitq, _get_vdoa_ipu_res(t),
  176250. + msecs_to_jiffies(t->timeout - DEF_DELAY_MS));
  176251. + if (ret == 0) {
  176252. + dev_err(t->dev, "ERR[0x%p,no-0x%x] wait_res timeout:%dms!\n",
  176253. + t, t->task_no, t->timeout - DEF_DELAY_MS);
  176254. + ret = -ETIMEDOUT;
  176255. + t->state = STATE_RES_TIMEOUT;
  176256. + goto out;
  176257. + } else {
  176258. + if (!(t->set.task & VDOA_ONLY) && (!t->ipu))
  176259. + dev_err(t->dev,
  176260. + "ERR[no-0x%x] can not get ipu!\n",
  176261. + t->task_no);
  176262. + ret = atomic_read(&req_cnt);
  176263. + if (ret > 0)
  176264. + ret = atomic_dec_return(&req_cnt);
  176265. + else
  176266. + dev_err(t->dev,
  176267. + "ERR[no-0x%x] req_cnt:%d mismatch!\n",
  176268. + t->task_no, ret);
  176269. + dev_dbg(t->dev, "no-0x%x,[0x%p],req_cnt:%d, got_res!\n",
  176270. + t->task_no, t, ret);
  176271. + found = 1;
  176272. + }
  176273. + }
  176274. +
  176275. +out:
  176276. + return found;
  176277. +}
  176278. +
  176279. +static struct ipu_task_entry *create_task_entry(struct ipu_task *task)
  176280. +{
  176281. + struct ipu_task_entry *tsk;
  176282. +
  176283. + tsk = kzalloc(sizeof(struct ipu_task_entry), GFP_KERNEL);
  176284. + if (!tsk)
  176285. + return ERR_PTR(-ENOMEM);
  176286. + kref_init(&tsk->refcount);
  176287. + tsk->state = -EINVAL;
  176288. + tsk->ipu_id = -1;
  176289. + tsk->dev = ipu_dev;
  176290. + tsk->input = task->input;
  176291. + tsk->output = task->output;
  176292. + tsk->overlay_en = task->overlay_en;
  176293. + if (tsk->overlay_en)
  176294. + tsk->overlay = task->overlay;
  176295. + if (task->timeout > DEF_TIMEOUT_MS)
  176296. + tsk->timeout = task->timeout;
  176297. + else
  176298. + tsk->timeout = DEF_TIMEOUT_MS;
  176299. +
  176300. + return tsk;
  176301. +}
  176302. +
  176303. +static void task_mem_free(struct kref *ref)
  176304. +{
  176305. + struct ipu_task_entry *tsk =
  176306. + container_of(ref, struct ipu_task_entry, refcount);
  176307. + kfree(tsk);
  176308. +}
  176309. +
  176310. +int create_split_child_task(struct ipu_split_task *sp_task)
  176311. +{
  176312. + int ret = 0;
  176313. + struct ipu_task_entry *tsk;
  176314. +
  176315. + tsk = create_task_entry(&sp_task->task);
  176316. + if (IS_ERR(tsk))
  176317. + return PTR_ERR(tsk);
  176318. +
  176319. + sp_task->child_task = tsk;
  176320. + tsk->task_no = sp_task->task_no;
  176321. +
  176322. + ret = prepare_task(tsk);
  176323. + if (ret < 0)
  176324. + goto err;
  176325. +
  176326. + tsk->parent = sp_task->parent_task;
  176327. + tsk->set.sp_setting = sp_task->parent_task->set.sp_setting;
  176328. +
  176329. + list_add(&tsk->node, &tsk->parent->split_list);
  176330. + dev_dbg(tsk->dev, "[0x%p] sp_tsk Q list,no-0x%x\n", tsk, tsk->task_no);
  176331. + tsk->state = STATE_QUEUE;
  176332. + CHECK_PERF(&tsk->ts_queue);
  176333. +err:
  176334. + return ret;
  176335. +}
  176336. +
  176337. +static inline int sp_task_check_done(struct ipu_split_task *sp_task,
  176338. + struct ipu_task_entry *parent, int num, int *idx)
  176339. +{
  176340. + int i;
  176341. + int ret = 0;
  176342. + struct ipu_task_entry *tsk;
  176343. + struct mutex *lock = &parent->split_lock;
  176344. +
  176345. + *idx = -EINVAL;
  176346. + mutex_lock(lock);
  176347. + for (i = 0; i < num; i++) {
  176348. + tsk = sp_task[i].child_task;
  176349. + if (tsk && tsk->split_done) {
  176350. + *idx = i;
  176351. + ret = 1;
  176352. + goto out;
  176353. + }
  176354. + }
  176355. +
  176356. +out:
  176357. + mutex_unlock(lock);
  176358. + return ret;
  176359. +}
  176360. +
  176361. +static int create_split_task(
  176362. + int stripe,
  176363. + struct ipu_split_task *sp_task)
  176364. +{
  176365. + struct ipu_task *task = &(sp_task->task);
  176366. + struct ipu_task_entry *t = sp_task->parent_task;
  176367. + int ret;
  176368. +
  176369. + sp_task->task_no |= stripe;
  176370. +
  176371. + task->input = t->input;
  176372. + task->output = t->output;
  176373. + task->overlay_en = t->overlay_en;
  176374. + if (task->overlay_en)
  176375. + task->overlay = t->overlay;
  176376. + task->task_id = t->task_id;
  176377. + if ((t->set.split_mode == RL_SPLIT) ||
  176378. + (t->set.split_mode == UD_SPLIT))
  176379. + task->timeout = t->timeout / 2;
  176380. + else
  176381. + task->timeout = t->timeout / 4;
  176382. +
  176383. + task->input.crop.w = t->set.sp_setting.iw;
  176384. + task->input.crop.h = t->set.sp_setting.ih;
  176385. + if (task->overlay_en) {
  176386. + task->overlay.crop.w = t->set.sp_setting.ow;
  176387. + task->overlay.crop.h = t->set.sp_setting.oh;
  176388. + }
  176389. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  176390. + task->output.crop.w = t->set.sp_setting.oh;
  176391. + task->output.crop.h = t->set.sp_setting.ow;
  176392. + t->set.sp_setting.rl_split_line = t->set.sp_setting.o_bottom_pos;
  176393. + t->set.sp_setting.ud_split_line = t->set.sp_setting.o_right_pos;
  176394. +
  176395. + } else {
  176396. + task->output.crop.w = t->set.sp_setting.ow;
  176397. + task->output.crop.h = t->set.sp_setting.oh;
  176398. + t->set.sp_setting.rl_split_line = t->set.sp_setting.o_right_pos;
  176399. + t->set.sp_setting.ud_split_line = t->set.sp_setting.o_bottom_pos;
  176400. + }
  176401. +
  176402. + if (stripe & LEFT_STRIPE)
  176403. + task->input.crop.pos.x += t->set.sp_setting.i_left_pos;
  176404. + else if (stripe & RIGHT_STRIPE)
  176405. + task->input.crop.pos.x += t->set.sp_setting.i_right_pos;
  176406. + if (stripe & UP_STRIPE)
  176407. + task->input.crop.pos.y += t->set.sp_setting.i_top_pos;
  176408. + else if (stripe & DOWN_STRIPE)
  176409. + task->input.crop.pos.y += t->set.sp_setting.i_bottom_pos;
  176410. +
  176411. + if (task->overlay_en) {
  176412. + if (stripe & LEFT_STRIPE)
  176413. + task->overlay.crop.pos.x += t->set.sp_setting.o_left_pos;
  176414. + else if (stripe & RIGHT_STRIPE)
  176415. + task->overlay.crop.pos.x += t->set.sp_setting.o_right_pos;
  176416. + if (stripe & UP_STRIPE)
  176417. + task->overlay.crop.pos.y += t->set.sp_setting.o_top_pos;
  176418. + else if (stripe & DOWN_STRIPE)
  176419. + task->overlay.crop.pos.y += t->set.sp_setting.o_bottom_pos;
  176420. + }
  176421. +
  176422. + switch (t->output.rotate) {
  176423. + case IPU_ROTATE_NONE:
  176424. + if (stripe & LEFT_STRIPE)
  176425. + task->output.crop.pos.x += t->set.sp_setting.o_left_pos;
  176426. + else if (stripe & RIGHT_STRIPE)
  176427. + task->output.crop.pos.x += t->set.sp_setting.o_right_pos;
  176428. + if (stripe & UP_STRIPE)
  176429. + task->output.crop.pos.y += t->set.sp_setting.o_top_pos;
  176430. + else if (stripe & DOWN_STRIPE)
  176431. + task->output.crop.pos.y += t->set.sp_setting.o_bottom_pos;
  176432. + break;
  176433. + case IPU_ROTATE_VERT_FLIP:
  176434. + if (stripe & LEFT_STRIPE)
  176435. + task->output.crop.pos.x += t->set.sp_setting.o_left_pos;
  176436. + else if (stripe & RIGHT_STRIPE)
  176437. + task->output.crop.pos.x += t->set.sp_setting.o_right_pos;
  176438. + if (stripe & UP_STRIPE)
  176439. + task->output.crop.pos.y =
  176440. + t->output.crop.pos.y + t->output.crop.h
  176441. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  176442. + else if (stripe & DOWN_STRIPE)
  176443. + task->output.crop.pos.y =
  176444. + t->output.crop.pos.y + t->output.crop.h
  176445. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  176446. + break;
  176447. + case IPU_ROTATE_HORIZ_FLIP:
  176448. + if (stripe & LEFT_STRIPE)
  176449. + task->output.crop.pos.x =
  176450. + t->output.crop.pos.x + t->output.crop.w
  176451. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  176452. + else if (stripe & RIGHT_STRIPE)
  176453. + task->output.crop.pos.x =
  176454. + t->output.crop.pos.x + t->output.crop.w
  176455. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  176456. + if (stripe & UP_STRIPE)
  176457. + task->output.crop.pos.y += t->set.sp_setting.o_top_pos;
  176458. + else if (stripe & DOWN_STRIPE)
  176459. + task->output.crop.pos.y += t->set.sp_setting.o_bottom_pos;
  176460. + break;
  176461. + case IPU_ROTATE_180:
  176462. + if (stripe & LEFT_STRIPE)
  176463. + task->output.crop.pos.x =
  176464. + t->output.crop.pos.x + t->output.crop.w
  176465. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  176466. + else if (stripe & RIGHT_STRIPE)
  176467. + task->output.crop.pos.x =
  176468. + t->output.crop.pos.x + t->output.crop.w
  176469. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  176470. + if (stripe & UP_STRIPE)
  176471. + task->output.crop.pos.y =
  176472. + t->output.crop.pos.y + t->output.crop.h
  176473. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  176474. + else if (stripe & DOWN_STRIPE)
  176475. + task->output.crop.pos.y =
  176476. + t->output.crop.pos.y + t->output.crop.h
  176477. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  176478. + break;
  176479. + case IPU_ROTATE_90_RIGHT:
  176480. + if (stripe & UP_STRIPE)
  176481. + task->output.crop.pos.x =
  176482. + t->output.crop.pos.x + t->output.crop.w
  176483. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  176484. + else if (stripe & DOWN_STRIPE)
  176485. + task->output.crop.pos.x =
  176486. + t->output.crop.pos.x + t->output.crop.w
  176487. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  176488. + if (stripe & LEFT_STRIPE)
  176489. + task->output.crop.pos.y += t->set.sp_setting.o_left_pos;
  176490. + else if (stripe & RIGHT_STRIPE)
  176491. + task->output.crop.pos.y += t->set.sp_setting.o_right_pos;
  176492. + break;
  176493. + case IPU_ROTATE_90_RIGHT_HFLIP:
  176494. + if (stripe & UP_STRIPE)
  176495. + task->output.crop.pos.x += t->set.sp_setting.o_top_pos;
  176496. + else if (stripe & DOWN_STRIPE)
  176497. + task->output.crop.pos.x += t->set.sp_setting.o_bottom_pos;
  176498. + if (stripe & LEFT_STRIPE)
  176499. + task->output.crop.pos.y += t->set.sp_setting.o_left_pos;
  176500. + else if (stripe & RIGHT_STRIPE)
  176501. + task->output.crop.pos.y += t->set.sp_setting.o_right_pos;
  176502. + break;
  176503. + case IPU_ROTATE_90_RIGHT_VFLIP:
  176504. + if (stripe & UP_STRIPE)
  176505. + task->output.crop.pos.x =
  176506. + t->output.crop.pos.x + t->output.crop.w
  176507. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  176508. + else if (stripe & DOWN_STRIPE)
  176509. + task->output.crop.pos.x =
  176510. + t->output.crop.pos.x + t->output.crop.w
  176511. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  176512. + if (stripe & LEFT_STRIPE)
  176513. + task->output.crop.pos.y =
  176514. + t->output.crop.pos.y + t->output.crop.h
  176515. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  176516. + else if (stripe & RIGHT_STRIPE)
  176517. + task->output.crop.pos.y =
  176518. + t->output.crop.pos.y + t->output.crop.h
  176519. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  176520. + break;
  176521. + case IPU_ROTATE_90_LEFT:
  176522. + if (stripe & UP_STRIPE)
  176523. + task->output.crop.pos.x += t->set.sp_setting.o_top_pos;
  176524. + else if (stripe & DOWN_STRIPE)
  176525. + task->output.crop.pos.x += t->set.sp_setting.o_bottom_pos;
  176526. + if (stripe & LEFT_STRIPE)
  176527. + task->output.crop.pos.y =
  176528. + t->output.crop.pos.y + t->output.crop.h
  176529. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  176530. + else if (stripe & RIGHT_STRIPE)
  176531. + task->output.crop.pos.y =
  176532. + t->output.crop.pos.y + t->output.crop.h
  176533. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  176534. + break;
  176535. + default:
  176536. + dev_err(t->dev, "ERR:should not be here\n");
  176537. + break;
  176538. + }
  176539. +
  176540. + ret = create_split_child_task(sp_task);
  176541. + if (ret < 0)
  176542. + dev_err(t->dev, "ERR:create_split_child_task() ret:%d\n", ret);
  176543. + return ret;
  176544. +}
  176545. +
  176546. +static int queue_split_task(struct ipu_task_entry *t,
  176547. + struct ipu_split_task *sp_task, uint32_t size)
  176548. +{
  176549. + int err[4];
  176550. + int ret = 0;
  176551. + int i, j;
  176552. + struct ipu_task_entry *tsk = NULL;
  176553. + struct mutex *lock = &t->split_lock;
  176554. + struct mutex *vdic_lock = &t->vdic_lock;
  176555. +
  176556. + dev_dbg(t->dev, "Split task 0x%p, no-0x%x, size:%d\n",
  176557. + t, t->task_no, size);
  176558. + mutex_init(lock);
  176559. + mutex_init(vdic_lock);
  176560. + init_waitqueue_head(&t->split_waitq);
  176561. + INIT_LIST_HEAD(&t->split_list);
  176562. + for (j = 0; j < size; j++) {
  176563. + memset(&sp_task[j], 0, sizeof(*sp_task));
  176564. + sp_task[j].parent_task = t;
  176565. + sp_task[j].task_no = t->task_no;
  176566. + }
  176567. +
  176568. + if (t->set.split_mode == RL_SPLIT) {
  176569. + i = 0;
  176570. + err[i] = create_split_task(RIGHT_STRIPE, &sp_task[i]);
  176571. + if (err[i] < 0)
  176572. + goto err_start;
  176573. + i = 1;
  176574. + err[i] = create_split_task(LEFT_STRIPE, &sp_task[i]);
  176575. + } else if (t->set.split_mode == UD_SPLIT) {
  176576. + i = 0;
  176577. + err[i] = create_split_task(DOWN_STRIPE, &sp_task[i]);
  176578. + if (err[i] < 0)
  176579. + goto err_start;
  176580. + i = 1;
  176581. + err[i] = create_split_task(UP_STRIPE, &sp_task[i]);
  176582. + } else {
  176583. + i = 0;
  176584. + err[i] = create_split_task(RIGHT_STRIPE | DOWN_STRIPE, &sp_task[i]);
  176585. + if (err[i] < 0)
  176586. + goto err_start;
  176587. + i = 1;
  176588. + err[i] = create_split_task(LEFT_STRIPE | DOWN_STRIPE, &sp_task[i]);
  176589. + if (err[i] < 0)
  176590. + goto err_start;
  176591. + i = 2;
  176592. + err[i] = create_split_task(RIGHT_STRIPE | UP_STRIPE, &sp_task[i]);
  176593. + if (err[i] < 0)
  176594. + goto err_start;
  176595. + i = 3;
  176596. + err[i] = create_split_task(LEFT_STRIPE | UP_STRIPE, &sp_task[i]);
  176597. + }
  176598. +
  176599. +err_start:
  176600. + for (j = 0; j < (i + 1); j++) {
  176601. + if (err[j] < 0) {
  176602. + if (sp_task[j].child_task)
  176603. + dev_err(t->dev,
  176604. + "sp_task[%d],no-0x%x fail state:%d, queue err:%d.\n",
  176605. + j, sp_task[j].child_task->task_no,
  176606. + sp_task[j].child_task->state, err[j]);
  176607. + goto err_exit;
  176608. + }
  176609. + dev_dbg(t->dev, "[0x%p] sp_task[%d], no-0x%x state:%s, queue ret:%d.\n",
  176610. + sp_task[j].child_task, j, sp_task[j].child_task->task_no,
  176611. + state_msg[sp_task[j].child_task->state].msg, err[j]);
  176612. + }
  176613. +
  176614. + return ret;
  176615. +
  176616. +err_exit:
  176617. + for (j = 0; j < (i + 1); j++) {
  176618. + if (err[j] < 0 && !ret)
  176619. + ret = err[j];
  176620. + tsk = sp_task[j].child_task;
  176621. + if (!tsk)
  176622. + continue;
  176623. + kfree(tsk);
  176624. + }
  176625. + t->state = STATE_ERR;
  176626. + return ret;
  176627. +
  176628. +}
  176629. +
  176630. +static int init_tiled_buf(struct ipu_soc *ipu, struct ipu_task_entry *t,
  176631. + ipu_channel_t channel, uint32_t ch_type)
  176632. +{
  176633. + int ret = 0;
  176634. + int i;
  176635. + uint32_t ipu_fmt;
  176636. + dma_addr_t inbuf_base = 0;
  176637. + u32 field_size;
  176638. + struct vdoa_params param;
  176639. + struct vdoa_ipu_buf buf;
  176640. + struct ipu_soc *ipu_idx;
  176641. + u32 ipu_stride, obuf_size;
  176642. + u32 height, width;
  176643. + ipu_buffer_t type;
  176644. +
  176645. + if ((IPU_PIX_FMT_YUYV != t->output.format) &&
  176646. + (IPU_PIX_FMT_NV12 != t->output.format)) {
  176647. + dev_err(t->dev, "ERR:[0x%d] output format\n", t->task_no);
  176648. + return -EINVAL;
  176649. + }
  176650. +
  176651. + memset(&param, 0, sizeof(param));
  176652. + /* init channel tiled bufs */
  176653. + if (deinterlace_3_field(t) &&
  176654. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  176655. + field_size = tiled_filed_size(t);
  176656. + if (INPUT_CHAN_VDI_P == ch_type) {
  176657. + inbuf_base = t->input.paddr + field_size;
  176658. + param.vfield_buf.prev_veba = inbuf_base + t->set.i_off;
  176659. + } else if (INPUT_CHAN == ch_type) {
  176660. + inbuf_base = t->input.paddr_n;
  176661. + param.vfield_buf.cur_veba = inbuf_base + t->set.i_off;
  176662. + } else if (INPUT_CHAN_VDI_N == ch_type) {
  176663. + inbuf_base = t->input.paddr_n + field_size;
  176664. + param.vfield_buf.next_veba = inbuf_base + t->set.i_off;
  176665. + } else
  176666. + return -EINVAL;
  176667. + height = t->input.crop.h >> 1; /* field format for vdoa */
  176668. + width = t->input.crop.w;
  176669. + param.vfield_buf.vubo = t->set.i_uoff;
  176670. + param.interlaced = 1;
  176671. + param.scan_order = 1;
  176672. + type = IPU_INPUT_BUFFER;
  176673. + } else if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) &&
  176674. + (INPUT_CHAN == ch_type)) {
  176675. + height = t->input.crop.h;
  176676. + width = t->input.crop.w;
  176677. + param.vframe_buf.veba = t->input.paddr + t->set.i_off;
  176678. + param.vframe_buf.vubo = t->set.i_uoff;
  176679. + type = IPU_INPUT_BUFFER;
  176680. + } else
  176681. + return -EINVAL;
  176682. +
  176683. + param.band_mode = (t->set.mode & VDOA_BAND_MODE) ? 1 : 0;
  176684. + if (param.band_mode && (t->set.band_lines != 3) &&
  176685. + (t->set.band_lines != 4) && (t->set.band_lines != 5))
  176686. + return -EINVAL;
  176687. + else if (param.band_mode)
  176688. + param.band_lines = (1 << t->set.band_lines);
  176689. + for (i = 0; i < max_ipu_no; i++) {
  176690. + ipu_idx = ipu_get_soc(i);
  176691. + if (!IS_ERR(ipu_idx) && ipu_idx == ipu)
  176692. + break;
  176693. + }
  176694. + if (t->set.task & VDOA_ONLY)
  176695. + /* dummy, didn't need ipu res */
  176696. + i = 0;
  176697. + if (max_ipu_no == i) {
  176698. + dev_err(t->dev, "ERR:[0x%p] get ipu num\n", t);
  176699. + return -EINVAL;
  176700. + }
  176701. +
  176702. + param.ipu_num = i;
  176703. + param.vpu_stride = t->input.width;
  176704. + param.height = height;
  176705. + param.width = width;
  176706. + if (IPU_PIX_FMT_NV12 == t->output.format)
  176707. + param.pfs = VDOA_PFS_NV12;
  176708. + else
  176709. + param.pfs = VDOA_PFS_YUYV;
  176710. + ipu_fmt = (param.pfs == VDOA_PFS_YUYV) ? IPU_PIX_FMT_YUYV :
  176711. + IPU_PIX_FMT_NV12;
  176712. + ipu_stride = param.width * bytes_per_pixel(ipu_fmt);
  176713. + obuf_size = PAGE_ALIGN(param.width * param.height *
  176714. + fmt_to_bpp(ipu_fmt)/8);
  176715. + dev_dbg(t->dev, "band_mode:%d, band_lines:%d\n",
  176716. + param.band_mode, param.band_lines);
  176717. + if (!param.band_mode) {
  176718. + /* note: if only for tiled -> raster convert and
  176719. + no other post-processing, we don't need alloc buf
  176720. + and use output buffer directly.
  176721. + */
  176722. + if (t->set.task & VDOA_ONLY)
  176723. + param.ieba0 = t->output.paddr;
  176724. + else {
  176725. + dev_err(t->dev, "ERR:[0x%d] vdoa task\n", t->task_no);
  176726. + return -EINVAL;
  176727. + }
  176728. + } else {
  176729. + if (IPU_PIX_FMT_TILED_NV12F != t->input.format) {
  176730. + dev_err(t->dev, "ERR [0x%d] vdoa task\n", t->task_no);
  176731. + return -EINVAL;
  176732. + }
  176733. + }
  176734. + ret = vdoa_setup(t->vdoa_handle, &param);
  176735. + if (ret)
  176736. + goto done;
  176737. + vdoa_get_output_buf(t->vdoa_handle, &buf);
  176738. + if (t->set.task & VDOA_ONLY)
  176739. + goto done;
  176740. +
  176741. + ret = ipu_init_channel_buffer(ipu,
  176742. + channel,
  176743. + type,
  176744. + ipu_fmt,
  176745. + width,
  176746. + height,
  176747. + ipu_stride,
  176748. + IPU_ROTATE_NONE,
  176749. + buf.ieba0,
  176750. + buf.ieba1,
  176751. + 0,
  176752. + buf.iubo,
  176753. + 0);
  176754. + if (ret < 0) {
  176755. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  176756. + goto done;
  176757. + }
  176758. +
  176759. + if (param.band_mode) {
  176760. + ret = ipu_set_channel_bandmode(ipu, channel,
  176761. + type, t->set.band_lines);
  176762. + if (ret < 0) {
  176763. + t->state = STATE_INIT_CHAN_BAND_FAIL;
  176764. + goto done;
  176765. + }
  176766. + }
  176767. +done:
  176768. + return ret;
  176769. +}
  176770. +
  176771. +static int init_tiled_ch_bufs(struct ipu_soc *ipu, struct ipu_task_entry *t)
  176772. +{
  176773. + int ret = 0;
  176774. +
  176775. + if (IPU_PIX_FMT_TILED_NV12 == t->input.format) {
  176776. + ret = init_tiled_buf(ipu, t, t->set.ic_chan, INPUT_CHAN);
  176777. + CHECK_RETCODE(ret < 0, "init tiled_ch", t->state, done, ret);
  176778. + } else if (IPU_PIX_FMT_TILED_NV12F == t->input.format) {
  176779. + ret = init_tiled_buf(ipu, t, t->set.ic_chan, INPUT_CHAN);
  176780. + CHECK_RETCODE(ret < 0, "init tiled_ch-c", t->state, done, ret);
  176781. + ret = init_tiled_buf(ipu, t, t->set.vdi_ic_p_chan,
  176782. + INPUT_CHAN_VDI_P);
  176783. + CHECK_RETCODE(ret < 0, "init tiled_ch-p", t->state, done, ret);
  176784. + ret = init_tiled_buf(ipu, t, t->set.vdi_ic_n_chan,
  176785. + INPUT_CHAN_VDI_N);
  176786. + CHECK_RETCODE(ret < 0, "init tiled_ch-n", t->state, done, ret);
  176787. + } else {
  176788. + ret = -EINVAL;
  176789. + dev_err(t->dev, "ERR[no-0x%x] invalid fmt:0x%x!\n",
  176790. + t->task_no, t->input.format);
  176791. + }
  176792. +
  176793. +done:
  176794. + return ret;
  176795. +}
  176796. +
  176797. +static int init_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
  176798. +{
  176799. + int ret = 0;
  176800. + ipu_channel_params_t params;
  176801. + dma_addr_t inbuf = 0, ovbuf = 0, ov_alp_buf = 0;
  176802. + dma_addr_t inbuf_p = 0, inbuf_n = 0;
  176803. + dma_addr_t outbuf = 0;
  176804. + int out_uoff = 0, out_voff = 0, out_rot;
  176805. + int out_w = 0, out_h = 0, out_stride;
  176806. + int out_fmt;
  176807. + u32 vdi_frame_idx = 0;
  176808. +
  176809. + memset(&params, 0, sizeof(params));
  176810. +
  176811. + /* is it need link a rot channel */
  176812. + if (ic_and_rot(t->set.mode)) {
  176813. + outbuf = t->set.r_paddr;
  176814. + out_w = t->set.r_width;
  176815. + out_h = t->set.r_height;
  176816. + out_stride = t->set.r_stride;
  176817. + out_fmt = t->set.r_fmt;
  176818. + out_uoff = 0;
  176819. + out_voff = 0;
  176820. + out_rot = IPU_ROTATE_NONE;
  176821. + } else {
  176822. + outbuf = t->output.paddr + t->set.o_off;
  176823. + out_w = t->output.crop.w;
  176824. + out_h = t->output.crop.h;
  176825. + out_stride = t->set.ostride;
  176826. + out_fmt = t->output.format;
  176827. + out_uoff = t->set.o_uoff;
  176828. + out_voff = t->set.o_voff;
  176829. + out_rot = t->output.rotate;
  176830. + }
  176831. +
  176832. + /* settings */
  176833. + params.mem_prp_vf_mem.in_width = t->input.crop.w;
  176834. + params.mem_prp_vf_mem.out_width = out_w;
  176835. + params.mem_prp_vf_mem.in_height = t->input.crop.h;
  176836. + params.mem_prp_vf_mem.out_height = out_h;
  176837. + params.mem_prp_vf_mem.in_pixel_fmt = t->input.format;
  176838. + params.mem_prp_vf_mem.out_pixel_fmt = out_fmt;
  176839. + params.mem_prp_vf_mem.motion_sel = t->input.deinterlace.motion;
  176840. +
  176841. + params.mem_prp_vf_mem.outh_resize_ratio =
  176842. + t->set.sp_setting.outh_resize_ratio;
  176843. + params.mem_prp_vf_mem.outv_resize_ratio =
  176844. + t->set.sp_setting.outv_resize_ratio;
  176845. +
  176846. + if (t->overlay_en) {
  176847. + params.mem_prp_vf_mem.in_g_pixel_fmt = t->overlay.format;
  176848. + params.mem_prp_vf_mem.graphics_combine_en = 1;
  176849. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_GLOBAL)
  176850. + params.mem_prp_vf_mem.global_alpha_en = 1;
  176851. + else if (t->overlay.alpha.loc_alp_paddr)
  176852. + params.mem_prp_vf_mem.alpha_chan_en = 1;
  176853. + /* otherwise, alpha bending per pixel is used. */
  176854. + params.mem_prp_vf_mem.alpha = t->overlay.alpha.gvalue;
  176855. + if (t->overlay.colorkey.enable) {
  176856. + params.mem_prp_vf_mem.key_color_en = 1;
  176857. + params.mem_prp_vf_mem.key_color = t->overlay.colorkey.value;
  176858. + }
  176859. + }
  176860. +
  176861. + if (t->input.deinterlace.enable) {
  176862. + if (t->input.deinterlace.field_fmt & IPU_DEINTERLACE_FIELD_MASK)
  176863. + params.mem_prp_vf_mem.field_fmt =
  176864. + IPU_DEINTERLACE_FIELD_BOTTOM;
  176865. + else
  176866. + params.mem_prp_vf_mem.field_fmt =
  176867. + IPU_DEINTERLACE_FIELD_TOP;
  176868. +
  176869. + if (t->input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN)
  176870. + vdi_frame_idx = t->input.deinterlace.field_fmt &
  176871. + IPU_DEINTERLACE_RATE_FRAME1;
  176872. + }
  176873. +
  176874. + if (t->set.mode & VDOA_MODE)
  176875. + ipu->vdoa_en = 1;
  176876. +
  176877. + /* init channels */
  176878. + if (!(t->set.task & VDOA_ONLY)) {
  176879. + ret = ipu_init_channel(ipu, t->set.ic_chan, &params);
  176880. + if (ret < 0) {
  176881. + t->state = STATE_INIT_CHAN_FAIL;
  176882. + goto done;
  176883. + }
  176884. + }
  176885. +
  176886. + if (deinterlace_3_field(t)) {
  176887. + ret = ipu_init_channel(ipu, t->set.vdi_ic_p_chan, &params);
  176888. + if (ret < 0) {
  176889. + t->state = STATE_INIT_CHAN_FAIL;
  176890. + goto done;
  176891. + }
  176892. + ret = ipu_init_channel(ipu, t->set.vdi_ic_n_chan, &params);
  176893. + if (ret < 0) {
  176894. + t->state = STATE_INIT_CHAN_FAIL;
  176895. + goto done;
  176896. + }
  176897. + }
  176898. +
  176899. + /* init channel bufs */
  176900. + if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  176901. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  176902. + ret = init_tiled_ch_bufs(ipu, t);
  176903. + if (ret < 0)
  176904. + goto done;
  176905. + } else {
  176906. + if ((deinterlace_3_field(t)) &&
  176907. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  176908. + if (params.mem_prp_vf_mem.field_fmt ==
  176909. + IPU_DEINTERLACE_FIELD_TOP) {
  176910. + if (vdi_frame_idx) {
  176911. + inbuf_p = t->input.paddr + t->set.istride +
  176912. + t->set.i_off;
  176913. + inbuf = t->input.paddr_n + t->set.i_off;
  176914. + inbuf_n = t->input.paddr_n + t->set.istride +
  176915. + t->set.i_off;
  176916. + params.mem_prp_vf_mem.field_fmt =
  176917. + IPU_DEINTERLACE_FIELD_BOTTOM;
  176918. + } else {
  176919. + inbuf_p = t->input.paddr + t->set.i_off;
  176920. + inbuf = t->input.paddr + t->set.istride + t->set.i_off;
  176921. + inbuf_n = t->input.paddr_n + t->set.i_off;
  176922. + }
  176923. + } else {
  176924. + if (vdi_frame_idx) {
  176925. + inbuf_p = t->input.paddr + t->set.i_off;
  176926. + inbuf = t->input.paddr_n + t->set.istride + t->set.i_off;
  176927. + inbuf_n = t->input.paddr_n + t->set.i_off;
  176928. + params.mem_prp_vf_mem.field_fmt =
  176929. + IPU_DEINTERLACE_FIELD_TOP;
  176930. + } else {
  176931. + inbuf_p = t->input.paddr + t->set.istride +
  176932. + t->set.i_off;
  176933. + inbuf = t->input.paddr + t->set.i_off;
  176934. + inbuf_n = t->input.paddr_n + t->set.istride +
  176935. + t->set.i_off;
  176936. + }
  176937. + }
  176938. + } else {
  176939. + if (t->input.deinterlace.enable) {
  176940. + if (params.mem_prp_vf_mem.field_fmt ==
  176941. + IPU_DEINTERLACE_FIELD_TOP) {
  176942. + if (vdi_frame_idx) {
  176943. + inbuf = t->input.paddr + t->set.istride + t->set.i_off;
  176944. + params.mem_prp_vf_mem.field_fmt =
  176945. + IPU_DEINTERLACE_FIELD_BOTTOM;
  176946. + } else
  176947. + inbuf = t->input.paddr + t->set.i_off;
  176948. + } else {
  176949. + if (vdi_frame_idx) {
  176950. + inbuf = t->input.paddr + t->set.i_off;
  176951. + params.mem_prp_vf_mem.field_fmt =
  176952. + IPU_DEINTERLACE_FIELD_TOP;
  176953. + } else
  176954. + inbuf = t->input.paddr + t->set.istride + t->set.i_off;
  176955. + }
  176956. + } else
  176957. + inbuf = t->input.paddr + t->set.i_off;
  176958. + }
  176959. +
  176960. + if (t->overlay_en)
  176961. + ovbuf = t->overlay.paddr + t->set.ov_off;
  176962. + }
  176963. + if (t->overlay_en && (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL))
  176964. + ov_alp_buf = t->overlay.alpha.loc_alp_paddr
  176965. + + t->set.ov_alpha_off;
  176966. +
  176967. + if ((IPU_PIX_FMT_TILED_NV12 != t->input.format) &&
  176968. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  176969. + ret = ipu_init_channel_buffer(ipu,
  176970. + t->set.ic_chan,
  176971. + IPU_INPUT_BUFFER,
  176972. + t->input.format,
  176973. + t->input.crop.w,
  176974. + t->input.crop.h,
  176975. + t->set.istride,
  176976. + IPU_ROTATE_NONE,
  176977. + inbuf,
  176978. + 0,
  176979. + 0,
  176980. + t->set.i_uoff,
  176981. + t->set.i_voff);
  176982. + if (ret < 0) {
  176983. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  176984. + goto done;
  176985. + }
  176986. + }
  176987. + if (deinterlace_3_field(t) &&
  176988. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  176989. + ret = ipu_init_channel_buffer(ipu,
  176990. + t->set.vdi_ic_p_chan,
  176991. + IPU_INPUT_BUFFER,
  176992. + t->input.format,
  176993. + t->input.crop.w,
  176994. + t->input.crop.h,
  176995. + t->set.istride,
  176996. + IPU_ROTATE_NONE,
  176997. + inbuf_p,
  176998. + 0,
  176999. + 0,
  177000. + t->set.i_uoff,
  177001. + t->set.i_voff);
  177002. + if (ret < 0) {
  177003. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177004. + goto done;
  177005. + }
  177006. +
  177007. + ret = ipu_init_channel_buffer(ipu,
  177008. + t->set.vdi_ic_n_chan,
  177009. + IPU_INPUT_BUFFER,
  177010. + t->input.format,
  177011. + t->input.crop.w,
  177012. + t->input.crop.h,
  177013. + t->set.istride,
  177014. + IPU_ROTATE_NONE,
  177015. + inbuf_n,
  177016. + 0,
  177017. + 0,
  177018. + t->set.i_uoff,
  177019. + t->set.i_voff);
  177020. + if (ret < 0) {
  177021. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177022. + goto done;
  177023. + }
  177024. + }
  177025. +
  177026. + if (t->overlay_en) {
  177027. + ret = ipu_init_channel_buffer(ipu,
  177028. + t->set.ic_chan,
  177029. + IPU_GRAPH_IN_BUFFER,
  177030. + t->overlay.format,
  177031. + t->overlay.crop.w,
  177032. + t->overlay.crop.h,
  177033. + t->set.ovstride,
  177034. + IPU_ROTATE_NONE,
  177035. + ovbuf,
  177036. + 0,
  177037. + 0,
  177038. + t->set.ov_uoff,
  177039. + t->set.ov_voff);
  177040. + if (ret < 0) {
  177041. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177042. + goto done;
  177043. + }
  177044. + }
  177045. +
  177046. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  177047. + ret = ipu_init_channel_buffer(ipu,
  177048. + t->set.ic_chan,
  177049. + IPU_ALPHA_IN_BUFFER,
  177050. + IPU_PIX_FMT_GENERIC,
  177051. + t->overlay.crop.w,
  177052. + t->overlay.crop.h,
  177053. + t->set.ov_alpha_stride,
  177054. + IPU_ROTATE_NONE,
  177055. + ov_alp_buf,
  177056. + 0,
  177057. + 0,
  177058. + 0, 0);
  177059. + if (ret < 0) {
  177060. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177061. + goto done;
  177062. + }
  177063. + }
  177064. +
  177065. + if (!(t->set.task & VDOA_ONLY)) {
  177066. + ret = ipu_init_channel_buffer(ipu,
  177067. + t->set.ic_chan,
  177068. + IPU_OUTPUT_BUFFER,
  177069. + out_fmt,
  177070. + out_w,
  177071. + out_h,
  177072. + out_stride,
  177073. + out_rot,
  177074. + outbuf,
  177075. + 0,
  177076. + 0,
  177077. + out_uoff,
  177078. + out_voff);
  177079. + if (ret < 0) {
  177080. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177081. + goto done;
  177082. + }
  177083. + }
  177084. +
  177085. + if ((t->set.mode & VDOA_BAND_MODE) && (t->set.task & VDI_VF)) {
  177086. + ret = ipu_link_channels(ipu, MEM_VDOA_MEM, t->set.ic_chan);
  177087. + CHECK_RETCODE(ret < 0, "ipu_link_ch vdoa_ic",
  177088. + STATE_LINK_CHAN_FAIL, done, ret);
  177089. + }
  177090. +
  177091. +done:
  177092. + return ret;
  177093. +}
  177094. +
  177095. +static void uninit_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
  177096. +{
  177097. + int ret;
  177098. +
  177099. + if ((t->set.mode & VDOA_BAND_MODE) && (t->set.task & VDI_VF)) {
  177100. + ret = ipu_unlink_channels(ipu, MEM_VDOA_MEM, t->set.ic_chan);
  177101. + CHECK_RETCODE_CONT(ret < 0, "ipu_unlink_ch vdoa_ic",
  177102. + STATE_UNLINK_CHAN_FAIL, ret);
  177103. + }
  177104. + ipu_uninit_channel(ipu, t->set.ic_chan);
  177105. + if (deinterlace_3_field(t)) {
  177106. + ipu_uninit_channel(ipu, t->set.vdi_ic_p_chan);
  177107. + ipu_uninit_channel(ipu, t->set.vdi_ic_n_chan);
  177108. + }
  177109. +}
  177110. +
  177111. +static int init_rot(struct ipu_soc *ipu, struct ipu_task_entry *t)
  177112. +{
  177113. + int ret = 0;
  177114. + dma_addr_t inbuf = 0, outbuf = 0;
  177115. + int in_uoff = 0, in_voff = 0;
  177116. + int in_fmt, in_width, in_height, in_stride;
  177117. +
  177118. + /* init channel */
  177119. + ret = ipu_init_channel(ipu, t->set.rot_chan, NULL);
  177120. + if (ret < 0) {
  177121. + t->state = STATE_INIT_CHAN_FAIL;
  177122. + goto done;
  177123. + }
  177124. +
  177125. + /* init channel buf */
  177126. + /* is it need link to a ic channel */
  177127. + if (ic_and_rot(t->set.mode)) {
  177128. + in_fmt = t->set.r_fmt;
  177129. + in_width = t->set.r_width;
  177130. + in_height = t->set.r_height;
  177131. + in_stride = t->set.r_stride;
  177132. + inbuf = t->set.r_paddr;
  177133. + in_uoff = 0;
  177134. + in_voff = 0;
  177135. + } else {
  177136. + in_fmt = t->input.format;
  177137. + in_width = t->input.crop.w;
  177138. + in_height = t->input.crop.h;
  177139. + in_stride = t->set.istride;
  177140. + inbuf = t->input.paddr + t->set.i_off;
  177141. + in_uoff = t->set.i_uoff;
  177142. + in_voff = t->set.i_voff;
  177143. + }
  177144. + outbuf = t->output.paddr + t->set.o_off;
  177145. +
  177146. + ret = ipu_init_channel_buffer(ipu,
  177147. + t->set.rot_chan,
  177148. + IPU_INPUT_BUFFER,
  177149. + in_fmt,
  177150. + in_width,
  177151. + in_height,
  177152. + in_stride,
  177153. + t->output.rotate,
  177154. + inbuf,
  177155. + 0,
  177156. + 0,
  177157. + in_uoff,
  177158. + in_voff);
  177159. + if (ret < 0) {
  177160. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177161. + goto done;
  177162. + }
  177163. +
  177164. + ret = ipu_init_channel_buffer(ipu,
  177165. + t->set.rot_chan,
  177166. + IPU_OUTPUT_BUFFER,
  177167. + t->output.format,
  177168. + t->output.crop.w,
  177169. + t->output.crop.h,
  177170. + t->set.ostride,
  177171. + IPU_ROTATE_NONE,
  177172. + outbuf,
  177173. + 0,
  177174. + 0,
  177175. + t->set.o_uoff,
  177176. + t->set.o_voff);
  177177. + if (ret < 0) {
  177178. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177179. + goto done;
  177180. + }
  177181. +
  177182. +done:
  177183. + return ret;
  177184. +}
  177185. +
  177186. +static void uninit_rot(struct ipu_soc *ipu, struct ipu_task_entry *t)
  177187. +{
  177188. + ipu_uninit_channel(ipu, t->set.rot_chan);
  177189. +}
  177190. +
  177191. +static int get_irq(struct ipu_task_entry *t)
  177192. +{
  177193. + int irq;
  177194. + ipu_channel_t chan;
  177195. +
  177196. + if (only_ic(t->set.mode))
  177197. + chan = t->set.ic_chan;
  177198. + else
  177199. + chan = t->set.rot_chan;
  177200. +
  177201. + switch (chan) {
  177202. + case MEM_ROT_VF_MEM:
  177203. + irq = IPU_IRQ_PRP_VF_ROT_OUT_EOF;
  177204. + break;
  177205. + case MEM_ROT_PP_MEM:
  177206. + irq = IPU_IRQ_PP_ROT_OUT_EOF;
  177207. + break;
  177208. + case MEM_VDI_PRP_VF_MEM:
  177209. + case MEM_PRP_VF_MEM:
  177210. + irq = IPU_IRQ_PRP_VF_OUT_EOF;
  177211. + break;
  177212. + case MEM_PP_MEM:
  177213. + irq = IPU_IRQ_PP_OUT_EOF;
  177214. + break;
  177215. + case MEM_VDI_MEM:
  177216. + irq = IPU_IRQ_VDIC_OUT_EOF;
  177217. + break;
  177218. + default:
  177219. + irq = -EINVAL;
  177220. + }
  177221. +
  177222. + return irq;
  177223. +}
  177224. +
  177225. +static irqreturn_t task_irq_handler(int irq, void *dev_id)
  177226. +{
  177227. + struct ipu_task_entry *prev_tsk = dev_id;
  177228. +
  177229. + CHECK_PERF(&prev_tsk->ts_inirq);
  177230. + complete(&prev_tsk->irq_comp);
  177231. + dev_dbg(prev_tsk->dev, "[0x%p] no-0x%x in-irq!",
  177232. + prev_tsk, prev_tsk->task_no);
  177233. +
  177234. + return IRQ_HANDLED;
  177235. +}
  177236. +
  177237. +/* Fix deinterlace up&down split mode medium line */
  177238. +static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
  177239. +{
  177240. + u32 vdi_size;
  177241. + u32 vdi_save_lines;
  177242. + u32 stripe_mode;
  177243. + u32 task_no;
  177244. + u32 i, offset_addr;
  177245. + u32 line_size;
  177246. + unsigned char *base_off;
  177247. + struct ipu_task_entry *parent = t->parent;
  177248. + struct mutex *lock = &parent->vdic_lock;
  177249. +
  177250. + if (!parent) {
  177251. + dev_err(t->dev, "ERR[0x%x]invalid parent\n", t->task_no);
  177252. + return;
  177253. + }
  177254. + mutex_lock(lock);
  177255. + stripe_mode = t->task_no & 0xf;
  177256. + task_no = t->task_no >> 4;
  177257. +
  177258. + /* Save both luma and chroma part for interleaved YUV(e.g. YUYV).
  177259. + * Save luma part for non-interleaved and partial-interleaved
  177260. + * YUV format (e.g NV12 and YV12). */
  177261. + if (t->output.format == IPU_PIX_FMT_YUYV ||
  177262. + t->output.format == IPU_PIX_FMT_UYVY)
  177263. + line_size = t->output.crop.w * fmt_to_bpp(t->output.format)/8;
  177264. + else
  177265. + line_size = t->output.crop.w;
  177266. +
  177267. + vdi_save_lines = (t->output.crop.h - t->set.sp_setting.ud_split_line)/2;
  177268. + vdi_size = vdi_save_lines * line_size;
  177269. + if (vdi_save_lines <= 0) {
  177270. + dev_err(t->dev, "[0x%p] vdi_save_line error\n", (void *)t);
  177271. + mutex_unlock(lock);
  177272. + return;
  177273. + }
  177274. +
  177275. + /*check vditmpbuf buffer have alloced or buffer size is changed */
  177276. + if ((vdi_save_lines != parent->old_save_lines) ||
  177277. + (vdi_size != parent->old_size)) {
  177278. + if (parent->vditmpbuf[0] != NULL)
  177279. + kfree(parent->vditmpbuf[0]);
  177280. + if (parent->vditmpbuf[1] != NULL)
  177281. + kfree(parent->vditmpbuf[1]);
  177282. +
  177283. + parent->vditmpbuf[0] = kmalloc(vdi_size, GFP_KERNEL);
  177284. + if (parent->vditmpbuf[0] == NULL) {
  177285. + dev_err(t->dev,
  177286. + "[0x%p]Falied Alloc vditmpbuf[0]\n", (void *)t);
  177287. + mutex_unlock(lock);
  177288. + return;
  177289. + }
  177290. + memset(parent->vditmpbuf[0], 0, vdi_size);
  177291. +
  177292. + parent->vditmpbuf[1] = kmalloc(vdi_size, GFP_KERNEL);
  177293. + if (parent->vditmpbuf[1] == NULL) {
  177294. + dev_err(t->dev,
  177295. + "[0x%p]Falied Alloc vditmpbuf[1]\n", (void *)t);
  177296. + mutex_unlock(lock);
  177297. + return;
  177298. + }
  177299. + memset(parent->vditmpbuf[1], 0, vdi_size);
  177300. +
  177301. + parent->old_save_lines = vdi_save_lines;
  177302. + parent->old_size = vdi_size;
  177303. + }
  177304. +
  177305. + if (pfn_valid(t->output.paddr >> PAGE_SHIFT)) {
  177306. + base_off = page_address(pfn_to_page(t->output.paddr >> PAGE_SHIFT));
  177307. + base_off += t->output.paddr & ((1 << PAGE_SHIFT) - 1);
  177308. + } else {
  177309. + base_off = (char *)ioremap_nocache(t->output.paddr,
  177310. + t->output.width * t->output.height *
  177311. + fmt_to_bpp(t->output.format)/8);
  177312. + }
  177313. + if (base_off == NULL) {
  177314. + dev_err(t->dev, "ERR[0x%p]Failed get virtual address\n", t);
  177315. + mutex_unlock(lock);
  177316. + return;
  177317. + }
  177318. +
  177319. + /* UP stripe or UP&LEFT stripe */
  177320. + if ((stripe_mode == UP_STRIPE) ||
  177321. + (stripe_mode == (UP_STRIPE | LEFT_STRIPE))) {
  177322. + if (!parent->buf0filled) {
  177323. + offset_addr = t->set.o_off +
  177324. + t->set.sp_setting.ud_split_line*t->set.ostride;
  177325. + dmac_flush_range(base_off + offset_addr,
  177326. + base_off + offset_addr + vdi_size);
  177327. + outer_flush_range(t->output.paddr + offset_addr,
  177328. + t->output.paddr + offset_addr + vdi_size);
  177329. +
  177330. + for (i = 0; i < vdi_save_lines; i++)
  177331. + memcpy(parent->vditmpbuf[0] + i*line_size,
  177332. + base_off + offset_addr +
  177333. + i*t->set.ostride, line_size);
  177334. + parent->buf0filled = true;
  177335. + } else {
  177336. + offset_addr = t->set.o_off + (t->output.crop.h -
  177337. + vdi_save_lines) * t->set.ostride;
  177338. + for (i = 0; i < vdi_save_lines; i++)
  177339. + memcpy(base_off + offset_addr + i*t->set.ostride,
  177340. + parent->vditmpbuf[0] + i*line_size, line_size);
  177341. +
  177342. + dmac_flush_range(base_off + offset_addr,
  177343. + base_off + offset_addr + i*t->set.ostride);
  177344. + outer_flush_range(t->output.paddr + offset_addr,
  177345. + t->output.paddr + offset_addr + i*t->set.ostride);
  177346. + parent->buf0filled = false;
  177347. + }
  177348. + }
  177349. + /*Down stripe or Down&Left stripe*/
  177350. + else if ((stripe_mode == DOWN_STRIPE) ||
  177351. + (stripe_mode == (DOWN_STRIPE | LEFT_STRIPE))) {
  177352. + if (!parent->buf0filled) {
  177353. + offset_addr = t->set.o_off + vdi_save_lines*t->set.ostride;
  177354. + dmac_flush_range(base_off + offset_addr,
  177355. + base_off + offset_addr + vdi_size);
  177356. + outer_flush_range(t->output.paddr + offset_addr,
  177357. + t->output.paddr + offset_addr + vdi_size);
  177358. +
  177359. + for (i = 0; i < vdi_save_lines; i++)
  177360. + memcpy(parent->vditmpbuf[0] + i*line_size,
  177361. + base_off + offset_addr + i*t->set.ostride,
  177362. + line_size);
  177363. + parent->buf0filled = true;
  177364. + } else {
  177365. + offset_addr = t->set.o_off;
  177366. + for (i = 0; i < vdi_save_lines; i++)
  177367. + memcpy(base_off + offset_addr + i*t->set.ostride,
  177368. + parent->vditmpbuf[0] + i*line_size,
  177369. + line_size);
  177370. +
  177371. + dmac_flush_range(base_off + offset_addr,
  177372. + base_off + offset_addr + i*t->set.ostride);
  177373. + outer_flush_range(t->output.paddr + offset_addr,
  177374. + t->output.paddr + offset_addr + i*t->set.ostride);
  177375. + parent->buf0filled = false;
  177376. + }
  177377. + }
  177378. + /*Up&Right stripe*/
  177379. + else if (stripe_mode == (UP_STRIPE | RIGHT_STRIPE)) {
  177380. + if (!parent->buf1filled) {
  177381. + offset_addr = t->set.o_off +
  177382. + t->set.sp_setting.ud_split_line*t->set.ostride;
  177383. + dmac_flush_range(base_off + offset_addr,
  177384. + base_off + offset_addr + vdi_size);
  177385. + outer_flush_range(t->output.paddr + offset_addr,
  177386. + t->output.paddr + offset_addr + vdi_size);
  177387. +
  177388. + for (i = 0; i < vdi_save_lines; i++)
  177389. + memcpy(parent->vditmpbuf[1] + i*line_size,
  177390. + base_off + offset_addr + i*t->set.ostride,
  177391. + line_size);
  177392. + parent->buf1filled = true;
  177393. + } else {
  177394. + offset_addr = t->set.o_off +
  177395. + (t->output.crop.h - vdi_save_lines)*t->set.ostride;
  177396. + for (i = 0; i < vdi_save_lines; i++)
  177397. + memcpy(base_off + offset_addr + i*t->set.ostride,
  177398. + parent->vditmpbuf[1] + i*line_size,
  177399. + line_size);
  177400. +
  177401. + dmac_flush_range(base_off + offset_addr,
  177402. + base_off + offset_addr + i*t->set.ostride);
  177403. + outer_flush_range(t->output.paddr + offset_addr,
  177404. + t->output.paddr + offset_addr + i*t->set.ostride);
  177405. + parent->buf1filled = false;
  177406. + }
  177407. + }
  177408. + /*Down stripe or Down&Right stript*/
  177409. + else if (stripe_mode == (DOWN_STRIPE | RIGHT_STRIPE)) {
  177410. + if (!parent->buf1filled) {
  177411. + offset_addr = t->set.o_off + vdi_save_lines*t->set.ostride;
  177412. + dmac_flush_range(base_off + offset_addr,
  177413. + base_off + offset_addr + vdi_save_lines*t->set.ostride);
  177414. + outer_flush_range(t->output.paddr + offset_addr,
  177415. + t->output.paddr + offset_addr + vdi_save_lines*t->set.ostride);
  177416. +
  177417. + for (i = 0; i < vdi_save_lines; i++)
  177418. + memcpy(parent->vditmpbuf[1] + i*line_size,
  177419. + base_off + offset_addr + i*t->set.ostride,
  177420. + line_size);
  177421. + parent->buf1filled = true;
  177422. + } else {
  177423. + offset_addr = t->set.o_off;
  177424. + for (i = 0; i < vdi_save_lines; i++)
  177425. + memcpy(base_off + offset_addr + i*t->set.ostride,
  177426. + parent->vditmpbuf[1] + i*line_size,
  177427. + line_size);
  177428. +
  177429. + dmac_flush_range(base_off + offset_addr,
  177430. + base_off + offset_addr + vdi_save_lines*t->set.ostride);
  177431. + outer_flush_range(t->output.paddr + offset_addr,
  177432. + t->output.paddr + offset_addr + vdi_save_lines*t->set.ostride);
  177433. + parent->buf1filled = false;
  177434. + }
  177435. + }
  177436. + if (!pfn_valid(t->output.paddr >> PAGE_SHIFT))
  177437. + iounmap(base_off);
  177438. + mutex_unlock(lock);
  177439. +}
  177440. +
  177441. +static void do_task_release(struct ipu_task_entry *t, int fail)
  177442. +{
  177443. + int ret;
  177444. + struct ipu_soc *ipu = t->ipu;
  177445. +
  177446. + if (t->input.deinterlace.enable && !fail &&
  177447. + (t->task_no & (UP_STRIPE | DOWN_STRIPE)))
  177448. + vdi_split_process(ipu, t);
  177449. +
  177450. + ipu_free_irq(ipu, t->irq, t);
  177451. +
  177452. + if (t->vdoa_dma.vaddr)
  177453. + dma_free_coherent(t->dev,
  177454. + t->vdoa_dma.size,
  177455. + t->vdoa_dma.vaddr,
  177456. + t->vdoa_dma.paddr);
  177457. +
  177458. + if (only_ic(t->set.mode)) {
  177459. + ret = ipu_disable_channel(ipu, t->set.ic_chan, true);
  177460. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic",
  177461. + STATE_DISABLE_CHAN_FAIL, ret);
  177462. + if (deinterlace_3_field(t)) {
  177463. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_p_chan,
  177464. + true);
  177465. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic_p",
  177466. + STATE_DISABLE_CHAN_FAIL, ret);
  177467. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_n_chan,
  177468. + true);
  177469. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic_n",
  177470. + STATE_DISABLE_CHAN_FAIL, ret);
  177471. + }
  177472. + } else if (only_rot(t->set.mode)) {
  177473. + ret = ipu_disable_channel(ipu, t->set.rot_chan, true);
  177474. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_rot",
  177475. + STATE_DISABLE_CHAN_FAIL, ret);
  177476. + } else if (ic_and_rot(t->set.mode)) {
  177477. + ret = ipu_unlink_channels(ipu, t->set.ic_chan, t->set.rot_chan);
  177478. + CHECK_RETCODE_CONT(ret < 0, "ipu_unlink_ch",
  177479. + STATE_UNLINK_CHAN_FAIL, ret);
  177480. + ret = ipu_disable_channel(ipu, t->set.rot_chan, true);
  177481. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch ic_and_rot-rot",
  177482. + STATE_DISABLE_CHAN_FAIL, ret);
  177483. + ret = ipu_disable_channel(ipu, t->set.ic_chan, true);
  177484. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch ic_and_rot-ic",
  177485. + STATE_DISABLE_CHAN_FAIL, ret);
  177486. + if (deinterlace_3_field(t)) {
  177487. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_p_chan,
  177488. + true);
  177489. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch icrot-ic-p",
  177490. + STATE_DISABLE_CHAN_FAIL, ret);
  177491. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_n_chan,
  177492. + true);
  177493. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch icrot-ic-n",
  177494. + STATE_DISABLE_CHAN_FAIL, ret);
  177495. + }
  177496. + }
  177497. +
  177498. + if (only_ic(t->set.mode))
  177499. + uninit_ic(ipu, t);
  177500. + else if (only_rot(t->set.mode))
  177501. + uninit_rot(ipu, t);
  177502. + else if (ic_and_rot(t->set.mode)) {
  177503. + uninit_ic(ipu, t);
  177504. + uninit_rot(ipu, t);
  177505. + }
  177506. +
  177507. + t->state = STATE_OK;
  177508. + CHECK_PERF(&t->ts_rel);
  177509. + return;
  177510. +}
  177511. +
  177512. +static void do_task_vdoa_only(struct ipu_task_entry *t)
  177513. +{
  177514. + int ret;
  177515. +
  177516. + ret = init_tiled_ch_bufs(NULL, t);
  177517. + CHECK_RETCODE(ret < 0, "do_vdoa_only", STATE_ERR, out, ret);
  177518. + ret = vdoa_start(t->vdoa_handle, VDOA_DEF_TIMEOUT_MS);
  177519. + vdoa_stop(t->vdoa_handle);
  177520. + CHECK_RETCODE(ret < 0, "vdoa_wait4complete, do_vdoa_only",
  177521. + STATE_VDOA_IRQ_TIMEOUT, out, ret);
  177522. +
  177523. + t->state = STATE_OK;
  177524. +out:
  177525. + return;
  177526. +}
  177527. +
  177528. +static void do_task(struct ipu_task_entry *t)
  177529. +{
  177530. + int r_size;
  177531. + int irq;
  177532. + int ret;
  177533. + uint32_t busy;
  177534. + struct ipu_soc *ipu = t->ipu;
  177535. +
  177536. + CHECK_PERF(&t->ts_dotask);
  177537. +
  177538. + if (!ipu) {
  177539. + t->state = STATE_NO_IPU;
  177540. + return;
  177541. + }
  177542. +
  177543. + init_completion(&t->irq_comp);
  177544. + dev_dbg(ipu->dev, "[0x%p]Do task no:0x%x: id %d\n", (void *)t,
  177545. + t->task_no, t->task_id);
  177546. + dump_task_info(t);
  177547. +
  177548. + if (t->set.task & IC_PP) {
  177549. + t->set.ic_chan = MEM_PP_MEM;
  177550. + dev_dbg(ipu->dev, "[0x%p]ic channel MEM_PP_MEM\n", (void *)t);
  177551. + } else if (t->set.task & IC_VF) {
  177552. + t->set.ic_chan = MEM_PRP_VF_MEM;
  177553. + dev_dbg(ipu->dev, "[0x%p]ic channel MEM_PRP_VF_MEM\n", (void *)t);
  177554. + } else if (t->set.task & VDI_VF) {
  177555. + if (t->set.mode & VDOA_BAND_MODE) {
  177556. + t->set.ic_chan = MEM_VDI_MEM;
  177557. + if (deinterlace_3_field(t)) {
  177558. + t->set.vdi_ic_p_chan = MEM_VDI_MEM_P;
  177559. + t->set.vdi_ic_n_chan = MEM_VDI_MEM_N;
  177560. + }
  177561. + dev_dbg(ipu->dev, "[0x%p]ic ch MEM_VDI_MEM\n",
  177562. + (void *)t);
  177563. + } else {
  177564. + t->set.ic_chan = MEM_VDI_PRP_VF_MEM;
  177565. + if (deinterlace_3_field(t)) {
  177566. + t->set.vdi_ic_p_chan = MEM_VDI_PRP_VF_MEM_P;
  177567. + t->set.vdi_ic_n_chan = MEM_VDI_PRP_VF_MEM_N;
  177568. + }
  177569. + dev_dbg(ipu->dev,
  177570. + "[0x%p]ic ch MEM_VDI_PRP_VF_MEM\n", t);
  177571. + }
  177572. + }
  177573. +
  177574. + if (t->set.task & ROT_PP) {
  177575. + t->set.rot_chan = MEM_ROT_PP_MEM;
  177576. + dev_dbg(ipu->dev, "[0x%p]rot channel MEM_ROT_PP_MEM\n", (void *)t);
  177577. + } else if (t->set.task & ROT_VF) {
  177578. + t->set.rot_chan = MEM_ROT_VF_MEM;
  177579. + dev_dbg(ipu->dev, "[0x%p]rot channel MEM_ROT_VF_MEM\n", (void *)t);
  177580. + }
  177581. +
  177582. + if (t->task_id == IPU_TASK_ID_VF)
  177583. + busy = ic_vf_pp_is_busy(ipu, true);
  177584. + else if (t->task_id == IPU_TASK_ID_PP)
  177585. + busy = ic_vf_pp_is_busy(ipu, false);
  177586. + else {
  177587. + dev_err(ipu->dev, "ERR[no:0x%x]ipu task_id:%d invalid!\n",
  177588. + t->task_no, t->task_id);
  177589. + return;
  177590. + }
  177591. + if (busy) {
  177592. + dev_err(ipu->dev, "ERR[0x%p-no:0x%x]ipu task_id:%d busy!\n",
  177593. + (void *)t, t->task_no, t->task_id);
  177594. + t->state = STATE_IPU_BUSY;
  177595. + return;
  177596. + }
  177597. +
  177598. + irq = get_irq(t);
  177599. + if (irq < 0) {
  177600. + t->state = STATE_NO_IRQ;
  177601. + return;
  177602. + }
  177603. + t->irq = irq;
  177604. +
  177605. + /* channel setup */
  177606. + if (only_ic(t->set.mode)) {
  177607. + dev_dbg(t->dev, "[0x%p]only ic mode\n", (void *)t);
  177608. + ret = init_ic(ipu, t);
  177609. + CHECK_RETCODE(ret < 0, "init_ic only_ic",
  177610. + t->state, chan_setup, ret);
  177611. + } else if (only_rot(t->set.mode)) {
  177612. + dev_dbg(t->dev, "[0x%p]only rot mode\n", (void *)t);
  177613. + ret = init_rot(ipu, t);
  177614. + CHECK_RETCODE(ret < 0, "init_rot only_rot",
  177615. + t->state, chan_setup, ret);
  177616. + } else if (ic_and_rot(t->set.mode)) {
  177617. + int rot_idx = (t->task_id == IPU_TASK_ID_VF) ? 0 : 1;
  177618. +
  177619. + dev_dbg(t->dev, "[0x%p]ic + rot mode\n", (void *)t);
  177620. + t->set.r_fmt = t->output.format;
  177621. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  177622. + t->set.r_width = t->output.crop.h;
  177623. + t->set.r_height = t->output.crop.w;
  177624. + } else {
  177625. + t->set.r_width = t->output.crop.w;
  177626. + t->set.r_height = t->output.crop.h;
  177627. + }
  177628. + t->set.r_stride = t->set.r_width *
  177629. + bytes_per_pixel(t->set.r_fmt);
  177630. + r_size = PAGE_ALIGN(t->set.r_width * t->set.r_height
  177631. + * fmt_to_bpp(t->set.r_fmt)/8);
  177632. +
  177633. + if (r_size > ipu->rot_dma[rot_idx].size) {
  177634. + dev_dbg(t->dev, "[0x%p]realloc rot buffer\n", (void *)t);
  177635. +
  177636. + if (ipu->rot_dma[rot_idx].vaddr)
  177637. + dma_free_coherent(t->dev,
  177638. + ipu->rot_dma[rot_idx].size,
  177639. + ipu->rot_dma[rot_idx].vaddr,
  177640. + ipu->rot_dma[rot_idx].paddr);
  177641. +
  177642. + ipu->rot_dma[rot_idx].size = r_size;
  177643. + ipu->rot_dma[rot_idx].vaddr = dma_alloc_coherent(t->dev,
  177644. + r_size,
  177645. + &ipu->rot_dma[rot_idx].paddr,
  177646. + GFP_DMA | GFP_KERNEL);
  177647. + CHECK_RETCODE(ipu->rot_dma[rot_idx].vaddr == NULL,
  177648. + "ic_and_rot", STATE_SYS_NO_MEM,
  177649. + chan_setup, -ENOMEM);
  177650. + }
  177651. + t->set.r_paddr = ipu->rot_dma[rot_idx].paddr;
  177652. +
  177653. + dev_dbg(t->dev, "[0x%p]rotation:\n", (void *)t);
  177654. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->set.r_fmt);
  177655. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->set.r_width);
  177656. + dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->set.r_height);
  177657. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->set.r_paddr);
  177658. + dev_dbg(t->dev, "[0x%p]\trstride = %d\n", (void *)t, t->set.r_stride);
  177659. +
  177660. + ret = init_ic(ipu, t);
  177661. + CHECK_RETCODE(ret < 0, "init_ic ic_and_rot",
  177662. + t->state, chan_setup, ret);
  177663. + ret = init_rot(ipu, t);
  177664. + CHECK_RETCODE(ret < 0, "init_rot ic_and_rot",
  177665. + t->state, chan_setup, ret);
  177666. + ret = ipu_link_channels(ipu, t->set.ic_chan,
  177667. + t->set.rot_chan);
  177668. + CHECK_RETCODE(ret < 0, "ipu_link_ch ic_and_rot",
  177669. + STATE_LINK_CHAN_FAIL, chan_setup, ret);
  177670. + } else {
  177671. + dev_err(t->dev, "ERR [0x%p]do task: should not be here\n", t);
  177672. + t->state = STATE_ERR;
  177673. + return;
  177674. + }
  177675. +
  177676. + ret = ipu_request_irq(ipu, irq, task_irq_handler, 0, NULL, t);
  177677. + CHECK_RETCODE(ret < 0, "ipu_req_irq",
  177678. + STATE_IRQ_FAIL, chan_setup, ret);
  177679. +
  177680. + /* enable/start channel */
  177681. + if (only_ic(t->set.mode)) {
  177682. + ret = ipu_enable_channel(ipu, t->set.ic_chan);
  177683. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic",
  177684. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177685. + if (deinterlace_3_field(t)) {
  177686. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_p_chan);
  177687. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic_p",
  177688. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177689. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_n_chan);
  177690. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic_n",
  177691. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177692. + }
  177693. +
  177694. + ret = ipu_select_buffer(ipu, t->set.ic_chan, IPU_OUTPUT_BUFFER,
  177695. + 0);
  177696. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic",
  177697. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177698. + if (t->overlay_en) {
  177699. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177700. + IPU_GRAPH_IN_BUFFER, 0);
  177701. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_g",
  177702. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177703. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  177704. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177705. + IPU_ALPHA_IN_BUFFER, 0);
  177706. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_a",
  177707. + STATE_SEL_BUF_FAIL, chan_buf,
  177708. + ret);
  177709. + }
  177710. + }
  177711. + if (!(t->set.mode & VDOA_BAND_MODE)) {
  177712. + if (deinterlace_3_field(t))
  177713. + ipu_select_multi_vdi_buffer(ipu, 0);
  177714. + else {
  177715. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177716. + IPU_INPUT_BUFFER, 0);
  177717. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_i",
  177718. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177719. + }
  177720. + }
  177721. + } else if (only_rot(t->set.mode)) {
  177722. + ret = ipu_enable_channel(ipu, t->set.rot_chan);
  177723. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_rot",
  177724. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177725. + ret = ipu_select_buffer(ipu, t->set.rot_chan,
  177726. + IPU_OUTPUT_BUFFER, 0);
  177727. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_rot_o",
  177728. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177729. + ret = ipu_select_buffer(ipu, t->set.rot_chan,
  177730. + IPU_INPUT_BUFFER, 0);
  177731. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_rot_i",
  177732. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177733. + } else if (ic_and_rot(t->set.mode)) {
  177734. + ret = ipu_enable_channel(ipu, t->set.rot_chan);
  177735. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-rot",
  177736. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177737. + ret = ipu_enable_channel(ipu, t->set.ic_chan);
  177738. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-ic",
  177739. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177740. + if (deinterlace_3_field(t)) {
  177741. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_p_chan);
  177742. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-p",
  177743. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177744. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_n_chan);
  177745. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-n",
  177746. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177747. + }
  177748. +
  177749. + ret = ipu_select_buffer(ipu, t->set.rot_chan,
  177750. + IPU_OUTPUT_BUFFER, 0);
  177751. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-rot-o",
  177752. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177753. + if (t->overlay_en) {
  177754. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177755. + IPU_GRAPH_IN_BUFFER, 0);
  177756. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-g",
  177757. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177758. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  177759. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177760. + IPU_ALPHA_IN_BUFFER, 0);
  177761. + CHECK_RETCODE(ret < 0, "ipu_sel_buf icrot-ic-a",
  177762. + STATE_SEL_BUF_FAIL,
  177763. + chan_buf, ret);
  177764. + }
  177765. + }
  177766. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177767. + IPU_OUTPUT_BUFFER, 0);
  177768. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-o",
  177769. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177770. + if (deinterlace_3_field(t))
  177771. + ipu_select_multi_vdi_buffer(ipu, 0);
  177772. + else {
  177773. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177774. + IPU_INPUT_BUFFER, 0);
  177775. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-i",
  177776. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177777. + }
  177778. + }
  177779. +
  177780. + if (need_split(t))
  177781. + t->state = STATE_IN_PROGRESS;
  177782. +
  177783. + if (t->set.mode & VDOA_BAND_MODE) {
  177784. + ret = vdoa_start(t->vdoa_handle, VDOA_DEF_TIMEOUT_MS);
  177785. + CHECK_RETCODE(ret < 0, "vdoa_wait4complete, do_vdoa_band",
  177786. + STATE_VDOA_IRQ_TIMEOUT, chan_rel, ret);
  177787. + }
  177788. +
  177789. + CHECK_PERF(&t->ts_waitirq);
  177790. + ret = wait_for_completion_timeout(&t->irq_comp,
  177791. + msecs_to_jiffies(t->timeout - DEF_DELAY_MS));
  177792. + CHECK_PERF(&t->ts_wakeup);
  177793. + CHECK_RETCODE(ret == 0, "wait_for_comp_timeout",
  177794. + STATE_IRQ_TIMEOUT, chan_rel, ret);
  177795. + dev_dbg(t->dev, "[0x%p] no-0x%x ipu irq done!", t, t->task_no);
  177796. +
  177797. +chan_rel:
  177798. +chan_buf:
  177799. +chan_en:
  177800. +chan_setup:
  177801. + if (t->set.mode & VDOA_BAND_MODE)
  177802. + vdoa_stop(t->vdoa_handle);
  177803. + do_task_release(t, t->state >= STATE_ERR);
  177804. + return;
  177805. +}
  177806. +
  177807. +static void do_task_vdoa_vdi(struct ipu_task_entry *t)
  177808. +{
  177809. + int i;
  177810. + int ret;
  177811. + u32 stripe_width;
  177812. +
  177813. + /* FIXME: crop mode not support now */
  177814. + stripe_width = t->input.width >> 1;
  177815. + t->input.crop.pos.x = 0;
  177816. + t->input.crop.pos.y = 0;
  177817. + t->input.crop.w = stripe_width;
  177818. + t->input.crop.h = t->input.height;
  177819. + t->output.crop.w = stripe_width;
  177820. + t->output.crop.h = t->input.height;
  177821. +
  177822. + for (i = 0; i < 2; i++) {
  177823. + t->input.crop.pos.x = t->input.crop.pos.x + i * stripe_width;
  177824. + t->output.crop.pos.x = t->output.crop.pos.x + i * stripe_width;
  177825. + /* check input */
  177826. + ret = set_crop(&t->input.crop, t->input.width, t->input.height,
  177827. + t->input.format);
  177828. + if (ret < 0) {
  177829. + ret = STATE_ERR;
  177830. + goto done;
  177831. + } else
  177832. + update_offset(t->input.format,
  177833. + t->input.width, t->input.height,
  177834. + t->input.crop.pos.x,
  177835. + t->input.crop.pos.y,
  177836. + &t->set.i_off, &t->set.i_uoff,
  177837. + &t->set.i_voff, &t->set.istride);
  177838. + dev_dbg(t->dev, "i_off:0x%x, i_uoff:0x%x, istride:%d.\n",
  177839. + t->set.i_off, t->set.i_uoff, t->set.istride);
  177840. + /* check output */
  177841. + ret = set_crop(&t->output.crop, t->input.width,
  177842. + t->output.height, t->output.format);
  177843. + if (ret < 0) {
  177844. + ret = STATE_ERR;
  177845. + goto done;
  177846. + } else
  177847. + update_offset(t->output.format,
  177848. + t->output.width, t->output.height,
  177849. + t->output.crop.pos.x,
  177850. + t->output.crop.pos.y,
  177851. + &t->set.o_off, &t->set.o_uoff,
  177852. + &t->set.o_voff, &t->set.ostride);
  177853. +
  177854. + dev_dbg(t->dev, "o_off:0x%x, o_uoff:0x%x, ostride:%d.\n",
  177855. + t->set.o_off, t->set.o_uoff, t->set.ostride);
  177856. +
  177857. + do_task(t);
  177858. + }
  177859. +
  177860. + return;
  177861. +done:
  177862. + dev_err(t->dev, "ERR %s set_crop.\n", __func__);
  177863. + t->state = ret;
  177864. + return;
  177865. +}
  177866. +
  177867. +static void get_res_do_task(struct ipu_task_entry *t)
  177868. +{
  177869. + uint32_t found;
  177870. + uint32_t split_child;
  177871. + struct mutex *lock;
  177872. +
  177873. + found = get_vdoa_ipu_res(t);
  177874. + if (!found) {
  177875. + dev_err(t->dev, "ERR:[0x%p] no-0x%x can not get res\n",
  177876. + t, t->task_no);
  177877. + return;
  177878. + } else {
  177879. + if (t->set.task & VDOA_ONLY)
  177880. + do_task_vdoa_only(t);
  177881. + else if ((IPU_PIX_FMT_TILED_NV12F == t->input.format) &&
  177882. + (t->set.mode & VDOA_BAND_MODE) &&
  177883. + (t->input.crop.w > soc_max_vdi_in_width()))
  177884. + do_task_vdoa_vdi(t);
  177885. + else
  177886. + do_task(t);
  177887. + put_vdoa_ipu_res(t, 0);
  177888. + }
  177889. + if (t->state != STATE_OK) {
  177890. + dev_err(t->dev, "ERR:[0x%p] no-0x%x state: %s\n",
  177891. + t, t->task_no, state_msg[t->state].msg);
  177892. + }
  177893. +
  177894. + split_child = need_split(t) && t->parent;
  177895. + if (split_child) {
  177896. + lock = &t->parent->split_lock;
  177897. + mutex_lock(lock);
  177898. + t->split_done = 1;
  177899. + mutex_unlock(lock);
  177900. + wake_up(&t->parent->split_waitq);
  177901. + }
  177902. +
  177903. + return;
  177904. +}
  177905. +
  177906. +static void wait_split_task_complete(struct ipu_task_entry *parent,
  177907. + struct ipu_split_task *sp_task, uint32_t size)
  177908. +{
  177909. + struct ipu_task_entry *tsk = NULL;
  177910. + int ret = 0, rc;
  177911. + int j, idx = -1;
  177912. + unsigned long flags;
  177913. + struct mutex *lock = &parent->split_lock;
  177914. + int k, busy_vf, busy_pp;
  177915. + struct ipu_soc *ipu;
  177916. + DECLARE_PERF_VAR;
  177917. +
  177918. + for (j = 0; j < size; j++) {
  177919. + rc = wait_event_timeout(
  177920. + parent->split_waitq,
  177921. + sp_task_check_done(sp_task, parent, size, &idx),
  177922. + msecs_to_jiffies(parent->timeout - DEF_DELAY_MS));
  177923. + if (!rc) {
  177924. + dev_err(parent->dev,
  177925. + "ERR:[0x%p] no-0x%x, split_task timeout,j:%d,"
  177926. + "size:%d.\n",
  177927. + parent, parent->task_no, j, size);
  177928. + ret = -ETIMEDOUT;
  177929. + goto out;
  177930. + } else {
  177931. + if (idx < 0) {
  177932. + dev_err(parent->dev,
  177933. + "ERR:[0x%p] no-0x%x, invalid task idx:%d\n",
  177934. + parent, parent->task_no, idx);
  177935. + continue;
  177936. + }
  177937. + tsk = sp_task[idx].child_task;
  177938. + mutex_lock(lock);
  177939. + if (!tsk->split_done || !tsk->ipu)
  177940. + dev_err(tsk->dev,
  177941. + "ERR:no-0x%x,split not done:%d/null ipu:0x%p\n",
  177942. + tsk->task_no, tsk->split_done, tsk->ipu);
  177943. + tsk->split_done = 0;
  177944. + mutex_unlock(lock);
  177945. +
  177946. + dev_dbg(tsk->dev,
  177947. + "[0x%p] no-0x%x sp_tsk[%d] done,state:%d.\n",
  177948. + tsk, tsk->task_no, idx, tsk->state);
  177949. + #ifdef DBG_IPU_PERF
  177950. + CHECK_PERF(&tsk->ts_rel);
  177951. + PRINT_TASK_STATISTICS;
  177952. + #endif
  177953. + }
  177954. + }
  177955. +
  177956. +out:
  177957. + if (ret == -ETIMEDOUT) {
  177958. + /* debug */
  177959. + for (k = 0; k < max_ipu_no; k++) {
  177960. + ipu = ipu_get_soc(k);
  177961. + if (IS_ERR(ipu)) {
  177962. + dev_err(parent->dev, "no:0x%x, null ipu:%d\n",
  177963. + parent->task_no, k);
  177964. + } else {
  177965. + busy_vf = ic_vf_pp_is_busy(ipu, true);
  177966. + busy_pp = ic_vf_pp_is_busy(ipu, false);
  177967. + dev_err(parent->dev,
  177968. + "ERR:ipu[%d] busy_vf:%d, busy_pp:%d.\n",
  177969. + k, busy_vf, busy_pp);
  177970. + }
  177971. + }
  177972. + for (k = 0; k < size; k++) {
  177973. + tsk = sp_task[k].child_task;
  177974. + if (!tsk)
  177975. + continue;
  177976. + dev_err(parent->dev,
  177977. + "ERR: sp_task[%d][0x%p] no-0x%x done:%d,"
  177978. + "state:%s,on_list:%d, ipu:0x%p,timeout!\n",
  177979. + k, tsk, tsk->task_no, tsk->split_done,
  177980. + state_msg[tsk->state].msg, tsk->task_in_list,
  177981. + tsk->ipu);
  177982. + }
  177983. + }
  177984. +
  177985. + for (j = 0; j < size; j++) {
  177986. + tsk = sp_task[j].child_task;
  177987. + if (!tsk)
  177988. + continue;
  177989. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  177990. + if (tsk->task_in_list) {
  177991. + list_del(&tsk->node);
  177992. + tsk->task_in_list = 0;
  177993. + dev_dbg(tsk->dev,
  177994. + "[0x%p] no-0x%x,id:%d sp_tsk timeout list_del.\n",
  177995. + tsk, tsk->task_no, tsk->task_id);
  177996. + }
  177997. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  177998. + if (!tsk->ipu)
  177999. + continue;
  178000. + if (tsk->state != STATE_OK) {
  178001. + dev_err(tsk->dev,
  178002. + "ERR:[0x%p] no-0x%x,id:%d, sp_tsk state: %s\n",
  178003. + tsk, tsk->task_no, tsk->task_id,
  178004. + state_msg[tsk->state].msg);
  178005. + }
  178006. + kref_put(&tsk->refcount, task_mem_free);
  178007. + }
  178008. +
  178009. + kfree(parent->vditmpbuf[0]);
  178010. + kfree(parent->vditmpbuf[1]);
  178011. +
  178012. + if (ret < 0)
  178013. + parent->state = STATE_TIMEOUT;
  178014. + else
  178015. + parent->state = STATE_OK;
  178016. + return;
  178017. +}
  178018. +
  178019. +static inline int find_task(struct ipu_task_entry **t, int thread_id)
  178020. +{
  178021. + int found;
  178022. + unsigned long flags;
  178023. + struct ipu_task_entry *tsk;
  178024. + struct list_head *task_list = &ipu_task_list;
  178025. +
  178026. + *t = NULL;
  178027. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  178028. + found = !list_empty(task_list);
  178029. + if (found) {
  178030. + tsk = list_first_entry(task_list, struct ipu_task_entry, node);
  178031. + if (tsk->task_in_list) {
  178032. + list_del(&tsk->node);
  178033. + tsk->task_in_list = 0;
  178034. + *t = tsk;
  178035. + kref_get(&tsk->refcount);
  178036. + dev_dbg(tsk->dev,
  178037. + "thread_id:%d,[0x%p] task_no:0x%x,mode:0x%x list_del\n",
  178038. + thread_id, tsk, tsk->task_no, tsk->set.mode);
  178039. + } else
  178040. + dev_err(tsk->dev,
  178041. + "thread_id:%d,task_no:0x%x,mode:0x%x not on list_del\n",
  178042. + thread_id, tsk->task_no, tsk->set.mode);
  178043. + }
  178044. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  178045. +
  178046. + return found;
  178047. +}
  178048. +
  178049. +static int ipu_task_thread(void *argv)
  178050. +{
  178051. + struct ipu_task_entry *tsk;
  178052. + struct ipu_task_entry *sp_tsk0;
  178053. + struct ipu_split_task sp_task[4];
  178054. + /* priority lower than irq_thread */
  178055. + const struct sched_param param = {
  178056. + .sched_priority = MAX_USER_RT_PRIO/2 - 1,
  178057. + };
  178058. + int ret;
  178059. + int curr_thread_id;
  178060. + uint32_t size;
  178061. + unsigned long flags;
  178062. + unsigned int cpu;
  178063. + struct cpumask cpu_mask;
  178064. + struct ipu_thread_data *data = (struct ipu_thread_data *)argv;
  178065. +
  178066. + thread_id++;
  178067. + curr_thread_id = thread_id;
  178068. + sched_setscheduler(current, SCHED_FIFO, &param);
  178069. +
  178070. + if (!data->is_vdoa) {
  178071. + cpu = cpumask_first(cpu_online_mask);
  178072. + cpumask_set_cpu(cpu, &cpu_mask);
  178073. + ret = sched_setaffinity(data->ipu->thread[data->id]->pid,
  178074. + &cpu_mask);
  178075. + if (ret < 0) {
  178076. + pr_err("%s: sched_setaffinity fail:%d.\n", __func__, ret);
  178077. + }
  178078. + pr_debug("%s: sched_setaffinity cpu:%d.\n", __func__, cpu);
  178079. + }
  178080. +
  178081. + while (!kthread_should_stop()) {
  178082. + int split_fail = 0;
  178083. + int split_parent;
  178084. + int split_child;
  178085. +
  178086. + wait_event_interruptible(thread_waitq, find_task(&tsk, curr_thread_id));
  178087. +
  178088. + if (!tsk) {
  178089. + pr_err("thread:%d can not find task.\n",
  178090. + curr_thread_id);
  178091. + continue;
  178092. + }
  178093. +
  178094. + /* note: other threads run split child task */
  178095. + split_parent = need_split(tsk) && !tsk->parent;
  178096. + split_child = need_split(tsk) && tsk->parent;
  178097. + if (split_parent) {
  178098. + if ((tsk->set.split_mode == RL_SPLIT) ||
  178099. + (tsk->set.split_mode == UD_SPLIT))
  178100. + size = 2;
  178101. + else
  178102. + size = 4;
  178103. + ret = queue_split_task(tsk, sp_task, size);
  178104. + if (ret < 0) {
  178105. + split_fail = 1;
  178106. + } else {
  178107. + struct list_head *pos;
  178108. +
  178109. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  178110. +
  178111. + sp_tsk0 = list_first_entry(&tsk->split_list,
  178112. + struct ipu_task_entry, node);
  178113. + list_del(&sp_tsk0->node);
  178114. +
  178115. + list_for_each(pos, &tsk->split_list) {
  178116. + struct ipu_task_entry *tmp;
  178117. +
  178118. + tmp = list_entry(pos,
  178119. + struct ipu_task_entry, node);
  178120. + tmp->task_in_list = 1;
  178121. + dev_dbg(tmp->dev,
  178122. + "[0x%p] no-0x%x,id:%d sp_tsk "
  178123. + "add_to_list.\n", tmp,
  178124. + tmp->task_no, tmp->task_id);
  178125. + }
  178126. + /* add to global list */
  178127. + list_splice(&tsk->split_list, &ipu_task_list);
  178128. +
  178129. + spin_unlock_irqrestore(&ipu_task_list_lock,
  178130. + flags);
  178131. + /* let the parent thread do the first sp_task */
  178132. + /* FIXME: ensure the correct sequence for split
  178133. + 4size: 5/6->9/a*/
  178134. + if (!sp_tsk0)
  178135. + dev_err(tsk->dev,
  178136. + "ERR: no-0x%x,can not get split_tsk0\n",
  178137. + tsk->task_no);
  178138. + wake_up_interruptible(&thread_waitq);
  178139. + get_res_do_task(sp_tsk0);
  178140. + dev_dbg(sp_tsk0->dev,
  178141. + "thread:%d complete tsk no:0x%x.\n",
  178142. + curr_thread_id, sp_tsk0->task_no);
  178143. + ret = atomic_read(&req_cnt);
  178144. + if (ret > 0) {
  178145. + wake_up(&res_waitq);
  178146. + dev_dbg(sp_tsk0->dev,
  178147. + "sp_tsk0 sche thread:%d no:0x%x,"
  178148. + "req_cnt:%d\n", curr_thread_id,
  178149. + sp_tsk0->task_no, ret);
  178150. + /* For other threads to get_res */
  178151. + schedule();
  178152. + }
  178153. + }
  178154. + } else
  178155. + get_res_do_task(tsk);
  178156. +
  178157. + /* wait for all 4 sp_task finished here or timeout
  178158. + and then release all resources */
  178159. + if (split_parent && !split_fail)
  178160. + wait_split_task_complete(tsk, sp_task, size);
  178161. +
  178162. + if (!split_child) {
  178163. + atomic_inc(&tsk->done);
  178164. + wake_up(&tsk->task_waitq);
  178165. + }
  178166. +
  178167. + dev_dbg(tsk->dev, "thread:%d complete tsk no:0x%x-[0x%p].\n",
  178168. + curr_thread_id, tsk->task_no, tsk);
  178169. + ret = atomic_read(&req_cnt);
  178170. + if (ret > 0) {
  178171. + wake_up(&res_waitq);
  178172. + dev_dbg(tsk->dev, "sche thread:%d no:0x%x,req_cnt:%d\n",
  178173. + curr_thread_id, tsk->task_no, ret);
  178174. + /* note: give cpu to other threads to get_res */
  178175. + schedule();
  178176. + }
  178177. +
  178178. + kref_put(&tsk->refcount, task_mem_free);
  178179. + }
  178180. +
  178181. + pr_info("ERR %s exit.\n", __func__);
  178182. + return 0;
  178183. +}
  178184. +
  178185. +int ipu_check_task(struct ipu_task *task)
  178186. +{
  178187. + struct ipu_task_entry *tsk;
  178188. + int ret = 0;
  178189. +
  178190. + tsk = create_task_entry(task);
  178191. + if (IS_ERR(tsk))
  178192. + return PTR_ERR(tsk);
  178193. +
  178194. + ret = check_task(tsk);
  178195. +
  178196. + task->input = tsk->input;
  178197. + task->output = tsk->output;
  178198. + task->overlay = tsk->overlay;
  178199. + dump_task_info(tsk);
  178200. +
  178201. + kref_put(&tsk->refcount, task_mem_free);
  178202. + if (ret != 0)
  178203. + pr_debug("%s ret:%d.\n", __func__, ret);
  178204. + return ret;
  178205. +}
  178206. +EXPORT_SYMBOL_GPL(ipu_check_task);
  178207. +
  178208. +int ipu_queue_task(struct ipu_task *task)
  178209. +{
  178210. + struct ipu_task_entry *tsk;
  178211. + unsigned long flags;
  178212. + int ret;
  178213. + u32 tmp_task_no;
  178214. + DECLARE_PERF_VAR;
  178215. +
  178216. + tsk = create_task_entry(task);
  178217. + if (IS_ERR(tsk))
  178218. + return PTR_ERR(tsk);
  178219. +
  178220. + CHECK_PERF(&tsk->ts_queue);
  178221. + ret = prepare_task(tsk);
  178222. + if (ret < 0)
  178223. + goto done;
  178224. +
  178225. + if (need_split(tsk)) {
  178226. + CHECK_PERF(&tsk->ts_dotask);
  178227. + CHECK_PERF(&tsk->ts_waitirq);
  178228. + CHECK_PERF(&tsk->ts_inirq);
  178229. + CHECK_PERF(&tsk->ts_wakeup);
  178230. + }
  178231. +
  178232. + /* task_no last four bits for split task type*/
  178233. + tmp_task_no = atomic_inc_return(&frame_no);
  178234. + tsk->task_no = tmp_task_no << 4;
  178235. + init_waitqueue_head(&tsk->task_waitq);
  178236. +
  178237. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  178238. + list_add_tail(&tsk->node, &ipu_task_list);
  178239. + tsk->task_in_list = 1;
  178240. + dev_dbg(tsk->dev, "[0x%p,no-0x%x] list_add_tail\n", tsk, tsk->task_no);
  178241. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  178242. + wake_up_interruptible(&thread_waitq);
  178243. +
  178244. + ret = wait_event_timeout(tsk->task_waitq, atomic_read(&tsk->done),
  178245. + msecs_to_jiffies(tsk->timeout));
  178246. + if (0 == ret) {
  178247. + /* note: the timeout should larger than the internal timeout!*/
  178248. + ret = -ETIMEDOUT;
  178249. + dev_err(tsk->dev, "ERR: [0x%p] no-0x%x, timeout:%dms!\n",
  178250. + tsk, tsk->task_no, tsk->timeout);
  178251. + } else {
  178252. + if (STATE_OK != tsk->state) {
  178253. + dev_err(tsk->dev, "ERR: [0x%p] no-0x%x,state %d: %s\n",
  178254. + tsk, tsk->task_no, tsk->state,
  178255. + state_msg[tsk->state].msg);
  178256. + ret = -ECANCELED;
  178257. + } else
  178258. + ret = 0;
  178259. + }
  178260. +
  178261. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  178262. + if (tsk->task_in_list) {
  178263. + list_del(&tsk->node);
  178264. + tsk->task_in_list = 0;
  178265. + dev_dbg(tsk->dev, "[0x%p] no:0x%x list_del\n",
  178266. + tsk, tsk->task_no);
  178267. + }
  178268. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  178269. +
  178270. +#ifdef DBG_IPU_PERF
  178271. + CHECK_PERF(&tsk->ts_rel);
  178272. + PRINT_TASK_STATISTICS;
  178273. + if (ts_frame_avg == 0)
  178274. + ts_frame_avg = ts_frame.tv_nsec / NSEC_PER_USEC +
  178275. + ts_frame.tv_sec * USEC_PER_SEC;
  178276. + else
  178277. + ts_frame_avg = (ts_frame_avg + ts_frame.tv_nsec / NSEC_PER_USEC
  178278. + + ts_frame.tv_sec * USEC_PER_SEC)/2;
  178279. + if (timespec_compare(&ts_frame, &ts_frame_max) > 0)
  178280. + ts_frame_max = ts_frame;
  178281. +
  178282. + atomic_inc(&frame_cnt);
  178283. +
  178284. + if ((atomic_read(&frame_cnt) % 1000) == 0)
  178285. + pr_debug("ipu_dev: max frame time:%ldus, avg frame time:%dus,"
  178286. + "frame_cnt:%d\n", ts_frame_max.tv_nsec / NSEC_PER_USEC
  178287. + + ts_frame_max.tv_sec * USEC_PER_SEC,
  178288. + ts_frame_avg, atomic_read(&frame_cnt));
  178289. +#endif
  178290. +done:
  178291. + if (ret < 0)
  178292. + dev_err(tsk->dev, "ERR: no-0x%x,ipu_queue_task err:%d\n",
  178293. + tsk->task_no, ret);
  178294. +
  178295. + kref_put(&tsk->refcount, task_mem_free);
  178296. +
  178297. + return ret;
  178298. +}
  178299. +EXPORT_SYMBOL_GPL(ipu_queue_task);
  178300. +
  178301. +static int mxc_ipu_open(struct inode *inode, struct file *file)
  178302. +{
  178303. + file->private_data = (void *)atomic_inc_return(&file_index);
  178304. + return 0;
  178305. +}
  178306. +
  178307. +static long mxc_ipu_ioctl(struct file *file,
  178308. + unsigned int cmd, unsigned long arg)
  178309. +{
  178310. + int __user *argp = (void __user *)arg;
  178311. + int ret = 0;
  178312. +
  178313. + switch (cmd) {
  178314. + case IPU_CHECK_TASK:
  178315. + {
  178316. + struct ipu_task task;
  178317. +
  178318. + if (copy_from_user
  178319. + (&task, (struct ipu_task *) arg,
  178320. + sizeof(struct ipu_task)))
  178321. + return -EFAULT;
  178322. + ret = ipu_check_task(&task);
  178323. + if (copy_to_user((struct ipu_task *) arg,
  178324. + &task, sizeof(struct ipu_task)))
  178325. + return -EFAULT;
  178326. + break;
  178327. + }
  178328. + case IPU_QUEUE_TASK:
  178329. + {
  178330. + struct ipu_task task;
  178331. +
  178332. + if (copy_from_user
  178333. + (&task, (struct ipu_task *) arg,
  178334. + sizeof(struct ipu_task)))
  178335. + return -EFAULT;
  178336. + ret = ipu_queue_task(&task);
  178337. + break;
  178338. + }
  178339. + case IPU_ALLOC:
  178340. + {
  178341. + int size;
  178342. + struct ipu_alloc_list *mem;
  178343. +
  178344. + mem = kzalloc(sizeof(*mem), GFP_KERNEL);
  178345. + if (mem == NULL)
  178346. + return -ENOMEM;
  178347. +
  178348. + if (get_user(size, argp))
  178349. + return -EFAULT;
  178350. +
  178351. + mem->size = PAGE_ALIGN(size);
  178352. +
  178353. + mem->cpu_addr = dma_alloc_coherent(ipu_dev, size,
  178354. + &mem->phy_addr,
  178355. + GFP_DMA | GFP_KERNEL);
  178356. + if (mem->cpu_addr == NULL) {
  178357. + kfree(mem);
  178358. + return -ENOMEM;
  178359. + }
  178360. + mem->file_index = file->private_data;
  178361. + mutex_lock(&ipu_alloc_lock);
  178362. + list_add(&mem->list, &ipu_alloc_list);
  178363. + mutex_unlock(&ipu_alloc_lock);
  178364. +
  178365. + dev_dbg(ipu_dev, "allocated %d bytes @ 0x%08X\n",
  178366. + mem->size, mem->phy_addr);
  178367. +
  178368. + if (put_user(mem->phy_addr, argp))
  178369. + return -EFAULT;
  178370. +
  178371. + break;
  178372. + }
  178373. + case IPU_FREE:
  178374. + {
  178375. + unsigned long offset;
  178376. + struct ipu_alloc_list *mem;
  178377. +
  178378. + if (get_user(offset, argp))
  178379. + return -EFAULT;
  178380. +
  178381. + ret = -EINVAL;
  178382. + mutex_lock(&ipu_alloc_lock);
  178383. + list_for_each_entry(mem, &ipu_alloc_list, list) {
  178384. + if (mem->phy_addr == offset) {
  178385. + list_del(&mem->list);
  178386. + dma_free_coherent(ipu_dev,
  178387. + mem->size,
  178388. + mem->cpu_addr,
  178389. + mem->phy_addr);
  178390. + kfree(mem);
  178391. + ret = 0;
  178392. + break;
  178393. + }
  178394. + }
  178395. + mutex_unlock(&ipu_alloc_lock);
  178396. + if (0 == ret)
  178397. + dev_dbg(ipu_dev, "free %d bytes @ 0x%08X\n",
  178398. + mem->size, mem->phy_addr);
  178399. +
  178400. + break;
  178401. + }
  178402. + default:
  178403. + break;
  178404. + }
  178405. + return ret;
  178406. +}
  178407. +
  178408. +static int mxc_ipu_mmap(struct file *file, struct vm_area_struct *vma)
  178409. +{
  178410. + bool found = false;
  178411. + u32 len;
  178412. + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  178413. + struct ipu_alloc_list *mem;
  178414. +
  178415. + mutex_lock(&ipu_alloc_lock);
  178416. + list_for_each_entry(mem, &ipu_alloc_list, list) {
  178417. + if (offset == mem->phy_addr) {
  178418. + found = true;
  178419. + len = mem->size;
  178420. + break;
  178421. + }
  178422. + }
  178423. + mutex_unlock(&ipu_alloc_lock);
  178424. + if (!found)
  178425. + return -EINVAL;
  178426. +
  178427. + if (vma->vm_end - vma->vm_start > len)
  178428. + return -EINVAL;
  178429. +
  178430. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  178431. +
  178432. + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  178433. + vma->vm_end - vma->vm_start,
  178434. + vma->vm_page_prot)) {
  178435. + printk(KERN_ERR
  178436. + "mmap failed!\n");
  178437. + return -ENOBUFS;
  178438. + }
  178439. + return 0;
  178440. +}
  178441. +
  178442. +static int mxc_ipu_release(struct inode *inode, struct file *file)
  178443. +{
  178444. + struct ipu_alloc_list *mem;
  178445. + struct ipu_alloc_list *n;
  178446. +
  178447. + mutex_lock(&ipu_alloc_lock);
  178448. + list_for_each_entry_safe(mem, n, &ipu_alloc_list, list) {
  178449. + if ((mem->cpu_addr != 0) &&
  178450. + (file->private_data == mem->file_index)) {
  178451. + list_del(&mem->list);
  178452. + dma_free_coherent(ipu_dev,
  178453. + mem->size,
  178454. + mem->cpu_addr,
  178455. + mem->phy_addr);
  178456. + dev_dbg(ipu_dev, "rel-free %d bytes @ 0x%08X\n",
  178457. + mem->size, mem->phy_addr);
  178458. + kfree(mem);
  178459. + }
  178460. + }
  178461. + mutex_unlock(&ipu_alloc_lock);
  178462. + atomic_dec(&file_index);
  178463. +
  178464. + return 0;
  178465. +}
  178466. +
  178467. +static struct file_operations mxc_ipu_fops = {
  178468. + .owner = THIS_MODULE,
  178469. + .open = mxc_ipu_open,
  178470. + .mmap = mxc_ipu_mmap,
  178471. + .release = mxc_ipu_release,
  178472. + .unlocked_ioctl = mxc_ipu_ioctl,
  178473. +};
  178474. +
  178475. +int register_ipu_device(struct ipu_soc *ipu, int id)
  178476. +{
  178477. + int ret = 0;
  178478. + static int idx;
  178479. + static struct ipu_thread_data thread_data[5];
  178480. +
  178481. + if (!major) {
  178482. + major = register_chrdev(0, "mxc_ipu", &mxc_ipu_fops);
  178483. + if (major < 0) {
  178484. + printk(KERN_ERR "Unable to register mxc_ipu as a char device\n");
  178485. + ret = major;
  178486. + goto register_cdev_fail;
  178487. + }
  178488. +
  178489. + ipu_class = class_create(THIS_MODULE, "mxc_ipu");
  178490. + if (IS_ERR(ipu_class)) {
  178491. + ret = PTR_ERR(ipu_class);
  178492. + goto ipu_class_fail;
  178493. + }
  178494. +
  178495. + ipu_dev = device_create(ipu_class, NULL, MKDEV(major, 0),
  178496. + NULL, "mxc_ipu");
  178497. + if (IS_ERR(ipu_dev)) {
  178498. + ret = PTR_ERR(ipu_dev);
  178499. + goto dev_create_fail;
  178500. + }
  178501. + ipu_dev->dma_mask = kmalloc(sizeof(*ipu_dev->dma_mask), GFP_KERNEL);
  178502. + *ipu_dev->dma_mask = DMA_BIT_MASK(32);
  178503. + ipu_dev->coherent_dma_mask = DMA_BIT_MASK(32);
  178504. +
  178505. + mutex_init(&ipu_ch_tbl.lock);
  178506. + }
  178507. + max_ipu_no = ++id;
  178508. + ipu->rot_dma[0].size = 0;
  178509. + ipu->rot_dma[1].size = 0;
  178510. +
  178511. + thread_data[idx].ipu = ipu;
  178512. + thread_data[idx].id = 0;
  178513. + thread_data[idx].is_vdoa = 0;
  178514. + ipu->thread[0] = kthread_run(ipu_task_thread, &thread_data[idx++],
  178515. + "ipu%d_task", id);
  178516. + if (IS_ERR(ipu->thread[0])) {
  178517. + ret = PTR_ERR(ipu->thread[0]);
  178518. + goto kthread0_fail;
  178519. + }
  178520. +
  178521. + thread_data[idx].ipu = ipu;
  178522. + thread_data[idx].id = 1;
  178523. + thread_data[idx].is_vdoa = 0;
  178524. + ipu->thread[1] = kthread_run(ipu_task_thread, &thread_data[idx++],
  178525. + "ipu%d_task", id);
  178526. + if (IS_ERR(ipu->thread[1])) {
  178527. + ret = PTR_ERR(ipu->thread[1]);
  178528. + goto kthread1_fail;
  178529. + }
  178530. +
  178531. +
  178532. + return ret;
  178533. +
  178534. +kthread1_fail:
  178535. + kthread_stop(ipu->thread[0]);
  178536. +kthread0_fail:
  178537. + if (id == 0)
  178538. + device_destroy(ipu_class, MKDEV(major, 0));
  178539. +dev_create_fail:
  178540. + if (id == 0) {
  178541. + class_destroy(ipu_class);
  178542. + }
  178543. +ipu_class_fail:
  178544. + if (id == 0)
  178545. + unregister_chrdev(major, "mxc_ipu");
  178546. +register_cdev_fail:
  178547. + return ret;
  178548. +}
  178549. +
  178550. +void unregister_ipu_device(struct ipu_soc *ipu, int id)
  178551. +{
  178552. + int i;
  178553. +
  178554. + kthread_stop(ipu->thread[0]);
  178555. + kthread_stop(ipu->thread[1]);
  178556. + for (i = 0; i < 2; i++) {
  178557. + if (ipu->rot_dma[i].vaddr)
  178558. + dma_free_coherent(ipu_dev,
  178559. + ipu->rot_dma[i].size,
  178560. + ipu->rot_dma[i].vaddr,
  178561. + ipu->rot_dma[i].paddr);
  178562. + }
  178563. +
  178564. + if (major) {
  178565. + device_destroy(ipu_class, MKDEV(major, 0));
  178566. + class_destroy(ipu_class);
  178567. + unregister_chrdev(major, "mxc_ipu");
  178568. + major = 0;
  178569. + }
  178570. +}
  178571. diff -Nur linux-3.14.15/drivers/mxc/ipu3/ipu_disp.c linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_disp.c
  178572. --- linux-3.14.15/drivers/mxc/ipu3/ipu_disp.c 1970-01-01 01:00:00.000000000 +0100
  178573. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_disp.c 2014-08-20 19:31:46.140869056 +0200
  178574. @@ -0,0 +1,1962 @@
  178575. +/*
  178576. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  178577. + */
  178578. +
  178579. +/*
  178580. + * The code contained herein is licensed under the GNU General Public
  178581. + * License. You may obtain a copy of the GNU General Public License
  178582. + * Version 2 or later at the following locations:
  178583. + *
  178584. + * http://www.opensource.org/licenses/gpl-license.html
  178585. + * http://www.gnu.org/copyleft/gpl.html
  178586. + */
  178587. +
  178588. +/*!
  178589. + * @file ipu_disp.c
  178590. + *
  178591. + * @brief IPU display submodule API functions
  178592. + *
  178593. + * @ingroup IPU
  178594. + */
  178595. +
  178596. +#include <linux/clk.h>
  178597. +#include <linux/clk-provider.h>
  178598. +#include <linux/delay.h>
  178599. +#include <linux/err.h>
  178600. +#include <linux/errno.h>
  178601. +#include <linux/io.h>
  178602. +#include <linux/ipu-v3.h>
  178603. +#include <linux/module.h>
  178604. +#include <linux/spinlock.h>
  178605. +#include <linux/types.h>
  178606. +
  178607. +#include <asm/atomic.h>
  178608. +
  178609. +#include "ipu_param_mem.h"
  178610. +#include "ipu_regs.h"
  178611. +
  178612. +struct dp_csc_param_t {
  178613. + int mode;
  178614. + void *coeff;
  178615. +};
  178616. +
  178617. +#define SYNC_WAVE 0
  178618. +#define NULL_WAVE (-1)
  178619. +#define ASYNC_SER_WAVE 6
  178620. +
  178621. +/* DC display ID assignments */
  178622. +#define DC_DISP_ID_SYNC(di) (di)
  178623. +#define DC_DISP_ID_SERIAL 2
  178624. +#define DC_DISP_ID_ASYNC 3
  178625. +
  178626. +int dmfc_type_setup;
  178627. +
  178628. +void _ipu_dmfc_init(struct ipu_soc *ipu, int dmfc_type, int first)
  178629. +{
  178630. + u32 dmfc_wr_chan, dmfc_dp_chan;
  178631. +
  178632. + if (first) {
  178633. + if (dmfc_type_setup > dmfc_type)
  178634. + dmfc_type = dmfc_type_setup;
  178635. + else
  178636. + dmfc_type_setup = dmfc_type;
  178637. +
  178638. + /* disable DMFC-IC channel*/
  178639. + ipu_dmfc_write(ipu, 0x2, DMFC_IC_CTRL);
  178640. + } else if (dmfc_type_setup >= DMFC_HIGH_RESOLUTION_DC) {
  178641. + dev_dbg(ipu->dev, "DMFC high resolution has set, will not change\n");
  178642. + return;
  178643. + } else
  178644. + dmfc_type_setup = dmfc_type;
  178645. +
  178646. + if (dmfc_type == DMFC_HIGH_RESOLUTION_DC) {
  178647. + /* 1 - segment 0~3;
  178648. + * 5B - segement 4, 5;
  178649. + * 5F - segement 6, 7;
  178650. + * 1C, 2C and 6B, 6F unused;
  178651. + */
  178652. + dev_info(ipu->dev, "IPU DMFC DC HIGH RESOLUTION: 1(0~3), 5B(4,5), 5F(6,7)\n");
  178653. + dmfc_wr_chan = 0x00000088;
  178654. + dmfc_dp_chan = 0x00009694;
  178655. + ipu->dmfc_size_28 = 256*4;
  178656. + ipu->dmfc_size_29 = 0;
  178657. + ipu->dmfc_size_24 = 0;
  178658. + ipu->dmfc_size_27 = 128*4;
  178659. + ipu->dmfc_size_23 = 128*4;
  178660. + } else if (dmfc_type == DMFC_HIGH_RESOLUTION_DP) {
  178661. + /* 1 - segment 0, 1;
  178662. + * 5B - segement 2~5;
  178663. + * 5F - segement 6,7;
  178664. + * 1C, 2C and 6B, 6F unused;
  178665. + */
  178666. + dev_info(ipu->dev, "IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)\n");
  178667. + dmfc_wr_chan = 0x00000090;
  178668. + dmfc_dp_chan = 0x0000968a;
  178669. + ipu->dmfc_size_28 = 128*4;
  178670. + ipu->dmfc_size_29 = 0;
  178671. + ipu->dmfc_size_24 = 0;
  178672. + ipu->dmfc_size_27 = 128*4;
  178673. + ipu->dmfc_size_23 = 256*4;
  178674. + } else if (dmfc_type == DMFC_HIGH_RESOLUTION_ONLY_DP) {
  178675. + /* 5B - segement 0~3;
  178676. + * 5F - segement 4~7;
  178677. + * 1, 1C, 2C and 6B, 6F unused;
  178678. + */
  178679. + dev_info(ipu->dev, "IPU DMFC ONLY-DP HIGH RESOLUTION: 5B(0~3), 5F(4~7)\n");
  178680. + dmfc_wr_chan = 0x00000000;
  178681. + dmfc_dp_chan = 0x00008c88;
  178682. + ipu->dmfc_size_28 = 0;
  178683. + ipu->dmfc_size_29 = 0;
  178684. + ipu->dmfc_size_24 = 0;
  178685. + ipu->dmfc_size_27 = 256*4;
  178686. + ipu->dmfc_size_23 = 256*4;
  178687. + } else {
  178688. + /* 1 - segment 0, 1;
  178689. + * 5B - segement 4, 5;
  178690. + * 5F - segement 6, 7;
  178691. + * 1C, 2C and 6B, 6F unused;
  178692. + */
  178693. + dev_info(ipu->dev, "IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)\n");
  178694. + dmfc_wr_chan = 0x00000090;
  178695. + dmfc_dp_chan = 0x00009694;
  178696. + ipu->dmfc_size_28 = 128*4;
  178697. + ipu->dmfc_size_29 = 0;
  178698. + ipu->dmfc_size_24 = 0;
  178699. + ipu->dmfc_size_27 = 128*4;
  178700. + ipu->dmfc_size_23 = 128*4;
  178701. + }
  178702. + ipu_dmfc_write(ipu, dmfc_wr_chan, DMFC_WR_CHAN);
  178703. + ipu_dmfc_write(ipu, 0x202020F6, DMFC_WR_CHAN_DEF);
  178704. + ipu_dmfc_write(ipu, dmfc_dp_chan, DMFC_DP_CHAN);
  178705. + /* Enable chan 5 watermark set at 5 bursts and clear at 7 bursts */
  178706. + ipu_dmfc_write(ipu, 0x2020F6F6, DMFC_DP_CHAN_DEF);
  178707. +}
  178708. +
  178709. +static int __init dmfc_setup(char *options)
  178710. +{
  178711. + get_option(&options, &dmfc_type_setup);
  178712. + if (dmfc_type_setup > DMFC_HIGH_RESOLUTION_ONLY_DP)
  178713. + dmfc_type_setup = DMFC_HIGH_RESOLUTION_ONLY_DP;
  178714. + return 1;
  178715. +}
  178716. +__setup("dmfc=", dmfc_setup);
  178717. +
  178718. +void _ipu_dmfc_set_wait4eot(struct ipu_soc *ipu, int dma_chan, int width)
  178719. +{
  178720. + u32 dmfc_gen1 = ipu_dmfc_read(ipu, DMFC_GENERAL1);
  178721. +
  178722. + if (width >= HIGH_RESOLUTION_WIDTH) {
  178723. + if (dma_chan == 23)
  178724. + _ipu_dmfc_init(ipu, DMFC_HIGH_RESOLUTION_DP, 0);
  178725. + else if (dma_chan == 28)
  178726. + _ipu_dmfc_init(ipu, DMFC_HIGH_RESOLUTION_DC, 0);
  178727. + }
  178728. +
  178729. + if (dma_chan == 23) { /*5B*/
  178730. + if (ipu->dmfc_size_23/width > 3)
  178731. + dmfc_gen1 |= 1UL << 20;
  178732. + else
  178733. + dmfc_gen1 &= ~(1UL << 20);
  178734. + } else if (dma_chan == 24) { /*6B*/
  178735. + if (ipu->dmfc_size_24/width > 1)
  178736. + dmfc_gen1 |= 1UL << 22;
  178737. + else
  178738. + dmfc_gen1 &= ~(1UL << 22);
  178739. + } else if (dma_chan == 27) { /*5F*/
  178740. + if (ipu->dmfc_size_27/width > 2)
  178741. + dmfc_gen1 |= 1UL << 21;
  178742. + else
  178743. + dmfc_gen1 &= ~(1UL << 21);
  178744. + } else if (dma_chan == 28) { /*1*/
  178745. + if (ipu->dmfc_size_28/width > 2)
  178746. + dmfc_gen1 |= 1UL << 16;
  178747. + else
  178748. + dmfc_gen1 &= ~(1UL << 16);
  178749. + } else if (dma_chan == 29) { /*6F*/
  178750. + if (ipu->dmfc_size_29/width > 1)
  178751. + dmfc_gen1 |= 1UL << 23;
  178752. + else
  178753. + dmfc_gen1 &= ~(1UL << 23);
  178754. + }
  178755. +
  178756. + ipu_dmfc_write(ipu, dmfc_gen1, DMFC_GENERAL1);
  178757. +}
  178758. +
  178759. +void _ipu_dmfc_set_burst_size(struct ipu_soc *ipu, int dma_chan, int burst_size)
  178760. +{
  178761. + u32 dmfc_wr_chan = ipu_dmfc_read(ipu, DMFC_WR_CHAN);
  178762. + u32 dmfc_dp_chan = ipu_dmfc_read(ipu, DMFC_DP_CHAN);
  178763. + int dmfc_bs = 0;
  178764. +
  178765. + switch (burst_size) {
  178766. + case 64:
  178767. + dmfc_bs = 0x40;
  178768. + break;
  178769. + case 32:
  178770. + case 20:
  178771. + dmfc_bs = 0x80;
  178772. + break;
  178773. + case 16:
  178774. + dmfc_bs = 0xc0;
  178775. + break;
  178776. + default:
  178777. + dev_err(ipu->dev, "Unsupported burst size %d\n",
  178778. + burst_size);
  178779. + return;
  178780. + }
  178781. +
  178782. + if (dma_chan == 23) { /*5B*/
  178783. + dmfc_dp_chan &= ~(0xc0);
  178784. + dmfc_dp_chan |= dmfc_bs;
  178785. + } else if (dma_chan == 27) { /*5F*/
  178786. + dmfc_dp_chan &= ~(0xc000);
  178787. + dmfc_dp_chan |= (dmfc_bs << 8);
  178788. + } else if (dma_chan == 28) { /*1*/
  178789. + dmfc_wr_chan &= ~(0xc0);
  178790. + dmfc_wr_chan |= dmfc_bs;
  178791. + }
  178792. +
  178793. + ipu_dmfc_write(ipu, dmfc_wr_chan, DMFC_WR_CHAN);
  178794. + ipu_dmfc_write(ipu, dmfc_dp_chan, DMFC_DP_CHAN);
  178795. +}
  178796. +
  178797. +static void _ipu_di_data_wave_config(struct ipu_soc *ipu,
  178798. + int di, int wave_gen,
  178799. + int access_size, int component_size)
  178800. +{
  178801. + u32 reg;
  178802. + reg = (access_size << DI_DW_GEN_ACCESS_SIZE_OFFSET) |
  178803. + (component_size << DI_DW_GEN_COMPONENT_SIZE_OFFSET);
  178804. + ipu_di_write(ipu, di, reg, DI_DW_GEN(wave_gen));
  178805. +}
  178806. +
  178807. +static void _ipu_di_data_pin_config(struct ipu_soc *ipu,
  178808. + int di, int wave_gen, int di_pin, int set,
  178809. + int up, int down)
  178810. +{
  178811. + u32 reg;
  178812. +
  178813. + reg = ipu_di_read(ipu, di, DI_DW_GEN(wave_gen));
  178814. + reg &= ~(0x3 << (di_pin * 2));
  178815. + reg |= set << (di_pin * 2);
  178816. + ipu_di_write(ipu, di, reg, DI_DW_GEN(wave_gen));
  178817. +
  178818. + ipu_di_write(ipu, di, (down << 16) | up, DI_DW_SET(wave_gen, set));
  178819. +}
  178820. +
  178821. +static void _ipu_di_sync_config(struct ipu_soc *ipu,
  178822. + int di, int wave_gen,
  178823. + int run_count, int run_src,
  178824. + int offset_count, int offset_src,
  178825. + int repeat_count, int cnt_clr_src,
  178826. + int cnt_polarity_gen_en,
  178827. + int cnt_polarity_clr_src,
  178828. + int cnt_polarity_trigger_src,
  178829. + int cnt_up, int cnt_down)
  178830. +{
  178831. + u32 reg;
  178832. +
  178833. + if ((run_count >= 0x1000) || (offset_count >= 0x1000) || (repeat_count >= 0x1000) ||
  178834. + (cnt_up >= 0x400) || (cnt_down >= 0x400)) {
  178835. + dev_err(ipu->dev, "DI%d counters out of range.\n", di);
  178836. + return;
  178837. + }
  178838. +
  178839. + reg = (run_count << 19) | (++run_src << 16) |
  178840. + (offset_count << 3) | ++offset_src;
  178841. + ipu_di_write(ipu, di, reg, DI_SW_GEN0(wave_gen));
  178842. + reg = (cnt_polarity_gen_en << 29) | (++cnt_clr_src << 25) |
  178843. + (++cnt_polarity_trigger_src << 12) | (++cnt_polarity_clr_src << 9);
  178844. + reg |= (cnt_down << 16) | cnt_up;
  178845. + if (repeat_count == 0) {
  178846. + /* Enable auto reload */
  178847. + reg |= 0x10000000;
  178848. + }
  178849. + ipu_di_write(ipu, di, reg, DI_SW_GEN1(wave_gen));
  178850. + reg = ipu_di_read(ipu, di, DI_STP_REP(wave_gen));
  178851. + reg &= ~(0xFFFF << (16 * ((wave_gen - 1) & 0x1)));
  178852. + reg |= repeat_count << (16 * ((wave_gen - 1) & 0x1));
  178853. + ipu_di_write(ipu, di, reg, DI_STP_REP(wave_gen));
  178854. +}
  178855. +
  178856. +static void _ipu_dc_map_link(struct ipu_soc *ipu,
  178857. + int current_map,
  178858. + int base_map_0, int buf_num_0,
  178859. + int base_map_1, int buf_num_1,
  178860. + int base_map_2, int buf_num_2)
  178861. +{
  178862. + int ptr_0 = base_map_0 * 3 + buf_num_0;
  178863. + int ptr_1 = base_map_1 * 3 + buf_num_1;
  178864. + int ptr_2 = base_map_2 * 3 + buf_num_2;
  178865. + int ptr;
  178866. + u32 reg;
  178867. + ptr = (ptr_2 << 10) + (ptr_1 << 5) + ptr_0;
  178868. +
  178869. + reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(current_map));
  178870. + reg &= ~(0x1F << ((16 * (current_map & 0x1))));
  178871. + reg |= ptr << ((16 * (current_map & 0x1)));
  178872. + ipu_dc_write(ipu, reg, DC_MAP_CONF_PTR(current_map));
  178873. +}
  178874. +
  178875. +static void _ipu_dc_map_config(struct ipu_soc *ipu,
  178876. + int map, int byte_num, int offset, int mask)
  178877. +{
  178878. + int ptr = map * 3 + byte_num;
  178879. + u32 reg;
  178880. +
  178881. + reg = ipu_dc_read(ipu, DC_MAP_CONF_VAL(ptr));
  178882. + reg &= ~(0xFFFF << (16 * (ptr & 0x1)));
  178883. + reg |= ((offset << 8) | mask) << (16 * (ptr & 0x1));
  178884. + ipu_dc_write(ipu, reg, DC_MAP_CONF_VAL(ptr));
  178885. +
  178886. + reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(map));
  178887. + reg &= ~(0x1F << ((16 * (map & 0x1)) + (5 * byte_num)));
  178888. + reg |= ptr << ((16 * (map & 0x1)) + (5 * byte_num));
  178889. + ipu_dc_write(ipu, reg, DC_MAP_CONF_PTR(map));
  178890. +}
  178891. +
  178892. +static void _ipu_dc_map_clear(struct ipu_soc *ipu, int map)
  178893. +{
  178894. + u32 reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(map));
  178895. + ipu_dc_write(ipu, reg & ~(0xFFFF << (16 * (map & 0x1))),
  178896. + DC_MAP_CONF_PTR(map));
  178897. +}
  178898. +
  178899. +static void _ipu_dc_write_tmpl(struct ipu_soc *ipu,
  178900. + int word, u32 opcode, u32 operand, int map,
  178901. + int wave, int glue, int sync, int stop)
  178902. +{
  178903. + u32 reg;
  178904. +
  178905. + if (opcode == WRG) {
  178906. + reg = sync;
  178907. + reg |= (glue << 4);
  178908. + reg |= (++wave << 11);
  178909. + reg |= ((operand & 0x1FFFF) << 15);
  178910. + ipu_dc_tmpl_write(ipu, reg, word * 8);
  178911. +
  178912. + reg = (operand >> 17);
  178913. + reg |= opcode << 7;
  178914. + reg |= (stop << 9);
  178915. + ipu_dc_tmpl_write(ipu, reg, word * 8 + 4);
  178916. + } else {
  178917. + reg = sync;
  178918. + reg |= (glue << 4);
  178919. + reg |= (++wave << 11);
  178920. + reg |= (++map << 15);
  178921. + reg |= (operand << 20) & 0xFFF00000;
  178922. + ipu_dc_tmpl_write(ipu, reg, word * 8);
  178923. +
  178924. + reg = (operand >> 12);
  178925. + reg |= opcode << 4;
  178926. + reg |= (stop << 9);
  178927. + ipu_dc_tmpl_write(ipu, reg, word * 8 + 4);
  178928. + }
  178929. +}
  178930. +
  178931. +static void _ipu_dc_link_event(struct ipu_soc *ipu,
  178932. + int chan, int event, int addr, int priority)
  178933. +{
  178934. + u32 reg;
  178935. + u32 address_shift;
  178936. + if (event < DC_EVEN_UGDE0) {
  178937. + reg = ipu_dc_read(ipu, DC_RL_CH(chan, event));
  178938. + reg &= ~(0xFFFF << (16 * (event & 0x1)));
  178939. + reg |= ((addr << 8) | priority) << (16 * (event & 0x1));
  178940. + ipu_dc_write(ipu, reg, DC_RL_CH(chan, event));
  178941. + } else {
  178942. + reg = ipu_dc_read(ipu, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
  178943. + if ((event - DC_EVEN_UGDE0) & 0x1) {
  178944. + reg &= ~(0x2FF << 16);
  178945. + reg |= (addr << 16);
  178946. + reg |= priority ? (2 << 24) : 0x0;
  178947. + } else {
  178948. + reg &= ~0xFC00FFFF;
  178949. + if (priority)
  178950. + chan = (chan >> 1) +
  178951. + ((((chan & 0x1) + ((chan & 0x2) >> 1))) | (chan >> 3));
  178952. + else
  178953. + chan = 0x7;
  178954. + address_shift = ((event - DC_EVEN_UGDE0) >> 1) ? 7 : 8;
  178955. + reg |= (addr << address_shift) | (priority << 3) | chan;
  178956. + }
  178957. + ipu_dc_write(ipu, reg, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
  178958. + }
  178959. +}
  178960. +
  178961. +/* Y = R * 1.200 + G * 2.343 + B * .453 + 0.250;
  178962. + U = R * -.672 + G * -1.328 + B * 2.000 + 512.250.;
  178963. + V = R * 2.000 + G * -1.672 + B * -.328 + 512.250.;*/
  178964. +static const int rgb2ycbcr_coeff[5][3] = {
  178965. + {0x4D, 0x96, 0x1D},
  178966. + {-0x2B, -0x55, 0x80},
  178967. + {0x80, -0x6B, -0x15},
  178968. + {0x0000, 0x0200, 0x0200}, /* B0, B1, B2 */
  178969. + {0x2, 0x2, 0x2}, /* S0, S1, S2 */
  178970. +};
  178971. +
  178972. +/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128));
  178973. + G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128));
  178974. + B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */
  178975. +static const int ycbcr2rgb_coeff[5][3] = {
  178976. + {0x095, 0x000, 0x0CC},
  178977. + {0x095, 0x3CE, 0x398},
  178978. + {0x095, 0x0FF, 0x000},
  178979. + {0x3E42, 0x010A, 0x3DD6}, /*B0,B1,B2 */
  178980. + {0x1, 0x1, 0x1}, /*S0,S1,S2 */
  178981. +};
  178982. +
  178983. +#define mask_a(a) ((u32)(a) & 0x3FF)
  178984. +#define mask_b(b) ((u32)(b) & 0x3FFF)
  178985. +
  178986. +/* Pls keep S0, S1 and S2 as 0x2 by using this convertion */
  178987. +static int _rgb_to_yuv(int n, int red, int green, int blue)
  178988. +{
  178989. + int c;
  178990. + c = red * rgb2ycbcr_coeff[n][0];
  178991. + c += green * rgb2ycbcr_coeff[n][1];
  178992. + c += blue * rgb2ycbcr_coeff[n][2];
  178993. + c /= 16;
  178994. + c += rgb2ycbcr_coeff[3][n] * 4;
  178995. + c += 8;
  178996. + c /= 16;
  178997. + if (c < 0)
  178998. + c = 0;
  178999. + if (c > 255)
  179000. + c = 255;
  179001. + return c;
  179002. +}
  179003. +
  179004. +/*
  179005. + * Row is for BG: RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE
  179006. + * Column is for FG: RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE
  179007. + */
  179008. +static struct dp_csc_param_t dp_csc_array[CSC_NUM][CSC_NUM] = {
  179009. +{{DP_COM_CONF_CSC_DEF_BOTH, &rgb2ycbcr_coeff}, {0, 0}, {0, 0}, {DP_COM_CONF_CSC_DEF_BG, &rgb2ycbcr_coeff}, {DP_COM_CONF_CSC_DEF_BG, &rgb2ycbcr_coeff} },
  179010. +{{0, 0}, {DP_COM_CONF_CSC_DEF_BOTH, &ycbcr2rgb_coeff}, {DP_COM_CONF_CSC_DEF_BG, &ycbcr2rgb_coeff}, {0, 0}, {DP_COM_CONF_CSC_DEF_BG, &ycbcr2rgb_coeff} },
  179011. +{{0, 0}, {DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff}, {0, 0}, {0, 0}, {0, 0} },
  179012. +{{DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff}, {0, 0}, {0, 0}, {0, 0}, {0, 0} },
  179013. +{{DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff}, {DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff}, {0, 0}, {0, 0}, {0, 0} }
  179014. +};
  179015. +
  179016. +void __ipu_dp_csc_setup(struct ipu_soc *ipu,
  179017. + int dp, struct dp_csc_param_t dp_csc_param,
  179018. + bool srm_mode_update)
  179019. +{
  179020. + u32 reg;
  179021. + const int (*coeff)[5][3];
  179022. +
  179023. + if (dp_csc_param.mode >= 0) {
  179024. + reg = ipu_dp_read(ipu, DP_COM_CONF(dp));
  179025. + reg &= ~DP_COM_CONF_CSC_DEF_MASK;
  179026. + reg |= dp_csc_param.mode;
  179027. + ipu_dp_write(ipu, reg, DP_COM_CONF(dp));
  179028. + }
  179029. +
  179030. + coeff = dp_csc_param.coeff;
  179031. +
  179032. + if (coeff) {
  179033. + ipu_dp_write(ipu, mask_a((*coeff)[0][0]) |
  179034. + (mask_a((*coeff)[0][1]) << 16), DP_CSC_A_0(dp));
  179035. + ipu_dp_write(ipu, mask_a((*coeff)[0][2]) |
  179036. + (mask_a((*coeff)[1][0]) << 16), DP_CSC_A_1(dp));
  179037. + ipu_dp_write(ipu, mask_a((*coeff)[1][1]) |
  179038. + (mask_a((*coeff)[1][2]) << 16), DP_CSC_A_2(dp));
  179039. + ipu_dp_write(ipu, mask_a((*coeff)[2][0]) |
  179040. + (mask_a((*coeff)[2][1]) << 16), DP_CSC_A_3(dp));
  179041. + ipu_dp_write(ipu, mask_a((*coeff)[2][2]) |
  179042. + (mask_b((*coeff)[3][0]) << 16) |
  179043. + ((*coeff)[4][0] << 30), DP_CSC_0(dp));
  179044. + ipu_dp_write(ipu, mask_b((*coeff)[3][1]) | ((*coeff)[4][1] << 14) |
  179045. + (mask_b((*coeff)[3][2]) << 16) |
  179046. + ((*coeff)[4][2] << 30), DP_CSC_1(dp));
  179047. + }
  179048. +
  179049. + if (srm_mode_update) {
  179050. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  179051. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  179052. + }
  179053. +}
  179054. +
  179055. +int _ipu_dp_init(struct ipu_soc *ipu,
  179056. + ipu_channel_t channel, uint32_t in_pixel_fmt,
  179057. + uint32_t out_pixel_fmt)
  179058. +{
  179059. + int in_fmt, out_fmt;
  179060. + int dp;
  179061. + int partial = false;
  179062. + uint32_t reg;
  179063. +
  179064. + if (channel == MEM_FG_SYNC) {
  179065. + dp = DP_SYNC;
  179066. + partial = true;
  179067. + } else if (channel == MEM_BG_SYNC) {
  179068. + dp = DP_SYNC;
  179069. + partial = false;
  179070. + } else if (channel == MEM_BG_ASYNC0) {
  179071. + dp = DP_ASYNC0;
  179072. + partial = false;
  179073. + } else {
  179074. + return -EINVAL;
  179075. + }
  179076. +
  179077. + in_fmt = format_to_colorspace(in_pixel_fmt);
  179078. + out_fmt = format_to_colorspace(out_pixel_fmt);
  179079. +
  179080. + if (partial) {
  179081. + if (in_fmt == RGB) {
  179082. + if (out_fmt == RGB)
  179083. + ipu->fg_csc_type = RGB2RGB;
  179084. + else
  179085. + ipu->fg_csc_type = RGB2YUV;
  179086. + } else {
  179087. + if (out_fmt == RGB)
  179088. + ipu->fg_csc_type = YUV2RGB;
  179089. + else
  179090. + ipu->fg_csc_type = YUV2YUV;
  179091. + }
  179092. + } else {
  179093. + if (in_fmt == RGB) {
  179094. + if (out_fmt == RGB)
  179095. + ipu->bg_csc_type = RGB2RGB;
  179096. + else
  179097. + ipu->bg_csc_type = RGB2YUV;
  179098. + } else {
  179099. + if (out_fmt == RGB)
  179100. + ipu->bg_csc_type = YUV2RGB;
  179101. + else
  179102. + ipu->bg_csc_type = YUV2YUV;
  179103. + }
  179104. + }
  179105. +
  179106. + /* Transform color key from rgb to yuv if CSC is enabled */
  179107. + reg = ipu_dp_read(ipu, DP_COM_CONF(dp));
  179108. + if (ipu->color_key_4rgb && (reg & DP_COM_CONF_GWCKE) &&
  179109. + (((ipu->fg_csc_type == RGB2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  179110. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == RGB2YUV)) ||
  179111. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  179112. + ((ipu->fg_csc_type == YUV2RGB) && (ipu->bg_csc_type == YUV2RGB)))) {
  179113. + int red, green, blue;
  179114. + int y, u, v;
  179115. + uint32_t color_key = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(dp)) & 0xFFFFFFL;
  179116. +
  179117. + dev_dbg(ipu->dev, "_ipu_dp_init color key 0x%x need change to yuv fmt!\n", color_key);
  179118. +
  179119. + red = (color_key >> 16) & 0xFF;
  179120. + green = (color_key >> 8) & 0xFF;
  179121. + blue = color_key & 0xFF;
  179122. +
  179123. + y = _rgb_to_yuv(0, red, green, blue);
  179124. + u = _rgb_to_yuv(1, red, green, blue);
  179125. + v = _rgb_to_yuv(2, red, green, blue);
  179126. + color_key = (y << 16) | (u << 8) | v;
  179127. +
  179128. + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(dp)) & 0xFF000000L;
  179129. + ipu_dp_write(ipu, reg | color_key, DP_GRAPH_WIND_CTRL(dp));
  179130. + ipu->color_key_4rgb = false;
  179131. +
  179132. + dev_dbg(ipu->dev, "_ipu_dp_init color key change to yuv fmt 0x%x!\n", color_key);
  179133. + }
  179134. +
  179135. + __ipu_dp_csc_setup(ipu, dp, dp_csc_array[ipu->bg_csc_type][ipu->fg_csc_type], true);
  179136. +
  179137. + return 0;
  179138. +}
  179139. +
  179140. +void _ipu_dp_uninit(struct ipu_soc *ipu, ipu_channel_t channel)
  179141. +{
  179142. + int dp;
  179143. + int partial = false;
  179144. +
  179145. + if (channel == MEM_FG_SYNC) {
  179146. + dp = DP_SYNC;
  179147. + partial = true;
  179148. + } else if (channel == MEM_BG_SYNC) {
  179149. + dp = DP_SYNC;
  179150. + partial = false;
  179151. + } else if (channel == MEM_BG_ASYNC0) {
  179152. + dp = DP_ASYNC0;
  179153. + partial = false;
  179154. + } else {
  179155. + return;
  179156. + }
  179157. +
  179158. + if (partial)
  179159. + ipu->fg_csc_type = CSC_NONE;
  179160. + else
  179161. + ipu->bg_csc_type = CSC_NONE;
  179162. +
  179163. + __ipu_dp_csc_setup(ipu, dp, dp_csc_array[ipu->bg_csc_type][ipu->fg_csc_type], false);
  179164. +}
  179165. +
  179166. +void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt)
  179167. +{
  179168. + u32 reg = 0;
  179169. +
  179170. + if ((dc_chan == 1) || (dc_chan == 5)) {
  179171. + if (interlaced) {
  179172. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 0, 3);
  179173. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 0, 2);
  179174. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 0, 1);
  179175. + } else {
  179176. + if (di) {
  179177. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 2, 3);
  179178. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 3, 2);
  179179. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 1, 1);
  179180. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  179181. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  179182. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  179183. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  179184. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE1, 9, 5);
  179185. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE1, 8, 5);
  179186. + }
  179187. + } else {
  179188. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 5, 3);
  179189. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 6, 2);
  179190. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 12, 1);
  179191. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  179192. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  179193. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  179194. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  179195. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE0, 10, 5);
  179196. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE0, 11, 5);
  179197. + }
  179198. + }
  179199. + }
  179200. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NF, 0, 0);
  179201. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NFIELD, 0, 0);
  179202. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOF, 0, 0);
  179203. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOFIELD, 0, 0);
  179204. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN, 0, 0);
  179205. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR, 0, 0);
  179206. +
  179207. + reg = 0x2;
  179208. + reg |= DC_DISP_ID_SYNC(di) << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET;
  179209. + reg |= di << 2;
  179210. + if (interlaced)
  179211. + reg |= DC_WR_CH_CONF_FIELD_MODE;
  179212. + } else if ((dc_chan == 8) || (dc_chan == 9)) {
  179213. + /* async channels */
  179214. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_0, 0x64, 1);
  179215. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_1, 0x64, 1);
  179216. +
  179217. + reg = 0x3;
  179218. + reg |= DC_DISP_ID_SERIAL << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET;
  179219. + }
  179220. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  179221. +
  179222. + ipu_dc_write(ipu, 0x00000000, DC_WR_CH_ADDR(dc_chan));
  179223. +
  179224. + ipu_dc_write(ipu, 0x00000084, DC_GEN);
  179225. +}
  179226. +
  179227. +void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan)
  179228. +{
  179229. + if ((dc_chan == 1) || (dc_chan == 5)) {
  179230. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 0, 0);
  179231. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 0, 0);
  179232. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 0, 0);
  179233. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NF, 0, 0);
  179234. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NFIELD, 0, 0);
  179235. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOF, 0, 0);
  179236. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOFIELD, 0, 0);
  179237. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN, 0, 0);
  179238. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR, 0, 0);
  179239. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE0, 0, 0);
  179240. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE0, 0, 0);
  179241. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE1, 0, 0);
  179242. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE1, 0, 0);
  179243. + } else if ((dc_chan == 8) || (dc_chan == 9)) {
  179244. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_W_0, 0, 0);
  179245. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_W_1, 0, 0);
  179246. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_W_0, 0, 0);
  179247. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_W_1, 0, 0);
  179248. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_0, 0, 0);
  179249. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_1, 0, 0);
  179250. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_R_0, 0, 0);
  179251. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_R_1, 0, 0);
  179252. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_R_0, 0, 0);
  179253. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_R_1, 0, 0);
  179254. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_R_0, 0, 0);
  179255. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_R_1, 0, 0);
  179256. + }
  179257. +}
  179258. +
  179259. +int _ipu_disp_chan_is_interlaced(struct ipu_soc *ipu, ipu_channel_t channel)
  179260. +{
  179261. + if (channel == MEM_DC_SYNC)
  179262. + return !!(ipu_dc_read(ipu, DC_WR_CH_CONF_1) &
  179263. + DC_WR_CH_CONF_FIELD_MODE);
  179264. + else if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC))
  179265. + return !!(ipu_dc_read(ipu, DC_WR_CH_CONF_5) &
  179266. + DC_WR_CH_CONF_FIELD_MODE);
  179267. + return 0;
  179268. +}
  179269. +
  179270. +void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel)
  179271. +{
  179272. + int di;
  179273. + uint32_t reg;
  179274. + uint32_t dc_chan;
  179275. + int irq = 0;
  179276. +
  179277. + if (channel == MEM_FG_SYNC)
  179278. + irq = IPU_IRQ_DP_SF_END;
  179279. + else if (channel == MEM_DC_SYNC)
  179280. + dc_chan = 1;
  179281. + else if (channel == MEM_BG_SYNC)
  179282. + dc_chan = 5;
  179283. + else
  179284. + return;
  179285. +
  179286. + if (channel == MEM_FG_SYNC) {
  179287. + /* Enable FG channel */
  179288. + reg = ipu_dp_read(ipu, DP_COM_CONF(DP_SYNC));
  179289. + ipu_dp_write(ipu, reg | DP_COM_CONF_FG_EN, DP_COM_CONF(DP_SYNC));
  179290. +
  179291. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  179292. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  179293. + return;
  179294. + } else if (channel == MEM_BG_SYNC) {
  179295. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  179296. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  179297. + }
  179298. +
  179299. + di = ipu->dc_di_assignment[dc_chan];
  179300. +
  179301. + /* Make sure other DC sync channel is not assigned same DI */
  179302. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(6 - dc_chan));
  179303. + if ((di << 2) == (reg & DC_WR_CH_CONF_PROG_DI_ID)) {
  179304. + reg &= ~DC_WR_CH_CONF_PROG_DI_ID;
  179305. + reg |= di ? 0 : DC_WR_CH_CONF_PROG_DI_ID;
  179306. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(6 - dc_chan));
  179307. + }
  179308. +
  179309. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
  179310. + reg |= 4 << DC_WR_CH_CONF_PROG_TYPE_OFFSET;
  179311. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  179312. +
  179313. + clk_prepare_enable(ipu->pixel_clk[di]);
  179314. +}
  179315. +
  179316. +static irqreturn_t dc_irq_handler(int irq, void *dev_id)
  179317. +{
  179318. + struct ipu_soc *ipu = dev_id;
  179319. + struct completion *comp = &ipu->dc_comp;
  179320. + uint32_t reg;
  179321. + uint32_t dc_chan;
  179322. +
  179323. + if (irq == IPU_IRQ_DC_FC_1)
  179324. + dc_chan = 1;
  179325. + else
  179326. + dc_chan = 5;
  179327. +
  179328. + if (!ipu->dc_swap) {
  179329. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
  179330. + reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
  179331. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  179332. +
  179333. + reg = ipu_cm_read(ipu, IPU_DISP_GEN);
  179334. + if (ipu->dc_di_assignment[dc_chan])
  179335. + reg &= ~DI1_COUNTER_RELEASE;
  179336. + else
  179337. + reg &= ~DI0_COUNTER_RELEASE;
  179338. + ipu_cm_write(ipu, reg, IPU_DISP_GEN);
  179339. + }
  179340. +
  179341. + complete(comp);
  179342. + return IRQ_HANDLED;
  179343. +}
  179344. +
  179345. +void _ipu_dp_dc_disable(struct ipu_soc *ipu, ipu_channel_t channel, bool swap)
  179346. +{
  179347. + int ret;
  179348. + uint32_t reg;
  179349. + uint32_t csc;
  179350. + uint32_t dc_chan;
  179351. + int irq = 0;
  179352. + int timeout = 50;
  179353. +
  179354. + ipu->dc_swap = swap;
  179355. +
  179356. + if (channel == MEM_DC_SYNC) {
  179357. + dc_chan = 1;
  179358. + irq = IPU_IRQ_DC_FC_1;
  179359. + } else if (channel == MEM_BG_SYNC) {
  179360. + dc_chan = 5;
  179361. + irq = IPU_IRQ_DP_SF_END;
  179362. + } else if (channel == MEM_FG_SYNC) {
  179363. + /* Disable FG channel */
  179364. + dc_chan = 5;
  179365. +
  179366. + reg = ipu_dp_read(ipu, DP_COM_CONF(DP_SYNC));
  179367. + csc = reg & DP_COM_CONF_CSC_DEF_MASK;
  179368. + if (csc == DP_COM_CONF_CSC_DEF_FG)
  179369. + reg &= ~DP_COM_CONF_CSC_DEF_MASK;
  179370. +
  179371. + reg &= ~DP_COM_CONF_FG_EN;
  179372. + ipu_dp_write(ipu, reg, DP_COM_CONF(DP_SYNC));
  179373. +
  179374. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  179375. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  179376. +
  179377. + if (ipu_is_channel_busy(ipu, MEM_BG_SYNC)) {
  179378. + ipu_cm_write(ipu, IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END),
  179379. + IPUIRQ_2_STATREG(IPU_IRQ_DP_SF_END));
  179380. + while ((ipu_cm_read(ipu, IPUIRQ_2_STATREG(IPU_IRQ_DP_SF_END)) &
  179381. + IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END)) == 0) {
  179382. + msleep(2);
  179383. + timeout -= 2;
  179384. + if (timeout <= 0)
  179385. + break;
  179386. + }
  179387. + }
  179388. + return;
  179389. + } else {
  179390. + return;
  179391. + }
  179392. +
  179393. + init_completion(&ipu->dc_comp);
  179394. + ret = ipu_request_irq(ipu, irq, dc_irq_handler, 0, NULL, ipu);
  179395. + if (ret < 0) {
  179396. + dev_err(ipu->dev, "DC irq %d in use\n", irq);
  179397. + return;
  179398. + }
  179399. + ret = wait_for_completion_timeout(&ipu->dc_comp, msecs_to_jiffies(50));
  179400. + ipu_free_irq(ipu, irq, ipu);
  179401. + dev_dbg(ipu->dev, "DC stop timeout - %d * 10ms\n", 5 - ret);
  179402. +
  179403. + if (ipu->dc_swap) {
  179404. + /* Swap DC channel 1 and 5 settings, and disable old dc chan */
  179405. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
  179406. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(6 - dc_chan));
  179407. + reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
  179408. + reg ^= DC_WR_CH_CONF_PROG_DI_ID;
  179409. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  179410. + }
  179411. +}
  179412. +
  179413. +void _ipu_init_dc_mappings(struct ipu_soc *ipu)
  179414. +{
  179415. + /* IPU_PIX_FMT_RGB24 */
  179416. + _ipu_dc_map_clear(ipu, 0);
  179417. + _ipu_dc_map_config(ipu, 0, 0, 7, 0xFF);
  179418. + _ipu_dc_map_config(ipu, 0, 1, 15, 0xFF);
  179419. + _ipu_dc_map_config(ipu, 0, 2, 23, 0xFF);
  179420. +
  179421. + /* IPU_PIX_FMT_RGB666 */
  179422. + _ipu_dc_map_clear(ipu, 1);
  179423. + _ipu_dc_map_config(ipu, 1, 0, 5, 0xFC);
  179424. + _ipu_dc_map_config(ipu, 1, 1, 11, 0xFC);
  179425. + _ipu_dc_map_config(ipu, 1, 2, 17, 0xFC);
  179426. +
  179427. + /* IPU_PIX_FMT_YUV444 */
  179428. + _ipu_dc_map_clear(ipu, 2);
  179429. + _ipu_dc_map_config(ipu, 2, 0, 15, 0xFF);
  179430. + _ipu_dc_map_config(ipu, 2, 1, 23, 0xFF);
  179431. + _ipu_dc_map_config(ipu, 2, 2, 7, 0xFF);
  179432. +
  179433. + /* IPU_PIX_FMT_RGB565 */
  179434. + _ipu_dc_map_clear(ipu, 3);
  179435. + _ipu_dc_map_config(ipu, 3, 0, 4, 0xF8);
  179436. + _ipu_dc_map_config(ipu, 3, 1, 10, 0xFC);
  179437. + _ipu_dc_map_config(ipu, 3, 2, 15, 0xF8);
  179438. +
  179439. + /* IPU_PIX_FMT_LVDS666 */
  179440. + _ipu_dc_map_clear(ipu, 4);
  179441. + _ipu_dc_map_config(ipu, 4, 0, 5, 0xFC);
  179442. + _ipu_dc_map_config(ipu, 4, 1, 13, 0xFC);
  179443. + _ipu_dc_map_config(ipu, 4, 2, 21, 0xFC);
  179444. +
  179445. + /* IPU_PIX_FMT_VYUY 16bit width */
  179446. + _ipu_dc_map_clear(ipu, 5);
  179447. + _ipu_dc_map_config(ipu, 5, 0, 7, 0xFF);
  179448. + _ipu_dc_map_config(ipu, 5, 1, 0, 0x0);
  179449. + _ipu_dc_map_config(ipu, 5, 2, 15, 0xFF);
  179450. + _ipu_dc_map_clear(ipu, 6);
  179451. + _ipu_dc_map_config(ipu, 6, 0, 0, 0x0);
  179452. + _ipu_dc_map_config(ipu, 6, 1, 7, 0xFF);
  179453. + _ipu_dc_map_config(ipu, 6, 2, 15, 0xFF);
  179454. +
  179455. + /* IPU_PIX_FMT_UYUV 16bit width */
  179456. + _ipu_dc_map_clear(ipu, 7);
  179457. + _ipu_dc_map_link(ipu, 7, 6, 0, 6, 1, 6, 2);
  179458. + _ipu_dc_map_clear(ipu, 8);
  179459. + _ipu_dc_map_link(ipu, 8, 5, 0, 5, 1, 5, 2);
  179460. +
  179461. + /* IPU_PIX_FMT_YUYV 16bit width */
  179462. + _ipu_dc_map_clear(ipu, 9);
  179463. + _ipu_dc_map_link(ipu, 9, 5, 2, 5, 1, 5, 0);
  179464. + _ipu_dc_map_clear(ipu, 10);
  179465. + _ipu_dc_map_link(ipu, 10, 5, 1, 5, 2, 5, 0);
  179466. +
  179467. + /* IPU_PIX_FMT_YVYU 16bit width */
  179468. + _ipu_dc_map_clear(ipu, 11);
  179469. + _ipu_dc_map_link(ipu, 11, 5, 1, 5, 2, 5, 0);
  179470. + _ipu_dc_map_clear(ipu, 12);
  179471. + _ipu_dc_map_link(ipu, 12, 5, 2, 5, 1, 5, 0);
  179472. +
  179473. + /* IPU_PIX_FMT_GBR24 */
  179474. + /* IPU_PIX_FMT_VYU444 */
  179475. + _ipu_dc_map_clear(ipu, 13);
  179476. + _ipu_dc_map_link(ipu, 13, 0, 2, 0, 0, 0, 1);
  179477. +
  179478. + /* IPU_PIX_FMT_BGR24 */
  179479. + _ipu_dc_map_clear(ipu, 14);
  179480. + _ipu_dc_map_link(ipu, 14, 0, 2, 0, 1, 0, 0);
  179481. +}
  179482. +
  179483. +int _ipu_pixfmt_to_map(uint32_t fmt)
  179484. +{
  179485. + switch (fmt) {
  179486. + case IPU_PIX_FMT_GENERIC:
  179487. + case IPU_PIX_FMT_RGB24:
  179488. + return 0;
  179489. + case IPU_PIX_FMT_RGB666:
  179490. + return 1;
  179491. + case IPU_PIX_FMT_YUV444:
  179492. + return 2;
  179493. + case IPU_PIX_FMT_RGB565:
  179494. + return 3;
  179495. + case IPU_PIX_FMT_LVDS666:
  179496. + return 4;
  179497. + case IPU_PIX_FMT_VYUY:
  179498. + return 6;
  179499. + case IPU_PIX_FMT_UYVY:
  179500. + return 8;
  179501. + case IPU_PIX_FMT_YUYV:
  179502. + return 10;
  179503. + case IPU_PIX_FMT_YVYU:
  179504. + return 12;
  179505. + case IPU_PIX_FMT_GBR24:
  179506. + case IPU_PIX_FMT_VYU444:
  179507. + return 13;
  179508. + case IPU_PIX_FMT_BGR24:
  179509. + return 14;
  179510. + }
  179511. +
  179512. + return -1;
  179513. +}
  179514. +
  179515. +/*!
  179516. + * This function sets the colorspace for of dp.
  179517. + * modes.
  179518. + *
  179519. + * @param ipu ipu handler
  179520. + * @param channel Input parameter for the logical channel ID.
  179521. + *
  179522. + * @param param If it's not NULL, update the csc table
  179523. + * with this parameter.
  179524. + *
  179525. + * @return N/A
  179526. + */
  179527. +void _ipu_dp_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3])
  179528. +{
  179529. + int dp;
  179530. + struct dp_csc_param_t dp_csc_param;
  179531. +
  179532. + if (channel == MEM_FG_SYNC)
  179533. + dp = DP_SYNC;
  179534. + else if (channel == MEM_BG_SYNC)
  179535. + dp = DP_SYNC;
  179536. + else if (channel == MEM_BG_ASYNC0)
  179537. + dp = DP_ASYNC0;
  179538. + else
  179539. + return;
  179540. +
  179541. + dp_csc_param.mode = -1;
  179542. + dp_csc_param.coeff = param;
  179543. + __ipu_dp_csc_setup(ipu, dp, dp_csc_param, true);
  179544. +}
  179545. +
  179546. +void ipu_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3])
  179547. +{
  179548. + _ipu_dp_set_csc_coefficients(ipu, channel, param);
  179549. +}
  179550. +EXPORT_SYMBOL(ipu_set_csc_coefficients);
  179551. +
  179552. +/*!
  179553. + * This function is called to adapt synchronous LCD panel to IPU restriction.
  179554. + *
  179555. + */
  179556. +void adapt_panel_to_ipu_restricitions(struct ipu_soc *ipu, uint16_t *v_start_width,
  179557. + uint16_t *v_sync_width,
  179558. + uint16_t *v_end_width)
  179559. +{
  179560. + if (*v_end_width < 2) {
  179561. + uint16_t diff = 2 - *v_end_width;
  179562. + if (*v_start_width >= diff) {
  179563. + *v_end_width = 2;
  179564. + *v_start_width = *v_start_width - diff;
  179565. + } else if (*v_sync_width > diff) {
  179566. + *v_end_width = 2;
  179567. + *v_sync_width = *v_sync_width - diff;
  179568. + } else
  179569. + dev_err(ipu->dev, "WARNING: try to adapt timming, but failed\n");
  179570. + dev_err(ipu->dev, "WARNING: adapt panel end blank lines\n");
  179571. + }
  179572. +}
  179573. +
  179574. +/*!
  179575. + * This function is called to initialize a synchronous LCD panel.
  179576. + *
  179577. + * @param ipu ipu handler
  179578. + * @param disp The DI the panel is attached to.
  179579. + *
  179580. + * @param pixel_clk Desired pixel clock frequency in Hz.
  179581. + *
  179582. + * @param pixel_fmt Input parameter for pixel format of buffer.
  179583. + * Pixel format is a FOURCC ASCII code.
  179584. + *
  179585. + * @param width The width of panel in pixels.
  179586. + *
  179587. + * @param height The height of panel in pixels.
  179588. + *
  179589. + * @param hStartWidth The number of pixel clocks between the HSYNC
  179590. + * signal pulse and the start of valid data.
  179591. + *
  179592. + * @param hSyncWidth The width of the HSYNC signal in units of pixel
  179593. + * clocks.
  179594. + *
  179595. + * @param hEndWidth The number of pixel clocks between the end of
  179596. + * valid data and the HSYNC signal for next line.
  179597. + *
  179598. + * @param vStartWidth The number of lines between the VSYNC
  179599. + * signal pulse and the start of valid data.
  179600. + *
  179601. + * @param vSyncWidth The width of the VSYNC signal in units of lines
  179602. + *
  179603. + * @param vEndWidth The number of lines between the end of valid
  179604. + * data and the VSYNC signal for next frame.
  179605. + *
  179606. + * @param sig Bitfield of signal polarities for LCD interface.
  179607. + *
  179608. + * @return This function returns 0 on success or negative error code on
  179609. + * fail.
  179610. + */
  179611. +int32_t ipu_init_sync_panel(struct ipu_soc *ipu, int disp, uint32_t pixel_clk,
  179612. + uint16_t width, uint16_t height,
  179613. + uint32_t pixel_fmt,
  179614. + uint16_t h_start_width, uint16_t h_sync_width,
  179615. + uint16_t h_end_width, uint16_t v_start_width,
  179616. + uint16_t v_sync_width, uint16_t v_end_width,
  179617. + uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig)
  179618. +{
  179619. + uint32_t field0_offset = 0;
  179620. + uint32_t field1_offset;
  179621. + uint32_t reg;
  179622. + uint32_t di_gen, vsync_cnt;
  179623. + uint32_t div, rounded_pixel_clk;
  179624. + uint32_t h_total, v_total;
  179625. + int map;
  179626. + int ret;
  179627. + struct clk *ldb_di0_clk, *ldb_di1_clk;
  179628. + struct clk *di_parent;
  179629. +
  179630. + dev_dbg(ipu->dev, "panel size = %d x %d\n", width, height);
  179631. +
  179632. + if ((v_sync_width == 0) || (h_sync_width == 0))
  179633. + return -EINVAL;
  179634. +
  179635. + adapt_panel_to_ipu_restricitions(ipu, &v_start_width, &v_sync_width, &v_end_width);
  179636. + h_total = width + h_sync_width + h_start_width + h_end_width;
  179637. + v_total = height + v_sync_width + v_start_width + v_end_width;
  179638. +
  179639. + /* Init clocking */
  179640. + dev_dbg(ipu->dev, "pixel clk = %d\n", pixel_clk);
  179641. +
  179642. + di_parent = clk_get_parent(ipu->di_clk_sel[disp]);
  179643. + if (!di_parent) {
  179644. + dev_err(ipu->dev, "get di clk parent fail\n");
  179645. + return -EINVAL;
  179646. + }
  179647. + ldb_di0_clk = clk_get(ipu->dev, "ldb_di0");
  179648. + if (IS_ERR(ldb_di0_clk)) {
  179649. + dev_err(ipu->dev, "clk_get di0 failed");
  179650. + return PTR_ERR(ldb_di0_clk);
  179651. + }
  179652. + ldb_di1_clk = clk_get(ipu->dev, "ldb_di1");
  179653. + if (IS_ERR(ldb_di1_clk)) {
  179654. + dev_err(ipu->dev, "clk_get di1 failed");
  179655. + return PTR_ERR(ldb_di1_clk);
  179656. + }
  179657. +
  179658. + if (ldb_di0_clk == di_parent || ldb_di1_clk == di_parent) {
  179659. + /* if di clk parent is tve/ldb, then keep it;*/
  179660. + dev_dbg(ipu->dev, "use special clk parent\n");
  179661. + ret = clk_set_parent(ipu->pixel_clk_sel[disp], ipu->di_clk[disp]);
  179662. + if (ret) {
  179663. + dev_err(ipu->dev, "set pixel clk error:%d\n", ret);
  179664. + return ret;
  179665. + }
  179666. + clk_put(ldb_di0_clk);
  179667. + clk_put(ldb_di1_clk);
  179668. + } else {
  179669. + /* try ipu clk first*/
  179670. + dev_dbg(ipu->dev, "try ipu internal clk\n");
  179671. + ret = clk_set_parent(ipu->pixel_clk_sel[disp], ipu->ipu_clk);
  179672. + if (ret) {
  179673. + dev_err(ipu->dev, "set pixel clk error:%d\n", ret);
  179674. + return ret;
  179675. + }
  179676. + rounded_pixel_clk = clk_round_rate(ipu->pixel_clk[disp], pixel_clk);
  179677. + dev_dbg(ipu->dev, "rounded pix clk:%d\n", rounded_pixel_clk);
  179678. + /*
  179679. + * we will only use 1/2 fraction for ipu clk,
  179680. + * so if the clk rate is not fit, try ext clk.
  179681. + */
  179682. + if (!sig.int_clk &&
  179683. + ((rounded_pixel_clk >= pixel_clk + pixel_clk/200) ||
  179684. + (rounded_pixel_clk <= pixel_clk - pixel_clk/200))) {
  179685. + dev_dbg(ipu->dev, "try ipu ext di clk\n");
  179686. +
  179687. + rounded_pixel_clk =
  179688. + clk_round_rate(ipu->di_clk[disp], pixel_clk);
  179689. + ret = clk_set_rate(ipu->di_clk[disp],
  179690. + rounded_pixel_clk);
  179691. + if (ret) {
  179692. + dev_err(ipu->dev,
  179693. + "set di clk rate error:%d\n", ret);
  179694. + return ret;
  179695. + }
  179696. + dev_dbg(ipu->dev, "di clk:%d\n", rounded_pixel_clk);
  179697. + ret = clk_set_parent(ipu->pixel_clk_sel[disp],
  179698. + ipu->di_clk[disp]);
  179699. + if (ret) {
  179700. + dev_err(ipu->dev,
  179701. + "set pixel clk parent error:%d\n", ret);
  179702. + return ret;
  179703. + }
  179704. + }
  179705. + }
  179706. + rounded_pixel_clk = clk_round_rate(ipu->pixel_clk[disp], pixel_clk);
  179707. + dev_dbg(ipu->dev, "round pixel clk:%d\n", rounded_pixel_clk);
  179708. + ret = clk_set_rate(ipu->pixel_clk[disp], rounded_pixel_clk);
  179709. + if (ret) {
  179710. + dev_err(ipu->dev, "set pixel clk rate error:%d\n", ret);
  179711. + return ret;
  179712. + }
  179713. + msleep(5);
  179714. + /* Get integer portion of divider */
  179715. + div = clk_get_rate(clk_get_parent(ipu->pixel_clk_sel[disp])) / rounded_pixel_clk;
  179716. + dev_dbg(ipu->dev, "div:%d\n", div);
  179717. + if (!div) {
  179718. + dev_err(ipu->dev, "invalid pixel clk div = 0\n");
  179719. + return -EINVAL;
  179720. + }
  179721. +
  179722. +
  179723. + mutex_lock(&ipu->mutex_lock);
  179724. +
  179725. + _ipu_di_data_wave_config(ipu, disp, SYNC_WAVE, div - 1, div - 1);
  179726. + _ipu_di_data_pin_config(ipu, disp, SYNC_WAVE, DI_PIN15, 3, 0, div * 2);
  179727. +
  179728. + map = _ipu_pixfmt_to_map(pixel_fmt);
  179729. + if (map < 0) {
  179730. + dev_dbg(ipu->dev, "IPU_DISP: No MAP\n");
  179731. + mutex_unlock(&ipu->mutex_lock);
  179732. + return -EINVAL;
  179733. + }
  179734. +
  179735. + /*clear DI*/
  179736. + di_gen = ipu_di_read(ipu, disp, DI_GENERAL);
  179737. + di_gen &= (0x3 << 20);
  179738. + ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
  179739. +
  179740. + if (sig.interlaced) {
  179741. + if (g_ipu_hw_rev >= IPU_V3DEX) {
  179742. + /* Setup internal HSYNC waveform */
  179743. + _ipu_di_sync_config(ipu,
  179744. + disp, /* display */
  179745. + 1, /* counter */
  179746. + h_total/2 - 1, /* run count */
  179747. + DI_SYNC_CLK, /* run_resolution */
  179748. + 0, /* offset */
  179749. + DI_SYNC_NONE, /* offset resolution */
  179750. + 0, /* repeat count */
  179751. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  179752. + 0, /* CNT_POLARITY_GEN_EN */
  179753. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179754. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179755. + 0, /* COUNT UP */
  179756. + 0 /* COUNT DOWN */
  179757. + );
  179758. +
  179759. + /* Field 1 VSYNC waveform */
  179760. + _ipu_di_sync_config(ipu,
  179761. + disp, /* display */
  179762. + 2, /* counter */
  179763. + h_total - 1, /* run count */
  179764. + DI_SYNC_CLK, /* run_resolution */
  179765. + 0, /* offset */
  179766. + DI_SYNC_NONE, /* offset resolution */
  179767. + 0, /* repeat count */
  179768. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  179769. + 0, /* CNT_POLARITY_GEN_EN */
  179770. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179771. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179772. + 0, /* COUNT UP */
  179773. + 2*div /* COUNT DOWN */
  179774. + );
  179775. +
  179776. + /* Setup internal HSYNC waveform */
  179777. + _ipu_di_sync_config(ipu,
  179778. + disp, /* display */
  179779. + 3, /* counter */
  179780. + v_total*2 - 1, /* run count */
  179781. + DI_SYNC_INT_HSYNC, /* run_resolution */
  179782. + 1, /* offset */
  179783. + DI_SYNC_INT_HSYNC, /* offset resolution */
  179784. + 0, /* repeat count */
  179785. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  179786. + 0, /* CNT_POLARITY_GEN_EN */
  179787. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179788. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179789. + 0, /* COUNT UP */
  179790. + 2*div /* COUNT DOWN */
  179791. + );
  179792. +
  179793. + /* Active Field ? */
  179794. + _ipu_di_sync_config(ipu,
  179795. + disp, /* display */
  179796. + 4, /* counter */
  179797. + v_total/2 - 1, /* run count */
  179798. + DI_SYNC_HSYNC, /* run_resolution */
  179799. + v_start_width, /* offset */
  179800. + DI_SYNC_HSYNC, /* offset resolution */
  179801. + 2, /* repeat count */
  179802. + DI_SYNC_VSYNC, /* CNT_CLR_SEL */
  179803. + 0, /* CNT_POLARITY_GEN_EN */
  179804. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179805. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179806. + 0, /* COUNT UP */
  179807. + 0 /* COUNT DOWN */
  179808. + );
  179809. +
  179810. + /* Active Line */
  179811. + _ipu_di_sync_config(ipu,
  179812. + disp, /* display */
  179813. + 5, /* counter */
  179814. + 0, /* run count */
  179815. + DI_SYNC_HSYNC, /* run_resolution */
  179816. + 0, /* offset */
  179817. + DI_SYNC_NONE, /* offset resolution */
  179818. + height/2, /* repeat count */
  179819. + 4, /* CNT_CLR_SEL */
  179820. + 0, /* CNT_POLARITY_GEN_EN */
  179821. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179822. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179823. + 0, /* COUNT UP */
  179824. + 0 /* COUNT DOWN */
  179825. + );
  179826. +
  179827. + /* Field 0 VSYNC waveform */
  179828. + _ipu_di_sync_config(ipu,
  179829. + disp, /* display */
  179830. + 6, /* counter */
  179831. + v_total - 1, /* run count */
  179832. + DI_SYNC_HSYNC, /* run_resolution */
  179833. + 0, /* offset */
  179834. + DI_SYNC_NONE, /* offset resolution */
  179835. + 0, /* repeat count */
  179836. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  179837. + 0, /* CNT_POLARITY_GEN_EN */
  179838. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179839. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179840. + 0, /* COUNT UP */
  179841. + 0 /* COUNT DOWN */
  179842. + );
  179843. +
  179844. + /* DC VSYNC waveform */
  179845. + vsync_cnt = 7;
  179846. + _ipu_di_sync_config(ipu,
  179847. + disp, /* display */
  179848. + 7, /* counter */
  179849. + v_total/2 - 1, /* run count */
  179850. + DI_SYNC_HSYNC, /* run_resolution */
  179851. + 9, /* offset */
  179852. + DI_SYNC_HSYNC, /* offset resolution */
  179853. + 2, /* repeat count */
  179854. + DI_SYNC_VSYNC, /* CNT_CLR_SEL */
  179855. + 0, /* CNT_POLARITY_GEN_EN */
  179856. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179857. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179858. + 0, /* COUNT UP */
  179859. + 0 /* COUNT DOWN */
  179860. + );
  179861. +
  179862. + /* active pixel waveform */
  179863. + _ipu_di_sync_config(ipu,
  179864. + disp, /* display */
  179865. + 8, /* counter */
  179866. + 0, /* run count */
  179867. + DI_SYNC_CLK, /* run_resolution */
  179868. + h_start_width, /* offset */
  179869. + DI_SYNC_CLK, /* offset resolution */
  179870. + width, /* repeat count */
  179871. + 5, /* CNT_CLR_SEL */
  179872. + 0, /* CNT_POLARITY_GEN_EN */
  179873. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179874. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179875. + 0, /* COUNT UP */
  179876. + 0 /* COUNT DOWN */
  179877. + );
  179878. +
  179879. + /* Second VSYNC */
  179880. + _ipu_di_sync_config(ipu,
  179881. + disp, /* display */
  179882. + 9, /* counter */
  179883. + v_total - 1, /* run count */
  179884. + DI_SYNC_INT_HSYNC, /* run_resolution */
  179885. + v_total/2, /* offset */
  179886. + DI_SYNC_INT_HSYNC, /* offset resolution */
  179887. + 0, /* repeat count */
  179888. + DI_SYNC_HSYNC, /* CNT_CLR_SEL */
  179889. + 0, /* CNT_POLARITY_GEN_EN */
  179890. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179891. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179892. + 0, /* COUNT UP */
  179893. + 2*div /* COUNT DOWN */
  179894. + );
  179895. +
  179896. + /* set gentime select and tag sel */
  179897. + reg = ipu_di_read(ipu, disp, DI_SW_GEN1(9));
  179898. + reg &= 0x1FFFFFFF;
  179899. + reg |= (3-1)<<29 | 0x00008000;
  179900. + ipu_di_write(ipu, disp, reg, DI_SW_GEN1(9));
  179901. +
  179902. + ipu_di_write(ipu, disp, v_total / 2 - 1, DI_SCR_CONF);
  179903. +
  179904. + /* set y_sel = 1 */
  179905. + di_gen |= 0x10000000;
  179906. + di_gen |= DI_GEN_POLARITY_5;
  179907. + di_gen |= DI_GEN_POLARITY_8;
  179908. + } else {
  179909. + /* Setup internal HSYNC waveform */
  179910. + _ipu_di_sync_config(ipu, disp, 1, h_total - 1, DI_SYNC_CLK,
  179911. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
  179912. + DI_SYNC_NONE, 0, 0);
  179913. +
  179914. + field1_offset = v_sync_width + v_start_width + height / 2 +
  179915. + v_end_width;
  179916. + if (sig.odd_field_first) {
  179917. + field0_offset = field1_offset - 1;
  179918. + field1_offset = 0;
  179919. + }
  179920. + v_total += v_start_width + v_end_width;
  179921. +
  179922. + /* Field 1 VSYNC waveform */
  179923. + _ipu_di_sync_config(ipu, disp, 2, v_total - 1, 1,
  179924. + field0_offset,
  179925. + field0_offset ? 1 : DI_SYNC_NONE,
  179926. + 0, DI_SYNC_NONE, 0,
  179927. + DI_SYNC_NONE, DI_SYNC_NONE, 0, 4);
  179928. +
  179929. + /* Setup internal HSYNC waveform */
  179930. + _ipu_di_sync_config(ipu, disp, 3, h_total - 1, DI_SYNC_CLK,
  179931. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0,
  179932. + DI_SYNC_NONE, DI_SYNC_NONE, 0, 4);
  179933. +
  179934. + /* Active Field ? */
  179935. + _ipu_di_sync_config(ipu, disp, 4,
  179936. + field0_offset ?
  179937. + field0_offset : field1_offset - 2,
  179938. + 1, v_start_width + v_sync_width, 1, 2, 2,
  179939. + 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0);
  179940. +
  179941. + /* Active Line */
  179942. + _ipu_di_sync_config(ipu, disp, 5, 0, 1,
  179943. + 0, DI_SYNC_NONE,
  179944. + height / 2, 4, 0, DI_SYNC_NONE,
  179945. + DI_SYNC_NONE, 0, 0);
  179946. +
  179947. + /* Field 0 VSYNC waveform */
  179948. + _ipu_di_sync_config(ipu, disp, 6, v_total - 1, 1,
  179949. + 0, DI_SYNC_NONE,
  179950. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
  179951. + DI_SYNC_NONE, 0, 0);
  179952. +
  179953. + /* DC VSYNC waveform */
  179954. + vsync_cnt = 7;
  179955. + _ipu_di_sync_config(ipu, disp, 7, 0, 1,
  179956. + field1_offset,
  179957. + field1_offset ? 1 : DI_SYNC_NONE,
  179958. + 1, 2, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0);
  179959. +
  179960. + /* active pixel waveform */
  179961. + _ipu_di_sync_config(ipu, disp, 8, 0, DI_SYNC_CLK,
  179962. + h_sync_width + h_start_width, DI_SYNC_CLK,
  179963. + width, 5, 0, DI_SYNC_NONE, DI_SYNC_NONE,
  179964. + 0, 0);
  179965. +
  179966. + /* ??? */
  179967. + _ipu_di_sync_config(ipu, disp, 9, v_total - 1, 2,
  179968. + 0, DI_SYNC_NONE,
  179969. + 0, DI_SYNC_NONE, 6, DI_SYNC_NONE,
  179970. + DI_SYNC_NONE, 0, 0);
  179971. +
  179972. + reg = ipu_di_read(ipu, disp, DI_SW_GEN1(9));
  179973. + reg |= 0x8000;
  179974. + ipu_di_write(ipu, disp, reg, DI_SW_GEN1(9));
  179975. +
  179976. + ipu_di_write(ipu, disp, v_sync_width + v_start_width +
  179977. + v_end_width + height / 2 - 1, DI_SCR_CONF);
  179978. + }
  179979. +
  179980. + /* Init template microcode */
  179981. + _ipu_dc_write_tmpl(ipu, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1);
  179982. +
  179983. + if (sig.Hsync_pol)
  179984. + di_gen |= DI_GEN_POLARITY_3;
  179985. + if (sig.Vsync_pol)
  179986. + di_gen |= DI_GEN_POLARITY_2;
  179987. + } else {
  179988. + /* Setup internal HSYNC waveform */
  179989. + _ipu_di_sync_config(ipu, disp, 1, h_total - 1, DI_SYNC_CLK,
  179990. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
  179991. + DI_SYNC_NONE, 0, 0);
  179992. +
  179993. + /* Setup external (delayed) HSYNC waveform */
  179994. + _ipu_di_sync_config(ipu, disp, DI_SYNC_HSYNC, h_total - 1,
  179995. + DI_SYNC_CLK, div * v_to_h_sync, DI_SYNC_CLK,
  179996. + 0, DI_SYNC_NONE, 1, DI_SYNC_NONE,
  179997. + DI_SYNC_CLK, 0, h_sync_width * 2);
  179998. + /* Setup VSYNC waveform */
  179999. + vsync_cnt = DI_SYNC_VSYNC;
  180000. + _ipu_di_sync_config(ipu, disp, DI_SYNC_VSYNC, v_total - 1,
  180001. + DI_SYNC_INT_HSYNC, 0, DI_SYNC_NONE, 0,
  180002. + DI_SYNC_NONE, 1, DI_SYNC_NONE,
  180003. + DI_SYNC_INT_HSYNC, 0, v_sync_width * 2);
  180004. + ipu_di_write(ipu, disp, v_total - 1, DI_SCR_CONF);
  180005. +
  180006. + /* Setup active data waveform to sync with DC */
  180007. + _ipu_di_sync_config(ipu, disp, 4, 0, DI_SYNC_HSYNC,
  180008. + v_sync_width + v_start_width, DI_SYNC_HSYNC, height,
  180009. + DI_SYNC_VSYNC, 0, DI_SYNC_NONE,
  180010. + DI_SYNC_NONE, 0, 0);
  180011. + _ipu_di_sync_config(ipu, disp, 5, 0, DI_SYNC_CLK,
  180012. + h_sync_width + h_start_width, DI_SYNC_CLK,
  180013. + width, 4, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0,
  180014. + 0);
  180015. +
  180016. + /* set VGA delayed hsync/vsync no matter VGA enabled */
  180017. + if (disp) {
  180018. + /* couter 7 for VGA delay HSYNC */
  180019. + _ipu_di_sync_config(ipu, disp, 7,
  180020. + h_total - 1, DI_SYNC_CLK,
  180021. + 18, DI_SYNC_CLK,
  180022. + 0, DI_SYNC_NONE,
  180023. + 1, DI_SYNC_NONE, DI_SYNC_CLK,
  180024. + 0, h_sync_width * 2);
  180025. +
  180026. + /* couter 8 for VGA delay VSYNC */
  180027. + _ipu_di_sync_config(ipu, disp, 8,
  180028. + v_total - 1, DI_SYNC_INT_HSYNC,
  180029. + 1, DI_SYNC_INT_HSYNC,
  180030. + 0, DI_SYNC_NONE,
  180031. + 1, DI_SYNC_NONE, DI_SYNC_INT_HSYNC,
  180032. + 0, v_sync_width * 2);
  180033. + }
  180034. +
  180035. + /* reset all unused counters */
  180036. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(6));
  180037. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(6));
  180038. + if (!disp) {
  180039. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(7));
  180040. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(7));
  180041. + ipu_di_write(ipu, disp, 0, DI_STP_REP(7));
  180042. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(8));
  180043. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(8));
  180044. + ipu_di_write(ipu, disp, 0, DI_STP_REP(8));
  180045. + }
  180046. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(9));
  180047. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(9));
  180048. + ipu_di_write(ipu, disp, 0, DI_STP_REP(9));
  180049. +
  180050. + reg = ipu_di_read(ipu, disp, DI_STP_REP(6));
  180051. + reg &= 0x0000FFFF;
  180052. + ipu_di_write(ipu, disp, reg, DI_STP_REP(6));
  180053. +
  180054. + /* Init template microcode */
  180055. + if (disp) {
  180056. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  180057. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  180058. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  180059. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  180060. + _ipu_dc_write_tmpl(ipu, 8, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
  180061. + _ipu_dc_write_tmpl(ipu, 9, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  180062. + /* configure user events according to DISP NUM */
  180063. + ipu_dc_write(ipu, (width - 1), DC_UGDE_3(disp));
  180064. + }
  180065. + _ipu_dc_write_tmpl(ipu, 2, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
  180066. + _ipu_dc_write_tmpl(ipu, 3, WROD(0), 0, map, SYNC_WAVE, 4, 5, 0);
  180067. + _ipu_dc_write_tmpl(ipu, 4, WRG, 0, map, NULL_WAVE, 0, 0, 1);
  180068. + _ipu_dc_write_tmpl(ipu, 1, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  180069. +
  180070. + } else {
  180071. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  180072. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  180073. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  180074. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  180075. + _ipu_dc_write_tmpl(ipu, 10, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
  180076. + _ipu_dc_write_tmpl(ipu, 11, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  180077. + /* configure user events according to DISP NUM */
  180078. + ipu_dc_write(ipu, width - 1, DC_UGDE_3(disp));
  180079. + }
  180080. + _ipu_dc_write_tmpl(ipu, 5, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
  180081. + _ipu_dc_write_tmpl(ipu, 6, WROD(0), 0, map, SYNC_WAVE, 4, 5, 0);
  180082. + _ipu_dc_write_tmpl(ipu, 7, WRG, 0, map, NULL_WAVE, 0, 0, 1);
  180083. + _ipu_dc_write_tmpl(ipu, 12, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  180084. + }
  180085. +
  180086. + if (sig.Hsync_pol) {
  180087. + di_gen |= DI_GEN_POLARITY_2;
  180088. + if (disp)
  180089. + di_gen |= DI_GEN_POLARITY_7;
  180090. + }
  180091. + if (sig.Vsync_pol) {
  180092. + di_gen |= DI_GEN_POLARITY_3;
  180093. + if (disp)
  180094. + di_gen |= DI_GEN_POLARITY_8;
  180095. + }
  180096. + }
  180097. + /* changinc DISP_CLK polarity: it can be wrong for some applications */
  180098. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  180099. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  180100. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  180101. + (pixel_fmt == IPU_PIX_FMT_VYUY))
  180102. + di_gen |= 0x00020000;
  180103. +
  180104. + if (!sig.clk_pol)
  180105. + di_gen |= DI_GEN_POLARITY_DISP_CLK;
  180106. +
  180107. + ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
  180108. +
  180109. + ipu_di_write(ipu, disp, (--vsync_cnt << DI_VSYNC_SEL_OFFSET) |
  180110. + 0x00000002, DI_SYNC_AS_GEN);
  180111. + reg = ipu_di_read(ipu, disp, DI_POL);
  180112. + reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15);
  180113. + if (sig.enable_pol)
  180114. + reg |= DI_POL_DRDY_POLARITY_15;
  180115. + if (sig.data_pol)
  180116. + reg |= DI_POL_DRDY_DATA_POLARITY;
  180117. + ipu_di_write(ipu, disp, reg, DI_POL);
  180118. +
  180119. + ipu_dc_write(ipu, width, DC_DISP_CONF2(DC_DISP_ID_SYNC(disp)));
  180120. +
  180121. + mutex_unlock(&ipu->mutex_lock);
  180122. +
  180123. + return 0;
  180124. +}
  180125. +EXPORT_SYMBOL(ipu_init_sync_panel);
  180126. +
  180127. +void ipu_uninit_sync_panel(struct ipu_soc *ipu, int disp)
  180128. +{
  180129. + uint32_t reg;
  180130. + uint32_t di_gen;
  180131. +
  180132. + if ((disp != 0) || (disp != 1))
  180133. + return;
  180134. +
  180135. + mutex_lock(&ipu->mutex_lock);
  180136. +
  180137. + di_gen = ipu_di_read(ipu, disp, DI_GENERAL);
  180138. + di_gen |= 0x3ff | DI_GEN_POLARITY_DISP_CLK;
  180139. + ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
  180140. +
  180141. + reg = ipu_di_read(ipu, disp, DI_POL);
  180142. + reg |= 0x3ffffff;
  180143. + ipu_di_write(ipu, disp, reg, DI_POL);
  180144. +
  180145. + mutex_unlock(&ipu->mutex_lock);
  180146. +}
  180147. +EXPORT_SYMBOL(ipu_uninit_sync_panel);
  180148. +
  180149. +int ipu_init_async_panel(struct ipu_soc *ipu, int disp, int type, uint32_t cycle_time,
  180150. + uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig)
  180151. +{
  180152. + int map;
  180153. + u32 ser_conf = 0;
  180154. + u32 div;
  180155. + u32 di_clk = clk_get_rate(ipu->ipu_clk);
  180156. +
  180157. + /* round up cycle_time, then calcalate the divider using scaled math */
  180158. + cycle_time += (1000000000UL / di_clk) - 1;
  180159. + div = (cycle_time * (di_clk / 256UL)) / (1000000000UL / 256UL);
  180160. +
  180161. + map = _ipu_pixfmt_to_map(pixel_fmt);
  180162. + if (map < 0)
  180163. + return -EINVAL;
  180164. +
  180165. + mutex_lock(&ipu->mutex_lock);
  180166. +
  180167. + if (type == IPU_PANEL_SERIAL) {
  180168. + ipu_di_write(ipu, disp, (div << 24) | ((sig.ifc_width - 1) << 4),
  180169. + DI_DW_GEN(ASYNC_SER_WAVE));
  180170. +
  180171. + _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_CS,
  180172. + 0, 0, (div * 2) + 1);
  180173. + _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_SER_CLK,
  180174. + 1, div, div * 2);
  180175. + _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_SER_RS,
  180176. + 2, 0, 0);
  180177. +
  180178. + _ipu_dc_write_tmpl(ipu, 0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0, 1);
  180179. +
  180180. + /* Configure DC for serial panel */
  180181. + ipu_dc_write(ipu, 0x14, DC_DISP_CONF1(DC_DISP_ID_SERIAL));
  180182. +
  180183. + if (sig.clk_pol)
  180184. + ser_conf |= DI_SER_CONF_SERIAL_CLK_POL;
  180185. + if (sig.data_pol)
  180186. + ser_conf |= DI_SER_CONF_SERIAL_DATA_POL;
  180187. + if (sig.rs_pol)
  180188. + ser_conf |= DI_SER_CONF_SERIAL_RS_POL;
  180189. + if (sig.cs_pol)
  180190. + ser_conf |= DI_SER_CONF_SERIAL_CS_POL;
  180191. + ipu_di_write(ipu, disp, ser_conf, DI_SER_CONF);
  180192. + }
  180193. +
  180194. + mutex_unlock(&ipu->mutex_lock);
  180195. + return 0;
  180196. +}
  180197. +EXPORT_SYMBOL(ipu_init_async_panel);
  180198. +
  180199. +/*!
  180200. + * This function sets the foreground and background plane global alpha blending
  180201. + * modes. This function also sets the DP graphic plane according to the
  180202. + * parameter of IPUv3 DP channel.
  180203. + *
  180204. + * @param ipu ipu handler
  180205. + * @param channel IPUv3 DP channel
  180206. + *
  180207. + * @param enable Boolean to enable or disable global alpha
  180208. + * blending. If disabled, local blending is used.
  180209. + *
  180210. + * @param alpha Global alpha value.
  180211. + *
  180212. + * @return Returns 0 on success or negative error code on fail
  180213. + */
  180214. +int32_t ipu_disp_set_global_alpha(struct ipu_soc *ipu, ipu_channel_t channel,
  180215. + bool enable, uint8_t alpha)
  180216. +{
  180217. + uint32_t reg;
  180218. + uint32_t flow;
  180219. + bool bg_chan;
  180220. +
  180221. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
  180222. + flow = DP_SYNC;
  180223. + else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
  180224. + flow = DP_ASYNC0;
  180225. + else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
  180226. + flow = DP_ASYNC1;
  180227. + else
  180228. + return -EINVAL;
  180229. +
  180230. + if (channel == MEM_BG_SYNC || channel == MEM_BG_ASYNC0 ||
  180231. + channel == MEM_BG_ASYNC1)
  180232. + bg_chan = true;
  180233. + else
  180234. + bg_chan = false;
  180235. +
  180236. + _ipu_get(ipu);
  180237. +
  180238. + mutex_lock(&ipu->mutex_lock);
  180239. +
  180240. + if (bg_chan) {
  180241. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180242. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWSEL, DP_COM_CONF(flow));
  180243. + } else {
  180244. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180245. + ipu_dp_write(ipu, reg | DP_COM_CONF_GWSEL, DP_COM_CONF(flow));
  180246. + }
  180247. +
  180248. + if (enable) {
  180249. + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(flow)) & 0x00FFFFFFL;
  180250. + ipu_dp_write(ipu, reg | ((uint32_t) alpha << 24),
  180251. + DP_GRAPH_WIND_CTRL(flow));
  180252. +
  180253. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180254. + ipu_dp_write(ipu, reg | DP_COM_CONF_GWAM, DP_COM_CONF(flow));
  180255. + } else {
  180256. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180257. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWAM, DP_COM_CONF(flow));
  180258. + }
  180259. +
  180260. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  180261. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  180262. +
  180263. + mutex_unlock(&ipu->mutex_lock);
  180264. +
  180265. + _ipu_put(ipu);
  180266. +
  180267. + return 0;
  180268. +}
  180269. +EXPORT_SYMBOL(ipu_disp_set_global_alpha);
  180270. +
  180271. +/*!
  180272. + * This function sets the transparent color key for SDC graphic plane.
  180273. + *
  180274. + * @param ipu ipu handler
  180275. + * @param channel Input parameter for the logical channel ID.
  180276. + *
  180277. + * @param enable Boolean to enable or disable color key
  180278. + *
  180279. + * @param colorKey 24-bit RGB color for transparent color key.
  180280. + *
  180281. + * @return Returns 0 on success or negative error code on fail
  180282. + */
  180283. +int32_t ipu_disp_set_color_key(struct ipu_soc *ipu, ipu_channel_t channel,
  180284. + bool enable, uint32_t color_key)
  180285. +{
  180286. + uint32_t reg, flow;
  180287. + int y, u, v;
  180288. + int red, green, blue;
  180289. +
  180290. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
  180291. + flow = DP_SYNC;
  180292. + else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
  180293. + flow = DP_ASYNC0;
  180294. + else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
  180295. + flow = DP_ASYNC1;
  180296. + else
  180297. + return -EINVAL;
  180298. +
  180299. + _ipu_get(ipu);
  180300. +
  180301. + mutex_lock(&ipu->mutex_lock);
  180302. +
  180303. + ipu->color_key_4rgb = true;
  180304. + /* Transform color key from rgb to yuv if CSC is enabled */
  180305. + if (((ipu->fg_csc_type == RGB2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  180306. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == RGB2YUV)) ||
  180307. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  180308. + ((ipu->fg_csc_type == YUV2RGB) && (ipu->bg_csc_type == YUV2RGB))) {
  180309. +
  180310. + dev_dbg(ipu->dev, "color key 0x%x need change to yuv fmt\n", color_key);
  180311. +
  180312. + red = (color_key >> 16) & 0xFF;
  180313. + green = (color_key >> 8) & 0xFF;
  180314. + blue = color_key & 0xFF;
  180315. +
  180316. + y = _rgb_to_yuv(0, red, green, blue);
  180317. + u = _rgb_to_yuv(1, red, green, blue);
  180318. + v = _rgb_to_yuv(2, red, green, blue);
  180319. + color_key = (y << 16) | (u << 8) | v;
  180320. +
  180321. + ipu->color_key_4rgb = false;
  180322. +
  180323. + dev_dbg(ipu->dev, "color key change to yuv fmt 0x%x\n", color_key);
  180324. + }
  180325. +
  180326. + if (enable) {
  180327. + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(flow)) & 0xFF000000L;
  180328. + ipu_dp_write(ipu, reg | color_key, DP_GRAPH_WIND_CTRL(flow));
  180329. +
  180330. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180331. + ipu_dp_write(ipu, reg | DP_COM_CONF_GWCKE, DP_COM_CONF(flow));
  180332. + } else {
  180333. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180334. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWCKE, DP_COM_CONF(flow));
  180335. + }
  180336. +
  180337. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  180338. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  180339. +
  180340. + mutex_unlock(&ipu->mutex_lock);
  180341. +
  180342. + _ipu_put(ipu);
  180343. +
  180344. + return 0;
  180345. +}
  180346. +EXPORT_SYMBOL(ipu_disp_set_color_key);
  180347. +
  180348. +/*!
  180349. + * This function sets the gamma correction for DP output.
  180350. + *
  180351. + * @param ipu ipu handler
  180352. + * @param channel Input parameter for the logical channel ID.
  180353. + *
  180354. + * @param enable Boolean to enable or disable gamma correction.
  180355. + *
  180356. + * @param constk Gamma piecewise linear approximation constk coeff.
  180357. + *
  180358. + * @param slopek Gamma piecewise linear approximation slopek coeff.
  180359. + *
  180360. + * @return Returns 0 on success or negative error code on fail
  180361. + */
  180362. +int32_t ipu_disp_set_gamma_correction(struct ipu_soc *ipu, ipu_channel_t channel, bool enable, int constk[], int slopek[])
  180363. +{
  180364. + uint32_t reg, flow, i;
  180365. +
  180366. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
  180367. + flow = DP_SYNC;
  180368. + else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
  180369. + flow = DP_ASYNC0;
  180370. + else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
  180371. + flow = DP_ASYNC1;
  180372. + else
  180373. + return -EINVAL;
  180374. +
  180375. + _ipu_get(ipu);
  180376. +
  180377. + mutex_lock(&ipu->mutex_lock);
  180378. +
  180379. + for (i = 0; i < 8; i++)
  180380. + ipu_dp_write(ipu, (constk[2*i] & 0x1ff) | ((constk[2*i+1] & 0x1ff) << 16), DP_GAMMA_C(flow, i));
  180381. + for (i = 0; i < 4; i++)
  180382. + ipu_dp_write(ipu, (slopek[4*i] & 0xff) | ((slopek[4*i+1] & 0xff) << 8) |
  180383. + ((slopek[4*i+2] & 0xff) << 16) | ((slopek[4*i+3] & 0xff) << 24), DP_GAMMA_S(flow, i));
  180384. +
  180385. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180386. + if (enable) {
  180387. + if ((ipu->bg_csc_type == RGB2YUV) || (ipu->bg_csc_type == YUV2YUV))
  180388. + reg |= DP_COM_CONF_GAMMA_YUV_EN;
  180389. + else
  180390. + reg &= ~DP_COM_CONF_GAMMA_YUV_EN;
  180391. + ipu_dp_write(ipu, reg | DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow));
  180392. + } else
  180393. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow));
  180394. +
  180395. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  180396. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  180397. +
  180398. + mutex_unlock(&ipu->mutex_lock);
  180399. +
  180400. + _ipu_put(ipu);
  180401. +
  180402. + return 0;
  180403. +}
  180404. +EXPORT_SYMBOL(ipu_disp_set_gamma_correction);
  180405. +
  180406. +/*!
  180407. + * This function sets the window position of the foreground or background plane.
  180408. + * modes.
  180409. + *
  180410. + * @param ipu ipu handler
  180411. + * @param channel Input parameter for the logical channel ID.
  180412. + *
  180413. + * @param x_pos The X coordinate position to place window at.
  180414. + * The position is relative to the top left corner.
  180415. + *
  180416. + * @param y_pos The Y coordinate position to place window at.
  180417. + * The position is relative to the top left corner.
  180418. + *
  180419. + * @return Returns 0 on success or negative error code on fail
  180420. + */
  180421. +int32_t _ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  180422. + int16_t x_pos, int16_t y_pos)
  180423. +{
  180424. + u32 reg;
  180425. + uint32_t flow = 0;
  180426. + uint32_t dp_srm_shift;
  180427. +
  180428. + if ((channel == MEM_FG_SYNC) || (channel == MEM_BG_SYNC)) {
  180429. + flow = DP_SYNC;
  180430. + dp_srm_shift = 3;
  180431. + } else if (channel == MEM_FG_ASYNC0) {
  180432. + flow = DP_ASYNC0;
  180433. + dp_srm_shift = 5;
  180434. + } else if (channel == MEM_FG_ASYNC1) {
  180435. + flow = DP_ASYNC1;
  180436. + dp_srm_shift = 7;
  180437. + } else
  180438. + return -EINVAL;
  180439. +
  180440. + ipu_dp_write(ipu, (x_pos << 16) | y_pos, DP_FG_POS(flow));
  180441. +
  180442. + if (ipu_is_channel_busy(ipu, channel)) {
  180443. + /* controled by FSU if channel enabled */
  180444. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift));
  180445. + reg |= (0x1 << dp_srm_shift);
  180446. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  180447. + } else {
  180448. + /* disable auto swap, controled by MCU if channel disabled */
  180449. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift));
  180450. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  180451. + }
  180452. +
  180453. + return 0;
  180454. +}
  180455. +
  180456. +int32_t ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  180457. + int16_t x_pos, int16_t y_pos)
  180458. +{
  180459. + int ret;
  180460. +
  180461. + _ipu_get(ipu);
  180462. + mutex_lock(&ipu->mutex_lock);
  180463. + ret = _ipu_disp_set_window_pos(ipu, channel, x_pos, y_pos);
  180464. + mutex_unlock(&ipu->mutex_lock);
  180465. + _ipu_put(ipu);
  180466. + return ret;
  180467. +}
  180468. +EXPORT_SYMBOL(ipu_disp_set_window_pos);
  180469. +
  180470. +int32_t _ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  180471. + int16_t *x_pos, int16_t *y_pos)
  180472. +{
  180473. + u32 reg;
  180474. + uint32_t flow = 0;
  180475. +
  180476. + if (channel == MEM_FG_SYNC)
  180477. + flow = DP_SYNC;
  180478. + else if (channel == MEM_FG_ASYNC0)
  180479. + flow = DP_ASYNC0;
  180480. + else if (channel == MEM_FG_ASYNC1)
  180481. + flow = DP_ASYNC1;
  180482. + else
  180483. + return -EINVAL;
  180484. +
  180485. + reg = ipu_dp_read(ipu, DP_FG_POS(flow));
  180486. +
  180487. + *x_pos = (reg >> 16) & 0x7FF;
  180488. + *y_pos = reg & 0x7FF;
  180489. +
  180490. + return 0;
  180491. +}
  180492. +int32_t ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  180493. + int16_t *x_pos, int16_t *y_pos)
  180494. +{
  180495. + int ret;
  180496. +
  180497. + _ipu_get(ipu);
  180498. + mutex_lock(&ipu->mutex_lock);
  180499. + ret = _ipu_disp_get_window_pos(ipu, channel, x_pos, y_pos);
  180500. + mutex_unlock(&ipu->mutex_lock);
  180501. + _ipu_put(ipu);
  180502. + return ret;
  180503. +}
  180504. +EXPORT_SYMBOL(ipu_disp_get_window_pos);
  180505. +
  180506. +void ipu_disp_direct_write(struct ipu_soc *ipu, ipu_channel_t channel, u32 value, u32 offset)
  180507. +{
  180508. + if (channel == DIRECT_ASYNC0)
  180509. + writel(value, ipu->disp_base[0] + offset);
  180510. + else if (channel == DIRECT_ASYNC1)
  180511. + writel(value, ipu->disp_base[1] + offset);
  180512. +}
  180513. +EXPORT_SYMBOL(ipu_disp_direct_write);
  180514. +
  180515. +void ipu_reset_disp_panel(struct ipu_soc *ipu)
  180516. +{
  180517. + uint32_t tmp;
  180518. +
  180519. + tmp = ipu_di_read(ipu, 1, DI_GENERAL);
  180520. + ipu_di_write(ipu, 1, tmp | 0x08, DI_GENERAL);
  180521. + msleep(10); /* tRES >= 100us */
  180522. + tmp = ipu_di_read(ipu, 1, DI_GENERAL);
  180523. + ipu_di_write(ipu, 1, tmp & ~0x08, DI_GENERAL);
  180524. + msleep(60);
  180525. +
  180526. + return;
  180527. +}
  180528. +EXPORT_SYMBOL(ipu_reset_disp_panel);
  180529. +
  180530. +void ipu_disp_init(struct ipu_soc *ipu)
  180531. +{
  180532. + ipu->fg_csc_type = ipu->bg_csc_type = CSC_NONE;
  180533. + ipu->color_key_4rgb = true;
  180534. + _ipu_init_dc_mappings(ipu);
  180535. + _ipu_dmfc_init(ipu, DMFC_NORMAL, 1);
  180536. +}
  180537. diff -Nur linux-3.14.15/drivers/mxc/ipu3/ipu_ic.c linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_ic.c
  180538. --- linux-3.14.15/drivers/mxc/ipu3/ipu_ic.c 1970-01-01 01:00:00.000000000 +0100
  180539. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_ic.c 2014-08-20 19:31:46.140869056 +0200
  180540. @@ -0,0 +1,924 @@
  180541. +/*
  180542. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  180543. + */
  180544. +
  180545. +/*
  180546. + * The code contained herein is licensed under the GNU General Public
  180547. + * License. You may obtain a copy of the GNU General Public License
  180548. + * Version 2 or later at the following locations:
  180549. + *
  180550. + * http://www.opensource.org/licenses/gpl-license.html
  180551. + * http://www.gnu.org/copyleft/gpl.html
  180552. + */
  180553. +
  180554. +/*
  180555. + * @file ipu_ic.c
  180556. + *
  180557. + * @brief IPU IC functions
  180558. + *
  180559. + * @ingroup IPU
  180560. + */
  180561. +#include <linux/errno.h>
  180562. +#include <linux/init.h>
  180563. +#include <linux/io.h>
  180564. +#include <linux/ipu-v3.h>
  180565. +#include <linux/spinlock.h>
  180566. +#include <linux/types.h>
  180567. +#include <linux/videodev2.h>
  180568. +
  180569. +#include "ipu_param_mem.h"
  180570. +#include "ipu_regs.h"
  180571. +
  180572. +enum {
  180573. + IC_TASK_VIEWFINDER,
  180574. + IC_TASK_ENCODER,
  180575. + IC_TASK_POST_PROCESSOR
  180576. +};
  180577. +
  180578. +static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in_format,
  180579. + ipu_color_space_t out_format, int csc_index);
  180580. +
  180581. +static int _calc_resize_coeffs(struct ipu_soc *ipu,
  180582. + uint32_t inSize, uint32_t outSize,
  180583. + uint32_t *resizeCoeff,
  180584. + uint32_t *downsizeCoeff);
  180585. +
  180586. +void _ipu_vdi_set_top_field_man(struct ipu_soc *ipu, bool top_field_0)
  180587. +{
  180588. + uint32_t reg;
  180589. +
  180590. + reg = ipu_vdi_read(ipu, VDI_C);
  180591. + if (top_field_0)
  180592. + reg &= ~VDI_C_TOP_FIELD_MAN_1;
  180593. + else
  180594. + reg |= VDI_C_TOP_FIELD_MAN_1;
  180595. + ipu_vdi_write(ipu, reg, VDI_C);
  180596. +}
  180597. +
  180598. +void _ipu_vdi_set_motion(struct ipu_soc *ipu, ipu_motion_sel motion_sel)
  180599. +{
  180600. + uint32_t reg;
  180601. +
  180602. + reg = ipu_vdi_read(ipu, VDI_C);
  180603. + reg &= ~(VDI_C_MOT_SEL_FULL | VDI_C_MOT_SEL_MED | VDI_C_MOT_SEL_LOW);
  180604. + if (motion_sel == HIGH_MOTION)
  180605. + reg |= VDI_C_MOT_SEL_FULL;
  180606. + else if (motion_sel == MED_MOTION)
  180607. + reg |= VDI_C_MOT_SEL_MED;
  180608. + else
  180609. + reg |= VDI_C_MOT_SEL_LOW;
  180610. +
  180611. + ipu_vdi_write(ipu, reg, VDI_C);
  180612. + dev_dbg(ipu->dev, "VDI_C = \t0x%08X\n", reg);
  180613. +}
  180614. +
  180615. +void ic_dump_register(struct ipu_soc *ipu)
  180616. +{
  180617. + printk(KERN_DEBUG "IC_CONF = \t0x%08X\n", ipu_ic_read(ipu, IC_CONF));
  180618. + printk(KERN_DEBUG "IC_PRP_ENC_RSC = \t0x%08X\n",
  180619. + ipu_ic_read(ipu, IC_PRP_ENC_RSC));
  180620. + printk(KERN_DEBUG "IC_PRP_VF_RSC = \t0x%08X\n",
  180621. + ipu_ic_read(ipu, IC_PRP_VF_RSC));
  180622. + printk(KERN_DEBUG "IC_PP_RSC = \t0x%08X\n", ipu_ic_read(ipu, IC_PP_RSC));
  180623. + printk(KERN_DEBUG "IC_IDMAC_1 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_1));
  180624. + printk(KERN_DEBUG "IC_IDMAC_2 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_2));
  180625. + printk(KERN_DEBUG "IC_IDMAC_3 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_3));
  180626. +}
  180627. +
  180628. +void _ipu_ic_enable_task(struct ipu_soc *ipu, ipu_channel_t channel)
  180629. +{
  180630. + uint32_t ic_conf;
  180631. +
  180632. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  180633. + switch (channel) {
  180634. + case CSI_PRP_VF_MEM:
  180635. + case MEM_PRP_VF_MEM:
  180636. + ic_conf |= IC_CONF_PRPVF_EN;
  180637. + break;
  180638. + case MEM_VDI_PRP_VF_MEM:
  180639. + ic_conf |= IC_CONF_PRPVF_EN;
  180640. + break;
  180641. + case MEM_VDI_MEM:
  180642. + ic_conf |= IC_CONF_PRPVF_EN | IC_CONF_RWS_EN ;
  180643. + break;
  180644. + case MEM_ROT_VF_MEM:
  180645. + ic_conf |= IC_CONF_PRPVF_ROT_EN;
  180646. + break;
  180647. + case CSI_PRP_ENC_MEM:
  180648. + case MEM_PRP_ENC_MEM:
  180649. + ic_conf |= IC_CONF_PRPENC_EN;
  180650. + break;
  180651. + case MEM_ROT_ENC_MEM:
  180652. + ic_conf |= IC_CONF_PRPENC_ROT_EN;
  180653. + break;
  180654. + case MEM_PP_MEM:
  180655. + ic_conf |= IC_CONF_PP_EN;
  180656. + break;
  180657. + case MEM_ROT_PP_MEM:
  180658. + ic_conf |= IC_CONF_PP_ROT_EN;
  180659. + break;
  180660. + default:
  180661. + break;
  180662. + }
  180663. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  180664. +}
  180665. +
  180666. +void _ipu_ic_disable_task(struct ipu_soc *ipu, ipu_channel_t channel)
  180667. +{
  180668. + uint32_t ic_conf;
  180669. +
  180670. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  180671. + switch (channel) {
  180672. + case CSI_PRP_VF_MEM:
  180673. + case MEM_PRP_VF_MEM:
  180674. + ic_conf &= ~IC_CONF_PRPVF_EN;
  180675. + break;
  180676. + case MEM_VDI_PRP_VF_MEM:
  180677. + ic_conf &= ~IC_CONF_PRPVF_EN;
  180678. + break;
  180679. + case MEM_VDI_MEM:
  180680. + ic_conf &= ~(IC_CONF_PRPVF_EN | IC_CONF_RWS_EN);
  180681. + break;
  180682. + case MEM_ROT_VF_MEM:
  180683. + ic_conf &= ~IC_CONF_PRPVF_ROT_EN;
  180684. + break;
  180685. + case CSI_PRP_ENC_MEM:
  180686. + case MEM_PRP_ENC_MEM:
  180687. + ic_conf &= ~IC_CONF_PRPENC_EN;
  180688. + break;
  180689. + case MEM_ROT_ENC_MEM:
  180690. + ic_conf &= ~IC_CONF_PRPENC_ROT_EN;
  180691. + break;
  180692. + case MEM_PP_MEM:
  180693. + ic_conf &= ~IC_CONF_PP_EN;
  180694. + break;
  180695. + case MEM_ROT_PP_MEM:
  180696. + ic_conf &= ~IC_CONF_PP_ROT_EN;
  180697. + break;
  180698. + default:
  180699. + break;
  180700. + }
  180701. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  180702. +}
  180703. +
  180704. +void _ipu_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params)
  180705. +{
  180706. + uint32_t reg;
  180707. + uint32_t pixel_fmt;
  180708. + uint32_t pix_per_burst;
  180709. +
  180710. + reg = ((params->mem_prp_vf_mem.in_height-1) << 16) |
  180711. + (params->mem_prp_vf_mem.in_width-1);
  180712. + ipu_vdi_write(ipu, reg, VDI_FSIZE);
  180713. +
  180714. + /* Full motion, only vertical filter is used
  180715. + Burst size is 4 accesses */
  180716. + if (params->mem_prp_vf_mem.in_pixel_fmt ==
  180717. + IPU_PIX_FMT_UYVY ||
  180718. + params->mem_prp_vf_mem.in_pixel_fmt ==
  180719. + IPU_PIX_FMT_YUYV) {
  180720. + pixel_fmt = VDI_C_CH_422;
  180721. + pix_per_burst = 32;
  180722. + } else {
  180723. + pixel_fmt = VDI_C_CH_420;
  180724. + pix_per_burst = 64;
  180725. + }
  180726. +
  180727. + reg = ipu_vdi_read(ipu, VDI_C);
  180728. + reg |= pixel_fmt;
  180729. + switch (channel) {
  180730. + case MEM_VDI_PRP_VF_MEM:
  180731. + reg |= VDI_C_BURST_SIZE2_4;
  180732. + break;
  180733. + case MEM_VDI_PRP_VF_MEM_P:
  180734. + reg |= VDI_C_BURST_SIZE1_4 | VDI_C_VWM1_SET_1 | VDI_C_VWM1_CLR_2;
  180735. + break;
  180736. + case MEM_VDI_PRP_VF_MEM_N:
  180737. + reg |= VDI_C_BURST_SIZE3_4 | VDI_C_VWM3_SET_1 | VDI_C_VWM3_CLR_2;
  180738. + break;
  180739. +
  180740. + case MEM_VDI_MEM:
  180741. + reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
  180742. + << VDI_C_BURST_SIZE2_OFFSET;
  180743. + break;
  180744. + case MEM_VDI_MEM_P:
  180745. + reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
  180746. + << VDI_C_BURST_SIZE1_OFFSET;
  180747. + reg |= VDI_C_VWM1_SET_2 | VDI_C_VWM1_CLR_2;
  180748. + break;
  180749. + case MEM_VDI_MEM_N:
  180750. + reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
  180751. + << VDI_C_BURST_SIZE3_OFFSET;
  180752. + reg |= VDI_C_VWM3_SET_2 | VDI_C_VWM3_CLR_2;
  180753. + break;
  180754. + default:
  180755. + break;
  180756. + }
  180757. + ipu_vdi_write(ipu, reg, VDI_C);
  180758. +
  180759. + if (params->mem_prp_vf_mem.field_fmt == IPU_DEINTERLACE_FIELD_TOP)
  180760. + _ipu_vdi_set_top_field_man(ipu, true);
  180761. + else if (params->mem_prp_vf_mem.field_fmt == IPU_DEINTERLACE_FIELD_BOTTOM)
  180762. + _ipu_vdi_set_top_field_man(ipu, false);
  180763. +
  180764. + _ipu_vdi_set_motion(ipu, params->mem_prp_vf_mem.motion_sel);
  180765. +
  180766. + reg = ipu_ic_read(ipu, IC_CONF);
  180767. + reg &= ~IC_CONF_RWS_EN;
  180768. + ipu_ic_write(ipu, reg, IC_CONF);
  180769. +}
  180770. +
  180771. +void _ipu_vdi_uninit(struct ipu_soc *ipu)
  180772. +{
  180773. + ipu_vdi_write(ipu, 0, VDI_FSIZE);
  180774. + ipu_vdi_write(ipu, 0, VDI_C);
  180775. +}
  180776. +
  180777. +int _ipu_ic_init_prpvf(struct ipu_soc *ipu, ipu_channel_params_t *params,
  180778. + bool src_is_csi)
  180779. +{
  180780. + uint32_t reg, ic_conf;
  180781. + uint32_t downsizeCoeff, resizeCoeff;
  180782. + ipu_color_space_t in_fmt, out_fmt;
  180783. + int ret = 0;
  180784. +
  180785. + /* Setup vertical resizing */
  180786. + if (!params->mem_prp_vf_mem.outv_resize_ratio) {
  180787. + ret = _calc_resize_coeffs(ipu, params->mem_prp_vf_mem.in_height,
  180788. + params->mem_prp_vf_mem.out_height,
  180789. + &resizeCoeff, &downsizeCoeff);
  180790. + if (ret < 0) {
  180791. + dev_err(ipu->dev, "failed to calculate prpvf height "
  180792. + "scaling coefficients\n");
  180793. + return ret;
  180794. + }
  180795. +
  180796. + reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
  180797. + } else
  180798. + reg = (params->mem_prp_vf_mem.outv_resize_ratio) << 16;
  180799. +
  180800. + /* Setup horizontal resizing */
  180801. + if (!params->mem_prp_vf_mem.outh_resize_ratio) {
  180802. + ret = _calc_resize_coeffs(ipu, params->mem_prp_vf_mem.in_width,
  180803. + params->mem_prp_vf_mem.out_width,
  180804. + &resizeCoeff, &downsizeCoeff);
  180805. + if (ret < 0) {
  180806. + dev_err(ipu->dev, "failed to calculate prpvf width "
  180807. + "scaling coefficients\n");
  180808. + return ret;
  180809. + }
  180810. +
  180811. + reg |= (downsizeCoeff << 14) | resizeCoeff;
  180812. + } else
  180813. + reg |= params->mem_prp_vf_mem.outh_resize_ratio;
  180814. +
  180815. + ipu_ic_write(ipu, reg, IC_PRP_VF_RSC);
  180816. +
  180817. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  180818. +
  180819. + /* Setup color space conversion */
  180820. + in_fmt = format_to_colorspace(params->mem_prp_vf_mem.in_pixel_fmt);
  180821. + out_fmt = format_to_colorspace(params->mem_prp_vf_mem.out_pixel_fmt);
  180822. + if (in_fmt == RGB) {
  180823. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  180824. + /* Enable RGB->YCBCR CSC1 */
  180825. + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, out_fmt, 1);
  180826. + ic_conf |= IC_CONF_PRPVF_CSC1;
  180827. + }
  180828. + }
  180829. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  180830. + if (out_fmt == RGB) {
  180831. + /* Enable YCBCR->RGB CSC1 */
  180832. + _init_csc(ipu, IC_TASK_VIEWFINDER, YCbCr, RGB, 1);
  180833. + ic_conf |= IC_CONF_PRPVF_CSC1;
  180834. + } else {
  180835. + /* TODO: Support YUV<->YCbCr conversion? */
  180836. + }
  180837. + }
  180838. +
  180839. + if (params->mem_prp_vf_mem.graphics_combine_en) {
  180840. + ic_conf |= IC_CONF_PRPVF_CMB;
  180841. +
  180842. + if (!(ic_conf & IC_CONF_PRPVF_CSC1)) {
  180843. + /* need transparent CSC1 conversion */
  180844. + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, RGB, 1);
  180845. + ic_conf |= IC_CONF_PRPVF_CSC1; /* Enable RGB->RGB CSC */
  180846. + }
  180847. + in_fmt = format_to_colorspace(params->mem_prp_vf_mem.in_g_pixel_fmt);
  180848. + out_fmt = format_to_colorspace(params->mem_prp_vf_mem.out_pixel_fmt);
  180849. + if (in_fmt == RGB) {
  180850. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  180851. + /* Enable RGB->YCBCR CSC2 */
  180852. + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, out_fmt, 2);
  180853. + ic_conf |= IC_CONF_PRPVF_CSC2;
  180854. + }
  180855. + }
  180856. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  180857. + if (out_fmt == RGB) {
  180858. + /* Enable YCBCR->RGB CSC2 */
  180859. + _init_csc(ipu, IC_TASK_VIEWFINDER, YCbCr, RGB, 2);
  180860. + ic_conf |= IC_CONF_PRPVF_CSC2;
  180861. + } else {
  180862. + /* TODO: Support YUV<->YCbCr conversion? */
  180863. + }
  180864. + }
  180865. +
  180866. + if (params->mem_prp_vf_mem.global_alpha_en) {
  180867. + ic_conf |= IC_CONF_IC_GLB_LOC_A;
  180868. + reg = ipu_ic_read(ipu, IC_CMBP_1);
  180869. + reg &= ~(0xff);
  180870. + reg |= params->mem_prp_vf_mem.alpha;
  180871. + ipu_ic_write(ipu, reg, IC_CMBP_1);
  180872. + } else
  180873. + ic_conf &= ~IC_CONF_IC_GLB_LOC_A;
  180874. +
  180875. + if (params->mem_prp_vf_mem.key_color_en) {
  180876. + ic_conf |= IC_CONF_KEY_COLOR_EN;
  180877. + ipu_ic_write(ipu, params->mem_prp_vf_mem.key_color,
  180878. + IC_CMBP_2);
  180879. + } else
  180880. + ic_conf &= ~IC_CONF_KEY_COLOR_EN;
  180881. + } else {
  180882. + ic_conf &= ~IC_CONF_PRPVF_CMB;
  180883. + }
  180884. +
  180885. + if (src_is_csi)
  180886. + ic_conf &= ~IC_CONF_RWS_EN;
  180887. + else
  180888. + ic_conf |= IC_CONF_RWS_EN;
  180889. +
  180890. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  180891. +
  180892. + return ret;
  180893. +}
  180894. +
  180895. +void _ipu_ic_uninit_prpvf(struct ipu_soc *ipu)
  180896. +{
  180897. + uint32_t reg;
  180898. +
  180899. + reg = ipu_ic_read(ipu, IC_CONF);
  180900. + reg &= ~(IC_CONF_PRPVF_EN | IC_CONF_PRPVF_CMB |
  180901. + IC_CONF_PRPVF_CSC2 | IC_CONF_PRPVF_CSC1);
  180902. + ipu_ic_write(ipu, reg, IC_CONF);
  180903. +}
  180904. +
  180905. +void _ipu_ic_init_rotate_vf(struct ipu_soc *ipu, ipu_channel_params_t *params)
  180906. +{
  180907. +}
  180908. +
  180909. +void _ipu_ic_uninit_rotate_vf(struct ipu_soc *ipu)
  180910. +{
  180911. + uint32_t reg;
  180912. + reg = ipu_ic_read(ipu, IC_CONF);
  180913. + reg &= ~IC_CONF_PRPVF_ROT_EN;
  180914. + ipu_ic_write(ipu, reg, IC_CONF);
  180915. +}
  180916. +
  180917. +int _ipu_ic_init_prpenc(struct ipu_soc *ipu, ipu_channel_params_t *params,
  180918. + bool src_is_csi)
  180919. +{
  180920. + uint32_t reg, ic_conf;
  180921. + uint32_t downsizeCoeff, resizeCoeff;
  180922. + ipu_color_space_t in_fmt, out_fmt;
  180923. + int ret = 0;
  180924. +
  180925. + /* Setup vertical resizing */
  180926. + if (!params->mem_prp_enc_mem.outv_resize_ratio) {
  180927. + ret = _calc_resize_coeffs(ipu,
  180928. + params->mem_prp_enc_mem.in_height,
  180929. + params->mem_prp_enc_mem.out_height,
  180930. + &resizeCoeff, &downsizeCoeff);
  180931. + if (ret < 0) {
  180932. + dev_err(ipu->dev, "failed to calculate prpenc height "
  180933. + "scaling coefficients\n");
  180934. + return ret;
  180935. + }
  180936. +
  180937. + reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
  180938. + } else
  180939. + reg = (params->mem_prp_enc_mem.outv_resize_ratio) << 16;
  180940. +
  180941. + /* Setup horizontal resizing */
  180942. + if (!params->mem_prp_enc_mem.outh_resize_ratio) {
  180943. + ret = _calc_resize_coeffs(ipu, params->mem_prp_enc_mem.in_width,
  180944. + params->mem_prp_enc_mem.out_width,
  180945. + &resizeCoeff, &downsizeCoeff);
  180946. + if (ret < 0) {
  180947. + dev_err(ipu->dev, "failed to calculate prpenc width "
  180948. + "scaling coefficients\n");
  180949. + return ret;
  180950. + }
  180951. +
  180952. + reg |= (downsizeCoeff << 14) | resizeCoeff;
  180953. + } else
  180954. + reg |= params->mem_prp_enc_mem.outh_resize_ratio;
  180955. +
  180956. + ipu_ic_write(ipu, reg, IC_PRP_ENC_RSC);
  180957. +
  180958. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  180959. +
  180960. + /* Setup color space conversion */
  180961. + in_fmt = format_to_colorspace(params->mem_prp_enc_mem.in_pixel_fmt);
  180962. + out_fmt = format_to_colorspace(params->mem_prp_enc_mem.out_pixel_fmt);
  180963. + if (in_fmt == RGB) {
  180964. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  180965. + /* Enable RGB->YCBCR CSC1 */
  180966. + _init_csc(ipu, IC_TASK_ENCODER, RGB, out_fmt, 1);
  180967. + ic_conf |= IC_CONF_PRPENC_CSC1;
  180968. + }
  180969. + }
  180970. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  180971. + if (out_fmt == RGB) {
  180972. + /* Enable YCBCR->RGB CSC1 */
  180973. + _init_csc(ipu, IC_TASK_ENCODER, YCbCr, RGB, 1);
  180974. + ic_conf |= IC_CONF_PRPENC_CSC1;
  180975. + } else {
  180976. + /* TODO: Support YUV<->YCbCr conversion? */
  180977. + }
  180978. + }
  180979. +
  180980. + if (src_is_csi)
  180981. + ic_conf &= ~IC_CONF_RWS_EN;
  180982. + else
  180983. + ic_conf |= IC_CONF_RWS_EN;
  180984. +
  180985. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  180986. +
  180987. + return ret;
  180988. +}
  180989. +
  180990. +void _ipu_ic_uninit_prpenc(struct ipu_soc *ipu)
  180991. +{
  180992. + uint32_t reg;
  180993. +
  180994. + reg = ipu_ic_read(ipu, IC_CONF);
  180995. + reg &= ~(IC_CONF_PRPENC_EN | IC_CONF_PRPENC_CSC1);
  180996. + ipu_ic_write(ipu, reg, IC_CONF);
  180997. +}
  180998. +
  180999. +void _ipu_ic_init_rotate_enc(struct ipu_soc *ipu, ipu_channel_params_t *params)
  181000. +{
  181001. +}
  181002. +
  181003. +void _ipu_ic_uninit_rotate_enc(struct ipu_soc *ipu)
  181004. +{
  181005. + uint32_t reg;
  181006. +
  181007. + reg = ipu_ic_read(ipu, IC_CONF);
  181008. + reg &= ~(IC_CONF_PRPENC_ROT_EN);
  181009. + ipu_ic_write(ipu, reg, IC_CONF);
  181010. +}
  181011. +
  181012. +int _ipu_ic_init_pp(struct ipu_soc *ipu, ipu_channel_params_t *params)
  181013. +{
  181014. + uint32_t reg, ic_conf;
  181015. + uint32_t downsizeCoeff, resizeCoeff;
  181016. + ipu_color_space_t in_fmt, out_fmt;
  181017. + int ret = 0;
  181018. +
  181019. + /* Setup vertical resizing */
  181020. + if (!params->mem_pp_mem.outv_resize_ratio) {
  181021. + ret = _calc_resize_coeffs(ipu, params->mem_pp_mem.in_height,
  181022. + params->mem_pp_mem.out_height,
  181023. + &resizeCoeff, &downsizeCoeff);
  181024. + if (ret < 0) {
  181025. + dev_err(ipu->dev, "failed to calculate pp height "
  181026. + "scaling coefficients\n");
  181027. + return ret;
  181028. + }
  181029. +
  181030. + reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
  181031. + } else {
  181032. + reg = (params->mem_pp_mem.outv_resize_ratio) << 16;
  181033. + }
  181034. +
  181035. + /* Setup horizontal resizing */
  181036. + if (!params->mem_pp_mem.outh_resize_ratio) {
  181037. + ret = _calc_resize_coeffs(ipu, params->mem_pp_mem.in_width,
  181038. + params->mem_pp_mem.out_width,
  181039. + &resizeCoeff, &downsizeCoeff);
  181040. + if (ret < 0) {
  181041. + dev_err(ipu->dev, "failed to calculate pp width "
  181042. + "scaling coefficients\n");
  181043. + return ret;
  181044. + }
  181045. +
  181046. + reg |= (downsizeCoeff << 14) | resizeCoeff;
  181047. + } else {
  181048. + reg |= params->mem_pp_mem.outh_resize_ratio;
  181049. + }
  181050. +
  181051. + ipu_ic_write(ipu, reg, IC_PP_RSC);
  181052. +
  181053. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  181054. +
  181055. + /* Setup color space conversion */
  181056. + in_fmt = format_to_colorspace(params->mem_pp_mem.in_pixel_fmt);
  181057. + out_fmt = format_to_colorspace(params->mem_pp_mem.out_pixel_fmt);
  181058. + if (in_fmt == RGB) {
  181059. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  181060. + /* Enable RGB->YCBCR CSC1 */
  181061. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, out_fmt, 1);
  181062. + ic_conf |= IC_CONF_PP_CSC1;
  181063. + }
  181064. + }
  181065. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  181066. + if (out_fmt == RGB) {
  181067. + /* Enable YCBCR->RGB CSC1 */
  181068. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, YCbCr, RGB, 1);
  181069. + ic_conf |= IC_CONF_PP_CSC1;
  181070. + } else {
  181071. + /* TODO: Support YUV<->YCbCr conversion? */
  181072. + }
  181073. + }
  181074. +
  181075. + if (params->mem_pp_mem.graphics_combine_en) {
  181076. + ic_conf |= IC_CONF_PP_CMB;
  181077. +
  181078. + if (!(ic_conf & IC_CONF_PP_CSC1)) {
  181079. + /* need transparent CSC1 conversion */
  181080. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, RGB, 1);
  181081. + ic_conf |= IC_CONF_PP_CSC1; /* Enable RGB->RGB CSC */
  181082. + }
  181083. +
  181084. + in_fmt = format_to_colorspace(params->mem_pp_mem.in_g_pixel_fmt);
  181085. + out_fmt = format_to_colorspace(params->mem_pp_mem.out_pixel_fmt);
  181086. + if (in_fmt == RGB) {
  181087. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  181088. + /* Enable RGB->YCBCR CSC2 */
  181089. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, out_fmt, 2);
  181090. + ic_conf |= IC_CONF_PP_CSC2;
  181091. + }
  181092. + }
  181093. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  181094. + if (out_fmt == RGB) {
  181095. + /* Enable YCBCR->RGB CSC2 */
  181096. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, YCbCr, RGB, 2);
  181097. + ic_conf |= IC_CONF_PP_CSC2;
  181098. + } else {
  181099. + /* TODO: Support YUV<->YCbCr conversion? */
  181100. + }
  181101. + }
  181102. +
  181103. + if (params->mem_pp_mem.global_alpha_en) {
  181104. + ic_conf |= IC_CONF_IC_GLB_LOC_A;
  181105. + reg = ipu_ic_read(ipu, IC_CMBP_1);
  181106. + reg &= ~(0xff00);
  181107. + reg |= (params->mem_pp_mem.alpha << 8);
  181108. + ipu_ic_write(ipu, reg, IC_CMBP_1);
  181109. + } else
  181110. + ic_conf &= ~IC_CONF_IC_GLB_LOC_A;
  181111. +
  181112. + if (params->mem_pp_mem.key_color_en) {
  181113. + ic_conf |= IC_CONF_KEY_COLOR_EN;
  181114. + ipu_ic_write(ipu, params->mem_pp_mem.key_color,
  181115. + IC_CMBP_2);
  181116. + } else
  181117. + ic_conf &= ~IC_CONF_KEY_COLOR_EN;
  181118. + } else {
  181119. + ic_conf &= ~IC_CONF_PP_CMB;
  181120. + }
  181121. +
  181122. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  181123. +
  181124. + return ret;
  181125. +}
  181126. +
  181127. +void _ipu_ic_uninit_pp(struct ipu_soc *ipu)
  181128. +{
  181129. + uint32_t reg;
  181130. +
  181131. + reg = ipu_ic_read(ipu, IC_CONF);
  181132. + reg &= ~(IC_CONF_PP_EN | IC_CONF_PP_CSC1 | IC_CONF_PP_CSC2 |
  181133. + IC_CONF_PP_CMB);
  181134. + ipu_ic_write(ipu, reg, IC_CONF);
  181135. +}
  181136. +
  181137. +void _ipu_ic_init_rotate_pp(struct ipu_soc *ipu, ipu_channel_params_t *params)
  181138. +{
  181139. +}
  181140. +
  181141. +void _ipu_ic_uninit_rotate_pp(struct ipu_soc *ipu)
  181142. +{
  181143. + uint32_t reg;
  181144. + reg = ipu_ic_read(ipu, IC_CONF);
  181145. + reg &= ~IC_CONF_PP_ROT_EN;
  181146. + ipu_ic_write(ipu, reg, IC_CONF);
  181147. +}
  181148. +
  181149. +int _ipu_ic_idma_init(struct ipu_soc *ipu, int dma_chan,
  181150. + uint16_t width, uint16_t height,
  181151. + int burst_size, ipu_rotate_mode_t rot)
  181152. +{
  181153. + u32 ic_idmac_1, ic_idmac_2, ic_idmac_3;
  181154. + u32 temp_rot = bitrev8(rot) >> 5;
  181155. + bool need_hor_flip = false;
  181156. +
  181157. + if ((burst_size != 8) && (burst_size != 16)) {
  181158. + dev_dbg(ipu->dev, "Illegal burst length for IC\n");
  181159. + return -EINVAL;
  181160. + }
  181161. +
  181162. + width--;
  181163. + height--;
  181164. +
  181165. + if (temp_rot & 0x2) /* Need horizontal flip */
  181166. + need_hor_flip = true;
  181167. +
  181168. + ic_idmac_1 = ipu_ic_read(ipu, IC_IDMAC_1);
  181169. + ic_idmac_2 = ipu_ic_read(ipu, IC_IDMAC_2);
  181170. + ic_idmac_3 = ipu_ic_read(ipu, IC_IDMAC_3);
  181171. + if (dma_chan == 22) { /* PP output - CB2 */
  181172. + if (burst_size == 16)
  181173. + ic_idmac_1 |= IC_IDMAC_1_CB2_BURST_16;
  181174. + else
  181175. + ic_idmac_1 &= ~IC_IDMAC_1_CB2_BURST_16;
  181176. +
  181177. + if (need_hor_flip)
  181178. + ic_idmac_1 |= IC_IDMAC_1_PP_FLIP_RS;
  181179. + else
  181180. + ic_idmac_1 &= ~IC_IDMAC_1_PP_FLIP_RS;
  181181. +
  181182. + ic_idmac_2 &= ~IC_IDMAC_2_PP_HEIGHT_MASK;
  181183. + ic_idmac_2 |= height << IC_IDMAC_2_PP_HEIGHT_OFFSET;
  181184. +
  181185. + ic_idmac_3 &= ~IC_IDMAC_3_PP_WIDTH_MASK;
  181186. + ic_idmac_3 |= width << IC_IDMAC_3_PP_WIDTH_OFFSET;
  181187. + } else if (dma_chan == 11) { /* PP Input - CB5 */
  181188. + if (burst_size == 16)
  181189. + ic_idmac_1 |= IC_IDMAC_1_CB5_BURST_16;
  181190. + else
  181191. + ic_idmac_1 &= ~IC_IDMAC_1_CB5_BURST_16;
  181192. + } else if (dma_chan == 47) { /* PP Rot input */
  181193. + ic_idmac_1 &= ~IC_IDMAC_1_PP_ROT_MASK;
  181194. + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PP_ROT_OFFSET;
  181195. + }
  181196. +
  181197. + if (dma_chan == 12) { /* PRP Input - CB6 */
  181198. + if (burst_size == 16)
  181199. + ic_idmac_1 |= IC_IDMAC_1_CB6_BURST_16;
  181200. + else
  181201. + ic_idmac_1 &= ~IC_IDMAC_1_CB6_BURST_16;
  181202. + }
  181203. +
  181204. + if (dma_chan == 20) { /* PRP ENC output - CB0 */
  181205. + if (burst_size == 16)
  181206. + ic_idmac_1 |= IC_IDMAC_1_CB0_BURST_16;
  181207. + else
  181208. + ic_idmac_1 &= ~IC_IDMAC_1_CB0_BURST_16;
  181209. +
  181210. + if (need_hor_flip)
  181211. + ic_idmac_1 |= IC_IDMAC_1_PRPENC_FLIP_RS;
  181212. + else
  181213. + ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_FLIP_RS;
  181214. +
  181215. + ic_idmac_2 &= ~IC_IDMAC_2_PRPENC_HEIGHT_MASK;
  181216. + ic_idmac_2 |= height << IC_IDMAC_2_PRPENC_HEIGHT_OFFSET;
  181217. +
  181218. + ic_idmac_3 &= ~IC_IDMAC_3_PRPENC_WIDTH_MASK;
  181219. + ic_idmac_3 |= width << IC_IDMAC_3_PRPENC_WIDTH_OFFSET;
  181220. +
  181221. + } else if (dma_chan == 45) { /* PRP ENC Rot input */
  181222. + ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_ROT_MASK;
  181223. + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPENC_ROT_OFFSET;
  181224. + }
  181225. +
  181226. + if (dma_chan == 21) { /* PRP VF output - CB1 */
  181227. + if (burst_size == 16)
  181228. + ic_idmac_1 |= IC_IDMAC_1_CB1_BURST_16;
  181229. + else
  181230. + ic_idmac_1 &= ~IC_IDMAC_1_CB1_BURST_16;
  181231. +
  181232. + if (need_hor_flip)
  181233. + ic_idmac_1 |= IC_IDMAC_1_PRPVF_FLIP_RS;
  181234. + else
  181235. + ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_FLIP_RS;
  181236. +
  181237. + ic_idmac_2 &= ~IC_IDMAC_2_PRPVF_HEIGHT_MASK;
  181238. + ic_idmac_2 |= height << IC_IDMAC_2_PRPVF_HEIGHT_OFFSET;
  181239. +
  181240. + ic_idmac_3 &= ~IC_IDMAC_3_PRPVF_WIDTH_MASK;
  181241. + ic_idmac_3 |= width << IC_IDMAC_3_PRPVF_WIDTH_OFFSET;
  181242. +
  181243. + } else if (dma_chan == 46) { /* PRP VF Rot input */
  181244. + ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_ROT_MASK;
  181245. + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPVF_ROT_OFFSET;
  181246. + }
  181247. +
  181248. + if (dma_chan == 14) { /* PRP VF graphics combining input - CB3 */
  181249. + if (burst_size == 16)
  181250. + ic_idmac_1 |= IC_IDMAC_1_CB3_BURST_16;
  181251. + else
  181252. + ic_idmac_1 &= ~IC_IDMAC_1_CB3_BURST_16;
  181253. + } else if (dma_chan == 15) { /* PP graphics combining input - CB4 */
  181254. + if (burst_size == 16)
  181255. + ic_idmac_1 |= IC_IDMAC_1_CB4_BURST_16;
  181256. + else
  181257. + ic_idmac_1 &= ~IC_IDMAC_1_CB4_BURST_16;
  181258. + } else if (dma_chan == 5) { /* VDIC OUTPUT - CB7 */
  181259. + if (burst_size == 16)
  181260. + ic_idmac_1 |= IC_IDMAC_1_CB7_BURST_16;
  181261. + else
  181262. + ic_idmac_1 &= ~IC_IDMAC_1_CB7_BURST_16;
  181263. + }
  181264. +
  181265. + ipu_ic_write(ipu, ic_idmac_1, IC_IDMAC_1);
  181266. + ipu_ic_write(ipu, ic_idmac_2, IC_IDMAC_2);
  181267. + ipu_ic_write(ipu, ic_idmac_3, IC_IDMAC_3);
  181268. + return 0;
  181269. +}
  181270. +
  181271. +static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in_format,
  181272. + ipu_color_space_t out_format, int csc_index)
  181273. +{
  181274. + /*
  181275. + * Y = 0.257 * R + 0.504 * G + 0.098 * B + 16;
  181276. + * U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
  181277. + * V = 0.439 * R - 0.368 * G - 0.071 * B + 128;
  181278. + */
  181279. + static const uint32_t rgb2ycbcr_coeff[4][3] = {
  181280. + {0x0042, 0x0081, 0x0019},
  181281. + {0x01DA, 0x01B6, 0x0070},
  181282. + {0x0070, 0x01A2, 0x01EE},
  181283. + {0x0040, 0x0200, 0x0200}, /* A0, A1, A2 */
  181284. + };
  181285. +
  181286. + /* transparent RGB->RGB matrix for combining
  181287. + */
  181288. + static const uint32_t rgb2rgb_coeff[4][3] = {
  181289. + {0x0080, 0x0000, 0x0000},
  181290. + {0x0000, 0x0080, 0x0000},
  181291. + {0x0000, 0x0000, 0x0080},
  181292. + {0x0000, 0x0000, 0x0000}, /* A0, A1, A2 */
  181293. + };
  181294. +
  181295. +/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128));
  181296. + G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128));
  181297. + B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */
  181298. + static const uint32_t ycbcr2rgb_coeff[4][3] = {
  181299. + {149, 0, 204},
  181300. + {149, 462, 408},
  181301. + {149, 255, 0},
  181302. + {8192 - 446, 266, 8192 - 554}, /* A0, A1, A2 */
  181303. + };
  181304. +
  181305. + uint32_t param;
  181306. + uint32_t *base = NULL;
  181307. +
  181308. + if (ic_task == IC_TASK_ENCODER) {
  181309. + base = (uint32_t *)ipu->tpmem_base + 0x2008 / 4;
  181310. + } else if (ic_task == IC_TASK_VIEWFINDER) {
  181311. + if (csc_index == 1)
  181312. + base = (uint32_t *)ipu->tpmem_base + 0x4028 / 4;
  181313. + else
  181314. + base = (uint32_t *)ipu->tpmem_base + 0x4040 / 4;
  181315. + } else if (ic_task == IC_TASK_POST_PROCESSOR) {
  181316. + if (csc_index == 1)
  181317. + base = (uint32_t *)ipu->tpmem_base + 0x6060 / 4;
  181318. + else
  181319. + base = (uint32_t *)ipu->tpmem_base + 0x6078 / 4;
  181320. + } else {
  181321. + BUG();
  181322. + }
  181323. +
  181324. + if ((in_format == YCbCr) && (out_format == RGB)) {
  181325. + /* Init CSC (YCbCr->RGB) */
  181326. + param = (ycbcr2rgb_coeff[3][0] << 27) |
  181327. + (ycbcr2rgb_coeff[0][0] << 18) |
  181328. + (ycbcr2rgb_coeff[1][1] << 9) | ycbcr2rgb_coeff[2][2];
  181329. + writel(param, base++);
  181330. + /* scale = 2, sat = 0 */
  181331. + param = (ycbcr2rgb_coeff[3][0] >> 5) | (2L << (40 - 32));
  181332. + writel(param, base++);
  181333. +
  181334. + param = (ycbcr2rgb_coeff[3][1] << 27) |
  181335. + (ycbcr2rgb_coeff[0][1] << 18) |
  181336. + (ycbcr2rgb_coeff[1][0] << 9) | ycbcr2rgb_coeff[2][0];
  181337. + writel(param, base++);
  181338. + param = (ycbcr2rgb_coeff[3][1] >> 5);
  181339. + writel(param, base++);
  181340. +
  181341. + param = (ycbcr2rgb_coeff[3][2] << 27) |
  181342. + (ycbcr2rgb_coeff[0][2] << 18) |
  181343. + (ycbcr2rgb_coeff[1][2] << 9) | ycbcr2rgb_coeff[2][1];
  181344. + writel(param, base++);
  181345. + param = (ycbcr2rgb_coeff[3][2] >> 5);
  181346. + writel(param, base++);
  181347. + } else if ((in_format == RGB) && (out_format == YCbCr)) {
  181348. + /* Init CSC (RGB->YCbCr) */
  181349. + param = (rgb2ycbcr_coeff[3][0] << 27) |
  181350. + (rgb2ycbcr_coeff[0][0] << 18) |
  181351. + (rgb2ycbcr_coeff[1][1] << 9) | rgb2ycbcr_coeff[2][2];
  181352. + writel(param, base++);
  181353. + /* scale = 1, sat = 0 */
  181354. + param = (rgb2ycbcr_coeff[3][0] >> 5) | (1UL << 8);
  181355. + writel(param, base++);
  181356. +
  181357. + param = (rgb2ycbcr_coeff[3][1] << 27) |
  181358. + (rgb2ycbcr_coeff[0][1] << 18) |
  181359. + (rgb2ycbcr_coeff[1][0] << 9) | rgb2ycbcr_coeff[2][0];
  181360. + writel(param, base++);
  181361. + param = (rgb2ycbcr_coeff[3][1] >> 5);
  181362. + writel(param, base++);
  181363. +
  181364. + param = (rgb2ycbcr_coeff[3][2] << 27) |
  181365. + (rgb2ycbcr_coeff[0][2] << 18) |
  181366. + (rgb2ycbcr_coeff[1][2] << 9) | rgb2ycbcr_coeff[2][1];
  181367. + writel(param, base++);
  181368. + param = (rgb2ycbcr_coeff[3][2] >> 5);
  181369. + writel(param, base++);
  181370. + } else if ((in_format == RGB) && (out_format == RGB)) {
  181371. + /* Init CSC */
  181372. + param =
  181373. + (rgb2rgb_coeff[3][0] << 27) | (rgb2rgb_coeff[0][0] << 18) |
  181374. + (rgb2rgb_coeff[1][1] << 9) | rgb2rgb_coeff[2][2];
  181375. + writel(param, base++);
  181376. + /* scale = 2, sat = 0 */
  181377. + param = (rgb2rgb_coeff[3][0] >> 5) | (2UL << 8);
  181378. + writel(param, base++);
  181379. +
  181380. + param =
  181381. + (rgb2rgb_coeff[3][1] << 27) | (rgb2rgb_coeff[0][1] << 18) |
  181382. + (rgb2rgb_coeff[1][0] << 9) | rgb2rgb_coeff[2][0];
  181383. + writel(param, base++);
  181384. + param = (rgb2rgb_coeff[3][1] >> 5);
  181385. + writel(param, base++);
  181386. +
  181387. + param =
  181388. + (rgb2rgb_coeff[3][2] << 27) | (rgb2rgb_coeff[0][2] << 18) |
  181389. + (rgb2rgb_coeff[1][2] << 9) | rgb2rgb_coeff[2][1];
  181390. + writel(param, base++);
  181391. + param = (rgb2rgb_coeff[3][2] >> 5);
  181392. + writel(param, base++);
  181393. + } else {
  181394. + dev_err(ipu->dev, "Unsupported color space conversion\n");
  181395. + }
  181396. +}
  181397. +
  181398. +static int _calc_resize_coeffs(struct ipu_soc *ipu,
  181399. + uint32_t inSize, uint32_t outSize,
  181400. + uint32_t *resizeCoeff,
  181401. + uint32_t *downsizeCoeff)
  181402. +{
  181403. + uint32_t tempSize;
  181404. + uint32_t tempDownsize;
  181405. +
  181406. + if (inSize > 4096) {
  181407. + dev_err(ipu->dev, "IC input size(%d) cannot exceed 4096\n",
  181408. + inSize);
  181409. + return -EINVAL;
  181410. + }
  181411. +
  181412. + if (outSize > 1024) {
  181413. + dev_err(ipu->dev, "IC output size(%d) cannot exceed 1024\n",
  181414. + outSize);
  181415. + return -EINVAL;
  181416. + }
  181417. +
  181418. + if ((outSize << 3) < inSize) {
  181419. + dev_err(ipu->dev, "IC cannot downsize more than 8:1\n");
  181420. + return -EINVAL;
  181421. + }
  181422. +
  181423. + /* Compute downsizing coefficient */
  181424. + /* Output of downsizing unit cannot be more than 1024 */
  181425. + tempDownsize = 0;
  181426. + tempSize = inSize;
  181427. + while (((tempSize > 1024) || (tempSize >= outSize * 2)) &&
  181428. + (tempDownsize < 2)) {
  181429. + tempSize >>= 1;
  181430. + tempDownsize++;
  181431. + }
  181432. + *downsizeCoeff = tempDownsize;
  181433. +
  181434. + /* compute resizing coefficient using the following equation:
  181435. + resizeCoeff = M*(SI -1)/(SO - 1)
  181436. + where M = 2^13, SI - input size, SO - output size */
  181437. + *resizeCoeff = (8192L * (tempSize - 1)) / (outSize - 1);
  181438. + if (*resizeCoeff >= 16384L) {
  181439. + dev_err(ipu->dev, "Overflow on IC resize coefficient.\n");
  181440. + return -EINVAL;
  181441. + }
  181442. +
  181443. + dev_dbg(ipu->dev, "resizing from %u -> %u pixels, "
  181444. + "downsize=%u, resize=%u.%lu (reg=%u)\n", inSize, outSize,
  181445. + *downsizeCoeff, (*resizeCoeff >= 8192L) ? 1 : 0,
  181446. + ((*resizeCoeff & 0x1FFF) * 10000L) / 8192L, *resizeCoeff);
  181447. +
  181448. + return 0;
  181449. +}
  181450. +
  181451. +void _ipu_vdi_toggle_top_field_man(struct ipu_soc *ipu)
  181452. +{
  181453. + uint32_t reg;
  181454. + uint32_t mask_reg;
  181455. +
  181456. + reg = ipu_vdi_read(ipu, VDI_C);
  181457. + mask_reg = reg & VDI_C_TOP_FIELD_MAN_1;
  181458. + if (mask_reg == VDI_C_TOP_FIELD_MAN_1)
  181459. + reg &= ~VDI_C_TOP_FIELD_MAN_1;
  181460. + else
  181461. + reg |= VDI_C_TOP_FIELD_MAN_1;
  181462. +
  181463. + ipu_vdi_write(ipu, reg, VDI_C);
  181464. +}
  181465. diff -Nur linux-3.14.15/drivers/mxc/ipu3/ipu_param_mem.h linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_param_mem.h
  181466. --- linux-3.14.15/drivers/mxc/ipu3/ipu_param_mem.h 1970-01-01 01:00:00.000000000 +0100
  181467. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_param_mem.h 2014-08-20 19:23:53.574845907 +0200
  181468. @@ -0,0 +1,921 @@
  181469. +/*
  181470. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  181471. + */
  181472. +
  181473. +/*
  181474. + * The code contained herein is licensed under the GNU General Public
  181475. + * License. You may obtain a copy of the GNU General Public License
  181476. + * Version 2 or later at the following locations:
  181477. + *
  181478. + * http://www.opensource.org/licenses/gpl-license.html
  181479. + * http://www.gnu.org/copyleft/gpl.html
  181480. + */
  181481. +#ifndef __INCLUDE_IPU_PARAM_MEM_H__
  181482. +#define __INCLUDE_IPU_PARAM_MEM_H__
  181483. +
  181484. +#include <linux/bitrev.h>
  181485. +#include <linux/types.h>
  181486. +
  181487. +#include "ipu_prv.h"
  181488. +
  181489. +extern u32 *ipu_cpmem_base;
  181490. +
  181491. +struct ipu_ch_param_word {
  181492. + uint32_t data[5];
  181493. + uint32_t res[3];
  181494. +};
  181495. +
  181496. +struct ipu_ch_param {
  181497. + struct ipu_ch_param_word word[2];
  181498. +};
  181499. +
  181500. +#define ipu_ch_param_addr(ipu, ch) (((struct ipu_ch_param *)ipu->cpmem_base) + (ch))
  181501. +
  181502. +#define _param_word(base, w) \
  181503. + (((struct ipu_ch_param *)(base))->word[(w)].data)
  181504. +
  181505. +#define ipu_ch_param_set_field(base, w, bit, size, v) { \
  181506. + int i = (bit) / 32; \
  181507. + int off = (bit) % 32; \
  181508. + _param_word(base, w)[i] |= (v) << off; \
  181509. + if (((bit)+(size)-1)/32 > i) { \
  181510. + _param_word(base, w)[i + 1] |= (v) >> (off ? (32 - off) : 0); \
  181511. + } \
  181512. +}
  181513. +
  181514. +#define ipu_ch_param_set_field_io(base, w, bit, size, v) { \
  181515. + int i = (bit) / 32; \
  181516. + int off = (bit) % 32; \
  181517. + unsigned reg_offset; \
  181518. + u32 temp; \
  181519. + reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
  181520. + reg_offset += i; \
  181521. + temp = readl((u32 *)base + reg_offset); \
  181522. + temp |= (v) << off; \
  181523. + writel(temp, (u32 *)base + reg_offset); \
  181524. + if (((bit)+(size)-1)/32 > i) { \
  181525. + reg_offset++; \
  181526. + temp = readl((u32 *)base + reg_offset); \
  181527. + temp |= (v) >> (off ? (32 - off) : 0); \
  181528. + writel(temp, (u32 *)base + reg_offset); \
  181529. + } \
  181530. +}
  181531. +
  181532. +#define ipu_ch_param_mod_field(base, w, bit, size, v) { \
  181533. + int i = (bit) / 32; \
  181534. + int off = (bit) % 32; \
  181535. + u32 mask = (1UL << size) - 1; \
  181536. + u32 temp = _param_word(base, w)[i]; \
  181537. + temp &= ~(mask << off); \
  181538. + _param_word(base, w)[i] = temp | (v) << off; \
  181539. + if (((bit)+(size)-1)/32 > i) { \
  181540. + temp = _param_word(base, w)[i + 1]; \
  181541. + temp &= ~(mask >> (32 - off)); \
  181542. + _param_word(base, w)[i + 1] = \
  181543. + temp | ((v) >> (off ? (32 - off) : 0)); \
  181544. + } \
  181545. +}
  181546. +
  181547. +#define ipu_ch_param_mod_field_io(base, w, bit, size, v) { \
  181548. + int i = (bit) / 32; \
  181549. + int off = (bit) % 32; \
  181550. + u32 mask = (1UL << size) - 1; \
  181551. + unsigned reg_offset; \
  181552. + u32 temp; \
  181553. + reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
  181554. + reg_offset += i; \
  181555. + temp = readl((u32 *)base + reg_offset); \
  181556. + temp &= ~(mask << off); \
  181557. + temp |= (v) << off; \
  181558. + writel(temp, (u32 *)base + reg_offset); \
  181559. + if (((bit)+(size)-1)/32 > i) { \
  181560. + reg_offset++; \
  181561. + temp = readl((u32 *)base + reg_offset); \
  181562. + temp &= ~(mask >> (32 - off)); \
  181563. + temp |= ((v) >> (off ? (32 - off) : 0)); \
  181564. + writel(temp, (u32 *)base + reg_offset); \
  181565. + } \
  181566. +}
  181567. +
  181568. +#define ipu_ch_param_read_field(base, w, bit, size) ({ \
  181569. + u32 temp2; \
  181570. + int i = (bit) / 32; \
  181571. + int off = (bit) % 32; \
  181572. + u32 mask = (1UL << size) - 1; \
  181573. + u32 temp1 = _param_word(base, w)[i]; \
  181574. + temp1 = mask & (temp1 >> off); \
  181575. + if (((bit)+(size)-1)/32 > i) { \
  181576. + temp2 = _param_word(base, w)[i + 1]; \
  181577. + temp2 &= mask >> (off ? (32 - off) : 0); \
  181578. + temp1 |= temp2 << (off ? (32 - off) : 0); \
  181579. + } \
  181580. + temp1; \
  181581. +})
  181582. +
  181583. +#define ipu_ch_param_read_field_io(base, w, bit, size) ({ \
  181584. + u32 temp1, temp2; \
  181585. + int i = (bit) / 32; \
  181586. + int off = (bit) % 32; \
  181587. + u32 mask = (1UL << size) - 1; \
  181588. + unsigned reg_offset; \
  181589. + reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
  181590. + reg_offset += i; \
  181591. + temp1 = readl((u32 *)base + reg_offset); \
  181592. + temp1 = mask & (temp1 >> off); \
  181593. + if (((bit)+(size)-1)/32 > i) { \
  181594. + reg_offset++; \
  181595. + temp2 = readl((u32 *)base + reg_offset); \
  181596. + temp2 &= mask >> (off ? (32 - off) : 0); \
  181597. + temp1 |= temp2 << (off ? (32 - off) : 0); \
  181598. + } \
  181599. + temp1; \
  181600. +})
  181601. +
  181602. +static inline int __ipu_ch_get_third_buf_cpmem_num(int ch)
  181603. +{
  181604. + switch (ch) {
  181605. + case 8:
  181606. + return 64;
  181607. + case 9:
  181608. + return 65;
  181609. + case 10:
  181610. + return 66;
  181611. + case 13:
  181612. + return 67;
  181613. + case 21:
  181614. + return 68;
  181615. + case 23:
  181616. + return 69;
  181617. + case 27:
  181618. + return 70;
  181619. + case 28:
  181620. + return 71;
  181621. + default:
  181622. + return -EINVAL;
  181623. + }
  181624. + return 0;
  181625. +}
  181626. +
  181627. +static inline void _ipu_ch_params_set_packing(struct ipu_ch_param *p,
  181628. + int red_width, int red_offset,
  181629. + int green_width, int green_offset,
  181630. + int blue_width, int blue_offset,
  181631. + int alpha_width, int alpha_offset)
  181632. +{
  181633. + /* Setup red width and offset */
  181634. + ipu_ch_param_set_field(p, 1, 116, 3, red_width - 1);
  181635. + ipu_ch_param_set_field(p, 1, 128, 5, red_offset);
  181636. + /* Setup green width and offset */
  181637. + ipu_ch_param_set_field(p, 1, 119, 3, green_width - 1);
  181638. + ipu_ch_param_set_field(p, 1, 133, 5, green_offset);
  181639. + /* Setup blue width and offset */
  181640. + ipu_ch_param_set_field(p, 1, 122, 3, blue_width - 1);
  181641. + ipu_ch_param_set_field(p, 1, 138, 5, blue_offset);
  181642. + /* Setup alpha width and offset */
  181643. + ipu_ch_param_set_field(p, 1, 125, 3, alpha_width - 1);
  181644. + ipu_ch_param_set_field(p, 1, 143, 5, alpha_offset);
  181645. +}
  181646. +
  181647. +static inline void _ipu_ch_param_dump(struct ipu_soc *ipu, int ch)
  181648. +{
  181649. + struct ipu_ch_param *p = ipu_ch_param_addr(ipu, ch);
  181650. + dev_dbg(ipu->dev, "ch %d word 0 - %08X %08X %08X %08X %08X\n", ch,
  181651. + p->word[0].data[0], p->word[0].data[1], p->word[0].data[2],
  181652. + p->word[0].data[3], p->word[0].data[4]);
  181653. + dev_dbg(ipu->dev, "ch %d word 1 - %08X %08X %08X %08X %08X\n", ch,
  181654. + p->word[1].data[0], p->word[1].data[1], p->word[1].data[2],
  181655. + p->word[1].data[3], p->word[1].data[4]);
  181656. + dev_dbg(ipu->dev, "PFS 0x%x, ",
  181657. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 85, 4));
  181658. + dev_dbg(ipu->dev, "BPP 0x%x, ",
  181659. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 107, 3));
  181660. + dev_dbg(ipu->dev, "NPB 0x%x\n",
  181661. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7));
  181662. +
  181663. + dev_dbg(ipu->dev, "FW %d, ",
  181664. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 125, 13));
  181665. + dev_dbg(ipu->dev, "FH %d, ",
  181666. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 138, 12));
  181667. + dev_dbg(ipu->dev, "EBA0 0x%x\n",
  181668. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 0, 29) << 3);
  181669. + dev_dbg(ipu->dev, "EBA1 0x%x\n",
  181670. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 29, 29) << 3);
  181671. + dev_dbg(ipu->dev, "Stride %d\n",
  181672. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14));
  181673. + dev_dbg(ipu->dev, "scan_order %d\n",
  181674. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 113, 1));
  181675. + dev_dbg(ipu->dev, "uv_stride %d\n",
  181676. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 128, 14));
  181677. + dev_dbg(ipu->dev, "u_offset 0x%x\n",
  181678. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22) << 3);
  181679. + dev_dbg(ipu->dev, "v_offset 0x%x\n",
  181680. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22) << 3);
  181681. +
  181682. + dev_dbg(ipu->dev, "Width0 %d+1, ",
  181683. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 116, 3));
  181684. + dev_dbg(ipu->dev, "Width1 %d+1, ",
  181685. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 119, 3));
  181686. + dev_dbg(ipu->dev, "Width2 %d+1, ",
  181687. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 122, 3));
  181688. + dev_dbg(ipu->dev, "Width3 %d+1, ",
  181689. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 125, 3));
  181690. + dev_dbg(ipu->dev, "Offset0 %d, ",
  181691. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 128, 5));
  181692. + dev_dbg(ipu->dev, "Offset1 %d, ",
  181693. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 133, 5));
  181694. + dev_dbg(ipu->dev, "Offset2 %d, ",
  181695. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 138, 5));
  181696. + dev_dbg(ipu->dev, "Offset3 %d\n",
  181697. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 143, 5));
  181698. +}
  181699. +
  181700. +static inline void fill_cpmem(struct ipu_soc *ipu, int ch, struct ipu_ch_param *params)
  181701. +{
  181702. + int i, w;
  181703. + void *addr = ipu_ch_param_addr(ipu, ch);
  181704. +
  181705. + /* 2 words, 5 valid data */
  181706. + for (w = 0; w < 2; w++) {
  181707. + for (i = 0; i < 5; i++) {
  181708. + writel(params->word[w].data[i], addr);
  181709. + addr += 4;
  181710. + }
  181711. + addr += 12;
  181712. + }
  181713. +}
  181714. +
  181715. +static inline void _ipu_ch_param_init(struct ipu_soc *ipu, int ch,
  181716. + uint32_t pixel_fmt, uint32_t width,
  181717. + uint32_t height, uint32_t stride,
  181718. + uint32_t u, uint32_t v,
  181719. + uint32_t uv_stride, dma_addr_t addr0,
  181720. + dma_addr_t addr1, dma_addr_t addr2)
  181721. +{
  181722. + uint32_t u_offset = 0;
  181723. + uint32_t v_offset = 0;
  181724. + int32_t sub_ch = 0;
  181725. + struct ipu_ch_param params;
  181726. +
  181727. + memset(&params, 0, sizeof(params));
  181728. +
  181729. + ipu_ch_param_set_field(&params, 0, 125, 13, width - 1);
  181730. +
  181731. + if (((ch == 8) || (ch == 9) || (ch == 10)) && !ipu->vdoa_en) {
  181732. + ipu_ch_param_set_field(&params, 0, 138, 12, (height / 2) - 1);
  181733. + ipu_ch_param_set_field(&params, 1, 102, 14, (stride * 2) - 1);
  181734. + } else {
  181735. + /* note: for vdoa+vdi- ch8/9/10, always use band mode */
  181736. + ipu_ch_param_set_field(&params, 0, 138, 12, height - 1);
  181737. + ipu_ch_param_set_field(&params, 1, 102, 14, stride - 1);
  181738. + }
  181739. +
  181740. + /* EBA is 8-byte aligned */
  181741. + ipu_ch_param_set_field(&params, 1, 0, 29, addr0 >> 3);
  181742. + ipu_ch_param_set_field(&params, 1, 29, 29, addr1 >> 3);
  181743. + if (addr0%8)
  181744. + dev_warn(ipu->dev,
  181745. + "IDMAC%d's EBA0 is not 8-byte aligned\n", ch);
  181746. + if (addr1%8)
  181747. + dev_warn(ipu->dev,
  181748. + "IDMAC%d's EBA1 is not 8-byte aligned\n", ch);
  181749. +
  181750. + switch (pixel_fmt) {
  181751. + case IPU_PIX_FMT_GENERIC:
  181752. + /*Represents 8-bit Generic data */
  181753. + ipu_ch_param_set_field(&params, 0, 107, 3, 5); /* bits/pixel */
  181754. + ipu_ch_param_set_field(&params, 1, 85, 4, 6); /* pix format */
  181755. + ipu_ch_param_set_field(&params, 1, 78, 7, 63); /* burst size */
  181756. +
  181757. + break;
  181758. + case IPU_PIX_FMT_GENERIC_16:
  181759. + /* Represents 16-bit generic data */
  181760. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  181761. + ipu_ch_param_set_field(&params, 1, 85, 4, 6); /* pix format */
  181762. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181763. +
  181764. + break;
  181765. + case IPU_PIX_FMT_GENERIC_32:
  181766. + /*Represents 32-bit Generic data */
  181767. + break;
  181768. + case IPU_PIX_FMT_RGB565:
  181769. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  181770. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181771. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181772. +
  181773. + _ipu_ch_params_set_packing(&params, 5, 0, 6, 5, 5, 11, 8, 16);
  181774. + break;
  181775. + case IPU_PIX_FMT_BGR24:
  181776. + ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
  181777. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181778. + ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
  181779. +
  181780. + _ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
  181781. + break;
  181782. + case IPU_PIX_FMT_RGB24:
  181783. + case IPU_PIX_FMT_YUV444:
  181784. + ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
  181785. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181786. + ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
  181787. +
  181788. + _ipu_ch_params_set_packing(&params, 8, 16, 8, 8, 8, 0, 8, 24);
  181789. + break;
  181790. + case IPU_PIX_FMT_VYU444:
  181791. + ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
  181792. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181793. + ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
  181794. +
  181795. + _ipu_ch_params_set_packing(&params, 8, 8, 8, 0, 8, 16, 8, 24);
  181796. + break;
  181797. + case IPU_PIX_FMT_BGRA32:
  181798. + case IPU_PIX_FMT_BGR32:
  181799. + ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
  181800. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181801. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  181802. +
  181803. + _ipu_ch_params_set_packing(&params, 8, 8, 8, 16, 8, 24, 8, 0);
  181804. + break;
  181805. + case IPU_PIX_FMT_RGBA32:
  181806. + case IPU_PIX_FMT_RGB32:
  181807. + ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
  181808. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181809. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  181810. +
  181811. + _ipu_ch_params_set_packing(&params, 8, 24, 8, 16, 8, 8, 8, 0);
  181812. + break;
  181813. + case IPU_PIX_FMT_ABGR32:
  181814. + ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
  181815. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181816. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  181817. +
  181818. + _ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
  181819. + break;
  181820. + case IPU_PIX_FMT_UYVY:
  181821. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  181822. + ipu_ch_param_set_field(&params, 1, 85, 4, 0xA); /* pix format */
  181823. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  181824. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  181825. + } else {
  181826. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181827. + }
  181828. + break;
  181829. + case IPU_PIX_FMT_YUYV:
  181830. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  181831. + ipu_ch_param_set_field(&params, 1, 85, 4, 0x8); /* pix format */
  181832. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  181833. + if (ipu->vdoa_en) {
  181834. + ipu_ch_param_set_field(&params, 1, 78, 7, 31);
  181835. + } else {
  181836. + ipu_ch_param_set_field(&params, 1, 78, 7, 15);
  181837. + }
  181838. + } else {
  181839. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181840. + }
  181841. + break;
  181842. + case IPU_PIX_FMT_YUV420P2:
  181843. + case IPU_PIX_FMT_YUV420P:
  181844. + ipu_ch_param_set_field(&params, 1, 85, 4, 2); /* pix format */
  181845. +
  181846. + if (uv_stride < stride / 2)
  181847. + uv_stride = stride / 2;
  181848. +
  181849. + u_offset = stride * height;
  181850. + v_offset = u_offset + (uv_stride * height / 2);
  181851. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  181852. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  181853. + uv_stride = uv_stride*2;
  181854. + } else {
  181855. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181856. + }
  181857. + break;
  181858. + case IPU_PIX_FMT_YVU420P:
  181859. + ipu_ch_param_set_field(&params, 1, 85, 4, 2); /* pix format */
  181860. +
  181861. + if (uv_stride < stride / 2)
  181862. + uv_stride = stride / 2;
  181863. +
  181864. + v_offset = stride * height;
  181865. + u_offset = v_offset + (uv_stride * height / 2);
  181866. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  181867. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  181868. + uv_stride = uv_stride*2;
  181869. + } else {
  181870. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181871. + }
  181872. + break;
  181873. + case IPU_PIX_FMT_YVU422P:
  181874. + /* BPP & pixel format */
  181875. + ipu_ch_param_set_field(&params, 1, 85, 4, 1); /* pix format */
  181876. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181877. +
  181878. + if (uv_stride < stride / 2)
  181879. + uv_stride = stride / 2;
  181880. +
  181881. + v_offset = (v == 0) ? stride * height : v;
  181882. + u_offset = (u == 0) ? v_offset + v_offset / 2 : u;
  181883. + break;
  181884. + case IPU_PIX_FMT_YUV422P:
  181885. + /* BPP & pixel format */
  181886. + ipu_ch_param_set_field(&params, 1, 85, 4, 1); /* pix format */
  181887. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181888. +
  181889. + if (uv_stride < stride / 2)
  181890. + uv_stride = stride / 2;
  181891. +
  181892. + u_offset = (u == 0) ? stride * height : u;
  181893. + v_offset = (v == 0) ? u_offset + u_offset / 2 : v;
  181894. + break;
  181895. + case IPU_PIX_FMT_YUV444P:
  181896. + /* BPP & pixel format */
  181897. + ipu_ch_param_set_field(&params, 1, 85, 4, 0); /* pix format */
  181898. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181899. + uv_stride = stride;
  181900. + u_offset = (u == 0) ? stride * height : u;
  181901. + v_offset = (v == 0) ? u_offset * 2 : v;
  181902. + break;
  181903. + case IPU_PIX_FMT_NV12:
  181904. + /* BPP & pixel format */
  181905. + ipu_ch_param_set_field(&params, 1, 85, 4, 4); /* pix format */
  181906. + uv_stride = stride;
  181907. + u_offset = (u == 0) ? stride * height : u;
  181908. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  181909. + if (ipu->vdoa_en) {
  181910. + /* one field buffer, memory width 64bits */
  181911. + ipu_ch_param_set_field(&params, 1, 78, 7, 63);
  181912. + } else {
  181913. + ipu_ch_param_set_field(&params, 1, 78, 7, 15);
  181914. + /* top/bottom field in one buffer*/
  181915. + uv_stride = uv_stride*2;
  181916. + }
  181917. + } else {
  181918. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181919. + }
  181920. + break;
  181921. + default:
  181922. + dev_err(ipu->dev, "mxc ipu: unimplemented pixel format\n");
  181923. + break;
  181924. + }
  181925. + /*set burst size to 16*/
  181926. +
  181927. +
  181928. + if (uv_stride)
  181929. + ipu_ch_param_set_field(&params, 1, 128, 14, uv_stride - 1);
  181930. +
  181931. + /* Get the uv offset from user when need cropping */
  181932. + if (u || v) {
  181933. + u_offset = u;
  181934. + v_offset = v;
  181935. + }
  181936. +
  181937. + /* UBO and VBO are 22-bit and 8-byte aligned */
  181938. + if (u_offset/8 > 0x3fffff)
  181939. + dev_warn(ipu->dev,
  181940. + "IDMAC%d's U offset exceeds IPU limitation\n", ch);
  181941. + if (v_offset/8 > 0x3fffff)
  181942. + dev_warn(ipu->dev,
  181943. + "IDMAC%d's V offset exceeds IPU limitation\n", ch);
  181944. + if (u_offset%8)
  181945. + dev_warn(ipu->dev,
  181946. + "IDMAC%d's U offset is not 8-byte aligned\n", ch);
  181947. + if (v_offset%8)
  181948. + dev_warn(ipu->dev,
  181949. + "IDMAC%d's V offset is not 8-byte aligned\n", ch);
  181950. +
  181951. + ipu_ch_param_set_field(&params, 0, 46, 22, u_offset / 8);
  181952. + ipu_ch_param_set_field(&params, 0, 68, 22, v_offset / 8);
  181953. +
  181954. + dev_dbg(ipu->dev, "initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ipu, ch));
  181955. + fill_cpmem(ipu, ch, &params);
  181956. + if (addr2) {
  181957. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  181958. + if (sub_ch <= 0)
  181959. + return;
  181960. +
  181961. + ipu_ch_param_set_field(&params, 1, 0, 29, addr2 >> 3);
  181962. + ipu_ch_param_set_field(&params, 1, 29, 29, 0);
  181963. + if (addr2%8)
  181964. + dev_warn(ipu->dev,
  181965. + "IDMAC%d's sub-CPMEM entry%d EBA0 is not "
  181966. + "8-byte aligned\n", ch, sub_ch);
  181967. +
  181968. + dev_dbg(ipu->dev, "initializing idma ch %d @ %p sub cpmem\n", ch,
  181969. + ipu_ch_param_addr(ipu, sub_ch));
  181970. + fill_cpmem(ipu, sub_ch, &params);
  181971. + }
  181972. +};
  181973. +
  181974. +static inline void _ipu_ch_param_set_burst_size(struct ipu_soc *ipu,
  181975. + uint32_t ch,
  181976. + uint16_t burst_pixels)
  181977. +{
  181978. + int32_t sub_ch = 0;
  181979. +
  181980. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7,
  181981. + burst_pixels - 1);
  181982. +
  181983. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  181984. + if (sub_ch <= 0)
  181985. + return;
  181986. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 78, 7,
  181987. + burst_pixels - 1);
  181988. +};
  181989. +
  181990. +static inline int _ipu_ch_param_get_burst_size(struct ipu_soc *ipu, uint32_t ch)
  181991. +{
  181992. + return ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7) + 1;
  181993. +};
  181994. +
  181995. +static inline int _ipu_ch_param_get_bpp(struct ipu_soc *ipu, uint32_t ch)
  181996. +{
  181997. + return ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 107, 3);
  181998. +};
  181999. +
  182000. +static inline void _ipu_ch_param_set_buffer(struct ipu_soc *ipu, uint32_t ch,
  182001. + int bufNum, dma_addr_t phyaddr)
  182002. +{
  182003. + if (bufNum == 2) {
  182004. + ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182005. + if (ch <= 0)
  182006. + return;
  182007. + bufNum = 0;
  182008. + }
  182009. +
  182010. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 29 * bufNum, 29,
  182011. + phyaddr / 8);
  182012. +};
  182013. +
  182014. +static inline void _ipu_ch_param_set_rotation(struct ipu_soc *ipu, uint32_t ch,
  182015. + ipu_rotate_mode_t rot)
  182016. +{
  182017. + u32 temp_rot = bitrev8(rot) >> 5;
  182018. + int32_t sub_ch = 0;
  182019. +
  182020. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 119, 3, temp_rot);
  182021. +
  182022. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182023. + if (sub_ch <= 0)
  182024. + return;
  182025. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 119, 3, temp_rot);
  182026. +};
  182027. +
  182028. +static inline void _ipu_ch_param_set_block_mode(struct ipu_soc *ipu, uint32_t ch)
  182029. +{
  182030. + int32_t sub_ch = 0;
  182031. +
  182032. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 117, 2, 1);
  182033. +
  182034. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182035. + if (sub_ch <= 0)
  182036. + return;
  182037. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 117, 2, 1);
  182038. +};
  182039. +
  182040. +static inline void _ipu_ch_param_set_alpha_use_separate_channel(struct ipu_soc *ipu,
  182041. + uint32_t ch,
  182042. + bool option)
  182043. +{
  182044. + int32_t sub_ch = 0;
  182045. +
  182046. + if (option) {
  182047. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 1);
  182048. + } else {
  182049. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 0);
  182050. + }
  182051. +
  182052. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182053. + if (sub_ch <= 0)
  182054. + return;
  182055. +
  182056. + if (option) {
  182057. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 1);
  182058. + } else {
  182059. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 0);
  182060. + }
  182061. +};
  182062. +
  182063. +static inline void _ipu_ch_param_set_alpha_condition_read(struct ipu_soc *ipu, uint32_t ch)
  182064. +{
  182065. + int32_t sub_ch = 0;
  182066. +
  182067. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 149, 1, 1);
  182068. +
  182069. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182070. + if (sub_ch <= 0)
  182071. + return;
  182072. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 149, 1, 1);
  182073. +};
  182074. +
  182075. +static inline void _ipu_ch_param_set_alpha_buffer_memory(struct ipu_soc *ipu, uint32_t ch)
  182076. +{
  182077. + int alp_mem_idx;
  182078. + int32_t sub_ch = 0;
  182079. +
  182080. + switch (ch) {
  182081. + case 14: /* PRP graphic */
  182082. + alp_mem_idx = 0;
  182083. + break;
  182084. + case 15: /* PP graphic */
  182085. + alp_mem_idx = 1;
  182086. + break;
  182087. + case 23: /* DP BG SYNC graphic */
  182088. + alp_mem_idx = 4;
  182089. + break;
  182090. + case 27: /* DP FG SYNC graphic */
  182091. + alp_mem_idx = 2;
  182092. + break;
  182093. + default:
  182094. + dev_err(ipu->dev, "unsupported correlative channel of local "
  182095. + "alpha channel\n");
  182096. + return;
  182097. + }
  182098. +
  182099. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 90, 3, alp_mem_idx);
  182100. +
  182101. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182102. + if (sub_ch <= 0)
  182103. + return;
  182104. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 90, 3, alp_mem_idx);
  182105. +};
  182106. +
  182107. +static inline void _ipu_ch_param_set_interlaced_scan(struct ipu_soc *ipu, uint32_t ch)
  182108. +{
  182109. + u32 stride;
  182110. + int32_t sub_ch = 0;
  182111. +
  182112. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182113. +
  182114. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch), 0, 113, 1, 1);
  182115. + if (sub_ch > 0)
  182116. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 113, 1, 1);
  182117. + stride = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14) + 1;
  182118. + /* ILO is 20-bit and 8-byte aligned */
  182119. + if (stride/8 > 0xfffff)
  182120. + dev_warn(ipu->dev,
  182121. + "IDMAC%d's ILO exceeds IPU limitation\n", ch);
  182122. + if (stride%8)
  182123. + dev_warn(ipu->dev,
  182124. + "IDMAC%d's ILO is not 8-byte aligned\n", ch);
  182125. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 58, 20, stride / 8);
  182126. + if (sub_ch > 0)
  182127. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 58, 20,
  182128. + stride / 8);
  182129. + stride *= 2;
  182130. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14, stride - 1);
  182131. + if (sub_ch > 0)
  182132. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 102, 14,
  182133. + stride - 1);
  182134. +};
  182135. +
  182136. +static inline void _ipu_ch_param_set_axi_id(struct ipu_soc *ipu, uint32_t ch, uint32_t id)
  182137. +{
  182138. + int32_t sub_ch = 0;
  182139. +
  182140. + id %= 4;
  182141. +
  182142. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 93, 2, id);
  182143. +
  182144. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182145. + if (sub_ch <= 0)
  182146. + return;
  182147. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 93, 2, id);
  182148. +};
  182149. +
  182150. +/* IDMAC U/V offset changing support */
  182151. +/* U and V input is not affected, */
  182152. +/* the update is done by new calculation according to */
  182153. +/* vertical_offset and horizontal_offset */
  182154. +static inline void _ipu_ch_offset_update(struct ipu_soc *ipu,
  182155. + int ch,
  182156. + uint32_t pixel_fmt,
  182157. + uint32_t width,
  182158. + uint32_t height,
  182159. + uint32_t stride,
  182160. + uint32_t u,
  182161. + uint32_t v,
  182162. + uint32_t uv_stride,
  182163. + uint32_t vertical_offset,
  182164. + uint32_t horizontal_offset)
  182165. +{
  182166. + uint32_t u_offset = 0;
  182167. + uint32_t v_offset = 0;
  182168. + uint32_t old_offset = 0;
  182169. + uint32_t u_fix = 0;
  182170. + uint32_t v_fix = 0;
  182171. + int32_t sub_ch = 0;
  182172. +
  182173. + switch (pixel_fmt) {
  182174. + case IPU_PIX_FMT_GENERIC:
  182175. + case IPU_PIX_FMT_GENERIC_16:
  182176. + case IPU_PIX_FMT_GENERIC_32:
  182177. + case IPU_PIX_FMT_RGB565:
  182178. + case IPU_PIX_FMT_BGR24:
  182179. + case IPU_PIX_FMT_RGB24:
  182180. + case IPU_PIX_FMT_YUV444:
  182181. + case IPU_PIX_FMT_BGRA32:
  182182. + case IPU_PIX_FMT_BGR32:
  182183. + case IPU_PIX_FMT_RGBA32:
  182184. + case IPU_PIX_FMT_RGB32:
  182185. + case IPU_PIX_FMT_ABGR32:
  182186. + case IPU_PIX_FMT_UYVY:
  182187. + case IPU_PIX_FMT_YUYV:
  182188. + break;
  182189. +
  182190. + case IPU_PIX_FMT_YUV420P2:
  182191. + case IPU_PIX_FMT_YUV420P:
  182192. + if (uv_stride < stride / 2)
  182193. + uv_stride = stride / 2;
  182194. +
  182195. + u_offset = stride * (height - vertical_offset - 1) +
  182196. + (stride - horizontal_offset) +
  182197. + (uv_stride * vertical_offset / 2) +
  182198. + horizontal_offset / 2;
  182199. + v_offset = u_offset + (uv_stride * height / 2);
  182200. + u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
  182201. + (horizontal_offset / 2) -
  182202. + (stride * vertical_offset) - (horizontal_offset)) :
  182203. + u_offset;
  182204. + v_fix = v ? (v + (uv_stride * vertical_offset / 2) +
  182205. + (horizontal_offset / 2) -
  182206. + (stride * vertical_offset) - (horizontal_offset)) :
  182207. + v_offset;
  182208. +
  182209. + break;
  182210. + case IPU_PIX_FMT_YVU420P:
  182211. + if (uv_stride < stride / 2)
  182212. + uv_stride = stride / 2;
  182213. +
  182214. + v_offset = stride * (height - vertical_offset - 1) +
  182215. + (stride - horizontal_offset) +
  182216. + (uv_stride * vertical_offset / 2) +
  182217. + horizontal_offset / 2;
  182218. + u_offset = v_offset + (uv_stride * height / 2);
  182219. + u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
  182220. + (horizontal_offset / 2) -
  182221. + (stride * vertical_offset) - (horizontal_offset)) :
  182222. + u_offset;
  182223. + v_fix = v ? (v + (uv_stride * vertical_offset / 2) +
  182224. + (horizontal_offset / 2) -
  182225. + (stride * vertical_offset) - (horizontal_offset)) :
  182226. + v_offset;
  182227. +
  182228. + break;
  182229. + case IPU_PIX_FMT_YVU422P:
  182230. + if (uv_stride < stride / 2)
  182231. + uv_stride = stride / 2;
  182232. +
  182233. + v_offset = stride * (height - vertical_offset - 1) +
  182234. + (stride - horizontal_offset) +
  182235. + (uv_stride * vertical_offset) +
  182236. + horizontal_offset / 2;
  182237. + u_offset = v_offset + uv_stride * height;
  182238. + u_fix = u ? (u + (uv_stride * vertical_offset) +
  182239. + horizontal_offset / 2 -
  182240. + (stride * vertical_offset) - (horizontal_offset)) :
  182241. + u_offset;
  182242. + v_fix = v ? (v + (uv_stride * vertical_offset) +
  182243. + horizontal_offset / 2 -
  182244. + (stride * vertical_offset) - (horizontal_offset)) :
  182245. + v_offset;
  182246. + break;
  182247. + case IPU_PIX_FMT_YUV422P:
  182248. + if (uv_stride < stride / 2)
  182249. + uv_stride = stride / 2;
  182250. +
  182251. + u_offset = stride * (height - vertical_offset - 1) +
  182252. + (stride - horizontal_offset) +
  182253. + (uv_stride * vertical_offset) +
  182254. + horizontal_offset / 2;
  182255. + v_offset = u_offset + uv_stride * height;
  182256. + u_fix = u ? (u + (uv_stride * vertical_offset) +
  182257. + horizontal_offset / 2 -
  182258. + (stride * vertical_offset) - (horizontal_offset)) :
  182259. + u_offset;
  182260. + v_fix = v ? (v + (uv_stride * vertical_offset) +
  182261. + horizontal_offset / 2 -
  182262. + (stride * vertical_offset) - (horizontal_offset)) :
  182263. + v_offset;
  182264. + break;
  182265. +
  182266. + case IPU_PIX_FMT_YUV444P:
  182267. + uv_stride = stride;
  182268. + u_offset = stride * (height - vertical_offset - 1) +
  182269. + (stride - horizontal_offset) +
  182270. + (uv_stride * vertical_offset) +
  182271. + horizontal_offset;
  182272. + v_offset = u_offset + uv_stride * height;
  182273. + u_fix = u ? (u + (uv_stride * vertical_offset) +
  182274. + horizontal_offset -
  182275. + (stride * vertical_offset) -
  182276. + (horizontal_offset)) :
  182277. + u_offset;
  182278. + v_fix = v ? (v + (uv_stride * vertical_offset) +
  182279. + horizontal_offset -
  182280. + (stride * vertical_offset) -
  182281. + (horizontal_offset)) :
  182282. + v_offset;
  182283. + break;
  182284. + case IPU_PIX_FMT_NV12:
  182285. + uv_stride = stride;
  182286. + u_offset = stride * (height - vertical_offset - 1) +
  182287. + (stride - horizontal_offset) +
  182288. + (uv_stride * vertical_offset / 2) +
  182289. + horizontal_offset;
  182290. + u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
  182291. + horizontal_offset -
  182292. + (stride * vertical_offset) - (horizontal_offset)) :
  182293. + u_offset;
  182294. +
  182295. + break;
  182296. + default:
  182297. + dev_err(ipu->dev, "mxc ipu: unimplemented pixel format\n");
  182298. + break;
  182299. + }
  182300. +
  182301. +
  182302. +
  182303. + if (u_fix > u_offset)
  182304. + u_offset = u_fix;
  182305. +
  182306. + if (v_fix > v_offset)
  182307. + v_offset = v_fix;
  182308. +
  182309. + /* UBO and VBO are 22-bit and 8-byte aligned */
  182310. + if (u_offset/8 > 0x3fffff)
  182311. + dev_warn(ipu->dev,
  182312. + "IDMAC%d's U offset exceeds IPU limitation\n", ch);
  182313. + if (v_offset/8 > 0x3fffff)
  182314. + dev_warn(ipu->dev,
  182315. + "IDMAC%d's V offset exceeds IPU limitation\n", ch);
  182316. + if (u_offset%8)
  182317. + dev_warn(ipu->dev,
  182318. + "IDMAC%d's U offset is not 8-byte aligned\n", ch);
  182319. + if (v_offset%8)
  182320. + dev_warn(ipu->dev,
  182321. + "IDMAC%d's V offset is not 8-byte aligned\n", ch);
  182322. +
  182323. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22);
  182324. + if (old_offset != u_offset / 8)
  182325. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22, u_offset / 8);
  182326. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22);
  182327. + if (old_offset != v_offset / 8)
  182328. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22, v_offset / 8);
  182329. +
  182330. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182331. + if (sub_ch <= 0)
  182332. + return;
  182333. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22);
  182334. + if (old_offset != u_offset / 8)
  182335. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22, u_offset / 8);
  182336. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22);
  182337. + if (old_offset != v_offset / 8)
  182338. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22, v_offset / 8);
  182339. +};
  182340. +
  182341. +static inline void _ipu_ch_params_set_alpha_width(struct ipu_soc *ipu, uint32_t ch, int alpha_width)
  182342. +{
  182343. + int32_t sub_ch = 0;
  182344. +
  182345. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch), 1, 125, 3, alpha_width - 1);
  182346. +
  182347. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182348. + if (sub_ch <= 0)
  182349. + return;
  182350. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 125, 3, alpha_width - 1);
  182351. +};
  182352. +
  182353. +static inline void _ipu_ch_param_set_bandmode(struct ipu_soc *ipu,
  182354. + uint32_t ch, uint32_t band_height)
  182355. +{
  182356. + int32_t sub_ch = 0;
  182357. +
  182358. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch),
  182359. + 0, 114, 3, band_height - 1);
  182360. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182361. + if (sub_ch <= 0)
  182362. + return;
  182363. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch),
  182364. + 0, 114, 3, band_height - 1);
  182365. +
  182366. + dev_dbg(ipu->dev, "BNDM 0x%x, ",
  182367. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 114, 3));
  182368. +}
  182369. +
  182370. +/*
  182371. + * The IPUv3 IDMAC has a bug to read 32bpp pixels from a graphics plane
  182372. + * whose alpha component is at the most significant 8 bits. The bug only
  182373. + * impacts on cases in which the relevant separate alpha channel is enabled.
  182374. + *
  182375. + * Return true on bad alpha component position, otherwise, return false.
  182376. + */
  182377. +static inline bool _ipu_ch_param_bad_alpha_pos(uint32_t pixel_fmt)
  182378. +{
  182379. + switch (pixel_fmt) {
  182380. + case IPU_PIX_FMT_BGRA32:
  182381. + case IPU_PIX_FMT_BGR32:
  182382. + case IPU_PIX_FMT_RGBA32:
  182383. + case IPU_PIX_FMT_RGB32:
  182384. + return true;
  182385. + }
  182386. +
  182387. + return false;
  182388. +}
  182389. +#endif
  182390. diff -Nur linux-3.14.15/drivers/mxc/ipu3/ipu_pixel_clk.c linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_pixel_clk.c
  182391. --- linux-3.14.15/drivers/mxc/ipu3/ipu_pixel_clk.c 1970-01-01 01:00:00.000000000 +0100
  182392. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_pixel_clk.c 2014-08-20 19:23:53.574845907 +0200
  182393. @@ -0,0 +1,317 @@
  182394. +/*
  182395. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  182396. + */
  182397. +
  182398. +/*
  182399. + * The code contained herein is licensed under the GNU General Public
  182400. + * License. You may obtain a copy of the GNU General Public License
  182401. + * Version 2 or later at the following locations:
  182402. + *
  182403. + * http://www.opensource.org/licenses/gpl-license.html
  182404. + * http://www.gnu.org/copyleft/gpl.html
  182405. + */
  182406. +
  182407. +/*!
  182408. + * @file ipu_pixel_clk.c
  182409. + *
  182410. + * @brief IPU pixel clock implementation
  182411. + *
  182412. + * @ingroup IPU
  182413. + */
  182414. +
  182415. +#include <linux/clk-provider.h>
  182416. +#include <linux/err.h>
  182417. +#include <linux/io.h>
  182418. +#include <linux/ipu-v3.h>
  182419. +#include <linux/module.h>
  182420. +#include <linux/slab.h>
  182421. +#include <linux/string.h>
  182422. +
  182423. +#include "ipu_prv.h"
  182424. +#include "ipu_regs.h"
  182425. +
  182426. + /*
  182427. + * muxd clock implementation
  182428. + */
  182429. +struct clk_di_mux {
  182430. + struct clk_hw hw;
  182431. + u8 ipu_id;
  182432. + u8 di_id;
  182433. + u8 flags;
  182434. + u8 index;
  182435. +};
  182436. +#define to_clk_di_mux(_hw) container_of(_hw, struct clk_di_mux, hw)
  182437. +
  182438. +static int _ipu_pixel_clk_set_parent(struct clk_hw *hw, u8 index)
  182439. +{
  182440. + struct clk_di_mux *mux = to_clk_di_mux(hw);
  182441. + struct ipu_soc *ipu = ipu_get_soc(mux->ipu_id);
  182442. + u32 di_gen;
  182443. +
  182444. + di_gen = ipu_di_read(ipu, mux->di_id, DI_GENERAL);
  182445. + if (index == 0)
  182446. + /* ipu1_clk or ipu2_clk internal clk */
  182447. + di_gen &= ~DI_GEN_DI_CLK_EXT;
  182448. + else
  182449. + di_gen |= DI_GEN_DI_CLK_EXT;
  182450. +
  182451. + ipu_di_write(ipu, mux->di_id, di_gen, DI_GENERAL);
  182452. + mux->index = index;
  182453. + pr_debug("ipu_pixel_clk: di_clk_ext:0x%x, di_gen reg:0x%x.\n",
  182454. + !(di_gen & DI_GEN_DI_CLK_EXT), di_gen);
  182455. + return 0;
  182456. +}
  182457. +
  182458. +static u8 _ipu_pixel_clk_get_parent(struct clk_hw *hw)
  182459. +{
  182460. + struct clk_di_mux *mux = to_clk_di_mux(hw);
  182461. +
  182462. + return mux->index;
  182463. +}
  182464. +
  182465. +const struct clk_ops clk_mux_di_ops = {
  182466. + .get_parent = _ipu_pixel_clk_get_parent,
  182467. + .set_parent = _ipu_pixel_clk_set_parent,
  182468. +};
  182469. +
  182470. +struct clk *clk_register_mux_pix_clk(struct device *dev, const char *name,
  182471. + const char **parent_names, u8 num_parents, unsigned long flags,
  182472. + u8 ipu_id, u8 di_id, u8 clk_mux_flags)
  182473. +{
  182474. + struct clk_di_mux *mux;
  182475. + struct clk *clk;
  182476. + struct clk_init_data init;
  182477. +
  182478. + mux = kzalloc(sizeof(struct clk_di_mux), GFP_KERNEL);
  182479. + if (!mux)
  182480. + return ERR_PTR(-ENOMEM);
  182481. +
  182482. + init.name = name;
  182483. + init.ops = &clk_mux_di_ops;
  182484. + init.flags = flags;
  182485. + init.parent_names = parent_names;
  182486. + init.num_parents = num_parents;
  182487. +
  182488. + mux->ipu_id = ipu_id;
  182489. + mux->di_id = di_id;
  182490. + mux->flags = clk_mux_flags | CLK_SET_RATE_PARENT;
  182491. + mux->hw.init = &init;
  182492. +
  182493. + clk = clk_register(dev, &mux->hw);
  182494. + if (IS_ERR(clk))
  182495. + kfree(mux);
  182496. +
  182497. + return clk;
  182498. +}
  182499. +
  182500. +/*
  182501. + * Gated clock implementation
  182502. + */
  182503. +struct clk_di_div {
  182504. + struct clk_hw hw;
  182505. + u8 ipu_id;
  182506. + u8 di_id;
  182507. + u8 flags;
  182508. +};
  182509. +#define to_clk_di_div(_hw) container_of(_hw, struct clk_di_div, hw)
  182510. +
  182511. +static unsigned long _ipu_pixel_clk_div_recalc_rate(struct clk_hw *hw,
  182512. + unsigned long parent_rate)
  182513. +{
  182514. + struct clk_di_div *di_div = to_clk_di_div(hw);
  182515. + struct ipu_soc *ipu = ipu_get_soc(di_div->ipu_id);
  182516. + u32 div;
  182517. + u64 final_rate = (unsigned long long)parent_rate * 16;
  182518. +
  182519. + _ipu_get(ipu);
  182520. + div = ipu_di_read(ipu, di_div->di_id, DI_BS_CLKGEN0);
  182521. + _ipu_put(ipu);
  182522. + pr_debug("ipu_di%d read BS_CLKGEN0 div:%d, final_rate:%lld, prate:%ld\n",
  182523. + di_div->di_id, div, final_rate, parent_rate);
  182524. +
  182525. + if (div == 0)
  182526. + return 0;
  182527. + do_div(final_rate, div);
  182528. +
  182529. + return (unsigned long)final_rate;
  182530. +}
  182531. +
  182532. +static long _ipu_pixel_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
  182533. + unsigned long *parent_clk_rate)
  182534. +{
  182535. + u64 div, final_rate;
  182536. + u32 remainder;
  182537. + u64 parent_rate = (unsigned long long)(*parent_clk_rate) * 16;
  182538. +
  182539. + /*
  182540. + * Calculate divider
  182541. + * Fractional part is 4 bits,
  182542. + * so simply multiply by 2^4 to get fractional part.
  182543. + */
  182544. + div = parent_rate;
  182545. + remainder = do_div(div, rate);
  182546. + /* Round the divider value */
  182547. + if (remainder > (rate/2))
  182548. + div++;
  182549. + if (div < 0x10) /* Min DI disp clock divider is 1 */
  182550. + div = 0x10;
  182551. + if (div & ~0xFEF)
  182552. + div &= 0xFF8;
  182553. + else {
  182554. + /* Round up divider if it gets us closer to desired pix clk */
  182555. + if ((div & 0xC) == 0xC) {
  182556. + div += 0x10;
  182557. + div &= ~0xF;
  182558. + }
  182559. + }
  182560. + final_rate = parent_rate;
  182561. + do_div(final_rate, div);
  182562. +
  182563. + return final_rate;
  182564. +}
  182565. +
  182566. +static int _ipu_pixel_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
  182567. + unsigned long parent_clk_rate)
  182568. +{
  182569. + struct clk_di_div *di_div = to_clk_di_div(hw);
  182570. + struct ipu_soc *ipu = ipu_get_soc(di_div->ipu_id);
  182571. + u64 div, parent_rate;
  182572. + u32 remainder;
  182573. +
  182574. + parent_rate = (unsigned long long)parent_clk_rate * 16;
  182575. + div = parent_rate;
  182576. + remainder = do_div(div, rate);
  182577. + /* Round the divider value */
  182578. + if (remainder > (rate/2))
  182579. + div++;
  182580. +
  182581. + /* Round up divider if it gets us closer to desired pix clk */
  182582. + if ((div & 0xC) == 0xC) {
  182583. + div += 0x10;
  182584. + div &= ~0xF;
  182585. + }
  182586. + if (div > 0x1000)
  182587. + pr_err("Overflow, di:%d, DI_BS_CLKGEN0 div:0x%x\n",
  182588. + di_div->di_id, (u32)div);
  182589. + _ipu_get(ipu);
  182590. + ipu_di_write(ipu, di_div->di_id, (u32)div, DI_BS_CLKGEN0);
  182591. +
  182592. + /* Setup pixel clock timing */
  182593. + /* FIXME: needs to be more flexible */
  182594. + /* Down time is half of period */
  182595. + ipu_di_write(ipu, di_div->di_id, ((u32)div / 16) << 16, DI_BS_CLKGEN1);
  182596. + _ipu_put(ipu);
  182597. +
  182598. + return 0;
  182599. +}
  182600. +
  182601. +static struct clk_ops clk_div_ops = {
  182602. + .recalc_rate = _ipu_pixel_clk_div_recalc_rate,
  182603. + .round_rate = _ipu_pixel_clk_div_round_rate,
  182604. + .set_rate = _ipu_pixel_clk_div_set_rate,
  182605. +};
  182606. +
  182607. +struct clk *clk_register_div_pix_clk(struct device *dev, const char *name,
  182608. + const char *parent_name, unsigned long flags,
  182609. + u8 ipu_id, u8 di_id, u8 clk_div_flags)
  182610. +{
  182611. + struct clk_di_div *di_div;
  182612. + struct clk *clk;
  182613. + struct clk_init_data init;
  182614. +
  182615. + di_div = kzalloc(sizeof(struct clk_di_div), GFP_KERNEL);
  182616. + if (!di_div)
  182617. + return ERR_PTR(-ENOMEM);
  182618. +
  182619. + /* struct clk_di_div assignments */
  182620. + di_div->ipu_id = ipu_id;
  182621. + di_div->di_id = di_id;
  182622. + di_div->flags = clk_div_flags;
  182623. +
  182624. + init.name = name;
  182625. + init.ops = &clk_div_ops;
  182626. + init.flags = flags | CLK_SET_RATE_PARENT;
  182627. + init.parent_names = parent_name ? &parent_name : NULL;
  182628. + init.num_parents = parent_name ? 1 : 0;
  182629. +
  182630. + di_div->hw.init = &init;
  182631. +
  182632. + clk = clk_register(dev, &di_div->hw);
  182633. + if (IS_ERR(clk))
  182634. + kfree(clk);
  182635. +
  182636. + return clk;
  182637. +}
  182638. +
  182639. +/*
  182640. + * Gated clock implementation
  182641. + */
  182642. +struct clk_di_gate {
  182643. + struct clk_hw hw;
  182644. + u8 ipu_id;
  182645. + u8 di_id;
  182646. + u8 flags;
  182647. +};
  182648. +#define to_clk_di_gate(_hw) container_of(_hw, struct clk_di_gate, hw)
  182649. +
  182650. +static int _ipu_pixel_clk_enable(struct clk_hw *hw)
  182651. +{
  182652. + struct clk_di_gate *gate = to_clk_di_gate(hw);
  182653. + struct ipu_soc *ipu = ipu_get_soc(gate->ipu_id);
  182654. + u32 disp_gen;
  182655. +
  182656. + disp_gen = ipu_cm_read(ipu, IPU_DISP_GEN);
  182657. + disp_gen |= gate->di_id ? DI1_COUNTER_RELEASE : DI0_COUNTER_RELEASE;
  182658. + ipu_cm_write(ipu, disp_gen, IPU_DISP_GEN);
  182659. +
  182660. + return 0;
  182661. +}
  182662. +
  182663. +static void _ipu_pixel_clk_disable(struct clk_hw *hw)
  182664. +{
  182665. + struct clk_di_gate *gate = to_clk_di_gate(hw);
  182666. + struct ipu_soc *ipu = ipu_get_soc(gate->ipu_id);
  182667. + u32 disp_gen;
  182668. +
  182669. + disp_gen = ipu_cm_read(ipu, IPU_DISP_GEN);
  182670. + disp_gen &= gate->di_id ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE;
  182671. + ipu_cm_write(ipu, disp_gen, IPU_DISP_GEN);
  182672. +
  182673. +}
  182674. +
  182675. +
  182676. +static struct clk_ops clk_gate_di_ops = {
  182677. + .enable = _ipu_pixel_clk_enable,
  182678. + .disable = _ipu_pixel_clk_disable,
  182679. +};
  182680. +
  182681. +struct clk *clk_register_gate_pix_clk(struct device *dev, const char *name,
  182682. + const char *parent_name, unsigned long flags,
  182683. + u8 ipu_id, u8 di_id, u8 clk_gate_flags)
  182684. +{
  182685. + struct clk_di_gate *gate;
  182686. + struct clk *clk;
  182687. + struct clk_init_data init;
  182688. +
  182689. + gate = kzalloc(sizeof(struct clk_di_gate), GFP_KERNEL);
  182690. + if (!gate)
  182691. + return ERR_PTR(-ENOMEM);
  182692. +
  182693. + gate->ipu_id = ipu_id;
  182694. + gate->di_id = di_id;
  182695. + gate->flags = clk_gate_flags;
  182696. +
  182697. + init.name = name;
  182698. + init.ops = &clk_gate_di_ops;
  182699. + init.flags = flags | CLK_SET_RATE_PARENT;
  182700. + init.parent_names = parent_name ? &parent_name : NULL;
  182701. + init.num_parents = parent_name ? 1 : 0;
  182702. +
  182703. + gate->hw.init = &init;
  182704. +
  182705. + clk = clk_register(dev, &gate->hw);
  182706. + if (IS_ERR(clk))
  182707. + kfree(clk);
  182708. +
  182709. + return clk;
  182710. +}
  182711. diff -Nur linux-3.14.15/drivers/mxc/ipu3/ipu_prv.h linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_prv.h
  182712. --- linux-3.14.15/drivers/mxc/ipu3/ipu_prv.h 1970-01-01 01:00:00.000000000 +0100
  182713. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_prv.h 2014-08-20 19:31:46.140869056 +0200
  182714. @@ -0,0 +1,356 @@
  182715. +/*
  182716. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  182717. + */
  182718. +
  182719. +/*
  182720. + * The code contained herein is licensed under the GNU General Public
  182721. + * License. You may obtain a copy of the GNU General Public License
  182722. + * Version 2 or later at the following locations:
  182723. + *
  182724. + * http://www.opensource.org/licenses/gpl-license.html
  182725. + * http://www.gnu.org/copyleft/gpl.html
  182726. + */
  182727. +#ifndef __INCLUDE_IPU_PRV_H__
  182728. +#define __INCLUDE_IPU_PRV_H__
  182729. +
  182730. +#include <linux/clkdev.h>
  182731. +#include <linux/device.h>
  182732. +#include <linux/fsl_devices.h>
  182733. +#include <linux/interrupt.h>
  182734. +#include <linux/types.h>
  182735. +
  182736. +#define MXC_IPU_MAX_NUM 2
  182737. +#define MXC_DI_NUM_PER_IPU 2
  182738. +
  182739. +/* Globals */
  182740. +extern int dmfc_type_setup;
  182741. +
  182742. +#define IDMA_CHAN_INVALID 0xFF
  182743. +#define HIGH_RESOLUTION_WIDTH 1024
  182744. +
  182745. +struct ipu_irq_node {
  182746. + irqreturn_t(*handler) (int, void *); /*!< the ISR */
  182747. + const char *name; /*!< device associated with the interrupt */
  182748. + void *dev_id; /*!< some unique information for the ISR */
  182749. + __u32 flags; /*!< not used */
  182750. +};
  182751. +
  182752. +enum csc_type_t {
  182753. + RGB2YUV = 0,
  182754. + YUV2RGB,
  182755. + RGB2RGB,
  182756. + YUV2YUV,
  182757. + CSC_NONE,
  182758. + CSC_NUM
  182759. +};
  182760. +
  182761. +enum imx_ipu_type {
  182762. + IMX6Q_IPU,
  182763. +};
  182764. +
  182765. +struct ipu_pltfm_data {
  182766. + u32 id;
  182767. + u32 devtype;
  182768. + int (*init) (int);
  182769. + void (*pg) (int);
  182770. +
  182771. + /*
  182772. + * Bypass reset to avoid display channel being
  182773. + * stopped by probe since it may starts to work
  182774. + * in bootloader.
  182775. + */
  182776. + bool bypass_reset;
  182777. +};
  182778. +
  182779. +struct ipu_soc {
  182780. + bool online;
  182781. + struct ipu_pltfm_data *pdata;
  182782. +
  182783. + /*clk*/
  182784. + struct clk *ipu_clk;
  182785. + struct clk *di_clk[2];
  182786. + struct clk *di_clk_sel[2];
  182787. + struct clk *pixel_clk[2];
  182788. + struct clk *pixel_clk_sel[2];
  182789. + struct clk *csi_clk[2];
  182790. +
  182791. + /*irq*/
  182792. + int irq_sync;
  182793. + int irq_err;
  182794. + struct ipu_irq_node irq_list[IPU_IRQ_COUNT];
  182795. +
  182796. + /*reg*/
  182797. + void __iomem *cm_reg;
  182798. + void __iomem *idmac_reg;
  182799. + void __iomem *dp_reg;
  182800. + void __iomem *ic_reg;
  182801. + void __iomem *dc_reg;
  182802. + void __iomem *dc_tmpl_reg;
  182803. + void __iomem *dmfc_reg;
  182804. + void __iomem *di_reg[2];
  182805. + void __iomem *smfc_reg;
  182806. + void __iomem *csi_reg[2];
  182807. + void __iomem *cpmem_base;
  182808. + void __iomem *tpmem_base;
  182809. + void __iomem *disp_base[2];
  182810. + void __iomem *vdi_reg;
  182811. +
  182812. + struct device *dev;
  182813. +
  182814. + ipu_channel_t csi_channel[2];
  182815. + ipu_channel_t using_ic_dirct_ch;
  182816. + unsigned char dc_di_assignment[10];
  182817. + bool sec_chan_en[24];
  182818. + bool thrd_chan_en[24];
  182819. + bool chan_is_interlaced[52];
  182820. + uint32_t channel_init_mask;
  182821. + uint32_t channel_enable_mask;
  182822. +
  182823. + /*use count*/
  182824. + int dc_use_count;
  182825. + int dp_use_count;
  182826. + int dmfc_use_count;
  182827. + int smfc_use_count;
  182828. + int ic_use_count;
  182829. + int rot_use_count;
  182830. + int vdi_use_count;
  182831. + int di_use_count[2];
  182832. + int csi_use_count[2];
  182833. +
  182834. + struct mutex mutex_lock;
  182835. + spinlock_t int_reg_spin_lock;
  182836. + spinlock_t rdy_reg_spin_lock;
  182837. +
  182838. + int dmfc_size_28;
  182839. + int dmfc_size_29;
  182840. + int dmfc_size_24;
  182841. + int dmfc_size_27;
  182842. + int dmfc_size_23;
  182843. +
  182844. + enum csc_type_t fg_csc_type;
  182845. + enum csc_type_t bg_csc_type;
  182846. + bool color_key_4rgb;
  182847. + bool dc_swap;
  182848. + struct completion dc_comp;
  182849. + struct completion csi_comp;
  182850. +
  182851. + struct rot_mem {
  182852. + void *vaddr;
  182853. + dma_addr_t paddr;
  182854. + int size;
  182855. + } rot_dma[2];
  182856. +
  182857. + int vdoa_en;
  182858. + struct task_struct *thread[2];
  182859. +
  182860. +};
  182861. +
  182862. +struct ipu_channel {
  182863. + u8 video_in_dma;
  182864. + u8 alpha_in_dma;
  182865. + u8 graph_in_dma;
  182866. + u8 out_dma;
  182867. +};
  182868. +
  182869. +enum ipu_dmfc_type {
  182870. + DMFC_NORMAL = 0,
  182871. + DMFC_HIGH_RESOLUTION_DC,
  182872. + DMFC_HIGH_RESOLUTION_DP,
  182873. + DMFC_HIGH_RESOLUTION_ONLY_DP,
  182874. +};
  182875. +
  182876. +static inline u32 ipu_cm_read(struct ipu_soc *ipu, unsigned offset)
  182877. +{
  182878. + return readl(ipu->cm_reg + offset);
  182879. +}
  182880. +
  182881. +static inline void ipu_cm_write(struct ipu_soc *ipu,
  182882. + u32 value, unsigned offset)
  182883. +{
  182884. + writel(value, ipu->cm_reg + offset);
  182885. +}
  182886. +
  182887. +static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset)
  182888. +{
  182889. + return readl(ipu->idmac_reg + offset);
  182890. +}
  182891. +
  182892. +static inline void ipu_idmac_write(struct ipu_soc *ipu,
  182893. + u32 value, unsigned offset)
  182894. +{
  182895. + writel(value, ipu->idmac_reg + offset);
  182896. +}
  182897. +
  182898. +static inline u32 ipu_dc_read(struct ipu_soc *ipu, unsigned offset)
  182899. +{
  182900. + return readl(ipu->dc_reg + offset);
  182901. +}
  182902. +
  182903. +static inline void ipu_dc_write(struct ipu_soc *ipu,
  182904. + u32 value, unsigned offset)
  182905. +{
  182906. + writel(value, ipu->dc_reg + offset);
  182907. +}
  182908. +
  182909. +static inline u32 ipu_dc_tmpl_read(struct ipu_soc *ipu, unsigned offset)
  182910. +{
  182911. + return readl(ipu->dc_tmpl_reg + offset);
  182912. +}
  182913. +
  182914. +static inline void ipu_dc_tmpl_write(struct ipu_soc *ipu,
  182915. + u32 value, unsigned offset)
  182916. +{
  182917. + writel(value, ipu->dc_tmpl_reg + offset);
  182918. +}
  182919. +
  182920. +static inline u32 ipu_dmfc_read(struct ipu_soc *ipu, unsigned offset)
  182921. +{
  182922. + return readl(ipu->dmfc_reg + offset);
  182923. +}
  182924. +
  182925. +static inline void ipu_dmfc_write(struct ipu_soc *ipu,
  182926. + u32 value, unsigned offset)
  182927. +{
  182928. + writel(value, ipu->dmfc_reg + offset);
  182929. +}
  182930. +
  182931. +static inline u32 ipu_dp_read(struct ipu_soc *ipu, unsigned offset)
  182932. +{
  182933. + return readl(ipu->dp_reg + offset);
  182934. +}
  182935. +
  182936. +static inline void ipu_dp_write(struct ipu_soc *ipu,
  182937. + u32 value, unsigned offset)
  182938. +{
  182939. + writel(value, ipu->dp_reg + offset);
  182940. +}
  182941. +
  182942. +static inline u32 ipu_di_read(struct ipu_soc *ipu, int di, unsigned offset)
  182943. +{
  182944. + return readl(ipu->di_reg[di] + offset);
  182945. +}
  182946. +
  182947. +static inline void ipu_di_write(struct ipu_soc *ipu, int di,
  182948. + u32 value, unsigned offset)
  182949. +{
  182950. + writel(value, ipu->di_reg[di] + offset);
  182951. +}
  182952. +
  182953. +static inline u32 ipu_csi_read(struct ipu_soc *ipu, int csi, unsigned offset)
  182954. +{
  182955. + return readl(ipu->csi_reg[csi] + offset);
  182956. +}
  182957. +
  182958. +static inline void ipu_csi_write(struct ipu_soc *ipu, int csi,
  182959. + u32 value, unsigned offset)
  182960. +{
  182961. + writel(value, ipu->csi_reg[csi] + offset);
  182962. +}
  182963. +
  182964. +static inline u32 ipu_smfc_read(struct ipu_soc *ipu, unsigned offset)
  182965. +{
  182966. + return readl(ipu->smfc_reg + offset);
  182967. +}
  182968. +
  182969. +static inline void ipu_smfc_write(struct ipu_soc *ipu,
  182970. + u32 value, unsigned offset)
  182971. +{
  182972. + writel(value, ipu->smfc_reg + offset);
  182973. +}
  182974. +
  182975. +static inline u32 ipu_vdi_read(struct ipu_soc *ipu, unsigned offset)
  182976. +{
  182977. + return readl(ipu->vdi_reg + offset);
  182978. +}
  182979. +
  182980. +static inline void ipu_vdi_write(struct ipu_soc *ipu,
  182981. + u32 value, unsigned offset)
  182982. +{
  182983. + writel(value, ipu->vdi_reg + offset);
  182984. +}
  182985. +
  182986. +static inline u32 ipu_ic_read(struct ipu_soc *ipu, unsigned offset)
  182987. +{
  182988. + return readl(ipu->ic_reg + offset);
  182989. +}
  182990. +
  182991. +static inline void ipu_ic_write(struct ipu_soc *ipu,
  182992. + u32 value, unsigned offset)
  182993. +{
  182994. + writel(value, ipu->ic_reg + offset);
  182995. +}
  182996. +
  182997. +int register_ipu_device(struct ipu_soc *ipu, int id);
  182998. +void unregister_ipu_device(struct ipu_soc *ipu, int id);
  182999. +ipu_color_space_t format_to_colorspace(uint32_t fmt);
  183000. +bool ipu_pixel_format_has_alpha(uint32_t fmt);
  183001. +
  183002. +void ipu_dump_registers(struct ipu_soc *ipu);
  183003. +
  183004. +uint32_t _ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel);
  183005. +
  183006. +void ipu_disp_init(struct ipu_soc *ipu);
  183007. +void _ipu_init_dc_mappings(struct ipu_soc *ipu);
  183008. +int _ipu_dp_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t in_pixel_fmt,
  183009. + uint32_t out_pixel_fmt);
  183010. +void _ipu_dp_uninit(struct ipu_soc *ipu, ipu_channel_t channel);
  183011. +void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt);
  183012. +void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan);
  183013. +void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel);
  183014. +void _ipu_dp_dc_disable(struct ipu_soc *ipu, ipu_channel_t channel, bool swap);
  183015. +void _ipu_dmfc_init(struct ipu_soc *ipu, int dmfc_type, int first);
  183016. +void _ipu_dmfc_set_wait4eot(struct ipu_soc *ipu, int dma_chan, int width);
  183017. +void _ipu_dmfc_set_burst_size(struct ipu_soc *ipu, int dma_chan, int burst_size);
  183018. +int _ipu_disp_chan_is_interlaced(struct ipu_soc *ipu, ipu_channel_t channel);
  183019. +
  183020. +void _ipu_ic_enable_task(struct ipu_soc *ipu, ipu_channel_t channel);
  183021. +void _ipu_ic_disable_task(struct ipu_soc *ipu, ipu_channel_t channel);
  183022. +int _ipu_ic_init_prpvf(struct ipu_soc *ipu, ipu_channel_params_t *params,
  183023. + bool src_is_csi);
  183024. +void _ipu_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params);
  183025. +void _ipu_vdi_uninit(struct ipu_soc *ipu);
  183026. +void _ipu_ic_uninit_prpvf(struct ipu_soc *ipu);
  183027. +void _ipu_ic_init_rotate_vf(struct ipu_soc *ipu, ipu_channel_params_t *params);
  183028. +void _ipu_ic_uninit_rotate_vf(struct ipu_soc *ipu);
  183029. +void _ipu_ic_init_csi(struct ipu_soc *ipu, ipu_channel_params_t *params);
  183030. +void _ipu_ic_uninit_csi(struct ipu_soc *ipu);
  183031. +int _ipu_ic_init_prpenc(struct ipu_soc *ipu, ipu_channel_params_t *params,
  183032. + bool src_is_csi);
  183033. +void _ipu_ic_uninit_prpenc(struct ipu_soc *ipu);
  183034. +void _ipu_ic_init_rotate_enc(struct ipu_soc *ipu, ipu_channel_params_t *params);
  183035. +void _ipu_ic_uninit_rotate_enc(struct ipu_soc *ipu);
  183036. +int _ipu_ic_init_pp(struct ipu_soc *ipu, ipu_channel_params_t *params);
  183037. +void _ipu_ic_uninit_pp(struct ipu_soc *ipu);
  183038. +void _ipu_ic_init_rotate_pp(struct ipu_soc *ipu, ipu_channel_params_t *params);
  183039. +void _ipu_ic_uninit_rotate_pp(struct ipu_soc *ipu);
  183040. +int _ipu_ic_idma_init(struct ipu_soc *ipu, int dma_chan, uint16_t width, uint16_t height,
  183041. + int burst_size, ipu_rotate_mode_t rot);
  183042. +void _ipu_vdi_toggle_top_field_man(struct ipu_soc *ipu);
  183043. +int _ipu_csi_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t csi);
  183044. +int _ipu_csi_set_mipi_di(struct ipu_soc *ipu, uint32_t num, uint32_t di_val, uint32_t csi);
  183045. +void ipu_csi_set_test_generator(struct ipu_soc *ipu, bool active, uint32_t r_value,
  183046. + uint32_t g_value, uint32_t b_value,
  183047. + uint32_t pix_clk, uint32_t csi);
  183048. +void _ipu_csi_ccir_err_detection_enable(struct ipu_soc *ipu, uint32_t csi);
  183049. +void _ipu_csi_ccir_err_detection_disable(struct ipu_soc *ipu, uint32_t csi);
  183050. +void _ipu_csi_wait4eof(struct ipu_soc *ipu, ipu_channel_t channel);
  183051. +void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi);
  183052. +void _ipu_smfc_set_burst_size(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t bs);
  183053. +void _ipu_dp_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]);
  183054. +int32_t _ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  183055. + int16_t x_pos, int16_t y_pos);
  183056. +int32_t _ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  183057. + int16_t *x_pos, int16_t *y_pos);
  183058. +void _ipu_get(struct ipu_soc *ipu);
  183059. +void _ipu_put(struct ipu_soc *ipu);
  183060. +
  183061. +struct clk *clk_register_mux_pix_clk(struct device *dev, const char *name,
  183062. + const char **parent_names, u8 num_parents, unsigned long flags,
  183063. + u8 ipu_id, u8 di_id, u8 clk_mux_flags);
  183064. +struct clk *clk_register_div_pix_clk(struct device *dev, const char *name,
  183065. + const char *parent_name, unsigned long flags,
  183066. + u8 ipu_id, u8 di_id, u8 clk_div_flags);
  183067. +struct clk *clk_register_gate_pix_clk(struct device *dev, const char *name,
  183068. + const char *parent_name, unsigned long flags,
  183069. + u8 ipu_id, u8 di_id, u8 clk_gate_flags);
  183070. +#endif /* __INCLUDE_IPU_PRV_H__ */
  183071. diff -Nur linux-3.14.15/drivers/mxc/ipu3/ipu_regs.h linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_regs.h
  183072. --- linux-3.14.15/drivers/mxc/ipu3/ipu_regs.h 1970-01-01 01:00:00.000000000 +0100
  183073. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/ipu_regs.h 2014-08-20 19:31:46.140869056 +0200
  183074. @@ -0,0 +1,743 @@
  183075. +/*
  183076. + * Copyright (C) 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  183077. + */
  183078. +
  183079. +/*
  183080. + * The code contained herein is licensed under the GNU General Public
  183081. + * License. You may obtain a copy of the GNU General Public License
  183082. + * Version 2 or later at the following locations:
  183083. + *
  183084. + * http://www.opensource.org/licenses/gpl-license.html
  183085. + * http://www.gnu.org/copyleft/gpl.html
  183086. + */
  183087. +
  183088. +/*
  183089. + * @file ipu_regs.h
  183090. + *
  183091. + * @brief IPU Register definitions
  183092. + *
  183093. + * @ingroup IPU
  183094. + */
  183095. +#ifndef __IPU_REGS_INCLUDED__
  183096. +#define __IPU_REGS_INCLUDED__
  183097. +
  183098. +enum imx_ipu_rev {
  183099. + IPU_V3DEX = 2,
  183100. + IPU_V3M,
  183101. + IPU_V3H,
  183102. +};
  183103. +
  183104. +/*
  183105. + * hw_rev 2: IPUV3DEX
  183106. + * hw_rev 3: IPUV3M
  183107. + * hw_rev 4: IPUV3H
  183108. + */
  183109. +extern int g_ipu_hw_rev;
  183110. +
  183111. +#define IPU_MAX_VDI_IN_WIDTH ({g_ipu_hw_rev >= 3 ? \
  183112. + (968) : \
  183113. + (720); })
  183114. +#define IPU_DISP0_BASE 0x00000000
  183115. +#define IPU_MCU_T_DEFAULT 8
  183116. +#define IPU_DISP1_BASE ({g_ipu_hw_rev < 4 ? \
  183117. + (IPU_MCU_T_DEFAULT << 25) : \
  183118. + (0x00000000); })
  183119. +#define IPUV3DEX_REG_BASE 0x1E000000
  183120. +#define IPUV3M_REG_BASE 0x06000000
  183121. +#define IPUV3H_REG_BASE 0x00200000
  183122. +
  183123. +#define IPU_CM_REG_BASE 0x00000000
  183124. +#define IPU_IDMAC_REG_BASE 0x00008000
  183125. +#define IPU_ISP_REG_BASE 0x00010000
  183126. +#define IPU_DP_REG_BASE 0x00018000
  183127. +#define IPU_IC_REG_BASE 0x00020000
  183128. +#define IPU_IRT_REG_BASE 0x00028000
  183129. +#define IPU_CSI0_REG_BASE 0x00030000
  183130. +#define IPU_CSI1_REG_BASE 0x00038000
  183131. +#define IPU_DI0_REG_BASE 0x00040000
  183132. +#define IPU_DI1_REG_BASE 0x00048000
  183133. +#define IPU_SMFC_REG_BASE 0x00050000
  183134. +#define IPU_DC_REG_BASE 0x00058000
  183135. +#define IPU_DMFC_REG_BASE 0x00060000
  183136. +#define IPU_VDI_REG_BASE 0x00068000
  183137. +#define IPU_CPMEM_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  183138. + (0x00100000) : \
  183139. + (0x01000000); })
  183140. +#define IPU_LUT_REG_BASE 0x01020000
  183141. +#define IPU_SRM_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  183142. + (0x00140000) : \
  183143. + (0x01040000); })
  183144. +#define IPU_TPM_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  183145. + (0x00160000) : \
  183146. + (0x01060000); })
  183147. +#define IPU_DC_TMPL_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  183148. + (0x00180000) : \
  183149. + (0x01080000); })
  183150. +#define IPU_ISP_TBPR_REG_BASE 0x010C0000
  183151. +
  183152. +/* Register addresses */
  183153. +/* IPU Common registers */
  183154. +#define IPU_CM_REG(offset) (offset)
  183155. +
  183156. +#define IPU_CONF IPU_CM_REG(0)
  183157. +#define IPU_SRM_PRI1 IPU_CM_REG(0x00A0)
  183158. +#define IPU_SRM_PRI2 IPU_CM_REG(0x00A4)
  183159. +#define IPU_FS_PROC_FLOW1 IPU_CM_REG(0x00A8)
  183160. +#define IPU_FS_PROC_FLOW2 IPU_CM_REG(0x00AC)
  183161. +#define IPU_FS_PROC_FLOW3 IPU_CM_REG(0x00B0)
  183162. +#define IPU_FS_DISP_FLOW1 IPU_CM_REG(0x00B4)
  183163. +#define IPU_FS_DISP_FLOW2 IPU_CM_REG(0x00B8)
  183164. +#define IPU_SKIP IPU_CM_REG(0x00BC)
  183165. +#define IPU_DISP_ALT_CONF IPU_CM_REG(0x00C0)
  183166. +#define IPU_DISP_GEN IPU_CM_REG(0x00C4)
  183167. +#define IPU_DISP_ALT1 IPU_CM_REG(0x00C8)
  183168. +#define IPU_DISP_ALT2 IPU_CM_REG(0x00CC)
  183169. +#define IPU_DISP_ALT3 IPU_CM_REG(0x00D0)
  183170. +#define IPU_DISP_ALT4 IPU_CM_REG(0x00D4)
  183171. +#define IPU_SNOOP IPU_CM_REG(0x00D8)
  183172. +#define IPU_MEM_RST IPU_CM_REG(0x00DC)
  183173. +#define IPU_PM IPU_CM_REG(0x00E0)
  183174. +#define IPU_GPR IPU_CM_REG(0x00E4)
  183175. +#define IPU_CHA_DB_MODE_SEL(ch) IPU_CM_REG(0x0150 + 4 * ((ch) / 32))
  183176. +#define IPU_ALT_CHA_DB_MODE_SEL(ch) IPU_CM_REG(0x0168 + 4 * ((ch) / 32))
  183177. +/*
  183178. + * IPUv3D doesn't support triple buffer, so point
  183179. + * IPU_CHA_TRB_MODE_SEL, IPU_CHA_TRIPLE_CUR_BUF and
  183180. + * IPU_CHA_BUF2_RDY to readonly
  183181. + * IPU_ALT_CUR_BUF0 for IPUv3D.
  183182. + */
  183183. +#define IPU_CHA_TRB_MODE_SEL(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183184. + (0x0178 + 4 * ((ch) / 32)) : \
  183185. + (0x012C); })
  183186. +#define IPU_CHA_TRIPLE_CUR_BUF(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183187. + (0x0258 + \
  183188. + 4 * (((ch) * 2) / 32)) : \
  183189. + (0x012C); })
  183190. +#define IPU_CHA_BUF2_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183191. + (0x0288 + 4 * ((ch) / 32)) : \
  183192. + (0x012C); })
  183193. +#define IPU_CHA_CUR_BUF(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183194. + (0x023C + 4 * ((ch) / 32)) : \
  183195. + (0x0124 + 4 * ((ch) / 32)); })
  183196. +#define IPU_ALT_CUR_BUF0 IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183197. + (0x0244) : \
  183198. + (0x012C); })
  183199. +#define IPU_ALT_CUR_BUF1 IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183200. + (0x0248) : \
  183201. + (0x0130); })
  183202. +#define IPU_SRM_STAT IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183203. + (0x024C) : \
  183204. + (0x0134); })
  183205. +#define IPU_PROC_TASK_STAT IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183206. + (0x0250) : \
  183207. + (0x0138); })
  183208. +#define IPU_DISP_TASK_STAT IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183209. + (0x0254) : \
  183210. + (0x013C); })
  183211. +#define IPU_CHA_BUF0_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183212. + (0x0268 + 4 * ((ch) / 32)) : \
  183213. + (0x0140 + 4 * ((ch) / 32)); })
  183214. +#define IPU_CHA_BUF1_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183215. + (0x0270 + 4 * ((ch) / 32)) : \
  183216. + (0x0148 + 4 * ((ch) / 32)); })
  183217. +#define IPU_ALT_CHA_BUF0_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183218. + (0x0278 + 4 * ((ch) / 32)) : \
  183219. + (0x0158 + 4 * ((ch) / 32)); })
  183220. +#define IPU_ALT_CHA_BUF1_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183221. + (0x0280 + 4 * ((ch) / 32)) : \
  183222. + (0x0160 + 4 * ((ch) / 32)); })
  183223. +
  183224. +#define IPU_INT_CTRL(n) IPU_CM_REG(0x003C + 4 * ((n) - 1))
  183225. +#define IPU_INT_STAT(n) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183226. + (0x0200 + 4 * ((n) - 1)) : \
  183227. + (0x00E8 + 4 * ((n) - 1)); })
  183228. +
  183229. +#define IPUIRQ_2_STATREG(irq) IPU_CM_REG(IPU_INT_STAT(1) + 4 * ((irq) / 32))
  183230. +#define IPUIRQ_2_CTRLREG(irq) IPU_CM_REG(IPU_INT_CTRL(1) + 4 * ((irq) / 32))
  183231. +#define IPUIRQ_2_MASK(irq) (1UL << ((irq) & 0x1F))
  183232. +
  183233. +/* IPU VDI registers */
  183234. +#define IPU_VDI_REG(offset) (offset)
  183235. +
  183236. +#define VDI_FSIZE IPU_VDI_REG(0)
  183237. +#define VDI_C IPU_VDI_REG(0x0004)
  183238. +
  183239. +/* IPU CSI Registers */
  183240. +#define IPU_CSI_REG(offset) (offset)
  183241. +
  183242. +#define CSI_SENS_CONF IPU_CSI_REG(0)
  183243. +#define CSI_SENS_FRM_SIZE IPU_CSI_REG(0x0004)
  183244. +#define CSI_ACT_FRM_SIZE IPU_CSI_REG(0x0008)
  183245. +#define CSI_OUT_FRM_CTRL IPU_CSI_REG(0x000C)
  183246. +#define CSI_TST_CTRL IPU_CSI_REG(0x0010)
  183247. +#define CSI_CCIR_CODE_1 IPU_CSI_REG(0x0014)
  183248. +#define CSI_CCIR_CODE_2 IPU_CSI_REG(0x0018)
  183249. +#define CSI_CCIR_CODE_3 IPU_CSI_REG(0x001C)
  183250. +#define CSI_MIPI_DI IPU_CSI_REG(0x0020)
  183251. +#define CSI_SKIP IPU_CSI_REG(0x0024)
  183252. +#define CSI_CPD_CTRL IPU_CSI_REG(0x0028)
  183253. +#define CSI_CPD_RC(n) IPU_CSI_REG(0x002C + 4 * (n))
  183254. +#define CSI_CPD_RS(n) IPU_CSI_REG(0x004C + 4 * (n))
  183255. +#define CSI_CPD_GRC(n) IPU_CSI_REG(0x005C + 4 * (n))
  183256. +#define CSI_CPD_GRS(n) IPU_CSI_REG(0x007C + 4 * (n))
  183257. +#define CSI_CPD_GBC(n) IPU_CSI_REG(0x008C + 4 * (n))
  183258. +#define CSI_CPD_GBS(n) IPU_CSI_REG(0x00AC + 4 * (n))
  183259. +#define CSI_CPD_BC(n) IPU_CSI_REG(0x00BC + 4 * (n))
  183260. +#define CSI_CPD_BS(n) IPU_CSI_REG(0x00DC + 4 * (n))
  183261. +#define CSI_CPD_OFFSET1 IPU_CSI_REG(0x00EC)
  183262. +#define CSI_CPD_OFFSET2 IPU_CSI_REG(0x00F0)
  183263. +
  183264. +/* IPU SMFC Registers */
  183265. +#define IPU_SMFC_REG(offset) (offset)
  183266. +
  183267. +#define SMFC_MAP IPU_SMFC_REG(0)
  183268. +#define SMFC_WMC IPU_SMFC_REG(0x0004)
  183269. +#define SMFC_BS IPU_SMFC_REG(0x0008)
  183270. +
  183271. +/* IPU IC Registers */
  183272. +#define IPU_IC_REG(offset) (offset)
  183273. +
  183274. +#define IC_CONF IPU_IC_REG(0)
  183275. +#define IC_PRP_ENC_RSC IPU_IC_REG(0x0004)
  183276. +#define IC_PRP_VF_RSC IPU_IC_REG(0x0008)
  183277. +#define IC_PP_RSC IPU_IC_REG(0x000C)
  183278. +#define IC_CMBP_1 IPU_IC_REG(0x0010)
  183279. +#define IC_CMBP_2 IPU_IC_REG(0x0014)
  183280. +#define IC_IDMAC_1 IPU_IC_REG(0x0018)
  183281. +#define IC_IDMAC_2 IPU_IC_REG(0x001C)
  183282. +#define IC_IDMAC_3 IPU_IC_REG(0x0020)
  183283. +#define IC_IDMAC_4 IPU_IC_REG(0x0024)
  183284. +
  183285. +/* IPU IDMAC Registers */
  183286. +#define IPU_IDMAC_REG(offset) (offset)
  183287. +
  183288. +#define IDMAC_CONF IPU_IDMAC_REG(0x0000)
  183289. +#define IDMAC_CHA_EN(ch) IPU_IDMAC_REG(0x0004 + 4 * ((ch) / 32))
  183290. +#define IDMAC_SEP_ALPHA IPU_IDMAC_REG(0x000C)
  183291. +#define IDMAC_ALT_SEP_ALPHA IPU_IDMAC_REG(0x0010)
  183292. +#define IDMAC_CHA_PRI(ch) IPU_IDMAC_REG(0x0014 + 4 * ((ch) / 32))
  183293. +#define IDMAC_WM_EN(ch) IPU_IDMAC_REG(0x001C + 4 * ((ch) / 32))
  183294. +#define IDMAC_CH_LOCK_EN_1 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183295. + (0x0024) : 0; })
  183296. +#define IDMAC_CH_LOCK_EN_2 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183297. + (0x0028) : \
  183298. + (0x0024); })
  183299. +#define IDMAC_SUB_ADDR_0 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183300. + (0x002C) : \
  183301. + (0x0028); })
  183302. +#define IDMAC_SUB_ADDR_1 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183303. + (0x0030) : \
  183304. + (0x002C); })
  183305. +#define IDMAC_SUB_ADDR_2 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183306. + (0x0034) : \
  183307. + (0x0030); })
  183308. +/*
  183309. + * IPUv3D doesn't support IDMAC_SUB_ADDR_3 and IDMAC_SUB_ADDR_4,
  183310. + * so point them to readonly IDMAC_CHA_BUSY1 for IPUv3D.
  183311. + */
  183312. +#define IDMAC_SUB_ADDR_3 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183313. + (0x0038) : \
  183314. + (0x0040); })
  183315. +#define IDMAC_SUB_ADDR_4 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183316. + (0x003C) : \
  183317. + (0x0040); })
  183318. +#define IDMAC_BAND_EN(ch) IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183319. + (0x0040 + 4 * ((ch) / 32)) : \
  183320. + (0x0034 + 4 * ((ch) / 32)); })
  183321. +#define IDMAC_CHA_BUSY(ch) IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183322. + (0x0100 + 4 * ((ch) / 32)) : \
  183323. + (0x0040 + 4 * ((ch) / 32)); })
  183324. +
  183325. +/* IPU DI Registers */
  183326. +#define IPU_DI_REG(offset) (offset)
  183327. +
  183328. +#define DI_GENERAL IPU_DI_REG(0)
  183329. +#define DI_BS_CLKGEN0 IPU_DI_REG(0x0004)
  183330. +#define DI_BS_CLKGEN1 IPU_DI_REG(0x0008)
  183331. +#define DI_SW_GEN0(gen) IPU_DI_REG(0x000C + 4 * ((gen) - 1))
  183332. +#define DI_SW_GEN1(gen) IPU_DI_REG(0x0030 + 4 * ((gen) - 1))
  183333. +#define DI_STP_REP(gen) IPU_DI_REG(0x0148 + 4 * (((gen) - 1) / 2))
  183334. +#define DI_SYNC_AS_GEN IPU_DI_REG(0x0054)
  183335. +#define DI_DW_GEN(gen) IPU_DI_REG(0x0058 + 4 * (gen))
  183336. +#define DI_DW_SET(gen, set) IPU_DI_REG(0x0088 + 4 * ((gen) + 0xC * (set)))
  183337. +#define DI_SER_CONF IPU_DI_REG(0x015C)
  183338. +#define DI_SSC IPU_DI_REG(0x0160)
  183339. +#define DI_POL IPU_DI_REG(0x0164)
  183340. +#define DI_AW0 IPU_DI_REG(0x0168)
  183341. +#define DI_AW1 IPU_DI_REG(0x016C)
  183342. +#define DI_SCR_CONF IPU_DI_REG(0x0170)
  183343. +#define DI_STAT IPU_DI_REG(0x0174)
  183344. +
  183345. +/* IPU DMFC Registers */
  183346. +#define IPU_DMFC_REG(offset) (offset)
  183347. +
  183348. +#define DMFC_RD_CHAN IPU_DMFC_REG(0)
  183349. +#define DMFC_WR_CHAN IPU_DMFC_REG(0x0004)
  183350. +#define DMFC_WR_CHAN_DEF IPU_DMFC_REG(0x0008)
  183351. +#define DMFC_DP_CHAN IPU_DMFC_REG(0x000C)
  183352. +#define DMFC_DP_CHAN_DEF IPU_DMFC_REG(0x0010)
  183353. +#define DMFC_GENERAL1 IPU_DMFC_REG(0x0014)
  183354. +#define DMFC_GENERAL2 IPU_DMFC_REG(0x0018)
  183355. +#define DMFC_IC_CTRL IPU_DMFC_REG(0x001C)
  183356. +#define DMFC_STAT IPU_DMFC_REG(0x0020)
  183357. +
  183358. +/* IPU DC Registers */
  183359. +#define IPU_DC_REG(offset) (offset)
  183360. +
  183361. +#define DC_MAP_CONF_PTR(n) IPU_DC_REG(0x0108 + ((n) & ~0x1) * 2)
  183362. +#define DC_MAP_CONF_VAL(n) IPU_DC_REG(0x0144 + ((n) & ~0x1) * 2)
  183363. +
  183364. +#define _RL_CH_2_OFFSET(ch) (((ch) == 0) ? 8 : ( \
  183365. + ((ch) == 1) ? 0x24 : ( \
  183366. + ((ch) == 2) ? 0x40 : ( \
  183367. + ((ch) == 5) ? 0x64 : ( \
  183368. + ((ch) == 6) ? 0x80 : ( \
  183369. + ((ch) == 8) ? 0x9C : ( \
  183370. + ((ch) == 9) ? 0xBC : (-1))))))))
  183371. +#define DC_RL_CH(ch, evt) IPU_DC_REG(_RL_CH_2_OFFSET(ch) + \
  183372. + ((evt) & ~0x1) * 2)
  183373. +
  183374. +#define DC_EVT_NF 0
  183375. +#define DC_EVT_NL 1
  183376. +#define DC_EVT_EOF 2
  183377. +#define DC_EVT_NFIELD 3
  183378. +#define DC_EVT_EOL 4
  183379. +#define DC_EVT_EOFIELD 5
  183380. +#define DC_EVT_NEW_ADDR 6
  183381. +#define DC_EVT_NEW_CHAN 7
  183382. +#define DC_EVT_NEW_DATA 8
  183383. +
  183384. +#define DC_EVT_NEW_ADDR_W_0 0
  183385. +#define DC_EVT_NEW_ADDR_W_1 1
  183386. +#define DC_EVT_NEW_CHAN_W_0 2
  183387. +#define DC_EVT_NEW_CHAN_W_1 3
  183388. +#define DC_EVT_NEW_DATA_W_0 4
  183389. +#define DC_EVT_NEW_DATA_W_1 5
  183390. +#define DC_EVT_NEW_ADDR_R_0 6
  183391. +#define DC_EVT_NEW_ADDR_R_1 7
  183392. +#define DC_EVT_NEW_CHAN_R_0 8
  183393. +#define DC_EVT_NEW_CHAN_R_1 9
  183394. +#define DC_EVT_NEW_DATA_R_0 10
  183395. +#define DC_EVT_NEW_DATA_R_1 11
  183396. +#define DC_EVEN_UGDE0 12
  183397. +#define DC_ODD_UGDE0 13
  183398. +#define DC_EVEN_UGDE1 14
  183399. +#define DC_ODD_UGDE1 15
  183400. +#define DC_EVEN_UGDE2 16
  183401. +#define DC_ODD_UGDE2 17
  183402. +#define DC_EVEN_UGDE3 18
  183403. +#define DC_ODD_UGDE3 19
  183404. +
  183405. +#define dc_ch_offset(ch) \
  183406. +({ \
  183407. + const u8 _offset[] = { \
  183408. + 0, 0x1C, 0x38, 0x54, 0x58, 0x5C, 0x78, 0, 0x94, 0xB4}; \
  183409. + _offset[ch]; \
  183410. +})
  183411. +#define DC_WR_CH_CONF(ch) IPU_DC_REG(dc_ch_offset(ch))
  183412. +#define DC_WR_CH_ADDR(ch) IPU_DC_REG(dc_ch_offset(ch) + 4)
  183413. +
  183414. +#define DC_WR_CH_CONF_1 IPU_DC_REG(0x001C)
  183415. +#define DC_WR_CH_ADDR_1 IPU_DC_REG(0x0020)
  183416. +#define DC_WR_CH_CONF_5 IPU_DC_REG(0x005C)
  183417. +#define DC_WR_CH_ADDR_5 IPU_DC_REG(0x0060)
  183418. +#define DC_GEN IPU_DC_REG(0x00D4)
  183419. +#define DC_DISP_CONF1(disp) IPU_DC_REG(0x00D8 + 4 * (disp))
  183420. +#define DC_DISP_CONF2(disp) IPU_DC_REG(0x00E8 + 4 * (disp))
  183421. +#define DC_STAT IPU_DC_REG(0x01C8)
  183422. +#define DC_UGDE_0(evt) IPU_DC_REG(0x0174 + 16 * (evt))
  183423. +#define DC_UGDE_1(evt) IPU_DC_REG(0x0178 + 16 * (evt))
  183424. +#define DC_UGDE_2(evt) IPU_DC_REG(0x017C + 16 * (evt))
  183425. +#define DC_UGDE_3(evt) IPU_DC_REG(0x0180 + 16 * (evt))
  183426. +
  183427. +/* IPU DP Registers */
  183428. +#define IPU_DP_REG(offset) (offset)
  183429. +
  183430. +#define DP_SYNC 0
  183431. +#define DP_ASYNC0 0x60
  183432. +#define DP_ASYNC1 0xBC
  183433. +#define DP_COM_CONF(flow) IPU_DP_REG(flow)
  183434. +#define DP_GRAPH_WIND_CTRL(flow) IPU_DP_REG(0x0004 + (flow))
  183435. +#define DP_FG_POS(flow) IPU_DP_REG(0x0008 + (flow))
  183436. +#define DP_GAMMA_C(flow, i) IPU_DP_REG(0x0014 + (flow) + 4 * (i))
  183437. +#define DP_GAMMA_S(flow, i) IPU_DP_REG(0x0034 + (flow) + 4 * (i))
  183438. +#define DP_CSC_A_0(flow) IPU_DP_REG(0x0044 + (flow))
  183439. +#define DP_CSC_A_1(flow) IPU_DP_REG(0x0048 + (flow))
  183440. +#define DP_CSC_A_2(flow) IPU_DP_REG(0x004C + (flow))
  183441. +#define DP_CSC_A_3(flow) IPU_DP_REG(0x0050 + (flow))
  183442. +#define DP_CSC_0(flow) IPU_DP_REG(0x0054 + (flow))
  183443. +#define DP_CSC_1(flow) IPU_DP_REG(0x0058 + (flow))
  183444. +
  183445. +enum {
  183446. + IPU_CONF_CSI0_EN = 0x00000001,
  183447. + IPU_CONF_CSI1_EN = 0x00000002,
  183448. + IPU_CONF_IC_EN = 0x00000004,
  183449. + IPU_CONF_ROT_EN = 0x00000008,
  183450. + IPU_CONF_ISP_EN = 0x00000010,
  183451. + IPU_CONF_DP_EN = 0x00000020,
  183452. + IPU_CONF_DI0_EN = 0x00000040,
  183453. + IPU_CONF_DI1_EN = 0x00000080,
  183454. + IPU_CONF_DMFC_EN = 0x00000400,
  183455. + IPU_CONF_SMFC_EN = 0x00000100,
  183456. + IPU_CONF_DC_EN = 0x00000200,
  183457. + IPU_CONF_VDI_EN = 0x00001000,
  183458. + IPU_CONF_IDMAC_DIS = 0x00400000,
  183459. + IPU_CONF_IC_DMFC_SEL = 0x02000000,
  183460. + IPU_CONF_IC_DMFC_SYNC = 0x04000000,
  183461. + IPU_CONF_VDI_DMFC_SYNC = 0x08000000,
  183462. + IPU_CONF_CSI0_DATA_SOURCE = 0x10000000,
  183463. + IPU_CONF_CSI0_DATA_SOURCE_OFFSET = 28,
  183464. + IPU_CONF_CSI1_DATA_SOURCE = 0x20000000,
  183465. + IPU_CONF_IC_INPUT = 0x40000000,
  183466. + IPU_CONF_CSI_SEL = 0x80000000,
  183467. +
  183468. + DI0_COUNTER_RELEASE = 0x01000000,
  183469. + DI1_COUNTER_RELEASE = 0x02000000,
  183470. +
  183471. + FS_PRPVF_ROT_SRC_SEL_MASK = 0x00000F00,
  183472. + FS_PRPVF_ROT_SRC_SEL_OFFSET = 8,
  183473. + FS_PRPENC_ROT_SRC_SEL_MASK = 0x0000000F,
  183474. + FS_PRPENC_ROT_SRC_SEL_OFFSET = 0,
  183475. + FS_PP_ROT_SRC_SEL_MASK = 0x000F0000,
  183476. + FS_PP_ROT_SRC_SEL_OFFSET = 16,
  183477. + FS_PP_SRC_SEL_MASK = 0x0000F000,
  183478. + FS_PP_SRC_SEL_VDOA = 0x00008000,
  183479. + FS_PP_SRC_SEL_OFFSET = 12,
  183480. + FS_PRP_SRC_SEL_MASK = 0x0F000000,
  183481. + FS_PRP_SRC_SEL_OFFSET = 24,
  183482. + FS_VF_IN_VALID = 0x80000000,
  183483. + FS_ENC_IN_VALID = 0x40000000,
  183484. + FS_VDI_SRC_SEL_MASK = 0x30000000,
  183485. + FS_VDI_SRC_SEL_VDOA = 0x20000000,
  183486. + FS_VDOA_DEST_SEL_MASK = 0x00030000,
  183487. + FS_VDOA_DEST_SEL_VDI = 0x00020000,
  183488. + FS_VDOA_DEST_SEL_IC = 0x00010000,
  183489. + FS_VDI_SRC_SEL_OFFSET = 28,
  183490. +
  183491. +
  183492. + FS_PRPENC_DEST_SEL_MASK = 0x0000000F,
  183493. + FS_PRPENC_DEST_SEL_OFFSET = 0,
  183494. + FS_PRPVF_DEST_SEL_MASK = 0x000000F0,
  183495. + FS_PRPVF_DEST_SEL_OFFSET = 4,
  183496. + FS_PRPVF_ROT_DEST_SEL_MASK = 0x00000F00,
  183497. + FS_PRPVF_ROT_DEST_SEL_OFFSET = 8,
  183498. + FS_PP_DEST_SEL_MASK = 0x0000F000,
  183499. + FS_PP_DEST_SEL_OFFSET = 12,
  183500. + FS_PP_ROT_DEST_SEL_MASK = 0x000F0000,
  183501. + FS_PP_ROT_DEST_SEL_OFFSET = 16,
  183502. + FS_PRPENC_ROT_DEST_SEL_MASK = 0x00F00000,
  183503. + FS_PRPENC_ROT_DEST_SEL_OFFSET = 20,
  183504. +
  183505. + FS_SMFC0_DEST_SEL_MASK = 0x0000000F,
  183506. + FS_SMFC0_DEST_SEL_OFFSET = 0,
  183507. + FS_SMFC1_DEST_SEL_MASK = 0x00000070,
  183508. + FS_SMFC1_DEST_SEL_OFFSET = 4,
  183509. + FS_SMFC2_DEST_SEL_MASK = 0x00000780,
  183510. + FS_SMFC2_DEST_SEL_OFFSET = 7,
  183511. + FS_SMFC3_DEST_SEL_MASK = 0x00003800,
  183512. + FS_SMFC3_DEST_SEL_OFFSET = 11,
  183513. +
  183514. + FS_DC1_SRC_SEL_MASK = 0x00F00000,
  183515. + FS_DC1_SRC_SEL_OFFSET = 20,
  183516. + FS_DC2_SRC_SEL_MASK = 0x000F0000,
  183517. + FS_DC2_SRC_SEL_OFFSET = 16,
  183518. + FS_DP_SYNC0_SRC_SEL_MASK = 0x0000000F,
  183519. + FS_DP_SYNC0_SRC_SEL_OFFSET = 0,
  183520. + FS_DP_SYNC1_SRC_SEL_MASK = 0x000000F0,
  183521. + FS_DP_SYNC1_SRC_SEL_OFFSET = 4,
  183522. + FS_DP_ASYNC0_SRC_SEL_MASK = 0x00000F00,
  183523. + FS_DP_ASYNC0_SRC_SEL_OFFSET = 8,
  183524. + FS_DP_ASYNC1_SRC_SEL_MASK = 0x0000F000,
  183525. + FS_DP_ASYNC1_SRC_SEL_OFFSET = 12,
  183526. +
  183527. + FS_AUTO_REF_PER_MASK = 0,
  183528. + FS_AUTO_REF_PER_OFFSET = 16,
  183529. +
  183530. + TSTAT_VF_MASK = 0x0000000C,
  183531. + TSTAT_VF_OFFSET = 2,
  183532. + TSTAT_VF_ROT_MASK = 0x00000300,
  183533. + TSTAT_VF_ROT_OFFSET = 8,
  183534. + TSTAT_ENC_MASK = 0x00000003,
  183535. + TSTAT_ENC_OFFSET = 0,
  183536. + TSTAT_ENC_ROT_MASK = 0x000000C0,
  183537. + TSTAT_ENC_ROT_OFFSET = 6,
  183538. + TSTAT_PP_MASK = 0x00000030,
  183539. + TSTAT_PP_OFFSET = 4,
  183540. + TSTAT_PP_ROT_MASK = 0x00000C00,
  183541. + TSTAT_PP_ROT_OFFSET = 10,
  183542. +
  183543. + TASK_STAT_IDLE = 0,
  183544. + TASK_STAT_ACTIVE = 1,
  183545. + TASK_STAT_WAIT4READY = 2,
  183546. +
  183547. + /* Image Converter Register bits */
  183548. + IC_CONF_PRPENC_EN = 0x00000001,
  183549. + IC_CONF_PRPENC_CSC1 = 0x00000002,
  183550. + IC_CONF_PRPENC_ROT_EN = 0x00000004,
  183551. + IC_CONF_PRPVF_EN = 0x00000100,
  183552. + IC_CONF_PRPVF_CSC1 = 0x00000200,
  183553. + IC_CONF_PRPVF_CSC2 = 0x00000400,
  183554. + IC_CONF_PRPVF_CMB = 0x00000800,
  183555. + IC_CONF_PRPVF_ROT_EN = 0x00001000,
  183556. + IC_CONF_PP_EN = 0x00010000,
  183557. + IC_CONF_PP_CSC1 = 0x00020000,
  183558. + IC_CONF_PP_CSC2 = 0x00040000,
  183559. + IC_CONF_PP_CMB = 0x00080000,
  183560. + IC_CONF_PP_ROT_EN = 0x00100000,
  183561. + IC_CONF_IC_GLB_LOC_A = 0x10000000,
  183562. + IC_CONF_KEY_COLOR_EN = 0x20000000,
  183563. + IC_CONF_RWS_EN = 0x40000000,
  183564. + IC_CONF_CSI_MEM_WR_EN = 0x80000000,
  183565. +
  183566. + IC_RSZ_MAX_RESIZE_RATIO = 0x00004000,
  183567. +
  183568. + IC_IDMAC_1_CB0_BURST_16 = 0x00000001,
  183569. + IC_IDMAC_1_CB1_BURST_16 = 0x00000002,
  183570. + IC_IDMAC_1_CB2_BURST_16 = 0x00000004,
  183571. + IC_IDMAC_1_CB3_BURST_16 = 0x00000008,
  183572. + IC_IDMAC_1_CB4_BURST_16 = 0x00000010,
  183573. + IC_IDMAC_1_CB5_BURST_16 = 0x00000020,
  183574. + IC_IDMAC_1_CB6_BURST_16 = 0x00000040,
  183575. + IC_IDMAC_1_CB7_BURST_16 = 0x00000080,
  183576. + IC_IDMAC_1_PRPENC_ROT_MASK = 0x00003800,
  183577. + IC_IDMAC_1_PRPENC_ROT_OFFSET = 11,
  183578. + IC_IDMAC_1_PRPVF_ROT_MASK = 0x0001C000,
  183579. + IC_IDMAC_1_PRPVF_ROT_OFFSET = 14,
  183580. + IC_IDMAC_1_PP_ROT_MASK = 0x000E0000,
  183581. + IC_IDMAC_1_PP_ROT_OFFSET = 17,
  183582. + IC_IDMAC_1_PP_FLIP_RS = 0x00400000,
  183583. + IC_IDMAC_1_PRPVF_FLIP_RS = 0x00200000,
  183584. + IC_IDMAC_1_PRPENC_FLIP_RS = 0x00100000,
  183585. +
  183586. + IC_IDMAC_2_PRPENC_HEIGHT_MASK = 0x000003FF,
  183587. + IC_IDMAC_2_PRPENC_HEIGHT_OFFSET = 0,
  183588. + IC_IDMAC_2_PRPVF_HEIGHT_MASK = 0x000FFC00,
  183589. + IC_IDMAC_2_PRPVF_HEIGHT_OFFSET = 10,
  183590. + IC_IDMAC_2_PP_HEIGHT_MASK = 0x3FF00000,
  183591. + IC_IDMAC_2_PP_HEIGHT_OFFSET = 20,
  183592. +
  183593. + IC_IDMAC_3_PRPENC_WIDTH_MASK = 0x000003FF,
  183594. + IC_IDMAC_3_PRPENC_WIDTH_OFFSET = 0,
  183595. + IC_IDMAC_3_PRPVF_WIDTH_MASK = 0x000FFC00,
  183596. + IC_IDMAC_3_PRPVF_WIDTH_OFFSET = 10,
  183597. + IC_IDMAC_3_PP_WIDTH_MASK = 0x3FF00000,
  183598. + IC_IDMAC_3_PP_WIDTH_OFFSET = 20,
  183599. +
  183600. + CSI_SENS_CONF_DATA_FMT_SHIFT = 8,
  183601. + CSI_SENS_CONF_DATA_FMT_MASK = 0x00000700,
  183602. + CSI_SENS_CONF_DATA_FMT_RGB_YUV444 = 0L,
  183603. + CSI_SENS_CONF_DATA_FMT_YUV422_YUYV = 1L,
  183604. + CSI_SENS_CONF_DATA_FMT_YUV422_UYVY = 2L,
  183605. + CSI_SENS_CONF_DATA_FMT_BAYER = 3L,
  183606. + CSI_SENS_CONF_DATA_FMT_RGB565 = 4L,
  183607. + CSI_SENS_CONF_DATA_FMT_RGB555 = 5L,
  183608. + CSI_SENS_CONF_DATA_FMT_RGB444 = 6L,
  183609. + CSI_SENS_CONF_DATA_FMT_JPEG = 7L,
  183610. +
  183611. + CSI_SENS_CONF_VSYNC_POL_SHIFT = 0,
  183612. + CSI_SENS_CONF_HSYNC_POL_SHIFT = 1,
  183613. + CSI_SENS_CONF_DATA_POL_SHIFT = 2,
  183614. + CSI_SENS_CONF_PIX_CLK_POL_SHIFT = 3,
  183615. + CSI_SENS_CONF_SENS_PRTCL_MASK = 0x00000070L,
  183616. + CSI_SENS_CONF_SENS_PRTCL_SHIFT = 4,
  183617. + CSI_SENS_CONF_PACK_TIGHT_SHIFT = 7,
  183618. + CSI_SENS_CONF_DATA_WIDTH_SHIFT = 11,
  183619. + CSI_SENS_CONF_EXT_VSYNC_SHIFT = 15,
  183620. + CSI_SENS_CONF_DIVRATIO_SHIFT = 16,
  183621. +
  183622. + CSI_SENS_CONF_DIVRATIO_MASK = 0x00FF0000L,
  183623. + CSI_SENS_CONF_DATA_DEST_SHIFT = 24,
  183624. + CSI_SENS_CONF_DATA_DEST_MASK = 0x07000000L,
  183625. + CSI_SENS_CONF_JPEG8_EN_SHIFT = 27,
  183626. + CSI_SENS_CONF_JPEG_EN_SHIFT = 28,
  183627. + CSI_SENS_CONF_FORCE_EOF_SHIFT = 29,
  183628. + CSI_SENS_CONF_DATA_EN_POL_SHIFT = 31,
  183629. +
  183630. + CSI_DATA_DEST_ISP = 1L,
  183631. + CSI_DATA_DEST_IC = 2L,
  183632. + CSI_DATA_DEST_IDMAC = 4L,
  183633. +
  183634. + CSI_CCIR_ERR_DET_EN = 0x01000000L,
  183635. + CSI_HORI_DOWNSIZE_EN = 0x80000000L,
  183636. + CSI_VERT_DOWNSIZE_EN = 0x40000000L,
  183637. + CSI_TEST_GEN_MODE_EN = 0x01000000L,
  183638. +
  183639. + CSI_HSC_MASK = 0x1FFF0000,
  183640. + CSI_HSC_SHIFT = 16,
  183641. + CSI_VSC_MASK = 0x00000FFF,
  183642. + CSI_VSC_SHIFT = 0,
  183643. +
  183644. + CSI_TEST_GEN_R_MASK = 0x000000FFL,
  183645. + CSI_TEST_GEN_R_SHIFT = 0,
  183646. + CSI_TEST_GEN_G_MASK = 0x0000FF00L,
  183647. + CSI_TEST_GEN_G_SHIFT = 8,
  183648. + CSI_TEST_GEN_B_MASK = 0x00FF0000L,
  183649. + CSI_TEST_GEN_B_SHIFT = 16,
  183650. +
  183651. + CSI_MIPI_DI0_MASK = 0x000000FFL,
  183652. + CSI_MIPI_DI0_SHIFT = 0,
  183653. + CSI_MIPI_DI1_MASK = 0x0000FF00L,
  183654. + CSI_MIPI_DI1_SHIFT = 8,
  183655. + CSI_MIPI_DI2_MASK = 0x00FF0000L,
  183656. + CSI_MIPI_DI2_SHIFT = 16,
  183657. + CSI_MIPI_DI3_MASK = 0xFF000000L,
  183658. + CSI_MIPI_DI3_SHIFT = 24,
  183659. +
  183660. + CSI_MAX_RATIO_SKIP_ISP_MASK = 0x00070000L,
  183661. + CSI_MAX_RATIO_SKIP_ISP_SHIFT = 16,
  183662. + CSI_SKIP_ISP_MASK = 0x00F80000L,
  183663. + CSI_SKIP_ISP_SHIFT = 19,
  183664. + CSI_MAX_RATIO_SKIP_SMFC_MASK = 0x00000007L,
  183665. + CSI_MAX_RATIO_SKIP_SMFC_SHIFT = 0,
  183666. + CSI_SKIP_SMFC_MASK = 0x000000F8L,
  183667. + CSI_SKIP_SMFC_SHIFT = 3,
  183668. + CSI_ID_2_SKIP_MASK = 0x00000300L,
  183669. + CSI_ID_2_SKIP_SHIFT = 8,
  183670. +
  183671. + CSI_COLOR_FIRST_ROW_MASK = 0x00000002L,
  183672. + CSI_COLOR_FIRST_COMP_MASK = 0x00000001L,
  183673. +
  183674. + SMFC_MAP_CH0_MASK = 0x00000007L,
  183675. + SMFC_MAP_CH0_SHIFT = 0,
  183676. + SMFC_MAP_CH1_MASK = 0x00000038L,
  183677. + SMFC_MAP_CH1_SHIFT = 3,
  183678. + SMFC_MAP_CH2_MASK = 0x000001C0L,
  183679. + SMFC_MAP_CH2_SHIFT = 6,
  183680. + SMFC_MAP_CH3_MASK = 0x00000E00L,
  183681. + SMFC_MAP_CH3_SHIFT = 9,
  183682. +
  183683. + SMFC_WM0_SET_MASK = 0x00000007L,
  183684. + SMFC_WM0_SET_SHIFT = 0,
  183685. + SMFC_WM1_SET_MASK = 0x000001C0L,
  183686. + SMFC_WM1_SET_SHIFT = 6,
  183687. + SMFC_WM2_SET_MASK = 0x00070000L,
  183688. + SMFC_WM2_SET_SHIFT = 16,
  183689. + SMFC_WM3_SET_MASK = 0x01C00000L,
  183690. + SMFC_WM3_SET_SHIFT = 22,
  183691. +
  183692. + SMFC_WM0_CLR_MASK = 0x00000038L,
  183693. + SMFC_WM0_CLR_SHIFT = 3,
  183694. + SMFC_WM1_CLR_MASK = 0x00000E00L,
  183695. + SMFC_WM1_CLR_SHIFT = 9,
  183696. + SMFC_WM2_CLR_MASK = 0x00380000L,
  183697. + SMFC_WM2_CLR_SHIFT = 19,
  183698. + SMFC_WM3_CLR_MASK = 0x0E000000L,
  183699. + SMFC_WM3_CLR_SHIFT = 25,
  183700. +
  183701. + SMFC_BS0_MASK = 0x0000000FL,
  183702. + SMFC_BS0_SHIFT = 0,
  183703. + SMFC_BS1_MASK = 0x000000F0L,
  183704. + SMFC_BS1_SHIFT = 4,
  183705. + SMFC_BS2_MASK = 0x00000F00L,
  183706. + SMFC_BS2_SHIFT = 8,
  183707. + SMFC_BS3_MASK = 0x0000F000L,
  183708. + SMFC_BS3_SHIFT = 12,
  183709. +
  183710. + PF_CONF_TYPE_MASK = 0x00000007,
  183711. + PF_CONF_TYPE_SHIFT = 0,
  183712. + PF_CONF_PAUSE_EN = 0x00000010,
  183713. + PF_CONF_RESET = 0x00008000,
  183714. + PF_CONF_PAUSE_ROW_MASK = 0x00FF0000,
  183715. + PF_CONF_PAUSE_ROW_SHIFT = 16,
  183716. +
  183717. + DI_DW_GEN_ACCESS_SIZE_OFFSET = 24,
  183718. + DI_DW_GEN_COMPONENT_SIZE_OFFSET = 16,
  183719. +
  183720. + DI_GEN_DI_CLK_EXT = 0x100000,
  183721. + DI_GEN_POLARITY_DISP_CLK = 0x00020000,
  183722. + DI_GEN_POLARITY_1 = 0x00000001,
  183723. + DI_GEN_POLARITY_2 = 0x00000002,
  183724. + DI_GEN_POLARITY_3 = 0x00000004,
  183725. + DI_GEN_POLARITY_4 = 0x00000008,
  183726. + DI_GEN_POLARITY_5 = 0x00000010,
  183727. + DI_GEN_POLARITY_6 = 0x00000020,
  183728. + DI_GEN_POLARITY_7 = 0x00000040,
  183729. + DI_GEN_POLARITY_8 = 0x00000080,
  183730. +
  183731. + DI_POL_DRDY_DATA_POLARITY = 0x00000080,
  183732. + DI_POL_DRDY_POLARITY_15 = 0x00000010,
  183733. +
  183734. + DI_VSYNC_SEL_OFFSET = 13,
  183735. +
  183736. + DC_WR_CH_CONF_FIELD_MODE = 0x00000200,
  183737. + DC_WR_CH_CONF_PROG_TYPE_OFFSET = 5,
  183738. + DC_WR_CH_CONF_PROG_TYPE_MASK = 0x000000E0,
  183739. + DC_WR_CH_CONF_PROG_DI_ID = 0x00000004,
  183740. + DC_WR_CH_CONF_PROG_DISP_ID_OFFSET = 3,
  183741. + DC_WR_CH_CONF_PROG_DISP_ID_MASK = 0x00000018,
  183742. +
  183743. + DC_UGDE_0_ODD_EN = 0x02000000,
  183744. + DC_UGDE_0_ID_CODED_MASK = 0x00000007,
  183745. + DC_UGDE_0_ID_CODED_OFFSET = 0,
  183746. + DC_UGDE_0_EV_PRIORITY_MASK = 0x00000078,
  183747. + DC_UGDE_0_EV_PRIORITY_OFFSET = 3,
  183748. +
  183749. + DP_COM_CONF_FG_EN = 0x00000001,
  183750. + DP_COM_CONF_GWSEL = 0x00000002,
  183751. + DP_COM_CONF_GWAM = 0x00000004,
  183752. + DP_COM_CONF_GWCKE = 0x00000008,
  183753. + DP_COM_CONF_CSC_DEF_MASK = 0x00000300,
  183754. + DP_COM_CONF_CSC_DEF_OFFSET = 8,
  183755. + DP_COM_CONF_CSC_DEF_FG = 0x00000300,
  183756. + DP_COM_CONF_CSC_DEF_BG = 0x00000200,
  183757. + DP_COM_CONF_CSC_DEF_BOTH = 0x00000100,
  183758. + DP_COM_CONF_GAMMA_EN = 0x00001000,
  183759. + DP_COM_CONF_GAMMA_YUV_EN = 0x00002000,
  183760. +
  183761. + DI_SER_CONF_LLA_SER_ACCESS = 0x00000020,
  183762. + DI_SER_CONF_SERIAL_CLK_POL = 0x00000010,
  183763. + DI_SER_CONF_SERIAL_DATA_POL = 0x00000008,
  183764. + DI_SER_CONF_SERIAL_RS_POL = 0x00000004,
  183765. + DI_SER_CONF_SERIAL_CS_POL = 0x00000002,
  183766. + DI_SER_CONF_WAIT4SERIAL = 0x00000001,
  183767. +
  183768. + VDI_C_CH_420 = 0x00000000,
  183769. + VDI_C_CH_422 = 0x00000002,
  183770. + VDI_C_MOT_SEL_FULL = 0x00000008,
  183771. + VDI_C_MOT_SEL_LOW = 0x00000004,
  183772. + VDI_C_MOT_SEL_MED = 0x00000000,
  183773. + VDI_C_BURST_SIZE1_4 = 0x00000030,
  183774. + VDI_C_BURST_SIZE2_4 = 0x00000300,
  183775. + VDI_C_BURST_SIZE3_4 = 0x00003000,
  183776. + VDI_C_BURST_SIZE_MASK = 0xF,
  183777. + VDI_C_BURST_SIZE1_OFFSET = 4,
  183778. + VDI_C_BURST_SIZE2_OFFSET = 8,
  183779. + VDI_C_BURST_SIZE3_OFFSET = 12,
  183780. + VDI_C_VWM1_SET_1 = 0x00000000,
  183781. + VDI_C_VWM1_SET_2 = 0x00010000,
  183782. + VDI_C_VWM1_CLR_2 = 0x00080000,
  183783. + VDI_C_VWM3_SET_1 = 0x00000000,
  183784. + VDI_C_VWM3_SET_2 = 0x00400000,
  183785. + VDI_C_VWM3_CLR_2 = 0x02000000,
  183786. + VDI_C_TOP_FIELD_MAN_1 = 0x40000000,
  183787. + VDI_C_TOP_FIELD_AUTO_1 = 0x80000000,
  183788. +};
  183789. +
  183790. +enum di_pins {
  183791. + DI_PIN11 = 0,
  183792. + DI_PIN12 = 1,
  183793. + DI_PIN13 = 2,
  183794. + DI_PIN14 = 3,
  183795. + DI_PIN15 = 4,
  183796. + DI_PIN16 = 5,
  183797. + DI_PIN17 = 6,
  183798. + DI_PIN_CS = 7,
  183799. +
  183800. + DI_PIN_SER_CLK = 0,
  183801. + DI_PIN_SER_RS = 1,
  183802. +};
  183803. +
  183804. +enum di_sync_wave {
  183805. + DI_SYNC_NONE = -1,
  183806. + DI_SYNC_CLK = 0,
  183807. + DI_SYNC_INT_HSYNC = 1,
  183808. + DI_SYNC_HSYNC = 2,
  183809. + DI_SYNC_VSYNC = 3,
  183810. + DI_SYNC_DE = 5,
  183811. +};
  183812. +
  183813. +/* DC template opcodes */
  183814. +#define WROD(lf) (0x18 | (lf << 1))
  183815. +#define WRG (0x01)
  183816. +
  183817. +#endif
  183818. diff -Nur linux-3.14.15/drivers/mxc/ipu3/Kconfig linux-linaro-stable-mx6/drivers/mxc/ipu3/Kconfig
  183819. --- linux-3.14.15/drivers/mxc/ipu3/Kconfig 1970-01-01 01:00:00.000000000 +0100
  183820. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/Kconfig 2014-08-20 19:23:53.574845907 +0200
  183821. @@ -0,0 +1,2 @@
  183822. +config MXC_IPU_V3
  183823. + bool
  183824. diff -Nur linux-3.14.15/drivers/mxc/ipu3/Makefile linux-linaro-stable-mx6/drivers/mxc/ipu3/Makefile
  183825. --- linux-3.14.15/drivers/mxc/ipu3/Makefile 1970-01-01 01:00:00.000000000 +0100
  183826. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/Makefile 2014-08-20 19:23:53.574845907 +0200
  183827. @@ -0,0 +1,4 @@
  183828. +obj-$(CONFIG_MXC_IPU_V3) = mxc_ipu.o
  183829. +
  183830. +mxc_ipu-objs := ipu_common.o ipu_ic.o ipu_disp.o ipu_capture.o ipu_device.o \
  183831. + ipu_calc_stripes_sizes.o vdoa.o ipu_pixel_clk.o
  183832. diff -Nur linux-3.14.15/drivers/mxc/ipu3/vdoa.c linux-linaro-stable-mx6/drivers/mxc/ipu3/vdoa.c
  183833. --- linux-3.14.15/drivers/mxc/ipu3/vdoa.c 1970-01-01 01:00:00.000000000 +0100
  183834. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/vdoa.c 2014-08-20 19:23:53.578845924 +0200
  183835. @@ -0,0 +1,543 @@
  183836. +/*
  183837. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  183838. + *
  183839. + * This program is free software; you can redistribute it and/or modify
  183840. + * it under the terms of the GNU General Public License as published by
  183841. + * the Free Software Foundation; either version 2 of the License, or
  183842. + * (at your option) any later version.
  183843. +
  183844. + * This program is distributed in the hope that it will be useful,
  183845. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  183846. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  183847. + * GNU General Public License for more details.
  183848. +
  183849. + * You should have received a copy of the GNU General Public License along
  183850. + * with this program; if not, write to the Free Software Foundation, Inc.,
  183851. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  183852. + */
  183853. +#include <linux/clk.h>
  183854. +#include <linux/err.h>
  183855. +#include <linux/io.h>
  183856. +#include <linux/ipu.h>
  183857. +#include <linux/genalloc.h>
  183858. +#include <linux/module.h>
  183859. +#include <linux/platform_device.h>
  183860. +#include <linux/slab.h>
  183861. +#include <linux/types.h>
  183862. +
  183863. +#include "vdoa.h"
  183864. +/* 6band(3field* double buffer) * (width*2) * bandline(8)
  183865. + = 6x1024x2x8 = 96k or 72k(1.5byte) */
  183866. +#define MAX_VDOA_IRAM_SIZE (1024*96)
  183867. +#define VDOA_IRAM_SIZE (1024*72)
  183868. +
  183869. +#define VDOAC_BAND_HEIGHT_32LINES (32)
  183870. +#define VDOAC_BAND_HEIGHT_16LINES (16)
  183871. +#define VDOAC_BAND_HEIGHT_8LINES (8)
  183872. +#define VDOAC_THREE_FRAMES (0x1 << 2)
  183873. +#define VDOAC_SYNC_BAND_MODE (0x1 << 3)
  183874. +#define VDOAC_SCAN_ORDER_INTERLACED (0x1 << 4)
  183875. +#define VDOAC_PFS_YUYV (0x1 << 5)
  183876. +#define VDOAC_IPU_SEL_1 (0x1 << 6)
  183877. +#define VDOAFP_FH_MASK (0x1FFF)
  183878. +#define VDOAFP_FH_SHIFT (16)
  183879. +#define VDOAFP_FW_MASK (0x3FFF)
  183880. +#define VDOAFP_FW_SHIFT (0)
  183881. +#define VDOASL_VSLY_MASK (0x3FFF)
  183882. +#define VDOASL_VSLY_SHIFT (16)
  183883. +#define VDOASL_ISLY_MASK (0x7FFF)
  183884. +#define VDOASL_ISLY_SHIFT (0)
  183885. +#define VDOASRR_START_XFER (0x2)
  183886. +#define VDOASRR_SWRST (0x1)
  183887. +#define VDOAIEIST_TRANSFER_ERR (0x2)
  183888. +#define VDOAIEIST_TRANSFER_END (0x1)
  183889. +
  183890. +#define VDOAC (0x0) /* Control Register */
  183891. +#define VDOASRR (0x4) /* Start and Reset Register */
  183892. +#define VDOAIE (0x8) /* Interrupt Enable Register */
  183893. +#define VDOAIST (0xc) /* Interrupt Status Register */
  183894. +#define VDOAFP (0x10) /* Frame Parameters Register */
  183895. +#define VDOAIEBA00 (0x14) /* External Buffer n Frame m Address Register */
  183896. +#define VDOAIEBA01 (0x18) /* External Buffer n Frame m Address Register */
  183897. +#define VDOAIEBA02 (0x1c) /* External Buffer n Frame m Address Register */
  183898. +#define VDOAIEBA10 (0x20) /* External Buffer n Frame m Address Register */
  183899. +#define VDOAIEBA11 (0x24) /* External Buffer n Frame m Address Register */
  183900. +#define VDOAIEBA12 (0x28) /* External Buffer n Frame m Address Register */
  183901. +#define VDOASL (0x2c) /* IPU Stride Line Register */
  183902. +#define VDOAIUBO (0x30) /* IPU Chroma Buffer Offset Register */
  183903. +#define VDOAVEBA0 (0x34) /* External Buffer m Address Register */
  183904. +#define VDOAVEBA1 (0x38) /* External Buffer m Address Register */
  183905. +#define VDOAVEBA2 (0x3c) /* External Buffer m Address Register */
  183906. +#define VDOAVUBO (0x40) /* VPU Chroma Buffer Offset */
  183907. +#define VDOASR (0x44) /* Status Register */
  183908. +#define VDOATD (0x48) /* Test Debug Register */
  183909. +
  183910. +
  183911. +enum {
  183912. + VDOA_INIT = 0x1,
  183913. + VDOA_GET = 0x2,
  183914. + VDOA_SETUP = 0x4,
  183915. + VDOA_GET_OBUF = 0x8,
  183916. + VDOA_START = 0x10,
  183917. + VDOA_INIRQ = 0x20,
  183918. + VDOA_STOP = 0x40,
  183919. + VDOA_PUT = VDOA_INIT,
  183920. +};
  183921. +
  183922. +enum {
  183923. + VDOA_NULL = 0,
  183924. + VDOA_FRAME = 1,
  183925. + VDOA_PREV_FIELD = 2,
  183926. + VDOA_CURR_FIELD = 3,
  183927. + VDOA_NEXT_FIELD = 4,
  183928. +};
  183929. +
  183930. +#define CHECK_STATE(expect, retcode) \
  183931. +do { \
  183932. + if (!((expect) & vdoa->state)) { \
  183933. + dev_err(vdoa->dev, "ERR: %s state:0x%x, expect:0x%x.\n",\
  183934. + __func__, vdoa->state, (expect)); \
  183935. + retcode; \
  183936. + } \
  183937. +} while (0)
  183938. +
  183939. +#define CHECK_NULL_PTR(ptr) \
  183940. +do { \
  183941. + pr_debug("vdoa_ptr:0x%p in %s state:0x%x.\n", \
  183942. + vdoa, __func__, vdoa->state); \
  183943. + if (NULL == (ptr)) { \
  183944. + pr_err("ERR vdoa: %s state:0x%x null ptr.\n", \
  183945. + __func__, vdoa->state); \
  183946. + } \
  183947. +} while (0)
  183948. +
  183949. +struct vdoa_info {
  183950. + int state;
  183951. + struct device *dev;
  183952. + struct clk *vdoa_clk;
  183953. + void __iomem *reg_base;
  183954. + struct gen_pool *iram_pool;
  183955. + unsigned long iram_base;
  183956. + unsigned long iram_paddr;
  183957. + int irq;
  183958. + int field;
  183959. + struct completion comp;
  183960. +};
  183961. +
  183962. +static struct vdoa_info *g_vdoa;
  183963. +static unsigned long iram_size;
  183964. +static DEFINE_MUTEX(vdoa_lock);
  183965. +
  183966. +static inline void vdoa_read_register(struct vdoa_info *vdoa,
  183967. + u32 reg, u32 *val)
  183968. +{
  183969. + *val = ioread32(vdoa->reg_base + reg);
  183970. + dev_dbg(vdoa->dev, "read_reg:0x%02x, val:0x%08x.\n", reg, *val);
  183971. +}
  183972. +
  183973. +static inline void vdoa_write_register(struct vdoa_info *vdoa,
  183974. + u32 reg, u32 val)
  183975. +{
  183976. + iowrite32(val, vdoa->reg_base + reg);
  183977. + dev_dbg(vdoa->dev, "\t\twrite_reg:0x%02x, val:0x%08x.\n", reg, val);
  183978. +}
  183979. +
  183980. +static void dump_registers(struct vdoa_info *vdoa)
  183981. +{
  183982. + int i;
  183983. + u32 data;
  183984. +
  183985. + for (i = VDOAC; i < VDOATD; i += 4)
  183986. + vdoa_read_register(vdoa, i, &data);
  183987. +}
  183988. +
  183989. +int vdoa_setup(vdoa_handle_t handle, struct vdoa_params *params)
  183990. +{
  183991. + int band_size;
  183992. + int total_band_size = 0;
  183993. + int ipu_stride;
  183994. + u32 data;
  183995. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  183996. +
  183997. + CHECK_NULL_PTR(vdoa);
  183998. + CHECK_STATE(VDOA_GET | VDOA_GET_OBUF | VDOA_STOP, return -EINVAL);
  183999. + if (VDOA_GET == vdoa->state) {
  184000. + dev_dbg(vdoa->dev, "w:%d, h:%d.\n",
  184001. + params->width, params->height);
  184002. + data = (params->band_lines == VDOAC_BAND_HEIGHT_32LINES) ? 2 :
  184003. + ((params->band_lines == VDOAC_BAND_HEIGHT_16LINES) ?
  184004. + 1 : 0);
  184005. + data |= params->scan_order ? VDOAC_SCAN_ORDER_INTERLACED : 0;
  184006. + data |= params->band_mode ? VDOAC_SYNC_BAND_MODE : 0;
  184007. + data |= params->pfs ? VDOAC_PFS_YUYV : 0;
  184008. + data |= params->ipu_num ? VDOAC_IPU_SEL_1 : 0;
  184009. + vdoa_write_register(vdoa, VDOAC, data);
  184010. +
  184011. + data = ((params->width & VDOAFP_FW_MASK) << VDOAFP_FW_SHIFT) |
  184012. + ((params->height & VDOAFP_FH_MASK) << VDOAFP_FH_SHIFT);
  184013. + vdoa_write_register(vdoa, VDOAFP, data);
  184014. +
  184015. + ipu_stride = params->pfs ? params->width << 1 : params->width;
  184016. + data = ((params->vpu_stride & VDOASL_VSLY_MASK) <<
  184017. + VDOASL_VSLY_SHIFT) |
  184018. + ((ipu_stride & VDOASL_ISLY_MASK) << VDOASL_ISLY_SHIFT);
  184019. + vdoa_write_register(vdoa, VDOASL, data);
  184020. +
  184021. + dev_dbg(vdoa->dev, "band_mode:%d, band_line:%d, base:0x%lx.\n",
  184022. + params->band_mode, params->band_lines, vdoa->iram_paddr);
  184023. + }
  184024. + /*
  184025. + * band size = (luma_per_line + chroma_per_line) * bandLines
  184026. + * = width * (3/2 or 2) * bandLines
  184027. + * double buffer mode used.
  184028. + */
  184029. + if (params->pfs)
  184030. + band_size = (params->width << 1) * params->band_lines;
  184031. + else
  184032. + band_size = ((params->width * 3) >> 1) *
  184033. + params->band_lines;
  184034. + if (params->interlaced) {
  184035. + total_band_size = 6 * band_size; /* 3 frames*double buffer */
  184036. + if (iram_size < total_band_size) {
  184037. + dev_err(vdoa->dev, "iram_size:0x%lx is smaller than "
  184038. + "request:0x%x!\n", iram_size, total_band_size);
  184039. + return -EINVAL;
  184040. + }
  184041. + if (params->vfield_buf.prev_veba) {
  184042. + if (params->band_mode) {
  184043. + vdoa_write_register(vdoa, VDOAIEBA00,
  184044. + vdoa->iram_paddr);
  184045. + vdoa_write_register(vdoa, VDOAIEBA10,
  184046. + vdoa->iram_paddr + band_size);
  184047. + } else
  184048. + vdoa_write_register(vdoa, VDOAIEBA00,
  184049. + params->ieba0);
  184050. + vdoa_write_register(vdoa, VDOAVEBA0,
  184051. + params->vfield_buf.prev_veba);
  184052. + vdoa->field = VDOA_PREV_FIELD;
  184053. + }
  184054. + if (params->vfield_buf.cur_veba) {
  184055. + if (params->band_mode) {
  184056. + vdoa_write_register(vdoa, VDOAIEBA01,
  184057. + vdoa->iram_paddr + band_size * 2);
  184058. + vdoa_write_register(vdoa, VDOAIEBA11,
  184059. + vdoa->iram_paddr + band_size * 3);
  184060. + } else
  184061. + vdoa_write_register(vdoa, VDOAIEBA01,
  184062. + params->ieba1);
  184063. + vdoa_write_register(vdoa, VDOAVEBA1,
  184064. + params->vfield_buf.cur_veba);
  184065. + vdoa->field = VDOA_CURR_FIELD;
  184066. + }
  184067. + if (params->vfield_buf.next_veba) {
  184068. + if (params->band_mode) {
  184069. + vdoa_write_register(vdoa, VDOAIEBA02,
  184070. + vdoa->iram_paddr + band_size * 4);
  184071. + vdoa_write_register(vdoa, VDOAIEBA12,
  184072. + vdoa->iram_paddr + band_size * 5);
  184073. + } else
  184074. + vdoa_write_register(vdoa, VDOAIEBA02,
  184075. + params->ieba2);
  184076. + vdoa_write_register(vdoa, VDOAVEBA2,
  184077. + params->vfield_buf.next_veba);
  184078. + vdoa->field = VDOA_NEXT_FIELD;
  184079. + vdoa_read_register(vdoa, VDOAC, &data);
  184080. + data |= VDOAC_THREE_FRAMES;
  184081. + vdoa_write_register(vdoa, VDOAC, data);
  184082. + }
  184083. +
  184084. + if (!params->pfs)
  184085. + vdoa_write_register(vdoa, VDOAIUBO,
  184086. + params->width * params->band_lines);
  184087. + vdoa_write_register(vdoa, VDOAVUBO,
  184088. + params->vfield_buf.vubo);
  184089. + dev_dbg(vdoa->dev, "total band_size:0x%x.\n", band_size*6);
  184090. + } else if (params->band_mode) {
  184091. + /* used for progressive frame resize on PrP channel */
  184092. + BUG(); /* currently not support */
  184093. + /* progressvie frame: band mode */
  184094. + vdoa_write_register(vdoa, VDOAIEBA00, vdoa->iram_paddr);
  184095. + vdoa_write_register(vdoa, VDOAIEBA10,
  184096. + vdoa->iram_paddr + band_size);
  184097. + if (!params->pfs)
  184098. + vdoa_write_register(vdoa, VDOAIUBO,
  184099. + params->width * params->band_lines);
  184100. + dev_dbg(vdoa->dev, "total band_size:0x%x\n", band_size*2);
  184101. + } else {
  184102. + /* progressive frame: mem->mem, non-band mode */
  184103. + vdoa->field = VDOA_FRAME;
  184104. + vdoa_write_register(vdoa, VDOAVEBA0, params->vframe_buf.veba);
  184105. + vdoa_write_register(vdoa, VDOAVUBO, params->vframe_buf.vubo);
  184106. + vdoa_write_register(vdoa, VDOAIEBA00, params->ieba0);
  184107. + if (!params->pfs)
  184108. + /* note: iubo is relative value, based on ieba0 */
  184109. + vdoa_write_register(vdoa, VDOAIUBO,
  184110. + params->width * params->height);
  184111. + }
  184112. + vdoa->state = VDOA_SETUP;
  184113. + return 0;
  184114. +}
  184115. +
  184116. +void vdoa_get_output_buf(vdoa_handle_t handle, struct vdoa_ipu_buf *buf)
  184117. +{
  184118. + u32 data;
  184119. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  184120. +
  184121. + CHECK_NULL_PTR(vdoa);
  184122. + CHECK_STATE(VDOA_SETUP, return);
  184123. + vdoa->state = VDOA_GET_OBUF;
  184124. + memset(buf, 0, sizeof(*buf));
  184125. +
  184126. + vdoa_read_register(vdoa, VDOAC, &data);
  184127. + switch (vdoa->field) {
  184128. + case VDOA_FRAME:
  184129. + case VDOA_PREV_FIELD:
  184130. + vdoa_read_register(vdoa, VDOAIEBA00, &buf->ieba0);
  184131. + if (data & VDOAC_SYNC_BAND_MODE)
  184132. + vdoa_read_register(vdoa, VDOAIEBA10, &buf->ieba1);
  184133. + break;
  184134. + case VDOA_CURR_FIELD:
  184135. + vdoa_read_register(vdoa, VDOAIEBA01, &buf->ieba0);
  184136. + vdoa_read_register(vdoa, VDOAIEBA11, &buf->ieba1);
  184137. + break;
  184138. + case VDOA_NEXT_FIELD:
  184139. + vdoa_read_register(vdoa, VDOAIEBA02, &buf->ieba0);
  184140. + vdoa_read_register(vdoa, VDOAIEBA12, &buf->ieba1);
  184141. + break;
  184142. + default:
  184143. + BUG();
  184144. + break;
  184145. + }
  184146. + if (!(data & VDOAC_PFS_YUYV))
  184147. + vdoa_read_register(vdoa, VDOAIUBO, &buf->iubo);
  184148. +}
  184149. +
  184150. +int vdoa_start(vdoa_handle_t handle, int timeout_ms)
  184151. +{
  184152. + int ret;
  184153. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  184154. +
  184155. + CHECK_NULL_PTR(vdoa);
  184156. + CHECK_STATE(VDOA_GET_OBUF, return -EINVAL);
  184157. + vdoa->state = VDOA_START;
  184158. + init_completion(&vdoa->comp);
  184159. + vdoa_write_register(vdoa, VDOAIST,
  184160. + VDOAIEIST_TRANSFER_ERR | VDOAIEIST_TRANSFER_END);
  184161. + vdoa_write_register(vdoa, VDOAIE,
  184162. + VDOAIEIST_TRANSFER_ERR | VDOAIEIST_TRANSFER_END);
  184163. +
  184164. + enable_irq(vdoa->irq);
  184165. + vdoa_write_register(vdoa, VDOASRR, VDOASRR_START_XFER);
  184166. + dump_registers(vdoa);
  184167. +
  184168. + ret = wait_for_completion_timeout(&vdoa->comp,
  184169. + msecs_to_jiffies(timeout_ms));
  184170. +
  184171. + return ret > 0 ? 0 : -ETIMEDOUT;
  184172. +}
  184173. +
  184174. +void vdoa_stop(vdoa_handle_t handle)
  184175. +{
  184176. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  184177. +
  184178. + CHECK_NULL_PTR(vdoa);
  184179. + CHECK_STATE(VDOA_GET | VDOA_START | VDOA_INIRQ, return);
  184180. + vdoa->state = VDOA_STOP;
  184181. +
  184182. + disable_irq(vdoa->irq);
  184183. +
  184184. + vdoa_write_register(vdoa, VDOASRR, VDOASRR_SWRST);
  184185. +}
  184186. +
  184187. +void vdoa_get_handle(vdoa_handle_t *handle)
  184188. +{
  184189. + struct vdoa_info *vdoa = g_vdoa;
  184190. +
  184191. + CHECK_NULL_PTR(handle);
  184192. + *handle = (vdoa_handle_t *)NULL;
  184193. + CHECK_STATE(VDOA_INIT, return);
  184194. + mutex_lock(&vdoa_lock);
  184195. + clk_prepare_enable(vdoa->vdoa_clk);
  184196. + vdoa->state = VDOA_GET;
  184197. + vdoa->field = VDOA_NULL;
  184198. + vdoa_write_register(vdoa, VDOASRR, VDOASRR_SWRST);
  184199. +
  184200. + *handle = (vdoa_handle_t *)vdoa;
  184201. +}
  184202. +
  184203. +void vdoa_put_handle(vdoa_handle_t *handle)
  184204. +{
  184205. + struct vdoa_info *vdoa = (struct vdoa_info *)(*handle);
  184206. +
  184207. + CHECK_NULL_PTR(vdoa);
  184208. + CHECK_STATE(VDOA_STOP, return);
  184209. + if (vdoa != g_vdoa)
  184210. + BUG();
  184211. +
  184212. + clk_disable_unprepare(vdoa->vdoa_clk);
  184213. + vdoa->state = VDOA_PUT;
  184214. + *handle = (vdoa_handle_t *)NULL;
  184215. + mutex_unlock(&vdoa_lock);
  184216. +}
  184217. +
  184218. +static irqreturn_t vdoa_irq_handler(int irq, void *data)
  184219. +{
  184220. + u32 status, mask, val;
  184221. + struct vdoa_info *vdoa = data;
  184222. +
  184223. + CHECK_NULL_PTR(vdoa);
  184224. + CHECK_STATE(VDOA_START, return IRQ_HANDLED);
  184225. + vdoa->state = VDOA_INIRQ;
  184226. + vdoa_read_register(vdoa, VDOAIST, &status);
  184227. + vdoa_read_register(vdoa, VDOAIE, &mask);
  184228. + val = status & mask;
  184229. + vdoa_write_register(vdoa, VDOAIST, val);
  184230. + if (VDOAIEIST_TRANSFER_ERR & val)
  184231. + dev_err(vdoa->dev, "vdoa Transfer err irq!\n");
  184232. + if (VDOAIEIST_TRANSFER_END & val)
  184233. + dev_dbg(vdoa->dev, "vdoa Transfer end irq!\n");
  184234. + if (0 == val) {
  184235. + dev_err(vdoa->dev, "vdoa unknown irq!\n");
  184236. + BUG();
  184237. + }
  184238. +
  184239. + complete(&vdoa->comp);
  184240. + return IRQ_HANDLED;
  184241. +}
  184242. +
  184243. +/* IRAM Size in Kbytes, example:vdoa_iram_size=64, 64KBytes */
  184244. +static int __init vdoa_iram_size_setup(char *options)
  184245. +{
  184246. + int ret;
  184247. +
  184248. + ret = strict_strtoul(options, 0, &iram_size);
  184249. + if (ret)
  184250. + iram_size = 0;
  184251. + else
  184252. + iram_size *= SZ_1K;
  184253. +
  184254. + return 1;
  184255. +}
  184256. +__setup("vdoa_iram_size=", vdoa_iram_size_setup);
  184257. +
  184258. +static const struct of_device_id imx_vdoa_dt_ids[] = {
  184259. + { .compatible = "fsl,imx6q-vdoa", },
  184260. + { /* sentinel */ }
  184261. +};
  184262. +
  184263. +static int vdoa_probe(struct platform_device *pdev)
  184264. +{
  184265. + int ret;
  184266. + struct vdoa_info *vdoa;
  184267. + struct resource *res;
  184268. + struct resource *res_irq;
  184269. + struct device *dev = &pdev->dev;
  184270. + struct device_node *np = pdev->dev.of_node;
  184271. +
  184272. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  184273. + if (!res) {
  184274. + dev_err(dev, "can't get device resources\n");
  184275. + return -ENOENT;
  184276. + }
  184277. +
  184278. + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  184279. + if (!res_irq) {
  184280. + dev_err(dev, "failed to get irq resource\n");
  184281. + return -ENOENT;
  184282. + }
  184283. +
  184284. + vdoa = devm_kzalloc(dev, sizeof(struct vdoa_info), GFP_KERNEL);
  184285. + if (!vdoa)
  184286. + return -ENOMEM;
  184287. + vdoa->dev = dev;
  184288. +
  184289. + vdoa->reg_base = devm_request_and_ioremap(&pdev->dev, res);
  184290. + if (!vdoa->reg_base)
  184291. + return -EBUSY;
  184292. +
  184293. + vdoa->irq = res_irq->start;
  184294. + ret = devm_request_irq(dev, vdoa->irq, vdoa_irq_handler, 0,
  184295. + "vdoa", vdoa);
  184296. + if (ret) {
  184297. + dev_err(dev, "can't claim irq %d\n", vdoa->irq);
  184298. + return ret;
  184299. + }
  184300. + disable_irq(vdoa->irq);
  184301. +
  184302. + vdoa->vdoa_clk = devm_clk_get(dev, NULL);
  184303. + if (IS_ERR(vdoa->vdoa_clk)) {
  184304. + dev_err(dev, "failed to get vdoa_clk\n");
  184305. + return PTR_ERR(vdoa->vdoa_clk);
  184306. + }
  184307. +
  184308. + vdoa->iram_pool = of_get_named_gen_pool(np, "iram", 0);
  184309. + if (!vdoa->iram_pool) {
  184310. + dev_err(&pdev->dev, "iram pool not available\n");
  184311. + return -ENOMEM;
  184312. + }
  184313. +
  184314. + if ((iram_size == 0) || (iram_size > MAX_VDOA_IRAM_SIZE))
  184315. + iram_size = VDOA_IRAM_SIZE;
  184316. +
  184317. + vdoa->iram_base = gen_pool_alloc(vdoa->iram_pool, iram_size);
  184318. + if (!vdoa->iram_base) {
  184319. + dev_err(&pdev->dev, "unable to alloc iram\n");
  184320. + return -ENOMEM;
  184321. + }
  184322. +
  184323. + vdoa->iram_paddr = gen_pool_virt_to_phys(vdoa->iram_pool,
  184324. + vdoa->iram_base);
  184325. +
  184326. + dev_dbg(dev, "iram_base:0x%lx,iram_paddr:0x%lx,size:0x%lx\n",
  184327. + vdoa->iram_base, vdoa->iram_paddr, iram_size);
  184328. +
  184329. + vdoa->state = VDOA_INIT;
  184330. + dev_set_drvdata(dev, vdoa);
  184331. + g_vdoa = vdoa;
  184332. + dev_info(dev, "i.MX Video Data Order Adapter(VDOA) driver probed\n");
  184333. + return 0;
  184334. +}
  184335. +
  184336. +static int vdoa_remove(struct platform_device *pdev)
  184337. +{
  184338. + struct vdoa_info *vdoa = dev_get_drvdata(&pdev->dev);
  184339. +
  184340. + gen_pool_free(vdoa->iram_pool, vdoa->iram_base, iram_size);
  184341. + kfree(vdoa);
  184342. + dev_set_drvdata(&pdev->dev, NULL);
  184343. +
  184344. + return 0;
  184345. +}
  184346. +
  184347. +static struct platform_driver vdoa_driver = {
  184348. + .driver = {
  184349. + .name = "mxc_vdoa",
  184350. + .of_match_table = imx_vdoa_dt_ids,
  184351. + },
  184352. + .probe = vdoa_probe,
  184353. + .remove = vdoa_remove,
  184354. +};
  184355. +
  184356. +static int __init vdoa_init(void)
  184357. +{
  184358. + int err;
  184359. +
  184360. + err = platform_driver_register(&vdoa_driver);
  184361. + if (err) {
  184362. + pr_err("vdoa_driver register failed\n");
  184363. + return -ENODEV;
  184364. + }
  184365. + return 0;
  184366. +}
  184367. +
  184368. +static void __exit vdoa_cleanup(void)
  184369. +{
  184370. + platform_driver_unregister(&vdoa_driver);
  184371. +}
  184372. +
  184373. +module_init(vdoa_init);
  184374. +module_exit(vdoa_cleanup);
  184375. +
  184376. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  184377. +MODULE_DESCRIPTION("i.MX Video Data Order Adapter(VDOA) driver");
  184378. +MODULE_LICENSE("GPL");
  184379. diff -Nur linux-3.14.15/drivers/mxc/ipu3/vdoa.h linux-linaro-stable-mx6/drivers/mxc/ipu3/vdoa.h
  184380. --- linux-3.14.15/drivers/mxc/ipu3/vdoa.h 1970-01-01 01:00:00.000000000 +0100
  184381. +++ linux-linaro-stable-mx6/drivers/mxc/ipu3/vdoa.h 2014-08-20 19:23:53.578845924 +0200
  184382. @@ -0,0 +1,69 @@
  184383. +/*
  184384. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  184385. + *
  184386. + * This program is free software; you can redistribute it and/or modify
  184387. + * it under the terms of the GNU General Public License as published by
  184388. + * the Free Software Foundation; either version 2 of the License, or
  184389. + * (at your option) any later version.
  184390. +
  184391. + * This program is distributed in the hope that it will be useful,
  184392. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  184393. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  184394. + * GNU General Public License for more details.
  184395. +
  184396. + * You should have received a copy of the GNU General Public License along
  184397. + * with this program; if not, write to the Free Software Foundation, Inc.,
  184398. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  184399. + */
  184400. +
  184401. +#ifndef __VDOA_H__
  184402. +#define __VDOA_H__
  184403. +
  184404. +#define VDOA_PFS_YUYV (1)
  184405. +#define VDOA_PFS_NV12 (0)
  184406. +
  184407. +
  184408. +struct vfield_buf {
  184409. + u32 prev_veba;
  184410. + u32 cur_veba;
  184411. + u32 next_veba;
  184412. + u32 vubo;
  184413. +};
  184414. +
  184415. +struct vframe_buf {
  184416. + u32 veba;
  184417. + u32 vubo;
  184418. +};
  184419. +
  184420. +struct vdoa_params {
  184421. + u32 width;
  184422. + u32 height;
  184423. + int vpu_stride;
  184424. + int interlaced;
  184425. + int scan_order;
  184426. + int ipu_num;
  184427. + int band_lines;
  184428. + int band_mode;
  184429. + int pfs;
  184430. + u32 ieba0;
  184431. + u32 ieba1;
  184432. + u32 ieba2;
  184433. + struct vframe_buf vframe_buf;
  184434. + struct vfield_buf vfield_buf;
  184435. +};
  184436. +struct vdoa_ipu_buf {
  184437. + u32 ieba0;
  184438. + u32 ieba1;
  184439. + u32 iubo;
  184440. +};
  184441. +
  184442. +struct vdoa_info;
  184443. +typedef void *vdoa_handle_t;
  184444. +
  184445. +int vdoa_setup(vdoa_handle_t handle, struct vdoa_params *params);
  184446. +void vdoa_get_output_buf(vdoa_handle_t handle, struct vdoa_ipu_buf *buf);
  184447. +int vdoa_start(vdoa_handle_t handle, int timeout_ms);
  184448. +void vdoa_stop(vdoa_handle_t handle);
  184449. +void vdoa_get_handle(vdoa_handle_t *handle);
  184450. +void vdoa_put_handle(vdoa_handle_t *handle);
  184451. +#endif
  184452. diff -Nur linux-3.14.15/drivers/mxc/Kconfig linux-linaro-stable-mx6/drivers/mxc/Kconfig
  184453. --- linux-3.14.15/drivers/mxc/Kconfig 1970-01-01 01:00:00.000000000 +0100
  184454. +++ linux-linaro-stable-mx6/drivers/mxc/Kconfig 2014-08-20 19:23:53.554845822 +0200
  184455. @@ -0,0 +1,24 @@
  184456. +# drivers/mxc/Kconfig
  184457. +
  184458. +if ARCH_MXC
  184459. +
  184460. +menu "MXC support drivers"
  184461. +
  184462. +config MXC_IPU
  184463. + bool "Image Processing Unit Driver"
  184464. + select MXC_IPU_V3
  184465. + help
  184466. + If you plan to use the Image Processing unit, say
  184467. + Y here. IPU is needed by Framebuffer and V4L2 drivers.
  184468. +
  184469. +source "drivers/mxc/gpu-viv/Kconfig"
  184470. +source "drivers/mxc/ipu3/Kconfig"
  184471. +source "drivers/mxc/asrc/Kconfig"
  184472. +source "drivers/mxc/vpu/Kconfig"
  184473. +source "drivers/mxc/hdmi-cec/Kconfig"
  184474. +source "drivers/mxc/mipi/Kconfig"
  184475. +source "drivers/mxc/mlb/Kconfig"
  184476. +
  184477. +endmenu
  184478. +
  184479. +endif
  184480. diff -Nur linux-3.14.15/drivers/mxc/Makefile linux-linaro-stable-mx6/drivers/mxc/Makefile
  184481. --- linux-3.14.15/drivers/mxc/Makefile 1970-01-01 01:00:00.000000000 +0100
  184482. +++ linux-linaro-stable-mx6/drivers/mxc/Makefile 2014-08-20 19:23:53.554845822 +0200
  184483. @@ -0,0 +1,7 @@
  184484. +obj-$(CONFIG_MXC_GPU_VIV) += gpu-viv/
  184485. +obj-$(CONFIG_MXC_IPU_V3) += ipu3/
  184486. +obj-$(CONFIG_MXC_ASRC) += asrc/
  184487. +obj-$(CONFIG_MXC_VPU) += vpu/
  184488. +obj-$(CONFIG_MXC_HDMI_CEC) += hdmi-cec/
  184489. +obj-$(CONFIG_MXC_MIPI_CSI2) += mipi/
  184490. +obj-$(CONFIG_MXC_MLB) += mlb/
  184491. diff -Nur linux-3.14.15/drivers/mxc/mipi/Kconfig linux-linaro-stable-mx6/drivers/mxc/mipi/Kconfig
  184492. --- linux-3.14.15/drivers/mxc/mipi/Kconfig 1970-01-01 01:00:00.000000000 +0100
  184493. +++ linux-linaro-stable-mx6/drivers/mxc/mipi/Kconfig 2014-08-20 19:23:53.578845924 +0200
  184494. @@ -0,0 +1,14 @@
  184495. +#
  184496. +# MIPI configuration
  184497. +#
  184498. +
  184499. +menu "MXC MIPI Support"
  184500. +
  184501. +config MXC_MIPI_CSI2
  184502. + tristate "MIPI CSI2 support"
  184503. + depends on SOC_IMX6Q
  184504. + default n
  184505. + ---help---
  184506. + Say Y to get the MIPI CSI2 support.
  184507. +
  184508. +endmenu
  184509. diff -Nur linux-3.14.15/drivers/mxc/mipi/Makefile linux-linaro-stable-mx6/drivers/mxc/mipi/Makefile
  184510. --- linux-3.14.15/drivers/mxc/mipi/Makefile 1970-01-01 01:00:00.000000000 +0100
  184511. +++ linux-linaro-stable-mx6/drivers/mxc/mipi/Makefile 2014-08-20 19:23:53.578845924 +0200
  184512. @@ -0,0 +1,4 @@
  184513. +#
  184514. +# Makefile for the mipi interface driver
  184515. +#
  184516. +obj-$(CONFIG_MXC_MIPI_CSI2) += mxc_mipi_csi2.o
  184517. diff -Nur linux-3.14.15/drivers/mxc/mipi/mxc_mipi_csi2.c linux-linaro-stable-mx6/drivers/mxc/mipi/mxc_mipi_csi2.c
  184518. --- linux-3.14.15/drivers/mxc/mipi/mxc_mipi_csi2.c 1970-01-01 01:00:00.000000000 +0100
  184519. +++ linux-linaro-stable-mx6/drivers/mxc/mipi/mxc_mipi_csi2.c 2014-08-20 19:31:46.140869056 +0200
  184520. @@ -0,0 +1,540 @@
  184521. +/*
  184522. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  184523. + *
  184524. + * This program is free software; you can redistribute it and/or modify
  184525. + * it under the terms of the GNU General Public License as published by
  184526. + * the Free Software Foundation; either version 2 of the License, or
  184527. + * (at your option) any later version.
  184528. +
  184529. + * This program is distributed in the hope that it will be useful,
  184530. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  184531. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  184532. + * GNU General Public License for more details.
  184533. +
  184534. + * You should have received a copy of the GNU General Public License along
  184535. + * with this program; if not, write to the Free Software Foundation, Inc.,
  184536. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  184537. + */
  184538. +
  184539. +#include <linux/module.h>
  184540. +#include <linux/types.h>
  184541. +#include <linux/interrupt.h>
  184542. +#include <linux/irq.h>
  184543. +#include <linux/irqdesc.h>
  184544. +#include <linux/init.h>
  184545. +#include <linux/platform_device.h>
  184546. +#include <linux/err.h>
  184547. +#include <linux/clk.h>
  184548. +#include <linux/console.h>
  184549. +#include <linux/io.h>
  184550. +#include <linux/bitops.h>
  184551. +#include <linux/delay.h>
  184552. +#include <linux/fsl_devices.h>
  184553. +#include <linux/slab.h>
  184554. +#include <linux/of.h>
  184555. +
  184556. +#include <linux/mipi_csi2.h>
  184557. +
  184558. +#include "mxc_mipi_csi2.h"
  184559. +
  184560. +static struct mipi_csi2_info *gmipi_csi2;
  184561. +
  184562. +void _mipi_csi2_lock(struct mipi_csi2_info *info)
  184563. +{
  184564. + if (!in_irq() && !in_softirq())
  184565. + mutex_lock(&info->mutex_lock);
  184566. +}
  184567. +
  184568. +void _mipi_csi2_unlock(struct mipi_csi2_info *info)
  184569. +{
  184570. + if (!in_irq() && !in_softirq())
  184571. + mutex_unlock(&info->mutex_lock);
  184572. +}
  184573. +
  184574. +static inline void mipi_csi2_write(struct mipi_csi2_info *info,
  184575. + unsigned value, unsigned offset)
  184576. +{
  184577. + writel(value, info->mipi_csi2_base + offset);
  184578. +}
  184579. +
  184580. +static inline unsigned int mipi_csi2_read(struct mipi_csi2_info *info,
  184581. + unsigned offset)
  184582. +{
  184583. + return readl(info->mipi_csi2_base + offset);
  184584. +}
  184585. +
  184586. +/*!
  184587. + * This function is called to enable the mipi csi2 interface.
  184588. + *
  184589. + * @param info mipi csi2 hander
  184590. + * @return Returns setted value
  184591. + */
  184592. +bool mipi_csi2_enable(struct mipi_csi2_info *info)
  184593. +{
  184594. + bool status;
  184595. +
  184596. + _mipi_csi2_lock(info);
  184597. +
  184598. + if (!info->mipi_en) {
  184599. + info->mipi_en = true;
  184600. + clk_prepare_enable(info->cfg_clk);
  184601. + clk_prepare_enable(info->dphy_clk);
  184602. + } else
  184603. + mipi_dbg("mipi csi2 already enabled!\n");
  184604. +
  184605. + status = info->mipi_en;
  184606. +
  184607. + _mipi_csi2_unlock(info);
  184608. +
  184609. + return status;
  184610. +}
  184611. +EXPORT_SYMBOL(mipi_csi2_enable);
  184612. +
  184613. +/*!
  184614. + * This function is called to disable the mipi csi2 interface.
  184615. + *
  184616. + * @param info mipi csi2 hander
  184617. + * @return Returns setted value
  184618. + */
  184619. +bool mipi_csi2_disable(struct mipi_csi2_info *info)
  184620. +{
  184621. + bool status;
  184622. +
  184623. + _mipi_csi2_lock(info);
  184624. +
  184625. + if (info->mipi_en) {
  184626. + info->mipi_en = false;
  184627. + clk_disable_unprepare(info->dphy_clk);
  184628. + clk_disable_unprepare(info->cfg_clk);
  184629. + } else
  184630. + mipi_dbg("mipi csi2 already disabled!\n");
  184631. +
  184632. + status = info->mipi_en;
  184633. +
  184634. + _mipi_csi2_unlock(info);
  184635. +
  184636. + return status;
  184637. +}
  184638. +EXPORT_SYMBOL(mipi_csi2_disable);
  184639. +
  184640. +/*!
  184641. + * This function is called to get mipi csi2 disable/enable status.
  184642. + *
  184643. + * @param info mipi csi2 hander
  184644. + * @return Returns mipi csi2 status
  184645. + */
  184646. +bool mipi_csi2_get_status(struct mipi_csi2_info *info)
  184647. +{
  184648. + bool status;
  184649. +
  184650. + _mipi_csi2_lock(info);
  184651. + status = info->mipi_en;
  184652. + _mipi_csi2_unlock(info);
  184653. +
  184654. + return status;
  184655. +}
  184656. +EXPORT_SYMBOL(mipi_csi2_get_status);
  184657. +
  184658. +/*!
  184659. + * This function is called to set mipi lanes.
  184660. + *
  184661. + * @param info mipi csi2 hander
  184662. + * @return Returns setted value
  184663. + */
  184664. +unsigned int mipi_csi2_set_lanes(struct mipi_csi2_info *info)
  184665. +{
  184666. + unsigned int lanes;
  184667. +
  184668. + _mipi_csi2_lock(info);
  184669. + mipi_csi2_write(info, info->lanes - 1, MIPI_CSI2_N_LANES);
  184670. + lanes = mipi_csi2_read(info, MIPI_CSI2_N_LANES);
  184671. + _mipi_csi2_unlock(info);
  184672. +
  184673. + return lanes;
  184674. +}
  184675. +EXPORT_SYMBOL(mipi_csi2_set_lanes);
  184676. +
  184677. +/*!
  184678. + * This function is called to set mipi data type.
  184679. + *
  184680. + * @param info mipi csi2 hander
  184681. + * @return Returns setted value
  184682. + */
  184683. +unsigned int mipi_csi2_set_datatype(struct mipi_csi2_info *info,
  184684. + unsigned int datatype)
  184685. +{
  184686. + unsigned int dtype;
  184687. +
  184688. + _mipi_csi2_lock(info);
  184689. + info->datatype = datatype;
  184690. + dtype = info->datatype;
  184691. + _mipi_csi2_unlock(info);
  184692. +
  184693. + return dtype;
  184694. +}
  184695. +EXPORT_SYMBOL(mipi_csi2_set_datatype);
  184696. +
  184697. +/*!
  184698. + * This function is called to get mipi data type.
  184699. + *
  184700. + * @param info mipi csi2 hander
  184701. + * @return Returns mipi data type
  184702. + */
  184703. +unsigned int mipi_csi2_get_datatype(struct mipi_csi2_info *info)
  184704. +{
  184705. + unsigned int dtype;
  184706. +
  184707. + _mipi_csi2_lock(info);
  184708. + dtype = info->datatype;
  184709. + _mipi_csi2_unlock(info);
  184710. +
  184711. + return dtype;
  184712. +}
  184713. +EXPORT_SYMBOL(mipi_csi2_get_datatype);
  184714. +
  184715. +/*!
  184716. + * This function is called to get mipi csi2 dphy status.
  184717. + *
  184718. + * @param info mipi csi2 hander
  184719. + * @return Returns dphy status
  184720. + */
  184721. +unsigned int mipi_csi2_dphy_status(struct mipi_csi2_info *info)
  184722. +{
  184723. + unsigned int status;
  184724. +
  184725. + _mipi_csi2_lock(info);
  184726. + status = mipi_csi2_read(info, MIPI_CSI2_PHY_STATE);
  184727. + _mipi_csi2_unlock(info);
  184728. +
  184729. + return status;
  184730. +}
  184731. +EXPORT_SYMBOL(mipi_csi2_dphy_status);
  184732. +
  184733. +/*!
  184734. + * This function is called to get mipi csi2 error1 status.
  184735. + *
  184736. + * @param info mipi csi2 hander
  184737. + * @return Returns error1 value
  184738. + */
  184739. +unsigned int mipi_csi2_get_error1(struct mipi_csi2_info *info)
  184740. +{
  184741. + unsigned int err1;
  184742. +
  184743. + _mipi_csi2_lock(info);
  184744. + err1 = mipi_csi2_read(info, MIPI_CSI2_ERR1);
  184745. + _mipi_csi2_unlock(info);
  184746. +
  184747. + return err1;
  184748. +}
  184749. +EXPORT_SYMBOL(mipi_csi2_get_error1);
  184750. +
  184751. +/*!
  184752. + * This function is called to get mipi csi2 error1 status.
  184753. + *
  184754. + * @param info mipi csi2 hander
  184755. + * @return Returns error1 value
  184756. + */
  184757. +unsigned int mipi_csi2_get_error2(struct mipi_csi2_info *info)
  184758. +{
  184759. + unsigned int err2;
  184760. +
  184761. + _mipi_csi2_lock(info);
  184762. + err2 = mipi_csi2_read(info, MIPI_CSI2_ERR2);
  184763. + _mipi_csi2_unlock(info);
  184764. +
  184765. + return err2;
  184766. +}
  184767. +EXPORT_SYMBOL(mipi_csi2_get_error2);
  184768. +
  184769. +/*!
  184770. + * This function is called to enable mipi to ipu pixel clock.
  184771. + *
  184772. + * @param info mipi csi2 hander
  184773. + * @return Returns 0 on success or negative error code on fail
  184774. + */
  184775. +int mipi_csi2_pixelclk_enable(struct mipi_csi2_info *info)
  184776. +{
  184777. + return clk_prepare_enable(info->pixel_clk);
  184778. +}
  184779. +EXPORT_SYMBOL(mipi_csi2_pixelclk_enable);
  184780. +
  184781. +/*!
  184782. + * This function is called to disable mipi to ipu pixel clock.
  184783. + *
  184784. + * @param info mipi csi2 hander
  184785. + * @return Returns 0 on success or negative error code on fail
  184786. + */
  184787. +void mipi_csi2_pixelclk_disable(struct mipi_csi2_info *info)
  184788. +{
  184789. + clk_disable_unprepare(info->pixel_clk);
  184790. +}
  184791. +EXPORT_SYMBOL(mipi_csi2_pixelclk_disable);
  184792. +
  184793. +/*!
  184794. + * This function is called to power on mipi csi2.
  184795. + *
  184796. + * @param info mipi csi2 hander
  184797. + * @return Returns 0 on success or negative error code on fail
  184798. + */
  184799. +int mipi_csi2_reset(struct mipi_csi2_info *info)
  184800. +{
  184801. + _mipi_csi2_lock(info);
  184802. +
  184803. + mipi_csi2_write(info, 0x0, MIPI_CSI2_PHY_SHUTDOWNZ);
  184804. + mipi_csi2_write(info, 0x0, MIPI_CSI2_DPHY_RSTZ);
  184805. + mipi_csi2_write(info, 0x0, MIPI_CSI2_CSI2_RESETN);
  184806. +
  184807. + mipi_csi2_write(info, 0x00000001, MIPI_CSI2_PHY_TST_CTRL0);
  184808. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL1);
  184809. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
  184810. + mipi_csi2_write(info, 0x00000002, MIPI_CSI2_PHY_TST_CTRL0);
  184811. + mipi_csi2_write(info, 0x00010044, MIPI_CSI2_PHY_TST_CTRL1);
  184812. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
  184813. + mipi_csi2_write(info, 0x00000014, MIPI_CSI2_PHY_TST_CTRL1);
  184814. + mipi_csi2_write(info, 0x00000002, MIPI_CSI2_PHY_TST_CTRL0);
  184815. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
  184816. +
  184817. + mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_PHY_SHUTDOWNZ);
  184818. + mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_DPHY_RSTZ);
  184819. + mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_CSI2_RESETN);
  184820. +
  184821. + _mipi_csi2_unlock(info);
  184822. +
  184823. + return 0;
  184824. +}
  184825. +EXPORT_SYMBOL(mipi_csi2_reset);
  184826. +
  184827. +/*!
  184828. + * This function is called to get mipi csi2 info.
  184829. + *
  184830. + * @return Returns mipi csi2 info struct pointor
  184831. + */
  184832. +struct mipi_csi2_info *mipi_csi2_get_info(void)
  184833. +{
  184834. + return gmipi_csi2;
  184835. +}
  184836. +EXPORT_SYMBOL(mipi_csi2_get_info);
  184837. +
  184838. +/*!
  184839. + * This function is called to get mipi csi2 bind ipu num.
  184840. + *
  184841. + * @return Returns mipi csi2 bind ipu num
  184842. + */
  184843. +int mipi_csi2_get_bind_ipu(struct mipi_csi2_info *info)
  184844. +{
  184845. + int ipu_id;
  184846. +
  184847. + _mipi_csi2_lock(info);
  184848. + ipu_id = info->ipu_id;
  184849. + _mipi_csi2_unlock(info);
  184850. +
  184851. + return ipu_id;
  184852. +}
  184853. +EXPORT_SYMBOL(mipi_csi2_get_bind_ipu);
  184854. +
  184855. +/*!
  184856. + * This function is called to get mipi csi2 bind csi num.
  184857. + *
  184858. + * @return Returns mipi csi2 bind csi num
  184859. + */
  184860. +unsigned int mipi_csi2_get_bind_csi(struct mipi_csi2_info *info)
  184861. +{
  184862. + unsigned int csi_id;
  184863. +
  184864. + _mipi_csi2_lock(info);
  184865. + csi_id = info->csi_id;
  184866. + _mipi_csi2_unlock(info);
  184867. +
  184868. + return csi_id;
  184869. +}
  184870. +EXPORT_SYMBOL(mipi_csi2_get_bind_csi);
  184871. +
  184872. +/*!
  184873. + * This function is called to get mipi csi2 virtual channel.
  184874. + *
  184875. + * @return Returns mipi csi2 virtual channel num
  184876. + */
  184877. +unsigned int mipi_csi2_get_virtual_channel(struct mipi_csi2_info *info)
  184878. +{
  184879. + unsigned int v_channel;
  184880. +
  184881. + _mipi_csi2_lock(info);
  184882. + v_channel = info->v_channel;
  184883. + _mipi_csi2_unlock(info);
  184884. +
  184885. + return v_channel;
  184886. +}
  184887. +EXPORT_SYMBOL(mipi_csi2_get_virtual_channel);
  184888. +
  184889. +/**
  184890. + * This function is called by the driver framework to initialize the MIPI CSI2
  184891. + * device.
  184892. + *
  184893. + * @param pdev The device structure for the MIPI CSI2 passed in by the
  184894. + * driver framework.
  184895. + *
  184896. + * @return Returns 0 on success or negative error code on error
  184897. + */
  184898. +static int mipi_csi2_probe(struct platform_device *pdev)
  184899. +{
  184900. + struct device *dev = &pdev->dev;
  184901. + struct device_node *np = pdev->dev.of_node;
  184902. + struct resource *res;
  184903. + u32 mipi_csi2_dphy_ver;
  184904. + int ret;
  184905. +
  184906. + gmipi_csi2 = kmalloc(sizeof(struct mipi_csi2_info), GFP_KERNEL);
  184907. + if (!gmipi_csi2) {
  184908. + ret = -ENOMEM;
  184909. + goto alloc_failed;
  184910. + }
  184911. +
  184912. + ret = of_property_read_u32(np, "ipu_id", &(gmipi_csi2->ipu_id));
  184913. + if (ret) {
  184914. + dev_err(&pdev->dev, "ipu_id missing or invalid\n");
  184915. + goto err;
  184916. + }
  184917. +
  184918. + ret = of_property_read_u32(np, "csi_id", &(gmipi_csi2->csi_id));
  184919. + if (ret) {
  184920. + dev_err(&pdev->dev, "csi_id missing or invalid\n");
  184921. + goto err;
  184922. + }
  184923. +
  184924. + ret = of_property_read_u32(np, "v_channel", &(gmipi_csi2->v_channel));
  184925. + if (ret) {
  184926. + dev_err(&pdev->dev, "v_channel missing or invalid\n");
  184927. + goto err;
  184928. + }
  184929. +
  184930. + ret = of_property_read_u32(np, "lanes", &(gmipi_csi2->lanes));
  184931. + if (ret) {
  184932. + dev_err(&pdev->dev, "lanes missing or invalid\n");
  184933. + goto err;
  184934. + }
  184935. +
  184936. + if ((gmipi_csi2->ipu_id < 0) || (gmipi_csi2->ipu_id > 1) ||
  184937. + (gmipi_csi2->csi_id > 1) || (gmipi_csi2->v_channel > 3) ||
  184938. + (gmipi_csi2->lanes > 4)) {
  184939. + dev_err(&pdev->dev, "invalid param for mipi csi2!\n");
  184940. + ret = -EINVAL;
  184941. + goto err;
  184942. + }
  184943. +
  184944. + /* initialize mutex */
  184945. + mutex_init(&gmipi_csi2->mutex_lock);
  184946. +
  184947. + /* get mipi csi2 informaiton */
  184948. + gmipi_csi2->pdev = pdev;
  184949. + gmipi_csi2->mipi_en = false;
  184950. +
  184951. + gmipi_csi2->cfg_clk = devm_clk_get(dev, "cfg_clk");
  184952. + if (IS_ERR(gmipi_csi2->cfg_clk)) {
  184953. + dev_err(&pdev->dev, "failed to get cfg_clk\n");
  184954. + ret = PTR_ERR(gmipi_csi2->cfg_clk);
  184955. + goto err;
  184956. + }
  184957. +
  184958. + /* get mipi dphy clk */
  184959. + gmipi_csi2->dphy_clk = devm_clk_get(dev, "dphy_clk");
  184960. + if (IS_ERR(gmipi_csi2->dphy_clk)) {
  184961. + dev_err(&pdev->dev, "failed to get dphy pll_ref_clk\n");
  184962. + ret = PTR_ERR(gmipi_csi2->dphy_clk);
  184963. + goto err;
  184964. + }
  184965. +
  184966. + /* get mipi to ipu pixel clk */
  184967. + gmipi_csi2->pixel_clk = devm_clk_get(dev, "pixel_clk");
  184968. + if (IS_ERR(gmipi_csi2->pixel_clk)) {
  184969. + dev_err(&pdev->dev, "failed to get mipi pixel clk\n");
  184970. + ret = PTR_ERR(gmipi_csi2->pixel_clk);
  184971. + goto err;
  184972. + }
  184973. +
  184974. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  184975. + if (!res) {
  184976. + ret = -ENODEV;
  184977. + goto err;
  184978. + }
  184979. +
  184980. + /* mipi register mapping */
  184981. + gmipi_csi2->mipi_csi2_base = ioremap(res->start, PAGE_SIZE);
  184982. + if (!gmipi_csi2->mipi_csi2_base) {
  184983. + ret = -ENOMEM;
  184984. + goto err;
  184985. + }
  184986. +
  184987. + /* mipi dphy clk enable for register access */
  184988. + clk_prepare_enable(gmipi_csi2->dphy_clk);
  184989. + /* get mipi csi2 dphy version */
  184990. + mipi_csi2_dphy_ver = mipi_csi2_read(gmipi_csi2, MIPI_CSI2_VERSION);
  184991. +
  184992. + clk_disable_unprepare(gmipi_csi2->dphy_clk);
  184993. +
  184994. + platform_set_drvdata(pdev, gmipi_csi2);
  184995. +
  184996. + dev_info(&pdev->dev, "i.MX MIPI CSI2 driver probed\n");
  184997. + dev_info(&pdev->dev, "i.MX MIPI CSI2 dphy version is 0x%x\n",
  184998. + mipi_csi2_dphy_ver);
  184999. +
  185000. + return 0;
  185001. +
  185002. +err:
  185003. + kfree(gmipi_csi2);
  185004. +alloc_failed:
  185005. + dev_err(&pdev->dev, "i.MX MIPI CSI2 driver probed - error\n");
  185006. + return ret;
  185007. +}
  185008. +
  185009. +static int mipi_csi2_remove(struct platform_device *pdev)
  185010. +{
  185011. + /* unmapping mipi register */
  185012. + iounmap(gmipi_csi2->mipi_csi2_base);
  185013. +
  185014. + kfree(gmipi_csi2);
  185015. +
  185016. + dev_set_drvdata(&pdev->dev, NULL);
  185017. +
  185018. + return 0;
  185019. +}
  185020. +
  185021. +static const struct of_device_id imx_mipi_csi2_dt_ids[] = {
  185022. + { .compatible = "fsl,imx6q-mipi-csi2", },
  185023. + { /* sentinel */ }
  185024. +};
  185025. +
  185026. +static struct platform_driver mipi_csi2_driver = {
  185027. + .driver = {
  185028. + .name = "mxc_mipi_csi2",
  185029. + .of_match_table = imx_mipi_csi2_dt_ids,
  185030. + },
  185031. + .probe = mipi_csi2_probe,
  185032. + .remove = mipi_csi2_remove,
  185033. +};
  185034. +
  185035. +static int __init mipi_csi2_init(void)
  185036. +{
  185037. + int err;
  185038. +
  185039. + err = platform_driver_register(&mipi_csi2_driver);
  185040. + if (err) {
  185041. + pr_err("mipi_csi2_driver register failed\n");
  185042. + return -ENODEV;
  185043. + }
  185044. +
  185045. + pr_info("MIPI CSI2 driver module loaded\n");
  185046. +
  185047. + return 0;
  185048. +}
  185049. +
  185050. +static void __exit mipi_csi2_cleanup(void)
  185051. +{
  185052. + platform_driver_unregister(&mipi_csi2_driver);
  185053. +}
  185054. +
  185055. +subsys_initcall(mipi_csi2_init);
  185056. +module_exit(mipi_csi2_cleanup);
  185057. +
  185058. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  185059. +MODULE_DESCRIPTION("i.MX MIPI CSI2 driver");
  185060. +MODULE_LICENSE("GPL");
  185061. diff -Nur linux-3.14.15/drivers/mxc/mipi/mxc_mipi_csi2.h linux-linaro-stable-mx6/drivers/mxc/mipi/mxc_mipi_csi2.h
  185062. --- linux-3.14.15/drivers/mxc/mipi/mxc_mipi_csi2.h 1970-01-01 01:00:00.000000000 +0100
  185063. +++ linux-linaro-stable-mx6/drivers/mxc/mipi/mxc_mipi_csi2.h 2014-08-20 19:31:46.140869056 +0200
  185064. @@ -0,0 +1,46 @@
  185065. +/*
  185066. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  185067. + *
  185068. + * This program is free software; you can redistribute it and/or modify
  185069. + * it under the terms of the GNU General Public License as published by
  185070. + * the Free Software Foundation; either version 2 of the License, or
  185071. + * (at your option) any later version.
  185072. +
  185073. + * This program is distributed in the hope that it will be useful,
  185074. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  185075. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  185076. + * GNU General Public License for more details.
  185077. +
  185078. + * You should have received a copy of the GNU General Public License along
  185079. + * with this program; if not, write to the Free Software Foundation, Inc.,
  185080. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  185081. + */
  185082. +
  185083. +#ifndef __MXC_MIPI_CSI2_H__
  185084. +#define __MXC_MIPI_CSI2_H__
  185085. +
  185086. +#ifdef DEBUG
  185087. +#define mipi_dbg(fmt, ...) \
  185088. + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
  185089. +#else
  185090. +#define mipi_dbg(fmt, ...)
  185091. +#endif
  185092. +
  185093. +/* driver private data */
  185094. +struct mipi_csi2_info {
  185095. + bool mipi_en;
  185096. + int ipu_id;
  185097. + unsigned int csi_id;
  185098. + unsigned int v_channel;
  185099. + unsigned int lanes;
  185100. + unsigned int datatype;
  185101. + struct clk *cfg_clk;
  185102. + struct clk *dphy_clk;
  185103. + struct clk *pixel_clk;
  185104. + void __iomem *mipi_csi2_base;
  185105. + struct platform_device *pdev;
  185106. +
  185107. + struct mutex mutex_lock;
  185108. +};
  185109. +
  185110. +#endif
  185111. diff -Nur linux-3.14.15/drivers/mxc/mlb/Kconfig linux-linaro-stable-mx6/drivers/mxc/mlb/Kconfig
  185112. --- linux-3.14.15/drivers/mxc/mlb/Kconfig 1970-01-01 01:00:00.000000000 +0100
  185113. +++ linux-linaro-stable-mx6/drivers/mxc/mlb/Kconfig 2014-08-20 19:23:53.578845924 +0200
  185114. @@ -0,0 +1,17 @@
  185115. +#
  185116. +# MLB150 configuration
  185117. +#
  185118. +
  185119. +menu "MXC Media Local Bus Driver"
  185120. +
  185121. +config MXC_MLB
  185122. + boolean
  185123. +
  185124. +config MXC_MLB150
  185125. + tristate "MLB150 support"
  185126. + depends on SOC_IMX6Q
  185127. + select MXC_MLB
  185128. + ---help---
  185129. + Say Y to get the MLB150 support.
  185130. +
  185131. +endmenu
  185132. diff -Nur linux-3.14.15/drivers/mxc/mlb/Makefile linux-linaro-stable-mx6/drivers/mxc/mlb/Makefile
  185133. --- linux-3.14.15/drivers/mxc/mlb/Makefile 1970-01-01 01:00:00.000000000 +0100
  185134. +++ linux-linaro-stable-mx6/drivers/mxc/mlb/Makefile 2014-08-20 19:23:53.578845924 +0200
  185135. @@ -0,0 +1,5 @@
  185136. +#
  185137. +# Makefile for the i.MX6Q/DL MLB150 driver
  185138. +#
  185139. +
  185140. +obj-$(CONFIG_MXC_MLB150) += mxc_mlb150.o
  185141. diff -Nur linux-3.14.15/drivers/mxc/mlb/mxc_mlb150.c linux-linaro-stable-mx6/drivers/mxc/mlb/mxc_mlb150.c
  185142. --- linux-3.14.15/drivers/mxc/mlb/mxc_mlb150.c 1970-01-01 01:00:00.000000000 +0100
  185143. +++ linux-linaro-stable-mx6/drivers/mxc/mlb/mxc_mlb150.c 2014-08-20 19:23:53.578845924 +0200
  185144. @@ -0,0 +1,2778 @@
  185145. +/*
  185146. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  185147. + *
  185148. + * This program is free software; you can redistribute it and/or modify
  185149. + * it under the terms of the GNU General Public License as published by
  185150. + * the Free Software Foundation; either version 2 of the License, or
  185151. + * (at your option) any later version.
  185152. + *
  185153. + * This program is distributed in the hope that it will be useful,
  185154. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  185155. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  185156. + * GNU General Public License for more details.
  185157. + *
  185158. + * You should have received a copy of the GNU General Public License along
  185159. + * with this program; if not, write to the Free Software Foundation, Inc.,
  185160. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  185161. + */
  185162. +
  185163. +#include <linux/cdev.h>
  185164. +#include <linux/circ_buf.h>
  185165. +#include <linux/clk.h>
  185166. +#include <linux/delay.h>
  185167. +#include <linux/device.h>
  185168. +#include <linux/errno.h>
  185169. +#include <linux/fs.h>
  185170. +#include <linux/genalloc.h>
  185171. +#include <linux/init.h>
  185172. +#include <linux/interrupt.h>
  185173. +#include <linux/io.h>
  185174. +#include <linux/kernel.h>
  185175. +#include <linux/module.h>
  185176. +#include <linux/mxc_mlb.h>
  185177. +#include <linux/of.h>
  185178. +#include <linux/platform_device.h>
  185179. +#include <linux/poll.h>
  185180. +#include <linux/regulator/consumer.h>
  185181. +#include <linux/sched.h>
  185182. +#include <linux/slab.h>
  185183. +#include <linux/spinlock.h>
  185184. +#include <linux/uaccess.h>
  185185. +
  185186. +#define DRIVER_NAME "mxc_mlb150"
  185187. +
  185188. +/*
  185189. + * MLB module memory map registers define
  185190. + */
  185191. +#define REG_MLBC0 0x0
  185192. +#define MLBC0_MLBEN (0x1)
  185193. +#define MLBC0_MLBCLK_MASK (0x7 << 2)
  185194. +#define MLBC0_MLBCLK_SHIFT (2)
  185195. +#define MLBC0_MLBPEN (0x1 << 5)
  185196. +#define MLBC0_MLBLK (0x1 << 7)
  185197. +#define MLBC0_ASYRETRY (0x1 << 12)
  185198. +#define MLBC0_CTLRETRY (0x1 << 12)
  185199. +#define MLBC0_FCNT_MASK (0x7 << 15)
  185200. +#define MLBC0_FCNT_SHIFT (15)
  185201. +
  185202. +#define REG_MLBPC0 0x8
  185203. +#define MLBPC0_MCLKHYS (0x1 << 11)
  185204. +
  185205. +#define REG_MS0 0xC
  185206. +#define REG_MS1 0x14
  185207. +
  185208. +#define REG_MSS 0x20
  185209. +#define MSS_RSTSYSCMD (0x1)
  185210. +#define MSS_LKSYSCMD (0x1 << 1)
  185211. +#define MSS_ULKSYSCMD (0x1 << 2)
  185212. +#define MSS_CSSYSCMD (0x1 << 3)
  185213. +#define MSS_SWSYSCMD (0x1 << 4)
  185214. +#define MSS_SERVREQ (0x1 << 5)
  185215. +
  185216. +#define REG_MSD 0x24
  185217. +
  185218. +#define REG_MIEN 0x2C
  185219. +#define MIEN_ISOC_PE (0x1)
  185220. +#define MIEN_ISOC_BUFO (0x1 << 1)
  185221. +#define MIEN_SYNC_PE (0x1 << 16)
  185222. +#define MIEN_ARX_DONE (0x1 << 17)
  185223. +#define MIEN_ARX_PE (0x1 << 18)
  185224. +#define MIEN_ARX_BREAK (0x1 << 19)
  185225. +#define MIEN_ATX_DONE (0x1 << 20)
  185226. +#define MIEN_ATX_PE (0x1 << 21)
  185227. +#define MIEN_ATX_BREAK (0x1 << 22)
  185228. +#define MIEN_CRX_DONE (0x1 << 24)
  185229. +#define MIEN_CRX_PE (0x1 << 25)
  185230. +#define MIEN_CRX_BREAK (0x1 << 26)
  185231. +#define MIEN_CTX_DONE (0x1 << 27)
  185232. +#define MIEN_CTX_PE (0x1 << 28)
  185233. +#define MIEN_CTX_BREAK (0x1 << 29)
  185234. +
  185235. +#define REG_MLBPC2 0x34
  185236. +#define REG_MLBPC1 0x38
  185237. +#define MLBPC1_VAL (0x00000888)
  185238. +
  185239. +#define REG_MLBC1 0x3C
  185240. +#define MLBC1_LOCK (0x1 << 6)
  185241. +#define MLBC1_CLKM (0x1 << 7)
  185242. +#define MLBC1_NDA_MASK (0xFF << 8)
  185243. +#define MLBC1_NDA_SHIFT (8)
  185244. +
  185245. +#define REG_HCTL 0x80
  185246. +#define HCTL_RST0 (0x1)
  185247. +#define HCTL_RST1 (0x1 << 1)
  185248. +#define HCTL_EN (0x1 << 15)
  185249. +
  185250. +#define REG_HCMR0 0x88
  185251. +#define REG_HCMR1 0x8C
  185252. +#define REG_HCER0 0x90
  185253. +#define REG_HCER1 0x94
  185254. +#define REG_HCBR0 0x98
  185255. +#define REG_HCBR1 0x9C
  185256. +
  185257. +#define REG_MDAT0 0xC0
  185258. +#define REG_MDAT1 0xC4
  185259. +#define REG_MDAT2 0xC8
  185260. +#define REG_MDAT3 0xCC
  185261. +
  185262. +#define REG_MDWE0 0xD0
  185263. +#define REG_MDWE1 0xD4
  185264. +#define REG_MDWE2 0xD8
  185265. +#define REG_MDWE3 0xDC
  185266. +
  185267. +#define REG_MCTL 0xE0
  185268. +#define MCTL_XCMP (0x1)
  185269. +
  185270. +#define REG_MADR 0xE4
  185271. +#define MADR_WNR (0x1 << 31)
  185272. +#define MADR_TB (0x1 << 30)
  185273. +#define MADR_ADDR_MASK (0x7f << 8)
  185274. +#define MADR_ADDR_SHIFT (0)
  185275. +
  185276. +#define REG_ACTL 0x3C0
  185277. +#define ACTL_MPB (0x1 << 4)
  185278. +#define ACTL_DMAMODE (0x1 << 2)
  185279. +#define ACTL_SMX (0x1 << 1)
  185280. +#define ACTL_SCE (0x1)
  185281. +
  185282. +#define REG_ACSR0 0x3D0
  185283. +#define REG_ACSR1 0x3D4
  185284. +#define REG_ACMR0 0x3D8
  185285. +#define REG_ACMR1 0x3DC
  185286. +
  185287. +#define REG_CAT_MDATn(ch) (REG_MDAT0 + ((ch % 8) >> 1) * 4)
  185288. +#define REG_CAT_MDWEn(ch) (REG_MDWE0 + ((ch % 8) >> 1) * 4)
  185289. +
  185290. +#define INT_AHB0_CH_START (0)
  185291. +#define INT_AHB1_CH_START (32)
  185292. +
  185293. +#define LOGIC_CH_NUM (64)
  185294. +#define BUF_CDT_OFFSET (0x0)
  185295. +#define BUF_ADT_OFFSET (0x40)
  185296. +#define BUF_CAT_MLB_OFFSET (0x80)
  185297. +#define BUF_CAT_HBI_OFFSET (0x88)
  185298. +#define BUF_CTR_END_OFFSET (0x8F)
  185299. +
  185300. +#define CAT_MODE_RX (0x1 << 0)
  185301. +#define CAT_MODE_TX (0x1 << 1)
  185302. +#define CAT_MODE_INBOUND_DMA (0x1 << 8)
  185303. +#define CAT_MODE_OUTBOUND_DMA (0x1 << 9)
  185304. +
  185305. +#define CH_SYNC_DEFAULT_QUAD (1)
  185306. +#define CH_SYNC_MAX_QUAD (15)
  185307. +#define CH_SYNC_CDT_BUF_DEP (CH_SYNC_DEFAULT_QUAD * 4 * 4)
  185308. +#define CH_SYNC_ADT_BUF_MULTI (4)
  185309. +#define CH_SYNC_ADT_BUF_DEP (CH_SYNC_CDT_BUF_DEP * CH_SYNC_ADT_BUF_MULTI)
  185310. +#define CH_SYNC_BUF_SZ (CH_SYNC_MAX_QUAD * 4 * 4 * \
  185311. + CH_SYNC_ADT_BUF_MULTI)
  185312. +#define CH_CTRL_CDT_BUF_DEP (64)
  185313. +#define CH_CTRL_ADT_BUF_DEP (CH_CTRL_CDT_BUF_DEP)
  185314. +#define CH_CTRL_BUF_SZ (CH_CTRL_ADT_BUF_DEP)
  185315. +#define CH_ASYNC_MDP_PACKET_LEN (1024)
  185316. +#define CH_ASYNC_MEP_PACKET_LEN (1536)
  185317. +#define CH_ASYNC_CDT_BUF_DEP (CH_ASYNC_MEP_PACKET_LEN)
  185318. +#define CH_ASYNC_ADT_BUF_DEP (CH_ASYNC_CDT_BUF_DEP)
  185319. +#define CH_ASYNC_BUF_SZ (CH_ASYNC_ADT_BUF_DEP)
  185320. +#define CH_ISOC_BLK_SIZE_188 (188)
  185321. +#define CH_ISOC_BLK_SIZE_196 (196)
  185322. +#define CH_ISOC_BLK_SIZE (CH_ISOC_BLK_SIZE_188)
  185323. +#define CH_ISOC_BLK_NUM (1)
  185324. +#define CH_ISOC_CDT_BUF_DEP (CH_ISOC_BLK_SIZE * CH_ISOC_BLK_NUM)
  185325. +#define CH_ISOC_ADT_BUF_DEP (CH_ISOC_CDT_BUF_DEP)
  185326. +#define CH_ISOC_BUF_SZ (1024)
  185327. +
  185328. +#define CH_SYNC_DBR_BUF_OFFSET (0x0)
  185329. +#define CH_CTRL_DBR_BUF_OFFSET (CH_SYNC_DBR_BUF_OFFSET + \
  185330. + 2 * (CH_SYNC_MAX_QUAD * 4 * 4))
  185331. +#define CH_ASYNC_DBR_BUF_OFFSET (CH_CTRL_DBR_BUF_OFFSET + \
  185332. + 2 * CH_CTRL_CDT_BUF_DEP)
  185333. +#define CH_ISOC_DBR_BUF_OFFSET (CH_ASYNC_DBR_BUF_OFFSET + \
  185334. + 2 * CH_ASYNC_CDT_BUF_DEP)
  185335. +
  185336. +#define DBR_BUF_START 0x00000
  185337. +
  185338. +#define CDT_LEN (16)
  185339. +#define ADT_LEN (16)
  185340. +#define CAT_LEN (2)
  185341. +
  185342. +#define CDT_SZ (CDT_LEN * LOGIC_CH_NUM)
  185343. +#define ADT_SZ (ADT_LEN * LOGIC_CH_NUM)
  185344. +#define CAT_SZ (CAT_LEN * LOGIC_CH_NUM * 2)
  185345. +
  185346. +#define CDT_BASE(base) (base + BUF_CDT_OFFSET)
  185347. +#define ADT_BASE(base) (base + BUF_ADT_OFFSET)
  185348. +#define CAT_MLB_BASE(base) (base + BUF_CAT_MLB_OFFSET)
  185349. +#define CAT_HBI_BASE(base) (base + BUF_CAT_HBI_OFFSET)
  185350. +
  185351. +#define CDTn_ADDR(base, n) (base + BUF_CDT_OFFSET + n * CDT_LEN)
  185352. +#define ADTn_ADDR(base, n) (base + BUF_ADT_OFFSET + n * ADT_LEN)
  185353. +#define CATn_MLB_ADDR(base, n) (base + BUF_CAT_MLB_OFFSET + n * CAT_LEN)
  185354. +#define CATn_HBI_ADDR(base, n) (base + BUF_CAT_HBI_OFFSET + n * CAT_LEN)
  185355. +
  185356. +#define CAT_CL_SHIFT (0x0)
  185357. +#define CAT_CT_SHIFT (8)
  185358. +#define CAT_CE (0x1 << 11)
  185359. +#define CAT_RNW (0x1 << 12)
  185360. +#define CAT_MT (0x1 << 13)
  185361. +#define CAT_FCE (0x1 << 14)
  185362. +#define CAT_MFE (0x1 << 14)
  185363. +
  185364. +#define CDT_WSBC_SHIFT (14)
  185365. +#define CDT_WPC_SHIFT (11)
  185366. +#define CDT_RSBC_SHIFT (30)
  185367. +#define CDT_RPC_SHIFT (27)
  185368. +#define CDT_WPC_1_SHIFT (12)
  185369. +#define CDT_RPC_1_SHIFT (28)
  185370. +#define CDT_WPTR_SHIFT (0)
  185371. +#define CDT_SYNC_WSTS_MASK (0x0000f000)
  185372. +#define CDT_SYNC_WSTS_SHIFT (12)
  185373. +#define CDT_CTRL_ASYNC_WSTS_MASK (0x0000f000)
  185374. +#define CDT_CTRL_ASYNC_WSTS_SHIFT (12)
  185375. +#define CDT_ISOC_WSTS_MASK (0x0000e000)
  185376. +#define CDT_ISOC_WSTS_SHIFT (13)
  185377. +#define CDT_RPTR_SHIFT (16)
  185378. +#define CDT_SYNC_RSTS_MASK (0xf0000000)
  185379. +#define CDT_SYNC_RSTS_SHIFT (28)
  185380. +#define CDT_CTRL_ASYNC_RSTS_MASK (0xf0000000)
  185381. +#define CDT_CTRL_ASYNC_RSTS_SHIFT (28)
  185382. +#define CDT_ISOC_RSTS_MASK (0xe0000000)
  185383. +#define CDT_ISOC_RSTS_SHIFT (29)
  185384. +#define CDT_CTRL_ASYNC_WSTS_1 (0x1 << 14)
  185385. +#define CDT_CTRL_ASYNC_RSTS_1 (0x1 << 15)
  185386. +#define CDT_BD_SHIFT (0)
  185387. +#define CDT_BA_SHIFT (16)
  185388. +#define CDT_BS_SHIFT (0)
  185389. +#define CDT_BF_SHIFT (31)
  185390. +
  185391. +#define ADT_PG (0x1 << 13)
  185392. +#define ADT_LE (0x1 << 14)
  185393. +#define ADT_CE (0x1 << 15)
  185394. +#define ADT_BD1_SHIFT (0)
  185395. +#define ADT_ERR1 (0x1 << 13)
  185396. +#define ADT_DNE1 (0x1 << 14)
  185397. +#define ADT_RDY1 (0x1 << 15)
  185398. +#define ADT_BD2_SHIFT (16)
  185399. +#define ADT_ERR2 (0x1 << 29)
  185400. +#define ADT_DNE2 (0x1 << 30)
  185401. +#define ADT_RDY2 (0x1 << 31)
  185402. +#define ADT_BA1_SHIFT (0x0)
  185403. +#define ADT_BA2_SHIFT (0x0)
  185404. +#define ADT_PS1 (0x1 << 12)
  185405. +#define ADT_PS2 (0x1 << 28)
  185406. +#define ADT_MEP1 (0x1 << 11)
  185407. +#define ADT_MEP2 (0x1 << 27)
  185408. +
  185409. +#define MLB_MINOR_DEVICES 4
  185410. +#define MLB_CONTROL_DEV_NAME "ctrl"
  185411. +#define MLB_ASYNC_DEV_NAME "async"
  185412. +#define MLB_SYNC_DEV_NAME "sync"
  185413. +#define MLB_ISOC_DEV_NAME "isoc"
  185414. +
  185415. +#define TX_CHANNEL 0
  185416. +#define RX_CHANNEL 1
  185417. +
  185418. +#define TRANS_RING_NODES (1 << 3)
  185419. +
  185420. +enum MLB_CTYPE {
  185421. + MLB_CTYPE_SYNC,
  185422. + MLB_CTYPE_CTRL,
  185423. + MLB_CTYPE_ASYNC,
  185424. + MLB_CTYPE_ISOC,
  185425. +};
  185426. +
  185427. +enum CLK_SPEED {
  185428. + CLK_256FS,
  185429. + CLK_512FS,
  185430. + CLK_1024FS,
  185431. + CLK_2048FS,
  185432. + CLK_3072FS,
  185433. + CLK_4096FS,
  185434. + CLK_6144FS,
  185435. + CLK_8192FS,
  185436. +};
  185437. +
  185438. +struct mlb_ringbuf {
  185439. + s8 *virt_bufs[TRANS_RING_NODES];
  185440. + u32 phy_addrs[TRANS_RING_NODES];
  185441. + s32 head;
  185442. + s32 tail;
  185443. + s32 unit_size;
  185444. + s32 total_size;
  185445. + rwlock_t rb_lock ____cacheline_aligned; /* ring index lock */
  185446. +};
  185447. +
  185448. +struct mlb_channel_info {
  185449. + /* Input MLB channel address */
  185450. + u32 address;
  185451. + /* Internal AHB channel label */
  185452. + u32 cl;
  185453. + /* DBR buf head */
  185454. + u32 dbr_buf_head;
  185455. +};
  185456. +
  185457. +struct mlb_dev_info {
  185458. + /* device node name */
  185459. + const char dev_name[20];
  185460. + /* channel type */
  185461. + const unsigned int channel_type;
  185462. + /* ch fps */
  185463. + enum CLK_SPEED fps;
  185464. + /* channel info for tx/rx */
  185465. + struct mlb_channel_info channels[2];
  185466. + /* ring buffer */
  185467. + u8 *rbuf_base_virt;
  185468. + u32 rbuf_base_phy;
  185469. + struct mlb_ringbuf rx_rbuf;
  185470. + struct mlb_ringbuf tx_rbuf;
  185471. + /* exception event */
  185472. + unsigned long ex_event;
  185473. + /* tx busy indicator */
  185474. + unsigned long tx_busy;
  185475. + /* channel started up or not */
  185476. + atomic_t on;
  185477. + /* device open count */
  185478. + atomic_t opencnt;
  185479. + /* wait queue head for channel */
  185480. + wait_queue_head_t rx_wq;
  185481. + wait_queue_head_t tx_wq;
  185482. + /* TX OK */
  185483. + s32 tx_ok;
  185484. + /* spinlock for event access */
  185485. + spinlock_t event_lock;
  185486. + /*
  185487. + * Block size for isoc mode
  185488. + * This variable can be configured in ioctl
  185489. + */
  185490. + u32 isoc_blksz;
  185491. + /*
  185492. + * Quads number for sync mode
  185493. + * This variable can be confifured in ioctl
  185494. + */
  185495. + u32 sync_quad;
  185496. + /* Buffer depth in cdt */
  185497. + u32 cdt_buf_dep;
  185498. + /* Buffer depth in adt */
  185499. + u32 adt_buf_dep;
  185500. + /* Buffer size to hold data */
  185501. + u32 buf_size;
  185502. +};
  185503. +
  185504. +struct mlb_data {
  185505. + struct mlb_dev_info *devinfo;
  185506. + struct clk *clk_mlb3p;
  185507. + struct clk *clk_mlb6p;
  185508. + struct cdev cdev;
  185509. + struct class *class; /* device class */
  185510. + dev_t firstdev;
  185511. +#ifdef CONFIG_REGULATOR
  185512. + struct regulator *nvcc;
  185513. +#endif
  185514. + void __iomem *membase; /* mlb module base address */
  185515. + struct gen_pool *iram_pool;
  185516. + u32 iram_size;
  185517. + u32 irq_ahb0;
  185518. + u32 irq_ahb1;
  185519. + u32 irq_mlb;
  185520. +};
  185521. +
  185522. +/*
  185523. + * For optimization, we use fixed channel label for
  185524. + * input channels of each mode
  185525. + * SYNC: CL = 0 for RX, CL = 64 for TX
  185526. + * CTRL: CL = 1 for RX, CL = 65 for TX
  185527. + * ASYNC: CL = 2 for RX, CL = 66 for TX
  185528. + * ISOC: CL = 3 for RX, CL = 67 for TX
  185529. + */
  185530. +#define SYNC_RX_CL_AHB0 0
  185531. +#define CTRL_RX_CL_AHB0 1
  185532. +#define ASYNC_RX_CL_AHB0 2
  185533. +#define ISOC_RX_CL_AHB0 3
  185534. +#define SYNC_TX_CL_AHB0 4
  185535. +#define CTRL_TX_CL_AHB0 5
  185536. +#define ASYNC_TX_CL_AHB0 6
  185537. +#define ISOC_TX_CL_AHB0 7
  185538. +
  185539. +#define SYNC_RX_CL_AHB1 32
  185540. +#define CTRL_RX_CL_AHB1 33
  185541. +#define ASYNC_RX_CL_AHB1 34
  185542. +#define ISOC_RX_CL_AHB1 35
  185543. +#define SYNC_TX_CL_AHB1 36
  185544. +#define CTRL_TX_CL_AHB1 37
  185545. +#define ASYNC_TX_CL_AHB1 38
  185546. +#define ISOC_TX_CL_AHB1 39
  185547. +
  185548. +#define SYNC_RX_CL SYNC_RX_CL_AHB0
  185549. +#define CTRL_RX_CL CTRL_RX_CL_AHB0
  185550. +#define ASYNC_RX_CL ASYNC_RX_CL_AHB0
  185551. +#define ISOC_RX_CL ISOC_RX_CL_AHB0
  185552. +
  185553. +#define SYNC_TX_CL SYNC_TX_CL_AHB0
  185554. +#define CTRL_TX_CL CTRL_TX_CL_AHB0
  185555. +#define ASYNC_TX_CL ASYNC_TX_CL_AHB0
  185556. +#define ISOC_TX_CL ISOC_TX_CL_AHB0
  185557. +
  185558. +static struct mlb_dev_info mlb_devinfo[MLB_MINOR_DEVICES] = {
  185559. + {
  185560. + .dev_name = MLB_SYNC_DEV_NAME,
  185561. + .channel_type = MLB_CTYPE_SYNC,
  185562. + .channels = {
  185563. + [0] = {
  185564. + .cl = SYNC_TX_CL,
  185565. + .dbr_buf_head = CH_SYNC_DBR_BUF_OFFSET,
  185566. + },
  185567. + [1] = {
  185568. + .cl = SYNC_RX_CL,
  185569. + .dbr_buf_head = CH_SYNC_DBR_BUF_OFFSET
  185570. + + CH_SYNC_BUF_SZ,
  185571. + },
  185572. + },
  185573. + .rx_rbuf = {
  185574. + .unit_size = CH_SYNC_BUF_SZ,
  185575. + .rb_lock =
  185576. + __RW_LOCK_UNLOCKED(mlb_devinfo[0].rx_rbuf.rb_lock),
  185577. + },
  185578. + .tx_rbuf = {
  185579. + .unit_size = CH_SYNC_BUF_SZ,
  185580. + .rb_lock =
  185581. + __RW_LOCK_UNLOCKED(mlb_devinfo[0].tx_rbuf.rb_lock),
  185582. + },
  185583. + .cdt_buf_dep = CH_SYNC_CDT_BUF_DEP,
  185584. + .adt_buf_dep = CH_SYNC_ADT_BUF_DEP,
  185585. + .buf_size = CH_SYNC_BUF_SZ,
  185586. + .on = ATOMIC_INIT(0),
  185587. + .opencnt = ATOMIC_INIT(0),
  185588. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[0].event_lock),
  185589. + },
  185590. + {
  185591. + .dev_name = MLB_CONTROL_DEV_NAME,
  185592. + .channel_type = MLB_CTYPE_CTRL,
  185593. + .channels = {
  185594. + [0] = {
  185595. + .cl = CTRL_TX_CL,
  185596. + .dbr_buf_head = CH_CTRL_DBR_BUF_OFFSET,
  185597. + },
  185598. + [1] = {
  185599. + .cl = CTRL_RX_CL,
  185600. + .dbr_buf_head = CH_CTRL_DBR_BUF_OFFSET
  185601. + + CH_CTRL_BUF_SZ,
  185602. + },
  185603. + },
  185604. + .rx_rbuf = {
  185605. + .unit_size = CH_CTRL_BUF_SZ,
  185606. + .rb_lock =
  185607. + __RW_LOCK_UNLOCKED(mlb_devinfo[1].rx_rbuf.rb_lock),
  185608. + },
  185609. + .tx_rbuf = {
  185610. + .unit_size = CH_CTRL_BUF_SZ,
  185611. + .rb_lock =
  185612. + __RW_LOCK_UNLOCKED(mlb_devinfo[1].tx_rbuf.rb_lock),
  185613. + },
  185614. + .cdt_buf_dep = CH_CTRL_CDT_BUF_DEP,
  185615. + .adt_buf_dep = CH_CTRL_ADT_BUF_DEP,
  185616. + .buf_size = CH_CTRL_BUF_SZ,
  185617. + .on = ATOMIC_INIT(0),
  185618. + .opencnt = ATOMIC_INIT(0),
  185619. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[1].event_lock),
  185620. + },
  185621. + {
  185622. + .dev_name = MLB_ASYNC_DEV_NAME,
  185623. + .channel_type = MLB_CTYPE_ASYNC,
  185624. + .channels = {
  185625. + [0] = {
  185626. + .cl = ASYNC_TX_CL,
  185627. + .dbr_buf_head = CH_ASYNC_DBR_BUF_OFFSET,
  185628. + },
  185629. + [1] = {
  185630. + .cl = ASYNC_RX_CL,
  185631. + .dbr_buf_head = CH_ASYNC_DBR_BUF_OFFSET
  185632. + + CH_ASYNC_BUF_SZ,
  185633. + },
  185634. + },
  185635. + .rx_rbuf = {
  185636. + .unit_size = CH_ASYNC_BUF_SZ,
  185637. + .rb_lock =
  185638. + __RW_LOCK_UNLOCKED(mlb_devinfo[2].rx_rbuf.rb_lock),
  185639. + },
  185640. + .tx_rbuf = {
  185641. + .unit_size = CH_ASYNC_BUF_SZ,
  185642. + .rb_lock =
  185643. + __RW_LOCK_UNLOCKED(mlb_devinfo[2].tx_rbuf.rb_lock),
  185644. + },
  185645. + .cdt_buf_dep = CH_ASYNC_CDT_BUF_DEP,
  185646. + .adt_buf_dep = CH_ASYNC_ADT_BUF_DEP,
  185647. + .buf_size = CH_ASYNC_BUF_SZ,
  185648. + .on = ATOMIC_INIT(0),
  185649. + .opencnt = ATOMIC_INIT(0),
  185650. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[2].event_lock),
  185651. + },
  185652. + {
  185653. + .dev_name = MLB_ISOC_DEV_NAME,
  185654. + .channel_type = MLB_CTYPE_ISOC,
  185655. + .channels = {
  185656. + [0] = {
  185657. + .cl = ISOC_TX_CL,
  185658. + .dbr_buf_head = CH_ISOC_DBR_BUF_OFFSET,
  185659. + },
  185660. + [1] = {
  185661. + .cl = ISOC_RX_CL,
  185662. + .dbr_buf_head = CH_ISOC_DBR_BUF_OFFSET
  185663. + + CH_ISOC_BUF_SZ,
  185664. + },
  185665. + },
  185666. + .rx_rbuf = {
  185667. + .unit_size = CH_ISOC_BUF_SZ,
  185668. + .rb_lock =
  185669. + __RW_LOCK_UNLOCKED(mlb_devinfo[3].rx_rbuf.rb_lock),
  185670. + },
  185671. + .tx_rbuf = {
  185672. + .unit_size = CH_ISOC_BUF_SZ,
  185673. + .rb_lock =
  185674. + __RW_LOCK_UNLOCKED(mlb_devinfo[3].tx_rbuf.rb_lock),
  185675. + },
  185676. + .cdt_buf_dep = CH_ISOC_CDT_BUF_DEP,
  185677. + .adt_buf_dep = CH_ISOC_ADT_BUF_DEP,
  185678. + .buf_size = CH_ISOC_BUF_SZ,
  185679. + .on = ATOMIC_INIT(0),
  185680. + .opencnt = ATOMIC_INIT(0),
  185681. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[3].event_lock),
  185682. + .isoc_blksz = CH_ISOC_BLK_SIZE_188,
  185683. + },
  185684. +};
  185685. +
  185686. +static void __iomem *mlb_base;
  185687. +
  185688. +DEFINE_SPINLOCK(ctr_lock);
  185689. +
  185690. +#ifdef DEBUG
  185691. +#define DUMP_REG(reg) pr_debug(#reg": 0x%08x\n", __raw_readl(mlb_base + reg))
  185692. +
  185693. +static void mlb150_dev_dump_reg(void)
  185694. +{
  185695. + pr_debug("mxc_mlb150: Dump registers:\n");
  185696. + DUMP_REG(REG_MLBC0);
  185697. + DUMP_REG(REG_MLBPC0);
  185698. + DUMP_REG(REG_MS0);
  185699. + DUMP_REG(REG_MS1);
  185700. + DUMP_REG(REG_MSS);
  185701. + DUMP_REG(REG_MSD);
  185702. + DUMP_REG(REG_MIEN);
  185703. + DUMP_REG(REG_MLBPC2);
  185704. + DUMP_REG(REG_MLBPC1);
  185705. + DUMP_REG(REG_MLBC1);
  185706. + DUMP_REG(REG_HCTL);
  185707. + DUMP_REG(REG_HCMR0);
  185708. + DUMP_REG(REG_HCMR1);
  185709. + DUMP_REG(REG_HCER0);
  185710. + DUMP_REG(REG_HCER1);
  185711. + DUMP_REG(REG_HCBR0);
  185712. + DUMP_REG(REG_HCBR1);
  185713. + DUMP_REG(REG_MDAT0);
  185714. + DUMP_REG(REG_MDAT1);
  185715. + DUMP_REG(REG_MDAT2);
  185716. + DUMP_REG(REG_MDAT3);
  185717. + DUMP_REG(REG_MDWE0);
  185718. + DUMP_REG(REG_MDWE1);
  185719. + DUMP_REG(REG_MDWE2);
  185720. + DUMP_REG(REG_MDWE3);
  185721. + DUMP_REG(REG_MCTL);
  185722. + DUMP_REG(REG_MADR);
  185723. + DUMP_REG(REG_ACTL);
  185724. + DUMP_REG(REG_ACSR0);
  185725. + DUMP_REG(REG_ACSR1);
  185726. + DUMP_REG(REG_ACMR0);
  185727. + DUMP_REG(REG_ACMR1);
  185728. +}
  185729. +
  185730. +static void mlb150_dev_dump_hex(const u8 *buf, u32 len)
  185731. +{
  185732. + print_hex_dump(KERN_DEBUG, "CTR DUMP:",
  185733. + DUMP_PREFIX_OFFSET, 8, 1, buf, len, 0);
  185734. +}
  185735. +#endif
  185736. +
  185737. +static inline void mlb150_dev_enable_ctr_write(u32 mdat0_bits_en,
  185738. + u32 mdat1_bits_en, u32 mdat2_bits_en, u32 mdat3_bits_en)
  185739. +{
  185740. + __raw_writel(mdat0_bits_en, mlb_base + REG_MDWE0);
  185741. + __raw_writel(mdat1_bits_en, mlb_base + REG_MDWE1);
  185742. + __raw_writel(mdat2_bits_en, mlb_base + REG_MDWE2);
  185743. + __raw_writel(mdat3_bits_en, mlb_base + REG_MDWE3);
  185744. +}
  185745. +
  185746. +#ifdef DEBUG
  185747. +static inline u8 mlb150_dev_dbr_read(u32 dbr_addr)
  185748. +{
  185749. + s32 timeout = 1000;
  185750. + u8 dbr_val = 0;
  185751. + unsigned long flags;
  185752. +
  185753. + spin_lock_irqsave(&ctr_lock, flags);
  185754. + __raw_writel(MADR_TB | dbr_addr,
  185755. + mlb_base + REG_MADR);
  185756. +
  185757. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  185758. + & MCTL_XCMP)) &&
  185759. + timeout--)
  185760. + ;
  185761. +
  185762. + if (0 == timeout) {
  185763. + spin_unlock_irqrestore(&ctr_lock, flags);
  185764. + return -ETIME;
  185765. + }
  185766. +
  185767. + dbr_val = __raw_readl(mlb_base + REG_MDAT0) & 0x000000ff;
  185768. +
  185769. + __raw_writel(0, mlb_base + REG_MCTL);
  185770. + spin_unlock_irqrestore(&ctr_lock, flags);
  185771. +
  185772. + return dbr_val;
  185773. +}
  185774. +
  185775. +static inline s32 mlb150_dev_dbr_write(u32 dbr_addr, u8 dbr_val)
  185776. +{
  185777. + s32 timeout = 1000;
  185778. + u32 mdat0 = dbr_val & 0x000000ff;
  185779. + unsigned long flags;
  185780. +
  185781. + spin_lock_irqsave(&ctr_lock, flags);
  185782. + __raw_writel(mdat0, mlb_base + REG_MDAT0);
  185783. +
  185784. + __raw_writel(MADR_WNR | MADR_TB | dbr_addr,
  185785. + mlb_base + REG_MADR);
  185786. +
  185787. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  185788. + & MCTL_XCMP)) &&
  185789. + timeout--)
  185790. + ;
  185791. +
  185792. + if (timeout <= 0) {
  185793. + spin_unlock_irqrestore(&ctr_lock, flags);
  185794. + return -ETIME;
  185795. + }
  185796. +
  185797. + __raw_writel(0, mlb_base + REG_MCTL);
  185798. + spin_unlock_irqrestore(&ctr_lock, flags);
  185799. +
  185800. + return 0;
  185801. +}
  185802. +
  185803. +static inline s32 mlb150_dev_dbr_dump(u32 addr, u32 size)
  185804. +{
  185805. + u8 *dump_buf = NULL;
  185806. + u8 *buf_ptr = NULL;
  185807. + s32 i;
  185808. +
  185809. + dump_buf = kzalloc(size, GFP_KERNEL);
  185810. + if (!dump_buf) {
  185811. + pr_err("can't allocate enough memory\n");
  185812. + return -ENOMEM;
  185813. + }
  185814. +
  185815. + for (i = 0, buf_ptr = dump_buf;
  185816. + i < size; ++i, ++buf_ptr)
  185817. + *buf_ptr = mlb150_dev_dbr_read(addr + i);
  185818. +
  185819. + mlb150_dev_dump_hex(dump_buf, size);
  185820. +
  185821. + kfree(dump_buf);
  185822. +
  185823. + return 0;
  185824. +}
  185825. +#endif
  185826. +
  185827. +static s32 mlb150_dev_ctr_read(u32 ctr_offset, u32 *ctr_val)
  185828. +{
  185829. + s32 timeout = 1000;
  185830. + unsigned long flags;
  185831. +
  185832. + spin_lock_irqsave(&ctr_lock, flags);
  185833. + __raw_writel(ctr_offset, mlb_base + REG_MADR);
  185834. +
  185835. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  185836. + & MCTL_XCMP)) &&
  185837. + timeout--)
  185838. + ;
  185839. +
  185840. + if (timeout <= 0) {
  185841. + spin_unlock_irqrestore(&ctr_lock, flags);
  185842. + pr_debug("mxc_mlb150: Read CTR timeout\n");
  185843. + return -ETIME;
  185844. + }
  185845. +
  185846. + ctr_val[0] = __raw_readl(mlb_base + REG_MDAT0);
  185847. + ctr_val[1] = __raw_readl(mlb_base + REG_MDAT1);
  185848. + ctr_val[2] = __raw_readl(mlb_base + REG_MDAT2);
  185849. + ctr_val[3] = __raw_readl(mlb_base + REG_MDAT3);
  185850. +
  185851. + __raw_writel(0, mlb_base + REG_MCTL);
  185852. +
  185853. + spin_unlock_irqrestore(&ctr_lock, flags);
  185854. +
  185855. + return 0;
  185856. +}
  185857. +
  185858. +static s32 mlb150_dev_ctr_write(u32 ctr_offset, const u32 *ctr_val)
  185859. +{
  185860. + s32 timeout = 1000;
  185861. + unsigned long flags;
  185862. +
  185863. + spin_lock_irqsave(&ctr_lock, flags);
  185864. +
  185865. + __raw_writel(ctr_val[0], mlb_base + REG_MDAT0);
  185866. + __raw_writel(ctr_val[1], mlb_base + REG_MDAT1);
  185867. + __raw_writel(ctr_val[2], mlb_base + REG_MDAT2);
  185868. + __raw_writel(ctr_val[3], mlb_base + REG_MDAT3);
  185869. +
  185870. + __raw_writel(MADR_WNR | ctr_offset,
  185871. + mlb_base + REG_MADR);
  185872. +
  185873. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  185874. + & MCTL_XCMP)) &&
  185875. + timeout--)
  185876. + ;
  185877. +
  185878. + if (timeout <= 0) {
  185879. + spin_unlock_irqrestore(&ctr_lock, flags);
  185880. + pr_debug("mxc_mlb150: Write CTR timeout\n");
  185881. + return -ETIME;
  185882. + }
  185883. +
  185884. + __raw_writel(0, mlb_base + REG_MCTL);
  185885. +
  185886. + spin_unlock_irqrestore(&ctr_lock, flags);
  185887. +
  185888. +#ifdef DEBUG_CTR
  185889. + {
  185890. + u32 ctr_rd[4] = { 0 };
  185891. +
  185892. + if (!mlb150_dev_ctr_read(ctr_offset, ctr_rd)) {
  185893. + if (ctr_val[0] == ctr_rd[0] &&
  185894. + ctr_val[1] == ctr_rd[1] &&
  185895. + ctr_val[2] == ctr_rd[2] &&
  185896. + ctr_val[3] == ctr_rd[3])
  185897. + return 0;
  185898. + else {
  185899. + pr_debug("mxc_mlb150: ctr write failed\n");
  185900. + pr_debug("offset: 0x%x\n", ctr_offset);
  185901. + pr_debug("Write: 0x%x 0x%x 0x%x 0x%x\n",
  185902. + ctr_val[3], ctr_val[2],
  185903. + ctr_val[1], ctr_val[0]);
  185904. + pr_debug("Read: 0x%x 0x%x 0x%x 0x%x\n",
  185905. + ctr_rd[3], ctr_rd[2],
  185906. + ctr_rd[1], ctr_rd[0]);
  185907. + return -EBADE;
  185908. + }
  185909. + } else {
  185910. + pr_debug("mxc_mlb150: ctr read failed\n");
  185911. + return -EBADE;
  185912. + }
  185913. + }
  185914. +#endif
  185915. +
  185916. + return 0;
  185917. +}
  185918. +
  185919. +#ifdef DEBUG
  185920. +static s32 mlb150_dev_cat_read(u32 ctr_offset, u32 ch, u16 *cat_val)
  185921. +{
  185922. + u16 ctr_val[8] = { 0 };
  185923. +
  185924. + if (mlb150_dev_ctr_read(ctr_offset, (u32 *)ctr_val))
  185925. + return -ETIME;
  185926. +
  185927. + /*
  185928. + * Use u16 array to get u32 array value,
  185929. + * need to convert
  185930. + */
  185931. + cat_val = ctr_val[ch % 8];
  185932. +
  185933. + return 0;
  185934. +}
  185935. +#endif
  185936. +
  185937. +static s32 mlb150_dev_cat_write(u32 ctr_offset, u32 ch, const u16 cat_val)
  185938. +{
  185939. + u16 ctr_val[8] = { 0 };
  185940. +
  185941. + if (mlb150_dev_ctr_read(ctr_offset, (u32 *)ctr_val))
  185942. + return -ETIME;
  185943. +
  185944. + ctr_val[ch % 8] = cat_val;
  185945. + if (mlb150_dev_ctr_write(ctr_offset, (u32 *)ctr_val))
  185946. + return -ETIME;
  185947. +
  185948. + return 0;
  185949. +}
  185950. +
  185951. +#define mlb150_dev_cat_mlb_read(ch, cat_val) \
  185952. + mlb150_dev_cat_read(BUF_CAT_MLB_OFFSET + (ch >> 3), ch, cat_val)
  185953. +#define mlb150_dev_cat_mlb_write(ch, cat_val) \
  185954. + mlb150_dev_cat_write(BUF_CAT_MLB_OFFSET + (ch >> 3), ch, cat_val)
  185955. +#define mlb150_dev_cat_hbi_read(ch, cat_val) \
  185956. + mlb150_dev_cat_read(BUF_CAT_HBI_OFFSET + (ch >> 3), ch, cat_val)
  185957. +#define mlb150_dev_cat_hbi_write(ch, cat_val) \
  185958. + mlb150_dev_cat_write(BUF_CAT_HBI_OFFSET + (ch >> 3), ch, cat_val)
  185959. +
  185960. +#define mlb150_dev_cdt_read(ch, cdt_val) \
  185961. + mlb150_dev_ctr_read(BUF_CDT_OFFSET + ch, cdt_val)
  185962. +#define mlb150_dev_cdt_write(ch, cdt_val) \
  185963. + mlb150_dev_ctr_write(BUF_CDT_OFFSET + ch, cdt_val)
  185964. +#define mlb150_dev_adt_read(ch, adt_val) \
  185965. + mlb150_dev_ctr_read(BUF_ADT_OFFSET + ch, adt_val)
  185966. +#define mlb150_dev_adt_write(ch, adt_val) \
  185967. + mlb150_dev_ctr_write(BUF_ADT_OFFSET + ch, adt_val)
  185968. +
  185969. +static s32 mlb150_dev_get_adt_sts(u32 ch)
  185970. +{
  185971. + s32 timeout = 1000;
  185972. + unsigned long flags;
  185973. + u32 reg;
  185974. +
  185975. + spin_lock_irqsave(&ctr_lock, flags);
  185976. + __raw_writel(BUF_ADT_OFFSET + ch,
  185977. + mlb_base + REG_MADR);
  185978. +
  185979. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  185980. + & MCTL_XCMP)) &&
  185981. + timeout--)
  185982. + ;
  185983. +
  185984. + if (timeout <= 0) {
  185985. + spin_unlock_irqrestore(&ctr_lock, flags);
  185986. + pr_debug("mxc_mlb150: Read CTR timeout\n");
  185987. + return -ETIME;
  185988. + }
  185989. +
  185990. + reg = __raw_readl(mlb_base + REG_MDAT1);
  185991. +
  185992. + __raw_writel(0, mlb_base + REG_MCTL);
  185993. + spin_unlock_irqrestore(&ctr_lock, flags);
  185994. +
  185995. +#ifdef DEBUG_ADT
  185996. + pr_debug("mxc_mlb150: Get ch %d adt sts: 0x%08x\n", ch, reg);
  185997. +#endif
  185998. +
  185999. + return reg;
  186000. +}
  186001. +
  186002. +#ifdef DEBUG
  186003. +static void mlb150_dev_dump_ctr_tbl(u32 ch_start, u32 ch_end)
  186004. +{
  186005. + u32 i = 0;
  186006. + u32 ctr_val[4] = { 0 };
  186007. +
  186008. + pr_debug("mxc_mlb150: CDT Table");
  186009. + for (i = BUF_CDT_OFFSET + ch_start;
  186010. + i < BUF_CDT_OFFSET + ch_end;
  186011. + ++i) {
  186012. + mlb150_dev_ctr_read(i, ctr_val);
  186013. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  186014. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  186015. + }
  186016. +
  186017. + pr_debug("mxc_mlb150: ADT Table");
  186018. + for (i = BUF_ADT_OFFSET + ch_start;
  186019. + i < BUF_ADT_OFFSET + ch_end;
  186020. + ++i) {
  186021. + mlb150_dev_ctr_read(i, ctr_val);
  186022. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  186023. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  186024. + }
  186025. +
  186026. + pr_debug("mxc_mlb150: CAT MLB Table");
  186027. + for (i = BUF_CAT_MLB_OFFSET + (ch_start >> 3);
  186028. + i <= BUF_CAT_MLB_OFFSET + ((ch_end + 8) >> 3);
  186029. + ++i) {
  186030. + mlb150_dev_ctr_read(i, ctr_val);
  186031. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  186032. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  186033. + }
  186034. +
  186035. + pr_debug("mxc_mlb150: CAT HBI Table");
  186036. + for (i = BUF_CAT_HBI_OFFSET + (ch_start >> 3);
  186037. + i <= BUF_CAT_HBI_OFFSET + ((ch_end + 8) >> 3);
  186038. + ++i) {
  186039. + mlb150_dev_ctr_read(i, ctr_val);
  186040. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  186041. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  186042. + }
  186043. +}
  186044. +#endif
  186045. +
  186046. +/*
  186047. + * Initial the MLB module device
  186048. + */
  186049. +static inline void mlb150_dev_enable_dma_irq(u32 enable)
  186050. +{
  186051. + u32 ch_rx_mask = (1 << SYNC_RX_CL_AHB0) | (1 << CTRL_RX_CL_AHB0)
  186052. + | (1 << ASYNC_RX_CL_AHB0) | (1 << ISOC_RX_CL_AHB0)
  186053. + | (1 << SYNC_TX_CL_AHB0) | (1 << CTRL_TX_CL_AHB0)
  186054. + | (1 << ASYNC_TX_CL_AHB0) | (1 << ISOC_TX_CL_AHB0);
  186055. + u32 ch_tx_mask = (1 << (SYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186056. + (1 << (CTRL_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186057. + (1 << (ASYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186058. + (1 << (ISOC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186059. + (1 << (SYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186060. + (1 << (CTRL_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186061. + (1 << (ASYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186062. + (1 << (ISOC_TX_CL_AHB1 - INT_AHB1_CH_START));
  186063. +
  186064. + if (enable) {
  186065. + __raw_writel(ch_rx_mask, mlb_base + REG_ACMR0);
  186066. + __raw_writel(ch_tx_mask, mlb_base + REG_ACMR1);
  186067. + } else {
  186068. + __raw_writel(0x0, mlb_base + REG_ACMR0);
  186069. + __raw_writel(0x0, mlb_base + REG_ACMR1);
  186070. + }
  186071. +}
  186072. +
  186073. +
  186074. +static void mlb150_dev_init_ir_amba_ahb(void)
  186075. +{
  186076. + u32 reg = 0;
  186077. +
  186078. + /*
  186079. + * Step 1. Program the ACMRn registers to enable interrupts from all
  186080. + * active DMA channels
  186081. + */
  186082. + mlb150_dev_enable_dma_irq(1);
  186083. +
  186084. + /*
  186085. + * Step 2. Select the status clear method:
  186086. + * ACTL.SCE = 0, hardware clears on read
  186087. + * ACTL.SCE = 1, software writes a '1' to clear
  186088. + * We only support DMA MODE 1
  186089. + */
  186090. + reg = __raw_readl(mlb_base + REG_ACTL);
  186091. + reg |= ACTL_DMAMODE;
  186092. +#ifdef MULTIPLE_PACKAGE_MODE
  186093. + reg |= REG_ACTL_MPB;
  186094. +#endif
  186095. +
  186096. + /*
  186097. + * Step 3. Select 1 or 2 interrupt signals:
  186098. + * ACTL.SMX = 0: one interrupt for channels 0 - 31 on ahb_init[0]
  186099. + * and another interrupt for channels 32 - 63 on ahb_init[1]
  186100. + * ACTL.SMX = 1: singel interrupt all channels on ahb_init[0]
  186101. + */
  186102. + reg &= ~ACTL_SMX;
  186103. +
  186104. + __raw_writel(reg, mlb_base + REG_ACTL);
  186105. +}
  186106. +
  186107. +static inline void mlb150_dev_enable_ir_mlb(u32 enable)
  186108. +{
  186109. + /*
  186110. + * Step 1, Select the MSn to be cleared by software,
  186111. + * writing a '0' to the appropriate bits
  186112. + */
  186113. + __raw_writel(0, mlb_base + REG_MS0);
  186114. + __raw_writel(0, mlb_base + REG_MS1);
  186115. +
  186116. + /*
  186117. + * Step 1, Program MIEN to enable protocol error
  186118. + * interrupts for all active MLB channels
  186119. + */
  186120. + if (enable)
  186121. + __raw_writel(MIEN_CTX_PE |
  186122. + MIEN_CRX_PE | MIEN_ATX_PE |
  186123. + MIEN_ARX_PE | MIEN_SYNC_PE |
  186124. + MIEN_ISOC_PE,
  186125. + mlb_base + REG_MIEN);
  186126. + else
  186127. + __raw_writel(0, mlb_base + REG_MIEN);
  186128. +}
  186129. +
  186130. +static inline void mlb150_enable_pll(struct mlb_data *drvdata)
  186131. +{
  186132. + u32 c0_val;
  186133. +
  186134. + __raw_writel(MLBPC1_VAL,
  186135. + drvdata->membase + REG_MLBPC1);
  186136. +
  186137. + c0_val = __raw_readl(drvdata->membase + REG_MLBC0);
  186138. + if (c0_val & MLBC0_MLBPEN) {
  186139. + c0_val &= ~MLBC0_MLBPEN;
  186140. + __raw_writel(c0_val,
  186141. + drvdata->membase + REG_MLBC0);
  186142. + }
  186143. +
  186144. + clk_prepare_enable(drvdata->clk_mlb6p);
  186145. +
  186146. + c0_val |= (MLBC0_MLBPEN);
  186147. + __raw_writel(c0_val, drvdata->membase + REG_MLBC0);
  186148. +}
  186149. +
  186150. +static inline void mlb150_disable_pll(struct mlb_data *drvdata)
  186151. +{
  186152. + u32 c0_val;
  186153. +
  186154. + clk_disable_unprepare(drvdata->clk_mlb6p);
  186155. +
  186156. + c0_val = __raw_readl(drvdata->membase + REG_MLBC0);
  186157. +
  186158. + __raw_writel(0x0, drvdata->membase + REG_MLBPC1);
  186159. +
  186160. + c0_val &= ~MLBC0_MLBPEN;
  186161. + __raw_writel(c0_val, drvdata->membase + REG_MLBC0);
  186162. +}
  186163. +
  186164. +static void mlb150_dev_reset_cdt(void)
  186165. +{
  186166. + int i = 0;
  186167. + u32 ctr_val[4] = { 0 };
  186168. +
  186169. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  186170. + 0xffffffff, 0xffffffff);
  186171. +
  186172. + for (i = 0; i < (LOGIC_CH_NUM); ++i)
  186173. + mlb150_dev_ctr_write(BUF_CDT_OFFSET + i, ctr_val);
  186174. +}
  186175. +
  186176. +static s32 mlb150_dev_init_ch_cdt(struct mlb_dev_info *pdevinfo, u32 ch,
  186177. + enum MLB_CTYPE ctype, u32 ch_func)
  186178. +{
  186179. + u32 cdt_val[4] = { 0 };
  186180. +
  186181. + /* a. Set the 14-bit base address (BA) */
  186182. + pr_debug("mxc_mlb150: ctype: %d, ch: %d, dbr_buf_head: 0x%08x",
  186183. + ctype, ch, pdevinfo->channels[ch_func].dbr_buf_head);
  186184. + cdt_val[3] = (pdevinfo->channels[ch_func].dbr_buf_head)
  186185. + << CDT_BA_SHIFT;
  186186. + /*
  186187. + * b. Set the 12-bit or 13-bit buffer depth (BD)
  186188. + * BD = buffer depth in bytes - 1
  186189. + * For synchronous channels: (BD + 1) = 4 * m * bpf
  186190. + * For control channels: (BD + 1) >= max packet length (64)
  186191. + * For asynchronous channels: (BD + 1) >= max packet length
  186192. + * 1024 for a MOST Data packet (MDP);
  186193. + * 1536 for a MOST Ethernet Packet (MEP)
  186194. + * For isochronous channels: (BD + 1) mod (BS + 1) = 0
  186195. + * BS
  186196. + */
  186197. + if (MLB_CTYPE_ISOC == ctype)
  186198. + cdt_val[1] |= (pdevinfo->isoc_blksz - 1);
  186199. + /* BD */
  186200. + cdt_val[3] |= (pdevinfo->cdt_buf_dep - 1) << CDT_BD_SHIFT;
  186201. +
  186202. + pr_debug("mxc_mlb150: Set CDT val of channel %d, type: %d: "
  186203. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  186204. + ch, ctype, cdt_val[3], cdt_val[2], cdt_val[1], cdt_val[0]);
  186205. +
  186206. + if (mlb150_dev_cdt_write(ch, cdt_val))
  186207. + return -ETIME;
  186208. +
  186209. +#ifdef DEBUG_CTR
  186210. + {
  186211. + u32 cdt_rd[4] = { 0 };
  186212. + if (!mlb150_dev_cdt_read(ch, cdt_rd)) {
  186213. + pr_debug("mxc_mlb150: CDT val of channel %d: "
  186214. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  186215. + ch, cdt_rd[3], cdt_rd[2], cdt_rd[1], cdt_rd[0]);
  186216. + if (cdt_rd[3] == cdt_val[3] &&
  186217. + cdt_rd[2] == cdt_val[2] &&
  186218. + cdt_rd[1] == cdt_val[1] &&
  186219. + cdt_rd[0] == cdt_val[0]) {
  186220. + pr_debug("mxc_mlb150: set cdt succeed!\n");
  186221. + return 0;
  186222. + } else {
  186223. + pr_debug("mxc_mlb150: set cdt failed!\n");
  186224. + return -EBADE;
  186225. + }
  186226. + } else {
  186227. + pr_debug("mxc_mlb150: Read CDT val of channel %d failed\n",
  186228. + ch);
  186229. + return -EBADE;
  186230. + }
  186231. + }
  186232. +#endif
  186233. +
  186234. + return 0;
  186235. +}
  186236. +
  186237. +static s32 mlb150_dev_init_ch_cat(u32 ch, u32 cl,
  186238. + u32 cat_mode, enum MLB_CTYPE ctype)
  186239. +{
  186240. + u16 cat_val = 0;
  186241. +#ifdef DEBUG_CTR
  186242. + u16 cat_rd = 0;
  186243. +#endif
  186244. +
  186245. + cat_val = CAT_CE | (ctype << CAT_CT_SHIFT) | cl;
  186246. +
  186247. + if (cat_mode & CAT_MODE_OUTBOUND_DMA)
  186248. + cat_val |= CAT_RNW;
  186249. +
  186250. + if (MLB_CTYPE_SYNC == ctype)
  186251. + cat_val |= CAT_MT;
  186252. +
  186253. + switch (cat_mode) {
  186254. + case CAT_MODE_RX | CAT_MODE_INBOUND_DMA:
  186255. + case CAT_MODE_TX | CAT_MODE_OUTBOUND_DMA:
  186256. + pr_debug("mxc_mlb150: set CAT val of channel %d, type: %d: 0x%04x\n",
  186257. + ch, ctype, cat_val);
  186258. +
  186259. + if (mlb150_dev_cat_mlb_write(ch, cat_val))
  186260. + return -ETIME;
  186261. +#ifdef DEBUG_CTR
  186262. + if (!mlb150_dev_cat_mlb_read(ch, &cat_rd))
  186263. + pr_debug("mxc_mlb150: CAT val of mlb channel %d: 0x%04x",
  186264. + ch, cat_rd);
  186265. + else {
  186266. + pr_debug("mxc_mlb150: Read CAT of mlb channel %d failed\n",
  186267. + ch);
  186268. + return -EBADE;
  186269. + }
  186270. +#endif
  186271. + break;
  186272. + case CAT_MODE_TX | CAT_MODE_INBOUND_DMA:
  186273. + case CAT_MODE_RX | CAT_MODE_OUTBOUND_DMA:
  186274. + pr_debug("mxc_mlb150: set CAT val of channel %d, type: %d: 0x%04x\n",
  186275. + cl, ctype, cat_val);
  186276. +
  186277. + if (mlb150_dev_cat_hbi_write(cl, cat_val))
  186278. + return -ETIME;
  186279. +#ifdef DEBUG_CTR
  186280. + if (!mlb150_dev_cat_hbi_read(cl, &cat_rd))
  186281. + pr_debug("mxc_mlb150: CAT val of hbi channel %d: 0x%04x",
  186282. + cl, cat_rd);
  186283. + else {
  186284. + pr_debug("mxc_mlb150: Read CAT of hbi channel %d failed\n",
  186285. + cl);
  186286. + return -EBADE;
  186287. + }
  186288. +#endif
  186289. + break;
  186290. + default:
  186291. + return EBADRQC;
  186292. + }
  186293. +
  186294. +#ifdef DEBUG_CTR
  186295. + {
  186296. + if (cat_val == cat_rd) {
  186297. + pr_debug("mxc_mlb150: set cat succeed!\n");
  186298. + return 0;
  186299. + } else {
  186300. + pr_debug("mxc_mlb150: set cat failed!\n");
  186301. + return -EBADE;
  186302. + }
  186303. + }
  186304. +#endif
  186305. + return 0;
  186306. +}
  186307. +
  186308. +static void mlb150_dev_reset_cat(void)
  186309. +{
  186310. + int i = 0;
  186311. + u32 ctr_val[4] = { 0 };
  186312. +
  186313. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  186314. + 0xffffffff, 0xffffffff);
  186315. +
  186316. + for (i = 0; i < (LOGIC_CH_NUM >> 3); ++i) {
  186317. + mlb150_dev_ctr_write(BUF_CAT_MLB_OFFSET + i, ctr_val);
  186318. + mlb150_dev_ctr_write(BUF_CAT_HBI_OFFSET + i, ctr_val);
  186319. + }
  186320. +}
  186321. +
  186322. +static void mlb150_dev_init_rfb(struct mlb_dev_info *pdevinfo, u32 rx_ch,
  186323. + u32 tx_ch, enum MLB_CTYPE ctype)
  186324. +{
  186325. + u32 rx_cl = pdevinfo->channels[RX_CHANNEL].cl;
  186326. + u32 tx_cl = pdevinfo->channels[TX_CHANNEL].cl;
  186327. + /* Step 1, Initialize all bits of CAT to '0' */
  186328. + mlb150_dev_reset_cat();
  186329. + mlb150_dev_reset_cdt();
  186330. + /*
  186331. + * Step 2, Initialize logical channel
  186332. + * Step 3, Program the CDT for channel N
  186333. + */
  186334. + mlb150_dev_init_ch_cdt(pdevinfo, rx_cl, ctype, RX_CHANNEL);
  186335. + mlb150_dev_init_ch_cdt(pdevinfo, tx_cl, ctype, TX_CHANNEL);
  186336. +
  186337. + /* Step 4&5, Program the CAT for the inbound and outbound DMA */
  186338. + mlb150_dev_init_ch_cat(rx_ch, rx_cl,
  186339. + CAT_MODE_RX | CAT_MODE_INBOUND_DMA,
  186340. + ctype);
  186341. + mlb150_dev_init_ch_cat(rx_ch, rx_cl,
  186342. + CAT_MODE_RX | CAT_MODE_OUTBOUND_DMA,
  186343. + ctype);
  186344. + mlb150_dev_init_ch_cat(tx_ch, tx_cl,
  186345. + CAT_MODE_TX | CAT_MODE_INBOUND_DMA,
  186346. + ctype);
  186347. + mlb150_dev_init_ch_cat(tx_ch, tx_cl,
  186348. + CAT_MODE_TX | CAT_MODE_OUTBOUND_DMA,
  186349. + ctype);
  186350. +}
  186351. +
  186352. +static void mlb150_dev_reset_adt(void)
  186353. +{
  186354. + int i = 0;
  186355. + u32 ctr_val[4] = { 0 };
  186356. +
  186357. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  186358. + 0xffffffff, 0xffffffff);
  186359. +
  186360. + for (i = 0; i < (LOGIC_CH_NUM); ++i)
  186361. + mlb150_dev_ctr_write(BUF_ADT_OFFSET + i, ctr_val);
  186362. +}
  186363. +
  186364. +static void mlb150_dev_reset_whole_ctr(void)
  186365. +{
  186366. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  186367. + 0xffffffff, 0xffffffff);
  186368. + mlb150_dev_reset_cdt();
  186369. + mlb150_dev_reset_adt();
  186370. + mlb150_dev_reset_cat();
  186371. +}
  186372. +
  186373. +#define CLR_REG(reg) __raw_writel(0x0, mlb_base + reg)
  186374. +
  186375. +static void mlb150_dev_reset_all_regs(void)
  186376. +{
  186377. + CLR_REG(REG_MLBC0);
  186378. + CLR_REG(REG_MLBPC0);
  186379. + CLR_REG(REG_MS0);
  186380. + CLR_REG(REG_MS1);
  186381. + CLR_REG(REG_MSS);
  186382. + CLR_REG(REG_MSD);
  186383. + CLR_REG(REG_MIEN);
  186384. + CLR_REG(REG_MLBPC2);
  186385. + CLR_REG(REG_MLBPC1);
  186386. + CLR_REG(REG_MLBC1);
  186387. + CLR_REG(REG_HCTL);
  186388. + CLR_REG(REG_HCMR0);
  186389. + CLR_REG(REG_HCMR1);
  186390. + CLR_REG(REG_HCER0);
  186391. + CLR_REG(REG_HCER1);
  186392. + CLR_REG(REG_HCBR0);
  186393. + CLR_REG(REG_HCBR1);
  186394. + CLR_REG(REG_MDAT0);
  186395. + CLR_REG(REG_MDAT1);
  186396. + CLR_REG(REG_MDAT2);
  186397. + CLR_REG(REG_MDAT3);
  186398. + CLR_REG(REG_MDWE0);
  186399. + CLR_REG(REG_MDWE1);
  186400. + CLR_REG(REG_MDWE2);
  186401. + CLR_REG(REG_MDWE3);
  186402. + CLR_REG(REG_MCTL);
  186403. + CLR_REG(REG_MADR);
  186404. + CLR_REG(REG_ACTL);
  186405. + CLR_REG(REG_ACSR0);
  186406. + CLR_REG(REG_ACSR1);
  186407. + CLR_REG(REG_ACMR0);
  186408. + CLR_REG(REG_ACMR1);
  186409. +}
  186410. +
  186411. +static inline s32 mlb150_dev_pipo_start(struct mlb_ringbuf *rbuf,
  186412. + u32 ahb_ch, u32 buf_addr)
  186413. +{
  186414. + u32 ctr_val[4] = { 0 };
  186415. +
  186416. + ctr_val[1] |= ADT_RDY1;
  186417. + ctr_val[2] = buf_addr;
  186418. +
  186419. + if (mlb150_dev_adt_write(ahb_ch, ctr_val))
  186420. + return -ETIME;
  186421. +
  186422. + return 0;
  186423. +}
  186424. +
  186425. +static inline s32 mlb150_dev_pipo_next(u32 ahb_ch, enum MLB_CTYPE ctype,
  186426. + u32 dne_sts, u32 buf_addr)
  186427. +{
  186428. + u32 ctr_val[4] = { 0 };
  186429. +
  186430. + if (MLB_CTYPE_ASYNC == ctype ||
  186431. + MLB_CTYPE_CTRL == ctype) {
  186432. + ctr_val[1] |= ADT_PS1;
  186433. + ctr_val[1] |= ADT_PS2;
  186434. + }
  186435. +
  186436. + /*
  186437. + * Clear DNE1 and ERR1
  186438. + * Set the page ready bit (RDY1)
  186439. + */
  186440. + if (dne_sts & ADT_DNE1) {
  186441. + ctr_val[1] |= ADT_RDY2;
  186442. + ctr_val[3] = buf_addr;
  186443. + } else {
  186444. + ctr_val[1] |= ADT_RDY1;
  186445. + ctr_val[2] = buf_addr;
  186446. + }
  186447. +
  186448. + if (mlb150_dev_adt_write(ahb_ch, ctr_val))
  186449. + return -ETIME;
  186450. +
  186451. + return 0;
  186452. +}
  186453. +
  186454. +static inline s32 mlb150_dev_pipo_stop(struct mlb_ringbuf *rbuf, u32 ahb_ch)
  186455. +{
  186456. + u32 ctr_val[4] = { 0 };
  186457. + unsigned long flags;
  186458. +
  186459. + write_lock_irqsave(&rbuf->rb_lock, flags);
  186460. + rbuf->head = rbuf->tail = 0;
  186461. + write_unlock_irqrestore(&rbuf->rb_lock, flags);
  186462. +
  186463. + if (mlb150_dev_adt_write(ahb_ch, ctr_val))
  186464. + return -ETIME;
  186465. +
  186466. + return 0;
  186467. +}
  186468. +
  186469. +static s32 mlb150_dev_init_ch_amba_ahb(struct mlb_dev_info *pdevinfo,
  186470. + struct mlb_channel_info *chinfo,
  186471. + enum MLB_CTYPE ctype)
  186472. +{
  186473. + u32 ctr_val[4] = { 0 };
  186474. +
  186475. + /* a. Set the 32-bit base address (BA1) */
  186476. + ctr_val[3] = 0;
  186477. + ctr_val[2] = 0;
  186478. + ctr_val[1] = (pdevinfo->adt_buf_dep - 1) << ADT_BD1_SHIFT;
  186479. + ctr_val[1] |= (pdevinfo->adt_buf_dep - 1) << ADT_BD2_SHIFT;
  186480. + if (MLB_CTYPE_ASYNC == ctype ||
  186481. + MLB_CTYPE_CTRL == ctype) {
  186482. + ctr_val[1] |= ADT_PS1;
  186483. + ctr_val[1] |= ADT_PS2;
  186484. + }
  186485. +
  186486. + ctr_val[0] |= (ADT_LE | ADT_CE);
  186487. +
  186488. + pr_debug("mxc_mlb150: Set ADT val of channel %d, ctype: %d: "
  186489. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  186490. + chinfo->cl, ctype, ctr_val[3], ctr_val[2],
  186491. + ctr_val[1], ctr_val[0]);
  186492. +
  186493. + if (mlb150_dev_adt_write(chinfo->cl, ctr_val))
  186494. + return -ETIME;
  186495. +
  186496. +#ifdef DEBUG_CTR
  186497. + {
  186498. + u32 ctr_rd[4] = { 0 };
  186499. + if (!mlb150_dev_adt_read(chinfo->cl, ctr_rd)) {
  186500. + pr_debug("mxc_mlb150: ADT val of channel %d: "
  186501. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  186502. + chinfo->cl, ctr_rd[3], ctr_rd[2],
  186503. + ctr_rd[1], ctr_rd[0]);
  186504. + if (ctr_rd[3] == ctr_val[3] &&
  186505. + ctr_rd[2] == ctr_val[2] &&
  186506. + ctr_rd[1] == ctr_val[1] &&
  186507. + ctr_rd[0] == ctr_val[0]) {
  186508. + pr_debug("mxc_mlb150: set adt succeed!\n");
  186509. + return 0;
  186510. + } else {
  186511. + pr_debug("mxc_mlb150: set adt failed!\n");
  186512. + return -EBADE;
  186513. + }
  186514. + } else {
  186515. + pr_debug("mxc_mlb150: Read ADT val of channel %d failed\n",
  186516. + chinfo->cl);
  186517. + return -EBADE;
  186518. + }
  186519. + }
  186520. +#endif
  186521. +
  186522. + return 0;
  186523. +}
  186524. +
  186525. +static void mlb150_dev_init_amba_ahb(struct mlb_dev_info *pdevinfo,
  186526. + enum MLB_CTYPE ctype)
  186527. +{
  186528. + struct mlb_channel_info *tx_chinfo = &pdevinfo->channels[TX_CHANNEL];
  186529. + struct mlb_channel_info *rx_chinfo = &pdevinfo->channels[RX_CHANNEL];
  186530. +
  186531. + /* Step 1, Initialize all bits of the ADT to '0' */
  186532. + mlb150_dev_reset_adt();
  186533. +
  186534. + /*
  186535. + * Step 2, Select a logic channel
  186536. + * Step 3, Program the AMBA AHB block ping page for channel N
  186537. + * Step 4, Program the AMBA AHB block pong page for channel N
  186538. + */
  186539. + mlb150_dev_init_ch_amba_ahb(pdevinfo, rx_chinfo, ctype);
  186540. + mlb150_dev_init_ch_amba_ahb(pdevinfo, tx_chinfo, ctype);
  186541. +}
  186542. +
  186543. +static void mlb150_dev_exit(void)
  186544. +{
  186545. + u32 c0_val, hctl_val;
  186546. +
  186547. + /* Disable EN bits */
  186548. + c0_val = __raw_readl(mlb_base + REG_MLBC0);
  186549. + c0_val &= ~(MLBC0_MLBEN | MLBC0_MLBPEN);
  186550. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  186551. +
  186552. + hctl_val = __raw_readl(mlb_base + REG_HCTL);
  186553. + hctl_val &= ~HCTL_EN;
  186554. + __raw_writel(hctl_val, mlb_base + REG_HCTL);
  186555. +
  186556. + __raw_writel(0x0, mlb_base + REG_HCMR0);
  186557. + __raw_writel(0x0, mlb_base + REG_HCMR1);
  186558. +
  186559. + mlb150_dev_enable_dma_irq(0);
  186560. + mlb150_dev_enable_ir_mlb(0);
  186561. +}
  186562. +
  186563. +static void mlb150_dev_init(void)
  186564. +{
  186565. + u32 c0_val;
  186566. + u32 ch_rx_mask = (1 << SYNC_RX_CL_AHB0) | (1 << CTRL_RX_CL_AHB0)
  186567. + | (1 << ASYNC_RX_CL_AHB0) | (1 << ISOC_RX_CL_AHB0)
  186568. + | (1 << SYNC_TX_CL_AHB0) | (1 << CTRL_TX_CL_AHB0)
  186569. + | (1 << ASYNC_TX_CL_AHB0) | (1 << ISOC_TX_CL_AHB0);
  186570. + u32 ch_tx_mask = (1 << (SYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186571. + (1 << (CTRL_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186572. + (1 << (ASYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186573. + (1 << (ISOC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186574. + (1 << (SYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186575. + (1 << (CTRL_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186576. + (1 << (ASYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186577. + (1 << (ISOC_TX_CL_AHB1 - INT_AHB1_CH_START));
  186578. +
  186579. + /* Disable EN bits */
  186580. + mlb150_dev_exit();
  186581. +
  186582. + /*
  186583. + * Step 1. Initialize CTR and registers
  186584. + * a. Set all bit of the CTR (CAT, CDT, and ADT) to 0.
  186585. + */
  186586. + mlb150_dev_reset_whole_ctr();
  186587. +
  186588. + /* a. Set all bit of the CTR (CAT, CDT, and ADT) to 0. */
  186589. + mlb150_dev_reset_all_regs();
  186590. +
  186591. + /*
  186592. + * Step 2, Configure the MediaLB interface
  186593. + * Select pin mode and clock, 3-pin and 256fs
  186594. + */
  186595. + c0_val = __raw_readl(mlb_base + REG_MLBC0);
  186596. + c0_val &= ~(MLBC0_MLBPEN | MLBC0_MLBCLK_MASK);
  186597. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  186598. +
  186599. + c0_val |= MLBC0_MLBEN;
  186600. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  186601. +
  186602. + /* Step 3, Configure the HBI interface */
  186603. + __raw_writel(ch_rx_mask, mlb_base + REG_HCMR0);
  186604. + __raw_writel(ch_tx_mask, mlb_base + REG_HCMR1);
  186605. + __raw_writel(HCTL_EN, mlb_base + REG_HCTL);
  186606. +
  186607. + mlb150_dev_init_ir_amba_ahb();
  186608. +
  186609. + mlb150_dev_enable_ir_mlb(1);
  186610. +}
  186611. +
  186612. +static s32 mlb150_dev_unmute_syn_ch(u32 rx_ch, u32 rx_cl, u32 tx_ch, u32 tx_cl)
  186613. +{
  186614. + u32 timeout = 10000;
  186615. +
  186616. + /*
  186617. + * Check that MediaLB clock is running (MLBC1.CLKM = 0)
  186618. + * If MLBC1.CLKM = 1, clear the register bit, wait one
  186619. + * APB or I/O clock cycle and repeat the check
  186620. + */
  186621. + while ((__raw_readl(mlb_base + REG_MLBC1) & MLBC1_CLKM)
  186622. + && --timeout)
  186623. + __raw_writel(~MLBC1_CLKM, mlb_base + REG_MLBC1);
  186624. +
  186625. + if (0 == timeout)
  186626. + return -ETIME;
  186627. +
  186628. + timeout = 10000;
  186629. + /* Poll for MLB lock (MLBC0.MLBLK = 1) */
  186630. + while (!(__raw_readl(mlb_base + REG_MLBC0) & MLBC0_MLBLK)
  186631. + && --timeout)
  186632. + ;
  186633. +
  186634. + if (0 == timeout)
  186635. + return -ETIME;
  186636. +
  186637. + /* Unmute synchronous channel(s) */
  186638. + mlb150_dev_cat_mlb_write(rx_ch, CAT_CE | rx_cl);
  186639. + mlb150_dev_cat_mlb_write(tx_ch,
  186640. + CAT_CE | tx_cl | CAT_RNW);
  186641. + mlb150_dev_cat_hbi_write(rx_cl,
  186642. + CAT_CE | rx_cl | CAT_RNW);
  186643. + mlb150_dev_cat_hbi_write(tx_cl, CAT_CE | tx_cl);
  186644. +
  186645. + return 0;
  186646. +}
  186647. +
  186648. +/* In case the user calls channel shutdown, but rx or tx is not completed yet */
  186649. +static s32 mlb150_trans_complete_check(struct mlb_dev_info *pdevinfo)
  186650. +{
  186651. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  186652. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  186653. + s32 timeout = 1024;
  186654. +
  186655. + while (timeout--) {
  186656. + read_lock(&tx_rbuf->rb_lock);
  186657. + if (!CIRC_CNT(tx_rbuf->head, tx_rbuf->tail, TRANS_RING_NODES)) {
  186658. + read_unlock(&tx_rbuf->rb_lock);
  186659. + break;
  186660. + } else
  186661. + read_unlock(&tx_rbuf->rb_lock);
  186662. + }
  186663. +
  186664. + if (timeout <= 0) {
  186665. + pr_debug("TX complete check timeout!\n");
  186666. + return -ETIME;
  186667. + }
  186668. +
  186669. + timeout = 1024;
  186670. + while (timeout--) {
  186671. + read_lock(&rx_rbuf->rb_lock);
  186672. + if (!CIRC_CNT(rx_rbuf->head, rx_rbuf->tail, TRANS_RING_NODES)) {
  186673. + read_unlock(&rx_rbuf->rb_lock);
  186674. + break;
  186675. + } else
  186676. + read_unlock(&rx_rbuf->rb_lock);
  186677. + }
  186678. +
  186679. + if (timeout <= 0) {
  186680. + pr_debug("RX complete check timeout!\n");
  186681. + return -ETIME;
  186682. + }
  186683. +
  186684. + /*
  186685. + * Interrupt from TX can only inform that the data is sent
  186686. + * to AHB bus, not mean that it is sent to MITB. Thus we add
  186687. + * a delay here for data to be completed sent.
  186688. + */
  186689. + udelay(1000);
  186690. +
  186691. + return 0;
  186692. +}
  186693. +
  186694. +/*
  186695. + * Enable/Disable the MLB IRQ
  186696. + */
  186697. +static void mxc_mlb150_irq_enable(struct mlb_data *drvdata, u8 enable)
  186698. +{
  186699. + if (enable) {
  186700. + enable_irq(drvdata->irq_ahb0);
  186701. + enable_irq(drvdata->irq_ahb1);
  186702. + enable_irq(drvdata->irq_mlb);
  186703. + } else {
  186704. + disable_irq(drvdata->irq_ahb0);
  186705. + disable_irq(drvdata->irq_ahb1);
  186706. + disable_irq(drvdata->irq_mlb);
  186707. + }
  186708. +}
  186709. +
  186710. +/*
  186711. + * Enable the MLB channel
  186712. + */
  186713. +static s32 mlb_channel_enable(struct mlb_data *drvdata,
  186714. + int chan_dev_id, int on)
  186715. +{
  186716. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  186717. + struct mlb_channel_info *tx_chinfo = &pdevinfo->channels[TX_CHANNEL];
  186718. + struct mlb_channel_info *rx_chinfo = &pdevinfo->channels[RX_CHANNEL];
  186719. + u32 tx_ch = tx_chinfo->address;
  186720. + u32 rx_ch = rx_chinfo->address;
  186721. + u32 tx_cl = tx_chinfo->cl;
  186722. + u32 rx_cl = rx_chinfo->cl;
  186723. + s32 ret = 0;
  186724. +
  186725. + /*
  186726. + * setup the direction, enable, channel type,
  186727. + * mode select, channel address and mask buf start
  186728. + */
  186729. + if (on) {
  186730. + u32 ctype = pdevinfo->channel_type;
  186731. +
  186732. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  186733. + 0xffffffff, 0xffffffff);
  186734. + mlb150_dev_init_rfb(pdevinfo, rx_ch, tx_ch, ctype);
  186735. +
  186736. + mlb150_dev_init_amba_ahb(pdevinfo, ctype);
  186737. +
  186738. +#ifdef DEBUG
  186739. + mlb150_dev_dump_ctr_tbl(0, tx_chinfo->cl + 1);
  186740. +#endif
  186741. + /* Synchronize and unmute synchrouous channel */
  186742. + if (MLB_CTYPE_SYNC == ctype) {
  186743. + ret = mlb150_dev_unmute_syn_ch(rx_ch, rx_cl,
  186744. + tx_ch, tx_cl);
  186745. + if (ret)
  186746. + return ret;
  186747. + }
  186748. +
  186749. + mlb150_dev_enable_ctr_write(0x0, ADT_RDY1 | ADT_DNE1 |
  186750. + ADT_ERR1 | ADT_PS1 |
  186751. + ADT_RDY2 | ADT_DNE2 | ADT_ERR2 | ADT_PS2,
  186752. + 0xffffffff, 0xffffffff);
  186753. +
  186754. + if (pdevinfo->fps >= CLK_2048FS)
  186755. + mlb150_enable_pll(drvdata);
  186756. +
  186757. + atomic_set(&pdevinfo->on, 1);
  186758. +
  186759. +#ifdef DEBUG
  186760. + mlb150_dev_dump_reg();
  186761. + mlb150_dev_dump_ctr_tbl(0, tx_chinfo->cl + 1);
  186762. +#endif
  186763. + /* Init RX ADT */
  186764. + mlb150_dev_pipo_start(&pdevinfo->rx_rbuf, rx_cl,
  186765. + pdevinfo->rx_rbuf.phy_addrs[0]);
  186766. + } else {
  186767. + mlb150_dev_pipo_stop(&pdevinfo->rx_rbuf, rx_cl);
  186768. +
  186769. + mlb150_dev_enable_dma_irq(0);
  186770. + mlb150_dev_enable_ir_mlb(0);
  186771. +
  186772. + mlb150_dev_reset_cat();
  186773. +
  186774. + atomic_set(&pdevinfo->on, 0);
  186775. +
  186776. + if (pdevinfo->fps >= CLK_2048FS)
  186777. + mlb150_disable_pll(drvdata);
  186778. + }
  186779. +
  186780. + return 0;
  186781. +}
  186782. +
  186783. +/*
  186784. + * MLB interrupt handler
  186785. + */
  186786. +static void mlb_rx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
  186787. +{
  186788. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  186789. + s32 head, tail, adt_sts;
  186790. + u32 rx_buf_ptr;
  186791. +
  186792. +#ifdef DEBUG_RX
  186793. + pr_debug("mxc_mlb150: mlb_rx_isr\n");
  186794. +#endif
  186795. +
  186796. + read_lock(&rx_rbuf->rb_lock);
  186797. +
  186798. + head = (rx_rbuf->head + 1) & (TRANS_RING_NODES - 1);
  186799. + tail = ACCESS_ONCE(rx_rbuf->tail);
  186800. + read_unlock(&rx_rbuf->rb_lock);
  186801. +
  186802. + if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1) {
  186803. + rx_buf_ptr = rx_rbuf->phy_addrs[head];
  186804. +
  186805. + /* commit the item before incrementing the head */
  186806. + smp_wmb();
  186807. +
  186808. + write_lock(&rx_rbuf->rb_lock);
  186809. + rx_rbuf->head = head;
  186810. + write_unlock(&rx_rbuf->rb_lock);
  186811. +
  186812. + /* wake up the reader */
  186813. + wake_up_interruptible(&pdevinfo->rx_wq);
  186814. + } else {
  186815. + rx_buf_ptr = rx_rbuf->phy_addrs[head];
  186816. + pr_debug("drop RX package, due to no space, (%d,%d)\n",
  186817. + head, tail);
  186818. + }
  186819. +
  186820. + adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
  186821. + /* Set ADT for RX */
  186822. + mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, rx_buf_ptr);
  186823. +}
  186824. +
  186825. +static void mlb_tx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
  186826. +{
  186827. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  186828. + s32 head, tail, adt_sts;
  186829. + u32 tx_buf_ptr;
  186830. +
  186831. + read_lock(&tx_rbuf->rb_lock);
  186832. +
  186833. + head = ACCESS_ONCE(tx_rbuf->head);
  186834. + tail = (tx_rbuf->tail + 1) & (TRANS_RING_NODES - 1);
  186835. + read_unlock(&tx_rbuf->rb_lock);
  186836. +
  186837. + smp_mb();
  186838. + write_lock(&tx_rbuf->rb_lock);
  186839. + tx_rbuf->tail = tail;
  186840. + write_unlock(&tx_rbuf->rb_lock);
  186841. +
  186842. + /* check the current tx buffer is available or not */
  186843. + if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1) {
  186844. + /* read index before reading contents at that index */
  186845. + smp_read_barrier_depends();
  186846. +
  186847. + tx_buf_ptr = tx_rbuf->phy_addrs[tail];
  186848. +
  186849. + wake_up_interruptible(&pdevinfo->tx_wq);
  186850. +
  186851. + adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
  186852. + /* Set ADT for TX */
  186853. + mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
  186854. + }
  186855. +}
  186856. +
  186857. +static irqreturn_t mlb_ahb_isr(int irq, void *dev_id)
  186858. +{
  186859. + u32 acsr0, hcer0;
  186860. + u32 ch_mask = (1 << SYNC_RX_CL) | (1 << CTRL_RX_CL)
  186861. + | (1 << ASYNC_RX_CL) | (1 << ISOC_RX_CL)
  186862. + | (1 << SYNC_TX_CL) | (1 << CTRL_TX_CL)
  186863. + | (1 << ASYNC_TX_CL) | (1 << ISOC_TX_CL);
  186864. +
  186865. + /*
  186866. + * Step 5, Read the ACSRn registers to determine which channel or
  186867. + * channels are causing the interrupt
  186868. + */
  186869. + acsr0 = __raw_readl(mlb_base + REG_ACSR0);
  186870. +
  186871. + hcer0 = __raw_readl(mlb_base + REG_HCER0);
  186872. +
  186873. + /*
  186874. + * Step 6, If ACTL.SCE = 1, write the result of step 5 back to ACSR0
  186875. + * and ACSR1 to clear the interrupt
  186876. + * We'll not set ACTL_SCE
  186877. + */
  186878. +
  186879. + if (ch_mask & hcer0)
  186880. + pr_err("CH encounters an AHB error: 0x%x\n", hcer0);
  186881. +
  186882. + if ((1 << SYNC_RX_CL) & acsr0)
  186883. + mlb_rx_isr(MLB_CTYPE_SYNC, SYNC_RX_CL,
  186884. + &mlb_devinfo[MLB_CTYPE_SYNC]);
  186885. +
  186886. + if ((1 << CTRL_RX_CL) & acsr0)
  186887. + mlb_rx_isr(MLB_CTYPE_CTRL, CTRL_RX_CL,
  186888. + &mlb_devinfo[MLB_CTYPE_CTRL]);
  186889. +
  186890. + if ((1 << ASYNC_RX_CL) & acsr0)
  186891. + mlb_rx_isr(MLB_CTYPE_ASYNC, ASYNC_RX_CL,
  186892. + &mlb_devinfo[MLB_CTYPE_ASYNC]);
  186893. +
  186894. + if ((1 << ISOC_RX_CL) & acsr0)
  186895. + mlb_rx_isr(MLB_CTYPE_ISOC, ISOC_RX_CL,
  186896. + &mlb_devinfo[MLB_CTYPE_ISOC]);
  186897. +
  186898. + if ((1 << SYNC_TX_CL) & acsr0)
  186899. + mlb_tx_isr(MLB_CTYPE_SYNC, SYNC_TX_CL,
  186900. + &mlb_devinfo[MLB_CTYPE_SYNC]);
  186901. +
  186902. + if ((1 << CTRL_TX_CL) & acsr0)
  186903. + mlb_tx_isr(MLB_CTYPE_CTRL, CTRL_TX_CL,
  186904. + &mlb_devinfo[MLB_CTYPE_CTRL]);
  186905. +
  186906. + if ((1 << ASYNC_TX_CL) & acsr0)
  186907. + mlb_tx_isr(MLB_CTYPE_ASYNC, ASYNC_TX_CL,
  186908. + &mlb_devinfo[MLB_CTYPE_ASYNC]);
  186909. +
  186910. + if ((1 << ISOC_TX_CL) & acsr0)
  186911. + mlb_tx_isr(MLB_CTYPE_ASYNC, ISOC_TX_CL,
  186912. + &mlb_devinfo[MLB_CTYPE_ISOC]);
  186913. +
  186914. + return IRQ_HANDLED;
  186915. +}
  186916. +
  186917. +static irqreturn_t mlb_isr(int irq, void *dev_id)
  186918. +{
  186919. + u32 rx_int_sts, tx_int_sts, ms0,
  186920. + ms1, tx_cis, rx_cis, ctype;
  186921. + int minor;
  186922. + u32 cdt_val[4] = { 0 };
  186923. +
  186924. + /*
  186925. + * Step 4, Read the MSn register to determine which channel(s)
  186926. + * are causing the interrupt
  186927. + */
  186928. + ms0 = __raw_readl(mlb_base + REG_MS0);
  186929. + ms1 = __raw_readl(mlb_base + REG_MS1);
  186930. +
  186931. + /*
  186932. + * The MLB150_MS0, MLB150_MS1 registers need to be cleared. In
  186933. + * the spec description, the registers should be cleared when
  186934. + * enabling interrupt. In fact, we also should clear it in ISR.
  186935. + */
  186936. + __raw_writel(0, mlb_base + REG_MS0);
  186937. + __raw_writel(0, mlb_base + REG_MS1);
  186938. +
  186939. + pr_debug("mxc_mlb150: mlb interrupt:0x%08x 0x%08x\n",
  186940. + (u32)ms0, (u32)ms1);
  186941. +
  186942. + for (minor = 0; minor < MLB_MINOR_DEVICES; minor++) {
  186943. + struct mlb_dev_info *pdevinfo = &mlb_devinfo[minor];
  186944. + u32 rx_mlb_ch = pdevinfo->channels[RX_CHANNEL].address;
  186945. + u32 tx_mlb_ch = pdevinfo->channels[TX_CHANNEL].address;
  186946. + u32 rx_mlb_cl = pdevinfo->channels[RX_CHANNEL].cl;
  186947. + u32 tx_mlb_cl = pdevinfo->channels[TX_CHANNEL].cl;
  186948. +
  186949. + tx_cis = rx_cis = 0;
  186950. +
  186951. + ctype = pdevinfo->channel_type;
  186952. + rx_int_sts = (rx_mlb_ch < 31) ? ms0 : ms1;
  186953. + tx_int_sts = (tx_mlb_ch < 31) ? ms0 : ms1;
  186954. +
  186955. + pr_debug("mxc_mlb150: channel interrupt: "
  186956. + "tx %d: 0x%08x, rx %d: 0x%08x\n",
  186957. + tx_mlb_ch, (u32)tx_int_sts, rx_mlb_ch, (u32)rx_int_sts);
  186958. +
  186959. + /* Get tx channel interrupt status */
  186960. + if (tx_int_sts & (1 << (tx_mlb_ch % 32))) {
  186961. + mlb150_dev_cdt_read(tx_mlb_cl, cdt_val);
  186962. + pr_debug("mxc_mlb150: TX_CH: %d, cdt_val[3]: 0x%08x, "
  186963. + "cdt_val[2]: 0x%08x, "
  186964. + "cdt_val[1]: 0x%08x, "
  186965. + "cdt_val[0]: 0x%08x\n",
  186966. + tx_mlb_ch, cdt_val[3], cdt_val[2],
  186967. + cdt_val[1], cdt_val[0]);
  186968. + switch (ctype) {
  186969. + case MLB_CTYPE_SYNC:
  186970. + tx_cis = (cdt_val[2] & ~CDT_SYNC_WSTS_MASK)
  186971. + >> CDT_SYNC_WSTS_SHIFT;
  186972. + /*
  186973. + * Clear RSTS/WSTS errors to resume
  186974. + * channel operation
  186975. + * a. For synchronous channels: WSTS[3] = 0
  186976. + */
  186977. + cdt_val[2] &= ~(0x8 << CDT_SYNC_WSTS_SHIFT);
  186978. + break;
  186979. + case MLB_CTYPE_CTRL:
  186980. + case MLB_CTYPE_ASYNC:
  186981. + tx_cis = (cdt_val[2] &
  186982. + ~CDT_CTRL_ASYNC_WSTS_MASK)
  186983. + >> CDT_CTRL_ASYNC_WSTS_SHIFT;
  186984. + tx_cis = (cdt_val[3] & CDT_CTRL_ASYNC_WSTS_1) ?
  186985. + (tx_cis | (0x1 << 4)) : tx_cis;
  186986. + /*
  186987. + * b. For async and ctrl channels:
  186988. + * RSTS[4]/WSTS[4] = 0
  186989. + * and RSTS[2]/WSTS[2] = 0
  186990. + */
  186991. + cdt_val[3] &= ~CDT_CTRL_ASYNC_WSTS_1;
  186992. + cdt_val[2] &=
  186993. + ~(0x4 << CDT_CTRL_ASYNC_WSTS_SHIFT);
  186994. + break;
  186995. + case MLB_CTYPE_ISOC:
  186996. + tx_cis = (cdt_val[2] & ~CDT_ISOC_WSTS_MASK)
  186997. + >> CDT_ISOC_WSTS_SHIFT;
  186998. + /* c. For isoc channels: WSTS[2:1] = 0x00 */
  186999. + cdt_val[2] &= ~(0x6 << CDT_ISOC_WSTS_SHIFT);
  187000. + break;
  187001. + default:
  187002. + break;
  187003. + }
  187004. + mlb150_dev_cdt_write(tx_mlb_ch, cdt_val);
  187005. + }
  187006. +
  187007. + /* Get rx channel interrupt status */
  187008. + if (rx_int_sts & (1 << (rx_mlb_ch % 32))) {
  187009. + mlb150_dev_cdt_read(rx_mlb_cl, cdt_val);
  187010. + pr_debug("mxc_mlb150: RX_CH: %d, cdt_val[3]: 0x%08x, "
  187011. + "cdt_val[2]: 0x%08x, "
  187012. + "cdt_val[1]: 0x%08x, "
  187013. + "cdt_val[0]: 0x%08x\n",
  187014. + rx_mlb_ch, cdt_val[3], cdt_val[2],
  187015. + cdt_val[1], cdt_val[0]);
  187016. + switch (ctype) {
  187017. + case MLB_CTYPE_SYNC:
  187018. + tx_cis = (cdt_val[2] & ~CDT_SYNC_RSTS_MASK)
  187019. + >> CDT_SYNC_RSTS_SHIFT;
  187020. + cdt_val[2] &= ~(0x8 << CDT_SYNC_WSTS_SHIFT);
  187021. + break;
  187022. + case MLB_CTYPE_CTRL:
  187023. + case MLB_CTYPE_ASYNC:
  187024. + tx_cis =
  187025. + (cdt_val[2] & ~CDT_CTRL_ASYNC_RSTS_MASK)
  187026. + >> CDT_CTRL_ASYNC_RSTS_SHIFT;
  187027. + tx_cis = (cdt_val[3] & CDT_CTRL_ASYNC_RSTS_1) ?
  187028. + (tx_cis | (0x1 << 4)) : tx_cis;
  187029. + cdt_val[3] &= ~CDT_CTRL_ASYNC_RSTS_1;
  187030. + cdt_val[2] &=
  187031. + ~(0x4 << CDT_CTRL_ASYNC_RSTS_SHIFT);
  187032. + break;
  187033. + case MLB_CTYPE_ISOC:
  187034. + tx_cis = (cdt_val[2] & ~CDT_ISOC_RSTS_MASK)
  187035. + >> CDT_ISOC_RSTS_SHIFT;
  187036. + cdt_val[2] &= ~(0x6 << CDT_ISOC_WSTS_SHIFT);
  187037. + break;
  187038. + default:
  187039. + break;
  187040. + }
  187041. + mlb150_dev_cdt_write(rx_mlb_ch, cdt_val);
  187042. + }
  187043. +
  187044. + if (!tx_cis && !rx_cis)
  187045. + continue;
  187046. +
  187047. + /* fill exception event */
  187048. + spin_lock(&pdevinfo->event_lock);
  187049. + pdevinfo->ex_event |= (rx_cis << 16) | tx_cis;
  187050. + spin_unlock(&pdevinfo->event_lock);
  187051. + }
  187052. +
  187053. + return IRQ_HANDLED;
  187054. +}
  187055. +
  187056. +static int mxc_mlb150_open(struct inode *inode, struct file *filp)
  187057. +{
  187058. + int minor, ring_buf_size, buf_size, j, ret;
  187059. + void __iomem *buf_addr;
  187060. + ulong phy_addr;
  187061. + struct mlb_dev_info *pdevinfo = NULL;
  187062. + struct mlb_channel_info *pchinfo = NULL;
  187063. + struct mlb_data *drvdata;
  187064. +
  187065. + minor = MINOR(inode->i_rdev);
  187066. + drvdata = container_of(inode->i_cdev, struct mlb_data, cdev);
  187067. +
  187068. + if (minor < 0 || minor >= MLB_MINOR_DEVICES) {
  187069. + pr_err("no device\n");
  187070. + return -ENODEV;
  187071. + }
  187072. +
  187073. + /* open for each channel device */
  187074. + if (atomic_cmpxchg(&mlb_devinfo[minor].opencnt, 0, 1) != 0) {
  187075. + pr_err("busy\n");
  187076. + return -EBUSY;
  187077. + }
  187078. +
  187079. + clk_prepare_enable(drvdata->clk_mlb3p);
  187080. +
  187081. + /* initial MLB module */
  187082. + mlb150_dev_init();
  187083. +
  187084. + pdevinfo = &mlb_devinfo[minor];
  187085. + pchinfo = &pdevinfo->channels[TX_CHANNEL];
  187086. +
  187087. + ring_buf_size = pdevinfo->buf_size;
  187088. + buf_size = ring_buf_size * (TRANS_RING_NODES * 2);
  187089. + buf_addr = (void __iomem *)gen_pool_alloc(drvdata->iram_pool, buf_size);
  187090. + if (buf_addr == NULL) {
  187091. + ret = -ENOMEM;
  187092. + pr_err("can not alloc rx/tx buffers: %d\n", buf_size);
  187093. + return ret;
  187094. + }
  187095. + phy_addr = gen_pool_virt_to_phys(drvdata->iram_pool, (ulong)buf_addr);
  187096. + pr_debug("IRAM Range: Virt 0x%p - 0x%p, Phys 0x%x - 0x%x, size: 0x%x\n",
  187097. + buf_addr, (buf_addr + buf_size - 1), (u32)phy_addr,
  187098. + (u32)(phy_addr + buf_size - 1), buf_size);
  187099. + pdevinfo->rbuf_base_virt = buf_addr;
  187100. + pdevinfo->rbuf_base_phy = phy_addr;
  187101. + drvdata->iram_size = buf_size;
  187102. +
  187103. + memset(buf_addr, 0, buf_size);
  187104. +
  187105. + for (j = 0; j < (TRANS_RING_NODES);
  187106. + ++j, buf_addr += ring_buf_size, phy_addr += ring_buf_size) {
  187107. + pdevinfo->rx_rbuf.virt_bufs[j] = buf_addr;
  187108. + pdevinfo->rx_rbuf.phy_addrs[j] = phy_addr;
  187109. + pr_debug("RX Ringbuf[%d]: 0x%p 0x%x\n",
  187110. + j, buf_addr, (u32)phy_addr);
  187111. + }
  187112. + pdevinfo->rx_rbuf.unit_size = ring_buf_size;
  187113. + pdevinfo->rx_rbuf.total_size = buf_size;
  187114. + for (j = 0; j < (TRANS_RING_NODES);
  187115. + ++j, buf_addr += ring_buf_size, phy_addr += ring_buf_size) {
  187116. + pdevinfo->tx_rbuf.virt_bufs[j] = buf_addr;
  187117. + pdevinfo->tx_rbuf.phy_addrs[j] = phy_addr;
  187118. + pr_debug("TX Ringbuf[%d]: 0x%p 0x%x\n",
  187119. + j, buf_addr, (u32)phy_addr);
  187120. + }
  187121. +
  187122. + pdevinfo->tx_rbuf.unit_size = ring_buf_size;
  187123. + pdevinfo->tx_rbuf.total_size = buf_size;
  187124. +
  187125. + /* reset the buffer read/write ptr */
  187126. + pdevinfo->rx_rbuf.head = pdevinfo->rx_rbuf.tail = 0;
  187127. + pdevinfo->tx_rbuf.head = pdevinfo->tx_rbuf.tail = 0;
  187128. + pdevinfo->ex_event = 0;
  187129. + pdevinfo->tx_ok = 0;
  187130. +
  187131. + init_waitqueue_head(&pdevinfo->rx_wq);
  187132. + init_waitqueue_head(&pdevinfo->tx_wq);
  187133. +
  187134. + drvdata = container_of(inode->i_cdev, struct mlb_data, cdev);
  187135. + drvdata->devinfo = pdevinfo;
  187136. + mxc_mlb150_irq_enable(drvdata, 1);
  187137. + filp->private_data = drvdata;
  187138. +
  187139. + return 0;
  187140. +}
  187141. +
  187142. +static int mxc_mlb150_release(struct inode *inode, struct file *filp)
  187143. +{
  187144. + int minor;
  187145. + struct mlb_data *drvdata = filp->private_data;
  187146. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187147. +
  187148. + minor = MINOR(inode->i_rdev);
  187149. + mxc_mlb150_irq_enable(drvdata, 0);
  187150. +
  187151. +#ifdef DEBUG
  187152. + mlb150_dev_dump_reg();
  187153. + mlb150_dev_dump_ctr_tbl(0, pdevinfo->channels[TX_CHANNEL].cl + 1);
  187154. +#endif
  187155. +
  187156. + gen_pool_free(drvdata->iram_pool,
  187157. + (ulong)pdevinfo->rbuf_base_virt, drvdata->iram_size);
  187158. +
  187159. + mlb150_dev_exit();
  187160. +
  187161. + if (pdevinfo && atomic_read(&pdevinfo->on)
  187162. + && (pdevinfo->fps >= CLK_2048FS))
  187163. + clk_disable_unprepare(drvdata->clk_mlb6p);
  187164. +
  187165. + atomic_set(&pdevinfo->on, 0);
  187166. +
  187167. + clk_disable_unprepare(drvdata->clk_mlb3p);
  187168. + /* decrease the open count */
  187169. + atomic_set(&pdevinfo->opencnt, 0);
  187170. +
  187171. + drvdata->devinfo = NULL;
  187172. +
  187173. + return 0;
  187174. +}
  187175. +
  187176. +static long mxc_mlb150_ioctl(struct file *filp,
  187177. + unsigned int cmd, unsigned long arg)
  187178. +{
  187179. + struct inode *inode = filp->f_dentry->d_inode;
  187180. + struct mlb_data *drvdata = filp->private_data;
  187181. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187182. + void __user *argp = (void __user *)arg;
  187183. + unsigned long flags, event;
  187184. + int minor;
  187185. +
  187186. + minor = MINOR(inode->i_rdev);
  187187. +
  187188. + switch (cmd) {
  187189. + case MLB_CHAN_SETADDR:
  187190. + {
  187191. + unsigned int caddr;
  187192. + /* get channel address from user space */
  187193. + if (copy_from_user(&caddr, argp, sizeof(caddr))) {
  187194. + pr_err("mxc_mlb150: copy from user failed\n");
  187195. + return -EFAULT;
  187196. + }
  187197. + pdevinfo->channels[TX_CHANNEL].address =
  187198. + (caddr >> 16) & 0xFFFF;
  187199. + pdevinfo->channels[RX_CHANNEL].address = caddr & 0xFFFF;
  187200. + pr_debug("mxc_mlb150: set ch addr, tx: %d, rx: %d\n",
  187201. + pdevinfo->channels[TX_CHANNEL].address,
  187202. + pdevinfo->channels[RX_CHANNEL].address);
  187203. + break;
  187204. + }
  187205. +
  187206. + case MLB_CHAN_STARTUP:
  187207. + if (atomic_read(&pdevinfo->on)) {
  187208. + pr_debug("mxc_mlb150: channel alreadly startup\n");
  187209. + break;
  187210. + }
  187211. + if (mlb_channel_enable(drvdata, minor, 1))
  187212. + return -EFAULT;
  187213. + break;
  187214. + case MLB_CHAN_SHUTDOWN:
  187215. + if (atomic_read(&pdevinfo->on) == 0) {
  187216. + pr_debug("mxc_mlb150: channel areadly shutdown\n");
  187217. + break;
  187218. + }
  187219. + mlb150_trans_complete_check(pdevinfo);
  187220. + mlb_channel_enable(drvdata, minor, 0);
  187221. + break;
  187222. + case MLB_CHAN_GETEVENT:
  187223. + /* get and clear the ex_event */
  187224. + spin_lock_irqsave(&pdevinfo->event_lock, flags);
  187225. + event = pdevinfo->ex_event;
  187226. + pdevinfo->ex_event = 0;
  187227. + spin_unlock_irqrestore(&pdevinfo->event_lock, flags);
  187228. +
  187229. + if (event) {
  187230. + if (copy_to_user(argp, &event, sizeof(event))) {
  187231. + pr_err("mxc_mlb150: copy to user failed\n");
  187232. + return -EFAULT;
  187233. + }
  187234. + } else
  187235. + return -EAGAIN;
  187236. + break;
  187237. + case MLB_SET_ISOC_BLKSIZE_188:
  187238. + pdevinfo->isoc_blksz = 188;
  187239. + pdevinfo->cdt_buf_dep = pdevinfo->adt_buf_dep =
  187240. + pdevinfo->isoc_blksz * CH_ISOC_BLK_NUM;
  187241. + break;
  187242. + case MLB_SET_ISOC_BLKSIZE_196:
  187243. + pdevinfo->isoc_blksz = 196;
  187244. + pdevinfo->cdt_buf_dep = pdevinfo->adt_buf_dep =
  187245. + pdevinfo->isoc_blksz * CH_ISOC_BLK_NUM;
  187246. + break;
  187247. + case MLB_SET_SYNC_QUAD:
  187248. + {
  187249. + u32 quad;
  187250. +
  187251. + if (copy_from_user(&quad, argp, sizeof(quad))) {
  187252. + pr_err("mxc_mlb150: get quad number "
  187253. + "from user failed\n");
  187254. + return -EFAULT;
  187255. + }
  187256. + if (quad <= 0 || quad > 3) {
  187257. + pr_err("mxc_mlb150: Invalid Quadlets!"
  187258. + "Quadlets in Sync mode can "
  187259. + "only be 1, 2, 3\n");
  187260. + return -EINVAL;
  187261. + }
  187262. + pdevinfo->sync_quad = quad;
  187263. + /* Each quadlets is 4 bytes */
  187264. + pdevinfo->cdt_buf_dep = quad * 4 * 4;
  187265. + pdevinfo->adt_buf_dep =
  187266. + pdevinfo->cdt_buf_dep * CH_SYNC_ADT_BUF_MULTI;
  187267. + }
  187268. + break;
  187269. + case MLB_SET_FPS:
  187270. + {
  187271. + u32 fps, c0_val;
  187272. +
  187273. + /* get fps from user space */
  187274. + if (copy_from_user(&fps, argp, sizeof(fps))) {
  187275. + pr_err("mxc_mlb150: copy from user failed\n");
  187276. + return -EFAULT;
  187277. + }
  187278. +
  187279. + c0_val = __raw_readl(mlb_base + REG_MLBC0);
  187280. + c0_val &= ~MLBC0_MLBCLK_MASK;
  187281. +
  187282. + /* check fps value */
  187283. + switch (fps) {
  187284. + case 256:
  187285. + case 512:
  187286. + case 1024:
  187287. + pdevinfo->fps = fps >> 9;
  187288. + c0_val &= ~MLBC0_MLBPEN;
  187289. + c0_val |= (fps >> 9)
  187290. + << MLBC0_MLBCLK_SHIFT;
  187291. +
  187292. + if (1024 == fps) {
  187293. + /*
  187294. + * Invert output clock phase
  187295. + * in 1024 fps
  187296. + */
  187297. + __raw_writel(0x1,
  187298. + mlb_base + REG_MLBPC2);
  187299. + }
  187300. + break;
  187301. + case 2048:
  187302. + case 3072:
  187303. + case 4096:
  187304. + pdevinfo->fps = (fps >> 10) + 1;
  187305. + c0_val |= ((fps >> 10) + 1)
  187306. + << MLBC0_MLBCLK_SHIFT;
  187307. + break;
  187308. + case 6144:
  187309. + pdevinfo->fps = fps >> 10;
  187310. + c0_val |= ((fps >> 10) + 1)
  187311. + << MLBC0_MLBCLK_SHIFT;
  187312. + break;
  187313. + case 8192:
  187314. + pdevinfo->fps = (fps >> 10) - 1;
  187315. + c0_val |= ((fps >> 10) - 1)
  187316. + << MLBC0_MLBCLK_SHIFT;
  187317. + break;
  187318. + default:
  187319. + pr_debug("mxc_mlb150: invalid fps argument: %d\n",
  187320. + fps);
  187321. + return -EINVAL;
  187322. + }
  187323. +
  187324. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  187325. +
  187326. + pr_debug("mxc_mlb150: set fps to %d, MLBC0: 0x%08x\n",
  187327. + fps,
  187328. + (u32)__raw_readl(mlb_base + REG_MLBC0));
  187329. +
  187330. + break;
  187331. + }
  187332. +
  187333. + case MLB_GET_VER:
  187334. + {
  187335. + u32 version;
  187336. +
  187337. + /* get MLB device module version */
  187338. + version = 0x03030003;
  187339. +
  187340. + pr_debug("mxc_mlb150: get version: 0x%08x\n",
  187341. + version);
  187342. +
  187343. + if (copy_to_user(argp, &version, sizeof(version))) {
  187344. + pr_err("mxc_mlb150: copy to user failed\n");
  187345. + return -EFAULT;
  187346. + }
  187347. + break;
  187348. + }
  187349. +
  187350. + case MLB_SET_DEVADDR:
  187351. + {
  187352. + u32 c1_val;
  187353. + u8 devaddr;
  187354. +
  187355. + /* get MLB device address from user space */
  187356. + if (copy_from_user
  187357. + (&devaddr, argp, sizeof(unsigned char))) {
  187358. + pr_err("mxc_mlb150: copy from user failed\n");
  187359. + return -EFAULT;
  187360. + }
  187361. +
  187362. + c1_val = __raw_readl(mlb_base + REG_MLBC1);
  187363. + c1_val &= ~MLBC1_NDA_MASK;
  187364. + c1_val |= devaddr << MLBC1_NDA_SHIFT;
  187365. + __raw_writel(c1_val, mlb_base + REG_MLBC1);
  187366. + pr_debug("mxc_mlb150: set dev addr, dev addr: %d, "
  187367. + "MLBC1: 0x%08x\n", devaddr,
  187368. + (u32)__raw_readl(mlb_base + REG_MLBC1));
  187369. +
  187370. + break;
  187371. + }
  187372. +
  187373. + case MLB_IRQ_DISABLE:
  187374. + {
  187375. + disable_irq(drvdata->irq_mlb);
  187376. + break;
  187377. + }
  187378. +
  187379. + case MLB_IRQ_ENABLE:
  187380. + {
  187381. + enable_irq(drvdata->irq_mlb);
  187382. + break;
  187383. + }
  187384. + default:
  187385. + pr_info("mxc_mlb150: Invalid ioctl command\n");
  187386. + return -EINVAL;
  187387. + }
  187388. +
  187389. + return 0;
  187390. +}
  187391. +
  187392. +/*
  187393. + * MLB read routine
  187394. + * Read the current received data from queued buffer,
  187395. + * and free this buffer for hw to fill ingress data.
  187396. + */
  187397. +static ssize_t mxc_mlb150_read(struct file *filp, char __user *buf,
  187398. + size_t count, loff_t *f_pos)
  187399. +{
  187400. + int size;
  187401. + struct mlb_data *drvdata = filp->private_data;
  187402. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187403. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  187404. + int head, tail;
  187405. + unsigned long flags;
  187406. +
  187407. + read_lock_irqsave(&rx_rbuf->rb_lock, flags);
  187408. +
  187409. + head = ACCESS_ONCE(rx_rbuf->head);
  187410. + tail = rx_rbuf->tail;
  187411. +
  187412. + read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
  187413. +
  187414. + /* check the current rx buffer is available or not */
  187415. + if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
  187416. +
  187417. + if (filp->f_flags & O_NONBLOCK)
  187418. + return -EAGAIN;
  187419. +
  187420. + do {
  187421. + DEFINE_WAIT(__wait);
  187422. +
  187423. + for (;;) {
  187424. + prepare_to_wait(&pdevinfo->rx_wq,
  187425. + &__wait, TASK_INTERRUPTIBLE);
  187426. +
  187427. + read_lock_irqsave(&rx_rbuf->rb_lock, flags);
  187428. + if (CIRC_CNT(rx_rbuf->head, rx_rbuf->tail,
  187429. + TRANS_RING_NODES) > 0) {
  187430. + read_unlock_irqrestore(&rx_rbuf->rb_lock,
  187431. + flags);
  187432. + break;
  187433. + }
  187434. + read_unlock_irqrestore(&rx_rbuf->rb_lock,
  187435. + flags);
  187436. +
  187437. + if (!signal_pending(current)) {
  187438. + schedule();
  187439. + continue;
  187440. + }
  187441. + return -ERESTARTSYS;
  187442. + }
  187443. + finish_wait(&pdevinfo->rx_wq, &__wait);
  187444. + } while (0);
  187445. + }
  187446. +
  187447. + /* read index before reading contents at that index */
  187448. + smp_read_barrier_depends();
  187449. +
  187450. + size = pdevinfo->adt_buf_dep;
  187451. + if (size > count) {
  187452. + /* the user buffer is too small */
  187453. + pr_warning
  187454. + ("mxc_mlb150: received data size is bigger than "
  187455. + "size: %d, count: %d\n", size, count);
  187456. + return -EINVAL;
  187457. + }
  187458. +
  187459. + /* extract one item from the buffer */
  187460. + if (copy_to_user(buf, rx_rbuf->virt_bufs[tail], size)) {
  187461. + pr_err("mxc_mlb150: copy from user failed\n");
  187462. + return -EFAULT;
  187463. + }
  187464. +
  187465. + /* finish reading descriptor before incrementing tail */
  187466. + smp_mb();
  187467. +
  187468. + write_lock_irqsave(&rx_rbuf->rb_lock, flags);
  187469. + rx_rbuf->tail = (tail + 1) & (TRANS_RING_NODES - 1);
  187470. + write_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
  187471. +
  187472. + *f_pos = 0;
  187473. +
  187474. + return size;
  187475. +}
  187476. +
  187477. +/*
  187478. + * MLB write routine
  187479. + * Copy the user data to tx channel buffer,
  187480. + * and prepare the channel current/next buffer ptr.
  187481. + */
  187482. +static ssize_t mxc_mlb150_write(struct file *filp, const char __user *buf,
  187483. + size_t count, loff_t *f_pos)
  187484. +{
  187485. + s32 ret = 0;
  187486. + struct mlb_channel_info *pchinfo = NULL;
  187487. + struct mlb_data *drvdata = filp->private_data;
  187488. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187489. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  187490. + int head, tail;
  187491. + unsigned long flags;
  187492. +
  187493. + /*
  187494. + * minor = MINOR(filp->f_dentry->d_inode->i_rdev);
  187495. + */
  187496. + pchinfo = &pdevinfo->channels[TX_CHANNEL];
  187497. +
  187498. + if (count > pdevinfo->buf_size) {
  187499. + /* too many data to write */
  187500. + pr_warning("mxc_mlb150: overflow write data\n");
  187501. + return -EFBIG;
  187502. + }
  187503. +
  187504. + *f_pos = 0;
  187505. +
  187506. + read_lock_irqsave(&tx_rbuf->rb_lock, flags);
  187507. +
  187508. + head = tx_rbuf->head;
  187509. + tail = ACCESS_ONCE(tx_rbuf->tail);
  187510. + read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  187511. +
  187512. + if (0 == CIRC_SPACE(head, tail, TRANS_RING_NODES)) {
  187513. + if (filp->f_flags & O_NONBLOCK)
  187514. + return -EAGAIN;
  187515. + do {
  187516. + DEFINE_WAIT(__wait);
  187517. +
  187518. + for (;;) {
  187519. + prepare_to_wait(&pdevinfo->tx_wq,
  187520. + &__wait, TASK_INTERRUPTIBLE);
  187521. +
  187522. + read_lock_irqsave(&tx_rbuf->rb_lock, flags);
  187523. + if (CIRC_SPACE(tx_rbuf->head, tx_rbuf->tail,
  187524. + TRANS_RING_NODES) > 0) {
  187525. + read_unlock_irqrestore(&tx_rbuf->rb_lock,
  187526. + flags);
  187527. + break;
  187528. + }
  187529. + read_unlock_irqrestore(&tx_rbuf->rb_lock,
  187530. + flags);
  187531. +
  187532. + if (!signal_pending(current)) {
  187533. + schedule();
  187534. + continue;
  187535. + }
  187536. + return -ERESTARTSYS;
  187537. + }
  187538. + finish_wait(&pdevinfo->tx_wq, &__wait);
  187539. + } while (0);
  187540. + }
  187541. +
  187542. + if (copy_from_user((void *)tx_rbuf->virt_bufs[head], buf, count)) {
  187543. + read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  187544. + pr_err("mxc_mlb: copy from user failed\n");
  187545. + ret = -EFAULT;
  187546. + goto out;
  187547. + }
  187548. +
  187549. + write_lock_irqsave(&tx_rbuf->rb_lock, flags);
  187550. + smp_wmb();
  187551. + tx_rbuf->head = (head + 1) & (TRANS_RING_NODES - 1);
  187552. + write_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  187553. +
  187554. + if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
  187555. + u32 tx_buf_ptr, ahb_ch;
  187556. + s32 adt_sts;
  187557. + u32 ctype = pdevinfo->channel_type;
  187558. +
  187559. + /* read index before reading contents at that index */
  187560. + smp_read_barrier_depends();
  187561. +
  187562. + tx_buf_ptr = tx_rbuf->phy_addrs[tail];
  187563. +
  187564. + ahb_ch = pdevinfo->channels[TX_CHANNEL].cl;
  187565. + adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
  187566. +
  187567. + /* Set ADT for TX */
  187568. + mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
  187569. + }
  187570. +
  187571. + ret = count;
  187572. +out:
  187573. + return ret;
  187574. +}
  187575. +
  187576. +static unsigned int mxc_mlb150_poll(struct file *filp,
  187577. + struct poll_table_struct *wait)
  187578. +{
  187579. + int minor;
  187580. + unsigned int ret = 0;
  187581. + struct mlb_data *drvdata = filp->private_data;
  187582. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187583. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  187584. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  187585. + int head, tail;
  187586. + unsigned long flags;
  187587. +
  187588. +
  187589. + minor = MINOR(filp->f_dentry->d_inode->i_rdev);
  187590. +
  187591. + poll_wait(filp, &pdevinfo->rx_wq, wait);
  187592. + poll_wait(filp, &pdevinfo->tx_wq, wait);
  187593. +
  187594. + read_lock_irqsave(&tx_rbuf->rb_lock, flags);
  187595. + head = tx_rbuf->head;
  187596. + tail = tx_rbuf->tail;
  187597. + read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  187598. +
  187599. + /* check the tx buffer is avaiable or not */
  187600. + if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1)
  187601. + ret |= POLLOUT | POLLWRNORM;
  187602. +
  187603. + read_lock_irqsave(&rx_rbuf->rb_lock, flags);
  187604. + head = rx_rbuf->head;
  187605. + tail = rx_rbuf->tail;
  187606. + read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
  187607. +
  187608. + /* check the rx buffer filled or not */
  187609. + if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1)
  187610. + ret |= POLLIN | POLLRDNORM;
  187611. +
  187612. +
  187613. + /* check the exception event */
  187614. + if (pdevinfo->ex_event)
  187615. + ret |= POLLIN | POLLRDNORM;
  187616. +
  187617. + return ret;
  187618. +}
  187619. +
  187620. +/*
  187621. + * char dev file operations structure
  187622. + */
  187623. +static const struct file_operations mxc_mlb150_fops = {
  187624. +
  187625. + .owner = THIS_MODULE,
  187626. + .open = mxc_mlb150_open,
  187627. + .release = mxc_mlb150_release,
  187628. + .unlocked_ioctl = mxc_mlb150_ioctl,
  187629. + .poll = mxc_mlb150_poll,
  187630. + .read = mxc_mlb150_read,
  187631. + .write = mxc_mlb150_write,
  187632. +};
  187633. +
  187634. +static struct platform_device_id imx_mlb150_devtype[] = {
  187635. + {
  187636. + .name = "imx6q-mlb150",
  187637. + .driver_data = 0,
  187638. + }, {
  187639. + /* sentinel */
  187640. + }
  187641. +};
  187642. +MODULE_DEVICE_TABLE(platform, imx_mlb150_devtype);
  187643. +
  187644. +static const struct of_device_id mlb150_imx_dt_ids[] = {
  187645. + { .compatible = "fsl,imx6q-mlb150", .data = &imx_mlb150_devtype[0], },
  187646. + { /* sentinel */ }
  187647. +};
  187648. +
  187649. +/*
  187650. + * This function is called whenever the MLB device is detected.
  187651. + */
  187652. +static int mxc_mlb150_probe(struct platform_device *pdev)
  187653. +{
  187654. + int ret, mlb_major, i;
  187655. + struct mlb_data *drvdata;
  187656. + struct resource *res;
  187657. + struct device_node *np = pdev->dev.of_node;
  187658. +
  187659. + drvdata = devm_kzalloc(&pdev->dev, sizeof(struct mlb_data),
  187660. + GFP_KERNEL);
  187661. + if (!drvdata) {
  187662. + dev_err(&pdev->dev, "can't allocate enough memory\n");
  187663. + return -ENOMEM;
  187664. + }
  187665. +
  187666. + /*
  187667. + * Register MLB lld as four character devices
  187668. + */
  187669. + ret = alloc_chrdev_region(&drvdata->firstdev, 0,
  187670. + MLB_MINOR_DEVICES, "mxc_mlb150");
  187671. + if (ret < 0) {
  187672. + dev_err(&pdev->dev, "alloc region error\n");
  187673. + goto err_reg;
  187674. + }
  187675. + mlb_major = MAJOR(drvdata->firstdev);
  187676. + dev_dbg(&pdev->dev, "MLB device major: %d\n", mlb_major);
  187677. +
  187678. + cdev_init(&drvdata->cdev, &mxc_mlb150_fops);
  187679. + drvdata->cdev.owner = THIS_MODULE;
  187680. +
  187681. + ret = cdev_add(&drvdata->cdev, drvdata->firstdev, MLB_MINOR_DEVICES);
  187682. + if (ret) {
  187683. + dev_err(&pdev->dev, "can't add cdev\n");
  187684. + goto err_reg;
  187685. + }
  187686. +
  187687. + /* create class and device for udev information */
  187688. + drvdata->class = class_create(THIS_MODULE, "mlb150");
  187689. + if (IS_ERR(drvdata->class)) {
  187690. + dev_err(&pdev->dev, "failed to create device class\n");
  187691. + ret = -ENOMEM;
  187692. + goto err_class;
  187693. + }
  187694. +
  187695. + for (i = 0; i < MLB_MINOR_DEVICES; i++) {
  187696. + struct device *class_dev;
  187697. +
  187698. + class_dev = device_create(drvdata->class, NULL,
  187699. + MKDEV(mlb_major, i),
  187700. + NULL, mlb_devinfo[i].dev_name);
  187701. + if (IS_ERR(class_dev)) {
  187702. + dev_err(&pdev->dev, "failed to create mlb150 %s"
  187703. + " class device\n", mlb_devinfo[i].dev_name);
  187704. + ret = -ENOMEM;
  187705. + goto err_dev;
  187706. + }
  187707. + }
  187708. +
  187709. + /* ahb0 irq */
  187710. + drvdata->irq_ahb0 = platform_get_irq(pdev, 1);
  187711. + if (drvdata->irq_ahb0 < 0) {
  187712. + dev_err(&pdev->dev, "No ahb0 irq line provided\n");
  187713. + goto err_dev;
  187714. + }
  187715. + dev_dbg(&pdev->dev, "ahb0_irq: %d\n", drvdata->irq_ahb0);
  187716. + if (devm_request_irq(&pdev->dev, drvdata->irq_ahb0, mlb_ahb_isr,
  187717. + 0, "mlb_ahb0", NULL)) {
  187718. + dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_ahb0);
  187719. + goto err_dev;
  187720. + }
  187721. +
  187722. + /* ahb1 irq */
  187723. + drvdata->irq_ahb1 = platform_get_irq(pdev, 2);
  187724. + if (drvdata->irq_ahb1 < 0) {
  187725. + dev_err(&pdev->dev, "No ahb1 irq line provided\n");
  187726. + goto err_dev;
  187727. + }
  187728. + dev_dbg(&pdev->dev, "ahb1_irq: %d\n", drvdata->irq_ahb1);
  187729. + if (devm_request_irq(&pdev->dev, drvdata->irq_ahb1, mlb_ahb_isr,
  187730. + 0, "mlb_ahb1", NULL)) {
  187731. + dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_ahb1);
  187732. + goto err_dev;
  187733. + }
  187734. +
  187735. + /* mlb irq */
  187736. + drvdata->irq_mlb = platform_get_irq(pdev, 0);
  187737. + if (drvdata->irq_mlb < 0) {
  187738. + dev_err(&pdev->dev, "No mlb irq line provided\n");
  187739. + goto err_dev;
  187740. + }
  187741. + dev_dbg(&pdev->dev, "mlb_irq: %d\n", drvdata->irq_mlb);
  187742. + if (devm_request_irq(&pdev->dev, drvdata->irq_mlb, mlb_isr,
  187743. + 0, "mlb", NULL)) {
  187744. + dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_mlb);
  187745. + goto err_dev;
  187746. + }
  187747. +
  187748. + /* ioremap from phy mlb to kernel space */
  187749. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  187750. + if (!res) {
  187751. + dev_err(&pdev->dev, "can't get device resources\n");
  187752. + ret = -ENOENT;
  187753. + goto err_dev;
  187754. + }
  187755. + mlb_base = devm_request_and_ioremap(&pdev->dev, res);
  187756. + dev_dbg(&pdev->dev, "mapped base address: 0x%08x\n", (u32)mlb_base);
  187757. + if (IS_ERR(mlb_base)) {
  187758. + dev_err(&pdev->dev,
  187759. + "failed to get ioremap base\n");
  187760. + ret = PTR_ERR(mlb_base);
  187761. + goto err_dev;
  187762. + }
  187763. + drvdata->membase = mlb_base;
  187764. +
  187765. +#ifdef CONFIG_REGULATOR
  187766. + drvdata->nvcc = devm_regulator_get(&pdev->dev, "reg_nvcc");
  187767. + if (!IS_ERR(drvdata->nvcc)) {
  187768. + regulator_set_voltage(drvdata->nvcc, 2500000, 2500000);
  187769. + dev_err(&pdev->dev, "enalbe regulator\n");
  187770. + ret = regulator_enable(drvdata->nvcc);
  187771. + if (ret) {
  187772. + dev_err(&pdev->dev, "vdd set voltage error\n");
  187773. + goto err_dev;
  187774. + }
  187775. + }
  187776. +#endif
  187777. +
  187778. + /* enable clock */
  187779. + drvdata->clk_mlb3p = devm_clk_get(&pdev->dev, "mlb");
  187780. + if (IS_ERR(drvdata->clk_mlb3p)) {
  187781. + dev_err(&pdev->dev, "unable to get mlb clock\n");
  187782. + ret = PTR_ERR(drvdata->clk_mlb3p);
  187783. + goto err_dev;
  187784. + }
  187785. +
  187786. + drvdata->clk_mlb6p = devm_clk_get(&pdev->dev, "pll8_mlb");
  187787. + if (IS_ERR(drvdata->clk_mlb6p)) {
  187788. + dev_err(&pdev->dev, "unable to get mlb pll clock\n");
  187789. + ret = PTR_ERR(drvdata->clk_mlb6p);
  187790. + goto err_dev;
  187791. + }
  187792. +
  187793. +
  187794. + drvdata->iram_pool = of_get_named_gen_pool(np, "iram", 0);
  187795. + if (!drvdata->iram_pool) {
  187796. + dev_err(&pdev->dev, "iram pool not available\n");
  187797. + ret = -ENOMEM;
  187798. + goto err_dev;
  187799. + }
  187800. +
  187801. + drvdata->devinfo = NULL;
  187802. + mxc_mlb150_irq_enable(drvdata, 0);
  187803. + platform_set_drvdata(pdev, drvdata);
  187804. + return 0;
  187805. +
  187806. +err_dev:
  187807. + for (--i; i >= 0; i--)
  187808. + device_destroy(drvdata->class, MKDEV(mlb_major, i));
  187809. +
  187810. + class_destroy(drvdata->class);
  187811. +err_class:
  187812. + cdev_del(&drvdata->cdev);
  187813. +err_reg:
  187814. + unregister_chrdev_region(drvdata->firstdev, MLB_MINOR_DEVICES);
  187815. +
  187816. + return ret;
  187817. +}
  187818. +
  187819. +static int mxc_mlb150_remove(struct platform_device *pdev)
  187820. +{
  187821. + int i;
  187822. + struct mlb_data *drvdata = platform_get_drvdata(pdev);
  187823. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187824. +
  187825. + if (pdevinfo && atomic_read(&pdevinfo->on)
  187826. + && (pdevinfo->fps >= CLK_2048FS))
  187827. + clk_disable_unprepare(drvdata->clk_mlb6p);
  187828. +
  187829. + if (pdevinfo && atomic_read(&pdevinfo->opencnt))
  187830. + clk_disable_unprepare(drvdata->clk_mlb3p);
  187831. +
  187832. + /* disable mlb power */
  187833. +#ifdef CONFIG_REGULATOR
  187834. + if (!IS_ERR(drvdata->nvcc))
  187835. + regulator_disable(drvdata->nvcc);
  187836. +#endif
  187837. +
  187838. + /* destroy mlb device class */
  187839. + for (i = MLB_MINOR_DEVICES - 1; i >= 0; i--)
  187840. + device_destroy(drvdata->class,
  187841. + MKDEV(MAJOR(drvdata->firstdev), i));
  187842. + class_destroy(drvdata->class);
  187843. +
  187844. + cdev_del(&drvdata->cdev);
  187845. +
  187846. + /* Unregister the two MLB devices */
  187847. + unregister_chrdev_region(drvdata->firstdev, MLB_MINOR_DEVICES);
  187848. +
  187849. + return 0;
  187850. +}
  187851. +
  187852. +#ifdef CONFIG_PM
  187853. +static int mxc_mlb150_suspend(struct platform_device *pdev, pm_message_t state)
  187854. +{
  187855. + struct mlb_data *drvdata = platform_get_drvdata(pdev);
  187856. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187857. +
  187858. + if (pdevinfo && atomic_read(&pdevinfo->on)
  187859. + && (pdevinfo->fps >= CLK_2048FS))
  187860. + clk_disable_unprepare(drvdata->clk_mlb6p);
  187861. +
  187862. + if (pdevinfo && atomic_read(&pdevinfo->opencnt)) {
  187863. + mlb150_dev_exit();
  187864. + clk_disable_unprepare(drvdata->clk_mlb3p);
  187865. + }
  187866. +
  187867. + return 0;
  187868. +}
  187869. +
  187870. +static int mxc_mlb150_resume(struct platform_device *pdev)
  187871. +{
  187872. + struct mlb_data *drvdata = platform_get_drvdata(pdev);
  187873. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187874. +
  187875. + if (pdevinfo && atomic_read(&pdevinfo->opencnt)) {
  187876. + clk_prepare_enable(drvdata->clk_mlb3p);
  187877. + mlb150_dev_init();
  187878. + }
  187879. +
  187880. + if (pdevinfo && atomic_read(&pdevinfo->on) &&
  187881. + (pdevinfo->fps >= CLK_2048FS))
  187882. + clk_prepare_enable(drvdata->clk_mlb6p);
  187883. +
  187884. + return 0;
  187885. +}
  187886. +#else
  187887. +#define mxc_mlb150_suspend NULL
  187888. +#define mxc_mlb150_resume NULL
  187889. +#endif
  187890. +
  187891. +/*
  187892. + * platform driver structure for MLB
  187893. + */
  187894. +static struct platform_driver mxc_mlb150_driver = {
  187895. + .driver = {
  187896. + .name = DRIVER_NAME,
  187897. + .owner = THIS_MODULE,
  187898. + .of_match_table = mlb150_imx_dt_ids,
  187899. + },
  187900. + .probe = mxc_mlb150_probe,
  187901. + .remove = mxc_mlb150_remove,
  187902. + .suspend = mxc_mlb150_suspend,
  187903. + .resume = mxc_mlb150_resume,
  187904. + .id_table = imx_mlb150_devtype,
  187905. +};
  187906. +
  187907. +static int __init mxc_mlb150_init(void)
  187908. +{
  187909. + return platform_driver_register(&mxc_mlb150_driver);
  187910. +}
  187911. +
  187912. +static void __exit mxc_mlb150_exit(void)
  187913. +{
  187914. + platform_driver_unregister(&mxc_mlb150_driver);
  187915. +}
  187916. +
  187917. +module_init(mxc_mlb150_init);
  187918. +module_exit(mxc_mlb150_exit);
  187919. +
  187920. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  187921. +MODULE_DESCRIPTION("MLB150 low level driver");
  187922. +MODULE_LICENSE("GPL");
  187923. diff -Nur linux-3.14.15/drivers/mxc/vpu/Kconfig linux-linaro-stable-mx6/drivers/mxc/vpu/Kconfig
  187924. --- linux-3.14.15/drivers/mxc/vpu/Kconfig 1970-01-01 01:00:00.000000000 +0100
  187925. +++ linux-linaro-stable-mx6/drivers/mxc/vpu/Kconfig 2014-08-20 19:23:53.578845924 +0200
  187926. @@ -0,0 +1,31 @@
  187927. +#
  187928. +# Codec configuration
  187929. +#
  187930. +
  187931. +menu "MXC VPU(Video Processing Unit) support"
  187932. +
  187933. +config MXC_VPU
  187934. + tristate "Support for MXC VPU(Video Processing Unit)"
  187935. + depends on (SOC_IMX27 || SOC_IMX5 || SOC_IMX6Q)
  187936. + default y
  187937. + ---help---
  187938. + The VPU codec device provides codec function for H.264/MPEG4/H.263,
  187939. + as well as MPEG2/VC-1/DivX on some platforms.
  187940. +
  187941. +config MXC_VPU_DEBUG
  187942. + bool "MXC VPU debugging"
  187943. + depends on MXC_VPU != n
  187944. + help
  187945. + This is an option for the developers; most people should
  187946. + say N here. This enables MXC VPU driver debugging.
  187947. +
  187948. +config MX6_VPU_352M
  187949. + bool "MX6 VPU 352M"
  187950. + depends on MXC_VPU
  187951. + default n
  187952. + help
  187953. + Increase VPU frequncy to 352M, the config will disable bus frequency
  187954. + adjust dynamic, and CPU lowest setpoint will be 352Mhz.
  187955. + This config is used for special VPU use case.
  187956. +
  187957. +endmenu
  187958. diff -Nur linux-3.14.15/drivers/mxc/vpu/Makefile linux-linaro-stable-mx6/drivers/mxc/vpu/Makefile
  187959. --- linux-3.14.15/drivers/mxc/vpu/Makefile 1970-01-01 01:00:00.000000000 +0100
  187960. +++ linux-linaro-stable-mx6/drivers/mxc/vpu/Makefile 2014-08-20 19:23:53.578845924 +0200
  187961. @@ -0,0 +1,9 @@
  187962. +#
  187963. +# Makefile for the VPU drivers.
  187964. +#
  187965. +
  187966. +obj-$(CONFIG_MXC_VPU) += mxc_vpu.o
  187967. +
  187968. +ifeq ($(CONFIG_MXC_VPU_DEBUG),y)
  187969. +EXTRA_CFLAGS += -DDEBUG
  187970. +endif
  187971. diff -Nur linux-3.14.15/drivers/mxc/vpu/mxc_vpu.c linux-linaro-stable-mx6/drivers/mxc/vpu/mxc_vpu.c
  187972. --- linux-3.14.15/drivers/mxc/vpu/mxc_vpu.c 1970-01-01 01:00:00.000000000 +0100
  187973. +++ linux-linaro-stable-mx6/drivers/mxc/vpu/mxc_vpu.c 2014-08-20 19:23:53.578845924 +0200
  187974. @@ -0,0 +1,1342 @@
  187975. +/*
  187976. + * Copyright 2006-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  187977. + */
  187978. +
  187979. +/*
  187980. + * The code contained herein is licensed under the GNU General Public
  187981. + * License. You may obtain a copy of the GNU General Public License
  187982. + * Version 2 or later at the following locations:
  187983. + *
  187984. + * http://www.opensource.org/licenses/gpl-license.html
  187985. + * http://www.gnu.org/copyleft/gpl.html
  187986. + */
  187987. +
  187988. +/*!
  187989. + * @file mxc_vpu.c
  187990. + *
  187991. + * @brief VPU system initialization and file operation implementation
  187992. + *
  187993. + * @ingroup VPU
  187994. + */
  187995. +
  187996. +#include <linux/kernel.h>
  187997. +#include <linux/mm.h>
  187998. +#include <linux/interrupt.h>
  187999. +#include <linux/ioport.h>
  188000. +#include <linux/stat.h>
  188001. +#include <linux/platform_device.h>
  188002. +#include <linux/kdev_t.h>
  188003. +#include <linux/dma-mapping.h>
  188004. +#include <linux/wait.h>
  188005. +#include <linux/list.h>
  188006. +#include <linux/clk.h>
  188007. +#include <linux/delay.h>
  188008. +#include <linux/fsl_devices.h>
  188009. +#include <linux/uaccess.h>
  188010. +#include <linux/io.h>
  188011. +#include <linux/slab.h>
  188012. +#include <linux/workqueue.h>
  188013. +#include <linux/sched.h>
  188014. +#include <linux/vmalloc.h>
  188015. +#include <linux/regulator/consumer.h>
  188016. +#include <linux/page-flags.h>
  188017. +#include <linux/mm_types.h>
  188018. +#include <linux/types.h>
  188019. +#include <linux/memblock.h>
  188020. +#include <linux/memory.h>
  188021. +#include <linux/version.h>
  188022. +#include <asm/page.h>
  188023. +
  188024. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188025. +#include <linux/module.h>
  188026. +#include <linux/pm_runtime.h>
  188027. +#include <linux/sizes.h>
  188028. +#endif
  188029. +
  188030. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
  188031. +#include <linux/iram_alloc.h>
  188032. +#include <mach/clock.h>
  188033. +#include <mach/hardware.h>
  188034. +#include <mach/mxc_vpu.h>
  188035. +#endif
  188036. +
  188037. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188038. +#include <linux/busfreq-imx6.h>
  188039. +#include <linux/clk.h>
  188040. +#include <linux/genalloc.h>
  188041. +#include <linux/mxc_vpu.h>
  188042. +#include <linux/of.h>
  188043. +#include <linux/reset.h>
  188044. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188045. +#include <mach/busfreq.h>
  188046. +#include <mach/common.h>
  188047. +#else
  188048. +#include <asm/sizes.h>
  188049. +#endif
  188050. +
  188051. +/* Define one new pgprot which combined uncached and XN(never executable) */
  188052. +#define pgprot_noncachedxn(prot) \
  188053. + __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
  188054. +
  188055. +struct vpu_priv {
  188056. + struct fasync_struct *async_queue;
  188057. + struct work_struct work;
  188058. + struct workqueue_struct *workqueue;
  188059. + struct mutex lock;
  188060. +};
  188061. +
  188062. +/* To track the allocated memory buffer */
  188063. +struct memalloc_record {
  188064. + struct list_head list;
  188065. + struct vpu_mem_desc mem;
  188066. +};
  188067. +
  188068. +struct iram_setting {
  188069. + u32 start;
  188070. + u32 end;
  188071. +};
  188072. +
  188073. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188074. +static struct gen_pool *iram_pool;
  188075. +static u32 iram_base;
  188076. +#endif
  188077. +
  188078. +static LIST_HEAD(head);
  188079. +
  188080. +static int vpu_major;
  188081. +static int vpu_clk_usercount;
  188082. +static struct class *vpu_class;
  188083. +static struct vpu_priv vpu_data;
  188084. +static u8 open_count;
  188085. +static struct clk *vpu_clk;
  188086. +static struct vpu_mem_desc bitwork_mem = { 0 };
  188087. +static struct vpu_mem_desc pic_para_mem = { 0 };
  188088. +static struct vpu_mem_desc user_data_mem = { 0 };
  188089. +static struct vpu_mem_desc share_mem = { 0 };
  188090. +static struct vpu_mem_desc vshare_mem = { 0 };
  188091. +
  188092. +static void __iomem *vpu_base;
  188093. +static int vpu_ipi_irq;
  188094. +static u32 phy_vpu_base_addr;
  188095. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  188096. +static phys_addr_t top_address_DRAM;
  188097. +static struct mxc_vpu_platform_data *vpu_plat;
  188098. +#endif
  188099. +
  188100. +static struct device *vpu_dev;
  188101. +
  188102. +/* IRAM setting */
  188103. +static struct iram_setting iram;
  188104. +
  188105. +/* implement the blocking ioctl */
  188106. +static int irq_status;
  188107. +static int codec_done;
  188108. +static wait_queue_head_t vpu_queue;
  188109. +
  188110. +#ifdef CONFIG_SOC_IMX6Q
  188111. +#define MXC_VPU_HAS_JPU
  188112. +#endif
  188113. +
  188114. +#ifdef MXC_VPU_HAS_JPU
  188115. +static int vpu_jpu_irq;
  188116. +#endif
  188117. +
  188118. +#ifdef CONFIG_PM
  188119. +static unsigned int regBk[64];
  188120. +static unsigned int pc_before_suspend;
  188121. +#endif
  188122. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188123. +static struct regulator *vpu_regulator;
  188124. +#endif
  188125. +static atomic_t clk_cnt_from_ioc = ATOMIC_INIT(0);
  188126. +
  188127. +#define READ_REG(x) readl_relaxed(vpu_base + x)
  188128. +#define WRITE_REG(val, x) writel_relaxed(val, vpu_base + x)
  188129. +
  188130. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188131. +/* redirect to static functions */
  188132. +static int cpu_is_mx6dl(void)
  188133. +{
  188134. + int ret;
  188135. + ret = of_machine_is_compatible("fsl,imx6dl");
  188136. + return ret;
  188137. +}
  188138. +
  188139. +static int cpu_is_mx6q(void)
  188140. +{
  188141. + int ret;
  188142. + ret = of_machine_is_compatible("fsl,imx6q");
  188143. + return ret;
  188144. +}
  188145. +#endif
  188146. +
  188147. +static void vpu_reset(void)
  188148. +{
  188149. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188150. + device_reset(vpu_dev);
  188151. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188152. + imx_src_reset_vpu();
  188153. +#else
  188154. + if (vpu_plat->reset)
  188155. + vpu_plat->reset();
  188156. +#endif
  188157. +}
  188158. +
  188159. +static long vpu_power_get(bool on)
  188160. +{
  188161. + long ret = 0;
  188162. +
  188163. + if (on) {
  188164. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  188165. + vpu_regulator = regulator_get(NULL, "cpu_vddvpu");
  188166. + ret = IS_ERR(vpu_regulator);
  188167. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188168. + vpu_regulator = devm_regulator_get(vpu_dev, "pu");
  188169. + ret = IS_ERR(vpu_regulator);
  188170. +#endif
  188171. + } else {
  188172. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  188173. + if (!IS_ERR(vpu_regulator))
  188174. + regulator_put(vpu_regulator);
  188175. +#endif
  188176. + }
  188177. + return ret;
  188178. +}
  188179. +
  188180. +static void vpu_power_up(bool on)
  188181. +{
  188182. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188183. + int ret = 0;
  188184. +
  188185. + if (on) {
  188186. + if (!IS_ERR(vpu_regulator)) {
  188187. + ret = regulator_enable(vpu_regulator);
  188188. + if (ret)
  188189. + dev_err(vpu_dev, "failed to power up vpu\n");
  188190. + }
  188191. + } else {
  188192. + if (!IS_ERR(vpu_regulator)) {
  188193. + ret = regulator_disable(vpu_regulator);
  188194. + if (ret)
  188195. + dev_err(vpu_dev, "failed to power down vpu\n");
  188196. + }
  188197. + }
  188198. +#else
  188199. + imx_gpc_power_up_pu(on);
  188200. +#endif
  188201. +}
  188202. +
  188203. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188204. +static int cpu_is_mx53(void)
  188205. +{
  188206. + return 0;
  188207. +}
  188208. +
  188209. +static int cpu_is_mx51(void)
  188210. +{
  188211. + return 0;
  188212. +}
  188213. +
  188214. +#define VM_RESERVED 0
  188215. +#endif
  188216. +
  188217. +/*!
  188218. + * Private function to alloc dma buffer
  188219. + * @return status 0 success.
  188220. + */
  188221. +static int vpu_alloc_dma_buffer(struct vpu_mem_desc *mem)
  188222. +{
  188223. + mem->cpu_addr = (unsigned long)
  188224. + dma_alloc_coherent(NULL, PAGE_ALIGN(mem->size),
  188225. + (dma_addr_t *) (&mem->phy_addr),
  188226. + GFP_DMA | GFP_KERNEL);
  188227. + dev_dbg(vpu_dev, "[ALLOC] mem alloc cpu_addr = 0x%x\n", mem->cpu_addr);
  188228. + if ((void *)(mem->cpu_addr) == NULL) {
  188229. + dev_err(vpu_dev, "Physical memory allocation error!\n");
  188230. + return -1;
  188231. + }
  188232. + return 0;
  188233. +}
  188234. +
  188235. +/*!
  188236. + * Private function to free dma buffer
  188237. + */
  188238. +static void vpu_free_dma_buffer(struct vpu_mem_desc *mem)
  188239. +{
  188240. + if (mem->cpu_addr != 0) {
  188241. + dma_free_coherent(0, PAGE_ALIGN(mem->size),
  188242. + (void *)mem->cpu_addr, mem->phy_addr);
  188243. + }
  188244. +}
  188245. +
  188246. +/*!
  188247. + * Private function to free buffers
  188248. + * @return status 0 success.
  188249. + */
  188250. +static int vpu_free_buffers(void)
  188251. +{
  188252. + struct memalloc_record *rec, *n;
  188253. + struct vpu_mem_desc mem;
  188254. +
  188255. + list_for_each_entry_safe(rec, n, &head, list) {
  188256. + mem = rec->mem;
  188257. + if (mem.cpu_addr != 0) {
  188258. + vpu_free_dma_buffer(&mem);
  188259. + dev_dbg(vpu_dev, "[FREE] freed paddr=0x%08X\n", mem.phy_addr);
  188260. + /* delete from list */
  188261. + list_del(&rec->list);
  188262. + kfree(rec);
  188263. + }
  188264. + }
  188265. +
  188266. + return 0;
  188267. +}
  188268. +
  188269. +static inline void vpu_worker_callback(struct work_struct *w)
  188270. +{
  188271. + struct vpu_priv *dev = container_of(w, struct vpu_priv,
  188272. + work);
  188273. +
  188274. + if (dev->async_queue)
  188275. + kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
  188276. +
  188277. + irq_status = 1;
  188278. + /*
  188279. + * Clock is gated on when dec/enc started, gate it off when
  188280. + * codec is done.
  188281. + */
  188282. + if (codec_done)
  188283. + codec_done = 0;
  188284. +
  188285. + wake_up_interruptible(&vpu_queue);
  188286. +}
  188287. +
  188288. +/*!
  188289. + * @brief vpu interrupt handler
  188290. + */
  188291. +static irqreturn_t vpu_ipi_irq_handler(int irq, void *dev_id)
  188292. +{
  188293. + struct vpu_priv *dev = dev_id;
  188294. + unsigned long reg;
  188295. +
  188296. + reg = READ_REG(BIT_INT_REASON);
  188297. + if (reg & 0x8)
  188298. + codec_done = 1;
  188299. + WRITE_REG(0x1, BIT_INT_CLEAR);
  188300. +
  188301. + queue_work(dev->workqueue, &dev->work);
  188302. +
  188303. + return IRQ_HANDLED;
  188304. +}
  188305. +
  188306. +/*!
  188307. + * @brief vpu jpu interrupt handler
  188308. + */
  188309. +#ifdef MXC_VPU_HAS_JPU
  188310. +static irqreturn_t vpu_jpu_irq_handler(int irq, void *dev_id)
  188311. +{
  188312. + struct vpu_priv *dev = dev_id;
  188313. + unsigned long reg;
  188314. +
  188315. + reg = READ_REG(MJPEG_PIC_STATUS_REG);
  188316. + if (reg & 0x3)
  188317. + codec_done = 1;
  188318. +
  188319. + queue_work(dev->workqueue, &dev->work);
  188320. +
  188321. + return IRQ_HANDLED;
  188322. +}
  188323. +#endif
  188324. +
  188325. +/*!
  188326. + * @brief check phy memory prepare to pass to vpu is valid or not, we
  188327. + * already address some issue that if pass a wrong address to vpu
  188328. + * (like virtual address), system will hang.
  188329. + *
  188330. + * @return true return is a valid phy memory address, false return not.
  188331. + */
  188332. +bool vpu_is_valid_phy_memory(u32 paddr)
  188333. +{
  188334. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  188335. + if (paddr > top_address_DRAM)
  188336. + return false;
  188337. +#endif
  188338. +
  188339. + return true;
  188340. +}
  188341. +
  188342. +/*!
  188343. + * @brief open function for vpu file operation
  188344. + *
  188345. + * @return 0 on success or negative error code on error
  188346. + */
  188347. +static int vpu_open(struct inode *inode, struct file *filp)
  188348. +{
  188349. +
  188350. + mutex_lock(&vpu_data.lock);
  188351. +
  188352. + if (open_count++ == 0) {
  188353. +
  188354. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188355. + pm_runtime_get_sync(vpu_dev);
  188356. +#endif
  188357. + vpu_power_up(true);
  188358. +
  188359. +#ifdef CONFIG_SOC_IMX6Q
  188360. + clk_prepare(vpu_clk);
  188361. + clk_enable(vpu_clk);
  188362. + if (READ_REG(BIT_CUR_PC))
  188363. + dev_dbg(vpu_dev, "Not power off before vpu open!\n");
  188364. + clk_disable(vpu_clk);
  188365. + clk_unprepare(vpu_clk);
  188366. +#endif
  188367. + }
  188368. +
  188369. + filp->private_data = (void *)(&vpu_data);
  188370. + mutex_unlock(&vpu_data.lock);
  188371. + return 0;
  188372. +}
  188373. +
  188374. +/*!
  188375. + * @brief IO ctrl function for vpu file operation
  188376. + * @param cmd IO ctrl command
  188377. + * @return 0 on success or negative error code on error
  188378. + */
  188379. +static long vpu_ioctl(struct file *filp, u_int cmd,
  188380. + u_long arg)
  188381. +{
  188382. + int ret = 0;
  188383. +
  188384. + switch (cmd) {
  188385. + case VPU_IOC_PHYMEM_ALLOC:
  188386. + {
  188387. + struct memalloc_record *rec;
  188388. +
  188389. + rec = kzalloc(sizeof(*rec), GFP_KERNEL);
  188390. + if (!rec)
  188391. + return -ENOMEM;
  188392. +
  188393. + ret = copy_from_user(&(rec->mem),
  188394. + (struct vpu_mem_desc *)arg,
  188395. + sizeof(struct vpu_mem_desc));
  188396. + if (ret) {
  188397. + kfree(rec);
  188398. + return -EFAULT;
  188399. + }
  188400. +
  188401. + dev_dbg(vpu_dev, "[ALLOC] mem alloc size = 0x%x\n",
  188402. + rec->mem.size);
  188403. +
  188404. + ret = vpu_alloc_dma_buffer(&(rec->mem));
  188405. + if (ret == -1) {
  188406. + kfree(rec);
  188407. + dev_err(vpu_dev,
  188408. + "Physical memory allocation error!\n");
  188409. + break;
  188410. + }
  188411. + ret = copy_to_user((void __user *)arg, &(rec->mem),
  188412. + sizeof(struct vpu_mem_desc));
  188413. + if (ret) {
  188414. + kfree(rec);
  188415. + ret = -EFAULT;
  188416. + break;
  188417. + }
  188418. +
  188419. + mutex_lock(&vpu_data.lock);
  188420. + list_add(&rec->list, &head);
  188421. + mutex_unlock(&vpu_data.lock);
  188422. +
  188423. + break;
  188424. + }
  188425. + case VPU_IOC_PHYMEM_FREE:
  188426. + {
  188427. + struct memalloc_record *rec, *n;
  188428. + struct vpu_mem_desc vpu_mem;
  188429. +
  188430. + ret = copy_from_user(&vpu_mem,
  188431. + (struct vpu_mem_desc *)arg,
  188432. + sizeof(struct vpu_mem_desc));
  188433. + if (ret)
  188434. + return -EACCES;
  188435. +
  188436. + dev_dbg(vpu_dev, "[FREE] mem freed cpu_addr = 0x%x\n",
  188437. + vpu_mem.cpu_addr);
  188438. + if ((void *)vpu_mem.cpu_addr != NULL)
  188439. + vpu_free_dma_buffer(&vpu_mem);
  188440. +
  188441. + mutex_lock(&vpu_data.lock);
  188442. + list_for_each_entry_safe(rec, n, &head, list) {
  188443. + if (rec->mem.cpu_addr == vpu_mem.cpu_addr) {
  188444. + /* delete from list */
  188445. + list_del(&rec->list);
  188446. + kfree(rec);
  188447. + break;
  188448. + }
  188449. + }
  188450. + mutex_unlock(&vpu_data.lock);
  188451. +
  188452. + break;
  188453. + }
  188454. + case VPU_IOC_WAIT4INT:
  188455. + {
  188456. + u_long timeout = (u_long) arg;
  188457. + if (!wait_event_interruptible_timeout
  188458. + (vpu_queue, irq_status != 0,
  188459. + msecs_to_jiffies(timeout))) {
  188460. + dev_warn(vpu_dev, "VPU blocking: timeout.\n");
  188461. + ret = -ETIME;
  188462. + } else if (signal_pending(current)) {
  188463. + dev_warn(vpu_dev, "VPU interrupt received.\n");
  188464. + ret = -ERESTARTSYS;
  188465. + } else
  188466. + irq_status = 0;
  188467. + break;
  188468. + }
  188469. + case VPU_IOC_IRAM_SETTING:
  188470. + {
  188471. + ret = copy_to_user((void __user *)arg, &iram,
  188472. + sizeof(struct iram_setting));
  188473. + if (ret)
  188474. + ret = -EFAULT;
  188475. +
  188476. + break;
  188477. + }
  188478. + case VPU_IOC_CLKGATE_SETTING:
  188479. + {
  188480. + u32 clkgate_en;
  188481. +
  188482. + if (get_user(clkgate_en, (u32 __user *) arg))
  188483. + return -EFAULT;
  188484. +
  188485. + if (clkgate_en) {
  188486. + clk_prepare(vpu_clk);
  188487. + clk_enable(vpu_clk);
  188488. + atomic_inc(&clk_cnt_from_ioc);
  188489. + } else {
  188490. + clk_disable(vpu_clk);
  188491. + clk_unprepare(vpu_clk);
  188492. + atomic_dec(&clk_cnt_from_ioc);
  188493. + }
  188494. +
  188495. + break;
  188496. + }
  188497. + case VPU_IOC_GET_SHARE_MEM:
  188498. + {
  188499. + mutex_lock(&vpu_data.lock);
  188500. + if (share_mem.cpu_addr != 0) {
  188501. + ret = copy_to_user((void __user *)arg,
  188502. + &share_mem,
  188503. + sizeof(struct vpu_mem_desc));
  188504. + mutex_unlock(&vpu_data.lock);
  188505. + break;
  188506. + } else {
  188507. + if (copy_from_user(&share_mem,
  188508. + (struct vpu_mem_desc *)arg,
  188509. + sizeof(struct vpu_mem_desc))) {
  188510. + mutex_unlock(&vpu_data.lock);
  188511. + return -EFAULT;
  188512. + }
  188513. + if (vpu_alloc_dma_buffer(&share_mem) == -1)
  188514. + ret = -EFAULT;
  188515. + else {
  188516. + if (copy_to_user((void __user *)arg,
  188517. + &share_mem,
  188518. + sizeof(struct
  188519. + vpu_mem_desc)))
  188520. + ret = -EFAULT;
  188521. + }
  188522. + }
  188523. + mutex_unlock(&vpu_data.lock);
  188524. + break;
  188525. + }
  188526. + case VPU_IOC_REQ_VSHARE_MEM:
  188527. + {
  188528. + mutex_lock(&vpu_data.lock);
  188529. + if (vshare_mem.cpu_addr != 0) {
  188530. + ret = copy_to_user((void __user *)arg,
  188531. + &vshare_mem,
  188532. + sizeof(struct vpu_mem_desc));
  188533. + mutex_unlock(&vpu_data.lock);
  188534. + break;
  188535. + } else {
  188536. + if (copy_from_user(&vshare_mem,
  188537. + (struct vpu_mem_desc *)arg,
  188538. + sizeof(struct
  188539. + vpu_mem_desc))) {
  188540. + mutex_unlock(&vpu_data.lock);
  188541. + return -EFAULT;
  188542. + }
  188543. + /* vmalloc shared memory if not allocated */
  188544. + if (!vshare_mem.cpu_addr)
  188545. + vshare_mem.cpu_addr =
  188546. + (unsigned long)
  188547. + vmalloc_user(vshare_mem.size);
  188548. + if (copy_to_user
  188549. + ((void __user *)arg, &vshare_mem,
  188550. + sizeof(struct vpu_mem_desc)))
  188551. + ret = -EFAULT;
  188552. + }
  188553. + mutex_unlock(&vpu_data.lock);
  188554. + break;
  188555. + }
  188556. + case VPU_IOC_GET_WORK_ADDR:
  188557. + {
  188558. + if (bitwork_mem.cpu_addr != 0) {
  188559. + ret =
  188560. + copy_to_user((void __user *)arg,
  188561. + &bitwork_mem,
  188562. + sizeof(struct vpu_mem_desc));
  188563. + break;
  188564. + } else {
  188565. + if (copy_from_user(&bitwork_mem,
  188566. + (struct vpu_mem_desc *)arg,
  188567. + sizeof(struct vpu_mem_desc)))
  188568. + return -EFAULT;
  188569. +
  188570. + if (vpu_alloc_dma_buffer(&bitwork_mem) == -1)
  188571. + ret = -EFAULT;
  188572. + else if (copy_to_user((void __user *)arg,
  188573. + &bitwork_mem,
  188574. + sizeof(struct
  188575. + vpu_mem_desc)))
  188576. + ret = -EFAULT;
  188577. + }
  188578. + break;
  188579. + }
  188580. + /*
  188581. + * The following two ioctl is used when user allocates working buffer
  188582. + * and register it to vpu driver.
  188583. + */
  188584. + case VPU_IOC_QUERY_BITWORK_MEM:
  188585. + {
  188586. + if (copy_to_user((void __user *)arg,
  188587. + &bitwork_mem,
  188588. + sizeof(struct vpu_mem_desc)))
  188589. + ret = -EFAULT;
  188590. + break;
  188591. + }
  188592. + case VPU_IOC_SET_BITWORK_MEM:
  188593. + {
  188594. + if (copy_from_user(&bitwork_mem,
  188595. + (struct vpu_mem_desc *)arg,
  188596. + sizeof(struct vpu_mem_desc)))
  188597. + ret = -EFAULT;
  188598. + break;
  188599. + }
  188600. + case VPU_IOC_SYS_SW_RESET:
  188601. + {
  188602. + vpu_reset();
  188603. + break;
  188604. + }
  188605. + case VPU_IOC_REG_DUMP:
  188606. + break;
  188607. + case VPU_IOC_PHYMEM_DUMP:
  188608. + break;
  188609. + case VPU_IOC_PHYMEM_CHECK:
  188610. + {
  188611. + struct vpu_mem_desc check_memory;
  188612. + ret = copy_from_user(&check_memory,
  188613. + (void __user *)arg,
  188614. + sizeof(struct vpu_mem_desc));
  188615. + if (ret != 0) {
  188616. + dev_err(vpu_dev, "copy from user failure:%d\n", ret);
  188617. + ret = -EFAULT;
  188618. + break;
  188619. + }
  188620. + ret = vpu_is_valid_phy_memory((u32)check_memory.phy_addr);
  188621. +
  188622. + dev_dbg(vpu_dev, "vpu: memory phy:0x%x %s phy memory\n",
  188623. + check_memory.phy_addr, (ret ? "is" : "isn't"));
  188624. + /* borrow .size to pass back the result. */
  188625. + check_memory.size = ret;
  188626. + ret = copy_to_user((void __user *)arg, &check_memory,
  188627. + sizeof(struct vpu_mem_desc));
  188628. + if (ret) {
  188629. + ret = -EFAULT;
  188630. + break;
  188631. + }
  188632. + break;
  188633. + }
  188634. + case VPU_IOC_LOCK_DEV:
  188635. + {
  188636. + u32 lock_en;
  188637. +
  188638. + if (get_user(lock_en, (u32 __user *) arg))
  188639. + return -EFAULT;
  188640. +
  188641. + if (lock_en)
  188642. + mutex_lock(&vpu_data.lock);
  188643. + else
  188644. + mutex_unlock(&vpu_data.lock);
  188645. +
  188646. + break;
  188647. + }
  188648. + default:
  188649. + {
  188650. + dev_err(vpu_dev, "No such IOCTL, cmd is %d\n", cmd);
  188651. + ret = -EINVAL;
  188652. + break;
  188653. + }
  188654. + }
  188655. + return ret;
  188656. +}
  188657. +
  188658. +/*!
  188659. + * @brief Release function for vpu file operation
  188660. + * @return 0 on success or negative error code on error
  188661. + */
  188662. +static int vpu_release(struct inode *inode, struct file *filp)
  188663. +{
  188664. + int i;
  188665. + unsigned long timeout;
  188666. +
  188667. + mutex_lock(&vpu_data.lock);
  188668. +
  188669. + if (open_count > 0 && !(--open_count)) {
  188670. +
  188671. + /* Wait for vpu go to idle state */
  188672. + clk_prepare(vpu_clk);
  188673. + clk_enable(vpu_clk);
  188674. + if (READ_REG(BIT_CUR_PC)) {
  188675. +
  188676. + timeout = jiffies + HZ;
  188677. + while (READ_REG(BIT_BUSY_FLAG)) {
  188678. + msleep(1);
  188679. + if (time_after(jiffies, timeout)) {
  188680. + dev_warn(vpu_dev, "VPU timeout during release\n");
  188681. + break;
  188682. + }
  188683. + }
  188684. + clk_disable(vpu_clk);
  188685. + clk_unprepare(vpu_clk);
  188686. +
  188687. + /* Clean up interrupt */
  188688. + cancel_work_sync(&vpu_data.work);
  188689. + flush_workqueue(vpu_data.workqueue);
  188690. + irq_status = 0;
  188691. +
  188692. + clk_prepare(vpu_clk);
  188693. + clk_enable(vpu_clk);
  188694. + if (READ_REG(BIT_BUSY_FLAG)) {
  188695. +
  188696. + if (cpu_is_mx51() || cpu_is_mx53()) {
  188697. + dev_err(vpu_dev,
  188698. + "fatal error: can't gate/power off when VPU is busy\n");
  188699. + clk_disable(vpu_clk);
  188700. + clk_unprepare(vpu_clk);
  188701. + mutex_unlock(&vpu_data.lock);
  188702. + return -EFAULT;
  188703. + }
  188704. +
  188705. +#ifdef CONFIG_SOC_IMX6Q
  188706. + if (cpu_is_mx6dl() || cpu_is_mx6q()) {
  188707. + WRITE_REG(0x11, 0x10F0);
  188708. + timeout = jiffies + HZ;
  188709. + while (READ_REG(0x10F4) != 0x77) {
  188710. + msleep(1);
  188711. + if (time_after(jiffies, timeout))
  188712. + break;
  188713. + }
  188714. +
  188715. + if (READ_REG(0x10F4) != 0x77) {
  188716. + dev_err(vpu_dev,
  188717. + "fatal error: can't gate/power off when VPU is busy\n");
  188718. + WRITE_REG(0x0, 0x10F0);
  188719. + clk_disable(vpu_clk);
  188720. + clk_unprepare(vpu_clk);
  188721. + mutex_unlock(&vpu_data.lock);
  188722. + return -EFAULT;
  188723. + } else
  188724. + vpu_reset();
  188725. + }
  188726. +#endif
  188727. + }
  188728. + }
  188729. + clk_disable(vpu_clk);
  188730. + clk_unprepare(vpu_clk);
  188731. +
  188732. + vpu_free_buffers();
  188733. +
  188734. + /* Free shared memory when vpu device is idle */
  188735. + vpu_free_dma_buffer(&share_mem);
  188736. + share_mem.cpu_addr = 0;
  188737. + vfree((void *)vshare_mem.cpu_addr);
  188738. + vshare_mem.cpu_addr = 0;
  188739. +
  188740. + vpu_clk_usercount = atomic_read(&clk_cnt_from_ioc);
  188741. + for (i = 0; i < vpu_clk_usercount; i++) {
  188742. + clk_disable(vpu_clk);
  188743. + clk_unprepare(vpu_clk);
  188744. + atomic_dec(&clk_cnt_from_ioc);
  188745. + }
  188746. +
  188747. + vpu_power_up(false);
  188748. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188749. + pm_runtime_put_sync_suspend(vpu_dev);
  188750. +#endif
  188751. +
  188752. + }
  188753. + mutex_unlock(&vpu_data.lock);
  188754. +
  188755. + return 0;
  188756. +}
  188757. +
  188758. +/*!
  188759. + * @brief fasync function for vpu file operation
  188760. + * @return 0 on success or negative error code on error
  188761. + */
  188762. +static int vpu_fasync(int fd, struct file *filp, int mode)
  188763. +{
  188764. + struct vpu_priv *dev = (struct vpu_priv *)filp->private_data;
  188765. + return fasync_helper(fd, filp, mode, &dev->async_queue);
  188766. +}
  188767. +
  188768. +/*!
  188769. + * @brief memory map function of harware registers for vpu file operation
  188770. + * @return 0 on success or negative error code on error
  188771. + */
  188772. +static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm)
  188773. +{
  188774. + unsigned long pfn;
  188775. +
  188776. + vm->vm_flags |= VM_IO | VM_RESERVED;
  188777. + /*
  188778. + * Since vpu registers have been mapped with ioremap() at probe
  188779. + * which L_PTE_XN is 1, and the same physical address must be
  188780. + * mapped multiple times with same type, so set L_PTE_XN to 1 here.
  188781. + * Otherwise, there may be unexpected result in video codec.
  188782. + */
  188783. + vm->vm_page_prot = pgprot_noncachedxn(vm->vm_page_prot);
  188784. + pfn = phy_vpu_base_addr >> PAGE_SHIFT;
  188785. + dev_dbg(vpu_dev, "size=0x%x, page no.=0x%x\n",
  188786. + (int)(vm->vm_end - vm->vm_start), (int)pfn);
  188787. + return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end - vm->vm_start,
  188788. + vm->vm_page_prot) ? -EAGAIN : 0;
  188789. +}
  188790. +
  188791. +/*!
  188792. + * @brief memory map function of memory for vpu file operation
  188793. + * @return 0 on success or negative error code on error
  188794. + */
  188795. +static int vpu_map_dma_mem(struct file *fp, struct vm_area_struct *vm)
  188796. +{
  188797. + int request_size;
  188798. + request_size = vm->vm_end - vm->vm_start;
  188799. +
  188800. + dev_dbg(vpu_dev, "start=0x%x, pgoff=0x%x, size=0x%x\n",
  188801. + (unsigned int)(vm->vm_start), (unsigned int)(vm->vm_pgoff),
  188802. + request_size);
  188803. +
  188804. + vm->vm_flags |= VM_IO | VM_RESERVED;
  188805. + vm->vm_page_prot = pgprot_writecombine(vm->vm_page_prot);
  188806. +
  188807. + return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff,
  188808. + request_size, vm->vm_page_prot) ? -EAGAIN : 0;
  188809. +
  188810. +}
  188811. +
  188812. +/* !
  188813. + * @brief memory map function of vmalloced share memory
  188814. + * @return 0 on success or negative error code on error
  188815. + */
  188816. +static int vpu_map_vshare_mem(struct file *fp, struct vm_area_struct *vm)
  188817. +{
  188818. + int ret = -EINVAL;
  188819. +
  188820. + ret = remap_vmalloc_range(vm, (void *)(vm->vm_pgoff << PAGE_SHIFT), 0);
  188821. + vm->vm_flags |= VM_IO;
  188822. +
  188823. + return ret;
  188824. +}
  188825. +/*!
  188826. + * @brief memory map interface for vpu file operation
  188827. + * @return 0 on success or negative error code on error
  188828. + */
  188829. +static int vpu_mmap(struct file *fp, struct vm_area_struct *vm)
  188830. +{
  188831. + unsigned long offset;
  188832. +
  188833. + offset = vshare_mem.cpu_addr >> PAGE_SHIFT;
  188834. +
  188835. + if (vm->vm_pgoff && (vm->vm_pgoff == offset))
  188836. + return vpu_map_vshare_mem(fp, vm);
  188837. + else if (vm->vm_pgoff)
  188838. + return vpu_map_dma_mem(fp, vm);
  188839. + else
  188840. + return vpu_map_hwregs(fp, vm);
  188841. +}
  188842. +
  188843. +const struct file_operations vpu_fops = {
  188844. + .owner = THIS_MODULE,
  188845. + .open = vpu_open,
  188846. + .unlocked_ioctl = vpu_ioctl,
  188847. + .release = vpu_release,
  188848. + .fasync = vpu_fasync,
  188849. + .mmap = vpu_mmap,
  188850. +};
  188851. +
  188852. +/*!
  188853. + * This function is called by the driver framework to initialize the vpu device.
  188854. + * @param dev The device structure for the vpu passed in by the framework.
  188855. + * @return 0 on success or negative error code on error
  188856. + */
  188857. +static int vpu_dev_probe(struct platform_device *pdev)
  188858. +{
  188859. + int err = 0;
  188860. + struct device *temp_class;
  188861. + struct resource *res;
  188862. + unsigned long addr = 0;
  188863. +
  188864. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188865. + struct device_node *np = pdev->dev.of_node;
  188866. + u32 iramsize;
  188867. +
  188868. + err = of_property_read_u32(np, "iramsize", (u32 *)&iramsize);
  188869. + if (!err && iramsize)
  188870. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188871. + {
  188872. + iram_pool = of_get_named_gen_pool(np, "iram", 0);
  188873. + if (!iram_pool) {
  188874. + dev_err(&pdev->dev, "iram pool not available\n");
  188875. + return -ENOMEM;
  188876. + }
  188877. +
  188878. + iram_base = gen_pool_alloc(iram_pool, iramsize);
  188879. + if (!iram_base) {
  188880. + dev_err(&pdev->dev, "unable to alloc iram\n");
  188881. + return -ENOMEM;
  188882. + }
  188883. +
  188884. + addr = gen_pool_virt_to_phys(iram_pool, iram_base);
  188885. + }
  188886. +#else
  188887. + iram_alloc(iramsize, &addr);
  188888. +#endif
  188889. + if (addr == 0)
  188890. + iram.start = iram.end = 0;
  188891. + else {
  188892. + iram.start = addr;
  188893. + iram.end = addr + iramsize - 1;
  188894. + }
  188895. +#else
  188896. +
  188897. + vpu_plat = pdev->dev.platform_data;
  188898. +
  188899. + if (vpu_plat && vpu_plat->iram_enable && vpu_plat->iram_size)
  188900. + iram_alloc(vpu_plat->iram_size, &addr);
  188901. + if (addr == 0)
  188902. + iram.start = iram.end = 0;
  188903. + else {
  188904. + iram.start = addr;
  188905. + iram.end = addr + vpu_plat->iram_size - 1;
  188906. + }
  188907. +#endif
  188908. +
  188909. + vpu_dev = &pdev->dev;
  188910. +
  188911. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu_regs");
  188912. + if (!res) {
  188913. + dev_err(vpu_dev, "vpu: unable to get vpu base addr\n");
  188914. + return -ENODEV;
  188915. + }
  188916. + phy_vpu_base_addr = res->start;
  188917. + vpu_base = ioremap(res->start, res->end - res->start);
  188918. +
  188919. + vpu_major = register_chrdev(vpu_major, "mxc_vpu", &vpu_fops);
  188920. + if (vpu_major < 0) {
  188921. + dev_err(vpu_dev, "vpu: unable to get a major for VPU\n");
  188922. + err = -EBUSY;
  188923. + goto error;
  188924. + }
  188925. +
  188926. + vpu_class = class_create(THIS_MODULE, "mxc_vpu");
  188927. + if (IS_ERR(vpu_class)) {
  188928. + err = PTR_ERR(vpu_class);
  188929. + goto err_out_chrdev;
  188930. + }
  188931. +
  188932. + temp_class = device_create(vpu_class, NULL, MKDEV(vpu_major, 0),
  188933. + NULL, "mxc_vpu");
  188934. + if (IS_ERR(temp_class)) {
  188935. + err = PTR_ERR(temp_class);
  188936. + goto err_out_class;
  188937. + }
  188938. +
  188939. + vpu_clk = clk_get(&pdev->dev, "vpu_clk");
  188940. + if (IS_ERR(vpu_clk)) {
  188941. + err = -ENOENT;
  188942. + goto err_out_class;
  188943. + }
  188944. +
  188945. + vpu_ipi_irq = platform_get_irq_byname(pdev, "vpu_ipi_irq");
  188946. + if (vpu_ipi_irq < 0) {
  188947. + dev_err(vpu_dev, "vpu: unable to get vpu interrupt\n");
  188948. + err = -ENXIO;
  188949. + goto err_out_class;
  188950. + }
  188951. + err = request_irq(vpu_ipi_irq, vpu_ipi_irq_handler, 0, "VPU_CODEC_IRQ",
  188952. + (void *)(&vpu_data));
  188953. + if (err)
  188954. + goto err_out_class;
  188955. + if (vpu_power_get(true)) {
  188956. + if (!(cpu_is_mx51() || cpu_is_mx53())) {
  188957. + dev_err(vpu_dev, "failed to get vpu power\n");
  188958. + goto err_out_class;
  188959. + } else {
  188960. + /* regulator_get will return error on MX5x,
  188961. + * just igore it everywhere*/
  188962. + dev_warn(vpu_dev, "failed to get vpu power\n");
  188963. + }
  188964. + }
  188965. +
  188966. +#ifdef MXC_VPU_HAS_JPU
  188967. + vpu_jpu_irq = platform_get_irq_byname(pdev, "vpu_jpu_irq");
  188968. + if (vpu_jpu_irq < 0) {
  188969. + dev_err(vpu_dev, "vpu: unable to get vpu jpu interrupt\n");
  188970. + err = -ENXIO;
  188971. + free_irq(vpu_ipi_irq, &vpu_data);
  188972. + goto err_out_class;
  188973. + }
  188974. + err = request_irq(vpu_jpu_irq, vpu_jpu_irq_handler, IRQF_TRIGGER_RISING,
  188975. + "VPU_JPG_IRQ", (void *)(&vpu_data));
  188976. + if (err) {
  188977. + free_irq(vpu_ipi_irq, &vpu_data);
  188978. + goto err_out_class;
  188979. + }
  188980. +#endif
  188981. +
  188982. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188983. + pm_runtime_enable(&pdev->dev);
  188984. +#endif
  188985. +
  188986. + vpu_data.workqueue = create_workqueue("vpu_wq");
  188987. + INIT_WORK(&vpu_data.work, vpu_worker_callback);
  188988. + mutex_init(&vpu_data.lock);
  188989. + dev_info(vpu_dev, "VPU initialized\n");
  188990. + goto out;
  188991. +
  188992. +err_out_class:
  188993. + device_destroy(vpu_class, MKDEV(vpu_major, 0));
  188994. + class_destroy(vpu_class);
  188995. +err_out_chrdev:
  188996. + unregister_chrdev(vpu_major, "mxc_vpu");
  188997. +error:
  188998. + iounmap(vpu_base);
  188999. +out:
  189000. + return err;
  189001. +}
  189002. +
  189003. +static int vpu_dev_remove(struct platform_device *pdev)
  189004. +{
  189005. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  189006. + pm_runtime_disable(&pdev->dev);
  189007. +#endif
  189008. + free_irq(vpu_ipi_irq, &vpu_data);
  189009. +#ifdef MXC_VPU_HAS_JPU
  189010. + free_irq(vpu_jpu_irq, &vpu_data);
  189011. +#endif
  189012. + cancel_work_sync(&vpu_data.work);
  189013. + flush_workqueue(vpu_data.workqueue);
  189014. + destroy_workqueue(vpu_data.workqueue);
  189015. +
  189016. + iounmap(vpu_base);
  189017. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  189018. + if (iram.start)
  189019. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  189020. + gen_pool_free(iram_pool, iram_base, iram.end-iram.start+1);
  189021. +#else
  189022. + iram_free(iram.start, iram.end-iram.start+1);
  189023. +#endif
  189024. +#else
  189025. + if (vpu_plat && vpu_plat->iram_enable && vpu_plat->iram_size)
  189026. + iram_free(iram.start, vpu_plat->iram_size);
  189027. +#endif
  189028. +
  189029. + vpu_power_get(false);
  189030. + return 0;
  189031. +}
  189032. +
  189033. +#ifdef CONFIG_PM
  189034. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  189035. +static int vpu_suspend(struct device *dev)
  189036. +#else
  189037. +static int vpu_suspend(struct platform_device *pdev, pm_message_t state)
  189038. +#endif
  189039. +{
  189040. + int i;
  189041. + unsigned long timeout;
  189042. +
  189043. + mutex_lock(&vpu_data.lock);
  189044. + if (open_count == 0) {
  189045. + /* VPU is released (all instances are freed),
  189046. + * clock is already off, context is no longer needed,
  189047. + * power is already off on MX6,
  189048. + * gate power on MX51 */
  189049. + if (cpu_is_mx51()) {
  189050. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189051. + if (vpu_plat->pg)
  189052. + vpu_plat->pg(1);
  189053. +#endif
  189054. + }
  189055. + } else {
  189056. + /* Wait for vpu go to idle state, suspect vpu cannot be changed
  189057. + to idle state after about 1 sec */
  189058. + timeout = jiffies + HZ;
  189059. + clk_prepare(vpu_clk);
  189060. + clk_enable(vpu_clk);
  189061. + while (READ_REG(BIT_BUSY_FLAG)) {
  189062. + msleep(1);
  189063. + if (time_after(jiffies, timeout)) {
  189064. + clk_disable(vpu_clk);
  189065. + clk_unprepare(vpu_clk);
  189066. + mutex_unlock(&vpu_data.lock);
  189067. + return -EAGAIN;
  189068. + }
  189069. + }
  189070. + clk_disable(vpu_clk);
  189071. + clk_unprepare(vpu_clk);
  189072. +
  189073. + /* Make sure clock is disabled before suspend */
  189074. + vpu_clk_usercount = atomic_read(&clk_cnt_from_ioc);
  189075. + for (i = 0; i < vpu_clk_usercount; i++) {
  189076. + clk_disable(vpu_clk);
  189077. + clk_unprepare(vpu_clk);
  189078. + }
  189079. +
  189080. + if (cpu_is_mx53()) {
  189081. + mutex_unlock(&vpu_data.lock);
  189082. + return 0;
  189083. + }
  189084. +
  189085. + if (bitwork_mem.cpu_addr != 0) {
  189086. + clk_prepare(vpu_clk);
  189087. + clk_enable(vpu_clk);
  189088. + /* Save 64 registers from BIT_CODE_BUF_ADDR */
  189089. + for (i = 0; i < 64; i++)
  189090. + regBk[i] = READ_REG(BIT_CODE_BUF_ADDR + (i * 4));
  189091. + pc_before_suspend = READ_REG(BIT_CUR_PC);
  189092. + clk_disable(vpu_clk);
  189093. + clk_unprepare(vpu_clk);
  189094. + }
  189095. +
  189096. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189097. + if (vpu_plat->pg)
  189098. + vpu_plat->pg(1);
  189099. +#endif
  189100. +
  189101. + /* If VPU is working before suspend, disable
  189102. + * regulator to make usecount right. */
  189103. + vpu_power_up(false);
  189104. + }
  189105. +
  189106. + mutex_unlock(&vpu_data.lock);
  189107. + return 0;
  189108. +}
  189109. +
  189110. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  189111. +static int vpu_resume(struct device *dev)
  189112. +#else
  189113. +static int vpu_resume(struct platform_device *pdev)
  189114. +#endif
  189115. +{
  189116. + int i;
  189117. +
  189118. + mutex_lock(&vpu_data.lock);
  189119. + if (open_count == 0) {
  189120. + /* VPU is released (all instances are freed),
  189121. + * clock should be kept off, context is no longer needed,
  189122. + * power should be kept off on MX6,
  189123. + * disable power gating on MX51 */
  189124. + if (cpu_is_mx51()) {
  189125. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189126. + if (vpu_plat->pg)
  189127. + vpu_plat->pg(0);
  189128. +#endif
  189129. + }
  189130. + } else {
  189131. + if (cpu_is_mx53())
  189132. + goto recover_clk;
  189133. +
  189134. + /* If VPU is working before suspend, enable
  189135. + * regulator to make usecount right. */
  189136. + vpu_power_up(true);
  189137. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189138. + if (vpu_plat->pg)
  189139. + vpu_plat->pg(0);
  189140. +#endif
  189141. +
  189142. + if (bitwork_mem.cpu_addr != 0) {
  189143. + u32 *p = (u32 *) bitwork_mem.cpu_addr;
  189144. + u32 data, pc;
  189145. + u16 data_hi;
  189146. + u16 data_lo;
  189147. +
  189148. + clk_prepare(vpu_clk);
  189149. + clk_enable(vpu_clk);
  189150. +
  189151. + pc = READ_REG(BIT_CUR_PC);
  189152. + if (pc) {
  189153. + dev_warn(vpu_dev, "Not power off after suspend (PC=0x%x)\n", pc);
  189154. + clk_disable(vpu_clk);
  189155. + clk_unprepare(vpu_clk);
  189156. + goto recover_clk;
  189157. + }
  189158. +
  189159. + /* Restore registers */
  189160. + for (i = 0; i < 64; i++)
  189161. + WRITE_REG(regBk[i], BIT_CODE_BUF_ADDR + (i * 4));
  189162. +
  189163. + WRITE_REG(0x0, BIT_RESET_CTRL);
  189164. + WRITE_REG(0x0, BIT_CODE_RUN);
  189165. + /* MX6 RTL has a bug not to init MBC_SET_SUBBLK_EN on reset */
  189166. +#ifdef CONFIG_SOC_IMX6Q
  189167. + WRITE_REG(0x0, MBC_SET_SUBBLK_EN);
  189168. +#endif
  189169. +
  189170. + /*
  189171. + * Re-load boot code, from the codebuffer in external RAM.
  189172. + * Thankfully, we only need 4096 bytes, same for all platforms.
  189173. + */
  189174. + for (i = 0; i < 2048; i += 4) {
  189175. + data = p[(i / 2) + 1];
  189176. + data_hi = (data >> 16) & 0xFFFF;
  189177. + data_lo = data & 0xFFFF;
  189178. + WRITE_REG((i << 16) | data_hi, BIT_CODE_DOWN);
  189179. + WRITE_REG(((i + 1) << 16) | data_lo,
  189180. + BIT_CODE_DOWN);
  189181. +
  189182. + data = p[i / 2];
  189183. + data_hi = (data >> 16) & 0xFFFF;
  189184. + data_lo = data & 0xFFFF;
  189185. + WRITE_REG(((i + 2) << 16) | data_hi,
  189186. + BIT_CODE_DOWN);
  189187. + WRITE_REG(((i + 3) << 16) | data_lo,
  189188. + BIT_CODE_DOWN);
  189189. + }
  189190. +
  189191. + if (pc_before_suspend) {
  189192. + WRITE_REG(0x1, BIT_BUSY_FLAG);
  189193. + WRITE_REG(0x1, BIT_CODE_RUN);
  189194. + while (READ_REG(BIT_BUSY_FLAG))
  189195. + ;
  189196. + } else {
  189197. + dev_warn(vpu_dev, "PC=0 before suspend\n");
  189198. + }
  189199. + clk_disable(vpu_clk);
  189200. + clk_unprepare(vpu_clk);
  189201. + }
  189202. +
  189203. +recover_clk:
  189204. + /* Recover vpu clock */
  189205. + for (i = 0; i < vpu_clk_usercount; i++) {
  189206. + clk_prepare(vpu_clk);
  189207. + clk_enable(vpu_clk);
  189208. + }
  189209. + }
  189210. +
  189211. + mutex_unlock(&vpu_data.lock);
  189212. + return 0;
  189213. +}
  189214. +
  189215. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  189216. +static int vpu_runtime_suspend(struct device *dev)
  189217. +{
  189218. + release_bus_freq(BUS_FREQ_HIGH);
  189219. + return 0;
  189220. +}
  189221. +
  189222. +static int vpu_runtime_resume(struct device *dev)
  189223. +{
  189224. + request_bus_freq(BUS_FREQ_HIGH);
  189225. + return 0;
  189226. +}
  189227. +
  189228. +static const struct dev_pm_ops vpu_pm_ops = {
  189229. + SET_RUNTIME_PM_OPS(vpu_runtime_suspend, vpu_runtime_resume, NULL)
  189230. + SET_SYSTEM_SLEEP_PM_OPS(vpu_suspend, vpu_resume)
  189231. +};
  189232. +#endif
  189233. +
  189234. +#else
  189235. +#define vpu_suspend NULL
  189236. +#define vpu_resume NULL
  189237. +#endif /* !CONFIG_PM */
  189238. +
  189239. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  189240. +static const struct of_device_id vpu_of_match[] = {
  189241. + { .compatible = "fsl,imx6-vpu", },
  189242. + {/* sentinel */}
  189243. +};
  189244. +MODULE_DEVICE_TABLE(of, vpu_of_match);
  189245. +#endif
  189246. +
  189247. +/*! Driver definition
  189248. + *
  189249. + */
  189250. +static struct platform_driver mxcvpu_driver = {
  189251. + .driver = {
  189252. + .name = "mxc_vpu",
  189253. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  189254. + .of_match_table = vpu_of_match,
  189255. +#ifdef CONFIG_PM
  189256. + .pm = &vpu_pm_ops,
  189257. +#endif
  189258. +#endif
  189259. + },
  189260. + .probe = vpu_dev_probe,
  189261. + .remove = vpu_dev_remove,
  189262. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189263. + .suspend = vpu_suspend,
  189264. + .resume = vpu_resume,
  189265. +#endif
  189266. +};
  189267. +
  189268. +static int __init vpu_init(void)
  189269. +{
  189270. + int ret = platform_driver_register(&mxcvpu_driver);
  189271. +
  189272. + init_waitqueue_head(&vpu_queue);
  189273. +
  189274. +
  189275. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189276. + memblock_analyze();
  189277. + top_address_DRAM = memblock_end_of_DRAM_with_reserved();
  189278. +#endif
  189279. +
  189280. + return ret;
  189281. +}
  189282. +
  189283. +static void __exit vpu_exit(void)
  189284. +{
  189285. + if (vpu_major > 0) {
  189286. + device_destroy(vpu_class, MKDEV(vpu_major, 0));
  189287. + class_destroy(vpu_class);
  189288. + unregister_chrdev(vpu_major, "mxc_vpu");
  189289. + vpu_major = 0;
  189290. + }
  189291. +
  189292. + vpu_free_dma_buffer(&bitwork_mem);
  189293. + vpu_free_dma_buffer(&pic_para_mem);
  189294. + vpu_free_dma_buffer(&user_data_mem);
  189295. +
  189296. + /* reset VPU state */
  189297. + vpu_power_up(true);
  189298. + clk_prepare(vpu_clk);
  189299. + clk_enable(vpu_clk);
  189300. + vpu_reset();
  189301. + clk_disable(vpu_clk);
  189302. + clk_unprepare(vpu_clk);
  189303. + vpu_power_up(false);
  189304. +
  189305. + clk_put(vpu_clk);
  189306. +
  189307. + platform_driver_unregister(&mxcvpu_driver);
  189308. + return;
  189309. +}
  189310. +
  189311. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  189312. +MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX/MXC");
  189313. +MODULE_LICENSE("GPL");
  189314. +
  189315. +module_init(vpu_init);
  189316. +module_exit(vpu_exit);
  189317. diff -Nur linux-3.14.15/drivers/net/bonding/bonding.h linux-linaro-stable-mx6/drivers/net/bonding/bonding.h
  189318. --- linux-3.14.15/drivers/net/bonding/bonding.h 2014-07-31 23:51:43.000000000 +0200
  189319. +++ linux-linaro-stable-mx6/drivers/net/bonding/bonding.h 2014-08-20 19:31:46.148869092 +0200
  189320. @@ -188,7 +188,8 @@
  189321. struct net_device *dev; /* first - useful for panic debug */
  189322. struct bonding *bond; /* our master */
  189323. int delay;
  189324. - unsigned long jiffies;
  189325. + /* all three in jiffies */
  189326. + unsigned long last_link_up;
  189327. unsigned long last_arp_rx;
  189328. unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS];
  189329. s8 link; /* one of BOND_LINK_XXXX */
  189330. diff -Nur linux-3.14.15/drivers/net/bonding/bond_main.c linux-linaro-stable-mx6/drivers/net/bonding/bond_main.c
  189331. --- linux-3.14.15/drivers/net/bonding/bond_main.c 2014-07-31 23:51:43.000000000 +0200
  189332. +++ linux-linaro-stable-mx6/drivers/net/bonding/bond_main.c 2014-08-20 19:31:46.148869092 +0200
  189333. @@ -798,7 +798,7 @@
  189334. return;
  189335. if (new_active) {
  189336. - new_active->jiffies = jiffies;
  189337. + new_active->last_link_up = jiffies;
  189338. if (new_active->link == BOND_LINK_BACK) {
  189339. if (USES_PRIMARY(bond->params.mode)) {
  189340. @@ -1457,7 +1457,7 @@
  189341. }
  189342. if (new_slave->link != BOND_LINK_DOWN)
  189343. - new_slave->jiffies = jiffies;
  189344. + new_slave->last_link_up = jiffies;
  189345. pr_debug("Initial state of slave_dev is BOND_LINK_%s\n",
  189346. new_slave->link == BOND_LINK_DOWN ? "DOWN" :
  189347. (new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
  189348. @@ -1908,7 +1908,7 @@
  189349. * recovered before downdelay expired
  189350. */
  189351. slave->link = BOND_LINK_UP;
  189352. - slave->jiffies = jiffies;
  189353. + slave->last_link_up = jiffies;
  189354. pr_info("%s: link status up again after %d ms for interface %s.\n",
  189355. bond->dev->name,
  189356. (bond->params.downdelay - slave->delay) *
  189357. @@ -1983,7 +1983,7 @@
  189358. case BOND_LINK_UP:
  189359. slave->link = BOND_LINK_UP;
  189360. - slave->jiffies = jiffies;
  189361. + slave->last_link_up = jiffies;
  189362. if (bond->params.mode == BOND_MODE_8023AD) {
  189363. /* prevent it from being the active one */
  189364. @@ -2268,6 +2268,7 @@
  189365. struct slave *slave)
  189366. {
  189367. struct arphdr *arp = (struct arphdr *)skb->data;
  189368. + struct slave *curr_active_slave;
  189369. unsigned char *arp_ptr;
  189370. __be32 sip, tip;
  189371. int alen;
  189372. @@ -2312,6 +2313,8 @@
  189373. bond->params.arp_validate, slave_do_arp_validate(bond, slave),
  189374. &sip, &tip);
  189375. + curr_active_slave = rcu_dereference(bond->curr_active_slave);
  189376. +
  189377. /*
  189378. * Backup slaves won't see the ARP reply, but do come through
  189379. * here for each ARP probe (so we swap the sip/tip to validate
  189380. @@ -2325,11 +2328,12 @@
  189381. * is done to avoid endless looping when we can't reach the
  189382. * arp_ip_target and fool ourselves with our own arp requests.
  189383. */
  189384. +
  189385. if (bond_is_active_slave(slave))
  189386. bond_validate_arp(bond, slave, sip, tip);
  189387. - else if (bond->curr_active_slave &&
  189388. - time_after(slave_last_rx(bond, bond->curr_active_slave),
  189389. - bond->curr_active_slave->jiffies))
  189390. + else if (curr_active_slave &&
  189391. + time_after(slave_last_rx(bond, curr_active_slave),
  189392. + curr_active_slave->last_link_up))
  189393. bond_validate_arp(bond, slave, tip, sip);
  189394. out_unlock:
  189395. @@ -2376,9 +2380,9 @@
  189396. oldcurrent = ACCESS_ONCE(bond->curr_active_slave);
  189397. /* see if any of the previous devices are up now (i.e. they have
  189398. * xmt and rcv traffic). the curr_active_slave does not come into
  189399. - * the picture unless it is null. also, slave->jiffies is not needed
  189400. - * here because we send an arp on each slave and give a slave as
  189401. - * long as it needs to get the tx/rx within the delta.
  189402. + * the picture unless it is null. also, slave->last_link_up is not
  189403. + * needed here because we send an arp on each slave and give a slave
  189404. + * as long as it needs to get the tx/rx within the delta.
  189405. * TODO: what about up/down delay in arp mode? it wasn't here before
  189406. * so it can wait
  189407. */
  189408. @@ -2505,7 +2509,7 @@
  189409. * active. This avoids bouncing, as the last receive
  189410. * times need a full ARP monitor cycle to be updated.
  189411. */
  189412. - if (bond_time_in_interval(bond, slave->jiffies, 2))
  189413. + if (bond_time_in_interval(bond, slave->last_link_up, 2))
  189414. continue;
  189415. /*
  189416. @@ -2698,7 +2702,7 @@
  189417. new_slave->link = BOND_LINK_BACK;
  189418. bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER);
  189419. bond_arp_send_all(bond, new_slave);
  189420. - new_slave->jiffies = jiffies;
  189421. + new_slave->last_link_up = jiffies;
  189422. rcu_assign_pointer(bond->current_arp_slave, new_slave);
  189423. check_state:
  189424. diff -Nur linux-3.14.15/drivers/net/can/flexcan.c linux-linaro-stable-mx6/drivers/net/can/flexcan.c
  189425. --- linux-3.14.15/drivers/net/can/flexcan.c 2014-07-31 23:51:43.000000000 +0200
  189426. +++ linux-linaro-stable-mx6/drivers/net/can/flexcan.c 2014-08-20 19:31:46.152869109 +0200
  189427. @@ -125,7 +125,8 @@
  189428. FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)
  189429. /* FLEXCAN interrupt flag register (IFLAG) bits */
  189430. -#define FLEXCAN_TX_BUF_ID 8
  189431. +#define FLEXCAN_RESERVED_BUF_ID 8
  189432. +#define FLEXCAN_TX_BUF_ID 13
  189433. #define FLEXCAN_IFLAG_BUF(x) BIT(x)
  189434. #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
  189435. #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
  189436. @@ -162,6 +163,7 @@
  189437. */
  189438. #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
  189439. #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */
  189440. +#define FLEXCAN_HAS_ERR005829 BIT(3) /* have errata ERR005829 */
  189441. /* Structure of the message buffer */
  189442. struct flexcan_mb {
  189443. @@ -221,7 +223,7 @@
  189444. };
  189445. static struct flexcan_devtype_data fsl_imx28_devtype_data;
  189446. static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
  189447. - .features = FLEXCAN_HAS_V10_FEATURES,
  189448. + .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_ERR005829,
  189449. };
  189450. static const struct can_bittiming_const flexcan_bittiming_const = {
  189451. @@ -428,6 +430,11 @@
  189452. flexcan_write(can_id, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
  189453. flexcan_write(ctrl, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
  189454. + if (priv->devtype_data->features & FLEXCAN_HAS_ERR005829) {
  189455. + writel(0x0, &regs->cantxfg[FLEXCAN_RESERVED_BUF_ID].can_ctrl);
  189456. + writel(0x0, &regs->cantxfg[FLEXCAN_RESERVED_BUF_ID].can_ctrl);
  189457. + }
  189458. +
  189459. return NETDEV_TX_OK;
  189460. }
  189461. diff -Nur linux-3.14.15/drivers/net/ethernet/adi/bfin_mac.c linux-linaro-stable-mx6/drivers/net/ethernet/adi/bfin_mac.c
  189462. --- linux-3.14.15/drivers/net/ethernet/adi/bfin_mac.c 2014-07-31 23:51:43.000000000 +0200
  189463. +++ linux-linaro-stable-mx6/drivers/net/ethernet/adi/bfin_mac.c 2014-08-20 19:31:46.168869177 +0200
  189464. @@ -1040,6 +1040,7 @@
  189465. .n_alarm = 0,
  189466. .n_ext_ts = 0,
  189467. .n_per_out = 0,
  189468. + .n_pins = 0,
  189469. .pps = 0,
  189470. .adjfreq = bfin_ptp_adjfreq,
  189471. .adjtime = bfin_ptp_adjtime,
  189472. diff -Nur linux-3.14.15/drivers/net/ethernet/broadcom/tg3.c linux-linaro-stable-mx6/drivers/net/ethernet/broadcom/tg3.c
  189473. --- linux-3.14.15/drivers/net/ethernet/broadcom/tg3.c 2014-07-31 23:51:43.000000000 +0200
  189474. +++ linux-linaro-stable-mx6/drivers/net/ethernet/broadcom/tg3.c 2014-08-20 19:31:46.220869402 +0200
  189475. @@ -6322,6 +6322,7 @@
  189476. .n_alarm = 0,
  189477. .n_ext_ts = 0,
  189478. .n_per_out = 1,
  189479. + .n_pins = 0,
  189480. .pps = 0,
  189481. .adjfreq = tg3_ptp_adjfreq,
  189482. .adjtime = tg3_ptp_adjtime,
  189483. diff -Nur linux-3.14.15/drivers/net/ethernet/cadence/macb.c linux-linaro-stable-mx6/drivers/net/ethernet/cadence/macb.c
  189484. --- linux-3.14.15/drivers/net/ethernet/cadence/macb.c 2014-07-31 23:51:43.000000000 +0200
  189485. +++ linux-linaro-stable-mx6/drivers/net/ethernet/cadence/macb.c 2014-08-20 19:31:46.224869419 +0200
  189486. @@ -605,25 +605,16 @@
  189487. {
  189488. unsigned int entry;
  189489. struct sk_buff *skb;
  189490. - struct macb_dma_desc *desc;
  189491. dma_addr_t paddr;
  189492. while (CIRC_SPACE(bp->rx_prepared_head, bp->rx_tail, RX_RING_SIZE) > 0) {
  189493. - u32 addr, ctrl;
  189494. -
  189495. entry = macb_rx_ring_wrap(bp->rx_prepared_head);
  189496. - desc = &bp->rx_ring[entry];
  189497. /* Make hw descriptor updates visible to CPU */
  189498. rmb();
  189499. - addr = desc->addr;
  189500. - ctrl = desc->ctrl;
  189501. bp->rx_prepared_head++;
  189502. - if ((addr & MACB_BIT(RX_USED)))
  189503. - continue;
  189504. -
  189505. if (bp->rx_skbuff[entry] == NULL) {
  189506. /* allocate sk_buff for this free entry in ring */
  189507. skb = netdev_alloc_skb(bp->dev, bp->rx_buffer_size);
  189508. @@ -704,7 +695,6 @@
  189509. if (!(addr & MACB_BIT(RX_USED)))
  189510. break;
  189511. - desc->addr &= ~MACB_BIT(RX_USED);
  189512. bp->rx_tail++;
  189513. count++;
  189514. diff -Nur linux-3.14.15/drivers/net/ethernet/chelsio/cxgb4vf/sge.c linux-linaro-stable-mx6/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
  189515. --- linux-3.14.15/drivers/net/ethernet/chelsio/cxgb4vf/sge.c 2014-07-31 23:51:43.000000000 +0200
  189516. +++ linux-linaro-stable-mx6/drivers/net/ethernet/chelsio/cxgb4vf/sge.c 2014-08-20 19:31:46.240869487 +0200
  189517. @@ -1510,7 +1510,8 @@
  189518. {
  189519. struct sk_buff *skb;
  189520. const struct cpl_rx_pkt *pkt = (void *)rsp;
  189521. - bool csum_ok = pkt->csum_calc && !pkt->err_vec;
  189522. + bool csum_ok = pkt->csum_calc && !pkt->err_vec &&
  189523. + (rspq->netdev->features & NETIF_F_RXCSUM);
  189524. struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq);
  189525. /*
  189526. @@ -1538,8 +1539,8 @@
  189527. skb_record_rx_queue(skb, rspq->idx);
  189528. rxq->stats.pkts++;
  189529. - if (csum_ok && (rspq->netdev->features & NETIF_F_RXCSUM) &&
  189530. - !pkt->err_vec && (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
  189531. + if (csum_ok && !pkt->err_vec &&
  189532. + (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
  189533. if (!pkt->ip_frag)
  189534. skb->ip_summed = CHECKSUM_UNNECESSARY;
  189535. else {
  189536. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/fec.h linux-linaro-stable-mx6/drivers/net/ethernet/freescale/fec.h
  189537. --- linux-3.14.15/drivers/net/ethernet/freescale/fec.h 2014-07-31 23:51:43.000000000 +0200
  189538. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/fec.h 2014-08-20 19:31:46.364870019 +0200
  189539. @@ -221,7 +221,7 @@
  189540. #define BD_ENET_TX_RCMASK ((ushort)0x003c)
  189541. #define BD_ENET_TX_UN ((ushort)0x0002)
  189542. #define BD_ENET_TX_CSL ((ushort)0x0001)
  189543. -#define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */
  189544. +#define BD_ENET_TX_STATS ((ushort)0x0fff) /* All status bits */
  189545. /*enhanced buffer descriptor control/status used by Ethernet transmit*/
  189546. #define BD_ENET_TX_INT 0x40000000
  189547. @@ -246,8 +246,8 @@
  189548. #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
  189549. #define FEC_ENET_TX_FRSIZE 2048
  189550. #define FEC_ENET_TX_FRPPG (PAGE_SIZE / FEC_ENET_TX_FRSIZE)
  189551. -#define TX_RING_SIZE 16 /* Must be power of two */
  189552. -#define TX_RING_MOD_MASK 15 /* for this to work */
  189553. +#define TX_RING_SIZE 512 /* Must be power of two */
  189554. +#define TX_RING_MOD_MASK 511 /* for this to work */
  189555. #define BD_ENET_RX_INT 0x00800000
  189556. #define BD_ENET_RX_PTP ((ushort)0x0400)
  189557. @@ -256,12 +256,6 @@
  189558. #define FLAG_RX_CSUM_ENABLED (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
  189559. #define FLAG_RX_CSUM_ERROR (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
  189560. -struct fec_enet_delayed_work {
  189561. - struct delayed_work delay_work;
  189562. - bool timeout;
  189563. - bool trig_tx;
  189564. -};
  189565. -
  189566. /* The FEC buffer descriptors track the ring buffers. The rx_bd_base and
  189567. * tx_bd_base always point to the base of the buffer descriptors. The
  189568. * cur_rx and cur_tx point to the currently available buffer.
  189569. @@ -296,12 +290,18 @@
  189570. /* The ring entries to be free()ed */
  189571. struct bufdesc *dirty_tx;
  189572. + unsigned short bufdesc_size;
  189573. unsigned short tx_ring_size;
  189574. unsigned short rx_ring_size;
  189575. + unsigned short tx_stop_threshold;
  189576. + unsigned short tx_wake_threshold;
  189577. +
  189578. + /* Software TSO */
  189579. + char *tso_hdrs;
  189580. + dma_addr_t tso_hdrs_dma;
  189581. struct platform_device *pdev;
  189582. - int opened;
  189583. int dev_id;
  189584. /* Phylib and MDIO interface */
  189585. @@ -321,6 +321,8 @@
  189586. struct napi_struct napi;
  189587. int csum_flags;
  189588. + struct work_struct tx_timeout_work;
  189589. +
  189590. struct ptp_clock *ptp_clock;
  189591. struct ptp_clock_info ptp_caps;
  189592. unsigned long last_overflow_check;
  189593. @@ -333,7 +335,6 @@
  189594. int hwts_rx_en;
  189595. int hwts_tx_en;
  189596. struct timer_list time_keep;
  189597. - struct fec_enet_delayed_work delay_work;
  189598. struct regulator *reg_phy;
  189599. };
  189600. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/fec_main.c linux-linaro-stable-mx6/drivers/net/ethernet/freescale/fec_main.c
  189601. --- linux-3.14.15/drivers/net/ethernet/freescale/fec_main.c 2014-07-31 23:51:43.000000000 +0200
  189602. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/fec_main.c 2014-08-20 19:31:46.364870019 +0200
  189603. @@ -36,6 +36,7 @@
  189604. #include <linux/in.h>
  189605. #include <linux/ip.h>
  189606. #include <net/ip.h>
  189607. +#include <net/tso.h>
  189608. #include <linux/tcp.h>
  189609. #include <linux/udp.h>
  189610. #include <linux/icmp.h>
  189611. @@ -54,6 +55,10 @@
  189612. #include <linux/of_net.h>
  189613. #include <linux/regulator/consumer.h>
  189614. #include <linux/if_vlan.h>
  189615. +#include <linux/pinctrl/consumer.h>
  189616. +#include <linux/busfreq-imx6.h>
  189617. +#include <linux/pm_runtime.h>
  189618. +#include <linux/pm_qos.h>
  189619. #include <asm/cacheflush.h>
  189620. @@ -91,6 +96,8 @@
  189621. #define FEC_QUIRK_HAS_CSUM (1 << 5)
  189622. /* Controller has hardware vlan support */
  189623. #define FEC_QUIRK_HAS_VLAN (1 << 6)
  189624. +/* Controller is FEC-MAC */
  189625. +#define FEC_QUIRK_FEC_MAC (1 << 7)
  189626. /* ENET IP errata ERR006358
  189627. *
  189628. * If the ready bit in the transmit buffer descriptor (TxBD[R]) is previously
  189629. @@ -100,7 +107,13 @@
  189630. * frames not being transmitted until there is a 0-to-1 transition on
  189631. * ENET_TDAR[TDAR].
  189632. */
  189633. -#define FEC_QUIRK_ERR006358 (1 << 7)
  189634. +#define FEC_QUIRK_ERR006358 (1 << 8)
  189635. +/*
  189636. + * i.MX6Q/DL ENET cannot wake up system in wait mode because ENET tx & rx
  189637. + * interrupt signal don't connect to GPC. So use pm qos to avoid cpu enter
  189638. + * to wait mode.
  189639. + */
  189640. +#define FEC_QUIRK_BUG_WAITMODE (1 << 9)
  189641. static struct platform_device_id fec_devtype[] = {
  189642. {
  189643. @@ -109,7 +122,7 @@
  189644. .driver_data = 0,
  189645. }, {
  189646. .name = "imx25-fec",
  189647. - .driver_data = FEC_QUIRK_USE_GASKET,
  189648. + .driver_data = FEC_QUIRK_USE_GASKET | FEC_QUIRK_FEC_MAC,
  189649. }, {
  189650. .name = "imx27-fec",
  189651. .driver_data = 0,
  189652. @@ -120,7 +133,8 @@
  189653. .name = "imx6q-fec",
  189654. .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
  189655. FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
  189656. - FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358,
  189657. + FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
  189658. + FEC_QUIRK_BUG_WAITMODE,
  189659. }, {
  189660. .name = "mvf600-fec",
  189661. .driver_data = FEC_QUIRK_ENET_MAC,
  189662. @@ -172,10 +186,6 @@
  189663. #endif
  189664. #endif /* CONFIG_M5272 */
  189665. -#if (((RX_RING_SIZE + TX_RING_SIZE) * 32) > PAGE_SIZE)
  189666. -#error "FEC: descriptor ring size constants too large"
  189667. -#endif
  189668. -
  189669. /* Interrupt events/masks. */
  189670. #define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
  189671. #define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
  189672. @@ -231,6 +241,15 @@
  189673. #define FEC_PAUSE_FLAG_AUTONEG 0x1
  189674. #define FEC_PAUSE_FLAG_ENABLE 0x2
  189675. +#define TSO_HEADER_SIZE 128
  189676. +/* Max number of allowed TCP segments for software TSO */
  189677. +#define FEC_MAX_TSO_SEGS 100
  189678. +#define FEC_MAX_SKB_DESCS (FEC_MAX_TSO_SEGS * 2 + MAX_SKB_FRAGS)
  189679. +
  189680. +#define IS_TSO_HEADER(txq, addr) \
  189681. + ((addr >= txq->tso_hdrs_dma) && \
  189682. + (addr < txq->tso_hdrs_dma + txq->tx_ring_size * TSO_HEADER_SIZE))
  189683. +
  189684. static int mii_cnt;
  189685. static inline
  189686. @@ -286,6 +305,22 @@
  189687. return (new_bd < base) ? (new_bd + ring_size) : new_bd;
  189688. }
  189689. +static int fec_enet_get_bd_index(struct bufdesc *base, struct bufdesc *bdp,
  189690. + struct fec_enet_private *fep)
  189691. +{
  189692. + return ((const char *)bdp - (const char *)base) / fep->bufdesc_size;
  189693. +}
  189694. +
  189695. +static int fec_enet_get_free_txdesc_num(struct fec_enet_private *fep)
  189696. +{
  189697. + int entries;
  189698. +
  189699. + entries = ((const char *)fep->dirty_tx -
  189700. + (const char *)fep->cur_tx) / fep->bufdesc_size - 1;
  189701. +
  189702. + return entries > 0 ? entries : entries + fep->tx_ring_size;
  189703. +}
  189704. +
  189705. static void *swap_buffer(void *bufaddr, int len)
  189706. {
  189707. int i;
  189708. @@ -297,6 +332,32 @@
  189709. return bufaddr;
  189710. }
  189711. +static void fec_dump(struct net_device *ndev)
  189712. +{
  189713. + struct fec_enet_private *fep = netdev_priv(ndev);
  189714. + struct bufdesc *bdp = fep->tx_bd_base;
  189715. + unsigned int index = 0;
  189716. +
  189717. + netdev_info(ndev, "TX ring dump\n");
  189718. + pr_info("Nr SC addr len SKB\n");
  189719. +
  189720. + do {
  189721. + pr_info("%3u %c%c 0x%04x 0x%08lx %4u %p\n",
  189722. + index,
  189723. + bdp == fep->cur_tx ? 'S' : ' ',
  189724. + bdp == fep->dirty_tx ? 'H' : ' ',
  189725. + bdp->cbd_sc, bdp->cbd_bufaddr, bdp->cbd_datlen,
  189726. + fep->tx_skbuff[index]);
  189727. + bdp = fec_enet_get_nextdesc(bdp, fep);
  189728. + index++;
  189729. + } while (bdp != fep->tx_bd_base);
  189730. +}
  189731. +
  189732. +static inline bool is_ipv4_pkt(struct sk_buff *skb)
  189733. +{
  189734. + return skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->version == 4;
  189735. +}
  189736. +
  189737. static int
  189738. fec_enet_clear_csum(struct sk_buff *skb, struct net_device *ndev)
  189739. {
  189740. @@ -307,137 +368,419 @@
  189741. if (unlikely(skb_cow_head(skb, 0)))
  189742. return -1;
  189743. + if (is_ipv4_pkt(skb))
  189744. + ip_hdr(skb)->check = 0;
  189745. *(__sum16 *)(skb->head + skb->csum_start + skb->csum_offset) = 0;
  189746. return 0;
  189747. }
  189748. -static netdev_tx_t
  189749. -fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
  189750. +static int
  189751. +fec_enet_txq_submit_frag_skb(struct sk_buff *skb, struct net_device *ndev)
  189752. {
  189753. struct fec_enet_private *fep = netdev_priv(ndev);
  189754. const struct platform_device_id *id_entry =
  189755. platform_get_device_id(fep->pdev);
  189756. - struct bufdesc *bdp, *bdp_pre;
  189757. - void *bufaddr;
  189758. - unsigned short status;
  189759. + struct bufdesc *bdp = fep->cur_tx;
  189760. + struct bufdesc_ex *ebdp;
  189761. + int nr_frags = skb_shinfo(skb)->nr_frags;
  189762. + int frag, frag_len;
  189763. + unsigned short status;
  189764. + unsigned int estatus = 0;
  189765. + skb_frag_t *this_frag;
  189766. unsigned int index;
  189767. + void *bufaddr;
  189768. + dma_addr_t addr;
  189769. + int i;
  189770. - /* Fill in a Tx ring entry */
  189771. + for (frag = 0; frag < nr_frags; frag++) {
  189772. + this_frag = &skb_shinfo(skb)->frags[frag];
  189773. + bdp = fec_enet_get_nextdesc(bdp, fep);
  189774. + ebdp = (struct bufdesc_ex *)bdp;
  189775. +
  189776. + status = bdp->cbd_sc;
  189777. + status &= ~BD_ENET_TX_STATS;
  189778. + status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
  189779. + frag_len = skb_shinfo(skb)->frags[frag].size;
  189780. +
  189781. + /* Handle the last BD specially */
  189782. + if (frag == nr_frags - 1) {
  189783. + status |= (BD_ENET_TX_INTR | BD_ENET_TX_LAST);
  189784. + if (fep->bufdesc_ex) {
  189785. + estatus |= BD_ENET_TX_INT;
  189786. + if (unlikely(skb_shinfo(skb)->tx_flags &
  189787. + SKBTX_HW_TSTAMP && fep->hwts_tx_en))
  189788. + estatus |= BD_ENET_TX_TS;
  189789. + }
  189790. + }
  189791. +
  189792. + if (fep->bufdesc_ex) {
  189793. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  189794. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  189795. + ebdp->cbd_bdu = 0;
  189796. + ebdp->cbd_esc = estatus;
  189797. + }
  189798. +
  189799. + bufaddr = page_address(this_frag->page.p) + this_frag->page_offset;
  189800. +
  189801. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  189802. + if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
  189803. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  189804. + memcpy(fep->tx_bounce[index], bufaddr, frag_len);
  189805. + bufaddr = fep->tx_bounce[index];
  189806. +
  189807. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  189808. + swap_buffer(bufaddr, frag_len);
  189809. + }
  189810. +
  189811. + addr = dma_map_single(&fep->pdev->dev, bufaddr, frag_len,
  189812. + DMA_TO_DEVICE);
  189813. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  189814. + dev_kfree_skb_any(skb);
  189815. + if (net_ratelimit())
  189816. + netdev_err(ndev, "Tx DMA memory map failed\n");
  189817. + goto dma_mapping_error;
  189818. + }
  189819. +
  189820. + bdp->cbd_bufaddr = addr;
  189821. + bdp->cbd_datlen = frag_len;
  189822. + bdp->cbd_sc = status;
  189823. + }
  189824. +
  189825. + fep->cur_tx = bdp;
  189826. +
  189827. + return 0;
  189828. +
  189829. +dma_mapping_error:
  189830. bdp = fep->cur_tx;
  189831. + for (i = 0; i < frag; i++) {
  189832. + bdp = fec_enet_get_nextdesc(bdp, fep);
  189833. + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
  189834. + bdp->cbd_datlen, DMA_TO_DEVICE);
  189835. + }
  189836. + return NETDEV_TX_OK;
  189837. +}
  189838. - status = bdp->cbd_sc;
  189839. +static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
  189840. +{
  189841. + struct fec_enet_private *fep = netdev_priv(ndev);
  189842. + const struct platform_device_id *id_entry =
  189843. + platform_get_device_id(fep->pdev);
  189844. + int nr_frags = skb_shinfo(skb)->nr_frags;
  189845. + struct bufdesc *bdp, *last_bdp;
  189846. + void *bufaddr;
  189847. + dma_addr_t addr;
  189848. + unsigned short status;
  189849. + unsigned short buflen;
  189850. + unsigned int estatus = 0;
  189851. + unsigned int index;
  189852. + int entries_free;
  189853. + int ret;
  189854. - if (status & BD_ENET_TX_READY) {
  189855. - /* Ooops. All transmit buffers are full. Bail out.
  189856. - * This should not happen, since ndev->tbusy should be set.
  189857. - */
  189858. - netdev_err(ndev, "tx queue full!\n");
  189859. - return NETDEV_TX_BUSY;
  189860. + entries_free = fec_enet_get_free_txdesc_num(fep);
  189861. + if (entries_free < MAX_SKB_FRAGS + 1) {
  189862. + dev_kfree_skb_any(skb);
  189863. + if (net_ratelimit())
  189864. + netdev_err(ndev, "NOT enough BD for SG!\n");
  189865. + return NETDEV_TX_OK;
  189866. }
  189867. /* Protocol checksum off-load for TCP and UDP. */
  189868. if (fec_enet_clear_csum(skb, ndev)) {
  189869. - kfree_skb(skb);
  189870. + dev_kfree_skb_any(skb);
  189871. return NETDEV_TX_OK;
  189872. }
  189873. - /* Clear all of the status flags */
  189874. + /* Fill in a Tx ring entry */
  189875. + bdp = fep->cur_tx;
  189876. + status = bdp->cbd_sc;
  189877. status &= ~BD_ENET_TX_STATS;
  189878. /* Set buffer length and buffer pointer */
  189879. bufaddr = skb->data;
  189880. - bdp->cbd_datlen = skb->len;
  189881. + buflen = skb_headlen(skb);
  189882. - /*
  189883. - * On some FEC implementations data must be aligned on
  189884. - * 4-byte boundaries. Use bounce buffers to copy data
  189885. - * and get it aligned. Ugh.
  189886. - */
  189887. - if (fep->bufdesc_ex)
  189888. - index = (struct bufdesc_ex *)bdp -
  189889. - (struct bufdesc_ex *)fep->tx_bd_base;
  189890. - else
  189891. - index = bdp - fep->tx_bd_base;
  189892. -
  189893. - if (((unsigned long) bufaddr) & FEC_ALIGNMENT) {
  189894. - memcpy(fep->tx_bounce[index], skb->data, skb->len);
  189895. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  189896. + if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
  189897. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  189898. + memcpy(fep->tx_bounce[index], skb->data, buflen);
  189899. bufaddr = fep->tx_bounce[index];
  189900. - }
  189901. - /*
  189902. - * Some design made an incorrect assumption on endian mode of
  189903. - * the system that it's running on. As the result, driver has to
  189904. - * swap every frame going to and coming from the controller.
  189905. - */
  189906. - if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  189907. - swap_buffer(bufaddr, skb->len);
  189908. -
  189909. - /* Save skb pointer */
  189910. - fep->tx_skbuff[index] = skb;
  189911. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  189912. + swap_buffer(bufaddr, buflen);
  189913. + }
  189914. - /* Push the data cache so the CPM does not get stale memory
  189915. - * data.
  189916. - */
  189917. - bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, bufaddr,
  189918. - skb->len, DMA_TO_DEVICE);
  189919. - if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
  189920. - bdp->cbd_bufaddr = 0;
  189921. - fep->tx_skbuff[index] = NULL;
  189922. + /* Push the data cache so the CPM does not get stale memory data. */
  189923. + addr = dma_map_single(&fep->pdev->dev, bufaddr, buflen, DMA_TO_DEVICE);
  189924. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  189925. dev_kfree_skb_any(skb);
  189926. if (net_ratelimit())
  189927. netdev_err(ndev, "Tx DMA memory map failed\n");
  189928. return NETDEV_TX_OK;
  189929. }
  189930. + if (nr_frags) {
  189931. + ret = fec_enet_txq_submit_frag_skb(skb, ndev);
  189932. + if (ret)
  189933. + return ret;
  189934. + } else {
  189935. + status |= (BD_ENET_TX_INTR | BD_ENET_TX_LAST);
  189936. + if (fep->bufdesc_ex) {
  189937. + estatus = BD_ENET_TX_INT;
  189938. + if (unlikely(skb_shinfo(skb)->tx_flags &
  189939. + SKBTX_HW_TSTAMP && fep->hwts_tx_en))
  189940. + estatus |= BD_ENET_TX_TS;
  189941. + }
  189942. + }
  189943. +
  189944. if (fep->bufdesc_ex) {
  189945. struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  189946. - ebdp->cbd_bdu = 0;
  189947. +
  189948. if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
  189949. - fep->hwts_tx_en)) {
  189950. - ebdp->cbd_esc = (BD_ENET_TX_TS | BD_ENET_TX_INT);
  189951. + fep->hwts_tx_en))
  189952. skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
  189953. - } else {
  189954. - ebdp->cbd_esc = BD_ENET_TX_INT;
  189955. - /* Enable protocol checksum flags
  189956. - * We do not bother with the IP Checksum bits as they
  189957. - * are done by the kernel
  189958. - */
  189959. - if (skb->ip_summed == CHECKSUM_PARTIAL)
  189960. - ebdp->cbd_esc |= BD_ENET_TX_PINS;
  189961. - }
  189962. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  189963. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  189964. +
  189965. + ebdp->cbd_bdu = 0;
  189966. + ebdp->cbd_esc = estatus;
  189967. }
  189968. + last_bdp = fep->cur_tx;
  189969. + index = fec_enet_get_bd_index(fep->tx_bd_base, last_bdp, fep);
  189970. + /* Save skb pointer */
  189971. + fep->tx_skbuff[index] = skb;
  189972. +
  189973. + bdp->cbd_datlen = buflen;
  189974. + bdp->cbd_bufaddr = addr;
  189975. +
  189976. /* Send it on its way. Tell FEC it's ready, interrupt when done,
  189977. * it's the last BD of the frame, and to put the CRC on the end.
  189978. */
  189979. - status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
  189980. - | BD_ENET_TX_LAST | BD_ENET_TX_TC);
  189981. + status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
  189982. bdp->cbd_sc = status;
  189983. - bdp_pre = fec_enet_get_prevdesc(bdp, fep);
  189984. - if ((id_entry->driver_data & FEC_QUIRK_ERR006358) &&
  189985. - !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) {
  189986. - fep->delay_work.trig_tx = true;
  189987. - schedule_delayed_work(&(fep->delay_work.delay_work),
  189988. - msecs_to_jiffies(1));
  189989. - }
  189990. -
  189991. /* If this was the last BD in the ring, start at the beginning again. */
  189992. - bdp = fec_enet_get_nextdesc(bdp, fep);
  189993. + bdp = fec_enet_get_nextdesc(last_bdp, fep);
  189994. skb_tx_timestamp(skb);
  189995. fep->cur_tx = bdp;
  189996. - if (fep->cur_tx == fep->dirty_tx)
  189997. - netif_stop_queue(ndev);
  189998. + /* Trigger transmission start */
  189999. + writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  190000. +
  190001. + return 0;
  190002. +}
  190003. +
  190004. +static int
  190005. +fec_enet_txq_put_data_tso(struct sk_buff *skb, struct net_device *ndev,
  190006. + struct bufdesc *bdp, int index, char *data,
  190007. + int size, bool last_tcp, bool is_last)
  190008. +{
  190009. + struct fec_enet_private *fep = netdev_priv(ndev);
  190010. + const struct platform_device_id *id_entry =
  190011. + platform_get_device_id(fep->pdev);
  190012. + struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  190013. + unsigned short status;
  190014. + unsigned int estatus = 0;
  190015. + dma_addr_t addr;
  190016. +
  190017. + status = bdp->cbd_sc;
  190018. + status &= ~BD_ENET_TX_STATS;
  190019. +
  190020. + status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
  190021. +
  190022. + if (((unsigned long) data) & FEC_ALIGNMENT ||
  190023. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  190024. + memcpy(fep->tx_bounce[index], data, size);
  190025. + data = fep->tx_bounce[index];
  190026. +
  190027. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  190028. + swap_buffer(data, size);
  190029. + }
  190030. +
  190031. + addr = dma_map_single(&fep->pdev->dev, data, size, DMA_TO_DEVICE);
  190032. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  190033. + dev_kfree_skb_any(skb);
  190034. + if (net_ratelimit())
  190035. + netdev_err(ndev, "Tx DMA memory map failed\n");
  190036. + return NETDEV_TX_BUSY;
  190037. + }
  190038. +
  190039. + bdp->cbd_datlen = size;
  190040. + bdp->cbd_bufaddr = addr;
  190041. +
  190042. + if (fep->bufdesc_ex) {
  190043. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  190044. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  190045. + ebdp->cbd_bdu = 0;
  190046. + ebdp->cbd_esc = estatus;
  190047. + }
  190048. +
  190049. + /* Handle the last BD specially */
  190050. + if (last_tcp)
  190051. + status |= (BD_ENET_TX_LAST | BD_ENET_TX_TC);
  190052. + if (is_last) {
  190053. + status |= BD_ENET_TX_INTR;
  190054. + if (fep->bufdesc_ex)
  190055. + ebdp->cbd_esc |= BD_ENET_TX_INT;
  190056. + }
  190057. +
  190058. + bdp->cbd_sc = status;
  190059. +
  190060. + return 0;
  190061. +}
  190062. +
  190063. +static int
  190064. +fec_enet_txq_put_hdr_tso(struct sk_buff *skb, struct net_device *ndev,
  190065. + struct bufdesc *bdp, int index)
  190066. +{
  190067. + struct fec_enet_private *fep = netdev_priv(ndev);
  190068. + const struct platform_device_id *id_entry =
  190069. + platform_get_device_id(fep->pdev);
  190070. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  190071. + struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  190072. + void *bufaddr;
  190073. + unsigned long dmabuf;
  190074. + unsigned short status;
  190075. + unsigned int estatus = 0;
  190076. +
  190077. + status = bdp->cbd_sc;
  190078. + status &= ~BD_ENET_TX_STATS;
  190079. + status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
  190080. +
  190081. + bufaddr = fep->tso_hdrs + index * TSO_HEADER_SIZE;
  190082. + dmabuf = fep->tso_hdrs_dma + index * TSO_HEADER_SIZE;
  190083. + if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
  190084. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  190085. + memcpy(fep->tx_bounce[index], skb->data, hdr_len);
  190086. + bufaddr = fep->tx_bounce[index];
  190087. +
  190088. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  190089. + swap_buffer(bufaddr, hdr_len);
  190090. +
  190091. + dmabuf = dma_map_single(&fep->pdev->dev, bufaddr,
  190092. + hdr_len, DMA_TO_DEVICE);
  190093. + if (dma_mapping_error(&fep->pdev->dev, dmabuf)) {
  190094. + dev_kfree_skb_any(skb);
  190095. + if (net_ratelimit())
  190096. + netdev_err(ndev, "Tx DMA memory map failed\n");
  190097. + return NETDEV_TX_BUSY;
  190098. + }
  190099. + }
  190100. +
  190101. + bdp->cbd_bufaddr = dmabuf;
  190102. + bdp->cbd_datlen = hdr_len;
  190103. +
  190104. + if (fep->bufdesc_ex) {
  190105. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  190106. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  190107. + ebdp->cbd_bdu = 0;
  190108. + ebdp->cbd_esc = estatus;
  190109. + }
  190110. +
  190111. + bdp->cbd_sc = status;
  190112. +
  190113. + return 0;
  190114. +}
  190115. +
  190116. +static int fec_enet_txq_submit_tso(struct sk_buff *skb, struct net_device *ndev)
  190117. +{
  190118. + struct fec_enet_private *fep = netdev_priv(ndev);
  190119. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  190120. + int total_len, data_left;
  190121. + struct bufdesc *bdp = fep->cur_tx;
  190122. + struct tso_t tso;
  190123. + unsigned int index = 0;
  190124. + int ret;
  190125. +
  190126. + if (tso_count_descs(skb) >= fec_enet_get_free_txdesc_num(fep)) {
  190127. + dev_kfree_skb_any(skb);
  190128. + if (net_ratelimit())
  190129. + netdev_err(ndev, "NOT enough BD for TSO!\n");
  190130. + return NETDEV_TX_OK;
  190131. + }
  190132. +
  190133. + /* Protocol checksum off-load for TCP and UDP. */
  190134. + if (fec_enet_clear_csum(skb, ndev)) {
  190135. + dev_kfree_skb_any(skb);
  190136. + return NETDEV_TX_OK;
  190137. + }
  190138. +
  190139. + /* Initialize the TSO handler, and prepare the first payload */
  190140. + tso_start(skb, &tso);
  190141. +
  190142. + total_len = skb->len - hdr_len;
  190143. + while (total_len > 0) {
  190144. + char *hdr;
  190145. +
  190146. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  190147. + data_left = min_t(int, skb_shinfo(skb)->gso_size, total_len);
  190148. + total_len -= data_left;
  190149. +
  190150. + /* prepare packet headers: MAC + IP + TCP */
  190151. + hdr = fep->tso_hdrs + index * TSO_HEADER_SIZE;
  190152. + tso_build_hdr(skb, hdr, &tso, data_left, total_len == 0);
  190153. + ret = fec_enet_txq_put_hdr_tso(skb, ndev, bdp, index);
  190154. + if (ret)
  190155. + goto err_release;
  190156. +
  190157. + while (data_left > 0) {
  190158. + int size;
  190159. +
  190160. + size = min_t(int, tso.size, data_left);
  190161. + bdp = fec_enet_get_nextdesc(bdp, fep);
  190162. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  190163. + ret = fec_enet_txq_put_data_tso(skb, ndev, bdp, index, tso.data,
  190164. + size, size == data_left,
  190165. + total_len == 0);
  190166. + if (ret)
  190167. + goto err_release;
  190168. +
  190169. + data_left -= size;
  190170. + tso_build_data(skb, &tso, size);
  190171. + }
  190172. +
  190173. + bdp = fec_enet_get_nextdesc(bdp, fep);
  190174. + }
  190175. +
  190176. + /* Save skb pointer */
  190177. + fep->tx_skbuff[index] = skb;
  190178. +
  190179. + skb_tx_timestamp(skb);
  190180. + fep->cur_tx = bdp;
  190181. /* Trigger transmission start */
  190182. writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  190183. + return 0;
  190184. +
  190185. +err_release:
  190186. + /* TODO: Release all used data descriptors for TSO */
  190187. + return ret;
  190188. +}
  190189. +
  190190. +static netdev_tx_t
  190191. +fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
  190192. +{
  190193. + struct fec_enet_private *fep = netdev_priv(ndev);
  190194. + int entries_free;
  190195. + int ret;
  190196. +
  190197. + if (skb_is_gso(skb))
  190198. + ret = fec_enet_txq_submit_tso(skb, ndev);
  190199. + else
  190200. + ret = fec_enet_txq_submit_skb(skb, ndev);
  190201. + if (ret)
  190202. + return ret;
  190203. +
  190204. + entries_free = fec_enet_get_free_txdesc_num(fep);
  190205. + if (entries_free <= fep->tx_stop_threshold)
  190206. + netif_stop_queue(ndev);
  190207. +
  190208. return NETDEV_TX_OK;
  190209. }
  190210. @@ -474,7 +817,7 @@
  190211. /* Initialize the BD for every fragment in the page. */
  190212. bdp->cbd_sc = 0;
  190213. - if (bdp->cbd_bufaddr && fep->tx_skbuff[i]) {
  190214. + if (fep->tx_skbuff[i]) {
  190215. dev_kfree_skb_any(fep->tx_skbuff[i]);
  190216. fep->tx_skbuff[i] = NULL;
  190217. }
  190218. @@ -488,12 +831,13 @@
  190219. fep->dirty_tx = bdp;
  190220. }
  190221. -/* This function is called to start or restart the FEC during a link
  190222. - * change. This only happens when switching between half and full
  190223. - * duplex.
  190224. +/*
  190225. + * This function is called to start or restart the FEC during a link
  190226. + * change, transmit timeout, or to reconfigure the FEC. The network
  190227. + * packet processing for this device must be stopped before this call.
  190228. */
  190229. static void
  190230. -fec_restart(struct net_device *ndev, int duplex)
  190231. +fec_restart(struct net_device *ndev)
  190232. {
  190233. struct fec_enet_private *fep = netdev_priv(ndev);
  190234. const struct platform_device_id *id_entry =
  190235. @@ -504,13 +848,6 @@
  190236. u32 rcntl = OPT_FRAME_SIZE | 0x04;
  190237. u32 ecntl = 0x2; /* ETHEREN */
  190238. - if (netif_running(ndev)) {
  190239. - netif_device_detach(ndev);
  190240. - napi_disable(&fep->napi);
  190241. - netif_stop_queue(ndev);
  190242. - netif_tx_lock_bh(ndev);
  190243. - }
  190244. -
  190245. /* Whack a reset. We should wait for this. */
  190246. writel(1, fep->hwp + FEC_ECNTRL);
  190247. udelay(10);
  190248. @@ -519,7 +856,8 @@
  190249. * enet-mac reset will reset mac address registers too,
  190250. * so need to reconfigure it.
  190251. */
  190252. - if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
  190253. + if (id_entry->driver_data & FEC_QUIRK_ENET_MAC ||
  190254. + id_entry->driver_data & FEC_QUIRK_FEC_MAC) {
  190255. memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN);
  190256. writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
  190257. writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
  190258. @@ -551,7 +889,7 @@
  190259. }
  190260. /* Enable MII mode */
  190261. - if (duplex) {
  190262. + if (fep->full_duplex == DUPLEX_FULL) {
  190263. /* FD enable */
  190264. writel(0x04, fep->hwp + FEC_X_CNTRL);
  190265. } else {
  190266. @@ -560,8 +898,6 @@
  190267. writel(0x0, fep->hwp + FEC_X_CNTRL);
  190268. }
  190269. - fep->full_duplex = duplex;
  190270. -
  190271. /* Set MII speed */
  190272. writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
  190273. @@ -679,13 +1015,6 @@
  190274. /* Enable interrupts we wish to service */
  190275. writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
  190276. -
  190277. - if (netif_running(ndev)) {
  190278. - netif_tx_unlock_bh(ndev);
  190279. - netif_wake_queue(ndev);
  190280. - napi_enable(&fep->napi);
  190281. - netif_device_attach(ndev);
  190282. - }
  190283. }
  190284. static void
  190285. @@ -723,29 +1052,44 @@
  190286. {
  190287. struct fec_enet_private *fep = netdev_priv(ndev);
  190288. + fec_dump(ndev);
  190289. +
  190290. ndev->stats.tx_errors++;
  190291. - fep->delay_work.timeout = true;
  190292. - schedule_delayed_work(&(fep->delay_work.delay_work), 0);
  190293. + schedule_work(&fep->tx_timeout_work);
  190294. }
  190295. -static void fec_enet_work(struct work_struct *work)
  190296. +static void fec_enet_timeout_work(struct work_struct *work)
  190297. {
  190298. struct fec_enet_private *fep =
  190299. - container_of(work,
  190300. - struct fec_enet_private,
  190301. - delay_work.delay_work.work);
  190302. -
  190303. - if (fep->delay_work.timeout) {
  190304. - fep->delay_work.timeout = false;
  190305. - fec_restart(fep->netdev, fep->full_duplex);
  190306. - netif_wake_queue(fep->netdev);
  190307. - }
  190308. + container_of(work, struct fec_enet_private, tx_timeout_work);
  190309. + struct net_device *ndev = fep->netdev;
  190310. - if (fep->delay_work.trig_tx) {
  190311. - fep->delay_work.trig_tx = false;
  190312. - writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  190313. + rtnl_lock();
  190314. + if (netif_device_present(ndev) || netif_running(ndev)) {
  190315. + napi_disable(&fep->napi);
  190316. + netif_tx_lock_bh(ndev);
  190317. + fec_restart(ndev);
  190318. + netif_wake_queue(ndev);
  190319. + netif_tx_unlock_bh(ndev);
  190320. + napi_enable(&fep->napi);
  190321. }
  190322. + rtnl_unlock();
  190323. +}
  190324. +
  190325. +static void
  190326. +fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts,
  190327. + struct skb_shared_hwtstamps *hwtstamps)
  190328. +{
  190329. + unsigned long flags;
  190330. + u64 ns;
  190331. +
  190332. + spin_lock_irqsave(&fep->tmreg_lock, flags);
  190333. + ns = timecounter_cyc2time(&fep->tc, ts);
  190334. + spin_unlock_irqrestore(&fep->tmreg_lock, flags);
  190335. +
  190336. + memset(hwtstamps, 0, sizeof(*hwtstamps));
  190337. + hwtstamps->hwtstamp = ns_to_ktime(ns);
  190338. }
  190339. static void
  190340. @@ -756,6 +1100,7 @@
  190341. unsigned short status;
  190342. struct sk_buff *skb;
  190343. int index = 0;
  190344. + int entries_free;
  190345. fep = netdev_priv(ndev);
  190346. bdp = fep->dirty_tx;
  190347. @@ -769,16 +1114,18 @@
  190348. if (bdp == fep->cur_tx)
  190349. break;
  190350. - if (fep->bufdesc_ex)
  190351. - index = (struct bufdesc_ex *)bdp -
  190352. - (struct bufdesc_ex *)fep->tx_bd_base;
  190353. - else
  190354. - index = bdp - fep->tx_bd_base;
  190355. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  190356. skb = fep->tx_skbuff[index];
  190357. - dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, skb->len,
  190358. - DMA_TO_DEVICE);
  190359. + fep->tx_skbuff[index] = NULL;
  190360. + if (!IS_TSO_HEADER(fep, bdp->cbd_bufaddr))
  190361. + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
  190362. + bdp->cbd_datlen, DMA_TO_DEVICE);
  190363. bdp->cbd_bufaddr = 0;
  190364. + if (!skb) {
  190365. + bdp = fec_enet_get_nextdesc(bdp, fep);
  190366. + continue;
  190367. + }
  190368. /* Check for errors. */
  190369. if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
  190370. @@ -797,26 +1144,18 @@
  190371. ndev->stats.tx_carrier_errors++;
  190372. } else {
  190373. ndev->stats.tx_packets++;
  190374. - ndev->stats.tx_bytes += bdp->cbd_datlen;
  190375. + ndev->stats.tx_bytes += skb->len;
  190376. }
  190377. if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) &&
  190378. fep->bufdesc_ex) {
  190379. struct skb_shared_hwtstamps shhwtstamps;
  190380. - unsigned long flags;
  190381. struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  190382. - memset(&shhwtstamps, 0, sizeof(shhwtstamps));
  190383. - spin_lock_irqsave(&fep->tmreg_lock, flags);
  190384. - shhwtstamps.hwtstamp = ns_to_ktime(
  190385. - timecounter_cyc2time(&fep->tc, ebdp->ts));
  190386. - spin_unlock_irqrestore(&fep->tmreg_lock, flags);
  190387. + fec_enet_hwtstamp(fep, ebdp->ts, &shhwtstamps);
  190388. skb_tstamp_tx(skb, &shhwtstamps);
  190389. }
  190390. - if (status & BD_ENET_TX_READY)
  190391. - netdev_err(ndev, "HEY! Enet xmit interrupt and TX_READY\n");
  190392. -
  190393. /* Deferred means some collisions occurred during transmit,
  190394. * but we eventually sent the packet OK.
  190395. */
  190396. @@ -825,7 +1164,6 @@
  190397. /* Free the sk buffer associated with this last transmit */
  190398. dev_kfree_skb_any(skb);
  190399. - fep->tx_skbuff[index] = NULL;
  190400. fep->dirty_tx = bdp;
  190401. @@ -834,14 +1172,17 @@
  190402. /* Since we have freed up a buffer, the ring is no longer full
  190403. */
  190404. - if (fep->dirty_tx != fep->cur_tx) {
  190405. - if (netif_queue_stopped(ndev))
  190406. + if (netif_queue_stopped(ndev)) {
  190407. + entries_free = fec_enet_get_free_txdesc_num(fep);
  190408. + if (entries_free >= fep->tx_wake_threshold)
  190409. netif_wake_queue(ndev);
  190410. }
  190411. }
  190412. - return;
  190413. -}
  190414. + /* ERR006538: Keep the transmitter going */
  190415. + if (bdp != fep->cur_tx && readl(fep->hwp + FEC_X_DES_ACTIVE) == 0)
  190416. + writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  190417. +}
  190418. /* During a receive, the cur_rx points to the current incoming buffer.
  190419. * When we update through the ring, if the next incoming buffer has
  190420. @@ -886,8 +1227,7 @@
  190421. if ((status & BD_ENET_RX_LAST) == 0)
  190422. netdev_err(ndev, "rcv is not +last\n");
  190423. - if (!fep->opened)
  190424. - goto rx_processing_done;
  190425. + writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
  190426. /* Check for errors. */
  190427. if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
  190428. @@ -920,11 +1260,7 @@
  190429. pkt_len = bdp->cbd_datlen;
  190430. ndev->stats.rx_bytes += pkt_len;
  190431. - if (fep->bufdesc_ex)
  190432. - index = (struct bufdesc_ex *)bdp -
  190433. - (struct bufdesc_ex *)fep->rx_bd_base;
  190434. - else
  190435. - index = bdp - fep->rx_bd_base;
  190436. + index = fec_enet_get_bd_index(fep->rx_bd_base, bdp, fep);
  190437. data = fep->rx_skbuff[index]->data;
  190438. dma_sync_single_for_cpu(&fep->pdev->dev, bdp->cbd_bufaddr,
  190439. FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
  190440. @@ -975,18 +1311,9 @@
  190441. skb->protocol = eth_type_trans(skb, ndev);
  190442. /* Get receive timestamp from the skb */
  190443. - if (fep->hwts_rx_en && fep->bufdesc_ex) {
  190444. - struct skb_shared_hwtstamps *shhwtstamps =
  190445. - skb_hwtstamps(skb);
  190446. - unsigned long flags;
  190447. -
  190448. - memset(shhwtstamps, 0, sizeof(*shhwtstamps));
  190449. -
  190450. - spin_lock_irqsave(&fep->tmreg_lock, flags);
  190451. - shhwtstamps->hwtstamp = ns_to_ktime(
  190452. - timecounter_cyc2time(&fep->tc, ebdp->ts));
  190453. - spin_unlock_irqrestore(&fep->tmreg_lock, flags);
  190454. - }
  190455. + if (fep->hwts_rx_en && fep->bufdesc_ex)
  190456. + fec_enet_hwtstamp(fep, ebdp->ts,
  190457. + skb_hwtstamps(skb));
  190458. if (fep->bufdesc_ex &&
  190459. (fep->csum_flags & FLAG_RX_CSUM_ENABLED)) {
  190460. @@ -1044,29 +1371,25 @@
  190461. {
  190462. struct net_device *ndev = dev_id;
  190463. struct fec_enet_private *fep = netdev_priv(ndev);
  190464. + const unsigned napi_mask = FEC_ENET_RXF | FEC_ENET_TXF;
  190465. uint int_events;
  190466. irqreturn_t ret = IRQ_NONE;
  190467. - do {
  190468. - int_events = readl(fep->hwp + FEC_IEVENT);
  190469. - writel(int_events, fep->hwp + FEC_IEVENT);
  190470. + int_events = readl(fep->hwp + FEC_IEVENT);
  190471. + writel(int_events & ~napi_mask, fep->hwp + FEC_IEVENT);
  190472. - if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) {
  190473. - ret = IRQ_HANDLED;
  190474. + if (int_events & napi_mask) {
  190475. + ret = IRQ_HANDLED;
  190476. - /* Disable the RX interrupt */
  190477. - if (napi_schedule_prep(&fep->napi)) {
  190478. - writel(FEC_RX_DISABLED_IMASK,
  190479. - fep->hwp + FEC_IMASK);
  190480. - __napi_schedule(&fep->napi);
  190481. - }
  190482. - }
  190483. + /* Disable the NAPI interrupts */
  190484. + writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
  190485. + napi_schedule(&fep->napi);
  190486. + }
  190487. - if (int_events & FEC_ENET_MII) {
  190488. - ret = IRQ_HANDLED;
  190489. - complete(&fep->mdio_done);
  190490. - }
  190491. - } while (int_events);
  190492. + if (int_events & FEC_ENET_MII) {
  190493. + ret = IRQ_HANDLED;
  190494. + complete(&fep->mdio_done);
  190495. + }
  190496. return ret;
  190497. }
  190498. @@ -1074,8 +1397,16 @@
  190499. static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
  190500. {
  190501. struct net_device *ndev = napi->dev;
  190502. - int pkts = fec_enet_rx(ndev, budget);
  190503. struct fec_enet_private *fep = netdev_priv(ndev);
  190504. + int pkts;
  190505. +
  190506. + /*
  190507. + * Clear any pending transmit or receive interrupts before
  190508. + * processing the rings to avoid racing with the hardware.
  190509. + */
  190510. + writel(FEC_ENET_RXF | FEC_ENET_TXF, fep->hwp + FEC_IEVENT);
  190511. +
  190512. + pkts = fec_enet_rx(ndev, budget);
  190513. fec_enet_tx(ndev);
  190514. @@ -1173,14 +1504,23 @@
  190515. return;
  190516. }
  190517. - if (phy_dev->link) {
  190518. + /*
  190519. + * If the netdev is down, or is going down, we're not interested
  190520. + * in link state events, so just mark our idea of the link as down
  190521. + * and ignore the event.
  190522. + */
  190523. + if (!netif_running(ndev) || !netif_device_present(ndev)) {
  190524. + fep->link = 0;
  190525. + } else if (phy_dev->link) {
  190526. if (!fep->link) {
  190527. fep->link = phy_dev->link;
  190528. status_change = 1;
  190529. }
  190530. - if (fep->full_duplex != phy_dev->duplex)
  190531. + if (fep->full_duplex != phy_dev->duplex) {
  190532. + fep->full_duplex = phy_dev->duplex;
  190533. status_change = 1;
  190534. + }
  190535. if (phy_dev->speed != fep->speed) {
  190536. fep->speed = phy_dev->speed;
  190537. @@ -1188,11 +1528,21 @@
  190538. }
  190539. /* if any of the above changed restart the FEC */
  190540. - if (status_change)
  190541. - fec_restart(ndev, phy_dev->duplex);
  190542. + if (status_change) {
  190543. + napi_disable(&fep->napi);
  190544. + netif_tx_lock_bh(ndev);
  190545. + fec_restart(ndev);
  190546. + netif_wake_queue(ndev);
  190547. + netif_tx_unlock_bh(ndev);
  190548. + napi_enable(&fep->napi);
  190549. + }
  190550. } else {
  190551. if (fep->link) {
  190552. + napi_disable(&fep->napi);
  190553. + netif_tx_lock_bh(ndev);
  190554. fec_stop(ndev);
  190555. + netif_tx_unlock_bh(ndev);
  190556. + napi_enable(&fep->napi);
  190557. fep->link = phy_dev->link;
  190558. status_change = 1;
  190559. }
  190560. @@ -1255,9 +1605,51 @@
  190561. return 0;
  190562. }
  190563. -static int fec_enet_mdio_reset(struct mii_bus *bus)
  190564. +static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
  190565. {
  190566. + struct fec_enet_private *fep = netdev_priv(ndev);
  190567. + int ret;
  190568. +
  190569. + if (enable) {
  190570. + pm_runtime_enable(&fep->pdev->dev);
  190571. +
  190572. + ret = clk_prepare_enable(fep->clk_ahb);
  190573. + if (ret)
  190574. + return ret;
  190575. + ret = clk_prepare_enable(fep->clk_ipg);
  190576. + if (ret)
  190577. + goto failed_clk_ipg;
  190578. + if (fep->clk_enet_out) {
  190579. + ret = clk_prepare_enable(fep->clk_enet_out);
  190580. + if (ret)
  190581. + goto failed_clk_enet_out;
  190582. + }
  190583. + if (fep->clk_ptp) {
  190584. + ret = clk_prepare_enable(fep->clk_ptp);
  190585. + if (ret)
  190586. + goto failed_clk_ptp;
  190587. + }
  190588. + } else {
  190589. + clk_disable_unprepare(fep->clk_ahb);
  190590. + clk_disable_unprepare(fep->clk_ipg);
  190591. + if (fep->clk_enet_out)
  190592. + clk_disable_unprepare(fep->clk_enet_out);
  190593. + if (fep->clk_ptp)
  190594. + clk_disable_unprepare(fep->clk_ptp);
  190595. +
  190596. + pm_runtime_disable(&fep->pdev->dev);
  190597. + }
  190598. +
  190599. return 0;
  190600. +failed_clk_ptp:
  190601. + if (fep->clk_enet_out)
  190602. + clk_disable_unprepare(fep->clk_enet_out);
  190603. +failed_clk_enet_out:
  190604. + clk_disable_unprepare(fep->clk_ipg);
  190605. +failed_clk_ipg:
  190606. + clk_disable_unprepare(fep->clk_ahb);
  190607. +
  190608. + return ret;
  190609. }
  190610. static int fec_enet_mii_probe(struct net_device *ndev)
  190611. @@ -1304,6 +1696,7 @@
  190612. /* mask with MAC supported features */
  190613. if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT) {
  190614. phy_dev->supported &= PHY_GBIT_FEATURES;
  190615. + phy_dev->supported &= ~SUPPORTED_1000baseT_Half;
  190616. #if !defined(CONFIG_M5272)
  190617. phy_dev->supported |= SUPPORTED_Pause;
  190618. #endif
  190619. @@ -1369,7 +1762,7 @@
  190620. * Reference Manual has an error on this, and gets fixed on i.MX6Q
  190621. * document.
  190622. */
  190623. - fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ahb), 5000000);
  190624. + fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ipg), 5000000);
  190625. if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
  190626. fep->phy_speed--;
  190627. fep->phy_speed <<= 1;
  190628. @@ -1384,7 +1777,6 @@
  190629. fep->mii_bus->name = "fec_enet_mii_bus";
  190630. fep->mii_bus->read = fec_enet_mdio_read;
  190631. fep->mii_bus->write = fec_enet_mdio_write;
  190632. - fep->mii_bus->reset = fec_enet_mdio_reset;
  190633. snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
  190634. pdev->name, fep->dev_id + 1);
  190635. fep->mii_bus->priv = fep;
  190636. @@ -1508,6 +1900,9 @@
  190637. {
  190638. struct fec_enet_private *fep = netdev_priv(ndev);
  190639. + if (!fep->phy_dev)
  190640. + return -ENODEV;
  190641. +
  190642. if (pause->tx_pause != pause->rx_pause) {
  190643. netdev_info(ndev,
  190644. "hardware only support enable/disable both tx and rx");
  190645. @@ -1533,8 +1928,14 @@
  190646. fec_stop(ndev);
  190647. phy_start_aneg(fep->phy_dev);
  190648. }
  190649. - if (netif_running(ndev))
  190650. - fec_restart(ndev, 0);
  190651. + if (netif_running(ndev)) {
  190652. + napi_disable(&fep->napi);
  190653. + netif_tx_lock_bh(ndev);
  190654. + fec_restart(ndev);
  190655. + netif_wake_queue(ndev);
  190656. + netif_tx_unlock_bh(ndev);
  190657. + napi_enable(&fep->napi);
  190658. + }
  190659. return 0;
  190660. }
  190661. @@ -1651,21 +2052,19 @@
  190662. }
  190663. static const struct ethtool_ops fec_enet_ethtool_ops = {
  190664. -#if !defined(CONFIG_M5272)
  190665. - .get_pauseparam = fec_enet_get_pauseparam,
  190666. - .set_pauseparam = fec_enet_set_pauseparam,
  190667. -#endif
  190668. .get_settings = fec_enet_get_settings,
  190669. .set_settings = fec_enet_set_settings,
  190670. .get_drvinfo = fec_enet_get_drvinfo,
  190671. - .get_link = ethtool_op_get_link,
  190672. - .get_ts_info = fec_enet_get_ts_info,
  190673. .nway_reset = fec_enet_nway_reset,
  190674. + .get_link = ethtool_op_get_link,
  190675. #ifndef CONFIG_M5272
  190676. - .get_ethtool_stats = fec_enet_get_ethtool_stats,
  190677. + .get_pauseparam = fec_enet_get_pauseparam,
  190678. + .set_pauseparam = fec_enet_set_pauseparam,
  190679. .get_strings = fec_enet_get_strings,
  190680. + .get_ethtool_stats = fec_enet_get_ethtool_stats,
  190681. .get_sset_count = fec_enet_get_sset_count,
  190682. #endif
  190683. + .get_ts_info = fec_enet_get_ts_info,
  190684. };
  190685. static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
  190686. @@ -1699,18 +2098,23 @@
  190687. bdp = fep->rx_bd_base;
  190688. for (i = 0; i < fep->rx_ring_size; i++) {
  190689. skb = fep->rx_skbuff[i];
  190690. -
  190691. - if (bdp->cbd_bufaddr)
  190692. + fep->rx_skbuff[i] = NULL;
  190693. + if (skb) {
  190694. dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
  190695. FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
  190696. - if (skb)
  190697. dev_kfree_skb(skb);
  190698. + }
  190699. bdp = fec_enet_get_nextdesc(bdp, fep);
  190700. }
  190701. bdp = fep->tx_bd_base;
  190702. - for (i = 0; i < fep->tx_ring_size; i++)
  190703. + for (i = 0; i < fep->tx_ring_size; i++) {
  190704. kfree(fep->tx_bounce[i]);
  190705. + fep->tx_bounce[i] = NULL;
  190706. + skb = fep->tx_skbuff[i];
  190707. + fep->tx_skbuff[i] = NULL;
  190708. + dev_kfree_skb(skb);
  190709. + }
  190710. }
  190711. static int fec_enet_alloc_buffers(struct net_device *ndev)
  190712. @@ -1722,21 +2126,23 @@
  190713. bdp = fep->rx_bd_base;
  190714. for (i = 0; i < fep->rx_ring_size; i++) {
  190715. + dma_addr_t addr;
  190716. +
  190717. skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
  190718. - if (!skb) {
  190719. - fec_enet_free_buffers(ndev);
  190720. - return -ENOMEM;
  190721. - }
  190722. - fep->rx_skbuff[i] = skb;
  190723. + if (!skb)
  190724. + goto err_alloc;
  190725. - bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data,
  190726. + addr = dma_map_single(&fep->pdev->dev, skb->data,
  190727. FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
  190728. - if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
  190729. - fec_enet_free_buffers(ndev);
  190730. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  190731. + dev_kfree_skb(skb);
  190732. if (net_ratelimit())
  190733. netdev_err(ndev, "Rx DMA memory map failed\n");
  190734. - return -ENOMEM;
  190735. + goto err_alloc;
  190736. }
  190737. +
  190738. + fep->rx_skbuff[i] = skb;
  190739. + bdp->cbd_bufaddr = addr;
  190740. bdp->cbd_sc = BD_ENET_RX_EMPTY;
  190741. if (fep->bufdesc_ex) {
  190742. @@ -1754,6 +2160,8 @@
  190743. bdp = fep->tx_bd_base;
  190744. for (i = 0; i < fep->tx_ring_size; i++) {
  190745. fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
  190746. + if (!fep->tx_bounce[i])
  190747. + goto err_alloc;
  190748. bdp->cbd_sc = 0;
  190749. bdp->cbd_bufaddr = 0;
  190750. @@ -1771,14 +2179,35 @@
  190751. bdp->cbd_sc |= BD_SC_WRAP;
  190752. return 0;
  190753. +
  190754. + err_alloc:
  190755. + fec_enet_free_buffers(ndev);
  190756. + return -ENOMEM;
  190757. }
  190758. static int
  190759. fec_enet_open(struct net_device *ndev)
  190760. {
  190761. struct fec_enet_private *fep = netdev_priv(ndev);
  190762. + const struct platform_device_id *id_entry =
  190763. + platform_get_device_id(fep->pdev);
  190764. int ret;
  190765. + if (id_entry->driver_data & FEC_QUIRK_BUG_WAITMODE)
  190766. + pm_qos_add_request(&ndev->pm_qos_req,
  190767. + PM_QOS_CPU_DMA_LATENCY,
  190768. + 0);
  190769. + else
  190770. + pm_qos_add_request(&ndev->pm_qos_req,
  190771. + PM_QOS_CPU_DMA_LATENCY,
  190772. + PM_QOS_DEFAULT_VALUE);
  190773. +
  190774. +
  190775. + pinctrl_pm_select_default_state(&fep->pdev->dev);
  190776. + ret = fec_enet_clk_enable(ndev, true);
  190777. + if (ret)
  190778. + return ret;
  190779. +
  190780. /* I should reset the ring buffers here, but I don't yet know
  190781. * a simple way to do that.
  190782. */
  190783. @@ -1794,10 +2223,12 @@
  190784. return ret;
  190785. }
  190786. + pm_runtime_get_sync(&fep->pdev->dev);
  190787. +
  190788. + fec_restart(ndev);
  190789. napi_enable(&fep->napi);
  190790. phy_start(fep->phy_dev);
  190791. netif_start_queue(ndev);
  190792. - fep->opened = 1;
  190793. return 0;
  190794. }
  190795. @@ -1806,17 +2237,22 @@
  190796. {
  190797. struct fec_enet_private *fep = netdev_priv(ndev);
  190798. - /* Don't know what to do yet. */
  190799. - napi_disable(&fep->napi);
  190800. - fep->opened = 0;
  190801. - netif_stop_queue(ndev);
  190802. - fec_stop(ndev);
  190803. + phy_stop(fep->phy_dev);
  190804. - if (fep->phy_dev) {
  190805. - phy_stop(fep->phy_dev);
  190806. - phy_disconnect(fep->phy_dev);
  190807. + if (netif_device_present(ndev)) {
  190808. + napi_disable(&fep->napi);
  190809. + netif_tx_disable(ndev);
  190810. + fec_stop(ndev);
  190811. }
  190812. + phy_disconnect(fep->phy_dev);
  190813. + fep->phy_dev = NULL;
  190814. +
  190815. + fec_enet_clk_enable(ndev, false);
  190816. + pinctrl_pm_select_sleep_state(&fep->pdev->dev);
  190817. + pm_qos_remove_request(&ndev->pm_qos_req);
  190818. + pm_runtime_put_sync_suspend(&fep->pdev->dev);
  190819. +
  190820. fec_enet_free_buffers(ndev);
  190821. return 0;
  190822. @@ -1904,10 +2340,11 @@
  190823. struct fec_enet_private *fep = netdev_priv(ndev);
  190824. struct sockaddr *addr = p;
  190825. - if (!is_valid_ether_addr(addr->sa_data))
  190826. - return -EADDRNOTAVAIL;
  190827. -
  190828. - memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
  190829. + if (addr) {
  190830. + if (!is_valid_ether_addr(addr->sa_data))
  190831. + return -EADDRNOTAVAIL;
  190832. + memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
  190833. + }
  190834. writel(ndev->dev_addr[3] | (ndev->dev_addr[2] << 8) |
  190835. (ndev->dev_addr[1] << 16) | (ndev->dev_addr[0] << 24),
  190836. @@ -1940,12 +2377,21 @@
  190837. }
  190838. #endif
  190839. +#define FEATURES_NEED_QUIESCE NETIF_F_RXCSUM
  190840. +
  190841. static int fec_set_features(struct net_device *netdev,
  190842. netdev_features_t features)
  190843. {
  190844. struct fec_enet_private *fep = netdev_priv(netdev);
  190845. netdev_features_t changed = features ^ netdev->features;
  190846. + /* Quiesce the device if necessary */
  190847. + if (netif_running(netdev) && changed & FEATURES_NEED_QUIESCE) {
  190848. + napi_disable(&fep->napi);
  190849. + netif_tx_lock_bh(netdev);
  190850. + fec_stop(netdev);
  190851. + }
  190852. +
  190853. netdev->features = features;
  190854. /* Receive checksum has been changed */
  190855. @@ -1954,14 +2400,14 @@
  190856. fep->csum_flags |= FLAG_RX_CSUM_ENABLED;
  190857. else
  190858. fep->csum_flags &= ~FLAG_RX_CSUM_ENABLED;
  190859. + }
  190860. - if (netif_running(netdev)) {
  190861. - fec_stop(netdev);
  190862. - fec_restart(netdev, fep->phy_dev->duplex);
  190863. - netif_wake_queue(netdev);
  190864. - } else {
  190865. - fec_restart(netdev, fep->phy_dev->duplex);
  190866. - }
  190867. + /* Resume the device after updates */
  190868. + if (netif_running(netdev) && changed & FEATURES_NEED_QUIESCE) {
  190869. + fec_restart(netdev);
  190870. + netif_wake_queue(netdev);
  190871. + netif_tx_unlock_bh(netdev);
  190872. + napi_enable(&fep->napi);
  190873. }
  190874. return 0;
  190875. @@ -1993,23 +2439,43 @@
  190876. const struct platform_device_id *id_entry =
  190877. platform_get_device_id(fep->pdev);
  190878. struct bufdesc *cbd_base;
  190879. + int bd_size;
  190880. +
  190881. + /* init the tx & rx ring size */
  190882. + fep->tx_ring_size = TX_RING_SIZE;
  190883. + fep->rx_ring_size = RX_RING_SIZE;
  190884. +
  190885. + fep->tx_stop_threshold = FEC_MAX_SKB_DESCS;
  190886. + fep->tx_wake_threshold = (fep->tx_ring_size - fep->tx_stop_threshold) / 2;
  190887. +
  190888. + if (fep->bufdesc_ex)
  190889. + fep->bufdesc_size = sizeof(struct bufdesc_ex);
  190890. + else
  190891. + fep->bufdesc_size = sizeof(struct bufdesc);
  190892. + bd_size = (fep->tx_ring_size + fep->rx_ring_size) *
  190893. + fep->bufdesc_size;
  190894. /* Allocate memory for buffer descriptors. */
  190895. - cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
  190896. + cbd_base = dma_alloc_coherent(NULL, bd_size, &fep->bd_dma,
  190897. GFP_KERNEL);
  190898. if (!cbd_base)
  190899. return -ENOMEM;
  190900. + fep->tso_hdrs = dma_alloc_coherent(NULL, fep->tx_ring_size * TSO_HEADER_SIZE,
  190901. + &fep->tso_hdrs_dma, GFP_KERNEL);
  190902. + if (!fep->tso_hdrs) {
  190903. + dma_free_coherent(NULL, bd_size, cbd_base, fep->bd_dma);
  190904. + return -ENOMEM;
  190905. + }
  190906. +
  190907. memset(cbd_base, 0, PAGE_SIZE);
  190908. fep->netdev = ndev;
  190909. /* Get the Ethernet address */
  190910. fec_get_mac(ndev);
  190911. -
  190912. - /* init the tx & rx ring size */
  190913. - fep->tx_ring_size = TX_RING_SIZE;
  190914. - fep->rx_ring_size = RX_RING_SIZE;
  190915. + /* make sure MAC we just acquired is programmed into the hw */
  190916. + fec_set_mac_address(ndev, NULL);
  190917. /* Set receive and transmit descriptor base. */
  190918. fep->rx_bd_base = cbd_base;
  190919. @@ -2027,22 +2493,22 @@
  190920. writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK);
  190921. netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, NAPI_POLL_WEIGHT);
  190922. - if (id_entry->driver_data & FEC_QUIRK_HAS_VLAN) {
  190923. + if (id_entry->driver_data & FEC_QUIRK_HAS_VLAN)
  190924. /* enable hw VLAN support */
  190925. ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
  190926. - ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
  190927. - }
  190928. if (id_entry->driver_data & FEC_QUIRK_HAS_CSUM) {
  190929. + ndev->gso_max_segs = FEC_MAX_TSO_SEGS;
  190930. +
  190931. /* enable hw accelerator */
  190932. ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
  190933. - | NETIF_F_RXCSUM);
  190934. - ndev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
  190935. - | NETIF_F_RXCSUM);
  190936. + | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO);
  190937. fep->csum_flags |= FLAG_RX_CSUM_ENABLED;
  190938. }
  190939. - fec_restart(ndev, 0);
  190940. + ndev->hw_features = ndev->features;
  190941. +
  190942. + fec_restart(ndev);
  190943. return 0;
  190944. }
  190945. @@ -2117,6 +2583,9 @@
  190946. fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG;
  190947. #endif
  190948. + /* Select default pin state */
  190949. + pinctrl_pm_select_default_state(&pdev->dev);
  190950. +
  190951. r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  190952. fep->hwp = devm_ioremap_resource(&pdev->dev, r);
  190953. if (IS_ERR(fep->hwp)) {
  190954. @@ -2167,26 +2636,10 @@
  190955. fep->bufdesc_ex = 0;
  190956. }
  190957. - ret = clk_prepare_enable(fep->clk_ahb);
  190958. + ret = fec_enet_clk_enable(ndev, true);
  190959. if (ret)
  190960. goto failed_clk;
  190961. - ret = clk_prepare_enable(fep->clk_ipg);
  190962. - if (ret)
  190963. - goto failed_clk_ipg;
  190964. -
  190965. - if (fep->clk_enet_out) {
  190966. - ret = clk_prepare_enable(fep->clk_enet_out);
  190967. - if (ret)
  190968. - goto failed_clk_enet_out;
  190969. - }
  190970. -
  190971. - if (fep->clk_ptp) {
  190972. - ret = clk_prepare_enable(fep->clk_ptp);
  190973. - if (ret)
  190974. - goto failed_clk_ptp;
  190975. - }
  190976. -
  190977. fep->reg_phy = devm_regulator_get(&pdev->dev, "phy");
  190978. if (!IS_ERR(fep->reg_phy)) {
  190979. ret = regulator_enable(fep->reg_phy);
  190980. @@ -2228,6 +2681,8 @@
  190981. /* Carrier starts down, phylib will bring it up */
  190982. netif_carrier_off(ndev);
  190983. + fec_enet_clk_enable(ndev, false);
  190984. + pinctrl_pm_select_sleep_state(&pdev->dev);
  190985. ret = register_netdev(ndev);
  190986. if (ret)
  190987. @@ -2236,7 +2691,7 @@
  190988. if (fep->bufdesc_ex && fep->ptp_clock)
  190989. netdev_info(ndev, "registered PHC device %d\n", fep->dev_id);
  190990. - INIT_DELAYED_WORK(&(fep->delay_work.delay_work), fec_enet_work);
  190991. + INIT_WORK(&fep->tx_timeout_work, fec_enet_timeout_work);
  190992. return 0;
  190993. failed_register:
  190994. @@ -2247,15 +2702,7 @@
  190995. if (fep->reg_phy)
  190996. regulator_disable(fep->reg_phy);
  190997. failed_regulator:
  190998. - if (fep->clk_ptp)
  190999. - clk_disable_unprepare(fep->clk_ptp);
  191000. -failed_clk_ptp:
  191001. - if (fep->clk_enet_out)
  191002. - clk_disable_unprepare(fep->clk_enet_out);
  191003. -failed_clk_enet_out:
  191004. - clk_disable_unprepare(fep->clk_ipg);
  191005. -failed_clk_ipg:
  191006. - clk_disable_unprepare(fep->clk_ahb);
  191007. + fec_enet_clk_enable(ndev, false);
  191008. failed_clk:
  191009. failed_ioremap:
  191010. free_netdev(ndev);
  191011. @@ -2269,42 +2716,40 @@
  191012. struct net_device *ndev = platform_get_drvdata(pdev);
  191013. struct fec_enet_private *fep = netdev_priv(ndev);
  191014. - cancel_delayed_work_sync(&(fep->delay_work.delay_work));
  191015. + cancel_work_sync(&fep->tx_timeout_work);
  191016. unregister_netdev(ndev);
  191017. fec_enet_mii_remove(fep);
  191018. del_timer_sync(&fep->time_keep);
  191019. if (fep->reg_phy)
  191020. regulator_disable(fep->reg_phy);
  191021. - if (fep->clk_ptp)
  191022. - clk_disable_unprepare(fep->clk_ptp);
  191023. if (fep->ptp_clock)
  191024. ptp_clock_unregister(fep->ptp_clock);
  191025. - if (fep->clk_enet_out)
  191026. - clk_disable_unprepare(fep->clk_enet_out);
  191027. - clk_disable_unprepare(fep->clk_ipg);
  191028. - clk_disable_unprepare(fep->clk_ahb);
  191029. + fec_enet_clk_enable(ndev, false);
  191030. free_netdev(ndev);
  191031. return 0;
  191032. }
  191033. -#ifdef CONFIG_PM_SLEEP
  191034. +#ifdef CONFIG_PM
  191035. static int
  191036. fec_suspend(struct device *dev)
  191037. {
  191038. struct net_device *ndev = dev_get_drvdata(dev);
  191039. struct fec_enet_private *fep = netdev_priv(ndev);
  191040. + rtnl_lock();
  191041. if (netif_running(ndev)) {
  191042. - fec_stop(ndev);
  191043. + phy_stop(fep->phy_dev);
  191044. + napi_disable(&fep->napi);
  191045. + netif_tx_lock_bh(ndev);
  191046. netif_device_detach(ndev);
  191047. + netif_tx_unlock_bh(ndev);
  191048. + fec_stop(ndev);
  191049. }
  191050. - if (fep->clk_ptp)
  191051. - clk_disable_unprepare(fep->clk_ptp);
  191052. - if (fep->clk_enet_out)
  191053. - clk_disable_unprepare(fep->clk_enet_out);
  191054. - clk_disable_unprepare(fep->clk_ipg);
  191055. - clk_disable_unprepare(fep->clk_ahb);
  191056. + rtnl_unlock();
  191057. +
  191058. + fec_enet_clk_enable(ndev, false);
  191059. + pinctrl_pm_select_sleep_state(&fep->pdev->dev);
  191060. if (fep->reg_phy)
  191061. regulator_disable(fep->reg_phy);
  191062. @@ -2325,48 +2770,49 @@
  191063. return ret;
  191064. }
  191065. - ret = clk_prepare_enable(fep->clk_ahb);
  191066. - if (ret)
  191067. - goto failed_clk_ahb;
  191068. -
  191069. - ret = clk_prepare_enable(fep->clk_ipg);
  191070. + pinctrl_pm_select_default_state(&fep->pdev->dev);
  191071. + ret = fec_enet_clk_enable(ndev, true);
  191072. if (ret)
  191073. - goto failed_clk_ipg;
  191074. -
  191075. - if (fep->clk_enet_out) {
  191076. - ret = clk_prepare_enable(fep->clk_enet_out);
  191077. - if (ret)
  191078. - goto failed_clk_enet_out;
  191079. - }
  191080. -
  191081. - if (fep->clk_ptp) {
  191082. - ret = clk_prepare_enable(fep->clk_ptp);
  191083. - if (ret)
  191084. - goto failed_clk_ptp;
  191085. - }
  191086. + goto failed_clk;
  191087. + rtnl_lock();
  191088. if (netif_running(ndev)) {
  191089. - fec_restart(ndev, fep->full_duplex);
  191090. + fec_restart(ndev);
  191091. + netif_tx_lock_bh(ndev);
  191092. netif_device_attach(ndev);
  191093. + netif_tx_unlock_bh(ndev);
  191094. + napi_enable(&fep->napi);
  191095. + phy_start(fep->phy_dev);
  191096. }
  191097. + rtnl_unlock();
  191098. return 0;
  191099. -failed_clk_ptp:
  191100. - if (fep->clk_enet_out)
  191101. - clk_disable_unprepare(fep->clk_enet_out);
  191102. -failed_clk_enet_out:
  191103. - clk_disable_unprepare(fep->clk_ipg);
  191104. -failed_clk_ipg:
  191105. - clk_disable_unprepare(fep->clk_ahb);
  191106. -failed_clk_ahb:
  191107. +failed_clk:
  191108. if (fep->reg_phy)
  191109. regulator_disable(fep->reg_phy);
  191110. return ret;
  191111. }
  191112. +
  191113. +static int fec_runtime_suspend(struct device *dev)
  191114. +{
  191115. + release_bus_freq(BUS_FREQ_HIGH);
  191116. + return 0;
  191117. +}
  191118. +
  191119. +static int fec_runtime_resume(struct device *dev)
  191120. +{
  191121. + request_bus_freq(BUS_FREQ_HIGH);
  191122. + return 0;
  191123. +}
  191124. +
  191125. +static const struct dev_pm_ops fec_pm_ops = {
  191126. + SET_RUNTIME_PM_OPS(fec_runtime_suspend, fec_runtime_resume, NULL)
  191127. + SET_SYSTEM_SLEEP_PM_OPS(fec_suspend, fec_resume)
  191128. +};
  191129. +
  191130. #endif /* CONFIG_PM_SLEEP */
  191131. -static SIMPLE_DEV_PM_OPS(fec_pm_ops, fec_suspend, fec_resume);
  191132. static struct platform_driver fec_driver = {
  191133. .driver = {
  191134. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/fec_ptp.c linux-linaro-stable-mx6/drivers/net/ethernet/freescale/fec_ptp.c
  191135. --- linux-3.14.15/drivers/net/ethernet/freescale/fec_ptp.c 2014-07-31 23:51:43.000000000 +0200
  191136. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/fec_ptp.c 2014-08-20 19:31:46.368870036 +0200
  191137. @@ -372,6 +372,7 @@
  191138. fep->ptp_caps.n_alarm = 0;
  191139. fep->ptp_caps.n_ext_ts = 0;
  191140. fep->ptp_caps.n_per_out = 0;
  191141. + fep->ptp_caps.n_pins = 0;
  191142. fep->ptp_caps.pps = 0;
  191143. fep->ptp_caps.adjfreq = fec_ptp_adjfreq;
  191144. fep->ptp_caps.adjtime = fec_ptp_adjtime;
  191145. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c linux-linaro-stable-mx6/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
  191146. --- linux-3.14.15/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 2014-07-31 23:51:43.000000000 +0200
  191147. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 2014-08-20 19:31:46.384870105 +0200
  191148. @@ -91,6 +91,9 @@
  191149. u16 pkt_len, sc;
  191150. int curidx;
  191151. + if (budget <= 0)
  191152. + return received;
  191153. +
  191154. /*
  191155. * First, grab all of the stats for the incoming packet.
  191156. * These get messed up if we get called due to a busy condition.
  191157. @@ -789,10 +792,6 @@
  191158. phydev = of_phy_connect(dev, fep->fpi->phy_node, &fs_adjust_link, 0,
  191159. iface);
  191160. if (!phydev) {
  191161. - phydev = of_phy_connect_fixed_link(dev, &fs_adjust_link,
  191162. - iface);
  191163. - }
  191164. - if (!phydev) {
  191165. dev_err(&dev->dev, "Could not attach to PHY\n");
  191166. return -ENODEV;
  191167. }
  191168. @@ -1026,9 +1025,16 @@
  191169. fpi->use_napi = 1;
  191170. fpi->napi_weight = 17;
  191171. fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0);
  191172. - if ((!fpi->phy_node) && (!of_get_property(ofdev->dev.of_node, "fixed-link",
  191173. - NULL)))
  191174. - goto out_free_fpi;
  191175. + if (!fpi->phy_node && of_phy_is_fixed_link(ofdev->dev.of_node)) {
  191176. + err = of_phy_register_fixed_link(ofdev->dev.of_node);
  191177. + if (err)
  191178. + goto out_free_fpi;
  191179. +
  191180. + /* In the case of a fixed PHY, the DT node associated
  191181. + * to the PHY is the Ethernet MAC DT node.
  191182. + */
  191183. + fpi->phy_node = ofdev->dev.of_node;
  191184. + }
  191185. if (of_device_is_compatible(ofdev->dev.of_node, "fsl,mpc5125-fec")) {
  191186. phy_connection_type = of_get_property(ofdev->dev.of_node,
  191187. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/fs_enet/mii-fec.c linux-linaro-stable-mx6/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
  191188. --- linux-3.14.15/drivers/net/ethernet/freescale/fs_enet/mii-fec.c 2014-07-31 23:51:43.000000000 +0200
  191189. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/fs_enet/mii-fec.c 2014-08-20 19:31:46.424870276 +0200
  191190. @@ -95,12 +95,6 @@
  191191. }
  191192. -static int fs_enet_fec_mii_reset(struct mii_bus *bus)
  191193. -{
  191194. - /* nothing here - for now */
  191195. - return 0;
  191196. -}
  191197. -
  191198. static struct of_device_id fs_enet_mdio_fec_match[];
  191199. static int fs_enet_mdio_probe(struct platform_device *ofdev)
  191200. {
  191201. @@ -128,7 +122,6 @@
  191202. new_bus->name = "FEC MII Bus";
  191203. new_bus->read = &fs_enet_fec_mii_read;
  191204. new_bus->write = &fs_enet_fec_mii_write;
  191205. - new_bus->reset = &fs_enet_fec_mii_reset;
  191206. ret = of_address_to_resource(ofdev->dev.of_node, 0, &res);
  191207. if (ret)
  191208. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/gianfar.c linux-linaro-stable-mx6/drivers/net/ethernet/freescale/gianfar.c
  191209. --- linux-3.14.15/drivers/net/ethernet/freescale/gianfar.c 2014-07-31 23:51:43.000000000 +0200
  191210. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/gianfar.c 2014-08-20 19:31:46.424870276 +0200
  191211. @@ -9,7 +9,7 @@
  191212. * Maintainer: Kumar Gala
  191213. * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  191214. *
  191215. - * Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
  191216. + * Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc.
  191217. * Copyright 2007 MontaVista Software, Inc.
  191218. *
  191219. * This program is free software; you can redistribute it and/or modify it
  191220. @@ -121,7 +121,7 @@
  191221. static irqreturn_t gfar_transmit(int irq, void *dev_id);
  191222. static irqreturn_t gfar_interrupt(int irq, void *dev_id);
  191223. static void adjust_link(struct net_device *dev);
  191224. -static void init_registers(struct net_device *dev);
  191225. +static noinline void gfar_update_link_state(struct gfar_private *priv);
  191226. static int init_phy(struct net_device *dev);
  191227. static int gfar_probe(struct platform_device *ofdev);
  191228. static int gfar_remove(struct platform_device *ofdev);
  191229. @@ -129,8 +129,10 @@
  191230. static void gfar_set_multi(struct net_device *dev);
  191231. static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
  191232. static void gfar_configure_serdes(struct net_device *dev);
  191233. -static int gfar_poll(struct napi_struct *napi, int budget);
  191234. -static int gfar_poll_sq(struct napi_struct *napi, int budget);
  191235. +static int gfar_poll_rx(struct napi_struct *napi, int budget);
  191236. +static int gfar_poll_tx(struct napi_struct *napi, int budget);
  191237. +static int gfar_poll_rx_sq(struct napi_struct *napi, int budget);
  191238. +static int gfar_poll_tx_sq(struct napi_struct *napi, int budget);
  191239. #ifdef CONFIG_NET_POLL_CONTROLLER
  191240. static void gfar_netpoll(struct net_device *dev);
  191241. #endif
  191242. @@ -138,9 +140,7 @@
  191243. static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue);
  191244. static void gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
  191245. int amount_pull, struct napi_struct *napi);
  191246. -void gfar_halt(struct net_device *dev);
  191247. -static void gfar_halt_nodisable(struct net_device *dev);
  191248. -void gfar_start(struct net_device *dev);
  191249. +static void gfar_halt_nodisable(struct gfar_private *priv);
  191250. static void gfar_clear_exact_match(struct net_device *dev);
  191251. static void gfar_set_mac_for_addr(struct net_device *dev, int num,
  191252. const u8 *addr);
  191253. @@ -332,72 +332,76 @@
  191254. }
  191255. }
  191256. -static void gfar_init_mac(struct net_device *ndev)
  191257. +static void gfar_rx_buff_size_config(struct gfar_private *priv)
  191258. {
  191259. - struct gfar_private *priv = netdev_priv(ndev);
  191260. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191261. - u32 rctrl = 0;
  191262. - u32 tctrl = 0;
  191263. - u32 attrs = 0;
  191264. -
  191265. - /* write the tx/rx base registers */
  191266. - gfar_init_tx_rx_base(priv);
  191267. -
  191268. - /* Configure the coalescing support */
  191269. - gfar_configure_coalescing_all(priv);
  191270. + int frame_size = priv->ndev->mtu + ETH_HLEN;
  191271. /* set this when rx hw offload (TOE) functions are being used */
  191272. priv->uses_rxfcb = 0;
  191273. + if (priv->ndev->features & (NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX))
  191274. + priv->uses_rxfcb = 1;
  191275. +
  191276. + if (priv->hwts_rx_en)
  191277. + priv->uses_rxfcb = 1;
  191278. +
  191279. + if (priv->uses_rxfcb)
  191280. + frame_size += GMAC_FCB_LEN;
  191281. +
  191282. + frame_size += priv->padding;
  191283. +
  191284. + frame_size = (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) +
  191285. + INCREMENTAL_BUFFER_SIZE;
  191286. +
  191287. + priv->rx_buffer_size = frame_size;
  191288. +}
  191289. +
  191290. +static void gfar_mac_rx_config(struct gfar_private *priv)
  191291. +{
  191292. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191293. + u32 rctrl = 0;
  191294. +
  191295. if (priv->rx_filer_enable) {
  191296. rctrl |= RCTRL_FILREN;
  191297. /* Program the RIR0 reg with the required distribution */
  191298. - gfar_write(&regs->rir0, DEFAULT_RIR0);
  191299. + if (priv->poll_mode == GFAR_SQ_POLLING)
  191300. + gfar_write(&regs->rir0, DEFAULT_2RXQ_RIR0);
  191301. + else /* GFAR_MQ_POLLING */
  191302. + gfar_write(&regs->rir0, DEFAULT_8RXQ_RIR0);
  191303. }
  191304. /* Restore PROMISC mode */
  191305. - if (ndev->flags & IFF_PROMISC)
  191306. + if (priv->ndev->flags & IFF_PROMISC)
  191307. rctrl |= RCTRL_PROM;
  191308. - if (ndev->features & NETIF_F_RXCSUM) {
  191309. + if (priv->ndev->features & NETIF_F_RXCSUM)
  191310. rctrl |= RCTRL_CHECKSUMMING;
  191311. - priv->uses_rxfcb = 1;
  191312. - }
  191313. -
  191314. - if (priv->extended_hash) {
  191315. - rctrl |= RCTRL_EXTHASH;
  191316. - gfar_clear_exact_match(ndev);
  191317. - rctrl |= RCTRL_EMEN;
  191318. - }
  191319. + if (priv->extended_hash)
  191320. + rctrl |= RCTRL_EXTHASH | RCTRL_EMEN;
  191321. if (priv->padding) {
  191322. rctrl &= ~RCTRL_PAL_MASK;
  191323. rctrl |= RCTRL_PADDING(priv->padding);
  191324. }
  191325. - /* Insert receive time stamps into padding alignment bytes */
  191326. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) {
  191327. - rctrl &= ~RCTRL_PAL_MASK;
  191328. - rctrl |= RCTRL_PADDING(8);
  191329. - priv->padding = 8;
  191330. - }
  191331. -
  191332. /* Enable HW time stamping if requested from user space */
  191333. - if (priv->hwts_rx_en) {
  191334. + if (priv->hwts_rx_en)
  191335. rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE;
  191336. - priv->uses_rxfcb = 1;
  191337. - }
  191338. - if (ndev->features & NETIF_F_HW_VLAN_CTAG_RX) {
  191339. + if (priv->ndev->features & NETIF_F_HW_VLAN_CTAG_RX)
  191340. rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT;
  191341. - priv->uses_rxfcb = 1;
  191342. - }
  191343. /* Init rctrl based on our settings */
  191344. gfar_write(&regs->rctrl, rctrl);
  191345. +}
  191346. - if (ndev->features & NETIF_F_IP_CSUM)
  191347. +static void gfar_mac_tx_config(struct gfar_private *priv)
  191348. +{
  191349. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191350. + u32 tctrl = 0;
  191351. +
  191352. + if (priv->ndev->features & NETIF_F_IP_CSUM)
  191353. tctrl |= TCTRL_INIT_CSUM;
  191354. if (priv->prio_sched_en)
  191355. @@ -408,30 +412,51 @@
  191356. gfar_write(&regs->tr47wt, DEFAULT_WRRS_WEIGHT);
  191357. }
  191358. - gfar_write(&regs->tctrl, tctrl);
  191359. + if (priv->ndev->features & NETIF_F_HW_VLAN_CTAG_TX)
  191360. + tctrl |= TCTRL_VLINS;
  191361. - /* Set the extraction length and index */
  191362. - attrs = ATTRELI_EL(priv->rx_stash_size) |
  191363. - ATTRELI_EI(priv->rx_stash_index);
  191364. + gfar_write(&regs->tctrl, tctrl);
  191365. +}
  191366. - gfar_write(&regs->attreli, attrs);
  191367. +static void gfar_configure_coalescing(struct gfar_private *priv,
  191368. + unsigned long tx_mask, unsigned long rx_mask)
  191369. +{
  191370. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191371. + u32 __iomem *baddr;
  191372. - /* Start with defaults, and add stashing or locking
  191373. - * depending on the approprate variables
  191374. - */
  191375. - attrs = ATTR_INIT_SETTINGS;
  191376. + if (priv->mode == MQ_MG_MODE) {
  191377. + int i = 0;
  191378. - if (priv->bd_stash_en)
  191379. - attrs |= ATTR_BDSTASH;
  191380. + baddr = &regs->txic0;
  191381. + for_each_set_bit(i, &tx_mask, priv->num_tx_queues) {
  191382. + gfar_write(baddr + i, 0);
  191383. + if (likely(priv->tx_queue[i]->txcoalescing))
  191384. + gfar_write(baddr + i, priv->tx_queue[i]->txic);
  191385. + }
  191386. - if (priv->rx_stash_size != 0)
  191387. - attrs |= ATTR_BUFSTASH;
  191388. + baddr = &regs->rxic0;
  191389. + for_each_set_bit(i, &rx_mask, priv->num_rx_queues) {
  191390. + gfar_write(baddr + i, 0);
  191391. + if (likely(priv->rx_queue[i]->rxcoalescing))
  191392. + gfar_write(baddr + i, priv->rx_queue[i]->rxic);
  191393. + }
  191394. + } else {
  191395. + /* Backward compatible case -- even if we enable
  191396. + * multiple queues, there's only single reg to program
  191397. + */
  191398. + gfar_write(&regs->txic, 0);
  191399. + if (likely(priv->tx_queue[0]->txcoalescing))
  191400. + gfar_write(&regs->txic, priv->tx_queue[0]->txic);
  191401. - gfar_write(&regs->attr, attrs);
  191402. + gfar_write(&regs->rxic, 0);
  191403. + if (unlikely(priv->rx_queue[0]->rxcoalescing))
  191404. + gfar_write(&regs->rxic, priv->rx_queue[0]->rxic);
  191405. + }
  191406. +}
  191407. - gfar_write(&regs->fifo_tx_thr, priv->fifo_threshold);
  191408. - gfar_write(&regs->fifo_tx_starve, priv->fifo_starve);
  191409. - gfar_write(&regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
  191410. +void gfar_configure_coalescing_all(struct gfar_private *priv)
  191411. +{
  191412. + gfar_configure_coalescing(priv, 0xFF, 0xFF);
  191413. }
  191414. static struct net_device_stats *gfar_get_stats(struct net_device *dev)
  191415. @@ -479,12 +504,27 @@
  191416. #endif
  191417. };
  191418. -void lock_rx_qs(struct gfar_private *priv)
  191419. +static void gfar_ints_disable(struct gfar_private *priv)
  191420. {
  191421. int i;
  191422. + for (i = 0; i < priv->num_grps; i++) {
  191423. + struct gfar __iomem *regs = priv->gfargrp[i].regs;
  191424. + /* Clear IEVENT */
  191425. + gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
  191426. - for (i = 0; i < priv->num_rx_queues; i++)
  191427. - spin_lock(&priv->rx_queue[i]->rxlock);
  191428. + /* Initialize IMASK */
  191429. + gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  191430. + }
  191431. +}
  191432. +
  191433. +static void gfar_ints_enable(struct gfar_private *priv)
  191434. +{
  191435. + int i;
  191436. + for (i = 0; i < priv->num_grps; i++) {
  191437. + struct gfar __iomem *regs = priv->gfargrp[i].regs;
  191438. + /* Unmask the interrupts we look for */
  191439. + gfar_write(&regs->imask, IMASK_DEFAULT);
  191440. + }
  191441. }
  191442. void lock_tx_qs(struct gfar_private *priv)
  191443. @@ -495,23 +535,50 @@
  191444. spin_lock(&priv->tx_queue[i]->txlock);
  191445. }
  191446. -void unlock_rx_qs(struct gfar_private *priv)
  191447. +void unlock_tx_qs(struct gfar_private *priv)
  191448. {
  191449. int i;
  191450. - for (i = 0; i < priv->num_rx_queues; i++)
  191451. - spin_unlock(&priv->rx_queue[i]->rxlock);
  191452. + for (i = 0; i < priv->num_tx_queues; i++)
  191453. + spin_unlock(&priv->tx_queue[i]->txlock);
  191454. }
  191455. -void unlock_tx_qs(struct gfar_private *priv)
  191456. +static int gfar_alloc_tx_queues(struct gfar_private *priv)
  191457. {
  191458. int i;
  191459. - for (i = 0; i < priv->num_tx_queues; i++)
  191460. - spin_unlock(&priv->tx_queue[i]->txlock);
  191461. + for (i = 0; i < priv->num_tx_queues; i++) {
  191462. + priv->tx_queue[i] = kzalloc(sizeof(struct gfar_priv_tx_q),
  191463. + GFP_KERNEL);
  191464. + if (!priv->tx_queue[i])
  191465. + return -ENOMEM;
  191466. +
  191467. + priv->tx_queue[i]->tx_skbuff = NULL;
  191468. + priv->tx_queue[i]->qindex = i;
  191469. + priv->tx_queue[i]->dev = priv->ndev;
  191470. + spin_lock_init(&(priv->tx_queue[i]->txlock));
  191471. + }
  191472. + return 0;
  191473. +}
  191474. +
  191475. +static int gfar_alloc_rx_queues(struct gfar_private *priv)
  191476. +{
  191477. + int i;
  191478. +
  191479. + for (i = 0; i < priv->num_rx_queues; i++) {
  191480. + priv->rx_queue[i] = kzalloc(sizeof(struct gfar_priv_rx_q),
  191481. + GFP_KERNEL);
  191482. + if (!priv->rx_queue[i])
  191483. + return -ENOMEM;
  191484. +
  191485. + priv->rx_queue[i]->rx_skbuff = NULL;
  191486. + priv->rx_queue[i]->qindex = i;
  191487. + priv->rx_queue[i]->dev = priv->ndev;
  191488. + }
  191489. + return 0;
  191490. }
  191491. -static void free_tx_pointers(struct gfar_private *priv)
  191492. +static void gfar_free_tx_queues(struct gfar_private *priv)
  191493. {
  191494. int i;
  191495. @@ -519,7 +586,7 @@
  191496. kfree(priv->tx_queue[i]);
  191497. }
  191498. -static void free_rx_pointers(struct gfar_private *priv)
  191499. +static void gfar_free_rx_queues(struct gfar_private *priv)
  191500. {
  191501. int i;
  191502. @@ -553,23 +620,26 @@
  191503. {
  191504. int i;
  191505. - for (i = 0; i < priv->num_grps; i++)
  191506. - napi_disable(&priv->gfargrp[i].napi);
  191507. + for (i = 0; i < priv->num_grps; i++) {
  191508. + napi_disable(&priv->gfargrp[i].napi_rx);
  191509. + napi_disable(&priv->gfargrp[i].napi_tx);
  191510. + }
  191511. }
  191512. static void enable_napi(struct gfar_private *priv)
  191513. {
  191514. int i;
  191515. - for (i = 0; i < priv->num_grps; i++)
  191516. - napi_enable(&priv->gfargrp[i].napi);
  191517. + for (i = 0; i < priv->num_grps; i++) {
  191518. + napi_enable(&priv->gfargrp[i].napi_rx);
  191519. + napi_enable(&priv->gfargrp[i].napi_tx);
  191520. + }
  191521. }
  191522. static int gfar_parse_group(struct device_node *np,
  191523. struct gfar_private *priv, const char *model)
  191524. {
  191525. struct gfar_priv_grp *grp = &priv->gfargrp[priv->num_grps];
  191526. - u32 *queue_mask;
  191527. int i;
  191528. for (i = 0; i < GFAR_NUM_IRQS; i++) {
  191529. @@ -598,16 +668,52 @@
  191530. grp->priv = priv;
  191531. spin_lock_init(&grp->grplock);
  191532. if (priv->mode == MQ_MG_MODE) {
  191533. - queue_mask = (u32 *)of_get_property(np, "fsl,rx-bit-map", NULL);
  191534. - grp->rx_bit_map = queue_mask ?
  191535. - *queue_mask : (DEFAULT_MAPPING >> priv->num_grps);
  191536. - queue_mask = (u32 *)of_get_property(np, "fsl,tx-bit-map", NULL);
  191537. - grp->tx_bit_map = queue_mask ?
  191538. - *queue_mask : (DEFAULT_MAPPING >> priv->num_grps);
  191539. + u32 *rxq_mask, *txq_mask;
  191540. + rxq_mask = (u32 *)of_get_property(np, "fsl,rx-bit-map", NULL);
  191541. + txq_mask = (u32 *)of_get_property(np, "fsl,tx-bit-map", NULL);
  191542. +
  191543. + if (priv->poll_mode == GFAR_SQ_POLLING) {
  191544. + /* One Q per interrupt group: Q0 to G0, Q1 to G1 */
  191545. + grp->rx_bit_map = (DEFAULT_MAPPING >> priv->num_grps);
  191546. + grp->tx_bit_map = (DEFAULT_MAPPING >> priv->num_grps);
  191547. + } else { /* GFAR_MQ_POLLING */
  191548. + grp->rx_bit_map = rxq_mask ?
  191549. + *rxq_mask : (DEFAULT_MAPPING >> priv->num_grps);
  191550. + grp->tx_bit_map = txq_mask ?
  191551. + *txq_mask : (DEFAULT_MAPPING >> priv->num_grps);
  191552. + }
  191553. } else {
  191554. grp->rx_bit_map = 0xFF;
  191555. grp->tx_bit_map = 0xFF;
  191556. }
  191557. +
  191558. + /* bit_map's MSB is q0 (from q0 to q7) but, for_each_set_bit parses
  191559. + * right to left, so we need to revert the 8 bits to get the q index
  191560. + */
  191561. + grp->rx_bit_map = bitrev8(grp->rx_bit_map);
  191562. + grp->tx_bit_map = bitrev8(grp->tx_bit_map);
  191563. +
  191564. + /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values,
  191565. + * also assign queues to groups
  191566. + */
  191567. + for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) {
  191568. + if (!grp->rx_queue)
  191569. + grp->rx_queue = priv->rx_queue[i];
  191570. + grp->num_rx_queues++;
  191571. + grp->rstat |= (RSTAT_CLEAR_RHALT >> i);
  191572. + priv->rqueue |= ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
  191573. + priv->rx_queue[i]->grp = grp;
  191574. + }
  191575. +
  191576. + for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) {
  191577. + if (!grp->tx_queue)
  191578. + grp->tx_queue = priv->tx_queue[i];
  191579. + grp->num_tx_queues++;
  191580. + grp->tstat |= (TSTAT_CLEAR_THALT >> i);
  191581. + priv->tqueue |= (TQUEUE_EN0 >> i);
  191582. + priv->tx_queue[i]->grp = grp;
  191583. + }
  191584. +
  191585. priv->num_grps++;
  191586. return 0;
  191587. @@ -628,13 +734,45 @@
  191588. const u32 *stash_idx;
  191589. unsigned int num_tx_qs, num_rx_qs;
  191590. u32 *tx_queues, *rx_queues;
  191591. + unsigned short mode, poll_mode;
  191592. if (!np || !of_device_is_available(np))
  191593. return -ENODEV;
  191594. - /* parse the num of tx and rx queues */
  191595. + if (of_device_is_compatible(np, "fsl,etsec2")) {
  191596. + mode = MQ_MG_MODE;
  191597. + poll_mode = GFAR_SQ_POLLING;
  191598. + } else {
  191599. + mode = SQ_SG_MODE;
  191600. + poll_mode = GFAR_SQ_POLLING;
  191601. + }
  191602. +
  191603. + /* parse the num of HW tx and rx queues */
  191604. tx_queues = (u32 *)of_get_property(np, "fsl,num_tx_queues", NULL);
  191605. - num_tx_qs = tx_queues ? *tx_queues : 1;
  191606. + rx_queues = (u32 *)of_get_property(np, "fsl,num_rx_queues", NULL);
  191607. +
  191608. + if (mode == SQ_SG_MODE) {
  191609. + num_tx_qs = 1;
  191610. + num_rx_qs = 1;
  191611. + } else { /* MQ_MG_MODE */
  191612. + /* get the actual number of supported groups */
  191613. + unsigned int num_grps = of_get_available_child_count(np);
  191614. +
  191615. + if (num_grps == 0 || num_grps > MAXGROUPS) {
  191616. + dev_err(&ofdev->dev, "Invalid # of int groups(%d)\n",
  191617. + num_grps);
  191618. + pr_err("Cannot do alloc_etherdev, aborting\n");
  191619. + return -EINVAL;
  191620. + }
  191621. +
  191622. + if (poll_mode == GFAR_SQ_POLLING) {
  191623. + num_tx_qs = num_grps; /* one txq per int group */
  191624. + num_rx_qs = num_grps; /* one rxq per int group */
  191625. + } else { /* GFAR_MQ_POLLING */
  191626. + num_tx_qs = tx_queues ? *tx_queues : 1;
  191627. + num_rx_qs = rx_queues ? *rx_queues : 1;
  191628. + }
  191629. + }
  191630. if (num_tx_qs > MAX_TX_QS) {
  191631. pr_err("num_tx_qs(=%d) greater than MAX_TX_QS(=%d)\n",
  191632. @@ -643,9 +781,6 @@
  191633. return -EINVAL;
  191634. }
  191635. - rx_queues = (u32 *)of_get_property(np, "fsl,num_rx_queues", NULL);
  191636. - num_rx_qs = rx_queues ? *rx_queues : 1;
  191637. -
  191638. if (num_rx_qs > MAX_RX_QS) {
  191639. pr_err("num_rx_qs(=%d) greater than MAX_RX_QS(=%d)\n",
  191640. num_rx_qs, MAX_RX_QS);
  191641. @@ -661,10 +796,20 @@
  191642. priv = netdev_priv(dev);
  191643. priv->ndev = dev;
  191644. + priv->mode = mode;
  191645. + priv->poll_mode = poll_mode;
  191646. +
  191647. priv->num_tx_queues = num_tx_qs;
  191648. netif_set_real_num_rx_queues(dev, num_rx_qs);
  191649. priv->num_rx_queues = num_rx_qs;
  191650. - priv->num_grps = 0x0;
  191651. +
  191652. + err = gfar_alloc_tx_queues(priv);
  191653. + if (err)
  191654. + goto tx_alloc_failed;
  191655. +
  191656. + err = gfar_alloc_rx_queues(priv);
  191657. + if (err)
  191658. + goto rx_alloc_failed;
  191659. /* Init Rx queue filer rule set linked list */
  191660. INIT_LIST_HEAD(&priv->rx_list.list);
  191661. @@ -677,52 +822,18 @@
  191662. priv->gfargrp[i].regs = NULL;
  191663. /* Parse and initialize group specific information */
  191664. - if (of_device_is_compatible(np, "fsl,etsec2")) {
  191665. - priv->mode = MQ_MG_MODE;
  191666. + if (priv->mode == MQ_MG_MODE) {
  191667. for_each_child_of_node(np, child) {
  191668. err = gfar_parse_group(child, priv, model);
  191669. if (err)
  191670. goto err_grp_init;
  191671. }
  191672. - } else {
  191673. - priv->mode = SQ_SG_MODE;
  191674. + } else { /* SQ_SG_MODE */
  191675. err = gfar_parse_group(np, priv, model);
  191676. if (err)
  191677. goto err_grp_init;
  191678. }
  191679. - for (i = 0; i < priv->num_tx_queues; i++)
  191680. - priv->tx_queue[i] = NULL;
  191681. - for (i = 0; i < priv->num_rx_queues; i++)
  191682. - priv->rx_queue[i] = NULL;
  191683. -
  191684. - for (i = 0; i < priv->num_tx_queues; i++) {
  191685. - priv->tx_queue[i] = kzalloc(sizeof(struct gfar_priv_tx_q),
  191686. - GFP_KERNEL);
  191687. - if (!priv->tx_queue[i]) {
  191688. - err = -ENOMEM;
  191689. - goto tx_alloc_failed;
  191690. - }
  191691. - priv->tx_queue[i]->tx_skbuff = NULL;
  191692. - priv->tx_queue[i]->qindex = i;
  191693. - priv->tx_queue[i]->dev = dev;
  191694. - spin_lock_init(&(priv->tx_queue[i]->txlock));
  191695. - }
  191696. -
  191697. - for (i = 0; i < priv->num_rx_queues; i++) {
  191698. - priv->rx_queue[i] = kzalloc(sizeof(struct gfar_priv_rx_q),
  191699. - GFP_KERNEL);
  191700. - if (!priv->rx_queue[i]) {
  191701. - err = -ENOMEM;
  191702. - goto rx_alloc_failed;
  191703. - }
  191704. - priv->rx_queue[i]->rx_skbuff = NULL;
  191705. - priv->rx_queue[i]->qindex = i;
  191706. - priv->rx_queue[i]->dev = dev;
  191707. - spin_lock_init(&(priv->rx_queue[i]->rxlock));
  191708. - }
  191709. -
  191710. -
  191711. stash = of_get_property(np, "bd-stash", NULL);
  191712. if (stash) {
  191713. @@ -749,17 +860,16 @@
  191714. memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
  191715. if (model && !strcasecmp(model, "TSEC"))
  191716. - priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
  191717. + priv->device_flags |= FSL_GIANFAR_DEV_HAS_GIGABIT |
  191718. FSL_GIANFAR_DEV_HAS_COALESCE |
  191719. FSL_GIANFAR_DEV_HAS_RMON |
  191720. FSL_GIANFAR_DEV_HAS_MULTI_INTR;
  191721. if (model && !strcasecmp(model, "eTSEC"))
  191722. - priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
  191723. + priv->device_flags |= FSL_GIANFAR_DEV_HAS_GIGABIT |
  191724. FSL_GIANFAR_DEV_HAS_COALESCE |
  191725. FSL_GIANFAR_DEV_HAS_RMON |
  191726. FSL_GIANFAR_DEV_HAS_MULTI_INTR |
  191727. - FSL_GIANFAR_DEV_HAS_PADDING |
  191728. FSL_GIANFAR_DEV_HAS_CSUM |
  191729. FSL_GIANFAR_DEV_HAS_VLAN |
  191730. FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
  191731. @@ -779,17 +889,28 @@
  191732. priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
  191733. + /* In the case of a fixed PHY, the DT node associated
  191734. + * to the PHY is the Ethernet MAC DT node.
  191735. + */
  191736. + if (of_phy_is_fixed_link(np)) {
  191737. + err = of_phy_register_fixed_link(np);
  191738. + if (err)
  191739. + goto err_grp_init;
  191740. +
  191741. + priv->phy_node = np;
  191742. + }
  191743. +
  191744. /* Find the TBI PHY. If it's not there, we don't support SGMII */
  191745. priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
  191746. return 0;
  191747. -rx_alloc_failed:
  191748. - free_rx_pointers(priv);
  191749. -tx_alloc_failed:
  191750. - free_tx_pointers(priv);
  191751. err_grp_init:
  191752. unmap_group_regs(priv);
  191753. +rx_alloc_failed:
  191754. + gfar_free_rx_queues(priv);
  191755. +tx_alloc_failed:
  191756. + gfar_free_tx_queues(priv);
  191757. free_gfar_dev(priv);
  191758. return err;
  191759. }
  191760. @@ -822,18 +943,16 @@
  191761. switch (config.rx_filter) {
  191762. case HWTSTAMP_FILTER_NONE:
  191763. if (priv->hwts_rx_en) {
  191764. - stop_gfar(netdev);
  191765. priv->hwts_rx_en = 0;
  191766. - startup_gfar(netdev);
  191767. + reset_gfar(netdev);
  191768. }
  191769. break;
  191770. default:
  191771. if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER))
  191772. return -ERANGE;
  191773. if (!priv->hwts_rx_en) {
  191774. - stop_gfar(netdev);
  191775. priv->hwts_rx_en = 1;
  191776. - startup_gfar(netdev);
  191777. + reset_gfar(netdev);
  191778. }
  191779. config.rx_filter = HWTSTAMP_FILTER_ALL;
  191780. break;
  191781. @@ -875,19 +994,6 @@
  191782. return phy_mii_ioctl(priv->phydev, rq, cmd);
  191783. }
  191784. -static unsigned int reverse_bitmap(unsigned int bit_map, unsigned int max_qs)
  191785. -{
  191786. - unsigned int new_bit_map = 0x0;
  191787. - int mask = 0x1 << (max_qs - 1), i;
  191788. -
  191789. - for (i = 0; i < max_qs; i++) {
  191790. - if (bit_map & mask)
  191791. - new_bit_map = new_bit_map + (1 << i);
  191792. - mask = mask >> 0x1;
  191793. - }
  191794. - return new_bit_map;
  191795. -}
  191796. -
  191797. static u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar,
  191798. u32 class)
  191799. {
  191800. @@ -1005,100 +1111,141 @@
  191801. priv->errata);
  191802. }
  191803. -/* Set up the ethernet device structure, private data,
  191804. - * and anything else we need before we start
  191805. - */
  191806. -static int gfar_probe(struct platform_device *ofdev)
  191807. +void gfar_mac_reset(struct gfar_private *priv)
  191808. {
  191809. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191810. u32 tempval;
  191811. - struct net_device *dev = NULL;
  191812. - struct gfar_private *priv = NULL;
  191813. - struct gfar __iomem *regs = NULL;
  191814. - int err = 0, i, grp_idx = 0;
  191815. - u32 rstat = 0, tstat = 0, rqueue = 0, tqueue = 0;
  191816. - u32 isrg = 0;
  191817. - u32 __iomem *baddr;
  191818. -
  191819. - err = gfar_of_init(ofdev, &dev);
  191820. -
  191821. - if (err)
  191822. - return err;
  191823. -
  191824. - priv = netdev_priv(dev);
  191825. - priv->ndev = dev;
  191826. - priv->ofdev = ofdev;
  191827. - priv->dev = &ofdev->dev;
  191828. - SET_NETDEV_DEV(dev, &ofdev->dev);
  191829. -
  191830. - spin_lock_init(&priv->bflock);
  191831. - INIT_WORK(&priv->reset_task, gfar_reset_task);
  191832. -
  191833. - platform_set_drvdata(ofdev, priv);
  191834. - regs = priv->gfargrp[0].regs;
  191835. -
  191836. - gfar_detect_errata(priv);
  191837. -
  191838. - /* Stop the DMA engine now, in case it was running before
  191839. - * (The firmware could have used it, and left it running).
  191840. - */
  191841. - gfar_halt(dev);
  191842. /* Reset MAC layer */
  191843. gfar_write(&regs->maccfg1, MACCFG1_SOFT_RESET);
  191844. /* We need to delay at least 3 TX clocks */
  191845. - udelay(2);
  191846. + udelay(3);
  191847. - tempval = 0;
  191848. - if (!priv->pause_aneg_en && priv->tx_pause_en)
  191849. - tempval |= MACCFG1_TX_FLOW;
  191850. - if (!priv->pause_aneg_en && priv->rx_pause_en)
  191851. - tempval |= MACCFG1_RX_FLOW;
  191852. /* the soft reset bit is not self-resetting, so we need to
  191853. * clear it before resuming normal operation
  191854. */
  191855. - gfar_write(&regs->maccfg1, tempval);
  191856. + gfar_write(&regs->maccfg1, 0);
  191857. - /* Initialize MACCFG2. */
  191858. - tempval = MACCFG2_INIT_SETTINGS;
  191859. - if (gfar_has_errata(priv, GFAR_ERRATA_74))
  191860. - tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK;
  191861. - gfar_write(&regs->maccfg2, tempval);
  191862. + udelay(3);
  191863. - /* Initialize ECNTRL */
  191864. - gfar_write(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
  191865. + /* Compute rx_buff_size based on config flags */
  191866. + gfar_rx_buff_size_config(priv);
  191867. - /* Set the dev->base_addr to the gfar reg region */
  191868. - dev->base_addr = (unsigned long) regs;
  191869. + /* Initialize the max receive frame/buffer lengths */
  191870. + gfar_write(&regs->maxfrm, priv->rx_buffer_size);
  191871. + gfar_write(&regs->mrblr, priv->rx_buffer_size);
  191872. - /* Fill in the dev structure */
  191873. - dev->watchdog_timeo = TX_TIMEOUT;
  191874. - dev->mtu = 1500;
  191875. - dev->netdev_ops = &gfar_netdev_ops;
  191876. - dev->ethtool_ops = &gfar_ethtool_ops;
  191877. + /* Initialize the Minimum Frame Length Register */
  191878. + gfar_write(&regs->minflr, MINFLR_INIT_SETTINGS);
  191879. - /* Register for napi ...We are registering NAPI for each grp */
  191880. - if (priv->mode == SQ_SG_MODE)
  191881. - netif_napi_add(dev, &priv->gfargrp[0].napi, gfar_poll_sq,
  191882. - GFAR_DEV_WEIGHT);
  191883. - else
  191884. - for (i = 0; i < priv->num_grps; i++)
  191885. - netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll,
  191886. - GFAR_DEV_WEIGHT);
  191887. + /* Initialize MACCFG2. */
  191888. + tempval = MACCFG2_INIT_SETTINGS;
  191889. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
  191890. - dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
  191891. - NETIF_F_RXCSUM;
  191892. - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
  191893. - NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
  191894. - }
  191895. + /* If the mtu is larger than the max size for standard
  191896. + * ethernet frames (ie, a jumbo frame), then set maccfg2
  191897. + * to allow huge frames, and to check the length
  191898. + */
  191899. + if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE ||
  191900. + gfar_has_errata(priv, GFAR_ERRATA_74))
  191901. + tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK;
  191902. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
  191903. - dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
  191904. - NETIF_F_HW_VLAN_CTAG_RX;
  191905. - dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
  191906. + gfar_write(&regs->maccfg2, tempval);
  191907. +
  191908. + /* Clear mac addr hash registers */
  191909. + gfar_write(&regs->igaddr0, 0);
  191910. + gfar_write(&regs->igaddr1, 0);
  191911. + gfar_write(&regs->igaddr2, 0);
  191912. + gfar_write(&regs->igaddr3, 0);
  191913. + gfar_write(&regs->igaddr4, 0);
  191914. + gfar_write(&regs->igaddr5, 0);
  191915. + gfar_write(&regs->igaddr6, 0);
  191916. + gfar_write(&regs->igaddr7, 0);
  191917. +
  191918. + gfar_write(&regs->gaddr0, 0);
  191919. + gfar_write(&regs->gaddr1, 0);
  191920. + gfar_write(&regs->gaddr2, 0);
  191921. + gfar_write(&regs->gaddr3, 0);
  191922. + gfar_write(&regs->gaddr4, 0);
  191923. + gfar_write(&regs->gaddr5, 0);
  191924. + gfar_write(&regs->gaddr6, 0);
  191925. + gfar_write(&regs->gaddr7, 0);
  191926. +
  191927. + if (priv->extended_hash)
  191928. + gfar_clear_exact_match(priv->ndev);
  191929. +
  191930. + gfar_mac_rx_config(priv);
  191931. +
  191932. + gfar_mac_tx_config(priv);
  191933. +
  191934. + gfar_set_mac_address(priv->ndev);
  191935. +
  191936. + gfar_set_multi(priv->ndev);
  191937. +
  191938. + /* clear ievent and imask before configuring coalescing */
  191939. + gfar_ints_disable(priv);
  191940. +
  191941. + /* Configure the coalescing support */
  191942. + gfar_configure_coalescing_all(priv);
  191943. +}
  191944. +
  191945. +static void gfar_hw_init(struct gfar_private *priv)
  191946. +{
  191947. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191948. + u32 attrs;
  191949. +
  191950. + /* Stop the DMA engine now, in case it was running before
  191951. + * (The firmware could have used it, and left it running).
  191952. + */
  191953. + gfar_halt(priv);
  191954. +
  191955. + gfar_mac_reset(priv);
  191956. +
  191957. + /* Zero out the rmon mib registers if it has them */
  191958. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
  191959. + memset_io(&(regs->rmon), 0, sizeof(struct rmon_mib));
  191960. +
  191961. + /* Mask off the CAM interrupts */
  191962. + gfar_write(&regs->rmon.cam1, 0xffffffff);
  191963. + gfar_write(&regs->rmon.cam2, 0xffffffff);
  191964. }
  191965. + /* Initialize ECNTRL */
  191966. + gfar_write(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
  191967. +
  191968. + /* Set the extraction length and index */
  191969. + attrs = ATTRELI_EL(priv->rx_stash_size) |
  191970. + ATTRELI_EI(priv->rx_stash_index);
  191971. +
  191972. + gfar_write(&regs->attreli, attrs);
  191973. +
  191974. + /* Start with defaults, and add stashing
  191975. + * depending on driver parameters
  191976. + */
  191977. + attrs = ATTR_INIT_SETTINGS;
  191978. +
  191979. + if (priv->bd_stash_en)
  191980. + attrs |= ATTR_BDSTASH;
  191981. +
  191982. + if (priv->rx_stash_size != 0)
  191983. + attrs |= ATTR_BUFSTASH;
  191984. +
  191985. + gfar_write(&regs->attr, attrs);
  191986. +
  191987. + /* FIFO configs */
  191988. + gfar_write(&regs->fifo_tx_thr, DEFAULT_FIFO_TX_THR);
  191989. + gfar_write(&regs->fifo_tx_starve, DEFAULT_FIFO_TX_STARVE);
  191990. + gfar_write(&regs->fifo_tx_starve_shutoff, DEFAULT_FIFO_TX_STARVE_OFF);
  191991. +
  191992. + /* Program the interrupt steering regs, only for MG devices */
  191993. + if (priv->num_grps > 1)
  191994. + gfar_write_isrg(priv);
  191995. +}
  191996. +
  191997. +static void gfar_init_addr_hash_table(struct gfar_private *priv)
  191998. +{
  191999. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  192000. +
  192001. if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
  192002. priv->extended_hash = 1;
  192003. priv->hash_width = 9;
  192004. @@ -1133,68 +1280,81 @@
  192005. priv->hash_regs[6] = &regs->gaddr6;
  192006. priv->hash_regs[7] = &regs->gaddr7;
  192007. }
  192008. +}
  192009. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_PADDING)
  192010. - priv->padding = DEFAULT_PADDING;
  192011. - else
  192012. - priv->padding = 0;
  192013. +/* Set up the ethernet device structure, private data,
  192014. + * and anything else we need before we start
  192015. + */
  192016. +static int gfar_probe(struct platform_device *ofdev)
  192017. +{
  192018. + struct net_device *dev = NULL;
  192019. + struct gfar_private *priv = NULL;
  192020. + int err = 0, i;
  192021. - if (dev->features & NETIF_F_IP_CSUM ||
  192022. - priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
  192023. - dev->needed_headroom = GMAC_FCB_LEN;
  192024. + err = gfar_of_init(ofdev, &dev);
  192025. - /* Program the isrg regs only if number of grps > 1 */
  192026. - if (priv->num_grps > 1) {
  192027. - baddr = &regs->isrg0;
  192028. - for (i = 0; i < priv->num_grps; i++) {
  192029. - isrg |= (priv->gfargrp[i].rx_bit_map << ISRG_SHIFT_RX);
  192030. - isrg |= (priv->gfargrp[i].tx_bit_map << ISRG_SHIFT_TX);
  192031. - gfar_write(baddr, isrg);
  192032. - baddr++;
  192033. - isrg = 0x0;
  192034. + if (err)
  192035. + return err;
  192036. +
  192037. + priv = netdev_priv(dev);
  192038. + priv->ndev = dev;
  192039. + priv->ofdev = ofdev;
  192040. + priv->dev = &ofdev->dev;
  192041. + SET_NETDEV_DEV(dev, &ofdev->dev);
  192042. +
  192043. + spin_lock_init(&priv->bflock);
  192044. + INIT_WORK(&priv->reset_task, gfar_reset_task);
  192045. +
  192046. + platform_set_drvdata(ofdev, priv);
  192047. +
  192048. + gfar_detect_errata(priv);
  192049. +
  192050. + /* Set the dev->base_addr to the gfar reg region */
  192051. + dev->base_addr = (unsigned long) priv->gfargrp[0].regs;
  192052. +
  192053. + /* Fill in the dev structure */
  192054. + dev->watchdog_timeo = TX_TIMEOUT;
  192055. + dev->mtu = 1500;
  192056. + dev->netdev_ops = &gfar_netdev_ops;
  192057. + dev->ethtool_ops = &gfar_ethtool_ops;
  192058. +
  192059. + /* Register for napi ...We are registering NAPI for each grp */
  192060. + for (i = 0; i < priv->num_grps; i++) {
  192061. + if (priv->poll_mode == GFAR_SQ_POLLING) {
  192062. + netif_napi_add(dev, &priv->gfargrp[i].napi_rx,
  192063. + gfar_poll_rx_sq, GFAR_DEV_WEIGHT);
  192064. + netif_napi_add(dev, &priv->gfargrp[i].napi_tx,
  192065. + gfar_poll_tx_sq, 2);
  192066. + } else {
  192067. + netif_napi_add(dev, &priv->gfargrp[i].napi_rx,
  192068. + gfar_poll_rx, GFAR_DEV_WEIGHT);
  192069. + netif_napi_add(dev, &priv->gfargrp[i].napi_tx,
  192070. + gfar_poll_tx, 2);
  192071. }
  192072. }
  192073. - /* Need to reverse the bit maps as bit_map's MSB is q0
  192074. - * but, for_each_set_bit parses from right to left, which
  192075. - * basically reverses the queue numbers
  192076. - */
  192077. - for (i = 0; i< priv->num_grps; i++) {
  192078. - priv->gfargrp[i].tx_bit_map =
  192079. - reverse_bitmap(priv->gfargrp[i].tx_bit_map, MAX_TX_QS);
  192080. - priv->gfargrp[i].rx_bit_map =
  192081. - reverse_bitmap(priv->gfargrp[i].rx_bit_map, MAX_RX_QS);
  192082. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
  192083. + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
  192084. + NETIF_F_RXCSUM;
  192085. + dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
  192086. + NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
  192087. }
  192088. - /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values,
  192089. - * also assign queues to groups
  192090. - */
  192091. - for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
  192092. - priv->gfargrp[grp_idx].num_rx_queues = 0x0;
  192093. -
  192094. - for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
  192095. - priv->num_rx_queues) {
  192096. - priv->gfargrp[grp_idx].num_rx_queues++;
  192097. - priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx];
  192098. - rstat = rstat | (RSTAT_CLEAR_RHALT >> i);
  192099. - rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
  192100. - }
  192101. - priv->gfargrp[grp_idx].num_tx_queues = 0x0;
  192102. -
  192103. - for_each_set_bit(i, &priv->gfargrp[grp_idx].tx_bit_map,
  192104. - priv->num_tx_queues) {
  192105. - priv->gfargrp[grp_idx].num_tx_queues++;
  192106. - priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx];
  192107. - tstat = tstat | (TSTAT_CLEAR_THALT >> i);
  192108. - tqueue = tqueue | (TQUEUE_EN0 >> i);
  192109. - }
  192110. - priv->gfargrp[grp_idx].rstat = rstat;
  192111. - priv->gfargrp[grp_idx].tstat = tstat;
  192112. - rstat = tstat =0;
  192113. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
  192114. + dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
  192115. + NETIF_F_HW_VLAN_CTAG_RX;
  192116. + dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
  192117. }
  192118. - gfar_write(&regs->rqueue, rqueue);
  192119. - gfar_write(&regs->tqueue, tqueue);
  192120. + gfar_init_addr_hash_table(priv);
  192121. +
  192122. + /* Insert receive time stamps into padding alignment bytes */
  192123. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
  192124. + priv->padding = 8;
  192125. +
  192126. + if (dev->features & NETIF_F_IP_CSUM ||
  192127. + priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
  192128. + dev->needed_headroom = GMAC_FCB_LEN;
  192129. priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE;
  192130. @@ -1220,6 +1380,10 @@
  192131. if (priv->num_tx_queues == 1)
  192132. priv->prio_sched_en = 1;
  192133. + set_bit(GFAR_DOWN, &priv->state);
  192134. +
  192135. + gfar_hw_init(priv);
  192136. +
  192137. /* Carrier starts down, phylib will bring it up */
  192138. netif_carrier_off(dev);
  192139. @@ -1251,9 +1415,6 @@
  192140. /* Initialize the filer table */
  192141. gfar_init_filer_table(priv);
  192142. - /* Create all the sysfs files */
  192143. - gfar_init_sysfs(dev);
  192144. -
  192145. /* Print out the device info */
  192146. netdev_info(dev, "mac: %pM\n", dev->dev_addr);
  192147. @@ -1272,8 +1433,8 @@
  192148. register_fail:
  192149. unmap_group_regs(priv);
  192150. - free_tx_pointers(priv);
  192151. - free_rx_pointers(priv);
  192152. + gfar_free_rx_queues(priv);
  192153. + gfar_free_tx_queues(priv);
  192154. if (priv->phy_node)
  192155. of_node_put(priv->phy_node);
  192156. if (priv->tbi_node)
  192157. @@ -1293,6 +1454,8 @@
  192158. unregister_netdev(priv->ndev);
  192159. unmap_group_regs(priv);
  192160. + gfar_free_rx_queues(priv);
  192161. + gfar_free_tx_queues(priv);
  192162. free_gfar_dev(priv);
  192163. return 0;
  192164. @@ -1318,9 +1481,8 @@
  192165. local_irq_save(flags);
  192166. lock_tx_qs(priv);
  192167. - lock_rx_qs(priv);
  192168. - gfar_halt_nodisable(ndev);
  192169. + gfar_halt_nodisable(priv);
  192170. /* Disable Tx, and Rx if wake-on-LAN is disabled. */
  192171. tempval = gfar_read(&regs->maccfg1);
  192172. @@ -1332,7 +1494,6 @@
  192173. gfar_write(&regs->maccfg1, tempval);
  192174. - unlock_rx_qs(priv);
  192175. unlock_tx_qs(priv);
  192176. local_irq_restore(flags);
  192177. @@ -1378,15 +1539,13 @@
  192178. */
  192179. local_irq_save(flags);
  192180. lock_tx_qs(priv);
  192181. - lock_rx_qs(priv);
  192182. tempval = gfar_read(&regs->maccfg2);
  192183. tempval &= ~MACCFG2_MPEN;
  192184. gfar_write(&regs->maccfg2, tempval);
  192185. - gfar_start(ndev);
  192186. + gfar_start(priv);
  192187. - unlock_rx_qs(priv);
  192188. unlock_tx_qs(priv);
  192189. local_irq_restore(flags);
  192190. @@ -1413,10 +1572,11 @@
  192191. return -ENOMEM;
  192192. }
  192193. - init_registers(ndev);
  192194. - gfar_set_mac_address(ndev);
  192195. - gfar_init_mac(ndev);
  192196. - gfar_start(ndev);
  192197. + gfar_mac_reset(priv);
  192198. +
  192199. + gfar_init_tx_rx_base(priv);
  192200. +
  192201. + gfar_start(priv);
  192202. priv->oldlink = 0;
  192203. priv->oldspeed = 0;
  192204. @@ -1511,9 +1671,6 @@
  192205. priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0,
  192206. interface);
  192207. - if (!priv->phydev)
  192208. - priv->phydev = of_phy_connect_fixed_link(dev, &adjust_link,
  192209. - interface);
  192210. if (!priv->phydev) {
  192211. dev_err(&dev->dev, "could not attach to PHY\n");
  192212. return -ENODEV;
  192213. @@ -1574,57 +1731,6 @@
  192214. BMCR_SPEED1000);
  192215. }
  192216. -static void init_registers(struct net_device *dev)
  192217. -{
  192218. - struct gfar_private *priv = netdev_priv(dev);
  192219. - struct gfar __iomem *regs = NULL;
  192220. - int i;
  192221. -
  192222. - for (i = 0; i < priv->num_grps; i++) {
  192223. - regs = priv->gfargrp[i].regs;
  192224. - /* Clear IEVENT */
  192225. - gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
  192226. -
  192227. - /* Initialize IMASK */
  192228. - gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  192229. - }
  192230. -
  192231. - regs = priv->gfargrp[0].regs;
  192232. - /* Init hash registers to zero */
  192233. - gfar_write(&regs->igaddr0, 0);
  192234. - gfar_write(&regs->igaddr1, 0);
  192235. - gfar_write(&regs->igaddr2, 0);
  192236. - gfar_write(&regs->igaddr3, 0);
  192237. - gfar_write(&regs->igaddr4, 0);
  192238. - gfar_write(&regs->igaddr5, 0);
  192239. - gfar_write(&regs->igaddr6, 0);
  192240. - gfar_write(&regs->igaddr7, 0);
  192241. -
  192242. - gfar_write(&regs->gaddr0, 0);
  192243. - gfar_write(&regs->gaddr1, 0);
  192244. - gfar_write(&regs->gaddr2, 0);
  192245. - gfar_write(&regs->gaddr3, 0);
  192246. - gfar_write(&regs->gaddr4, 0);
  192247. - gfar_write(&regs->gaddr5, 0);
  192248. - gfar_write(&regs->gaddr6, 0);
  192249. - gfar_write(&regs->gaddr7, 0);
  192250. -
  192251. - /* Zero out the rmon mib registers if it has them */
  192252. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
  192253. - memset_io(&(regs->rmon), 0, sizeof (struct rmon_mib));
  192254. -
  192255. - /* Mask off the CAM interrupts */
  192256. - gfar_write(&regs->rmon.cam1, 0xffffffff);
  192257. - gfar_write(&regs->rmon.cam2, 0xffffffff);
  192258. - }
  192259. -
  192260. - /* Initialize the max receive buffer length */
  192261. - gfar_write(&regs->mrblr, priv->rx_buffer_size);
  192262. -
  192263. - /* Initialize the Minimum Frame Length Register */
  192264. - gfar_write(&regs->minflr, MINFLR_INIT_SETTINGS);
  192265. -}
  192266. -
  192267. static int __gfar_is_rx_idle(struct gfar_private *priv)
  192268. {
  192269. u32 res;
  192270. @@ -1648,23 +1754,13 @@
  192271. }
  192272. /* Halt the receive and transmit queues */
  192273. -static void gfar_halt_nodisable(struct net_device *dev)
  192274. +static void gfar_halt_nodisable(struct gfar_private *priv)
  192275. {
  192276. - struct gfar_private *priv = netdev_priv(dev);
  192277. - struct gfar __iomem *regs = NULL;
  192278. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  192279. u32 tempval;
  192280. - int i;
  192281. -
  192282. - for (i = 0; i < priv->num_grps; i++) {
  192283. - regs = priv->gfargrp[i].regs;
  192284. - /* Mask all interrupts */
  192285. - gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  192286. - /* Clear all interrupts */
  192287. - gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
  192288. - }
  192289. + gfar_ints_disable(priv);
  192290. - regs = priv->gfargrp[0].regs;
  192291. /* Stop the DMA, and wait for it to stop */
  192292. tempval = gfar_read(&regs->dmactrl);
  192293. if ((tempval & (DMACTRL_GRS | DMACTRL_GTS)) !=
  192294. @@ -1685,56 +1781,41 @@
  192295. }
  192296. /* Halt the receive and transmit queues */
  192297. -void gfar_halt(struct net_device *dev)
  192298. +void gfar_halt(struct gfar_private *priv)
  192299. {
  192300. - struct gfar_private *priv = netdev_priv(dev);
  192301. struct gfar __iomem *regs = priv->gfargrp[0].regs;
  192302. u32 tempval;
  192303. - gfar_halt_nodisable(dev);
  192304. + /* Dissable the Rx/Tx hw queues */
  192305. + gfar_write(&regs->rqueue, 0);
  192306. + gfar_write(&regs->tqueue, 0);
  192307. - /* Disable Rx and Tx */
  192308. + mdelay(10);
  192309. +
  192310. + gfar_halt_nodisable(priv);
  192311. +
  192312. + /* Disable Rx/Tx DMA */
  192313. tempval = gfar_read(&regs->maccfg1);
  192314. tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
  192315. gfar_write(&regs->maccfg1, tempval);
  192316. }
  192317. -static void free_grp_irqs(struct gfar_priv_grp *grp)
  192318. -{
  192319. - free_irq(gfar_irq(grp, TX)->irq, grp);
  192320. - free_irq(gfar_irq(grp, RX)->irq, grp);
  192321. - free_irq(gfar_irq(grp, ER)->irq, grp);
  192322. -}
  192323. -
  192324. void stop_gfar(struct net_device *dev)
  192325. {
  192326. struct gfar_private *priv = netdev_priv(dev);
  192327. - unsigned long flags;
  192328. - int i;
  192329. -
  192330. - phy_stop(priv->phydev);
  192331. + netif_tx_stop_all_queues(dev);
  192332. - /* Lock it down */
  192333. - local_irq_save(flags);
  192334. - lock_tx_qs(priv);
  192335. - lock_rx_qs(priv);
  192336. + smp_mb__before_clear_bit();
  192337. + set_bit(GFAR_DOWN, &priv->state);
  192338. + smp_mb__after_clear_bit();
  192339. - gfar_halt(dev);
  192340. + disable_napi(priv);
  192341. - unlock_rx_qs(priv);
  192342. - unlock_tx_qs(priv);
  192343. - local_irq_restore(flags);
  192344. + /* disable ints and gracefully shut down Rx/Tx DMA */
  192345. + gfar_halt(priv);
  192346. - /* Free the IRQs */
  192347. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
  192348. - for (i = 0; i < priv->num_grps; i++)
  192349. - free_grp_irqs(&priv->gfargrp[i]);
  192350. - } else {
  192351. - for (i = 0; i < priv->num_grps; i++)
  192352. - free_irq(gfar_irq(&priv->gfargrp[i], TX)->irq,
  192353. - &priv->gfargrp[i]);
  192354. - }
  192355. + phy_stop(priv->phydev);
  192356. free_skb_resources(priv);
  192357. }
  192358. @@ -1825,17 +1906,15 @@
  192359. priv->tx_queue[0]->tx_bd_dma_base);
  192360. }
  192361. -void gfar_start(struct net_device *dev)
  192362. +void gfar_start(struct gfar_private *priv)
  192363. {
  192364. - struct gfar_private *priv = netdev_priv(dev);
  192365. struct gfar __iomem *regs = priv->gfargrp[0].regs;
  192366. u32 tempval;
  192367. int i = 0;
  192368. - /* Enable Rx and Tx in MACCFG1 */
  192369. - tempval = gfar_read(&regs->maccfg1);
  192370. - tempval |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
  192371. - gfar_write(&regs->maccfg1, tempval);
  192372. + /* Enable Rx/Tx hw queues */
  192373. + gfar_write(&regs->rqueue, priv->rqueue);
  192374. + gfar_write(&regs->tqueue, priv->tqueue);
  192375. /* Initialize DMACTRL to have WWR and WOP */
  192376. tempval = gfar_read(&regs->dmactrl);
  192377. @@ -1852,52 +1931,23 @@
  192378. /* Clear THLT/RHLT, so that the DMA starts polling now */
  192379. gfar_write(&regs->tstat, priv->gfargrp[i].tstat);
  192380. gfar_write(&regs->rstat, priv->gfargrp[i].rstat);
  192381. - /* Unmask the interrupts we look for */
  192382. - gfar_write(&regs->imask, IMASK_DEFAULT);
  192383. }
  192384. - dev->trans_start = jiffies; /* prevent tx timeout */
  192385. -}
  192386. -
  192387. -static void gfar_configure_coalescing(struct gfar_private *priv,
  192388. - unsigned long tx_mask, unsigned long rx_mask)
  192389. -{
  192390. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  192391. - u32 __iomem *baddr;
  192392. + /* Enable Rx/Tx DMA */
  192393. + tempval = gfar_read(&regs->maccfg1);
  192394. + tempval |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
  192395. + gfar_write(&regs->maccfg1, tempval);
  192396. - if (priv->mode == MQ_MG_MODE) {
  192397. - int i = 0;
  192398. + gfar_ints_enable(priv);
  192399. - baddr = &regs->txic0;
  192400. - for_each_set_bit(i, &tx_mask, priv->num_tx_queues) {
  192401. - gfar_write(baddr + i, 0);
  192402. - if (likely(priv->tx_queue[i]->txcoalescing))
  192403. - gfar_write(baddr + i, priv->tx_queue[i]->txic);
  192404. - }
  192405. -
  192406. - baddr = &regs->rxic0;
  192407. - for_each_set_bit(i, &rx_mask, priv->num_rx_queues) {
  192408. - gfar_write(baddr + i, 0);
  192409. - if (likely(priv->rx_queue[i]->rxcoalescing))
  192410. - gfar_write(baddr + i, priv->rx_queue[i]->rxic);
  192411. - }
  192412. - } else {
  192413. - /* Backward compatible case -- even if we enable
  192414. - * multiple queues, there's only single reg to program
  192415. - */
  192416. - gfar_write(&regs->txic, 0);
  192417. - if (likely(priv->tx_queue[0]->txcoalescing))
  192418. - gfar_write(&regs->txic, priv->tx_queue[0]->txic);
  192419. -
  192420. - gfar_write(&regs->rxic, 0);
  192421. - if (unlikely(priv->rx_queue[0]->rxcoalescing))
  192422. - gfar_write(&regs->rxic, priv->rx_queue[0]->rxic);
  192423. - }
  192424. + priv->ndev->trans_start = jiffies; /* prevent tx timeout */
  192425. }
  192426. -void gfar_configure_coalescing_all(struct gfar_private *priv)
  192427. +static void free_grp_irqs(struct gfar_priv_grp *grp)
  192428. {
  192429. - gfar_configure_coalescing(priv, 0xFF, 0xFF);
  192430. + free_irq(gfar_irq(grp, TX)->irq, grp);
  192431. + free_irq(gfar_irq(grp, RX)->irq, grp);
  192432. + free_irq(gfar_irq(grp, ER)->irq, grp);
  192433. }
  192434. static int register_grp_irqs(struct gfar_priv_grp *grp)
  192435. @@ -1956,46 +2006,65 @@
  192436. }
  192437. -/* Bring the controller up and running */
  192438. -int startup_gfar(struct net_device *ndev)
  192439. +static void gfar_free_irq(struct gfar_private *priv)
  192440. {
  192441. - struct gfar_private *priv = netdev_priv(ndev);
  192442. - struct gfar __iomem *regs = NULL;
  192443. - int err, i, j;
  192444. + int i;
  192445. - for (i = 0; i < priv->num_grps; i++) {
  192446. - regs= priv->gfargrp[i].regs;
  192447. - gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  192448. + /* Free the IRQs */
  192449. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
  192450. + for (i = 0; i < priv->num_grps; i++)
  192451. + free_grp_irqs(&priv->gfargrp[i]);
  192452. + } else {
  192453. + for (i = 0; i < priv->num_grps; i++)
  192454. + free_irq(gfar_irq(&priv->gfargrp[i], TX)->irq,
  192455. + &priv->gfargrp[i]);
  192456. }
  192457. +}
  192458. - regs= priv->gfargrp[0].regs;
  192459. - err = gfar_alloc_skb_resources(ndev);
  192460. - if (err)
  192461. - return err;
  192462. -
  192463. - gfar_init_mac(ndev);
  192464. +static int gfar_request_irq(struct gfar_private *priv)
  192465. +{
  192466. + int err, i, j;
  192467. for (i = 0; i < priv->num_grps; i++) {
  192468. err = register_grp_irqs(&priv->gfargrp[i]);
  192469. if (err) {
  192470. for (j = 0; j < i; j++)
  192471. free_grp_irqs(&priv->gfargrp[j]);
  192472. - goto irq_fail;
  192473. + return err;
  192474. }
  192475. }
  192476. - /* Start the controller */
  192477. - gfar_start(ndev);
  192478. + return 0;
  192479. +}
  192480. +
  192481. +/* Bring the controller up and running */
  192482. +int startup_gfar(struct net_device *ndev)
  192483. +{
  192484. + struct gfar_private *priv = netdev_priv(ndev);
  192485. + int err;
  192486. +
  192487. + gfar_mac_reset(priv);
  192488. +
  192489. + err = gfar_alloc_skb_resources(ndev);
  192490. + if (err)
  192491. + return err;
  192492. +
  192493. + gfar_init_tx_rx_base(priv);
  192494. +
  192495. + smp_mb__before_clear_bit();
  192496. + clear_bit(GFAR_DOWN, &priv->state);
  192497. + smp_mb__after_clear_bit();
  192498. +
  192499. + /* Start Rx/Tx DMA and enable the interrupts */
  192500. + gfar_start(priv);
  192501. phy_start(priv->phydev);
  192502. - gfar_configure_coalescing_all(priv);
  192503. + enable_napi(priv);
  192504. - return 0;
  192505. + netif_tx_wake_all_queues(ndev);
  192506. -irq_fail:
  192507. - free_skb_resources(priv);
  192508. - return err;
  192509. + return 0;
  192510. }
  192511. /* Called when something needs to use the ethernet device
  192512. @@ -2006,27 +2075,17 @@
  192513. struct gfar_private *priv = netdev_priv(dev);
  192514. int err;
  192515. - enable_napi(priv);
  192516. -
  192517. - /* Initialize a bunch of registers */
  192518. - init_registers(dev);
  192519. -
  192520. - gfar_set_mac_address(dev);
  192521. -
  192522. err = init_phy(dev);
  192523. + if (err)
  192524. + return err;
  192525. - if (err) {
  192526. - disable_napi(priv);
  192527. + err = gfar_request_irq(priv);
  192528. + if (err)
  192529. return err;
  192530. - }
  192531. err = startup_gfar(dev);
  192532. - if (err) {
  192533. - disable_napi(priv);
  192534. + if (err)
  192535. return err;
  192536. - }
  192537. -
  192538. - netif_tx_start_all_queues(dev);
  192539. device_set_wakeup_enable(&dev->dev, priv->wol_en);
  192540. @@ -2152,13 +2211,13 @@
  192541. skb_new = skb_realloc_headroom(skb, fcb_len);
  192542. if (!skb_new) {
  192543. dev->stats.tx_errors++;
  192544. - kfree_skb(skb);
  192545. + dev_kfree_skb_any(skb);
  192546. return NETDEV_TX_OK;
  192547. }
  192548. if (skb->sk)
  192549. skb_set_owner_w(skb_new, skb->sk);
  192550. - consume_skb(skb);
  192551. + dev_consume_skb_any(skb);
  192552. skb = skb_new;
  192553. }
  192554. @@ -2351,8 +2410,6 @@
  192555. {
  192556. struct gfar_private *priv = netdev_priv(dev);
  192557. - disable_napi(priv);
  192558. -
  192559. cancel_work_sync(&priv->reset_task);
  192560. stop_gfar(dev);
  192561. @@ -2360,7 +2417,7 @@
  192562. phy_disconnect(priv->phydev);
  192563. priv->phydev = NULL;
  192564. - netif_tx_stop_all_queues(dev);
  192565. + gfar_free_irq(priv);
  192566. return 0;
  192567. }
  192568. @@ -2373,77 +2430,9 @@
  192569. return 0;
  192570. }
  192571. -/* Check if rx parser should be activated */
  192572. -void gfar_check_rx_parser_mode(struct gfar_private *priv)
  192573. -{
  192574. - struct gfar __iomem *regs;
  192575. - u32 tempval;
  192576. -
  192577. - regs = priv->gfargrp[0].regs;
  192578. -
  192579. - tempval = gfar_read(&regs->rctrl);
  192580. - /* If parse is no longer required, then disable parser */
  192581. - if (tempval & RCTRL_REQ_PARSER) {
  192582. - tempval |= RCTRL_PRSDEP_INIT;
  192583. - priv->uses_rxfcb = 1;
  192584. - } else {
  192585. - tempval &= ~RCTRL_PRSDEP_INIT;
  192586. - priv->uses_rxfcb = 0;
  192587. - }
  192588. - gfar_write(&regs->rctrl, tempval);
  192589. -}
  192590. -
  192591. -/* Enables and disables VLAN insertion/extraction */
  192592. -void gfar_vlan_mode(struct net_device *dev, netdev_features_t features)
  192593. -{
  192594. - struct gfar_private *priv = netdev_priv(dev);
  192595. - struct gfar __iomem *regs = NULL;
  192596. - unsigned long flags;
  192597. - u32 tempval;
  192598. -
  192599. - regs = priv->gfargrp[0].regs;
  192600. - local_irq_save(flags);
  192601. - lock_rx_qs(priv);
  192602. -
  192603. - if (features & NETIF_F_HW_VLAN_CTAG_TX) {
  192604. - /* Enable VLAN tag insertion */
  192605. - tempval = gfar_read(&regs->tctrl);
  192606. - tempval |= TCTRL_VLINS;
  192607. - gfar_write(&regs->tctrl, tempval);
  192608. - } else {
  192609. - /* Disable VLAN tag insertion */
  192610. - tempval = gfar_read(&regs->tctrl);
  192611. - tempval &= ~TCTRL_VLINS;
  192612. - gfar_write(&regs->tctrl, tempval);
  192613. - }
  192614. -
  192615. - if (features & NETIF_F_HW_VLAN_CTAG_RX) {
  192616. - /* Enable VLAN tag extraction */
  192617. - tempval = gfar_read(&regs->rctrl);
  192618. - tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT);
  192619. - gfar_write(&regs->rctrl, tempval);
  192620. - priv->uses_rxfcb = 1;
  192621. - } else {
  192622. - /* Disable VLAN tag extraction */
  192623. - tempval = gfar_read(&regs->rctrl);
  192624. - tempval &= ~RCTRL_VLEX;
  192625. - gfar_write(&regs->rctrl, tempval);
  192626. -
  192627. - gfar_check_rx_parser_mode(priv);
  192628. - }
  192629. -
  192630. - gfar_change_mtu(dev, dev->mtu);
  192631. -
  192632. - unlock_rx_qs(priv);
  192633. - local_irq_restore(flags);
  192634. -}
  192635. -
  192636. static int gfar_change_mtu(struct net_device *dev, int new_mtu)
  192637. {
  192638. - int tempsize, tempval;
  192639. struct gfar_private *priv = netdev_priv(dev);
  192640. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  192641. - int oldsize = priv->rx_buffer_size;
  192642. int frame_size = new_mtu + ETH_HLEN;
  192643. if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) {
  192644. @@ -2451,45 +2440,33 @@
  192645. return -EINVAL;
  192646. }
  192647. - if (priv->uses_rxfcb)
  192648. - frame_size += GMAC_FCB_LEN;
  192649. -
  192650. - frame_size += priv->padding;
  192651. -
  192652. - tempsize = (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) +
  192653. - INCREMENTAL_BUFFER_SIZE;
  192654. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  192655. + cpu_relax();
  192656. - /* Only stop and start the controller if it isn't already
  192657. - * stopped, and we changed something
  192658. - */
  192659. - if ((oldsize != tempsize) && (dev->flags & IFF_UP))
  192660. + if (dev->flags & IFF_UP)
  192661. stop_gfar(dev);
  192662. - priv->rx_buffer_size = tempsize;
  192663. -
  192664. dev->mtu = new_mtu;
  192665. - gfar_write(&regs->mrblr, priv->rx_buffer_size);
  192666. - gfar_write(&regs->maxfrm, priv->rx_buffer_size);
  192667. + if (dev->flags & IFF_UP)
  192668. + startup_gfar(dev);
  192669. - /* If the mtu is larger than the max size for standard
  192670. - * ethernet frames (ie, a jumbo frame), then set maccfg2
  192671. - * to allow huge frames, and to check the length
  192672. - */
  192673. - tempval = gfar_read(&regs->maccfg2);
  192674. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  192675. - if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE ||
  192676. - gfar_has_errata(priv, GFAR_ERRATA_74))
  192677. - tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);
  192678. - else
  192679. - tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);
  192680. + return 0;
  192681. +}
  192682. - gfar_write(&regs->maccfg2, tempval);
  192683. +void reset_gfar(struct net_device *ndev)
  192684. +{
  192685. + struct gfar_private *priv = netdev_priv(ndev);
  192686. - if ((oldsize != tempsize) && (dev->flags & IFF_UP))
  192687. - startup_gfar(dev);
  192688. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  192689. + cpu_relax();
  192690. - return 0;
  192691. + stop_gfar(ndev);
  192692. + startup_gfar(ndev);
  192693. +
  192694. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  192695. }
  192696. /* gfar_reset_task gets scheduled when a packet has not been
  192697. @@ -2501,16 +2478,7 @@
  192698. {
  192699. struct gfar_private *priv = container_of(work, struct gfar_private,
  192700. reset_task);
  192701. - struct net_device *dev = priv->ndev;
  192702. -
  192703. - if (dev->flags & IFF_UP) {
  192704. - netif_tx_stop_all_queues(dev);
  192705. - stop_gfar(dev);
  192706. - startup_gfar(dev);
  192707. - netif_tx_start_all_queues(dev);
  192708. - }
  192709. -
  192710. - netif_tx_schedule_all(dev);
  192711. + reset_gfar(priv->ndev);
  192712. }
  192713. static void gfar_timeout(struct net_device *dev)
  192714. @@ -2623,8 +2591,10 @@
  192715. }
  192716. /* If we freed a buffer, we can restart transmission, if necessary */
  192717. - if (netif_tx_queue_stopped(txq) && tx_queue->num_txbdfree)
  192718. - netif_wake_subqueue(dev, tqi);
  192719. + if (tx_queue->num_txbdfree &&
  192720. + netif_tx_queue_stopped(txq) &&
  192721. + !(test_bit(GFAR_DOWN, &priv->state)))
  192722. + netif_wake_subqueue(priv->ndev, tqi);
  192723. /* Update dirty indicators */
  192724. tx_queue->skb_dirtytx = skb_dirtytx;
  192725. @@ -2633,31 +2603,6 @@
  192726. netdev_tx_completed_queue(txq, howmany, bytes_sent);
  192727. }
  192728. -static void gfar_schedule_cleanup(struct gfar_priv_grp *gfargrp)
  192729. -{
  192730. - unsigned long flags;
  192731. -
  192732. - spin_lock_irqsave(&gfargrp->grplock, flags);
  192733. - if (napi_schedule_prep(&gfargrp->napi)) {
  192734. - gfar_write(&gfargrp->regs->imask, IMASK_RTX_DISABLED);
  192735. - __napi_schedule(&gfargrp->napi);
  192736. - } else {
  192737. - /* Clear IEVENT, so interrupts aren't called again
  192738. - * because of the packets that have already arrived.
  192739. - */
  192740. - gfar_write(&gfargrp->regs->ievent, IEVENT_RTX_MASK);
  192741. - }
  192742. - spin_unlock_irqrestore(&gfargrp->grplock, flags);
  192743. -
  192744. -}
  192745. -
  192746. -/* Interrupt Handler for Transmit complete */
  192747. -static irqreturn_t gfar_transmit(int irq, void *grp_id)
  192748. -{
  192749. - gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id);
  192750. - return IRQ_HANDLED;
  192751. -}
  192752. -
  192753. static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp,
  192754. struct sk_buff *skb)
  192755. {
  192756. @@ -2728,7 +2673,48 @@
  192757. irqreturn_t gfar_receive(int irq, void *grp_id)
  192758. {
  192759. - gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id);
  192760. + struct gfar_priv_grp *grp = (struct gfar_priv_grp *)grp_id;
  192761. + unsigned long flags;
  192762. + u32 imask;
  192763. +
  192764. + if (likely(napi_schedule_prep(&grp->napi_rx))) {
  192765. + spin_lock_irqsave(&grp->grplock, flags);
  192766. + imask = gfar_read(&grp->regs->imask);
  192767. + imask &= IMASK_RX_DISABLED;
  192768. + gfar_write(&grp->regs->imask, imask);
  192769. + spin_unlock_irqrestore(&grp->grplock, flags);
  192770. + __napi_schedule(&grp->napi_rx);
  192771. + } else {
  192772. + /* Clear IEVENT, so interrupts aren't called again
  192773. + * because of the packets that have already arrived.
  192774. + */
  192775. + gfar_write(&grp->regs->ievent, IEVENT_RX_MASK);
  192776. + }
  192777. +
  192778. + return IRQ_HANDLED;
  192779. +}
  192780. +
  192781. +/* Interrupt Handler for Transmit complete */
  192782. +static irqreturn_t gfar_transmit(int irq, void *grp_id)
  192783. +{
  192784. + struct gfar_priv_grp *grp = (struct gfar_priv_grp *)grp_id;
  192785. + unsigned long flags;
  192786. + u32 imask;
  192787. +
  192788. + if (likely(napi_schedule_prep(&grp->napi_tx))) {
  192789. + spin_lock_irqsave(&grp->grplock, flags);
  192790. + imask = gfar_read(&grp->regs->imask);
  192791. + imask &= IMASK_TX_DISABLED;
  192792. + gfar_write(&grp->regs->imask, imask);
  192793. + spin_unlock_irqrestore(&grp->grplock, flags);
  192794. + __napi_schedule(&grp->napi_tx);
  192795. + } else {
  192796. + /* Clear IEVENT, so interrupts aren't called again
  192797. + * because of the packets that have already arrived.
  192798. + */
  192799. + gfar_write(&grp->regs->ievent, IEVENT_TX_MASK);
  192800. + }
  192801. +
  192802. return IRQ_HANDLED;
  192803. }
  192804. @@ -2852,7 +2838,7 @@
  192805. rx_queue->stats.rx_bytes += pkt_len;
  192806. skb_record_rx_queue(skb, rx_queue->qindex);
  192807. gfar_process_frame(dev, skb, amount_pull,
  192808. - &rx_queue->grp->napi);
  192809. + &rx_queue->grp->napi_rx);
  192810. } else {
  192811. netif_warn(priv, rx_err, dev, "Missing skb!\n");
  192812. @@ -2881,66 +2867,81 @@
  192813. return howmany;
  192814. }
  192815. -static int gfar_poll_sq(struct napi_struct *napi, int budget)
  192816. +static int gfar_poll_rx_sq(struct napi_struct *napi, int budget)
  192817. {
  192818. struct gfar_priv_grp *gfargrp =
  192819. - container_of(napi, struct gfar_priv_grp, napi);
  192820. + container_of(napi, struct gfar_priv_grp, napi_rx);
  192821. struct gfar __iomem *regs = gfargrp->regs;
  192822. - struct gfar_priv_tx_q *tx_queue = gfargrp->priv->tx_queue[0];
  192823. - struct gfar_priv_rx_q *rx_queue = gfargrp->priv->rx_queue[0];
  192824. + struct gfar_priv_rx_q *rx_queue = gfargrp->rx_queue;
  192825. int work_done = 0;
  192826. /* Clear IEVENT, so interrupts aren't called again
  192827. * because of the packets that have already arrived
  192828. */
  192829. - gfar_write(&regs->ievent, IEVENT_RTX_MASK);
  192830. -
  192831. - /* run Tx cleanup to completion */
  192832. - if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx])
  192833. - gfar_clean_tx_ring(tx_queue);
  192834. + gfar_write(&regs->ievent, IEVENT_RX_MASK);
  192835. work_done = gfar_clean_rx_ring(rx_queue, budget);
  192836. if (work_done < budget) {
  192837. + u32 imask;
  192838. napi_complete(napi);
  192839. /* Clear the halt bit in RSTAT */
  192840. gfar_write(&regs->rstat, gfargrp->rstat);
  192841. - gfar_write(&regs->imask, IMASK_DEFAULT);
  192842. -
  192843. - /* If we are coalescing interrupts, update the timer
  192844. - * Otherwise, clear it
  192845. - */
  192846. - gfar_write(&regs->txic, 0);
  192847. - if (likely(tx_queue->txcoalescing))
  192848. - gfar_write(&regs->txic, tx_queue->txic);
  192849. -
  192850. - gfar_write(&regs->rxic, 0);
  192851. - if (unlikely(rx_queue->rxcoalescing))
  192852. - gfar_write(&regs->rxic, rx_queue->rxic);
  192853. + spin_lock_irq(&gfargrp->grplock);
  192854. + imask = gfar_read(&regs->imask);
  192855. + imask |= IMASK_RX_DEFAULT;
  192856. + gfar_write(&regs->imask, imask);
  192857. + spin_unlock_irq(&gfargrp->grplock);
  192858. }
  192859. return work_done;
  192860. }
  192861. -static int gfar_poll(struct napi_struct *napi, int budget)
  192862. +static int gfar_poll_tx_sq(struct napi_struct *napi, int budget)
  192863. +{
  192864. + struct gfar_priv_grp *gfargrp =
  192865. + container_of(napi, struct gfar_priv_grp, napi_tx);
  192866. + struct gfar __iomem *regs = gfargrp->regs;
  192867. + struct gfar_priv_tx_q *tx_queue = gfargrp->tx_queue;
  192868. + u32 imask;
  192869. +
  192870. + /* Clear IEVENT, so interrupts aren't called again
  192871. + * because of the packets that have already arrived
  192872. + */
  192873. + gfar_write(&regs->ievent, IEVENT_TX_MASK);
  192874. +
  192875. + /* run Tx cleanup to completion */
  192876. + if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx])
  192877. + gfar_clean_tx_ring(tx_queue);
  192878. +
  192879. + napi_complete(napi);
  192880. +
  192881. + spin_lock_irq(&gfargrp->grplock);
  192882. + imask = gfar_read(&regs->imask);
  192883. + imask |= IMASK_TX_DEFAULT;
  192884. + gfar_write(&regs->imask, imask);
  192885. + spin_unlock_irq(&gfargrp->grplock);
  192886. +
  192887. + return 0;
  192888. +}
  192889. +
  192890. +static int gfar_poll_rx(struct napi_struct *napi, int budget)
  192891. {
  192892. struct gfar_priv_grp *gfargrp =
  192893. - container_of(napi, struct gfar_priv_grp, napi);
  192894. + container_of(napi, struct gfar_priv_grp, napi_rx);
  192895. struct gfar_private *priv = gfargrp->priv;
  192896. struct gfar __iomem *regs = gfargrp->regs;
  192897. - struct gfar_priv_tx_q *tx_queue = NULL;
  192898. struct gfar_priv_rx_q *rx_queue = NULL;
  192899. int work_done = 0, work_done_per_q = 0;
  192900. int i, budget_per_q = 0;
  192901. - int has_tx_work = 0;
  192902. unsigned long rstat_rxf;
  192903. int num_act_queues;
  192904. /* Clear IEVENT, so interrupts aren't called again
  192905. * because of the packets that have already arrived
  192906. */
  192907. - gfar_write(&regs->ievent, IEVENT_RTX_MASK);
  192908. + gfar_write(&regs->ievent, IEVENT_RX_MASK);
  192909. rstat_rxf = gfar_read(&regs->rstat) & RSTAT_RXF_MASK;
  192910. @@ -2948,15 +2949,6 @@
  192911. if (num_act_queues)
  192912. budget_per_q = budget/num_act_queues;
  192913. - for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) {
  192914. - tx_queue = priv->tx_queue[i];
  192915. - /* run Tx cleanup to completion */
  192916. - if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) {
  192917. - gfar_clean_tx_ring(tx_queue);
  192918. - has_tx_work = 1;
  192919. - }
  192920. - }
  192921. -
  192922. for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
  192923. /* skip queue if not active */
  192924. if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i)))
  192925. @@ -2979,25 +2971,62 @@
  192926. }
  192927. }
  192928. - if (!num_act_queues && !has_tx_work) {
  192929. -
  192930. + if (!num_act_queues) {
  192931. + u32 imask;
  192932. napi_complete(napi);
  192933. /* Clear the halt bit in RSTAT */
  192934. gfar_write(&regs->rstat, gfargrp->rstat);
  192935. - gfar_write(&regs->imask, IMASK_DEFAULT);
  192936. -
  192937. - /* If we are coalescing interrupts, update the timer
  192938. - * Otherwise, clear it
  192939. - */
  192940. - gfar_configure_coalescing(priv, gfargrp->rx_bit_map,
  192941. - gfargrp->tx_bit_map);
  192942. + spin_lock_irq(&gfargrp->grplock);
  192943. + imask = gfar_read(&regs->imask);
  192944. + imask |= IMASK_RX_DEFAULT;
  192945. + gfar_write(&regs->imask, imask);
  192946. + spin_unlock_irq(&gfargrp->grplock);
  192947. }
  192948. return work_done;
  192949. }
  192950. +static int gfar_poll_tx(struct napi_struct *napi, int budget)
  192951. +{
  192952. + struct gfar_priv_grp *gfargrp =
  192953. + container_of(napi, struct gfar_priv_grp, napi_tx);
  192954. + struct gfar_private *priv = gfargrp->priv;
  192955. + struct gfar __iomem *regs = gfargrp->regs;
  192956. + struct gfar_priv_tx_q *tx_queue = NULL;
  192957. + int has_tx_work = 0;
  192958. + int i;
  192959. +
  192960. + /* Clear IEVENT, so interrupts aren't called again
  192961. + * because of the packets that have already arrived
  192962. + */
  192963. + gfar_write(&regs->ievent, IEVENT_TX_MASK);
  192964. +
  192965. + for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) {
  192966. + tx_queue = priv->tx_queue[i];
  192967. + /* run Tx cleanup to completion */
  192968. + if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) {
  192969. + gfar_clean_tx_ring(tx_queue);
  192970. + has_tx_work = 1;
  192971. + }
  192972. + }
  192973. +
  192974. + if (!has_tx_work) {
  192975. + u32 imask;
  192976. + napi_complete(napi);
  192977. +
  192978. + spin_lock_irq(&gfargrp->grplock);
  192979. + imask = gfar_read(&regs->imask);
  192980. + imask |= IMASK_TX_DEFAULT;
  192981. + gfar_write(&regs->imask, imask);
  192982. + spin_unlock_irq(&gfargrp->grplock);
  192983. + }
  192984. +
  192985. + return 0;
  192986. +}
  192987. +
  192988. +
  192989. #ifdef CONFIG_NET_POLL_CONTROLLER
  192990. /* Polling 'interrupt' - used by things like netconsole to send skbs
  192991. * without having to re-enable interrupts. It's not called while
  192992. @@ -3056,41 +3085,6 @@
  192993. return IRQ_HANDLED;
  192994. }
  192995. -static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv)
  192996. -{
  192997. - struct phy_device *phydev = priv->phydev;
  192998. - u32 val = 0;
  192999. -
  193000. - if (!phydev->duplex)
  193001. - return val;
  193002. -
  193003. - if (!priv->pause_aneg_en) {
  193004. - if (priv->tx_pause_en)
  193005. - val |= MACCFG1_TX_FLOW;
  193006. - if (priv->rx_pause_en)
  193007. - val |= MACCFG1_RX_FLOW;
  193008. - } else {
  193009. - u16 lcl_adv, rmt_adv;
  193010. - u8 flowctrl;
  193011. - /* get link partner capabilities */
  193012. - rmt_adv = 0;
  193013. - if (phydev->pause)
  193014. - rmt_adv = LPA_PAUSE_CAP;
  193015. - if (phydev->asym_pause)
  193016. - rmt_adv |= LPA_PAUSE_ASYM;
  193017. -
  193018. - lcl_adv = mii_advertise_flowctrl(phydev->advertising);
  193019. -
  193020. - flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
  193021. - if (flowctrl & FLOW_CTRL_TX)
  193022. - val |= MACCFG1_TX_FLOW;
  193023. - if (flowctrl & FLOW_CTRL_RX)
  193024. - val |= MACCFG1_RX_FLOW;
  193025. - }
  193026. -
  193027. - return val;
  193028. -}
  193029. -
  193030. /* Called every time the controller might need to be made
  193031. * aware of new link state. The PHY code conveys this
  193032. * information through variables in the phydev structure, and this
  193033. @@ -3100,86 +3094,12 @@
  193034. static void adjust_link(struct net_device *dev)
  193035. {
  193036. struct gfar_private *priv = netdev_priv(dev);
  193037. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193038. - unsigned long flags;
  193039. struct phy_device *phydev = priv->phydev;
  193040. - int new_state = 0;
  193041. -
  193042. - local_irq_save(flags);
  193043. - lock_tx_qs(priv);
  193044. -
  193045. - if (phydev->link) {
  193046. - u32 tempval1 = gfar_read(&regs->maccfg1);
  193047. - u32 tempval = gfar_read(&regs->maccfg2);
  193048. - u32 ecntrl = gfar_read(&regs->ecntrl);
  193049. -
  193050. - /* Now we make sure that we can be in full duplex mode.
  193051. - * If not, we operate in half-duplex mode.
  193052. - */
  193053. - if (phydev->duplex != priv->oldduplex) {
  193054. - new_state = 1;
  193055. - if (!(phydev->duplex))
  193056. - tempval &= ~(MACCFG2_FULL_DUPLEX);
  193057. - else
  193058. - tempval |= MACCFG2_FULL_DUPLEX;
  193059. -
  193060. - priv->oldduplex = phydev->duplex;
  193061. - }
  193062. -
  193063. - if (phydev->speed != priv->oldspeed) {
  193064. - new_state = 1;
  193065. - switch (phydev->speed) {
  193066. - case 1000:
  193067. - tempval =
  193068. - ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII);
  193069. -
  193070. - ecntrl &= ~(ECNTRL_R100);
  193071. - break;
  193072. - case 100:
  193073. - case 10:
  193074. - tempval =
  193075. - ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
  193076. -
  193077. - /* Reduced mode distinguishes
  193078. - * between 10 and 100
  193079. - */
  193080. - if (phydev->speed == SPEED_100)
  193081. - ecntrl |= ECNTRL_R100;
  193082. - else
  193083. - ecntrl &= ~(ECNTRL_R100);
  193084. - break;
  193085. - default:
  193086. - netif_warn(priv, link, dev,
  193087. - "Ack! Speed (%d) is not 10/100/1000!\n",
  193088. - phydev->speed);
  193089. - break;
  193090. - }
  193091. -
  193092. - priv->oldspeed = phydev->speed;
  193093. - }
  193094. -
  193095. - tempval1 &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW);
  193096. - tempval1 |= gfar_get_flowctrl_cfg(priv);
  193097. -
  193098. - gfar_write(&regs->maccfg1, tempval1);
  193099. - gfar_write(&regs->maccfg2, tempval);
  193100. - gfar_write(&regs->ecntrl, ecntrl);
  193101. -
  193102. - if (!priv->oldlink) {
  193103. - new_state = 1;
  193104. - priv->oldlink = 1;
  193105. - }
  193106. - } else if (priv->oldlink) {
  193107. - new_state = 1;
  193108. - priv->oldlink = 0;
  193109. - priv->oldspeed = 0;
  193110. - priv->oldduplex = -1;
  193111. - }
  193112. - if (new_state && netif_msg_link(priv))
  193113. - phy_print_status(phydev);
  193114. - unlock_tx_qs(priv);
  193115. - local_irq_restore(flags);
  193116. + if (unlikely(phydev->link != priv->oldlink ||
  193117. + phydev->duplex != priv->oldduplex ||
  193118. + phydev->speed != priv->oldspeed))
  193119. + gfar_update_link_state(priv);
  193120. }
  193121. /* Update the hash table based on the current list of multicast
  193122. @@ -3425,6 +3345,114 @@
  193123. return IRQ_HANDLED;
  193124. }
  193125. +static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv)
  193126. +{
  193127. + struct phy_device *phydev = priv->phydev;
  193128. + u32 val = 0;
  193129. +
  193130. + if (!phydev->duplex)
  193131. + return val;
  193132. +
  193133. + if (!priv->pause_aneg_en) {
  193134. + if (priv->tx_pause_en)
  193135. + val |= MACCFG1_TX_FLOW;
  193136. + if (priv->rx_pause_en)
  193137. + val |= MACCFG1_RX_FLOW;
  193138. + } else {
  193139. + u16 lcl_adv, rmt_adv;
  193140. + u8 flowctrl;
  193141. + /* get link partner capabilities */
  193142. + rmt_adv = 0;
  193143. + if (phydev->pause)
  193144. + rmt_adv = LPA_PAUSE_CAP;
  193145. + if (phydev->asym_pause)
  193146. + rmt_adv |= LPA_PAUSE_ASYM;
  193147. +
  193148. + lcl_adv = mii_advertise_flowctrl(phydev->advertising);
  193149. +
  193150. + flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
  193151. + if (flowctrl & FLOW_CTRL_TX)
  193152. + val |= MACCFG1_TX_FLOW;
  193153. + if (flowctrl & FLOW_CTRL_RX)
  193154. + val |= MACCFG1_RX_FLOW;
  193155. + }
  193156. +
  193157. + return val;
  193158. +}
  193159. +
  193160. +static noinline void gfar_update_link_state(struct gfar_private *priv)
  193161. +{
  193162. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193163. + struct phy_device *phydev = priv->phydev;
  193164. +
  193165. + if (unlikely(test_bit(GFAR_RESETTING, &priv->state)))
  193166. + return;
  193167. +
  193168. + if (phydev->link) {
  193169. + u32 tempval1 = gfar_read(&regs->maccfg1);
  193170. + u32 tempval = gfar_read(&regs->maccfg2);
  193171. + u32 ecntrl = gfar_read(&regs->ecntrl);
  193172. +
  193173. + if (phydev->duplex != priv->oldduplex) {
  193174. + if (!(phydev->duplex))
  193175. + tempval &= ~(MACCFG2_FULL_DUPLEX);
  193176. + else
  193177. + tempval |= MACCFG2_FULL_DUPLEX;
  193178. +
  193179. + priv->oldduplex = phydev->duplex;
  193180. + }
  193181. +
  193182. + if (phydev->speed != priv->oldspeed) {
  193183. + switch (phydev->speed) {
  193184. + case 1000:
  193185. + tempval =
  193186. + ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII);
  193187. +
  193188. + ecntrl &= ~(ECNTRL_R100);
  193189. + break;
  193190. + case 100:
  193191. + case 10:
  193192. + tempval =
  193193. + ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
  193194. +
  193195. + /* Reduced mode distinguishes
  193196. + * between 10 and 100
  193197. + */
  193198. + if (phydev->speed == SPEED_100)
  193199. + ecntrl |= ECNTRL_R100;
  193200. + else
  193201. + ecntrl &= ~(ECNTRL_R100);
  193202. + break;
  193203. + default:
  193204. + netif_warn(priv, link, priv->ndev,
  193205. + "Ack! Speed (%d) is not 10/100/1000!\n",
  193206. + phydev->speed);
  193207. + break;
  193208. + }
  193209. +
  193210. + priv->oldspeed = phydev->speed;
  193211. + }
  193212. +
  193213. + tempval1 &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW);
  193214. + tempval1 |= gfar_get_flowctrl_cfg(priv);
  193215. +
  193216. + gfar_write(&regs->maccfg1, tempval1);
  193217. + gfar_write(&regs->maccfg2, tempval);
  193218. + gfar_write(&regs->ecntrl, ecntrl);
  193219. +
  193220. + if (!priv->oldlink)
  193221. + priv->oldlink = 1;
  193222. +
  193223. + } else if (priv->oldlink) {
  193224. + priv->oldlink = 0;
  193225. + priv->oldspeed = 0;
  193226. + priv->oldduplex = -1;
  193227. + }
  193228. +
  193229. + if (netif_msg_link(priv))
  193230. + phy_print_status(phydev);
  193231. +}
  193232. +
  193233. static struct of_device_id gfar_match[] =
  193234. {
  193235. {
  193236. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/gianfar_ethtool.c linux-linaro-stable-mx6/drivers/net/ethernet/freescale/gianfar_ethtool.c
  193237. --- linux-3.14.15/drivers/net/ethernet/freescale/gianfar_ethtool.c 2014-07-31 23:51:43.000000000 +0200
  193238. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/gianfar_ethtool.c 2014-08-20 19:31:46.428870293 +0200
  193239. @@ -44,10 +44,6 @@
  193240. #include "gianfar.h"
  193241. -extern void gfar_start(struct net_device *dev);
  193242. -extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue,
  193243. - int rx_work_limit);
  193244. -
  193245. #define GFAR_MAX_COAL_USECS 0xffff
  193246. #define GFAR_MAX_COAL_FRAMES 0xff
  193247. static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
  193248. @@ -364,25 +360,11 @@
  193249. struct ethtool_coalesce *cvals)
  193250. {
  193251. struct gfar_private *priv = netdev_priv(dev);
  193252. - int i = 0;
  193253. + int i, err = 0;
  193254. if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
  193255. return -EOPNOTSUPP;
  193256. - /* Set up rx coalescing */
  193257. - /* As of now, we will enable/disable coalescing for all
  193258. - * queues together in case of eTSEC2, this will be modified
  193259. - * along with the ethtool interface
  193260. - */
  193261. - if ((cvals->rx_coalesce_usecs == 0) ||
  193262. - (cvals->rx_max_coalesced_frames == 0)) {
  193263. - for (i = 0; i < priv->num_rx_queues; i++)
  193264. - priv->rx_queue[i]->rxcoalescing = 0;
  193265. - } else {
  193266. - for (i = 0; i < priv->num_rx_queues; i++)
  193267. - priv->rx_queue[i]->rxcoalescing = 1;
  193268. - }
  193269. -
  193270. if (NULL == priv->phydev)
  193271. return -ENODEV;
  193272. @@ -399,6 +381,32 @@
  193273. return -EINVAL;
  193274. }
  193275. + /* Check the bounds of the values */
  193276. + if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
  193277. + netdev_info(dev, "Coalescing is limited to %d microseconds\n",
  193278. + GFAR_MAX_COAL_USECS);
  193279. + return -EINVAL;
  193280. + }
  193281. +
  193282. + if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
  193283. + netdev_info(dev, "Coalescing is limited to %d frames\n",
  193284. + GFAR_MAX_COAL_FRAMES);
  193285. + return -EINVAL;
  193286. + }
  193287. +
  193288. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  193289. + cpu_relax();
  193290. +
  193291. + /* Set up rx coalescing */
  193292. + if ((cvals->rx_coalesce_usecs == 0) ||
  193293. + (cvals->rx_max_coalesced_frames == 0)) {
  193294. + for (i = 0; i < priv->num_rx_queues; i++)
  193295. + priv->rx_queue[i]->rxcoalescing = 0;
  193296. + } else {
  193297. + for (i = 0; i < priv->num_rx_queues; i++)
  193298. + priv->rx_queue[i]->rxcoalescing = 1;
  193299. + }
  193300. +
  193301. for (i = 0; i < priv->num_rx_queues; i++) {
  193302. priv->rx_queue[i]->rxic = mk_ic_value(
  193303. cvals->rx_max_coalesced_frames,
  193304. @@ -415,28 +423,22 @@
  193305. priv->tx_queue[i]->txcoalescing = 1;
  193306. }
  193307. - /* Check the bounds of the values */
  193308. - if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
  193309. - netdev_info(dev, "Coalescing is limited to %d microseconds\n",
  193310. - GFAR_MAX_COAL_USECS);
  193311. - return -EINVAL;
  193312. - }
  193313. -
  193314. - if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
  193315. - netdev_info(dev, "Coalescing is limited to %d frames\n",
  193316. - GFAR_MAX_COAL_FRAMES);
  193317. - return -EINVAL;
  193318. - }
  193319. -
  193320. for (i = 0; i < priv->num_tx_queues; i++) {
  193321. priv->tx_queue[i]->txic = mk_ic_value(
  193322. cvals->tx_max_coalesced_frames,
  193323. gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs));
  193324. }
  193325. - gfar_configure_coalescing_all(priv);
  193326. + if (dev->flags & IFF_UP) {
  193327. + stop_gfar(dev);
  193328. + err = startup_gfar(dev);
  193329. + } else {
  193330. + gfar_mac_reset(priv);
  193331. + }
  193332. +
  193333. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  193334. - return 0;
  193335. + return err;
  193336. }
  193337. /* Fills in rvals with the current ring parameters. Currently,
  193338. @@ -467,15 +469,13 @@
  193339. }
  193340. /* Change the current ring parameters, stopping the controller if
  193341. - * necessary so that we don't mess things up while we're in
  193342. - * motion. We wait for the ring to be clean before reallocating
  193343. - * the rings.
  193344. + * necessary so that we don't mess things up while we're in motion.
  193345. */
  193346. static int gfar_sringparam(struct net_device *dev,
  193347. struct ethtool_ringparam *rvals)
  193348. {
  193349. struct gfar_private *priv = netdev_priv(dev);
  193350. - int err = 0, i = 0;
  193351. + int err = 0, i;
  193352. if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE)
  193353. return -EINVAL;
  193354. @@ -493,44 +493,25 @@
  193355. return -EINVAL;
  193356. }
  193357. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  193358. + cpu_relax();
  193359. - if (dev->flags & IFF_UP) {
  193360. - unsigned long flags;
  193361. -
  193362. - /* Halt TX and RX, and process the frames which
  193363. - * have already been received
  193364. - */
  193365. - local_irq_save(flags);
  193366. - lock_tx_qs(priv);
  193367. - lock_rx_qs(priv);
  193368. -
  193369. - gfar_halt(dev);
  193370. -
  193371. - unlock_rx_qs(priv);
  193372. - unlock_tx_qs(priv);
  193373. - local_irq_restore(flags);
  193374. -
  193375. - for (i = 0; i < priv->num_rx_queues; i++)
  193376. - gfar_clean_rx_ring(priv->rx_queue[i],
  193377. - priv->rx_queue[i]->rx_ring_size);
  193378. -
  193379. - /* Now we take down the rings to rebuild them */
  193380. + if (dev->flags & IFF_UP)
  193381. stop_gfar(dev);
  193382. - }
  193383. - /* Change the size */
  193384. - for (i = 0; i < priv->num_rx_queues; i++) {
  193385. + /* Change the sizes */
  193386. + for (i = 0; i < priv->num_rx_queues; i++)
  193387. priv->rx_queue[i]->rx_ring_size = rvals->rx_pending;
  193388. +
  193389. + for (i = 0; i < priv->num_tx_queues; i++)
  193390. priv->tx_queue[i]->tx_ring_size = rvals->tx_pending;
  193391. - priv->tx_queue[i]->num_txbdfree =
  193392. - priv->tx_queue[i]->tx_ring_size;
  193393. - }
  193394. /* Rebuild the rings with the new size */
  193395. - if (dev->flags & IFF_UP) {
  193396. + if (dev->flags & IFF_UP)
  193397. err = startup_gfar(dev);
  193398. - netif_tx_wake_all_queues(dev);
  193399. - }
  193400. +
  193401. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  193402. +
  193403. return err;
  193404. }
  193405. @@ -552,6 +533,9 @@
  193406. struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193407. u32 oldadv, newadv;
  193408. + if (!phydev)
  193409. + return -ENODEV;
  193410. +
  193411. if (!(phydev->supported & SUPPORTED_Pause) ||
  193412. (!(phydev->supported & SUPPORTED_Asym_Pause) &&
  193413. (epause->rx_pause != epause->tx_pause)))
  193414. @@ -608,43 +592,29 @@
  193415. int gfar_set_features(struct net_device *dev, netdev_features_t features)
  193416. {
  193417. - struct gfar_private *priv = netdev_priv(dev);
  193418. - unsigned long flags;
  193419. - int err = 0, i = 0;
  193420. netdev_features_t changed = dev->features ^ features;
  193421. + struct gfar_private *priv = netdev_priv(dev);
  193422. + int err = 0;
  193423. - if (changed & (NETIF_F_HW_VLAN_CTAG_TX|NETIF_F_HW_VLAN_CTAG_RX))
  193424. - gfar_vlan_mode(dev, features);
  193425. -
  193426. - if (!(changed & NETIF_F_RXCSUM))
  193427. + if (!(changed & (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
  193428. + NETIF_F_RXCSUM)))
  193429. return 0;
  193430. - if (dev->flags & IFF_UP) {
  193431. - /* Halt TX and RX, and process the frames which
  193432. - * have already been received
  193433. - */
  193434. - local_irq_save(flags);
  193435. - lock_tx_qs(priv);
  193436. - lock_rx_qs(priv);
  193437. -
  193438. - gfar_halt(dev);
  193439. -
  193440. - unlock_tx_qs(priv);
  193441. - unlock_rx_qs(priv);
  193442. - local_irq_restore(flags);
  193443. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  193444. + cpu_relax();
  193445. - for (i = 0; i < priv->num_rx_queues; i++)
  193446. - gfar_clean_rx_ring(priv->rx_queue[i],
  193447. - priv->rx_queue[i]->rx_ring_size);
  193448. + dev->features = features;
  193449. + if (dev->flags & IFF_UP) {
  193450. /* Now we take down the rings to rebuild them */
  193451. stop_gfar(dev);
  193452. -
  193453. - dev->features = features;
  193454. -
  193455. err = startup_gfar(dev);
  193456. - netif_tx_wake_all_queues(dev);
  193457. + } else {
  193458. + gfar_mac_reset(priv);
  193459. }
  193460. +
  193461. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  193462. +
  193463. return err;
  193464. }
  193465. @@ -1610,9 +1580,6 @@
  193466. if (tab->index > MAX_FILER_IDX - 1)
  193467. return -EBUSY;
  193468. - /* Avoid inconsistent filer table to be processed */
  193469. - lock_rx_qs(priv);
  193470. -
  193471. /* Fill regular entries */
  193472. for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].ctrl);
  193473. i++)
  193474. @@ -1625,8 +1592,6 @@
  193475. */
  193476. gfar_write_filer(priv, i, 0x20, 0x0);
  193477. - unlock_rx_qs(priv);
  193478. -
  193479. return 0;
  193480. }
  193481. @@ -1831,6 +1796,9 @@
  193482. struct gfar_private *priv = netdev_priv(dev);
  193483. int ret = 0;
  193484. + if (test_bit(GFAR_RESETTING, &priv->state))
  193485. + return -EBUSY;
  193486. +
  193487. mutex_lock(&priv->rx_queue_access);
  193488. switch (cmd->cmd) {
  193489. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/gianfar.h linux-linaro-stable-mx6/drivers/net/ethernet/freescale/gianfar.h
  193490. --- linux-3.14.15/drivers/net/ethernet/freescale/gianfar.h 2014-07-31 23:51:43.000000000 +0200
  193491. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/gianfar.h 2014-08-20 19:31:46.424870276 +0200
  193492. @@ -9,7 +9,7 @@
  193493. * Maintainer: Kumar Gala
  193494. * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  193495. *
  193496. - * Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
  193497. + * Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc.
  193498. *
  193499. * This program is free software; you can redistribute it and/or modify it
  193500. * under the terms of the GNU General Public License as published by the
  193501. @@ -377,8 +377,11 @@
  193502. IMASK_RXFEN0 | IMASK_BSY | IMASK_EBERR | IMASK_BABR | \
  193503. IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
  193504. | IMASK_PERR)
  193505. -#define IMASK_RTX_DISABLED ((~(IMASK_RXFEN0 | IMASK_TXFEN | IMASK_BSY)) \
  193506. - & IMASK_DEFAULT)
  193507. +#define IMASK_RX_DEFAULT (IMASK_RXFEN0 | IMASK_BSY)
  193508. +#define IMASK_TX_DEFAULT (IMASK_TXFEN | IMASK_TXBEN)
  193509. +
  193510. +#define IMASK_RX_DISABLED ((~(IMASK_RX_DEFAULT)) & IMASK_DEFAULT)
  193511. +#define IMASK_TX_DISABLED ((~(IMASK_TX_DEFAULT)) & IMASK_DEFAULT)
  193512. /* Fifo management */
  193513. #define FIFO_TX_THR_MASK 0x01ff
  193514. @@ -409,7 +412,9 @@
  193515. /* This default RIR value directly corresponds
  193516. * to the 3-bit hash value generated */
  193517. -#define DEFAULT_RIR0 0x05397700
  193518. +#define DEFAULT_8RXQ_RIR0 0x05397700
  193519. +/* Map even hash values to Q0, and odd ones to Q1 */
  193520. +#define DEFAULT_2RXQ_RIR0 0x04104100
  193521. /* RQFCR register bits */
  193522. #define RQFCR_GPI 0x80000000
  193523. @@ -880,7 +885,6 @@
  193524. #define FSL_GIANFAR_DEV_HAS_CSUM 0x00000010
  193525. #define FSL_GIANFAR_DEV_HAS_VLAN 0x00000020
  193526. #define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH 0x00000040
  193527. -#define FSL_GIANFAR_DEV_HAS_PADDING 0x00000080
  193528. #define FSL_GIANFAR_DEV_HAS_MAGIC_PACKET 0x00000100
  193529. #define FSL_GIANFAR_DEV_HAS_BD_STASHING 0x00000200
  193530. #define FSL_GIANFAR_DEV_HAS_BUF_STASHING 0x00000400
  193531. @@ -892,8 +896,8 @@
  193532. #define DEFAULT_MAPPING 0xFF
  193533. #endif
  193534. -#define ISRG_SHIFT_TX 0x10
  193535. -#define ISRG_SHIFT_RX 0x18
  193536. +#define ISRG_RR0 0x80000000
  193537. +#define ISRG_TR0 0x00800000
  193538. /* The same driver can operate in two modes */
  193539. /* SQ_SG_MODE: Single Queue Single Group Mode
  193540. @@ -905,6 +909,22 @@
  193541. MQ_MG_MODE
  193542. };
  193543. +/* GFAR_SQ_POLLING: Single Queue NAPI polling mode
  193544. + * The driver supports a single pair of RX/Tx queues
  193545. + * per interrupt group (Rx/Tx int line). MQ_MG mode
  193546. + * devices have 2 interrupt groups, so the device will
  193547. + * have a total of 2 Tx and 2 Rx queues in this case.
  193548. + * GFAR_MQ_POLLING: Multi Queue NAPI polling mode
  193549. + * The driver supports all the 8 Rx and Tx HW queues
  193550. + * each queue mapped by the Device Tree to one of
  193551. + * the 2 interrupt groups. This mode implies significant
  193552. + * processing overhead (CPU and controller level).
  193553. + */
  193554. +enum gfar_poll_mode {
  193555. + GFAR_SQ_POLLING = 0,
  193556. + GFAR_MQ_POLLING
  193557. +};
  193558. +
  193559. /*
  193560. * Per TX queue stats
  193561. */
  193562. @@ -966,7 +986,6 @@
  193563. /**
  193564. * struct gfar_priv_rx_q - per rx queue structure
  193565. - * @rxlock: per queue rx spin lock
  193566. * @rx_skbuff: skb pointers
  193567. * @skb_currx: currently use skb pointer
  193568. * @rx_bd_base: First rx buffer descriptor
  193569. @@ -979,8 +998,7 @@
  193570. */
  193571. struct gfar_priv_rx_q {
  193572. - spinlock_t rxlock __attribute__ ((aligned (SMP_CACHE_BYTES)));
  193573. - struct sk_buff ** rx_skbuff;
  193574. + struct sk_buff **rx_skbuff __aligned(SMP_CACHE_BYTES);
  193575. dma_addr_t rx_bd_dma_base;
  193576. struct rxbd8 *rx_bd_base;
  193577. struct rxbd8 *cur_rx;
  193578. @@ -1016,17 +1034,20 @@
  193579. */
  193580. struct gfar_priv_grp {
  193581. - spinlock_t grplock __attribute__ ((aligned (SMP_CACHE_BYTES)));
  193582. - struct napi_struct napi;
  193583. - struct gfar_private *priv;
  193584. + spinlock_t grplock __aligned(SMP_CACHE_BYTES);
  193585. + struct napi_struct napi_rx;
  193586. + struct napi_struct napi_tx;
  193587. struct gfar __iomem *regs;
  193588. - unsigned int rstat;
  193589. - unsigned long num_rx_queues;
  193590. - unsigned long rx_bit_map;
  193591. - /* cacheline 3 */
  193592. + struct gfar_priv_tx_q *tx_queue;
  193593. + struct gfar_priv_rx_q *rx_queue;
  193594. unsigned int tstat;
  193595. + unsigned int rstat;
  193596. +
  193597. + struct gfar_private *priv;
  193598. unsigned long num_tx_queues;
  193599. unsigned long tx_bit_map;
  193600. + unsigned long num_rx_queues;
  193601. + unsigned long rx_bit_map;
  193602. struct gfar_irqinfo *irqinfo[GFAR_NUM_IRQS];
  193603. };
  193604. @@ -1041,6 +1062,11 @@
  193605. GFAR_ERRATA_12 = 0x08, /* a.k.a errata eTSEC49 */
  193606. };
  193607. +enum gfar_dev_state {
  193608. + GFAR_DOWN = 1,
  193609. + GFAR_RESETTING
  193610. +};
  193611. +
  193612. /* Struct stolen almost completely (and shamelessly) from the FCC enet source
  193613. * (Ok, that's not so true anymore, but there is a family resemblance)
  193614. * The GFAR buffer descriptors track the ring buffers. The rx_bd_base
  193615. @@ -1051,8 +1077,6 @@
  193616. * the buffer descriptor determines the actual condition.
  193617. */
  193618. struct gfar_private {
  193619. - unsigned int num_rx_queues;
  193620. -
  193621. struct device *dev;
  193622. struct net_device *ndev;
  193623. enum gfar_errata errata;
  193624. @@ -1060,6 +1084,7 @@
  193625. u16 uses_rxfcb;
  193626. u16 padding;
  193627. + u32 device_flags;
  193628. /* HW time stamping enabled flag */
  193629. int hwts_rx_en;
  193630. @@ -1069,10 +1094,12 @@
  193631. struct gfar_priv_rx_q *rx_queue[MAX_RX_QS];
  193632. struct gfar_priv_grp gfargrp[MAXGROUPS];
  193633. - u32 device_flags;
  193634. + unsigned long state;
  193635. - unsigned int mode;
  193636. + unsigned short mode;
  193637. + unsigned short poll_mode;
  193638. unsigned int num_tx_queues;
  193639. + unsigned int num_rx_queues;
  193640. unsigned int num_grps;
  193641. /* Network Statistics */
  193642. @@ -1113,6 +1140,9 @@
  193643. unsigned int total_tx_ring_size;
  193644. unsigned int total_rx_ring_size;
  193645. + u32 rqueue;
  193646. + u32 tqueue;
  193647. +
  193648. /* RX per device parameters */
  193649. unsigned int rx_stash_size;
  193650. unsigned int rx_stash_index;
  193651. @@ -1127,11 +1157,6 @@
  193652. u32 __iomem *hash_regs[16];
  193653. int hash_width;
  193654. - /* global parameters */
  193655. - unsigned int fifo_threshold;
  193656. - unsigned int fifo_starve;
  193657. - unsigned int fifo_starve_off;
  193658. -
  193659. /*Filer table*/
  193660. unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
  193661. unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
  193662. @@ -1176,21 +1201,42 @@
  193663. *fpr = gfar_read(&regs->rqfpr);
  193664. }
  193665. -void lock_rx_qs(struct gfar_private *priv);
  193666. -void lock_tx_qs(struct gfar_private *priv);
  193667. -void unlock_rx_qs(struct gfar_private *priv);
  193668. -void unlock_tx_qs(struct gfar_private *priv);
  193669. +static inline void gfar_write_isrg(struct gfar_private *priv)
  193670. +{
  193671. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193672. + u32 __iomem *baddr = &regs->isrg0;
  193673. + u32 isrg = 0;
  193674. + int grp_idx, i;
  193675. +
  193676. + for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
  193677. + struct gfar_priv_grp *grp = &priv->gfargrp[grp_idx];
  193678. +
  193679. + for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) {
  193680. + isrg |= (ISRG_RR0 >> i);
  193681. + }
  193682. +
  193683. + for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) {
  193684. + isrg |= (ISRG_TR0 >> i);
  193685. + }
  193686. +
  193687. + gfar_write(baddr, isrg);
  193688. +
  193689. + baddr++;
  193690. + isrg = 0;
  193691. + }
  193692. +}
  193693. +
  193694. irqreturn_t gfar_receive(int irq, void *dev_id);
  193695. int startup_gfar(struct net_device *dev);
  193696. void stop_gfar(struct net_device *dev);
  193697. -void gfar_halt(struct net_device *dev);
  193698. +void reset_gfar(struct net_device *dev);
  193699. +void gfar_mac_reset(struct gfar_private *priv);
  193700. +void gfar_halt(struct gfar_private *priv);
  193701. +void gfar_start(struct gfar_private *priv);
  193702. void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, int enable,
  193703. u32 regnum, u32 read);
  193704. void gfar_configure_coalescing_all(struct gfar_private *priv);
  193705. -void gfar_init_sysfs(struct net_device *dev);
  193706. int gfar_set_features(struct net_device *dev, netdev_features_t features);
  193707. -void gfar_check_rx_parser_mode(struct gfar_private *priv);
  193708. -void gfar_vlan_mode(struct net_device *dev, netdev_features_t features);
  193709. extern const struct ethtool_ops gfar_ethtool_ops;
  193710. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/gianfar_ptp.c linux-linaro-stable-mx6/drivers/net/ethernet/freescale/gianfar_ptp.c
  193711. --- linux-3.14.15/drivers/net/ethernet/freescale/gianfar_ptp.c 2014-07-31 23:51:43.000000000 +0200
  193712. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/gianfar_ptp.c 2014-08-20 19:31:46.428870293 +0200
  193713. @@ -414,6 +414,7 @@
  193714. .n_alarm = 0,
  193715. .n_ext_ts = N_EXT_TS,
  193716. .n_per_out = 0,
  193717. + .n_pins = 0,
  193718. .pps = 1,
  193719. .adjfreq = ptp_gianfar_adjfreq,
  193720. .adjtime = ptp_gianfar_adjtime,
  193721. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/gianfar_sysfs.c linux-linaro-stable-mx6/drivers/net/ethernet/freescale/gianfar_sysfs.c
  193722. --- linux-3.14.15/drivers/net/ethernet/freescale/gianfar_sysfs.c 2014-07-31 23:51:43.000000000 +0200
  193723. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/gianfar_sysfs.c 1970-01-01 01:00:00.000000000 +0100
  193724. @@ -1,340 +0,0 @@
  193725. -/*
  193726. - * drivers/net/ethernet/freescale/gianfar_sysfs.c
  193727. - *
  193728. - * Gianfar Ethernet Driver
  193729. - * This driver is designed for the non-CPM ethernet controllers
  193730. - * on the 85xx and 83xx family of integrated processors
  193731. - * Based on 8260_io/fcc_enet.c
  193732. - *
  193733. - * Author: Andy Fleming
  193734. - * Maintainer: Kumar Gala (galak@kernel.crashing.org)
  193735. - * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  193736. - *
  193737. - * Copyright 2002-2009 Freescale Semiconductor, Inc.
  193738. - *
  193739. - * This program is free software; you can redistribute it and/or modify it
  193740. - * under the terms of the GNU General Public License as published by the
  193741. - * Free Software Foundation; either version 2 of the License, or (at your
  193742. - * option) any later version.
  193743. - *
  193744. - * Sysfs file creation and management
  193745. - */
  193746. -
  193747. -#include <linux/kernel.h>
  193748. -#include <linux/string.h>
  193749. -#include <linux/errno.h>
  193750. -#include <linux/unistd.h>
  193751. -#include <linux/delay.h>
  193752. -#include <linux/etherdevice.h>
  193753. -#include <linux/spinlock.h>
  193754. -#include <linux/mm.h>
  193755. -#include <linux/device.h>
  193756. -
  193757. -#include <asm/uaccess.h>
  193758. -#include <linux/module.h>
  193759. -
  193760. -#include "gianfar.h"
  193761. -
  193762. -static ssize_t gfar_show_bd_stash(struct device *dev,
  193763. - struct device_attribute *attr, char *buf)
  193764. -{
  193765. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193766. -
  193767. - return sprintf(buf, "%s\n", priv->bd_stash_en ? "on" : "off");
  193768. -}
  193769. -
  193770. -static ssize_t gfar_set_bd_stash(struct device *dev,
  193771. - struct device_attribute *attr,
  193772. - const char *buf, size_t count)
  193773. -{
  193774. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193775. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193776. - int new_setting = 0;
  193777. - u32 temp;
  193778. - unsigned long flags;
  193779. -
  193780. - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BD_STASHING))
  193781. - return count;
  193782. -
  193783. -
  193784. - /* Find out the new setting */
  193785. - if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
  193786. - new_setting = 1;
  193787. - else if (!strncmp("off", buf, count - 1) ||
  193788. - !strncmp("0", buf, count - 1))
  193789. - new_setting = 0;
  193790. - else
  193791. - return count;
  193792. -
  193793. -
  193794. - local_irq_save(flags);
  193795. - lock_rx_qs(priv);
  193796. -
  193797. - /* Set the new stashing value */
  193798. - priv->bd_stash_en = new_setting;
  193799. -
  193800. - temp = gfar_read(&regs->attr);
  193801. -
  193802. - if (new_setting)
  193803. - temp |= ATTR_BDSTASH;
  193804. - else
  193805. - temp &= ~(ATTR_BDSTASH);
  193806. -
  193807. - gfar_write(&regs->attr, temp);
  193808. -
  193809. - unlock_rx_qs(priv);
  193810. - local_irq_restore(flags);
  193811. -
  193812. - return count;
  193813. -}
  193814. -
  193815. -static DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash);
  193816. -
  193817. -static ssize_t gfar_show_rx_stash_size(struct device *dev,
  193818. - struct device_attribute *attr, char *buf)
  193819. -{
  193820. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193821. -
  193822. - return sprintf(buf, "%d\n", priv->rx_stash_size);
  193823. -}
  193824. -
  193825. -static ssize_t gfar_set_rx_stash_size(struct device *dev,
  193826. - struct device_attribute *attr,
  193827. - const char *buf, size_t count)
  193828. -{
  193829. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193830. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193831. - unsigned int length = simple_strtoul(buf, NULL, 0);
  193832. - u32 temp;
  193833. - unsigned long flags;
  193834. -
  193835. - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
  193836. - return count;
  193837. -
  193838. - local_irq_save(flags);
  193839. - lock_rx_qs(priv);
  193840. -
  193841. - if (length > priv->rx_buffer_size)
  193842. - goto out;
  193843. -
  193844. - if (length == priv->rx_stash_size)
  193845. - goto out;
  193846. -
  193847. - priv->rx_stash_size = length;
  193848. -
  193849. - temp = gfar_read(&regs->attreli);
  193850. - temp &= ~ATTRELI_EL_MASK;
  193851. - temp |= ATTRELI_EL(length);
  193852. - gfar_write(&regs->attreli, temp);
  193853. -
  193854. - /* Turn stashing on/off as appropriate */
  193855. - temp = gfar_read(&regs->attr);
  193856. -
  193857. - if (length)
  193858. - temp |= ATTR_BUFSTASH;
  193859. - else
  193860. - temp &= ~(ATTR_BUFSTASH);
  193861. -
  193862. - gfar_write(&regs->attr, temp);
  193863. -
  193864. -out:
  193865. - unlock_rx_qs(priv);
  193866. - local_irq_restore(flags);
  193867. -
  193868. - return count;
  193869. -}
  193870. -
  193871. -static DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size,
  193872. - gfar_set_rx_stash_size);
  193873. -
  193874. -/* Stashing will only be enabled when rx_stash_size != 0 */
  193875. -static ssize_t gfar_show_rx_stash_index(struct device *dev,
  193876. - struct device_attribute *attr,
  193877. - char *buf)
  193878. -{
  193879. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193880. -
  193881. - return sprintf(buf, "%d\n", priv->rx_stash_index);
  193882. -}
  193883. -
  193884. -static ssize_t gfar_set_rx_stash_index(struct device *dev,
  193885. - struct device_attribute *attr,
  193886. - const char *buf, size_t count)
  193887. -{
  193888. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193889. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193890. - unsigned short index = simple_strtoul(buf, NULL, 0);
  193891. - u32 temp;
  193892. - unsigned long flags;
  193893. -
  193894. - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
  193895. - return count;
  193896. -
  193897. - local_irq_save(flags);
  193898. - lock_rx_qs(priv);
  193899. -
  193900. - if (index > priv->rx_stash_size)
  193901. - goto out;
  193902. -
  193903. - if (index == priv->rx_stash_index)
  193904. - goto out;
  193905. -
  193906. - priv->rx_stash_index = index;
  193907. -
  193908. - temp = gfar_read(&regs->attreli);
  193909. - temp &= ~ATTRELI_EI_MASK;
  193910. - temp |= ATTRELI_EI(index);
  193911. - gfar_write(&regs->attreli, temp);
  193912. -
  193913. -out:
  193914. - unlock_rx_qs(priv);
  193915. - local_irq_restore(flags);
  193916. -
  193917. - return count;
  193918. -}
  193919. -
  193920. -static DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index,
  193921. - gfar_set_rx_stash_index);
  193922. -
  193923. -static ssize_t gfar_show_fifo_threshold(struct device *dev,
  193924. - struct device_attribute *attr,
  193925. - char *buf)
  193926. -{
  193927. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193928. -
  193929. - return sprintf(buf, "%d\n", priv->fifo_threshold);
  193930. -}
  193931. -
  193932. -static ssize_t gfar_set_fifo_threshold(struct device *dev,
  193933. - struct device_attribute *attr,
  193934. - const char *buf, size_t count)
  193935. -{
  193936. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193937. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193938. - unsigned int length = simple_strtoul(buf, NULL, 0);
  193939. - u32 temp;
  193940. - unsigned long flags;
  193941. -
  193942. - if (length > GFAR_MAX_FIFO_THRESHOLD)
  193943. - return count;
  193944. -
  193945. - local_irq_save(flags);
  193946. - lock_tx_qs(priv);
  193947. -
  193948. - priv->fifo_threshold = length;
  193949. -
  193950. - temp = gfar_read(&regs->fifo_tx_thr);
  193951. - temp &= ~FIFO_TX_THR_MASK;
  193952. - temp |= length;
  193953. - gfar_write(&regs->fifo_tx_thr, temp);
  193954. -
  193955. - unlock_tx_qs(priv);
  193956. - local_irq_restore(flags);
  193957. -
  193958. - return count;
  193959. -}
  193960. -
  193961. -static DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold,
  193962. - gfar_set_fifo_threshold);
  193963. -
  193964. -static ssize_t gfar_show_fifo_starve(struct device *dev,
  193965. - struct device_attribute *attr, char *buf)
  193966. -{
  193967. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193968. -
  193969. - return sprintf(buf, "%d\n", priv->fifo_starve);
  193970. -}
  193971. -
  193972. -static ssize_t gfar_set_fifo_starve(struct device *dev,
  193973. - struct device_attribute *attr,
  193974. - const char *buf, size_t count)
  193975. -{
  193976. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193977. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193978. - unsigned int num = simple_strtoul(buf, NULL, 0);
  193979. - u32 temp;
  193980. - unsigned long flags;
  193981. -
  193982. - if (num > GFAR_MAX_FIFO_STARVE)
  193983. - return count;
  193984. -
  193985. - local_irq_save(flags);
  193986. - lock_tx_qs(priv);
  193987. -
  193988. - priv->fifo_starve = num;
  193989. -
  193990. - temp = gfar_read(&regs->fifo_tx_starve);
  193991. - temp &= ~FIFO_TX_STARVE_MASK;
  193992. - temp |= num;
  193993. - gfar_write(&regs->fifo_tx_starve, temp);
  193994. -
  193995. - unlock_tx_qs(priv);
  193996. - local_irq_restore(flags);
  193997. -
  193998. - return count;
  193999. -}
  194000. -
  194001. -static DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve,
  194002. - gfar_set_fifo_starve);
  194003. -
  194004. -static ssize_t gfar_show_fifo_starve_off(struct device *dev,
  194005. - struct device_attribute *attr,
  194006. - char *buf)
  194007. -{
  194008. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  194009. -
  194010. - return sprintf(buf, "%d\n", priv->fifo_starve_off);
  194011. -}
  194012. -
  194013. -static ssize_t gfar_set_fifo_starve_off(struct device *dev,
  194014. - struct device_attribute *attr,
  194015. - const char *buf, size_t count)
  194016. -{
  194017. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  194018. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  194019. - unsigned int num = simple_strtoul(buf, NULL, 0);
  194020. - u32 temp;
  194021. - unsigned long flags;
  194022. -
  194023. - if (num > GFAR_MAX_FIFO_STARVE_OFF)
  194024. - return count;
  194025. -
  194026. - local_irq_save(flags);
  194027. - lock_tx_qs(priv);
  194028. -
  194029. - priv->fifo_starve_off = num;
  194030. -
  194031. - temp = gfar_read(&regs->fifo_tx_starve_shutoff);
  194032. - temp &= ~FIFO_TX_STARVE_OFF_MASK;
  194033. - temp |= num;
  194034. - gfar_write(&regs->fifo_tx_starve_shutoff, temp);
  194035. -
  194036. - unlock_tx_qs(priv);
  194037. - local_irq_restore(flags);
  194038. -
  194039. - return count;
  194040. -}
  194041. -
  194042. -static DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off,
  194043. - gfar_set_fifo_starve_off);
  194044. -
  194045. -void gfar_init_sysfs(struct net_device *dev)
  194046. -{
  194047. - struct gfar_private *priv = netdev_priv(dev);
  194048. - int rc;
  194049. -
  194050. - /* Initialize the default values */
  194051. - priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
  194052. - priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
  194053. - priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
  194054. -
  194055. - /* Create our sysfs files */
  194056. - rc = device_create_file(&dev->dev, &dev_attr_bd_stash);
  194057. - rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_size);
  194058. - rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_index);
  194059. - rc |= device_create_file(&dev->dev, &dev_attr_fifo_threshold);
  194060. - rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve);
  194061. - rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve_off);
  194062. - if (rc)
  194063. - dev_err(&dev->dev, "Error creating gianfar sysfs files\n");
  194064. -}
  194065. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/Kconfig linux-linaro-stable-mx6/drivers/net/ethernet/freescale/Kconfig
  194066. --- linux-3.14.15/drivers/net/ethernet/freescale/Kconfig 2014-07-31 23:51:43.000000000 +0200
  194067. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/Kconfig 2014-08-20 19:31:46.364870019 +0200
  194068. @@ -67,6 +67,7 @@
  194069. tristate "Freescale XGMAC MDIO"
  194070. depends on FSL_SOC
  194071. select PHYLIB
  194072. + select OF_MDIO
  194073. ---help---
  194074. This driver supports the MDIO bus on the Fman 10G Ethernet MACs.
  194075. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/Makefile linux-linaro-stable-mx6/drivers/net/ethernet/freescale/Makefile
  194076. --- linux-3.14.15/drivers/net/ethernet/freescale/Makefile 2014-07-31 23:51:43.000000000 +0200
  194077. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/Makefile 2014-08-20 19:31:46.364870019 +0200
  194078. @@ -14,7 +14,6 @@
  194079. obj-$(CONFIG_GIANFAR) += gianfar_driver.o
  194080. obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o
  194081. gianfar_driver-objs := gianfar.o \
  194082. - gianfar_ethtool.o \
  194083. - gianfar_sysfs.o
  194084. + gianfar_ethtool.o
  194085. obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
  194086. ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
  194087. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/ucc_geth.c linux-linaro-stable-mx6/drivers/net/ethernet/freescale/ucc_geth.c
  194088. --- linux-3.14.15/drivers/net/ethernet/freescale/ucc_geth.c 2014-07-31 23:51:43.000000000 +0200
  194089. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/ucc_geth.c 2014-08-20 19:31:46.428870293 +0200
  194090. @@ -1728,9 +1728,6 @@
  194091. phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0,
  194092. priv->phy_interface);
  194093. - if (!phydev)
  194094. - phydev = of_phy_connect_fixed_link(dev, &adjust_link,
  194095. - priv->phy_interface);
  194096. if (!phydev) {
  194097. dev_err(&dev->dev, "Could not attach to PHY\n");
  194098. return -ENODEV;
  194099. @@ -3261,7 +3258,7 @@
  194100. dev->stats.tx_packets++;
  194101. - dev_kfree_skb(skb);
  194102. + dev_consume_skb_any(skb);
  194103. ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
  194104. ugeth->skb_dirtytx[txQ] =
  194105. @@ -3790,6 +3787,17 @@
  194106. ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
  194107. ug_info->phy_node = of_parse_phandle(np, "phy-handle", 0);
  194108. + if (!ug_info->phy_node) {
  194109. + /* In the case of a fixed PHY, the DT node associated
  194110. + * to the PHY is the Ethernet MAC DT node.
  194111. + */
  194112. + if (of_phy_is_fixed_link(np)) {
  194113. + err = of_phy_register_fixed_link(np);
  194114. + if (err)
  194115. + return err;
  194116. + }
  194117. + ug_info->phy_node = np;
  194118. + }
  194119. /* Find the TBI PHY node. If it's not there, we don't support SGMII */
  194120. ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
  194121. diff -Nur linux-3.14.15/drivers/net/ethernet/freescale/xgmac_mdio.c linux-linaro-stable-mx6/drivers/net/ethernet/freescale/xgmac_mdio.c
  194122. --- linux-3.14.15/drivers/net/ethernet/freescale/xgmac_mdio.c 2014-07-31 23:51:43.000000000 +0200
  194123. +++ linux-linaro-stable-mx6/drivers/net/ethernet/freescale/xgmac_mdio.c 2014-08-20 19:31:46.428870293 +0200
  194124. @@ -162,7 +162,9 @@
  194125. /* Return all Fs if nothing was there */
  194126. if (in_be32(&regs->mdio_stat) & MDIO_STAT_RD_ER) {
  194127. - dev_err(&bus->dev, "MDIO read error\n");
  194128. + dev_err(&bus->dev,
  194129. + "Error while reading PHY%d reg at %d.%d\n",
  194130. + phy_id, dev_addr, regnum);
  194131. return 0xffff;
  194132. }
  194133. diff -Nur linux-3.14.15/drivers/net/ethernet/intel/e1000e/ptp.c linux-linaro-stable-mx6/drivers/net/ethernet/intel/e1000e/ptp.c
  194134. --- linux-3.14.15/drivers/net/ethernet/intel/e1000e/ptp.c 2014-07-31 23:51:43.000000000 +0200
  194135. +++ linux-linaro-stable-mx6/drivers/net/ethernet/intel/e1000e/ptp.c 2014-08-20 19:31:46.508870637 +0200
  194136. @@ -191,6 +191,7 @@
  194137. .n_alarm = 0,
  194138. .n_ext_ts = 0,
  194139. .n_per_out = 0,
  194140. + .n_pins = 0,
  194141. .pps = 0,
  194142. .adjfreq = e1000e_phc_adjfreq,
  194143. .adjtime = e1000e_phc_adjtime,
  194144. diff -Nur linux-3.14.15/drivers/net/ethernet/mellanox/mlx4/en_clock.c linux-linaro-stable-mx6/drivers/net/ethernet/mellanox/mlx4/en_clock.c
  194145. --- linux-3.14.15/drivers/net/ethernet/mellanox/mlx4/en_clock.c 2014-07-31 23:51:43.000000000 +0200
  194146. +++ linux-linaro-stable-mx6/drivers/net/ethernet/mellanox/mlx4/en_clock.c 2014-08-20 19:31:46.560870860 +0200
  194147. @@ -276,6 +276,7 @@
  194148. .n_alarm = 0,
  194149. .n_ext_ts = 0,
  194150. .n_per_out = 0,
  194151. + .n_pins = 0,
  194152. .pps = 0,
  194153. .adjfreq = mlx4_en_phc_adjfreq,
  194154. .adjtime = mlx4_en_phc_adjtime,
  194155. diff -Nur linux-3.14.15/drivers/net/ethernet/sfc/ptp.c linux-linaro-stable-mx6/drivers/net/ethernet/sfc/ptp.c
  194156. --- linux-3.14.15/drivers/net/ethernet/sfc/ptp.c 2014-07-31 23:51:43.000000000 +0200
  194157. +++ linux-linaro-stable-mx6/drivers/net/ethernet/sfc/ptp.c 2014-08-20 19:31:46.628871152 +0200
  194158. @@ -1208,6 +1208,7 @@
  194159. .n_alarm = 0,
  194160. .n_ext_ts = 0,
  194161. .n_per_out = 0,
  194162. + .n_pins = 0,
  194163. .pps = 1,
  194164. .adjfreq = efx_phc_adjfreq,
  194165. .adjtime = efx_phc_adjtime,
  194166. diff -Nur linux-3.14.15/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c linux-linaro-stable-mx6/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
  194167. --- linux-3.14.15/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c 2014-07-31 23:51:43.000000000 +0200
  194168. +++ linux-linaro-stable-mx6/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c 2014-08-20 19:31:46.644871222 +0200
  194169. @@ -164,6 +164,7 @@
  194170. .n_alarm = 0,
  194171. .n_ext_ts = 0,
  194172. .n_per_out = 0,
  194173. + .n_pins = 0,
  194174. .pps = 0,
  194175. .adjfreq = stmmac_adjust_freq,
  194176. .adjtime = stmmac_adjust_time,
  194177. diff -Nur linux-3.14.15/drivers/net/ethernet/ti/cpts.c linux-linaro-stable-mx6/drivers/net/ethernet/ti/cpts.c
  194178. --- linux-3.14.15/drivers/net/ethernet/ti/cpts.c 2014-07-31 23:51:43.000000000 +0200
  194179. +++ linux-linaro-stable-mx6/drivers/net/ethernet/ti/cpts.c 2014-08-20 19:31:46.656871271 +0200
  194180. @@ -217,6 +217,7 @@
  194181. .name = "CTPS timer",
  194182. .max_adj = 1000000,
  194183. .n_ext_ts = 0,
  194184. + .n_pins = 0,
  194185. .pps = 0,
  194186. .adjfreq = cpts_ptp_adjfreq,
  194187. .adjtime = cpts_ptp_adjtime,
  194188. diff -Nur linux-3.14.15/drivers/net/ethernet/tile/tilegx.c linux-linaro-stable-mx6/drivers/net/ethernet/tile/tilegx.c
  194189. --- linux-3.14.15/drivers/net/ethernet/tile/tilegx.c 2014-07-31 23:51:43.000000000 +0200
  194190. +++ linux-linaro-stable-mx6/drivers/net/ethernet/tile/tilegx.c 2014-08-20 19:31:46.660871289 +0200
  194191. @@ -870,6 +870,7 @@
  194192. .name = "mPIPE clock",
  194193. .max_adj = 999999999,
  194194. .n_ext_ts = 0,
  194195. + .n_pins = 0,
  194196. .pps = 0,
  194197. .adjfreq = ptp_mpipe_adjfreq,
  194198. .adjtime = ptp_mpipe_adjtime,
  194199. diff -Nur linux-3.14.15/drivers/net/ieee802154/Kconfig linux-linaro-stable-mx6/drivers/net/ieee802154/Kconfig
  194200. --- linux-3.14.15/drivers/net/ieee802154/Kconfig 2014-07-31 23:51:43.000000000 +0200
  194201. +++ linux-linaro-stable-mx6/drivers/net/ieee802154/Kconfig 2014-08-20 19:31:46.676871358 +0200
  194202. @@ -15,9 +15,9 @@
  194203. depends on IEEE802154_DRIVERS
  194204. ---help---
  194205. Say Y here to enable the fake driver that serves as an example
  194206. - of HardMAC device driver.
  194207. + of HardMAC device driver.
  194208. - This driver can also be built as a module. To do so say M here.
  194209. + This driver can also be built as a module. To do so say M here.
  194210. The module will be called 'fakehard'.
  194211. config IEEE802154_FAKELB
  194212. @@ -31,17 +31,17 @@
  194213. The module will be called 'fakelb'.
  194214. config IEEE802154_AT86RF230
  194215. - depends on IEEE802154_DRIVERS && MAC802154
  194216. - tristate "AT86RF230/231 transceiver driver"
  194217. - depends on SPI
  194218. + depends on IEEE802154_DRIVERS && MAC802154
  194219. + tristate "AT86RF230/231 transceiver driver"
  194220. + depends on SPI
  194221. config IEEE802154_MRF24J40
  194222. - tristate "Microchip MRF24J40 transceiver driver"
  194223. - depends on IEEE802154_DRIVERS && MAC802154
  194224. - depends on SPI
  194225. - ---help---
  194226. - Say Y here to enable the MRF24J20 SPI 802.15.4 wireless
  194227. - controller.
  194228. + tristate "Microchip MRF24J40 transceiver driver"
  194229. + depends on IEEE802154_DRIVERS && MAC802154
  194230. + depends on SPI
  194231. + ---help---
  194232. + Say Y here to enable the MRF24J20 SPI 802.15.4 wireless
  194233. + controller.
  194234. - This driver can also be built as a module. To do so, say M here.
  194235. - the module will be called 'mrf24j40'.
  194236. + This driver can also be built as a module. To do so, say M here.
  194237. + the module will be called 'mrf24j40'.
  194238. diff -Nur linux-3.14.15/drivers/net/phy/at803x.c linux-linaro-stable-mx6/drivers/net/phy/at803x.c
  194239. --- linux-3.14.15/drivers/net/phy/at803x.c 2014-07-31 23:51:43.000000000 +0200
  194240. +++ linux-linaro-stable-mx6/drivers/net/phy/at803x.c 2014-08-20 19:31:46.688871410 +0200
  194241. @@ -27,6 +27,9 @@
  194242. #define AT803X_MMD_ACCESS_CONTROL 0x0D
  194243. #define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E
  194244. #define AT803X_FUNC_DATA 0x4003
  194245. +#define AT803X_INER 0x0012
  194246. +#define AT803X_INER_INIT 0xec00
  194247. +#define AT803X_INSR 0x0013
  194248. #define AT803X_DEBUG_ADDR 0x1D
  194249. #define AT803X_DEBUG_DATA 0x1E
  194250. #define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05
  194251. @@ -141,41 +144,11 @@
  194252. static int at803x_config_init(struct phy_device *phydev)
  194253. {
  194254. - int val;
  194255. int ret;
  194256. - u32 features;
  194257. - features = SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_AUI |
  194258. - SUPPORTED_FIBRE | SUPPORTED_BNC;
  194259. -
  194260. - val = phy_read(phydev, MII_BMSR);
  194261. - if (val < 0)
  194262. - return val;
  194263. -
  194264. - if (val & BMSR_ANEGCAPABLE)
  194265. - features |= SUPPORTED_Autoneg;
  194266. - if (val & BMSR_100FULL)
  194267. - features |= SUPPORTED_100baseT_Full;
  194268. - if (val & BMSR_100HALF)
  194269. - features |= SUPPORTED_100baseT_Half;
  194270. - if (val & BMSR_10FULL)
  194271. - features |= SUPPORTED_10baseT_Full;
  194272. - if (val & BMSR_10HALF)
  194273. - features |= SUPPORTED_10baseT_Half;
  194274. -
  194275. - if (val & BMSR_ESTATEN) {
  194276. - val = phy_read(phydev, MII_ESTATUS);
  194277. - if (val < 0)
  194278. - return val;
  194279. -
  194280. - if (val & ESTATUS_1000_TFULL)
  194281. - features |= SUPPORTED_1000baseT_Full;
  194282. - if (val & ESTATUS_1000_THALF)
  194283. - features |= SUPPORTED_1000baseT_Half;
  194284. - }
  194285. -
  194286. - phydev->supported = features;
  194287. - phydev->advertising = features;
  194288. + ret = genphy_config_init(phydev);
  194289. + if (ret < 0)
  194290. + return ret;
  194291. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
  194292. ret = phy_write(phydev, AT803X_DEBUG_ADDR,
  194293. @@ -191,6 +164,31 @@
  194294. return 0;
  194295. }
  194296. +static int at803x_ack_interrupt(struct phy_device *phydev)
  194297. +{
  194298. + int err;
  194299. +
  194300. + err = phy_read(phydev, AT803X_INSR);
  194301. +
  194302. + return (err < 0) ? err : 0;
  194303. +}
  194304. +
  194305. +static int at803x_config_intr(struct phy_device *phydev)
  194306. +{
  194307. + int err;
  194308. + int value;
  194309. +
  194310. + value = phy_read(phydev, AT803X_INER);
  194311. +
  194312. + if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  194313. + err = phy_write(phydev, AT803X_INER,
  194314. + value | AT803X_INER_INIT);
  194315. + else
  194316. + err = phy_write(phydev, AT803X_INER, 0);
  194317. +
  194318. + return err;
  194319. +}
  194320. +
  194321. static struct phy_driver at803x_driver[] = {
  194322. {
  194323. /* ATHEROS 8035 */
  194324. @@ -240,6 +238,8 @@
  194325. .flags = PHY_HAS_INTERRUPT,
  194326. .config_aneg = genphy_config_aneg,
  194327. .read_status = genphy_read_status,
  194328. + .ack_interrupt = &at803x_ack_interrupt,
  194329. + .config_intr = &at803x_config_intr,
  194330. .driver = {
  194331. .owner = THIS_MODULE,
  194332. },
  194333. @@ -253,8 +253,7 @@
  194334. static void __exit atheros_exit(void)
  194335. {
  194336. - return phy_drivers_unregister(at803x_driver,
  194337. - ARRAY_SIZE(at803x_driver));
  194338. + phy_drivers_unregister(at803x_driver, ARRAY_SIZE(at803x_driver));
  194339. }
  194340. module_init(atheros_init);
  194341. diff -Nur linux-3.14.15/drivers/net/phy/phy_device.c linux-linaro-stable-mx6/drivers/net/phy/phy_device.c
  194342. --- linux-3.14.15/drivers/net/phy/phy_device.c 2014-07-31 23:51:43.000000000 +0200
  194343. +++ linux-linaro-stable-mx6/drivers/net/phy/phy_device.c 2014-08-20 19:31:46.700871461 +0200
  194344. @@ -1029,7 +1029,7 @@
  194345. return 0;
  194346. }
  194347. -static int genphy_config_init(struct phy_device *phydev)
  194348. +int genphy_config_init(struct phy_device *phydev)
  194349. {
  194350. int val;
  194351. u32 features;
  194352. @@ -1075,6 +1075,8 @@
  194353. return 0;
  194354. }
  194355. +EXPORT_SYMBOL(genphy_config_init);
  194356. +
  194357. static int gen10g_config_init(struct phy_device *phydev)
  194358. {
  194359. /* Temporarily just say we support everything */
  194360. diff -Nur linux-3.14.15/drivers/net/phy/smsc.c linux-linaro-stable-mx6/drivers/net/phy/smsc.c
  194361. --- linux-3.14.15/drivers/net/phy/smsc.c 2014-07-31 23:51:43.000000000 +0200
  194362. +++ linux-linaro-stable-mx6/drivers/net/phy/smsc.c 2014-08-20 19:31:46.700871461 +0200
  194363. @@ -249,8 +249,7 @@
  194364. static void __exit smsc_exit(void)
  194365. {
  194366. - return phy_drivers_unregister(smsc_phy_driver,
  194367. - ARRAY_SIZE(smsc_phy_driver));
  194368. + phy_drivers_unregister(smsc_phy_driver, ARRAY_SIZE(smsc_phy_driver));
  194369. }
  194370. MODULE_DESCRIPTION("SMSC PHY driver");
  194371. diff -Nur linux-3.14.15/drivers/net/phy/vitesse.c linux-linaro-stable-mx6/drivers/net/phy/vitesse.c
  194372. --- linux-3.14.15/drivers/net/phy/vitesse.c 2014-07-31 23:51:43.000000000 +0200
  194373. +++ linux-linaro-stable-mx6/drivers/net/phy/vitesse.c 2014-08-20 19:31:46.704871478 +0200
  194374. @@ -319,8 +319,7 @@
  194375. static void __exit vsc82xx_exit(void)
  194376. {
  194377. - return phy_drivers_unregister(vsc82xx_driver,
  194378. - ARRAY_SIZE(vsc82xx_driver));
  194379. + phy_drivers_unregister(vsc82xx_driver, ARRAY_SIZE(vsc82xx_driver));
  194380. }
  194381. module_init(vsc82xx_init);
  194382. diff -Nur linux-3.14.15/drivers/net/veth.c linux-linaro-stable-mx6/drivers/net/veth.c
  194383. --- linux-3.14.15/drivers/net/veth.c 2014-07-31 23:51:43.000000000 +0200
  194384. +++ linux-linaro-stable-mx6/drivers/net/veth.c 2014-08-20 19:31:46.736871615 +0200
  194385. @@ -14,6 +14,7 @@
  194386. #include <linux/etherdevice.h>
  194387. #include <linux/u64_stats_sync.h>
  194388. +#include <net/rtnetlink.h>
  194389. #include <net/dst.h>
  194390. #include <net/xfrm.h>
  194391. #include <linux/veth.h>
  194392. @@ -336,10 +337,9 @@
  194393. nla_peer = data[VETH_INFO_PEER];
  194394. ifmp = nla_data(nla_peer);
  194395. - err = nla_parse(peer_tb, IFLA_MAX,
  194396. - nla_data(nla_peer) + sizeof(struct ifinfomsg),
  194397. - nla_len(nla_peer) - sizeof(struct ifinfomsg),
  194398. - ifla_policy);
  194399. + err = rtnl_nla_parse_ifla(peer_tb,
  194400. + nla_data(nla_peer) + sizeof(struct ifinfomsg),
  194401. + nla_len(nla_peer) - sizeof(struct ifinfomsg));
  194402. if (err < 0)
  194403. return err;
  194404. diff -Nur linux-3.14.15/drivers/net/wireless/ath/ar5523/ar5523.c linux-linaro-stable-mx6/drivers/net/wireless/ath/ar5523/ar5523.c
  194405. --- linux-3.14.15/drivers/net/wireless/ath/ar5523/ar5523.c 2014-07-31 23:51:43.000000000 +0200
  194406. +++ linux-linaro-stable-mx6/drivers/net/wireless/ath/ar5523/ar5523.c 2014-08-20 19:31:46.748871667 +0200
  194407. @@ -1090,7 +1090,8 @@
  194408. return ret;
  194409. }
  194410. -static void ar5523_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  194411. +static void ar5523_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  194412. + u32 queues, bool drop)
  194413. {
  194414. struct ar5523 *ar = hw->priv;
  194415. diff -Nur linux-3.14.15/drivers/net/wireless/ath/ath10k/mac.c linux-linaro-stable-mx6/drivers/net/wireless/ath/ath10k/mac.c
  194416. --- linux-3.14.15/drivers/net/wireless/ath/ath10k/mac.c 2014-07-31 23:51:43.000000000 +0200
  194417. +++ linux-linaro-stable-mx6/drivers/net/wireless/ath/ath10k/mac.c 2014-08-20 19:31:46.764871737 +0200
  194418. @@ -3183,7 +3183,8 @@
  194419. return ret;
  194420. }
  194421. -static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  194422. +static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  194423. + u32 queues, bool drop)
  194424. {
  194425. struct ath10k *ar = hw->priv;
  194426. bool skip;
  194427. diff -Nur linux-3.14.15/drivers/net/wireless/ath/ath6kl/cfg80211.c linux-linaro-stable-mx6/drivers/net/wireless/ath/ath6kl/cfg80211.c
  194428. --- linux-3.14.15/drivers/net/wireless/ath/ath6kl/cfg80211.c 2014-07-31 23:51:43.000000000 +0200
  194429. +++ linux-linaro-stable-mx6/drivers/net/wireless/ath/ath6kl/cfg80211.c 2014-08-20 19:31:46.772871770 +0200
  194430. @@ -790,7 +790,7 @@
  194431. if (nw_type & ADHOC_NETWORK) {
  194432. ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
  194433. nw_type & ADHOC_CREATOR ? "creator" : "joiner");
  194434. - cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
  194435. + cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
  194436. cfg80211_put_bss(ar->wiphy, bss);
  194437. return;
  194438. }
  194439. @@ -861,13 +861,9 @@
  194440. }
  194441. if (vif->nw_type & ADHOC_NETWORK) {
  194442. - if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
  194443. + if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
  194444. ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
  194445. "%s: ath6k not in ibss mode\n", __func__);
  194446. - return;
  194447. - }
  194448. - memset(bssid, 0, ETH_ALEN);
  194449. - cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
  194450. return;
  194451. }
  194452. diff -Nur linux-3.14.15/drivers/net/wireless/ath/ath6kl/hif.h linux-linaro-stable-mx6/drivers/net/wireless/ath/ath6kl/hif.h
  194453. --- linux-3.14.15/drivers/net/wireless/ath/ath6kl/hif.h 2014-07-31 23:51:43.000000000 +0200
  194454. +++ linux-linaro-stable-mx6/drivers/net/wireless/ath/ath6kl/hif.h 2014-08-20 19:23:54.246848776 +0200
  194455. @@ -197,9 +197,9 @@
  194456. /* bounce buffer for upper layers to copy to/from */
  194457. u8 *virt_dma_buf;
  194458. - struct hif_scatter_item scat_list[1];
  194459. -
  194460. u32 scat_q_depth;
  194461. +
  194462. + struct hif_scatter_item scat_list[0];
  194463. };
  194464. struct ath6kl_irq_proc_registers {
  194465. diff -Nur linux-3.14.15/drivers/net/wireless/ath/ath6kl/sdio.c linux-linaro-stable-mx6/drivers/net/wireless/ath/ath6kl/sdio.c
  194466. --- linux-3.14.15/drivers/net/wireless/ath/ath6kl/sdio.c 2014-07-31 23:51:43.000000000 +0200
  194467. +++ linux-linaro-stable-mx6/drivers/net/wireless/ath/ath6kl/sdio.c 2014-08-20 19:31:46.776871786 +0200
  194468. @@ -222,6 +222,7 @@
  194469. struct mmc_data *data)
  194470. {
  194471. struct scatterlist *sg;
  194472. + struct hif_scatter_item *scat_list;
  194473. int i;
  194474. data->blksz = HIF_MBOX_BLOCK_SIZE;
  194475. @@ -240,14 +241,14 @@
  194476. sg = scat_req->sgentries;
  194477. sg_init_table(sg, scat_req->scat_entries);
  194478. + scat_list = &scat_req->scat_list[0];
  194479. +
  194480. /* assemble SG list */
  194481. - for (i = 0; i < scat_req->scat_entries; i++, sg++) {
  194482. + for (i = 0; i < scat_req->scat_entries; i++, sg++, scat_list++) {
  194483. ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n",
  194484. - i, scat_req->scat_list[i].buf,
  194485. - scat_req->scat_list[i].len);
  194486. + i, scat_list->buf, scat_list->len);
  194487. - sg_set_buf(sg, scat_req->scat_list[i].buf,
  194488. - scat_req->scat_list[i].len);
  194489. + sg_set_buf(sg, scat_list->buf, scat_list->len);
  194490. }
  194491. /* set scatter-gather table for request */
  194492. @@ -348,7 +349,7 @@
  194493. int i, scat_req_sz, scat_list_sz, size;
  194494. u8 *virt_buf;
  194495. - scat_list_sz = (n_scat_entry - 1) * sizeof(struct hif_scatter_item);
  194496. + scat_list_sz = n_scat_entry * sizeof(struct hif_scatter_item);
  194497. scat_req_sz = sizeof(*s_req) + scat_list_sz;
  194498. if (!virt_scat)
  194499. diff -Nur linux-3.14.15/drivers/net/wireless/ath/ath9k/main.c linux-linaro-stable-mx6/drivers/net/wireless/ath/ath9k/main.c
  194500. --- linux-3.14.15/drivers/net/wireless/ath/ath9k/main.c 2014-07-31 23:51:43.000000000 +0200
  194501. +++ linux-linaro-stable-mx6/drivers/net/wireless/ath/ath9k/main.c 2014-08-20 19:31:46.832872028 +0200
  194502. @@ -1883,7 +1883,8 @@
  194503. return !!npend;
  194504. }
  194505. -static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  194506. +static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  194507. + u32 queues, bool drop)
  194508. {
  194509. struct ath_softc *sc = hw->priv;
  194510. struct ath_hw *ah = sc->sc_ah;
  194511. diff -Nur linux-3.14.15/drivers/net/wireless/ath/carl9170/main.c linux-linaro-stable-mx6/drivers/net/wireless/ath/carl9170/main.c
  194512. --- linux-3.14.15/drivers/net/wireless/ath/carl9170/main.c 2014-07-31 23:51:43.000000000 +0200
  194513. +++ linux-linaro-stable-mx6/drivers/net/wireless/ath/carl9170/main.c 2014-08-20 19:31:46.836872046 +0200
  194514. @@ -1707,7 +1707,9 @@
  194515. return 0;
  194516. }
  194517. -static void carl9170_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  194518. +static void carl9170_op_flush(struct ieee80211_hw *hw,
  194519. + struct ieee80211_vif *vif,
  194520. + u32 queues, bool drop)
  194521. {
  194522. struct ar9170 *ar = hw->priv;
  194523. unsigned int vid;
  194524. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
  194525. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c 2014-07-31 23:51:43.000000000 +0200
  194526. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c 2014-08-20 19:31:46.868872181 +0200
  194527. @@ -43,7 +43,6 @@
  194528. #include "dhd_bus.h"
  194529. #include "dhd_dbg.h"
  194530. #include "sdio_host.h"
  194531. -#include "sdio_chip.h"
  194532. #define SDIOH_API_ACCESS_RETRY_LIMIT 2
  194533. @@ -54,6 +53,12 @@
  194534. /* Maximum milliseconds to wait for F2 to come up */
  194535. #define SDIO_WAIT_F2RDY 3000
  194536. +#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
  194537. +#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
  194538. +
  194539. +static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
  194540. +module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
  194541. +MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
  194542. static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)
  194543. {
  194544. @@ -264,26 +269,17 @@
  194545. break;
  194546. }
  194547. - if (ret) {
  194548. - /*
  194549. - * SleepCSR register access can fail when
  194550. - * waking up the device so reduce this noise
  194551. - * in the logs.
  194552. - */
  194553. - if (addr != SBSDIO_FUNC1_SLEEPCSR)
  194554. - brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
  194555. - write ? "write" : "read", fn, addr, ret);
  194556. - else
  194557. - brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
  194558. - write ? "write" : "read", fn, addr, ret);
  194559. - }
  194560. + if (ret)
  194561. + brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
  194562. + write ? "write" : "read", fn, addr, ret);
  194563. +
  194564. return ret;
  194565. }
  194566. static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
  194567. u8 regsz, void *data, bool write)
  194568. {
  194569. - u8 func_num;
  194570. + u8 func;
  194571. s32 retry = 0;
  194572. int ret;
  194573. @@ -297,9 +293,9 @@
  194574. * The rest: function 1 silicon backplane core registers
  194575. */
  194576. if ((addr & ~REG_F0_REG_MASK) == 0)
  194577. - func_num = SDIO_FUNC_0;
  194578. + func = SDIO_FUNC_0;
  194579. else
  194580. - func_num = SDIO_FUNC_1;
  194581. + func = SDIO_FUNC_1;
  194582. do {
  194583. if (!write)
  194584. @@ -307,16 +303,26 @@
  194585. /* for retry wait for 1 ms till bus get settled down */
  194586. if (retry)
  194587. usleep_range(1000, 2000);
  194588. - ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz,
  194589. + ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
  194590. data, write);
  194591. } while (ret != 0 && ret != -ENOMEDIUM &&
  194592. retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
  194593. if (ret == -ENOMEDIUM)
  194594. brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM);
  194595. - else if (ret != 0)
  194596. - brcmf_err("failed with %d\n", ret);
  194597. -
  194598. + else if (ret != 0) {
  194599. + /*
  194600. + * SleepCSR register access can fail when
  194601. + * waking up the device so reduce this noise
  194602. + * in the logs.
  194603. + */
  194604. + if (addr != SBSDIO_FUNC1_SLEEPCSR)
  194605. + brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
  194606. + write ? "write" : "read", func, addr, ret);
  194607. + else
  194608. + brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
  194609. + write ? "write" : "read", func, addr, ret);
  194610. + }
  194611. return ret;
  194612. }
  194613. @@ -488,7 +494,6 @@
  194614. struct mmc_request mmc_req;
  194615. struct mmc_command mmc_cmd;
  194616. struct mmc_data mmc_dat;
  194617. - struct sg_table st;
  194618. struct scatterlist *sgl;
  194619. int ret = 0;
  194620. @@ -533,16 +538,11 @@
  194621. pkt_offset = 0;
  194622. pkt_next = target_list->next;
  194623. - if (sg_alloc_table(&st, max_seg_cnt, GFP_KERNEL)) {
  194624. - ret = -ENOMEM;
  194625. - goto exit;
  194626. - }
  194627. -
  194628. memset(&mmc_req, 0, sizeof(struct mmc_request));
  194629. memset(&mmc_cmd, 0, sizeof(struct mmc_command));
  194630. memset(&mmc_dat, 0, sizeof(struct mmc_data));
  194631. - mmc_dat.sg = st.sgl;
  194632. + mmc_dat.sg = sdiodev->sgtable.sgl;
  194633. mmc_dat.blksz = func_blk_sz;
  194634. mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
  194635. mmc_cmd.opcode = SD_IO_RW_EXTENDED;
  194636. @@ -558,7 +558,7 @@
  194637. while (seg_sz) {
  194638. req_sz = 0;
  194639. sg_cnt = 0;
  194640. - sgl = st.sgl;
  194641. + sgl = sdiodev->sgtable.sgl;
  194642. /* prep sg table */
  194643. while (pkt_next != (struct sk_buff *)target_list) {
  194644. pkt_data = pkt_next->data + pkt_offset;
  194645. @@ -640,7 +640,7 @@
  194646. }
  194647. exit:
  194648. - sg_free_table(&st);
  194649. + sg_init_table(sdiodev->sgtable.sgl, sdiodev->sgtable.orig_nents);
  194650. while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
  194651. brcmu_pkt_buf_free_skb(pkt_next);
  194652. @@ -827,7 +827,7 @@
  194653. }
  194654. if (!write)
  194655. memcpy(data, pkt->data, dsize);
  194656. - skb_trim(pkt, dsize);
  194657. + skb_trim(pkt, 0);
  194658. /* Adjust for next transfer (if any) */
  194659. size -= dsize;
  194660. @@ -864,6 +864,29 @@
  194661. return 0;
  194662. }
  194663. +static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
  194664. +{
  194665. + uint nents;
  194666. + int err;
  194667. +
  194668. + if (!sdiodev->sg_support)
  194669. + return;
  194670. +
  194671. + nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, brcmf_sdiod_txglomsz);
  194672. + nents += (nents >> 4) + 1;
  194673. +
  194674. + WARN_ON(nents > sdiodev->max_segment_count);
  194675. +
  194676. + brcmf_dbg(TRACE, "nents=%d\n", nents);
  194677. + err = sg_alloc_table(&sdiodev->sgtable, nents, GFP_KERNEL);
  194678. + if (err < 0) {
  194679. + brcmf_err("allocation failed: disable scatter-gather");
  194680. + sdiodev->sg_support = false;
  194681. + }
  194682. +
  194683. + sdiodev->txglomsz = brcmf_sdiod_txglomsz;
  194684. +}
  194685. +
  194686. static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
  194687. {
  194688. if (sdiodev->bus) {
  194689. @@ -881,6 +904,7 @@
  194690. sdio_disable_func(sdiodev->func[1]);
  194691. sdio_release_host(sdiodev->func[1]);
  194692. + sg_free_table(&sdiodev->sgtable);
  194693. sdiodev->sbwad = 0;
  194694. return 0;
  194695. @@ -936,6 +960,11 @@
  194696. SG_MAX_SINGLE_ALLOC);
  194697. sdiodev->max_segment_size = host->max_seg_size;
  194698. + /* allocate scatter-gather table. sg support
  194699. + * will be disabled upon allocation failure.
  194700. + */
  194701. + brcmf_sdiod_sgtable_alloc(sdiodev);
  194702. +
  194703. /* try to attach to the target device */
  194704. sdiodev->bus = brcmf_sdio_probe(sdiodev);
  194705. if (!sdiodev->bus) {
  194706. @@ -960,6 +989,7 @@
  194707. {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)},
  194708. {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM,
  194709. SDIO_DEVICE_ID_BROADCOM_4335_4339)},
  194710. + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4354)},
  194711. { /* end: all zeroes */ },
  194712. };
  194713. MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
  194714. @@ -1073,9 +1103,7 @@
  194715. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  194716. int ret = 0;
  194717. - brcmf_dbg(SDIO, "\n");
  194718. -
  194719. - atomic_set(&sdiodev->suspend, true);
  194720. + brcmf_dbg(SDIO, "Enter\n");
  194721. sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
  194722. if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
  194723. @@ -1083,9 +1111,12 @@
  194724. return -EINVAL;
  194725. }
  194726. + atomic_set(&sdiodev->suspend, true);
  194727. +
  194728. ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
  194729. if (ret) {
  194730. brcmf_err("Failed to set pm_flags\n");
  194731. + atomic_set(&sdiodev->suspend, false);
  194732. return ret;
  194733. }
  194734. @@ -1099,6 +1130,7 @@
  194735. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  194736. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  194737. + brcmf_dbg(SDIO, "Enter\n");
  194738. brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
  194739. atomic_set(&sdiodev->suspend, false);
  194740. return 0;
  194741. @@ -1115,14 +1147,15 @@
  194742. .remove = brcmf_ops_sdio_remove,
  194743. .name = BRCMFMAC_SDIO_PDATA_NAME,
  194744. .id_table = brcmf_sdmmc_ids,
  194745. -#ifdef CONFIG_PM_SLEEP
  194746. .drv = {
  194747. + .owner = THIS_MODULE,
  194748. +#ifdef CONFIG_PM_SLEEP
  194749. .pm = &brcmf_sdio_pm_ops,
  194750. - },
  194751. #endif /* CONFIG_PM_SLEEP */
  194752. + },
  194753. };
  194754. -static int brcmf_sdio_pd_probe(struct platform_device *pdev)
  194755. +static int __init brcmf_sdio_pd_probe(struct platform_device *pdev)
  194756. {
  194757. brcmf_dbg(SDIO, "Enter\n");
  194758. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/chip.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/chip.c
  194759. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/chip.c 1970-01-01 01:00:00.000000000 +0100
  194760. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/chip.c 2014-08-20 19:31:46.884872251 +0200
  194761. @@ -0,0 +1,1035 @@
  194762. +/*
  194763. + * Copyright (c) 2014 Broadcom Corporation
  194764. + *
  194765. + * Permission to use, copy, modify, and/or distribute this software for any
  194766. + * purpose with or without fee is hereby granted, provided that the above
  194767. + * copyright notice and this permission notice appear in all copies.
  194768. + *
  194769. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  194770. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  194771. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  194772. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  194773. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  194774. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  194775. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  194776. + */
  194777. +#include <linux/kernel.h>
  194778. +#include <linux/delay.h>
  194779. +#include <linux/list.h>
  194780. +#include <linux/ssb/ssb_regs.h>
  194781. +#include <linux/bcma/bcma.h>
  194782. +#include <linux/bcma/bcma_regs.h>
  194783. +
  194784. +#include <defs.h>
  194785. +#include <soc.h>
  194786. +#include <brcm_hw_ids.h>
  194787. +#include <brcmu_utils.h>
  194788. +#include <chipcommon.h>
  194789. +#include "dhd_dbg.h"
  194790. +#include "chip.h"
  194791. +
  194792. +/* SOC Interconnect types (aka chip types) */
  194793. +#define SOCI_SB 0
  194794. +#define SOCI_AI 1
  194795. +
  194796. +/* PL-368 DMP definitions */
  194797. +#define DMP_DESC_TYPE_MSK 0x0000000F
  194798. +#define DMP_DESC_EMPTY 0x00000000
  194799. +#define DMP_DESC_VALID 0x00000001
  194800. +#define DMP_DESC_COMPONENT 0x00000001
  194801. +#define DMP_DESC_MASTER_PORT 0x00000003
  194802. +#define DMP_DESC_ADDRESS 0x00000005
  194803. +#define DMP_DESC_ADDRSIZE_GT32 0x00000008
  194804. +#define DMP_DESC_EOT 0x0000000F
  194805. +
  194806. +#define DMP_COMP_DESIGNER 0xFFF00000
  194807. +#define DMP_COMP_DESIGNER_S 20
  194808. +#define DMP_COMP_PARTNUM 0x000FFF00
  194809. +#define DMP_COMP_PARTNUM_S 8
  194810. +#define DMP_COMP_CLASS 0x000000F0
  194811. +#define DMP_COMP_CLASS_S 4
  194812. +#define DMP_COMP_REVISION 0xFF000000
  194813. +#define DMP_COMP_REVISION_S 24
  194814. +#define DMP_COMP_NUM_SWRAP 0x00F80000
  194815. +#define DMP_COMP_NUM_SWRAP_S 19
  194816. +#define DMP_COMP_NUM_MWRAP 0x0007C000
  194817. +#define DMP_COMP_NUM_MWRAP_S 14
  194818. +#define DMP_COMP_NUM_SPORT 0x00003E00
  194819. +#define DMP_COMP_NUM_SPORT_S 9
  194820. +#define DMP_COMP_NUM_MPORT 0x000001F0
  194821. +#define DMP_COMP_NUM_MPORT_S 4
  194822. +
  194823. +#define DMP_MASTER_PORT_UID 0x0000FF00
  194824. +#define DMP_MASTER_PORT_UID_S 8
  194825. +#define DMP_MASTER_PORT_NUM 0x000000F0
  194826. +#define DMP_MASTER_PORT_NUM_S 4
  194827. +
  194828. +#define DMP_SLAVE_ADDR_BASE 0xFFFFF000
  194829. +#define DMP_SLAVE_ADDR_BASE_S 12
  194830. +#define DMP_SLAVE_PORT_NUM 0x00000F00
  194831. +#define DMP_SLAVE_PORT_NUM_S 8
  194832. +#define DMP_SLAVE_TYPE 0x000000C0
  194833. +#define DMP_SLAVE_TYPE_S 6
  194834. +#define DMP_SLAVE_TYPE_SLAVE 0
  194835. +#define DMP_SLAVE_TYPE_BRIDGE 1
  194836. +#define DMP_SLAVE_TYPE_SWRAP 2
  194837. +#define DMP_SLAVE_TYPE_MWRAP 3
  194838. +#define DMP_SLAVE_SIZE_TYPE 0x00000030
  194839. +#define DMP_SLAVE_SIZE_TYPE_S 4
  194840. +#define DMP_SLAVE_SIZE_4K 0
  194841. +#define DMP_SLAVE_SIZE_8K 1
  194842. +#define DMP_SLAVE_SIZE_16K 2
  194843. +#define DMP_SLAVE_SIZE_DESC 3
  194844. +
  194845. +/* EROM CompIdentB */
  194846. +#define CIB_REV_MASK 0xff000000
  194847. +#define CIB_REV_SHIFT 24
  194848. +
  194849. +/* ARM CR4 core specific control flag bits */
  194850. +#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
  194851. +
  194852. +/* D11 core specific control flag bits */
  194853. +#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
  194854. +#define D11_BCMA_IOCTL_PHYRESET 0x0008
  194855. +
  194856. +/* chip core base & ramsize */
  194857. +/* bcm4329 */
  194858. +/* SDIO device core, ID 0x829 */
  194859. +#define BCM4329_CORE_BUS_BASE 0x18011000
  194860. +/* internal memory core, ID 0x80e */
  194861. +#define BCM4329_CORE_SOCRAM_BASE 0x18003000
  194862. +/* ARM Cortex M3 core, ID 0x82a */
  194863. +#define BCM4329_CORE_ARM_BASE 0x18002000
  194864. +#define BCM4329_RAMSIZE 0x48000
  194865. +
  194866. +/* bcm43143 */
  194867. +/* SDIO device core */
  194868. +#define BCM43143_CORE_BUS_BASE 0x18002000
  194869. +/* internal memory core */
  194870. +#define BCM43143_CORE_SOCRAM_BASE 0x18004000
  194871. +/* ARM Cortex M3 core, ID 0x82a */
  194872. +#define BCM43143_CORE_ARM_BASE 0x18003000
  194873. +#define BCM43143_RAMSIZE 0x70000
  194874. +
  194875. +#define CORE_SB(base, field) \
  194876. + (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
  194877. +#define SBCOREREV(sbidh) \
  194878. + ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
  194879. + ((sbidh) & SSB_IDHIGH_RCLO))
  194880. +
  194881. +struct sbconfig {
  194882. + u32 PAD[2];
  194883. + u32 sbipsflag; /* initiator port ocp slave flag */
  194884. + u32 PAD[3];
  194885. + u32 sbtpsflag; /* target port ocp slave flag */
  194886. + u32 PAD[11];
  194887. + u32 sbtmerrloga; /* (sonics >= 2.3) */
  194888. + u32 PAD;
  194889. + u32 sbtmerrlog; /* (sonics >= 2.3) */
  194890. + u32 PAD[3];
  194891. + u32 sbadmatch3; /* address match3 */
  194892. + u32 PAD;
  194893. + u32 sbadmatch2; /* address match2 */
  194894. + u32 PAD;
  194895. + u32 sbadmatch1; /* address match1 */
  194896. + u32 PAD[7];
  194897. + u32 sbimstate; /* initiator agent state */
  194898. + u32 sbintvec; /* interrupt mask */
  194899. + u32 sbtmstatelow; /* target state */
  194900. + u32 sbtmstatehigh; /* target state */
  194901. + u32 sbbwa0; /* bandwidth allocation table0 */
  194902. + u32 PAD;
  194903. + u32 sbimconfiglow; /* initiator configuration */
  194904. + u32 sbimconfighigh; /* initiator configuration */
  194905. + u32 sbadmatch0; /* address match0 */
  194906. + u32 PAD;
  194907. + u32 sbtmconfiglow; /* target configuration */
  194908. + u32 sbtmconfighigh; /* target configuration */
  194909. + u32 sbbconfig; /* broadcast configuration */
  194910. + u32 PAD;
  194911. + u32 sbbstate; /* broadcast state */
  194912. + u32 PAD[3];
  194913. + u32 sbactcnfg; /* activate configuration */
  194914. + u32 PAD[3];
  194915. + u32 sbflagst; /* current sbflags */
  194916. + u32 PAD[3];
  194917. + u32 sbidlow; /* identification */
  194918. + u32 sbidhigh; /* identification */
  194919. +};
  194920. +
  194921. +struct brcmf_core_priv {
  194922. + struct brcmf_core pub;
  194923. + u32 wrapbase;
  194924. + struct list_head list;
  194925. + struct brcmf_chip_priv *chip;
  194926. +};
  194927. +
  194928. +/* ARM CR4 core specific control flag bits */
  194929. +#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
  194930. +
  194931. +/* D11 core specific control flag bits */
  194932. +#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
  194933. +#define D11_BCMA_IOCTL_PHYRESET 0x0008
  194934. +
  194935. +struct brcmf_chip_priv {
  194936. + struct brcmf_chip pub;
  194937. + const struct brcmf_buscore_ops *ops;
  194938. + void *ctx;
  194939. + /* assured first core is chipcommon, second core is buscore */
  194940. + struct list_head cores;
  194941. + u16 num_cores;
  194942. +
  194943. + bool (*iscoreup)(struct brcmf_core_priv *core);
  194944. + void (*coredisable)(struct brcmf_core_priv *core, u32 prereset,
  194945. + u32 reset);
  194946. + void (*resetcore)(struct brcmf_core_priv *core, u32 prereset, u32 reset,
  194947. + u32 postreset);
  194948. +};
  194949. +
  194950. +static void brcmf_chip_sb_corerev(struct brcmf_chip_priv *ci,
  194951. + struct brcmf_core *core)
  194952. +{
  194953. + u32 regdata;
  194954. +
  194955. + regdata = ci->ops->read32(ci->ctx, CORE_SB(core->base, sbidhigh));
  194956. + core->rev = SBCOREREV(regdata);
  194957. +}
  194958. +
  194959. +static bool brcmf_chip_sb_iscoreup(struct brcmf_core_priv *core)
  194960. +{
  194961. + struct brcmf_chip_priv *ci;
  194962. + u32 regdata;
  194963. + u32 address;
  194964. +
  194965. + ci = core->chip;
  194966. + address = CORE_SB(core->pub.base, sbtmstatelow);
  194967. + regdata = ci->ops->read32(ci->ctx, address);
  194968. + regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
  194969. + SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
  194970. + return SSB_TMSLOW_CLOCK == regdata;
  194971. +}
  194972. +
  194973. +static bool brcmf_chip_ai_iscoreup(struct brcmf_core_priv *core)
  194974. +{
  194975. + struct brcmf_chip_priv *ci;
  194976. + u32 regdata;
  194977. + bool ret;
  194978. +
  194979. + ci = core->chip;
  194980. + regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  194981. + ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
  194982. +
  194983. + regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
  194984. + ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
  194985. +
  194986. + return ret;
  194987. +}
  194988. +
  194989. +static void brcmf_chip_sb_coredisable(struct brcmf_core_priv *core,
  194990. + u32 prereset, u32 reset)
  194991. +{
  194992. + struct brcmf_chip_priv *ci;
  194993. + u32 val, base;
  194994. +
  194995. + ci = core->chip;
  194996. + base = core->pub.base;
  194997. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  194998. + if (val & SSB_TMSLOW_RESET)
  194999. + return;
  195000. +
  195001. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  195002. + if ((val & SSB_TMSLOW_CLOCK) != 0) {
  195003. + /*
  195004. + * set target reject and spin until busy is clear
  195005. + * (preserve core-specific bits)
  195006. + */
  195007. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  195008. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  195009. + val | SSB_TMSLOW_REJECT);
  195010. +
  195011. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  195012. + udelay(1);
  195013. + SPINWAIT((ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh))
  195014. + & SSB_TMSHIGH_BUSY), 100000);
  195015. +
  195016. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh));
  195017. + if (val & SSB_TMSHIGH_BUSY)
  195018. + brcmf_err("core state still busy\n");
  195019. +
  195020. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
  195021. + if (val & SSB_IDLOW_INITIATOR) {
  195022. + val = ci->ops->read32(ci->ctx,
  195023. + CORE_SB(base, sbimstate));
  195024. + val |= SSB_IMSTATE_REJECT;
  195025. + ci->ops->write32(ci->ctx,
  195026. + CORE_SB(base, sbimstate), val);
  195027. + val = ci->ops->read32(ci->ctx,
  195028. + CORE_SB(base, sbimstate));
  195029. + udelay(1);
  195030. + SPINWAIT((ci->ops->read32(ci->ctx,
  195031. + CORE_SB(base, sbimstate)) &
  195032. + SSB_IMSTATE_BUSY), 100000);
  195033. + }
  195034. +
  195035. + /* set reset and reject while enabling the clocks */
  195036. + val = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
  195037. + SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
  195038. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow), val);
  195039. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  195040. + udelay(10);
  195041. +
  195042. + /* clear the initiator reject bit */
  195043. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
  195044. + if (val & SSB_IDLOW_INITIATOR) {
  195045. + val = ci->ops->read32(ci->ctx,
  195046. + CORE_SB(base, sbimstate));
  195047. + val &= ~SSB_IMSTATE_REJECT;
  195048. + ci->ops->write32(ci->ctx,
  195049. + CORE_SB(base, sbimstate), val);
  195050. + }
  195051. + }
  195052. +
  195053. + /* leave reset and reject asserted */
  195054. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  195055. + (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
  195056. + udelay(1);
  195057. +}
  195058. +
  195059. +static void brcmf_chip_ai_coredisable(struct brcmf_core_priv *core,
  195060. + u32 prereset, u32 reset)
  195061. +{
  195062. + struct brcmf_chip_priv *ci;
  195063. + u32 regdata;
  195064. +
  195065. + ci = core->chip;
  195066. +
  195067. + /* if core is already in reset, skip reset */
  195068. + regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
  195069. + if ((regdata & BCMA_RESET_CTL_RESET) != 0)
  195070. + goto in_reset_configure;
  195071. +
  195072. + /* configure reset */
  195073. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
  195074. + prereset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
  195075. + ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  195076. +
  195077. + /* put in reset */
  195078. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_RESET_CTL,
  195079. + BCMA_RESET_CTL_RESET);
  195080. + usleep_range(10, 20);
  195081. +
  195082. + /* wait till reset is 1 */
  195083. + SPINWAIT(ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) !=
  195084. + BCMA_RESET_CTL_RESET, 300);
  195085. +
  195086. +in_reset_configure:
  195087. + /* in-reset configure */
  195088. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
  195089. + reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
  195090. + ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  195091. +}
  195092. +
  195093. +static void brcmf_chip_sb_resetcore(struct brcmf_core_priv *core, u32 prereset,
  195094. + u32 reset, u32 postreset)
  195095. +{
  195096. + struct brcmf_chip_priv *ci;
  195097. + u32 regdata;
  195098. + u32 base;
  195099. +
  195100. + ci = core->chip;
  195101. + base = core->pub.base;
  195102. + /*
  195103. + * Must do the disable sequence first to work for
  195104. + * arbitrary current core state.
  195105. + */
  195106. + brcmf_chip_sb_coredisable(core, 0, 0);
  195107. +
  195108. + /*
  195109. + * Now do the initialization sequence.
  195110. + * set reset while enabling the clock and
  195111. + * forcing them on throughout the core
  195112. + */
  195113. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  195114. + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
  195115. + SSB_TMSLOW_RESET);
  195116. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  195117. + udelay(1);
  195118. +
  195119. + /* clear any serror */
  195120. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh));
  195121. + if (regdata & SSB_TMSHIGH_SERR)
  195122. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatehigh), 0);
  195123. +
  195124. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbimstate));
  195125. + if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) {
  195126. + regdata &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO);
  195127. + ci->ops->write32(ci->ctx, CORE_SB(base, sbimstate), regdata);
  195128. + }
  195129. +
  195130. + /* clear reset and allow it to propagate throughout the core */
  195131. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  195132. + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK);
  195133. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  195134. + udelay(1);
  195135. +
  195136. + /* leave clock enabled */
  195137. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  195138. + SSB_TMSLOW_CLOCK);
  195139. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  195140. + udelay(1);
  195141. +}
  195142. +
  195143. +static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset,
  195144. + u32 reset, u32 postreset)
  195145. +{
  195146. + struct brcmf_chip_priv *ci;
  195147. + int count;
  195148. +
  195149. + ci = core->chip;
  195150. +
  195151. + /* must disable first to work for arbitrary current core state */
  195152. + brcmf_chip_ai_coredisable(core, prereset, reset);
  195153. +
  195154. + count = 0;
  195155. + while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) &
  195156. + BCMA_RESET_CTL_RESET) {
  195157. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_RESET_CTL, 0);
  195158. + count++;
  195159. + if (count > 50)
  195160. + break;
  195161. + usleep_range(40, 60);
  195162. + }
  195163. +
  195164. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
  195165. + postreset | BCMA_IOCTL_CLK);
  195166. + ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  195167. +}
  195168. +
  195169. +static char *brcmf_chip_name(uint chipid, char *buf, uint len)
  195170. +{
  195171. + const char *fmt;
  195172. +
  195173. + fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
  195174. + snprintf(buf, len, fmt, chipid);
  195175. + return buf;
  195176. +}
  195177. +
  195178. +static struct brcmf_core *brcmf_chip_add_core(struct brcmf_chip_priv *ci,
  195179. + u16 coreid, u32 base,
  195180. + u32 wrapbase)
  195181. +{
  195182. + struct brcmf_core_priv *core;
  195183. +
  195184. + core = kzalloc(sizeof(*core), GFP_KERNEL);
  195185. + if (!core)
  195186. + return ERR_PTR(-ENOMEM);
  195187. +
  195188. + core->pub.id = coreid;
  195189. + core->pub.base = base;
  195190. + core->chip = ci;
  195191. + core->wrapbase = wrapbase;
  195192. +
  195193. + list_add_tail(&core->list, &ci->cores);
  195194. + return &core->pub;
  195195. +}
  195196. +
  195197. +#ifdef DEBUG
  195198. +/* safety check for chipinfo */
  195199. +static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
  195200. +{
  195201. + struct brcmf_core_priv *core;
  195202. + bool need_socram = false;
  195203. + bool has_socram = false;
  195204. + int idx = 1;
  195205. +
  195206. + list_for_each_entry(core, &ci->cores, list) {
  195207. + brcmf_dbg(INFO, " [%-2d] core 0x%x:%-2d base 0x%08x wrap 0x%08x\n",
  195208. + idx++, core->pub.id, core->pub.rev, core->pub.base,
  195209. + core->wrapbase);
  195210. +
  195211. + switch (core->pub.id) {
  195212. + case BCMA_CORE_ARM_CM3:
  195213. + need_socram = true;
  195214. + break;
  195215. + case BCMA_CORE_INTERNAL_MEM:
  195216. + has_socram = true;
  195217. + break;
  195218. + case BCMA_CORE_ARM_CR4:
  195219. + if (ci->pub.rambase == 0) {
  195220. + brcmf_err("RAM base not provided with ARM CR4 core\n");
  195221. + return -ENOMEM;
  195222. + }
  195223. + break;
  195224. + default:
  195225. + break;
  195226. + }
  195227. + }
  195228. +
  195229. + /* check RAM core presence for ARM CM3 core */
  195230. + if (need_socram && !has_socram) {
  195231. + brcmf_err("RAM core not provided with ARM CM3 core\n");
  195232. + return -ENODEV;
  195233. + }
  195234. + return 0;
  195235. +}
  195236. +#else /* DEBUG */
  195237. +static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
  195238. +{
  195239. + return 0;
  195240. +}
  195241. +#endif
  195242. +
  195243. +static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
  195244. +{
  195245. + switch (ci->pub.chip) {
  195246. + case BCM4329_CHIP_ID:
  195247. + ci->pub.ramsize = BCM4329_RAMSIZE;
  195248. + break;
  195249. + case BCM43143_CHIP_ID:
  195250. + ci->pub.ramsize = BCM43143_RAMSIZE;
  195251. + break;
  195252. + case BCM43241_CHIP_ID:
  195253. + ci->pub.ramsize = 0x90000;
  195254. + break;
  195255. + case BCM4330_CHIP_ID:
  195256. + ci->pub.ramsize = 0x48000;
  195257. + break;
  195258. + case BCM4334_CHIP_ID:
  195259. + ci->pub.ramsize = 0x80000;
  195260. + break;
  195261. + case BCM4335_CHIP_ID:
  195262. + ci->pub.ramsize = 0xc0000;
  195263. + ci->pub.rambase = 0x180000;
  195264. + break;
  195265. + case BCM43362_CHIP_ID:
  195266. + ci->pub.ramsize = 0x3c000;
  195267. + break;
  195268. + case BCM4339_CHIP_ID:
  195269. + case BCM4354_CHIP_ID:
  195270. + ci->pub.ramsize = 0xc0000;
  195271. + ci->pub.rambase = 0x180000;
  195272. + break;
  195273. + default:
  195274. + brcmf_err("unknown chip: %s\n", ci->pub.name);
  195275. + break;
  195276. + }
  195277. +}
  195278. +
  195279. +static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
  195280. + u8 *type)
  195281. +{
  195282. + u32 val;
  195283. +
  195284. + /* read next descriptor */
  195285. + val = ci->ops->read32(ci->ctx, *eromaddr);
  195286. + *eromaddr += 4;
  195287. +
  195288. + if (!type)
  195289. + return val;
  195290. +
  195291. + /* determine descriptor type */
  195292. + *type = (val & DMP_DESC_TYPE_MSK);
  195293. + if ((*type & ~DMP_DESC_ADDRSIZE_GT32) == DMP_DESC_ADDRESS)
  195294. + *type = DMP_DESC_ADDRESS;
  195295. +
  195296. + return val;
  195297. +}
  195298. +
  195299. +static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv *ci, u32 *eromaddr,
  195300. + u32 *regbase, u32 *wrapbase)
  195301. +{
  195302. + u8 desc;
  195303. + u32 val;
  195304. + u8 mpnum = 0;
  195305. + u8 stype, sztype, wraptype;
  195306. +
  195307. + *regbase = 0;
  195308. + *wrapbase = 0;
  195309. +
  195310. + val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
  195311. + if (desc == DMP_DESC_MASTER_PORT) {
  195312. + mpnum = (val & DMP_MASTER_PORT_NUM) >> DMP_MASTER_PORT_NUM_S;
  195313. + wraptype = DMP_SLAVE_TYPE_MWRAP;
  195314. + } else if (desc == DMP_DESC_ADDRESS) {
  195315. + /* revert erom address */
  195316. + *eromaddr -= 4;
  195317. + wraptype = DMP_SLAVE_TYPE_SWRAP;
  195318. + } else {
  195319. + *eromaddr -= 4;
  195320. + return -EILSEQ;
  195321. + }
  195322. +
  195323. + do {
  195324. + /* locate address descriptor */
  195325. + do {
  195326. + val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
  195327. + /* unexpected table end */
  195328. + if (desc == DMP_DESC_EOT) {
  195329. + *eromaddr -= 4;
  195330. + return -EFAULT;
  195331. + }
  195332. + } while (desc != DMP_DESC_ADDRESS);
  195333. +
  195334. + /* skip upper 32-bit address descriptor */
  195335. + if (val & DMP_DESC_ADDRSIZE_GT32)
  195336. + brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
  195337. +
  195338. + sztype = (val & DMP_SLAVE_SIZE_TYPE) >> DMP_SLAVE_SIZE_TYPE_S;
  195339. +
  195340. + /* next size descriptor can be skipped */
  195341. + if (sztype == DMP_SLAVE_SIZE_DESC) {
  195342. + val = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
  195343. + /* skip upper size descriptor if present */
  195344. + if (val & DMP_DESC_ADDRSIZE_GT32)
  195345. + brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
  195346. + }
  195347. +
  195348. + /* only look for 4K register regions */
  195349. + if (sztype != DMP_SLAVE_SIZE_4K)
  195350. + continue;
  195351. +
  195352. + stype = (val & DMP_SLAVE_TYPE) >> DMP_SLAVE_TYPE_S;
  195353. +
  195354. + /* only regular slave and wrapper */
  195355. + if (*regbase == 0 && stype == DMP_SLAVE_TYPE_SLAVE)
  195356. + *regbase = val & DMP_SLAVE_ADDR_BASE;
  195357. + if (*wrapbase == 0 && stype == wraptype)
  195358. + *wrapbase = val & DMP_SLAVE_ADDR_BASE;
  195359. + } while (*regbase == 0 || *wrapbase == 0);
  195360. +
  195361. + return 0;
  195362. +}
  195363. +
  195364. +static
  195365. +int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci)
  195366. +{
  195367. + struct brcmf_core *core;
  195368. + u32 eromaddr;
  195369. + u8 desc_type = 0;
  195370. + u32 val;
  195371. + u16 id;
  195372. + u8 nmp, nsp, nmw, nsw, rev;
  195373. + u32 base, wrap;
  195374. + int err;
  195375. +
  195376. + eromaddr = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, eromptr));
  195377. +
  195378. + while (desc_type != DMP_DESC_EOT) {
  195379. + val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
  195380. + if (!(val & DMP_DESC_VALID))
  195381. + continue;
  195382. +
  195383. + if (desc_type == DMP_DESC_EMPTY)
  195384. + continue;
  195385. +
  195386. + /* need a component descriptor */
  195387. + if (desc_type != DMP_DESC_COMPONENT)
  195388. + continue;
  195389. +
  195390. + id = (val & DMP_COMP_PARTNUM) >> DMP_COMP_PARTNUM_S;
  195391. +
  195392. + /* next descriptor must be component as well */
  195393. + val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
  195394. + if (WARN_ON((val & DMP_DESC_TYPE_MSK) != DMP_DESC_COMPONENT))
  195395. + return -EFAULT;
  195396. +
  195397. + /* only look at cores with master port(s) */
  195398. + nmp = (val & DMP_COMP_NUM_MPORT) >> DMP_COMP_NUM_MPORT_S;
  195399. + nsp = (val & DMP_COMP_NUM_SPORT) >> DMP_COMP_NUM_SPORT_S;
  195400. + nmw = (val & DMP_COMP_NUM_MWRAP) >> DMP_COMP_NUM_MWRAP_S;
  195401. + nsw = (val & DMP_COMP_NUM_SWRAP) >> DMP_COMP_NUM_SWRAP_S;
  195402. + rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S;
  195403. +
  195404. + /* need core with ports */
  195405. + if (nmw + nsw == 0)
  195406. + continue;
  195407. +
  195408. + /* try to obtain register address info */
  195409. + err = brcmf_chip_dmp_get_regaddr(ci, &eromaddr, &base, &wrap);
  195410. + if (err)
  195411. + continue;
  195412. +
  195413. + /* finally a core to be added */
  195414. + core = brcmf_chip_add_core(ci, id, base, wrap);
  195415. + if (IS_ERR(core))
  195416. + return PTR_ERR(core);
  195417. +
  195418. + core->rev = rev;
  195419. + }
  195420. +
  195421. + return 0;
  195422. +}
  195423. +
  195424. +static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
  195425. +{
  195426. + struct brcmf_core *core;
  195427. + u32 regdata;
  195428. + u32 socitype;
  195429. +
  195430. + /* Get CC core rev
  195431. + * Chipid is assume to be at offset 0 from SI_ENUM_BASE
  195432. + * For different chiptypes or old sdio hosts w/o chipcommon,
  195433. + * other ways of recognition should be added here.
  195434. + */
  195435. + regdata = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, chipid));
  195436. + ci->pub.chip = regdata & CID_ID_MASK;
  195437. + ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
  195438. + socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
  195439. +
  195440. + brcmf_chip_name(ci->pub.chip, ci->pub.name, sizeof(ci->pub.name));
  195441. + brcmf_dbg(INFO, "found %s chip: BCM%s, rev=%d\n",
  195442. + socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name,
  195443. + ci->pub.chiprev);
  195444. +
  195445. + if (socitype == SOCI_SB) {
  195446. + if (ci->pub.chip != BCM4329_CHIP_ID) {
  195447. + brcmf_err("SB chip is not supported\n");
  195448. + return -ENODEV;
  195449. + }
  195450. + ci->iscoreup = brcmf_chip_sb_iscoreup;
  195451. + ci->coredisable = brcmf_chip_sb_coredisable;
  195452. + ci->resetcore = brcmf_chip_sb_resetcore;
  195453. +
  195454. + core = brcmf_chip_add_core(ci, BCMA_CORE_CHIPCOMMON,
  195455. + SI_ENUM_BASE, 0);
  195456. + brcmf_chip_sb_corerev(ci, core);
  195457. + core = brcmf_chip_add_core(ci, BCMA_CORE_SDIO_DEV,
  195458. + BCM4329_CORE_BUS_BASE, 0);
  195459. + brcmf_chip_sb_corerev(ci, core);
  195460. + core = brcmf_chip_add_core(ci, BCMA_CORE_INTERNAL_MEM,
  195461. + BCM4329_CORE_SOCRAM_BASE, 0);
  195462. + brcmf_chip_sb_corerev(ci, core);
  195463. + core = brcmf_chip_add_core(ci, BCMA_CORE_ARM_CM3,
  195464. + BCM4329_CORE_ARM_BASE, 0);
  195465. + brcmf_chip_sb_corerev(ci, core);
  195466. +
  195467. + core = brcmf_chip_add_core(ci, BCMA_CORE_80211, 0x18001000, 0);
  195468. + brcmf_chip_sb_corerev(ci, core);
  195469. + } else if (socitype == SOCI_AI) {
  195470. + ci->iscoreup = brcmf_chip_ai_iscoreup;
  195471. + ci->coredisable = brcmf_chip_ai_coredisable;
  195472. + ci->resetcore = brcmf_chip_ai_resetcore;
  195473. +
  195474. + brcmf_chip_dmp_erom_scan(ci);
  195475. + } else {
  195476. + brcmf_err("chip backplane type %u is not supported\n",
  195477. + socitype);
  195478. + return -ENODEV;
  195479. + }
  195480. +
  195481. + brcmf_chip_get_raminfo(ci);
  195482. +
  195483. + return brcmf_chip_cores_check(ci);
  195484. +}
  195485. +
  195486. +static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
  195487. +{
  195488. + struct brcmf_core *core;
  195489. + struct brcmf_core_priv *cr4;
  195490. + u32 val;
  195491. +
  195492. +
  195493. + core = brcmf_chip_get_core(&chip->pub, id);
  195494. + if (!core)
  195495. + return;
  195496. +
  195497. + switch (id) {
  195498. + case BCMA_CORE_ARM_CM3:
  195499. + brcmf_chip_coredisable(core, 0, 0);
  195500. + break;
  195501. + case BCMA_CORE_ARM_CR4:
  195502. + cr4 = container_of(core, struct brcmf_core_priv, pub);
  195503. +
  195504. + /* clear all IOCTL bits except HALT bit */
  195505. + val = chip->ops->read32(chip->ctx, cr4->wrapbase + BCMA_IOCTL);
  195506. + val &= ARMCR4_BCMA_IOCTL_CPUHALT;
  195507. + brcmf_chip_resetcore(core, val, ARMCR4_BCMA_IOCTL_CPUHALT,
  195508. + ARMCR4_BCMA_IOCTL_CPUHALT);
  195509. + break;
  195510. + default:
  195511. + brcmf_err("unknown id: %u\n", id);
  195512. + break;
  195513. + }
  195514. +}
  195515. +
  195516. +static int brcmf_chip_setup(struct brcmf_chip_priv *chip)
  195517. +{
  195518. + struct brcmf_chip *pub;
  195519. + struct brcmf_core_priv *cc;
  195520. + u32 base;
  195521. + u32 val;
  195522. + int ret = 0;
  195523. +
  195524. + pub = &chip->pub;
  195525. + cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
  195526. + base = cc->pub.base;
  195527. +
  195528. + /* get chipcommon capabilites */
  195529. + pub->cc_caps = chip->ops->read32(chip->ctx,
  195530. + CORE_CC_REG(base, capabilities));
  195531. +
  195532. + /* get pmu caps & rev */
  195533. + if (pub->cc_caps & CC_CAP_PMU) {
  195534. + val = chip->ops->read32(chip->ctx,
  195535. + CORE_CC_REG(base, pmucapabilities));
  195536. + pub->pmurev = val & PCAP_REV_MASK;
  195537. + pub->pmucaps = val;
  195538. + }
  195539. +
  195540. + brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, pmucaps=0x%x\n",
  195541. + cc->pub.rev, pub->pmurev, pub->pmucaps);
  195542. +
  195543. + /* execute bus core specific setup */
  195544. + if (chip->ops->setup)
  195545. + ret = chip->ops->setup(chip->ctx, pub);
  195546. +
  195547. + /*
  195548. + * Make sure any on-chip ARM is off (in case strapping is wrong),
  195549. + * or downloaded code was already running.
  195550. + */
  195551. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
  195552. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
  195553. + return ret;
  195554. +}
  195555. +
  195556. +struct brcmf_chip *brcmf_chip_attach(void *ctx,
  195557. + const struct brcmf_buscore_ops *ops)
  195558. +{
  195559. + struct brcmf_chip_priv *chip;
  195560. + int err = 0;
  195561. +
  195562. + if (WARN_ON(!ops->read32))
  195563. + err = -EINVAL;
  195564. + if (WARN_ON(!ops->write32))
  195565. + err = -EINVAL;
  195566. + if (WARN_ON(!ops->prepare))
  195567. + err = -EINVAL;
  195568. + if (WARN_ON(!ops->exit_dl))
  195569. + err = -EINVAL;
  195570. + if (err < 0)
  195571. + return ERR_PTR(-EINVAL);
  195572. +
  195573. + chip = kzalloc(sizeof(*chip), GFP_KERNEL);
  195574. + if (!chip)
  195575. + return ERR_PTR(-ENOMEM);
  195576. +
  195577. + INIT_LIST_HEAD(&chip->cores);
  195578. + chip->num_cores = 0;
  195579. + chip->ops = ops;
  195580. + chip->ctx = ctx;
  195581. +
  195582. + err = ops->prepare(ctx);
  195583. + if (err < 0)
  195584. + goto fail;
  195585. +
  195586. + err = brcmf_chip_recognition(chip);
  195587. + if (err < 0)
  195588. + goto fail;
  195589. +
  195590. + err = brcmf_chip_setup(chip);
  195591. + if (err < 0)
  195592. + goto fail;
  195593. +
  195594. + return &chip->pub;
  195595. +
  195596. +fail:
  195597. + brcmf_chip_detach(&chip->pub);
  195598. + return ERR_PTR(err);
  195599. +}
  195600. +
  195601. +void brcmf_chip_detach(struct brcmf_chip *pub)
  195602. +{
  195603. + struct brcmf_chip_priv *chip;
  195604. + struct brcmf_core_priv *core;
  195605. + struct brcmf_core_priv *tmp;
  195606. +
  195607. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195608. + list_for_each_entry_safe(core, tmp, &chip->cores, list) {
  195609. + list_del(&core->list);
  195610. + kfree(core);
  195611. + }
  195612. + kfree(chip);
  195613. +}
  195614. +
  195615. +struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
  195616. +{
  195617. + struct brcmf_chip_priv *chip;
  195618. + struct brcmf_core_priv *core;
  195619. +
  195620. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195621. + list_for_each_entry(core, &chip->cores, list)
  195622. + if (core->pub.id == coreid)
  195623. + return &core->pub;
  195624. +
  195625. + return NULL;
  195626. +}
  195627. +
  195628. +struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *pub)
  195629. +{
  195630. + struct brcmf_chip_priv *chip;
  195631. + struct brcmf_core_priv *cc;
  195632. +
  195633. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195634. + cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
  195635. + if (WARN_ON(!cc || cc->pub.id != BCMA_CORE_CHIPCOMMON))
  195636. + return brcmf_chip_get_core(pub, BCMA_CORE_CHIPCOMMON);
  195637. + return &cc->pub;
  195638. +}
  195639. +
  195640. +bool brcmf_chip_iscoreup(struct brcmf_core *pub)
  195641. +{
  195642. + struct brcmf_core_priv *core;
  195643. +
  195644. + core = container_of(pub, struct brcmf_core_priv, pub);
  195645. + return core->chip->iscoreup(core);
  195646. +}
  195647. +
  195648. +void brcmf_chip_coredisable(struct brcmf_core *pub, u32 prereset, u32 reset)
  195649. +{
  195650. + struct brcmf_core_priv *core;
  195651. +
  195652. + core = container_of(pub, struct brcmf_core_priv, pub);
  195653. + core->chip->coredisable(core, prereset, reset);
  195654. +}
  195655. +
  195656. +void brcmf_chip_resetcore(struct brcmf_core *pub, u32 prereset, u32 reset,
  195657. + u32 postreset)
  195658. +{
  195659. + struct brcmf_core_priv *core;
  195660. +
  195661. + core = container_of(pub, struct brcmf_core_priv, pub);
  195662. + core->chip->resetcore(core, prereset, reset, postreset);
  195663. +}
  195664. +
  195665. +static void
  195666. +brcmf_chip_cm3_enterdl(struct brcmf_chip_priv *chip)
  195667. +{
  195668. + struct brcmf_core *core;
  195669. +
  195670. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
  195671. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
  195672. + brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
  195673. + D11_BCMA_IOCTL_PHYCLOCKEN,
  195674. + D11_BCMA_IOCTL_PHYCLOCKEN,
  195675. + D11_BCMA_IOCTL_PHYCLOCKEN);
  195676. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
  195677. + brcmf_chip_resetcore(core, 0, 0, 0);
  195678. +}
  195679. +
  195680. +static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv *chip)
  195681. +{
  195682. + struct brcmf_core *core;
  195683. +
  195684. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
  195685. + if (!brcmf_chip_iscoreup(core)) {
  195686. + brcmf_err("SOCRAM core is down after reset?\n");
  195687. + return false;
  195688. + }
  195689. +
  195690. + chip->ops->exit_dl(chip->ctx, &chip->pub, 0);
  195691. +
  195692. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3);
  195693. + brcmf_chip_resetcore(core, 0, 0, 0);
  195694. +
  195695. + return true;
  195696. +}
  195697. +
  195698. +static inline void
  195699. +brcmf_chip_cr4_enterdl(struct brcmf_chip_priv *chip)
  195700. +{
  195701. + struct brcmf_core *core;
  195702. +
  195703. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
  195704. +
  195705. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
  195706. + brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
  195707. + D11_BCMA_IOCTL_PHYCLOCKEN,
  195708. + D11_BCMA_IOCTL_PHYCLOCKEN,
  195709. + D11_BCMA_IOCTL_PHYCLOCKEN);
  195710. +}
  195711. +
  195712. +static bool brcmf_chip_cr4_exitdl(struct brcmf_chip_priv *chip, u32 rstvec)
  195713. +{
  195714. + struct brcmf_core *core;
  195715. +
  195716. + chip->ops->exit_dl(chip->ctx, &chip->pub, rstvec);
  195717. +
  195718. + /* restore ARM */
  195719. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4);
  195720. + brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);
  195721. +
  195722. + return true;
  195723. +}
  195724. +
  195725. +void brcmf_chip_enter_download(struct brcmf_chip *pub)
  195726. +{
  195727. + struct brcmf_chip_priv *chip;
  195728. + struct brcmf_core *arm;
  195729. +
  195730. + brcmf_dbg(TRACE, "Enter\n");
  195731. +
  195732. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195733. + arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
  195734. + if (arm) {
  195735. + brcmf_chip_cr4_enterdl(chip);
  195736. + return;
  195737. + }
  195738. +
  195739. + brcmf_chip_cm3_enterdl(chip);
  195740. +}
  195741. +
  195742. +bool brcmf_chip_exit_download(struct brcmf_chip *pub, u32 rstvec)
  195743. +{
  195744. + struct brcmf_chip_priv *chip;
  195745. + struct brcmf_core *arm;
  195746. +
  195747. + brcmf_dbg(TRACE, "Enter\n");
  195748. +
  195749. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195750. + arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
  195751. + if (arm)
  195752. + return brcmf_chip_cr4_exitdl(chip, rstvec);
  195753. +
  195754. + return brcmf_chip_cm3_exitdl(chip);
  195755. +}
  195756. +
  195757. +bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
  195758. +{
  195759. + u32 base, addr, reg, pmu_cc3_mask = ~0;
  195760. + struct brcmf_chip_priv *chip;
  195761. +
  195762. + brcmf_dbg(TRACE, "Enter\n");
  195763. +
  195764. + /* old chips with PMU version less than 17 don't support save restore */
  195765. + if (pub->pmurev < 17)
  195766. + return false;
  195767. +
  195768. + base = brcmf_chip_get_chipcommon(pub)->base;
  195769. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195770. +
  195771. + switch (pub->chip) {
  195772. + case BCM4354_CHIP_ID:
  195773. + /* explicitly check SR engine enable bit */
  195774. + pmu_cc3_mask = BIT(2);
  195775. + /* fall-through */
  195776. + case BCM43241_CHIP_ID:
  195777. + case BCM4335_CHIP_ID:
  195778. + case BCM4339_CHIP_ID:
  195779. + /* read PMU chipcontrol register 3 */
  195780. + addr = CORE_CC_REG(base, chipcontrol_addr);
  195781. + chip->ops->write32(chip->ctx, addr, 3);
  195782. + addr = CORE_CC_REG(base, chipcontrol_data);
  195783. + reg = chip->ops->read32(chip->ctx, addr);
  195784. + return (reg & pmu_cc3_mask) != 0;
  195785. + default:
  195786. + addr = CORE_CC_REG(base, pmucapabilities_ext);
  195787. + reg = chip->ops->read32(chip->ctx, addr);
  195788. + if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
  195789. + return false;
  195790. +
  195791. + addr = CORE_CC_REG(base, retention_ctl);
  195792. + reg = chip->ops->read32(chip->ctx, addr);
  195793. + return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
  195794. + PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
  195795. + }
  195796. +}
  195797. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/chip.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/chip.h
  195798. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/chip.h 1970-01-01 01:00:00.000000000 +0100
  195799. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/chip.h 2014-08-20 19:31:46.884872251 +0200
  195800. @@ -0,0 +1,91 @@
  195801. +/*
  195802. + * Copyright (c) 2014 Broadcom Corporation
  195803. + *
  195804. + * Permission to use, copy, modify, and/or distribute this software for any
  195805. + * purpose with or without fee is hereby granted, provided that the above
  195806. + * copyright notice and this permission notice appear in all copies.
  195807. + *
  195808. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  195809. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  195810. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  195811. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  195812. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  195813. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  195814. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  195815. + */
  195816. +#ifndef BRCMF_CHIP_H
  195817. +#define BRCMF_CHIP_H
  195818. +
  195819. +#include <linux/types.h>
  195820. +
  195821. +#define CORE_CC_REG(base, field) \
  195822. + (base + offsetof(struct chipcregs, field))
  195823. +
  195824. +/**
  195825. + * struct brcmf_chip - chip level information.
  195826. + *
  195827. + * @chip: chip identifier.
  195828. + * @chiprev: chip revision.
  195829. + * @cc_caps: chipcommon core capabilities.
  195830. + * @pmucaps: PMU capabilities.
  195831. + * @pmurev: PMU revision.
  195832. + * @rambase: RAM base address (only applicable for ARM CR4 chips).
  195833. + * @ramsize: amount of RAM on chip.
  195834. + * @name: string representation of the chip identifier.
  195835. + */
  195836. +struct brcmf_chip {
  195837. + u32 chip;
  195838. + u32 chiprev;
  195839. + u32 cc_caps;
  195840. + u32 pmucaps;
  195841. + u32 pmurev;
  195842. + u32 rambase;
  195843. + u32 ramsize;
  195844. + char name[8];
  195845. +};
  195846. +
  195847. +/**
  195848. + * struct brcmf_core - core related information.
  195849. + *
  195850. + * @id: core identifier.
  195851. + * @rev: core revision.
  195852. + * @base: base address of core register space.
  195853. + */
  195854. +struct brcmf_core {
  195855. + u16 id;
  195856. + u16 rev;
  195857. + u32 base;
  195858. +};
  195859. +
  195860. +/**
  195861. + * struct brcmf_buscore_ops - buscore specific callbacks.
  195862. + *
  195863. + * @read32: read 32-bit value over bus.
  195864. + * @write32: write 32-bit value over bus.
  195865. + * @prepare: prepare bus for core configuration.
  195866. + * @setup: bus-specific core setup.
  195867. + * @exit_dl: exit download state.
  195868. + * The callback should use the provided @rstvec when non-zero.
  195869. + */
  195870. +struct brcmf_buscore_ops {
  195871. + u32 (*read32)(void *ctx, u32 addr);
  195872. + void (*write32)(void *ctx, u32 addr, u32 value);
  195873. + int (*prepare)(void *ctx);
  195874. + int (*setup)(void *ctx, struct brcmf_chip *chip);
  195875. + void (*exit_dl)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
  195876. +};
  195877. +
  195878. +struct brcmf_chip *brcmf_chip_attach(void *ctx,
  195879. + const struct brcmf_buscore_ops *ops);
  195880. +void brcmf_chip_detach(struct brcmf_chip *chip);
  195881. +struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
  195882. +struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip);
  195883. +bool brcmf_chip_iscoreup(struct brcmf_core *core);
  195884. +void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset);
  195885. +void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset,
  195886. + u32 postreset);
  195887. +void brcmf_chip_enter_download(struct brcmf_chip *ci);
  195888. +bool brcmf_chip_exit_download(struct brcmf_chip *ci, u32 rstvec);
  195889. +bool brcmf_chip_sr_capable(struct brcmf_chip *pub);
  195890. +
  195891. +#endif /* BRCMF_AXIDMP_H */
  195892. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
  195893. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h 2014-07-31 23:51:43.000000000 +0200
  195894. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h 2014-08-20 19:31:46.884872251 +0200
  195895. @@ -63,7 +63,6 @@
  195896. */
  195897. struct brcmf_bus_ops {
  195898. int (*preinit)(struct device *dev);
  195899. - int (*init)(struct device *dev);
  195900. void (*stop)(struct device *dev);
  195901. int (*txdata)(struct device *dev, struct sk_buff *skb);
  195902. int (*txctl)(struct device *dev, unsigned char *msg, uint len);
  195903. @@ -99,6 +98,7 @@
  195904. unsigned long tx_realloc;
  195905. u32 chip;
  195906. u32 chiprev;
  195907. + bool always_use_fws_queue;
  195908. struct brcmf_bus_ops *ops;
  195909. };
  195910. @@ -113,11 +113,6 @@
  195911. return bus->ops->preinit(bus->dev);
  195912. }
  195913. -static inline int brcmf_bus_init(struct brcmf_bus *bus)
  195914. -{
  195915. - return bus->ops->init(bus->dev);
  195916. -}
  195917. -
  195918. static inline void brcmf_bus_stop(struct brcmf_bus *bus)
  195919. {
  195920. bus->ops->stop(bus->dev);
  195921. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
  195922. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c 2014-07-31 23:51:43.000000000 +0200
  195923. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c 2014-08-20 19:31:46.884872251 +0200
  195924. @@ -32,6 +32,9 @@
  195925. #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
  195926. #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00"
  195927. +/* boost value for RSSI_DELTA in preferred join selection */
  195928. +#define BRCMF_JOIN_PREF_RSSI_BOOST 8
  195929. +
  195930. bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
  195931. struct sk_buff *pkt, int prec)
  195932. @@ -246,6 +249,7 @@
  195933. {
  195934. s8 eventmask[BRCMF_EVENTING_MASK_LEN];
  195935. u8 buf[BRCMF_DCMD_SMLEN];
  195936. + struct brcmf_join_pref_params join_pref_params[2];
  195937. char *ptr;
  195938. s32 err;
  195939. @@ -298,6 +302,20 @@
  195940. goto done;
  195941. }
  195942. + /* Setup join_pref to select target by RSSI(with boost on 5GHz) */
  195943. + join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA;
  195944. + join_pref_params[0].len = 2;
  195945. + join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST;
  195946. + join_pref_params[0].band = WLC_BAND_5G;
  195947. + join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI;
  195948. + join_pref_params[1].len = 2;
  195949. + join_pref_params[1].rssi_gain = 0;
  195950. + join_pref_params[1].band = 0;
  195951. + err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
  195952. + sizeof(join_pref_params));
  195953. + if (err)
  195954. + brcmf_err("Set join_pref error (%d)\n", err);
  195955. +
  195956. /* Setup event_msgs, enable E_IF */
  195957. err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
  195958. BRCMF_EVENTING_MASK_LEN);
  195959. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/dhd.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
  195960. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/dhd.h 2014-07-31 23:51:43.000000000 +0200
  195961. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/dhd.h 2014-08-20 19:31:46.884872251 +0200
  195962. @@ -186,7 +186,7 @@
  195963. void brcmf_txflowblock_if(struct brcmf_if *ifp,
  195964. enum brcmf_netif_stop_reason reason, bool state);
  195965. u32 brcmf_get_chip_info(struct brcmf_if *ifp);
  195966. -void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
  195967. +void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
  195968. bool success);
  195969. /* Sets dongle media info (drv_version, mac address). */
  195970. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
  195971. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c 2014-07-31 23:51:43.000000000 +0200
  195972. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c 2014-08-20 19:31:46.884872251 +0200
  195973. @@ -190,7 +190,7 @@
  195974. int ret;
  195975. struct brcmf_if *ifp = netdev_priv(ndev);
  195976. struct brcmf_pub *drvr = ifp->drvr;
  195977. - struct ethhdr *eh;
  195978. + struct ethhdr *eh = (struct ethhdr *)(skb->data);
  195979. brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx);
  195980. @@ -236,6 +236,9 @@
  195981. goto done;
  195982. }
  195983. + if (eh->h_proto == htons(ETH_P_PAE))
  195984. + atomic_inc(&ifp->pend_8021x_cnt);
  195985. +
  195986. ret = brcmf_fws_process_skb(ifp, skb);
  195987. done:
  195988. @@ -538,31 +541,26 @@
  195989. brcmf_netif_rx(ifp, skb);
  195990. }
  195991. -void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
  195992. +void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
  195993. bool success)
  195994. {
  195995. struct brcmf_if *ifp;
  195996. struct ethhdr *eh;
  195997. - u8 ifidx;
  195998. u16 type;
  195999. - int res;
  196000. -
  196001. - res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
  196002. ifp = drvr->iflist[ifidx];
  196003. if (!ifp)
  196004. goto done;
  196005. - if (res == 0) {
  196006. - eh = (struct ethhdr *)(txp->data);
  196007. - type = ntohs(eh->h_proto);
  196008. -
  196009. - if (type == ETH_P_PAE) {
  196010. - atomic_dec(&ifp->pend_8021x_cnt);
  196011. - if (waitqueue_active(&ifp->pend_8021x_wait))
  196012. - wake_up(&ifp->pend_8021x_wait);
  196013. - }
  196014. + eh = (struct ethhdr *)(txp->data);
  196015. + type = ntohs(eh->h_proto);
  196016. +
  196017. + if (type == ETH_P_PAE) {
  196018. + atomic_dec(&ifp->pend_8021x_cnt);
  196019. + if (waitqueue_active(&ifp->pend_8021x_wait))
  196020. + wake_up(&ifp->pend_8021x_wait);
  196021. }
  196022. +
  196023. if (!success)
  196024. ifp->stats.tx_errors++;
  196025. done:
  196026. @@ -573,13 +571,17 @@
  196027. {
  196028. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  196029. struct brcmf_pub *drvr = bus_if->drvr;
  196030. + u8 ifidx;
  196031. /* await txstatus signal for firmware if active */
  196032. if (brcmf_fws_fc_active(drvr->fws)) {
  196033. if (!success)
  196034. brcmf_fws_bustxfail(drvr->fws, txp);
  196035. } else {
  196036. - brcmf_txfinalize(drvr, txp, success);
  196037. + if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp))
  196038. + brcmu_pkt_buf_free_skb(txp);
  196039. + else
  196040. + brcmf_txfinalize(drvr, txp, ifidx, success);
  196041. }
  196042. }
  196043. @@ -914,13 +916,6 @@
  196044. brcmf_dbg(TRACE, "\n");
  196045. - /* Bring up the bus */
  196046. - ret = brcmf_bus_init(bus_if);
  196047. - if (ret != 0) {
  196048. - brcmf_err("brcmf_sdbrcm_bus_init failed %d\n", ret);
  196049. - return ret;
  196050. - }
  196051. -
  196052. /* add primary networking interface */
  196053. ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
  196054. if (IS_ERR(ifp))
  196055. @@ -1040,12 +1035,12 @@
  196056. brcmf_cfg80211_detach(drvr->config);
  196057. + brcmf_fws_deinit(drvr);
  196058. +
  196059. brcmf_bus_detach(drvr);
  196060. brcmf_proto_detach(drvr);
  196061. - brcmf_fws_deinit(drvr);
  196062. -
  196063. brcmf_debugfs_detach(drvr);
  196064. bus_if->drvr = NULL;
  196065. kfree(drvr);
  196066. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
  196067. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c 2014-07-31 23:51:43.000000000 +0200
  196068. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c 2014-08-20 19:31:46.888872268 +0200
  196069. @@ -23,6 +23,7 @@
  196070. #include <linux/interrupt.h>
  196071. #include <linux/sched.h>
  196072. #include <linux/mmc/sdio.h>
  196073. +#include <linux/mmc/sdio_ids.h>
  196074. #include <linux/mmc/sdio_func.h>
  196075. #include <linux/mmc/card.h>
  196076. #include <linux/semaphore.h>
  196077. @@ -40,8 +41,8 @@
  196078. #include <brcm_hw_ids.h>
  196079. #include <soc.h>
  196080. #include "sdio_host.h"
  196081. -#include "sdio_chip.h"
  196082. -#include "nvram.h"
  196083. +#include "chip.h"
  196084. +#include "firmware.h"
  196085. #define DCMD_RESP_TIMEOUT 2000 /* In milli second */
  196086. @@ -112,8 +113,6 @@
  196087. #define BRCMF_TXBOUND 20 /* Default for max tx frames in
  196088. one scheduling */
  196089. -#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
  196090. -
  196091. #define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
  196092. #define MEMBLOCK 2048 /* Block size used for downloading
  196093. @@ -156,6 +155,34 @@
  196094. /* manfid tuple length, include tuple, link bytes */
  196095. #define SBSDIO_CIS_MANFID_TUPLE_LEN 6
  196096. +#define CORE_BUS_REG(base, field) \
  196097. + (base + offsetof(struct sdpcmd_regs, field))
  196098. +
  196099. +/* SDIO function 1 register CHIPCLKCSR */
  196100. +/* Force ALP request to backplane */
  196101. +#define SBSDIO_FORCE_ALP 0x01
  196102. +/* Force HT request to backplane */
  196103. +#define SBSDIO_FORCE_HT 0x02
  196104. +/* Force ILP request to backplane */
  196105. +#define SBSDIO_FORCE_ILP 0x04
  196106. +/* Make ALP ready (power up xtal) */
  196107. +#define SBSDIO_ALP_AVAIL_REQ 0x08
  196108. +/* Make HT ready (power up PLL) */
  196109. +#define SBSDIO_HT_AVAIL_REQ 0x10
  196110. +/* Squelch clock requests from HW */
  196111. +#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
  196112. +/* Status: ALP is ready */
  196113. +#define SBSDIO_ALP_AVAIL 0x40
  196114. +/* Status: HT is ready */
  196115. +#define SBSDIO_HT_AVAIL 0x80
  196116. +#define SBSDIO_CSR_MASK 0x1F
  196117. +#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
  196118. +#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
  196119. +#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
  196120. +#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
  196121. +#define SBSDIO_CLKAV(regval, alponly) \
  196122. + (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
  196123. +
  196124. /* intstatus */
  196125. #define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */
  196126. #define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */
  196127. @@ -276,7 +303,6 @@
  196128. /* Flags for SDH calls */
  196129. #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
  196130. -#define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */
  196131. #define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
  196132. * when idle
  196133. */
  196134. @@ -433,10 +459,11 @@
  196135. bool alp_only; /* Don't use HT clock (ALP only) */
  196136. u8 *ctrl_frame_buf;
  196137. - u32 ctrl_frame_len;
  196138. + u16 ctrl_frame_len;
  196139. bool ctrl_frame_stat;
  196140. - spinlock_t txqlock;
  196141. + spinlock_t txq_lock; /* protect bus->txq */
  196142. + struct semaphore tx_seq_lock; /* protect bus->tx_seq */
  196143. wait_queue_head_t ctrl_wait;
  196144. wait_queue_head_t dcmd_resp_wait;
  196145. @@ -483,16 +510,58 @@
  196146. #define ALIGNMENT 4
  196147. -static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
  196148. -module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0);
  196149. -MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
  196150. -
  196151. enum brcmf_sdio_frmtype {
  196152. BRCMF_SDIO_FT_NORMAL,
  196153. BRCMF_SDIO_FT_SUPER,
  196154. BRCMF_SDIO_FT_SUB,
  196155. };
  196156. +#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
  196157. +
  196158. +/* SDIO Pad drive strength to select value mappings */
  196159. +struct sdiod_drive_str {
  196160. + u8 strength; /* Pad Drive Strength in mA */
  196161. + u8 sel; /* Chip-specific select value */
  196162. +};
  196163. +
  196164. +/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
  196165. +static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
  196166. + {32, 0x6},
  196167. + {26, 0x7},
  196168. + {22, 0x4},
  196169. + {16, 0x5},
  196170. + {12, 0x2},
  196171. + {8, 0x3},
  196172. + {4, 0x0},
  196173. + {0, 0x1}
  196174. +};
  196175. +
  196176. +/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
  196177. +static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = {
  196178. + {6, 0x7},
  196179. + {5, 0x6},
  196180. + {4, 0x5},
  196181. + {3, 0x4},
  196182. + {2, 0x2},
  196183. + {1, 0x1},
  196184. + {0, 0x0}
  196185. +};
  196186. +
  196187. +/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
  196188. +static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = {
  196189. + {3, 0x3},
  196190. + {2, 0x2},
  196191. + {1, 0x1},
  196192. + {0, 0x0} };
  196193. +
  196194. +/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
  196195. +static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
  196196. + {16, 0x7},
  196197. + {12, 0x5},
  196198. + {8, 0x3},
  196199. + {4, 0x1}
  196200. +};
  196201. +
  196202. #define BCM43143_FIRMWARE_NAME "brcm/brcmfmac43143-sdio.bin"
  196203. #define BCM43143_NVRAM_NAME "brcm/brcmfmac43143-sdio.txt"
  196204. #define BCM43241B0_FIRMWARE_NAME "brcm/brcmfmac43241b0-sdio.bin"
  196205. @@ -511,6 +580,8 @@
  196206. #define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt"
  196207. #define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin"
  196208. #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt"
  196209. +#define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin"
  196210. +#define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt"
  196211. MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME);
  196212. MODULE_FIRMWARE(BCM43143_NVRAM_NAME);
  196213. @@ -530,6 +601,8 @@
  196214. MODULE_FIRMWARE(BCM43362_NVRAM_NAME);
  196215. MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
  196216. MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
  196217. +MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
  196218. +MODULE_FIRMWARE(BCM4354_NVRAM_NAME);
  196219. struct brcmf_firmware_names {
  196220. u32 chipid;
  196221. @@ -555,46 +628,32 @@
  196222. { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
  196223. { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
  196224. { BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
  196225. - { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }
  196226. + { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
  196227. + { BCM4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
  196228. };
  196229. -
  196230. -static const struct firmware *brcmf_sdio_get_fw(struct brcmf_sdio *bus,
  196231. - enum brcmf_firmware_type type)
  196232. +static const char *brcmf_sdio_get_fwname(struct brcmf_chip *ci,
  196233. + enum brcmf_firmware_type type)
  196234. {
  196235. - const struct firmware *fw;
  196236. - const char *name;
  196237. - int err, i;
  196238. + int i;
  196239. for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
  196240. - if (brcmf_fwname_data[i].chipid == bus->ci->chip &&
  196241. - brcmf_fwname_data[i].revmsk & BIT(bus->ci->chiprev)) {
  196242. + if (brcmf_fwname_data[i].chipid == ci->chip &&
  196243. + brcmf_fwname_data[i].revmsk & BIT(ci->chiprev)) {
  196244. switch (type) {
  196245. case BRCMF_FIRMWARE_BIN:
  196246. - name = brcmf_fwname_data[i].bin;
  196247. - break;
  196248. + return brcmf_fwname_data[i].bin;
  196249. case BRCMF_FIRMWARE_NVRAM:
  196250. - name = brcmf_fwname_data[i].nv;
  196251. - break;
  196252. + return brcmf_fwname_data[i].nv;
  196253. default:
  196254. brcmf_err("invalid firmware type (%d)\n", type);
  196255. return NULL;
  196256. }
  196257. - goto found;
  196258. }
  196259. }
  196260. brcmf_err("Unknown chipid %d [%d]\n",
  196261. - bus->ci->chip, bus->ci->chiprev);
  196262. + ci->chip, ci->chiprev);
  196263. return NULL;
  196264. -
  196265. -found:
  196266. - err = request_firmware(&fw, name, &bus->sdiodev->func[2]->dev);
  196267. - if ((err) || (!fw)) {
  196268. - brcmf_err("fail to request firmware %s (%d)\n", name, err);
  196269. - return NULL;
  196270. - }
  196271. -
  196272. - return fw;
  196273. }
  196274. static void pkt_align(struct sk_buff *p, int len, int align)
  196275. @@ -618,27 +677,24 @@
  196276. * Reads a register in the SDIO hardware block. This block occupies a series of
  196277. * adresses on the 32 bit backplane bus.
  196278. */
  196279. -static int
  196280. -r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
  196281. +static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
  196282. {
  196283. - u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  196284. + struct brcmf_core *core;
  196285. int ret;
  196286. - *regvar = brcmf_sdiod_regrl(bus->sdiodev,
  196287. - bus->ci->c_inf[idx].base + offset, &ret);
  196288. + core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
  196289. + *regvar = brcmf_sdiod_regrl(bus->sdiodev, core->base + offset, &ret);
  196290. return ret;
  196291. }
  196292. -static int
  196293. -w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
  196294. +static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
  196295. {
  196296. - u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  196297. + struct brcmf_core *core;
  196298. int ret;
  196299. - brcmf_sdiod_regwl(bus->sdiodev,
  196300. - bus->ci->c_inf[idx].base + reg_offset,
  196301. - regval, &ret);
  196302. + core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
  196303. + brcmf_sdiod_regwl(bus->sdiodev, core->base + reg_offset, regval, &ret);
  196304. return ret;
  196305. }
  196306. @@ -650,16 +706,12 @@
  196307. int err = 0;
  196308. int try_cnt = 0;
  196309. - brcmf_dbg(TRACE, "Enter\n");
  196310. + brcmf_dbg(TRACE, "Enter: on=%d\n", on);
  196311. wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
  196312. /* 1st KSO write goes to AOS wake up core if device is asleep */
  196313. brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
  196314. wr_val, &err);
  196315. - if (err) {
  196316. - brcmf_err("SDIO_AOS KSO write error: %d\n", err);
  196317. - return err;
  196318. - }
  196319. if (on) {
  196320. /* device WAKEUP through KSO:
  196321. @@ -689,18 +741,22 @@
  196322. &err);
  196323. if (((rd_val & bmask) == cmp_val) && !err)
  196324. break;
  196325. - brcmf_dbg(SDIO, "KSO wr/rd retry:%d (max: %d) ERR:%x\n",
  196326. - try_cnt, MAX_KSO_ATTEMPTS, err);
  196327. +
  196328. udelay(KSO_WAIT_US);
  196329. brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
  196330. wr_val, &err);
  196331. } while (try_cnt++ < MAX_KSO_ATTEMPTS);
  196332. + if (try_cnt > 2)
  196333. + brcmf_dbg(SDIO, "try_cnt=%d rd_val=0x%x err=%d\n", try_cnt,
  196334. + rd_val, err);
  196335. +
  196336. + if (try_cnt > MAX_KSO_ATTEMPTS)
  196337. + brcmf_err("max tries: rd_val=0x%x err=%d\n", rd_val, err);
  196338. +
  196339. return err;
  196340. }
  196341. -#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND)
  196342. -
  196343. #define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
  196344. /* Turn backplane clock on or off */
  196345. @@ -799,7 +855,6 @@
  196346. }
  196347. #endif /* defined (DEBUG) */
  196348. - bus->activity = true;
  196349. } else {
  196350. clkreq = 0;
  196351. @@ -899,8 +954,9 @@
  196352. brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
  196353. {
  196354. int err = 0;
  196355. - brcmf_dbg(TRACE, "Enter\n");
  196356. - brcmf_dbg(SDIO, "request %s currently %s\n",
  196357. + u8 clkcsr;
  196358. +
  196359. + brcmf_dbg(SDIO, "Enter: request %s currently %s\n",
  196360. (sleep ? "SLEEP" : "WAKE"),
  196361. (bus->sleeping ? "SLEEP" : "WAKE"));
  196362. @@ -917,8 +973,20 @@
  196363. atomic_read(&bus->ipend) > 0 ||
  196364. (!atomic_read(&bus->fcstate) &&
  196365. brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
  196366. - data_ok(bus)))
  196367. - return -EBUSY;
  196368. + data_ok(bus))) {
  196369. + err = -EBUSY;
  196370. + goto done;
  196371. + }
  196372. +
  196373. + clkcsr = brcmf_sdiod_regrb(bus->sdiodev,
  196374. + SBSDIO_FUNC1_CHIPCLKCSR,
  196375. + &err);
  196376. + if ((clkcsr & SBSDIO_CSR_MASK) == 0) {
  196377. + brcmf_dbg(SDIO, "no clock, set ALP\n");
  196378. + brcmf_sdiod_regwb(bus->sdiodev,
  196379. + SBSDIO_FUNC1_CHIPCLKCSR,
  196380. + SBSDIO_ALP_AVAIL_REQ, &err);
  196381. + }
  196382. err = brcmf_sdio_kso_control(bus, false);
  196383. /* disable watchdog */
  196384. if (!err)
  196385. @@ -935,7 +1003,7 @@
  196386. } else {
  196387. brcmf_err("error while changing bus sleep state %d\n",
  196388. err);
  196389. - return err;
  196390. + goto done;
  196391. }
  196392. }
  196393. @@ -947,11 +1015,92 @@
  196394. } else {
  196395. brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
  196396. }
  196397. -
  196398. +done:
  196399. + brcmf_dbg(SDIO, "Exit: err=%d\n", err);
  196400. return err;
  196401. }
  196402. +#ifdef DEBUG
  196403. +static inline bool brcmf_sdio_valid_shared_address(u32 addr)
  196404. +{
  196405. + return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
  196406. +}
  196407. +
  196408. +static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
  196409. + struct sdpcm_shared *sh)
  196410. +{
  196411. + u32 addr;
  196412. + int rv;
  196413. + u32 shaddr = 0;
  196414. + struct sdpcm_shared_le sh_le;
  196415. + __le32 addr_le;
  196416. +
  196417. + shaddr = bus->ci->rambase + bus->ramsize - 4;
  196418. +
  196419. + /*
  196420. + * Read last word in socram to determine
  196421. + * address of sdpcm_shared structure
  196422. + */
  196423. + sdio_claim_host(bus->sdiodev->func[1]);
  196424. + brcmf_sdio_bus_sleep(bus, false, false);
  196425. + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
  196426. + sdio_release_host(bus->sdiodev->func[1]);
  196427. + if (rv < 0)
  196428. + return rv;
  196429. +
  196430. + addr = le32_to_cpu(addr_le);
  196431. +
  196432. + brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
  196433. +
  196434. + /*
  196435. + * Check if addr is valid.
  196436. + * NVRAM length at the end of memory should have been overwritten.
  196437. + */
  196438. + if (!brcmf_sdio_valid_shared_address(addr)) {
  196439. + brcmf_err("invalid sdpcm_shared address 0x%08X\n",
  196440. + addr);
  196441. + return -EINVAL;
  196442. + }
  196443. +
  196444. + /* Read hndrte_shared structure */
  196445. + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
  196446. + sizeof(struct sdpcm_shared_le));
  196447. + if (rv < 0)
  196448. + return rv;
  196449. +
  196450. + /* Endianness */
  196451. + sh->flags = le32_to_cpu(sh_le.flags);
  196452. + sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
  196453. + sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
  196454. + sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
  196455. + sh->assert_line = le32_to_cpu(sh_le.assert_line);
  196456. + sh->console_addr = le32_to_cpu(sh_le.console_addr);
  196457. + sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);
  196458. +
  196459. + if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
  196460. + brcmf_err("sdpcm shared version unsupported: dhd %d dongle %d\n",
  196461. + SDPCM_SHARED_VERSION,
  196462. + sh->flags & SDPCM_SHARED_VERSION_MASK);
  196463. + return -EPROTO;
  196464. + }
  196465. +
  196466. + return 0;
  196467. +}
  196468. +
  196469. +static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
  196470. +{
  196471. + struct sdpcm_shared sh;
  196472. +
  196473. + if (brcmf_sdio_readshared(bus, &sh) == 0)
  196474. + bus->console_addr = sh.console_addr;
  196475. +}
  196476. +#else
  196477. +static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
  196478. +{
  196479. +}
  196480. +#endif /* DEBUG */
  196481. +
  196482. static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
  196483. {
  196484. u32 intstatus = 0;
  196485. @@ -995,6 +1144,12 @@
  196486. else
  196487. brcmf_dbg(SDIO, "Dongle ready, protocol version %d\n",
  196488. bus->sdpcm_ver);
  196489. +
  196490. + /*
  196491. + * Retrieve console state address now that firmware should have
  196492. + * updated it.
  196493. + */
  196494. + brcmf_sdio_get_console_addr(bus);
  196495. }
  196496. /*
  196497. @@ -1083,6 +1238,28 @@
  196498. bus->cur_read.len = 0;
  196499. }
  196500. +static void brcmf_sdio_txfail(struct brcmf_sdio *bus)
  196501. +{
  196502. + struct brcmf_sdio_dev *sdiodev = bus->sdiodev;
  196503. + u8 i, hi, lo;
  196504. +
  196505. + /* On failure, abort the command and terminate the frame */
  196506. + brcmf_err("sdio error, abort command and terminate frame\n");
  196507. + bus->sdcnt.tx_sderrs++;
  196508. +
  196509. + brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2);
  196510. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
  196511. + bus->sdcnt.f1regdata++;
  196512. +
  196513. + for (i = 0; i < 3; i++) {
  196514. + hi = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL);
  196515. + lo = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL);
  196516. + bus->sdcnt.f1regdata += 2;
  196517. + if ((hi == 0) && (lo == 0))
  196518. + break;
  196519. + }
  196520. +}
  196521. +
  196522. /* return total length of buffer chain */
  196523. static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus)
  196524. {
  196525. @@ -1955,7 +2132,7 @@
  196526. memcpy(pkt_pad->data,
  196527. pkt->data + pkt->len - tail_chop,
  196528. tail_chop);
  196529. - *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
  196530. + *(u16 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
  196531. skb_trim(pkt, pkt->len - tail_chop);
  196532. skb_trim(pkt_pad, tail_pad + tail_chop);
  196533. __skb_queue_after(pktq, pkt, pkt_pad);
  196534. @@ -2003,7 +2180,7 @@
  196535. * already properly aligned and does not
  196536. * need an sdpcm header.
  196537. */
  196538. - if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
  196539. + if (*(u16 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
  196540. continue;
  196541. /* align packet data pointer */
  196542. @@ -2037,10 +2214,10 @@
  196543. if (BRCMF_BYTES_ON() &&
  196544. ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
  196545. (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
  196546. - brcmf_dbg_hex_dump(true, pkt_next, hd_info.len,
  196547. + brcmf_dbg_hex_dump(true, pkt_next->data, hd_info.len,
  196548. "Tx Frame:\n");
  196549. else if (BRCMF_HDRS_ON())
  196550. - brcmf_dbg_hex_dump(true, pkt_next,
  196551. + brcmf_dbg_hex_dump(true, pkt_next->data,
  196552. head_pad + bus->tx_hdrlen,
  196553. "Tx Header:\n");
  196554. }
  196555. @@ -2067,11 +2244,11 @@
  196556. u8 *hdr;
  196557. u32 dat_offset;
  196558. u16 tail_pad;
  196559. - u32 dummy_flags, chop_len;
  196560. + u16 dummy_flags, chop_len;
  196561. struct sk_buff *pkt_next, *tmp, *pkt_prev;
  196562. skb_queue_walk_safe(pktq, pkt_next, tmp) {
  196563. - dummy_flags = *(u32 *)(pkt_next->cb);
  196564. + dummy_flags = *(u16 *)(pkt_next->cb);
  196565. if (dummy_flags & ALIGN_SKB_FLAG) {
  196566. chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
  196567. if (chop_len) {
  196568. @@ -2100,7 +2277,6 @@
  196569. uint chan)
  196570. {
  196571. int ret;
  196572. - int i;
  196573. struct sk_buff *pkt_next, *tmp;
  196574. brcmf_dbg(TRACE, "Enter\n");
  196575. @@ -2113,28 +2289,9 @@
  196576. ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq);
  196577. bus->sdcnt.f2txdata++;
  196578. - if (ret < 0) {
  196579. - /* On failure, abort the command and terminate the frame */
  196580. - brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
  196581. - ret);
  196582. - bus->sdcnt.tx_sderrs++;
  196583. + if (ret < 0)
  196584. + brcmf_sdio_txfail(bus);
  196585. - brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
  196586. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
  196587. - SFC_WF_TERM, NULL);
  196588. - bus->sdcnt.f1regdata++;
  196589. -
  196590. - for (i = 0; i < 3; i++) {
  196591. - u8 hi, lo;
  196592. - hi = brcmf_sdiod_regrb(bus->sdiodev,
  196593. - SBSDIO_FUNC1_WFRAMEBCHI, NULL);
  196594. - lo = brcmf_sdiod_regrb(bus->sdiodev,
  196595. - SBSDIO_FUNC1_WFRAMEBCLO, NULL);
  196596. - bus->sdcnt.f1regdata += 2;
  196597. - if ((hi == 0) && (lo == 0))
  196598. - break;
  196599. - }
  196600. - }
  196601. sdio_release_host(bus->sdiodev->func[1]);
  196602. done:
  196603. @@ -2164,13 +2321,15 @@
  196604. /* Send frames until the limit or some other event */
  196605. for (cnt = 0; (cnt < maxframes) && data_ok(bus);) {
  196606. pkt_num = 1;
  196607. - __skb_queue_head_init(&pktq);
  196608. + if (down_interruptible(&bus->tx_seq_lock))
  196609. + return cnt;
  196610. if (bus->txglom)
  196611. pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
  196612. - brcmf_sdio_txglomsz);
  196613. + bus->sdiodev->txglomsz);
  196614. pkt_num = min_t(u32, pkt_num,
  196615. brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
  196616. - spin_lock_bh(&bus->txqlock);
  196617. + __skb_queue_head_init(&pktq);
  196618. + spin_lock_bh(&bus->txq_lock);
  196619. for (i = 0; i < pkt_num; i++) {
  196620. pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map,
  196621. &prec_out);
  196622. @@ -2178,15 +2337,19 @@
  196623. break;
  196624. __skb_queue_tail(&pktq, pkt);
  196625. }
  196626. - spin_unlock_bh(&bus->txqlock);
  196627. - if (i == 0)
  196628. + spin_unlock_bh(&bus->txq_lock);
  196629. + if (i == 0) {
  196630. + up(&bus->tx_seq_lock);
  196631. break;
  196632. + }
  196633. ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL);
  196634. + up(&bus->tx_seq_lock);
  196635. +
  196636. cnt += i;
  196637. /* In poll mode, need to check for other events */
  196638. - if (!bus->intr && cnt) {
  196639. + if (!bus->intr) {
  196640. /* Check device status, signal pending interrupt */
  196641. sdio_claim_host(bus->sdiodev->func[1]);
  196642. ret = r_sdreg32(bus, &intstatus,
  196643. @@ -2211,6 +2374,68 @@
  196644. return cnt;
  196645. }
  196646. +static int brcmf_sdio_tx_ctrlframe(struct brcmf_sdio *bus, u8 *frame, u16 len)
  196647. +{
  196648. + u8 doff;
  196649. + u16 pad;
  196650. + uint retries = 0;
  196651. + struct brcmf_sdio_hdrinfo hd_info = {0};
  196652. + int ret;
  196653. +
  196654. + brcmf_dbg(TRACE, "Enter\n");
  196655. +
  196656. + /* Back the pointer to make room for bus header */
  196657. + frame -= bus->tx_hdrlen;
  196658. + len += bus->tx_hdrlen;
  196659. +
  196660. + /* Add alignment padding (optional for ctl frames) */
  196661. + doff = ((unsigned long)frame % bus->head_align);
  196662. + if (doff) {
  196663. + frame -= doff;
  196664. + len += doff;
  196665. + memset(frame + bus->tx_hdrlen, 0, doff);
  196666. + }
  196667. +
  196668. + /* Round send length to next SDIO block */
  196669. + pad = 0;
  196670. + if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
  196671. + pad = bus->blocksize - (len % bus->blocksize);
  196672. + if ((pad > bus->roundup) || (pad >= bus->blocksize))
  196673. + pad = 0;
  196674. + } else if (len % bus->head_align) {
  196675. + pad = bus->head_align - (len % bus->head_align);
  196676. + }
  196677. + len += pad;
  196678. +
  196679. + hd_info.len = len - pad;
  196680. + hd_info.channel = SDPCM_CONTROL_CHANNEL;
  196681. + hd_info.dat_offset = doff + bus->tx_hdrlen;
  196682. + hd_info.seq_num = bus->tx_seq;
  196683. + hd_info.lastfrm = true;
  196684. + hd_info.tail_pad = pad;
  196685. + brcmf_sdio_hdpack(bus, frame, &hd_info);
  196686. +
  196687. + if (bus->txglom)
  196688. + brcmf_sdio_update_hwhdr(frame, len);
  196689. +
  196690. + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
  196691. + frame, len, "Tx Frame:\n");
  196692. + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
  196693. + BRCMF_HDRS_ON(),
  196694. + frame, min_t(u16, len, 16), "TxHdr:\n");
  196695. +
  196696. + do {
  196697. + ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len);
  196698. +
  196699. + if (ret < 0)
  196700. + brcmf_sdio_txfail(bus);
  196701. + else
  196702. + bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
  196703. + } while (ret < 0 && retries++ < TXRETRIES);
  196704. +
  196705. + return ret;
  196706. +}
  196707. +
  196708. static void brcmf_sdio_bus_stop(struct device *dev)
  196709. {
  196710. u32 local_hostintmask;
  196711. @@ -2292,21 +2517,29 @@
  196712. }
  196713. }
  196714. +static void atomic_orr(int val, atomic_t *v)
  196715. +{
  196716. + int old_val;
  196717. +
  196718. + old_val = atomic_read(v);
  196719. + while (atomic_cmpxchg(v, old_val, val | old_val) != old_val)
  196720. + old_val = atomic_read(v);
  196721. +}
  196722. +
  196723. static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
  196724. {
  196725. - u8 idx;
  196726. + struct brcmf_core *buscore;
  196727. u32 addr;
  196728. unsigned long val;
  196729. - int n, ret;
  196730. + int ret;
  196731. - idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  196732. - addr = bus->ci->c_inf[idx].base +
  196733. - offsetof(struct sdpcmd_regs, intstatus);
  196734. + buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
  196735. + addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus);
  196736. val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret);
  196737. bus->sdcnt.f1regdata++;
  196738. if (ret != 0)
  196739. - val = 0;
  196740. + return ret;
  196741. val &= bus->hostintmask;
  196742. atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE));
  196743. @@ -2315,13 +2548,7 @@
  196744. if (val) {
  196745. brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
  196746. bus->sdcnt.f1regdata++;
  196747. - }
  196748. -
  196749. - if (ret) {
  196750. - atomic_set(&bus->intstatus, 0);
  196751. - } else if (val) {
  196752. - for_each_set_bit(n, &val, 32)
  196753. - set_bit(n, (unsigned long *)&bus->intstatus.counter);
  196754. + atomic_orr(val, &bus->intstatus);
  196755. }
  196756. return ret;
  196757. @@ -2331,10 +2558,9 @@
  196758. {
  196759. u32 newstatus = 0;
  196760. unsigned long intstatus;
  196761. - uint rxlimit = bus->rxbound; /* Rx frames to read before resched */
  196762. uint txlimit = bus->txbound; /* Tx frames to send before resched */
  196763. - uint framecnt = 0; /* Temporary counter of tx/rx frames */
  196764. - int err = 0, n;
  196765. + uint framecnt; /* Temporary counter of tx/rx frames */
  196766. + int err = 0;
  196767. brcmf_dbg(TRACE, "Enter\n");
  196768. @@ -2431,70 +2657,38 @@
  196769. intstatus &= ~I_HMB_FRAME_IND;
  196770. /* On frame indication, read available frames */
  196771. - if (PKT_AVAILABLE() && bus->clkstate == CLK_AVAIL) {
  196772. - framecnt = brcmf_sdio_readframes(bus, rxlimit);
  196773. + if ((intstatus & I_HMB_FRAME_IND) && (bus->clkstate == CLK_AVAIL)) {
  196774. + brcmf_sdio_readframes(bus, bus->rxbound);
  196775. if (!bus->rxpending)
  196776. intstatus &= ~I_HMB_FRAME_IND;
  196777. - rxlimit -= min(framecnt, rxlimit);
  196778. }
  196779. /* Keep still-pending events for next scheduling */
  196780. - if (intstatus) {
  196781. - for_each_set_bit(n, &intstatus, 32)
  196782. - set_bit(n, (unsigned long *)&bus->intstatus.counter);
  196783. - }
  196784. + if (intstatus)
  196785. + atomic_orr(intstatus, &bus->intstatus);
  196786. brcmf_sdio_clrintr(bus);
  196787. - if (data_ok(bus) && bus->ctrl_frame_stat &&
  196788. - (bus->clkstate == CLK_AVAIL)) {
  196789. - int i;
  196790. -
  196791. - sdio_claim_host(bus->sdiodev->func[1]);
  196792. - err = brcmf_sdiod_send_buf(bus->sdiodev, bus->ctrl_frame_buf,
  196793. - (u32)bus->ctrl_frame_len);
  196794. -
  196795. - if (err < 0) {
  196796. - /* On failure, abort the command and
  196797. - terminate the frame */
  196798. - brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
  196799. - err);
  196800. - bus->sdcnt.tx_sderrs++;
  196801. -
  196802. - brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
  196803. -
  196804. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
  196805. - SFC_WF_TERM, &err);
  196806. - bus->sdcnt.f1regdata++;
  196807. -
  196808. - for (i = 0; i < 3; i++) {
  196809. - u8 hi, lo;
  196810. - hi = brcmf_sdiod_regrb(bus->sdiodev,
  196811. - SBSDIO_FUNC1_WFRAMEBCHI,
  196812. - &err);
  196813. - lo = brcmf_sdiod_regrb(bus->sdiodev,
  196814. - SBSDIO_FUNC1_WFRAMEBCLO,
  196815. - &err);
  196816. - bus->sdcnt.f1regdata += 2;
  196817. - if ((hi == 0) && (lo == 0))
  196818. - break;
  196819. - }
  196820. + if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
  196821. + (down_interruptible(&bus->tx_seq_lock) == 0)) {
  196822. + if (data_ok(bus)) {
  196823. + sdio_claim_host(bus->sdiodev->func[1]);
  196824. + err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf,
  196825. + bus->ctrl_frame_len);
  196826. + sdio_release_host(bus->sdiodev->func[1]);
  196827. - } else {
  196828. - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
  196829. + bus->ctrl_frame_stat = false;
  196830. + brcmf_sdio_wait_event_wakeup(bus);
  196831. }
  196832. - sdio_release_host(bus->sdiodev->func[1]);
  196833. - bus->ctrl_frame_stat = false;
  196834. - brcmf_sdio_wait_event_wakeup(bus);
  196835. + up(&bus->tx_seq_lock);
  196836. }
  196837. /* Send queued frames (limit 1 if rx may still be pending) */
  196838. - else if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) &&
  196839. - brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
  196840. - && data_ok(bus)) {
  196841. + if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) &&
  196842. + brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit &&
  196843. + data_ok(bus)) {
  196844. framecnt = bus->rxpending ? min(txlimit, bus->txminmax) :
  196845. txlimit;
  196846. - framecnt = brcmf_sdio_sendfromq(bus, framecnt);
  196847. - txlimit -= framecnt;
  196848. + brcmf_sdio_sendfromq(bus, framecnt);
  196849. }
  196850. if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) {
  196851. @@ -2504,19 +2698,9 @@
  196852. atomic_read(&bus->ipend) > 0 ||
  196853. (!atomic_read(&bus->fcstate) &&
  196854. brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
  196855. - data_ok(bus)) || PKT_AVAILABLE()) {
  196856. + data_ok(bus))) {
  196857. atomic_inc(&bus->dpc_tskcnt);
  196858. }
  196859. -
  196860. - /* If we're done for now, turn off clock request. */
  196861. - if ((bus->clkstate != CLK_PENDING)
  196862. - && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
  196863. - bus->activity = false;
  196864. - brcmf_dbg(SDIO, "idle state\n");
  196865. - sdio_claim_host(bus->sdiodev->func[1]);
  196866. - brcmf_sdio_bus_sleep(bus, true, false);
  196867. - sdio_release_host(bus->sdiodev->func[1]);
  196868. - }
  196869. }
  196870. static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev)
  196871. @@ -2531,15 +2715,12 @@
  196872. static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
  196873. {
  196874. int ret = -EBADE;
  196875. - uint datalen, prec;
  196876. + uint prec;
  196877. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  196878. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  196879. struct brcmf_sdio *bus = sdiodev->bus;
  196880. - ulong flags;
  196881. -
  196882. - brcmf_dbg(TRACE, "Enter\n");
  196883. - datalen = pkt->len;
  196884. + brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len);
  196885. /* Add space for the header */
  196886. skb_push(pkt, bus->tx_hdrlen);
  196887. @@ -2553,7 +2734,9 @@
  196888. bus->sdcnt.fcqueued++;
  196889. /* Priority based enq */
  196890. - spin_lock_irqsave(&bus->txqlock, flags);
  196891. + spin_lock_bh(&bus->txq_lock);
  196892. + /* reset bus_flags in packet cb */
  196893. + *(u16 *)(pkt->cb) = 0;
  196894. if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
  196895. skb_pull(pkt, bus->tx_hdrlen);
  196896. brcmf_err("out of bus->txq !!!\n");
  196897. @@ -2566,7 +2749,7 @@
  196898. bus->txoff = true;
  196899. brcmf_txflowblock(bus->sdiodev->dev, true);
  196900. }
  196901. - spin_unlock_irqrestore(&bus->txqlock, flags);
  196902. + spin_unlock_bh(&bus->txq_lock);
  196903. #ifdef DEBUG
  196904. if (pktq_plen(&bus->txq, prec) > qcount[prec])
  196905. @@ -2661,110 +2844,27 @@
  196906. }
  196907. #endif /* DEBUG */
  196908. -static int brcmf_sdio_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
  196909. -{
  196910. - int i;
  196911. - int ret;
  196912. -
  196913. - bus->ctrl_frame_stat = false;
  196914. - ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len);
  196915. -
  196916. - if (ret < 0) {
  196917. - /* On failure, abort the command and terminate the frame */
  196918. - brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
  196919. - ret);
  196920. - bus->sdcnt.tx_sderrs++;
  196921. -
  196922. - brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
  196923. -
  196924. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
  196925. - SFC_WF_TERM, NULL);
  196926. - bus->sdcnt.f1regdata++;
  196927. -
  196928. - for (i = 0; i < 3; i++) {
  196929. - u8 hi, lo;
  196930. - hi = brcmf_sdiod_regrb(bus->sdiodev,
  196931. - SBSDIO_FUNC1_WFRAMEBCHI, NULL);
  196932. - lo = brcmf_sdiod_regrb(bus->sdiodev,
  196933. - SBSDIO_FUNC1_WFRAMEBCLO, NULL);
  196934. - bus->sdcnt.f1regdata += 2;
  196935. - if (hi == 0 && lo == 0)
  196936. - break;
  196937. - }
  196938. - return ret;
  196939. - }
  196940. -
  196941. - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
  196942. -
  196943. - return ret;
  196944. -}
  196945. -
  196946. static int
  196947. brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
  196948. {
  196949. - u8 *frame;
  196950. - u16 len, pad;
  196951. - uint retries = 0;
  196952. - u8 doff = 0;
  196953. - int ret = -1;
  196954. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  196955. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  196956. struct brcmf_sdio *bus = sdiodev->bus;
  196957. - struct brcmf_sdio_hdrinfo hd_info = {0};
  196958. + int ret = -1;
  196959. brcmf_dbg(TRACE, "Enter\n");
  196960. - /* Back the pointer to make a room for bus header */
  196961. - frame = msg - bus->tx_hdrlen;
  196962. - len = (msglen += bus->tx_hdrlen);
  196963. + if (down_interruptible(&bus->tx_seq_lock))
  196964. + return -EINTR;
  196965. - /* Add alignment padding (optional for ctl frames) */
  196966. - doff = ((unsigned long)frame % bus->head_align);
  196967. - if (doff) {
  196968. - frame -= doff;
  196969. - len += doff;
  196970. - msglen += doff;
  196971. - memset(frame, 0, doff + bus->tx_hdrlen);
  196972. - }
  196973. - /* precondition: doff < bus->head_align */
  196974. - doff += bus->tx_hdrlen;
  196975. -
  196976. - /* Round send length to next SDIO block */
  196977. - pad = 0;
  196978. - if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
  196979. - pad = bus->blocksize - (len % bus->blocksize);
  196980. - if ((pad > bus->roundup) || (pad >= bus->blocksize))
  196981. - pad = 0;
  196982. - } else if (len % bus->head_align) {
  196983. - pad = bus->head_align - (len % bus->head_align);
  196984. - }
  196985. - len += pad;
  196986. -
  196987. - /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
  196988. -
  196989. - /* Make sure backplane clock is on */
  196990. - sdio_claim_host(bus->sdiodev->func[1]);
  196991. - brcmf_sdio_bus_sleep(bus, false, false);
  196992. - sdio_release_host(bus->sdiodev->func[1]);
  196993. -
  196994. - hd_info.len = (u16)msglen;
  196995. - hd_info.channel = SDPCM_CONTROL_CHANNEL;
  196996. - hd_info.dat_offset = doff;
  196997. - hd_info.seq_num = bus->tx_seq;
  196998. - hd_info.lastfrm = true;
  196999. - hd_info.tail_pad = pad;
  197000. - brcmf_sdio_hdpack(bus, frame, &hd_info);
  197001. -
  197002. - if (bus->txglom)
  197003. - brcmf_sdio_update_hwhdr(frame, len);
  197004. -
  197005. - if (!data_ok(bus)) {
  197006. - brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
  197007. - bus->tx_max, bus->tx_seq);
  197008. - bus->ctrl_frame_stat = true;
  197009. - /* Send from dpc */
  197010. - bus->ctrl_frame_buf = frame;
  197011. - bus->ctrl_frame_len = len;
  197012. + if (!data_ok(bus)) {
  197013. + brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
  197014. + bus->tx_max, bus->tx_seq);
  197015. + up(&bus->tx_seq_lock);
  197016. + /* Send from dpc */
  197017. + bus->ctrl_frame_buf = msg;
  197018. + bus->ctrl_frame_len = msglen;
  197019. + bus->ctrl_frame_stat = true;
  197020. wait_event_interruptible_timeout(bus->ctrl_wait,
  197021. !bus->ctrl_frame_stat,
  197022. @@ -2775,31 +2875,18 @@
  197023. ret = 0;
  197024. } else {
  197025. brcmf_dbg(SDIO, "ctrl_frame_stat == true\n");
  197026. + bus->ctrl_frame_stat = false;
  197027. + if (down_interruptible(&bus->tx_seq_lock))
  197028. + return -EINTR;
  197029. ret = -1;
  197030. }
  197031. }
  197032. -
  197033. if (ret == -1) {
  197034. - brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
  197035. - frame, len, "Tx Frame:\n");
  197036. - brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
  197037. - BRCMF_HDRS_ON(),
  197038. - frame, min_t(u16, len, 16), "TxHdr:\n");
  197039. -
  197040. - do {
  197041. - sdio_claim_host(bus->sdiodev->func[1]);
  197042. - ret = brcmf_sdio_tx_frame(bus, frame, len);
  197043. - sdio_release_host(bus->sdiodev->func[1]);
  197044. - } while (ret < 0 && retries++ < TXRETRIES);
  197045. - }
  197046. -
  197047. - if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) &&
  197048. - atomic_read(&bus->dpc_tskcnt) == 0) {
  197049. - bus->activity = false;
  197050. sdio_claim_host(bus->sdiodev->func[1]);
  197051. - brcmf_dbg(INFO, "idle\n");
  197052. - brcmf_sdio_clkctl(bus, CLK_NONE, true);
  197053. + brcmf_sdio_bus_sleep(bus, false, false);
  197054. + ret = brcmf_sdio_tx_ctrlframe(bus, msg, msglen);
  197055. sdio_release_host(bus->sdiodev->func[1]);
  197056. + up(&bus->tx_seq_lock);
  197057. }
  197058. if (ret)
  197059. @@ -2811,72 +2898,6 @@
  197060. }
  197061. #ifdef DEBUG
  197062. -static inline bool brcmf_sdio_valid_shared_address(u32 addr)
  197063. -{
  197064. - return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
  197065. -}
  197066. -
  197067. -static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
  197068. - struct sdpcm_shared *sh)
  197069. -{
  197070. - u32 addr;
  197071. - int rv;
  197072. - u32 shaddr = 0;
  197073. - struct sdpcm_shared_le sh_le;
  197074. - __le32 addr_le;
  197075. -
  197076. - shaddr = bus->ci->rambase + bus->ramsize - 4;
  197077. -
  197078. - /*
  197079. - * Read last word in socram to determine
  197080. - * address of sdpcm_shared structure
  197081. - */
  197082. - sdio_claim_host(bus->sdiodev->func[1]);
  197083. - brcmf_sdio_bus_sleep(bus, false, false);
  197084. - rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
  197085. - sdio_release_host(bus->sdiodev->func[1]);
  197086. - if (rv < 0)
  197087. - return rv;
  197088. -
  197089. - addr = le32_to_cpu(addr_le);
  197090. -
  197091. - brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
  197092. -
  197093. - /*
  197094. - * Check if addr is valid.
  197095. - * NVRAM length at the end of memory should have been overwritten.
  197096. - */
  197097. - if (!brcmf_sdio_valid_shared_address(addr)) {
  197098. - brcmf_err("invalid sdpcm_shared address 0x%08X\n",
  197099. - addr);
  197100. - return -EINVAL;
  197101. - }
  197102. -
  197103. - /* Read hndrte_shared structure */
  197104. - rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
  197105. - sizeof(struct sdpcm_shared_le));
  197106. - if (rv < 0)
  197107. - return rv;
  197108. -
  197109. - /* Endianness */
  197110. - sh->flags = le32_to_cpu(sh_le.flags);
  197111. - sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
  197112. - sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
  197113. - sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
  197114. - sh->assert_line = le32_to_cpu(sh_le.assert_line);
  197115. - sh->console_addr = le32_to_cpu(sh_le.console_addr);
  197116. - sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);
  197117. -
  197118. - if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
  197119. - brcmf_err("sdpcm shared version unsupported: dhd %d dongle %d\n",
  197120. - SDPCM_SHARED_VERSION,
  197121. - sh->flags & SDPCM_SHARED_VERSION_MASK);
  197122. - return -EPROTO;
  197123. - }
  197124. -
  197125. - return 0;
  197126. -}
  197127. -
  197128. static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
  197129. struct sdpcm_shared *sh, char __user *data,
  197130. size_t count)
  197131. @@ -3106,6 +3127,8 @@
  197132. debugfs_create_file("forensics", S_IRUGO, dentry, bus,
  197133. &brcmf_sdio_forensic_ops);
  197134. brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt);
  197135. + debugfs_create_u32("console_interval", 0644, dentry,
  197136. + &bus->console_interval);
  197137. }
  197138. #else
  197139. static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
  197140. @@ -3224,51 +3247,29 @@
  197141. const struct firmware *fw)
  197142. {
  197143. int err;
  197144. - int offset;
  197145. - int address;
  197146. - int len;
  197147. brcmf_dbg(TRACE, "Enter\n");
  197148. - err = 0;
  197149. - offset = 0;
  197150. - address = bus->ci->rambase;
  197151. - while (offset < fw->size) {
  197152. - len = ((offset + MEMBLOCK) < fw->size) ? MEMBLOCK :
  197153. - fw->size - offset;
  197154. - err = brcmf_sdiod_ramrw(bus->sdiodev, true, address,
  197155. - (u8 *)&fw->data[offset], len);
  197156. - if (err) {
  197157. - brcmf_err("error %d on writing %d membytes at 0x%08x\n",
  197158. - err, len, address);
  197159. - return err;
  197160. - }
  197161. - offset += len;
  197162. - address += len;
  197163. - }
  197164. - if (!err)
  197165. - if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase,
  197166. - (u8 *)fw->data, fw->size))
  197167. - err = -EIO;
  197168. + err = brcmf_sdiod_ramrw(bus->sdiodev, true, bus->ci->rambase,
  197169. + (u8 *)fw->data, fw->size);
  197170. + if (err)
  197171. + brcmf_err("error %d on writing %d membytes at 0x%08x\n",
  197172. + err, (int)fw->size, bus->ci->rambase);
  197173. + else if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase,
  197174. + (u8 *)fw->data, fw->size))
  197175. + err = -EIO;
  197176. return err;
  197177. }
  197178. static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus,
  197179. - const struct firmware *nv)
  197180. + void *vars, u32 varsz)
  197181. {
  197182. - void *vars;
  197183. - u32 varsz;
  197184. int address;
  197185. int err;
  197186. brcmf_dbg(TRACE, "Enter\n");
  197187. - vars = brcmf_nvram_strip(nv, &varsz);
  197188. -
  197189. - if (vars == NULL)
  197190. - return -EINVAL;
  197191. -
  197192. address = bus->ci->ramsize - varsz + bus->ci->rambase;
  197193. err = brcmf_sdiod_ramrw(bus->sdiodev, true, address, vars, varsz);
  197194. if (err)
  197195. @@ -3277,28 +3278,21 @@
  197196. else if (!brcmf_sdio_verifymemory(bus->sdiodev, address, vars, varsz))
  197197. err = -EIO;
  197198. - brcmf_nvram_free(vars);
  197199. -
  197200. return err;
  197201. }
  197202. -static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus)
  197203. +static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
  197204. + const struct firmware *fw,
  197205. + void *nvram, u32 nvlen)
  197206. {
  197207. int bcmerror = -EFAULT;
  197208. - const struct firmware *fw;
  197209. u32 rstvec;
  197210. sdio_claim_host(bus->sdiodev->func[1]);
  197211. brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
  197212. /* Keep arm in reset */
  197213. - brcmf_sdio_chip_enter_download(bus->sdiodev, bus->ci);
  197214. -
  197215. - fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN);
  197216. - if (fw == NULL) {
  197217. - bcmerror = -ENOENT;
  197218. - goto err;
  197219. - }
  197220. + brcmf_chip_enter_download(bus->ci);
  197221. rstvec = get_unaligned_le32(fw->data);
  197222. brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
  197223. @@ -3307,24 +3301,19 @@
  197224. release_firmware(fw);
  197225. if (bcmerror) {
  197226. brcmf_err("dongle image file download failed\n");
  197227. + brcmf_fw_nvram_free(nvram);
  197228. goto err;
  197229. }
  197230. - fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM);
  197231. - if (fw == NULL) {
  197232. - bcmerror = -ENOENT;
  197233. - goto err;
  197234. - }
  197235. -
  197236. - bcmerror = brcmf_sdio_download_nvram(bus, fw);
  197237. - release_firmware(fw);
  197238. + bcmerror = brcmf_sdio_download_nvram(bus, nvram, nvlen);
  197239. + brcmf_fw_nvram_free(nvram);
  197240. if (bcmerror) {
  197241. brcmf_err("dongle nvram file download failed\n");
  197242. goto err;
  197243. }
  197244. /* Take arm out of reset */
  197245. - if (!brcmf_sdio_chip_exit_download(bus->sdiodev, bus->ci, rstvec)) {
  197246. + if (!brcmf_chip_exit_download(bus->ci, rstvec)) {
  197247. brcmf_err("error getting out of ARM core reset\n");
  197248. goto err;
  197249. }
  197250. @@ -3339,40 +3328,6 @@
  197251. return bcmerror;
  197252. }
  197253. -static bool brcmf_sdio_sr_capable(struct brcmf_sdio *bus)
  197254. -{
  197255. - u32 addr, reg, pmu_cc3_mask = ~0;
  197256. - int err;
  197257. -
  197258. - brcmf_dbg(TRACE, "Enter\n");
  197259. -
  197260. - /* old chips with PMU version less than 17 don't support save restore */
  197261. - if (bus->ci->pmurev < 17)
  197262. - return false;
  197263. -
  197264. - switch (bus->ci->chip) {
  197265. - case BCM43241_CHIP_ID:
  197266. - case BCM4335_CHIP_ID:
  197267. - case BCM4339_CHIP_ID:
  197268. - /* read PMU chipcontrol register 3 */
  197269. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr);
  197270. - brcmf_sdiod_regwl(bus->sdiodev, addr, 3, NULL);
  197271. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data);
  197272. - reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL);
  197273. - return (reg & pmu_cc3_mask) != 0;
  197274. - default:
  197275. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, pmucapabilities_ext);
  197276. - reg = brcmf_sdiod_regrl(bus->sdiodev, addr, &err);
  197277. - if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
  197278. - return false;
  197279. -
  197280. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, retention_ctl);
  197281. - reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL);
  197282. - return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
  197283. - PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
  197284. - }
  197285. -}
  197286. -
  197287. static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
  197288. {
  197289. int err = 0;
  197290. @@ -3424,7 +3379,7 @@
  197291. brcmf_dbg(TRACE, "Enter\n");
  197292. /* KSO bit added in SDIO core rev 12 */
  197293. - if (bus->ci->c_inf[1].rev < 12)
  197294. + if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12)
  197295. return 0;
  197296. val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
  197297. @@ -3455,15 +3410,13 @@
  197298. struct brcmf_sdio *bus = sdiodev->bus;
  197299. uint pad_size;
  197300. u32 value;
  197301. - u8 idx;
  197302. int err;
  197303. /* the commands below use the terms tx and rx from
  197304. * a device perspective, ie. bus:txglom affects the
  197305. * bus transfers from device to host.
  197306. */
  197307. - idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  197308. - if (bus->ci->c_inf[idx].rev < 12) {
  197309. + if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) {
  197310. /* for sdio core rev < 12, disable txgloming */
  197311. value = 0;
  197312. err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
  197313. @@ -3503,97 +3456,6 @@
  197314. return err;
  197315. }
  197316. -static int brcmf_sdio_bus_init(struct device *dev)
  197317. -{
  197318. - struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  197319. - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  197320. - struct brcmf_sdio *bus = sdiodev->bus;
  197321. - int err, ret = 0;
  197322. - u8 saveclk;
  197323. -
  197324. - brcmf_dbg(TRACE, "Enter\n");
  197325. -
  197326. - /* try to download image and nvram to the dongle */
  197327. - if (bus_if->state == BRCMF_BUS_DOWN) {
  197328. - bus->alp_only = true;
  197329. - err = brcmf_sdio_download_firmware(bus);
  197330. - if (err)
  197331. - return err;
  197332. - bus->alp_only = false;
  197333. - }
  197334. -
  197335. - if (!bus->sdiodev->bus_if->drvr)
  197336. - return 0;
  197337. -
  197338. - /* Start the watchdog timer */
  197339. - bus->sdcnt.tickcnt = 0;
  197340. - brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
  197341. -
  197342. - sdio_claim_host(bus->sdiodev->func[1]);
  197343. -
  197344. - /* Make sure backplane clock is on, needed to generate F2 interrupt */
  197345. - brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
  197346. - if (bus->clkstate != CLK_AVAIL)
  197347. - goto exit;
  197348. -
  197349. - /* Force clocks on backplane to be sure F2 interrupt propagates */
  197350. - saveclk = brcmf_sdiod_regrb(bus->sdiodev,
  197351. - SBSDIO_FUNC1_CHIPCLKCSR, &err);
  197352. - if (!err) {
  197353. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  197354. - (saveclk | SBSDIO_FORCE_HT), &err);
  197355. - }
  197356. - if (err) {
  197357. - brcmf_err("Failed to force clock for F2: err %d\n", err);
  197358. - goto exit;
  197359. - }
  197360. -
  197361. - /* Enable function 2 (frame transfers) */
  197362. - w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
  197363. - offsetof(struct sdpcmd_regs, tosbmailboxdata));
  197364. - err = sdio_enable_func(bus->sdiodev->func[SDIO_FUNC_2]);
  197365. -
  197366. -
  197367. - brcmf_dbg(INFO, "enable F2: err=%d\n", err);
  197368. -
  197369. - /* If F2 successfully enabled, set core and enable interrupts */
  197370. - if (!err) {
  197371. - /* Set up the interrupt mask and enable interrupts */
  197372. - bus->hostintmask = HOSTINTMASK;
  197373. - w_sdreg32(bus, bus->hostintmask,
  197374. - offsetof(struct sdpcmd_regs, hostintmask));
  197375. -
  197376. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err);
  197377. - } else {
  197378. - /* Disable F2 again */
  197379. - sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
  197380. - ret = -ENODEV;
  197381. - }
  197382. -
  197383. - if (brcmf_sdio_sr_capable(bus)) {
  197384. - brcmf_sdio_sr_init(bus);
  197385. - } else {
  197386. - /* Restore previous clock setting */
  197387. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  197388. - saveclk, &err);
  197389. - }
  197390. -
  197391. - if (ret == 0) {
  197392. - ret = brcmf_sdiod_intr_register(bus->sdiodev);
  197393. - if (ret != 0)
  197394. - brcmf_err("intr register failed:%d\n", ret);
  197395. - }
  197396. -
  197397. - /* If we didn't come up, turn off backplane clock */
  197398. - if (ret != 0)
  197399. - brcmf_sdio_clkctl(bus, CLK_NONE, false);
  197400. -
  197401. -exit:
  197402. - sdio_release_host(bus->sdiodev->func[1]);
  197403. -
  197404. - return ret;
  197405. -}
  197406. -
  197407. void brcmf_sdio_isr(struct brcmf_sdio *bus)
  197408. {
  197409. brcmf_dbg(TRACE, "Enter\n");
  197410. @@ -3714,11 +3576,175 @@
  197411. datawork);
  197412. while (atomic_read(&bus->dpc_tskcnt)) {
  197413. + atomic_set(&bus->dpc_tskcnt, 0);
  197414. brcmf_sdio_dpc(bus);
  197415. - atomic_dec(&bus->dpc_tskcnt);
  197416. }
  197417. }
  197418. +static void
  197419. +brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
  197420. + struct brcmf_chip *ci, u32 drivestrength)
  197421. +{
  197422. + const struct sdiod_drive_str *str_tab = NULL;
  197423. + u32 str_mask;
  197424. + u32 str_shift;
  197425. + u32 base;
  197426. + u32 i;
  197427. + u32 drivestrength_sel = 0;
  197428. + u32 cc_data_temp;
  197429. + u32 addr;
  197430. +
  197431. + if (!(ci->cc_caps & CC_CAP_PMU))
  197432. + return;
  197433. +
  197434. + switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
  197435. + case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
  197436. + str_tab = sdiod_drvstr_tab1_1v8;
  197437. + str_mask = 0x00003800;
  197438. + str_shift = 11;
  197439. + break;
  197440. + case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
  197441. + str_tab = sdiod_drvstr_tab6_1v8;
  197442. + str_mask = 0x00001800;
  197443. + str_shift = 11;
  197444. + break;
  197445. + case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
  197446. + /* note: 43143 does not support tristate */
  197447. + i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
  197448. + if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
  197449. + str_tab = sdiod_drvstr_tab2_3v3;
  197450. + str_mask = 0x00000007;
  197451. + str_shift = 0;
  197452. + } else
  197453. + brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
  197454. + ci->name, drivestrength);
  197455. + break;
  197456. + case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
  197457. + str_tab = sdiod_drive_strength_tab5_1v8;
  197458. + str_mask = 0x00003800;
  197459. + str_shift = 11;
  197460. + break;
  197461. + default:
  197462. + brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
  197463. + ci->name, ci->chiprev, ci->pmurev);
  197464. + break;
  197465. + }
  197466. +
  197467. + if (str_tab != NULL) {
  197468. + for (i = 0; str_tab[i].strength != 0; i++) {
  197469. + if (drivestrength >= str_tab[i].strength) {
  197470. + drivestrength_sel = str_tab[i].sel;
  197471. + break;
  197472. + }
  197473. + }
  197474. + base = brcmf_chip_get_chipcommon(ci)->base;
  197475. + addr = CORE_CC_REG(base, chipcontrol_addr);
  197476. + brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
  197477. + cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
  197478. + cc_data_temp &= ~str_mask;
  197479. + drivestrength_sel <<= str_shift;
  197480. + cc_data_temp |= drivestrength_sel;
  197481. + brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
  197482. +
  197483. + brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
  197484. + str_tab[i].strength, drivestrength, cc_data_temp);
  197485. + }
  197486. +}
  197487. +
  197488. +static int brcmf_sdio_buscoreprep(void *ctx)
  197489. +{
  197490. + struct brcmf_sdio_dev *sdiodev = ctx;
  197491. + int err = 0;
  197492. + u8 clkval, clkset;
  197493. +
  197494. + /* Try forcing SDIO core to do ALPAvail request only */
  197495. + clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
  197496. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  197497. + if (err) {
  197498. + brcmf_err("error writing for HT off\n");
  197499. + return err;
  197500. + }
  197501. +
  197502. + /* If register supported, wait for ALPAvail and then force ALP */
  197503. + /* This may take up to 15 milliseconds */
  197504. + clkval = brcmf_sdiod_regrb(sdiodev,
  197505. + SBSDIO_FUNC1_CHIPCLKCSR, NULL);
  197506. +
  197507. + if ((clkval & ~SBSDIO_AVBITS) != clkset) {
  197508. + brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
  197509. + clkset, clkval);
  197510. + return -EACCES;
  197511. + }
  197512. +
  197513. + SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
  197514. + SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
  197515. + !SBSDIO_ALPAV(clkval)),
  197516. + PMU_MAX_TRANSITION_DLY);
  197517. + if (!SBSDIO_ALPAV(clkval)) {
  197518. + brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
  197519. + clkval);
  197520. + return -EBUSY;
  197521. + }
  197522. +
  197523. + clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
  197524. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  197525. + udelay(65);
  197526. +
  197527. + /* Also, disable the extra SDIO pull-ups */
  197528. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
  197529. +
  197530. + return 0;
  197531. +}
  197532. +
  197533. +static void brcmf_sdio_buscore_exitdl(void *ctx, struct brcmf_chip *chip,
  197534. + u32 rstvec)
  197535. +{
  197536. + struct brcmf_sdio_dev *sdiodev = ctx;
  197537. + struct brcmf_core *core;
  197538. + u32 reg_addr;
  197539. +
  197540. + /* clear all interrupts */
  197541. + core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
  197542. + reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus);
  197543. + brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
  197544. +
  197545. + if (rstvec)
  197546. + /* Write reset vector to address 0 */
  197547. + brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&rstvec,
  197548. + sizeof(rstvec));
  197549. +}
  197550. +
  197551. +static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
  197552. +{
  197553. + struct brcmf_sdio_dev *sdiodev = ctx;
  197554. + u32 val, rev;
  197555. +
  197556. + val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
  197557. + if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
  197558. + addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
  197559. + rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
  197560. + if (rev >= 2) {
  197561. + val &= ~CID_ID_MASK;
  197562. + val |= BCM4339_CHIP_ID;
  197563. + }
  197564. + }
  197565. + return val;
  197566. +}
  197567. +
  197568. +static void brcmf_sdio_buscore_write32(void *ctx, u32 addr, u32 val)
  197569. +{
  197570. + struct brcmf_sdio_dev *sdiodev = ctx;
  197571. +
  197572. + brcmf_sdiod_regwl(sdiodev, addr, val, NULL);
  197573. +}
  197574. +
  197575. +static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
  197576. + .prepare = brcmf_sdio_buscoreprep,
  197577. + .exit_dl = brcmf_sdio_buscore_exitdl,
  197578. + .read32 = brcmf_sdio_buscore_read32,
  197579. + .write32 = brcmf_sdio_buscore_write32,
  197580. +};
  197581. +
  197582. static bool
  197583. brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
  197584. {
  197585. @@ -3734,7 +3760,7 @@
  197586. brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
  197587. /*
  197588. - * Force PLL off until brcmf_sdio_chip_attach()
  197589. + * Force PLL off until brcmf_chip_attach()
  197590. * programs PLL control regs
  197591. */
  197592. @@ -3755,8 +3781,10 @@
  197593. */
  197594. brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN);
  197595. - if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci)) {
  197596. - brcmf_err("brcmf_sdio_chip_attach failed!\n");
  197597. + bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops);
  197598. + if (IS_ERR(bus->ci)) {
  197599. + brcmf_err("brcmf_chip_attach failed!\n");
  197600. + bus->ci = NULL;
  197601. goto fail;
  197602. }
  197603. @@ -3769,7 +3797,7 @@
  197604. drivestrength = bus->sdiodev->pdata->drive_strength;
  197605. else
  197606. drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;
  197607. - brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength);
  197608. + brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength);
  197609. /* Get info on the SOCRAM cores... */
  197610. bus->ramsize = bus->ci->ramsize;
  197611. @@ -3792,24 +3820,18 @@
  197612. goto fail;
  197613. /* set PMUControl so a backplane reset does PMU state reload */
  197614. - reg_addr = CORE_CC_REG(bus->ci->c_inf[0].base,
  197615. + reg_addr = CORE_CC_REG(brcmf_chip_get_chipcommon(bus->ci)->base,
  197616. pmucontrol);
  197617. - reg_val = brcmf_sdiod_regrl(bus->sdiodev,
  197618. - reg_addr,
  197619. - &err);
  197620. + reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err);
  197621. if (err)
  197622. goto fail;
  197623. reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT);
  197624. - brcmf_sdiod_regwl(bus->sdiodev,
  197625. - reg_addr,
  197626. - reg_val,
  197627. - &err);
  197628. + brcmf_sdiod_regwl(bus->sdiodev, reg_addr, reg_val, &err);
  197629. if (err)
  197630. goto fail;
  197631. -
  197632. sdio_release_host(bus->sdiodev->func[1]);
  197633. brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
  197634. @@ -3849,6 +3871,7 @@
  197635. brcmf_sdio_bus_watchdog(bus);
  197636. /* Count the tick for reference */
  197637. bus->sdcnt.tickcnt++;
  197638. + reinit_completion(&bus->watchdog_wait);
  197639. } else
  197640. break;
  197641. }
  197642. @@ -3872,13 +3895,114 @@
  197643. static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
  197644. .stop = brcmf_sdio_bus_stop,
  197645. .preinit = brcmf_sdio_bus_preinit,
  197646. - .init = brcmf_sdio_bus_init,
  197647. .txdata = brcmf_sdio_bus_txdata,
  197648. .txctl = brcmf_sdio_bus_txctl,
  197649. .rxctl = brcmf_sdio_bus_rxctl,
  197650. .gettxq = brcmf_sdio_bus_gettxq,
  197651. };
  197652. +static void brcmf_sdio_firmware_callback(struct device *dev,
  197653. + const struct firmware *code,
  197654. + void *nvram, u32 nvram_len)
  197655. +{
  197656. + struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  197657. + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  197658. + struct brcmf_sdio *bus = sdiodev->bus;
  197659. + int err = 0;
  197660. + u8 saveclk;
  197661. +
  197662. + brcmf_dbg(TRACE, "Enter: dev=%s\n", dev_name(dev));
  197663. +
  197664. + /* try to download image and nvram to the dongle */
  197665. + if (bus_if->state == BRCMF_BUS_DOWN) {
  197666. + bus->alp_only = true;
  197667. + err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
  197668. + if (err)
  197669. + goto fail;
  197670. + bus->alp_only = false;
  197671. + }
  197672. +
  197673. + if (!bus_if->drvr)
  197674. + return;
  197675. +
  197676. + /* Start the watchdog timer */
  197677. + bus->sdcnt.tickcnt = 0;
  197678. + brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
  197679. +
  197680. + sdio_claim_host(sdiodev->func[1]);
  197681. +
  197682. + /* Make sure backplane clock is on, needed to generate F2 interrupt */
  197683. + brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
  197684. + if (bus->clkstate != CLK_AVAIL)
  197685. + goto release;
  197686. +
  197687. + /* Force clocks on backplane to be sure F2 interrupt propagates */
  197688. + saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
  197689. + if (!err) {
  197690. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  197691. + (saveclk | SBSDIO_FORCE_HT), &err);
  197692. + }
  197693. + if (err) {
  197694. + brcmf_err("Failed to force clock for F2: err %d\n", err);
  197695. + goto release;
  197696. + }
  197697. +
  197698. + /* Enable function 2 (frame transfers) */
  197699. + w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
  197700. + offsetof(struct sdpcmd_regs, tosbmailboxdata));
  197701. + err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]);
  197702. +
  197703. +
  197704. + brcmf_dbg(INFO, "enable F2: err=%d\n", err);
  197705. +
  197706. + /* If F2 successfully enabled, set core and enable interrupts */
  197707. + if (!err) {
  197708. + /* Set up the interrupt mask and enable interrupts */
  197709. + bus->hostintmask = HOSTINTMASK;
  197710. + w_sdreg32(bus, bus->hostintmask,
  197711. + offsetof(struct sdpcmd_regs, hostintmask));
  197712. +
  197713. + brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, 8, &err);
  197714. + } else {
  197715. + /* Disable F2 again */
  197716. + sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
  197717. + goto release;
  197718. + }
  197719. +
  197720. + if (brcmf_chip_sr_capable(bus->ci)) {
  197721. + brcmf_sdio_sr_init(bus);
  197722. + } else {
  197723. + /* Restore previous clock setting */
  197724. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  197725. + saveclk, &err);
  197726. + }
  197727. +
  197728. + if (err == 0) {
  197729. + err = brcmf_sdiod_intr_register(sdiodev);
  197730. + if (err != 0)
  197731. + brcmf_err("intr register failed:%d\n", err);
  197732. + }
  197733. +
  197734. + /* If we didn't come up, turn off backplane clock */
  197735. + if (err != 0)
  197736. + brcmf_sdio_clkctl(bus, CLK_NONE, false);
  197737. +
  197738. + sdio_release_host(sdiodev->func[1]);
  197739. +
  197740. + err = brcmf_bus_start(dev);
  197741. + if (err != 0) {
  197742. + brcmf_err("dongle is not responding\n");
  197743. + goto fail;
  197744. + }
  197745. + return;
  197746. +
  197747. +release:
  197748. + sdio_release_host(sdiodev->func[1]);
  197749. +fail:
  197750. + brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err);
  197751. + device_release_driver(dev);
  197752. +}
  197753. +
  197754. struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
  197755. {
  197756. int ret;
  197757. @@ -3925,7 +4049,8 @@
  197758. }
  197759. spin_lock_init(&bus->rxctl_lock);
  197760. - spin_lock_init(&bus->txqlock);
  197761. + spin_lock_init(&bus->txq_lock);
  197762. + sema_init(&bus->tx_seq_lock, 1);
  197763. init_waitqueue_head(&bus->ctrl_wait);
  197764. init_waitqueue_head(&bus->dcmd_resp_wait);
  197765. @@ -3961,8 +4086,13 @@
  197766. goto fail;
  197767. }
  197768. + /* Query the F2 block size, set roundup accordingly */
  197769. + bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
  197770. + bus->roundup = min(max_roundup, bus->blocksize);
  197771. +
  197772. /* Allocate buffers */
  197773. if (bus->sdiodev->bus_if->maxctl) {
  197774. + bus->sdiodev->bus_if->maxctl += bus->roundup;
  197775. bus->rxblen =
  197776. roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN),
  197777. ALIGNMENT) + bus->head_align;
  197778. @@ -3990,10 +4120,6 @@
  197779. bus->idletime = BRCMF_IDLE_INTERVAL;
  197780. bus->idleclock = BRCMF_IDLE_ACTIVE;
  197781. - /* Query the F2 block size, set roundup accordingly */
  197782. - bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
  197783. - bus->roundup = min(max_roundup, bus->blocksize);
  197784. -
  197785. /* SR state */
  197786. bus->sleeping = false;
  197787. bus->sr_enabled = false;
  197788. @@ -4001,10 +4127,14 @@
  197789. brcmf_sdio_debugfs_create(bus);
  197790. brcmf_dbg(INFO, "completed!!\n");
  197791. - /* if firmware path present try to download and bring up bus */
  197792. - ret = brcmf_bus_start(bus->sdiodev->dev);
  197793. + ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM,
  197794. + brcmf_sdio_get_fwname(bus->ci,
  197795. + BRCMF_FIRMWARE_BIN),
  197796. + brcmf_sdio_get_fwname(bus->ci,
  197797. + BRCMF_FIRMWARE_NVRAM),
  197798. + brcmf_sdio_firmware_callback);
  197799. if (ret != 0) {
  197800. - brcmf_err("dongle is not responding\n");
  197801. + brcmf_err("async firmware request failed: %d\n", ret);
  197802. goto fail;
  197803. }
  197804. @@ -4024,14 +4154,12 @@
  197805. /* De-register interrupt handler */
  197806. brcmf_sdiod_intr_unregister(bus->sdiodev);
  197807. + brcmf_detach(bus->sdiodev->dev);
  197808. +
  197809. cancel_work_sync(&bus->datawork);
  197810. if (bus->brcmf_wq)
  197811. destroy_workqueue(bus->brcmf_wq);
  197812. - if (bus->sdiodev->bus_if->drvr) {
  197813. - brcmf_detach(bus->sdiodev->dev);
  197814. - }
  197815. -
  197816. if (bus->ci) {
  197817. if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
  197818. sdio_claim_host(bus->sdiodev->func[1]);
  197819. @@ -4042,12 +4170,11 @@
  197820. * all necessary cores.
  197821. */
  197822. msleep(20);
  197823. - brcmf_sdio_chip_enter_download(bus->sdiodev,
  197824. - bus->ci);
  197825. + brcmf_chip_enter_download(bus->ci);
  197826. brcmf_sdio_clkctl(bus, CLK_NONE, false);
  197827. sdio_release_host(bus->sdiodev->func[1]);
  197828. }
  197829. - brcmf_sdio_chip_detach(&bus->ci);
  197830. + brcmf_chip_detach(bus->ci);
  197831. }
  197832. kfree(bus->rxbuf);
  197833. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/firmware.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
  197834. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/firmware.c 1970-01-01 01:00:00.000000000 +0100
  197835. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/firmware.c 2014-08-20 19:31:46.888872268 +0200
  197836. @@ -0,0 +1,332 @@
  197837. +/*
  197838. + * Copyright (c) 2013 Broadcom Corporation
  197839. + *
  197840. + * Permission to use, copy, modify, and/or distribute this software for any
  197841. + * purpose with or without fee is hereby granted, provided that the above
  197842. + * copyright notice and this permission notice appear in all copies.
  197843. + *
  197844. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  197845. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  197846. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  197847. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  197848. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  197849. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  197850. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  197851. + */
  197852. +
  197853. +#include <linux/kernel.h>
  197854. +#include <linux/slab.h>
  197855. +#include <linux/device.h>
  197856. +#include <linux/firmware.h>
  197857. +
  197858. +#include "dhd_dbg.h"
  197859. +#include "firmware.h"
  197860. +
  197861. +enum nvram_parser_state {
  197862. + IDLE,
  197863. + KEY,
  197864. + VALUE,
  197865. + COMMENT,
  197866. + END
  197867. +};
  197868. +
  197869. +/**
  197870. + * struct nvram_parser - internal info for parser.
  197871. + *
  197872. + * @state: current parser state.
  197873. + * @fwnv: input buffer being parsed.
  197874. + * @nvram: output buffer with parse result.
  197875. + * @nvram_len: lenght of parse result.
  197876. + * @line: current line.
  197877. + * @column: current column in line.
  197878. + * @pos: byte offset in input buffer.
  197879. + * @entry: start position of key,value entry.
  197880. + */
  197881. +struct nvram_parser {
  197882. + enum nvram_parser_state state;
  197883. + const struct firmware *fwnv;
  197884. + u8 *nvram;
  197885. + u32 nvram_len;
  197886. + u32 line;
  197887. + u32 column;
  197888. + u32 pos;
  197889. + u32 entry;
  197890. +};
  197891. +
  197892. +static bool is_nvram_char(char c)
  197893. +{
  197894. + /* comment marker excluded */
  197895. + if (c == '#')
  197896. + return false;
  197897. +
  197898. + /* key and value may have any other readable character */
  197899. + return (c > 0x20 && c < 0x7f);
  197900. +}
  197901. +
  197902. +static bool is_whitespace(char c)
  197903. +{
  197904. + return (c == ' ' || c == '\r' || c == '\n' || c == '\t');
  197905. +}
  197906. +
  197907. +static enum nvram_parser_state brcmf_nvram_handle_idle(struct nvram_parser *nvp)
  197908. +{
  197909. + char c;
  197910. +
  197911. + c = nvp->fwnv->data[nvp->pos];
  197912. + if (c == '\n')
  197913. + return COMMENT;
  197914. + if (is_whitespace(c))
  197915. + goto proceed;
  197916. + if (c == '#')
  197917. + return COMMENT;
  197918. + if (is_nvram_char(c)) {
  197919. + nvp->entry = nvp->pos;
  197920. + return KEY;
  197921. + }
  197922. + brcmf_dbg(INFO, "warning: ln=%d:col=%d: ignoring invalid character\n",
  197923. + nvp->line, nvp->column);
  197924. +proceed:
  197925. + nvp->column++;
  197926. + nvp->pos++;
  197927. + return IDLE;
  197928. +}
  197929. +
  197930. +static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp)
  197931. +{
  197932. + enum nvram_parser_state st = nvp->state;
  197933. + char c;
  197934. +
  197935. + c = nvp->fwnv->data[nvp->pos];
  197936. + if (c == '=') {
  197937. + st = VALUE;
  197938. + } else if (!is_nvram_char(c)) {
  197939. + brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
  197940. + nvp->line, nvp->column);
  197941. + return COMMENT;
  197942. + }
  197943. +
  197944. + nvp->column++;
  197945. + nvp->pos++;
  197946. + return st;
  197947. +}
  197948. +
  197949. +static enum nvram_parser_state
  197950. +brcmf_nvram_handle_value(struct nvram_parser *nvp)
  197951. +{
  197952. + char c;
  197953. + char *skv;
  197954. + char *ekv;
  197955. + u32 cplen;
  197956. +
  197957. + c = nvp->fwnv->data[nvp->pos];
  197958. + if (!is_nvram_char(c)) {
  197959. + /* key,value pair complete */
  197960. + ekv = (u8 *)&nvp->fwnv->data[nvp->pos];
  197961. + skv = (u8 *)&nvp->fwnv->data[nvp->entry];
  197962. + cplen = ekv - skv;
  197963. + /* copy to output buffer */
  197964. + memcpy(&nvp->nvram[nvp->nvram_len], skv, cplen);
  197965. + nvp->nvram_len += cplen;
  197966. + nvp->nvram[nvp->nvram_len] = '\0';
  197967. + nvp->nvram_len++;
  197968. + return IDLE;
  197969. + }
  197970. + nvp->pos++;
  197971. + nvp->column++;
  197972. + return VALUE;
  197973. +}
  197974. +
  197975. +static enum nvram_parser_state
  197976. +brcmf_nvram_handle_comment(struct nvram_parser *nvp)
  197977. +{
  197978. + char *eol, *sol;
  197979. +
  197980. + sol = (char *)&nvp->fwnv->data[nvp->pos];
  197981. + eol = strchr(sol, '\n');
  197982. + if (eol == NULL)
  197983. + return END;
  197984. +
  197985. + /* eat all moving to next line */
  197986. + nvp->line++;
  197987. + nvp->column = 1;
  197988. + nvp->pos += (eol - sol) + 1;
  197989. + return IDLE;
  197990. +}
  197991. +
  197992. +static enum nvram_parser_state brcmf_nvram_handle_end(struct nvram_parser *nvp)
  197993. +{
  197994. + /* final state */
  197995. + return END;
  197996. +}
  197997. +
  197998. +static enum nvram_parser_state
  197999. +(*nv_parser_states[])(struct nvram_parser *nvp) = {
  198000. + brcmf_nvram_handle_idle,
  198001. + brcmf_nvram_handle_key,
  198002. + brcmf_nvram_handle_value,
  198003. + brcmf_nvram_handle_comment,
  198004. + brcmf_nvram_handle_end
  198005. +};
  198006. +
  198007. +static int brcmf_init_nvram_parser(struct nvram_parser *nvp,
  198008. + const struct firmware *nv)
  198009. +{
  198010. + memset(nvp, 0, sizeof(*nvp));
  198011. + nvp->fwnv = nv;
  198012. + /* Alloc for extra 0 byte + roundup by 4 + length field */
  198013. + nvp->nvram = kzalloc(nv->size + 1 + 3 + sizeof(u32), GFP_KERNEL);
  198014. + if (!nvp->nvram)
  198015. + return -ENOMEM;
  198016. +
  198017. + nvp->line = 1;
  198018. + nvp->column = 1;
  198019. + return 0;
  198020. +}
  198021. +
  198022. +/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a fil
  198023. + * and ending in a NUL. Removes carriage returns, empty lines, comment lines,
  198024. + * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
  198025. + * End of buffer is completed with token identifying length of buffer.
  198026. + */
  198027. +static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length)
  198028. +{
  198029. + struct nvram_parser nvp;
  198030. + u32 pad;
  198031. + u32 token;
  198032. + __le32 token_le;
  198033. +
  198034. + if (brcmf_init_nvram_parser(&nvp, nv) < 0)
  198035. + return NULL;
  198036. +
  198037. + while (nvp.pos < nv->size) {
  198038. + nvp.state = nv_parser_states[nvp.state](&nvp);
  198039. + if (nvp.state == END)
  198040. + break;
  198041. + }
  198042. + pad = nvp.nvram_len;
  198043. + *new_length = roundup(nvp.nvram_len + 1, 4);
  198044. + while (pad != *new_length) {
  198045. + nvp.nvram[pad] = 0;
  198046. + pad++;
  198047. + }
  198048. +
  198049. + token = *new_length / 4;
  198050. + token = (~token << 16) | (token & 0x0000FFFF);
  198051. + token_le = cpu_to_le32(token);
  198052. +
  198053. + memcpy(&nvp.nvram[*new_length], &token_le, sizeof(token_le));
  198054. + *new_length += sizeof(token_le);
  198055. +
  198056. + return nvp.nvram;
  198057. +}
  198058. +
  198059. +void brcmf_fw_nvram_free(void *nvram)
  198060. +{
  198061. + kfree(nvram);
  198062. +}
  198063. +
  198064. +struct brcmf_fw {
  198065. + struct device *dev;
  198066. + u16 flags;
  198067. + const struct firmware *code;
  198068. + const char *nvram_name;
  198069. + void (*done)(struct device *dev, const struct firmware *fw,
  198070. + void *nvram_image, u32 nvram_len);
  198071. +};
  198072. +
  198073. +static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
  198074. +{
  198075. + struct brcmf_fw *fwctx = ctx;
  198076. + u32 nvram_length = 0;
  198077. + void *nvram = NULL;
  198078. +
  198079. + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
  198080. + if (!fw && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
  198081. + goto fail;
  198082. +
  198083. + if (fw) {
  198084. + nvram = brcmf_fw_nvram_strip(fw, &nvram_length);
  198085. + release_firmware(fw);
  198086. + if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
  198087. + goto fail;
  198088. + }
  198089. +
  198090. + fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length);
  198091. + kfree(fwctx);
  198092. + return;
  198093. +
  198094. +fail:
  198095. + brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
  198096. + if (fwctx->code)
  198097. + release_firmware(fwctx->code);
  198098. + device_release_driver(fwctx->dev);
  198099. + kfree(fwctx);
  198100. +}
  198101. +
  198102. +static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
  198103. +{
  198104. + struct brcmf_fw *fwctx = ctx;
  198105. + int ret;
  198106. +
  198107. + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
  198108. + if (!fw)
  198109. + goto fail;
  198110. +
  198111. + /* only requested code so done here */
  198112. + if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) {
  198113. + fwctx->done(fwctx->dev, fw, NULL, 0);
  198114. + kfree(fwctx);
  198115. + return;
  198116. + }
  198117. + fwctx->code = fw;
  198118. + ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name,
  198119. + fwctx->dev, GFP_KERNEL, fwctx,
  198120. + brcmf_fw_request_nvram_done);
  198121. +
  198122. + if (!ret)
  198123. + return;
  198124. +
  198125. + /* when nvram is optional call .done() callback here */
  198126. + if (fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL) {
  198127. + fwctx->done(fwctx->dev, fw, NULL, 0);
  198128. + kfree(fwctx);
  198129. + return;
  198130. + }
  198131. +
  198132. + /* failed nvram request */
  198133. + release_firmware(fw);
  198134. +fail:
  198135. + brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
  198136. + device_release_driver(fwctx->dev);
  198137. + kfree(fwctx);
  198138. +}
  198139. +
  198140. +int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
  198141. + const char *code, const char *nvram,
  198142. + void (*fw_cb)(struct device *dev,
  198143. + const struct firmware *fw,
  198144. + void *nvram_image, u32 nvram_len))
  198145. +{
  198146. + struct brcmf_fw *fwctx;
  198147. +
  198148. + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
  198149. + if (!fw_cb || !code)
  198150. + return -EINVAL;
  198151. +
  198152. + if ((flags & BRCMF_FW_REQUEST_NVRAM) && !nvram)
  198153. + return -EINVAL;
  198154. +
  198155. + fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL);
  198156. + if (!fwctx)
  198157. + return -ENOMEM;
  198158. +
  198159. + fwctx->dev = dev;
  198160. + fwctx->flags = flags;
  198161. + fwctx->done = fw_cb;
  198162. + if (flags & BRCMF_FW_REQUEST_NVRAM)
  198163. + fwctx->nvram_name = nvram;
  198164. +
  198165. + return request_firmware_nowait(THIS_MODULE, true, code, dev,
  198166. + GFP_KERNEL, fwctx,
  198167. + brcmf_fw_request_code_done);
  198168. +}
  198169. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/firmware.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/firmware.h
  198170. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/firmware.h 1970-01-01 01:00:00.000000000 +0100
  198171. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/firmware.h 2014-08-20 19:31:46.888872268 +0200
  198172. @@ -0,0 +1,36 @@
  198173. +/*
  198174. + * Copyright (c) 2013 Broadcom Corporation
  198175. + *
  198176. + * Permission to use, copy, modify, and/or distribute this software for any
  198177. + * purpose with or without fee is hereby granted, provided that the above
  198178. + * copyright notice and this permission notice appear in all copies.
  198179. + *
  198180. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  198181. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  198182. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  198183. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  198184. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  198185. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  198186. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  198187. + */
  198188. +#ifndef BRCMFMAC_FIRMWARE_H
  198189. +#define BRCMFMAC_FIRMWARE_H
  198190. +
  198191. +#define BRCMF_FW_REQUEST 0x000F
  198192. +#define BRCMF_FW_REQUEST_NVRAM 0x0001
  198193. +#define BRCMF_FW_REQ_FLAGS 0x00F0
  198194. +#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010
  198195. +
  198196. +void brcmf_fw_nvram_free(void *nvram);
  198197. +/*
  198198. + * Request firmware(s) asynchronously. When the asynchronous request
  198199. + * fails it will not use the callback, but call device_release_driver()
  198200. + * instead which will call the driver .remove() callback.
  198201. + */
  198202. +int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
  198203. + const char *code, const char *nvram,
  198204. + void (*fw_cb)(struct device *dev,
  198205. + const struct firmware *fw,
  198206. + void *nvram_image, u32 nvram_len));
  198207. +
  198208. +#endif /* BRCMFMAC_FIRMWARE_H */
  198209. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/fwil.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
  198210. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/fwil.c 2014-07-31 23:51:43.000000000 +0200
  198211. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/fwil.c 2014-08-20 19:31:46.888872268 +0200
  198212. @@ -124,7 +124,8 @@
  198213. }
  198214. static u32
  198215. -brcmf_create_iovar(char *name, char *data, u32 datalen, char *buf, u32 buflen)
  198216. +brcmf_create_iovar(char *name, const char *data, u32 datalen,
  198217. + char *buf, u32 buflen)
  198218. {
  198219. u32 len;
  198220. @@ -144,7 +145,7 @@
  198221. s32
  198222. -brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data,
  198223. +brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, const void *data,
  198224. u32 len)
  198225. {
  198226. struct brcmf_pub *drvr = ifp->drvr;
  198227. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/fwil.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
  198228. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/fwil.h 2014-07-31 23:51:43.000000000 +0200
  198229. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/fwil.h 2014-08-20 19:31:46.888872268 +0200
  198230. @@ -83,7 +83,7 @@
  198231. s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data);
  198232. s32 brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data);
  198233. -s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data,
  198234. +s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, const void *data,
  198235. u32 len);
  198236. s32 brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data,
  198237. u32 len);
  198238. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
  198239. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h 2014-07-31 23:51:43.000000000 +0200
  198240. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h 2014-08-20 19:31:46.888872268 +0200
  198241. @@ -48,6 +48,19 @@
  198242. #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
  198243. +/* OBSS Coex Auto/On/Off */
  198244. +#define BRCMF_OBSS_COEX_AUTO (-1)
  198245. +#define BRCMF_OBSS_COEX_OFF 0
  198246. +#define BRCMF_OBSS_COEX_ON 1
  198247. +
  198248. +/* join preference types for join_pref iovar */
  198249. +enum brcmf_join_pref_types {
  198250. + BRCMF_JOIN_PREF_RSSI = 1,
  198251. + BRCMF_JOIN_PREF_WPA,
  198252. + BRCMF_JOIN_PREF_BAND,
  198253. + BRCMF_JOIN_PREF_RSSI_DELTA,
  198254. +};
  198255. +
  198256. enum brcmf_fil_p2p_if_types {
  198257. BRCMF_FIL_P2P_IF_CLIENT,
  198258. BRCMF_FIL_P2P_IF_GO,
  198259. @@ -87,6 +100,11 @@
  198260. __le32 enable;
  198261. };
  198262. +struct brcmf_fil_bwcap_le {
  198263. + __le32 band;
  198264. + __le32 bw_cap;
  198265. +};
  198266. +
  198267. /**
  198268. * struct tdls_iovar - common structure for tdls iovars.
  198269. *
  198270. @@ -272,6 +290,22 @@
  198271. __le16 chanspec_list[1];
  198272. };
  198273. +/**
  198274. + * struct join_pref params - parameters for preferred join selection.
  198275. + *
  198276. + * @type: preference type (see enum brcmf_join_pref_types).
  198277. + * @len: length of bytes following (currently always 2).
  198278. + * @rssi_gain: signal gain for selection (only when @type is RSSI_DELTA).
  198279. + * @band: band to which selection preference applies.
  198280. + * This is used if @type is BAND or RSSI_DELTA.
  198281. + */
  198282. +struct brcmf_join_pref_params {
  198283. + u8 type;
  198284. + u8 len;
  198285. + u8 rssi_gain;
  198286. + u8 band;
  198287. +};
  198288. +
  198289. /* used for join with or without a specific bssid and channel list */
  198290. struct brcmf_join_params {
  198291. struct brcmf_ssid_le ssid_le;
  198292. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
  198293. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c 2014-07-31 23:51:43.000000000 +0200
  198294. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c 2014-08-20 19:31:46.892872284 +0200
  198295. @@ -476,6 +476,7 @@
  198296. bool bus_flow_blocked;
  198297. bool creditmap_received;
  198298. u8 mode;
  198299. + bool avoid_queueing;
  198300. };
  198301. /*
  198302. @@ -1369,13 +1370,12 @@
  198303. }
  198304. static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
  198305. - struct sk_buff *skb, u32 genbit,
  198306. - u16 seq)
  198307. + struct sk_buff *skb, u8 ifidx,
  198308. + u32 genbit, u16 seq)
  198309. {
  198310. struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
  198311. u32 hslot;
  198312. int ret;
  198313. - u8 ifidx;
  198314. hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
  198315. @@ -1389,29 +1389,21 @@
  198316. entry->generation = genbit;
  198317. - ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
  198318. - if (ret == 0) {
  198319. - brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
  198320. - brcmf_skbcb(skb)->htod_seq = seq;
  198321. - if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
  198322. - brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
  198323. - brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
  198324. - } else {
  198325. - brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
  198326. - }
  198327. - ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
  198328. - skb);
  198329. + brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
  198330. + brcmf_skbcb(skb)->htod_seq = seq;
  198331. + if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
  198332. + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
  198333. + brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
  198334. + } else {
  198335. + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
  198336. }
  198337. + ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb);
  198338. if (ret != 0) {
  198339. - /* suppress q is full or hdrpull failed, drop this packet */
  198340. - brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
  198341. - true);
  198342. + /* suppress q is full drop this packet */
  198343. + brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, true);
  198344. } else {
  198345. - /*
  198346. - * Mark suppressed to avoid a double free during
  198347. - * wlfc cleanup
  198348. - */
  198349. + /* Mark suppressed to avoid a double free during wlfc cleanup */
  198350. brcmf_fws_hanger_mark_suppressed(&fws->hanger, hslot);
  198351. }
  198352. @@ -1428,6 +1420,7 @@
  198353. struct sk_buff *skb;
  198354. struct brcmf_skbuff_cb *skcb;
  198355. struct brcmf_fws_mac_descriptor *entry = NULL;
  198356. + u8 ifidx;
  198357. brcmf_dbg(DATA, "flags %d\n", flags);
  198358. @@ -1476,12 +1469,15 @@
  198359. }
  198360. brcmf_fws_macdesc_return_req_credit(skb);
  198361. + if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) {
  198362. + brcmu_pkt_buf_free_skb(skb);
  198363. + return -EINVAL;
  198364. + }
  198365. if (!remove_from_hanger)
  198366. - ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit,
  198367. - seq);
  198368. -
  198369. + ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx,
  198370. + genbit, seq);
  198371. if (remove_from_hanger || ret)
  198372. - brcmf_txfinalize(fws->drvr, skb, true);
  198373. + brcmf_txfinalize(fws->drvr, skb, ifidx, true);
  198374. return 0;
  198375. }
  198376. @@ -1868,7 +1864,7 @@
  198377. struct ethhdr *eh = (struct ethhdr *)(skb->data);
  198378. int fifo = BRCMF_FWS_FIFO_BCMC;
  198379. bool multicast = is_multicast_ether_addr(eh->h_dest);
  198380. - bool pae = eh->h_proto == htons(ETH_P_PAE);
  198381. + int rc = 0;
  198382. brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto));
  198383. /* determine the priority */
  198384. @@ -1876,8 +1872,13 @@
  198385. skb->priority = cfg80211_classify8021d(skb, NULL);
  198386. drvr->tx_multicast += !!multicast;
  198387. - if (pae)
  198388. - atomic_inc(&ifp->pend_8021x_cnt);
  198389. +
  198390. + if (fws->avoid_queueing) {
  198391. + rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb);
  198392. + if (rc < 0)
  198393. + brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
  198394. + return rc;
  198395. + }
  198396. /* set control buffer information */
  198397. skcb->if_flags = 0;
  198398. @@ -1899,15 +1900,12 @@
  198399. brcmf_fws_schedule_deq(fws);
  198400. } else {
  198401. brcmf_err("drop skb: no hanger slot\n");
  198402. - if (pae) {
  198403. - atomic_dec(&ifp->pend_8021x_cnt);
  198404. - if (waitqueue_active(&ifp->pend_8021x_wait))
  198405. - wake_up(&ifp->pend_8021x_wait);
  198406. - }
  198407. - brcmu_pkt_buf_free_skb(skb);
  198408. + brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
  198409. + rc = -ENOMEM;
  198410. }
  198411. brcmf_fws_unlock(fws);
  198412. - return 0;
  198413. +
  198414. + return rc;
  198415. }
  198416. void brcmf_fws_reset_interface(struct brcmf_if *ifp)
  198417. @@ -1982,7 +1980,8 @@
  198418. ret = brcmf_proto_txdata(drvr, ifidx, 0, skb);
  198419. brcmf_fws_lock(fws);
  198420. if (ret < 0)
  198421. - brcmf_txfinalize(drvr, skb, false);
  198422. + brcmf_txfinalize(drvr, skb, ifidx,
  198423. + false);
  198424. if (fws->bus_flow_blocked)
  198425. break;
  198426. }
  198427. @@ -2039,6 +2038,13 @@
  198428. fws->drvr = drvr;
  198429. fws->fcmode = fcmode;
  198430. + if ((drvr->bus_if->always_use_fws_queue == false) &&
  198431. + (fcmode == BRCMF_FWS_FCMODE_NONE)) {
  198432. + fws->avoid_queueing = true;
  198433. + brcmf_dbg(INFO, "FWS queueing will be avoided\n");
  198434. + return 0;
  198435. + }
  198436. +
  198437. fws->fws_wq = create_singlethread_workqueue("brcmf_fws_wq");
  198438. if (fws->fws_wq == NULL) {
  198439. brcmf_err("workqueue creation failed\n");
  198440. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/Makefile linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/Makefile
  198441. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/Makefile 2014-07-31 23:51:43.000000000 +0200
  198442. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/Makefile 2014-08-20 19:31:46.868872181 +0200
  198443. @@ -24,6 +24,7 @@
  198444. obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
  198445. brcmfmac-objs += \
  198446. wl_cfg80211.o \
  198447. + chip.o \
  198448. fwil.o \
  198449. fweh.o \
  198450. fwsignal.o \
  198451. @@ -32,12 +33,11 @@
  198452. bcdc.o \
  198453. dhd_common.o \
  198454. dhd_linux.o \
  198455. - nvram.o \
  198456. + firmware.o \
  198457. btcoex.o
  198458. brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
  198459. dhd_sdio.o \
  198460. - bcmsdh.o \
  198461. - sdio_chip.o
  198462. + bcmsdh.o
  198463. brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
  198464. usb.o
  198465. brcmfmac-$(CONFIG_BRCMDBG) += \
  198466. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/nvram.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/nvram.c
  198467. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/nvram.c 2014-07-31 23:51:43.000000000 +0200
  198468. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/nvram.c 1970-01-01 01:00:00.000000000 +0100
  198469. @@ -1,94 +0,0 @@
  198470. -/*
  198471. - * Copyright (c) 2013 Broadcom Corporation
  198472. - *
  198473. - * Permission to use, copy, modify, and/or distribute this software for any
  198474. - * purpose with or without fee is hereby granted, provided that the above
  198475. - * copyright notice and this permission notice appear in all copies.
  198476. - *
  198477. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  198478. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  198479. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  198480. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  198481. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  198482. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  198483. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  198484. - */
  198485. -
  198486. -#include <linux/kernel.h>
  198487. -#include <linux/slab.h>
  198488. -#include <linux/firmware.h>
  198489. -
  198490. -#include "nvram.h"
  198491. -
  198492. -/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a file
  198493. - * and ending in a NUL. Removes carriage returns, empty lines, comment lines,
  198494. - * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
  198495. - * End of buffer is completed with token identifying length of buffer.
  198496. - */
  198497. -void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length)
  198498. -{
  198499. - u8 *nvram;
  198500. - u32 i;
  198501. - u32 len;
  198502. - u32 column;
  198503. - u8 val;
  198504. - bool comment;
  198505. - u32 token;
  198506. - __le32 token_le;
  198507. -
  198508. - /* Alloc for extra 0 byte + roundup by 4 + length field */
  198509. - nvram = kmalloc(nv->size + 1 + 3 + sizeof(token_le), GFP_KERNEL);
  198510. - if (!nvram)
  198511. - return NULL;
  198512. -
  198513. - len = 0;
  198514. - column = 0;
  198515. - comment = false;
  198516. - for (i = 0; i < nv->size; i++) {
  198517. - val = nv->data[i];
  198518. - if (val == 0)
  198519. - break;
  198520. - if (val == '\r')
  198521. - continue;
  198522. - if (comment && (val != '\n'))
  198523. - continue;
  198524. - comment = false;
  198525. - if (val == '#') {
  198526. - comment = true;
  198527. - continue;
  198528. - }
  198529. - if (val == '\n') {
  198530. - if (column == 0)
  198531. - continue;
  198532. - nvram[len] = 0;
  198533. - len++;
  198534. - column = 0;
  198535. - continue;
  198536. - }
  198537. - nvram[len] = val;
  198538. - len++;
  198539. - column++;
  198540. - }
  198541. - column = len;
  198542. - *new_length = roundup(len + 1, 4);
  198543. - while (column != *new_length) {
  198544. - nvram[column] = 0;
  198545. - column++;
  198546. - }
  198547. -
  198548. - token = *new_length / 4;
  198549. - token = (~token << 16) | (token & 0x0000FFFF);
  198550. - token_le = cpu_to_le32(token);
  198551. -
  198552. - memcpy(&nvram[*new_length], &token_le, sizeof(token_le));
  198553. - *new_length += sizeof(token_le);
  198554. -
  198555. - return nvram;
  198556. -}
  198557. -
  198558. -void brcmf_nvram_free(void *nvram)
  198559. -{
  198560. - kfree(nvram);
  198561. -}
  198562. -
  198563. -
  198564. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/nvram.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/nvram.h
  198565. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/nvram.h 2014-07-31 23:51:43.000000000 +0200
  198566. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/nvram.h 1970-01-01 01:00:00.000000000 +0100
  198567. @@ -1,24 +0,0 @@
  198568. -/*
  198569. - * Copyright (c) 2013 Broadcom Corporation
  198570. - *
  198571. - * Permission to use, copy, modify, and/or distribute this software for any
  198572. - * purpose with or without fee is hereby granted, provided that the above
  198573. - * copyright notice and this permission notice appear in all copies.
  198574. - *
  198575. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  198576. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  198577. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  198578. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  198579. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  198580. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  198581. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  198582. - */
  198583. -#ifndef BRCMFMAC_NVRAM_H
  198584. -#define BRCMFMAC_NVRAM_H
  198585. -
  198586. -
  198587. -void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length);
  198588. -void brcmf_nvram_free(void *nvram);
  198589. -
  198590. -
  198591. -#endif /* BRCMFMAC_NVRAM_H */
  198592. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/p2p.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
  198593. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/p2p.c 2014-07-31 23:51:43.000000000 +0200
  198594. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/p2p.c 2014-08-20 19:31:46.892872284 +0200
  198595. @@ -797,7 +797,8 @@
  198596. /* SOCIAL CHANNELS 1, 6, 11 */
  198597. search_state = WL_P2P_DISC_ST_SEARCH;
  198598. brcmf_dbg(INFO, "P2P SEARCH PHASE START\n");
  198599. - } else if (dev != NULL && vif->mode == WL_MODE_AP) {
  198600. + } else if (dev != NULL &&
  198601. + vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
  198602. /* If you are already a GO, then do SEARCH only */
  198603. brcmf_dbg(INFO, "Already a GO. Do SEARCH Only\n");
  198604. search_state = WL_P2P_DISC_ST_SEARCH;
  198605. @@ -2256,7 +2257,6 @@
  198606. struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
  198607. struct brcmf_cfg80211_vif *vif;
  198608. enum brcmf_fil_p2p_if_types iftype;
  198609. - enum wl_mode mode;
  198610. int err;
  198611. if (brcmf_cfg80211_vif_event_armed(cfg))
  198612. @@ -2267,11 +2267,9 @@
  198613. switch (type) {
  198614. case NL80211_IFTYPE_P2P_CLIENT:
  198615. iftype = BRCMF_FIL_P2P_IF_CLIENT;
  198616. - mode = WL_MODE_BSS;
  198617. break;
  198618. case NL80211_IFTYPE_P2P_GO:
  198619. iftype = BRCMF_FIL_P2P_IF_GO;
  198620. - mode = WL_MODE_AP;
  198621. break;
  198622. case NL80211_IFTYPE_P2P_DEVICE:
  198623. return brcmf_p2p_create_p2pdev(&cfg->p2p, wiphy,
  198624. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
  198625. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c 2014-07-31 23:51:43.000000000 +0200
  198626. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c 1970-01-01 01:00:00.000000000 +0100
  198627. @@ -1,973 +0,0 @@
  198628. -/*
  198629. - * Copyright (c) 2011 Broadcom Corporation
  198630. - *
  198631. - * Permission to use, copy, modify, and/or distribute this software for any
  198632. - * purpose with or without fee is hereby granted, provided that the above
  198633. - * copyright notice and this permission notice appear in all copies.
  198634. - *
  198635. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  198636. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  198637. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  198638. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  198639. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  198640. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  198641. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  198642. - */
  198643. -/* ***** SDIO interface chip backplane handle functions ***** */
  198644. -
  198645. -#include <linux/types.h>
  198646. -#include <linux/netdevice.h>
  198647. -#include <linux/mmc/card.h>
  198648. -#include <linux/mmc/sdio_func.h>
  198649. -#include <linux/mmc/sdio_ids.h>
  198650. -#include <linux/ssb/ssb_regs.h>
  198651. -#include <linux/bcma/bcma.h>
  198652. -
  198653. -#include <chipcommon.h>
  198654. -#include <brcm_hw_ids.h>
  198655. -#include <brcmu_wifi.h>
  198656. -#include <brcmu_utils.h>
  198657. -#include <soc.h>
  198658. -#include "dhd_dbg.h"
  198659. -#include "sdio_host.h"
  198660. -#include "sdio_chip.h"
  198661. -
  198662. -/* chip core base & ramsize */
  198663. -/* bcm4329 */
  198664. -/* SDIO device core, ID 0x829 */
  198665. -#define BCM4329_CORE_BUS_BASE 0x18011000
  198666. -/* internal memory core, ID 0x80e */
  198667. -#define BCM4329_CORE_SOCRAM_BASE 0x18003000
  198668. -/* ARM Cortex M3 core, ID 0x82a */
  198669. -#define BCM4329_CORE_ARM_BASE 0x18002000
  198670. -#define BCM4329_RAMSIZE 0x48000
  198671. -
  198672. -/* bcm43143 */
  198673. -/* SDIO device core */
  198674. -#define BCM43143_CORE_BUS_BASE 0x18002000
  198675. -/* internal memory core */
  198676. -#define BCM43143_CORE_SOCRAM_BASE 0x18004000
  198677. -/* ARM Cortex M3 core, ID 0x82a */
  198678. -#define BCM43143_CORE_ARM_BASE 0x18003000
  198679. -#define BCM43143_RAMSIZE 0x70000
  198680. -
  198681. -/* All D11 cores, ID 0x812 */
  198682. -#define BCM43xx_CORE_D11_BASE 0x18001000
  198683. -
  198684. -#define SBCOREREV(sbidh) \
  198685. - ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
  198686. - ((sbidh) & SSB_IDHIGH_RCLO))
  198687. -
  198688. -/* SOC Interconnect types (aka chip types) */
  198689. -#define SOCI_SB 0
  198690. -#define SOCI_AI 1
  198691. -
  198692. -/* EROM CompIdentB */
  198693. -#define CIB_REV_MASK 0xff000000
  198694. -#define CIB_REV_SHIFT 24
  198695. -
  198696. -/* ARM CR4 core specific control flag bits */
  198697. -#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
  198698. -
  198699. -/* D11 core specific control flag bits */
  198700. -#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
  198701. -#define D11_BCMA_IOCTL_PHYRESET 0x0008
  198702. -
  198703. -#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
  198704. -/* SDIO Pad drive strength to select value mappings */
  198705. -struct sdiod_drive_str {
  198706. - u8 strength; /* Pad Drive Strength in mA */
  198707. - u8 sel; /* Chip-specific select value */
  198708. -};
  198709. -/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
  198710. -static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
  198711. - {32, 0x6},
  198712. - {26, 0x7},
  198713. - {22, 0x4},
  198714. - {16, 0x5},
  198715. - {12, 0x2},
  198716. - {8, 0x3},
  198717. - {4, 0x0},
  198718. - {0, 0x1}
  198719. -};
  198720. -
  198721. -/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
  198722. -static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = {
  198723. - {6, 0x7},
  198724. - {5, 0x6},
  198725. - {4, 0x5},
  198726. - {3, 0x4},
  198727. - {2, 0x2},
  198728. - {1, 0x1},
  198729. - {0, 0x0}
  198730. -};
  198731. -
  198732. -/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
  198733. -static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = {
  198734. - {3, 0x3},
  198735. - {2, 0x2},
  198736. - {1, 0x1},
  198737. - {0, 0x0} };
  198738. -
  198739. -/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
  198740. -static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
  198741. - {16, 0x7},
  198742. - {12, 0x5},
  198743. - {8, 0x3},
  198744. - {4, 0x1}
  198745. -};
  198746. -
  198747. -u8
  198748. -brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid)
  198749. -{
  198750. - u8 idx;
  198751. -
  198752. - for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
  198753. - if (coreid == ci->c_inf[idx].id)
  198754. - return idx;
  198755. -
  198756. - return BRCMF_MAX_CORENUM;
  198757. -}
  198758. -
  198759. -static u32
  198760. -brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
  198761. - struct brcmf_chip *ci, u16 coreid)
  198762. -{
  198763. - u32 regdata;
  198764. - u8 idx;
  198765. -
  198766. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198767. -
  198768. - regdata = brcmf_sdiod_regrl(sdiodev,
  198769. - CORE_SB(ci->c_inf[idx].base, sbidhigh),
  198770. - NULL);
  198771. - return SBCOREREV(regdata);
  198772. -}
  198773. -
  198774. -static u32
  198775. -brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
  198776. - struct brcmf_chip *ci, u16 coreid)
  198777. -{
  198778. - u8 idx;
  198779. -
  198780. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198781. -
  198782. - return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
  198783. -}
  198784. -
  198785. -static bool
  198786. -brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
  198787. - struct brcmf_chip *ci, u16 coreid)
  198788. -{
  198789. - u32 regdata;
  198790. - u8 idx;
  198791. -
  198792. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198793. - if (idx == BRCMF_MAX_CORENUM)
  198794. - return false;
  198795. -
  198796. - regdata = brcmf_sdiod_regrl(sdiodev,
  198797. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  198798. - NULL);
  198799. - regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
  198800. - SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
  198801. - return (SSB_TMSLOW_CLOCK == regdata);
  198802. -}
  198803. -
  198804. -static bool
  198805. -brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
  198806. - struct brcmf_chip *ci, u16 coreid)
  198807. -{
  198808. - u32 regdata;
  198809. - u8 idx;
  198810. - bool ret;
  198811. -
  198812. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198813. - if (idx == BRCMF_MAX_CORENUM)
  198814. - return false;
  198815. -
  198816. - regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
  198817. - NULL);
  198818. - ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
  198819. -
  198820. - regdata = brcmf_sdiod_regrl(sdiodev,
  198821. - ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
  198822. - NULL);
  198823. - ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
  198824. -
  198825. - return ret;
  198826. -}
  198827. -
  198828. -static void
  198829. -brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
  198830. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  198831. - u32 in_resetbits)
  198832. -{
  198833. - u32 regdata, base;
  198834. - u8 idx;
  198835. -
  198836. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198837. - base = ci->c_inf[idx].base;
  198838. -
  198839. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
  198840. - if (regdata & SSB_TMSLOW_RESET)
  198841. - return;
  198842. -
  198843. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
  198844. - if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
  198845. - /*
  198846. - * set target reject and spin until busy is clear
  198847. - * (preserve core-specific bits)
  198848. - */
  198849. - regdata = brcmf_sdiod_regrl(sdiodev,
  198850. - CORE_SB(base, sbtmstatelow), NULL);
  198851. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
  198852. - regdata | SSB_TMSLOW_REJECT, NULL);
  198853. -
  198854. - regdata = brcmf_sdiod_regrl(sdiodev,
  198855. - CORE_SB(base, sbtmstatelow), NULL);
  198856. - udelay(1);
  198857. - SPINWAIT((brcmf_sdiod_regrl(sdiodev,
  198858. - CORE_SB(base, sbtmstatehigh),
  198859. - NULL) &
  198860. - SSB_TMSHIGH_BUSY), 100000);
  198861. -
  198862. - regdata = brcmf_sdiod_regrl(sdiodev,
  198863. - CORE_SB(base, sbtmstatehigh),
  198864. - NULL);
  198865. - if (regdata & SSB_TMSHIGH_BUSY)
  198866. - brcmf_err("core state still busy\n");
  198867. -
  198868. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
  198869. - NULL);
  198870. - if (regdata & SSB_IDLOW_INITIATOR) {
  198871. - regdata = brcmf_sdiod_regrl(sdiodev,
  198872. - CORE_SB(base, sbimstate),
  198873. - NULL);
  198874. - regdata |= SSB_IMSTATE_REJECT;
  198875. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
  198876. - regdata, NULL);
  198877. - regdata = brcmf_sdiod_regrl(sdiodev,
  198878. - CORE_SB(base, sbimstate),
  198879. - NULL);
  198880. - udelay(1);
  198881. - SPINWAIT((brcmf_sdiod_regrl(sdiodev,
  198882. - CORE_SB(base, sbimstate),
  198883. - NULL) &
  198884. - SSB_IMSTATE_BUSY), 100000);
  198885. - }
  198886. -
  198887. - /* set reset and reject while enabling the clocks */
  198888. - regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
  198889. - SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
  198890. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
  198891. - regdata, NULL);
  198892. - regdata = brcmf_sdiod_regrl(sdiodev,
  198893. - CORE_SB(base, sbtmstatelow), NULL);
  198894. - udelay(10);
  198895. -
  198896. - /* clear the initiator reject bit */
  198897. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
  198898. - NULL);
  198899. - if (regdata & SSB_IDLOW_INITIATOR) {
  198900. - regdata = brcmf_sdiod_regrl(sdiodev,
  198901. - CORE_SB(base, sbimstate),
  198902. - NULL);
  198903. - regdata &= ~SSB_IMSTATE_REJECT;
  198904. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
  198905. - regdata, NULL);
  198906. - }
  198907. - }
  198908. -
  198909. - /* leave reset and reject asserted */
  198910. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
  198911. - (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
  198912. - udelay(1);
  198913. -}
  198914. -
  198915. -static void
  198916. -brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
  198917. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  198918. - u32 in_resetbits)
  198919. -{
  198920. - u8 idx;
  198921. - u32 regdata;
  198922. - u32 wrapbase;
  198923. -
  198924. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198925. - if (idx == BRCMF_MAX_CORENUM)
  198926. - return;
  198927. -
  198928. - wrapbase = ci->c_inf[idx].wrapbase;
  198929. -
  198930. - /* if core is already in reset, skip reset */
  198931. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL);
  198932. - if ((regdata & BCMA_RESET_CTL_RESET) != 0)
  198933. - goto post_reset_config;
  198934. -
  198935. - /* configure reset */
  198936. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
  198937. - BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
  198938. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  198939. -
  198940. - /* put in reset */
  198941. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL,
  198942. - BCMA_RESET_CTL_RESET, NULL);
  198943. - usleep_range(10, 20);
  198944. -
  198945. - /* wait till reset is 1 */
  198946. - SPINWAIT(brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) !=
  198947. - BCMA_RESET_CTL_RESET, 300);
  198948. -
  198949. -post_reset_config:
  198950. - /* post reset configure */
  198951. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
  198952. - BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
  198953. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  198954. -}
  198955. -
  198956. -static void
  198957. -brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
  198958. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  198959. - u32 in_resetbits, u32 post_resetbits)
  198960. -{
  198961. - u32 regdata;
  198962. - u8 idx;
  198963. -
  198964. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198965. - if (idx == BRCMF_MAX_CORENUM)
  198966. - return;
  198967. -
  198968. - /*
  198969. - * Must do the disable sequence first to work for
  198970. - * arbitrary current core state.
  198971. - */
  198972. - brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, pre_resetbits,
  198973. - in_resetbits);
  198974. -
  198975. - /*
  198976. - * Now do the initialization sequence.
  198977. - * set reset while enabling the clock and
  198978. - * forcing them on throughout the core
  198979. - */
  198980. - brcmf_sdiod_regwl(sdiodev,
  198981. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  198982. - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
  198983. - NULL);
  198984. - regdata = brcmf_sdiod_regrl(sdiodev,
  198985. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  198986. - NULL);
  198987. - udelay(1);
  198988. -
  198989. - /* clear any serror */
  198990. - regdata = brcmf_sdiod_regrl(sdiodev,
  198991. - CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
  198992. - NULL);
  198993. - if (regdata & SSB_TMSHIGH_SERR)
  198994. - brcmf_sdiod_regwl(sdiodev,
  198995. - CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
  198996. - 0, NULL);
  198997. -
  198998. - regdata = brcmf_sdiod_regrl(sdiodev,
  198999. - CORE_SB(ci->c_inf[idx].base, sbimstate),
  199000. - NULL);
  199001. - if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
  199002. - brcmf_sdiod_regwl(sdiodev,
  199003. - CORE_SB(ci->c_inf[idx].base, sbimstate),
  199004. - regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
  199005. - NULL);
  199006. -
  199007. - /* clear reset and allow it to propagate throughout the core */
  199008. - brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  199009. - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
  199010. - regdata = brcmf_sdiod_regrl(sdiodev,
  199011. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  199012. - NULL);
  199013. - udelay(1);
  199014. -
  199015. - /* leave clock enabled */
  199016. - brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  199017. - SSB_TMSLOW_CLOCK, NULL);
  199018. - regdata = brcmf_sdiod_regrl(sdiodev,
  199019. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  199020. - NULL);
  199021. - udelay(1);
  199022. -}
  199023. -
  199024. -static void
  199025. -brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
  199026. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  199027. - u32 in_resetbits, u32 post_resetbits)
  199028. -{
  199029. - u8 idx;
  199030. - u32 regdata;
  199031. - u32 wrapbase;
  199032. -
  199033. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  199034. - if (idx == BRCMF_MAX_CORENUM)
  199035. - return;
  199036. -
  199037. - wrapbase = ci->c_inf[idx].wrapbase;
  199038. -
  199039. - /* must disable first to work for arbitrary current core state */
  199040. - brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, pre_resetbits,
  199041. - in_resetbits);
  199042. -
  199043. - while (brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) &
  199044. - BCMA_RESET_CTL_RESET) {
  199045. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL, 0, NULL);
  199046. - usleep_range(40, 60);
  199047. - }
  199048. -
  199049. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, post_resetbits |
  199050. - BCMA_IOCTL_CLK, NULL);
  199051. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  199052. -}
  199053. -
  199054. -#ifdef DEBUG
  199055. -/* safety check for chipinfo */
  199056. -static int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
  199057. -{
  199058. - u8 core_idx;
  199059. -
  199060. - /* check RAM core presence for ARM CM3 core */
  199061. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
  199062. - if (BRCMF_MAX_CORENUM != core_idx) {
  199063. - core_idx = brcmf_sdio_chip_getinfidx(ci,
  199064. - BCMA_CORE_INTERNAL_MEM);
  199065. - if (BRCMF_MAX_CORENUM == core_idx) {
  199066. - brcmf_err("RAM core not provided with ARM CM3 core\n");
  199067. - return -ENODEV;
  199068. - }
  199069. - }
  199070. -
  199071. - /* check RAM base for ARM CR4 core */
  199072. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
  199073. - if (BRCMF_MAX_CORENUM != core_idx) {
  199074. - if (ci->rambase == 0) {
  199075. - brcmf_err("RAM base not provided with ARM CR4 core\n");
  199076. - return -ENOMEM;
  199077. - }
  199078. - }
  199079. -
  199080. - return 0;
  199081. -}
  199082. -#else /* DEBUG */
  199083. -static inline int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
  199084. -{
  199085. - return 0;
  199086. -}
  199087. -#endif
  199088. -
  199089. -static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
  199090. - struct brcmf_chip *ci)
  199091. -{
  199092. - u32 regdata;
  199093. - u32 socitype;
  199094. -
  199095. - /* Get CC core rev
  199096. - * Chipid is assume to be at offset 0 from SI_ENUM_BASE
  199097. - * For different chiptypes or old sdio hosts w/o chipcommon,
  199098. - * other ways of recognition should be added here.
  199099. - */
  199100. - regdata = brcmf_sdiod_regrl(sdiodev,
  199101. - CORE_CC_REG(SI_ENUM_BASE, chipid),
  199102. - NULL);
  199103. - ci->chip = regdata & CID_ID_MASK;
  199104. - ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
  199105. - if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
  199106. - ci->chiprev >= 2)
  199107. - ci->chip = BCM4339_CHIP_ID;
  199108. - socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
  199109. -
  199110. - brcmf_dbg(INFO, "found %s chip: id=0x%x, rev=%d\n",
  199111. - socitype == SOCI_SB ? "SB" : "AXI", ci->chip, ci->chiprev);
  199112. -
  199113. - if (socitype == SOCI_SB) {
  199114. - if (ci->chip != BCM4329_CHIP_ID) {
  199115. - brcmf_err("SB chip is not supported\n");
  199116. - return -ENODEV;
  199117. - }
  199118. - ci->iscoreup = brcmf_sdio_sb_iscoreup;
  199119. - ci->corerev = brcmf_sdio_sb_corerev;
  199120. - ci->coredisable = brcmf_sdio_sb_coredisable;
  199121. - ci->resetcore = brcmf_sdio_sb_resetcore;
  199122. -
  199123. - ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
  199124. - ci->c_inf[0].base = SI_ENUM_BASE;
  199125. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199126. - ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
  199127. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199128. - ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
  199129. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199130. - ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
  199131. - ci->c_inf[4].id = BCMA_CORE_80211;
  199132. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199133. - ci->ramsize = BCM4329_RAMSIZE;
  199134. - } else if (socitype == SOCI_AI) {
  199135. - ci->iscoreup = brcmf_sdio_ai_iscoreup;
  199136. - ci->corerev = brcmf_sdio_ai_corerev;
  199137. - ci->coredisable = brcmf_sdio_ai_coredisable;
  199138. - ci->resetcore = brcmf_sdio_ai_resetcore;
  199139. -
  199140. - ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
  199141. - ci->c_inf[0].base = SI_ENUM_BASE;
  199142. -
  199143. - /* Address of cores for new chips should be added here */
  199144. - switch (ci->chip) {
  199145. - case BCM43143_CHIP_ID:
  199146. - ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000;
  199147. - ci->c_inf[0].cib = 0x2b000000;
  199148. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199149. - ci->c_inf[1].base = BCM43143_CORE_BUS_BASE;
  199150. - ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000;
  199151. - ci->c_inf[1].cib = 0x18000000;
  199152. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199153. - ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE;
  199154. - ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000;
  199155. - ci->c_inf[2].cib = 0x14000000;
  199156. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199157. - ci->c_inf[3].base = BCM43143_CORE_ARM_BASE;
  199158. - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
  199159. - ci->c_inf[3].cib = 0x07000000;
  199160. - ci->c_inf[4].id = BCMA_CORE_80211;
  199161. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199162. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  199163. - ci->ramsize = BCM43143_RAMSIZE;
  199164. - break;
  199165. - case BCM43241_CHIP_ID:
  199166. - ci->c_inf[0].wrapbase = 0x18100000;
  199167. - ci->c_inf[0].cib = 0x2a084411;
  199168. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199169. - ci->c_inf[1].base = 0x18002000;
  199170. - ci->c_inf[1].wrapbase = 0x18102000;
  199171. - ci->c_inf[1].cib = 0x0e004211;
  199172. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199173. - ci->c_inf[2].base = 0x18004000;
  199174. - ci->c_inf[2].wrapbase = 0x18104000;
  199175. - ci->c_inf[2].cib = 0x14080401;
  199176. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199177. - ci->c_inf[3].base = 0x18003000;
  199178. - ci->c_inf[3].wrapbase = 0x18103000;
  199179. - ci->c_inf[3].cib = 0x07004211;
  199180. - ci->c_inf[4].id = BCMA_CORE_80211;
  199181. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199182. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  199183. - ci->ramsize = 0x90000;
  199184. - break;
  199185. - case BCM4330_CHIP_ID:
  199186. - ci->c_inf[0].wrapbase = 0x18100000;
  199187. - ci->c_inf[0].cib = 0x27004211;
  199188. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199189. - ci->c_inf[1].base = 0x18002000;
  199190. - ci->c_inf[1].wrapbase = 0x18102000;
  199191. - ci->c_inf[1].cib = 0x07004211;
  199192. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199193. - ci->c_inf[2].base = 0x18004000;
  199194. - ci->c_inf[2].wrapbase = 0x18104000;
  199195. - ci->c_inf[2].cib = 0x0d080401;
  199196. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199197. - ci->c_inf[3].base = 0x18003000;
  199198. - ci->c_inf[3].wrapbase = 0x18103000;
  199199. - ci->c_inf[3].cib = 0x03004211;
  199200. - ci->c_inf[4].id = BCMA_CORE_80211;
  199201. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199202. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  199203. - ci->ramsize = 0x48000;
  199204. - break;
  199205. - case BCM4334_CHIP_ID:
  199206. - ci->c_inf[0].wrapbase = 0x18100000;
  199207. - ci->c_inf[0].cib = 0x29004211;
  199208. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199209. - ci->c_inf[1].base = 0x18002000;
  199210. - ci->c_inf[1].wrapbase = 0x18102000;
  199211. - ci->c_inf[1].cib = 0x0d004211;
  199212. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199213. - ci->c_inf[2].base = 0x18004000;
  199214. - ci->c_inf[2].wrapbase = 0x18104000;
  199215. - ci->c_inf[2].cib = 0x13080401;
  199216. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199217. - ci->c_inf[3].base = 0x18003000;
  199218. - ci->c_inf[3].wrapbase = 0x18103000;
  199219. - ci->c_inf[3].cib = 0x07004211;
  199220. - ci->c_inf[4].id = BCMA_CORE_80211;
  199221. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199222. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  199223. - ci->ramsize = 0x80000;
  199224. - break;
  199225. - case BCM4335_CHIP_ID:
  199226. - ci->c_inf[0].wrapbase = 0x18100000;
  199227. - ci->c_inf[0].cib = 0x2b084411;
  199228. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199229. - ci->c_inf[1].base = 0x18005000;
  199230. - ci->c_inf[1].wrapbase = 0x18105000;
  199231. - ci->c_inf[1].cib = 0x0f004211;
  199232. - ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
  199233. - ci->c_inf[2].base = 0x18002000;
  199234. - ci->c_inf[2].wrapbase = 0x18102000;
  199235. - ci->c_inf[2].cib = 0x01084411;
  199236. - ci->c_inf[3].id = BCMA_CORE_80211;
  199237. - ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
  199238. - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
  199239. - ci->ramsize = 0xc0000;
  199240. - ci->rambase = 0x180000;
  199241. - break;
  199242. - case BCM43362_CHIP_ID:
  199243. - ci->c_inf[0].wrapbase = 0x18100000;
  199244. - ci->c_inf[0].cib = 0x27004211;
  199245. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199246. - ci->c_inf[1].base = 0x18002000;
  199247. - ci->c_inf[1].wrapbase = 0x18102000;
  199248. - ci->c_inf[1].cib = 0x0a004211;
  199249. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199250. - ci->c_inf[2].base = 0x18004000;
  199251. - ci->c_inf[2].wrapbase = 0x18104000;
  199252. - ci->c_inf[2].cib = 0x08080401;
  199253. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199254. - ci->c_inf[3].base = 0x18003000;
  199255. - ci->c_inf[3].wrapbase = 0x18103000;
  199256. - ci->c_inf[3].cib = 0x03004211;
  199257. - ci->c_inf[4].id = BCMA_CORE_80211;
  199258. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199259. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  199260. - ci->ramsize = 0x3C000;
  199261. - break;
  199262. - case BCM4339_CHIP_ID:
  199263. - ci->c_inf[0].wrapbase = 0x18100000;
  199264. - ci->c_inf[0].cib = 0x2e084411;
  199265. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199266. - ci->c_inf[1].base = 0x18005000;
  199267. - ci->c_inf[1].wrapbase = 0x18105000;
  199268. - ci->c_inf[1].cib = 0x15004211;
  199269. - ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
  199270. - ci->c_inf[2].base = 0x18002000;
  199271. - ci->c_inf[2].wrapbase = 0x18102000;
  199272. - ci->c_inf[2].cib = 0x04084411;
  199273. - ci->c_inf[3].id = BCMA_CORE_80211;
  199274. - ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
  199275. - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
  199276. - ci->ramsize = 0xc0000;
  199277. - ci->rambase = 0x180000;
  199278. - break;
  199279. - default:
  199280. - brcmf_err("AXI chip is not supported\n");
  199281. - return -ENODEV;
  199282. - }
  199283. - } else {
  199284. - brcmf_err("chip backplane type %u is not supported\n",
  199285. - socitype);
  199286. - return -ENODEV;
  199287. - }
  199288. -
  199289. - return brcmf_sdio_chip_cichk(ci);
  199290. -}
  199291. -
  199292. -static int
  199293. -brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
  199294. -{
  199295. - int err = 0;
  199296. - u8 clkval, clkset;
  199297. -
  199298. - /* Try forcing SDIO core to do ALPAvail request only */
  199299. - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
  199300. - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  199301. - if (err) {
  199302. - brcmf_err("error writing for HT off\n");
  199303. - return err;
  199304. - }
  199305. -
  199306. - /* If register supported, wait for ALPAvail and then force ALP */
  199307. - /* This may take up to 15 milliseconds */
  199308. - clkval = brcmf_sdiod_regrb(sdiodev,
  199309. - SBSDIO_FUNC1_CHIPCLKCSR, NULL);
  199310. -
  199311. - if ((clkval & ~SBSDIO_AVBITS) != clkset) {
  199312. - brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
  199313. - clkset, clkval);
  199314. - return -EACCES;
  199315. - }
  199316. -
  199317. - SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
  199318. - SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
  199319. - !SBSDIO_ALPAV(clkval)),
  199320. - PMU_MAX_TRANSITION_DLY);
  199321. - if (!SBSDIO_ALPAV(clkval)) {
  199322. - brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
  199323. - clkval);
  199324. - return -EBUSY;
  199325. - }
  199326. -
  199327. - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
  199328. - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  199329. - udelay(65);
  199330. -
  199331. - /* Also, disable the extra SDIO pull-ups */
  199332. - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
  199333. -
  199334. - return 0;
  199335. -}
  199336. -
  199337. -static void
  199338. -brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
  199339. - struct brcmf_chip *ci)
  199340. -{
  199341. - u32 base = ci->c_inf[0].base;
  199342. -
  199343. - /* get chipcommon rev */
  199344. - ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
  199345. -
  199346. - /* get chipcommon capabilites */
  199347. - ci->c_inf[0].caps = brcmf_sdiod_regrl(sdiodev,
  199348. - CORE_CC_REG(base, capabilities),
  199349. - NULL);
  199350. -
  199351. - /* get pmu caps & rev */
  199352. - if (ci->c_inf[0].caps & CC_CAP_PMU) {
  199353. - ci->pmucaps =
  199354. - brcmf_sdiod_regrl(sdiodev,
  199355. - CORE_CC_REG(base, pmucapabilities),
  199356. - NULL);
  199357. - ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
  199358. - }
  199359. -
  199360. - ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id);
  199361. -
  199362. - brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
  199363. - ci->c_inf[0].rev, ci->pmurev,
  199364. - ci->c_inf[1].rev, ci->c_inf[1].id);
  199365. -
  199366. - /*
  199367. - * Make sure any on-chip ARM is off (in case strapping is wrong),
  199368. - * or downloaded code was already running.
  199369. - */
  199370. - ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
  199371. -}
  199372. -
  199373. -int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
  199374. - struct brcmf_chip **ci_ptr)
  199375. -{
  199376. - int ret;
  199377. - struct brcmf_chip *ci;
  199378. -
  199379. - brcmf_dbg(TRACE, "Enter\n");
  199380. -
  199381. - ci = kzalloc(sizeof(*ci), GFP_ATOMIC);
  199382. - if (!ci)
  199383. - return -ENOMEM;
  199384. -
  199385. - ret = brcmf_sdio_chip_buscoreprep(sdiodev);
  199386. - if (ret != 0)
  199387. - goto err;
  199388. -
  199389. - ret = brcmf_sdio_chip_recognition(sdiodev, ci);
  199390. - if (ret != 0)
  199391. - goto err;
  199392. -
  199393. - brcmf_sdio_chip_buscoresetup(sdiodev, ci);
  199394. -
  199395. - brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
  199396. - 0, NULL);
  199397. - brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
  199398. - 0, NULL);
  199399. -
  199400. - *ci_ptr = ci;
  199401. - return 0;
  199402. -
  199403. -err:
  199404. - kfree(ci);
  199405. - return ret;
  199406. -}
  199407. -
  199408. -void
  199409. -brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr)
  199410. -{
  199411. - brcmf_dbg(TRACE, "Enter\n");
  199412. -
  199413. - kfree(*ci_ptr);
  199414. - *ci_ptr = NULL;
  199415. -}
  199416. -
  199417. -static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
  199418. -{
  199419. - const char *fmt;
  199420. -
  199421. - fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
  199422. - snprintf(buf, len, fmt, chipid);
  199423. - return buf;
  199424. -}
  199425. -
  199426. -void
  199427. -brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
  199428. - struct brcmf_chip *ci, u32 drivestrength)
  199429. -{
  199430. - const struct sdiod_drive_str *str_tab = NULL;
  199431. - u32 str_mask;
  199432. - u32 str_shift;
  199433. - char chn[8];
  199434. - u32 base = ci->c_inf[0].base;
  199435. - u32 i;
  199436. - u32 drivestrength_sel = 0;
  199437. - u32 cc_data_temp;
  199438. - u32 addr;
  199439. -
  199440. - if (!(ci->c_inf[0].caps & CC_CAP_PMU))
  199441. - return;
  199442. -
  199443. - switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
  199444. - case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
  199445. - str_tab = sdiod_drvstr_tab1_1v8;
  199446. - str_mask = 0x00003800;
  199447. - str_shift = 11;
  199448. - break;
  199449. - case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
  199450. - str_tab = sdiod_drvstr_tab6_1v8;
  199451. - str_mask = 0x00001800;
  199452. - str_shift = 11;
  199453. - break;
  199454. - case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
  199455. - /* note: 43143 does not support tristate */
  199456. - i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
  199457. - if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
  199458. - str_tab = sdiod_drvstr_tab2_3v3;
  199459. - str_mask = 0x00000007;
  199460. - str_shift = 0;
  199461. - } else
  199462. - brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
  199463. - brcmf_sdio_chip_name(ci->chip, chn, 8),
  199464. - drivestrength);
  199465. - break;
  199466. - case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
  199467. - str_tab = sdiod_drive_strength_tab5_1v8;
  199468. - str_mask = 0x00003800;
  199469. - str_shift = 11;
  199470. - break;
  199471. - default:
  199472. - brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
  199473. - brcmf_sdio_chip_name(ci->chip, chn, 8),
  199474. - ci->chiprev, ci->pmurev);
  199475. - break;
  199476. - }
  199477. -
  199478. - if (str_tab != NULL) {
  199479. - for (i = 0; str_tab[i].strength != 0; i++) {
  199480. - if (drivestrength >= str_tab[i].strength) {
  199481. - drivestrength_sel = str_tab[i].sel;
  199482. - break;
  199483. - }
  199484. - }
  199485. - addr = CORE_CC_REG(base, chipcontrol_addr);
  199486. - brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
  199487. - cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
  199488. - cc_data_temp &= ~str_mask;
  199489. - drivestrength_sel <<= str_shift;
  199490. - cc_data_temp |= drivestrength_sel;
  199491. - brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
  199492. -
  199493. - brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
  199494. - str_tab[i].strength, drivestrength, cc_data_temp);
  199495. - }
  199496. -}
  199497. -
  199498. -static void
  199499. -brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev,
  199500. - struct brcmf_chip *ci)
  199501. -{
  199502. - ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
  199503. - ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
  199504. - D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
  199505. - D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
  199506. - ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0, 0, 0);
  199507. -}
  199508. -
  199509. -static bool brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev,
  199510. - struct brcmf_chip *ci)
  199511. -{
  199512. - u8 core_idx;
  199513. - u32 reg_addr;
  199514. -
  199515. - if (!ci->iscoreup(sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) {
  199516. - brcmf_err("SOCRAM core is down after reset?\n");
  199517. - return false;
  199518. - }
  199519. -
  199520. - /* clear all interrupts */
  199521. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
  199522. - reg_addr = ci->c_inf[core_idx].base;
  199523. - reg_addr += offsetof(struct sdpcmd_regs, intstatus);
  199524. - brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
  199525. -
  199526. - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0, 0);
  199527. -
  199528. - return true;
  199529. -}
  199530. -
  199531. -static inline void
  199532. -brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev,
  199533. - struct brcmf_chip *ci)
  199534. -{
  199535. - u8 idx;
  199536. - u32 regdata;
  199537. - u32 wrapbase;
  199538. - idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
  199539. -
  199540. - if (idx == BRCMF_MAX_CORENUM)
  199541. - return;
  199542. -
  199543. - wrapbase = ci->c_inf[idx].wrapbase;
  199544. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  199545. - regdata &= ARMCR4_BCMA_IOCTL_CPUHALT;
  199546. - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, regdata,
  199547. - ARMCR4_BCMA_IOCTL_CPUHALT, ARMCR4_BCMA_IOCTL_CPUHALT);
  199548. - ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
  199549. - D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
  199550. - D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
  199551. -}
  199552. -
  199553. -static bool brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev,
  199554. - struct brcmf_chip *ci, u32 rstvec)
  199555. -{
  199556. - u8 core_idx;
  199557. - u32 reg_addr;
  199558. -
  199559. - /* clear all interrupts */
  199560. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
  199561. - reg_addr = ci->c_inf[core_idx].base;
  199562. - reg_addr += offsetof(struct sdpcmd_regs, intstatus);
  199563. - brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
  199564. -
  199565. - /* Write reset vector to address 0 */
  199566. - brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&rstvec,
  199567. - sizeof(rstvec));
  199568. -
  199569. - /* restore ARM */
  199570. - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, ARMCR4_BCMA_IOCTL_CPUHALT,
  199571. - 0, 0);
  199572. -
  199573. - return true;
  199574. -}
  199575. -
  199576. -void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
  199577. - struct brcmf_chip *ci)
  199578. -{
  199579. - u8 arm_core_idx;
  199580. -
  199581. - arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
  199582. - if (BRCMF_MAX_CORENUM != arm_core_idx) {
  199583. - brcmf_sdio_chip_cm3_enterdl(sdiodev, ci);
  199584. - return;
  199585. - }
  199586. -
  199587. - brcmf_sdio_chip_cr4_enterdl(sdiodev, ci);
  199588. -}
  199589. -
  199590. -bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
  199591. - struct brcmf_chip *ci, u32 rstvec)
  199592. -{
  199593. - u8 arm_core_idx;
  199594. -
  199595. - arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
  199596. - if (BRCMF_MAX_CORENUM != arm_core_idx)
  199597. - return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci);
  199598. -
  199599. - return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, rstvec);
  199600. -}
  199601. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
  199602. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h 2014-07-31 23:51:43.000000000 +0200
  199603. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h 1970-01-01 01:00:00.000000000 +0100
  199604. @@ -1,231 +0,0 @@
  199605. -/*
  199606. - * Copyright (c) 2011 Broadcom Corporation
  199607. - *
  199608. - * Permission to use, copy, modify, and/or distribute this software for any
  199609. - * purpose with or without fee is hereby granted, provided that the above
  199610. - * copyright notice and this permission notice appear in all copies.
  199611. - *
  199612. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  199613. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  199614. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  199615. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  199616. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  199617. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  199618. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  199619. - */
  199620. -
  199621. -#ifndef _BRCMFMAC_SDIO_CHIP_H_
  199622. -#define _BRCMFMAC_SDIO_CHIP_H_
  199623. -
  199624. -/*
  199625. - * Core reg address translation.
  199626. - * Both macro's returns a 32 bits byte address on the backplane bus.
  199627. - */
  199628. -#define CORE_CC_REG(base, field) \
  199629. - (base + offsetof(struct chipcregs, field))
  199630. -#define CORE_BUS_REG(base, field) \
  199631. - (base + offsetof(struct sdpcmd_regs, field))
  199632. -#define CORE_SB(base, field) \
  199633. - (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
  199634. -
  199635. -/* SDIO function 1 register CHIPCLKCSR */
  199636. -/* Force ALP request to backplane */
  199637. -#define SBSDIO_FORCE_ALP 0x01
  199638. -/* Force HT request to backplane */
  199639. -#define SBSDIO_FORCE_HT 0x02
  199640. -/* Force ILP request to backplane */
  199641. -#define SBSDIO_FORCE_ILP 0x04
  199642. -/* Make ALP ready (power up xtal) */
  199643. -#define SBSDIO_ALP_AVAIL_REQ 0x08
  199644. -/* Make HT ready (power up PLL) */
  199645. -#define SBSDIO_HT_AVAIL_REQ 0x10
  199646. -/* Squelch clock requests from HW */
  199647. -#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
  199648. -/* Status: ALP is ready */
  199649. -#define SBSDIO_ALP_AVAIL 0x40
  199650. -/* Status: HT is ready */
  199651. -#define SBSDIO_HT_AVAIL 0x80
  199652. -#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
  199653. -#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
  199654. -#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
  199655. -#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
  199656. -#define SBSDIO_CLKAV(regval, alponly) \
  199657. - (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
  199658. -
  199659. -#define BRCMF_MAX_CORENUM 6
  199660. -
  199661. -struct brcmf_core {
  199662. - u16 id;
  199663. - u16 rev;
  199664. - u32 base;
  199665. - u32 wrapbase;
  199666. - u32 caps;
  199667. - u32 cib;
  199668. -};
  199669. -
  199670. -struct brcmf_chip {
  199671. - u32 chip;
  199672. - u32 chiprev;
  199673. - /* core info */
  199674. - /* always put chipcommon core at 0, bus core at 1 */
  199675. - struct brcmf_core c_inf[BRCMF_MAX_CORENUM];
  199676. - u32 pmurev;
  199677. - u32 pmucaps;
  199678. - u32 ramsize;
  199679. - u32 rambase;
  199680. - u32 rst_vec; /* reset vertor for ARM CR4 core */
  199681. -
  199682. - bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
  199683. - u16 coreid);
  199684. - u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
  199685. - u16 coreid);
  199686. - void (*coredisable)(struct brcmf_sdio_dev *sdiodev,
  199687. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  199688. - u32 in_resetbits);
  199689. - void (*resetcore)(struct brcmf_sdio_dev *sdiodev,
  199690. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  199691. - u32 in_resetbits, u32 post_resetbits);
  199692. -};
  199693. -
  199694. -struct sbconfig {
  199695. - u32 PAD[2];
  199696. - u32 sbipsflag; /* initiator port ocp slave flag */
  199697. - u32 PAD[3];
  199698. - u32 sbtpsflag; /* target port ocp slave flag */
  199699. - u32 PAD[11];
  199700. - u32 sbtmerrloga; /* (sonics >= 2.3) */
  199701. - u32 PAD;
  199702. - u32 sbtmerrlog; /* (sonics >= 2.3) */
  199703. - u32 PAD[3];
  199704. - u32 sbadmatch3; /* address match3 */
  199705. - u32 PAD;
  199706. - u32 sbadmatch2; /* address match2 */
  199707. - u32 PAD;
  199708. - u32 sbadmatch1; /* address match1 */
  199709. - u32 PAD[7];
  199710. - u32 sbimstate; /* initiator agent state */
  199711. - u32 sbintvec; /* interrupt mask */
  199712. - u32 sbtmstatelow; /* target state */
  199713. - u32 sbtmstatehigh; /* target state */
  199714. - u32 sbbwa0; /* bandwidth allocation table0 */
  199715. - u32 PAD;
  199716. - u32 sbimconfiglow; /* initiator configuration */
  199717. - u32 sbimconfighigh; /* initiator configuration */
  199718. - u32 sbadmatch0; /* address match0 */
  199719. - u32 PAD;
  199720. - u32 sbtmconfiglow; /* target configuration */
  199721. - u32 sbtmconfighigh; /* target configuration */
  199722. - u32 sbbconfig; /* broadcast configuration */
  199723. - u32 PAD;
  199724. - u32 sbbstate; /* broadcast state */
  199725. - u32 PAD[3];
  199726. - u32 sbactcnfg; /* activate configuration */
  199727. - u32 PAD[3];
  199728. - u32 sbflagst; /* current sbflags */
  199729. - u32 PAD[3];
  199730. - u32 sbidlow; /* identification */
  199731. - u32 sbidhigh; /* identification */
  199732. -};
  199733. -
  199734. -/* sdio core registers */
  199735. -struct sdpcmd_regs {
  199736. - u32 corecontrol; /* 0x00, rev8 */
  199737. - u32 corestatus; /* rev8 */
  199738. - u32 PAD[1];
  199739. - u32 biststatus; /* rev8 */
  199740. -
  199741. - /* PCMCIA access */
  199742. - u16 pcmciamesportaladdr; /* 0x010, rev8 */
  199743. - u16 PAD[1];
  199744. - u16 pcmciamesportalmask; /* rev8 */
  199745. - u16 PAD[1];
  199746. - u16 pcmciawrframebc; /* rev8 */
  199747. - u16 PAD[1];
  199748. - u16 pcmciaunderflowtimer; /* rev8 */
  199749. - u16 PAD[1];
  199750. -
  199751. - /* interrupt */
  199752. - u32 intstatus; /* 0x020, rev8 */
  199753. - u32 hostintmask; /* rev8 */
  199754. - u32 intmask; /* rev8 */
  199755. - u32 sbintstatus; /* rev8 */
  199756. - u32 sbintmask; /* rev8 */
  199757. - u32 funcintmask; /* rev4 */
  199758. - u32 PAD[2];
  199759. - u32 tosbmailbox; /* 0x040, rev8 */
  199760. - u32 tohostmailbox; /* rev8 */
  199761. - u32 tosbmailboxdata; /* rev8 */
  199762. - u32 tohostmailboxdata; /* rev8 */
  199763. -
  199764. - /* synchronized access to registers in SDIO clock domain */
  199765. - u32 sdioaccess; /* 0x050, rev8 */
  199766. - u32 PAD[3];
  199767. -
  199768. - /* PCMCIA frame control */
  199769. - u8 pcmciaframectrl; /* 0x060, rev8 */
  199770. - u8 PAD[3];
  199771. - u8 pcmciawatermark; /* rev8 */
  199772. - u8 PAD[155];
  199773. -
  199774. - /* interrupt batching control */
  199775. - u32 intrcvlazy; /* 0x100, rev8 */
  199776. - u32 PAD[3];
  199777. -
  199778. - /* counters */
  199779. - u32 cmd52rd; /* 0x110, rev8 */
  199780. - u32 cmd52wr; /* rev8 */
  199781. - u32 cmd53rd; /* rev8 */
  199782. - u32 cmd53wr; /* rev8 */
  199783. - u32 abort; /* rev8 */
  199784. - u32 datacrcerror; /* rev8 */
  199785. - u32 rdoutofsync; /* rev8 */
  199786. - u32 wroutofsync; /* rev8 */
  199787. - u32 writebusy; /* rev8 */
  199788. - u32 readwait; /* rev8 */
  199789. - u32 readterm; /* rev8 */
  199790. - u32 writeterm; /* rev8 */
  199791. - u32 PAD[40];
  199792. - u32 clockctlstatus; /* rev8 */
  199793. - u32 PAD[7];
  199794. -
  199795. - u32 PAD[128]; /* DMA engines */
  199796. -
  199797. - /* SDIO/PCMCIA CIS region */
  199798. - char cis[512]; /* 0x400-0x5ff, rev6 */
  199799. -
  199800. - /* PCMCIA function control registers */
  199801. - char pcmciafcr[256]; /* 0x600-6ff, rev6 */
  199802. - u16 PAD[55];
  199803. -
  199804. - /* PCMCIA backplane access */
  199805. - u16 backplanecsr; /* 0x76E, rev6 */
  199806. - u16 backplaneaddr0; /* rev6 */
  199807. - u16 backplaneaddr1; /* rev6 */
  199808. - u16 backplaneaddr2; /* rev6 */
  199809. - u16 backplaneaddr3; /* rev6 */
  199810. - u16 backplanedata0; /* rev6 */
  199811. - u16 backplanedata1; /* rev6 */
  199812. - u16 backplanedata2; /* rev6 */
  199813. - u16 backplanedata3; /* rev6 */
  199814. - u16 PAD[31];
  199815. -
  199816. - /* sprom "size" & "blank" info */
  199817. - u16 spromstatus; /* 0x7BE, rev2 */
  199818. - u32 PAD[464];
  199819. -
  199820. - u16 PAD[0x80];
  199821. -};
  199822. -
  199823. -int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
  199824. - struct brcmf_chip **ci_ptr);
  199825. -void brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr);
  199826. -void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
  199827. - struct brcmf_chip *ci,
  199828. - u32 drivestrength);
  199829. -u8 brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid);
  199830. -void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
  199831. - struct brcmf_chip *ci);
  199832. -bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
  199833. - struct brcmf_chip *ci, u32 rstvec);
  199834. -
  199835. -#endif /* _BRCMFMAC_SDIO_CHIP_H_ */
  199836. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
  199837. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h 2014-07-31 23:51:43.000000000 +0200
  199838. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h 2014-08-20 19:31:46.892872284 +0200
  199839. @@ -180,6 +180,97 @@
  199840. uint max_request_size;
  199841. ushort max_segment_count;
  199842. uint max_segment_size;
  199843. + uint txglomsz;
  199844. + struct sg_table sgtable;
  199845. +};
  199846. +
  199847. +/* sdio core registers */
  199848. +struct sdpcmd_regs {
  199849. + u32 corecontrol; /* 0x00, rev8 */
  199850. + u32 corestatus; /* rev8 */
  199851. + u32 PAD[1];
  199852. + u32 biststatus; /* rev8 */
  199853. +
  199854. + /* PCMCIA access */
  199855. + u16 pcmciamesportaladdr; /* 0x010, rev8 */
  199856. + u16 PAD[1];
  199857. + u16 pcmciamesportalmask; /* rev8 */
  199858. + u16 PAD[1];
  199859. + u16 pcmciawrframebc; /* rev8 */
  199860. + u16 PAD[1];
  199861. + u16 pcmciaunderflowtimer; /* rev8 */
  199862. + u16 PAD[1];
  199863. +
  199864. + /* interrupt */
  199865. + u32 intstatus; /* 0x020, rev8 */
  199866. + u32 hostintmask; /* rev8 */
  199867. + u32 intmask; /* rev8 */
  199868. + u32 sbintstatus; /* rev8 */
  199869. + u32 sbintmask; /* rev8 */
  199870. + u32 funcintmask; /* rev4 */
  199871. + u32 PAD[2];
  199872. + u32 tosbmailbox; /* 0x040, rev8 */
  199873. + u32 tohostmailbox; /* rev8 */
  199874. + u32 tosbmailboxdata; /* rev8 */
  199875. + u32 tohostmailboxdata; /* rev8 */
  199876. +
  199877. + /* synchronized access to registers in SDIO clock domain */
  199878. + u32 sdioaccess; /* 0x050, rev8 */
  199879. + u32 PAD[3];
  199880. +
  199881. + /* PCMCIA frame control */
  199882. + u8 pcmciaframectrl; /* 0x060, rev8 */
  199883. + u8 PAD[3];
  199884. + u8 pcmciawatermark; /* rev8 */
  199885. + u8 PAD[155];
  199886. +
  199887. + /* interrupt batching control */
  199888. + u32 intrcvlazy; /* 0x100, rev8 */
  199889. + u32 PAD[3];
  199890. +
  199891. + /* counters */
  199892. + u32 cmd52rd; /* 0x110, rev8 */
  199893. + u32 cmd52wr; /* rev8 */
  199894. + u32 cmd53rd; /* rev8 */
  199895. + u32 cmd53wr; /* rev8 */
  199896. + u32 abort; /* rev8 */
  199897. + u32 datacrcerror; /* rev8 */
  199898. + u32 rdoutofsync; /* rev8 */
  199899. + u32 wroutofsync; /* rev8 */
  199900. + u32 writebusy; /* rev8 */
  199901. + u32 readwait; /* rev8 */
  199902. + u32 readterm; /* rev8 */
  199903. + u32 writeterm; /* rev8 */
  199904. + u32 PAD[40];
  199905. + u32 clockctlstatus; /* rev8 */
  199906. + u32 PAD[7];
  199907. +
  199908. + u32 PAD[128]; /* DMA engines */
  199909. +
  199910. + /* SDIO/PCMCIA CIS region */
  199911. + char cis[512]; /* 0x400-0x5ff, rev6 */
  199912. +
  199913. + /* PCMCIA function control registers */
  199914. + char pcmciafcr[256]; /* 0x600-6ff, rev6 */
  199915. + u16 PAD[55];
  199916. +
  199917. + /* PCMCIA backplane access */
  199918. + u16 backplanecsr; /* 0x76E, rev6 */
  199919. + u16 backplaneaddr0; /* rev6 */
  199920. + u16 backplaneaddr1; /* rev6 */
  199921. + u16 backplaneaddr2; /* rev6 */
  199922. + u16 backplaneaddr3; /* rev6 */
  199923. + u16 backplanedata0; /* rev6 */
  199924. + u16 backplanedata1; /* rev6 */
  199925. + u16 backplanedata2; /* rev6 */
  199926. + u16 backplanedata3; /* rev6 */
  199927. + u16 PAD[31];
  199928. +
  199929. + /* sprom "size" & "blank" info */
  199930. + u16 spromstatus; /* 0x7BE, rev2 */
  199931. + u32 PAD[464];
  199932. +
  199933. + u16 PAD[0x80];
  199934. };
  199935. /* Register/deregister interrupt handler. */
  199936. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/usb.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/usb.c
  199937. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/usb.c 2014-07-31 23:51:43.000000000 +0200
  199938. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/usb.c 2014-08-20 19:31:46.896872302 +0200
  199939. @@ -25,6 +25,7 @@
  199940. #include <dhd_bus.h>
  199941. #include <dhd_dbg.h>
  199942. +#include "firmware.h"
  199943. #include "usb_rdl.h"
  199944. #include "usb.h"
  199945. @@ -61,12 +62,6 @@
  199946. u8 *image;
  199947. int image_len;
  199948. };
  199949. -static struct list_head fw_image_list;
  199950. -
  199951. -struct intr_transfer_buf {
  199952. - u32 notification;
  199953. - u32 reserved;
  199954. -};
  199955. struct brcmf_usbdev_info {
  199956. struct brcmf_usbdev bus_pub; /* MUST BE FIRST */
  199957. @@ -75,7 +70,7 @@
  199958. struct list_head rx_postq;
  199959. struct list_head tx_freeq;
  199960. struct list_head tx_postq;
  199961. - uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
  199962. + uint rx_pipe, tx_pipe, rx_pipe2;
  199963. int rx_low_watermark;
  199964. int tx_low_watermark;
  199965. @@ -87,7 +82,7 @@
  199966. struct brcmf_usbreq *tx_reqs;
  199967. struct brcmf_usbreq *rx_reqs;
  199968. - u8 *image; /* buffer for combine fw and nvram */
  199969. + const u8 *image; /* buffer for combine fw and nvram */
  199970. int image_len;
  199971. struct usb_device *usbdev;
  199972. @@ -104,10 +99,6 @@
  199973. ulong ctl_op;
  199974. struct urb *bulk_urb; /* used for FW download */
  199975. - struct urb *intr_urb; /* URB for interrupt endpoint */
  199976. - int intr_size; /* Size of interrupt message */
  199977. - int interval; /* Interrupt polling interval */
  199978. - struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */
  199979. };
  199980. static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
  199981. @@ -531,39 +522,6 @@
  199982. }
  199983. }
  199984. -static void
  199985. -brcmf_usb_intr_complete(struct urb *urb)
  199986. -{
  199987. - struct brcmf_usbdev_info *devinfo =
  199988. - (struct brcmf_usbdev_info *)urb->context;
  199989. - int err;
  199990. -
  199991. - brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status);
  199992. -
  199993. - if (devinfo == NULL)
  199994. - return;
  199995. -
  199996. - if (unlikely(urb->status)) {
  199997. - if (urb->status == -ENOENT ||
  199998. - urb->status == -ESHUTDOWN ||
  199999. - urb->status == -ENODEV) {
  200000. - brcmf_usb_state_change(devinfo,
  200001. - BRCMFMAC_USB_STATE_DOWN);
  200002. - }
  200003. - }
  200004. -
  200005. - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) {
  200006. - brcmf_err("intr cb when DBUS down, ignoring\n");
  200007. - return;
  200008. - }
  200009. -
  200010. - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) {
  200011. - err = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
  200012. - if (err)
  200013. - brcmf_err("usb_submit_urb, err=%d\n", err);
  200014. - }
  200015. -}
  200016. -
  200017. static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
  200018. {
  200019. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
  200020. @@ -619,7 +577,6 @@
  200021. {
  200022. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
  200023. u16 ifnum;
  200024. - int ret;
  200025. brcmf_dbg(USB, "Enter\n");
  200026. if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP)
  200027. @@ -628,23 +585,6 @@
  200028. /* Success, indicate devinfo is fully up */
  200029. brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_UP);
  200030. - if (devinfo->intr_urb) {
  200031. - usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev,
  200032. - devinfo->intr_pipe,
  200033. - &devinfo->intr,
  200034. - devinfo->intr_size,
  200035. - (usb_complete_t)brcmf_usb_intr_complete,
  200036. - devinfo,
  200037. - devinfo->interval);
  200038. -
  200039. - ret = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
  200040. - if (ret) {
  200041. - brcmf_err("USB_SUBMIT_URB failed with status %d\n",
  200042. - ret);
  200043. - return -EINVAL;
  200044. - }
  200045. - }
  200046. -
  200047. if (devinfo->ctl_urb) {
  200048. devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);
  200049. devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0);
  200050. @@ -681,8 +621,6 @@
  200051. return;
  200052. brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN);
  200053. - if (devinfo->intr_urb)
  200054. - usb_kill_urb(devinfo->intr_urb);
  200055. if (devinfo->ctl_urb)
  200056. usb_kill_urb(devinfo->ctl_urb);
  200057. @@ -1021,7 +959,7 @@
  200058. }
  200059. err = brcmf_usb_dlstart(devinfo,
  200060. - devinfo->image, devinfo->image_len);
  200061. + (u8 *)devinfo->image, devinfo->image_len);
  200062. if (err == 0)
  200063. err = brcmf_usb_dlrun(devinfo);
  200064. return err;
  200065. @@ -1036,7 +974,6 @@
  200066. brcmf_usb_free_q(&devinfo->rx_freeq, false);
  200067. brcmf_usb_free_q(&devinfo->tx_freeq, false);
  200068. - usb_free_urb(devinfo->intr_urb);
  200069. usb_free_urb(devinfo->ctl_urb);
  200070. usb_free_urb(devinfo->bulk_urb);
  200071. @@ -1080,68 +1017,20 @@
  200072. return -1;
  200073. }
  200074. -static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
  200075. +static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo)
  200076. {
  200077. - s8 *fwname;
  200078. - const struct firmware *fw;
  200079. - struct brcmf_usb_image *fw_image;
  200080. - int err;
  200081. -
  200082. - brcmf_dbg(USB, "Enter\n");
  200083. switch (devinfo->bus_pub.devid) {
  200084. case 43143:
  200085. - fwname = BRCMF_USB_43143_FW_NAME;
  200086. - break;
  200087. + return BRCMF_USB_43143_FW_NAME;
  200088. case 43235:
  200089. case 43236:
  200090. case 43238:
  200091. - fwname = BRCMF_USB_43236_FW_NAME;
  200092. - break;
  200093. + return BRCMF_USB_43236_FW_NAME;
  200094. case 43242:
  200095. - fwname = BRCMF_USB_43242_FW_NAME;
  200096. - break;
  200097. + return BRCMF_USB_43242_FW_NAME;
  200098. default:
  200099. - return -EINVAL;
  200100. - break;
  200101. - }
  200102. - brcmf_dbg(USB, "Loading FW %s\n", fwname);
  200103. - list_for_each_entry(fw_image, &fw_image_list, list) {
  200104. - if (fw_image->fwname == fwname) {
  200105. - devinfo->image = fw_image->image;
  200106. - devinfo->image_len = fw_image->image_len;
  200107. - return 0;
  200108. - }
  200109. - }
  200110. - /* fw image not yet loaded. Load it now and add to list */
  200111. - err = request_firmware(&fw, fwname, devinfo->dev);
  200112. - if (!fw) {
  200113. - brcmf_err("fail to request firmware %s\n", fwname);
  200114. - return err;
  200115. - }
  200116. - if (check_file(fw->data) < 0) {
  200117. - brcmf_err("invalid firmware %s\n", fwname);
  200118. - return -EINVAL;
  200119. + return NULL;
  200120. }
  200121. -
  200122. - fw_image = kzalloc(sizeof(*fw_image), GFP_ATOMIC);
  200123. - if (!fw_image)
  200124. - return -ENOMEM;
  200125. - INIT_LIST_HEAD(&fw_image->list);
  200126. - list_add_tail(&fw_image->list, &fw_image_list);
  200127. - fw_image->fwname = fwname;
  200128. - fw_image->image = vmalloc(fw->size);
  200129. - if (!fw_image->image)
  200130. - return -ENOMEM;
  200131. -
  200132. - memcpy(fw_image->image, fw->data, fw->size);
  200133. - fw_image->image_len = fw->size;
  200134. -
  200135. - release_firmware(fw);
  200136. -
  200137. - devinfo->image = fw_image->image;
  200138. - devinfo->image_len = fw_image->image_len;
  200139. -
  200140. - return 0;
  200141. }
  200142. @@ -1186,11 +1075,6 @@
  200143. goto error;
  200144. devinfo->tx_freecount = ntxq;
  200145. - devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);
  200146. - if (!devinfo->intr_urb) {
  200147. - brcmf_err("usb_alloc_urb (intr) failed\n");
  200148. - goto error;
  200149. - }
  200150. devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);
  200151. if (!devinfo->ctl_urb) {
  200152. brcmf_err("usb_alloc_urb (ctl) failed\n");
  200153. @@ -1202,16 +1086,6 @@
  200154. goto error;
  200155. }
  200156. - if (!brcmf_usb_dlneeded(devinfo))
  200157. - return &devinfo->bus_pub;
  200158. -
  200159. - brcmf_dbg(USB, "Start fw downloading\n");
  200160. - if (brcmf_usb_get_fw(devinfo))
  200161. - goto error;
  200162. -
  200163. - if (brcmf_usb_fw_download(devinfo))
  200164. - goto error;
  200165. -
  200166. return &devinfo->bus_pub;
  200167. error:
  200168. @@ -1222,18 +1096,77 @@
  200169. static struct brcmf_bus_ops brcmf_usb_bus_ops = {
  200170. .txdata = brcmf_usb_tx,
  200171. - .init = brcmf_usb_up,
  200172. .stop = brcmf_usb_down,
  200173. .txctl = brcmf_usb_tx_ctlpkt,
  200174. .rxctl = brcmf_usb_rx_ctlpkt,
  200175. };
  200176. +static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
  200177. +{
  200178. + int ret;
  200179. +
  200180. + /* Attach to the common driver interface */
  200181. + ret = brcmf_attach(devinfo->dev);
  200182. + if (ret) {
  200183. + brcmf_err("brcmf_attach failed\n");
  200184. + return ret;
  200185. + }
  200186. +
  200187. + ret = brcmf_usb_up(devinfo->dev);
  200188. + if (ret)
  200189. + goto fail;
  200190. +
  200191. + ret = brcmf_bus_start(devinfo->dev);
  200192. + if (ret)
  200193. + goto fail;
  200194. +
  200195. + return 0;
  200196. +fail:
  200197. + brcmf_detach(devinfo->dev);
  200198. + return ret;
  200199. +}
  200200. +
  200201. +static void brcmf_usb_probe_phase2(struct device *dev,
  200202. + const struct firmware *fw,
  200203. + void *nvram, u32 nvlen)
  200204. +{
  200205. + struct brcmf_bus *bus = dev_get_drvdata(dev);
  200206. + struct brcmf_usbdev_info *devinfo;
  200207. + int ret;
  200208. +
  200209. + brcmf_dbg(USB, "Start fw downloading\n");
  200210. + ret = check_file(fw->data);
  200211. + if (ret < 0) {
  200212. + brcmf_err("invalid firmware\n");
  200213. + release_firmware(fw);
  200214. + goto error;
  200215. + }
  200216. +
  200217. + devinfo = bus->bus_priv.usb->devinfo;
  200218. + devinfo->image = fw->data;
  200219. + devinfo->image_len = fw->size;
  200220. +
  200221. + ret = brcmf_usb_fw_download(devinfo);
  200222. + release_firmware(fw);
  200223. + if (ret)
  200224. + goto error;
  200225. +
  200226. + ret = brcmf_usb_bus_setup(devinfo);
  200227. + if (ret)
  200228. + goto error;
  200229. +
  200230. + return;
  200231. +error:
  200232. + brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret);
  200233. + device_release_driver(dev);
  200234. +}
  200235. +
  200236. static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
  200237. {
  200238. struct brcmf_bus *bus = NULL;
  200239. struct brcmf_usbdev *bus_pub = NULL;
  200240. - int ret;
  200241. struct device *dev = devinfo->dev;
  200242. + int ret;
  200243. brcmf_dbg(USB, "Enter\n");
  200244. bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);
  200245. @@ -1254,22 +1187,18 @@
  200246. bus->chip = bus_pub->devid;
  200247. bus->chiprev = bus_pub->chiprev;
  200248. bus->proto_type = BRCMF_PROTO_BCDC;
  200249. + bus->always_use_fws_queue = true;
  200250. - /* Attach to the common driver interface */
  200251. - ret = brcmf_attach(dev);
  200252. - if (ret) {
  200253. - brcmf_err("brcmf_attach failed\n");
  200254. - goto fail;
  200255. - }
  200256. -
  200257. - ret = brcmf_bus_start(dev);
  200258. - if (ret) {
  200259. - brcmf_err("dongle is not responding\n");
  200260. - brcmf_detach(dev);
  200261. - goto fail;
  200262. + if (!brcmf_usb_dlneeded(devinfo)) {
  200263. + ret = brcmf_usb_bus_setup(devinfo);
  200264. + if (ret)
  200265. + goto fail;
  200266. }
  200267. -
  200268. + /* request firmware here */
  200269. + brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,
  200270. + brcmf_usb_probe_phase2);
  200271. return 0;
  200272. +
  200273. fail:
  200274. /* Release resources in reverse order */
  200275. kfree(bus);
  200276. @@ -1357,9 +1286,6 @@
  200277. goto fail;
  200278. }
  200279. - endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
  200280. - devinfo->intr_pipe = usb_rcvintpipe(usb, endpoint_num);
  200281. -
  200282. devinfo->rx_pipe = 0;
  200283. devinfo->rx_pipe2 = 0;
  200284. devinfo->tx_pipe = 0;
  200285. @@ -1391,16 +1317,9 @@
  200286. }
  200287. }
  200288. - /* Allocate interrupt URB and data buffer */
  200289. - /* RNDIS says 8-byte intr, our old drivers used 4-byte */
  200290. - if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))
  200291. - devinfo->intr_size = 8;
  200292. - else
  200293. - devinfo->intr_size = 4;
  200294. -
  200295. - devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
  200296. -
  200297. - if (usb->speed == USB_SPEED_HIGH)
  200298. + if (usb->speed == USB_SPEED_SUPER)
  200299. + brcmf_dbg(USB, "Broadcom super speed USB wireless device detected\n");
  200300. + else if (usb->speed == USB_SPEED_HIGH)
  200301. brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n");
  200302. else
  200303. brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n");
  200304. @@ -1455,23 +1374,18 @@
  200305. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
  200306. brcmf_dbg(USB, "Enter\n");
  200307. - if (!brcmf_attach(devinfo->dev))
  200308. - return brcmf_bus_start(&usb->dev);
  200309. -
  200310. - return 0;
  200311. + return brcmf_usb_bus_setup(devinfo);
  200312. }
  200313. static int brcmf_usb_reset_resume(struct usb_interface *intf)
  200314. {
  200315. struct usb_device *usb = interface_to_usbdev(intf);
  200316. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
  200317. -
  200318. brcmf_dbg(USB, "Enter\n");
  200319. - if (!brcmf_usb_fw_download(devinfo))
  200320. - return brcmf_usb_resume(intf);
  200321. -
  200322. - return -EIO;
  200323. + return brcmf_fw_get_firmwares(&usb->dev, 0,
  200324. + brcmf_usb_get_fwname(devinfo), NULL,
  200325. + brcmf_usb_probe_phase2);
  200326. }
  200327. #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c
  200328. @@ -1506,16 +1420,6 @@
  200329. .disable_hub_initiated_lpm = 1,
  200330. };
  200331. -static void brcmf_release_fw(struct list_head *q)
  200332. -{
  200333. - struct brcmf_usb_image *fw_image, *next;
  200334. -
  200335. - list_for_each_entry_safe(fw_image, next, q, list) {
  200336. - vfree(fw_image->image);
  200337. - list_del_init(&fw_image->list);
  200338. - }
  200339. -}
  200340. -
  200341. static int brcmf_usb_reset_device(struct device *dev, void *notused)
  200342. {
  200343. /* device past is the usb interface so we
  200344. @@ -1534,12 +1438,10 @@
  200345. ret = driver_for_each_device(drv, NULL, NULL,
  200346. brcmf_usb_reset_device);
  200347. usb_deregister(&brcmf_usbdrvr);
  200348. - brcmf_release_fw(&fw_image_list);
  200349. }
  200350. void brcmf_usb_register(void)
  200351. {
  200352. brcmf_dbg(USB, "Enter\n");
  200353. - INIT_LIST_HEAD(&fw_image_list);
  200354. usb_register(&brcmf_usbdrvr);
  200355. }
  200356. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
  200357. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c 2014-07-31 23:51:43.000000000 +0200
  200358. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c 2014-08-20 19:31:46.896872302 +0200
  200359. @@ -18,6 +18,7 @@
  200360. #include <linux/kernel.h>
  200361. #include <linux/etherdevice.h>
  200362. +#include <linux/module.h>
  200363. #include <net/cfg80211.h>
  200364. #include <net/netlink.h>
  200365. @@ -190,6 +191,7 @@
  200366. .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
  200367. .bitrates = wl_g_rates,
  200368. .n_bitrates = wl_g_rates_size,
  200369. + .ht_cap = {IEEE80211_HT_CAP_SUP_WIDTH_20_40, true},
  200370. };
  200371. static struct ieee80211_supported_band __wl_band_5ghz_a = {
  200372. @@ -219,9 +221,9 @@
  200373. */
  200374. REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
  200375. /* IEEE 802.11a, channel 36..64 */
  200376. - REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
  200377. + REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
  200378. /* IEEE 802.11a, channel 100..165 */
  200379. - REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), }
  200380. + REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
  200381. };
  200382. static const u32 __wl_cipher_suites[] = {
  200383. @@ -251,6 +253,10 @@
  200384. struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
  200385. };
  200386. +static int brcmf_roamoff;
  200387. +module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
  200388. +MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
  200389. +
  200390. /* Quarter dBm units to mW
  200391. * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
  200392. * Table is offset so the last entry is largest mW value that fits in
  200393. @@ -335,6 +341,60 @@
  200394. return qdbm;
  200395. }
  200396. +static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
  200397. + struct cfg80211_chan_def *ch)
  200398. +{
  200399. + struct brcmu_chan ch_inf;
  200400. + s32 primary_offset;
  200401. +
  200402. + brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
  200403. + ch->chan->center_freq, ch->center_freq1, ch->width);
  200404. + ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
  200405. + primary_offset = ch->center_freq1 - ch->chan->center_freq;
  200406. + switch (ch->width) {
  200407. + case NL80211_CHAN_WIDTH_20:
  200408. + ch_inf.bw = BRCMU_CHAN_BW_20;
  200409. + WARN_ON(primary_offset != 0);
  200410. + break;
  200411. + case NL80211_CHAN_WIDTH_40:
  200412. + ch_inf.bw = BRCMU_CHAN_BW_40;
  200413. + if (primary_offset < 0)
  200414. + ch_inf.sb = BRCMU_CHAN_SB_U;
  200415. + else
  200416. + ch_inf.sb = BRCMU_CHAN_SB_L;
  200417. + break;
  200418. + case NL80211_CHAN_WIDTH_80:
  200419. + ch_inf.bw = BRCMU_CHAN_BW_80;
  200420. + if (primary_offset < 0) {
  200421. + if (primary_offset < -CH_10MHZ_APART)
  200422. + ch_inf.sb = BRCMU_CHAN_SB_UU;
  200423. + else
  200424. + ch_inf.sb = BRCMU_CHAN_SB_UL;
  200425. + } else {
  200426. + if (primary_offset > CH_10MHZ_APART)
  200427. + ch_inf.sb = BRCMU_CHAN_SB_LL;
  200428. + else
  200429. + ch_inf.sb = BRCMU_CHAN_SB_LU;
  200430. + }
  200431. + break;
  200432. + default:
  200433. + WARN_ON_ONCE(1);
  200434. + }
  200435. + switch (ch->chan->band) {
  200436. + case IEEE80211_BAND_2GHZ:
  200437. + ch_inf.band = BRCMU_CHAN_BAND_2G;
  200438. + break;
  200439. + case IEEE80211_BAND_5GHZ:
  200440. + ch_inf.band = BRCMU_CHAN_BAND_5G;
  200441. + break;
  200442. + default:
  200443. + WARN_ON_ONCE(1);
  200444. + }
  200445. + d11inf->encchspec(&ch_inf);
  200446. +
  200447. + return ch_inf.chspec;
  200448. +}
  200449. +
  200450. u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
  200451. struct ieee80211_channel *ch)
  200452. {
  200453. @@ -351,13 +411,11 @@
  200454. * triples, returning a pointer to the substring whose first element
  200455. * matches tag
  200456. */
  200457. -struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
  200458. +const struct brcmf_tlv *
  200459. +brcmf_parse_tlvs(const void *buf, int buflen, uint key)
  200460. {
  200461. - struct brcmf_tlv *elt;
  200462. - int totlen;
  200463. -
  200464. - elt = (struct brcmf_tlv *)buf;
  200465. - totlen = buflen;
  200466. + const struct brcmf_tlv *elt = buf;
  200467. + int totlen = buflen;
  200468. /* find tagged parameter */
  200469. while (totlen >= TLV_HDR_LEN) {
  200470. @@ -378,8 +436,8 @@
  200471. * not update the tlvs buffer pointer/length.
  200472. */
  200473. static bool
  200474. -brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
  200475. - u8 *oui, u32 oui_len, u8 type)
  200476. +brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
  200477. + const u8 *oui, u32 oui_len, u8 type)
  200478. {
  200479. /* If the contents match the OUI and the type */
  200480. if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
  200481. @@ -401,12 +459,12 @@
  200482. }
  200483. static struct brcmf_vs_tlv *
  200484. -brcmf_find_wpaie(u8 *parse, u32 len)
  200485. +brcmf_find_wpaie(const u8 *parse, u32 len)
  200486. {
  200487. - struct brcmf_tlv *ie;
  200488. + const struct brcmf_tlv *ie;
  200489. while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
  200490. - if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
  200491. + if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
  200492. WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
  200493. return (struct brcmf_vs_tlv *)ie;
  200494. }
  200495. @@ -414,9 +472,9 @@
  200496. }
  200497. static struct brcmf_vs_tlv *
  200498. -brcmf_find_wpsie(u8 *parse, u32 len)
  200499. +brcmf_find_wpsie(const u8 *parse, u32 len)
  200500. {
  200501. - struct brcmf_tlv *ie;
  200502. + const struct brcmf_tlv *ie;
  200503. while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
  200504. if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
  200505. @@ -491,6 +549,19 @@
  200506. return err;
  200507. }
  200508. +static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
  200509. +{
  200510. + enum nl80211_iftype iftype;
  200511. +
  200512. + iftype = vif->wdev.iftype;
  200513. + return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
  200514. +}
  200515. +
  200516. +static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
  200517. +{
  200518. + return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
  200519. +}
  200520. +
  200521. static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
  200522. const char *name,
  200523. enum nl80211_iftype type,
  200524. @@ -569,6 +640,9 @@
  200525. if (err)
  200526. brcmf_err("Scan abort failed\n");
  200527. }
  200528. +
  200529. + brcmf_set_mpc(ifp, 1);
  200530. +
  200531. /*
  200532. * e-scan can be initiated by scheduled scan
  200533. * which takes precedence.
  200534. @@ -578,12 +652,10 @@
  200535. cfg->sched_escan = false;
  200536. if (!aborted)
  200537. cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
  200538. - brcmf_set_mpc(ifp, 1);
  200539. } else if (scan_request) {
  200540. brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
  200541. aborted ? "Aborted" : "Done");
  200542. cfg80211_scan_done(scan_request, aborted);
  200543. - brcmf_set_mpc(ifp, 1);
  200544. }
  200545. if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
  200546. brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
  200547. @@ -651,7 +723,6 @@
  200548. type);
  200549. return -EOPNOTSUPP;
  200550. case NL80211_IFTYPE_ADHOC:
  200551. - vif->mode = WL_MODE_IBSS;
  200552. infra = 0;
  200553. break;
  200554. case NL80211_IFTYPE_STATION:
  200555. @@ -667,12 +738,10 @@
  200556. */
  200557. return 0;
  200558. }
  200559. - vif->mode = WL_MODE_BSS;
  200560. infra = 1;
  200561. break;
  200562. case NL80211_IFTYPE_AP:
  200563. case NL80211_IFTYPE_P2P_GO:
  200564. - vif->mode = WL_MODE_AP;
  200565. ap = 1;
  200566. break;
  200567. default:
  200568. @@ -696,7 +765,7 @@
  200569. err = -EAGAIN;
  200570. goto done;
  200571. }
  200572. - brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
  200573. + brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
  200574. "Adhoc" : "Infra");
  200575. }
  200576. ndev->ieee80211_ptr->iftype = type;
  200577. @@ -1222,8 +1291,8 @@
  200578. params->chandef.chan->center_freq);
  200579. if (params->channel_fixed) {
  200580. /* adding chanspec */
  200581. - chanspec = channel_to_chanspec(&cfg->d11inf,
  200582. - params->chandef.chan);
  200583. + chanspec = chandef_to_chanspec(&cfg->d11inf,
  200584. + &params->chandef);
  200585. join_params.params_le.chanspec_list[0] =
  200586. cpu_to_le16(chanspec);
  200587. join_params.params_le.chanspec_num = cpu_to_le32(1);
  200588. @@ -1340,13 +1409,14 @@
  200589. }
  200590. static s32
  200591. -brcmf_set_set_cipher(struct net_device *ndev,
  200592. - struct cfg80211_connect_params *sme)
  200593. +brcmf_set_wsec_mode(struct net_device *ndev,
  200594. + struct cfg80211_connect_params *sme, bool mfp)
  200595. {
  200596. struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
  200597. struct brcmf_cfg80211_security *sec;
  200598. s32 pval = 0;
  200599. s32 gval = 0;
  200600. + s32 wsec;
  200601. s32 err = 0;
  200602. if (sme->crypto.n_ciphers_pairwise) {
  200603. @@ -1398,7 +1468,12 @@
  200604. if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
  200605. sme->privacy)
  200606. pval = AES_ENABLED;
  200607. - err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
  200608. +
  200609. + if (mfp)
  200610. + wsec = pval | gval | MFP_CAPABLE;
  200611. + else
  200612. + wsec = pval | gval;
  200613. + err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
  200614. if (err) {
  200615. brcmf_err("error (%d)\n", err);
  200616. return err;
  200617. @@ -1562,13 +1637,12 @@
  200618. struct ieee80211_channel *chan = sme->channel;
  200619. struct brcmf_join_params join_params;
  200620. size_t join_params_size;
  200621. - struct brcmf_tlv *rsn_ie;
  200622. - struct brcmf_vs_tlv *wpa_ie;
  200623. - void *ie;
  200624. + const struct brcmf_tlv *rsn_ie;
  200625. + const struct brcmf_vs_tlv *wpa_ie;
  200626. + const void *ie;
  200627. u32 ie_len;
  200628. struct brcmf_ext_join_params_le *ext_join_params;
  200629. u16 chanspec;
  200630. -
  200631. s32 err = 0;
  200632. brcmf_dbg(TRACE, "Enter\n");
  200633. @@ -1591,7 +1665,8 @@
  200634. ie_len = wpa_ie->len + TLV_HDR_LEN;
  200635. } else {
  200636. /* find the RSN_IE */
  200637. - rsn_ie = brcmf_parse_tlvs((u8 *)sme->ie, sme->ie_len,
  200638. + rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
  200639. + sme->ie_len,
  200640. WLAN_EID_RSN);
  200641. if (rsn_ie) {
  200642. ie = rsn_ie;
  200643. @@ -1636,7 +1711,7 @@
  200644. goto done;
  200645. }
  200646. - err = brcmf_set_set_cipher(ndev, sme);
  200647. + err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
  200648. if (err) {
  200649. brcmf_err("wl_set_set_cipher failed (%d)\n", err);
  200650. goto done;
  200651. @@ -1678,22 +1753,9 @@
  200652. ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
  200653. memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
  200654. profile->ssid.SSID_len);
  200655. - /*increase dwell time to receive probe response or detect Beacon
  200656. - * from target AP at a noisy air only during connect command
  200657. - */
  200658. - ext_join_params->scan_le.active_time =
  200659. - cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
  200660. - ext_join_params->scan_le.passive_time =
  200661. - cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
  200662. +
  200663. /* Set up join scan parameters */
  200664. ext_join_params->scan_le.scan_type = -1;
  200665. - /* to sync with presence period of VSDB GO.
  200666. - * Send probe request more frequently. Probe request will be stopped
  200667. - * when it gets probe response from target AP/GO.
  200668. - */
  200669. - ext_join_params->scan_le.nprobes =
  200670. - cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
  200671. - BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
  200672. ext_join_params->scan_le.home_time = cpu_to_le32(-1);
  200673. if (sme->bssid)
  200674. @@ -1706,6 +1768,25 @@
  200675. ext_join_params->assoc_le.chanspec_list[0] =
  200676. cpu_to_le16(chanspec);
  200677. + /* Increase dwell time to receive probe response or detect
  200678. + * beacon from target AP at a noisy air only during connect
  200679. + * command.
  200680. + */
  200681. + ext_join_params->scan_le.active_time =
  200682. + cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
  200683. + ext_join_params->scan_le.passive_time =
  200684. + cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
  200685. + /* To sync with presence period of VSDB GO send probe request
  200686. + * more frequently. Probe request will be stopped when it gets
  200687. + * probe response from target AP/GO.
  200688. + */
  200689. + ext_join_params->scan_le.nprobes =
  200690. + cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
  200691. + BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
  200692. + } else {
  200693. + ext_join_params->scan_le.active_time = cpu_to_le32(-1);
  200694. + ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
  200695. + ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
  200696. }
  200697. err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
  200698. @@ -1913,7 +1994,7 @@
  200699. brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
  200700. memcpy(key.data, params->key, key.len);
  200701. - if ((ifp->vif->mode != WL_MODE_AP) &&
  200702. + if (!brcmf_is_apmode(ifp->vif) &&
  200703. (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
  200704. brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
  200705. memcpy(keybuf, &key.data[24], sizeof(keybuf));
  200706. @@ -1981,7 +2062,9 @@
  200707. if (!check_vif_up(ifp->vif))
  200708. return -EIO;
  200709. - if (mac_addr) {
  200710. + if (mac_addr &&
  200711. + (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
  200712. + (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
  200713. brcmf_dbg(TRACE, "Exit");
  200714. return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
  200715. }
  200716. @@ -2010,7 +2093,7 @@
  200717. brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
  200718. break;
  200719. case WLAN_CIPHER_SUITE_TKIP:
  200720. - if (ifp->vif->mode != WL_MODE_AP) {
  200721. + if (!brcmf_is_apmode(ifp->vif)) {
  200722. brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
  200723. memcpy(keybuf, &key.data[24], sizeof(keybuf));
  200724. memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
  200725. @@ -2164,12 +2247,14 @@
  200726. s32 err = 0;
  200727. u8 *bssid = profile->bssid;
  200728. struct brcmf_sta_info_le sta_info_le;
  200729. + u32 beacon_period;
  200730. + u32 dtim_period;
  200731. brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
  200732. if (!check_vif_up(ifp->vif))
  200733. return -EIO;
  200734. - if (ifp->vif->mode == WL_MODE_AP) {
  200735. + if (brcmf_is_apmode(ifp->vif)) {
  200736. memcpy(&sta_info_le, mac, ETH_ALEN);
  200737. err = brcmf_fil_iovar_data_get(ifp, "sta_info",
  200738. &sta_info_le,
  200739. @@ -2186,7 +2271,7 @@
  200740. }
  200741. brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
  200742. sinfo->inactive_time, sinfo->connected_time);
  200743. - } else if (ifp->vif->mode == WL_MODE_BSS) {
  200744. + } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) {
  200745. if (memcmp(mac, bssid, ETH_ALEN)) {
  200746. brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
  200747. mac, bssid);
  200748. @@ -2218,6 +2303,30 @@
  200749. sinfo->signal = rssi;
  200750. brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
  200751. }
  200752. + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD,
  200753. + &beacon_period);
  200754. + if (err) {
  200755. + brcmf_err("Could not get beacon period (%d)\n",
  200756. + err);
  200757. + goto done;
  200758. + } else {
  200759. + sinfo->bss_param.beacon_interval =
  200760. + beacon_period;
  200761. + brcmf_dbg(CONN, "Beacon peroid %d\n",
  200762. + beacon_period);
  200763. + }
  200764. + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD,
  200765. + &dtim_period);
  200766. + if (err) {
  200767. + brcmf_err("Could not get DTIM period (%d)\n",
  200768. + err);
  200769. + goto done;
  200770. + } else {
  200771. + sinfo->bss_param.dtim_period = dtim_period;
  200772. + brcmf_dbg(CONN, "DTIM peroid %d\n",
  200773. + dtim_period);
  200774. + }
  200775. + sinfo->filled |= STATION_INFO_BSS_PARAM;
  200776. }
  200777. } else
  200778. err = -EPERM;
  200779. @@ -2444,18 +2553,13 @@
  200780. return err;
  200781. }
  200782. -static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
  200783. -{
  200784. - return vif->mode == WL_MODE_IBSS;
  200785. -}
  200786. -
  200787. static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
  200788. struct brcmf_if *ifp)
  200789. {
  200790. struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
  200791. struct brcmf_bss_info_le *bi;
  200792. struct brcmf_ssid *ssid;
  200793. - struct brcmf_tlv *tim;
  200794. + const struct brcmf_tlv *tim;
  200795. u16 beacon_interval;
  200796. u8 dtim_period;
  200797. size_t ie_len;
  200798. @@ -3075,7 +3179,7 @@
  200799. }
  200800. if (!request->n_ssids || !request->n_match_sets) {
  200801. - brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
  200802. + brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
  200803. request->n_ssids);
  200804. return -EINVAL;
  200805. }
  200806. @@ -3220,8 +3324,9 @@
  200807. }
  200808. static s32
  200809. -brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
  200810. - bool is_rsn_ie)
  200811. +brcmf_configure_wpaie(struct net_device *ndev,
  200812. + const struct brcmf_vs_tlv *wpa_ie,
  200813. + bool is_rsn_ie)
  200814. {
  200815. struct brcmf_if *ifp = netdev_priv(ndev);
  200816. u32 auth = 0; /* d11 open authentication */
  200817. @@ -3684,42 +3789,26 @@
  200818. }
  200819. static s32
  200820. -brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
  200821. - struct brcmf_if *ifp,
  200822. - struct ieee80211_channel *channel)
  200823. -{
  200824. - u16 chanspec;
  200825. - s32 err;
  200826. -
  200827. - brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
  200828. - channel->center_freq);
  200829. -
  200830. - chanspec = channel_to_chanspec(&cfg->d11inf, channel);
  200831. - err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
  200832. -
  200833. - return err;
  200834. -}
  200835. -
  200836. -static s32
  200837. brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
  200838. struct cfg80211_ap_settings *settings)
  200839. {
  200840. s32 ie_offset;
  200841. struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
  200842. struct brcmf_if *ifp = netdev_priv(ndev);
  200843. - struct brcmf_tlv *ssid_ie;
  200844. + const struct brcmf_tlv *ssid_ie;
  200845. struct brcmf_ssid_le ssid_le;
  200846. s32 err = -EPERM;
  200847. - struct brcmf_tlv *rsn_ie;
  200848. - struct brcmf_vs_tlv *wpa_ie;
  200849. + const struct brcmf_tlv *rsn_ie;
  200850. + const struct brcmf_vs_tlv *wpa_ie;
  200851. struct brcmf_join_params join_params;
  200852. enum nl80211_iftype dev_role;
  200853. struct brcmf_fil_bss_enable_le bss_enable;
  200854. + u16 chanspec;
  200855. - brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
  200856. - cfg80211_get_chandef_type(&settings->chandef),
  200857. - settings->beacon_interval,
  200858. - settings->dtim_period);
  200859. + brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
  200860. + settings->chandef.chan->hw_value,
  200861. + settings->chandef.center_freq1, settings->chandef.width,
  200862. + settings->beacon_interval, settings->dtim_period);
  200863. brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
  200864. settings->ssid, settings->ssid_len, settings->auth_type,
  200865. settings->inactivity_timeout);
  200866. @@ -3776,9 +3865,10 @@
  200867. brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
  200868. - err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan);
  200869. + chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
  200870. + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
  200871. if (err < 0) {
  200872. - brcmf_err("Set Channel failed, %d\n", err);
  200873. + brcmf_err("Set Channel failed: chspec=%d, %d\n", chanspec, err);
  200874. goto exit;
  200875. }
  200876. @@ -4220,32 +4310,6 @@
  200877. CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
  200878. };
  200879. -static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
  200880. -{
  200881. - switch (type) {
  200882. - case NL80211_IFTYPE_AP_VLAN:
  200883. - case NL80211_IFTYPE_WDS:
  200884. - case NL80211_IFTYPE_MONITOR:
  200885. - case NL80211_IFTYPE_MESH_POINT:
  200886. - return -ENOTSUPP;
  200887. - case NL80211_IFTYPE_ADHOC:
  200888. - return WL_MODE_IBSS;
  200889. - case NL80211_IFTYPE_STATION:
  200890. - case NL80211_IFTYPE_P2P_CLIENT:
  200891. - return WL_MODE_BSS;
  200892. - case NL80211_IFTYPE_AP:
  200893. - case NL80211_IFTYPE_P2P_GO:
  200894. - return WL_MODE_AP;
  200895. - case NL80211_IFTYPE_P2P_DEVICE:
  200896. - return WL_MODE_P2P;
  200897. - case NL80211_IFTYPE_UNSPECIFIED:
  200898. - default:
  200899. - break;
  200900. - }
  200901. -
  200902. - return -EINVAL;
  200903. -}
  200904. -
  200905. static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
  200906. {
  200907. /* scheduled scan settings */
  200908. @@ -4340,6 +4404,8 @@
  200909. WIPHY_FLAG_OFFCHAN_TX |
  200910. WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
  200911. WIPHY_FLAG_SUPPORTS_TDLS;
  200912. + if (!brcmf_roamoff)
  200913. + wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
  200914. wiphy->mgmt_stypes = brcmf_txrx_stypes;
  200915. wiphy->max_remain_on_channel_duration = 5000;
  200916. brcmf_wiphy_pno_params(wiphy);
  200917. @@ -4370,7 +4436,6 @@
  200918. vif->wdev.wiphy = cfg->wiphy;
  200919. vif->wdev.iftype = type;
  200920. - vif->mode = brcmf_nl80211_iftype_to_mode(type);
  200921. vif->pm_block = pm_block;
  200922. vif->roam_off = -1;
  200923. @@ -4416,7 +4481,9 @@
  200924. u32 event = e->event_code;
  200925. u16 flags = e->flags;
  200926. - if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
  200927. + if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
  200928. + (event == BRCMF_E_DISASSOC_IND) ||
  200929. + ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
  200930. brcmf_dbg(CONN, "Processing link down\n");
  200931. return true;
  200932. }
  200933. @@ -4658,16 +4725,18 @@
  200934. struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
  200935. struct net_device *ndev = ifp->ndev;
  200936. struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
  200937. + struct ieee80211_channel *chan;
  200938. s32 err = 0;
  200939. - if (ifp->vif->mode == WL_MODE_AP) {
  200940. + if (brcmf_is_apmode(ifp->vif)) {
  200941. err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
  200942. } else if (brcmf_is_linkup(e)) {
  200943. brcmf_dbg(CONN, "Linkup\n");
  200944. if (brcmf_is_ibssmode(ifp->vif)) {
  200945. + chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
  200946. memcpy(profile->bssid, e->addr, ETH_ALEN);
  200947. wl_inform_ibss(cfg, ndev, e->addr);
  200948. - cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
  200949. + cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
  200950. clear_bit(BRCMF_VIF_STATUS_CONNECTING,
  200951. &ifp->vif->sme_state);
  200952. set_bit(BRCMF_VIF_STATUS_CONNECTED,
  200953. @@ -4678,10 +4747,6 @@
  200954. brcmf_dbg(CONN, "Linkdown\n");
  200955. if (!brcmf_is_ibssmode(ifp->vif)) {
  200956. brcmf_bss_connect_done(cfg, ndev, e, false);
  200957. - if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
  200958. - &ifp->vif->sme_state))
  200959. - cfg80211_disconnected(ndev, 0, NULL, 0,
  200960. - GFP_KERNEL);
  200961. }
  200962. brcmf_link_down(ifp->vif);
  200963. brcmf_init_prof(ndev_to_prof(ndev));
  200964. @@ -4875,11 +4940,8 @@
  200965. cfg->scan_request = NULL;
  200966. cfg->pwr_save = true;
  200967. - cfg->roam_on = true; /* roam on & off switch.
  200968. - we enable roam per default */
  200969. - cfg->active_scan = true; /* we do active scan for
  200970. - specific scan per default */
  200971. - cfg->dongle_up = false; /* dongle is not up yet */
  200972. + cfg->active_scan = true; /* we do active scan per default */
  200973. + cfg->dongle_up = false; /* dongle is not up yet */
  200974. err = brcmf_init_priv_mem(cfg);
  200975. if (err)
  200976. return err;
  200977. @@ -4904,6 +4966,30 @@
  200978. mutex_init(&event->vif_event_lock);
  200979. }
  200980. +static int brcmf_enable_bw40_2g(struct brcmf_if *ifp)
  200981. +{
  200982. + struct brcmf_fil_bwcap_le band_bwcap;
  200983. + u32 val;
  200984. + int err;
  200985. +
  200986. + /* verify support for bw_cap command */
  200987. + val = WLC_BAND_5G;
  200988. + err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
  200989. +
  200990. + if (!err) {
  200991. + /* only set 2G bandwidth using bw_cap command */
  200992. + band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
  200993. + band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
  200994. + err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
  200995. + sizeof(band_bwcap));
  200996. + } else {
  200997. + brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
  200998. + val = WLC_N_BW_40ALL;
  200999. + err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
  201000. + }
  201001. + return err;
  201002. +}
  201003. +
  201004. struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
  201005. struct device *busdev)
  201006. {
  201007. @@ -4961,6 +5047,17 @@
  201008. goto cfg80211_p2p_attach_out;
  201009. }
  201010. + /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
  201011. + * setup 40MHz in 2GHz band and enable OBSS scanning.
  201012. + */
  201013. + if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap &
  201014. + IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
  201015. + err = brcmf_enable_bw40_2g(ifp);
  201016. + if (!err)
  201017. + err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
  201018. + BRCMF_OBSS_COEX_AUTO);
  201019. + }
  201020. +
  201021. err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
  201022. if (err) {
  201023. brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
  201024. @@ -4999,7 +5096,7 @@
  201025. }
  201026. static s32
  201027. -brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
  201028. +brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
  201029. {
  201030. s32 err = 0;
  201031. __le32 roamtrigger[2];
  201032. @@ -5009,7 +5106,7 @@
  201033. * Setup timeout if Beacons are lost and roam is
  201034. * off to report link down
  201035. */
  201036. - if (roamvar) {
  201037. + if (brcmf_roamoff) {
  201038. err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
  201039. if (err) {
  201040. brcmf_err("bcn_timeout error (%d)\n", err);
  201041. @@ -5021,8 +5118,9 @@
  201042. * Enable/Disable built-in roaming to allow supplicant
  201043. * to take care of roaming
  201044. */
  201045. - brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
  201046. - err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
  201047. + brcmf_dbg(INFO, "Internal Roaming = %s\n",
  201048. + brcmf_roamoff ? "Off" : "On");
  201049. + err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
  201050. if (err) {
  201051. brcmf_err("roam_off error (%d)\n", err);
  201052. goto dongle_rom_out;
  201053. @@ -5148,6 +5246,9 @@
  201054. if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
  201055. ch.bw == BRCMU_CHAN_BW_40)
  201056. continue;
  201057. + if (!(bw_cap[band] & WLC_BW_80MHZ_BIT) &&
  201058. + ch.bw == BRCMU_CHAN_BW_80)
  201059. + continue;
  201060. update = false;
  201061. for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
  201062. if (band_chan_arr[j].hw_value == ch.chnum) {
  201063. @@ -5164,13 +5265,13 @@
  201064. ieee80211_channel_to_frequency(ch.chnum, band);
  201065. band_chan_arr[index].hw_value = ch.chnum;
  201066. - brcmf_err("channel %d: f=%d bw=%d sb=%d\n",
  201067. - ch.chnum, band_chan_arr[index].center_freq,
  201068. - ch.bw, ch.sb);
  201069. - if (ch.bw == BRCMU_CHAN_BW_40) {
  201070. - /* assuming the order is HT20, HT40 Upper,
  201071. - * HT40 lower from chanspecs
  201072. - */
  201073. + /* assuming the chanspecs order is HT20,
  201074. + * HT40 upper, HT40 lower, and VHT80.
  201075. + */
  201076. + if (ch.bw == BRCMU_CHAN_BW_80) {
  201077. + band_chan_arr[index].flags &=
  201078. + ~IEEE80211_CHAN_NO_80MHZ;
  201079. + } else if (ch.bw == BRCMU_CHAN_BW_40) {
  201080. ht40_flag = band_chan_arr[index].flags &
  201081. IEEE80211_CHAN_NO_HT40;
  201082. if (ch.sb == BRCMU_CHAN_SB_U) {
  201083. @@ -5191,8 +5292,13 @@
  201084. IEEE80211_CHAN_NO_HT40MINUS;
  201085. }
  201086. } else {
  201087. + /* disable other bandwidths for now as mentioned
  201088. + * order assure they are enabled for subsequent
  201089. + * chanspecs.
  201090. + */
  201091. band_chan_arr[index].flags =
  201092. - IEEE80211_CHAN_NO_HT40;
  201093. + IEEE80211_CHAN_NO_HT40 |
  201094. + IEEE80211_CHAN_NO_80MHZ;
  201095. ch.bw = BRCMU_CHAN_BW_20;
  201096. cfg->d11inf.encchspec(&ch);
  201097. channel = ch.chspec;
  201098. @@ -5259,14 +5365,66 @@
  201099. }
  201100. }
  201101. +static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
  201102. + u32 bw_cap[2], u32 nchain)
  201103. +{
  201104. + band->ht_cap.ht_supported = true;
  201105. + if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
  201106. + band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
  201107. + band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
  201108. + }
  201109. + band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
  201110. + band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
  201111. + band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
  201112. + band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
  201113. + memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
  201114. + band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
  201115. +}
  201116. +
  201117. +static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
  201118. +{
  201119. + u16 mcs_map;
  201120. + int i;
  201121. +
  201122. + for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
  201123. + mcs_map = (mcs_map << 2) | supp;
  201124. +
  201125. + return cpu_to_le16(mcs_map);
  201126. +}
  201127. +
  201128. +static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
  201129. + u32 bw_cap[2], u32 nchain)
  201130. +{
  201131. + __le16 mcs_map;
  201132. +
  201133. + /* not allowed in 2.4G band */
  201134. + if (band->band == IEEE80211_BAND_2GHZ)
  201135. + return;
  201136. +
  201137. + band->vht_cap.vht_supported = true;
  201138. + /* 80MHz is mandatory */
  201139. + band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
  201140. + if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
  201141. + band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
  201142. + band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
  201143. + }
  201144. + /* all support 256-QAM */
  201145. + mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
  201146. + band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
  201147. + band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
  201148. +}
  201149. +
  201150. static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
  201151. {
  201152. struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
  201153. struct wiphy *wiphy;
  201154. s32 phy_list;
  201155. u32 band_list[3];
  201156. - u32 nmode;
  201157. + u32 nmode = 0;
  201158. + u32 vhtmode = 0;
  201159. u32 bw_cap[2] = { 0, 0 };
  201160. + u32 rxchain;
  201161. + u32 nchain;
  201162. s8 phy;
  201163. s32 err;
  201164. u32 nband;
  201165. @@ -5294,14 +5452,26 @@
  201166. brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
  201167. band_list[0], band_list[1], band_list[2]);
  201168. + (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
  201169. err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
  201170. if (err) {
  201171. brcmf_err("nmode error (%d)\n", err);
  201172. } else {
  201173. brcmf_get_bwcap(ifp, bw_cap);
  201174. }
  201175. - brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode,
  201176. - bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]);
  201177. + brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
  201178. + nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
  201179. + bw_cap[IEEE80211_BAND_5GHZ]);
  201180. +
  201181. + err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
  201182. + if (err) {
  201183. + brcmf_err("rxchain error (%d)\n", err);
  201184. + nchain = 1;
  201185. + } else {
  201186. + for (nchain = 0; rxchain; nchain++)
  201187. + rxchain = rxchain & (rxchain - 1);
  201188. + }
  201189. + brcmf_dbg(INFO, "nchain=%d\n", nchain);
  201190. err = brcmf_construct_reginfo(cfg, bw_cap);
  201191. if (err) {
  201192. @@ -5322,20 +5492,10 @@
  201193. else
  201194. continue;
  201195. - if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
  201196. - band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
  201197. - band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
  201198. - }
  201199. - band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
  201200. - band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
  201201. - band->ht_cap.ht_supported = true;
  201202. - band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
  201203. - band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
  201204. - /* An HT shall support all EQM rates for one spatial
  201205. - * stream
  201206. - */
  201207. - band->ht_cap.mcs.rx_mask[0] = 0xff;
  201208. - band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
  201209. + if (nmode)
  201210. + brcmf_update_ht_cap(band, bw_cap, nchain);
  201211. + if (vhtmode)
  201212. + brcmf_update_vht_cap(band, bw_cap, nchain);
  201213. bands[band->band] = band;
  201214. }
  201215. @@ -5381,7 +5541,7 @@
  201216. brcmf_dbg(INFO, "power save set to %s\n",
  201217. (power_mode ? "enabled" : "disabled"));
  201218. - err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
  201219. + err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
  201220. if (err)
  201221. goto default_conf_out;
  201222. err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
  201223. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
  201224. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h 2014-07-31 23:51:43.000000000 +0200
  201225. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h 2014-08-20 19:31:46.896872302 +0200
  201226. @@ -89,21 +89,6 @@
  201227. BRCMF_SCAN_STATUS_SUPPRESS,
  201228. };
  201229. -/**
  201230. - * enum wl_mode - driver mode of virtual interface.
  201231. - *
  201232. - * @WL_MODE_BSS: connects to BSS.
  201233. - * @WL_MODE_IBSS: operate as ad-hoc.
  201234. - * @WL_MODE_AP: operate as access-point.
  201235. - * @WL_MODE_P2P: provide P2P discovery.
  201236. - */
  201237. -enum wl_mode {
  201238. - WL_MODE_BSS,
  201239. - WL_MODE_IBSS,
  201240. - WL_MODE_AP,
  201241. - WL_MODE_P2P
  201242. -};
  201243. -
  201244. /* dongle configuration */
  201245. struct brcmf_cfg80211_conf {
  201246. u32 frag_threshold;
  201247. @@ -193,7 +178,6 @@
  201248. * @ifp: lower layer interface pointer
  201249. * @wdev: wireless device.
  201250. * @profile: profile information.
  201251. - * @mode: operating mode.
  201252. * @roam_off: roaming state.
  201253. * @sme_state: SME state using enum brcmf_vif_status bits.
  201254. * @pm_block: power-management blocked.
  201255. @@ -204,7 +188,6 @@
  201256. struct brcmf_if *ifp;
  201257. struct wireless_dev wdev;
  201258. struct brcmf_cfg80211_profile profile;
  201259. - s32 mode;
  201260. s32 roam_off;
  201261. unsigned long sme_state;
  201262. bool pm_block;
  201263. @@ -402,7 +385,6 @@
  201264. bool ibss_starter;
  201265. bool pwr_save;
  201266. bool dongle_up;
  201267. - bool roam_on;
  201268. bool scan_tried;
  201269. u8 *dcmd_buf;
  201270. u8 *extra_buf;
  201271. @@ -491,7 +473,8 @@
  201272. s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
  201273. const u8 *vndr_ie_buf, u32 vndr_ie_len);
  201274. s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif);
  201275. -struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key);
  201276. +const struct brcmf_tlv *
  201277. +brcmf_parse_tlvs(const void *buf, int buflen, uint key);
  201278. u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
  201279. struct ieee80211_channel *ch);
  201280. u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state);
  201281. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
  201282. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c 2014-07-31 23:51:43.000000000 +0200
  201283. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c 2014-08-20 19:31:46.896872302 +0200
  201284. @@ -897,7 +897,8 @@
  201285. return result;
  201286. }
  201287. -static void brcms_ops_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201288. +static void brcms_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201289. + u32 queues, bool drop)
  201290. {
  201291. struct brcms_info *wl = hw->priv;
  201292. int ret;
  201293. @@ -1092,12 +1093,6 @@
  201294. * Attach to the WL device identified by vendor and device parameters.
  201295. * regs is a host accessible memory address pointing to WL device registers.
  201296. *
  201297. - * brcms_attach is not defined as static because in the case where no bus
  201298. - * is defined, wl_attach will never be called, and thus, gcc will issue
  201299. - * a warning that this function is defined but not used if we declare
  201300. - * it as static.
  201301. - *
  201302. - *
  201303. * is called in brcms_bcma_probe() context, therefore no locking required.
  201304. */
  201305. static struct brcms_info *brcms_attach(struct bcma_device *pdev)
  201306. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmsmac/main.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmsmac/main.c
  201307. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmsmac/main.c 2014-07-31 23:51:43.000000000 +0200
  201308. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmsmac/main.c 2014-08-20 19:31:46.900872320 +0200
  201309. @@ -4870,14 +4870,11 @@
  201310. /*
  201311. * low level detach
  201312. */
  201313. -static int brcms_b_detach(struct brcms_c_info *wlc)
  201314. +static void brcms_b_detach(struct brcms_c_info *wlc)
  201315. {
  201316. uint i;
  201317. struct brcms_hw_band *band;
  201318. struct brcms_hardware *wlc_hw = wlc->hw;
  201319. - int callbacks;
  201320. -
  201321. - callbacks = 0;
  201322. brcms_b_detach_dmapio(wlc_hw);
  201323. @@ -4900,9 +4897,6 @@
  201324. ai_detach(wlc_hw->sih);
  201325. wlc_hw->sih = NULL;
  201326. }
  201327. -
  201328. - return callbacks;
  201329. -
  201330. }
  201331. /*
  201332. @@ -4917,14 +4911,15 @@
  201333. */
  201334. uint brcms_c_detach(struct brcms_c_info *wlc)
  201335. {
  201336. - uint callbacks = 0;
  201337. + uint callbacks;
  201338. if (wlc == NULL)
  201339. return 0;
  201340. - callbacks += brcms_b_detach(wlc);
  201341. + brcms_b_detach(wlc);
  201342. /* delete software timers */
  201343. + callbacks = 0;
  201344. if (!brcms_c_radio_monitor_stop(wlc))
  201345. callbacks++;
  201346. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/brcmutil/d11.c linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmutil/d11.c
  201347. --- linux-3.14.15/drivers/net/wireless/brcm80211/brcmutil/d11.c 2014-07-31 23:51:43.000000000 +0200
  201348. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/brcmutil/d11.c 2014-08-20 19:31:46.900872320 +0200
  201349. @@ -21,19 +21,46 @@
  201350. #include <brcmu_wifi.h>
  201351. #include <brcmu_d11.h>
  201352. -static void brcmu_d11n_encchspec(struct brcmu_chan *ch)
  201353. +static u16 d11n_sb(enum brcmu_chan_sb sb)
  201354. {
  201355. - ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK;
  201356. + switch (sb) {
  201357. + case BRCMU_CHAN_SB_NONE:
  201358. + return BRCMU_CHSPEC_D11N_SB_N;
  201359. + case BRCMU_CHAN_SB_L:
  201360. + return BRCMU_CHSPEC_D11N_SB_L;
  201361. + case BRCMU_CHAN_SB_U:
  201362. + return BRCMU_CHSPEC_D11N_SB_U;
  201363. + default:
  201364. + WARN_ON(1);
  201365. + }
  201366. + return 0;
  201367. +}
  201368. - switch (ch->bw) {
  201369. +static u16 d11n_bw(enum brcmu_chan_bw bw)
  201370. +{
  201371. + switch (bw) {
  201372. case BRCMU_CHAN_BW_20:
  201373. - ch->chspec |= BRCMU_CHSPEC_D11N_BW_20 | BRCMU_CHSPEC_D11N_SB_N;
  201374. - break;
  201375. + return BRCMU_CHSPEC_D11N_BW_20;
  201376. case BRCMU_CHAN_BW_40:
  201377. + return BRCMU_CHSPEC_D11N_BW_40;
  201378. default:
  201379. - WARN_ON_ONCE(1);
  201380. - break;
  201381. + WARN_ON(1);
  201382. }
  201383. + return 0;
  201384. +}
  201385. +
  201386. +static void brcmu_d11n_encchspec(struct brcmu_chan *ch)
  201387. +{
  201388. + if (ch->bw == BRCMU_CHAN_BW_20)
  201389. + ch->sb = BRCMU_CHAN_SB_NONE;
  201390. +
  201391. + ch->chspec = 0;
  201392. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,
  201393. + BRCMU_CHSPEC_CH_SHIFT, ch->chnum);
  201394. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_SB_MASK,
  201395. + 0, d11n_sb(ch->sb));
  201396. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_BW_MASK,
  201397. + 0, d11n_bw(ch->bw));
  201398. if (ch->chnum <= CH_MAX_2G_CHANNEL)
  201399. ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G;
  201400. @@ -41,23 +68,34 @@
  201401. ch->chspec |= BRCMU_CHSPEC_D11N_BND_5G;
  201402. }
  201403. -static void brcmu_d11ac_encchspec(struct brcmu_chan *ch)
  201404. +static u16 d11ac_bw(enum brcmu_chan_bw bw)
  201405. {
  201406. - ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK;
  201407. -
  201408. - switch (ch->bw) {
  201409. + switch (bw) {
  201410. case BRCMU_CHAN_BW_20:
  201411. - ch->chspec |= BRCMU_CHSPEC_D11AC_BW_20;
  201412. - break;
  201413. + return BRCMU_CHSPEC_D11AC_BW_20;
  201414. case BRCMU_CHAN_BW_40:
  201415. + return BRCMU_CHSPEC_D11AC_BW_40;
  201416. case BRCMU_CHAN_BW_80:
  201417. - case BRCMU_CHAN_BW_80P80:
  201418. - case BRCMU_CHAN_BW_160:
  201419. + return BRCMU_CHSPEC_D11AC_BW_80;
  201420. default:
  201421. - WARN_ON_ONCE(1);
  201422. - break;
  201423. + WARN_ON(1);
  201424. }
  201425. + return 0;
  201426. +}
  201427. +static void brcmu_d11ac_encchspec(struct brcmu_chan *ch)
  201428. +{
  201429. + if (ch->bw == BRCMU_CHAN_BW_20 || ch->sb == BRCMU_CHAN_SB_NONE)
  201430. + ch->sb = BRCMU_CHAN_SB_L;
  201431. +
  201432. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,
  201433. + BRCMU_CHSPEC_CH_SHIFT, ch->chnum);
  201434. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,
  201435. + BRCMU_CHSPEC_D11AC_SB_SHIFT, ch->sb);
  201436. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_BW_MASK,
  201437. + 0, d11ac_bw(ch->bw));
  201438. +
  201439. + ch->chspec &= ~BRCMU_CHSPEC_D11AC_BND_MASK;
  201440. if (ch->chnum <= CH_MAX_2G_CHANNEL)
  201441. ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G;
  201442. else
  201443. @@ -73,6 +111,7 @@
  201444. switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) {
  201445. case BRCMU_CHSPEC_D11N_BW_20:
  201446. ch->bw = BRCMU_CHAN_BW_20;
  201447. + ch->sb = BRCMU_CHAN_SB_NONE;
  201448. break;
  201449. case BRCMU_CHSPEC_D11N_BW_40:
  201450. ch->bw = BRCMU_CHAN_BW_40;
  201451. @@ -112,6 +151,7 @@
  201452. switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) {
  201453. case BRCMU_CHSPEC_D11AC_BW_20:
  201454. ch->bw = BRCMU_CHAN_BW_20;
  201455. + ch->sb = BRCMU_CHAN_SB_NONE;
  201456. break;
  201457. case BRCMU_CHSPEC_D11AC_BW_40:
  201458. ch->bw = BRCMU_CHAN_BW_40;
  201459. @@ -128,6 +168,25 @@
  201460. break;
  201461. case BRCMU_CHSPEC_D11AC_BW_80:
  201462. ch->bw = BRCMU_CHAN_BW_80;
  201463. + ch->sb = brcmu_maskget16(ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,
  201464. + BRCMU_CHSPEC_D11AC_SB_SHIFT);
  201465. + switch (ch->sb) {
  201466. + case BRCMU_CHAN_SB_LL:
  201467. + ch->chnum -= CH_30MHZ_APART;
  201468. + break;
  201469. + case BRCMU_CHAN_SB_LU:
  201470. + ch->chnum -= CH_10MHZ_APART;
  201471. + break;
  201472. + case BRCMU_CHAN_SB_UL:
  201473. + ch->chnum += CH_10MHZ_APART;
  201474. + break;
  201475. + case BRCMU_CHAN_SB_UU:
  201476. + ch->chnum += CH_30MHZ_APART;
  201477. + break;
  201478. + default:
  201479. + WARN_ON_ONCE(1);
  201480. + break;
  201481. + }
  201482. break;
  201483. case BRCMU_CHSPEC_D11AC_BW_8080:
  201484. case BRCMU_CHSPEC_D11AC_BW_160:
  201485. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
  201486. --- linux-3.14.15/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h 2014-07-31 23:51:43.000000000 +0200
  201487. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h 2014-08-20 19:31:46.900872320 +0200
  201488. @@ -43,5 +43,6 @@
  201489. #define BCM4335_CHIP_ID 0x4335
  201490. #define BCM43362_CHIP_ID 43362
  201491. #define BCM4339_CHIP_ID 0x4339
  201492. +#define BCM4354_CHIP_ID 0x4354
  201493. #endif /* _BRCM_HW_IDS_H_ */
  201494. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/include/brcmu_d11.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/include/brcmu_d11.h
  201495. --- linux-3.14.15/drivers/net/wireless/brcm80211/include/brcmu_d11.h 2014-07-31 23:51:43.000000000 +0200
  201496. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/include/brcmu_d11.h 2014-08-20 19:31:46.900872320 +0200
  201497. @@ -108,13 +108,7 @@
  201498. };
  201499. enum brcmu_chan_sb {
  201500. - BRCMU_CHAN_SB_NONE = 0,
  201501. - BRCMU_CHAN_SB_L,
  201502. - BRCMU_CHAN_SB_U,
  201503. - BRCMU_CHAN_SB_LL,
  201504. - BRCMU_CHAN_SB_LU,
  201505. - BRCMU_CHAN_SB_UL,
  201506. - BRCMU_CHAN_SB_UU,
  201507. + BRCMU_CHAN_SB_NONE = -1,
  201508. BRCMU_CHAN_SB_LLL,
  201509. BRCMU_CHAN_SB_LLU,
  201510. BRCMU_CHAN_SB_LUL,
  201511. @@ -123,6 +117,12 @@
  201512. BRCMU_CHAN_SB_ULU,
  201513. BRCMU_CHAN_SB_UUL,
  201514. BRCMU_CHAN_SB_UUU,
  201515. + BRCMU_CHAN_SB_L = BRCMU_CHAN_SB_LLL,
  201516. + BRCMU_CHAN_SB_U = BRCMU_CHAN_SB_LLU,
  201517. + BRCMU_CHAN_SB_LL = BRCMU_CHAN_SB_LLL,
  201518. + BRCMU_CHAN_SB_LU = BRCMU_CHAN_SB_LLU,
  201519. + BRCMU_CHAN_SB_UL = BRCMU_CHAN_SB_LUL,
  201520. + BRCMU_CHAN_SB_UU = BRCMU_CHAN_SB_LUU,
  201521. };
  201522. struct brcmu_chan {
  201523. diff -Nur linux-3.14.15/drivers/net/wireless/brcm80211/include/brcmu_wifi.h linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
  201524. --- linux-3.14.15/drivers/net/wireless/brcm80211/include/brcmu_wifi.h 2014-07-31 23:51:43.000000000 +0200
  201525. +++ linux-linaro-stable-mx6/drivers/net/wireless/brcm80211/include/brcmu_wifi.h 2014-08-20 19:31:46.900872320 +0200
  201526. @@ -29,6 +29,7 @@
  201527. #define CH_UPPER_SB 0x01
  201528. #define CH_LOWER_SB 0x02
  201529. #define CH_EWA_VALID 0x04
  201530. +#define CH_30MHZ_APART 6
  201531. #define CH_20MHZ_APART 4
  201532. #define CH_10MHZ_APART 2
  201533. #define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
  201534. @@ -217,6 +218,9 @@
  201535. #define WSEC_SWFLAG 0x0008
  201536. /* to go into transition mode without setting wep */
  201537. #define SES_OW_ENABLED 0x0040
  201538. +/* MFP */
  201539. +#define MFP_CAPABLE 0x0200
  201540. +#define MFP_REQUIRED 0x0400
  201541. /* WPA authentication mode bitvec */
  201542. #define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */
  201543. diff -Nur linux-3.14.15/drivers/net/wireless/cw1200/sta.c linux-linaro-stable-mx6/drivers/net/wireless/cw1200/sta.c
  201544. --- linux-3.14.15/drivers/net/wireless/cw1200/sta.c 2014-07-31 23:51:43.000000000 +0200
  201545. +++ linux-linaro-stable-mx6/drivers/net/wireless/cw1200/sta.c 2014-08-20 19:31:46.904872337 +0200
  201546. @@ -936,7 +936,8 @@
  201547. return ret;
  201548. }
  201549. -void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201550. +void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201551. + u32 queues, bool drop)
  201552. {
  201553. struct cw1200_common *priv = hw->priv;
  201554. diff -Nur linux-3.14.15/drivers/net/wireless/cw1200/sta.h linux-linaro-stable-mx6/drivers/net/wireless/cw1200/sta.h
  201555. --- linux-3.14.15/drivers/net/wireless/cw1200/sta.h 2014-07-31 23:51:43.000000000 +0200
  201556. +++ linux-linaro-stable-mx6/drivers/net/wireless/cw1200/sta.h 2014-08-20 19:31:46.904872337 +0200
  201557. @@ -40,7 +40,8 @@
  201558. int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
  201559. -void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
  201560. +void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201561. + u32 queues, bool drop);
  201562. u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
  201563. struct netdev_hw_addr_list *mc_list);
  201564. diff -Nur linux-3.14.15/drivers/net/wireless/iwlegacy/common.c linux-linaro-stable-mx6/drivers/net/wireless/iwlegacy/common.c
  201565. --- linux-3.14.15/drivers/net/wireless/iwlegacy/common.c 2014-07-31 23:51:43.000000000 +0200
  201566. +++ linux-linaro-stable-mx6/drivers/net/wireless/iwlegacy/common.c 2014-08-20 19:31:46.924872422 +0200
  201567. @@ -4701,7 +4701,8 @@
  201568. }
  201569. EXPORT_SYMBOL(il_mac_change_interface);
  201570. -void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201571. +void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201572. + u32 queues, bool drop)
  201573. {
  201574. struct il_priv *il = hw->priv;
  201575. unsigned long timeout = jiffies + msecs_to_jiffies(500);
  201576. diff -Nur linux-3.14.15/drivers/net/wireless/iwlegacy/common.h linux-linaro-stable-mx6/drivers/net/wireless/iwlegacy/common.h
  201577. --- linux-3.14.15/drivers/net/wireless/iwlegacy/common.h 2014-07-31 23:51:43.000000000 +0200
  201578. +++ linux-linaro-stable-mx6/drivers/net/wireless/iwlegacy/common.h 2014-08-20 19:31:46.924872422 +0200
  201579. @@ -1722,7 +1722,8 @@
  201580. struct ieee80211_vif *vif);
  201581. int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201582. enum nl80211_iftype newtype, bool newp2p);
  201583. -void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
  201584. +void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201585. + u32 queues, bool drop);
  201586. int il_alloc_txq_mem(struct il_priv *il);
  201587. void il_free_txq_mem(struct il_priv *il);
  201588. diff -Nur linux-3.14.15/drivers/net/wireless/iwlwifi/dvm/mac80211.c linux-linaro-stable-mx6/drivers/net/wireless/iwlwifi/dvm/mac80211.c
  201589. --- linux-3.14.15/drivers/net/wireless/iwlwifi/dvm/mac80211.c 2014-07-31 23:51:43.000000000 +0200
  201590. +++ linux-linaro-stable-mx6/drivers/net/wireless/iwlwifi/dvm/mac80211.c 2014-08-20 19:31:46.928872440 +0200
  201591. @@ -1091,7 +1091,8 @@
  201592. FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
  201593. }
  201594. -static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201595. +static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201596. + u32 queues, bool drop)
  201597. {
  201598. struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
  201599. diff -Nur linux-3.14.15/drivers/net/wireless/libertas/cfg.c linux-linaro-stable-mx6/drivers/net/wireless/libertas/cfg.c
  201600. --- linux-3.14.15/drivers/net/wireless/libertas/cfg.c 2014-07-31 23:51:43.000000000 +0200
  201601. +++ linux-linaro-stable-mx6/drivers/net/wireless/libertas/cfg.c 2014-08-20 19:31:46.968872611 +0200
  201602. @@ -1766,7 +1766,8 @@
  201603. memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
  201604. priv->wdev->ssid_len = params->ssid_len;
  201605. - cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
  201606. + cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan,
  201607. + GFP_KERNEL);
  201608. /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
  201609. priv->connect_status = LBS_CONNECTED;
  201610. diff -Nur linux-3.14.15/drivers/net/wireless/mac80211_hwsim.c linux-linaro-stable-mx6/drivers/net/wireless/mac80211_hwsim.c
  201611. --- linux-3.14.15/drivers/net/wireless/mac80211_hwsim.c 2014-07-31 23:51:43.000000000 +0200
  201612. +++ linux-linaro-stable-mx6/drivers/net/wireless/mac80211_hwsim.c 2014-08-20 19:31:46.972872628 +0200
  201613. @@ -1671,7 +1671,9 @@
  201614. return 0;
  201615. }
  201616. -static void mac80211_hwsim_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201617. +static void mac80211_hwsim_flush(struct ieee80211_hw *hw,
  201618. + struct ieee80211_vif *vif,
  201619. + u32 queues, bool drop)
  201620. {
  201621. /* Not implemented, queues only on kernel side */
  201622. }
  201623. diff -Nur linux-3.14.15/drivers/net/wireless/mwifiex/cfg80211.c linux-linaro-stable-mx6/drivers/net/wireless/mwifiex/cfg80211.c
  201624. --- linux-3.14.15/drivers/net/wireless/mwifiex/cfg80211.c 2014-07-31 23:51:43.000000000 +0200
  201625. +++ linux-linaro-stable-mx6/drivers/net/wireless/mwifiex/cfg80211.c 2014-08-20 19:31:46.976872647 +0200
  201626. @@ -1881,7 +1881,8 @@
  201627. params->privacy);
  201628. done:
  201629. if (!ret) {
  201630. - cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
  201631. + cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
  201632. + params->chandef.chan, GFP_KERNEL);
  201633. dev_dbg(priv->adapter->dev,
  201634. "info: joined/created adhoc network with bssid"
  201635. " %pM successfully\n", priv->cfg_bssid);
  201636. diff -Nur linux-3.14.15/drivers/net/wireless/mwifiex/main.h linux-linaro-stable-mx6/drivers/net/wireless/mwifiex/main.h
  201637. --- linux-3.14.15/drivers/net/wireless/mwifiex/main.h 2014-07-31 23:51:43.000000000 +0200
  201638. +++ linux-linaro-stable-mx6/drivers/net/wireless/mwifiex/main.h 2014-08-20 19:31:46.984872680 +0200
  201639. @@ -1078,7 +1078,7 @@
  201640. const u8 *key, int key_len, u8 key_index,
  201641. const u8 *mac_addr, int disable);
  201642. -int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
  201643. +int mwifiex_set_gen_ie(struct mwifiex_private *priv, const u8 *ie, int ie_len);
  201644. int mwifiex_get_ver_ext(struct mwifiex_private *priv);
  201645. diff -Nur linux-3.14.15/drivers/net/wireless/mwifiex/sta_ioctl.c linux-linaro-stable-mx6/drivers/net/wireless/mwifiex/sta_ioctl.c
  201646. --- linux-3.14.15/drivers/net/wireless/mwifiex/sta_ioctl.c 2014-07-31 23:51:43.000000000 +0200
  201647. +++ linux-linaro-stable-mx6/drivers/net/wireless/mwifiex/sta_ioctl.c 2014-08-20 19:31:46.992872714 +0200
  201648. @@ -1391,7 +1391,7 @@
  201649. * with requisite parameters and calls the IOCTL handler.
  201650. */
  201651. int
  201652. -mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len)
  201653. +mwifiex_set_gen_ie(struct mwifiex_private *priv, const u8 *ie, int ie_len)
  201654. {
  201655. struct mwifiex_ds_misc_gen_ie gen_ie;
  201656. diff -Nur linux-3.14.15/drivers/net/wireless/p54/main.c linux-linaro-stable-mx6/drivers/net/wireless/p54/main.c
  201657. --- linux-3.14.15/drivers/net/wireless/p54/main.c 2014-07-31 23:51:43.000000000 +0200
  201658. +++ linux-linaro-stable-mx6/drivers/net/wireless/p54/main.c 2014-08-20 19:31:47.008872783 +0200
  201659. @@ -669,7 +669,8 @@
  201660. return total;
  201661. }
  201662. -static void p54_flush(struct ieee80211_hw *dev, u32 queues, bool drop)
  201663. +static void p54_flush(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
  201664. + u32 queues, bool drop)
  201665. {
  201666. struct p54_common *priv = dev->priv;
  201667. unsigned int total, i;
  201668. diff -Nur linux-3.14.15/drivers/net/wireless/rndis_wlan.c linux-linaro-stable-mx6/drivers/net/wireless/rndis_wlan.c
  201669. --- linux-3.14.15/drivers/net/wireless/rndis_wlan.c 2014-07-31 23:51:43.000000000 +0200
  201670. +++ linux-linaro-stable-mx6/drivers/net/wireless/rndis_wlan.c 2014-08-20 19:31:47.016872817 +0200
  201671. @@ -2835,7 +2835,9 @@
  201672. bssid, req_ie, req_ie_len,
  201673. resp_ie, resp_ie_len, GFP_KERNEL);
  201674. } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
  201675. - cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
  201676. + cfg80211_ibss_joined(usbdev->net, bssid,
  201677. + get_current_channel(usbdev, NULL),
  201678. + GFP_KERNEL);
  201679. kfree(info);
  201680. diff -Nur linux-3.14.15/drivers/net/wireless/rt2x00/rt2x00.h linux-linaro-stable-mx6/drivers/net/wireless/rt2x00/rt2x00.h
  201681. --- linux-3.14.15/drivers/net/wireless/rt2x00/rt2x00.h 2014-07-31 23:51:43.000000000 +0200
  201682. +++ linux-linaro-stable-mx6/drivers/net/wireless/rt2x00/rt2x00.h 2014-08-20 19:31:47.028872869 +0200
  201683. @@ -1449,7 +1449,8 @@
  201684. struct ieee80211_vif *vif, u16 queue,
  201685. const struct ieee80211_tx_queue_params *params);
  201686. void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
  201687. -void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
  201688. +void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201689. + u32 queues, bool drop);
  201690. int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
  201691. int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
  201692. void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
  201693. diff -Nur linux-3.14.15/drivers/net/wireless/rt2x00/rt2x00mac.c linux-linaro-stable-mx6/drivers/net/wireless/rt2x00/rt2x00mac.c
  201694. --- linux-3.14.15/drivers/net/wireless/rt2x00/rt2x00mac.c 2014-07-31 23:51:43.000000000 +0200
  201695. +++ linux-linaro-stable-mx6/drivers/net/wireless/rt2x00/rt2x00mac.c 2014-08-20 19:31:47.040872920 +0200
  201696. @@ -751,7 +751,8 @@
  201697. }
  201698. EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
  201699. -void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201700. +void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201701. + u32 queues, bool drop)
  201702. {
  201703. struct rt2x00_dev *rt2x00dev = hw->priv;
  201704. struct data_queue *queue;
  201705. diff -Nur linux-3.14.15/drivers/net/wireless/rtl818x/rtl8187/dev.c linux-linaro-stable-mx6/drivers/net/wireless/rtl818x/rtl8187/dev.c
  201706. --- linux-3.14.15/drivers/net/wireless/rtl818x/rtl8187/dev.c 2014-07-31 23:51:43.000000000 +0200
  201707. +++ linux-linaro-stable-mx6/drivers/net/wireless/rtl818x/rtl8187/dev.c 2014-08-20 19:31:47.060873006 +0200
  201708. @@ -1636,10 +1636,10 @@
  201709. err_free_dmabuf:
  201710. kfree(priv->io_dmabuf);
  201711. - err_free_dev:
  201712. - ieee80211_free_hw(dev);
  201713. usb_set_intfdata(intf, NULL);
  201714. usb_put_dev(udev);
  201715. + err_free_dev:
  201716. + ieee80211_free_hw(dev);
  201717. return err;
  201718. }
  201719. diff -Nur linux-3.14.15/drivers/net/wireless/rtlwifi/core.c linux-linaro-stable-mx6/drivers/net/wireless/rtlwifi/core.c
  201720. --- linux-3.14.15/drivers/net/wireless/rtlwifi/core.c 2014-07-31 23:51:43.000000000 +0200
  201721. +++ linux-linaro-stable-mx6/drivers/net/wireless/rtlwifi/core.c 2014-08-20 19:31:47.060873006 +0200
  201722. @@ -1309,7 +1309,8 @@
  201723. * before switch channel or power save, or tx buffer packet
  201724. * maybe send after offchannel or rf sleep, this may cause
  201725. * dis-association by AP */
  201726. -static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201727. +static void rtl_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201728. + u32 queues, bool drop)
  201729. {
  201730. struct rtl_priv *rtlpriv = rtl_priv(hw);
  201731. diff -Nur linux-3.14.15/drivers/net/wireless/ti/wlcore/main.c linux-linaro-stable-mx6/drivers/net/wireless/ti/wlcore/main.c
  201732. --- linux-3.14.15/drivers/net/wireless/ti/wlcore/main.c 2014-07-31 23:51:43.000000000 +0200
  201733. +++ linux-linaro-stable-mx6/drivers/net/wireless/ti/wlcore/main.c 2014-08-20 19:31:47.084873109 +0200
  201734. @@ -5156,7 +5156,8 @@
  201735. mutex_unlock(&wl->mutex);
  201736. }
  201737. -static void wlcore_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201738. +static void wlcore_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201739. + u32 queues, bool drop)
  201740. {
  201741. struct wl1271 *wl = hw->priv;
  201742. diff -Nur linux-3.14.15/drivers/parport/Kconfig linux-linaro-stable-mx6/drivers/parport/Kconfig
  201743. --- linux-3.14.15/drivers/parport/Kconfig 2014-07-31 23:51:43.000000000 +0200
  201744. +++ linux-linaro-stable-mx6/drivers/parport/Kconfig 2014-08-20 19:31:47.128873298 +0200
  201745. @@ -5,12 +5,6 @@
  201746. # Parport configuration.
  201747. #
  201748. -config ARCH_MIGHT_HAVE_PC_PARPORT
  201749. - bool
  201750. - help
  201751. - Select this config option from the architecture Kconfig if
  201752. - the architecture might have PC parallel port hardware.
  201753. -
  201754. menuconfig PARPORT
  201755. tristate "Parallel port support"
  201756. depends on HAS_IOMEM
  201757. @@ -37,6 +31,12 @@
  201758. If unsure, say Y.
  201759. +config ARCH_MIGHT_HAVE_PC_PARPORT
  201760. + bool
  201761. + help
  201762. + Select this config option from the architecture Kconfig if
  201763. + the architecture might have PC parallel port hardware.
  201764. +
  201765. if PARPORT
  201766. config PARPORT_PC
  201767. diff -Nur linux-3.14.15/drivers/pci/host/Kconfig linux-linaro-stable-mx6/drivers/pci/host/Kconfig
  201768. --- linux-3.14.15/drivers/pci/host/Kconfig 2014-07-31 23:51:43.000000000 +0200
  201769. +++ linux-linaro-stable-mx6/drivers/pci/host/Kconfig 2014-08-20 19:31:47.132873314 +0200
  201770. @@ -21,6 +21,23 @@
  201771. select PCIEPORTBUS
  201772. select PCIE_DW
  201773. +config EP_MODE_IN_EP_RC_SYS
  201774. + bool "PCI Express EP mode in the IMX6 RC/EP interconnection system"
  201775. + depends on PCI_IMX6
  201776. +
  201777. +config EP_SELF_IO_TEST
  201778. + bool "PCI Express EP_SELF_IO_TEST in EP mode"
  201779. + depends on EP_MODE_IN_EP_RC_SYS
  201780. +
  201781. +config RC_MODE_IN_EP_RC_SYS
  201782. + bool "PCI Express RC mode in the IMX6 RC/EP interconnection system"
  201783. + depends on PCI_IMX6
  201784. +
  201785. +config PCI_IMX_EP_DRV
  201786. + bool "i.MX6 PCI Express EP skeleton driver"
  201787. + depends on RC_MODE_IN_EP_RC_SYS
  201788. + default y
  201789. +
  201790. config PCI_TEGRA
  201791. bool "NVIDIA Tegra PCIe controller"
  201792. depends on ARCH_TEGRA
  201793. diff -Nur linux-3.14.15/drivers/pci/host/Makefile linux-linaro-stable-mx6/drivers/pci/host/Makefile
  201794. --- linux-3.14.15/drivers/pci/host/Makefile 2014-07-31 23:51:43.000000000 +0200
  201795. +++ linux-linaro-stable-mx6/drivers/pci/host/Makefile 2014-08-20 19:31:47.132873314 +0200
  201796. @@ -1,6 +1,7 @@
  201797. obj-$(CONFIG_PCIE_DW) += pcie-designware.o
  201798. obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
  201799. obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
  201800. +obj-$(CONFIG_PCI_IMX_EP_DRV) += pci-imx6-ep-driver.o
  201801. obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
  201802. obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
  201803. obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
  201804. diff -Nur linux-3.14.15/drivers/pci/host/pcie-designware.c linux-linaro-stable-mx6/drivers/pci/host/pcie-designware.c
  201805. --- linux-3.14.15/drivers/pci/host/pcie-designware.c 2014-07-31 23:51:43.000000000 +0200
  201806. +++ linux-linaro-stable-mx6/drivers/pci/host/pcie-designware.c 2014-08-20 19:31:47.236873762 +0200
  201807. @@ -23,48 +23,6 @@
  201808. #include "pcie-designware.h"
  201809. -/* Synopsis specific PCIE configuration registers */
  201810. -#define PCIE_PORT_LINK_CONTROL 0x710
  201811. -#define PORT_LINK_MODE_MASK (0x3f << 16)
  201812. -#define PORT_LINK_MODE_1_LANES (0x1 << 16)
  201813. -#define PORT_LINK_MODE_2_LANES (0x3 << 16)
  201814. -#define PORT_LINK_MODE_4_LANES (0x7 << 16)
  201815. -
  201816. -#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
  201817. -#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
  201818. -#define PORT_LOGIC_LINK_WIDTH_MASK (0x1ff << 8)
  201819. -#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
  201820. -#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
  201821. -#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
  201822. -
  201823. -#define PCIE_MSI_ADDR_LO 0x820
  201824. -#define PCIE_MSI_ADDR_HI 0x824
  201825. -#define PCIE_MSI_INTR0_ENABLE 0x828
  201826. -#define PCIE_MSI_INTR0_MASK 0x82C
  201827. -#define PCIE_MSI_INTR0_STATUS 0x830
  201828. -
  201829. -#define PCIE_ATU_VIEWPORT 0x900
  201830. -#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
  201831. -#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
  201832. -#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
  201833. -#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
  201834. -#define PCIE_ATU_CR1 0x904
  201835. -#define PCIE_ATU_TYPE_MEM (0x0 << 0)
  201836. -#define PCIE_ATU_TYPE_IO (0x2 << 0)
  201837. -#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
  201838. -#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
  201839. -#define PCIE_ATU_CR2 0x908
  201840. -#define PCIE_ATU_ENABLE (0x1 << 31)
  201841. -#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
  201842. -#define PCIE_ATU_LOWER_BASE 0x90C
  201843. -#define PCIE_ATU_UPPER_BASE 0x910
  201844. -#define PCIE_ATU_LIMIT 0x914
  201845. -#define PCIE_ATU_LOWER_TARGET 0x918
  201846. -#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
  201847. -#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
  201848. -#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
  201849. -#define PCIE_ATU_UPPER_TARGET 0x91C
  201850. -
  201851. static struct hw_pci dw_pci;
  201852. static unsigned long global_io_offset;
  201853. @@ -332,23 +290,28 @@
  201854. return -EINVAL;
  201855. }
  201856. - pci_read_config_word(pdev, desc->msi_attrib.pos+PCI_MSI_FLAGS,
  201857. - &msg_ctr);
  201858. - msgvec = (msg_ctr&PCI_MSI_FLAGS_QSIZE) >> 4;
  201859. - if (msgvec == 0)
  201860. - msgvec = (msg_ctr & PCI_MSI_FLAGS_QMASK) >> 1;
  201861. - if (msgvec > 5)
  201862. - msgvec = 0;
  201863. -
  201864. - irq = assign_irq((1 << msgvec), desc, &pos);
  201865. - if (irq < 0)
  201866. - return irq;
  201867. -
  201868. - /*
  201869. - * write_msi_msg() will update PCI_MSI_FLAGS so there is
  201870. - * no need to explicitly call pci_write_config_word().
  201871. - */
  201872. - desc->msi_attrib.multiple = msgvec;
  201873. + if (pp->quirks & DW_PCIE_QUIRK_NO_MSI_VEC) {
  201874. + irq = assign_irq(1, desc, &pos);
  201875. + set_irq_flags(irq, IRQF_VALID);
  201876. + } else {
  201877. + pci_read_config_word(pdev, desc->msi_attrib.pos+PCI_MSI_FLAGS,
  201878. + &msg_ctr);
  201879. + msgvec = (msg_ctr&PCI_MSI_FLAGS_QSIZE) >> 4;
  201880. + if (msgvec == 0)
  201881. + msgvec = (msg_ctr & PCI_MSI_FLAGS_QMASK) >> 1;
  201882. + if (msgvec > 5)
  201883. + msgvec = 0;
  201884. +
  201885. + irq = assign_irq((1 << msgvec), desc, &pos);
  201886. + if (irq < 0)
  201887. + return irq;
  201888. +
  201889. + msg_ctr &= ~PCI_MSI_FLAGS_QSIZE;
  201890. + msg_ctr |= msgvec << 4;
  201891. + pci_write_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
  201892. + msg_ctr);
  201893. + desc->msi_attrib.multiple = msgvec;
  201894. + }
  201895. msg.address_lo = virt_to_phys((void *)pp->msi_data);
  201896. msg.address_hi = 0x0;
  201897. @@ -363,9 +326,30 @@
  201898. clear_irq(irq);
  201899. }
  201900. +static int dw_msi_check_device(struct msi_chip *chip, struct pci_dev *pdev,
  201901. + int nvec, int type)
  201902. +{
  201903. + struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
  201904. + u32 val;
  201905. +
  201906. + if (pp->quirks & DW_PCIE_QUIRK_MSI_SELF_EN) {
  201907. + if ((type == PCI_CAP_ID_MSI) || (type == PCI_CAP_ID_MSIX)) {
  201908. + /* Set MSI enable of RC here */
  201909. + val = readl(pp->dbi_base + 0x50);
  201910. + if ((val & (PCI_MSI_FLAGS_ENABLE << 16)) == 0) {
  201911. + val |= PCI_MSI_FLAGS_ENABLE << 16;
  201912. + writel(val, pp->dbi_base + 0x50);
  201913. + }
  201914. + }
  201915. + }
  201916. +
  201917. + return 0;
  201918. +}
  201919. +
  201920. static struct msi_chip dw_pcie_msi_chip = {
  201921. .setup_irq = dw_msi_setup_irq,
  201922. .teardown_irq = dw_msi_teardown_irq,
  201923. + .check_device = dw_msi_check_device,
  201924. };
  201925. int dw_pcie_link_up(struct pcie_port *pp)
  201926. @@ -531,38 +515,6 @@
  201927. dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
  201928. }
  201929. -static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
  201930. -{
  201931. - /* Program viewport 0 : OUTBOUND : MEM */
  201932. - dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
  201933. - PCIE_ATU_VIEWPORT);
  201934. - dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
  201935. - dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE);
  201936. - dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE);
  201937. - dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1,
  201938. - PCIE_ATU_LIMIT);
  201939. - dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET);
  201940. - dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
  201941. - PCIE_ATU_UPPER_TARGET);
  201942. - dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
  201943. -}
  201944. -
  201945. -static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
  201946. -{
  201947. - /* Program viewport 1 : OUTBOUND : IO */
  201948. - dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
  201949. - PCIE_ATU_VIEWPORT);
  201950. - dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1);
  201951. - dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE);
  201952. - dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE);
  201953. - dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1,
  201954. - PCIE_ATU_LIMIT);
  201955. - dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET);
  201956. - dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
  201957. - PCIE_ATU_UPPER_TARGET);
  201958. - dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
  201959. -}
  201960. -
  201961. static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
  201962. u32 devfn, int where, int size, u32 *val)
  201963. {
  201964. @@ -577,12 +529,10 @@
  201965. dw_pcie_prog_viewport_cfg0(pp, busdev);
  201966. ret = dw_pcie_cfg_read(pp->va_cfg0_base + address, where, size,
  201967. val);
  201968. - dw_pcie_prog_viewport_mem_outbound(pp);
  201969. } else {
  201970. dw_pcie_prog_viewport_cfg1(pp, busdev);
  201971. ret = dw_pcie_cfg_read(pp->va_cfg1_base + address, where, size,
  201972. val);
  201973. - dw_pcie_prog_viewport_io_outbound(pp);
  201974. }
  201975. return ret;
  201976. @@ -602,12 +552,10 @@
  201977. dw_pcie_prog_viewport_cfg0(pp, busdev);
  201978. ret = dw_pcie_cfg_write(pp->va_cfg0_base + address, where, size,
  201979. val);
  201980. - dw_pcie_prog_viewport_mem_outbound(pp);
  201981. } else {
  201982. dw_pcie_prog_viewport_cfg1(pp, busdev);
  201983. ret = dw_pcie_cfg_write(pp->va_cfg1_base + address, where, size,
  201984. val);
  201985. - dw_pcie_prog_viewport_io_outbound(pp);
  201986. }
  201987. return ret;
  201988. @@ -739,7 +687,13 @@
  201989. {
  201990. struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
  201991. - return pp->irq;
  201992. + switch (pin) {
  201993. + case 1: return pp->irq;
  201994. + case 2: return pp->irq - 1;
  201995. + case 3: return pp->irq - 2;
  201996. + case 4: return pp->irq - 3;
  201997. + default: return -1;
  201998. + }
  201999. }
  202000. static void dw_pcie_add_bus(struct pci_bus *bus)
  202001. diff -Nur linux-3.14.15/drivers/pci/host/pcie-designware.h linux-linaro-stable-mx6/drivers/pci/host/pcie-designware.h
  202002. --- linux-3.14.15/drivers/pci/host/pcie-designware.h 2014-07-31 23:51:43.000000000 +0200
  202003. +++ linux-linaro-stable-mx6/drivers/pci/host/pcie-designware.h 2014-08-20 19:31:47.236873762 +0200
  202004. @@ -14,6 +14,48 @@
  202005. #ifndef _PCIE_DESIGNWARE_H
  202006. #define _PCIE_DESIGNWARE_H
  202007. +/* Synopsis specific PCIE configuration registers */
  202008. +#define PCIE_PORT_LINK_CONTROL 0x710
  202009. +#define PORT_LINK_MODE_MASK (0x3f << 16)
  202010. +#define PORT_LINK_MODE_1_LANES (0x1 << 16)
  202011. +#define PORT_LINK_MODE_2_LANES (0x3 << 16)
  202012. +#define PORT_LINK_MODE_4_LANES (0x7 << 16)
  202013. +
  202014. +#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
  202015. +#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
  202016. +#define PORT_LOGIC_LINK_WIDTH_MASK (0x1ff << 8)
  202017. +#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
  202018. +#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
  202019. +#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
  202020. +
  202021. +#define PCIE_MSI_ADDR_LO 0x820
  202022. +#define PCIE_MSI_ADDR_HI 0x824
  202023. +#define PCIE_MSI_INTR0_ENABLE 0x828
  202024. +#define PCIE_MSI_INTR0_MASK 0x82C
  202025. +#define PCIE_MSI_INTR0_STATUS 0x830
  202026. +
  202027. +#define PCIE_ATU_VIEWPORT 0x900
  202028. +#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
  202029. +#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
  202030. +#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
  202031. +#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
  202032. +#define PCIE_ATU_CR1 0x904
  202033. +#define PCIE_ATU_TYPE_MEM (0x0 << 0)
  202034. +#define PCIE_ATU_TYPE_IO (0x2 << 0)
  202035. +#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
  202036. +#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
  202037. +#define PCIE_ATU_CR2 0x908
  202038. +#define PCIE_ATU_ENABLE (0x1 << 31)
  202039. +#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
  202040. +#define PCIE_ATU_LOWER_BASE 0x90C
  202041. +#define PCIE_ATU_UPPER_BASE 0x910
  202042. +#define PCIE_ATU_LIMIT 0x914
  202043. +#define PCIE_ATU_LOWER_TARGET 0x918
  202044. +#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
  202045. +#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
  202046. +#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
  202047. +#define PCIE_ATU_UPPER_TARGET 0x91C
  202048. +
  202049. struct pcie_port_info {
  202050. u32 cfg0_size;
  202051. u32 cfg1_size;
  202052. @@ -49,6 +91,11 @@
  202053. int irq;
  202054. u32 lanes;
  202055. struct pcie_host_ops *ops;
  202056. + u32 quirks; /* Deviations from spec. */
  202057. +/* Controller doesn't support MSI VEC */
  202058. +#define DW_PCIE_QUIRK_NO_MSI_VEC (1<<0)
  202059. +/* MSI EN of Controller should be configured when MSI is enabled */
  202060. +#define DW_PCIE_QUIRK_MSI_SELF_EN (1<<1)
  202061. int msi_irq;
  202062. struct irq_domain *irq_domain;
  202063. unsigned long msi_data;
  202064. diff -Nur linux-3.14.15/drivers/pci/host/pci-imx6.c linux-linaro-stable-mx6/drivers/pci/host/pci-imx6.c
  202065. --- linux-3.14.15/drivers/pci/host/pci-imx6.c 2014-07-31 23:51:43.000000000 +0200
  202066. +++ linux-linaro-stable-mx6/drivers/pci/host/pci-imx6.c 2014-08-20 19:31:47.228873726 +0200
  202067. @@ -1,6 +1,7 @@
  202068. /*
  202069. * PCIe host controller driver for Freescale i.MX6 SoCs
  202070. *
  202071. + * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  202072. * Copyright (C) 2013 Kosagi
  202073. * http://www.kosagi.com
  202074. *
  202075. @@ -14,6 +15,7 @@
  202076. #include <linux/clk.h>
  202077. #include <linux/delay.h>
  202078. #include <linux/gpio.h>
  202079. +#include <linux/interrupt.h>
  202080. #include <linux/kernel.h>
  202081. #include <linux/mfd/syscon.h>
  202082. #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  202083. @@ -25,11 +27,21 @@
  202084. #include <linux/resource.h>
  202085. #include <linux/signal.h>
  202086. #include <linux/types.h>
  202087. +#include <linux/busfreq-imx6.h>
  202088. #include "pcie-designware.h"
  202089. #define to_imx6_pcie(x) container_of(x, struct imx6_pcie, pp)
  202090. +/*
  202091. + * The default value of the reserved ddr memory
  202092. + * used to verify EP/RC memory space access operations.
  202093. + * BTW, here is the layout of the 1G ddr on SD boards
  202094. + * 0x1000_0000 ~ 0x4FFF_FFFF
  202095. + */
  202096. +static u32 ddr_test_region = 0x40000000;
  202097. +static u32 test_region_size = SZ_2M;
  202098. +
  202099. struct imx6_pcie {
  202100. int reset_gpio;
  202101. int power_on_gpio;
  202102. @@ -214,18 +226,6 @@
  202103. return 0;
  202104. }
  202105. -static int imx6_pcie_assert_core_reset(struct pcie_port *pp)
  202106. -{
  202107. - struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
  202108. -
  202109. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  202110. - IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
  202111. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  202112. - IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
  202113. -
  202114. - return 0;
  202115. -}
  202116. -
  202117. static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
  202118. {
  202119. struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
  202120. @@ -238,6 +238,7 @@
  202121. IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
  202122. regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  202123. IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
  202124. + request_bus_freq(BUS_FREQ_HIGH);
  202125. ret = clk_prepare_enable(imx6_pcie->sata_ref_100m);
  202126. if (ret) {
  202127. @@ -251,10 +252,13 @@
  202128. goto err_pcie_ref;
  202129. }
  202130. - ret = clk_prepare_enable(imx6_pcie->lvds_gate);
  202131. - if (ret) {
  202132. - dev_err(pp->dev, "unable to enable lvds_gate\n");
  202133. - goto err_lvds_gate;
  202134. + if (!IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)
  202135. + && !IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS)) {
  202136. + ret = clk_prepare_enable(imx6_pcie->lvds_gate);
  202137. + if (ret) {
  202138. + dev_err(pp->dev, "unable to enable lvds_gate\n");
  202139. + goto err_lvds_gate;
  202140. + }
  202141. }
  202142. ret = clk_prepare_enable(imx6_pcie->pcie_axi);
  202143. @@ -281,6 +285,7 @@
  202144. err_pcie_ref:
  202145. clk_disable_unprepare(imx6_pcie->sata_ref_100m);
  202146. err_sata_ref:
  202147. + release_bus_freq(BUS_FREQ_HIGH);
  202148. return ret;
  202149. }
  202150. @@ -293,8 +298,14 @@
  202151. IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
  202152. /* configure constant input signal to the pcie ctrl and phy */
  202153. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202154. - IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12);
  202155. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS))
  202156. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202157. + IMX6Q_GPR12_DEVICE_TYPE,
  202158. + PCI_EXP_TYPE_ENDPOINT << 12);
  202159. + else
  202160. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202161. + IMX6Q_GPR12_DEVICE_TYPE,
  202162. + PCI_EXP_TYPE_ROOT_PORT << 12);
  202163. regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202164. IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
  202165. @@ -312,6 +323,7 @@
  202166. static int imx6_pcie_wait_for_link(struct pcie_port *pp)
  202167. {
  202168. + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
  202169. int count = 200;
  202170. while (!dw_pcie_link_up(pp)) {
  202171. @@ -326,6 +338,18 @@
  202172. return -EINVAL;
  202173. }
  202174. + if (IS_ENABLED(CONFIG_PCI_MSI)) {
  202175. + pp->quirks |= DW_PCIE_QUIRK_NO_MSI_VEC;
  202176. + pp->quirks |= DW_PCIE_QUIRK_MSI_SELF_EN;
  202177. + dw_pcie_msi_init(pp);
  202178. + }
  202179. +
  202180. + if (gpio_is_valid(imx6_pcie->reset_gpio)) {
  202181. + gpio_set_value(imx6_pcie->reset_gpio, 0);
  202182. + msleep(100);
  202183. + gpio_set_value(imx6_pcie->reset_gpio, 1);
  202184. + }
  202185. +
  202186. return 0;
  202187. }
  202188. @@ -392,10 +416,17 @@
  202189. return ret;
  202190. }
  202191. -static void imx6_pcie_host_init(struct pcie_port *pp)
  202192. +static irqreturn_t imx_pcie_msi_irq_handler(int irq, void *arg)
  202193. {
  202194. - imx6_pcie_assert_core_reset(pp);
  202195. + struct pcie_port *pp = arg;
  202196. +
  202197. + dw_handle_msi_irq(pp);
  202198. + return IRQ_HANDLED;
  202199. +}
  202200. +
  202201. +static void imx6_pcie_host_init(struct pcie_port *pp)
  202202. +{
  202203. imx6_pcie_init_phy(pp);
  202204. imx6_pcie_deassert_core_reset(pp);
  202205. @@ -498,6 +529,22 @@
  202206. return -ENODEV;
  202207. }
  202208. + if (IS_ENABLED(CONFIG_PCI_MSI)) {
  202209. + pp->msi_irq = pp->irq - 3;
  202210. + if (!pp->msi_irq) {
  202211. + dev_err(&pdev->dev, "failed to get msi irq\n");
  202212. + return -ENODEV;
  202213. + }
  202214. +
  202215. + ret = devm_request_irq(&pdev->dev, pp->msi_irq,
  202216. + imx_pcie_msi_irq_handler,
  202217. + IRQF_SHARED, "imx6q-pcie", pp);
  202218. + if (ret) {
  202219. + dev_err(&pdev->dev, "failed to request msi irq\n");
  202220. + return ret;
  202221. + }
  202222. + }
  202223. +
  202224. pp->root_bus_nr = -1;
  202225. pp->ops = &imx6_pcie_host_ops;
  202226. @@ -511,29 +558,188 @@
  202227. return 0;
  202228. }
  202229. +static ssize_t imx_pcie_bar0_addr_info(struct device *dev,
  202230. + struct device_attribute *devattr, char *buf)
  202231. +{
  202232. + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
  202233. + struct pcie_port *pp = &imx6_pcie->pp;
  202234. +
  202235. + return sprintf(buf, "imx-pcie-bar0-addr-info start 0x%08x\n",
  202236. + readl(pp->dbi_base + PCI_BASE_ADDRESS_0));
  202237. +}
  202238. +
  202239. +static ssize_t imx_pcie_bar0_addr_start(struct device *dev,
  202240. + struct device_attribute *attr, const char *buf, size_t count)
  202241. +{
  202242. + u32 bar_start;
  202243. + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
  202244. + struct pcie_port *pp = &imx6_pcie->pp;
  202245. +
  202246. + sscanf(buf, "%x\n", &bar_start);
  202247. + writel(bar_start, pp->dbi_base + PCI_BASE_ADDRESS_0);
  202248. +
  202249. + return count;
  202250. +}
  202251. +
  202252. +static void imx_pcie_regions_setup(struct device *dev)
  202253. +{
  202254. + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
  202255. + struct pcie_port *pp = &imx6_pcie->pp;
  202256. +
  202257. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
  202258. + /*
  202259. + * region2 outbound used to access rc mem
  202260. + * in imx6 pcie ep/rc validation system
  202261. + */
  202262. + writel(0, pp->dbi_base + PCIE_ATU_VIEWPORT);
  202263. + writel(0x01000000, pp->dbi_base + PCIE_ATU_LOWER_BASE);
  202264. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_BASE);
  202265. + writel(0x01000000 + test_region_size,
  202266. + pp->dbi_base + PCIE_ATU_LIMIT);
  202267. +
  202268. + writel(ddr_test_region,
  202269. + pp->dbi_base + PCIE_ATU_LOWER_TARGET);
  202270. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_TARGET);
  202271. + writel(PCIE_ATU_TYPE_MEM, pp->dbi_base + PCIE_ATU_CR1);
  202272. + writel(PCIE_ATU_ENABLE, pp->dbi_base + PCIE_ATU_CR2);
  202273. + }
  202274. +
  202275. + if (IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS)) {
  202276. + /*
  202277. + * region2 outbound used to access ep mem
  202278. + * in imx6 pcie ep/rc validation system
  202279. + */
  202280. + writel(2, pp->dbi_base + PCIE_ATU_VIEWPORT);
  202281. + writel(0x01000000, pp->dbi_base + PCIE_ATU_LOWER_BASE);
  202282. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_BASE);
  202283. + writel(0x01000000 + test_region_size,
  202284. + pp->dbi_base + PCIE_ATU_LIMIT);
  202285. +
  202286. + writel(ddr_test_region,
  202287. + pp->dbi_base + PCIE_ATU_LOWER_TARGET);
  202288. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_TARGET);
  202289. + writel(PCIE_ATU_TYPE_MEM, pp->dbi_base + PCIE_ATU_CR1);
  202290. + writel(PCIE_ATU_ENABLE, pp->dbi_base + PCIE_ATU_CR2);
  202291. + }
  202292. +}
  202293. +
  202294. +static ssize_t imx_pcie_memw_info(struct device *dev,
  202295. + struct device_attribute *devattr, char *buf)
  202296. +{
  202297. + return sprintf(buf, "imx-pcie-rc-memw-info start 0x%08x, size 0x%08x\n",
  202298. + ddr_test_region, test_region_size);
  202299. +}
  202300. +
  202301. +static ssize_t
  202302. +imx_pcie_memw_start(struct device *dev, struct device_attribute *attr,
  202303. + const char *buf, size_t count)
  202304. +{
  202305. + u32 memw_start;
  202306. +
  202307. + sscanf(buf, "%x\n", &memw_start);
  202308. +
  202309. + if (memw_start < 0x10000000) {
  202310. + dev_err(dev, "Invalid memory start address.\n");
  202311. + dev_info(dev, "For example: echo 0x41000000 > /sys/...");
  202312. + return -1;
  202313. + }
  202314. +
  202315. + if (ddr_test_region != memw_start) {
  202316. + ddr_test_region = memw_start;
  202317. + /* Re-setup the iATU */
  202318. + imx_pcie_regions_setup(dev);
  202319. + }
  202320. +
  202321. + return count;
  202322. +}
  202323. +
  202324. +static ssize_t
  202325. +imx_pcie_memw_size(struct device *dev, struct device_attribute *attr,
  202326. + const char *buf, size_t count)
  202327. +{
  202328. + u32 memw_size;
  202329. +
  202330. + sscanf(buf, "%x\n", &memw_size);
  202331. +
  202332. + if ((memw_size > (SZ_16M - SZ_1M)) || (memw_size < SZ_64K)) {
  202333. + dev_err(dev, "Invalid, should be [SZ_64K,SZ_16M - SZ_1MB].\n");
  202334. + dev_info(dev, "For example: echo 0x800000 > /sys/...");
  202335. + return -1;
  202336. + }
  202337. +
  202338. + if (test_region_size != memw_size) {
  202339. + test_region_size = memw_size;
  202340. + /* Re-setup the iATU */
  202341. + imx_pcie_regions_setup(dev);
  202342. + }
  202343. +
  202344. + return count;
  202345. +}
  202346. +
  202347. +static DEVICE_ATTR(memw_info, S_IRUGO, imx_pcie_memw_info, NULL);
  202348. +static DEVICE_ATTR(memw_start_set, S_IWUGO, NULL, imx_pcie_memw_start);
  202349. +static DEVICE_ATTR(memw_size_set, S_IWUGO, NULL, imx_pcie_memw_size);
  202350. +static DEVICE_ATTR(ep_bar0_addr, S_IRWXUGO, imx_pcie_bar0_addr_info,
  202351. + imx_pcie_bar0_addr_start);
  202352. +
  202353. +static struct attribute *imx_pcie_attrs[] = {
  202354. + /*
  202355. + * The start address, and the limitation (64KB ~ (16MB - 1MB))
  202356. + * of the ddr mem window reserved by RC, and used for EP to access.
  202357. + * BTW, these attrs are only configured at EP side.
  202358. + */
  202359. + &dev_attr_memw_info.attr,
  202360. + &dev_attr_memw_start_set.attr,
  202361. + &dev_attr_memw_size_set.attr,
  202362. + &dev_attr_ep_bar0_addr.attr,
  202363. + NULL
  202364. +};
  202365. +
  202366. +static struct attribute_group imx_pcie_attrgroup = {
  202367. + .attrs = imx_pcie_attrs,
  202368. +};
  202369. +
  202370. static int __init imx6_pcie_probe(struct platform_device *pdev)
  202371. {
  202372. struct imx6_pcie *imx6_pcie;
  202373. struct pcie_port *pp;
  202374. struct device_node *np = pdev->dev.of_node;
  202375. struct resource *dbi_base;
  202376. - int ret;
  202377. + int ret = 0;
  202378. + int i;
  202379. + void *test_reg1, *test_reg2;
  202380. + void __iomem *pcie_arb_base_addr;
  202381. + struct timeval tv1, tv2, tv3;
  202382. + u32 tv_count1, tv_count2;
  202383. imx6_pcie = devm_kzalloc(&pdev->dev, sizeof(*imx6_pcie), GFP_KERNEL);
  202384. - if (!imx6_pcie)
  202385. - return -ENOMEM;
  202386. + if (!imx6_pcie) {
  202387. + ret = -ENOMEM;
  202388. + goto err;
  202389. + }
  202390. pp = &imx6_pcie->pp;
  202391. pp->dev = &pdev->dev;
  202392. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
  202393. + /* add attributes for device */
  202394. + ret = sysfs_create_group(&pdev->dev.kobj, &imx_pcie_attrgroup);
  202395. + if (ret) {
  202396. + ret = -EINVAL;
  202397. + goto err;
  202398. + }
  202399. + }
  202400. +
  202401. /* Added for PCI abort handling */
  202402. hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0,
  202403. "imprecise external abort");
  202404. dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  202405. pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base);
  202406. - if (IS_ERR(pp->dbi_base))
  202407. - return PTR_ERR(pp->dbi_base);
  202408. + if (IS_ERR(pp->dbi_base)) {
  202409. + ret = PTR_ERR(pp->dbi_base);
  202410. + goto err;
  202411. + }
  202412. /* Fetch GPIOs */
  202413. imx6_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
  202414. @@ -542,7 +748,7 @@
  202415. GPIOF_OUT_INIT_LOW, "PCIe reset");
  202416. if (ret) {
  202417. dev_err(&pdev->dev, "unable to get reset gpio\n");
  202418. - return ret;
  202419. + goto err;
  202420. }
  202421. }
  202422. @@ -554,7 +760,7 @@
  202423. "PCIe power enable");
  202424. if (ret) {
  202425. dev_err(&pdev->dev, "unable to get power-on gpio\n");
  202426. - return ret;
  202427. + goto err;
  202428. }
  202429. }
  202430. @@ -566,7 +772,7 @@
  202431. "PCIe wake up");
  202432. if (ret) {
  202433. dev_err(&pdev->dev, "unable to get wake-up gpio\n");
  202434. - return ret;
  202435. + goto err;
  202436. }
  202437. }
  202438. @@ -578,7 +784,7 @@
  202439. "PCIe disable endpoint");
  202440. if (ret) {
  202441. dev_err(&pdev->dev, "unable to get disable-ep gpio\n");
  202442. - return ret;
  202443. + goto err;
  202444. }
  202445. }
  202446. @@ -587,28 +793,32 @@
  202447. if (IS_ERR(imx6_pcie->lvds_gate)) {
  202448. dev_err(&pdev->dev,
  202449. "lvds_gate clock select missing or invalid\n");
  202450. - return PTR_ERR(imx6_pcie->lvds_gate);
  202451. + ret = PTR_ERR(imx6_pcie->lvds_gate);
  202452. + goto err;
  202453. }
  202454. imx6_pcie->sata_ref_100m = devm_clk_get(&pdev->dev, "sata_ref_100m");
  202455. if (IS_ERR(imx6_pcie->sata_ref_100m)) {
  202456. dev_err(&pdev->dev,
  202457. "sata_ref_100m clock source missing or invalid\n");
  202458. - return PTR_ERR(imx6_pcie->sata_ref_100m);
  202459. + ret = PTR_ERR(imx6_pcie->sata_ref_100m);
  202460. + goto err;
  202461. }
  202462. imx6_pcie->pcie_ref_125m = devm_clk_get(&pdev->dev, "pcie_ref_125m");
  202463. if (IS_ERR(imx6_pcie->pcie_ref_125m)) {
  202464. dev_err(&pdev->dev,
  202465. "pcie_ref_125m clock source missing or invalid\n");
  202466. - return PTR_ERR(imx6_pcie->pcie_ref_125m);
  202467. + ret = PTR_ERR(imx6_pcie->pcie_ref_125m);
  202468. + goto err;
  202469. }
  202470. imx6_pcie->pcie_axi = devm_clk_get(&pdev->dev, "pcie_axi");
  202471. if (IS_ERR(imx6_pcie->pcie_axi)) {
  202472. dev_err(&pdev->dev,
  202473. "pcie_axi clock source missing or invalid\n");
  202474. - return PTR_ERR(imx6_pcie->pcie_axi);
  202475. + ret = PTR_ERR(imx6_pcie->pcie_axi);
  202476. + goto err;
  202477. }
  202478. /* Grab GPR config register range */
  202479. @@ -616,15 +826,167 @@
  202480. syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  202481. if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
  202482. dev_err(&pdev->dev, "unable to find iomuxc registers\n");
  202483. - return PTR_ERR(imx6_pcie->iomuxc_gpr);
  202484. + ret = PTR_ERR(imx6_pcie->iomuxc_gpr);
  202485. + goto err;
  202486. }
  202487. - ret = imx6_add_pcie_port(pp, pdev);
  202488. - if (ret < 0)
  202489. - return ret;
  202490. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
  202491. + if (IS_ENABLED(CONFIG_EP_SELF_IO_TEST)) {
  202492. + /* Prepare the test regions and data */
  202493. + test_reg1 = devm_kzalloc(&pdev->dev,
  202494. + test_region_size, GFP_KERNEL);
  202495. + if (!test_reg1) {
  202496. + pr_err("pcie ep: can't alloc the test reg1.\n");
  202497. + ret = PTR_ERR(test_reg1);
  202498. + goto err;
  202499. + }
  202500. +
  202501. + test_reg2 = devm_kzalloc(&pdev->dev,
  202502. + test_region_size, GFP_KERNEL);
  202503. + if (!test_reg2) {
  202504. + pr_err("pcie ep: can't alloc the test reg2.\n");
  202505. + ret = PTR_ERR(test_reg1);
  202506. + goto err;
  202507. + }
  202508. +
  202509. + pcie_arb_base_addr = ioremap_cache(0x01000000,
  202510. + test_region_size);
  202511. +
  202512. + if (!pcie_arb_base_addr) {
  202513. + pr_err("error with ioremap in ep selftest\n");
  202514. + ret = PTR_ERR(pcie_arb_base_addr);
  202515. + goto err;
  202516. + }
  202517. +
  202518. + for (i = 0; i < test_region_size; i = i + 4) {
  202519. + writel(0xE6600D00 + i, test_reg1 + i);
  202520. + writel(0xDEADBEAF, test_reg2 + i);
  202521. + }
  202522. + }
  202523. - platform_set_drvdata(pdev, imx6_pcie);
  202524. - return 0;
  202525. + imx6_pcie_init_phy(pp);
  202526. +
  202527. + imx6_pcie_deassert_core_reset(pp);
  202528. +
  202529. + /* assert LTSSM enable */
  202530. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202531. + IMX6Q_GPR12_PCIE_CTL_2, 1 << 10);
  202532. +
  202533. +
  202534. + dev_info(&pdev->dev, "PCIe EP: waiting for link up...\n");
  202535. +
  202536. + platform_set_drvdata(pdev, imx6_pcie);
  202537. + /* link is indicated by the bit4 of DB_R1 register */
  202538. + do {
  202539. + usleep_range(10, 20);
  202540. + } while ((readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & 0x10) == 0);
  202541. +
  202542. + /* CMD reg:I/O space, MEM space, and Bus Master Enable */
  202543. + writel(readl(pp->dbi_base + PCI_COMMAND)
  202544. + | PCI_COMMAND_IO
  202545. + | PCI_COMMAND_MEMORY
  202546. + | PCI_COMMAND_MASTER,
  202547. + pp->dbi_base + PCI_COMMAND);
  202548. +
  202549. + /*
  202550. + * configure the class_rev(emaluate one memory ram ep device),
  202551. + * bar0 and bar1 of ep
  202552. + */
  202553. + writel(0xdeadbeaf, pp->dbi_base + PCI_VENDOR_ID);
  202554. + writel(readl(pp->dbi_base + PCI_CLASS_REVISION)
  202555. + | (PCI_CLASS_MEMORY_RAM << 16),
  202556. + pp->dbi_base + PCI_CLASS_REVISION);
  202557. + writel(0xdeadbeaf, pp->dbi_base
  202558. + + PCI_SUBSYSTEM_VENDOR_ID);
  202559. +
  202560. + /* 32bit none-prefetchable 8M bytes memory on bar0 */
  202561. + writel(0x0, pp->dbi_base + PCI_BASE_ADDRESS_0);
  202562. + writel(SZ_8M - 1, pp->dbi_base + (1 << 12)
  202563. + + PCI_BASE_ADDRESS_0);
  202564. +
  202565. + /* None used bar1 */
  202566. + writel(0x0, pp->dbi_base + PCI_BASE_ADDRESS_1);
  202567. + writel(0, pp->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_1);
  202568. +
  202569. + /* 4K bytes IO on bar2 */
  202570. + writel(0x1, pp->dbi_base + PCI_BASE_ADDRESS_2);
  202571. + writel(SZ_4K - 1, pp->dbi_base + (1 << 12) +
  202572. + PCI_BASE_ADDRESS_2);
  202573. +
  202574. + /*
  202575. + * 32bit prefetchable 1M bytes memory on bar3
  202576. + * FIXME BAR MASK3 is not changable, the size
  202577. + * is fixed to 256 bytes.
  202578. + */
  202579. + writel(0x8, pp->dbi_base + PCI_BASE_ADDRESS_3);
  202580. + writel(SZ_1M - 1, pp->dbi_base + (1 << 12)
  202581. + + PCI_BASE_ADDRESS_3);
  202582. +
  202583. + /*
  202584. + * 64bit prefetchable 1M bytes memory on bar4-5.
  202585. + * FIXME BAR4,5 are not enabled yet
  202586. + */
  202587. + writel(0xc, pp->dbi_base + PCI_BASE_ADDRESS_4);
  202588. + writel(SZ_1M - 1, pp->dbi_base + (1 << 12)
  202589. + + PCI_BASE_ADDRESS_4);
  202590. + writel(0, pp->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_5);
  202591. +
  202592. + /* Re-setup the iATU */
  202593. + imx_pcie_regions_setup(&pdev->dev);
  202594. +
  202595. + if (IS_ENABLED(CONFIG_EP_SELF_IO_TEST)) {
  202596. + /* PCIe EP start the data transfer after link up */
  202597. + pr_info("pcie ep: Starting data transfer...\n");
  202598. + do_gettimeofday(&tv1);
  202599. +
  202600. + memcpy((unsigned long *)pcie_arb_base_addr,
  202601. + (unsigned long *)test_reg1,
  202602. + test_region_size);
  202603. +
  202604. + do_gettimeofday(&tv2);
  202605. +
  202606. + memcpy((unsigned long *)test_reg2,
  202607. + (unsigned long *)pcie_arb_base_addr,
  202608. + test_region_size);
  202609. +
  202610. + do_gettimeofday(&tv3);
  202611. +
  202612. + if (memcmp(test_reg2, test_reg1, test_region_size) == 0) {
  202613. + tv_count1 = (tv2.tv_sec - tv1.tv_sec)
  202614. + * USEC_PER_SEC
  202615. + + tv2.tv_usec - tv1.tv_usec;
  202616. + tv_count2 = (tv3.tv_sec - tv2.tv_sec)
  202617. + * USEC_PER_SEC
  202618. + + tv3.tv_usec - tv2.tv_usec;
  202619. +
  202620. + pr_info("pcie ep: Data transfer is successful."
  202621. + " tv_count1 %dus,"
  202622. + " tv_count2 %dus.\n",
  202623. + tv_count1, tv_count2);
  202624. + pr_info("pcie ep: Data write speed:%ldMB/s.\n",
  202625. + ((test_region_size/1024)
  202626. + * MSEC_PER_SEC)
  202627. + /(tv_count1));
  202628. + pr_info("pcie ep: Data read speed:%ldMB/s.\n",
  202629. + ((test_region_size/1024)
  202630. + * MSEC_PER_SEC)
  202631. + /(tv_count2));
  202632. + } else {
  202633. + pr_info("pcie ep: Data transfer is failed.\n");
  202634. + }
  202635. + }
  202636. + } else {
  202637. + ret = imx6_add_pcie_port(pp, pdev);
  202638. + if (ret < 0)
  202639. + goto err;
  202640. + platform_set_drvdata(pdev, imx6_pcie);
  202641. +
  202642. + /* Re-setup the iATU */
  202643. + imx_pcie_regions_setup(&pdev->dev);
  202644. + }
  202645. +
  202646. +err:
  202647. + return ret;
  202648. }
  202649. static const struct of_device_id imx6_pcie_of_match[] = {
  202650. diff -Nur linux-3.14.15/drivers/pci/host/pci-imx6-ep-driver.c linux-linaro-stable-mx6/drivers/pci/host/pci-imx6-ep-driver.c
  202651. --- linux-3.14.15/drivers/pci/host/pci-imx6-ep-driver.c 1970-01-01 01:00:00.000000000 +0100
  202652. +++ linux-linaro-stable-mx6/drivers/pci/host/pci-imx6-ep-driver.c 2014-08-20 19:31:47.132873314 +0200
  202653. @@ -0,0 +1,159 @@
  202654. +/*
  202655. + * PCIe endpoint skeleton driver for IMX6 SOCs
  202656. + *
  202657. + * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  202658. + *
  202659. + * This program is free software; you can redistribute it and/or modify
  202660. + * it under the terms of the GNU General Public License as published by
  202661. + * the Free Software Foundation; either version 2 of the License, or
  202662. + * (at your option) any later version.
  202663. +
  202664. + * This program is distributed in the hope that it will be useful,
  202665. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  202666. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  202667. + * GNU General Public License for more details.
  202668. +
  202669. + * You should have received a copy of the GNU General Public License along
  202670. + * with this program; if not, write to the Free Software Foundation, Inc.,
  202671. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  202672. + */
  202673. +
  202674. +#include <linux/kernel.h>
  202675. +#include <linux/module.h>
  202676. +#include <linux/init.h>
  202677. +#include <linux/pci.h>
  202678. +#include <linux/pci-aspm.h>
  202679. +#include <linux/slab.h>
  202680. +#include <linux/dma-mapping.h>
  202681. +#include <linux/delay.h>
  202682. +#include <linux/sched.h>
  202683. +#include <linux/interrupt.h>
  202684. +
  202685. +#define DRV_DESCRIPTION "i.MX PCIE endpoint device driver"
  202686. +#define DRV_VERSION "version 0.1"
  202687. +#define DRV_NAME "imx_pcie_ep"
  202688. +
  202689. +struct imx_pcie_ep_priv {
  202690. + struct pci_dev *pci_dev;
  202691. + void __iomem *hw_base;
  202692. +};
  202693. +
  202694. +/**
  202695. + * imx_pcie_ep_probe - Device Initialization Routine
  202696. + * @pdev: PCI device information struct
  202697. + * @id: entry in id_tbl
  202698. + *
  202699. + * Returns 0 on success, negative on failure
  202700. + **/
  202701. +static int imx_pcie_ep_probe(struct pci_dev *pdev,
  202702. + const struct pci_device_id *id)
  202703. +{
  202704. + int ret = 0;
  202705. + struct device *dev = &pdev->dev;
  202706. + struct imx_pcie_ep_priv *priv;
  202707. +
  202708. + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  202709. + if (!priv) {
  202710. + dev_err(dev, "can't alloc imx pcie priv\n");
  202711. + return -ENOMEM;
  202712. + }
  202713. +
  202714. + priv->pci_dev = pdev;
  202715. +
  202716. + if (pci_enable_device(pdev)) {
  202717. + ret = -ENODEV;
  202718. + goto out;
  202719. + }
  202720. + pci_set_master(pdev);
  202721. +
  202722. + pci_set_drvdata(pdev, priv);
  202723. +
  202724. + priv->hw_base = pci_iomap(pdev, 0, 0);
  202725. + if (!priv->hw_base) {
  202726. + ret = -ENODEV;
  202727. + goto out;
  202728. + }
  202729. +
  202730. + pr_info("pci_resource_len = 0x%08llx\n",
  202731. + (unsigned long long) pci_resource_len(pdev, 0));
  202732. + pr_info("pci_resource_base = %p\n", priv->hw_base);
  202733. +
  202734. + ret = pci_enable_msi(priv->pci_dev);
  202735. + if (ret < 0) {
  202736. + dev_err(dev, "can't enable msi\n");
  202737. + return ret;
  202738. + }
  202739. +
  202740. + /*
  202741. + * Force to use 0x01FF8000 as the MSI address,
  202742. + * to do the MSI demo
  202743. + */
  202744. + pci_bus_write_config_dword(pdev->bus, 0, 0x54, 0x01FF8000);
  202745. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x820, 0x01FF8000);
  202746. +
  202747. + /* configure rc's msi cap */
  202748. + pci_bus_read_config_dword(pdev->bus->parent, 0, 0x50, &ret);
  202749. + ret |= (PCI_MSI_FLAGS_ENABLE << 16);
  202750. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x50, ret);
  202751. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x828, 0x1);
  202752. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x82C, 0xFFFFFFFE);
  202753. +
  202754. + return 0;
  202755. +
  202756. +out:
  202757. + return ret;
  202758. +}
  202759. +
  202760. +static void imx_pcie_ep_remove(struct pci_dev *pdev)
  202761. +{
  202762. + struct imx_pcie_ep_priv *priv = pci_get_drvdata(pdev);
  202763. +
  202764. + if (!priv)
  202765. + return;
  202766. + pr_info("***imx pcie ep driver unload***\n");
  202767. +}
  202768. +
  202769. +static struct pci_device_id imx_pcie_ep_ids[] = {
  202770. + {
  202771. + .class = PCI_CLASS_MEMORY_RAM << 8,
  202772. + .class_mask = ~0,
  202773. + .vendor = 0xbeaf,
  202774. + .device = 0xdead,
  202775. + .subvendor = PCI_ANY_ID,
  202776. + .subdevice = PCI_ANY_ID,
  202777. + },
  202778. + { } /* terminate list */
  202779. +};
  202780. +MODULE_DEVICE_TABLE(pci, imx_pcie_ep_ids);
  202781. +
  202782. +static struct pci_driver imx_pcie_ep_driver = {
  202783. + .name = DRV_NAME,
  202784. + .id_table = imx_pcie_ep_ids,
  202785. + .probe = imx_pcie_ep_probe,
  202786. + .remove = imx_pcie_ep_remove,
  202787. +};
  202788. +
  202789. +static int __init imx_pcie_ep_init(void)
  202790. +{
  202791. + int ret;
  202792. + pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
  202793. +
  202794. + ret = pci_register_driver(&imx_pcie_ep_driver);
  202795. + if (ret)
  202796. + pr_err("Unable to initialize PCI module\n");
  202797. +
  202798. + return ret;
  202799. +}
  202800. +
  202801. +static void __exit imx_pcie_ep_exit(void)
  202802. +{
  202803. + pci_unregister_driver(&imx_pcie_ep_driver);
  202804. +}
  202805. +
  202806. +module_exit(imx_pcie_ep_exit);
  202807. +module_init(imx_pcie_ep_init);
  202808. +
  202809. +MODULE_DESCRIPTION(DRV_DESCRIPTION);
  202810. +MODULE_VERSION(DRV_VERSION);
  202811. +MODULE_LICENSE("GPL");
  202812. +MODULE_ALIAS("imx_pcie_ep");
  202813. diff -Nur linux-3.14.15/drivers/pinctrl/devicetree.c linux-linaro-stable-mx6/drivers/pinctrl/devicetree.c
  202814. --- linux-3.14.15/drivers/pinctrl/devicetree.c 2014-07-31 23:51:43.000000000 +0200
  202815. +++ linux-linaro-stable-mx6/drivers/pinctrl/devicetree.c 2014-08-20 19:23:54.870851440 +0200
  202816. @@ -18,6 +18,7 @@
  202817. #include <linux/device.h>
  202818. #include <linux/of.h>
  202819. +#include <linux/of_gpio.h>
  202820. #include <linux/pinctrl/pinctrl.h>
  202821. #include <linux/slab.h>
  202822. @@ -172,6 +173,43 @@
  202823. return dt_remember_or_free_map(p, statename, NULL, map, 1);
  202824. }
  202825. +static int dt_gpio_assert_pinctrl(struct pinctrl *p)
  202826. +{
  202827. + struct device_node *np = p->dev->of_node;
  202828. + enum of_gpio_flags flags;
  202829. + int gpio;
  202830. + int index = 0;
  202831. + int ret;
  202832. +
  202833. + if (!of_find_property(np, "pinctrl-assert-gpios", NULL))
  202834. + return 0; /* Missing the property, so nothing to be done */
  202835. +
  202836. + for (;; index++) {
  202837. + gpio = of_get_named_gpio_flags(np, "pinctrl-assert-gpios",
  202838. + index, &flags);
  202839. + if (gpio < 0)
  202840. + break; /* End of the phandle list */
  202841. +
  202842. + if (!gpio_is_valid(gpio))
  202843. + return -EINVAL;
  202844. +
  202845. + ret = devm_gpio_request_one(p->dev, gpio, GPIOF_OUT_INIT_LOW,
  202846. + NULL);
  202847. + if (ret < 0)
  202848. + return ret;
  202849. +
  202850. + if (flags & OF_GPIO_ACTIVE_LOW)
  202851. + continue;
  202852. +
  202853. + if (gpio_cansleep(gpio))
  202854. + gpio_set_value_cansleep(gpio, 1);
  202855. + else
  202856. + gpio_set_value(gpio, 1);
  202857. + }
  202858. +
  202859. + return 0;
  202860. +}
  202861. +
  202862. int pinctrl_dt_to_map(struct pinctrl *p)
  202863. {
  202864. struct device_node *np = p->dev->of_node;
  202865. @@ -190,6 +228,12 @@
  202866. return 0;
  202867. }
  202868. + ret = dt_gpio_assert_pinctrl(p);
  202869. + if (ret) {
  202870. + dev_dbg(p->dev, "failed to assert pinctrl setting: %d\n", ret);
  202871. + return ret;
  202872. + }
  202873. +
  202874. /* We may store pointers to property names within the node */
  202875. of_node_get(np);
  202876. diff -Nur linux-3.14.15/drivers/pinctrl/pinctrl-imx6sl.c linux-linaro-stable-mx6/drivers/pinctrl/pinctrl-imx6sl.c
  202877. --- linux-3.14.15/drivers/pinctrl/pinctrl-imx6sl.c 2014-07-31 23:51:43.000000000 +0200
  202878. +++ linux-linaro-stable-mx6/drivers/pinctrl/pinctrl-imx6sl.c 2014-08-20 19:31:47.424874568 +0200
  202879. @@ -384,6 +384,10 @@
  202880. },
  202881. .probe = imx6sl_pinctrl_probe,
  202882. .remove = imx_pinctrl_remove,
  202883. +#ifdef CONFIG_PM
  202884. + .suspend = imx_pinctrl_suspend,
  202885. + .resume = imx_pinctrl_resume,
  202886. +#endif
  202887. };
  202888. static int __init imx6sl_pinctrl_init(void)
  202889. diff -Nur linux-3.14.15/drivers/pinctrl/pinctrl-imx.c linux-linaro-stable-mx6/drivers/pinctrl/pinctrl-imx.c
  202890. --- linux-3.14.15/drivers/pinctrl/pinctrl-imx.c 2014-07-31 23:51:43.000000000 +0200
  202891. +++ linux-linaro-stable-mx6/drivers/pinctrl/pinctrl-imx.c 2014-08-20 19:31:47.420874552 +0200
  202892. @@ -1,7 +1,7 @@
  202893. /*
  202894. * Core driver for the imx pin controller
  202895. *
  202896. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  202897. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  202898. * Copyright (C) 2012 Linaro Ltd.
  202899. *
  202900. * Author: Dong Aisheng <dong.aisheng@linaro.org>
  202901. @@ -628,3 +628,25 @@
  202902. return 0;
  202903. }
  202904. +
  202905. +#ifdef CONFIG_PM
  202906. +int imx_pinctrl_suspend(struct platform_device *pdev, pm_message_t state)
  202907. +{
  202908. + struct imx_pinctrl *ipctl = platform_get_drvdata(pdev);
  202909. +
  202910. + if (!ipctl)
  202911. + return -EINVAL;
  202912. +
  202913. + return pinctrl_force_sleep(ipctl->pctl);
  202914. +}
  202915. +
  202916. +int imx_pinctrl_resume(struct platform_device *pdev)
  202917. +{
  202918. + struct imx_pinctrl *ipctl = platform_get_drvdata(pdev);
  202919. +
  202920. + if (!ipctl)
  202921. + return -EINVAL;
  202922. +
  202923. + return pinctrl_force_default(ipctl->pctl);
  202924. +}
  202925. +#endif
  202926. diff -Nur linux-3.14.15/drivers/pinctrl/pinctrl-imx.h linux-linaro-stable-mx6/drivers/pinctrl/pinctrl-imx.h
  202927. --- linux-3.14.15/drivers/pinctrl/pinctrl-imx.h 2014-07-31 23:51:43.000000000 +0200
  202928. +++ linux-linaro-stable-mx6/drivers/pinctrl/pinctrl-imx.h 2014-08-20 19:31:47.424874568 +0200
  202929. @@ -1,7 +1,7 @@
  202930. /*
  202931. * IMX pinmux core definitions
  202932. *
  202933. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  202934. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  202935. * Copyright (C) 2012 Linaro Ltd.
  202936. *
  202937. * Author: Dong Aisheng <dong.aisheng@linaro.org>
  202938. @@ -98,4 +98,8 @@
  202939. int imx_pinctrl_probe(struct platform_device *pdev,
  202940. struct imx_pinctrl_soc_info *info);
  202941. int imx_pinctrl_remove(struct platform_device *pdev);
  202942. +#ifdef CONFIG_PM
  202943. +int imx_pinctrl_suspend(struct platform_device *pdev, pm_message_t state);
  202944. +int imx_pinctrl_resume(struct platform_device *pdev);
  202945. +#endif
  202946. #endif /* __DRIVERS_PINCTRL_IMX_H */
  202947. diff -Nur linux-3.14.15/drivers/power/imx6_usb_charger.c linux-linaro-stable-mx6/drivers/power/imx6_usb_charger.c
  202948. --- linux-3.14.15/drivers/power/imx6_usb_charger.c 1970-01-01 01:00:00.000000000 +0100
  202949. +++ linux-linaro-stable-mx6/drivers/power/imx6_usb_charger.c 2014-08-20 19:23:54.934851713 +0200
  202950. @@ -0,0 +1,294 @@
  202951. +/*
  202952. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  202953. + *
  202954. + * The code contained herein is licensed under the GNU General Public
  202955. + * License. You may obtain a copy of the GNU General Public License
  202956. + * Version 2 or later at the following locations:
  202957. + *
  202958. + * http://www.opensource.org/licenses/gpl-license.html
  202959. + * http://www.gnu.org/copyleft/gpl.html
  202960. + */
  202961. +
  202962. +#include <linux/delay.h>
  202963. +#include <linux/device.h>
  202964. +#include <linux/power/imx6_usb_charger.h>
  202965. +#include <linux/regmap.h>
  202966. +
  202967. +#define HW_ANADIG_REG_3P0_SET (0x00000124)
  202968. +#define HW_ANADIG_REG_3P0_CLR (0x00000128)
  202969. +#define BM_ANADIG_REG_3P0_ENABLE_ILIMIT 0x00000004
  202970. +#define BM_ANADIG_REG_3P0_ENABLE_LINREG 0x00000001
  202971. +
  202972. +#define HW_ANADIG_USB1_CHRG_DETECT_SET (0x000001b4)
  202973. +#define HW_ANADIG_USB1_CHRG_DETECT_CLR (0x000001b8)
  202974. +
  202975. +#define BM_ANADIG_USB1_CHRG_DETECT_EN_B 0x00100000
  202976. +#define BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B 0x00080000
  202977. +#define BM_ANADIG_USB1_CHRG_DETECT_CHK_CONTACT 0x00040000
  202978. +
  202979. +#define HW_ANADIG_USB1_VBUS_DET_STAT (0x000001c0)
  202980. +
  202981. +#define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID 0x00000008
  202982. +
  202983. +#define HW_ANADIG_USB1_CHRG_DET_STAT (0x000001d0)
  202984. +
  202985. +#define BM_ANADIG_USB1_CHRG_DET_STAT_DM_STATE 0x00000004
  202986. +#define BM_ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED 0x00000002
  202987. +#define BM_ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT 0x00000001
  202988. +
  202989. +static char *imx6_usb_charger_supplied_to[] = {
  202990. + "imx6_usb_charger",
  202991. +};
  202992. +
  202993. +static enum power_supply_property imx6_usb_charger_power_props[] = {
  202994. + POWER_SUPPLY_PROP_PRESENT, /* Charger detected */
  202995. + POWER_SUPPLY_PROP_ONLINE, /* VBUS online */
  202996. + POWER_SUPPLY_PROP_CURRENT_MAX, /* Maximum current in mA */
  202997. +};
  202998. +
  202999. +static int imx6_usb_charger_get_property(struct power_supply *psy,
  203000. + enum power_supply_property psp,
  203001. + union power_supply_propval *val)
  203002. +{
  203003. + struct usb_charger *charger =
  203004. + container_of(psy, struct usb_charger, psy);
  203005. +
  203006. + switch (psp) {
  203007. + case POWER_SUPPLY_PROP_PRESENT:
  203008. + val->intval = charger->present;
  203009. + break;
  203010. + case POWER_SUPPLY_PROP_ONLINE:
  203011. + val->intval = charger->online;
  203012. + break;
  203013. + case POWER_SUPPLY_PROP_CURRENT_MAX:
  203014. + val->intval = charger->max_current;
  203015. + break;
  203016. + default:
  203017. + return -EINVAL;
  203018. + }
  203019. + return 0;
  203020. +}
  203021. +
  203022. +static void disable_charger_detector(struct regmap *regmap)
  203023. +{
  203024. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_SET,
  203025. + BM_ANADIG_USB1_CHRG_DETECT_EN_B |
  203026. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
  203027. +}
  203028. +
  203029. +static void disable_current_limiter(struct regmap *regmap)
  203030. +{
  203031. + /* Disable the vdd3p0 current limiter */
  203032. + regmap_write(regmap, HW_ANADIG_REG_3P0_CLR,
  203033. + BM_ANADIG_REG_3P0_ENABLE_ILIMIT);
  203034. +}
  203035. +
  203036. +/* Return value if the charger is present */
  203037. +static int imx6_usb_charger_detect(struct usb_charger *charger)
  203038. +{
  203039. + struct regmap *regmap = charger->anatop;
  203040. + u32 val;
  203041. + int i, data_pin_contact_count = 0;
  203042. +
  203043. + /* Enable the vdd3p0 curret limiter */
  203044. + regmap_write(regmap, HW_ANADIG_REG_3P0_SET,
  203045. + BM_ANADIG_REG_3P0_ENABLE_LINREG |
  203046. + BM_ANADIG_REG_3P0_ENABLE_ILIMIT);
  203047. +
  203048. + /* check if vbus is valid */
  203049. + regmap_read(regmap, HW_ANADIG_USB1_VBUS_DET_STAT, &val);
  203050. + if (!(val & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)) {
  203051. + dev_err(charger->dev, "vbus is error\n");
  203052. + disable_current_limiter(regmap);
  203053. + return -EINVAL;
  203054. + }
  203055. +
  203056. + /* Enable charger detector */
  203057. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_CLR,
  203058. + BM_ANADIG_USB1_CHRG_DETECT_EN_B);
  203059. + /*
  203060. + * - Do not check whether a charger is connected to the USB port
  203061. + * - Check whether the USB plug has been in contact with each other
  203062. + */
  203063. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_SET,
  203064. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
  203065. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
  203066. +
  203067. + /* Check if plug is connected */
  203068. + for (i = 0; i < 100; i = i + 1) {
  203069. + regmap_read(regmap, HW_ANADIG_USB1_CHRG_DET_STAT, &val);
  203070. + if (val & BM_ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT) {
  203071. + if (data_pin_contact_count++ > 5)
  203072. + /* Data pin makes contact */
  203073. + break;
  203074. + } else {
  203075. + msleep(20);
  203076. + }
  203077. + }
  203078. +
  203079. + if (i == 100) {
  203080. + dev_err(charger->dev,
  203081. + "VBUS is coming from a dedicated power supply.\n");
  203082. + disable_current_limiter(regmap);
  203083. + disable_charger_detector(regmap);
  203084. + return -ENXIO;
  203085. + }
  203086. +
  203087. + /*
  203088. + * - Do check whether a charger is connected to the USB port
  203089. + * - Do not Check whether the USB plug has been in contact with
  203090. + * each other
  203091. + */
  203092. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_CLR,
  203093. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
  203094. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
  203095. + msleep(45);
  203096. +
  203097. + /* Check if it is a charger */
  203098. + regmap_read(regmap, HW_ANADIG_USB1_CHRG_DET_STAT, &val);
  203099. + if (!(val & BM_ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED)) {
  203100. + dev_dbg(charger->dev, "It is a stardard downstream port\n");
  203101. + charger->psy.type = POWER_SUPPLY_TYPE_USB;
  203102. + charger->max_current = 500;
  203103. + disable_charger_detector(regmap);
  203104. + } else {
  203105. + /* It is a charger */
  203106. + disable_charger_detector(regmap);
  203107. + msleep(45);
  203108. + }
  203109. +
  203110. + disable_current_limiter(regmap);
  203111. +
  203112. + return 0;
  203113. +}
  203114. +
  203115. +/*
  203116. + * imx6_usb_vbus_connect - inform about VBUS connection
  203117. + * @charger: the usb charger
  203118. + *
  203119. + * Inform the charger VBUS is connected, vbus detect supplier should call it.
  203120. + * Besides, the USB device controller is expected to keep the dataline
  203121. + * pullups disabled.
  203122. + */
  203123. +int imx6_usb_vbus_connect(struct usb_charger *charger)
  203124. +{
  203125. + int ret;
  203126. +
  203127. + charger->online = 1;
  203128. +
  203129. + mutex_lock(&charger->lock);
  203130. +
  203131. + /* Start the 1st period charger detection. */
  203132. + ret = imx6_usb_charger_detect(charger);
  203133. + if (ret)
  203134. + dev_err(charger->dev,
  203135. + "Error occurs during detection: %d\n",
  203136. + ret);
  203137. + else
  203138. + charger->present = 1;
  203139. +
  203140. + mutex_unlock(&charger->lock);
  203141. +
  203142. + return ret;
  203143. +}
  203144. +EXPORT_SYMBOL(imx6_usb_vbus_connect);
  203145. +
  203146. +/*
  203147. + * It must be called after dp is pulled up (from USB controller driver),
  203148. + * That is used to differentiate DCP and CDP
  203149. + */
  203150. +int imx6_usb_charger_detect_post(struct usb_charger *charger)
  203151. +{
  203152. + struct regmap *regmap = charger->anatop;
  203153. + int val;
  203154. +
  203155. + mutex_lock(&charger->lock);
  203156. +
  203157. + msleep(40);
  203158. +
  203159. + regmap_read(regmap, HW_ANADIG_USB1_CHRG_DET_STAT, &val);
  203160. + if (val & BM_ANADIG_USB1_CHRG_DET_STAT_DM_STATE) {
  203161. + dev_dbg(charger->dev, "It is a dedicate charging port\n");
  203162. + charger->psy.type = POWER_SUPPLY_TYPE_USB_DCP;
  203163. + charger->max_current = 1500;
  203164. + } else {
  203165. + dev_dbg(charger->dev, "It is a charging downstream port\n");
  203166. + charger->psy.type = POWER_SUPPLY_TYPE_USB_CDP;
  203167. + charger->max_current = 900;
  203168. + }
  203169. +
  203170. + power_supply_changed(&charger->psy);
  203171. +
  203172. + mutex_unlock(&charger->lock);
  203173. +
  203174. + return 0;
  203175. +}
  203176. +EXPORT_SYMBOL(imx6_usb_charger_detect_post);
  203177. +
  203178. +/*
  203179. + * imx6_usb_vbus_disconnect - inform about VBUS disconnection
  203180. + * @charger: the usb charger
  203181. + *
  203182. + * Inform the charger that VBUS is disconnected. The charging will be
  203183. + * stopped and the charger properties cleared.
  203184. + */
  203185. +int imx6_usb_vbus_disconnect(struct usb_charger *charger)
  203186. +{
  203187. + charger->online = 0;
  203188. + charger->present = 0;
  203189. + charger->max_current = 0;
  203190. + charger->psy.type = POWER_SUPPLY_TYPE_MAINS;
  203191. +
  203192. + power_supply_changed(&charger->psy);
  203193. +
  203194. + return 0;
  203195. +}
  203196. +EXPORT_SYMBOL(imx6_usb_vbus_disconnect);
  203197. +
  203198. +/*
  203199. + * imx6_usb_create_charger - create a USB charger
  203200. + * @charger: the charger to be initialized
  203201. + * @name: name for the power supply
  203202. +
  203203. + * Registers a power supply for the charger. The USB Controller
  203204. + * driver will call this after filling struct usb_charger.
  203205. + */
  203206. +int imx6_usb_create_charger(struct usb_charger *charger,
  203207. + const char *name)
  203208. +{
  203209. + struct power_supply *psy = &charger->psy;
  203210. +
  203211. + if (!charger->dev)
  203212. + return -EINVAL;
  203213. +
  203214. + if (name)
  203215. + psy->name = name;
  203216. + else
  203217. + psy->name = "imx6_usb_charger";
  203218. +
  203219. + charger->bc = BATTERY_CHARGING_SPEC_1_2;
  203220. + mutex_init(&charger->lock);
  203221. +
  203222. + psy->type = POWER_SUPPLY_TYPE_MAINS;
  203223. + psy->properties = imx6_usb_charger_power_props;
  203224. + psy->num_properties = ARRAY_SIZE(imx6_usb_charger_power_props);
  203225. + psy->get_property = imx6_usb_charger_get_property;
  203226. + psy->supplied_to = imx6_usb_charger_supplied_to;
  203227. + psy->num_supplicants = sizeof(imx6_usb_charger_supplied_to)
  203228. + / sizeof(char *);
  203229. +
  203230. + return power_supply_register(charger->dev, psy);
  203231. +}
  203232. +EXPORT_SYMBOL(imx6_usb_create_charger);
  203233. +
  203234. +/*
  203235. + * imx6_usb_remove_charger - remove a USB charger
  203236. + * @charger: the charger to be removed
  203237. + *
  203238. + * Unregister the chargers power supply.
  203239. + */
  203240. +void imx6_usb_remove_charger(struct usb_charger *charger)
  203241. +{
  203242. + power_supply_unregister(&charger->psy);
  203243. +}
  203244. +EXPORT_SYMBOL(imx6_usb_remove_charger);
  203245. diff -Nur linux-3.14.15/drivers/power/Kconfig linux-linaro-stable-mx6/drivers/power/Kconfig
  203246. --- linux-3.14.15/drivers/power/Kconfig 2014-07-31 23:51:43.000000000 +0200
  203247. +++ linux-linaro-stable-mx6/drivers/power/Kconfig 2014-08-20 19:31:47.464874741 +0200
  203248. @@ -389,6 +389,12 @@
  203249. Say Y to enable support for the battery and AC power in the
  203250. Goldfish emulator.
  203251. +config IMX6_USB_CHARGER
  203252. + bool "Freescale imx6 USB Charger"
  203253. + depends on SOC_IMX6Q || SOC_IMX6SL
  203254. + help
  203255. + Say Y to enable Freescale imx6 USB Charger Detect.
  203256. +
  203257. source "drivers/power/reset/Kconfig"
  203258. endif # POWER_SUPPLY
  203259. diff -Nur linux-3.14.15/drivers/power/Makefile linux-linaro-stable-mx6/drivers/power/Makefile
  203260. --- linux-3.14.15/drivers/power/Makefile 2014-07-31 23:51:43.000000000 +0200
  203261. +++ linux-linaro-stable-mx6/drivers/power/Makefile 2014-08-20 19:31:47.464874741 +0200
  203262. @@ -58,3 +58,4 @@
  203263. obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
  203264. obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
  203265. obj-$(CONFIG_POWER_RESET) += reset/
  203266. +obj-$(CONFIG_IMX6_USB_CHARGER) += imx6_usb_charger.o
  203267. diff -Nur linux-3.14.15/drivers/ptp/ptp_chardev.c linux-linaro-stable-mx6/drivers/ptp/ptp_chardev.c
  203268. --- linux-3.14.15/drivers/ptp/ptp_chardev.c 2014-07-31 23:51:43.000000000 +0200
  203269. +++ linux-linaro-stable-mx6/drivers/ptp/ptp_chardev.c 2014-08-20 19:31:47.536875050 +0200
  203270. @@ -25,6 +25,96 @@
  203271. #include "ptp_private.h"
  203272. +static int ptp_disable_pinfunc(struct ptp_clock_info *ops,
  203273. + enum ptp_pin_function func, unsigned int chan)
  203274. +{
  203275. + struct ptp_clock_request rq;
  203276. + int err = 0;
  203277. +
  203278. + memset(&rq, 0, sizeof(rq));
  203279. +
  203280. + switch (func) {
  203281. + case PTP_PF_NONE:
  203282. + break;
  203283. + case PTP_PF_EXTTS:
  203284. + rq.type = PTP_CLK_REQ_EXTTS;
  203285. + rq.extts.index = chan;
  203286. + err = ops->enable(ops, &rq, 0);
  203287. + break;
  203288. + case PTP_PF_PEROUT:
  203289. + rq.type = PTP_CLK_REQ_PEROUT;
  203290. + rq.perout.index = chan;
  203291. + err = ops->enable(ops, &rq, 0);
  203292. + break;
  203293. + case PTP_PF_PHYSYNC:
  203294. + break;
  203295. + default:
  203296. + return -EINVAL;
  203297. + }
  203298. +
  203299. + return err;
  203300. +}
  203301. +
  203302. +int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
  203303. + enum ptp_pin_function func, unsigned int chan)
  203304. +{
  203305. + struct ptp_clock_info *info = ptp->info;
  203306. + struct ptp_pin_desc *pin1 = NULL, *pin2 = &info->pin_config[pin];
  203307. + unsigned int i;
  203308. +
  203309. + /* Check to see if any other pin previously had this function. */
  203310. + for (i = 0; i < info->n_pins; i++) {
  203311. + if (info->pin_config[i].func == func &&
  203312. + info->pin_config[i].chan == chan) {
  203313. + pin1 = &info->pin_config[i];
  203314. + break;
  203315. + }
  203316. + }
  203317. + if (pin1 && i == pin)
  203318. + return 0;
  203319. +
  203320. + /* Check the desired function and channel. */
  203321. + switch (func) {
  203322. + case PTP_PF_NONE:
  203323. + break;
  203324. + case PTP_PF_EXTTS:
  203325. + if (chan >= info->n_ext_ts)
  203326. + return -EINVAL;
  203327. + break;
  203328. + case PTP_PF_PEROUT:
  203329. + if (chan >= info->n_per_out)
  203330. + return -EINVAL;
  203331. + break;
  203332. + case PTP_PF_PHYSYNC:
  203333. + pr_err("sorry, cannot reassign the calibration pin\n");
  203334. + return -EINVAL;
  203335. + default:
  203336. + return -EINVAL;
  203337. + }
  203338. +
  203339. + if (pin2->func == PTP_PF_PHYSYNC) {
  203340. + pr_err("sorry, cannot reprogram the calibration pin\n");
  203341. + return -EINVAL;
  203342. + }
  203343. +
  203344. + if (info->verify(info, pin, func, chan)) {
  203345. + pr_err("driver cannot use function %u on pin %u\n", func, chan);
  203346. + return -EOPNOTSUPP;
  203347. + }
  203348. +
  203349. + /* Disable whatever function was previously assigned. */
  203350. + if (pin1) {
  203351. + ptp_disable_pinfunc(info, func, chan);
  203352. + pin1->func = PTP_PF_NONE;
  203353. + pin1->chan = 0;
  203354. + }
  203355. + ptp_disable_pinfunc(info, pin2->func, pin2->chan);
  203356. + pin2->func = func;
  203357. + pin2->chan = chan;
  203358. +
  203359. + return 0;
  203360. +}
  203361. +
  203362. int ptp_open(struct posix_clock *pc, fmode_t fmode)
  203363. {
  203364. return 0;
  203365. @@ -35,12 +125,13 @@
  203366. struct ptp_clock_caps caps;
  203367. struct ptp_clock_request req;
  203368. struct ptp_sys_offset *sysoff = NULL;
  203369. + struct ptp_pin_desc pd;
  203370. struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
  203371. struct ptp_clock_info *ops = ptp->info;
  203372. struct ptp_clock_time *pct;
  203373. struct timespec ts;
  203374. int enable, err = 0;
  203375. - unsigned int i;
  203376. + unsigned int i, pin_index;
  203377. switch (cmd) {
  203378. @@ -51,6 +142,7 @@
  203379. caps.n_ext_ts = ptp->info->n_ext_ts;
  203380. caps.n_per_out = ptp->info->n_per_out;
  203381. caps.pps = ptp->info->pps;
  203382. + caps.n_pins = ptp->info->n_pins;
  203383. if (copy_to_user((void __user *)arg, &caps, sizeof(caps)))
  203384. err = -EFAULT;
  203385. break;
  203386. @@ -126,6 +218,40 @@
  203387. err = -EFAULT;
  203388. break;
  203389. + case PTP_PIN_GETFUNC:
  203390. + if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
  203391. + err = -EFAULT;
  203392. + break;
  203393. + }
  203394. + pin_index = pd.index;
  203395. + if (pin_index >= ops->n_pins) {
  203396. + err = -EINVAL;
  203397. + break;
  203398. + }
  203399. + if (mutex_lock_interruptible(&ptp->pincfg_mux))
  203400. + return -ERESTARTSYS;
  203401. + pd = ops->pin_config[pin_index];
  203402. + mutex_unlock(&ptp->pincfg_mux);
  203403. + if (!err && copy_to_user((void __user *)arg, &pd, sizeof(pd)))
  203404. + err = -EFAULT;
  203405. + break;
  203406. +
  203407. + case PTP_PIN_SETFUNC:
  203408. + if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
  203409. + err = -EFAULT;
  203410. + break;
  203411. + }
  203412. + pin_index = pd.index;
  203413. + if (pin_index >= ops->n_pins) {
  203414. + err = -EINVAL;
  203415. + break;
  203416. + }
  203417. + if (mutex_lock_interruptible(&ptp->pincfg_mux))
  203418. + return -ERESTARTSYS;
  203419. + err = ptp_set_pinfunc(ptp, pin_index, pd.func, pd.chan);
  203420. + mutex_unlock(&ptp->pincfg_mux);
  203421. + break;
  203422. +
  203423. default:
  203424. err = -ENOTTY;
  203425. break;
  203426. diff -Nur linux-3.14.15/drivers/ptp/ptp_clock.c linux-linaro-stable-mx6/drivers/ptp/ptp_clock.c
  203427. --- linux-3.14.15/drivers/ptp/ptp_clock.c 2014-07-31 23:51:43.000000000 +0200
  203428. +++ linux-linaro-stable-mx6/drivers/ptp/ptp_clock.c 2014-08-20 19:31:47.536875050 +0200
  203429. @@ -169,6 +169,7 @@
  203430. struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
  203431. mutex_destroy(&ptp->tsevq_mux);
  203432. + mutex_destroy(&ptp->pincfg_mux);
  203433. ida_simple_remove(&ptp_clocks_map, ptp->index);
  203434. kfree(ptp);
  203435. }
  203436. @@ -203,6 +204,7 @@
  203437. ptp->index = index;
  203438. spin_lock_init(&ptp->tsevq.lock);
  203439. mutex_init(&ptp->tsevq_mux);
  203440. + mutex_init(&ptp->pincfg_mux);
  203441. init_waitqueue_head(&ptp->tsev_wq);
  203442. /* Create a new device in our class. */
  203443. @@ -249,6 +251,7 @@
  203444. device_destroy(ptp_class, ptp->devid);
  203445. no_device:
  203446. mutex_destroy(&ptp->tsevq_mux);
  203447. + mutex_destroy(&ptp->pincfg_mux);
  203448. no_slot:
  203449. kfree(ptp);
  203450. no_memory:
  203451. @@ -305,6 +308,26 @@
  203452. }
  203453. EXPORT_SYMBOL(ptp_clock_index);
  203454. +int ptp_find_pin(struct ptp_clock *ptp,
  203455. + enum ptp_pin_function func, unsigned int chan)
  203456. +{
  203457. + struct ptp_pin_desc *pin = NULL;
  203458. + int i;
  203459. +
  203460. + mutex_lock(&ptp->pincfg_mux);
  203461. + for (i = 0; i < ptp->info->n_pins; i++) {
  203462. + if (ptp->info->pin_config[i].func == func &&
  203463. + ptp->info->pin_config[i].chan == chan) {
  203464. + pin = &ptp->info->pin_config[i];
  203465. + break;
  203466. + }
  203467. + }
  203468. + mutex_unlock(&ptp->pincfg_mux);
  203469. +
  203470. + return pin ? i : -1;
  203471. +}
  203472. +EXPORT_SYMBOL(ptp_find_pin);
  203473. +
  203474. /* module operations */
  203475. static void __exit ptp_exit(void)
  203476. diff -Nur linux-3.14.15/drivers/ptp/ptp_ixp46x.c linux-linaro-stable-mx6/drivers/ptp/ptp_ixp46x.c
  203477. --- linux-3.14.15/drivers/ptp/ptp_ixp46x.c 2014-07-31 23:51:43.000000000 +0200
  203478. +++ linux-linaro-stable-mx6/drivers/ptp/ptp_ixp46x.c 2014-08-20 19:31:47.536875050 +0200
  203479. @@ -244,6 +244,7 @@
  203480. .name = "IXP46X timer",
  203481. .max_adj = 66666655,
  203482. .n_ext_ts = N_EXT_TS,
  203483. + .n_pins = 0,
  203484. .pps = 0,
  203485. .adjfreq = ptp_ixp_adjfreq,
  203486. .adjtime = ptp_ixp_adjtime,
  203487. diff -Nur linux-3.14.15/drivers/ptp/ptp_pch.c linux-linaro-stable-mx6/drivers/ptp/ptp_pch.c
  203488. --- linux-3.14.15/drivers/ptp/ptp_pch.c 2014-07-31 23:51:43.000000000 +0200
  203489. +++ linux-linaro-stable-mx6/drivers/ptp/ptp_pch.c 2014-08-20 19:31:47.536875050 +0200
  203490. @@ -514,6 +514,7 @@
  203491. .name = "PCH timer",
  203492. .max_adj = 50000000,
  203493. .n_ext_ts = N_EXT_TS,
  203494. + .n_pins = 0,
  203495. .pps = 0,
  203496. .adjfreq = ptp_pch_adjfreq,
  203497. .adjtime = ptp_pch_adjtime,
  203498. diff -Nur linux-3.14.15/drivers/ptp/ptp_private.h linux-linaro-stable-mx6/drivers/ptp/ptp_private.h
  203499. --- linux-3.14.15/drivers/ptp/ptp_private.h 2014-07-31 23:51:43.000000000 +0200
  203500. +++ linux-linaro-stable-mx6/drivers/ptp/ptp_private.h 2014-08-20 19:31:47.536875050 +0200
  203501. @@ -48,6 +48,7 @@
  203502. long dialed_frequency; /* remembers the frequency adjustment */
  203503. struct timestamp_event_queue tsevq; /* simple fifo for time stamps */
  203504. struct mutex tsevq_mux; /* one process at a time reading the fifo */
  203505. + struct mutex pincfg_mux; /* protect concurrent info->pin_config access */
  203506. wait_queue_head_t tsev_wq;
  203507. int defunct; /* tells readers to go away when clock is being removed */
  203508. };
  203509. @@ -69,6 +70,10 @@
  203510. * see ptp_chardev.c
  203511. */
  203512. +/* caller must hold pincfg_mux */
  203513. +int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
  203514. + enum ptp_pin_function func, unsigned int chan);
  203515. +
  203516. long ptp_ioctl(struct posix_clock *pc,
  203517. unsigned int cmd, unsigned long arg);
  203518. diff -Nur linux-3.14.15/drivers/pwm/pwm-imx.c linux-linaro-stable-mx6/drivers/pwm/pwm-imx.c
  203519. --- linux-3.14.15/drivers/pwm/pwm-imx.c 2014-07-31 23:51:43.000000000 +0200
  203520. +++ linux-linaro-stable-mx6/drivers/pwm/pwm-imx.c 2014-08-20 19:31:47.540875067 +0200
  203521. @@ -1,4 +1,5 @@
  203522. /*
  203523. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  203524. * simple driver for PWM (Pulse Width Modulator) controller
  203525. *
  203526. * This program is free software; you can redistribute it and/or modify
  203527. @@ -293,11 +294,34 @@
  203528. return pwmchip_remove(&imx->chip);
  203529. }
  203530. +#ifdef CONFIG_PM
  203531. +static int imx_pwm_suspend(struct device *dev)
  203532. +{
  203533. + pinctrl_pm_select_sleep_state(dev);
  203534. +
  203535. + return 0;
  203536. +}
  203537. +
  203538. +static int imx_pwm_resume(struct device *dev)
  203539. +{
  203540. + pinctrl_pm_select_default_state(dev);
  203541. +
  203542. + return 0;
  203543. +}
  203544. +
  203545. +static const struct dev_pm_ops imx_pwm_pm_ops = {
  203546. + SET_SYSTEM_SLEEP_PM_OPS(imx_pwm_suspend, imx_pwm_resume)
  203547. +};
  203548. +#endif
  203549. +
  203550. static struct platform_driver imx_pwm_driver = {
  203551. .driver = {
  203552. .name = "imx-pwm",
  203553. .owner = THIS_MODULE,
  203554. .of_match_table = imx_pwm_dt_ids,
  203555. +#ifdef CONFIG_PM
  203556. + .pm = &imx_pwm_pm_ops,
  203557. +#endif
  203558. },
  203559. .probe = imx_pwm_probe,
  203560. .remove = imx_pwm_remove,
  203561. diff -Nur linux-3.14.15/drivers/regulator/anatop-regulator.c linux-linaro-stable-mx6/drivers/regulator/anatop-regulator.c
  203562. --- linux-3.14.15/drivers/regulator/anatop-regulator.c 2014-07-31 23:51:43.000000000 +0200
  203563. +++ linux-linaro-stable-mx6/drivers/regulator/anatop-regulator.c 2014-08-20 19:31:47.624875427 +0200
  203564. @@ -1,5 +1,5 @@
  203565. /*
  203566. - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
  203567. + * Copyright (C) 2011, 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  203568. */
  203569. /*
  203570. @@ -34,6 +34,22 @@
  203571. #define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */
  203572. #define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */
  203573. +#define REG_SET 0x4
  203574. +#define REG_CLR 0x8
  203575. +#define SOC_PU_FIELD_OFFSET 0x9
  203576. +
  203577. +/*
  203578. + * for CORE, SOC and PU regulator, the register field
  203579. + * has following definition: 00001 -- Target core voltage
  203580. + * = 0.725V, which means the lowest setting in this
  203581. + * field is 0.725V once the regulator is enabled. So
  203582. + * when these regulators are turned on from off status,
  203583. + * we need to count the voltage step of 0V to 0.7V, it will
  203584. + * need additional delay, so the additional step number is
  203585. + * 700mV / 25mV = 28.
  203586. + */
  203587. +#define CORE_REG_ENABLE_STEP_ADD 28
  203588. +
  203589. struct anatop_regulator {
  203590. const char *name;
  203591. u32 control_reg;
  203592. @@ -97,12 +113,86 @@
  203593. return regulator_get_voltage_sel_regmap(reg);
  203594. }
  203595. +/*
  203596. + * currently on anatop regulators, only PU regulator supports
  203597. + * enable/disable function, and its voltage must be equal
  203598. + * to SOC voltage, so we need to get SOC voltage then set
  203599. + * into PU regulator. Other regulators are always on due
  203600. + * to hardware design, so enable/disable/is_enabled/enable_time
  203601. + * functions are only used by PU regulator.
  203602. + */
  203603. +static int anatop_regmap_enable(struct regulator_dev *reg)
  203604. +{
  203605. + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  203606. + u32 val;
  203607. +
  203608. + if (!anatop_reg->control_reg)
  203609. + return -ENOTSUPP;
  203610. +
  203611. + regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
  203612. + val &= ((1 << anatop_reg->vol_bit_width) - 1) <<
  203613. + (anatop_reg->vol_bit_shift + SOC_PU_FIELD_OFFSET);
  203614. + regmap_write(anatop_reg->anatop, anatop_reg->control_reg +
  203615. + REG_SET, val >> SOC_PU_FIELD_OFFSET);
  203616. +
  203617. + return 0;
  203618. +}
  203619. +
  203620. +static int anatop_regmap_disable(struct regulator_dev *reg)
  203621. +{
  203622. + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  203623. +
  203624. + if (!anatop_reg->control_reg)
  203625. + return -ENOTSUPP;
  203626. +
  203627. + regmap_write(anatop_reg->anatop, anatop_reg->control_reg +
  203628. + REG_CLR, ((1 << anatop_reg->vol_bit_width) - 1) <<
  203629. + anatop_reg->vol_bit_shift);
  203630. +
  203631. + return 0;
  203632. +}
  203633. +
  203634. +static int anatop_regmap_is_enabled(struct regulator_dev *reg)
  203635. +{
  203636. + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  203637. + u32 val;
  203638. +
  203639. + if (!anatop_reg->control_reg)
  203640. + return -ENOTSUPP;
  203641. +
  203642. + regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
  203643. +
  203644. + return (val >> anatop_reg->vol_bit_shift) &
  203645. + ((1 << anatop_reg->vol_bit_width) - 1) ? 1 : 0;
  203646. +}
  203647. +
  203648. +static int anatop_regmap_enable_time(struct regulator_dev *reg)
  203649. +{
  203650. + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  203651. + u32 val, soc_val;
  203652. +
  203653. + if (!anatop_reg->control_reg)
  203654. + return -ENOTSUPP;
  203655. +
  203656. + regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
  203657. + soc_val = (val >> (anatop_reg->vol_bit_shift +
  203658. + SOC_PU_FIELD_OFFSET)) &
  203659. + ((1 << anatop_reg->vol_bit_width) - 1);
  203660. +
  203661. + return anatop_regmap_set_voltage_time_sel(reg, 0,
  203662. + soc_val + CORE_REG_ENABLE_STEP_ADD);
  203663. +}
  203664. +
  203665. static struct regulator_ops anatop_rops = {
  203666. .set_voltage_sel = anatop_regmap_set_voltage_sel,
  203667. .set_voltage_time_sel = anatop_regmap_set_voltage_time_sel,
  203668. .get_voltage_sel = anatop_regmap_get_voltage_sel,
  203669. + .enable = anatop_regmap_enable,
  203670. + .disable = anatop_regmap_disable,
  203671. + .is_enabled = anatop_regmap_is_enabled,
  203672. .list_voltage = regulator_list_voltage_linear,
  203673. .map_voltage = regulator_map_voltage_linear,
  203674. + .enable_time = anatop_regmap_enable_time,
  203675. };
  203676. static int anatop_regulator_probe(struct platform_device *pdev)
  203677. @@ -196,6 +286,7 @@
  203678. config.driver_data = sreg;
  203679. config.of_node = pdev->dev.of_node;
  203680. config.regmap = sreg->anatop;
  203681. + config.ena_gpio = -EINVAL;
  203682. /* register regulator */
  203683. rdev = devm_regulator_register(dev, rdesc, &config);
  203684. diff -Nur linux-3.14.15/drivers/regulator/core.c linux-linaro-stable-mx6/drivers/regulator/core.c
  203685. --- linux-3.14.15/drivers/regulator/core.c 2014-07-31 23:51:43.000000000 +0200
  203686. +++ linux-linaro-stable-mx6/drivers/regulator/core.c 2014-08-20 19:31:47.632875462 +0200
  203687. @@ -3,6 +3,7 @@
  203688. *
  203689. * Copyright 2007, 2008 Wolfson Microelectronics PLC.
  203690. * Copyright 2008 SlimLogic Ltd.
  203691. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  203692. *
  203693. * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  203694. *
  203695. @@ -24,6 +25,7 @@
  203696. #include <linux/suspend.h>
  203697. #include <linux/delay.h>
  203698. #include <linux/gpio.h>
  203699. +#include <linux/gpio/consumer.h>
  203700. #include <linux/of.h>
  203701. #include <linux/regmap.h>
  203702. #include <linux/regulator/of_regulator.h>
  203703. @@ -77,7 +79,7 @@
  203704. */
  203705. struct regulator_enable_gpio {
  203706. struct list_head list;
  203707. - int gpio;
  203708. + struct gpio_desc *gpiod;
  203709. u32 enable_count; /* a number of enabled shared GPIO */
  203710. u32 request_count; /* a number of requested shared GPIO */
  203711. unsigned int ena_gpio_invert:1;
  203712. @@ -1653,10 +1655,13 @@
  203713. const struct regulator_config *config)
  203714. {
  203715. struct regulator_enable_gpio *pin;
  203716. + struct gpio_desc *gpiod;
  203717. int ret;
  203718. + gpiod = gpio_to_desc(config->ena_gpio);
  203719. +
  203720. list_for_each_entry(pin, &regulator_ena_gpio_list, list) {
  203721. - if (pin->gpio == config->ena_gpio) {
  203722. + if (pin->gpiod == gpiod) {
  203723. rdev_dbg(rdev, "GPIO %d is already used\n",
  203724. config->ena_gpio);
  203725. goto update_ena_gpio_to_rdev;
  203726. @@ -1675,7 +1680,7 @@
  203727. return -ENOMEM;
  203728. }
  203729. - pin->gpio = config->ena_gpio;
  203730. + pin->gpiod = gpiod;
  203731. pin->ena_gpio_invert = config->ena_gpio_invert;
  203732. list_add(&pin->list, &regulator_ena_gpio_list);
  203733. @@ -1694,10 +1699,10 @@
  203734. /* Free the GPIO only in case of no use */
  203735. list_for_each_entry_safe(pin, n, &regulator_ena_gpio_list, list) {
  203736. - if (pin->gpio == rdev->ena_pin->gpio) {
  203737. + if (pin->gpiod == rdev->ena_pin->gpiod) {
  203738. if (pin->request_count <= 1) {
  203739. pin->request_count = 0;
  203740. - gpio_free(pin->gpio);
  203741. + gpiod_put(pin->gpiod);
  203742. list_del(&pin->list);
  203743. kfree(pin);
  203744. } else {
  203745. @@ -1725,8 +1730,8 @@
  203746. if (enable) {
  203747. /* Enable GPIO at initial use */
  203748. if (pin->enable_count == 0)
  203749. - gpio_set_value_cansleep(pin->gpio,
  203750. - !pin->ena_gpio_invert);
  203751. + gpiod_set_value_cansleep(pin->gpiod,
  203752. + !pin->ena_gpio_invert);
  203753. pin->enable_count++;
  203754. } else {
  203755. @@ -1737,8 +1742,8 @@
  203756. /* Disable GPIO if not used */
  203757. if (pin->enable_count <= 1) {
  203758. - gpio_set_value_cansleep(pin->gpio,
  203759. - pin->ena_gpio_invert);
  203760. + gpiod_set_value_cansleep(pin->gpiod,
  203761. + pin->ena_gpio_invert);
  203762. pin->enable_count = 0;
  203763. }
  203764. }
  203765. @@ -1815,6 +1820,7 @@
  203766. }
  203767. trace_regulator_enable_complete(rdev_get_name(rdev));
  203768. + _notifier_call_chain(rdev, REGULATOR_EVENT_ENABLE, NULL);
  203769. return 0;
  203770. }
  203771. @@ -1892,6 +1898,7 @@
  203772. {
  203773. int ret;
  203774. + _notifier_call_chain(rdev, REGULATOR_EVENT_PRE_DISABLE, NULL);
  203775. trace_regulator_disable(rdev_get_name(rdev));
  203776. if (rdev->ena_pin) {
  203777. @@ -2138,7 +2145,7 @@
  203778. * @regulator: regulator source
  203779. *
  203780. * Returns positive if the regulator driver backing the source/client
  203781. - * can change its voltage, false otherwise. Usefull for detecting fixed
  203782. + * can change its voltage, false otherwise. Useful for detecting fixed
  203783. * or dummy regulators and disabling voltage change logic in the client
  203784. * driver.
  203785. */
  203786. @@ -3445,7 +3452,7 @@
  203787. dev_set_drvdata(&rdev->dev, rdev);
  203788. - if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) {
  203789. + if (gpio_is_valid(config->ena_gpio)) {
  203790. ret = regulator_ena_gpio_request(rdev, config);
  203791. if (ret != 0) {
  203792. rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
  203793. diff -Nur linux-3.14.15/drivers/regulator/dummy.c linux-linaro-stable-mx6/drivers/regulator/dummy.c
  203794. --- linux-3.14.15/drivers/regulator/dummy.c 2014-07-31 23:51:43.000000000 +0200
  203795. +++ linux-linaro-stable-mx6/drivers/regulator/dummy.c 2014-08-20 19:23:55.014852055 +0200
  203796. @@ -44,6 +44,7 @@
  203797. config.dev = &pdev->dev;
  203798. config.init_data = &dummy_initdata;
  203799. + config.ena_gpio = -EINVAL;
  203800. dummy_regulator_rdev = regulator_register(&dummy_desc, &config);
  203801. if (IS_ERR(dummy_regulator_rdev)) {
  203802. diff -Nur linux-3.14.15/drivers/regulator/fixed.c linux-linaro-stable-mx6/drivers/regulator/fixed.c
  203803. --- linux-3.14.15/drivers/regulator/fixed.c 2014-07-31 23:51:43.000000000 +0200
  203804. +++ linux-linaro-stable-mx6/drivers/regulator/fixed.c 2014-08-20 19:31:47.640875496 +0200
  203805. @@ -163,9 +163,7 @@
  203806. drvdata->desc.n_voltages = 1;
  203807. drvdata->desc.fixed_uV = config->microvolts;
  203808. -
  203809. - if (config->gpio >= 0)
  203810. - cfg.ena_gpio = config->gpio;
  203811. + cfg.ena_gpio = config->gpio;
  203812. cfg.ena_gpio_invert = !config->enable_high;
  203813. if (config->enabled_at_boot) {
  203814. if (config->enable_high)
  203815. diff -Nur linux-3.14.15/drivers/reset/gpio-reset.c linux-linaro-stable-mx6/drivers/reset/gpio-reset.c
  203816. --- linux-3.14.15/drivers/reset/gpio-reset.c 1970-01-01 01:00:00.000000000 +0100
  203817. +++ linux-linaro-stable-mx6/drivers/reset/gpio-reset.c 2014-08-20 19:23:55.034852141 +0200
  203818. @@ -0,0 +1,187 @@
  203819. +/*
  203820. + * GPIO Reset Controller driver
  203821. + *
  203822. + * Copyright 2013 Philipp Zabel, Pengutronix
  203823. + *
  203824. + * This program is free software; you can redistribute it and/or modify
  203825. + * it under the terms of the GNU General Public License as published by
  203826. + * the Free Software Foundation; either version 2 of the License, or
  203827. + * (at your option) any later version.
  203828. + */
  203829. +#include <linux/delay.h>
  203830. +#include <linux/err.h>
  203831. +#include <linux/gpio.h>
  203832. +#include <linux/module.h>
  203833. +#include <linux/of_gpio.h>
  203834. +#include <linux/platform_device.h>
  203835. +#include <linux/reset-controller.h>
  203836. +
  203837. +struct gpio_reset_data {
  203838. + struct reset_controller_dev rcdev;
  203839. + unsigned int gpio;
  203840. + bool active_low;
  203841. + s32 delay_us;
  203842. +};
  203843. +
  203844. +static void gpio_reset_set(struct reset_controller_dev *rcdev, int asserted)
  203845. +{
  203846. + struct gpio_reset_data *drvdata = container_of(rcdev,
  203847. + struct gpio_reset_data, rcdev);
  203848. + int value = asserted;
  203849. +
  203850. + if (drvdata->active_low)
  203851. + value = !value;
  203852. +
  203853. + if (gpio_cansleep(drvdata->gpio))
  203854. + gpio_set_value_cansleep(drvdata->gpio, value);
  203855. + else
  203856. + gpio_set_value(drvdata->gpio, value);
  203857. +}
  203858. +
  203859. +static int gpio_reset(struct reset_controller_dev *rcdev, unsigned long id)
  203860. +{
  203861. + struct gpio_reset_data *drvdata = container_of(rcdev,
  203862. + struct gpio_reset_data, rcdev);
  203863. +
  203864. + if (drvdata->delay_us < 0)
  203865. + return -ENOSYS;
  203866. +
  203867. + gpio_reset_set(rcdev, 1);
  203868. + udelay(drvdata->delay_us);
  203869. + gpio_reset_set(rcdev, 0);
  203870. +
  203871. + return 0;
  203872. +}
  203873. +
  203874. +static int gpio_reset_assert(struct reset_controller_dev *rcdev,
  203875. + unsigned long id)
  203876. +{
  203877. + gpio_reset_set(rcdev, 1);
  203878. +
  203879. + return 0;
  203880. +}
  203881. +
  203882. +static int gpio_reset_deassert(struct reset_controller_dev *rcdev,
  203883. + unsigned long id)
  203884. +{
  203885. + gpio_reset_set(rcdev, 0);
  203886. +
  203887. + return 0;
  203888. +}
  203889. +
  203890. +static struct reset_control_ops gpio_reset_ops = {
  203891. + .reset = gpio_reset,
  203892. + .assert = gpio_reset_assert,
  203893. + .deassert = gpio_reset_deassert,
  203894. +};
  203895. +
  203896. +static int of_gpio_reset_xlate(struct reset_controller_dev *rcdev,
  203897. + const struct of_phandle_args *reset_spec)
  203898. +{
  203899. + if (WARN_ON(reset_spec->args_count != 0))
  203900. + return -EINVAL;
  203901. +
  203902. + return 0;
  203903. +}
  203904. +
  203905. +static int gpio_reset_probe(struct platform_device *pdev)
  203906. +{
  203907. + struct device_node *np = pdev->dev.of_node;
  203908. + struct gpio_reset_data *drvdata;
  203909. + enum of_gpio_flags flags;
  203910. + unsigned long gpio_flags;
  203911. + bool initially_in_reset;
  203912. + int ret;
  203913. +
  203914. + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
  203915. + if (drvdata == NULL)
  203916. + return -ENOMEM;
  203917. +
  203918. + if (of_gpio_named_count(np, "reset-gpios") != 1) {
  203919. + dev_err(&pdev->dev,
  203920. + "reset-gpios property missing, or not a single gpio\n");
  203921. + return -EINVAL;
  203922. + }
  203923. +
  203924. + drvdata->gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags);
  203925. + if (drvdata->gpio == -EPROBE_DEFER) {
  203926. + return drvdata->gpio;
  203927. + } else if (!gpio_is_valid(drvdata->gpio)) {
  203928. + dev_err(&pdev->dev, "invalid reset gpio: %d\n", drvdata->gpio);
  203929. + return drvdata->gpio;
  203930. + }
  203931. +
  203932. + drvdata->active_low = flags & OF_GPIO_ACTIVE_LOW;
  203933. +
  203934. + ret = of_property_read_u32(np, "reset-delay-us", &drvdata->delay_us);
  203935. + if (ret < 0)
  203936. + drvdata->delay_us = -1;
  203937. + else if (drvdata->delay_us < 0)
  203938. + dev_warn(&pdev->dev, "reset delay too high\n");
  203939. +
  203940. + initially_in_reset = of_property_read_bool(np, "initially-in-reset");
  203941. + if (drvdata->active_low ^ initially_in_reset)
  203942. + gpio_flags = GPIOF_OUT_INIT_HIGH;
  203943. + else
  203944. + gpio_flags = GPIOF_OUT_INIT_LOW;
  203945. +
  203946. + ret = devm_gpio_request_one(&pdev->dev, drvdata->gpio, gpio_flags, NULL);
  203947. + if (ret < 0) {
  203948. + dev_err(&pdev->dev, "failed to request gpio %d: %d\n",
  203949. + drvdata->gpio, ret);
  203950. + return ret;
  203951. + }
  203952. +
  203953. + platform_set_drvdata(pdev, drvdata);
  203954. +
  203955. + drvdata->rcdev.of_node = np;
  203956. + drvdata->rcdev.owner = THIS_MODULE;
  203957. + drvdata->rcdev.nr_resets = 1;
  203958. + drvdata->rcdev.ops = &gpio_reset_ops;
  203959. + drvdata->rcdev.of_xlate = of_gpio_reset_xlate;
  203960. + reset_controller_register(&drvdata->rcdev);
  203961. +
  203962. + return 0;
  203963. +}
  203964. +
  203965. +static int gpio_reset_remove(struct platform_device *pdev)
  203966. +{
  203967. + struct gpio_reset_data *drvdata = platform_get_drvdata(pdev);
  203968. +
  203969. + reset_controller_unregister(&drvdata->rcdev);
  203970. +
  203971. + return 0;
  203972. +}
  203973. +
  203974. +static struct of_device_id gpio_reset_dt_ids[] = {
  203975. + { .compatible = "gpio-reset" },
  203976. + { }
  203977. +};
  203978. +
  203979. +static struct platform_driver gpio_reset_driver = {
  203980. + .probe = gpio_reset_probe,
  203981. + .remove = gpio_reset_remove,
  203982. + .driver = {
  203983. + .name = "gpio-reset",
  203984. + .owner = THIS_MODULE,
  203985. + .of_match_table = of_match_ptr(gpio_reset_dt_ids),
  203986. + },
  203987. +};
  203988. +
  203989. +static int __init gpio_reset_init(void)
  203990. +{
  203991. + return platform_driver_register(&gpio_reset_driver);
  203992. +}
  203993. +arch_initcall(gpio_reset_init);
  203994. +
  203995. +static void __exit gpio_reset_exit(void)
  203996. +{
  203997. + platform_driver_unregister(&gpio_reset_driver);
  203998. +}
  203999. +module_exit(gpio_reset_exit);
  204000. +
  204001. +MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
  204002. +MODULE_DESCRIPTION("gpio reset controller");
  204003. +MODULE_LICENSE("GPL");
  204004. +MODULE_ALIAS("platform:gpio-reset");
  204005. +MODULE_DEVICE_TABLE(of, gpio_reset_dt_ids);
  204006. diff -Nur linux-3.14.15/drivers/reset/Kconfig linux-linaro-stable-mx6/drivers/reset/Kconfig
  204007. --- linux-3.14.15/drivers/reset/Kconfig 2014-07-31 23:51:43.000000000 +0200
  204008. +++ linux-linaro-stable-mx6/drivers/reset/Kconfig 2014-08-20 19:23:55.034852141 +0200
  204009. @@ -11,3 +11,15 @@
  204010. via GPIOs or SoC-internal reset controller modules.
  204011. If unsure, say no.
  204012. +
  204013. +if RESET_CONTROLLER
  204014. +
  204015. +config RESET_GPIO
  204016. + tristate "GPIO reset controller support"
  204017. + default y
  204018. + depends on GPIOLIB && OF
  204019. + help
  204020. + This driver provides support for reset lines that are controlled
  204021. + directly by GPIOs.
  204022. +
  204023. +endif
  204024. diff -Nur linux-3.14.15/drivers/reset/Makefile linux-linaro-stable-mx6/drivers/reset/Makefile
  204025. --- linux-3.14.15/drivers/reset/Makefile 2014-07-31 23:51:43.000000000 +0200
  204026. +++ linux-linaro-stable-mx6/drivers/reset/Makefile 2014-08-20 19:31:47.672875633 +0200
  204027. @@ -1,2 +1,3 @@
  204028. obj-$(CONFIG_RESET_CONTROLLER) += core.o
  204029. +obj-$(CONFIG_RESET_GPIO) += gpio-reset.o
  204030. obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
  204031. diff -Nur linux-3.14.15/drivers/rtc/rtc-pcf8523.c linux-linaro-stable-mx6/drivers/rtc/rtc-pcf8523.c
  204032. --- linux-3.14.15/drivers/rtc/rtc-pcf8523.c 2014-07-31 23:51:43.000000000 +0200
  204033. +++ linux-linaro-stable-mx6/drivers/rtc/rtc-pcf8523.c 2014-08-20 19:23:55.050852208 +0200
  204034. @@ -7,6 +7,7 @@
  204035. */
  204036. #include <linux/bcd.h>
  204037. +#include <linux/delay.h>
  204038. #include <linux/i2c.h>
  204039. #include <linux/module.h>
  204040. #include <linux/rtc.h>
  204041. @@ -82,24 +83,85 @@
  204042. return 0;
  204043. }
  204044. -static int pcf8523_select_capacitance(struct i2c_client *client, bool high)
  204045. +static int pcf8523_rtc_check_oscillator(struct i2c_client *client)
  204046. {
  204047. u8 value;
  204048. int err;
  204049. - err = pcf8523_read(client, REG_CONTROL1, &value);
  204050. + err = pcf8523_read(client, REG_SECONDS, &value);
  204051. if (err < 0)
  204052. return err;
  204053. - if (!high)
  204054. - value &= ~REG_CONTROL1_CAP_SEL;
  204055. - else
  204056. - value |= REG_CONTROL1_CAP_SEL;
  204057. + if (value & REG_SECONDS_OS) {
  204058. + /*
  204059. + * If the oscillator was stopped, try to clear the flag. Upon
  204060. + * power-up the flag is always set, but if we cannot clear it
  204061. + * the oscillator isn't running properly for some reason. The
  204062. + * sensible thing therefore is to return an error, signalling
  204063. + * that the clock cannot be assumed to be correct.
  204064. + */
  204065. +
  204066. + value &= ~REG_SECONDS_OS;
  204067. +
  204068. + err = pcf8523_write(client, REG_SECONDS, value);
  204069. + if (err < 0)
  204070. + return err;
  204071. +
  204072. + err = pcf8523_read(client, REG_SECONDS, &value);
  204073. + if (err < 0)
  204074. + return err;
  204075. +
  204076. + if (value & REG_SECONDS_OS)
  204077. + return -EAGAIN;
  204078. + }
  204079. +
  204080. + return 0;
  204081. +}
  204082. +
  204083. +static int pcf8523_switch_capacitance(struct i2c_client *client)
  204084. +{
  204085. + u8 value;
  204086. + int err;
  204087. +
  204088. + err = pcf8523_read(client, REG_CONTROL1, &value);
  204089. + if (err < 0)
  204090. + goto out;
  204091. +
  204092. + value ^= REG_CONTROL1_CAP_SEL;
  204093. err = pcf8523_write(client, REG_CONTROL1, value);
  204094. +
  204095. +out:
  204096. + return err;
  204097. +}
  204098. +
  204099. +static int pcf8523_enable_oscillator(struct i2c_client *client)
  204100. +{
  204101. + int err, loop;
  204102. +
  204103. + loop = 0;
  204104. + while (loop < 200) {
  204105. + err = pcf8523_rtc_check_oscillator(client);
  204106. + if (!err)
  204107. + return 0;
  204108. + loop++;
  204109. + msleep(10);
  204110. + }
  204111. +
  204112. + err = pcf8523_switch_capacitance(client);
  204113. if (err < 0)
  204114. - return err;
  204115. + goto out;
  204116. +
  204117. + loop = 0;
  204118. + while (loop < 200) {
  204119. + err = pcf8523_rtc_check_oscillator(client);
  204120. + if (!err)
  204121. + return 0;
  204122. + loop++;
  204123. + msleep(10);
  204124. + }
  204125. +out:
  204126. return err;
  204127. }
  204128. @@ -290,6 +352,7 @@
  204129. const struct i2c_device_id *id)
  204130. {
  204131. struct pcf8523 *pcf;
  204132. + u8 value;
  204133. int err;
  204134. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
  204135. @@ -299,10 +362,20 @@
  204136. if (!pcf)
  204137. return -ENOMEM;
  204138. - err = pcf8523_select_capacitance(client, true);
  204139. + /* Check whether the RTC reports battery low */
  204140. + err = pcf8523_read(client, REG_CONTROL3, &value);
  204141. if (err < 0)
  204142. return err;
  204143. + if (value & REG_CONTROL3_BLF)
  204144. + dev_warn(&client->dev, "RTC reports battery is low\n");
  204145. +
  204146. + err = pcf8523_enable_oscillator(client);
  204147. + if (err < 0) {
  204148. + dev_warn(&client->dev, "RTC reports oscillator is not running\n");
  204149. + return err;
  204150. + }
  204151. +
  204152. err = pcf8523_set_pm(client, 0);
  204153. if (err < 0)
  204154. return err;
  204155. diff -Nur linux-3.14.15/drivers/rtc/rtc-snvs.c linux-linaro-stable-mx6/drivers/rtc/rtc-snvs.c
  204156. --- linux-3.14.15/drivers/rtc/rtc-snvs.c 2014-07-31 23:51:43.000000000 +0200
  204157. +++ linux-linaro-stable-mx6/drivers/rtc/rtc-snvs.c 2014-08-20 19:31:47.696875736 +0200
  204158. @@ -1,5 +1,5 @@
  204159. /*
  204160. - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
  204161. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  204162. *
  204163. * The code contained herein is licensed under the GNU General Public
  204164. * License. You may obtain a copy of the GNU General Public License
  204165. @@ -41,6 +41,8 @@
  204166. spinlock_t lock;
  204167. };
  204168. +static void __iomem *snvs_base;
  204169. +
  204170. static u32 rtc_read_lp_counter(void __iomem *ioaddr)
  204171. {
  204172. u64 read1, read2;
  204173. @@ -241,6 +243,15 @@
  204174. return events ? IRQ_HANDLED : IRQ_NONE;
  204175. }
  204176. +static void snvs_poweroff(void)
  204177. +{
  204178. + u32 value;
  204179. +
  204180. + value = readl(snvs_base + SNVS_LPCR);
  204181. + /* set TOP and DP_EN bit */
  204182. + writel(value | 0x60, snvs_base + SNVS_LPCR);
  204183. +}
  204184. +
  204185. static int snvs_rtc_probe(struct platform_device *pdev)
  204186. {
  204187. struct snvs_rtc_data *data;
  204188. @@ -270,13 +281,15 @@
  204189. /* Clear interrupt status */
  204190. writel(0xffffffff, data->ioaddr + SNVS_LPSR);
  204191. + snvs_base = data->ioaddr;
  204192. /* Enable RTC */
  204193. snvs_rtc_enable(data, true);
  204194. device_init_wakeup(&pdev->dev, true);
  204195. ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler,
  204196. - IRQF_SHARED, "rtc alarm", &pdev->dev);
  204197. + IRQF_SHARED | IRQF_NO_SUSPEND,
  204198. + "rtc alarm", &pdev->dev);
  204199. if (ret) {
  204200. dev_err(&pdev->dev, "failed to request irq %d: %d\n",
  204201. data->irq, ret);
  204202. @@ -290,6 +303,12 @@
  204203. dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
  204204. return ret;
  204205. }
  204206. + /*
  204207. + * if no specific power off function in board file, power off system by
  204208. + * SNVS
  204209. + */
  204210. + if (!pm_power_off)
  204211. + pm_power_off = snvs_poweroff;
  204212. return 0;
  204213. }
  204214. diff -Nur linux-3.14.15/drivers/scsi/scsi_transport_iscsi.c linux-linaro-stable-mx6/drivers/scsi/scsi_transport_iscsi.c
  204215. --- linux-3.14.15/drivers/scsi/scsi_transport_iscsi.c 2014-07-31 23:51:43.000000000 +0200
  204216. +++ linux-linaro-stable-mx6/drivers/scsi/scsi_transport_iscsi.c 2014-08-20 19:31:47.940876783 +0200
  204217. @@ -1225,7 +1225,7 @@
  204218. * Adds a sysfs entry for the flashnode session attributes
  204219. *
  204220. * Returns:
  204221. - * pointer to allocated flashnode sess on sucess
  204222. + * pointer to allocated flashnode sess on success
  204223. * %NULL on failure
  204224. */
  204225. struct iscsi_bus_flash_session *
  204226. @@ -1423,7 +1423,7 @@
  204227. }
  204228. /**
  204229. - * iscsi_destroy_flashnode_sess - destory flashnode session entry
  204230. + * iscsi_destroy_flashnode_sess - destroy flashnode session entry
  204231. * @fnode_sess: pointer to flashnode session entry to be destroyed
  204232. *
  204233. * Deletes the flashnode session entry and all children flashnode connection
  204234. @@ -1453,7 +1453,7 @@
  204235. }
  204236. /**
  204237. - * iscsi_destroy_all_flashnode - destory all flashnode session entries
  204238. + * iscsi_destroy_all_flashnode - destroy all flashnode session entries
  204239. * @shost: pointer to host data
  204240. *
  204241. * Destroys all the flashnode session entries and all corresponding children
  204242. diff -Nur linux-3.14.15/drivers/staging/bcm/Typedefs.h linux-linaro-stable-mx6/drivers/staging/bcm/Typedefs.h
  204243. --- linux-3.14.15/drivers/staging/bcm/Typedefs.h 2014-07-31 23:51:43.000000000 +0200
  204244. +++ linux-linaro-stable-mx6/drivers/staging/bcm/Typedefs.h 2014-08-20 19:31:48.016877109 +0200
  204245. @@ -25,16 +25,16 @@
  204246. typedef unsigned long ULONG;
  204247. typedef unsigned long DWORD;
  204248. -typedef char* PCHAR;
  204249. -typedef short* PSHORT;
  204250. -typedef int* PINT;
  204251. -typedef long* PLONG;
  204252. -typedef void* PVOID;
  204253. +typedef char *PCHAR;
  204254. +typedef short *PSHORT;
  204255. +typedef int *PINT;
  204256. +typedef long *PLONG;
  204257. +typedef void *PVOID;
  204258. -typedef unsigned char* PUCHAR;
  204259. -typedef unsigned short* PUSHORT;
  204260. -typedef unsigned int* PUINT;
  204261. -typedef unsigned long* PULONG;
  204262. +typedef unsigned char *PUCHAR;
  204263. +typedef unsigned short *PUSHORT;
  204264. +typedef unsigned int *PUINT;
  204265. +typedef unsigned long *PULONG;
  204266. typedef unsigned long long ULONG64;
  204267. typedef unsigned long long LARGE_INTEGER;
  204268. typedef unsigned int UINT32;
  204269. diff -Nur linux-3.14.15/drivers/staging/media/omap4iss/Kconfig linux-linaro-stable-mx6/drivers/staging/media/omap4iss/Kconfig
  204270. --- linux-3.14.15/drivers/staging/media/omap4iss/Kconfig 2014-07-31 23:51:43.000000000 +0200
  204271. +++ linux-linaro-stable-mx6/drivers/staging/media/omap4iss/Kconfig 2014-08-20 19:31:48.564879463 +0200
  204272. @@ -1,6 +1,6 @@
  204273. config VIDEO_OMAP4
  204274. bool "OMAP 4 Camera support"
  204275. - depends on VIDEO_V4L2=y && VIDEO_V4L2_SUBDEV_API && I2C=y && ARCH_OMAP4
  204276. + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && I2C && ARCH_OMAP4
  204277. select VIDEOBUF2_DMA_CONTIG
  204278. ---help---
  204279. Driver for an OMAP 4 ISS controller.
  204280. diff -Nur linux-3.14.15/drivers/staging/octeon/ethernet-rgmii.c linux-linaro-stable-mx6/drivers/staging/octeon/ethernet-rgmii.c
  204281. --- linux-3.14.15/drivers/staging/octeon/ethernet-rgmii.c 2014-07-31 23:51:43.000000000 +0200
  204282. +++ linux-linaro-stable-mx6/drivers/staging/octeon/ethernet-rgmii.c 2014-08-20 19:31:48.596879600 +0200
  204283. @@ -166,9 +166,8 @@
  204284. if (use_global_register_lock)
  204285. spin_unlock_irqrestore(&global_register_lock, flags);
  204286. - else {
  204287. + else
  204288. mutex_unlock(&priv->phydev->bus->mdio_lock);
  204289. - }
  204290. if (priv->phydev == NULL) {
  204291. /* Tell core. */
  204292. diff -Nur linux-3.14.15/drivers/staging/rtl8821ae/core.c linux-linaro-stable-mx6/drivers/staging/rtl8821ae/core.c
  204293. --- linux-3.14.15/drivers/staging/rtl8821ae/core.c 2014-07-31 23:51:43.000000000 +0200
  204294. +++ linux-linaro-stable-mx6/drivers/staging/rtl8821ae/core.c 2014-08-20 19:31:48.776880373 +0200
  204295. @@ -1414,23 +1414,15 @@
  204296. * before switch channle or power save, or tx buffer packet
  204297. * maybe send after offchannel or rf sleep, this may cause
  204298. * dis-association by AP */
  204299. -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
  204300. -static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  204301. +static void rtl_op_flush(struct ieee80211_hw *hw,
  204302. + struct ieee80211_vif *vif,
  204303. + u32 queues, bool drop)
  204304. {
  204305. struct rtl_priv *rtlpriv = rtl_priv(hw);
  204306. if (rtlpriv->intf_ops->flush)
  204307. rtlpriv->intf_ops->flush(hw, queues, drop);
  204308. }
  204309. -#else
  204310. -static void rtl_op_flush(struct ieee80211_hw *hw, bool drop)
  204311. -{
  204312. - struct rtl_priv *rtlpriv = rtl_priv(hw);
  204313. -
  204314. - if (rtlpriv->intf_ops->flush)
  204315. - rtlpriv->intf_ops->flush(hw, drop);
  204316. -}
  204317. -#endif
  204318. const struct ieee80211_ops rtl_ops = {
  204319. .start = rtl_op_start,
  204320. diff -Nur linux-3.14.15/drivers/thermal/device_cooling.c linux-linaro-stable-mx6/drivers/thermal/device_cooling.c
  204321. --- linux-3.14.15/drivers/thermal/device_cooling.c 1970-01-01 01:00:00.000000000 +0100
  204322. +++ linux-linaro-stable-mx6/drivers/thermal/device_cooling.c 2014-08-20 19:23:57.174861277 +0200
  204323. @@ -0,0 +1,151 @@
  204324. +/*
  204325. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  204326. + *
  204327. + * This program is free software; you can redistribute it and/or modify
  204328. + * it under the terms of the GNU General Public License version 2 as
  204329. + * published by the Free Software Foundation.
  204330. + *
  204331. + */
  204332. +
  204333. +#include <linux/module.h>
  204334. +#include <linux/thermal.h>
  204335. +#include <linux/err.h>
  204336. +#include <linux/slab.h>
  204337. +
  204338. +struct devfreq_cooling_device {
  204339. + int id;
  204340. + struct thermal_cooling_device *cool_dev;
  204341. + unsigned int devfreq_state;
  204342. +};
  204343. +
  204344. +static DEFINE_IDR(devfreq_idr);
  204345. +static DEFINE_MUTEX(devfreq_cooling_lock);
  204346. +
  204347. +#define MAX_STATE 1
  204348. +
  204349. +static BLOCKING_NOTIFIER_HEAD(devfreq_cooling_chain_head);
  204350. +
  204351. +int register_devfreq_cooling_notifier(struct notifier_block *nb)
  204352. +{
  204353. + return blocking_notifier_chain_register(
  204354. + &devfreq_cooling_chain_head, nb);
  204355. +}
  204356. +EXPORT_SYMBOL_GPL(register_devfreq_cooling_notifier);
  204357. +
  204358. +int unregister_devfreq_cooling_notifier(struct notifier_block *nb)
  204359. +{
  204360. + return blocking_notifier_chain_unregister(
  204361. + &devfreq_cooling_chain_head, nb);
  204362. +}
  204363. +EXPORT_SYMBOL_GPL(unregister_devfreq_cooling_notifier);
  204364. +
  204365. +static int devfreq_cooling_notifier_call_chain(unsigned long val)
  204366. +{
  204367. + return (blocking_notifier_call_chain(
  204368. + &devfreq_cooling_chain_head, val, NULL)
  204369. + == NOTIFY_BAD) ? -EINVAL : 0;
  204370. +}
  204371. +
  204372. +static int devfreq_set_cur_state(struct thermal_cooling_device *cdev,
  204373. + unsigned long state)
  204374. +{
  204375. + struct devfreq_cooling_device *devfreq_device = cdev->devdata;
  204376. + int ret;
  204377. +
  204378. + ret = devfreq_cooling_notifier_call_chain(state);
  204379. + if (ret)
  204380. + return -EINVAL;
  204381. + devfreq_device->devfreq_state = state;
  204382. +
  204383. + return 0;
  204384. +}
  204385. +
  204386. +static int devfreq_get_max_state(struct thermal_cooling_device *cdev,
  204387. + unsigned long *state)
  204388. +{
  204389. + *state = MAX_STATE;
  204390. +
  204391. + return 0;
  204392. +}
  204393. +
  204394. +static int devfreq_get_cur_state(struct thermal_cooling_device *cdev,
  204395. + unsigned long *state)
  204396. +{
  204397. + struct devfreq_cooling_device *devfreq_device = cdev->devdata;
  204398. +
  204399. + *state = devfreq_device->devfreq_state;
  204400. +
  204401. + return 0;
  204402. +}
  204403. +
  204404. +static struct thermal_cooling_device_ops const devfreq_cooling_ops = {
  204405. + .get_max_state = devfreq_get_max_state,
  204406. + .get_cur_state = devfreq_get_cur_state,
  204407. + .set_cur_state = devfreq_set_cur_state,
  204408. +};
  204409. +
  204410. +static int get_idr(struct idr *idr, int *id)
  204411. +{
  204412. + int ret;
  204413. +
  204414. + mutex_lock(&devfreq_cooling_lock);
  204415. + ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
  204416. + mutex_unlock(&devfreq_cooling_lock);
  204417. + if (unlikely(ret < 0))
  204418. + return ret;
  204419. + *id = ret;
  204420. +
  204421. + return 0;
  204422. +}
  204423. +
  204424. +static void release_idr(struct idr *idr, int id)
  204425. +{
  204426. + mutex_lock(&devfreq_cooling_lock);
  204427. + idr_remove(idr, id);
  204428. + mutex_unlock(&devfreq_cooling_lock);
  204429. +}
  204430. +
  204431. +struct thermal_cooling_device *devfreq_cooling_register(void)
  204432. +{
  204433. + struct thermal_cooling_device *cool_dev;
  204434. + struct devfreq_cooling_device *devfreq_dev = NULL;
  204435. + char dev_name[THERMAL_NAME_LENGTH];
  204436. + int ret = 0;
  204437. +
  204438. + devfreq_dev = kzalloc(sizeof(struct devfreq_cooling_device),
  204439. + GFP_KERNEL);
  204440. + if (!devfreq_dev)
  204441. + return ERR_PTR(-ENOMEM);
  204442. +
  204443. + ret = get_idr(&devfreq_idr, &devfreq_dev->id);
  204444. + if (ret) {
  204445. + kfree(devfreq_dev);
  204446. + return ERR_PTR(-EINVAL);
  204447. + }
  204448. +
  204449. + snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d",
  204450. + devfreq_dev->id);
  204451. +
  204452. + cool_dev = thermal_cooling_device_register(dev_name, devfreq_dev,
  204453. + &devfreq_cooling_ops);
  204454. + if (!cool_dev) {
  204455. + release_idr(&devfreq_idr, devfreq_dev->id);
  204456. + kfree(devfreq_dev);
  204457. + return ERR_PTR(-EINVAL);
  204458. + }
  204459. + devfreq_dev->cool_dev = cool_dev;
  204460. + devfreq_dev->devfreq_state = 0;
  204461. +
  204462. + return cool_dev;
  204463. +}
  204464. +EXPORT_SYMBOL_GPL(devfreq_cooling_register);
  204465. +
  204466. +void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
  204467. +{
  204468. + struct devfreq_cooling_device *devfreq_dev = cdev->devdata;
  204469. +
  204470. + thermal_cooling_device_unregister(devfreq_dev->cool_dev);
  204471. + release_idr(&devfreq_idr, devfreq_dev->id);
  204472. + kfree(devfreq_dev);
  204473. +}
  204474. +EXPORT_SYMBOL_GPL(devfreq_cooling_unregister);
  204475. diff -Nur linux-3.14.15/drivers/thermal/imx_thermal.c linux-linaro-stable-mx6/drivers/thermal/imx_thermal.c
  204476. --- linux-3.14.15/drivers/thermal/imx_thermal.c 2014-07-31 23:51:43.000000000 +0200
  204477. +++ linux-linaro-stable-mx6/drivers/thermal/imx_thermal.c 2014-08-20 19:31:49.116881832 +0200
  204478. @@ -12,6 +12,7 @@
  204479. #include <linux/cpufreq.h>
  204480. #include <linux/delay.h>
  204481. #include <linux/device.h>
  204482. +#include <linux/device_cooling.h>
  204483. #include <linux/init.h>
  204484. #include <linux/interrupt.h>
  204485. #include <linux/io.h>
  204486. @@ -58,13 +59,14 @@
  204487. * that will trigger cooling action when crossed.
  204488. */
  204489. #define IMX_TEMP_PASSIVE 85000
  204490. +#define IMX_TEMP_PASSIVE_COOL_DELTA 10000
  204491. #define IMX_POLLING_DELAY 2000 /* millisecond */
  204492. #define IMX_PASSIVE_DELAY 1000
  204493. struct imx_thermal_data {
  204494. struct thermal_zone_device *tz;
  204495. - struct thermal_cooling_device *cdev;
  204496. + struct thermal_cooling_device *cdev[2];
  204497. enum thermal_device_mode mode;
  204498. struct regmap *tempmon;
  204499. int c1, c2; /* See formula in imx_get_sensor_data() */
  204500. @@ -286,6 +288,24 @@
  204501. return 0;
  204502. }
  204503. + int imx_get_trend(struct thermal_zone_device *tz,
  204504. + int trip, enum thermal_trend *trend)
  204505. +{
  204506. + int ret;
  204507. + unsigned long trip_temp;
  204508. +
  204509. + ret = imx_get_trip_temp(tz, trip, &trip_temp);
  204510. + if (ret < 0)
  204511. + return ret;
  204512. +
  204513. + if (tz->temperature >= (trip_temp - IMX_TEMP_PASSIVE_COOL_DELTA))
  204514. + *trend = THERMAL_TREND_RAISE_FULL;
  204515. + else
  204516. + *trend = THERMAL_TREND_DROP_FULL;
  204517. +
  204518. + return 0;
  204519. +}
  204520. +
  204521. static struct thermal_zone_device_ops imx_tz_ops = {
  204522. .bind = imx_bind,
  204523. .unbind = imx_unbind,
  204524. @@ -295,6 +315,7 @@
  204525. .get_trip_type = imx_get_trip_type,
  204526. .get_trip_temp = imx_get_trip_temp,
  204527. .get_crit_temp = imx_get_crit_temp,
  204528. + .get_trend = imx_get_trend,
  204529. .set_trip_temp = imx_set_trip_temp,
  204530. };
  204531. @@ -437,9 +458,17 @@
  204532. regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
  204533. cpumask_set_cpu(0, &clip_cpus);
  204534. - data->cdev = cpufreq_cooling_register(&clip_cpus);
  204535. - if (IS_ERR(data->cdev)) {
  204536. - ret = PTR_ERR(data->cdev);
  204537. + data->cdev[0] = cpufreq_cooling_register(&clip_cpus);
  204538. + if (IS_ERR(data->cdev[0])) {
  204539. + ret = PTR_ERR(data->cdev[0]);
  204540. + dev_err(&pdev->dev,
  204541. + "failed to register cpufreq cooling device: %d\n", ret);
  204542. + return ret;
  204543. + }
  204544. +
  204545. + data->cdev[1] = cpufreq_cooling_register(&clip_cpus);
  204546. + if (IS_ERR(data->cdev[1])) {
  204547. + ret = PTR_ERR(data->cdev[1]);
  204548. dev_err(&pdev->dev,
  204549. "failed to register cpufreq cooling device: %d\n", ret);
  204550. return ret;
  204551. @@ -455,7 +484,8 @@
  204552. ret = PTR_ERR(data->tz);
  204553. dev_err(&pdev->dev,
  204554. "failed to register thermal zone device %d\n", ret);
  204555. - cpufreq_cooling_unregister(data->cdev);
  204556. + cpufreq_cooling_unregister(data->cdev[0]);
  204557. + devfreq_cooling_unregister(data->cdev[1]);
  204558. return ret;
  204559. }
  204560. @@ -500,7 +530,8 @@
  204561. clk_disable_unprepare(data->thermal_clk);
  204562. thermal_zone_device_unregister(data->tz);
  204563. - cpufreq_cooling_unregister(data->cdev);
  204564. + cpufreq_cooling_unregister(data->cdev[0]);
  204565. + devfreq_cooling_unregister(data->cdev[1]);
  204566. return 0;
  204567. }
  204568. diff -Nur linux-3.14.15/drivers/thermal/Kconfig linux-linaro-stable-mx6/drivers/thermal/Kconfig
  204569. --- linux-3.14.15/drivers/thermal/Kconfig 2014-07-31 23:51:43.000000000 +0200
  204570. +++ linux-linaro-stable-mx6/drivers/thermal/Kconfig 2014-08-20 19:31:49.116881832 +0200
  204571. @@ -125,6 +125,13 @@
  204572. cpufreq is used as the cooling device to throttle CPUs when the
  204573. passive trip is crossed.
  204574. +config DEVICE_THERMAL
  204575. + tristate "generic device cooling support"
  204576. + help
  204577. + Support for device cooling.
  204578. + It supports notification of crossing passive trip for devices,
  204579. + devices need to do their own actions to cool down the SOC.
  204580. +
  204581. config SPEAR_THERMAL
  204582. bool "SPEAr thermal sensor driver"
  204583. depends on PLAT_SPEAR
  204584. diff -Nur linux-3.14.15/drivers/thermal/Makefile linux-linaro-stable-mx6/drivers/thermal/Makefile
  204585. --- linux-3.14.15/drivers/thermal/Makefile 2014-07-31 23:51:43.000000000 +0200
  204586. +++ linux-linaro-stable-mx6/drivers/thermal/Makefile 2014-08-20 19:31:49.116881832 +0200
  204587. @@ -26,6 +26,7 @@
  204588. obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
  204589. obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
  204590. obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
  204591. +obj-$(CONFIG_DEVICE_THERMAL) += device_cooling.o
  204592. obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
  204593. obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
  204594. obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o
  204595. diff -Nur linux-3.14.15/drivers/tty/serial/earlycon.c linux-linaro-stable-mx6/drivers/tty/serial/earlycon.c
  204596. --- linux-3.14.15/drivers/tty/serial/earlycon.c 1970-01-01 01:00:00.000000000 +0100
  204597. +++ linux-linaro-stable-mx6/drivers/tty/serial/earlycon.c 2014-08-20 19:31:49.196882175 +0200
  204598. @@ -0,0 +1,152 @@
  204599. +/*
  204600. + * Copyright (C) 2014 Linaro Ltd.
  204601. + * Author: Rob Herring <robh@kernel.org>
  204602. + *
  204603. + * Based on 8250 earlycon:
  204604. + * (c) Copyright 2004 Hewlett-Packard Development Company, L.P.
  204605. + * Bjorn Helgaas <bjorn.helgaas@hp.com>
  204606. + *
  204607. + * This program is free software: you can redistribute it and/or modify
  204608. + * it under the terms of the GNU General Public License version 2 as
  204609. + * published by the Free Software Foundation.
  204610. + */
  204611. +#include <linux/console.h>
  204612. +#include <linux/kernel.h>
  204613. +#include <linux/init.h>
  204614. +#include <linux/io.h>
  204615. +#include <linux/serial_core.h>
  204616. +
  204617. +#ifdef CONFIG_FIX_EARLYCON_MEM
  204618. +#include <asm/fixmap.h>
  204619. +#endif
  204620. +
  204621. +#include <asm/serial.h>
  204622. +
  204623. +static struct console early_con = {
  204624. + .name = "earlycon",
  204625. + .flags = CON_PRINTBUFFER | CON_BOOT,
  204626. + .index = -1,
  204627. +};
  204628. +
  204629. +static struct earlycon_device early_console_dev = {
  204630. + .con = &early_con,
  204631. +};
  204632. +
  204633. +static void __iomem * __init earlycon_map(unsigned long paddr, size_t size)
  204634. +{
  204635. + void __iomem *base;
  204636. +#ifdef CONFIG_FIX_EARLYCON_MEM
  204637. + set_fixmap_io(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK);
  204638. + base = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
  204639. + base += paddr & ~PAGE_MASK;
  204640. +#else
  204641. + base = ioremap(paddr, size);
  204642. +#endif
  204643. + if (!base)
  204644. + pr_err("%s: Couldn't map 0x%llx\n", __func__,
  204645. + (unsigned long long)paddr);
  204646. +
  204647. + return base;
  204648. +}
  204649. +
  204650. +static int __init parse_options(struct earlycon_device *device,
  204651. + char *options)
  204652. +{
  204653. + struct uart_port *port = &device->port;
  204654. + int mmio, mmio32, length, ret;
  204655. + unsigned long addr;
  204656. +
  204657. + if (!options)
  204658. + return -ENODEV;
  204659. +
  204660. + mmio = !strncmp(options, "mmio,", 5);
  204661. + mmio32 = !strncmp(options, "mmio32,", 7);
  204662. + if (mmio || mmio32) {
  204663. + port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32);
  204664. + options += mmio ? 5 : 7;
  204665. + ret = kstrtoul(options, 0, &addr);
  204666. + if (ret)
  204667. + return ret;
  204668. + port->mapbase = addr;
  204669. + if (mmio32)
  204670. + port->regshift = 2;
  204671. + } else if (!strncmp(options, "io,", 3)) {
  204672. + port->iotype = UPIO_PORT;
  204673. + options += 3;
  204674. + ret = kstrtoul(options, 0, &addr);
  204675. + if (ret)
  204676. + return ret;
  204677. + port->iobase = addr;
  204678. + mmio = 0;
  204679. + } else if (!strncmp(options, "0x", 2)) {
  204680. + port->iotype = UPIO_MEM;
  204681. + ret = kstrtoul(options, 0, &addr);
  204682. + if (ret)
  204683. + return ret;
  204684. + port->mapbase = addr;
  204685. + } else {
  204686. + return -EINVAL;
  204687. + }
  204688. +
  204689. + port->uartclk = BASE_BAUD * 16;
  204690. +
  204691. + options = strchr(options, ',');
  204692. + if (options) {
  204693. + options++;
  204694. + ret = kstrtouint(options, 0, &device->baud);
  204695. + if (ret)
  204696. + return ret;
  204697. + length = min(strcspn(options, " ") + 1,
  204698. + (size_t)(sizeof(device->options)));
  204699. + strlcpy(device->options, options, length);
  204700. + }
  204701. +
  204702. + if (mmio || mmio32)
  204703. + pr_info("Early serial console at MMIO%s 0x%llx (options '%s')\n",
  204704. + mmio32 ? "32" : "",
  204705. + (unsigned long long)port->mapbase,
  204706. + device->options);
  204707. + else
  204708. + pr_info("Early serial console at I/O port 0x%lx (options '%s')\n",
  204709. + port->iobase,
  204710. + device->options);
  204711. +
  204712. + return 0;
  204713. +}
  204714. +
  204715. +int __init setup_earlycon(char *buf, const char *match,
  204716. + int (*setup)(struct earlycon_device *, const char *))
  204717. +{
  204718. + int err;
  204719. + size_t len;
  204720. + struct uart_port *port = &early_console_dev.port;
  204721. +
  204722. + if (!buf || !match || !setup)
  204723. + return 0;
  204724. +
  204725. + len = strlen(match);
  204726. + if (strncmp(buf, match, len))
  204727. + return 0;
  204728. + if (buf[len] && (buf[len] != ','))
  204729. + return 0;
  204730. +
  204731. + buf += len + 1;
  204732. +
  204733. + err = parse_options(&early_console_dev, buf);
  204734. + /* On parsing error, pass the options buf to the setup function */
  204735. + if (!err)
  204736. + buf = NULL;
  204737. +
  204738. + if (port->mapbase)
  204739. + port->membase = earlycon_map(port->mapbase, 64);
  204740. +
  204741. + early_console_dev.con->data = &early_console_dev;
  204742. + err = setup(&early_console_dev, buf);
  204743. + if (err < 0)
  204744. + return err;
  204745. + if (!early_console_dev.con->write)
  204746. + return -ENODEV;
  204747. +
  204748. + register_console(early_console_dev.con);
  204749. + return 0;
  204750. +}
  204751. diff -Nur linux-3.14.15/drivers/tty/serial/Kconfig linux-linaro-stable-mx6/drivers/tty/serial/Kconfig
  204752. --- linux-3.14.15/drivers/tty/serial/Kconfig 2014-07-31 23:51:43.000000000 +0200
  204753. +++ linux-linaro-stable-mx6/drivers/tty/serial/Kconfig 2014-08-20 19:31:49.188882141 +0200
  204754. @@ -7,6 +7,13 @@
  204755. menu "Serial drivers"
  204756. depends on HAS_IOMEM
  204757. +config SERIAL_EARLYCON
  204758. + bool
  204759. + help
  204760. + Support for early consoles with the earlycon parameter. This enables
  204761. + the console before standard serial driver is probed. The console is
  204762. + enabled when early_param is processed.
  204763. +
  204764. source "drivers/tty/serial/8250/Kconfig"
  204765. comment "Non-8250 serial port support"
  204766. diff -Nur linux-3.14.15/drivers/tty/serial/Makefile linux-linaro-stable-mx6/drivers/tty/serial/Makefile
  204767. --- linux-3.14.15/drivers/tty/serial/Makefile 2014-07-31 23:51:43.000000000 +0200
  204768. +++ linux-linaro-stable-mx6/drivers/tty/serial/Makefile 2014-08-20 19:31:49.188882141 +0200
  204769. @@ -5,6 +5,8 @@
  204770. obj-$(CONFIG_SERIAL_CORE) += serial_core.o
  204771. obj-$(CONFIG_SERIAL_21285) += 21285.o
  204772. +obj-$(CONFIG_SERIAL_EARLYCON) += earlycon.o
  204773. +
  204774. # These Sparc drivers have to appear before others such as 8250
  204775. # which share ttySx minor node space. Otherwise console device
  204776. # names change and other unplesantries.
  204777. diff -Nur linux-3.14.15/drivers/usb/chipidea/ci.h linux-linaro-stable-mx6/drivers/usb/chipidea/ci.h
  204778. --- linux-3.14.15/drivers/usb/chipidea/ci.h 2014-07-31 23:51:43.000000000 +0200
  204779. +++ linux-linaro-stable-mx6/drivers/usb/chipidea/ci.h 2014-08-20 19:31:49.240882364 +0200
  204780. @@ -139,8 +139,8 @@
  204781. * @roles: array of supported roles for this controller
  204782. * @role: current role
  204783. * @is_otg: if the device is otg-capable
  204784. - * @work: work for role changing
  204785. - * @wq: workqueue thread
  204786. + * @otg_task: the thread for handling otg task
  204787. + * @otg_wait: the otg event waitqueue head
  204788. * @qh_pool: allocation pool for queue heads
  204789. * @td_pool: allocation pool for transfer descriptors
  204790. * @gadget: device side representation for peripheral controller
  204791. @@ -165,6 +165,10 @@
  204792. * @b_sess_valid_event: indicates there is a vbus event, and handled
  204793. * at ci_otg_work
  204794. * @imx28_write_fix: Freescale imx28 needs swp instruction for writing
  204795. + * @supports_runtime_pm: if runtime pm is supported
  204796. + * @in_lpm: if the core in low power mode
  204797. + * @wakeup_int: if wakeup interrupt occur
  204798. + * @timer: timer to delay clock closing
  204799. */
  204800. struct ci_hdrc {
  204801. struct device *dev;
  204802. @@ -174,8 +178,8 @@
  204803. struct ci_role_driver *roles[CI_ROLE_END];
  204804. enum ci_role role;
  204805. bool is_otg;
  204806. - struct work_struct work;
  204807. - struct workqueue_struct *wq;
  204808. + struct task_struct *otg_task;
  204809. + wait_queue_head_t otg_wait;
  204810. struct dma_pool *qh_pool;
  204811. struct dma_pool *td_pool;
  204812. @@ -204,6 +208,10 @@
  204813. bool id_event;
  204814. bool b_sess_valid_event;
  204815. bool imx28_write_fix;
  204816. + bool supports_runtime_pm;
  204817. + bool in_lpm;
  204818. + bool wakeup_int;
  204819. + struct timer_list timer;
  204820. };
  204821. static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
  204822. diff -Nur linux-3.14.15/drivers/usb/chipidea/ci_hdrc_imx.c linux-linaro-stable-mx6/drivers/usb/chipidea/ci_hdrc_imx.c
  204823. --- linux-3.14.15/drivers/usb/chipidea/ci_hdrc_imx.c 2014-07-31 23:51:43.000000000 +0200
  204824. +++ linux-linaro-stable-mx6/drivers/usb/chipidea/ci_hdrc_imx.c 2014-08-20 19:31:49.240882364 +0200
  204825. @@ -19,11 +19,14 @@
  204826. #include <linux/dma-mapping.h>
  204827. #include <linux/usb/chipidea.h>
  204828. #include <linux/clk.h>
  204829. +#include <linux/busfreq-imx6.h>
  204830. #include "ci.h"
  204831. #include "ci_hdrc_imx.h"
  204832. -#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
  204833. +#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
  204834. +#define CI_HDRC_IMX_SUPPORT_RUNTIME_PM BIT(1)
  204835. +#define CI_HDRC_IMX_HOST_QUIRK BIT(2)
  204836. struct ci_hdrc_imx_platform_flag {
  204837. unsigned int flags;
  204838. @@ -32,12 +35,30 @@
  204839. static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
  204840. };
  204841. +static const struct ci_hdrc_imx_platform_flag imx23_usb_data = {
  204842. + .flags = CI_HDRC_IMX_HOST_QUIRK,
  204843. +};
  204844. +
  204845. static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
  204846. - .flags = CI_HDRC_IMX_IMX28_WRITE_FIX,
  204847. + .flags = CI_HDRC_IMX_IMX28_WRITE_FIX |
  204848. + CI_HDRC_IMX_HOST_QUIRK,
  204849. +};
  204850. +
  204851. +static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
  204852. + .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM |
  204853. + CI_HDRC_IMX_HOST_QUIRK,
  204854. +};
  204855. +
  204856. +static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
  204857. + .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM |
  204858. + CI_HDRC_IMX_HOST_QUIRK,
  204859. };
  204860. static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
  204861. + { .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
  204862. + { .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
  204863. { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
  204864. + { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
  204865. { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
  204866. { /* sentinel */ }
  204867. };
  204868. @@ -48,6 +69,8 @@
  204869. struct platform_device *ci_pdev;
  204870. struct clk *clk;
  204871. struct imx_usbmisc_data *usbmisc_data;
  204872. + bool supports_runtime_pm;
  204873. + bool in_lpm;
  204874. };
  204875. /* Common functions shared by usbmisc drivers */
  204876. @@ -123,8 +146,10 @@
  204877. return PTR_ERR(data->clk);
  204878. }
  204879. + request_bus_freq(BUS_FREQ_HIGH);
  204880. ret = clk_prepare_enable(data->clk);
  204881. if (ret) {
  204882. + release_bus_freq(BUS_FREQ_HIGH);
  204883. dev_err(&pdev->dev,
  204884. "Failed to prepare or enable clock, err=%d\n", ret);
  204885. return ret;
  204886. @@ -145,6 +170,14 @@
  204887. if (ret)
  204888. goto err_clk;
  204889. + if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM) {
  204890. + pdata.flags |= CI_HDRC_SUPPORTS_RUNTIME_PM;
  204891. + data->supports_runtime_pm = true;
  204892. + }
  204893. +
  204894. + if (imx_platform_flag->flags & CI_HDRC_IMX_HOST_QUIRK)
  204895. + pdata.flags |= CI_HDRC_IMX_EHCI_QUIRK;
  204896. +
  204897. if (data->usbmisc_data) {
  204898. ret = imx_usbmisc_init(data->usbmisc_data);
  204899. if (ret) {
  204900. @@ -165,6 +198,11 @@
  204901. goto err_clk;
  204902. }
  204903. + /* usbmisc needs to know dr mode to choose wakeup setting */
  204904. + if (data->usbmisc_data)
  204905. + data->usbmisc_data->available_role =
  204906. + ci_hdrc_query_available_role(data->ci_pdev);
  204907. +
  204908. if (data->usbmisc_data) {
  204909. ret = imx_usbmisc_init_post(data->usbmisc_data);
  204910. if (ret) {
  204911. @@ -174,10 +212,23 @@
  204912. }
  204913. }
  204914. + if (data->usbmisc_data) {
  204915. + ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
  204916. + if (ret) {
  204917. + dev_err(&pdev->dev, "usbmisc set_wakeup failed, ret=%d\n",
  204918. + ret);
  204919. + goto disable_device;
  204920. + }
  204921. + }
  204922. +
  204923. platform_set_drvdata(pdev, data);
  204924. - pm_runtime_no_callbacks(&pdev->dev);
  204925. - pm_runtime_enable(&pdev->dev);
  204926. + device_set_wakeup_capable(&pdev->dev, true);
  204927. +
  204928. + if (data->supports_runtime_pm) {
  204929. + pm_runtime_set_active(&pdev->dev);
  204930. + pm_runtime_enable(&pdev->dev);
  204931. + }
  204932. return 0;
  204933. @@ -185,6 +236,7 @@
  204934. ci_hdrc_remove_device(data->ci_pdev);
  204935. err_clk:
  204936. clk_disable_unprepare(data->clk);
  204937. + release_bus_freq(BUS_FREQ_HIGH);
  204938. return ret;
  204939. }
  204940. @@ -195,10 +247,119 @@
  204941. pm_runtime_disable(&pdev->dev);
  204942. ci_hdrc_remove_device(data->ci_pdev);
  204943. clk_disable_unprepare(data->clk);
  204944. + release_bus_freq(BUS_FREQ_HIGH);
  204945. return 0;
  204946. }
  204947. +#ifdef CONFIG_PM
  204948. +static int imx_controller_suspend(struct device *dev)
  204949. +{
  204950. + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
  204951. + int ret;
  204952. +
  204953. + dev_dbg(dev, "at %s\n", __func__);
  204954. +
  204955. + if (data->in_lpm)
  204956. + return 0;
  204957. +
  204958. + if (data->usbmisc_data) {
  204959. + ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true);
  204960. + if (ret) {
  204961. + dev_err(dev,
  204962. + "usbmisc set_wakeup failed, ret=%d\n",
  204963. + ret);
  204964. + return ret;
  204965. + }
  204966. + }
  204967. +
  204968. + clk_disable_unprepare(data->clk);
  204969. + release_bus_freq(BUS_FREQ_HIGH);
  204970. + data->in_lpm = true;
  204971. +
  204972. + return 0;
  204973. +}
  204974. +
  204975. +static int imx_controller_resume(struct device *dev)
  204976. +{
  204977. + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
  204978. + int ret = 0;
  204979. +
  204980. + dev_dbg(dev, "at %s\n", __func__);
  204981. +
  204982. + if (!data->in_lpm)
  204983. + return 0;
  204984. +
  204985. + request_bus_freq(BUS_FREQ_HIGH);
  204986. + ret = clk_prepare_enable(data->clk);
  204987. + if (ret) {
  204988. + release_bus_freq(BUS_FREQ_HIGH);
  204989. + return ret;
  204990. + }
  204991. +
  204992. + data->in_lpm = false;
  204993. +
  204994. + if (data->usbmisc_data) {
  204995. + ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
  204996. + if (ret) {
  204997. + dev_err(dev,
  204998. + "usbmisc set_wakeup failed, ret=%d\n",
  204999. + ret);
  205000. + ret = -EINVAL;
  205001. + goto clk_disable;
  205002. + }
  205003. + }
  205004. +
  205005. + return 0;
  205006. +
  205007. +clk_disable:
  205008. + clk_disable_unprepare(data->clk);
  205009. + release_bus_freq(BUS_FREQ_HIGH);
  205010. +
  205011. + return ret;
  205012. +}
  205013. +
  205014. +#ifdef CONFIG_PM_SLEEP
  205015. +static int ci_hdrc_imx_suspend(struct device *dev)
  205016. +{
  205017. + return imx_controller_suspend(dev);
  205018. +}
  205019. +
  205020. +static int ci_hdrc_imx_resume(struct device *dev)
  205021. +{
  205022. + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
  205023. + int ret;
  205024. +
  205025. + ret = imx_controller_resume(dev);
  205026. + if (!ret && data->supports_runtime_pm) {
  205027. + pm_runtime_disable(dev);
  205028. + pm_runtime_set_active(dev);
  205029. + pm_runtime_enable(dev);
  205030. + }
  205031. +
  205032. + return ret;
  205033. +}
  205034. +#endif /* CONFIG_PM_SLEEP */
  205035. +
  205036. +#ifdef CONFIG_PM_RUNTIME
  205037. +static int ci_hdrc_imx_runtime_suspend(struct device *dev)
  205038. +{
  205039. + return imx_controller_suspend(dev);
  205040. +}
  205041. +
  205042. +static int ci_hdrc_imx_runtime_resume(struct device *dev)
  205043. +{
  205044. + return imx_controller_resume(dev);
  205045. +}
  205046. +#endif /* CONFIG_PM_RUNTIME */
  205047. +
  205048. +#endif /* CONFIG_PM */
  205049. +static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
  205050. + SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
  205051. + SET_RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend,
  205052. + ci_hdrc_imx_runtime_resume, NULL)
  205053. +};
  205054. +
  205055. static struct platform_driver ci_hdrc_imx_driver = {
  205056. .probe = ci_hdrc_imx_probe,
  205057. .remove = ci_hdrc_imx_remove,
  205058. @@ -206,6 +367,7 @@
  205059. .name = "imx_usb",
  205060. .owner = THIS_MODULE,
  205061. .of_match_table = ci_hdrc_imx_dt_ids,
  205062. + .pm = &ci_hdrc_imx_pm_ops,
  205063. },
  205064. };
  205065. diff -Nur linux-3.14.15/drivers/usb/chipidea/ci_hdrc_imx.h linux-linaro-stable-mx6/drivers/usb/chipidea/ci_hdrc_imx.h
  205066. --- linux-3.14.15/drivers/usb/chipidea/ci_hdrc_imx.h 2014-07-31 23:51:43.000000000 +0200
  205067. +++ linux-linaro-stable-mx6/drivers/usb/chipidea/ci_hdrc_imx.h 2014-08-20 19:31:49.240882364 +0200
  205068. @@ -1,5 +1,5 @@
  205069. /*
  205070. - * Copyright 2012 Freescale Semiconductor, Inc.
  205071. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  205072. *
  205073. * The code contained herein is licensed under the GNU General Public
  205074. * License. You may obtain a copy of the GNU General Public License
  205075. @@ -12,14 +12,18 @@
  205076. #ifndef __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H
  205077. #define __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H
  205078. +#include <linux/usb/otg.h>
  205079. +
  205080. struct imx_usbmisc_data {
  205081. int index;
  205082. unsigned int disable_oc:1; /* over current detect disabled */
  205083. unsigned int evdo:1; /* set external vbus divider option */
  205084. + enum usb_dr_mode available_role;
  205085. };
  205086. int imx_usbmisc_init(struct imx_usbmisc_data *);
  205087. int imx_usbmisc_init_post(struct imx_usbmisc_data *);
  205088. +int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *, bool);
  205089. #endif /* __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H */
  205090. diff -Nur linux-3.14.15/drivers/usb/chipidea/ci_hdrc_msm.c linux-linaro-stable-mx6/drivers/usb/chipidea/ci_hdrc_msm.c
  205091. --- linux-3.14.15/drivers/usb/chipidea/ci_hdrc_msm.c 2014-07-31 23:51:43.000000000 +0200
  205092. +++ linux-linaro-stable-mx6/drivers/usb/chipidea/ci_hdrc_msm.c 2014-08-20 19:23:57.250861602 +0200
  205093. @@ -17,7 +17,7 @@
  205094. #define MSM_USB_BASE (ci->hw_bank.abs)
  205095. -static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
  205096. +static int ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
  205097. {
  205098. struct device *dev = ci->gadget.dev.parent;
  205099. int val;
  205100. @@ -43,6 +43,8 @@
  205101. dev_dbg(dev, "unknown ci_hdrc event\n");
  205102. break;
  205103. }
  205104. +
  205105. + return 0;
  205106. }
  205107. static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
  205108. diff -Nur linux-3.14.15/drivers/usb/chipidea/core.c linux-linaro-stable-mx6/drivers/usb/chipidea/core.c
  205109. --- linux-3.14.15/drivers/usb/chipidea/core.c 2014-07-31 23:51:43.000000000 +0200
  205110. +++ linux-linaro-stable-mx6/drivers/usb/chipidea/core.c 2014-08-20 19:31:49.240882364 +0200
  205111. @@ -165,25 +165,30 @@
  205112. return hw_read(ci, OP_PORTSC, PORTSC_PTC) >> __ffs(PORTSC_PTC);
  205113. }
  205114. +static void hw_wait_phy_stable(void)
  205115. +{
  205116. + /* The controller needs at least 1ms to reflect PHY's status */
  205117. + usleep_range(2000, 2500);
  205118. +}
  205119. +
  205120. +static void delay_runtime_pm_put_timer(unsigned long arg)
  205121. +{
  205122. + struct ci_hdrc *ci = (struct ci_hdrc *)arg;
  205123. +
  205124. + pm_runtime_put(ci->dev);
  205125. +}
  205126. +
  205127. /* The PHY enters/leaves low power mode */
  205128. static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable)
  205129. {
  205130. enum ci_hw_regs reg = ci->hw_bank.lpm ? OP_DEVLC : OP_PORTSC;
  205131. bool lpm = !!(hw_read(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm)));
  205132. - if (enable && !lpm) {
  205133. + if (enable && !lpm)
  205134. hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
  205135. PORTSC_PHCD(ci->hw_bank.lpm));
  205136. - } else if (!enable && lpm) {
  205137. - hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
  205138. - 0);
  205139. - /*
  205140. - * The controller needs at least 1ms to reflect
  205141. - * PHY's status, the PHY also needs some time (less
  205142. - * than 1ms) to leave low power mode.
  205143. - */
  205144. - usleep_range(1500, 2000);
  205145. - }
  205146. + else if (!enable && lpm)
  205147. + hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm), 0);
  205148. }
  205149. static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
  205150. @@ -351,6 +356,13 @@
  205151. irqreturn_t ret = IRQ_NONE;
  205152. u32 otgsc = 0;
  205153. + if (ci->in_lpm) {
  205154. + disable_irq_nosync(irq);
  205155. + ci->wakeup_int = true;
  205156. + pm_runtime_get(ci->dev);
  205157. + return IRQ_HANDLED;
  205158. + }
  205159. +
  205160. if (ci->is_otg)
  205161. otgsc = hw_read(ci, OP_OTGSC, ~0);
  205162. @@ -362,7 +374,7 @@
  205163. ci->id_event = true;
  205164. ci_clear_otg_interrupt(ci, OTGSC_IDIS);
  205165. disable_irq_nosync(ci->irq);
  205166. - queue_work(ci->wq, &ci->work);
  205167. + wake_up(&ci->otg_wait);
  205168. return IRQ_HANDLED;
  205169. }
  205170. @@ -374,7 +386,7 @@
  205171. ci->b_sess_valid_event = true;
  205172. ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
  205173. disable_irq_nosync(ci->irq);
  205174. - queue_work(ci->wq, &ci->work);
  205175. + wake_up(&ci->otg_wait);
  205176. return IRQ_HANDLED;
  205177. }
  205178. @@ -473,6 +485,33 @@
  205179. }
  205180. EXPORT_SYMBOL_GPL(ci_hdrc_remove_device);
  205181. +/**
  205182. + * ci_hdrc_query_available_role: get runtime available operation mode
  205183. + *
  205184. + * The glue layer can get current operation mode (host/peripheral/otg)
  205185. + * This function should be called after ci core device has created.
  205186. + *
  205187. + * @pdev: the platform device of ci core.
  205188. + *
  205189. + * Return USB_DR_MODE_XXX.
  205190. + */
  205191. +enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev)
  205192. +{
  205193. + struct ci_hdrc *ci = platform_get_drvdata(pdev);
  205194. +
  205195. + if (!ci)
  205196. + return USB_DR_MODE_UNKNOWN;
  205197. + if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET])
  205198. + return USB_DR_MODE_OTG;
  205199. + else if (ci->roles[CI_ROLE_HOST])
  205200. + return USB_DR_MODE_HOST;
  205201. + else if (ci->roles[CI_ROLE_GADGET])
  205202. + return USB_DR_MODE_PERIPHERAL;
  205203. + else
  205204. + return USB_DR_MODE_UNKNOWN;
  205205. +}
  205206. +EXPORT_SYMBOL_GPL(ci_hdrc_query_available_role);
  205207. +
  205208. static inline void ci_role_destroy(struct ci_hdrc *ci)
  205209. {
  205210. ci_hdrc_gadget_destroy(ci);
  205211. @@ -498,9 +537,14 @@
  205212. static int ci_usb_phy_init(struct ci_hdrc *ci)
  205213. {
  205214. + int ret;
  205215. +
  205216. if (ci->platdata->phy) {
  205217. ci->transceiver = ci->platdata->phy;
  205218. - return usb_phy_init(ci->transceiver);
  205219. + ret = usb_phy_init(ci->transceiver);
  205220. + if (!ret)
  205221. + hw_wait_phy_stable();
  205222. + return ret;
  205223. } else {
  205224. ci->global_phy = true;
  205225. ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
  205226. @@ -559,8 +603,6 @@
  205227. return -ENODEV;
  205228. }
  205229. - hw_phymode_configure(ci);
  205230. -
  205231. ret = ci_usb_phy_init(ci);
  205232. if (ret) {
  205233. dev_err(dev, "unable to init phy: %d\n", ret);
  205234. @@ -578,7 +620,13 @@
  205235. ci_get_otg_capable(ci);
  205236. + hw_phymode_configure(ci);
  205237. +
  205238. dr_mode = ci->platdata->dr_mode;
  205239. +
  205240. + ci->supports_runtime_pm = !!(ci->platdata->flags &
  205241. + CI_HDRC_SUPPORTS_RUNTIME_PM);
  205242. +
  205243. /* initialize role(s) before the interrupt is requested */
  205244. if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
  205245. ret = ci_hdrc_host_init(ci);
  205246. @@ -619,11 +667,6 @@
  205247. if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
  205248. if (ci->is_otg) {
  205249. - /*
  205250. - * ID pin needs 1ms debouce time,
  205251. - * we delay 2ms for safe.
  205252. - */
  205253. - mdelay(2);
  205254. ci->role = ci_otg_role(ci);
  205255. ci_enable_otg_interrupt(ci, OTGSC_IDIE);
  205256. } else {
  205257. @@ -656,6 +699,15 @@
  205258. if (ret)
  205259. goto stop;
  205260. + device_set_wakeup_capable(&pdev->dev, true);
  205261. +
  205262. + if (ci->supports_runtime_pm) {
  205263. + pm_runtime_set_active(&pdev->dev);
  205264. + pm_runtime_enable(&pdev->dev);
  205265. + }
  205266. +
  205267. + setup_timer(&ci->timer, delay_runtime_pm_put_timer,
  205268. + (unsigned long)ci);
  205269. ret = dbg_create_files(ci);
  205270. if (!ret)
  205271. return 0;
  205272. @@ -673,6 +725,11 @@
  205273. {
  205274. struct ci_hdrc *ci = platform_get_drvdata(pdev);
  205275. + if (ci->supports_runtime_pm) {
  205276. + pm_runtime_get_sync(&pdev->dev);
  205277. + pm_runtime_disable(&pdev->dev);
  205278. + pm_runtime_put_noidle(&pdev->dev);
  205279. + }
  205280. dbg_remove_files(ci);
  205281. free_irq(ci->irq, ci);
  205282. ci_role_destroy(ci);
  205283. @@ -682,11 +739,120 @@
  205284. return 0;
  205285. }
  205286. +#ifdef CONFIG_PM
  205287. +static int ci_controller_suspend(struct device *dev)
  205288. +{
  205289. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  205290. +
  205291. + dev_dbg(dev, "at %s\n", __func__);
  205292. +
  205293. + if (ci->in_lpm)
  205294. + return 0;
  205295. +
  205296. + disable_irq(ci->irq);
  205297. +
  205298. + if (ci->transceiver)
  205299. + usb_phy_set_wakeup(ci->transceiver, true);
  205300. +
  205301. + ci_hdrc_enter_lpm(ci, true);
  205302. +
  205303. + if (ci->transceiver)
  205304. + usb_phy_set_suspend(ci->transceiver, 1);
  205305. +
  205306. + ci->in_lpm = true;
  205307. +
  205308. + enable_irq(ci->irq);
  205309. +
  205310. + return 0;
  205311. +}
  205312. +
  205313. +static int ci_controller_resume(struct device *dev)
  205314. +{
  205315. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  205316. +
  205317. + dev_dbg(dev, "at %s\n", __func__);
  205318. +
  205319. + if (!ci->in_lpm)
  205320. + return 0;
  205321. +
  205322. + ci_hdrc_enter_lpm(ci, false);
  205323. +
  205324. + if (ci->transceiver) {
  205325. + usb_phy_set_suspend(ci->transceiver, 0);
  205326. + usb_phy_set_wakeup(ci->transceiver, false);
  205327. + hw_wait_phy_stable();
  205328. + }
  205329. +
  205330. + ci->in_lpm = false;
  205331. +
  205332. + if (ci->wakeup_int) {
  205333. + ci->wakeup_int = false;
  205334. + enable_irq(ci->irq);
  205335. + mod_timer(&ci->timer, jiffies + msecs_to_jiffies(2000));
  205336. + }
  205337. +
  205338. + return 0;
  205339. +}
  205340. +
  205341. +#ifdef CONFIG_PM_SLEEP
  205342. +static int ci_suspend(struct device *dev)
  205343. +{
  205344. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  205345. + int ret;
  205346. +
  205347. + ret = ci_controller_suspend(dev);
  205348. + if (ret)
  205349. + return ret;
  205350. +
  205351. + if (device_may_wakeup(dev))
  205352. + enable_irq_wake(ci->irq);
  205353. +
  205354. + return ret;
  205355. +}
  205356. +
  205357. +static int ci_resume(struct device *dev)
  205358. +{
  205359. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  205360. + int ret;
  205361. +
  205362. + if (device_may_wakeup(dev))
  205363. + disable_irq_wake(ci->irq);
  205364. +
  205365. + ret = ci_controller_resume(dev);
  205366. + if (!ret && ci->supports_runtime_pm) {
  205367. + pm_runtime_disable(dev);
  205368. + pm_runtime_set_active(dev);
  205369. + pm_runtime_enable(dev);
  205370. + }
  205371. +
  205372. + return ret;
  205373. +}
  205374. +#endif /* CONFIG_PM_SLEEP */
  205375. +
  205376. +#ifdef CONFIG_PM_RUNTIME
  205377. +static int ci_runtime_suspend(struct device *dev)
  205378. +{
  205379. + return ci_controller_suspend(dev);
  205380. +}
  205381. +
  205382. +static int ci_runtime_resume(struct device *dev)
  205383. +{
  205384. + return ci_controller_resume(dev);
  205385. +}
  205386. +#endif /* CONFIG_PM_RUNTIME */
  205387. +
  205388. +#endif /* CONFIG_PM */
  205389. +static const struct dev_pm_ops ci_pm_ops = {
  205390. + SET_SYSTEM_SLEEP_PM_OPS(ci_suspend, ci_resume)
  205391. + SET_RUNTIME_PM_OPS(ci_runtime_suspend, ci_runtime_resume, NULL)
  205392. +};
  205393. +
  205394. static struct platform_driver ci_hdrc_driver = {
  205395. .probe = ci_hdrc_probe,
  205396. .remove = ci_hdrc_remove,
  205397. .driver = {
  205398. .name = "ci_hdrc",
  205399. + .pm = &ci_pm_ops,
  205400. },
  205401. };
  205402. diff -Nur linux-3.14.15/drivers/usb/chipidea/host.c linux-linaro-stable-mx6/drivers/usb/chipidea/host.c
  205403. --- linux-3.14.15/drivers/usb/chipidea/host.c 2014-07-31 23:51:43.000000000 +0200
  205404. +++ linux-linaro-stable-mx6/drivers/usb/chipidea/host.c 2014-08-20 19:31:49.240882364 +0200
  205405. @@ -33,6 +33,176 @@
  205406. #include "host.h"
  205407. static struct hc_driver __read_mostly ci_ehci_hc_driver;
  205408. +static int (*orig_bus_suspend)(struct usb_hcd *hcd);
  205409. +static int (*orig_bus_resume)(struct usb_hcd *hcd);
  205410. +static int (*orig_hub_control)(struct usb_hcd *hcd,
  205411. + u16 typeReq, u16 wValue, u16 wIndex,
  205412. + char *buf, u16 wLength);
  205413. +
  205414. +static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
  205415. +{
  205416. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  205417. + int port;
  205418. + u32 tmp;
  205419. +
  205420. + int ret = orig_bus_suspend(hcd);
  205421. +
  205422. + if (ret)
  205423. + return ret;
  205424. +
  205425. + port = HCS_N_PORTS(ehci->hcs_params);
  205426. + while (port--) {
  205427. + u32 __iomem *reg = &ehci->regs->port_status[port];
  205428. + u32 portsc = ehci_readl(ehci, reg);
  205429. +
  205430. + if (portsc & PORT_CONNECT) {
  205431. + /*
  205432. + * For chipidea, the resume signal will be ended
  205433. + * automatically, so for remote wakeup case, the
  205434. + * usbcmd.rs may not be set before the resume has
  205435. + * ended if other resume path consumes too much
  205436. + * time (~23ms-24ms), in that case, the SOF will not
  205437. + * send out within 3ms after resume ends, then the
  205438. + * device will enter suspend again.
  205439. + */
  205440. + if (hcd->self.root_hub->do_remote_wakeup) {
  205441. + ehci_dbg(ehci,
  205442. + "Remote wakeup is enabled, "
  205443. + "and device is on the port\n");
  205444. +
  205445. + tmp = ehci_readl(ehci, &ehci->regs->command);
  205446. + tmp |= CMD_RUN;
  205447. + ehci_writel(ehci, tmp, &ehci->regs->command);
  205448. + /*
  205449. + * It needs a short delay between set RUNSTOP
  205450. + * and set PHCD.
  205451. + */
  205452. + udelay(125);
  205453. + }
  205454. + if (hcd->phy && test_bit(port, &ehci->bus_suspended)
  205455. + && (ehci_port_speed(ehci, portsc) ==
  205456. + USB_PORT_STAT_HIGH_SPEED))
  205457. + /*
  205458. + * notify the USB PHY, it is for global
  205459. + * suspend case.
  205460. + */
  205461. + usb_phy_notify_suspend(hcd->phy,
  205462. + USB_SPEED_HIGH);
  205463. + }
  205464. + }
  205465. +
  205466. + return 0;
  205467. +}
  205468. +
  205469. +static int ci_imx_ehci_bus_resume(struct usb_hcd *hcd)
  205470. +{
  205471. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  205472. + int port;
  205473. +
  205474. + int ret = orig_bus_resume(hcd);
  205475. +
  205476. + if (ret)
  205477. + return ret;
  205478. +
  205479. + port = HCS_N_PORTS(ehci->hcs_params);
  205480. + while (port--) {
  205481. + u32 __iomem *reg = &ehci->regs->port_status[port];
  205482. + u32 portsc = ehci_readl(ehci, reg);
  205483. + /*
  205484. + * Notify PHY after resume signal has finished, it is
  205485. + * for global suspend case.
  205486. + */
  205487. + if (hcd->phy
  205488. + && test_bit(port, &ehci->bus_suspended)
  205489. + && (portsc & PORT_CONNECT)
  205490. + && (ehci_port_speed(ehci, portsc) ==
  205491. + USB_PORT_STAT_HIGH_SPEED))
  205492. + /* notify the USB PHY */
  205493. + usb_phy_notify_resume(hcd->phy, USB_SPEED_HIGH);
  205494. + }
  205495. +
  205496. + return 0;
  205497. +}
  205498. +
  205499. +/* The below code is based on tegra ehci driver */
  205500. +static int ci_imx_ehci_hub_control(
  205501. + struct usb_hcd *hcd,
  205502. + u16 typeReq,
  205503. + u16 wValue,
  205504. + u16 wIndex,
  205505. + char *buf,
  205506. + u16 wLength
  205507. +)
  205508. +{
  205509. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  205510. + u32 __iomem *status_reg;
  205511. + u32 temp;
  205512. + unsigned long flags;
  205513. + int retval = 0;
  205514. +
  205515. + status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
  205516. +
  205517. + spin_lock_irqsave(&ehci->lock, flags);
  205518. +
  205519. + if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
  205520. + temp = ehci_readl(ehci, status_reg);
  205521. + if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
  205522. + retval = -EPIPE;
  205523. + goto done;
  205524. + }
  205525. +
  205526. + temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
  205527. + temp |= PORT_WKDISC_E | PORT_WKOC_E;
  205528. + ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
  205529. +
  205530. + /*
  205531. + * If a transaction is in progress, there may be a delay in
  205532. + * suspending the port. Poll until the port is suspended.
  205533. + */
  205534. + if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
  205535. + PORT_SUSPEND, 5000))
  205536. + ehci_err(ehci, "timeout waiting for SUSPEND\n");
  205537. +
  205538. + spin_unlock_irqrestore(&ehci->lock, flags);
  205539. + if (ehci_port_speed(ehci, temp) ==
  205540. + USB_PORT_STAT_HIGH_SPEED && hcd->phy) {
  205541. + /* notify the USB PHY */
  205542. + usb_phy_notify_suspend(hcd->phy, USB_SPEED_HIGH);
  205543. + }
  205544. + spin_lock_irqsave(&ehci->lock, flags);
  205545. +
  205546. + set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
  205547. + goto done;
  205548. + }
  205549. +
  205550. + /*
  205551. + * After resume has finished, it needs do some post resume
  205552. + * operation for some SoCs.
  205553. + */
  205554. + else if (typeReq == ClearPortFeature &&
  205555. + wValue == USB_PORT_FEAT_C_SUSPEND) {
  205556. +
  205557. + /* Make sure the resume has finished, it should be finished */
  205558. + if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 25000))
  205559. + ehci_err(ehci, "timeout waiting for resume\n");
  205560. +
  205561. + temp = ehci_readl(ehci, status_reg);
  205562. +
  205563. + if (ehci_port_speed(ehci, temp) ==
  205564. + USB_PORT_STAT_HIGH_SPEED && hcd->phy) {
  205565. + /* notify the USB PHY */
  205566. + usb_phy_notify_resume(hcd->phy, USB_SPEED_HIGH);
  205567. + }
  205568. + }
  205569. +
  205570. + spin_unlock_irqrestore(&ehci->lock, flags);
  205571. +
  205572. + /* Handle the hub control events here */
  205573. + return orig_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
  205574. +done:
  205575. + spin_unlock_irqrestore(&ehci->lock, flags);
  205576. + return retval;
  205577. +}
  205578. static irqreturn_t host_irq(struct ci_hdrc *ci)
  205579. {
  205580. @@ -64,7 +234,6 @@
  205581. ehci = hcd_to_ehci(hcd);
  205582. ehci->caps = ci->hw_bank.cap;
  205583. ehci->has_hostpc = ci->hw_bank.lpm;
  205584. - ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
  205585. ehci->imx28_write_fix = ci->imx28_write_fix;
  205586. if (ci->platdata->reg_vbus) {
  205587. @@ -136,5 +305,15 @@
  205588. ehci_init_driver(&ci_ehci_hc_driver, NULL);
  205589. + orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
  205590. + orig_bus_resume = ci_ehci_hc_driver.bus_resume;
  205591. + orig_hub_control = ci_ehci_hc_driver.hub_control;
  205592. +
  205593. + ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
  205594. + if (ci->platdata->flags & CI_HDRC_IMX_EHCI_QUIRK) {
  205595. + ci_ehci_hc_driver.bus_resume = ci_imx_ehci_bus_resume;
  205596. + ci_ehci_hc_driver.hub_control = ci_imx_ehci_hub_control;
  205597. + }
  205598. +
  205599. return 0;
  205600. }
  205601. diff -Nur linux-3.14.15/drivers/usb/chipidea/otg.c linux-linaro-stable-mx6/drivers/usb/chipidea/otg.c
  205602. --- linux-3.14.15/drivers/usb/chipidea/otg.c 2014-07-31 23:51:43.000000000 +0200
  205603. +++ linux-linaro-stable-mx6/drivers/usb/chipidea/otg.c 2014-08-20 19:31:49.240882364 +0200
  205604. @@ -18,6 +18,8 @@
  205605. #include <linux/usb/otg.h>
  205606. #include <linux/usb/gadget.h>
  205607. #include <linux/usb/chipidea.h>
  205608. +#include <linux/kthread.h>
  205609. +#include <linux/freezer.h>
  205610. #include "ci.h"
  205611. #include "bits.h"
  205612. @@ -68,26 +70,53 @@
  205613. ci_role_start(ci, role);
  205614. }
  205615. }
  205616. +
  205617. +/* If there is pending otg event */
  205618. +static inline bool ci_otg_event_is_pending(struct ci_hdrc *ci)
  205619. +{
  205620. + return ci->id_event || ci->b_sess_valid_event;
  205621. +}
  205622. +
  205623. /**
  205624. - * ci_otg_work - perform otg (vbus/id) event handle
  205625. - * @work: work struct
  205626. + * ci_otg_event - perform otg (vbus/id) event handle
  205627. + * @ci: ci_hdrc struct
  205628. */
  205629. -static void ci_otg_work(struct work_struct *work)
  205630. +static void ci_otg_event(struct ci_hdrc *ci)
  205631. {
  205632. - struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
  205633. -
  205634. if (ci->id_event) {
  205635. ci->id_event = false;
  205636. + /* Keep controller active during id switch */
  205637. + pm_runtime_get_sync(ci->dev);
  205638. ci_handle_id_switch(ci);
  205639. + pm_runtime_put_sync(ci->dev);
  205640. } else if (ci->b_sess_valid_event) {
  205641. ci->b_sess_valid_event = false;
  205642. + pm_runtime_get_sync(ci->dev);
  205643. ci_handle_vbus_change(ci);
  205644. + pm_runtime_put_sync(ci->dev);
  205645. } else
  205646. - dev_err(ci->dev, "unexpected event occurs at %s\n", __func__);
  205647. + dev_dbg(ci->dev, "it should be quit event\n");
  205648. enable_irq(ci->irq);
  205649. }
  205650. +static int ci_otg_thread(void *ptr)
  205651. +{
  205652. + struct ci_hdrc *ci = ptr;
  205653. +
  205654. + set_freezable();
  205655. +
  205656. + do {
  205657. + wait_event_freezable(ci->otg_wait,
  205658. + ci_otg_event_is_pending(ci) ||
  205659. + kthread_should_stop());
  205660. + ci_otg_event(ci);
  205661. + } while (!kthread_should_stop());
  205662. +
  205663. + dev_warn(ci->dev, "ci_otg_thread quits\n");
  205664. +
  205665. + return 0;
  205666. +}
  205667. /**
  205668. * ci_hdrc_otg_init - initialize otg struct
  205669. @@ -95,11 +124,11 @@
  205670. */
  205671. int ci_hdrc_otg_init(struct ci_hdrc *ci)
  205672. {
  205673. - INIT_WORK(&ci->work, ci_otg_work);
  205674. - ci->wq = create_singlethread_workqueue("ci_otg");
  205675. - if (!ci->wq) {
  205676. - dev_err(ci->dev, "can't create workqueue\n");
  205677. - return -ENODEV;
  205678. + init_waitqueue_head(&ci->otg_wait);
  205679. + ci->otg_task = kthread_run(ci_otg_thread, ci, "ci otg thread");
  205680. + if (IS_ERR(ci->otg_task)) {
  205681. + dev_err(ci->dev, "error to create otg thread\n");
  205682. + return PTR_ERR(ci->otg_task);
  205683. }
  205684. return 0;
  205685. @@ -111,10 +140,7 @@
  205686. */
  205687. void ci_hdrc_otg_destroy(struct ci_hdrc *ci)
  205688. {
  205689. - if (ci->wq) {
  205690. - flush_workqueue(ci->wq);
  205691. - destroy_workqueue(ci->wq);
  205692. - }
  205693. + kthread_stop(ci->otg_task);
  205694. ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
  205695. ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
  205696. }
  205697. diff -Nur linux-3.14.15/drivers/usb/chipidea/udc.c linux-linaro-stable-mx6/drivers/usb/chipidea/udc.c
  205698. --- linux-3.14.15/drivers/usb/chipidea/udc.c 2014-07-31 23:51:43.000000000 +0200
  205699. +++ linux-linaro-stable-mx6/drivers/usb/chipidea/udc.c 2014-08-20 19:31:49.244882382 +0200
  205700. @@ -681,12 +681,6 @@
  205701. struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
  205702. unsigned long flags;
  205703. - spin_lock_irqsave(&ci->lock, flags);
  205704. - ci->gadget.speed = USB_SPEED_UNKNOWN;
  205705. - ci->remote_wakeup = 0;
  205706. - ci->suspended = 0;
  205707. - spin_unlock_irqrestore(&ci->lock, flags);
  205708. -
  205709. /* flush all endpoints */
  205710. gadget_for_each_ep(ep, gadget) {
  205711. usb_ep_fifo_flush(ep);
  205712. @@ -704,6 +698,12 @@
  205713. ci->status = NULL;
  205714. }
  205715. + spin_lock_irqsave(&ci->lock, flags);
  205716. + ci->gadget.speed = USB_SPEED_UNKNOWN;
  205717. + ci->remote_wakeup = 0;
  205718. + ci->suspended = 0;
  205719. + spin_unlock_irqrestore(&ci->lock, flags);
  205720. +
  205721. return 0;
  205722. }
  205723. @@ -1222,6 +1222,10 @@
  205724. return -EBUSY;
  205725. spin_lock_irqsave(hwep->lock, flags);
  205726. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  205727. + spin_unlock_irqrestore(hwep->lock, flags);
  205728. + return 0;
  205729. + }
  205730. /* only internal SW should disable ctrl endpts */
  205731. @@ -1311,6 +1315,10 @@
  205732. return -EINVAL;
  205733. spin_lock_irqsave(hwep->lock, flags);
  205734. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  205735. + spin_unlock_irqrestore(hwep->lock, flags);
  205736. + return 0;
  205737. + }
  205738. retval = _ep_queue(ep, req, gfp_flags);
  205739. spin_unlock_irqrestore(hwep->lock, flags);
  205740. return retval;
  205741. @@ -1334,8 +1342,8 @@
  205742. return -EINVAL;
  205743. spin_lock_irqsave(hwep->lock, flags);
  205744. -
  205745. - hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
  205746. + if (hwep->ci->gadget.speed != USB_SPEED_UNKNOWN)
  205747. + hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
  205748. list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) {
  205749. dma_pool_free(hwep->td_pool, node->ptr, node->dma);
  205750. @@ -1379,6 +1387,10 @@
  205751. spin_lock_irqsave(hwep->lock, flags);
  205752. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  205753. + spin_unlock_irqrestore(hwep->lock, flags);
  205754. + return 0;
  205755. + }
  205756. #ifndef STALL_IN
  205757. /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
  205758. if (value && hwep->type == USB_ENDPOINT_XFER_BULK && hwep->dir == TX &&
  205759. @@ -1440,6 +1452,10 @@
  205760. }
  205761. spin_lock_irqsave(hwep->lock, flags);
  205762. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  205763. + spin_unlock_irqrestore(hwep->lock, flags);
  205764. + return;
  205765. + }
  205766. hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
  205767. @@ -1506,6 +1522,10 @@
  205768. int ret = 0;
  205769. spin_lock_irqsave(&ci->lock, flags);
  205770. + if (ci->gadget.speed == USB_SPEED_UNKNOWN) {
  205771. + spin_unlock_irqrestore(&ci->lock, flags);
  205772. + return 0;
  205773. + }
  205774. if (!ci->remote_wakeup) {
  205775. ret = -EOPNOTSUPP;
  205776. goto out;
  205777. diff -Nur linux-3.14.15/drivers/usb/chipidea/usbmisc_imx.c linux-linaro-stable-mx6/drivers/usb/chipidea/usbmisc_imx.c
  205778. --- linux-3.14.15/drivers/usb/chipidea/usbmisc_imx.c 2014-07-31 23:51:43.000000000 +0200
  205779. +++ linux-linaro-stable-mx6/drivers/usb/chipidea/usbmisc_imx.c 2014-08-20 19:31:49.244882382 +0200
  205780. @@ -1,5 +1,5 @@
  205781. /*
  205782. - * Copyright 2012 Freescale Semiconductor, Inc.
  205783. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  205784. *
  205785. * The code contained herein is licensed under the GNU General Public
  205786. * License. You may obtain a copy of the GNU General Public License
  205787. @@ -11,10 +11,10 @@
  205788. #include <linux/module.h>
  205789. #include <linux/of_platform.h>
  205790. -#include <linux/clk.h>
  205791. #include <linux/err.h>
  205792. #include <linux/io.h>
  205793. #include <linux/delay.h>
  205794. +#include <linux/regulator/consumer.h>
  205795. #include "ci_hdrc_imx.h"
  205796. @@ -33,22 +33,28 @@
  205797. #define MX53_BM_OVER_CUR_DIS_UHx BIT(30)
  205798. #define MX6_BM_OVER_CUR_DIS BIT(7)
  205799. +#define MX6_BM_WAKEUP_ENABLE BIT(10)
  205800. +#define MX6_BM_ID_WAKEUP BIT(16)
  205801. +#define MX6_BM_VBUS_WAKEUP BIT(17)
  205802. +#define MX6_BM_WAKEUP_INTR BIT(31)
  205803. struct usbmisc_ops {
  205804. /* It's called once when probe a usb device */
  205805. int (*init)(struct imx_usbmisc_data *data);
  205806. /* It's called once after adding a usb device */
  205807. int (*post)(struct imx_usbmisc_data *data);
  205808. + /* It's called when we need to enable usb wakeup */
  205809. + int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled);
  205810. };
  205811. struct imx_usbmisc {
  205812. void __iomem *base;
  205813. spinlock_t lock;
  205814. - struct clk *clk;
  205815. const struct usbmisc_ops *ops;
  205816. };
  205817. static struct imx_usbmisc *usbmisc;
  205818. +static struct regulator *vbus_wakeup_reg;
  205819. static int usbmisc_imx25_post(struct imx_usbmisc_data *data)
  205820. {
  205821. @@ -158,6 +164,47 @@
  205822. return 0;
  205823. }
  205824. +static u32 imx6q_finalize_wakeup_setting(struct imx_usbmisc_data *data)
  205825. +{
  205826. + if (data->available_role == USB_DR_MODE_PERIPHERAL)
  205827. + return MX6_BM_VBUS_WAKEUP;
  205828. + else if (data->available_role == USB_DR_MODE_OTG)
  205829. + return MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP;
  205830. +
  205831. + return 0;
  205832. +}
  205833. +
  205834. +static int usbmisc_imx6q_set_wakeup
  205835. + (struct imx_usbmisc_data *data, bool enabled)
  205836. +{
  205837. + unsigned long flags;
  205838. + u32 reg, val = MX6_BM_WAKEUP_ENABLE;
  205839. + int ret = 0;
  205840. +
  205841. + if (data->index > 3)
  205842. + return -EINVAL;
  205843. +
  205844. + spin_lock_irqsave(&usbmisc->lock, flags);
  205845. + reg = readl(usbmisc->base + data->index * 4);
  205846. + if (enabled) {
  205847. + val |= imx6q_finalize_wakeup_setting(data);
  205848. + writel(reg | val, usbmisc->base + data->index * 4);
  205849. + if (vbus_wakeup_reg)
  205850. + ret = regulator_enable(vbus_wakeup_reg);
  205851. + } else {
  205852. + if (reg & MX6_BM_WAKEUP_INTR)
  205853. + pr_debug("wakeup int at ci_hdrc.%d\n", data->index);
  205854. + val = MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP
  205855. + | MX6_BM_ID_WAKEUP;
  205856. + writel(reg & ~val, usbmisc->base + data->index * 4);
  205857. + if (vbus_wakeup_reg && regulator_is_enabled(vbus_wakeup_reg))
  205858. + regulator_disable(vbus_wakeup_reg);
  205859. + }
  205860. + spin_unlock_irqrestore(&usbmisc->lock, flags);
  205861. +
  205862. + return ret;
  205863. +}
  205864. +
  205865. static const struct usbmisc_ops imx25_usbmisc_ops = {
  205866. .post = usbmisc_imx25_post,
  205867. };
  205868. @@ -172,6 +219,7 @@
  205869. static const struct usbmisc_ops imx6q_usbmisc_ops = {
  205870. .init = usbmisc_imx6q_init,
  205871. + .set_wakeup = usbmisc_imx6q_set_wakeup,
  205872. };
  205873. int imx_usbmisc_init(struct imx_usbmisc_data *data)
  205874. @@ -194,6 +242,16 @@
  205875. }
  205876. EXPORT_SYMBOL_GPL(imx_usbmisc_init_post);
  205877. +int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled)
  205878. +{
  205879. + if (!usbmisc)
  205880. + return -ENODEV;
  205881. + if (!usbmisc->ops->set_wakeup)
  205882. + return 0;
  205883. + return usbmisc->ops->set_wakeup(data, enabled);
  205884. +}
  205885. +EXPORT_SYMBOL_GPL(imx_usbmisc_set_wakeup);
  205886. +
  205887. static const struct of_device_id usbmisc_imx_dt_ids[] = {
  205888. {
  205889. .compatible = "fsl,imx25-usbmisc",
  205890. @@ -223,7 +281,6 @@
  205891. {
  205892. struct resource *res;
  205893. struct imx_usbmisc *data;
  205894. - int ret;
  205895. struct of_device_id *tmp_dev;
  205896. if (usbmisc)
  205897. @@ -240,31 +297,28 @@
  205898. if (IS_ERR(data->base))
  205899. return PTR_ERR(data->base);
  205900. - data->clk = devm_clk_get(&pdev->dev, NULL);
  205901. - if (IS_ERR(data->clk)) {
  205902. - dev_err(&pdev->dev,
  205903. - "failed to get clock, err=%ld\n", PTR_ERR(data->clk));
  205904. - return PTR_ERR(data->clk);
  205905. - }
  205906. -
  205907. - ret = clk_prepare_enable(data->clk);
  205908. - if (ret) {
  205909. - dev_err(&pdev->dev,
  205910. - "clk_prepare_enable failed, err=%d\n", ret);
  205911. - return ret;
  205912. - }
  205913. -
  205914. tmp_dev = (struct of_device_id *)
  205915. of_match_device(usbmisc_imx_dt_ids, &pdev->dev);
  205916. data->ops = (const struct usbmisc_ops *)tmp_dev->data;
  205917. usbmisc = data;
  205918. + vbus_wakeup_reg = devm_regulator_get(&pdev->dev, "vbus-wakeup");
  205919. + if (PTR_ERR(vbus_wakeup_reg) == -EPROBE_DEFER)
  205920. + return -EPROBE_DEFER;
  205921. + else if (PTR_ERR(vbus_wakeup_reg) == -ENODEV)
  205922. + /* no vbus regualator is needed */
  205923. + vbus_wakeup_reg = NULL;
  205924. + else if (IS_ERR(vbus_wakeup_reg)) {
  205925. + dev_err(&pdev->dev, "Getting regulator error: %ld\n",
  205926. + PTR_ERR(vbus_wakeup_reg));
  205927. + return PTR_ERR(vbus_wakeup_reg);
  205928. + }
  205929. +
  205930. return 0;
  205931. }
  205932. static int usbmisc_imx_remove(struct platform_device *pdev)
  205933. {
  205934. - clk_disable_unprepare(usbmisc->clk);
  205935. usbmisc = NULL;
  205936. return 0;
  205937. }
  205938. diff -Nur linux-3.14.15/drivers/usb/core/hub.c linux-linaro-stable-mx6/drivers/usb/core/hub.c
  205939. --- linux-3.14.15/drivers/usb/core/hub.c 2014-07-31 23:51:43.000000000 +0200
  205940. +++ linux-linaro-stable-mx6/drivers/usb/core/hub.c 2014-08-20 19:31:49.248882399 +0200
  205941. @@ -3867,6 +3867,12 @@
  205942. void usb_enable_ltm(struct usb_device *udev) { }
  205943. EXPORT_SYMBOL_GPL(usb_enable_ltm);
  205944. +static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
  205945. + u16 portstatus, u16 portchange)
  205946. +{
  205947. + return 0;
  205948. +}
  205949. +
  205950. #endif /* CONFIG_PM */
  205951. @@ -4460,8 +4466,7 @@
  205952. /* Disconnect any existing devices under this port */
  205953. if (udev) {
  205954. - if (hcd->phy && !hdev->parent &&
  205955. - !(portstatus & USB_PORT_STAT_CONNECTION))
  205956. + if (hcd->phy && !hdev->parent)
  205957. usb_phy_notify_disconnect(hcd->phy, udev->speed);
  205958. usb_disconnect(&hub->ports[port1 - 1]->child);
  205959. }
  205960. diff -Nur linux-3.14.15/drivers/usb/core/message.c linux-linaro-stable-mx6/drivers/usb/core/message.c
  205961. --- linux-3.14.15/drivers/usb/core/message.c 2014-07-31 23:51:43.000000000 +0200
  205962. +++ linux-linaro-stable-mx6/drivers/usb/core/message.c 2014-08-20 19:31:49.248882399 +0200
  205963. @@ -178,7 +178,7 @@
  205964. *
  205965. * Return:
  205966. * If successful, 0. Otherwise a negative error number. The number of actual
  205967. - * bytes transferred will be stored in the @actual_length paramater.
  205968. + * bytes transferred will be stored in the @actual_length parameter.
  205969. */
  205970. int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
  205971. void *data, int len, int *actual_length, int timeout)
  205972. diff -Nur linux-3.14.15/drivers/usb/core/urb.c linux-linaro-stable-mx6/drivers/usb/core/urb.c
  205973. --- linux-3.14.15/drivers/usb/core/urb.c 2014-07-31 23:51:43.000000000 +0200
  205974. +++ linux-linaro-stable-mx6/drivers/usb/core/urb.c 2014-08-20 19:31:49.252882416 +0200
  205975. @@ -831,7 +831,7 @@
  205976. *
  205977. * this allows all outstanding URBs to be unlinked starting
  205978. * from the back of the queue. This function is asynchronous.
  205979. - * The unlinking is just tiggered. It may happen after this
  205980. + * The unlinking is just triggered. It may happen after this
  205981. * function has returned.
  205982. *
  205983. * This routine should not be called by a driver after its disconnect
  205984. diff -Nur linux-3.14.15/drivers/usb/gadget/f_mass_storage.c linux-linaro-stable-mx6/drivers/usb/gadget/f_mass_storage.c
  205985. --- linux-3.14.15/drivers/usb/gadget/f_mass_storage.c 2014-07-31 23:51:43.000000000 +0200
  205986. +++ linux-linaro-stable-mx6/drivers/usb/gadget/f_mass_storage.c 2014-08-20 19:31:49.296882606 +0200
  205987. @@ -336,8 +336,15 @@
  205988. struct usb_ep *bulk_in;
  205989. struct usb_ep *bulk_out;
  205990. +#ifdef CONFIG_FSL_UTP
  205991. + void *utp;
  205992. +#endif
  205993. };
  205994. +#ifdef CONFIG_FSL_UTP
  205995. +#include "fsl_updater.h"
  205996. +#endif
  205997. +
  205998. static inline int __fsg_is_set(struct fsg_common *common,
  205999. const char *func, unsigned line)
  206000. {
  206001. @@ -1131,6 +1138,13 @@
  206002. }
  206003. #endif
  206004. +#ifdef CONFIG_FSL_UTP
  206005. + if (utp_get_sense(common->fsg) == 0) { /* got the sense from the UTP */
  206006. + sd = UTP_CTX(common->fsg)->sd;
  206007. + sdinfo = UTP_CTX(common->fsg)->sdinfo;
  206008. + valid = 0;
  206009. + } else
  206010. +#endif
  206011. if (!curlun) { /* Unsupported LUNs are okay */
  206012. common->bad_lun_okay = 1;
  206013. sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
  206014. @@ -1152,6 +1166,9 @@
  206015. buf[7] = 18 - 8; /* Additional sense length */
  206016. buf[12] = ASC(sd);
  206017. buf[13] = ASCQ(sd);
  206018. +#ifdef CONFIG_FSL_UTP
  206019. + put_unaligned_be32(UTP_CTX(common->fsg)->sdinfo_h, &buf[8]);
  206020. +#endif
  206021. return 18;
  206022. }
  206023. @@ -1645,7 +1662,18 @@
  206024. sd = SS_INVALID_COMMAND;
  206025. } else if (sd != SS_NO_SENSE) {
  206026. DBG(common, "sending command-failure status\n");
  206027. +#ifdef CONFIG_FSL_UTP
  206028. +/*
  206029. + * mfgtool host frequently reset bus during transfer
  206030. + * - the response in csw to request sense will be 1 due to UTP change
  206031. + * some storage information
  206032. + * - host will reset the bus if response to request sense is 1
  206033. + * - change the response to 0 if CONFIG_FSL_UTP is defined
  206034. + */
  206035. + status = US_BULK_STAT_OK;
  206036. +#else
  206037. status = US_BULK_STAT_FAIL;
  206038. +#endif
  206039. VDBG(common, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
  206040. " info x%x\n",
  206041. SK(sd), ASC(sd), ASCQ(sd), sdinfo);
  206042. @@ -1836,6 +1864,13 @@
  206043. common->phase_error = 0;
  206044. common->short_packet_received = 0;
  206045. +#ifdef CONFIG_FSL_UTP
  206046. + reply = utp_handle_message(common->fsg, common->cmnd, reply);
  206047. +
  206048. + if (reply != -EINVAL)
  206049. + return reply;
  206050. +#endif
  206051. +
  206052. down_read(&common->filesem); /* We're using the backing file */
  206053. switch (common->cmnd[0]) {
  206054. @@ -2502,12 +2537,14 @@
  206055. /* Allow the thread to be frozen */
  206056. set_freezable();
  206057. +#ifndef CONFIG_FSL_UTP
  206058. /*
  206059. * Arrange for userspace references to be interpreted as kernel
  206060. * pointers. That way we can pass a kernel pointer to a routine
  206061. * that expects a __user pointer and it will work okay.
  206062. */
  206063. set_fs(get_ds());
  206064. +#endif
  206065. /* The main loop */
  206066. while (common->state != FSG_STATE_TERMINATED) {
  206067. @@ -3096,6 +3133,10 @@
  206068. /*-------------------------------------------------------------------------*/
  206069. +#ifdef CONFIG_FSL_UTP
  206070. +#include "fsl_updater.c"
  206071. +#endif
  206072. +
  206073. static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
  206074. {
  206075. struct fsg_dev *fsg = fsg_from_func(f);
  206076. @@ -3127,6 +3168,10 @@
  206077. fsg_intf_desc.bInterfaceNumber = i;
  206078. fsg->interface_number = i;
  206079. +#ifdef CONFIG_FSL_UTP
  206080. + utp_init(fsg);
  206081. +#endif
  206082. +
  206083. /* Find all the endpoints we will use */
  206084. ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
  206085. if (!ep)
  206086. @@ -3185,6 +3230,10 @@
  206087. }
  206088. usb_free_all_descriptors(&fsg->function);
  206089. +
  206090. +#ifdef CONFIG_FSL_UTP
  206091. + utp_exit(fsg);
  206092. +#endif
  206093. }
  206094. static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
  206095. diff -Nur linux-3.14.15/drivers/usb/gadget/fsl_updater.c linux-linaro-stable-mx6/drivers/usb/gadget/fsl_updater.c
  206096. --- linux-3.14.15/drivers/usb/gadget/fsl_updater.c 1970-01-01 01:00:00.000000000 +0100
  206097. +++ linux-linaro-stable-mx6/drivers/usb/gadget/fsl_updater.c 2014-08-20 19:23:57.318861891 +0200
  206098. @@ -0,0 +1,594 @@
  206099. +/*
  206100. + * Freescale UUT driver
  206101. + *
  206102. + * Copyright 2008-2013 Freescale Semiconductor, Inc.
  206103. + * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
  206104. + */
  206105. +
  206106. +/*
  206107. + * The code contained herein is licensed under the GNU General Public
  206108. + * License. You may obtain a copy of the GNU General Public License
  206109. + * Version 2 or later at the following locations:
  206110. + *
  206111. + * http://www.opensource.org/licenses/gpl-license.html
  206112. + * http://www.gnu.org/copyleft/gpl.html
  206113. + */
  206114. +
  206115. +static u64 get_be64(u8 *buf)
  206116. +{
  206117. + return ((u64)get_unaligned_be32(buf) << 32) |
  206118. + get_unaligned_be32(buf + 4);
  206119. +}
  206120. +
  206121. +static int utp_init(struct fsg_dev *fsg)
  206122. +{
  206123. + init_waitqueue_head(&utp_context.wq);
  206124. + init_waitqueue_head(&utp_context.list_full_wq);
  206125. +
  206126. + INIT_LIST_HEAD(&utp_context.read);
  206127. + INIT_LIST_HEAD(&utp_context.write);
  206128. + mutex_init(&utp_context.lock);
  206129. +
  206130. + /* the max message is 64KB */
  206131. + utp_context.buffer = vmalloc(0x10000);
  206132. + if (!utp_context.buffer)
  206133. + return -EIO;
  206134. + utp_context.utp_version = 0x1ull;
  206135. + fsg->utp = &utp_context;
  206136. + return misc_register(&utp_dev);
  206137. +}
  206138. +
  206139. +static void utp_exit(struct fsg_dev *fsg)
  206140. +{
  206141. + vfree(utp_context.buffer);
  206142. + misc_deregister(&utp_dev);
  206143. +}
  206144. +
  206145. +static struct utp_user_data *utp_user_data_alloc(size_t size)
  206146. +{
  206147. + struct utp_user_data *uud;
  206148. +
  206149. + uud = vmalloc(size + sizeof(*uud));
  206150. + if (!uud)
  206151. + return uud;
  206152. + memset(uud, 0, size + sizeof(*uud));
  206153. + uud->data.size = size + sizeof(uud->data);
  206154. + INIT_LIST_HEAD(&uud->link);
  206155. + return uud;
  206156. +}
  206157. +
  206158. +static void utp_user_data_free(struct utp_user_data *uud)
  206159. +{
  206160. + mutex_lock(&utp_context.lock);
  206161. + list_del(&uud->link);
  206162. + mutex_unlock(&utp_context.lock);
  206163. + vfree(uud);
  206164. +}
  206165. +
  206166. +/* Get the number of element for list */
  206167. +static u32 count_list(struct list_head *l)
  206168. +{
  206169. + u32 count = 0;
  206170. + struct list_head *tmp;
  206171. +
  206172. + mutex_lock(&utp_context.lock);
  206173. + list_for_each(tmp, l) {
  206174. + count++;
  206175. + }
  206176. + mutex_unlock(&utp_context.lock);
  206177. +
  206178. + return count;
  206179. +}
  206180. +/* The routine will not go on if utp_context.queue is empty */
  206181. +#define WAIT_ACTIVITY(queue) \
  206182. + wait_event_interruptible(utp_context.wq, !list_empty(&utp_context.queue))
  206183. +
  206184. +/* Called by userspace program (uuc) */
  206185. +static ssize_t utp_file_read(struct file *file,
  206186. + char __user *buf,
  206187. + size_t size,
  206188. + loff_t *off)
  206189. +{
  206190. + struct utp_user_data *uud;
  206191. + size_t size_to_put;
  206192. + int free = 0;
  206193. +
  206194. + WAIT_ACTIVITY(read);
  206195. +
  206196. + mutex_lock(&utp_context.lock);
  206197. + uud = list_first_entry(&utp_context.read, struct utp_user_data, link);
  206198. + mutex_unlock(&utp_context.lock);
  206199. + size_to_put = uud->data.size;
  206200. +
  206201. + if (size >= size_to_put)
  206202. + free = !0;
  206203. + if (copy_to_user(buf, &uud->data, size_to_put)) {
  206204. + printk(KERN_INFO "[ %s ] copy error\n", __func__);
  206205. + return -EACCES;
  206206. + }
  206207. + if (free)
  206208. + utp_user_data_free(uud);
  206209. + else {
  206210. + pr_info("sizeof = %d, size = %d\n",
  206211. + sizeof(uud->data),
  206212. + uud->data.size);
  206213. +
  206214. + pr_err("Will not free utp_user_data, because buffer size = %d,"
  206215. + "need to put %d\n", size, size_to_put);
  206216. + }
  206217. +
  206218. + /*
  206219. + * The user program has already finished data process,
  206220. + * go on getting data from the host
  206221. + */
  206222. + wake_up(&utp_context.list_full_wq);
  206223. +
  206224. + return size_to_put;
  206225. +}
  206226. +
  206227. +static ssize_t utp_file_write(struct file *file, const char __user *buf,
  206228. + size_t size, loff_t *off)
  206229. +{
  206230. + struct utp_user_data *uud;
  206231. +
  206232. + if (size < sizeof(uud->data))
  206233. + return -EINVAL;
  206234. + uud = utp_user_data_alloc(size);
  206235. + if (uud == NULL)
  206236. + return -ENOMEM;
  206237. + if (copy_from_user(&uud->data, buf, size)) {
  206238. + printk(KERN_INFO "[ %s ] copy error!\n", __func__);
  206239. + vfree(uud);
  206240. + return -EACCES;
  206241. + }
  206242. + mutex_lock(&utp_context.lock);
  206243. + list_add_tail(&uud->link, &utp_context.write);
  206244. + /* Go on EXEC routine process */
  206245. + wake_up(&utp_context.wq);
  206246. + mutex_unlock(&utp_context.lock);
  206247. + return size;
  206248. +}
  206249. +
  206250. +/*
  206251. + * uuc should change to use soc bus infrastructure to soc information
  206252. + * /sys/devices/soc0/soc_id
  206253. + * this function can be removed.
  206254. + */
  206255. +static long
  206256. +utp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  206257. +{
  206258. + int cpu_id = 0;
  206259. +
  206260. + switch (cmd) {
  206261. + case UTP_GET_CPU_ID:
  206262. + return put_user(cpu_id, (int __user *)arg);
  206263. + default:
  206264. + return -ENOIOCTLCMD;
  206265. + }
  206266. +}
  206267. +
  206268. +/* Will be called when the host wants to get the sense data */
  206269. +static int utp_get_sense(struct fsg_dev *fsg)
  206270. +{
  206271. + if (UTP_CTX(fsg)->processed == 0)
  206272. + return -1;
  206273. +
  206274. + UTP_CTX(fsg)->processed = 0;
  206275. + return 0;
  206276. +}
  206277. +
  206278. +static int utp_do_read(struct fsg_dev *fsg, void *data, size_t size)
  206279. +{
  206280. + struct fsg_buffhd *bh;
  206281. + int rc;
  206282. + u32 amount_left;
  206283. + unsigned int amount;
  206284. +
  206285. + /* Get the starting Logical Block Address and check that it's
  206286. + * not too big */
  206287. +
  206288. + amount_left = size;
  206289. + if (unlikely(amount_left == 0))
  206290. + return -EIO; /* No default reply*/
  206291. +
  206292. + pr_debug("%s: sending %d\n", __func__, size);
  206293. + for (;;) {
  206294. + /* Figure out how much we need to read:
  206295. + * Try to read the remaining amount.
  206296. + * But don't read more than the buffer size.
  206297. + * And don't try to read past the end of the file.
  206298. + * Finally, if we're not at a page boundary, don't read past
  206299. + * the next page.
  206300. + * If this means reading 0 then we were asked to read past
  206301. + * the end of file. */
  206302. + amount = min((unsigned int) amount_left, FSG_BUFLEN);
  206303. +
  206304. + /* Wait for the next buffer to become available */
  206305. + bh = fsg->common->next_buffhd_to_fill;
  206306. + while (bh->state != BUF_STATE_EMPTY) {
  206307. + rc = sleep_thread(fsg->common);
  206308. + if (rc)
  206309. + return rc;
  206310. + }
  206311. +
  206312. + /* If we were asked to read past the end of file,
  206313. + * end with an empty buffer. */
  206314. + if (amount == 0) {
  206315. + bh->inreq->length = 0;
  206316. + bh->state = BUF_STATE_FULL;
  206317. + break;
  206318. + }
  206319. +
  206320. + /* Perform the read */
  206321. + pr_info("Copied to %p, %d bytes started from %d\n",
  206322. + bh->buf, amount, size - amount_left);
  206323. + /* from upt buffer to file_storeage buffer */
  206324. + memcpy(bh->buf, data + size - amount_left, amount);
  206325. + amount_left -= amount;
  206326. + fsg->common->residue -= amount;
  206327. +
  206328. + bh->inreq->length = amount;
  206329. + bh->state = BUF_STATE_FULL;
  206330. +
  206331. + /* Send this buffer and go read some more */
  206332. + bh->inreq->zero = 0;
  206333. +
  206334. + /* USB Physical transfer: Data from device to host */
  206335. + start_transfer(fsg, fsg->bulk_in, bh->inreq,
  206336. + &bh->inreq_busy, &bh->state);
  206337. +
  206338. + fsg->common->next_buffhd_to_fill = bh->next;
  206339. +
  206340. + if (amount_left <= 0)
  206341. + break;
  206342. + }
  206343. +
  206344. + return size - amount_left;
  206345. +}
  206346. +
  206347. +static int utp_do_write(struct fsg_dev *fsg, void *data, size_t size)
  206348. +{
  206349. + struct fsg_buffhd *bh;
  206350. + int get_some_more;
  206351. + u32 amount_left_to_req, amount_left_to_write;
  206352. + unsigned int amount;
  206353. + int rc;
  206354. + loff_t offset;
  206355. +
  206356. + /* Carry out the file writes */
  206357. + get_some_more = 1;
  206358. + amount_left_to_req = amount_left_to_write = size;
  206359. +
  206360. + if (unlikely(amount_left_to_write == 0))
  206361. + return -EIO;
  206362. +
  206363. + offset = 0;
  206364. + while (amount_left_to_write > 0) {
  206365. +
  206366. + /* Queue a request for more data from the host */
  206367. + bh = fsg->common->next_buffhd_to_fill;
  206368. + if (bh->state == BUF_STATE_EMPTY && get_some_more) {
  206369. +
  206370. + /* Figure out how much we want to get:
  206371. + * Try to get the remaining amount.
  206372. + * But don't get more than the buffer size.
  206373. + * And don't try to go past the end of the file.
  206374. + * If we're not at a page boundary,
  206375. + * don't go past the next page.
  206376. + * If this means getting 0, then we were asked
  206377. + * to write past the end of file.
  206378. + * Finally, round down to a block boundary. */
  206379. + amount = min(amount_left_to_req, FSG_BUFLEN);
  206380. +
  206381. + if (amount == 0) {
  206382. + get_some_more = 0;
  206383. + /* cry now */
  206384. + continue;
  206385. + }
  206386. +
  206387. + /* Get the next buffer */
  206388. + amount_left_to_req -= amount;
  206389. + if (amount_left_to_req == 0)
  206390. + get_some_more = 0;
  206391. +
  206392. + /* amount is always divisible by 512, hence by
  206393. + * the bulk-out maxpacket size */
  206394. + bh->outreq->length = bh->bulk_out_intended_length =
  206395. + amount;
  206396. + bh->outreq->short_not_ok = 1;
  206397. + start_transfer(fsg, fsg->bulk_out, bh->outreq,
  206398. + &bh->outreq_busy, &bh->state);
  206399. + fsg->common->next_buffhd_to_fill = bh->next;
  206400. + continue;
  206401. + }
  206402. +
  206403. + /* Write the received data to the backing file */
  206404. + bh = fsg->common->next_buffhd_to_drain;
  206405. + if (bh->state == BUF_STATE_EMPTY && !get_some_more)
  206406. + break; /* We stopped early */
  206407. + if (bh->state == BUF_STATE_FULL) {
  206408. + smp_rmb();
  206409. + fsg->common->next_buffhd_to_drain = bh->next;
  206410. + bh->state = BUF_STATE_EMPTY;
  206411. +
  206412. + /* Did something go wrong with the transfer? */
  206413. + if (bh->outreq->status != 0)
  206414. + /* cry again, COMMUNICATION_FAILURE */
  206415. + break;
  206416. +
  206417. + amount = bh->outreq->actual;
  206418. +
  206419. + /* Perform the write */
  206420. + memcpy(data + offset, bh->buf, amount);
  206421. +
  206422. + offset += amount;
  206423. + if (signal_pending(current))
  206424. + return -EINTR; /* Interrupted!*/
  206425. + amount_left_to_write -= amount;
  206426. + fsg->common->residue -= amount;
  206427. +
  206428. + /* Did the host decide to stop early? */
  206429. + if (bh->outreq->actual != bh->outreq->length) {
  206430. + fsg->common->short_packet_received = 1;
  206431. + break;
  206432. + }
  206433. + continue;
  206434. + }
  206435. +
  206436. + /* Wait for something to happen */
  206437. + rc = sleep_thread(fsg->common);
  206438. + if (rc)
  206439. + return rc;
  206440. + }
  206441. +
  206442. + return -EIO;
  206443. +}
  206444. +
  206445. +static inline void utp_set_sense(struct fsg_dev *fsg, u16 code, u64 reply)
  206446. +{
  206447. + UTP_CTX(fsg)->processed = true;
  206448. + UTP_CTX(fsg)->sdinfo = reply & 0xFFFFFFFF;
  206449. + UTP_CTX(fsg)->sdinfo_h = (reply >> 32) & 0xFFFFFFFF;
  206450. + UTP_CTX(fsg)->sd = (UTP_SENSE_KEY << 16) | code;
  206451. +}
  206452. +
  206453. +static void utp_poll(struct fsg_dev *fsg)
  206454. +{
  206455. + struct utp_context *ctx = UTP_CTX(fsg);
  206456. + struct utp_user_data *uud = NULL;
  206457. +
  206458. + mutex_lock(&ctx->lock);
  206459. + if (!list_empty(&ctx->write))
  206460. + uud = list_first_entry(&ctx->write, struct utp_user_data, link);
  206461. + mutex_unlock(&ctx->lock);
  206462. +
  206463. + if (uud) {
  206464. + if (uud->data.flags & UTP_FLAG_STATUS) {
  206465. + printk(KERN_WARNING "%s: exit with status %d\n",
  206466. + __func__, uud->data.status);
  206467. + UTP_SS_EXIT(fsg, uud->data.status);
  206468. + } else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
  206469. + UTP_SS_BUSY(fsg, --ctx->counter);
  206470. + } else {
  206471. + printk("%s: pass returned.\n", __func__);
  206472. + UTP_SS_PASS(fsg);
  206473. + }
  206474. + utp_user_data_free(uud);
  206475. + } else {
  206476. + if (utp_context.cur_state & UTP_FLAG_DATA) {
  206477. + if (count_list(&ctx->read) < 7) {
  206478. + pr_debug("%s: pass returned in POLL stage. \n", __func__);
  206479. + UTP_SS_PASS(fsg);
  206480. + utp_context.cur_state = 0;
  206481. + return;
  206482. + }
  206483. + }
  206484. + UTP_SS_BUSY(fsg, --ctx->counter);
  206485. + }
  206486. +}
  206487. +
  206488. +static int utp_exec(struct fsg_dev *fsg,
  206489. + char *command,
  206490. + int cmdsize,
  206491. + unsigned long long payload)
  206492. +{
  206493. + struct utp_user_data *uud = NULL, *uud2r;
  206494. + struct utp_context *ctx = UTP_CTX(fsg);
  206495. +
  206496. + ctx->counter = 0xFFFF;
  206497. + uud2r = utp_user_data_alloc(cmdsize + 1);
  206498. + if (!uud2r)
  206499. + return -ENOMEM;
  206500. + uud2r->data.flags = UTP_FLAG_COMMAND;
  206501. + uud2r->data.payload = payload;
  206502. + strncpy(uud2r->data.command, command, cmdsize);
  206503. +
  206504. + mutex_lock(&ctx->lock);
  206505. + list_add_tail(&uud2r->link, &ctx->read);
  206506. + mutex_unlock(&ctx->lock);
  206507. + /* wake up the read routine */
  206508. + wake_up(&ctx->wq);
  206509. +
  206510. + if (command[0] == '!') /* there will be no response */
  206511. + return 0;
  206512. +
  206513. + /*
  206514. + * the user program (uuc) will return utp_message
  206515. + * and add list to write list
  206516. + */
  206517. + WAIT_ACTIVITY(write);
  206518. +
  206519. + mutex_lock(&ctx->lock);
  206520. + if (!list_empty(&ctx->write)) {
  206521. + uud = list_first_entry(&ctx->write, struct utp_user_data, link);
  206522. +#ifdef DEBUG
  206523. + pr_info("UUD:\n\tFlags = %02X\n", uud->data.flags);
  206524. + if (uud->data.flags & UTP_FLAG_DATA) {
  206525. + pr_info("\tbufsize = %d\n", uud->data.bufsize);
  206526. + print_hex_dump(KERN_DEBUG, "\t", DUMP_PREFIX_NONE,
  206527. + 16, 2, uud->data.data, uud->data.bufsize, true);
  206528. + }
  206529. + if (uud->data.flags & UTP_FLAG_REPORT_BUSY)
  206530. + pr_info("\tBUSY\n");
  206531. +#endif
  206532. + }
  206533. + mutex_unlock(&ctx->lock);
  206534. +
  206535. + if (uud->data.flags & UTP_FLAG_DATA) {
  206536. + memcpy(ctx->buffer, uud->data.data, uud->data.bufsize);
  206537. + UTP_SS_SIZE(fsg, uud->data.bufsize);
  206538. + } else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
  206539. + UTP_SS_BUSY(fsg, ctx->counter);
  206540. + } else if (uud->data.flags & UTP_FLAG_STATUS) {
  206541. + printk(KERN_WARNING "%s: exit with status %d\n", __func__,
  206542. + uud->data.status);
  206543. + UTP_SS_EXIT(fsg, uud->data.status);
  206544. + } else {
  206545. + pr_debug("%s: pass returned in EXEC stage. \n", __func__);
  206546. + UTP_SS_PASS(fsg);
  206547. + }
  206548. + utp_user_data_free(uud);
  206549. + return 0;
  206550. +}
  206551. +
  206552. +static int utp_send_status(struct fsg_dev *fsg)
  206553. +{
  206554. + struct fsg_buffhd *bh;
  206555. + u8 status = US_BULK_STAT_OK;
  206556. + struct bulk_cs_wrap *csw;
  206557. + int rc;
  206558. +
  206559. + /* Wait for the next buffer to become available */
  206560. + bh = fsg->common->next_buffhd_to_fill;
  206561. + while (bh->state != BUF_STATE_EMPTY) {
  206562. + rc = sleep_thread(fsg->common);
  206563. + if (rc)
  206564. + return rc;
  206565. + }
  206566. +
  206567. + if (fsg->common->phase_error) {
  206568. + DBG(fsg, "sending phase-error status\n");
  206569. + status = US_BULK_STAT_PHASE;
  206570. +
  206571. + } else if ((UTP_CTX(fsg)->sd & 0xFFFF) != UTP_REPLY_PASS) {
  206572. + status = US_BULK_STAT_FAIL;
  206573. + }
  206574. +
  206575. + csw = bh->buf;
  206576. +
  206577. + /* Store and send the Bulk-only CSW */
  206578. + csw->Signature = __constant_cpu_to_le32(US_BULK_CS_SIGN);
  206579. + csw->Tag = fsg->common->tag;
  206580. + csw->Residue = cpu_to_le32(fsg->common->residue);
  206581. + csw->Status = status;
  206582. +
  206583. + bh->inreq->length = US_BULK_CS_WRAP_LEN;
  206584. + bh->inreq->zero = 0;
  206585. + start_transfer(fsg, fsg->bulk_in, bh->inreq,
  206586. + &bh->inreq_busy, &bh->state);
  206587. + fsg->common->next_buffhd_to_fill = bh->next;
  206588. + return 0;
  206589. +}
  206590. +
  206591. +static int utp_handle_message(struct fsg_dev *fsg,
  206592. + char *cdb_data,
  206593. + int default_reply)
  206594. +{
  206595. + struct utp_msg *m = (struct utp_msg *)cdb_data;
  206596. + void *data = NULL;
  206597. + int r;
  206598. + struct utp_user_data *uud2r;
  206599. + unsigned long long param;
  206600. + unsigned long tag;
  206601. +
  206602. + if (m->f0 != 0xF0)
  206603. + return default_reply;
  206604. +
  206605. + tag = get_unaligned_be32((void *)&m->utp_msg_tag);
  206606. + param = get_be64((void *)&m->param);
  206607. + pr_debug("Type 0x%x, tag 0x%08lx, param %llx\n",
  206608. + m->utp_msg_type, tag, param);
  206609. +
  206610. + switch ((enum utp_msg_type)m->utp_msg_type) {
  206611. +
  206612. + case UTP_POLL:
  206613. + if (get_be64((void *)&m->param) == 1) {
  206614. + pr_debug("%s: version request\n", __func__);
  206615. + UTP_SS_EXIT(fsg, UTP_CTX(fsg)->utp_version);
  206616. + break;
  206617. + }
  206618. + utp_poll(fsg);
  206619. + break;
  206620. + case UTP_EXEC:
  206621. + pr_debug("%s: EXEC\n", __func__);
  206622. + data = vmalloc(fsg->common->data_size);
  206623. + memset(data, 0, fsg->common->data_size);
  206624. + /* copy data from usb buffer to utp buffer */
  206625. + utp_do_write(fsg, data, fsg->common->data_size);
  206626. + utp_exec(fsg, data, fsg->common->data_size, param);
  206627. + vfree(data);
  206628. + break;
  206629. + case UTP_GET: /* data from device to host */
  206630. + pr_debug("%s: GET, %d bytes\n", __func__,
  206631. + fsg->common->data_size);
  206632. + r = utp_do_read(fsg, UTP_CTX(fsg)->buffer,
  206633. + fsg->common->data_size);
  206634. + UTP_SS_PASS(fsg);
  206635. + break;
  206636. + case UTP_PUT:
  206637. + utp_context.cur_state = UTP_FLAG_DATA;
  206638. + pr_debug("%s: PUT, Received %d bytes\n", __func__, fsg->common->data_size);/* data from host to device */
  206639. + uud2r = utp_user_data_alloc(fsg->common->data_size);
  206640. + if (!uud2r)
  206641. + return -ENOMEM;
  206642. + uud2r->data.bufsize = fsg->common->data_size;
  206643. + uud2r->data.flags = UTP_FLAG_DATA;
  206644. + utp_do_write(fsg, uud2r->data.data, fsg->common->data_size);
  206645. + /* don't know what will be written */
  206646. + mutex_lock(&UTP_CTX(fsg)->lock);
  206647. + list_add_tail(&uud2r->link, &UTP_CTX(fsg)->read);
  206648. + mutex_unlock(&UTP_CTX(fsg)->lock);
  206649. + wake_up(&UTP_CTX(fsg)->wq);
  206650. + /*
  206651. + * Return PASS or FAIL according to uuc's status
  206652. + * Please open it if need to check uuc's status
  206653. + * and use another version uuc
  206654. + */
  206655. +#if 0
  206656. + struct utp_user_data *uud = NULL;
  206657. + struct utp_context *ctx;
  206658. + WAIT_ACTIVITY(write);
  206659. + ctx = UTP_CTX(fsg);
  206660. + mutex_lock(&ctx->lock);
  206661. +
  206662. + if (!list_empty(&ctx->write))
  206663. + uud = list_first_entry(&ctx->write,
  206664. + struct utp_user_data, link);
  206665. +
  206666. + mutex_unlock(&ctx->lock);
  206667. + if (uud) {
  206668. + if (uud->data.flags & UTP_FLAG_STATUS) {
  206669. + printk(KERN_WARNING "%s: exit with status %d\n",
  206670. + __func__, uud->data.status);
  206671. + UTP_SS_EXIT(fsg, uud->data.status);
  206672. + } else {
  206673. + pr_debug("%s: pass\n", __func__);
  206674. + UTP_SS_PASS(fsg);
  206675. + }
  206676. + utp_user_data_free(uud);
  206677. + } else{
  206678. + UTP_SS_PASS(fsg);
  206679. + }
  206680. +#endif
  206681. + if (count_list(&UTP_CTX(fsg)->read) < 7) {
  206682. + utp_context.cur_state = 0;
  206683. + UTP_SS_PASS(fsg);
  206684. + } else
  206685. + UTP_SS_BUSY(fsg, UTP_CTX(fsg)->counter);
  206686. +
  206687. + break;
  206688. + }
  206689. +
  206690. + utp_send_status(fsg);
  206691. + return -1;
  206692. +}
  206693. diff -Nur linux-3.14.15/drivers/usb/gadget/fsl_updater.h linux-linaro-stable-mx6/drivers/usb/gadget/fsl_updater.h
  206694. --- linux-3.14.15/drivers/usb/gadget/fsl_updater.h 1970-01-01 01:00:00.000000000 +0100
  206695. +++ linux-linaro-stable-mx6/drivers/usb/gadget/fsl_updater.h 2014-08-20 19:23:57.318861891 +0200
  206696. @@ -0,0 +1,150 @@
  206697. +/*
  206698. + * Freescale UUT driver
  206699. + *
  206700. + * Copyright 2008-2013 Freescale Semiconductor, Inc.
  206701. + * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
  206702. + */
  206703. +
  206704. +/*
  206705. + * The code contained herein is licensed under the GNU General Public
  206706. + * License. You may obtain a copy of the GNU General Public License
  206707. + * Version 2 or later at the following locations:
  206708. + *
  206709. + * http://www.opensource.org/licenses/gpl-license.html
  206710. + * http://www.gnu.org/copyleft/gpl.html
  206711. + */
  206712. +
  206713. +#ifndef __FSL_UPDATER_H
  206714. +#define __FSL_UPDATER_H
  206715. +
  206716. +#include <linux/miscdevice.h>
  206717. +#include <linux/list.h>
  206718. +#include <linux/vmalloc.h>
  206719. +#include <linux/ioctl.h>
  206720. +/* #include <mach/hardware.h> */
  206721. +
  206722. +static int utp_init(struct fsg_dev *fsg);
  206723. +static void utp_exit(struct fsg_dev *fsg);
  206724. +static ssize_t utp_file_read(struct file *file,
  206725. + char __user *buf,
  206726. + size_t size,
  206727. + loff_t *off);
  206728. +
  206729. +static ssize_t utp_file_write(struct file *file,
  206730. + const char __user *buf,
  206731. + size_t size,
  206732. + loff_t *off);
  206733. +
  206734. +static long utp_ioctl(struct file *file,
  206735. + unsigned int cmd, unsigned long arg);
  206736. +static struct utp_user_data *utp_user_data_alloc(size_t size);
  206737. +static void utp_user_data_free(struct utp_user_data *uud);
  206738. +static int utp_get_sense(struct fsg_dev *fsg);
  206739. +static int utp_do_read(struct fsg_dev *fsg, void *data, size_t size);
  206740. +static int utp_do_write(struct fsg_dev *fsg, void *data, size_t size);
  206741. +static inline void utp_set_sense(struct fsg_dev *fsg, u16 code, u64 reply);
  206742. +static int utp_handle_message(struct fsg_dev *fsg,
  206743. + char *cdb_data,
  206744. + int default_reply);
  206745. +
  206746. +#define UTP_REPLY_PASS 0
  206747. +#define UTP_REPLY_EXIT 0x8001
  206748. +#define UTP_REPLY_BUSY 0x8002
  206749. +#define UTP_REPLY_SIZE 0x8003
  206750. +#define UTP_SENSE_KEY 9
  206751. +
  206752. +#define UTP_MINOR 222
  206753. +/* MISC_DYNAMIC_MINOR would be better, but... */
  206754. +
  206755. +#define UTP_COMMAND_SIZE 80
  206756. +
  206757. +#define UTP_SS_EXIT(fsg, r) utp_set_sense(fsg, UTP_REPLY_EXIT, (u64)r)
  206758. +#define UTP_SS_PASS(fsg) utp_set_sense(fsg, UTP_REPLY_PASS, 0)
  206759. +#define UTP_SS_BUSY(fsg, r) utp_set_sense(fsg, UTP_REPLY_BUSY, (u64)r)
  206760. +#define UTP_SS_SIZE(fsg, r) utp_set_sense(fsg, UTP_REPLY_SIZE, (u64)r)
  206761. +
  206762. +#define UTP_IOCTL_BASE 'U'
  206763. +#define UTP_GET_CPU_ID _IOR(UTP_IOCTL_BASE, 0, int)
  206764. +/* the structure of utp message which is mapped to 16-byte SCSI CBW's CDB */
  206765. +#pragma pack(1)
  206766. +struct utp_msg {
  206767. + u8 f0;
  206768. + u8 utp_msg_type;
  206769. + u32 utp_msg_tag;
  206770. + union {
  206771. + struct {
  206772. + u32 param_lsb;
  206773. + u32 param_msb;
  206774. + };
  206775. + u64 param;
  206776. + };
  206777. +};
  206778. +
  206779. +enum utp_msg_type {
  206780. + UTP_POLL = 0,
  206781. + UTP_EXEC,
  206782. + UTP_GET,
  206783. + UTP_PUT,
  206784. +};
  206785. +
  206786. +static struct utp_context {
  206787. + wait_queue_head_t wq;
  206788. + wait_queue_head_t list_full_wq;
  206789. + struct mutex lock;
  206790. + struct list_head read;
  206791. + struct list_head write;
  206792. + u32 sd, sdinfo, sdinfo_h; /* sense data */
  206793. + int processed;
  206794. + u8 *buffer;
  206795. + u32 counter;
  206796. + u64 utp_version;
  206797. + u32 cur_state;
  206798. +} utp_context;
  206799. +
  206800. +static const struct file_operations utp_fops = {
  206801. + .open = nonseekable_open,
  206802. + .read = utp_file_read,
  206803. + .write = utp_file_write,
  206804. + /* .ioctl = utp_ioctl, */
  206805. + .unlocked_ioctl = utp_ioctl,
  206806. +};
  206807. +
  206808. +static struct miscdevice utp_dev = {
  206809. + .minor = UTP_MINOR,
  206810. + .name = "utp",
  206811. + .fops = &utp_fops,
  206812. +};
  206813. +
  206814. +#define UTP_FLAG_COMMAND 0x00000001
  206815. +#define UTP_FLAG_DATA 0x00000002
  206816. +#define UTP_FLAG_STATUS 0x00000004
  206817. +#define UTP_FLAG_REPORT_BUSY 0x10000000
  206818. +struct utp_message {
  206819. + u32 flags;
  206820. + size_t size;
  206821. + union {
  206822. + struct {
  206823. + u64 payload;
  206824. + char command[1];
  206825. + };
  206826. + struct {
  206827. + size_t bufsize;
  206828. + u8 data[1];
  206829. + };
  206830. + u32 status;
  206831. + };
  206832. +};
  206833. +
  206834. +struct utp_user_data {
  206835. + struct list_head link;
  206836. + struct utp_message data;
  206837. +};
  206838. +#pragma pack()
  206839. +
  206840. +static inline struct utp_context *UTP_CTX(struct fsg_dev *fsg)
  206841. +{
  206842. + return (struct utp_context *)fsg->utp;
  206843. +}
  206844. +
  206845. +#endif /* __FSL_UPDATER_H */
  206846. +
  206847. diff -Nur linux-3.14.15/drivers/usb/gadget/Kconfig linux-linaro-stable-mx6/drivers/usb/gadget/Kconfig
  206848. --- linux-3.14.15/drivers/usb/gadget/Kconfig 2014-07-31 23:51:43.000000000 +0200
  206849. +++ linux-linaro-stable-mx6/drivers/usb/gadget/Kconfig 2014-08-20 19:31:49.280882536 +0200
  206850. @@ -952,6 +952,12 @@
  206851. Say "y" to link the driver statically, or "m" to build
  206852. a dynamically linked module called "g_mass_storage".
  206853. +config FSL_UTP
  206854. + bool "UTP over Storage Gadget"
  206855. + depends on USB_MASS_STORAGE
  206856. + help
  206857. + Freescale's extension to MSC protocol
  206858. +
  206859. config USB_GADGET_TARGET
  206860. tristate "USB Gadget Target Fabric Module"
  206861. depends on TARGET_CORE
  206862. diff -Nur linux-3.14.15/drivers/usb/gadget/mass_storage.c linux-linaro-stable-mx6/drivers/usb/gadget/mass_storage.c
  206863. --- linux-3.14.15/drivers/usb/gadget/mass_storage.c 2014-07-31 23:51:43.000000000 +0200
  206864. +++ linux-linaro-stable-mx6/drivers/usb/gadget/mass_storage.c 2014-08-20 19:31:49.324882725 +0200
  206865. @@ -266,7 +266,7 @@
  206866. {
  206867. return usb_composite_probe(&msg_driver);
  206868. }
  206869. -module_init(msg_init);
  206870. +late_initcall(msg_init);
  206871. static void msg_cleanup(void)
  206872. {
  206873. diff -Nur linux-3.14.15/drivers/usb/host/ehci-h20ahb.c linux-linaro-stable-mx6/drivers/usb/host/ehci-h20ahb.c
  206874. --- linux-3.14.15/drivers/usb/host/ehci-h20ahb.c 1970-01-01 01:00:00.000000000 +0100
  206875. +++ linux-linaro-stable-mx6/drivers/usb/host/ehci-h20ahb.c 2014-08-20 19:31:49.344882811 +0200
  206876. @@ -0,0 +1,341 @@
  206877. +/*
  206878. + * Copyright (C) 2007-2013 Texas Instruments, Inc.
  206879. + * Author: Vikram Pandita <vikram.pandita@ti.com>
  206880. + * Author: Anand Gadiyar <gadiyar@ti.com>
  206881. + * Author: Keshava Munegowda <keshava_mgowda@ti.com>
  206882. + * Author: Roger Quadros <rogerq@ti.com>
  206883. + *
  206884. + * Copyright (C) 2009 Nokia Corporation
  206885. + * Contact: Felipe Balbi <felipe.balbi@nokia.com>
  206886. + *
  206887. + * Based on ehci-omap.c - driver for USBHOST on OMAP3/4 processors
  206888. + *
  206889. + * This file is subject to the terms and conditions of the GNU General Public
  206890. + * License. See the file COPYING in the main directory of this archive
  206891. + * for more details.
  206892. + *
  206893. + */
  206894. +
  206895. +#include <linux/kernel.h>
  206896. +#include <linux/module.h>
  206897. +#include <linux/io.h>
  206898. +#include <linux/platform_device.h>
  206899. +#include <linux/slab.h>
  206900. +#include <linux/usb/ulpi.h>
  206901. +#include <linux/pm_runtime.h>
  206902. +#include <linux/gpio.h>
  206903. +#include <linux/clk.h>
  206904. +#include <linux/usb.h>
  206905. +#include <linux/usb/hcd.h>
  206906. +#include <linux/of.h>
  206907. +#include <linux/dma-mapping.h>
  206908. +
  206909. +#include "ehci.h"
  206910. +
  206911. +#define H20AHB_HS_USB_PORTS 1
  206912. +
  206913. +/* EHCI Synopsys-specific Register Set */
  206914. +#define EHCI_INSNREG04 (0xA0)
  206915. +#define EHCI_INSNREG04_DISABLE_UNSUSPEND (1 << 5)
  206916. +#define EHCI_INSNREG05_ULPI (0xA4)
  206917. +#define EHCI_INSNREG05_ULPI_CONTROL_SHIFT 31
  206918. +#define EHCI_INSNREG05_ULPI_PORTSEL_SHIFT 24
  206919. +#define EHCI_INSNREG05_ULPI_OPSEL_SHIFT 22
  206920. +#define EHCI_INSNREG05_ULPI_REGADD_SHIFT 16
  206921. +#define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8
  206922. +#define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0
  206923. +
  206924. +#define DRIVER_DESC "H20AHB-EHCI Host Controller driver"
  206925. +
  206926. +static const char hcd_name[] = "ehci-h20ahb";
  206927. +
  206928. +/*-------------------------------------------------------------------------*/
  206929. +
  206930. +struct h20ahb_hcd {
  206931. + struct usb_phy *phy[H20AHB_HS_USB_PORTS]; /* one PHY for each port */
  206932. + int nports;
  206933. +};
  206934. +
  206935. +static inline void ehci_write(void __iomem *base, u32 reg, u32 val)
  206936. +{
  206937. + __raw_writel(val, base + reg);
  206938. +}
  206939. +
  206940. +static inline u32 ehci_read(void __iomem *base, u32 reg)
  206941. +{
  206942. + return __raw_readl(base + reg);
  206943. +}
  206944. +
  206945. +/* configure so an HC device and id are always provided */
  206946. +/* always called with process context; sleeping is OK */
  206947. +
  206948. +static struct hc_driver __read_mostly ehci_h20ahb_hc_driver;
  206949. +
  206950. +static const struct ehci_driver_overrides ehci_h20ahb_overrides __initdata = {
  206951. + .extra_priv_size = sizeof(struct h20ahb_hcd),
  206952. +};
  206953. +
  206954. +static int ehci_h20ahb_phy_read(struct usb_phy *x, u32 reg)
  206955. +{
  206956. + u32 val = (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |
  206957. + (1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |
  206958. + (3 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |
  206959. + (reg << EHCI_INSNREG05_ULPI_REGADD_SHIFT);
  206960. + ehci_write(x->io_priv, 0, val);
  206961. + while ((val = ehci_read(x->io_priv, 0)) &
  206962. + (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT));
  206963. + return val & 0xff;
  206964. +}
  206965. +
  206966. +static int ehci_h20ahb_phy_write(struct usb_phy *x, u32 val, u32 reg)
  206967. +{
  206968. + u32 v = (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |
  206969. + (1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |
  206970. + (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |
  206971. + (reg << EHCI_INSNREG05_ULPI_REGADD_SHIFT) |
  206972. + (val & 0xff);
  206973. + ehci_write(x->io_priv, 0, v);
  206974. + while ((v = ehci_read(x->io_priv, 0)) &
  206975. + (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT));
  206976. + return 0;
  206977. +}
  206978. +
  206979. +static struct usb_phy_io_ops ehci_h20ahb_phy_io_ops = {
  206980. + .read = ehci_h20ahb_phy_read,
  206981. + .write = ehci_h20ahb_phy_write,
  206982. +};
  206983. +
  206984. +
  206985. +/**
  206986. + * ehci_hcd_h20ahb_probe - initialize Synopsis-based HCDs
  206987. + *
  206988. + * Allocates basic resources for this USB host controller, and
  206989. + * then invokes the start() method for the HCD associated with it
  206990. + * through the hotplug entry's driver_data.
  206991. + */
  206992. +static int ehci_hcd_h20ahb_probe(struct platform_device *pdev)
  206993. +{
  206994. + struct device *dev = &pdev->dev;
  206995. + struct resource *res;
  206996. + struct usb_hcd *hcd;
  206997. + void __iomem *regs;
  206998. + int ret;
  206999. + int irq;
  207000. + int i;
  207001. + struct h20ahb_hcd *h20ahb;
  207002. +
  207003. + if (usb_disabled())
  207004. + return -ENODEV;
  207005. +
  207006. + /* if (!dev->parent) {
  207007. + dev_err(dev, "Missing parent device\n");
  207008. + return -ENODEV;
  207009. + }*/
  207010. +
  207011. + /* For DT boot, get platform data from parent. i.e. usbhshost */
  207012. + /*if (dev->of_node) {
  207013. + pdata = dev_get_platdata(dev->parent);
  207014. + dev->platform_data = pdata;
  207015. + }
  207016. +
  207017. + if (!pdata) {
  207018. + dev_err(dev, "Missing platform data\n");
  207019. + return -ENODEV;
  207020. + }*/
  207021. +
  207022. + irq = platform_get_irq(pdev, 0);
  207023. + if (irq < 0) {
  207024. + dev_err(dev, "EHCI irq failed\n");
  207025. + return -ENODEV;
  207026. + }
  207027. +
  207028. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  207029. + regs = devm_ioremap_resource(dev, res);
  207030. + if (IS_ERR(regs))
  207031. + return PTR_ERR(regs);
  207032. +
  207033. + /*
  207034. + * Right now device-tree probed devices don't get dma_mask set.
  207035. + * Since shared usb code relies on it, set it here for now.
  207036. + * Once we have dma capability bindings this can go away.
  207037. + */
  207038. + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
  207039. + if (ret)
  207040. + return ret;
  207041. +
  207042. + ret = -ENODEV;
  207043. + hcd = usb_create_hcd(&ehci_h20ahb_hc_driver, dev,
  207044. + dev_name(dev));
  207045. + if (!hcd) {
  207046. + dev_err(dev, "Failed to create HCD\n");
  207047. + return -ENOMEM;
  207048. + }
  207049. +
  207050. + hcd->rsrc_start = res->start;
  207051. + hcd->rsrc_len = resource_size(res);
  207052. + hcd->regs = regs;
  207053. + hcd_to_ehci(hcd)->caps = regs;
  207054. +
  207055. + h20ahb = (struct h20ahb_hcd *)hcd_to_ehci(hcd)->priv;
  207056. + h20ahb->nports = 1;
  207057. +
  207058. + platform_set_drvdata(pdev, hcd);
  207059. +
  207060. + /* get the PHY devices if needed */
  207061. + for (i = 0 ; i < h20ahb->nports ; i++) {
  207062. + struct usb_phy *phy;
  207063. +
  207064. + /* get the PHY device */
  207065. +#if 0
  207066. + if (dev->of_node)
  207067. + phy = devm_usb_get_phy_by_phandle(dev, "phys", i);
  207068. + else
  207069. + phy = devm_usb_get_phy_dev(dev, i);
  207070. +#endif
  207071. + phy = otg_ulpi_create(&ehci_h20ahb_phy_io_ops, 0);
  207072. + if (IS_ERR(phy)) {
  207073. + ret = PTR_ERR(phy);
  207074. + dev_err(dev, "Can't get PHY device for port %d: %d\n",
  207075. + i, ret);
  207076. + goto err_phy;
  207077. + }
  207078. + phy->dev = dev;
  207079. + usb_add_phy_dev(phy);
  207080. +
  207081. + h20ahb->phy[i] = phy;
  207082. + phy->io_priv = hcd->regs + EHCI_INSNREG05_ULPI;
  207083. +
  207084. +#if 0
  207085. + usb_phy_init(h20ahb->phy[i]);
  207086. + /* bring PHY out of suspend */
  207087. + usb_phy_set_suspend(h20ahb->phy[i], 0);
  207088. +#endif
  207089. + }
  207090. +
  207091. + /* make the first port's phy the one used by hcd as well */
  207092. + hcd->phy = h20ahb->phy[0];
  207093. +
  207094. + pm_runtime_enable(dev);
  207095. + pm_runtime_get_sync(dev);
  207096. +
  207097. + /*
  207098. + * An undocumented "feature" in the H20AHB EHCI controller,
  207099. + * causes suspended ports to be taken out of suspend when
  207100. + * the USBCMD.Run/Stop bit is cleared (for example when
  207101. + * we do ehci_bus_suspend).
  207102. + * This breaks suspend-resume if the root-hub is allowed
  207103. + * to suspend. Writing 1 to this undocumented register bit
  207104. + * disables this feature and restores normal behavior.
  207105. + */
  207106. + ehci_write(regs, EHCI_INSNREG04,
  207107. + EHCI_INSNREG04_DISABLE_UNSUSPEND);
  207108. +
  207109. + ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
  207110. + if (ret) {
  207111. + dev_err(dev, "failed to add hcd with err %d\n", ret);
  207112. + goto err_pm_runtime;
  207113. + }
  207114. + device_wakeup_enable(hcd->self.controller);
  207115. +
  207116. + /*
  207117. + * Bring PHYs out of reset for non PHY modes.
  207118. + * Even though HSIC mode is a PHY-less mode, the reset
  207119. + * line exists between the chips and can be modelled
  207120. + * as a PHY device for reset control.
  207121. + */
  207122. + for (i = 0; i < h20ahb->nports; i++) {
  207123. + usb_phy_init(h20ahb->phy[i]);
  207124. + /* bring PHY out of suspend */
  207125. + usb_phy_set_suspend(h20ahb->phy[i], 0);
  207126. + }
  207127. +
  207128. + return 0;
  207129. +
  207130. +err_pm_runtime:
  207131. + pm_runtime_put_sync(dev);
  207132. +
  207133. +err_phy:
  207134. + for (i = 0; i < h20ahb->nports; i++) {
  207135. + if (h20ahb->phy[i])
  207136. + usb_phy_shutdown(h20ahb->phy[i]);
  207137. + }
  207138. +
  207139. + usb_put_hcd(hcd);
  207140. +
  207141. + return ret;
  207142. +}
  207143. +
  207144. +
  207145. +/**
  207146. + * ehci_hcd_h20ahb_remove - shutdown processing for EHCI HCDs
  207147. + * @pdev: USB Host Controller being removed
  207148. + *
  207149. + * Reverses the effect of usb_ehci_hcd_h20ahb_probe(), first invoking
  207150. + * the HCD's stop() method. It is always called from a thread
  207151. + * context, normally "rmmod", "apmd", or something similar.
  207152. + */
  207153. +static int ehci_hcd_h20ahb_remove(struct platform_device *pdev)
  207154. +{
  207155. + struct device *dev = &pdev->dev;
  207156. + struct usb_hcd *hcd = dev_get_drvdata(dev);
  207157. + struct h20ahb_hcd *h20ahb = (struct h20ahb_hcd *)hcd_to_ehci(hcd)->priv;
  207158. + int i;
  207159. +
  207160. + usb_remove_hcd(hcd);
  207161. +
  207162. + for (i = 0; i < h20ahb->nports; i++) {
  207163. + if (h20ahb->phy[i])
  207164. + usb_phy_shutdown(h20ahb->phy[i]);
  207165. + }
  207166. +
  207167. + usb_put_hcd(hcd);
  207168. + pm_runtime_put_sync(dev);
  207169. + pm_runtime_disable(dev);
  207170. +
  207171. + return 0;
  207172. +}
  207173. +
  207174. +static const struct of_device_id h20ahb_ehci_dt_ids[] = {
  207175. + { .compatible = "snps,ehci-h20ahb" },
  207176. + { }
  207177. +};
  207178. +
  207179. +MODULE_DEVICE_TABLE(of, h20ahb_ehci_dt_ids);
  207180. +
  207181. +static struct platform_driver ehci_hcd_h20ahb_driver = {
  207182. + .probe = ehci_hcd_h20ahb_probe,
  207183. + .remove = ehci_hcd_h20ahb_remove,
  207184. + .shutdown = usb_hcd_platform_shutdown,
  207185. + /*.suspend = ehci_hcd_h20ahb_suspend, */
  207186. + /*.resume = ehci_hcd_h20ahb_resume, */
  207187. + .driver = {
  207188. + .name = hcd_name,
  207189. + .of_match_table = h20ahb_ehci_dt_ids,
  207190. + }
  207191. +};
  207192. +
  207193. +/*-------------------------------------------------------------------------*/
  207194. +
  207195. +static int __init ehci_h20ahb_init(void)
  207196. +{
  207197. + if (usb_disabled())
  207198. + return -ENODEV;
  207199. +
  207200. + pr_info("%s: " DRIVER_DESC "\n", hcd_name);
  207201. +
  207202. + ehci_init_driver(&ehci_h20ahb_hc_driver, &ehci_h20ahb_overrides);
  207203. + return platform_driver_register(&ehci_hcd_h20ahb_driver);
  207204. +}
  207205. +module_init(ehci_h20ahb_init);
  207206. +
  207207. +static void __exit ehci_h20ahb_cleanup(void)
  207208. +{
  207209. + platform_driver_unregister(&ehci_hcd_h20ahb_driver);
  207210. +}
  207211. +module_exit(ehci_h20ahb_cleanup);
  207212. +
  207213. +MODULE_ALIAS("platform:ehci-h20ahb");
  207214. +MODULE_AUTHOR("Liviu Dudau <Liviu.Dudau@arm.com>");
  207215. +
  207216. +MODULE_DESCRIPTION(DRIVER_DESC);
  207217. +MODULE_LICENSE("GPL");
  207218. diff -Nur linux-3.14.15/drivers/usb/host/ehci-hcd.c linux-linaro-stable-mx6/drivers/usb/host/ehci-hcd.c
  207219. --- linux-3.14.15/drivers/usb/host/ehci-hcd.c 2014-07-31 23:51:43.000000000 +0200
  207220. +++ linux-linaro-stable-mx6/drivers/usb/host/ehci-hcd.c 2014-08-20 19:31:49.344882811 +0200
  207221. @@ -590,11 +590,16 @@
  207222. */
  207223. hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
  207224. if (HCC_64BIT_ADDR(hcc_params)) {
  207225. - ehci_writel(ehci, 0, &ehci->regs->segment);
  207226. -#if 0
  207227. -// this is deeply broken on almost all architectures
  207228. +#ifdef CONFIG_ARM64
  207229. + ehci_writel(ehci, ehci->periodic_dma >> 32, &ehci->regs->segment);
  207230. + /*
  207231. + * this is deeply broken on almost all architectures
  207232. + * but arm64 can use it so enable it
  207233. + */
  207234. if (!dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)))
  207235. ehci_info(ehci, "enabled 64bit DMA\n");
  207236. +#else
  207237. + ehci_writel(ehci, 0, &ehci->regs->segment);
  207238. #endif
  207239. }
  207240. diff -Nur linux-3.14.15/drivers/usb/host/ehci-hub.c linux-linaro-stable-mx6/drivers/usb/host/ehci-hub.c
  207241. --- linux-3.14.15/drivers/usb/host/ehci-hub.c 2014-07-31 23:51:43.000000000 +0200
  207242. +++ linux-linaro-stable-mx6/drivers/usb/host/ehci-hub.c 2014-08-20 19:31:49.344882811 +0200
  207243. @@ -313,6 +313,15 @@
  207244. USB_PORT_STAT_HIGH_SPEED)
  207245. fs_idle_delay = true;
  207246. ehci_writel(ehci, t2, reg);
  207247. + if ((t2 & PORT_WKDISC_E)
  207248. + && (ehci_port_speed(ehci, t2) ==
  207249. + USB_PORT_STAT_HIGH_SPEED))
  207250. + /*
  207251. + * If the high-speed device has not switched
  207252. + * to full-speed idle before WKDISC_E has
  207253. + * effected, there will be a WKDISC event.
  207254. + */
  207255. + mdelay(4);
  207256. changed = 1;
  207257. }
  207258. }
  207259. diff -Nur linux-3.14.15/drivers/usb/host/Kconfig linux-linaro-stable-mx6/drivers/usb/host/Kconfig
  207260. --- linux-3.14.15/drivers/usb/host/Kconfig 2014-07-31 23:51:43.000000000 +0200
  207261. +++ linux-linaro-stable-mx6/drivers/usb/host/Kconfig 2014-08-20 19:31:49.340882794 +0200
  207262. @@ -158,6 +158,13 @@
  207263. Enables support for the on-chip EHCI controller on
  207264. ST SPEAr chips.
  207265. +config USB_EHCI_HCD_SYNOPSYS
  207266. + tristate "Support for Synopsys Host-AHB USB 2.0 controller"
  207267. + depends on USB_EHCI_HCD && USB_PHY
  207268. + ---help---
  207269. + Enable support for onchip USB controllers based on DesignWare USB 2.0
  207270. + Host-AHB Controller IP from Synopsys.
  207271. +
  207272. config USB_EHCI_HCD_AT91
  207273. tristate "Support for Atmel on-chip EHCI USB controller"
  207274. depends on USB_EHCI_HCD && ARCH_AT91
  207275. diff -Nur linux-3.14.15/drivers/usb/host/Makefile linux-linaro-stable-mx6/drivers/usb/host/Makefile
  207276. --- linux-3.14.15/drivers/usb/host/Makefile 2014-07-31 23:51:43.000000000 +0200
  207277. +++ linux-linaro-stable-mx6/drivers/usb/host/Makefile 2014-08-20 19:31:49.340882794 +0200
  207278. @@ -33,6 +33,8 @@
  207279. obj-$(CONFIG_USB_EHCI_HCD_ORION) += ehci-orion.o
  207280. obj-$(CONFIG_USB_EHCI_HCD_SPEAR) += ehci-spear.o
  207281. obj-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
  207282. +obj-$(CONFIG_USB_EHCI_S5P) += ehci-s5p.o
  207283. +obj-$(CONFIG_USB_EHCI_HCD_SYNOPSYS) += ehci-h20ahb.o
  207284. obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
  207285. obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o
  207286. obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
  207287. diff -Nur linux-3.14.15/drivers/usb/phy/Kconfig linux-linaro-stable-mx6/drivers/usb/phy/Kconfig
  207288. --- linux-3.14.15/drivers/usb/phy/Kconfig 2014-07-31 23:51:43.000000000 +0200
  207289. +++ linux-linaro-stable-mx6/drivers/usb/phy/Kconfig 2014-08-20 19:31:49.532883619 +0200
  207290. @@ -253,7 +253,7 @@
  207291. config USB_ULPI
  207292. bool "Generic ULPI Transceiver Driver"
  207293. - depends on ARM
  207294. + depends on ARM || ARM64
  207295. help
  207296. Enable this to support ULPI connected USB OTG transceivers which
  207297. are likely found on embedded boards.
  207298. diff -Nur linux-3.14.15/drivers/usb/phy/phy-mxs-usb.c linux-linaro-stable-mx6/drivers/usb/phy/phy-mxs-usb.c
  207299. --- linux-3.14.15/drivers/usb/phy/phy-mxs-usb.c 2014-07-31 23:51:43.000000000 +0200
  207300. +++ linux-linaro-stable-mx6/drivers/usb/phy/phy-mxs-usb.c 2014-08-20 19:31:49.536883636 +0200
  207301. @@ -1,5 +1,5 @@
  207302. /*
  207303. - * Copyright 2012 Freescale Semiconductor, Inc.
  207304. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  207305. * Copyright (C) 2012 Marek Vasut <marex@denx.de>
  207306. * on behalf of DENX Software Engineering GmbH
  207307. *
  207308. @@ -20,6 +20,9 @@
  207309. #include <linux/delay.h>
  207310. #include <linux/err.h>
  207311. #include <linux/io.h>
  207312. +#include <linux/of_device.h>
  207313. +#include <linux/regmap.h>
  207314. +#include <linux/mfd/syscon.h>
  207315. #define DRIVER_NAME "mxs_phy"
  207316. @@ -28,18 +31,137 @@
  207317. #define HW_USBPHY_CTRL_SET 0x34
  207318. #define HW_USBPHY_CTRL_CLR 0x38
  207319. +#define HW_USBPHY_DEBUG_SET 0x54
  207320. +#define HW_USBPHY_DEBUG_CLR 0x58
  207321. +
  207322. +#define HW_USBPHY_IP 0x90
  207323. +#define HW_USBPHY_IP_SET 0x94
  207324. +#define HW_USBPHY_IP_CLR 0x98
  207325. +
  207326. #define BM_USBPHY_CTRL_SFTRST BIT(31)
  207327. #define BM_USBPHY_CTRL_CLKGATE BIT(30)
  207328. +#define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS BIT(26)
  207329. +#define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE BIT(25)
  207330. +#define BM_USBPHY_CTRL_ENVBUSCHG_WKUP BIT(23)
  207331. +#define BM_USBPHY_CTRL_ENIDCHG_WKUP BIT(22)
  207332. +#define BM_USBPHY_CTRL_ENDPDMCHG_WKUP BIT(21)
  207333. +#define BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD BIT(20)
  207334. +#define BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE BIT(19)
  207335. +#define BM_USBPHY_CTRL_ENAUTO_PWRON_PLL BIT(18)
  207336. #define BM_USBPHY_CTRL_ENUTMILEVEL3 BIT(15)
  207337. #define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14)
  207338. #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1)
  207339. +#define BM_USBPHY_IP_FIX (BIT(17) | BIT(18))
  207340. +
  207341. +#define BM_USBPHY_DEBUG_CLKGATE BIT(30)
  207342. +
  207343. +/* Anatop Registers */
  207344. +#define ANADIG_ANA_MISC0 0x150
  207345. +#define ANADIG_ANA_MISC0_SET 0x154
  207346. +#define ANADIG_ANA_MISC0_CLR 0x158
  207347. +
  207348. +#define ANADIG_USB1_VBUS_DET_STAT 0x1c0
  207349. +#define ANADIG_USB2_VBUS_DET_STAT 0x220
  207350. +
  207351. +#define ANADIG_USB1_LOOPBACK_SET 0x1e4
  207352. +#define ANADIG_USB1_LOOPBACK_CLR 0x1e8
  207353. +#define ANADIG_USB2_LOOPBACK_SET 0x244
  207354. +#define ANADIG_USB2_LOOPBACK_CLR 0x248
  207355. +
  207356. +#define ANADIG_USB1_MISC 0x1f0
  207357. +#define ANADIG_USB2_MISC 0x250
  207358. +
  207359. +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG BIT(12)
  207360. +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11)
  207361. +
  207362. +#define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID BIT(3)
  207363. +#define BM_ANADIG_USB2_VBUS_DET_STAT_VBUS_VALID BIT(3)
  207364. +
  207365. +#define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 BIT(2)
  207366. +#define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN BIT(5)
  207367. +#define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 BIT(2)
  207368. +#define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN BIT(5)
  207369. +
  207370. +#define BM_ANADIG_USB1_MISC_RX_VPIN_FS BIT(29)
  207371. +#define BM_ANADIG_USB1_MISC_RX_VMIN_FS BIT(28)
  207372. +#define BM_ANADIG_USB2_MISC_RX_VPIN_FS BIT(29)
  207373. +#define BM_ANADIG_USB2_MISC_RX_VMIN_FS BIT(28)
  207374. +
  207375. +#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
  207376. +
  207377. +/* Do disconnection between PHY and controller without vbus */
  207378. +#define MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS BIT(0)
  207379. +
  207380. +/*
  207381. + * The PHY will be in messy if there is an wakeup after putting
  207382. + * bus to suspend (set portsc.suspendM) but before setting PHY to low
  207383. + * power mode (set portsc.phcd).
  207384. + */
  207385. +#define MXS_PHY_ABNORAML_IN_SUSPEND BIT(1)
  207386. +
  207387. +/*
  207388. + * The SOF sends too fast after resuming, it will cause disconnection
  207389. + * between host and high speed device.
  207390. + */
  207391. +#define MXS_PHY_SENDING_SOF_TOO_FAST BIT(2)
  207392. +
  207393. +/* The SoCs who have anatop module */
  207394. +#define MXS_PHY_HAS_ANATOP BIT(3)
  207395. +
  207396. +struct mxs_phy_data {
  207397. + unsigned int flags;
  207398. +};
  207399. +
  207400. +static const struct mxs_phy_data imx23_phy_data = {
  207401. + .flags = MXS_PHY_ABNORAML_IN_SUSPEND | MXS_PHY_SENDING_SOF_TOO_FAST,
  207402. +};
  207403. +
  207404. +static const struct mxs_phy_data imx6q_phy_data = {
  207405. + .flags = MXS_PHY_SENDING_SOF_TOO_FAST |
  207406. + MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
  207407. + MXS_PHY_HAS_ANATOP,
  207408. +};
  207409. +
  207410. +static const struct mxs_phy_data imx6sl_phy_data = {
  207411. + .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
  207412. + MXS_PHY_HAS_ANATOP,
  207413. +};
  207414. +
  207415. +static const struct of_device_id mxs_phy_dt_ids[] = {
  207416. + { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
  207417. + { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
  207418. + { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
  207419. + { /* sentinel */ }
  207420. +};
  207421. +MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
  207422. +
  207423. struct mxs_phy {
  207424. struct usb_phy phy;
  207425. struct clk *clk;
  207426. + const struct mxs_phy_data *data;
  207427. + struct regmap *regmap_anatop;
  207428. + int port_id;
  207429. };
  207430. -#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
  207431. +static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy)
  207432. +{
  207433. + return mxs_phy->data == &imx6q_phy_data;
  207434. +}
  207435. +
  207436. +static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy)
  207437. +{
  207438. + return mxs_phy->data == &imx6sl_phy_data;
  207439. +}
  207440. +
  207441. +/*
  207442. + * PHY needs some 32K cycles to switch from 32K clock to
  207443. + * bus (such as AHB/AXI, etc) clock.
  207444. + */
  207445. +static void mxs_phy_clock_switch(void)
  207446. +{
  207447. + usleep_range(300, 400);
  207448. +}
  207449. static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
  207450. {
  207451. @@ -53,19 +175,122 @@
  207452. /* Power up the PHY */
  207453. writel(0, base + HW_USBPHY_PWD);
  207454. - /* enable FS/LS device */
  207455. - writel(BM_USBPHY_CTRL_ENUTMILEVEL2 |
  207456. - BM_USBPHY_CTRL_ENUTMILEVEL3,
  207457. + /*
  207458. + * USB PHY Ctrl Setting
  207459. + * - Auto clock/power on
  207460. + * - Enable full/low speed support
  207461. + */
  207462. + writel(BM_USBPHY_CTRL_ENAUTOSET_USBCLKS |
  207463. + BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE |
  207464. + BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD |
  207465. + BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE |
  207466. + BM_USBPHY_CTRL_ENAUTO_PWRON_PLL |
  207467. + BM_USBPHY_CTRL_ENUTMILEVEL2 |
  207468. + BM_USBPHY_CTRL_ENUTMILEVEL3,
  207469. base + HW_USBPHY_CTRL_SET);
  207470. + /* Enable IC solution */
  207471. + if (is_imx6q_phy(mxs_phy) || is_imx6sl_phy(mxs_phy))
  207472. + writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET);
  207473. +
  207474. return 0;
  207475. }
  207476. +/* Return true if the vbus is there */
  207477. +static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy)
  207478. +{
  207479. + unsigned int vbus_value;
  207480. +
  207481. + if (mxs_phy->port_id == 0)
  207482. + regmap_read(mxs_phy->regmap_anatop,
  207483. + ANADIG_USB1_VBUS_DET_STAT,
  207484. + &vbus_value);
  207485. + else if (mxs_phy->port_id == 1)
  207486. + regmap_read(mxs_phy->regmap_anatop,
  207487. + ANADIG_USB2_VBUS_DET_STAT,
  207488. + &vbus_value);
  207489. +
  207490. + if (vbus_value & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)
  207491. + return true;
  207492. + else
  207493. + return false;
  207494. +}
  207495. +
  207496. +static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
  207497. +{
  207498. + void __iomem *base = mxs_phy->phy.io_priv;
  207499. + u32 reg;
  207500. +
  207501. + if (disconnect)
  207502. + writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
  207503. + base + HW_USBPHY_DEBUG_CLR);
  207504. +
  207505. + if (mxs_phy->port_id == 0) {
  207506. + reg = disconnect ? ANADIG_USB1_LOOPBACK_SET
  207507. + : ANADIG_USB1_LOOPBACK_CLR;
  207508. + regmap_write(mxs_phy->regmap_anatop, reg,
  207509. + BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 |
  207510. + BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN);
  207511. + } else if (mxs_phy->port_id == 1) {
  207512. + reg = disconnect ? ANADIG_USB2_LOOPBACK_SET
  207513. + : ANADIG_USB2_LOOPBACK_CLR;
  207514. + regmap_write(mxs_phy->regmap_anatop, reg,
  207515. + BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 |
  207516. + BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN);
  207517. + }
  207518. +
  207519. + if (!disconnect)
  207520. + writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
  207521. + base + HW_USBPHY_DEBUG_SET);
  207522. +
  207523. + /* Delay some time, and let Linestate be SE0 for controller */
  207524. + if (disconnect)
  207525. + usleep_range(500, 1000);
  207526. +}
  207527. +
  207528. +static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
  207529. +{
  207530. + bool vbus_is_on = false;
  207531. +
  207532. + /* If the SoCs don't need to disconnect line without vbus, quit */
  207533. + if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS))
  207534. + return;
  207535. +
  207536. + /* If the SoCs don't have anatop, quit */
  207537. + if (!mxs_phy->regmap_anatop)
  207538. + return;
  207539. +
  207540. + vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
  207541. +
  207542. + if (on && !vbus_is_on)
  207543. + __mxs_phy_disconnect_line(mxs_phy, true);
  207544. + else
  207545. + __mxs_phy_disconnect_line(mxs_phy, false);
  207546. +
  207547. +}
  207548. +
  207549. +static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on)
  207550. +{
  207551. + unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR;
  207552. +
  207553. + /* If the SoCs don't have anatop, quit */
  207554. + if (!mxs_phy->regmap_anatop)
  207555. + return;
  207556. +
  207557. + if (is_imx6q_phy(mxs_phy))
  207558. + regmap_write(mxs_phy->regmap_anatop, reg,
  207559. + BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG);
  207560. + else if (is_imx6sl_phy(mxs_phy))
  207561. + regmap_write(mxs_phy->regmap_anatop,
  207562. + reg, BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL);
  207563. +}
  207564. +
  207565. static int mxs_phy_init(struct usb_phy *phy)
  207566. {
  207567. int ret;
  207568. struct mxs_phy *mxs_phy = to_mxs_phy(phy);
  207569. + mxs_phy_clock_switch();
  207570. ret = clk_prepare_enable(mxs_phy->clk);
  207571. if (ret)
  207572. return ret;
  207573. @@ -83,17 +308,62 @@
  207574. clk_disable_unprepare(mxs_phy->clk);
  207575. }
  207576. +static bool mxs_phy_is_low_speed_connection(struct mxs_phy *mxs_phy)
  207577. +{
  207578. + unsigned int line_state;
  207579. + /* bit definition is the same for all controllers */
  207580. + unsigned int dp_bit = BM_ANADIG_USB1_MISC_RX_VPIN_FS,
  207581. + dm_bit = BM_ANADIG_USB1_MISC_RX_VMIN_FS;
  207582. + unsigned int reg = ANADIG_USB1_MISC;
  207583. +
  207584. + /* If the SoCs don't have anatop, quit */
  207585. + if (!mxs_phy->regmap_anatop)
  207586. + return false;
  207587. +
  207588. + if (mxs_phy->port_id == 0)
  207589. + reg = ANADIG_USB1_MISC;
  207590. + else if (mxs_phy->port_id == 1)
  207591. + reg = ANADIG_USB2_MISC;
  207592. +
  207593. + regmap_read(mxs_phy->regmap_anatop, reg, &line_state);
  207594. +
  207595. + if ((line_state & (dp_bit | dm_bit)) == dm_bit)
  207596. + return true;
  207597. + else
  207598. + return false;
  207599. +}
  207600. +
  207601. static int mxs_phy_suspend(struct usb_phy *x, int suspend)
  207602. {
  207603. int ret;
  207604. struct mxs_phy *mxs_phy = to_mxs_phy(x);
  207605. + bool low_speed_connection, vbus_is_on;
  207606. +
  207607. + low_speed_connection = mxs_phy_is_low_speed_connection(mxs_phy);
  207608. + vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
  207609. if (suspend) {
  207610. writel(0xffffffff, x->io_priv + HW_USBPHY_PWD);
  207611. + /*
  207612. + * FIXME: Do not power down RXPWD1PT1 bit for low speed
  207613. + * connect. The low speed connection will have problem at
  207614. + * very rare cases during usb suspend and resume process.
  207615. + */
  207616. + if (low_speed_connection & vbus_is_on) {
  207617. + /*
  207618. + * If value to be set as pwd value is not 0xffffffff,
  207619. + * several 32Khz cycles are needed.
  207620. + */
  207621. + mxs_phy_clock_switch();
  207622. + writel(0xffbfffff, x->io_priv + HW_USBPHY_PWD);
  207623. + } else {
  207624. + writel(0xffffffff, x->io_priv + HW_USBPHY_PWD);
  207625. + }
  207626. writel(BM_USBPHY_CTRL_CLKGATE,
  207627. x->io_priv + HW_USBPHY_CTRL_SET);
  207628. clk_disable_unprepare(mxs_phy->clk);
  207629. } else {
  207630. + mxs_phy_clock_switch();
  207631. ret = clk_prepare_enable(mxs_phy->clk);
  207632. if (ret)
  207633. return ret;
  207634. @@ -105,11 +375,28 @@
  207635. return 0;
  207636. }
  207637. +static int mxs_phy_set_wakeup(struct usb_phy *x, bool enabled)
  207638. +{
  207639. + struct mxs_phy *mxs_phy = to_mxs_phy(x);
  207640. + u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP |
  207641. + BM_USBPHY_CTRL_ENDPDMCHG_WKUP |
  207642. + BM_USBPHY_CTRL_ENIDCHG_WKUP;
  207643. + if (enabled) {
  207644. + mxs_phy_disconnect_line(mxs_phy, true);
  207645. + writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_SET);
  207646. + } else {
  207647. + writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_CLR);
  207648. + mxs_phy_disconnect_line(mxs_phy, false);
  207649. + }
  207650. +
  207651. + return 0;
  207652. +}
  207653. +
  207654. static int mxs_phy_on_connect(struct usb_phy *phy,
  207655. enum usb_device_speed speed)
  207656. {
  207657. - dev_dbg(phy->dev, "%s speed device has connected\n",
  207658. - (speed == USB_SPEED_HIGH) ? "high" : "non-high");
  207659. + dev_dbg(phy->dev, "%s device has connected\n",
  207660. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  207661. if (speed == USB_SPEED_HIGH)
  207662. writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  207663. @@ -121,8 +408,8 @@
  207664. static int mxs_phy_on_disconnect(struct usb_phy *phy,
  207665. enum usb_device_speed speed)
  207666. {
  207667. - dev_dbg(phy->dev, "%s speed device has disconnected\n",
  207668. - (speed == USB_SPEED_HIGH) ? "high" : "non-high");
  207669. + dev_dbg(phy->dev, "%s device has disconnected\n",
  207670. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  207671. if (speed == USB_SPEED_HIGH)
  207672. writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  207673. @@ -131,6 +418,48 @@
  207674. return 0;
  207675. }
  207676. +static int mxs_phy_on_suspend(struct usb_phy *phy,
  207677. + enum usb_device_speed speed)
  207678. +{
  207679. + struct mxs_phy *mxs_phy = to_mxs_phy(phy);
  207680. +
  207681. + dev_dbg(phy->dev, "%s device has suspended\n",
  207682. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  207683. +
  207684. + /* delay 4ms to wait bus entering idle */
  207685. + usleep_range(4000, 5000);
  207686. +
  207687. + if (mxs_phy->data->flags & MXS_PHY_ABNORAML_IN_SUSPEND) {
  207688. + writel_relaxed(0xffffffff, phy->io_priv + HW_USBPHY_PWD);
  207689. + writel_relaxed(0, phy->io_priv + HW_USBPHY_PWD);
  207690. + }
  207691. +
  207692. + if (speed == USB_SPEED_HIGH)
  207693. + writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  207694. + phy->io_priv + HW_USBPHY_CTRL_CLR);
  207695. +
  207696. + return 0;
  207697. +}
  207698. +
  207699. +/*
  207700. + * The resume signal must be finished here.
  207701. + */
  207702. +static int mxs_phy_on_resume(struct usb_phy *phy,
  207703. + enum usb_device_speed speed)
  207704. +{
  207705. + dev_dbg(phy->dev, "%s device has resumed\n",
  207706. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  207707. +
  207708. + if (speed == USB_SPEED_HIGH) {
  207709. + /* Make sure the device has switched to High-Speed mode */
  207710. + udelay(500);
  207711. + writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  207712. + phy->io_priv + HW_USBPHY_CTRL_SET);
  207713. + }
  207714. +
  207715. + return 0;
  207716. +}
  207717. +
  207718. static int mxs_phy_probe(struct platform_device *pdev)
  207719. {
  207720. struct resource *res;
  207721. @@ -138,6 +467,9 @@
  207722. struct clk *clk;
  207723. struct mxs_phy *mxs_phy;
  207724. int ret;
  207725. + const struct of_device_id *of_id =
  207726. + of_match_device(mxs_phy_dt_ids, &pdev->dev);
  207727. + struct device_node *np = pdev->dev.of_node;
  207728. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  207729. base = devm_ioremap_resource(&pdev->dev, res);
  207730. @@ -157,6 +489,13 @@
  207731. return -ENOMEM;
  207732. }
  207733. + ret = of_alias_get_id(np, "usbphy");
  207734. + if (ret < 0) {
  207735. + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
  207736. + return ret;
  207737. + }
  207738. + mxs_phy->port_id = ret;
  207739. +
  207740. mxs_phy->phy.io_priv = base;
  207741. mxs_phy->phy.dev = &pdev->dev;
  207742. mxs_phy->phy.label = DRIVER_NAME;
  207743. @@ -166,11 +505,30 @@
  207744. mxs_phy->phy.notify_connect = mxs_phy_on_connect;
  207745. mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect;
  207746. mxs_phy->phy.type = USB_PHY_TYPE_USB2;
  207747. + mxs_phy->phy.set_wakeup = mxs_phy_set_wakeup;
  207748. mxs_phy->clk = clk;
  207749. + mxs_phy->data = of_id->data;
  207750. +
  207751. + if (mxs_phy->data->flags & MXS_PHY_SENDING_SOF_TOO_FAST) {
  207752. + mxs_phy->phy.notify_suspend = mxs_phy_on_suspend;
  207753. + mxs_phy->phy.notify_resume = mxs_phy_on_resume;
  207754. + }
  207755. platform_set_drvdata(pdev, mxs_phy);
  207756. + if (mxs_phy->data->flags & MXS_PHY_HAS_ANATOP) {
  207757. + mxs_phy->regmap_anatop = syscon_regmap_lookup_by_phandle
  207758. + (np, "fsl,anatop");
  207759. + if (IS_ERR(mxs_phy->regmap_anatop)) {
  207760. + dev_dbg(&pdev->dev,
  207761. + "failed to find regmap for anatop\n");
  207762. + return PTR_ERR(mxs_phy->regmap_anatop);
  207763. + }
  207764. + }
  207765. +
  207766. + device_set_wakeup_capable(&pdev->dev, true);
  207767. +
  207768. ret = usb_add_phy_dev(&mxs_phy->phy);
  207769. if (ret)
  207770. return ret;
  207771. @@ -187,11 +545,27 @@
  207772. return 0;
  207773. }
  207774. -static const struct of_device_id mxs_phy_dt_ids[] = {
  207775. - { .compatible = "fsl,imx23-usbphy", },
  207776. - { /* sentinel */ }
  207777. -};
  207778. -MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
  207779. +static int mxs_phy_system_suspend(struct device *dev)
  207780. +{
  207781. + struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
  207782. +
  207783. + if (device_may_wakeup(dev))
  207784. + mxs_phy_enable_ldo_in_suspend(mxs_phy, true);
  207785. +
  207786. + return 0;
  207787. +}
  207788. +
  207789. +static int mxs_phy_system_resume(struct device *dev)
  207790. +{
  207791. + struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
  207792. +
  207793. + if (device_may_wakeup(dev))
  207794. + mxs_phy_enable_ldo_in_suspend(mxs_phy, false);
  207795. +
  207796. + return 0;
  207797. +}
  207798. +
  207799. +SIMPLE_DEV_PM_OPS(mxs_phy_pm, mxs_phy_system_suspend, mxs_phy_system_resume);
  207800. static struct platform_driver mxs_phy_driver = {
  207801. .probe = mxs_phy_probe,
  207802. @@ -200,6 +574,7 @@
  207803. .name = DRIVER_NAME,
  207804. .owner = THIS_MODULE,
  207805. .of_match_table = mxs_phy_dt_ids,
  207806. + .pm = &mxs_phy_pm,
  207807. },
  207808. };
  207809. diff -Nur linux-3.14.15/drivers/usb/phy/phy-ulpi.c linux-linaro-stable-mx6/drivers/usb/phy/phy-ulpi.c
  207810. --- linux-3.14.15/drivers/usb/phy/phy-ulpi.c 2014-07-31 23:51:43.000000000 +0200
  207811. +++ linux-linaro-stable-mx6/drivers/usb/phy/phy-ulpi.c 2014-08-20 19:31:49.536883636 +0200
  207812. @@ -48,6 +48,7 @@
  207813. ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"),
  207814. ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"),
  207815. ULPI_INFO(ULPI_ID(0x0424, 0x0007), "SMSC USB3320"),
  207816. + ULPI_INFO(ULPI_ID(0x0424, 0x0009), "SMSC USB334x"),
  207817. ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"),
  207818. };
  207819. diff -Nur linux-3.14.15/drivers/video/amba-clcd.c linux-linaro-stable-mx6/drivers/video/amba-clcd.c
  207820. --- linux-3.14.15/drivers/video/amba-clcd.c 2014-07-31 23:51:43.000000000 +0200
  207821. +++ linux-linaro-stable-mx6/drivers/video/amba-clcd.c 2014-08-20 19:31:49.580883825 +0200
  207822. @@ -17,7 +17,10 @@
  207823. #include <linux/string.h>
  207824. #include <linux/slab.h>
  207825. #include <linux/delay.h>
  207826. +#include <linux/dma-mapping.h>
  207827. +#include <linux/memblock.h>
  207828. #include <linux/mm.h>
  207829. +#include <linux/of.h>
  207830. #include <linux/fb.h>
  207831. #include <linux/init.h>
  207832. #include <linux/ioport.h>
  207833. @@ -31,8 +34,20 @@
  207834. #define to_clcd(info) container_of(info, struct clcd_fb, fb)
  207835. +#ifdef CONFIG_ARM
  207836. +#define clcdfb_dma_alloc dma_alloc_writecombine
  207837. +#define clcdfb_dma_free dma_free_writecombine
  207838. +#define clcdfb_dma_mmap dma_mmap_writecombine
  207839. +#else
  207840. +#define clcdfb_dma_alloc dma_alloc_coherent
  207841. +#define clcdfb_dma_free dma_free_coherent
  207842. +#define clcdfb_dma_mmap dma_mmap_coherent
  207843. +#endif
  207844. +
  207845. /* This is limited to 16 characters when displayed by X startup */
  207846. static const char *clcd_name = "CLCD FB";
  207847. +static char *def_mode;
  207848. +module_param_named(mode, def_mode, charp, 0);
  207849. /*
  207850. * Unfortunately, the enable/disable functions may be called either from
  207851. @@ -234,6 +249,17 @@
  207852. bgr = caps & CLCD_CAP_BGR && var->blue.offset == 0;
  207853. rgb = caps & CLCD_CAP_RGB && var->red.offset == 0;
  207854. + /*
  207855. + * Seems that for 32-bit mode there is confusion about RGB
  207856. + * ordering somewhere between user-side, kernel and hardware.
  207857. + * The following hack seems get things working, at least on
  207858. + * vexpress hardware and models...
  207859. + */
  207860. + if (var->bits_per_pixel == 32) {
  207861. + bgr = false;
  207862. + rgb = true;
  207863. + }
  207864. +
  207865. if (!bgr && !rgb)
  207866. /*
  207867. * The requested format was not possible, try just
  207868. @@ -393,6 +419,44 @@
  207869. return 0;
  207870. }
  207871. +int clcdfb_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma)
  207872. +{
  207873. + return clcdfb_dma_mmap(&fb->dev->dev, vma,
  207874. + fb->fb.screen_base,
  207875. + fb->fb.fix.smem_start,
  207876. + fb->fb.fix.smem_len);
  207877. +}
  207878. +
  207879. +int clcdfb_mmap_io(struct clcd_fb *fb, struct vm_area_struct *vma)
  207880. +{
  207881. + unsigned long user_count, count, pfn, off;
  207882. +
  207883. + user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
  207884. + count = PAGE_ALIGN(fb->fb.fix.smem_len) >> PAGE_SHIFT;
  207885. + pfn = fb->fb.fix.smem_start >> PAGE_SHIFT;
  207886. + off = vma->vm_pgoff;
  207887. +
  207888. + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  207889. +
  207890. + if (off < count && user_count <= (count - off))
  207891. + return remap_pfn_range(vma, vma->vm_start, pfn + off,
  207892. + user_count << PAGE_SHIFT,
  207893. + vma->vm_page_prot);
  207894. +
  207895. + return -ENXIO;
  207896. +}
  207897. +
  207898. +void clcdfb_remove_dma(struct clcd_fb *fb)
  207899. +{
  207900. + clcdfb_dma_free(&fb->dev->dev, fb->fb.fix.smem_len,
  207901. + fb->fb.screen_base, fb->fb.fix.smem_start);
  207902. +}
  207903. +
  207904. +void clcdfb_remove_io(struct clcd_fb *fb)
  207905. +{
  207906. + iounmap(fb->fb.screen_base);
  207907. +}
  207908. +
  207909. static int clcdfb_mmap(struct fb_info *info,
  207910. struct vm_area_struct *vma)
  207911. {
  207912. @@ -543,14 +607,247 @@
  207913. return ret;
  207914. }
  207915. +struct string_lookup {
  207916. + const char *string;
  207917. + const u32 val;
  207918. +};
  207919. +
  207920. +static struct string_lookup vmode_lookups[] = {
  207921. + { "FB_VMODE_NONINTERLACED", FB_VMODE_NONINTERLACED},
  207922. + { "FB_VMODE_INTERLACED", FB_VMODE_INTERLACED},
  207923. + { "FB_VMODE_DOUBLE", FB_VMODE_DOUBLE},
  207924. + { "FB_VMODE_ODD_FLD_FIRST", FB_VMODE_ODD_FLD_FIRST},
  207925. + { NULL, 0 },
  207926. +};
  207927. +
  207928. +static struct string_lookup tim2_lookups[] = {
  207929. + { "TIM2_CLKSEL", TIM2_CLKSEL},
  207930. + { "TIM2_IVS", TIM2_IVS},
  207931. + { "TIM2_IHS", TIM2_IHS},
  207932. + { "TIM2_IPC", TIM2_IPC},
  207933. + { "TIM2_IOE", TIM2_IOE},
  207934. + { "TIM2_BCD", TIM2_BCD},
  207935. + { NULL, 0},
  207936. +};
  207937. +static struct string_lookup cntl_lookups[] = {
  207938. + {"CNTL_LCDEN", CNTL_LCDEN},
  207939. + {"CNTL_LCDBPP1", CNTL_LCDBPP1},
  207940. + {"CNTL_LCDBPP2", CNTL_LCDBPP2},
  207941. + {"CNTL_LCDBPP4", CNTL_LCDBPP4},
  207942. + {"CNTL_LCDBPP8", CNTL_LCDBPP8},
  207943. + {"CNTL_LCDBPP16", CNTL_LCDBPP16},
  207944. + {"CNTL_LCDBPP16_565", CNTL_LCDBPP16_565},
  207945. + {"CNTL_LCDBPP16_444", CNTL_LCDBPP16_444},
  207946. + {"CNTL_LCDBPP24", CNTL_LCDBPP24},
  207947. + {"CNTL_LCDBW", CNTL_LCDBW},
  207948. + {"CNTL_LCDTFT", CNTL_LCDTFT},
  207949. + {"CNTL_LCDMONO8", CNTL_LCDMONO8},
  207950. + {"CNTL_LCDDUAL", CNTL_LCDDUAL},
  207951. + {"CNTL_BGR", CNTL_BGR},
  207952. + {"CNTL_BEBO", CNTL_BEBO},
  207953. + {"CNTL_BEPO", CNTL_BEPO},
  207954. + {"CNTL_LCDPWR", CNTL_LCDPWR},
  207955. + {"CNTL_LCDVCOMP(1)", CNTL_LCDVCOMP(1)},
  207956. + {"CNTL_LCDVCOMP(2)", CNTL_LCDVCOMP(2)},
  207957. + {"CNTL_LCDVCOMP(3)", CNTL_LCDVCOMP(3)},
  207958. + {"CNTL_LCDVCOMP(4)", CNTL_LCDVCOMP(4)},
  207959. + {"CNTL_LCDVCOMP(5)", CNTL_LCDVCOMP(5)},
  207960. + {"CNTL_LCDVCOMP(6)", CNTL_LCDVCOMP(6)},
  207961. + {"CNTL_LCDVCOMP(7)", CNTL_LCDVCOMP(7)},
  207962. + {"CNTL_LDMAFIFOTIME", CNTL_LDMAFIFOTIME},
  207963. + {"CNTL_WATERMARK", CNTL_WATERMARK},
  207964. + { NULL, 0},
  207965. +};
  207966. +static struct string_lookup caps_lookups[] = {
  207967. + {"CLCD_CAP_RGB444", CLCD_CAP_RGB444},
  207968. + {"CLCD_CAP_RGB5551", CLCD_CAP_RGB5551},
  207969. + {"CLCD_CAP_RGB565", CLCD_CAP_RGB565},
  207970. + {"CLCD_CAP_RGB888", CLCD_CAP_RGB888},
  207971. + {"CLCD_CAP_BGR444", CLCD_CAP_BGR444},
  207972. + {"CLCD_CAP_BGR5551", CLCD_CAP_BGR5551},
  207973. + {"CLCD_CAP_BGR565", CLCD_CAP_BGR565},
  207974. + {"CLCD_CAP_BGR888", CLCD_CAP_BGR888},
  207975. + {"CLCD_CAP_444", CLCD_CAP_444},
  207976. + {"CLCD_CAP_5551", CLCD_CAP_5551},
  207977. + {"CLCD_CAP_565", CLCD_CAP_565},
  207978. + {"CLCD_CAP_888", CLCD_CAP_888},
  207979. + {"CLCD_CAP_RGB", CLCD_CAP_RGB},
  207980. + {"CLCD_CAP_BGR", CLCD_CAP_BGR},
  207981. + {"CLCD_CAP_ALL", CLCD_CAP_ALL},
  207982. + { NULL, 0},
  207983. +};
  207984. +
  207985. +u32 parse_setting(struct string_lookup *lookup, const char *name)
  207986. +{
  207987. + int i = 0;
  207988. + while (lookup[i].string != NULL) {
  207989. + if (strcmp(lookup[i].string, name) == 0)
  207990. + return lookup[i].val;
  207991. + ++i;
  207992. + }
  207993. + return -EINVAL;
  207994. +}
  207995. +
  207996. +u32 get_string_lookup(struct device_node *node, const char *name,
  207997. + struct string_lookup *lookup)
  207998. +{
  207999. + const char *string;
  208000. + int count, i, ret = 0;
  208001. +
  208002. + count = of_property_count_strings(node, name);
  208003. + if (count >= 0)
  208004. + for (i = 0; i < count; i++)
  208005. + if (of_property_read_string_index(node, name, i,
  208006. + &string) == 0)
  208007. + ret |= parse_setting(lookup, string);
  208008. + return ret;
  208009. +}
  208010. +
  208011. +int get_val(struct device_node *node, const char *string)
  208012. +{
  208013. + u32 ret = 0;
  208014. +
  208015. + if (of_property_read_u32(node, string, &ret))
  208016. + ret = -1;
  208017. + return ret;
  208018. +}
  208019. +
  208020. +struct clcd_panel *getPanel(struct device_node *node)
  208021. +{
  208022. + static struct clcd_panel panel;
  208023. +
  208024. + panel.mode.refresh = get_val(node, "refresh");
  208025. + panel.mode.xres = get_val(node, "xres");
  208026. + panel.mode.yres = get_val(node, "yres");
  208027. + panel.mode.pixclock = get_val(node, "pixclock");
  208028. + panel.mode.left_margin = get_val(node, "left_margin");
  208029. + panel.mode.right_margin = get_val(node, "right_margin");
  208030. + panel.mode.upper_margin = get_val(node, "upper_margin");
  208031. + panel.mode.lower_margin = get_val(node, "lower_margin");
  208032. + panel.mode.hsync_len = get_val(node, "hsync_len");
  208033. + panel.mode.vsync_len = get_val(node, "vsync_len");
  208034. + panel.mode.sync = get_val(node, "sync");
  208035. + panel.bpp = get_val(node, "bpp");
  208036. + panel.width = (signed short) get_val(node, "width");
  208037. + panel.height = (signed short) get_val(node, "height");
  208038. +
  208039. + panel.mode.vmode = get_string_lookup(node, "vmode", vmode_lookups);
  208040. + panel.tim2 = get_string_lookup(node, "tim2", tim2_lookups);
  208041. + panel.cntl = get_string_lookup(node, "cntl", cntl_lookups);
  208042. + panel.caps = get_string_lookup(node, "caps", caps_lookups);
  208043. +
  208044. + return &panel;
  208045. +}
  208046. +
  208047. +struct clcd_panel *clcdfb_get_panel(const char *name)
  208048. +{
  208049. + struct device_node *node = NULL;
  208050. + const char *mode;
  208051. + struct clcd_panel *panel = NULL;
  208052. +
  208053. + do {
  208054. + node = of_find_compatible_node(node, NULL, "panel");
  208055. + if (node)
  208056. + if (of_property_read_string(node, "mode", &mode) == 0)
  208057. + if (strcmp(mode, name) == 0) {
  208058. + panel = getPanel(node);
  208059. + panel->mode.name = name;
  208060. + }
  208061. + } while (node != NULL);
  208062. +
  208063. + return panel;
  208064. +}
  208065. +
  208066. +#ifdef CONFIG_OF
  208067. +static int clcdfb_dt_init(struct clcd_fb *fb)
  208068. +{
  208069. + int err = 0;
  208070. + struct device_node *node;
  208071. + const char *mode;
  208072. + dma_addr_t dma;
  208073. + u32 use_dma;
  208074. + const __be32 *prop;
  208075. + int len, na, ns;
  208076. + phys_addr_t fb_base, fb_size;
  208077. +
  208078. + node = fb->dev->dev.of_node;
  208079. + if (!node)
  208080. + return -ENODEV;
  208081. +
  208082. + na = of_n_addr_cells(node);
  208083. + ns = of_n_size_cells(node);
  208084. +
  208085. + if (def_mode && strlen(def_mode) > 0) {
  208086. + fb->panel = clcdfb_get_panel(def_mode);
  208087. + if (!fb->panel)
  208088. + printk(KERN_ERR "CLCD: invalid mode specified on the command line (%s)\n", def_mode);
  208089. + }
  208090. +
  208091. + if (!fb->panel) {
  208092. + if (WARN_ON(of_property_read_string(node, "mode", &mode)))
  208093. + return -ENODEV;
  208094. + fb->panel = clcdfb_get_panel(mode);
  208095. + }
  208096. +
  208097. + if (!fb->panel)
  208098. + return -EINVAL;
  208099. + fb->fb.fix.smem_len = fb->panel->mode.xres * fb->panel->mode.yres * 4;
  208100. +
  208101. + fb->board->name = "Device Tree CLCD PL111";
  208102. + fb->board->caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888;
  208103. + fb->board->check = clcdfb_check;
  208104. + fb->board->decode = clcdfb_decode;
  208105. +
  208106. + if (of_property_read_u32(node, "use_dma", &use_dma))
  208107. + use_dma = 0;
  208108. +
  208109. + if (use_dma) {
  208110. + fb->fb.screen_base = clcdfb_dma_alloc(&fb->dev->dev,
  208111. + fb->fb.fix.smem_len,
  208112. + &dma, GFP_KERNEL);
  208113. + if (!fb->fb.screen_base) {
  208114. + pr_err("CLCD: unable to map framebuffer\n");
  208115. + return -ENOMEM;
  208116. + }
  208117. +
  208118. + fb->fb.fix.smem_start = dma;
  208119. + fb->board->mmap = clcdfb_mmap_dma;
  208120. + fb->board->remove = clcdfb_remove_dma;
  208121. + } else {
  208122. + prop = of_get_property(node, "framebuffer", &len);
  208123. + if (WARN_ON(!prop || len < (na + ns) * sizeof(*prop)))
  208124. + return -EINVAL;
  208125. +
  208126. + fb_base = of_read_number(prop, na);
  208127. + fb_size = of_read_number(prop + na, ns);
  208128. +
  208129. + fb->fb.fix.smem_start = fb_base;
  208130. + fb->fb.screen_base = ioremap_wc(fb_base, fb_size);
  208131. + fb->board->mmap = clcdfb_mmap_io;
  208132. + fb->board->remove = clcdfb_remove_io;
  208133. + }
  208134. +
  208135. + return err;
  208136. +}
  208137. +#endif /* CONFIG_OF */
  208138. +
  208139. static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
  208140. {
  208141. struct clcd_board *board = dev_get_platdata(&dev->dev);
  208142. struct clcd_fb *fb;
  208143. int ret;
  208144. - if (!board)
  208145. - return -EINVAL;
  208146. + if (!board) {
  208147. +#ifdef CONFIG_OF
  208148. + if (dev->dev.of_node) {
  208149. + board = kzalloc(sizeof(struct clcd_board), GFP_KERNEL);
  208150. + if (!board)
  208151. + return -ENOMEM;
  208152. + board->setup = clcdfb_dt_init;
  208153. + } else
  208154. +#endif
  208155. + return -EINVAL;
  208156. + }
  208157. ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
  208158. if (ret)
  208159. diff -Nur linux-3.14.15/drivers/video/arm-hdlcd.c linux-linaro-stable-mx6/drivers/video/arm-hdlcd.c
  208160. --- linux-3.14.15/drivers/video/arm-hdlcd.c 1970-01-01 01:00:00.000000000 +0100
  208161. +++ linux-linaro-stable-mx6/drivers/video/arm-hdlcd.c 2014-08-20 19:23:57.474862558 +0200
  208162. @@ -0,0 +1,844 @@
  208163. +/*
  208164. + * drivers/video/arm-hdlcd.c
  208165. + *
  208166. + * Copyright (C) 2011 ARM Limited
  208167. + *
  208168. + * This file is subject to the terms and conditions of the GNU General Public
  208169. + * License. See the file COPYING in the main directory of this archive
  208170. + * for more details.
  208171. + *
  208172. + * ARM HDLCD Controller
  208173. + */
  208174. +
  208175. +#include <linux/module.h>
  208176. +#include <linux/kernel.h>
  208177. +#include <linux/errno.h>
  208178. +#include <linux/string.h>
  208179. +#include <linux/ctype.h>
  208180. +#include <linux/mm.h>
  208181. +#include <linux/delay.h>
  208182. +#include <linux/of.h>
  208183. +#include <linux/fb.h>
  208184. +#include <linux/clk.h>
  208185. +#include <linux/init.h>
  208186. +#include <linux/interrupt.h>
  208187. +#include <linux/ioport.h>
  208188. +#include <linux/dma-mapping.h>
  208189. +#include <linux/platform_device.h>
  208190. +#include <linux/memblock.h>
  208191. +#include <linux/arm-hdlcd.h>
  208192. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  208193. +#include <linux/proc_fs.h>
  208194. +#include <linux/seq_file.h>
  208195. +#endif
  208196. +
  208197. +#include "edid.h"
  208198. +
  208199. +#ifdef CONFIG_SERIAL_AMBA_PCU_UART
  208200. +int get_edid(u8 *msgbuf);
  208201. +#else
  208202. +#endif
  208203. +
  208204. +#define to_hdlcd_device(info) container_of(info, struct hdlcd_device, fb)
  208205. +
  208206. +static struct of_device_id hdlcd_of_matches[] = {
  208207. + { .compatible = "arm,hdlcd" },
  208208. + {},
  208209. +};
  208210. +
  208211. +/* Framebuffer size. */
  208212. +static unsigned long framebuffer_size;
  208213. +
  208214. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  208215. +static unsigned long buffer_underrun_events;
  208216. +static DEFINE_SPINLOCK(hdlcd_underrun_lock);
  208217. +
  208218. +static void hdlcd_underrun_set(unsigned long val)
  208219. +{
  208220. + spin_lock(&hdlcd_underrun_lock);
  208221. + buffer_underrun_events = val;
  208222. + spin_unlock(&hdlcd_underrun_lock);
  208223. +}
  208224. +
  208225. +static unsigned long hdlcd_underrun_get(void)
  208226. +{
  208227. + unsigned long val;
  208228. + spin_lock(&hdlcd_underrun_lock);
  208229. + val = buffer_underrun_events;
  208230. + spin_unlock(&hdlcd_underrun_lock);
  208231. + return val;
  208232. +}
  208233. +
  208234. +#ifdef CONFIG_PROC_FS
  208235. +static int hdlcd_underrun_show(struct seq_file *m, void *v)
  208236. +{
  208237. + unsigned char underrun_string[32];
  208238. + snprintf(underrun_string, 32, "%lu\n", hdlcd_underrun_get());
  208239. + seq_puts(m, underrun_string);
  208240. + return 0;
  208241. +}
  208242. +
  208243. +static int proc_hdlcd_underrun_open(struct inode *inode, struct file *file)
  208244. +{
  208245. + return single_open(file, hdlcd_underrun_show, NULL);
  208246. +}
  208247. +
  208248. +static const struct file_operations proc_hdlcd_underrun_operations = {
  208249. + .open = proc_hdlcd_underrun_open,
  208250. + .read = seq_read,
  208251. + .llseek = seq_lseek,
  208252. + .release = single_release,
  208253. +};
  208254. +
  208255. +static int hdlcd_underrun_init(void)
  208256. +{
  208257. + hdlcd_underrun_set(0);
  208258. + proc_create("hdlcd_underrun", 0, NULL, &proc_hdlcd_underrun_operations);
  208259. + return 0;
  208260. +}
  208261. +static void hdlcd_underrun_close(void)
  208262. +{
  208263. + remove_proc_entry("hdlcd_underrun", NULL);
  208264. +}
  208265. +#else
  208266. +static int hdlcd_underrun_init(void) { return 0; }
  208267. +static void hdlcd_underrun_close(void) { }
  208268. +#endif
  208269. +#endif
  208270. +
  208271. +static char *fb_mode = "1680x1050-32@60\0\0\0\0\0";
  208272. +
  208273. +static struct fb_var_screeninfo cached_var_screeninfo;
  208274. +
  208275. +static struct fb_videomode hdlcd_default_mode = {
  208276. + .refresh = 60,
  208277. + .xres = 1680,
  208278. + .yres = 1050,
  208279. + .pixclock = 8403,
  208280. + .left_margin = 80,
  208281. + .right_margin = 48,
  208282. + .upper_margin = 21,
  208283. + .lower_margin = 3,
  208284. + .hsync_len = 32,
  208285. + .vsync_len = 6,
  208286. + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  208287. + .vmode = FB_VMODE_NONINTERLACED
  208288. +};
  208289. +
  208290. +static inline void hdlcd_enable(struct hdlcd_device *hdlcd)
  208291. +{
  208292. + dev_dbg(hdlcd->dev, "HDLCD: output enabled\n");
  208293. + writel(1, hdlcd->base + HDLCD_REG_COMMAND);
  208294. +}
  208295. +
  208296. +static inline void hdlcd_disable(struct hdlcd_device *hdlcd)
  208297. +{
  208298. + dev_dbg(hdlcd->dev, "HDLCD: output disabled\n");
  208299. + writel(0, hdlcd->base + HDLCD_REG_COMMAND);
  208300. +}
  208301. +
  208302. +static int hdlcd_set_bitfields(struct hdlcd_device *hdlcd,
  208303. + struct fb_var_screeninfo *var)
  208304. +{
  208305. + int ret = 0;
  208306. +
  208307. + memset(&var->transp, 0, sizeof(var->transp));
  208308. + var->red.msb_right = 0;
  208309. + var->green.msb_right = 0;
  208310. + var->blue.msb_right = 0;
  208311. + var->blue.offset = 0;
  208312. +
  208313. + switch (var->bits_per_pixel) {
  208314. + case 8:
  208315. + /* pseudocolor */
  208316. + var->red.length = 8;
  208317. + var->green.length = 8;
  208318. + var->blue.length = 8;
  208319. + break;
  208320. + case 16:
  208321. + /* 565 format */
  208322. + var->red.length = 5;
  208323. + var->green.length = 6;
  208324. + var->blue.length = 5;
  208325. + break;
  208326. + case 32:
  208327. + var->transp.length = 8;
  208328. + case 24:
  208329. + var->red.length = 8;
  208330. + var->green.length = 8;
  208331. + var->blue.length = 8;
  208332. + break;
  208333. + default:
  208334. + ret = -EINVAL;
  208335. + break;
  208336. + }
  208337. +
  208338. + if (!ret) {
  208339. + if(var->bits_per_pixel != 32)
  208340. + {
  208341. + var->green.offset = var->blue.length;
  208342. + var->red.offset = var->green.offset + var->green.length;
  208343. + }
  208344. + else
  208345. + {
  208346. + /* Previously, the byte ordering for 32-bit color was
  208347. + * (msb)<alpha><red><green><blue>(lsb)
  208348. + * but this does not match what android expects and
  208349. + * the colors are odd. Instead, use
  208350. + * <alpha><blue><green><red>
  208351. + * Since we tell fb what we are doing, console
  208352. + * , X and directfb access should work fine.
  208353. + */
  208354. + var->green.offset = var->red.length;
  208355. + var->blue.offset = var->green.offset + var->green.length;
  208356. + var->transp.offset = var->blue.offset + var->blue.length;
  208357. + }
  208358. + }
  208359. +
  208360. + return ret;
  208361. +}
  208362. +
  208363. +static int hdlcd_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  208364. +{
  208365. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  208366. + int bytes_per_pixel = var->bits_per_pixel / 8;
  208367. +
  208368. +#ifdef HDLCD_NO_VIRTUAL_SCREEN
  208369. + var->yres_virtual = var->yres;
  208370. +#else
  208371. + var->yres_virtual = 2 * var->yres;
  208372. +#endif
  208373. +
  208374. + if ((var->xres_virtual * bytes_per_pixel * var->yres_virtual) > hdlcd->fb.fix.smem_len)
  208375. + return -ENOMEM;
  208376. +
  208377. + if (var->xres > HDLCD_MAX_XRES || var->yres > HDLCD_MAX_YRES)
  208378. + return -EINVAL;
  208379. +
  208380. + /* make sure the bitfields are set appropriately */
  208381. + return hdlcd_set_bitfields(hdlcd, var);
  208382. +}
  208383. +
  208384. +/* prototype */
  208385. +static int hdlcd_pan_display(struct fb_var_screeninfo *var,
  208386. + struct fb_info *info);
  208387. +
  208388. +#define WRITE_HDLCD_REG(reg, value) writel((value), hdlcd->base + (reg))
  208389. +#define READ_HDLCD_REG(reg) readl(hdlcd->base + (reg))
  208390. +
  208391. +static int hdlcd_set_par(struct fb_info *info)
  208392. +{
  208393. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  208394. + int bytes_per_pixel = hdlcd->fb.var.bits_per_pixel / 8;
  208395. + int polarities;
  208396. + int old_yoffset;
  208397. +
  208398. + /* check for shortcuts */
  208399. + old_yoffset = cached_var_screeninfo.yoffset;
  208400. + cached_var_screeninfo.yoffset = info->var.yoffset;
  208401. + if (!memcmp(&info->var, &cached_var_screeninfo,
  208402. + sizeof(struct fb_var_screeninfo))) {
  208403. + if(old_yoffset != info->var.yoffset) {
  208404. + /* we only changed yoffset, and we already
  208405. + * already recorded it a couple lines up
  208406. + */
  208407. + hdlcd_pan_display(&info->var, info);
  208408. + }
  208409. + /* or no change */
  208410. + return 0;
  208411. + }
  208412. +
  208413. + hdlcd->fb.fix.line_length = hdlcd->fb.var.xres * bytes_per_pixel;
  208414. +
  208415. + if (hdlcd->fb.var.bits_per_pixel >= 16)
  208416. + hdlcd->fb.fix.visual = FB_VISUAL_TRUECOLOR;
  208417. + else
  208418. + hdlcd->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
  208419. +
  208420. + memcpy(&cached_var_screeninfo, &info->var, sizeof(struct fb_var_screeninfo));
  208421. +
  208422. + polarities = HDLCD_POLARITY_DATAEN |
  208423. +#ifndef CONFIG_ARCH_TUSCAN
  208424. + HDLCD_POLARITY_PIXELCLK |
  208425. +#endif
  208426. + HDLCD_POLARITY_DATA;
  208427. + polarities |= (hdlcd->fb.var.sync & FB_SYNC_HOR_HIGH_ACT) ? HDLCD_POLARITY_HSYNC : 0;
  208428. + polarities |= (hdlcd->fb.var.sync & FB_SYNC_VERT_HIGH_ACT) ? HDLCD_POLARITY_VSYNC : 0;
  208429. +
  208430. + hdlcd_disable(hdlcd);
  208431. +
  208432. + WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_LENGTH, hdlcd->fb.var.xres * bytes_per_pixel);
  208433. + WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_PITCH, hdlcd->fb.var.xres * bytes_per_pixel);
  208434. + WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_COUNT, hdlcd->fb.var.yres - 1);
  208435. + WRITE_HDLCD_REG(HDLCD_REG_V_SYNC, hdlcd->fb.var.vsync_len - 1);
  208436. + WRITE_HDLCD_REG(HDLCD_REG_V_BACK_PORCH, hdlcd->fb.var.upper_margin - 1);
  208437. + WRITE_HDLCD_REG(HDLCD_REG_V_DATA, hdlcd->fb.var.yres - 1);
  208438. + WRITE_HDLCD_REG(HDLCD_REG_V_FRONT_PORCH, hdlcd->fb.var.lower_margin - 1);
  208439. + WRITE_HDLCD_REG(HDLCD_REG_H_SYNC, hdlcd->fb.var.hsync_len - 1);
  208440. + WRITE_HDLCD_REG(HDLCD_REG_H_BACK_PORCH, hdlcd->fb.var.left_margin - 1);
  208441. + WRITE_HDLCD_REG(HDLCD_REG_H_DATA, hdlcd->fb.var.xres - 1);
  208442. + WRITE_HDLCD_REG(HDLCD_REG_H_FRONT_PORCH, hdlcd->fb.var.right_margin - 1);
  208443. + WRITE_HDLCD_REG(HDLCD_REG_POLARITIES, polarities);
  208444. + WRITE_HDLCD_REG(HDLCD_REG_PIXEL_FORMAT, (bytes_per_pixel - 1) << 3);
  208445. +#ifdef HDLCD_RED_DEFAULT_COLOUR
  208446. + WRITE_HDLCD_REG(HDLCD_REG_RED_SELECT, (0x00ff0000 | (hdlcd->fb.var.red.length & 0xf) << 8) \
  208447. + | hdlcd->fb.var.red.offset);
  208448. +#else
  208449. + WRITE_HDLCD_REG(HDLCD_REG_RED_SELECT, ((hdlcd->fb.var.red.length & 0xf) << 8) | hdlcd->fb.var.red.offset);
  208450. +#endif
  208451. + WRITE_HDLCD_REG(HDLCD_REG_GREEN_SELECT, ((hdlcd->fb.var.green.length & 0xf) << 8) | hdlcd->fb.var.green.offset);
  208452. + WRITE_HDLCD_REG(HDLCD_REG_BLUE_SELECT, ((hdlcd->fb.var.blue.length & 0xf) << 8) | hdlcd->fb.var.blue.offset);
  208453. +
  208454. + clk_set_rate(hdlcd->clk, (1000000000 / hdlcd->fb.var.pixclock) * 1000);
  208455. + clk_enable(hdlcd->clk);
  208456. +
  208457. + hdlcd_enable(hdlcd);
  208458. +
  208459. + return 0;
  208460. +}
  208461. +
  208462. +static int hdlcd_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
  208463. + unsigned int blue, unsigned int transp, struct fb_info *info)
  208464. +{
  208465. + if (regno < 16) {
  208466. + u32 *pal = info->pseudo_palette;
  208467. +
  208468. + pal[regno] = ((red >> 8) << info->var.red.offset) |
  208469. + ((green >> 8) << info->var.green.offset) |
  208470. + ((blue >> 8) << info->var.blue.offset);
  208471. + }
  208472. +
  208473. + return 0;
  208474. +}
  208475. +
  208476. +static irqreturn_t hdlcd_irq(int irq, void *data)
  208477. +{
  208478. + struct hdlcd_device *hdlcd = data;
  208479. + unsigned long irq_mask, irq_status;
  208480. +
  208481. + irq_mask = READ_HDLCD_REG(HDLCD_REG_INT_MASK);
  208482. + irq_status = READ_HDLCD_REG(HDLCD_REG_INT_STATUS);
  208483. +
  208484. + /* acknowledge interrupt(s) */
  208485. + WRITE_HDLCD_REG(HDLCD_REG_INT_CLEAR, irq_status);
  208486. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  208487. + if (irq_status & HDLCD_INTERRUPT_UNDERRUN) {
  208488. + /* increment the count */
  208489. + hdlcd_underrun_set(hdlcd_underrun_get() + 1);
  208490. + }
  208491. +#endif
  208492. + if (irq_status & HDLCD_INTERRUPT_VSYNC) {
  208493. + /* disable future VSYNC interrupts */
  208494. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, irq_mask & ~HDLCD_INTERRUPT_VSYNC);
  208495. +
  208496. + complete(&hdlcd->vsync_completion);
  208497. + }
  208498. +
  208499. + return IRQ_HANDLED;
  208500. +}
  208501. +
  208502. +static int hdlcd_wait_for_vsync(struct fb_info *info)
  208503. +{
  208504. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  208505. + unsigned long irq_mask;
  208506. + int err;
  208507. +
  208508. + /* enable VSYNC interrupt */
  208509. + irq_mask = READ_HDLCD_REG(HDLCD_REG_INT_MASK);
  208510. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, irq_mask | HDLCD_INTERRUPT_VSYNC);
  208511. +
  208512. + err = wait_for_completion_interruptible_timeout(&hdlcd->vsync_completion,
  208513. + msecs_to_jiffies(100));
  208514. +
  208515. + if (!err)
  208516. + return -ETIMEDOUT;
  208517. +
  208518. + return 0;
  208519. +}
  208520. +
  208521. +static int hdlcd_blank(int blank_mode, struct fb_info *info)
  208522. +{
  208523. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  208524. +
  208525. + switch (blank_mode) {
  208526. + case FB_BLANK_POWERDOWN:
  208527. + clk_disable(hdlcd->clk);
  208528. + case FB_BLANK_NORMAL:
  208529. + hdlcd_disable(hdlcd);
  208530. + break;
  208531. + case FB_BLANK_UNBLANK:
  208532. + clk_enable(hdlcd->clk);
  208533. + hdlcd_enable(hdlcd);
  208534. + break;
  208535. + case FB_BLANK_VSYNC_SUSPEND:
  208536. + case FB_BLANK_HSYNC_SUSPEND:
  208537. + default:
  208538. + return 1;
  208539. + }
  208540. +
  208541. + return 0;
  208542. +}
  208543. +
  208544. +static void hdlcd_mmap_open(struct vm_area_struct *vma)
  208545. +{
  208546. +}
  208547. +
  208548. +static void hdlcd_mmap_close(struct vm_area_struct *vma)
  208549. +{
  208550. +}
  208551. +
  208552. +static struct vm_operations_struct hdlcd_mmap_ops = {
  208553. + .open = hdlcd_mmap_open,
  208554. + .close = hdlcd_mmap_close,
  208555. +};
  208556. +
  208557. +static int hdlcd_mmap(struct fb_info *info, struct vm_area_struct *vma)
  208558. +{
  208559. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  208560. + unsigned long off;
  208561. + unsigned long start;
  208562. + unsigned long len = hdlcd->fb.fix.smem_len;
  208563. +
  208564. + if (vma->vm_end - vma->vm_start == 0)
  208565. + return 0;
  208566. + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
  208567. + return -EINVAL;
  208568. +
  208569. + off = vma->vm_pgoff << PAGE_SHIFT;
  208570. + if ((off >= len) || (vma->vm_end - vma->vm_start + off) > len)
  208571. + return -EINVAL;
  208572. +
  208573. + start = hdlcd->fb.fix.smem_start;
  208574. + off += start;
  208575. +
  208576. + vma->vm_pgoff = off >> PAGE_SHIFT;
  208577. + vma->vm_flags |= VM_IO;
  208578. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  208579. + vma->vm_ops = &hdlcd_mmap_ops;
  208580. + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
  208581. + vma->vm_end - vma->vm_start,
  208582. + vma->vm_page_prot))
  208583. + return -EAGAIN;
  208584. +
  208585. + return 0;
  208586. +}
  208587. +
  208588. +static int hdlcd_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
  208589. +{
  208590. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  208591. +
  208592. + hdlcd->fb.var.yoffset = var->yoffset;
  208593. + WRITE_HDLCD_REG(HDLCD_REG_FB_BASE, hdlcd->fb.fix.smem_start +
  208594. + (var->yoffset * hdlcd->fb.fix.line_length));
  208595. +
  208596. + hdlcd_wait_for_vsync(info);
  208597. +
  208598. + return 0;
  208599. +}
  208600. +
  208601. +static int hdlcd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  208602. +{
  208603. + int err;
  208604. +
  208605. + switch (cmd) {
  208606. + case FBIO_WAITFORVSYNC:
  208607. + err = hdlcd_wait_for_vsync(info);
  208608. + break;
  208609. + default:
  208610. + err = -ENOIOCTLCMD;
  208611. + break;
  208612. + }
  208613. +
  208614. + return err;
  208615. +}
  208616. +
  208617. +static struct fb_ops hdlcd_ops = {
  208618. + .owner = THIS_MODULE,
  208619. + .fb_check_var = hdlcd_check_var,
  208620. + .fb_set_par = hdlcd_set_par,
  208621. + .fb_setcolreg = hdlcd_setcolreg,
  208622. + .fb_blank = hdlcd_blank,
  208623. + .fb_fillrect = cfb_fillrect,
  208624. + .fb_copyarea = cfb_copyarea,
  208625. + .fb_imageblit = cfb_imageblit,
  208626. + .fb_mmap = hdlcd_mmap,
  208627. + .fb_pan_display = hdlcd_pan_display,
  208628. + .fb_ioctl = hdlcd_ioctl,
  208629. + .fb_compat_ioctl = hdlcd_ioctl
  208630. +};
  208631. +
  208632. +static int hdlcd_setup(struct hdlcd_device *hdlcd)
  208633. +{
  208634. + u32 version;
  208635. + int err = -EFAULT;
  208636. +
  208637. + hdlcd->fb.device = hdlcd->dev;
  208638. +
  208639. + hdlcd->clk = clk_get(hdlcd->dev, NULL);
  208640. + if (IS_ERR(hdlcd->clk)) {
  208641. + dev_err(hdlcd->dev, "HDLCD: unable to find clock data\n");
  208642. + return PTR_ERR(hdlcd->clk);
  208643. + }
  208644. +
  208645. + err = clk_prepare(hdlcd->clk);
  208646. + if (err)
  208647. + goto clk_prepare_err;
  208648. +
  208649. + hdlcd->base = ioremap_nocache(hdlcd->fb.fix.mmio_start, hdlcd->fb.fix.mmio_len);
  208650. + if (!hdlcd->base) {
  208651. + dev_err(hdlcd->dev, "HDLCD: unable to map registers\n");
  208652. + goto remap_err;
  208653. + }
  208654. +
  208655. + hdlcd->fb.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
  208656. + if (!hdlcd->fb.pseudo_palette) {
  208657. + dev_err(hdlcd->dev, "HDLCD: unable to allocate pseudo_palette memory\n");
  208658. + err = -ENOMEM;
  208659. + goto kmalloc_err;
  208660. + }
  208661. +
  208662. + version = readl(hdlcd->base + HDLCD_REG_VERSION);
  208663. + if ((version & HDLCD_PRODUCT_MASK) != HDLCD_PRODUCT_ID) {
  208664. + dev_err(hdlcd->dev, "HDLCD: unknown product id: 0x%x\n", version);
  208665. + err = -EINVAL;
  208666. + goto kmalloc_err;
  208667. + }
  208668. + dev_info(hdlcd->dev, "HDLCD: found ARM HDLCD version r%dp%d\n",
  208669. + (version & HDLCD_VERSION_MAJOR_MASK) >> 8,
  208670. + version & HDLCD_VERSION_MINOR_MASK);
  208671. +
  208672. + strcpy(hdlcd->fb.fix.id, "hdlcd");
  208673. + hdlcd->fb.fbops = &hdlcd_ops;
  208674. + hdlcd->fb.flags = FBINFO_FLAG_DEFAULT/* | FBINFO_VIRTFB*/;
  208675. +
  208676. + hdlcd->fb.fix.type = FB_TYPE_PACKED_PIXELS;
  208677. + hdlcd->fb.fix.type_aux = 0;
  208678. + hdlcd->fb.fix.xpanstep = 0;
  208679. + hdlcd->fb.fix.ypanstep = 1;
  208680. + hdlcd->fb.fix.ywrapstep = 0;
  208681. + hdlcd->fb.fix.accel = FB_ACCEL_NONE;
  208682. +
  208683. + hdlcd->fb.var.nonstd = 0;
  208684. + hdlcd->fb.var.activate = FB_ACTIVATE_NOW;
  208685. + hdlcd->fb.var.height = -1;
  208686. + hdlcd->fb.var.width = -1;
  208687. + hdlcd->fb.var.accel_flags = 0;
  208688. +
  208689. + init_completion(&hdlcd->vsync_completion);
  208690. +
  208691. + if (hdlcd->edid) {
  208692. + /* build modedb from EDID */
  208693. + fb_edid_to_monspecs(hdlcd->edid, &hdlcd->fb.monspecs);
  208694. + fb_videomode_to_modelist(hdlcd->fb.monspecs.modedb,
  208695. + hdlcd->fb.monspecs.modedb_len,
  208696. + &hdlcd->fb.modelist);
  208697. + fb_find_mode(&hdlcd->fb.var, &hdlcd->fb, fb_mode,
  208698. + hdlcd->fb.monspecs.modedb,
  208699. + hdlcd->fb.monspecs.modedb_len,
  208700. + &hdlcd_default_mode, 32);
  208701. + } else {
  208702. + hdlcd->fb.monspecs.hfmin = 0;
  208703. + hdlcd->fb.monspecs.hfmax = 100000;
  208704. + hdlcd->fb.monspecs.vfmin = 0;
  208705. + hdlcd->fb.monspecs.vfmax = 400;
  208706. + hdlcd->fb.monspecs.dclkmin = 1000000;
  208707. + hdlcd->fb.monspecs.dclkmax = 100000000;
  208708. + fb_find_mode(&hdlcd->fb.var, &hdlcd->fb, fb_mode, NULL, 0, &hdlcd_default_mode, 32);
  208709. + }
  208710. +
  208711. + dev_info(hdlcd->dev, "using %dx%d-%d@%d mode\n", hdlcd->fb.var.xres,
  208712. + hdlcd->fb.var.yres, hdlcd->fb.var.bits_per_pixel,
  208713. + hdlcd->fb.mode ? hdlcd->fb.mode->refresh : 60);
  208714. + hdlcd->fb.var.xres_virtual = hdlcd->fb.var.xres;
  208715. +#ifdef HDLCD_NO_VIRTUAL_SCREEN
  208716. + hdlcd->fb.var.yres_virtual = hdlcd->fb.var.yres;
  208717. +#else
  208718. + hdlcd->fb.var.yres_virtual = hdlcd->fb.var.yres * 2;
  208719. +#endif
  208720. +
  208721. + /* initialise and set the palette */
  208722. + if (fb_alloc_cmap(&hdlcd->fb.cmap, NR_PALETTE, 0)) {
  208723. + dev_err(hdlcd->dev, "failed to allocate cmap memory\n");
  208724. + err = -ENOMEM;
  208725. + goto setup_err;
  208726. + }
  208727. + fb_set_cmap(&hdlcd->fb.cmap, &hdlcd->fb);
  208728. +
  208729. + /* Allow max number of outstanding requests with the largest beat burst */
  208730. + WRITE_HDLCD_REG(HDLCD_REG_BUS_OPTIONS, HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);
  208731. + /* Set the framebuffer base to start of allocated memory */
  208732. + WRITE_HDLCD_REG(HDLCD_REG_FB_BASE, hdlcd->fb.fix.smem_start);
  208733. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  208734. + /* turn on underrun interrupt for counting */
  208735. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, HDLCD_INTERRUPT_UNDERRUN);
  208736. +#else
  208737. + /* Ensure interrupts are disabled */
  208738. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, 0);
  208739. +#endif
  208740. + fb_set_var(&hdlcd->fb, &hdlcd->fb.var);
  208741. +
  208742. + if (!register_framebuffer(&hdlcd->fb)) {
  208743. + return 0;
  208744. + }
  208745. +
  208746. + dev_err(hdlcd->dev, "HDLCD: cannot register framebuffer\n");
  208747. +
  208748. + fb_dealloc_cmap(&hdlcd->fb.cmap);
  208749. +setup_err:
  208750. + iounmap(hdlcd->base);
  208751. +kmalloc_err:
  208752. + kfree(hdlcd->fb.pseudo_palette);
  208753. +remap_err:
  208754. + clk_unprepare(hdlcd->clk);
  208755. +clk_prepare_err:
  208756. + clk_put(hdlcd->clk);
  208757. + return err;
  208758. +}
  208759. +
  208760. +static inline unsigned char atohex(u8 data)
  208761. +{
  208762. + if (!isxdigit(data))
  208763. + return 0;
  208764. + /* truncate the upper nibble and add 9 to non-digit values */
  208765. + return (data > 0x39) ? ((data & 0xf) + 9) : (data & 0xf);
  208766. +}
  208767. +
  208768. +/* EDID data is passed from devicetree in a literal string that can contain spaces and
  208769. + the hexadecimal dump of the data */
  208770. +static int parse_edid_data(struct hdlcd_device *hdlcd, const u8 *edid_data, int data_len)
  208771. +{
  208772. + int i, j;
  208773. +
  208774. + if (!edid_data)
  208775. + return -EINVAL;
  208776. +
  208777. + hdlcd->edid = kzalloc(EDID_LENGTH, GFP_KERNEL);
  208778. + if (!hdlcd->edid)
  208779. + return -ENOMEM;
  208780. +
  208781. + for (i = 0, j = 0; i < data_len; i++) {
  208782. + if (isspace(edid_data[i]))
  208783. + continue;
  208784. + hdlcd->edid[j++] = atohex(edid_data[i]);
  208785. + if (j >= EDID_LENGTH)
  208786. + break;
  208787. + }
  208788. +
  208789. + if (j < EDID_LENGTH) {
  208790. + kfree(hdlcd->edid);
  208791. + hdlcd->edid = NULL;
  208792. + return -EINVAL;
  208793. + }
  208794. +
  208795. + return 0;
  208796. +}
  208797. +
  208798. +static int hdlcd_probe(struct platform_device *pdev)
  208799. +{
  208800. + int err = 0, i;
  208801. + struct hdlcd_device *hdlcd;
  208802. + struct resource *mem;
  208803. +#ifdef CONFIG_OF
  208804. + struct device_node *of_node;
  208805. +#endif
  208806. +
  208807. + memset(&cached_var_screeninfo, 0, sizeof(struct fb_var_screeninfo));
  208808. +
  208809. + dev_dbg(&pdev->dev, "HDLCD: probing\n");
  208810. +
  208811. + hdlcd = kzalloc(sizeof(*hdlcd), GFP_KERNEL);
  208812. + if (!hdlcd)
  208813. + return -ENOMEM;
  208814. +
  208815. +#ifdef CONFIG_OF
  208816. + of_node = pdev->dev.of_node;
  208817. + if (of_node) {
  208818. + int len;
  208819. + const u8 *edid;
  208820. + const __be32 *prop = of_get_property(of_node, "mode", &len);
  208821. + if (prop)
  208822. + strncpy(fb_mode, (char *)prop, len);
  208823. + prop = of_get_property(of_node, "framebuffer", &len);
  208824. + if (prop) {
  208825. + hdlcd->fb.fix.smem_start = of_read_ulong(prop,
  208826. + of_n_addr_cells(of_node));
  208827. + prop += of_n_addr_cells(of_node);
  208828. + framebuffer_size = of_read_ulong(prop,
  208829. + of_n_size_cells(of_node));
  208830. + if (framebuffer_size > HDLCD_MAX_FRAMEBUFFER_SIZE)
  208831. + framebuffer_size = HDLCD_MAX_FRAMEBUFFER_SIZE;
  208832. + dev_dbg(&pdev->dev, "HDLCD: phys_addr = 0x%lx, size = 0x%lx\n",
  208833. + hdlcd->fb.fix.smem_start, framebuffer_size);
  208834. + }
  208835. + edid = of_get_property(of_node, "edid", &len);
  208836. + if (edid) {
  208837. + err = parse_edid_data(hdlcd, edid, len);
  208838. +#ifdef CONFIG_SERIAL_AMBA_PCU_UART
  208839. + } else {
  208840. + /* ask the firmware to fetch the EDID */
  208841. + dev_dbg(&pdev->dev, "HDLCD: Requesting EDID data\n");
  208842. + hdlcd->edid = kzalloc(EDID_LENGTH, GFP_KERNEL);
  208843. + if (!hdlcd->edid)
  208844. + return -ENOMEM;
  208845. + err = get_edid(hdlcd->edid);
  208846. +#endif /* CONFIG_SERIAL_AMBA_PCU_UART */
  208847. + }
  208848. + if (err)
  208849. + dev_info(&pdev->dev, "HDLCD: Failed to parse EDID data\n");
  208850. + }
  208851. +#endif /* CONFIG_OF */
  208852. +
  208853. + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  208854. + if (!mem) {
  208855. + dev_err(&pdev->dev, "HDLCD: cannot get platform resources\n");
  208856. + err = -EINVAL;
  208857. + goto resource_err;
  208858. + }
  208859. +
  208860. + i = platform_get_irq(pdev, 0);
  208861. + if (i < 0) {
  208862. + dev_err(&pdev->dev, "HDLCD: no irq defined for vsync\n");
  208863. + err = -ENOENT;
  208864. + goto resource_err;
  208865. + } else {
  208866. + err = request_irq(i, hdlcd_irq, 0, dev_name(&pdev->dev), hdlcd);
  208867. + if (err) {
  208868. + dev_err(&pdev->dev, "HDLCD: unable to request irq\n");
  208869. + goto resource_err;
  208870. + }
  208871. + hdlcd->irq = i;
  208872. + }
  208873. +
  208874. + if (!request_mem_region(mem->start, resource_size(mem), dev_name(&pdev->dev))) {
  208875. + err = -ENXIO;
  208876. + goto request_err;
  208877. + }
  208878. +
  208879. + if (!hdlcd->fb.fix.smem_start) {
  208880. + dev_err(&pdev->dev, "platform did not allocate frame buffer memory\n");
  208881. + err = -ENOMEM;
  208882. + goto memalloc_err;
  208883. + }
  208884. + hdlcd->fb.screen_base = ioremap_wc(hdlcd->fb.fix.smem_start, framebuffer_size);
  208885. + if (!hdlcd->fb.screen_base) {
  208886. + dev_err(&pdev->dev, "unable to ioremap framebuffer\n");
  208887. + err = -ENOMEM;
  208888. + goto probe_err;
  208889. + }
  208890. +
  208891. + hdlcd->fb.screen_size = framebuffer_size;
  208892. + hdlcd->fb.fix.smem_len = framebuffer_size;
  208893. + hdlcd->fb.fix.mmio_start = mem->start;
  208894. + hdlcd->fb.fix.mmio_len = resource_size(mem);
  208895. +
  208896. + /* Clear the framebuffer */
  208897. + memset(hdlcd->fb.screen_base, 0, framebuffer_size);
  208898. +
  208899. + hdlcd->dev = &pdev->dev;
  208900. +
  208901. + dev_dbg(&pdev->dev, "HDLCD: framebuffer virt base %p, phys base 0x%lX\n",
  208902. + hdlcd->fb.screen_base, (unsigned long)hdlcd->fb.fix.smem_start);
  208903. +
  208904. + err = hdlcd_setup(hdlcd);
  208905. +
  208906. + if (err)
  208907. + goto probe_err;
  208908. +
  208909. + platform_set_drvdata(pdev, hdlcd);
  208910. + return 0;
  208911. +
  208912. +probe_err:
  208913. + iounmap(hdlcd->fb.screen_base);
  208914. + memblock_free(hdlcd->fb.fix.smem_start, hdlcd->fb.fix.smem_start);
  208915. +
  208916. +memalloc_err:
  208917. + release_mem_region(mem->start, resource_size(mem));
  208918. +
  208919. +request_err:
  208920. + free_irq(hdlcd->irq, hdlcd);
  208921. +
  208922. +resource_err:
  208923. + kfree(hdlcd);
  208924. +
  208925. + return err;
  208926. +}
  208927. +
  208928. +static int hdlcd_remove(struct platform_device *pdev)
  208929. +{
  208930. + struct hdlcd_device *hdlcd = platform_get_drvdata(pdev);
  208931. +
  208932. + clk_disable(hdlcd->clk);
  208933. + clk_unprepare(hdlcd->clk);
  208934. + clk_put(hdlcd->clk);
  208935. +
  208936. + /* unmap memory */
  208937. + iounmap(hdlcd->fb.screen_base);
  208938. + iounmap(hdlcd->base);
  208939. +
  208940. + /* deallocate fb memory */
  208941. + fb_dealloc_cmap(&hdlcd->fb.cmap);
  208942. + kfree(hdlcd->fb.pseudo_palette);
  208943. + memblock_free(hdlcd->fb.fix.smem_start, hdlcd->fb.fix.smem_start);
  208944. + release_mem_region(hdlcd->fb.fix.mmio_start, hdlcd->fb.fix.mmio_len);
  208945. +
  208946. + free_irq(hdlcd->irq, NULL);
  208947. + kfree(hdlcd);
  208948. +
  208949. + return 0;
  208950. +}
  208951. +
  208952. +#ifdef CONFIG_PM
  208953. +static int hdlcd_suspend(struct platform_device *pdev, pm_message_t state)
  208954. +{
  208955. + /* not implemented yet */
  208956. + return 0;
  208957. +}
  208958. +
  208959. +static int hdlcd_resume(struct platform_device *pdev)
  208960. +{
  208961. + /* not implemented yet */
  208962. + return 0;
  208963. +}
  208964. +#else
  208965. +#define hdlcd_suspend NULL
  208966. +#define hdlcd_resume NULL
  208967. +#endif
  208968. +
  208969. +static struct platform_driver hdlcd_driver = {
  208970. + .probe = hdlcd_probe,
  208971. + .remove = hdlcd_remove,
  208972. + .suspend = hdlcd_suspend,
  208973. + .resume = hdlcd_resume,
  208974. + .driver = {
  208975. + .name = "hdlcd",
  208976. + .owner = THIS_MODULE,
  208977. + .of_match_table = hdlcd_of_matches,
  208978. + },
  208979. +};
  208980. +
  208981. +static int __init hdlcd_init(void)
  208982. +{
  208983. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  208984. + int err = platform_driver_register(&hdlcd_driver);
  208985. + if (!err)
  208986. + hdlcd_underrun_init();
  208987. + return err;
  208988. +#else
  208989. + return platform_driver_register(&hdlcd_driver);
  208990. +#endif
  208991. +}
  208992. +
  208993. +void __exit hdlcd_exit(void)
  208994. +{
  208995. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  208996. + hdlcd_underrun_close();
  208997. +#endif
  208998. + platform_driver_unregister(&hdlcd_driver);
  208999. +}
  209000. +
  209001. +module_init(hdlcd_init);
  209002. +module_exit(hdlcd_exit);
  209003. +
  209004. +MODULE_AUTHOR("Liviu Dudau");
  209005. +MODULE_DESCRIPTION("ARM HDLCD core driver");
  209006. +MODULE_LICENSE("GPL v2");
  209007. diff -Nur linux-3.14.15/drivers/video/backlight/backlight.c linux-linaro-stable-mx6/drivers/video/backlight/backlight.c
  209008. --- linux-3.14.15/drivers/video/backlight/backlight.c 2014-07-31 23:51:43.000000000 +0200
  209009. +++ linux-linaro-stable-mx6/drivers/video/backlight/backlight.c 2014-08-20 19:31:49.592883875 +0200
  209010. @@ -41,6 +41,8 @@
  209011. {
  209012. struct backlight_device *bd;
  209013. struct fb_event *evdata = data;
  209014. + int node = evdata->info->node;
  209015. + int fb_blank = 0;
  209016. /* If we aren't interested in this event, skip it immediately ... */
  209017. if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK)
  209018. @@ -51,12 +53,24 @@
  209019. if (bd->ops)
  209020. if (!bd->ops->check_fb ||
  209021. bd->ops->check_fb(bd, evdata->info)) {
  209022. - bd->props.fb_blank = *(int *)evdata->data;
  209023. - if (bd->props.fb_blank == FB_BLANK_UNBLANK)
  209024. - bd->props.state &= ~BL_CORE_FBBLANK;
  209025. - else
  209026. - bd->props.state |= BL_CORE_FBBLANK;
  209027. - backlight_update_status(bd);
  209028. + fb_blank = *(int *)evdata->data;
  209029. + if (fb_blank == FB_BLANK_UNBLANK &&
  209030. + !bd->fb_bl_on[node]) {
  209031. + bd->fb_bl_on[node] = true;
  209032. + if (!bd->use_count++) {
  209033. + bd->props.state &= ~BL_CORE_FBBLANK;
  209034. + bd->props.fb_blank = FB_BLANK_UNBLANK;
  209035. + backlight_update_status(bd);
  209036. + }
  209037. + } else if (fb_blank != FB_BLANK_UNBLANK &&
  209038. + bd->fb_bl_on[node]) {
  209039. + bd->fb_bl_on[node] = false;
  209040. + if (!(--bd->use_count)) {
  209041. + bd->props.state |= BL_CORE_FBBLANK;
  209042. + bd->props.fb_blank = FB_BLANK_POWERDOWN;
  209043. + backlight_update_status(bd);
  209044. + }
  209045. + }
  209046. }
  209047. mutex_unlock(&bd->ops_lock);
  209048. return 0;
  209049. diff -Nur linux-3.14.15/drivers/video/Kconfig linux-linaro-stable-mx6/drivers/video/Kconfig
  209050. --- linux-3.14.15/drivers/video/Kconfig 2014-07-31 23:51:43.000000000 +0200
  209051. +++ linux-linaro-stable-mx6/drivers/video/Kconfig 2014-08-20 19:31:49.580883825 +0200
  209052. @@ -39,6 +39,11 @@
  209053. config HDMI
  209054. bool
  209055. +config VEXPRESS_DVI_CONTROL
  209056. + bool "Versatile Express DVI control"
  209057. + depends on FB && VEXPRESS_CONFIG
  209058. + default y
  209059. +
  209060. menuconfig FB
  209061. tristate "Support for frame buffer devices"
  209062. ---help---
  209063. @@ -327,6 +332,21 @@
  209064. here and read <file:Documentation/kbuild/modules.txt>. The module
  209065. will be called amba-clcd.
  209066. +config FB_ARMHDLCD
  209067. + tristate "ARM High Definition LCD support"
  209068. + depends on FB && ARM
  209069. + select FB_CFB_FILLRECT
  209070. + select FB_CFB_COPYAREA
  209071. + select FB_CFB_IMAGEBLIT
  209072. + help
  209073. + This framebuffer device driver is for the ARM High Definition
  209074. + Colour LCD controller.
  209075. +
  209076. + If you want to compile this as a module (=code which can be
  209077. + inserted into and removed from the running kernel), say M
  209078. + here and read <file:Documentation/kbuild/modules.txt>. The module
  209079. + will be called arm-hdlcd.
  209080. +
  209081. config FB_ACORN
  209082. bool "Acorn VIDC support"
  209083. depends on (FB = y) && ARM && ARCH_ACORN
  209084. @@ -2491,6 +2511,10 @@
  209085. source "drivers/video/mmp/Kconfig"
  209086. source "drivers/video/backlight/Kconfig"
  209087. +if ARCH_MXC
  209088. +source "drivers/video/mxc/Kconfig"
  209089. +endif
  209090. +
  209091. if VT
  209092. source "drivers/video/console/Kconfig"
  209093. endif
  209094. diff -Nur linux-3.14.15/drivers/video/Makefile linux-linaro-stable-mx6/drivers/video/Makefile
  209095. --- linux-3.14.15/drivers/video/Makefile 2014-07-31 23:51:43.000000000 +0200
  209096. +++ linux-linaro-stable-mx6/drivers/video/Makefile 2014-08-20 19:31:49.580883825 +0200
  209097. @@ -53,6 +53,7 @@
  209098. obj-$(CONFIG_FB_SAVAGE) += savage/
  209099. obj-$(CONFIG_FB_GEODE) += geode/
  209100. obj-$(CONFIG_FB_MBX) += mbx/
  209101. +obj-$(CONFIG_FB_MXC) += mxc/
  209102. obj-$(CONFIG_FB_NEOMAGIC) += neofb.o
  209103. obj-$(CONFIG_FB_3DFX) += tdfxfb.o
  209104. obj-$(CONFIG_FB_CONTROL) += controlfb.o
  209105. @@ -99,6 +100,7 @@
  209106. obj-$(CONFIG_FB_PVR2) += pvr2fb.o
  209107. obj-$(CONFIG_FB_VOODOO1) += sstfb.o
  209108. obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
  209109. +obj-$(CONFIG_FB_ARMHDLCD) += arm-hdlcd.o
  209110. obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
  209111. obj-$(CONFIG_FB_68328) += 68328fb.o
  209112. obj-$(CONFIG_FB_GBE) += gbefb.o
  209113. @@ -178,3 +180,6 @@
  209114. ifeq ($(CONFIG_OF),y)
  209115. obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o
  209116. endif
  209117. +
  209118. +# platform specific output drivers
  209119. +obj-$(CONFIG_VEXPRESS_DVI_CONTROL) += vexpress-dvi.o
  209120. diff -Nur linux-3.14.15/drivers/video/mxc/Kconfig linux-linaro-stable-mx6/drivers/video/mxc/Kconfig
  209121. --- linux-3.14.15/drivers/video/mxc/Kconfig 1970-01-01 01:00:00.000000000 +0100
  209122. +++ linux-linaro-stable-mx6/drivers/video/mxc/Kconfig 2014-08-20 19:31:50.020885713 +0200
  209123. @@ -0,0 +1,48 @@
  209124. +config FB_MXC
  209125. + tristate "MXC Framebuffer support"
  209126. + depends on FB
  209127. + select FB_CFB_FILLRECT
  209128. + select FB_CFB_COPYAREA
  209129. + select FB_CFB_IMAGEBLIT
  209130. + select FB_MODE_HELPERS
  209131. + default y
  209132. + help
  209133. + This is a framebuffer device for the MXC LCD Controller.
  209134. + See <http://www.linux-fbdev.org/> for information on framebuffer
  209135. + devices.
  209136. +
  209137. + If you plan to use the LCD display with your MXC system, say
  209138. + Y here.
  209139. +
  209140. +config FB_MXC_SYNC_PANEL
  209141. + depends on FB_MXC
  209142. + tristate "Synchronous Panel Framebuffer"
  209143. +
  209144. +config FB_MXC_LDB
  209145. + tristate "MXC LDB"
  209146. + depends on FB_MXC_SYNC_PANEL
  209147. + depends on MXC_IPU_V3
  209148. +
  209149. +config FB_MXC_MIPI_DSI
  209150. + tristate "MXC MIPI_DSI"
  209151. + depends on FB_MXC_SYNC_PANEL
  209152. + depends on MXC_IPU_V3
  209153. +
  209154. +config FB_MXC_TRULY_WVGA_SYNC_PANEL
  209155. + tristate "TRULY WVGA Panel"
  209156. + depends on FB_MXC_SYNC_PANEL
  209157. + depends on FB_MXC_MIPI_DSI
  209158. +
  209159. +config FB_MXC_HDMI
  209160. + depends on FB_MXC_SYNC_PANEL
  209161. + depends on MXC_IPU_V3
  209162. + depends on I2C
  209163. + tristate "MXC HDMI driver support"
  209164. + select MFD_MXC_HDMI
  209165. + help
  209166. + Driver for the on-chip MXC HDMI controller.
  209167. +
  209168. +config FB_MXC_EDID
  209169. + depends on FB_MXC && I2C
  209170. + tristate "MXC EDID support"
  209171. + default y
  209172. diff -Nur linux-3.14.15/drivers/video/mxc/ldb.c linux-linaro-stable-mx6/drivers/video/mxc/ldb.c
  209173. --- linux-3.14.15/drivers/video/mxc/ldb.c 1970-01-01 01:00:00.000000000 +0100
  209174. +++ linux-linaro-stable-mx6/drivers/video/mxc/ldb.c 2014-08-20 19:23:58.566867220 +0200
  209175. @@ -0,0 +1,1036 @@
  209176. +/*
  209177. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  209178. + */
  209179. +
  209180. +/*
  209181. + * This program is free software; you can redistribute it and/or modify
  209182. + * it under the terms of the GNU General Public License as published by
  209183. + * the Free Software Foundation; either version 2 of the License, or
  209184. + * (at your option) any later version.
  209185. +
  209186. + * This program is distributed in the hope that it will be useful,
  209187. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  209188. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  209189. + * GNU General Public License for more details.
  209190. +
  209191. + * You should have received a copy of the GNU General Public License along
  209192. + * with this program; if not, write to the Free Software Foundation, Inc.,
  209193. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  209194. + */
  209195. +
  209196. +/*!
  209197. + * @file mxc_ldb.c
  209198. + *
  209199. + * @brief This file contains the LDB driver device interface and fops
  209200. + * functions.
  209201. + */
  209202. +#include <linux/types.h>
  209203. +#include <linux/init.h>
  209204. +#include <linux/module.h>
  209205. +#include <linux/platform_device.h>
  209206. +#include <linux/err.h>
  209207. +#include <linux/clk.h>
  209208. +#include <linux/console.h>
  209209. +#include <linux/io.h>
  209210. +#include <linux/ipu.h>
  209211. +#include <linux/mxcfb.h>
  209212. +#include <linux/regulator/consumer.h>
  209213. +#include <linux/spinlock.h>
  209214. +#include <linux/of_device.h>
  209215. +#include <linux/mod_devicetable.h>
  209216. +#include "mxc_dispdrv.h"
  209217. +
  209218. +#define DISPDRV_LDB "ldb"
  209219. +
  209220. +#define LDB_BGREF_RMODE_MASK 0x00008000
  209221. +#define LDB_BGREF_RMODE_INT 0x00008000
  209222. +#define LDB_BGREF_RMODE_EXT 0x0
  209223. +
  209224. +#define LDB_DI1_VS_POL_MASK 0x00000400
  209225. +#define LDB_DI1_VS_POL_ACT_LOW 0x00000400
  209226. +#define LDB_DI1_VS_POL_ACT_HIGH 0x0
  209227. +#define LDB_DI0_VS_POL_MASK 0x00000200
  209228. +#define LDB_DI0_VS_POL_ACT_LOW 0x00000200
  209229. +#define LDB_DI0_VS_POL_ACT_HIGH 0x0
  209230. +
  209231. +#define LDB_BIT_MAP_CH1_MASK 0x00000100
  209232. +#define LDB_BIT_MAP_CH1_JEIDA 0x00000100
  209233. +#define LDB_BIT_MAP_CH1_SPWG 0x0
  209234. +#define LDB_BIT_MAP_CH0_MASK 0x00000040
  209235. +#define LDB_BIT_MAP_CH0_JEIDA 0x00000040
  209236. +#define LDB_BIT_MAP_CH0_SPWG 0x0
  209237. +
  209238. +#define LDB_DATA_WIDTH_CH1_MASK 0x00000080
  209239. +#define LDB_DATA_WIDTH_CH1_24 0x00000080
  209240. +#define LDB_DATA_WIDTH_CH1_18 0x0
  209241. +#define LDB_DATA_WIDTH_CH0_MASK 0x00000020
  209242. +#define LDB_DATA_WIDTH_CH0_24 0x00000020
  209243. +#define LDB_DATA_WIDTH_CH0_18 0x0
  209244. +
  209245. +#define LDB_CH1_MODE_MASK 0x0000000C
  209246. +#define LDB_CH1_MODE_EN_TO_DI1 0x0000000C
  209247. +#define LDB_CH1_MODE_EN_TO_DI0 0x00000004
  209248. +#define LDB_CH1_MODE_DISABLE 0x0
  209249. +#define LDB_CH0_MODE_MASK 0x00000003
  209250. +#define LDB_CH0_MODE_EN_TO_DI1 0x00000003
  209251. +#define LDB_CH0_MODE_EN_TO_DI0 0x00000001
  209252. +#define LDB_CH0_MODE_DISABLE 0x0
  209253. +
  209254. +#define LDB_SPLIT_MODE_EN 0x00000010
  209255. +
  209256. +enum {
  209257. + IMX6_LDB,
  209258. +};
  209259. +
  209260. +enum {
  209261. + LDB_IMX6 = 1,
  209262. +};
  209263. +
  209264. +struct fsl_mxc_ldb_platform_data {
  209265. + int devtype;
  209266. + u32 ext_ref;
  209267. +#define LDB_SPL_DI0 1
  209268. +#define LDB_SPL_DI1 2
  209269. +#define LDB_DUL_DI0 3
  209270. +#define LDB_DUL_DI1 4
  209271. +#define LDB_SIN0 5
  209272. +#define LDB_SIN1 6
  209273. +#define LDB_SEP0 7
  209274. +#define LDB_SEP1 8
  209275. + int mode;
  209276. + int ipu_id;
  209277. + int disp_id;
  209278. +
  209279. + /*only work for separate mode*/
  209280. + int sec_ipu_id;
  209281. + int sec_disp_id;
  209282. +};
  209283. +
  209284. +struct ldb_data {
  209285. + struct platform_device *pdev;
  209286. + struct mxc_dispdrv_handle *disp_ldb;
  209287. + uint32_t *reg;
  209288. + uint32_t *control_reg;
  209289. + uint32_t *gpr3_reg;
  209290. + uint32_t control_reg_data;
  209291. + struct regulator *lvds_bg_reg;
  209292. + int mode;
  209293. + bool inited;
  209294. + struct ldb_setting {
  209295. + struct clk *di_clk;
  209296. + struct clk *ldb_di_clk;
  209297. + struct clk *div_3_5_clk;
  209298. + struct clk *div_7_clk;
  209299. + struct clk *div_sel_clk;
  209300. + bool active;
  209301. + bool clk_en;
  209302. + int ipu;
  209303. + int di;
  209304. + uint32_t ch_mask;
  209305. + uint32_t ch_val;
  209306. + } setting[2];
  209307. + struct notifier_block nb;
  209308. +};
  209309. +
  209310. +static int g_ldb_mode;
  209311. +
  209312. +static struct fb_videomode ldb_modedb[] = {
  209313. + {
  209314. + "LDB-WXGA", 60, 1280, 800, 14065,
  209315. + 40, 40,
  209316. + 10, 3,
  209317. + 80, 10,
  209318. + 0,
  209319. + FB_VMODE_NONINTERLACED,
  209320. + FB_MODE_IS_DETAILED,},
  209321. + {
  209322. + "LDB-XGA", 60, 1024, 768, 15385,
  209323. + 220, 40,
  209324. + 21, 7,
  209325. + 60, 10,
  209326. + 0,
  209327. + FB_VMODE_NONINTERLACED,
  209328. + FB_MODE_IS_DETAILED,},
  209329. + {
  209330. + "LDB-1080P60", 60, 1920, 1080, 7692,
  209331. + 100, 40,
  209332. + 30, 3,
  209333. + 10, 2,
  209334. + 0,
  209335. + FB_VMODE_NONINTERLACED,
  209336. + FB_MODE_IS_DETAILED,},
  209337. +};
  209338. +static int ldb_modedb_sz = ARRAY_SIZE(ldb_modedb);
  209339. +
  209340. +static inline int is_imx6_ldb(struct fsl_mxc_ldb_platform_data *plat_data)
  209341. +{
  209342. + return (plat_data->devtype == LDB_IMX6);
  209343. +}
  209344. +
  209345. +static int bits_per_pixel(int pixel_fmt)
  209346. +{
  209347. + switch (pixel_fmt) {
  209348. + case IPU_PIX_FMT_BGR24:
  209349. + case IPU_PIX_FMT_RGB24:
  209350. + return 24;
  209351. + break;
  209352. + case IPU_PIX_FMT_BGR666:
  209353. + case IPU_PIX_FMT_RGB666:
  209354. + case IPU_PIX_FMT_LVDS666:
  209355. + return 18;
  209356. + break;
  209357. + default:
  209358. + break;
  209359. + }
  209360. + return 0;
  209361. +}
  209362. +
  209363. +static int valid_mode(int pixel_fmt)
  209364. +{
  209365. + return ((pixel_fmt == IPU_PIX_FMT_RGB24) ||
  209366. + (pixel_fmt == IPU_PIX_FMT_BGR24) ||
  209367. + (pixel_fmt == IPU_PIX_FMT_LVDS666) ||
  209368. + (pixel_fmt == IPU_PIX_FMT_RGB666) ||
  209369. + (pixel_fmt == IPU_PIX_FMT_BGR666));
  209370. +}
  209371. +
  209372. +static int parse_ldb_mode(char *mode)
  209373. +{
  209374. + int ldb_mode;
  209375. +
  209376. + if (!strcmp(mode, "spl0"))
  209377. + ldb_mode = LDB_SPL_DI0;
  209378. + else if (!strcmp(mode, "spl1"))
  209379. + ldb_mode = LDB_SPL_DI1;
  209380. + else if (!strcmp(mode, "dul0"))
  209381. + ldb_mode = LDB_DUL_DI0;
  209382. + else if (!strcmp(mode, "dul1"))
  209383. + ldb_mode = LDB_DUL_DI1;
  209384. + else if (!strcmp(mode, "sin0"))
  209385. + ldb_mode = LDB_SIN0;
  209386. + else if (!strcmp(mode, "sin1"))
  209387. + ldb_mode = LDB_SIN1;
  209388. + else if (!strcmp(mode, "sep0"))
  209389. + ldb_mode = LDB_SEP0;
  209390. + else if (!strcmp(mode, "sep1"))
  209391. + ldb_mode = LDB_SEP1;
  209392. + else
  209393. + ldb_mode = -EINVAL;
  209394. +
  209395. + return ldb_mode;
  209396. +}
  209397. +
  209398. +#ifndef MODULE
  209399. +/*
  209400. + * "ldb=spl0/1" -- split mode on DI0/1
  209401. + * "ldb=dul0/1" -- dual mode on DI0/1
  209402. + * "ldb=sin0/1" -- single mode on LVDS0/1
  209403. + * "ldb=sep0/1" -- separate mode begin from LVDS0/1
  209404. + *
  209405. + * there are two LVDS channels(LVDS0 and LVDS1) which can transfer video
  209406. + * datas, there two channels can be used as split/dual/single/separate mode.
  209407. + *
  209408. + * split mode means display data from DI0 or DI1 will send to both channels
  209409. + * LVDS0+LVDS1.
  209410. + * dual mode means display data from DI0 or DI1 will be duplicated on LVDS0
  209411. + * and LVDS1, it said, LVDS0 and LVDS1 has the same content.
  209412. + * single mode means only work for DI0/DI1->LVDS0 or DI0/DI1->LVDS1.
  209413. + * separate mode means you can make DI0/DI1->LVDS0 and DI0/DI1->LVDS1 work
  209414. + * at the same time.
  209415. + */
  209416. +static int __init ldb_setup(char *options)
  209417. +{
  209418. + g_ldb_mode = parse_ldb_mode(options);
  209419. + return (g_ldb_mode < 0) ? 0 : 1;
  209420. +}
  209421. +__setup("ldb=", ldb_setup);
  209422. +#endif
  209423. +
  209424. +static int ldb_get_of_property(struct platform_device *pdev,
  209425. + struct fsl_mxc_ldb_platform_data *plat_data)
  209426. +{
  209427. + struct device_node *np = pdev->dev.of_node;
  209428. + int err;
  209429. + u32 ipu_id, disp_id;
  209430. + u32 sec_ipu_id, sec_disp_id;
  209431. + char *mode;
  209432. + u32 ext_ref;
  209433. +
  209434. + err = of_property_read_string(np, "mode", (const char **)&mode);
  209435. + if (err) {
  209436. + dev_dbg(&pdev->dev, "get of property mode fail\n");
  209437. + return err;
  209438. + }
  209439. + err = of_property_read_u32(np, "ext_ref", &ext_ref);
  209440. + if (err) {
  209441. + dev_dbg(&pdev->dev, "get of property ext_ref fail\n");
  209442. + return err;
  209443. + }
  209444. + err = of_property_read_u32(np, "ipu_id", &ipu_id);
  209445. + if (err) {
  209446. + dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
  209447. + return err;
  209448. + }
  209449. + err = of_property_read_u32(np, "disp_id", &disp_id);
  209450. + if (err) {
  209451. + dev_dbg(&pdev->dev, "get of property disp_id fail\n");
  209452. + return err;
  209453. + }
  209454. + err = of_property_read_u32(np, "sec_ipu_id", &sec_ipu_id);
  209455. + if (err) {
  209456. + dev_dbg(&pdev->dev, "get of property sec_ipu_id fail\n");
  209457. + return err;
  209458. + }
  209459. + err = of_property_read_u32(np, "sec_disp_id", &sec_disp_id);
  209460. + if (err) {
  209461. + dev_dbg(&pdev->dev, "get of property sec_disp_id fail\n");
  209462. + return err;
  209463. + }
  209464. +
  209465. + plat_data->mode = parse_ldb_mode(mode);
  209466. + plat_data->ext_ref = ext_ref;
  209467. + plat_data->ipu_id = ipu_id;
  209468. + plat_data->disp_id = disp_id;
  209469. + plat_data->sec_ipu_id = sec_ipu_id;
  209470. + plat_data->sec_disp_id = sec_disp_id;
  209471. +
  209472. + return err;
  209473. +}
  209474. +
  209475. +static int find_ldb_setting(struct ldb_data *ldb, struct fb_info *fbi)
  209476. +{
  209477. + char *id_di[] = {
  209478. + "DISP3 BG",
  209479. + "DISP3 BG - DI1",
  209480. + };
  209481. + char id[16];
  209482. + int i;
  209483. +
  209484. + for (i = 0; i < 2; i++) {
  209485. + if (ldb->setting[i].active) {
  209486. + memset(id, 0, 16);
  209487. + memcpy(id, id_di[ldb->setting[i].di],
  209488. + strlen(id_di[ldb->setting[i].di]));
  209489. + id[4] += ldb->setting[i].ipu;
  209490. + if (!strcmp(id, fbi->fix.id))
  209491. + return i;
  209492. + }
  209493. + }
  209494. + return -EINVAL;
  209495. +}
  209496. +
  209497. +static int ldb_disp_setup(struct mxc_dispdrv_handle *disp, struct fb_info *fbi)
  209498. +{
  209499. + uint32_t reg, val;
  209500. + uint32_t pixel_clk, rounded_pixel_clk;
  209501. + struct clk *ldb_clk_parent;
  209502. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  209503. + int setting_idx, di;
  209504. + int ret;
  209505. +
  209506. + setting_idx = find_ldb_setting(ldb, fbi);
  209507. + if (setting_idx < 0)
  209508. + return setting_idx;
  209509. +
  209510. + di = ldb->setting[setting_idx].di;
  209511. +
  209512. + /* restore channel mode setting */
  209513. + val = readl(ldb->control_reg);
  209514. + val |= ldb->setting[setting_idx].ch_val;
  209515. + writel(val, ldb->control_reg);
  209516. + dev_dbg(&ldb->pdev->dev, "LDB setup, control reg:0x%x\n",
  209517. + readl(ldb->control_reg));
  209518. +
  209519. + /* vsync setup */
  209520. + reg = readl(ldb->control_reg);
  209521. + if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) {
  209522. + if (di == 0)
  209523. + reg = (reg & ~LDB_DI0_VS_POL_MASK)
  209524. + | LDB_DI0_VS_POL_ACT_HIGH;
  209525. + else
  209526. + reg = (reg & ~LDB_DI1_VS_POL_MASK)
  209527. + | LDB_DI1_VS_POL_ACT_HIGH;
  209528. + } else {
  209529. + if (di == 0)
  209530. + reg = (reg & ~LDB_DI0_VS_POL_MASK)
  209531. + | LDB_DI0_VS_POL_ACT_LOW;
  209532. + else
  209533. + reg = (reg & ~LDB_DI1_VS_POL_MASK)
  209534. + | LDB_DI1_VS_POL_ACT_LOW;
  209535. + }
  209536. + writel(reg, ldb->control_reg);
  209537. +
  209538. + /* clk setup */
  209539. + if (ldb->setting[setting_idx].clk_en)
  209540. + clk_disable_unprepare(ldb->setting[setting_idx].ldb_di_clk);
  209541. + pixel_clk = (PICOS2KHZ(fbi->var.pixclock)) * 1000UL;
  209542. + ldb_clk_parent = clk_get_parent(ldb->setting[setting_idx].ldb_di_clk);
  209543. + if (IS_ERR(ldb_clk_parent)) {
  209544. + dev_err(&ldb->pdev->dev, "get ldb di parent clk fail\n");
  209545. + return PTR_ERR(ldb_clk_parent);
  209546. + }
  209547. + if ((ldb->mode == LDB_SPL_DI0) || (ldb->mode == LDB_SPL_DI1))
  209548. + ret = clk_set_rate(ldb_clk_parent, pixel_clk * 7 / 2);
  209549. + else
  209550. + ret = clk_set_rate(ldb_clk_parent, pixel_clk * 7);
  209551. + if (ret < 0) {
  209552. + dev_err(&ldb->pdev->dev, "set ldb parent clk fail:%d\n", ret);
  209553. + return ret;
  209554. + }
  209555. + rounded_pixel_clk = clk_round_rate(ldb->setting[setting_idx].ldb_di_clk,
  209556. + pixel_clk);
  209557. + dev_dbg(&ldb->pdev->dev, "pixel_clk:%d, rounded_pixel_clk:%d\n",
  209558. + pixel_clk, rounded_pixel_clk);
  209559. + ret = clk_set_rate(ldb->setting[setting_idx].ldb_di_clk,
  209560. + rounded_pixel_clk);
  209561. + if (ret < 0) {
  209562. + dev_err(&ldb->pdev->dev, "set ldb di clk fail:%d\n", ret);
  209563. + return ret;
  209564. + }
  209565. + ret = clk_prepare_enable(ldb->setting[setting_idx].ldb_di_clk);
  209566. + if (ret < 0) {
  209567. + dev_err(&ldb->pdev->dev, "enable ldb di clk fail:%d\n", ret);
  209568. + return ret;
  209569. + }
  209570. +
  209571. + if (!ldb->setting[setting_idx].clk_en)
  209572. + ldb->setting[setting_idx].clk_en = true;
  209573. +
  209574. + return 0;
  209575. +}
  209576. +
  209577. +int ldb_fb_event(struct notifier_block *nb, unsigned long val, void *v)
  209578. +{
  209579. + struct ldb_data *ldb = container_of(nb, struct ldb_data, nb);
  209580. + struct fb_event *event = v;
  209581. + struct fb_info *fbi = event->info;
  209582. + int index;
  209583. + uint32_t data;
  209584. +
  209585. + index = find_ldb_setting(ldb, fbi);
  209586. + if (index < 0)
  209587. + return 0;
  209588. +
  209589. + fbi->mode = (struct fb_videomode *)fb_match_mode(&fbi->var,
  209590. + &fbi->modelist);
  209591. +
  209592. + if (!fbi->mode) {
  209593. + dev_warn(&ldb->pdev->dev,
  209594. + "LDB: can not find mode for xres=%d, yres=%d\n",
  209595. + fbi->var.xres, fbi->var.yres);
  209596. + if (ldb->setting[index].clk_en) {
  209597. + clk_disable(ldb->setting[index].ldb_di_clk);
  209598. + ldb->setting[index].clk_en = false;
  209599. + data = readl(ldb->control_reg);
  209600. + data &= ~ldb->setting[index].ch_mask;
  209601. + writel(data, ldb->control_reg);
  209602. + }
  209603. + return 0;
  209604. + }
  209605. +
  209606. + switch (val) {
  209607. + case FB_EVENT_BLANK:
  209608. + {
  209609. + if (*((int *)event->data) == FB_BLANK_UNBLANK) {
  209610. + if (!ldb->setting[index].clk_en) {
  209611. + clk_enable(ldb->setting[index].ldb_di_clk);
  209612. + ldb->setting[index].clk_en = true;
  209613. + }
  209614. + } else {
  209615. + if (ldb->setting[index].clk_en) {
  209616. + clk_disable(ldb->setting[index].ldb_di_clk);
  209617. + ldb->setting[index].clk_en = false;
  209618. + data = readl(ldb->control_reg);
  209619. + data &= ~ldb->setting[index].ch_mask;
  209620. + writel(data, ldb->control_reg);
  209621. + dev_dbg(&ldb->pdev->dev,
  209622. + "LDB blank, control reg:0x%x\n",
  209623. + readl(ldb->control_reg));
  209624. + }
  209625. + }
  209626. + break;
  209627. + }
  209628. + case FB_EVENT_SUSPEND:
  209629. + if (ldb->setting[index].clk_en) {
  209630. + clk_disable(ldb->setting[index].ldb_di_clk);
  209631. + ldb->setting[index].clk_en = false;
  209632. + }
  209633. + break;
  209634. + default:
  209635. + break;
  209636. + }
  209637. + return 0;
  209638. +}
  209639. +
  209640. +#define LVDS_MUX_CTL_WIDTH 2
  209641. +#define LVDS_MUX_CTL_MASK 3
  209642. +#define LVDS0_MUX_CTL_OFFS 6
  209643. +#define LVDS1_MUX_CTL_OFFS 8
  209644. +#define LVDS0_MUX_CTL_MASK (LVDS_MUX_CTL_MASK << 6)
  209645. +#define LVDS1_MUX_CTL_MASK (LVDS_MUX_CTL_MASK << 8)
  209646. +#define ROUTE_IPU_DI(ipu, di) (((ipu << 1) | di) & LVDS_MUX_CTL_MASK)
  209647. +static int ldb_ipu_ldb_route(int ipu, int di, struct ldb_data *ldb)
  209648. +{
  209649. + uint32_t reg;
  209650. + int channel;
  209651. + int shift;
  209652. + int mode = ldb->mode;
  209653. +
  209654. + reg = readl(ldb->gpr3_reg);
  209655. + if (mode < LDB_SIN0) {
  209656. + reg &= ~(LVDS0_MUX_CTL_MASK | LVDS1_MUX_CTL_MASK);
  209657. + reg |= (ROUTE_IPU_DI(ipu, di) << LVDS0_MUX_CTL_OFFS) |
  209658. + (ROUTE_IPU_DI(ipu, di) << LVDS1_MUX_CTL_OFFS);
  209659. + dev_dbg(&ldb->pdev->dev,
  209660. + "Dual/Split mode both channels route to IPU%d-DI%d\n",
  209661. + ipu, di);
  209662. + } else if ((mode == LDB_SIN0) || (mode == LDB_SIN1)) {
  209663. + reg &= ~(LVDS0_MUX_CTL_MASK | LVDS1_MUX_CTL_MASK);
  209664. + channel = mode - LDB_SIN0;
  209665. + shift = LVDS0_MUX_CTL_OFFS + channel * LVDS_MUX_CTL_WIDTH;
  209666. + reg |= ROUTE_IPU_DI(ipu, di) << shift;
  209667. + dev_dbg(&ldb->pdev->dev,
  209668. + "Single mode channel %d route to IPU%d-DI%d\n",
  209669. + channel, ipu, di);
  209670. + } else {
  209671. + static bool first = true;
  209672. +
  209673. + if (first) {
  209674. + if (mode == LDB_SEP0) {
  209675. + reg &= ~LVDS0_MUX_CTL_MASK;
  209676. + channel = 0;
  209677. + } else {
  209678. + reg &= ~LVDS1_MUX_CTL_MASK;
  209679. + channel = 1;
  209680. + }
  209681. + first = false;
  209682. + } else {
  209683. + if (mode == LDB_SEP0) {
  209684. + reg &= ~LVDS1_MUX_CTL_MASK;
  209685. + channel = 1;
  209686. + } else {
  209687. + reg &= ~LVDS0_MUX_CTL_MASK;
  209688. + channel = 0;
  209689. + }
  209690. + }
  209691. +
  209692. + shift = LVDS0_MUX_CTL_OFFS + channel * LVDS_MUX_CTL_WIDTH;
  209693. + reg |= ROUTE_IPU_DI(ipu, di) << shift;
  209694. +
  209695. + dev_dbg(&ldb->pdev->dev,
  209696. + "Separate mode channel %d route to IPU%d-DI%d\n",
  209697. + channel, ipu, di);
  209698. + }
  209699. + writel(reg, ldb->gpr3_reg);
  209700. +
  209701. + return 0;
  209702. +}
  209703. +
  209704. +static int ldb_disp_init(struct mxc_dispdrv_handle *disp,
  209705. + struct mxc_dispdrv_setting *setting)
  209706. +{
  209707. + int ret = 0, i, lvds_channel = 0;
  209708. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  209709. + struct fsl_mxc_ldb_platform_data *plat_data = ldb->pdev->dev.platform_data;
  209710. + struct resource *res;
  209711. + uint32_t reg, setting_idx;
  209712. + uint32_t ch_mask = 0, ch_val = 0;
  209713. + uint32_t ipu_id, disp_id;
  209714. + char di_clk[] = "ipu1_di0_sel";
  209715. + char ldb_clk[] = "ldb_di0";
  209716. + char div_3_5_clk[] = "di0_div_3_5";
  209717. + char div_7_clk[] = "di0_div_7";
  209718. + char div_sel_clk[] = "di0_div_sel";
  209719. +
  209720. + /* if input format not valid, make RGB666 as default*/
  209721. + if (!valid_mode(setting->if_fmt)) {
  209722. + dev_warn(&ldb->pdev->dev, "Input pixel format not valid"
  209723. + " use default RGB666\n");
  209724. + setting->if_fmt = IPU_PIX_FMT_RGB666;
  209725. + }
  209726. +
  209727. + if (!ldb->inited) {
  209728. + setting_idx = 0;
  209729. + res = platform_get_resource(ldb->pdev, IORESOURCE_MEM, 0);
  209730. + if (!res) {
  209731. + dev_err(&ldb->pdev->dev, "get iomem fail.\n");
  209732. + return -ENOMEM;
  209733. + }
  209734. +
  209735. + ldb->reg = devm_ioremap(&ldb->pdev->dev, res->start,
  209736. + resource_size(res));
  209737. + ldb->control_reg = ldb->reg + 2;
  209738. + ldb->gpr3_reg = ldb->reg + 3;
  209739. +
  209740. + /* ipu selected by platform data setting */
  209741. + setting->dev_id = plat_data->ipu_id;
  209742. +
  209743. + reg = readl(ldb->control_reg);
  209744. +
  209745. + /* refrence resistor select */
  209746. + reg &= ~LDB_BGREF_RMODE_MASK;
  209747. + if (plat_data->ext_ref)
  209748. + reg |= LDB_BGREF_RMODE_EXT;
  209749. + else
  209750. + reg |= LDB_BGREF_RMODE_INT;
  209751. +
  209752. + /* TODO: now only use SPWG data mapping for both channel */
  209753. + reg &= ~(LDB_BIT_MAP_CH0_MASK | LDB_BIT_MAP_CH1_MASK);
  209754. + reg |= LDB_BIT_MAP_CH0_SPWG | LDB_BIT_MAP_CH1_SPWG;
  209755. +
  209756. + /* channel mode setting */
  209757. + reg &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
  209758. + reg &= ~(LDB_DATA_WIDTH_CH0_MASK | LDB_DATA_WIDTH_CH1_MASK);
  209759. +
  209760. + if (bits_per_pixel(setting->if_fmt) == 24)
  209761. + reg |= LDB_DATA_WIDTH_CH0_24 | LDB_DATA_WIDTH_CH1_24;
  209762. + else
  209763. + reg |= LDB_DATA_WIDTH_CH0_18 | LDB_DATA_WIDTH_CH1_18;
  209764. +
  209765. + if (g_ldb_mode >= LDB_SPL_DI0)
  209766. + ldb->mode = g_ldb_mode;
  209767. + else
  209768. + ldb->mode = plat_data->mode;
  209769. +
  209770. + if ((ldb->mode == LDB_SIN0) || (ldb->mode == LDB_SIN1)) {
  209771. + ret = ldb->mode - LDB_SIN0;
  209772. + if (plat_data->disp_id != ret) {
  209773. + dev_warn(&ldb->pdev->dev,
  209774. + "change IPU DI%d to IPU DI%d for LDB "
  209775. + "channel%d.\n",
  209776. + plat_data->disp_id, ret, ret);
  209777. + plat_data->disp_id = ret;
  209778. + }
  209779. + } else if (((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1))
  209780. + && is_imx6_ldb(plat_data)) {
  209781. + if (plat_data->disp_id == plat_data->sec_disp_id) {
  209782. + dev_err(&ldb->pdev->dev,
  209783. + "For LVDS separate mode,"
  209784. + "two DIs should be different!\n");
  209785. + return -EINVAL;
  209786. + }
  209787. +
  209788. + if (((!plat_data->disp_id) && (ldb->mode == LDB_SEP1))
  209789. + || ((plat_data->disp_id) &&
  209790. + (ldb->mode == LDB_SEP0))) {
  209791. + dev_dbg(&ldb->pdev->dev,
  209792. + "LVDS separate mode:"
  209793. + "swap DI configuration!\n");
  209794. + ipu_id = plat_data->ipu_id;
  209795. + disp_id = plat_data->disp_id;
  209796. + plat_data->ipu_id = plat_data->sec_ipu_id;
  209797. + plat_data->disp_id = plat_data->sec_disp_id;
  209798. + plat_data->sec_ipu_id = ipu_id;
  209799. + plat_data->sec_disp_id = disp_id;
  209800. + }
  209801. + }
  209802. +
  209803. + if (ldb->mode == LDB_SPL_DI0) {
  209804. + reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI0
  209805. + | LDB_CH1_MODE_EN_TO_DI0;
  209806. + setting->disp_id = 0;
  209807. + } else if (ldb->mode == LDB_SPL_DI1) {
  209808. + reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI1
  209809. + | LDB_CH1_MODE_EN_TO_DI1;
  209810. + setting->disp_id = 1;
  209811. + } else if (ldb->mode == LDB_DUL_DI0) {
  209812. + reg &= ~LDB_SPLIT_MODE_EN;
  209813. + reg |= LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0;
  209814. + setting->disp_id = 0;
  209815. + } else if (ldb->mode == LDB_DUL_DI1) {
  209816. + reg &= ~LDB_SPLIT_MODE_EN;
  209817. + reg |= LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1;
  209818. + setting->disp_id = 1;
  209819. + } else if (ldb->mode == LDB_SIN0) {
  209820. + reg &= ~LDB_SPLIT_MODE_EN;
  209821. + setting->disp_id = plat_data->disp_id;
  209822. + if (setting->disp_id == 0)
  209823. + reg |= LDB_CH0_MODE_EN_TO_DI0;
  209824. + else
  209825. + reg |= LDB_CH0_MODE_EN_TO_DI1;
  209826. + ch_mask = LDB_CH0_MODE_MASK;
  209827. + ch_val = reg & LDB_CH0_MODE_MASK;
  209828. + } else if (ldb->mode == LDB_SIN1) {
  209829. + reg &= ~LDB_SPLIT_MODE_EN;
  209830. + setting->disp_id = plat_data->disp_id;
  209831. + if (setting->disp_id == 0)
  209832. + reg |= LDB_CH1_MODE_EN_TO_DI0;
  209833. + else
  209834. + reg |= LDB_CH1_MODE_EN_TO_DI1;
  209835. + ch_mask = LDB_CH1_MODE_MASK;
  209836. + ch_val = reg & LDB_CH1_MODE_MASK;
  209837. + } else { /* separate mode*/
  209838. + setting->disp_id = plat_data->disp_id;
  209839. +
  209840. + /* first output is LVDS0 or LVDS1 */
  209841. + if (ldb->mode == LDB_SEP0)
  209842. + lvds_channel = 0;
  209843. + else
  209844. + lvds_channel = 1;
  209845. +
  209846. + reg &= ~LDB_SPLIT_MODE_EN;
  209847. +
  209848. + if ((lvds_channel == 0) && (setting->disp_id == 0))
  209849. + reg |= LDB_CH0_MODE_EN_TO_DI0;
  209850. + else if ((lvds_channel == 0) && (setting->disp_id == 1))
  209851. + reg |= LDB_CH0_MODE_EN_TO_DI1;
  209852. + else if ((lvds_channel == 1) && (setting->disp_id == 0))
  209853. + reg |= LDB_CH1_MODE_EN_TO_DI0;
  209854. + else
  209855. + reg |= LDB_CH1_MODE_EN_TO_DI1;
  209856. + ch_mask = lvds_channel ? LDB_CH1_MODE_MASK :
  209857. + LDB_CH0_MODE_MASK;
  209858. + ch_val = reg & ch_mask;
  209859. +
  209860. + if (bits_per_pixel(setting->if_fmt) == 24) {
  209861. + if (lvds_channel == 0)
  209862. + reg &= ~LDB_DATA_WIDTH_CH1_24;
  209863. + else
  209864. + reg &= ~LDB_DATA_WIDTH_CH0_24;
  209865. + } else {
  209866. + if (lvds_channel == 0)
  209867. + reg &= ~LDB_DATA_WIDTH_CH1_18;
  209868. + else
  209869. + reg &= ~LDB_DATA_WIDTH_CH0_18;
  209870. + }
  209871. + }
  209872. +
  209873. + writel(reg, ldb->control_reg);
  209874. + if (ldb->mode < LDB_SIN0) {
  209875. + ch_mask = LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK;
  209876. + ch_val = reg & (LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
  209877. + }
  209878. + } else { /* second time for separate mode */
  209879. + if ((ldb->mode == LDB_SPL_DI0) ||
  209880. + (ldb->mode == LDB_SPL_DI1) ||
  209881. + (ldb->mode == LDB_DUL_DI0) ||
  209882. + (ldb->mode == LDB_DUL_DI1) ||
  209883. + (ldb->mode == LDB_SIN0) ||
  209884. + (ldb->mode == LDB_SIN1)) {
  209885. + dev_err(&ldb->pdev->dev, "for second ldb disp"
  209886. + "ldb mode should in separate mode\n");
  209887. + return -EINVAL;
  209888. + }
  209889. +
  209890. + setting_idx = 1;
  209891. + if (is_imx6_ldb(plat_data)) {
  209892. + setting->dev_id = plat_data->sec_ipu_id;
  209893. + setting->disp_id = plat_data->sec_disp_id;
  209894. + } else {
  209895. + setting->dev_id = plat_data->ipu_id;
  209896. + setting->disp_id = !plat_data->disp_id;
  209897. + }
  209898. + if (setting->disp_id == ldb->setting[0].di) {
  209899. + dev_err(&ldb->pdev->dev, "Err: for second ldb disp in"
  209900. + "separate mode, DI should be different!\n");
  209901. + return -EINVAL;
  209902. + }
  209903. +
  209904. + /* second output is LVDS0 or LVDS1 */
  209905. + if (ldb->mode == LDB_SEP0)
  209906. + lvds_channel = 1;
  209907. + else
  209908. + lvds_channel = 0;
  209909. +
  209910. + reg = readl(ldb->control_reg);
  209911. + if ((lvds_channel == 0) && (setting->disp_id == 0))
  209912. + reg |= LDB_CH0_MODE_EN_TO_DI0;
  209913. + else if ((lvds_channel == 0) && (setting->disp_id == 1))
  209914. + reg |= LDB_CH0_MODE_EN_TO_DI1;
  209915. + else if ((lvds_channel == 1) && (setting->disp_id == 0))
  209916. + reg |= LDB_CH1_MODE_EN_TO_DI0;
  209917. + else
  209918. + reg |= LDB_CH1_MODE_EN_TO_DI1;
  209919. + ch_mask = lvds_channel ? LDB_CH1_MODE_MASK :
  209920. + LDB_CH0_MODE_MASK;
  209921. + ch_val = reg & ch_mask;
  209922. +
  209923. + if (bits_per_pixel(setting->if_fmt) == 24) {
  209924. + if (lvds_channel == 0)
  209925. + reg |= LDB_DATA_WIDTH_CH0_24;
  209926. + else
  209927. + reg |= LDB_DATA_WIDTH_CH1_24;
  209928. + } else {
  209929. + if (lvds_channel == 0)
  209930. + reg |= LDB_DATA_WIDTH_CH0_18;
  209931. + else
  209932. + reg |= LDB_DATA_WIDTH_CH1_18;
  209933. + }
  209934. + writel(reg, ldb->control_reg);
  209935. + }
  209936. +
  209937. + /* get clocks */
  209938. + if (is_imx6_ldb(plat_data) &&
  209939. + ((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1))) {
  209940. + ldb_clk[6] += lvds_channel;
  209941. + div_3_5_clk[2] += lvds_channel;
  209942. + div_7_clk[2] += lvds_channel;
  209943. + div_sel_clk[2] += lvds_channel;
  209944. + } else {
  209945. + ldb_clk[6] += setting->disp_id;
  209946. + div_3_5_clk[2] += setting->disp_id;
  209947. + div_7_clk[2] += setting->disp_id;
  209948. + div_sel_clk[2] += setting->disp_id;
  209949. + }
  209950. + ldb->setting[setting_idx].ldb_di_clk = clk_get(&ldb->pdev->dev,
  209951. + ldb_clk);
  209952. + if (IS_ERR(ldb->setting[setting_idx].ldb_di_clk)) {
  209953. + dev_err(&ldb->pdev->dev, "get ldb clk failed\n");
  209954. + return PTR_ERR(ldb->setting[setting_idx].ldb_di_clk);
  209955. + }
  209956. +
  209957. + ldb->setting[setting_idx].div_3_5_clk = clk_get(&ldb->pdev->dev,
  209958. + div_3_5_clk);
  209959. + if (IS_ERR(ldb->setting[setting_idx].div_3_5_clk)) {
  209960. + dev_err(&ldb->pdev->dev, "get div 3.5 clk failed\n");
  209961. + return PTR_ERR(ldb->setting[setting_idx].div_3_5_clk);
  209962. + }
  209963. + ldb->setting[setting_idx].div_7_clk = clk_get(&ldb->pdev->dev,
  209964. + div_7_clk);
  209965. + if (IS_ERR(ldb->setting[setting_idx].div_7_clk)) {
  209966. + dev_err(&ldb->pdev->dev, "get div 7 clk failed\n");
  209967. + return PTR_ERR(ldb->setting[setting_idx].div_7_clk);
  209968. + }
  209969. +
  209970. + ldb->setting[setting_idx].div_sel_clk = clk_get(&ldb->pdev->dev,
  209971. + div_sel_clk);
  209972. + if (IS_ERR(ldb->setting[setting_idx].div_sel_clk)) {
  209973. + dev_err(&ldb->pdev->dev, "get div sel clk failed\n");
  209974. + return PTR_ERR(ldb->setting[setting_idx].div_sel_clk);
  209975. + }
  209976. +
  209977. + di_clk[3] += setting->dev_id;
  209978. + di_clk[7] += setting->disp_id;
  209979. + ldb->setting[setting_idx].di_clk = clk_get(&ldb->pdev->dev,
  209980. + di_clk);
  209981. + if (IS_ERR(ldb->setting[setting_idx].di_clk)) {
  209982. + dev_err(&ldb->pdev->dev, "get di clk failed\n");
  209983. + return PTR_ERR(ldb->setting[setting_idx].di_clk);
  209984. + }
  209985. +
  209986. + ldb->setting[setting_idx].ch_mask = ch_mask;
  209987. + ldb->setting[setting_idx].ch_val = ch_val;
  209988. +
  209989. + if (is_imx6_ldb(plat_data))
  209990. + ldb_ipu_ldb_route(setting->dev_id, setting->disp_id, ldb);
  209991. +
  209992. + /* must use spec video mode defined by driver */
  209993. + ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str,
  209994. + ldb_modedb, ldb_modedb_sz, NULL, setting->default_bpp);
  209995. + if (ret != 1)
  209996. + fb_videomode_to_var(&setting->fbi->var, &ldb_modedb[0]);
  209997. +
  209998. + INIT_LIST_HEAD(&setting->fbi->modelist);
  209999. + for (i = 0; i < ldb_modedb_sz; i++) {
  210000. + struct fb_videomode m;
  210001. + fb_var_to_videomode(&m, &setting->fbi->var);
  210002. + if (fb_mode_is_equal(&m, &ldb_modedb[i])) {
  210003. + fb_add_videomode(&ldb_modedb[i],
  210004. + &setting->fbi->modelist);
  210005. + break;
  210006. + }
  210007. + }
  210008. +
  210009. + ldb->setting[setting_idx].ipu = setting->dev_id;
  210010. + ldb->setting[setting_idx].di = setting->disp_id;
  210011. +
  210012. + return ret;
  210013. +}
  210014. +
  210015. +static int ldb_post_disp_init(struct mxc_dispdrv_handle *disp,
  210016. + int ipu_id, int disp_id)
  210017. +{
  210018. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  210019. + int setting_idx = ldb->inited ? 1 : 0;
  210020. + int ret = 0;
  210021. +
  210022. + if (!ldb->inited) {
  210023. + ldb->nb.notifier_call = ldb_fb_event;
  210024. + fb_register_client(&ldb->nb);
  210025. + }
  210026. +
  210027. + ret = clk_set_parent(ldb->setting[setting_idx].di_clk,
  210028. + ldb->setting[setting_idx].ldb_di_clk);
  210029. + if (ret) {
  210030. + dev_err(&ldb->pdev->dev, "fail to set ldb_di clk as"
  210031. + "the parent of ipu_di clk\n");
  210032. + return ret;
  210033. + }
  210034. +
  210035. + if ((ldb->mode == LDB_SPL_DI0) || (ldb->mode == LDB_SPL_DI1)) {
  210036. + ret = clk_set_parent(ldb->setting[setting_idx].div_sel_clk,
  210037. + ldb->setting[setting_idx].div_3_5_clk);
  210038. + if (ret) {
  210039. + dev_err(&ldb->pdev->dev, "fail to set div 3.5 clk as"
  210040. + "the parent of div sel clk\n");
  210041. + return ret;
  210042. + }
  210043. + } else {
  210044. + ret = clk_set_parent(ldb->setting[setting_idx].div_sel_clk,
  210045. + ldb->setting[setting_idx].div_7_clk);
  210046. + if (ret) {
  210047. + dev_err(&ldb->pdev->dev, "fail to set div 7 clk as"
  210048. + "the parent of div sel clk\n");
  210049. + return ret;
  210050. + }
  210051. + }
  210052. +
  210053. + /* save active ldb setting for fb notifier */
  210054. + ldb->setting[setting_idx].active = true;
  210055. +
  210056. + ldb->inited = true;
  210057. + return ret;
  210058. +}
  210059. +
  210060. +static void ldb_disp_deinit(struct mxc_dispdrv_handle *disp)
  210061. +{
  210062. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  210063. + int i;
  210064. +
  210065. + writel(0, ldb->control_reg);
  210066. +
  210067. + for (i = 0; i < 2; i++) {
  210068. + clk_disable(ldb->setting[i].ldb_di_clk);
  210069. + clk_put(ldb->setting[i].ldb_di_clk);
  210070. + clk_put(ldb->setting[i].div_3_5_clk);
  210071. + clk_put(ldb->setting[i].div_7_clk);
  210072. + clk_put(ldb->setting[i].div_sel_clk);
  210073. + }
  210074. +
  210075. + fb_unregister_client(&ldb->nb);
  210076. +}
  210077. +
  210078. +static struct mxc_dispdrv_driver ldb_drv = {
  210079. + .name = DISPDRV_LDB,
  210080. + .init = ldb_disp_init,
  210081. + .post_init = ldb_post_disp_init,
  210082. + .deinit = ldb_disp_deinit,
  210083. + .setup = ldb_disp_setup,
  210084. +};
  210085. +
  210086. +static int ldb_suspend(struct platform_device *pdev, pm_message_t state)
  210087. +{
  210088. + struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);
  210089. + uint32_t data;
  210090. +
  210091. + if (!ldb->inited)
  210092. + return 0;
  210093. + data = readl(ldb->control_reg);
  210094. + ldb->control_reg_data = data;
  210095. + data &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
  210096. + writel(data, ldb->control_reg);
  210097. +
  210098. + return 0;
  210099. +}
  210100. +
  210101. +static int ldb_resume(struct platform_device *pdev)
  210102. +{
  210103. + struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);
  210104. +
  210105. + if (!ldb->inited)
  210106. + return 0;
  210107. + writel(ldb->control_reg_data, ldb->control_reg);
  210108. +
  210109. + return 0;
  210110. +}
  210111. +
  210112. +static struct platform_device_id imx_ldb_devtype[] = {
  210113. + {
  210114. + .name = "ldb-imx6",
  210115. + .driver_data = LDB_IMX6,
  210116. + }, {
  210117. + /* sentinel */
  210118. + }
  210119. +};
  210120. +
  210121. +static const struct of_device_id imx_ldb_dt_ids[] = {
  210122. + { .compatible = "fsl,imx6q-ldb", .data = &imx_ldb_devtype[IMX6_LDB],},
  210123. + { /* sentinel */ }
  210124. +};
  210125. +
  210126. +/*!
  210127. + * This function is called by the driver framework to initialize the LDB
  210128. + * device.
  210129. + *
  210130. + * @param dev The device structure for the LDB passed in by the
  210131. + * driver framework.
  210132. + *
  210133. + * @return Returns 0 on success or negative error code on error
  210134. + */
  210135. +static int ldb_probe(struct platform_device *pdev)
  210136. +{
  210137. + int ret = 0;
  210138. + struct ldb_data *ldb;
  210139. + struct fsl_mxc_ldb_platform_data *plat_data;
  210140. + const struct of_device_id *of_id =
  210141. + of_match_device(imx_ldb_dt_ids, &pdev->dev);
  210142. +
  210143. + dev_dbg(&pdev->dev, "%s enter\n", __func__);
  210144. + ldb = devm_kzalloc(&pdev->dev, sizeof(struct ldb_data), GFP_KERNEL);
  210145. + if (!ldb)
  210146. + return -ENOMEM;
  210147. +
  210148. + plat_data = devm_kzalloc(&pdev->dev,
  210149. + sizeof(struct fsl_mxc_ldb_platform_data),
  210150. + GFP_KERNEL);
  210151. + if (!plat_data)
  210152. + return -ENOMEM;
  210153. + pdev->dev.platform_data = plat_data;
  210154. + if (of_id)
  210155. + pdev->id_entry = of_id->data;
  210156. + plat_data->devtype = pdev->id_entry->driver_data;
  210157. +
  210158. + ret = ldb_get_of_property(pdev, plat_data);
  210159. + if (ret < 0) {
  210160. + dev_err(&pdev->dev, "get ldb of property fail\n");
  210161. + return ret;
  210162. + }
  210163. +
  210164. + ldb->pdev = pdev;
  210165. + ldb->disp_ldb = mxc_dispdrv_register(&ldb_drv);
  210166. + mxc_dispdrv_setdata(ldb->disp_ldb, ldb);
  210167. +
  210168. + dev_set_drvdata(&pdev->dev, ldb);
  210169. +
  210170. + dev_dbg(&pdev->dev, "%s exit\n", __func__);
  210171. + return ret;
  210172. +}
  210173. +
  210174. +static int ldb_remove(struct platform_device *pdev)
  210175. +{
  210176. + struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);
  210177. +
  210178. + if (!ldb->inited)
  210179. + return 0;
  210180. + mxc_dispdrv_puthandle(ldb->disp_ldb);
  210181. + mxc_dispdrv_unregister(ldb->disp_ldb);
  210182. + return 0;
  210183. +}
  210184. +
  210185. +static struct platform_driver mxcldb_driver = {
  210186. + .driver = {
  210187. + .name = "mxc_ldb",
  210188. + .of_match_table = imx_ldb_dt_ids,
  210189. + },
  210190. + .probe = ldb_probe,
  210191. + .remove = ldb_remove,
  210192. + .suspend = ldb_suspend,
  210193. + .resume = ldb_resume,
  210194. +};
  210195. +
  210196. +static int __init ldb_init(void)
  210197. +{
  210198. + return platform_driver_register(&mxcldb_driver);
  210199. +}
  210200. +
  210201. +static void __exit ldb_uninit(void)
  210202. +{
  210203. + platform_driver_unregister(&mxcldb_driver);
  210204. +}
  210205. +
  210206. +module_init(ldb_init);
  210207. +module_exit(ldb_uninit);
  210208. +
  210209. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  210210. +MODULE_DESCRIPTION("MXC LDB driver");
  210211. +MODULE_LICENSE("GPL");
  210212. diff -Nur linux-3.14.15/drivers/video/mxc/Makefile linux-linaro-stable-mx6/drivers/video/mxc/Makefile
  210213. --- linux-3.14.15/drivers/video/mxc/Makefile 1970-01-01 01:00:00.000000000 +0100
  210214. +++ linux-linaro-stable-mx6/drivers/video/mxc/Makefile 2014-08-20 19:31:50.020885713 +0200
  210215. @@ -0,0 +1,6 @@
  210216. +obj-$(CONFIG_FB_MXC_LDB) += ldb.o
  210217. +obj-$(CONFIG_FB_MXC_MIPI_DSI) += mipi_dsi.o
  210218. +obj-$(CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL) += mxcfb_hx8369_wvga.o
  210219. +obj-$(CONFIG_FB_MXC_HDMI) += mxc_hdmi.o
  210220. +obj-$(CONFIG_FB_MXC_EDID) += mxc_edid.o
  210221. +obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxc_dispdrv.o mxc_lcdif.o mxc_ipuv3_fb.o
  210222. diff -Nur linux-3.14.15/drivers/video/mxc/mipi_dsi.c linux-linaro-stable-mx6/drivers/video/mxc/mipi_dsi.c
  210223. --- linux-3.14.15/drivers/video/mxc/mipi_dsi.c 1970-01-01 01:00:00.000000000 +0100
  210224. +++ linux-linaro-stable-mx6/drivers/video/mxc/mipi_dsi.c 2014-08-20 19:23:58.566867220 +0200
  210225. @@ -0,0 +1,953 @@
  210226. +/*
  210227. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  210228. + *
  210229. + * This program is free software; you can redistribute it and/or modify
  210230. + * it under the terms of the GNU General Public License as published by
  210231. + * the Free Software Foundation; either version 2 of the License, or
  210232. + * (at your option) any later version.
  210233. +
  210234. + * This program is distributed in the hope that it will be useful,
  210235. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  210236. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  210237. + * GNU General Public License for more details.
  210238. +
  210239. + * You should have received a copy of the GNU General Public License along
  210240. + * with this program; if not, write to the Free Software Foundation, Inc.,
  210241. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  210242. + */
  210243. +
  210244. +#include <linux/types.h>
  210245. +#include <linux/init.h>
  210246. +#include <linux/platform_device.h>
  210247. +#include <linux/err.h>
  210248. +#include <linux/clk.h>
  210249. +#include <linux/console.h>
  210250. +#include <linux/io.h>
  210251. +#include <linux/bitops.h>
  210252. +#include <linux/ipu.h>
  210253. +#include <linux/mfd/syscon.h>
  210254. +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  210255. +#include <linux/mipi_dsi.h>
  210256. +#include <linux/module.h>
  210257. +#include <linux/mxcfb.h>
  210258. +#include <linux/backlight.h>
  210259. +#include <linux/of_device.h>
  210260. +#include <linux/regulator/consumer.h>
  210261. +#include <linux/reset.h>
  210262. +#include <linux/spinlock.h>
  210263. +#include <linux/delay.h>
  210264. +#include <video/mipi_display.h>
  210265. +
  210266. +#include "mxc_dispdrv.h"
  210267. +#include "mipi_dsi.h"
  210268. +
  210269. +#define DISPDRV_MIPI "mipi_dsi"
  210270. +#define ROUND_UP(x) ((x)+1)
  210271. +#define NS2PS_RATIO (1000)
  210272. +#define NUMBER_OF_CHUNKS (0x8)
  210273. +#define NULL_PKT_SIZE (0x8)
  210274. +#define PHY_BTA_MAXTIME (0xd00)
  210275. +#define PHY_LP2HS_MAXTIME (0x40)
  210276. +#define PHY_HS2LP_MAXTIME (0x40)
  210277. +#define PHY_STOP_WAIT_TIME (0x20)
  210278. +#define DSI_CLKMGR_CFG_CLK_DIV (0x107)
  210279. +#define DSI_GEN_PLD_DATA_BUF_ENTRY (0x10)
  210280. +#define MIPI_MUX_CTRL(v) (((v) & 0x3) << 4)
  210281. +#define MIPI_LCD_SLEEP_MODE_DELAY (120)
  210282. +#define MIPI_DSI_REG_RW_TIMEOUT (20)
  210283. +#define MIPI_DSI_PHY_TIMEOUT (10)
  210284. +
  210285. +static struct mipi_dsi_match_lcd mipi_dsi_lcd_db[] = {
  210286. +#ifdef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
  210287. + {
  210288. + "TRULY-WVGA",
  210289. + {mipid_hx8369_get_lcd_videomode, mipid_hx8369_lcd_setup}
  210290. + },
  210291. +#endif
  210292. + {
  210293. + "", {NULL, NULL}
  210294. + }
  210295. +};
  210296. +
  210297. +struct _mipi_dsi_phy_pll_clk {
  210298. + u32 max_phy_clk;
  210299. + u32 config;
  210300. +};
  210301. +
  210302. +/* configure data for DPHY PLL 27M reference clk out */
  210303. +static const struct _mipi_dsi_phy_pll_clk mipi_dsi_phy_pll_clk_table[] = {
  210304. + {1000, 0x74}, /* 950-1000MHz */
  210305. + {950, 0x54}, /* 900-950Mhz */
  210306. + {900, 0x34}, /* 850-900Mhz */
  210307. + {850, 0x14}, /* 800-850MHz */
  210308. + {800, 0x32}, /* 750-800MHz */
  210309. + {750, 0x12}, /* 700-750Mhz */
  210310. + {700, 0x30}, /* 650-700Mhz */
  210311. + {650, 0x10}, /* 600-650MHz */
  210312. + {600, 0x2e}, /* 550-600MHz */
  210313. + {550, 0x0e}, /* 500-550Mhz */
  210314. + {500, 0x2c}, /* 450-500Mhz */
  210315. + {450, 0x0c}, /* 400-450MHz */
  210316. + {400, 0x4a}, /* 360-400MHz */
  210317. + {360, 0x2a}, /* 330-360Mhz */
  210318. + {330, 0x48}, /* 300-330Mhz */
  210319. + {300, 0x28}, /* 270-300MHz */
  210320. + {270, 0x08}, /* 250-270MHz */
  210321. + {250, 0x46}, /* 240-250Mhz */
  210322. + {240, 0x26}, /* 210-240Mhz */
  210323. + {210, 0x06}, /* 200-210MHz */
  210324. + {200, 0x44}, /* 180-200MHz */
  210325. + {180, 0x24}, /* 160-180MHz */
  210326. + {160, 0x04}, /* 150-160MHz */
  210327. +};
  210328. +
  210329. +static int valid_mode(int pixel_fmt)
  210330. +{
  210331. + return ((pixel_fmt == IPU_PIX_FMT_RGB24) ||
  210332. + (pixel_fmt == IPU_PIX_FMT_BGR24) ||
  210333. + (pixel_fmt == IPU_PIX_FMT_RGB666) ||
  210334. + (pixel_fmt == IPU_PIX_FMT_RGB565) ||
  210335. + (pixel_fmt == IPU_PIX_FMT_BGR666) ||
  210336. + (pixel_fmt == IPU_PIX_FMT_RGB332));
  210337. +}
  210338. +
  210339. +static inline void mipi_dsi_read_register(struct mipi_dsi_info *mipi_dsi,
  210340. + u32 reg, u32 *val)
  210341. +{
  210342. + *val = ioread32(mipi_dsi->mmio_base + reg);
  210343. + dev_dbg(&mipi_dsi->pdev->dev, "read_reg:0x%02x, val:0x%08x.\n",
  210344. + reg, *val);
  210345. +}
  210346. +
  210347. +static inline void mipi_dsi_write_register(struct mipi_dsi_info *mipi_dsi,
  210348. + u32 reg, u32 val)
  210349. +{
  210350. + iowrite32(val, mipi_dsi->mmio_base + reg);
  210351. + dev_dbg(&mipi_dsi->pdev->dev, "\t\twrite_reg:0x%02x, val:0x%08x.\n",
  210352. + reg, val);
  210353. +}
  210354. +
  210355. +int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi_dsi,
  210356. + u8 data_type, const u32 *buf, int len)
  210357. +{
  210358. + u32 val;
  210359. + u32 status = 0;
  210360. + int write_len = len;
  210361. + uint32_t timeout = 0;
  210362. +
  210363. + if (len) {
  210364. + /* generic long write command */
  210365. + while (len / DSI_GEN_PLD_DATA_BUF_SIZE) {
  210366. + mipi_dsi_write_register(mipi_dsi,
  210367. + MIPI_DSI_GEN_PLD_DATA, *buf);
  210368. + buf++;
  210369. + len -= DSI_GEN_PLD_DATA_BUF_SIZE;
  210370. + mipi_dsi_read_register(mipi_dsi,
  210371. + MIPI_DSI_CMD_PKT_STATUS, &status);
  210372. + while ((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) ==
  210373. + DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) {
  210374. + msleep(1);
  210375. + timeout++;
  210376. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  210377. + return -EIO;
  210378. + mipi_dsi_read_register(mipi_dsi,
  210379. + MIPI_DSI_CMD_PKT_STATUS, &status);
  210380. + }
  210381. + }
  210382. + /* write the remainder bytes */
  210383. + if (len > 0) {
  210384. + while ((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) ==
  210385. + DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) {
  210386. + msleep(1);
  210387. + timeout++;
  210388. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  210389. + return -EIO;
  210390. + mipi_dsi_read_register(mipi_dsi,
  210391. + MIPI_DSI_CMD_PKT_STATUS, &status);
  210392. + }
  210393. + mipi_dsi_write_register(mipi_dsi,
  210394. + MIPI_DSI_GEN_PLD_DATA, *buf);
  210395. + }
  210396. +
  210397. + val = data_type | ((write_len & DSI_GEN_HDR_DATA_MASK)
  210398. + << DSI_GEN_HDR_DATA_SHIFT);
  210399. + } else {
  210400. + /* generic short write command */
  210401. + val = data_type | ((*buf & DSI_GEN_HDR_DATA_MASK)
  210402. + << DSI_GEN_HDR_DATA_SHIFT);
  210403. + }
  210404. +
  210405. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &status);
  210406. + while ((status & DSI_CMD_PKT_STATUS_GEN_CMD_FULL) ==
  210407. + DSI_CMD_PKT_STATUS_GEN_CMD_FULL) {
  210408. + msleep(1);
  210409. + timeout++;
  210410. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  210411. + return -EIO;
  210412. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  210413. + &status);
  210414. + }
  210415. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_GEN_HDR, val);
  210416. +
  210417. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &status);
  210418. + while (!((status & DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY) ==
  210419. + DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY) ||
  210420. + !((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY) ==
  210421. + DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY)) {
  210422. + msleep(1);
  210423. + timeout++;
  210424. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  210425. + return -EIO;
  210426. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  210427. + &status);
  210428. + }
  210429. +
  210430. + return 0;
  210431. +}
  210432. +
  210433. +int mipi_dsi_pkt_read(struct mipi_dsi_info *mipi_dsi,
  210434. + u8 data_type, u32 *buf, int len)
  210435. +{
  210436. + u32 val;
  210437. + int read_len = 0;
  210438. + uint32_t timeout = 0;
  210439. +
  210440. + if (!len) {
  210441. + mipi_dbg("%s, len = 0 invalid error!\n", __func__);
  210442. + return -EINVAL;
  210443. + }
  210444. +
  210445. + val = data_type | ((*buf & DSI_GEN_HDR_DATA_MASK)
  210446. + << DSI_GEN_HDR_DATA_SHIFT);
  210447. + memset(buf, 0, len);
  210448. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_GEN_HDR, val);
  210449. +
  210450. + /* wait for cmd to sent out */
  210451. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &val);
  210452. + while ((val & DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) !=
  210453. + DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) {
  210454. + msleep(1);
  210455. + timeout++;
  210456. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  210457. + return -EIO;
  210458. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  210459. + &val);
  210460. + }
  210461. + /* wait for entire response stroed in FIFO */
  210462. + while ((val & DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) ==
  210463. + DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) {
  210464. + msleep(1);
  210465. + timeout++;
  210466. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  210467. + return -EIO;
  210468. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  210469. + &val);
  210470. + }
  210471. +
  210472. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &val);
  210473. + while (!(val & DSI_CMD_PKT_STATUS_GEN_PLD_R_EMPTY)) {
  210474. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_GEN_PLD_DATA, buf);
  210475. + read_len += DSI_GEN_PLD_DATA_BUF_SIZE;
  210476. + buf++;
  210477. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  210478. + &val);
  210479. + if (read_len == (DSI_GEN_PLD_DATA_BUF_ENTRY *
  210480. + DSI_GEN_PLD_DATA_BUF_SIZE))
  210481. + break;
  210482. + }
  210483. +
  210484. + if ((len <= read_len) &&
  210485. + ((len + DSI_GEN_PLD_DATA_BUF_SIZE) >= read_len))
  210486. + return 0;
  210487. + else {
  210488. + dev_err(&mipi_dsi->pdev->dev,
  210489. + "actually read_len:%d != len:%d.\n", read_len, len);
  210490. + return -ERANGE;
  210491. + }
  210492. +}
  210493. +
  210494. +int mipi_dsi_dcs_cmd(struct mipi_dsi_info *mipi_dsi,
  210495. + u8 cmd, const u32 *param, int num)
  210496. +{
  210497. + int err = 0;
  210498. + u32 buf[DSI_CMD_BUF_MAXSIZE];
  210499. +
  210500. + switch (cmd) {
  210501. + case MIPI_DCS_EXIT_SLEEP_MODE:
  210502. + case MIPI_DCS_ENTER_SLEEP_MODE:
  210503. + case MIPI_DCS_SET_DISPLAY_ON:
  210504. + case MIPI_DCS_SET_DISPLAY_OFF:
  210505. + buf[0] = cmd;
  210506. + err = mipi_dsi_pkt_write(mipi_dsi,
  210507. + MIPI_DSI_DCS_SHORT_WRITE, buf, 0);
  210508. + break;
  210509. +
  210510. + default:
  210511. + dev_err(&mipi_dsi->pdev->dev,
  210512. + "MIPI DSI DCS Command:0x%x Not supported!\n", cmd);
  210513. + break;
  210514. + }
  210515. +
  210516. + return err;
  210517. +}
  210518. +
  210519. +static void mipi_dsi_dphy_init(struct mipi_dsi_info *mipi_dsi,
  210520. + u32 cmd, u32 data)
  210521. +{
  210522. + u32 val;
  210523. + u32 timeout = 0;
  210524. +
  210525. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
  210526. + DSI_PHY_IF_CTRL_RESET);
  210527. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP, DSI_PWRUP_POWERUP);
  210528. +
  210529. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
  210530. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL1,
  210531. + (0x10000 | cmd));
  210532. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 2);
  210533. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
  210534. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL1, (0 | data));
  210535. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 2);
  210536. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
  210537. + val = DSI_PHY_RSTZ_EN_CLK | DSI_PHY_RSTZ_DISABLE_RST |
  210538. + DSI_PHY_RSTZ_DISABLE_SHUTDOWN;
  210539. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ, val);
  210540. +
  210541. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
  210542. + while ((val & DSI_PHY_STATUS_LOCK) != DSI_PHY_STATUS_LOCK) {
  210543. + msleep(1);
  210544. + timeout++;
  210545. + if (timeout == MIPI_DSI_PHY_TIMEOUT) {
  210546. + dev_err(&mipi_dsi->pdev->dev,
  210547. + "Error: phy lock timeout!\n");
  210548. + break;
  210549. + }
  210550. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
  210551. + }
  210552. + timeout = 0;
  210553. + while ((val & DSI_PHY_STATUS_STOPSTATE_CLK_LANE) !=
  210554. + DSI_PHY_STATUS_STOPSTATE_CLK_LANE) {
  210555. + msleep(1);
  210556. + timeout++;
  210557. + if (timeout == MIPI_DSI_PHY_TIMEOUT) {
  210558. + dev_err(&mipi_dsi->pdev->dev,
  210559. + "Error: phy lock lane timeout!\n");
  210560. + break;
  210561. + }
  210562. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
  210563. + }
  210564. +}
  210565. +
  210566. +static void mipi_dsi_enable_controller(struct mipi_dsi_info *mipi_dsi,
  210567. + bool init)
  210568. +{
  210569. + u32 val;
  210570. + u32 lane_byte_clk_period;
  210571. + struct fb_videomode *mode = mipi_dsi->mode;
  210572. + struct mipi_lcd_config *lcd_config = mipi_dsi->lcd_config;
  210573. +
  210574. + if (init) {
  210575. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  210576. + DSI_PWRUP_RESET);
  210577. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ,
  210578. + DSI_PHY_RSTZ_RST);
  210579. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CLKMGR_CFG,
  210580. + DSI_CLKMGR_CFG_CLK_DIV);
  210581. +
  210582. + if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
  210583. + val = DSI_DPI_CFG_VSYNC_ACT_LOW;
  210584. + if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
  210585. + val |= DSI_DPI_CFG_HSYNC_ACT_LOW;
  210586. + if ((mode->sync & FB_SYNC_OE_LOW_ACT))
  210587. + val |= DSI_DPI_CFG_DATAEN_ACT_LOW;
  210588. + if (MIPI_RGB666_LOOSELY == lcd_config->dpi_fmt)
  210589. + val |= DSI_DPI_CFG_EN18LOOSELY;
  210590. + val |= (lcd_config->dpi_fmt & DSI_DPI_CFG_COLORCODE_MASK)
  210591. + << DSI_DPI_CFG_COLORCODE_SHIFT;
  210592. + val |= (lcd_config->virtual_ch & DSI_DPI_CFG_VID_MASK)
  210593. + << DSI_DPI_CFG_VID_SHIFT;
  210594. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_DPI_CFG, val);
  210595. +
  210596. + val = DSI_PCKHDL_CFG_EN_BTA |
  210597. + DSI_PCKHDL_CFG_EN_ECC_RX |
  210598. + DSI_PCKHDL_CFG_EN_CRC_RX;
  210599. +
  210600. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PCKHDL_CFG, val);
  210601. +
  210602. + val = (mode->xres & DSI_VID_PKT_CFG_VID_PKT_SZ_MASK)
  210603. + << DSI_VID_PKT_CFG_VID_PKT_SZ_SHIFT;
  210604. + val |= (NUMBER_OF_CHUNKS & DSI_VID_PKT_CFG_NUM_CHUNKS_MASK)
  210605. + << DSI_VID_PKT_CFG_NUM_CHUNKS_SHIFT;
  210606. + val |= (NULL_PKT_SIZE & DSI_VID_PKT_CFG_NULL_PKT_SZ_MASK)
  210607. + << DSI_VID_PKT_CFG_NULL_PKT_SZ_SHIFT;
  210608. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_PKT_CFG, val);
  210609. +
  210610. + /* enable LP mode when TX DCS cmd and enable DSI command mode */
  210611. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG,
  210612. + MIPI_DSI_CMD_MODE_CFG_EN_LOWPOWER);
  210613. +
  210614. + /* mipi lane byte clk period in ns unit */
  210615. + lane_byte_clk_period = NS2PS_RATIO /
  210616. + (lcd_config->max_phy_clk / BITS_PER_BYTE);
  210617. + val = ROUND_UP(mode->hsync_len * mode->pixclock /
  210618. + NS2PS_RATIO / lane_byte_clk_period)
  210619. + << DSI_TME_LINE_CFG_HSA_TIME_SHIFT;
  210620. + val |= ROUND_UP(mode->left_margin * mode->pixclock /
  210621. + NS2PS_RATIO / lane_byte_clk_period)
  210622. + << DSI_TME_LINE_CFG_HBP_TIME_SHIFT;
  210623. + val |= ROUND_UP((mode->left_margin + mode->right_margin +
  210624. + mode->hsync_len + mode->xres) * mode->pixclock
  210625. + / NS2PS_RATIO / lane_byte_clk_period)
  210626. + << DSI_TME_LINE_CFG_HLINE_TIME_SHIFT;
  210627. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_TMR_LINE_CFG, val);
  210628. +
  210629. + val = ((mode->vsync_len & DSI_VTIMING_CFG_VSA_LINES_MASK)
  210630. + << DSI_VTIMING_CFG_VSA_LINES_SHIFT);
  210631. + val |= ((mode->upper_margin & DSI_VTIMING_CFG_VBP_LINES_MASK)
  210632. + << DSI_VTIMING_CFG_VBP_LINES_SHIFT);
  210633. + val |= ((mode->lower_margin & DSI_VTIMING_CFG_VFP_LINES_MASK)
  210634. + << DSI_VTIMING_CFG_VFP_LINES_SHIFT);
  210635. + val |= ((mode->yres & DSI_VTIMING_CFG_V_ACT_LINES_MASK)
  210636. + << DSI_VTIMING_CFG_V_ACT_LINES_SHIFT);
  210637. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VTIMING_CFG, val);
  210638. +
  210639. + val = ((PHY_BTA_MAXTIME & DSI_PHY_TMR_CFG_BTA_TIME_MASK)
  210640. + << DSI_PHY_TMR_CFG_BTA_TIME_SHIFT);
  210641. + val |= ((PHY_LP2HS_MAXTIME & DSI_PHY_TMR_CFG_LP2HS_TIME_MASK)
  210642. + << DSI_PHY_TMR_CFG_LP2HS_TIME_SHIFT);
  210643. + val |= ((PHY_HS2LP_MAXTIME & DSI_PHY_TMR_CFG_HS2LP_TIME_MASK)
  210644. + << DSI_PHY_TMR_CFG_HS2LP_TIME_SHIFT);
  210645. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TMR_CFG, val);
  210646. +
  210647. + val = (((lcd_config->data_lane_num - 1) &
  210648. + DSI_PHY_IF_CFG_N_LANES_MASK)
  210649. + << DSI_PHY_IF_CFG_N_LANES_SHIFT);
  210650. + val |= ((PHY_STOP_WAIT_TIME & DSI_PHY_IF_CFG_WAIT_TIME_MASK)
  210651. + << DSI_PHY_IF_CFG_WAIT_TIME_SHIFT);
  210652. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CFG, val);
  210653. +
  210654. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST0, &val);
  210655. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST1, &val);
  210656. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_ERROR_MSK0, 0);
  210657. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_ERROR_MSK1, 0);
  210658. +
  210659. + mipi_dsi_dphy_init(mipi_dsi, DSI_PHY_CLK_INIT_COMMAND,
  210660. + mipi_dsi->dphy_pll_config);
  210661. + } else {
  210662. + mipi_dsi_dphy_init(mipi_dsi, DSI_PHY_CLK_INIT_COMMAND,
  210663. + mipi_dsi->dphy_pll_config);
  210664. + }
  210665. +}
  210666. +
  210667. +static void mipi_dsi_disable_controller(struct mipi_dsi_info *mipi_dsi)
  210668. +{
  210669. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
  210670. + DSI_PHY_IF_CTRL_RESET);
  210671. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP, DSI_PWRUP_RESET);
  210672. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ, DSI_PHY_RSTZ_RST);
  210673. +}
  210674. +
  210675. +static irqreturn_t mipi_dsi_irq_handler(int irq, void *data)
  210676. +{
  210677. + u32 mask0;
  210678. + u32 mask1;
  210679. + u32 status0;
  210680. + u32 status1;
  210681. + struct mipi_dsi_info *mipi_dsi;
  210682. +
  210683. + mipi_dsi = (struct mipi_dsi_info *)data;
  210684. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST0, &status0);
  210685. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST1, &status1);
  210686. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_MSK0, &mask0);
  210687. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_MSK1, &mask1);
  210688. +
  210689. + if ((status0 & (~mask0)) || (status1 & (~mask1))) {
  210690. + dev_err(&mipi_dsi->pdev->dev,
  210691. + "mipi_dsi IRQ status0:0x%x, status1:0x%x!\n",
  210692. + status0, status1);
  210693. + }
  210694. +
  210695. + return IRQ_HANDLED;
  210696. +}
  210697. +
  210698. +static inline void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,
  210699. + bool cmd_mode)
  210700. +{
  210701. + u32 val;
  210702. +
  210703. + if (cmd_mode) {
  210704. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  210705. + DSI_PWRUP_RESET);
  210706. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
  210707. + val |= MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
  210708. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
  210709. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, 0);
  210710. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  210711. + DSI_PWRUP_POWERUP);
  210712. + } else {
  210713. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  210714. + DSI_PWRUP_RESET);
  210715. + /* Disable Command mode when tranfering video data */
  210716. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
  210717. + val &= ~MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
  210718. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
  210719. + val = DSI_VID_MODE_CFG_EN | DSI_VID_MODE_CFG_EN_BURSTMODE |
  210720. + DSI_VID_MODE_CFG_EN_LP_MODE;
  210721. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, val);
  210722. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  210723. + DSI_PWRUP_POWERUP);
  210724. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
  210725. + DSI_PHY_IF_CTRL_TX_REQ_CLK_HS);
  210726. + }
  210727. +}
  210728. +
  210729. +static int mipi_dsi_power_on(struct mxc_dispdrv_handle *disp)
  210730. +{
  210731. + int err;
  210732. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  210733. +
  210734. + if (!mipi_dsi->dsi_power_on) {
  210735. + clk_prepare_enable(mipi_dsi->dphy_clk);
  210736. + clk_prepare_enable(mipi_dsi->cfg_clk);
  210737. + mipi_dsi_enable_controller(mipi_dsi, false);
  210738. + mipi_dsi_set_mode(mipi_dsi, false);
  210739. + /* host send pclk/hsync/vsync for two frames before sleep-out */
  210740. + msleep((1000/mipi_dsi->mode->refresh + 1) << 1);
  210741. + mipi_dsi_set_mode(mipi_dsi, true);
  210742. + err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_EXIT_SLEEP_MODE,
  210743. + NULL, 0);
  210744. + if (err) {
  210745. + dev_err(&mipi_dsi->pdev->dev,
  210746. + "MIPI DSI DCS Command sleep-in error!\n");
  210747. + }
  210748. + msleep(MIPI_LCD_SLEEP_MODE_DELAY);
  210749. + mipi_dsi_set_mode(mipi_dsi, false);
  210750. + mipi_dsi->dsi_power_on = 1;
  210751. + }
  210752. +
  210753. + return 0;
  210754. +}
  210755. +
  210756. +void mipi_dsi_power_off(struct mxc_dispdrv_handle *disp)
  210757. +{
  210758. + int err;
  210759. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  210760. +
  210761. + if (mipi_dsi->dsi_power_on) {
  210762. + mipi_dsi_set_mode(mipi_dsi, true);
  210763. + err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_ENTER_SLEEP_MODE,
  210764. + NULL, 0);
  210765. + if (err) {
  210766. + dev_err(&mipi_dsi->pdev->dev,
  210767. + "MIPI DSI DCS Command display on error!\n");
  210768. + }
  210769. + /* To allow time for the supply voltages
  210770. + * and clock circuits to stabilize.
  210771. + */
  210772. + msleep(5);
  210773. + /* video stream timing on */
  210774. + mipi_dsi_set_mode(mipi_dsi, false);
  210775. + msleep(MIPI_LCD_SLEEP_MODE_DELAY);
  210776. +
  210777. + mipi_dsi_set_mode(mipi_dsi, true);
  210778. + mipi_dsi_disable_controller(mipi_dsi);
  210779. + mipi_dsi->dsi_power_on = 0;
  210780. + clk_disable_unprepare(mipi_dsi->dphy_clk);
  210781. + clk_disable_unprepare(mipi_dsi->cfg_clk);
  210782. + }
  210783. +}
  210784. +
  210785. +static int mipi_dsi_lcd_init(struct mipi_dsi_info *mipi_dsi,
  210786. + struct mxc_dispdrv_setting *setting)
  210787. +{
  210788. + int err;
  210789. + int size;
  210790. + int i;
  210791. + struct fb_videomode *mipi_lcd_modedb;
  210792. + struct fb_videomode mode;
  210793. + struct device *dev = &mipi_dsi->pdev->dev;
  210794. +
  210795. + for (i = 0; i < ARRAY_SIZE(mipi_dsi_lcd_db); i++) {
  210796. + if (!strcmp(mipi_dsi->lcd_panel,
  210797. + mipi_dsi_lcd_db[i].lcd_panel)) {
  210798. + mipi_dsi->lcd_callback =
  210799. + &mipi_dsi_lcd_db[i].lcd_callback;
  210800. + break;
  210801. + }
  210802. + }
  210803. + if (i == ARRAY_SIZE(mipi_dsi_lcd_db)) {
  210804. + dev_err(dev, "failed to find supported lcd panel.\n");
  210805. + return -EINVAL;
  210806. + }
  210807. + /* get the videomode in the order: cmdline->platform data->driver */
  210808. + mipi_dsi->lcd_callback->get_mipi_lcd_videomode(&mipi_lcd_modedb, &size,
  210809. + &mipi_dsi->lcd_config);
  210810. + err = fb_find_mode(&setting->fbi->var, setting->fbi,
  210811. + setting->dft_mode_str,
  210812. + mipi_lcd_modedb, size, NULL,
  210813. + setting->default_bpp);
  210814. + if (err != 1)
  210815. + fb_videomode_to_var(&setting->fbi->var, mipi_lcd_modedb);
  210816. +
  210817. + INIT_LIST_HEAD(&setting->fbi->modelist);
  210818. + for (i = 0; i < size; i++) {
  210819. + fb_var_to_videomode(&mode, &setting->fbi->var);
  210820. + if (fb_mode_is_equal(&mode, mipi_lcd_modedb + i)) {
  210821. + err = fb_add_videomode(mipi_lcd_modedb + i,
  210822. + &setting->fbi->modelist);
  210823. + /* Note: only support fb mode from driver */
  210824. + mipi_dsi->mode = mipi_lcd_modedb + i;
  210825. + break;
  210826. + }
  210827. + }
  210828. + if ((err < 0) || (size == i)) {
  210829. + dev_err(dev, "failed to add videomode.\n");
  210830. + return err;
  210831. + }
  210832. +
  210833. + for (i = 0; i < ARRAY_SIZE(mipi_dsi_phy_pll_clk_table); i++) {
  210834. + if (mipi_dsi_phy_pll_clk_table[i].max_phy_clk <
  210835. + mipi_dsi->lcd_config->max_phy_clk)
  210836. + break;
  210837. + }
  210838. + if ((i == ARRAY_SIZE(mipi_dsi_phy_pll_clk_table)) ||
  210839. + (mipi_dsi->lcd_config->max_phy_clk >
  210840. + mipi_dsi_phy_pll_clk_table[0].max_phy_clk)) {
  210841. + dev_err(dev, "failed to find data in"
  210842. + "mipi_dsi_phy_pll_clk_table.\n");
  210843. + return -EINVAL;
  210844. + }
  210845. + mipi_dsi->dphy_pll_config = mipi_dsi_phy_pll_clk_table[--i].config;
  210846. + dev_dbg(dev, "dphy_pll_config:0x%x.\n", mipi_dsi->dphy_pll_config);
  210847. +
  210848. + return 0;
  210849. +}
  210850. +
  210851. +int mipi_dsi_enable(struct mxc_dispdrv_handle *disp)
  210852. +{
  210853. + int err;
  210854. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  210855. +
  210856. + if (!mipi_dsi->lcd_inited) {
  210857. + err = clk_prepare_enable(mipi_dsi->dphy_clk);
  210858. + err |= clk_prepare_enable(mipi_dsi->cfg_clk);
  210859. + if (err)
  210860. + dev_err(&mipi_dsi->pdev->dev,
  210861. + "clk enable error:%d!\n", err);
  210862. + mipi_dsi_enable_controller(mipi_dsi, true);
  210863. + err = mipi_dsi->lcd_callback->mipi_lcd_setup(
  210864. + mipi_dsi);
  210865. + if (err < 0) {
  210866. + dev_err(&mipi_dsi->pdev->dev,
  210867. + "failed to init mipi lcd.");
  210868. + clk_disable_unprepare(mipi_dsi->dphy_clk);
  210869. + clk_disable_unprepare(mipi_dsi->cfg_clk);
  210870. + return err;
  210871. + }
  210872. + mipi_dsi_set_mode(mipi_dsi, false);
  210873. + mipi_dsi->dsi_power_on = 1;
  210874. + mipi_dsi->lcd_inited = 1;
  210875. + }
  210876. + mipi_dsi_power_on(mipi_dsi->disp_mipi);
  210877. +
  210878. + return 0;
  210879. +}
  210880. +
  210881. +static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
  210882. + struct mxc_dispdrv_setting *setting)
  210883. +{
  210884. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  210885. + struct device *dev = &mipi_dsi->pdev->dev;
  210886. + int ret = 0;
  210887. +
  210888. + if (!valid_mode(setting->if_fmt)) {
  210889. + dev_warn(dev, "Input pixel format not valid"
  210890. + "use default RGB24\n");
  210891. + setting->if_fmt = IPU_PIX_FMT_RGB24;
  210892. + }
  210893. +
  210894. + setting->dev_id = mipi_dsi->dev_id;
  210895. + setting->disp_id = mipi_dsi->disp_id;
  210896. +
  210897. + ret = mipi_dsi_lcd_init(mipi_dsi, setting);
  210898. + if (ret) {
  210899. + dev_err(dev, "failed to init mipi dsi lcd\n");
  210900. + return ret;
  210901. + }
  210902. +
  210903. + dev_dbg(dev, "MIPI DSI dispdrv inited!\n");
  210904. + return ret;
  210905. +}
  210906. +
  210907. +static void mipi_dsi_disp_deinit(struct mxc_dispdrv_handle *disp)
  210908. +{
  210909. + struct mipi_dsi_info *mipi_dsi;
  210910. +
  210911. + mipi_dsi = mxc_dispdrv_getdata(disp);
  210912. +
  210913. + mipi_dsi_power_off(mipi_dsi->disp_mipi);
  210914. + if (mipi_dsi->bl)
  210915. + backlight_device_unregister(mipi_dsi->bl);
  210916. +}
  210917. +
  210918. +static struct mxc_dispdrv_driver mipi_dsi_drv = {
  210919. + .name = DISPDRV_MIPI,
  210920. + .init = mipi_dsi_disp_init,
  210921. + .deinit = mipi_dsi_disp_deinit,
  210922. + .enable = mipi_dsi_enable,
  210923. + .disable = mipi_dsi_power_off,
  210924. +};
  210925. +
  210926. +static int imx6q_mipi_dsi_get_mux(int dev_id, int disp_id)
  210927. +{
  210928. + if (dev_id > 1 || disp_id > 1)
  210929. + return -EINVAL;
  210930. +
  210931. + return (dev_id << 5) | (disp_id << 4);
  210932. +}
  210933. +
  210934. +static struct mipi_dsi_bus_mux imx6q_mipi_dsi_mux[] = {
  210935. + {
  210936. + .reg = IOMUXC_GPR3,
  210937. + .mask = IMX6Q_GPR3_MIPI_MUX_CTL_MASK,
  210938. + .get_mux = imx6q_mipi_dsi_get_mux,
  210939. + },
  210940. +};
  210941. +
  210942. +static int imx6dl_mipi_dsi_get_mux(int dev_id, int disp_id)
  210943. +{
  210944. + if (dev_id > 1 || disp_id > 1)
  210945. + return -EINVAL;
  210946. +
  210947. + /* MIPI DSI source is LCDIF */
  210948. + if (dev_id)
  210949. + disp_id = 0;
  210950. +
  210951. + return (dev_id << 5) | (disp_id << 4);
  210952. +}
  210953. +
  210954. +static struct mipi_dsi_bus_mux imx6dl_mipi_dsi_mux[] = {
  210955. + {
  210956. + .reg = IOMUXC_GPR3,
  210957. + .mask = IMX6Q_GPR3_MIPI_MUX_CTL_MASK,
  210958. + .get_mux = imx6dl_mipi_dsi_get_mux,
  210959. + },
  210960. +};
  210961. +
  210962. +static const struct of_device_id imx_mipi_dsi_dt_ids[] = {
  210963. + { .compatible = "fsl,imx6q-mipi-dsi", .data = imx6q_mipi_dsi_mux, },
  210964. + { .compatible = "fsl,imx6dl-mipi-dsi", .data = imx6dl_mipi_dsi_mux, },
  210965. + { }
  210966. +};
  210967. +MODULE_DEVICE_TABLE(of, imx_mipi_dsi_dt_ids);
  210968. +
  210969. +/**
  210970. + * This function is called by the driver framework to initialize the MIPI DSI
  210971. + * device.
  210972. + *
  210973. + * @param pdev The device structure for the MIPI DSI passed in by the
  210974. + * driver framework.
  210975. + *
  210976. + * @return Returns 0 on success or negative error code on error
  210977. + */
  210978. +static int mipi_dsi_probe(struct platform_device *pdev)
  210979. +{
  210980. + struct device_node *np = pdev->dev.of_node;
  210981. + const struct of_device_id *of_id =
  210982. + of_match_device(of_match_ptr(imx_mipi_dsi_dt_ids),
  210983. + &pdev->dev);
  210984. + struct mipi_dsi_info *mipi_dsi;
  210985. + struct resource *res;
  210986. + u32 dev_id, disp_id;
  210987. + const char *lcd_panel;
  210988. + unsigned int mux;
  210989. + int ret = 0;
  210990. +
  210991. + mipi_dsi = devm_kzalloc(&pdev->dev, sizeof(*mipi_dsi), GFP_KERNEL);
  210992. + if (!mipi_dsi)
  210993. + return -ENOMEM;
  210994. +
  210995. + ret = of_property_read_string(np, "lcd_panel", &lcd_panel);
  210996. + if (ret) {
  210997. + dev_err(&pdev->dev, "failed to read of property lcd_panel\n");
  210998. + return ret;
  210999. + }
  211000. +
  211001. + ret = of_property_read_u32(np, "dev_id", &dev_id);
  211002. + if (ret) {
  211003. + dev_err(&pdev->dev, "failed to read of property dev_id\n");
  211004. + return ret;
  211005. + }
  211006. + ret = of_property_read_u32(np, "disp_id", &disp_id);
  211007. + if (ret) {
  211008. + dev_err(&pdev->dev, "failed to read of property disp_id\n");
  211009. + return ret;
  211010. + }
  211011. + mipi_dsi->dev_id = dev_id;
  211012. + mipi_dsi->disp_id = disp_id;
  211013. +
  211014. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  211015. + if (!res) {
  211016. + dev_err(&pdev->dev, "failed to get platform resource 0\n");
  211017. + return -ENODEV;
  211018. + }
  211019. +
  211020. + if (!devm_request_mem_region(&pdev->dev, res->start,
  211021. + resource_size(res), pdev->name))
  211022. + return -EBUSY;
  211023. +
  211024. + mipi_dsi->mmio_base = devm_ioremap(&pdev->dev, res->start,
  211025. + resource_size(res));
  211026. + if (!mipi_dsi->mmio_base)
  211027. + return -EBUSY;
  211028. +
  211029. + mipi_dsi->irq = platform_get_irq(pdev, 0);
  211030. + if (mipi_dsi->irq < 0) {
  211031. + dev_err(&pdev->dev, "failed get device irq\n");
  211032. + return -ENODEV;
  211033. + }
  211034. +
  211035. + ret = devm_request_irq(&pdev->dev, mipi_dsi->irq,
  211036. + mipi_dsi_irq_handler,
  211037. + 0, "mipi_dsi", mipi_dsi);
  211038. + if (ret) {
  211039. + dev_err(&pdev->dev, "failed to request irq\n");
  211040. + return ret;
  211041. + }
  211042. +
  211043. + mipi_dsi->dphy_clk = devm_clk_get(&pdev->dev, "mipi_pllref_clk");
  211044. + if (IS_ERR(mipi_dsi->dphy_clk)) {
  211045. + dev_err(&pdev->dev, "failed to get dphy pll_ref_clk\n");
  211046. + return PTR_ERR(mipi_dsi->dphy_clk);
  211047. + }
  211048. +
  211049. + mipi_dsi->cfg_clk = devm_clk_get(&pdev->dev, "mipi_cfg_clk");
  211050. + if (IS_ERR(mipi_dsi->cfg_clk)) {
  211051. + dev_err(&pdev->dev, "failed to get cfg_clk\n");
  211052. + return PTR_ERR(mipi_dsi->cfg_clk);
  211053. + }
  211054. +
  211055. + mipi_dsi->disp_power_on = devm_regulator_get(&pdev->dev,
  211056. + "disp-power-on");
  211057. + if (!IS_ERR(mipi_dsi->disp_power_on)) {
  211058. + ret = regulator_enable(mipi_dsi->disp_power_on);
  211059. + if (ret) {
  211060. + dev_err(&pdev->dev, "failed to enable display "
  211061. + "power regulator, err=%d\n", ret);
  211062. + return ret;
  211063. + }
  211064. + } else {
  211065. + mipi_dsi->disp_power_on = NULL;
  211066. + }
  211067. +
  211068. + ret = device_reset(&pdev->dev);
  211069. + if (ret) {
  211070. + dev_err(&pdev->dev, "failed to reset: %d\n", ret);
  211071. + goto dev_reset_fail;
  211072. + }
  211073. +
  211074. + if (of_id)
  211075. + mipi_dsi->bus_mux = of_id->data;
  211076. +
  211077. + mipi_dsi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
  211078. + if (IS_ERR(mipi_dsi->regmap)) {
  211079. + dev_err(&pdev->dev, "failed to get parent regmap\n");
  211080. + ret = PTR_ERR(mipi_dsi->regmap);
  211081. + goto get_parent_regmap_fail;
  211082. + }
  211083. +
  211084. + mux = mipi_dsi->bus_mux->get_mux(dev_id, disp_id);
  211085. + if (mux >= 0)
  211086. + regmap_update_bits(mipi_dsi->regmap, mipi_dsi->bus_mux->reg,
  211087. + mipi_dsi->bus_mux->mask, mux);
  211088. + else
  211089. + dev_warn(&pdev->dev, "invalid dev_id or disp_id muxing\n");
  211090. +
  211091. + mipi_dsi->lcd_panel = kstrdup(lcd_panel, GFP_KERNEL);
  211092. + if (!mipi_dsi->lcd_panel) {
  211093. + dev_err(&pdev->dev, "failed to allocate lcd panel name\n");
  211094. + ret = -ENOMEM;
  211095. + goto kstrdup_fail;
  211096. + }
  211097. +
  211098. + mipi_dsi->pdev = pdev;
  211099. + mipi_dsi->disp_mipi = mxc_dispdrv_register(&mipi_dsi_drv);
  211100. + if (IS_ERR(mipi_dsi->disp_mipi)) {
  211101. + dev_err(&pdev->dev, "mxc_dispdrv_register error\n");
  211102. + ret = PTR_ERR(mipi_dsi->disp_mipi);
  211103. + goto dispdrv_reg_fail;
  211104. + }
  211105. +
  211106. + mxc_dispdrv_setdata(mipi_dsi->disp_mipi, mipi_dsi);
  211107. + dev_set_drvdata(&pdev->dev, mipi_dsi);
  211108. +
  211109. + dev_info(&pdev->dev, "i.MX MIPI DSI driver probed\n");
  211110. + return ret;
  211111. +
  211112. +dispdrv_reg_fail:
  211113. + kfree(mipi_dsi->lcd_panel);
  211114. +kstrdup_fail:
  211115. +get_parent_regmap_fail:
  211116. +dev_reset_fail:
  211117. + if (mipi_dsi->disp_power_on)
  211118. + regulator_disable(mipi_dsi->disp_power_on);
  211119. + return ret;
  211120. +}
  211121. +
  211122. +static void mipi_dsi_shutdown(struct platform_device *pdev)
  211123. +{
  211124. + struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
  211125. +
  211126. + mipi_dsi_power_off(mipi_dsi->disp_mipi);
  211127. +}
  211128. +
  211129. +static int mipi_dsi_remove(struct platform_device *pdev)
  211130. +{
  211131. + struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
  211132. +
  211133. + mxc_dispdrv_puthandle(mipi_dsi->disp_mipi);
  211134. + mxc_dispdrv_unregister(mipi_dsi->disp_mipi);
  211135. +
  211136. + if (mipi_dsi->disp_power_on)
  211137. + regulator_disable(mipi_dsi->disp_power_on);
  211138. +
  211139. + kfree(mipi_dsi->lcd_panel);
  211140. + dev_set_drvdata(&pdev->dev, NULL);
  211141. +
  211142. + return 0;
  211143. +}
  211144. +
  211145. +static struct platform_driver mipi_dsi_driver = {
  211146. + .driver = {
  211147. + .of_match_table = imx_mipi_dsi_dt_ids,
  211148. + .name = "mxc_mipi_dsi",
  211149. + },
  211150. + .probe = mipi_dsi_probe,
  211151. + .remove = mipi_dsi_remove,
  211152. + .shutdown = mipi_dsi_shutdown,
  211153. +};
  211154. +
  211155. +static int __init mipi_dsi_init(void)
  211156. +{
  211157. + int err;
  211158. +
  211159. + err = platform_driver_register(&mipi_dsi_driver);
  211160. + if (err) {
  211161. + pr_err("mipi_dsi_driver register failed\n");
  211162. + return -ENODEV;
  211163. + }
  211164. + pr_info("MIPI DSI driver module loaded\n");
  211165. + return 0;
  211166. +}
  211167. +
  211168. +static void __exit mipi_dsi_cleanup(void)
  211169. +{
  211170. + platform_driver_unregister(&mipi_dsi_driver);
  211171. +}
  211172. +
  211173. +module_init(mipi_dsi_init);
  211174. +module_exit(mipi_dsi_cleanup);
  211175. +
  211176. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  211177. +MODULE_DESCRIPTION("i.MX MIPI DSI driver");
  211178. +MODULE_LICENSE("GPL");
  211179. diff -Nur linux-3.14.15/drivers/video/mxc/mipi_dsi.h linux-linaro-stable-mx6/drivers/video/mxc/mipi_dsi.h
  211180. --- linux-3.14.15/drivers/video/mxc/mipi_dsi.h 1970-01-01 01:00:00.000000000 +0100
  211181. +++ linux-linaro-stable-mx6/drivers/video/mxc/mipi_dsi.h 2014-08-20 19:23:58.566867220 +0200
  211182. @@ -0,0 +1,112 @@
  211183. +/*
  211184. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  211185. + *
  211186. + * This program is free software; you can redistribute it and/or modify
  211187. + * it under the terms of the GNU General Public License as published by
  211188. + * the Free Software Foundation; either version 2 of the License, or
  211189. + * (at your option) any later version.
  211190. +
  211191. + * This program is distributed in the hope that it will be useful,
  211192. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  211193. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  211194. + * GNU General Public License for more details.
  211195. +
  211196. + * You should have received a copy of the GNU General Public License along
  211197. + * with this program; if not, write to the Free Software Foundation, Inc.,
  211198. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  211199. + */
  211200. +
  211201. +#ifndef __MIPI_DSI_H__
  211202. +#define __MIPI_DSI_H__
  211203. +
  211204. +#include <linux/regmap.h>
  211205. +
  211206. +#ifdef DEBUG
  211207. +#define mipi_dbg(fmt, ...) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
  211208. +#else
  211209. +#define mipi_dbg(fmt, ...)
  211210. +#endif
  211211. +
  211212. +#define DSI_CMD_BUF_MAXSIZE (32)
  211213. +
  211214. +/* DPI interface pixel color coding map */
  211215. +enum mipi_dsi_dpi_fmt {
  211216. + MIPI_RGB565_PACKED = 0,
  211217. + MIPI_RGB565_LOOSELY,
  211218. + MIPI_RGB565_CONFIG3,
  211219. + MIPI_RGB666_PACKED,
  211220. + MIPI_RGB666_LOOSELY,
  211221. + MIPI_RGB888,
  211222. +};
  211223. +
  211224. +struct mipi_lcd_config {
  211225. + u32 virtual_ch;
  211226. + u32 data_lane_num;
  211227. + /* device max DPHY clock in MHz unit */
  211228. + u32 max_phy_clk;
  211229. + enum mipi_dsi_dpi_fmt dpi_fmt;
  211230. +};
  211231. +
  211232. +struct mipi_dsi_info;
  211233. +struct mipi_dsi_lcd_callback {
  211234. + /* callback for lcd panel operation */
  211235. + void (*get_mipi_lcd_videomode)(struct fb_videomode **, int *,
  211236. + struct mipi_lcd_config **);
  211237. + int (*mipi_lcd_setup)(struct mipi_dsi_info *);
  211238. +
  211239. +};
  211240. +
  211241. +struct mipi_dsi_match_lcd {
  211242. + char *lcd_panel;
  211243. + struct mipi_dsi_lcd_callback lcd_callback;
  211244. +};
  211245. +
  211246. +struct mipi_dsi_bus_mux {
  211247. + int reg;
  211248. + int mask;
  211249. + int (*get_mux) (int dev_id, int disp_id);
  211250. +};
  211251. +
  211252. +/* driver private data */
  211253. +struct mipi_dsi_info {
  211254. + struct platform_device *pdev;
  211255. + void __iomem *mmio_base;
  211256. + struct regmap *regmap;
  211257. + const struct mipi_dsi_bus_mux *bus_mux;
  211258. + int dsi_power_on;
  211259. + int lcd_inited;
  211260. + u32 dphy_pll_config;
  211261. + int dev_id;
  211262. + int disp_id;
  211263. + char *lcd_panel;
  211264. + int irq;
  211265. + struct clk *dphy_clk;
  211266. + struct clk *cfg_clk;
  211267. + struct mxc_dispdrv_handle *disp_mipi;
  211268. + struct fb_videomode *mode;
  211269. + struct regulator *disp_power_on;
  211270. + struct mipi_lcd_config *lcd_config;
  211271. + /* board related power control */
  211272. + struct backlight_device *bl;
  211273. + /* callback for lcd panel operation */
  211274. + struct mipi_dsi_lcd_callback *lcd_callback;
  211275. +};
  211276. +
  211277. +int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi,
  211278. + u8 data_type, const u32 *buf, int len);
  211279. +int mipi_dsi_pkt_read(struct mipi_dsi_info *mipi,
  211280. + u8 data_type, u32 *buf, int len);
  211281. +int mipi_dsi_dcs_cmd(struct mipi_dsi_info *mipi,
  211282. + u8 cmd, const u32 *param, int num);
  211283. +
  211284. +#ifdef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
  211285. +void mipid_hx8369_get_lcd_videomode(struct fb_videomode **mode, int *size,
  211286. + struct mipi_lcd_config **data);
  211287. +int mipid_hx8369_lcd_setup(struct mipi_dsi_info *);
  211288. +#endif
  211289. +
  211290. +#ifndef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
  211291. +#error "Please configure MIPI LCD panel, we cannot find one!"
  211292. +#endif
  211293. +
  211294. +#endif
  211295. diff -Nur linux-3.14.15/drivers/video/mxc/mxc_dispdrv.c linux-linaro-stable-mx6/drivers/video/mxc/mxc_dispdrv.c
  211296. --- linux-3.14.15/drivers/video/mxc/mxc_dispdrv.c 1970-01-01 01:00:00.000000000 +0100
  211297. +++ linux-linaro-stable-mx6/drivers/video/mxc/mxc_dispdrv.c 2014-08-20 19:23:58.566867220 +0200
  211298. @@ -0,0 +1,150 @@
  211299. +/*
  211300. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  211301. + */
  211302. +
  211303. +/*
  211304. + * The code contained herein is licensed under the GNU General Public
  211305. + * License. You may obtain a copy of the GNU General Public License
  211306. + * Version 2 or later at the following locations:
  211307. + *
  211308. + * http://www.opensource.org/licenses/gpl-license.html
  211309. + * http://www.gnu.org/copyleft/gpl.html
  211310. + */
  211311. +
  211312. +/*!
  211313. + * @file mxc_dispdrv.c
  211314. + * @brief mxc display driver framework.
  211315. + *
  211316. + * A display device driver could call mxc_dispdrv_register(drv) in its dev_probe() function.
  211317. + * Move all dev_probe() things into mxc_dispdrv_driver->init(), init() function should init
  211318. + * and feedback setting;
  211319. + * Necessary deferred operations can be done in mxc_dispdrv_driver->post_init(),
  211320. + * after dev_id and disp_id pass usage check;
  211321. + * Move all dev_remove() things into mxc_dispdrv_driver->deinit();
  211322. + * Move all dev_suspend() things into fb_notifier for SUSPEND, if there is;
  211323. + * Move all dev_resume() things into fb_notifier for RESUME, if there is;
  211324. + *
  211325. + * ipuv3 fb driver could call mxc_dispdrv_gethandle(name, setting) before a fb
  211326. + * need be added, with fbi param passing by setting, after
  211327. + * mxc_dispdrv_gethandle() return, FB driver should get the basic setting
  211328. + * about fbi info and ipuv3-hw (ipu_id and disp_id).
  211329. + *
  211330. + * @ingroup Framebuffer
  211331. + */
  211332. +
  211333. +#include <linux/kernel.h>
  211334. +#include <linux/module.h>
  211335. +#include <linux/list.h>
  211336. +#include <linux/mutex.h>
  211337. +#include <linux/slab.h>
  211338. +#include <linux/err.h>
  211339. +#include <linux/string.h>
  211340. +#include "mxc_dispdrv.h"
  211341. +
  211342. +static LIST_HEAD(dispdrv_list);
  211343. +static DEFINE_MUTEX(dispdrv_lock);
  211344. +
  211345. +struct mxc_dispdrv_entry {
  211346. + /* Note: drv always the first element */
  211347. + struct mxc_dispdrv_driver *drv;
  211348. + bool active;
  211349. + void *priv;
  211350. + struct list_head list;
  211351. +};
  211352. +
  211353. +struct mxc_dispdrv_handle *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv)
  211354. +{
  211355. + struct mxc_dispdrv_entry *new;
  211356. +
  211357. + mutex_lock(&dispdrv_lock);
  211358. +
  211359. + new = kzalloc(sizeof(struct mxc_dispdrv_entry), GFP_KERNEL);
  211360. + if (!new) {
  211361. + mutex_unlock(&dispdrv_lock);
  211362. + return ERR_PTR(-ENOMEM);
  211363. + }
  211364. +
  211365. + new->drv = drv;
  211366. + list_add_tail(&new->list, &dispdrv_list);
  211367. +
  211368. + mutex_unlock(&dispdrv_lock);
  211369. +
  211370. + return (struct mxc_dispdrv_handle *)new;
  211371. +}
  211372. +EXPORT_SYMBOL_GPL(mxc_dispdrv_register);
  211373. +
  211374. +int mxc_dispdrv_unregister(struct mxc_dispdrv_handle *handle)
  211375. +{
  211376. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  211377. +
  211378. + if (entry) {
  211379. + mutex_lock(&dispdrv_lock);
  211380. + list_del(&entry->list);
  211381. + mutex_unlock(&dispdrv_lock);
  211382. + kfree(entry);
  211383. + return 0;
  211384. + } else
  211385. + return -EINVAL;
  211386. +}
  211387. +EXPORT_SYMBOL_GPL(mxc_dispdrv_unregister);
  211388. +
  211389. +struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name,
  211390. + struct mxc_dispdrv_setting *setting)
  211391. +{
  211392. + int ret, found = 0;
  211393. + struct mxc_dispdrv_entry *entry;
  211394. +
  211395. + mutex_lock(&dispdrv_lock);
  211396. + list_for_each_entry(entry, &dispdrv_list, list) {
  211397. + if (!strcmp(entry->drv->name, name) && (entry->drv->init)) {
  211398. + ret = entry->drv->init((struct mxc_dispdrv_handle *)
  211399. + entry, setting);
  211400. + if (ret >= 0) {
  211401. + entry->active = true;
  211402. + found = 1;
  211403. + break;
  211404. + }
  211405. + }
  211406. + }
  211407. + mutex_unlock(&dispdrv_lock);
  211408. +
  211409. + return found ? (struct mxc_dispdrv_handle *)entry:ERR_PTR(-ENODEV);
  211410. +}
  211411. +EXPORT_SYMBOL_GPL(mxc_dispdrv_gethandle);
  211412. +
  211413. +void mxc_dispdrv_puthandle(struct mxc_dispdrv_handle *handle)
  211414. +{
  211415. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  211416. +
  211417. + mutex_lock(&dispdrv_lock);
  211418. + if (entry && entry->active && entry->drv->deinit) {
  211419. + entry->drv->deinit(handle);
  211420. + entry->active = false;
  211421. + }
  211422. + mutex_unlock(&dispdrv_lock);
  211423. +
  211424. +}
  211425. +EXPORT_SYMBOL_GPL(mxc_dispdrv_puthandle);
  211426. +
  211427. +int mxc_dispdrv_setdata(struct mxc_dispdrv_handle *handle, void *data)
  211428. +{
  211429. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  211430. +
  211431. + if (entry) {
  211432. + entry->priv = data;
  211433. + return 0;
  211434. + } else
  211435. + return -EINVAL;
  211436. +}
  211437. +EXPORT_SYMBOL_GPL(mxc_dispdrv_setdata);
  211438. +
  211439. +void *mxc_dispdrv_getdata(struct mxc_dispdrv_handle *handle)
  211440. +{
  211441. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  211442. +
  211443. + if (entry) {
  211444. + return entry->priv;
  211445. + } else
  211446. + return ERR_PTR(-EINVAL);
  211447. +}
  211448. +EXPORT_SYMBOL_GPL(mxc_dispdrv_getdata);
  211449. diff -Nur linux-3.14.15/drivers/video/mxc/mxc_dispdrv.h linux-linaro-stable-mx6/drivers/video/mxc/mxc_dispdrv.h
  211450. --- linux-3.14.15/drivers/video/mxc/mxc_dispdrv.h 1970-01-01 01:00:00.000000000 +0100
  211451. +++ linux-linaro-stable-mx6/drivers/video/mxc/mxc_dispdrv.h 2014-08-20 19:23:58.566867220 +0200
  211452. @@ -0,0 +1,54 @@
  211453. +/*
  211454. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  211455. + */
  211456. +
  211457. +/*
  211458. + * The code contained herein is licensed under the GNU General Public
  211459. + * License. You may obtain a copy of the GNU General Public License
  211460. + * Version 2 or later at the following locations:
  211461. + *
  211462. + * http://www.opensource.org/licenses/gpl-license.html
  211463. + * http://www.gnu.org/copyleft/gpl.html
  211464. + */
  211465. +#ifndef __MXC_DISPDRV_H__
  211466. +#define __MXC_DISPDRV_H__
  211467. +#include <linux/fb.h>
  211468. +
  211469. +struct mxc_dispdrv_handle {
  211470. + struct mxc_dispdrv_driver *drv;
  211471. +};
  211472. +
  211473. +struct mxc_dispdrv_setting {
  211474. + /*input-feedback parameter*/
  211475. + struct fb_info *fbi;
  211476. + int if_fmt;
  211477. + int default_bpp;
  211478. + char *dft_mode_str;
  211479. +
  211480. + /*feedback parameter*/
  211481. + int dev_id;
  211482. + int disp_id;
  211483. +};
  211484. +
  211485. +struct mxc_dispdrv_driver {
  211486. + const char *name;
  211487. + int (*init) (struct mxc_dispdrv_handle *, struct mxc_dispdrv_setting *);
  211488. + /* deferred operations after dev_id and disp_id pass usage check */
  211489. + int (*post_init) (struct mxc_dispdrv_handle *, int dev_id, int disp_id);
  211490. + void (*deinit) (struct mxc_dispdrv_handle *);
  211491. + /* display driver enable function for extension */
  211492. + int (*enable) (struct mxc_dispdrv_handle *);
  211493. + /* display driver disable function, called at early part of fb_blank */
  211494. + void (*disable) (struct mxc_dispdrv_handle *);
  211495. + /* display driver setup function, called at early part of fb_set_par */
  211496. + int (*setup) (struct mxc_dispdrv_handle *, struct fb_info *fbi);
  211497. +};
  211498. +
  211499. +struct mxc_dispdrv_handle *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv);
  211500. +int mxc_dispdrv_unregister(struct mxc_dispdrv_handle *handle);
  211501. +struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name,
  211502. + struct mxc_dispdrv_setting *setting);
  211503. +void mxc_dispdrv_puthandle(struct mxc_dispdrv_handle *handle);
  211504. +int mxc_dispdrv_setdata(struct mxc_dispdrv_handle *handle, void *data);
  211505. +void *mxc_dispdrv_getdata(struct mxc_dispdrv_handle *handle);
  211506. +#endif
  211507. diff -Nur linux-3.14.15/drivers/video/mxc/mxc_edid.c linux-linaro-stable-mx6/drivers/video/mxc/mxc_edid.c
  211508. --- linux-3.14.15/drivers/video/mxc/mxc_edid.c 1970-01-01 01:00:00.000000000 +0100
  211509. +++ linux-linaro-stable-mx6/drivers/video/mxc/mxc_edid.c 2014-08-20 19:23:58.566867220 +0200
  211510. @@ -0,0 +1,762 @@
  211511. +/*
  211512. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  211513. + */
  211514. +
  211515. +/*
  211516. + * The code contained herein is licensed under the GNU General Public
  211517. + * License. You may obtain a copy of the GNU General Public License
  211518. + * Version 2 or later at the following locations:
  211519. + *
  211520. + * http://www.opensource.org/licenses/gpl-license.html
  211521. + * http://www.gnu.org/copyleft/gpl.html
  211522. + */
  211523. +
  211524. +/*!
  211525. + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
  211526. + */
  211527. +
  211528. +/*!
  211529. + * @file mxc_edid.c
  211530. + *
  211531. + * @brief MXC EDID driver
  211532. + *
  211533. + * @ingroup Framebuffer
  211534. + */
  211535. +
  211536. +/*!
  211537. + * Include files
  211538. + */
  211539. +#include <linux/i2c.h>
  211540. +#include <linux/fb.h>
  211541. +#include <video/mxc_edid.h>
  211542. +#include "../edid.h"
  211543. +
  211544. +#undef DEBUG /* define this for verbose EDID parsing output */
  211545. +#ifdef DEBUG
  211546. +#define DPRINTK(fmt, args...) printk(fmt, ## args)
  211547. +#else
  211548. +#define DPRINTK(fmt, args...)
  211549. +#endif
  211550. +
  211551. +const struct fb_videomode mxc_cea_mode[64] = {
  211552. + /* #1: 640x480p@59.94/60Hz 4:3 */
  211553. + [1] = {
  211554. + NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0,
  211555. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  211556. + },
  211557. + /* #2: 720x480p@59.94/60Hz 4:3 */
  211558. + [2] = {
  211559. + NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
  211560. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  211561. + },
  211562. + /* #3: 720x480p@59.94/60Hz 16:9 */
  211563. + [3] = {
  211564. + NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
  211565. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211566. + },
  211567. + /* #4: 1280x720p@59.94/60Hz 16:9 */
  211568. + [4] = {
  211569. + NULL, 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5,
  211570. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  211571. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
  211572. + },
  211573. + /* #5: 1920x1080i@59.94/60Hz 16:9 */
  211574. + [5] = {
  211575. + NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5,
  211576. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  211577. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211578. + },
  211579. + /* #6: 720(1440)x480iH@59.94/60Hz 4:3 */
  211580. + [6] = {
  211581. + NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
  211582. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_4_3, 0,
  211583. + },
  211584. + /* #7: 720(1440)x480iH@59.94/60Hz 16:9 */
  211585. + [7] = {
  211586. + NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
  211587. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211588. + },
  211589. + /* #8: 720(1440)x240pH@59.94/60Hz 4:3 */
  211590. + [8] = {
  211591. + NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
  211592. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  211593. + },
  211594. + /* #9: 720(1440)x240pH@59.94/60Hz 16:9 */
  211595. + [9] = {
  211596. + NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
  211597. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211598. + },
  211599. + /* #14: 1440x480p@59.94/60Hz 4:3 */
  211600. + [14] = {
  211601. + NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
  211602. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  211603. + },
  211604. + /* #15: 1440x480p@59.94/60Hz 16:9 */
  211605. + [15] = {
  211606. + NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
  211607. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211608. + },
  211609. + /* #16: 1920x1080p@60Hz 16:9 */
  211610. + [16] = {
  211611. + NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
  211612. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  211613. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211614. + },
  211615. + /* #17: 720x576pH@50Hz 4:3 */
  211616. + [17] = {
  211617. + NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
  211618. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  211619. + },
  211620. + /* #18: 720x576pH@50Hz 16:9 */
  211621. + [18] = {
  211622. + NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
  211623. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211624. + },
  211625. + /* #19: 1280x720p@50Hz */
  211626. + [19] = {
  211627. + NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5,
  211628. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  211629. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211630. + },
  211631. + /* #20: 1920x1080i@50Hz */
  211632. + [20] = {
  211633. + NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5,
  211634. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  211635. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211636. + },
  211637. + /* #23: 720(1440)x288pH@50Hz 4:3 */
  211638. + [23] = {
  211639. + NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
  211640. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  211641. + },
  211642. + /* #24: 720(1440)x288pH@50Hz 16:9 */
  211643. + [24] = {
  211644. + NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
  211645. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211646. + },
  211647. + /* #29: 720(1440)x576pH@50Hz 4:3 */
  211648. + [29] = {
  211649. + NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
  211650. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  211651. + },
  211652. + /* #30: 720(1440)x576pH@50Hz 16:9 */
  211653. + [30] = {
  211654. + NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
  211655. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211656. + },
  211657. + /* #31: 1920x1080p@50Hz */
  211658. + [31] = {
  211659. + NULL, 50, 1920, 1080, 6734, 148, 528, 36, 4, 44, 5,
  211660. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  211661. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211662. + },
  211663. + /* #32: 1920x1080p@23.98/24Hz */
  211664. + [32] = {
  211665. + NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5,
  211666. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  211667. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211668. + },
  211669. + /* #33: 1920x1080p@25Hz */
  211670. + [33] = {
  211671. + NULL, 25, 1920, 1080, 13468, 148, 528, 36, 4, 44, 5,
  211672. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  211673. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211674. + },
  211675. + /* #34: 1920x1080p@30Hz */
  211676. + [34] = {
  211677. + NULL, 30, 1920, 1080, 13468, 148, 88, 36, 4, 44, 5,
  211678. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  211679. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  211680. + },
  211681. + /* #41: 1280x720p@100Hz 16:9 */
  211682. + [41] = {
  211683. + NULL, 100, 1280, 720, 6734, 220, 440, 20, 5, 40, 5,
  211684. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  211685. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
  211686. + },
  211687. + /* #47: 1280x720p@119.88/120Hz 16:9 */
  211688. + [47] = {
  211689. + NULL, 120, 1280, 720, 6734, 220, 110, 20, 5, 40, 5,
  211690. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  211691. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
  211692. + },
  211693. +};
  211694. +
  211695. +/*
  211696. + * We have a special version of fb_mode_is_equal that ignores
  211697. + * pixclock, since for many CEA modes, 2 frequencies are supported
  211698. + * e.g. 640x480 @ 60Hz or 59.94Hz
  211699. + */
  211700. +int mxc_edid_fb_mode_is_equal(bool use_aspect,
  211701. + const struct fb_videomode *mode1,
  211702. + const struct fb_videomode *mode2)
  211703. +{
  211704. + u32 mask;
  211705. +
  211706. + if (use_aspect)
  211707. + mask = ~0;
  211708. + else
  211709. + mask = ~FB_VMODE_ASPECT_MASK;
  211710. +
  211711. + return (mode1->xres == mode2->xres &&
  211712. + mode1->yres == mode2->yres &&
  211713. + mode1->hsync_len == mode2->hsync_len &&
  211714. + mode1->vsync_len == mode2->vsync_len &&
  211715. + mode1->left_margin == mode2->left_margin &&
  211716. + mode1->right_margin == mode2->right_margin &&
  211717. + mode1->upper_margin == mode2->upper_margin &&
  211718. + mode1->lower_margin == mode2->lower_margin &&
  211719. + mode1->sync == mode2->sync &&
  211720. + /* refresh check, 59.94Hz and 60Hz have the same parameter
  211721. + * in struct of mxc_cea_mode */
  211722. + abs(mode1->refresh - mode2->refresh) <= 1 &&
  211723. + (mode1->vmode & mask) == (mode2->vmode & mask));
  211724. +}
  211725. +
  211726. +static void get_detailed_timing(unsigned char *block,
  211727. + struct fb_videomode *mode)
  211728. +{
  211729. + mode->xres = H_ACTIVE;
  211730. + mode->yres = V_ACTIVE;
  211731. + mode->pixclock = PIXEL_CLOCK;
  211732. + mode->pixclock /= 1000;
  211733. + mode->pixclock = KHZ2PICOS(mode->pixclock);
  211734. + mode->right_margin = H_SYNC_OFFSET;
  211735. + mode->left_margin = (H_ACTIVE + H_BLANKING) -
  211736. + (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
  211737. + mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
  211738. + V_SYNC_WIDTH;
  211739. + mode->lower_margin = V_SYNC_OFFSET;
  211740. + mode->hsync_len = H_SYNC_WIDTH;
  211741. + mode->vsync_len = V_SYNC_WIDTH;
  211742. + if (HSYNC_POSITIVE)
  211743. + mode->sync |= FB_SYNC_HOR_HIGH_ACT;
  211744. + if (VSYNC_POSITIVE)
  211745. + mode->sync |= FB_SYNC_VERT_HIGH_ACT;
  211746. + mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
  211747. + (V_ACTIVE + V_BLANKING));
  211748. + if (INTERLACED) {
  211749. + mode->yres *= 2;
  211750. + mode->upper_margin *= 2;
  211751. + mode->lower_margin *= 2;
  211752. + mode->vsync_len *= 2;
  211753. + mode->vmode |= FB_VMODE_INTERLACED;
  211754. + }
  211755. + mode->flag = FB_MODE_IS_DETAILED;
  211756. +
  211757. + if ((H_SIZE / 16) == (V_SIZE / 9))
  211758. + mode->vmode |= FB_VMODE_ASPECT_16_9;
  211759. + else if ((H_SIZE / 4) == (V_SIZE / 3))
  211760. + mode->vmode |= FB_VMODE_ASPECT_4_3;
  211761. + else if ((mode->xres / 16) == (mode->yres / 9))
  211762. + mode->vmode |= FB_VMODE_ASPECT_16_9;
  211763. + else if ((mode->xres / 4) == (mode->yres / 3))
  211764. + mode->vmode |= FB_VMODE_ASPECT_4_3;
  211765. +
  211766. + if (mode->vmode & FB_VMODE_ASPECT_16_9)
  211767. + DPRINTK("Aspect ratio: 16:9\n");
  211768. + if (mode->vmode & FB_VMODE_ASPECT_4_3)
  211769. + DPRINTK("Aspect ratio: 4:3\n");
  211770. + DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000);
  211771. + DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET,
  211772. + H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING);
  211773. + DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET,
  211774. + V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING);
  211775. + DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-",
  211776. + (VSYNC_POSITIVE) ? "+" : "-");
  211777. +}
  211778. +
  211779. +int mxc_edid_parse_ext_blk(unsigned char *edid,
  211780. + struct mxc_edid_cfg *cfg,
  211781. + struct fb_monspecs *specs)
  211782. +{
  211783. + char detail_timing_desc_offset;
  211784. + struct fb_videomode *mode, *m;
  211785. + unsigned char index = 0x0;
  211786. + unsigned char *block;
  211787. + int i, num = 0, revision;
  211788. +
  211789. + if (edid[index++] != 0x2) /* only support cea ext block now */
  211790. + return -1;
  211791. + revision = edid[index++];
  211792. + DPRINTK("cea extent revision %d\n", revision);
  211793. + mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
  211794. + if (mode == NULL)
  211795. + return -1;
  211796. +
  211797. + detail_timing_desc_offset = edid[index++];
  211798. +
  211799. + if (revision >= 2) {
  211800. + cfg->cea_underscan = (edid[index] >> 7) & 0x1;
  211801. + cfg->cea_basicaudio = (edid[index] >> 6) & 0x1;
  211802. + cfg->cea_ycbcr444 = (edid[index] >> 5) & 0x1;
  211803. + cfg->cea_ycbcr422 = (edid[index] >> 4) & 0x1;
  211804. +
  211805. + DPRINTK("CEA underscan %d\n", cfg->cea_underscan);
  211806. + DPRINTK("CEA basicaudio %d\n", cfg->cea_basicaudio);
  211807. + DPRINTK("CEA ycbcr444 %d\n", cfg->cea_ycbcr444);
  211808. + DPRINTK("CEA ycbcr422 %d\n", cfg->cea_ycbcr422);
  211809. + }
  211810. +
  211811. + if (revision >= 3) {
  211812. + /* short desc */
  211813. + DPRINTK("CEA Short desc timmings\n");
  211814. + index++;
  211815. + while (index < detail_timing_desc_offset) {
  211816. + unsigned char tagcode, blklen;
  211817. +
  211818. + tagcode = (edid[index] >> 5) & 0x7;
  211819. + blklen = (edid[index]) & 0x1f;
  211820. +
  211821. + DPRINTK("Tagcode %x Len %d\n", tagcode, blklen);
  211822. +
  211823. + switch (tagcode) {
  211824. + case 0x2: /*Video data block*/
  211825. + {
  211826. + int cea_idx;
  211827. + i = 0;
  211828. + while (i < blklen) {
  211829. + index++;
  211830. + cea_idx = edid[index] & 0x7f;
  211831. + if (cea_idx < ARRAY_SIZE(mxc_cea_mode) &&
  211832. + (mxc_cea_mode[cea_idx].xres)) {
  211833. + DPRINTK("Support CEA Format #%d\n", cea_idx);
  211834. + mode[num] = mxc_cea_mode[cea_idx];
  211835. + mode[num].flag |= FB_MODE_IS_STANDARD;
  211836. + num++;
  211837. + }
  211838. + i++;
  211839. + }
  211840. + break;
  211841. + }
  211842. + case 0x3: /*Vendor specific data*/
  211843. + {
  211844. + unsigned char IEEE_reg_iden[3];
  211845. + unsigned char deep_color;
  211846. + unsigned char latency_present;
  211847. + unsigned char I_latency_present;
  211848. + unsigned char hdmi_video_present;
  211849. + unsigned char hdmi_3d_present;
  211850. + unsigned char hdmi_3d_multi_present;
  211851. + unsigned char hdmi_vic_len;
  211852. + unsigned char hdmi_3d_len;
  211853. + unsigned char index_inc = 0;
  211854. + unsigned char vsd_end;
  211855. +
  211856. + vsd_end = index + blklen;
  211857. +
  211858. + IEEE_reg_iden[0] = edid[index+1];
  211859. + IEEE_reg_iden[1] = edid[index+2];
  211860. + IEEE_reg_iden[2] = edid[index+3];
  211861. + cfg->physical_address[0] = (edid[index+4] & 0xf0) >> 4;
  211862. + cfg->physical_address[1] = (edid[index+4] & 0x0f);
  211863. + cfg->physical_address[2] = (edid[index+5] & 0xf0) >> 4;
  211864. + cfg->physical_address[3] = (edid[index+5] & 0x0f);
  211865. +
  211866. + if ((IEEE_reg_iden[0] == 0x03) &&
  211867. + (IEEE_reg_iden[1] == 0x0c) &&
  211868. + (IEEE_reg_iden[2] == 0x00))
  211869. + cfg->hdmi_cap = 1;
  211870. +
  211871. + if (blklen > 5) {
  211872. + deep_color = edid[index+6];
  211873. + if (deep_color & 0x80)
  211874. + cfg->vsd_support_ai = true;
  211875. + if (deep_color & 0x40)
  211876. + cfg->vsd_dc_48bit = true;
  211877. + if (deep_color & 0x20)
  211878. + cfg->vsd_dc_36bit = true;
  211879. + if (deep_color & 0x10)
  211880. + cfg->vsd_dc_30bit = true;
  211881. + if (deep_color & 0x08)
  211882. + cfg->vsd_dc_y444 = true;
  211883. + if (deep_color & 0x01)
  211884. + cfg->vsd_dvi_dual = true;
  211885. + }
  211886. +
  211887. + DPRINTK("VSD hdmi capability %d\n", cfg->hdmi_cap);
  211888. + DPRINTK("VSD support ai %d\n", cfg->vsd_support_ai);
  211889. + DPRINTK("VSD support deep color 48bit %d\n", cfg->vsd_dc_48bit);
  211890. + DPRINTK("VSD support deep color 36bit %d\n", cfg->vsd_dc_36bit);
  211891. + DPRINTK("VSD support deep color 30bit %d\n", cfg->vsd_dc_30bit);
  211892. + DPRINTK("VSD support deep color y444 %d\n", cfg->vsd_dc_y444);
  211893. + DPRINTK("VSD support dvi dual %d\n", cfg->vsd_dvi_dual);
  211894. +
  211895. + if (blklen > 6)
  211896. + cfg->vsd_max_tmdsclk_rate = edid[index+7] * 5;
  211897. + DPRINTK("VSD MAX TMDS CLOCK RATE %d\n", cfg->vsd_max_tmdsclk_rate);
  211898. +
  211899. + if (blklen > 7) {
  211900. + latency_present = edid[index+8] >> 7;
  211901. + I_latency_present = (edid[index+8] & 0x40) >> 6;
  211902. + hdmi_video_present = (edid[index+8] & 0x20) >> 5;
  211903. + cfg->vsd_cnc3 = (edid[index+8] & 0x8) >> 3;
  211904. + cfg->vsd_cnc2 = (edid[index+8] & 0x4) >> 2;
  211905. + cfg->vsd_cnc1 = (edid[index+8] & 0x2) >> 1;
  211906. + cfg->vsd_cnc0 = edid[index+8] & 0x1;
  211907. +
  211908. + DPRINTK("VSD cnc0 %d\n", cfg->vsd_cnc0);
  211909. + DPRINTK("VSD cnc1 %d\n", cfg->vsd_cnc1);
  211910. + DPRINTK("VSD cnc2 %d\n", cfg->vsd_cnc2);
  211911. + DPRINTK("VSD cnc3 %d\n", cfg->vsd_cnc3);
  211912. + DPRINTK("latency_present %d\n", latency_present);
  211913. + DPRINTK("I_latency_present %d\n", I_latency_present);
  211914. + DPRINTK("hdmi_video_present %d\n", hdmi_video_present);
  211915. +
  211916. + } else {
  211917. + index += blklen;
  211918. + break;
  211919. + }
  211920. +
  211921. + index += 9;
  211922. +
  211923. + /*latency present */
  211924. + if (latency_present) {
  211925. + cfg->vsd_video_latency = edid[index++];
  211926. + cfg->vsd_audio_latency = edid[index++];
  211927. +
  211928. + if (I_latency_present) {
  211929. + cfg->vsd_I_video_latency = edid[index++];
  211930. + cfg->vsd_I_audio_latency = edid[index++];
  211931. + } else {
  211932. + cfg->vsd_I_video_latency = cfg->vsd_video_latency;
  211933. + cfg->vsd_I_audio_latency = cfg->vsd_audio_latency;
  211934. + }
  211935. +
  211936. + DPRINTK("VSD latency video_latency %d\n", cfg->vsd_video_latency);
  211937. + DPRINTK("VSD latency audio_latency %d\n", cfg->vsd_audio_latency);
  211938. + DPRINTK("VSD latency I_video_latency %d\n", cfg->vsd_I_video_latency);
  211939. + DPRINTK("VSD latency I_audio_latency %d\n", cfg->vsd_I_audio_latency);
  211940. + }
  211941. +
  211942. + if (hdmi_video_present) {
  211943. + hdmi_3d_present = edid[index] >> 7;
  211944. + hdmi_3d_multi_present = (edid[index] & 0x60) >> 5;
  211945. + index++;
  211946. + hdmi_vic_len = (edid[index] & 0xe0) >> 5;
  211947. + hdmi_3d_len = edid[index] & 0x1f;
  211948. + index++;
  211949. +
  211950. + DPRINTK("hdmi_3d_present %d\n", hdmi_3d_present);
  211951. + DPRINTK("hdmi_3d_multi_present %d\n", hdmi_3d_multi_present);
  211952. + DPRINTK("hdmi_vic_len %d\n", hdmi_vic_len);
  211953. + DPRINTK("hdmi_3d_len %d\n", hdmi_3d_len);
  211954. +
  211955. + if (hdmi_vic_len > 0) {
  211956. + for (i = 0; i < hdmi_vic_len; i++) {
  211957. + cfg->hdmi_vic[i] = edid[index++];
  211958. + DPRINTK("HDMI_vic=%d\n", cfg->hdmi_vic[i]);
  211959. + }
  211960. + }
  211961. +
  211962. + if (hdmi_3d_len > 0) {
  211963. + if (hdmi_3d_present) {
  211964. + if (hdmi_3d_multi_present == 0x1) {
  211965. + cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
  211966. + index_inc = 2;
  211967. + } else if (hdmi_3d_multi_present == 0x2) {
  211968. + cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
  211969. + cfg->hdmi_3d_mask_all = (edid[index+2] << 8) | edid[index+3];
  211970. + index_inc = 4;
  211971. + } else
  211972. + index_inc = 0;
  211973. + }
  211974. +
  211975. + DPRINTK("HDMI 3d struct all =0x%x\n", cfg->hdmi_3d_struct_all);
  211976. + DPRINTK("HDMI 3d mask all =0x%x\n", cfg->hdmi_3d_mask_all);
  211977. +
  211978. + /* Read 2D vic 3D_struct */
  211979. + if ((hdmi_3d_len - index_inc) > 0) {
  211980. + DPRINTK("Support 3D video format\n");
  211981. + i = 0;
  211982. + while ((hdmi_3d_len - index_inc) > 0) {
  211983. +
  211984. + cfg->hdmi_3d_format[i].vic_order_2d = edid[index+index_inc] >> 4;
  211985. + cfg->hdmi_3d_format[i].struct_3d = edid[index+index_inc] & 0x0f;
  211986. + index_inc++;
  211987. +
  211988. + if (cfg->hdmi_3d_format[i].struct_3d == 8) {
  211989. + cfg->hdmi_3d_format[i].detail_3d = edid[index+index_inc] >> 4;
  211990. + index_inc++;
  211991. + } else if (cfg->hdmi_3d_format[i].struct_3d > 8) {
  211992. + cfg->hdmi_3d_format[i].detail_3d = 0;
  211993. + index_inc++;
  211994. + }
  211995. +
  211996. + DPRINTK("vic_order_2d=%d, 3d_struct=%d, 3d_detail=0x%x\n",
  211997. + cfg->hdmi_3d_format[i].vic_order_2d,
  211998. + cfg->hdmi_3d_format[i].struct_3d,
  211999. + cfg->hdmi_3d_format[i].detail_3d);
  212000. + i++;
  212001. + }
  212002. + }
  212003. + index += index_inc;
  212004. + }
  212005. + }
  212006. +
  212007. + index = vsd_end;
  212008. +
  212009. + break;
  212010. + }
  212011. + case 0x1: /*Audio data block*/
  212012. + {
  212013. + u8 audio_format, max_ch, byte1, byte2, byte3;
  212014. +
  212015. + i = 0;
  212016. + cfg->max_channels = 0;
  212017. + cfg->sample_rates = 0;
  212018. + cfg->sample_sizes = 0;
  212019. +
  212020. + while (i < blklen) {
  212021. + byte1 = edid[index + 1];
  212022. + byte2 = edid[index + 2];
  212023. + byte3 = edid[index + 3];
  212024. + index += 3;
  212025. + i += 3;
  212026. +
  212027. + audio_format = byte1 >> 3;
  212028. + max_ch = (byte1 & 0x07) + 1;
  212029. +
  212030. + DPRINTK("Audio Format Descriptor : %2d\n", audio_format);
  212031. + DPRINTK("Max Number of Channels : %2d\n", max_ch);
  212032. + DPRINTK("Sample Rates : %02x\n", byte2);
  212033. +
  212034. + /* ALSA can't specify specific compressed
  212035. + * formats, so only care about PCM for now. */
  212036. + if (audio_format == AUDIO_CODING_TYPE_LPCM) {
  212037. + if (max_ch > cfg->max_channels)
  212038. + cfg->max_channels = max_ch;
  212039. +
  212040. + cfg->sample_rates |= byte2;
  212041. + cfg->sample_sizes |= byte3 & 0x7;
  212042. + DPRINTK("Sample Sizes : %02x\n",
  212043. + byte3 & 0x7);
  212044. + }
  212045. + }
  212046. + break;
  212047. + }
  212048. + case 0x4: /*Speaker allocation block*/
  212049. + {
  212050. + i = 0;
  212051. + while (i < blklen) {
  212052. + cfg->speaker_alloc = edid[index + 1];
  212053. + index += 3;
  212054. + i += 3;
  212055. + DPRINTK("Speaker Alloc : %02x\n", cfg->speaker_alloc);
  212056. + }
  212057. + break;
  212058. + }
  212059. + case 0x7: /*User extended block*/
  212060. + default:
  212061. + /* skip */
  212062. + DPRINTK("Not handle block, tagcode = 0x%x\n", tagcode);
  212063. + index += blklen;
  212064. + break;
  212065. + }
  212066. +
  212067. + index++;
  212068. + }
  212069. + }
  212070. +
  212071. + /* long desc */
  212072. + DPRINTK("CEA long desc timmings\n");
  212073. + index = detail_timing_desc_offset;
  212074. + block = edid + index;
  212075. + while (index < (EDID_LENGTH - DETAILED_TIMING_DESCRIPTION_SIZE)) {
  212076. + if (!(block[0] == 0x00 && block[1] == 0x00)) {
  212077. + get_detailed_timing(block, &mode[num]);
  212078. + num++;
  212079. + }
  212080. + block += DETAILED_TIMING_DESCRIPTION_SIZE;
  212081. + index += DETAILED_TIMING_DESCRIPTION_SIZE;
  212082. + }
  212083. +
  212084. + if (!num) {
  212085. + kfree(mode);
  212086. + return 0;
  212087. + }
  212088. +
  212089. + m = kmalloc((num + specs->modedb_len) *
  212090. + sizeof(struct fb_videomode), GFP_KERNEL);
  212091. + if (!m)
  212092. + return 0;
  212093. +
  212094. + if (specs->modedb_len) {
  212095. + memmove(m, specs->modedb,
  212096. + specs->modedb_len * sizeof(struct fb_videomode));
  212097. + kfree(specs->modedb);
  212098. + }
  212099. + memmove(m+specs->modedb_len, mode,
  212100. + num * sizeof(struct fb_videomode));
  212101. + kfree(mode);
  212102. +
  212103. + specs->modedb_len += num;
  212104. + specs->modedb = m;
  212105. +
  212106. + return 0;
  212107. +}
  212108. +EXPORT_SYMBOL(mxc_edid_parse_ext_blk);
  212109. +
  212110. +static int mxc_edid_readblk(struct i2c_adapter *adp,
  212111. + unsigned short addr, unsigned char *edid)
  212112. +{
  212113. + int ret = 0, extblknum = 0;
  212114. + unsigned char regaddr = 0x0;
  212115. + struct i2c_msg msg[2] = {
  212116. + {
  212117. + .addr = addr,
  212118. + .flags = 0,
  212119. + .len = 1,
  212120. + .buf = &regaddr,
  212121. + }, {
  212122. + .addr = addr,
  212123. + .flags = I2C_M_RD,
  212124. + .len = EDID_LENGTH,
  212125. + .buf = edid,
  212126. + },
  212127. + };
  212128. +
  212129. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  212130. + if (ret != ARRAY_SIZE(msg)) {
  212131. + DPRINTK("unable to read EDID block\n");
  212132. + return -EIO;
  212133. + }
  212134. +
  212135. + if (edid[1] == 0x00)
  212136. + return -ENOENT;
  212137. +
  212138. + extblknum = edid[0x7E];
  212139. +
  212140. + if (extblknum) {
  212141. + regaddr = 128;
  212142. + msg[1].buf = edid + EDID_LENGTH;
  212143. +
  212144. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  212145. + if (ret != ARRAY_SIZE(msg)) {
  212146. + DPRINTK("unable to read EDID ext block\n");
  212147. + return -EIO;
  212148. + }
  212149. + }
  212150. +
  212151. + return extblknum;
  212152. +}
  212153. +
  212154. +static int mxc_edid_readsegblk(struct i2c_adapter *adp, unsigned short addr,
  212155. + unsigned char *edid, int seg_num)
  212156. +{
  212157. + int ret = 0;
  212158. + unsigned char segment = 0x1, regaddr = 0;
  212159. + struct i2c_msg msg[3] = {
  212160. + {
  212161. + .addr = 0x30,
  212162. + .flags = 0,
  212163. + .len = 1,
  212164. + .buf = &segment,
  212165. + }, {
  212166. + .addr = addr,
  212167. + .flags = 0,
  212168. + .len = 1,
  212169. + .buf = &regaddr,
  212170. + }, {
  212171. + .addr = addr,
  212172. + .flags = I2C_M_RD,
  212173. + .len = EDID_LENGTH,
  212174. + .buf = edid,
  212175. + },
  212176. + };
  212177. +
  212178. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  212179. + if (ret != ARRAY_SIZE(msg)) {
  212180. + DPRINTK("unable to read EDID block\n");
  212181. + return -EIO;
  212182. + }
  212183. +
  212184. + if (seg_num == 2) {
  212185. + regaddr = 128;
  212186. + msg[2].buf = edid + EDID_LENGTH;
  212187. +
  212188. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  212189. + if (ret != ARRAY_SIZE(msg)) {
  212190. + DPRINTK("unable to read EDID block\n");
  212191. + return -EIO;
  212192. + }
  212193. + }
  212194. +
  212195. + return ret;
  212196. +}
  212197. +
  212198. +int mxc_edid_var_to_vic(struct fb_var_screeninfo *var)
  212199. +{
  212200. + int i;
  212201. + struct fb_videomode m;
  212202. +
  212203. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  212204. + fb_var_to_videomode(&m, var);
  212205. + if (mxc_edid_fb_mode_is_equal(false, &m, &mxc_cea_mode[i]))
  212206. + break;
  212207. + }
  212208. +
  212209. + if (i == ARRAY_SIZE(mxc_cea_mode))
  212210. + return 0;
  212211. +
  212212. + return i;
  212213. +}
  212214. +EXPORT_SYMBOL(mxc_edid_var_to_vic);
  212215. +
  212216. +int mxc_edid_mode_to_vic(const struct fb_videomode *mode)
  212217. +{
  212218. + int i;
  212219. + bool use_aspect = (mode->vmode & FB_VMODE_ASPECT_MASK);
  212220. +
  212221. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  212222. + if (mxc_edid_fb_mode_is_equal(use_aspect, mode, &mxc_cea_mode[i]))
  212223. + break;
  212224. + }
  212225. +
  212226. + if (i == ARRAY_SIZE(mxc_cea_mode))
  212227. + return 0;
  212228. +
  212229. + return i;
  212230. +}
  212231. +EXPORT_SYMBOL(mxc_edid_mode_to_vic);
  212232. +
  212233. +/* make sure edid has 512 bytes*/
  212234. +int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
  212235. + unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi)
  212236. +{
  212237. + int ret = 0, extblknum;
  212238. + if (!adp || !edid || !cfg || !fbi)
  212239. + return -EINVAL;
  212240. +
  212241. + memset(edid, 0, EDID_LENGTH*4);
  212242. + memset(cfg, 0, sizeof(struct mxc_edid_cfg));
  212243. +
  212244. + extblknum = mxc_edid_readblk(adp, addr, edid);
  212245. + if (extblknum < 0)
  212246. + return extblknum;
  212247. +
  212248. + /* edid first block parsing */
  212249. + memset(&fbi->monspecs, 0, sizeof(fbi->monspecs));
  212250. + fb_edid_to_monspecs(edid, &fbi->monspecs);
  212251. +
  212252. + if (extblknum) {
  212253. + int i;
  212254. +
  212255. + /* need read segment block? */
  212256. + if (extblknum > 1) {
  212257. + ret = mxc_edid_readsegblk(adp, addr,
  212258. + edid + EDID_LENGTH*2, extblknum - 1);
  212259. + if (ret < 0)
  212260. + return ret;
  212261. + }
  212262. +
  212263. + for (i = 1; i <= extblknum; i++)
  212264. + /* edid ext block parsing */
  212265. + mxc_edid_parse_ext_blk(edid + i*EDID_LENGTH,
  212266. + cfg, &fbi->monspecs);
  212267. + }
  212268. +
  212269. + return 0;
  212270. +}
  212271. +EXPORT_SYMBOL(mxc_edid_read);
  212272. +
  212273. diff -Nur linux-3.14.15/drivers/video/mxc/mxcfb_hx8369_wvga.c linux-linaro-stable-mx6/drivers/video/mxc/mxcfb_hx8369_wvga.c
  212274. --- linux-3.14.15/drivers/video/mxc/mxcfb_hx8369_wvga.c 1970-01-01 01:00:00.000000000 +0100
  212275. +++ linux-linaro-stable-mx6/drivers/video/mxc/mxcfb_hx8369_wvga.c 2014-08-20 19:23:58.566867220 +0200
  212276. @@ -0,0 +1,449 @@
  212277. +/*
  212278. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  212279. + *
  212280. + * This program is free software; you can redistribute it and/or modify
  212281. + * it under the terms of the GNU General Public License as published by
  212282. + * the Free Software Foundation; either version 2 of the License, or
  212283. + * (at your option) any later version.
  212284. +
  212285. + * This program is distributed in the hope that it will be useful,
  212286. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  212287. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  212288. + * GNU General Public License for more details.
  212289. +
  212290. + * You should have received a copy of the GNU General Public License along
  212291. + * with this program; if not, write to the Free Software Foundation, Inc.,
  212292. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  212293. + */
  212294. +
  212295. +#include <linux/types.h>
  212296. +#include <linux/init.h>
  212297. +#include <linux/delay.h>
  212298. +#include <linux/platform_device.h>
  212299. +#include <linux/err.h>
  212300. +#include <linux/clk.h>
  212301. +#include <linux/console.h>
  212302. +#include <linux/io.h>
  212303. +#include <linux/bitops.h>
  212304. +#include <linux/spinlock.h>
  212305. +#include <linux/mipi_dsi.h>
  212306. +#include <linux/mxcfb.h>
  212307. +#include <linux/backlight.h>
  212308. +#include <video/mipi_display.h>
  212309. +
  212310. +#include "mipi_dsi.h"
  212311. +
  212312. +#define MIPI_DSI_MAX_RET_PACK_SIZE (0x4)
  212313. +
  212314. +#define HX8369BL_MAX_BRIGHT (255)
  212315. +#define HX8369BL_DEF_BRIGHT (255)
  212316. +
  212317. +#define HX8369_MAX_DPHY_CLK (800)
  212318. +#define HX8369_ONE_DATA_LANE (0x1)
  212319. +#define HX8369_TWO_DATA_LANE (0x2)
  212320. +
  212321. +#define HX8369_CMD_SETEXTC (0xB9)
  212322. +#define HX8369_CMD_SETEXTC_LEN (0x4)
  212323. +#define HX8369_CMD_SETEXTC_PARAM_1 (0x6983ff)
  212324. +
  212325. +#define HX8369_CMD_GETHXID (0xF4)
  212326. +#define HX8369_CMD_GETHXID_LEN (0x4)
  212327. +#define HX8369_ID (0x69)
  212328. +#define HX8369_ID_MASK (0xFF)
  212329. +
  212330. +#define HX8369_CMD_SETDISP (0xB2)
  212331. +#define HX8369_CMD_SETDISP_LEN (16)
  212332. +#define HX8369_CMD_SETDISP_1_HALT (0x00)
  212333. +#define HX8369_CMD_SETDISP_2_RES_MODE (0x23)
  212334. +#define HX8369_CMD_SETDISP_3_BP (0x03)
  212335. +#define HX8369_CMD_SETDISP_4_FP (0x03)
  212336. +#define HX8369_CMD_SETDISP_5_SAP (0x70)
  212337. +#define HX8369_CMD_SETDISP_6_GENON (0x00)
  212338. +#define HX8369_CMD_SETDISP_7_GENOFF (0xff)
  212339. +#define HX8369_CMD_SETDISP_8_RTN (0x00)
  212340. +#define HX8369_CMD_SETDISP_9_TEI (0x00)
  212341. +#define HX8369_CMD_SETDISP_10_TEP_UP (0x00)
  212342. +#define HX8369_CMD_SETDISP_11_TEP_LOW (0x00)
  212343. +#define HX8369_CMD_SETDISP_12_BP_PE (0x03)
  212344. +#define HX8369_CMD_SETDISP_13_FP_PE (0x03)
  212345. +#define HX8369_CMD_SETDISP_14_RTN_PE (0x00)
  212346. +#define HX8369_CMD_SETDISP_15_GON (0x01)
  212347. +
  212348. +#define HX8369_CMD_SETCYC (0xB4)
  212349. +#define HX8369_CMD_SETCYC_LEN (6)
  212350. +#define HX8369_CMD_SETCYC_PARAM_1 (0x5f1d00)
  212351. +#define HX8369_CMD_SETCYC_PARAM_2 (0x060e)
  212352. +
  212353. +#define HX8369_CMD_SETGIP (0xD5)
  212354. +#define HX8369_CMD_SETGIP_LEN (27)
  212355. +#define HX8369_CMD_SETGIP_PARAM_1 (0x030400)
  212356. +#define HX8369_CMD_SETGIP_PARAM_2 (0x1c050100)
  212357. +#define HX8369_CMD_SETGIP_PARAM_3 (0x00030170)
  212358. +#define HX8369_CMD_SETGIP_PARAM_4 (0x51064000)
  212359. +#define HX8369_CMD_SETGIP_PARAM_5 (0x41000007)
  212360. +#define HX8369_CMD_SETGIP_PARAM_6 (0x07075006)
  212361. +#define HX8369_CMD_SETGIP_PARAM_7 (0x040f)
  212362. +
  212363. +#define HX8369_CMD_SETPOWER (0xB1)
  212364. +#define HX8369_CMD_SETPOWER_LEN (20)
  212365. +#define HX8369_CMD_SETPOWER_PARAM_1 (0x340001)
  212366. +#define HX8369_CMD_SETPOWER_PARAM_2 (0x0f0f0006)
  212367. +#define HX8369_CMD_SETPOWER_PARAM_3 (0x3f3f322a)
  212368. +#define HX8369_CMD_SETPOWER_PARAM_4 (0xe6013a07)
  212369. +#define HX8369_CMD_SETPOWER_PARAM_5 (0xe6e6e6e6)
  212370. +
  212371. +#define HX8369_CMD_SETVCOM (0xB6)
  212372. +#define HX8369_CMD_SETVCOM_LEN (3)
  212373. +#define HX8369_CMD_SETVCOM_PARAM_1 (0x5656)
  212374. +
  212375. +#define HX8369_CMD_SETPANEL (0xCC)
  212376. +#define HX8369_CMD_SETPANEL_PARAM_1 (0x02)
  212377. +
  212378. +#define HX8369_CMD_SETGAMMA (0xE0)
  212379. +#define HX8369_CMD_SETGAMMA_LEN (35)
  212380. +#define HX8369_CMD_SETGAMMA_PARAM_1 (0x221d00)
  212381. +#define HX8369_CMD_SETGAMMA_PARAM_2 (0x2e3f3d38)
  212382. +#define HX8369_CMD_SETGAMMA_PARAM_3 (0x0f0d064a)
  212383. +#define HX8369_CMD_SETGAMMA_PARAM_4 (0x16131513)
  212384. +#define HX8369_CMD_SETGAMMA_PARAM_5 (0x1d001910)
  212385. +#define HX8369_CMD_SETGAMMA_PARAM_6 (0x3f3d3822)
  212386. +#define HX8369_CMD_SETGAMMA_PARAM_7 (0x0d064a2e)
  212387. +#define HX8369_CMD_SETGAMMA_PARAM_8 (0x1315130f)
  212388. +#define HX8369_CMD_SETGAMMA_PARAM_9 (0x191016)
  212389. +
  212390. +#define HX8369_CMD_SETMIPI (0xBA)
  212391. +#define HX8369_CMD_SETMIPI_LEN (14)
  212392. +#define HX8369_CMD_SETMIPI_PARAM_1 (0xc6a000)
  212393. +#define HX8369_CMD_SETMIPI_PARAM_2 (0x10000a00)
  212394. +#define HX8369_CMD_SETMIPI_ONELANE (0x10 << 24)
  212395. +#define HX8369_CMD_SETMIPI_TWOLANE (0x11 << 24)
  212396. +#define HX8369_CMD_SETMIPI_PARAM_3 (0x00026f30)
  212397. +#define HX8369_CMD_SETMIPI_PARAM_4 (0x4018)
  212398. +
  212399. +#define HX8369_CMD_SETPIXEL_FMT (0x3A)
  212400. +#define HX8369_CMD_SETPIXEL_FMT_24BPP (0x77)
  212401. +#define HX8369_CMD_SETPIXEL_FMT_18BPP (0x66)
  212402. +#define HX8369_CMD_SETPIXEL_FMT_16BPP (0x55)
  212403. +
  212404. +#define HX8369_CMD_SETCLUMN_ADDR (0x2A)
  212405. +#define HX8369_CMD_SETCLUMN_ADDR_LEN (5)
  212406. +#define HX8369_CMD_SETCLUMN_ADDR_PARAM_1 (0xdf0000)
  212407. +#define HX8369_CMD_SETCLUMN_ADDR_PARAM_2 (0x01)
  212408. +
  212409. +#define HX8369_CMD_SETPAGE_ADDR (0x2B)
  212410. +#define HX8369_CMD_SETPAGE_ADDR_LEN (5)
  212411. +#define HX8369_CMD_SETPAGE_ADDR_PARAM_1 (0x1f0000)
  212412. +#define HX8369_CMD_SETPAGE_ADDR_PARAM_2 (0x03)
  212413. +
  212414. +#define HX8369_CMD_WRT_DISP_BRIGHT (0x51)
  212415. +#define HX8369_CMD_WRT_DISP_BRIGHT_PARAM_1 (0xFF)
  212416. +
  212417. +#define HX8369_CMD_WRT_CABC_MIN_BRIGHT (0x5E)
  212418. +#define HX8369_CMD_WRT_CABC_MIN_BRIGHT_PARAM_1 (0x20)
  212419. +
  212420. +#define HX8369_CMD_WRT_CABC_CTRL (0x55)
  212421. +#define HX8369_CMD_WRT_CABC_CTRL_PARAM_1 (0x1)
  212422. +
  212423. +#define HX8369_CMD_WRT_CTRL_DISP (0x53)
  212424. +#define HX8369_CMD_WRT_CTRL_DISP_PARAM_1 (0x24)
  212425. +
  212426. +#define CHECK_RETCODE(ret) \
  212427. +do { \
  212428. + if (ret < 0) { \
  212429. + dev_err(&mipi_dsi->pdev->dev, \
  212430. + "%s ERR: ret:%d, line:%d.\n", \
  212431. + __func__, ret, __LINE__); \
  212432. + return ret; \
  212433. + } \
  212434. +} while (0)
  212435. +
  212436. +static int hx8369bl_brightness;
  212437. +static int mipid_init_backlight(struct mipi_dsi_info *mipi_dsi);
  212438. +
  212439. +static struct fb_videomode truly_lcd_modedb[] = {
  212440. + {
  212441. + "TRULY-WVGA", 64, 480, 800, 37880,
  212442. + 8, 8,
  212443. + 6, 6,
  212444. + 8, 6,
  212445. + FB_SYNC_OE_LOW_ACT,
  212446. + FB_VMODE_NONINTERLACED,
  212447. + 0,
  212448. + },
  212449. +};
  212450. +
  212451. +static struct mipi_lcd_config lcd_config = {
  212452. + .virtual_ch = 0x0,
  212453. + .data_lane_num = HX8369_TWO_DATA_LANE,
  212454. + .max_phy_clk = HX8369_MAX_DPHY_CLK,
  212455. + .dpi_fmt = MIPI_RGB888,
  212456. +};
  212457. +void mipid_hx8369_get_lcd_videomode(struct fb_videomode **mode, int *size,
  212458. + struct mipi_lcd_config **data)
  212459. +{
  212460. + *mode = &truly_lcd_modedb[0];
  212461. + *size = ARRAY_SIZE(truly_lcd_modedb);
  212462. + *data = &lcd_config;
  212463. +}
  212464. +
  212465. +int mipid_hx8369_lcd_setup(struct mipi_dsi_info *mipi_dsi)
  212466. +{
  212467. + u32 buf[DSI_CMD_BUF_MAXSIZE];
  212468. + int err;
  212469. +
  212470. + dev_dbg(&mipi_dsi->pdev->dev, "MIPI DSI LCD setup.\n");
  212471. + buf[0] = HX8369_CMD_SETEXTC | (HX8369_CMD_SETEXTC_PARAM_1 << 8);
  212472. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  212473. + buf, HX8369_CMD_SETEXTC_LEN);
  212474. + CHECK_RETCODE(err);
  212475. + buf[0] = MIPI_DSI_MAX_RET_PACK_SIZE;
  212476. + err = mipi_dsi_pkt_write(mipi_dsi,
  212477. + MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
  212478. + buf, 0);
  212479. + CHECK_RETCODE(err);
  212480. + buf[0] = HX8369_CMD_GETHXID;
  212481. + err = mipi_dsi_pkt_read(mipi_dsi,
  212482. + MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM,
  212483. + buf, HX8369_CMD_GETHXID_LEN);
  212484. + if (!err && ((buf[0] & HX8369_ID_MASK) == HX8369_ID)) {
  212485. + dev_info(&mipi_dsi->pdev->dev,
  212486. + "MIPI DSI LCD ID:0x%x.\n", buf[0]);
  212487. + } else {
  212488. + dev_err(&mipi_dsi->pdev->dev,
  212489. + "mipi_dsi_pkt_read err:%d, data:0x%x.\n",
  212490. + err, buf[0]);
  212491. + dev_info(&mipi_dsi->pdev->dev,
  212492. + "MIPI DSI LCD not detected!\n");
  212493. + return err;
  212494. + }
  212495. +
  212496. + /* set LCD resolution as 480RGBx800, DPI interface,
  212497. + * display operation mode: RGB data bypass GRAM mode.
  212498. + */
  212499. + buf[0] = HX8369_CMD_SETDISP | (HX8369_CMD_SETDISP_1_HALT << 8) |
  212500. + (HX8369_CMD_SETDISP_2_RES_MODE << 16) |
  212501. + (HX8369_CMD_SETDISP_3_BP << 24);
  212502. + buf[1] = HX8369_CMD_SETDISP_4_FP | (HX8369_CMD_SETDISP_5_SAP << 8) |
  212503. + (HX8369_CMD_SETDISP_6_GENON << 16) |
  212504. + (HX8369_CMD_SETDISP_7_GENOFF << 24);
  212505. + buf[2] = HX8369_CMD_SETDISP_8_RTN | (HX8369_CMD_SETDISP_9_TEI << 8) |
  212506. + (HX8369_CMD_SETDISP_10_TEP_UP << 16) |
  212507. + (HX8369_CMD_SETDISP_11_TEP_LOW << 24);
  212508. + buf[3] = HX8369_CMD_SETDISP_12_BP_PE |
  212509. + (HX8369_CMD_SETDISP_13_FP_PE << 8) |
  212510. + (HX8369_CMD_SETDISP_14_RTN_PE << 16) |
  212511. + (HX8369_CMD_SETDISP_15_GON << 24);
  212512. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  212513. + buf, HX8369_CMD_SETDISP_LEN);
  212514. + CHECK_RETCODE(err);
  212515. +
  212516. + /* Set display waveform cycle */
  212517. + buf[0] = HX8369_CMD_SETCYC | (HX8369_CMD_SETCYC_PARAM_1 << 8);
  212518. + buf[1] = HX8369_CMD_SETCYC_PARAM_2;
  212519. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  212520. + buf, HX8369_CMD_SETCYC_LEN);
  212521. + CHECK_RETCODE(err);
  212522. +
  212523. + /* Set GIP timing output control */
  212524. + buf[0] = HX8369_CMD_SETGIP | (HX8369_CMD_SETGIP_PARAM_1 << 8);
  212525. + buf[1] = HX8369_CMD_SETGIP_PARAM_2;
  212526. + buf[2] = HX8369_CMD_SETGIP_PARAM_3;
  212527. + buf[3] = HX8369_CMD_SETGIP_PARAM_4;
  212528. + buf[4] = HX8369_CMD_SETGIP_PARAM_5;
  212529. + buf[5] = HX8369_CMD_SETGIP_PARAM_6;
  212530. + buf[6] = HX8369_CMD_SETGIP_PARAM_7;
  212531. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  212532. + HX8369_CMD_SETGIP_LEN);
  212533. + CHECK_RETCODE(err);
  212534. +
  212535. + /* Set power: standby, DC etc. */
  212536. + buf[0] = HX8369_CMD_SETPOWER | (HX8369_CMD_SETPOWER_PARAM_1 << 8);
  212537. + buf[1] = HX8369_CMD_SETPOWER_PARAM_2;
  212538. + buf[2] = HX8369_CMD_SETPOWER_PARAM_3;
  212539. + buf[3] = HX8369_CMD_SETPOWER_PARAM_4;
  212540. + buf[4] = HX8369_CMD_SETPOWER_PARAM_5;
  212541. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  212542. + HX8369_CMD_SETPOWER_LEN);
  212543. + CHECK_RETCODE(err);
  212544. +
  212545. + /* Set VCOM voltage. */
  212546. + buf[0] = HX8369_CMD_SETVCOM | (HX8369_CMD_SETVCOM_PARAM_1 << 8);
  212547. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  212548. + HX8369_CMD_SETVCOM_LEN);
  212549. + CHECK_RETCODE(err);
  212550. +
  212551. + /* Set Panel: BGR/RGB or Inversion. */
  212552. + buf[0] = HX8369_CMD_SETPANEL | (HX8369_CMD_SETPANEL_PARAM_1 << 8);
  212553. + err = mipi_dsi_pkt_write(mipi_dsi,
  212554. + MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM, buf, 0);
  212555. + CHECK_RETCODE(err);
  212556. +
  212557. + /* Set gamma curve related setting */
  212558. + buf[0] = HX8369_CMD_SETGAMMA | (HX8369_CMD_SETGAMMA_PARAM_1 << 8);
  212559. + buf[1] = HX8369_CMD_SETGAMMA_PARAM_2;
  212560. + buf[2] = HX8369_CMD_SETGAMMA_PARAM_3;
  212561. + buf[3] = HX8369_CMD_SETGAMMA_PARAM_4;
  212562. + buf[4] = HX8369_CMD_SETGAMMA_PARAM_5;
  212563. + buf[5] = HX8369_CMD_SETGAMMA_PARAM_6;
  212564. + buf[7] = HX8369_CMD_SETGAMMA_PARAM_7;
  212565. + buf[7] = HX8369_CMD_SETGAMMA_PARAM_8;
  212566. + buf[8] = HX8369_CMD_SETGAMMA_PARAM_9;
  212567. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  212568. + HX8369_CMD_SETGAMMA_LEN);
  212569. + CHECK_RETCODE(err);
  212570. +
  212571. + /* Set MIPI: DPHYCMD & DSICMD, data lane number */
  212572. + buf[0] = HX8369_CMD_SETMIPI | (HX8369_CMD_SETMIPI_PARAM_1 << 8);
  212573. + buf[1] = HX8369_CMD_SETMIPI_PARAM_2;
  212574. + buf[2] = HX8369_CMD_SETMIPI_PARAM_3;
  212575. + if (lcd_config.data_lane_num == HX8369_ONE_DATA_LANE)
  212576. + buf[2] |= HX8369_CMD_SETMIPI_ONELANE;
  212577. + else
  212578. + buf[2] |= HX8369_CMD_SETMIPI_TWOLANE;
  212579. + buf[3] = HX8369_CMD_SETMIPI_PARAM_4;
  212580. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  212581. + HX8369_CMD_SETMIPI_LEN);
  212582. + CHECK_RETCODE(err);
  212583. +
  212584. + /* Set pixel format:24bpp */
  212585. + buf[0] = HX8369_CMD_SETPIXEL_FMT;
  212586. + switch (lcd_config.dpi_fmt) {
  212587. + case MIPI_RGB565_PACKED:
  212588. + case MIPI_RGB565_LOOSELY:
  212589. + case MIPI_RGB565_CONFIG3:
  212590. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_16BPP << 8);
  212591. + break;
  212592. +
  212593. + case MIPI_RGB666_LOOSELY:
  212594. + case MIPI_RGB666_PACKED:
  212595. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_18BPP << 8);
  212596. + break;
  212597. +
  212598. + case MIPI_RGB888:
  212599. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_24BPP << 8);
  212600. + break;
  212601. +
  212602. + default:
  212603. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_24BPP << 8);
  212604. + break;
  212605. + }
  212606. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  212607. + buf, 0);
  212608. + CHECK_RETCODE(err);
  212609. +
  212610. + /* Set column address: 0~479 */
  212611. + buf[0] = HX8369_CMD_SETCLUMN_ADDR |
  212612. + (HX8369_CMD_SETCLUMN_ADDR_PARAM_1 << 8);
  212613. + buf[1] = HX8369_CMD_SETCLUMN_ADDR_PARAM_2;
  212614. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  212615. + buf, HX8369_CMD_SETCLUMN_ADDR_LEN);
  212616. + CHECK_RETCODE(err);
  212617. +
  212618. + /* Set page address: 0~799 */
  212619. + buf[0] = HX8369_CMD_SETPAGE_ADDR |
  212620. + (HX8369_CMD_SETPAGE_ADDR_PARAM_1 << 8);
  212621. + buf[1] = HX8369_CMD_SETPAGE_ADDR_PARAM_2;
  212622. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  212623. + buf, HX8369_CMD_SETPAGE_ADDR_LEN);
  212624. + CHECK_RETCODE(err);
  212625. +
  212626. + /* Set display brightness related */
  212627. + buf[0] = HX8369_CMD_WRT_DISP_BRIGHT |
  212628. + (HX8369_CMD_WRT_DISP_BRIGHT_PARAM_1 << 8);
  212629. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  212630. + buf, 0);
  212631. + CHECK_RETCODE(err);
  212632. +
  212633. + buf[0] = HX8369_CMD_WRT_CABC_CTRL |
  212634. + (HX8369_CMD_WRT_CABC_CTRL_PARAM_1 << 8);
  212635. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  212636. + buf, 0);
  212637. + CHECK_RETCODE(err);
  212638. +
  212639. + buf[0] = HX8369_CMD_WRT_CTRL_DISP |
  212640. + (HX8369_CMD_WRT_CTRL_DISP_PARAM_1 << 8);
  212641. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  212642. + buf, 0);
  212643. + CHECK_RETCODE(err);
  212644. +
  212645. + /* exit sleep mode and set display on */
  212646. + buf[0] = MIPI_DCS_EXIT_SLEEP_MODE;
  212647. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM,
  212648. + buf, 0);
  212649. + CHECK_RETCODE(err);
  212650. + /* To allow time for the supply voltages
  212651. + * and clock circuits to stabilize.
  212652. + */
  212653. + msleep(5);
  212654. + buf[0] = MIPI_DCS_SET_DISPLAY_ON;
  212655. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM,
  212656. + buf, 0);
  212657. + CHECK_RETCODE(err);
  212658. +
  212659. + err = mipid_init_backlight(mipi_dsi);
  212660. + return err;
  212661. +}
  212662. +
  212663. +static int mipid_bl_update_status(struct backlight_device *bl)
  212664. +{
  212665. + u32 buf;
  212666. + int brightness = bl->props.brightness;
  212667. + struct mipi_dsi_info *mipi_dsi = bl_get_data(bl);
  212668. +
  212669. + if (bl->props.power != FB_BLANK_UNBLANK ||
  212670. + bl->props.fb_blank != FB_BLANK_UNBLANK)
  212671. + brightness = 0;
  212672. +
  212673. + buf = HX8369_CMD_WRT_DISP_BRIGHT |
  212674. + ((brightness & HX8369BL_MAX_BRIGHT) << 8);
  212675. + mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  212676. + &buf, 0);
  212677. +
  212678. + hx8369bl_brightness = brightness & HX8369BL_MAX_BRIGHT;
  212679. +
  212680. + dev_dbg(&bl->dev, "mipid backlight bringtness:%d.\n", brightness);
  212681. + return 0;
  212682. +}
  212683. +
  212684. +static int mipid_bl_get_brightness(struct backlight_device *bl)
  212685. +{
  212686. + return hx8369bl_brightness;
  212687. +}
  212688. +
  212689. +static int mipi_bl_check_fb(struct backlight_device *bl, struct fb_info *fbi)
  212690. +{
  212691. + return 0;
  212692. +}
  212693. +
  212694. +static const struct backlight_ops mipid_lcd_bl_ops = {
  212695. + .update_status = mipid_bl_update_status,
  212696. + .get_brightness = mipid_bl_get_brightness,
  212697. + .check_fb = mipi_bl_check_fb,
  212698. +};
  212699. +
  212700. +static int mipid_init_backlight(struct mipi_dsi_info *mipi_dsi)
  212701. +{
  212702. + struct backlight_properties props;
  212703. + struct backlight_device *bl;
  212704. +
  212705. + if (mipi_dsi->bl) {
  212706. + pr_debug("mipid backlight already init!\n");
  212707. + return 0;
  212708. + }
  212709. + memset(&props, 0, sizeof(struct backlight_properties));
  212710. + props.max_brightness = HX8369BL_MAX_BRIGHT;
  212711. + props.type = BACKLIGHT_RAW;
  212712. + bl = backlight_device_register("mipid-bl", &mipi_dsi->pdev->dev,
  212713. + mipi_dsi, &mipid_lcd_bl_ops, &props);
  212714. + if (IS_ERR(bl)) {
  212715. + pr_err("error %ld on backlight register\n", PTR_ERR(bl));
  212716. + return PTR_ERR(bl);
  212717. + }
  212718. + mipi_dsi->bl = bl;
  212719. + bl->props.power = FB_BLANK_UNBLANK;
  212720. + bl->props.fb_blank = FB_BLANK_UNBLANK;
  212721. + bl->props.brightness = HX8369BL_DEF_BRIGHT;
  212722. +
  212723. + mipid_bl_update_status(bl);
  212724. + return 0;
  212725. +}
  212726. diff -Nur linux-3.14.15/drivers/video/mxc/mxc_hdmi.c linux-linaro-stable-mx6/drivers/video/mxc/mxc_hdmi.c
  212727. --- linux-3.14.15/drivers/video/mxc/mxc_hdmi.c 1970-01-01 01:00:00.000000000 +0100
  212728. +++ linux-linaro-stable-mx6/drivers/video/mxc/mxc_hdmi.c 2014-08-20 19:31:50.020885713 +0200
  212729. @@ -0,0 +1,2920 @@
  212730. +/*
  212731. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
  212732. + *
  212733. + * This program is free software; you can redistribute it and/or modify
  212734. + * it under the terms of the GNU General Public License as published by
  212735. + * the Free Software Foundation; either version 2 of the License, or
  212736. + * (at your option) any later version.
  212737. + *
  212738. + * This program is distributed in the hope that it will be useful,
  212739. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  212740. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  212741. + * GNU General Public License for more details.
  212742. + *
  212743. + * You should have received a copy of the GNU General Public License
  212744. + * along with this program; if not, write to the Free Software
  212745. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  212746. + *
  212747. + */
  212748. +/*
  212749. + * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
  212750. + * for SLISHDMI13T and SLIPHDMIT IP cores
  212751. + *
  212752. + * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  212753. + *
  212754. + * This program is free software; you can redistribute it and/or modify
  212755. + * it under the terms of the GNU General Public License version 2 as
  212756. + * published by the Free Software Foundation.
  212757. + */
  212758. +#include <linux/module.h>
  212759. +#include <linux/kernel.h>
  212760. +#include <linux/device.h>
  212761. +#include <linux/platform_device.h>
  212762. +#include <linux/input.h>
  212763. +#include <linux/interrupt.h>
  212764. +#include <linux/irq.h>
  212765. +#include <linux/io.h>
  212766. +#include <linux/fb.h>
  212767. +#include <linux/init.h>
  212768. +#include <linux/list.h>
  212769. +#include <linux/delay.h>
  212770. +#include <linux/dma-mapping.h>
  212771. +#include <linux/err.h>
  212772. +#include <linux/clk.h>
  212773. +#include <linux/uaccess.h>
  212774. +#include <linux/cpufreq.h>
  212775. +#include <linux/firmware.h>
  212776. +#include <linux/kthread.h>
  212777. +#include <linux/regulator/driver.h>
  212778. +#include <linux/fsl_devices.h>
  212779. +#include <linux/ipu.h>
  212780. +#include <linux/regmap.h>
  212781. +#include <linux/pinctrl/consumer.h>
  212782. +#include <linux/of_device.h>
  212783. +
  212784. +#include <linux/console.h>
  212785. +#include <linux/types.h>
  212786. +
  212787. +#include "../edid.h"
  212788. +#include <video/mxc_edid.h>
  212789. +#include <video/mxc_hdmi.h>
  212790. +#include "mxc_dispdrv.h"
  212791. +
  212792. +#include <linux/mfd/mxc-hdmi-core.h>
  212793. +
  212794. +#define DISPDRV_HDMI "hdmi"
  212795. +#define HDMI_EDID_LEN 512
  212796. +
  212797. +/* status codes for reading edid */
  212798. +#define HDMI_EDID_SUCCESS 0
  212799. +#define HDMI_EDID_FAIL -1
  212800. +#define HDMI_EDID_SAME -2
  212801. +#define HDMI_EDID_NO_MODES -3
  212802. +
  212803. +#define NUM_CEA_VIDEO_MODES 64
  212804. +#define DEFAULT_VIDEO_MODE 16 /* 1080P */
  212805. +
  212806. +#define RGB 0
  212807. +#define YCBCR444 1
  212808. +#define YCBCR422_16BITS 2
  212809. +#define YCBCR422_8BITS 3
  212810. +#define XVYCC444 4
  212811. +
  212812. +/*
  212813. + * We follow a flowchart which is in the "Synopsys DesignWare Courses
  212814. + * HDMI Transmitter Controller User Guide, 1.30a", section 3.1
  212815. + * (dwc_hdmi_tx_user.pdf)
  212816. + *
  212817. + * Below are notes that say "HDMI Initialization Step X"
  212818. + * These correspond to the flowchart.
  212819. + */
  212820. +
  212821. +/*
  212822. + * We are required to configure VGA mode before reading edid
  212823. + * in HDMI Initialization Step B
  212824. + */
  212825. +static const struct fb_videomode vga_mode = {
  212826. + /* 640x480 @ 60 Hz, 31.5 kHz hsync */
  212827. + NULL, 60, 640, 480, 39721, 48, 16, 33, 10, 96, 2, 0,
  212828. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, FB_MODE_IS_VESA,
  212829. +};
  212830. +
  212831. +enum hdmi_datamap {
  212832. + RGB444_8B = 0x01,
  212833. + RGB444_10B = 0x03,
  212834. + RGB444_12B = 0x05,
  212835. + RGB444_16B = 0x07,
  212836. + YCbCr444_8B = 0x09,
  212837. + YCbCr444_10B = 0x0B,
  212838. + YCbCr444_12B = 0x0D,
  212839. + YCbCr444_16B = 0x0F,
  212840. + YCbCr422_8B = 0x16,
  212841. + YCbCr422_10B = 0x14,
  212842. + YCbCr422_12B = 0x12,
  212843. +};
  212844. +
  212845. +enum hdmi_colorimetry {
  212846. + eITU601,
  212847. + eITU709,
  212848. +};
  212849. +
  212850. +struct hdmi_vmode {
  212851. + bool mDVI;
  212852. + bool mHSyncPolarity;
  212853. + bool mVSyncPolarity;
  212854. + bool mInterlaced;
  212855. + bool mDataEnablePolarity;
  212856. +
  212857. + unsigned int mPixelClock;
  212858. + unsigned int mPixelRepetitionInput;
  212859. + unsigned int mPixelRepetitionOutput;
  212860. +};
  212861. +
  212862. +struct hdmi_data_info {
  212863. + unsigned int enc_in_format;
  212864. + unsigned int enc_out_format;
  212865. + unsigned int enc_color_depth;
  212866. + unsigned int colorimetry;
  212867. + unsigned int pix_repet_factor;
  212868. + unsigned int hdcp_enable;
  212869. + unsigned int rgb_out_enable;
  212870. + struct hdmi_vmode video_mode;
  212871. +};
  212872. +
  212873. +struct hdmi_phy_reg_config {
  212874. + /* HDMI PHY register config for pass HCT */
  212875. + u16 reg_vlev;
  212876. + u16 reg_cksymtx;
  212877. +};
  212878. +
  212879. +struct mxc_hdmi {
  212880. + struct platform_device *pdev;
  212881. + struct platform_device *core_pdev;
  212882. + struct mxc_dispdrv_handle *disp_mxc_hdmi;
  212883. + struct fb_info *fbi;
  212884. + struct clk *hdmi_isfr_clk;
  212885. + struct clk *hdmi_iahb_clk;
  212886. + struct delayed_work hotplug_work;
  212887. + struct delayed_work hdcp_hdp_work;
  212888. +
  212889. + struct notifier_block nb;
  212890. +
  212891. + struct hdmi_data_info hdmi_data;
  212892. + int vic;
  212893. + struct mxc_edid_cfg edid_cfg;
  212894. + u8 edid[HDMI_EDID_LEN];
  212895. + bool fb_reg;
  212896. + bool cable_plugin;
  212897. + u8 blank;
  212898. + bool dft_mode_set;
  212899. + char *dft_mode_str;
  212900. + int default_bpp;
  212901. + u8 latest_intr_stat;
  212902. + bool irq_enabled;
  212903. + spinlock_t irq_lock;
  212904. + bool phy_enabled;
  212905. + struct fb_videomode default_mode;
  212906. + struct fb_videomode previous_non_vga_mode;
  212907. + bool requesting_vga_for_initialization;
  212908. +
  212909. + int *gpr_base;
  212910. + int *gpr_hdmi_base;
  212911. + int *gpr_sdma_base;
  212912. + int cpu_type;
  212913. + int cpu_version;
  212914. + struct hdmi_phy_reg_config phy_config;
  212915. +
  212916. + struct pinctrl *pinctrl;
  212917. +};
  212918. +
  212919. +static int hdmi_major;
  212920. +static struct class *hdmi_class;
  212921. +
  212922. +struct i2c_client *hdmi_i2c;
  212923. +struct mxc_hdmi *g_hdmi;
  212924. +
  212925. +static bool hdmi_inited;
  212926. +static bool hdcp_init;
  212927. +
  212928. +extern const struct fb_videomode mxc_cea_mode[64];
  212929. +extern void mxc_hdmi_cec_handle(u16 cec_stat);
  212930. +
  212931. +static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event);
  212932. +static void hdmi_enable_overflow_interrupts(void);
  212933. +static void hdmi_disable_overflow_interrupts(void);
  212934. +
  212935. +static struct platform_device_id imx_hdmi_devtype[] = {
  212936. + {
  212937. + .name = "hdmi-imx6DL",
  212938. + .driver_data = IMX6DL_HDMI,
  212939. + }, {
  212940. + .name = "hdmi-imx6Q",
  212941. + .driver_data = IMX6Q_HDMI,
  212942. + }, {
  212943. + /* sentinel */
  212944. + }
  212945. +};
  212946. +MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
  212947. +
  212948. +static const struct of_device_id imx_hdmi_dt_ids[] = {
  212949. + { .compatible = "fsl,imx6dl-hdmi-video", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
  212950. + { .compatible = "fsl,imx6q-hdmi-video", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
  212951. + { /* sentinel */ }
  212952. +};
  212953. +MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
  212954. +
  212955. +static inline int cpu_is_imx6dl(struct mxc_hdmi *hdmi)
  212956. +{
  212957. + return hdmi->cpu_type == IMX6DL_HDMI;
  212958. +}
  212959. +#ifdef DEBUG
  212960. +static void dump_fb_videomode(struct fb_videomode *m)
  212961. +{
  212962. + pr_debug("fb_videomode = %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
  212963. + m->refresh, m->xres, m->yres, m->pixclock, m->left_margin,
  212964. + m->right_margin, m->upper_margin, m->lower_margin,
  212965. + m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
  212966. +}
  212967. +#else
  212968. +static void dump_fb_videomode(struct fb_videomode *m)
  212969. +{}
  212970. +#endif
  212971. +
  212972. +static ssize_t mxc_hdmi_show_name(struct device *dev,
  212973. + struct device_attribute *attr, char *buf)
  212974. +{
  212975. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  212976. +
  212977. + strcpy(buf, hdmi->fbi->fix.id);
  212978. + sprintf(buf+strlen(buf), "\n");
  212979. +
  212980. + return strlen(buf);
  212981. +}
  212982. +
  212983. +static DEVICE_ATTR(fb_name, S_IRUGO, mxc_hdmi_show_name, NULL);
  212984. +
  212985. +static ssize_t mxc_hdmi_show_state(struct device *dev,
  212986. + struct device_attribute *attr, char *buf)
  212987. +{
  212988. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  212989. +
  212990. + if (hdmi->cable_plugin == false)
  212991. + strcpy(buf, "plugout\n");
  212992. + else
  212993. + strcpy(buf, "plugin\n");
  212994. +
  212995. + return strlen(buf);
  212996. +}
  212997. +
  212998. +static DEVICE_ATTR(cable_state, S_IRUGO, mxc_hdmi_show_state, NULL);
  212999. +
  213000. +static ssize_t mxc_hdmi_show_edid(struct device *dev,
  213001. + struct device_attribute *attr, char *buf)
  213002. +{
  213003. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213004. + int i, j, len = 0;
  213005. +
  213006. + for (j = 0; j < HDMI_EDID_LEN/16; j++) {
  213007. + for (i = 0; i < 16; i++)
  213008. + len += sprintf(buf+len, "0x%02X ",
  213009. + hdmi->edid[j*16 + i]);
  213010. + len += sprintf(buf+len, "\n");
  213011. + }
  213012. +
  213013. + return len;
  213014. +}
  213015. +
  213016. +static DEVICE_ATTR(edid, S_IRUGO, mxc_hdmi_show_edid, NULL);
  213017. +
  213018. +static ssize_t mxc_hdmi_show_rgb_out_enable(struct device *dev,
  213019. + struct device_attribute *attr, char *buf)
  213020. +{
  213021. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213022. +
  213023. + if (hdmi->hdmi_data.rgb_out_enable == true)
  213024. + strcpy(buf, "RGB out\n");
  213025. + else
  213026. + strcpy(buf, "YCbCr out\n");
  213027. +
  213028. + return strlen(buf);
  213029. +}
  213030. +
  213031. +static ssize_t mxc_hdmi_store_rgb_out_enable(struct device *dev,
  213032. + struct device_attribute *attr, const char *buf, size_t count)
  213033. +{
  213034. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213035. + unsigned long value;
  213036. + int ret;
  213037. +
  213038. + ret = strict_strtoul(buf, 10, &value);
  213039. + if (ret)
  213040. + return ret;
  213041. +
  213042. + hdmi->hdmi_data.rgb_out_enable = value;
  213043. +
  213044. + /* Reconfig HDMI for output color space change */
  213045. + mxc_hdmi_setup(hdmi, 0);
  213046. +
  213047. + return count;
  213048. +}
  213049. +
  213050. +static DEVICE_ATTR(rgb_out_enable, S_IRUGO | S_IWUSR,
  213051. + mxc_hdmi_show_rgb_out_enable,
  213052. + mxc_hdmi_store_rgb_out_enable);
  213053. +
  213054. +static ssize_t mxc_hdmi_show_hdcp_enable(struct device *dev,
  213055. + struct device_attribute *attr, char *buf)
  213056. +{
  213057. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213058. +
  213059. + if (hdmi->hdmi_data.hdcp_enable == false)
  213060. + strcpy(buf, "hdcp disable\n");
  213061. + else
  213062. + strcpy(buf, "hdcp enable\n");
  213063. +
  213064. + return strlen(buf);
  213065. +
  213066. +}
  213067. +
  213068. +static ssize_t mxc_hdmi_store_hdcp_enable(struct device *dev,
  213069. + struct device_attribute *attr, const char *buf, size_t count)
  213070. +{
  213071. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213072. + char event_string[32];
  213073. + char *envp[] = { event_string, NULL };
  213074. + unsigned long value;
  213075. + int ret;
  213076. +
  213077. + ret = strict_strtoul(buf, 10, &value);
  213078. + if (ret)
  213079. + return ret;
  213080. +
  213081. + hdmi->hdmi_data.hdcp_enable = value;
  213082. +
  213083. + /* Reconfig HDMI for HDCP */
  213084. + mxc_hdmi_setup(hdmi, 0);
  213085. +
  213086. + if (hdmi->hdmi_data.hdcp_enable == false) {
  213087. + sprintf(event_string, "EVENT=hdcpdisable");
  213088. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  213089. + } else {
  213090. + sprintf(event_string, "EVENT=hdcpenable");
  213091. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  213092. + }
  213093. +
  213094. + return count;
  213095. +
  213096. +}
  213097. +
  213098. +static DEVICE_ATTR(hdcp_enable, S_IRUGO | S_IWUSR,
  213099. + mxc_hdmi_show_hdcp_enable, mxc_hdmi_store_hdcp_enable);
  213100. +
  213101. +/*!
  213102. + * this submodule is responsible for the video data synchronization.
  213103. + * for example, for RGB 4:4:4 input, the data map is defined as
  213104. + * pin{47~40} <==> R[7:0]
  213105. + * pin{31~24} <==> G[7:0]
  213106. + * pin{15~8} <==> B[7:0]
  213107. + */
  213108. +static void hdmi_video_sample(struct mxc_hdmi *hdmi)
  213109. +{
  213110. + int color_format = 0;
  213111. + u8 val;
  213112. +
  213113. + if (hdmi->hdmi_data.enc_in_format == RGB) {
  213114. + if (hdmi->hdmi_data.enc_color_depth == 8)
  213115. + color_format = 0x01;
  213116. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  213117. + color_format = 0x03;
  213118. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  213119. + color_format = 0x05;
  213120. + else if (hdmi->hdmi_data.enc_color_depth == 16)
  213121. + color_format = 0x07;
  213122. + else
  213123. + return;
  213124. + } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) {
  213125. + if (hdmi->hdmi_data.enc_color_depth == 8)
  213126. + color_format = 0x09;
  213127. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  213128. + color_format = 0x0B;
  213129. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  213130. + color_format = 0x0D;
  213131. + else if (hdmi->hdmi_data.enc_color_depth == 16)
  213132. + color_format = 0x0F;
  213133. + else
  213134. + return;
  213135. + } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) {
  213136. + if (hdmi->hdmi_data.enc_color_depth == 8)
  213137. + color_format = 0x16;
  213138. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  213139. + color_format = 0x14;
  213140. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  213141. + color_format = 0x12;
  213142. + else
  213143. + return;
  213144. + }
  213145. +
  213146. + val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
  213147. + ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
  213148. + HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
  213149. + hdmi_writeb(val, HDMI_TX_INVID0);
  213150. +
  213151. + /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
  213152. + val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
  213153. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
  213154. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
  213155. + hdmi_writeb(val, HDMI_TX_INSTUFFING);
  213156. + hdmi_writeb(0x0, HDMI_TX_GYDATA0);
  213157. + hdmi_writeb(0x0, HDMI_TX_GYDATA1);
  213158. + hdmi_writeb(0x0, HDMI_TX_RCRDATA0);
  213159. + hdmi_writeb(0x0, HDMI_TX_RCRDATA1);
  213160. + hdmi_writeb(0x0, HDMI_TX_BCBDATA0);
  213161. + hdmi_writeb(0x0, HDMI_TX_BCBDATA1);
  213162. +}
  213163. +
  213164. +static int isColorSpaceConversion(struct mxc_hdmi *hdmi)
  213165. +{
  213166. + return (hdmi->hdmi_data.enc_in_format !=
  213167. + hdmi->hdmi_data.enc_out_format);
  213168. +}
  213169. +
  213170. +static int isColorSpaceDecimation(struct mxc_hdmi *hdmi)
  213171. +{
  213172. + return ((hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) &&
  213173. + (hdmi->hdmi_data.enc_in_format == RGB ||
  213174. + hdmi->hdmi_data.enc_in_format == YCBCR444));
  213175. +}
  213176. +
  213177. +static int isColorSpaceInterpolation(struct mxc_hdmi *hdmi)
  213178. +{
  213179. + return ((hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) &&
  213180. + (hdmi->hdmi_data.enc_out_format == RGB
  213181. + || hdmi->hdmi_data.enc_out_format == YCBCR444));
  213182. +}
  213183. +
  213184. +/*!
  213185. + * update the color space conversion coefficients.
  213186. + */
  213187. +static void update_csc_coeffs(struct mxc_hdmi *hdmi)
  213188. +{
  213189. + unsigned short csc_coeff[3][4];
  213190. + unsigned int csc_scale = 1;
  213191. + u8 val;
  213192. + bool coeff_selected = false;
  213193. +
  213194. + if (isColorSpaceConversion(hdmi)) { /* csc needed */
  213195. + if (hdmi->hdmi_data.enc_out_format == RGB) {
  213196. + if (hdmi->hdmi_data.colorimetry == eITU601) {
  213197. + csc_coeff[0][0] = 0x2000;
  213198. + csc_coeff[0][1] = 0x6926;
  213199. + csc_coeff[0][2] = 0x74fd;
  213200. + csc_coeff[0][3] = 0x010e;
  213201. +
  213202. + csc_coeff[1][0] = 0x2000;
  213203. + csc_coeff[1][1] = 0x2cdd;
  213204. + csc_coeff[1][2] = 0x0000;
  213205. + csc_coeff[1][3] = 0x7e9a;
  213206. +
  213207. + csc_coeff[2][0] = 0x2000;
  213208. + csc_coeff[2][1] = 0x0000;
  213209. + csc_coeff[2][2] = 0x38b4;
  213210. + csc_coeff[2][3] = 0x7e3b;
  213211. +
  213212. + csc_scale = 1;
  213213. + coeff_selected = true;
  213214. + } else if (hdmi->hdmi_data.colorimetry == eITU709) {
  213215. + csc_coeff[0][0] = 0x2000;
  213216. + csc_coeff[0][1] = 0x7106;
  213217. + csc_coeff[0][2] = 0x7a02;
  213218. + csc_coeff[0][3] = 0x00a7;
  213219. +
  213220. + csc_coeff[1][0] = 0x2000;
  213221. + csc_coeff[1][1] = 0x3264;
  213222. + csc_coeff[1][2] = 0x0000;
  213223. + csc_coeff[1][3] = 0x7e6d;
  213224. +
  213225. + csc_coeff[2][0] = 0x2000;
  213226. + csc_coeff[2][1] = 0x0000;
  213227. + csc_coeff[2][2] = 0x3b61;
  213228. + csc_coeff[2][3] = 0x7e25;
  213229. +
  213230. + csc_scale = 1;
  213231. + coeff_selected = true;
  213232. + }
  213233. + } else if (hdmi->hdmi_data.enc_in_format == RGB) {
  213234. + if (hdmi->hdmi_data.colorimetry == eITU601) {
  213235. + csc_coeff[0][0] = 0x2591;
  213236. + csc_coeff[0][1] = 0x1322;
  213237. + csc_coeff[0][2] = 0x074b;
  213238. + csc_coeff[0][3] = 0x0000;
  213239. +
  213240. + csc_coeff[1][0] = 0x6535;
  213241. + csc_coeff[1][1] = 0x2000;
  213242. + csc_coeff[1][2] = 0x7acc;
  213243. + csc_coeff[1][3] = 0x0200;
  213244. +
  213245. + csc_coeff[2][0] = 0x6acd;
  213246. + csc_coeff[2][1] = 0x7534;
  213247. + csc_coeff[2][2] = 0x2000;
  213248. + csc_coeff[2][3] = 0x0200;
  213249. +
  213250. + csc_scale = 0;
  213251. + coeff_selected = true;
  213252. + } else if (hdmi->hdmi_data.colorimetry == eITU709) {
  213253. + csc_coeff[0][0] = 0x2dc5;
  213254. + csc_coeff[0][1] = 0x0d9b;
  213255. + csc_coeff[0][2] = 0x049e;
  213256. + csc_coeff[0][3] = 0x0000;
  213257. +
  213258. + csc_coeff[1][0] = 0x62f0;
  213259. + csc_coeff[1][1] = 0x2000;
  213260. + csc_coeff[1][2] = 0x7d11;
  213261. + csc_coeff[1][3] = 0x0200;
  213262. +
  213263. + csc_coeff[2][0] = 0x6756;
  213264. + csc_coeff[2][1] = 0x78ab;
  213265. + csc_coeff[2][2] = 0x2000;
  213266. + csc_coeff[2][3] = 0x0200;
  213267. +
  213268. + csc_scale = 0;
  213269. + coeff_selected = true;
  213270. + }
  213271. + }
  213272. + }
  213273. +
  213274. + if (!coeff_selected) {
  213275. + csc_coeff[0][0] = 0x2000;
  213276. + csc_coeff[0][1] = 0x0000;
  213277. + csc_coeff[0][2] = 0x0000;
  213278. + csc_coeff[0][3] = 0x0000;
  213279. +
  213280. + csc_coeff[1][0] = 0x0000;
  213281. + csc_coeff[1][1] = 0x2000;
  213282. + csc_coeff[1][2] = 0x0000;
  213283. + csc_coeff[1][3] = 0x0000;
  213284. +
  213285. + csc_coeff[2][0] = 0x0000;
  213286. + csc_coeff[2][1] = 0x0000;
  213287. + csc_coeff[2][2] = 0x2000;
  213288. + csc_coeff[2][3] = 0x0000;
  213289. +
  213290. + csc_scale = 1;
  213291. + }
  213292. +
  213293. + /* Update CSC parameters in HDMI CSC registers */
  213294. + hdmi_writeb((unsigned char)(csc_coeff[0][0] & 0xFF),
  213295. + HDMI_CSC_COEF_A1_LSB);
  213296. + hdmi_writeb((unsigned char)(csc_coeff[0][0] >> 8),
  213297. + HDMI_CSC_COEF_A1_MSB);
  213298. + hdmi_writeb((unsigned char)(csc_coeff[0][1] & 0xFF),
  213299. + HDMI_CSC_COEF_A2_LSB);
  213300. + hdmi_writeb((unsigned char)(csc_coeff[0][1] >> 8),
  213301. + HDMI_CSC_COEF_A2_MSB);
  213302. + hdmi_writeb((unsigned char)(csc_coeff[0][2] & 0xFF),
  213303. + HDMI_CSC_COEF_A3_LSB);
  213304. + hdmi_writeb((unsigned char)(csc_coeff[0][2] >> 8),
  213305. + HDMI_CSC_COEF_A3_MSB);
  213306. + hdmi_writeb((unsigned char)(csc_coeff[0][3] & 0xFF),
  213307. + HDMI_CSC_COEF_A4_LSB);
  213308. + hdmi_writeb((unsigned char)(csc_coeff[0][3] >> 8),
  213309. + HDMI_CSC_COEF_A4_MSB);
  213310. +
  213311. + hdmi_writeb((unsigned char)(csc_coeff[1][0] & 0xFF),
  213312. + HDMI_CSC_COEF_B1_LSB);
  213313. + hdmi_writeb((unsigned char)(csc_coeff[1][0] >> 8),
  213314. + HDMI_CSC_COEF_B1_MSB);
  213315. + hdmi_writeb((unsigned char)(csc_coeff[1][1] & 0xFF),
  213316. + HDMI_CSC_COEF_B2_LSB);
  213317. + hdmi_writeb((unsigned char)(csc_coeff[1][1] >> 8),
  213318. + HDMI_CSC_COEF_B2_MSB);
  213319. + hdmi_writeb((unsigned char)(csc_coeff[1][2] & 0xFF),
  213320. + HDMI_CSC_COEF_B3_LSB);
  213321. + hdmi_writeb((unsigned char)(csc_coeff[1][2] >> 8),
  213322. + HDMI_CSC_COEF_B3_MSB);
  213323. + hdmi_writeb((unsigned char)(csc_coeff[1][3] & 0xFF),
  213324. + HDMI_CSC_COEF_B4_LSB);
  213325. + hdmi_writeb((unsigned char)(csc_coeff[1][3] >> 8),
  213326. + HDMI_CSC_COEF_B4_MSB);
  213327. +
  213328. + hdmi_writeb((unsigned char)(csc_coeff[2][0] & 0xFF),
  213329. + HDMI_CSC_COEF_C1_LSB);
  213330. + hdmi_writeb((unsigned char)(csc_coeff[2][0] >> 8),
  213331. + HDMI_CSC_COEF_C1_MSB);
  213332. + hdmi_writeb((unsigned char)(csc_coeff[2][1] & 0xFF),
  213333. + HDMI_CSC_COEF_C2_LSB);
  213334. + hdmi_writeb((unsigned char)(csc_coeff[2][1] >> 8),
  213335. + HDMI_CSC_COEF_C2_MSB);
  213336. + hdmi_writeb((unsigned char)(csc_coeff[2][2] & 0xFF),
  213337. + HDMI_CSC_COEF_C3_LSB);
  213338. + hdmi_writeb((unsigned char)(csc_coeff[2][2] >> 8),
  213339. + HDMI_CSC_COEF_C3_MSB);
  213340. + hdmi_writeb((unsigned char)(csc_coeff[2][3] & 0xFF),
  213341. + HDMI_CSC_COEF_C4_LSB);
  213342. + hdmi_writeb((unsigned char)(csc_coeff[2][3] >> 8),
  213343. + HDMI_CSC_COEF_C4_MSB);
  213344. +
  213345. + val = hdmi_readb(HDMI_CSC_SCALE);
  213346. + val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK;
  213347. + val |= csc_scale & HDMI_CSC_SCALE_CSCSCALE_MASK;
  213348. + hdmi_writeb(val, HDMI_CSC_SCALE);
  213349. +}
  213350. +
  213351. +static void hdmi_video_csc(struct mxc_hdmi *hdmi)
  213352. +{
  213353. + int color_depth = 0;
  213354. + int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
  213355. + int decimation = 0;
  213356. + u8 val;
  213357. +
  213358. + /* YCC422 interpolation to 444 mode */
  213359. + if (isColorSpaceInterpolation(hdmi))
  213360. + interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
  213361. + else if (isColorSpaceDecimation(hdmi))
  213362. + decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
  213363. +
  213364. + if (hdmi->hdmi_data.enc_color_depth == 8)
  213365. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
  213366. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  213367. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
  213368. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  213369. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
  213370. + else if (hdmi->hdmi_data.enc_color_depth == 16)
  213371. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
  213372. + else
  213373. + return;
  213374. +
  213375. + /*configure the CSC registers */
  213376. + hdmi_writeb(interpolation | decimation, HDMI_CSC_CFG);
  213377. + val = hdmi_readb(HDMI_CSC_SCALE);
  213378. + val &= ~HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK;
  213379. + val |= color_depth;
  213380. + hdmi_writeb(val, HDMI_CSC_SCALE);
  213381. +
  213382. + update_csc_coeffs(hdmi);
  213383. +}
  213384. +
  213385. +/*!
  213386. + * HDMI video packetizer is used to packetize the data.
  213387. + * for example, if input is YCC422 mode or repeater is used,
  213388. + * data should be repacked this module can be bypassed.
  213389. + */
  213390. +static void hdmi_video_packetize(struct mxc_hdmi *hdmi)
  213391. +{
  213392. + unsigned int color_depth = 0;
  213393. + unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
  213394. + unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
  213395. + struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
  213396. + u8 val;
  213397. +
  213398. + if (hdmi_data->enc_out_format == RGB
  213399. + || hdmi_data->enc_out_format == YCBCR444) {
  213400. + if (hdmi_data->enc_color_depth == 0)
  213401. + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
  213402. + else if (hdmi_data->enc_color_depth == 8) {
  213403. + color_depth = 4;
  213404. + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
  213405. + } else if (hdmi_data->enc_color_depth == 10)
  213406. + color_depth = 5;
  213407. + else if (hdmi_data->enc_color_depth == 12)
  213408. + color_depth = 6;
  213409. + else if (hdmi_data->enc_color_depth == 16)
  213410. + color_depth = 7;
  213411. + else
  213412. + return;
  213413. + } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
  213414. + if (hdmi_data->enc_color_depth == 0 ||
  213415. + hdmi_data->enc_color_depth == 8)
  213416. + remap_size = HDMI_VP_REMAP_YCC422_16bit;
  213417. + else if (hdmi_data->enc_color_depth == 10)
  213418. + remap_size = HDMI_VP_REMAP_YCC422_20bit;
  213419. + else if (hdmi_data->enc_color_depth == 12)
  213420. + remap_size = HDMI_VP_REMAP_YCC422_24bit;
  213421. + else
  213422. + return;
  213423. + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
  213424. + } else
  213425. + return;
  213426. +
  213427. + /* HDMI not support deep color,
  213428. + * because IPU MAX support color depth is 24bit */
  213429. + color_depth = 0;
  213430. +
  213431. + /* set the packetizer registers */
  213432. + val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
  213433. + HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
  213434. + ((hdmi_data->pix_repet_factor <<
  213435. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
  213436. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
  213437. + hdmi_writeb(val, HDMI_VP_PR_CD);
  213438. +
  213439. + val = hdmi_readb(HDMI_VP_STUFF);
  213440. + val &= ~HDMI_VP_STUFF_PR_STUFFING_MASK;
  213441. + val |= HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE;
  213442. + hdmi_writeb(val, HDMI_VP_STUFF);
  213443. +
  213444. + /* Data from pixel repeater block */
  213445. + if (hdmi_data->pix_repet_factor > 1) {
  213446. + val = hdmi_readb(HDMI_VP_CONF);
  213447. + val &= ~(HDMI_VP_CONF_PR_EN_MASK |
  213448. + HDMI_VP_CONF_BYPASS_SELECT_MASK);
  213449. + val |= HDMI_VP_CONF_PR_EN_ENABLE |
  213450. + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
  213451. + hdmi_writeb(val, HDMI_VP_CONF);
  213452. + } else { /* data from packetizer block */
  213453. + val = hdmi_readb(HDMI_VP_CONF);
  213454. + val &= ~(HDMI_VP_CONF_PR_EN_MASK |
  213455. + HDMI_VP_CONF_BYPASS_SELECT_MASK);
  213456. + val |= HDMI_VP_CONF_PR_EN_DISABLE |
  213457. + HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
  213458. + hdmi_writeb(val, HDMI_VP_CONF);
  213459. + }
  213460. +
  213461. + val = hdmi_readb(HDMI_VP_STUFF);
  213462. + val &= ~HDMI_VP_STUFF_IDEFAULT_PHASE_MASK;
  213463. + val |= 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET;
  213464. + hdmi_writeb(val, HDMI_VP_STUFF);
  213465. +
  213466. + hdmi_writeb(remap_size, HDMI_VP_REMAP);
  213467. +
  213468. + if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
  213469. + val = hdmi_readb(HDMI_VP_CONF);
  213470. + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
  213471. + HDMI_VP_CONF_PP_EN_ENMASK |
  213472. + HDMI_VP_CONF_YCC422_EN_MASK);
  213473. + val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
  213474. + HDMI_VP_CONF_PP_EN_ENABLE |
  213475. + HDMI_VP_CONF_YCC422_EN_DISABLE;
  213476. + hdmi_writeb(val, HDMI_VP_CONF);
  213477. + } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
  213478. + val = hdmi_readb(HDMI_VP_CONF);
  213479. + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
  213480. + HDMI_VP_CONF_PP_EN_ENMASK |
  213481. + HDMI_VP_CONF_YCC422_EN_MASK);
  213482. + val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
  213483. + HDMI_VP_CONF_PP_EN_DISABLE |
  213484. + HDMI_VP_CONF_YCC422_EN_ENABLE;
  213485. + hdmi_writeb(val, HDMI_VP_CONF);
  213486. + } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
  213487. + val = hdmi_readb(HDMI_VP_CONF);
  213488. + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
  213489. + HDMI_VP_CONF_PP_EN_ENMASK |
  213490. + HDMI_VP_CONF_YCC422_EN_MASK);
  213491. + val |= HDMI_VP_CONF_BYPASS_EN_ENABLE |
  213492. + HDMI_VP_CONF_PP_EN_DISABLE |
  213493. + HDMI_VP_CONF_YCC422_EN_DISABLE;
  213494. + hdmi_writeb(val, HDMI_VP_CONF);
  213495. + } else {
  213496. + return;
  213497. + }
  213498. +
  213499. + val = hdmi_readb(HDMI_VP_STUFF);
  213500. + val &= ~(HDMI_VP_STUFF_PP_STUFFING_MASK |
  213501. + HDMI_VP_STUFF_YCC422_STUFFING_MASK);
  213502. + val |= HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
  213503. + HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE;
  213504. + hdmi_writeb(val, HDMI_VP_STUFF);
  213505. +
  213506. + val = hdmi_readb(HDMI_VP_CONF);
  213507. + val &= ~HDMI_VP_CONF_OUTPUT_SELECTOR_MASK;
  213508. + val |= output_select;
  213509. + hdmi_writeb(val, HDMI_VP_CONF);
  213510. +}
  213511. +
  213512. +#if 0
  213513. +/* Force a fixed color screen */
  213514. +static void hdmi_video_force_output(struct mxc_hdmi *hdmi, unsigned char force)
  213515. +{
  213516. + u8 val;
  213517. +
  213518. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  213519. +
  213520. + if (force) {
  213521. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */
  213522. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */
  213523. + hdmi_writeb(0xFF, HDMI_FC_DBGTMDS0); /* B */
  213524. + val = hdmi_readb(HDMI_FC_DBGFORCE);
  213525. + val |= HDMI_FC_DBGFORCE_FORCEVIDEO;
  213526. + hdmi_writeb(val, HDMI_FC_DBGFORCE);
  213527. + } else {
  213528. + val = hdmi_readb(HDMI_FC_DBGFORCE);
  213529. + val &= ~HDMI_FC_DBGFORCE_FORCEVIDEO;
  213530. + hdmi_writeb(val, HDMI_FC_DBGFORCE);
  213531. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */
  213532. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */
  213533. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS0); /* B */
  213534. + }
  213535. +}
  213536. +#endif
  213537. +
  213538. +static inline void hdmi_phy_test_clear(struct mxc_hdmi *hdmi,
  213539. + unsigned char bit)
  213540. +{
  213541. + u8 val = hdmi_readb(HDMI_PHY_TST0);
  213542. + val &= ~HDMI_PHY_TST0_TSTCLR_MASK;
  213543. + val |= (bit << HDMI_PHY_TST0_TSTCLR_OFFSET) &
  213544. + HDMI_PHY_TST0_TSTCLR_MASK;
  213545. + hdmi_writeb(val, HDMI_PHY_TST0);
  213546. +}
  213547. +
  213548. +static inline void hdmi_phy_test_enable(struct mxc_hdmi *hdmi,
  213549. + unsigned char bit)
  213550. +{
  213551. + u8 val = hdmi_readb(HDMI_PHY_TST0);
  213552. + val &= ~HDMI_PHY_TST0_TSTEN_MASK;
  213553. + val |= (bit << HDMI_PHY_TST0_TSTEN_OFFSET) &
  213554. + HDMI_PHY_TST0_TSTEN_MASK;
  213555. + hdmi_writeb(val, HDMI_PHY_TST0);
  213556. +}
  213557. +
  213558. +static inline void hdmi_phy_test_clock(struct mxc_hdmi *hdmi,
  213559. + unsigned char bit)
  213560. +{
  213561. + u8 val = hdmi_readb(HDMI_PHY_TST0);
  213562. + val &= ~HDMI_PHY_TST0_TSTCLK_MASK;
  213563. + val |= (bit << HDMI_PHY_TST0_TSTCLK_OFFSET) &
  213564. + HDMI_PHY_TST0_TSTCLK_MASK;
  213565. + hdmi_writeb(val, HDMI_PHY_TST0);
  213566. +}
  213567. +
  213568. +static inline void hdmi_phy_test_din(struct mxc_hdmi *hdmi,
  213569. + unsigned char bit)
  213570. +{
  213571. + hdmi_writeb(bit, HDMI_PHY_TST1);
  213572. +}
  213573. +
  213574. +static inline void hdmi_phy_test_dout(struct mxc_hdmi *hdmi,
  213575. + unsigned char bit)
  213576. +{
  213577. + hdmi_writeb(bit, HDMI_PHY_TST2);
  213578. +}
  213579. +
  213580. +static bool hdmi_phy_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
  213581. +{
  213582. + unsigned char val = 0;
  213583. + val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
  213584. + while (val == 0) {
  213585. + udelay(1000);
  213586. + if (msec-- == 0)
  213587. + return false;
  213588. + val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
  213589. + }
  213590. + return true;
  213591. +}
  213592. +
  213593. +static void hdmi_phy_i2c_write(struct mxc_hdmi *hdmi, unsigned short data,
  213594. + unsigned char addr)
  213595. +{
  213596. + hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
  213597. + hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
  213598. + hdmi_writeb((unsigned char)(data >> 8),
  213599. + HDMI_PHY_I2CM_DATAO_1_ADDR);
  213600. + hdmi_writeb((unsigned char)(data >> 0),
  213601. + HDMI_PHY_I2CM_DATAO_0_ADDR);
  213602. + hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
  213603. + HDMI_PHY_I2CM_OPERATION_ADDR);
  213604. + hdmi_phy_wait_i2c_done(hdmi, 1000);
  213605. +}
  213606. +
  213607. +#if 0
  213608. +static unsigned short hdmi_phy_i2c_read(struct mxc_hdmi *hdmi,
  213609. + unsigned char addr)
  213610. +{
  213611. + unsigned short data;
  213612. + unsigned char msb = 0, lsb = 0;
  213613. + hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
  213614. + hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
  213615. + hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_READ,
  213616. + HDMI_PHY_I2CM_OPERATION_ADDR);
  213617. + hdmi_phy_wait_i2c_done(hdmi, 1000);
  213618. + msb = hdmi_readb(HDMI_PHY_I2CM_DATAI_1_ADDR);
  213619. + lsb = hdmi_readb(HDMI_PHY_I2CM_DATAI_0_ADDR);
  213620. + data = (msb << 8) | lsb;
  213621. + return data;
  213622. +}
  213623. +
  213624. +static int hdmi_phy_i2c_write_verify(struct mxc_hdmi *hdmi, unsigned short data,
  213625. + unsigned char addr)
  213626. +{
  213627. + unsigned short val = 0;
  213628. + hdmi_phy_i2c_write(hdmi, data, addr);
  213629. + val = hdmi_phy_i2c_read(hdmi, addr);
  213630. + return (val == data);
  213631. +}
  213632. +#endif
  213633. +
  213634. +static bool hdmi_edid_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
  213635. +{
  213636. + unsigned char val = 0;
  213637. + val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2;
  213638. + while (val == 0) {
  213639. +
  213640. + udelay(1000);
  213641. + if (msec-- == 0) {
  213642. + dev_dbg(&hdmi->pdev->dev,
  213643. + "HDMI EDID i2c operation time out!!\n");
  213644. + return false;
  213645. + }
  213646. + val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2;
  213647. + }
  213648. + return true;
  213649. +}
  213650. +
  213651. +static u8 hdmi_edid_i2c_read(struct mxc_hdmi *hdmi,
  213652. + u8 addr, u8 blockno)
  213653. +{
  213654. + u8 spointer = blockno / 2;
  213655. + u8 edidaddress = ((blockno % 2) * 0x80) + addr;
  213656. + u8 data;
  213657. +
  213658. + hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0);
  213659. + hdmi_writeb(edidaddress, HDMI_I2CM_ADDRESS);
  213660. + hdmi_writeb(spointer, HDMI_I2CM_SEGADDR);
  213661. + if (spointer == 0)
  213662. + hdmi_writeb(HDMI_I2CM_OPERATION_READ,
  213663. + HDMI_I2CM_OPERATION);
  213664. + else
  213665. + hdmi_writeb(HDMI_I2CM_OPERATION_READ_EXT,
  213666. + HDMI_I2CM_OPERATION);
  213667. +
  213668. + hdmi_edid_wait_i2c_done(hdmi, 1000);
  213669. + data = hdmi_readb(HDMI_I2CM_DATAI);
  213670. + hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0);
  213671. + return data;
  213672. +}
  213673. +
  213674. +
  213675. +/* "Power-down enable (active low)"
  213676. + * That mean that power up == 1! */
  213677. +static void mxc_hdmi_phy_enable_power(u8 enable)
  213678. +{
  213679. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  213680. + HDMI_PHY_CONF0_PDZ_OFFSET,
  213681. + HDMI_PHY_CONF0_PDZ_MASK);
  213682. +}
  213683. +
  213684. +static void mxc_hdmi_phy_enable_tmds(u8 enable)
  213685. +{
  213686. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  213687. + HDMI_PHY_CONF0_ENTMDS_OFFSET,
  213688. + HDMI_PHY_CONF0_ENTMDS_MASK);
  213689. +}
  213690. +
  213691. +static void mxc_hdmi_phy_gen2_pddq(u8 enable)
  213692. +{
  213693. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  213694. + HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
  213695. + HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
  213696. +}
  213697. +
  213698. +static void mxc_hdmi_phy_gen2_txpwron(u8 enable)
  213699. +{
  213700. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  213701. + HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
  213702. + HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
  213703. +}
  213704. +
  213705. +#if 0
  213706. +static void mxc_hdmi_phy_gen2_enhpdrxsense(u8 enable)
  213707. +{
  213708. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  213709. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET,
  213710. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK);
  213711. +}
  213712. +#endif
  213713. +
  213714. +static void mxc_hdmi_phy_sel_data_en_pol(u8 enable)
  213715. +{
  213716. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  213717. + HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
  213718. + HDMI_PHY_CONF0_SELDATAENPOL_MASK);
  213719. +}
  213720. +
  213721. +static void mxc_hdmi_phy_sel_interface_control(u8 enable)
  213722. +{
  213723. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  213724. + HDMI_PHY_CONF0_SELDIPIF_OFFSET,
  213725. + HDMI_PHY_CONF0_SELDIPIF_MASK);
  213726. +}
  213727. +
  213728. +static int hdmi_phy_configure(struct mxc_hdmi *hdmi, unsigned char pRep,
  213729. + unsigned char cRes, int cscOn)
  213730. +{
  213731. + u8 val;
  213732. + u8 msec;
  213733. +
  213734. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  213735. +
  213736. + /* color resolution 0 is 8 bit colour depth */
  213737. + if (cRes == 0)
  213738. + cRes = 8;
  213739. +
  213740. + if (pRep != 0)
  213741. + return false;
  213742. + else if (cRes != 8 && cRes != 12)
  213743. + return false;
  213744. +
  213745. + /* Enable csc path */
  213746. + if (cscOn)
  213747. + val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
  213748. + else
  213749. + val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
  213750. +
  213751. + hdmi_writeb(val, HDMI_MC_FLOWCTRL);
  213752. +
  213753. + /* gen2 tx power off */
  213754. + mxc_hdmi_phy_gen2_txpwron(0);
  213755. +
  213756. + /* gen2 pddq */
  213757. + mxc_hdmi_phy_gen2_pddq(1);
  213758. +
  213759. + /* PHY reset */
  213760. + hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
  213761. + hdmi_writeb(HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
  213762. +
  213763. + hdmi_writeb(HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
  213764. +
  213765. + hdmi_phy_test_clear(hdmi, 1);
  213766. + hdmi_writeb(HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
  213767. + HDMI_PHY_I2CM_SLAVE_ADDR);
  213768. + hdmi_phy_test_clear(hdmi, 0);
  213769. +
  213770. + if (hdmi->hdmi_data.video_mode.mPixelClock < 0) {
  213771. + dev_dbg(&hdmi->pdev->dev, "Pixel clock (%d) must be positive\n",
  213772. + hdmi->hdmi_data.video_mode.mPixelClock);
  213773. + return false;
  213774. + }
  213775. +
  213776. + if (hdmi->hdmi_data.video_mode.mPixelClock <= 45250000) {
  213777. + switch (cRes) {
  213778. + case 8:
  213779. + /* PLL/MPLL Cfg */
  213780. + hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06);
  213781. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); /* GMPCTRL */
  213782. + break;
  213783. + case 10:
  213784. + hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06);
  213785. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
  213786. + break;
  213787. + case 12:
  213788. + hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06);
  213789. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
  213790. + break;
  213791. + default:
  213792. + return false;
  213793. + }
  213794. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 92500000) {
  213795. + switch (cRes) {
  213796. + case 8:
  213797. + hdmi_phy_i2c_write(hdmi, 0x0140, 0x06);
  213798. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
  213799. + break;
  213800. + case 10:
  213801. + hdmi_phy_i2c_write(hdmi, 0x2141, 0x06);
  213802. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
  213803. + break;
  213804. + case 12:
  213805. + hdmi_phy_i2c_write(hdmi, 0x4142, 0x06);
  213806. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
  213807. + default:
  213808. + return false;
  213809. + }
  213810. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 148500000) {
  213811. + switch (cRes) {
  213812. + case 8:
  213813. + hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
  213814. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  213815. + break;
  213816. + case 10:
  213817. + hdmi_phy_i2c_write(hdmi, 0x20a1, 0x06);
  213818. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  213819. + break;
  213820. + case 12:
  213821. + hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06);
  213822. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  213823. + default:
  213824. + return false;
  213825. + }
  213826. + } else {
  213827. + switch (cRes) {
  213828. + case 8:
  213829. + hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
  213830. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  213831. + break;
  213832. + case 10:
  213833. + hdmi_phy_i2c_write(hdmi, 0x2001, 0x06);
  213834. + hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
  213835. + break;
  213836. + case 12:
  213837. + hdmi_phy_i2c_write(hdmi, 0x4002, 0x06);
  213838. + hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
  213839. + default:
  213840. + return false;
  213841. + }
  213842. + }
  213843. +
  213844. + if (hdmi->hdmi_data.video_mode.mPixelClock <= 54000000) {
  213845. + switch (cRes) {
  213846. + case 8:
  213847. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); /* CURRCTRL */
  213848. + break;
  213849. + case 10:
  213850. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  213851. + break;
  213852. + case 12:
  213853. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  213854. + break;
  213855. + default:
  213856. + return false;
  213857. + }
  213858. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 58400000) {
  213859. + switch (cRes) {
  213860. + case 8:
  213861. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  213862. + break;
  213863. + case 10:
  213864. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  213865. + break;
  213866. + case 12:
  213867. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  213868. + break;
  213869. + default:
  213870. + return false;
  213871. + }
  213872. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 72000000) {
  213873. + switch (cRes) {
  213874. + case 8:
  213875. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  213876. + break;
  213877. + case 10:
  213878. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  213879. + break;
  213880. + case 12:
  213881. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  213882. + break;
  213883. + default:
  213884. + return false;
  213885. + }
  213886. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 74250000) {
  213887. + switch (cRes) {
  213888. + case 8:
  213889. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  213890. + break;
  213891. + case 10:
  213892. + hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
  213893. + break;
  213894. + case 12:
  213895. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  213896. + break;
  213897. + default:
  213898. + return false;
  213899. + }
  213900. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 118800000) {
  213901. + switch (cRes) {
  213902. + case 8:
  213903. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  213904. + break;
  213905. + case 10:
  213906. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  213907. + break;
  213908. + case 12:
  213909. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  213910. + break;
  213911. + default:
  213912. + return false;
  213913. + }
  213914. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 216000000) {
  213915. + switch (cRes) {
  213916. + case 8:
  213917. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  213918. + break;
  213919. + case 10:
  213920. + hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
  213921. + break;
  213922. + case 12:
  213923. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  213924. + break;
  213925. + default:
  213926. + return false;
  213927. + }
  213928. + } else {
  213929. + dev_err(&hdmi->pdev->dev,
  213930. + "Pixel clock %d - unsupported by HDMI\n",
  213931. + hdmi->hdmi_data.video_mode.mPixelClock);
  213932. + return false;
  213933. + }
  213934. +
  213935. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */
  213936. + hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
  213937. + /* RESISTANCE TERM 133Ohm Cfg */
  213938. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */
  213939. + /* PREEMP Cgf 0.00 */
  213940. + hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */
  213941. + /* TX/CK LVL 10 */
  213942. + hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */
  213943. +
  213944. + /* Board specific setting for PHY register 0x09, 0x0e to pass HCT */
  213945. + if (hdmi->phy_config.reg_cksymtx != 0)
  213946. + hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_cksymtx, 0x09);
  213947. +
  213948. + if (hdmi->phy_config.reg_vlev != 0)
  213949. + hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_vlev, 0x0E);
  213950. +
  213951. + /* REMOVE CLK TERM */
  213952. + hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */
  213953. +
  213954. + if (hdmi->hdmi_data.video_mode.mPixelClock > 148500000) {
  213955. + hdmi_phy_i2c_write(hdmi, 0x800b, 0x09);
  213956. + hdmi_phy_i2c_write(hdmi, 0x0129, 0x0E);
  213957. + }
  213958. +
  213959. + mxc_hdmi_phy_enable_power(1);
  213960. +
  213961. + /* toggle TMDS enable */
  213962. + mxc_hdmi_phy_enable_tmds(0);
  213963. + mxc_hdmi_phy_enable_tmds(1);
  213964. +
  213965. + /* gen2 tx power on */
  213966. + mxc_hdmi_phy_gen2_txpwron(1);
  213967. + mxc_hdmi_phy_gen2_pddq(0);
  213968. +
  213969. + /*Wait for PHY PLL lock */
  213970. + msec = 4;
  213971. + val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
  213972. + while (val == 0) {
  213973. + udelay(1000);
  213974. + if (msec-- == 0) {
  213975. + dev_dbg(&hdmi->pdev->dev, "PHY PLL not locked\n");
  213976. + return false;
  213977. + }
  213978. + val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
  213979. + }
  213980. +
  213981. + return true;
  213982. +}
  213983. +
  213984. +static void mxc_hdmi_phy_init(struct mxc_hdmi *hdmi)
  213985. +{
  213986. + int i;
  213987. + bool cscon = false;
  213988. +
  213989. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  213990. +
  213991. + /* Never do phy init if pixel clock is gated.
  213992. + * Otherwise HDMI PHY will get messed up and generate an overflow
  213993. + * interrupt that can't be cleared or detected by accessing the
  213994. + * status register. */
  213995. + if (!hdmi->fb_reg || !hdmi->cable_plugin
  213996. + || (hdmi->blank != FB_BLANK_UNBLANK))
  213997. + return;
  213998. +
  213999. + /*check csc whether needed activated in HDMI mode */
  214000. + cscon = (isColorSpaceConversion(hdmi) &&
  214001. + !hdmi->hdmi_data.video_mode.mDVI);
  214002. +
  214003. + /* HDMI Phy spec says to do the phy initialization sequence twice */
  214004. + for (i = 0 ; i < 2 ; i++) {
  214005. + mxc_hdmi_phy_sel_data_en_pol(1);
  214006. + mxc_hdmi_phy_sel_interface_control(0);
  214007. + mxc_hdmi_phy_enable_tmds(0);
  214008. + mxc_hdmi_phy_enable_power(0);
  214009. +
  214010. + /* Enable CSC */
  214011. + hdmi_phy_configure(hdmi, 0, 8, cscon);
  214012. + }
  214013. +
  214014. + hdmi->phy_enabled = true;
  214015. + if (!hdmi->hdmi_data.video_mode.mDVI)
  214016. + hdmi_enable_overflow_interrupts();
  214017. +}
  214018. +
  214019. +static void hdmi_config_AVI(struct mxc_hdmi *hdmi)
  214020. +{
  214021. + u8 val;
  214022. + u8 pix_fmt;
  214023. + u8 under_scan;
  214024. + u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
  214025. + struct fb_videomode mode;
  214026. + const struct fb_videomode *edid_mode;
  214027. + bool aspect_16_9;
  214028. +
  214029. + dev_dbg(&hdmi->pdev->dev, "set up AVI frame\n");
  214030. +
  214031. + fb_var_to_videomode(&mode, &hdmi->fbi->var);
  214032. + /* Use mode from list extracted from EDID to get aspect ratio */
  214033. + if (!list_empty(&hdmi->fbi->modelist)) {
  214034. + edid_mode = fb_find_nearest_mode(&mode, &hdmi->fbi->modelist);
  214035. + if (edid_mode->vmode & FB_VMODE_ASPECT_16_9)
  214036. + aspect_16_9 = true;
  214037. + else
  214038. + aspect_16_9 = false;
  214039. + } else
  214040. + aspect_16_9 = false;
  214041. +
  214042. + /********************************************
  214043. + * AVI Data Byte 1
  214044. + ********************************************/
  214045. + if (hdmi->hdmi_data.enc_out_format == YCBCR444)
  214046. + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444;
  214047. + else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS)
  214048. + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422;
  214049. + else
  214050. + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
  214051. +
  214052. + if (hdmi->edid_cfg.cea_underscan)
  214053. + under_scan = HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN;
  214054. + else
  214055. + under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
  214056. +
  214057. + /*
  214058. + * Active format identification data is present in the AVI InfoFrame.
  214059. + * Under scan info, no bar data
  214060. + */
  214061. + val = pix_fmt | under_scan |
  214062. + HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
  214063. + HDMI_FC_AVICONF0_BAR_DATA_NO_DATA;
  214064. +
  214065. + hdmi_writeb(val, HDMI_FC_AVICONF0);
  214066. +
  214067. + /********************************************
  214068. + * AVI Data Byte 2
  214069. + ********************************************/
  214070. +
  214071. + /* Set the Aspect Ratio */
  214072. + if (aspect_16_9) {
  214073. + act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
  214074. + coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
  214075. + } else {
  214076. + act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
  214077. + coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
  214078. + }
  214079. +
  214080. + /* Set up colorimetry */
  214081. + if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
  214082. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
  214083. + if (hdmi->hdmi_data.colorimetry == eITU601)
  214084. + ext_colorimetry =
  214085. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  214086. + else /* hdmi->hdmi_data.colorimetry == eITU709 */
  214087. + ext_colorimetry =
  214088. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
  214089. + } else if (hdmi->hdmi_data.enc_out_format != RGB) {
  214090. + if (hdmi->hdmi_data.colorimetry == eITU601)
  214091. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
  214092. + else /* hdmi->hdmi_data.colorimetry == eITU709 */
  214093. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
  214094. + ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  214095. + } else { /* Carries no data */
  214096. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA;
  214097. + ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  214098. + }
  214099. +
  214100. + val = colorimetry | coded_ratio | act_ratio;
  214101. + hdmi_writeb(val, HDMI_FC_AVICONF1);
  214102. +
  214103. + /********************************************
  214104. + * AVI Data Byte 3
  214105. + ********************************************/
  214106. +
  214107. + val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry |
  214108. + HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT |
  214109. + HDMI_FC_AVICONF2_SCALING_NONE;
  214110. + hdmi_writeb(val, HDMI_FC_AVICONF2);
  214111. +
  214112. + /********************************************
  214113. + * AVI Data Byte 4
  214114. + ********************************************/
  214115. + hdmi_writeb(hdmi->vic, HDMI_FC_AVIVID);
  214116. +
  214117. + /********************************************
  214118. + * AVI Data Byte 5
  214119. + ********************************************/
  214120. +
  214121. + /* Set up input and output pixel repetition */
  214122. + val = (((hdmi->hdmi_data.video_mode.mPixelRepetitionInput + 1) <<
  214123. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
  214124. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
  214125. + ((hdmi->hdmi_data.video_mode.mPixelRepetitionOutput <<
  214126. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
  214127. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
  214128. + hdmi_writeb(val, HDMI_FC_PRCONF);
  214129. +
  214130. + /* IT Content and quantization range = don't care */
  214131. + val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS |
  214132. + HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED;
  214133. + hdmi_writeb(val, HDMI_FC_AVICONF3);
  214134. +
  214135. + /********************************************
  214136. + * AVI Data Bytes 6-13
  214137. + ********************************************/
  214138. + hdmi_writeb(0, HDMI_FC_AVIETB0);
  214139. + hdmi_writeb(0, HDMI_FC_AVIETB1);
  214140. + hdmi_writeb(0, HDMI_FC_AVISBB0);
  214141. + hdmi_writeb(0, HDMI_FC_AVISBB1);
  214142. + hdmi_writeb(0, HDMI_FC_AVIELB0);
  214143. + hdmi_writeb(0, HDMI_FC_AVIELB1);
  214144. + hdmi_writeb(0, HDMI_FC_AVISRB0);
  214145. + hdmi_writeb(0, HDMI_FC_AVISRB1);
  214146. +}
  214147. +
  214148. +/*!
  214149. + * this submodule is responsible for the video/audio data composition.
  214150. + */
  214151. +static void hdmi_av_composer(struct mxc_hdmi *hdmi)
  214152. +{
  214153. + u8 inv_val;
  214154. + struct fb_info *fbi = hdmi->fbi;
  214155. + struct fb_videomode fb_mode;
  214156. + struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
  214157. + int hblank, vblank;
  214158. +
  214159. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214160. +
  214161. + fb_var_to_videomode(&fb_mode, &fbi->var);
  214162. +
  214163. + vmode->mHSyncPolarity = ((fb_mode.sync & FB_SYNC_HOR_HIGH_ACT) != 0);
  214164. + vmode->mVSyncPolarity = ((fb_mode.sync & FB_SYNC_VERT_HIGH_ACT) != 0);
  214165. + vmode->mInterlaced = ((fb_mode.vmode & FB_VMODE_INTERLACED) != 0);
  214166. + vmode->mPixelClock = (fb_mode.xres + fb_mode.left_margin +
  214167. + fb_mode.right_margin + fb_mode.hsync_len) * (fb_mode.yres +
  214168. + fb_mode.upper_margin + fb_mode.lower_margin +
  214169. + fb_mode.vsync_len) * fb_mode.refresh;
  214170. +
  214171. + dev_dbg(&hdmi->pdev->dev, "final pixclk = %d\n", vmode->mPixelClock);
  214172. +
  214173. + /* Set up HDMI_FC_INVIDCONF */
  214174. + inv_val = (vmode->mVSyncPolarity ?
  214175. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
  214176. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
  214177. +
  214178. + inv_val |= (vmode->mHSyncPolarity ?
  214179. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
  214180. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
  214181. +
  214182. + inv_val |= (vmode->mDataEnablePolarity ?
  214183. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
  214184. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
  214185. +
  214186. + if (hdmi->vic == 39)
  214187. + inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
  214188. + else
  214189. + inv_val |= (vmode->mInterlaced ?
  214190. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
  214191. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW);
  214192. +
  214193. + inv_val |= (vmode->mInterlaced ?
  214194. + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
  214195. + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE);
  214196. +
  214197. + inv_val |= (vmode->mDVI ?
  214198. + HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE :
  214199. + HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE);
  214200. +
  214201. + hdmi_writeb(inv_val, HDMI_FC_INVIDCONF);
  214202. +
  214203. + /* Set up horizontal active pixel region width */
  214204. + hdmi_writeb(fb_mode.xres >> 8, HDMI_FC_INHACTV1);
  214205. + hdmi_writeb(fb_mode.xres, HDMI_FC_INHACTV0);
  214206. +
  214207. + /* Set up vertical blanking pixel region width */
  214208. + hdmi_writeb(fb_mode.yres >> 8, HDMI_FC_INVACTV1);
  214209. + hdmi_writeb(fb_mode.yres, HDMI_FC_INVACTV0);
  214210. +
  214211. + /* Set up horizontal blanking pixel region width */
  214212. + hblank = fb_mode.left_margin + fb_mode.right_margin +
  214213. + fb_mode.hsync_len;
  214214. + hdmi_writeb(hblank >> 8, HDMI_FC_INHBLANK1);
  214215. + hdmi_writeb(hblank, HDMI_FC_INHBLANK0);
  214216. +
  214217. + /* Set up vertical blanking pixel region width */
  214218. + vblank = fb_mode.upper_margin + fb_mode.lower_margin +
  214219. + fb_mode.vsync_len;
  214220. + hdmi_writeb(vblank, HDMI_FC_INVBLANK);
  214221. +
  214222. + /* Set up HSYNC active edge delay width (in pixel clks) */
  214223. + hdmi_writeb(fb_mode.right_margin >> 8, HDMI_FC_HSYNCINDELAY1);
  214224. + hdmi_writeb(fb_mode.right_margin, HDMI_FC_HSYNCINDELAY0);
  214225. +
  214226. + /* Set up VSYNC active edge delay (in pixel clks) */
  214227. + hdmi_writeb(fb_mode.lower_margin, HDMI_FC_VSYNCINDELAY);
  214228. +
  214229. + /* Set up HSYNC active pulse width (in pixel clks) */
  214230. + hdmi_writeb(fb_mode.hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
  214231. + hdmi_writeb(fb_mode.hsync_len, HDMI_FC_HSYNCINWIDTH0);
  214232. +
  214233. + /* Set up VSYNC active edge delay (in pixel clks) */
  214234. + hdmi_writeb(fb_mode.vsync_len, HDMI_FC_VSYNCINWIDTH);
  214235. +
  214236. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  214237. +}
  214238. +
  214239. +static int mxc_edid_read_internal(struct mxc_hdmi *hdmi, unsigned char *edid,
  214240. + struct mxc_edid_cfg *cfg, struct fb_info *fbi)
  214241. +{
  214242. + int extblknum;
  214243. + int i, j, ret;
  214244. + unsigned char *ediddata = edid;
  214245. + unsigned char tmpedid[EDID_LENGTH];
  214246. +
  214247. + dev_info(&hdmi->pdev->dev, "%s\n", __func__);
  214248. +
  214249. + if (!edid || !cfg || !fbi)
  214250. + return -EINVAL;
  214251. +
  214252. + /* init HDMI I2CM for read edid*/
  214253. + hdmi_writeb(0x0, HDMI_I2CM_DIV);
  214254. + hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_HCNT_1_ADDR);
  214255. + hdmi_writeb(0x79, HDMI_I2CM_SS_SCL_HCNT_0_ADDR);
  214256. + hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_LCNT_1_ADDR);
  214257. + hdmi_writeb(0x91, HDMI_I2CM_SS_SCL_LCNT_0_ADDR);
  214258. +
  214259. + hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_HCNT_1_ADDR);
  214260. + hdmi_writeb(0x0F, HDMI_I2CM_FS_SCL_HCNT_0_ADDR);
  214261. + hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_LCNT_1_ADDR);
  214262. + hdmi_writeb(0x21, HDMI_I2CM_FS_SCL_LCNT_0_ADDR);
  214263. +
  214264. + hdmi_writeb(0x50, HDMI_I2CM_SLAVE);
  214265. + hdmi_writeb(0x30, HDMI_I2CM_SEGADDR);
  214266. +
  214267. + /* Umask edid interrupt */
  214268. + hdmi_writeb(HDMI_I2CM_INT_DONE_POL,
  214269. + HDMI_I2CM_INT);
  214270. +
  214271. + hdmi_writeb(HDMI_I2CM_CTLINT_NAC_POL |
  214272. + HDMI_I2CM_CTLINT_ARBITRATION_POL,
  214273. + HDMI_I2CM_CTLINT);
  214274. +
  214275. + /* reset edid data zero */
  214276. + memset(edid, 0, EDID_LENGTH*4);
  214277. + memset(cfg, 0, sizeof(struct mxc_edid_cfg));
  214278. +
  214279. + /* Check first three byte of EDID head */
  214280. + if (!(hdmi_edid_i2c_read(hdmi, 0, 0) == 0x00) ||
  214281. + !(hdmi_edid_i2c_read(hdmi, 1, 0) == 0xFF) ||
  214282. + !(hdmi_edid_i2c_read(hdmi, 2, 0) == 0xFF)) {
  214283. + dev_info(&hdmi->pdev->dev, "EDID head check failed!");
  214284. + return -ENOENT;
  214285. + }
  214286. +
  214287. + for (i = 0; i < 128; i++) {
  214288. + *ediddata = hdmi_edid_i2c_read(hdmi, i, 0);
  214289. + ediddata++;
  214290. + }
  214291. +
  214292. + extblknum = edid[0x7E];
  214293. + if (extblknum < 0)
  214294. + return extblknum;
  214295. +
  214296. + if (extblknum) {
  214297. + ediddata = edid + EDID_LENGTH;
  214298. + for (i = 0; i < 128; i++) {
  214299. + *ediddata = hdmi_edid_i2c_read(hdmi, i, 1);
  214300. + ediddata++;
  214301. + }
  214302. + }
  214303. +
  214304. + /* edid first block parsing */
  214305. + memset(&fbi->monspecs, 0, sizeof(fbi->monspecs));
  214306. + fb_edid_to_monspecs(edid, &fbi->monspecs);
  214307. +
  214308. + ret = mxc_edid_parse_ext_blk(edid + EDID_LENGTH,
  214309. + cfg, &fbi->monspecs);
  214310. + if (ret < 0)
  214311. + return -ENOENT;
  214312. +
  214313. + /* need read segment block? */
  214314. + if (extblknum > 1) {
  214315. + for (j = 1; j <= extblknum; j++) {
  214316. + for (i = 0; i < 128; i++)
  214317. + *(tmpedid + 1) = hdmi_edid_i2c_read(hdmi, i, j);
  214318. +
  214319. + /* edid ext block parsing */
  214320. + ret = mxc_edid_parse_ext_blk(tmpedid + EDID_LENGTH,
  214321. + cfg, &fbi->monspecs);
  214322. + if (ret < 0)
  214323. + return -ENOENT;
  214324. + }
  214325. + }
  214326. +
  214327. + return 0;
  214328. +}
  214329. +
  214330. +static int mxc_hdmi_read_edid(struct mxc_hdmi *hdmi)
  214331. +{
  214332. + int ret;
  214333. + u8 edid_old[HDMI_EDID_LEN];
  214334. + u8 clkdis;
  214335. +
  214336. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214337. +
  214338. + /* save old edid */
  214339. + memcpy(edid_old, hdmi->edid, HDMI_EDID_LEN);
  214340. +
  214341. + /* Read EDID via HDMI DDC when HDCP Enable */
  214342. + if (!hdcp_init)
  214343. + ret = mxc_edid_read(hdmi_i2c->adapter, hdmi_i2c->addr,
  214344. + hdmi->edid, &hdmi->edid_cfg, hdmi->fbi);
  214345. + else {
  214346. +
  214347. + /* Disable HDCP clk */
  214348. + if (hdmi->hdmi_data.hdcp_enable) {
  214349. + clkdis = hdmi_readb(HDMI_MC_CLKDIS);
  214350. + clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE;
  214351. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  214352. + }
  214353. +
  214354. + ret = mxc_edid_read_internal(hdmi, hdmi->edid,
  214355. + &hdmi->edid_cfg, hdmi->fbi);
  214356. +
  214357. + /* Enable HDCP clk */
  214358. + if (hdmi->hdmi_data.hdcp_enable) {
  214359. + clkdis = hdmi_readb(HDMI_MC_CLKDIS);
  214360. + clkdis &= ~HDMI_MC_CLKDIS_HDCPCLK_DISABLE;
  214361. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  214362. + }
  214363. +
  214364. + }
  214365. + if (ret < 0)
  214366. + return HDMI_EDID_FAIL;
  214367. +
  214368. + /* Save edid cfg for audio driver */
  214369. + hdmi_set_edid_cfg(&hdmi->edid_cfg);
  214370. +
  214371. + if (!memcmp(edid_old, hdmi->edid, HDMI_EDID_LEN)) {
  214372. + dev_info(&hdmi->pdev->dev, "same edid\n");
  214373. + return HDMI_EDID_SAME;
  214374. + }
  214375. +
  214376. + if (hdmi->fbi->monspecs.modedb_len == 0) {
  214377. + dev_info(&hdmi->pdev->dev, "No modes read from edid\n");
  214378. + return HDMI_EDID_NO_MODES;
  214379. + }
  214380. +
  214381. + return HDMI_EDID_SUCCESS;
  214382. +}
  214383. +
  214384. +static void mxc_hdmi_phy_disable(struct mxc_hdmi *hdmi)
  214385. +{
  214386. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214387. +
  214388. + if (!hdmi->phy_enabled)
  214389. + return;
  214390. +
  214391. + hdmi_disable_overflow_interrupts();
  214392. +
  214393. + /* Setting PHY to reset status */
  214394. + hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
  214395. +
  214396. + /* Power down PHY */
  214397. + mxc_hdmi_phy_enable_tmds(0);
  214398. + mxc_hdmi_phy_enable_power(0);
  214399. + mxc_hdmi_phy_gen2_txpwron(0);
  214400. + mxc_hdmi_phy_gen2_pddq(1);
  214401. +
  214402. + hdmi->phy_enabled = false;
  214403. + dev_dbg(&hdmi->pdev->dev, "%s - exit\n", __func__);
  214404. +}
  214405. +
  214406. +/* HDMI Initialization Step B.4 */
  214407. +static void mxc_hdmi_enable_video_path(struct mxc_hdmi *hdmi)
  214408. +{
  214409. + u8 clkdis;
  214410. +
  214411. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214412. +
  214413. + /* control period minimum duration */
  214414. + hdmi_writeb(12, HDMI_FC_CTRLDUR);
  214415. + hdmi_writeb(32, HDMI_FC_EXCTRLDUR);
  214416. + hdmi_writeb(1, HDMI_FC_EXCTRLSPAC);
  214417. +
  214418. + /* Set to fill TMDS data channels */
  214419. + hdmi_writeb(0x0B, HDMI_FC_CH0PREAM);
  214420. + hdmi_writeb(0x16, HDMI_FC_CH1PREAM);
  214421. + hdmi_writeb(0x21, HDMI_FC_CH2PREAM);
  214422. +
  214423. + /* Save CEC clock */
  214424. + clkdis = hdmi_readb(HDMI_MC_CLKDIS) & HDMI_MC_CLKDIS_CECCLK_DISABLE;
  214425. + clkdis |= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
  214426. +
  214427. + /* Enable pixel clock and tmds data path */
  214428. + clkdis = 0x7F & clkdis;
  214429. + clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
  214430. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  214431. +
  214432. + clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
  214433. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  214434. +
  214435. + /* Enable csc path */
  214436. + if (isColorSpaceConversion(hdmi)) {
  214437. + clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
  214438. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  214439. + }
  214440. +}
  214441. +
  214442. +static void hdmi_enable_audio_clk(struct mxc_hdmi *hdmi)
  214443. +{
  214444. + u8 clkdis;
  214445. +
  214446. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214447. +
  214448. + clkdis = hdmi_readb(HDMI_MC_CLKDIS);
  214449. + clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
  214450. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  214451. +}
  214452. +
  214453. +/* Workaround to clear the overflow condition */
  214454. +static void mxc_hdmi_clear_overflow(struct mxc_hdmi *hdmi)
  214455. +{
  214456. + int count;
  214457. + u8 val;
  214458. +
  214459. + /* TMDS software reset */
  214460. + hdmi_writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
  214461. +
  214462. + val = hdmi_readb(HDMI_FC_INVIDCONF);
  214463. +
  214464. + if (cpu_is_imx6dl(hdmi)) {
  214465. + hdmi_writeb(val, HDMI_FC_INVIDCONF);
  214466. + return;
  214467. + }
  214468. +
  214469. + for (count = 0 ; count < 5 ; count++)
  214470. + hdmi_writeb(val, HDMI_FC_INVIDCONF);
  214471. +}
  214472. +
  214473. +static void hdmi_enable_overflow_interrupts(void)
  214474. +{
  214475. + pr_debug("%s\n", __func__);
  214476. + hdmi_writeb(0, HDMI_FC_MASK2);
  214477. + hdmi_writeb(0, HDMI_IH_MUTE_FC_STAT2);
  214478. +}
  214479. +
  214480. +static void hdmi_disable_overflow_interrupts(void)
  214481. +{
  214482. + pr_debug("%s\n", __func__);
  214483. + hdmi_writeb(HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
  214484. + HDMI_IH_MUTE_FC_STAT2);
  214485. + hdmi_writeb(0xff, HDMI_FC_MASK2);
  214486. +}
  214487. +
  214488. +static void mxc_hdmi_notify_fb(struct mxc_hdmi *hdmi)
  214489. +{
  214490. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214491. +
  214492. + /* Don't notify if we aren't registered yet */
  214493. + WARN_ON(!hdmi->fb_reg);
  214494. +
  214495. + /* disable the phy before ipu changes mode */
  214496. + mxc_hdmi_phy_disable(hdmi);
  214497. +
  214498. + /*
  214499. + * Note that fb_set_var will block. During this time,
  214500. + * FB_EVENT_MODE_CHANGE callback will happen.
  214501. + * So by the end of this function, mxc_hdmi_setup()
  214502. + * will be done.
  214503. + */
  214504. + hdmi->fbi->var.activate |= FB_ACTIVATE_FORCE;
  214505. + console_lock();
  214506. + hdmi->fbi->flags |= FBINFO_MISC_USEREVENT;
  214507. + fb_set_var(hdmi->fbi, &hdmi->fbi->var);
  214508. + hdmi->fbi->flags &= ~FBINFO_MISC_USEREVENT;
  214509. + console_unlock();
  214510. +
  214511. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  214512. +}
  214513. +
  214514. +static void mxc_hdmi_edid_rebuild_modelist(struct mxc_hdmi *hdmi)
  214515. +{
  214516. + int i;
  214517. + struct fb_videomode *mode;
  214518. +
  214519. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214520. +
  214521. + console_lock();
  214522. +
  214523. + fb_destroy_modelist(&hdmi->fbi->modelist);
  214524. + fb_add_videomode(&vga_mode, &hdmi->fbi->modelist);
  214525. +
  214526. + for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) {
  214527. + /*
  214528. + * We might check here if mode is supported by HDMI.
  214529. + * We do not currently support interlaced modes.
  214530. + * And add CEA modes in the modelist.
  214531. + */
  214532. + mode = &hdmi->fbi->monspecs.modedb[i];
  214533. +
  214534. + if (!(mode->vmode & FB_VMODE_INTERLACED) &&
  214535. + (mxc_edid_mode_to_vic(mode) != 0)) {
  214536. +
  214537. + dev_dbg(&hdmi->pdev->dev, "Added mode %d:", i);
  214538. + dev_dbg(&hdmi->pdev->dev,
  214539. + "xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n",
  214540. + hdmi->fbi->monspecs.modedb[i].xres,
  214541. + hdmi->fbi->monspecs.modedb[i].yres,
  214542. + hdmi->fbi->monspecs.modedb[i].refresh,
  214543. + hdmi->fbi->monspecs.modedb[i].vmode,
  214544. + hdmi->fbi->monspecs.modedb[i].flag);
  214545. +
  214546. + fb_add_videomode(mode, &hdmi->fbi->modelist);
  214547. + }
  214548. + }
  214549. +
  214550. + console_unlock();
  214551. +}
  214552. +
  214553. +static void mxc_hdmi_default_edid_cfg(struct mxc_hdmi *hdmi)
  214554. +{
  214555. + /* Default setting HDMI working in HDMI mode */
  214556. + hdmi->edid_cfg.hdmi_cap = true;
  214557. +}
  214558. +
  214559. +static void mxc_hdmi_default_modelist(struct mxc_hdmi *hdmi)
  214560. +{
  214561. + u32 i;
  214562. + const struct fb_videomode *mode;
  214563. +
  214564. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214565. +
  214566. + /* If not EDID data read, set up default modelist */
  214567. + dev_info(&hdmi->pdev->dev, "No modes read from edid\n");
  214568. + dev_info(&hdmi->pdev->dev, "create default modelist\n");
  214569. +
  214570. + console_lock();
  214571. +
  214572. + fb_destroy_modelist(&hdmi->fbi->modelist);
  214573. +
  214574. + /*Add all no interlaced CEA mode to default modelist */
  214575. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  214576. + mode = &mxc_cea_mode[i];
  214577. + if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0))
  214578. + fb_add_videomode(mode, &hdmi->fbi->modelist);
  214579. + }
  214580. +
  214581. + console_unlock();
  214582. +}
  214583. +
  214584. +static void mxc_hdmi_set_mode_to_vga_dvi(struct mxc_hdmi *hdmi)
  214585. +{
  214586. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214587. +
  214588. + hdmi_disable_overflow_interrupts();
  214589. +
  214590. + fb_videomode_to_var(&hdmi->fbi->var, &vga_mode);
  214591. +
  214592. + hdmi->requesting_vga_for_initialization = true;
  214593. + mxc_hdmi_notify_fb(hdmi);
  214594. + hdmi->requesting_vga_for_initialization = false;
  214595. +}
  214596. +
  214597. +static void mxc_hdmi_set_mode(struct mxc_hdmi *hdmi)
  214598. +{
  214599. + const struct fb_videomode *mode;
  214600. + struct fb_videomode m;
  214601. + struct fb_var_screeninfo var;
  214602. +
  214603. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214604. +
  214605. + /* Set the default mode only once. */
  214606. + if (!hdmi->dft_mode_set) {
  214607. + fb_videomode_to_var(&var, &hdmi->default_mode);
  214608. + hdmi->dft_mode_set = true;
  214609. + } else
  214610. + fb_videomode_to_var(&var, &hdmi->previous_non_vga_mode);
  214611. +
  214612. + fb_var_to_videomode(&m, &var);
  214613. + dump_fb_videomode(&m);
  214614. +
  214615. + mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
  214616. + if (!mode) {
  214617. + pr_err("%s: could not find mode in modelist\n", __func__);
  214618. + return;
  214619. + }
  214620. +
  214621. + /* If video mode same as previous, init HDMI again */
  214622. + if (fb_mode_is_equal(&hdmi->previous_non_vga_mode, mode)) {
  214623. + dev_dbg(&hdmi->pdev->dev,
  214624. + "%s: Video mode same as previous\n", __func__);
  214625. + /* update fbi mode in case modelist is updated */
  214626. + hdmi->fbi->mode = (struct fb_videomode *)mode;
  214627. + /* update hdmi setting in case EDID data updated */
  214628. + mxc_hdmi_setup(hdmi, 0);
  214629. + } else {
  214630. + dev_dbg(&hdmi->pdev->dev, "%s: New video mode\n", __func__);
  214631. + mxc_hdmi_set_mode_to_vga_dvi(hdmi);
  214632. + fb_videomode_to_var(&hdmi->fbi->var, mode);
  214633. + dump_fb_videomode((struct fb_videomode *)mode);
  214634. + mxc_hdmi_notify_fb(hdmi);
  214635. + }
  214636. +
  214637. +}
  214638. +
  214639. +static void mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
  214640. +{
  214641. + int edid_status;
  214642. +
  214643. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214644. +
  214645. + hdmi->cable_plugin = true;
  214646. +
  214647. + /* HDMI Initialization Step C */
  214648. + edid_status = mxc_hdmi_read_edid(hdmi);
  214649. +
  214650. + /* Read EDID again if first EDID read failed */
  214651. + if (edid_status == HDMI_EDID_NO_MODES ||
  214652. + edid_status == HDMI_EDID_FAIL) {
  214653. + dev_info(&hdmi->pdev->dev, "Read EDID again\n");
  214654. + edid_status = mxc_hdmi_read_edid(hdmi);
  214655. + }
  214656. +
  214657. + /* HDMI Initialization Steps D, E, F */
  214658. + switch (edid_status) {
  214659. + case HDMI_EDID_SUCCESS:
  214660. + mxc_hdmi_edid_rebuild_modelist(hdmi);
  214661. + break;
  214662. +
  214663. + /* Nothing to do if EDID same */
  214664. + case HDMI_EDID_SAME:
  214665. + break;
  214666. +
  214667. + case HDMI_EDID_FAIL:
  214668. + mxc_hdmi_default_edid_cfg(hdmi);
  214669. + /* No break here */
  214670. + case HDMI_EDID_NO_MODES:
  214671. + default:
  214672. + mxc_hdmi_default_modelist(hdmi);
  214673. + break;
  214674. + }
  214675. +
  214676. + /* Setting video mode */
  214677. + mxc_hdmi_set_mode(hdmi);
  214678. +
  214679. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  214680. +}
  214681. +
  214682. +static int mxc_hdmi_power_on(struct mxc_dispdrv_handle *disp)
  214683. +{
  214684. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  214685. + mxc_hdmi_phy_init(hdmi);
  214686. + return 0;
  214687. +}
  214688. +
  214689. +static void mxc_hdmi_power_off(struct mxc_dispdrv_handle *disp)
  214690. +{
  214691. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  214692. + mxc_hdmi_phy_disable(hdmi);
  214693. +}
  214694. +
  214695. +static void mxc_hdmi_cable_disconnected(struct mxc_hdmi *hdmi)
  214696. +{
  214697. + u8 clkdis;
  214698. +
  214699. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214700. +
  214701. + /* Save CEC clock */
  214702. + clkdis = hdmi_readb(HDMI_MC_CLKDIS) & HDMI_MC_CLKDIS_CECCLK_DISABLE;
  214703. + clkdis |= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
  214704. +
  214705. + /* Disable All HDMI clock */
  214706. + hdmi_writeb(0xff & clkdis, HDMI_MC_CLKDIS);
  214707. +
  214708. + mxc_hdmi_phy_disable(hdmi);
  214709. +
  214710. + hdmi_disable_overflow_interrupts();
  214711. +
  214712. + hdmi->cable_plugin = false;
  214713. +}
  214714. +
  214715. +static void hotplug_worker(struct work_struct *work)
  214716. +{
  214717. + struct delayed_work *delay_work = to_delayed_work(work);
  214718. + struct mxc_hdmi *hdmi =
  214719. + container_of(delay_work, struct mxc_hdmi, hotplug_work);
  214720. + u32 phy_int_stat, phy_int_pol, phy_int_mask;
  214721. + u8 val;
  214722. + unsigned long flags;
  214723. + char event_string[32];
  214724. + char *envp[] = { event_string, NULL };
  214725. +
  214726. + phy_int_stat = hdmi->latest_intr_stat;
  214727. + phy_int_pol = hdmi_readb(HDMI_PHY_POL0);
  214728. +
  214729. + dev_dbg(&hdmi->pdev->dev, "phy_int_stat=0x%x, phy_int_pol=0x%x\n",
  214730. + phy_int_stat, phy_int_pol);
  214731. +
  214732. + /* check cable status */
  214733. + if (phy_int_stat & HDMI_IH_PHY_STAT0_HPD) {
  214734. + /* cable connection changes */
  214735. + if (phy_int_pol & HDMI_PHY_HPD) {
  214736. + /* Plugin event */
  214737. + dev_dbg(&hdmi->pdev->dev, "EVENT=plugin\n");
  214738. + mxc_hdmi_cable_connected(hdmi);
  214739. +
  214740. + /* Make HPD intr active low to capture unplug event */
  214741. + val = hdmi_readb(HDMI_PHY_POL0);
  214742. + val &= ~HDMI_PHY_HPD;
  214743. + hdmi_writeb(val, HDMI_PHY_POL0);
  214744. +
  214745. + hdmi_set_cable_state(1);
  214746. +
  214747. + sprintf(event_string, "EVENT=plugin");
  214748. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  214749. +#ifdef CONFIG_MXC_HDMI_CEC
  214750. + mxc_hdmi_cec_handle(0x80);
  214751. +#endif
  214752. + } else if (!(phy_int_pol & HDMI_PHY_HPD)) {
  214753. + /* Plugout event */
  214754. + dev_dbg(&hdmi->pdev->dev, "EVENT=plugout\n");
  214755. + hdmi_set_cable_state(0);
  214756. + mxc_hdmi_abort_stream();
  214757. + mxc_hdmi_cable_disconnected(hdmi);
  214758. +
  214759. + /* Make HPD intr active high to capture plugin event */
  214760. + val = hdmi_readb(HDMI_PHY_POL0);
  214761. + val |= HDMI_PHY_HPD;
  214762. + hdmi_writeb(val, HDMI_PHY_POL0);
  214763. +
  214764. + sprintf(event_string, "EVENT=plugout");
  214765. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  214766. +#ifdef CONFIG_MXC_HDMI_CEC
  214767. + mxc_hdmi_cec_handle(0x100);
  214768. +#endif
  214769. +
  214770. + } else
  214771. + dev_dbg(&hdmi->pdev->dev, "EVENT=none?\n");
  214772. + }
  214773. +
  214774. + /* Lock here to ensure full powerdown sequence
  214775. + * completed before next interrupt processed */
  214776. + spin_lock_irqsave(&hdmi->irq_lock, flags);
  214777. +
  214778. + /* Re-enable HPD interrupts */
  214779. + phy_int_mask = hdmi_readb(HDMI_PHY_MASK0);
  214780. + phy_int_mask &= ~HDMI_PHY_HPD;
  214781. + hdmi_writeb(phy_int_mask, HDMI_PHY_MASK0);
  214782. +
  214783. + /* Unmute interrupts */
  214784. + hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
  214785. +
  214786. + if (hdmi_readb(HDMI_IH_FC_STAT2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK)
  214787. + mxc_hdmi_clear_overflow(hdmi);
  214788. +
  214789. + spin_unlock_irqrestore(&hdmi->irq_lock, flags);
  214790. +}
  214791. +
  214792. +static void hdcp_hdp_worker(struct work_struct *work)
  214793. +{
  214794. + struct delayed_work *delay_work = to_delayed_work(work);
  214795. + struct mxc_hdmi *hdmi =
  214796. + container_of(delay_work, struct mxc_hdmi, hdcp_hdp_work);
  214797. + char event_string[32];
  214798. + char *envp[] = { event_string, NULL };
  214799. +
  214800. + /* HDCP interrupt */
  214801. + sprintf(event_string, "EVENT=hdcpint");
  214802. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  214803. +
  214804. + /* Unmute interrupts in HDCP application*/
  214805. +}
  214806. +
  214807. +static irqreturn_t mxc_hdmi_hotplug(int irq, void *data)
  214808. +{
  214809. + struct mxc_hdmi *hdmi = data;
  214810. + u8 val, intr_stat;
  214811. + unsigned long flags;
  214812. +
  214813. + spin_lock_irqsave(&hdmi->irq_lock, flags);
  214814. +
  214815. + /* Check and clean packet overflow interrupt.*/
  214816. + if (hdmi_readb(HDMI_IH_FC_STAT2) &
  214817. + HDMI_IH_FC_STAT2_OVERFLOW_MASK) {
  214818. + mxc_hdmi_clear_overflow(hdmi);
  214819. +
  214820. + dev_dbg(&hdmi->pdev->dev, "Overflow interrupt received\n");
  214821. + /* clear irq status */
  214822. + hdmi_writeb(HDMI_IH_FC_STAT2_OVERFLOW_MASK,
  214823. + HDMI_IH_FC_STAT2);
  214824. + }
  214825. +
  214826. + /*
  214827. + * We could not disable the irq. Probably the audio driver
  214828. + * has enabled it. Masking off the HDMI interrupts using
  214829. + * HDMI registers.
  214830. + */
  214831. + /* Capture status - used in hotplug_worker ISR */
  214832. + intr_stat = hdmi_readb(HDMI_IH_PHY_STAT0);
  214833. +
  214834. + if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
  214835. +
  214836. + dev_dbg(&hdmi->pdev->dev, "Hotplug interrupt received\n");
  214837. + hdmi->latest_intr_stat = intr_stat;
  214838. +
  214839. + /* Mute interrupts until handled */
  214840. +
  214841. + val = hdmi_readb(HDMI_IH_MUTE_PHY_STAT0);
  214842. + val |= HDMI_IH_MUTE_PHY_STAT0_HPD;
  214843. + hdmi_writeb(val, HDMI_IH_MUTE_PHY_STAT0);
  214844. +
  214845. + val = hdmi_readb(HDMI_PHY_MASK0);
  214846. + val |= HDMI_PHY_HPD;
  214847. + hdmi_writeb(val, HDMI_PHY_MASK0);
  214848. +
  214849. + /* Clear Hotplug interrupts */
  214850. + hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
  214851. +
  214852. + schedule_delayed_work(&(hdmi->hotplug_work), msecs_to_jiffies(20));
  214853. + }
  214854. +
  214855. + /* Check HDCP interrupt state */
  214856. + if (hdmi->hdmi_data.hdcp_enable) {
  214857. + val = hdmi_readb(HDMI_A_APIINTSTAT);
  214858. + if (val != 0) {
  214859. + /* Mute interrupts until interrupt handled */
  214860. + val = 0xFF;
  214861. + hdmi_writeb(val, HDMI_A_APIINTMSK);
  214862. + schedule_delayed_work(&(hdmi->hdcp_hdp_work), msecs_to_jiffies(50));
  214863. + }
  214864. + }
  214865. +
  214866. + spin_unlock_irqrestore(&hdmi->irq_lock, flags);
  214867. + return IRQ_HANDLED;
  214868. +}
  214869. +
  214870. +static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event)
  214871. +{
  214872. + struct fb_videomode m;
  214873. + const struct fb_videomode *edid_mode;
  214874. +
  214875. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214876. +
  214877. + fb_var_to_videomode(&m, &hdmi->fbi->var);
  214878. + dump_fb_videomode(&m);
  214879. +
  214880. + dev_dbg(&hdmi->pdev->dev, "%s - video mode changed\n", __func__);
  214881. +
  214882. + hdmi->vic = 0;
  214883. + if (!hdmi->requesting_vga_for_initialization) {
  214884. + /* Save mode if this isn't the result of requesting
  214885. + * vga default. */
  214886. + memcpy(&hdmi->previous_non_vga_mode, &m,
  214887. + sizeof(struct fb_videomode));
  214888. + if (!list_empty(&hdmi->fbi->modelist)) {
  214889. + edid_mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
  214890. + pr_debug("edid mode ");
  214891. + dump_fb_videomode((struct fb_videomode *)edid_mode);
  214892. + /* update fbi mode */
  214893. + hdmi->fbi->mode = (struct fb_videomode *)edid_mode;
  214894. + hdmi->vic = mxc_edid_mode_to_vic(edid_mode);
  214895. + }
  214896. + }
  214897. +
  214898. + hdmi_disable_overflow_interrupts();
  214899. +
  214900. + dev_dbg(&hdmi->pdev->dev, "CEA mode used vic=%d\n", hdmi->vic);
  214901. + if (hdmi->edid_cfg.hdmi_cap)
  214902. + hdmi->hdmi_data.video_mode.mDVI = false;
  214903. + else {
  214904. + dev_dbg(&hdmi->pdev->dev, "CEA mode vic=%d work in DVI\n", hdmi->vic);
  214905. + hdmi->hdmi_data.video_mode.mDVI = true;
  214906. + }
  214907. +
  214908. + if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
  214909. + (hdmi->vic == 21) || (hdmi->vic == 22) ||
  214910. + (hdmi->vic == 2) || (hdmi->vic == 3) ||
  214911. + (hdmi->vic == 17) || (hdmi->vic == 18))
  214912. + hdmi->hdmi_data.colorimetry = eITU601;
  214913. + else
  214914. + hdmi->hdmi_data.colorimetry = eITU709;
  214915. +
  214916. + if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
  214917. + (hdmi->vic == 12) || (hdmi->vic == 13) ||
  214918. + (hdmi->vic == 14) || (hdmi->vic == 15) ||
  214919. + (hdmi->vic == 25) || (hdmi->vic == 26) ||
  214920. + (hdmi->vic == 27) || (hdmi->vic == 28) ||
  214921. + (hdmi->vic == 29) || (hdmi->vic == 30) ||
  214922. + (hdmi->vic == 35) || (hdmi->vic == 36) ||
  214923. + (hdmi->vic == 37) || (hdmi->vic == 38))
  214924. + hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 1;
  214925. + else
  214926. + hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 0;
  214927. +
  214928. + hdmi->hdmi_data.video_mode.mPixelRepetitionInput = 0;
  214929. +
  214930. + /* TODO: Get input format from IPU (via FB driver iface) */
  214931. + hdmi->hdmi_data.enc_in_format = RGB;
  214932. +
  214933. + hdmi->hdmi_data.enc_out_format = RGB;
  214934. +
  214935. + /* YCbCr only enabled in HDMI mode */
  214936. + if (!hdmi->hdmi_data.video_mode.mDVI &&
  214937. + !hdmi->hdmi_data.rgb_out_enable) {
  214938. + if (hdmi->edid_cfg.cea_ycbcr444)
  214939. + hdmi->hdmi_data.enc_out_format = YCBCR444;
  214940. + else if (hdmi->edid_cfg.cea_ycbcr422)
  214941. + hdmi->hdmi_data.enc_out_format = YCBCR422_8BITS;
  214942. + }
  214943. +
  214944. + /* IPU not support depth color output */
  214945. + hdmi->hdmi_data.enc_color_depth = 8;
  214946. + hdmi->hdmi_data.pix_repet_factor = 0;
  214947. + hdmi->hdmi_data.video_mode.mDataEnablePolarity = true;
  214948. +
  214949. + /* HDMI Initialization Step B.1 */
  214950. + hdmi_av_composer(hdmi);
  214951. +
  214952. + /* HDMI Initializateion Step B.2 */
  214953. + mxc_hdmi_phy_init(hdmi);
  214954. +
  214955. + /* HDMI Initialization Step B.3 */
  214956. + mxc_hdmi_enable_video_path(hdmi);
  214957. +
  214958. + /* not for DVI mode */
  214959. + if (hdmi->hdmi_data.video_mode.mDVI)
  214960. + dev_dbg(&hdmi->pdev->dev, "%s DVI mode\n", __func__);
  214961. + else {
  214962. + dev_dbg(&hdmi->pdev->dev, "%s CEA mode\n", __func__);
  214963. +
  214964. + /* HDMI Initialization Step E - Configure audio */
  214965. + hdmi_clk_regenerator_update_pixel_clock(hdmi->fbi->var.pixclock);
  214966. + hdmi_enable_audio_clk(hdmi);
  214967. +
  214968. + /* HDMI Initialization Step F - Configure AVI InfoFrame */
  214969. + hdmi_config_AVI(hdmi);
  214970. + }
  214971. +
  214972. + hdmi_video_packetize(hdmi);
  214973. + hdmi_video_csc(hdmi);
  214974. + hdmi_video_sample(hdmi);
  214975. +
  214976. + mxc_hdmi_clear_overflow(hdmi);
  214977. +
  214978. + dev_dbg(&hdmi->pdev->dev, "%s exit\n\n", __func__);
  214979. +
  214980. +}
  214981. +
  214982. +/* Wait until we are registered to enable interrupts */
  214983. +static void mxc_hdmi_fb_registered(struct mxc_hdmi *hdmi)
  214984. +{
  214985. + unsigned long flags;
  214986. +
  214987. + if (hdmi->fb_reg)
  214988. + return;
  214989. +
  214990. + spin_lock_irqsave(&hdmi->irq_lock, flags);
  214991. +
  214992. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214993. +
  214994. + hdmi_writeb(HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
  214995. + HDMI_PHY_I2CM_INT_ADDR);
  214996. +
  214997. + hdmi_writeb(HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
  214998. + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
  214999. + HDMI_PHY_I2CM_CTLINT_ADDR);
  215000. +
  215001. + /* enable cable hot plug irq */
  215002. + hdmi_writeb((u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
  215003. +
  215004. + /* Clear Hotplug interrupts */
  215005. + hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
  215006. +
  215007. + /* Unmute interrupts */
  215008. + hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
  215009. +
  215010. + hdmi->fb_reg = true;
  215011. +
  215012. + spin_unlock_irqrestore(&hdmi->irq_lock, flags);
  215013. +
  215014. +}
  215015. +
  215016. +static int mxc_hdmi_fb_event(struct notifier_block *nb,
  215017. + unsigned long val, void *v)
  215018. +{
  215019. + struct fb_event *event = v;
  215020. + struct mxc_hdmi *hdmi = container_of(nb, struct mxc_hdmi, nb);
  215021. +
  215022. + if (strcmp(event->info->fix.id, hdmi->fbi->fix.id))
  215023. + return 0;
  215024. +
  215025. + switch (val) {
  215026. + case FB_EVENT_FB_REGISTERED:
  215027. + dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_REGISTERED\n");
  215028. + mxc_hdmi_fb_registered(hdmi);
  215029. + hdmi_set_registered(1);
  215030. + break;
  215031. +
  215032. + case FB_EVENT_FB_UNREGISTERED:
  215033. + dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_UNREGISTERED\n");
  215034. + hdmi->fb_reg = false;
  215035. + hdmi_set_registered(0);
  215036. + break;
  215037. +
  215038. + case FB_EVENT_MODE_CHANGE:
  215039. + dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_MODE_CHANGE\n");
  215040. + if (hdmi->fb_reg)
  215041. + mxc_hdmi_setup(hdmi, val);
  215042. + break;
  215043. +
  215044. + case FB_EVENT_BLANK:
  215045. + if ((*((int *)event->data) == FB_BLANK_UNBLANK) &&
  215046. + (*((int *)event->data) != hdmi->blank)) {
  215047. + dev_dbg(&hdmi->pdev->dev,
  215048. + "event=FB_EVENT_BLANK - UNBLANK\n");
  215049. +
  215050. + hdmi->blank = *((int *)event->data);
  215051. +
  215052. + if (hdmi->fb_reg && hdmi->cable_plugin)
  215053. + mxc_hdmi_setup(hdmi, val);
  215054. + hdmi_set_blank_state(1);
  215055. +
  215056. + } else if (*((int *)event->data) != hdmi->blank) {
  215057. + dev_dbg(&hdmi->pdev->dev,
  215058. + "event=FB_EVENT_BLANK - BLANK\n");
  215059. + hdmi_set_blank_state(0);
  215060. + mxc_hdmi_abort_stream();
  215061. +
  215062. + mxc_hdmi_phy_disable(hdmi);
  215063. +
  215064. + hdmi->blank = *((int *)event->data);
  215065. + } else
  215066. + dev_dbg(&hdmi->pdev->dev,
  215067. + "FB BLANK state no changed!\n");
  215068. +
  215069. + break;
  215070. +
  215071. + case FB_EVENT_SUSPEND:
  215072. + dev_dbg(&hdmi->pdev->dev,
  215073. + "event=FB_EVENT_SUSPEND\n");
  215074. +
  215075. + if (hdmi->blank == FB_BLANK_UNBLANK) {
  215076. + mxc_hdmi_phy_disable(hdmi);
  215077. + clk_disable(hdmi->hdmi_iahb_clk);
  215078. + clk_disable(hdmi->hdmi_isfr_clk);
  215079. + }
  215080. + break;
  215081. +
  215082. + case FB_EVENT_RESUME:
  215083. + dev_dbg(&hdmi->pdev->dev,
  215084. + "event=FB_EVENT_RESUME\n");
  215085. +
  215086. + if (hdmi->blank == FB_BLANK_UNBLANK) {
  215087. + clk_enable(hdmi->hdmi_iahb_clk);
  215088. + clk_enable(hdmi->hdmi_isfr_clk);
  215089. + mxc_hdmi_phy_init(hdmi);
  215090. + }
  215091. + break;
  215092. +
  215093. + }
  215094. + return 0;
  215095. +}
  215096. +
  215097. +static void hdmi_init_route(struct mxc_hdmi *hdmi)
  215098. +{
  215099. + uint32_t hdmi_mux_setting, reg;
  215100. + int ipu_id, disp_id;
  215101. +
  215102. + ipu_id = mxc_hdmi_ipu_id;
  215103. + disp_id = mxc_hdmi_disp_id;
  215104. +
  215105. + if ((ipu_id > 1) || (ipu_id < 0)) {
  215106. + pr_err("Invalid IPU select for HDMI: %d. Set to 0\n", ipu_id);
  215107. + ipu_id = 0;
  215108. + }
  215109. +
  215110. + if ((disp_id > 1) || (disp_id < 0)) {
  215111. + pr_err("Invalid DI select for HDMI: %d. Set to 0\n", disp_id);
  215112. + disp_id = 0;
  215113. + }
  215114. +
  215115. + reg = readl(hdmi->gpr_hdmi_base);
  215116. +
  215117. + /* Configure the connection between IPU1/2 and HDMI */
  215118. + hdmi_mux_setting = 2*ipu_id + disp_id;
  215119. +
  215120. + /* GPR3, bits 2-3 = HDMI_MUX_CTL */
  215121. + reg &= ~0xd;
  215122. + reg |= hdmi_mux_setting << 2;
  215123. +
  215124. + writel(reg, hdmi->gpr_hdmi_base);
  215125. +
  215126. + /* Set HDMI event as SDMA event2 for HDMI audio */
  215127. + reg = readl(hdmi->gpr_sdma_base);
  215128. + reg |= 0x1;
  215129. + writel(reg, hdmi->gpr_sdma_base);
  215130. +}
  215131. +
  215132. +static void hdmi_hdcp_get_property(struct platform_device *pdev)
  215133. +{
  215134. + struct device_node *np = pdev->dev.of_node;
  215135. +
  215136. + /* Check hdcp enable by dts.*/
  215137. + hdcp_init = of_property_read_bool(np, "fsl,hdcp");
  215138. + if (hdcp_init)
  215139. + dev_dbg(&pdev->dev, "hdcp enable\n");
  215140. + else
  215141. + dev_dbg(&pdev->dev, "hdcp disable\n");
  215142. +}
  215143. +
  215144. +static void hdmi_get_of_property(struct mxc_hdmi *hdmi)
  215145. +{
  215146. + struct platform_device *pdev = hdmi->pdev;
  215147. + struct device_node *np = pdev->dev.of_node;
  215148. + const struct of_device_id *of_id =
  215149. + of_match_device(imx_hdmi_dt_ids, &pdev->dev);
  215150. + int ret;
  215151. + u32 phy_reg_vlev = 0, phy_reg_cksymtx = 0;
  215152. +
  215153. + if (of_id) {
  215154. + pdev->id_entry = of_id->data;
  215155. + hdmi->cpu_type = pdev->id_entry->driver_data;
  215156. + }
  215157. +
  215158. + /* HDMI PHY register vlev and cksymtx preperty is optional.
  215159. + * It is for specific board to pass HCT electrical part.
  215160. + * Default value will been setting in HDMI PHY config function
  215161. + * if it is not define in device tree.
  215162. + */
  215163. + ret = of_property_read_u32(np, "fsl,phy_reg_vlev", &phy_reg_vlev);
  215164. + if (ret)
  215165. + dev_dbg(&pdev->dev, "No board specific HDMI PHY vlev\n");
  215166. +
  215167. + ret = of_property_read_u32(np, "fsl,phy_reg_cksymtx", &phy_reg_cksymtx);
  215168. + if (ret)
  215169. + dev_dbg(&pdev->dev, "No board specific HDMI PHY cksymtx\n");
  215170. +
  215171. + /* Specific phy config */
  215172. + hdmi->phy_config.reg_cksymtx = phy_reg_cksymtx;
  215173. + hdmi->phy_config.reg_vlev = phy_reg_vlev;
  215174. +
  215175. +}
  215176. +
  215177. +/* HDMI Initialization Step A */
  215178. +static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp,
  215179. + struct mxc_dispdrv_setting *setting)
  215180. +{
  215181. + int ret = 0;
  215182. + u32 i;
  215183. + const struct fb_videomode *mode;
  215184. + struct fb_videomode m;
  215185. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  215186. + int irq = platform_get_irq(hdmi->pdev, 0);
  215187. +
  215188. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215189. +
  215190. + /* Check hdmi disp init once */
  215191. + if (hdmi_inited) {
  215192. + dev_err(&hdmi->pdev->dev,
  215193. + "Error only one HDMI output support now!\n");
  215194. + return -1;
  215195. + }
  215196. +
  215197. + hdmi_get_of_property(hdmi);
  215198. +
  215199. + if (irq < 0)
  215200. + return -ENODEV;
  215201. +
  215202. + /* Setting HDMI default to blank state */
  215203. + hdmi->blank = FB_BLANK_POWERDOWN;
  215204. +
  215205. + setting->dev_id = mxc_hdmi_ipu_id;
  215206. + setting->disp_id = mxc_hdmi_disp_id;
  215207. + setting->if_fmt = IPU_PIX_FMT_RGB24;
  215208. +
  215209. + hdmi->dft_mode_str = setting->dft_mode_str;
  215210. + hdmi->default_bpp = setting->default_bpp;
  215211. + dev_dbg(&hdmi->pdev->dev, "%s - default mode %s bpp=%d\n",
  215212. + __func__, hdmi->dft_mode_str, hdmi->default_bpp);
  215213. +
  215214. + hdmi->fbi = setting->fbi;
  215215. +
  215216. + hdmi_init_route(hdmi);
  215217. +
  215218. + hdmi->hdmi_isfr_clk = clk_get(&hdmi->pdev->dev, "hdmi_isfr");
  215219. + if (IS_ERR(hdmi->hdmi_isfr_clk)) {
  215220. + ret = PTR_ERR(hdmi->hdmi_isfr_clk);
  215221. + dev_err(&hdmi->pdev->dev,
  215222. + "Unable to get HDMI clk: %d\n", ret);
  215223. + goto egetclk1;
  215224. + }
  215225. +
  215226. + ret = clk_prepare_enable(hdmi->hdmi_isfr_clk);
  215227. + if (ret < 0) {
  215228. + dev_err(&hdmi->pdev->dev,
  215229. + "Cannot enable HDMI isfr clock: %d\n", ret);
  215230. + goto erate1;
  215231. + }
  215232. +
  215233. + hdmi->hdmi_iahb_clk = clk_get(&hdmi->pdev->dev, "hdmi_iahb");
  215234. + if (IS_ERR(hdmi->hdmi_iahb_clk)) {
  215235. + ret = PTR_ERR(hdmi->hdmi_iahb_clk);
  215236. + dev_err(&hdmi->pdev->dev,
  215237. + "Unable to get HDMI clk: %d\n", ret);
  215238. + goto egetclk2;
  215239. + }
  215240. +
  215241. + ret = clk_prepare_enable(hdmi->hdmi_iahb_clk);
  215242. + if (ret < 0) {
  215243. + dev_err(&hdmi->pdev->dev,
  215244. + "Cannot enable HDMI iahb clock: %d\n", ret);
  215245. + goto erate2;
  215246. + }
  215247. +
  215248. + dev_dbg(&hdmi->pdev->dev, "Enabled HDMI clocks\n");
  215249. +
  215250. + /* Init DDC pins for HDCP */
  215251. + if (hdcp_init) {
  215252. + hdmi->pinctrl = devm_pinctrl_get_select_default(&hdmi->pdev->dev);
  215253. + if (IS_ERR(hdmi->pinctrl)) {
  215254. + dev_err(&hdmi->pdev->dev, "can't get/select DDC pinctrl\n");
  215255. + goto erate2;
  215256. + }
  215257. + }
  215258. +
  215259. + /* Product and revision IDs */
  215260. + dev_info(&hdmi->pdev->dev,
  215261. + "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
  215262. + hdmi_readb(HDMI_DESIGN_ID),
  215263. + hdmi_readb(HDMI_REVISION_ID),
  215264. + hdmi_readb(HDMI_PRODUCT_ID0),
  215265. + hdmi_readb(HDMI_PRODUCT_ID1));
  215266. +
  215267. + /* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
  215268. + * N and cts values before enabling phy */
  215269. + hdmi_init_clk_regenerator();
  215270. +
  215271. + INIT_LIST_HEAD(&hdmi->fbi->modelist);
  215272. +
  215273. + spin_lock_init(&hdmi->irq_lock);
  215274. +
  215275. + /* Set the default mode and modelist when disp init. */
  215276. + fb_find_mode(&hdmi->fbi->var, hdmi->fbi,
  215277. + hdmi->dft_mode_str, NULL, 0, NULL,
  215278. + hdmi->default_bpp);
  215279. +
  215280. + console_lock();
  215281. +
  215282. + fb_destroy_modelist(&hdmi->fbi->modelist);
  215283. +
  215284. + /*Add all no interlaced CEA mode to default modelist */
  215285. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  215286. + mode = &mxc_cea_mode[i];
  215287. + if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0))
  215288. + fb_add_videomode(mode, &hdmi->fbi->modelist);
  215289. + }
  215290. +
  215291. + console_unlock();
  215292. +
  215293. + /* Find a nearest mode in default modelist */
  215294. + fb_var_to_videomode(&m, &hdmi->fbi->var);
  215295. + dump_fb_videomode(&m);
  215296. +
  215297. + hdmi->dft_mode_set = false;
  215298. + /* Save default video mode */
  215299. + memcpy(&hdmi->default_mode, &m, sizeof(struct fb_videomode));
  215300. +
  215301. + mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
  215302. + if (!mode) {
  215303. + pr_err("%s: could not find mode in modelist\n", __func__);
  215304. + return -1;
  215305. + }
  215306. +
  215307. + fb_videomode_to_var(&hdmi->fbi->var, mode);
  215308. +
  215309. + /* update fbi mode */
  215310. + hdmi->fbi->mode = (struct fb_videomode *)mode;
  215311. +
  215312. + /* Default setting HDMI working in HDMI mode*/
  215313. + hdmi->edid_cfg.hdmi_cap = true;
  215314. +
  215315. + INIT_DELAYED_WORK(&hdmi->hotplug_work, hotplug_worker);
  215316. + INIT_DELAYED_WORK(&hdmi->hdcp_hdp_work, hdcp_hdp_worker);
  215317. +
  215318. + /* Configure registers related to HDMI interrupt
  215319. + * generation before registering IRQ. */
  215320. + hdmi_writeb(HDMI_PHY_HPD, HDMI_PHY_POL0);
  215321. +
  215322. + /* Clear Hotplug interrupts */
  215323. + hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
  215324. +
  215325. + hdmi->nb.notifier_call = mxc_hdmi_fb_event;
  215326. + ret = fb_register_client(&hdmi->nb);
  215327. + if (ret < 0)
  215328. + goto efbclient;
  215329. +
  215330. + memset(&hdmi->hdmi_data, 0, sizeof(struct hdmi_data_info));
  215331. +
  215332. + /* Default HDMI working in RGB mode */
  215333. + hdmi->hdmi_data.rgb_out_enable = true;
  215334. +
  215335. + ret = devm_request_irq(&hdmi->pdev->dev, irq, mxc_hdmi_hotplug, IRQF_SHARED,
  215336. + dev_name(&hdmi->pdev->dev), hdmi);
  215337. + if (ret < 0) {
  215338. + dev_err(&hdmi->pdev->dev,
  215339. + "Unable to request irq: %d\n", ret);
  215340. + goto ereqirq;
  215341. + }
  215342. +
  215343. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_fb_name);
  215344. + if (ret < 0)
  215345. + dev_warn(&hdmi->pdev->dev,
  215346. + "cound not create sys node for fb name\n");
  215347. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_cable_state);
  215348. + if (ret < 0)
  215349. + dev_warn(&hdmi->pdev->dev,
  215350. + "cound not create sys node for cable state\n");
  215351. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_edid);
  215352. + if (ret < 0)
  215353. + dev_warn(&hdmi->pdev->dev,
  215354. + "cound not create sys node for edid\n");
  215355. +
  215356. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_rgb_out_enable);
  215357. + if (ret < 0)
  215358. + dev_warn(&hdmi->pdev->dev,
  215359. + "cound not create sys node for rgb out enable\n");
  215360. +
  215361. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_hdcp_enable);
  215362. + if (ret < 0)
  215363. + dev_warn(&hdmi->pdev->dev,
  215364. + "cound not create sys node for hdcp enable\n");
  215365. +
  215366. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  215367. +
  215368. + hdmi_inited = true;
  215369. +
  215370. + return ret;
  215371. +
  215372. +efbclient:
  215373. + free_irq(irq, hdmi);
  215374. +ereqirq:
  215375. + clk_disable_unprepare(hdmi->hdmi_iahb_clk);
  215376. +erate2:
  215377. + clk_put(hdmi->hdmi_iahb_clk);
  215378. +egetclk2:
  215379. + clk_disable_unprepare(hdmi->hdmi_isfr_clk);
  215380. +erate1:
  215381. + clk_put(hdmi->hdmi_isfr_clk);
  215382. +egetclk1:
  215383. + dev_dbg(&hdmi->pdev->dev, "%s error exit\n", __func__);
  215384. +
  215385. + return ret;
  215386. +}
  215387. +
  215388. +static void mxc_hdmi_disp_deinit(struct mxc_dispdrv_handle *disp)
  215389. +{
  215390. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  215391. +
  215392. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215393. +
  215394. + fb_unregister_client(&hdmi->nb);
  215395. +
  215396. + clk_disable_unprepare(hdmi->hdmi_isfr_clk);
  215397. + clk_put(hdmi->hdmi_isfr_clk);
  215398. + clk_disable_unprepare(hdmi->hdmi_iahb_clk);
  215399. + clk_put(hdmi->hdmi_iahb_clk);
  215400. +
  215401. + platform_device_unregister(hdmi->pdev);
  215402. +
  215403. + hdmi_inited = false;
  215404. +}
  215405. +
  215406. +static struct mxc_dispdrv_driver mxc_hdmi_drv = {
  215407. + .name = DISPDRV_HDMI,
  215408. + .init = mxc_hdmi_disp_init,
  215409. + .deinit = mxc_hdmi_disp_deinit,
  215410. + .enable = mxc_hdmi_power_on,
  215411. + .disable = mxc_hdmi_power_off,
  215412. +};
  215413. +
  215414. +
  215415. +static int mxc_hdmi_open(struct inode *inode, struct file *file)
  215416. +{
  215417. + return 0;
  215418. +}
  215419. +
  215420. +static long mxc_hdmi_ioctl(struct file *file,
  215421. + unsigned int cmd, unsigned long arg)
  215422. +{
  215423. + int __user *argp = (void __user *)arg;
  215424. + int ret = 0;
  215425. +
  215426. + switch (cmd) {
  215427. + case HDMI_IOC_GET_RESOURCE:
  215428. + ret = copy_to_user(argp, &g_hdmi->hdmi_data,
  215429. + sizeof(g_hdmi->hdmi_data)) ? -EFAULT : 0;
  215430. + break;
  215431. + case HDMI_IOC_GET_CPU_TYPE:
  215432. + *argp = g_hdmi->cpu_type;
  215433. + break;
  215434. + default:
  215435. + pr_debug("Unsupport cmd %d\n", cmd);
  215436. + break;
  215437. + }
  215438. + return ret;
  215439. +}
  215440. +
  215441. +static int mxc_hdmi_release(struct inode *inode, struct file *file)
  215442. +{
  215443. + return 0;
  215444. +}
  215445. +
  215446. +static const struct file_operations mxc_hdmi_fops = {
  215447. + .owner = THIS_MODULE,
  215448. + .open = mxc_hdmi_open,
  215449. + .release = mxc_hdmi_release,
  215450. + .unlocked_ioctl = mxc_hdmi_ioctl,
  215451. +};
  215452. +
  215453. +
  215454. +static int mxc_hdmi_probe(struct platform_device *pdev)
  215455. +{
  215456. + struct mxc_hdmi *hdmi;
  215457. + struct device *temp_class;
  215458. + struct resource *res;
  215459. + int ret = 0;
  215460. +
  215461. + /* Check I2C driver is loaded and available
  215462. + * check hdcp function is enable by dts */
  215463. + hdmi_hdcp_get_property(pdev);
  215464. + if (!hdmi_i2c && !hdcp_init)
  215465. + return -ENODEV;
  215466. +
  215467. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  215468. + if (!res)
  215469. + return -ENOENT;
  215470. +
  215471. + hdmi = devm_kzalloc(&pdev->dev,
  215472. + sizeof(struct mxc_hdmi),
  215473. + GFP_KERNEL);
  215474. + if (!hdmi) {
  215475. + dev_err(&pdev->dev, "Cannot allocate device data\n");
  215476. + ret = -ENOMEM;
  215477. + goto ealloc;
  215478. + }
  215479. + g_hdmi = hdmi;
  215480. +
  215481. + hdmi_major = register_chrdev(hdmi_major, "mxc_hdmi", &mxc_hdmi_fops);
  215482. + if (hdmi_major < 0) {
  215483. + printk(KERN_ERR "HDMI: unable to get a major for HDMI\n");
  215484. + ret = -EBUSY;
  215485. + goto ealloc;
  215486. + }
  215487. +
  215488. + hdmi_class = class_create(THIS_MODULE, "mxc_hdmi");
  215489. + if (IS_ERR(hdmi_class)) {
  215490. + ret = PTR_ERR(hdmi_class);
  215491. + goto err_out_chrdev;
  215492. + }
  215493. +
  215494. + temp_class = device_create(hdmi_class, NULL, MKDEV(hdmi_major, 0),
  215495. + NULL, "mxc_hdmi");
  215496. + if (IS_ERR(temp_class)) {
  215497. + ret = PTR_ERR(temp_class);
  215498. + goto err_out_class;
  215499. + }
  215500. +
  215501. + hdmi->pdev = pdev;
  215502. +
  215503. + hdmi->core_pdev = platform_device_alloc("mxc_hdmi_core", -1);
  215504. + if (!hdmi->core_pdev) {
  215505. + pr_err("%s failed platform_device_alloc for hdmi core\n",
  215506. + __func__);
  215507. + ret = -ENOMEM;
  215508. + goto ecore;
  215509. + }
  215510. +
  215511. + hdmi->gpr_base = ioremap(res->start, resource_size(res));
  215512. + if (!hdmi->gpr_base) {
  215513. + dev_err(&pdev->dev, "ioremap failed\n");
  215514. + ret = -ENOMEM;
  215515. + goto eiomap;
  215516. + }
  215517. +
  215518. + hdmi->gpr_hdmi_base = hdmi->gpr_base + 3;
  215519. + hdmi->gpr_sdma_base = hdmi->gpr_base;
  215520. +
  215521. + hdmi_inited = false;
  215522. +
  215523. + hdmi->disp_mxc_hdmi = mxc_dispdrv_register(&mxc_hdmi_drv);
  215524. + if (IS_ERR(hdmi->disp_mxc_hdmi)) {
  215525. + dev_err(&pdev->dev, "Failed to register dispdrv - 0x%x\n",
  215526. + (int)hdmi->disp_mxc_hdmi);
  215527. + ret = (int)hdmi->disp_mxc_hdmi;
  215528. + goto edispdrv;
  215529. + }
  215530. + mxc_dispdrv_setdata(hdmi->disp_mxc_hdmi, hdmi);
  215531. +
  215532. + platform_set_drvdata(pdev, hdmi);
  215533. +
  215534. + return 0;
  215535. +edispdrv:
  215536. + iounmap(hdmi->gpr_base);
  215537. +eiomap:
  215538. + platform_device_put(hdmi->core_pdev);
  215539. +ecore:
  215540. + kfree(hdmi);
  215541. +err_out_class:
  215542. + device_destroy(hdmi_class, MKDEV(hdmi_major, 0));
  215543. + class_destroy(hdmi_class);
  215544. +err_out_chrdev:
  215545. + unregister_chrdev(hdmi_major, "mxc_hdmi");
  215546. +ealloc:
  215547. + return ret;
  215548. +}
  215549. +
  215550. +static int mxc_hdmi_remove(struct platform_device *pdev)
  215551. +{
  215552. + struct mxc_hdmi *hdmi = platform_get_drvdata(pdev);
  215553. + int irq = platform_get_irq(pdev, 0);
  215554. +
  215555. + fb_unregister_client(&hdmi->nb);
  215556. +
  215557. + mxc_dispdrv_puthandle(hdmi->disp_mxc_hdmi);
  215558. + mxc_dispdrv_unregister(hdmi->disp_mxc_hdmi);
  215559. + iounmap(hdmi->gpr_base);
  215560. + /* No new work will be scheduled, wait for running ISR */
  215561. + free_irq(irq, hdmi);
  215562. + kfree(hdmi);
  215563. + g_hdmi = NULL;
  215564. +
  215565. + return 0;
  215566. +}
  215567. +
  215568. +static struct platform_driver mxc_hdmi_driver = {
  215569. + .probe = mxc_hdmi_probe,
  215570. + .remove = mxc_hdmi_remove,
  215571. + .driver = {
  215572. + .name = "mxc_hdmi",
  215573. + .of_match_table = imx_hdmi_dt_ids,
  215574. + .owner = THIS_MODULE,
  215575. + },
  215576. +};
  215577. +
  215578. +static int __init mxc_hdmi_init(void)
  215579. +{
  215580. + return platform_driver_register(&mxc_hdmi_driver);
  215581. +}
  215582. +module_init(mxc_hdmi_init);
  215583. +
  215584. +static void __exit mxc_hdmi_exit(void)
  215585. +{
  215586. + if (hdmi_major > 0) {
  215587. + device_destroy(hdmi_class, MKDEV(hdmi_major, 0));
  215588. + class_destroy(hdmi_class);
  215589. + unregister_chrdev(hdmi_major, "mxc_hdmi");
  215590. + hdmi_major = 0;
  215591. + }
  215592. +
  215593. + platform_driver_unregister(&mxc_hdmi_driver);
  215594. +}
  215595. +module_exit(mxc_hdmi_exit);
  215596. +
  215597. +static int mxc_hdmi_i2c_probe(struct i2c_client *client,
  215598. + const struct i2c_device_id *id)
  215599. +{
  215600. + if (!i2c_check_functionality(client->adapter,
  215601. + I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
  215602. + return -ENODEV;
  215603. +
  215604. + hdmi_i2c = client;
  215605. +
  215606. + return 0;
  215607. +}
  215608. +
  215609. +static int mxc_hdmi_i2c_remove(struct i2c_client *client)
  215610. +{
  215611. + hdmi_i2c = NULL;
  215612. + return 0;
  215613. +}
  215614. +
  215615. +static const struct of_device_id imx_hdmi_i2c_match[] = {
  215616. + { .compatible = "fsl,imx6-hdmi-i2c", },
  215617. + { /* sentinel */ }
  215618. +};
  215619. +
  215620. +static const struct i2c_device_id mxc_hdmi_i2c_id[] = {
  215621. + { "mxc_hdmi_i2c", 0 },
  215622. + {},
  215623. +};
  215624. +MODULE_DEVICE_TABLE(i2c, mxc_hdmi_i2c_id);
  215625. +
  215626. +static struct i2c_driver mxc_hdmi_i2c_driver = {
  215627. + .driver = {
  215628. + .name = "mxc_hdmi_i2c",
  215629. + .of_match_table = imx_hdmi_i2c_match,
  215630. + },
  215631. + .probe = mxc_hdmi_i2c_probe,
  215632. + .remove = mxc_hdmi_i2c_remove,
  215633. + .id_table = mxc_hdmi_i2c_id,
  215634. +};
  215635. +
  215636. +static int __init mxc_hdmi_i2c_init(void)
  215637. +{
  215638. + return i2c_add_driver(&mxc_hdmi_i2c_driver);
  215639. +}
  215640. +
  215641. +static void __exit mxc_hdmi_i2c_exit(void)
  215642. +{
  215643. + i2c_del_driver(&mxc_hdmi_i2c_driver);
  215644. +}
  215645. +
  215646. +module_init(mxc_hdmi_i2c_init);
  215647. +module_exit(mxc_hdmi_i2c_exit);
  215648. +
  215649. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  215650. diff -Nur linux-3.14.15/drivers/video/mxc/mxc_ipuv3_fb.c linux-linaro-stable-mx6/drivers/video/mxc/mxc_ipuv3_fb.c
  215651. --- linux-3.14.15/drivers/video/mxc/mxc_ipuv3_fb.c 1970-01-01 01:00:00.000000000 +0100
  215652. +++ linux-linaro-stable-mx6/drivers/video/mxc/mxc_ipuv3_fb.c 2014-08-20 19:31:50.020885713 +0200
  215653. @@ -0,0 +1,2578 @@
  215654. +/*
  215655. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  215656. + */
  215657. +
  215658. +/*
  215659. + * The code contained herein is licensed under the GNU General Public
  215660. + * License. You may obtain a copy of the GNU General Public License
  215661. + * Version 2 or later at the following locations:
  215662. + *
  215663. + * http://www.opensource.org/licenses/gpl-license.html
  215664. + * http://www.gnu.org/copyleft/gpl.html
  215665. + */
  215666. +
  215667. +/*!
  215668. + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
  215669. + */
  215670. +
  215671. +/*!
  215672. + * @file mxcfb.c
  215673. + *
  215674. + * @brief MXC Frame buffer driver for SDC
  215675. + *
  215676. + * @ingroup Framebuffer
  215677. + */
  215678. +
  215679. +/*!
  215680. + * Include files
  215681. + */
  215682. +#include <linux/clk.h>
  215683. +#include <linux/console.h>
  215684. +#include <linux/delay.h>
  215685. +#include <linux/dma-mapping.h>
  215686. +#include <linux/errno.h>
  215687. +#include <linux/fb.h>
  215688. +#include <linux/fsl_devices.h>
  215689. +#include <linux/init.h>
  215690. +#include <linux/interrupt.h>
  215691. +#include <linux/io.h>
  215692. +#include <linux/ioport.h>
  215693. +#include <linux/ipu.h>
  215694. +#include <linux/ipu-v3.h>
  215695. +#include <linux/kernel.h>
  215696. +#include <linux/module.h>
  215697. +#include <linux/mxcfb.h>
  215698. +#include <linux/of_device.h>
  215699. +#include <linux/platform_device.h>
  215700. +#include <linux/sched.h>
  215701. +#include <linux/slab.h>
  215702. +#include <linux/string.h>
  215703. +#include <linux/uaccess.h>
  215704. +
  215705. +#include "mxc_dispdrv.h"
  215706. +
  215707. +/*
  215708. + * Driver name
  215709. + */
  215710. +#define MXCFB_NAME "mxc_sdc_fb"
  215711. +
  215712. +/* Display port number */
  215713. +#define MXCFB_PORT_NUM 2
  215714. +/*!
  215715. + * Structure containing the MXC specific framebuffer information.
  215716. + */
  215717. +struct mxcfb_info {
  215718. + int default_bpp;
  215719. + int cur_blank;
  215720. + int next_blank;
  215721. + ipu_channel_t ipu_ch;
  215722. + int ipu_id;
  215723. + int ipu_di;
  215724. + u32 ipu_di_pix_fmt;
  215725. + bool ipu_int_clk;
  215726. + bool overlay;
  215727. + bool alpha_chan_en;
  215728. + bool late_init;
  215729. + bool first_set_par;
  215730. + dma_addr_t alpha_phy_addr0;
  215731. + dma_addr_t alpha_phy_addr1;
  215732. + void *alpha_virt_addr0;
  215733. + void *alpha_virt_addr1;
  215734. + uint32_t alpha_mem_len;
  215735. + uint32_t ipu_ch_irq;
  215736. + uint32_t ipu_ch_nf_irq;
  215737. + uint32_t ipu_alp_ch_irq;
  215738. + uint32_t cur_ipu_buf;
  215739. + uint32_t cur_ipu_alpha_buf;
  215740. +
  215741. + u32 pseudo_palette[16];
  215742. +
  215743. + bool mode_found;
  215744. + struct completion flip_complete;
  215745. + struct completion alpha_flip_complete;
  215746. + struct completion vsync_complete;
  215747. +
  215748. + void *ipu;
  215749. + struct fb_info *ovfbi;
  215750. +
  215751. + struct mxc_dispdrv_handle *dispdrv;
  215752. +
  215753. + struct fb_var_screeninfo cur_var;
  215754. +};
  215755. +
  215756. +struct mxcfb_pfmt {
  215757. + u32 fb_pix_fmt;
  215758. + int bpp;
  215759. + struct fb_bitfield red;
  215760. + struct fb_bitfield green;
  215761. + struct fb_bitfield blue;
  215762. + struct fb_bitfield transp;
  215763. +};
  215764. +
  215765. +static const struct mxcfb_pfmt mxcfb_pfmts[] = {
  215766. + /* pixel bpp red green blue transp */
  215767. + {IPU_PIX_FMT_RGB565, 16, {11, 5, 0}, { 5, 6, 0}, { 0, 5, 0}, { 0, 0, 0} },
  215768. + {IPU_PIX_FMT_RGB24, 24, { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0}, { 0, 0, 0} },
  215769. + {IPU_PIX_FMT_BGR24, 24, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 0, 0, 0} },
  215770. + {IPU_PIX_FMT_RGB32, 32, { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0}, {24, 8, 0} },
  215771. + {IPU_PIX_FMT_BGR32, 32, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, {24, 8, 0} },
  215772. + {IPU_PIX_FMT_ABGR32, 32, {24, 8, 0}, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0} },
  215773. +};
  215774. +
  215775. +struct mxcfb_alloc_list {
  215776. + struct list_head list;
  215777. + dma_addr_t phy_addr;
  215778. + void *cpu_addr;
  215779. + u32 size;
  215780. +};
  215781. +
  215782. +enum {
  215783. + BOTH_ON,
  215784. + SRC_ON,
  215785. + TGT_ON,
  215786. + BOTH_OFF
  215787. +};
  215788. +
  215789. +static bool g_dp_in_use[2];
  215790. +LIST_HEAD(fb_alloc_list);
  215791. +
  215792. +/* Return default standard(RGB) pixel format */
  215793. +static uint32_t bpp_to_pixfmt(int bpp)
  215794. +{
  215795. + uint32_t pixfmt = 0;
  215796. +
  215797. + switch (bpp) {
  215798. + case 24:
  215799. + pixfmt = IPU_PIX_FMT_BGR24;
  215800. + break;
  215801. + case 32:
  215802. + pixfmt = IPU_PIX_FMT_BGR32;
  215803. + break;
  215804. + case 16:
  215805. + pixfmt = IPU_PIX_FMT_RGB565;
  215806. + break;
  215807. + }
  215808. + return pixfmt;
  215809. +}
  215810. +
  215811. +static inline int bitfield_is_equal(struct fb_bitfield f1,
  215812. + struct fb_bitfield f2)
  215813. +{
  215814. + return !memcmp(&f1, &f2, sizeof(f1));
  215815. +}
  215816. +
  215817. +static int pixfmt_to_var(uint32_t pixfmt, struct fb_var_screeninfo *var)
  215818. +{
  215819. + int i, ret = -1;
  215820. +
  215821. + for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
  215822. + if (pixfmt == mxcfb_pfmts[i].fb_pix_fmt) {
  215823. + var->red = mxcfb_pfmts[i].red;
  215824. + var->green = mxcfb_pfmts[i].green;
  215825. + var->blue = mxcfb_pfmts[i].blue;
  215826. + var->transp = mxcfb_pfmts[i].transp;
  215827. + var->bits_per_pixel = mxcfb_pfmts[i].bpp;
  215828. + ret = 0;
  215829. + break;
  215830. + }
  215831. + }
  215832. + return ret;
  215833. +}
  215834. +
  215835. +static int bpp_to_var(int bpp, struct fb_var_screeninfo *var)
  215836. +{
  215837. + uint32_t pixfmt = 0;
  215838. +
  215839. + pixfmt = bpp_to_pixfmt(bpp);
  215840. + if (pixfmt)
  215841. + return pixfmt_to_var(pixfmt, var);
  215842. + else
  215843. + return -1;
  215844. +}
  215845. +
  215846. +static int check_var_pixfmt(struct fb_var_screeninfo *var)
  215847. +{
  215848. + int i, ret = -1;
  215849. +
  215850. + for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
  215851. + if (bitfield_is_equal(var->red, mxcfb_pfmts[i].red) &&
  215852. + bitfield_is_equal(var->green, mxcfb_pfmts[i].green) &&
  215853. + bitfield_is_equal(var->blue, mxcfb_pfmts[i].blue) &&
  215854. + bitfield_is_equal(var->transp, mxcfb_pfmts[i].transp) &&
  215855. + var->bits_per_pixel == mxcfb_pfmts[i].bpp) {
  215856. + ret = 0;
  215857. + break;
  215858. + }
  215859. + }
  215860. + return ret;
  215861. +}
  215862. +
  215863. +static uint32_t fbi_to_pixfmt(struct fb_info *fbi)
  215864. +{
  215865. + int i;
  215866. + uint32_t pixfmt = 0;
  215867. +
  215868. + if (fbi->var.nonstd)
  215869. + return fbi->var.nonstd;
  215870. +
  215871. + for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
  215872. + if (bitfield_is_equal(fbi->var.red, mxcfb_pfmts[i].red) &&
  215873. + bitfield_is_equal(fbi->var.green, mxcfb_pfmts[i].green) &&
  215874. + bitfield_is_equal(fbi->var.blue, mxcfb_pfmts[i].blue) &&
  215875. + bitfield_is_equal(fbi->var.transp, mxcfb_pfmts[i].transp)) {
  215876. + pixfmt = mxcfb_pfmts[i].fb_pix_fmt;
  215877. + break;
  215878. + }
  215879. + }
  215880. +
  215881. + if (pixfmt == 0)
  215882. + dev_err(fbi->device, "cannot get pixel format\n");
  215883. +
  215884. + return pixfmt;
  215885. +}
  215886. +
  215887. +static struct fb_info *found_registered_fb(ipu_channel_t ipu_ch, int ipu_id)
  215888. +{
  215889. + int i;
  215890. + struct mxcfb_info *mxc_fbi;
  215891. + struct fb_info *fbi = NULL;
  215892. +
  215893. + for (i = 0; i < num_registered_fb; i++) {
  215894. + mxc_fbi =
  215895. + ((struct mxcfb_info *)(registered_fb[i]->par));
  215896. +
  215897. + if ((mxc_fbi->ipu_ch == ipu_ch) &&
  215898. + (mxc_fbi->ipu_id == ipu_id)) {
  215899. + fbi = registered_fb[i];
  215900. + break;
  215901. + }
  215902. + }
  215903. + return fbi;
  215904. +}
  215905. +
  215906. +static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id);
  215907. +static irqreturn_t mxcfb_nf_irq_handler(int irq, void *dev_id);
  215908. +static int mxcfb_blank(int blank, struct fb_info *info);
  215909. +static int mxcfb_map_video_memory(struct fb_info *fbi);
  215910. +static int mxcfb_unmap_video_memory(struct fb_info *fbi);
  215911. +
  215912. +/*
  215913. + * Set fixed framebuffer parameters based on variable settings.
  215914. + *
  215915. + * @param info framebuffer information pointer
  215916. + */
  215917. +static int mxcfb_set_fix(struct fb_info *info)
  215918. +{
  215919. + struct fb_fix_screeninfo *fix = &info->fix;
  215920. + struct fb_var_screeninfo *var = &info->var;
  215921. +
  215922. + fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
  215923. +
  215924. + fix->type = FB_TYPE_PACKED_PIXELS;
  215925. + fix->accel = FB_ACCEL_NONE;
  215926. + fix->visual = FB_VISUAL_TRUECOLOR;
  215927. + fix->xpanstep = 1;
  215928. + fix->ywrapstep = 1;
  215929. + fix->ypanstep = 1;
  215930. +
  215931. + return 0;
  215932. +}
  215933. +
  215934. +static int _setup_disp_channel1(struct fb_info *fbi)
  215935. +{
  215936. + ipu_channel_params_t params;
  215937. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  215938. +
  215939. + memset(&params, 0, sizeof(params));
  215940. +
  215941. + if (mxc_fbi->ipu_ch == MEM_DC_SYNC) {
  215942. + params.mem_dc_sync.di = mxc_fbi->ipu_di;
  215943. + if (fbi->var.vmode & FB_VMODE_INTERLACED)
  215944. + params.mem_dc_sync.interlaced = true;
  215945. + params.mem_dc_sync.out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
  215946. + params.mem_dc_sync.in_pixel_fmt = fbi_to_pixfmt(fbi);
  215947. + } else {
  215948. + params.mem_dp_bg_sync.di = mxc_fbi->ipu_di;
  215949. + if (fbi->var.vmode & FB_VMODE_INTERLACED)
  215950. + params.mem_dp_bg_sync.interlaced = true;
  215951. + params.mem_dp_bg_sync.out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
  215952. + params.mem_dp_bg_sync.in_pixel_fmt = fbi_to_pixfmt(fbi);
  215953. + if (mxc_fbi->alpha_chan_en)
  215954. + params.mem_dp_bg_sync.alpha_chan_en = true;
  215955. + }
  215956. + ipu_init_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, &params);
  215957. +
  215958. + return 0;
  215959. +}
  215960. +
  215961. +static int _setup_disp_channel2(struct fb_info *fbi)
  215962. +{
  215963. + int retval = 0;
  215964. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  215965. + int fb_stride;
  215966. + unsigned long base;
  215967. + unsigned int fr_xoff, fr_yoff, fr_w, fr_h;
  215968. +
  215969. + switch (fbi_to_pixfmt(fbi)) {
  215970. + case IPU_PIX_FMT_YUV420P2:
  215971. + case IPU_PIX_FMT_YVU420P:
  215972. + case IPU_PIX_FMT_NV12:
  215973. + case IPU_PIX_FMT_YUV422P:
  215974. + case IPU_PIX_FMT_YVU422P:
  215975. + case IPU_PIX_FMT_YUV420P:
  215976. + case IPU_PIX_FMT_YUV444P:
  215977. + fb_stride = fbi->var.xres_virtual;
  215978. + break;
  215979. + default:
  215980. + fb_stride = fbi->fix.line_length;
  215981. + }
  215982. +
  215983. + base = fbi->fix.smem_start;
  215984. + fr_xoff = fbi->var.xoffset;
  215985. + fr_w = fbi->var.xres_virtual;
  215986. + if (!(fbi->var.vmode & FB_VMODE_YWRAP)) {
  215987. + dev_dbg(fbi->device, "Y wrap disabled\n");
  215988. + fr_yoff = fbi->var.yoffset % fbi->var.yres;
  215989. + fr_h = fbi->var.yres;
  215990. + base += fbi->fix.line_length * fbi->var.yres *
  215991. + (fbi->var.yoffset / fbi->var.yres);
  215992. + } else {
  215993. + dev_dbg(fbi->device, "Y wrap enabled\n");
  215994. + fr_yoff = fbi->var.yoffset;
  215995. + fr_h = fbi->var.yres_virtual;
  215996. + }
  215997. + base += fr_yoff * fb_stride + fr_xoff;
  215998. +
  215999. + mxc_fbi->cur_ipu_buf = 2;
  216000. + init_completion(&mxc_fbi->flip_complete);
  216001. + /*
  216002. + * We don't need to wait for vsync at the first time
  216003. + * we do pan display after fb is initialized, as IPU will
  216004. + * switch to the newly selected buffer automatically,
  216005. + * so we call complete() for both mxc_fbi->flip_complete
  216006. + * and mxc_fbi->alpha_flip_complete.
  216007. + */
  216008. + complete(&mxc_fbi->flip_complete);
  216009. + if (mxc_fbi->alpha_chan_en) {
  216010. + mxc_fbi->cur_ipu_alpha_buf = 1;
  216011. + init_completion(&mxc_fbi->alpha_flip_complete);
  216012. + complete(&mxc_fbi->alpha_flip_complete);
  216013. + }
  216014. +
  216015. + retval = ipu_init_channel_buffer(mxc_fbi->ipu,
  216016. + mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
  216017. + fbi_to_pixfmt(fbi),
  216018. + fbi->var.xres, fbi->var.yres,
  216019. + fb_stride,
  216020. + fbi->var.rotate,
  216021. + base,
  216022. + base,
  216023. + fbi->var.accel_flags &
  216024. + FB_ACCEL_DOUBLE_FLAG ? 0 : base,
  216025. + 0, 0);
  216026. + if (retval) {
  216027. + dev_err(fbi->device,
  216028. + "ipu_init_channel_buffer error %d\n", retval);
  216029. + return retval;
  216030. + }
  216031. +
  216032. + /* update u/v offset */
  216033. + ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  216034. + IPU_INPUT_BUFFER,
  216035. + fbi_to_pixfmt(fbi),
  216036. + fr_w,
  216037. + fr_h,
  216038. + fr_w,
  216039. + 0, 0,
  216040. + fr_yoff,
  216041. + fr_xoff);
  216042. +
  216043. + if (mxc_fbi->alpha_chan_en) {
  216044. + retval = ipu_init_channel_buffer(mxc_fbi->ipu,
  216045. + mxc_fbi->ipu_ch,
  216046. + IPU_ALPHA_IN_BUFFER,
  216047. + IPU_PIX_FMT_GENERIC,
  216048. + fbi->var.xres, fbi->var.yres,
  216049. + fbi->var.xres,
  216050. + fbi->var.rotate,
  216051. + mxc_fbi->alpha_phy_addr1,
  216052. + mxc_fbi->alpha_phy_addr0,
  216053. + 0,
  216054. + 0, 0);
  216055. + if (retval) {
  216056. + dev_err(fbi->device,
  216057. + "ipu_init_channel_buffer error %d\n", retval);
  216058. + return retval;
  216059. + }
  216060. + }
  216061. +
  216062. + return retval;
  216063. +}
  216064. +
  216065. +static bool mxcfb_need_to_set_par(struct fb_info *fbi)
  216066. +{
  216067. + struct mxcfb_info *mxc_fbi = fbi->par;
  216068. +
  216069. + if ((fbi->var.activate & FB_ACTIVATE_FORCE) &&
  216070. + (fbi->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
  216071. + return true;
  216072. +
  216073. + /*
  216074. + * Ignore xoffset and yoffset update,
  216075. + * because pan display handles this case.
  216076. + */
  216077. + mxc_fbi->cur_var.xoffset = fbi->var.xoffset;
  216078. + mxc_fbi->cur_var.yoffset = fbi->var.yoffset;
  216079. +
  216080. + return !!memcmp(&mxc_fbi->cur_var, &fbi->var,
  216081. + sizeof(struct fb_var_screeninfo));
  216082. +}
  216083. +
  216084. +/*
  216085. + * Set framebuffer parameters and change the operating mode.
  216086. + *
  216087. + * @param info framebuffer information pointer
  216088. + */
  216089. +static int mxcfb_set_par(struct fb_info *fbi)
  216090. +{
  216091. + int retval = 0;
  216092. + u32 mem_len, alpha_mem_len;
  216093. + ipu_di_signal_cfg_t sig_cfg;
  216094. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  216095. +
  216096. + int16_t ov_pos_x = 0, ov_pos_y = 0;
  216097. + int ov_pos_ret = 0;
  216098. + struct mxcfb_info *mxc_fbi_fg = NULL;
  216099. + bool ovfbi_enable = false;
  216100. +
  216101. + if (ipu_ch_param_bad_alpha_pos(fbi_to_pixfmt(fbi)) &&
  216102. + mxc_fbi->alpha_chan_en) {
  216103. + dev_err(fbi->device, "Bad pixel format for "
  216104. + "graphics plane fb\n");
  216105. + return -EINVAL;
  216106. + }
  216107. +
  216108. + if (mxc_fbi->ovfbi)
  216109. + mxc_fbi_fg = (struct mxcfb_info *)mxc_fbi->ovfbi->par;
  216110. +
  216111. + if (mxc_fbi->ovfbi && mxc_fbi_fg)
  216112. + if (mxc_fbi_fg->next_blank == FB_BLANK_UNBLANK)
  216113. + ovfbi_enable = true;
  216114. +
  216115. + if (!mxcfb_need_to_set_par(fbi))
  216116. + return 0;
  216117. +
  216118. + dev_dbg(fbi->device, "Reconfiguring framebuffer\n");
  216119. +
  216120. + if (fbi->var.xres == 0 || fbi->var.yres == 0)
  216121. + return 0;
  216122. +
  216123. + if (ovfbi_enable) {
  216124. + ov_pos_ret = ipu_disp_get_window_pos(
  216125. + mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch,
  216126. + &ov_pos_x, &ov_pos_y);
  216127. + if (ov_pos_ret < 0)
  216128. + dev_err(fbi->device, "Get overlay pos failed, dispdrv:%s.\n",
  216129. + mxc_fbi->dispdrv->drv->name);
  216130. +
  216131. + ipu_clear_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_irq);
  216132. + ipu_disable_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_irq);
  216133. + ipu_clear_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_nf_irq);
  216134. + ipu_disable_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_nf_irq);
  216135. + ipu_disable_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch, true);
  216136. + ipu_uninit_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
  216137. + }
  216138. +
  216139. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  216140. + ipu_disable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  216141. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  216142. + ipu_disable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  216143. + ipu_disable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, true);
  216144. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  216145. +
  216146. + /*
  216147. + * Disable IPU hsp clock if it is enabled for an
  216148. + * additional time in ipu common driver.
  216149. + */
  216150. + if (mxc_fbi->first_set_par && mxc_fbi->late_init)
  216151. + ipu_disable_hsp_clk(mxc_fbi->ipu);
  216152. +
  216153. + mxcfb_set_fix(fbi);
  216154. +
  216155. + mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
  216156. + if (!fbi->fix.smem_start || (mem_len > fbi->fix.smem_len)) {
  216157. + if (fbi->fix.smem_start)
  216158. + mxcfb_unmap_video_memory(fbi);
  216159. +
  216160. + if (mxcfb_map_video_memory(fbi) < 0)
  216161. + return -ENOMEM;
  216162. + }
  216163. +
  216164. + if (mxc_fbi->first_set_par) {
  216165. + /*
  216166. + * Clear the screen in case uboot fb pixel format is not
  216167. + * the same to kernel fb pixel format.
  216168. + */
  216169. + if (mxc_fbi->late_init)
  216170. + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
  216171. +
  216172. + mxc_fbi->first_set_par = false;
  216173. + }
  216174. +
  216175. + if (mxc_fbi->alpha_chan_en) {
  216176. + alpha_mem_len = fbi->var.xres * fbi->var.yres;
  216177. + if ((!mxc_fbi->alpha_phy_addr0 && !mxc_fbi->alpha_phy_addr1) ||
  216178. + (alpha_mem_len > mxc_fbi->alpha_mem_len)) {
  216179. + if (mxc_fbi->alpha_phy_addr0)
  216180. + dma_free_coherent(fbi->device,
  216181. + mxc_fbi->alpha_mem_len,
  216182. + mxc_fbi->alpha_virt_addr0,
  216183. + mxc_fbi->alpha_phy_addr0);
  216184. + if (mxc_fbi->alpha_phy_addr1)
  216185. + dma_free_coherent(fbi->device,
  216186. + mxc_fbi->alpha_mem_len,
  216187. + mxc_fbi->alpha_virt_addr1,
  216188. + mxc_fbi->alpha_phy_addr1);
  216189. +
  216190. + mxc_fbi->alpha_virt_addr0 =
  216191. + dma_alloc_coherent(fbi->device,
  216192. + alpha_mem_len,
  216193. + &mxc_fbi->alpha_phy_addr0,
  216194. + GFP_DMA | GFP_KERNEL);
  216195. +
  216196. + mxc_fbi->alpha_virt_addr1 =
  216197. + dma_alloc_coherent(fbi->device,
  216198. + alpha_mem_len,
  216199. + &mxc_fbi->alpha_phy_addr1,
  216200. + GFP_DMA | GFP_KERNEL);
  216201. + if (mxc_fbi->alpha_virt_addr0 == NULL ||
  216202. + mxc_fbi->alpha_virt_addr1 == NULL) {
  216203. + dev_err(fbi->device, "mxcfb: dma alloc for"
  216204. + " alpha buffer failed.\n");
  216205. + if (mxc_fbi->alpha_virt_addr0)
  216206. + dma_free_coherent(fbi->device,
  216207. + mxc_fbi->alpha_mem_len,
  216208. + mxc_fbi->alpha_virt_addr0,
  216209. + mxc_fbi->alpha_phy_addr0);
  216210. + if (mxc_fbi->alpha_virt_addr1)
  216211. + dma_free_coherent(fbi->device,
  216212. + mxc_fbi->alpha_mem_len,
  216213. + mxc_fbi->alpha_virt_addr1,
  216214. + mxc_fbi->alpha_phy_addr1);
  216215. + return -ENOMEM;
  216216. + }
  216217. + mxc_fbi->alpha_mem_len = alpha_mem_len;
  216218. + }
  216219. + }
  216220. +
  216221. + if (mxc_fbi->next_blank != FB_BLANK_UNBLANK)
  216222. + return retval;
  216223. +
  216224. + if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->setup) {
  216225. + retval = mxc_fbi->dispdrv->drv->setup(mxc_fbi->dispdrv, fbi);
  216226. + if (retval < 0) {
  216227. + dev_err(fbi->device, "setup error, dispdrv:%s.\n",
  216228. + mxc_fbi->dispdrv->drv->name);
  216229. + return -EINVAL;
  216230. + }
  216231. + }
  216232. +
  216233. + _setup_disp_channel1(fbi);
  216234. + if (ovfbi_enable)
  216235. + _setup_disp_channel1(mxc_fbi->ovfbi);
  216236. +
  216237. + if (!mxc_fbi->overlay) {
  216238. + uint32_t out_pixel_fmt;
  216239. +
  216240. + memset(&sig_cfg, 0, sizeof(sig_cfg));
  216241. + if (fbi->var.vmode & FB_VMODE_INTERLACED)
  216242. + sig_cfg.interlaced = true;
  216243. + out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
  216244. + if (fbi->var.vmode & FB_VMODE_ODD_FLD_FIRST) /* PAL */
  216245. + sig_cfg.odd_field_first = true;
  216246. + if (mxc_fbi->ipu_int_clk)
  216247. + sig_cfg.int_clk = true;
  216248. + if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
  216249. + sig_cfg.Hsync_pol = true;
  216250. + if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
  216251. + sig_cfg.Vsync_pol = true;
  216252. + if (!(fbi->var.sync & FB_SYNC_CLK_LAT_FALL))
  216253. + sig_cfg.clk_pol = true;
  216254. + if (fbi->var.sync & FB_SYNC_DATA_INVERT)
  216255. + sig_cfg.data_pol = true;
  216256. + if (!(fbi->var.sync & FB_SYNC_OE_LOW_ACT))
  216257. + sig_cfg.enable_pol = true;
  216258. + if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
  216259. + sig_cfg.clkidle_en = true;
  216260. +
  216261. + dev_dbg(fbi->device, "pixclock = %ul Hz\n",
  216262. + (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
  216263. +
  216264. + if (ipu_init_sync_panel(mxc_fbi->ipu, mxc_fbi->ipu_di,
  216265. + (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
  216266. + fbi->var.xres, fbi->var.yres,
  216267. + out_pixel_fmt,
  216268. + fbi->var.left_margin,
  216269. + fbi->var.hsync_len,
  216270. + fbi->var.right_margin,
  216271. + fbi->var.upper_margin,
  216272. + fbi->var.vsync_len,
  216273. + fbi->var.lower_margin,
  216274. + 0, sig_cfg) != 0) {
  216275. + dev_err(fbi->device,
  216276. + "mxcfb: Error initializing panel.\n");
  216277. + return -EINVAL;
  216278. + }
  216279. +
  216280. + fbi->mode =
  216281. + (struct fb_videomode *)fb_match_mode(&fbi->var,
  216282. + &fbi->modelist);
  216283. +
  216284. + ipu_disp_set_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch, 0, 0);
  216285. + }
  216286. +
  216287. + retval = _setup_disp_channel2(fbi);
  216288. + if (retval) {
  216289. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  216290. + return retval;
  216291. + }
  216292. +
  216293. + if (ovfbi_enable) {
  216294. + if (ov_pos_ret >= 0)
  216295. + ipu_disp_set_window_pos(
  216296. + mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch,
  216297. + ov_pos_x, ov_pos_y);
  216298. + retval = _setup_disp_channel2(mxc_fbi->ovfbi);
  216299. + if (retval) {
  216300. + ipu_uninit_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
  216301. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  216302. + return retval;
  216303. + }
  216304. + }
  216305. +
  216306. + ipu_enable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  216307. + if (ovfbi_enable)
  216308. + ipu_enable_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
  216309. +
  216310. + if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->enable) {
  216311. + retval = mxc_fbi->dispdrv->drv->enable(mxc_fbi->dispdrv);
  216312. + if (retval < 0) {
  216313. + dev_err(fbi->device, "enable error, dispdrv:%s.\n",
  216314. + mxc_fbi->dispdrv->drv->name);
  216315. + return -EINVAL;
  216316. + }
  216317. + }
  216318. +
  216319. + mxc_fbi->cur_var = fbi->var;
  216320. +
  216321. + return retval;
  216322. +}
  216323. +
  216324. +static int _swap_channels(struct fb_info *fbi_from,
  216325. + struct fb_info *fbi_to, bool both_on)
  216326. +{
  216327. + int retval, tmp;
  216328. + ipu_channel_t old_ch;
  216329. + struct fb_info *ovfbi;
  216330. + struct mxcfb_info *mxc_fbi_from = (struct mxcfb_info *)fbi_from->par;
  216331. + struct mxcfb_info *mxc_fbi_to = (struct mxcfb_info *)fbi_to->par;
  216332. +
  216333. + if (both_on) {
  216334. + ipu_disable_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch, true);
  216335. + ipu_uninit_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch);
  216336. + }
  216337. +
  216338. + /* switch the mxc fbi parameters */
  216339. + old_ch = mxc_fbi_from->ipu_ch;
  216340. + mxc_fbi_from->ipu_ch = mxc_fbi_to->ipu_ch;
  216341. + mxc_fbi_to->ipu_ch = old_ch;
  216342. + tmp = mxc_fbi_from->ipu_ch_irq;
  216343. + mxc_fbi_from->ipu_ch_irq = mxc_fbi_to->ipu_ch_irq;
  216344. + mxc_fbi_to->ipu_ch_irq = tmp;
  216345. + tmp = mxc_fbi_from->ipu_ch_nf_irq;
  216346. + mxc_fbi_from->ipu_ch_nf_irq = mxc_fbi_to->ipu_ch_nf_irq;
  216347. + mxc_fbi_to->ipu_ch_nf_irq = tmp;
  216348. + ovfbi = mxc_fbi_from->ovfbi;
  216349. + mxc_fbi_from->ovfbi = mxc_fbi_to->ovfbi;
  216350. + mxc_fbi_to->ovfbi = ovfbi;
  216351. +
  216352. + _setup_disp_channel1(fbi_from);
  216353. + retval = _setup_disp_channel2(fbi_from);
  216354. + if (retval)
  216355. + return retval;
  216356. +
  216357. + /* switch between dp and dc, disable old idmac, enable new idmac */
  216358. + retval = ipu_swap_channel(mxc_fbi_from->ipu, old_ch, mxc_fbi_from->ipu_ch);
  216359. + ipu_uninit_channel(mxc_fbi_from->ipu, old_ch);
  216360. +
  216361. + if (both_on) {
  216362. + _setup_disp_channel1(fbi_to);
  216363. + retval = _setup_disp_channel2(fbi_to);
  216364. + if (retval)
  216365. + return retval;
  216366. + ipu_enable_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch);
  216367. + }
  216368. +
  216369. + return retval;
  216370. +}
  216371. +
  216372. +static int swap_channels(struct fb_info *fbi_from)
  216373. +{
  216374. + int i;
  216375. + int swap_mode;
  216376. + ipu_channel_t ch_to;
  216377. + struct mxcfb_info *mxc_fbi_from = (struct mxcfb_info *)fbi_from->par;
  216378. + struct fb_info *fbi_to = NULL;
  216379. + struct mxcfb_info *mxc_fbi_to;
  216380. +
  216381. + /* what's the target channel? */
  216382. + if (mxc_fbi_from->ipu_ch == MEM_BG_SYNC)
  216383. + ch_to = MEM_DC_SYNC;
  216384. + else
  216385. + ch_to = MEM_BG_SYNC;
  216386. +
  216387. + fbi_to = found_registered_fb(ch_to, mxc_fbi_from->ipu_id);
  216388. + if (!fbi_to)
  216389. + return -1;
  216390. + mxc_fbi_to = (struct mxcfb_info *)fbi_to->par;
  216391. +
  216392. + ipu_clear_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq);
  216393. + ipu_clear_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq);
  216394. + ipu_free_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq, fbi_from);
  216395. + ipu_free_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq, fbi_to);
  216396. + ipu_clear_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq);
  216397. + ipu_clear_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq);
  216398. + ipu_free_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq, fbi_from);
  216399. + ipu_free_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq, fbi_to);
  216400. +
  216401. + if (mxc_fbi_from->cur_blank == FB_BLANK_UNBLANK) {
  216402. + if (mxc_fbi_to->cur_blank == FB_BLANK_UNBLANK)
  216403. + swap_mode = BOTH_ON;
  216404. + else
  216405. + swap_mode = SRC_ON;
  216406. + } else {
  216407. + if (mxc_fbi_to->cur_blank == FB_BLANK_UNBLANK)
  216408. + swap_mode = TGT_ON;
  216409. + else
  216410. + swap_mode = BOTH_OFF;
  216411. + }
  216412. +
  216413. + switch (swap_mode) {
  216414. + case BOTH_ON:
  216415. + /* disable target->switch src->enable target */
  216416. + _swap_channels(fbi_from, fbi_to, true);
  216417. + break;
  216418. + case SRC_ON:
  216419. + /* just switch src */
  216420. + _swap_channels(fbi_from, fbi_to, false);
  216421. + break;
  216422. + case TGT_ON:
  216423. + /* just switch target */
  216424. + _swap_channels(fbi_to, fbi_from, false);
  216425. + break;
  216426. + case BOTH_OFF:
  216427. + /* switch directly, no more need to do */
  216428. + mxc_fbi_to->ipu_ch = mxc_fbi_from->ipu_ch;
  216429. + mxc_fbi_from->ipu_ch = ch_to;
  216430. + i = mxc_fbi_from->ipu_ch_irq;
  216431. + mxc_fbi_from->ipu_ch_irq = mxc_fbi_to->ipu_ch_irq;
  216432. + mxc_fbi_to->ipu_ch_irq = i;
  216433. + i = mxc_fbi_from->ipu_ch_nf_irq;
  216434. + mxc_fbi_from->ipu_ch_nf_irq = mxc_fbi_to->ipu_ch_nf_irq;
  216435. + mxc_fbi_to->ipu_ch_nf_irq = i;
  216436. + break;
  216437. + default:
  216438. + break;
  216439. + }
  216440. +
  216441. + if (ipu_request_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq,
  216442. + mxcfb_irq_handler, IPU_IRQF_ONESHOT,
  216443. + MXCFB_NAME, fbi_from) != 0) {
  216444. + dev_err(fbi_from->device, "Error registering irq %d\n",
  216445. + mxc_fbi_from->ipu_ch_irq);
  216446. + return -EBUSY;
  216447. + }
  216448. + ipu_disable_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq);
  216449. + if (ipu_request_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq,
  216450. + mxcfb_irq_handler, IPU_IRQF_ONESHOT,
  216451. + MXCFB_NAME, fbi_to) != 0) {
  216452. + dev_err(fbi_to->device, "Error registering irq %d\n",
  216453. + mxc_fbi_to->ipu_ch_irq);
  216454. + return -EBUSY;
  216455. + }
  216456. + ipu_disable_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq);
  216457. + if (ipu_request_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq,
  216458. + mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT,
  216459. + MXCFB_NAME, fbi_from) != 0) {
  216460. + dev_err(fbi_from->device, "Error registering irq %d\n",
  216461. + mxc_fbi_from->ipu_ch_nf_irq);
  216462. + return -EBUSY;
  216463. + }
  216464. + ipu_disable_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq);
  216465. + if (ipu_request_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq,
  216466. + mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT,
  216467. + MXCFB_NAME, fbi_to) != 0) {
  216468. + dev_err(fbi_to->device, "Error registering irq %d\n",
  216469. + mxc_fbi_to->ipu_ch_nf_irq);
  216470. + return -EBUSY;
  216471. + }
  216472. + ipu_disable_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq);
  216473. +
  216474. + return 0;
  216475. +}
  216476. +
  216477. +/*
  216478. + * Check framebuffer variable parameters and adjust to valid values.
  216479. + *
  216480. + * @param var framebuffer variable parameters
  216481. + *
  216482. + * @param info framebuffer information pointer
  216483. + */
  216484. +static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  216485. +{
  216486. + u32 vtotal;
  216487. + u32 htotal;
  216488. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par;
  216489. +
  216490. +
  216491. + if (var->xres == 0 || var->yres == 0)
  216492. + return 0;
  216493. +
  216494. + /* fg should not bigger than bg */
  216495. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  216496. + struct fb_info *fbi_tmp;
  216497. + int bg_xres = 0, bg_yres = 0;
  216498. + int16_t pos_x, pos_y;
  216499. +
  216500. + bg_xres = var->xres;
  216501. + bg_yres = var->yres;
  216502. +
  216503. + fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  216504. + if (fbi_tmp) {
  216505. + bg_xres = fbi_tmp->var.xres;
  216506. + bg_yres = fbi_tmp->var.yres;
  216507. + }
  216508. +
  216509. + ipu_disp_get_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch, &pos_x, &pos_y);
  216510. +
  216511. + if ((var->xres + pos_x) > bg_xres)
  216512. + var->xres = bg_xres - pos_x;
  216513. + if ((var->yres + pos_y) > bg_yres)
  216514. + var->yres = bg_yres - pos_y;
  216515. + }
  216516. +
  216517. + if (var->rotate > IPU_ROTATE_VERT_FLIP)
  216518. + var->rotate = IPU_ROTATE_NONE;
  216519. +
  216520. + if (var->xres_virtual < var->xres)
  216521. + var->xres_virtual = var->xres;
  216522. +
  216523. + if (var->yres_virtual < var->yres)
  216524. + var->yres_virtual = var->yres * 3;
  216525. +
  216526. + if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) &&
  216527. + (var->bits_per_pixel != 16) && (var->bits_per_pixel != 12) &&
  216528. + (var->bits_per_pixel != 8))
  216529. + var->bits_per_pixel = 16;
  216530. +
  216531. + if (check_var_pixfmt(var))
  216532. + /* Fall back to default */
  216533. + bpp_to_var(var->bits_per_pixel, var);
  216534. +
  216535. + if (var->pixclock < 1000) {
  216536. + htotal = var->xres + var->right_margin + var->hsync_len +
  216537. + var->left_margin;
  216538. + vtotal = var->yres + var->lower_margin + var->vsync_len +
  216539. + var->upper_margin;
  216540. + var->pixclock = (vtotal * htotal * 6UL) / 100UL;
  216541. + var->pixclock = KHZ2PICOS(var->pixclock);
  216542. + dev_dbg(info->device,
  216543. + "pixclock set for 60Hz refresh = %u ps\n",
  216544. + var->pixclock);
  216545. + }
  216546. +
  216547. + var->height = -1;
  216548. + var->width = -1;
  216549. + var->grayscale = 0;
  216550. +
  216551. + return 0;
  216552. +}
  216553. +
  216554. +static inline u_int _chan_to_field(u_int chan, struct fb_bitfield *bf)
  216555. +{
  216556. + chan &= 0xffff;
  216557. + chan >>= 16 - bf->length;
  216558. + return chan << bf->offset;
  216559. +}
  216560. +
  216561. +static int mxcfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
  216562. + u_int trans, struct fb_info *fbi)
  216563. +{
  216564. + unsigned int val;
  216565. + int ret = 1;
  216566. +
  216567. + /*
  216568. + * If greyscale is true, then we convert the RGB value
  216569. + * to greyscale no matter what visual we are using.
  216570. + */
  216571. + if (fbi->var.grayscale)
  216572. + red = green = blue = (19595 * red + 38470 * green +
  216573. + 7471 * blue) >> 16;
  216574. + switch (fbi->fix.visual) {
  216575. + case FB_VISUAL_TRUECOLOR:
  216576. + /*
  216577. + * 16-bit True Colour. We encode the RGB value
  216578. + * according to the RGB bitfield information.
  216579. + */
  216580. + if (regno < 16) {
  216581. + u32 *pal = fbi->pseudo_palette;
  216582. +
  216583. + val = _chan_to_field(red, &fbi->var.red);
  216584. + val |= _chan_to_field(green, &fbi->var.green);
  216585. + val |= _chan_to_field(blue, &fbi->var.blue);
  216586. +
  216587. + pal[regno] = val;
  216588. + ret = 0;
  216589. + }
  216590. + break;
  216591. +
  216592. + case FB_VISUAL_STATIC_PSEUDOCOLOR:
  216593. + case FB_VISUAL_PSEUDOCOLOR:
  216594. + break;
  216595. + }
  216596. +
  216597. + return ret;
  216598. +}
  216599. +
  216600. +/*
  216601. + * Function to handle custom ioctls for MXC framebuffer.
  216602. + *
  216603. + * @param inode inode struct
  216604. + *
  216605. + * @param file file struct
  216606. + *
  216607. + * @param cmd Ioctl command to handle
  216608. + *
  216609. + * @param arg User pointer to command arguments
  216610. + *
  216611. + * @param fbi framebuffer information pointer
  216612. + */
  216613. +static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
  216614. +{
  216615. + int retval = 0;
  216616. + int __user *argp = (void __user *)arg;
  216617. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  216618. +
  216619. + switch (cmd) {
  216620. + case MXCFB_SET_GBL_ALPHA:
  216621. + {
  216622. + struct mxcfb_gbl_alpha ga;
  216623. +
  216624. + if (copy_from_user(&ga, (void *)arg, sizeof(ga))) {
  216625. + retval = -EFAULT;
  216626. + break;
  216627. + }
  216628. +
  216629. + if (ipu_disp_set_global_alpha(mxc_fbi->ipu,
  216630. + mxc_fbi->ipu_ch,
  216631. + (bool)ga.enable,
  216632. + ga.alpha)) {
  216633. + retval = -EINVAL;
  216634. + break;
  216635. + }
  216636. +
  216637. + if (ga.enable)
  216638. + mxc_fbi->alpha_chan_en = false;
  216639. +
  216640. + if (ga.enable)
  216641. + dev_dbg(fbi->device,
  216642. + "Set global alpha of %s to %d\n",
  216643. + fbi->fix.id, ga.alpha);
  216644. + break;
  216645. + }
  216646. + case MXCFB_SET_LOC_ALPHA:
  216647. + {
  216648. + struct mxcfb_loc_alpha la;
  216649. + bool bad_pixfmt =
  216650. + ipu_ch_param_bad_alpha_pos(fbi_to_pixfmt(fbi));
  216651. +
  216652. + if (copy_from_user(&la, (void *)arg, sizeof(la))) {
  216653. + retval = -EFAULT;
  216654. + break;
  216655. + }
  216656. +
  216657. + if (la.enable && !la.alpha_in_pixel) {
  216658. + struct fb_info *fbi_tmp;
  216659. + ipu_channel_t ipu_ch;
  216660. +
  216661. + if (bad_pixfmt) {
  216662. + dev_err(fbi->device, "Bad pixel format "
  216663. + "for graphics plane fb\n");
  216664. + retval = -EINVAL;
  216665. + break;
  216666. + }
  216667. +
  216668. + mxc_fbi->alpha_chan_en = true;
  216669. +
  216670. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC)
  216671. + ipu_ch = MEM_BG_SYNC;
  216672. + else if (mxc_fbi->ipu_ch == MEM_BG_SYNC)
  216673. + ipu_ch = MEM_FG_SYNC;
  216674. + else {
  216675. + retval = -EINVAL;
  216676. + break;
  216677. + }
  216678. +
  216679. + fbi_tmp = found_registered_fb(ipu_ch, mxc_fbi->ipu_id);
  216680. + if (fbi_tmp)
  216681. + ((struct mxcfb_info *)(fbi_tmp->par))->alpha_chan_en = false;
  216682. + } else
  216683. + mxc_fbi->alpha_chan_en = false;
  216684. +
  216685. + if (ipu_disp_set_global_alpha(mxc_fbi->ipu,
  216686. + mxc_fbi->ipu_ch,
  216687. + !(bool)la.enable, 0)) {
  216688. + retval = -EINVAL;
  216689. + break;
  216690. + }
  216691. +
  216692. + fbi->var.activate = (fbi->var.activate & ~FB_ACTIVATE_MASK) |
  216693. + FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
  216694. + mxcfb_set_par(fbi);
  216695. +
  216696. + la.alpha_phy_addr0 = mxc_fbi->alpha_phy_addr0;
  216697. + la.alpha_phy_addr1 = mxc_fbi->alpha_phy_addr1;
  216698. + if (copy_to_user((void *)arg, &la, sizeof(la))) {
  216699. + retval = -EFAULT;
  216700. + break;
  216701. + }
  216702. +
  216703. + if (la.enable)
  216704. + dev_dbg(fbi->device,
  216705. + "Enable DP local alpha for %s\n",
  216706. + fbi->fix.id);
  216707. + break;
  216708. + }
  216709. + case MXCFB_SET_LOC_ALP_BUF:
  216710. + {
  216711. + unsigned long base;
  216712. + uint32_t ipu_alp_ch_irq;
  216713. +
  216714. + if (!(((mxc_fbi->ipu_ch == MEM_FG_SYNC) ||
  216715. + (mxc_fbi->ipu_ch == MEM_BG_SYNC)) &&
  216716. + (mxc_fbi->alpha_chan_en))) {
  216717. + dev_err(fbi->device,
  216718. + "Should use background or overlay "
  216719. + "framebuffer to set the alpha buffer "
  216720. + "number\n");
  216721. + return -EINVAL;
  216722. + }
  216723. +
  216724. + if (get_user(base, argp))
  216725. + return -EFAULT;
  216726. +
  216727. + if (base != mxc_fbi->alpha_phy_addr0 &&
  216728. + base != mxc_fbi->alpha_phy_addr1) {
  216729. + dev_err(fbi->device,
  216730. + "Wrong alpha buffer physical address "
  216731. + "%lu\n", base);
  216732. + return -EINVAL;
  216733. + }
  216734. +
  216735. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC)
  216736. + ipu_alp_ch_irq = IPU_IRQ_FG_ALPHA_SYNC_EOF;
  216737. + else
  216738. + ipu_alp_ch_irq = IPU_IRQ_BG_ALPHA_SYNC_EOF;
  216739. +
  216740. + retval = wait_for_completion_timeout(
  216741. + &mxc_fbi->alpha_flip_complete, HZ/2);
  216742. + if (retval == 0) {
  216743. + dev_err(fbi->device, "timeout when waiting for alpha flip irq\n");
  216744. + retval = -ETIMEDOUT;
  216745. + break;
  216746. + }
  216747. +
  216748. + mxc_fbi->cur_ipu_alpha_buf =
  216749. + !mxc_fbi->cur_ipu_alpha_buf;
  216750. + if (ipu_update_channel_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  216751. + IPU_ALPHA_IN_BUFFER,
  216752. + mxc_fbi->
  216753. + cur_ipu_alpha_buf,
  216754. + base) == 0) {
  216755. + ipu_select_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  216756. + IPU_ALPHA_IN_BUFFER,
  216757. + mxc_fbi->cur_ipu_alpha_buf);
  216758. + ipu_clear_irq(mxc_fbi->ipu, ipu_alp_ch_irq);
  216759. + ipu_enable_irq(mxc_fbi->ipu, ipu_alp_ch_irq);
  216760. + } else {
  216761. + dev_err(fbi->device,
  216762. + "Error updating %s SDC alpha buf %d "
  216763. + "to address=0x%08lX\n",
  216764. + fbi->fix.id,
  216765. + mxc_fbi->cur_ipu_alpha_buf, base);
  216766. + }
  216767. + break;
  216768. + }
  216769. + case MXCFB_SET_CLR_KEY:
  216770. + {
  216771. + struct mxcfb_color_key key;
  216772. + if (copy_from_user(&key, (void *)arg, sizeof(key))) {
  216773. + retval = -EFAULT;
  216774. + break;
  216775. + }
  216776. + retval = ipu_disp_set_color_key(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  216777. + key.enable,
  216778. + key.color_key);
  216779. + dev_dbg(fbi->device, "Set color key to 0x%08X\n",
  216780. + key.color_key);
  216781. + break;
  216782. + }
  216783. + case MXCFB_SET_GAMMA:
  216784. + {
  216785. + struct mxcfb_gamma gamma;
  216786. + if (copy_from_user(&gamma, (void *)arg, sizeof(gamma))) {
  216787. + retval = -EFAULT;
  216788. + break;
  216789. + }
  216790. + retval = ipu_disp_set_gamma_correction(mxc_fbi->ipu,
  216791. + mxc_fbi->ipu_ch,
  216792. + gamma.enable,
  216793. + gamma.constk,
  216794. + gamma.slopek);
  216795. + break;
  216796. + }
  216797. + case MXCFB_WAIT_FOR_VSYNC:
  216798. + {
  216799. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  216800. + /* BG should poweron */
  216801. + struct mxcfb_info *bg_mxcfbi = NULL;
  216802. + struct fb_info *fbi_tmp;
  216803. +
  216804. + fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  216805. + if (fbi_tmp)
  216806. + bg_mxcfbi = ((struct mxcfb_info *)(fbi_tmp->par));
  216807. +
  216808. + if (!bg_mxcfbi) {
  216809. + retval = -EINVAL;
  216810. + break;
  216811. + }
  216812. + if (bg_mxcfbi->cur_blank != FB_BLANK_UNBLANK) {
  216813. + retval = -EINVAL;
  216814. + break;
  216815. + }
  216816. + }
  216817. + if (mxc_fbi->cur_blank != FB_BLANK_UNBLANK) {
  216818. + retval = -EINVAL;
  216819. + break;
  216820. + }
  216821. +
  216822. + init_completion(&mxc_fbi->vsync_complete);
  216823. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  216824. + ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  216825. + retval = wait_for_completion_interruptible_timeout(
  216826. + &mxc_fbi->vsync_complete, 1 * HZ);
  216827. + if (retval == 0) {
  216828. + dev_err(fbi->device,
  216829. + "MXCFB_WAIT_FOR_VSYNC: timeout %d\n",
  216830. + retval);
  216831. + retval = -ETIME;
  216832. + } else if (retval > 0) {
  216833. + retval = 0;
  216834. + }
  216835. + break;
  216836. + }
  216837. + case FBIO_ALLOC:
  216838. + {
  216839. + int size;
  216840. + struct mxcfb_alloc_list *mem;
  216841. +
  216842. + mem = kzalloc(sizeof(*mem), GFP_KERNEL);
  216843. + if (mem == NULL)
  216844. + return -ENOMEM;
  216845. +
  216846. + if (get_user(size, argp))
  216847. + return -EFAULT;
  216848. +
  216849. + mem->size = PAGE_ALIGN(size);
  216850. +
  216851. + mem->cpu_addr = dma_alloc_coherent(fbi->device, size,
  216852. + &mem->phy_addr,
  216853. + GFP_KERNEL);
  216854. + if (mem->cpu_addr == NULL) {
  216855. + kfree(mem);
  216856. + return -ENOMEM;
  216857. + }
  216858. +
  216859. + list_add(&mem->list, &fb_alloc_list);
  216860. +
  216861. + dev_dbg(fbi->device, "allocated %d bytes @ 0x%08X\n",
  216862. + mem->size, mem->phy_addr);
  216863. +
  216864. + if (put_user(mem->phy_addr, argp))
  216865. + return -EFAULT;
  216866. +
  216867. + break;
  216868. + }
  216869. + case FBIO_FREE:
  216870. + {
  216871. + unsigned long offset;
  216872. + struct mxcfb_alloc_list *mem;
  216873. +
  216874. + if (get_user(offset, argp))
  216875. + return -EFAULT;
  216876. +
  216877. + retval = -EINVAL;
  216878. + list_for_each_entry(mem, &fb_alloc_list, list) {
  216879. + if (mem->phy_addr == offset) {
  216880. + list_del(&mem->list);
  216881. + dma_free_coherent(fbi->device,
  216882. + mem->size,
  216883. + mem->cpu_addr,
  216884. + mem->phy_addr);
  216885. + kfree(mem);
  216886. + retval = 0;
  216887. + break;
  216888. + }
  216889. + }
  216890. +
  216891. + break;
  216892. + }
  216893. + case MXCFB_SET_OVERLAY_POS:
  216894. + {
  216895. + struct mxcfb_pos pos;
  216896. + struct fb_info *bg_fbi = NULL;
  216897. + struct mxcfb_info *bg_mxcfbi = NULL;
  216898. +
  216899. + if (mxc_fbi->ipu_ch != MEM_FG_SYNC) {
  216900. + dev_err(fbi->device, "Should use the overlay "
  216901. + "framebuffer to set the position of "
  216902. + "the overlay window\n");
  216903. + retval = -EINVAL;
  216904. + break;
  216905. + }
  216906. +
  216907. + if (copy_from_user(&pos, (void *)arg, sizeof(pos))) {
  216908. + retval = -EFAULT;
  216909. + break;
  216910. + }
  216911. +
  216912. + bg_fbi = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  216913. + if (bg_fbi)
  216914. + bg_mxcfbi = ((struct mxcfb_info *)(bg_fbi->par));
  216915. +
  216916. + if (bg_fbi == NULL) {
  216917. + dev_err(fbi->device, "Cannot find the "
  216918. + "background framebuffer\n");
  216919. + retval = -ENOENT;
  216920. + break;
  216921. + }
  216922. +
  216923. + /* if fb is unblank, check if the pos fit the display */
  216924. + if (mxc_fbi->cur_blank == FB_BLANK_UNBLANK) {
  216925. + if (fbi->var.xres + pos.x > bg_fbi->var.xres) {
  216926. + if (bg_fbi->var.xres < fbi->var.xres)
  216927. + pos.x = 0;
  216928. + else
  216929. + pos.x = bg_fbi->var.xres - fbi->var.xres;
  216930. + }
  216931. + if (fbi->var.yres + pos.y > bg_fbi->var.yres) {
  216932. + if (bg_fbi->var.yres < fbi->var.yres)
  216933. + pos.y = 0;
  216934. + else
  216935. + pos.y = bg_fbi->var.yres - fbi->var.yres;
  216936. + }
  216937. + }
  216938. +
  216939. + retval = ipu_disp_set_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  216940. + pos.x, pos.y);
  216941. +
  216942. + if (copy_to_user((void *)arg, &pos, sizeof(pos))) {
  216943. + retval = -EFAULT;
  216944. + break;
  216945. + }
  216946. + break;
  216947. + }
  216948. + case MXCFB_GET_FB_IPU_CHAN:
  216949. + {
  216950. + struct mxcfb_info *mxc_fbi =
  216951. + (struct mxcfb_info *)fbi->par;
  216952. +
  216953. + if (put_user(mxc_fbi->ipu_ch, argp))
  216954. + return -EFAULT;
  216955. + break;
  216956. + }
  216957. + case MXCFB_GET_DIFMT:
  216958. + {
  216959. + struct mxcfb_info *mxc_fbi =
  216960. + (struct mxcfb_info *)fbi->par;
  216961. +
  216962. + if (put_user(mxc_fbi->ipu_di_pix_fmt, argp))
  216963. + return -EFAULT;
  216964. + break;
  216965. + }
  216966. + case MXCFB_GET_FB_IPU_DI:
  216967. + {
  216968. + struct mxcfb_info *mxc_fbi =
  216969. + (struct mxcfb_info *)fbi->par;
  216970. +
  216971. + if (put_user(mxc_fbi->ipu_di, argp))
  216972. + return -EFAULT;
  216973. + break;
  216974. + }
  216975. + case MXCFB_GET_FB_BLANK:
  216976. + {
  216977. + struct mxcfb_info *mxc_fbi =
  216978. + (struct mxcfb_info *)fbi->par;
  216979. +
  216980. + if (put_user(mxc_fbi->cur_blank, argp))
  216981. + return -EFAULT;
  216982. + break;
  216983. + }
  216984. + case MXCFB_SET_DIFMT:
  216985. + {
  216986. + struct mxcfb_info *mxc_fbi =
  216987. + (struct mxcfb_info *)fbi->par;
  216988. +
  216989. + if (get_user(mxc_fbi->ipu_di_pix_fmt, argp))
  216990. + return -EFAULT;
  216991. +
  216992. + break;
  216993. + }
  216994. + case MXCFB_CSC_UPDATE:
  216995. + {
  216996. + struct mxcfb_csc_matrix csc;
  216997. +
  216998. + if (copy_from_user(&csc, (void *) arg, sizeof(csc)))
  216999. + return -EFAULT;
  217000. +
  217001. + if ((mxc_fbi->ipu_ch != MEM_FG_SYNC) &&
  217002. + (mxc_fbi->ipu_ch != MEM_BG_SYNC) &&
  217003. + (mxc_fbi->ipu_ch != MEM_BG_ASYNC0))
  217004. + return -EFAULT;
  217005. + ipu_set_csc_coefficients(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  217006. + csc.param);
  217007. + }
  217008. + default:
  217009. + retval = -EINVAL;
  217010. + }
  217011. + return retval;
  217012. +}
  217013. +
  217014. +/*
  217015. + * mxcfb_blank():
  217016. + * Blank the display.
  217017. + */
  217018. +static int mxcfb_blank(int blank, struct fb_info *info)
  217019. +{
  217020. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par;
  217021. + int ret = 0;
  217022. +
  217023. + dev_dbg(info->device, "blank = %d\n", blank);
  217024. +
  217025. + if (mxc_fbi->cur_blank == blank)
  217026. + return 0;
  217027. +
  217028. + mxc_fbi->next_blank = blank;
  217029. +
  217030. + switch (blank) {
  217031. + case FB_BLANK_POWERDOWN:
  217032. + case FB_BLANK_VSYNC_SUSPEND:
  217033. + case FB_BLANK_HSYNC_SUSPEND:
  217034. + case FB_BLANK_NORMAL:
  217035. + if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->disable)
  217036. + mxc_fbi->dispdrv->drv->disable(mxc_fbi->dispdrv);
  217037. + ipu_disable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, true);
  217038. + if (mxc_fbi->ipu_di >= 0)
  217039. + ipu_uninit_sync_panel(mxc_fbi->ipu, mxc_fbi->ipu_di);
  217040. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  217041. + break;
  217042. + case FB_BLANK_UNBLANK:
  217043. + info->var.activate = (info->var.activate & ~FB_ACTIVATE_MASK) |
  217044. + FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
  217045. + ret = mxcfb_set_par(info);
  217046. + break;
  217047. + }
  217048. + if (!ret)
  217049. + mxc_fbi->cur_blank = blank;
  217050. + return ret;
  217051. +}
  217052. +
  217053. +/*
  217054. + * Pan or Wrap the Display
  217055. + *
  217056. + * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
  217057. + *
  217058. + * @param var Variable screen buffer information
  217059. + * @param info Framebuffer information pointer
  217060. + */
  217061. +static int
  217062. +mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
  217063. +{
  217064. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par,
  217065. + *mxc_graphic_fbi = NULL;
  217066. + u_int y_bottom;
  217067. + unsigned int fr_xoff, fr_yoff, fr_w, fr_h;
  217068. + unsigned long base, active_alpha_phy_addr = 0;
  217069. + bool loc_alpha_en = false;
  217070. + int fb_stride;
  217071. + int i;
  217072. + int ret;
  217073. +
  217074. + /* no pan display during fb blank */
  217075. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  217076. + struct mxcfb_info *bg_mxcfbi = NULL;
  217077. + struct fb_info *fbi_tmp;
  217078. +
  217079. + fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  217080. + if (fbi_tmp)
  217081. + bg_mxcfbi = ((struct mxcfb_info *)(fbi_tmp->par));
  217082. + if (!bg_mxcfbi)
  217083. + return -EINVAL;
  217084. + if (bg_mxcfbi->cur_blank != FB_BLANK_UNBLANK)
  217085. + return -EINVAL;
  217086. + }
  217087. + if (mxc_fbi->cur_blank != FB_BLANK_UNBLANK)
  217088. + return -EINVAL;
  217089. +
  217090. + y_bottom = var->yoffset;
  217091. +
  217092. + if (y_bottom > info->var.yres_virtual)
  217093. + return -EINVAL;
  217094. +
  217095. + switch (fbi_to_pixfmt(info)) {
  217096. + case IPU_PIX_FMT_YUV420P2:
  217097. + case IPU_PIX_FMT_YVU420P:
  217098. + case IPU_PIX_FMT_NV12:
  217099. + case IPU_PIX_FMT_YUV422P:
  217100. + case IPU_PIX_FMT_YVU422P:
  217101. + case IPU_PIX_FMT_YUV420P:
  217102. + case IPU_PIX_FMT_YUV444P:
  217103. + fb_stride = info->var.xres_virtual;
  217104. + break;
  217105. + default:
  217106. + fb_stride = info->fix.line_length;
  217107. + }
  217108. +
  217109. + base = info->fix.smem_start;
  217110. + fr_xoff = var->xoffset;
  217111. + fr_w = info->var.xres_virtual;
  217112. + if (!(var->vmode & FB_VMODE_YWRAP)) {
  217113. + dev_dbg(info->device, "Y wrap disabled\n");
  217114. + fr_yoff = var->yoffset % info->var.yres;
  217115. + fr_h = info->var.yres;
  217116. + base += info->fix.line_length * info->var.yres *
  217117. + (var->yoffset / info->var.yres);
  217118. + } else {
  217119. + dev_dbg(info->device, "Y wrap enabled\n");
  217120. + fr_yoff = var->yoffset;
  217121. + fr_h = info->var.yres_virtual;
  217122. + }
  217123. + base += fr_yoff * fb_stride + fr_xoff;
  217124. +
  217125. + /* Check if DP local alpha is enabled and find the graphic fb */
  217126. + if (mxc_fbi->ipu_ch == MEM_BG_SYNC || mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  217127. + for (i = 0; i < num_registered_fb; i++) {
  217128. + char bg_id[] = "DISP3 BG";
  217129. + char fg_id[] = "DISP3 FG";
  217130. + char *idstr = registered_fb[i]->fix.id;
  217131. + bg_id[4] += mxc_fbi->ipu_id;
  217132. + fg_id[4] += mxc_fbi->ipu_id;
  217133. + if ((strcmp(idstr, bg_id) == 0 ||
  217134. + strcmp(idstr, fg_id) == 0) &&
  217135. + ((struct mxcfb_info *)
  217136. + (registered_fb[i]->par))->alpha_chan_en) {
  217137. + loc_alpha_en = true;
  217138. + mxc_graphic_fbi = (struct mxcfb_info *)
  217139. + (registered_fb[i]->par);
  217140. + active_alpha_phy_addr =
  217141. + mxc_fbi->cur_ipu_alpha_buf ?
  217142. + mxc_graphic_fbi->alpha_phy_addr1 :
  217143. + mxc_graphic_fbi->alpha_phy_addr0;
  217144. + dev_dbg(info->device, "Updating SDC alpha "
  217145. + "buf %d address=0x%08lX\n",
  217146. + !mxc_fbi->cur_ipu_alpha_buf,
  217147. + active_alpha_phy_addr);
  217148. + break;
  217149. + }
  217150. + }
  217151. + }
  217152. +
  217153. + ret = wait_for_completion_timeout(&mxc_fbi->flip_complete, HZ/2);
  217154. + if (ret == 0) {
  217155. + dev_err(info->device, "timeout when waiting for flip irq\n");
  217156. + return -ETIMEDOUT;
  217157. + }
  217158. +
  217159. + ++mxc_fbi->cur_ipu_buf;
  217160. + mxc_fbi->cur_ipu_buf %= 3;
  217161. + mxc_fbi->cur_ipu_alpha_buf = !mxc_fbi->cur_ipu_alpha_buf;
  217162. +
  217163. + dev_dbg(info->device, "Updating SDC %s buf %d address=0x%08lX\n",
  217164. + info->fix.id, mxc_fbi->cur_ipu_buf, base);
  217165. +
  217166. + if (ipu_update_channel_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
  217167. + mxc_fbi->cur_ipu_buf, base) == 0) {
  217168. + /* Update the DP local alpha buffer only for graphic plane */
  217169. + if (loc_alpha_en && mxc_graphic_fbi == mxc_fbi &&
  217170. + ipu_update_channel_buffer(mxc_graphic_fbi->ipu, mxc_graphic_fbi->ipu_ch,
  217171. + IPU_ALPHA_IN_BUFFER,
  217172. + mxc_fbi->cur_ipu_alpha_buf,
  217173. + active_alpha_phy_addr) == 0) {
  217174. + ipu_select_buffer(mxc_graphic_fbi->ipu, mxc_graphic_fbi->ipu_ch,
  217175. + IPU_ALPHA_IN_BUFFER,
  217176. + mxc_fbi->cur_ipu_alpha_buf);
  217177. + }
  217178. +
  217179. + /* update u/v offset */
  217180. + ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  217181. + IPU_INPUT_BUFFER,
  217182. + fbi_to_pixfmt(info),
  217183. + fr_w,
  217184. + fr_h,
  217185. + fr_w,
  217186. + 0, 0,
  217187. + fr_yoff,
  217188. + fr_xoff);
  217189. +
  217190. + ipu_select_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
  217191. + mxc_fbi->cur_ipu_buf);
  217192. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  217193. + ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  217194. + } else {
  217195. + dev_err(info->device,
  217196. + "Error updating SDC buf %d to address=0x%08lX, "
  217197. + "current buf %d, buf0 ready %d, buf1 ready %d, "
  217198. + "buf2 ready %d\n", mxc_fbi->cur_ipu_buf, base,
  217199. + ipu_get_cur_buffer_idx(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  217200. + IPU_INPUT_BUFFER),
  217201. + ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  217202. + IPU_INPUT_BUFFER, 0),
  217203. + ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  217204. + IPU_INPUT_BUFFER, 1),
  217205. + ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  217206. + IPU_INPUT_BUFFER, 2));
  217207. + ++mxc_fbi->cur_ipu_buf;
  217208. + mxc_fbi->cur_ipu_buf %= 3;
  217209. + ++mxc_fbi->cur_ipu_buf;
  217210. + mxc_fbi->cur_ipu_buf %= 3;
  217211. + mxc_fbi->cur_ipu_alpha_buf = !mxc_fbi->cur_ipu_alpha_buf;
  217212. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  217213. + ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  217214. + return -EBUSY;
  217215. + }
  217216. +
  217217. + dev_dbg(info->device, "Update complete\n");
  217218. +
  217219. + info->var.yoffset = var->yoffset;
  217220. +
  217221. + return 0;
  217222. +}
  217223. +
  217224. +/*
  217225. + * Function to handle custom mmap for MXC framebuffer.
  217226. + *
  217227. + * @param fbi framebuffer information pointer
  217228. + *
  217229. + * @param vma Pointer to vm_area_struct
  217230. + */
  217231. +static int mxcfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
  217232. +{
  217233. + bool found = false;
  217234. + u32 len;
  217235. + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  217236. + struct mxcfb_alloc_list *mem;
  217237. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  217238. +
  217239. + if (offset < fbi->fix.smem_len) {
  217240. + /* mapping framebuffer memory */
  217241. + len = fbi->fix.smem_len - offset;
  217242. + vma->vm_pgoff = (fbi->fix.smem_start + offset) >> PAGE_SHIFT;
  217243. + } else if ((vma->vm_pgoff ==
  217244. + (mxc_fbi->alpha_phy_addr0 >> PAGE_SHIFT)) ||
  217245. + (vma->vm_pgoff ==
  217246. + (mxc_fbi->alpha_phy_addr1 >> PAGE_SHIFT))) {
  217247. + len = mxc_fbi->alpha_mem_len;
  217248. + } else {
  217249. + list_for_each_entry(mem, &fb_alloc_list, list) {
  217250. + if (offset == mem->phy_addr) {
  217251. + found = true;
  217252. + len = mem->size;
  217253. + break;
  217254. + }
  217255. + }
  217256. + if (!found)
  217257. + return -EINVAL;
  217258. + }
  217259. +
  217260. + len = PAGE_ALIGN(len);
  217261. + if (vma->vm_end - vma->vm_start > len)
  217262. + return -EINVAL;
  217263. +
  217264. + /* make buffers bufferable */
  217265. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  217266. +
  217267. + vma->vm_flags |= VM_IO;
  217268. +
  217269. + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  217270. + vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
  217271. + dev_dbg(fbi->device, "mmap remap_pfn_range failed\n");
  217272. + return -ENOBUFS;
  217273. + }
  217274. +
  217275. + return 0;
  217276. +}
  217277. +
  217278. +/*!
  217279. + * This structure contains the pointers to the control functions that are
  217280. + * invoked by the core framebuffer driver to perform operations like
  217281. + * blitting, rectangle filling, copy regions and cursor definition.
  217282. + */
  217283. +static struct fb_ops mxcfb_ops = {
  217284. + .owner = THIS_MODULE,
  217285. + .fb_set_par = mxcfb_set_par,
  217286. + .fb_check_var = mxcfb_check_var,
  217287. + .fb_setcolreg = mxcfb_setcolreg,
  217288. + .fb_pan_display = mxcfb_pan_display,
  217289. + .fb_ioctl = mxcfb_ioctl,
  217290. + .fb_mmap = mxcfb_mmap,
  217291. + .fb_fillrect = cfb_fillrect,
  217292. + .fb_copyarea = cfb_copyarea,
  217293. + .fb_imageblit = cfb_imageblit,
  217294. + .fb_blank = mxcfb_blank,
  217295. +};
  217296. +
  217297. +static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id)
  217298. +{
  217299. + struct fb_info *fbi = dev_id;
  217300. + struct mxcfb_info *mxc_fbi = fbi->par;
  217301. +
  217302. + complete(&mxc_fbi->flip_complete);
  217303. + return IRQ_HANDLED;
  217304. +}
  217305. +
  217306. +static irqreturn_t mxcfb_nf_irq_handler(int irq, void *dev_id)
  217307. +{
  217308. + struct fb_info *fbi = dev_id;
  217309. + struct mxcfb_info *mxc_fbi = fbi->par;
  217310. +
  217311. + complete(&mxc_fbi->vsync_complete);
  217312. + return IRQ_HANDLED;
  217313. +}
  217314. +
  217315. +static irqreturn_t mxcfb_alpha_irq_handler(int irq, void *dev_id)
  217316. +{
  217317. + struct fb_info *fbi = dev_id;
  217318. + struct mxcfb_info *mxc_fbi = fbi->par;
  217319. +
  217320. + complete(&mxc_fbi->alpha_flip_complete);
  217321. + return IRQ_HANDLED;
  217322. +}
  217323. +
  217324. +/*
  217325. + * Suspends the framebuffer and blanks the screen. Power management support
  217326. + */
  217327. +static int mxcfb_suspend(struct platform_device *pdev, pm_message_t state)
  217328. +{
  217329. + struct fb_info *fbi = platform_get_drvdata(pdev);
  217330. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  217331. + int saved_blank;
  217332. +#ifdef CONFIG_FB_MXC_LOW_PWR_DISPLAY
  217333. + void *fbmem;
  217334. +#endif
  217335. +
  217336. + if (mxc_fbi->ovfbi) {
  217337. + struct mxcfb_info *mxc_fbi_fg =
  217338. + (struct mxcfb_info *)mxc_fbi->ovfbi->par;
  217339. +
  217340. + console_lock();
  217341. + fb_set_suspend(mxc_fbi->ovfbi, 1);
  217342. + saved_blank = mxc_fbi_fg->cur_blank;
  217343. + mxcfb_blank(FB_BLANK_POWERDOWN, mxc_fbi->ovfbi);
  217344. + mxc_fbi_fg->next_blank = saved_blank;
  217345. + console_unlock();
  217346. + }
  217347. +
  217348. + console_lock();
  217349. + fb_set_suspend(fbi, 1);
  217350. + saved_blank = mxc_fbi->cur_blank;
  217351. + mxcfb_blank(FB_BLANK_POWERDOWN, fbi);
  217352. + mxc_fbi->next_blank = saved_blank;
  217353. + console_unlock();
  217354. +
  217355. + return 0;
  217356. +}
  217357. +
  217358. +/*
  217359. + * Resumes the framebuffer and unblanks the screen. Power management support
  217360. + */
  217361. +static int mxcfb_resume(struct platform_device *pdev)
  217362. +{
  217363. + struct fb_info *fbi = platform_get_drvdata(pdev);
  217364. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  217365. +
  217366. + console_lock();
  217367. + mxcfb_blank(mxc_fbi->next_blank, fbi);
  217368. + fb_set_suspend(fbi, 0);
  217369. + console_unlock();
  217370. +
  217371. + if (mxc_fbi->ovfbi) {
  217372. + struct mxcfb_info *mxc_fbi_fg =
  217373. + (struct mxcfb_info *)mxc_fbi->ovfbi->par;
  217374. + console_lock();
  217375. + mxcfb_blank(mxc_fbi_fg->next_blank, mxc_fbi->ovfbi);
  217376. + fb_set_suspend(mxc_fbi->ovfbi, 0);
  217377. + console_unlock();
  217378. + }
  217379. +
  217380. + return 0;
  217381. +}
  217382. +
  217383. +/*
  217384. + * Main framebuffer functions
  217385. + */
  217386. +
  217387. +/*!
  217388. + * Allocates the DRAM memory for the frame buffer. This buffer is remapped
  217389. + * into a non-cached, non-buffered, memory region to allow palette and pixel
  217390. + * writes to occur without flushing the cache. Once this area is remapped,
  217391. + * all virtual memory access to the video memory should occur at the new region.
  217392. + *
  217393. + * @param fbi framebuffer information pointer
  217394. + *
  217395. + * @return Error code indicating success or failure
  217396. + */
  217397. +static int mxcfb_map_video_memory(struct fb_info *fbi)
  217398. +{
  217399. + if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length)
  217400. + fbi->fix.smem_len = fbi->var.yres_virtual *
  217401. + fbi->fix.line_length;
  217402. +
  217403. + fbi->screen_base = dma_alloc_writecombine(fbi->device,
  217404. + fbi->fix.smem_len,
  217405. + (dma_addr_t *)&fbi->fix.smem_start,
  217406. + GFP_DMA | GFP_KERNEL);
  217407. + if (fbi->screen_base == 0) {
  217408. + dev_err(fbi->device, "Unable to allocate framebuffer memory\n");
  217409. + fbi->fix.smem_len = 0;
  217410. + fbi->fix.smem_start = 0;
  217411. + return -EBUSY;
  217412. + }
  217413. +
  217414. + dev_dbg(fbi->device, "allocated fb @ paddr=0x%08X, size=%d.\n",
  217415. + (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
  217416. +
  217417. + fbi->screen_size = fbi->fix.smem_len;
  217418. +
  217419. + /* Clear the screen */
  217420. + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
  217421. +
  217422. + return 0;
  217423. +}
  217424. +
  217425. +/*!
  217426. + * De-allocates the DRAM memory for the frame buffer.
  217427. + *
  217428. + * @param fbi framebuffer information pointer
  217429. + *
  217430. + * @return Error code indicating success or failure
  217431. + */
  217432. +static int mxcfb_unmap_video_memory(struct fb_info *fbi)
  217433. +{
  217434. + dma_free_writecombine(fbi->device, fbi->fix.smem_len,
  217435. + fbi->screen_base, fbi->fix.smem_start);
  217436. + fbi->screen_base = 0;
  217437. + fbi->fix.smem_start = 0;
  217438. + fbi->fix.smem_len = 0;
  217439. + return 0;
  217440. +}
  217441. +
  217442. +/*!
  217443. + * Initializes the framebuffer information pointer. After allocating
  217444. + * sufficient memory for the framebuffer structure, the fields are
  217445. + * filled with custom information passed in from the configurable
  217446. + * structures. This includes information such as bits per pixel,
  217447. + * color maps, screen width/height and RGBA offsets.
  217448. + *
  217449. + * @return Framebuffer structure initialized with our information
  217450. + */
  217451. +static struct fb_info *mxcfb_init_fbinfo(struct device *dev, struct fb_ops *ops)
  217452. +{
  217453. + struct fb_info *fbi;
  217454. + struct mxcfb_info *mxcfbi;
  217455. +
  217456. + /*
  217457. + * Allocate sufficient memory for the fb structure
  217458. + */
  217459. + fbi = framebuffer_alloc(sizeof(struct mxcfb_info), dev);
  217460. + if (!fbi)
  217461. + return NULL;
  217462. +
  217463. + mxcfbi = (struct mxcfb_info *)fbi->par;
  217464. +
  217465. + fbi->var.activate = FB_ACTIVATE_NOW;
  217466. +
  217467. + fbi->fbops = ops;
  217468. + fbi->flags = FBINFO_FLAG_DEFAULT;
  217469. + fbi->pseudo_palette = mxcfbi->pseudo_palette;
  217470. +
  217471. + /*
  217472. + * Allocate colormap
  217473. + */
  217474. + fb_alloc_cmap(&fbi->cmap, 16, 0);
  217475. +
  217476. + return fbi;
  217477. +}
  217478. +
  217479. +static ssize_t show_disp_chan(struct device *dev,
  217480. + struct device_attribute *attr, char *buf)
  217481. +{
  217482. + struct fb_info *info = dev_get_drvdata(dev);
  217483. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
  217484. +
  217485. + if (mxcfbi->ipu_ch == MEM_BG_SYNC)
  217486. + return sprintf(buf, "2-layer-fb-bg\n");
  217487. + else if (mxcfbi->ipu_ch == MEM_FG_SYNC)
  217488. + return sprintf(buf, "2-layer-fb-fg\n");
  217489. + else if (mxcfbi->ipu_ch == MEM_DC_SYNC)
  217490. + return sprintf(buf, "1-layer-fb\n");
  217491. + else
  217492. + return sprintf(buf, "err: no display chan\n");
  217493. +}
  217494. +
  217495. +static ssize_t swap_disp_chan(struct device *dev,
  217496. + struct device_attribute *attr,
  217497. + const char *buf, size_t count)
  217498. +{
  217499. + struct fb_info *info = dev_get_drvdata(dev);
  217500. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
  217501. + struct mxcfb_info *fg_mxcfbi = NULL;
  217502. +
  217503. + console_lock();
  217504. + /* swap only happen between DP-BG and DC, while DP-FG disable */
  217505. + if (((mxcfbi->ipu_ch == MEM_BG_SYNC) &&
  217506. + (strstr(buf, "1-layer-fb") != NULL)) ||
  217507. + ((mxcfbi->ipu_ch == MEM_DC_SYNC) &&
  217508. + (strstr(buf, "2-layer-fb-bg") != NULL))) {
  217509. + struct fb_info *fbi_fg;
  217510. +
  217511. + fbi_fg = found_registered_fb(MEM_FG_SYNC, mxcfbi->ipu_id);
  217512. + if (fbi_fg)
  217513. + fg_mxcfbi = (struct mxcfb_info *)fbi_fg->par;
  217514. +
  217515. + if (!fg_mxcfbi ||
  217516. + fg_mxcfbi->cur_blank == FB_BLANK_UNBLANK) {
  217517. + dev_err(dev,
  217518. + "Can not switch while fb2(fb-fg) is on.\n");
  217519. + console_unlock();
  217520. + return count;
  217521. + }
  217522. +
  217523. + if (swap_channels(info) < 0)
  217524. + dev_err(dev, "Swap display channel failed.\n");
  217525. + }
  217526. +
  217527. + console_unlock();
  217528. + return count;
  217529. +}
  217530. +static DEVICE_ATTR(fsl_disp_property, S_IWUSR | S_IRUGO,
  217531. + show_disp_chan, swap_disp_chan);
  217532. +
  217533. +static ssize_t show_disp_dev(struct device *dev,
  217534. + struct device_attribute *attr, char *buf)
  217535. +{
  217536. + struct fb_info *info = dev_get_drvdata(dev);
  217537. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
  217538. +
  217539. + if (mxcfbi->ipu_ch == MEM_FG_SYNC)
  217540. + return sprintf(buf, "overlay\n");
  217541. + else
  217542. + return sprintf(buf, "%s\n", mxcfbi->dispdrv->drv->name);
  217543. +}
  217544. +static DEVICE_ATTR(fsl_disp_dev_property, S_IRUGO, show_disp_dev, NULL);
  217545. +
  217546. +static int mxcfb_dispdrv_init(struct platform_device *pdev,
  217547. + struct fb_info *fbi)
  217548. +{
  217549. + struct ipuv3_fb_platform_data *plat_data = pdev->dev.platform_data;
  217550. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
  217551. + struct mxc_dispdrv_setting setting;
  217552. + char disp_dev[32], *default_dev = "lcd";
  217553. + int ret = 0;
  217554. +
  217555. + setting.if_fmt = plat_data->interface_pix_fmt;
  217556. + setting.dft_mode_str = plat_data->mode_str;
  217557. + setting.default_bpp = plat_data->default_bpp;
  217558. + if (!setting.default_bpp)
  217559. + setting.default_bpp = 16;
  217560. + setting.fbi = fbi;
  217561. + if (!strlen(plat_data->disp_dev)) {
  217562. + memcpy(disp_dev, default_dev, strlen(default_dev));
  217563. + disp_dev[strlen(default_dev)] = '\0';
  217564. + } else {
  217565. + memcpy(disp_dev, plat_data->disp_dev,
  217566. + strlen(plat_data->disp_dev));
  217567. + disp_dev[strlen(plat_data->disp_dev)] = '\0';
  217568. + }
  217569. +
  217570. + dev_info(&pdev->dev, "register mxc display driver %s\n", disp_dev);
  217571. +
  217572. + mxcfbi->dispdrv = mxc_dispdrv_gethandle(disp_dev, &setting);
  217573. + if (IS_ERR(mxcfbi->dispdrv)) {
  217574. + ret = PTR_ERR(mxcfbi->dispdrv);
  217575. + dev_err(&pdev->dev, "NO mxc display driver found!\n");
  217576. + return ret;
  217577. + } else {
  217578. + /* fix-up */
  217579. + mxcfbi->ipu_di_pix_fmt = setting.if_fmt;
  217580. + mxcfbi->default_bpp = setting.default_bpp;
  217581. +
  217582. + /* setting */
  217583. + mxcfbi->ipu_id = setting.dev_id;
  217584. + mxcfbi->ipu_di = setting.disp_id;
  217585. + dev_dbg(&pdev->dev, "di_pixfmt:0x%x, bpp:0x%x, di:%d, ipu:%d\n",
  217586. + setting.if_fmt, setting.default_bpp,
  217587. + setting.disp_id, setting.dev_id);
  217588. + }
  217589. +
  217590. + return ret;
  217591. +}
  217592. +
  217593. +/*
  217594. + * Parse user specified options (`video=trident:')
  217595. + * example:
  217596. + * video=mxcfb0:dev=lcd,800x480M-16@55,if=RGB565,bpp=16,noaccel
  217597. + * video=mxcfb0:dev=lcd,800x480M-16@55,if=RGB565,fbpix=RGB565
  217598. + */
  217599. +static int mxcfb_option_setup(struct platform_device *pdev, struct fb_info *fbi)
  217600. +{
  217601. + struct ipuv3_fb_platform_data *pdata = pdev->dev.platform_data;
  217602. + char *options, *opt, *fb_mode_str = NULL;
  217603. + char name[] = "mxcfb0";
  217604. + uint32_t fb_pix_fmt = 0;
  217605. +
  217606. + name[5] += pdev->id;
  217607. + if (fb_get_options(name, &options)) {
  217608. + dev_err(&pdev->dev, "Can't get fb option for %s!\n", name);
  217609. + return -ENODEV;
  217610. + }
  217611. +
  217612. + if (!options || !*options)
  217613. + return 0;
  217614. +
  217615. + while ((opt = strsep(&options, ",")) != NULL) {
  217616. + if (!*opt)
  217617. + continue;
  217618. +
  217619. + if (!strncmp(opt, "dev=", 4)) {
  217620. + memcpy(pdata->disp_dev, opt + 4, strlen(opt) - 4);
  217621. + pdata->disp_dev[strlen(opt) - 4] = '\0';
  217622. + } else if (!strncmp(opt, "if=", 3)) {
  217623. + if (!strncmp(opt+3, "RGB24", 5))
  217624. + pdata->interface_pix_fmt = IPU_PIX_FMT_RGB24;
  217625. + else if (!strncmp(opt+3, "BGR24", 5))
  217626. + pdata->interface_pix_fmt = IPU_PIX_FMT_BGR24;
  217627. + else if (!strncmp(opt+3, "GBR24", 5))
  217628. + pdata->interface_pix_fmt = IPU_PIX_FMT_GBR24;
  217629. + else if (!strncmp(opt+3, "RGB565", 6))
  217630. + pdata->interface_pix_fmt = IPU_PIX_FMT_RGB565;
  217631. + else if (!strncmp(opt+3, "RGB666", 6))
  217632. + pdata->interface_pix_fmt = IPU_PIX_FMT_RGB666;
  217633. + else if (!strncmp(opt+3, "YUV444", 6))
  217634. + pdata->interface_pix_fmt = IPU_PIX_FMT_YUV444;
  217635. + else if (!strncmp(opt+3, "LVDS666", 7))
  217636. + pdata->interface_pix_fmt = IPU_PIX_FMT_LVDS666;
  217637. + else if (!strncmp(opt+3, "YUYV16", 6))
  217638. + pdata->interface_pix_fmt = IPU_PIX_FMT_YUYV;
  217639. + else if (!strncmp(opt+3, "UYVY16", 6))
  217640. + pdata->interface_pix_fmt = IPU_PIX_FMT_UYVY;
  217641. + else if (!strncmp(opt+3, "YVYU16", 6))
  217642. + pdata->interface_pix_fmt = IPU_PIX_FMT_YVYU;
  217643. + else if (!strncmp(opt+3, "VYUY16", 6))
  217644. + pdata->interface_pix_fmt = IPU_PIX_FMT_VYUY;
  217645. + } else if (!strncmp(opt, "fbpix=", 6)) {
  217646. + if (!strncmp(opt+6, "RGB24", 5))
  217647. + fb_pix_fmt = IPU_PIX_FMT_RGB24;
  217648. + else if (!strncmp(opt+6, "BGR24", 5))
  217649. + fb_pix_fmt = IPU_PIX_FMT_BGR24;
  217650. + else if (!strncmp(opt+6, "RGB32", 5))
  217651. + fb_pix_fmt = IPU_PIX_FMT_RGB32;
  217652. + else if (!strncmp(opt+6, "BGR32", 5))
  217653. + fb_pix_fmt = IPU_PIX_FMT_BGR32;
  217654. + else if (!strncmp(opt+6, "ABGR32", 6))
  217655. + fb_pix_fmt = IPU_PIX_FMT_ABGR32;
  217656. + else if (!strncmp(opt+6, "RGB565", 6))
  217657. + fb_pix_fmt = IPU_PIX_FMT_RGB565;
  217658. +
  217659. + if (fb_pix_fmt) {
  217660. + pixfmt_to_var(fb_pix_fmt, &fbi->var);
  217661. + pdata->default_bpp =
  217662. + fbi->var.bits_per_pixel;
  217663. + }
  217664. + } else if (!strncmp(opt, "int_clk", 7)) {
  217665. + pdata->int_clk = true;
  217666. + continue;
  217667. + } else if (!strncmp(opt, "bpp=", 4)) {
  217668. + /* bpp setting cannot overwirte fbpix setting */
  217669. + if (fb_pix_fmt)
  217670. + continue;
  217671. +
  217672. + pdata->default_bpp =
  217673. + simple_strtoul(opt + 4, NULL, 0);
  217674. +
  217675. + fb_pix_fmt = bpp_to_pixfmt(pdata->default_bpp);
  217676. + if (fb_pix_fmt)
  217677. + pixfmt_to_var(fb_pix_fmt, &fbi->var);
  217678. + } else
  217679. + fb_mode_str = opt;
  217680. + }
  217681. +
  217682. + if (fb_mode_str)
  217683. + pdata->mode_str = fb_mode_str;
  217684. +
  217685. + return 0;
  217686. +}
  217687. +
  217688. +static int mxcfb_register(struct fb_info *fbi)
  217689. +{
  217690. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
  217691. + struct fb_videomode m;
  217692. + int ret = 0;
  217693. + char bg0_id[] = "DISP3 BG";
  217694. + char bg1_id[] = "DISP3 BG - DI1";
  217695. + char fg_id[] = "DISP3 FG";
  217696. +
  217697. + if (mxcfbi->ipu_di == 0) {
  217698. + bg0_id[4] += mxcfbi->ipu_id;
  217699. + strcpy(fbi->fix.id, bg0_id);
  217700. + } else if (mxcfbi->ipu_di == 1) {
  217701. + bg1_id[4] += mxcfbi->ipu_id;
  217702. + strcpy(fbi->fix.id, bg1_id);
  217703. + } else { /* Overlay */
  217704. + fg_id[4] += mxcfbi->ipu_id;
  217705. + strcpy(fbi->fix.id, fg_id);
  217706. + }
  217707. +
  217708. + mxcfb_check_var(&fbi->var, fbi);
  217709. +
  217710. + mxcfb_set_fix(fbi);
  217711. +
  217712. + /* Added first mode to fbi modelist. */
  217713. + if (!fbi->modelist.next || !fbi->modelist.prev)
  217714. + INIT_LIST_HEAD(&fbi->modelist);
  217715. + fb_var_to_videomode(&m, &fbi->var);
  217716. + fb_add_videomode(&m, &fbi->modelist);
  217717. +
  217718. + if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq,
  217719. + mxcfb_irq_handler, IPU_IRQF_ONESHOT, MXCFB_NAME, fbi) != 0) {
  217720. + dev_err(fbi->device, "Error registering EOF irq handler.\n");
  217721. + ret = -EBUSY;
  217722. + goto err0;
  217723. + }
  217724. + ipu_disable_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq);
  217725. + if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq,
  217726. + mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT, MXCFB_NAME, fbi) != 0) {
  217727. + dev_err(fbi->device, "Error registering NFACK irq handler.\n");
  217728. + ret = -EBUSY;
  217729. + goto err1;
  217730. + }
  217731. + ipu_disable_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq);
  217732. +
  217733. + if (mxcfbi->ipu_alp_ch_irq != -1)
  217734. + if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq,
  217735. + mxcfb_alpha_irq_handler, IPU_IRQF_ONESHOT,
  217736. + MXCFB_NAME, fbi) != 0) {
  217737. + dev_err(fbi->device, "Error registering alpha irq "
  217738. + "handler.\n");
  217739. + ret = -EBUSY;
  217740. + goto err2;
  217741. + }
  217742. +
  217743. + if (!mxcfbi->late_init) {
  217744. + fbi->var.activate |= FB_ACTIVATE_FORCE;
  217745. + console_lock();
  217746. + fbi->flags |= FBINFO_MISC_USEREVENT;
  217747. + ret = fb_set_var(fbi, &fbi->var);
  217748. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  217749. + console_unlock();
  217750. + if (ret < 0) {
  217751. + dev_err(fbi->device, "Error fb_set_var ret:%d\n", ret);
  217752. + goto err3;
  217753. + }
  217754. +
  217755. + if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
  217756. + console_lock();
  217757. + ret = fb_blank(fbi, FB_BLANK_UNBLANK);
  217758. + console_unlock();
  217759. + if (ret < 0) {
  217760. + dev_err(fbi->device,
  217761. + "Error fb_blank ret:%d\n", ret);
  217762. + goto err4;
  217763. + }
  217764. + }
  217765. + } else {
  217766. + /*
  217767. + * Setup the channel again though bootloader
  217768. + * has done this, then set_par() can stop the
  217769. + * channel neatly and re-initialize it .
  217770. + */
  217771. + if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
  217772. + console_lock();
  217773. + _setup_disp_channel1(fbi);
  217774. + ipu_enable_channel(mxcfbi->ipu, mxcfbi->ipu_ch);
  217775. + console_unlock();
  217776. + }
  217777. + }
  217778. +
  217779. +
  217780. + ret = register_framebuffer(fbi);
  217781. + if (ret < 0)
  217782. + goto err5;
  217783. +
  217784. + return ret;
  217785. +err5:
  217786. + if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
  217787. + console_lock();
  217788. + if (!mxcfbi->late_init)
  217789. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  217790. + else {
  217791. + ipu_disable_channel(mxcfbi->ipu, mxcfbi->ipu_ch,
  217792. + true);
  217793. + ipu_uninit_channel(mxcfbi->ipu, mxcfbi->ipu_ch);
  217794. + }
  217795. + console_unlock();
  217796. + }
  217797. +err4:
  217798. +err3:
  217799. + if (mxcfbi->ipu_alp_ch_irq != -1)
  217800. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq, fbi);
  217801. +err2:
  217802. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq, fbi);
  217803. +err1:
  217804. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq, fbi);
  217805. +err0:
  217806. + return ret;
  217807. +}
  217808. +
  217809. +static void mxcfb_unregister(struct fb_info *fbi)
  217810. +{
  217811. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
  217812. +
  217813. + if (mxcfbi->ipu_alp_ch_irq != -1)
  217814. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq, fbi);
  217815. + if (mxcfbi->ipu_ch_irq)
  217816. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq, fbi);
  217817. + if (mxcfbi->ipu_ch_nf_irq)
  217818. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq, fbi);
  217819. +
  217820. + unregister_framebuffer(fbi);
  217821. +}
  217822. +
  217823. +static int mxcfb_setup_overlay(struct platform_device *pdev,
  217824. + struct fb_info *fbi_bg, struct resource *res)
  217825. +{
  217826. + struct fb_info *ovfbi;
  217827. + struct mxcfb_info *mxcfbi_bg = (struct mxcfb_info *)fbi_bg->par;
  217828. + struct mxcfb_info *mxcfbi_fg;
  217829. + int ret = 0;
  217830. +
  217831. + ovfbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops);
  217832. + if (!ovfbi) {
  217833. + ret = -ENOMEM;
  217834. + goto init_ovfbinfo_failed;
  217835. + }
  217836. + mxcfbi_fg = (struct mxcfb_info *)ovfbi->par;
  217837. +
  217838. + mxcfbi_fg->ipu = ipu_get_soc(mxcfbi_bg->ipu_id);
  217839. + if (IS_ERR(mxcfbi_fg->ipu)) {
  217840. + ret = -ENODEV;
  217841. + goto get_ipu_failed;
  217842. + }
  217843. + mxcfbi_fg->ipu_id = mxcfbi_bg->ipu_id;
  217844. + mxcfbi_fg->ipu_ch_irq = IPU_IRQ_FG_SYNC_EOF;
  217845. + mxcfbi_fg->ipu_ch_nf_irq = IPU_IRQ_FG_SYNC_NFACK;
  217846. + mxcfbi_fg->ipu_alp_ch_irq = IPU_IRQ_FG_ALPHA_SYNC_EOF;
  217847. + mxcfbi_fg->ipu_ch = MEM_FG_SYNC;
  217848. + mxcfbi_fg->ipu_di = -1;
  217849. + mxcfbi_fg->ipu_di_pix_fmt = mxcfbi_bg->ipu_di_pix_fmt;
  217850. + mxcfbi_fg->overlay = true;
  217851. + mxcfbi_fg->cur_blank = mxcfbi_fg->next_blank = FB_BLANK_POWERDOWN;
  217852. +
  217853. + /* Need dummy values until real panel is configured */
  217854. + ovfbi->var.xres = 240;
  217855. + ovfbi->var.yres = 320;
  217856. +
  217857. + if (res && res->start && res->end) {
  217858. + ovfbi->fix.smem_len = res->end - res->start + 1;
  217859. + ovfbi->fix.smem_start = res->start;
  217860. + ovfbi->screen_base = ioremap(
  217861. + ovfbi->fix.smem_start,
  217862. + ovfbi->fix.smem_len);
  217863. + }
  217864. +
  217865. + ret = mxcfb_register(ovfbi);
  217866. + if (ret < 0)
  217867. + goto register_ov_failed;
  217868. +
  217869. + mxcfbi_bg->ovfbi = ovfbi;
  217870. +
  217871. + return ret;
  217872. +
  217873. +register_ov_failed:
  217874. +get_ipu_failed:
  217875. + fb_dealloc_cmap(&ovfbi->cmap);
  217876. + framebuffer_release(ovfbi);
  217877. +init_ovfbinfo_failed:
  217878. + return ret;
  217879. +}
  217880. +
  217881. +static void mxcfb_unsetup_overlay(struct fb_info *fbi_bg)
  217882. +{
  217883. + struct mxcfb_info *mxcfbi_bg = (struct mxcfb_info *)fbi_bg->par;
  217884. + struct fb_info *ovfbi = mxcfbi_bg->ovfbi;
  217885. +
  217886. + mxcfb_unregister(ovfbi);
  217887. +
  217888. + if (&ovfbi->cmap)
  217889. + fb_dealloc_cmap(&ovfbi->cmap);
  217890. + framebuffer_release(ovfbi);
  217891. +}
  217892. +
  217893. +static bool ipu_usage[2][2];
  217894. +static int ipu_test_set_usage(int ipu, int di)
  217895. +{
  217896. + if (ipu_usage[ipu][di])
  217897. + return -EBUSY;
  217898. + else
  217899. + ipu_usage[ipu][di] = true;
  217900. + return 0;
  217901. +}
  217902. +
  217903. +static void ipu_clear_usage(int ipu, int di)
  217904. +{
  217905. + ipu_usage[ipu][di] = false;
  217906. +}
  217907. +
  217908. +static int mxcfb_get_of_property(struct platform_device *pdev,
  217909. + struct ipuv3_fb_platform_data *plat_data)
  217910. +{
  217911. + struct device_node *np = pdev->dev.of_node;
  217912. + const char *disp_dev;
  217913. + const char *mode_str;
  217914. + const char *pixfmt;
  217915. + int err;
  217916. + int len;
  217917. + u32 bpp, int_clk;
  217918. + u32 late_init;
  217919. +
  217920. + err = of_property_read_string(np, "disp_dev", &disp_dev);
  217921. + if (err < 0) {
  217922. + dev_dbg(&pdev->dev, "get of property disp_dev fail\n");
  217923. + return err;
  217924. + }
  217925. + err = of_property_read_string(np, "mode_str", &mode_str);
  217926. + if (err < 0) {
  217927. + dev_dbg(&pdev->dev, "get of property mode_str fail\n");
  217928. + return err;
  217929. + }
  217930. + err = of_property_read_string(np, "interface_pix_fmt", &pixfmt);
  217931. + if (err) {
  217932. + dev_dbg(&pdev->dev, "get of property pix fmt fail\n");
  217933. + return err;
  217934. + }
  217935. + err = of_property_read_u32(np, "default_bpp", &bpp);
  217936. + if (err) {
  217937. + dev_dbg(&pdev->dev, "get of property bpp fail\n");
  217938. + return err;
  217939. + }
  217940. + err = of_property_read_u32(np, "int_clk", &int_clk);
  217941. + if (err) {
  217942. + dev_dbg(&pdev->dev, "get of property int_clk fail\n");
  217943. + return err;
  217944. + }
  217945. + err = of_property_read_u32(np, "late_init", &late_init);
  217946. + if (err) {
  217947. + dev_dbg(&pdev->dev, "get of property late_init fail\n");
  217948. + return err;
  217949. + }
  217950. +
  217951. + if (!strncmp(pixfmt, "RGB24", 5))
  217952. + plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB24;
  217953. + else if (!strncmp(pixfmt, "BGR24", 5))
  217954. + plat_data->interface_pix_fmt = IPU_PIX_FMT_BGR24;
  217955. + else if (!strncmp(pixfmt, "GBR24", 5))
  217956. + plat_data->interface_pix_fmt = IPU_PIX_FMT_GBR24;
  217957. + else if (!strncmp(pixfmt, "RGB565", 6))
  217958. + plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB565;
  217959. + else if (!strncmp(pixfmt, "RGB666", 6))
  217960. + plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB666;
  217961. + else if (!strncmp(pixfmt, "YUV444", 6))
  217962. + plat_data->interface_pix_fmt = IPU_PIX_FMT_YUV444;
  217963. + else if (!strncmp(pixfmt, "LVDS666", 7))
  217964. + plat_data->interface_pix_fmt = IPU_PIX_FMT_LVDS666;
  217965. + else if (!strncmp(pixfmt, "YUYV16", 6))
  217966. + plat_data->interface_pix_fmt = IPU_PIX_FMT_YUYV;
  217967. + else if (!strncmp(pixfmt, "UYVY16", 6))
  217968. + plat_data->interface_pix_fmt = IPU_PIX_FMT_UYVY;
  217969. + else if (!strncmp(pixfmt, "YVYU16", 6))
  217970. + plat_data->interface_pix_fmt = IPU_PIX_FMT_YVYU;
  217971. + else if (!strncmp(pixfmt, "VYUY16", 6))
  217972. + plat_data->interface_pix_fmt = IPU_PIX_FMT_VYUY;
  217973. + else {
  217974. + dev_err(&pdev->dev, "err interface_pix_fmt!\n");
  217975. + return -ENOENT;
  217976. + }
  217977. +
  217978. + len = min(sizeof(plat_data->disp_dev) - 1, strlen(disp_dev));
  217979. + memcpy(plat_data->disp_dev, disp_dev, len);
  217980. + plat_data->disp_dev[len] = '\0';
  217981. + plat_data->mode_str = (char *)mode_str;
  217982. + plat_data->default_bpp = bpp;
  217983. + plat_data->int_clk = (bool)int_clk;
  217984. + plat_data->late_init = (bool)late_init;
  217985. + return err;
  217986. +}
  217987. +
  217988. +/*!
  217989. + * Probe routine for the framebuffer driver. It is called during the
  217990. + * driver binding process. The following functions are performed in
  217991. + * this routine: Framebuffer initialization, Memory allocation and
  217992. + * mapping, Framebuffer registration, IPU initialization.
  217993. + *
  217994. + * @return Appropriate error code to the kernel common code
  217995. + */
  217996. +static int mxcfb_probe(struct platform_device *pdev)
  217997. +{
  217998. + struct ipuv3_fb_platform_data *plat_data;
  217999. + struct fb_info *fbi;
  218000. + struct mxcfb_info *mxcfbi;
  218001. + struct resource *res;
  218002. + int ret = 0;
  218003. +
  218004. + dev_dbg(&pdev->dev, "%s enter\n", __func__);
  218005. + pdev->id = of_alias_get_id(pdev->dev.of_node, "mxcfb");
  218006. + if (pdev->id < 0) {
  218007. + dev_err(&pdev->dev, "can not get alias id\n");
  218008. + return pdev->id;
  218009. + }
  218010. +
  218011. + plat_data = devm_kzalloc(&pdev->dev, sizeof(struct
  218012. + ipuv3_fb_platform_data), GFP_KERNEL);
  218013. + if (!plat_data)
  218014. + return -ENOMEM;
  218015. + pdev->dev.platform_data = plat_data;
  218016. +
  218017. + ret = mxcfb_get_of_property(pdev, plat_data);
  218018. + if (ret < 0) {
  218019. + dev_err(&pdev->dev, "get mxcfb of property fail\n");
  218020. + return ret;
  218021. + }
  218022. +
  218023. + /* Initialize FB structures */
  218024. + fbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops);
  218025. + if (!fbi) {
  218026. + ret = -ENOMEM;
  218027. + goto init_fbinfo_failed;
  218028. + }
  218029. +
  218030. + ret = mxcfb_option_setup(pdev, fbi);
  218031. + if (ret)
  218032. + goto get_fb_option_failed;
  218033. +
  218034. + mxcfbi = (struct mxcfb_info *)fbi->par;
  218035. + mxcfbi->ipu_int_clk = plat_data->int_clk;
  218036. + mxcfbi->late_init = plat_data->late_init;
  218037. + mxcfbi->first_set_par = true;
  218038. + ret = mxcfb_dispdrv_init(pdev, fbi);
  218039. + if (ret < 0)
  218040. + goto init_dispdrv_failed;
  218041. +
  218042. + ret = ipu_test_set_usage(mxcfbi->ipu_id, mxcfbi->ipu_di);
  218043. + if (ret < 0) {
  218044. + dev_err(&pdev->dev, "ipu%d-di%d already in use\n",
  218045. + mxcfbi->ipu_id, mxcfbi->ipu_di);
  218046. + goto ipu_in_busy;
  218047. + }
  218048. +
  218049. + if (mxcfbi->dispdrv->drv->post_init) {
  218050. + ret = mxcfbi->dispdrv->drv->post_init(mxcfbi->dispdrv,
  218051. + mxcfbi->ipu_id,
  218052. + mxcfbi->ipu_di);
  218053. + if (ret < 0) {
  218054. + dev_err(&pdev->dev, "post init failed\n");
  218055. + goto post_init_failed;
  218056. + }
  218057. + }
  218058. +
  218059. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  218060. + if (res && res->start && res->end) {
  218061. + fbi->fix.smem_len = res->end - res->start + 1;
  218062. + fbi->fix.smem_start = res->start;
  218063. + fbi->screen_base = ioremap(fbi->fix.smem_start, fbi->fix.smem_len);
  218064. + /* Do not clear the fb content drawn in bootloader. */
  218065. + if (!mxcfbi->late_init)
  218066. + memset(fbi->screen_base, 0, fbi->fix.smem_len);
  218067. + }
  218068. +
  218069. + mxcfbi->ipu = ipu_get_soc(mxcfbi->ipu_id);
  218070. + if (IS_ERR(mxcfbi->ipu)) {
  218071. + ret = -ENODEV;
  218072. + goto get_ipu_failed;
  218073. + }
  218074. +
  218075. + /* first user uses DP with alpha feature */
  218076. + if (!g_dp_in_use[mxcfbi->ipu_id]) {
  218077. + mxcfbi->ipu_ch_irq = IPU_IRQ_BG_SYNC_EOF;
  218078. + mxcfbi->ipu_ch_nf_irq = IPU_IRQ_BG_SYNC_NFACK;
  218079. + mxcfbi->ipu_alp_ch_irq = IPU_IRQ_BG_ALPHA_SYNC_EOF;
  218080. + mxcfbi->ipu_ch = MEM_BG_SYNC;
  218081. + /* Unblank the primary fb only by default */
  218082. + if (pdev->id == 0)
  218083. + mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_UNBLANK;
  218084. + else
  218085. + mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
  218086. +
  218087. + ret = mxcfb_register(fbi);
  218088. + if (ret < 0)
  218089. + goto mxcfb_register_failed;
  218090. +
  218091. + ipu_disp_set_global_alpha(mxcfbi->ipu, mxcfbi->ipu_ch,
  218092. + true, 0x80);
  218093. + ipu_disp_set_color_key(mxcfbi->ipu, mxcfbi->ipu_ch, false, 0);
  218094. +
  218095. + res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  218096. + ret = mxcfb_setup_overlay(pdev, fbi, res);
  218097. +
  218098. + if (ret < 0) {
  218099. + mxcfb_unregister(fbi);
  218100. + goto mxcfb_setupoverlay_failed;
  218101. + }
  218102. +
  218103. + g_dp_in_use[mxcfbi->ipu_id] = true;
  218104. +
  218105. + ret = device_create_file(mxcfbi->ovfbi->dev,
  218106. + &dev_attr_fsl_disp_property);
  218107. + if (ret)
  218108. + dev_err(mxcfbi->ovfbi->dev, "Error %d on creating "
  218109. + "file for disp property\n",
  218110. + ret);
  218111. +
  218112. + ret = device_create_file(mxcfbi->ovfbi->dev,
  218113. + &dev_attr_fsl_disp_dev_property);
  218114. + if (ret)
  218115. + dev_err(mxcfbi->ovfbi->dev, "Error %d on creating "
  218116. + "file for disp device "
  218117. + "propety\n", ret);
  218118. + } else {
  218119. + mxcfbi->ipu_ch_irq = IPU_IRQ_DC_SYNC_EOF;
  218120. + mxcfbi->ipu_ch_nf_irq = IPU_IRQ_DC_SYNC_NFACK;
  218121. + mxcfbi->ipu_alp_ch_irq = -1;
  218122. + mxcfbi->ipu_ch = MEM_DC_SYNC;
  218123. + mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
  218124. +
  218125. + ret = mxcfb_register(fbi);
  218126. + if (ret < 0)
  218127. + goto mxcfb_register_failed;
  218128. + }
  218129. +
  218130. + platform_set_drvdata(pdev, fbi);
  218131. +
  218132. + ret = device_create_file(fbi->dev, &dev_attr_fsl_disp_property);
  218133. + if (ret)
  218134. + dev_err(&pdev->dev, "Error %d on creating file for disp "
  218135. + "property\n", ret);
  218136. +
  218137. + ret = device_create_file(fbi->dev, &dev_attr_fsl_disp_dev_property);
  218138. + if (ret)
  218139. + dev_err(&pdev->dev, "Error %d on creating file for disp "
  218140. + " device propety\n", ret);
  218141. +
  218142. + return 0;
  218143. +
  218144. +mxcfb_setupoverlay_failed:
  218145. +mxcfb_register_failed:
  218146. +get_ipu_failed:
  218147. +post_init_failed:
  218148. + ipu_clear_usage(mxcfbi->ipu_id, mxcfbi->ipu_di);
  218149. +ipu_in_busy:
  218150. +init_dispdrv_failed:
  218151. + fb_dealloc_cmap(&fbi->cmap);
  218152. + framebuffer_release(fbi);
  218153. +get_fb_option_failed:
  218154. +init_fbinfo_failed:
  218155. + return ret;
  218156. +}
  218157. +
  218158. +static int mxcfb_remove(struct platform_device *pdev)
  218159. +{
  218160. + struct fb_info *fbi = platform_get_drvdata(pdev);
  218161. + struct mxcfb_info *mxc_fbi = fbi->par;
  218162. +
  218163. + if (!fbi)
  218164. + return 0;
  218165. +
  218166. + device_remove_file(fbi->dev, &dev_attr_fsl_disp_dev_property);
  218167. + device_remove_file(fbi->dev, &dev_attr_fsl_disp_property);
  218168. + mxcfb_blank(FB_BLANK_POWERDOWN, fbi);
  218169. + mxcfb_unregister(fbi);
  218170. + mxcfb_unmap_video_memory(fbi);
  218171. +
  218172. + if (mxc_fbi->ovfbi) {
  218173. + device_remove_file(mxc_fbi->ovfbi->dev,
  218174. + &dev_attr_fsl_disp_dev_property);
  218175. + device_remove_file(mxc_fbi->ovfbi->dev,
  218176. + &dev_attr_fsl_disp_property);
  218177. + mxcfb_blank(FB_BLANK_POWERDOWN, mxc_fbi->ovfbi);
  218178. + mxcfb_unsetup_overlay(fbi);
  218179. + mxcfb_unmap_video_memory(mxc_fbi->ovfbi);
  218180. + }
  218181. +
  218182. + ipu_clear_usage(mxc_fbi->ipu_id, mxc_fbi->ipu_di);
  218183. + if (&fbi->cmap)
  218184. + fb_dealloc_cmap(&fbi->cmap);
  218185. + framebuffer_release(fbi);
  218186. + return 0;
  218187. +}
  218188. +
  218189. +static const struct of_device_id imx_mxcfb_dt_ids[] = {
  218190. + { .compatible = "fsl,mxc_sdc_fb"},
  218191. + { /* sentinel */ }
  218192. +};
  218193. +
  218194. +/*!
  218195. + * This structure contains pointers to the power management callback functions.
  218196. + */
  218197. +static struct platform_driver mxcfb_driver = {
  218198. + .driver = {
  218199. + .name = MXCFB_NAME,
  218200. + .of_match_table = imx_mxcfb_dt_ids,
  218201. + },
  218202. + .probe = mxcfb_probe,
  218203. + .remove = mxcfb_remove,
  218204. + .suspend = mxcfb_suspend,
  218205. + .resume = mxcfb_resume,
  218206. +};
  218207. +
  218208. +/*!
  218209. + * Main entry function for the framebuffer. The function registers the power
  218210. + * management callback functions with the kernel and also registers the MXCFB
  218211. + * callback functions with the core Linux framebuffer driver \b fbmem.c
  218212. + *
  218213. + * @return Error code indicating success or failure
  218214. + */
  218215. +int __init mxcfb_init(void)
  218216. +{
  218217. + return platform_driver_register(&mxcfb_driver);
  218218. +}
  218219. +
  218220. +void mxcfb_exit(void)
  218221. +{
  218222. + platform_driver_unregister(&mxcfb_driver);
  218223. +}
  218224. +
  218225. +module_init(mxcfb_init);
  218226. +module_exit(mxcfb_exit);
  218227. +
  218228. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  218229. +MODULE_DESCRIPTION("MXC framebuffer driver");
  218230. +MODULE_LICENSE("GPL");
  218231. +MODULE_SUPPORTED_DEVICE("fb");
  218232. diff -Nur linux-3.14.15/drivers/video/mxc/mxc_lcdif.c linux-linaro-stable-mx6/drivers/video/mxc/mxc_lcdif.c
  218233. --- linux-3.14.15/drivers/video/mxc/mxc_lcdif.c 1970-01-01 01:00:00.000000000 +0100
  218234. +++ linux-linaro-stable-mx6/drivers/video/mxc/mxc_lcdif.c 2014-08-20 19:23:58.566867220 +0200
  218235. @@ -0,0 +1,235 @@
  218236. +/*
  218237. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  218238. + */
  218239. +
  218240. +/*
  218241. + * The code contained herein is licensed under the GNU General Public
  218242. + * License. You may obtain a copy of the GNU General Public License
  218243. + * Version 2 or later at the following locations:
  218244. + *
  218245. + * http://www.opensource.org/licenses/gpl-license.html
  218246. + * http://www.gnu.org/copyleft/gpl.html
  218247. + */
  218248. +
  218249. +#include <linux/init.h>
  218250. +#include <linux/ipu.h>
  218251. +#include <linux/kernel.h>
  218252. +#include <linux/module.h>
  218253. +#include <linux/mxcfb.h>
  218254. +#include <linux/of_device.h>
  218255. +#include <linux/pinctrl/consumer.h>
  218256. +#include <linux/platform_device.h>
  218257. +
  218258. +#include "mxc_dispdrv.h"
  218259. +
  218260. +struct mxc_lcd_platform_data {
  218261. + u32 default_ifmt;
  218262. + u32 ipu_id;
  218263. + u32 disp_id;
  218264. +};
  218265. +
  218266. +struct mxc_lcdif_data {
  218267. + struct platform_device *pdev;
  218268. + struct mxc_dispdrv_handle *disp_lcdif;
  218269. +};
  218270. +
  218271. +#define DISPDRV_LCD "lcd"
  218272. +
  218273. +static struct fb_videomode lcdif_modedb[] = {
  218274. + {
  218275. + /* 800x480 @ 57 Hz , pixel clk @ 27MHz */
  218276. + "CLAA-WVGA", 57, 800, 480, 37037, 40, 60, 10, 10, 20, 10,
  218277. + FB_SYNC_CLK_LAT_FALL,
  218278. + FB_VMODE_NONINTERLACED,
  218279. + 0,},
  218280. + {
  218281. + /* 800x480 @ 60 Hz , pixel clk @ 32MHz */
  218282. + "SEIKO-WVGA", 60, 800, 480, 29850, 89, 164, 23, 10, 10, 10,
  218283. + FB_SYNC_CLK_LAT_FALL,
  218284. + FB_VMODE_NONINTERLACED,
  218285. + 0,},
  218286. +};
  218287. +static int lcdif_modedb_sz = ARRAY_SIZE(lcdif_modedb);
  218288. +
  218289. +static int lcdif_init(struct mxc_dispdrv_handle *disp,
  218290. + struct mxc_dispdrv_setting *setting)
  218291. +{
  218292. + int ret, i;
  218293. + struct mxc_lcdif_data *lcdif = mxc_dispdrv_getdata(disp);
  218294. + struct mxc_lcd_platform_data *plat_data
  218295. + = lcdif->pdev->dev.platform_data;
  218296. + struct fb_videomode *modedb = lcdif_modedb;
  218297. + int modedb_sz = lcdif_modedb_sz;
  218298. +
  218299. + /* use platform defined ipu/di */
  218300. + setting->dev_id = plat_data->ipu_id;
  218301. + setting->disp_id = plat_data->disp_id;
  218302. +
  218303. + ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str,
  218304. + modedb, modedb_sz, NULL, setting->default_bpp);
  218305. + if (!ret) {
  218306. + fb_videomode_to_var(&setting->fbi->var, &modedb[0]);
  218307. + setting->if_fmt = plat_data->default_ifmt;
  218308. + }
  218309. +
  218310. + INIT_LIST_HEAD(&setting->fbi->modelist);
  218311. + for (i = 0; i < modedb_sz; i++) {
  218312. + struct fb_videomode m;
  218313. + fb_var_to_videomode(&m, &setting->fbi->var);
  218314. + if (fb_mode_is_equal(&m, &modedb[i])) {
  218315. + fb_add_videomode(&modedb[i],
  218316. + &setting->fbi->modelist);
  218317. + break;
  218318. + }
  218319. + }
  218320. +
  218321. + return ret;
  218322. +}
  218323. +
  218324. +void lcdif_deinit(struct mxc_dispdrv_handle *disp)
  218325. +{
  218326. + /*TODO*/
  218327. +}
  218328. +
  218329. +static struct mxc_dispdrv_driver lcdif_drv = {
  218330. + .name = DISPDRV_LCD,
  218331. + .init = lcdif_init,
  218332. + .deinit = lcdif_deinit,
  218333. +};
  218334. +
  218335. +static int lcd_get_of_property(struct platform_device *pdev,
  218336. + struct mxc_lcd_platform_data *plat_data)
  218337. +{
  218338. + struct device_node *np = pdev->dev.of_node;
  218339. + int err;
  218340. + u32 ipu_id, disp_id;
  218341. + const char *default_ifmt;
  218342. +
  218343. + err = of_property_read_string(np, "default_ifmt", &default_ifmt);
  218344. + if (err) {
  218345. + dev_dbg(&pdev->dev, "get of property default_ifmt fail\n");
  218346. + return err;
  218347. + }
  218348. + err = of_property_read_u32(np, "ipu_id", &ipu_id);
  218349. + if (err) {
  218350. + dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
  218351. + return err;
  218352. + }
  218353. + err = of_property_read_u32(np, "disp_id", &disp_id);
  218354. + if (err) {
  218355. + dev_dbg(&pdev->dev, "get of property disp_id fail\n");
  218356. + return err;
  218357. + }
  218358. +
  218359. + plat_data->ipu_id = ipu_id;
  218360. + plat_data->disp_id = disp_id;
  218361. + if (!strncmp(default_ifmt, "RGB24", 5))
  218362. + plat_data->default_ifmt = IPU_PIX_FMT_RGB24;
  218363. + else if (!strncmp(default_ifmt, "BGR24", 5))
  218364. + plat_data->default_ifmt = IPU_PIX_FMT_BGR24;
  218365. + else if (!strncmp(default_ifmt, "GBR24", 5))
  218366. + plat_data->default_ifmt = IPU_PIX_FMT_GBR24;
  218367. + else if (!strncmp(default_ifmt, "RGB565", 6))
  218368. + plat_data->default_ifmt = IPU_PIX_FMT_RGB565;
  218369. + else if (!strncmp(default_ifmt, "RGB666", 6))
  218370. + plat_data->default_ifmt = IPU_PIX_FMT_RGB666;
  218371. + else if (!strncmp(default_ifmt, "YUV444", 6))
  218372. + plat_data->default_ifmt = IPU_PIX_FMT_YUV444;
  218373. + else if (!strncmp(default_ifmt, "LVDS666", 7))
  218374. + plat_data->default_ifmt = IPU_PIX_FMT_LVDS666;
  218375. + else if (!strncmp(default_ifmt, "YUYV16", 6))
  218376. + plat_data->default_ifmt = IPU_PIX_FMT_YUYV;
  218377. + else if (!strncmp(default_ifmt, "UYVY16", 6))
  218378. + plat_data->default_ifmt = IPU_PIX_FMT_UYVY;
  218379. + else if (!strncmp(default_ifmt, "YVYU16", 6))
  218380. + plat_data->default_ifmt = IPU_PIX_FMT_YVYU;
  218381. + else if (!strncmp(default_ifmt, "VYUY16", 6))
  218382. + plat_data->default_ifmt = IPU_PIX_FMT_VYUY;
  218383. + else {
  218384. + dev_err(&pdev->dev, "err default_ifmt!\n");
  218385. + return -ENOENT;
  218386. + }
  218387. +
  218388. + return err;
  218389. +}
  218390. +
  218391. +static int mxc_lcdif_probe(struct platform_device *pdev)
  218392. +{
  218393. + int ret;
  218394. + struct pinctrl *pinctrl;
  218395. + struct mxc_lcdif_data *lcdif;
  218396. + struct mxc_lcd_platform_data *plat_data;
  218397. +
  218398. + dev_dbg(&pdev->dev, "%s enter\n", __func__);
  218399. + lcdif = devm_kzalloc(&pdev->dev, sizeof(struct mxc_lcdif_data),
  218400. + GFP_KERNEL);
  218401. + if (!lcdif)
  218402. + return -ENOMEM;
  218403. + plat_data = devm_kzalloc(&pdev->dev,
  218404. + sizeof(struct mxc_lcd_platform_data),
  218405. + GFP_KERNEL);
  218406. + if (!plat_data)
  218407. + return -ENOMEM;
  218408. + pdev->dev.platform_data = plat_data;
  218409. +
  218410. + ret = lcd_get_of_property(pdev, plat_data);
  218411. + if (ret < 0) {
  218412. + dev_err(&pdev->dev, "get lcd of property fail\n");
  218413. + return ret;
  218414. + }
  218415. +
  218416. + pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
  218417. + if (IS_ERR(pinctrl)) {
  218418. + dev_err(&pdev->dev, "can't get/select pinctrl\n");
  218419. + return PTR_ERR(pinctrl);
  218420. + }
  218421. +
  218422. + lcdif->pdev = pdev;
  218423. + lcdif->disp_lcdif = mxc_dispdrv_register(&lcdif_drv);
  218424. + mxc_dispdrv_setdata(lcdif->disp_lcdif, lcdif);
  218425. +
  218426. + dev_set_drvdata(&pdev->dev, lcdif);
  218427. + dev_dbg(&pdev->dev, "%s exit\n", __func__);
  218428. +
  218429. + return ret;
  218430. +}
  218431. +
  218432. +static int mxc_lcdif_remove(struct platform_device *pdev)
  218433. +{
  218434. + struct mxc_lcdif_data *lcdif = dev_get_drvdata(&pdev->dev);
  218435. +
  218436. + mxc_dispdrv_puthandle(lcdif->disp_lcdif);
  218437. + mxc_dispdrv_unregister(lcdif->disp_lcdif);
  218438. + kfree(lcdif);
  218439. + return 0;
  218440. +}
  218441. +
  218442. +static const struct of_device_id imx_lcd_dt_ids[] = {
  218443. + { .compatible = "fsl,lcd"},
  218444. + { /* sentinel */ }
  218445. +};
  218446. +static struct platform_driver mxc_lcdif_driver = {
  218447. + .driver = {
  218448. + .name = "mxc_lcdif",
  218449. + .of_match_table = imx_lcd_dt_ids,
  218450. + },
  218451. + .probe = mxc_lcdif_probe,
  218452. + .remove = mxc_lcdif_remove,
  218453. +};
  218454. +
  218455. +static int __init mxc_lcdif_init(void)
  218456. +{
  218457. + return platform_driver_register(&mxc_lcdif_driver);
  218458. +}
  218459. +
  218460. +static void __exit mxc_lcdif_exit(void)
  218461. +{
  218462. + platform_driver_unregister(&mxc_lcdif_driver);
  218463. +}
  218464. +
  218465. +module_init(mxc_lcdif_init);
  218466. +module_exit(mxc_lcdif_exit);
  218467. +
  218468. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  218469. +MODULE_DESCRIPTION("i.MX ipuv3 LCD extern port driver");
  218470. +MODULE_LICENSE("GPL");
  218471. diff -Nur linux-3.14.15/drivers/video/mxsfb.c linux-linaro-stable-mx6/drivers/video/mxsfb.c
  218472. --- linux-3.14.15/drivers/video/mxsfb.c 2014-07-31 23:51:43.000000000 +0200
  218473. +++ linux-linaro-stable-mx6/drivers/video/mxsfb.c 2014-08-20 19:31:50.020885713 +0200
  218474. @@ -96,9 +96,10 @@
  218475. #define CTRL_DF24 (1 << 1)
  218476. #define CTRL_RUN (1 << 0)
  218477. -#define CTRL1_FIFO_CLEAR (1 << 21)
  218478. -#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
  218479. -#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
  218480. +#define CTRL1_RECOVERY_ON_UNDERFLOW (1 << 24)
  218481. +#define CTRL1_FIFO_CLEAR (1 << 21)
  218482. +#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
  218483. +#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
  218484. #define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16)
  218485. #define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff)
  218486. @@ -149,8 +150,8 @@
  218487. #define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
  218488. #define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
  218489. -#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
  218490. -#define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negtive edge sampling */
  218491. +#define FB_SYNC_OE_LOW_ACT 0x80000000
  218492. +#define FB_SYNC_CLK_LAT_FALL 0x40000000
  218493. enum mxsfb_devtype {
  218494. MXSFB_V3,
  218495. @@ -178,7 +179,6 @@
  218496. unsigned ld_intf_width;
  218497. unsigned dotclk_delay;
  218498. const struct mxsfb_devdata *devdata;
  218499. - u32 sync;
  218500. struct regulator *reg_lcd;
  218501. };
  218502. @@ -275,9 +275,15 @@
  218503. if (var->yres < MIN_YRES)
  218504. var->yres = MIN_YRES;
  218505. - var->xres_virtual = var->xres;
  218506. + if (var->xres_virtual > var->xres) {
  218507. + dev_dbg(fb_info->device, "stride not supported\n");
  218508. + return -EINVAL;
  218509. + }
  218510. - var->yres_virtual = var->yres;
  218511. + if (var->xres_virtual < var->xres)
  218512. + var->xres_virtual = var->xres;
  218513. + if (var->yres_virtual < var->yres)
  218514. + var->yres_virtual = var->yres;
  218515. switch (var->bits_per_pixel) {
  218516. case 16:
  218517. @@ -344,6 +350,9 @@
  218518. writel(CTRL_RUN, host->base + LCDC_CTRL + REG_SET);
  218519. + /* Recovery on underflow */
  218520. + writel(CTRL1_RECOVERY_ON_UNDERFLOW, host->base + LCDC_CTRL1 + REG_SET);
  218521. +
  218522. host->enabled = 1;
  218523. }
  218524. @@ -392,14 +401,6 @@
  218525. int line_size, fb_size;
  218526. int reenable = 0;
  218527. - line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
  218528. - fb_size = fb_info->var.yres_virtual * line_size;
  218529. -
  218530. - if (fb_size > fb_info->fix.smem_len)
  218531. - return -ENOMEM;
  218532. -
  218533. - fb_info->fix.line_length = line_size;
  218534. -
  218535. /*
  218536. * It seems, you can't re-program the controller if it is still running.
  218537. * This may lead into shifted pictures (FIFO issue?).
  218538. @@ -413,6 +414,19 @@
  218539. /* clear the FIFOs */
  218540. writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET);
  218541. + line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
  218542. + fb_info->fix.line_length = line_size;
  218543. + fb_size = fb_info->var.yres_virtual * line_size;
  218544. +
  218545. + /* Reallocate memory */
  218546. + if (!fb_info->fix.smem_start || (fb_size > fb_info->fix.smem_len)) {
  218547. + if (fb_info->fix.smem_start)
  218548. + mxsfb_unmap_videomem(fb_info);
  218549. +
  218550. + if (mxsfb_map_videomem(fb_info) < 0)
  218551. + return -ENOMEM;
  218552. + }
  218553. +
  218554. ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER |
  218555. CTRL_SET_BUS_WIDTH(host->ld_intf_width);
  218556. @@ -459,9 +473,9 @@
  218557. vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
  218558. if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT)
  218559. vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
  218560. - if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT)
  218561. + if (!(fb_info->var.sync & FB_SYNC_OE_LOW_ACT))
  218562. vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
  218563. - if (host->sync & MXSFB_SYNC_DOTCLK_FALLING_ACT)
  218564. + if (fb_info->var.sync & FB_SYNC_CLK_LAT_FALL)
  218565. vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING;
  218566. writel(vdctrl0, host->base + LCDC_VDCTRL0);
  218567. @@ -578,6 +592,34 @@
  218568. return 0;
  218569. }
  218570. +static int mxsfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
  218571. +{
  218572. + u32 len;
  218573. + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  218574. +
  218575. + if (offset < info->fix.smem_len) {
  218576. + /* mapping framebuffer memory */
  218577. + len = info->fix.smem_len - offset;
  218578. + vma->vm_pgoff = (info->fix.smem_start + offset) >> PAGE_SHIFT;
  218579. + } else
  218580. + return -EINVAL;
  218581. +
  218582. + len = PAGE_ALIGN(len);
  218583. + if (vma->vm_end - vma->vm_start > len)
  218584. + return -EINVAL;
  218585. +
  218586. + /* make buffers bufferable */
  218587. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  218588. +
  218589. + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  218590. + vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
  218591. + dev_dbg(info->device, "mmap remap_pfn_range failed\n");
  218592. + return -ENOBUFS;
  218593. + }
  218594. +
  218595. + return 0;
  218596. +}
  218597. +
  218598. static struct fb_ops mxsfb_ops = {
  218599. .owner = THIS_MODULE,
  218600. .fb_check_var = mxsfb_check_var,
  218601. @@ -585,6 +627,7 @@
  218602. .fb_setcolreg = mxsfb_setcolreg,
  218603. .fb_blank = mxsfb_blank,
  218604. .fb_pan_display = mxsfb_pan_display,
  218605. + .fb_mmap = mxsfb_mmap,
  218606. .fb_fillrect = cfb_fillrect,
  218607. .fb_copyarea = cfb_copyarea,
  218608. .fb_imageblit = cfb_imageblit,
  218609. @@ -800,7 +843,62 @@
  218610. {
  218611. struct fb_info *fb_info = &host->fb_info;
  218612. - free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len);
  218613. + mxsfb_unmap_videomem(fb_info);
  218614. +}
  218615. +
  218616. +/*!
  218617. + * Allocates the DRAM memory for the frame buffer. This buffer is remapped
  218618. + * into a non-cached, non-buffered, memory region to allow palette and pixel
  218619. + * writes to occur without flushing the cache. Once this area is remapped,
  218620. + * all virtual memory access to the video memory should occur at the new region.
  218621. + *
  218622. + * @param fbi framebuffer information pointer
  218623. + *
  218624. + * @return Error code indicating success or failure
  218625. + */
  218626. +static int mxsfb_map_videomem(struct fb_info *fbi)
  218627. +{
  218628. + if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length)
  218629. + fbi->fix.smem_len = fbi->var.yres_virtual *
  218630. + fbi->fix.line_length;
  218631. +
  218632. + fbi->screen_base = dma_alloc_writecombine(fbi->device,
  218633. + fbi->fix.smem_len,
  218634. + (dma_addr_t *)&fbi->fix.smem_start,
  218635. + GFP_DMA | GFP_KERNEL);
  218636. + if (fbi->screen_base == 0) {
  218637. + dev_err(fbi->device, "Unable to allocate framebuffer memory\n");
  218638. + fbi->fix.smem_len = 0;
  218639. + fbi->fix.smem_start = 0;
  218640. + return -EBUSY;
  218641. + }
  218642. +
  218643. + dev_dbg(fbi->device, "allocated fb @ paddr=0x%08X, size=%d.\n",
  218644. + (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
  218645. +
  218646. + fbi->screen_size = fbi->fix.smem_len;
  218647. +
  218648. + /* Clear the screen */
  218649. + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
  218650. +
  218651. + return 0;
  218652. +}
  218653. +
  218654. +/*!
  218655. + * De-allocates the DRAM memory for the frame buffer.
  218656. + *
  218657. + * @param fbi framebuffer information pointer
  218658. + *
  218659. + * @return Error code indicating success or failure
  218660. + */
  218661. +static int mxsfb_unmap_videomem(struct fb_info *fbi)
  218662. +{
  218663. + dma_free_writecombine(fbi->device, fbi->fix.smem_len,
  218664. + fbi->screen_base, fbi->fix.smem_start);
  218665. + fbi->screen_base = 0;
  218666. + fbi->fix.smem_start = 0;
  218667. + fbi->fix.smem_len = 0;
  218668. + return 0;
  218669. }
  218670. static struct platform_device_id mxsfb_devtype[] = {
  218671. diff -Nur linux-3.14.15/drivers/video/vexpress-dvi.c linux-linaro-stable-mx6/drivers/video/vexpress-dvi.c
  218672. --- linux-3.14.15/drivers/video/vexpress-dvi.c 1970-01-01 01:00:00.000000000 +0100
  218673. +++ linux-linaro-stable-mx6/drivers/video/vexpress-dvi.c 2014-08-20 19:24:03.438888022 +0200
  218674. @@ -0,0 +1,220 @@
  218675. +/*
  218676. + * This program is free software; you can redistribute it and/or modify
  218677. + * it under the terms of the GNU General Public License version 2 as
  218678. + * published by the Free Software Foundation.
  218679. + *
  218680. + * This program is distributed in the hope that it will be useful,
  218681. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  218682. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  218683. + * GNU General Public License for more details.
  218684. + *
  218685. + * Copyright (C) 2012 ARM Limited
  218686. + */
  218687. +
  218688. +#define pr_fmt(fmt) "vexpress-dvi: " fmt
  218689. +
  218690. +#include <linux/fb.h>
  218691. +#include <linux/of.h>
  218692. +#include <linux/of_device.h>
  218693. +#include <linux/vexpress.h>
  218694. +
  218695. +
  218696. +static struct vexpress_config_func *vexpress_dvimode_func;
  218697. +
  218698. +static struct {
  218699. + u32 xres, yres, mode;
  218700. +} vexpress_dvi_dvimodes[] = {
  218701. + { 640, 480, 0 }, /* VGA */
  218702. + { 800, 600, 1 }, /* SVGA */
  218703. + { 1024, 768, 2 }, /* XGA */
  218704. + { 1280, 1024, 3 }, /* SXGA */
  218705. + { 1600, 1200, 4 }, /* UXGA */
  218706. + { 1920, 1080, 5 }, /* HD1080 */
  218707. +};
  218708. +
  218709. +static void vexpress_dvi_mode_set(struct fb_info *info, u32 xres, u32 yres)
  218710. +{
  218711. + int err = -ENOENT;
  218712. + int i;
  218713. +
  218714. + if (!vexpress_dvimode_func)
  218715. + return;
  218716. +
  218717. + for (i = 0; i < ARRAY_SIZE(vexpress_dvi_dvimodes); i++) {
  218718. + if (vexpress_dvi_dvimodes[i].xres == xres &&
  218719. + vexpress_dvi_dvimodes[i].yres == yres) {
  218720. + pr_debug("mode: %ux%u = %d\n", xres, yres,
  218721. + vexpress_dvi_dvimodes[i].mode);
  218722. + err = vexpress_config_write(vexpress_dvimode_func, 0,
  218723. + vexpress_dvi_dvimodes[i].mode);
  218724. + break;
  218725. + }
  218726. + }
  218727. +
  218728. + if (err)
  218729. + pr_warn("Failed to set %ux%u mode! (%d)\n", xres, yres, err);
  218730. +}
  218731. +
  218732. +
  218733. +static struct vexpress_config_func *vexpress_muxfpga_func;
  218734. +static int vexpress_dvi_fb = -1;
  218735. +
  218736. +static int vexpress_dvi_mux_set(struct fb_info *info)
  218737. +{
  218738. + int err;
  218739. + u32 site = vexpress_get_site_by_dev(info->device);
  218740. +
  218741. + if (!vexpress_muxfpga_func)
  218742. + return -ENXIO;
  218743. +
  218744. + err = vexpress_config_write(vexpress_muxfpga_func, 0, site);
  218745. + if (!err) {
  218746. + pr_debug("Selected MUXFPGA input %d (fb%d)\n", site,
  218747. + info->node);
  218748. + vexpress_dvi_fb = info->node;
  218749. + vexpress_dvi_mode_set(info, info->var.xres,
  218750. + info->var.yres);
  218751. + } else {
  218752. + pr_warn("Failed to select MUXFPGA input %d (fb%d)! (%d)\n",
  218753. + site, info->node, err);
  218754. + }
  218755. +
  218756. + return err;
  218757. +}
  218758. +
  218759. +static int vexpress_dvi_fb_select(int fb)
  218760. +{
  218761. + int err;
  218762. + struct fb_info *info;
  218763. +
  218764. + /* fb0 is the default */
  218765. + if (fb < 0)
  218766. + fb = 0;
  218767. +
  218768. + info = registered_fb[fb];
  218769. + if (!info || !lock_fb_info(info))
  218770. + return -ENODEV;
  218771. +
  218772. + err = vexpress_dvi_mux_set(info);
  218773. +
  218774. + unlock_fb_info(info);
  218775. +
  218776. + return err;
  218777. +}
  218778. +
  218779. +static ssize_t vexpress_dvi_fb_show(struct device *dev,
  218780. + struct device_attribute *attr, char *buf)
  218781. +{
  218782. + return sprintf(buf, "%d\n", vexpress_dvi_fb);
  218783. +}
  218784. +
  218785. +static ssize_t vexpress_dvi_fb_store(struct device *dev,
  218786. + struct device_attribute *attr, const char *buf, size_t count)
  218787. +{
  218788. + long value;
  218789. + int err = kstrtol(buf, 0, &value);
  218790. +
  218791. + if (!err)
  218792. + err = vexpress_dvi_fb_select(value);
  218793. +
  218794. + return err ? err : count;
  218795. +}
  218796. +
  218797. +DEVICE_ATTR(fb, S_IRUGO | S_IWUSR, vexpress_dvi_fb_show,
  218798. + vexpress_dvi_fb_store);
  218799. +
  218800. +
  218801. +static int vexpress_dvi_fb_event_notify(struct notifier_block *self,
  218802. + unsigned long action, void *data)
  218803. +{
  218804. + struct fb_event *event = data;
  218805. + struct fb_info *info = event->info;
  218806. + struct fb_videomode *mode = event->data;
  218807. +
  218808. + switch (action) {
  218809. + case FB_EVENT_FB_REGISTERED:
  218810. + if (vexpress_dvi_fb < 0)
  218811. + vexpress_dvi_mux_set(info);
  218812. + break;
  218813. + case FB_EVENT_MODE_CHANGE:
  218814. + case FB_EVENT_MODE_CHANGE_ALL:
  218815. + if (info->node == vexpress_dvi_fb)
  218816. + vexpress_dvi_mode_set(info, mode->xres, mode->yres);
  218817. + break;
  218818. + }
  218819. +
  218820. + return NOTIFY_OK;
  218821. +}
  218822. +
  218823. +static struct notifier_block vexpress_dvi_fb_notifier = {
  218824. + .notifier_call = vexpress_dvi_fb_event_notify,
  218825. +};
  218826. +static bool vexpress_dvi_fb_notifier_registered;
  218827. +
  218828. +
  218829. +enum vexpress_dvi_func { FUNC_MUXFPGA, FUNC_DVIMODE };
  218830. +
  218831. +static struct of_device_id vexpress_dvi_of_match[] = {
  218832. + {
  218833. + .compatible = "arm,vexpress-muxfpga",
  218834. + .data = (void *)FUNC_MUXFPGA,
  218835. + }, {
  218836. + .compatible = "arm,vexpress-dvimode",
  218837. + .data = (void *)FUNC_DVIMODE,
  218838. + },
  218839. + {}
  218840. +};
  218841. +
  218842. +static int vexpress_dvi_probe(struct platform_device *pdev)
  218843. +{
  218844. + enum vexpress_dvi_func func;
  218845. + const struct of_device_id *match =
  218846. + of_match_device(vexpress_dvi_of_match, &pdev->dev);
  218847. +
  218848. + if (match)
  218849. + func = (enum vexpress_dvi_func)match->data;
  218850. + else
  218851. + func = pdev->id_entry->driver_data;
  218852. +
  218853. + switch (func) {
  218854. + case FUNC_MUXFPGA:
  218855. + vexpress_muxfpga_func =
  218856. + vexpress_config_func_get_by_dev(&pdev->dev);
  218857. + device_create_file(&pdev->dev, &dev_attr_fb);
  218858. + break;
  218859. + case FUNC_DVIMODE:
  218860. + vexpress_dvimode_func =
  218861. + vexpress_config_func_get_by_dev(&pdev->dev);
  218862. + break;
  218863. + }
  218864. +
  218865. + if (!vexpress_dvi_fb_notifier_registered) {
  218866. + fb_register_client(&vexpress_dvi_fb_notifier);
  218867. + vexpress_dvi_fb_notifier_registered = true;
  218868. + }
  218869. +
  218870. + vexpress_dvi_fb_select(vexpress_dvi_fb);
  218871. +
  218872. + return 0;
  218873. +}
  218874. +
  218875. +static const struct platform_device_id vexpress_dvi_id_table[] = {
  218876. + { .name = "vexpress-muxfpga", .driver_data = FUNC_MUXFPGA, },
  218877. + { .name = "vexpress-dvimode", .driver_data = FUNC_DVIMODE, },
  218878. + {}
  218879. +};
  218880. +
  218881. +static struct platform_driver vexpress_dvi_driver = {
  218882. + .probe = vexpress_dvi_probe,
  218883. + .driver = {
  218884. + .name = "vexpress-dvi",
  218885. + .of_match_table = vexpress_dvi_of_match,
  218886. + },
  218887. + .id_table = vexpress_dvi_id_table,
  218888. +};
  218889. +
  218890. +static int __init vexpress_dvi_init(void)
  218891. +{
  218892. + return platform_driver_register(&vexpress_dvi_driver);
  218893. +}
  218894. +device_initcall(vexpress_dvi_init);
  218895. diff -Nur linux-3.14.15/firmware/imx/sdma/sdma-imx6q.bin.ihex linux-linaro-stable-mx6/firmware/imx/sdma/sdma-imx6q.bin.ihex
  218896. --- linux-3.14.15/firmware/imx/sdma/sdma-imx6q.bin.ihex 1970-01-01 01:00:00.000000000 +0100
  218897. +++ linux-linaro-stable-mx6/firmware/imx/sdma/sdma-imx6q.bin.ihex 2014-08-20 19:24:03.654888945 +0200
  218898. @@ -0,0 +1,116 @@
  218899. +:1000000053444D4101000000010000001C000000AD
  218900. +:1000100026000000B40000007A0600008202000002
  218901. +:10002000FFFFFFFF00000000FFFFFFFFFFFFFFFFDC
  218902. +:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
  218903. +:10004000FFFFFFFFFFFFFFFF6A1A0000FFFFFFFF38
  218904. +:10005000EB020000BB180000FFFFFFFF08040000D8
  218905. +:10006000FFFFFFFFC0030000FFFFFFFFFFFFFFFFD9
  218906. +:10007000FFFFFFFFAB020000FFFFFFFF7B0300005D
  218907. +:10008000FFFFFFFFFFFFFFFF4C0400006E040000B6
  218908. +:10009000FFFFFFFF00180000FFFFFFFFFFFFFFFF54
  218909. +:1000A000000000000018000062180000161A00008E
  218910. +:1000B000061B0000E3C1DB57E35FE357F352016A1D
  218911. +:1000C0008F00D500017D8D00A005EB5D7804037DD8
  218912. +:1000D00079042C7D367C79041F7CEE56000F600677
  218913. +:1000E000057D0965437E0A62417E20980A623E7E54
  218914. +:1000F00009653C7E12051205AD026007037DFB55C4
  218915. +:10010000D36D2B98FB55041DD36DC86A2F7F011F3B
  218916. +:1001100003200048E47C5398FB55D76D1500057803
  218917. +:100120000962C86A0962C86AD76D5298FB55D76DD3
  218918. +:100130001500150005780A62C86A0A62C86AD76D98
  218919. +:100140005298FB55D76D15001500150005780B6208
  218920. +:10015000C86A0B62C86AD76D097CDF6D077F000033
  218921. +:10016000EB55004D077DFAC1E35706980700CC68B0
  218922. +:100170000C6813C20AC20398D9C1E3C1DB57E35F1D
  218923. +:10018000E357F352216A8F00D500017D8D00A00551
  218924. +:10019000EB5DFB567804037D79042A7D317C79047C
  218925. +:1001A000207C700B1103EB53000F6003057D096584
  218926. +:1001B000377E0A62357E86980A62327E0965307E15
  218927. +:1001C00012051205AD026007027C065A8E98265A67
  218928. +:1001D000277F011F03200048E87C700B1103135395
  218929. +:1001E000AF98150004780962065A0962265AAE983B
  218930. +:1001F0001500150004780A62065A0A62265AAE985B
  218931. +:1002000015001500150004780B62065A0B62265A79
  218932. +:10021000077C0000EB55004D067DFAC1E357699855
  218933. +:1002200007000C6813C20AC26698700B11031353BF
  218934. +:100230006C07017CD9C1FB5E8A066B07017CD9C1C2
  218935. +:10024000F35EDB59D3588F0110010F398B003CC18D
  218936. +:100250002B7DC05AC85B4EC1277C88038906E35CAE
  218937. +:10026000FF0D1105FF1DBC053E07004D187D7008F0
  218938. +:1002700011007E07097D7D07027D2852E698F8521D
  218939. +:10028000DB54BC02CC02097C7C07027D2852EF982B
  218940. +:10029000F852D354BC02CC02097D0004DD988B00D7
  218941. +:1002A000C052C85359C1D67D0002CD98FF08BF0087
  218942. +:1002B0007F07157D8804D500017D8D00A005EB5DCD
  218943. +:1002C0008F0212021202FF3ADA05027C3E071899E9
  218944. +:1002D000A402DD02027D3E0718995E071899EB55CE
  218945. +:1002E0009805EB5DF352FB546A07267D6C07017D90
  218946. +:1002F00055996B07577C6907047D6807027D010EDD
  218947. +:100300002F999358D600017D8E009355A005935DDB
  218948. +:10031000A00602780255045D1D7C004E087C69072A
  218949. +:10032000037D0255177E3C99045D147F8906935026
  218950. +:100330000048017D2799A099150006780255045DB3
  218951. +:100340004F070255245D2F07017CA09917006F0706
  218952. +:10035000017C012093559D000700A7D9F598D36C27
  218953. +:100360006907047D6807027D010E64999358D600E1
  218954. +:10037000017D8E009355A005935DA006027802557D
  218955. +:10038000C86D0F7C004E087C6907037D0255097E0D
  218956. +:100390007199C86D067F890693500048017D5C996C
  218957. +:1003A000A0999A99C36A6907047D6807027D010EC6
  218958. +:1003B00087999358D600017D8E009355A005935DD3
  218959. +:1003C000A0060278C865045D0F7C004E087C6907B2
  218960. +:1003D000037DC865097E9499045D067F8906935064
  218961. +:1003E0000048017D7F99A09993559D000700FF6CFF
  218962. +:1003F000A7D9F5980000E354EB55004D017CF59822
  218963. +:10040000DD98E354EB55FF0A1102FF1A7F07027CC7
  218964. +:10041000A005B4999D008C05BA05A0051002BA0488
  218965. +:10042000AD0454040600E3C1DB57FB52C36AF35228
  218966. +:10043000056A8F00D500017D8D00A005EB5D780475
  218967. +:10044000037D79042B7D1E7C7904337CEE56000FEE
  218968. +:10045000FB556007027DC36DD599041DC36DC8624D
  218969. +:100460003B7E6006027D10021202096A357F12028D
  218970. +:10047000096A327F1202096A2F7F011F0320004898
  218971. +:10048000E77C099AFB55C76D150015001500057826
  218972. +:10049000C8620B6AC8620B6AC76D089AFB55C76DC4
  218973. +:1004A000150015000578C8620A6AC8620A6AC76D35
  218974. +:1004B000089AFB55C76D15000578C862096AC862BD
  218975. +:1004C000096AC76D097C286A077F0000EB55004D5B
  218976. +:1004D000057DFAC1DB57BF9977C254040AC2BA99A5
  218977. +:1004E000D9C1E3C1DB57F352056A8F00D500017D06
  218978. +:1004F0008D00A005FB567804037D7904297D1F7CBF
  218979. +:1005000079042E7CE35D700D1105ED55000F600739
  218980. +:10051000027D0652329A2652337E6005027D100219
  218981. +:100520001202096A2D7F1202096A2A7F1202096AE1
  218982. +:10053000277F011F03200048EA7CE3555D9A1500E0
  218983. +:1005400015001500047806520B6A26520B6A5C9A55
  218984. +:1005500015001500047806520A6A26520A6A5C9A47
  218985. +:10056000150004780652096A2652096A097C286A2D
  218986. +:10057000077F0000DB57004D057DFAC1DB571B9A52
  218987. +:1005800077C254040AC2189AE3C1DB57F352056AD2
  218988. +:10059000FB568E02941AC36AC8626902247D941EB7
  218989. +:1005A000C36ED36EC8624802C86A9426981EC36E92
  218990. +:1005B000D36EC8624C02C86A9826C36E981EC36E7A
  218991. +:1005C000C8629826C36E6002097CC8626E02247DF0
  218992. +:1005D000096A1E7F0125004D257D849A286A187FAF
  218993. +:1005E00004627AC2B89AE36E8F00D805017D8D004F
  218994. +:1005F000A005C8626E02107D096A0A7F0120F97C9D
  218995. +:10060000286A067F0000004D0D7DFAC1DB576E9A07
  218996. +:10061000070004620C6AB59A286AFA7F04627AC2FB
  218997. +:1006200058045404286AF47F0AC26B9AD9C1E3C102
  218998. +:10063000DB57F352056AFB568E02941A0252690286
  218999. +:100640001D7D941E06524802065A9426981E065294
  219000. +:100650004C02065A9826981E065260020A7C98267A
  219001. +:1006600006526E02237D096A1D7F0125004D247DFF
  219002. +:10067000D19A286A177F04627AC2029B8F00D8053C
  219003. +:10068000017D8D00A00506526E02107D096A0A7F69
  219004. +:100690000120F97C286A067F0000004D0D7DFAC11B
  219005. +:1006A000DB57C19A070004620C6AFF9A286AFA7F36
  219006. +:1006B00004627AC258045404286AF47F0AC2BE9ABB
  219007. +:1006C000016E0B612F7E0B622D7E0B632B7E0C0D5A
  219008. +:1006D0001704170417049D04081DCC05017C0C0D9C
  219009. +:1006E000D16A000F4207C86FDD6F1C7F8E009D002E
  219010. +:1006F00001680B67177ED56B04080278C86F120774
  219011. +:10070000117C0B670F7E04080278C86F12070A7C01
  219012. +:10071000DD6F087FD169010FC86FDD6F037F0101B5
  219013. +:0E0720000004129B0700FF680C680002129B89
  219014. +:00000001FF
  219015. diff -Nur linux-3.14.15/firmware/Makefile linux-linaro-stable-mx6/firmware/Makefile
  219016. --- linux-3.14.15/firmware/Makefile 2014-07-31 23:51:43.000000000 +0200
  219017. +++ linux-linaro-stable-mx6/firmware/Makefile 2014-08-20 19:31:50.432887482 +0200
  219018. @@ -61,6 +61,7 @@
  219019. radeon/RV770_pfp.bin radeon/RV770_me.bin \
  219020. radeon/RV730_pfp.bin radeon/RV730_me.bin \
  219021. radeon/RV710_pfp.bin radeon/RV710_me.bin
  219022. +fw-shipped-$(CONFIG_IMX_SDMA) += imx/sdma/sdma-imx6q.bin
  219023. fw-shipped-$(CONFIG_DVB_AV7110) += av7110/bootcode.bin
  219024. fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
  219025. fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
  219026. @@ -210,6 +211,8 @@
  219027. $(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %)
  219028. $(call cmd,ihex)
  219029. +.NOTPARALLEL: $(obj)/%
  219030. +
  219031. # Don't depend on ihex2fw if we're installing and it already exists.
  219032. # Putting it after | in the dependencies doesn't seem sufficient when
  219033. # we're installing after a cross-compile, because ihex2fw has dependencies
  219034. diff -Nur linux-3.14.15/fs/btrfs/Kconfig linux-linaro-stable-mx6/fs/btrfs/Kconfig
  219035. --- linux-3.14.15/fs/btrfs/Kconfig 2014-07-31 23:51:43.000000000 +0200
  219036. +++ linux-linaro-stable-mx6/fs/btrfs/Kconfig 2014-08-20 19:31:50.448887549 +0200
  219037. @@ -1,5 +1,6 @@
  219038. config BTRFS_FS
  219039. tristate "Btrfs filesystem support"
  219040. + select LIBCRC32C
  219041. select CRYPTO
  219042. select CRYPTO_CRC32C
  219043. select ZLIB_INFLATE
  219044. diff -Nur linux-3.14.15/fs/buffer.c linux-linaro-stable-mx6/fs/buffer.c
  219045. --- linux-3.14.15/fs/buffer.c 2014-07-31 23:51:43.000000000 +0200
  219046. +++ linux-linaro-stable-mx6/fs/buffer.c 2014-08-20 19:31:50.500887773 +0200
  219047. @@ -3088,7 +3088,7 @@
  219048. * until the buffer gets unlocked).
  219049. *
  219050. * ll_rw_block sets b_end_io to simple completion handler that marks
  219051. - * the buffer up-to-date (if approriate), unlocks the buffer and wakes
  219052. + * the buffer up-to-date (if appropriate), unlocks the buffer and wakes
  219053. * any waiters.
  219054. *
  219055. * All of the buffers must be for the same device, and must also be a
  219056. diff -Nur linux-3.14.15/fs/compat_binfmt_elf.c linux-linaro-stable-mx6/fs/compat_binfmt_elf.c
  219057. --- linux-3.14.15/fs/compat_binfmt_elf.c 2014-07-31 23:51:43.000000000 +0200
  219058. +++ linux-linaro-stable-mx6/fs/compat_binfmt_elf.c 2014-08-20 19:31:50.528887893 +0200
  219059. @@ -88,6 +88,11 @@
  219060. #define ELF_HWCAP COMPAT_ELF_HWCAP
  219061. #endif
  219062. +#ifdef COMPAT_ELF_HWCAP2
  219063. +#undef ELF_HWCAP2
  219064. +#define ELF_HWCAP2 COMPAT_ELF_HWCAP2
  219065. +#endif
  219066. +
  219067. #ifdef COMPAT_ARCH_DLINFO
  219068. #undef ARCH_DLINFO
  219069. #define ARCH_DLINFO COMPAT_ARCH_DLINFO
  219070. diff -Nur linux-3.14.15/fs/coredump.c linux-linaro-stable-mx6/fs/coredump.c
  219071. --- linux-3.14.15/fs/coredump.c 2014-07-31 23:51:43.000000000 +0200
  219072. +++ linux-linaro-stable-mx6/fs/coredump.c 2014-08-20 19:31:50.528887893 +0200
  219073. @@ -306,7 +306,7 @@
  219074. if (unlikely(nr < 0))
  219075. return nr;
  219076. - tsk->flags |= PF_DUMPCORE;
  219077. + tsk->flags = PF_DUMPCORE;
  219078. if (atomic_read(&mm->mm_users) == nr + 1)
  219079. goto done;
  219080. /*
  219081. diff -Nur linux-3.14.15/fs/debugfs/inode.c linux-linaro-stable-mx6/fs/debugfs/inode.c
  219082. --- linux-3.14.15/fs/debugfs/inode.c 2014-07-31 23:51:43.000000000 +0200
  219083. +++ linux-linaro-stable-mx6/fs/debugfs/inode.c 2014-08-20 19:31:50.532887910 +0200
  219084. @@ -358,7 +358,7 @@
  219085. * @name: a pointer to a string containing the name of the file to create.
  219086. * @mode: the permission that the file should have.
  219087. * @parent: a pointer to the parent dentry for this file. This should be a
  219088. - * directory dentry if set. If this paramater is NULL, then the
  219089. + * directory dentry if set. If this parameter is NULL, then the
  219090. * file will be created in the root of the debugfs filesystem.
  219091. * @data: a pointer to something that the caller will want to get to later
  219092. * on. The inode.i_private pointer will point to this value on
  219093. @@ -400,7 +400,7 @@
  219094. * @name: a pointer to a string containing the name of the directory to
  219095. * create.
  219096. * @parent: a pointer to the parent dentry for this file. This should be a
  219097. - * directory dentry if set. If this paramater is NULL, then the
  219098. + * directory dentry if set. If this parameter is NULL, then the
  219099. * directory will be created in the root of the debugfs filesystem.
  219100. *
  219101. * This function creates a directory in debugfs with the given name.
  219102. @@ -425,7 +425,7 @@
  219103. * @name: a pointer to a string containing the name of the symbolic link to
  219104. * create.
  219105. * @parent: a pointer to the parent dentry for this symbolic link. This
  219106. - * should be a directory dentry if set. If this paramater is NULL,
  219107. + * should be a directory dentry if set. If this parameter is NULL,
  219108. * then the symbolic link will be created in the root of the debugfs
  219109. * filesystem.
  219110. * @target: a pointer to a string containing the path to the target of the
  219111. diff -Nur linux-3.14.15/fs/namei.c linux-linaro-stable-mx6/fs/namei.c
  219112. --- linux-3.14.15/fs/namei.c 2014-07-31 23:51:43.000000000 +0200
  219113. +++ linux-linaro-stable-mx6/fs/namei.c 2014-08-20 19:31:50.640888375 +0200
  219114. @@ -2247,10 +2247,9 @@
  219115. goto out;
  219116. }
  219117. path->dentry = dentry;
  219118. - path->mnt = nd->path.mnt;
  219119. + path->mnt = mntget(nd->path.mnt);
  219120. if (should_follow_link(dentry, nd->flags & LOOKUP_FOLLOW))
  219121. return 1;
  219122. - mntget(path->mnt);
  219123. follow_mount(path);
  219124. error = 0;
  219125. out:
  219126. diff -Nur linux-3.14.15/fs/nfs/nfs3acl.c linux-linaro-stable-mx6/fs/nfs/nfs3acl.c
  219127. --- linux-3.14.15/fs/nfs/nfs3acl.c 2014-07-31 23:51:43.000000000 +0200
  219128. +++ linux-linaro-stable-mx6/fs/nfs/nfs3acl.c 2014-08-20 19:31:50.652888427 +0200
  219129. @@ -247,46 +247,3 @@
  219130. &posix_acl_default_xattr_handler,
  219131. NULL,
  219132. };
  219133. -
  219134. -static int
  219135. -nfs3_list_one_acl(struct inode *inode, int type, const char *name, void *data,
  219136. - size_t size, ssize_t *result)
  219137. -{
  219138. - struct posix_acl *acl;
  219139. - char *p = data + *result;
  219140. -
  219141. - acl = get_acl(inode, type);
  219142. - if (!acl)
  219143. - return 0;
  219144. -
  219145. - posix_acl_release(acl);
  219146. -
  219147. - *result += strlen(name);
  219148. - *result += 1;
  219149. - if (!size)
  219150. - return 0;
  219151. - if (*result > size)
  219152. - return -ERANGE;
  219153. -
  219154. - strcpy(p, name);
  219155. - return 0;
  219156. -}
  219157. -
  219158. -ssize_t
  219159. -nfs3_listxattr(struct dentry *dentry, char *data, size_t size)
  219160. -{
  219161. - struct inode *inode = dentry->d_inode;
  219162. - ssize_t result = 0;
  219163. - int error;
  219164. -
  219165. - error = nfs3_list_one_acl(inode, ACL_TYPE_ACCESS,
  219166. - POSIX_ACL_XATTR_ACCESS, data, size, &result);
  219167. - if (error)
  219168. - return error;
  219169. -
  219170. - error = nfs3_list_one_acl(inode, ACL_TYPE_DEFAULT,
  219171. - POSIX_ACL_XATTR_DEFAULT, data, size, &result);
  219172. - if (error)
  219173. - return error;
  219174. - return result;
  219175. -}
  219176. diff -Nur linux-3.14.15/fs/nfs/nfs3proc.c linux-linaro-stable-mx6/fs/nfs/nfs3proc.c
  219177. --- linux-3.14.15/fs/nfs/nfs3proc.c 2014-07-31 23:51:43.000000000 +0200
  219178. +++ linux-linaro-stable-mx6/fs/nfs/nfs3proc.c 2014-08-20 19:31:50.652888427 +0200
  219179. @@ -926,7 +926,7 @@
  219180. .getattr = nfs_getattr,
  219181. .setattr = nfs_setattr,
  219182. #ifdef CONFIG_NFS_V3_ACL
  219183. - .listxattr = nfs3_listxattr,
  219184. + .listxattr = generic_listxattr,
  219185. .getxattr = generic_getxattr,
  219186. .setxattr = generic_setxattr,
  219187. .removexattr = generic_removexattr,
  219188. @@ -940,7 +940,7 @@
  219189. .getattr = nfs_getattr,
  219190. .setattr = nfs_setattr,
  219191. #ifdef CONFIG_NFS_V3_ACL
  219192. - .listxattr = nfs3_listxattr,
  219193. + .listxattr = generic_listxattr,
  219194. .getxattr = generic_getxattr,
  219195. .setxattr = generic_setxattr,
  219196. .removexattr = generic_removexattr,
  219197. diff -Nur linux-3.14.15/include/asm-generic/word-at-a-time.h linux-linaro-stable-mx6/include/asm-generic/word-at-a-time.h
  219198. --- linux-3.14.15/include/asm-generic/word-at-a-time.h 2014-07-31 23:51:43.000000000 +0200
  219199. +++ linux-linaro-stable-mx6/include/asm-generic/word-at-a-time.h 2014-08-20 19:31:51.020890006 +0200
  219200. @@ -50,7 +50,7 @@
  219201. }
  219202. #ifndef zero_bytemask
  219203. -#define zero_bytemask(mask) (~0ul << __fls(mask) << 1)
  219204. +#define zero_bytemask(mask) (~1ul << __fls(mask))
  219205. #endif
  219206. #endif /* _ASM_WORD_AT_A_TIME_H */
  219207. diff -Nur linux-3.14.15/include/crypto/algapi.h linux-linaro-stable-mx6/include/crypto/algapi.h
  219208. --- linux-3.14.15/include/crypto/algapi.h 2014-07-31 23:51:43.000000000 +0200
  219209. +++ linux-linaro-stable-mx6/include/crypto/algapi.h 2014-08-20 19:31:51.020890006 +0200
  219210. @@ -100,9 +100,12 @@
  219211. void *page;
  219212. u8 *buffer;
  219213. u8 *iv;
  219214. + unsigned int ivsize;
  219215. int flags;
  219216. - unsigned int blocksize;
  219217. + unsigned int walk_blocksize;
  219218. + unsigned int cipher_blocksize;
  219219. + unsigned int alignmask;
  219220. };
  219221. struct ablkcipher_walk {
  219222. @@ -192,6 +195,10 @@
  219223. int blkcipher_walk_virt_block(struct blkcipher_desc *desc,
  219224. struct blkcipher_walk *walk,
  219225. unsigned int blocksize);
  219226. +int blkcipher_aead_walk_virt_block(struct blkcipher_desc *desc,
  219227. + struct blkcipher_walk *walk,
  219228. + struct crypto_aead *tfm,
  219229. + unsigned int blocksize);
  219230. int ablkcipher_walk_done(struct ablkcipher_request *req,
  219231. struct ablkcipher_walk *walk, int err);
  219232. diff -Nur linux-3.14.15/include/drm/drm_fb_helper.h linux-linaro-stable-mx6/include/drm/drm_fb_helper.h
  219233. --- linux-3.14.15/include/drm/drm_fb_helper.h 2014-07-31 23:51:43.000000000 +0200
  219234. +++ linux-linaro-stable-mx6/include/drm/drm_fb_helper.h 2014-08-20 19:31:51.024890023 +0200
  219235. @@ -55,7 +55,7 @@
  219236. * save the current lut when force-restoring the fbdev for e.g.
  219237. * kdbg.
  219238. * @fb_probe: Driver callback to allocate and initialize the fbdev info
  219239. - * structure. Futhermore it also needs to allocate the drm
  219240. + * structure. Furthermore it also needs to allocate the drm
  219241. * framebuffer used to back the fbdev.
  219242. * @initial_config: Setup an initial fbdev display configuration
  219243. *
  219244. diff -Nur linux-3.14.15/include/dt-bindings/clock/imx6sl-clock.h linux-linaro-stable-mx6/include/dt-bindings/clock/imx6sl-clock.h
  219245. --- linux-3.14.15/include/dt-bindings/clock/imx6sl-clock.h 2014-07-31 23:51:43.000000000 +0200
  219246. +++ linux-linaro-stable-mx6/include/dt-bindings/clock/imx6sl-clock.h 2014-08-20 19:31:51.116890419 +0200
  219247. @@ -1,5 +1,5 @@
  219248. /*
  219249. - * Copyright 2013 Freescale Semiconductor, Inc.
  219250. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  219251. *
  219252. * This program is free software; you can redistribute it and/or modify
  219253. * it under the terms of the GNU General Public License version 2 as
  219254. @@ -71,8 +71,8 @@
  219255. #define IMX6SL_CLK_PERIPH 58
  219256. #define IMX6SL_CLK_PERIPH2 59
  219257. #define IMX6SL_CLK_OCRAM_PODF 60
  219258. -#define IMX6SL_CLK_PERIPH_CLK2_PODF 61
  219259. -#define IMX6SL_CLK_PERIPH2_CLK2_PODF 62
  219260. +#define IMX6SL_CLK_PERIPH_CLK2 61
  219261. +#define IMX6SL_CLK_PERIPH2_CLK2 62
  219262. #define IMX6SL_CLK_IPG 63
  219263. #define IMX6SL_CLK_CSI_PODF 64
  219264. #define IMX6SL_CLK_LCDIF_AXI_PODF 65
  219265. @@ -145,6 +145,7 @@
  219266. #define IMX6SL_CLK_USDHC4 132
  219267. #define IMX6SL_CLK_PLL4_AUDIO_DIV 133
  219268. #define IMX6SL_CLK_SPBA 134
  219269. -#define IMX6SL_CLK_END 135
  219270. +#define IMX6SL_CLK_UART_OSC_4M 135
  219271. +#define IMX6SL_CLK_END 136
  219272. #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */
  219273. diff -Nur linux-3.14.15/include/linux/ahci_platform.h linux-linaro-stable-mx6/include/linux/ahci_platform.h
  219274. --- linux-3.14.15/include/linux/ahci_platform.h 2014-07-31 23:51:43.000000000 +0200
  219275. +++ linux-linaro-stable-mx6/include/linux/ahci_platform.h 2014-08-20 19:31:51.184890711 +0200
  219276. @@ -19,15 +19,38 @@
  219277. struct device;
  219278. struct ata_port_info;
  219279. +struct ahci_host_priv;
  219280. +struct platform_device;
  219281. +/*
  219282. + * Note ahci_platform_data is deprecated, it is only kept around for use
  219283. + * by the old da850 and spear13xx ahci code.
  219284. + * New drivers should instead declare their own platform_driver struct, and
  219285. + * use ahci_platform* functions in their own probe, suspend and resume methods.
  219286. + */
  219287. struct ahci_platform_data {
  219288. int (*init)(struct device *dev, void __iomem *addr);
  219289. void (*exit)(struct device *dev);
  219290. int (*suspend)(struct device *dev);
  219291. int (*resume)(struct device *dev);
  219292. - const struct ata_port_info *ata_port_info;
  219293. - unsigned int force_port_map;
  219294. - unsigned int mask_port_map;
  219295. };
  219296. +int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
  219297. +void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
  219298. +int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
  219299. +void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
  219300. +struct ahci_host_priv *ahci_platform_get_resources(
  219301. + struct platform_device *pdev);
  219302. +int ahci_platform_init_host(struct platform_device *pdev,
  219303. + struct ahci_host_priv *hpriv,
  219304. + const struct ata_port_info *pi_template,
  219305. + unsigned long host_flags,
  219306. + unsigned int force_port_map,
  219307. + unsigned int mask_port_map);
  219308. +
  219309. +int ahci_platform_suspend_host(struct device *dev);
  219310. +int ahci_platform_resume_host(struct device *dev);
  219311. +int ahci_platform_suspend(struct device *dev);
  219312. +int ahci_platform_resume(struct device *dev);
  219313. +
  219314. #endif /* _AHCI_PLATFORM_H */
  219315. diff -Nur linux-3.14.15/include/linux/amba/clcd.h linux-linaro-stable-mx6/include/linux/amba/clcd.h
  219316. --- linux-3.14.15/include/linux/amba/clcd.h 2014-07-31 23:51:43.000000000 +0200
  219317. +++ linux-linaro-stable-mx6/include/linux/amba/clcd.h 2014-08-20 19:31:51.780893269 +0200
  219318. @@ -243,6 +243,9 @@
  219319. val |= CNTL_BGR;
  219320. }
  219321. + /* Reset the current colour depth */
  219322. + val &= ~CNTL_LCDBPP16_444;
  219323. +
  219324. switch (var->bits_per_pixel) {
  219325. case 1:
  219326. val |= CNTL_LCDBPP1;
  219327. @@ -264,14 +267,15 @@
  219328. */
  219329. if (amba_part(fb->dev) == 0x110 ||
  219330. var->green.length == 5)
  219331. - val |= CNTL_LCDBPP16;
  219332. + val |= CNTL_LCDBPP16 | CNTL_BGR;
  219333. else if (var->green.length == 6)
  219334. - val |= CNTL_LCDBPP16_565;
  219335. + val |= CNTL_LCDBPP16_565 | CNTL_BGR;
  219336. else
  219337. - val |= CNTL_LCDBPP16_444;
  219338. + val |= CNTL_LCDBPP16_444 | CNTL_BGR;
  219339. break;
  219340. case 32:
  219341. val |= CNTL_LCDBPP24;
  219342. + val &= ~CNTL_BGR;
  219343. break;
  219344. }
  219345. diff -Nur linux-3.14.15/include/linux/arm-hdlcd.h linux-linaro-stable-mx6/include/linux/arm-hdlcd.h
  219346. --- linux-3.14.15/include/linux/arm-hdlcd.h 1970-01-01 01:00:00.000000000 +0100
  219347. +++ linux-linaro-stable-mx6/include/linux/arm-hdlcd.h 2014-08-20 19:24:04.598892975 +0200
  219348. @@ -0,0 +1,122 @@
  219349. +/*
  219350. + * include/linux/arm-hdlcd.h
  219351. + *
  219352. + * Copyright (C) 2011 ARM Limited
  219353. + *
  219354. + * This file is subject to the terms and conditions of the GNU General Public
  219355. + * License. See the file COPYING in the main directory of this archive
  219356. + * for more details.
  219357. + *
  219358. + * ARM HDLCD Controller register definition
  219359. + */
  219360. +
  219361. +#include <linux/fb.h>
  219362. +#include <linux/completion.h>
  219363. +
  219364. +/* register offsets */
  219365. +#define HDLCD_REG_VERSION 0x0000 /* ro */
  219366. +#define HDLCD_REG_INT_RAWSTAT 0x0010 /* rw */
  219367. +#define HDLCD_REG_INT_CLEAR 0x0014 /* wo */
  219368. +#define HDLCD_REG_INT_MASK 0x0018 /* rw */
  219369. +#define HDLCD_REG_INT_STATUS 0x001c /* ro */
  219370. +#define HDLCD_REG_USER_OUT 0x0020 /* rw */
  219371. +#define HDLCD_REG_FB_BASE 0x0100 /* rw */
  219372. +#define HDLCD_REG_FB_LINE_LENGTH 0x0104 /* rw */
  219373. +#define HDLCD_REG_FB_LINE_COUNT 0x0108 /* rw */
  219374. +#define HDLCD_REG_FB_LINE_PITCH 0x010c /* rw */
  219375. +#define HDLCD_REG_BUS_OPTIONS 0x0110 /* rw */
  219376. +#define HDLCD_REG_V_SYNC 0x0200 /* rw */
  219377. +#define HDLCD_REG_V_BACK_PORCH 0x0204 /* rw */
  219378. +#define HDLCD_REG_V_DATA 0x0208 /* rw */
  219379. +#define HDLCD_REG_V_FRONT_PORCH 0x020c /* rw */
  219380. +#define HDLCD_REG_H_SYNC 0x0210 /* rw */
  219381. +#define HDLCD_REG_H_BACK_PORCH 0x0214 /* rw */
  219382. +#define HDLCD_REG_H_DATA 0x0218 /* rw */
  219383. +#define HDLCD_REG_H_FRONT_PORCH 0x021c /* rw */
  219384. +#define HDLCD_REG_POLARITIES 0x0220 /* rw */
  219385. +#define HDLCD_REG_COMMAND 0x0230 /* rw */
  219386. +#define HDLCD_REG_PIXEL_FORMAT 0x0240 /* rw */
  219387. +#define HDLCD_REG_BLUE_SELECT 0x0244 /* rw */
  219388. +#define HDLCD_REG_GREEN_SELECT 0x0248 /* rw */
  219389. +#define HDLCD_REG_RED_SELECT 0x024c /* rw */
  219390. +
  219391. +/* version */
  219392. +#define HDLCD_PRODUCT_ID 0x1CDC0000
  219393. +#define HDLCD_PRODUCT_MASK 0xFFFF0000
  219394. +#define HDLCD_VERSION_MAJOR_MASK 0x0000FF00
  219395. +#define HDLCD_VERSION_MINOR_MASK 0x000000FF
  219396. +
  219397. +/* interrupts */
  219398. +#define HDLCD_INTERRUPT_DMA_END (1 << 0)
  219399. +#define HDLCD_INTERRUPT_BUS_ERROR (1 << 1)
  219400. +#define HDLCD_INTERRUPT_VSYNC (1 << 2)
  219401. +#define HDLCD_INTERRUPT_UNDERRUN (1 << 3)
  219402. +
  219403. +/* polarity */
  219404. +#define HDLCD_POLARITY_VSYNC (1 << 0)
  219405. +#define HDLCD_POLARITY_HSYNC (1 << 1)
  219406. +#define HDLCD_POLARITY_DATAEN (1 << 2)
  219407. +#define HDLCD_POLARITY_DATA (1 << 3)
  219408. +#define HDLCD_POLARITY_PIXELCLK (1 << 4)
  219409. +
  219410. +/* commands */
  219411. +#define HDLCD_COMMAND_DISABLE (0 << 0)
  219412. +#define HDLCD_COMMAND_ENABLE (1 << 0)
  219413. +
  219414. +/* pixel format */
  219415. +#define HDLCD_PIXEL_FMT_LITTLE_ENDIAN (0 << 31)
  219416. +#define HDLCD_PIXEL_FMT_BIG_ENDIAN (1 << 31)
  219417. +#define HDLCD_BYTES_PER_PIXEL_MASK (3 << 3)
  219418. +
  219419. +/* bus options */
  219420. +#define HDLCD_BUS_BURST_MASK 0x01f
  219421. +#define HDLCD_BUS_MAX_OUTSTAND 0xf00
  219422. +#define HDLCD_BUS_BURST_NONE (0 << 0)
  219423. +#define HDLCD_BUS_BURST_1 (1 << 0)
  219424. +#define HDLCD_BUS_BURST_2 (1 << 1)
  219425. +#define HDLCD_BUS_BURST_4 (1 << 2)
  219426. +#define HDLCD_BUS_BURST_8 (1 << 3)
  219427. +#define HDLCD_BUS_BURST_16 (1 << 4)
  219428. +
  219429. +/* Max resolution supported is 4096x4096, 8 bit per color component,
  219430. + 8 bit alpha, but we are going to choose the usual hardware default
  219431. + (2048x2048, 32 bpp) and enable double buffering */
  219432. +#define HDLCD_MAX_XRES 2048
  219433. +#define HDLCD_MAX_YRES 2048
  219434. +#define HDLCD_MAX_FRAMEBUFFER_SIZE (HDLCD_MAX_XRES * HDLCD_MAX_YRES << 2)
  219435. +
  219436. +#define HDLCD_MEM_BASE (CONFIG_PAGE_OFFSET - 0x1000000)
  219437. +
  219438. +#define NR_PALETTE 256
  219439. +
  219440. +/* OEMs using HDLCD may wish to enable these settings if
  219441. + * display disruption is apparent and you suspect HDLCD
  219442. + * access to RAM may be starved.
  219443. + */
  219444. +/* Turn HDLCD default color red instead of black so
  219445. + * that it's easy to see pixel clock data underruns
  219446. + * (compared to other visual disruption)
  219447. + */
  219448. +//#define HDLCD_RED_DEFAULT_COLOUR
  219449. +/* Add a counter in the IRQ handler to count buffer underruns
  219450. + * and /proc/hdlcd_underrun to read the counter
  219451. + */
  219452. +//#define HDLCD_COUNT_BUFFERUNDERRUNS
  219453. +/* Restrict height to 1x screen size
  219454. + *
  219455. + */
  219456. +//#define HDLCD_NO_VIRTUAL_SCREEN
  219457. +
  219458. +#ifdef CONFIG_ANDROID
  219459. +#define HDLCD_NO_VIRTUAL_SCREEN
  219460. +#endif
  219461. +
  219462. +struct hdlcd_device {
  219463. + struct fb_info fb;
  219464. + struct device *dev;
  219465. + struct clk *clk;
  219466. + void __iomem *base;
  219467. + int irq;
  219468. + struct completion vsync_completion;
  219469. + unsigned char *edid;
  219470. +};
  219471. diff -Nur linux-3.14.15/include/linux/backlight.h linux-linaro-stable-mx6/include/linux/backlight.h
  219472. --- linux-3.14.15/include/linux/backlight.h 2014-07-31 23:51:43.000000000 +0200
  219473. +++ linux-linaro-stable-mx6/include/linux/backlight.h 2014-08-20 19:31:51.980894126 +0200
  219474. @@ -9,6 +9,7 @@
  219475. #define _LINUX_BACKLIGHT_H
  219476. #include <linux/device.h>
  219477. +#include <linux/fb.h>
  219478. #include <linux/mutex.h>
  219479. #include <linux/notifier.h>
  219480. @@ -104,6 +105,11 @@
  219481. struct list_head entry;
  219482. struct device dev;
  219483. +
  219484. + /* Multiple framebuffers may share one backlight device */
  219485. + bool fb_bl_on[FB_MAX];
  219486. +
  219487. + int use_count;
  219488. };
  219489. static inline void backlight_update_status(struct backlight_device *bd)
  219490. diff -Nur linux-3.14.15/include/linux/busfreq-imx6.h linux-linaro-stable-mx6/include/linux/busfreq-imx6.h
  219491. --- linux-3.14.15/include/linux/busfreq-imx6.h 1970-01-01 01:00:00.000000000 +0100
  219492. +++ linux-linaro-stable-mx6/include/linux/busfreq-imx6.h 2014-08-20 19:24:04.606893010 +0200
  219493. @@ -0,0 +1,23 @@
  219494. +/*
  219495. + * Copyright 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  219496. + *
  219497. + * This program is free software; you can redistribute it and/or modify
  219498. + * it under the terms of the GNU General Public License version 2 as
  219499. + * published by the Free Software Foundation.
  219500. + */
  219501. +
  219502. +#ifndef __ASM_ARCH_MXC_BUSFREQ_H__
  219503. +#define __ASM_ARCH_MXC_BUSFREQ_H__
  219504. +
  219505. +/*
  219506. + * This enumerates busfreq mode.
  219507. + */
  219508. +enum bus_freq_mode {
  219509. + BUS_FREQ_HIGH,
  219510. + BUS_FREQ_MED,
  219511. + BUS_FREQ_AUDIO,
  219512. + BUS_FREQ_LOW,
  219513. +};
  219514. +void request_bus_freq(enum bus_freq_mode mode);
  219515. +void release_bus_freq(enum bus_freq_mode mode);
  219516. +#endif
  219517. diff -Nur linux-3.14.15/include/linux/cgroup_subsys.h linux-linaro-stable-mx6/include/linux/cgroup_subsys.h
  219518. --- linux-3.14.15/include/linux/cgroup_subsys.h 2014-07-31 23:51:43.000000000 +0200
  219519. +++ linux-linaro-stable-mx6/include/linux/cgroup_subsys.h 2014-08-20 19:31:52.216895139 +0200
  219520. @@ -39,6 +39,10 @@
  219521. SUBSYS(blkio)
  219522. #endif
  219523. +#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_BFQIO)
  219524. +SUBSYS(bfqio)
  219525. +#endif
  219526. +
  219527. #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_PERF)
  219528. SUBSYS(perf)
  219529. #endif
  219530. diff -Nur linux-3.14.15/include/linux/cpufeature.h linux-linaro-stable-mx6/include/linux/cpufeature.h
  219531. --- linux-3.14.15/include/linux/cpufeature.h 1970-01-01 01:00:00.000000000 +0100
  219532. +++ linux-linaro-stable-mx6/include/linux/cpufeature.h 2014-08-20 19:31:52.252895296 +0200
  219533. @@ -0,0 +1,60 @@
  219534. +/*
  219535. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  219536. + *
  219537. + * This program is free software; you can redistribute it and/or modify
  219538. + * it under the terms of the GNU General Public License version 2 as
  219539. + * published by the Free Software Foundation.
  219540. + */
  219541. +
  219542. +#ifndef __LINUX_CPUFEATURE_H
  219543. +#define __LINUX_CPUFEATURE_H
  219544. +
  219545. +#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
  219546. +
  219547. +#include <linux/mod_devicetable.h>
  219548. +#include <asm/cpufeature.h>
  219549. +
  219550. +/*
  219551. + * Macros imported from <asm/cpufeature.h>:
  219552. + * - cpu_feature(x) ordinal value of feature called 'x'
  219553. + * - cpu_have_feature(u32 n) whether feature #n is available
  219554. + * - MAX_CPU_FEATURES upper bound for feature ordinal values
  219555. + * Optional:
  219556. + * - CPU_FEATURE_TYPEFMT format string fragment for printing the cpu type
  219557. + * - CPU_FEATURE_TYPEVAL set of values matching the format string above
  219558. + */
  219559. +
  219560. +#ifndef CPU_FEATURE_TYPEFMT
  219561. +#define CPU_FEATURE_TYPEFMT "%s"
  219562. +#endif
  219563. +
  219564. +#ifndef CPU_FEATURE_TYPEVAL
  219565. +#define CPU_FEATURE_TYPEVAL ELF_PLATFORM
  219566. +#endif
  219567. +
  219568. +/*
  219569. + * Use module_cpu_feature_match(feature, module_init_function) to
  219570. + * declare that
  219571. + * a) the module shall be probed upon discovery of CPU feature 'feature'
  219572. + * (typically at boot time using udev)
  219573. + * b) the module must not be loaded if CPU feature 'feature' is not present
  219574. + * (not even by manual insmod).
  219575. + *
  219576. + * For a list of legal values for 'feature', please consult the file
  219577. + * 'asm/cpufeature.h' of your favorite architecture.
  219578. + */
  219579. +#define module_cpu_feature_match(x, __init) \
  219580. +static struct cpu_feature const cpu_feature_match_ ## x[] = \
  219581. + { { .feature = cpu_feature(x) }, { } }; \
  219582. +MODULE_DEVICE_TABLE(cpu, cpu_feature_match_ ## x); \
  219583. + \
  219584. +static int cpu_feature_match_ ## x ## _init(void) \
  219585. +{ \
  219586. + if (!cpu_have_feature(cpu_feature(x))) \
  219587. + return -ENODEV; \
  219588. + return __init(); \
  219589. +} \
  219590. +module_init(cpu_feature_match_ ## x ## _init)
  219591. +
  219592. +#endif
  219593. +#endif
  219594. diff -Nur linux-3.14.15/include/linux/cpufreq.h linux-linaro-stable-mx6/include/linux/cpufreq.h
  219595. --- linux-3.14.15/include/linux/cpufreq.h 2014-07-31 23:51:43.000000000 +0200
  219596. +++ linux-linaro-stable-mx6/include/linux/cpufreq.h 2014-08-20 19:31:52.252895296 +0200
  219597. @@ -429,6 +429,9 @@
  219598. #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND)
  219599. extern struct cpufreq_governor cpufreq_gov_ondemand;
  219600. #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_ondemand)
  219601. +#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE)
  219602. +extern struct cpufreq_governor cpufreq_gov_interactive;
  219603. +#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_interactive)
  219604. #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE)
  219605. extern struct cpufreq_governor cpufreq_gov_conservative;
  219606. #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_conservative)
  219607. diff -Nur linux-3.14.15/include/linux/cpu.h linux-linaro-stable-mx6/include/linux/cpu.h
  219608. --- linux-3.14.15/include/linux/cpu.h 2014-07-31 23:51:43.000000000 +0200
  219609. +++ linux-linaro-stable-mx6/include/linux/cpu.h 2014-08-20 19:31:52.248895278 +0200
  219610. @@ -226,4 +226,11 @@
  219611. void arch_cpu_idle_exit(void);
  219612. void arch_cpu_idle_dead(void);
  219613. +#define IDLE_START 1
  219614. +#define IDLE_END 2
  219615. +
  219616. +void idle_notifier_register(struct notifier_block *n);
  219617. +void idle_notifier_unregister(struct notifier_block *n);
  219618. +void idle_notifier_call_chain(unsigned long val);
  219619. +
  219620. #endif /* _LINUX_CPU_H_ */
  219621. diff -Nur linux-3.14.15/include/linux/device_cooling.h linux-linaro-stable-mx6/include/linux/device_cooling.h
  219622. --- linux-3.14.15/include/linux/device_cooling.h 1970-01-01 01:00:00.000000000 +0100
  219623. +++ linux-linaro-stable-mx6/include/linux/device_cooling.h 2014-08-20 19:24:04.638893146 +0200
  219624. @@ -0,0 +1,45 @@
  219625. +/*
  219626. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  219627. + *
  219628. + * This program is free software; you can redistribute it and/or modify
  219629. + * it under the terms of the GNU General Public License version 2 as
  219630. + * published by the Free Software Foundation.
  219631. + *
  219632. + */
  219633. +
  219634. +#ifndef __DEVICE_THERMAL_H__
  219635. +#define __DEVICE_THERMAL_H__
  219636. +
  219637. +#include <linux/thermal.h>
  219638. +
  219639. +#ifdef CONFIG_DEVICE_THERMAL
  219640. +int register_devfreq_cooling_notifier(struct notifier_block *nb);
  219641. +int unregister_devfreq_cooling_notifier(struct notifier_block *nb);
  219642. +struct thermal_cooling_device *devfreq_cooling_register(void);
  219643. +void devfreq_cooling_unregister(struct thermal_cooling_device *cdev);
  219644. +#else
  219645. +static inline
  219646. +int register_devfreq_cooling_notifier(struct notifier_block *nb)
  219647. +{
  219648. + return 0;
  219649. +}
  219650. +
  219651. +static inline
  219652. +int unregister_devfreq_cooling_notifier(struct notifier_block *nb)
  219653. +{
  219654. + return 0;
  219655. +}
  219656. +
  219657. +static inline
  219658. +struct thermal_cooling_device *devfreq_cooling_register(void)
  219659. +{
  219660. + return NULL;
  219661. +}
  219662. +
  219663. +static inline
  219664. +void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
  219665. +{
  219666. + return;
  219667. +}
  219668. +#endif
  219669. +#endif /* __DEVICE_THERMAL_H__ */
  219670. diff -Nur linux-3.14.15/include/linux/dmaengine.h linux-linaro-stable-mx6/include/linux/dmaengine.h
  219671. --- linux-3.14.15/include/linux/dmaengine.h 2014-07-31 23:51:43.000000000 +0200
  219672. +++ linux-linaro-stable-mx6/include/linux/dmaengine.h 2014-08-20 19:31:52.268895363 +0200
  219673. @@ -333,6 +333,8 @@
  219674. * @slave_id: Slave requester id. Only valid for slave channels. The dma
  219675. * slave peripheral will have unique id as dma requester which need to be
  219676. * pass as slave config.
  219677. + * @dma_request0: this is the first dma request of this dma channel.
  219678. + * @dma_request1: this is the second dma request of this dma channel.
  219679. *
  219680. * This struct is passed in as configuration data to a DMA engine
  219681. * in order to set up a certain channel for DMA transport at runtime.
  219682. @@ -361,6 +363,8 @@
  219683. u32 dst_maxburst;
  219684. bool device_fc;
  219685. unsigned int slave_id;
  219686. + int dma_request0;
  219687. + int dma_request1;
  219688. };
  219689. /**
  219690. diff -Nur linux-3.14.15/include/linux/ftrace.h linux-linaro-stable-mx6/include/linux/ftrace.h
  219691. --- linux-3.14.15/include/linux/ftrace.h 2014-07-31 23:51:43.000000000 +0200
  219692. +++ linux-linaro-stable-mx6/include/linux/ftrace.h 2014-08-20 19:31:52.304895518 +0200
  219693. @@ -605,25 +605,27 @@
  219694. #endif
  219695. }
  219696. -#ifndef HAVE_ARCH_CALLER_ADDR
  219697. +/* All archs should have this, but we define it for consistency */
  219698. +#ifndef ftrace_return_address0
  219699. +# define ftrace_return_address0 __builtin_return_address(0)
  219700. +#endif
  219701. +
  219702. +/* Archs may use other ways for ADDR1 and beyond */
  219703. +#ifndef ftrace_return_address
  219704. # ifdef CONFIG_FRAME_POINTER
  219705. -# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  219706. -# define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
  219707. -# define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
  219708. -# define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
  219709. -# define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
  219710. -# define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
  219711. -# define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
  219712. +# define ftrace_return_address(n) __builtin_return_address(n)
  219713. # else
  219714. -# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  219715. -# define CALLER_ADDR1 0UL
  219716. -# define CALLER_ADDR2 0UL
  219717. -# define CALLER_ADDR3 0UL
  219718. -# define CALLER_ADDR4 0UL
  219719. -# define CALLER_ADDR5 0UL
  219720. -# define CALLER_ADDR6 0UL
  219721. +# define ftrace_return_address(n) 0UL
  219722. # endif
  219723. -#endif /* ifndef HAVE_ARCH_CALLER_ADDR */
  219724. +#endif
  219725. +
  219726. +#define CALLER_ADDR0 ((unsigned long)ftrace_return_address0)
  219727. +#define CALLER_ADDR1 ((unsigned long)ftrace_return_address(1))
  219728. +#define CALLER_ADDR2 ((unsigned long)ftrace_return_address(2))
  219729. +#define CALLER_ADDR3 ((unsigned long)ftrace_return_address(3))
  219730. +#define CALLER_ADDR4 ((unsigned long)ftrace_return_address(4))
  219731. +#define CALLER_ADDR5 ((unsigned long)ftrace_return_address(5))
  219732. +#define CALLER_ADDR6 ((unsigned long)ftrace_return_address(6))
  219733. #ifdef CONFIG_IRQSOFF_TRACER
  219734. extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
  219735. diff -Nur linux-3.14.15/include/linux/hardirq.h linux-linaro-stable-mx6/include/linux/hardirq.h
  219736. --- linux-3.14.15/include/linux/hardirq.h 2014-07-31 23:51:43.000000000 +0200
  219737. +++ linux-linaro-stable-mx6/include/linux/hardirq.h 2014-08-20 19:31:52.308895534 +0200
  219738. @@ -9,6 +9,7 @@
  219739. extern void synchronize_irq(unsigned int irq);
  219740. +extern void synchronize_hardirq(unsigned int irq);
  219741. #if defined(CONFIG_TINY_RCU)
  219742. diff -Nur linux-3.14.15/include/linux/hsi/hsi.h linux-linaro-stable-mx6/include/linux/hsi/hsi.h
  219743. --- linux-3.14.15/include/linux/hsi/hsi.h 2014-07-31 23:51:43.000000000 +0200
  219744. +++ linux-linaro-stable-mx6/include/linux/hsi/hsi.h 2014-08-20 19:31:52.316895570 +0200
  219745. @@ -178,7 +178,7 @@
  219746. * @complete: Transfer completion callback
  219747. * @destructor: Destructor to free resources when flushing
  219748. * @status: Status of the transfer when completed
  219749. - * @actual_len: Actual length of data transfered on completion
  219750. + * @actual_len: Actual length of data transferred on completion
  219751. * @channel: Channel were to TX/RX the message
  219752. * @ttype: Transfer type (TX if set, RX otherwise)
  219753. * @break_frame: if true HSI will send/receive a break frame. Data buffers are
  219754. diff -Nur linux-3.14.15/include/linux/ipu.h linux-linaro-stable-mx6/include/linux/ipu.h
  219755. --- linux-3.14.15/include/linux/ipu.h 1970-01-01 01:00:00.000000000 +0100
  219756. +++ linux-linaro-stable-mx6/include/linux/ipu.h 2014-08-20 19:24:04.734893555 +0200
  219757. @@ -0,0 +1,38 @@
  219758. +/*
  219759. + * Copyright 2005-2013 Freescale Semiconductor, Inc.
  219760. + */
  219761. +
  219762. +/*
  219763. + * The code contained herein is licensed under the GNU Lesser General
  219764. + * Public License. You may obtain a copy of the GNU Lesser General
  219765. + * Public License Version 2.1 or later at the following locations:
  219766. + *
  219767. + * http://www.opensource.org/licenses/lgpl-license.html
  219768. + * http://www.gnu.org/copyleft/lgpl.html
  219769. + */
  219770. +
  219771. +/*!
  219772. + * @defgroup IPU MXC Image Processing Unit (IPU) Driver
  219773. + */
  219774. +/*!
  219775. + * @file linux/ipu.h
  219776. + *
  219777. + * @brief This file contains the IPU driver API declarations.
  219778. + *
  219779. + * @ingroup IPU
  219780. + */
  219781. +
  219782. +#ifndef __LINUX_IPU_H__
  219783. +#define __LINUX_IPU_H__
  219784. +
  219785. +#include <linux/interrupt.h>
  219786. +#include <uapi/linux/ipu.h>
  219787. +
  219788. +unsigned int fmt_to_bpp(unsigned int pixelformat);
  219789. +cs_t colorspaceofpixel(int fmt);
  219790. +int need_csc(int ifmt, int ofmt);
  219791. +
  219792. +int ipu_queue_task(struct ipu_task *task);
  219793. +int ipu_check_task(struct ipu_task *task);
  219794. +
  219795. +#endif
  219796. diff -Nur linux-3.14.15/include/linux/ipu-v3.h linux-linaro-stable-mx6/include/linux/ipu-v3.h
  219797. --- linux-3.14.15/include/linux/ipu-v3.h 1970-01-01 01:00:00.000000000 +0100
  219798. +++ linux-linaro-stable-mx6/include/linux/ipu-v3.h 2014-08-20 19:24:04.734893555 +0200
  219799. @@ -0,0 +1,752 @@
  219800. +/*
  219801. + * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
  219802. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  219803. + *
  219804. + * This program is free software; you can redistribute it and/or modify it
  219805. + * under the terms of the GNU General Public License as published by the
  219806. + * Free Software Foundation; either version 2 of the License, or (at your
  219807. + * option) any later version.
  219808. + *
  219809. + * This program is distributed in the hope that it will be useful, but
  219810. + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  219811. + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  219812. + * for more details.
  219813. + */
  219814. +
  219815. +#ifndef __LINUX_IPU_V3_H_
  219816. +#define __LINUX_IPU_V3_H_
  219817. +
  219818. +#include <linux/ipu.h>
  219819. +
  219820. +/* IPU Driver channels definitions. */
  219821. +/* Note these are different from IDMA channels */
  219822. +#define IPU_MAX_CH 32
  219823. +#define _MAKE_CHAN(num, v_in, g_in, a_in, out) \
  219824. + ((num << 24) | (v_in << 18) | (g_in << 12) | (a_in << 6) | out)
  219825. +#define _MAKE_ALT_CHAN(ch) (ch | (IPU_MAX_CH << 24))
  219826. +#define IPU_CHAN_ID(ch) (ch >> 24)
  219827. +#define IPU_CHAN_ALT(ch) (ch & 0x02000000)
  219828. +#define IPU_CHAN_ALPHA_IN_DMA(ch) ((uint32_t) (ch >> 6) & 0x3F)
  219829. +#define IPU_CHAN_GRAPH_IN_DMA(ch) ((uint32_t) (ch >> 12) & 0x3F)
  219830. +#define IPU_CHAN_VIDEO_IN_DMA(ch) ((uint32_t) (ch >> 18) & 0x3F)
  219831. +#define IPU_CHAN_OUT_DMA(ch) ((uint32_t) (ch & 0x3F))
  219832. +#define NO_DMA 0x3F
  219833. +#define ALT 1
  219834. +/*!
  219835. + * Enumeration of IPU logical channels. An IPU logical channel is defined as a
  219836. + * combination of an input (memory to IPU), output (IPU to memory), and/or
  219837. + * secondary input IDMA channels and in some cases an Image Converter task.
  219838. + * Some channels consist of only an input or output.
  219839. + */
  219840. +typedef enum {
  219841. + CHAN_NONE = -1,
  219842. + MEM_ROT_ENC_MEM = _MAKE_CHAN(1, 45, NO_DMA, NO_DMA, 48),
  219843. + MEM_ROT_VF_MEM = _MAKE_CHAN(2, 46, NO_DMA, NO_DMA, 49),
  219844. + MEM_ROT_PP_MEM = _MAKE_CHAN(3, 47, NO_DMA, NO_DMA, 50),
  219845. +
  219846. + MEM_PRP_ENC_MEM = _MAKE_CHAN(4, 12, 14, 17, 20),
  219847. + MEM_PRP_VF_MEM = _MAKE_CHAN(5, 12, 14, 17, 21),
  219848. + MEM_PP_MEM = _MAKE_CHAN(6, 11, 15, 18, 22),
  219849. +
  219850. + MEM_DC_SYNC = _MAKE_CHAN(7, 28, NO_DMA, NO_DMA, NO_DMA),
  219851. + MEM_DC_ASYNC = _MAKE_CHAN(8, 41, NO_DMA, NO_DMA, NO_DMA),
  219852. + MEM_BG_SYNC = _MAKE_CHAN(9, 23, NO_DMA, 51, NO_DMA),
  219853. + MEM_FG_SYNC = _MAKE_CHAN(10, 27, NO_DMA, 31, NO_DMA),
  219854. +
  219855. + MEM_BG_ASYNC0 = _MAKE_CHAN(11, 24, NO_DMA, 52, NO_DMA),
  219856. + MEM_FG_ASYNC0 = _MAKE_CHAN(12, 29, NO_DMA, 33, NO_DMA),
  219857. + MEM_BG_ASYNC1 = _MAKE_ALT_CHAN(MEM_BG_ASYNC0),
  219858. + MEM_FG_ASYNC1 = _MAKE_ALT_CHAN(MEM_FG_ASYNC0),
  219859. +
  219860. + DIRECT_ASYNC0 = _MAKE_CHAN(13, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
  219861. + DIRECT_ASYNC1 = _MAKE_CHAN(14, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
  219862. +
  219863. + CSI_MEM0 = _MAKE_CHAN(15, NO_DMA, NO_DMA, NO_DMA, 0),
  219864. + CSI_MEM1 = _MAKE_CHAN(16, NO_DMA, NO_DMA, NO_DMA, 1),
  219865. + CSI_MEM2 = _MAKE_CHAN(17, NO_DMA, NO_DMA, NO_DMA, 2),
  219866. + CSI_MEM3 = _MAKE_CHAN(18, NO_DMA, NO_DMA, NO_DMA, 3),
  219867. +
  219868. + CSI_MEM = CSI_MEM0,
  219869. +
  219870. + CSI_PRP_ENC_MEM = _MAKE_CHAN(19, NO_DMA, NO_DMA, NO_DMA, 20),
  219871. + CSI_PRP_VF_MEM = _MAKE_CHAN(20, NO_DMA, NO_DMA, NO_DMA, 21),
  219872. +
  219873. + /* for vdi mem->vdi->ic->mem , add graphics plane and alpha*/
  219874. + MEM_VDI_PRP_VF_MEM_P = _MAKE_CHAN(21, 8, 14, 17, 21),
  219875. + MEM_VDI_PRP_VF_MEM = _MAKE_CHAN(22, 9, 14, 17, 21),
  219876. + MEM_VDI_PRP_VF_MEM_N = _MAKE_CHAN(23, 10, 14, 17, 21),
  219877. +
  219878. + /* for vdi mem->vdi->mem */
  219879. + MEM_VDI_MEM_P = _MAKE_CHAN(24, 8, NO_DMA, NO_DMA, 5),
  219880. + MEM_VDI_MEM = _MAKE_CHAN(25, 9, NO_DMA, NO_DMA, 5),
  219881. + MEM_VDI_MEM_N = _MAKE_CHAN(26, 10, NO_DMA, NO_DMA, 5),
  219882. +
  219883. + /* fake channel for vdoa to link with IPU */
  219884. + MEM_VDOA_MEM = _MAKE_CHAN(27, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
  219885. +
  219886. + MEM_PP_ADC = CHAN_NONE,
  219887. + ADC_SYS2 = CHAN_NONE,
  219888. +
  219889. +} ipu_channel_t;
  219890. +
  219891. +/*!
  219892. + * Enumeration of types of buffers for a logical channel.
  219893. + */
  219894. +typedef enum {
  219895. + IPU_OUTPUT_BUFFER = 0, /*!< Buffer for output from IPU */
  219896. + IPU_ALPHA_IN_BUFFER = 1, /*!< Buffer for input to IPU */
  219897. + IPU_GRAPH_IN_BUFFER = 2, /*!< Buffer for input to IPU */
  219898. + IPU_VIDEO_IN_BUFFER = 3, /*!< Buffer for input to IPU */
  219899. + IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER,
  219900. + IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER,
  219901. +} ipu_buffer_t;
  219902. +
  219903. +#define IPU_PANEL_SERIAL 1
  219904. +#define IPU_PANEL_PARALLEL 2
  219905. +
  219906. +/*!
  219907. + * Enumeration of ADC channel operation mode.
  219908. + */
  219909. +typedef enum {
  219910. + Disable,
  219911. + WriteTemplateNonSeq,
  219912. + ReadTemplateNonSeq,
  219913. + WriteTemplateUnCon,
  219914. + ReadTemplateUnCon,
  219915. + WriteDataWithRS,
  219916. + WriteDataWoRS,
  219917. + WriteCmd
  219918. +} mcu_mode_t;
  219919. +
  219920. +/*!
  219921. + * Enumeration of ADC channel addressing mode.
  219922. + */
  219923. +typedef enum {
  219924. + FullWoBE,
  219925. + FullWithBE,
  219926. + XY
  219927. +} display_addressing_t;
  219928. +
  219929. +/*!
  219930. + * Union of initialization parameters for a logical channel.
  219931. + */
  219932. +typedef union {
  219933. + struct {
  219934. + uint32_t csi;
  219935. + uint32_t mipi_id;
  219936. + uint32_t mipi_vc;
  219937. + bool mipi_en;
  219938. + bool interlaced;
  219939. + } csi_mem;
  219940. + struct {
  219941. + uint32_t in_width;
  219942. + uint32_t in_height;
  219943. + uint32_t in_pixel_fmt;
  219944. + uint32_t out_width;
  219945. + uint32_t out_height;
  219946. + uint32_t out_pixel_fmt;
  219947. + uint32_t outh_resize_ratio;
  219948. + uint32_t outv_resize_ratio;
  219949. + uint32_t csi;
  219950. + uint32_t mipi_id;
  219951. + uint32_t mipi_vc;
  219952. + bool mipi_en;
  219953. + } csi_prp_enc_mem;
  219954. + struct {
  219955. + uint32_t in_width;
  219956. + uint32_t in_height;
  219957. + uint32_t in_pixel_fmt;
  219958. + uint32_t out_width;
  219959. + uint32_t out_height;
  219960. + uint32_t out_pixel_fmt;
  219961. + uint32_t outh_resize_ratio;
  219962. + uint32_t outv_resize_ratio;
  219963. + } mem_prp_enc_mem;
  219964. + struct {
  219965. + uint32_t in_width;
  219966. + uint32_t in_height;
  219967. + uint32_t in_pixel_fmt;
  219968. + uint32_t out_width;
  219969. + uint32_t out_height;
  219970. + uint32_t out_pixel_fmt;
  219971. + } mem_rot_enc_mem;
  219972. + struct {
  219973. + uint32_t in_width;
  219974. + uint32_t in_height;
  219975. + uint32_t in_pixel_fmt;
  219976. + uint32_t out_width;
  219977. + uint32_t out_height;
  219978. + uint32_t out_pixel_fmt;
  219979. + uint32_t outh_resize_ratio;
  219980. + uint32_t outv_resize_ratio;
  219981. + bool graphics_combine_en;
  219982. + bool global_alpha_en;
  219983. + bool key_color_en;
  219984. + uint32_t in_g_pixel_fmt;
  219985. + uint8_t alpha;
  219986. + uint32_t key_color;
  219987. + bool alpha_chan_en;
  219988. + ipu_motion_sel motion_sel;
  219989. + enum v4l2_field field_fmt;
  219990. + uint32_t csi;
  219991. + uint32_t mipi_id;
  219992. + uint32_t mipi_vc;
  219993. + bool mipi_en;
  219994. + } csi_prp_vf_mem;
  219995. + struct {
  219996. + uint32_t in_width;
  219997. + uint32_t in_height;
  219998. + uint32_t in_pixel_fmt;
  219999. + uint32_t out_width;
  220000. + uint32_t out_height;
  220001. + uint32_t out_pixel_fmt;
  220002. + bool graphics_combine_en;
  220003. + bool global_alpha_en;
  220004. + bool key_color_en;
  220005. + display_port_t disp;
  220006. + uint32_t out_left;
  220007. + uint32_t out_top;
  220008. + } csi_prp_vf_adc;
  220009. + struct {
  220010. + uint32_t in_width;
  220011. + uint32_t in_height;
  220012. + uint32_t in_pixel_fmt;
  220013. + uint32_t out_width;
  220014. + uint32_t out_height;
  220015. + uint32_t out_pixel_fmt;
  220016. + uint32_t outh_resize_ratio;
  220017. + uint32_t outv_resize_ratio;
  220018. + bool graphics_combine_en;
  220019. + bool global_alpha_en;
  220020. + bool key_color_en;
  220021. + uint32_t in_g_pixel_fmt;
  220022. + uint8_t alpha;
  220023. + uint32_t key_color;
  220024. + bool alpha_chan_en;
  220025. + ipu_motion_sel motion_sel;
  220026. + enum v4l2_field field_fmt;
  220027. + } mem_prp_vf_mem;
  220028. + struct {
  220029. + uint32_t temp;
  220030. + } mem_prp_vf_adc;
  220031. + struct {
  220032. + uint32_t temp;
  220033. + } mem_rot_vf_mem;
  220034. + struct {
  220035. + uint32_t in_width;
  220036. + uint32_t in_height;
  220037. + uint32_t in_pixel_fmt;
  220038. + uint32_t out_width;
  220039. + uint32_t out_height;
  220040. + uint32_t out_pixel_fmt;
  220041. + uint32_t outh_resize_ratio;
  220042. + uint32_t outv_resize_ratio;
  220043. + bool graphics_combine_en;
  220044. + bool global_alpha_en;
  220045. + bool key_color_en;
  220046. + uint32_t in_g_pixel_fmt;
  220047. + uint8_t alpha;
  220048. + uint32_t key_color;
  220049. + bool alpha_chan_en;
  220050. + } mem_pp_mem;
  220051. + struct {
  220052. + uint32_t temp;
  220053. + } mem_rot_mem;
  220054. + struct {
  220055. + uint32_t in_width;
  220056. + uint32_t in_height;
  220057. + uint32_t in_pixel_fmt;
  220058. + uint32_t out_width;
  220059. + uint32_t out_height;
  220060. + uint32_t out_pixel_fmt;
  220061. + bool graphics_combine_en;
  220062. + bool global_alpha_en;
  220063. + bool key_color_en;
  220064. + display_port_t disp;
  220065. + uint32_t out_left;
  220066. + uint32_t out_top;
  220067. + } mem_pp_adc;
  220068. + struct {
  220069. + uint32_t di;
  220070. + bool interlaced;
  220071. + uint32_t in_pixel_fmt;
  220072. + uint32_t out_pixel_fmt;
  220073. + } mem_dc_sync;
  220074. + struct {
  220075. + uint32_t temp;
  220076. + } mem_sdc_fg;
  220077. + struct {
  220078. + uint32_t di;
  220079. + bool interlaced;
  220080. + uint32_t in_pixel_fmt;
  220081. + uint32_t out_pixel_fmt;
  220082. + bool alpha_chan_en;
  220083. + } mem_dp_bg_sync;
  220084. + struct {
  220085. + uint32_t temp;
  220086. + } mem_sdc_bg;
  220087. + struct {
  220088. + uint32_t di;
  220089. + bool interlaced;
  220090. + uint32_t in_pixel_fmt;
  220091. + uint32_t out_pixel_fmt;
  220092. + bool alpha_chan_en;
  220093. + } mem_dp_fg_sync;
  220094. + struct {
  220095. + uint32_t di;
  220096. + } direct_async;
  220097. + struct {
  220098. + display_port_t disp;
  220099. + mcu_mode_t ch_mode;
  220100. + uint32_t out_left;
  220101. + uint32_t out_top;
  220102. + } adc_sys1;
  220103. + struct {
  220104. + display_port_t disp;
  220105. + mcu_mode_t ch_mode;
  220106. + uint32_t out_left;
  220107. + uint32_t out_top;
  220108. + } adc_sys2;
  220109. +} ipu_channel_params_t;
  220110. +
  220111. +/*
  220112. + * IPU_IRQF_ONESHOT - Interrupt is not reenabled after the irq handler finished.
  220113. + */
  220114. +#define IPU_IRQF_NONE 0x00000000
  220115. +#define IPU_IRQF_ONESHOT 0x00000001
  220116. +
  220117. +/*!
  220118. + * Enumeration of IPU interrupt sources.
  220119. + */
  220120. +enum ipu_irq_line {
  220121. + IPU_IRQ_CSI0_OUT_EOF = 0,
  220122. + IPU_IRQ_CSI1_OUT_EOF = 1,
  220123. + IPU_IRQ_CSI2_OUT_EOF = 2,
  220124. + IPU_IRQ_CSI3_OUT_EOF = 3,
  220125. + IPU_IRQ_VDIC_OUT_EOF = 5,
  220126. + IPU_IRQ_VDI_P_IN_EOF = 8,
  220127. + IPU_IRQ_VDI_C_IN_EOF = 9,
  220128. + IPU_IRQ_VDI_N_IN_EOF = 10,
  220129. + IPU_IRQ_PP_IN_EOF = 11,
  220130. + IPU_IRQ_PRP_IN_EOF = 12,
  220131. + IPU_IRQ_PRP_GRAPH_IN_EOF = 14,
  220132. + IPU_IRQ_PP_GRAPH_IN_EOF = 15,
  220133. + IPU_IRQ_PRP_ALPHA_IN_EOF = 17,
  220134. + IPU_IRQ_PP_ALPHA_IN_EOF = 18,
  220135. + IPU_IRQ_PRP_ENC_OUT_EOF = 20,
  220136. + IPU_IRQ_PRP_VF_OUT_EOF = 21,
  220137. + IPU_IRQ_PP_OUT_EOF = 22,
  220138. + IPU_IRQ_BG_SYNC_EOF = 23,
  220139. + IPU_IRQ_BG_ASYNC_EOF = 24,
  220140. + IPU_IRQ_FG_SYNC_EOF = 27,
  220141. + IPU_IRQ_DC_SYNC_EOF = 28,
  220142. + IPU_IRQ_FG_ASYNC_EOF = 29,
  220143. + IPU_IRQ_FG_ALPHA_SYNC_EOF = 31,
  220144. +
  220145. + IPU_IRQ_FG_ALPHA_ASYNC_EOF = 33,
  220146. + IPU_IRQ_DC_READ_EOF = 40,
  220147. + IPU_IRQ_DC_ASYNC_EOF = 41,
  220148. + IPU_IRQ_DC_CMD1_EOF = 42,
  220149. + IPU_IRQ_DC_CMD2_EOF = 43,
  220150. + IPU_IRQ_DC_MASK_EOF = 44,
  220151. + IPU_IRQ_PRP_ENC_ROT_IN_EOF = 45,
  220152. + IPU_IRQ_PRP_VF_ROT_IN_EOF = 46,
  220153. + IPU_IRQ_PP_ROT_IN_EOF = 47,
  220154. + IPU_IRQ_PRP_ENC_ROT_OUT_EOF = 48,
  220155. + IPU_IRQ_PRP_VF_ROT_OUT_EOF = 49,
  220156. + IPU_IRQ_PP_ROT_OUT_EOF = 50,
  220157. + IPU_IRQ_BG_ALPHA_SYNC_EOF = 51,
  220158. + IPU_IRQ_BG_ALPHA_ASYNC_EOF = 52,
  220159. +
  220160. + IPU_IRQ_BG_SYNC_NFACK = 64 + 23,
  220161. + IPU_IRQ_FG_SYNC_NFACK = 64 + 27,
  220162. + IPU_IRQ_DC_SYNC_NFACK = 64 + 28,
  220163. +
  220164. + IPU_IRQ_DP_SF_START = 448 + 2,
  220165. + IPU_IRQ_DP_SF_END = 448 + 3,
  220166. + IPU_IRQ_BG_SF_END = IPU_IRQ_DP_SF_END,
  220167. + IPU_IRQ_DC_FC_0 = 448 + 8,
  220168. + IPU_IRQ_DC_FC_1 = 448 + 9,
  220169. + IPU_IRQ_DC_FC_2 = 448 + 10,
  220170. + IPU_IRQ_DC_FC_3 = 448 + 11,
  220171. + IPU_IRQ_DC_FC_4 = 448 + 12,
  220172. + IPU_IRQ_DC_FC_6 = 448 + 13,
  220173. + IPU_IRQ_VSYNC_PRE_0 = 448 + 14,
  220174. + IPU_IRQ_VSYNC_PRE_1 = 448 + 15,
  220175. +
  220176. + IPU_IRQ_COUNT
  220177. +};
  220178. +
  220179. +/*!
  220180. + * Bitfield of Display Interface signal polarities.
  220181. + */
  220182. +typedef struct {
  220183. + unsigned datamask_en:1;
  220184. + unsigned int_clk:1;
  220185. + unsigned interlaced:1;
  220186. + unsigned odd_field_first:1;
  220187. + unsigned clksel_en:1;
  220188. + unsigned clkidle_en:1;
  220189. + unsigned data_pol:1; /* true = inverted */
  220190. + unsigned clk_pol:1; /* true = rising edge */
  220191. + unsigned enable_pol:1;
  220192. + unsigned Hsync_pol:1; /* true = active high */
  220193. + unsigned Vsync_pol:1;
  220194. +} ipu_di_signal_cfg_t;
  220195. +
  220196. +/*!
  220197. + * Bitfield of CSI signal polarities and modes.
  220198. + */
  220199. +
  220200. +typedef struct {
  220201. + unsigned data_width:4;
  220202. + unsigned clk_mode:3;
  220203. + unsigned ext_vsync:1;
  220204. + unsigned Vsync_pol:1;
  220205. + unsigned Hsync_pol:1;
  220206. + unsigned pixclk_pol:1;
  220207. + unsigned data_pol:1;
  220208. + unsigned sens_clksrc:1;
  220209. + unsigned pack_tight:1;
  220210. + unsigned force_eof:1;
  220211. + unsigned data_en_pol:1;
  220212. + unsigned data_fmt;
  220213. + unsigned csi;
  220214. + unsigned mclk;
  220215. +} ipu_csi_signal_cfg_t;
  220216. +
  220217. +/*!
  220218. + * Enumeration of CSI data bus widths.
  220219. + */
  220220. +enum {
  220221. + IPU_CSI_DATA_WIDTH_4 = 0,
  220222. + IPU_CSI_DATA_WIDTH_8 = 1,
  220223. + IPU_CSI_DATA_WIDTH_10 = 3,
  220224. + IPU_CSI_DATA_WIDTH_16 = 9,
  220225. +};
  220226. +
  220227. +/*!
  220228. + * Enumeration of CSI clock modes.
  220229. + */
  220230. +enum {
  220231. + IPU_CSI_CLK_MODE_GATED_CLK,
  220232. + IPU_CSI_CLK_MODE_NONGATED_CLK,
  220233. + IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE,
  220234. + IPU_CSI_CLK_MODE_CCIR656_INTERLACED,
  220235. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR,
  220236. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR,
  220237. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR,
  220238. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR,
  220239. +};
  220240. +
  220241. +enum {
  220242. + IPU_CSI_MIPI_DI0,
  220243. + IPU_CSI_MIPI_DI1,
  220244. + IPU_CSI_MIPI_DI2,
  220245. + IPU_CSI_MIPI_DI3,
  220246. +};
  220247. +
  220248. +typedef enum {
  220249. + RGB,
  220250. + YCbCr,
  220251. + YUV
  220252. +} ipu_color_space_t;
  220253. +
  220254. +/*!
  220255. + * Enumeration of ADC vertical sync mode.
  220256. + */
  220257. +typedef enum {
  220258. + VsyncNone,
  220259. + VsyncInternal,
  220260. + VsyncCSI,
  220261. + VsyncExternal
  220262. +} vsync_t;
  220263. +
  220264. +typedef enum {
  220265. + DAT,
  220266. + CMD
  220267. +} cmddata_t;
  220268. +
  220269. +/*!
  220270. + * Enumeration of ADC display update mode.
  220271. + */
  220272. +typedef enum {
  220273. + IPU_ADC_REFRESH_NONE,
  220274. + IPU_ADC_AUTO_REFRESH,
  220275. + IPU_ADC_AUTO_REFRESH_SNOOP,
  220276. + IPU_ADC_SNOOPING,
  220277. +} ipu_adc_update_mode_t;
  220278. +
  220279. +/*!
  220280. + * Enumeration of ADC display interface types (serial or parallel).
  220281. + */
  220282. +enum {
  220283. + IPU_ADC_IFC_MODE_SYS80_TYPE1,
  220284. + IPU_ADC_IFC_MODE_SYS80_TYPE2,
  220285. + IPU_ADC_IFC_MODE_SYS68K_TYPE1,
  220286. + IPU_ADC_IFC_MODE_SYS68K_TYPE2,
  220287. + IPU_ADC_IFC_MODE_3WIRE_SERIAL,
  220288. + IPU_ADC_IFC_MODE_4WIRE_SERIAL,
  220289. + IPU_ADC_IFC_MODE_5WIRE_SERIAL_CLK,
  220290. + IPU_ADC_IFC_MODE_5WIRE_SERIAL_CS,
  220291. +};
  220292. +
  220293. +enum {
  220294. + IPU_ADC_IFC_WIDTH_8,
  220295. + IPU_ADC_IFC_WIDTH_16,
  220296. +};
  220297. +
  220298. +/*!
  220299. + * Enumeration of ADC display interface burst mode.
  220300. + */
  220301. +enum {
  220302. + IPU_ADC_BURST_WCS,
  220303. + IPU_ADC_BURST_WBLCK,
  220304. + IPU_ADC_BURST_NONE,
  220305. + IPU_ADC_BURST_SERIAL,
  220306. +};
  220307. +
  220308. +/*!
  220309. + * Enumeration of ADC display interface RW signal timing modes.
  220310. + */
  220311. +enum {
  220312. + IPU_ADC_SER_NO_RW,
  220313. + IPU_ADC_SER_RW_BEFORE_RS,
  220314. + IPU_ADC_SER_RW_AFTER_RS,
  220315. +};
  220316. +
  220317. +/*!
  220318. + * Bitfield of ADC signal polarities and modes.
  220319. + */
  220320. +typedef struct {
  220321. + unsigned data_pol:1;
  220322. + unsigned clk_pol:1;
  220323. + unsigned cs_pol:1;
  220324. + unsigned rs_pol:1;
  220325. + unsigned addr_pol:1;
  220326. + unsigned read_pol:1;
  220327. + unsigned write_pol:1;
  220328. + unsigned Vsync_pol:1;
  220329. + unsigned burst_pol:1;
  220330. + unsigned burst_mode:2;
  220331. + unsigned ifc_mode:3;
  220332. + unsigned ifc_width:5;
  220333. + unsigned ser_preamble_len:4;
  220334. + unsigned ser_preamble:8;
  220335. + unsigned ser_rw_mode:2;
  220336. +} ipu_adc_sig_cfg_t;
  220337. +
  220338. +/*!
  220339. + * Enumeration of ADC template commands.
  220340. + */
  220341. +enum {
  220342. + RD_DATA,
  220343. + RD_ACK,
  220344. + RD_WAIT,
  220345. + WR_XADDR,
  220346. + WR_YADDR,
  220347. + WR_ADDR,
  220348. + WR_CMND,
  220349. + WR_DATA,
  220350. +};
  220351. +
  220352. +/*!
  220353. + * Enumeration of ADC template command flow control.
  220354. + */
  220355. +enum {
  220356. + SINGLE_STEP,
  220357. + PAUSE,
  220358. + STOP,
  220359. +};
  220360. +
  220361. +
  220362. +/*Define template constants*/
  220363. +#define ATM_ADDR_RANGE 0x20 /*offset address of DISP */
  220364. +#define TEMPLATE_BUF_SIZE 0x20 /*size of template */
  220365. +
  220366. +/*!
  220367. + * Define to create ADC template command entry.
  220368. + */
  220369. +#define ipu_adc_template_gen(oc, rs, fc, dat) (((rs) << 29) | ((fc) << 27) | \
  220370. + ((oc) << 24) | (dat))
  220371. +
  220372. +typedef struct {
  220373. + u32 reg;
  220374. + u32 value;
  220375. +} ipu_lpmc_reg_t;
  220376. +
  220377. +#define IPU_LPMC_REG_READ 0x80000000L
  220378. +
  220379. +#define CSI_MCLK_VF 1
  220380. +#define CSI_MCLK_ENC 2
  220381. +#define CSI_MCLK_RAW 4
  220382. +#define CSI_MCLK_I2C 8
  220383. +
  220384. +struct ipu_soc;
  220385. +/* Common IPU API */
  220386. +struct ipu_soc *ipu_get_soc(int id);
  220387. +int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params);
  220388. +void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel);
  220389. +void ipu_disable_hsp_clk(struct ipu_soc *ipu);
  220390. +
  220391. +static inline bool ipu_can_rotate_in_place(ipu_rotate_mode_t rot)
  220392. +{
  220393. +#ifdef CONFIG_MXC_IPU_V3D
  220394. + return (rot < IPU_ROTATE_HORIZ_FLIP);
  220395. +#else
  220396. + return (rot < IPU_ROTATE_90_RIGHT);
  220397. +#endif
  220398. +}
  220399. +
  220400. +int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  220401. + uint32_t pixel_fmt,
  220402. + uint16_t width, uint16_t height,
  220403. + uint32_t stride,
  220404. + ipu_rotate_mode_t rot_mode,
  220405. + dma_addr_t phyaddr_0, dma_addr_t phyaddr_1,
  220406. + dma_addr_t phyaddr_2,
  220407. + uint32_t u_offset, uint32_t v_offset);
  220408. +
  220409. +int32_t ipu_update_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  220410. + uint32_t bufNum, dma_addr_t phyaddr);
  220411. +
  220412. +int32_t ipu_update_channel_offset(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  220413. + uint32_t pixel_fmt,
  220414. + uint16_t width, uint16_t height,
  220415. + uint32_t stride,
  220416. + uint32_t u, uint32_t v,
  220417. + uint32_t vertical_offset, uint32_t horizontal_offset);
  220418. +
  220419. +int32_t ipu_select_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  220420. + ipu_buffer_t type, uint32_t bufNum);
  220421. +int32_t ipu_select_multi_vdi_buffer(struct ipu_soc *ipu, uint32_t bufNum);
  220422. +
  220423. +int32_t ipu_link_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch);
  220424. +int32_t ipu_unlink_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch);
  220425. +
  220426. +int32_t ipu_is_channel_busy(struct ipu_soc *ipu, ipu_channel_t channel);
  220427. +int32_t ipu_check_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  220428. + uint32_t bufNum);
  220429. +void ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  220430. + uint32_t bufNum);
  220431. +uint32_t ipu_get_cur_buffer_idx(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type);
  220432. +int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel);
  220433. +int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wait_for_stop);
  220434. +int32_t ipu_swap_channel(struct ipu_soc *ipu, ipu_channel_t from_ch, ipu_channel_t to_ch);
  220435. +uint32_t ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel);
  220436. +
  220437. +int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi);
  220438. +int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi);
  220439. +
  220440. +int ipu_lowpwr_display_enable(void);
  220441. +int ipu_lowpwr_display_disable(void);
  220442. +
  220443. +int ipu_enable_irq(struct ipu_soc *ipu, uint32_t irq);
  220444. +void ipu_disable_irq(struct ipu_soc *ipu, uint32_t irq);
  220445. +void ipu_clear_irq(struct ipu_soc *ipu, uint32_t irq);
  220446. +int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
  220447. + irqreturn_t(*handler) (int, void *),
  220448. + uint32_t irq_flags, const char *devname, void *dev_id);
  220449. +void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id);
  220450. +bool ipu_get_irq_status(struct ipu_soc *ipu, uint32_t irq);
  220451. +void ipu_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]);
  220452. +int32_t ipu_set_channel_bandmode(struct ipu_soc *ipu, ipu_channel_t channel,
  220453. + ipu_buffer_t type, uint32_t band_height);
  220454. +
  220455. +/* two stripe calculations */
  220456. +struct stripe_param{
  220457. + unsigned int input_width; /* width of the input stripe */
  220458. + unsigned int output_width; /* width of the output stripe */
  220459. + unsigned int input_column; /* the first column on the input stripe */
  220460. + unsigned int output_column; /* the first column on the output stripe */
  220461. + unsigned int idr;
  220462. + /* inverse downisizing ratio parameter; expressed as a power of 2 */
  220463. + unsigned int irr;
  220464. + /* inverse resizing ratio parameter; expressed as a multiple of 2^-13 */
  220465. +};
  220466. +int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
  220467. + unsigned int output_frame_width,
  220468. + const unsigned int maximal_stripe_width,
  220469. + const unsigned long long cirr,
  220470. + const unsigned int equal_stripes,
  220471. + u32 input_pixelformat,
  220472. + u32 output_pixelformat,
  220473. + struct stripe_param *left,
  220474. + struct stripe_param *right);
  220475. +
  220476. +/* SDC API */
  220477. +int32_t ipu_init_sync_panel(struct ipu_soc *ipu, int disp,
  220478. + uint32_t pixel_clk,
  220479. + uint16_t width, uint16_t height,
  220480. + uint32_t pixel_fmt,
  220481. + uint16_t h_start_width, uint16_t h_sync_width,
  220482. + uint16_t h_end_width, uint16_t v_start_width,
  220483. + uint16_t v_sync_width, uint16_t v_end_width,
  220484. + uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig);
  220485. +
  220486. +void ipu_uninit_sync_panel(struct ipu_soc *ipu, int disp);
  220487. +
  220488. +int32_t ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, int16_t x_pos,
  220489. + int16_t y_pos);
  220490. +int32_t ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, int16_t *x_pos,
  220491. + int16_t *y_pos);
  220492. +int32_t ipu_disp_set_global_alpha(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
  220493. + uint8_t alpha);
  220494. +int32_t ipu_disp_set_color_key(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
  220495. + uint32_t colorKey);
  220496. +int32_t ipu_disp_set_gamma_correction(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
  220497. + int constk[], int slopek[]);
  220498. +
  220499. +int ipu_init_async_panel(struct ipu_soc *ipu, int disp, int type, uint32_t cycle_time,
  220500. + uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig);
  220501. +void ipu_disp_direct_write(struct ipu_soc *ipu, ipu_channel_t channel, u32 value, u32 offset);
  220502. +void ipu_reset_disp_panel(struct ipu_soc *ipu);
  220503. +
  220504. +/* CMOS Sensor Interface API */
  220505. +int32_t ipu_csi_init_interface(struct ipu_soc *ipu, uint16_t width, uint16_t height,
  220506. + uint32_t pixel_fmt, ipu_csi_signal_cfg_t sig);
  220507. +
  220508. +int32_t ipu_csi_get_sensor_protocol(struct ipu_soc *ipu, uint32_t csi);
  220509. +
  220510. +int32_t ipu_csi_enable_mclk(struct ipu_soc *ipu, int src, bool flag, bool wait);
  220511. +
  220512. +static inline int32_t ipu_csi_enable_mclk_if(struct ipu_soc *ipu, int src, uint32_t csi,
  220513. + bool flag, bool wait)
  220514. +{
  220515. + return ipu_csi_enable_mclk(ipu, csi, flag, wait);
  220516. +}
  220517. +
  220518. +int ipu_csi_read_mclk_flag(void);
  220519. +
  220520. +void ipu_csi_flash_strobe(bool flag);
  220521. +
  220522. +void ipu_csi_get_window_size(struct ipu_soc *ipu, uint32_t *width, uint32_t *height, uint32_t csi);
  220523. +
  220524. +void ipu_csi_set_window_size(struct ipu_soc *ipu, uint32_t width, uint32_t height, uint32_t csi);
  220525. +
  220526. +void ipu_csi_set_window_pos(struct ipu_soc *ipu, uint32_t left, uint32_t top, uint32_t csi);
  220527. +
  220528. +uint32_t bytes_per_pixel(uint32_t fmt);
  220529. +
  220530. +bool ipu_ch_param_bad_alpha_pos(uint32_t fmt);
  220531. +
  220532. +struct ipuv3_fb_platform_data {
  220533. + char disp_dev[32];
  220534. + u32 interface_pix_fmt;
  220535. + char *mode_str;
  220536. + int default_bpp;
  220537. + bool int_clk;
  220538. +
  220539. + /* reserved mem */
  220540. + resource_size_t res_base[2];
  220541. + resource_size_t res_size[2];
  220542. +
  220543. + /*
  220544. + * Late init to avoid display channel being
  220545. + * re-initialized as we've probably setup the
  220546. + * channel in bootloader.
  220547. + */
  220548. + bool late_init;
  220549. +};
  220550. +
  220551. +#endif /* __LINUX_IPU_V3_H_ */
  220552. diff -Nur linux-3.14.15/include/linux/isl29023.h linux-linaro-stable-mx6/include/linux/isl29023.h
  220553. --- linux-3.14.15/include/linux/isl29023.h 1970-01-01 01:00:00.000000000 +0100
  220554. +++ linux-linaro-stable-mx6/include/linux/isl29023.h 2014-08-20 19:24:04.746893607 +0200
  220555. @@ -0,0 +1,47 @@
  220556. +/*
  220557. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  220558. + */
  220559. +
  220560. +/*
  220561. + * This program is free software; you can redistribute it and/or modify
  220562. + * it under the terms of the GNU General Public License as published by
  220563. + * the Free Software Foundation; either version 2 of the License, or
  220564. + * (at your option) any later version.
  220565. +
  220566. + * This program is distributed in the hope that it will be useful,
  220567. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  220568. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  220569. + * GNU General Public License for more details.
  220570. +
  220571. + * You should have received a copy of the GNU General Public License along
  220572. + * with this program; if not, write to the Free Software Foundation, Inc.,
  220573. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  220574. + */
  220575. +
  220576. +#ifndef __ISL29023_H__
  220577. +#define __ISL29023_H__
  220578. +
  220579. +#include <linux/types.h>
  220580. +
  220581. +#define ISL29023_PD_MODE 0x0
  220582. +#define ISL29023_ALS_ONCE_MODE 0x1
  220583. +#define ISL29023_IR_ONCE_MODE 0x2
  220584. +#define ISL29023_ALS_CONT_MODE 0x5
  220585. +#define ISL29023_IR_CONT_MODE 0x6
  220586. +
  220587. +#define ISL29023_INT_PERSISTS_1 0x0
  220588. +#define ISL29023_INT_PERSISTS_4 0x1
  220589. +#define ISL29023_INT_PERSISTS_8 0x2
  220590. +#define ISL29023_INT_PERSISTS_16 0x3
  220591. +
  220592. +#define ISL29023_RES_16 0x0
  220593. +#define ISL29023_RES_12 0x1
  220594. +#define ISL29023_RES_8 0x2
  220595. +#define ISL29023_RES_4 0x3
  220596. +
  220597. +#define ISL29023_RANGE_1K 0x0
  220598. +#define ISL29023_RANGE_4K 0x1
  220599. +#define ISL29023_RANGE_16K 0x2
  220600. +#define ISL29023_RANGE_64K 0x3
  220601. +
  220602. +#endif
  220603. diff -Nur linux-3.14.15/include/linux/kfifo.h linux-linaro-stable-mx6/include/linux/kfifo.h
  220604. --- linux-3.14.15/include/linux/kfifo.h 2014-07-31 23:51:43.000000000 +0200
  220605. +++ linux-linaro-stable-mx6/include/linux/kfifo.h 2014-08-20 19:31:52.356895741 +0200
  220606. @@ -722,7 +722,7 @@
  220607. /**
  220608. * kfifo_dma_out_finish - finish a DMA OUT operation
  220609. * @fifo: address of the fifo to be used
  220610. - * @len: number of bytes transferd
  220611. + * @len: number of bytes transferrd
  220612. *
  220613. * This macro finish a DMA OUT operation. The out counter will be updated by
  220614. * the len parameter. No error checking will be done.
  220615. diff -Nur linux-3.14.15/include/linux/libata.h linux-linaro-stable-mx6/include/linux/libata.h
  220616. --- linux-3.14.15/include/linux/libata.h 2014-07-31 23:51:43.000000000 +0200
  220617. +++ linux-linaro-stable-mx6/include/linux/libata.h 2014-08-20 19:31:52.368895793 +0200
  220618. @@ -593,7 +593,6 @@
  220619. struct device *dev;
  220620. void __iomem * const *iomap;
  220621. unsigned int n_ports;
  220622. - unsigned int n_tags; /* nr of NCQ tags */
  220623. void *private_data;
  220624. struct ata_port_operations *ops;
  220625. unsigned long flags;
  220626. diff -Nur linux-3.14.15/include/linux/mailbox_client.h linux-linaro-stable-mx6/include/linux/mailbox_client.h
  220627. --- linux-3.14.15/include/linux/mailbox_client.h 1970-01-01 01:00:00.000000000 +0100
  220628. +++ linux-linaro-stable-mx6/include/linux/mailbox_client.h 2014-08-20 19:31:52.380895844 +0200
  220629. @@ -0,0 +1,46 @@
  220630. +/*
  220631. + * Copyright (C) 2014 Linaro Ltd.
  220632. + * Author: Jassi Brar <jassisinghbrar@gmail.com>
  220633. + *
  220634. + * This program is free software; you can redistribute it and/or modify
  220635. + * it under the terms of the GNU General Public License version 2 as
  220636. + * published by the Free Software Foundation.
  220637. + */
  220638. +
  220639. +#ifndef __MAILBOX_CLIENT_H
  220640. +#define __MAILBOX_CLIENT_H
  220641. +
  220642. +#include <linux/of.h>
  220643. +
  220644. +struct mbox_chan;
  220645. +
  220646. +/**
  220647. + * struct mbox_client - User of a mailbox
  220648. + * @dev: The client device
  220649. + * @chan_name: The "controller:channel" this client wants
  220650. + * @rx_callback: Atomic callback to provide client the data received
  220651. + * @tx_done: Atomic callback to tell client of data transmission
  220652. + * @tx_block: If the mbox_send_message should block until data is
  220653. + * transmitted.
  220654. + * @tx_tout: Max block period in ms before TX is assumed failure
  220655. + * @knows_txdone: if the client could run the TX state machine. Usually
  220656. + * if the client receives some ACK packet for transmission.
  220657. + * Unused if the controller already has TX_Done/RTR IRQ.
  220658. + */
  220659. +struct mbox_client {
  220660. + struct device *dev;
  220661. + const char *chan_name;
  220662. + void (*rx_callback)(struct mbox_client *cl, void *mssg);
  220663. + void (*tx_done)(struct mbox_client *cl, void *mssg, int r);
  220664. + bool tx_block;
  220665. + unsigned long tx_tout;
  220666. + bool knows_txdone;
  220667. +};
  220668. +
  220669. +struct mbox_chan *mbox_request_channel(struct mbox_client *cl);
  220670. +int mbox_send_message(struct mbox_chan *chan, void *mssg);
  220671. +void mbox_client_txdone(struct mbox_chan *chan, int r);
  220672. +bool mbox_client_peek_data(struct mbox_chan *chan);
  220673. +void mbox_free_channel(struct mbox_chan *chan);
  220674. +
  220675. +#endif /* __MAILBOX_CLIENT_H */
  220676. diff -Nur linux-3.14.15/include/linux/mailbox_controller.h linux-linaro-stable-mx6/include/linux/mailbox_controller.h
  220677. --- linux-3.14.15/include/linux/mailbox_controller.h 1970-01-01 01:00:00.000000000 +0100
  220678. +++ linux-linaro-stable-mx6/include/linux/mailbox_controller.h 2014-08-20 19:31:52.380895844 +0200
  220679. @@ -0,0 +1,121 @@
  220680. +/*
  220681. + * This program is free software; you can redistribute it and/or modify
  220682. + * it under the terms of the GNU General Public License version 2 as
  220683. + * published by the Free Software Foundation.
  220684. + */
  220685. +
  220686. +#ifndef __MAILBOX_CONTROLLER_H
  220687. +#define __MAILBOX_CONTROLLER_H
  220688. +
  220689. +#include <linux/of.h>
  220690. +
  220691. +struct mbox_chan;
  220692. +
  220693. +/**
  220694. + * struct mbox_chan_ops - s/w representation of a communication chan
  220695. + * @send_data: The API asks the MBOX controller driver, in atomic
  220696. + * context try to transmit a message on the bus. Returns 0 if
  220697. + * data is accepted for transmission, -EBUSY while rejecting
  220698. + * if the remote hasn't yet read the last data sent. Actual
  220699. + * transmission of data is reported by the controller via
  220700. + * mbox_chan_txdone (if it has some TX ACK irq). It must not
  220701. + * block.
  220702. + * @startup: Called when a client requests the chan. The controller
  220703. + * could ask clients for additional parameters of communication
  220704. + * to be provided via client's chan_data. This call may
  220705. + * block. After this call the Controller must forward any
  220706. + * data received on the chan by calling mbox_chan_received_data.
  220707. + * @shutdown: Called when a client relinquishes control of a chan.
  220708. + * This call may block too. The controller must not forwared
  220709. + * any received data anymore.
  220710. + * @last_tx_done: If the controller sets 'txdone_poll', the API calls
  220711. + * this to poll status of last TX. The controller must
  220712. + * give priority to IRQ method over polling and never
  220713. + * set both txdone_poll and txdone_irq. Only in polling
  220714. + * mode 'send_data' is expected to return -EBUSY.
  220715. + * Used only if txdone_poll:=true && txdone_irq:=false
  220716. + * @peek_data: Atomic check for any received data. Return true if controller
  220717. + * has some data to push to the client. False otherwise.
  220718. + */
  220719. +struct mbox_chan_ops {
  220720. + int (*send_data)(struct mbox_chan *chan, void *data);
  220721. + int (*startup)(struct mbox_chan *chan);
  220722. + void (*shutdown)(struct mbox_chan *chan);
  220723. + bool (*last_tx_done)(struct mbox_chan *chan);
  220724. + bool (*peek_data)(struct mbox_chan *chan);
  220725. +};
  220726. +
  220727. +/**
  220728. + * struct mbox_controller - Controller of a class of communication chans
  220729. + * @dev: Device backing this controller
  220730. + * @controller_name: Literal name of the controller.
  220731. + * @ops: Operators that work on each communication chan
  220732. + * @chans: Null terminated array of chans.
  220733. + * @txdone_irq: Indicates if the controller can report to API when
  220734. + * the last transmitted data was read by the remote.
  220735. + * Eg, if it has some TX ACK irq.
  220736. + * @txdone_poll: If the controller can read but not report the TX
  220737. + * done. Ex, some register shows the TX status but
  220738. + * no interrupt rises. Ignored if 'txdone_irq' is set.
  220739. + * @txpoll_period: If 'txdone_poll' is in effect, the API polls for
  220740. + * last TX's status after these many millisecs
  220741. + */
  220742. +struct mbox_controller {
  220743. + struct device *dev;
  220744. + struct mbox_chan_ops *ops;
  220745. + struct mbox_chan *chans;
  220746. + int num_chans;
  220747. + bool txdone_irq;
  220748. + bool txdone_poll;
  220749. + unsigned txpoll_period;
  220750. + struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox,
  220751. + const struct of_phandle_args *sp);
  220752. + /*
  220753. + * If the controller supports only TXDONE_BY_POLL,
  220754. + * this timer polls all the links for txdone.
  220755. + */
  220756. + struct timer_list poll;
  220757. + unsigned period;
  220758. + /* Hook to add to the global controller list */
  220759. + struct list_head node;
  220760. +};
  220761. +
  220762. +/*
  220763. + * The length of circular buffer for queuing messages from a client.
  220764. + * 'msg_count' tracks the number of buffered messages while 'msg_free'
  220765. + * is the index where the next message would be buffered.
  220766. + * We shouldn't need it too big because every transferr is interrupt
  220767. + * triggered and if we have lots of data to transfer, the interrupt
  220768. + * latencies are going to be the bottleneck, not the buffer length.
  220769. + * Besides, mbox_send_message could be called from atomic context and
  220770. + * the client could also queue another message from the notifier 'tx_done'
  220771. + * of the last transfer done.
  220772. + * REVIST: If too many platforms see the "Try increasing MBOX_TX_QUEUE_LEN"
  220773. + * print, it needs to be taken from config option or somesuch.
  220774. + */
  220775. +#define MBOX_TX_QUEUE_LEN 20
  220776. +
  220777. +struct mbox_chan {
  220778. + struct mbox_controller *mbox; /* Parent Controller */
  220779. + unsigned txdone_method;
  220780. +
  220781. + /* client */
  220782. + struct mbox_client *cl;
  220783. + struct completion tx_complete;
  220784. +
  220785. + void *active_req;
  220786. + unsigned msg_count, msg_free;
  220787. + void *msg_data[MBOX_TX_QUEUE_LEN];
  220788. + /* Access to the channel */
  220789. + spinlock_t lock;
  220790. +
  220791. + /* Private data for controller */
  220792. + void *con_priv;
  220793. +};
  220794. +
  220795. +int mbox_controller_register(struct mbox_controller *mbox);
  220796. +void mbox_chan_received_data(struct mbox_chan *chan, void *data);
  220797. +void mbox_chan_txdone(struct mbox_chan *chan, int r);
  220798. +void mbox_controller_unregister(struct mbox_controller *mbox);
  220799. +
  220800. +#endif /* __MAILBOX_CONTROLLER_H */
  220801. diff -Nur linux-3.14.15/include/linux/mailbox.h linux-linaro-stable-mx6/include/linux/mailbox.h
  220802. --- linux-3.14.15/include/linux/mailbox.h 2014-07-31 23:51:43.000000000 +0200
  220803. +++ linux-linaro-stable-mx6/include/linux/mailbox.h 1970-01-01 01:00:00.000000000 +0100
  220804. @@ -1,17 +0,0 @@
  220805. -/*
  220806. - * This program is free software; you can redistribute it and/or modify it
  220807. - * under the terms and conditions of the GNU General Public License,
  220808. - * version 2, as published by the Free Software Foundation.
  220809. - *
  220810. - * This program is distributed in the hope it will be useful, but WITHOUT
  220811. - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  220812. - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  220813. - * more details.
  220814. - *
  220815. - * You should have received a copy of the GNU General Public License along with
  220816. - * this program. If not, see <http://www.gnu.org/licenses/>.
  220817. - */
  220818. -
  220819. -int pl320_ipc_transmit(u32 *data);
  220820. -int pl320_ipc_register_notifier(struct notifier_block *nb);
  220821. -int pl320_ipc_unregister_notifier(struct notifier_block *nb);
  220822. diff -Nur linux-3.14.15/include/linux/mfd/abx500/ab8500.h linux-linaro-stable-mx6/include/linux/mfd/abx500/ab8500.h
  220823. --- linux-3.14.15/include/linux/mfd/abx500/ab8500.h 2014-07-31 23:51:43.000000000 +0200
  220824. +++ linux-linaro-stable-mx6/include/linux/mfd/abx500/ab8500.h 2014-08-20 19:31:52.388895878 +0200
  220825. @@ -347,7 +347,6 @@
  220826. struct mutex lock;
  220827. struct mutex irq_lock;
  220828. atomic_t transfer_ongoing;
  220829. - int irq_base;
  220830. int irq;
  220831. struct irq_domain *domain;
  220832. enum ab8500_version version;
  220833. @@ -378,7 +377,6 @@
  220834. * @regulator: machine-specific constraints for regulators
  220835. */
  220836. struct ab8500_platform_data {
  220837. - int irq_base;
  220838. void (*init) (struct ab8500 *);
  220839. struct ab8500_regulator_platform_data *regulator;
  220840. struct ab8500_codec_platform_data *codec;
  220841. diff -Nur linux-3.14.15/include/linux/mfd/dbx500-prcmu.h linux-linaro-stable-mx6/include/linux/mfd/dbx500-prcmu.h
  220842. --- linux-3.14.15/include/linux/mfd/dbx500-prcmu.h 2014-07-31 23:51:43.000000000 +0200
  220843. +++ linux-linaro-stable-mx6/include/linux/mfd/dbx500-prcmu.h 2014-08-20 19:31:52.440896102 +0200
  220844. @@ -183,8 +183,6 @@
  220845. bool enable_set_ddr_opp;
  220846. bool enable_ape_opp_100_voltage;
  220847. struct ab8500_platform_data *ab_platdata;
  220848. - int ab_irq;
  220849. - int irq_base;
  220850. u32 version_offset;
  220851. u32 legacy_offset;
  220852. u32 adt_offset;
  220853. diff -Nur linux-3.14.15/include/linux/mfd/mxc-hdmi-core.h linux-linaro-stable-mx6/include/linux/mfd/mxc-hdmi-core.h
  220854. --- linux-3.14.15/include/linux/mfd/mxc-hdmi-core.h 1970-01-01 01:00:00.000000000 +0100
  220855. +++ linux-linaro-stable-mx6/include/linux/mfd/mxc-hdmi-core.h 2014-08-20 19:24:05.602897262 +0200
  220856. @@ -0,0 +1,64 @@
  220857. +/*
  220858. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  220859. + *
  220860. + * This program is free software; you can redistribute it and/or modify
  220861. + * it under the terms of the GNU General Public License as published by
  220862. + * the Free Software Foundation; either version 2 of the License, or
  220863. + * (at your option) any later version.
  220864. + *
  220865. + * This program is distributed in the hope that it will be useful,
  220866. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  220867. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  220868. + * GNU General Public License for more details.
  220869. + *
  220870. + * You should have received a copy of the GNU General Public License
  220871. + * along with this program; if not, write to the Free Software
  220872. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  220873. + *
  220874. + */
  220875. +#ifndef __LINUX_MXC_HDMI_CORE_H_
  220876. +#define __LINUX_MXC_HDMI_CORE_H_
  220877. +
  220878. +#include <video/mxc_edid.h>
  220879. +
  220880. +#include <sound/core.h>
  220881. +#include <sound/pcm.h>
  220882. +#include <sound/pcm_params.h>
  220883. +#include <sound/soc.h>
  220884. +
  220885. +#define IRQ_DISABLE_SUCCEED 0
  220886. +#define IRQ_DISABLE_FAIL 1
  220887. +
  220888. +bool hdmi_check_overflow(void);
  220889. +
  220890. +u8 hdmi_readb(unsigned int reg);
  220891. +void hdmi_writeb(u8 value, unsigned int reg);
  220892. +void hdmi_mask_writeb(u8 data, unsigned int addr, u8 shift, u8 mask);
  220893. +unsigned int hdmi_read4(unsigned int reg);
  220894. +void hdmi_write4(unsigned int value, unsigned int reg);
  220895. +
  220896. +void hdmi_irq_init(void);
  220897. +void hdmi_irq_enable(int irq);
  220898. +unsigned int hdmi_irq_disable(int irq);
  220899. +
  220900. +void hdmi_set_sample_rate(unsigned int rate);
  220901. +void hdmi_set_dma_mode(unsigned int dma_running);
  220902. +void hdmi_init_clk_regenerator(void);
  220903. +void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock);
  220904. +
  220905. +void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg);
  220906. +void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg);
  220907. +
  220908. +extern int mxc_hdmi_ipu_id;
  220909. +extern int mxc_hdmi_disp_id;
  220910. +
  220911. +void hdmi_set_registered(int registered);
  220912. +int hdmi_get_registered(void);
  220913. +int mxc_hdmi_abort_stream(void);
  220914. +int mxc_hdmi_register_audio(struct snd_pcm_substream *substream);
  220915. +void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream);
  220916. +unsigned int hdmi_set_cable_state(unsigned int state);
  220917. +unsigned int hdmi_set_blank_state(unsigned int state);
  220918. +int check_hdmi_state(void);
  220919. +
  220920. +#endif
  220921. diff -Nur linux-3.14.15/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h linux-linaro-stable-mx6/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
  220922. --- linux-3.14.15/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h 2014-07-31 23:51:43.000000000 +0200
  220923. +++ linux-linaro-stable-mx6/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h 2014-08-20 19:24:05.630897382 +0200
  220924. @@ -1,5 +1,5 @@
  220925. /*
  220926. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  220927. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  220928. *
  220929. * This program is free software; you can redistribute it and/or modify
  220930. * it under the terms of the GNU General Public License version 2 as
  220931. @@ -122,7 +122,9 @@
  220932. #define IMX6Q_GPR1_USB_OTG_ID_SEL_MASK BIT(13)
  220933. #define IMX6Q_GPR1_USB_OTG_ID_SEL_ENET_RX_ER 0x0
  220934. #define IMX6Q_GPR1_USB_OTG_ID_SEL_GPIO_1 BIT(13)
  220935. -#define IMX6Q_GPR1_GINT BIT(12)
  220936. +#define IMX6Q_GPR1_GINT_MASK BIT(12)
  220937. +#define IMX6Q_GPR1_GINT_CLEAR 0x0
  220938. +#define IMX6Q_GPR1_GINT_ASSERT BIT(12)
  220939. #define IMX6Q_GPR1_ADDRS3_MASK (0x3 << 10)
  220940. #define IMX6Q_GPR1_ADDRS3_32MB (0x0 << 10)
  220941. #define IMX6Q_GPR1_ADDRS3_64MB (0x1 << 10)
  220942. diff -Nur linux-3.14.15/include/linux/mipi_csi2.h linux-linaro-stable-mx6/include/linux/mipi_csi2.h
  220943. --- linux-3.14.15/include/linux/mipi_csi2.h 1970-01-01 01:00:00.000000000 +0100
  220944. +++ linux-linaro-stable-mx6/include/linux/mipi_csi2.h 2014-08-20 19:31:52.548896564 +0200
  220945. @@ -0,0 +1,93 @@
  220946. +/*
  220947. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  220948. + *
  220949. + * This program is free software; you can redistribute it and/or modify
  220950. + * it under the terms of the GNU General Public License as published by
  220951. + * the Free Software Foundation; either version 2 of the License, or
  220952. + * (at your option) any later version.
  220953. + *
  220954. + * This program is distributed in the hope that it will be useful,
  220955. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  220956. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  220957. + * GNU General Public License for more details.
  220958. + *
  220959. + * You should have received a copy of the GNU General Public License along
  220960. + * with this program; if not, write to the Free Software Foundation, Inc.,
  220961. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  220962. + */
  220963. +
  220964. +#ifndef __INCLUDE_MIPI_CSI2_H
  220965. +#define __INCLUDE_MIPI_CSI2_H
  220966. +
  220967. +/* MIPI CSI2 registers */
  220968. +#define MIPI_CSI2_REG(offset) (offset)
  220969. +
  220970. +#define MIPI_CSI2_VERSION MIPI_CSI2_REG(0x000)
  220971. +#define MIPI_CSI2_N_LANES MIPI_CSI2_REG(0x004)
  220972. +#define MIPI_CSI2_PHY_SHUTDOWNZ MIPI_CSI2_REG(0x008)
  220973. +#define MIPI_CSI2_DPHY_RSTZ MIPI_CSI2_REG(0x00c)
  220974. +#define MIPI_CSI2_CSI2_RESETN MIPI_CSI2_REG(0x010)
  220975. +#define MIPI_CSI2_PHY_STATE MIPI_CSI2_REG(0x014)
  220976. +#define MIPI_CSI2_DATA_IDS_1 MIPI_CSI2_REG(0x018)
  220977. +#define MIPI_CSI2_DATA_IDS_2 MIPI_CSI2_REG(0x01c)
  220978. +#define MIPI_CSI2_ERR1 MIPI_CSI2_REG(0x020)
  220979. +#define MIPI_CSI2_ERR2 MIPI_CSI2_REG(0x024)
  220980. +#define MIPI_CSI2_MASK1 MIPI_CSI2_REG(0x028)
  220981. +#define MIPI_CSI2_MASK2 MIPI_CSI2_REG(0x02c)
  220982. +#define MIPI_CSI2_PHY_TST_CTRL0 MIPI_CSI2_REG(0x030)
  220983. +#define MIPI_CSI2_PHY_TST_CTRL1 MIPI_CSI2_REG(0x034)
  220984. +#define MIPI_CSI2_SFT_RESET MIPI_CSI2_REG(0xf00)
  220985. +
  220986. +/* mipi data type */
  220987. +#define MIPI_DT_YUV420 0x18 /* YYY.../UYVY.... */
  220988. +#define MIPI_DT_YUV420_LEGACY 0x1a /* UYY.../VYY... */
  220989. +#define MIPI_DT_YUV422 0x1e /* UYVY... */
  220990. +#define MIPI_DT_RGB444 0x20
  220991. +#define MIPI_DT_RGB555 0x21
  220992. +#define MIPI_DT_RGB565 0x22
  220993. +#define MIPI_DT_RGB666 0x23
  220994. +#define MIPI_DT_RGB888 0x24
  220995. +#define MIPI_DT_RAW6 0x28
  220996. +#define MIPI_DT_RAW7 0x29
  220997. +#define MIPI_DT_RAW8 0x2a
  220998. +#define MIPI_DT_RAW10 0x2b
  220999. +#define MIPI_DT_RAW12 0x2c
  221000. +#define MIPI_DT_RAW14 0x2d
  221001. +
  221002. +
  221003. +struct mipi_csi2_info;
  221004. +/* mipi csi2 API */
  221005. +struct mipi_csi2_info *mipi_csi2_get_info(void);
  221006. +
  221007. +bool mipi_csi2_enable(struct mipi_csi2_info *info);
  221008. +
  221009. +bool mipi_csi2_disable(struct mipi_csi2_info *info);
  221010. +
  221011. +bool mipi_csi2_get_status(struct mipi_csi2_info *info);
  221012. +
  221013. +int mipi_csi2_get_bind_ipu(struct mipi_csi2_info *info);
  221014. +
  221015. +unsigned int mipi_csi2_get_bind_csi(struct mipi_csi2_info *info);
  221016. +
  221017. +unsigned int mipi_csi2_get_virtual_channel(struct mipi_csi2_info *info);
  221018. +
  221019. +unsigned int mipi_csi2_set_lanes(struct mipi_csi2_info *info);
  221020. +
  221021. +unsigned int mipi_csi2_set_datatype(struct mipi_csi2_info *info,
  221022. + unsigned int datatype);
  221023. +
  221024. +unsigned int mipi_csi2_get_datatype(struct mipi_csi2_info *info);
  221025. +
  221026. +unsigned int mipi_csi2_dphy_status(struct mipi_csi2_info *info);
  221027. +
  221028. +unsigned int mipi_csi2_get_error1(struct mipi_csi2_info *info);
  221029. +
  221030. +unsigned int mipi_csi2_get_error2(struct mipi_csi2_info *info);
  221031. +
  221032. +int mipi_csi2_pixelclk_enable(struct mipi_csi2_info *info);
  221033. +
  221034. +void mipi_csi2_pixelclk_disable(struct mipi_csi2_info *info);
  221035. +
  221036. +int mipi_csi2_reset(struct mipi_csi2_info *info);
  221037. +
  221038. +#endif
  221039. diff -Nur linux-3.14.15/include/linux/mipi_dsi.h linux-linaro-stable-mx6/include/linux/mipi_dsi.h
  221040. --- linux-3.14.15/include/linux/mipi_dsi.h 1970-01-01 01:00:00.000000000 +0100
  221041. +++ linux-linaro-stable-mx6/include/linux/mipi_dsi.h 2014-08-20 19:24:05.694897655 +0200
  221042. @@ -0,0 +1,171 @@
  221043. +/*
  221044. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  221045. + *
  221046. + * This program is free software; you can redistribute it and/or modify
  221047. + * it under the terms of the GNU General Public License as published by
  221048. + * the Free Software Foundation; either version 2 of the License, or
  221049. + * (at your option) any later version.
  221050. + *
  221051. + * This program is distributed in the hope that it will be useful,
  221052. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  221053. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  221054. + * GNU General Public License for more details.
  221055. + *
  221056. + * You should have received a copy of the GNU General Public License along
  221057. + * with this program; if not, write to the Free Software Foundation, Inc.,
  221058. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  221059. + */
  221060. +
  221061. +#ifndef __INCLUDE_MIPI_DSI_H
  221062. +#define __INCLUDE_MIPI_DSI_H
  221063. +
  221064. +#define MIPI_DSI_VERSION (0x000)
  221065. +#define MIPI_DSI_PWR_UP (0x004)
  221066. +#define MIPI_DSI_CLKMGR_CFG (0x008)
  221067. +#define MIPI_DSI_DPI_CFG (0x00c)
  221068. +#define MIPI_DSI_DBI_CFG (0x010)
  221069. +#define MIPI_DSI_DBIS_CMDSIZE (0x014)
  221070. +#define MIPI_DSI_PCKHDL_CFG (0x018)
  221071. +#define MIPI_DSI_VID_MODE_CFG (0x01c)
  221072. +#define MIPI_DSI_VID_PKT_CFG (0x020)
  221073. +#define MIPI_DSI_CMD_MODE_CFG (0x024)
  221074. +#define MIPI_DSI_TMR_LINE_CFG (0x028)
  221075. +#define MIPI_DSI_VTIMING_CFG (0x02c)
  221076. +#define MIPI_DSI_PHY_TMR_CFG (0x030)
  221077. +#define MIPI_DSI_GEN_HDR (0x034)
  221078. +#define MIPI_DSI_GEN_PLD_DATA (0x038)
  221079. +#define MIPI_DSI_CMD_PKT_STATUS (0x03c)
  221080. +#define MIPI_DSI_TO_CNT_CFG (0x040)
  221081. +#define MIPI_DSI_ERROR_ST0 (0x044)
  221082. +#define MIPI_DSI_ERROR_ST1 (0x048)
  221083. +#define MIPI_DSI_ERROR_MSK0 (0x04c)
  221084. +#define MIPI_DSI_ERROR_MSK1 (0x050)
  221085. +#define MIPI_DSI_PHY_RSTZ (0x054)
  221086. +#define MIPI_DSI_PHY_IF_CFG (0x058)
  221087. +#define MIPI_DSI_PHY_IF_CTRL (0x05c)
  221088. +#define MIPI_DSI_PHY_STATUS (0x060)
  221089. +#define MIPI_DSI_PHY_TST_CTRL0 (0x064)
  221090. +#define MIPI_DSI_PHY_TST_CTRL1 (0x068)
  221091. +
  221092. +#define DSI_PWRUP_RESET (0x0 << 0)
  221093. +#define DSI_PWRUP_POWERUP (0x1 << 0)
  221094. +
  221095. +#define DSI_DPI_CFG_VID_SHIFT (0)
  221096. +#define DSI_DPI_CFG_VID_MASK (0x3)
  221097. +#define DSI_DPI_CFG_COLORCODE_SHIFT (2)
  221098. +#define DSI_DPI_CFG_COLORCODE_MASK (0x7)
  221099. +#define DSI_DPI_CFG_DATAEN_ACT_LOW (0x1 << 5)
  221100. +#define DSI_DPI_CFG_DATAEN_ACT_HIGH (0x0 << 5)
  221101. +#define DSI_DPI_CFG_VSYNC_ACT_LOW (0x1 << 6)
  221102. +#define DSI_DPI_CFG_VSYNC_ACT_HIGH (0x0 << 6)
  221103. +#define DSI_DPI_CFG_HSYNC_ACT_LOW (0x1 << 7)
  221104. +#define DSI_DPI_CFG_HSYNC_ACT_HIGH (0x0 << 7)
  221105. +#define DSI_DPI_CFG_SHUTD_ACT_LOW (0x1 << 8)
  221106. +#define DSI_DPI_CFG_SHUTD_ACT_HIGH (0x0 << 8)
  221107. +#define DSI_DPI_CFG_COLORMODE_ACT_LOW (0x1 << 9)
  221108. +#define DSI_DPI_CFG_COLORMODE_ACT_HIGH (0x0 << 9)
  221109. +#define DSI_DPI_CFG_EN18LOOSELY (0x1 << 10)
  221110. +
  221111. +#define DSI_PCKHDL_CFG_EN_EOTP_TX (0x1 << 0)
  221112. +#define DSI_PCKHDL_CFG_EN_EOTP_RX (0x1 << 1)
  221113. +#define DSI_PCKHDL_CFG_EN_BTA (0x1 << 2)
  221114. +#define DSI_PCKHDL_CFG_EN_ECC_RX (0x1 << 3)
  221115. +#define DSI_PCKHDL_CFG_EN_CRC_RX (0x1 << 4)
  221116. +#define DSI_PCKHDL_CFG_GEN_VID_RX_MASK (0x3)
  221117. +#define DSI_PCKHDL_CFG_GEN_VID_RX_SHIFT (5)
  221118. +
  221119. +#define DSI_VID_MODE_CFG_EN (0x1 << 0)
  221120. +#define DSI_VID_MODE_CFG_EN_BURSTMODE (0x3 << 1)
  221121. +#define DSI_VID_MODE_CFG_TYPE_MASK (0x3)
  221122. +#define DSI_VID_MODE_CFG_TYPE_SHIFT (1)
  221123. +#define DSI_VID_MODE_CFG_EN_LP_VSA (0x1 << 3)
  221124. +#define DSI_VID_MODE_CFG_EN_LP_VBP (0x1 << 4)
  221125. +#define DSI_VID_MODE_CFG_EN_LP_VFP (0x1 << 5)
  221126. +#define DSI_VID_MODE_CFG_EN_LP_VACT (0x1 << 6)
  221127. +#define DSI_VID_MODE_CFG_EN_LP_HBP (0x1 << 7)
  221128. +#define DSI_VID_MODE_CFG_EN_LP_HFP (0x1 << 8)
  221129. +#define DSI_VID_MODE_CFG_EN_MULTI_PKT (0x1 << 9)
  221130. +#define DSI_VID_MODE_CFG_EN_NULL_PKT (0x1 << 10)
  221131. +#define DSI_VID_MODE_CFG_EN_FRAME_ACK (0x1 << 11)
  221132. +#define DSI_VID_MODE_CFG_EN_LP_MODE (DSI_VID_MODE_CFG_EN_LP_VSA | \
  221133. + DSI_VID_MODE_CFG_EN_LP_VBP | \
  221134. + DSI_VID_MODE_CFG_EN_LP_VFP | \
  221135. + DSI_VID_MODE_CFG_EN_LP_HFP | \
  221136. + DSI_VID_MODE_CFG_EN_LP_HBP | \
  221137. + DSI_VID_MODE_CFG_EN_LP_VACT)
  221138. +
  221139. +
  221140. +
  221141. +#define DSI_VID_PKT_CFG_VID_PKT_SZ_MASK (0x7ff)
  221142. +#define DSI_VID_PKT_CFG_VID_PKT_SZ_SHIFT (0)
  221143. +#define DSI_VID_PKT_CFG_NUM_CHUNKS_MASK (0x3ff)
  221144. +#define DSI_VID_PKT_CFG_NUM_CHUNKS_SHIFT (11)
  221145. +#define DSI_VID_PKT_CFG_NULL_PKT_SZ_MASK (0x3ff)
  221146. +#define DSI_VID_PKT_CFG_NULL_PKT_SZ_SHIFT (21)
  221147. +
  221148. +#define MIPI_DSI_CMD_MODE_CFG_EN_LOWPOWER (0x1FFF)
  221149. +#define MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE (0x1 << 0)
  221150. +
  221151. +#define DSI_TME_LINE_CFG_HSA_TIME_MASK (0x1ff)
  221152. +#define DSI_TME_LINE_CFG_HSA_TIME_SHIFT (0)
  221153. +#define DSI_TME_LINE_CFG_HBP_TIME_MASK (0x1ff)
  221154. +#define DSI_TME_LINE_CFG_HBP_TIME_SHIFT (9)
  221155. +#define DSI_TME_LINE_CFG_HLINE_TIME_MASK (0x3fff)
  221156. +#define DSI_TME_LINE_CFG_HLINE_TIME_SHIFT (18)
  221157. +
  221158. +#define DSI_VTIMING_CFG_VSA_LINES_MASK (0xf)
  221159. +#define DSI_VTIMING_CFG_VSA_LINES_SHIFT (0)
  221160. +#define DSI_VTIMING_CFG_VBP_LINES_MASK (0x3f)
  221161. +#define DSI_VTIMING_CFG_VBP_LINES_SHIFT (4)
  221162. +#define DSI_VTIMING_CFG_VFP_LINES_MASK (0x3f)
  221163. +#define DSI_VTIMING_CFG_VFP_LINES_SHIFT (10)
  221164. +#define DSI_VTIMING_CFG_V_ACT_LINES_MASK (0x7ff)
  221165. +#define DSI_VTIMING_CFG_V_ACT_LINES_SHIFT (16)
  221166. +
  221167. +#define DSI_PHY_TMR_CFG_BTA_TIME_MASK (0xfff)
  221168. +#define DSI_PHY_TMR_CFG_BTA_TIME_SHIFT (0)
  221169. +#define DSI_PHY_TMR_CFG_LP2HS_TIME_MASK (0xff)
  221170. +#define DSI_PHY_TMR_CFG_LP2HS_TIME_SHIFT (12)
  221171. +#define DSI_PHY_TMR_CFG_HS2LP_TIME_MASK (0xff)
  221172. +#define DSI_PHY_TMR_CFG_HS2LP_TIME_SHIFT (20)
  221173. +
  221174. +#define DSI_PHY_IF_CFG_N_LANES_MASK (0x3)
  221175. +#define DSI_PHY_IF_CFG_N_LANES_SHIFT (0)
  221176. +#define DSI_PHY_IF_CFG_WAIT_TIME_MASK (0xff)
  221177. +#define DSI_PHY_IF_CFG_WAIT_TIME_SHIFT (2)
  221178. +
  221179. +#define DSI_PHY_RSTZ_EN_CLK (0x1 << 2)
  221180. +#define DSI_PHY_RSTZ_DISABLE_RST (0x1 << 1)
  221181. +#define DSI_PHY_RSTZ_DISABLE_SHUTDOWN (0x1 << 0)
  221182. +#define DSI_PHY_RSTZ_RST (0x0)
  221183. +
  221184. +#define DSI_PHY_STATUS_LOCK (0x1 << 0)
  221185. +#define DSI_PHY_STATUS_STOPSTATE_CLK_LANE (0x1 << 2)
  221186. +
  221187. +#define DSI_GEN_HDR_TYPE_MASK (0xff)
  221188. +#define DSI_GEN_HDR_TYPE_SHIFT (0)
  221189. +#define DSI_GEN_HDR_DATA_MASK (0xffff)
  221190. +#define DSI_GEN_HDR_DATA_SHIFT (8)
  221191. +
  221192. +#define DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY (0x1 << 0)
  221193. +#define DSI_CMD_PKT_STATUS_GEN_CMD_FULL (0x1 << 1)
  221194. +#define DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY (0x1 << 2)
  221195. +#define DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL (0x1 << 3)
  221196. +#define DSI_CMD_PKT_STATUS_GEN_PLD_R_EMPTY (0x1 << 4)
  221197. +#define DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY (0x1 << 6)
  221198. +
  221199. +#define DSI_ERROR_MSK0_ALL_MASK (0x1fffff)
  221200. +#define DSI_ERROR_MSK1_ALL_MASK (0x3ffff)
  221201. +
  221202. +#define DSI_PHY_IF_CTRL_RESET (0x0)
  221203. +#define DSI_PHY_IF_CTRL_TX_REQ_CLK_HS (0x1 << 0)
  221204. +#define DSI_PHY_IF_CTRL_TX_REQ_CLK_ULPS (0x1 << 1)
  221205. +#define DSI_PHY_IF_CTRL_TX_EXIT_CLK_ULPS (0x1 << 2)
  221206. +#define DSI_PHY_IF_CTRL_TX_REQ_DATA_ULPS (0x1 << 3)
  221207. +#define DSI_PHY_IF_CTRL_TX_EXIT_DATA_ULPS (0x1 << 4)
  221208. +#define DSI_PHY_IF_CTRL_TX_TRIG_MASK (0xF)
  221209. +#define DSI_PHY_IF_CTRL_TX_TRIG_SHIFT (5)
  221210. +
  221211. +#define DSI_PHY_CLK_INIT_COMMAND (0x44)
  221212. +#define DSI_GEN_PLD_DATA_BUF_SIZE (0x4)
  221213. +#endif
  221214. diff -Nur linux-3.14.15/include/linux/mmc/card.h linux-linaro-stable-mx6/include/linux/mmc/card.h
  221215. --- linux-3.14.15/include/linux/mmc/card.h 2014-07-31 23:51:43.000000000 +0200
  221216. +++ linux-linaro-stable-mx6/include/linux/mmc/card.h 2014-08-20 19:31:52.556896600 +0200
  221217. @@ -86,10 +86,13 @@
  221218. unsigned int data_sector_size; /* 512 bytes or 4KB */
  221219. unsigned int data_tag_unit_size; /* DATA TAG UNIT size */
  221220. unsigned int boot_ro_lock; /* ro lock support */
  221221. + unsigned int boot_size;
  221222. bool boot_ro_lockable;
  221223. u8 raw_exception_status; /* 54 */
  221224. u8 raw_partition_support; /* 160 */
  221225. u8 raw_rpmb_size_mult; /* 168 */
  221226. + u8 boot_bus_width; /* 177 */
  221227. + u8 boot_config; /* 179 */
  221228. u8 raw_erased_mem_count; /* 181 */
  221229. u8 raw_ext_csd_structure; /* 194 */
  221230. u8 raw_card_type; /* 196 */
  221231. @@ -102,6 +105,7 @@
  221232. u8 raw_hc_erase_gap_size; /* 221 */
  221233. u8 raw_erase_timeout_mult; /* 223 */
  221234. u8 raw_hc_erase_grp_size; /* 224 */
  221235. + u8 boot_info; /* 228 */
  221236. u8 raw_sec_trim_mult; /* 229 */
  221237. u8 raw_sec_erase_mult; /* 230 */
  221238. u8 raw_sec_feature_support;/* 231 */
  221239. diff -Nur linux-3.14.15/include/linux/mmc/host.h linux-linaro-stable-mx6/include/linux/mmc/host.h
  221240. --- linux-3.14.15/include/linux/mmc/host.h 2014-07-31 23:51:43.000000000 +0200
  221241. +++ linux-linaro-stable-mx6/include/linux/mmc/host.h 2014-08-20 19:31:52.560896617 +0200
  221242. @@ -282,6 +282,7 @@
  221243. MMC_CAP2_PACKED_WR)
  221244. #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */
  221245. #define MMC_CAP2_SANITIZE (1 << 15) /* Support Sanitize */
  221246. +#define MMC_CAP2_SDIO_NOTHREAD (1 << 16)
  221247. mmc_pm_flag_t pm_caps; /* supported pm features */
  221248. @@ -297,6 +298,11 @@
  221249. unsigned long clkgate_delay;
  221250. #endif
  221251. + /* card specific properties to deal with power and reset */
  221252. + struct regulator *card_regulator; /* External VCC needed by the card */
  221253. + struct gpio_desc *card_reset_gpios[2]; /* External resets, active low */
  221254. + struct clk *card_clk; /* External clock needed by the card */
  221255. +
  221256. /* host specific block data */
  221257. unsigned int max_seg_size; /* see blk_queue_max_segment_size */
  221258. unsigned short max_segs; /* see blk_queue_max_segments */
  221259. @@ -397,6 +403,8 @@
  221260. wake_up_process(host->sdio_irq_thread);
  221261. }
  221262. +void sdio_run_irqs(struct mmc_host *host);
  221263. +
  221264. #ifdef CONFIG_REGULATOR
  221265. int mmc_regulator_get_ocrmask(struct regulator *supply);
  221266. int mmc_regulator_set_ocr(struct mmc_host *mmc,
  221267. diff -Nur linux-3.14.15/include/linux/mmc/mmc.h linux-linaro-stable-mx6/include/linux/mmc/mmc.h
  221268. --- linux-3.14.15/include/linux/mmc/mmc.h 2014-07-31 23:51:43.000000000 +0200
  221269. +++ linux-linaro-stable-mx6/include/linux/mmc/mmc.h 2014-08-20 19:24:05.722897774 +0200
  221270. @@ -292,6 +292,7 @@
  221271. #define EXT_CSD_RPMB_MULT 168 /* RO */
  221272. #define EXT_CSD_BOOT_WP 173 /* R/W */
  221273. #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
  221274. +#define EXT_CSD_BOOT_BUS_WIDTH 177 /* R/W */
  221275. #define EXT_CSD_PART_CONFIG 179 /* R/W */
  221276. #define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
  221277. #define EXT_CSD_BUS_WIDTH 183 /* R/W */
  221278. @@ -313,6 +314,7 @@
  221279. #define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
  221280. #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
  221281. #define EXT_CSD_BOOT_MULT 226 /* RO */
  221282. +#define EXT_CSD_BOOT_INFO 228 /* RO, 1 bytes */
  221283. #define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
  221284. #define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
  221285. #define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
  221286. @@ -378,6 +380,29 @@
  221287. #define EXT_CSD_SEC_GB_CL_EN BIT(4)
  221288. #define EXT_CSD_SEC_SANITIZE BIT(6) /* v4.5 only */
  221289. +#define EXT_CSD_BOOT_BUS_WIDTH_MASK (0x1F)
  221290. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_MASK (0x3 << 3)
  221291. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_SDR_NORMAL (0x0)
  221292. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_SDR_HIGH (0x1)
  221293. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_DDR (0x2)
  221294. +#define EXT_CSD_BOOT_BUS_WIDTH_RST_WIDTH (1 << 2)
  221295. +#define EXT_CSD_BOOT_BUS_WIDTH_WIDTH_MASK (0x3)
  221296. +#define EXT_CSD_BOOT_BUS_WIDTH_1_SDR_4_DDR (0x0)
  221297. +#define EXT_CSD_BOOT_BUS_WIDTH_4_SDR_4_DDR (0x1)
  221298. +#define EXT_CSD_BOOT_BUS_WIDTH_8_SDR_8_DDR (0x2)
  221299. +
  221300. +#define EXT_CSD_BOOT_ACK_ENABLE (0x1 << 6)
  221301. +#define EXT_CSD_BOOT_PARTITION_ENABLE_MASK (0x7 << 3)
  221302. +#define EXT_CSD_BOOT_PARTITION_DISABLE (0x0)
  221303. +#define EXT_CSD_BOOT_PARTITION_PART1 (0x1 << 3)
  221304. +#define EXT_CSD_BOOT_PARTITION_PART2 (0x2 << 3)
  221305. +#define EXT_CSD_BOOT_PARTITION_USER (0x7 << 3)
  221306. +
  221307. +#define EXT_CSD_BOOT_PARTITION_ACCESS_MASK (0x7)
  221308. +#define EXT_CSD_BOOT_PARTITION_ACCESS_DISABLE (0x0)
  221309. +#define EXT_CSD_BOOT_PARTITION_ACCESS_PART1 (0x1)
  221310. +#define EXT_CSD_BOOT_PARTITION_ACCESS_PART2 (0x2)
  221311. +
  221312. #define EXT_CSD_RST_N_EN_MASK 0x3
  221313. #define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
  221314. diff -Nur linux-3.14.15/include/linux/mmc/sdhci.h linux-linaro-stable-mx6/include/linux/mmc/sdhci.h
  221315. --- linux-3.14.15/include/linux/mmc/sdhci.h 2014-07-31 23:51:43.000000000 +0200
  221316. +++ linux-linaro-stable-mx6/include/linux/mmc/sdhci.h 2014-08-20 19:31:52.560896617 +0200
  221317. @@ -57,12 +57,8 @@
  221318. #define SDHCI_QUIRK_BROKEN_CARD_DETECTION (1<<15)
  221319. /* Controller reports inverted write-protect state */
  221320. #define SDHCI_QUIRK_INVERTED_WRITE_PROTECT (1<<16)
  221321. -/* Controller has nonstandard clock management */
  221322. -#define SDHCI_QUIRK_NONSTANDARD_CLOCK (1<<17)
  221323. /* Controller does not like fast PIO transfers */
  221324. #define SDHCI_QUIRK_PIO_NEEDS_DELAY (1<<18)
  221325. -/* Controller losing signal/interrupt enable states after reset */
  221326. -#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET (1<<19)
  221327. /* Controller has to be forced to use block size of 2048 bytes */
  221328. #define SDHCI_QUIRK_FORCE_BLK_SZ_2048 (1<<20)
  221329. /* Controller cannot do multi-block transfers */
  221330. @@ -100,6 +96,7 @@
  221331. #define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
  221332. /* Controller does not support HS200 */
  221333. #define SDHCI_QUIRK2_BROKEN_HS200 (1<<6)
  221334. +#define SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER (1<<7)
  221335. int irq; /* Device IRQ */
  221336. void __iomem *ioaddr; /* Mapped address */
  221337. @@ -145,6 +142,7 @@
  221338. bool runtime_suspended; /* Host is runtime suspended */
  221339. bool bus_on; /* Bus power prevents runtime suspend */
  221340. + bool preset_enabled; /* Preset is enabled */
  221341. struct mmc_request *mrq; /* Current request */
  221342. struct mmc_command *cmd; /* Current command */
  221343. @@ -162,8 +160,7 @@
  221344. dma_addr_t adma_addr; /* Mapped ADMA descr. table */
  221345. dma_addr_t align_addr; /* Mapped bounce buffer */
  221346. - struct tasklet_struct card_tasklet; /* Tasklet structures */
  221347. - struct tasklet_struct finish_tasklet;
  221348. + struct tasklet_struct finish_tasklet; /* Tasklet structures */
  221349. struct timer_list timer; /* Timer for timeouts */
  221350. @@ -175,6 +172,13 @@
  221351. unsigned int ocr_avail_mmc;
  221352. u32 ocr_mask; /* available voltages */
  221353. + unsigned timing; /* Current timing */
  221354. +
  221355. + u32 thread_isr;
  221356. +
  221357. + /* cached registers */
  221358. + u32 ier;
  221359. +
  221360. wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */
  221361. unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */
  221362. diff -Nur linux-3.14.15/include/linux/mmc/sdio_ids.h linux-linaro-stable-mx6/include/linux/mmc/sdio_ids.h
  221363. --- linux-3.14.15/include/linux/mmc/sdio_ids.h 2014-07-31 23:51:43.000000000 +0200
  221364. +++ linux-linaro-stable-mx6/include/linux/mmc/sdio_ids.h 2014-08-20 19:31:52.560896617 +0200
  221365. @@ -31,6 +31,7 @@
  221366. #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
  221367. #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335
  221368. #define SDIO_DEVICE_ID_BROADCOM_43362 43362
  221369. +#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
  221370. #define SDIO_VENDOR_ID_INTEL 0x0089
  221371. #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402
  221372. diff -Nur linux-3.14.15/include/linux/mod_devicetable.h linux-linaro-stable-mx6/include/linux/mod_devicetable.h
  221373. --- linux-3.14.15/include/linux/mod_devicetable.h 2014-07-31 23:51:43.000000000 +0200
  221374. +++ linux-linaro-stable-mx6/include/linux/mod_devicetable.h 2014-08-20 19:31:52.560896617 +0200
  221375. @@ -564,6 +564,15 @@
  221376. #define X86_MODEL_ANY 0
  221377. #define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */
  221378. +/*
  221379. + * Generic table type for matching CPU features.
  221380. + * @feature: the bit number of the feature (0 - 65535)
  221381. + */
  221382. +
  221383. +struct cpu_feature {
  221384. + __u16 feature;
  221385. +};
  221386. +
  221387. #define IPACK_ANY_FORMAT 0xff
  221388. #define IPACK_ANY_ID (~0)
  221389. struct ipack_device_id {
  221390. diff -Nur linux-3.14.15/include/linux/mtd/map.h linux-linaro-stable-mx6/include/linux/mtd/map.h
  221391. --- linux-3.14.15/include/linux/mtd/map.h 2014-07-31 23:51:43.000000000 +0200
  221392. +++ linux-linaro-stable-mx6/include/linux/mtd/map.h 2014-08-20 19:24:05.734897826 +0200
  221393. @@ -438,7 +438,7 @@
  221394. if (map->cached)
  221395. memcpy(to, (char *)map->cached + from, len);
  221396. else
  221397. - memcpy_fromio(to, map->virt + from, len);
  221398. + memcpy(to, map->virt + from, len);
  221399. }
  221400. static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
  221401. diff -Nur linux-3.14.15/include/linux/mxc_asrc.h linux-linaro-stable-mx6/include/linux/mxc_asrc.h
  221402. --- linux-3.14.15/include/linux/mxc_asrc.h 1970-01-01 01:00:00.000000000 +0100
  221403. +++ linux-linaro-stable-mx6/include/linux/mxc_asrc.h 2014-08-20 19:24:05.738897843 +0200
  221404. @@ -0,0 +1,386 @@
  221405. +/*
  221406. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  221407. + *
  221408. + * The code contained herein is licensed under the GNU General Public
  221409. + * License. You may obtain a copy of the GNU General Public License
  221410. + * Version 2 or later at the following locations:
  221411. + *
  221412. + * http://www.opensource.org/licenses/gpl-license.html
  221413. + * http://www.gnu.org/copyleft/gpl.html
  221414. + *
  221415. + * @file mxc_asrc.h
  221416. + *
  221417. + * @brief i.MX Asynchronous Sample Rate Converter
  221418. + *
  221419. + * @ingroup Audio
  221420. + */
  221421. +
  221422. +#ifndef __MXC_ASRC_H__
  221423. +#define __MXC_ASRC_H__
  221424. +
  221425. +#include <uapi/linux/mxc_asrc.h>
  221426. +#include <linux/scatterlist.h>
  221427. +
  221428. +#define ASRC_DMA_BUFFER_NUM 2
  221429. +#define ASRC_INPUTFIFO_THRESHOLD 32
  221430. +#define ASRC_OUTPUTFIFO_THRESHOLD 32
  221431. +#define ASRC_FIFO_THRESHOLD_MIN 0
  221432. +#define ASRC_FIFO_THRESHOLD_MAX 63
  221433. +#define ASRC_DMA_BUFFER_SIZE (1024 * 48 * 4)
  221434. +#define ASRC_MAX_BUFFER_SIZE (1024 * 48)
  221435. +#define ASRC_OUTPUT_LAST_SAMPLE_DEFAULT 8
  221436. +
  221437. +
  221438. +/* Ideal Ratio mode doesn't care the outclk frequency, so be fixed */
  221439. +#define ASRC_PRESCALER_IDEAL_RATIO 5
  221440. +/* SPDIF rxclk pulse rate is 128 * samplerate, so 2 ^ 7 */
  221441. +#define ASRC_PRESCALER_SPDIF_RX 7
  221442. +/* SPDIF txclk pulse rate is 64 * samplerate, so 2 ^ 6 */
  221443. +#define ASRC_PRESCALER_SPDIF_TX 6
  221444. +/* I2S bclk is 16 * 2 = 32, so 2 ^ 5 */
  221445. +#define ASRC_PRESCALER_I2S_16BIT 5
  221446. +/* I2S bclk is 24 * 2 = 48 -> 64, so 2 ^ 6 */
  221447. +#define ASRC_PRESCALER_I2S_24BIT 6
  221448. +
  221449. +
  221450. +#define REG_ASRCTR 0x00
  221451. +#define REG_ASRIER 0x04
  221452. +#define REG_ASRCNCR 0x0C
  221453. +#define REG_ASRCFG 0x10
  221454. +#define REG_ASRCSR 0x14
  221455. +
  221456. +#define REG_ASRCDR1 0x18
  221457. +#define REG_ASRCDR2 0x1C
  221458. +#define REG_ASRCDR(x) ((x < 2) ? REG_ASRCDR1 : REG_ASRCDR2)
  221459. +
  221460. +#define REG_ASRSTR 0x20
  221461. +#define REG_ASRRA 0x24
  221462. +#define REG_ASRRB 0x28
  221463. +#define REG_ASRRC 0x2C
  221464. +#define REG_ASRPM1 0x40
  221465. +#define REG_ASRPM2 0x44
  221466. +#define REG_ASRPM3 0x48
  221467. +#define REG_ASRPM4 0x4C
  221468. +#define REG_ASRPM5 0x50
  221469. +#define REG_ASRTFR1 0x54
  221470. +#define REG_ASRCCR 0x5C
  221471. +
  221472. +#define REG_ASRDIA 0x60
  221473. +#define REG_ASRDOA 0x64
  221474. +#define REG_ASRDIB 0x68
  221475. +#define REG_ASRDOB 0x6C
  221476. +#define REG_ASRDIC 0x70
  221477. +#define REG_ASRDOC 0x74
  221478. +#define REG_ASRDI(x) (REG_ASRDIA + (x << 3))
  221479. +#define REG_ASRDO(x) (REG_ASRDOA + (x << 3))
  221480. +
  221481. +#define REG_ASRIDRHA 0x80
  221482. +#define REG_ASRIDRLA 0x84
  221483. +#define REG_ASRIDRHB 0x88
  221484. +#define REG_ASRIDRLB 0x8C
  221485. +#define REG_ASRIDRHC 0x90
  221486. +#define REG_ASRIDRLC 0x94
  221487. +#define REG_ASRIDRH(x) (REG_ASRIDRHA + (x << 3))
  221488. +#define REG_ASRIDRL(x) (REG_ASRIDRLA + (x << 3))
  221489. +
  221490. +#define REG_ASR76K 0x98
  221491. +#define REG_ASR56K 0x9C
  221492. +
  221493. +#define REG_ASRMCRA 0xA0
  221494. +#define REG_ASRFSTA 0xA4
  221495. +#define REG_ASRMCRB 0xA8
  221496. +#define REG_ASRFSTB 0xAC
  221497. +#define REG_ASRMCRC 0xB0
  221498. +#define REG_ASRFSTC 0xB4
  221499. +#define REG_ASRMCR(x) (REG_ASRMCRA + (x << 3))
  221500. +#define REG_ASRFST(x) (REG_ASRFSTA + (x << 3))
  221501. +
  221502. +#define REG_ASRMCR1A 0xC0
  221503. +#define REG_ASRMCR1B 0xC4
  221504. +#define REG_ASRMCR1C 0xC8
  221505. +#define REG_ASRMCR1(x) (REG_ASRMCR1A + (x << 2))
  221506. +
  221507. +
  221508. +/* REG0 0x00 REG_ASRCTR */
  221509. +#define ASRCTR_ATSx_SHIFT(x) (20 + x)
  221510. +#define ASRCTR_ATSx_MASK(x) (1 << ASRCTR_ATSx_SHIFT(x))
  221511. +#define ASRCTR_ATS(x) (1 << ASRCTR_ATSx_SHIFT(x))
  221512. +#define ASRCTR_USRx_SHIFT(x) (14 + (x << 1))
  221513. +#define ASRCTR_USRx_MASK(x) (1 << ASRCTR_USRx_SHIFT(x))
  221514. +#define ASRCTR_USR(x) (1 << ASRCTR_USRx_SHIFT(x))
  221515. +#define ASRCTR_IDRx_SHIFT(x) (13 + (x << 1))
  221516. +#define ASRCTR_IDRx_MASK(x) (1 << ASRCTR_IDRx_SHIFT(x))
  221517. +#define ASRCTR_IDR(x) (1 << ASRCTR_IDRx_SHIFT(x))
  221518. +#define ASRCTR_SRST_SHIFT 4
  221519. +#define ASRCTR_SRST_MASK (1 << ASRCTR_SRST_SHIFT)
  221520. +#define ASRCTR_SRST (1 << ASRCTR_SRST_SHIFT)
  221521. +#define ASRCTR_ASRCEx_SHIFT(x) (1 + x)
  221522. +#define ASRCTR_ASRCEx_MASK(x) (1 << ASRCTR_ASRCEx_SHIFT(x))
  221523. +#define ASRCTR_ASRCE(x) (1 << ASRCTR_ASRCEx_SHIFT(x))
  221524. +#define ASRCTR_ASRCEN_SHIFT 0
  221525. +#define ASRCTR_ASRCEN_MASK (1 << ASRCTR_ASRCEN_SHIFT)
  221526. +#define ASRCTR_ASRCEN (1 << ASRCTR_ASRCEN_SHIFT)
  221527. +
  221528. +/* REG1 0x04 REG_ASRIER */
  221529. +#define ASRIER_AFPWE_SHIFT 7
  221530. +#define ASRIER_AFPWE_MASK (1 << ASRIER_AFPWE_SHIFT)
  221531. +#define ASRIER_AFPWE (1 << ASRIER_AFPWE_SHIFT)
  221532. +#define ASRIER_AOLIE_SHIFT 6
  221533. +#define ASRIER_AOLIE_MASK (1 << ASRIER_AOLIE_SHIFT)
  221534. +#define ASRIER_AOLIE (1 << ASRIER_AOLIE_SHIFT)
  221535. +#define ASRIER_ADOEx_SHIFT(x) (3 + x)
  221536. +#define ASRIER_ADOEx_MASK(x) (1 << ASRIER_ADOEx_SHIFT(x))
  221537. +#define ASRIER_ADOE(x) (1 << ASRIER_ADOEx_SHIFT(x))
  221538. +#define ASRIER_ADIEx_SHIFT(x) (0 + x)
  221539. +#define ASRIER_ADIEx_MASK(x) (1 << ASRIER_ADIEx_SHIFT(x))
  221540. +#define ASRIER_ADIE(x) (1 << ASRIER_ADIEx_SHIFT(x))
  221541. +
  221542. +/* REG2 0x0C REG_ASRCNCR */
  221543. +#define ASRCNCR_ANCx_SHIFT(x, b) (b * x)
  221544. +#define ASRCNCR_ANCx_MASK(x, b) (((1 << b) - 1) << ASRCNCR_ANCx_SHIFT(x, b))
  221545. +#define ASRCNCR_ANCx_get(x, v, b) ((v & ASRCNCR_ANCx_MASK(x, b)) >> ASRCNCR_ANCx_SHIFT(x, b))
  221546. +#define ASRCNCR_ANCx_set(x, v, b) ((v << ASRCNCR_ANCx_SHIFT(x, b)) & ASRCNCR_ANCx_MASK(x, b))
  221547. +
  221548. +/* REG3 0x10 REG_ASRCFG */
  221549. +#define ASRCFG_INIRQx_SHIFT(x) (21 + x)
  221550. +#define ASRCFG_INIRQx_MASK(x) (1 << ASRCFG_INIRQx_SHIFT(x))
  221551. +#define ASRCFG_INIRQx (1 << ASRCFG_INIRQx_SHIFT(x))
  221552. +#define ASRCFG_NDPRx_SHIFT(x) (18 + x)
  221553. +#define ASRCFG_NDPRx_MASK(x) (1 << ASRCFG_NDPRx_SHIFT(x))
  221554. +#define ASRCFG_NDPRx (1 << ASRCFG_NDPRx_SHIFT(x))
  221555. +#define ASRCFG_POSTMODx_SHIFT(x) (8 + (x << 2))
  221556. +#define ASRCFG_POSTMODx_WIDTH 2
  221557. +#define ASRCFG_POSTMODx_MASK(x) (((1 << ASRCFG_POSTMODx_WIDTH) - 1) << ASRCFG_POSTMODx_SHIFT(x))
  221558. +#define ASRCFG_POSTMOD(x, v) ((v) << ASRCFG_POSTMODx_SHIFT(x))
  221559. +#define ASRCFG_POSTMODx_UP(x) (0 << ASRCFG_POSTMODx_SHIFT(x))
  221560. +#define ASRCFG_POSTMODx_DCON(x) (1 << ASRCFG_POSTMODx_SHIFT(x))
  221561. +#define ASRCFG_POSTMODx_DOWN(x) (2 << ASRCFG_POSTMODx_SHIFT(x))
  221562. +#define ASRCFG_PREMODx_SHIFT(x) (6 + (x << 2))
  221563. +#define ASRCFG_PREMODx_WIDTH 2
  221564. +#define ASRCFG_PREMODx_MASK(x) (((1 << ASRCFG_PREMODx_WIDTH) - 1) << ASRCFG_PREMODx_SHIFT(x))
  221565. +#define ASRCFG_PREMOD(x, v) ((v) << ASRCFG_PREMODx_SHIFT(x))
  221566. +#define ASRCFG_PREMODx_UP(x) (0 << ASRCFG_PREMODx_SHIFT(x))
  221567. +#define ASRCFG_PREMODx_DCON(x) (1 << ASRCFG_PREMODx_SHIFT(x))
  221568. +#define ASRCFG_PREMODx_DOWN(x) (2 << ASRCFG_PREMODx_SHIFT(x))
  221569. +#define ASRCFG_PREMODx_BYPASS(x) (3 << ASRCFG_PREMODx_SHIFT(x))
  221570. +
  221571. +/* REG4 0x14 REG_ASRCSR */
  221572. +#define ASRCSR_AxCSx_WIDTH 4
  221573. +#define ASRCSR_AxCSx_MASK ((1 << ASRCSR_AxCSx_WIDTH) - 1)
  221574. +#define ASRCSR_AOCSx_SHIFT(x) (12 + (x << 2))
  221575. +#define ASRCSR_AOCSx_MASK(x) (((1 << ASRCSR_AxCSx_WIDTH) - 1) << ASRCSR_AOCSx_SHIFT(x))
  221576. +#define ASRCSR_AOCS(x, v) ((v) << ASRCSR_AOCSx_SHIFT(x))
  221577. +#define ASRCSR_AICSx_SHIFT(x) (x << 2)
  221578. +#define ASRCSR_AICSx_MASK(x) (((1 << ASRCSR_AxCSx_WIDTH) - 1) << ASRCSR_AICSx_SHIFT(x))
  221579. +#define ASRCSR_AICS(x, v) ((v) << ASRCSR_AICSx_SHIFT(x))
  221580. +
  221581. +/* REG5&6 0x18 & 0x1C REG_ASRCDR1 & ASRCDR2 */
  221582. +#define ASRCDRx_AxCPx_WIDTH 3
  221583. +#define ASRCDRx_AICPx_SHIFT(x) (0 + (x % 2) * 6)
  221584. +#define ASRCDRx_AICPx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AICPx_SHIFT(x))
  221585. +#define ASRCDRx_AICP(x, v) ((v) << ASRCDRx_AICPx_SHIFT(x))
  221586. +#define ASRCDRx_AICDx_SHIFT(x) (3 + (x % 2) * 6)
  221587. +#define ASRCDRx_AICDx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AICDx_SHIFT(x))
  221588. +#define ASRCDRx_AICD(x, v) ((v) << ASRCDRx_AICDx_SHIFT(x))
  221589. +#define ASRCDRx_AOCPx_SHIFT(x) ((x < 2) ? 12 + x * 6 : 6)
  221590. +#define ASRCDRx_AOCPx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AOCPx_SHIFT(x))
  221591. +#define ASRCDRx_AOCP(x, v) ((v) << ASRCDRx_AOCPx_SHIFT(x))
  221592. +#define ASRCDRx_AOCDx_SHIFT(x) ((x < 2) ? 15 + x * 6 : 9)
  221593. +#define ASRCDRx_AOCDx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AOCDx_SHIFT(x))
  221594. +#define ASRCDRx_AOCD(x, v) ((v) << ASRCDRx_AOCDx_SHIFT(x))
  221595. +
  221596. +/* REG7 0x20 REG_ASRSTR */
  221597. +#define ASRSTR_DSLCNT_SHIFT 21
  221598. +#define ASRSTR_DSLCNT_MASK (1 << ASRSTR_DSLCNT_SHIFT)
  221599. +#define ASRSTR_DSLCNT (1 << ASRSTR_DSLCNT_SHIFT)
  221600. +#define ASRSTR_ATQOL_SHIFT 20
  221601. +#define ASRSTR_ATQOL_MASK (1 << ASRSTR_ATQOL_SHIFT)
  221602. +#define ASRSTR_ATQOL (1 << ASRSTR_ATQOL_SHIFT)
  221603. +#define ASRSTR_AOOLx_SHIFT(x) (17 + x)
  221604. +#define ASRSTR_AOOLx_MASK(x) (1 << ASRSTR_AOOLx_SHIFT(x))
  221605. +#define ASRSTR_AOOL(x) (1 << ASRSTR_AOOLx_SHIFT(x))
  221606. +#define ASRSTR_AIOLx_SHIFT(x) (14 + x)
  221607. +#define ASRSTR_AIOLx_MASK(x) (1 << ASRSTR_AIOLx_SHIFT(x))
  221608. +#define ASRSTR_AIOL(x) (1 << ASRSTR_AIOLx_SHIFT(x))
  221609. +#define ASRSTR_AODOx_SHIFT(x) (11 + x)
  221610. +#define ASRSTR_AODOx_MASK(x) (1 << ASRSTR_AODOx_SHIFT(x))
  221611. +#define ASRSTR_AODO(x) (1 << ASRSTR_AODOx_SHIFT(x))
  221612. +#define ASRSTR_AIDUx_SHIFT(x) (8 + x)
  221613. +#define ASRSTR_AIDUx_MASK(x) (1 << ASRSTR_AIDUx_SHIFT(x))
  221614. +#define ASRSTR_AIDU(x) (1 << ASRSTR_AIDUx_SHIFT(x))
  221615. +#define ASRSTR_FPWT_SHIFT 7
  221616. +#define ASRSTR_FPWT_MASK (1 << ASRSTR_FPWT_SHIFT)
  221617. +#define ASRSTR_FPWT (1 << ASRSTR_FPWT_SHIFT)
  221618. +#define ASRSTR_AOLE_SHIFT 6
  221619. +#define ASRSTR_AOLE_MASK (1 << ASRSTR_AOLE_SHIFT)
  221620. +#define ASRSTR_AOLE (1 << ASRSTR_AOLE_SHIFT)
  221621. +#define ASRSTR_AODEx_SHIFT(x) (3 + x)
  221622. +#define ASRSTR_AODFx_MASK(x) (1 << ASRSTR_AODEx_SHIFT(x))
  221623. +#define ASRSTR_AODF(x) (1 << ASRSTR_AODEx_SHIFT(x))
  221624. +#define ASRSTR_AIDEx_SHIFT(x) (0 + x)
  221625. +#define ASRSTR_AIDEx_MASK(x) (1 << ASRSTR_AIDEx_SHIFT(x))
  221626. +#define ASRSTR_AIDE(x) (1 << ASRSTR_AIDEx_SHIFT(x))
  221627. +
  221628. +/* REG10 0x54 REG_ASRTFR1 */
  221629. +#define ASRTFR1_TF_BASE_WIDTH 7
  221630. +#define ASRTFR1_TF_BASE_SHIFT 6
  221631. +#define ASRTFR1_TF_BASE_MASK (((1 << ASRTFR1_TF_BASE_WIDTH) - 1) << ASRTFR1_TF_BASE_SHIFT)
  221632. +#define ASRTFR1_TF_BASE(x) ((x) << ASRTFR1_TF_BASE_SHIFT)
  221633. +
  221634. +/*
  221635. + * REG22 0xA0 REG_ASRMCRA
  221636. + * REG24 0xA8 REG_ASRMCRB
  221637. + * REG26 0xB0 REG_ASRMCRC
  221638. + */
  221639. +#define ASRMCRx_ZEROBUFx_SHIFT 23
  221640. +#define ASRMCRx_ZEROBUFxCLR_MASK (1 << ASRMCRx_ZEROBUFx_SHIFT)
  221641. +#define ASRMCRx_ZEROBUFxCLR (1 << ASRMCRx_ZEROBUFx_SHIFT)
  221642. +#define ASRMCRx_EXTTHRSHx_SHIFT 22
  221643. +#define ASRMCRx_EXTTHRSHx_MASK (1 << ASRMCRx_EXTTHRSHx_SHIFT)
  221644. +#define ASRMCRx_EXTTHRSHx (1 << ASRMCRx_EXTTHRSHx_SHIFT)
  221645. +#define ASRMCRx_BUFSTALLx_SHIFT 21
  221646. +#define ASRMCRx_BUFSTALLx_MASK (1 << ASRMCRx_BUFSTALLx_SHIFT)
  221647. +#define ASRMCRx_BUFSTALLx (1 << ASRMCRx_BUFSTALLx_SHIFT)
  221648. +#define ASRMCRx_BYPASSPOLYx_SHIFT 20
  221649. +#define ASRMCRx_BYPASSPOLYx_MASK (1 << ASRMCRx_BYPASSPOLYx_SHIFT)
  221650. +#define ASRMCRx_BYPASSPOLYx (1 << ASRMCRx_BYPASSPOLYx_SHIFT)
  221651. +#define ASRMCRx_OUTFIFO_THRESHOLD_WIDTH 6
  221652. +#define ASRMCRx_OUTFIFO_THRESHOLD_SHIFT 12
  221653. +#define ASRMCRx_OUTFIFO_THRESHOLD_MASK (((1 << ASRMCRx_OUTFIFO_THRESHOLD_WIDTH) - 1) << ASRMCRx_OUTFIFO_THRESHOLD_SHIFT)
  221654. +#define ASRMCRx_OUTFIFO_THRESHOLD(v) (((v) << ASRMCRx_OUTFIFO_THRESHOLD_SHIFT) & ASRMCRx_OUTFIFO_THRESHOLD_MASK)
  221655. +#define ASRMCRx_RSYNIFx_SHIFT 11
  221656. +#define ASRMCRx_RSYNIFx_MASK (1 << ASRMCRx_RSYNIFx_SHIFT)
  221657. +#define ASRMCRx_RSYNIFx (1 << ASRMCRx_RSYNIFx_SHIFT)
  221658. +#define ASRMCRx_RSYNOFx_SHIFT 10
  221659. +#define ASRMCRx_RSYNOFx_MASK (1 << ASRMCRx_RSYNOFx_SHIFT)
  221660. +#define ASRMCRx_RSYNOFx (1 << ASRMCRx_RSYNOFx_SHIFT)
  221661. +#define ASRMCRx_INFIFO_THRESHOLD_WIDTH 6
  221662. +#define ASRMCRx_INFIFO_THRESHOLD_SHIFT 0
  221663. +#define ASRMCRx_INFIFO_THRESHOLD_MASK (((1 << ASRMCRx_INFIFO_THRESHOLD_WIDTH) - 1) << ASRMCRx_INFIFO_THRESHOLD_SHIFT)
  221664. +#define ASRMCRx_INFIFO_THRESHOLD(v) (((v) << ASRMCRx_INFIFO_THRESHOLD_SHIFT) & ASRMCRx_INFIFO_THRESHOLD_MASK)
  221665. +
  221666. +/*
  221667. + * REG23 0xA4 REG_ASRFSTA
  221668. + * REG25 0xAC REG_ASRFSTB
  221669. + * REG27 0xB4 REG_ASRFSTC
  221670. + */
  221671. +#define ASRFSTx_OAFx_SHIFT 23
  221672. +#define ASRFSTx_OAFx_MASK (1 << ASRFSTx_OAFx_SHIFT)
  221673. +#define ASRFSTx_OAFx (1 << ASRFSTx_OAFx_SHIFT)
  221674. +#define ASRFSTx_OUTPUT_FIFO_WIDTH 7
  221675. +#define ASRFSTx_OUTPUT_FIFO_SHIFT 12
  221676. +#define ASRFSTx_OUTPUT_FIFO_MASK (((1 << ASRFSTx_OUTPUT_FIFO_WIDTH) - 1) << ASRFSTx_OUTPUT_FIFO_SHIFT)
  221677. +#define ASRFSTx_IAEx_SHIFT 11
  221678. +#define ASRFSTx_IAEx_MASK (1 << ASRFSTx_OAFx_SHIFT)
  221679. +#define ASRFSTx_IAEx (1 << ASRFSTx_OAFx_SHIFT)
  221680. +#define ASRFSTx_INPUT_FIFO_WIDTH 7
  221681. +#define ASRFSTx_INPUT_FIFO_SHIFT 0
  221682. +#define ASRFSTx_INPUT_FIFO_MASK ((1 << ASRFSTx_INPUT_FIFO_WIDTH) - 1)
  221683. +
  221684. +/* REG28 0xC0 & 0xC4 & 0xC8 REG_ASRMCR1x */
  221685. +#define ASRMCR1x_IWD_WIDTH 3
  221686. +#define ASRMCR1x_IWD_SHIFT 9
  221687. +#define ASRMCR1x_IWD_MASK (((1 << ASRMCR1x_IWD_WIDTH) - 1) << ASRMCR1x_IWD_SHIFT)
  221688. +#define ASRMCR1x_IWD(v) ((v) << ASRMCR1x_IWD_SHIFT)
  221689. +#define ASRMCR1x_IMSB_SHIFT 8
  221690. +#define ASRMCR1x_IMSB_MASK (1 << ASRMCR1x_IMSB_SHIFT)
  221691. +#define ASRMCR1x_IMSB_MSB (1 << ASRMCR1x_IMSB_SHIFT)
  221692. +#define ASRMCR1x_IMSB_LSB (0 << ASRMCR1x_IMSB_SHIFT)
  221693. +#define ASRMCR1x_OMSB_SHIFT 2
  221694. +#define ASRMCR1x_OMSB_MASK (1 << ASRMCR1x_OMSB_SHIFT)
  221695. +#define ASRMCR1x_OMSB_MSB (1 << ASRMCR1x_OMSB_SHIFT)
  221696. +#define ASRMCR1x_OMSB_LSB (0 << ASRMCR1x_OMSB_SHIFT)
  221697. +#define ASRMCR1x_OSGN_SHIFT 1
  221698. +#define ASRMCR1x_OSGN_MASK (1 << ASRMCR1x_OSGN_SHIFT)
  221699. +#define ASRMCR1x_OSGN (1 << ASRMCR1x_OSGN_SHIFT)
  221700. +#define ASRMCR1x_OW16_SHIFT 0
  221701. +#define ASRMCR1x_OW16_MASK (1 << ASRMCR1x_OW16_SHIFT)
  221702. +#define ASRMCR1x_OW16(v) ((v) << ASRMCR1x_OW16_SHIFT)
  221703. +
  221704. +
  221705. +struct dma_block {
  221706. + unsigned int index;
  221707. + unsigned int length;
  221708. + void *dma_vaddr;
  221709. + dma_addr_t dma_paddr;
  221710. + struct list_head queue;
  221711. +};
  221712. +
  221713. +struct asrc_p2p_params {
  221714. + u32 p2p_rate; /* ASRC output rate for p2p */
  221715. + enum asrc_word_width p2p_width; /* ASRC output wordwidth for p2p */
  221716. +};
  221717. +
  221718. +struct asrc_pair_params {
  221719. + enum asrc_pair_index index;
  221720. + struct completion input_complete;
  221721. + struct completion output_complete;
  221722. + struct completion lastperiod_complete;
  221723. + struct dma_chan *input_dma_channel;
  221724. + struct dma_chan *output_dma_channel;
  221725. + unsigned int input_buffer_size;
  221726. + unsigned int output_buffer_size;
  221727. + unsigned int buffer_num;
  221728. + unsigned int pair_hold;
  221729. + unsigned int asrc_active;
  221730. + unsigned int channel_nums;
  221731. + struct dma_block input_dma_total;
  221732. + struct dma_block input_dma[ASRC_DMA_BUFFER_NUM];
  221733. + struct dma_block output_dma_total;
  221734. + struct dma_block output_dma[ASRC_DMA_BUFFER_NUM];
  221735. + struct dma_block output_last_period;
  221736. + struct dma_async_tx_descriptor *desc_in;
  221737. + struct dma_async_tx_descriptor *desc_out;
  221738. + struct work_struct task_output_work;
  221739. + unsigned int input_sg_nodes;
  221740. + unsigned int output_sg_nodes;
  221741. + struct scatterlist input_sg[4], output_sg[4];
  221742. + enum asrc_word_width input_word_width;
  221743. + enum asrc_word_width output_word_width;
  221744. + u32 input_sample_rate;
  221745. + u32 output_sample_rate;
  221746. + u32 input_wm;
  221747. + u32 output_wm;
  221748. + unsigned int last_period_sample;
  221749. +};
  221750. +
  221751. +struct asrc_data {
  221752. + struct asrc_pair asrc_pair[ASRC_PAIR_MAX_NUM];
  221753. + struct proc_dir_entry *proc_asrc;
  221754. + struct class *asrc_class;
  221755. + struct regmap *regmap;
  221756. + struct clk *asrc_clk;
  221757. + struct clk *dma_clk;
  221758. + unsigned long paddr;
  221759. + unsigned int channel_bits;
  221760. + int asrc_major;
  221761. + int irq;
  221762. + struct device *dev;
  221763. +};
  221764. +
  221765. +struct asrc_p2p_ops {
  221766. + void (*asrc_p2p_start_conv)(enum asrc_pair_index);
  221767. + void (*asrc_p2p_stop_conv)(enum asrc_pair_index);
  221768. + int (*asrc_p2p_get_dma_request)(enum asrc_pair_index, bool);
  221769. + u32 (*asrc_p2p_per_addr)(enum asrc_pair_index, bool);
  221770. + int (*asrc_p2p_req_pair)(int, enum asrc_pair_index *index);
  221771. + int (*asrc_p2p_config_pair)(struct asrc_config *config);
  221772. + void (*asrc_p2p_release_pair)(enum asrc_pair_index);
  221773. + void (*asrc_p2p_finish_conv)(enum asrc_pair_index);
  221774. +};
  221775. +
  221776. +extern void asrc_p2p_hook(struct asrc_p2p_ops *asrc_p2p_ct);
  221777. +
  221778. +extern int asrc_req_pair(int chn_num, enum asrc_pair_index *index);
  221779. +extern void asrc_release_pair(enum asrc_pair_index index);
  221780. +extern int asrc_config_pair(struct asrc_config *config);
  221781. +extern void asrc_get_status(struct asrc_status_flags *flags);
  221782. +extern void asrc_start_conv(enum asrc_pair_index index);
  221783. +extern void asrc_stop_conv(enum asrc_pair_index index);
  221784. +extern u32 asrc_get_per_addr(enum asrc_pair_index index, bool i);
  221785. +extern int asrc_get_dma_request(enum asrc_pair_index index, bool i);
  221786. +extern void asrc_finish_conv(enum asrc_pair_index index);
  221787. +extern int asrc_set_watermark(enum asrc_pair_index index,
  221788. + u32 in_wm, u32 out_wm);
  221789. +
  221790. +#endif/* __MXC_ASRC_H__ */
  221791. diff -Nur linux-3.14.15/include/linux/mxcfb.h linux-linaro-stable-mx6/include/linux/mxcfb.h
  221792. --- linux-3.14.15/include/linux/mxcfb.h 1970-01-01 01:00:00.000000000 +0100
  221793. +++ linux-linaro-stable-mx6/include/linux/mxcfb.h 2014-08-20 19:24:05.738897843 +0200
  221794. @@ -0,0 +1,46 @@
  221795. +/*
  221796. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  221797. + */
  221798. +
  221799. +/*
  221800. + * The code contained herein is licensed under the GNU Lesser General
  221801. + * Public License. You may obtain a copy of the GNU Lesser General
  221802. + * Public License Version 2.1 or later at the following locations:
  221803. + *
  221804. + * http://www.opensource.org/licenses/lgpl-license.html
  221805. + * http://www.gnu.org/copyleft/lgpl.html
  221806. + */
  221807. +
  221808. +/*
  221809. + * @file linux/mxcfb.h
  221810. + *
  221811. + * @brief Global header file for the MXC Frame buffer
  221812. + *
  221813. + * @ingroup Framebuffer
  221814. + */
  221815. +#ifndef __LINUX_MXCFB_H__
  221816. +#define __LINUX_MXCFB_H__
  221817. +
  221818. +#include <uapi/linux/mxcfb.h>
  221819. +
  221820. +extern struct fb_videomode mxcfb_modedb[];
  221821. +extern int mxcfb_modedb_sz;
  221822. +
  221823. +enum {
  221824. + MXC_DISP_SPEC_DEV = 0,
  221825. + MXC_DISP_DDC_DEV = 1,
  221826. +};
  221827. +
  221828. +enum {
  221829. + MXCFB_REFRESH_OFF,
  221830. + MXCFB_REFRESH_AUTO,
  221831. + MXCFB_REFRESH_PARTIAL,
  221832. +};
  221833. +
  221834. +int mxcfb_set_refresh_mode(struct fb_info *fbi, int mode,
  221835. + struct mxcfb_rect *update_region);
  221836. +int mxc_elcdif_frame_addr_setup(dma_addr_t phys);
  221837. +void mxcfb_elcdif_register_mode(const struct fb_videomode *modedb,
  221838. + int num_modes, int dev_mode);
  221839. +
  221840. +#endif
  221841. diff -Nur linux-3.14.15/include/linux/mxc_mlb.h linux-linaro-stable-mx6/include/linux/mxc_mlb.h
  221842. --- linux-3.14.15/include/linux/mxc_mlb.h 1970-01-01 01:00:00.000000000 +0100
  221843. +++ linux-linaro-stable-mx6/include/linux/mxc_mlb.h 2014-08-20 19:24:05.738897843 +0200
  221844. @@ -0,0 +1,55 @@
  221845. +/*
  221846. + * mxc_mlb.h
  221847. + *
  221848. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  221849. + */
  221850. +
  221851. +/*
  221852. + * The code contained herein is licensed under the GNU General Public
  221853. + * License. You may obtain a copy of the GNU General Public License
  221854. + * Version 2 or later at the following locations:
  221855. + *
  221856. + * http://www.opensource.org/licenses/gpl-license.html
  221857. + * http://www.gnu.org/copyleft/gpl.html
  221858. + */
  221859. +
  221860. +#ifndef _MXC_MLB_H
  221861. +#define _MXC_MLB_H
  221862. +
  221863. +/* define IOCTL command */
  221864. +#define MLB_DBG_RUNTIME _IO('S', 0x09)
  221865. +#define MLB_SET_FPS _IOW('S', 0x10, unsigned int)
  221866. +#define MLB_GET_VER _IOR('S', 0x11, unsigned long)
  221867. +#define MLB_SET_DEVADDR _IOR('S', 0x12, unsigned char)
  221868. +
  221869. +/*!
  221870. + * set channel address for each logical channel
  221871. + * the MSB 16bits is for tx channel, the left LSB is for rx channel
  221872. + */
  221873. +#define MLB_CHAN_SETADDR _IOW('S', 0x13, unsigned int)
  221874. +#define MLB_CHAN_STARTUP _IO('S', 0x14)
  221875. +#define MLB_CHAN_SHUTDOWN _IO('S', 0x15)
  221876. +#define MLB_CHAN_GETEVENT _IOR('S', 0x16, unsigned long)
  221877. +
  221878. +#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
  221879. +#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
  221880. +#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
  221881. +#define MLB_IRQ_ENABLE _IO('S', 0x20)
  221882. +#define MLB_IRQ_DISABLE _IO('S', 0x21)
  221883. +
  221884. +/*!
  221885. + * MLB event define
  221886. + */
  221887. +enum {
  221888. + MLB_EVT_TX_PROTO_ERR_CUR = 1 << 0,
  221889. + MLB_EVT_TX_BRK_DETECT_CUR = 1 << 1,
  221890. + MLB_EVT_TX_PROTO_ERR_PREV = 1 << 8,
  221891. + MLB_EVT_TX_BRK_DETECT_PREV = 1 << 9,
  221892. + MLB_EVT_RX_PROTO_ERR_CUR = 1 << 16,
  221893. + MLB_EVT_RX_BRK_DETECT_CUR = 1 << 17,
  221894. + MLB_EVT_RX_PROTO_ERR_PREV = 1 << 24,
  221895. + MLB_EVT_RX_BRK_DETECT_PREV = 1 << 25,
  221896. +};
  221897. +
  221898. +
  221899. +#endif /* _MXC_MLB_H */
  221900. diff -Nur linux-3.14.15/include/linux/mxc_v4l2.h linux-linaro-stable-mx6/include/linux/mxc_v4l2.h
  221901. --- linux-3.14.15/include/linux/mxc_v4l2.h 1970-01-01 01:00:00.000000000 +0100
  221902. +++ linux-linaro-stable-mx6/include/linux/mxc_v4l2.h 2014-08-20 19:24:05.738897843 +0200
  221903. @@ -0,0 +1,27 @@
  221904. +/*
  221905. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  221906. + */
  221907. +
  221908. +/*
  221909. + * The code contained herein is licensed under the GNU Lesser General
  221910. + * Public License. You may obtain a copy of the GNU Lesser General
  221911. + * Public License Version 2.1 or later at the following locations:
  221912. + *
  221913. + * http://www.opensource.org/licenses/lgpl-license.html
  221914. + * http://www.gnu.org/copyleft/lgpl.html
  221915. + */
  221916. +
  221917. +/*!
  221918. + * @file linux/mxc_v4l2.h
  221919. + *
  221920. + * @brief MXC V4L2 private header file
  221921. + *
  221922. + * @ingroup MXC V4L2
  221923. + */
  221924. +
  221925. +#ifndef __LINUX_MXC_V4L2_H__
  221926. +#define __LINUX_MXC_V4L2_H__
  221927. +
  221928. +#include <uapi/linux/mxc_v4l2.h>
  221929. +
  221930. +#endif
  221931. diff -Nur linux-3.14.15/include/linux/mxc_vpu.h linux-linaro-stable-mx6/include/linux/mxc_vpu.h
  221932. --- linux-3.14.15/include/linux/mxc_vpu.h 1970-01-01 01:00:00.000000000 +0100
  221933. +++ linux-linaro-stable-mx6/include/linux/mxc_vpu.h 2014-08-20 19:24:05.738897843 +0200
  221934. @@ -0,0 +1,118 @@
  221935. +/*
  221936. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  221937. + */
  221938. +
  221939. +/*
  221940. + * The code contained herein is licensed under the GNU Lesser General
  221941. + * Public License. You may obtain a copy of the GNU Lesser General
  221942. + * Public License Version 2.1 or later at the following locations:
  221943. + *
  221944. + * http://www.opensource.org/licenses/lgpl-license.html
  221945. + * http://www.gnu.org/copyleft/lgpl.html
  221946. + */
  221947. +
  221948. +/*!
  221949. + * @defgroup VPU Video Processor Unit Driver
  221950. + */
  221951. +
  221952. +/*!
  221953. + * @file linux/mxc_vpu.h
  221954. + *
  221955. + * @brief VPU system initialization and file operation definition
  221956. + *
  221957. + * @ingroup VPU
  221958. + */
  221959. +
  221960. +#ifndef __LINUX_MXC_VPU_H__
  221961. +#define __LINUX_MXC_VPU_H__
  221962. +
  221963. +#include <linux/fs.h>
  221964. +
  221965. +struct mxc_vpu_platform_data {
  221966. + bool iram_enable;
  221967. + int iram_size;
  221968. + void (*reset) (void);
  221969. + void (*pg) (int);
  221970. +};
  221971. +
  221972. +struct vpu_mem_desc {
  221973. + u32 size;
  221974. + dma_addr_t phy_addr;
  221975. + u32 cpu_addr; /* cpu address to free the dma mem */
  221976. + u32 virt_uaddr; /* virtual user space address */
  221977. +};
  221978. +
  221979. +#define VPU_IOC_MAGIC 'V'
  221980. +
  221981. +#define VPU_IOC_PHYMEM_ALLOC _IO(VPU_IOC_MAGIC, 0)
  221982. +#define VPU_IOC_PHYMEM_FREE _IO(VPU_IOC_MAGIC, 1)
  221983. +#define VPU_IOC_WAIT4INT _IO(VPU_IOC_MAGIC, 2)
  221984. +#define VPU_IOC_PHYMEM_DUMP _IO(VPU_IOC_MAGIC, 3)
  221985. +#define VPU_IOC_REG_DUMP _IO(VPU_IOC_MAGIC, 4)
  221986. +#define VPU_IOC_IRAM_SETTING _IO(VPU_IOC_MAGIC, 6)
  221987. +#define VPU_IOC_CLKGATE_SETTING _IO(VPU_IOC_MAGIC, 7)
  221988. +#define VPU_IOC_GET_WORK_ADDR _IO(VPU_IOC_MAGIC, 8)
  221989. +#define VPU_IOC_REQ_VSHARE_MEM _IO(VPU_IOC_MAGIC, 9)
  221990. +#define VPU_IOC_SYS_SW_RESET _IO(VPU_IOC_MAGIC, 11)
  221991. +#define VPU_IOC_GET_SHARE_MEM _IO(VPU_IOC_MAGIC, 12)
  221992. +#define VPU_IOC_QUERY_BITWORK_MEM _IO(VPU_IOC_MAGIC, 13)
  221993. +#define VPU_IOC_SET_BITWORK_MEM _IO(VPU_IOC_MAGIC, 14)
  221994. +#define VPU_IOC_PHYMEM_CHECK _IO(VPU_IOC_MAGIC, 15)
  221995. +#define VPU_IOC_LOCK_DEV _IO(VPU_IOC_MAGIC, 16)
  221996. +
  221997. +#define BIT_CODE_RUN 0x000
  221998. +#define BIT_CODE_DOWN 0x004
  221999. +#define BIT_INT_CLEAR 0x00C
  222000. +#define BIT_INT_STATUS 0x010
  222001. +#define BIT_CUR_PC 0x018
  222002. +#define BIT_INT_REASON 0x174
  222003. +
  222004. +#define MJPEG_PIC_STATUS_REG 0x3004
  222005. +#define MBC_SET_SUBBLK_EN 0x4A0
  222006. +
  222007. +#define BIT_WORK_CTRL_BUF_BASE 0x100
  222008. +#define BIT_WORK_CTRL_BUF_REG(i) (BIT_WORK_CTRL_BUF_BASE + i * 4)
  222009. +#define BIT_CODE_BUF_ADDR BIT_WORK_CTRL_BUF_REG(0)
  222010. +#define BIT_WORK_BUF_ADDR BIT_WORK_CTRL_BUF_REG(1)
  222011. +#define BIT_PARA_BUF_ADDR BIT_WORK_CTRL_BUF_REG(2)
  222012. +#define BIT_BIT_STREAM_CTRL BIT_WORK_CTRL_BUF_REG(3)
  222013. +#define BIT_FRAME_MEM_CTRL BIT_WORK_CTRL_BUF_REG(4)
  222014. +#define BIT_BIT_STREAM_PARAM BIT_WORK_CTRL_BUF_REG(5)
  222015. +
  222016. +#ifndef CONFIG_SOC_IMX6Q
  222017. +#define BIT_RESET_CTRL 0x11C
  222018. +#else
  222019. +#define BIT_RESET_CTRL 0x128
  222020. +#endif
  222021. +
  222022. +/* i could be 0, 1, 2, 3 */
  222023. +#define BIT_RD_PTR_BASE 0x120
  222024. +#define BIT_RD_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8)
  222025. +#define BIT_WR_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8 + 4)
  222026. +
  222027. +/* i could be 0, 1, 2, 3 */
  222028. +#define BIT_FRM_DIS_FLG_BASE (cpu_is_mx51() ? 0x150 : 0x140)
  222029. +#define BIT_FRM_DIS_FLG_REG(i) (BIT_FRM_DIS_FLG_BASE + i * 4)
  222030. +
  222031. +#define BIT_BUSY_FLAG 0x160
  222032. +#define BIT_RUN_COMMAND 0x164
  222033. +#define BIT_INT_ENABLE 0x170
  222034. +
  222035. +#define BITVAL_PIC_RUN 8
  222036. +
  222037. +#define VPU_SLEEP_REG_VALUE 10
  222038. +#define VPU_WAKE_REG_VALUE 11
  222039. +
  222040. +int vl2cc_init(u32 vl2cc_hw_base);
  222041. +void vl2cc_enable(void);
  222042. +void vl2cc_flush(void);
  222043. +void vl2cc_disable(void);
  222044. +void vl2cc_cleanup(void);
  222045. +
  222046. +int vl2cc_init(u32 vl2cc_hw_base);
  222047. +void vl2cc_enable(void);
  222048. +void vl2cc_flush(void);
  222049. +void vl2cc_disable(void);
  222050. +void vl2cc_cleanup(void);
  222051. +
  222052. +#endif
  222053. diff -Nur linux-3.14.15/include/linux/phy.h linux-linaro-stable-mx6/include/linux/phy.h
  222054. --- linux-3.14.15/include/linux/phy.h 2014-07-31 23:51:43.000000000 +0200
  222055. +++ linux-linaro-stable-mx6/include/linux/phy.h 2014-08-20 19:31:53.076898833 +0200
  222056. @@ -609,6 +609,7 @@
  222057. return phydev->drv->read_status(phydev);
  222058. }
  222059. +int genphy_config_init(struct phy_device *phydev);
  222060. int genphy_setup_forced(struct phy_device *phydev);
  222061. int genphy_restart_aneg(struct phy_device *phydev);
  222062. int genphy_config_aneg(struct phy_device *phydev);
  222063. diff -Nur linux-3.14.15/include/linux/pipe_fs_i.h linux-linaro-stable-mx6/include/linux/pipe_fs_i.h
  222064. --- linux-3.14.15/include/linux/pipe_fs_i.h 2014-07-31 23:51:43.000000000 +0200
  222065. +++ linux-linaro-stable-mx6/include/linux/pipe_fs_i.h 2014-08-20 19:31:53.080898851 +0200
  222066. @@ -35,7 +35,7 @@
  222067. * @tmp_page: cached released page
  222068. * @readers: number of current readers of this pipe
  222069. * @writers: number of current writers of this pipe
  222070. - * @files: number of struct file refering this pipe (protected by ->i_lock)
  222071. + * @files: number of struct file referring this pipe (protected by ->i_lock)
  222072. * @waiting_writers: number of writers blocked waiting for room
  222073. * @r_counter: reader counter
  222074. * @w_counter: writer counter
  222075. diff -Nur linux-3.14.15/include/linux/pl320-ipc.h linux-linaro-stable-mx6/include/linux/pl320-ipc.h
  222076. --- linux-3.14.15/include/linux/pl320-ipc.h 1970-01-01 01:00:00.000000000 +0100
  222077. +++ linux-linaro-stable-mx6/include/linux/pl320-ipc.h 2014-08-20 19:31:53.080898851 +0200
  222078. @@ -0,0 +1,17 @@
  222079. +/*
  222080. + * This program is free software; you can redistribute it and/or modify it
  222081. + * under the terms and conditions of the GNU General Public License,
  222082. + * version 2, as published by the Free Software Foundation.
  222083. + *
  222084. + * This program is distributed in the hope it will be useful, but WITHOUT
  222085. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  222086. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  222087. + * more details.
  222088. + *
  222089. + * You should have received a copy of the GNU General Public License along with
  222090. + * this program. If not, see <http://www.gnu.org/licenses/>.
  222091. + */
  222092. +
  222093. +int pl320_ipc_transmit(u32 *data);
  222094. +int pl320_ipc_register_notifier(struct notifier_block *nb);
  222095. +int pl320_ipc_unregister_notifier(struct notifier_block *nb);
  222096. diff -Nur linux-3.14.15/include/linux/platform_data/dma-imx.h linux-linaro-stable-mx6/include/linux/platform_data/dma-imx.h
  222097. --- linux-3.14.15/include/linux/platform_data/dma-imx.h 2014-07-31 23:51:43.000000000 +0200
  222098. +++ linux-linaro-stable-mx6/include/linux/platform_data/dma-imx.h 2014-08-20 19:31:53.100898936 +0200
  222099. @@ -1,5 +1,5 @@
  222100. /*
  222101. - * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
  222102. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  222103. *
  222104. * This program is free software; you can redistribute it and/or modify
  222105. * it under the terms of the GNU General Public License version 2 as
  222106. @@ -40,6 +40,7 @@
  222107. IMX_DMATYPE_ASRC, /* ASRC */
  222108. IMX_DMATYPE_ESAI, /* ESAI */
  222109. IMX_DMATYPE_SSI_DUAL, /* SSI Dual FIFO */
  222110. + IMX_DMATYPE_HDMI, /* HDMI Audio */
  222111. };
  222112. enum imx_dma_prio {
  222113. @@ -49,9 +50,11 @@
  222114. };
  222115. struct imx_dma_data {
  222116. - int dma_request; /* DMA request line */
  222117. + int dma_request0; /* DMA request line */
  222118. + int dma_request1;
  222119. enum sdma_peripheral_type peripheral_type;
  222120. int priority;
  222121. + void *data_addr1, *data_addr2;
  222122. };
  222123. static inline int imx_dma_is_ipu(struct dma_chan *chan)
  222124. @@ -59,6 +62,11 @@
  222125. return !strcmp(dev_name(chan->device->dev), "ipu-core");
  222126. }
  222127. +static inline int imx_dma_is_pxp(struct dma_chan *chan)
  222128. +{
  222129. + return strstr(dev_name(chan->device->dev), "pxp") != NULL;
  222130. +}
  222131. +
  222132. static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
  222133. {
  222134. return !strcmp(chan->device->dev->driver->name, "imx-sdma") ||
  222135. diff -Nur linux-3.14.15/include/linux/power/imx6_usb_charger.h linux-linaro-stable-mx6/include/linux/power/imx6_usb_charger.h
  222136. --- linux-3.14.15/include/linux/power/imx6_usb_charger.h 1970-01-01 01:00:00.000000000 +0100
  222137. +++ linux-linaro-stable-mx6/include/linux/power/imx6_usb_charger.h 2014-08-20 19:24:05.934898680 +0200
  222138. @@ -0,0 +1,80 @@
  222139. +/*
  222140. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  222141. + *
  222142. + * The code contained herein is licensed under the GNU General Public
  222143. + * License. You may obtain a copy of the GNU General Public License
  222144. + * Version 2 or later at the following locations:
  222145. + *
  222146. + * http://www.opensource.org/licenses/gpl-license.html
  222147. + * http://www.gnu.org/copyleft/gpl.html
  222148. + */
  222149. +
  222150. +#ifndef __IMXUSB6_CHARGER_H
  222151. +#define __IMXUSB6_CHARGER_H
  222152. +
  222153. +#include <linux/power_supply.h>
  222154. +enum battery_charging_spec {
  222155. + BATTERY_CHARGING_SPEC_NONE = 0,
  222156. + BATTERY_CHARGING_SPEC_UNKNOWN,
  222157. + BATTERY_CHARGING_SPEC_1_0,
  222158. + BATTERY_CHARGING_SPEC_1_1,
  222159. + BATTERY_CHARGING_SPEC_1_2,
  222160. +};
  222161. +
  222162. +struct usb_charger {
  222163. + /* The anatop regmap */
  222164. + struct regmap *anatop;
  222165. + /* USB controller */
  222166. + struct device *dev;
  222167. + struct power_supply psy;
  222168. + struct mutex lock;
  222169. +
  222170. + /* Compliant with Battery Charging Specification version (if any) */
  222171. + enum battery_charging_spec bc;
  222172. +
  222173. + /* properties */
  222174. + unsigned present:1;
  222175. + unsigned online:1;
  222176. + unsigned max_current;
  222177. + int (*connect)(struct usb_charger *charger);
  222178. + int (*disconnect)(struct usb_charger *charger);
  222179. + int (*set_power)(struct usb_charger *charger, unsigned mA);
  222180. +
  222181. + int (*detect)(struct usb_charger *charger);
  222182. +};
  222183. +
  222184. +#ifdef CONFIG_IMX6_USB_CHARGER
  222185. +extern void imx6_usb_remove_charger(struct usb_charger *charger);
  222186. +extern int imx6_usb_create_charger(struct usb_charger *charger,
  222187. + const char *name);
  222188. +extern int imx6_usb_vbus_disconnect(struct usb_charger *charger);
  222189. +extern int imx6_usb_vbus_connect(struct usb_charger *charger);
  222190. +extern int imx6_usb_charger_detect_post(struct usb_charger *charger);
  222191. +#else
  222192. +void imx6_usb_remove_charger(struct usb_charger *charger)
  222193. +{
  222194. +
  222195. +}
  222196. +
  222197. +int imx6_usb_create_charger(struct usb_charger *charger,
  222198. + const char *name)
  222199. +{
  222200. + return -ENODEV;
  222201. +}
  222202. +
  222203. +int imx6_usb_vbus_disconnect(struct usb_charger *charger)
  222204. +{
  222205. + return -ENODEV;
  222206. +}
  222207. +
  222208. +int imx6_usb_vbus_connect(struct usb_charger *charger)
  222209. +{
  222210. + return -ENODEV;
  222211. +}
  222212. +int imx6_usb_charger_detect_post(struct usb_charger *charger)
  222213. +{
  222214. + return -ENODEV;
  222215. +}
  222216. +#endif
  222217. +
  222218. +#endif /* __IMXUSB6_CHARGER_H */
  222219. diff -Nur linux-3.14.15/include/linux/ptp_clock_kernel.h linux-linaro-stable-mx6/include/linux/ptp_clock_kernel.h
  222220. --- linux-3.14.15/include/linux/ptp_clock_kernel.h 2014-07-31 23:51:43.000000000 +0200
  222221. +++ linux-linaro-stable-mx6/include/linux/ptp_clock_kernel.h 2014-08-20 19:31:53.204899381 +0200
  222222. @@ -49,7 +49,11 @@
  222223. * @n_alarm: The number of programmable alarms.
  222224. * @n_ext_ts: The number of external time stamp channels.
  222225. * @n_per_out: The number of programmable periodic signals.
  222226. + * @n_pins: The number of programmable pins.
  222227. * @pps: Indicates whether the clock supports a PPS callback.
  222228. + * @pin_config: Array of length 'n_pins'. If the number of
  222229. + * programmable pins is nonzero, then drivers must
  222230. + * allocate and initialize this array.
  222231. *
  222232. * clock operations
  222233. *
  222234. @@ -70,6 +74,18 @@
  222235. * parameter request: Desired resource to enable or disable.
  222236. * parameter on: Caller passes one to enable or zero to disable.
  222237. *
  222238. + * @verify: Confirm that a pin can perform a given function. The PTP
  222239. + * Hardware Clock subsystem maintains the 'pin_config'
  222240. + * array on behalf of the drivers, but the PHC subsystem
  222241. + * assumes that every pin can perform every function. This
  222242. + * hook gives drivers a way of telling the core about
  222243. + * limitations on specific pins. This function must return
  222244. + * zero if the function can be assigned to this pin, and
  222245. + * nonzero otherwise.
  222246. + * parameter pin: index of the pin in question.
  222247. + * parameter func: the desired function to use.
  222248. + * parameter chan: the function channel index to use.
  222249. + *
  222250. * Drivers should embed their ptp_clock_info within a private
  222251. * structure, obtaining a reference to it using container_of().
  222252. *
  222253. @@ -83,13 +99,17 @@
  222254. int n_alarm;
  222255. int n_ext_ts;
  222256. int n_per_out;
  222257. + int n_pins;
  222258. int pps;
  222259. + struct ptp_pin_desc *pin_config;
  222260. int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta);
  222261. int (*adjtime)(struct ptp_clock_info *ptp, s64 delta);
  222262. int (*gettime)(struct ptp_clock_info *ptp, struct timespec *ts);
  222263. int (*settime)(struct ptp_clock_info *ptp, const struct timespec *ts);
  222264. int (*enable)(struct ptp_clock_info *ptp,
  222265. struct ptp_clock_request *request, int on);
  222266. + int (*verify)(struct ptp_clock_info *ptp, unsigned int pin,
  222267. + enum ptp_pin_function func, unsigned int chan);
  222268. };
  222269. struct ptp_clock;
  222270. @@ -156,4 +176,17 @@
  222271. extern int ptp_clock_index(struct ptp_clock *ptp);
  222272. +/**
  222273. + * ptp_find_pin() - obtain the pin index of a given auxiliary function
  222274. + *
  222275. + * @ptp: The clock obtained from ptp_clock_register().
  222276. + * @func: One of the ptp_pin_function enumerated values.
  222277. + * @chan: The particular functional channel to find.
  222278. + * Return: Pin index in the range of zero to ptp_clock_caps.n_pins - 1,
  222279. + * or -1 if the auxiliary function cannot be found.
  222280. + */
  222281. +
  222282. +int ptp_find_pin(struct ptp_clock *ptp,
  222283. + enum ptp_pin_function func, unsigned int chan);
  222284. +
  222285. #endif
  222286. diff -Nur linux-3.14.15/include/linux/pxp_device.h linux-linaro-stable-mx6/include/linux/pxp_device.h
  222287. --- linux-3.14.15/include/linux/pxp_device.h 1970-01-01 01:00:00.000000000 +0100
  222288. +++ linux-linaro-stable-mx6/include/linux/pxp_device.h 2014-08-20 19:31:53.204899381 +0200
  222289. @@ -0,0 +1,68 @@
  222290. +/*
  222291. + * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  222292. + *
  222293. + * This program is free software; you can redistribute it and/or modify
  222294. + * it under the terms of the GNU General Public License as published by
  222295. + * the Free Software Foundation; either version 2 of the License, or
  222296. + * (at your option) any later version.
  222297. + *
  222298. + * This program is distributed in the hope that it will be useful,
  222299. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  222300. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  222301. + * GNU General Public License for more details.
  222302. + *
  222303. + * You should have received a copy of the GNU General Public License
  222304. + * along with this program; if not, write to the Free Software
  222305. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  222306. + *
  222307. + */
  222308. +#ifndef _PXP_DEVICE
  222309. +#define _PXP_DEVICE
  222310. +
  222311. +#include <linux/idr.h>
  222312. +#include <linux/hash.h>
  222313. +#include <uapi/linux/pxp_device.h>
  222314. +
  222315. +struct pxp_irq_info {
  222316. + wait_queue_head_t waitq;
  222317. + atomic_t irq_pending;
  222318. + int hist_status;
  222319. +};
  222320. +
  222321. +struct pxp_buffer_hash {
  222322. + struct hlist_head *hash_table;
  222323. + u32 order;
  222324. + spinlock_t hash_lock;
  222325. +};
  222326. +
  222327. +struct pxp_buf_obj {
  222328. + uint32_t handle;
  222329. +
  222330. + uint32_t size;
  222331. + uint32_t mem_type;
  222332. +
  222333. + unsigned long offset;
  222334. + void *virtual;
  222335. +
  222336. + struct hlist_node item;
  222337. +};
  222338. +
  222339. +struct pxp_chan_obj {
  222340. + uint32_t handle;
  222341. + struct dma_chan *chan;
  222342. +};
  222343. +
  222344. +/* File private data */
  222345. +struct pxp_file {
  222346. + struct file *filp;
  222347. +
  222348. + /* record allocated dma buffer */
  222349. + struct idr buffer_idr;
  222350. + spinlock_t buffer_lock;
  222351. +
  222352. + /* record allocated dma channel */
  222353. + struct idr channel_idr;
  222354. + spinlock_t channel_lock;
  222355. +};
  222356. +
  222357. +#endif
  222358. diff -Nur linux-3.14.15/include/linux/pxp_dma.h linux-linaro-stable-mx6/include/linux/pxp_dma.h
  222359. --- linux-3.14.15/include/linux/pxp_dma.h 1970-01-01 01:00:00.000000000 +0100
  222360. +++ linux-linaro-stable-mx6/include/linux/pxp_dma.h 2014-08-20 19:31:53.204899381 +0200
  222361. @@ -0,0 +1,72 @@
  222362. +/*
  222363. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  222364. + *
  222365. + * This program is free software; you can redistribute it and/or modify
  222366. + * it under the terms of the GNU General Public License as published by
  222367. + * the Free Software Foundation; either version 2 of the License, or
  222368. + * (at your option) any later version.
  222369. + *
  222370. + * This program is distributed in the hope that it will be useful,
  222371. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  222372. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  222373. + * GNU General Public License for more details.
  222374. + *
  222375. + * You should have received a copy of the GNU General Public License
  222376. + * along with this program; if not, write to the Free Software
  222377. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  222378. + *
  222379. + */
  222380. +#ifndef _PXP_DMA
  222381. +#define _PXP_DMA
  222382. +
  222383. +#include <uapi/linux/pxp_dma.h>
  222384. +
  222385. +struct pxp_tx_desc {
  222386. + struct dma_async_tx_descriptor txd;
  222387. + struct list_head tx_list;
  222388. + struct list_head list;
  222389. + int len;
  222390. + union {
  222391. + struct pxp_layer_param s0_param;
  222392. + struct pxp_layer_param out_param;
  222393. + struct pxp_layer_param ol_param;
  222394. + } layer_param;
  222395. + struct pxp_proc_data proc_data;
  222396. +
  222397. + u32 hist_status; /* Histogram output status */
  222398. +
  222399. + struct pxp_tx_desc *next;
  222400. +};
  222401. +
  222402. +struct pxp_channel {
  222403. + struct dma_chan dma_chan;
  222404. + dma_cookie_t completed; /* last completed cookie */
  222405. + enum pxp_channel_status status;
  222406. + void *client; /* Only one client per channel */
  222407. + unsigned int n_tx_desc;
  222408. + struct pxp_tx_desc *desc; /* allocated tx-descriptors */
  222409. + struct list_head queue; /* queued tx-descriptors */
  222410. + struct list_head list; /* track queued channel number */
  222411. + spinlock_t lock; /* protects sg[0,1], queue,
  222412. + * status, cookie, free_list
  222413. + */
  222414. + int active_buffer;
  222415. + unsigned int eof_irq;
  222416. + char eof_name[16]; /* EOF IRQ name for request_irq() */
  222417. +};
  222418. +
  222419. +#define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
  222420. +#define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
  222421. +
  222422. +void pxp_txd_ack(struct dma_async_tx_descriptor *txd,
  222423. + struct pxp_channel *pxp_chan);
  222424. +
  222425. +#ifdef CONFIG_MXC_PXP_CLIENT_DEVICE
  222426. +int register_pxp_device(void);
  222427. +void unregister_pxp_device(void);
  222428. +#else
  222429. +int register_pxp_device(void) { return 0; }
  222430. +void unregister_pxp_device(void) {}
  222431. +#endif
  222432. +
  222433. +#endif
  222434. diff -Nur linux-3.14.15/include/linux/regulator/consumer.h linux-linaro-stable-mx6/include/linux/regulator/consumer.h
  222435. --- linux-3.14.15/include/linux/regulator/consumer.h 2014-07-31 23:51:43.000000000 +0200
  222436. +++ linux-linaro-stable-mx6/include/linux/regulator/consumer.h 2014-08-20 19:31:53.216899434 +0200
  222437. @@ -2,6 +2,7 @@
  222438. * consumer.h -- SoC Regulator consumer support.
  222439. *
  222440. * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
  222441. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  222442. *
  222443. * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  222444. *
  222445. @@ -105,6 +106,8 @@
  222446. #define REGULATOR_EVENT_FORCE_DISABLE 0x20
  222447. #define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
  222448. #define REGULATOR_EVENT_DISABLE 0x80
  222449. +#define REGULATOR_EVENT_PRE_DISABLE 0x100
  222450. +#define REGULATOR_EVENT_ENABLE 0x200
  222451. struct regulator;
  222452. diff -Nur linux-3.14.15/include/linux/reset.h linux-linaro-stable-mx6/include/linux/reset.h
  222453. --- linux-3.14.15/include/linux/reset.h 2014-07-31 23:51:43.000000000 +0200
  222454. +++ linux-linaro-stable-mx6/include/linux/reset.h 2014-08-20 19:24:05.950898748 +0200
  222455. @@ -12,6 +12,13 @@
  222456. void reset_control_put(struct reset_control *rstc);
  222457. struct reset_control *devm_reset_control_get(struct device *dev, const char *id);
  222458. +#ifdef CONFIG_RESET_CONTROLLER
  222459. int device_reset(struct device *dev);
  222460. +#else
  222461. +static inline int device_reset(struct device *dev)
  222462. +{
  222463. + return 0;
  222464. +}
  222465. +#endif /* CONFIG_RESET_CONTROLLER */
  222466. #endif
  222467. diff -Nur linux-3.14.15/include/linux/serial_core.h linux-linaro-stable-mx6/include/linux/serial_core.h
  222468. --- linux-3.14.15/include/linux/serial_core.h 2014-07-31 23:51:43.000000000 +0200
  222469. +++ linux-linaro-stable-mx6/include/linux/serial_core.h 2014-08-20 19:31:53.236899518 +0200
  222470. @@ -285,6 +285,22 @@
  222471. /*
  222472. * Console helpers.
  222473. */
  222474. +struct earlycon_device {
  222475. + struct console *con;
  222476. + struct uart_port port;
  222477. + char options[16]; /* e.g., 115200n8 */
  222478. + unsigned int baud;
  222479. +};
  222480. +int setup_earlycon(char *buf, const char *match,
  222481. + int (*setup)(struct earlycon_device *, const char *));
  222482. +
  222483. +#define EARLYCON_DECLARE(name, func) \
  222484. +static int __init name ## _setup_earlycon(char *buf) \
  222485. +{ \
  222486. + return setup_earlycon(buf, __stringify(name), func); \
  222487. +} \
  222488. +early_param("earlycon", name ## _setup_earlycon);
  222489. +
  222490. struct uart_port *uart_get_console(struct uart_port *ports, int nr,
  222491. struct console *c);
  222492. void uart_parse_options(char *options, int *baud, int *parity, int *bits,
  222493. diff -Nur linux-3.14.15/include/linux/skbuff.h linux-linaro-stable-mx6/include/linux/skbuff.h
  222494. --- linux-3.14.15/include/linux/skbuff.h 2014-07-31 23:51:43.000000000 +0200
  222495. +++ linux-linaro-stable-mx6/include/linux/skbuff.h 2014-08-20 19:31:53.240899537 +0200
  222496. @@ -2038,7 +2038,7 @@
  222497. }
  222498. /**
  222499. - * skb_frag_page - retrieve the page refered to by a paged fragment
  222500. + * skb_frag_page - retrieve the page referred to by a paged fragment
  222501. * @frag: the paged fragment
  222502. *
  222503. * Returns the &struct page associated with @frag.
  222504. diff -Nur linux-3.14.15/include/linux/spi/spi.h linux-linaro-stable-mx6/include/linux/spi/spi.h
  222505. --- linux-3.14.15/include/linux/spi/spi.h 2014-07-31 23:51:43.000000000 +0200
  222506. +++ linux-linaro-stable-mx6/include/linux/spi/spi.h 2014-08-20 19:31:53.240899537 +0200
  222507. @@ -234,7 +234,7 @@
  222508. * @mode_bits: flags understood by this controller driver
  222509. * @bits_per_word_mask: A mask indicating which values of bits_per_word are
  222510. * supported by the driver. Bit n indicates that a bits_per_word n+1 is
  222511. - * suported. If set, the SPI core will reject any transfer with an
  222512. + * supported. If set, the SPI core will reject any transfer with an
  222513. * unsupported bits_per_word. If not set, this value is simply ignored,
  222514. * and it's up to the individual driver to perform any validation.
  222515. * @min_speed_hz: Lowest supported transfer speed
  222516. @@ -259,7 +259,7 @@
  222517. * @cur_msg: the currently in-flight message
  222518. * @cur_msg_prepared: spi_prepare_message was called for the currently
  222519. * in-flight message
  222520. - * @xfer_completion: used by core tranfer_one_message()
  222521. + * @xfer_completion: used by core transfer_one_message()
  222522. * @busy: message pump is busy
  222523. * @running: message pump is running
  222524. * @rt: whether this queue is set to run as a realtime task
  222525. @@ -498,7 +498,7 @@
  222526. * @rx_buf: data to be read (dma-safe memory), or NULL
  222527. * @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped
  222528. * @rx_dma: DMA address of rx_buf, if @spi_message.is_dma_mapped
  222529. - * @tx_nbits: number of bits used for writting. If 0 the default
  222530. + * @tx_nbits: number of bits used for writing. If 0 the default
  222531. * (SPI_NBITS_SINGLE) is used.
  222532. * @rx_nbits: number of bits used for reading. If 0 the default
  222533. * (SPI_NBITS_SINGLE) is used.
  222534. @@ -556,7 +556,7 @@
  222535. * by the results of previous messages and where the whole transaction
  222536. * ends when the chipselect goes intactive.
  222537. *
  222538. - * When SPI can transfer in 1x,2x or 4x. It can get this tranfer information
  222539. + * When SPI can transfer in 1x,2x or 4x. It can get this transfer information
  222540. * from device through @tx_nbits and @rx_nbits. In Bi-direction, these
  222541. * two should both be set. User can set transfer mode with SPI_NBITS_SINGLE(1x)
  222542. * SPI_NBITS_DUAL(2x) and SPI_NBITS_QUAD(4x) to support these three transfer.
  222543. diff -Nur linux-3.14.15/include/linux/syscalls.h linux-linaro-stable-mx6/include/linux/syscalls.h
  222544. --- linux-3.14.15/include/linux/syscalls.h 2014-07-31 23:51:43.000000000 +0200
  222545. +++ linux-linaro-stable-mx6/include/linux/syscalls.h 2014-08-20 19:31:53.248899571 +0200
  222546. @@ -744,6 +744,9 @@
  222547. int newdfd, const char __user *newname, int flags);
  222548. asmlinkage long sys_renameat(int olddfd, const char __user * oldname,
  222549. int newdfd, const char __user * newname);
  222550. +asmlinkage long sys_renameat2(int olddfd, const char __user *oldname,
  222551. + int newdfd, const char __user *newname,
  222552. + unsigned int flags);
  222553. asmlinkage long sys_futimesat(int dfd, const char __user *filename,
  222554. struct timeval __user *utimes);
  222555. asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode);
  222556. diff -Nur linux-3.14.15/include/linux/usb/chipidea.h linux-linaro-stable-mx6/include/linux/usb/chipidea.h
  222557. --- linux-3.14.15/include/linux/usb/chipidea.h 2014-07-31 23:51:43.000000000 +0200
  222558. +++ linux-linaro-stable-mx6/include/linux/usb/chipidea.h 2014-08-20 19:31:53.264899640 +0200
  222559. @@ -18,6 +18,7 @@
  222560. unsigned long flags;
  222561. #define CI_HDRC_REGS_SHARED BIT(0)
  222562. #define CI_HDRC_REQUIRE_TRANSCEIVER BIT(1)
  222563. +#define CI_HDRC_SUPPORTS_RUNTIME_PM BIT(2)
  222564. #define CI_HDRC_DISABLE_STREAMING BIT(3)
  222565. /*
  222566. * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
  222567. @@ -25,6 +26,7 @@
  222568. */
  222569. #define CI_HDRC_DUAL_ROLE_NOT_OTG BIT(4)
  222570. #define CI_HDRC_IMX28_WRITE_FIX BIT(5)
  222571. +#define CI_HDRC_IMX_EHCI_QUIRK BIT(6)
  222572. enum usb_dr_mode dr_mode;
  222573. #define CI_HDRC_CONTROLLER_RESET_EVENT 0
  222574. #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
  222575. @@ -42,4 +44,6 @@
  222576. /* Remove ci hdrc device */
  222577. void ci_hdrc_remove_device(struct platform_device *pdev);
  222578. +/* Get current available role */
  222579. +enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev);
  222580. #endif
  222581. diff -Nur linux-3.14.15/include/linux/usb/composite.h linux-linaro-stable-mx6/include/linux/usb/composite.h
  222582. --- linux-3.14.15/include/linux/usb/composite.h 2014-07-31 23:51:43.000000000 +0200
  222583. +++ linux-linaro-stable-mx6/include/linux/usb/composite.h 2014-08-20 19:31:53.264899640 +0200
  222584. @@ -92,7 +92,7 @@
  222585. * @suspend: Notifies functions when the host stops sending USB traffic.
  222586. * @resume: Notifies functions when the host restarts USB traffic.
  222587. * @get_status: Returns function status as a reply to
  222588. - * GetStatus() request when the recepient is Interface.
  222589. + * GetStatus() request when the recipient is Interface.
  222590. * @func_suspend: callback to be called when
  222591. * SetFeature(FUNCTION_SUSPEND) is reseived
  222592. *
  222593. diff -Nur linux-3.14.15/include/linux/usb/phy.h linux-linaro-stable-mx6/include/linux/usb/phy.h
  222594. --- linux-3.14.15/include/linux/usb/phy.h 2014-07-31 23:51:43.000000000 +0200
  222595. +++ linux-linaro-stable-mx6/include/linux/usb/phy.h 2014-08-20 19:31:53.268899657 +0200
  222596. @@ -111,11 +111,23 @@
  222597. int (*set_suspend)(struct usb_phy *x,
  222598. int suspend);
  222599. + /*
  222600. + * Set wakeup enable for PHY, in that case, the PHY can be
  222601. + * waken up from suspend status due to external events,
  222602. + * like vbus change, dp/dm change and id.
  222603. + */
  222604. + int (*set_wakeup)(struct usb_phy *x, bool enabled);
  222605. +
  222606. /* notify phy connect status change */
  222607. int (*notify_connect)(struct usb_phy *x,
  222608. enum usb_device_speed speed);
  222609. int (*notify_disconnect)(struct usb_phy *x,
  222610. enum usb_device_speed speed);
  222611. + int (*notify_suspend)(struct usb_phy *x,
  222612. + enum usb_device_speed speed);
  222613. + int (*notify_resume)(struct usb_phy *x,
  222614. + enum usb_device_speed speed);
  222615. +
  222616. };
  222617. /**
  222618. @@ -265,6 +277,15 @@
  222619. }
  222620. static inline int
  222621. +usb_phy_set_wakeup(struct usb_phy *x, bool enabled)
  222622. +{
  222623. + if (x && x->set_wakeup)
  222624. + return x->set_wakeup(x, enabled);
  222625. + else
  222626. + return 0;
  222627. +}
  222628. +
  222629. +static inline int
  222630. usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed)
  222631. {
  222632. if (x && x->notify_connect)
  222633. @@ -281,6 +302,24 @@
  222634. else
  222635. return 0;
  222636. }
  222637. +
  222638. +static inline int usb_phy_notify_suspend
  222639. + (struct usb_phy *x, enum usb_device_speed speed)
  222640. +{
  222641. + if (x && x->notify_suspend)
  222642. + return x->notify_suspend(x, speed);
  222643. + else
  222644. + return 0;
  222645. +}
  222646. +
  222647. +static inline int usb_phy_notify_resume
  222648. + (struct usb_phy *x, enum usb_device_speed speed)
  222649. +{
  222650. + if (x && x->notify_resume)
  222651. + return x->notify_resume(x, speed);
  222652. + else
  222653. + return 0;
  222654. +}
  222655. /* notifiers */
  222656. static inline int
  222657. diff -Nur linux-3.14.15/include/net/cfg80211.h linux-linaro-stable-mx6/include/net/cfg80211.h
  222658. --- linux-3.14.15/include/net/cfg80211.h 2014-07-31 23:51:43.000000000 +0200
  222659. +++ linux-linaro-stable-mx6/include/net/cfg80211.h 2014-08-20 19:31:53.404900240 +0200
  222660. @@ -1729,7 +1729,7 @@
  222661. u8 *ssid;
  222662. size_t ssid_len;
  222663. enum nl80211_auth_type auth_type;
  222664. - u8 *ie;
  222665. + const u8 *ie;
  222666. size_t ie_len;
  222667. bool privacy;
  222668. enum nl80211_mfp mfp;
  222669. @@ -3888,6 +3888,7 @@
  222670. *
  222671. * @dev: network device
  222672. * @bssid: the BSSID of the IBSS joined
  222673. + * @channel: the channel of the IBSS joined
  222674. * @gfp: allocation flags
  222675. *
  222676. * This function notifies cfg80211 that the device joined an IBSS or
  222677. @@ -3897,7 +3898,8 @@
  222678. * with the locally generated beacon -- this guarantees that there is
  222679. * always a scan result for this IBSS. cfg80211 will handle the rest.
  222680. */
  222681. -void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
  222682. +void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  222683. + struct ieee80211_channel *channel, gfp_t gfp);
  222684. /**
  222685. * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
  222686. diff -Nur linux-3.14.15/include/net/mac80211.h linux-linaro-stable-mx6/include/net/mac80211.h
  222687. --- linux-3.14.15/include/net/mac80211.h 2014-07-31 23:51:43.000000000 +0200
  222688. +++ linux-linaro-stable-mx6/include/net/mac80211.h 2014-08-20 19:31:53.420900308 +0200
  222689. @@ -1895,7 +1895,7 @@
  222690. *
  222691. * Driver informs U-APSD client support by enabling
  222692. * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the
  222693. - * uapsd paramater in conf_tx() operation. Hardware needs to send the QoS
  222694. + * uapsd parameter in conf_tx() operation. Hardware needs to send the QoS
  222695. * Nullfunc frames and stay awake until the service period has ended. To
  222696. * utilize U-APSD, dynamic powersave is disabled for voip AC and all frames
  222697. * from that AC are transmitted with powersave enabled.
  222698. @@ -2101,7 +2101,7 @@
  222699. * with the number of frames to be released and which TIDs they are
  222700. * to come from. In this case, the driver is responsible for setting
  222701. * the EOSP (for uAPSD) and MORE_DATA bits in the released frames,
  222702. - * to help the @more_data paramter is passed to tell the driver if
  222703. + * to help the @more_data parameter is passed to tell the driver if
  222704. * there is more data on other TIDs -- the TIDs to release frames
  222705. * from are ignored since mac80211 doesn't know how many frames the
  222706. * buffers for those TIDs contain.
  222707. @@ -2616,6 +2616,7 @@
  222708. * of queues to flush, which is useful if different virtual interfaces
  222709. * use different hardware queues; it may also indicate all queues.
  222710. * If the parameter @drop is set to %true, pending frames may be dropped.
  222711. + * Note that vif can be NULL.
  222712. * The callback can sleep.
  222713. *
  222714. * @channel_switch: Drivers that need (or want) to offload the channel
  222715. @@ -2662,7 +2663,7 @@
  222716. * parameters. In the case where the driver buffers some frames for
  222717. * sleeping stations mac80211 will use this callback to tell the driver
  222718. * to release some frames, either for PS-poll or uAPSD.
  222719. - * Note that if the @more_data paramter is %false the driver must check
  222720. + * Note that if the @more_data parameter is %false the driver must check
  222721. * if there are more frames on the given TIDs, and if there are more than
  222722. * the frames being released then it must still set the more-data bit in
  222723. * the frame. If the @more_data parameter is %true, then of course the
  222724. @@ -2878,7 +2879,8 @@
  222725. struct netlink_callback *cb,
  222726. void *data, int len);
  222727. #endif
  222728. - void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop);
  222729. + void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  222730. + u32 queues, bool drop);
  222731. void (*channel_switch)(struct ieee80211_hw *hw,
  222732. struct ieee80211_channel_switch *ch_switch);
  222733. int (*napi_poll)(struct ieee80211_hw *hw, int budget);
  222734. diff -Nur linux-3.14.15/include/net/rtnetlink.h linux-linaro-stable-mx6/include/net/rtnetlink.h
  222735. --- linux-3.14.15/include/net/rtnetlink.h 2014-07-31 23:51:43.000000000 +0200
  222736. +++ linux-linaro-stable-mx6/include/net/rtnetlink.h 2014-08-20 19:31:53.456900464 +0200
  222737. @@ -140,7 +140,7 @@
  222738. struct nlattr *tb[]);
  222739. int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm);
  222740. -extern const struct nla_policy ifla_policy[IFLA_MAX+1];
  222741. +int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len);
  222742. #define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind)
  222743. diff -Nur linux-3.14.15/include/net/tso.h linux-linaro-stable-mx6/include/net/tso.h
  222744. --- linux-3.14.15/include/net/tso.h 1970-01-01 01:00:00.000000000 +0100
  222745. +++ linux-linaro-stable-mx6/include/net/tso.h 2014-08-20 19:31:54.492904910 +0200
  222746. @@ -0,0 +1,20 @@
  222747. +#ifndef _TSO_H
  222748. +#define _TSO_H
  222749. +
  222750. +#include <net/ip.h>
  222751. +
  222752. +struct tso_t {
  222753. + int next_frag_idx;
  222754. + void *data;
  222755. + size_t size;
  222756. + u16 ip_id;
  222757. + u32 tcp_seq;
  222758. +};
  222759. +
  222760. +int tso_count_descs(struct sk_buff *skb);
  222761. +void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,
  222762. + int size, bool is_last);
  222763. +void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size);
  222764. +void tso_start(struct sk_buff *skb, struct tso_t *tso);
  222765. +
  222766. +#endif /* _TSO_H */
  222767. diff -Nur linux-3.14.15/include/sound/wm8962.h linux-linaro-stable-mx6/include/sound/wm8962.h
  222768. --- linux-3.14.15/include/sound/wm8962.h 2014-07-31 23:51:43.000000000 +0200
  222769. +++ linux-linaro-stable-mx6/include/sound/wm8962.h 2014-08-20 19:24:06.398900661 +0200
  222770. @@ -55,6 +55,9 @@
  222771. * in a DC measurement configuration.
  222772. */
  222773. bool in4_dc_measure;
  222774. +
  222775. + /* MCLK for wm8962 */
  222776. + struct clk *codec_mclk;
  222777. };
  222778. #endif
  222779. diff -Nur linux-3.14.15/include/trace/events/cpufreq_interactive.h linux-linaro-stable-mx6/include/trace/events/cpufreq_interactive.h
  222780. --- linux-3.14.15/include/trace/events/cpufreq_interactive.h 1970-01-01 01:00:00.000000000 +0100
  222781. +++ linux-linaro-stable-mx6/include/trace/events/cpufreq_interactive.h 2014-08-20 19:31:54.724905906 +0200
  222782. @@ -0,0 +1,112 @@
  222783. +#undef TRACE_SYSTEM
  222784. +#define TRACE_SYSTEM cpufreq_interactive
  222785. +
  222786. +#if !defined(_TRACE_CPUFREQ_INTERACTIVE_H) || defined(TRACE_HEADER_MULTI_READ)
  222787. +#define _TRACE_CPUFREQ_INTERACTIVE_H
  222788. +
  222789. +#include <linux/tracepoint.h>
  222790. +
  222791. +DECLARE_EVENT_CLASS(set,
  222792. + TP_PROTO(u32 cpu_id, unsigned long targfreq,
  222793. + unsigned long actualfreq),
  222794. + TP_ARGS(cpu_id, targfreq, actualfreq),
  222795. +
  222796. + TP_STRUCT__entry(
  222797. + __field( u32, cpu_id )
  222798. + __field(unsigned long, targfreq )
  222799. + __field(unsigned long, actualfreq )
  222800. + ),
  222801. +
  222802. + TP_fast_assign(
  222803. + __entry->cpu_id = (u32) cpu_id;
  222804. + __entry->targfreq = targfreq;
  222805. + __entry->actualfreq = actualfreq;
  222806. + ),
  222807. +
  222808. + TP_printk("cpu=%u targ=%lu actual=%lu",
  222809. + __entry->cpu_id, __entry->targfreq,
  222810. + __entry->actualfreq)
  222811. +);
  222812. +
  222813. +DEFINE_EVENT(set, cpufreq_interactive_setspeed,
  222814. + TP_PROTO(u32 cpu_id, unsigned long targfreq,
  222815. + unsigned long actualfreq),
  222816. + TP_ARGS(cpu_id, targfreq, actualfreq)
  222817. +);
  222818. +
  222819. +DECLARE_EVENT_CLASS(loadeval,
  222820. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  222821. + unsigned long curtarg, unsigned long curactual,
  222822. + unsigned long newtarg),
  222823. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg),
  222824. +
  222825. + TP_STRUCT__entry(
  222826. + __field(unsigned long, cpu_id )
  222827. + __field(unsigned long, load )
  222828. + __field(unsigned long, curtarg )
  222829. + __field(unsigned long, curactual )
  222830. + __field(unsigned long, newtarg )
  222831. + ),
  222832. +
  222833. + TP_fast_assign(
  222834. + __entry->cpu_id = cpu_id;
  222835. + __entry->load = load;
  222836. + __entry->curtarg = curtarg;
  222837. + __entry->curactual = curactual;
  222838. + __entry->newtarg = newtarg;
  222839. + ),
  222840. +
  222841. + TP_printk("cpu=%lu load=%lu cur=%lu actual=%lu targ=%lu",
  222842. + __entry->cpu_id, __entry->load, __entry->curtarg,
  222843. + __entry->curactual, __entry->newtarg)
  222844. +);
  222845. +
  222846. +DEFINE_EVENT(loadeval, cpufreq_interactive_target,
  222847. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  222848. + unsigned long curtarg, unsigned long curactual,
  222849. + unsigned long newtarg),
  222850. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
  222851. +);
  222852. +
  222853. +DEFINE_EVENT(loadeval, cpufreq_interactive_already,
  222854. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  222855. + unsigned long curtarg, unsigned long curactual,
  222856. + unsigned long newtarg),
  222857. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
  222858. +);
  222859. +
  222860. +DEFINE_EVENT(loadeval, cpufreq_interactive_notyet,
  222861. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  222862. + unsigned long curtarg, unsigned long curactual,
  222863. + unsigned long newtarg),
  222864. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
  222865. +);
  222866. +
  222867. +TRACE_EVENT(cpufreq_interactive_boost,
  222868. + TP_PROTO(const char *s),
  222869. + TP_ARGS(s),
  222870. + TP_STRUCT__entry(
  222871. + __string(s, s)
  222872. + ),
  222873. + TP_fast_assign(
  222874. + __assign_str(s, s);
  222875. + ),
  222876. + TP_printk("%s", __get_str(s))
  222877. +);
  222878. +
  222879. +TRACE_EVENT(cpufreq_interactive_unboost,
  222880. + TP_PROTO(const char *s),
  222881. + TP_ARGS(s),
  222882. + TP_STRUCT__entry(
  222883. + __string(s, s)
  222884. + ),
  222885. + TP_fast_assign(
  222886. + __assign_str(s, s);
  222887. + ),
  222888. + TP_printk("%s", __get_str(s))
  222889. +);
  222890. +
  222891. +#endif /* _TRACE_CPUFREQ_INTERACTIVE_H */
  222892. +
  222893. +/* This part must be outside protection */
  222894. +#include <trace/define_trace.h>
  222895. diff -Nur linux-3.14.15/include/uapi/linux/ipu.h linux-linaro-stable-mx6/include/uapi/linux/ipu.h
  222896. --- linux-3.14.15/include/uapi/linux/ipu.h 1970-01-01 01:00:00.000000000 +0100
  222897. +++ linux-linaro-stable-mx6/include/uapi/linux/ipu.h 2014-08-20 19:24:06.526901208 +0200
  222898. @@ -0,0 +1,282 @@
  222899. +/*
  222900. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  222901. + */
  222902. +
  222903. +/*
  222904. + * This program is free software; you can redistribute it and/or modify
  222905. + * it under the terms of the GNU General Public License as published by
  222906. + * the Free Software Foundation; either version 2 of the License, or
  222907. + * (at your option) any later version.
  222908. + *
  222909. + * This program is distributed in the hope that it will be useful,
  222910. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  222911. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  222912. + * GNU General Public License for more details.
  222913. + *
  222914. + * You should have received a copy of the GNU General Public License along
  222915. + * with this program; if not, write to the Free Software Foundation, Inc.,
  222916. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  222917. + */
  222918. +
  222919. +/*!
  222920. + * @defgroup IPU MXC Image Processing Unit (IPU) Driver
  222921. + */
  222922. +/*!
  222923. + * @file uapi/linux/ipu.h
  222924. + *
  222925. + * @brief This file contains the IPU driver API declarations.
  222926. + *
  222927. + * @ingroup IPU
  222928. + */
  222929. +
  222930. +#ifndef __ASM_ARCH_IPU_H__
  222931. +#define __ASM_ARCH_IPU_H__
  222932. +
  222933. +#include <linux/types.h>
  222934. +#include <linux/videodev2.h>
  222935. +
  222936. +#ifndef __KERNEL__
  222937. +#ifndef __cplusplus
  222938. +typedef unsigned char bool;
  222939. +#endif
  222940. +#define irqreturn_t int
  222941. +#define dma_addr_t int
  222942. +#define uint32_t unsigned int
  222943. +#define uint16_t unsigned short
  222944. +#define uint8_t unsigned char
  222945. +#define u32 unsigned int
  222946. +#define u8 unsigned char
  222947. +#define __u32 u32
  222948. +#endif
  222949. +
  222950. +/*!
  222951. + * Enumeration of IPU rotation modes
  222952. + */
  222953. +typedef enum {
  222954. + /* Note the enum values correspond to BAM value */
  222955. + IPU_ROTATE_NONE = 0,
  222956. + IPU_ROTATE_VERT_FLIP = 1,
  222957. + IPU_ROTATE_HORIZ_FLIP = 2,
  222958. + IPU_ROTATE_180 = 3,
  222959. + IPU_ROTATE_90_RIGHT = 4,
  222960. + IPU_ROTATE_90_RIGHT_VFLIP = 5,
  222961. + IPU_ROTATE_90_RIGHT_HFLIP = 6,
  222962. + IPU_ROTATE_90_LEFT = 7,
  222963. +} ipu_rotate_mode_t;
  222964. +
  222965. +/*!
  222966. + * Enumeration of VDI MOTION select
  222967. + */
  222968. +typedef enum {
  222969. + MED_MOTION = 0,
  222970. + LOW_MOTION = 1,
  222971. + HIGH_MOTION = 2,
  222972. +} ipu_motion_sel;
  222973. +
  222974. +/*!
  222975. + * Enumeration of DI ports for ADC.
  222976. + */
  222977. +typedef enum {
  222978. + DISP0,
  222979. + DISP1,
  222980. + DISP2,
  222981. + DISP3
  222982. +} display_port_t;
  222983. +
  222984. +/* IPU Pixel format definitions */
  222985. +/* Four-character-code (FOURCC) */
  222986. +#define fourcc(a, b, c, d)\
  222987. + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
  222988. +
  222989. +/*!
  222990. + * @name IPU Pixel Formats
  222991. + *
  222992. + * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
  222993. + * the same used by V4L2 API.
  222994. + */
  222995. +
  222996. +/*! @{ */
  222997. +/*! @name Generic or Raw Data Formats */
  222998. +/*! @{ */
  222999. +#define IPU_PIX_FMT_GENERIC fourcc('I', 'P', 'U', '0') /*!< IPU Generic Data */
  223000. +#define IPU_PIX_FMT_GENERIC_32 fourcc('I', 'P', 'U', '1') /*!< IPU Generic Data */
  223001. +#define IPU_PIX_FMT_GENERIC_16 fourcc('I', 'P', 'U', '2') /*!< IPU Generic Data */
  223002. +#define IPU_PIX_FMT_LVDS666 fourcc('L', 'V', 'D', '6') /*!< IPU Generic Data */
  223003. +#define IPU_PIX_FMT_LVDS888 fourcc('L', 'V', 'D', '8') /*!< IPU Generic Data */
  223004. +/*! @} */
  223005. +/*! @name RGB Formats */
  223006. +/*! @{ */
  223007. +#define IPU_PIX_FMT_RGB332 fourcc('R', 'G', 'B', '1') /*!< 8 RGB-3-3-2 */
  223008. +#define IPU_PIX_FMT_RGB555 fourcc('R', 'G', 'B', 'O') /*!< 16 RGB-5-5-5 */
  223009. +#define IPU_PIX_FMT_RGB565 fourcc('R', 'G', 'B', 'P') /*!< 1 6 RGB-5-6-5 */
  223010. +#define IPU_PIX_FMT_RGB666 fourcc('R', 'G', 'B', '6') /*!< 18 RGB-6-6-6 */
  223011. +#define IPU_PIX_FMT_BGR666 fourcc('B', 'G', 'R', '6') /*!< 18 BGR-6-6-6 */
  223012. +#define IPU_PIX_FMT_BGR24 fourcc('B', 'G', 'R', '3') /*!< 24 BGR-8-8-8 */
  223013. +#define IPU_PIX_FMT_RGB24 fourcc('R', 'G', 'B', '3') /*!< 24 RGB-8-8-8 */
  223014. +#define IPU_PIX_FMT_GBR24 fourcc('G', 'B', 'R', '3') /*!< 24 GBR-8-8-8 */
  223015. +#define IPU_PIX_FMT_BGR32 fourcc('B', 'G', 'R', '4') /*!< 32 BGR-8-8-8-8 */
  223016. +#define IPU_PIX_FMT_BGRA32 fourcc('B', 'G', 'R', 'A') /*!< 32 BGR-8-8-8-8 */
  223017. +#define IPU_PIX_FMT_RGB32 fourcc('R', 'G', 'B', '4') /*!< 32 RGB-8-8-8-8 */
  223018. +#define IPU_PIX_FMT_RGBA32 fourcc('R', 'G', 'B', 'A') /*!< 32 RGB-8-8-8-8 */
  223019. +#define IPU_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R') /*!< 32 ABGR-8-8-8-8 */
  223020. +/*! @} */
  223021. +/*! @name YUV Interleaved Formats */
  223022. +/*! @{ */
  223023. +#define IPU_PIX_FMT_YUYV fourcc('Y', 'U', 'Y', 'V') /*!< 16 YUV 4:2:2 */
  223024. +#define IPU_PIX_FMT_UYVY fourcc('U', 'Y', 'V', 'Y') /*!< 16 YUV 4:2:2 */
  223025. +#define IPU_PIX_FMT_YVYU fourcc('Y', 'V', 'Y', 'U') /*!< 16 YVYU 4:2:2 */
  223026. +#define IPU_PIX_FMT_VYUY fourcc('V', 'Y', 'U', 'Y') /*!< 16 VYYU 4:2:2 */
  223027. +#define IPU_PIX_FMT_Y41P fourcc('Y', '4', '1', 'P') /*!< 12 YUV 4:1:1 */
  223028. +#define IPU_PIX_FMT_YUV444 fourcc('Y', '4', '4', '4') /*!< 24 YUV 4:4:4 */
  223029. +#define IPU_PIX_FMT_VYU444 fourcc('V', '4', '4', '4') /*!< 24 VYU 4:4:4 */
  223030. +/* two planes -- one Y, one Cb + Cr interleaved */
  223031. +#define IPU_PIX_FMT_NV12 fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
  223032. +/* two planes -- 12 tiled Y/CbCr 4:2:0 */
  223033. +#define IPU_PIX_FMT_TILED_NV12 fourcc('T', 'N', 'V', 'P')
  223034. +#define IPU_PIX_FMT_TILED_NV12F fourcc('T', 'N', 'V', 'F')
  223035. +
  223036. +/*! @} */
  223037. +/*! @name YUV Planar Formats */
  223038. +/*! @{ */
  223039. +#define IPU_PIX_FMT_GREY fourcc('G', 'R', 'E', 'Y') /*!< 8 Greyscale */
  223040. +#define IPU_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*!< 9 YVU 4:1:0 */
  223041. +#define IPU_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*!< 9 YUV 4:1:0 */
  223042. +#define IPU_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*!< 12 YVU 4:2:0 */
  223043. +#define IPU_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*!< 12 YUV 4:2:0 */
  223044. +#define IPU_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2') /*!< 12 YUV 4:2:0 */
  223045. +#define IPU_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*!< 16 YVU 4:2:2 */
  223046. +#define IPU_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*!< 16 YUV 4:2:2 */
  223047. +/* non-interleaved 4:4:4 */
  223048. +#define IPU_PIX_FMT_YUV444P fourcc('4', '4', '4', 'P') /*!< 24 YUV 4:4:4 */
  223049. +/*! @} */
  223050. +#define IPU_PIX_FMT_TILED_NV12_MBALIGN (16)
  223051. +#define TILED_NV12_FRAME_SIZE(w, h) \
  223052. + (ALIGN((w) * (h), SZ_4K) + ALIGN((w) * (h) / 2, SZ_4K))
  223053. +/* IPU device */
  223054. +typedef enum {
  223055. + RGB_CS,
  223056. + YUV_CS,
  223057. + NULL_CS
  223058. +} cs_t;
  223059. +
  223060. +struct ipu_pos {
  223061. + u32 x;
  223062. + u32 y;
  223063. +};
  223064. +
  223065. +struct ipu_crop {
  223066. + struct ipu_pos pos;
  223067. + u32 w;
  223068. + u32 h;
  223069. +};
  223070. +
  223071. +struct ipu_deinterlace {
  223072. + bool enable;
  223073. + u8 motion; /*see ipu_motion_sel*/
  223074. +#define IPU_DEINTERLACE_FIELD_TOP 0
  223075. +#define IPU_DEINTERLACE_FIELD_BOTTOM 1
  223076. +#define IPU_DEINTERLACE_FIELD_MASK \
  223077. + (IPU_DEINTERLACE_FIELD_TOP | IPU_DEINTERLACE_FIELD_BOTTOM)
  223078. + /* deinterlace frame rate double flags */
  223079. +#define IPU_DEINTERLACE_RATE_EN 0x80
  223080. +#define IPU_DEINTERLACE_RATE_FRAME1 0x40
  223081. +#define IPU_DEINTERLACE_RATE_MASK \
  223082. + (IPU_DEINTERLACE_RATE_EN | IPU_DEINTERLACE_RATE_FRAME1)
  223083. +#define IPU_DEINTERLACE_MAX_FRAME 2
  223084. + u8 field_fmt;
  223085. +};
  223086. +
  223087. +struct ipu_input {
  223088. + u32 width;
  223089. + u32 height;
  223090. + u32 format;
  223091. + struct ipu_crop crop;
  223092. + dma_addr_t paddr;
  223093. +
  223094. + struct ipu_deinterlace deinterlace;
  223095. + dma_addr_t paddr_n; /*valid when deinterlace enable*/
  223096. +};
  223097. +
  223098. +struct ipu_alpha {
  223099. +#define IPU_ALPHA_MODE_GLOBAL 0
  223100. +#define IPU_ALPHA_MODE_LOCAL 1
  223101. + u8 mode;
  223102. + u8 gvalue; /* 0~255 */
  223103. + dma_addr_t loc_alp_paddr;
  223104. +};
  223105. +
  223106. +struct ipu_colorkey {
  223107. + bool enable;
  223108. + u32 value; /* RGB 24bit */
  223109. +};
  223110. +
  223111. +struct ipu_overlay {
  223112. + u32 width;
  223113. + u32 height;
  223114. + u32 format;
  223115. + struct ipu_crop crop;
  223116. + struct ipu_alpha alpha;
  223117. + struct ipu_colorkey colorkey;
  223118. + dma_addr_t paddr;
  223119. +};
  223120. +
  223121. +struct ipu_output {
  223122. + u32 width;
  223123. + u32 height;
  223124. + u32 format;
  223125. + u8 rotate;
  223126. + struct ipu_crop crop;
  223127. + dma_addr_t paddr;
  223128. +};
  223129. +
  223130. +struct ipu_task {
  223131. + struct ipu_input input;
  223132. + struct ipu_output output;
  223133. +
  223134. + bool overlay_en;
  223135. + struct ipu_overlay overlay;
  223136. +
  223137. +#define IPU_TASK_PRIORITY_NORMAL 0
  223138. +#define IPU_TASK_PRIORITY_HIGH 1
  223139. + u8 priority;
  223140. +
  223141. +#define IPU_TASK_ID_ANY 0
  223142. +#define IPU_TASK_ID_VF 1
  223143. +#define IPU_TASK_ID_PP 2
  223144. +#define IPU_TASK_ID_MAX 3
  223145. + u8 task_id;
  223146. +
  223147. + int timeout;
  223148. +};
  223149. +
  223150. +enum {
  223151. + IPU_CHECK_OK = 0,
  223152. + IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN = 0x1,
  223153. + IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN = 0x2,
  223154. + IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN = 0x4,
  223155. + IPU_CHECK_ERR_MIN,
  223156. + IPU_CHECK_ERR_INPUT_CROP,
  223157. + IPU_CHECK_ERR_OUTPUT_CROP,
  223158. + IPU_CHECK_ERR_OVERLAY_CROP,
  223159. + IPU_CHECK_ERR_INPUT_OVER_LIMIT,
  223160. + IPU_CHECK_ERR_OV_OUT_NO_FIT,
  223161. + IPU_CHECK_ERR_OVERLAY_WITH_VDI,
  223162. + IPU_CHECK_ERR_PROC_NO_NEED,
  223163. + IPU_CHECK_ERR_SPLIT_INPUTW_OVER,
  223164. + IPU_CHECK_ERR_SPLIT_INPUTH_OVER,
  223165. + IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER,
  223166. + IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER,
  223167. + IPU_CHECK_ERR_SPLIT_WITH_ROT,
  223168. + IPU_CHECK_ERR_NOT_SUPPORT,
  223169. + IPU_CHECK_ERR_NOT16ALIGN,
  223170. + IPU_CHECK_ERR_W_DOWNSIZE_OVER,
  223171. + IPU_CHECK_ERR_H_DOWNSIZE_OVER,
  223172. +};
  223173. +
  223174. +/* IOCTL commands */
  223175. +#define IPU_CHECK_TASK _IOWR('I', 0x1, struct ipu_task)
  223176. +#define IPU_QUEUE_TASK _IOW('I', 0x2, struct ipu_task)
  223177. +#define IPU_ALLOC _IOWR('I', 0x3, int)
  223178. +#define IPU_FREE _IOW('I', 0x4, int)
  223179. +
  223180. +#endif
  223181. diff -Nur linux-3.14.15/include/uapi/linux/isl29023.h linux-linaro-stable-mx6/include/uapi/linux/isl29023.h
  223182. --- linux-3.14.15/include/uapi/linux/isl29023.h 1970-01-01 01:00:00.000000000 +0100
  223183. +++ linux-linaro-stable-mx6/include/uapi/linux/isl29023.h 2014-08-20 19:24:06.526901208 +0200
  223184. @@ -0,0 +1,47 @@
  223185. +/*
  223186. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  223187. + */
  223188. +
  223189. +/*
  223190. + * This program is free software; you can redistribute it and/or modify
  223191. + * it under the terms of the GNU General Public License as published by
  223192. + * the Free Software Foundation; either version 2 of the License, or
  223193. + * (at your option) any later version.
  223194. +
  223195. + * This program is distributed in the hope that it will be useful,
  223196. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223197. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223198. + * GNU General Public License for more details.
  223199. +
  223200. + * You should have received a copy of the GNU General Public License along
  223201. + * with this program; if not, write to the Free Software Foundation, Inc.,
  223202. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  223203. + */
  223204. +
  223205. +#ifndef __UAPI_LINUX_ISL29023_H__
  223206. +#define __UAPI_LINUX_ISL29023_H__
  223207. +
  223208. +#include <linux/types.h>
  223209. +
  223210. +#define ISL29023_PD_MODE 0x0
  223211. +#define ISL29023_ALS_ONCE_MODE 0x1
  223212. +#define ISL29023_IR_ONCE_MODE 0x2
  223213. +#define ISL29023_ALS_CONT_MODE 0x5
  223214. +#define ISL29023_IR_CONT_MODE 0x6
  223215. +
  223216. +#define ISL29023_INT_PERSISTS_1 0x0
  223217. +#define ISL29023_INT_PERSISTS_4 0x1
  223218. +#define ISL29023_INT_PERSISTS_8 0x2
  223219. +#define ISL29023_INT_PERSISTS_16 0x3
  223220. +
  223221. +#define ISL29023_RES_16 0x0
  223222. +#define ISL29023_RES_12 0x1
  223223. +#define ISL29023_RES_8 0x2
  223224. +#define ISL29023_RES_4 0x3
  223225. +
  223226. +#define ISL29023_RANGE_1K 0x0
  223227. +#define ISL29023_RANGE_4K 0x1
  223228. +#define ISL29023_RANGE_16K 0x2
  223229. +#define ISL29023_RANGE_64K 0x3
  223230. +
  223231. +#endif
  223232. diff -Nur linux-3.14.15/include/uapi/linux/Kbuild linux-linaro-stable-mx6/include/uapi/linux/Kbuild
  223233. --- linux-3.14.15/include/uapi/linux/Kbuild 2014-07-31 23:51:43.000000000 +0200
  223234. +++ linux-linaro-stable-mx6/include/uapi/linux/Kbuild 2014-08-20 19:31:54.740905976 +0200
  223235. @@ -226,6 +226,7 @@
  223236. header-y += kvm_para.h
  223237. endif
  223238. +header-y += ipu.h
  223239. header-y += l2tp.h
  223240. header-y += libc-compat.h
  223241. header-y += limits.h
  223242. @@ -253,6 +254,9 @@
  223243. header-y += msdos_fs.h
  223244. header-y += msg.h
  223245. header-y += mtio.h
  223246. +header-y += mxcfb.h
  223247. +header-y += mxc_asrc.h
  223248. +header-y += mxc_v4l2.h
  223249. header-y += n_r3964.h
  223250. header-y += nbd.h
  223251. header-y += ncp.h
  223252. @@ -318,6 +322,8 @@
  223253. header-y += prctl.h
  223254. header-y += ptp_clock.h
  223255. header-y += ptrace.h
  223256. +header-y += pxp_dma.h
  223257. +header-y += pxp_device.h
  223258. header-y += qnx4_fs.h
  223259. header-y += qnxtypes.h
  223260. header-y += quota.h
  223261. diff -Nur linux-3.14.15/include/uapi/linux/mxc_asrc.h linux-linaro-stable-mx6/include/uapi/linux/mxc_asrc.h
  223262. --- linux-3.14.15/include/uapi/linux/mxc_asrc.h 1970-01-01 01:00:00.000000000 +0100
  223263. +++ linux-linaro-stable-mx6/include/uapi/linux/mxc_asrc.h 2014-08-20 19:24:06.550901310 +0200
  223264. @@ -0,0 +1,143 @@
  223265. +/*
  223266. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  223267. + *
  223268. + * The code contained herein is licensed under the GNU General Public
  223269. + * License. You may obtain a copy of the GNU General Public License
  223270. + * Version 2 or later at the following locations:
  223271. + *
  223272. + * http://www.opensource.org/licenses/gpl-license.html
  223273. + * http://www.gnu.org/copyleft/gpl.html
  223274. + *
  223275. + * @file mxc_asrc.h
  223276. + *
  223277. + * @brief i.MX Asynchronous Sample Rate Converter
  223278. + *
  223279. + * @ingroup Audio
  223280. + */
  223281. +
  223282. +#ifndef __MXC_ASRC_UAPI_H__
  223283. +#define __MXC_ASRC_UAPI_H__
  223284. +
  223285. +#define ASRC_IOC_MAGIC 'C'
  223286. +
  223287. +#define ASRC_REQ_PAIR _IOWR(ASRC_IOC_MAGIC, 0, struct asrc_req)
  223288. +#define ASRC_CONFIG_PAIR _IOWR(ASRC_IOC_MAGIC, 1, struct asrc_config)
  223289. +#define ASRC_RELEASE_PAIR _IOW(ASRC_IOC_MAGIC, 2, enum asrc_pair_index)
  223290. +#define ASRC_CONVERT _IOW(ASRC_IOC_MAGIC, 3, struct asrc_convert_buffer)
  223291. +#define ASRC_START_CONV _IOW(ASRC_IOC_MAGIC, 4, enum asrc_pair_index)
  223292. +#define ASRC_STOP_CONV _IOW(ASRC_IOC_MAGIC, 5, enum asrc_pair_index)
  223293. +#define ASRC_STATUS _IOW(ASRC_IOC_MAGIC, 6, struct asrc_status_flags)
  223294. +#define ASRC_FLUSH _IOW(ASRC_IOC_MAGIC, 7, enum asrc_pair_index)
  223295. +
  223296. +enum asrc_pair_index {
  223297. + ASRC_UNVALID_PAIR = -1,
  223298. + ASRC_PAIR_A = 0,
  223299. + ASRC_PAIR_B = 1,
  223300. + ASRC_PAIR_C = 2,
  223301. +};
  223302. +
  223303. +#define ASRC_PAIR_MAX_NUM (ASRC_PAIR_C + 1)
  223304. +
  223305. +enum asrc_inclk {
  223306. + INCLK_NONE = 0x03,
  223307. + INCLK_ESAI_RX = 0x00,
  223308. + INCLK_SSI1_RX = 0x01,
  223309. + INCLK_SSI2_RX = 0x02,
  223310. + INCLK_SSI3_RX = 0x07,
  223311. + INCLK_SPDIF_RX = 0x04,
  223312. + INCLK_MLB_CLK = 0x05,
  223313. + INCLK_PAD = 0x06,
  223314. + INCLK_ESAI_TX = 0x08,
  223315. + INCLK_SSI1_TX = 0x09,
  223316. + INCLK_SSI2_TX = 0x0a,
  223317. + INCLK_SSI3_TX = 0x0b,
  223318. + INCLK_SPDIF_TX = 0x0c,
  223319. + INCLK_ASRCK1_CLK = 0x0f,
  223320. +};
  223321. +
  223322. +enum asrc_outclk {
  223323. + OUTCLK_NONE = 0x03,
  223324. + OUTCLK_ESAI_TX = 0x00,
  223325. + OUTCLK_SSI1_TX = 0x01,
  223326. + OUTCLK_SSI2_TX = 0x02,
  223327. + OUTCLK_SSI3_TX = 0x07,
  223328. + OUTCLK_SPDIF_TX = 0x04,
  223329. + OUTCLK_MLB_CLK = 0x05,
  223330. + OUTCLK_PAD = 0x06,
  223331. + OUTCLK_ESAI_RX = 0x08,
  223332. + OUTCLK_SSI1_RX = 0x09,
  223333. + OUTCLK_SSI2_RX = 0x0a,
  223334. + OUTCLK_SSI3_RX = 0x0b,
  223335. + OUTCLK_SPDIF_RX = 0x0c,
  223336. + OUTCLK_ASRCK1_CLK = 0x0f,
  223337. +};
  223338. +
  223339. +enum asrc_word_width {
  223340. + ASRC_WIDTH_24_BIT = 0,
  223341. + ASRC_WIDTH_16_BIT = 1,
  223342. + ASRC_WIDTH_8_BIT = 2,
  223343. +};
  223344. +
  223345. +struct asrc_config {
  223346. + enum asrc_pair_index pair;
  223347. + unsigned int channel_num;
  223348. + unsigned int buffer_num;
  223349. + unsigned int dma_buffer_size;
  223350. + unsigned int input_sample_rate;
  223351. + unsigned int output_sample_rate;
  223352. + enum asrc_word_width input_word_width;
  223353. + enum asrc_word_width output_word_width;
  223354. + enum asrc_inclk inclk;
  223355. + enum asrc_outclk outclk;
  223356. +};
  223357. +
  223358. +struct asrc_pair {
  223359. + unsigned int start_channel;
  223360. + unsigned int chn_num;
  223361. + unsigned int chn_max;
  223362. + unsigned int active;
  223363. + unsigned int overload_error;
  223364. +};
  223365. +
  223366. +struct asrc_req {
  223367. + unsigned int chn_num;
  223368. + enum asrc_pair_index index;
  223369. +};
  223370. +
  223371. +struct asrc_querybuf {
  223372. + unsigned int buffer_index;
  223373. + unsigned int input_length;
  223374. + unsigned int output_length;
  223375. + unsigned long input_offset;
  223376. + unsigned long output_offset;
  223377. +};
  223378. +
  223379. +struct asrc_convert_buffer {
  223380. + void *input_buffer_vaddr;
  223381. + void *output_buffer_vaddr;
  223382. + unsigned int input_buffer_length;
  223383. + unsigned int output_buffer_length;
  223384. +};
  223385. +
  223386. +struct asrc_buffer {
  223387. + unsigned int index;
  223388. + unsigned int length;
  223389. + unsigned int output_last_length;
  223390. + int buf_valid;
  223391. +};
  223392. +
  223393. +struct asrc_status_flags {
  223394. + enum asrc_pair_index index;
  223395. + unsigned int overload_error;
  223396. +};
  223397. +
  223398. +#define ASRC_BUF_NA -35 /* ASRC DQ's buffer is NOT available */
  223399. +#define ASRC_BUF_AV 35 /* ASRC DQ's buffer is available */
  223400. +enum asrc_error_status {
  223401. + ASRC_TASK_Q_OVERLOAD = 0x01,
  223402. + ASRC_OUTPUT_TASK_OVERLOAD = 0x02,
  223403. + ASRC_INPUT_TASK_OVERLOAD = 0x04,
  223404. + ASRC_OUTPUT_BUFFER_OVERFLOW = 0x08,
  223405. + ASRC_INPUT_BUFFER_UNDERRUN = 0x10,
  223406. +};
  223407. +#endif/* __MXC_ASRC_UAPI_H__ */
  223408. diff -Nur linux-3.14.15/include/uapi/linux/mxcfb.h linux-linaro-stable-mx6/include/uapi/linux/mxcfb.h
  223409. --- linux-3.14.15/include/uapi/linux/mxcfb.h 1970-01-01 01:00:00.000000000 +0100
  223410. +++ linux-linaro-stable-mx6/include/uapi/linux/mxcfb.h 2014-08-20 19:24:06.550901310 +0200
  223411. @@ -0,0 +1,174 @@
  223412. +/*
  223413. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  223414. + */
  223415. +
  223416. +/*
  223417. + * This program is free software; you can redistribute it and/or modify
  223418. + * it under the terms of the GNU General Public License as published by
  223419. + * the Free Software Foundation; either version 2 of the License, or
  223420. + * (at your option) any later version.
  223421. + *
  223422. + * This program is distributed in the hope that it will be useful,
  223423. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223424. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223425. + * GNU General Public License for more details.
  223426. + *
  223427. + * You should have received a copy of the GNU General Public License along
  223428. + * with this program; if not, write to the Free Software Foundation, Inc.,
  223429. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  223430. + */
  223431. +
  223432. +/*
  223433. + * @file uapi/linux/mxcfb.h
  223434. + *
  223435. + * @brief Global header file for the MXC frame buffer
  223436. + *
  223437. + * @ingroup Framebuffer
  223438. + */
  223439. +#ifndef __ASM_ARCH_MXCFB_H__
  223440. +#define __ASM_ARCH_MXCFB_H__
  223441. +
  223442. +#include <linux/fb.h>
  223443. +
  223444. +#define FB_SYNC_OE_LOW_ACT 0x80000000
  223445. +#define FB_SYNC_CLK_LAT_FALL 0x40000000
  223446. +#define FB_SYNC_DATA_INVERT 0x20000000
  223447. +#define FB_SYNC_CLK_IDLE_EN 0x10000000
  223448. +#define FB_SYNC_SHARP_MODE 0x08000000
  223449. +#define FB_SYNC_SWAP_RGB 0x04000000
  223450. +#define FB_ACCEL_TRIPLE_FLAG 0x00000000
  223451. +#define FB_ACCEL_DOUBLE_FLAG 0x00000001
  223452. +
  223453. +struct mxcfb_gbl_alpha {
  223454. + int enable;
  223455. + int alpha;
  223456. +};
  223457. +
  223458. +struct mxcfb_loc_alpha {
  223459. + int enable;
  223460. + int alpha_in_pixel;
  223461. + unsigned long alpha_phy_addr0;
  223462. + unsigned long alpha_phy_addr1;
  223463. +};
  223464. +
  223465. +struct mxcfb_color_key {
  223466. + int enable;
  223467. + __u32 color_key;
  223468. +};
  223469. +
  223470. +struct mxcfb_pos {
  223471. + __u16 x;
  223472. + __u16 y;
  223473. +};
  223474. +
  223475. +struct mxcfb_gamma {
  223476. + int enable;
  223477. + int constk[16];
  223478. + int slopek[16];
  223479. +};
  223480. +
  223481. +struct mxcfb_rect {
  223482. + __u32 top;
  223483. + __u32 left;
  223484. + __u32 width;
  223485. + __u32 height;
  223486. +};
  223487. +
  223488. +#define GRAYSCALE_8BIT 0x1
  223489. +#define GRAYSCALE_8BIT_INVERTED 0x2
  223490. +#define GRAYSCALE_4BIT 0x3
  223491. +#define GRAYSCALE_4BIT_INVERTED 0x4
  223492. +
  223493. +#define AUTO_UPDATE_MODE_REGION_MODE 0
  223494. +#define AUTO_UPDATE_MODE_AUTOMATIC_MODE 1
  223495. +
  223496. +#define UPDATE_SCHEME_SNAPSHOT 0
  223497. +#define UPDATE_SCHEME_QUEUE 1
  223498. +#define UPDATE_SCHEME_QUEUE_AND_MERGE 2
  223499. +
  223500. +#define UPDATE_MODE_PARTIAL 0x0
  223501. +#define UPDATE_MODE_FULL 0x1
  223502. +
  223503. +#define WAVEFORM_MODE_AUTO 257
  223504. +
  223505. +#define TEMP_USE_AMBIENT 0x1000
  223506. +
  223507. +#define EPDC_FLAG_ENABLE_INVERSION 0x01
  223508. +#define EPDC_FLAG_FORCE_MONOCHROME 0x02
  223509. +#define EPDC_FLAG_USE_CMAP 0x04
  223510. +#define EPDC_FLAG_USE_ALT_BUFFER 0x100
  223511. +#define EPDC_FLAG_TEST_COLLISION 0x200
  223512. +#define EPDC_FLAG_GROUP_UPDATE 0x400
  223513. +#define EPDC_FLAG_USE_DITHERING_Y1 0x2000
  223514. +#define EPDC_FLAG_USE_DITHERING_Y4 0x4000
  223515. +
  223516. +#define FB_POWERDOWN_DISABLE -1
  223517. +
  223518. +struct mxcfb_alt_buffer_data {
  223519. + __u32 phys_addr;
  223520. + __u32 width; /* width of entire buffer */
  223521. + __u32 height; /* height of entire buffer */
  223522. + struct mxcfb_rect alt_update_region; /* region within buffer to update */
  223523. +};
  223524. +
  223525. +struct mxcfb_update_data {
  223526. + struct mxcfb_rect update_region;
  223527. + __u32 waveform_mode;
  223528. + __u32 update_mode;
  223529. + __u32 update_marker;
  223530. + int temp;
  223531. + unsigned int flags;
  223532. + struct mxcfb_alt_buffer_data alt_buffer_data;
  223533. +};
  223534. +
  223535. +struct mxcfb_update_marker_data {
  223536. + __u32 update_marker;
  223537. + __u32 collision_test;
  223538. +};
  223539. +
  223540. +/*
  223541. + * Structure used to define waveform modes for driver
  223542. + * Needed for driver to perform auto-waveform selection
  223543. + */
  223544. +struct mxcfb_waveform_modes {
  223545. + int mode_init;
  223546. + int mode_du;
  223547. + int mode_gc4;
  223548. + int mode_gc8;
  223549. + int mode_gc16;
  223550. + int mode_gc32;
  223551. +};
  223552. +
  223553. +/*
  223554. + * Structure used to define a 5*3 matrix of parameters for
  223555. + * setting IPU DP CSC module related to this framebuffer.
  223556. + */
  223557. +struct mxcfb_csc_matrix {
  223558. + int param[5][3];
  223559. +};
  223560. +
  223561. +#define MXCFB_WAIT_FOR_VSYNC _IOW('F', 0x20, u_int32_t)
  223562. +#define MXCFB_SET_GBL_ALPHA _IOW('F', 0x21, struct mxcfb_gbl_alpha)
  223563. +#define MXCFB_SET_CLR_KEY _IOW('F', 0x22, struct mxcfb_color_key)
  223564. +#define MXCFB_SET_OVERLAY_POS _IOWR('F', 0x24, struct mxcfb_pos)
  223565. +#define MXCFB_GET_FB_IPU_CHAN _IOR('F', 0x25, u_int32_t)
  223566. +#define MXCFB_SET_LOC_ALPHA _IOWR('F', 0x26, struct mxcfb_loc_alpha)
  223567. +#define MXCFB_SET_LOC_ALP_BUF _IOW('F', 0x27, unsigned long)
  223568. +#define MXCFB_SET_GAMMA _IOW('F', 0x28, struct mxcfb_gamma)
  223569. +#define MXCFB_GET_FB_IPU_DI _IOR('F', 0x29, u_int32_t)
  223570. +#define MXCFB_GET_DIFMT _IOR('F', 0x2A, u_int32_t)
  223571. +#define MXCFB_GET_FB_BLANK _IOR('F', 0x2B, u_int32_t)
  223572. +#define MXCFB_SET_DIFMT _IOW('F', 0x2C, u_int32_t)
  223573. +#define MXCFB_CSC_UPDATE _IOW('F', 0x2D, struct mxcfb_csc_matrix)
  223574. +
  223575. +/* IOCTLs for E-ink panel updates */
  223576. +#define MXCFB_SET_WAVEFORM_MODES _IOW('F', 0x2B, struct mxcfb_waveform_modes)
  223577. +#define MXCFB_SET_TEMPERATURE _IOW('F', 0x2C, int32_t)
  223578. +#define MXCFB_SET_AUTO_UPDATE_MODE _IOW('F', 0x2D, __u32)
  223579. +#define MXCFB_SEND_UPDATE _IOW('F', 0x2E, struct mxcfb_update_data)
  223580. +#define MXCFB_WAIT_FOR_UPDATE_COMPLETE _IOWR('F', 0x2F, struct mxcfb_update_marker_data)
  223581. +#define MXCFB_SET_PWRDOWN_DELAY _IOW('F', 0x30, int32_t)
  223582. +#define MXCFB_GET_PWRDOWN_DELAY _IOR('F', 0x31, int32_t)
  223583. +#define MXCFB_SET_UPDATE_SCHEME _IOW('F', 0x32, __u32)
  223584. +#define MXCFB_GET_WORK_BUFFER _IOWR('F', 0x34, unsigned long)
  223585. +#endif
  223586. diff -Nur linux-3.14.15/include/uapi/linux/mxc_mlb.h linux-linaro-stable-mx6/include/uapi/linux/mxc_mlb.h
  223587. --- linux-3.14.15/include/uapi/linux/mxc_mlb.h 1970-01-01 01:00:00.000000000 +0100
  223588. +++ linux-linaro-stable-mx6/include/uapi/linux/mxc_mlb.h 2014-08-20 19:24:06.550901310 +0200
  223589. @@ -0,0 +1,55 @@
  223590. +/*
  223591. + * mxc_mlb.h
  223592. + *
  223593. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  223594. + */
  223595. +
  223596. +/*
  223597. + * The code contained herein is licensed under the GNU General Public
  223598. + * License. You may obtain a copy of the GNU General Public License
  223599. + * Version 2 or later at the following locations:
  223600. + *
  223601. + * http://www.opensource.org/licenses/gpl-license.html
  223602. + * http://www.gnu.org/copyleft/gpl.html
  223603. + */
  223604. +
  223605. +#ifndef _MXC_MLB_UAPI_H
  223606. +#define _MXC_MLB_UAPI_H
  223607. +
  223608. +/* define IOCTL command */
  223609. +#define MLB_DBG_RUNTIME _IO('S', 0x09)
  223610. +#define MLB_SET_FPS _IOW('S', 0x10, unsigned int)
  223611. +#define MLB_GET_VER _IOR('S', 0x11, unsigned long)
  223612. +#define MLB_SET_DEVADDR _IOR('S', 0x12, unsigned char)
  223613. +
  223614. +/*!
  223615. + * set channel address for each logical channel
  223616. + * the MSB 16bits is for tx channel, the left LSB is for rx channel
  223617. + */
  223618. +#define MLB_CHAN_SETADDR _IOW('S', 0x13, unsigned int)
  223619. +#define MLB_CHAN_STARTUP _IO('S', 0x14)
  223620. +#define MLB_CHAN_SHUTDOWN _IO('S', 0x15)
  223621. +#define MLB_CHAN_GETEVENT _IOR('S', 0x16, unsigned long)
  223622. +
  223623. +#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
  223624. +#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
  223625. +#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
  223626. +#define MLB_IRQ_ENABLE _IO('S', 0x20)
  223627. +#define MLB_IRQ_DISABLE _IO('S', 0x21)
  223628. +
  223629. +/*!
  223630. + * MLB event define
  223631. + */
  223632. +enum {
  223633. + MLB_EVT_TX_PROTO_ERR_CUR = 1 << 0,
  223634. + MLB_EVT_TX_BRK_DETECT_CUR = 1 << 1,
  223635. + MLB_EVT_TX_PROTO_ERR_PREV = 1 << 8,
  223636. + MLB_EVT_TX_BRK_DETECT_PREV = 1 << 9,
  223637. + MLB_EVT_RX_PROTO_ERR_CUR = 1 << 16,
  223638. + MLB_EVT_RX_BRK_DETECT_CUR = 1 << 17,
  223639. + MLB_EVT_RX_PROTO_ERR_PREV = 1 << 24,
  223640. + MLB_EVT_RX_BRK_DETECT_PREV = 1 << 25,
  223641. +};
  223642. +
  223643. +
  223644. +#endif /* _MXC_MLB_H */
  223645. diff -Nur linux-3.14.15/include/uapi/linux/mxc_v4l2.h linux-linaro-stable-mx6/include/uapi/linux/mxc_v4l2.h
  223646. --- linux-3.14.15/include/uapi/linux/mxc_v4l2.h 1970-01-01 01:00:00.000000000 +0100
  223647. +++ linux-linaro-stable-mx6/include/uapi/linux/mxc_v4l2.h 2014-08-20 19:24:06.550901310 +0200
  223648. @@ -0,0 +1,56 @@
  223649. +/*
  223650. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  223651. + */
  223652. +
  223653. +/*
  223654. + * This program is free software; you can redistribute it and/or modify
  223655. + * it under the terms of the GNU General Public License as published by
  223656. + * the Free Software Foundation; either version 2 of the License, or
  223657. + * (at your option) any later version.
  223658. + *
  223659. + * This program is distributed in the hope that it will be useful,
  223660. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223661. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223662. + * GNU General Public License for more details.
  223663. + *
  223664. + * You should have received a copy of the GNU General Public License along
  223665. + * with this program; if not, write to the Free Software Foundation, Inc.,
  223666. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  223667. + */
  223668. +
  223669. +/*!
  223670. + * @file uapi/linux/mxc_v4l2.h
  223671. + *
  223672. + * @brief MXC V4L2 private header file
  223673. + *
  223674. + * @ingroup MXC V4L2
  223675. + */
  223676. +
  223677. +#ifndef __ASM_ARCH_MXC_V4L2_H__
  223678. +#define __ASM_ARCH_MXC_V4L2_H__
  223679. +
  223680. +/*
  223681. + * For IPUv1 and IPUv3, V4L2_CID_MXC_ROT means encoder ioctl ID.
  223682. + * And V4L2_CID_MXC_VF_ROT is viewfinder ioctl ID only for IPUv1 and IPUv3.
  223683. + */
  223684. +#define V4L2_CID_MXC_ROT (V4L2_CID_PRIVATE_BASE + 0)
  223685. +#define V4L2_CID_MXC_FLASH (V4L2_CID_PRIVATE_BASE + 1)
  223686. +#define V4L2_CID_MXC_VF_ROT (V4L2_CID_PRIVATE_BASE + 2)
  223687. +#define V4L2_CID_MXC_MOTION (V4L2_CID_PRIVATE_BASE + 3)
  223688. +#define V4L2_CID_MXC_SWITCH_CAM (V4L2_CID_PRIVATE_BASE + 6)
  223689. +
  223690. +#define V4L2_MXC_ROTATE_NONE 0
  223691. +#define V4L2_MXC_ROTATE_VERT_FLIP 1
  223692. +#define V4L2_MXC_ROTATE_HORIZ_FLIP 2
  223693. +#define V4L2_MXC_ROTATE_180 3
  223694. +#define V4L2_MXC_ROTATE_90_RIGHT 4
  223695. +#define V4L2_MXC_ROTATE_90_RIGHT_VFLIP 5
  223696. +#define V4L2_MXC_ROTATE_90_RIGHT_HFLIP 6
  223697. +#define V4L2_MXC_ROTATE_90_LEFT 7
  223698. +
  223699. +struct v4l2_mxc_offset {
  223700. + uint32_t u_offset;
  223701. + uint32_t v_offset;
  223702. +};
  223703. +
  223704. +#endif
  223705. diff -Nur linux-3.14.15/include/uapi/linux/ptp_clock.h linux-linaro-stable-mx6/include/uapi/linux/ptp_clock.h
  223706. --- linux-3.14.15/include/uapi/linux/ptp_clock.h 2014-07-31 23:51:43.000000000 +0200
  223707. +++ linux-linaro-stable-mx6/include/uapi/linux/ptp_clock.h 2014-08-20 19:31:54.808906267 +0200
  223708. @@ -50,7 +50,8 @@
  223709. int n_ext_ts; /* Number of external time stamp channels. */
  223710. int n_per_out; /* Number of programmable periodic signals. */
  223711. int pps; /* Whether the clock supports a PPS callback. */
  223712. - int rsv[15]; /* Reserved for future use. */
  223713. + int n_pins; /* Number of input/output pins. */
  223714. + int rsv[14]; /* Reserved for future use. */
  223715. };
  223716. struct ptp_extts_request {
  223717. @@ -80,6 +81,40 @@
  223718. struct ptp_clock_time ts[2 * PTP_MAX_SAMPLES + 1];
  223719. };
  223720. +enum ptp_pin_function {
  223721. + PTP_PF_NONE,
  223722. + PTP_PF_EXTTS,
  223723. + PTP_PF_PEROUT,
  223724. + PTP_PF_PHYSYNC,
  223725. +};
  223726. +
  223727. +struct ptp_pin_desc {
  223728. + /*
  223729. + * Hardware specific human readable pin name. This field is
  223730. + * set by the kernel during the PTP_PIN_GETFUNC ioctl and is
  223731. + * ignored for the PTP_PIN_SETFUNC ioctl.
  223732. + */
  223733. + char name[64];
  223734. + /*
  223735. + * Pin index in the range of zero to ptp_clock_caps.n_pins - 1.
  223736. + */
  223737. + unsigned int index;
  223738. + /*
  223739. + * Which of the PTP_PF_xxx functions to use on this pin.
  223740. + */
  223741. + unsigned int func;
  223742. + /*
  223743. + * The specific channel to use for this function.
  223744. + * This corresponds to the 'index' field of the
  223745. + * PTP_EXTTS_REQUEST and PTP_PEROUT_REQUEST ioctls.
  223746. + */
  223747. + unsigned int chan;
  223748. + /*
  223749. + * Reserved for future use.
  223750. + */
  223751. + unsigned int rsv[5];
  223752. +};
  223753. +
  223754. #define PTP_CLK_MAGIC '='
  223755. #define PTP_CLOCK_GETCAPS _IOR(PTP_CLK_MAGIC, 1, struct ptp_clock_caps)
  223756. @@ -87,6 +122,8 @@
  223757. #define PTP_PEROUT_REQUEST _IOW(PTP_CLK_MAGIC, 3, struct ptp_perout_request)
  223758. #define PTP_ENABLE_PPS _IOW(PTP_CLK_MAGIC, 4, int)
  223759. #define PTP_SYS_OFFSET _IOW(PTP_CLK_MAGIC, 5, struct ptp_sys_offset)
  223760. +#define PTP_PIN_GETFUNC _IOWR(PTP_CLK_MAGIC, 6, struct ptp_pin_desc)
  223761. +#define PTP_PIN_SETFUNC _IOW(PTP_CLK_MAGIC, 7, struct ptp_pin_desc)
  223762. struct ptp_extts_event {
  223763. struct ptp_clock_time t; /* Time event occured. */
  223764. diff -Nur linux-3.14.15/include/uapi/linux/pxp_device.h linux-linaro-stable-mx6/include/uapi/linux/pxp_device.h
  223765. --- linux-3.14.15/include/uapi/linux/pxp_device.h 1970-01-01 01:00:00.000000000 +0100
  223766. +++ linux-linaro-stable-mx6/include/uapi/linux/pxp_device.h 2014-08-20 19:31:54.812906284 +0200
  223767. @@ -0,0 +1,63 @@
  223768. +/*
  223769. + * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  223770. + *
  223771. + * This program is free software; you can redistribute it and/or modify
  223772. + * it under the terms of the GNU General Public License as published by
  223773. + * the Free Software Foundation; either version 2 of the License, or
  223774. + * (at your option) any later version.
  223775. + *
  223776. + * This program is distributed in the hope that it will be useful,
  223777. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223778. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223779. + * GNU General Public License for more details.
  223780. + *
  223781. + * You should have received a copy of the GNU General Public License
  223782. + * along with this program; if not, write to the Free Software
  223783. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  223784. + *
  223785. + */
  223786. +#ifndef _UAPI_PXP_DEVICE
  223787. +#define _UAPI_PXP_DEVICE
  223788. +
  223789. +#include <linux/pxp_dma.h>
  223790. +
  223791. +struct pxp_chan_handle {
  223792. + unsigned int handle;
  223793. + int hist_status;
  223794. +};
  223795. +
  223796. +struct pxp_mem_desc {
  223797. + unsigned int handle;
  223798. + unsigned int size;
  223799. + dma_addr_t phys_addr;
  223800. + unsigned int virt_uaddr; /* virtual user space address */
  223801. + unsigned int mtype;
  223802. +};
  223803. +
  223804. +struct pxp_mem_flush {
  223805. + unsigned int handle;
  223806. + unsigned int type;
  223807. +};
  223808. +
  223809. +#define PXP_IOC_MAGIC 'P'
  223810. +
  223811. +#define PXP_IOC_GET_CHAN _IOR(PXP_IOC_MAGIC, 0, struct pxp_mem_desc)
  223812. +#define PXP_IOC_PUT_CHAN _IOW(PXP_IOC_MAGIC, 1, struct pxp_mem_desc)
  223813. +#define PXP_IOC_CONFIG_CHAN _IOW(PXP_IOC_MAGIC, 2, struct pxp_mem_desc)
  223814. +#define PXP_IOC_START_CHAN _IOW(PXP_IOC_MAGIC, 3, struct pxp_mem_desc)
  223815. +#define PXP_IOC_GET_PHYMEM _IOWR(PXP_IOC_MAGIC, 4, struct pxp_mem_desc)
  223816. +#define PXP_IOC_PUT_PHYMEM _IOW(PXP_IOC_MAGIC, 5, struct pxp_mem_desc)
  223817. +#define PXP_IOC_WAIT4CMPLT _IOWR(PXP_IOC_MAGIC, 6, struct pxp_mem_desc)
  223818. +#define PXP_IOC_FLUSH_PHYMEM _IOR(PXP_IOC_MAGIC, 7, struct pxp_mem_flush)
  223819. +
  223820. +/* Memory types supported*/
  223821. +#define MEMORY_TYPE_UNCACHED 0x0
  223822. +#define MEMORY_TYPE_WC 0x1
  223823. +#define MEMORY_TYPE_CACHED 0x2
  223824. +
  223825. +/* Cache flush operations */
  223826. +#define CACHE_CLEAN 0x1
  223827. +#define CACHE_INVALIDATE 0x2
  223828. +#define CACHE_FLUSH 0x4
  223829. +
  223830. +#endif
  223831. diff -Nur linux-3.14.15/include/uapi/linux/pxp_dma.h linux-linaro-stable-mx6/include/uapi/linux/pxp_dma.h
  223832. --- linux-3.14.15/include/uapi/linux/pxp_dma.h 1970-01-01 01:00:00.000000000 +0100
  223833. +++ linux-linaro-stable-mx6/include/uapi/linux/pxp_dma.h 2014-08-20 19:31:54.812906284 +0200
  223834. @@ -0,0 +1,173 @@
  223835. +/*
  223836. + * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  223837. + *
  223838. + * This program is free software; you can redistribute it and/or modify
  223839. + * it under the terms of the GNU General Public License as published by
  223840. + * the Free Software Foundation; either version 2 of the License, or
  223841. + * (at your option) any later version.
  223842. + *
  223843. + * This program is distributed in the hope that it will be useful,
  223844. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223845. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223846. + * GNU General Public License for more details.
  223847. + *
  223848. + * You should have received a copy of the GNU General Public License
  223849. + * along with this program; if not, write to the Free Software
  223850. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  223851. + *
  223852. + */
  223853. +#ifndef _UAPI_PXP_DMA
  223854. +#define _UAPI_PXP_DMA
  223855. +
  223856. +#include <linux/posix_types.h>
  223857. +#include <linux/types.h>
  223858. +
  223859. +#ifndef __KERNEL__
  223860. +typedef unsigned long dma_addr_t;
  223861. +typedef unsigned char bool;
  223862. +#endif
  223863. +
  223864. +/* PXP Pixel format definitions */
  223865. +/* Four-character-code (FOURCC) */
  223866. +#define fourcc(a, b, c, d)\
  223867. + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
  223868. +
  223869. +/*!
  223870. + * @name PXP Pixel Formats
  223871. + *
  223872. + * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
  223873. + * the same used by V4L2 API.
  223874. + */
  223875. +
  223876. +/*! @} */
  223877. +/*! @name RGB Formats */
  223878. +/*! @{ */
  223879. +#define PXP_PIX_FMT_RGB332 fourcc('R', 'G', 'B', '1') /*!< 8 RGB-3-3-2 */
  223880. +#define PXP_PIX_FMT_RGB555 fourcc('R', 'G', 'B', 'O') /*!< 16 RGB-5-5-5 */
  223881. +#define PXP_PIX_FMT_RGB565 fourcc('R', 'G', 'B', 'P') /*!< 1 6 RGB-5-6-5 */
  223882. +#define PXP_PIX_FMT_RGB666 fourcc('R', 'G', 'B', '6') /*!< 18 RGB-6-6-6 */
  223883. +#define PXP_PIX_FMT_BGR666 fourcc('B', 'G', 'R', '6') /*!< 18 BGR-6-6-6 */
  223884. +#define PXP_PIX_FMT_BGR24 fourcc('B', 'G', 'R', '3') /*!< 24 BGR-8-8-8 */
  223885. +#define PXP_PIX_FMT_RGB24 fourcc('R', 'G', 'B', '3') /*!< 24 RGB-8-8-8 */
  223886. +#define PXP_PIX_FMT_BGR32 fourcc('B', 'G', 'R', '4') /*!< 32 BGR-8-8-8-8 */
  223887. +#define PXP_PIX_FMT_BGRA32 fourcc('B', 'G', 'R', 'A') /*!< 32 BGR-8-8-8-8 */
  223888. +#define PXP_PIX_FMT_RGB32 fourcc('R', 'G', 'B', '4') /*!< 32 RGB-8-8-8-8 */
  223889. +#define PXP_PIX_FMT_RGBA32 fourcc('R', 'G', 'B', 'A') /*!< 32 RGB-8-8-8-8 */
  223890. +#define PXP_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R') /*!< 32 ABGR-8-8-8-8 */
  223891. +/*! @} */
  223892. +/*! @name YUV Interleaved Formats */
  223893. +/*! @{ */
  223894. +#define PXP_PIX_FMT_YUYV fourcc('Y', 'U', 'Y', 'V') /*!< 16 YUV 4:2:2 */
  223895. +#define PXP_PIX_FMT_UYVY fourcc('U', 'Y', 'V', 'Y') /*!< 16 YUV 4:2:2 */
  223896. +#define PXP_PIX_FMT_VYUY fourcc('V', 'Y', 'U', 'Y') /*!< 16 YVU 4:2:2 */
  223897. +#define PXP_PIX_FMT_YVYU fourcc('Y', 'V', 'Y', 'U') /*!< 16 YVU 4:2:2 */
  223898. +#define PXP_PIX_FMT_Y41P fourcc('Y', '4', '1', 'P') /*!< 12 YUV 4:1:1 */
  223899. +#define PXP_PIX_FMT_YUV444 fourcc('Y', '4', '4', '4') /*!< 24 YUV 4:4:4 */
  223900. +/* two planes -- one Y, one Cb + Cr interleaved */
  223901. +#define PXP_PIX_FMT_NV12 fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
  223902. +#define PXP_PIX_FMT_NV21 fourcc('N', 'V', '2', '1') /* 12 Y/CbCr 4:2:0 */
  223903. +#define PXP_PIX_FMT_NV16 fourcc('N', 'V', '1', '6') /* 12 Y/CbCr 4:2:2 */
  223904. +#define PXP_PIX_FMT_NV61 fourcc('N', 'V', '6', '1') /* 12 Y/CbCr 4:2:2 */
  223905. +/*! @} */
  223906. +/*! @name YUV Planar Formats */
  223907. +/*! @{ */
  223908. +#define PXP_PIX_FMT_GREY fourcc('G', 'R', 'E', 'Y') /*!< 8 Greyscale */
  223909. +#define PXP_PIX_FMT_GY04 fourcc('G', 'Y', '0', '4') /*!< 4 Greyscale */
  223910. +#define PXP_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*!< 9 YVU 4:1:0 */
  223911. +#define PXP_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*!< 9 YUV 4:1:0 */
  223912. +#define PXP_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*!< 12 YVU 4:2:0 */
  223913. +#define PXP_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*!< 12 YUV 4:2:0 */
  223914. +#define PXP_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2') /*!< 12 YUV 4:2:0 */
  223915. +#define PXP_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*!< 16 YVU 4:2:2 */
  223916. +#define PXP_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*!< 16 YUV 4:2:2 */
  223917. +/*! @} */
  223918. +
  223919. +#define PXP_LUT_NONE 0x0
  223920. +#define PXP_LUT_INVERT 0x1
  223921. +#define PXP_LUT_BLACK_WHITE 0x2
  223922. +#define PXP_LUT_USE_CMAP 0x4
  223923. +
  223924. +#define NR_PXP_VIRT_CHANNEL 16
  223925. +
  223926. +/* Order significant! */
  223927. +enum pxp_channel_status {
  223928. + PXP_CHANNEL_FREE,
  223929. + PXP_CHANNEL_INITIALIZED,
  223930. + PXP_CHANNEL_READY,
  223931. +};
  223932. +
  223933. +struct rect {
  223934. + int top; /* Upper left coordinate of rectangle */
  223935. + int left;
  223936. + int width;
  223937. + int height;
  223938. +};
  223939. +
  223940. +struct pxp_layer_param {
  223941. + unsigned short width;
  223942. + unsigned short height;
  223943. + unsigned short stride; /* aka pitch */
  223944. + unsigned int pixel_fmt;
  223945. +
  223946. + /* layers combining parameters
  223947. + * (these are ignored for S0 and output
  223948. + * layers, and only apply for OL layer)
  223949. + */
  223950. + bool combine_enable;
  223951. + unsigned int color_key_enable;
  223952. + unsigned int color_key;
  223953. + bool global_alpha_enable;
  223954. + /* global alpha is either override or multiply */
  223955. + bool global_override;
  223956. + unsigned char global_alpha;
  223957. + bool alpha_invert;
  223958. + bool local_alpha_enable;
  223959. +
  223960. + dma_addr_t paddr;
  223961. +};
  223962. +
  223963. +struct pxp_proc_data {
  223964. + /* S0 Transformation Info */
  223965. + int scaling;
  223966. + int hflip;
  223967. + int vflip;
  223968. + int rotate;
  223969. + int rot_pos;
  223970. + int yuv;
  223971. +
  223972. + /* Source rectangle (srect) defines the sub-rectangle
  223973. + * within S0 to undergo processing.
  223974. + */
  223975. + struct rect srect;
  223976. + /* Dest rect (drect) defines how to position the processed
  223977. + * source rectangle (after resizing) within the output frame,
  223978. + * whose dimensions are defined in pxp->pxp_conf_state.out_param
  223979. + */
  223980. + struct rect drect;
  223981. +
  223982. + /* Current S0 configuration */
  223983. + unsigned int bgcolor;
  223984. +
  223985. + /* Output overlay support */
  223986. + int overlay_state;
  223987. +
  223988. + /* LUT transformation on Y data */
  223989. + int lut_transform;
  223990. + unsigned char *lut_map; /* 256 entries */
  223991. + bool lut_map_updated; /* Map recently changed */
  223992. + bool combine_enable;
  223993. +};
  223994. +
  223995. +struct pxp_config_data {
  223996. + struct pxp_layer_param s0_param;
  223997. + struct pxp_layer_param ol_param[8];
  223998. + struct pxp_layer_param out_param;
  223999. + struct pxp_proc_data proc_data;
  224000. + int layer_nr;
  224001. +
  224002. + /* Users don't touch */
  224003. + int handle;
  224004. +};
  224005. +
  224006. +
  224007. +#endif
  224008. diff -Nur linux-3.14.15/include/video/mxc_edid.h linux-linaro-stable-mx6/include/video/mxc_edid.h
  224009. --- linux-3.14.15/include/video/mxc_edid.h 1970-01-01 01:00:00.000000000 +0100
  224010. +++ linux-linaro-stable-mx6/include/video/mxc_edid.h 2014-08-20 19:24:06.682901874 +0200
  224011. @@ -0,0 +1,105 @@
  224012. +/*
  224013. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  224014. + */
  224015. +
  224016. +/*
  224017. + * The code contained herein is licensed under the GNU General Public
  224018. + * License. You may obtain a copy of the GNU General Public License
  224019. + * Version 2 or later at the following locations:
  224020. + *
  224021. + * http://www.opensource.org/licenses/gpl-license.html
  224022. + * http://www.gnu.org/copyleft/gpl.html
  224023. + */
  224024. +
  224025. +/*!
  224026. + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
  224027. + */
  224028. +
  224029. +/*!
  224030. + * @file mxc_edid.h
  224031. + *
  224032. + * @brief MXC EDID tools
  224033. + *
  224034. + * @ingroup Framebuffer
  224035. + */
  224036. +
  224037. +#ifndef MXC_EDID_H
  224038. +#define MXC_EDID_H
  224039. +
  224040. +#include <linux/fb.h>
  224041. +
  224042. +#define FB_VMODE_ASPECT_4_3 0x10
  224043. +#define FB_VMODE_ASPECT_16_9 0x20
  224044. +#define FB_VMODE_ASPECT_MASK (FB_VMODE_ASPECT_4_3 | FB_VMODE_ASPECT_16_9)
  224045. +
  224046. +enum cea_audio_coding_types {
  224047. + AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0,
  224048. + AUDIO_CODING_TYPE_LPCM = 1,
  224049. + AUDIO_CODING_TYPE_AC3 = 2,
  224050. + AUDIO_CODING_TYPE_MPEG1 = 3,
  224051. + AUDIO_CODING_TYPE_MP3 = 4,
  224052. + AUDIO_CODING_TYPE_MPEG2 = 5,
  224053. + AUDIO_CODING_TYPE_AACLC = 6,
  224054. + AUDIO_CODING_TYPE_DTS = 7,
  224055. + AUDIO_CODING_TYPE_ATRAC = 8,
  224056. + AUDIO_CODING_TYPE_SACD = 9,
  224057. + AUDIO_CODING_TYPE_EAC3 = 10,
  224058. + AUDIO_CODING_TYPE_DTS_HD = 11,
  224059. + AUDIO_CODING_TYPE_MLP = 12,
  224060. + AUDIO_CODING_TYPE_DST = 13,
  224061. + AUDIO_CODING_TYPE_WMAPRO = 14,
  224062. + AUDIO_CODING_TYPE_RESERVED = 15,
  224063. +};
  224064. +
  224065. +struct mxc_hdmi_3d_format {
  224066. + unsigned char vic_order_2d;
  224067. + unsigned char struct_3d;
  224068. + unsigned char detail_3d;
  224069. + unsigned char reserved;
  224070. +};
  224071. +
  224072. +struct mxc_edid_cfg {
  224073. + bool cea_underscan;
  224074. + bool cea_basicaudio;
  224075. + bool cea_ycbcr444;
  224076. + bool cea_ycbcr422;
  224077. + bool hdmi_cap;
  224078. +
  224079. + /*VSD*/
  224080. + bool vsd_support_ai;
  224081. + bool vsd_dc_48bit;
  224082. + bool vsd_dc_36bit;
  224083. + bool vsd_dc_30bit;
  224084. + bool vsd_dc_y444;
  224085. + bool vsd_dvi_dual;
  224086. +
  224087. + bool vsd_cnc0;
  224088. + bool vsd_cnc1;
  224089. + bool vsd_cnc2;
  224090. + bool vsd_cnc3;
  224091. +
  224092. + u8 vsd_video_latency;
  224093. + u8 vsd_audio_latency;
  224094. + u8 vsd_I_video_latency;
  224095. + u8 vsd_I_audio_latency;
  224096. +
  224097. + u8 physical_address[4];
  224098. + u8 hdmi_vic[64];
  224099. + struct mxc_hdmi_3d_format hdmi_3d_format[64];
  224100. + u16 hdmi_3d_mask_all;
  224101. + u16 hdmi_3d_struct_all;
  224102. + u32 vsd_max_tmdsclk_rate;
  224103. +
  224104. + u8 max_channels;
  224105. + u8 sample_sizes;
  224106. + u8 sample_rates;
  224107. + u8 speaker_alloc;
  224108. +};
  224109. +
  224110. +int mxc_edid_var_to_vic(struct fb_var_screeninfo *var);
  224111. +int mxc_edid_mode_to_vic(const struct fb_videomode *mode);
  224112. +int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
  224113. + unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi);
  224114. +int mxc_edid_parse_ext_blk(unsigned char *edid, struct mxc_edid_cfg *cfg,
  224115. + struct fb_monspecs *specs);
  224116. +#endif
  224117. diff -Nur linux-3.14.15/include/video/mxc_hdmi.h linux-linaro-stable-mx6/include/video/mxc_hdmi.h
  224118. --- linux-3.14.15/include/video/mxc_hdmi.h 1970-01-01 01:00:00.000000000 +0100
  224119. +++ linux-linaro-stable-mx6/include/video/mxc_hdmi.h 2014-08-20 19:31:54.848906440 +0200
  224120. @@ -0,0 +1,1020 @@
  224121. +/*
  224122. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  224123. + */
  224124. +
  224125. +/*
  224126. + * This program is free software; you can redistribute it and/or modify
  224127. + * it under the terms of the GNU General Public License as published by
  224128. + * the Free Software Foundation; either version 2 of the License, or
  224129. + * (at your option) any later version.
  224130. + *
  224131. + * This program is distributed in the hope that it will be useful,
  224132. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  224133. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  224134. + * GNU General Public License for more details.
  224135. + *
  224136. + * You should have received a copy of the GNU General Public License along
  224137. + * with this program; if not, write to the Free Software Foundation, Inc.,
  224138. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  224139. + */
  224140. +
  224141. +#ifndef __MXC_HDMI_H__
  224142. +#define __MXC_HDMI_H__
  224143. +
  224144. +/*
  224145. + * Hdmi controller registers
  224146. + */
  224147. +
  224148. +/* Identification Registers */
  224149. +#define HDMI_DESIGN_ID 0x0000
  224150. +#define HDMI_REVISION_ID 0x0001
  224151. +#define HDMI_PRODUCT_ID0 0x0002
  224152. +#define HDMI_PRODUCT_ID1 0x0003
  224153. +#define HDMI_CONFIG0_ID 0x0004
  224154. +#define HDMI_CONFIG1_ID 0x0005
  224155. +#define HDMI_CONFIG2_ID 0x0006
  224156. +#define HDMI_CONFIG3_ID 0x0007
  224157. +
  224158. +/* Interrupt Registers */
  224159. +#define HDMI_IH_FC_STAT0 0x0100
  224160. +#define HDMI_IH_FC_STAT1 0x0101
  224161. +#define HDMI_IH_FC_STAT2 0x0102
  224162. +#define HDMI_IH_AS_STAT0 0x0103
  224163. +#define HDMI_IH_PHY_STAT0 0x0104
  224164. +#define HDMI_IH_I2CM_STAT0 0x0105
  224165. +#define HDMI_IH_CEC_STAT0 0x0106
  224166. +#define HDMI_IH_VP_STAT0 0x0107
  224167. +#define HDMI_IH_I2CMPHY_STAT0 0x0108
  224168. +#define HDMI_IH_AHBDMAAUD_STAT0 0x0109
  224169. +
  224170. +#define HDMI_IH_MUTE_FC_STAT0 0x0180
  224171. +#define HDMI_IH_MUTE_FC_STAT1 0x0181
  224172. +#define HDMI_IH_MUTE_FC_STAT2 0x0182
  224173. +#define HDMI_IH_MUTE_AS_STAT0 0x0183
  224174. +#define HDMI_IH_MUTE_PHY_STAT0 0x0184
  224175. +#define HDMI_IH_MUTE_I2CM_STAT0 0x0185
  224176. +#define HDMI_IH_MUTE_CEC_STAT0 0x0186
  224177. +#define HDMI_IH_MUTE_VP_STAT0 0x0187
  224178. +#define HDMI_IH_MUTE_I2CMPHY_STAT0 0x0188
  224179. +#define HDMI_IH_MUTE_AHBDMAAUD_STAT0 0x0189
  224180. +#define HDMI_IH_MUTE 0x01FF
  224181. +
  224182. +/* Video Sample Registers */
  224183. +#define HDMI_TX_INVID0 0x0200
  224184. +#define HDMI_TX_INSTUFFING 0x0201
  224185. +#define HDMI_TX_GYDATA0 0x0202
  224186. +#define HDMI_TX_GYDATA1 0x0203
  224187. +#define HDMI_TX_RCRDATA0 0x0204
  224188. +#define HDMI_TX_RCRDATA1 0x0205
  224189. +#define HDMI_TX_BCBDATA0 0x0206
  224190. +#define HDMI_TX_BCBDATA1 0x0207
  224191. +
  224192. +/* Video Packetizer Registers */
  224193. +#define HDMI_VP_STATUS 0x0800
  224194. +#define HDMI_VP_PR_CD 0x0801
  224195. +#define HDMI_VP_STUFF 0x0802
  224196. +#define HDMI_VP_REMAP 0x0803
  224197. +#define HDMI_VP_CONF 0x0804
  224198. +#define HDMI_VP_STAT 0x0805
  224199. +#define HDMI_VP_INT 0x0806
  224200. +#define HDMI_VP_MASK 0x0807
  224201. +#define HDMI_VP_POL 0x0808
  224202. +
  224203. +/* Frame Composer Registers */
  224204. +#define HDMI_FC_INVIDCONF 0x1000
  224205. +#define HDMI_FC_INHACTV0 0x1001
  224206. +#define HDMI_FC_INHACTV1 0x1002
  224207. +#define HDMI_FC_INHBLANK0 0x1003
  224208. +#define HDMI_FC_INHBLANK1 0x1004
  224209. +#define HDMI_FC_INVACTV0 0x1005
  224210. +#define HDMI_FC_INVACTV1 0x1006
  224211. +#define HDMI_FC_INVBLANK 0x1007
  224212. +#define HDMI_FC_HSYNCINDELAY0 0x1008
  224213. +#define HDMI_FC_HSYNCINDELAY1 0x1009
  224214. +#define HDMI_FC_HSYNCINWIDTH0 0x100A
  224215. +#define HDMI_FC_HSYNCINWIDTH1 0x100B
  224216. +#define HDMI_FC_VSYNCINDELAY 0x100C
  224217. +#define HDMI_FC_VSYNCINWIDTH 0x100D
  224218. +#define HDMI_FC_INFREQ0 0x100E
  224219. +#define HDMI_FC_INFREQ1 0x100F
  224220. +#define HDMI_FC_INFREQ2 0x1010
  224221. +#define HDMI_FC_CTRLDUR 0x1011
  224222. +#define HDMI_FC_EXCTRLDUR 0x1012
  224223. +#define HDMI_FC_EXCTRLSPAC 0x1013
  224224. +#define HDMI_FC_CH0PREAM 0x1014
  224225. +#define HDMI_FC_CH1PREAM 0x1015
  224226. +#define HDMI_FC_CH2PREAM 0x1016
  224227. +#define HDMI_FC_AVICONF3 0x1017
  224228. +#define HDMI_FC_GCP 0x1018
  224229. +#define HDMI_FC_AVICONF0 0x1019
  224230. +#define HDMI_FC_AVICONF1 0x101A
  224231. +#define HDMI_FC_AVICONF2 0x101B
  224232. +#define HDMI_FC_AVIVID 0x101C
  224233. +#define HDMI_FC_AVIETB0 0x101D
  224234. +#define HDMI_FC_AVIETB1 0x101E
  224235. +#define HDMI_FC_AVISBB0 0x101F
  224236. +#define HDMI_FC_AVISBB1 0x1020
  224237. +#define HDMI_FC_AVIELB0 0x1021
  224238. +#define HDMI_FC_AVIELB1 0x1022
  224239. +#define HDMI_FC_AVISRB0 0x1023
  224240. +#define HDMI_FC_AVISRB1 0x1024
  224241. +#define HDMI_FC_AUDICONF0 0x1025
  224242. +#define HDMI_FC_AUDICONF1 0x1026
  224243. +#define HDMI_FC_AUDICONF2 0x1027
  224244. +#define HDMI_FC_AUDICONF3 0x1028
  224245. +#define HDMI_FC_VSDIEEEID0 0x1029
  224246. +#define HDMI_FC_VSDSIZE 0x102A
  224247. +#define HDMI_FC_VSDIEEEID1 0x1030
  224248. +#define HDMI_FC_VSDIEEEID2 0x1031
  224249. +#define HDMI_FC_VSDPAYLOAD0 0x1032
  224250. +#define HDMI_FC_VSDPAYLOAD1 0x1033
  224251. +#define HDMI_FC_VSDPAYLOAD2 0x1034
  224252. +#define HDMI_FC_VSDPAYLOAD3 0x1035
  224253. +#define HDMI_FC_VSDPAYLOAD4 0x1036
  224254. +#define HDMI_FC_VSDPAYLOAD5 0x1037
  224255. +#define HDMI_FC_VSDPAYLOAD6 0x1038
  224256. +#define HDMI_FC_VSDPAYLOAD7 0x1039
  224257. +#define HDMI_FC_VSDPAYLOAD8 0x103A
  224258. +#define HDMI_FC_VSDPAYLOAD9 0x103B
  224259. +#define HDMI_FC_VSDPAYLOAD10 0x103C
  224260. +#define HDMI_FC_VSDPAYLOAD11 0x103D
  224261. +#define HDMI_FC_VSDPAYLOAD12 0x103E
  224262. +#define HDMI_FC_VSDPAYLOAD13 0x103F
  224263. +#define HDMI_FC_VSDPAYLOAD14 0x1040
  224264. +#define HDMI_FC_VSDPAYLOAD15 0x1041
  224265. +#define HDMI_FC_VSDPAYLOAD16 0x1042
  224266. +#define HDMI_FC_VSDPAYLOAD17 0x1043
  224267. +#define HDMI_FC_VSDPAYLOAD18 0x1044
  224268. +#define HDMI_FC_VSDPAYLOAD19 0x1045
  224269. +#define HDMI_FC_VSDPAYLOAD20 0x1046
  224270. +#define HDMI_FC_VSDPAYLOAD21 0x1047
  224271. +#define HDMI_FC_VSDPAYLOAD22 0x1048
  224272. +#define HDMI_FC_VSDPAYLOAD23 0x1049
  224273. +#define HDMI_FC_SPDVENDORNAME0 0x104A
  224274. +#define HDMI_FC_SPDVENDORNAME1 0x104B
  224275. +#define HDMI_FC_SPDVENDORNAME2 0x104C
  224276. +#define HDMI_FC_SPDVENDORNAME3 0x104D
  224277. +#define HDMI_FC_SPDVENDORNAME4 0x104E
  224278. +#define HDMI_FC_SPDVENDORNAME5 0x104F
  224279. +#define HDMI_FC_SPDVENDORNAME6 0x1050
  224280. +#define HDMI_FC_SPDVENDORNAME7 0x1051
  224281. +#define HDMI_FC_SDPPRODUCTNAME0 0x1052
  224282. +#define HDMI_FC_SDPPRODUCTNAME1 0x1053
  224283. +#define HDMI_FC_SDPPRODUCTNAME2 0x1054
  224284. +#define HDMI_FC_SDPPRODUCTNAME3 0x1055
  224285. +#define HDMI_FC_SDPPRODUCTNAME4 0x1056
  224286. +#define HDMI_FC_SDPPRODUCTNAME5 0x1057
  224287. +#define HDMI_FC_SDPPRODUCTNAME6 0x1058
  224288. +#define HDMI_FC_SDPPRODUCTNAME7 0x1059
  224289. +#define HDMI_FC_SDPPRODUCTNAME8 0x105A
  224290. +#define HDMI_FC_SDPPRODUCTNAME9 0x105B
  224291. +#define HDMI_FC_SDPPRODUCTNAME10 0x105C
  224292. +#define HDMI_FC_SDPPRODUCTNAME11 0x105D
  224293. +#define HDMI_FC_SDPPRODUCTNAME12 0x105E
  224294. +#define HDMI_FC_SDPPRODUCTNAME13 0x105F
  224295. +#define HDMI_FC_SDPPRODUCTNAME14 0x1060
  224296. +#define HDMI_FC_SPDPRODUCTNAME15 0x1061
  224297. +#define HDMI_FC_SPDDEVICEINF 0x1062
  224298. +#define HDMI_FC_AUDSCONF 0x1063
  224299. +#define HDMI_FC_AUDSSTAT 0x1064
  224300. +#define HDMI_FC_DATACH0FILL 0x1070
  224301. +#define HDMI_FC_DATACH1FILL 0x1071
  224302. +#define HDMI_FC_DATACH2FILL 0x1072
  224303. +#define HDMI_FC_CTRLQHIGH 0x1073
  224304. +#define HDMI_FC_CTRLQLOW 0x1074
  224305. +#define HDMI_FC_ACP0 0x1075
  224306. +#define HDMI_FC_ACP28 0x1076
  224307. +#define HDMI_FC_ACP27 0x1077
  224308. +#define HDMI_FC_ACP26 0x1078
  224309. +#define HDMI_FC_ACP25 0x1079
  224310. +#define HDMI_FC_ACP24 0x107A
  224311. +#define HDMI_FC_ACP23 0x107B
  224312. +#define HDMI_FC_ACP22 0x107C
  224313. +#define HDMI_FC_ACP21 0x107D
  224314. +#define HDMI_FC_ACP20 0x107E
  224315. +#define HDMI_FC_ACP19 0x107F
  224316. +#define HDMI_FC_ACP18 0x1080
  224317. +#define HDMI_FC_ACP17 0x1081
  224318. +#define HDMI_FC_ACP16 0x1082
  224319. +#define HDMI_FC_ACP15 0x1083
  224320. +#define HDMI_FC_ACP14 0x1084
  224321. +#define HDMI_FC_ACP13 0x1085
  224322. +#define HDMI_FC_ACP12 0x1086
  224323. +#define HDMI_FC_ACP11 0x1087
  224324. +#define HDMI_FC_ACP10 0x1088
  224325. +#define HDMI_FC_ACP9 0x1089
  224326. +#define HDMI_FC_ACP8 0x108A
  224327. +#define HDMI_FC_ACP7 0x108B
  224328. +#define HDMI_FC_ACP6 0x108C
  224329. +#define HDMI_FC_ACP5 0x108D
  224330. +#define HDMI_FC_ACP4 0x108E
  224331. +#define HDMI_FC_ACP3 0x108F
  224332. +#define HDMI_FC_ACP2 0x1090
  224333. +#define HDMI_FC_ACP1 0x1091
  224334. +#define HDMI_FC_ISCR1_0 0x1092
  224335. +#define HDMI_FC_ISCR1_16 0x1093
  224336. +#define HDMI_FC_ISCR1_15 0x1094
  224337. +#define HDMI_FC_ISCR1_14 0x1095
  224338. +#define HDMI_FC_ISCR1_13 0x1096
  224339. +#define HDMI_FC_ISCR1_12 0x1097
  224340. +#define HDMI_FC_ISCR1_11 0x1098
  224341. +#define HDMI_FC_ISCR1_10 0x1099
  224342. +#define HDMI_FC_ISCR1_9 0x109A
  224343. +#define HDMI_FC_ISCR1_8 0x109B
  224344. +#define HDMI_FC_ISCR1_7 0x109C
  224345. +#define HDMI_FC_ISCR1_6 0x109D
  224346. +#define HDMI_FC_ISCR1_5 0x109E
  224347. +#define HDMI_FC_ISCR1_4 0x109F
  224348. +#define HDMI_FC_ISCR1_3 0x10A0
  224349. +#define HDMI_FC_ISCR1_2 0x10A1
  224350. +#define HDMI_FC_ISCR1_1 0x10A2
  224351. +#define HDMI_FC_ISCR2_15 0x10A3
  224352. +#define HDMI_FC_ISCR2_14 0x10A4
  224353. +#define HDMI_FC_ISCR2_13 0x10A5
  224354. +#define HDMI_FC_ISCR2_12 0x10A6
  224355. +#define HDMI_FC_ISCR2_11 0x10A7
  224356. +#define HDMI_FC_ISCR2_10 0x10A8
  224357. +#define HDMI_FC_ISCR2_9 0x10A9
  224358. +#define HDMI_FC_ISCR2_8 0x10AA
  224359. +#define HDMI_FC_ISCR2_7 0x10AB
  224360. +#define HDMI_FC_ISCR2_6 0x10AC
  224361. +#define HDMI_FC_ISCR2_5 0x10AD
  224362. +#define HDMI_FC_ISCR2_4 0x10AE
  224363. +#define HDMI_FC_ISCR2_3 0x10AF
  224364. +#define HDMI_FC_ISCR2_2 0x10B0
  224365. +#define HDMI_FC_ISCR2_1 0x10B1
  224366. +#define HDMI_FC_ISCR2_0 0x10B2
  224367. +#define HDMI_FC_DATAUTO0 0x10B3
  224368. +#define HDMI_FC_DATAUTO1 0x10B4
  224369. +#define HDMI_FC_DATAUTO2 0x10B5
  224370. +#define HDMI_FC_DATMAN 0x10B6
  224371. +#define HDMI_FC_DATAUTO3 0x10B7
  224372. +#define HDMI_FC_RDRB0 0x10B8
  224373. +#define HDMI_FC_RDRB1 0x10B9
  224374. +#define HDMI_FC_RDRB2 0x10BA
  224375. +#define HDMI_FC_RDRB3 0x10BB
  224376. +#define HDMI_FC_RDRB4 0x10BC
  224377. +#define HDMI_FC_RDRB5 0x10BD
  224378. +#define HDMI_FC_RDRB6 0x10BE
  224379. +#define HDMI_FC_RDRB7 0x10BF
  224380. +#define HDMI_FC_STAT0 0x10D0
  224381. +#define HDMI_FC_INT0 0x10D1
  224382. +#define HDMI_FC_MASK0 0x10D2
  224383. +#define HDMI_FC_POL0 0x10D3
  224384. +#define HDMI_FC_STAT1 0x10D4
  224385. +#define HDMI_FC_INT1 0x10D5
  224386. +#define HDMI_FC_MASK1 0x10D6
  224387. +#define HDMI_FC_POL1 0x10D7
  224388. +#define HDMI_FC_STAT2 0x10D8
  224389. +#define HDMI_FC_INT2 0x10D9
  224390. +#define HDMI_FC_MASK2 0x10DA
  224391. +#define HDMI_FC_POL2 0x10DB
  224392. +#define HDMI_FC_PRCONF 0x10E0
  224393. +
  224394. +#define HDMI_FC_GMD_STAT 0x1100
  224395. +#define HDMI_FC_GMD_EN 0x1101
  224396. +#define HDMI_FC_GMD_UP 0x1102
  224397. +#define HDMI_FC_GMD_CONF 0x1103
  224398. +#define HDMI_FC_GMD_HB 0x1104
  224399. +#define HDMI_FC_GMD_PB0 0x1105
  224400. +#define HDMI_FC_GMD_PB1 0x1106
  224401. +#define HDMI_FC_GMD_PB2 0x1107
  224402. +#define HDMI_FC_GMD_PB3 0x1108
  224403. +#define HDMI_FC_GMD_PB4 0x1109
  224404. +#define HDMI_FC_GMD_PB5 0x110A
  224405. +#define HDMI_FC_GMD_PB6 0x110B
  224406. +#define HDMI_FC_GMD_PB7 0x110C
  224407. +#define HDMI_FC_GMD_PB8 0x110D
  224408. +#define HDMI_FC_GMD_PB9 0x110E
  224409. +#define HDMI_FC_GMD_PB10 0x110F
  224410. +#define HDMI_FC_GMD_PB11 0x1110
  224411. +#define HDMI_FC_GMD_PB12 0x1111
  224412. +#define HDMI_FC_GMD_PB13 0x1112
  224413. +#define HDMI_FC_GMD_PB14 0x1113
  224414. +#define HDMI_FC_GMD_PB15 0x1114
  224415. +#define HDMI_FC_GMD_PB16 0x1115
  224416. +#define HDMI_FC_GMD_PB17 0x1116
  224417. +#define HDMI_FC_GMD_PB18 0x1117
  224418. +#define HDMI_FC_GMD_PB19 0x1118
  224419. +#define HDMI_FC_GMD_PB20 0x1119
  224420. +#define HDMI_FC_GMD_PB21 0x111A
  224421. +#define HDMI_FC_GMD_PB22 0x111B
  224422. +#define HDMI_FC_GMD_PB23 0x111C
  224423. +#define HDMI_FC_GMD_PB24 0x111D
  224424. +#define HDMI_FC_GMD_PB25 0x111E
  224425. +#define HDMI_FC_GMD_PB26 0x111F
  224426. +#define HDMI_FC_GMD_PB27 0x1120
  224427. +
  224428. +#define HDMI_FC_DBGFORCE 0x1200
  224429. +#define HDMI_FC_DBGAUD0CH0 0x1201
  224430. +#define HDMI_FC_DBGAUD1CH0 0x1202
  224431. +#define HDMI_FC_DBGAUD2CH0 0x1203
  224432. +#define HDMI_FC_DBGAUD0CH1 0x1204
  224433. +#define HDMI_FC_DBGAUD1CH1 0x1205
  224434. +#define HDMI_FC_DBGAUD2CH1 0x1206
  224435. +#define HDMI_FC_DBGAUD0CH2 0x1207
  224436. +#define HDMI_FC_DBGAUD1CH2 0x1208
  224437. +#define HDMI_FC_DBGAUD2CH2 0x1209
  224438. +#define HDMI_FC_DBGAUD0CH3 0x120A
  224439. +#define HDMI_FC_DBGAUD1CH3 0x120B
  224440. +#define HDMI_FC_DBGAUD2CH3 0x120C
  224441. +#define HDMI_FC_DBGAUD0CH4 0x120D
  224442. +#define HDMI_FC_DBGAUD1CH4 0x120E
  224443. +#define HDMI_FC_DBGAUD2CH4 0x120F
  224444. +#define HDMI_FC_DBGAUD0CH5 0x1210
  224445. +#define HDMI_FC_DBGAUD1CH5 0x1211
  224446. +#define HDMI_FC_DBGAUD2CH5 0x1212
  224447. +#define HDMI_FC_DBGAUD0CH6 0x1213
  224448. +#define HDMI_FC_DBGAUD1CH6 0x1214
  224449. +#define HDMI_FC_DBGAUD2CH6 0x1215
  224450. +#define HDMI_FC_DBGAUD0CH7 0x1216
  224451. +#define HDMI_FC_DBGAUD1CH7 0x1217
  224452. +#define HDMI_FC_DBGAUD2CH7 0x1218
  224453. +#define HDMI_FC_DBGTMDS0 0x1219
  224454. +#define HDMI_FC_DBGTMDS1 0x121A
  224455. +#define HDMI_FC_DBGTMDS2 0x121B
  224456. +
  224457. +/* HDMI Source PHY Registers */
  224458. +#define HDMI_PHY_CONF0 0x3000
  224459. +#define HDMI_PHY_TST0 0x3001
  224460. +#define HDMI_PHY_TST1 0x3002
  224461. +#define HDMI_PHY_TST2 0x3003
  224462. +#define HDMI_PHY_STAT0 0x3004
  224463. +#define HDMI_PHY_INT0 0x3005
  224464. +#define HDMI_PHY_MASK0 0x3006
  224465. +#define HDMI_PHY_POL0 0x3007
  224466. +
  224467. +/* HDMI Master PHY Registers */
  224468. +#define HDMI_PHY_I2CM_SLAVE_ADDR 0x3020
  224469. +#define HDMI_PHY_I2CM_ADDRESS_ADDR 0x3021
  224470. +#define HDMI_PHY_I2CM_DATAO_1_ADDR 0x3022
  224471. +#define HDMI_PHY_I2CM_DATAO_0_ADDR 0x3023
  224472. +#define HDMI_PHY_I2CM_DATAI_1_ADDR 0x3024
  224473. +#define HDMI_PHY_I2CM_DATAI_0_ADDR 0x3025
  224474. +#define HDMI_PHY_I2CM_OPERATION_ADDR 0x3026
  224475. +#define HDMI_PHY_I2CM_INT_ADDR 0x3027
  224476. +#define HDMI_PHY_I2CM_CTLINT_ADDR 0x3028
  224477. +#define HDMI_PHY_I2CM_DIV_ADDR 0x3029
  224478. +#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR 0x302a
  224479. +#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b
  224480. +#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c
  224481. +#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d
  224482. +#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e
  224483. +#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f
  224484. +#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030
  224485. +#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031
  224486. +#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032
  224487. +
  224488. +/* Audio Sampler Registers */
  224489. +#define HDMI_AUD_CONF0 0x3100
  224490. +#define HDMI_AUD_CONF1 0x3101
  224491. +#define HDMI_AUD_INT 0x3102
  224492. +#define HDMI_AUD_CONF2 0x3103
  224493. +#define HDMI_AUD_N1 0x3200
  224494. +#define HDMI_AUD_N2 0x3201
  224495. +#define HDMI_AUD_N3 0x3202
  224496. +#define HDMI_AUD_CTS1 0x3203
  224497. +#define HDMI_AUD_CTS2 0x3204
  224498. +#define HDMI_AUD_CTS3 0x3205
  224499. +#define HDMI_AUD_INPUTCLKFS 0x3206
  224500. +#define HDMI_AUD_SPDIFINT 0x3302
  224501. +#define HDMI_AUD_CONF0_HBR 0x3400
  224502. +#define HDMI_AUD_HBR_STATUS 0x3401
  224503. +#define HDMI_AUD_HBR_INT 0x3402
  224504. +#define HDMI_AUD_HBR_POL 0x3403
  224505. +#define HDMI_AUD_HBR_MASK 0x3404
  224506. +
  224507. +/* Generic Parallel Audio Interface Registers */
  224508. +/* Not used as GPAUD interface is not enabled in hw */
  224509. +#define HDMI_GP_CONF0 0x3500
  224510. +#define HDMI_GP_CONF1 0x3501
  224511. +#define HDMI_GP_CONF2 0x3502
  224512. +#define HDMI_GP_STAT 0x3503
  224513. +#define HDMI_GP_INT 0x3504
  224514. +#define HDMI_GP_MASK 0x3505
  224515. +#define HDMI_GP_POL 0x3506
  224516. +
  224517. +/* Audio DMA Registers */
  224518. +#define HDMI_AHB_DMA_CONF0 0x3600
  224519. +#define HDMI_AHB_DMA_START 0x3601
  224520. +#define HDMI_AHB_DMA_STOP 0x3602
  224521. +#define HDMI_AHB_DMA_THRSLD 0x3603
  224522. +#define HDMI_AHB_DMA_STRADDR0 0x3604
  224523. +#define HDMI_AHB_DMA_STRADDR1 0x3605
  224524. +#define HDMI_AHB_DMA_STRADDR2 0x3606
  224525. +#define HDMI_AHB_DMA_STRADDR3 0x3607
  224526. +#define HDMI_AHB_DMA_STPADDR0 0x3608
  224527. +#define HDMI_AHB_DMA_STPADDR1 0x3609
  224528. +#define HDMI_AHB_DMA_STPADDR2 0x360a
  224529. +#define HDMI_AHB_DMA_STPADDR3 0x360b
  224530. +#define HDMI_AHB_DMA_BSTADDR0 0x360c
  224531. +#define HDMI_AHB_DMA_BSTADDR1 0x360d
  224532. +#define HDMI_AHB_DMA_BSTADDR2 0x360e
  224533. +#define HDMI_AHB_DMA_BSTADDR3 0x360f
  224534. +#define HDMI_AHB_DMA_MBLENGTH0 0x3610
  224535. +#define HDMI_AHB_DMA_MBLENGTH1 0x3611
  224536. +#define HDMI_AHB_DMA_STAT 0x3612
  224537. +#define HDMI_AHB_DMA_INT 0x3613
  224538. +#define HDMI_AHB_DMA_MASK 0x3614
  224539. +#define HDMI_AHB_DMA_POL 0x3615
  224540. +#define HDMI_AHB_DMA_CONF1 0x3616
  224541. +#define HDMI_AHB_DMA_BUFFSTAT 0x3617
  224542. +#define HDMI_AHB_DMA_BUFFINT 0x3618
  224543. +#define HDMI_AHB_DMA_BUFFMASK 0x3619
  224544. +#define HDMI_AHB_DMA_BUFFPOL 0x361a
  224545. +
  224546. +/* Main Controller Registers */
  224547. +#define HDMI_MC_SFRDIV 0x4000
  224548. +#define HDMI_MC_CLKDIS 0x4001
  224549. +#define HDMI_MC_SWRSTZ 0x4002
  224550. +#define HDMI_MC_OPCTRL 0x4003
  224551. +#define HDMI_MC_FLOWCTRL 0x4004
  224552. +#define HDMI_MC_PHYRSTZ 0x4005
  224553. +#define HDMI_MC_LOCKONCLOCK 0x4006
  224554. +#define HDMI_MC_HEACPHY_RST 0x4007
  224555. +
  224556. +/* Color Space Converter Registers */
  224557. +#define HDMI_CSC_CFG 0x4100
  224558. +#define HDMI_CSC_SCALE 0x4101
  224559. +#define HDMI_CSC_COEF_A1_MSB 0x4102
  224560. +#define HDMI_CSC_COEF_A1_LSB 0x4103
  224561. +#define HDMI_CSC_COEF_A2_MSB 0x4104
  224562. +#define HDMI_CSC_COEF_A2_LSB 0x4105
  224563. +#define HDMI_CSC_COEF_A3_MSB 0x4106
  224564. +#define HDMI_CSC_COEF_A3_LSB 0x4107
  224565. +#define HDMI_CSC_COEF_A4_MSB 0x4108
  224566. +#define HDMI_CSC_COEF_A4_LSB 0x4109
  224567. +#define HDMI_CSC_COEF_B1_MSB 0x410A
  224568. +#define HDMI_CSC_COEF_B1_LSB 0x410B
  224569. +#define HDMI_CSC_COEF_B2_MSB 0x410C
  224570. +#define HDMI_CSC_COEF_B2_LSB 0x410D
  224571. +#define HDMI_CSC_COEF_B3_MSB 0x410E
  224572. +#define HDMI_CSC_COEF_B3_LSB 0x410F
  224573. +#define HDMI_CSC_COEF_B4_MSB 0x4110
  224574. +#define HDMI_CSC_COEF_B4_LSB 0x4111
  224575. +#define HDMI_CSC_COEF_C1_MSB 0x4112
  224576. +#define HDMI_CSC_COEF_C1_LSB 0x4113
  224577. +#define HDMI_CSC_COEF_C2_MSB 0x4114
  224578. +#define HDMI_CSC_COEF_C2_LSB 0x4115
  224579. +#define HDMI_CSC_COEF_C3_MSB 0x4116
  224580. +#define HDMI_CSC_COEF_C3_LSB 0x4117
  224581. +#define HDMI_CSC_COEF_C4_MSB 0x4118
  224582. +#define HDMI_CSC_COEF_C4_LSB 0x4119
  224583. +
  224584. +/* HDCP Interrupt Registers */
  224585. +#define HDMI_A_APIINTCLR 0x5006
  224586. +#define HDMI_A_APIINTSTAT 0x5007
  224587. +#define HDMI_A_APIINTMSK 0x5008
  224588. +
  224589. +/* CEC Engine Registers */
  224590. +#define HDMI_CEC_CTRL 0x7D00
  224591. +#define HDMI_CEC_STAT 0x7D01
  224592. +#define HDMI_CEC_MASK 0x7D02
  224593. +#define HDMI_CEC_POLARITY 0x7D03
  224594. +#define HDMI_CEC_INT 0x7D04
  224595. +#define HDMI_CEC_ADDR_L 0x7D05
  224596. +#define HDMI_CEC_ADDR_H 0x7D06
  224597. +#define HDMI_CEC_TX_CNT 0x7D07
  224598. +#define HDMI_CEC_RX_CNT 0x7D08
  224599. +#define HDMI_CEC_TX_DATA0 0x7D10
  224600. +#define HDMI_CEC_TX_DATA1 0x7D11
  224601. +#define HDMI_CEC_TX_DATA2 0x7D12
  224602. +#define HDMI_CEC_TX_DATA3 0x7D13
  224603. +#define HDMI_CEC_TX_DATA4 0x7D14
  224604. +#define HDMI_CEC_TX_DATA5 0x7D15
  224605. +#define HDMI_CEC_TX_DATA6 0x7D16
  224606. +#define HDMI_CEC_TX_DATA7 0x7D17
  224607. +#define HDMI_CEC_TX_DATA8 0x7D18
  224608. +#define HDMI_CEC_TX_DATA9 0x7D19
  224609. +#define HDMI_CEC_TX_DATA10 0x7D1a
  224610. +#define HDMI_CEC_TX_DATA11 0x7D1b
  224611. +#define HDMI_CEC_TX_DATA12 0x7D1c
  224612. +#define HDMI_CEC_TX_DATA13 0x7D1d
  224613. +#define HDMI_CEC_TX_DATA14 0x7D1e
  224614. +#define HDMI_CEC_TX_DATA15 0x7D1f
  224615. +#define HDMI_CEC_RX_DATA0 0x7D20
  224616. +#define HDMI_CEC_RX_DATA1 0x7D21
  224617. +#define HDMI_CEC_RX_DATA2 0x7D22
  224618. +#define HDMI_CEC_RX_DATA3 0x7D23
  224619. +#define HDMI_CEC_RX_DATA4 0x7D24
  224620. +#define HDMI_CEC_RX_DATA5 0x7D25
  224621. +#define HDMI_CEC_RX_DATA6 0x7D26
  224622. +#define HDMI_CEC_RX_DATA7 0x7D27
  224623. +#define HDMI_CEC_RX_DATA8 0x7D28
  224624. +#define HDMI_CEC_RX_DATA9 0x7D29
  224625. +#define HDMI_CEC_RX_DATA10 0x7D2a
  224626. +#define HDMI_CEC_RX_DATA11 0x7D2b
  224627. +#define HDMI_CEC_RX_DATA12 0x7D2c
  224628. +#define HDMI_CEC_RX_DATA13 0x7D2d
  224629. +#define HDMI_CEC_RX_DATA14 0x7D2e
  224630. +#define HDMI_CEC_RX_DATA15 0x7D2f
  224631. +#define HDMI_CEC_LOCK 0x7D30
  224632. +#define HDMI_CEC_WKUPCTRL 0x7D31
  224633. +
  224634. +/* I2C Master Registers (E-DDC) */
  224635. +#define HDMI_I2CM_SLAVE 0x7E00
  224636. +#define HDMI_I2CM_ADDRESS 0x7E01
  224637. +#define HDMI_I2CM_DATAO 0x7E02
  224638. +#define HDMI_I2CM_DATAI 0x7E03
  224639. +#define HDMI_I2CM_OPERATION 0x7E04
  224640. +#define HDMI_I2CM_INT 0x7E05
  224641. +#define HDMI_I2CM_CTLINT 0x7E06
  224642. +#define HDMI_I2CM_DIV 0x7E07
  224643. +#define HDMI_I2CM_SEGADDR 0x7E08
  224644. +#define HDMI_I2CM_SOFTRSTZ 0x7E09
  224645. +#define HDMI_I2CM_SEGPTR 0x7E0A
  224646. +#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR 0x7E0B
  224647. +#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x7E0C
  224648. +#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR 0x7E0D
  224649. +#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0x7E0E
  224650. +#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR 0x7E0F
  224651. +#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR 0x7E10
  224652. +#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR 0x7E11
  224653. +#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12
  224654. +
  224655. +/* Random Number Generator Registers (RNG) */
  224656. +#define HDMI_RNG_BASE 0x8000
  224657. +
  224658. +
  224659. +/*
  224660. + * Register field definitions
  224661. + */
  224662. +enum {
  224663. +/* IH_FC_INT2 field values */
  224664. + HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
  224665. + HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
  224666. + HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  224667. +
  224668. +/* IH_FC_STAT2 field values */
  224669. + HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03,
  224670. + HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
  224671. + HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  224672. +
  224673. +/* IH_PHY_STAT0 field values */
  224674. + HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20,
  224675. + HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10,
  224676. + HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8,
  224677. + HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4,
  224678. + HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2,
  224679. + HDMI_IH_PHY_STAT0_HPD = 0x1,
  224680. +
  224681. +/* IH_CEC_STAT0 field values */
  224682. + HDMI_IH_CEC_STAT0_WAKEUP = 0x40,
  224683. + HDMI_IH_CEC_STAT0_ERROR_FOLL = 0x20,
  224684. + HDMI_IH_CEC_STAT0_ERROR_INIT = 0x10,
  224685. + HDMI_IH_CEC_STAT0_ARB_LOST = 0x8,
  224686. + HDMI_IH_CEC_STAT0_NACK = 0x4,
  224687. + HDMI_IH_CEC_STAT0_EOM = 0x2,
  224688. + HDMI_IH_CEC_STAT0_DONE = 0x1,
  224689. +
  224690. +
  224691. +/* IH_MUTE_I2CMPHY_STAT0 field values */
  224692. + HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2,
  224693. + HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1,
  224694. +
  224695. +/* IH_PHY_STAT0 field values */
  224696. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE3 = 0x20,
  224697. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE2 = 0x10,
  224698. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE1 = 0x8,
  224699. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE0 = 0x4,
  224700. + HDMI_IH_MUTE_PHY_STAT0_TX_PHY_LOCK = 0x2,
  224701. + HDMI_IH_MUTE_PHY_STAT0_HPD = 0x1,
  224702. +
  224703. +/* IH_AHBDMAAUD_STAT0 field values */
  224704. + HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20,
  224705. + HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10,
  224706. + HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08,
  224707. + HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04,
  224708. + HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
  224709. + HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
  224710. +
  224711. +/* IH_MUTE_FC_STAT2 field values */
  224712. + HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03,
  224713. + HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
  224714. + HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  224715. +
  224716. +/* IH_MUTE_AHBDMAAUD_STAT0 field values */
  224717. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20,
  224718. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10,
  224719. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08,
  224720. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04,
  224721. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
  224722. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
  224723. +
  224724. +/* IH_MUTE field values */
  224725. + HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2,
  224726. + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1,
  224727. +
  224728. +/* TX_INVID0 field values */
  224729. + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80,
  224730. + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80,
  224731. + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00,
  224732. + HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F,
  224733. + HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0,
  224734. +
  224735. +/* TX_INSTUFFING field values */
  224736. + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4,
  224737. + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4,
  224738. + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0,
  224739. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2,
  224740. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2,
  224741. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0,
  224742. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1,
  224743. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1,
  224744. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0,
  224745. +
  224746. +/* VP_PR_CD field values */
  224747. + HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0,
  224748. + HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4,
  224749. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F,
  224750. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0,
  224751. +
  224752. +/* VP_STUFF field values */
  224753. + HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20,
  224754. + HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5,
  224755. + HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10,
  224756. + HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4,
  224757. + HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8,
  224758. + HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3,
  224759. + HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4,
  224760. + HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4,
  224761. + HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0,
  224762. + HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2,
  224763. + HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2,
  224764. + HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0,
  224765. + HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1,
  224766. + HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1,
  224767. + HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0,
  224768. +
  224769. +/* VP_CONF field values */
  224770. + HDMI_VP_CONF_BYPASS_EN_MASK = 0x40,
  224771. + HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40,
  224772. + HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00,
  224773. + HDMI_VP_CONF_PP_EN_ENMASK = 0x20,
  224774. + HDMI_VP_CONF_PP_EN_ENABLE = 0x20,
  224775. + HDMI_VP_CONF_PP_EN_DISABLE = 0x00,
  224776. + HDMI_VP_CONF_PR_EN_MASK = 0x10,
  224777. + HDMI_VP_CONF_PR_EN_ENABLE = 0x10,
  224778. + HDMI_VP_CONF_PR_EN_DISABLE = 0x00,
  224779. + HDMI_VP_CONF_YCC422_EN_MASK = 0x8,
  224780. + HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8,
  224781. + HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0,
  224782. + HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4,
  224783. + HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4,
  224784. + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0,
  224785. + HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3,
  224786. + HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3,
  224787. + HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1,
  224788. + HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0,
  224789. +
  224790. +/* VP_REMAP field values */
  224791. + HDMI_VP_REMAP_MASK = 0x3,
  224792. + HDMI_VP_REMAP_YCC422_24bit = 0x2,
  224793. + HDMI_VP_REMAP_YCC422_20bit = 0x1,
  224794. + HDMI_VP_REMAP_YCC422_16bit = 0x0,
  224795. +
  224796. +/* FC_INVIDCONF field values */
  224797. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40,
  224798. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40,
  224799. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
  224800. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20,
  224801. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20,
  224802. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
  224803. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10,
  224804. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10,
  224805. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00,
  224806. + HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8,
  224807. + HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8,
  224808. + HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0,
  224809. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2,
  224810. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2,
  224811. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0,
  224812. + HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1,
  224813. + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1,
  224814. + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0,
  224815. +
  224816. +/* FC_AUDICONF0 field values */
  224817. + HDMI_FC_AUDICONF0_CC_OFFSET = 4,
  224818. + HDMI_FC_AUDICONF0_CC_MASK = 0x70,
  224819. + HDMI_FC_AUDICONF0_CT_OFFSET = 0,
  224820. + HDMI_FC_AUDICONF0_CT_MASK = 0xF,
  224821. +
  224822. +/* FC_AUDICONF1 field values */
  224823. + HDMI_FC_AUDICONF1_SS_OFFSET = 3,
  224824. + HDMI_FC_AUDICONF1_SS_MASK = 0x18,
  224825. + HDMI_FC_AUDICONF1_SF_OFFSET = 0,
  224826. + HDMI_FC_AUDICONF1_SF_MASK = 0x7,
  224827. +
  224828. +/* FC_AUDICONF3 field values */
  224829. + HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5,
  224830. + HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60,
  224831. + HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4,
  224832. + HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10,
  224833. + HDMI_FC_AUDICONF3_LSV_OFFSET = 0,
  224834. + HDMI_FC_AUDICONF3_LSV_MASK = 0xF,
  224835. +
  224836. +/* FC_AUDSCHNLS0 field values */
  224837. + HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4,
  224838. + HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30,
  224839. + HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0,
  224840. + HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01,
  224841. +
  224842. +/* FC_AUDSCHNLS3-6 field values */
  224843. + HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0,
  224844. + HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f,
  224845. + HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4,
  224846. + HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0,
  224847. + HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0,
  224848. + HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f,
  224849. + HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4,
  224850. + HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0,
  224851. +
  224852. + HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0,
  224853. + HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f,
  224854. + HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4,
  224855. + HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0,
  224856. + HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0,
  224857. + HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f,
  224858. + HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4,
  224859. + HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0,
  224860. +
  224861. +/* HDMI_FC_AUDSCHNLS7 field values */
  224862. + HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4,
  224863. + HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30,
  224864. +
  224865. +/* HDMI_FC_AUDSCHNLS8 field values */
  224866. + HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0,
  224867. + HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4,
  224868. + HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f,
  224869. + HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0,
  224870. +
  224871. +/* FC_AUDSCONF field values */
  224872. + HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0,
  224873. + HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4,
  224874. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1,
  224875. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0,
  224876. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1,
  224877. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0,
  224878. +
  224879. +/* FC_STAT2 field values */
  224880. + HDMI_FC_STAT2_OVERFLOW_MASK = 0x03,
  224881. + HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
  224882. + HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  224883. +
  224884. +/* FC_INT2 field values */
  224885. + HDMI_FC_INT2_OVERFLOW_MASK = 0x03,
  224886. + HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
  224887. + HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  224888. +
  224889. +/* FC_MASK2 field values */
  224890. + HDMI_FC_MASK2_OVERFLOW_MASK = 0x03,
  224891. + HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02,
  224892. + HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01,
  224893. +
  224894. +/* FC_PRCONF field values */
  224895. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0,
  224896. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4,
  224897. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F,
  224898. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0,
  224899. +
  224900. +/* FC_AVICONF0-FC_AVICONF3 field values */
  224901. + HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03,
  224902. + HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00,
  224903. + HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01,
  224904. + HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02,
  224905. + HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40,
  224906. + HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40,
  224907. + HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00,
  224908. + HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C,
  224909. + HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00,
  224910. + HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04,
  224911. + HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08,
  224912. + HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C,
  224913. + HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30,
  224914. + HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10,
  224915. + HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20,
  224916. + HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00,
  224917. +
  224918. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F,
  224919. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08,
  224920. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09,
  224921. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A,
  224922. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B,
  224923. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30,
  224924. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00,
  224925. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10,
  224926. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20,
  224927. + HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0,
  224928. + HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00,
  224929. + HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40,
  224930. + HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80,
  224931. + HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0,
  224932. +
  224933. + HDMI_FC_AVICONF2_SCALING_MASK = 0x03,
  224934. + HDMI_FC_AVICONF2_SCALING_NONE = 0x00,
  224935. + HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01,
  224936. + HDMI_FC_AVICONF2_SCALING_VERT = 0x02,
  224937. + HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03,
  224938. + HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C,
  224939. + HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00,
  224940. + HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04,
  224941. + HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08,
  224942. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70,
  224943. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00,
  224944. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10,
  224945. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20,
  224946. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30,
  224947. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40,
  224948. + HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80,
  224949. + HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00,
  224950. + HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80,
  224951. +
  224952. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03,
  224953. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00,
  224954. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01,
  224955. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02,
  224956. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03,
  224957. + HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C,
  224958. + HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00,
  224959. + HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04,
  224960. +
  224961. +/* FC_DBGFORCE field values */
  224962. + HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10,
  224963. + HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1,
  224964. +
  224965. +/* PHY_CONF0 field values */
  224966. + HDMI_PHY_CONF0_PDZ_MASK = 0x80,
  224967. + HDMI_PHY_CONF0_PDZ_OFFSET = 7,
  224968. + HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
  224969. + HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
  224970. + HDMI_PHY_CONF0_SPARECTRL = 0x20,
  224971. + HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
  224972. + HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
  224973. + HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
  224974. + HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3,
  224975. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4,
  224976. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2,
  224977. + HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2,
  224978. + HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1,
  224979. + HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1,
  224980. + HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0,
  224981. +
  224982. +/* PHY_TST0 field values */
  224983. + HDMI_PHY_TST0_TSTCLR_MASK = 0x20,
  224984. + HDMI_PHY_TST0_TSTCLR_OFFSET = 5,
  224985. + HDMI_PHY_TST0_TSTEN_MASK = 0x10,
  224986. + HDMI_PHY_TST0_TSTEN_OFFSET = 4,
  224987. + HDMI_PHY_TST0_TSTCLK_MASK = 0x1,
  224988. + HDMI_PHY_TST0_TSTCLK_OFFSET = 0,
  224989. +
  224990. +/* PHY_STAT0 field values */
  224991. + HDMI_PHY_RX_SENSE3 = 0x80,
  224992. + HDMI_PHY_RX_SENSE2 = 0x40,
  224993. + HDMI_PHY_RX_SENSE1 = 0x20,
  224994. + HDMI_PHY_RX_SENSE0 = 0x10,
  224995. + HDMI_PHY_HPD = 0x02,
  224996. + HDMI_PHY_TX_PHY_LOCK = 0x01,
  224997. +
  224998. +/* PHY_I2CM_SLAVE_ADDR field values */
  224999. + HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69,
  225000. + HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49,
  225001. +
  225002. +/* PHY_I2CM_OPERATION_ADDR field values */
  225003. + HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10,
  225004. + HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1,
  225005. +
  225006. +/* HDMI_PHY_I2CM_INT_ADDR */
  225007. + HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08,
  225008. + HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04,
  225009. +
  225010. +/* HDMI_PHY_I2CM_CTLINT_ADDR */
  225011. + HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80,
  225012. + HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40,
  225013. + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08,
  225014. + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04,
  225015. +
  225016. +/* AUD_CTS3 field values */
  225017. + HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5,
  225018. + HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0,
  225019. + HDMI_AUD_CTS3_N_SHIFT_1 = 0,
  225020. + HDMI_AUD_CTS3_N_SHIFT_16 = 0x20,
  225021. + HDMI_AUD_CTS3_N_SHIFT_32 = 0x40,
  225022. + HDMI_AUD_CTS3_N_SHIFT_64 = 0x60,
  225023. + HDMI_AUD_CTS3_N_SHIFT_128 = 0x80,
  225024. + HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0,
  225025. + /* note that the CTS3 MANUAL bit has been removed
  225026. + from our part. Can't set it, will read as 0. */
  225027. + HDMI_AUD_CTS3_CTS_MANUAL = 0x10,
  225028. + HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f,
  225029. +
  225030. +/* AHB_DMA_CONF0 field values */
  225031. + HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7,
  225032. + HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80,
  225033. + HDMI_AHB_DMA_CONF0_HBR_OFFSET = 4,
  225034. + HDMI_AHB_DMA_CONF0_HBR_MASK = 0x10,
  225035. + HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3,
  225036. + HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08,
  225037. + HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1,
  225038. + HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06,
  225039. + HDMI_AHB_DMA_CONF0_INCR4 = 0x0,
  225040. + HDMI_AHB_DMA_CONF0_INCR8 = 0x2,
  225041. + HDMI_AHB_DMA_CONF0_INCR16 = 0x4,
  225042. + HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1,
  225043. +
  225044. +/* HDMI_AHB_DMA_START field values */
  225045. + HDMI_AHB_DMA_START_START_OFFSET = 0,
  225046. + HDMI_AHB_DMA_START_START_MASK = 0x01,
  225047. +
  225048. +/* HDMI_AHB_DMA_STOP field values */
  225049. + HDMI_AHB_DMA_STOP_STOP_OFFSET = 0,
  225050. + HDMI_AHB_DMA_STOP_STOP_MASK = 0x01,
  225051. +
  225052. +/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */
  225053. + HDMI_AHB_DMA_DONE = 0x80,
  225054. + HDMI_AHB_DMA_RETRY_SPLIT = 0x40,
  225055. + HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20,
  225056. + HDMI_AHB_DMA_ERROR = 0x10,
  225057. + HDMI_AHB_DMA_FIFO_THREMPTY = 0x04,
  225058. + HDMI_AHB_DMA_FIFO_FULL = 0x02,
  225059. + HDMI_AHB_DMA_FIFO_EMPTY = 0x01,
  225060. +
  225061. +/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT, AHB_DMA_BUFFMASK, AHB_DMA_BUFFPOL field values */
  225062. + HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02,
  225063. + HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01,
  225064. +
  225065. +/* MC_CLKDIS field values */
  225066. + HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40,
  225067. + HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20,
  225068. + HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10,
  225069. + HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8,
  225070. + HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4,
  225071. + HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2,
  225072. + HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1,
  225073. +
  225074. +/* MC_SWRSTZ field values */
  225075. + HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02,
  225076. +
  225077. +/* MC_FLOWCTRL field values */
  225078. + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1,
  225079. + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1,
  225080. + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0,
  225081. +
  225082. +/* MC_PHYRSTZ field values */
  225083. + HDMI_MC_PHYRSTZ_ASSERT = 0x0,
  225084. + HDMI_MC_PHYRSTZ_DEASSERT = 0x1,
  225085. +
  225086. +/* MC_HEACPHY_RST field values */
  225087. + HDMI_MC_HEACPHY_RST_ASSERT = 0x1,
  225088. + HDMI_MC_HEACPHY_RST_DEASSERT = 0x0,
  225089. +
  225090. +/* CSC_CFG field values */
  225091. + HDMI_CSC_CFG_INTMODE_MASK = 0x30,
  225092. + HDMI_CSC_CFG_INTMODE_OFFSET = 4,
  225093. + HDMI_CSC_CFG_INTMODE_DISABLE = 0x00,
  225094. + HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10,
  225095. + HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20,
  225096. + HDMI_CSC_CFG_DECMODE_MASK = 0x3,
  225097. + HDMI_CSC_CFG_DECMODE_OFFSET = 0,
  225098. + HDMI_CSC_CFG_DECMODE_DISABLE = 0x0,
  225099. + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1,
  225100. + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2,
  225101. + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3,
  225102. +
  225103. +/* CSC_SCALE field values */
  225104. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0,
  225105. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00,
  225106. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50,
  225107. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60,
  225108. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70,
  225109. + HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03,
  225110. +
  225111. +/* I2CM_OPERATION field values */
  225112. + HDMI_I2CM_OPERATION_WRITE = 0x10,
  225113. + HDMI_I2CM_OPERATION_READ_EXT = 0x2,
  225114. + HDMI_I2CM_OPERATION_READ = 0x1,
  225115. +
  225116. +/* HDMI_I2CM_INT */
  225117. + HDMI_I2CM_INT_DONE_POL = 0x08,
  225118. + HDMI_I2CM_INT_DONE_MASK = 0x04,
  225119. +
  225120. +/* HDMI_I2CM_CTLINT */
  225121. + HDMI_I2CM_CTLINT_NAC_POL = 0x80,
  225122. + HDMI_I2CM_CTLINT_NAC_MASK = 0x40,
  225123. + HDMI_I2CM_CTLINT_ARBITRATION_POL = 0x08,
  225124. + HDMI_I2CM_CTLINT_ARBITRATION_MASK = 0x04,
  225125. +
  225126. +};
  225127. +
  225128. +enum imx_hdmi_type {
  225129. + IMX6DL_HDMI,
  225130. + IMX6Q_HDMI,
  225131. +};
  225132. +
  225133. +/* IOCTL commands */
  225134. +#define HDMI_IOC_MAGIC 'H'
  225135. +
  225136. +#define HDMI_IOC_GET_RESOURCE _IO(HDMI_IOC_MAGIC, 0)
  225137. +#define HDMI_IOC_GET_CPU_TYPE _IO(HDMI_IOC_MAGIC, 1)
  225138. +
  225139. +
  225140. +#endif /* __MXC_HDMI_H__ */
  225141. diff -Nur linux-3.14.15/kernel/cpu.c linux-linaro-stable-mx6/kernel/cpu.c
  225142. --- linux-3.14.15/kernel/cpu.c 2014-07-31 23:51:43.000000000 +0200
  225143. +++ linux-linaro-stable-mx6/kernel/cpu.c 2014-08-20 19:31:54.868906526 +0200
  225144. @@ -722,3 +722,22 @@
  225145. {
  225146. cpumask_copy(to_cpumask(cpu_online_bits), src);
  225147. }
  225148. +
  225149. +static ATOMIC_NOTIFIER_HEAD(idle_notifier);
  225150. +void idle_notifier_register(struct notifier_block *n)
  225151. +{
  225152. + atomic_notifier_chain_register(&idle_notifier, n);
  225153. +}
  225154. +EXPORT_SYMBOL_GPL(idle_notifier_register);
  225155. +
  225156. +void idle_notifier_unregister(struct notifier_block *n)
  225157. +{
  225158. + atomic_notifier_chain_unregister(&idle_notifier, n);
  225159. +}
  225160. +EXPORT_SYMBOL_GPL(idle_notifier_unregister);
  225161. +
  225162. +void idle_notifier_call_chain(unsigned long val)
  225163. +{
  225164. + atomic_notifier_call_chain(&idle_notifier, val, NULL);
  225165. +}
  225166. +EXPORT_SYMBOL_GPL(idle_notifier_call_chain);
  225167. diff -Nur linux-3.14.15/kernel/irq/manage.c linux-linaro-stable-mx6/kernel/irq/manage.c
  225168. --- linux-3.14.15/kernel/irq/manage.c 2014-07-31 23:51:43.000000000 +0200
  225169. +++ linux-linaro-stable-mx6/kernel/irq/manage.c 2014-08-20 19:31:54.880906576 +0200
  225170. @@ -32,24 +32,10 @@
  225171. early_param("threadirqs", setup_forced_irqthreads);
  225172. #endif
  225173. -/**
  225174. - * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
  225175. - * @irq: interrupt number to wait for
  225176. - *
  225177. - * This function waits for any pending IRQ handlers for this interrupt
  225178. - * to complete before returning. If you use this function while
  225179. - * holding a resource the IRQ handler may need you will deadlock.
  225180. - *
  225181. - * This function may be called - with care - from IRQ context.
  225182. - */
  225183. -void synchronize_irq(unsigned int irq)
  225184. +static void __synchronize_hardirq(struct irq_desc *desc)
  225185. {
  225186. - struct irq_desc *desc = irq_to_desc(irq);
  225187. bool inprogress;
  225188. - if (!desc)
  225189. - return;
  225190. -
  225191. do {
  225192. unsigned long flags;
  225193. @@ -67,12 +53,56 @@
  225194. /* Oops, that failed? */
  225195. } while (inprogress);
  225196. +}
  225197. +
  225198. +/**
  225199. + * synchronize_hardirq - wait for pending hard IRQ handlers (on other CPUs)
  225200. + * @irq: interrupt number to wait for
  225201. + *
  225202. + * This function waits for any pending hard IRQ handlers for this
  225203. + * interrupt to complete before returning. If you use this
  225204. + * function while holding a resource the IRQ handler may need you
  225205. + * will deadlock. It does not take associated threaded handlers
  225206. + * into account.
  225207. + *
  225208. + * Do not use this for shutdown scenarios where you must be sure
  225209. + * that all parts (hardirq and threaded handler) have completed.
  225210. + *
  225211. + * This function may be called - with care - from IRQ context.
  225212. + */
  225213. +void synchronize_hardirq(unsigned int irq)
  225214. +{
  225215. + struct irq_desc *desc = irq_to_desc(irq);
  225216. - /*
  225217. - * We made sure that no hardirq handler is running. Now verify
  225218. - * that no threaded handlers are active.
  225219. - */
  225220. - wait_event(desc->wait_for_threads, !atomic_read(&desc->threads_active));
  225221. + if (desc)
  225222. + __synchronize_hardirq(desc);
  225223. +}
  225224. +EXPORT_SYMBOL(synchronize_hardirq);
  225225. +
  225226. +/**
  225227. + * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
  225228. + * @irq: interrupt number to wait for
  225229. + *
  225230. + * This function waits for any pending IRQ handlers for this interrupt
  225231. + * to complete before returning. If you use this function while
  225232. + * holding a resource the IRQ handler may need you will deadlock.
  225233. + *
  225234. + * This function may be called - with care - from IRQ context.
  225235. + */
  225236. +void synchronize_irq(unsigned int irq)
  225237. +{
  225238. + struct irq_desc *desc = irq_to_desc(irq);
  225239. +
  225240. + if (desc) {
  225241. + __synchronize_hardirq(desc);
  225242. + /*
  225243. + * We made sure that no hardirq handler is
  225244. + * running. Now verify that no threaded handlers are
  225245. + * active.
  225246. + */
  225247. + wait_event(desc->wait_for_threads,
  225248. + !atomic_read(&desc->threads_active));
  225249. + }
  225250. }
  225251. EXPORT_SYMBOL(synchronize_irq);
  225252. diff -Nur linux-3.14.15/kernel/relay.c linux-linaro-stable-mx6/kernel/relay.c
  225253. --- linux-3.14.15/kernel/relay.c 2014-07-31 23:51:43.000000000 +0200
  225254. +++ linux-linaro-stable-mx6/kernel/relay.c 2014-08-20 19:31:54.992907058 +0200
  225255. @@ -227,7 +227,7 @@
  225256. * relay_remove_buf - remove a channel buffer
  225257. * @kref: target kernel reference that contains the relay buffer
  225258. *
  225259. - * Removes the file from the fileystem, which also frees the
  225260. + * Removes the file from the filesystem, which also frees the
  225261. * rchan_buf_struct and the channel buffer. Should only be called from
  225262. * kref_put().
  225263. */
  225264. diff -Nur linux-3.14.15/kernel/signal.c linux-linaro-stable-mx6/kernel/signal.c
  225265. --- linux-3.14.15/kernel/signal.c 2014-07-31 23:51:43.000000000 +0200
  225266. +++ linux-linaro-stable-mx6/kernel/signal.c 2014-08-20 19:31:55.012907143 +0200
  225267. @@ -2382,7 +2382,7 @@
  225268. * @regs: user register state
  225269. * @stepping: nonzero if debugger single-step or block-step in use
  225270. *
  225271. - * This function should be called when a signal has succesfully been
  225272. + * This function should be called when a signal has successfully been
  225273. * delivered. It updates the blocked signals accordingly (@ka->sa.sa_mask
  225274. * is always blocked, and the signal itself is blocked unless %SA_NODEFER
  225275. * is set in @ka->sa.sa_flags. Tracing is notified.
  225276. diff -Nur linux-3.14.15/kernel/trace/trace.c linux-linaro-stable-mx6/kernel/trace/trace.c
  225277. --- linux-3.14.15/kernel/trace/trace.c 2014-07-31 23:51:43.000000000 +0200
  225278. +++ linux-linaro-stable-mx6/kernel/trace/trace.c 2014-08-20 19:31:55.032907228 +0200
  225279. @@ -811,7 +811,7 @@
  225280. { trace_clock_local, "local", 1 },
  225281. { trace_clock_global, "global", 1 },
  225282. { trace_clock_counter, "counter", 0 },
  225283. - { trace_clock_jiffies, "uptime", 0 },
  225284. + { trace_clock_jiffies, "uptime", 1 },
  225285. { trace_clock, "perf", 1 },
  225286. ARCH_TRACE_CLOCKS
  225287. };
  225288. diff -Nur linux-3.14.15/kernel/trace/trace_clock.c linux-linaro-stable-mx6/kernel/trace/trace_clock.c
  225289. --- linux-3.14.15/kernel/trace/trace_clock.c 2014-07-31 23:51:43.000000000 +0200
  225290. +++ linux-linaro-stable-mx6/kernel/trace/trace_clock.c 2014-08-20 19:24:07.766906502 +0200
  225291. @@ -59,14 +59,13 @@
  225292. /*
  225293. * trace_jiffy_clock(): Simply use jiffies as a clock counter.
  225294. - * Note that this use of jiffies_64 is not completely safe on
  225295. - * 32-bit systems. But the window is tiny, and the effect if
  225296. - * we are affected is that we will have an obviously bogus
  225297. - * timestamp on a trace event - i.e. not life threatening.
  225298. */
  225299. u64 notrace trace_clock_jiffies(void)
  225300. {
  225301. - return jiffies_64_to_clock_t(jiffies_64 - INITIAL_JIFFIES);
  225302. + u64 jiffy = jiffies - INITIAL_JIFFIES;
  225303. +
  225304. + /* Return nsecs */
  225305. + return (u64)jiffies_to_usecs(jiffy) * 1000ULL;
  225306. }
  225307. /*
  225308. diff -Nur linux-3.14.15/linaro/configs/android.conf linux-linaro-stable-mx6/linaro/configs/android.conf
  225309. --- linux-3.14.15/linaro/configs/android.conf 1970-01-01 01:00:00.000000000 +0100
  225310. +++ linux-linaro-stable-mx6/linaro/configs/android.conf 2014-08-20 19:31:55.176907848 +0200
  225311. @@ -0,0 +1,42 @@
  225312. +CONFIG_IPV6=y
  225313. +# CONFIG_IPV6_SIT is not set
  225314. +CONFIG_PANIC_TIMEOUT=0
  225315. +CONFIG_HAS_WAKELOCK=y
  225316. +CONFIG_WAKELOCK=y
  225317. +CONFIG_BLK_DEV_LOOP=y
  225318. +CONFIG_DM_CRYPT=y
  225319. +CONFIG_POWER_SUPPLY=y
  225320. +CONFIG_ANDROID_PARANOID_NETWORK=y
  225321. +CONFIG_NET_ACTIVITY_STATS=y
  225322. +CONFIG_INPUT_MISC=y
  225323. +CONFIG_INPUT_UINPUT=y
  225324. +CONFIG_INPUT_GPIO=y
  225325. +CONFIG_USB_G_ANDROID=y
  225326. +CONFIG_SWITCH=y
  225327. +CONFIG_STAGING=y
  225328. +CONFIG_ANDROID=y
  225329. +CONFIG_ANDROID_BINDER_IPC=y
  225330. +CONFIG_ASHMEM=y
  225331. +CONFIG_ANDROID_LOGGER=y
  225332. +CONFIG_ANDROID_TIMED_OUTPUT=y
  225333. +CONFIG_ANDROID_TIMED_GPIO=y
  225334. +CONFIG_ANDROID_LOW_MEMORY_KILLER=y
  225335. +CONFIG_ANDROID_INTF_ALARM_DEV=y
  225336. +CONFIG_CRYPTO_TWOFISH=y
  225337. +CONFIG_BLK_DEV_RAM=y
  225338. +CONFIG_BLK_DEV_RAM_COUNT=16
  225339. +CONFIG_BLK_DEV_RAM_SIZE=16384
  225340. +CONFIG_FUSE_FS=y
  225341. +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
  225342. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  225343. +CONFIG_ION=y
  225344. +CONFIG_SYNC=y
  225345. +CONFIG_SW_SYNC=y
  225346. +CONFIG_SW_SYNC_USER=y
  225347. +CONFIG_ION_TEST=y
  225348. +CONFIG_ION_DUMMY=y
  225349. +CONFIG_ADF=y
  225350. +CONFIG_ADF_FBDEV=y
  225351. +CONFIG_ADF_MEMBLOCK=y
  225352. +CONFIG_DMA_SHARED_BUFFER=y
  225353. +CONFIG_TUN=y
  225354. diff -Nur linux-3.14.15/linaro/configs/arndale.conf linux-linaro-stable-mx6/linaro/configs/arndale.conf
  225355. --- linux-3.14.15/linaro/configs/arndale.conf 1970-01-01 01:00:00.000000000 +0100
  225356. +++ linux-linaro-stable-mx6/linaro/configs/arndale.conf 2014-08-20 19:24:07.902907083 +0200
  225357. @@ -0,0 +1,66 @@
  225358. +CONFIG_KALLSYMS_ALL=y
  225359. +CONFIG_PARTITION_ADVANCED=y
  225360. +CONFIG_BSD_DISKLABEL=y
  225361. +CONFIG_SOLARIS_X86_PARTITION=y
  225362. +CONFIG_ARCH_EXYNOS=y
  225363. +CONFIG_S3C_LOWLEVEL_UART_PORT=2
  225364. +CONFIG_ARCH_EXYNOS5=y
  225365. +# CONFIG_EXYNOS_ATAGS is not set
  225366. +CONFIG_MACH_EXYNOS4_DT=y
  225367. +CONFIG_VMSPLIT_2G=y
  225368. +CONFIG_NR_CPUS=2
  225369. +CONFIG_HIGHMEM=y
  225370. +# CONFIG_COMPACTION is not set
  225371. +CONFIG_ARM_APPENDED_DTB=y
  225372. +CONFIG_ARM_ATAG_DTB_COMPAT=y
  225373. +CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init= mem=256M"
  225374. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  225375. +CONFIG_VFP=y
  225376. +CONFIG_NEON=y
  225377. +CONFIG_PM_RUNTIME=y
  225378. +CONFIG_BLK_DEV_LOOP=y
  225379. +CONFIG_BLK_DEV_SD=y
  225380. +CONFIG_CHR_DEV_SG=y
  225381. +CONFIG_ATA=y
  225382. +CONFIG_SATA_AHCI_PLATFORM=y
  225383. +CONFIG_SATA_EXYNOS=y
  225384. +CONFIG_AX88796=y
  225385. +CONFIG_AX88796_93CX6=y
  225386. +CONFIG_INPUT_EVDEV=y
  225387. +CONFIG_KEYBOARD_GPIO=y
  225388. +CONFIG_INPUT_TOUCHSCREEN=y
  225389. +CONFIG_SERIAL_8250=y
  225390. +CONFIG_SERIAL_SAMSUNG=y
  225391. +CONFIG_SERIAL_SAMSUNG_CONSOLE=y
  225392. +CONFIG_HW_RANDOM=y
  225393. +CONFIG_I2C=y
  225394. +CONFIG_I2C_S3C2410=y
  225395. +CONFIG_THERMAL=y
  225396. +CONFIG_CPU_THERMAL=y
  225397. +CONFIG_EXYNOS_THERMAL=y
  225398. +CONFIG_MFD_SEC_CORE=y
  225399. +CONFIG_REGULATOR=y
  225400. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  225401. +CONFIG_REGULATOR_S5M8767=y
  225402. +CONFIG_DRM=y
  225403. +CONFIG_DRM_LOAD_EDID_FIRMWARE=y
  225404. +CONFIG_DRM_EXYNOS=y
  225405. +CONFIG_DRM_EXYNOS_DMABUF=y
  225406. +CONFIG_DRM_EXYNOS_HDMI=y
  225407. +CONFIG_FRAMEBUFFER_CONSOLE=y
  225408. +CONFIG_LOGO=y
  225409. +CONFIG_MMC=y
  225410. +CONFIG_MMC_UNSAFE_RESUME=y
  225411. +CONFIG_MMC_DW=y
  225412. +CONFIG_MMC_DW_IDMAC=y
  225413. +CONFIG_MMC_DW_EXYNOS=y
  225414. +CONFIG_RTC_CLASS=y
  225415. +CONFIG_RTC_DRV_S3C=y
  225416. +CONFIG_DEBUG_KERNEL=y
  225417. +CONFIG_DETECT_HUNG_TASK=y
  225418. +CONFIG_DEBUG_RT_MUTEXES=y
  225419. +CONFIG_DEBUG_SPINLOCK=y
  225420. +CONFIG_DEBUG_INFO=y
  225421. +CONFIG_RCU_CPU_STALL_TIMEOUT=60
  225422. +CONFIG_DEBUG_USER=y
  225423. +CONFIG_TUN=y
  225424. diff -Nur linux-3.14.15/linaro/configs/bigendian.conf linux-linaro-stable-mx6/linaro/configs/bigendian.conf
  225425. --- linux-3.14.15/linaro/configs/bigendian.conf 1970-01-01 01:00:00.000000000 +0100
  225426. +++ linux-linaro-stable-mx6/linaro/configs/bigendian.conf 2014-08-20 19:31:55.180907865 +0200
  225427. @@ -0,0 +1,4 @@
  225428. +CONFIG_CPU_BIG_ENDIAN=y
  225429. +CONFIG_CPU_ENDIAN_BE8=y
  225430. +# CONFIG_VIRTUALIZATION is not set
  225431. +# CONFIG_MMC_DW_IDMAC is not set
  225432. diff -Nur linux-3.14.15/linaro/configs/big-LITTLE-IKS.conf linux-linaro-stable-mx6/linaro/configs/big-LITTLE-IKS.conf
  225433. --- linux-3.14.15/linaro/configs/big-LITTLE-IKS.conf 1970-01-01 01:00:00.000000000 +0100
  225434. +++ linux-linaro-stable-mx6/linaro/configs/big-LITTLE-IKS.conf 2014-08-20 19:24:07.902907083 +0200
  225435. @@ -0,0 +1,5 @@
  225436. +CONFIG_BIG_LITTLE=y
  225437. +CONFIG_BL_SWITCHER=y
  225438. +CONFIG_ARM_DT_BL_CPUFREQ=y
  225439. +CONFIG_ARM_VEXPRESS_BL_CPUFREQ=y
  225440. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  225441. diff -Nur linux-3.14.15/linaro/configs/debug.conf linux-linaro-stable-mx6/linaro/configs/debug.conf
  225442. --- linux-3.14.15/linaro/configs/debug.conf 1970-01-01 01:00:00.000000000 +0100
  225443. +++ linux-linaro-stable-mx6/linaro/configs/debug.conf 2014-08-20 19:24:07.902907083 +0200
  225444. @@ -0,0 +1 @@
  225445. +CONFIG_PROVE_LOCKING=y
  225446. diff -Nur linux-3.14.15/linaro/configs/distribution.conf linux-linaro-stable-mx6/linaro/configs/distribution.conf
  225447. --- linux-3.14.15/linaro/configs/distribution.conf 1970-01-01 01:00:00.000000000 +0100
  225448. +++ linux-linaro-stable-mx6/linaro/configs/distribution.conf 2014-08-20 19:31:55.180907865 +0200
  225449. @@ -0,0 +1,49 @@
  225450. +# CONFIG_LOCALVERSION_AUTO is not set
  225451. +CONFIG_CGROUPS=y
  225452. +# CONFIG_COMPAT_BRK is not set
  225453. +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
  225454. +CONFIG_SECCOMP=y
  225455. +CONFIG_CC_STACKPROTECTOR=y
  225456. +CONFIG_SYN_COOKIES=y
  225457. +CONFIG_IPV6=y
  225458. +CONFIG_NETLABEL=y
  225459. +CONFIG_BRIDGE_NETFILTER=y
  225460. +CONFIG_NF_CONNTRACK=m
  225461. +CONFIG_NETFILTER_XT_CONNMARK=m
  225462. +CONFIG_NETFILTER_XT_MARK=m
  225463. +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
  225464. +CONFIG_NF_CONNTRACK_IPV4=m
  225465. +CONFIG_NF_NAT_IPV4=m
  225466. +CONFIG_IP_NF_IPTABLES=m
  225467. +CONFIG_IP_NF_FILTER=m
  225468. +CONFIG_IP_NF_MANGLE=m
  225469. +CONFIG_NF_CONNTRACK_IPV6=m
  225470. +CONFIG_NF_NAT_IPV6=m
  225471. +CONFIG_IP6_NF_IPTABLES=m
  225472. +CONFIG_IP6_NF_FILTER=m
  225473. +CONFIG_IP6_NF_MANGLE=m
  225474. +CONFIG_BRIDGE_NF_EBTABLES=m
  225475. +CONFIG_BRIDGE_EBT_MARK_T=m
  225476. +CONFIG_BRIDGE=m
  225477. +CONFIG_TUN=y
  225478. +CONFIG_DEVTMPFS=y
  225479. +CONFIG_DEVTMPFS_MOUNT=y
  225480. +CONFIG_BLK_DEV_RAM=y
  225481. +CONFIG_BLK_DEV_RAM_SIZE=65536
  225482. +CONFIG_INPUT_MISC=y
  225483. +CONFIG_INPUT_UINPUT=y
  225484. +# CONFIG_DEVKMEM is not set
  225485. +CONFIG_FRAMEBUFFER_CONSOLE=y
  225486. +CONFIG_AUTOFS4_FS=y
  225487. +CONFIG_TMPFS_POSIX_ACL=y
  225488. +CONFIG_STRICT_DEVMEM=y
  225489. +CONFIG_SECURITY=y
  225490. +CONFIG_LSM_MMAP_MIN_ADDR=0
  225491. +CONFIG_SECURITY_SELINUX=y
  225492. +CONFIG_SECURITY_SMACK=y
  225493. +CONFIG_SECURITY_APPARMOR=y
  225494. +CONFIG_DEFAULT_SECURITY_APPARMOR=y
  225495. +CONFIG_HUGETLBFS=y
  225496. +CONFIG_HUGETLB_PAGE=y
  225497. +CONFIG_TRANSPARENT_HUGEPAGE=y
  225498. +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
  225499. diff -Nur linux-3.14.15/linaro/configs/highbank.conf linux-linaro-stable-mx6/linaro/configs/highbank.conf
  225500. --- linux-3.14.15/linaro/configs/highbank.conf 1970-01-01 01:00:00.000000000 +0100
  225501. +++ linux-linaro-stable-mx6/linaro/configs/highbank.conf 2014-08-20 19:24:07.902907083 +0200
  225502. @@ -0,0 +1,40 @@
  225503. +CONFIG_EXPERIMENTAL=y
  225504. +CONFIG_NO_HZ=y
  225505. +CONFIG_HIGH_RES_TIMERS=y
  225506. +CONFIG_ARCH_HIGHBANK=y
  225507. +CONFIG_ARM_ERRATA_754322=y
  225508. +CONFIG_SMP=y
  225509. +CONFIG_SCHED_MC=y
  225510. +CONFIG_AEABI=y
  225511. +CONFIG_CMDLINE="console=ttyAMA0"
  225512. +CONFIG_CPU_IDLE=y
  225513. +CONFIG_VFP=y
  225514. +CONFIG_NEON=y
  225515. +CONFIG_NET=y
  225516. +CONFIG_SCSI=y
  225517. +CONFIG_BLK_DEV_SD=y
  225518. +CONFIG_ATA=y
  225519. +CONFIG_SATA_AHCI_PLATFORM=y
  225520. +CONFIG_SATA_HIGHBANK=y
  225521. +CONFIG_NETDEVICES=y
  225522. +CONFIG_NET_CALXEDA_XGMAC=y
  225523. +CONFIG_SERIAL_AMBA_PL011=y
  225524. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  225525. +CONFIG_IPMI_HANDLER=y
  225526. +CONFIG_IPMI_SI=y
  225527. +CONFIG_I2C=y
  225528. +CONFIG_I2C_DESIGNWARE_PLATFORM=y
  225529. +CONFIG_SPI=y
  225530. +CONFIG_SPI_PL022=y
  225531. +CONFIG_GPIO_PL061=y
  225532. +CONFIG_MMC=y
  225533. +CONFIG_MMC_SDHCI=y
  225534. +CONFIG_MMC_SDHCI_PLTFM=y
  225535. +CONFIG_EDAC=y
  225536. +CONFIG_EDAC_MM_EDAC=y
  225537. +CONFIG_EDAC_HIGHBANK_MC=y
  225538. +CONFIG_EDAC_HIGHBANK_L2=y
  225539. +CONFIG_RTC_CLASS=y
  225540. +CONFIG_RTC_DRV_PL031=y
  225541. +CONFIG_DMADEVICES=y
  225542. +CONFIG_PL330_DMA=y
  225543. diff -Nur linux-3.14.15/linaro/configs/kvm-guest.conf linux-linaro-stable-mx6/linaro/configs/kvm-guest.conf
  225544. --- linux-3.14.15/linaro/configs/kvm-guest.conf 1970-01-01 01:00:00.000000000 +0100
  225545. +++ linux-linaro-stable-mx6/linaro/configs/kvm-guest.conf 2014-08-20 19:24:07.906907101 +0200
  225546. @@ -0,0 +1,11 @@
  225547. +CONFIG_BALLOON_COMPACTION=y
  225548. +CONFIG_VIRTIO_BLK=y
  225549. +CONFIG_VIRTIO_NET=y
  225550. +CONFIG_HVC_DRIVER=y
  225551. +CONFIG_VIRTIO_CONSOLE=y
  225552. +CONFIG_VIRTIO=y
  225553. +CONFIG_VIRTIO_BALLOON=y
  225554. +CONFIG_VIRTIO_MMIO=y
  225555. +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
  225556. +CONFIG_VIRTUALIZATION=y
  225557. +# CONFIG_THUMB2_KERNEL is not set
  225558. diff -Nur linux-3.14.15/linaro/configs/kvm-host.conf linux-linaro-stable-mx6/linaro/configs/kvm-host.conf
  225559. --- linux-3.14.15/linaro/configs/kvm-host.conf 1970-01-01 01:00:00.000000000 +0100
  225560. +++ linux-linaro-stable-mx6/linaro/configs/kvm-host.conf 2014-08-20 19:24:07.906907101 +0200
  225561. @@ -0,0 +1,11 @@
  225562. +CONFIG_VIRTUALIZATION=y
  225563. +CONFIG_ARM_LPAE=y
  225564. +CONFIG_ARM_VIRT_EXT=y
  225565. +CONFIG_HAVE_KVM_IRQCHIP=y
  225566. +CONFIG_KVM_ARM_HOST=y
  225567. +CONFIG_KVM_ARM_MAX_VCPUS=4
  225568. +CONFIG_KVM_ARM_TIMER=y
  225569. +CONFIG_KVM_ARM_VGIC=y
  225570. +CONFIG_KVM_MMIO=y
  225571. +CONFIG_KVM=y
  225572. +CONFIG_BLK_DEV_NBD=m
  225573. diff -Nur linux-3.14.15/linaro/configs/linaro-base.conf linux-linaro-stable-mx6/linaro/configs/linaro-base.conf
  225574. --- linux-3.14.15/linaro/configs/linaro-base.conf 1970-01-01 01:00:00.000000000 +0100
  225575. +++ linux-linaro-stable-mx6/linaro/configs/linaro-base.conf 2014-08-20 19:31:55.180907865 +0200
  225576. @@ -0,0 +1,115 @@
  225577. +CONFIG_SYSVIPC=y
  225578. +CONFIG_POSIX_MQUEUE=y
  225579. +CONFIG_BSD_PROCESS_ACCT=y
  225580. +CONFIG_IKCONFIG=y
  225581. +CONFIG_IKCONFIG_PROC=y
  225582. +CONFIG_LOG_BUF_SHIFT=16
  225583. +CONFIG_BLK_DEV_INITRD=y
  225584. +CONFIG_EMBEDDED=y
  225585. +CONFIG_HOTPLUG=y
  225586. +CONFIG_PERF_EVENTS=y
  225587. +CONFIG_SLAB=y
  225588. +CONFIG_PROFILING=y
  225589. +CONFIG_OPROFILE=y
  225590. +CONFIG_MODULES=y
  225591. +CONFIG_MODULE_UNLOAD=y
  225592. +CONFIG_NO_HZ=y
  225593. +CONFIG_HIGH_RES_TIMERS=y
  225594. +CONFIG_SMP=y
  225595. +CONFIG_SCHED_MC=y
  225596. +CONFIG_SCHED_SMT=y
  225597. +CONFIG_THUMB2_KERNEL=y
  225598. +CONFIG_AEABI=y
  225599. +# CONFIG_OABI_COMPAT is not set
  225600. +CONFIG_CPU_FREQ=y
  225601. +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
  225602. +CONFIG_CPU_IDLE=y
  225603. +CONFIG_BINFMT_MISC=y
  225604. +CONFIG_MD=y
  225605. +CONFIG_BLK_DEV_DM=y
  225606. +CONFIG_NET=y
  225607. +CONFIG_PACKET=y
  225608. +CONFIG_UNIX=y
  225609. +CONFIG_XFRM_USER=y
  225610. +CONFIG_NET_KEY=y
  225611. +CONFIG_NET_KEY_MIGRATE=y
  225612. +CONFIG_INET=y
  225613. +CONFIG_IP_MULTICAST=y
  225614. +CONFIG_IP_PNP=y
  225615. +CONFIG_IP_PNP_DHCP=y
  225616. +CONFIG_IP_PNP_BOOTP=y
  225617. +CONFIG_IP_PNP_RARP=y
  225618. +# CONFIG_INET_LRO is not set
  225619. +CONFIG_NETFILTER=y
  225620. +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
  225621. +CONFIG_CONNECTOR=y
  225622. +CONFIG_MTD=y
  225623. +CONFIG_MTD_CMDLINE_PARTS=y
  225624. +CONFIG_MTD_BLOCK=y
  225625. +CONFIG_MTD_OOPS=y
  225626. +CONFIG_MTD_CFI=y
  225627. +CONFIG_MTD_CFI_INTELEXT=y
  225628. +CONFIG_MTD_NAND=y
  225629. +CONFIG_NETDEVICES=y
  225630. +CONFIG_EXT2_FS=y
  225631. +CONFIG_EXT3_FS=y
  225632. +CONFIG_EXT4_FS=y
  225633. +CONFIG_BTRFS_FS=y
  225634. +CONFIG_QUOTA=y
  225635. +CONFIG_QFMT_V2=y
  225636. +CONFIG_MSDOS_FS=y
  225637. +CONFIG_VFAT_FS=y
  225638. +CONFIG_TMPFS=y
  225639. +CONFIG_ECRYPT_FS=y
  225640. +CONFIG_JFFS2_FS=y
  225641. +CONFIG_JFFS2_SUMMARY=y
  225642. +CONFIG_JFFS2_FS_XATTR=y
  225643. +CONFIG_JFFS2_COMPRESSION_OPTIONS=y
  225644. +CONFIG_JFFS2_LZO=y
  225645. +CONFIG_JFFS2_RUBIN=y
  225646. +CONFIG_CRAMFS=y
  225647. +CONFIG_NETWORK_FILESYSTEMS=y
  225648. +CONFIG_NFS_FS=y
  225649. +# CONFIG_NFS_V2 is not set
  225650. +CONFIG_NFS_V3=y
  225651. +CONFIG_NFS_V3_ACL=y
  225652. +CONFIG_NFS_V4=y
  225653. +CONFIG_ROOT_NFS=y
  225654. +CONFIG_NLS_CODEPAGE_437=y
  225655. +CONFIG_NLS_ISO8859_1=y
  225656. +CONFIG_PRINTK_TIME=y
  225657. +CONFIG_MAGIC_SYSRQ=y
  225658. +CONFIG_DEBUG_FS=y
  225659. +CONFIG_SCHEDSTATS=y
  225660. +CONFIG_TIMER_STATS=y
  225661. +CONFIG_KEYS=y
  225662. +CONFIG_CRYPTO_MICHAEL_MIC=y
  225663. +CONFIG_CRC_CCITT=y
  225664. +CONFIG_CRC_T10DIF=y
  225665. +CONFIG_CRC_ITU_T=y
  225666. +CONFIG_CRC7=y
  225667. +CONFIG_HW_PERF_EVENTS=y
  225668. +CONFIG_FUNCTION_TRACER=y
  225669. +CONFIG_ENABLE_DEFAULT_TRACERS=y
  225670. +CONFIG_PROC_DEVICETREE=y
  225671. +CONFIG_JUMP_LABEL=y
  225672. +CONFIG_STRICT_DEVMEM=y
  225673. +CONFIG_KGDB=y
  225674. +CONFIG_KGDB_TESTS=y
  225675. +CONFIG_OF_IDLE_STATES=y
  225676. +CONFIG_FTRACE=y
  225677. +CONFIG_FUNCTION_TRACER=y
  225678. +CONFIG_FTRACE_SYSCALLS=y
  225679. +CONFIG_STACK_TRACER=y
  225680. +CONFIG_FUNCTION_PROFILER=y
  225681. +CONFIG_MAILBOX=y
  225682. +CONFIG_AUDIT=y
  225683. +CONFIG_NF_CONNTRACK_SECMARK=y
  225684. +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
  225685. +CONFIG_NETFILTER_XT_TARGET_SECMARK=y
  225686. +CONFIG_IP_NF_SECURITY=y
  225687. +CONFIG_SECURITY=y
  225688. +CONFIG_SECURITY_NETWORK=y
  225689. +CONFIG_LSM_MMAP_MIN_ADDR=4096
  225690. +CONFIG_SECURITY_SELINUX=y
  225691. +CONFIG_EXT4_FS_SECURITY=y
  225692. diff -Nur linux-3.14.15/linaro/configs/omap4.conf linux-linaro-stable-mx6/linaro/configs/omap4.conf
  225693. --- linux-3.14.15/linaro/configs/omap4.conf 1970-01-01 01:00:00.000000000 +0100
  225694. +++ linux-linaro-stable-mx6/linaro/configs/omap4.conf 2014-08-20 19:31:55.180907865 +0200
  225695. @@ -0,0 +1,196 @@
  225696. +CONFIG_EXPERT=y
  225697. +CONFIG_KPROBES=y
  225698. +CONFIG_MODULE_FORCE_LOAD=y
  225699. +CONFIG_MODULE_FORCE_UNLOAD=y
  225700. +CONFIG_MODVERSIONS=y
  225701. +CONFIG_MODULE_SRCVERSION_ALL=y
  225702. +# CONFIG_BLK_DEV_BSG is not set
  225703. +CONFIG_PARTITION_ADVANCED=y
  225704. +CONFIG_GPIO_PCA953X=y
  225705. +CONFIG_OMAP_RESET_CLOCKS=y
  225706. +CONFIG_OMAP_MUX_DEBUG=y
  225707. +CONFIG_ARCH_OMAP3=y
  225708. +CONFIG_ARCH_OMAP4=y
  225709. +CONFIG_ARCH_OMAP2PLUS=y
  225710. +CONFIG_SOC_OMAP5=y
  225711. +# CONFIG_ARCH_OMAP2 is not set
  225712. +CONFIG_ARCH_VEXPRESS_CA9X4=y
  225713. +CONFIG_ARM_THUMBEE=y
  225714. +CONFIG_ARM_ERRATA_411920=y
  225715. +CONFIG_NR_CPUS=2
  225716. +CONFIG_ZBOOT_ROM_TEXT=0x0
  225717. +CONFIG_ZBOOT_ROM_BSS=0x0
  225718. +CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
  225719. +CONFIG_KEXEC=y
  225720. +CONFIG_PM_DEBUG=y
  225721. +CONFIG_CAN=m
  225722. +CONFIG_CAN_C_CAN=m
  225723. +CONFIG_CAN_C_CAN_PLATFORM=m
  225724. +CONFIG_BT=m
  225725. +CONFIG_BT_HCIUART=m
  225726. +CONFIG_BT_HCIUART_H4=y
  225727. +CONFIG_BT_HCIUART_BCSP=y
  225728. +CONFIG_BT_HCIUART_LL=y
  225729. +CONFIG_BT_HCIBCM203X=m
  225730. +CONFIG_BT_HCIBPA10X=m
  225731. +CONFIG_CFG80211=m
  225732. +CONFIG_MAC80211=m
  225733. +CONFIG_MAC80211_RC_PID=y
  225734. +CONFIG_MAC80211_RC_DEFAULT_PID=y
  225735. +CONFIG_CMA=y
  225736. +CONFIG_MTD_NAND_OMAP2=y
  225737. +CONFIG_MTD_ONENAND=y
  225738. +CONFIG_MTD_ONENAND_VERIFY_WRITE=y
  225739. +CONFIG_MTD_ONENAND_OMAP2=y
  225740. +CONFIG_MTD_UBI=y
  225741. +CONFIG_BLK_DEV_LOOP=y
  225742. +CONFIG_BLK_DEV_RAM_SIZE=16384
  225743. +CONFIG_SENSORS_TSL2550=m
  225744. +CONFIG_SENSORS_LIS3_I2C=m
  225745. +CONFIG_SCSI=y
  225746. +CONFIG_BLK_DEV_SD=y
  225747. +CONFIG_SCSI_MULTI_LUN=y
  225748. +CONFIG_SCSI_SCAN_ASYNC=y
  225749. +CONFIG_KS8851=y
  225750. +CONFIG_KS8851_MLL=y
  225751. +CONFIG_SMC91X=y
  225752. +CONFIG_SMSC911X=y
  225753. +CONFIG_TI_CPSW=y
  225754. +CONFIG_SMSC_PHY=y
  225755. +CONFIG_USB_USBNET=y
  225756. +CONFIG_USB_NET_SMSC95XX=y
  225757. +CONFIG_USB_ALI_M5632=y
  225758. +CONFIG_USB_AN2720=y
  225759. +CONFIG_USB_EPSON2888=y
  225760. +CONFIG_USB_KC2190=y
  225761. +CONFIG_LIBERTAS=m
  225762. +CONFIG_LIBERTAS_USB=m
  225763. +CONFIG_LIBERTAS_SDIO=m
  225764. +CONFIG_LIBERTAS_DEBUG=y
  225765. +CONFIG_INPUT_JOYDEV=y
  225766. +CONFIG_INPUT_EVDEV=y
  225767. +CONFIG_KEYBOARD_GPIO=y
  225768. +CONFIG_KEYBOARD_MATRIX=m
  225769. +CONFIG_KEYBOARD_TWL4030=y
  225770. +CONFIG_INPUT_TOUCHSCREEN=y
  225771. +CONFIG_TOUCHSCREEN_ADS7846=y
  225772. +CONFIG_INPUT_TWL4030_PWRBUTTON=y
  225773. +CONFIG_VT_HW_CONSOLE_BINDING=y
  225774. +# CONFIG_LEGACY_PTYS is not set
  225775. +CONFIG_SERIAL_8250=y
  225776. +CONFIG_SERIAL_8250_CONSOLE=y
  225777. +CONFIG_SERIAL_8250_NR_UARTS=32
  225778. +CONFIG_SERIAL_8250_EXTENDED=y
  225779. +CONFIG_SERIAL_8250_MANY_PORTS=y
  225780. +CONFIG_SERIAL_8250_SHARE_IRQ=y
  225781. +CONFIG_SERIAL_8250_DETECT_IRQ=y
  225782. +CONFIG_SERIAL_8250_RSA=y
  225783. +CONFIG_SERIAL_AMBA_PL011=y
  225784. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  225785. +CONFIG_SERIAL_OMAP=y
  225786. +CONFIG_SERIAL_OMAP_CONSOLE=y
  225787. +CONFIG_HW_RANDOM=y
  225788. +CONFIG_I2C_CHARDEV=y
  225789. +CONFIG_SPI=y
  225790. +CONFIG_SPI_OMAP24XX=y
  225791. +CONFIG_PINCTRL_SINGLE=y
  225792. +CONFIG_DEBUG_GPIO=y
  225793. +CONFIG_GPIO_SYSFS=y
  225794. +CONFIG_GPIO_TWL4030=y
  225795. +CONFIG_W1=y
  225796. +CONFIG_SENSORS_LM75=m
  225797. +CONFIG_WATCHDOG=y
  225798. +CONFIG_OMAP_WATCHDOG=y
  225799. +CONFIG_TWL4030_WATCHDOG=y
  225800. +CONFIG_MFD_TPS65217=y
  225801. +CONFIG_MFD_TPS65910=y
  225802. +CONFIG_TWL6040_CORE=y
  225803. +CONFIG_REGULATOR_TPS65023=y
  225804. +CONFIG_REGULATOR_TPS6507X=y
  225805. +CONFIG_REGULATOR_TPS65217=y
  225806. +CONFIG_REGULATOR_TPS65910=y
  225807. +CONFIG_REGULATOR_TWL4030=y
  225808. +CONFIG_FB=y
  225809. +CONFIG_FIRMWARE_EDID=y
  225810. +CONFIG_FB_MODE_HELPERS=y
  225811. +CONFIG_FB_TILEBLITTING=y
  225812. +CONFIG_OMAP2_DSS=m
  225813. +CONFIG_OMAP2_DSS_RFBI=y
  225814. +CONFIG_OMAP2_DSS_SDI=y
  225815. +CONFIG_OMAP2_DSS_DSI=y
  225816. +CONFIG_FB_OMAP2=m
  225817. +CONFIG_PANEL_GENERIC_DPI=m
  225818. +CONFIG_PANEL_TFP410=m
  225819. +CONFIG_PANEL_SHARP_LS037V7DW01=m
  225820. +CONFIG_PANEL_NEC_NL8048HL11_01B=m
  225821. +CONFIG_PANEL_TAAL=m
  225822. +CONFIG_PANEL_TPO_TD043MTEA1=m
  225823. +CONFIG_PANEL_ACX565AKM=m
  225824. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  225825. +CONFIG_LCD_CLASS_DEVICE=y
  225826. +CONFIG_LCD_PLATFORM=y
  225827. +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
  225828. +CONFIG_FONTS=y
  225829. +CONFIG_FONT_8x8=y
  225830. +CONFIG_FONT_8x16=y
  225831. +CONFIG_LOGO=y
  225832. +CONFIG_SOUND=m
  225833. +CONFIG_SND=m
  225834. +CONFIG_SND_VERBOSE_PRINTK=y
  225835. +CONFIG_SND_DEBUG=y
  225836. +CONFIG_SND_USB_AUDIO=m
  225837. +CONFIG_SND_SOC=m
  225838. +CONFIG_SND_OMAP_SOC=m
  225839. +CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m
  225840. +CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m
  225841. +CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
  225842. +CONFIG_USB=y
  225843. +CONFIG_USB_DEBUG=y
  225844. +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
  225845. +CONFIG_USB_MON=y
  225846. +CONFIG_USB_EHCI_HCD=y
  225847. +CONFIG_USB_OHCI_HCD=y
  225848. +CONFIG_USB_WDM=y
  225849. +CONFIG_USB_STORAGE=y
  225850. +CONFIG_USB_TEST=y
  225851. +CONFIG_USB_PHY=y
  225852. +CONFIG_NOP_USB_XCEIV=y
  225853. +CONFIG_USB_GADGET=y
  225854. +CONFIG_USB_GADGET_DEBUG=y
  225855. +CONFIG_USB_GADGET_DEBUG_FILES=y
  225856. +CONFIG_USB_GADGET_DEBUG_FS=y
  225857. +CONFIG_USB_ZERO=m
  225858. +CONFIG_MMC=y
  225859. +CONFIG_MMC_UNSAFE_RESUME=y
  225860. +CONFIG_SDIO_UART=y
  225861. +CONFIG_MMC_ARMMMCI=y
  225862. +CONFIG_MMC_OMAP=y
  225863. +CONFIG_MMC_OMAP_HS=y
  225864. +CONFIG_NEW_LEDS=y
  225865. +CONFIG_LEDS_CLASS=y
  225866. +CONFIG_LEDS_GPIO=y
  225867. +CONFIG_LEDS_TRIGGERS=y
  225868. +CONFIG_LEDS_TRIGGER_TIMER=y
  225869. +CONFIG_LEDS_TRIGGER_ONESHOT=y
  225870. +CONFIG_LEDS_TRIGGER_HEARTBEAT=y
  225871. +CONFIG_LEDS_TRIGGER_BACKLIGHT=y
  225872. +CONFIG_LEDS_TRIGGER_CPU=y
  225873. +CONFIG_LEDS_TRIGGER_GPIO=y
  225874. +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
  225875. +CONFIG_RTC_CLASS=y
  225876. +CONFIG_RTC_DRV_TWL92330=y
  225877. +CONFIG_RTC_DRV_TWL4030=y
  225878. +CONFIG_RTC_DRV_OMAP=y
  225879. +CONFIG_DMADEVICES=y
  225880. +CONFIG_DMA_OMAP=y
  225881. +# CONFIG_EXT3_FS_XATTR is not set
  225882. +CONFIG_UBIFS_FS=y
  225883. +CONFIG_NFS_FS=y
  225884. +CONFIG_NFS_V3_ACL=y
  225885. +CONFIG_NFS_V4=y
  225886. +CONFIG_ROOT_NFS=y
  225887. +# CONFIG_DEBUG_BUGVERBOSE is not set
  225888. +CONFIG_DEBUG_INFO=y
  225889. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  225890. +CONFIG_LIBCRC32C=y
  225891. +# CONFIG_CPU_FREQ is not set
  225892. diff -Nur linux-3.14.15/linaro/configs/preempt-rt.conf linux-linaro-stable-mx6/linaro/configs/preempt-rt.conf
  225893. --- linux-3.14.15/linaro/configs/preempt-rt.conf 1970-01-01 01:00:00.000000000 +0100
  225894. +++ linux-linaro-stable-mx6/linaro/configs/preempt-rt.conf 2014-08-20 19:31:55.180907865 +0200
  225895. @@ -0,0 +1,4 @@
  225896. +CONFIG_PREEMPT=y
  225897. +CONFIG_PREEMPT_RT_FULL=y
  225898. +CONFIG_SLUB=y
  225899. +# CONFIG_CPU_FREQ is not set
  225900. diff -Nur linux-3.14.15/linaro/configs/vexpress64.conf linux-linaro-stable-mx6/linaro/configs/vexpress64.conf
  225901. --- linux-3.14.15/linaro/configs/vexpress64.conf 1970-01-01 01:00:00.000000000 +0100
  225902. +++ linux-linaro-stable-mx6/linaro/configs/vexpress64.conf 2014-08-20 19:31:55.184907882 +0200
  225903. @@ -0,0 +1,56 @@
  225904. +CONFIG_ARCH_VEXPRESS=y
  225905. +CONFIG_SMP=y
  225906. +CONFIG_NR_CPUS=8
  225907. +CONFIG_CMDLINE="console=ttyAMA0"
  225908. +CONFIG_COMPAT=y
  225909. +CONFIG_SMC91X=y
  225910. +CONFIG_INPUT_EVDEV=y
  225911. +CONFIG_SERIO_AMBAKMI=y
  225912. +CONFIG_SERIAL_AMBA_PL011=y
  225913. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  225914. +# CONFIG_SERIO_I8042 is not set
  225915. +CONFIG_FB=y
  225916. +CONFIG_FB_ARMCLCD=y
  225917. +CONFIG_FRAMEBUFFER_CONSOLE=y
  225918. +# CONFIG_VGA_CONSOLE is not set
  225919. +CONFIG_LOGO=y
  225920. +# CONFIG_LOGO_LINUX_MONO is not set
  225921. +# CONFIG_LOGO_LINUX_VGA16 is not set
  225922. +CONFIG_MMC=y
  225923. +CONFIG_MMC_ARMMMCI=y
  225924. +CONFIG_RTC_CLASS=y
  225925. +CONFIG_RTC_DRV_PL031=y
  225926. +CONFIG_NFS_FS=y
  225927. +CONFIG_NFS_V3=y
  225928. +CONFIG_NFS_V3_ACL=y
  225929. +CONFIG_NFS_V4=y
  225930. +CONFIG_ROOT_NFS=y
  225931. +CONFIG_VIRTIO=y
  225932. +CONFIG_VIRTIO_BLK=y
  225933. +CONFIG_VIRTIO_MMIO=y
  225934. +CONFIG_REGULATOR=y
  225935. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  225936. +CONFIG_CMA=y
  225937. +CONFIG_DMA_CMA=y
  225938. +CONFIG_COMMON_CLK_SCPI=y
  225939. +CONFIG_SMSC911X=y
  225940. +CONFIG_I2C=y
  225941. +CONFIG_ARM_MHU_MBOX=y
  225942. +CONFIG_ARM_SCPI_PROTOCOL=y
  225943. +CONFIG_USB_HIDDEV=y
  225944. +CONFIG_SCSI=y
  225945. +CONFIG_BLK_DEV_SD=y
  225946. +CONFIG_USB_STORAGE=y
  225947. +CONFIG_USB=y
  225948. +CONFIG_USB_ULPI=y
  225949. +CONFIG_USB_EHCI_HCD=y
  225950. +CONFIG_USB_EHCI_HCD_SYNOPSYS=y
  225951. +CONFIG_USB_OHCI_HCD=y
  225952. +CONFIG_USB_PHY=y
  225953. +CONFIG_USB_ISP1301=y
  225954. +CONFIG_PM_OPP=y
  225955. +CONFIG_GENERIC_CPUFREQ_CPU0=y
  225956. +CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
  225957. +CONFIG_ARM_DT_BL_CPUFREQ=y
  225958. +CONFIG_ARM64_CPUIDLE=y
  225959. +CONFIG_ARM64_CRYPTO=y
  225960. diff -Nur linux-3.14.15/linaro/configs/vexpress.conf linux-linaro-stable-mx6/linaro/configs/vexpress.conf
  225961. --- linux-3.14.15/linaro/configs/vexpress.conf 1970-01-01 01:00:00.000000000 +0100
  225962. +++ linux-linaro-stable-mx6/linaro/configs/vexpress.conf 2014-08-20 19:31:55.184907882 +0200
  225963. @@ -0,0 +1,64 @@
  225964. +CONFIG_ARCH_VEXPRESS=y
  225965. +CONFIG_ARCH_VEXPRESS_CA9X4=y
  225966. +CONFIG_HAVE_ARM_ARCH_TIMER=y
  225967. +CONFIG_NR_CPUS=8
  225968. +CONFIG_HIGHMEM=y
  225969. +CONFIG_HIGHPTE=y
  225970. +CONFIG_ARM_PSCI=y
  225971. +CONFIG_MCPM=y
  225972. +CONFIG_ARCH_VEXPRESS_DCSCB=y
  225973. +CONFIG_ARCH_VEXPRESS_TC2_PM=y
  225974. +CONFIG_ARM_BIG_LITTLE_CPUIDLE=y
  225975. +CONFIG_BIG_LITTLE=y
  225976. +CONFIG_ARM_VEXPRESS_SPC_CPUFREQ=y
  225977. +CONFIG_PM_OPP=y
  225978. +CONFIG_CPU_FREQ=y
  225979. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  225980. +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
  225981. +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
  225982. +CONFIG_CMDLINE="console=ttyAMA0,38400n8 root=/dev/mmcblk0p2 rootwait mmci.fmax=4000000"
  225983. +CONFIG_VFP=y
  225984. +CONFIG_NEON=y
  225985. +CONFIG_SCSI=y
  225986. +CONFIG_BLK_DEV_SD=y
  225987. +CONFIG_SMSC911X=y
  225988. +CONFIG_SMC91X=y
  225989. +CONFIG_INPUT_EVDEV=y
  225990. +CONFIG_SERIO_AMBAKMI=y
  225991. +CONFIG_SERIAL_AMBA_PL011=y
  225992. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  225993. +CONFIG_FB=y
  225994. +CONFIG_FB_ARMCLCD=y
  225995. +CONFIG_FB_ARMHDLCD=y
  225996. +CONFIG_LOGO=y
  225997. +# CONFIG_LOGO_LINUX_MONO is not set
  225998. +# CONFIG_LOGO_LINUX_VGA16 is not set
  225999. +CONFIG_SOUND=y
  226000. +CONFIG_SND=y
  226001. +CONFIG_SND_ARMAACI=y
  226002. +CONFIG_USB=y
  226003. +CONFIG_USB_ISP1760_HCD=y
  226004. +CONFIG_USB_STORAGE=y
  226005. +CONFIG_MMC=y
  226006. +CONFIG_MMC_ARMMMCI=y
  226007. +CONFIG_RTC_CLASS=y
  226008. +CONFIG_RTC_DRV_PL031=y
  226009. +CONFIG_NFS_FS=y
  226010. +CONFIG_NFS_V3=y
  226011. +CONFIG_NFS_V3_ACL=y
  226012. +CONFIG_NFS_V4=y
  226013. +CONFIG_ROOT_NFS=y
  226014. +CONFIG_VEXPRESS_CONFIG=y
  226015. +CONFIG_SENSORS_VEXPRESS=y
  226016. +CONFIG_REGULATOR=y
  226017. +CONFIG_REGULATOR_VEXPRESS=y
  226018. +CONFIG_NEW_LEDS=y
  226019. +CONFIG_LEDS_CLASS=y
  226020. +CONFIG_LEDS_GPIO=y
  226021. +CONFIG_LEDS_TRIGGERS=y
  226022. +CONFIG_LEDS_TRIGGER_HEARTBEAT=y
  226023. +CONFIG_LEDS_TRIGGER_CPU=y
  226024. +CONFIG_VIRTIO=y
  226025. +CONFIG_VIRTIO_BLK=y
  226026. +CONFIG_VIRTIO_MMIO=y
  226027. +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
  226028. diff -Nur linux-3.14.15/linaro/configs/vexpress-tuning.conf linux-linaro-stable-mx6/linaro/configs/vexpress-tuning.conf
  226029. --- linux-3.14.15/linaro/configs/vexpress-tuning.conf 1970-01-01 01:00:00.000000000 +0100
  226030. +++ linux-linaro-stable-mx6/linaro/configs/vexpress-tuning.conf 2014-08-20 19:24:07.906907101 +0200
  226031. @@ -0,0 +1 @@
  226032. +# CONFIG_PROVE_LOCKING is not set
  226033. diff -Nur linux-3.14.15/linaro/configs/xen.conf linux-linaro-stable-mx6/linaro/configs/xen.conf
  226034. --- linux-3.14.15/linaro/configs/xen.conf 1970-01-01 01:00:00.000000000 +0100
  226035. +++ linux-linaro-stable-mx6/linaro/configs/xen.conf 2014-08-20 19:24:07.906907101 +0200
  226036. @@ -0,0 +1,7 @@
  226037. +CONFIG_XEN=y
  226038. +CONFIG_XEN_NETDEV_FRONTEND=y
  226039. +CONFIG_XEN_NETDEV_BACKEND=y
  226040. +CONFIG_XEN_BLKDEV_FRONTEND=y
  226041. +CONFIG_XEN_BLKDEV_BACKEND=y
  226042. +CONFIG_XENFS=y
  226043. +CONFIG_XEN_COMPAT_XENFS=y
  226044. diff -Nur linux-3.14.15/MAINTAINERS linux-linaro-stable-mx6/MAINTAINERS
  226045. --- linux-3.14.15/MAINTAINERS 2014-07-31 23:51:43.000000000 +0200
  226046. +++ linux-linaro-stable-mx6/MAINTAINERS 2014-08-20 19:31:39.704841430 +0200
  226047. @@ -5511,6 +5511,14 @@
  226048. F: drivers/net/macvlan.c
  226049. F: include/linux/if_macvlan.h
  226050. +MAILBOX API
  226051. +M: Jassi Brar <jassisinghbrar@gmail.com>
  226052. +L: linux-kernel@vger.kernel.org
  226053. +S: Maintained
  226054. +F: drivers/mailbox/
  226055. +F: include/linux/mailbox_client.h
  226056. +F: include/linux/mailbox_controller.h
  226057. +
  226058. MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
  226059. M: Michael Kerrisk <mtk.manpages@gmail.com>
  226060. W: http://www.kernel.org/doc/man-pages
  226061. diff -Nur linux-3.14.15/Makefile linux-linaro-stable-mx6/Makefile
  226062. --- linux-3.14.15/Makefile 2014-07-31 23:51:43.000000000 +0200
  226063. +++ linux-linaro-stable-mx6/Makefile 2014-08-20 22:02:59.718382139 +0200
  226064. @@ -639,8 +639,6 @@
  226065. endif
  226066. endif
  226067. -KBUILD_CFLAGS += $(call cc-option, -fno-var-tracking-assignments)
  226068. -
  226069. ifdef CONFIG_DEBUG_INFO
  226070. KBUILD_CFLAGS += -g
  226071. KBUILD_AFLAGS += -Wa,--gdwarf-2
  226072. diff -Nur linux-3.14.15/mm/hugetlb.c linux-linaro-stable-mx6/mm/hugetlb.c
  226073. --- linux-3.14.15/mm/hugetlb.c 2014-07-31 23:51:43.000000000 +0200
  226074. +++ linux-linaro-stable-mx6/mm/hugetlb.c 2014-08-20 19:31:55.188907899 +0200
  226075. @@ -2422,7 +2422,6 @@
  226076. } else {
  226077. if (cow)
  226078. huge_ptep_set_wrprotect(src, addr, src_pte);
  226079. - entry = huge_ptep_get(src_pte);
  226080. ptepage = pte_page(entry);
  226081. get_page(ptepage);
  226082. page_dup_rmap(ptepage);
  226083. diff -Nur linux-3.14.15/mm/slab_common.c linux-linaro-stable-mx6/mm/slab_common.c
  226084. --- linux-3.14.15/mm/slab_common.c 2014-07-31 23:51:43.000000000 +0200
  226085. +++ linux-linaro-stable-mx6/mm/slab_common.c 2014-08-20 19:31:55.220908036 +0200
  226086. @@ -56,7 +56,7 @@
  226087. continue;
  226088. }
  226089. -#if !defined(CONFIG_SLUB)
  226090. +#if !defined(CONFIG_SLUB) || !defined(CONFIG_SLUB_DEBUG_ON)
  226091. /*
  226092. * For simplicity, we won't check this in the list of memcg
  226093. * caches. We have control over memcg naming, and if there
  226094. diff -Nur linux-3.14.15/net/atm/svc.c linux-linaro-stable-mx6/net/atm/svc.c
  226095. --- linux-3.14.15/net/atm/svc.c 2014-07-31 23:51:43.000000000 +0200
  226096. +++ linux-linaro-stable-mx6/net/atm/svc.c 2014-08-20 19:31:55.276908277 +0200
  226097. @@ -263,17 +263,11 @@
  226098. goto out;
  226099. }
  226100. }
  226101. -/*
  226102. - * Not supported yet
  226103. - *
  226104. - * #ifndef CONFIG_SINGLE_SIGITF
  226105. - */
  226106. +
  226107. vcc->qos.txtp.max_pcr = SELECT_TOP_PCR(vcc->qos.txtp);
  226108. vcc->qos.txtp.pcr = 0;
  226109. vcc->qos.txtp.min_pcr = 0;
  226110. -/*
  226111. - * #endif
  226112. - */
  226113. +
  226114. error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci);
  226115. if (!error)
  226116. sock->state = SS_CONNECTED;
  226117. diff -Nur linux-3.14.15/net/core/dev.c linux-linaro-stable-mx6/net/core/dev.c
  226118. --- linux-3.14.15/net/core/dev.c 2014-07-31 23:51:43.000000000 +0200
  226119. +++ linux-linaro-stable-mx6/net/core/dev.c 2014-08-20 19:31:55.316908449 +0200
  226120. @@ -3453,7 +3453,7 @@
  226121. * @rx_handler: receive handler to register
  226122. * @rx_handler_data: data pointer that is used by rx handler
  226123. *
  226124. - * Register a receive hander for a device. This handler will then be
  226125. + * Register a receive handler for a device. This handler will then be
  226126. * called from __netif_receive_skb. A negative errno code is returned
  226127. * on a failure.
  226128. *
  226129. diff -Nur linux-3.14.15/net/core/Makefile linux-linaro-stable-mx6/net/core/Makefile
  226130. --- linux-3.14.15/net/core/Makefile 2014-07-31 23:51:43.000000000 +0200
  226131. +++ linux-linaro-stable-mx6/net/core/Makefile 2014-08-20 19:31:55.316908449 +0200
  226132. @@ -9,7 +9,7 @@
  226133. obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \
  226134. neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
  226135. - sock_diag.o dev_ioctl.o
  226136. + sock_diag.o dev_ioctl.o tso.o
  226137. obj-$(CONFIG_XFRM) += flow.o
  226138. obj-y += net-sysfs.o
  226139. diff -Nur linux-3.14.15/net/core/rtnetlink.c linux-linaro-stable-mx6/net/core/rtnetlink.c
  226140. --- linux-3.14.15/net/core/rtnetlink.c 2014-07-31 23:51:43.000000000 +0200
  226141. +++ linux-linaro-stable-mx6/net/core/rtnetlink.c 2014-08-20 19:31:55.324908483 +0200
  226142. @@ -1156,73 +1156,7 @@
  226143. return -EMSGSIZE;
  226144. }
  226145. -static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
  226146. -{
  226147. - struct net *net = sock_net(skb->sk);
  226148. - int h, s_h;
  226149. - int idx = 0, s_idx;
  226150. - struct net_device *dev;
  226151. - struct hlist_head *head;
  226152. - struct nlattr *tb[IFLA_MAX+1];
  226153. - u32 ext_filter_mask = 0;
  226154. - int err;
  226155. - int hdrlen;
  226156. -
  226157. - s_h = cb->args[0];
  226158. - s_idx = cb->args[1];
  226159. -
  226160. - rcu_read_lock();
  226161. - cb->seq = net->dev_base_seq;
  226162. -
  226163. - /* A hack to preserve kernel<->userspace interface.
  226164. - * The correct header is ifinfomsg. It is consistent with rtnl_getlink.
  226165. - * However, before Linux v3.9 the code here assumed rtgenmsg and that's
  226166. - * what iproute2 < v3.9.0 used.
  226167. - * We can detect the old iproute2. Even including the IFLA_EXT_MASK
  226168. - * attribute, its netlink message is shorter than struct ifinfomsg.
  226169. - */
  226170. - hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ?
  226171. - sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
  226172. -
  226173. - if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) {
  226174. -
  226175. - if (tb[IFLA_EXT_MASK])
  226176. - ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
  226177. - }
  226178. -
  226179. - for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
  226180. - idx = 0;
  226181. - head = &net->dev_index_head[h];
  226182. - hlist_for_each_entry_rcu(dev, head, index_hlist) {
  226183. - if (idx < s_idx)
  226184. - goto cont;
  226185. - err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
  226186. - NETLINK_CB(cb->skb).portid,
  226187. - cb->nlh->nlmsg_seq, 0,
  226188. - NLM_F_MULTI,
  226189. - ext_filter_mask);
  226190. - /* If we ran out of room on the first message,
  226191. - * we're in trouble
  226192. - */
  226193. - WARN_ON((err == -EMSGSIZE) && (skb->len == 0));
  226194. -
  226195. - if (err <= 0)
  226196. - goto out;
  226197. -
  226198. - nl_dump_check_consistent(cb, nlmsg_hdr(skb));
  226199. -cont:
  226200. - idx++;
  226201. - }
  226202. - }
  226203. -out:
  226204. - rcu_read_unlock();
  226205. - cb->args[1] = idx;
  226206. - cb->args[0] = h;
  226207. -
  226208. - return skb->len;
  226209. -}
  226210. -
  226211. -const struct nla_policy ifla_policy[IFLA_MAX+1] = {
  226212. +static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
  226213. [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
  226214. [IFLA_ADDRESS] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
  226215. [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
  226216. @@ -1249,7 +1183,6 @@
  226217. [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
  226218. [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
  226219. };
  226220. -EXPORT_SYMBOL(ifla_policy);
  226221. static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
  226222. [IFLA_INFO_KIND] = { .type = NLA_STRING },
  226223. @@ -1287,6 +1220,61 @@
  226224. [IFLA_PORT_RESPONSE] = { .type = NLA_U16, },
  226225. };
  226226. +static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
  226227. +{
  226228. + struct net *net = sock_net(skb->sk);
  226229. + int h, s_h;
  226230. + int idx = 0, s_idx;
  226231. + struct net_device *dev;
  226232. + struct hlist_head *head;
  226233. + struct nlattr *tb[IFLA_MAX+1];
  226234. + u32 ext_filter_mask = 0;
  226235. +
  226236. + s_h = cb->args[0];
  226237. + s_idx = cb->args[1];
  226238. +
  226239. + rcu_read_lock();
  226240. + cb->seq = net->dev_base_seq;
  226241. +
  226242. + if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
  226243. + ifla_policy) >= 0) {
  226244. +
  226245. + if (tb[IFLA_EXT_MASK])
  226246. + ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
  226247. + }
  226248. +
  226249. + for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
  226250. + idx = 0;
  226251. + head = &net->dev_index_head[h];
  226252. + hlist_for_each_entry_rcu(dev, head, index_hlist) {
  226253. + if (idx < s_idx)
  226254. + goto cont;
  226255. + if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
  226256. + NETLINK_CB(cb->skb).portid,
  226257. + cb->nlh->nlmsg_seq, 0,
  226258. + NLM_F_MULTI,
  226259. + ext_filter_mask) <= 0)
  226260. + goto out;
  226261. +
  226262. + nl_dump_check_consistent(cb, nlmsg_hdr(skb));
  226263. +cont:
  226264. + idx++;
  226265. + }
  226266. + }
  226267. +out:
  226268. + rcu_read_unlock();
  226269. + cb->args[1] = idx;
  226270. + cb->args[0] = h;
  226271. +
  226272. + return skb->len;
  226273. +}
  226274. +
  226275. +int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len)
  226276. +{
  226277. + return nla_parse(tb, IFLA_MAX, head, len, ifla_policy);
  226278. +}
  226279. +EXPORT_SYMBOL(rtnl_nla_parse_ifla);
  226280. +
  226281. struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
  226282. {
  226283. struct net *net;
  226284. diff -Nur linux-3.14.15/net/core/tso.c linux-linaro-stable-mx6/net/core/tso.c
  226285. --- linux-3.14.15/net/core/tso.c 1970-01-01 01:00:00.000000000 +0100
  226286. +++ linux-linaro-stable-mx6/net/core/tso.c 2014-08-20 19:31:55.332908517 +0200
  226287. @@ -0,0 +1,72 @@
  226288. +#include <net/ip.h>
  226289. +#include <net/tso.h>
  226290. +
  226291. +/* Calculate expected number of TX descriptors */
  226292. +int tso_count_descs(struct sk_buff *skb)
  226293. +{
  226294. + /* The Marvell Way */
  226295. + return skb_shinfo(skb)->gso_segs * 2 + skb_shinfo(skb)->nr_frags;
  226296. +}
  226297. +
  226298. +void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,
  226299. + int size, bool is_last)
  226300. +{
  226301. + struct iphdr *iph;
  226302. + struct tcphdr *tcph;
  226303. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  226304. + int mac_hdr_len = skb_network_offset(skb);
  226305. +
  226306. + memcpy(hdr, skb->data, hdr_len);
  226307. + iph = (struct iphdr *)(hdr + mac_hdr_len);
  226308. + iph->id = htons(tso->ip_id);
  226309. + iph->tot_len = htons(size + hdr_len - mac_hdr_len);
  226310. + tcph = (struct tcphdr *)(hdr + skb_transport_offset(skb));
  226311. + tcph->seq = htonl(tso->tcp_seq);
  226312. + tso->ip_id++;
  226313. +
  226314. + if (!is_last) {
  226315. + /* Clear all special flags for not last packet */
  226316. + tcph->psh = 0;
  226317. + tcph->fin = 0;
  226318. + tcph->rst = 0;
  226319. + }
  226320. +}
  226321. +
  226322. +void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size)
  226323. +{
  226324. + tso->tcp_seq += size;
  226325. + tso->size -= size;
  226326. + tso->data += size;
  226327. +
  226328. + if ((tso->size == 0) &&
  226329. + (tso->next_frag_idx < skb_shinfo(skb)->nr_frags)) {
  226330. + skb_frag_t *frag = &skb_shinfo(skb)->frags[tso->next_frag_idx];
  226331. +
  226332. + /* Move to next segment */
  226333. + tso->size = frag->size;
  226334. + tso->data = page_address(frag->page.p) + frag->page_offset;
  226335. + tso->next_frag_idx++;
  226336. + }
  226337. +}
  226338. +
  226339. +void tso_start(struct sk_buff *skb, struct tso_t *tso)
  226340. +{
  226341. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  226342. +
  226343. + tso->ip_id = ntohs(ip_hdr(skb)->id);
  226344. + tso->tcp_seq = ntohl(tcp_hdr(skb)->seq);
  226345. + tso->next_frag_idx = 0;
  226346. +
  226347. + /* Build first data */
  226348. + tso->size = skb_headlen(skb) - hdr_len;
  226349. + tso->data = skb->data + hdr_len;
  226350. + if ((tso->size == 0) &&
  226351. + (tso->next_frag_idx < skb_shinfo(skb)->nr_frags)) {
  226352. + skb_frag_t *frag = &skb_shinfo(skb)->frags[tso->next_frag_idx];
  226353. +
  226354. + /* Move to next segment */
  226355. + tso->size = frag->size;
  226356. + tso->data = page_address(frag->page.p) + frag->page_offset;
  226357. + tso->next_frag_idx++;
  226358. + }
  226359. +}
  226360. diff -Nur linux-3.14.15/net/ieee802154/Kconfig linux-linaro-stable-mx6/net/ieee802154/Kconfig
  226361. --- linux-3.14.15/net/ieee802154/Kconfig 2014-07-31 23:51:43.000000000 +0200
  226362. +++ linux-linaro-stable-mx6/net/ieee802154/Kconfig 2014-08-20 19:31:55.344908570 +0200
  226363. @@ -15,7 +15,7 @@
  226364. depends on IEEE802154 && IPV6
  226365. select 6LOWPAN_IPHC
  226366. ---help---
  226367. - IPv6 compression over IEEE 802.15.4.
  226368. + IPv6 compression over IEEE 802.15.4.
  226369. config 6LOWPAN_IPHC
  226370. tristate
  226371. diff -Nur linux-3.14.15/net/mac80211/driver-ops.h linux-linaro-stable-mx6/net/mac80211/driver-ops.h
  226372. --- linux-3.14.15/net/mac80211/driver-ops.h 2014-07-31 23:51:43.000000000 +0200
  226373. +++ linux-linaro-stable-mx6/net/mac80211/driver-ops.h 2014-08-20 19:31:55.496909221 +0200
  226374. @@ -722,13 +722,19 @@
  226375. }
  226376. static inline void drv_flush(struct ieee80211_local *local,
  226377. + struct ieee80211_sub_if_data *sdata,
  226378. u32 queues, bool drop)
  226379. {
  226380. + struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL;
  226381. +
  226382. might_sleep();
  226383. + if (sdata)
  226384. + check_sdata_in_driver(sdata);
  226385. +
  226386. trace_drv_flush(local, queues, drop);
  226387. if (local->ops->flush)
  226388. - local->ops->flush(&local->hw, queues, drop);
  226389. + local->ops->flush(&local->hw, vif, queues, drop);
  226390. trace_drv_return_void(local);
  226391. }
  226392. diff -Nur linux-3.14.15/net/mac80211/ibss.c linux-linaro-stable-mx6/net/mac80211/ibss.c
  226393. --- linux-3.14.15/net/mac80211/ibss.c 2014-07-31 23:51:43.000000000 +0200
  226394. +++ linux-linaro-stable-mx6/net/mac80211/ibss.c 2014-08-20 19:31:55.496909221 +0200
  226395. @@ -386,7 +386,7 @@
  226396. presp->head_len, 0, GFP_KERNEL);
  226397. cfg80211_put_bss(local->hw.wiphy, bss);
  226398. netif_carrier_on(sdata->dev);
  226399. - cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
  226400. + cfg80211_ibss_joined(sdata->dev, ifibss->bssid, chan, GFP_KERNEL);
  226401. }
  226402. static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
  226403. diff -Nur linux-3.14.15/net/mac80211/util.c linux-linaro-stable-mx6/net/mac80211/util.c
  226404. --- linux-3.14.15/net/mac80211/util.c 2014-07-31 23:51:43.000000000 +0200
  226405. +++ linux-linaro-stable-mx6/net/mac80211/util.c 2014-08-20 19:31:55.524909342 +0200
  226406. @@ -554,7 +554,7 @@
  226407. ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
  226408. IEEE80211_QUEUE_STOP_REASON_FLUSH);
  226409. - drv_flush(local, queues, false);
  226410. + drv_flush(local, sdata, queues, false);
  226411. ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
  226412. IEEE80211_QUEUE_STOP_REASON_FLUSH);
  226413. diff -Nur linux-3.14.15/net/wireless/core.h linux-linaro-stable-mx6/net/wireless/core.h
  226414. --- linux-3.14.15/net/wireless/core.h 2014-07-31 23:51:43.000000000 +0200
  226415. +++ linux-linaro-stable-mx6/net/wireless/core.h 2014-08-20 19:31:56.540913704 +0200
  226416. @@ -211,6 +211,7 @@
  226417. } dc;
  226418. struct {
  226419. u8 bssid[ETH_ALEN];
  226420. + struct ieee80211_channel *channel;
  226421. } ij;
  226422. };
  226423. };
  226424. @@ -258,7 +259,8 @@
  226425. struct net_device *dev, bool nowext);
  226426. int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
  226427. struct net_device *dev, bool nowext);
  226428. -void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
  226429. +void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  226430. + struct ieee80211_channel *channel);
  226431. int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
  226432. struct wireless_dev *wdev);
  226433. diff -Nur linux-3.14.15/net/wireless/ibss.c linux-linaro-stable-mx6/net/wireless/ibss.c
  226434. --- linux-3.14.15/net/wireless/ibss.c 2014-07-31 23:51:43.000000000 +0200
  226435. +++ linux-linaro-stable-mx6/net/wireless/ibss.c 2014-08-20 19:31:56.540913704 +0200
  226436. @@ -14,7 +14,8 @@
  226437. #include "rdev-ops.h"
  226438. -void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
  226439. +void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  226440. + struct ieee80211_channel *channel)
  226441. {
  226442. struct wireless_dev *wdev = dev->ieee80211_ptr;
  226443. struct cfg80211_bss *bss;
  226444. @@ -28,8 +29,7 @@
  226445. if (!wdev->ssid_len)
  226446. return;
  226447. - bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
  226448. - wdev->ssid, wdev->ssid_len,
  226449. + bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0,
  226450. WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
  226451. if (WARN_ON(!bss))
  226452. @@ -54,21 +54,26 @@
  226453. #endif
  226454. }
  226455. -void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
  226456. +void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  226457. + struct ieee80211_channel *channel, gfp_t gfp)
  226458. {
  226459. struct wireless_dev *wdev = dev->ieee80211_ptr;
  226460. struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
  226461. struct cfg80211_event *ev;
  226462. unsigned long flags;
  226463. - trace_cfg80211_ibss_joined(dev, bssid);
  226464. + trace_cfg80211_ibss_joined(dev, bssid, channel);
  226465. +
  226466. + if (WARN_ON(!channel))
  226467. + return;
  226468. ev = kzalloc(sizeof(*ev), gfp);
  226469. if (!ev)
  226470. return;
  226471. ev->type = EVENT_IBSS_JOINED;
  226472. - memcpy(ev->cr.bssid, bssid, ETH_ALEN);
  226473. + memcpy(ev->ij.bssid, bssid, ETH_ALEN);
  226474. + ev->ij.channel = channel;
  226475. spin_lock_irqsave(&wdev->event_lock, flags);
  226476. list_add_tail(&ev->list, &wdev->event_list);
  226477. diff -Nur linux-3.14.15/net/wireless/nl80211.c linux-linaro-stable-mx6/net/wireless/nl80211.c
  226478. --- linux-3.14.15/net/wireless/nl80211.c 2014-07-31 23:51:43.000000000 +0200
  226479. +++ linux-linaro-stable-mx6/net/wireless/nl80211.c 2014-08-20 19:31:56.540913704 +0200
  226480. @@ -1450,17 +1450,18 @@
  226481. }
  226482. CMD(start_p2p_device, START_P2P_DEVICE);
  226483. CMD(set_mcast_rate, SET_MCAST_RATE);
  226484. -#ifdef CONFIG_NL80211_TESTMODE
  226485. - CMD(testmode_cmd, TESTMODE);
  226486. -#endif
  226487. if (state->split) {
  226488. CMD(crit_proto_start, CRIT_PROTOCOL_START);
  226489. CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
  226490. if (dev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
  226491. CMD(channel_switch, CHANNEL_SWITCH);
  226492. - CMD(set_qos_map, SET_QOS_MAP);
  226493. }
  226494. - /* add into the if now */
  226495. + CMD(set_qos_map, SET_QOS_MAP);
  226496. +
  226497. +#ifdef CONFIG_NL80211_TESTMODE
  226498. + CMD(testmode_cmd, TESTMODE);
  226499. +#endif
  226500. +
  226501. #undef CMD
  226502. if (dev->ops->connect || dev->ops->auth) {
  226503. diff -Nur linux-3.14.15/net/wireless/trace.h linux-linaro-stable-mx6/net/wireless/trace.h
  226504. --- linux-3.14.15/net/wireless/trace.h 2014-07-31 23:51:43.000000000 +0200
  226505. +++ linux-linaro-stable-mx6/net/wireless/trace.h 2014-08-20 19:31:56.544913721 +0200
  226506. @@ -2278,11 +2278,6 @@
  226507. TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr))
  226508. );
  226509. -DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined,
  226510. - TP_PROTO(struct net_device *netdev, const u8 *addr),
  226511. - TP_ARGS(netdev, addr)
  226512. -);
  226513. -
  226514. DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame,
  226515. TP_PROTO(struct net_device *netdev, const u8 *addr),
  226516. TP_ARGS(netdev, addr)
  226517. @@ -2293,6 +2288,24 @@
  226518. TP_ARGS(netdev, addr)
  226519. );
  226520. +TRACE_EVENT(cfg80211_ibss_joined,
  226521. + TP_PROTO(struct net_device *netdev, const u8 *bssid,
  226522. + struct ieee80211_channel *channel),
  226523. + TP_ARGS(netdev, bssid, channel),
  226524. + TP_STRUCT__entry(
  226525. + NETDEV_ENTRY
  226526. + MAC_ENTRY(bssid)
  226527. + CHAN_ENTRY
  226528. + ),
  226529. + TP_fast_assign(
  226530. + NETDEV_ASSIGN;
  226531. + MAC_ASSIGN(bssid, bssid);
  226532. + CHAN_ASSIGN(channel);
  226533. + ),
  226534. + TP_printk(NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", " CHAN_PR_FMT,
  226535. + NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
  226536. +);
  226537. +
  226538. TRACE_EVENT(cfg80211_probe_status,
  226539. TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie,
  226540. bool acked),
  226541. diff -Nur linux-3.14.15/net/wireless/util.c linux-linaro-stable-mx6/net/wireless/util.c
  226542. --- linux-3.14.15/net/wireless/util.c 2014-07-31 23:51:43.000000000 +0200
  226543. +++ linux-linaro-stable-mx6/net/wireless/util.c 2014-08-20 19:31:56.544913721 +0200
  226544. @@ -820,7 +820,8 @@
  226545. ev->dc.reason, true);
  226546. break;
  226547. case EVENT_IBSS_JOINED:
  226548. - __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
  226549. + __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,
  226550. + ev->ij.channel);
  226551. break;
  226552. }
  226553. wdev_unlock(wdev);
  226554. diff -Nur linux-3.14.15/scripts/Makefile.lib linux-linaro-stable-mx6/scripts/Makefile.lib
  226555. --- linux-3.14.15/scripts/Makefile.lib 2014-07-31 23:51:43.000000000 +0200
  226556. +++ linux-linaro-stable-mx6/scripts/Makefile.lib 2014-08-20 19:31:56.552913755 +0200
  226557. @@ -153,6 +153,7 @@
  226558. -I$(srctree)/arch/$(SRCARCH)/boot/dts \
  226559. -I$(srctree)/arch/$(SRCARCH)/boot/dts/include \
  226560. -I$(srctree)/drivers/of/testcase-data \
  226561. + -I$(srctree)/include \
  226562. -undef -D__DTS__
  226563. # Finds the multi-part object the current object will be linked into
  226564. diff -Nur linux-3.14.15/scripts/mod/devicetable-offsets.c linux-linaro-stable-mx6/scripts/mod/devicetable-offsets.c
  226565. --- linux-3.14.15/scripts/mod/devicetable-offsets.c 2014-07-31 23:51:43.000000000 +0200
  226566. +++ linux-linaro-stable-mx6/scripts/mod/devicetable-offsets.c 2014-08-20 19:31:57.120916194 +0200
  226567. @@ -174,6 +174,9 @@
  226568. DEVID_FIELD(x86_cpu_id, model);
  226569. DEVID_FIELD(x86_cpu_id, vendor);
  226570. + DEVID(cpu_feature);
  226571. + DEVID_FIELD(cpu_feature, feature);
  226572. +
  226573. DEVID(mei_cl_device_id);
  226574. DEVID_FIELD(mei_cl_device_id, name);
  226575. diff -Nur linux-3.14.15/scripts/mod/file2alias.c linux-linaro-stable-mx6/scripts/mod/file2alias.c
  226576. --- linux-3.14.15/scripts/mod/file2alias.c 2014-07-31 23:51:43.000000000 +0200
  226577. +++ linux-linaro-stable-mx6/scripts/mod/file2alias.c 2014-08-20 19:31:57.148916314 +0200
  226578. @@ -1135,6 +1135,16 @@
  226579. }
  226580. ADD_TO_DEVTABLE("x86cpu", x86_cpu_id, do_x86cpu_entry);
  226581. +/* LOOKS like cpu:type:*:feature:*FEAT* */
  226582. +static int do_cpu_entry(const char *filename, void *symval, char *alias)
  226583. +{
  226584. + DEF_FIELD(symval, cpu_feature, feature);
  226585. +
  226586. + sprintf(alias, "cpu:type:*:feature:*%04X*", feature);
  226587. + return 1;
  226588. +}
  226589. +ADD_TO_DEVTABLE("cpu", cpu_feature, do_cpu_entry);
  226590. +
  226591. /* Looks like: mei:S */
  226592. static int do_mei_entry(const char *filename, void *symval,
  226593. char *alias)
  226594. diff -Nur linux-3.14.15/scripts/recordmcount.c linux-linaro-stable-mx6/scripts/recordmcount.c
  226595. --- linux-3.14.15/scripts/recordmcount.c 2014-07-31 23:51:43.000000000 +0200
  226596. +++ linux-linaro-stable-mx6/scripts/recordmcount.c 2014-08-20 19:31:57.256916777 +0200
  226597. @@ -40,6 +40,11 @@
  226598. #define R_METAG_NONE 3
  226599. #endif
  226600. +#ifndef EM_AARCH64
  226601. +#define EM_AARCH64 183
  226602. +#define R_AARCH64_ABS64 257
  226603. +#endif
  226604. +
  226605. static int fd_map; /* File descriptor for file being modified. */
  226606. static int mmap_failed; /* Boolean flag. */
  226607. static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */
  226608. @@ -347,6 +352,8 @@
  226609. case EM_ARM: reltype = R_ARM_ABS32;
  226610. altmcount = "__gnu_mcount_nc";
  226611. break;
  226612. + case EM_AARCH64:
  226613. + reltype = R_AARCH64_ABS64; gpfx = '_'; break;
  226614. case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break;
  226615. case EM_METAG: reltype = R_METAG_ADDR32;
  226616. altmcount = "_mcount_wrapper";
  226617. diff -Nur linux-3.14.15/scripts/recordmcount.pl linux-linaro-stable-mx6/scripts/recordmcount.pl
  226618. --- linux-3.14.15/scripts/recordmcount.pl 2014-07-31 23:51:43.000000000 +0200
  226619. +++ linux-linaro-stable-mx6/scripts/recordmcount.pl 2014-08-20 19:31:57.256916777 +0200
  226620. @@ -279,6 +279,11 @@
  226621. $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_ARM_(CALL|PC24|THM_CALL)" .
  226622. "\\s+(__gnu_mcount_nc|mcount)\$";
  226623. +} elsif ($arch eq "arm64") {
  226624. + $alignment = 3;
  226625. + $section_type = '%progbits';
  226626. + $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_AARCH64_CALL26\\s+_mcount\$";
  226627. + $type = ".quad";
  226628. } elsif ($arch eq "ia64") {
  226629. $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
  226630. $type = "data8";
  226631. diff -Nur linux-3.14.15/sound/soc/codecs/cs42888.c linux-linaro-stable-mx6/sound/soc/codecs/cs42888.c
  226632. --- linux-3.14.15/sound/soc/codecs/cs42888.c 1970-01-01 01:00:00.000000000 +0100
  226633. +++ linux-linaro-stable-mx6/sound/soc/codecs/cs42888.c 2014-08-20 19:24:09.490913864 +0200
  226634. @@ -0,0 +1,934 @@
  226635. +/*
  226636. + * cs42888.c -- CS42888 ALSA SoC Audio Driver
  226637. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  226638. + */
  226639. +/*
  226640. + * The code contained herein is licensed under the GNU General Public
  226641. + * License. You may obtain a copy of the GNU General Public License
  226642. + * Version 2 or later at the following locations:
  226643. + *
  226644. + * http://www.opensource.org/licenses/gpl-license.html
  226645. + * http://www.gnu.org/copyleft/gpl.html
  226646. + */
  226647. +
  226648. +#include <linux/module.h>
  226649. +#include <linux/moduleparam.h>
  226650. +#include <linux/kernel.h>
  226651. +#include <linux/init.h>
  226652. +#include <linux/clk.h>
  226653. +#include <linux/delay.h>
  226654. +#include <linux/pm.h>
  226655. +#include <linux/i2c.h>
  226656. +#include <linux/spi/spi.h>
  226657. +#include <linux/platform_device.h>
  226658. +#include <linux/regulator/consumer.h>
  226659. +
  226660. +#include <sound/core.h>
  226661. +#include <sound/pcm.h>
  226662. +#include <sound/pcm_params.h>
  226663. +#include <sound/soc.h>
  226664. +#include <sound/soc-dapm.h>
  226665. +#include <sound/tlv.h>
  226666. +#include <sound/initval.h>
  226667. +#include <asm/div64.h>
  226668. +#include "cs42888.h"
  226669. +
  226670. +#define CS42888_NUM_SUPPLIES 4
  226671. +static const char *cs42888_supply_names[CS42888_NUM_SUPPLIES] = {
  226672. + "VA",
  226673. + "VD",
  226674. + "VLS",
  226675. + "VLC",
  226676. +};
  226677. +
  226678. +#define CS42888_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
  226679. + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
  226680. +
  226681. +/* Private data for the CS42888 */
  226682. +struct cs42888_private {
  226683. + struct clk *clk;
  226684. + struct snd_soc_codec *codec;
  226685. + u8 reg_cache[CS42888_NUMREGS + 1];
  226686. + unsigned int mclk; /* Input frequency of the MCLK pin */
  226687. + unsigned int slave_mode;
  226688. + struct regulator_bulk_data supplies[CS42888_NUM_SUPPLIES];
  226689. +};
  226690. +
  226691. +/**
  226692. + * cs42888_fill_cache - pre-fill the CS42888 register cache.
  226693. + * @codec: the codec for this CS42888
  226694. + *
  226695. + * This function fills in the CS42888 register cache by reading the register
  226696. + * values from the hardware.
  226697. + *
  226698. + * This CS42888 registers are cached to avoid excessive I2C I/O operations.
  226699. + * After the initial read to pre-fill the cache, the CS42888 never updates
  226700. + * the register values, so we won't have a cache coherency problem.
  226701. + *
  226702. + * We use the auto-increment feature of the CS42888 to read all registers in
  226703. + * one shot.
  226704. + */
  226705. +static int cs42888_fill_cache(struct snd_soc_codec *codec)
  226706. +{
  226707. + u8 *cache = codec->reg_cache;
  226708. + struct i2c_client *i2c_client = to_i2c_client(codec->dev);
  226709. + s32 length;
  226710. +
  226711. + length = i2c_smbus_read_i2c_block_data(i2c_client,
  226712. + CS42888_FIRSTREG | CS42888_I2C_INCR, CS42888_NUMREGS, \
  226713. + cache + 1);
  226714. +
  226715. + if (length != CS42888_NUMREGS) {
  226716. + dev_err(codec->dev, "i2c read failure, addr=0x%x\n",
  226717. + i2c_client->addr);
  226718. + return -EIO;
  226719. + }
  226720. + return 0;
  226721. +}
  226722. +
  226723. +#ifdef DEBUG
  226724. +static void dump_reg(struct snd_soc_codec *codec)
  226725. +{
  226726. + int i, reg;
  226727. + int ret;
  226728. + u8 *cache = codec->reg_cache + 1;
  226729. +
  226730. + dev_dbg(codec->dev, "dump begin\n");
  226731. + dev_dbg(codec->dev, "reg value in cache\n");
  226732. + for (i = 0; i < CS42888_NUMREGS; i++)
  226733. + dev_dbg(codec->dev, "reg[%d] = 0x%x\n", i, cache[i]);
  226734. +
  226735. + dev_dbg(codec->dev, "real reg value\n");
  226736. + ret = cs42888_fill_cache(codec);
  226737. + if (ret < 0) {
  226738. + dev_err(codec->dev, "failed to fill register cache\n");
  226739. + return ret;
  226740. + }
  226741. + for (i = 0; i < CS42888_NUMREGS; i++)
  226742. + dev_dbg(codec->dev, "reg[%d] = 0x%x\n", i, cache[i]);
  226743. +
  226744. + dev_dbg(codec->dev, "dump end\n");
  226745. +}
  226746. +#else
  226747. +static void dump_reg(struct snd_soc_codec *codec)
  226748. +{
  226749. +}
  226750. +#endif
  226751. +
  226752. +/* -127.5dB to 0dB with step of 0.5dB */
  226753. +static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
  226754. +/* -64dB to 24dB with step of 0.5dB */
  226755. +static const DECLARE_TLV_DB_SCALE(adc_tlv, -6400, 50, 1);
  226756. +
  226757. +static int cs42888_out_vu(struct snd_kcontrol *kcontrol,
  226758. + struct snd_ctl_elem_value *ucontrol)
  226759. +{
  226760. + return snd_soc_put_volsw_2r(kcontrol, ucontrol);
  226761. +}
  226762. +
  226763. +static int cs42888_info_volsw_s8(struct snd_kcontrol *kcontrol,
  226764. + struct snd_ctl_elem_info *uinfo)
  226765. +{
  226766. + struct soc_mixer_control *mc =
  226767. + (struct soc_mixer_control *)kcontrol->private_value;
  226768. +
  226769. + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  226770. + uinfo->count = 2;
  226771. + uinfo->value.integer.min = 0;
  226772. + uinfo->value.integer.max = mc->max - mc->min;
  226773. + return 0;
  226774. +}
  226775. +
  226776. +static int cs42888_get_volsw_s8(struct snd_kcontrol *kcontrol,
  226777. + struct snd_ctl_elem_value *ucontrol)
  226778. +{
  226779. + struct soc_mixer_control *mc =
  226780. + (struct soc_mixer_control *)kcontrol->private_value;
  226781. + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  226782. + s8 val = snd_soc_read(codec, mc->reg);
  226783. + ucontrol->value.integer.value[0] = val - mc->min;
  226784. +
  226785. + val = snd_soc_read(codec, mc->rreg);
  226786. + ucontrol->value.integer.value[1] = val - mc->min;
  226787. + return 0;
  226788. +}
  226789. +
  226790. +int cs42888_put_volsw_s8(struct snd_kcontrol *kcontrol,
  226791. + struct snd_ctl_elem_value *ucontrol)
  226792. +{
  226793. + struct soc_mixer_control *mc =
  226794. + (struct soc_mixer_control *)kcontrol->private_value;
  226795. + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  226796. + unsigned short val;
  226797. + int ret;
  226798. +
  226799. + val = ucontrol->value.integer.value[0] + mc->min;
  226800. + ret = snd_soc_write(codec, mc->reg, val);
  226801. + if (ret < 0) {
  226802. + dev_err(codec->dev, "i2c write failed\n");
  226803. + return ret;
  226804. + }
  226805. +
  226806. + val = ucontrol->value.integer.value[1] + mc->min;
  226807. + ret = snd_soc_write(codec, mc->rreg, val);
  226808. + if (ret < 0) {
  226809. + dev_err(codec->dev, "i2c write failed\n");
  226810. + return ret;
  226811. + }
  226812. + return 0;
  226813. +}
  226814. +
  226815. +#define SOC_CS42888_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
  226816. + xinvert, tlv_array) \
  226817. +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  226818. + .name = (xname), \
  226819. + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
  226820. + SNDRV_CTL_ELEM_ACCESS_READWRITE, \
  226821. + .tlv.p = (tlv_array), \
  226822. + .info = snd_soc_info_volsw, \
  226823. + .get = snd_soc_get_volsw, \
  226824. + .put = cs42888_out_vu, \
  226825. + .private_value = (unsigned long)&(struct soc_mixer_control) \
  226826. + {.reg = reg_left, \
  226827. + .rreg = reg_right, \
  226828. + .shift = xshift, \
  226829. + .max = xmax, \
  226830. + .invert = xinvert} \
  226831. +}
  226832. +
  226833. +#define SOC_CS42888_DOUBLE_R_S8_TLV(xname, reg_left, reg_right, xmin, xmax, \
  226834. + tlv_array) \
  226835. +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
  226836. + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
  226837. + SNDRV_CTL_ELEM_ACCESS_READWRITE, \
  226838. + .tlv.p = (tlv_array), \
  226839. + .info = cs42888_info_volsw_s8, \
  226840. + .get = cs42888_get_volsw_s8, \
  226841. + .put = cs42888_put_volsw_s8, \
  226842. + .private_value = (unsigned long)&(struct soc_mixer_control) \
  226843. + {.reg = reg_left, \
  226844. + .rreg = reg_right, \
  226845. + .min = xmin, \
  226846. + .max = xmax} \
  226847. +}
  226848. +
  226849. +static const char *cs42888_adcfilter[] = { "None", "High Pass" };
  226850. +static const char *cs42888_dacinvert[] = { "Disabled", "Enabled" };
  226851. +static const char *cs42888_adcinvert[] = { "Disabled", "Enabled" };
  226852. +static const char *cs42888_dacamute[] = { "Disabled", "AutoMute" };
  226853. +static const char *cs42888_dac_sngvol[] = { "Disabled", "Enabled" };
  226854. +static const char *cs42888_dac_szc[] = { "Immediate Change", "Zero Cross",
  226855. + "Soft Ramp", "Soft Ramp on Zero Cross" };
  226856. +static const char *cs42888_mute_adc[] = { "UnMute", "Mute" };
  226857. +static const char *cs42888_adc_sngvol[] = { "Disabled", "Enabled" };
  226858. +static const char *cs42888_adc_szc[] = { "Immediate Change", "Zero Cross",
  226859. + "Soft Ramp", "Soft Ramp on Zero Cross" };
  226860. +static const char *cs42888_dac_dem[] = { "No-De-Emphasis", "De-Emphasis" };
  226861. +static const char *cs42888_adc_single[] = { "Differential", "Single-Ended" };
  226862. +
  226863. +static const struct soc_enum cs42888_enum[] = {
  226864. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 7, 2, cs42888_adcfilter),
  226865. + SOC_ENUM_DOUBLE(CS42888_DACINV, 0, 1, 2, cs42888_dacinvert),
  226866. + SOC_ENUM_DOUBLE(CS42888_DACINV, 2, 3, 2, cs42888_dacinvert),
  226867. + SOC_ENUM_DOUBLE(CS42888_DACINV, 4, 5, 2, cs42888_dacinvert),
  226868. + SOC_ENUM_DOUBLE(CS42888_DACINV, 6, 7, 2, cs42888_dacinvert),
  226869. + SOC_ENUM_DOUBLE(CS42888_ADCINV, 0, 1, 2, cs42888_adcinvert),
  226870. + SOC_ENUM_DOUBLE(CS42888_ADCINV, 2, 3, 2, cs42888_adcinvert),
  226871. + SOC_ENUM_SINGLE(CS42888_TRANS, 4, 2, cs42888_dacamute),
  226872. + SOC_ENUM_SINGLE(CS42888_TRANS, 7, 2, cs42888_dac_sngvol),
  226873. + SOC_ENUM_SINGLE(CS42888_TRANS, 5, 4, cs42888_dac_szc),
  226874. + SOC_ENUM_SINGLE(CS42888_TRANS, 3, 2, cs42888_mute_adc),
  226875. + SOC_ENUM_SINGLE(CS42888_TRANS, 2, 2, cs42888_adc_sngvol),
  226876. + SOC_ENUM_SINGLE(CS42888_TRANS, 0, 4, cs42888_adc_szc),
  226877. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 5, 2, cs42888_dac_dem),
  226878. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 4, 2, cs42888_adc_single),
  226879. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 3, 2, cs42888_adc_single),
  226880. +};
  226881. +
  226882. +static const struct snd_kcontrol_new cs42888_snd_controls[] = {
  226883. + SOC_CS42888_DOUBLE_R_TLV("DAC1 Playback Volume", CS42888_VOLAOUT1,
  226884. + CS42888_VOLAOUT2, 0, 0xff, 1, dac_tlv),
  226885. + SOC_CS42888_DOUBLE_R_TLV("DAC2 Playback Volume", CS42888_VOLAOUT3,
  226886. + CS42888_VOLAOUT4, 0, 0xff, 1, dac_tlv),
  226887. + SOC_CS42888_DOUBLE_R_TLV("DAC3 Playback Volume", CS42888_VOLAOUT5,
  226888. + CS42888_VOLAOUT6, 0, 0xff, 1, dac_tlv),
  226889. + SOC_CS42888_DOUBLE_R_TLV("DAC4 Playback Volume", CS42888_VOLAOUT7,
  226890. + CS42888_VOLAOUT8, 0, 0xff, 1, dac_tlv),
  226891. + SOC_CS42888_DOUBLE_R_S8_TLV("ADC1 Capture Volume", CS42888_VOLAIN1,
  226892. + CS42888_VOLAIN2, -128, 48, adc_tlv),
  226893. + SOC_CS42888_DOUBLE_R_S8_TLV("ADC2 Capture Volume", CS42888_VOLAIN3,
  226894. + CS42888_VOLAIN4, -128, 48, adc_tlv),
  226895. + SOC_ENUM("ADC High-Pass Filter Switch", cs42888_enum[0]),
  226896. + SOC_ENUM("DAC1 Invert Switch", cs42888_enum[1]),
  226897. + SOC_ENUM("DAC2 Invert Switch", cs42888_enum[2]),
  226898. + SOC_ENUM("DAC3 Invert Switch", cs42888_enum[3]),
  226899. + SOC_ENUM("DAC4 Invert Switch", cs42888_enum[4]),
  226900. + SOC_ENUM("ADC1 Invert Switch", cs42888_enum[5]),
  226901. + SOC_ENUM("ADC2 Invert Switch", cs42888_enum[6]),
  226902. + SOC_ENUM("DAC Auto Mute Switch", cs42888_enum[7]),
  226903. + SOC_ENUM("DAC Single Volume Control Switch", cs42888_enum[8]),
  226904. + SOC_ENUM("DAC Soft Ramp and Zero Cross Control Switch", cs42888_enum[9]),
  226905. + SOC_ENUM("Mute ADC Serial Port Switch", cs42888_enum[10]),
  226906. + SOC_ENUM("ADC Single Volume Control Switch", cs42888_enum[11]),
  226907. + SOC_ENUM("ADC Soft Ramp and Zero Cross Control Switch", cs42888_enum[12]),
  226908. + SOC_ENUM("DAC Deemphasis Switch", cs42888_enum[13]),
  226909. + SOC_ENUM("ADC1 Single Ended Mode Switch", cs42888_enum[14]),
  226910. + SOC_ENUM("ADC2 Single Ended Mode Switch", cs42888_enum[15]),
  226911. +};
  226912. +
  226913. +
  226914. +static const struct snd_soc_dapm_widget cs42888_dapm_widgets[] = {
  226915. + SND_SOC_DAPM_DAC("DAC1", "codec-Playback", CS42888_PWRCTL, 1, 1),
  226916. + SND_SOC_DAPM_DAC("DAC2", "codec-Playback", CS42888_PWRCTL, 2, 1),
  226917. + SND_SOC_DAPM_DAC("DAC3", "codec-Playback", CS42888_PWRCTL, 3, 1),
  226918. + SND_SOC_DAPM_DAC("DAC4", "codec-Playback", CS42888_PWRCTL, 4, 1),
  226919. +
  226920. + SND_SOC_DAPM_OUTPUT("AOUT1L"),
  226921. + SND_SOC_DAPM_OUTPUT("AOUT1R"),
  226922. + SND_SOC_DAPM_OUTPUT("AOUT2L"),
  226923. + SND_SOC_DAPM_OUTPUT("AOUT2R"),
  226924. + SND_SOC_DAPM_OUTPUT("AOUT3L"),
  226925. + SND_SOC_DAPM_OUTPUT("AOUT3R"),
  226926. + SND_SOC_DAPM_OUTPUT("AOUT4L"),
  226927. + SND_SOC_DAPM_OUTPUT("AOUT4R"),
  226928. +
  226929. + SND_SOC_DAPM_ADC("ADC1", "codec-Capture", CS42888_PWRCTL, 5, 1),
  226930. + SND_SOC_DAPM_ADC("ADC2", "codec-Capture", CS42888_PWRCTL, 6, 1),
  226931. +
  226932. + SND_SOC_DAPM_INPUT("AIN1L"),
  226933. + SND_SOC_DAPM_INPUT("AIN1R"),
  226934. + SND_SOC_DAPM_INPUT("AIN2L"),
  226935. + SND_SOC_DAPM_INPUT("AIN2R"),
  226936. +
  226937. + SND_SOC_DAPM_PGA_E("PWR", CS42888_PWRCTL, 0, 1, NULL, 0,
  226938. + NULL, 0),
  226939. +};
  226940. +
  226941. +static const struct snd_soc_dapm_route audio_map[] = {
  226942. + /* Playback */
  226943. + { "PWR", NULL, "DAC1" },
  226944. + { "PWR", NULL, "DAC1" },
  226945. +
  226946. + { "PWR", NULL, "DAC2" },
  226947. + { "PWR", NULL, "DAC2" },
  226948. +
  226949. + { "PWR", NULL, "DAC3" },
  226950. + { "PWR", NULL, "DAC3" },
  226951. +
  226952. + { "PWR", NULL, "DAC4" },
  226953. + { "PWR", NULL, "DAC4" },
  226954. +
  226955. + { "AOUT1L", NULL, "PWR" },
  226956. + { "AOUT1R", NULL, "PWR" },
  226957. +
  226958. + { "AOUT2L", NULL, "PWR" },
  226959. + { "AOUT2R", NULL, "PWR" },
  226960. +
  226961. + { "AOUT3L", NULL, "PWR" },
  226962. + { "AOUT3R", NULL, "PWR" },
  226963. +
  226964. + { "AOUT4L", NULL, "PWR" },
  226965. + { "AOUT4R", NULL, "PWR" },
  226966. +
  226967. + /* Capture */
  226968. + { "PWR", NULL, "AIN1L" },
  226969. + { "PWR", NULL, "AIN1R" },
  226970. +
  226971. + { "PWR", NULL, "AIN2L" },
  226972. + { "PWR", NULL, "AIN2R" },
  226973. +
  226974. + { "ADC1", NULL, "PWR" },
  226975. + { "ADC1", NULL, "PWR" },
  226976. +
  226977. + { "ADC2", NULL, "PWR" },
  226978. + { "ADC2", NULL, "PWR" },
  226979. +};
  226980. +
  226981. +
  226982. +static int cs42888_add_widgets(struct snd_soc_codec *codec)
  226983. +{
  226984. + snd_soc_dapm_new_controls(&codec->dapm, cs42888_dapm_widgets,
  226985. + ARRAY_SIZE(cs42888_dapm_widgets));
  226986. +
  226987. + snd_soc_dapm_add_routes(&codec->dapm, audio_map, ARRAY_SIZE(audio_map));
  226988. +
  226989. + snd_soc_dapm_new_widgets(&codec->dapm);
  226990. + return 0;
  226991. +}
  226992. +
  226993. +/**
  226994. + * struct cs42888_mode_ratios - clock ratio tables
  226995. + * @ratio: the ratio of MCLK to the sample rate
  226996. + * @speed_mode: the Speed Mode bits to set in the Mode Control register for
  226997. + * this ratio
  226998. + * @mclk: the Ratio Select bits to set in the Mode Control register for this
  226999. + * ratio
  227000. + *
  227001. + * The data for this chart is taken from Table 10 of the CS42888 reference
  227002. + * manual.
  227003. + *
  227004. + * This table is used to determine how to program the Functional Mode register.
  227005. + * It is also used by cs42888_set_dai_sysclk() to tell ALSA which sampling
  227006. + * rates the CS42888 currently supports.
  227007. + *
  227008. + * @speed_mode is the corresponding bit pattern to be written to the
  227009. + * MODE bits of the Mode Control Register
  227010. + *
  227011. + * @mclk is the corresponding bit pattern to be wirten to the MCLK bits of
  227012. + * the Mode Control Register.
  227013. + *
  227014. + */
  227015. +struct cs42888_mode_ratios {
  227016. + unsigned int ratio;
  227017. + u8 speed_mode;
  227018. + u8 mclk;
  227019. +};
  227020. +
  227021. +static struct cs42888_mode_ratios cs42888_mode_ratios[] = {
  227022. + {64, CS42888_MODE_4X, CS42888_MODE_DIV1},
  227023. + {96, CS42888_MODE_4X, CS42888_MODE_DIV2},
  227024. + {128, CS42888_MODE_2X, CS42888_MODE_DIV1},
  227025. + {192, CS42888_MODE_2X, CS42888_MODE_DIV2},
  227026. + {256, CS42888_MODE_1X, CS42888_MODE_DIV1},
  227027. + {384, CS42888_MODE_2X, CS42888_MODE_DIV4},
  227028. + {512, CS42888_MODE_1X, CS42888_MODE_DIV3},
  227029. + {768, CS42888_MODE_1X, CS42888_MODE_DIV4},
  227030. + {1024, CS42888_MODE_1X, CS42888_MODE_DIV5}
  227031. +};
  227032. +
  227033. +/* The number of MCLK/LRCK ratios supported by the CS42888 */
  227034. +#define NUM_MCLK_RATIOS ARRAY_SIZE(cs42888_mode_ratios)
  227035. +
  227036. +/**
  227037. + * cs42888_set_dai_sysclk - determine the CS42888 samples rates.
  227038. + * @codec_dai: the codec DAI
  227039. + * @clk_id: the clock ID (ignored)
  227040. + * @freq: the MCLK input frequency
  227041. + * @dir: the clock direction (ignored)
  227042. + *
  227043. + * This function is used to tell the codec driver what the input MCLK
  227044. + * frequency is.
  227045. + *
  227046. + */
  227047. +static int cs42888_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  227048. + int clk_id, unsigned int freq, int dir)
  227049. +{
  227050. + struct snd_soc_codec *codec = codec_dai->codec;
  227051. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  227052. +
  227053. + cs42888->mclk = freq;
  227054. + return 0;
  227055. +}
  227056. +
  227057. +/**
  227058. + * cs42888_set_dai_fmt - configure the codec for the selected audio format
  227059. + * @codec_dai: the codec DAI
  227060. + * @format: a SND_SOC_DAIFMT_x value indicating the data format
  227061. + *
  227062. + * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the
  227063. + * codec accordingly.
  227064. + *
  227065. + * Currently, this function only supports SND_SOC_DAIFMT_I2S and
  227066. + * SND_SOC_DAIFMT_LEFT_J. The CS42888 codec also supports right-justified
  227067. + * data for playback only, but ASoC currently does not support different
  227068. + * formats for playback vs. record.
  227069. + */
  227070. +static int cs42888_set_dai_fmt(struct snd_soc_dai *codec_dai,
  227071. + unsigned int format)
  227072. +{
  227073. + struct snd_soc_codec *codec = codec_dai->codec;
  227074. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  227075. + int ret = 0;
  227076. + u8 val;
  227077. +
  227078. + val = snd_soc_read(codec, CS42888_FORMAT);
  227079. + val &= ~CS42888_FORMAT_DAC_DIF_MASK;
  227080. + val &= ~CS42888_FORMAT_ADC_DIF_MASK;
  227081. + /* set DAI format */
  227082. + switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
  227083. + case SND_SOC_DAIFMT_LEFT_J:
  227084. + val |= DIF_LEFT_J << CS42888_FORMAT_DAC_DIF_OFFSET;
  227085. + val |= DIF_LEFT_J << CS42888_FORMAT_ADC_DIF_OFFSET;
  227086. + break;
  227087. + case SND_SOC_DAIFMT_I2S:
  227088. + val |= DIF_I2S << CS42888_FORMAT_DAC_DIF_OFFSET;
  227089. + val |= DIF_I2S << CS42888_FORMAT_ADC_DIF_OFFSET;
  227090. + break;
  227091. + case SND_SOC_DAIFMT_RIGHT_J:
  227092. + val |= DIF_RIGHT_J << CS42888_FORMAT_DAC_DIF_OFFSET;
  227093. + val |= DIF_RIGHT_J << CS42888_FORMAT_ADC_DIF_OFFSET;
  227094. + break;
  227095. + default:
  227096. + dev_err(codec->dev, "invalid dai format\n");
  227097. + return -EINVAL;
  227098. + }
  227099. +
  227100. + ret = snd_soc_write(codec, CS42888_FORMAT, val);
  227101. + if (ret < 0) {
  227102. + dev_err(codec->dev, "i2c write failed\n");
  227103. + return ret;
  227104. + }
  227105. +
  227106. + val = snd_soc_read(codec, CS42888_MODE);
  227107. + /* set master/slave audio interface */
  227108. + switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
  227109. + case SND_SOC_DAIFMT_CBS_CFS:
  227110. + cs42888->slave_mode = 1;
  227111. + val &= ~CS42888_MODE_SPEED_MASK;
  227112. + val |= CS42888_MODE_SLAVE;
  227113. + break;
  227114. + case SND_SOC_DAIFMT_CBM_CFM:
  227115. + cs42888->slave_mode = 0;
  227116. + break;
  227117. + default:
  227118. + /* all other modes are unsupported by the hardware */
  227119. + return -EINVAL;
  227120. + }
  227121. +
  227122. + ret = snd_soc_write(codec, CS42888_MODE, val);
  227123. + if (ret < 0) {
  227124. + dev_err(codec->dev, "i2c write failed\n");
  227125. + return ret;
  227126. + }
  227127. +
  227128. + dump_reg(codec);
  227129. + return ret;
  227130. +}
  227131. +
  227132. +/**
  227133. + * cs42888_hw_params - program the CS42888 with the given hardware parameters.
  227134. + * @substream: the audio stream
  227135. + * @params: the hardware parameters to set
  227136. +
  227137. + * @dai: the SOC DAI (ignored)
  227138. + *
  227139. + * This function programs the hardware with the values provided.
  227140. + * Specifically, the sample rate and the data format.
  227141. + *
  227142. + * The .ops functions are used to provide board-specific data, like input
  227143. + * frequencies, to this driver. This function takes that information,
  227144. + * combines it with the hardware parameters provided, and programs the
  227145. + * hardware accordingly.
  227146. + */
  227147. +static int cs42888_hw_params(struct snd_pcm_substream *substream,
  227148. + struct snd_pcm_hw_params *params,
  227149. + struct snd_soc_dai *dai)
  227150. +{
  227151. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  227152. + struct snd_soc_codec *codec = rtd->codec;
  227153. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  227154. + int ret;
  227155. + u32 i, rate, ratio, val;
  227156. +
  227157. + rate = params_rate(params); /* Sampling rate, in Hz */
  227158. + ratio = cs42888->mclk / rate; /* MCLK/LRCK ratio */
  227159. + for (i = 0; i < NUM_MCLK_RATIOS; i++) {
  227160. + if (cs42888_mode_ratios[i].ratio == ratio)
  227161. + break;
  227162. + }
  227163. +
  227164. + if (i == NUM_MCLK_RATIOS) {
  227165. + /* We did not find a matching ratio */
  227166. + dev_err(codec->dev, "could not find matching ratio\n");
  227167. + return -EINVAL;
  227168. + }
  227169. +
  227170. + if (!cs42888->slave_mode) {
  227171. + val = snd_soc_read(codec, CS42888_MODE);
  227172. + val &= ~CS42888_MODE_SPEED_MASK;
  227173. + val |= cs42888_mode_ratios[i].speed_mode;
  227174. + val &= ~CS42888_MODE_DIV_MASK;
  227175. + val |= cs42888_mode_ratios[i].mclk;
  227176. + } else {
  227177. + val = snd_soc_read(codec, CS42888_MODE);
  227178. + val &= ~CS42888_MODE_SPEED_MASK;
  227179. + val |= CS42888_MODE_SLAVE;
  227180. + val &= ~CS42888_MODE_DIV_MASK;
  227181. + val |= cs42888_mode_ratios[i].mclk;
  227182. + }
  227183. + ret = snd_soc_write(codec, CS42888_MODE, val);
  227184. + if (ret < 0) {
  227185. + dev_err(codec->dev, "i2c write failed\n");
  227186. + return ret;
  227187. + }
  227188. +
  227189. + /* Unmute all the channels */
  227190. + val = snd_soc_read(codec, CS42888_MUTE);
  227191. + val &= ~CS42888_MUTE_ALL;
  227192. + ret = snd_soc_write(codec, CS42888_MUTE, val);
  227193. + if (ret < 0) {
  227194. + dev_err(codec->dev, "i2c write failed\n");
  227195. + return ret;
  227196. + }
  227197. +
  227198. + ret = cs42888_fill_cache(codec);
  227199. + if (ret < 0) {
  227200. + dev_err(codec->dev, "failed to fill register cache\n");
  227201. + return ret;
  227202. + }
  227203. +
  227204. + dump_reg(codec);
  227205. + return ret;
  227206. +}
  227207. +
  227208. +/**
  227209. + * cs42888_shutdown - cs42888 enters into low power mode again.
  227210. + * @substream: the audio stream
  227211. + * @dai: the SOC DAI (ignored)
  227212. + *
  227213. + * The .ops functions are used to provide board-specific data, like input
  227214. + * frequencies, to this driver. This function takes that information,
  227215. + * combines it with the hardware parameters provided, and programs the
  227216. + * hardware accordingly.
  227217. + */
  227218. +static void cs42888_shutdown(struct snd_pcm_substream *substream,
  227219. + struct snd_soc_dai *dai)
  227220. +{
  227221. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  227222. + struct snd_soc_codec *codec = rtd->codec;
  227223. + int ret;
  227224. + u8 val;
  227225. +
  227226. + /* Mute all the channels */
  227227. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  227228. + val = snd_soc_read(codec, CS42888_MUTE);
  227229. + val |= CS42888_MUTE_ALL;
  227230. + ret = snd_soc_write(codec, CS42888_MUTE, val);
  227231. + if (ret < 0)
  227232. + dev_err(codec->dev, "i2c write failed\n");
  227233. + }
  227234. +}
  227235. +
  227236. +static int cs42888_prepare(struct snd_pcm_substream *substream,
  227237. + struct snd_soc_dai *dai)
  227238. +{
  227239. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  227240. + struct snd_soc_card *card = rtd->card;
  227241. + struct snd_soc_dai *tmp_codec_dai;
  227242. + struct snd_soc_pcm_runtime *tmp_rtd;
  227243. + u32 i;
  227244. +
  227245. + for (i = 0; i < card->num_rtd; i++) {
  227246. + tmp_codec_dai = card->rtd[i].codec_dai;
  227247. + tmp_rtd = (struct snd_soc_pcm_runtime *)(card->rtd + i);
  227248. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  227249. + cancel_delayed_work(&tmp_rtd->delayed_work);
  227250. + }
  227251. + return 0;
  227252. +}
  227253. +
  227254. +static struct snd_soc_dai_ops cs42888_dai_ops = {
  227255. + .set_fmt = cs42888_set_dai_fmt,
  227256. + .set_sysclk = cs42888_set_dai_sysclk,
  227257. + .hw_params = cs42888_hw_params,
  227258. + .shutdown = cs42888_shutdown,
  227259. + .prepare = cs42888_prepare,
  227260. +};
  227261. +
  227262. +
  227263. +static struct snd_soc_dai_driver cs42888_dai = {
  227264. + .name = "CS42888",
  227265. + .playback = {
  227266. + .stream_name = "codec-Playback",
  227267. + .channels_min = 2,
  227268. + .channels_max = 8,
  227269. + .rates = SNDRV_PCM_RATE_8000_192000,
  227270. + .formats = CS42888_FORMATS,
  227271. + },
  227272. + .capture = {
  227273. + .stream_name = "codec-Capture",
  227274. + .channels_min = 2,
  227275. + .channels_max = 4,
  227276. + .rates = SNDRV_PCM_RATE_8000_192000,
  227277. + .formats = CS42888_FORMATS,
  227278. + },
  227279. + .ops = &cs42888_dai_ops,
  227280. +};
  227281. +
  227282. +/**
  227283. + * cs42888_probe - ASoC probe function
  227284. + * @pdev: platform device
  227285. + *
  227286. + * This function is called when ASoC has all the pieces it needs to
  227287. + * instantiate a sound driver.
  227288. + */
  227289. +static int cs42888_probe(struct snd_soc_codec *codec)
  227290. +{
  227291. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  227292. + int ret, i, val;
  227293. +
  227294. + cs42888->codec = codec;
  227295. + /* setup i2c data ops */
  227296. + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
  227297. + if (ret < 0) {
  227298. + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
  227299. + return ret;
  227300. + }
  227301. +
  227302. + for (i = 0; i < ARRAY_SIZE(cs42888->supplies); i++)
  227303. + cs42888->supplies[i].supply = cs42888_supply_names[i];
  227304. +
  227305. + ret = devm_regulator_bulk_get(codec->dev,
  227306. + ARRAY_SIZE(cs42888->supplies), cs42888->supplies);
  227307. + if (ret) {
  227308. + dev_err(codec->dev, "Failed to request supplies: %d\n",
  227309. + ret);
  227310. + return ret;
  227311. + }
  227312. +
  227313. + ret = regulator_bulk_enable(ARRAY_SIZE(cs42888->supplies),
  227314. + cs42888->supplies);
  227315. + if (ret) {
  227316. + dev_err(codec->dev, "Failed to enable supplies: %d\n",
  227317. + ret);
  227318. + goto err;
  227319. + }
  227320. + msleep(1);
  227321. +
  227322. + /* The I2C interface is set up, so pre-fill our register cache */
  227323. + ret = cs42888_fill_cache(codec);
  227324. + if (ret < 0) {
  227325. + dev_err(codec->dev, "failed to fill register cache\n");
  227326. + goto err;
  227327. + }
  227328. +
  227329. + /* Enter low power state */
  227330. + val = snd_soc_read(codec, CS42888_PWRCTL);
  227331. + val |= CS42888_PWRCTL_PDN_MASK;
  227332. + ret = snd_soc_write(codec, CS42888_PWRCTL, val);
  227333. + if (ret < 0) {
  227334. + dev_err(codec->dev, "i2c write failed\n");
  227335. + goto err;
  227336. + }
  227337. +
  227338. + /* Disable auto-mute */
  227339. + val = snd_soc_read(codec, CS42888_TRANS);
  227340. + val &= ~CS42888_TRANS_AMUTE_MASK;
  227341. + val &= ~CS42888_TRANS_DAC_SZC_MASK;
  227342. + val |= CS42888_TRANS_DAC_SZC_SR;
  227343. + ret = snd_soc_write(codec, CS42888_TRANS, val);
  227344. + if (ret < 0) {
  227345. + dev_err(codec->dev, "i2c write failed\n");
  227346. + goto err;
  227347. + }
  227348. + /* Add the non-DAPM controls */
  227349. + snd_soc_add_codec_controls(codec, cs42888_snd_controls,
  227350. + ARRAY_SIZE(cs42888_snd_controls));
  227351. +
  227352. + /* Add DAPM controls */
  227353. + cs42888_add_widgets(codec);
  227354. + return 0;
  227355. +err:
  227356. + regulator_bulk_disable(ARRAY_SIZE(cs42888->supplies),
  227357. + cs42888->supplies);
  227358. + return ret;
  227359. +}
  227360. +
  227361. +/**
  227362. + * cs42888_remove - ASoC remove function
  227363. + * @pdev: platform device
  227364. + *
  227365. + * This function is the counterpart to cs42888_probe().
  227366. + */
  227367. +static int cs42888_remove(struct snd_soc_codec *codec)
  227368. +{
  227369. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  227370. +
  227371. + regulator_bulk_disable(ARRAY_SIZE(cs42888->supplies),
  227372. + cs42888->supplies);
  227373. +
  227374. + return 0;
  227375. +};
  227376. +
  227377. +/*
  227378. + * ASoC codec device structure
  227379. + *
  227380. + * Assign this variable to the codec_dev field of the machine driver's
  227381. + * snd_soc_device structure.
  227382. + */
  227383. +static struct snd_soc_codec_driver cs42888_driver = {
  227384. + .probe = cs42888_probe,
  227385. + .remove = cs42888_remove,
  227386. + .reg_cache_size = CS42888_NUMREGS + 1,
  227387. + .reg_word_size = sizeof(u8),
  227388. + .reg_cache_step = 1,
  227389. +};
  227390. +
  227391. +/**
  227392. + * cs42888_i2c_probe - initialize the I2C interface of the CS42888
  227393. + * @i2c_client: the I2C client object
  227394. + * @id: the I2C device ID (ignored)
  227395. + *
  227396. + * This function is called whenever the I2C subsystem finds a device that
  227397. + * matches the device ID given via a prior call to i2c_add_driver().
  227398. + */
  227399. +static int cs42888_i2c_probe(struct i2c_client *i2c_client,
  227400. + const struct i2c_device_id *id)
  227401. +{
  227402. + struct cs42888_private *cs42888;
  227403. + int ret, val;
  227404. +
  227405. + /* Verify that we have a CS42888 */
  227406. + val = i2c_smbus_read_byte_data(i2c_client, CS42888_CHIPID);
  227407. + if (val < 0) {
  227408. + dev_err(&i2c_client->dev, "Device with ID register %x is not a CS42888", val);
  227409. + return -ENODEV;
  227410. + }
  227411. + /* The top four bits of the chip ID should be 0000. */
  227412. + if ((val & CS42888_CHIPID_ID_MASK) != 0x00) {
  227413. + dev_err(&i2c_client->dev, "device is not a CS42888\n");
  227414. + return -ENODEV;
  227415. + }
  227416. +
  227417. + dev_info(&i2c_client->dev, "found device at i2c address %X\n",
  227418. + i2c_client->addr);
  227419. + dev_info(&i2c_client->dev, "hardware revision %X\n", val & 0xF);
  227420. +
  227421. + /* Allocate enough space for the snd_soc_codec structure
  227422. + and our private data together. */
  227423. + cs42888 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42888_private), GFP_KERNEL);
  227424. + if (!cs42888) {
  227425. + dev_err(&i2c_client->dev, "could not allocate codec\n");
  227426. + return -ENOMEM;
  227427. + }
  227428. +
  227429. + i2c_set_clientdata(i2c_client, cs42888);
  227430. +
  227431. + cs42888->clk = devm_clk_get(&i2c_client->dev, NULL);
  227432. + if (IS_ERR(cs42888->clk)) {
  227433. + ret = PTR_ERR(cs42888->clk);
  227434. + dev_err(&i2c_client->dev, "Cannot get the clock: %d\n", ret);
  227435. + return ret;
  227436. + }
  227437. +
  227438. + cs42888->mclk = clk_get_rate(cs42888->clk);
  227439. + switch (cs42888->mclk) {
  227440. + case 24576000:
  227441. + cs42888_dai.playback.rates = SNDRV_PCM_RATE_48000 |
  227442. + SNDRV_PCM_RATE_96000 |
  227443. + SNDRV_PCM_RATE_192000;
  227444. + cs42888_dai.capture.rates = SNDRV_PCM_RATE_48000 |
  227445. + SNDRV_PCM_RATE_96000 |
  227446. + SNDRV_PCM_RATE_192000;
  227447. + break;
  227448. + case 16934400:
  227449. + cs42888_dai.playback.rates = SNDRV_PCM_RATE_44100 |
  227450. + SNDRV_PCM_RATE_88200 |
  227451. + SNDRV_PCM_RATE_176400;
  227452. + cs42888_dai.capture.rates = SNDRV_PCM_RATE_44100 |
  227453. + SNDRV_PCM_RATE_88200 |
  227454. + SNDRV_PCM_RATE_176400;
  227455. + break;
  227456. + default:
  227457. + dev_err(&i2c_client->dev, "codec mclk is not supported %d\n", cs42888->mclk);
  227458. + break;
  227459. + }
  227460. +
  227461. + ret = snd_soc_register_codec(&i2c_client->dev,
  227462. + &cs42888_driver, &cs42888_dai, 1);
  227463. + if (ret) {
  227464. + dev_err(&i2c_client->dev, "Failed to register codec:%d\n", ret);
  227465. + return ret;
  227466. + }
  227467. + return 0;
  227468. +}
  227469. +
  227470. +/**
  227471. + * cs42888_i2c_remove - remove an I2C device
  227472. + * @i2c_client: the I2C client object
  227473. + *
  227474. + * This function is the counterpart to cs42888_i2c_probe().
  227475. + */
  227476. +static int cs42888_i2c_remove(struct i2c_client *i2c_client)
  227477. +{
  227478. + snd_soc_unregister_codec(&i2c_client->dev);
  227479. + return 0;
  227480. +}
  227481. +
  227482. +/*
  227483. + * cs42888_i2c_id - I2C device IDs supported by this driver
  227484. + */
  227485. +static struct i2c_device_id cs42888_i2c_id[] = {
  227486. + {"cs42888", 0},
  227487. + {}
  227488. +};
  227489. +MODULE_DEVICE_TABLE(i2c, cs42888_i2c_id);
  227490. +
  227491. +#ifdef CONFIG_PM
  227492. +/* This suspend/resume implementation can handle both - a simple standby
  227493. + * where the codec remains powered, and a full suspend, where the voltage
  227494. + * domain the codec is connected to is teared down and/or any other hardware
  227495. + * reset condition is asserted.
  227496. + *
  227497. + * The codec's own power saving features are enabled in the suspend callback,
  227498. + * and all registers are written back to the hardware when resuming.
  227499. + */
  227500. +
  227501. +static int cs42888_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
  227502. +{
  227503. + struct cs42888_private *cs42888 = i2c_get_clientdata(client);
  227504. + struct snd_soc_codec *codec = cs42888->codec;
  227505. + int reg = snd_soc_read(codec, CS42888_PWRCTL) | CS42888_PWRCTL_PDN_MASK;
  227506. + return snd_soc_write(codec, CS42888_PWRCTL, reg);
  227507. +}
  227508. +
  227509. +static int cs42888_i2c_resume(struct i2c_client *client)
  227510. +{
  227511. + struct cs42888_private *cs42888 = i2c_get_clientdata(client);
  227512. + struct snd_soc_codec *codec = cs42888->codec;
  227513. + int reg;
  227514. +
  227515. + /* In case the device was put to hard reset during sleep, we need to
  227516. + * wait 500ns here before any I2C communication. */
  227517. + ndelay(500);
  227518. +
  227519. + /* first restore the entire register cache ... */
  227520. + for (reg = CS42888_FIRSTREG; reg <= CS42888_LASTREG; reg++) {
  227521. + u8 val = snd_soc_read(codec, reg);
  227522. +
  227523. + if (i2c_smbus_write_byte_data(client, reg, val)) {
  227524. + dev_err(codec->dev, "i2c write failed\n");
  227525. + return -EIO;
  227526. + }
  227527. + }
  227528. +
  227529. + /* ... then disable the power-down bits */
  227530. + reg = snd_soc_read(codec, CS42888_PWRCTL);
  227531. + reg &= ~CS42888_PWRCTL_PDN_MASK;
  227532. + return snd_soc_write(codec, CS42888_PWRCTL, reg);
  227533. +}
  227534. +#else
  227535. +#define cs42888_i2c_suspend NULL
  227536. +#define cs42888_i2c_resume NULL
  227537. +#endif /* CONFIG_PM */
  227538. +
  227539. +/*
  227540. + * cs42888_i2c_driver - I2C device identification
  227541. + *
  227542. + * This structure tells the I2C subsystem how to identify and support a
  227543. + * given I2C device type.
  227544. + */
  227545. +
  227546. +static const struct of_device_id cs42888_dt_ids[] = {
  227547. + { .compatible = "cirrus,cs42888", },
  227548. + { /* sentinel */ }
  227549. +};
  227550. +
  227551. +static struct i2c_driver cs42888_i2c_driver = {
  227552. + .driver = {
  227553. + .name = "cs42888",
  227554. + .owner = THIS_MODULE,
  227555. + .of_match_table = cs42888_dt_ids,
  227556. + },
  227557. + .probe = cs42888_i2c_probe,
  227558. + .remove = cs42888_i2c_remove,
  227559. + .suspend = cs42888_i2c_suspend,
  227560. + .resume = cs42888_i2c_resume,
  227561. + .id_table = cs42888_i2c_id,
  227562. +};
  227563. +
  227564. +module_i2c_driver(cs42888_i2c_driver);
  227565. +
  227566. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  227567. +MODULE_DESCRIPTION("Cirrus Logic CS42888 ALSA SoC Codec Driver");
  227568. +MODULE_LICENSE("GPL");
  227569. diff -Nur linux-3.14.15/sound/soc/codecs/cs42888.h linux-linaro-stable-mx6/sound/soc/codecs/cs42888.h
  227570. --- linux-3.14.15/sound/soc/codecs/cs42888.h 1970-01-01 01:00:00.000000000 +0100
  227571. +++ linux-linaro-stable-mx6/sound/soc/codecs/cs42888.h 2014-08-20 19:24:09.490913864 +0200
  227572. @@ -0,0 +1,123 @@
  227573. +/*
  227574. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  227575. + */
  227576. +
  227577. +/*
  227578. + * The code contained herein is licensed under the GNU General Public
  227579. + * License. You may obtain a copy of the GNU General Public License
  227580. + * Version 2 or later at the following locations:
  227581. + *
  227582. + * http://www.opensource.org/licenses/gpl-license.html
  227583. + * http://www.gnu.org/copyleft/gpl.html
  227584. + */
  227585. +
  227586. +#ifndef _CS42888_H
  227587. +#define _CS42888_H
  227588. +
  227589. +/* CS42888 registers addresses */
  227590. +#define CS42888_CHIPID 0x01 /* Chip ID */
  227591. +#define CS42888_PWRCTL 0x02 /* Power Control */
  227592. +#define CS42888_MODE 0x03 /* Functional Mode */
  227593. +#define CS42888_FORMAT 0x04 /* Interface Formats */
  227594. +#define CS42888_ADCCTL 0x05 /* ADC Control */
  227595. +#define CS42888_TRANS 0x06 /* Transition Control */
  227596. +#define CS42888_MUTE 0x07 /* Mute Control */
  227597. +#define CS42888_VOLAOUT1 0x08 /* Volume Control AOUT1*/
  227598. +#define CS42888_VOLAOUT2 0x09 /* Volume Control AOUT2*/
  227599. +#define CS42888_VOLAOUT3 0x0A /* Volume Control AOUT3*/
  227600. +#define CS42888_VOLAOUT4 0x0B /* Volume Control AOUT4*/
  227601. +#define CS42888_VOLAOUT5 0x0C /* Volume Control AOUT5*/
  227602. +#define CS42888_VOLAOUT6 0x0D /* Volume Control AOUT6*/
  227603. +#define CS42888_VOLAOUT7 0x0E /* Volume Control AOUT7*/
  227604. +#define CS42888_VOLAOUT8 0x0F /* Volume Control AOUT8*/
  227605. +#define CS42888_DACINV 0x10 /* DAC Channel Invert */
  227606. +#define CS42888_VOLAIN1 0x11 /* Volume Control AIN1 */
  227607. +#define CS42888_VOLAIN2 0x12 /* Volume Control AIN2 */
  227608. +#define CS42888_VOLAIN3 0x13 /* Volume Control AIN3 */
  227609. +#define CS42888_VOLAIN4 0x14 /* Volume Control AIN4 */
  227610. +#define CS42888_ADCINV 0x17 /* ADC Channel Invert */
  227611. +#define CS42888_STATUSCTL 0x18 /* Status Control */
  227612. +#define CS42888_STATUS 0x19 /* Status */
  227613. +#define CS42888_STATUSMASK 0x1A /* Status Mask */
  227614. +
  227615. +#define CS42888_FIRSTREG 0x01
  227616. +#define CS42888_LASTREG 0x1A
  227617. +#define CS42888_NUMREGS (CS42888_LASTREG - CS42888_FIRSTREG + 1)
  227618. +#define CS42888_I2C_INCR 0x80
  227619. +
  227620. +/* Bit masks for the CS42888 registers */
  227621. +#define CS42888_CHIPID_ID_MASK 0xF0
  227622. +#define CS42888_CHIPID_REV 0x0F
  227623. +#define CS42888_PWRCTL_PDN_ADC2_OFFSET 6
  227624. +#define CS42888_PWRCTL_PDN_ADC1_OFFSET 5
  227625. +#define CS42888_PWRCTL_PDN_DAC4_OFFSET 4
  227626. +#define CS42888_PWRCTL_PDN_DAC3_OFFSET 3
  227627. +#define CS42888_PWRCTL_PDN_DAC2_OFFSET 2
  227628. +#define CS42888_PWRCTL_PDN_DAC1_OFFSET 1
  227629. +#define CS42888_PWRCTL_PDN_OFFSET 0
  227630. +#define CS42888_PWRCTL_PDN_ADC2_MASK (1 << CS42888_PWRCTL_PDN_ADC2_OFFSET)
  227631. +#define CS42888_PWRCTL_PDN_ADC1_MASK (1 << CS42888_PWRCTL_PDN_ADC1_OFFSET)
  227632. +#define CS42888_PWRCTL_PDN_DAC4_MASK (1 << CS42888_PWRCTL_PDN_DAC4_OFFSET)
  227633. +#define CS42888_PWRCTL_PDN_DAC3_MASK (1 << CS42888_PWRCTL_PDN_DAC3_OFFSET)
  227634. +#define CS42888_PWRCTL_PDN_DAC2_MASK (1 << CS42888_PWRCTL_PDN_DAC2_OFFSET)
  227635. +#define CS42888_PWRCTL_PDN_DAC1_MASK (1 << CS42888_PWRCTL_PDN_DAC1_OFFSET)
  227636. +#define CS42888_PWRCTL_PDN_MASK (1 << CS42888_PWRCTL_PDN_OFFSET)
  227637. +
  227638. +#define CS42888_MODE_SPEED_MASK 0xF0
  227639. +#define CS42888_MODE_1X 0x00
  227640. +#define CS42888_MODE_2X 0x50
  227641. +#define CS42888_MODE_4X 0xA0
  227642. +#define CS42888_MODE_SLAVE 0xF0
  227643. +#define CS42888_MODE_DIV_MASK 0x0E
  227644. +#define CS42888_MODE_DIV1 0x00
  227645. +#define CS42888_MODE_DIV2 0x02
  227646. +#define CS42888_MODE_DIV3 0x04
  227647. +#define CS42888_MODE_DIV4 0x06
  227648. +#define CS42888_MODE_DIV5 0x08
  227649. +
  227650. +#define CS42888_FORMAT_FREEZE_OFFSET 7
  227651. +#define CS42888_FORMAT_AUX_DIF_OFFSET 6
  227652. +#define CS42888_FORMAT_DAC_DIF_OFFSET 3
  227653. +#define CS42888_FORMAT_ADC_DIF_OFFSET 0
  227654. +#define CS42888_FORMAT_FREEZE_MASK (1 << CS42888_FORMAT_FREEZE_OFFSET)
  227655. +#define CS42888_FORMAT_AUX_DIF_MASK (1 << CS42888_FORMAT_AUX_DIF_OFFSET)
  227656. +#define CS42888_FORMAT_DAC_DIF_MASK (7 << CS42888_FORMAT_DAC_DIF_OFFSET)
  227657. +#define CS42888_FORMAT_ADC_DIF_MASK (7 << CS42888_FORMAT_ADC_DIF_OFFSET)
  227658. +
  227659. +#define CS42888_TRANS_DAC_SNGVOL_OFFSET 7
  227660. +#define CS42888_TRANS_DAC_SZC_OFFSET 5
  227661. +#define CS42888_TRANS_AMUTE_OFFSET 4
  227662. +#define CS42888_TRANS_MUTE_ADC_SP_OFFSET 3
  227663. +#define CS42888_TRANS_ADC_SNGVOL_OFFSET 2
  227664. +#define CS42888_TRANS_ADC_SZC_OFFSET 0
  227665. +#define CS42888_TRANS_DAC_SNGVOL_MASK (1 << CS42888_TRANS_DAC_SNGVOL_OFFSET)
  227666. +#define CS42888_TRANS_DAC_SZC_MASK (3 << CS42888_TRANS_DAC_SZC_OFFSET)
  227667. +#define CS42888_TRANS_AMUTE_MASK (1 << CS42888_TRANS_AMUTE_OFFSET)
  227668. +#define CS42888_TRANS_MUTE_ADC_SP_MASK (1 << CS42888_TRANS_MUTE_ADC_SP_OFFSET)
  227669. +#define CS42888_TRANS_ADC_SNGVOL_MASK (1 << CS42888_TRANS_ADC_SNGVOL_OFFSET)
  227670. +#define CS42888_TRANS_ADC_SZC_MASK (3 << CS42888_TRANS_ADC_SZC_OFFSET)
  227671. +#define CS42888_TRANS_DAC_SZC_IC (0 << CS42888_TRANS_DAC_SZC_OFFSET)
  227672. +#define CS42888_TRANS_DAC_SZC_ZC (1 << CS42888_TRANS_DAC_SZC_OFFSET)
  227673. +#define CS42888_TRANS_DAC_SZC_SR (2 << CS42888_TRANS_DAC_SZC_OFFSET)
  227674. +#define CS42888_TRANS_DAC_SZC_SRZC (3 << CS42888_TRANS_DAC_SZC_OFFSET)
  227675. +
  227676. +#define CS42888_MUTE_AOUT8 (0x1 << 7)
  227677. +#define CS42888_MUTE_AOUT7 (0x1 << 6)
  227678. +#define CS42888_MUTE_AOUT6 (0x1 << 5)
  227679. +#define CS42888_MUTE_AOUT5 (0x1 << 4)
  227680. +#define CS42888_MUTE_AOUT4 (0x1 << 3)
  227681. +#define CS42888_MUTE_AOUT3 (0x1 << 2)
  227682. +#define CS42888_MUTE_AOUT2 (0x1 << 1)
  227683. +#define CS42888_MUTE_AOUT1 (0x1 << 0)
  227684. +#define CS42888_MUTE_ALL (CS42888_MUTE_AOUT1 | CS42888_MUTE_AOUT2 | \
  227685. + CS42888_MUTE_AOUT3 | CS42888_MUTE_AOUT4 | \
  227686. + CS42888_MUTE_AOUT5 | CS42888_MUTE_AOUT6 | \
  227687. + CS42888_MUTE_AOUT7 | CS42888_MUTE_AOUT8)
  227688. +
  227689. +#define DIF_LEFT_J 0
  227690. +#define DIF_I2S 1
  227691. +#define DIF_RIGHT_J 2
  227692. +#define DIF_TDM 6
  227693. +
  227694. +
  227695. +#endif
  227696. diff -Nur linux-3.14.15/sound/soc/codecs/Kconfig linux-linaro-stable-mx6/sound/soc/codecs/Kconfig
  227697. --- linux-3.14.15/sound/soc/codecs/Kconfig 2014-07-31 23:51:43.000000000 +0200
  227698. +++ linux-linaro-stable-mx6/sound/soc/codecs/Kconfig 2014-08-20 19:31:58.628922667 +0200
  227699. @@ -37,6 +37,7 @@
  227700. select SND_SOC_CS42L73 if I2C
  227701. select SND_SOC_CS4270 if I2C
  227702. select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
  227703. + select SND_SOC_CS42888 if I2C
  227704. select SND_SOC_CX20442 if TTY
  227705. select SND_SOC_DA7210 if I2C
  227706. select SND_SOC_DA7213 if I2C
  227707. @@ -254,6 +255,9 @@
  227708. config SND_SOC_CS4271
  227709. tristate
  227710. +config SND_SOC_CS42888
  227711. + tristate
  227712. +
  227713. config SND_SOC_CX20442
  227714. tristate
  227715. depends on TTY
  227716. diff -Nur linux-3.14.15/sound/soc/codecs/Makefile linux-linaro-stable-mx6/sound/soc/codecs/Makefile
  227717. --- linux-3.14.15/sound/soc/codecs/Makefile 2014-07-31 23:51:43.000000000 +0200
  227718. +++ linux-linaro-stable-mx6/sound/soc/codecs/Makefile 2014-08-20 19:31:58.628922667 +0200
  227719. @@ -23,6 +23,7 @@
  227720. snd-soc-cs42l73-objs := cs42l73.o
  227721. snd-soc-cs4270-objs := cs4270.o
  227722. snd-soc-cs4271-objs := cs4271.o
  227723. +snd-soc-cs42888-objs := cs42888.o
  227724. snd-soc-cx20442-objs := cx20442.o
  227725. snd-soc-da7210-objs := da7210.o
  227726. snd-soc-da7213-objs := da7213.o
  227727. @@ -156,6 +157,7 @@
  227728. obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o
  227729. obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
  227730. obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
  227731. +obj-$(CONFIG_SND_SOC_CS42888) += snd-soc-cs42888.o
  227732. obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
  227733. obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
  227734. obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
  227735. diff -Nur linux-3.14.15/sound/soc/codecs/sgtl5000.c linux-linaro-stable-mx6/sound/soc/codecs/sgtl5000.c
  227736. --- linux-3.14.15/sound/soc/codecs/sgtl5000.c 2014-07-31 23:51:43.000000000 +0200
  227737. +++ linux-linaro-stable-mx6/sound/soc/codecs/sgtl5000.c 2014-08-20 19:31:58.688922925 +0200
  227738. @@ -756,7 +756,7 @@
  227739. struct ldo_regulator *ldo = rdev_get_drvdata(dev);
  227740. struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
  227741. int reg;
  227742. -
  227743. +dev_info(codec->dev, "%s(): enabled %u\n", __func__, ldo->enabled);
  227744. if (ldo_regulator_is_enabled(dev))
  227745. return 0;
  227746. @@ -788,10 +788,16 @@
  227747. {
  227748. struct ldo_regulator *ldo = rdev_get_drvdata(dev);
  227749. struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
  227750. +dev_info(codec->dev, "%s(): enabled %u\n", __func__, ldo->enabled);
  227751. +
  227752. + snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  227753. + SGTL5000_LINREG_SIMPLE_POWERUP,
  227754. + SGTL5000_LINREG_SIMPLE_POWERUP);
  227755. snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  227756. SGTL5000_LINEREG_D_POWERUP,
  227757. 0);
  227758. +dev_info(codec->dev, "%s: ANA_POWER = 0x%04x\n", __func__, snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER));
  227759. /* clear voltage info */
  227760. snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
  227761. @@ -849,6 +855,7 @@
  227762. config.dev = codec->dev;
  227763. config.driver_data = ldo;
  227764. config.init_data = init_data;
  227765. + config.ena_gpio = -EINVAL;
  227766. ldo->dev = regulator_register(&ldo->desc, &config);
  227767. if (IS_ERR(ldo->dev)) {
  227768. @@ -1202,8 +1209,11 @@
  227769. * if vddio and vddd > 3.1v,
  227770. * charge pump should be clean before set ana_pwr
  227771. */
  227772. - snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  227773. - SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
  227774. +// FIXME: this is total crap - we have read this register above into
  227775. +// ana_pwr, which we then modify (above), and then write back to the
  227776. +// register below. This modification just gets completely overwritten.
  227777. +// snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  227778. +// SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
  227779. /* VDDC use VDDIO rail */
  227780. lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
  227781. @@ -1320,7 +1330,7 @@
  227782. return ret;
  227783. }
  227784. - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
  227785. + ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
  227786. sgtl5000->supplies);
  227787. if (ret)
  227788. goto err_ldo_remove;
  227789. @@ -1328,16 +1338,13 @@
  227790. ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
  227791. sgtl5000->supplies);
  227792. if (ret)
  227793. - goto err_regulator_free;
  227794. + goto err_ldo_remove;
  227795. /* wait for all power rails bring up */
  227796. udelay(10);
  227797. return 0;
  227798. -err_regulator_free:
  227799. - regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
  227800. - sgtl5000->supplies);
  227801. err_ldo_remove:
  227802. if (!external_vddd)
  227803. ldo_regulator_remove(codec);
  227804. @@ -1358,6 +1365,9 @@
  227805. return ret;
  227806. }
  227807. + if (!devres_open_group(codec->dev, NULL, GFP_KERNEL))
  227808. + return -ENOMEM;
  227809. +
  227810. ret = sgtl5000_enable_regulators(codec);
  227811. if (ret)
  227812. return ret;
  227813. @@ -1415,8 +1425,9 @@
  227814. err:
  227815. regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
  227816. sgtl5000->supplies);
  227817. - regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
  227818. - sgtl5000->supplies);
  227819. +
  227820. + devres_release_group(codec->dev, NULL);
  227821. +
  227822. ldo_regulator_remove(codec);
  227823. return ret;
  227824. @@ -1430,8 +1441,9 @@
  227825. regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
  227826. sgtl5000->supplies);
  227827. - regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
  227828. - sgtl5000->supplies);
  227829. +
  227830. + devres_release_group(codec->dev, NULL);
  227831. +
  227832. ldo_regulator_remove(codec);
  227833. return 0;
  227834. diff -Nur linux-3.14.15/sound/soc/codecs/spdif_transmitter.c linux-linaro-stable-mx6/sound/soc/codecs/spdif_transmitter.c
  227835. --- linux-3.14.15/sound/soc/codecs/spdif_transmitter.c 2014-07-31 23:51:43.000000000 +0200
  227836. +++ linux-linaro-stable-mx6/sound/soc/codecs/spdif_transmitter.c 2014-08-20 19:31:58.692922943 +0200
  227837. @@ -24,7 +24,7 @@
  227838. #define DRV_NAME "spdif-dit"
  227839. -#define STUB_RATES SNDRV_PCM_RATE_8000_96000
  227840. +#define STUB_RATES SNDRV_PCM_RATE_8000_192000
  227841. #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
  227842. SNDRV_PCM_FMTBIT_S20_3LE | \
  227843. SNDRV_PCM_FMTBIT_S24_LE)
  227844. diff -Nur linux-3.14.15/sound/soc/codecs/wm8962.c linux-linaro-stable-mx6/sound/soc/codecs/wm8962.c
  227845. --- linux-3.14.15/sound/soc/codecs/wm8962.c 2014-07-31 23:51:43.000000000 +0200
  227846. +++ linux-linaro-stable-mx6/sound/soc/codecs/wm8962.c 2014-08-20 19:31:58.720923064 +0200
  227847. @@ -16,6 +16,7 @@
  227848. #include <linux/init.h>
  227849. #include <linux/delay.h>
  227850. #include <linux/pm.h>
  227851. +#include <linux/clk.h>
  227852. #include <linux/gcd.h>
  227853. #include <linux/gpio.h>
  227854. #include <linux/i2c.h>
  227855. @@ -2942,7 +2943,8 @@
  227856. WM8962_DAC_MUTE, val);
  227857. }
  227858. -#define WM8962_RATES SNDRV_PCM_RATE_8000_96000
  227859. +#define WM8962_RATES (SNDRV_PCM_RATE_8000_48000 |\
  227860. + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
  227861. #define WM8962_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
  227862. SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
  227863. @@ -3536,6 +3538,15 @@
  227864. pdata->gpio_init[i] = 0x0;
  227865. }
  227866. + pdata->codec_mclk = devm_clk_get(&i2c->dev, NULL);
  227867. +
  227868. + /*
  227869. + * If clk_get() failed, we assume that clock's enabled by default.
  227870. + * Otherwise, we let driver prepare and control the clock source.
  227871. + */
  227872. + if (IS_ERR(pdata->codec_mclk))
  227873. + pdata->codec_mclk = NULL;
  227874. +
  227875. return 0;
  227876. }
  227877. @@ -3567,6 +3578,9 @@
  227878. return ret;
  227879. }
  227880. + if (wm8962->pdata.codec_mclk)
  227881. + clk_prepare(wm8962->pdata.codec_mclk);
  227882. +
  227883. for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
  227884. wm8962->supplies[i].supply = wm8962_supply_names[i];
  227885. @@ -3669,6 +3683,27 @@
  227886. WM8962_MICBIAS_LVL,
  227887. wm8962->pdata.mic_cfg);
  227888. + /* set the default volume for playback and record*/
  227889. + snd_soc_update_bits(codec, WM8962_HPOUTL_VOLUME,
  227890. + WM8962_HPOUTL_VOL_MASK, 0x5d);
  227891. + snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME,
  227892. + WM8962_HPOUTR_VOL_MASK, 0x5d);
  227893. + snd_soc_update_bits(codec, WM8962_SPKOUTL_VOLUME,
  227894. + WM8962_SPKOUTL_VOL_MASK, 0x72);
  227895. + snd_soc_update_bits(codec, WM8962_SPKOUTR_VOLUME,
  227896. + WM8962_SPKOUTR_VOL_MASK, 0x72);
  227897. +
  227898. + snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME,
  227899. + WM8962_INL_VOL_MASK, 0x3f);
  227900. + snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_VOLUME,
  227901. + WM8962_INR_VOL_MASK, 0x3f);
  227902. + snd_soc_update_bits(codec, WM8962_LEFT_ADC_VOLUME,
  227903. + WM8962_ADCL_VOL_MASK, 0xd8);
  227904. + snd_soc_update_bits(codec, WM8962_RIGHT_ADC_VOLUME,
  227905. + WM8962_ADCR_VOL_MASK, 0xd8);
  227906. + snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_MIXER_VOLUME,
  227907. + WM8962_IN3R_MIXINR_VOL_MASK, 0x7);
  227908. +
  227909. /* Latch volume update bits */
  227910. regmap_update_bits(wm8962->regmap, WM8962_LEFT_INPUT_VOLUME,
  227911. WM8962_IN_VU, WM8962_IN_VU);
  227912. @@ -3752,6 +3787,9 @@
  227913. regcache_cache_only(wm8962->regmap, true);
  227914. + /* The cache-only should be turned on before we power down the codec */
  227915. + regcache_cache_only(wm8962->regmap, true);
  227916. +
  227917. /* The drivers should power up as needed */
  227918. regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
  227919. @@ -3760,11 +3798,19 @@
  227920. err_enable:
  227921. regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
  227922. err:
  227923. + if (wm8962->pdata.codec_mclk)
  227924. + clk_unprepare(wm8962->pdata.codec_mclk);
  227925. +
  227926. return ret;
  227927. }
  227928. static int wm8962_i2c_remove(struct i2c_client *client)
  227929. {
  227930. + struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev);
  227931. +
  227932. + if (wm8962->pdata.codec_mclk)
  227933. + clk_unprepare(wm8962->pdata.codec_mclk);
  227934. +
  227935. snd_soc_unregister_codec(&client->dev);
  227936. return 0;
  227937. }
  227938. @@ -3775,6 +3821,9 @@
  227939. struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
  227940. int ret;
  227941. + if (wm8962->pdata.codec_mclk)
  227942. + clk_enable(wm8962->pdata.codec_mclk);
  227943. +
  227944. ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
  227945. wm8962->supplies);
  227946. if (ret != 0) {
  227947. @@ -3834,6 +3883,10 @@
  227948. regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
  227949. wm8962->supplies);
  227950. + if (wm8962->pdata.codec_mclk)
  227951. + clk_disable(wm8962->pdata.codec_mclk);
  227952. +
  227953. +
  227954. return 0;
  227955. }
  227956. #endif
  227957. diff -Nur linux-3.14.15/sound/soc/fsl/fsl_asrc.c linux-linaro-stable-mx6/sound/soc/fsl/fsl_asrc.c
  227958. --- linux-3.14.15/sound/soc/fsl/fsl_asrc.c 1970-01-01 01:00:00.000000000 +0100
  227959. +++ linux-linaro-stable-mx6/sound/soc/fsl/fsl_asrc.c 2014-08-20 19:31:58.740923149 +0200
  227960. @@ -0,0 +1,498 @@
  227961. +/*
  227962. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  227963. + *
  227964. + * The code contained herein is licensed under the GNU General Public
  227965. + * License. You may obtain a copy of the GNU General Public License
  227966. + * Version 2 or later at the following locations:
  227967. + *
  227968. + * http://www.opensource.org/licenses/gpl-license.html
  227969. + * http://www.gnu.org/copyleft/gpl.html
  227970. + */
  227971. +
  227972. +#include <linux/module.h>
  227973. +#include <linux/of.h>
  227974. +#include <linux/of_platform.h>
  227975. +#include <linux/slab.h>
  227976. +#include <linux/device.h>
  227977. +#include <linux/i2c.h>
  227978. +#include <linux/clk.h>
  227979. +#include <linux/delay.h>
  227980. +#include <linux/mxc_asrc.h>
  227981. +#include <sound/core.h>
  227982. +#include <sound/pcm.h>
  227983. +#include <sound/pcm_params.h>
  227984. +#include <sound/soc.h>
  227985. +#include <sound/initval.h>
  227986. +#include <sound/dmaengine_pcm.h>
  227987. +
  227988. +#include "fsl_asrc.h"
  227989. +#include "imx-pcm.h"
  227990. +
  227991. +static bool filter(struct dma_chan *chan, void *param)
  227992. +{
  227993. + if (!imx_dma_is_general_purpose(chan))
  227994. + return false;
  227995. +
  227996. + chan->private = param;
  227997. +
  227998. + return true;
  227999. +}
  228000. +
  228001. +static int asrc_p2p_request_channel(struct snd_pcm_substream *substream)
  228002. +{
  228003. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  228004. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  228005. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  228006. + enum dma_slave_buswidth buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
  228007. + struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
  228008. + struct snd_dmaengine_dai_dma_data *dma_params_fe = NULL;
  228009. + struct imx_dma_data *fe_filter_data = NULL;
  228010. + struct imx_dma_data *be_filter_data = NULL;
  228011. +
  228012. + struct dma_slave_config slave_config;
  228013. + dma_cap_mask_t mask;
  228014. + struct dma_chan *chan;
  228015. + int ret;
  228016. + struct snd_soc_dpcm *dpcm;
  228017. +
  228018. + /* find the be for this fe stream */
  228019. + list_for_each_entry(dpcm, &rtd->dpcm[substream->stream].be_clients, list_be) {
  228020. + if (dpcm->fe == rtd) {
  228021. + struct snd_soc_pcm_runtime *be = dpcm->be;
  228022. + struct snd_soc_dai *dai = be->cpu_dai;
  228023. + struct snd_pcm_substream *be_substream;
  228024. + be_substream = snd_soc_dpcm_get_substream(be, substream->stream);
  228025. + dma_params_be = snd_soc_dai_get_dma_data(dai, be_substream);
  228026. + break;
  228027. + }
  228028. + }
  228029. +
  228030. + if (!dma_params_be) {
  228031. + dev_err(rtd->card->dev, "can not get be substream\n");
  228032. + return -EINVAL;
  228033. + }
  228034. +
  228035. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  228036. + dma_params_fe = &asrc_p2p->dma_params_tx;
  228037. + else
  228038. + dma_params_fe = &asrc_p2p->dma_params_rx;
  228039. +
  228040. + fe_filter_data = dma_params_fe->filter_data;
  228041. + be_filter_data = dma_params_be->filter_data;
  228042. +
  228043. + if (asrc_p2p->output_width == 16)
  228044. + buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
  228045. + else
  228046. + buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
  228047. +
  228048. + /* reconfig memory to FIFO dma request */
  228049. + dma_params_fe->addr = asrc_p2p->asrc_ops.asrc_p2p_per_addr(
  228050. + asrc_p2p->asrc_index, 1);
  228051. + fe_filter_data->dma_request0 = asrc_p2p->dmarx[asrc_p2p->asrc_index];
  228052. + dma_params_fe->maxburst = dma_params_be->maxburst;
  228053. +
  228054. + dma_cap_zero(mask);
  228055. + dma_cap_set(DMA_SLAVE, mask);
  228056. + dma_cap_set(DMA_CYCLIC, mask);
  228057. +
  228058. + /* config p2p dma channel */
  228059. + asrc_p2p->asrc_p2p_dma_data.peripheral_type = IMX_DMATYPE_ASRC;
  228060. + asrc_p2p->asrc_p2p_dma_data.priority = DMA_PRIO_HIGH;
  228061. + asrc_p2p->asrc_p2p_dma_data.dma_request1 = asrc_p2p->dmatx[asrc_p2p->asrc_index];
  228062. + /* need to get target device's dma dma_addr, burstsize */
  228063. + asrc_p2p->asrc_p2p_dma_data.dma_request0 = be_filter_data->dma_request0;
  228064. +
  228065. + /* Request channel */
  228066. + asrc_p2p->asrc_p2p_dma_chan =
  228067. + dma_request_channel(mask, filter, &asrc_p2p->asrc_p2p_dma_data);
  228068. +
  228069. + if (!asrc_p2p->asrc_p2p_dma_chan) {
  228070. + dev_err(rtd->card->dev, "can not request dma channel\n");
  228071. + goto error;
  228072. + }
  228073. + chan = asrc_p2p->asrc_p2p_dma_chan;
  228074. +
  228075. + /*
  228076. + * Buswidth is not used in the sdma for p2p. Here we set the maxburst fix to
  228077. + * twice of dma_params's burstsize.
  228078. + */
  228079. + slave_config.direction = DMA_DEV_TO_DEV;
  228080. + slave_config.src_addr = asrc_p2p->asrc_ops.asrc_p2p_per_addr(asrc_p2p->asrc_index, 0);
  228081. + slave_config.src_addr_width = buswidth;
  228082. + slave_config.src_maxburst = dma_params_be->maxburst * 2;
  228083. + slave_config.dst_addr = dma_params_be->addr;
  228084. + slave_config.dst_addr_width = buswidth;
  228085. + slave_config.dst_maxburst = dma_params_be->maxburst * 2;
  228086. + slave_config.dma_request0 = be_filter_data->dma_request0;
  228087. + slave_config.dma_request1 = asrc_p2p->dmatx[asrc_p2p->asrc_index];
  228088. +
  228089. + ret = dmaengine_slave_config(asrc_p2p->asrc_p2p_dma_chan,
  228090. + &slave_config);
  228091. + if (ret) {
  228092. + dev_err(rtd->card->dev, "can not config dma channel\n");
  228093. + goto error;
  228094. + }
  228095. +
  228096. + return 0;
  228097. +error:
  228098. + if (asrc_p2p->asrc_p2p_dma_chan) {
  228099. + dma_release_channel(asrc_p2p->asrc_p2p_dma_chan);
  228100. + asrc_p2p->asrc_p2p_dma_chan = NULL;
  228101. + }
  228102. +
  228103. + return -EINVAL;
  228104. +}
  228105. +
  228106. +static int config_asrc(struct snd_pcm_substream *substream,
  228107. + struct snd_pcm_hw_params *params)
  228108. +{
  228109. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  228110. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  228111. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  228112. + unsigned int rate = params_rate(params);
  228113. + unsigned int channel = params_channels(params);
  228114. + struct asrc_config config = {0};
  228115. + int output_word_width = 0;
  228116. + int input_word_width = 0;
  228117. + int ret = 0;
  228118. + if ((channel != 2) && (channel != 4) && (channel != 6)) {
  228119. + dev_err(cpu_dai->dev, "param channel is not correct\n");
  228120. + return -EINVAL;
  228121. + }
  228122. +
  228123. + ret = asrc_p2p->asrc_ops.asrc_p2p_req_pair(channel, &asrc_p2p->asrc_index);
  228124. + if (ret < 0) {
  228125. + dev_err(cpu_dai->dev, "Fail to request asrc pair\n");
  228126. + return -EINVAL;
  228127. + }
  228128. +
  228129. + if (asrc_p2p->output_width == 16)
  228130. + output_word_width = ASRC_WIDTH_16_BIT;
  228131. + else
  228132. + output_word_width = ASRC_WIDTH_24_BIT;
  228133. +
  228134. + switch (params_format(params)) {
  228135. + case SNDRV_PCM_FORMAT_U16:
  228136. + case SNDRV_PCM_FORMAT_S16_LE:
  228137. + case SNDRV_PCM_FORMAT_S16_BE:
  228138. + input_word_width = ASRC_WIDTH_16_BIT;
  228139. + break;
  228140. + case SNDRV_PCM_FORMAT_S20_3LE:
  228141. + case SNDRV_PCM_FORMAT_S20_3BE:
  228142. + case SNDRV_PCM_FORMAT_S24_3LE:
  228143. + case SNDRV_PCM_FORMAT_S24_3BE:
  228144. + case SNDRV_PCM_FORMAT_S24_BE:
  228145. + case SNDRV_PCM_FORMAT_S24_LE:
  228146. + case SNDRV_PCM_FORMAT_U24_BE:
  228147. + case SNDRV_PCM_FORMAT_U24_LE:
  228148. + case SNDRV_PCM_FORMAT_U24_3BE:
  228149. + case SNDRV_PCM_FORMAT_U24_3LE:
  228150. + input_word_width = ASRC_WIDTH_24_BIT;
  228151. + break;
  228152. + case SNDRV_PCM_FORMAT_S8:
  228153. + case SNDRV_PCM_FORMAT_U8:
  228154. + case SNDRV_PCM_FORMAT_S32:
  228155. + case SNDRV_PCM_FORMAT_U32:
  228156. + default:
  228157. + dev_err(cpu_dai->dev, "Format is not support!\n");
  228158. + return -EINVAL;
  228159. + }
  228160. +
  228161. + config.input_word_width = input_word_width;
  228162. + config.output_word_width = output_word_width;
  228163. + config.pair = asrc_p2p->asrc_index;
  228164. + config.channel_num = channel;
  228165. + config.input_sample_rate = rate;
  228166. + config.output_sample_rate = asrc_p2p->output_rate;
  228167. + config.inclk = INCLK_NONE;
  228168. +
  228169. + switch (asrc_p2p->per_dev) {
  228170. + case SSI1:
  228171. + config.outclk = OUTCLK_SSI1_TX;
  228172. + break;
  228173. + case SSI2:
  228174. + config.outclk = OUTCLK_SSI2_TX;
  228175. + break;
  228176. + case SSI3:
  228177. + config.outclk = OUTCLK_SSI3_TX;
  228178. + break;
  228179. + case ESAI:
  228180. + config.outclk = OUTCLK_ESAI_TX;
  228181. + break;
  228182. + default:
  228183. + dev_err(cpu_dai->dev, "peripheral device is not correct\n");
  228184. + return -EINVAL;
  228185. + }
  228186. +
  228187. + ret = asrc_p2p->asrc_ops.asrc_p2p_config_pair(&config);
  228188. + if (ret < 0) {
  228189. + dev_err(cpu_dai->dev, "Fail to config asrc\n");
  228190. + return ret;
  228191. + }
  228192. +
  228193. + return 0;
  228194. +}
  228195. +
  228196. +static int fsl_asrc_p2p_hw_params(struct snd_pcm_substream *substream,
  228197. + struct snd_pcm_hw_params *params,
  228198. + struct snd_soc_dai *cpu_dai)
  228199. +{
  228200. + int ret = 0;
  228201. +
  228202. + ret = config_asrc(substream, params);
  228203. + if (ret < 0)
  228204. + return ret;
  228205. +
  228206. + return asrc_p2p_request_channel(substream);
  228207. +}
  228208. +
  228209. +static int fsl_asrc_p2p_hw_free(struct snd_pcm_substream *substream,
  228210. + struct snd_soc_dai *cpu_dai)
  228211. +{
  228212. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  228213. +
  228214. + if (asrc_p2p->asrc_p2p_dma_chan) {
  228215. + /* Release p2p dma resource */
  228216. + dma_release_channel(asrc_p2p->asrc_p2p_dma_chan);
  228217. + asrc_p2p->asrc_p2p_dma_chan = NULL;
  228218. + }
  228219. +
  228220. + if (asrc_p2p->asrc_index != -1) {
  228221. + asrc_p2p->asrc_ops.asrc_p2p_release_pair(asrc_p2p->asrc_index);
  228222. + asrc_p2p->asrc_ops.asrc_p2p_finish_conv(asrc_p2p->asrc_index);
  228223. + }
  228224. + asrc_p2p->asrc_index = -1;
  228225. +
  228226. + return 0;
  228227. +}
  228228. +
  228229. +static int fsl_asrc_dma_prepare_and_submit(struct snd_pcm_substream *substream,
  228230. + struct fsl_asrc_p2p *asrc_p2p)
  228231. +{
  228232. + struct dma_async_tx_descriptor *desc = asrc_p2p->asrc_p2p_desc;
  228233. + struct dma_chan *chan = asrc_p2p->asrc_p2p_dma_chan;
  228234. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  228235. + struct device *dev = rtd->platform->dev;
  228236. +
  228237. + desc = dmaengine_prep_dma_cyclic(chan, 0xffff, 64, 64, DMA_DEV_TO_DEV, 0);
  228238. + if (!desc) {
  228239. + dev_err(dev, "failed to prepare slave dma\n");
  228240. + return -EINVAL;
  228241. + }
  228242. +
  228243. + dmaengine_submit(desc);
  228244. +
  228245. + return 0;
  228246. +}
  228247. +
  228248. +static int fsl_asrc_p2p_trigger(struct snd_pcm_substream *substream, int cmd,
  228249. + struct snd_soc_dai *cpu_dai)
  228250. +{
  228251. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  228252. + int ret;
  228253. +
  228254. + switch (cmd) {
  228255. + case SNDRV_PCM_TRIGGER_START:
  228256. + case SNDRV_PCM_TRIGGER_RESUME:
  228257. + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  228258. + ret = fsl_asrc_dma_prepare_and_submit(substream, asrc_p2p);
  228259. + if (ret)
  228260. + return ret;
  228261. + dma_async_issue_pending(asrc_p2p->asrc_p2p_dma_chan);
  228262. + asrc_p2p->asrc_ops.asrc_p2p_start_conv(asrc_p2p->asrc_index);
  228263. + break;
  228264. + case SNDRV_PCM_TRIGGER_SUSPEND:
  228265. + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  228266. + case SNDRV_PCM_TRIGGER_STOP:
  228267. + dmaengine_terminate_all(asrc_p2p->asrc_p2p_dma_chan);
  228268. + asrc_p2p->asrc_ops.asrc_p2p_stop_conv(asrc_p2p->asrc_index);
  228269. + break;
  228270. + default:
  228271. + return -EINVAL;
  228272. + }
  228273. +
  228274. + return 0;
  228275. +}
  228276. +
  228277. +#define IMX_ASRC_RATES SNDRV_PCM_RATE_8000_192000
  228278. +
  228279. +#define IMX_ASRC_FORMATS \
  228280. + (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE | \
  228281. + SNDRV_PCM_FORMAT_S20_3LE)
  228282. +
  228283. +static struct snd_soc_dai_ops fsl_asrc_p2p_dai_ops = {
  228284. + .trigger = fsl_asrc_p2p_trigger,
  228285. + .hw_params = fsl_asrc_p2p_hw_params,
  228286. + .hw_free = fsl_asrc_p2p_hw_free,
  228287. +};
  228288. +
  228289. +static int fsl_asrc_p2p_dai_probe(struct snd_soc_dai *dai)
  228290. +{
  228291. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(dai);
  228292. +
  228293. + dai->playback_dma_data = &asrc_p2p->dma_params_tx;
  228294. + dai->capture_dma_data = &asrc_p2p->dma_params_rx;
  228295. +
  228296. + return 0;
  228297. +}
  228298. +
  228299. +static struct snd_soc_dai_driver fsl_asrc_p2p_dai = {
  228300. + .probe = fsl_asrc_p2p_dai_probe,
  228301. + .playback = {
  228302. + .stream_name = "asrc-Playback",
  228303. + .channels_min = 1,
  228304. + .channels_max = 10,
  228305. + .rates = IMX_ASRC_RATES,
  228306. + .formats = IMX_ASRC_FORMATS,
  228307. + },
  228308. + .capture = {
  228309. + .stream_name = "asrc-Capture",
  228310. + .channels_min = 1,
  228311. + .channels_max = 4,
  228312. + .rates = IMX_ASRC_RATES,
  228313. + .formats = IMX_ASRC_FORMATS,
  228314. + },
  228315. + .ops = &fsl_asrc_p2p_dai_ops,
  228316. +};
  228317. +
  228318. +static const struct snd_soc_component_driver fsl_asrc_p2p_component = {
  228319. + .name = "fsl-asrc-p2p",
  228320. +};
  228321. +
  228322. +/*
  228323. + * This function will register the snd_soc_pcm_link drivers.
  228324. + */
  228325. +static int fsl_asrc_p2p_probe(struct platform_device *pdev)
  228326. +{
  228327. + struct fsl_asrc_p2p *asrc_p2p;
  228328. + struct device_node *np = pdev->dev.of_node;
  228329. + const char *p;
  228330. + const uint32_t *iprop_rate, *iprop_width;
  228331. + int ret = 0;
  228332. +
  228333. + if (!of_device_is_available(np)) {
  228334. + dev_err(&pdev->dev, "There is no device node\n");
  228335. + return -ENODEV;
  228336. + }
  228337. +
  228338. + asrc_p2p = devm_kzalloc(&pdev->dev, sizeof(struct fsl_asrc_p2p), GFP_KERNEL);
  228339. + if (!asrc_p2p) {
  228340. + dev_err(&pdev->dev, "can not alloc memory\n");
  228341. + return -ENOMEM;
  228342. + }
  228343. + asrc_p2p->asrc_ops.asrc_p2p_start_conv = asrc_start_conv;
  228344. + asrc_p2p->asrc_ops.asrc_p2p_stop_conv = asrc_stop_conv;
  228345. + asrc_p2p->asrc_ops.asrc_p2p_per_addr = asrc_get_per_addr;
  228346. + asrc_p2p->asrc_ops.asrc_p2p_req_pair = asrc_req_pair;
  228347. + asrc_p2p->asrc_ops.asrc_p2p_config_pair = asrc_config_pair;
  228348. + asrc_p2p->asrc_ops.asrc_p2p_release_pair = asrc_release_pair;
  228349. + asrc_p2p->asrc_ops.asrc_p2p_finish_conv = asrc_finish_conv;
  228350. +
  228351. + asrc_p2p->asrc_index = -1;
  228352. +
  228353. + iprop_rate = of_get_property(np, "fsl,output-rate", NULL);
  228354. + if (iprop_rate)
  228355. + asrc_p2p->output_rate = be32_to_cpup(iprop_rate);
  228356. + else {
  228357. + dev_err(&pdev->dev, "There is no output-rate in dts\n");
  228358. + return -EINVAL;
  228359. + }
  228360. + iprop_width = of_get_property(np, "fsl,output-width", NULL);
  228361. + if (iprop_width)
  228362. + asrc_p2p->output_width = be32_to_cpup(iprop_width);
  228363. +
  228364. + if (asrc_p2p->output_width != 16 && asrc_p2p->output_width != 24) {
  228365. + dev_err(&pdev->dev, "output_width is not acceptable\n");
  228366. + return -EINVAL;
  228367. + }
  228368. +
  228369. + ret = of_property_read_u32_array(np,
  228370. + "fsl,asrc-dma-tx-events", asrc_p2p->dmatx, 3);
  228371. + if (ret) {
  228372. + dev_err(&pdev->dev, "Failed to get fsl,asrc-dma-tx-events.\n");
  228373. + return -EINVAL;
  228374. + }
  228375. +
  228376. + ret = of_property_read_u32_array(np,
  228377. + "fsl,asrc-dma-rx-events", asrc_p2p->dmarx, 3);
  228378. + if (ret) {
  228379. + dev_err(&pdev->dev, "Failed to get fsl,asrc-dma-rx-events.\n");
  228380. + return -EINVAL;
  228381. + }
  228382. +
  228383. + asrc_p2p->filter_data_tx.peripheral_type = IMX_DMATYPE_ASRC;
  228384. + asrc_p2p->filter_data_rx.peripheral_type = IMX_DMATYPE_ASRC;
  228385. +
  228386. + asrc_p2p->dma_params_tx.filter_data = &asrc_p2p->filter_data_tx;
  228387. + asrc_p2p->dma_params_rx.filter_data = &asrc_p2p->filter_data_rx;
  228388. +
  228389. + platform_set_drvdata(pdev, asrc_p2p);
  228390. +
  228391. + p = strrchr(np->full_name, '/') + 1;
  228392. + strcpy(asrc_p2p->name, p);
  228393. + fsl_asrc_p2p_dai.name = asrc_p2p->name;
  228394. +
  228395. + ret = snd_soc_register_component(&pdev->dev, &fsl_asrc_p2p_component,
  228396. + &fsl_asrc_p2p_dai, 1);
  228397. + if (ret) {
  228398. + dev_err(&pdev->dev, "register DAI failed\n");
  228399. + goto failed_register;
  228400. + }
  228401. +
  228402. + asrc_p2p->soc_platform_pdev = platform_device_register_simple(
  228403. + "imx-pcm-asrc", -1, NULL, 0);
  228404. + if (IS_ERR(asrc_p2p->soc_platform_pdev)) {
  228405. + ret = PTR_ERR(asrc_p2p->soc_platform_pdev);
  228406. + goto failed_pdev_alloc;
  228407. + }
  228408. +
  228409. + ret = imx_pcm_dma_init(asrc_p2p->soc_platform_pdev, SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
  228410. + SND_DMAENGINE_PCM_FLAG_NO_DT |
  228411. + SND_DMAENGINE_PCM_FLAG_COMPAT,
  228412. + IMX_ASRC_DMABUF_SIZE);
  228413. + if (ret) {
  228414. + dev_err(&pdev->dev, "init pcm dma failed\n");
  228415. + goto failed_pcm_init;
  228416. + }
  228417. +
  228418. + return 0;
  228419. +
  228420. +failed_pcm_init:
  228421. + platform_device_unregister(asrc_p2p->soc_platform_pdev);
  228422. +failed_pdev_alloc:
  228423. + snd_soc_unregister_component(&pdev->dev);
  228424. +failed_register:
  228425. +
  228426. + return ret;
  228427. +}
  228428. +
  228429. +static int fsl_asrc_p2p_remove(struct platform_device *pdev)
  228430. +{
  228431. + struct fsl_asrc_p2p *asrc_p2p = platform_get_drvdata(pdev);
  228432. +
  228433. + platform_device_unregister(asrc_p2p->soc_platform_pdev);
  228434. + snd_soc_unregister_component(&pdev->dev);
  228435. +
  228436. + return 0;
  228437. +}
  228438. +
  228439. +static const struct of_device_id fsl_asrc_p2p_dt_ids[] = {
  228440. + { .compatible = "fsl,imx6q-asrc-p2p", },
  228441. + { /* sentinel */ }
  228442. +};
  228443. +
  228444. +static struct platform_driver fsl_asrc_p2p_driver = {
  228445. + .probe = fsl_asrc_p2p_probe,
  228446. + .remove = fsl_asrc_p2p_remove,
  228447. + .driver = {
  228448. + .name = "fsl-asrc-p2p",
  228449. + .owner = THIS_MODULE,
  228450. + .of_match_table = fsl_asrc_p2p_dt_ids,
  228451. + },
  228452. +};
  228453. +module_platform_driver(fsl_asrc_p2p_driver);
  228454. +
  228455. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  228456. +MODULE_DESCRIPTION("i.MX ASoC ASRC P2P driver");
  228457. +MODULE_ALIAS("platform:fsl-asrc-p2p");
  228458. +MODULE_LICENSE("GPL");
  228459. diff -Nur linux-3.14.15/sound/soc/fsl/fsl_asrc.h linux-linaro-stable-mx6/sound/soc/fsl/fsl_asrc.h
  228460. --- linux-3.14.15/sound/soc/fsl/fsl_asrc.h 1970-01-01 01:00:00.000000000 +0100
  228461. +++ linux-linaro-stable-mx6/sound/soc/fsl/fsl_asrc.h 2014-08-20 19:24:09.534914052 +0200
  228462. @@ -0,0 +1,48 @@
  228463. +/*
  228464. + * fsl_asrc.h - ALSA ASRC interface
  228465. + *
  228466. + * Copyright (C) 2013 Freescale Semiconductor, Inc. This file is licensed
  228467. + * under the terms of the GNU General Public License version 2. This
  228468. + * program is licensed "as is" without any warranty of any kind, whether
  228469. + * express or implied.
  228470. + */
  228471. +
  228472. +#ifndef _FSL_ASRC_P2P_H
  228473. +#define _FSL_ASRC_P2P_H
  228474. +
  228475. +#include <linux/mxc_asrc.h>
  228476. +#include <sound/dmaengine_pcm.h>
  228477. +#include <linux/platform_data/dma-imx.h>
  228478. +
  228479. +enum peripheral_device_type {
  228480. + UNKNOWN,
  228481. + SSI1,
  228482. + SSI2,
  228483. + SSI3,
  228484. + ESAI,
  228485. +};
  228486. +
  228487. +struct fsl_asrc_p2p {
  228488. + int output_rate;
  228489. + int output_width;
  228490. + enum asrc_pair_index asrc_index;
  228491. + enum peripheral_device_type per_dev;
  228492. + struct asrc_p2p_ops asrc_ops;
  228493. +
  228494. + struct snd_dmaengine_dai_dma_data dma_params_rx;
  228495. + struct snd_dmaengine_dai_dma_data dma_params_tx;
  228496. + struct imx_dma_data filter_data_tx;
  228497. + struct imx_dma_data filter_data_rx;
  228498. +
  228499. + struct dma_async_tx_descriptor *asrc_p2p_desc;
  228500. + struct dma_chan *asrc_p2p_dma_chan;
  228501. + struct imx_dma_data asrc_p2p_dma_data;
  228502. + struct platform_device *soc_platform_pdev;
  228503. +
  228504. + int dmarx[3];
  228505. + int dmatx[3];
  228506. +
  228507. + char name[32];
  228508. +};
  228509. +
  228510. +#endif
  228511. diff -Nur linux-3.14.15/sound/soc/fsl/fsl_asrc_pcm.c linux-linaro-stable-mx6/sound/soc/fsl/fsl_asrc_pcm.c
  228512. --- linux-3.14.15/sound/soc/fsl/fsl_asrc_pcm.c 1970-01-01 01:00:00.000000000 +0100
  228513. +++ linux-linaro-stable-mx6/sound/soc/fsl/fsl_asrc_pcm.c 2014-08-20 19:24:09.534914052 +0200
  228514. @@ -0,0 +1,41 @@
  228515. +/*
  228516. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  228517. + *
  228518. + * The code contained herein is licensed under the GNU General Public
  228519. + * License. You may obtain a copy of the GNU General Public License
  228520. + * Version 2 or later at the following locations:
  228521. + *
  228522. + * http://www.opensource.org/licenses/gpl-license.html
  228523. + * http://www.gnu.org/copyleft/gpl.html
  228524. + */
  228525. +
  228526. +#include <linux/module.h>
  228527. +#include <linux/platform_device.h>
  228528. +
  228529. +
  228530. +/*
  228531. + * Here add one platform module "imx-pcm-asrc" as pcm platform module.
  228532. + * If we use the asrc_p2p node as the pcm platform, there will be one issue.
  228533. + * snd_soc_dapm_new_dai_widgets will be called twice, one in probe link_dais,
  228534. + * one in probe platform. so there will be two dai_widgets added to widget list.
  228535. + * but only the seconed one will be recorded in dai->playback_widget.
  228536. + * Machine driver will add the audio route, but when it go through the
  228537. + * widget list, it will found the cpu_dai widget is the first one in the list.
  228538. + * add use the first one to link the audio route.
  228539. + * when use the fe/be architecture for asrc p2p, it need to go through from
  228540. + * the fe->cpu_dai->playback_widget. but this is the second widget, so the
  228541. + * result is that it can't find a availble audio route for p2p case. So here
  228542. + * use another pcm platform to avoid this issue.
  228543. + */
  228544. +static struct platform_driver imx_pcm_driver = {
  228545. + .driver = {
  228546. + .name = "imx-pcm-asrc",
  228547. + .owner = THIS_MODULE,
  228548. + },
  228549. +};
  228550. +
  228551. +module_platform_driver(imx_pcm_driver);
  228552. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  228553. +MODULE_DESCRIPTION("i.MX ASoC PCM driver");
  228554. +MODULE_ALIAS("platform:imx-pcm-asrc");
  228555. +MODULE_LICENSE("GPL");
  228556. diff -Nur linux-3.14.15/sound/soc/fsl/fsl_esai.c linux-linaro-stable-mx6/sound/soc/fsl/fsl_esai.c
  228557. --- linux-3.14.15/sound/soc/fsl/fsl_esai.c 2014-07-31 23:51:43.000000000 +0200
  228558. +++ linux-linaro-stable-mx6/sound/soc/fsl/fsl_esai.c 2014-08-20 19:31:58.740923149 +0200
  228559. @@ -785,7 +785,7 @@
  228560. return ret;
  228561. }
  228562. - ret = imx_pcm_dma_init(pdev);
  228563. + ret = imx_pcm_dma_init(pdev, NULL, IMX_ESAI_DMABUF_SIZE);
  228564. if (ret)
  228565. dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
  228566. diff -Nur linux-3.14.15/sound/soc/fsl/fsl_hdmi.c linux-linaro-stable-mx6/sound/soc/fsl/fsl_hdmi.c
  228567. --- linux-3.14.15/sound/soc/fsl/fsl_hdmi.c 1970-01-01 01:00:00.000000000 +0100
  228568. +++ linux-linaro-stable-mx6/sound/soc/fsl/fsl_hdmi.c 2014-08-20 19:31:58.740923149 +0200
  228569. @@ -0,0 +1,611 @@
  228570. +/*
  228571. + * ALSA SoC HDMI Audio Layer for Freescale i.MX
  228572. + *
  228573. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  228574. + *
  228575. + * Some code from patch_hdmi.c
  228576. + * Copyright (c) 2008-2010 Intel Corporation. All rights reserved.
  228577. + * Copyright (c) 2006 ATI Technologies Inc.
  228578. + * Copyright (c) 2008 NVIDIA Corp. All rights reserved.
  228579. + * Copyright (c) 2008 Wei Ni <wni@nvidia.com>
  228580. + *
  228581. + * This program is free software; you can redistribute it and/or modify
  228582. + * it under the terms of the GNU General Public License as published by
  228583. + * the Free Software Foundation; either version 2 of the License, or
  228584. + * (at your option) any later version.
  228585. + *
  228586. + * This program is distributed in the hope that it will be useful,
  228587. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  228588. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  228589. + * GNU General Public License for more details.
  228590. + *
  228591. + * You should have received a copy of the GNU General Public License along
  228592. + * with this program; if not, write to the Free Software Foundation, Inc.,
  228593. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  228594. + */
  228595. +
  228596. +#include <linux/init.h>
  228597. +#include <linux/module.h>
  228598. +#include <linux/dma-mapping.h>
  228599. +#include <linux/slab.h>
  228600. +#include <linux/clk.h>
  228601. +#include <linux/delay.h>
  228602. +#include <linux/mfd/mxc-hdmi-core.h>
  228603. +#include <sound/pcm.h>
  228604. +#include <sound/soc.h>
  228605. +#include <sound/asoundef.h>
  228606. +
  228607. +#include <video/mxc_hdmi.h>
  228608. +
  228609. +#include "imx-hdmi.h"
  228610. +
  228611. +
  228612. +static struct mxc_edid_cfg edid_cfg;
  228613. +
  228614. +static u32 playback_rates[HDMI_MAX_RATES];
  228615. +static u32 playback_sample_size[HDMI_MAX_SAMPLE_SIZE];
  228616. +static u32 playback_channels[HDMI_MAX_CHANNEL_CONSTRAINTS];
  228617. +
  228618. +static struct snd_pcm_hw_constraint_list playback_constraint_rates;
  228619. +static struct snd_pcm_hw_constraint_list playback_constraint_bits;
  228620. +static struct snd_pcm_hw_constraint_list playback_constraint_channels;
  228621. +
  228622. +#ifdef DEBUG
  228623. +static void dumpregs(struct snd_soc_dai *dai)
  228624. +{
  228625. + u32 n, cts;
  228626. +
  228627. + cts = (hdmi_readb(HDMI_AUD_CTS3) << 16) |
  228628. + (hdmi_readb(HDMI_AUD_CTS2) << 8) |
  228629. + hdmi_readb(HDMI_AUD_CTS1);
  228630. +
  228631. + n = (hdmi_readb(HDMI_AUD_N3) << 16) |
  228632. + (hdmi_readb(HDMI_AUD_N2) << 8) |
  228633. + hdmi_readb(HDMI_AUD_N1);
  228634. +
  228635. + dev_dbg(dai->dev, "HDMI_PHY_CONF0 0x%02x\n",
  228636. + hdmi_readb(HDMI_PHY_CONF0));
  228637. + dev_dbg(dai->dev, "HDMI_MC_CLKDIS 0x%02x\n",
  228638. + hdmi_readb(HDMI_MC_CLKDIS));
  228639. + dev_dbg(dai->dev, "HDMI_AUD_N[1-3] 0x%06x (%d)\n",
  228640. + n, n);
  228641. + dev_dbg(dai->dev, "HDMI_AUD_CTS[1-3] 0x%06x (%d)\n",
  228642. + cts, cts);
  228643. + dev_dbg(dai->dev, "HDMI_FC_AUDSCONF 0x%02x\n",
  228644. + hdmi_readb(HDMI_FC_AUDSCONF));
  228645. +}
  228646. +#else
  228647. +static void dumpregs(struct snd_soc_dai *dai) {}
  228648. +#endif
  228649. +
  228650. +enum cea_speaker_placement {
  228651. + FL = (1 << 0), /* Front Left */
  228652. + FC = (1 << 1), /* Front Center */
  228653. + FR = (1 << 2), /* Front Right */
  228654. + FLC = (1 << 3), /* Front Left Center */
  228655. + FRC = (1 << 4), /* Front Right Center */
  228656. + RL = (1 << 5), /* Rear Left */
  228657. + RC = (1 << 6), /* Rear Center */
  228658. + RR = (1 << 7), /* Rear Right */
  228659. + RLC = (1 << 8), /* Rear Left Center */
  228660. + RRC = (1 << 9), /* Rear Right Center */
  228661. + LFE = (1 << 10), /* Low Frequency Effect */
  228662. + FLW = (1 << 11), /* Front Left Wide */
  228663. + FRW = (1 << 12), /* Front Right Wide */
  228664. + FLH = (1 << 13), /* Front Left High */
  228665. + FCH = (1 << 14), /* Front Center High */
  228666. + FRH = (1 << 15), /* Front Right High */
  228667. + TC = (1 << 16), /* Top Center */
  228668. +};
  228669. +
  228670. +/*
  228671. + * EDID SA bits in the CEA Speaker Allocation data block
  228672. + */
  228673. +static int edid_speaker_allocation_bits[] = {
  228674. + [0] = FL | FR,
  228675. + [1] = LFE,
  228676. + [2] = FC,
  228677. + [3] = RL | RR,
  228678. + [4] = RC,
  228679. + [5] = FLC | FRC,
  228680. + [6] = RLC | RRC,
  228681. + [7] = FLW | FRW,
  228682. + [8] = FLH | FRH,
  228683. + [9] = TC,
  228684. + [10] = FCH,
  228685. +};
  228686. +
  228687. +struct cea_channel_speaker_allocation {
  228688. + int ca_index;
  228689. + int speakers[8];
  228690. +
  228691. + /* Derived values, just for convenience */
  228692. + int channels;
  228693. + int spk_mask;
  228694. +};
  228695. +
  228696. +/*
  228697. + * This is an ordered list!
  228698. + *
  228699. + * The preceding ones have better chances to be selected by
  228700. + * hdmi_channel_allocation().
  228701. + */
  228702. +static struct cea_channel_speaker_allocation channel_allocations[] = {
  228703. + /* channel: 7 6 5 4 3 2 1 0 */
  228704. + { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL },},
  228705. + /* 2.1 */
  228706. + { .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL },},
  228707. + /* Dolby Surround */
  228708. + { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL },}, /* Prefer FL/FR/RL/RR over FL/FR/LFE/FC */
  228709. + { .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL },},
  228710. + { .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL },},
  228711. + { .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL },},
  228712. + { .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL },},
  228713. + { .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL },},
  228714. + { .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL },},
  228715. + { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL },},
  228716. + { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL },},
  228717. + /* surround51 */
  228718. + { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL },},
  228719. + { .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL },},
  228720. + { .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL },},
  228721. + { .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL },},
  228722. + /* 6.1 */
  228723. + { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL },},
  228724. + { .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL },},
  228725. + { .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL },},
  228726. + { .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL },},
  228727. + /* surround71 */
  228728. + { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL },},
  228729. + { .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL },},
  228730. + { .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL },},
  228731. + { .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL },},
  228732. + { .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL },},
  228733. + { .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL },},
  228734. + { .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL },},
  228735. + { .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL },},
  228736. + { .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL },},
  228737. + { .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL },},
  228738. + { .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL },},
  228739. + { .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL },},
  228740. + { .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL },},
  228741. + { .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL },},
  228742. + { .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL },},
  228743. + { .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL },},
  228744. + { .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL },},
  228745. + { .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL },},
  228746. + { .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL },},
  228747. + { .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL },},
  228748. + { .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL },},
  228749. + { .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL },},
  228750. + { .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL },},
  228751. + { .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL },},
  228752. + { .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL },},
  228753. + { .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL },},
  228754. + { .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL },},
  228755. + { .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL },},
  228756. + { .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL },},
  228757. + { .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL },},
  228758. + { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL },},
  228759. +};
  228760. +
  228761. +/* Compute derived values in channel_allocations[] */
  228762. +static void init_channel_allocations(void)
  228763. +{
  228764. + struct cea_channel_speaker_allocation *p;
  228765. + int i, j;
  228766. +
  228767. + for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  228768. + p = channel_allocations + i;
  228769. + p->channels = 0;
  228770. + p->spk_mask = 0;
  228771. + for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
  228772. + if (p->speakers[j]) {
  228773. + p->channels++;
  228774. + p->spk_mask |= p->speakers[j];
  228775. + }
  228776. + }
  228777. +}
  228778. +
  228779. +/*
  228780. + * The transformation takes two steps:
  228781. + *
  228782. + * speaker_alloc => (edid_speaker_allocation_bits[]) => spk_mask
  228783. + * spk_mask => (channel_allocations[]) => CA
  228784. + *
  228785. + * TODO: it could select the wrong CA from multiple candidates.
  228786. +*/
  228787. +static int hdmi_channel_allocation(int channels)
  228788. +{
  228789. + int spk_mask = 0, ca = 0, i, tmpchn, tmpspk;
  228790. +
  228791. + /* CA defaults to 0 for basic stereo audio */
  228792. + if (channels <= 2)
  228793. + return 0;
  228794. +
  228795. + /*
  228796. + * Expand EDID's speaker allocation mask
  228797. + *
  228798. + * EDID tells the speaker mask in a compact(paired) form,
  228799. + * expand EDID's notions to match the ones used by Audio InfoFrame.
  228800. + */
  228801. + for (i = 0; i < ARRAY_SIZE(edid_speaker_allocation_bits); i++) {
  228802. + if (edid_cfg.speaker_alloc & (1 << i))
  228803. + spk_mask |= edid_speaker_allocation_bits[i];
  228804. + }
  228805. +
  228806. + /* Search for the first working match in the CA table */
  228807. + for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  228808. + tmpchn = channel_allocations[i].channels;
  228809. + tmpspk = channel_allocations[i].spk_mask;
  228810. +
  228811. + if (channels == tmpchn && (spk_mask & tmpspk) == tmpspk) {
  228812. + ca = channel_allocations[i].ca_index;
  228813. + break;
  228814. + }
  228815. + }
  228816. +
  228817. + return ca;
  228818. +}
  228819. +
  228820. +static void hdmi_set_audio_infoframe(unsigned int channels)
  228821. +{
  228822. + u8 audiconf0, audiconf2;
  228823. +
  228824. + /*
  228825. + * From CEA-861-D spec:
  228826. + * HDMI requires the CT, SS and SF fields to be set to 0 ("Refer
  228827. + * to Stream Header") as these items are carried in the audio stream.
  228828. + *
  228829. + * So we only set the CC and CA fields.
  228830. + */
  228831. + audiconf0 = ((channels - 1) << HDMI_FC_AUDICONF0_CC_OFFSET) &
  228832. + HDMI_FC_AUDICONF0_CC_MASK;
  228833. +
  228834. + audiconf2 = hdmi_channel_allocation(channels);
  228835. +
  228836. + hdmi_writeb(audiconf0, HDMI_FC_AUDICONF0);
  228837. + hdmi_writeb(0, HDMI_FC_AUDICONF1);
  228838. + hdmi_writeb(audiconf2, HDMI_FC_AUDICONF2);
  228839. + hdmi_writeb(0, HDMI_FC_AUDICONF3);
  228840. +}
  228841. +
  228842. +static int cea_audio_rates[HDMI_MAX_RATES] = {
  228843. + 32000, 44100, 48000, 88200, 96000, 176400, 192000,
  228844. +};
  228845. +
  228846. +static void fsl_hdmi_get_playback_rates(void)
  228847. +{
  228848. + int i, count = 0;
  228849. + u8 rates;
  228850. +
  228851. + /* Always assume basic audio support */
  228852. + rates = edid_cfg.sample_rates | 0x7;
  228853. +
  228854. + for (i = 0 ; i < HDMI_MAX_RATES ; i++)
  228855. + if ((rates & (1 << i)) != 0)
  228856. + playback_rates[count++] = cea_audio_rates[i];
  228857. +
  228858. + playback_constraint_rates.list = playback_rates;
  228859. + playback_constraint_rates.count = count;
  228860. +
  228861. + for (i = 0 ; i < playback_constraint_rates.count ; i++)
  228862. + pr_debug("%s: constraint = %d Hz\n", __func__, playback_rates[i]);
  228863. +}
  228864. +
  228865. +static void fsl_hdmi_get_playback_sample_size(void)
  228866. +{
  228867. + int i = 0;
  228868. +
  228869. + /* Always assume basic audio support */
  228870. + playback_sample_size[i++] = 16;
  228871. +
  228872. + if (edid_cfg.sample_sizes & 0x4)
  228873. + playback_sample_size[i++] = 32;
  228874. +
  228875. + playback_constraint_bits.list = playback_sample_size;
  228876. + playback_constraint_bits.count = i;
  228877. +
  228878. + for (i = 0 ; i < playback_constraint_bits.count ; i++)
  228879. + pr_debug("%s: constraint = %d bits\n", __func__, playback_sample_size[i]);
  228880. +}
  228881. +
  228882. +static void fsl_hdmi_get_playback_channels(void)
  228883. +{
  228884. + int channels = 2, i = 0;
  228885. +
  228886. + /* Always assume basic audio support */
  228887. + playback_channels[i++] = channels;
  228888. + channels += 2;
  228889. +
  228890. + while ((i < HDMI_MAX_CHANNEL_CONSTRAINTS) &&
  228891. + (channels <= edid_cfg.max_channels)) {
  228892. + playback_channels[i++] = channels;
  228893. + channels += 2;
  228894. + }
  228895. +
  228896. + playback_constraint_channels.list = playback_channels;
  228897. + playback_constraint_channels.count = i;
  228898. +
  228899. + for (i = 0 ; i < playback_constraint_channels.count ; i++)
  228900. + pr_debug("%s: constraint = %d channels\n", __func__, playback_channels[i]);
  228901. +}
  228902. +
  228903. +static int fsl_hdmi_update_constraints(struct snd_pcm_substream *substream)
  228904. +{
  228905. + struct snd_pcm_runtime *runtime = substream->runtime;
  228906. + int ret;
  228907. +
  228908. + hdmi_get_edid_cfg(&edid_cfg);
  228909. +
  228910. + fsl_hdmi_get_playback_rates();
  228911. + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  228912. + &playback_constraint_rates);
  228913. + if (ret)
  228914. + return ret;
  228915. +
  228916. + fsl_hdmi_get_playback_sample_size();
  228917. + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
  228918. + &playback_constraint_bits);
  228919. + if (ret)
  228920. + return ret;
  228921. +
  228922. + fsl_hdmi_get_playback_channels();
  228923. + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
  228924. + &playback_constraint_channels);
  228925. + if (ret)
  228926. + return ret;
  228927. +
  228928. + ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
  228929. + if (ret)
  228930. + return ret;
  228931. +
  228932. + return 0;
  228933. +}
  228934. +
  228935. +static int fsl_hdmi_soc_startup(struct snd_pcm_substream *substream,
  228936. + struct snd_soc_dai *dai)
  228937. +{
  228938. + struct imx_hdmi *hdmi_data = snd_soc_dai_get_drvdata(dai);
  228939. + int ret;
  228940. +
  228941. + clk_prepare_enable(hdmi_data->isfr_clk);
  228942. + clk_prepare_enable(hdmi_data->iahb_clk);
  228943. +
  228944. + dev_dbg(dai->dev, "%s hdmi clks: isfr:%d iahb:%d\n", __func__,
  228945. + (int)clk_get_rate(hdmi_data->isfr_clk),
  228946. + (int)clk_get_rate(hdmi_data->iahb_clk));
  228947. +
  228948. + ret = fsl_hdmi_update_constraints(substream);
  228949. + if (ret < 0)
  228950. + return ret;
  228951. +
  228952. + /* Indicates the subpacket represents a flatline sample */
  228953. + hdmi_audio_writeb(FC_AUDSCONF, AUD_PACKET_SAMPFIT, 0x0);
  228954. +
  228955. + return 0;
  228956. +}
  228957. +
  228958. +static void fsl_hdmi_soc_shutdown(struct snd_pcm_substream *substream,
  228959. + struct snd_soc_dai *dai)
  228960. +{
  228961. + struct imx_hdmi *hdmi_data = snd_soc_dai_get_drvdata(dai);
  228962. +
  228963. + clk_disable_unprepare(hdmi_data->iahb_clk);
  228964. + clk_disable_unprepare(hdmi_data->isfr_clk);
  228965. +}
  228966. +
  228967. +static int fsl_hdmi_soc_prepare(struct snd_pcm_substream *substream,
  228968. + struct snd_soc_dai *dai)
  228969. +{
  228970. + struct snd_pcm_runtime *runtime = substream->runtime;
  228971. +
  228972. + hdmi_set_audio_infoframe(runtime->channels);
  228973. + hdmi_audio_writeb(FC_AUDSCONF, AUD_PACKET_LAYOUT,
  228974. + (runtime->channels > 2) ? 0x1 : 0x0);
  228975. + hdmi_set_sample_rate(runtime->rate);
  228976. + dumpregs(dai);
  228977. +
  228978. + return 0;
  228979. +}
  228980. +
  228981. +static struct snd_soc_dai_ops fsl_hdmi_soc_dai_ops = {
  228982. + .startup = fsl_hdmi_soc_startup,
  228983. + .shutdown = fsl_hdmi_soc_shutdown,
  228984. + .prepare = fsl_hdmi_soc_prepare,
  228985. +};
  228986. +
  228987. +/* IEC60958 status functions */
  228988. +static int fsl_hdmi_iec_info(struct snd_kcontrol *kcontrol,
  228989. + struct snd_ctl_elem_info *uinfo)
  228990. +{
  228991. + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
  228992. + uinfo->count = 1;
  228993. +
  228994. + return 0;
  228995. +}
  228996. +
  228997. +
  228998. +static int fsl_hdmi_iec_get(struct snd_kcontrol *kcontrol,
  228999. + struct snd_ctl_elem_value *uvalue)
  229000. +{
  229001. + int i;
  229002. +
  229003. + for (i = 0 ; i < 4 ; i++)
  229004. + uvalue->value.iec958.status[i] = iec_header.status[i];
  229005. +
  229006. + return 0;
  229007. +}
  229008. +
  229009. +static int fsl_hdmi_iec_put(struct snd_kcontrol *kcontrol,
  229010. + struct snd_ctl_elem_value *uvalue)
  229011. +{
  229012. + int i;
  229013. +
  229014. + /* Do not allow professional mode */
  229015. + if (uvalue->value.iec958.status[0] & IEC958_AES0_PROFESSIONAL)
  229016. + return -EPERM;
  229017. +
  229018. + for (i = 0 ; i < 4 ; i++) {
  229019. + iec_header.status[i] = uvalue->value.iec958.status[i];
  229020. + pr_debug("%s status[%d]=0x%02x\n", __func__, i, iec_header.status[i]);
  229021. + }
  229022. +
  229023. + return 0;
  229024. +}
  229025. +
  229026. +static struct snd_kcontrol_new fsl_hdmi_ctrls[] = {
  229027. + /* Status cchanel controller */
  229028. + {
  229029. + .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  229030. + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
  229031. + .access = SNDRV_CTL_ELEM_ACCESS_READ |
  229032. + SNDRV_CTL_ELEM_ACCESS_WRITE |
  229033. + SNDRV_CTL_ELEM_ACCESS_VOLATILE,
  229034. + .info = fsl_hdmi_iec_info,
  229035. + .get = fsl_hdmi_iec_get,
  229036. + .put = fsl_hdmi_iec_put,
  229037. + },
  229038. +};
  229039. +
  229040. +static int fsl_hdmi_soc_dai_probe(struct snd_soc_dai *dai)
  229041. +{
  229042. + int ret;
  229043. +
  229044. + init_channel_allocations();
  229045. +
  229046. + ret = snd_soc_add_dai_controls(dai, fsl_hdmi_ctrls,
  229047. + ARRAY_SIZE(fsl_hdmi_ctrls));
  229048. + if (ret)
  229049. + dev_warn(dai->dev, "failed to add dai controls\n");
  229050. +
  229051. + return 0;
  229052. +}
  229053. +
  229054. +static struct snd_soc_dai_driver fsl_hdmi_dai = {
  229055. + .probe = &fsl_hdmi_soc_dai_probe,
  229056. + .playback = {
  229057. + .channels_min = 2,
  229058. + .channels_max = 8,
  229059. + .rates = MXC_HDMI_RATES_PLAYBACK,
  229060. + .formats = MXC_HDMI_FORMATS_PLAYBACK,
  229061. + },
  229062. + .ops = &fsl_hdmi_soc_dai_ops,
  229063. +};
  229064. +
  229065. +static const struct snd_soc_component_driver fsl_hdmi_component = {
  229066. + .name = "fsl-hdmi",
  229067. +};
  229068. +
  229069. +static int fsl_hdmi_dai_probe(struct platform_device *pdev)
  229070. +{
  229071. + struct device_node *np = pdev->dev.of_node;
  229072. + struct imx_hdmi *hdmi_data;
  229073. + int ret = 0;
  229074. +
  229075. + if (!np)
  229076. + return -ENODEV;
  229077. +
  229078. + if (!hdmi_get_registered()) {
  229079. + dev_err(&pdev->dev, "failed to probe. Load HDMI-video first.\n");
  229080. + return -ENOMEM;
  229081. + }
  229082. +
  229083. + hdmi_data = devm_kzalloc(&pdev->dev, sizeof(*hdmi_data), GFP_KERNEL);
  229084. + if (!hdmi_data) {
  229085. + dev_err(&pdev->dev, "failed to alloc hdmi_data\n");
  229086. + return -ENOMEM;
  229087. + }
  229088. +
  229089. + hdmi_data->pdev = pdev;
  229090. +
  229091. + memcpy(&hdmi_data->cpu_dai_drv, &fsl_hdmi_dai, sizeof(fsl_hdmi_dai));
  229092. + hdmi_data->cpu_dai_drv.name = np->name;
  229093. +
  229094. + hdmi_data->isfr_clk = devm_clk_get(&pdev->dev, "hdmi_isfr");
  229095. + if (IS_ERR(hdmi_data->isfr_clk)) {
  229096. + ret = PTR_ERR(hdmi_data->isfr_clk);
  229097. + dev_err(&pdev->dev, "failed to get HDMI isfr clk: %d\n", ret);
  229098. + return -EINVAL;
  229099. + }
  229100. +
  229101. + hdmi_data->iahb_clk = devm_clk_get(&pdev->dev, "hdmi_iahb");
  229102. + if (IS_ERR(hdmi_data->iahb_clk)) {
  229103. + ret = PTR_ERR(hdmi_data->iahb_clk);
  229104. + dev_err(&pdev->dev, "failed to get HDMI ahb clk: %d\n", ret);
  229105. + return -EINVAL;
  229106. + }
  229107. +
  229108. + dev_set_drvdata(&pdev->dev, hdmi_data);
  229109. + ret = snd_soc_register_component(&pdev->dev, &fsl_hdmi_component,
  229110. + &hdmi_data->cpu_dai_drv, 1);
  229111. + if (ret) {
  229112. + dev_err(&pdev->dev, "register DAI failed\n");
  229113. + return ret;
  229114. + }
  229115. +
  229116. + hdmi_data->codec_dev = platform_device_register_simple(
  229117. + "hdmi-audio-codec", -1, NULL, 0);
  229118. + if (IS_ERR(hdmi_data->codec_dev)) {
  229119. + dev_err(&pdev->dev, "failed to register HDMI audio codec\n");
  229120. + ret = PTR_ERR(hdmi_data->codec_dev);
  229121. + goto fail;
  229122. + }
  229123. +
  229124. + hdmi_data->dma_dev = platform_device_alloc("imx-hdmi-audio", -1);
  229125. + if (IS_ERR(hdmi_data->dma_dev)) {
  229126. + ret = PTR_ERR(hdmi_data->dma_dev);
  229127. + goto fail_dma;
  229128. + }
  229129. +
  229130. + platform_set_drvdata(hdmi_data->dma_dev, hdmi_data);
  229131. +
  229132. + ret = platform_device_add(hdmi_data->dma_dev);
  229133. + if (ret) {
  229134. + platform_device_put(hdmi_data->dma_dev);
  229135. + goto fail_dma;
  229136. + }
  229137. +
  229138. + return 0;
  229139. +
  229140. +fail_dma:
  229141. + platform_device_unregister(hdmi_data->codec_dev);
  229142. +fail:
  229143. + snd_soc_unregister_component(&pdev->dev);
  229144. +
  229145. + return ret;
  229146. +}
  229147. +
  229148. +static int fsl_hdmi_dai_remove(struct platform_device *pdev)
  229149. +{
  229150. + struct imx_hdmi *hdmi_data = platform_get_drvdata(pdev);
  229151. +
  229152. + platform_device_unregister(hdmi_data->dma_dev);
  229153. + platform_device_unregister(hdmi_data->codec_dev);
  229154. + snd_soc_unregister_component(&pdev->dev);
  229155. +
  229156. + return 0;
  229157. +}
  229158. +
  229159. +static const struct of_device_id fsl_hdmi_dai_dt_ids[] = {
  229160. + { .compatible = "fsl,imx6dl-hdmi-audio", },
  229161. + { .compatible = "fsl,imx6q-hdmi-audio", },
  229162. + { /* sentinel */ }
  229163. +};
  229164. +MODULE_DEVICE_TABLE(of, fsl_hdmi_dai_dt_ids);
  229165. +
  229166. +static struct platform_driver fsl_hdmi_driver = {
  229167. + .probe = fsl_hdmi_dai_probe,
  229168. + .remove = fsl_hdmi_dai_remove,
  229169. + .driver = {
  229170. + .name = "fsl-hdmi-dai",
  229171. + .owner = THIS_MODULE,
  229172. + .of_match_table = fsl_hdmi_dai_dt_ids,
  229173. + },
  229174. +};
  229175. +module_platform_driver(fsl_hdmi_driver);
  229176. +
  229177. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  229178. +MODULE_DESCRIPTION("IMX HDMI TX DAI");
  229179. +MODULE_LICENSE("GPL");
  229180. +MODULE_ALIAS("platform:fsl-hdmi-dai");
  229181. diff -Nur linux-3.14.15/sound/soc/fsl/fsl_spdif.c linux-linaro-stable-mx6/sound/soc/fsl/fsl_spdif.c
  229182. --- linux-3.14.15/sound/soc/fsl/fsl_spdif.c 2014-07-31 23:51:43.000000000 +0200
  229183. +++ linux-linaro-stable-mx6/sound/soc/fsl/fsl_spdif.c 2014-08-20 19:31:58.744923167 +0200
  229184. @@ -21,6 +21,8 @@
  229185. #include <linux/of_address.h>
  229186. #include <linux/of_device.h>
  229187. #include <linux/of_irq.h>
  229188. +#include <linux/pm_runtime.h>
  229189. +#include <linux/busfreq-imx6.h>
  229190. #include <sound/asoundef.h>
  229191. #include <sound/soc.h>
  229192. @@ -53,7 +55,7 @@
  229193. spinlock_t ctl_lock;
  229194. /* IEC958 channel tx status bit */
  229195. - unsigned char ch_status[4];
  229196. + unsigned char ch_status[6];
  229197. /* User bits */
  229198. unsigned char subcode[2 * SPDIF_UBITS_SIZE];
  229199. @@ -80,6 +82,7 @@
  229200. u8 rxclk_src;
  229201. struct clk *txclk[SPDIF_TXRATE_MAX];
  229202. struct clk *rxclk;
  229203. + struct clk *sysclk;
  229204. struct snd_dmaengine_dai_dma_data dma_params_tx;
  229205. struct snd_dmaengine_dai_dma_data dma_params_rx;
  229206. @@ -295,11 +298,11 @@
  229207. return -EBUSY;
  229208. }
  229209. -static void spdif_set_cstatus(struct spdif_mixer_control *ctrl,
  229210. - u8 mask, u8 cstatus)
  229211. +static inline void spdif_set_cstatus(struct spdif_mixer_control *ctrl,
  229212. + u8 byteno, u8 mask, u8 cstatus)
  229213. {
  229214. - ctrl->ch_status[3] &= ~mask;
  229215. - ctrl->ch_status[3] |= cstatus & mask;
  229216. + ctrl->ch_status[byteno] &= ~mask;
  229217. + ctrl->ch_status[byteno] |= cstatus & mask;
  229218. }
  229219. static void spdif_write_channel_status(struct fsl_spdif_priv *spdif_priv)
  229220. @@ -316,10 +319,16 @@
  229221. dev_dbg(&pdev->dev, "STCSCH: 0x%06x\n", ch_status);
  229222. - ch_status = bitrev8(ctrl->ch_status[3]) << 16;
  229223. + ch_status = bitrev8(ctrl->ch_status[3]) << 16 |
  229224. + (bitrev8(ctrl->ch_status[4]) << 8) |
  229225. + bitrev8(ctrl->ch_status[5]);
  229226. regmap_write(regmap, REG_SPDIF_STCSCL, ch_status);
  229227. dev_dbg(&pdev->dev, "STCSCL: 0x%06x\n", ch_status);
  229228. +
  229229. + /* Set outgoing validity (0: pcm, 1: non-audio) */
  229230. + regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_VAL_MASK,
  229231. + (ctrl->ch_status[0] & IEC958_AES0_NONAUDIO) ? 0 : SCR_VAL_CLEAR);
  229232. }
  229233. /* Set SPDIF PhaseConfig register for rx clock */
  229234. @@ -347,23 +356,45 @@
  229235. struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
  229236. struct regmap *regmap = spdif_priv->regmap;
  229237. struct platform_device *pdev = spdif_priv->pdev;
  229238. - unsigned long csfs = 0;
  229239. u32 stc, mask, rate;
  229240. - u8 clk, div;
  229241. + u8 clk, div, csfs, csofs;
  229242. int ret;
  229243. switch (sample_rate) {
  229244. case 32000:
  229245. rate = SPDIF_TXRATE_32000;
  229246. csfs = IEC958_AES3_CON_FS_32000;
  229247. + csofs = IEC958_AES4_CON_ORIGFS_32000;
  229248. break;
  229249. case 44100:
  229250. rate = SPDIF_TXRATE_44100;
  229251. csfs = IEC958_AES3_CON_FS_44100;
  229252. + csofs = IEC958_AES4_CON_ORIGFS_44100;
  229253. break;
  229254. case 48000:
  229255. rate = SPDIF_TXRATE_48000;
  229256. csfs = IEC958_AES3_CON_FS_48000;
  229257. + csofs = IEC958_AES4_CON_ORIGFS_48000;
  229258. + break;
  229259. + case 88200:
  229260. + rate = SPDIF_TXRATE_88200;
  229261. + csfs = IEC958_AES3_CON_FS_88200;
  229262. + csofs = IEC958_AES4_CON_ORIGFS_88200;
  229263. + break;
  229264. + case 96000:
  229265. + rate = SPDIF_TXRATE_96000;
  229266. + csfs = IEC958_AES3_CON_FS_96000;
  229267. + csofs = IEC958_AES4_CON_ORIGFS_96000;
  229268. + break;
  229269. + case 176400:
  229270. + rate = SPDIF_TXRATE_176400;
  229271. + csfs = IEC958_AES3_CON_FS_176400;
  229272. + csofs = IEC958_AES4_CON_ORIGFS_176400;
  229273. + break;
  229274. + case 192000:
  229275. + rate = SPDIF_TXRATE_192000;
  229276. + csfs = IEC958_AES3_CON_FS_192000;
  229277. + csofs = IEC958_AES4_CON_ORIGFS_192000;
  229278. break;
  229279. default:
  229280. dev_err(&pdev->dev, "unsupported sample rate %d\n", sample_rate);
  229281. @@ -399,7 +430,8 @@
  229282. clk_get_rate(spdif_priv->txclk[rate]));
  229283. /* set fs field in consumer channel status */
  229284. - spdif_set_cstatus(ctrl, IEC958_AES3_CON_FS, csfs);
  229285. + spdif_set_cstatus(ctrl, 3, IEC958_AES3_CON_FS, csfs);
  229286. + spdif_set_cstatus(ctrl, 4, IEC958_AES4_CON_ORIGFS, csofs);
  229287. /* select clock source and divisor */
  229288. stc = STC_TXCLK_ALL_EN | STC_TXCLK_SRC_SET(clk) | STC_TXCLK_DIV(div);
  229289. @@ -421,6 +453,8 @@
  229290. u32 scr, mask, i;
  229291. int ret;
  229292. + pm_runtime_get_sync(cpu_dai->dev);
  229293. +
  229294. /* Reset module and interrupts only for first initialization */
  229295. if (!cpu_dai->active) {
  229296. ret = spdif_softreset(spdif_priv);
  229297. @@ -485,6 +519,8 @@
  229298. regmap_update_bits(regmap, REG_SPDIF_SCR,
  229299. SCR_LOW_POWER, SCR_LOW_POWER);
  229300. }
  229301. +
  229302. + pm_runtime_put_sync(cpu_dai->dev);
  229303. }
  229304. static int fsl_spdif_hw_params(struct snd_pcm_substream *substream,
  229305. @@ -505,8 +541,8 @@
  229306. __func__, sample_rate);
  229307. return ret;
  229308. }
  229309. - spdif_set_cstatus(ctrl, IEC958_AES3_CON_CLOCK,
  229310. - IEC958_AES3_CON_CLOCK_1000PPM);
  229311. + spdif_set_cstatus(ctrl, 3, IEC958_AES3_CON_CLOCK,
  229312. + IEC958_AES3_CON_CLOCK_1000PPM);
  229313. spdif_write_channel_status(spdif_priv);
  229314. } else {
  229315. /* Setup rx clock source */
  229316. @@ -576,14 +612,13 @@
  229317. static int fsl_spdif_pb_get(struct snd_kcontrol *kcontrol,
  229318. struct snd_ctl_elem_value *uvalue)
  229319. {
  229320. + int i;
  229321. struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
  229322. struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
  229323. struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
  229324. - uvalue->value.iec958.status[0] = ctrl->ch_status[0];
  229325. - uvalue->value.iec958.status[1] = ctrl->ch_status[1];
  229326. - uvalue->value.iec958.status[2] = ctrl->ch_status[2];
  229327. - uvalue->value.iec958.status[3] = ctrl->ch_status[3];
  229328. + for (i = 0; i < ARRAY_SIZE(ctrl->ch_status); i++)
  229329. + uvalue->value.iec958.status[i] = ctrl->ch_status[i];
  229330. return 0;
  229331. }
  229332. @@ -591,14 +626,13 @@
  229333. static int fsl_spdif_pb_put(struct snd_kcontrol *kcontrol,
  229334. struct snd_ctl_elem_value *uvalue)
  229335. {
  229336. + int i;
  229337. struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
  229338. struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
  229339. struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
  229340. - ctrl->ch_status[0] = uvalue->value.iec958.status[0];
  229341. - ctrl->ch_status[1] = uvalue->value.iec958.status[1];
  229342. - ctrl->ch_status[2] = uvalue->value.iec958.status[2];
  229343. - ctrl->ch_status[3] = uvalue->value.iec958.status[3];
  229344. + for (i = 0; i < ARRAY_SIZE(ctrl->ch_status); i++)
  229345. + ctrl->ch_status[i] = uvalue->value.iec958.status[i];
  229346. spdif_write_channel_status(spdif_priv);
  229347. @@ -754,7 +788,7 @@
  229348. clksrc = (phaseconf >> SRPC_CLKSRC_SEL_OFFSET) & 0xf;
  229349. if (srpc_dpll_locked[clksrc] && (phaseconf & SRPC_DPLL_LOCKED)) {
  229350. /* Get bus clock from system */
  229351. - busclk_freq = clk_get_rate(spdif_priv->rxclk);
  229352. + busclk_freq = clk_get_rate(spdif_priv->sysclk);
  229353. }
  229354. /* FreqMeas_CLK = (BUS_CLK * FreqMeas) / 2 ^ 10 / GAINSEL / 128 */
  229355. @@ -999,7 +1033,7 @@
  229356. struct clk *clk, u64 savesub,
  229357. enum spdif_txrate index)
  229358. {
  229359. - const u32 rate[] = { 32000, 44100, 48000 };
  229360. + const u32 rate[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 };
  229361. u64 rate_ideal, rate_actual, sub;
  229362. u32 div, arate;
  229363. @@ -1017,7 +1051,7 @@
  229364. break;
  229365. } else if (arate / rate[index] == 1) {
  229366. /* A little bigger than expect */
  229367. - sub = (arate - rate[index]) * 100000;
  229368. + sub = (u64)(arate - rate[index]) * 100000;
  229369. do_div(sub, rate[index]);
  229370. if (sub < savesub) {
  229371. savesub = sub;
  229372. @@ -1025,7 +1059,7 @@
  229373. }
  229374. } else if (rate[index] / arate == 1) {
  229375. /* A little smaller than expect */
  229376. - sub = (rate[index] - arate) * 100000;
  229377. + sub = (u64)(rate[index] - arate) * 100000;
  229378. do_div(sub, rate[index]);
  229379. if (sub < savesub) {
  229380. savesub = sub;
  229381. @@ -1040,7 +1074,7 @@
  229382. static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
  229383. enum spdif_txrate index)
  229384. {
  229385. - const u32 rate[] = { 32000, 44100, 48000 };
  229386. + const u32 rate[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 };
  229387. struct platform_device *pdev = spdif_priv->pdev;
  229388. struct device *dev = &pdev->dev;
  229389. u64 savesub = 100000, ret;
  229390. @@ -1058,6 +1092,13 @@
  229391. if (!clk_get_rate(clk))
  229392. continue;
  229393. + /* TODO: We here ignore sysclk source due to imperfect clock
  229394. + * selecting mechanism: sysclk is a bit different which we can
  229395. + * not change its clock rate but use another inner divider to
  229396. + * derive a proper clock rate. */
  229397. + if (i == SPDIF_CLK_SRC_SYSCLK)
  229398. + continue;
  229399. +
  229400. ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index);
  229401. if (savesub == ret)
  229402. continue;
  229403. @@ -1131,6 +1172,13 @@
  229404. return ret;
  229405. }
  229406. + /* Get system clock for rx clock rate calculation */
  229407. + spdif_priv->sysclk = devm_clk_get(&pdev->dev, "rxtx5");
  229408. + if (IS_ERR(spdif_priv->sysclk)) {
  229409. + dev_err(&pdev->dev, "no system clock(rxtx5) in devicetree\n");
  229410. + return PTR_ERR(spdif_priv->sysclk);
  229411. + }
  229412. +
  229413. /* Select clock source for rx/tx clock */
  229414. spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1");
  229415. if (IS_ERR(spdif_priv->rxclk)) {
  229416. @@ -1150,12 +1198,13 @@
  229417. spin_lock_init(&ctrl->ctl_lock);
  229418. /* Init tx channel status default value */
  229419. - ctrl->ch_status[0] =
  229420. - IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_5015;
  229421. + ctrl->ch_status[0] = IEC958_AES0_CON_NOT_COPYRIGHT;
  229422. ctrl->ch_status[1] = IEC958_AES1_CON_DIGDIGCONV_ID;
  229423. ctrl->ch_status[2] = 0x00;
  229424. ctrl->ch_status[3] =
  229425. IEC958_AES3_CON_FS_44100 | IEC958_AES3_CON_CLOCK_1000PPM;
  229426. + ctrl->ch_status[4] = IEC958_AES4_CON_ORIGFS_44100;
  229427. + ctrl->ch_status[5] = IEC958_AES5_CON_CGMSA_COPYFREELY;
  229428. spdif_priv->dpll_locked = false;
  229429. @@ -1164,6 +1213,8 @@
  229430. spdif_priv->dma_params_tx.addr = res->start + REG_SPDIF_STL;
  229431. spdif_priv->dma_params_rx.addr = res->start + REG_SPDIF_SRL;
  229432. + pm_runtime_enable(&pdev->dev);
  229433. +
  229434. /* Register with ASoC */
  229435. dev_set_drvdata(&pdev->dev, spdif_priv);
  229436. @@ -1174,13 +1225,34 @@
  229437. return ret;
  229438. }
  229439. - ret = imx_pcm_dma_init(pdev);
  229440. + ret = imx_pcm_dma_init(pdev, SND_DMAENGINE_PCM_FLAG_COMPAT,
  229441. + IMX_SPDIF_DMABUF_SIZE);
  229442. if (ret)
  229443. dev_err(&pdev->dev, "imx_pcm_dma_init failed: %d\n", ret);
  229444. return ret;
  229445. }
  229446. +#ifdef CONFIG_PM_RUNTIME
  229447. +static int fsl_spdif_runtime_resume(struct device *dev)
  229448. +{
  229449. + request_bus_freq(BUS_FREQ_HIGH);
  229450. + return 0;
  229451. +}
  229452. +
  229453. +static int fsl_spdif_runtime_suspend(struct device *dev)
  229454. +{
  229455. + release_bus_freq(BUS_FREQ_HIGH);
  229456. + return 0;
  229457. +}
  229458. +#endif
  229459. +
  229460. +static const struct dev_pm_ops fsl_spdif_pm = {
  229461. + SET_RUNTIME_PM_OPS(fsl_spdif_runtime_suspend,
  229462. + fsl_spdif_runtime_resume,
  229463. + NULL)
  229464. +};
  229465. +
  229466. static const struct of_device_id fsl_spdif_dt_ids[] = {
  229467. { .compatible = "fsl,imx35-spdif", },
  229468. {}
  229469. @@ -1192,6 +1264,7 @@
  229470. .name = "fsl-spdif-dai",
  229471. .owner = THIS_MODULE,
  229472. .of_match_table = fsl_spdif_dt_ids,
  229473. + .pm = &fsl_spdif_pm,
  229474. },
  229475. .probe = fsl_spdif_probe,
  229476. };
  229477. diff -Nur linux-3.14.15/sound/soc/fsl/fsl_spdif.h linux-linaro-stable-mx6/sound/soc/fsl/fsl_spdif.h
  229478. --- linux-3.14.15/sound/soc/fsl/fsl_spdif.h 2014-07-31 23:51:43.000000000 +0200
  229479. +++ linux-linaro-stable-mx6/sound/soc/fsl/fsl_spdif.h 2014-08-20 19:31:58.744923167 +0200
  229480. @@ -157,13 +157,19 @@
  229481. #define STC_TXCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_TXCLK_DIV_MASK)
  229482. #define STC_TXCLK_SRC_MAX 8
  229483. +#define SPDIF_CLK_SRC_SYSCLK 5
  229484. +
  229485. /* SPDIF tx rate */
  229486. enum spdif_txrate {
  229487. SPDIF_TXRATE_32000 = 0,
  229488. SPDIF_TXRATE_44100,
  229489. SPDIF_TXRATE_48000,
  229490. + SPDIF_TXRATE_88200,
  229491. + SPDIF_TXRATE_96000,
  229492. + SPDIF_TXRATE_176400,
  229493. + SPDIF_TXRATE_192000,
  229494. };
  229495. -#define SPDIF_TXRATE_MAX (SPDIF_TXRATE_48000 + 1)
  229496. +#define SPDIF_TXRATE_MAX (SPDIF_TXRATE_192000 + 1)
  229497. #define SPDIF_CSTATUS_BYTE 6
  229498. @@ -173,7 +179,11 @@
  229499. #define FSL_SPDIF_RATES_PLAYBACK (SNDRV_PCM_RATE_32000 | \
  229500. SNDRV_PCM_RATE_44100 | \
  229501. - SNDRV_PCM_RATE_48000)
  229502. + SNDRV_PCM_RATE_48000 | \
  229503. + SNDRV_PCM_RATE_88200 | \
  229504. + SNDRV_PCM_RATE_96000 | \
  229505. + SNDRV_PCM_RATE_176400| \
  229506. + SNDRV_PCM_RATE_192000)
  229507. #define FSL_SPDIF_RATES_CAPTURE (SNDRV_PCM_RATE_16000 | \
  229508. SNDRV_PCM_RATE_32000 | \
  229509. diff -Nur linux-3.14.15/sound/soc/fsl/fsl_ssi.c linux-linaro-stable-mx6/sound/soc/fsl/fsl_ssi.c
  229510. --- linux-3.14.15/sound/soc/fsl/fsl_ssi.c 2014-07-31 23:51:43.000000000 +0200
  229511. +++ linux-linaro-stable-mx6/sound/soc/fsl/fsl_ssi.c 2014-08-20 19:31:58.744923167 +0200
  229512. @@ -3,7 +3,7 @@
  229513. *
  229514. * Author: Timur Tabi <timur@freescale.com>
  229515. *
  229516. - * Copyright 2007-2010 Freescale Semiconductor, Inc.
  229517. + * Copyright (C) 2007-2013 Freescale Semiconductor, Inc.
  229518. *
  229519. * This file is licensed under the terms of the GNU General Public License
  229520. * version 2. This program is licensed "as is" without any warranty of any
  229521. @@ -30,6 +30,7 @@
  229522. * around this by not polling these bits but only wait a fixed delay.
  229523. */
  229524. +#include <linux/busfreq-imx6.h>
  229525. #include <linux/init.h>
  229526. #include <linux/io.h>
  229527. #include <linux/module.h>
  229528. @@ -43,6 +44,7 @@
  229529. #include <linux/of_address.h>
  229530. #include <linux/of_irq.h>
  229531. #include <linux/of_platform.h>
  229532. +#include <linux/pm_runtime.h>
  229533. #include <sound/core.h>
  229534. #include <sound/pcm.h>
  229535. @@ -73,6 +75,24 @@
  229536. }
  229537. #endif
  229538. +#ifdef DEBUG
  229539. +#define NUM_OF_SSI_REG (sizeof(struct ccsr_ssi) / sizeof(__be32))
  229540. +
  229541. +void dump_reg(struct ccsr_ssi __iomem *ssi)
  229542. +{
  229543. + u32 val, i;
  229544. +
  229545. + for (i = 0; i < NUM_OF_SSI_REG; i++) {
  229546. + if (&ssi->stx0 + i == NULL)
  229547. + continue;
  229548. + val = read_ssi(&ssi->stx0 + i);
  229549. + pr_debug("REG %x = %x\n", (u32)(&ssi->stx0 + i) & 0xff, val);
  229550. + }
  229551. +}
  229552. +#else
  229553. +void dump_reg(struct ccsr_ssi __iomem *ssi) {}
  229554. +#endif
  229555. +
  229556. /**
  229557. * FSLSSI_I2S_RATES: sample rates supported by the I2S
  229558. *
  229559. @@ -171,8 +191,6 @@
  229560. struct clk *clk;
  229561. struct snd_dmaengine_dai_dma_data dma_params_tx;
  229562. struct snd_dmaengine_dai_dma_data dma_params_rx;
  229563. - struct imx_dma_data filter_data_tx;
  229564. - struct imx_dma_data filter_data_rx;
  229565. struct imx_pcm_fiq_params fiq_params;
  229566. /* Register values for rx/tx configuration */
  229567. struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
  229568. @@ -206,6 +224,26 @@
  229569. char name[1];
  229570. };
  229571. +#ifdef CONFIG_PM_RUNTIME
  229572. +static int fsl_ssi_runtime_resume(struct device *dev)
  229573. +{
  229574. + request_bus_freq(BUS_FREQ_AUDIO);
  229575. + return 0;
  229576. +}
  229577. +
  229578. +static int fsl_ssi_runtime_suspend(struct device *dev)
  229579. +{
  229580. + release_bus_freq(BUS_FREQ_AUDIO);
  229581. + return 0;
  229582. +}
  229583. +#endif
  229584. +
  229585. +static const struct dev_pm_ops fsl_ssi_pm = {
  229586. + SET_RUNTIME_PM_OPS(fsl_ssi_runtime_suspend,
  229587. + fsl_ssi_runtime_resume,
  229588. + NULL)
  229589. +};
  229590. +
  229591. static const struct of_device_id fsl_ssi_ids[] = {
  229592. { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610},
  229593. { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51},
  229594. @@ -489,6 +527,23 @@
  229595. }
  229596. }
  229597. +static void fsl_ssi_clk_ctrl(struct fsl_ssi_private *ssi_private, bool enable)
  229598. +{
  229599. + if (enable) {
  229600. + if (ssi_private->ssi_on_imx) {
  229601. + if (!IS_ERR(ssi_private->baudclk))
  229602. + clk_enable(ssi_private->baudclk);
  229603. + clk_enable(ssi_private->clk);
  229604. + }
  229605. + } else {
  229606. + if (ssi_private->ssi_on_imx) {
  229607. + if (!IS_ERR(ssi_private->baudclk))
  229608. + clk_disable(ssi_private->baudclk);
  229609. + clk_disable(ssi_private->clk);
  229610. + }
  229611. + }
  229612. +}
  229613. +
  229614. /*
  229615. * Enable/Disable a ssi configuration. You have to pass either
  229616. * ssi_private->rxtx_reg_val.rx or tx as vals parameter.
  229617. @@ -509,6 +564,8 @@
  229618. else
  229619. avals = &ssi_private->rxtx_reg_val.rx;
  229620. + fsl_ssi_clk_ctrl(ssi_private, enable);
  229621. +
  229622. /* If vals should be disabled, start with disabling the unit */
  229623. if (!enable) {
  229624. u32 scr = vals->scr & (vals->scr ^ avals->scr);
  229625. @@ -748,6 +805,8 @@
  229626. snd_soc_dai_get_drvdata(rtd->cpu_dai);
  229627. unsigned long flags;
  229628. + pm_runtime_get_sync(dai->dev);
  229629. +
  229630. /* First, we only do fsl_ssi_setup() when SSI is going to be active.
  229631. * Second, fsl_ssi_setup was already called by ac97_init earlier if
  229632. * the driver is in ac97 mode.
  229633. @@ -1083,14 +1142,17 @@
  229634. switch (cmd) {
  229635. case SNDRV_PCM_TRIGGER_START:
  229636. + case SNDRV_PCM_TRIGGER_RESUME:
  229637. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  229638. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  229639. fsl_ssi_tx_config(ssi_private, true);
  229640. else
  229641. fsl_ssi_rx_config(ssi_private, true);
  229642. + dump_reg(ssi);
  229643. break;
  229644. case SNDRV_PCM_TRIGGER_STOP:
  229645. + case SNDRV_PCM_TRIGGER_SUSPEND:
  229646. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  229647. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  229648. fsl_ssi_tx_config(ssi_private, false);
  229649. @@ -1119,6 +1181,12 @@
  229650. return 0;
  229651. }
  229652. +static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
  229653. + struct snd_soc_dai *dai)
  229654. +{
  229655. + pm_runtime_put_sync(dai->dev);
  229656. +}
  229657. +
  229658. static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
  229659. {
  229660. struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);
  229661. @@ -1138,6 +1206,7 @@
  229662. .set_sysclk = fsl_ssi_set_dai_sysclk,
  229663. .set_tdm_slot = fsl_ssi_set_dai_tdm_slot,
  229664. .trigger = fsl_ssi_trigger,
  229665. + .shutdown = fsl_ssi_shutdown,
  229666. };
  229667. /* Template for the CPU dai driver structure */
  229668. @@ -1263,7 +1332,6 @@
  229669. const uint32_t *iprop;
  229670. struct resource res;
  229671. char name[64];
  229672. - bool shared;
  229673. bool ac97 = false;
  229674. /* SSIs that are not connected on the board should have a
  229675. @@ -1381,7 +1449,6 @@
  229676. if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 ||
  229677. hw_type == FSL_SSI_MX35) {
  229678. - u32 dma_events[2], dmas[4];
  229679. ssi_private->ssi_on_imx = true;
  229680. ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
  229681. @@ -1390,9 +1457,9 @@
  229682. dev_err(&pdev->dev, "could not get clock: %d\n", ret);
  229683. goto error_irqmap;
  229684. }
  229685. - ret = clk_prepare_enable(ssi_private->clk);
  229686. + ret = clk_prepare(ssi_private->clk);
  229687. if (ret) {
  229688. - dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n",
  229689. + dev_err(&pdev->dev, "clk_prepare failed: %d\n",
  229690. ret);
  229691. goto error_irqmap;
  229692. }
  229693. @@ -1405,56 +1472,16 @@
  229694. dev_dbg(&pdev->dev, "could not get baud clock: %ld\n",
  229695. PTR_ERR(ssi_private->baudclk));
  229696. else
  229697. - clk_prepare_enable(ssi_private->baudclk);
  229698. + clk_prepare(ssi_private->baudclk);
  229699. /*
  229700. * We have burstsize be "fifo_depth - 2" to match the SSI
  229701. * watermark setting in fsl_ssi_startup().
  229702. */
  229703. - ssi_private->dma_params_tx.maxburst =
  229704. - ssi_private->fifo_depth - 2;
  229705. - ssi_private->dma_params_rx.maxburst =
  229706. - ssi_private->fifo_depth - 2;
  229707. ssi_private->dma_params_tx.addr =
  229708. ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
  229709. ssi_private->dma_params_rx.addr =
  229710. ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
  229711. - ssi_private->dma_params_tx.filter_data =
  229712. - &ssi_private->filter_data_tx;
  229713. - ssi_private->dma_params_rx.filter_data =
  229714. - &ssi_private->filter_data_rx;
  229715. - if (!of_property_read_bool(pdev->dev.of_node, "dmas") &&
  229716. - ssi_private->use_dma) {
  229717. - /*
  229718. - * FIXME: This is a temporary solution until all
  229719. - * necessary dma drivers support the generic dma
  229720. - * bindings.
  229721. - */
  229722. - ret = of_property_read_u32_array(pdev->dev.of_node,
  229723. - "fsl,ssi-dma-events", dma_events, 2);
  229724. - if (ret && ssi_private->use_dma) {
  229725. - dev_err(&pdev->dev, "could not get dma events but fsl-ssi is configured to use DMA\n");
  229726. - goto error_clk;
  229727. - }
  229728. - }
  229729. - /* Should this be merge with the above? */
  229730. - if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4)
  229731. - && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
  229732. - ssi_private->use_dual_fifo = true;
  229733. - /* When using dual fifo mode, we need to keep watermark
  229734. - * as even numbers due to dma script limitation.
  229735. - */
  229736. - ssi_private->dma_params_tx.maxburst &= ~0x1;
  229737. - ssi_private->dma_params_rx.maxburst &= ~0x1;
  229738. - }
  229739. -
  229740. - shared = of_device_is_compatible(of_get_parent(np),
  229741. - "fsl,spba-bus");
  229742. -
  229743. - imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx,
  229744. - dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
  229745. - imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
  229746. - dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
  229747. }
  229748. /*
  229749. @@ -1474,6 +1501,8 @@
  229750. }
  229751. }
  229752. + pm_runtime_enable(&pdev->dev);
  229753. +
  229754. /* Register with ASoC */
  229755. dev_set_drvdata(&pdev->dev, ssi_private);
  229756. @@ -1509,7 +1538,8 @@
  229757. if (ret)
  229758. goto error_pcm;
  229759. } else {
  229760. - ret = imx_pcm_dma_init(pdev);
  229761. + ret = imx_pcm_dma_init(pdev, SND_DMAENGINE_PCM_FLAG_NO_RESIDUE,
  229762. + IMX_SSI_DMABUF_SIZE);
  229763. if (ret)
  229764. goto error_pcm;
  229765. }
  229766. @@ -1565,12 +1595,16 @@
  229767. error_dev:
  229768. device_remove_file(&pdev->dev, dev_attr);
  229769. -error_clk:
  229770. if (ssi_private->ssi_on_imx) {
  229771. if (!IS_ERR(ssi_private->baudclk))
  229772. - clk_disable_unprepare(ssi_private->baudclk);
  229773. - clk_disable_unprepare(ssi_private->clk);
  229774. + clk_unprepare(ssi_private->baudclk);
  229775. + clk_unprepare(ssi_private->clk);
  229776. }
  229777. +error_clk:
  229778. + if (!IS_ERR(ssi_private->baudclk))
  229779. + clk_unprepare(ssi_private->baudclk);
  229780. + if (!IS_ERR(ssi_private->clk))
  229781. + clk_unprepare(ssi_private->clk);
  229782. error_irqmap:
  229783. if (ssi_private->irq_stats)
  229784. @@ -1590,8 +1624,8 @@
  229785. snd_soc_unregister_component(&pdev->dev);
  229786. if (ssi_private->ssi_on_imx) {
  229787. if (!IS_ERR(ssi_private->baudclk))
  229788. - clk_disable_unprepare(ssi_private->baudclk);
  229789. - clk_disable_unprepare(ssi_private->clk);
  229790. + clk_unprepare(ssi_private->baudclk);
  229791. + clk_unprepare(ssi_private->clk);
  229792. }
  229793. if (ssi_private->irq_stats)
  229794. irq_dispose_mapping(ssi_private->irq);
  229795. @@ -1604,6 +1638,7 @@
  229796. .name = "fsl-ssi-dai",
  229797. .owner = THIS_MODULE,
  229798. .of_match_table = fsl_ssi_ids,
  229799. + .pm = &fsl_ssi_pm,
  229800. },
  229801. .probe = fsl_ssi_probe,
  229802. .remove = fsl_ssi_remove,
  229803. diff -Nur linux-3.14.15/sound/soc/fsl/imx-cs42888.c linux-linaro-stable-mx6/sound/soc/fsl/imx-cs42888.c
  229804. --- linux-3.14.15/sound/soc/fsl/imx-cs42888.c 1970-01-01 01:00:00.000000000 +0100
  229805. +++ linux-linaro-stable-mx6/sound/soc/fsl/imx-cs42888.c 2014-08-20 19:31:58.744923167 +0200
  229806. @@ -0,0 +1,369 @@
  229807. +/*
  229808. + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  229809. + */
  229810. +
  229811. +/*
  229812. + * The code contained herein is licensed under the GNU General Public
  229813. + * License. You may obtain a copy of the GNU General Public License
  229814. + * Version 2 or later at the following locations:
  229815. + *
  229816. + * http://www.opensource.org/licenses/gpl-license.html
  229817. + * http://www.gnu.org/copyleft/gpl.html
  229818. + */
  229819. +
  229820. +#include <linux/module.h>
  229821. +#include <linux/of.h>
  229822. +#include <linux/of_platform.h>
  229823. +#include <linux/slab.h>
  229824. +#include <linux/device.h>
  229825. +#include <linux/i2c.h>
  229826. +#include <linux/clk.h>
  229827. +#include <linux/delay.h>
  229828. +#include <sound/core.h>
  229829. +#include <sound/pcm.h>
  229830. +#include <sound/soc.h>
  229831. +#include <sound/initval.h>
  229832. +#include <sound/pcm_params.h>
  229833. +
  229834. +#include "fsl_esai.h"
  229835. +#include "fsl_asrc.h"
  229836. +
  229837. +#define CODEC_CLK_EXTER_OSC 1
  229838. +#define CODEC_CLK_ESAI_HCKT 2
  229839. +
  229840. +struct imx_priv {
  229841. + int hw;
  229842. + int fe_output_rate;
  229843. + int fe_output_width;
  229844. + unsigned int mclk_freq;
  229845. + unsigned int codec_mclk;
  229846. + struct platform_device *pdev;
  229847. +};
  229848. +
  229849. +static struct imx_priv card_priv;
  229850. +
  229851. +static int imx_cs42888_startup(struct snd_pcm_substream *substream)
  229852. +{
  229853. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  229854. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  229855. + struct imx_priv *priv = &card_priv;
  229856. +
  229857. + if (!cpu_dai->active)
  229858. + priv->hw = 0;
  229859. + return 0;
  229860. +}
  229861. +
  229862. +static void imx_cs42888_shutdown(struct snd_pcm_substream *substream)
  229863. +{
  229864. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  229865. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  229866. + struct imx_priv *priv = &card_priv;
  229867. +
  229868. + if (!cpu_dai->active)
  229869. + priv->hw = 0;
  229870. +}
  229871. +
  229872. +static const struct {
  229873. + int rate;
  229874. + int ratio1;
  229875. + int ratio2;
  229876. +} sr_vals[] = {
  229877. + { 32000, 5, 3 },
  229878. + { 48000, 5, 3 },
  229879. + { 64000, 2, 1 },
  229880. + { 96000, 2, 1 },
  229881. + { 128000, 2, 1 },
  229882. + { 44100, 5, 3 },
  229883. + { 88200, 2, 1 },
  229884. + { 176400, 0, 0 },
  229885. + { 192000, 0, 0 },
  229886. +};
  229887. +
  229888. +static int imx_cs42888_surround_hw_params(struct snd_pcm_substream *substream,
  229889. + struct snd_pcm_hw_params *params)
  229890. +{
  229891. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  229892. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  229893. + struct snd_soc_dai *codec_dai = rtd->codec_dai;
  229894. + struct imx_priv *priv = &card_priv;
  229895. + unsigned int rate = params_rate(params);
  229896. + unsigned int lrclk_ratio = 0, i;
  229897. + u32 dai_format = 0;
  229898. +
  229899. + if (priv->hw)
  229900. + return 0;
  229901. +
  229902. + priv->hw = 1;
  229903. +
  229904. + if (priv->codec_mclk & CODEC_CLK_ESAI_HCKT) {
  229905. + for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
  229906. + if (sr_vals[i].rate == rate) {
  229907. + lrclk_ratio = sr_vals[i].ratio1;
  229908. + break;
  229909. + }
  229910. + }
  229911. + if (i == ARRAY_SIZE(sr_vals)) {
  229912. + dev_err(&priv->pdev->dev, "Unsupported rate %dHz\n", rate);
  229913. + return -EINVAL;
  229914. + }
  229915. +
  229916. + dai_format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
  229917. + SND_SOC_DAIFMT_CBS_CFS;
  229918. +
  229919. + /* set the ESAI system clock as output */
  229920. + snd_soc_dai_set_sysclk(cpu_dai, ESAI_CLK_EXTAL_DIV,
  229921. + priv->mclk_freq, SND_SOC_CLOCK_OUT);
  229922. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PM, 2);
  229923. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PM, 2);
  229924. + /* set codec Master clock */
  229925. + snd_soc_dai_set_sysclk(codec_dai, 0, priv->mclk_freq,\
  229926. + SND_SOC_CLOCK_IN);
  229927. + } else if (priv->codec_mclk & CODEC_CLK_EXTER_OSC) {
  229928. + for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
  229929. + if (sr_vals[i].rate == rate) {
  229930. + lrclk_ratio = sr_vals[i].ratio2;
  229931. + break;
  229932. + }
  229933. + }
  229934. + if (i == ARRAY_SIZE(sr_vals)) {
  229935. + dev_err(&priv->pdev->dev, "Unsupported rate %dHz\n", rate);
  229936. + return -EINVAL;
  229937. + }
  229938. +
  229939. + dai_format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
  229940. + SND_SOC_DAIFMT_CBS_CFS;
  229941. +
  229942. + snd_soc_dai_set_sysclk(cpu_dai, ESAI_CLK_EXTAL,
  229943. + priv->mclk_freq, SND_SOC_CLOCK_OUT);
  229944. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PM, 0);
  229945. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PM, 0);
  229946. + snd_soc_dai_set_sysclk(codec_dai, 0, priv->mclk_freq,\
  229947. + SND_SOC_CLOCK_IN);
  229948. + }
  229949. +
  229950. + /* set cpu DAI configuration */
  229951. + snd_soc_dai_set_fmt(cpu_dai, dai_format);
  229952. + /* set i.MX active slot mask */
  229953. + snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 32);
  229954. + /* set the ratio */
  229955. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PSR, 1);
  229956. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_FP, lrclk_ratio);
  229957. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PSR, 1);
  229958. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_FP, lrclk_ratio);
  229959. +
  229960. + /* set codec DAI configuration */
  229961. + snd_soc_dai_set_fmt(codec_dai, dai_format);
  229962. + return 0;
  229963. +}
  229964. +
  229965. +static struct snd_soc_ops imx_cs42888_surround_ops = {
  229966. + .startup = imx_cs42888_startup,
  229967. + .shutdown = imx_cs42888_shutdown,
  229968. + .hw_params = imx_cs42888_surround_hw_params,
  229969. +};
  229970. +
  229971. +static const struct snd_soc_dapm_widget imx_cs42888_dapm_widgets[] = {
  229972. + SND_SOC_DAPM_LINE("Line Out Jack", NULL),
  229973. + SND_SOC_DAPM_LINE("Line In Jack", NULL),
  229974. +};
  229975. +
  229976. +static const struct snd_soc_dapm_route audio_map[] = {
  229977. + /* Line out jack */
  229978. + {"Line Out Jack", NULL, "AOUT1L"},
  229979. + {"Line Out Jack", NULL, "AOUT1R"},
  229980. + {"Line Out Jack", NULL, "AOUT2L"},
  229981. + {"Line Out Jack", NULL, "AOUT2R"},
  229982. + {"Line Out Jack", NULL, "AOUT3L"},
  229983. + {"Line Out Jack", NULL, "AOUT3R"},
  229984. + {"Line Out Jack", NULL, "AOUT4L"},
  229985. + {"Line Out Jack", NULL, "AOUT4R"},
  229986. + {"AIN1L", NULL, "Line In Jack"},
  229987. + {"AIN1R", NULL, "Line In Jack"},
  229988. + {"AIN2L", NULL, "Line In Jack"},
  229989. + {"AIN2R", NULL, "Line In Jack"},
  229990. + {"esai-Playback", NULL, "asrc-Playback"},
  229991. + {"codec-Playback", NULL, "esai-Playback"},/*Playback is the codec dai*/
  229992. +};
  229993. +
  229994. +static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
  229995. + struct snd_pcm_hw_params *params) {
  229996. +
  229997. + struct imx_priv *priv = &card_priv;
  229998. +
  229999. + hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = priv->fe_output_rate;
  230000. + hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max = priv->fe_output_rate;
  230001. + snd_mask_none(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT));
  230002. + if (priv->fe_output_width == 16)
  230003. + snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
  230004. + SNDRV_PCM_FORMAT_S16_LE);
  230005. + else
  230006. + snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
  230007. + SNDRV_PCM_FORMAT_S24_LE);
  230008. + return 0;
  230009. +}
  230010. +
  230011. +static struct snd_soc_dai_link imx_cs42888_dai[] = {
  230012. + {
  230013. + .name = "HiFi",
  230014. + .stream_name = "HiFi",
  230015. + .codec_dai_name = "CS42888",
  230016. + .ops = &imx_cs42888_surround_ops,
  230017. + },
  230018. + {
  230019. + .name = "HiFi-ASRC-FE",
  230020. + .stream_name = "HiFi-ASRC-FE",
  230021. + .codec_name = "snd-soc-dummy",
  230022. + .codec_dai_name = "snd-soc-dummy-dai",
  230023. + .dynamic = 1,
  230024. + },
  230025. + {
  230026. + .name = "HiFi-ASRC-BE",
  230027. + .stream_name = "HiFi-ASRC-BE",
  230028. + .codec_dai_name = "CS42888",
  230029. + .platform_name = "snd-soc-dummy",
  230030. + .no_pcm = 1,
  230031. + .ops = &imx_cs42888_surround_ops,
  230032. + .be_hw_params_fixup = be_hw_params_fixup,
  230033. + },
  230034. +};
  230035. +
  230036. +static struct snd_soc_card snd_soc_card_imx_cs42888 = {
  230037. + .name = "cs42888-audio",
  230038. + .dai_link = imx_cs42888_dai,
  230039. + .dapm_widgets = imx_cs42888_dapm_widgets,
  230040. + .num_dapm_widgets = ARRAY_SIZE(imx_cs42888_dapm_widgets),
  230041. + .dapm_routes = audio_map,
  230042. + .num_dapm_routes = ARRAY_SIZE(audio_map),
  230043. +};
  230044. +
  230045. +/*
  230046. + * This function will register the snd_soc_pcm_link drivers.
  230047. + */
  230048. +static int imx_cs42888_probe(struct platform_device *pdev)
  230049. +{
  230050. + struct device_node *esai_np, *codec_np;
  230051. + struct device_node *asrc_np;
  230052. + struct platform_device *esai_pdev;
  230053. + struct platform_device *asrc_pdev = NULL;
  230054. + struct i2c_client *codec_dev;
  230055. + struct imx_priv *priv = &card_priv;
  230056. + struct clk *codec_clk = NULL;
  230057. + const char *mclk_name;
  230058. + int ret;
  230059. +
  230060. + priv->pdev = pdev;
  230061. +
  230062. + esai_np = of_parse_phandle(pdev->dev.of_node, "esai-controller", 0);
  230063. + codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
  230064. + if (!esai_np || !codec_np) {
  230065. + dev_err(&pdev->dev, "phandle missing or invalid\n");
  230066. + ret = -EINVAL;
  230067. + goto fail;
  230068. + }
  230069. +
  230070. + asrc_np = of_parse_phandle(pdev->dev.of_node, "asrc-controller", 0);
  230071. + if (asrc_np) {
  230072. + asrc_pdev = of_find_device_by_node(asrc_np);
  230073. + if (asrc_pdev) {
  230074. + struct fsl_asrc_p2p *asrc_p2p;
  230075. + asrc_p2p = platform_get_drvdata(asrc_pdev);
  230076. + asrc_p2p->per_dev = ESAI;
  230077. + priv->fe_output_rate = asrc_p2p->output_rate;
  230078. + priv->fe_output_width = asrc_p2p->output_width;
  230079. + }
  230080. + }
  230081. +
  230082. + esai_pdev = of_find_device_by_node(esai_np);
  230083. + if (!esai_pdev) {
  230084. + dev_err(&pdev->dev, "failed to find ESAI platform device\n");
  230085. + ret = -EINVAL;
  230086. + goto fail;
  230087. + }
  230088. + codec_dev = of_find_i2c_device_by_node(codec_np);
  230089. + if (!codec_dev) {
  230090. + dev_err(&pdev->dev, "failed to find codec platform device\n");
  230091. + ret = -EINVAL;
  230092. + goto fail;
  230093. + }
  230094. +
  230095. + /*if there is no asrc controller, we only enable one device*/
  230096. + if (!asrc_pdev) {
  230097. + imx_cs42888_dai[0].codec_of_node = codec_np;
  230098. + imx_cs42888_dai[0].cpu_dai_name = dev_name(&esai_pdev->dev);
  230099. + imx_cs42888_dai[0].platform_of_node = esai_np;
  230100. + snd_soc_card_imx_cs42888.num_links = 1;
  230101. + } else {
  230102. + imx_cs42888_dai[0].codec_of_node = codec_np;
  230103. + imx_cs42888_dai[0].cpu_dai_name = dev_name(&esai_pdev->dev);
  230104. + imx_cs42888_dai[0].platform_of_node = esai_np;
  230105. + imx_cs42888_dai[1].cpu_dai_name = dev_name(&asrc_pdev->dev);
  230106. + imx_cs42888_dai[1].platform_name = "imx-pcm-asrc";
  230107. + imx_cs42888_dai[2].codec_of_node = codec_np;
  230108. + imx_cs42888_dai[2].cpu_dai_name = dev_name(&esai_pdev->dev);
  230109. + snd_soc_card_imx_cs42888.num_links = 3;
  230110. + }
  230111. +
  230112. + codec_clk = devm_clk_get(&codec_dev->dev, NULL);
  230113. + if (IS_ERR(codec_clk)) {
  230114. + ret = PTR_ERR(codec_clk);
  230115. + dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
  230116. + goto fail;
  230117. + }
  230118. + priv->mclk_freq = clk_get_rate(codec_clk);
  230119. +
  230120. + ret = of_property_read_string(codec_np, "clock-names", &mclk_name);
  230121. + if (ret) {
  230122. + dev_err(&pdev->dev, "%s: failed to get mclk source\n", __func__);
  230123. + goto fail;
  230124. + }
  230125. + if (!strcmp(mclk_name, "codec_osc"))
  230126. + priv->codec_mclk = CODEC_CLK_EXTER_OSC;
  230127. + else if (!strcmp(mclk_name, "esai"))
  230128. + priv->codec_mclk = CODEC_CLK_ESAI_HCKT;
  230129. + else {
  230130. + dev_err(&pdev->dev, "mclk source is not correct %s\n", mclk_name);
  230131. + goto fail;
  230132. + }
  230133. +
  230134. + snd_soc_card_imx_cs42888.dev = &pdev->dev;
  230135. +
  230136. + platform_set_drvdata(pdev, &snd_soc_card_imx_cs42888);
  230137. +
  230138. + ret = snd_soc_register_card(&snd_soc_card_imx_cs42888);
  230139. + if (ret)
  230140. + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
  230141. +fail:
  230142. + if (esai_np)
  230143. + of_node_put(esai_np);
  230144. + if (codec_np)
  230145. + of_node_put(codec_np);
  230146. + return ret;
  230147. +}
  230148. +
  230149. +static int imx_cs42888_remove(struct platform_device *pdev)
  230150. +{
  230151. + snd_soc_unregister_card(&snd_soc_card_imx_cs42888);
  230152. + return 0;
  230153. +}
  230154. +
  230155. +static const struct of_device_id imx_cs42888_dt_ids[] = {
  230156. + { .compatible = "fsl,imx-audio-cs42888", },
  230157. + { /* sentinel */ }
  230158. +};
  230159. +
  230160. +static struct platform_driver imx_cs42888_driver = {
  230161. + .probe = imx_cs42888_probe,
  230162. + .remove = imx_cs42888_remove,
  230163. + .driver = {
  230164. + .name = "imx-cs42888",
  230165. + .owner = THIS_MODULE,
  230166. + .pm = &snd_soc_pm_ops,
  230167. + .of_match_table = imx_cs42888_dt_ids,
  230168. + },
  230169. +};
  230170. +module_platform_driver(imx_cs42888_driver);
  230171. +
  230172. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  230173. +MODULE_DESCRIPTION("ALSA SoC cs42888 Machine Layer Driver");
  230174. +MODULE_ALIAS("platform:imx-cs42888");
  230175. +MODULE_LICENSE("GPL");
  230176. diff -Nur linux-3.14.15/sound/soc/fsl/imx-hdmi.c linux-linaro-stable-mx6/sound/soc/fsl/imx-hdmi.c
  230177. --- linux-3.14.15/sound/soc/fsl/imx-hdmi.c 1970-01-01 01:00:00.000000000 +0100
  230178. +++ linux-linaro-stable-mx6/sound/soc/fsl/imx-hdmi.c 2014-08-20 19:24:09.562914171 +0200
  230179. @@ -0,0 +1,113 @@
  230180. +/*
  230181. + * ASoC HDMI Transmitter driver for IMX development boards
  230182. + *
  230183. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  230184. + *
  230185. + * based on stmp3780_devb_hdmi.c
  230186. + *
  230187. + * Vladimir Barinov <vbarinov@embeddedalley.com>
  230188. + *
  230189. + * Copyright 2008 SigmaTel, Inc
  230190. + * Copyright 2008 Embedded Alley Solutions, Inc
  230191. + *
  230192. + * This file is licensed under the terms of the GNU General Public License
  230193. + * version 2. This program is licensed "as is" without any warranty of any
  230194. + * kind, whether express or implied.
  230195. + */
  230196. +
  230197. +#include <linux/module.h>
  230198. +#include <linux/of_platform.h>
  230199. +#include <linux/mfd/mxc-hdmi-core.h>
  230200. +#include <sound/soc.h>
  230201. +
  230202. +#include "imx-hdmi.h"
  230203. +
  230204. +/* imx digital audio interface glue - connects codec <--> CPU */
  230205. +static struct snd_soc_dai_link imx_hdmi_dai_link = {
  230206. + .name = "i.MX HDMI Audio Tx",
  230207. + .stream_name = "i.MX HDMI Audio Tx",
  230208. + .codec_dai_name = "hdmi-hifi",
  230209. + .codec_name = "hdmi-audio-codec",
  230210. + .platform_name = "imx-hdmi-audio",
  230211. +};
  230212. +
  230213. +static struct snd_soc_card snd_soc_card_imx_hdmi = {
  230214. + .name = "imx-hdmi-soc",
  230215. + .dai_link = &imx_hdmi_dai_link,
  230216. + .num_links = 1,
  230217. +};
  230218. +
  230219. +static int imx_hdmi_audio_probe(struct platform_device *pdev)
  230220. +{
  230221. + struct device_node *hdmi_np, *np = pdev->dev.of_node;
  230222. + struct snd_soc_card *card = &snd_soc_card_imx_hdmi;
  230223. + struct platform_device *hdmi_pdev;
  230224. + int ret = 0;
  230225. +
  230226. + if (!hdmi_get_registered()) {
  230227. + dev_err(&pdev->dev, "initialize HDMI-audio failed. load HDMI-video first!\n");
  230228. + return -ENODEV;
  230229. + }
  230230. +
  230231. + hdmi_np = of_parse_phandle(np, "hdmi-controller", 0);
  230232. + if (!hdmi_np) {
  230233. + dev_err(&pdev->dev, "failed to find hdmi-audio cpudai\n");
  230234. + ret = -EINVAL;
  230235. + goto end;
  230236. + }
  230237. +
  230238. + hdmi_pdev = of_find_device_by_node(hdmi_np);
  230239. + if (!hdmi_pdev) {
  230240. + dev_err(&pdev->dev, "failed to find SSI platform device\n");
  230241. + ret = -EINVAL;
  230242. + goto end;
  230243. + }
  230244. +
  230245. + card->dev = &pdev->dev;
  230246. + card->dai_link->cpu_dai_name = dev_name(&hdmi_pdev->dev);
  230247. +
  230248. + platform_set_drvdata(pdev, card);
  230249. +
  230250. + ret = snd_soc_register_card(card);
  230251. + if (ret)
  230252. + dev_err(&pdev->dev, "failed to register card: %d\n", ret);
  230253. +
  230254. +end:
  230255. + if (hdmi_np)
  230256. + of_node_put(hdmi_np);
  230257. +
  230258. + return ret;
  230259. +}
  230260. +
  230261. +static int imx_hdmi_audio_remove(struct platform_device *pdev)
  230262. +{
  230263. + struct snd_soc_card *card = platform_get_drvdata(pdev);
  230264. +
  230265. + snd_soc_unregister_card(card);
  230266. +
  230267. + return 0;
  230268. +}
  230269. +
  230270. +static const struct of_device_id imx_hdmi_dt_ids[] = {
  230271. + { .compatible = "fsl,imx-audio-hdmi", },
  230272. + { /* sentinel */ }
  230273. +};
  230274. +MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
  230275. +
  230276. +static struct platform_driver imx_hdmi_audio_driver = {
  230277. + .probe = imx_hdmi_audio_probe,
  230278. + .remove = imx_hdmi_audio_remove,
  230279. + .driver = {
  230280. + .of_match_table = imx_hdmi_dt_ids,
  230281. + .name = "imx-audio-hdmi",
  230282. + .owner = THIS_MODULE,
  230283. + .pm = &snd_soc_pm_ops,
  230284. + },
  230285. +};
  230286. +
  230287. +module_platform_driver(imx_hdmi_audio_driver);
  230288. +
  230289. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  230290. +MODULE_DESCRIPTION("IMX HDMI TX ASoC driver");
  230291. +MODULE_LICENSE("GPL");
  230292. +MODULE_ALIAS("platform:imx-audio-hdmi");
  230293. diff -Nur linux-3.14.15/sound/soc/fsl/imx-hdmi-dma.c linux-linaro-stable-mx6/sound/soc/fsl/imx-hdmi-dma.c
  230294. --- linux-3.14.15/sound/soc/fsl/imx-hdmi-dma.c 1970-01-01 01:00:00.000000000 +0100
  230295. +++ linux-linaro-stable-mx6/sound/soc/fsl/imx-hdmi-dma.c 2014-08-20 19:31:58.744923167 +0200
  230296. @@ -0,0 +1,1214 @@
  230297. +/*
  230298. + * imx-hdmi-dma.c -- HDMI DMA driver for ALSA Soc Audio Layer
  230299. + *
  230300. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
  230301. + *
  230302. + * based on imx-pcm-dma-mx2.c
  230303. + * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
  230304. + *
  230305. + * This code is based on code copyrighted by Freescale,
  230306. + * Liam Girdwood, Javier Martin and probably others.
  230307. + *
  230308. + * This program is free software; you can redistribute it and/or modify it
  230309. + * under the terms of the GNU General Public License as published by the
  230310. + * Free Software Foundation; either version 2 of the License, or (at your
  230311. + * option) any later version.
  230312. + */
  230313. +
  230314. +#include <linux/module.h>
  230315. +#include <linux/delay.h>
  230316. +#include <linux/dma-mapping.h>
  230317. +#include <linux/mfd/mxc-hdmi-core.h>
  230318. +#include <linux/platform_data/dma-imx.h>
  230319. +
  230320. +#include <video/mxc_hdmi.h>
  230321. +
  230322. +#include "imx-hdmi.h"
  230323. +
  230324. +#define HDMI_DMA_BURST_UNSPECIFIED_LEGNTH 0
  230325. +#define HDMI_DMA_BURST_INCR4 1
  230326. +#define HDMI_DMA_BURST_INCR8 2
  230327. +#define HDMI_DMA_BURST_INCR16 3
  230328. +
  230329. +#define HDMI_BASE_ADDR 0x00120000
  230330. +
  230331. +struct hdmi_sdma_script {
  230332. + int control_reg_addr;
  230333. + int status_reg_addr;
  230334. + int dma_start_addr;
  230335. + u32 buffer[20];
  230336. +};
  230337. +
  230338. +struct hdmi_dma_priv {
  230339. + struct snd_pcm_substream *substream;
  230340. + struct platform_device *pdev;
  230341. +
  230342. + struct snd_dma_buffer hw_buffer;
  230343. + unsigned long buffer_bytes;
  230344. + unsigned long appl_bytes;
  230345. +
  230346. + int periods;
  230347. + int period_time;
  230348. + int period_bytes;
  230349. + int dma_period_bytes;
  230350. + int buffer_ratio;
  230351. +
  230352. + unsigned long offset;
  230353. +
  230354. + snd_pcm_format_t format;
  230355. + int sample_align;
  230356. + int sample_bits;
  230357. + int channels;
  230358. + int rate;
  230359. +
  230360. + int frame_idx;
  230361. +
  230362. + bool tx_active;
  230363. + spinlock_t irq_lock;
  230364. +
  230365. + /* SDMA part */
  230366. + dma_addr_t phy_hdmi_sdma_t;
  230367. + struct hdmi_sdma_script *hdmi_sdma_t;
  230368. + struct dma_chan *dma_channel;
  230369. + struct imx_dma_data dma_data;
  230370. + struct dma_async_tx_descriptor *desc;
  230371. + struct imx_hdmi_sdma_params sdma_params;
  230372. +};
  230373. +
  230374. +/* bit 0:0:0:b:p(0):c:(u)0:(v)0 */
  230375. +/* max 8 channels supported; channels are interleaved */
  230376. +static u8 g_packet_head_table[48 * 8];
  230377. +
  230378. +/* channel remapping for hdmi_dma_copy_xxxx() */
  230379. +static u8 g_channel_remap_table[24];
  230380. +
  230381. +/* default mapping tables */
  230382. +static const u8 channel_maps_alsa_cea[5][8] = {
  230383. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 0CH: no remapping */
  230384. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 2CH: no remapping */
  230385. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 4CH: no remapping */
  230386. + { 0, 1, 4, 5, 3, 2, 6, 7 }, /* 6CH: ALSA5.1 to CEA */
  230387. + { 0, 1, 6, 7, 3, 2, 4, 5 } /* 8CH: ALSA7.1 to CEA */
  230388. +};
  230389. +
  230390. +static const u8 channel_maps_cea_alsa[5][8] = {
  230391. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 0CH: no remapping */
  230392. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 2CH: no remapping */
  230393. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 4CH: no remapping */
  230394. + { 0, 1, 5, 4, 2, 3, 6, 7 }, /* 6CH: CEA to ALSA5.1 */
  230395. + { 0, 1, 5, 4, 6, 7, 2, 3 } /* 8CH: CEA to ALSA7.1 */
  230396. +};
  230397. +
  230398. +union hdmi_audio_header_t iec_header;
  230399. +EXPORT_SYMBOL(iec_header);
  230400. +
  230401. +/*
  230402. + * Note that the period size for DMA != period size for ALSA because the
  230403. + * driver adds iec frame info to the audio samples (in hdmi_dma_copy).
  230404. + *
  230405. + * Each 4 byte subframe = 1 byte of iec data + 3 byte audio sample.
  230406. + *
  230407. + * A 16 bit audio sample becomes 32 bits including the frame info. Ratio=2
  230408. + * A 24 bit audio sample becomes 32 bits including the frame info. Ratio=3:4
  230409. + * If the 24 bit raw audio is in 32 bit words, the
  230410. + *
  230411. + * Original Packed into subframe Ratio of size Format
  230412. + * sample how many size of DMA buffer
  230413. + * (bits) bits to ALSA buffer
  230414. + * -------- ----------- -------- -------------- ------------------------
  230415. + * 16 16 32 2 SNDRV_PCM_FORMAT_S16_LE
  230416. + * 24 24 32 1.33 SNDRV_PCM_FORMAT_S24_3LE*
  230417. + * 24 32 32 1 SNDRV_PCM_FORMAT_S24_LE
  230418. + *
  230419. + * *so SNDRV_PCM_FORMAT_S24_3LE is not supported.
  230420. + */
  230421. +
  230422. +/*
  230423. + * The minimum dma period is one IEC audio frame (192 * 4 * channels).
  230424. + * The maximum dma period for the HDMI DMA is 8K.
  230425. + *
  230426. + * channels minimum maximum
  230427. + * dma period dma period
  230428. + * -------- ------------------ ----------
  230429. + * 2 192 * 4 * 2 = 1536 * 4 = 6144
  230430. + * 4 192 * 4 * 4 = 3072 * 2 = 6144
  230431. + * 6 192 * 4 * 6 = 4608 * 1 = 4608
  230432. + * 8 192 * 4 * 8 = 6144 * 1 = 6144
  230433. + *
  230434. + * Bottom line:
  230435. + * 1. Must keep the ratio of DMA buffer to ALSA buffer consistent.
  230436. + * 2. frame_idx is saved in the private data, so even if a frame cannot be
  230437. + * transmitted in a period, it can be continued in the next period. This
  230438. + * is necessary for 6 ch.
  230439. + */
  230440. +#define HDMI_DMA_PERIOD_BYTES (12288)
  230441. +#define HDMI_DMA_BUF_SIZE (128 * 1024)
  230442. +#define HDMI_PCM_BUF_SIZE (128 * 1024)
  230443. +
  230444. +#define hdmi_audio_debug(dev, reg) \
  230445. + dev_dbg(dev, #reg ": 0x%02x\n", hdmi_readb(reg))
  230446. +
  230447. +#ifdef DEBUG
  230448. +static void dumpregs(struct device *dev)
  230449. +{
  230450. + hdmi_audio_debug(dev, HDMI_AHB_DMA_CONF0);
  230451. + hdmi_audio_debug(dev, HDMI_AHB_DMA_START);
  230452. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STOP);
  230453. + hdmi_audio_debug(dev, HDMI_AHB_DMA_THRSLD);
  230454. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STRADDR0);
  230455. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STPADDR0);
  230456. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BSTADDR0);
  230457. + hdmi_audio_debug(dev, HDMI_AHB_DMA_MBLENGTH0);
  230458. + hdmi_audio_debug(dev, HDMI_AHB_DMA_MBLENGTH1);
  230459. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STAT);
  230460. + hdmi_audio_debug(dev, HDMI_AHB_DMA_INT);
  230461. + hdmi_audio_debug(dev, HDMI_AHB_DMA_MASK);
  230462. + hdmi_audio_debug(dev, HDMI_AHB_DMA_POL);
  230463. + hdmi_audio_debug(dev, HDMI_AHB_DMA_CONF1);
  230464. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFSTAT);
  230465. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFINT);
  230466. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFMASK);
  230467. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFPOL);
  230468. + hdmi_audio_debug(dev, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  230469. + hdmi_audio_debug(dev, HDMI_IH_AHBDMAAUD_STAT0);
  230470. + hdmi_audio_debug(dev, HDMI_IH_MUTE);
  230471. +}
  230472. +
  230473. +static void dumppriv(struct device *dev, struct hdmi_dma_priv *priv)
  230474. +{
  230475. + dev_dbg(dev, "channels = %d\n", priv->channels);
  230476. + dev_dbg(dev, "periods = %d\n", priv->periods);
  230477. + dev_dbg(dev, "period_bytes = %d\n", priv->period_bytes);
  230478. + dev_dbg(dev, "dma period_bytes = %d\n", priv->dma_period_bytes);
  230479. + dev_dbg(dev, "buffer_ratio = %d\n", priv->buffer_ratio);
  230480. + dev_dbg(dev, "hw dma buffer = 0x%08x\n", (int)priv->hw_buffer.addr);
  230481. + dev_dbg(dev, "dma buf size = %d\n", (int)priv->buffer_bytes);
  230482. + dev_dbg(dev, "sample_rate = %d\n", (int)priv->rate);
  230483. +}
  230484. +#else
  230485. +static void dumpregs(struct device *dev) {}
  230486. +static void dumppriv(struct device *dev, struct hdmi_dma_priv *priv) {}
  230487. +#endif
  230488. +
  230489. +/*
  230490. + * Conditions for DMA to work:
  230491. + * ((final_addr - initial_addr)>>2)+1) < 2k. So max period is 8k.
  230492. + * (inital_addr & 0x3) == 0
  230493. + * (final_addr & 0x3) == 0x3
  230494. + *
  230495. + * The DMA Period should be an integer multiple of the IEC 60958 audio
  230496. + * frame size, which is 768 bytes (192 * 4).
  230497. + */
  230498. +static void hdmi_dma_set_addr(int start_addr, int dma_period_bytes)
  230499. +{
  230500. + int final_addr = start_addr + dma_period_bytes - 1;
  230501. +
  230502. + hdmi_write4(start_addr, HDMI_AHB_DMA_STRADDR0);
  230503. + hdmi_write4(final_addr, HDMI_AHB_DMA_STPADDR0);
  230504. +}
  230505. +
  230506. +static void hdmi_dma_irq_set(bool set)
  230507. +{
  230508. + u8 val = hdmi_readb(HDMI_AHB_DMA_MASK);
  230509. +
  230510. + if (set)
  230511. + val |= HDMI_AHB_DMA_DONE;
  230512. + else
  230513. + val &= (u8)~HDMI_AHB_DMA_DONE;
  230514. +
  230515. + hdmi_writeb(val, HDMI_AHB_DMA_MASK);
  230516. +}
  230517. +
  230518. +static void hdmi_mask(int mask)
  230519. +{
  230520. + u8 regval = hdmi_readb(HDMI_AHB_DMA_MASK);
  230521. +
  230522. + if (mask)
  230523. + regval |= HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY;
  230524. + else
  230525. + regval &= (u8)~(HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY);
  230526. +
  230527. + hdmi_writeb(regval, HDMI_AHB_DMA_MASK);
  230528. +}
  230529. +
  230530. +static inline int odd_ones(unsigned a)
  230531. +{
  230532. + a ^= a >> 16;
  230533. + a ^= a >> 8;
  230534. + a ^= a >> 4;
  230535. + a ^= a >> 2;
  230536. + a ^= a >> 1;
  230537. +
  230538. + return a & 1;
  230539. +}
  230540. +
  230541. +/* Add frame information for one pcm subframe */
  230542. +static u32 hdmi_dma_add_frame_info(struct hdmi_dma_priv *priv,
  230543. + u32 pcm_data, int subframe_idx)
  230544. +{
  230545. + union hdmi_audio_dma_data_t subframe;
  230546. +
  230547. + subframe.U = 0;
  230548. +
  230549. + /* fill c (channel status) */
  230550. + if (priv->frame_idx < 42) {
  230551. + iec_header.B.channel =
  230552. + (iec_header.B.linear_pcm == 0) ? subframe_idx : 0;
  230553. + subframe.B.c = iec_header.U >> priv->frame_idx;
  230554. + }
  230555. +
  230556. + /* fill v (validity) */
  230557. + subframe.B.v = iec_header.B.linear_pcm;
  230558. +
  230559. + /* fill data */
  230560. + if (priv->sample_bits == 16)
  230561. + subframe.B.data = pcm_data << 8;
  230562. + else
  230563. + subframe.B.data = pcm_data;
  230564. +
  230565. + /* fill p (parity) Note: Do not include b ! */
  230566. + subframe.B.p = odd_ones(subframe.U);
  230567. +
  230568. + /* fill b (start-of-block) */
  230569. + if (priv->frame_idx == 0)
  230570. + subframe.B.b = 1;
  230571. +
  230572. + return subframe.U;
  230573. +}
  230574. +
  230575. +static void init_table(int channels)
  230576. +{
  230577. + unsigned char *p = g_packet_head_table;
  230578. + int i, map_sel, ch = 0;
  230579. +
  230580. + for (i = 0; i < 48; i++) {
  230581. + int b = 0;
  230582. + if (i == 0)
  230583. + b = 1;
  230584. +
  230585. + for (ch = 0; ch < channels; ch++) {
  230586. + int c = 0;
  230587. + if (i < 42) {
  230588. + iec_header.B.channel = ch+1;
  230589. + c = (iec_header.U >> i) & 0x1;
  230590. + }
  230591. + /* preset bit p as c */
  230592. + *p++ = (b << 4) | (c << 2) | (c << 3);
  230593. + }
  230594. + }
  230595. +
  230596. + map_sel = channels / 2;
  230597. + for (i = 0; i < 24; i++) {
  230598. + g_channel_remap_table[i] = (i / channels) * channels +
  230599. + channel_maps_cea_alsa[map_sel][i % channels];
  230600. + }
  230601. +}
  230602. +
  230603. +/* Optimization for IEC head */
  230604. +static void hdmi_dma_copy_16_c_lut(u16 *src, u32 *dst, int samples,
  230605. + u8 *lookup_table)
  230606. +{
  230607. + u32 sample, head;
  230608. + int i = 0;
  230609. +
  230610. + while (samples--) {
  230611. + /* get source sample */
  230612. + sample = src[g_channel_remap_table[i]];
  230613. +
  230614. + /* get packet header and p-bit */
  230615. + head = *lookup_table++ ^ (odd_ones(sample) << 3);
  230616. +
  230617. + /* store sample and header */
  230618. + *dst++ = (head << 24) | (sample << 8);
  230619. +
  230620. + if (++i == 24) {
  230621. + src += 24;
  230622. + i = 0;
  230623. + }
  230624. + }
  230625. +}
  230626. +
  230627. +static void hdmi_dma_copy_16_c_fast(u16 *src, u32 *dst, int samples)
  230628. +{
  230629. + u32 sample;
  230630. + int i = 0;
  230631. +
  230632. + while (samples--) {
  230633. + /* get source sample */
  230634. + sample = src[g_channel_remap_table[i]];
  230635. +
  230636. + /* store sample and p-bit */
  230637. + *dst++ = (odd_ones(sample) << (3+24)) | (sample << 8);
  230638. +
  230639. + if (++i == 24) {
  230640. + src += 24;
  230641. + i = 0;
  230642. + }
  230643. + }
  230644. +}
  230645. +
  230646. +static void hdmi_dma_copy_24_c_lut(u32 *src, u32 *dst, int samples,
  230647. + u8 *lookup_table)
  230648. +{
  230649. + u32 sample, head;
  230650. + int i = 0;
  230651. +
  230652. + while (samples--) {
  230653. + /* get source sample */
  230654. + sample = src[g_channel_remap_table[i]] & 0x00ffffff;
  230655. +
  230656. + /* get packet header and p-bit */
  230657. + head = *lookup_table++ ^ (odd_ones(sample) << 3);
  230658. +
  230659. + /* store sample and header */
  230660. + *dst++ = (head << 24) | sample;
  230661. +
  230662. + if (++i == 24) {
  230663. + src += 24;
  230664. + i = 0;
  230665. + }
  230666. + }
  230667. +}
  230668. +
  230669. +static void hdmi_dma_copy_24_c_fast(u32 *src, u32 *dst, int samples)
  230670. +{
  230671. + u32 sample;
  230672. + int i = 0;
  230673. +
  230674. + while (samples--) {
  230675. + /* get source sample */
  230676. + sample = src[g_channel_remap_table[i]] & 0x00ffffff;
  230677. +
  230678. + /* store sample and p-bit */
  230679. + *dst++ = (odd_ones(sample) << (3+24)) | sample;
  230680. +
  230681. + if (++i == 24) {
  230682. + src += 24;
  230683. + i = 0;
  230684. + }
  230685. + }
  230686. +}
  230687. +
  230688. +static void hdmi_mmap_copy(u8 *src, int samplesize, u32 *dst, int framecnt, int channelcnt)
  230689. +{
  230690. + /* split input frames into 192-frame each */
  230691. + int count_in_192 = (framecnt + 191) / 192;
  230692. + int i;
  230693. +
  230694. + typedef void (*fn_copy_lut)(u8 *src, u32 *dst, int samples, u8 *lookup_table);
  230695. + typedef void (*fn_copy_fast)(u8 *src, u32 *dst, int samples);
  230696. + fn_copy_lut copy_lut;
  230697. + fn_copy_fast copy_fast;
  230698. +
  230699. + if (samplesize == 4) {
  230700. + copy_lut = (fn_copy_lut)hdmi_dma_copy_24_c_lut;
  230701. + copy_fast = (fn_copy_fast)hdmi_dma_copy_24_c_fast;
  230702. + } else {
  230703. + copy_lut = (fn_copy_lut)hdmi_dma_copy_16_c_lut;
  230704. + copy_fast = (fn_copy_fast)hdmi_dma_copy_16_c_fast;
  230705. + }
  230706. +
  230707. + for (i = 0; i < count_in_192; i++) {
  230708. + int count, samples;
  230709. +
  230710. + /* handles frame index [0, 48) */
  230711. + count = (framecnt < 48) ? framecnt : 48;
  230712. + samples = count * channelcnt;
  230713. + copy_lut(src, dst, samples, g_packet_head_table);
  230714. + framecnt -= count;
  230715. + if (framecnt == 0)
  230716. + break;
  230717. +
  230718. + src += samples * samplesize;
  230719. + dst += samples;
  230720. +
  230721. + /* handles frame index [48, 192) */
  230722. + count = (framecnt < 192 - 48) ? framecnt : 192 - 48;
  230723. + samples = count * channelcnt;
  230724. + copy_fast(src, dst, samples);
  230725. + framecnt -= count;
  230726. + src += samples * samplesize;
  230727. + dst += samples;
  230728. + }
  230729. +}
  230730. +
  230731. +static void hdmi_dma_mmap_copy(struct snd_pcm_substream *substream,
  230732. + int offset, int count)
  230733. +{
  230734. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  230735. + struct snd_pcm_runtime *runtime = substream->runtime;
  230736. + struct hdmi_dma_priv *priv = runtime->private_data;
  230737. + struct device *dev = rtd->platform->dev;
  230738. + u32 framecount, *dst;
  230739. +
  230740. + framecount = count / (priv->sample_align * priv->channels);
  230741. +
  230742. + /* hw_buffer is the destination for pcm data plus frame info. */
  230743. + dst = (u32 *)(priv->hw_buffer.area + (offset * priv->buffer_ratio));
  230744. +
  230745. + switch (priv->format) {
  230746. + case SNDRV_PCM_FORMAT_S16_LE:
  230747. + case SNDRV_PCM_FORMAT_S24_LE:
  230748. + /* dma_buffer is the mmapped buffer we are copying pcm from. */
  230749. + hdmi_mmap_copy(runtime->dma_area + offset,
  230750. + priv->sample_align, dst, framecount, priv->channels);
  230751. + break;
  230752. + default:
  230753. + dev_err(dev, "unsupported sample format %s\n",
  230754. + snd_pcm_format_name(priv->format));
  230755. + return;
  230756. + }
  230757. +}
  230758. +
  230759. +static void hdmi_dma_data_copy(struct snd_pcm_substream *substream,
  230760. + struct hdmi_dma_priv *priv, char type)
  230761. +{
  230762. + struct snd_pcm_runtime *runtime = substream->runtime;
  230763. + unsigned long offset, count, appl_bytes, space_to_end;
  230764. +
  230765. + if (runtime->access != SNDRV_PCM_ACCESS_MMAP_INTERLEAVED)
  230766. + return;
  230767. +
  230768. + appl_bytes = frames_to_bytes(runtime, runtime->status->hw_ptr);
  230769. +
  230770. + switch (type) {
  230771. + case 'p':
  230772. + offset = (appl_bytes + 2 * priv->period_bytes) % priv->buffer_bytes;
  230773. + count = priv->period_bytes;
  230774. + space_to_end = priv->period_bytes;
  230775. + break;
  230776. + case 'b':
  230777. + offset = appl_bytes % priv->buffer_bytes;
  230778. + count = priv->buffer_bytes;
  230779. + space_to_end = priv->buffer_bytes - offset;
  230780. + break;
  230781. + default:
  230782. + return;
  230783. + }
  230784. +
  230785. + if (count <= space_to_end) {
  230786. + hdmi_dma_mmap_copy(substream, offset, count);
  230787. + } else {
  230788. + hdmi_dma_mmap_copy(substream, offset, space_to_end);
  230789. + hdmi_dma_mmap_copy(substream, 0, count - space_to_end);
  230790. + }
  230791. +}
  230792. +
  230793. +static void hdmi_sdma_callback(void *data)
  230794. +{
  230795. + struct hdmi_dma_priv *priv = (struct hdmi_dma_priv *)data;
  230796. + struct snd_pcm_substream *substream = priv->substream;
  230797. + struct snd_pcm_runtime *runtime = substream->runtime;
  230798. + unsigned long flags;
  230799. +
  230800. + spin_lock_irqsave(&priv->irq_lock, flags);
  230801. +
  230802. + if (runtime && runtime->dma_area && priv->tx_active) {
  230803. + priv->offset += priv->period_bytes;
  230804. + priv->offset %= priv->period_bytes * priv->periods;
  230805. +
  230806. + /* Copy data by period_bytes */
  230807. + hdmi_dma_data_copy(substream, priv, 'p');
  230808. +
  230809. + snd_pcm_period_elapsed(substream);
  230810. + }
  230811. +
  230812. + spin_unlock_irqrestore(&priv->irq_lock, flags);
  230813. +
  230814. + return;
  230815. +}
  230816. +
  230817. +static int hdmi_dma_set_thrsld_incrtype(struct device *dev, int channels)
  230818. +{
  230819. + u8 mask = HDMI_AHB_DMA_CONF0_BURST_MODE | HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK;
  230820. + u8 val = hdmi_readb(HDMI_AHB_DMA_CONF0) & ~mask;
  230821. + int incr_type, threshold;
  230822. +
  230823. + switch (hdmi_readb(HDMI_REVISION_ID)) {
  230824. + case 0x0a:
  230825. + incr_type = HDMI_DMA_BURST_INCR4;
  230826. + if (channels == 2)
  230827. + threshold = 126;
  230828. + else
  230829. + threshold = 124;
  230830. + break;
  230831. + case 0x1a:
  230832. + incr_type = HDMI_DMA_BURST_INCR8;
  230833. + threshold = 128;
  230834. + break;
  230835. + default:
  230836. + dev_err(dev, "unknown hdmi controller!\n");
  230837. + return -ENODEV;
  230838. + }
  230839. +
  230840. + hdmi_writeb(threshold, HDMI_AHB_DMA_THRSLD);
  230841. +
  230842. + switch (incr_type) {
  230843. + case HDMI_DMA_BURST_UNSPECIFIED_LEGNTH:
  230844. + break;
  230845. + case HDMI_DMA_BURST_INCR4:
  230846. + val |= HDMI_AHB_DMA_CONF0_BURST_MODE;
  230847. + break;
  230848. + case HDMI_DMA_BURST_INCR8:
  230849. + val |= HDMI_AHB_DMA_CONF0_BURST_MODE |
  230850. + HDMI_AHB_DMA_CONF0_INCR8;
  230851. + break;
  230852. + case HDMI_DMA_BURST_INCR16:
  230853. + val |= HDMI_AHB_DMA_CONF0_BURST_MODE |
  230854. + HDMI_AHB_DMA_CONF0_INCR16;
  230855. + break;
  230856. + default:
  230857. + dev_err(dev, "invalid increment type: %d!", incr_type);
  230858. + return -EINVAL;
  230859. + }
  230860. +
  230861. + hdmi_writeb(val, HDMI_AHB_DMA_CONF0);
  230862. +
  230863. + hdmi_audio_debug(dev, HDMI_AHB_DMA_THRSLD);
  230864. +
  230865. + return 0;
  230866. +}
  230867. +
  230868. +static int hdmi_dma_configure_dma(struct device *dev, int channels)
  230869. +{
  230870. + int ret;
  230871. + static u8 chan_enable[] = { 0x00, 0x03, 0x33, 0x3f, 0xff };
  230872. +
  230873. + if (channels <= 0 || channels > 8 || channels % 2 != 0) {
  230874. + dev_err(dev, "unsupported channel number: %d\n", channels);
  230875. + return -EINVAL;
  230876. + }
  230877. +
  230878. + hdmi_audio_writeb(AHB_DMA_CONF0, EN_HLOCK, 0x1);
  230879. +
  230880. + ret = hdmi_dma_set_thrsld_incrtype(dev, channels);
  230881. + if (ret)
  230882. + return ret;
  230883. +
  230884. + hdmi_writeb(chan_enable[channels / 2], HDMI_AHB_DMA_CONF1);
  230885. +
  230886. + return 0;
  230887. +}
  230888. +
  230889. +static void hdmi_dma_init_iec_header(void)
  230890. +{
  230891. + iec_header.U = 0;
  230892. +
  230893. + iec_header.B.consumer = 0; /* Consumer use */
  230894. + iec_header.B.linear_pcm = 0; /* linear pcm audio */
  230895. + iec_header.B.copyright = 1; /* no copyright */
  230896. + iec_header.B.pre_emphasis = 0; /* 2 channels without pre-emphasis */
  230897. + iec_header.B.mode = 0; /* Mode 0 */
  230898. +
  230899. + iec_header.B.category_code = 0;
  230900. +
  230901. + iec_header.B.source = 2; /* stereo */
  230902. + iec_header.B.channel = 0;
  230903. +
  230904. + iec_header.B.sample_freq = 0x02; /* 48 KHz */
  230905. + iec_header.B.clock_acc = 0; /* Level II */
  230906. +
  230907. + iec_header.B.word_length = 0x02; /* 16 bits */
  230908. + iec_header.B.org_sample_freq = 0x0D; /* 48 KHz */
  230909. +
  230910. + iec_header.B.cgms_a = 0; /* Copying is permitted without restriction */
  230911. +}
  230912. +
  230913. +static int hdmi_dma_update_iec_header(struct snd_pcm_substream *substream)
  230914. +{
  230915. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  230916. + struct snd_pcm_runtime *runtime = substream->runtime;
  230917. + struct hdmi_dma_priv *priv = runtime->private_data;
  230918. + struct device *dev = rtd->platform->dev;
  230919. +
  230920. + iec_header.B.source = priv->channels;
  230921. +
  230922. + switch (priv->rate) {
  230923. + case 32000:
  230924. + iec_header.B.sample_freq = 0x03;
  230925. + iec_header.B.org_sample_freq = 0x0C;
  230926. + break;
  230927. + case 44100:
  230928. + iec_header.B.sample_freq = 0x00;
  230929. + iec_header.B.org_sample_freq = 0x0F;
  230930. + break;
  230931. + case 48000:
  230932. + iec_header.B.sample_freq = 0x02;
  230933. + iec_header.B.org_sample_freq = 0x0D;
  230934. + break;
  230935. + case 88200:
  230936. + iec_header.B.sample_freq = 0x08;
  230937. + iec_header.B.org_sample_freq = 0x07;
  230938. + break;
  230939. + case 96000:
  230940. + iec_header.B.sample_freq = 0x0A;
  230941. + iec_header.B.org_sample_freq = 0x05;
  230942. + break;
  230943. + case 176400:
  230944. + iec_header.B.sample_freq = 0x0C;
  230945. + iec_header.B.org_sample_freq = 0x03;
  230946. + break;
  230947. + case 192000:
  230948. + iec_header.B.sample_freq = 0x0E;
  230949. + iec_header.B.org_sample_freq = 0x01;
  230950. + break;
  230951. + default:
  230952. + dev_err(dev, "unsupported sample rate\n");
  230953. + return -EFAULT;
  230954. + }
  230955. +
  230956. + switch (priv->format) {
  230957. + case SNDRV_PCM_FORMAT_S16_LE:
  230958. + iec_header.B.word_length = 0x02;
  230959. + break;
  230960. + case SNDRV_PCM_FORMAT_S24_LE:
  230961. + iec_header.B.word_length = 0x0b;
  230962. + break;
  230963. + default:
  230964. + return -EFAULT;
  230965. + }
  230966. +
  230967. + return 0;
  230968. +}
  230969. +
  230970. +/*
  230971. + * The HDMI block transmits the audio data without adding any of the audio
  230972. + * frame bits. So we have to copy the raw dma data from the ALSA buffer
  230973. + * to the DMA buffer, adding the frame information.
  230974. + */
  230975. +static int hdmi_dma_copy(struct snd_pcm_substream *substream, int channel,
  230976. + snd_pcm_uframes_t pos, void __user *buf,
  230977. + snd_pcm_uframes_t frames)
  230978. +{
  230979. + struct snd_pcm_runtime *runtime = substream->runtime;
  230980. + struct hdmi_dma_priv *priv = runtime->private_data;
  230981. + unsigned int count = frames_to_bytes(runtime, frames);
  230982. + unsigned int pos_bytes = frames_to_bytes(runtime, pos);
  230983. + int channel_no, pcm_idx, subframe_no, bits_left, sample_bits, map_sel;
  230984. + u32 pcm_data[8], pcm_temp, *hw_buf, sample_block;
  230985. +
  230986. + /* Adding frame info to pcm data from userspace and copy to hw_buffer */
  230987. + hw_buf = (u32 *)(priv->hw_buffer.area + (pos_bytes * priv->buffer_ratio));
  230988. +
  230989. + sample_bits = priv->sample_align * 8;
  230990. + sample_block = priv->sample_align * priv->channels;
  230991. + map_sel = (iec_header.B.linear_pcm == 0) ? (priv->channels / 2) : 0;
  230992. +
  230993. + while (count > 0) {
  230994. + if (copy_from_user(pcm_data, buf, sample_block))
  230995. + return -EFAULT;
  230996. +
  230997. + buf += sample_block;
  230998. + count -= sample_block;
  230999. +
  231000. + channel_no = pcm_idx = 0;
  231001. + do {
  231002. + pcm_temp = pcm_data[pcm_idx++];
  231003. + bits_left = 32;
  231004. + for (;;) {
  231005. + /* re-map channels */
  231006. + subframe_no = channel_maps_alsa_cea[map_sel][channel_no];
  231007. +
  231008. + /* Save the header info to the audio dma buffer */
  231009. + hw_buf[subframe_no] = hdmi_dma_add_frame_info(
  231010. + priv, pcm_temp, subframe_no + 1);
  231011. + channel_no++;
  231012. +
  231013. + if (bits_left <= sample_bits)
  231014. + break;
  231015. +
  231016. + bits_left -= sample_bits;
  231017. + pcm_temp >>= sample_bits;
  231018. + }
  231019. + } while (channel_no < priv->channels);
  231020. +
  231021. + hw_buf += priv->channels;
  231022. +
  231023. + priv->frame_idx++;
  231024. + if (priv->frame_idx == 192)
  231025. + priv->frame_idx = 0;
  231026. + }
  231027. +
  231028. + return 0;
  231029. +}
  231030. +
  231031. +static int hdmi_sdma_initbuf(struct device *dev, struct hdmi_dma_priv *priv)
  231032. +{
  231033. + struct hdmi_sdma_script *hdmi_sdma_t = priv->hdmi_sdma_t;
  231034. + u32 *head, *tail, i;
  231035. +
  231036. + if (!hdmi_sdma_t) {
  231037. + dev_err(dev, "hdmi private addr invalid!!!\n");
  231038. + return -EINVAL;
  231039. + }
  231040. +
  231041. + hdmi_sdma_t->control_reg_addr = HDMI_BASE_ADDR + HDMI_AHB_DMA_START;
  231042. + hdmi_sdma_t->status_reg_addr = HDMI_BASE_ADDR + HDMI_IH_AHBDMAAUD_STAT0;
  231043. + hdmi_sdma_t->dma_start_addr = HDMI_BASE_ADDR + HDMI_AHB_DMA_STRADDR0;
  231044. +
  231045. + head = &hdmi_sdma_t->buffer[0];
  231046. + tail = &hdmi_sdma_t->buffer[1];
  231047. +
  231048. + for (i = 0; i < priv->sdma_params.buffer_num; i++) {
  231049. + *head = priv->hw_buffer.addr + i * priv->period_bytes * priv->buffer_ratio;
  231050. + *tail = *head + priv->dma_period_bytes - 1;
  231051. + head += 2;
  231052. + tail += 2;
  231053. + }
  231054. +
  231055. + return 0;
  231056. +}
  231057. +
  231058. +static int hdmi_sdma_config(struct snd_pcm_substream *substream,
  231059. + struct hdmi_dma_priv *priv)
  231060. +{
  231061. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231062. + struct device *dai_dev = &priv->pdev->dev;
  231063. + struct device *dev = rtd->platform->dev;
  231064. + struct dma_slave_config slave_config;
  231065. + int ret;
  231066. +
  231067. + priv->dma_channel = dma_request_slave_channel(dai_dev, "tx");
  231068. + if (priv->dma_channel == NULL) {
  231069. + dev_err(dev, "failed to alloc dma channel\n");
  231070. + return -EBUSY;
  231071. + }
  231072. +
  231073. + priv->dma_data.data_addr1 = &priv->sdma_params.buffer_num;
  231074. + priv->dma_data.data_addr2 = &priv->sdma_params.phyaddr;
  231075. + priv->dma_channel->private = &priv->dma_data;
  231076. +
  231077. + slave_config.direction = DMA_TRANS_NONE;
  231078. + slave_config.dma_request0 = 0;
  231079. + slave_config.dma_request1 = 0;
  231080. +
  231081. + ret = dmaengine_slave_config(priv->dma_channel, &slave_config);
  231082. + if (ret) {
  231083. + dev_err(dev, "failed to config slave dma\n");
  231084. + return -EINVAL;
  231085. + }
  231086. +
  231087. + return 0;
  231088. +}
  231089. +
  231090. +static int hdmi_dma_hw_free(struct snd_pcm_substream *substream)
  231091. +{
  231092. + struct snd_pcm_runtime *runtime = substream->runtime;
  231093. + struct hdmi_dma_priv *priv = runtime->private_data;
  231094. +
  231095. + if (priv->dma_channel) {
  231096. + dma_release_channel(priv->dma_channel);
  231097. + priv->dma_channel = NULL;
  231098. + }
  231099. +
  231100. + return 0;
  231101. +}
  231102. +
  231103. +static int hdmi_dma_hw_params(struct snd_pcm_substream *substream,
  231104. + struct snd_pcm_hw_params *params)
  231105. +{
  231106. + struct snd_pcm_runtime *runtime = substream->runtime;
  231107. + struct hdmi_dma_priv *priv = runtime->private_data;
  231108. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231109. + struct device *dev = rtd->platform->dev;
  231110. + int ret;
  231111. +
  231112. + priv->buffer_bytes = params_buffer_bytes(params);
  231113. + priv->periods = params_periods(params);
  231114. + priv->period_bytes = params_period_bytes(params);
  231115. + priv->channels = params_channels(params);
  231116. + priv->format = params_format(params);
  231117. + priv->rate = params_rate(params);
  231118. +
  231119. + priv->offset = 0;
  231120. + priv->period_time = HZ / (priv->rate / params_period_size(params));
  231121. +
  231122. + switch (priv->format) {
  231123. + case SNDRV_PCM_FORMAT_S16_LE:
  231124. + priv->buffer_ratio = 2;
  231125. + priv->sample_align = 2;
  231126. + priv->sample_bits = 16;
  231127. + break;
  231128. + case SNDRV_PCM_FORMAT_S24_LE:
  231129. + /* 24 bit audio in 32 bit word */
  231130. + priv->buffer_ratio = 1;
  231131. + priv->sample_align = 4;
  231132. + priv->sample_bits = 24;
  231133. + break;
  231134. + default:
  231135. + dev_err(dev, "unsupported sample format: %d\n", priv->format);
  231136. + return -EINVAL;
  231137. + }
  231138. +
  231139. + priv->dma_period_bytes = priv->period_bytes * priv->buffer_ratio;
  231140. + priv->sdma_params.buffer_num = priv->periods;
  231141. + priv->sdma_params.phyaddr = priv->phy_hdmi_sdma_t;
  231142. +
  231143. + ret = hdmi_sdma_initbuf(dev, priv);
  231144. + if (ret)
  231145. + return ret;
  231146. +
  231147. + ret = hdmi_sdma_config(substream, priv);
  231148. + if (ret)
  231149. + return ret;
  231150. +
  231151. + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
  231152. +
  231153. + ret = hdmi_dma_configure_dma(dev, priv->channels);
  231154. + if (ret)
  231155. + return ret;
  231156. +
  231157. + hdmi_dma_set_addr(priv->hw_buffer.addr, priv->dma_period_bytes);
  231158. +
  231159. + dumppriv(dev, priv);
  231160. +
  231161. + hdmi_dma_update_iec_header(substream);
  231162. +
  231163. + /* Init par for mmap optimizate */
  231164. + init_table(priv->channels);
  231165. +
  231166. + priv->appl_bytes = 0;
  231167. +
  231168. + return 0;
  231169. +}
  231170. +
  231171. +static void hdmi_dma_trigger_init(struct snd_pcm_substream *substream,
  231172. + struct hdmi_dma_priv *priv)
  231173. +{
  231174. + unsigned long status;
  231175. + bool hbr;
  231176. +
  231177. + /*
  231178. + * Set HBR mode (>192kHz IEC-61937 HD audio bitstreaming).
  231179. + * This is done this late because userspace may alter the AESx
  231180. + * parameters until the stream is finally prepared.
  231181. + */
  231182. + hbr = (iec_header.B.linear_pcm != 0 && priv->channels == 8);
  231183. + hdmi_audio_writeb(AHB_DMA_CONF0, HBR, !!hbr);
  231184. +
  231185. + priv->offset = 0;
  231186. + priv->frame_idx = 0;
  231187. +
  231188. + /* Copy data by buffer_bytes */
  231189. + hdmi_dma_data_copy(substream, priv, 'b');
  231190. +
  231191. + hdmi_audio_writeb(AHB_DMA_CONF0, SW_FIFO_RST, 0x1);
  231192. +
  231193. + /* Delay after reset */
  231194. + udelay(1);
  231195. +
  231196. + status = hdmi_readb(HDMI_IH_AHBDMAAUD_STAT0);
  231197. + hdmi_writeb(status, HDMI_IH_AHBDMAAUD_STAT0);
  231198. +}
  231199. +
  231200. +static int hdmi_dma_prepare_and_submit(struct snd_pcm_substream *substream,
  231201. + struct hdmi_dma_priv *priv)
  231202. +{
  231203. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231204. + struct device *dev = rtd->platform->dev;
  231205. +
  231206. + priv->desc = dmaengine_prep_dma_cyclic(priv->dma_channel, 0, 0, 0,
  231207. + DMA_TRANS_NONE, 0);
  231208. + if (!priv->desc) {
  231209. + dev_err(dev, "failed to prepare slave dma\n");
  231210. + return -EINVAL;
  231211. + }
  231212. +
  231213. + priv->desc->callback = hdmi_sdma_callback;
  231214. + priv->desc->callback_param = (void *)priv;
  231215. + dmaengine_submit(priv->desc);
  231216. +
  231217. + return 0;
  231218. +}
  231219. +
  231220. +static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd)
  231221. +{
  231222. + struct snd_pcm_runtime *runtime = substream->runtime;
  231223. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231224. + struct hdmi_dma_priv *priv = runtime->private_data;
  231225. + struct device *dev = rtd->platform->dev;
  231226. + int ret;
  231227. +
  231228. + switch (cmd) {
  231229. + case SNDRV_PCM_TRIGGER_START:
  231230. + case SNDRV_PCM_TRIGGER_RESUME:
  231231. + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  231232. + if (!check_hdmi_state())
  231233. + return 0;
  231234. + hdmi_dma_trigger_init(substream, priv);
  231235. +
  231236. + dumpregs(dev);
  231237. +
  231238. + priv->tx_active = true;
  231239. + hdmi_audio_writeb(AHB_DMA_START, START, 0x1);
  231240. + hdmi_dma_irq_set(false);
  231241. + hdmi_set_dma_mode(1);
  231242. + ret = hdmi_dma_prepare_and_submit(substream, priv);
  231243. + if (ret)
  231244. + return ret;
  231245. + dma_async_issue_pending(priv->desc->chan);
  231246. + break;
  231247. + case SNDRV_PCM_TRIGGER_STOP:
  231248. + case SNDRV_PCM_TRIGGER_SUSPEND:
  231249. + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  231250. + dmaengine_terminate_all(priv->dma_channel);
  231251. + hdmi_set_dma_mode(0);
  231252. + hdmi_dma_irq_set(true);
  231253. + hdmi_audio_writeb(AHB_DMA_STOP, STOP, 0x1);
  231254. + priv->tx_active = false;
  231255. + break;
  231256. + default:
  231257. + return -EINVAL;
  231258. + }
  231259. +
  231260. + return 0;
  231261. +}
  231262. +
  231263. +static snd_pcm_uframes_t hdmi_dma_pointer(struct snd_pcm_substream *substream)
  231264. +{
  231265. + struct snd_pcm_runtime *runtime = substream->runtime;
  231266. + struct hdmi_dma_priv *priv = runtime->private_data;
  231267. +
  231268. + return bytes_to_frames(runtime, priv->offset);
  231269. +}
  231270. +
  231271. +static struct snd_pcm_hardware snd_imx_hardware = {
  231272. + .info = SNDRV_PCM_INFO_INTERLEAVED |
  231273. + SNDRV_PCM_INFO_BLOCK_TRANSFER |
  231274. + SNDRV_PCM_INFO_MMAP |
  231275. + SNDRV_PCM_INFO_MMAP_VALID |
  231276. + SNDRV_PCM_INFO_PAUSE |
  231277. + SNDRV_PCM_INFO_RESUME,
  231278. + .formats = MXC_HDMI_FORMATS_PLAYBACK,
  231279. + .rate_min = 32000,
  231280. + .channels_min = 2,
  231281. + .channels_max = 8,
  231282. + .buffer_bytes_max = HDMI_PCM_BUF_SIZE,
  231283. + .period_bytes_min = HDMI_DMA_PERIOD_BYTES / 2,
  231284. + .period_bytes_max = HDMI_DMA_PERIOD_BYTES / 2,
  231285. + .periods_min = 8,
  231286. + .periods_max = 8,
  231287. + .fifo_size = 0,
  231288. +};
  231289. +
  231290. +static void hdmi_dma_irq_enable(struct hdmi_dma_priv *priv)
  231291. +{
  231292. + unsigned long flags;
  231293. +
  231294. + hdmi_writeb(0xff, HDMI_AHB_DMA_POL);
  231295. + hdmi_writeb(0xff, HDMI_AHB_DMA_BUFFPOL);
  231296. +
  231297. + spin_lock_irqsave(&priv->irq_lock, flags);
  231298. +
  231299. + hdmi_writeb(0xff, HDMI_IH_AHBDMAAUD_STAT0);
  231300. + hdmi_writeb(0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  231301. + hdmi_dma_irq_set(false);
  231302. + hdmi_mask(0);
  231303. +
  231304. + spin_unlock_irqrestore(&priv->irq_lock, flags);
  231305. +}
  231306. +
  231307. +static void hdmi_dma_irq_disable(struct hdmi_dma_priv *priv)
  231308. +{
  231309. + unsigned long flags;
  231310. +
  231311. + spin_lock_irqsave(&priv->irq_lock, flags);
  231312. +
  231313. + hdmi_dma_irq_set(true);
  231314. + hdmi_writeb(0x0, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  231315. + hdmi_writeb(0xff, HDMI_IH_AHBDMAAUD_STAT0);
  231316. + hdmi_mask(1);
  231317. +
  231318. + spin_unlock_irqrestore(&priv->irq_lock, flags);
  231319. +}
  231320. +
  231321. +static int hdmi_dma_open(struct snd_pcm_substream *substream)
  231322. +{
  231323. + struct snd_pcm_runtime *runtime = substream->runtime;
  231324. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231325. + struct device *dev = rtd->platform->dev;
  231326. + struct hdmi_dma_priv *priv = dev_get_drvdata(dev);
  231327. + int ret;
  231328. +
  231329. + runtime->private_data = priv;
  231330. +
  231331. + ret = mxc_hdmi_register_audio(substream);
  231332. + if (ret < 0) {
  231333. + dev_err(dev, "HDMI Video is not ready!\n");
  231334. + return ret;
  231335. + }
  231336. +
  231337. + hdmi_audio_writeb(AHB_DMA_CONF0, SW_FIFO_RST, 0x1);
  231338. +
  231339. + ret = snd_pcm_hw_constraint_integer(substream->runtime,
  231340. + SNDRV_PCM_HW_PARAM_PERIODS);
  231341. + if (ret < 0)
  231342. + return ret;
  231343. +
  231344. + snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
  231345. +
  231346. + hdmi_dma_irq_enable(priv);
  231347. +
  231348. + return 0;
  231349. +}
  231350. +
  231351. +static int hdmi_dma_close(struct snd_pcm_substream *substream)
  231352. +{
  231353. + struct snd_pcm_runtime *runtime = substream->runtime;
  231354. + struct hdmi_dma_priv *priv = runtime->private_data;
  231355. +
  231356. + hdmi_dma_irq_disable(priv);
  231357. + mxc_hdmi_unregister_audio(substream);
  231358. +
  231359. + return 0;
  231360. +}
  231361. +
  231362. +static struct snd_pcm_ops imx_hdmi_dma_pcm_ops = {
  231363. + .open = hdmi_dma_open,
  231364. + .close = hdmi_dma_close,
  231365. + .ioctl = snd_pcm_lib_ioctl,
  231366. + .hw_params = hdmi_dma_hw_params,
  231367. + .hw_free = hdmi_dma_hw_free,
  231368. + .trigger = hdmi_dma_trigger,
  231369. + .pointer = hdmi_dma_pointer,
  231370. + .copy = hdmi_dma_copy,
  231371. +};
  231372. +
  231373. +static int imx_hdmi_dma_pcm_new(struct snd_soc_pcm_runtime *rtd)
  231374. +{
  231375. + struct hdmi_dma_priv *priv = dev_get_drvdata(rtd->platform->dev);
  231376. + struct snd_card *card = rtd->card->snd_card;
  231377. + struct snd_pcm_substream *substream;
  231378. + struct snd_pcm *pcm = rtd->pcm;
  231379. + u64 dma_mask = DMA_BIT_MASK(32);
  231380. + int ret = 0;
  231381. +
  231382. + if (!card->dev->dma_mask)
  231383. + card->dev->dma_mask = &dma_mask;
  231384. + if (!card->dev->coherent_dma_mask)
  231385. + card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  231386. +
  231387. + substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
  231388. +
  231389. + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
  231390. + HDMI_PCM_BUF_SIZE, &substream->dma_buffer);
  231391. + if (ret) {
  231392. + dev_err(card->dev, "failed to alloc playback dma buffer\n");
  231393. + return ret;
  231394. + }
  231395. +
  231396. + priv->substream = substream;
  231397. +
  231398. + /* Alloc the hw_buffer */
  231399. + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
  231400. + HDMI_DMA_BUF_SIZE, &priv->hw_buffer);
  231401. + if (ret) {
  231402. + dev_err(card->dev, "failed to alloc hw dma buffer\n");
  231403. + return ret;
  231404. + }
  231405. +
  231406. + return ret;
  231407. +}
  231408. +
  231409. +static void imx_hdmi_dma_pcm_free(struct snd_pcm *pcm)
  231410. +{
  231411. + int stream = SNDRV_PCM_STREAM_PLAYBACK;
  231412. + struct snd_pcm_substream *substream = pcm->streams[stream].substream;
  231413. + struct snd_soc_pcm_runtime *rtd = pcm->private_data;
  231414. + struct hdmi_dma_priv *priv = dev_get_drvdata(rtd->platform->dev);
  231415. +
  231416. + if (substream) {
  231417. + snd_dma_free_pages(&substream->dma_buffer);
  231418. + substream->dma_buffer.area = NULL;
  231419. + substream->dma_buffer.addr = 0;
  231420. + }
  231421. +
  231422. + /* Free the hw_buffer */
  231423. + snd_dma_free_pages(&priv->hw_buffer);
  231424. + priv->hw_buffer.area = NULL;
  231425. + priv->hw_buffer.addr = 0;
  231426. +}
  231427. +
  231428. +static struct snd_soc_platform_driver imx_hdmi_platform = {
  231429. + .ops = &imx_hdmi_dma_pcm_ops,
  231430. + .pcm_new = imx_hdmi_dma_pcm_new,
  231431. + .pcm_free = imx_hdmi_dma_pcm_free,
  231432. +};
  231433. +
  231434. +static int imx_soc_platform_probe(struct platform_device *pdev)
  231435. +{
  231436. + struct imx_hdmi *hdmi_drvdata = platform_get_drvdata(pdev);
  231437. + struct hdmi_dma_priv *priv;
  231438. + int ret = 0;
  231439. +
  231440. + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  231441. + if (!priv) {
  231442. + dev_err(&pdev->dev, "Failed to alloc hdmi_dma\n");
  231443. + return -ENOMEM;
  231444. + }
  231445. +
  231446. + priv->hdmi_sdma_t = dma_alloc_coherent(NULL,
  231447. + sizeof(struct hdmi_sdma_script),
  231448. + &priv->phy_hdmi_sdma_t, GFP_KERNEL);
  231449. + if (!priv->hdmi_sdma_t) {
  231450. + dev_err(&pdev->dev, "Failed to alloc hdmi_sdma_t\n");
  231451. + return -ENOMEM;
  231452. + }
  231453. +
  231454. + priv->tx_active = false;
  231455. + spin_lock_init(&priv->irq_lock);
  231456. +
  231457. + priv->pdev = hdmi_drvdata->pdev;
  231458. +
  231459. + hdmi_dma_init_iec_header();
  231460. +
  231461. + dev_set_drvdata(&pdev->dev, priv);
  231462. +
  231463. + switch (hdmi_readb(HDMI_REVISION_ID)) {
  231464. + case 0x0a:
  231465. + snd_imx_hardware.period_bytes_max = HDMI_DMA_PERIOD_BYTES / 4;
  231466. + snd_imx_hardware.period_bytes_min = HDMI_DMA_PERIOD_BYTES / 4;
  231467. + break;
  231468. + default:
  231469. + break;
  231470. + }
  231471. +
  231472. + ret = snd_soc_register_platform(&pdev->dev, &imx_hdmi_platform);
  231473. + if (ret)
  231474. + goto err_plat;
  231475. +
  231476. + return 0;
  231477. +
  231478. +err_plat:
  231479. + dma_free_coherent(NULL, sizeof(struct hdmi_sdma_script),
  231480. + priv->hdmi_sdma_t, priv->phy_hdmi_sdma_t);
  231481. +
  231482. + return ret;
  231483. +}
  231484. +
  231485. +static int imx_soc_platform_remove(struct platform_device *pdev)
  231486. +{
  231487. + struct hdmi_dma_priv *priv = dev_get_drvdata(&pdev->dev);
  231488. +
  231489. + dma_free_coherent(NULL, sizeof(struct hdmi_sdma_script),
  231490. + priv->hdmi_sdma_t, priv->phy_hdmi_sdma_t);
  231491. +
  231492. + snd_soc_unregister_platform(&pdev->dev);
  231493. +
  231494. + return 0;
  231495. +}
  231496. +
  231497. +static struct platform_driver imx_hdmi_dma_driver = {
  231498. + .driver = {
  231499. + .name = "imx-hdmi-audio",
  231500. + .owner = THIS_MODULE,
  231501. + },
  231502. + .probe = imx_soc_platform_probe,
  231503. + .remove = imx_soc_platform_remove,
  231504. +};
  231505. +
  231506. +module_platform_driver(imx_hdmi_dma_driver);
  231507. +
  231508. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  231509. +MODULE_DESCRIPTION("i.MX HDMI audio DMA");
  231510. +MODULE_LICENSE("GPL");
  231511. diff -Nur linux-3.14.15/sound/soc/fsl/imx-hdmi.h linux-linaro-stable-mx6/sound/soc/fsl/imx-hdmi.h
  231512. --- linux-3.14.15/sound/soc/fsl/imx-hdmi.h 1970-01-01 01:00:00.000000000 +0100
  231513. +++ linux-linaro-stable-mx6/sound/soc/fsl/imx-hdmi.h 2014-08-20 19:24:09.562914171 +0200
  231514. @@ -0,0 +1,105 @@
  231515. +/*
  231516. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  231517. + *
  231518. + * This program is free software; you can redistribute it and/or modify
  231519. + * it under the terms of the GNU General Public License as published by
  231520. + * the Free Software Foundation; either version 2 of the License, or
  231521. + * (at your option) any later version.
  231522. + *
  231523. + * This program is distributed in the hope that it will be useful,
  231524. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  231525. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  231526. + * GNU General Public License for more details.
  231527. + *
  231528. + * You should have received a copy of the GNU General Public License along
  231529. + * with this program; if not, write to the Free Software Foundation, Inc.,
  231530. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  231531. + */
  231532. +
  231533. +#ifndef __IMX_HDMI_H
  231534. +#define __IMX_HDMI_H
  231535. +
  231536. +struct imx_hdmi_sdma_params {
  231537. + dma_addr_t phyaddr;
  231538. + u32 buffer_num;
  231539. + int dma;
  231540. +};
  231541. +
  231542. +struct imx_hdmi {
  231543. + struct snd_soc_dai_driver cpu_dai_drv;
  231544. + struct platform_device *codec_dev;
  231545. + struct platform_device *dma_dev;
  231546. + struct platform_device *pdev;
  231547. + struct clk *isfr_clk;
  231548. + struct clk *iahb_clk;
  231549. +};
  231550. +
  231551. +#define HDMI_MAX_RATES 7
  231552. +#define HDMI_MAX_SAMPLE_SIZE 3
  231553. +#define HDMI_MAX_CHANNEL_CONSTRAINTS 4
  231554. +
  231555. +#define MXC_HDMI_RATES_PLAYBACK \
  231556. + (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
  231557. + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
  231558. + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
  231559. +
  231560. +#define MXC_HDMI_FORMATS_PLAYBACK \
  231561. + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
  231562. +
  231563. +union hdmi_audio_header_t {
  231564. + uint64_t U;
  231565. + struct {
  231566. + unsigned consumer:1;
  231567. + unsigned linear_pcm:1;
  231568. + unsigned copyright:1;
  231569. + unsigned pre_emphasis:3;
  231570. + unsigned mode:2;
  231571. +
  231572. + unsigned category_code:8;
  231573. +
  231574. + unsigned source:4;
  231575. + unsigned channel:4;
  231576. +
  231577. + unsigned sample_freq:4;
  231578. + unsigned clock_acc:2;
  231579. + unsigned reserved0:2;
  231580. +
  231581. + unsigned word_length:4;
  231582. + unsigned org_sample_freq:4;
  231583. +
  231584. + unsigned cgms_a:2;
  231585. + unsigned reserved1:6;
  231586. +
  231587. + unsigned reserved2:8;
  231588. +
  231589. + unsigned reserved3:8;
  231590. + } B;
  231591. + unsigned char status[8];
  231592. +};
  231593. +
  231594. +union hdmi_audio_dma_data_t {
  231595. + uint32_t U;
  231596. + struct {
  231597. + unsigned data:24;
  231598. + unsigned v:1;
  231599. + unsigned u:1;
  231600. + unsigned c:1;
  231601. + unsigned p:1;
  231602. + unsigned b:1;
  231603. + unsigned reserved:3;
  231604. + } B;
  231605. +};
  231606. +
  231607. +extern union hdmi_audio_header_t iec_header;
  231608. +
  231609. +#define hdmi_audio_writeb(reg, bit, val) \
  231610. + do { \
  231611. + hdmi_mask_writeb(val, HDMI_ ## reg, \
  231612. + HDMI_ ## reg ## _ ## bit ## _OFFSET, \
  231613. + HDMI_ ## reg ## _ ## bit ## _MASK); \
  231614. + pr_debug("Set reg: HDMI_" #reg " (0x%x) "\
  231615. + "bit: HDMI_" #reg "_" #bit " (%d) to val: %x\n", \
  231616. + HDMI_ ## reg, HDMI_ ## reg ## _ ## bit ## _OFFSET, val); \
  231617. + } while (0)
  231618. +
  231619. +#endif /* __IMX_HDMI_H */
  231620. diff -Nur linux-3.14.15/sound/soc/fsl/imx-pcm-dma.c linux-linaro-stable-mx6/sound/soc/fsl/imx-pcm-dma.c
  231621. --- linux-3.14.15/sound/soc/fsl/imx-pcm-dma.c 2014-07-31 23:51:43.000000000 +0200
  231622. +++ linux-linaro-stable-mx6/sound/soc/fsl/imx-pcm-dma.c 2014-08-20 19:31:58.748923182 +0200
  231623. @@ -11,6 +11,10 @@
  231624. * Free Software Foundation; either version 2 of the License, or (at your
  231625. * option) any later version.
  231626. */
  231627. +#include <linux/init.h>
  231628. +#include <linux/kernel.h>
  231629. +#include <linux/module.h>
  231630. +#include <linux/device.h>
  231631. #include <linux/platform_device.h>
  231632. #include <linux/dmaengine.h>
  231633. #include <linux/types.h>
  231634. @@ -20,6 +24,7 @@
  231635. #include <sound/pcm.h>
  231636. #include <sound/soc.h>
  231637. #include <sound/dmaengine_pcm.h>
  231638. +#include <linux/platform_data/dma-imx.h>
  231639. #include "imx-pcm.h"
  231640. @@ -40,28 +45,97 @@
  231641. SNDRV_PCM_INFO_MMAP_VALID |
  231642. SNDRV_PCM_INFO_PAUSE |
  231643. SNDRV_PCM_INFO_RESUME,
  231644. - .formats = SNDRV_PCM_FMTBIT_S16_LE,
  231645. - .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
  231646. + .formats = SNDRV_PCM_FMTBIT_S16_LE |
  231647. + SNDRV_PCM_FMTBIT_S24_LE |
  231648. + SNDRV_PCM_FMTBIT_S20_3LE,
  231649. + .buffer_bytes_max = IMX_DEFAULT_DMABUF_SIZE,
  231650. .period_bytes_min = 128,
  231651. .period_bytes_max = 65535, /* Limited by SDMA engine */
  231652. - .periods_min = 2,
  231653. + .periods_min = 4,
  231654. .periods_max = 255,
  231655. .fifo_size = 0,
  231656. };
  231657. +static void imx_pcm_dma_set_config_from_dai_data(
  231658. + const struct snd_pcm_substream *substream,
  231659. + const struct snd_dmaengine_dai_dma_data *dma_data,
  231660. + struct dma_slave_config *slave_config)
  231661. +{
  231662. + struct imx_dma_data *filter_data = dma_data->filter_data;
  231663. +
  231664. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  231665. + slave_config->dst_addr = dma_data->addr;
  231666. + slave_config->dst_maxburst = dma_data->maxburst;
  231667. + if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
  231668. + slave_config->dst_addr_width = dma_data->addr_width;
  231669. + } else {
  231670. + slave_config->src_addr = dma_data->addr;
  231671. + slave_config->src_maxburst = dma_data->maxburst;
  231672. + if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
  231673. + slave_config->src_addr_width = dma_data->addr_width;
  231674. + }
  231675. +
  231676. + slave_config->slave_id = dma_data->slave_id;
  231677. +
  231678. + /*
  231679. + * In dma binding mode, there is no filter_data, so dma_request need to be
  231680. + * set to zero.
  231681. + */
  231682. + if (filter_data) {
  231683. + slave_config->dma_request0 = filter_data->dma_request0;
  231684. + slave_config->dma_request1 = filter_data->dma_request1;
  231685. + } else {
  231686. + slave_config->dma_request0 = 0;
  231687. + slave_config->dma_request1 = 0;
  231688. + }
  231689. +}
  231690. +
  231691. +static int imx_pcm_dma_prepare_slave_config(struct snd_pcm_substream *substream,
  231692. + struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config)
  231693. +{
  231694. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231695. + struct snd_dmaengine_dai_dma_data *dma_data;
  231696. + int ret;
  231697. +
  231698. + dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
  231699. +
  231700. + ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
  231701. + if (ret)
  231702. + return ret;
  231703. +
  231704. + imx_pcm_dma_set_config_from_dai_data(substream, dma_data,
  231705. + slave_config);
  231706. +
  231707. + return 0;
  231708. +}
  231709. +
  231710. static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = {
  231711. .pcm_hardware = &imx_pcm_hardware,
  231712. - .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
  231713. + .prepare_slave_config = imx_pcm_dma_prepare_slave_config,
  231714. .compat_filter_fn = filter,
  231715. - .prealloc_buffer_size = IMX_SSI_DMABUF_SIZE,
  231716. + .prealloc_buffer_size = IMX_DEFAULT_DMABUF_SIZE,
  231717. };
  231718. -int imx_pcm_dma_init(struct platform_device *pdev)
  231719. +int imx_pcm_dma_init(struct platform_device *pdev, unsigned int flags, size_t size)
  231720. {
  231721. - return devm_snd_dmaengine_pcm_register(&pdev->dev,
  231722. - &imx_dmaengine_pcm_config,
  231723. - SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
  231724. - SND_DMAENGINE_PCM_FLAG_COMPAT);
  231725. + struct snd_dmaengine_pcm_config *config;
  231726. + struct snd_pcm_hardware *pcm_hardware;
  231727. +
  231728. + config = devm_kzalloc(&pdev->dev,
  231729. + sizeof(struct snd_dmaengine_pcm_config), GFP_KERNEL);
  231730. + *config = imx_dmaengine_pcm_config;
  231731. + if (size)
  231732. + config->prealloc_buffer_size = size;
  231733. +
  231734. + pcm_hardware = devm_kzalloc(&pdev->dev,
  231735. + sizeof(struct snd_pcm_hardware), GFP_KERNEL);
  231736. + *pcm_hardware = imx_pcm_hardware;
  231737. + if (size)
  231738. + pcm_hardware->buffer_bytes_max = size;
  231739. +
  231740. + config->pcm_hardware = pcm_hardware;
  231741. +
  231742. + return devm_snd_dmaengine_pcm_register(&pdev->dev, config, flags);
  231743. }
  231744. EXPORT_SYMBOL_GPL(imx_pcm_dma_init);
  231745. diff -Nur linux-3.14.15/sound/soc/fsl/imx-pcm.h linux-linaro-stable-mx6/sound/soc/fsl/imx-pcm.h
  231746. --- linux-3.14.15/sound/soc/fsl/imx-pcm.h 2014-07-31 23:51:43.000000000 +0200
  231747. +++ linux-linaro-stable-mx6/sound/soc/fsl/imx-pcm.h 2014-08-20 19:31:58.748923182 +0200
  231748. @@ -18,13 +18,17 @@
  231749. /*
  231750. * Do not change this as the FIQ handler depends on this size
  231751. */
  231752. +#define IMX_DEFAULT_DMABUF_SIZE (256 * 1024)
  231753. #define IMX_SSI_DMABUF_SIZE (64 * 1024)
  231754. +#define IMX_SPDIF_DMABUF_SIZE (64 * 1024)
  231755. +#define IMX_ESAI_DMABUF_SIZE (256 * 1024)
  231756. +#define IMX_ASRC_DMABUF_SIZE (256 * 1024)
  231757. static inline void
  231758. imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data,
  231759. int dma, enum sdma_peripheral_type peripheral_type)
  231760. {
  231761. - dma_data->dma_request = dma;
  231762. + dma_data->dma_request0 = dma;
  231763. dma_data->priority = DMA_PRIO_HIGH;
  231764. dma_data->peripheral_type = peripheral_type;
  231765. }
  231766. @@ -39,9 +43,10 @@
  231767. };
  231768. #if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA)
  231769. -int imx_pcm_dma_init(struct platform_device *pdev);
  231770. +int imx_pcm_dma_init(struct platform_device *pdev, unsigned int flags, size_t size);
  231771. #else
  231772. -static inline int imx_pcm_dma_init(struct platform_device *pdev)
  231773. +static inline int imx_pcm_dma_init(struct platform_device *pdev,
  231774. + unsigned int flags, size_t size)
  231775. {
  231776. return -ENODEV;
  231777. }
  231778. diff -Nur linux-3.14.15/sound/soc/fsl/imx-spdif.c linux-linaro-stable-mx6/sound/soc/fsl/imx-spdif.c
  231779. --- linux-3.14.15/sound/soc/fsl/imx-spdif.c 2014-07-31 23:51:43.000000000 +0200
  231780. +++ linux-linaro-stable-mx6/sound/soc/fsl/imx-spdif.c 2014-08-20 19:31:58.752923199 +0200
  231781. @@ -65,14 +65,15 @@
  231782. if (ret)
  231783. goto end;
  231784. + platform_set_drvdata(pdev, &data->card);
  231785. + snd_soc_card_set_drvdata(&data->card, data);
  231786. +
  231787. ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
  231788. if (ret) {
  231789. dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret);
  231790. goto end;
  231791. }
  231792. - platform_set_drvdata(pdev, data);
  231793. -
  231794. end:
  231795. if (spdif_np)
  231796. of_node_put(spdif_np);
  231797. @@ -90,6 +91,7 @@
  231798. .driver = {
  231799. .name = "imx-spdif",
  231800. .owner = THIS_MODULE,
  231801. + .pm = &snd_soc_pm_ops,
  231802. .of_match_table = imx_spdif_dt_ids,
  231803. },
  231804. .probe = imx_spdif_audio_probe,
  231805. diff -Nur linux-3.14.15/sound/soc/fsl/imx-ssi.c linux-linaro-stable-mx6/sound/soc/fsl/imx-ssi.c
  231806. --- linux-3.14.15/sound/soc/fsl/imx-ssi.c 2014-07-31 23:51:43.000000000 +0200
  231807. +++ linux-linaro-stable-mx6/sound/soc/fsl/imx-ssi.c 2014-08-20 19:31:58.752923199 +0200
  231808. @@ -602,7 +602,8 @@
  231809. ssi->fiq_params.dma_params_tx = &ssi->dma_params_tx;
  231810. ssi->fiq_init = imx_pcm_fiq_init(pdev, &ssi->fiq_params);
  231811. - ssi->dma_init = imx_pcm_dma_init(pdev);
  231812. + ssi->dma_init = imx_pcm_dma_init(pdev, SND_DMAENGINE_PCM_FLAG_NO_RESIDUE,
  231813. + IMX_SSI_DMABUF_SIZE);
  231814. if (ssi->fiq_init && ssi->dma_init) {
  231815. ret = ssi->fiq_init;
  231816. diff -Nur linux-3.14.15/sound/soc/fsl/imx-wm8962.c linux-linaro-stable-mx6/sound/soc/fsl/imx-wm8962.c
  231817. --- linux-3.14.15/sound/soc/fsl/imx-wm8962.c 2014-07-31 23:51:43.000000000 +0200
  231818. +++ linux-linaro-stable-mx6/sound/soc/fsl/imx-wm8962.c 2014-08-20 19:31:58.752923199 +0200
  231819. @@ -1,9 +1,9 @@
  231820. /*
  231821. - * Copyright 2013 Freescale Semiconductor, Inc.
  231822. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  231823. *
  231824. * Based on imx-sgtl5000.c
  231825. - * Copyright 2012 Freescale Semiconductor, Inc.
  231826. - * Copyright 2012 Linaro Ltd.
  231827. + * Copyright (C) 2012 Freescale Semiconductor, Inc.
  231828. + * Copyright (C) 2012 Linaro Ltd.
  231829. *
  231830. * The code contained herein is licensed under the GNU General Public
  231831. * License. You may obtain a copy of the GNU General Public License
  231832. @@ -16,9 +16,12 @@
  231833. #include <linux/module.h>
  231834. #include <linux/of_platform.h>
  231835. #include <linux/i2c.h>
  231836. +#include <linux/of_gpio.h>
  231837. #include <linux/slab.h>
  231838. +#include <linux/gpio.h>
  231839. #include <linux/clk.h>
  231840. #include <sound/soc.h>
  231841. +#include <sound/jack.h>
  231842. #include <sound/pcm_params.h>
  231843. #include <sound/soc-dapm.h>
  231844. #include <linux/pinctrl/consumer.h>
  231845. @@ -33,15 +36,134 @@
  231846. struct snd_soc_card card;
  231847. char codec_dai_name[DAI_NAME_SIZE];
  231848. char platform_name[DAI_NAME_SIZE];
  231849. - struct clk *codec_clk;
  231850. unsigned int clk_frequency;
  231851. };
  231852. struct imx_priv {
  231853. + int hp_gpio;
  231854. + int hp_active_low;
  231855. + int mic_gpio;
  231856. + int mic_active_low;
  231857. + bool amic_mono;
  231858. + bool dmic_mono;
  231859. + struct snd_soc_codec *codec;
  231860. struct platform_device *pdev;
  231861. + struct snd_pcm_substream *first_stream;
  231862. + struct snd_pcm_substream *second_stream;
  231863. };
  231864. static struct imx_priv card_priv;
  231865. +static struct snd_soc_jack imx_hp_jack;
  231866. +static struct snd_soc_jack_pin imx_hp_jack_pins[] = {
  231867. + {
  231868. + .pin = "Headphone Jack",
  231869. + .mask = SND_JACK_HEADPHONE,
  231870. + },
  231871. +};
  231872. +static struct snd_soc_jack_gpio imx_hp_jack_gpio = {
  231873. + .name = "headphone detect",
  231874. + .report = SND_JACK_HEADPHONE,
  231875. + .debounce_time = 250,
  231876. + .invert = 0,
  231877. +};
  231878. +
  231879. +static struct snd_soc_jack imx_mic_jack;
  231880. +static struct snd_soc_jack_pin imx_mic_jack_pins[] = {
  231881. + {
  231882. + .pin = "AMIC",
  231883. + .mask = SND_JACK_MICROPHONE,
  231884. + },
  231885. +};
  231886. +static struct snd_soc_jack_gpio imx_mic_jack_gpio = {
  231887. + .name = "microphone detect",
  231888. + .report = SND_JACK_MICROPHONE,
  231889. + .debounce_time = 250,
  231890. + .invert = 0,
  231891. +};
  231892. +
  231893. +static int hpjack_status_check(void)
  231894. +{
  231895. + struct imx_priv *priv = &card_priv;
  231896. + struct platform_device *pdev = priv->pdev;
  231897. + char *envp[3], *buf;
  231898. + int hp_status, ret;
  231899. +
  231900. + if (!gpio_is_valid(priv->hp_gpio))
  231901. + return 0;
  231902. +
  231903. + hp_status = gpio_get_value(priv->hp_gpio) ? 1 : 0;
  231904. +
  231905. + buf = kmalloc(32, GFP_ATOMIC);
  231906. + if (!buf) {
  231907. + dev_err(&pdev->dev, "%s kmalloc failed\n", __func__);
  231908. + return -ENOMEM;
  231909. + }
  231910. +
  231911. + if (hp_status != priv->hp_active_low) {
  231912. + snprintf(buf, 32, "STATE=%d", 2);
  231913. + snd_soc_dapm_disable_pin(&priv->codec->dapm, "Ext Spk");
  231914. + ret = imx_hp_jack_gpio.report;
  231915. + } else {
  231916. + snprintf(buf, 32, "STATE=%d", 0);
  231917. + snd_soc_dapm_enable_pin(&priv->codec->dapm, "Ext Spk");
  231918. + ret = 0;
  231919. + }
  231920. +
  231921. + envp[0] = "NAME=headphone";
  231922. + envp[1] = buf;
  231923. + envp[2] = NULL;
  231924. + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
  231925. + kfree(buf);
  231926. +
  231927. + return ret;
  231928. +}
  231929. +
  231930. +static int micjack_status_check(void)
  231931. +{
  231932. + struct imx_priv *priv = &card_priv;
  231933. + struct platform_device *pdev = priv->pdev;
  231934. + char *envp[3], *buf;
  231935. + int mic_status, ret;
  231936. +
  231937. + if (!gpio_is_valid(priv->mic_gpio))
  231938. + return 0;
  231939. +
  231940. + mic_status = gpio_get_value(priv->mic_gpio) ? 1 : 0;
  231941. +
  231942. + if ((mic_status != priv->mic_active_low && priv->amic_mono)
  231943. + || (mic_status == priv->mic_active_low && priv->dmic_mono))
  231944. + snd_soc_update_bits(priv->codec, WM8962_THREED1,
  231945. + WM8962_ADC_MONOMIX_MASK, WM8962_ADC_MONOMIX);
  231946. + else
  231947. + snd_soc_update_bits(priv->codec, WM8962_THREED1,
  231948. + WM8962_ADC_MONOMIX_MASK, 0);
  231949. +
  231950. + buf = kmalloc(32, GFP_ATOMIC);
  231951. + if (!buf) {
  231952. + dev_err(&pdev->dev, "%s kmalloc failed\n", __func__);
  231953. + return -ENOMEM;
  231954. + }
  231955. +
  231956. + if (mic_status != priv->mic_active_low) {
  231957. + snprintf(buf, 32, "STATE=%d", 2);
  231958. + snd_soc_dapm_disable_pin(&priv->codec->dapm, "DMIC");
  231959. + ret = imx_mic_jack_gpio.report;
  231960. + } else {
  231961. + snprintf(buf, 32, "STATE=%d", 0);
  231962. + snd_soc_dapm_enable_pin(&priv->codec->dapm, "DMIC");
  231963. + ret = 0;
  231964. + }
  231965. +
  231966. + envp[0] = "NAME=microphone";
  231967. + envp[1] = buf;
  231968. + envp[2] = NULL;
  231969. + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
  231970. + kfree(buf);
  231971. +
  231972. + return ret;
  231973. +}
  231974. +
  231975. +
  231976. static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
  231977. SND_SOC_DAPM_HP("Headphone Jack", NULL),
  231978. SND_SOC_DAPM_SPK("Ext Spk", NULL),
  231979. @@ -49,14 +171,57 @@
  231980. SND_SOC_DAPM_MIC("DMIC", NULL),
  231981. };
  231982. -static int sample_rate = 44100;
  231983. -static snd_pcm_format_t sample_format = SNDRV_PCM_FORMAT_S16_LE;
  231984. -
  231985. static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
  231986. - struct snd_pcm_hw_params *params)
  231987. + struct snd_pcm_hw_params *params)
  231988. {
  231989. - sample_rate = params_rate(params);
  231990. - sample_format = params_format(params);
  231991. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231992. + struct snd_soc_dai *codec_dai = rtd->codec_dai;
  231993. + struct imx_priv *priv = &card_priv;
  231994. + struct device *dev = &priv->pdev->dev;
  231995. + struct snd_soc_card *card = codec_dai->codec->card;
  231996. + struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
  231997. + unsigned int sample_rate = params_rate(params);
  231998. + snd_pcm_format_t sample_format = params_format(params);
  231999. + u32 dai_format, pll_out;
  232000. + int ret = 0;
  232001. +
  232002. + if (!priv->first_stream) {
  232003. + priv->first_stream = substream;
  232004. + } else {
  232005. + priv->second_stream = substream;
  232006. +
  232007. + /* We suppose the two substream are using same params */
  232008. + return 0;
  232009. + }
  232010. +
  232011. + dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  232012. + SND_SOC_DAIFMT_CBM_CFM;
  232013. +
  232014. + /* set codec DAI configuration */
  232015. + ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
  232016. + if (ret) {
  232017. + dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
  232018. + return ret;
  232019. + }
  232020. +
  232021. + if (sample_format == SNDRV_PCM_FORMAT_S24_LE)
  232022. + pll_out = sample_rate * 384;
  232023. + else
  232024. + pll_out = sample_rate * 256;
  232025. +
  232026. + ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, WM8962_FLL_MCLK,
  232027. + data->clk_frequency, pll_out);
  232028. + if (ret) {
  232029. + dev_err(dev, "failed to start FLL: %d\n", ret);
  232030. + return ret;
  232031. + }
  232032. +
  232033. + ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_FLL,
  232034. + pll_out, SND_SOC_CLOCK_IN);
  232035. + if (ret) {
  232036. + dev_err(dev, "failed to set SYSCLK: %d\n", ret);
  232037. + return ret;
  232038. + }
  232039. return 0;
  232040. }
  232041. @@ -133,6 +298,89 @@
  232042. return 0;
  232043. }
  232044. +static int imx_wm8962_gpio_init(struct snd_soc_pcm_runtime *rtd)
  232045. +{
  232046. + struct snd_soc_codec *codec = rtd->codec;
  232047. + struct imx_priv *priv = &card_priv;
  232048. +
  232049. + priv->codec = codec;
  232050. +
  232051. + if (gpio_is_valid(priv->hp_gpio)) {
  232052. + imx_hp_jack_gpio.gpio = priv->hp_gpio;
  232053. + imx_hp_jack_gpio.jack_status_check = hpjack_status_check;
  232054. +
  232055. + snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, &imx_hp_jack);
  232056. + snd_soc_jack_add_pins(&imx_hp_jack,
  232057. + ARRAY_SIZE(imx_hp_jack_pins), imx_hp_jack_pins);
  232058. + snd_soc_jack_add_gpios(&imx_hp_jack, 1, &imx_hp_jack_gpio);
  232059. + }
  232060. +
  232061. + if (gpio_is_valid(priv->mic_gpio)) {
  232062. + imx_mic_jack_gpio.gpio = priv->mic_gpio;
  232063. + imx_mic_jack_gpio.jack_status_check = micjack_status_check;
  232064. +
  232065. + snd_soc_jack_new(codec, "AMIC", SND_JACK_MICROPHONE, &imx_mic_jack);
  232066. + snd_soc_jack_add_pins(&imx_mic_jack,
  232067. + ARRAY_SIZE(imx_mic_jack_pins), imx_mic_jack_pins);
  232068. + snd_soc_jack_add_gpios(&imx_mic_jack, 1, &imx_mic_jack_gpio);
  232069. + } else if (priv->amic_mono || priv->dmic_mono) {
  232070. + /*
  232071. + * Permanent set monomix bit if only one microphone
  232072. + * is present on the board while it needs monomix.
  232073. + */
  232074. + snd_soc_update_bits(priv->codec, WM8962_THREED1,
  232075. + WM8962_ADC_MONOMIX_MASK, WM8962_ADC_MONOMIX);
  232076. + }
  232077. +
  232078. + return 0;
  232079. +}
  232080. +
  232081. +static ssize_t show_headphone(struct device_driver *dev, char *buf)
  232082. +{
  232083. + struct imx_priv *priv = &card_priv;
  232084. + int hp_status;
  232085. +
  232086. + if (!gpio_is_valid(priv->hp_gpio)) {
  232087. + strcpy(buf, "no detect gpio connected\n");
  232088. + return strlen(buf);
  232089. + }
  232090. +
  232091. + /* Check if headphone is plugged in */
  232092. + hp_status = gpio_get_value(priv->hp_gpio) ? 1 : 0;
  232093. +
  232094. + if (hp_status != priv->hp_active_low)
  232095. + strcpy(buf, "headphone\n");
  232096. + else
  232097. + strcpy(buf, "speaker\n");
  232098. +
  232099. + return strlen(buf);
  232100. +}
  232101. +
  232102. +static DRIVER_ATTR(headphone, S_IRUGO | S_IWUSR, show_headphone, NULL);
  232103. +
  232104. +static ssize_t show_mic(struct device_driver *dev, char *buf)
  232105. +{
  232106. + struct imx_priv *priv = &card_priv;
  232107. + int mic_status;
  232108. +
  232109. + if (!gpio_is_valid(priv->mic_gpio)) {
  232110. + strcpy(buf, "no detect gpio connected\n");
  232111. + return strlen(buf);
  232112. + }
  232113. +
  232114. + /* Check if analog microphone is plugged in */
  232115. + mic_status = gpio_get_value(priv->mic_gpio) ? 1 : 0;
  232116. +
  232117. + if (mic_status != priv->mic_active_low)
  232118. + strcpy(buf, "amic\n");
  232119. + else
  232120. + strcpy(buf, "dmic\n");
  232121. +
  232122. + return strlen(buf);
  232123. +}
  232124. +
  232125. +static DRIVER_ATTR(microphone, S_IRUGO | S_IWUSR, show_mic, NULL);
  232126. +
  232127. static int imx_wm8962_late_probe(struct snd_soc_card *card)
  232128. {
  232129. struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
  232130. @@ -157,6 +405,7 @@
  232131. struct imx_priv *priv = &card_priv;
  232132. struct i2c_client *codec_dev;
  232133. struct imx_wm8962_data *data;
  232134. + struct clk *codec_clk = NULL;
  232135. int int_port, ext_port;
  232136. int ret;
  232137. @@ -219,25 +468,31 @@
  232138. goto fail;
  232139. }
  232140. + priv->first_stream = NULL;
  232141. + priv->second_stream = NULL;
  232142. +
  232143. data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
  232144. if (!data) {
  232145. ret = -ENOMEM;
  232146. goto fail;
  232147. }
  232148. - data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
  232149. - if (IS_ERR(data->codec_clk)) {
  232150. - ret = PTR_ERR(data->codec_clk);
  232151. + codec_clk = devm_clk_get(&codec_dev->dev, NULL);
  232152. + if (IS_ERR(codec_clk)) {
  232153. + ret = PTR_ERR(codec_clk);
  232154. dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
  232155. goto fail;
  232156. }
  232157. - data->clk_frequency = clk_get_rate(data->codec_clk);
  232158. - ret = clk_prepare_enable(data->codec_clk);
  232159. - if (ret) {
  232160. - dev_err(&codec_dev->dev, "failed to enable codec clk: %d\n", ret);
  232161. - goto fail;
  232162. - }
  232163. + data->clk_frequency = clk_get_rate(codec_clk);
  232164. +
  232165. + priv->amic_mono = of_property_read_bool(codec_np, "amic-mono");
  232166. + priv->dmic_mono = of_property_read_bool(codec_np, "dmic-mono");
  232167. +
  232168. + priv->hp_gpio = of_get_named_gpio_flags(np, "hp-det-gpios", 0,
  232169. + (enum of_gpio_flags *)&priv->hp_active_low);
  232170. + priv->mic_gpio = of_get_named_gpio_flags(np, "mic-det-gpios", 0,
  232171. + (enum of_gpio_flags *)&priv->mic_active_low);
  232172. data->dai.name = "HiFi";
  232173. data->dai.stream_name = "HiFi";
  232174. @@ -246,23 +501,23 @@
  232175. data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev);
  232176. data->dai.platform_of_node = ssi_np;
  232177. data->dai.ops = &imx_hifi_ops;
  232178. + data->dai.init = &imx_wm8962_gpio_init;
  232179. data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  232180. SND_SOC_DAIFMT_CBM_CFM;
  232181. data->card.dev = &pdev->dev;
  232182. ret = snd_soc_of_parse_card_name(&data->card, "model");
  232183. if (ret)
  232184. - goto clk_fail;
  232185. + goto fail;
  232186. ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
  232187. if (ret)
  232188. - goto clk_fail;
  232189. + goto fail;
  232190. data->card.num_links = 1;
  232191. data->card.dai_link = &data->dai;
  232192. data->card.dapm_widgets = imx_wm8962_dapm_widgets;
  232193. data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8962_dapm_widgets);
  232194. data->card.late_probe = imx_wm8962_late_probe;
  232195. - data->card.set_bias_level = imx_wm8962_set_bias_level;
  232196. platform_set_drvdata(pdev, &data->card);
  232197. snd_soc_card_set_drvdata(&data->card, data);
  232198. @@ -270,16 +525,31 @@
  232199. ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
  232200. if (ret) {
  232201. dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
  232202. - goto clk_fail;
  232203. + goto fail;
  232204. }
  232205. - of_node_put(ssi_np);
  232206. - of_node_put(codec_np);
  232207. + if (gpio_is_valid(priv->hp_gpio)) {
  232208. + ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone);
  232209. + if (ret) {
  232210. + dev_err(&pdev->dev, "create hp attr failed (%d)\n", ret);
  232211. + goto fail_hp;
  232212. + }
  232213. + }
  232214. - return 0;
  232215. + if (gpio_is_valid(priv->mic_gpio)) {
  232216. + ret = driver_create_file(pdev->dev.driver, &driver_attr_microphone);
  232217. + if (ret) {
  232218. + dev_err(&pdev->dev, "create mic attr failed (%d)\n", ret);
  232219. + goto fail_mic;
  232220. + }
  232221. + }
  232222. +
  232223. + goto fail;
  232224. -clk_fail:
  232225. - clk_disable_unprepare(data->codec_clk);
  232226. +fail_mic:
  232227. + driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
  232228. +fail_hp:
  232229. + snd_soc_unregister_card(&data->card);
  232230. fail:
  232231. if (ssi_np)
  232232. of_node_put(ssi_np);
  232233. @@ -291,11 +561,8 @@
  232234. static int imx_wm8962_remove(struct platform_device *pdev)
  232235. {
  232236. - struct snd_soc_card *card = platform_get_drvdata(pdev);
  232237. - struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
  232238. -
  232239. - if (!IS_ERR(data->codec_clk))
  232240. - clk_disable_unprepare(data->codec_clk);
  232241. + driver_remove_file(pdev->dev.driver, &driver_attr_microphone);
  232242. + driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
  232243. return 0;
  232244. }
  232245. diff -Nur linux-3.14.15/sound/soc/fsl/Kconfig linux-linaro-stable-mx6/sound/soc/fsl/Kconfig
  232246. --- linux-3.14.15/sound/soc/fsl/Kconfig 2014-07-31 23:51:43.000000000 +0200
  232247. +++ linux-linaro-stable-mx6/sound/soc/fsl/Kconfig 2014-08-20 19:31:58.740923149 +0200
  232248. @@ -11,6 +11,12 @@
  232249. config SND_SOC_FSL_ESAI
  232250. tristate
  232251. +config SND_SOC_FSL_ASRC
  232252. + tristate
  232253. +
  232254. +config SND_SOC_FSL_HDMI
  232255. + tristate
  232256. +
  232257. config SND_SOC_FSL_UTILS
  232258. tristate
  232259. @@ -126,6 +132,11 @@
  232260. tristate
  232261. select SND_SOC_GENERIC_DMAENGINE_PCM
  232262. +config SND_SOC_IMX_HDMI_DMA
  232263. + bool
  232264. + select SND_SOC_GENERIC_DMAENGINE_PCM
  232265. + select SND_SOC_IMX_PCM_DMA
  232266. +
  232267. config SND_SOC_IMX_AUDMUX
  232268. tristate
  232269. @@ -178,6 +189,18 @@
  232270. Enable I2S based access to the TLV320AIC23B codec attached
  232271. to the SSI interface
  232272. +config SND_SOC_IMX_CS42888
  232273. + tristate "SoC Audio support for i.MX boards with cs42888"
  232274. + depends on OF && I2C
  232275. + select SND_SOC_CS42888
  232276. + select SND_SOC_IMX_PCM_DMA
  232277. + select SND_SOC_FSL_ESAI
  232278. + select SND_SOC_FSL_UTILS
  232279. + help
  232280. + SoC Audio support for i.MX boards with cs42888
  232281. + Say Y if you want to add support for SoC audio on an i.MX board with
  232282. + a cs42888 codec.
  232283. +
  232284. config SND_SOC_IMX_WM8962
  232285. tristate "SoC Audio support for i.MX boards with wm8962"
  232286. depends on OF && I2C
  232287. @@ -210,6 +233,17 @@
  232288. Say Y if you want to add support for SoC audio on an i.MX board with
  232289. a S/DPDIF.
  232290. +config SND_SOC_IMX_HDMI
  232291. + tristate "SoC Audio support for i.MX boards with HDMI port"
  232292. + depends on MFD_MXC_HDMI
  232293. + select SND_SOC_IMX_HDMI_DMA
  232294. + select SND_SOC_FSL_HDMI
  232295. + select SND_SOC_HDMI_CODEC
  232296. + help
  232297. + SoC Audio support for i.MX boards with HDMI audio
  232298. + Say Y if you want to add support for SoC audio on an i.MX board with
  232299. + IMX HDMI.
  232300. +
  232301. config SND_SOC_IMX_MC13783
  232302. tristate "SoC Audio support for I.MX boards with mc13783"
  232303. depends on MFD_MC13XXX && ARM
  232304. diff -Nur linux-3.14.15/sound/soc/fsl/Makefile linux-linaro-stable-mx6/sound/soc/fsl/Makefile
  232305. --- linux-3.14.15/sound/soc/fsl/Makefile 2014-07-31 23:51:43.000000000 +0200
  232306. +++ linux-linaro-stable-mx6/sound/soc/fsl/Makefile 2014-08-20 19:31:58.740923149 +0200
  232307. @@ -14,13 +14,19 @@
  232308. snd-soc-fsl-sai-objs := fsl_sai.o
  232309. snd-soc-fsl-ssi-objs := fsl_ssi.o
  232310. snd-soc-fsl-spdif-objs := fsl_spdif.o
  232311. +snd-soc-fsl-hdmi-objs := fsl_hdmi.o
  232312. snd-soc-fsl-esai-objs := fsl_esai.o
  232313. +snd-soc-fsl-asrc-pcm-objs := fsl_asrc_pcm.o
  232314. +snd-soc-fsl-asrc-objs := fsl_asrc.o
  232315. snd-soc-fsl-utils-objs := fsl_utils.o
  232316. snd-soc-fsl-dma-objs := fsl_dma.o
  232317. obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
  232318. obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
  232319. obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o
  232320. +obj-$(CONFIG_SND_SOC_FSL_HDMI) += snd-soc-fsl-hdmi.o
  232321. obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o
  232322. +obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc-pcm.o
  232323. +obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
  232324. obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
  232325. obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
  232326. @@ -41,22 +47,27 @@
  232327. obj-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o
  232328. obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
  232329. +obj-$(CONFIG_SND_SOC_IMX_HDMI_DMA) += imx-hdmi-dma.o
  232330. # i.MX Machine Support
  232331. snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
  232332. snd-soc-phycore-ac97-objs := phycore-ac97.o
  232333. snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
  232334. snd-soc-wm1133-ev1-objs := wm1133-ev1.o
  232335. +snd-soc-imx-cs42888-objs := imx-cs42888.o
  232336. snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
  232337. snd-soc-imx-wm8962-objs := imx-wm8962.o
  232338. snd-soc-imx-spdif-objs := imx-spdif.o
  232339. +snd-soc-imx-hdmi-objs := imx-hdmi.o
  232340. snd-soc-imx-mc13783-objs := imx-mc13783.o
  232341. obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
  232342. obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
  232343. obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
  232344. obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
  232345. +obj-$(CONFIG_SND_SOC_IMX_CS42888) += snd-soc-imx-cs42888.o
  232346. obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
  232347. obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
  232348. obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
  232349. +obj-$(CONFIG_SND_SOC_IMX_HDMI) += snd-soc-imx-hdmi.o
  232350. obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
  232351. diff -Nur linux-3.14.15/sound/soc/soc-pcm.c linux-linaro-stable-mx6/sound/soc/soc-pcm.c
  232352. --- linux-3.14.15/sound/soc/soc-pcm.c 2014-07-31 23:51:43.000000000 +0200
  232353. +++ linux-linaro-stable-mx6/sound/soc/soc-pcm.c 2014-08-20 19:31:59.380925896 +0200
  232354. @@ -945,7 +945,7 @@
  232355. }
  232356. }
  232357. - dev_err(card->dev, "ASoC: can't get %s BE for %s\n",
  232358. + dev_dbg(card->dev, "ASoC: can't get %s BE for %s\n",
  232359. stream ? "capture" : "playback", widget->name);
  232360. return NULL;
  232361. }
  232362. @@ -1062,7 +1062,7 @@
  232363. /* is there a valid BE rtd for this widget */
  232364. be = dpcm_get_be(card, list->widgets[i], stream);
  232365. if (!be) {
  232366. - dev_err(fe->dev, "ASoC: no BE found for %s\n",
  232367. + dev_dbg(fe->dev, "ASoC: no BE found for %s\n",
  232368. list->widgets[i]->name);
  232369. continue;
  232370. }